This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

** Intro to Linear Regression: First Base hitting stats**

# Read in data
firstbase = read.csv("C:/Users/duway/Downloads/firstbasestats.csv")
str(firstbase)# check the structure of the data
'data.frame':   23 obs. of  15 variables:
 $ Player            : chr  "Freddie Freeman" "Jose Abreu" "Nate Lowe" "Paul Goldschmidt" ...
 $ Pos               : chr  "1B" "1B" "1B" "1B" ...
 $ Team              : chr  "LAD" "CHW" "TEX" "STL" ...
 $ GP                : int  159 157 157 151 160 140 160 145 146 143 ...
 $ AB                : int  612 601 593 561 638 551 583 555 545 519 ...
 $ H                 : int  199 183 179 178 175 152 141 139 132 124 ...
 $ X2B               : int  47 40 26 41 35 27 25 28 40 23 ...
 $ HR                : int  21 15 27 35 32 20 36 22 8 18 ...
 $ RBI               : int  100 75 76 115 97 84 94 85 53 63 ...
 $ AVG               : num  0.325 0.305 0.302 0.317 0.274 0.276 0.242 0.251 0.242 0.239 ...
 $ OBP               : num  0.407 0.379 0.358 0.404 0.339 0.34 0.327 0.305 0.288 0.319 ...
 $ SLG               : num  0.511 0.446 0.492 0.578 0.48 0.437 0.477 0.423 0.36 0.391 ...
 $ OPS               : num  0.918 0.824 0.851 0.981 0.818 0.777 0.804 0.729 0.647 0.71 ...
 $ WAR               : num  5.77 4.19 3.21 7.86 3.85 3.07 5.05 1.32 -0.33 1.87 ...
 $ Payroll.Salary2023: num  27000000 19500000 4050000 26000000 14500000 ...
# 23 rows and 15 columns(23 observations and 15 variables)
# create a summary of the data
summary(firstbase)
    Player              Pos           
 Length:23          Length:23         
 Class :character   Class :character  
 Mode  :character   Mode  :character  
                                      
                                      
                                      
     Team                 GP              AB       
 Length:23          Min.   :  5.0   Min.   : 14.0  
 Class :character   1st Qu.:105.5   1st Qu.:309.0  
 Mode  :character   Median :131.0   Median :465.0  
                    Mean   :120.2   Mean   :426.9  
                    3rd Qu.:152.0   3rd Qu.:558.0  
                    Max.   :160.0   Max.   :638.0  
       H              X2B              HR       
 Min.   :  3.0   Min.   : 1.00   Min.   : 0.00  
 1st Qu.: 74.5   1st Qu.:13.50   1st Qu.: 8.00  
 Median :115.0   Median :23.00   Median :18.00  
 Mean   :110.0   Mean   :22.39   Mean   :17.09  
 3rd Qu.:146.5   3rd Qu.:28.00   3rd Qu.:24.50  
 Max.   :199.0   Max.   :47.00   Max.   :36.00  
      RBI              AVG              OBP        
 Min.   :  1.00   Min.   :0.2020   Min.   :0.2140  
 1st Qu.: 27.00   1st Qu.:0.2180   1st Qu.:0.3030  
 Median : 63.00   Median :0.2420   Median :0.3210  
 Mean   : 59.43   Mean   :0.2499   Mean   :0.3242  
 3rd Qu.: 84.50   3rd Qu.:0.2750   3rd Qu.:0.3395  
 Max.   :115.00   Max.   :0.3250   Max.   :0.4070  
      SLG              OPS              WAR        
 Min.   :0.2860   Min.   :0.5000   Min.   :-1.470  
 1st Qu.:0.3505   1st Qu.:0.6445   1st Qu.: 0.190  
 Median :0.4230   Median :0.7290   Median : 1.310  
 Mean   :0.4106   Mean   :0.7346   Mean   : 1.788  
 3rd Qu.:0.4690   3rd Qu.:0.8175   3rd Qu.: 3.140  
 Max.   :0.5780   Max.   :0.9810   Max.   : 7.860  
 Payroll.Salary2023
 Min.   :  720000  
 1st Qu.:  739200  
 Median : 4050000  
 Mean   : 6972743  
 3rd Qu.: 8150000  
 Max.   :27000000  

