Overview
This project will begin on Friday, June 19 and involve a 15 minute presentation one week later on Friday, June 26. There is also a written report with a maximum of 4 pages due by 5:00pm EST on Wednesday, July 1st. Both the presentation and written submission will follow the same structure: starting with a summary of key takeaways and then walking through EDA, the modeling process, results and conclusions. Teams will work in groups of 2, and data sets will be assigned randomly.
The goal of this project is to practice planning, creating, evaluating and interpreting linear regression models in R. Each team will fit a linear model using one of the continuous variables in their provided data set. Models should be tested with out-of-sample prediction methods, and must be interpretable. Making a model nedlesly complicated can lead to overfitting and make results difficult to interpret.
The first slide of the presentation, and first page of the written report, will be for key takeaways. For the presentation this can be in the form of a single graph, bullet points or a statement. For the written report it should be a combination of the three. This is your work in elevator pitch form, meant to grab the audiences attention and give them a reason to be interested. In the working world you may have only a short time to pitch results to superiors, and will have to start with the conclusions before explaining your process.
The rest of the presentation, and second page and beyond in the written report will follow a more traditional data anaylsis report format. The format will be as follows:
- Introduction of the data set & sport
- Exploratory Data Analysis conducted
- Modeling analysis & model validation
- this step includes variable selection, error rates, and checking diagnostic plots
- Model Results
- this step should include interpretation of the coefficients in the model
- Conclusion
Deliverables & Timeline
There will be 3 different deliverable deadlines:
Tuesday, June 23 @ 4:00pm EST - Each student will push an Rmarkdown file with their analysis so far to thier GitHub accounts for review. We will then provide feedback on the code submitted.
Friday, June 26 @ 12:00pm EST - Slides must be completed and ready for presentation. Send your slides to Nick’s email ncitrone@pittsburghpenguins.com . All code and visualizations must be done in R, but the slides may be created in any program. Presentations will be 15 minutes long with 5 minutes for Q&A.
As a reminder, the presentation should start with a Key Takeaway slide, and then lead into a traditional data analysis report (Introduction, EDA, Modeling, Results, Conclusion)
Wednesday, July 1 @ 5:00pm EST - Each team’s final written report must be emailed to Nick’s email ncitrone@pittsburghpenguins.com .
As a reminder, the written report will have the ‘model pitch’ on the first page, which is a short executive summary and potentially a key graphic. The second page and beyond of the written file will follow the traditional data analysis report format (Introduction, EDA, Modeling, Results, Conclusion). These last pages should set up and support your key takeaways.
Notes
Although this project will use simple linear regression, feel free to contact any of the instructors if you have questions about potential GLM (poisson, logistic) models using any of the data sets provided.
Data Sets
There are eight different datasets for the regression projects (three of which were generated via the init_regression_project_data.R script):
- nba_team_season_summary.csv - summary of regular season performance for each NBA team since 2003, courtesy of NBA stats via the ‘nbastatR package’,
- tennis_2013_2017_GS.csv - tennis grand slam statistics for 3066 ATP and WTA matches between 2013 and 2017. Data from Jeff Sackman’s tennis data repo, retreived by Stephanie Kovalchik’s
R deuce package, and synthesized in Gallagher, Frisoli, and Luby’s R courtsports package.
- baseball_batting.csv - MLB player season level batting statistics for 1429 player-seasons from 2010 to 2019. Data generated by FanGraphs and accessed courtesy of the
baseballr package,
- cfb_2019_games.csv - Results from all NCAA D1 College Football games in 2019. Includes team data, final score and an excitement rating for the game. Data accessed via the
cfbscrapR package,
- overwatch_odds.csv - Overwatch E-Sports League head to head match results with betting odds data. Data from Kaggle’s E-Sports Data Sets,
- womens_ncaa_soccer_20182019.csv - NCAA Women’s D1 soccer offensive and defensive team statistics from the 2018 and 2019 seasons. Data acquired from NCAA.com.
- womens_ncaa_volleyball_20182019.csv - NCAA Women’s D1 volleyball offensive and defensive team statistics from the 2018 and 2019 seasons. Data acquired from NCAA.com.
- womens_ncaa_lacrosse.csv - NCAA Women’s D1 lacrosse offensive and defensive team statistics from the 2018, 2019 and shortened 2020 seasons. Data acquired from NCAA.com.
NBA team season summary data
Each row in the nba_team_season_summary.csv dataset corresponds to a single NBA team in a single regular season dating back to 2003. The column names self-explanatory, but note that the columns ending with *_perc mean the percentage based statistics.
Tennis grand slams data
Each row in the data corresponds to a grand slam match between two players. A variety of summary statistics of the match are reported along with winner and loser information. Variables include:
tournament - one of the four grand slams: Australian Open, French Open, US Open, and Wimbledon
year
winner_name and loser_name
winner_rank and loser_rank according to ATP or WTA, respectively at the time of tournament
Retirement whether the match ended in a retirement (i.e. one person was unable to finish the match). Logical – TRUE means the match ended in retirement
Tour either WTA or ATP
round - R128 Round of 128, R64 - Round of 64, R32 - Round of 32, R16 Round of 16, QF Quarter Final, SF Semi Final, and F Final
w_* and l_* stands for winner and loser, respectively where the suffix is one of many summary statistics including
ave_serve_speed in mph
n_aces number of aces
n_winners number of winners including aces
n_netpt_w number of net points won
n_netpt number of net points played
n_bp_w number of break points won (to break the opponent)
n_bp number of break points (to break the opponent)
n_ue number of unforced errors
n_sv number of serves
n_sv_w number of service points won
MLB Batting Statistics 2010-2019
Each row in the baseball_batting.csv data corresponds to the batting statistics for a single player in a single season between 2010 and 2019. THe first few variables as well as the singles, doubles and triples are self-explanatory, and the other baseball variables mean as follows:
G games played
AB at bats: Plate appearances, not including bases on balls, being hit by pitch, sacrifices, interference, or obstruction.
PA plate appearances
H hits
HR home runs
R runs scored; the number of times a player crosses home plate
RBI runs batted in: the number of runners who score due to a batter’s action
BB walks ‘base on balls’
IBB intentional base on balls, times walked intentionally by pitcher
HBP hit by pitch: walked as a result of being hit by a pitch
SF sacrifice fly: fly balls hit to the outfield which although caught for an out, allow a baserunner to advance
SH sacrifice hit: number of sacrifice bunts which allow runners to advance on the basepaths
GDP ground into double-play: number of ground balls that became double plays
SB stolen bases
CS number of times caught stealing
AVG batting average
Pitches number of pitches faced
Balls number of balls faced
Strikes number of strikes faced
SO strike outs
BB_K walks / strike outs. Walk to strike out ratio
OBP on base percentage
SLG slugging average: total baseas achieved on hits / at bats
OPS on-base plus slugging: on-base percentage plus slugging average
ISO isolated power: a hitter’s ability to hit for extra bases, calculated by subtracting batting average from slugging percentage
wOBA weighted on base average
WAR wins above replacement: a non-standard formula to calculate the number of wins a player contributes to his team over a “replacement-level player”
WPA_plus win probability added, positive total
WPA_minus win probability added, negative total
Overwatch League Results and Odds
Each row in the overwatch_odds.csv data set contains data on a single Overwatch League match played between 2018 and 2020. Data includes the two teams, stage, winner, as well as information on the two teams success in the season thus far and in their history up until that point. Columns include:
id game id
corona_virus_isolation was the game played under corona virus isolation measures?
t1_wins_season t2_wins_season how many games team 1 has won in the season prior to the game (t2 for team 2)
t1_losses_season t2_losses_season how many games team 1 has lost in the season prior to the game (t2 for team 2)
t1_win_percent team 1 (t2 for team 2) win percentage in the season, in the last X games or all-time depending on variable name
t1_odds betting odds for team 1 to win the game.
Positive figures: The odds state the winnings on a 100 dollar bet (e.g. american odds of 110 would win 110 on a 100 dollar bet.)
Negative figures: The odds state how much must be bet to win 100 profit (e.g. american odds of -90 would win 100 on a 90 dollar bet.)
t2_odds betting odds for team 2 to win the game
t1_probability the implied win probability for team 1 given the betting odds
t2_probability the implied win probability for team 2 given the betting odds
Women’s NCAA D1 Soccer 2018 & 2019 Team Statistics
Each row in the womens_ncaa_soccer_20182019.csv data set refers to the statistics for a single school in a particular season. There are 668 team-school combinations spanning 2018 and 2019. Variables include:
assists the total number of assists earned by players on the team
team_games games played
assists_gp total assists earned per game played
corners corner kicks taken. This variable is unavailable for 2018
corners_gp corner kicks taken per game played. This variable is unavailable for 2018
fouls total fouls called on the team.
fouls_gp fouls called on the team per game played
ga goals against
team_min total minutes played by the team, including stoppage time
gaa goals against per game played
ps penalty kicks scored on
psatt penalty kicks attempted
pk_pct percentage of penalty kicks completed
points total points (goals + assists) accumulated for all players on the team
points_gp points accumulated by players on the team per game played
saves saves made by team goalkeepers
save_pct percentage of shots faced that goalkeepers saved
saves_gp number of saves made per game played
goals total goals scored by team
gpg the number of goals scored by the team per game played
sog total shots on goal
shatt total shot attempts
sog_pct percentage of shot attempts that were on goal
won games won
lost games lost
tied games tied
win_pct winning percentage
sog_gp number of shots on goal per game played
season the season the data refers to
Women’s NCAA D1 Volleyball 2018 & 2019 Team Statistics
Each row in the womens_ncaa_volleyball_20182019.csv data set refers to the statistics for a single school in a particular season. There are 666 team-school combinations spanning 2018 and 2019. Variables include:
s number of sets played
aces aces hit. An ace is a serve which lands in the opponent’s court without being touched, or is touched, but unable to be kept in play by one or more receiving team players
aces_per_set aces earned per set played
assists total team assists. Assists are awarded to a player who passes the ball to a teammate who attacks the ball for a kill. Can be awarded off a dig (first contact), provided the attack comes on the second contact
assists_per_set assists earned per set played
block_solos total team solo blocks. Players blocks the ball into the opponent’s court leading to a point or side out
block_assists total team assisted blocks
blocks_per_set total team blocks per set
digs total team digs. A dig occurs when a player passes the ball which has been attacked by the opposition. Digs are only given when players receive an attacked ball and it is kept in play
digs_per_set team digs per set played
kills team kills. An attack by a player that is not returnable by the receiving player on the opposing team and leads directly to a point or loss of rally
errors total team serve errors
total_attackstotal attack attempts. An attack is any overhead contact of the ball designed to score
hit_pct Hitting percentage is calculated by totaling kills, subtracting the hitting errors, then dividing that number by the total number of attack attempts.
kills_per_set kills earned per set played
w team wins
l team losses
win_pct team winning percentage
season season
Women’s NCAA D1 Lacrosse 2018, 2019 & 2020 Team Statistics
Each row in the womens_ncaa_lacrosse.csv data set refers to the D1 Women’s lacrosse statistics for a single school in a particular season. There are 348 team-school combinations spanning 2018, 2019 and 2020. Due to the Corona Virus pandemcic no team has played more than 10 games in 2020. Note that all _gp variables are the per game played versions of the variable they name (e.g. assists_gp is total team assists per game played). Other variable definitions are:
assists total team assists. The player who passes the ball to the player who scores a goal is credited with an assist
caused_tos total turnovers caused by the team. Also referred to as ‘takeaways’
draw_controls total team draw controls. A draw control occurs when a player successfully gains control of the ball after a draw.
fouls total team fouls
clears total team clears. A clear occurs when a team passes the offensive restraining line and is clearly able to get an offensive attempt.
clr_att total team attempted clears
clr_pct percent of team clear attempts that were succesfull
opp_dc opponents draw control total
drawc_control_pct percent of total draws that the team controlled
freepos_goals total free positiong goals. Free-position shot in women’s lacrosse is similar to a foul shot in basketball, awarded to an offensive player when a defender commits a major foul inside the 8-meter arc
freepos_shots total free positioning shots taken
free_position_pct percent of free position shots which resutled in goals
goals total team goals scored
points total points earned by all players on the team (goals + assists)
team_min total team minutes played
goals_allowed total goals allowed
saves total saves from all team goalkeepers
sv_pct team percentage of shots allowed which were saved, and not goals against
ga_gp goals allowed per game played
margin difference in goals scored - goals allowed per game played
gf_gp goals scored per game played
sog total shots on goal
turnovers total team turnovers committed
won games won
lost games lost
win_pct team winning percentage
yellow_cards total yellow cards earned by all players on the team
season season
LS0tCnRpdGxlOiAiTGluZWFyIFJlZ3Jlc3Npb24gUHJvamVjdCBSZXF1aXJlbWVudHMiCm91dHB1dDogaHRtbF9kb2N1bWVudAotLS0KCmBgYHtyLCBlY2hvID0gRkFMU0V9Cm9wdGlvbnModGlueXRleC52ZXJib3NlID0gVFJVRSkKCmBgYAoKIyMgT3ZlcnZpZXcKClRoaXMgcHJvamVjdCB3aWxsIGJlZ2luIG9uIEZyaWRheSwgSnVuZSAxOSBhbmQgaW52b2x2ZSBhIDE1IG1pbnV0ZSBwcmVzZW50YXRpb24gb25lIHdlZWsgbGF0ZXIgb24gRnJpZGF5LCBKdW5lIDI2LiAgVGhlcmUgaXMgYWxzbyBhIHdyaXR0ZW4gcmVwb3J0IHdpdGggYSBtYXhpbXVtIG9mIDQgcGFnZXMgZHVlIGJ5IDU6MDBwbSBFU1Qgb24gV2VkbmVzZGF5LCBKdWx5IDFzdC4gIEJvdGggdGhlIHByZXNlbnRhdGlvbiBhbmQgd3JpdHRlbiBzdWJtaXNzaW9uIHdpbGwgZm9sbG93IHRoZSBzYW1lIHN0cnVjdHVyZTogc3RhcnRpbmcgd2l0aCBhIHN1bW1hcnkgb2Yga2V5IHRha2Vhd2F5cyBhbmQgdGhlbiB3YWxraW5nIHRocm91Z2ggRURBLCB0aGUgbW9kZWxpbmcgcHJvY2VzcywgcmVzdWx0cyBhbmQgY29uY2x1c2lvbnMuICBUZWFtcyB3aWxsIHdvcmsgaW4gZ3JvdXBzIG9mIDIsIGFuZCBkYXRhIHNldHMgd2lsbCBiZSBhc3NpZ25lZCByYW5kb21seS4KClRoZSBnb2FsIG9mIHRoaXMgcHJvamVjdCBpcyB0byBwcmFjdGljZSBwbGFubmluZywgY3JlYXRpbmcsIGV2YWx1YXRpbmcgYW5kIGludGVycHJldGluZyBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbHMgaW4gUi4gIEVhY2ggdGVhbSB3aWxsIGZpdCBhIGxpbmVhciBtb2RlbCB1c2luZyBvbmUgb2YgdGhlIGNvbnRpbnVvdXMgdmFyaWFibGVzIGluIHRoZWlyIHByb3ZpZGVkIGRhdGEgc2V0LiAgTW9kZWxzIHNob3VsZCBiZSB0ZXN0ZWQgd2l0aCBvdXQtb2Ytc2FtcGxlIHByZWRpY3Rpb24gbWV0aG9kcywgYW5kIG11c3QgYmUgaW50ZXJwcmV0YWJsZS4gIE1ha2luZyBhIG1vZGVsIG5lZGxlc2x5IGNvbXBsaWNhdGVkIGNhbiBsZWFkIHRvIG92ZXJmaXR0aW5nIGFuZCBtYWtlIHJlc3VsdHMgZGlmZmljdWx0IHRvIGludGVycHJldC4KClRoZSBmaXJzdCBzbGlkZSBvZiB0aGUgcHJlc2VudGF0aW9uLCBhbmQgZmlyc3QgcGFnZSBvZiB0aGUgd3JpdHRlbiByZXBvcnQsIHdpbGwgYmUgZm9yIGtleSB0YWtlYXdheXMuICBGb3IgdGhlIHByZXNlbnRhdGlvbiB0aGlzIGNhbiBiZSBpbiB0aGUgZm9ybSBvZiBhIHNpbmdsZSBncmFwaCwgYnVsbGV0IHBvaW50cyBvciBhIHN0YXRlbWVudC4gIEZvciB0aGUgd3JpdHRlbiByZXBvcnQgaXQgc2hvdWxkIGJlIGEgY29tYmluYXRpb24gb2YgdGhlIHRocmVlLiAgVGhpcyBpcyB5b3VyIHdvcmsgaW4gZWxldmF0b3IgcGl0Y2ggZm9ybSwgbWVhbnQgdG8gZ3JhYiB0aGUgYXVkaWVuY2VzIGF0dGVudGlvbiBhbmQgZ2l2ZSB0aGVtIGEgcmVhc29uIHRvIGJlIGludGVyZXN0ZWQuICBJbiB0aGUgd29ya2luZyB3b3JsZCB5b3UgbWF5IGhhdmUgb25seSBhIHNob3J0IHRpbWUgdG8gcGl0Y2ggcmVzdWx0cyB0byBzdXBlcmlvcnMsIGFuZCB3aWxsIGhhdmUgdG8gc3RhcnQgd2l0aCB0aGUgY29uY2x1c2lvbnMgYmVmb3JlIGV4cGxhaW5pbmcgeW91ciBwcm9jZXNzLgoKVGhlIHJlc3Qgb2YgdGhlIHByZXNlbnRhdGlvbiwgYW5kIHNlY29uZCBwYWdlIGFuZCBiZXlvbmQgaW4gdGhlIHdyaXR0ZW4gcmVwb3J0IHdpbGwgZm9sbG93IGEgbW9yZSB0cmFkaXRpb25hbCBkYXRhIGFuYXlsc2lzIHJlcG9ydCBmb3JtYXQuICBUaGUgZm9ybWF0IHdpbGwgYmUgYXMgZm9sbG93czoKCi0gSW50cm9kdWN0aW9uIG9mIHRoZSBkYXRhIHNldCAmIHNwb3J0Ci0gRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyBjb25kdWN0ZWQKLSBNb2RlbGluZyBhbmFseXNpcyAmIG1vZGVsIHZhbGlkYXRpb24KICAtIHRoaXMgc3RlcCBpbmNsdWRlcyB2YXJpYWJsZSBzZWxlY3Rpb24sIGVycm9yIHJhdGVzLCBhbmQgY2hlY2tpbmcgZGlhZ25vc3RpYyBwbG90cwotIE1vZGVsIFJlc3VsdHMKICAtIHRoaXMgc3RlcCBzaG91bGQgaW5jbHVkZSBpbnRlcnByZXRhdGlvbiBvZiB0aGUgY29lZmZpY2llbnRzIGluIHRoZSBtb2RlbAotIENvbmNsdXNpb24KCiMjIERlbGl2ZXJhYmxlcyAmIFRpbWVsaW5lCgpUaGVyZSB3aWxsIGJlIDMgZGlmZmVyZW50IGRlbGl2ZXJhYmxlIGRlYWRsaW5lczoKCioqVHVlc2RheSwgSnVuZSAyMyBAIDQ6MDBwbSBFU1QqKiAtIEVhY2ggc3R1ZGVudCB3aWxsIHB1c2ggYW4gUm1hcmtkb3duIGZpbGUgd2l0aCB0aGVpciBhbmFseXNpcyBzbyBmYXIgdG8gdGhpZXIgR2l0SHViIGFjY291bnRzIGZvciByZXZpZXcuICBXZSB3aWxsIHRoZW4gcHJvdmlkZSBmZWVkYmFjayBvbiB0aGUgY29kZSBzdWJtaXR0ZWQuCgoqKkZyaWRheSwgSnVuZSAyNiBAIDEyOjAwcG0gRVNUKiogLSBTbGlkZXMgbXVzdCBiZSBjb21wbGV0ZWQgYW5kIHJlYWR5IGZvciBwcmVzZW50YXRpb24uICBTZW5kIHlvdXIgc2xpZGVzIHRvIE5pY2sncyBlbWFpbCBuY2l0cm9uZUBwaXR0c2J1cmdocGVuZ3VpbnMuY29tIC4gIEFsbCBjb2RlIGFuZCB2aXN1YWxpemF0aW9ucyBtdXN0IGJlIGRvbmUgaW4gUiwgYnV0IHRoZSBzbGlkZXMgbWF5IGJlIGNyZWF0ZWQgaW4gYW55IHByb2dyYW0uICBQcmVzZW50YXRpb25zIHdpbGwgYmUgMTUgbWludXRlcyBsb25nIHdpdGggNSBtaW51dGVzIGZvciBRJkEuCgpBcyBhIHJlbWluZGVyLCB0aGUgcHJlc2VudGF0aW9uIHNob3VsZCBzdGFydCB3aXRoIGEgS2V5IFRha2Vhd2F5IHNsaWRlLCBhbmQgdGhlbiBsZWFkIGludG8gYSB0cmFkaXRpb25hbCBkYXRhIGFuYWx5c2lzIHJlcG9ydCAoSW50cm9kdWN0aW9uLCBFREEsIE1vZGVsaW5nLCBSZXN1bHRzLCBDb25jbHVzaW9uKQoKKipXZWRuZXNkYXksIEp1bHkgMSBAIDU6MDBwbSBFU1QqKiAtIEVhY2ggdGVhbSdzIGZpbmFsIHdyaXR0ZW4gcmVwb3J0IG11c3QgYmUgZW1haWxlZCB0byBOaWNrJ3MgZW1haWwgbmNpdHJvbmVAcGl0dHNidXJnaHBlbmd1aW5zLmNvbSAuCgpBcyBhIHJlbWluZGVyLCB0aGUgd3JpdHRlbiByZXBvcnQgd2lsbCBoYXZlIHRoZSAnbW9kZWwgcGl0Y2gnIG9uIHRoZSBmaXJzdCBwYWdlLCB3aGljaCBpcyBhIHNob3J0IGV4ZWN1dGl2ZSBzdW1tYXJ5IGFuZCBwb3RlbnRpYWxseSBhIGtleSBncmFwaGljLiAgVGhlIHNlY29uZCBwYWdlIGFuZCBiZXlvbmQgb2YgdGhlIHdyaXR0ZW4gZmlsZSB3aWxsIGZvbGxvdyB0aGUgdHJhZGl0aW9uYWwgZGF0YSBhbmFseXNpcyByZXBvcnQgZm9ybWF0IChJbnRyb2R1Y3Rpb24sIEVEQSwgTW9kZWxpbmcsIFJlc3VsdHMsIENvbmNsdXNpb24pLiAgVGhlc2UgbGFzdCBwYWdlcyBzaG91bGQgc2V0IHVwIGFuZCBzdXBwb3J0IHlvdXIga2V5IHRha2Vhd2F5cy4KCiMjIE5vdGVzCgpBbHRob3VnaCB0aGlzIHByb2plY3Qgd2lsbCB1c2Ugc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uLCBmZWVsIGZyZWUgdG8gY29udGFjdCBhbnkgb2YgdGhlIGluc3RydWN0b3JzIGlmIHlvdSBoYXZlIHF1ZXN0aW9ucyBhYm91dCBwb3RlbnRpYWwgR0xNIChwb2lzc29uLCBsb2dpc3RpYykgbW9kZWxzIHVzaW5nIGFueSBvZiB0aGUgZGF0YSBzZXRzIHByb3ZpZGVkLgoKIyMgRGF0YSBTZXRzCgpUaGVyZSBhcmUgZWlnaHQgZGlmZmVyZW50IGRhdGFzZXRzIGZvciB0aGUgcmVncmVzc2lvbiBwcm9qZWN0cyAodGhyZWUgb2Ygd2hpY2ggd2VyZSBnZW5lcmF0ZWQgdmlhIHRoZSBbYGluaXRfcmVncmVzc2lvbl9wcm9qZWN0X2RhdGEuUmBdKGh0dHBzOi8vZ2l0aHViLmNvbS9yeXVya28vQ01TQUNhbXAyMDIwL2Jsb2IvbWFzdGVyL1IvaW5pdF9kYXRhL2luaXRfcmVncmVzc2lvbl9wcm9qZWN0X2RhdGEuUikgc2NyaXB0KToKICAKKiBbbmJhX3RlYW1fc2Vhc29uX3N1bW1hcnkuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL3JlZ3Jlc3Npb25fcHJvamVjdHMvbmJhX3RlYW1fc2Vhc29uX3N1bW1hcnkuY3N2KSAtIHN1bW1hcnkgb2YgcmVndWxhciBzZWFzb24gcGVyZm9ybWFuY2UgZm9yIGVhY2ggTkJBIHRlYW0gc2luY2UgMjAwMywgY291cnRlc3kgb2YgW05CQSBzdGF0c10oaHR0cHM6Ly9zdGF0cy5uYmEuY29tLykgdmlhIHRoZSBbJ25iYXN0YXRSIHBhY2thZ2UnXShodHRwOi8vYXNiY2xsYy5jb20vbmJhc3RhdFIvaW5kZXguaHRtbCksCiogW3Rlbm5pc18yMDEzXzIwMTdfR1MuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL3JlZ3Jlc3Npb25fcHJvamVjdHMvdGVubmlzXzIwMTNfMjAxN19HUy5jc3YpIC0gdGVubmlzIGdyYW5kIHNsYW0gc3RhdGlzdGljcyBmb3IgMzA2NiBBVFAgYW5kIFdUQSBtYXRjaGVzIGJldHdlZW4gMjAxMyBhbmQgMjAxNy4gIERhdGEgZnJvbSBKZWZmIFNhY2ttYW4ncyBbdGVubmlzIGRhdGEgcmVwb10oaHR0cHM6Ly9naXRodWIuY29tL0plZmZTYWNrbWFubiksIHJldHJlaXZlZCBieSBTdGVwaGFuaWUgS292YWxjaGlrJ3MgW2BSIGRldWNlYCBwYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vc2tvdmFsL2RldWNlL2Jsb2IvbWFzdGVyL0RFU0NSSVBUSU9OKSwgYW5kIHN5bnRoZXNpemVkIGluIEdhbGxhZ2hlciwgRnJpc29saSwgYW5kIEx1YnkncyBbYFIgY291cnRzcG9ydHNgIHBhY2thZ2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9zaGFubm9uZzE5L2NvdXJ0c3BvcnRzKS4KKiBbYmFzZWJhbGxfYmF0dGluZy5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvcmVncmVzc2lvbl9wcm9qZWN0cy9iYXNlYmFsbF9iYXR0aW5nLmNzdikgLSBNTEIgcGxheWVyIHNlYXNvbiBsZXZlbCBiYXR0aW5nIHN0YXRpc3RpY3MgZm9yIDE0MjkgcGxheWVyLXNlYXNvbnMgZnJvbSAyMDEwIHRvIDIwMTkuICBEYXRhIGdlbmVyYXRlZCBieSBGYW5HcmFwaHMgYW5kIGFjY2Vzc2VkIGNvdXJ0ZXN5IG9mIHRoZSBbYGJhc2ViYWxscmAgcGFja2FnZV0oaHR0cDovL2JpbGxwZXR0aS5naXRodWIuaW8vYmFzZWJhbGxyLyksCiogW2NmYl8yMDE5X2dhbWVzLmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9yZWdyZXNzaW9uX3Byb2plY3RzL2NmYl8yMDE5X2dhbWVzLmNzdikgLSBSZXN1bHRzIGZyb20gYWxsIE5DQUEgRDEgQ29sbGVnZSBGb290YmFsbCBnYW1lcyBpbiAyMDE5LiAgSW5jbHVkZXMgdGVhbSBkYXRhLCBmaW5hbCBzY29yZSBhbmQgYW4gZXhjaXRlbWVudCByYXRpbmcgZm9yIHRoZSBnYW1lLiAgRGF0YSBhY2Nlc3NlZCB2aWEgdGhlIFtgY2Zic2NyYXBSYCBwYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vbWV5c3ViYi9jZmJzY3JhcFIpLAoqIFtvdmVyd2F0Y2hfb2Rkcy5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvcmVncmVzc2lvbl9wcm9qZWN0cy9vdmVyd2F0Y2hfb2Rkcy5jc3YpIC0gT3ZlcndhdGNoIEUtU3BvcnRzIExlYWd1ZSBoZWFkIHRvIGhlYWQgbWF0Y2ggcmVzdWx0cyB3aXRoIGJldHRpbmcgb2RkcyBkYXRhLiBEYXRhIGZyb20gW0thZ2dsZSdzIEUtU3BvcnRzIERhdGEgU2V0c10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9tZGFiYmVydC9vdmVyd2F0Y2gtbGVhZ3VlLXdpdGgtb2Rkcy9kYXRhKSwKKiBbd29tZW5zX25jYWFfc29jY2VyXzIwMTgyMDE5LmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9yZWdyZXNzaW9uX3Byb2plY3RzL3dvbWVuc19uY2FhX3NvY2Nlcl8yMDE4MjAxOS5jc3YpIC0gTkNBQSBXb21lbidzIEQxIHNvY2NlciBvZmZlbnNpdmUgYW5kIGRlZmVuc2l2ZSB0ZWFtIHN0YXRpc3RpY3MgZnJvbSB0aGUgMjAxOCBhbmQgMjAxOSBzZWFzb25zLiAgRGF0YSBhY3F1aXJlZCBmcm9tIFtOQ0FBLmNvbV0oaHR0cHM6Ly93d3cubmNhYS5jb20pLgoqIFt3b21lbnNfbmNhYV92b2xsZXliYWxsXzIwMTgyMDE5LmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9yZWdyZXNzaW9uX3Byb2plY3RzL3dvbWVuc19uY2FhX3ZvbGxleWJhbGxfMjAxODIwMTkuY3N2KSAtIE5DQUEgV29tZW4ncyBEMSB2b2xsZXliYWxsIG9mZmVuc2l2ZSBhbmQgZGVmZW5zaXZlIHRlYW0gc3RhdGlzdGljcyBmcm9tIHRoZSAyMDE4IGFuZCAyMDE5IHNlYXNvbnMuICBEYXRhIGFjcXVpcmVkIGZyb20gW05DQUEuY29tXShodHRwczovL3d3dy5uY2FhLmNvbSkuCiogW3dvbWVuc19uY2FhX2xhY3Jvc3NlLmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9yZWdyZXNzaW9uX3Byb2plY3RzL3dvbWVuc19uY2FhX2xhY3Jvc3NlLmNzdikgLSBOQ0FBIFdvbWVuJ3MgRDEgbGFjcm9zc2Ugb2ZmZW5zaXZlIGFuZCBkZWZlbnNpdmUgdGVhbSBzdGF0aXN0aWNzIGZyb20gdGhlIDIwMTgsIDIwMTkgYW5kIHNob3J0ZW5lZCAyMDIwIHNlYXNvbnMuICBEYXRhIGFjcXVpcmVkIGZyb20gW05DQUEuY29tXShodHRwczovL3d3dy5uY2FhLmNvbSkuCgojIyMgTkJBIHRlYW0gc2Vhc29uIHN1bW1hcnkgZGF0YQoKRWFjaCByb3cgaW4gdGhlIFtuYmFfdGVhbV9zZWFzb25fc3VtbWFyeS5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvcmVncmVzc2lvbl9wcm9qZWN0cy9uYmFfdGVhbV9zZWFzb25fc3VtbWFyeS5jc3YpIGRhdGFzZXQgY29ycmVzcG9uZHMgdG8gYSBzaW5nbGUgTkJBIHRlYW0gaW4gYSBzaW5nbGUgcmVndWxhcgpzZWFzb24gZGF0aW5nIGJhY2sgdG8gMjAwMy4gVGhlIGNvbHVtbiBuYW1lcyBzZWxmLWV4cGxhbmF0b3J5LCBidXQgbm90ZSB0aGF0IHRoZSBjb2x1bW5zIGVuZGluZyB3aXRoCmAqX3BlcmNgIG1lYW4gdGhlIHBlcmNlbnRhZ2UgYmFzZWQgc3RhdGlzdGljcy4KCiMjIyBUZW5uaXMgZ3JhbmQgc2xhbXMgZGF0YQoKRWFjaCByb3cgaW4gdGhlIGRhdGEgY29ycmVzcG9uZHMgdG8gYSBncmFuZCBzbGFtIG1hdGNoIGJldHdlZW4gdHdvIHBsYXllcnMuICBBIHZhcmlldHkgb2Ygc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBtYXRjaCBhcmUgcmVwb3J0ZWQgYWxvbmcgd2l0aCB3aW5uZXIgYW5kIGxvc2VyIGluZm9ybWF0aW9uLiAgVmFyaWFibGVzIGluY2x1ZGU6CgoqIGB0b3VybmFtZW50YCAtIG9uZSBvZiB0aGUgZm91ciBncmFuZCBzbGFtczogQXVzdHJhbGlhbiBPcGVuLCBGcmVuY2ggT3BlbiwgVVMgT3BlbiwgYW5kIFdpbWJsZWRvbgoqIGB5ZWFyYAoqIGB3aW5uZXJfbmFtZWAgYW5kIGBsb3Nlcl9uYW1lYAoqIGB3aW5uZXJfcmFua2AgYW5kIGBsb3Nlcl9yYW5rYCBhY2NvcmRpbmcgdG8gQVRQIG9yIFdUQSwgcmVzcGVjdGl2ZWx5IGF0IHRoZSB0aW1lIG9mIHRvdXJuYW1lbnQKKiBgUmV0aXJlbWVudGAgICB3aGV0aGVyIHRoZSBtYXRjaCBlbmRlZCBpbiBhIHJldGlyZW1lbnQgKGkuZS4gb25lIHBlcnNvbiB3YXMgdW5hYmxlIHRvIGZpbmlzaCB0aGUgbWF0Y2gpLiAgTG9naWNhbCAtLSBUUlVFIG1lYW5zIHRoZSBtYXRjaCBlbmRlZCBpbiByZXRpcmVtZW50CiogYFRvdXJgIGVpdGhlciBXVEEgb3IgQVRQCiogYHJvdW5kYCAtIGBSMTI4YCBSb3VuZCBvZiAxMjgsIGBSNjRgIC0gUm91bmQgb2YgNjQsIGBSMzJgIC0gUm91bmQgb2YgMzIsIGBSMTZgIFJvdW5kIG9mIDE2LCBgUUZgIFF1YXJ0ZXIgRmluYWwsIGBTRmAgU2VtaSBGaW5hbCwgYW5kIGBGYCBGaW5hbCAgICAgCiogYHdfKmAgYW5kIGBsXypgIHN0YW5kcyBmb3Igd2lubmVyIGFuZCBsb3NlciwgcmVzcGVjdGl2ZWx5IHdoZXJlIHRoZSBzdWZmaXggaXMgb25lIG9mIG1hbnkgc3VtbWFyeSBzdGF0aXN0aWNzIGluY2x1ZGluZwoqIGBhdmVfc2VydmVfc3BlZWRgICAgIGluIG1waAoqIGBuX2FjZXNgIG51bWJlciBvZiBhY2VzCiogYG5fd2lubmVyc2AgbnVtYmVyIG9mIHdpbm5lcnMgaW5jbHVkaW5nIGFjZXMKKiBgbl9uZXRwdF93YCBudW1iZXIgb2YgbmV0IHBvaW50cyB3b24KKiBgbl9uZXRwdGAgbnVtYmVyIG9mIG5ldCBwb2ludHMgcGxheWVkCiogYG5fYnBfd2AgbnVtYmVyIG9mIGJyZWFrIHBvaW50cyB3b24gKHRvIGJyZWFrIHRoZSBvcHBvbmVudCkKKiBgbl9icGAgbnVtYmVyIG9mIGJyZWFrIHBvaW50cyAodG8gYnJlYWsgdGhlIG9wcG9uZW50KQoqIGBuX3VlYCBudW1iZXIgb2YgdW5mb3JjZWQgZXJyb3JzCiogYG5fc3ZgIG51bWJlciBvZiBzZXJ2ZXMKKiBgbl9zdl93YCBudW1iZXIgb2Ygc2VydmljZSBwb2ludHMgd29uCgojIyMgTUxCIEJhdHRpbmcgU3RhdGlzdGljcyAyMDEwLTIwMTkKCkVhY2ggcm93IGluIHRoZSBbYmFzZWJhbGxfYmF0dGluZy5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvcmVncmVzc2lvbl9wcm9qZWN0cy9iYXNlYmFsbF9iYXR0aW5nLmNzdikgZGF0YSBjb3JyZXNwb25kcyB0byB0aGUgYmF0dGluZyBzdGF0aXN0aWNzIGZvciBhIHNpbmdsZSBwbGF5ZXIgaW4gYSBzaW5nbGUgc2Vhc29uIGJldHdlZW4gMjAxMCBhbmQgMjAxOS4gIFRIZSBmaXJzdCBmZXcgdmFyaWFibGVzIGFzIHdlbGwgYXMgdGhlIHNpbmdsZXMsIGRvdWJsZXMgYW5kIHRyaXBsZXMgYXJlIHNlbGYtZXhwbGFuYXRvcnksIGFuZCB0aGUgb3RoZXIgYmFzZWJhbGwgdmFyaWFibGVzIG1lYW4gYXMgZm9sbG93czoKCiogYEdgIGdhbWVzIHBsYXllZAoqIGBBQmAgYXQgYmF0czogUGxhdGUgYXBwZWFyYW5jZXMsIG5vdCBpbmNsdWRpbmcgYmFzZXMgb24gYmFsbHMsIGJlaW5nIGhpdCBieSBwaXRjaCwgc2FjcmlmaWNlcywgaW50ZXJmZXJlbmNlLCBvciBvYnN0cnVjdGlvbi4KKiBgUEFgIHBsYXRlIGFwcGVhcmFuY2VzCiogYEhgIGhpdHMKKiBgSFJgIGhvbWUgcnVucwoqIGBSYCBydW5zIHNjb3JlZDsgdGhlIG51bWJlciBvZiB0aW1lcyBhIHBsYXllciBjcm9zc2VzIGhvbWUgcGxhdGUKKiBgUkJJYCBydW5zIGJhdHRlZCBpbjogdGhlIG51bWJlciBvZiBydW5uZXJzIHdobyBzY29yZSBkdWUgdG8gYSBiYXR0ZXIncyBhY3Rpb24KKiBgQkJgIHdhbGtzICdiYXNlIG9uIGJhbGxzJwoqIGBJQkJgIGludGVudGlvbmFsIGJhc2Ugb24gYmFsbHMsIHRpbWVzIHdhbGtlZCBpbnRlbnRpb25hbGx5IGJ5IHBpdGNoZXIKKiBgSEJQYCBoaXQgYnkgcGl0Y2g6IHdhbGtlZCBhcyBhIHJlc3VsdCBvZiBiZWluZyBoaXQgYnkgYSBwaXRjaAoqIGBTRmAgc2FjcmlmaWNlIGZseTogZmx5IGJhbGxzIGhpdCB0byB0aGUgb3V0ZmllbGQgd2hpY2ggYWx0aG91Z2ggY2F1Z2h0IGZvciBhbiBvdXQsIGFsbG93IGEgYmFzZXJ1bm5lciB0byBhZHZhbmNlCiogYFNIYCBzYWNyaWZpY2UgaGl0OiBudW1iZXIgb2Ygc2FjcmlmaWNlIGJ1bnRzIHdoaWNoIGFsbG93IHJ1bm5lcnMgdG8gYWR2YW5jZSBvbiB0aGUgYmFzZXBhdGhzCiogYEdEUGAgZ3JvdW5kIGludG8gZG91YmxlLXBsYXk6IG51bWJlciBvZiBncm91bmQgYmFsbHMgdGhhdCBiZWNhbWUgZG91YmxlIHBsYXlzCiogYFNCYCBzdG9sZW4gYmFzZXMKKiBgQ1NgIG51bWJlciBvZiB0aW1lcyBjYXVnaHQgc3RlYWxpbmcKKiBgQVZHYCBiYXR0aW5nIGF2ZXJhZ2UKKiBgUGl0Y2hlc2AgbnVtYmVyIG9mIHBpdGNoZXMgZmFjZWQKKiBgQmFsbHNgIG51bWJlciBvZiBiYWxscyBmYWNlZAoqIGBTdHJpa2VzYCBudW1iZXIgb2Ygc3RyaWtlcyBmYWNlZAoqIGBTT2Agc3RyaWtlIG91dHMKKiBgQkJfS2Agd2Fsa3MgLyBzdHJpa2Ugb3V0cy4gIFdhbGsgdG8gc3RyaWtlIG91dCByYXRpbwoqIGBPQlBgIG9uIGJhc2UgcGVyY2VudGFnZQoqIGBTTEdgIHNsdWdnaW5nIGF2ZXJhZ2U6IHRvdGFsIGJhc2VhcyBhY2hpZXZlZCBvbiBoaXRzIC8gYXQgYmF0cwoqIGBPUFNgIG9uLWJhc2UgcGx1cyBzbHVnZ2luZzogb24tYmFzZSBwZXJjZW50YWdlIHBsdXMgc2x1Z2dpbmcgYXZlcmFnZQoqIGBJU09gIGlzb2xhdGVkIHBvd2VyOiBhIGhpdHRlcidzIGFiaWxpdHkgdG8gaGl0IGZvciBleHRyYSBiYXNlcywgY2FsY3VsYXRlZCBieSBzdWJ0cmFjdGluZyBiYXR0aW5nIGF2ZXJhZ2UgZnJvbSBzbHVnZ2luZyBwZXJjZW50YWdlCiogYHdPQkFgIHdlaWdodGVkIG9uIGJhc2UgYXZlcmFnZQoqIGBXQVJgIHdpbnMgYWJvdmUgcmVwbGFjZW1lbnQ6IGEgbm9uLXN0YW5kYXJkIGZvcm11bGEgdG8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2Ygd2lucyBhIHBsYXllciBjb250cmlidXRlcyB0byBoaXMgdGVhbSBvdmVyIGEgInJlcGxhY2VtZW50LWxldmVsIHBsYXllciIKKiBgV1BBX3BsdXNgIHdpbiBwcm9iYWJpbGl0eSBhZGRlZCwgcG9zaXRpdmUgdG90YWwKKiBgV1BBX21pbnVzYCB3aW4gcHJvYmFiaWxpdHkgYWRkZWQsIG5lZ2F0aXZlIHRvdGFsCgojIyMgTkNBQSBDb2xsZWdlIEZvb3RiYWxsIEQxIDIwMTkKCkVhY2ggcm93IGluIHRoZSBbY2ZiXzIwMTlfZ2FtZXMuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL3JlZ3Jlc3Npb25fcHJvamVjdHMvY2ZiXzIwMTlfZ2FtZXMuY3N2KSBkYXRhIHNldCByZWZlcnMgdG8gYSBzaW5nbGUgZ2FtZSBwbGF5ZWQgYmV0d2VlbiB0d28gTkNBQSBEMSBzY2hvb2xzCmR1cmluZyB0aGUgMjAxOSBzZWFzb24uICBNb3N0IG9mIHRoZSB2YXJpYWJsZXMgYXJlIHNlbGYtZXhwbGFuYXRvcnkuICBWZW51ZSBhbmQgdGVhbSBpZHMgaGF2ZSBiZWVuIHByb3ZpZGVkIGJ1dCB3aWxsIG5vdCBuZWNlc3NhcmlseSBiZSBuZWVkZWQuICBUaGUgZGVmaW5pdGlvbnMgZm9yIGxlc3MgY2xlYXIgdmFyaWFibGVzIGFyZSBhc2wgZm9sbG93czoKCiogYGlkYCBnYW1lIGlkCiogYG5ldHVyYWxfc2l0ZWAgd2FzIHRoZSBnYW1lIHBsYXllZCBvbiBhIG5ldXRyYWwgc2l0ZSwgbWVhbmluZyBhdCBuZWl0aGVyIHRlYW0ncyBob21lIHN0YWRpdW0/CiogYGNvbmZlcmVuY2VfZ2FtZWAgaXMgdGhlIGdhbWUgYmV0d2VlbiB0d28gb3Bwb25lbnRzIGZyb20gdGhlIHNhbWUgY29uZmVyZW5jZT8KKiBgZXhjaXRlbWVudF9pbmRleGAgYSBudW1lcmljYWwgdmFsdWUgbWVhc3VyaW5nIHRoZSBleGNpdGVtZW50IG9mIHRoZSBnYW1lLCBjYWxjdWxhdGVkIHVzaW5nIHdpbiBwcm9iYWJpbGl0eSB0aHJvdWdob3V0IHRoZSBnYW1lLgoqIGBob21lXzFfcHRzYCAtIGBob21lXzRfcHRzYCB0aGUgYW1vdW50IG9mIHBvaW50cyBzY29yZWQgYnkgdGhlIGhvbWUgdGVhbSBpbiB0aGUgMXN0LzJuZC8zcmQvNHRoIHF1YXJ0ZXJzCiogYGF3YXlfMV9wdHNgIC0gYGF3YXlfNF9wdHNgIHRoZSBhbW91bnQgb2YgcG9pbnRzIHNjb3JlZCBieSB0aGUgYXdheSB0ZWFtIGluIHRoZSAxc3QvMm5kLzNyZC80dGggcXVhcnRlcnMKCiMjIyBPdmVyd2F0Y2ggTGVhZ3VlIFJlc3VsdHMgYW5kIE9kZHMKCkVhY2ggcm93IGluIHRoZSBbb3ZlcndhdGNoX29kZHMuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL3JlZ3Jlc3Npb25fcHJvamVjdHMvb3ZlcndhdGNoX29kZHMuY3N2KSBkYXRhIHNldCBjb250YWlucyBkYXRhIG9uIGEgc2luZ2xlIE92ZXJ3YXRjaCBMZWFndWUgbWF0Y2ggcGxheWVkIGJldHdlZW4gMjAxOCBhbmQgMjAyMC4gIERhdGEgaW5jbHVkZXMgdGhlIHR3byB0ZWFtcywgc3RhZ2UsIHdpbm5lciwgYXMgd2VsbCBhcyBpbmZvcm1hdGlvbiBvbiB0aGUgdHdvIHRlYW1zIHN1Y2Nlc3MgaW4gdGhlIHNlYXNvbiB0aHVzIGZhciBhbmQgaW4gdGhlaXIgaGlzdG9yeSB1cCB1bnRpbCB0aGF0IHBvaW50LiAgQ29sdW1ucyBpbmNsdWRlOgoKKiBgaWRgIGdhbWUgaWQKKiBgY29yb25hX3ZpcnVzX2lzb2xhdGlvbmAgd2FzIHRoZSBnYW1lIHBsYXllZCB1bmRlciBjb3JvbmEgdmlydXMgaXNvbGF0aW9uIG1lYXN1cmVzPwoqIGB0MV93aW5zX3NlYXNvbmAgXCBgdDJfd2luc19zZWFzb25gIGhvdyBtYW55IGdhbWVzIHRlYW0gMSBoYXMgd29uIGluIHRoZSBzZWFzb24gcHJpb3IgdG8gdGhlIGdhbWUgKHQyIGZvciB0ZWFtIDIpCiogYHQxX2xvc3Nlc19zZWFzb25gIFwgYHQyX2xvc3Nlc19zZWFzb25gIGhvdyBtYW55IGdhbWVzIHRlYW0gMSBoYXMgbG9zdCBpbiB0aGUgc2Vhc29uIHByaW9yIHRvIHRoZSBnYW1lICh0MiBmb3IgdGVhbSAyKQoqIGB0MV93aW5fcGVyY2VudGAgdGVhbSAxICh0MiBmb3IgdGVhbSAyKSB3aW4gcGVyY2VudGFnZSBpbiB0aGUgc2Vhc29uLCBpbiB0aGUgbGFzdCBYIGdhbWVzIG9yIGFsbC10aW1lIGRlcGVuZGluZyBvbiB2YXJpYWJsZSBuYW1lCiogYHQxX29kZHNgIGJldHRpbmcgb2RkcyBmb3IgdGVhbSAxIHRvIHdpbiB0aGUgZ2FtZS4KClBvc2l0aXZlIGZpZ3VyZXM6IFRoZSBvZGRzIHN0YXRlIHRoZSB3aW5uaW5ncyBvbiBhIDEwMCBkb2xsYXIgYmV0IChlLmcuIGFtZXJpY2FuIG9kZHMgb2YgMTEwIHdvdWxkIHdpbiAxMTAgb24gYSAxMDAgZG9sbGFyIGJldC4pCgpOZWdhdGl2ZSBmaWd1cmVzOiBUaGUgb2RkcyBzdGF0ZSBob3cgbXVjaCBtdXN0IGJlIGJldCB0byB3aW4gMTAwIHByb2ZpdCAoZS5nLiBhbWVyaWNhbiBvZGRzIG9mIC05MCB3b3VsZCB3aW4gMTAwIG9uIGEgOTAgZG9sbGFyIGJldC4pCgoqIGB0Ml9vZGRzYCBiZXR0aW5nIG9kZHMgZm9yIHRlYW0gMiB0byB3aW4gdGhlIGdhbWUKKiBgdDFfcHJvYmFiaWxpdHlgIHRoZSBpbXBsaWVkIHdpbiBwcm9iYWJpbGl0eSBmb3IgdGVhbSAxIGdpdmVuIHRoZSBiZXR0aW5nIG9kZHMKKiBgdDJfcHJvYmFiaWxpdHlgIHRoZSBpbXBsaWVkIHdpbiBwcm9iYWJpbGl0eSBmb3IgdGVhbSAyIGdpdmVuIHRoZSBiZXR0aW5nIG9kZHMKCiMjIyBXb21lbidzIE5DQUEgRDEgU29jY2VyIDIwMTggJiAyMDE5IFRlYW0gU3RhdGlzdGljcwoKRWFjaCByb3cgaW4gdGhlIFt3b21lbnNfbmNhYV9zb2NjZXJfMjAxODIwMTkuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL3JlZ3Jlc3Npb25fcHJvamVjdHMvd29tZW5zX25jYWFfc29jY2VyXzIwMTgyMDE5LmNzdikgZGF0YSBzZXQgcmVmZXJzIHRvIHRoZSBzdGF0aXN0aWNzIGZvciBhIHNpbmdsZSBzY2hvb2wgaW4gYSBwYXJ0aWN1bGFyIHNlYXNvbi4gIFRoZXJlIGFyZSA2NjggdGVhbS1zY2hvb2wgY29tYmluYXRpb25zIHNwYW5uaW5nIDIwMTggYW5kIDIwMTkuICBWYXJpYWJsZXMgaW5jbHVkZToKCiogYGFzc2lzdHNgIHRoZSB0b3RhbCBudW1iZXIgb2YgYXNzaXN0cyBlYXJuZWQgYnkgcGxheWVycyBvbiB0aGUgdGVhbQoqIGB0ZWFtX2dhbWVzYCBnYW1lcyBwbGF5ZWQKKiBgYXNzaXN0c19ncGAgdG90YWwgYXNzaXN0cyBlYXJuZWQgcGVyIGdhbWUgcGxheWVkCiogYGNvcm5lcnNgIGNvcm5lciBraWNrcyB0YWtlbi4gIFRoaXMgdmFyaWFibGUgaXMgdW5hdmFpbGFibGUgZm9yIDIwMTgKKiBgY29ybmVyc19ncGAgY29ybmVyIGtpY2tzIHRha2VuIHBlciBnYW1lIHBsYXllZC4gICBUaGlzIHZhcmlhYmxlIGlzIHVuYXZhaWxhYmxlIGZvciAyMDE4CiogYGZvdWxzYCB0b3RhbCBmb3VscyBjYWxsZWQgb24gdGhlIHRlYW0uCiogYGZvdWxzX2dwYCBmb3VscyBjYWxsZWQgb24gdGhlIHRlYW0gcGVyIGdhbWUgcGxheWVkCiogYGdhYCBnb2FscyBhZ2FpbnN0CiogYHRlYW1fbWluYCB0b3RhbCBtaW51dGVzIHBsYXllZCBieSB0aGUgdGVhbSwgaW5jbHVkaW5nIHN0b3BwYWdlIHRpbWUKKiBgZ2FhYCBnb2FscyBhZ2FpbnN0IHBlciBnYW1lIHBsYXllZAoqIGBwc2AgcGVuYWx0eSBraWNrcyBzY29yZWQgb24KKiBgcHNhdHRgIHBlbmFsdHkga2lja3MgYXR0ZW1wdGVkCiogYHBrX3BjdGAgcGVyY2VudGFnZSBvZiBwZW5hbHR5IGtpY2tzIGNvbXBsZXRlZAoqIGBwb2ludHNgIHRvdGFsIHBvaW50cyAoZ29hbHMgKyBhc3Npc3RzKSBhY2N1bXVsYXRlZCBmb3IgYWxsIHBsYXllcnMgb24gdGhlIHRlYW0KKiBgcG9pbnRzX2dwYCBwb2ludHMgYWNjdW11bGF0ZWQgYnkgcGxheWVycyBvbiB0aGUgdGVhbSAgcGVyIGdhbWUgcGxheWVkCiogYHNhdmVzYCBzYXZlcyBtYWRlIGJ5IHRlYW0gZ29hbGtlZXBlcnMKKiBgc2F2ZV9wY3RgIHBlcmNlbnRhZ2Ugb2Ygc2hvdHMgZmFjZWQgdGhhdCBnb2Fsa2VlcGVycyBzYXZlZAoqIGBzYXZlc19ncGAgbnVtYmVyIG9mIHNhdmVzIG1hZGUgcGVyIGdhbWUgcGxheWVkCiogYGdvYWxzYCB0b3RhbCBnb2FscyBzY29yZWQgYnkgdGVhbQoqIGBncGdgIHRoZSBudW1iZXIgb2YgZ29hbHMgc2NvcmVkIGJ5IHRoZSB0ZWFtIHBlciBnYW1lIHBsYXllZAoqIGBzb2dgIHRvdGFsIHNob3RzIG9uIGdvYWwKKiBgc2hhdHRgIHRvdGFsIHNob3QgYXR0ZW1wdHMKKiBgc29nX3BjdGAgcGVyY2VudGFnZSBvZiBzaG90IGF0dGVtcHRzIHRoYXQgd2VyZSBvbiBnb2FsCiogYHdvbmAgZ2FtZXMgd29uCiogYGxvc3RgIGdhbWVzIGxvc3QKKiBgdGllZGAgZ2FtZXMgdGllZAoqIGB3aW5fcGN0YCB3aW5uaW5nIHBlcmNlbnRhZ2UKKiBgc29nX2dwYCBudW1iZXIgb2Ygc2hvdHMgb24gZ29hbCBwZXIgZ2FtZSBwbGF5ZWQKKiBgc2Vhc29uYCB0aGUgc2Vhc29uIHRoZSBkYXRhIHJlZmVycyB0bwoKCgojIyMgV29tZW4ncyBOQ0FBIEQxIFZvbGxleWJhbGwgMjAxOCAmIDIwMTkgVGVhbSBTdGF0aXN0aWNzCgpFYWNoIHJvdyBpbiB0aGUgW3dvbWVuc19uY2FhX3ZvbGxleWJhbGxfMjAxODIwMTkuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL3JlZ3Jlc3Npb25fcHJvamVjdHMvd29tZW5zX25jYWFfdm9sbGV5YmFsbF8yMDE4MjAxOS5jc3YpIGRhdGEgc2V0IHJlZmVycyB0byB0aGUgc3RhdGlzdGljcyBmb3IgYSBzaW5nbGUgc2Nob29sIGluIGEgcGFydGljdWxhciBzZWFzb24uICBUaGVyZSBhcmUgNjY2IHRlYW0tc2Nob29sIGNvbWJpbmF0aW9ucyBzcGFubmluZyAyMDE4IGFuZCAyMDE5LiAgVmFyaWFibGVzIGluY2x1ZGU6CgoqIGBzYCBudW1iZXIgb2Ygc2V0cyBwbGF5ZWQKKiBgYWNlc2AgYWNlcyBoaXQuICBBbiBhY2UgaXMgYSBzZXJ2ZSB3aGljaCBsYW5kcyBpbiB0aGUgb3Bwb25lbnQncyBjb3VydCB3aXRob3V0IGJlaW5nIHRvdWNoZWQsIG9yIGlzIHRvdWNoZWQsIGJ1dCB1bmFibGUgdG8gYmUga2VwdCBpbiBwbGF5IGJ5IG9uZSBvciBtb3JlIHJlY2VpdmluZyB0ZWFtIHBsYXllcnMKKiBgYWNlc19wZXJfc2V0YCBhY2VzIGVhcm5lZCBwZXIgc2V0IHBsYXllZAoqIGBhc3Npc3RzYCB0b3RhbCB0ZWFtIGFzc2lzdHMuICBBc3Npc3RzIGFyZSBhd2FyZGVkIHRvIGEgcGxheWVyIHdobyBwYXNzZXMgdGhlIGJhbGwgdG8gYSB0ZWFtbWF0ZSB3aG8gYXR0YWNrcyB0aGUgYmFsbCBmb3IgYSBraWxsLiAgQ2FuIGJlIGF3YXJkZWQgb2ZmIGEgZGlnIChmaXJzdCBjb250YWN0KSwgcHJvdmlkZWQgdGhlIGF0dGFjayBjb21lcyBvbiB0aGUgc2Vjb25kIGNvbnRhY3QKKiBgYXNzaXN0c19wZXJfc2V0YCBhc3Npc3RzIGVhcm5lZCBwZXIgc2V0IHBsYXllZAoqIGBibG9ja19zb2xvc2AgIHRvdGFsIHRlYW0gc29sbyBibG9ja3MuICBQbGF5ZXJzIGJsb2NrcyB0aGUgYmFsbCBpbnRvIHRoZSBvcHBvbmVudCdzIGNvdXJ0IGxlYWRpbmcgdG8gYSBwb2ludCBvciBzaWRlIG91dAoqIGBibG9ja19hc3Npc3RzYCB0b3RhbCB0ZWFtIGFzc2lzdGVkIGJsb2NrcwoqIGBibG9ja3NfcGVyX3NldGAgdG90YWwgdGVhbSBibG9ja3MgcGVyIHNldAoqIGBkaWdzYCB0b3RhbCB0ZWFtIGRpZ3MuICBBIGRpZyBvY2N1cnMgd2hlbiBhIHBsYXllciBwYXNzZXMgdGhlIGJhbGwgd2hpY2ggaGFzIGJlZW4gYXR0YWNrZWQgYnkgdGhlIG9wcG9zaXRpb24uICBEaWdzIGFyZSBvbmx5IGdpdmVuIHdoZW4gcGxheWVycyByZWNlaXZlIGFuIGF0dGFja2VkIGJhbGwgYW5kIGl0IGlzIGtlcHQgaW4gcGxheQoqIGBkaWdzX3Blcl9zZXRgIHRlYW0gZGlncyBwZXIgc2V0IHBsYXllZAoqIGBraWxsc2AgdGVhbSBraWxscy4gIEFuIGF0dGFjayBieSBhIHBsYXllciB0aGF0IGlzIG5vdCByZXR1cm5hYmxlIGJ5IHRoZSByZWNlaXZpbmcgcGxheWVyIG9uIHRoZSBvcHBvc2luZyB0ZWFtIGFuZCBsZWFkcyBkaXJlY3RseSB0byBhIHBvaW50IG9yIGxvc3Mgb2YgcmFsbHkKKiBgZXJyb3JzYCB0b3RhbCB0ZWFtIHNlcnZlIGVycm9ycwoqIGB0b3RhbF9hdHRhY2tzYHRvdGFsIGF0dGFjayBhdHRlbXB0cy4gQW4gYXR0YWNrIGlzIGFueSBvdmVyaGVhZCBjb250YWN0IG9mIHRoZSBiYWxsIGRlc2lnbmVkIHRvIHNjb3JlCiogYGhpdF9wY3RgIEhpdHRpbmcgcGVyY2VudGFnZSBpcyBjYWxjdWxhdGVkIGJ5IHRvdGFsaW5nIGtpbGxzLCBzdWJ0cmFjdGluZyB0aGUgaGl0dGluZyBlcnJvcnMsIHRoZW4gZGl2aWRpbmcgdGhhdCBudW1iZXIgYnkgdGhlIHRvdGFsIG51bWJlciBvZiBhdHRhY2sgYXR0ZW1wdHMuCiogYGtpbGxzX3Blcl9zZXRgIGtpbGxzIGVhcm5lZCBwZXIgc2V0IHBsYXllZAoqIGB3YCB0ZWFtIHdpbnMKKiBgbGAgdGVhbSBsb3NzZXMKKiBgd2luX3BjdGAgdGVhbSB3aW5uaW5nIHBlcmNlbnRhZ2UKKiBgc2Vhc29uYCBzZWFzb24KCiMjIyBXb21lbidzIE5DQUEgRDEgTGFjcm9zc2UgMjAxOCwgMjAxOSAmIDIwMjAgVGVhbSBTdGF0aXN0aWNzCgpFYWNoIHJvdyBpbiB0aGUgW3dvbWVuc19uY2FhX2xhY3Jvc3NlLmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9yZWdyZXNzaW9uX3Byb2plY3RzL3dvbWVuc19uY2FhX2xhY3Jvc3NlLmNzdikgZGF0YSBzZXQgcmVmZXJzIHRvIHRoZSBEMSBXb21lbidzIGxhY3Jvc3NlIHN0YXRpc3RpY3MgZm9yIGEgc2luZ2xlIHNjaG9vbCBpbiBhIHBhcnRpY3VsYXIgc2Vhc29uLiAgVGhlcmUgYXJlIDM0OCB0ZWFtLXNjaG9vbCBjb21iaW5hdGlvbnMgc3Bhbm5pbmcgMjAxOCwgMjAxOSBhbmQgMjAyMC4gIER1ZSB0byB0aGUgQ29yb25hIFZpcnVzIHBhbmRlbWNpYyBubyB0ZWFtIGhhcyBwbGF5ZWQgbW9yZSB0aGFuIDEwIGdhbWVzIGluIDIwMjAuICBOb3RlIHRoYXQgYWxsIGBfZ3BgIHZhcmlhYmxlcyBhcmUgdGhlIHBlciBnYW1lIHBsYXllZCB2ZXJzaW9ucyBvZiB0aGUgdmFyaWFibGUgdGhleSBuYW1lIChlLmcuIGFzc2lzdHNfZ3AgaXMgdG90YWwgdGVhbSBhc3Npc3RzIHBlciBnYW1lIHBsYXllZCkuICBPdGhlciB2YXJpYWJsZSBkZWZpbml0aW9ucyBhcmU6CgoqIGBhc3Npc3RzYCB0b3RhbCB0ZWFtIGFzc2lzdHMuICBUaGUgcGxheWVyIHdobyBwYXNzZXMgdGhlIGJhbGwgdG8gdGhlIHBsYXllciB3aG8gc2NvcmVzIGEgZ29hbCBpcyBjcmVkaXRlZCB3aXRoIGFuIGFzc2lzdAoqIGBjYXVzZWRfdG9zYCB0b3RhbCB0dXJub3ZlcnMgY2F1c2VkIGJ5IHRoZSB0ZWFtLiAgQWxzbyByZWZlcnJlZCB0byBhcyAndGFrZWF3YXlzJwoqIGBkcmF3X2NvbnRyb2xzYCB0b3RhbCB0ZWFtIGRyYXcgY29udHJvbHMuIEEgZHJhdyBjb250cm9sIG9jY3VycyB3aGVuIGEgcGxheWVyIHN1Y2Nlc3NmdWxseSBnYWlucyBjb250cm9sIG9mIHRoZSBiYWxsIGFmdGVyIGEgZHJhdy4KKiBgZm91bHNgIHRvdGFsIHRlYW0gZm91bHMKKiBgY2xlYXJzYCB0b3RhbCB0ZWFtIGNsZWFycy4gQSBjbGVhciBvY2N1cnMgd2hlbiBhIHRlYW0gcGFzc2VzIHRoZSBvZmZlbnNpdmUgcmVzdHJhaW5pbmcgbGluZSBhbmQgaXMgY2xlYXJseSBhYmxlIHRvIGdldCBhbiBvZmZlbnNpdmUgYXR0ZW1wdC4KKiBgY2xyX2F0dGAgdG90YWwgdGVhbSBhdHRlbXB0ZWQgY2xlYXJzCiogYGNscl9wY3RgIHBlcmNlbnQgb2YgdGVhbSBjbGVhciBhdHRlbXB0cyB0aGF0IHdlcmUgc3VjY2VzZnVsbAoqIGBvcHBfZGNgIG9wcG9uZW50cyBkcmF3IGNvbnRyb2wgdG90YWwKKiBgZHJhd2NfY29udHJvbF9wY3RgIHBlcmNlbnQgb2YgdG90YWwgZHJhd3MgdGhhdCB0aGUgdGVhbSBjb250cm9sbGVkCiogYGZyZWVwb3NfZ29hbHNgIHRvdGFsIGZyZWUgcG9zaXRpb25nIGdvYWxzLiAgRnJlZS1wb3NpdGlvbiBzaG90IGluIHdvbWVuJ3MgbGFjcm9zc2UgaXMgc2ltaWxhciB0byBhIGZvdWwgc2hvdCBpbiBiYXNrZXRiYWxsLCBhd2FyZGVkIHRvIGFuIG9mZmVuc2l2ZSBwbGF5ZXIgd2hlbiBhIGRlZmVuZGVyIGNvbW1pdHMgYSBtYWpvciBmb3VsIGluc2lkZSB0aGUgOC1tZXRlciBhcmMKKiBgZnJlZXBvc19zaG90c2AgdG90YWwgZnJlZSBwb3NpdGlvbmluZyBzaG90cyB0YWtlbgoqIGBmcmVlX3Bvc2l0aW9uX3BjdGAgcGVyY2VudCBvZiBmcmVlIHBvc2l0aW9uIHNob3RzIHdoaWNoIHJlc3V0bGVkIGluIGdvYWxzCiogYGdvYWxzYCB0b3RhbCB0ZWFtIGdvYWxzIHNjb3JlZAoqIGBwb2ludHNgIHRvdGFsIHBvaW50cyBlYXJuZWQgYnkgYWxsIHBsYXllcnMgb24gdGhlIHRlYW0gKGdvYWxzICsgYXNzaXN0cykKKiBgdGVhbV9taW5gIHRvdGFsIHRlYW0gbWludXRlcyBwbGF5ZWQKKiBgZ29hbHNfYWxsb3dlZGAgdG90YWwgZ29hbHMgYWxsb3dlZAoqIGBzYXZlc2AgdG90YWwgc2F2ZXMgZnJvbSBhbGwgdGVhbSBnb2Fsa2VlcGVycwoqIGBzdl9wY3RgIHRlYW0gcGVyY2VudGFnZSBvZiBzaG90cyBhbGxvd2VkIHdoaWNoIHdlcmUgc2F2ZWQsIGFuZCBub3QgZ29hbHMgYWdhaW5zdAoqIGBnYV9ncGAgZ29hbHMgYWxsb3dlZCBwZXIgZ2FtZSBwbGF5ZWQKKiBgbWFyZ2luYCBkaWZmZXJlbmNlIGluIGdvYWxzIHNjb3JlZCAtIGdvYWxzIGFsbG93ZWQgcGVyIGdhbWUgcGxheWVkCiogYGdmX2dwYCBnb2FscyBzY29yZWQgcGVyIGdhbWUgcGxheWVkCiogYHNvZ2AgdG90YWwgc2hvdHMgb24gZ29hbAoqIGB0dXJub3ZlcnNgIHRvdGFsIHRlYW0gdHVybm92ZXJzIGNvbW1pdHRlZAoqIGB3b25gIGdhbWVzIHdvbgoqIGBsb3N0YCBnYW1lcyBsb3N0CiogYHdpbl9wY3RgIHRlYW0gd2lubmluZyBwZXJjZW50YWdlCiogYHllbGxvd19jYXJkc2AgdG90YWwgeWVsbG93IGNhcmRzIGVhcm5lZCBieSBhbGwgcGxheWVycyBvbiB0aGUgdGVhbQoqIGBzZWFzb25gIHNlYXNvbgoK