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_attacks
total 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