** Create a linear model to predict HRs from ABs**

# create a linear model to predict salaries and RBI
model1 = lm(Payroll.Salary2023 ~ RBI, data=firstbase)
summary(model1)

Call:
lm(formula = Payroll.Salary2023 ~ RBI, data = firstbase)

Residuals:
      Min        1Q    Median        3Q       Max 
-10250331  -5220790   -843455   2386848  13654950 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -2363744    2866320  -0.825  0.41883   
RBI           157088      42465   3.699  0.00133 **
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6516000 on 21 degrees of freedom
Multiple R-squared:  0.3945,    Adjusted R-squared:  0.3657 
F-statistic: 13.68 on 1 and 21 DF,  p-value: 0.001331
#sum of squared Errors
model1$residuals
          1           2           3           4 
 13654950.2  10082148.6  -5524939.3  10298631.2 
          5           6           7           8 
  1626214.0  -6731642.8  -5902522.2 -10250330.7 
          9          10          11          12 
 -4711916.8   -532796.1  -6667082.5  -6696203.1 
         13          14          15          16 
  7582148.6  -4916640.9  -1898125.3   -336532.3 
         17          18          19          20 
  -995042.5  -1311618.3   -843454.5   8050721.3 
         21          22          23 
  1250336.9   1847040.4   2926656.0 
# sse
# adj r square explains the proportion of the variance in the dependent variable that is predictable from the independent variable
# example 0.5 means 50% of the variance in the dependent variable is predictable from the independent variable
sum(model1$residuals^2)
[1] 8.914926e+14
# Linear Regression (two variables)
model2 = lm(Payroll.Salary2023 ~ AVG + RBI, data=firstbase)
summary(model2)

Call:
lm(formula = Payroll.Salary2023 ~ AVG + RBI, data = firstbase)

Residuals:
     Min       1Q   Median       3Q      Max 
-9097952 -4621582   -33233  3016541 10260245 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)  
(Intercept) -18083756    9479037  -1.908   0.0709 .
AVG          74374031   42934155   1.732   0.0986 .
RBI            108850      49212   2.212   0.0388 *
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6226000 on 20 degrees of freedom
Multiple R-squared:  0.4735,    Adjusted R-squared:  0.4209 
F-statistic: 8.994 on 2 and 20 DF,  p-value: 0.001636
# Sum of Squared Errors
SSE = sum(model2$residuals^2)
SSE
[1] 7.751841e+14

** Create a linear model to predict HRs with all predictors **

#Linear Regression (all variables)
model3 = lm(Payroll.Salary2023 ~ HR + RBI + AVG + OBP+ OPS, data=firstbase)
summary(model3)

Call:
lm(formula = Payroll.Salary2023 ~ HR + RBI + AVG + OBP + OPS, 
    data = firstbase)

Residuals:
     Min       1Q   Median       3Q      Max 
-9611440 -3338119    64016  4472451  9490309 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)  
(Intercept) -31107859   11738494  -2.650   0.0168 *
HR            -341069     552069  -0.618   0.5449  
RBI            115786     113932   1.016   0.3237  
AVG         -63824769  104544645  -0.611   0.5496  
OBP          27054948  131210166   0.206   0.8391  
OPS          60181012   95415131   0.631   0.5366  
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6023000 on 17 degrees of freedom
Multiple R-squared:  0.5811,    Adjusted R-squared:  0.4579 
F-statistic: 4.717 on 5 and 17 DF,  p-value: 0.006951
# Sum of Squared Errors
SSE = sum(model3$residuals^2)
SSE
[1] 6.167793e+14

