plot(cars)
# Read in data
baseball = read.csv("baseball.csv")
str(baseball)
...
*MLB Glossary*
Team: A code for the name of the team
League: The Major League Baseball league the team belongs to, either AL (American League) or NL (National League)
Year: The year of the corresponding record
RS: The number of runs scored by the team in that year
RA: The number of runs allowed by the team in that year
W: The number of regular season wins by the team in that year
OBP: The on-base percentage of the team in that year
SLG: The slugging percentage of the team in that year
BA: The batting average of the team in that year
Playoffs: Whether the team made the playoffs in that year (1 for yes, 0 for no)
RankSeason: Among the playoff teams in that year, the ranking of their regular season records (1 is best)
RankPlayoffs: Among the playoff teams in that year, how well they fared in the playoffs. The team winning the World Series gets a RankPlayoffs of 1.
G: The number of games a team played in that year
OOBP: The team’s opponents’ on-base percentage in that year
OSLG: The team’s opponents’ slugging percentage in that year
#Each row in the baseball dataset represents a team in a particular year.How many team/year pairs are there in the whole dataset?
nrow(baseball)
#Though the dataset contains data from 1962 until 2012, we removed several years with shorter-than-usual seasons. Using the table() function, identify the total number of years included in this dataset.
table(baseball$Year)
#The baseball dataset contains 47 years (1972, 1981, 1994, and 1995 are missing). We can count the number of years in the table, or use the command length(table(baseball$Year)) directly to get the answer.
length(table(baseball$Year))
Limiting to Teams Making the Playoffs Because we’re only analyzing
teams that made the playoffs, we can use the subset() function to
replace baseball with a data frame limited to teams that made the
playoffs (so our subsetted data frame should still be called
“baseball”). How many team/year pairs are included in the new
dataset?
baseball = subset(baseball, Playoffs == 1)
nrow(baseball)
#Through the years, different numbers of teams have been invited to the playoffs.
table(baseball$Year)
The number of teams in the postseason has changed.
table(table(baseball$Year))
Adding an Important Predictor It’s much harder to win the World
Series if there are 10 teams competing for the championship versus just
two. Therefore, we will add the predictor variable NumCompetitors to the
baseball data frame. NumCompetitors will contain the number of total
teams making the playoffs in the year of a particular team/year pair.
For instance, NumCompetitors should be 2 for the 1962 New York Yankees,
but it should be 8 for the 1998 Boston Red Sox.
#We start by storing the output of the table() function that counts the number of playoff teams from each year:
PlayoffTable = table(baseball$Year)
#You can output the table with the following command:
PlayoffTable
str(names(PlayoffTable))
#Which function call returns the number of playoff teams in 1990 and 2001?
PlayoffTable[c("1990", "2001")]
#Putting it all together, we want to look up the number of teams in the playoffs for each team/year pair in the dataset, and store it as a new variable named NumCompetitors in the baseball data frame.
baseball$NumCompetitors = PlayoffTable[as.character(baseball$Year)]
baseball$NumCompetitors
#How many playoff team/year pairs are there in our dataset from years where 8 teams were invited to the playoffs?
table(baseball$NumCompetitors)
Bivariate Models for Predicting World Series Winner In this problem, we seek to predict whether a team won the World Series; in our dataset this is denoted with a RankPlayoffs value of 1. Add a variable named WorldSeries to the baseball data frame, by typing the following command in your R console:
baseballWorldSeries=as.numeric(baseball
RankPlayoffs == 1)
WorldSeries takes value 1 if a team won the World Series in the indicated year and a 0 otherwise.
#How many observations do we have in our dataset where a team did NOT win the World Series?
baseball$WorldSeries = as.numeric(baseball$RankPlayoffs == 1)
table(baseball$WorldSeries)
Bivariate Models for Predicting World Series Winner When we’re not
sure which of our variables are useful in predicting a particular
outcome, it’s often helpful to build bivariate models, which are models
that predict the outcome using a single independent variable. Which of
the following variables is a significant predictor of the WorldSeries
variable in a bivariate logistic regression model? To determine
significance, remember to look at the stars in the summary output of the
model. We’ll define an independent variable as significant if there is
at least one star at the end of the coefficients row for that variable
(this is equivalent to the probability column having a value smaller
than 0.05). Note that you have to build 12 models to answer this
question! Use the entire dataset baseball to build the models
#Which of the following variables is a significant predictor of the WorldSeries variable in a bivariate logistic regression model?
#Varibales to use as predictors for each bivariate model(Year, RS, RA, W, OBP, SLG, BA, RankSeason, OOBP,OSLG, NumCompetitors, League)
model1<-glm(WorldSeries~Year, data=baseball, family="binomial")
smary(model1)
Year is a significant predictor!
model2<-glm(WorldSeries~RS, data=baseball, family="binomial")
summary(model2)
RS is not significant
model3<-glm(WorldSeries~RA, data=baseball, family="binomial")
summary(model3)
RA is a significant predictor!
model4<-glm(WorldSeries~W, data=baseball, family="binomial")
summary(model4)
W is not significant
model5<-glm(WorldSeries~OBP, data=baseball, family="binomial")
summary(model5)
OBP is not significant
model6<-glm(WorldSeries~SLG, data=baseball, family="binomial")
summary(model6)
SLG is not significant
model7<-glm(WorldSeries~BA, data=baseball, family="binomial")
summary(model7)
BA is not significant
model8<-glm(WorldSeries~RankSeason, data=baseball, family="binomial")
summary(model8)
RankSeason is significant!
model9<-glm(WorldSeries~OOBP, data=baseball, family="binomial")
summary(model9)
OOBP is not significant
model10<-glm(WorldSeries~OSLG, data=baseball, family="binomial")
summary(model10)
OSLG is not significant
model11<-glm(WorldSeries~NumCompetitors, data=baseball, family="binomial")
summary(model11)
NumCompetitors is significant!
model12<-glm(WorldSeries~League, data=baseball, family="binomial")
summary(model12)
League is not significant
In short, the significant predictors are Year, RA, and
NumCompetitors.
Multivariate Models for Predicting World Series Winner
In this section, we’ll consider multivariate models that combine the
variables we found to be significant in bivariate models. Build a model
using all of the variables that you found to be significant in the
bivariate models. How many variables are significant in the combined
model?
#How many variables are significant in the combined model?
LogModel = glm(WorldSeries ~ Year + RA + RankSeason + NumCompetitors, data=baseball, family=binomial)
summary(LogModel)
Looking at summary(LogModel), we can see that none of the variables are significant in the multivariate model. Often, variables that were significant in bivariate models are no longer significant in multivariate analysis due to correlation between the variables. Which of the following variable pairs have a high degree of correlation (a correlation greater than 0.8 or less than -0.8)?
#We can compute all pair-wise correlations between these variables with:
cor(baseball[c("Year", "RA", "RankSeason", "NumCompetitors")])
While every pair was at least moderately correlated, the only
strongly correlated pair was Year/NumCompetitors, with correlation
coefficient 0.914.
Let us build all six of the two variable models listed in the
previous problem. Together with the four bivariate models that were
significant, we should have 10 different logistic regression models to
analyze. Which model has the best AIC value (the minimum AIC value)?
#The two-variable models can be built with the following commands:
model13 = glm(WorldSeries ~ Year + RA, data=baseball, family=binomial)
summary(model13)
model14 = glm(WorldSeries ~ Year + RankSeason, data=baseball, family=binomial)
summary(model14)
model15 = glm(WorldSeries ~ Year + NumCompetitors, data=baseball, family=binomial)
summary(model15)
model16 = glm(WorldSeries ~ RA + RankSeason, data=baseball, family=binomial)
summary(model16)
model17 = glm(WorldSeries ~ RA + NumCompetitors, data=baseball, family=binomial)
summary(model17)
model18 = glm(WorldSeries ~ RankSeason + NumCompetitors, data=baseball, family=binomial)
summary(model18)
None of the models with two independent variables had both variables
significant, so none seem promising as compared to a simple bivariate
model. Indeed the model with the lowest AIC value is the model with just
NumCompetitors as the independent variable. This seems to confirm the
claim made by Billy Beane in Moneyball that all that matters in the
Playoffs is luck, since NumCompetitors has nothing to do with the
quality of the teams!
LS0tDQp0aXRsZTogIkluLUNsYXNzIEFjdHZpdHkgIzE1Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQoNCmBgYHtyfQ0KcGxvdChjYXJzKQ0KYGBgDQpgYGB7cn0NCiMgUmVhZCBpbiBkYXRhDQpiYXNlYmFsbCA9IHJlYWQuY3N2KCJiYXNlYmFsbC5jc3YiKQ0Kc3RyKGJhc2ViYWxsKQ0KDQogLi4uDQoqTUxCIEdsb3NzYXJ5Kg0KDQpUZWFtOiBBIGNvZGUgZm9yIHRoZSBuYW1lIG9mIHRoZSB0ZWFtDQpMZWFndWU6IFRoZSBNYWpvciBMZWFndWUgQmFzZWJhbGwgbGVhZ3VlIHRoZSB0ZWFtIGJlbG9uZ3MgdG8sIGVpdGhlciBBTCAoQW1lcmljYW4gTGVhZ3VlKSBvciBOTCAoTmF0aW9uYWwgTGVhZ3VlKQ0KWWVhcjogVGhlIHllYXIgb2YgdGhlIGNvcnJlc3BvbmRpbmcgcmVjb3JkDQpSUzogVGhlIG51bWJlciBvZiBydW5zIHNjb3JlZCBieSB0aGUgdGVhbSBpbiB0aGF0IHllYXINClJBOiBUaGUgbnVtYmVyIG9mIHJ1bnMgYWxsb3dlZCBieSB0aGUgdGVhbSBpbiB0aGF0IHllYXINClc6IFRoZSBudW1iZXIgb2YgcmVndWxhciBzZWFzb24gd2lucyBieSB0aGUgdGVhbSBpbiB0aGF0IHllYXINCk9CUDogVGhlIG9uLWJhc2UgcGVyY2VudGFnZSBvZiB0aGUgdGVhbSBpbiB0aGF0IHllYXINClNMRzogVGhlIHNsdWdnaW5nIHBlcmNlbnRhZ2Ugb2YgdGhlIHRlYW0gaW4gdGhhdCB5ZWFyDQpCQTogVGhlIGJhdHRpbmcgYXZlcmFnZSBvZiB0aGUgdGVhbSBpbiB0aGF0IHllYXINClBsYXlvZmZzOiBXaGV0aGVyIHRoZSB0ZWFtIG1hZGUgdGhlIHBsYXlvZmZzIGluIHRoYXQgeWVhciAoMSBmb3IgeWVzLCAwIGZvciBubykNClJhbmtTZWFzb246IEFtb25nIHRoZSBwbGF5b2ZmIHRlYW1zIGluIHRoYXQgeWVhciwgdGhlIHJhbmtpbmcgb2YgdGhlaXIgcmVndWxhciBzZWFzb24gcmVjb3JkcyAoMSBpcyBiZXN0KQ0KUmFua1BsYXlvZmZzOiBBbW9uZyB0aGUgcGxheW9mZiB0ZWFtcyBpbiB0aGF0IHllYXIsIGhvdyB3ZWxsIHRoZXkgZmFyZWQgaW4gdGhlIHBsYXlvZmZzLiBUaGUgdGVhbSB3aW5uaW5nIHRoZSBXb3JsZCBTZXJpZXMgZ2V0cyBhIFJhbmtQbGF5b2ZmcyBvZiAxLg0KRzogVGhlIG51bWJlciBvZiBnYW1lcyBhIHRlYW0gcGxheWVkIGluIHRoYXQgeWVhcg0KT09CUDogVGhlIHRlYW3igJlzIG9wcG9uZW50c+KAmSBvbi1iYXNlIHBlcmNlbnRhZ2UgaW4gdGhhdCB5ZWFyDQpPU0xHOiBUaGUgdGVhbeKAmXMgb3Bwb25lbnRz4oCZIHNsdWdnaW5nIHBlcmNlbnRhZ2UgaW4gdGhhdCB5ZWFyDQpgYGANCmBgYHtyfQ0KI0VhY2ggcm93IGluIHRoZSBiYXNlYmFsbCBkYXRhc2V0IHJlcHJlc2VudHMgYSB0ZWFtIGluIGEgcGFydGljdWxhciB5ZWFyLkhvdyBtYW55IHRlYW0veWVhciBwYWlycyBhcmUgdGhlcmUgaW4gdGhlIHdob2xlIGRhdGFzZXQ/DQpucm93KGJhc2ViYWxsKQ0KYGBgDQoNCg0KYGBge3J9DQojVGhvdWdoIHRoZSBkYXRhc2V0IGNvbnRhaW5zIGRhdGEgZnJvbSAxOTYyIHVudGlsIDIwMTIsIHdlIHJlbW92ZWQgc2V2ZXJhbCB5ZWFycyB3aXRoIHNob3J0ZXItdGhhbi11c3VhbCBzZWFzb25zLiBVc2luZyB0aGUgdGFibGUoKSBmdW5jdGlvbiwgaWRlbnRpZnkgdGhlIHRvdGFsIG51bWJlciBvZiB5ZWFycyBpbmNsdWRlZCBpbiB0aGlzIGRhdGFzZXQuDQp0YWJsZShiYXNlYmFsbCRZZWFyKQ0KYGBgDQoNCg0KYGBge3J9DQojVGhlIGJhc2ViYWxsIGRhdGFzZXQgY29udGFpbnMgNDcgeWVhcnMgKDE5NzIsIDE5ODEsIDE5OTQsIGFuZCAxOTk1IGFyZSBtaXNzaW5nKS4gV2UgY2FuIGNvdW50IHRoZSBudW1iZXIgb2YgeWVhcnMgaW4gdGhlIHRhYmxlLCBvciB1c2UgdGhlIGNvbW1hbmQgbGVuZ3RoKHRhYmxlKGJhc2ViYWxsJFllYXIpKSBkaXJlY3RseSB0byBnZXQgdGhlIGFuc3dlci4NCmxlbmd0aCh0YWJsZShiYXNlYmFsbCRZZWFyKSkNCmBgYA0KDQpMaW1pdGluZyB0byBUZWFtcyBNYWtpbmcgdGhlIFBsYXlvZmZzIEJlY2F1c2Ugd2XigJlyZSBvbmx5IGFuYWx5emluZyB0ZWFtcyB0aGF0IG1hZGUgdGhlIHBsYXlvZmZzLCB3ZSBjYW4gdXNlIHRoZSBzdWJzZXQoKSBmdW5jdGlvbiB0byByZXBsYWNlIGJhc2ViYWxsIHdpdGggYSBkYXRhIGZyYW1lIGxpbWl0ZWQgdG8gdGVhbXMgdGhhdCBtYWRlIHRoZSBwbGF5b2ZmcyAoc28gb3VyIHN1YnNldHRlZCBkYXRhIGZyYW1lIHNob3VsZCBzdGlsbCBiZSBjYWxsZWQg4oCcYmFzZWJhbGzigJ0pLiBIb3cgbWFueSB0ZWFtL3llYXIgcGFpcnMgYXJlIGluY2x1ZGVkIGluIHRoZSBuZXcgZGF0YXNldD8NCg0KYGBge3J9DQpiYXNlYmFsbCA9IHN1YnNldChiYXNlYmFsbCwgUGxheW9mZnMgPT0gMSkNCm5yb3coYmFzZWJhbGwpDQpgYGANCg0KDQoNCmBgYHtyfQ0KI1Rocm91Z2ggdGhlIHllYXJzLCBkaWZmZXJlbnQgbnVtYmVycyBvZiB0ZWFtcyBoYXZlIGJlZW4gaW52aXRlZCB0byB0aGUgcGxheW9mZnMuDQp0YWJsZShiYXNlYmFsbCRZZWFyKQ0KYGBgDQoNClRoZSBudW1iZXIgb2YgdGVhbXMgaW4gdGhlIHBvc3RzZWFzb24gaGFzIGNoYW5nZWQuDQoNCmBgYHtyfQ0KdGFibGUodGFibGUoYmFzZWJhbGwkWWVhcikpDQpgYGANCg0KQWRkaW5nIGFuIEltcG9ydGFudCBQcmVkaWN0b3IgSXTigJlzIG11Y2ggaGFyZGVyIHRvIHdpbiB0aGUgV29ybGQgU2VyaWVzIGlmIHRoZXJlIGFyZSAxMCB0ZWFtcyBjb21wZXRpbmcgZm9yIHRoZSBjaGFtcGlvbnNoaXAgdmVyc3VzIGp1c3QgdHdvLiBUaGVyZWZvcmUsIHdlIHdpbGwgYWRkIHRoZSBwcmVkaWN0b3IgdmFyaWFibGUgTnVtQ29tcGV0aXRvcnMgdG8gdGhlIGJhc2ViYWxsIGRhdGEgZnJhbWUuIE51bUNvbXBldGl0b3JzIHdpbGwgY29udGFpbiB0aGUgbnVtYmVyIG9mIHRvdGFsIHRlYW1zIG1ha2luZyB0aGUgcGxheW9mZnMgaW4gdGhlIHllYXIgb2YgYSBwYXJ0aWN1bGFyIHRlYW0veWVhciBwYWlyLiBGb3IgaW5zdGFuY2UsIE51bUNvbXBldGl0b3JzIHNob3VsZCBiZSAyIGZvciB0aGUgMTk2MiBOZXcgWW9yayBZYW5rZWVzLCBidXQgaXQgc2hvdWxkIGJlIDggZm9yIHRoZSAxOTk4IEJvc3RvbiBSZWQgU294Lg0KDQoNCmBgYHtyfQ0KI1dlIHN0YXJ0IGJ5IHN0b3JpbmcgdGhlIG91dHB1dCBvZiB0aGUgdGFibGUoKSBmdW5jdGlvbiB0aGF0IGNvdW50cyB0aGUgbnVtYmVyIG9mIHBsYXlvZmYgdGVhbXMgZnJvbSBlYWNoIHllYXI6DQoNClBsYXlvZmZUYWJsZSA9IHRhYmxlKGJhc2ViYWxsJFllYXIpDQoNCiNZb3UgY2FuIG91dHB1dCB0aGUgdGFibGUgd2l0aCB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6DQoNClBsYXlvZmZUYWJsZQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnN0cihuYW1lcyhQbGF5b2ZmVGFibGUpKQ0KYGBgDQoNCg0KYGBge3J9DQogI1doaWNoIGZ1bmN0aW9uIGNhbGwgcmV0dXJucyB0aGUgbnVtYmVyIG9mIHBsYXlvZmYgdGVhbXMgaW4gMTk5MCBhbmQgMjAwMT8NClBsYXlvZmZUYWJsZVtjKCIxOTkwIiwgIjIwMDEiKV0NCmBgYA0KDQoNCg0KYGBge3J9DQojUHV0dGluZyBpdCBhbGwgdG9nZXRoZXIsIHdlIHdhbnQgdG8gbG9vayB1cCB0aGUgbnVtYmVyIG9mIHRlYW1zIGluIHRoZSBwbGF5b2ZmcyBmb3IgZWFjaCB0ZWFtL3llYXIgcGFpciBpbiB0aGUgZGF0YXNldCwgYW5kIHN0b3JlIGl0IGFzIGEgbmV3IHZhcmlhYmxlIG5hbWVkIE51bUNvbXBldGl0b3JzIGluIHRoZSBiYXNlYmFsbCBkYXRhIGZyYW1lLg0KYmFzZWJhbGwkTnVtQ29tcGV0aXRvcnMgPSBQbGF5b2ZmVGFibGVbYXMuY2hhcmFjdGVyKGJhc2ViYWxsJFllYXIpXQ0KYmFzZWJhbGwkTnVtQ29tcGV0aXRvcnMNCmBgYA0KDQoNCg0KYGBge3J9DQojSG93IG1hbnkgcGxheW9mZiB0ZWFtL3llYXIgcGFpcnMgYXJlIHRoZXJlIGluIG91ciBkYXRhc2V0IGZyb20geWVhcnMgd2hlcmUgOCB0ZWFtcyB3ZXJlIGludml0ZWQgdG8gdGhlIHBsYXlvZmZzPw0KdGFibGUoYmFzZWJhbGwkTnVtQ29tcGV0aXRvcnMpDQoNCg0KQml2YXJpYXRlIE1vZGVscyBmb3IgUHJlZGljdGluZyBXb3JsZCBTZXJpZXMgV2lubmVyIEluIHRoaXMgcHJvYmxlbSwgd2Ugc2VlayB0byBwcmVkaWN0IHdoZXRoZXIgYSB0ZWFtIHdvbiB0aGUgV29ybGQgU2VyaWVzOyBpbiBvdXIgZGF0YXNldCB0aGlzIGlzIGRlbm90ZWQgd2l0aCBhIFJhbmtQbGF5b2ZmcyB2YWx1ZSBvZiAxLiBBZGQgYSB2YXJpYWJsZSBuYW1lZCBXb3JsZFNlcmllcyB0byB0aGUgYmFzZWJhbGwgZGF0YSBmcmFtZSwgYnkgdHlwaW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZCBpbiB5b3VyIFIgY29uc29sZToNCg0KYmFzZWJhbGxXb3JsZFNlcmllcz1hcy5udW1lcmljKGJhc2ViYWxsDQpSYW5rUGxheW9mZnMgPT0gMSkNCg0KV29ybGRTZXJpZXMgdGFrZXMgdmFsdWUgMSBpZiBhIHRlYW0gd29uIHRoZSBXb3JsZCBTZXJpZXMgaW4gdGhlIGluZGljYXRlZCB5ZWFyIGFuZCBhIDAgb3RoZXJ3aXNlLg0KYGBgDQoNCmBgYHtyfQ0KI0hvdyBtYW55IG9ic2VydmF0aW9ucyBkbyB3ZSBoYXZlIGluIG91ciBkYXRhc2V0IHdoZXJlIGEgdGVhbSBkaWQgTk9UIHdpbiB0aGUgV29ybGQgU2VyaWVzPw0KYmFzZWJhbGwkV29ybGRTZXJpZXMgPSBhcy5udW1lcmljKGJhc2ViYWxsJFJhbmtQbGF5b2ZmcyA9PSAxKQ0KdGFibGUoYmFzZWJhbGwkV29ybGRTZXJpZXMpDQpgYGANCg0KDQpCaXZhcmlhdGUgTW9kZWxzIGZvciBQcmVkaWN0aW5nIFdvcmxkIFNlcmllcyBXaW5uZXIgV2hlbiB3ZeKAmXJlIG5vdCBzdXJlIHdoaWNoIG9mIG91ciB2YXJpYWJsZXMgYXJlIHVzZWZ1bCBpbiBwcmVkaWN0aW5nIGEgcGFydGljdWxhciBvdXRjb21lLCBpdOKAmXMgb2Z0ZW4gaGVscGZ1bCB0byBidWlsZCBiaXZhcmlhdGUgbW9kZWxzLCB3aGljaCBhcmUgbW9kZWxzIHRoYXQgcHJlZGljdCB0aGUgb3V0Y29tZSB1c2luZyBhIHNpbmdsZSBpbmRlcGVuZGVudCB2YXJpYWJsZS4gV2hpY2ggb2YgdGhlIGZvbGxvd2luZyB2YXJpYWJsZXMgaXMgYSBzaWduaWZpY2FudCBwcmVkaWN0b3Igb2YgdGhlIFdvcmxkU2VyaWVzIHZhcmlhYmxlIGluIGEgYml2YXJpYXRlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWw/IFRvIGRldGVybWluZSBzaWduaWZpY2FuY2UsIHJlbWVtYmVyIHRvIGxvb2sgYXQgdGhlIHN0YXJzIGluIHRoZSBzdW1tYXJ5IG91dHB1dCBvZiB0aGUgbW9kZWwuIFdl4oCZbGwgZGVmaW5lIGFuIGluZGVwZW5kZW50IHZhcmlhYmxlIGFzIHNpZ25pZmljYW50IGlmIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBzdGFyIGF0IHRoZSBlbmQgb2YgdGhlIGNvZWZmaWNpZW50cyByb3cgZm9yIHRoYXQgdmFyaWFibGUgKHRoaXMgaXMgZXF1aXZhbGVudCB0byB0aGUgcHJvYmFiaWxpdHkgY29sdW1uIGhhdmluZyBhIHZhbHVlIHNtYWxsZXIgdGhhbiAwLjA1KS4gTm90ZSB0aGF0IHlvdSBoYXZlIHRvIGJ1aWxkIDEyIG1vZGVscyB0byBhbnN3ZXIgdGhpcyBxdWVzdGlvbiEgVXNlIHRoZSBlbnRpcmUgZGF0YXNldCBiYXNlYmFsbCB0byBidWlsZCB0aGUgbW9kZWxzDQoNCmBgYHtyfQ0KI1doaWNoIG9mIHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIGlzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yIG9mIHRoZSBXb3JsZFNlcmllcyB2YXJpYWJsZSBpbiBhIGJpdmFyaWF0ZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsPw0KI1ZhcmliYWxlcyB0byB1c2UgYXMgcHJlZGljdG9ycyBmb3IgZWFjaCBiaXZhcmlhdGUgbW9kZWwoWWVhciwgUlMsIFJBLCBXLCBPQlAsIFNMRywgQkEsIFJhbmtTZWFzb24sIE9PQlAsT1NMRywgTnVtQ29tcGV0aXRvcnMsIExlYWd1ZSkNCm1vZGVsMTwtZ2xtKFdvcmxkU2VyaWVzflllYXIsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQ0Kc21hcnkobW9kZWwxKQ0KYGBgDQoNClllYXIgaXMgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IhDQoNCg0KYGBge3J9DQptb2RlbDI8LWdsbShXb3JsZFNlcmllc35SUywgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpDQpzdW1tYXJ5KG1vZGVsMikNCmBgYA0KDQpSUyBpcyBub3Qgc2lnbmlmaWNhbnQNCg0KYGBge3J9DQptb2RlbDM8LWdsbShXb3JsZFNlcmllc35SQSwgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpDQpzdW1tYXJ5KG1vZGVsMykNCmBgYA0KDQpSQSBpcyBhIHNpZ25pZmljYW50IHByZWRpY3RvciENCg0KDQpgYGB7cn0NCm1vZGVsNDwtZ2xtKFdvcmxkU2VyaWVzflcsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQ0Kc3VtbWFyeShtb2RlbDQpDQpgYGANCg0KVyBpcyBub3Qgc2lnbmlmaWNhbnQNCg0KDQpgYGB7cn0NCm1vZGVsNTwtZ2xtKFdvcmxkU2VyaWVzfk9CUCwgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpDQpzdW1tYXJ5KG1vZGVsNSkNCmBgYA0KDQpPQlAgaXMgbm90IHNpZ25pZmljYW50DQoNCmBgYHtyfQ0KbW9kZWw2PC1nbG0oV29ybGRTZXJpZXN+U0xHLCBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9ImJpbm9taWFsIikNCnN1bW1hcnkobW9kZWw2KQ0KYGBgDQoNCg0KU0xHIGlzIG5vdCBzaWduaWZpY2FudA0KDQpgYGB7cn0NCm1vZGVsNzwtZ2xtKFdvcmxkU2VyaWVzfkJBLCBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9ImJpbm9taWFsIikNCnN1bW1hcnkobW9kZWw3KQ0KYGBgDQoNCkJBIGlzIG5vdCBzaWduaWZpY2FudA0KDQpgYGB7cn0NCm1vZGVsODwtZ2xtKFdvcmxkU2VyaWVzflJhbmtTZWFzb24sIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQ0Kc3VtbWFyeShtb2RlbDgpIA0KYGBgDQoNClJhbmtTZWFzb24gaXMgc2lnbmlmaWNhbnQhDQoNCmBgYHtyfQ0KbW9kZWw5PC1nbG0oV29ybGRTZXJpZXN+T09CUCwgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PSJiaW5vbWlhbCIpDQpzdW1tYXJ5KG1vZGVsOSkNCmBgYA0KDQpPT0JQIGlzIG5vdCBzaWduaWZpY2FudA0KDQoNCmBgYHtyfQ0KbW9kZWwxMDwtZ2xtKFdvcmxkU2VyaWVzfk9TTEcsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQ0Kc3VtbWFyeShtb2RlbDEwKQ0KYGBgDQoNCk9TTEcgaXMgbm90IHNpZ25pZmljYW50DQoNCg0KYGBge3J9DQptb2RlbDExPC1nbG0oV29ybGRTZXJpZXN+TnVtQ29tcGV0aXRvcnMsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQ0Kc3VtbWFyeShtb2RlbDExKQ0KYGBgDQoNCk51bUNvbXBldGl0b3JzIGlzIHNpZ25pZmljYW50IQ0KDQpgYGB7cn0NCm1vZGVsMTI8LWdsbShXb3JsZFNlcmllc35MZWFndWUsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT0iYmlub21pYWwiKQ0Kc3VtbWFyeShtb2RlbDEyKQ0KYGBgDQoNCkxlYWd1ZSBpcyBub3Qgc2lnbmlmaWNhbnQNCg0KSW4gc2hvcnQsIHRoZSBzaWduaWZpY2FudCBwcmVkaWN0b3JzIGFyZSBZZWFyLCBSQSwgYW5kIE51bUNvbXBldGl0b3JzLg0KDQpNdWx0aXZhcmlhdGUgTW9kZWxzIGZvciBQcmVkaWN0aW5nIFdvcmxkIFNlcmllcyBXaW5uZXINCg0KSW4gdGhpcyBzZWN0aW9uLCB3ZeKAmWxsIGNvbnNpZGVyIG11bHRpdmFyaWF0ZSBtb2RlbHMgdGhhdCBjb21iaW5lIHRoZSB2YXJpYWJsZXMgd2UgZm91bmQgdG8gYmUgc2lnbmlmaWNhbnQgaW4gYml2YXJpYXRlIG1vZGVscy4gQnVpbGQgYSBtb2RlbCB1c2luZyBhbGwgb2YgdGhlIHZhcmlhYmxlcyB0aGF0IHlvdSBmb3VuZCB0byBiZSBzaWduaWZpY2FudCBpbiB0aGUgYml2YXJpYXRlIG1vZGVscy4gSG93IG1hbnkgdmFyaWFibGVzIGFyZSBzaWduaWZpY2FudCBpbiB0aGUgY29tYmluZWQgbW9kZWw/DQoNCg0KYGBge3J9DQojSG93IG1hbnkgdmFyaWFibGVzIGFyZSBzaWduaWZpY2FudCBpbiB0aGUgY29tYmluZWQgbW9kZWw/DQpMb2dNb2RlbCA9IGdsbShXb3JsZFNlcmllcyB+IFllYXIgKyBSQSArIFJhbmtTZWFzb24gKyBOdW1Db21wZXRpdG9ycywgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PWJpbm9taWFsKQ0Kc3VtbWFyeShMb2dNb2RlbCkNCg0KDQpMb29raW5nIGF0IHN1bW1hcnkoTG9nTW9kZWwpLCB3ZSBjYW4gc2VlIHRoYXQgbm9uZSBvZiB0aGUgdmFyaWFibGVzIGFyZSBzaWduaWZpY2FudCBpbiB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsLiBPZnRlbiwgdmFyaWFibGVzIHRoYXQgd2VyZSBzaWduaWZpY2FudCBpbiBiaXZhcmlhdGUgbW9kZWxzIGFyZSBubyBsb25nZXIgc2lnbmlmaWNhbnQgaW4gbXVsdGl2YXJpYXRlIGFuYWx5c2lzIGR1ZSB0byBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMuIFdoaWNoIG9mIHRoZSBmb2xsb3dpbmcgdmFyaWFibGUgcGFpcnMgaGF2ZSBhIGhpZ2ggZGVncmVlIG9mIGNvcnJlbGF0aW9uIChhIGNvcnJlbGF0aW9uIGdyZWF0ZXIgdGhhbiAwLjggb3IgbGVzcyB0aGFuIC0wLjgpPw0KYGBgDQoNCg0KYGBge3J9DQojV2UgY2FuIGNvbXB1dGUgYWxsIHBhaXItd2lzZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiB0aGVzZSB2YXJpYWJsZXMgd2l0aDoNCmNvcihiYXNlYmFsbFtjKCJZZWFyIiwgIlJBIiwgIlJhbmtTZWFzb24iLCAiTnVtQ29tcGV0aXRvcnMiKV0pDQpgYGANCg0KV2hpbGUgZXZlcnkgcGFpciB3YXMgYXQgbGVhc3QgbW9kZXJhdGVseSBjb3JyZWxhdGVkLCB0aGUgb25seSBzdHJvbmdseSBjb3JyZWxhdGVkIHBhaXIgd2FzIFllYXIvTnVtQ29tcGV0aXRvcnMsIHdpdGggY29ycmVsYXRpb24gY29lZmZpY2llbnQgMC45MTQuDQoNCkxldCB1cyBidWlsZCBhbGwgc2l4IG9mIHRoZSB0d28gdmFyaWFibGUgbW9kZWxzIGxpc3RlZCBpbiB0aGUgcHJldmlvdXMgcHJvYmxlbS4gVG9nZXRoZXIgd2l0aCB0aGUgZm91ciBiaXZhcmlhdGUgbW9kZWxzIHRoYXQgd2VyZSBzaWduaWZpY2FudCwgd2Ugc2hvdWxkIGhhdmUgMTAgZGlmZmVyZW50IGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWxzIHRvIGFuYWx5emUuIFdoaWNoIG1vZGVsIGhhcyB0aGUgYmVzdCBBSUMgdmFsdWUgKHRoZSBtaW5pbXVtIEFJQyB2YWx1ZSk/DQoNCg0KYGBge3J9DQojVGhlIHR3by12YXJpYWJsZSBtb2RlbHMgY2FuIGJlIGJ1aWx0IHdpdGggdGhlIGZvbGxvd2luZyBjb21tYW5kczoNCg0KbW9kZWwxMyA9IGdsbShXb3JsZFNlcmllcyB+IFllYXIgKyBSQSwgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PWJpbm9taWFsKQ0Kc3VtbWFyeShtb2RlbDEzKQ0KYGBgDQoNCg0KYGBge3J9DQptb2RlbDE0ID0gZ2xtKFdvcmxkU2VyaWVzIH4gWWVhciArIFJhbmtTZWFzb24sIGRhdGE9YmFzZWJhbGwsIGZhbWlseT1iaW5vbWlhbCkNCnN1bW1hcnkobW9kZWwxNCkNCmBgYA0KDQpgYGB7cn0NCm1vZGVsMTUgPSBnbG0oV29ybGRTZXJpZXMgfiBZZWFyICsgTnVtQ29tcGV0aXRvcnMsIGRhdGE9YmFzZWJhbGwsIGZhbWlseT1iaW5vbWlhbCkNCnN1bW1hcnkobW9kZWwxNSkNCmBgYA0KDQoNCg0KYGBge3J9DQptb2RlbDE2ID0gZ2xtKFdvcmxkU2VyaWVzIH4gUkEgKyBSYW5rU2Vhc29uLCBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9Ymlub21pYWwpDQpzdW1tYXJ5KG1vZGVsMTYpDQpgYGANCg0KDQpgYGB7cn0NCm1vZGVsMTcgPSBnbG0oV29ybGRTZXJpZXMgfiBSQSArIE51bUNvbXBldGl0b3JzLCBkYXRhPWJhc2ViYWxsLCBmYW1pbHk9Ymlub21pYWwpDQpzdW1tYXJ5KG1vZGVsMTcpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbW9kZWwxOCA9IGdsbShXb3JsZFNlcmllcyB+IFJhbmtTZWFzb24gKyBOdW1Db21wZXRpdG9ycywgZGF0YT1iYXNlYmFsbCwgZmFtaWx5PWJpbm9taWFsKQ0Kc3VtbWFyeShtb2RlbDE4KQ0KYGBgDQoNCk5vbmUgb2YgdGhlIG1vZGVscyB3aXRoIHR3byBpbmRlcGVuZGVudCB2YXJpYWJsZXMgaGFkIGJvdGggdmFyaWFibGVzIHNpZ25pZmljYW50LCBzbyBub25lIHNlZW0gcHJvbWlzaW5nIGFzIGNvbXBhcmVkIHRvIGEgc2ltcGxlIGJpdmFyaWF0ZSBtb2RlbC4gSW5kZWVkIHRoZSBtb2RlbCB3aXRoIHRoZSBsb3dlc3QgQUlDIHZhbHVlIGlzIHRoZSBtb2RlbCB3aXRoIGp1c3QgTnVtQ29tcGV0aXRvcnMgYXMgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlLiBUaGlzIHNlZW1zIHRvIGNvbmZpcm0gdGhlIGNsYWltIG1hZGUgYnkgQmlsbHkgQmVhbmUgaW4gTW9uZXliYWxsIHRoYXQgYWxsIHRoYXQgbWF0dGVycyBpbiB0aGUgUGxheW9mZnMgaXMgbHVjaywgc2luY2UgTnVtQ29tcGV0aXRvcnMgaGFzIG5vdGhpbmcgdG8gZG8gd2l0aCB0aGUgcXVhbGl0eSBvZiB0aGUgdGVhbXMhDQoNCg==