Thesis: The Project 538 prediction models overestimate the popular
vote support for third-party candidates, resulting in an underestimation
of Republican popular vote support and creating the false impression
that the race is less competitive than it truly is.
This analysis uses popular vote data from 2016 and 2020 to predict
the popular vote per candidate for the 2024 election. Its data includes
the election year, the candidate, the grade of the pollster, and the
popular vote prediction per pollster. If Project 538 pollster data over
predicts the third-party candidate and under predicts the republican and
democratic candidate, I expect the actual popular vote to have less
votes for the third-party candidate and more votes for republican and
democratic candidates. Proportionally, though, the republican candidate
should get more of the third-party votes than the democratic candidate.
However, if the predictions for the republican, democratic, and
third-party candidate are accurate, the Project 538 pollster data is
accurate as is.
Data Description
Project 538 provided over thirty-thousand rows of data from the 2016,
2020, 2024 presidential elections. Twenty-thousand rows related to
specific states were excluded.
Key variables included:
- Candidate: The presidential candidate termed either
by republican, democrat, or other.
- Average Error: The error of actual percentage minus
predicted percentage on average per candidate.
- Predicted Percentage: The percentage of the popular
vote per candidate that was predicted by the 538 pollster data.
- Expected Percentage: The percentage of the popular
vote per candidate that is expected based on the 538 pollster data
predictions.
- Actual Percentage: The percentage of the popular
vote per candidate that actually occurred for previous elections.
- Average Percentage: The average percentage of the
popular vote per candidate predicted with and without a model.
- Frequency: The number of times a value occurs.
- Residuals: The actual percentage result per
candidate minus the predicted percentage result per candidate.
Methods
Average Error in Popular Vote Predictions Per Candidate
In 2016 and in 2020, the popular vote was overpredicted for the
third-party, or “other”, candidate. This overprediction was mainly taken
from the republican candidate. However, both the republican and
democratic candidate were underpredicted.
── Attaching core tidyverse packages ────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ──────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
Attaching package: ‘janitor’
The following objects are masked from ‘package:stats’:
chisq.test, fisher.test

Expected Popular Vote Results Without Using a Regression Model
By using the average underprediction of the republican and democratic
candidates and the average overprediction of the other candidates, a
simple model can be made based on predicted 2024 popular vote per
candidate to predict the actual 2024 popular vote per candidate.
Attaching package: ‘gridExtra’
The following object is masked from ‘package:dplyr’:
combine

Creating a Regression Model Based on 2016 and 2020 Data
Using 2016 and 2020 popular vote data, a training and testing dataset
can be created to create a model that predicts the popular vote by
candidate based on the predicted percentage of votes, the grade of the
pollster, and the candidate in the election.
Loading required package: lattice
Registered S3 method overwritten by 'data.table':
method from
print.data.table
Attaching package: ‘caret’
The following object is masked from ‘package:purrr’:
lift

Results of the 2016/2020 Model on the Testing Data
The values and histogram below show the results of the training model
being applied to the testing data. It appears that the model is
overfitted due to the extremely high R^2 value and the small
residuals.
[1] "Testing RMSE: 0.0075"
[1] "R-squared for testing: 0.998"

Applying the Model to 2024 Predicted Data
The output below does not produce the result that is wanted. The
output shows that the other candidate will receive more votes than
expected, and that proportionally, the democratic candidate will receive
more votes than expected than the republican candidate.