the model with all predictors has the lowest sum of squared errors suggesting that it is the best model to predict payroll salary 2023 so far.

firstbase<-firstbase[,-(1:3)]# remove the first three columns
# Correlations
cor(firstbase$RBI, firstbase$Payroll.Salary2023)
[1] 0.6281239

the correlation between RBI and Payroll Salary 2023 is 0.63 which is a strong positive correlation relative to other variables.

cor(firstbase$AVG, firstbase$OBP)
[1] 0.8028894

the correlation between AVG and OBP is 0.80 which is a strong positive correlation relative to other variables.

cor(firstbase)# correlation matrix
                          GP        AB         H       X2B
GP                 1.0000000 0.9779421 0.9056508 0.8446267
AB                 0.9779421 1.0000000 0.9516701 0.8924632
H                  0.9056508 0.9516701 1.0000000 0.9308318
X2B                0.8446267 0.8924632 0.9308318 1.0000000
HR                 0.7432552 0.7721339 0.7155225 0.5889699
RBI                0.8813917 0.9125839 0.9068893 0.8485911
AVG                0.4430808 0.5126292 0.7393167 0.6613085
OBP                0.4841583 0.5026125 0.6560021 0.5466537
SLG                0.6875270 0.7471949 0.8211406 0.7211259
OPS                0.6504483 0.6980141 0.8069779 0.6966830
WAR                0.5645243 0.6211558 0.7688712 0.6757470
Payroll.Salary2023 0.4614889 0.5018820 0.6249911 0.6450730
                          HR       RBI       AVG       OBP
GP                 0.7432552 0.8813917 0.4430808 0.4841583
AB                 0.7721339 0.9125839 0.5126292 0.5026125
H                  0.7155225 0.9068893 0.7393167 0.6560021
X2B                0.5889699 0.8485911 0.6613085 0.5466537
HR                 1.0000000 0.8929048 0.3444242 0.4603408
RBI                0.8929048 1.0000000 0.5658479 0.5704463
AVG                0.3444242 0.5658479 1.0000000 0.8028894
OBP                0.4603408 0.5704463 0.8028894 1.0000000
SLG                0.8681501 0.8824090 0.7254274 0.7617499
OPS                0.7638721 0.8156612 0.7989005 0.8987390
WAR                0.6897677 0.7885666 0.7855945 0.7766375
Payroll.Salary2023 0.5317619 0.6281239 0.5871543 0.7025979
                         SLG       OPS       WAR Payroll.Salary2023
GP                 0.6875270 0.6504483 0.5645243          0.4614889
AB                 0.7471949 0.6980141 0.6211558          0.5018820
H                  0.8211406 0.8069779 0.7688712          0.6249911
X2B                0.7211259 0.6966830 0.6757470          0.6450730
HR                 0.8681501 0.7638721 0.6897677          0.5317619
RBI                0.8824090 0.8156612 0.7885666          0.6281239
AVG                0.7254274 0.7989005 0.7855945          0.5871543
OBP                0.7617499 0.8987390 0.7766375          0.7025979
SLG                1.0000000 0.9686752 0.8611140          0.6974086
OPS                0.9686752 1.0000000 0.8799893          0.7394981
WAR                0.8611140 0.8799893 1.0000000          0.8086359
Payroll.Salary2023 0.6974086 0.7394981 0.8086359          1.0000000
#Removing AVG
model5 = lm(Payroll.Salary2023 ~ RBI + OBP+OPS, data=firstbase)
summary(model5)

Call:
lm(formula = Payroll.Salary2023 ~ RBI + OBP + OPS, data = firstbase)

Residuals:
     Min       1Q   Median       3Q      Max 
