library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.0.4
library(openintro)
library(statsr)
## Warning: package 'statsr' was built under R version 4.0.5
## Warning: package 'BayesFactor' was built under R version 4.0.5
## Warning: package 'coda' was built under R version 4.0.5

In this lab we’ll be looking at data from all 30 Major League Baseball teams and examining the linear relationship between runs scored in a season and a number of other player statistics. Our aim will be to summarize these relationships both graphically and numerically in order to find which variable, if any, helps us best predict a team’s runs scored in a season.

#load the data

download.file("http://www.openintro.org/stat/data/mlb11.RData", destfile = "mlb11.RData")
load("mlb11.RData")

In addition to runs scored, there are seven traditionally used variables in the data set: at-bats, hits, home runs, batting average, strikeouts, stolen bases, and wins. There are also three newer variables: on-base percentage, slugging percentage, and on-base plus slugging. For the first portion of the analysis we’ll consider the seven traditional variables. At the end of the lab, you’ll work with the newer variables on your own.

summary(mlb11)
##                    team         runs          at_bats          hits     
##  Arizona Diamondbacks: 1   Min.   :556.0   Min.   :5417   Min.   :1263  
##  Atlanta Braves      : 1   1st Qu.:629.0   1st Qu.:5448   1st Qu.:1348  
##  Baltimore Orioles   : 1   Median :705.5   Median :5516   Median :1394  
##  Boston Red Sox      : 1   Mean   :693.6   Mean   :5524   Mean   :1409  
##  Chicago Cubs        : 1   3rd Qu.:734.0   3rd Qu.:5575   3rd Qu.:1441  
##  Chicago White Sox   : 1   Max.   :875.0   Max.   :5710   Max.   :1600  
##  (Other)             :24                                                
##     homeruns        bat_avg         strikeouts    stolen_bases   
##  Min.   : 91.0   Min.   :0.2330   Min.   : 930   Min.   : 49.00  
##  1st Qu.:118.0   1st Qu.:0.2447   1st Qu.:1085   1st Qu.: 89.75  
##  Median :154.0   Median :0.2530   Median :1140   Median :107.00  
##  Mean   :151.7   Mean   :0.2549   Mean   :1150   Mean   :109.30  
##  3rd Qu.:172.8   3rd Qu.:0.2602   3rd Qu.:1248   3rd Qu.:130.75  
##  Max.   :222.0   Max.   :0.2830   Max.   :1323   Max.   :170.00  
##                                                                  
##       wins          new_onbase        new_slug         new_obs      
##  Min.   : 56.00   Min.   :0.2920   Min.   :0.3480   Min.   :0.6400  
##  1st Qu.: 72.00   1st Qu.:0.3110   1st Qu.:0.3770   1st Qu.:0.6920  
##  Median : 80.00   Median :0.3185   Median :0.3985   Median :0.7160  
##  Mean   : 80.97   Mean   :0.3205   Mean   :0.3988   Mean   :0.7191  
##  3rd Qu.: 90.00   3rd Qu.:0.3282   3rd Qu.:0.4130   3rd Qu.:0.7382  
##  Max.   :102.00   Max.   :0.3490   Max.   :0.4610   Max.   :0.8100  
## 

Exercise 1

What type of plot would you use to display the relationship between runs and one of the other numerical variables? Plot this relationship using the variable at_bats as the predictor. Does the relationship look linear? If you knew a team’s at_bats, would you be comfortable using a linear model to predict the number of runs?

Answer 1. I would use a scatterplot to display the relationship between runs and one of the other numerical variables such as at_bats. 2. See Plot below between runs and at_bats 3. The trend does show some linear relationship between runs and at_bats, but there appears to be a lot of variation, so the linear model doesn’t appear to be very useful as an accurate predictor in this case.

#scatterplot 

plot(mlb11$runs ~ mlb11$at_bats,
     main = "Relationship Between Runs and At_Bats",
     ylab = "Runs", 
     xlab = "At_Bats")

#If the relationship looks linear, we can quantify the strength of the relationship with the correlation coefficient.
cor(mlb11$runs, mlb11$at_bats)
## [1] 0.610627

Sum of squared residuals Think back to the way that we described the distribution of a single variable. Recall that we discussed characteristics such as center, spread, and shape. It’s also useful to be able to describe the relationship of two numerical variables, such as runs and at_bats above.

Exercise 2

Looking at your plot from the previous exercise, describe the relationship between these two variables. Make sure to discuss the form, direction, and strength of the relationship as well as any unusual observations.

Answer

As at_bats increase, runs increase, so there is a positive relationship between the two variables. The correlation coefficient of .611 means there is a moderately strong relationship between at_bats and runs, but it’s certainly not 1-to-1 as a correlation coefficient of 1 one would indicate (for every bat, there is a run). So, while the relationship appears positive and increasing, it’s only moderately strong with a fair number of variances from the best fit line.

#Just as we used the mean and standard deviation to summarize a single variable, we can summarize the relationship between these two variables by finding the line that best follows their #association. Use the following interactive function to select the line that you think does the best job of going through the cloud of points.



plot_ss(x = mlb11$at_bats, y = mlb11$runs, showSquares = TRUE)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##  -2789.2429       0.6305  
## 
## Sum of Squares:  123721.9
#showSquares = TRUE   #The most common way to do linear regression is to select the line that minimizes the sum of squared residuals. To visualize the squared residuals, run this line
                     #Note that the output from the plot_ss function provides you with the slope and intercept of your line as well as the sum of squares.

After running this command, you’ll be prompted to click two points on the plot to define a line. Once you’ve done that, the line you specified will be shown in black and the residuals in blue. Note that there are 30 residuals, one for each of the 30 observations. Recall that the residuals are the difference between the observed values and the values predicted by the line:

ei=yi−y^i

Exercise 3

Using plot_ss, choose a line that does a good job of minimizing the sum of squares. Run the function several times. What was the smallest sum of squares that you got? How does it compare to your neighbors?

Answer I ran the function several times. Something appears wrong….my sum of squares didn’t change. It stayed the same, 123721.9 I must have done something wrong.

plot_ss(x = mlb11$at_bats, y = mlb11$runs, showSquares = TRUE)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##  -2789.2429       0.6305  
## 
## Sum of Squares:  123721.9
                     #The most common way to do linear regression is to select the line that minimizes the sum of squared residuals. To visualize the squared residuals, run this line
                     #Note that the output from the plot_ss function provides you with the slope and intercept of your line as well as the sum of squares.

The linear model It is rather cumbersome to try to get the correct least squares line, i.e. the line that minimizes the sum of squared residuals, through trial and error. Instead we can use the lm function in R to fit the linear model (a.k.a. regression line).