Limitations
The original model exhibited overfitting, leading to unrealistic
predictions. A primary concern is that the model assumes the Democratic
candidate will win the popular vote in 2024, based on their victories in
2016 and 2020. As a result, the model unjustly deducts points from the
Republican candidate’s expected outcomes. To fix this overfitting, it
would be beneficial to include data from multiple elections rather than
relying solely on these two recent elections.
Discussion
Before the election, I created a predictive model by hand and a
predictive model using linear regression that were intended to predict
the popular vote for each party (Republican, Democrat, Other) in the
2024 election. My model by hand, which utilized Project 538 pollster
predictions adjusted by average 2016 and 2020 error predicted that Trump
would receive 49.8% of the vote, Harris would receive 48.7% of the vote,
and that other candidates would receive 0.4% of the vote. My linear
regression model, which used the Project 538 pollster predicted
percentage of votes, the candidate, and the grade of pollsters as
inputs, predicted that Trump would receive 47.1% of the vote, Harris
would receive 49.8% of the vote, and that other candidates would receive
4.1% of the vote. In reality, Trump received 50.2% of the popular vote,
Harris received 48.1% of the popular vote, and the other candidates
received 1.7% of the popular vote.
My model by hand was a better predictor of the popular vote than my
linear regression model. My model by hand correctly predicted which
candidate would win the popular vote and had an average margin of error
of roughly 0.8%. My linear regression model was not a good predictor of
the popular vote. My linear regression model incorrectly predicted which
candidate would win the popular vote and had an average margin of error
of roughly 2.4%.
I am happy with my initial analysis, thesis, code, and thought
process throughout the project. Using a rough model by hand, I was able
to correctly predict who would win the popular vote within a reasonable
margin of error. However, I am not happy that my thesis did not
correlate to my linear regression model, which was the main focus of the
project. That error and lack of correlation definitely came from the
overfitting of my model that I used to predict the 2024 popular vote.
Because the Democratic candidate won the popular vote in 2016 and 2020,
my overfit linear regression model assumed that they would as well in
2024. Overall, I am happy with my thesis and handmade model, but
frustrated with my linear regression model.
References
Sources included:
LS0tDQp0aXRsZTogIlIgUHJvamVjdCAyIg0KYXV0aG9yOiAiSm9zaCBGcmVlbWFuIg0KZGF0ZTogIjEwLzE1LzIwMjQiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyBUaGVzaXM6IFRoZSBQcm9qZWN0IDUzOCBwcmVkaWN0aW9uIG1vZGVscyBvdmVyZXN0aW1hdGUgdGhlIHBvcHVsYXIgdm90ZSBzdXBwb3J0IGZvciB0aGlyZC1wYXJ0eSBjYW5kaWRhdGVzLCByZXN1bHRpbmcgaW4gYW4gdW5kZXJlc3RpbWF0aW9uIG9mIFJlcHVibGljYW4gcG9wdWxhciB2b3RlIHN1cHBvcnQgYW5kIGNyZWF0aW5nIHRoZSBmYWxzZSBpbXByZXNzaW9uIHRoYXQgdGhlIHJhY2UgaXMgbGVzcyBjb21wZXRpdGl2ZSB0aGFuIGl0IHRydWx5IGlzLg0KDQpUaGlzIGFuYWx5c2lzIHVzZXMgcG9wdWxhciB2b3RlIGRhdGEgZnJvbSAyMDE2IGFuZCAyMDIwIHRvIHByZWRpY3QgdGhlIHBvcHVsYXIgdm90ZSBwZXIgY2FuZGlkYXRlIGZvciB0aGUgMjAyNCBlbGVjdGlvbi4gSXRzIGRhdGEgaW5jbHVkZXMgdGhlIGVsZWN0aW9uIHllYXIsIHRoZSBjYW5kaWRhdGUsIHRoZSBncmFkZSBvZiB0aGUgcG9sbHN0ZXIsIGFuZCB0aGUgcG9wdWxhciB2b3RlIHByZWRpY3Rpb24gcGVyIHBvbGxzdGVyLiBJZiBQcm9qZWN0IDUzOCBwb2xsc3RlciBkYXRhIG92ZXIgcHJlZGljdHMgdGhlIHRoaXJkLXBhcnR5IGNhbmRpZGF0ZSBhbmQgdW5kZXIgcHJlZGljdHMgdGhlIHJlcHVibGljYW4gYW5kIGRlbW9jcmF0aWMgY2FuZGlkYXRlLCBJIGV4cGVjdCB0aGUgYWN0dWFsIHBvcHVsYXIgdm90ZSB0byBoYXZlIGxlc3Mgdm90ZXMgZm9yIHRoZSB0aGlyZC1wYXJ0eSBjYW5kaWRhdGUgYW5kIG1vcmUgdm90ZXMgZm9yIHJlcHVibGljYW4gYW5kIGRlbW9jcmF0aWMgY2FuZGlkYXRlcy4gUHJvcG9ydGlvbmFsbHksIHRob3VnaCwgdGhlIHJlcHVibGljYW4gY2FuZGlkYXRlIHNob3VsZCBnZXQgbW9yZSBvZiB0aGUgdGhpcmQtcGFydHkgdm90ZXMgdGhhbiB0aGUgZGVtb2NyYXRpYyBjYW5kaWRhdGUuIEhvd2V2ZXIsIGlmIHRoZSBwcmVkaWN0aW9ucyBmb3IgdGhlIHJlcHVibGljYW4sIGRlbW9jcmF0aWMsIGFuZCB0aGlyZC1wYXJ0eSBjYW5kaWRhdGUgYXJlIGFjY3VyYXRlLCB0aGUgUHJvamVjdCA1MzggcG9sbHN0ZXIgZGF0YSBpcyBhY2N1cmF0ZSBhcyBpcy4NCg0KDQojIyBEYXRhIERlc2NyaXB0aW9uDQoNClByb2plY3QgNTM4IHByb3ZpZGVkIG92ZXIgdGhpcnR5LXRob3VzYW5kIHJvd3Mgb2YgZGF0YSBmcm9tIHRoZSAyMDE2LCAyMDIwLCAyMDI0IHByZXNpZGVudGlhbCBlbGVjdGlvbnMuIFR3ZW50eS10aG91c2FuZCByb3dzIHJlbGF0ZWQgdG8gc3BlY2lmaWMgc3RhdGVzIHdlcmUgZXhjbHVkZWQuDQoNCktleSB2YXJpYWJsZXMgaW5jbHVkZWQ6DQoNCi0gKipDYW5kaWRhdGUqKjogVGhlIHByZXNpZGVudGlhbCBjYW5kaWRhdGUgdGVybWVkIGVpdGhlciBieSByZXB1YmxpY2FuLCBkZW1vY3JhdCwgb3Igb3RoZXIuDQotICoqQXZlcmFnZSBFcnJvcioqOiBUaGUgZXJyb3Igb2YgYWN0dWFsIHBlcmNlbnRhZ2UgbWludXMgcHJlZGljdGVkIHBlcmNlbnRhZ2Ugb24gYXZlcmFnZSBwZXIgY2FuZGlkYXRlLg0KLSAqKlByZWRpY3RlZCBQZXJjZW50YWdlKio6IFRoZSBwZXJjZW50YWdlIG9mIHRoZSBwb3B1bGFyIHZvdGUgcGVyIGNhbmRpZGF0ZSB0aGF0IHdhcyBwcmVkaWN0ZWQgYnkgdGhlIDUzOCBwb2xsc3RlciBkYXRhLg0KLSAqKkV4cGVjdGVkIFBlcmNlbnRhZ2UqKjogVGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIHBvcHVsYXIgdm90ZSBwZXIgY2FuZGlkYXRlIHRoYXQgaXMgZXhwZWN0ZWQgYmFzZWQgb24gdGhlIDUzOCBwb2xsc3RlciBkYXRhIHByZWRpY3Rpb25zLg0KLSAqKkFjdHVhbCBQZXJjZW50YWdlKio6IFRoZSBwZXJjZW50YWdlIG9mIHRoZSBwb3B1bGFyIHZvdGUgcGVyIGNhbmRpZGF0ZSB0aGF0IGFjdHVhbGx5IG9jY3VycmVkIGZvciBwcmV2aW91cyBlbGVjdGlvbnMuDQotICoqQXZlcmFnZSBQZXJjZW50YWdlKio6IFRoZSBhdmVyYWdlIHBlcmNlbnRhZ2Ugb2YgdGhlIHBvcHVsYXIgdm90ZSBwZXIgY2FuZGlkYXRlIHByZWRpY3RlZCB3aXRoIGFuZCB3aXRob3V0IGEgbW9kZWwuDQotICoqRnJlcXVlbmN5Kio6IFRoZSBudW1iZXIgb2YgdGltZXMgYSB2YWx1ZSBvY2N1cnMuDQotICoqUmVzaWR1YWxzKio6IFRoZSBhY3R1YWwgcGVyY2VudGFnZSByZXN1bHQgcGVyIGNhbmRpZGF0ZSBtaW51cyB0aGUgcHJlZGljdGVkIHBlcmNlbnRhZ2UgcmVzdWx0IHBlciBjYW5kaWRhdGUuDQoNCg0KIyMgTWV0aG9kcw0KDQoNCiMjIyBBdmVyYWdlIEVycm9yIGluIFBvcHVsYXIgVm90ZSBQcmVkaWN0aW9ucyBQZXIgQ2FuZGlkYXRlDQoNCg0KSW4gMjAxNiBhbmQgaW4gMjAyMCwgdGhlIHBvcHVsYXIgdm90ZSB3YXMgb3ZlcnByZWRpY3RlZCBmb3IgdGhlIHRoaXJkLXBhcnR5LCBvciAib3RoZXIiLCBjYW5kaWRhdGUuIFRoaXMgb3ZlcnByZWRpY3Rpb24gd2FzIG1haW5seSB0YWtlbiBmcm9tIHRoZSByZXB1YmxpY2FuIGNhbmRpZGF0ZS4gSG93ZXZlciwgYm90aCB0aGUgcmVwdWJsaWNhbiBhbmQgZGVtb2NyYXRpYyBjYW5kaWRhdGUgd2VyZSB1bmRlcnByZWRpY3RlZC4gDQoNCg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdyYWRlX21hcHBpbmcgPC0gYygNCiAgIkMtIiA9IDAuNSwgIkMiID0gMC44LCAiQysiID0gMS4xLA0KICAiQi0iID0gMS40LCAiQiIgPSAxLjc1LCAiQisiID0gMi4xLA0KICAiQS0iID0gMi40LCAiQSIgPSAyLjcsICJBKyIgPSAzLjANCikNCg0KdF9wcmVzaWRlbnRfcG9sbHNfVVNfMjAxNiA8LSByZWFkX2NzdigncHJlc2lkZW50X2dlbmVyYWxfcG9sbHNfMjAxNiAoMSkuY3N2Jywgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JSANCiAgICAgc2VsZWN0KGN5Y2xlLCBzdGF0ZSwgcG9sbF9pZCwgZ3JhZGUsIHJhd3BvbGxfY2xpbnRvbiwgcmF3cG9sbF90cnVtcCwgcmF3cG9sbF9qb2huc29uKSAlPiUgDQogICAgbXV0YXRlKGRlbW9jcmF0ID0gYXMubnVtZXJpYyhnc3ViKCIlIiwgIiIsIHJhd3BvbGxfY2xpbnRvbikpIC8gMTAwLA0KICAgICAgICAgICByZXB1YmxpY2FuID0gYXMubnVtZXJpYyhnc3ViKCIlIiwgIiIsIHJhd3BvbGxfdHJ1bXApKSAvIDEwMCwNCiAgICAgICAgICAgb3RoZXIgPSBhcy5udW1lcmljKGdzdWIoIiUiLCAiIiwgcmF3cG9sbF9qb2huc29uKSkgLyAxMDApICU+JSANCiAgICBtdXRhdGUoeWVhciA9IGN5Y2xlLA0KICAgICAgICAgcG9sbCA9IHBvbGxfaWQpICU+JSANCiAgZmlsdGVyKHN0YXRlID09ICJVLlMuIikgJT4lDQogZHJvcF9uYShvdGhlciwgZ3JhZGUpICU+JSANCiAgc2VsZWN0KHllYXIsIHN0YXRlLCBwb2xsLCBncmFkZSwgZGVtb2NyYXQsIHJlcHVibGljYW4sIG90aGVyKSAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhkZW1vY3JhdCwgcmVwdWJsaWNhbiwgb3RoZXIpLCBuYW1lc190byA9ICJjYW5kaWRhdGUiLCB2YWx1ZXNfdG8gPSAicHJlZGljdGVkX3BlcmNlbnRhZ2UiKSAlPiUNCiAgICBtdXRhdGUoYWN0dWFsX3BlcmNlbnRhZ2UgPSBjYXNlX3doZW4oDQogICAgY2FuZGlkYXRlID09ICJkZW1vY3JhdCIgfiAwLjQ4NSwNCiAgICBjYW5kaWRhdGUgPT0gInJlcHVibGljYW4iIH4gMC40NjQsDQogICAgY2FuZGlkYXRlID09ICJvdGhlciIgfiAwLjA1MSwNCiAgICBUUlVFIH4gTkFfcmVhbF8NCiAgKSkgJT4lIA0KICAgIG11dGF0ZShlcnJvciA9IGFjdHVhbF9wZXJjZW50YWdlIC0gcHJlZGljdGVkX3BlcmNlbnRhZ2UpICU+JSANCiAgbXV0YXRlKGdyYWRlID0gaWZlbHNlKHllYXIgPT0gMjAxNiwgcmVjb2RlKGdyYWRlLCAhISFncmFkZV9tYXBwaW5nKSwgZ3JhZGUpKQ0KDQoNCnRfcHJlc2lkZW50X3BvbGxzX1VTXzIwMjAgPC0gcmVhZF9jc3YoJ3ByZXNpZGVudF9wb2xsc19oaXN0b3JpY2FsLmNzdicsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpICU+JSANCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgDQogIHNlbGVjdChjeWNsZSwgc3RhdGVfbmFtZSwgcG9sbF9pZCwgY2FuZGlkYXRlX2lkLCBudW1lcmljX2dyYWRlLCBjYW5kaWRhdGVfbmFtZSwgcGVyY2VudGFnZSkgJT4lIA0KICAgIG11dGF0ZShwZXJjZW50YWdlID0gYXMubnVtZXJpYyhnc3ViKCIlIiwgIiIsIHBlcmNlbnRhZ2UpKSAvIDEwMCwNCiAgICAgICAgICAgc3RhdGUgPSBzdGF0ZV9uYW1lLA0KICAgICAgICAgICB5ZWFyID0gY3ljbGUsDQogICAgICAgICAgIHByZWRpY3RlZF9wZXJjZW50YWdlID0gcGVyY2VudGFnZSkgJT4lIA0KICAgIHNlbGVjdCgtc3RhdGVfbmFtZSwgLWN5Y2xlKSAlPiUgDQogIGZpbHRlcihpcy5uYShzdGF0ZSkpICU+JSANCiAgICAgIHJlcGxhY2VfbmEobGlzdChzdGF0ZSA9ICJVLlMuIikpICU+JSANCiAgbXV0YXRlKGNhbmRpZGF0ZSA9IGNhc2Vfd2hlbigNCiAgICBjYW5kaWRhdGVfbmFtZSA9PSAiSm9lIEJpZGVuIiB+ICJkZW1vY3JhdCIsDQogICAgY2FuZGlkYXRlX25hbWUgPT0gIkRvbmFsZCBUcnVtcCIgfiAicmVwdWJsaWNhbiIsDQogICAgY2FuZGlkYXRlX25hbWUgPT0gIkpvIEpvcmdlbnNlbiIgfiAib3RoZXIiKSwNCiAgICBwb2xsID0gcG9sbF9pZCwNCiAgICBncmFkZSA9IG51bWVyaWNfZ3JhZGUNCiAgKSAlPiUNCiAgZmlsdGVyKGNhbmRpZGF0ZSAlaW4lIGMoImRlbW9jcmF0IiwgInJlcHVibGljYW4iLCAib3RoZXIiKSkgJT4lIA0KICBzZWxlY3QoeWVhciwgc3RhdGUsIHBvbGwsIGdyYWRlLCBjYW5kaWRhdGUsIHByZWRpY3RlZF9wZXJjZW50YWdlKSAlPiUgDQogICAgICBtdXRhdGUoYWN0dWFsX3BlcmNlbnRhZ2UgPSBjYXNlX3doZW4oDQogICAgY2FuZGlkYXRlID09ICJkZW1vY3JhdCIgfiAwLjUxMywNCiAgICBjYW5kaWRhdGUgPT0gInJlcHVibGljYW4iIH4gMC40NjksDQogICAgY2FuZGlkYXRlID09ICJvdGhlciIgfiAwLjAxOCwgICAgDQogICAgVFJVRSB+IE5BX3JlYWxfDQogICkpICU+JSANCiAgICBtdXRhdGUoZXJyb3IgPSBhY3R1YWxfcGVyY2VudGFnZSAtIHByZWRpY3RlZF9wZXJjZW50YWdlKSAlPiUgDQogIGZpbHRlcighaXMubmEoZ3JhZGUpKQ0KDQoNCmF2ZXJhZ2VfZXJyb3JfMjAxNiA8LSB0X3ByZXNpZGVudF9wb2xsc19VU18yMDE2ICU+JSANCiAgICBncm91cF9ieShjYW5kaWRhdGUpICU+JSAgDQogIHN1bW1hcmlzZShhdmVyYWdlX2Vycm9yID0gbWVhbihlcnJvciwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBtdXRhdGUoeWVhciA9ICIyMDE2IikNCg0KDQphdmVyYWdlX2Vycm9yXzIwMjAgPC0gdF9wcmVzaWRlbnRfcG9sbHNfVVNfMjAyMCAlPiUgDQogICAgZ3JvdXBfYnkoY2FuZGlkYXRlKSAlPiUgIA0KICBzdW1tYXJpc2UoYXZlcmFnZV9lcnJvciA9IG1lYW4oZXJyb3IsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgbXV0YXRlKHllYXIgPSAiMjAyMCIpDQoNCg0KYXZlcmFnZV9lcnJvciA8LSBiaW5kX3Jvd3MoYXZlcmFnZV9lcnJvcl8yMDE2LCBhdmVyYWdlX2Vycm9yXzIwMjApDQoNCiAgDQpnZ3Bsb3QoYXZlcmFnZV9lcnJvciwgYWVzKHggPSBjYW5kaWRhdGUsIHkgPSBhdmVyYWdlX2Vycm9yLCBmaWxsID0gY2FuZGlkYXRlKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBmYWNldF93cmFwKH4geWVhcikgKyAgDQogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBFcnJvciBieSBDYW5kaWRhdGUgZm9yIDIwMTYgYW5kIDIwMjAiLA0KICAgICAgIHggPSAiQ2FuZGlkYXRlIiwNCiAgICAgICB5ID0gIkF2ZXJhZ2UgRXJyb3IiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImRlbW9jcmF0IiA9ICJibHVlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXB1YmxpY2FuIiA9ICJyZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvdGhlciIgPSAiZ3JlZW4iKSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMSkNCg0KYGBgDQoNCg0KIyMjIEV4cGVjdGVkIFBvcHVsYXIgVm90ZSBSZXN1bHRzIFdpdGhvdXQgVXNpbmcgYSBSZWdyZXNzaW9uIE1vZGVsDQoNCg0KQnkgdXNpbmcgdGhlIGF2ZXJhZ2UgdW5kZXJwcmVkaWN0aW9uIG9mIHRoZSByZXB1YmxpY2FuIGFuZCBkZW1vY3JhdGljIGNhbmRpZGF0ZXMgYW5kIHRoZSBhdmVyYWdlIG92ZXJwcmVkaWN0aW9uIG9mIHRoZSBvdGhlciBjYW5kaWRhdGVzLCBhIHNpbXBsZSBtb2RlbCBjYW4gYmUgbWFkZSBiYXNlZCBvbiBwcmVkaWN0ZWQgMjAyNCBwb3B1bGFyIHZvdGUgcGVyIGNhbmRpZGF0ZSB0byBwcmVkaWN0IHRoZSBhY3R1YWwgMjAyNCBwb3B1bGFyIHZvdGUgcGVyIGNhbmRpZGF0ZS4gIA0KDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KDQoNCnRfcHJlc2lkZW50X3BvbGxzX1VTXzIwMjQgPC0gcmVhZF9jc3YoJ3ByZXNpZGVudF9wb2xscy5jc3YnLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUgDQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIA0KICBzZWxlY3QoY3ljbGUsIHN0YXRlX25hbWUsIHBvbGxfaWQsIG51bWVyaWNfZ3JhZGUsIGNhbmRpZGF0ZV9uYW1lLCBwZXJjZW50YWdlKSAlPiUgDQogICAgbXV0YXRlKHByZWRpY3RlZF9wZXJjZW50YWdlID0gYXMubnVtZXJpYyhnc3ViKCIlIiwgIiIsIHBlcmNlbnRhZ2UpKSAvIDEwMCwNCiAgICAgICAgICAgeWVhciA9IGN5Y2xlLA0KICAgICAgICAgICBzdGF0ZSA9IHN0YXRlX25hbWUsDQogICAgICAgICAgIHBvbGwgPSBwb2xsX2lkLCANCiAgICAgICAgICAgZ3JhZGUgPSBudW1lcmljX2dyYWRlLCANCiAgICAgICAgICAgY2FuZGlkYXRlID0gY2FuZGlkYXRlX25hbWUpICU+JSANCiAgc2VsZWN0KHllYXIsIHN0YXRlLCBwb2xsLCBncmFkZSwgY2FuZGlkYXRlLCBwcmVkaWN0ZWRfcGVyY2VudGFnZSkgJT4lIA0KICBmaWx0ZXIoaXMubmEoc3RhdGUpKSAlPiUNCiAgbXV0YXRlKHN0YXRlID0gIlUuUy4iKSAlPiUgDQogIGZpbHRlcihjYW5kaWRhdGUgJWluJSBjKCJEb25hbGQgVHJ1bXAiLCAiS2FtYWxhIEhhcnJpcyIsICJDb3JuZWwgV2VzdCIsICJKaWxsIFN0ZWluIiwgIkNoYXNlIE9saXZlciIpKSAlPiUgDQogICAgICBtdXRhdGUoY2FuZGlkYXRlID0gY2FzZV93aGVuKA0KICAgIGNhbmRpZGF0ZSA9PSAiS2FtYWxhIEhhcnJpcyIgfiAiZGVtb2NyYXQiLA0KICAgIGNhbmRpZGF0ZSA9PSAiRG9uYWxkIFRydW1wIiB+ICJyZXB1YmxpY2FuIiwNCiAgICBjYW5kaWRhdGUgJWluJSBjKCJDaGFzZSBPbGl2ZXIiLCAiQ29ybmVsIFdlc3QiLCAiSmlsbCBTdGVpbiIpIH4gIm90aGVyIiwNCiAgICBUUlVFIH4gY2FuZGlkYXRlDQogICkpICU+JSANCiAgIGZpbHRlcighaXMubmEoZ3JhZGUpKQ0KDQoNCmF2ZXJhZ2VfZXJyb3JfcGVyX2NhbmRpZGF0ZSA8LSBhdmVyYWdlX2Vycm9yICU+JQ0KICBzZWxlY3QoLXllYXIpICU+JSANCiAgZ3JvdXBfYnkoY2FuZGlkYXRlKSAlPiUgDQogIHN1bW1hcml6ZShhdmVyYWdlX2Vycm9yID0gbWVhbihhdmVyYWdlX2Vycm9yLCBuYS5ybSA9IFRSVUUpKQ0KDQphdmVyYWdlX3BlcmNlbnRhZ2VfMjAyNCA8LSB0X3ByZXNpZGVudF9wb2xsc19VU18yMDI0ICU+JQ0KICBncm91cF9ieShjYW5kaWRhdGUpICU+JQ0KICBzdW1tYXJpemUoYXZlcmFnZV9wcmVkaWN0ZWRfcGVyY2VudGFnZSA9IG1lYW4ocHJlZGljdGVkX3BlcmNlbnRhZ2UsIG5hLnJtID0gVFJVRSkpDQoNCg0KdF9wcmVzaWRlbnRfcG9sbHNfVVNfMjAyNF9ub19tb2RlbCA8LSBhdmVyYWdlX3BlcmNlbnRhZ2VfMjAyNCAlPiUgDQogICAgbGVmdF9qb2luKGF2ZXJhZ2VfZXJyb3JfcGVyX2NhbmRpZGF0ZSwgYnkgPSAiY2FuZGlkYXRlIikgJT4lDQogIG11dGF0ZShleHBlY3RlZF9wZXJjZW50YWdlID0gYXZlcmFnZV9wcmVkaWN0ZWRfcGVyY2VudGFnZSArIGF2ZXJhZ2VfZXJyb3IpDQoNCm1heF95IDwtIG1heCh0X3ByZXNpZGVudF9wb2xsc19VU18yMDI0X25vX21vZGVsJGF2ZXJhZ2VfcHJlZGljdGVkX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgICB0X3ByZXNpZGVudF9wb2xsc19VU18yMDI0X25vX21vZGVsJGV4cGVjdGVkX3BlcmNlbnRhZ2UpDQoNCnBsb3QxIDwtIGdncGxvdCh0X3ByZXNpZGVudF9wb2xsc19VU18yMDI0X25vX21vZGVsLCBhZXMoeCA9IGNhbmRpZGF0ZSwgeSA9IGF2ZXJhZ2VfcHJlZGljdGVkX3BlcmNlbnRhZ2UsIGZpbGwgPSBjYW5kaWRhdGUpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArICANCiAgbGFicygNCiAgICB0aXRsZSA9ICIyMDI0IFBvcHVsYXIgVm90ZSAoQmVmb3JlIEFkanVzdG1lbnQpIiwgDQogICAgeCA9ICJDYW5kaWRhdGUiLA0KICAgIHkgPSAiUHJlZGljdGVkIFBlcmNlbnRhZ2UiDQogICkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJyZXB1YmxpY2FuIiA9ICJyZWQiLCAiZGVtb2NyYXQiID0gImJsdWUiLCAib3RoZXIiID0gImdyZWVuIikpICsNCiAgeWxpbSgwLCBtYXhfeSkgKyAgIyBTZXQgdGhlIHNhbWUgeS1heGlzIGxpbWl0DQogIHRoZW1lX21pbmltYWwoKQ0KDQpwbG90MiA8LSBnZ3Bsb3QodF9wcmVzaWRlbnRfcG9sbHNfVVNfMjAyNF9ub19tb2RlbCwgYWVzKHggPSBjYW5kaWRhdGUsIHkgPSBleHBlY3RlZF9wZXJjZW50YWdlLCBmaWxsID0gY2FuZGlkYXRlKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAgDQogIGxhYnMoDQogICAgdGl0bGUgPSAiMjAyNCBQb3B1bGFyIFZvdGUgKEFkanVzdGVkIGZvciBFcnJvcikiLCAgDQogICAgeCA9ICJDYW5kaWRhdGUiLA0KICAgIHkgPSAiRXhwZWN0ZWQgUGVyY2VudGFnZSINCiAgKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoInJlcHVibGljYW4iID0gInJlZCIsICJkZW1vY3JhdCIgPSAiYmx1ZSIsICJvdGhlciIgPSAiZ3JlZW4iKSkgKw0KICB5bGltKDAsIG1heF95KSArICAjIFNldCB0aGUgc2FtZSB5LWF4aXMgbGltaXQNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmdyaWQuYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2wgPSAyKQ0KYGBgDQoNCg0KIyMjIENyZWF0aW5nIGEgUmVncmVzc2lvbiBNb2RlbCBCYXNlZCBvbiAyMDE2IGFuZCAyMDIwIERhdGENCg0KDQpVc2luZyAyMDE2IGFuZCAyMDIwIHBvcHVsYXIgdm90ZSBkYXRhLCBhIHRyYWluaW5nIGFuZCB0ZXN0aW5nIGRhdGFzZXQgY2FuIGJlIGNyZWF0ZWQgdG8gY3JlYXRlIGEgbW9kZWwgdGhhdCBwcmVkaWN0cyB0aGUgcG9wdWxhciB2b3RlIGJ5IGNhbmRpZGF0ZSBiYXNlZCBvbiB0aGUgcHJlZGljdGVkIHBlcmNlbnRhZ2Ugb2Ygdm90ZXMsIHRoZSBncmFkZSBvZiB0aGUgcG9sbHN0ZXIsIGFuZCB0aGUgY2FuZGlkYXRlIGluIHRoZSBlbGVjdGlvbi4gDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2djb3JycGxvdCkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY2FyZXQpDQoNCg0KdF9wcmVzaWRlbnRfcG9sbHNfVVNfYWxsIDwtIHJiaW5kKHRfcHJlc2lkZW50X3BvbGxzX1VTXzIwMTYsIHRfcHJlc2lkZW50X3BvbGxzX1VTXzIwMjApDQoNCnNldC5zZWVkKDEyMykNCg0KdHJhaW5faW5kaWNlcyA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKHRfcHJlc2lkZW50X3BvbGxzX1VTX2FsbCRhY3R1YWxfcGVyY2VudGFnZSwgcCA9IDAuNSwgbGlzdCA9IEZBTFNFKQ0KdF90cmFpbmluZ19zZXQgPC0gdF9wcmVzaWRlbnRfcG9sbHNfVVNfYWxsW3RyYWluX2luZGljZXMsIF0NCnRfdGVzdGluZ19zZXQgPC0gdF9wcmVzaWRlbnRfcG9sbHNfVVNfYWxsWy10cmFpbl9pbmRpY2VzLCBdDQoNCm1vZGVsIDwtIGxtKGFjdHVhbF9wZXJjZW50YWdlIH4gcHJlZGljdGVkX3BlcmNlbnRhZ2UgKyBjYW5kaWRhdGUgKyBncmFkZSwgZGF0YSA9IHRfdHJhaW5pbmdfc2V0KQ0KDQp0X3Rlc3Rpbmdfc2V0IDwtIHRfdGVzdGluZ19zZXQgJT4lIA0KICBtdXRhdGUocHJlZGljdGVkID0gcHJlZGljdChtb2RlbCwgbmV3ZGF0YSA9IHRfdGVzdGluZ19zZXQpLA0KICAgICAgICAgcmVzaWR1YWxzID0gcHJlZGljdGVkIC0gYWN0dWFsX3BlcmNlbnRhZ2UpDQoNCnJlZ3Jlc3Npb25fcGxvdCA8LSBnZ3Bsb3QodF90ZXN0aW5nX3NldCwgYWVzKHggPSBwcmVkaWN0ZWQsIHkgPSBhY3R1YWxfcGVyY2VudGFnZSkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgY29sb3IgPSAiYmx1ZSIpICsgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gInJlZCIsIHNlID0gRkFMU0UpICsgDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUmVncmVzc2lvbiBNb2RlbCBQcmVkaWN0aW9ucyB2cyBBY3R1YWwgUmVzdWx0cyBmb3IgMjAxNiAmIDIwMjAgVGVzdGluZyBEYXRhIiwNCiAgICB4ID0gIlByZWRpY3RlZCBQZXJjZW50YWdlIiwNCiAgICB5ID0gIkFjdHVhbCBQZXJjZW50YWdlIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCnN1cHByZXNzTWVzc2FnZXMoDQogIHByaW50KHJlZ3Jlc3Npb25fcGxvdCkNCikNCg0KYGBgDQoNCg0KIyMjIFJlc3VsdHMgb2YgdGhlIDIwMTYvMjAyMCBNb2RlbCBvbiB0aGUgVGVzdGluZyBEYXRhDQoNCg0KVGhlIHZhbHVlcyBhbmQgaGlzdG9ncmFtIGJlbG93IHNob3cgdGhlIHJlc3VsdHMgb2YgdGhlIHRyYWluaW5nIG1vZGVsIGJlaW5nIGFwcGxpZWQgdG8gdGhlIHRlc3RpbmcgZGF0YS4gSXQgYXBwZWFycyB0aGF0IHRoZSBtb2RlbCBpcyBvdmVyZml0dGVkIGR1ZSB0byB0aGUgZXh0cmVtZWx5IGhpZ2ggUl4yIHZhbHVlIGFuZCB0aGUgc21hbGwgcmVzaWR1YWxzLiANCg0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ2NvcnJwbG90KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShjYXJldCkNCg0Kcm1zZV90ZXN0IDwtIHNxcnQobWVhbih0X3Rlc3Rpbmdfc2V0JHJlc2lkdWFsc14yKSkNCnJtc2VfdGVzdF9yb3VuZGVkIDwtIHJvdW5kKHJtc2VfdGVzdCwgNCkNCnByaW50KHBhc3RlKCJUZXN0aW5nIFJNU0U6Iiwgcm1zZV90ZXN0X3JvdW5kZWQpKQ0KDQpyZXNpZHVhbF9zdW1fb2Zfc3F1YXJlc190ZXN0IDwtIHN1bSh0X3Rlc3Rpbmdfc2V0JHJlc2lkdWFscyBeIDIpDQp0b3RhbF92YXJpYXRpb25faW5fbW9kZWxfdGVzdCA8LSB0X3Rlc3Rpbmdfc2V0JGFjdHVhbF9wZXJjZW50YWdlIC0gbWVhbih0X3Rlc3Rpbmdfc2V0JGFjdHVhbF9wZXJjZW50YWdlKQ0KdG90YWxfc3VtX29mX3NxdWFyZXNfdGVzdCA8LSBzdW0odG90YWxfdmFyaWF0aW9uX2luX21vZGVsX3Rlc3QgXiAyKQ0KcjJfdGVzdCA8LSAxIC0gKHJlc2lkdWFsX3N1bV9vZl9zcXVhcmVzX3Rlc3QgLyB0b3RhbF9zdW1fb2Zfc3F1YXJlc190ZXN0KQ0KcjJfdGVzdF9yb3VuZGVkIDwtIHJvdW5kKHIyX3Rlc3QsIDQpDQpwcmludChwYXN0ZSgiUi1zcXVhcmVkIGZvciB0ZXN0aW5nOiIsIHIyX3Rlc3Rfcm91bmRlZCkpDQoNCmhpc3QodF90ZXN0aW5nX3NldCRyZXNpZHVhbHMsIG1haW4gPSAiSGlzdG9ncmFtIG9mIFRlc3RpbmcgU2V0IFJlc2lkdWFscyBmb3IgUGVyY2VudGFnZSIsIHhsYWIgPSAiUmVzaWR1YWxzIikNCg0KDQpgYGANCg0KIyMjIEFwcGx5aW5nIHRoZSBNb2RlbCB0byAyMDI0IFByZWRpY3RlZCBEYXRhDQoNClRoZSBvdXRwdXQgYmVsb3cgZG9lcyBub3QgcHJvZHVjZSB0aGUgcmVzdWx0IHRoYXQgaXMgd2FudGVkLiBUaGUgb3V0cHV0IHNob3dzIHRoYXQgdGhlIG90aGVyIGNhbmRpZGF0ZSB3aWxsIHJlY2VpdmUgbW9yZSB2b3RlcyB0aGFuIGV4cGVjdGVkLCBhbmQgdGhhdCBwcm9wb3J0aW9uYWxseSwgdGhlIGRlbW9jcmF0aWMgY2FuZGlkYXRlIHdpbGwgcmVjZWl2ZSBtb3JlIHZvdGVzIHRoYW4gZXhwZWN0ZWQgdGhhbiB0aGUgcmVwdWJsaWNhbiBjYW5kaWRhdGUuIA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ2NvcnJwbG90KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpwcmVkaWN0aW9uc18yMDI0IDwtIHRfcHJlc2lkZW50X3BvbGxzX1VTXzIwMjQgJT4lIA0KICBtdXRhdGUocHJlZGljdGVkID0gcHJlZGljdChtb2RlbCwgbmV3ZGF0YSA9IHRfcHJlc2lkZW50X3BvbGxzX1VTXzIwMjQpKQ0KDQoNCmF2ZXJhZ2VfcmVzdWx0c18yMDI0IDwtIHByZWRpY3Rpb25zXzIwMjQgJT4lDQogIGdyb3VwX2J5KGNhbmRpZGF0ZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBhdmdfcHJlZGljdGVkX3BlcmNlbnRhZ2UgPSBtZWFuKHByZWRpY3RlZF9wZXJjZW50YWdlLCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19wcmVkaWN0ZWRfYnlfbW9kZWwgPSBtZWFuKHByZWRpY3RlZCwgbmEucm0gPSBUUlVFKQ0KICApICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoYXZnX3ByZWRpY3RlZF9wZXJjZW50YWdlLCBhdmdfcHJlZGljdGVkX2J5X21vZGVsKSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInByZWRpY3Rpb25fdHlwZSIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiYXZlcmFnZV9wZXJjZW50YWdlIikgJT4lDQogICMgU2V0IHRoZSBsZXZlbHMgZm9yIHByZWRpY3Rpb25fdHlwZSBpbiB0aGUgZGVzaXJlZCBvcmRlcg0KICBtdXRhdGUocHJlZGljdGlvbl90eXBlID0gZmFjdG9yKHByZWRpY3Rpb25fdHlwZSwgbGV2ZWxzID0gYygiYXZnX3ByZWRpY3RlZF9wZXJjZW50YWdlIiwgImF2Z19wcmVkaWN0ZWRfYnlfbW9kZWwiKSkpDQoNCiMgQ3JlYXRlIHRoZSBjb21iaW5lZCBwbG90IHdpdGggZml4ZWQgeS1heGlzIGxpbWl0cw0KZ2dwbG90KGRhdGEgPSBhdmVyYWdlX3Jlc3VsdHNfMjAyNCwgYWVzKHggPSBjYW5kaWRhdGUsIHkgPSBhdmVyYWdlX3BlcmNlbnRhZ2UsIGZpbGwgPSBjYW5kaWRhdGUpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsNCiAgZmFjZXRfd3JhcCh+IHByZWRpY3Rpb25fdHlwZSwgc2NhbGVzID0gImZpeGVkIiwgbGFiZWxsZXIgPSBsYWJlbGxlcihwcmVkaWN0aW9uX3R5cGUgPSBjKA0KICAgIGF2Z19wcmVkaWN0ZWRfcGVyY2VudGFnZSA9ICJQcmVkaWN0ZWQgQmVmb3JlaGFuZCIsDQogICAgYXZnX3ByZWRpY3RlZF9ieV9tb2RlbCA9ICJQcmVkaWN0ZWQgd2l0aCBNb2RlbCINCiAgKSkpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJBdmVyYWdlIFByZWRpY3RlZCBQZXJjZW50YWdlcyBieSBDYW5kaWRhdGUgZm9yIDIwMjQiLA0KICAgIHggPSAiQ2FuZGlkYXRlIiwNCiAgICB5ID0gIkF2ZXJhZ2UgUGVyY2VudGFnZSIsDQogICAgZmlsbCA9ICJDYW5kaWRhdGUiDQogICkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJkZW1vY3JhdCIgPSAiYmx1ZSIsICJyZXB1YmxpY2FuIiA9ICJyZWQiLCAib3RoZXIiID0gImdyZWVuIikpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCiMjIExpbWl0YXRpb25zDQoNClRoZSBvcmlnaW5hbCBtb2RlbCBleGhpYml0ZWQgb3ZlcmZpdHRpbmcsIGxlYWRpbmcgdG8gdW5yZWFsaXN0aWMgcHJlZGljdGlvbnMuIEEgcHJpbWFyeSBjb25jZXJuIGlzIHRoYXQgdGhlIG1vZGVsIGFzc3VtZXMgdGhlIERlbW9jcmF0aWMgY2FuZGlkYXRlIHdpbGwgd2luIHRoZSBwb3B1bGFyIHZvdGUgaW4gMjAyNCwgYmFzZWQgb24gdGhlaXIgdmljdG9yaWVzIGluIDIwMTYgYW5kIDIwMjAuIEFzIGEgcmVzdWx0LCB0aGUgbW9kZWwgdW5qdXN0bHkgZGVkdWN0cyBwb2ludHMgZnJvbSB0aGUgUmVwdWJsaWNhbiBjYW5kaWRhdGUncyBleHBlY3RlZCBvdXRjb21lcy4gVG8gZml4IHRoaXMgb3ZlcmZpdHRpbmcsIGl0IHdvdWxkIGJlIGJlbmVmaWNpYWwgdG8gaW5jbHVkZSBkYXRhIGZyb20gbXVsdGlwbGUgZWxlY3Rpb25zIHJhdGhlciB0aGFuIHJlbHlpbmcgc29sZWx5IG9uIHRoZXNlIHR3byByZWNlbnQgZWxlY3Rpb25zLg0KDQojIyBEaXNjdXNzaW9uDQoNCkJlZm9yZSB0aGUgZWxlY3Rpb24sIEkgY3JlYXRlZCBhIHByZWRpY3RpdmUgbW9kZWwgYnkgaGFuZCBhbmQgYSBwcmVkaWN0aXZlIG1vZGVsIHVzaW5nIGxpbmVhciByZWdyZXNzaW9uIHRoYXQgd2VyZSBpbnRlbmRlZCB0byBwcmVkaWN0IHRoZSBwb3B1bGFyIHZvdGUgZm9yIGVhY2ggcGFydHkgKFJlcHVibGljYW4sIERlbW9jcmF0LCBPdGhlcikgaW4gdGhlIDIwMjQgZWxlY3Rpb24uIE15IG1vZGVsIGJ5IGhhbmQsIHdoaWNoIHV0aWxpemVkIFByb2plY3QgNTM4IHBvbGxzdGVyIHByZWRpY3Rpb25zIGFkanVzdGVkIGJ5IGF2ZXJhZ2UgMjAxNiBhbmQgMjAyMCBlcnJvciBwcmVkaWN0ZWQgdGhhdCBUcnVtcCB3b3VsZCByZWNlaXZlIDQ5LjglIG9mIHRoZSB2b3RlLCBIYXJyaXMgd291bGQgcmVjZWl2ZSA0OC43JSBvZiB0aGUgdm90ZSwgYW5kIHRoYXQgb3RoZXIgY2FuZGlkYXRlcyB3b3VsZCByZWNlaXZlIDAuNCUgb2YgdGhlIHZvdGUuIE15IGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLCB3aGljaCB1c2VkIHRoZSBQcm9qZWN0IDUzOCBwb2xsc3RlciBwcmVkaWN0ZWQgcGVyY2VudGFnZSBvZiB2b3RlcywgdGhlIGNhbmRpZGF0ZSwgYW5kIHRoZSBncmFkZSBvZiBwb2xsc3RlcnMgYXMgaW5wdXRzLCBwcmVkaWN0ZWQgdGhhdCBUcnVtcCB3b3VsZCByZWNlaXZlIDQ3LjElIG9mIHRoZSB2b3RlLCBIYXJyaXMgd291bGQgcmVjZWl2ZSA0OS44JSBvZiB0aGUgdm90ZSwgYW5kIHRoYXQgb3RoZXIgY2FuZGlkYXRlcyB3b3VsZCByZWNlaXZlIDQuMSUgb2YgdGhlIHZvdGUuIEluIHJlYWxpdHksIFRydW1wIHJlY2VpdmVkIDUwLjIlIG9mIHRoZSBwb3B1bGFyIHZvdGUsIEhhcnJpcyByZWNlaXZlZCA0OC4xJSBvZiB0aGUgcG9wdWxhciB2b3RlLCBhbmQgdGhlIG90aGVyIGNhbmRpZGF0ZXMgcmVjZWl2ZWQgMS43JSBvZiB0aGUgcG9wdWxhciB2b3RlLiANCg0KTXkgbW9kZWwgYnkgaGFuZCB3YXMgYSBiZXR0ZXIgcHJlZGljdG9yIG9mIHRoZSBwb3B1bGFyIHZvdGUgdGhhbiBteSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbC4gTXkgbW9kZWwgYnkgaGFuZCBjb3JyZWN0bHkgcHJlZGljdGVkIHdoaWNoIGNhbmRpZGF0ZSB3b3VsZCB3aW4gdGhlIHBvcHVsYXIgdm90ZSBhbmQgaGFkIGFuIGF2ZXJhZ2UgbWFyZ2luIG9mIGVycm9yIG9mIHJvdWdobHkgMC44JS4gTXkgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgd2FzIG5vdCBhIGdvb2QgcHJlZGljdG9yIG9mIHRoZSBwb3B1bGFyIHZvdGUuIE15IGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIGluY29ycmVjdGx5IHByZWRpY3RlZCB3aGljaCBjYW5kaWRhdGUgd291bGQgd2luIHRoZSBwb3B1bGFyIHZvdGUgYW5kIGhhZCBhbiBhdmVyYWdlIG1hcmdpbiBvZiBlcnJvciBvZiByb3VnaGx5IDIuNCUuIA0KDQpJIGFtIGhhcHB5IHdpdGggbXkgaW5pdGlhbCBhbmFseXNpcywgdGhlc2lzLCBjb2RlLCBhbmQgdGhvdWdodCBwcm9jZXNzIHRocm91Z2hvdXQgdGhlIHByb2plY3QuIFVzaW5nIGEgcm91Z2ggbW9kZWwgYnkgaGFuZCwgSSB3YXMgYWJsZSB0byBjb3JyZWN0bHkgcHJlZGljdCB3aG8gd291bGQgd2luIHRoZSBwb3B1bGFyIHZvdGUgd2l0aGluIGEgcmVhc29uYWJsZSBtYXJnaW4gb2YgZXJyb3IuIEhvd2V2ZXIsIEkgYW0gbm90IGhhcHB5IHRoYXQgbXkgdGhlc2lzIGRpZCBub3QgY29ycmVsYXRlIHRvIG15IGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLCB3aGljaCB3YXMgdGhlIG1haW4gZm9jdXMgb2YgdGhlIHByb2plY3QuIFRoYXQgZXJyb3IgYW5kIGxhY2sgb2YgY29ycmVsYXRpb24gZGVmaW5pdGVseSBjYW1lIGZyb20gdGhlIG92ZXJmaXR0aW5nIG9mIG15IG1vZGVsIHRoYXQgSSB1c2VkIHRvIHByZWRpY3QgdGhlIDIwMjQgcG9wdWxhciB2b3RlLiBCZWNhdXNlIHRoZSBEZW1vY3JhdGljIGNhbmRpZGF0ZSB3b24gdGhlIHBvcHVsYXIgdm90ZSBpbiAyMDE2IGFuZCAyMDIwLCBteSBvdmVyZml0IGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIGFzc3VtZWQgdGhhdCB0aGV5IHdvdWxkIGFzIHdlbGwgaW4gMjAyNC4gT3ZlcmFsbCwgSSBhbSBoYXBweSB3aXRoIG15IHRoZXNpcyBhbmQgaGFuZG1hZGUgbW9kZWwsIGJ1dCBmcnVzdHJhdGVkIHdpdGggbXkgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwuIA0KDQojIyBSZWZlcmVuY2VzDQoNClNvdXJjZXMgaW5jbHVkZWQ6DQoNCi0gUHJvamVjdCA1MzggMjAxNiBwcmVzaWRlbnRpYWwgZGF0YToNCmh0dHBzOi8vcHJvamVjdHMuZml2ZXRoaXJ0eWVpZ2h0LmNvbS8yMDE2LWVsZWN0aW9uLWZvcmVjYXN0Lw0KLSBQcm9qZWN0IDUzOCAyMDIwIGFuZCAyMDI0IHByZXNpZGVudGlhbCBkYXRhOiBodHRwczovL3Byb2plY3RzLmZpdmV0aGlydHllaWdodC5jb20vcG9sbHMvcHJlc2lkZW50LWdlbmVyYWwvMjAyNC8NCi0gQ2hhdEdQVDogaHR0cHM6Ly9vcGVuYWkuY29tL2NoYXRncHQvb3ZlcnZpZXcvDQpDaGF0R1BUIGhlbHBlZCBtZSB0aHJvdWdob3V0IHRoZSBwcm9qZWN0IGFuZCBvbiBlYWNoIHNlY3Rpb24uIEkgd291bGQgd3JpdGUgdXAgdGhlIGNvZGUgdGhhdCBJIHdhbnRlZCwgYW5kIHRoZW4gYXNrIENoYXRHUFQgd2hhdCBJIHNob3VsZCBkbyBpZiBhbnkgaXNzdWVzIGFyb3NlIGFuZCBhc2tlZCBDaGF0R1BUIGZvciByZWNvbW1lbmRhdGlvbnMgb24gaG93IHRvIGRvIHRoaW5ncyB0aGF0IEkgd2Fzbid0IHN1cmUgb2YgaG93IHRvIGRvLiBJIGFsc28gYXNrZWQgQ2hhdCBHUFQgZm9yIGFkdmljZSBvbiBob3cgdG8gd29yayBhbmQgYWNoaWV2ZSBteSBvdXRwdXQgZWZmaWNpZW50bHkuIA0KDQoNCg==