-9465449 -3411234   259746  4102864  8876798 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)  
(Intercept) -29737007   10855411  -2.739    0.013 *
RBI             72393      84646   0.855    0.403  
OBP          82751360   83534224   0.991    0.334  
OPS           7598051   45525575   0.167    0.869  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5767000 on 19 degrees of freedom
Multiple R-squared:  0.5709,    Adjusted R-squared:  0.5031 
F-statistic: 8.426 on 3 and 19 DF,  p-value: 0.000913

the model with RBI, OBP, and OPS has the lowest sum of squared errors .

#Removing AVG
model5 = lm(Payroll.Salary2023 ~ RBI + OBP+OPS, data=firstbase)
summary(model5)

Call:
lm(formula = Payroll.Salary2023 ~ RBI + OBP + OPS, data = firstbase)

Residuals:
     Min       1Q   Median       3Q      Max 
-9465449 -3411234   259746  4102864  8876798 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)  
(Intercept) -29737007   10855411  -2.739    0.013 *
RBI             72393      84646   0.855    0.403  
OBP          82751360   83534224   0.991    0.334  
OPS           7598051   45525575   0.167    0.869  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5767000 on 19 degrees of freedom
Multiple R-squared:  0.5709,    Adjusted R-squared:  0.5031 
F-statistic: 8.426 on 3 and 19 DF,  p-value: 0.000913

#intercept is -2.74 shows a statistal significance #RBI, OBP, and OPS are not statistically significant predictors of Payroll Salary 2023 in this model as there p-values are greater than 0.05.

model6 = lm(Payroll.Salary2023 ~ RBI + OBP, data=firstbase)
summary(model6)

Call:
lm(formula = Payroll.Salary2023 ~ RBI + OBP, data = firstbase)

Residuals:
     Min       1Q   Median       3Q      Max 
-9045497 -3487008   139497  4084739  9190185 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) -28984802    9632560  -3.009  0.00693 **
RBI             84278      44634   1.888  0.07360 . 
OBP          95468873   33385182   2.860  0.00969 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5625000 on 20 degrees of freedom
Multiple R-squared:  0.5703,    Adjusted R-squared:  0.5273 
F-statistic: 13.27 on 2 and 20 DF,  p-value: 0.0002149

Model6 with RBI and OBP as predictors shows that the T-value for RBI is 1.888 and the T-value for OBP is 2.860 are statistically significant predictors of Payroll Salary 2023 as their p-values are less than 0.05.

Below we are going to use the test set to predict the payroll salary 2023 using the model with RBI and OBP as predictors.

# Read in test set
firstbaseTest = read.csv("C:/Users/duway/Downloads/firstbasestats_test.csv")
str(firstbaseTest)
'data.frame':   2 obs. of  15 variables:
 $ Player            : chr  "Matt Olson" "Josh Bell"
 $ Pos               : chr  "1B" "1B"
 $ Team              : chr  "ATL" "SD"
 $ GP                : int  162 156
 $ AB                : int  616 552
 $ H                 : int  148 147
 $ X2B               : int  44 29
 $ HR                : int  34 17
 $ RBI               : int  103 71
 $ AVG               : num  0.24 0.266
 $ OBP               : num  0.325 0.362
 $ SLG               : num  0.477 0.422
 $ OPS               : num  0.802 0.784
 $ WAR               : num  3.29 3.5
 $ Payroll.Salary2023: num  21000000 16500000
# Make test set predictions
predictTest = predict(model6, newdata=firstbaseTest)
predictTest
       1        2 
10723186 11558647 
# Compute R-squared
SSE = sum((firstbaseTest$Payroll.Salary2023 - predictTest)^2)
SST = sum((firstbaseTest$Payroll.Salary2023 - mean(firstbase$Payroll.Salary2023))^2)
1 - SSE/SST
[1] 0.5477734

The model does a resoaonable job of predicting Payroll Salary 2023 as the R-squared value is 0.54 which means 54% of the variance in the dependent variable is predictable from the independent variables.