m1 <- lm(runs ~ at_bats, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of at_bats
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and at_bats variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ at_bats, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -125.58  -47.05  -16.59   54.40  176.87 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2789.2429   853.6957  -3.267 0.002871 ** 
## at_bats         0.6305     0.1545   4.080 0.000339 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 66.47 on 28 degrees of freedom
## Multiple R-squared:  0.3729, Adjusted R-squared:  0.3505 
## F-statistic: 16.65 on 1 and 28 DF,  p-value: 0.0003388

Let’s consider this output piece by piece: 1. formula used to describe the model. 2. five-number summary of the residuals. 3. The “Coefficients” table shown next is key; its first column displays the linear model’s y-intercept and the coefficient of at_bats. With this table, we can write down the least squares regression line for the linear model:

y^=−2789.2429+0.6305∗atbats

One last piece of information we will discuss from the summary output is the Multiple R-squared, or more simply, R2. The R2 value represents the proportion of variability in the response variable that is explained by the explanatory variable. For this model, 37.3% of the variability in runs is explained by at-bats.

Exercise 4

Fit a new model that uses homeruns to predict runs. Using the estimates from the R output, write the equation of the regression line. What does the slope tell us in the context of the relationship between success of a team and its home runs?

Answer The line is increasing; the slope is positive; the correlation coefficient is fairly linear at 0.7915577
In terms of the slope (rise/run) of the line, for each increase in homeruns, run increases by 1.8345

Equation of the Regression Line The “Coefficients” table shown below is key; its first column displays the linear model’s y-intercept and the coefficient of homeruns. With this table, we can write down the least squares regression line for the linear model:

y^= 415.2389+1.8345∗homeruns

#plot of homeruns to predict runs

plot_ss(x = mlb11$homeruns, y = mlb11$runs, showSquares = TRUE)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##     415.239        1.835  
## 
## Sum of Squares:  73671.99
lm(formula = runs ~ homeruns, data = mlb11)
## 
## Call:
## lm(formula = runs ~ homeruns, data = mlb11)
## 
## Coefficients:
## (Intercept)     homeruns  
##     415.239        1.835
##make a linear model of runs as a function of homeruns
#R should look in the mlb11 data frame to find the runs and homeruns variables.
#The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
m1 <- lm(runs ~ homeruns, data = mlb11)
summary(m1)
## 
## Call:
## lm(formula = runs ~ homeruns, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -91.615 -33.410   3.231  24.292 104.631 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 415.2389    41.6779   9.963 1.04e-10 ***
## homeruns      1.8345     0.2677   6.854 1.90e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 51.29 on 28 degrees of freedom
## Multiple R-squared:  0.6266, Adjusted R-squared:  0.6132 
## F-statistic: 46.98 on 1 and 28 DF,  p-value: 1.9e-07
#If the relationship looks linear, we can quantify the strength of the relationship with the correlation coefficient.
cor(mlb11$runs, mlb11$homeruns)
## [1] 0.7915577

Prediction and prediction errors Let’s create a scatterplot with the least squares line laid on top.

#Extrapolation

#The function abline plots a line based on its slope and intercept. Here, we used a shortcut by providing the model m1, which contains both parameter estimates. This line can be used to #predict y at any value of x. When predictions are made for values of x that are beyond the range of the observed data, it is referred to as extrapolation and is not usually recommended. #However, predictions made within the range of the data are more reliable. They’re also used to compute the residuals.


plot(mlb11$runs ~ mlb11$at_bats)
abline(m1)

Exercise 5

If a team manager saw the least squares regression line and not the actual data, how many runs would he or she predict for a team with 5,578 at-bats? Is this an overestimate or an underestimate, and by how much? In other words, what is the residual for this prediction?

Answer We know from Exercise 3 above that the least squares regression line for the linear model is: y^=−2789.2429+0.6305∗atbats If at_bats = 5,578; so y^=727.6861. Without the actual data, a team manager would predict runs of 727.69 (728) with 5,578 at_bats.

In looking at the data table, there is an at_bat of 5,579 and a run of 713; 728 - 713 = residual overstatement of 15 for this estimate

We ran the following code to get the equation: m1 <- lm(runs ~ at_bats, data = mlb11) #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of at_bats #The second argument specifies that R should look in the mlb11 data frame to find the runs and at_bats variables. #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this #information using the summary function. summary(m1)

#look at the data and pull a close data point 
view(mlb11)    #in the table, there is an at_bat of 5,579 and a run of 713

Model diagnostics To assess whether the linear model is reliable, we need to check for (1) linearity, (2) nearly normal residuals, and (3) constant variability.

Linearity: You already checked if the relationship between runs and at-bats is linear using a scatterplot. We should also verify this condition with a plot of the residuals vs. at-bats. Recall that any code following a # is intended to be a comment that helps understand the code but is ignored by R.

#To assess whether the linear model is reliable, we need to check for (1) linearity, (2) nearly normal residuals, and (3) constant variability.
#ITEM 1:  Linearity:  DID ALL OF THIS ABOVE
#ITEM 1:  Linearity:  Check if relationship between runs and at-bats is linear by verifying condition with a plot of the residuals vs. at-bats.  

plot(m1$residuals ~ mlb11$at_bats)
abline(h = 0, lty = 3)  # adds a horizontal dashed line at y = 0

Exercise 6

#To assess whether the linear model is reliable, we need to check for (1) linearity, (2) nearly normal residuals, and (3) constant variability. #ITEM 1: Linearity: DID ALL OF THIS ABOVE #ITEM 1: Linearity: Check if relationship between runs and at-bats is linear by verifying condition with a plot of the residuals vs. at-bats. #Item 2: Nearly Normal Residuals: Histogram #Item 2: Nearly Normal Residuals: or a normal probability plot of the residuals.

Is there any apparent pattern in the residuals plot? What does this indicate about the linearity of the relationship between runs and at-bats?

Answer There is no apparent pattern in the residuals plot.

This indicates the relationship between runs and at-bats is linear.

#Nearly normal residuals: To check this condition, we can look at a histogram
hist(m1$residuals)

#or a normal probability plot of the residuals.
qqnorm(m1$residuals)
qqline(m1$residuals)  # adds diagonal line to the normal prob plot

Exercise 7

Based on the histogram and the normal probability plot, does the nearly normal residuals condition appear to be met?

Answer

Yes, based on the histogram and normal probability plot, there appears to be a normal distribution with very few extreme variances.

Exercise 8

Based on the plot in (1), does the constant variability condition appear to be met?

Answer

The constant variability condition is met when the points around the line appear to be evenly varied/distanced. Yes, the constant variability condition appears to be met based on the plot in (1).

ON YOUR OWN 1

Choose another traditional variable from mlb11 that you think might be a good predictor of runs. Produce a scatterplot of the two variables and fit a linear model. At a glance, does there seem to be a linear relationship?

Answer Scatterplot with a linear model: Traditional variable selected = bat_avg Does there seem to be a linear relationship: Yes, there seems to be a linear relationship. The correlation coefficient of .8099 indicates a linear relationship between batting average and runs. The slope is positive between the two variables.

#scatterplot 

plot(mlb11$runs ~ mlb11$bat_avg,
     main = "Relationship Between Runs and Bat_Avg",
     ylab = "Runs", 
     xlab = "Bat_Avg",)


#fit a simple linear regression model
model <- lm(mlb11$run ~ mlb11$bat_avg, data = mlb11)

#add the fitted regression line to the scatterplot
abline(model)

#If the relationship looks linear, we can quantify the strength of the relationship with the correlation coefficient.
cor(mlb11$runs, mlb11$bat_avg)
## [1] 0.8099859

ON YOUR OWN 2

How does this relationship compare to the relationship between runs and at_bats? Use the R2 values from the two model summaries to compare. Does your variable seem to predict runs better than at_bats? How can you tell?

Answer

R2 - at_bats: 0.3729 R2 - bat_avg: 0.6561

Based on the values of R2, the relationship between runs and bat_avg seems is stronger than that of runs and at_bats. The R2 value for the linear model using at_bats is 0.3729 while for the linear model using bat_avg is 0.6561. The linear model using bat_avg is a better predictor of runs. The sum of residuals for the linear model using the variable at_bats as a predictor of runs is 123721.9 (see R Console output of plot_ss) and for the linear model using the variable bat_avg as a predictor of runs is 67849.52 (see R Console output of plot_ss). The model summary using bat_avg is the best predictor of runs as compared to that of the model using the at_bats variable.

#Runs and AT_BATS
plot_ss(x = mlb11$at_bats, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##  -2789.2429       0.6305  
## 
## Sum of Squares:  123721.9

The linear model use the lm function in R to fit the linear model (a.k.a. regression line).

m1 <- lm(runs ~ at_bats, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of at_bats
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and at_bats variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ at_bats, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -125.58  -47.05  -16.59   54.40  176.87 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2789.2429   853.6957  -3.267 0.002871 ** 
## at_bats         0.6305     0.1545   4.080 0.000339 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 66.47 on 28 degrees of freedom
## Multiple R-squared:  0.3729, Adjusted R-squared:  0.3505 
## F-statistic: 16.65 on 1 and 28 DF,  p-value: 0.0003388
#BAT_AVB
plot_ss(x = mlb11$bat_avg, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##      -642.8       5242.2  
## 
## Sum of Squares:  67849.52
m1 <- lm(runs ~ bat_avg, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of at_bats
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and at_bats variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ bat_avg, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -94.676 -26.303  -5.496  28.482 131.113 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -642.8      183.1  -3.511  0.00153 ** 
## bat_avg       5242.2      717.3   7.308 5.88e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 49.23 on 28 degrees of freedom
## Multiple R-squared:  0.6561, Adjusted R-squared:  0.6438 
## F-statistic: 53.41 on 1 and 28 DF,  p-value: 5.877e-08

ON YOUR OWN 3

Now that you can summarize the linear relationship between two variables, investigate the relationships between runs and each of the other five traditional variables. Which variable best predicts runs? Support your conclusion using the graphical and numerical methods we’ve discussed (for the sake of conciseness, only include output for the best variable, not all five).

Answer 1. R2 - hits: 0.6419 1. Sum of Residuals - hits: 70638.75

  1. R2 - homeruns: 0.6266

  2. Sum of Residuals - homeruns: 73671.99

  3. R2 - strikeouts: 0.1694

  4. Sum of Residuals - strikeouts: 163870.1

  5. R2 - stolen_bases: 0.002914

  6. Sum of Residuals - Stolen Bases: 196706.3

  7. R2 - wins: 0.361

  8. Sum of Residuals - Wins: 126068.4

Based on the values of R2, the relationship between runs and hits and runs and homeruns is very close at .64 for hits and .63 for homeruns. Hits appears to be the best predictor as far as R2 value is concerned, but it is very close to homeruns. Using the sum of residuals between hits and homeruns, homeruns is a better predictor at 73,672 vs 70,639. Using sum of residuals, however, stolen_bases appears to be the strongest predictor of runs at 196,703 as compared to the other models.

Overall, in looking at the traditional variables, bat_bat avg. appears to be the best predictor followed by hits.

# all plots together
trad1=lm(runs~hits,data=mlb11)
trad2=lm(runs~homeruns,data=mlb11)
trad3=lm(runs~strikeouts,data=mlb11)
trad4=lm(runs~stolen_bases, data=mlb11)
trad5=lm(runs~wins,data=mlb11)
par(mfrow=c(2,3))
plot(mlb11$hits,mlb11$runs,xlab="Hits",ylab="Runs",main="Hits Vs Runs") 
abline(trad1)
plot(mlb11$homeruns,mlb11$runs,xlab="Homeruns",ylab="Runs",main="Homeruns Vs Runs") 
abline(trad2)
plot(mlb11$strikeouts,mlb11$runs,xlab="Strikeouts",ylab="Runs",main="Strikeouts Vs Runs") 
abline(trad3)
plot(mlb11$stolen_bases,mlb11$runs,xlab="Stolen Bases",ylab="Runs",main="Stolen Bases Vs Runs") 
abline(trad4)
plot(mlb11$wins,mlb11$runs,xlab="Wins",ylab="Runs",main="Wins Vs Runs") 
abline(trad5)

#1.  Runs and HITS
plot_ss(x = mlb11$hits, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##   -375.5600       0.7589  
## 
## Sum of Squares:  70638.75
##1.  Runs and HITS
m1 <- lm(runs ~ hits, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of hits
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and hits variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ hits, data = mlb11)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -103.718  -27.179   -5.233   19.322  140.693 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -375.5600   151.1806  -2.484   0.0192 *  
## hits           0.7589     0.1071   7.085 1.04e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 50.23 on 28 degrees of freedom
## Multiple R-squared:  0.6419, Adjusted R-squared:  0.6292 
## F-statistic:  50.2 on 1 and 28 DF,  p-value: 1.043e-07
#2.  Runs and HOMERUNS
plot_ss(x = mlb11$homeruns, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##     415.239        1.835  
## 
## Sum of Squares:  73671.99
##2.  Runs and HOMERUNS
m1 <- lm(runs ~ homeruns, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of homeruns
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and homeruns variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ homeruns, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -91.615 -33.410   3.231  24.292 104.631 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 415.2389    41.6779   9.963 1.04e-10 ***
## homeruns      1.8345     0.2677   6.854 1.90e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 51.29 on 28 degrees of freedom
## Multiple R-squared:  0.6266, Adjusted R-squared:  0.6132 
## F-statistic: 46.98 on 1 and 28 DF,  p-value: 1.9e-07
#3.  Runs and STRIKEOUTS
plot_ss(x = mlb11$strikeouts, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##   1054.7342      -0.3141  
## 
## Sum of Squares:  163870.1
##3.  Runs and STRIKEOUTS
m1 <- lm(runs ~ strikeouts, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of strikeouts
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and strikeouts variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ strikeouts, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -132.27  -46.95  -11.92   55.14  169.76 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 1054.7342   151.7890   6.949 1.49e-07 ***
## strikeouts    -0.3141     0.1315  -2.389   0.0239 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 76.5 on 28 degrees of freedom
## Multiple R-squared:  0.1694, Adjusted R-squared:  0.1397 
## F-statistic: 5.709 on 1 and 28 DF,  p-value: 0.02386
#4.  Runs and STOLEN BASES
plot_ss(x = mlb11$stolen_bases, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##    677.3074       0.1491  
## 
## Sum of Squares:  196706.3
##4.  Runs and STOLEN BASES
m1 <- lm(runs ~ stolen_bases, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of stolen bases
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and stolen bases variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ stolen_bases, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -139.94  -62.87   10.01   38.54  182.49 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  677.3074    58.9751  11.485 4.17e-12 ***
## stolen_bases   0.1491     0.5211   0.286    0.777    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 83.82 on 28 degrees of freedom
## Multiple R-squared:  0.002914,   Adjusted R-squared:  -0.0327 
## F-statistic: 0.08183 on 1 and 28 DF,  p-value: 0.7769
#5.  Runs and Wins
plot_ss(x = mlb11$wins, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##     342.121        4.341  
## 
## Sum of Squares:  126068.4
##5.  Runs and STOLEN BASES
m1 <- lm(runs ~ wins, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of wins
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and wins variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ wins, data = mlb11)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -145.450  -47.506   -7.482   47.346  142.186 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  342.121     89.223   3.834 0.000654 ***
## wins           4.341      1.092   3.977 0.000447 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 67.1 on 28 degrees of freedom
## Multiple R-squared:  0.361,  Adjusted R-squared:  0.3381 
## F-statistic: 15.82 on 1 and 28 DF,  p-value: 0.0004469

ON YOUR OWN 4

Now examine the three newer variables. These are the statistics used by the author of Moneyball to predict a teams success. In general, are they more or less effective at predicting runs that the old variables? Explain using appropriate graphical and numerical evidence. Of all ten variables we’ve analyzed, which seems to be the best predictor of runs? Using the limited (or not so limited) information you know about these baseball statistics, does your result make sense?

Answer

Answer The new variables, Onbase, slug, and obs, have higher R2 values than the traditional variables. The Sum of Squares for the residuals is less for the new variables than for the traditional variables. With the R2 values being higher and sum of squares of residual being less for the new variables, the new variables are more effective predictors of runs than the traditional variables. Of all ten variables we’ve analyzed, the new variables seem to be the best predictor of runs, with new_obs being the best of the three.

NEW VARIABLES 1. R2 - new_onbase: 0.8491 1. Sum of Residuals - new_onbase: 29768.7

  1. R2 - new_slug: 0.8969

  2. Sum of Residuals - new_slug: 20345.54

  3. R2 - new_obs: 0.9349

  4. Sum of Residuals - new_obs: 12837.66

TRADITIONAL VARIABILES (SEE ON YOUR OWN 3 FOR WORK) R2 - hits: 0.6419 1. Sum of Residuals - hits: 70638.75

  1. R2 - homeruns: 0.6266

  2. Sum of Residuals - homeruns: 73671.99

  3. R2 - strikeouts: 0.1694

  4. Sum of Residuals - strikeouts: 163870.1

  5. R2 - stolen_bases: 0.002914

  6. Sum of Residuals - Stolen Bases: 196706.3

  7. R2 - wins: 0.361

  8. Sum of Residuals - Wins: 126068.4

# all plots together
new1=lm(runs~new_onbase,data=mlb11)
new2=lm(runs~new_slug,data=mlb11)
new3=lm(runs~new_obs,data=mlb11)
par(mfrow=c(1,3))
plot(mlb11$new_onbase,mlb11$runs,xlab="New On Base",ylab="Runs",main="New On Base Vs Runs") 
abline(new1)
plot(mlb11$new_slug,mlb11$runs,xlab="New Slug",ylab="Runs",main="New Slug Vs Runs") 
abline(new2)
plot(mlb11$new_obs,mlb11$runs,xlab="New Obs",ylab="Runs",main="New Obs Vs Runs") 
abline(new3)

summary(new1)
## 
## Call:
## lm(formula = runs ~ new_onbase, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -58.270 -18.335   3.249  19.520  69.002 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -1118.4      144.5  -7.741 1.97e-08 ***
## new_onbase    5654.3      450.5  12.552 5.12e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 32.61 on 28 degrees of freedom
## Multiple R-squared:  0.8491, Adjusted R-squared:  0.8437 
## F-statistic: 157.6 on 1 and 28 DF,  p-value: 5.116e-13
summary(new2)
## 
## Call:
## lm(formula = runs ~ new_slug, data = mlb11)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -45.41 -18.66  -0.91  16.29  52.29 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -375.80      68.71   -5.47 7.70e-06 ***
## new_slug     2681.33     171.83   15.61 2.42e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 26.96 on 28 degrees of freedom
## Multiple R-squared:  0.8969, Adjusted R-squared:  0.8932 
## F-statistic: 243.5 on 1 and 28 DF,  p-value: 2.42e-15
summary(new3)
## 
## Call:
## lm(formula = runs ~ new_obs, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -43.456 -13.690   1.165  13.935  41.156 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -686.61      68.93  -9.962 1.05e-10 ***
## new_obs      1919.36      95.70  20.057  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 21.41 on 28 degrees of freedom
## Multiple R-squared:  0.9349, Adjusted R-squared:  0.9326 
## F-statistic: 402.3 on 1 and 28 DF,  p-value: < 2.2e-16
#1.  Runs and new_onbase
plot_ss(x = mlb11$new_onbase, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##       -1118         5654  
## 
## Sum of Squares:  29768.7
##1.  Runs and new_onbase
m1 <- lm(runs ~ new_onbase, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of new_onbase
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and new_onbase variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ new_onbase, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -58.270 -18.335   3.249  19.520  69.002 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -1118.4      144.5  -7.741 1.97e-08 ***
## new_onbase    5654.3      450.5  12.552 5.12e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 32.61 on 28 degrees of freedom
## Multiple R-squared:  0.8491, Adjusted R-squared:  0.8437 
## F-statistic: 157.6 on 1 and 28 DF,  p-value: 5.116e-13
#1.  Runs and new_slug
plot_ss(x = mlb11$new_slug, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##      -375.8       2681.3  
## 
## Sum of Squares:  20345.54
##1.  Runs and new_slug
m1 <- lm(runs ~ new_onbase, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of new_slug
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and new_slug variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ new_onbase, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -58.270 -18.335   3.249  19.520  69.002 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -1118.4      144.5  -7.741 1.97e-08 ***
## new_onbase    5654.3      450.5  12.552 5.12e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 32.61 on 28 degrees of freedom
## Multiple R-squared:  0.8491, Adjusted R-squared:  0.8437 
## F-statistic: 157.6 on 1 and 28 DF,  p-value: 5.116e-13
#1.  Runs and new_obs
plot_ss(x = mlb11$new_obs, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##      -686.6       1919.4  
## 
## Sum of Squares:  12837.66
##1.  Runs and new_obs
m1 <- lm(runs ~ new_obs, data = mlb11)  #lm is a formula that takes the form y ~ x. Here it can be read that we want to make a linear model of runs as a function of new_obs
                                        #The second argument specifies that R should look in the mlb11 data frame to find the runs and new_obs variables.
                                        #The output of lm is an object that contains all of the information we need about the linear model that was just fit. We can access this 
                                              #information using the summary function.
summary(m1)
## 
## Call:
## lm(formula = runs ~ new_obs, data = mlb11)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -43.456 -13.690   1.165  13.935  41.156 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -686.61      68.93  -9.962 1.05e-10 ***
## new_obs      1919.36      95.70  20.057  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 21.41 on 28 degrees of freedom
## Multiple R-squared:  0.9349, Adjusted R-squared:  0.9326 
## F-statistic: 402.3 on 1 and 28 DF,  p-value: < 2.2e-16

ON YOUR OWN 5

Check the model diagnostics for the regression model with the variable you decided was the best predictor for runs.

Answer

As noted in On Your Own 5, new_obs is the best variable for predicting runs. New_obs R2 value is higher than all other models at .935 (rounded to the 3rd decimal place), and the sum of square residuals error is lower than all the other models at 12837.66.

  1. R2 - new_obs: 0.9349
  2. Sum of Residuals - new_obs: 12837.66
new3=lm(runs~new_obs,data=mlb11)
par(mfrow=c(1,1))
plot(mlb11$new_obs,mlb11$runs,xlab="New Obs",ylab="Runs",main="New Obs Vs Runs") 
abline(new3)

#1.  Runs and new_obs
plot_ss(x = mlb11$new_obs, y = mlb11$runs)

## Click two points to make a line.
                                
## Call:
## lm(formula = y ~ x, data = pts)
## 
## Coefficients:
## (Intercept)            x  
##      -686.6       1919.4  
## 
## Sum of Squares:  12837.66
LS0tDQp0aXRsZTogIkludHJvIHRvIExpbmVhciBSZWdyZXNzaW9uIC0gV2VlayAxMSINCmF1dGhvcjogIkFhcnluIFppbW1lcm1hbiINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KYGBge3IgbG9hZC1wYWNrYWdlcywgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShvcGVuaW50cm8pDQpsaWJyYXJ5KHN0YXRzcikNCg0KYGBgDQpJbiB0aGlzIGxhYiB3ZeKAmWxsIGJlIGxvb2tpbmcgYXQgZGF0YSBmcm9tIGFsbCAzMCBNYWpvciBMZWFndWUgQmFzZWJhbGwgdGVhbXMgYW5kIGV4YW1pbmluZyB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHJ1bnMgc2NvcmVkIGluIGEgc2Vhc29uIGFuZCBhIG51bWJlciBvZiBvdGhlciBwbGF5ZXIgc3RhdGlzdGljcy4gT3VyIGFpbSB3aWxsIGJlIHRvIHN1bW1hcml6ZSB0aGVzZSByZWxhdGlvbnNoaXBzIGJvdGggZ3JhcGhpY2FsbHkgYW5kIG51bWVyaWNhbGx5IGluIG9yZGVyIHRvIGZpbmQgd2hpY2ggdmFyaWFibGUsIGlmIGFueSwgaGVscHMgdXMgYmVzdCBwcmVkaWN0IGEgdGVhbeKAmXMgcnVucyBzY29yZWQgaW4gYSBzZWFzb24uDQoNCmBgYHtyfQ0KI2xvYWQgdGhlIGRhdGENCg0KZG93bmxvYWQuZmlsZSgiaHR0cDovL3d3dy5vcGVuaW50cm8ub3JnL3N0YXQvZGF0YS9tbGIxMS5SRGF0YSIsIGRlc3RmaWxlID0gIm1sYjExLlJEYXRhIikNCmxvYWQoIm1sYjExLlJEYXRhIikNCg0KDQpgYGANCkluIGFkZGl0aW9uIHRvIHJ1bnMgc2NvcmVkLCB0aGVyZSBhcmUgc2V2ZW4gdHJhZGl0aW9uYWxseSB1c2VkIHZhcmlhYmxlcyBpbiB0aGUgZGF0YSBzZXQ6IGF0LWJhdHMsIGhpdHMsIGhvbWUgcnVucywgYmF0dGluZyBhdmVyYWdlLCBzdHJpa2VvdXRzLCBzdG9sZW4gYmFzZXMsIGFuZCB3aW5zLiBUaGVyZSBhcmUgYWxzbyB0aHJlZSBuZXdlciB2YXJpYWJsZXM6IG9uLWJhc2UgcGVyY2VudGFnZSwgc2x1Z2dpbmcgcGVyY2VudGFnZSwgYW5kIG9uLWJhc2UgcGx1cyBzbHVnZ2luZy4gRm9yIHRoZSBmaXJzdCBwb3J0aW9uIG9mIHRoZSBhbmFseXNpcyB3ZeKAmWxsIGNvbnNpZGVyIHRoZSBzZXZlbiB0cmFkaXRpb25hbCB2YXJpYWJsZXMuIEF0IHRoZSBlbmQgb2YgdGhlIGxhYiwgeW914oCZbGwgd29yayB3aXRoIHRoZSBuZXdlciB2YXJpYWJsZXMgb24geW91ciBvd24uDQoNCmBgYHtyfQ0Kc3VtbWFyeShtbGIxMSkNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSAxDQoNCldoYXQgdHlwZSBvZiBwbG90IHdvdWxkIHlvdSB1c2UgdG8gZGlzcGxheSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gcnVucyBhbmQgb25lIG9mIHRoZSBvdGhlciBudW1lcmljYWwgdmFyaWFibGVzPyBQbG90IHRoaXMgcmVsYXRpb25zaGlwIHVzaW5nIHRoZSB2YXJpYWJsZSBhdF9iYXRzIGFzIHRoZSBwcmVkaWN0b3IuIERvZXMgdGhlIHJlbGF0aW9uc2hpcCBsb29rIGxpbmVhcj8gSWYgeW91IGtuZXcgYSB0ZWFt4oCZcyBhdF9iYXRzLCB3b3VsZCB5b3UgYmUgY29tZm9ydGFibGUgdXNpbmcgYSBsaW5lYXIgbW9kZWwgdG8gcHJlZGljdCB0aGUgbnVtYmVyIG9mIHJ1bnM/DQoNCg0KKioqQW5zd2VyKioqDQoxLiAgSSB3b3VsZCB1c2UgYSBzY2F0dGVycGxvdCB0byBkaXNwbGF5IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBydW5zIGFuZCBvbmUgb2YgdGhlIG90aGVyIG51bWVyaWNhbCB2YXJpYWJsZXMgc3VjaCBhcyBhdF9iYXRzLg0KMi4gIFNlZSBQbG90IGJlbG93IGJldHdlZW4gcnVucyBhbmQgYXRfYmF0cw0KMy4gIFRoZSB0cmVuZCBkb2VzIHNob3cgc29tZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gcnVucyBhbmQgYXRfYmF0cywgYnV0IHRoZXJlIGFwcGVhcnMgdG8gYmUgYSBsb3Qgb2YgdmFyaWF0aW9uLCBzbyB0aGUgbGluZWFyIG1vZGVsIGRvZXNuJ3QgYXBwZWFyIHRvIGJlIHZlcnkgdXNlZnVsIGFzIGFuIGFjY3VyYXRlIHByZWRpY3RvciBpbiB0aGlzIGNhc2UuDQoNCg0KDQpgYGB7ciBjb2RlLWNodW5rLWxhYmVsfQ0KI3NjYXR0ZXJwbG90IA0KDQpwbG90KG1sYjExJHJ1bnMgfiBtbGIxMSRhdF9iYXRzLA0KICAgICBtYWluID0gIlJlbGF0aW9uc2hpcCBCZXR3ZWVuIFJ1bnMgYW5kIEF0X0JhdHMiLA0KICAgICB5bGFiID0gIlJ1bnMiLCANCiAgICAgeGxhYiA9ICJBdF9CYXRzIikNCmBgYA0KDQoNCmBgYHtyfQ0KI0lmIHRoZSByZWxhdGlvbnNoaXAgbG9va3MgbGluZWFyLCB3ZSBjYW4gcXVhbnRpZnkgdGhlIHN0cmVuZ3RoIG9mIHRoZSByZWxhdGlvbnNoaXAgd2l0aCB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQuDQpjb3IobWxiMTEkcnVucywgbWxiMTEkYXRfYmF0cykNCg0KDQpgYGANClN1bSBvZiBzcXVhcmVkIHJlc2lkdWFscw0KVGhpbmsgYmFjayB0byB0aGUgd2F5IHRoYXQgd2UgZGVzY3JpYmVkIHRoZSBkaXN0cmlidXRpb24gb2YgYSBzaW5nbGUgdmFyaWFibGUuIFJlY2FsbCB0aGF0IHdlIGRpc2N1c3NlZCBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyBjZW50ZXIsIHNwcmVhZCwgYW5kIHNoYXBlLiBJdOKAmXMgYWxzbyB1c2VmdWwgdG8gYmUgYWJsZSB0byBkZXNjcmliZSB0aGUgcmVsYXRpb25zaGlwIG9mIHR3byBudW1lcmljYWwgdmFyaWFibGVzLCBzdWNoIGFzIHJ1bnMgYW5kIGF0X2JhdHMgYWJvdmUuDQoNCg0KIyMjIEV4ZXJjaXNlIDINCkxvb2tpbmcgYXQgeW91ciBwbG90IGZyb20gdGhlIHByZXZpb3VzIGV4ZXJjaXNlLCBkZXNjcmliZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlc2UgdHdvIHZhcmlhYmxlcy4gTWFrZSBzdXJlIHRvIGRpc2N1c3MgdGhlIGZvcm0sIGRpcmVjdGlvbiwgYW5kIHN0cmVuZ3RoIG9mIHRoZSByZWxhdGlvbnNoaXAgYXMgd2VsbCBhcyBhbnkgdW51c3VhbCBvYnNlcnZhdGlvbnMuDQoNCg0KKioqQW5zd2VyKioqDQoNCkFzIGF0X2JhdHMgaW5jcmVhc2UsIHJ1bnMgaW5jcmVhc2UsIHNvIHRoZXJlIGlzIGEgcG9zaXRpdmUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHR3byB2YXJpYWJsZXMuICBUaGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgb2YgLjYxMSBtZWFucyB0aGVyZSBpcyBhIG1vZGVyYXRlbHkgc3Ryb25nIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGF0X2JhdHMgYW5kIHJ1bnMsIGJ1dCBpdCdzIGNlcnRhaW5seSBub3QgMS10by0xIGFzIGEgY29ycmVsYXRpb24gY29lZmZpY2llbnQgb2YgMSBvbmUgd291bGQgaW5kaWNhdGUgKGZvciBldmVyeSBiYXQsIHRoZXJlIGlzIGEgcnVuKS4gIFNvLCB3aGlsZSB0aGUgcmVsYXRpb25zaGlwIGFwcGVhcnMgcG9zaXRpdmUgYW5kIGluY3JlYXNpbmcsIGl0J3Mgb25seSBtb2RlcmF0ZWx5IHN0cm9uZyB3aXRoIGEgZmFpciBudW1iZXIgb2YgdmFyaWFuY2VzIGZyb20gdGhlIGJlc3QgZml0IGxpbmUuDQoNCg0KYGBge3J9DQoNCg0KI0p1c3QgYXMgd2UgdXNlZCB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIHRvIHN1bW1hcml6ZSBhIHNpbmdsZSB2YXJpYWJsZSwgd2UgY2FuIHN1bW1hcml6ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlc2UgdHdvIHZhcmlhYmxlcyBieSBmaW5kaW5nIHRoZSBsaW5lIHRoYXQgYmVzdCBmb2xsb3dzIHRoZWlyICNhc3NvY2lhdGlvbi4gVXNlIHRoZSBmb2xsb3dpbmcgaW50ZXJhY3RpdmUgZnVuY3Rpb24gdG8gc2VsZWN0IHRoZSBsaW5lIHRoYXQgeW91IHRoaW5rIGRvZXMgdGhlIGJlc3Qgam9iIG9mIGdvaW5nIHRocm91Z2ggdGhlIGNsb3VkIG9mIHBvaW50cy4NCg0KDQoNCnBsb3Rfc3MoeCA9IG1sYjExJGF0X2JhdHMsIHkgPSBtbGIxMSRydW5zLCBzaG93U3F1YXJlcyA9IFRSVUUpDQoNCiNzaG93U3F1YXJlcyA9IFRSVUUgICAjVGhlIG1vc3QgY29tbW9uIHdheSB0byBkbyBsaW5lYXIgcmVncmVzc2lvbiBpcyB0byBzZWxlY3QgdGhlIGxpbmUgdGhhdCBtaW5pbWl6ZXMgdGhlIHN1bSBvZiBzcXVhcmVkIHJlc2lkdWFscy4gVG8gdmlzdWFsaXplIHRoZSBzcXVhcmVkIHJlc2lkdWFscywgcnVuIHRoaXMgbGluZQ0KICAgICAgICAgICAgICAgICAgICAgI05vdGUgdGhhdCB0aGUgb3V0cHV0IGZyb20gdGhlIHBsb3Rfc3MgZnVuY3Rpb24gcHJvdmlkZXMgeW91IHdpdGggdGhlIHNsb3BlIGFuZCBpbnRlcmNlcHQgb2YgeW91ciBsaW5lIGFzIHdlbGwgYXMgdGhlIHN1bSBvZiBzcXVhcmVzLg0KYGBgDQoNCg0KQWZ0ZXIgcnVubmluZyB0aGlzIGNvbW1hbmQsIHlvdeKAmWxsIGJlIHByb21wdGVkIHRvIGNsaWNrIHR3byBwb2ludHMgb24gdGhlIHBsb3QgdG8gZGVmaW5lIGEgbGluZS4gT25jZSB5b3XigJl2ZSBkb25lIHRoYXQsIHRoZSBsaW5lIHlvdSBzcGVjaWZpZWQgd2lsbCBiZSBzaG93biBpbiBibGFjayBhbmQgdGhlIHJlc2lkdWFscyBpbiBibHVlLiBOb3RlIHRoYXQgdGhlcmUgYXJlIDMwIHJlc2lkdWFscywgb25lIGZvciBlYWNoIG9mIHRoZSAzMCBvYnNlcnZhdGlvbnMuIFJlY2FsbCB0aGF0IHRoZSByZXNpZHVhbHMgYXJlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIG9ic2VydmVkIHZhbHVlcyBhbmQgdGhlIHZhbHVlcyBwcmVkaWN0ZWQgYnkgdGhlIGxpbmU6DQoNCmVpPXlp4oiSeV5pDQoNCg0KYGBge3J9DQoNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSAzDQpVc2luZyBwbG90X3NzLCBjaG9vc2UgYSBsaW5lIHRoYXQgZG9lcyBhIGdvb2Qgam9iIG9mIG1pbmltaXppbmcgdGhlIHN1bSBvZiBzcXVhcmVzLiBSdW4gdGhlIGZ1bmN0aW9uIHNldmVyYWwgdGltZXMuIFdoYXQgd2FzIHRoZSBzbWFsbGVzdCBzdW0gb2Ygc3F1YXJlcyB0aGF0IHlvdSBnb3Q/IEhvdyBkb2VzIGl0IGNvbXBhcmUgdG8geW91ciBuZWlnaGJvcnM/DQoNCg0KKioqQW5zd2VyKioqDQpJIHJhbiB0aGUgZnVuY3Rpb24gc2V2ZXJhbCB0aW1lcy4gIFNvbWV0aGluZyBhcHBlYXJzIHdyb25nLi4uLm15IHN1bSBvZiBzcXVhcmVzIGRpZG4ndCBjaGFuZ2UuICBJdCBzdGF5ZWQgdGhlIHNhbWUsIDEyMzcyMS45ICBJIG11c3QgaGF2ZSBkb25lIHNvbWV0aGluZyB3cm9uZy4NCg0KDQpgYGB7cn0NCg0KDQpwbG90X3NzKHggPSBtbGIxMSRhdF9iYXRzLCB5ID0gbWxiMTEkcnVucywgc2hvd1NxdWFyZXMgPSBUUlVFKQ0KICAgICAgICAgICAgICAgICAgICAgI1RoZSBtb3N0IGNvbW1vbiB3YXkgdG8gZG8gbGluZWFyIHJlZ3Jlc3Npb24gaXMgdG8gc2VsZWN0IHRoZSBsaW5lIHRoYXQgbWluaW1pemVzIHRoZSBzdW0gb2Ygc3F1YXJlZCByZXNpZHVhbHMuIFRvIHZpc3VhbGl6ZSB0aGUgc3F1YXJlZCByZXNpZHVhbHMsIHJ1biB0aGlzIGxpbmUNCiAgICAgICAgICAgICAgICAgICAgICNOb3RlIHRoYXQgdGhlIG91dHB1dCBmcm9tIHRoZSBwbG90X3NzIGZ1bmN0aW9uIHByb3ZpZGVzIHlvdSB3aXRoIHRoZSBzbG9wZSBhbmQgaW50ZXJjZXB0IG9mIHlvdXIgbGluZSBhcyB3ZWxsIGFzIHRoZSBzdW0gb2Ygc3F1YXJlcy4NCg0KDQpgYGANCmBgYHtyfQ0KDQpgYGANCg0KVGhlIGxpbmVhciBtb2RlbA0KSXQgaXMgcmF0aGVyIGN1bWJlcnNvbWUgdG8gdHJ5IHRvIGdldCB0aGUgY29ycmVjdCBsZWFzdCBzcXVhcmVzIGxpbmUsIGkuZS4gdGhlIGxpbmUgdGhhdCBtaW5pbWl6ZXMgdGhlIHN1bSBvZiBzcXVhcmVkIHJlc2lkdWFscywgdGhyb3VnaCB0cmlhbCBhbmQgZXJyb3IuIEluc3RlYWQgd2UgY2FuIHVzZSB0aGUgbG0gZnVuY3Rpb24gaW4gUiB0byBmaXQgdGhlIGxpbmVhciBtb2RlbCAoYS5rLmEuIHJlZ3Jlc3Npb24gbGluZSkuDQoNCmBgYHtyfQ0KbTEgPC0gbG0ocnVucyB+IGF0X2JhdHMsIGRhdGEgPSBtbGIxMSkgICNsbSBpcyBhIGZvcm11bGEgdGhhdCB0YWtlcyB0aGUgZm9ybSB5IH4geC4gSGVyZSBpdCBjYW4gYmUgcmVhZCB0aGF0IHdlIHdhbnQgdG8gbWFrZSBhIGxpbmVhciBtb2RlbCBvZiBydW5zIGFzIGEgZnVuY3Rpb24gb2YgYXRfYmF0cw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGF0IFIgc2hvdWxkIGxvb2sgaW4gdGhlIG1sYjExIGRhdGEgZnJhbWUgdG8gZmluZCB0aGUgcnVucyBhbmQgYXRfYmF0cyB2YXJpYWJsZXMuDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBvdXRwdXQgb2YgbG0gaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIGFib3V0IHRoZSBsaW5lYXIgbW9kZWwgdGhhdCB3YXMganVzdCBmaXQuIFdlIGNhbiBhY2Nlc3MgdGhpcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjaW5mb3JtYXRpb24gdXNpbmcgdGhlIHN1bW1hcnkgZnVuY3Rpb24uDQpzdW1tYXJ5KG0xKQ0KYGBgDQpMZXTigJlzIGNvbnNpZGVyIHRoaXMgb3V0cHV0IHBpZWNlIGJ5IHBpZWNlOg0KMS4gIGZvcm11bGEgdXNlZCB0byBkZXNjcmliZSB0aGUgbW9kZWwuIA0KMi4gIGZpdmUtbnVtYmVyIHN1bW1hcnkgb2YgdGhlIHJlc2lkdWFscy4gDQozLiAgVGhlIOKAnENvZWZmaWNpZW50c+KAnSB0YWJsZSBzaG93biBuZXh0IGlzIGtleTsgaXRzIGZpcnN0IGNvbHVtbiBkaXNwbGF5cyB0aGUgbGluZWFyIG1vZGVs4oCZcyB5LWludGVyY2VwdCBhbmQgdGhlIGNvZWZmaWNpZW50IG9mIGF0X2JhdHMuIFdpdGggdGhpcyB0YWJsZSwgd2UgY2FuIHdyaXRlIGRvd24gdGhlIGxlYXN0IHNxdWFyZXMgcmVncmVzc2lvbiBsaW5lIGZvciB0aGUgbGluZWFyIG1vZGVsOg0KDQp5Xj3iiJIyNzg5LjI0MjkrMC42MzA14oiXYXRiYXRzDQoNCk9uZSBsYXN0IHBpZWNlIG9mIGluZm9ybWF0aW9uIHdlIHdpbGwgZGlzY3VzcyBmcm9tIHRoZSBzdW1tYXJ5IG91dHB1dCBpcyB0aGUgTXVsdGlwbGUgUi1zcXVhcmVkLCBvciBtb3JlIHNpbXBseSwgUjIuIFRoZSBSMiB2YWx1ZSByZXByZXNlbnRzIHRoZSBwcm9wb3J0aW9uIG9mIHZhcmlhYmlsaXR5IGluIHRoZSByZXNwb25zZSB2YXJpYWJsZSB0aGF0IGlzIGV4cGxhaW5lZCBieSB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGUuIEZvciB0aGlzIG1vZGVsLCAzNy4zJSBvZiB0aGUgdmFyaWFiaWxpdHkgaW4gcnVucyBpcyBleHBsYWluZWQgYnkgYXQtYmF0cy4NCg0KDQoNCmBgYHtyfQ0KDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgNA0KDQpGaXQgYSBuZXcgbW9kZWwgdGhhdCB1c2VzIGhvbWVydW5zIHRvIHByZWRpY3QgcnVucy4gVXNpbmcgdGhlIGVzdGltYXRlcyBmcm9tIHRoZSBSIG91dHB1dCwgd3JpdGUgdGhlIGVxdWF0aW9uIG9mIHRoZSByZWdyZXNzaW9uIGxpbmUuIFdoYXQgZG9lcyB0aGUgc2xvcGUgdGVsbCB1cyBpbiB0aGUgY29udGV4dCBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gc3VjY2VzcyBvZiBhIHRlYW0gYW5kIGl0cyBob21lIHJ1bnM/DQoNCg0KKioqQW5zd2VyKioqDQpUaGUgbGluZSBpcyBpbmNyZWFzaW5nOyB0aGUgc2xvcGUgaXMgcG9zaXRpdmU7IHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBpcyBmYWlybHkgbGluZWFyIGF0IDAuNzkxNTU3NyAgDQpJbiB0ZXJtcyBvZiB0aGUgc2xvcGUgKHJpc2UvcnVuKSBvZiB0aGUgbGluZSwgZm9yIGVhY2ggaW5jcmVhc2UgaW4gaG9tZXJ1bnMsIHJ1biBpbmNyZWFzZXMgYnkgMS44MzQ1ICANCg0KDQpFcXVhdGlvbiBvZiB0aGUgUmVncmVzc2lvbiBMaW5lDQpUaGUg4oCcQ29lZmZpY2llbnRz4oCdIHRhYmxlIHNob3duIGJlbG93IGlzIGtleTsgaXRzIGZpcnN0IGNvbHVtbiBkaXNwbGF5cyB0aGUgbGluZWFyIG1vZGVs4oCZcyB5LWludGVyY2VwdCBhbmQgdGhlIGNvZWZmaWNpZW50IG9mIGhvbWVydW5zLiBXaXRoIHRoaXMgdGFibGUsIHdlIGNhbiB3cml0ZSBkb3duIHRoZSBsZWFzdCBzcXVhcmVzIHJlZ3Jlc3Npb24gbGluZSBmb3IgdGhlIGxpbmVhciBtb2RlbDoNCg0KeV49IDQxNS4yMzg5KzEuODM0NeKIl2hvbWVydW5zDQoNCg0KDQpgYGB7cn0NCiNwbG90IG9mIGhvbWVydW5zIHRvIHByZWRpY3QgcnVucw0KDQpwbG90X3NzKHggPSBtbGIxMSRob21lcnVucywgeSA9IG1sYjExJHJ1bnMsIHNob3dTcXVhcmVzID0gVFJVRSkNCmxtKGZvcm11bGEgPSBydW5zIH4gaG9tZXJ1bnMsIGRhdGEgPSBtbGIxMSkNCg0KDQpgYGANCg0KYGBge3J9DQoNCiMjbWFrZSBhIGxpbmVhciBtb2RlbCBvZiBydW5zIGFzIGEgZnVuY3Rpb24gb2YgaG9tZXJ1bnMNCiNSIHNob3VsZCBsb29rIGluIHRoZSBtbGIxMSBkYXRhIGZyYW1lIHRvIGZpbmQgdGhlIHJ1bnMgYW5kIGhvbWVydW5zIHZhcmlhYmxlcy4NCiNUaGUgb3V0cHV0IG9mIGxtIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFsbCBvZiB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCBhYm91dCB0aGUgbGluZWFyIG1vZGVsIHRoYXQgd2FzIGp1c3QgZml0LiBXZSBjYW4gYWNjZXNzIHRoaXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2luZm9ybWF0aW9uIHVzaW5nIHRoZSBzdW1tYXJ5IGZ1bmN0aW9uLg0KbTEgPC0gbG0ocnVucyB+IGhvbWVydW5zLCBkYXRhID0gbWxiMTEpDQpzdW1tYXJ5KG0xKQ0KYGBgDQpgYGB7cn0NCiNJZiB0aGUgcmVsYXRpb25zaGlwIGxvb2tzIGxpbmVhciwgd2UgY2FuIHF1YW50aWZ5IHRoZSBzdHJlbmd0aCBvZiB0aGUgcmVsYXRpb25zaGlwIHdpdGggdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50Lg0KY29yKG1sYjExJHJ1bnMsIG1sYjExJGhvbWVydW5zKQ0KYGBgDQoNClByZWRpY3Rpb24gYW5kIHByZWRpY3Rpb24gZXJyb3JzDQpMZXTigJlzIGNyZWF0ZSBhIHNjYXR0ZXJwbG90IHdpdGggdGhlIGxlYXN0IHNxdWFyZXMgbGluZSBsYWlkIG9uIHRvcC4NCg0KYGBge3J9DQojRXh0cmFwb2xhdGlvbg0KDQojVGhlIGZ1bmN0aW9uIGFibGluZSBwbG90cyBhIGxpbmUgYmFzZWQgb24gaXRzIHNsb3BlIGFuZCBpbnRlcmNlcHQuIEhlcmUsIHdlIHVzZWQgYSBzaG9ydGN1dCBieSBwcm92aWRpbmcgdGhlIG1vZGVsIG0xLCB3aGljaCBjb250YWlucyBib3RoIHBhcmFtZXRlciBlc3RpbWF0ZXMuIFRoaXMgbGluZSBjYW4gYmUgdXNlZCB0byAjcHJlZGljdCB5IGF0IGFueSB2YWx1ZSBvZiB4LiBXaGVuIHByZWRpY3Rpb25zIGFyZSBtYWRlIGZvciB2YWx1ZXMgb2YgeCB0aGF0IGFyZSBiZXlvbmQgdGhlIHJhbmdlIG9mIHRoZSBvYnNlcnZlZCBkYXRhLCBpdCBpcyByZWZlcnJlZCB0byBhcyBleHRyYXBvbGF0aW9uIGFuZCBpcyBub3QgdXN1YWxseSByZWNvbW1lbmRlZC4gI0hvd2V2ZXIsIHByZWRpY3Rpb25zIG1hZGUgd2l0aGluIHRoZSByYW5nZSBvZiB0aGUgZGF0YSBhcmUgbW9yZSByZWxpYWJsZS4gVGhleeKAmXJlIGFsc28gdXNlZCB0byBjb21wdXRlIHRoZSByZXNpZHVhbHMuDQoNCg0KcGxvdChtbGIxMSRydW5zIH4gbWxiMTEkYXRfYmF0cykNCmFibGluZShtMSkNCg0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgNQ0KDQpJZiBhIHRlYW0gbWFuYWdlciBzYXcgdGhlIGxlYXN0IHNxdWFyZXMgcmVncmVzc2lvbiBsaW5lIGFuZCBub3QgdGhlIGFjdHVhbCBkYXRhLCBob3cgbWFueSBydW5zIHdvdWxkIGhlIG9yIHNoZSBwcmVkaWN0IGZvciBhIHRlYW0gd2l0aCA1LDU3OCBhdC1iYXRzPyBJcyB0aGlzIGFuIG92ZXJlc3RpbWF0ZSBvciBhbiB1bmRlcmVzdGltYXRlLCBhbmQgYnkgaG93IG11Y2g/IEluIG90aGVyIHdvcmRzLCB3aGF0IGlzIHRoZSByZXNpZHVhbCBmb3IgdGhpcyBwcmVkaWN0aW9uPw0KDQoNCioqKkFuc3dlcioqKg0KV2Uga25vdyBmcm9tIEV4ZXJjaXNlIDMgYWJvdmUgdGhhdCB0aGUgbGVhc3Qgc3F1YXJlcyByZWdyZXNzaW9uIGxpbmUgZm9yIHRoZSBsaW5lYXIgbW9kZWwgaXM6ICB5Xj3iiJIyNzg5LjI0MjkrMC42MzA14oiXYXRiYXRzDQpJZiBhdF9iYXRzID0gNSw1Nzg7IHNvIHlePTcyNy42ODYxLiAgV2l0aG91dCB0aGUgYWN0dWFsIGRhdGEsIGEgdGVhbSBtYW5hZ2VyIHdvdWxkIHByZWRpY3QgcnVucyBvZiA3MjcuNjkgKDcyOCkgd2l0aCA1LDU3OCBhdF9iYXRzLg0KDQpJbiBsb29raW5nIGF0IHRoZSBkYXRhIHRhYmxlLCB0aGVyZSBpcyBhbiBhdF9iYXQgb2YgNSw1NzkgYW5kIGEgcnVuIG9mIDcxMzsgICAgNzI4IC0gNzEzID0gcmVzaWR1YWwgb3ZlcnN0YXRlbWVudCBvZiAxNSBmb3IgdGhpcyBlc3RpbWF0ZQ0KDQoNCg0KV2UgcmFuIHRoZSBmb2xsb3dpbmcgY29kZSB0byBnZXQgdGhlIGVxdWF0aW9uOg0KbTEgPC0gbG0ocnVucyB+IGF0X2JhdHMsIGRhdGEgPSBtbGIxMSkgICNsbSBpcyBhIGZvcm11bGEgdGhhdCB0YWtlcyB0aGUgZm9ybSB5IH4geC4gSGVyZSBpdCBjYW4gYmUgcmVhZCB0aGF0IHdlIHdhbnQgdG8gbWFrZSBhIGxpbmVhciBtb2RlbCBvZiBydW5zIGFzIGEgZnVuY3Rpb24gb2YgYXRfYmF0cw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGF0IFIgc2hvdWxkIGxvb2sgaW4gdGhlIG1sYjExIGRhdGEgZnJhbWUgdG8gZmluZCB0aGUgcnVucyBhbmQgYXRfYmF0cyB2YXJpYWJsZXMuDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBvdXRwdXQgb2YgbG0gaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIGFib3V0IHRoZSBsaW5lYXIgbW9kZWwgdGhhdCB3YXMganVzdCBmaXQuIFdlIGNhbiBhY2Nlc3MgdGhpcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjaW5mb3JtYXRpb24gdXNpbmcgdGhlIHN1bW1hcnkgZnVuY3Rpb24uDQpzdW1tYXJ5KG0xKQ0KDQpgYGB7cn0NCiNsb29rIGF0IHRoZSBkYXRhIGFuZCBwdWxsIGEgY2xvc2UgZGF0YSBwb2ludCANCnZpZXcobWxiMTEpICAgICNpbiB0aGUgdGFibGUsIHRoZXJlIGlzIGFuIGF0X2JhdCBvZiA1LDU3OSBhbmQgYSBydW4gb2YgNzEzDQoNCg0KYGBgDQoNCg0KTW9kZWwgZGlhZ25vc3RpY3MNClRvIGFzc2VzcyB3aGV0aGVyIHRoZSBsaW5lYXIgbW9kZWwgaXMgcmVsaWFibGUsIHdlIG5lZWQgdG8gY2hlY2sgZm9yICgxKSBsaW5lYXJpdHksICgyKSBuZWFybHkgbm9ybWFsIHJlc2lkdWFscywgYW5kICgzKSBjb25zdGFudCB2YXJpYWJpbGl0eS4NCg0KTGluZWFyaXR5OiBZb3UgYWxyZWFkeSBjaGVja2VkIGlmIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBydW5zIGFuZCBhdC1iYXRzIGlzIGxpbmVhciB1c2luZyBhIHNjYXR0ZXJwbG90LiBXZSBzaG91bGQgYWxzbyB2ZXJpZnkgdGhpcyBjb25kaXRpb24gd2l0aCBhIHBsb3Qgb2YgdGhlIHJlc2lkdWFscyB2cy4gYXQtYmF0cy4gUmVjYWxsIHRoYXQgYW55IGNvZGUgZm9sbG93aW5nIGEgIyBpcyBpbnRlbmRlZCB0byBiZSBhIGNvbW1lbnQgdGhhdCBoZWxwcyB1bmRlcnN0YW5kIHRoZSBjb2RlIGJ1dCBpcyBpZ25vcmVkIGJ5IFIuDQoNCmBgYHtyfQ0KDQojVG8gYXNzZXNzIHdoZXRoZXIgdGhlIGxpbmVhciBtb2RlbCBpcyByZWxpYWJsZSwgd2UgbmVlZCB0byBjaGVjayBmb3IgKDEpIGxpbmVhcml0eSwgKDIpIG5lYXJseSBub3JtYWwgcmVzaWR1YWxzLCBhbmQgKDMpIGNvbnN0YW50IHZhcmlhYmlsaXR5Lg0KI0lURU0gMTogIExpbmVhcml0eTogIERJRCBBTEwgT0YgVEhJUyBBQk9WRQ0KI0lURU0gMTogIExpbmVhcml0eTogIENoZWNrIGlmIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHJ1bnMgYW5kIGF0LWJhdHMgaXMgbGluZWFyIGJ5IHZlcmlmeWluZyBjb25kaXRpb24gd2l0aCBhIHBsb3Qgb2YgdGhlIHJlc2lkdWFscyB2cy4gYXQtYmF0cy4gIA0KDQpwbG90KG0xJHJlc2lkdWFscyB+IG1sYjExJGF0X2JhdHMpDQphYmxpbmUoaCA9IDAsIGx0eSA9IDMpICAjIGFkZHMgYSBob3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwDQpgYGANCmBgYHtyfQ0KDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDYNCg0KI1RvIGFzc2VzcyB3aGV0aGVyIHRoZSBsaW5lYXIgbW9kZWwgaXMgcmVsaWFibGUsIHdlIG5lZWQgdG8gY2hlY2sgZm9yICgxKSBsaW5lYXJpdHksICgyKSBuZWFybHkgbm9ybWFsIHJlc2lkdWFscywgYW5kICgzKSBjb25zdGFudCB2YXJpYWJpbGl0eS4NCiNJVEVNIDE6ICBMaW5lYXJpdHk6ICBESUQgQUxMIE9GIFRISVMgQUJPVkUNCiNJVEVNIDE6ICBMaW5lYXJpdHk6ICBDaGVjayBpZiByZWxhdGlvbnNoaXAgYmV0d2VlbiBydW5zIGFuZCBhdC1iYXRzIGlzIGxpbmVhciBieSB2ZXJpZnlpbmcgY29uZGl0aW9uIHdpdGggYSBwbG90IG9mIHRoZSByZXNpZHVhbHMgdnMuIGF0LWJhdHMuDQojSXRlbSAyOiAgTmVhcmx5IE5vcm1hbCBSZXNpZHVhbHM6ICBIaXN0b2dyYW0NCiNJdGVtIDI6ICBOZWFybHkgTm9ybWFsIFJlc2lkdWFsczogIG9yIGEgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3Qgb2YgdGhlIHJlc2lkdWFscy4NCg0KDQpJcyB0aGVyZSBhbnkgYXBwYXJlbnQgcGF0dGVybiBpbiB0aGUgcmVzaWR1YWxzIHBsb3Q/IFdoYXQgZG9lcyB0aGlzIGluZGljYXRlIGFib3V0IHRoZSBsaW5lYXJpdHkgb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHJ1bnMgYW5kIGF0LWJhdHM/DQoNCioqKkFuc3dlcioqKg0KVGhlcmUgaXMgbm8gYXBwYXJlbnQgcGF0dGVybiBpbiB0aGUgcmVzaWR1YWxzIHBsb3QuDQoNClRoaXMgaW5kaWNhdGVzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBydW5zIGFuZCBhdC1iYXRzIGlzIGxpbmVhci4NCg0KYGBge3J9DQojTmVhcmx5IG5vcm1hbCByZXNpZHVhbHM6IFRvIGNoZWNrIHRoaXMgY29uZGl0aW9uLCB3ZSBjYW4gbG9vayBhdCBhIGhpc3RvZ3JhbQ0KaGlzdChtMSRyZXNpZHVhbHMpDQoNCmBgYA0KYGBge3J9DQojb3IgYSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBvZiB0aGUgcmVzaWR1YWxzLg0KcXFub3JtKG0xJHJlc2lkdWFscykNCnFxbGluZShtMSRyZXNpZHVhbHMpICAjIGFkZHMgZGlhZ29uYWwgbGluZSB0byB0aGUgbm9ybWFsIHByb2IgcGxvdA0KDQoNCmBgYA0KYGBge3J9DQoNCmBgYA0KDQojIyMgRXhlcmNpc2UgNw0KQmFzZWQgb24gdGhlIGhpc3RvZ3JhbSBhbmQgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90LCBkb2VzIHRoZSBuZWFybHkgbm9ybWFsIHJlc2lkdWFscyBjb25kaXRpb24gYXBwZWFyIHRvIGJlIG1ldD8NCg0KKioqQW5zd2VyKioqDQoNClllcywgYmFzZWQgb24gdGhlIGhpc3RvZ3JhbSBhbmQgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QsIHRoZXJlIGFwcGVhcnMgdG8gYmUgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggdmVyeSBmZXcgZXh0cmVtZSB2YXJpYW5jZXMuDQpgYGB7cn0NCg0KYGBgDQoNCiMjIyBFeGVyY2lzZSA4DQpCYXNlZCBvbiB0aGUgcGxvdCBpbiAoMSksIGRvZXMgdGhlIGNvbnN0YW50IHZhcmlhYmlsaXR5IGNvbmRpdGlvbiBhcHBlYXIgdG8gYmUgbWV0Pw0KDQoqKipBbnN3ZXIqKioNCg0KVGhlIGNvbnN0YW50IHZhcmlhYmlsaXR5IGNvbmRpdGlvbiBpcyBtZXQgd2hlbiB0aGUgcG9pbnRzIGFyb3VuZCB0aGUgbGluZSBhcHBlYXIgdG8gYmUgZXZlbmx5IHZhcmllZC9kaXN0YW5jZWQuICBZZXMsIHRoZSBjb25zdGFudCB2YXJpYWJpbGl0eSBjb25kaXRpb24gYXBwZWFycyB0byBiZSBtZXQgYmFzZWQgb24gdGhlIHBsb3QgaW4gKDEpLg0KDQoNCg0KYGBge3J9DQoNCmBgYA0KDQojIyMgT04gWU9VUiBPV04gMQ0KQ2hvb3NlIGFub3RoZXIgdHJhZGl0aW9uYWwgdmFyaWFibGUgZnJvbSBtbGIxMSB0aGF0IHlvdSB0aGluayBtaWdodCBiZSBhIGdvb2QgcHJlZGljdG9yIG9mIHJ1bnMuIFByb2R1Y2UgYSBzY2F0dGVycGxvdCBvZiB0aGUgdHdvIHZhcmlhYmxlcyBhbmQgZml0IGEgbGluZWFyIG1vZGVsLiBBdCBhIGdsYW5jZSwgZG9lcyB0aGVyZSBzZWVtIHRvIGJlIGEgbGluZWFyIHJlbGF0aW9uc2hpcD8NCg0KDQoqKipBbnN3ZXIqKioNClNjYXR0ZXJwbG90IHdpdGggYSBsaW5lYXIgbW9kZWw6ICBUcmFkaXRpb25hbCB2YXJpYWJsZSBzZWxlY3RlZCA9IGJhdF9hdmcNCkRvZXMgdGhlcmUgc2VlbSB0byBiZSBhIGxpbmVhciByZWxhdGlvbnNoaXA6ICBZZXMsIHRoZXJlIHNlZW1zIHRvIGJlIGEgbGluZWFyIHJlbGF0aW9uc2hpcC4gIFRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBvZiAuODA5OSBpbmRpY2F0ZXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gYmF0dGluZyBhdmVyYWdlIGFuZCBydW5zLiAgVGhlIHNsb3BlIGlzIHBvc2l0aXZlIGJldHdlZW4gdGhlIHR3byB2YXJpYWJsZXMuIA0KDQoNCmBgYHtyfQ0KI3NjYXR0ZXJwbG90IA0KDQpwbG90KG1sYjExJHJ1bnMgfiBtbGIxMSRiYXRfYXZnLA0KICAgICBtYWluID0gIlJlbGF0aW9uc2hpcCBCZXR3ZWVuIFJ1bnMgYW5kIEJhdF9BdmciLA0KICAgICB5bGFiID0gIlJ1bnMiLCANCiAgICAgeGxhYiA9ICJCYXRfQXZnIiwpDQoNCg0KI2ZpdCBhIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbA0KbW9kZWwgPC0gbG0obWxiMTEkcnVuIH4gbWxiMTEkYmF0X2F2ZywgZGF0YSA9IG1sYjExKQ0KDQojYWRkIHRoZSBmaXR0ZWQgcmVncmVzc2lvbiBsaW5lIHRvIHRoZSBzY2F0dGVycGxvdA0KYWJsaW5lKG1vZGVsKQ0KDQpgYGANCg0KYGBge3J9DQojSWYgdGhlIHJlbGF0aW9uc2hpcCBsb29rcyBsaW5lYXIsIHdlIGNhbiBxdWFudGlmeSB0aGUgc3RyZW5ndGggb2YgdGhlIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudC4NCmNvcihtbGIxMSRydW5zLCBtbGIxMSRiYXRfYXZnKQ0KYGBgDQpgYGB7cn0NCg0KYGBgDQoNCiMjIyBPTiBZT1VSIE9XTiAyDQoNCkhvdyBkb2VzIHRoaXMgcmVsYXRpb25zaGlwIGNvbXBhcmUgdG8gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHJ1bnMgYW5kIGF0X2JhdHM/IFVzZSB0aGUgUjIgdmFsdWVzIGZyb20gdGhlIHR3byBtb2RlbCBzdW1tYXJpZXMgdG8gY29tcGFyZS4gRG9lcyB5b3VyIHZhcmlhYmxlIHNlZW0gdG8gcHJlZGljdCBydW5zIGJldHRlciB0aGFuIGF0X2JhdHM/IEhvdyBjYW4geW91IHRlbGw/DQoNCg0KKioqQW5zd2VyKioqDQoNClIyIC0gYXRfYmF0czogIDAuMzcyOQ0KUjIgLSBiYXRfYXZnOiAgMC42NTYxDQoNCg0KDQpCYXNlZCBvbiB0aGUgdmFsdWVzIG9mIFIyLCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gcnVucyBhbmQgYmF0X2F2ZyBzZWVtcyBpcyBzdHJvbmdlciB0aGFuIHRoYXQgb2YgcnVucyBhbmQgYXRfYmF0cy4gVGhlIFIyIHZhbHVlIGZvciB0aGUgbGluZWFyIG1vZGVsIHVzaW5nIGF0X2JhdHMgaXMgMC4zNzI5IHdoaWxlIGZvciB0aGUgbGluZWFyIG1vZGVsIHVzaW5nIGJhdF9hdmcgaXMgMC42NTYxLiAgVGhlIGxpbmVhciBtb2RlbCB1c2luZyBiYXRfYXZnIGlzIGEgYmV0dGVyIHByZWRpY3RvciBvZiBydW5zLiBUaGUgc3VtIG9mIHJlc2lkdWFscyBmb3IgdGhlIGxpbmVhciBtb2RlbCB1c2luZyB0aGUgdmFyaWFibGUgYXRfYmF0cyBhcyBhIHByZWRpY3RvciBvZiBydW5zIGlzIDEyMzcyMS45IChzZWUgUiBDb25zb2xlIG91dHB1dCBvZiBwbG90X3NzKSBhbmQgZm9yIHRoZSBsaW5lYXIgbW9kZWwgdXNpbmcgdGhlIHZhcmlhYmxlIGJhdF9hdmcgYXMgYSBwcmVkaWN0b3Igb2YgcnVucyBpcyA2Nzg0OS41MiAoc2VlIFIgQ29uc29sZSBvdXRwdXQgb2YgcGxvdF9zcykuIFRoZSBtb2RlbCBzdW1tYXJ5IHVzaW5nIGJhdF9hdmcgaXMgdGhlIGJlc3QgcHJlZGljdG9yIG9mIHJ1bnMgYXMgY29tcGFyZWQgdG8gdGhhdCBvZiB0aGUgbW9kZWwgdXNpbmcgdGhlIGF0X2JhdHMgdmFyaWFibGUuDQoNCg0KDQoNCmBgYHtyfQ0KI1J1bnMgYW5kIEFUX0JBVFMNCnBsb3Rfc3MoeCA9IG1sYjExJGF0X2JhdHMsIHkgPSBtbGIxMSRydW5zKQ0KYGBgDQpUaGUgbGluZWFyIG1vZGVsDQp1c2UgdGhlIGxtIGZ1bmN0aW9uIGluIFIgdG8gZml0IHRoZSBsaW5lYXIgbW9kZWwgKGEuay5hLiByZWdyZXNzaW9uIGxpbmUpLg0KDQpgYGB7cn0NCm0xIDwtIGxtKHJ1bnMgfiBhdF9iYXRzLCBkYXRhID0gbWxiMTEpICAjbG0gaXMgYSBmb3JtdWxhIHRoYXQgdGFrZXMgdGhlIGZvcm0geSB+IHguIEhlcmUgaXQgY2FuIGJlIHJlYWQgdGhhdCB3ZSB3YW50IHRvIG1ha2UgYSBsaW5lYXIgbW9kZWwgb2YgcnVucyBhcyBhIGZ1bmN0aW9uIG9mIGF0X2JhdHMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjVGhlIHNlY29uZCBhcmd1bWVudCBzcGVjaWZpZXMgdGhhdCBSIHNob3VsZCBsb29rIGluIHRoZSBtbGIxMSBkYXRhIGZyYW1lIHRvIGZpbmQgdGhlIHJ1bnMgYW5kIGF0X2JhdHMgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgb3V0cHV0IG9mIGxtIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFsbCBvZiB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCBhYm91dCB0aGUgbGluZWFyIG1vZGVsIHRoYXQgd2FzIGp1c3QgZml0LiBXZSBjYW4gYWNjZXNzIHRoaXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2luZm9ybWF0aW9uIHVzaW5nIHRoZSBzdW1tYXJ5IGZ1bmN0aW9uLg0Kc3VtbWFyeShtMSkNCmBgYA0KYGBge3J9DQoNCiNCQVRfQVZCDQpwbG90X3NzKHggPSBtbGIxMSRiYXRfYXZnLCB5ID0gbWxiMTEkcnVucykNCg0KDQoNCmBgYA0KDQpgYGB7cn0NCm0xIDwtIGxtKHJ1bnMgfiBiYXRfYXZnLCBkYXRhID0gbWxiMTEpICAjbG0gaXMgYSBmb3JtdWxhIHRoYXQgdGFrZXMgdGhlIGZvcm0geSB+IHguIEhlcmUgaXQgY2FuIGJlIHJlYWQgdGhhdCB3ZSB3YW50IHRvIG1ha2UgYSBsaW5lYXIgbW9kZWwgb2YgcnVucyBhcyBhIGZ1bmN0aW9uIG9mIGF0X2JhdHMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjVGhlIHNlY29uZCBhcmd1bWVudCBzcGVjaWZpZXMgdGhhdCBSIHNob3VsZCBsb29rIGluIHRoZSBtbGIxMSBkYXRhIGZyYW1lIHRvIGZpbmQgdGhlIHJ1bnMgYW5kIGF0X2JhdHMgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgb3V0cHV0IG9mIGxtIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFsbCBvZiB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCBhYm91dCB0aGUgbGluZWFyIG1vZGVsIHRoYXQgd2FzIGp1c3QgZml0LiBXZSBjYW4gYWNjZXNzIHRoaXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2luZm9ybWF0aW9uIHVzaW5nIHRoZSBzdW1tYXJ5IGZ1bmN0aW9uLg0Kc3VtbWFyeShtMSkNCmBgYA0KYGBge3J9DQoNCmBgYA0KDQojIyMgT04gWU9VUiBPV04gMw0KDQoNCk5vdyB0aGF0IHlvdSBjYW4gc3VtbWFyaXplIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdHdvIHZhcmlhYmxlcywgaW52ZXN0aWdhdGUgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBydW5zIGFuZCBlYWNoIG9mIHRoZSBvdGhlciBmaXZlIHRyYWRpdGlvbmFsIHZhcmlhYmxlcy4gV2hpY2ggdmFyaWFibGUgYmVzdCBwcmVkaWN0cyBydW5zPyBTdXBwb3J0IHlvdXIgY29uY2x1c2lvbiB1c2luZyB0aGUgZ3JhcGhpY2FsIGFuZCBudW1lcmljYWwgbWV0aG9kcyB3ZeKAmXZlIGRpc2N1c3NlZCAoZm9yIHRoZSBzYWtlIG9mIGNvbmNpc2VuZXNzLCBvbmx5IGluY2x1ZGUgb3V0cHV0IGZvciB0aGUgYmVzdCB2YXJpYWJsZSwgbm90IGFsbCBmaXZlKS4NCg0KDQoNCioqKkFuc3dlcioqKg0KMS4gIFIyIC0gaGl0czogIDAuNjQxOQ0KMS4gIFN1bSBvZiBSZXNpZHVhbHMgLSBoaXRzOiAgNzA2MzguNzUNCg0KMi4gIFIyIC0gaG9tZXJ1bnM6ICAwLjYyNjYNCjIuICBTdW0gb2YgUmVzaWR1YWxzIC0gaG9tZXJ1bnM6ICA3MzY3MS45OQ0KDQozLiAgUjIgLSBzdHJpa2VvdXRzOiAgMC4xNjk0DQozLiAgU3VtIG9mIFJlc2lkdWFscyAtIHN0cmlrZW91dHM6ICAxNjM4NzAuMQ0KDQo0LiAgUjIgLSBzdG9sZW5fYmFzZXM6ICAwLjAwMjkxNA0KNC4gIFN1bSBvZiBSZXNpZHVhbHMgLSBTdG9sZW4gQmFzZXM6ICAxOTY3MDYuMw0KDQo1LiAgUjIgLSB3aW5zOiAgIDAuMzYxDQo1LiAgU3VtIG9mIFJlc2lkdWFscyAtIFdpbnM6ICAxMjYwNjguNA0KDQoNCkJhc2VkIG9uIHRoZSB2YWx1ZXMgb2YgUjIsIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBydW5zIGFuZCBoaXRzIGFuZCBydW5zIGFuZCBob21lcnVucyBpcyB2ZXJ5IGNsb3NlIGF0IC42NCBmb3IgaGl0cyBhbmQgLjYzIGZvciBob21lcnVucy4gIEhpdHMgYXBwZWFycyB0byBiZSB0aGUgYmVzdCBwcmVkaWN0b3IgYXMgZmFyIGFzIFIyIHZhbHVlIGlzIGNvbmNlcm5lZCwgYnV0IGl0IGlzIHZlcnkgY2xvc2UgdG8gaG9tZXJ1bnMuICBVc2luZyB0aGUgc3VtIG9mIHJlc2lkdWFscyBiZXR3ZWVuIGhpdHMgYW5kIGhvbWVydW5zLCBob21lcnVucyBpcyBhIGJldHRlciBwcmVkaWN0b3IgYXQgNzMsNjcyIHZzIDcwLDYzOS4gIFVzaW5nIHN1bSBvZiByZXNpZHVhbHMsIGhvd2V2ZXIsIHN0b2xlbl9iYXNlcyBhcHBlYXJzIHRvIGJlIHRoZSBzdHJvbmdlc3QgcHJlZGljdG9yIG9mIHJ1bnMgYXQgMTk2LDcwMyBhcyBjb21wYXJlZCB0byB0aGUgb3RoZXIgbW9kZWxzLg0KDQpPdmVyYWxsLCBpbiBsb29raW5nIGF0IHRoZSB0cmFkaXRpb25hbCB2YXJpYWJsZXMsIGJhdF9iYXQgYXZnLiBhcHBlYXJzIHRvIGJlIHRoZSBiZXN0IHByZWRpY3RvciBmb2xsb3dlZCBieSBoaXRzLg0KDQoNCmBgYHtyfQ0KIyBhbGwgcGxvdHMgdG9nZXRoZXINCnRyYWQxPWxtKHJ1bnN+aGl0cyxkYXRhPW1sYjExKQ0KdHJhZDI9bG0ocnVuc35ob21lcnVucyxkYXRhPW1sYjExKQ0KdHJhZDM9bG0ocnVuc35zdHJpa2VvdXRzLGRhdGE9bWxiMTEpDQp0cmFkND1sbShydW5zfnN0b2xlbl9iYXNlcywgZGF0YT1tbGIxMSkNCnRyYWQ1PWxtKHJ1bnN+d2lucyxkYXRhPW1sYjExKQ0KcGFyKG1mcm93PWMoMiwzKSkNCnBsb3QobWxiMTEkaGl0cyxtbGIxMSRydW5zLHhsYWI9IkhpdHMiLHlsYWI9IlJ1bnMiLG1haW49IkhpdHMgVnMgUnVucyIpIA0KYWJsaW5lKHRyYWQxKQ0KcGxvdChtbGIxMSRob21lcnVucyxtbGIxMSRydW5zLHhsYWI9IkhvbWVydW5zIix5bGFiPSJSdW5zIixtYWluPSJIb21lcnVucyBWcyBSdW5zIikgDQphYmxpbmUodHJhZDIpDQpwbG90KG1sYjExJHN0cmlrZW91dHMsbWxiMTEkcnVucyx4bGFiPSJTdHJpa2VvdXRzIix5bGFiPSJSdW5zIixtYWluPSJTdHJpa2VvdXRzIFZzIFJ1bnMiKSANCmFibGluZSh0cmFkMykNCnBsb3QobWxiMTEkc3RvbGVuX2Jhc2VzLG1sYjExJHJ1bnMseGxhYj0iU3RvbGVuIEJhc2VzIix5bGFiPSJSdW5zIixtYWluPSJTdG9sZW4gQmFzZXMgVnMgUnVucyIpIA0KYWJsaW5lKHRyYWQ0KQ0KcGxvdChtbGIxMSR3aW5zLG1sYjExJHJ1bnMseGxhYj0iV2lucyIseWxhYj0iUnVucyIsbWFpbj0iV2lucyBWcyBSdW5zIikgDQphYmxpbmUodHJhZDUpDQpgYGANCg0KDQoNCg0KDQpgYGB7cn0NCiMxLiAgUnVucyBhbmQgSElUUw0KcGxvdF9zcyh4ID0gbWxiMTEkaGl0cywgeSA9IG1sYjExJHJ1bnMpDQpgYGANCg0KYGBge3J9DQojIzEuICBSdW5zIGFuZCBISVRTDQptMSA8LSBsbShydW5zIH4gaGl0cywgZGF0YSA9IG1sYjExKSAgI2xtIGlzIGEgZm9ybXVsYSB0aGF0IHRha2VzIHRoZSBmb3JtIHkgfiB4LiBIZXJlIGl0IGNhbiBiZSByZWFkIHRoYXQgd2Ugd2FudCB0byBtYWtlIGEgbGluZWFyIG1vZGVsIG9mIHJ1bnMgYXMgYSBmdW5jdGlvbiBvZiBoaXRzDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBzZWNvbmQgYXJndW1lbnQgc3BlY2lmaWVzIHRoYXQgUiBzaG91bGQgbG9vayBpbiB0aGUgbWxiMTEgZGF0YSBmcmFtZSB0byBmaW5kIHRoZSBydW5zIGFuZCBoaXRzIHZhcmlhYmxlcy4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjVGhlIG91dHB1dCBvZiBsbSBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgb2YgdGhlIGluZm9ybWF0aW9uIHdlIG5lZWQgYWJvdXQgdGhlIGxpbmVhciBtb2RlbCB0aGF0IHdhcyBqdXN0IGZpdC4gV2UgY2FuIGFjY2VzcyB0aGlzIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNpbmZvcm1hdGlvbiB1c2luZyB0aGUgc3VtbWFyeSBmdW5jdGlvbi4NCnN1bW1hcnkobTEpDQpgYGANCmBgYHtyfQ0KIzIuICBSdW5zIGFuZCBIT01FUlVOUw0KcGxvdF9zcyh4ID0gbWxiMTEkaG9tZXJ1bnMsIHkgPSBtbGIxMSRydW5zKQ0KYGBgDQoNCmBgYHtyfQ0KIyMyLiAgUnVucyBhbmQgSE9NRVJVTlMNCm0xIDwtIGxtKHJ1bnMgfiBob21lcnVucywgZGF0YSA9IG1sYjExKSAgI2xtIGlzIGEgZm9ybXVsYSB0aGF0IHRha2VzIHRoZSBmb3JtIHkgfiB4LiBIZXJlIGl0IGNhbiBiZSByZWFkIHRoYXQgd2Ugd2FudCB0byBtYWtlIGEgbGluZWFyIG1vZGVsIG9mIHJ1bnMgYXMgYSBmdW5jdGlvbiBvZiBob21lcnVucw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGF0IFIgc2hvdWxkIGxvb2sgaW4gdGhlIG1sYjExIGRhdGEgZnJhbWUgdG8gZmluZCB0aGUgcnVucyBhbmQgaG9tZXJ1bnMgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgb3V0cHV0IG9mIGxtIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFsbCBvZiB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCBhYm91dCB0aGUgbGluZWFyIG1vZGVsIHRoYXQgd2FzIGp1c3QgZml0LiBXZSBjYW4gYWNjZXNzIHRoaXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2luZm9ybWF0aW9uIHVzaW5nIHRoZSBzdW1tYXJ5IGZ1bmN0aW9uLg0Kc3VtbWFyeShtMSkNCmBgYA0KDQpgYGB7cn0NCiMzLiAgUnVucyBhbmQgU1RSSUtFT1VUUw0KcGxvdF9zcyh4ID0gbWxiMTEkc3RyaWtlb3V0cywgeSA9IG1sYjExJHJ1bnMpDQpgYGANCg0KYGBge3J9DQojIzMuICBSdW5zIGFuZCBTVFJJS0VPVVRTDQptMSA8LSBsbShydW5zIH4gc3RyaWtlb3V0cywgZGF0YSA9IG1sYjExKSAgI2xtIGlzIGEgZm9ybXVsYSB0aGF0IHRha2VzIHRoZSBmb3JtIHkgfiB4LiBIZXJlIGl0IGNhbiBiZSByZWFkIHRoYXQgd2Ugd2FudCB0byBtYWtlIGEgbGluZWFyIG1vZGVsIG9mIHJ1bnMgYXMgYSBmdW5jdGlvbiBvZiBzdHJpa2VvdXRzDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBzZWNvbmQgYXJndW1lbnQgc3BlY2lmaWVzIHRoYXQgUiBzaG91bGQgbG9vayBpbiB0aGUgbWxiMTEgZGF0YSBmcmFtZSB0byBmaW5kIHRoZSBydW5zIGFuZCBzdHJpa2VvdXRzIHZhcmlhYmxlcy4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjVGhlIG91dHB1dCBvZiBsbSBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgb2YgdGhlIGluZm9ybWF0aW9uIHdlIG5lZWQgYWJvdXQgdGhlIGxpbmVhciBtb2RlbCB0aGF0IHdhcyBqdXN0IGZpdC4gV2UgY2FuIGFjY2VzcyB0aGlzIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNpbmZvcm1hdGlvbiB1c2luZyB0aGUgc3VtbWFyeSBmdW5jdGlvbi4NCnN1bW1hcnkobTEpDQpgYGANCg0KYGBge3J9DQojNC4gIFJ1bnMgYW5kIFNUT0xFTiBCQVNFUw0KcGxvdF9zcyh4ID0gbWxiMTEkc3RvbGVuX2Jhc2VzLCB5ID0gbWxiMTEkcnVucykNCmBgYA0KDQoNCmBgYHtyfQ0KIyM0LiAgUnVucyBhbmQgU1RPTEVOIEJBU0VTDQptMSA8LSBsbShydW5zIH4gc3RvbGVuX2Jhc2VzLCBkYXRhID0gbWxiMTEpICAjbG0gaXMgYSBmb3JtdWxhIHRoYXQgdGFrZXMgdGhlIGZvcm0geSB+IHguIEhlcmUgaXQgY2FuIGJlIHJlYWQgdGhhdCB3ZSB3YW50IHRvIG1ha2UgYSBsaW5lYXIgbW9kZWwgb2YgcnVucyBhcyBhIGZ1bmN0aW9uIG9mIHN0b2xlbiBiYXNlcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGF0IFIgc2hvdWxkIGxvb2sgaW4gdGhlIG1sYjExIGRhdGEgZnJhbWUgdG8gZmluZCB0aGUgcnVucyBhbmQgc3RvbGVuIGJhc2VzIHZhcmlhYmxlcy4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjVGhlIG91dHB1dCBvZiBsbSBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgb2YgdGhlIGluZm9ybWF0aW9uIHdlIG5lZWQgYWJvdXQgdGhlIGxpbmVhciBtb2RlbCB0aGF0IHdhcyBqdXN0IGZpdC4gV2UgY2FuIGFjY2VzcyB0aGlzIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNpbmZvcm1hdGlvbiB1c2luZyB0aGUgc3VtbWFyeSBmdW5jdGlvbi4NCnN1bW1hcnkobTEpDQpgYGANCg0KDQpgYGB7cn0NCiM1LiAgUnVucyBhbmQgV2lucw0KcGxvdF9zcyh4ID0gbWxiMTEkd2lucywgeSA9IG1sYjExJHJ1bnMpDQpgYGANCg0KYGBge3J9DQojIzUuICBSdW5zIGFuZCBTVE9MRU4gQkFTRVMNCm0xIDwtIGxtKHJ1bnMgfiB3aW5zLCBkYXRhID0gbWxiMTEpICAjbG0gaXMgYSBmb3JtdWxhIHRoYXQgdGFrZXMgdGhlIGZvcm0geSB+IHguIEhlcmUgaXQgY2FuIGJlIHJlYWQgdGhhdCB3ZSB3YW50IHRvIG1ha2UgYSBsaW5lYXIgbW9kZWwgb2YgcnVucyBhcyBhIGZ1bmN0aW9uIG9mIHdpbnMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjVGhlIHNlY29uZCBhcmd1bWVudCBzcGVjaWZpZXMgdGhhdCBSIHNob3VsZCBsb29rIGluIHRoZSBtbGIxMSBkYXRhIGZyYW1lIHRvIGZpbmQgdGhlIHJ1bnMgYW5kIHdpbnMgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgb3V0cHV0IG9mIGxtIGlzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGFsbCBvZiB0aGUgaW5mb3JtYXRpb24gd2UgbmVlZCBhYm91dCB0aGUgbGluZWFyIG1vZGVsIHRoYXQgd2FzIGp1c3QgZml0LiBXZSBjYW4gYWNjZXNzIHRoaXMgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2luZm9ybWF0aW9uIHVzaW5nIHRoZSBzdW1tYXJ5IGZ1bmN0aW9uLg0Kc3VtbWFyeShtMSkNCmBgYA0KYGBge3J9DQoNCmBgYA0KDQoNCiMjIyBPTiBZT1VSIE9XTiA0DQoNCk5vdyBleGFtaW5lIHRoZSB0aHJlZSBuZXdlciB2YXJpYWJsZXMuIFRoZXNlIGFyZSB0aGUgc3RhdGlzdGljcyB1c2VkIGJ5IHRoZSBhdXRob3Igb2YgTW9uZXliYWxsIHRvIHByZWRpY3QgYSB0ZWFtcyBzdWNjZXNzLiBJbiBnZW5lcmFsLCBhcmUgdGhleSBtb3JlIG9yIGxlc3MgZWZmZWN0aXZlIGF0IHByZWRpY3RpbmcgcnVucyB0aGF0IHRoZSBvbGQgdmFyaWFibGVzPyBFeHBsYWluIHVzaW5nIGFwcHJvcHJpYXRlIGdyYXBoaWNhbCBhbmQgbnVtZXJpY2FsIGV2aWRlbmNlLiBPZiBhbGwgdGVuIHZhcmlhYmxlcyB3ZeKAmXZlIGFuYWx5emVkLCB3aGljaCBzZWVtcyB0byBiZSB0aGUgYmVzdCBwcmVkaWN0b3Igb2YgcnVucz8gVXNpbmcgdGhlIGxpbWl0ZWQgKG9yIG5vdCBzbyBsaW1pdGVkKSBpbmZvcm1hdGlvbiB5b3Uga25vdyBhYm91dCB0aGVzZSBiYXNlYmFsbCBzdGF0aXN0aWNzLCBkb2VzIHlvdXIgcmVzdWx0IG1ha2Ugc2Vuc2U/DQoNCg0KKioqQW5zd2VyKioqDQoNCg0KKioqQW5zd2VyKioqDQpUaGUgbmV3IHZhcmlhYmxlcywgT25iYXNlLCBzbHVnLCBhbmQgb2JzLCBoYXZlIGhpZ2hlciBSMiB2YWx1ZXMgdGhhbiB0aGUgdHJhZGl0aW9uYWwgdmFyaWFibGVzLiAgVGhlIFN1bSBvZiBTcXVhcmVzIGZvciB0aGUgcmVzaWR1YWxzIGlzIGxlc3MgZm9yIHRoZSBuZXcgdmFyaWFibGVzIHRoYW4gZm9yIHRoZSB0cmFkaXRpb25hbCB2YXJpYWJsZXMuICBXaXRoIHRoZSBSMiB2YWx1ZXMgYmVpbmcgaGlnaGVyIGFuZCBzdW0gb2Ygc3F1YXJlcyBvZiByZXNpZHVhbCBiZWluZyBsZXNzIGZvciB0aGUgbmV3IHZhcmlhYmxlcywgdGhlIG5ldyB2YXJpYWJsZXMgYXJlIG1vcmUgZWZmZWN0aXZlIHByZWRpY3RvcnMgb2YgcnVucyB0aGFuIHRoZSB0cmFkaXRpb25hbCB2YXJpYWJsZXMuICBPZiBhbGwgdGVuIHZhcmlhYmxlcyB3ZSd2ZSBhbmFseXplZCwgdGhlIG5ldyB2YXJpYWJsZXMgc2VlbSB0byBiZSB0aGUgYmVzdCBwcmVkaWN0b3Igb2YgcnVucywgd2l0aCBuZXdfb2JzIGJlaW5nIHRoZSBiZXN0IG9mIHRoZSB0aHJlZS4gIA0KDQpORVcgVkFSSUFCTEVTDQoxLiAgUjIgLSBuZXdfb25iYXNlOiAgMC44NDkxDQoxLiAgU3VtIG9mIFJlc2lkdWFscyAtIG5ld19vbmJhc2U6ICAgMjk3NjguNw0KDQoyLiAgUjIgLSBuZXdfc2x1ZzogICAwLjg5NjkNCjIuICBTdW0gb2YgUmVzaWR1YWxzIC0gbmV3X3NsdWc6ICAyMDM0NS41NA0KDQozLiAgUjIgLSBuZXdfb2JzOiAgMC45MzQ5DQozLiAgU3VtIG9mIFJlc2lkdWFscyAtIG5ld19vYnM6ICAxMjgzNy42Ng0KDQoNCg0KVFJBRElUSU9OQUwgVkFSSUFCSUxFUyAoU0VFIE9OIFlPVVIgT1dOIDMgRk9SIFdPUkspDQogUjIgLSBoaXRzOiAgMC42NDE5DQoxLiAgU3VtIG9mIFJlc2lkdWFscyAtIGhpdHM6ICA3MDYzOC43NQ0KDQoyLiAgUjIgLSBob21lcnVuczogIDAuNjI2Ng0KMi4gIFN1bSBvZiBSZXNpZHVhbHMgLSBob21lcnVuczogIDczNjcxLjk5DQoNCjMuICBSMiAtIHN0cmlrZW91dHM6ICAwLjE2OTQNCjMuICBTdW0gb2YgUmVzaWR1YWxzIC0gc3RyaWtlb3V0czogIDE2Mzg3MC4xDQoNCjQuICBSMiAtIHN0b2xlbl9iYXNlczogIDAuMDAyOTE0DQo0LiAgU3VtIG9mIFJlc2lkdWFscyAtIFN0b2xlbiBCYXNlczogIDE5NjcwNi4zDQoNCjUuICBSMiAtIHdpbnM6ICAgMC4zNjENCjUuICBTdW0gb2YgUmVzaWR1YWxzIC0gV2luczogIDEyNjA2OC40DQoNCg0KDQoNCmBgYHtyfQ0KIyBhbGwgcGxvdHMgdG9nZXRoZXINCm5ldzE9bG0ocnVuc35uZXdfb25iYXNlLGRhdGE9bWxiMTEpDQpuZXcyPWxtKHJ1bnN+bmV3X3NsdWcsZGF0YT1tbGIxMSkNCm5ldzM9bG0ocnVuc35uZXdfb2JzLGRhdGE9bWxiMTEpDQpwYXIobWZyb3c9YygxLDMpKQ0KcGxvdChtbGIxMSRuZXdfb25iYXNlLG1sYjExJHJ1bnMseGxhYj0iTmV3IE9uIEJhc2UiLHlsYWI9IlJ1bnMiLG1haW49Ik5ldyBPbiBCYXNlIFZzIFJ1bnMiKSANCmFibGluZShuZXcxKQ0KcGxvdChtbGIxMSRuZXdfc2x1ZyxtbGIxMSRydW5zLHhsYWI9Ik5ldyBTbHVnIix5bGFiPSJSdW5zIixtYWluPSJOZXcgU2x1ZyBWcyBSdW5zIikgDQphYmxpbmUobmV3MikNCnBsb3QobWxiMTEkbmV3X29icyxtbGIxMSRydW5zLHhsYWI9Ik5ldyBPYnMiLHlsYWI9IlJ1bnMiLG1haW49Ik5ldyBPYnMgVnMgUnVucyIpIA0KYWJsaW5lKG5ldzMpDQpgYGANCg0KDQpgYGB7cn0NCnN1bW1hcnkobmV3MSkNCnN1bW1hcnkobmV3MikNCnN1bW1hcnkobmV3MykNCg0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCmBgYHtyfQ0KDQojMS4gIFJ1bnMgYW5kIG5ld19vbmJhc2UNCnBsb3Rfc3MoeCA9IG1sYjExJG5ld19vbmJhc2UsIHkgPSBtbGIxMSRydW5zKQ0KDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyMxLiAgUnVucyBhbmQgbmV3X29uYmFzZQ0KbTEgPC0gbG0ocnVucyB+IG5ld19vbmJhc2UsIGRhdGEgPSBtbGIxMSkgICNsbSBpcyBhIGZvcm11bGEgdGhhdCB0YWtlcyB0aGUgZm9ybSB5IH4geC4gSGVyZSBpdCBjYW4gYmUgcmVhZCB0aGF0IHdlIHdhbnQgdG8gbWFrZSBhIGxpbmVhciBtb2RlbCBvZiBydW5zIGFzIGEgZnVuY3Rpb24gb2YgbmV3X29uYmFzZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGF0IFIgc2hvdWxkIGxvb2sgaW4gdGhlIG1sYjExIGRhdGEgZnJhbWUgdG8gZmluZCB0aGUgcnVucyBhbmQgbmV3X29uYmFzZSB2YXJpYWJsZXMuDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBvdXRwdXQgb2YgbG0gaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIGFib3V0IHRoZSBsaW5lYXIgbW9kZWwgdGhhdCB3YXMganVzdCBmaXQuIFdlIGNhbiBhY2Nlc3MgdGhpcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjaW5mb3JtYXRpb24gdXNpbmcgdGhlIHN1bW1hcnkgZnVuY3Rpb24uDQpzdW1tYXJ5KG0xKQ0KYGBgDQoNCg0KYGBge3J9DQoNCiMxLiAgUnVucyBhbmQgbmV3X3NsdWcNCnBsb3Rfc3MoeCA9IG1sYjExJG5ld19zbHVnLCB5ID0gbWxiMTEkcnVucykNCmBgYA0KDQoNCmBgYHtyfQ0KIyMxLiAgUnVucyBhbmQgbmV3X3NsdWcNCm0xIDwtIGxtKHJ1bnMgfiBuZXdfb25iYXNlLCBkYXRhID0gbWxiMTEpICAjbG0gaXMgYSBmb3JtdWxhIHRoYXQgdGFrZXMgdGhlIGZvcm0geSB+IHguIEhlcmUgaXQgY2FuIGJlIHJlYWQgdGhhdCB3ZSB3YW50IHRvIG1ha2UgYSBsaW5lYXIgbW9kZWwgb2YgcnVucyBhcyBhIGZ1bmN0aW9uIG9mIG5ld19zbHVnDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBzZWNvbmQgYXJndW1lbnQgc3BlY2lmaWVzIHRoYXQgUiBzaG91bGQgbG9vayBpbiB0aGUgbWxiMTEgZGF0YSBmcmFtZSB0byBmaW5kIHRoZSBydW5zIGFuZCBuZXdfc2x1ZyB2YXJpYWJsZXMuDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBvdXRwdXQgb2YgbG0gaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIGFib3V0IHRoZSBsaW5lYXIgbW9kZWwgdGhhdCB3YXMganVzdCBmaXQuIFdlIGNhbiBhY2Nlc3MgdGhpcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjaW5mb3JtYXRpb24gdXNpbmcgdGhlIHN1bW1hcnkgZnVuY3Rpb24uDQpzdW1tYXJ5KG0xKQ0KYGBgDQpgYGB7cn0NCiMxLiAgUnVucyBhbmQgbmV3X29icw0KcGxvdF9zcyh4ID0gbWxiMTEkbmV3X29icywgeSA9IG1sYjExJHJ1bnMpDQpgYGANCmBgYHtyfQ0KIyMxLiAgUnVucyBhbmQgbmV3X29icw0KbTEgPC0gbG0ocnVucyB+IG5ld19vYnMsIGRhdGEgPSBtbGIxMSkgICNsbSBpcyBhIGZvcm11bGEgdGhhdCB0YWtlcyB0aGUgZm9ybSB5IH4geC4gSGVyZSBpdCBjYW4gYmUgcmVhZCB0aGF0IHdlIHdhbnQgdG8gbWFrZSBhIGxpbmVhciBtb2RlbCBvZiBydW5zIGFzIGEgZnVuY3Rpb24gb2YgbmV3X29icw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGF0IFIgc2hvdWxkIGxvb2sgaW4gdGhlIG1sYjExIGRhdGEgZnJhbWUgdG8gZmluZCB0aGUgcnVucyBhbmQgbmV3X29icyB2YXJpYWJsZXMuDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI1RoZSBvdXRwdXQgb2YgbG0gaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYWxsIG9mIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIGFib3V0IHRoZSBsaW5lYXIgbW9kZWwgdGhhdCB3YXMganVzdCBmaXQuIFdlIGNhbiBhY2Nlc3MgdGhpcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjaW5mb3JtYXRpb24gdXNpbmcgdGhlIHN1bW1hcnkgZnVuY3Rpb24uDQpzdW1tYXJ5KG0xKQ0KYGBgDQoNCiMjIyBPTiBZT1VSIE9XTiA1DQpDaGVjayB0aGUgbW9kZWwgZGlhZ25vc3RpY3MgZm9yIHRoZSByZWdyZXNzaW9uIG1vZGVsIHdpdGggdGhlIHZhcmlhYmxlIHlvdSBkZWNpZGVkIHdhcyB0aGUgYmVzdCBwcmVkaWN0b3IgZm9yIHJ1bnMuDQoNCioqKkFuc3dlcioqKg0KDQpBcyBub3RlZCBpbiBPbiBZb3VyIE93biA1LCBuZXdfb2JzIGlzIHRoZSBiZXN0IHZhcmlhYmxlIGZvciBwcmVkaWN0aW5nIHJ1bnMuIE5ld19vYnMgUjIgdmFsdWUgaXMgaGlnaGVyIHRoYW4gYWxsIG90aGVyIG1vZGVscyBhdCAuOTM1IChyb3VuZGVkIHRvIHRoZSAzcmQgZGVjaW1hbCBwbGFjZSksIGFuZCB0aGUgc3VtIG9mIHNxdWFyZSByZXNpZHVhbHMgZXJyb3IgaXMgbG93ZXIgdGhhbiBhbGwgdGhlIG90aGVyIG1vZGVscyBhdCAxMjgzNy42Ni4gDQoNCjMuICBSMiAtIG5ld19vYnM6ICAwLjkzNDkNCjMuICBTdW0gb2YgUmVzaWR1YWxzIC0gbmV3X29iczogIDEyODM3LjY2DQoNCg0KDQpgYGB7cn0NCg0KbmV3Mz1sbShydW5zfm5ld19vYnMsZGF0YT1tbGIxMSkNCnBhcihtZnJvdz1jKDEsMSkpDQpwbG90KG1sYjExJG5ld19vYnMsbWxiMTEkcnVucyx4bGFiPSJOZXcgT2JzIix5bGFiPSJSdW5zIixtYWluPSJOZXcgT2JzIFZzIFJ1bnMiKSANCmFibGluZShuZXczKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCiMxLiAgUnVucyBhbmQgbmV3X29icw0KcGxvdF9zcyh4ID0gbWxiMTEkbmV3X29icywgeSA9IG1sYjExJHJ1bnMpDQpgYGANCg0K