#plot the data and set the intercept to 0
plot(firstbase$RBI, firstbase$Payroll.Salary2023, xlab="RBI", ylab="Payroll Salary 2023", main="RBI vs Payroll Salary 2023")
abline(model1, col="red")
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KDQoNCioqIEludHJvIHRvIExpbmVhciBSZWdyZXNzaW9uOiBGaXJzdCBCYXNlIGhpdHRpbmcgc3RhdHMqKiANCg0KDQoNCg0KYGBge3J9DQojIFJlYWQgaW4gZGF0YQ0KZmlyc3RiYXNlID0gcmVhZC5jc3YoIkM6L1VzZXJzL2R1d2F5L0Rvd25sb2Fkcy9maXJzdGJhc2VzdGF0cy5jc3YiKQ0Kc3RyKGZpcnN0YmFzZSkjIGNoZWNrIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGENCiMgMjMgcm93cyBhbmQgMTUgY29sdW1ucygyMyBvYnNlcnZhdGlvbnMgYW5kIDE1IHZhcmlhYmxlcykNCg0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KIyBjcmVhdGUgYSBzdW1tYXJ5IG9mIHRoZSBkYXRhDQpzdW1tYXJ5KGZpcnN0YmFzZSkNCmBgYA0KDQoqKiBDcmVhdGUgYSBsaW5lYXIgbW9kZWwgdG8gcHJlZGljdCBIUnMgZnJvbSBBQnMqKiANCmBgYHtyfQ0KIyBjcmVhdGUgYSBsaW5lYXIgbW9kZWwgdG8gcHJlZGljdCBzYWxhcmllcyBhbmQgUkJJDQptb2RlbDEgPSBsbShQYXlyb2xsLlNhbGFyeTIwMjMgfiBSQkksIGRhdGE9Zmlyc3RiYXNlKQ0Kc3VtbWFyeShtb2RlbDEpDQpgYGANCg0KDQpgYGB7cn0NCiNzdW0gb2Ygc3F1YXJlZCBFcnJvcnMNCm1vZGVsMSRyZXNpZHVhbHMNCg0KYGBgDQoNCmBgYHtyfQ0KIyBzc2UNCiMgYWRqIHIgc3F1YXJlIGV4cGxhaW5zIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSB2YXJpYW5jZSBpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIHRoYXQgaXMgcHJlZGljdGFibGUgZnJvbSB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUNCiMgZXhhbXBsZSAwLjUgbWVhbnMgNTAlIG9mIHRoZSB2YXJpYW5jZSBpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGlzIHByZWRpY3RhYmxlIGZyb20gdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlDQpzdW0obW9kZWwxJHJlc2lkdWFsc14yKQ0KYGBgDQoNCmBgYHtyfQ0KIyBMaW5lYXIgUmVncmVzc2lvbiAodHdvIHZhcmlhYmxlcykNCm1vZGVsMiA9IGxtKFBheXJvbGwuU2FsYXJ5MjAyMyB+IEFWRyArIFJCSSwgZGF0YT1maXJzdGJhc2UpDQpzdW1tYXJ5KG1vZGVsMikNCg0KDQpgYGANCg0KDQpgYGB7cn0NCiMgU3VtIG9mIFNxdWFyZWQgRXJyb3JzDQpTU0UgPSBzdW0obW9kZWwyJHJlc2lkdWFsc14yKQ0KU1NFDQpgYGANCg0KKiogQ3JlYXRlIGEgbGluZWFyIG1vZGVsIHRvIHByZWRpY3QgSFJzIHdpdGggYWxsIHByZWRpY3RvcnMgKiogDQpgYGB7cn0NCiNMaW5lYXIgUmVncmVzc2lvbiAoYWxsIHZhcmlhYmxlcykNCm1vZGVsMyA9IGxtKFBheXJvbGwuU2FsYXJ5MjAyMyB+IEhSICsgUkJJICsgQVZHICsgT0JQKyBPUFMsIGRhdGE9Zmlyc3RiYXNlKQ0Kc3VtbWFyeShtb2RlbDMpDQoNCmBgYA0KYGBge3J9DQojIFN1bSBvZiBTcXVhcmVkIEVycm9ycw0KU1NFID0gc3VtKG1vZGVsMyRyZXNpZHVhbHNeMikNClNTRQ0KDQpgYGANCiMgdGhlIG1vZGVsIHdpdGggYWxsIHByZWRpY3RvcnMgaGFzIHRoZSBsb3dlc3Qgc3VtIG9mIHNxdWFyZWQgZXJyb3JzIHN1Z2dlc3RpbmcgdGhhdCBpdCBpcyB0aGUgYmVzdCBtb2RlbCB0byBwcmVkaWN0IHBheXJvbGwgc2FsYXJ5IDIwMjMgc28gZmFyLg0KDQoNCg0KYGBge3J9DQpmaXJzdGJhc2U8LWZpcnN0YmFzZVssLSgxOjMpXSMgcmVtb3ZlIHRoZSBmaXJzdCB0aHJlZSBjb2x1bW5zDQpgYGANCg0KDQpgYGB7cn0NCiMgQ29ycmVsYXRpb25zDQpjb3IoZmlyc3RiYXNlJFJCSSwgZmlyc3RiYXNlJFBheXJvbGwuU2FsYXJ5MjAyMykNCmBgYA0KIyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBSQkkgYW5kIFBheXJvbGwgU2FsYXJ5IDIwMjMgaXMgMC42MyB3aGljaCBpcyBhIHN0cm9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiByZWxhdGl2ZSB0byBvdGhlciB2YXJpYWJsZXMuDQoNCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KY29yKGZpcnN0YmFzZSRBVkcsIGZpcnN0YmFzZSRPQlApDQpgYGANCg0KIyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBBVkcgYW5kIE9CUCBpcyAwLjgwIHdoaWNoIGlzIGEgc3Ryb25nIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHJlbGF0aXZlIHRvIG90aGVyIHZhcmlhYmxlcy4NCg0KDQpgYGB7cn0NCmNvcihmaXJzdGJhc2UpIyBjb3JyZWxhdGlvbiBtYXRyaXgNCmBgYA0KDQoNCmBgYHtyfQ0KI1JlbW92aW5nIEFWRw0KbW9kZWw1ID0gbG0oUGF5cm9sbC5TYWxhcnkyMDIzIH4gUkJJICsgT0JQK09QUywgZGF0YT1maXJzdGJhc2UpDQpzdW1tYXJ5KG1vZGVsNSkNCmBgYA0KDQoNCg0KIyB0aGUgbW9kZWwgd2l0aCBSQkksIE9CUCwgYW5kIE9QUyBoYXMgdGhlIGxvd2VzdCBzdW0gb2Ygc3F1YXJlZCBlcnJvcnMgLg0KYGBge3J9DQojUmVtb3ZpbmcgQVZHDQptb2RlbDUgPSBsbShQYXlyb2xsLlNhbGFyeTIwMjMgfiBSQkkgKyBPQlArT1BTLCBkYXRhPWZpcnN0YmFzZSkNCnN1bW1hcnkobW9kZWw1KQ0KYGBgDQojaW50ZXJjZXB0IGlzIC0yLjc0IHNob3dzIGEgc3RhdGlzdGFsIHNpZ25pZmljYW5jZQ0KI1JCSSwgT0JQLCBhbmQgT1BTIGFyZSBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBwcmVkaWN0b3JzIG9mIFBheXJvbGwgU2FsYXJ5IDIwMjMgaW4gdGhpcyBtb2RlbCBhcyB0aGVyZSBwLXZhbHVlcyBhcmUgZ3JlYXRlciB0aGFuIDAuMDUuDQoNCmBgYHtyfQ0KbW9kZWw2ID0gbG0oUGF5cm9sbC5TYWxhcnkyMDIzIH4gUkJJICsgT0JQLCBkYXRhPWZpcnN0YmFzZSkNCnN1bW1hcnkobW9kZWw2KQ0KYGBgDQojIE1vZGVsNiB3aXRoIFJCSSBhbmQgT0JQIGFzIHByZWRpY3RvcnMgc2hvd3MgdGhhdCB0aGUgVC12YWx1ZSBmb3IgUkJJIGlzIDEuODg4IGFuZCB0aGUgVC12YWx1ZSBmb3IgT0JQIGlzIDIuODYwIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHByZWRpY3RvcnMgb2YgUGF5cm9sbCBTYWxhcnkgMjAyMyBhcyB0aGVpciBwLXZhbHVlcyBhcmUgbGVzcyB0aGFuIDAuMDUuDQoNCg0KDQoNCiMgQmVsb3cgd2UgYXJlIGdvaW5nIHRvIHVzZSB0aGUgdGVzdCBzZXQgdG8gcHJlZGljdCB0aGUgcGF5cm9sbCBzYWxhcnkgMjAyMyB1c2luZyB0aGUgbW9kZWwgd2l0aCBSQkkgYW5kIE9CUCBhcyBwcmVkaWN0b3JzLg0KDQpgYGB7cn0NCiMgUmVhZCBpbiB0ZXN0IHNldA0KZmlyc3RiYXNlVGVzdCA9IHJlYWQuY3N2KCJDOi9Vc2Vycy9kdXdheS9Eb3dubG9hZHMvZmlyc3RiYXNlc3RhdHNfdGVzdC5jc3YiKQ0Kc3RyKGZpcnN0YmFzZVRlc3QpDQpgYGANCg0KDQoNCg0KYGBge3J9DQojIE1ha2UgdGVzdCBzZXQgcHJlZGljdGlvbnMNCnByZWRpY3RUZXN0ID0gcHJlZGljdChtb2RlbDYsIG5ld2RhdGE9Zmlyc3RiYXNlVGVzdCkNCnByZWRpY3RUZXN0DQpgYGANCg0KYGBge3J9DQojIENvbXB1dGUgUi1zcXVhcmVkDQpTU0UgPSBzdW0oKGZpcnN0YmFzZVRlc3QkUGF5cm9sbC5TYWxhcnkyMDIzIC0gcHJlZGljdFRlc3QpXjIpDQpTU1QgPSBzdW0oKGZpcnN0YmFzZVRlc3QkUGF5cm9sbC5TYWxhcnkyMDIzIC0gbWVhbihmaXJzdGJhc2UkUGF5cm9sbC5TYWxhcnkyMDIzKSleMikNCjEgLSBTU0UvU1NUDQpgYGANCiMgVGhlIG1vZGVsIGRvZXMgYSByZXNvYW9uYWJsZSBqb2Igb2YgcHJlZGljdGluZyBQYXlyb2xsIFNhbGFyeSAyMDIzIGFzIHRoZSBSLXNxdWFyZWQgdmFsdWUgaXMgMC41NCB3aGljaCBtZWFucyA1NCUgb2YgdGhlIHZhcmlhbmNlIGluIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgaXMgcHJlZGljdGFibGUgZnJvbSB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KYGBge3J9DQojcGxvdCB0aGUgZGF0YSBhbmQgc2V0IHRoZSBpbnRlcmNlcHQgdG8gMA0KcGxvdChmaXJzdGJhc2UkUkJJLCBmaXJzdGJhc2UkUGF5cm9sbC5TYWxhcnkyMDIzLCB4bGFiPSJSQkkiLCB5bGFiPSJQYXlyb2xsIFNhbGFyeSAyMDIzIiwgbWFpbj0iUkJJIHZzIFBheXJvbGwgU2FsYXJ5IDIwMjMiKQ0KYWJsaW5lKG1vZGVsMSwgY29sPSJyZWQiKQ0KDQpgYGANCg0KDQoNCg0KDQo=