Introduction

This notebook follows the Moneyball analysis from Videos 2 and 3. The goal is to use historical baseball data to build regression models for wins, runs scored, and runs allowed.

Question 1: Read and inspect the baseball data

Answer

baseball <- read.csv("baseball.csv")
str(baseball)
'data.frame':   1232 obs. of  15 variables:
 $ Team        : chr  "ARI" "ATL" "BAL" "BOS" ...
 $ League      : chr  "NL" "NL" "AL" "AL" ...
 $ Year        : int  2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
 $ RS          : int  734 700 712 734 613 748 669 667 758 726 ...
 $ RA          : int  688 600 705 806 759 676 588 845 890 670 ...
 $ W           : int  81 94 93 69 61 85 97 68 64 88 ...
 $ OBP         : num  0.328 0.32 0.311 0.315 0.302 0.318 0.315 0.324 0.33 0.335 ...
 $ SLG         : num  0.418 0.389 0.417 0.415 0.378 0.422 0.411 0.381 0.436 0.422 ...
 $ BA          : num  0.259 0.247 0.247 0.26 0.24 0.255 0.251 0.251 0.274 0.268 ...
 $ Playoffs    : int  0 1 1 0 0 0 1 0 0 1 ...
 $ RankSeason  : int  NA 4 5 NA NA NA 2 NA NA 6 ...
 $ RankPlayoffs: int  NA 5 4 NA NA NA 4 NA NA 2 ...
 $ G           : int  162 162 162 162 162 162 162 162 162 162 ...
 $ OOBP        : num  0.317 0.306 0.315 0.331 0.335 0.319 0.305 0.336 0.357 0.314 ...
 $ OSLG        : num  0.415 0.378 0.403 0.428 0.424 0.405 0.39 0.43 0.47 0.402 ...

The dataset contains team, league, year, runs scored, runs allowed, wins, offensive statistics, playoff information, and opponent statistics.

Question 2: Create the Moneyball-era dataset

Answer

moneyball <- subset(baseball, Year < 2002)
str(moneyball)
'data.frame':   902 obs. of  15 variables:
 $ Team        : chr  "ANA" "ARI" "ATL" "BAL" ...
 $ League      : chr  "AL" "NL" "NL" "AL" ...
 $ Year        : int  2001 2001 2001 2001 2001 2001 2001 2001 2001 2001 ...
 $ RS          : int  691 818 729 687 772 777 798 735 897 923 ...
 $ RA          : int  730 677 643 829 745 701 795 850 821 906 ...
 $ W           : int  75 92 88 63 82 88 83 66 91 73 ...
 $ OBP         : num  0.327 0.341 0.324 0.319 0.334 0.336 0.334 0.324 0.35 0.354 ...
 $ SLG         : num  0.405 0.442 0.412 0.38 0.439 0.43 0.451 0.419 0.458 0.483 ...
 $ BA          : num  0.261 0.267 0.26 0.248 0.266 0.261 0.268 0.262 0.278 0.292 ...
 $ Playoffs    : int  0 1 1 0 0 0 0 0 1 0 ...
 $ RankSeason  : int  NA 5 7 NA NA NA NA NA 6 NA ...
 $ RankPlayoffs: int  NA 1 3 NA NA NA NA NA 4 NA ...
 $ G           : int  162 162 162 162 161 162 162 162 162 162 ...
 $ OOBP        : num  0.331 0.311 0.314 0.337 0.329 0.321 0.334 0.341 0.341 0.35 ...
 $ OSLG        : num  0.412 0.404 0.384 0.439 0.393 0.398 0.427 0.455 0.417 0.48 ...

This keeps only seasons before 2002, which are the seasons used in the Moneyball analysis.

Question 3: Compute run difference

Answer

Run difference is calculated as runs scored minus runs allowed.

moneyball$RD <- moneyball$RS - moneyball$RA
str(moneyball)
'data.frame':   902 obs. of  16 variables:
 $ Team        : chr  "ANA" "ARI" "ATL" "BAL" ...
 $ League      : chr  "AL" "NL" "NL" "AL" ...
 $ Year        : int  2001 2001 2001 2001 2001 2001 2001 2001 2001 2001 ...
 $ RS          : int  691 818 729 687 772 777 798 735 897 923 ...
 $ RA          : int  730 677 643 829 745 701 795 850 821 906 ...
 $ W           : int  75 92 88 63 82 88 83 66 91 73 ...
 $ OBP         : num  0.327 0.341 0.324 0.319 0.334 0.336 0.334 0.324 0.35 0.354 ...
 $ SLG         : num  0.405 0.442 0.412 0.38 0.439 0.43 0.451 0.419 0.458 0.483 ...
 $ BA          : num  0.261 0.267 0.26 0.248 0.266 0.261 0.268 0.262 0.278 0.292 ...
 $ Playoffs    : int  0 1 1 0 0 0 0 0 1 0 ...
 $ RankSeason  : int  NA 5 7 NA NA NA NA NA 6 NA ...
 $ RankPlayoffs: int  NA 1 3 NA NA NA NA NA 4 NA ...
 $ G           : int  162 162 162 162 161 162 162 162 162 162 ...
 $ OOBP        : num  0.331 0.311 0.314 0.337 0.329 0.321 0.334 0.341 0.341 0.35 ...
 $ OSLG        : num  0.412 0.404 0.384 0.439 0.393 0.398 0.427 0.455 0.417 0.48 ...
 $ RD          : int  -39 141 86 -142 27 76 3 -115 76 17 ...

A positive run difference means a team scored more runs than it allowed.

Question 4: Examine run difference and wins

Answer

plot(
  moneyball$RD,
  moneyball$W,
  xlab = "Run Difference",
  ylab = "Wins",
  main = "Run Difference and Team Wins"
)

The scatterplot should show a strong positive linear relationship.

Question 5: Predict wins from run difference

Answer

WinsReg <- lm(W ~ RD, data = moneyball)
summary(WinsReg)

Call:
lm(formula = W ~ RD, data = moneyball)

Residuals:
     Min       1Q   Median       3Q      Max 
-14.2662  -2.6509   0.1234   2.9364  11.6570 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 80.881375   0.131157  616.67   <2e-16 ***
RD           0.105766   0.001297   81.55   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.939 on 900 degrees of freedom
Multiple R-squared:  0.8808,    Adjusted R-squared:  0.8807 
F-statistic:  6651 on 1 and 900 DF,  p-value: < 2.2e-16

The estimated equation is approximately:

\[ \widehat{W} = 80.88 + 0.106(RD) \]

This means about 9 to 10 additional runs of run difference are associated with one extra win. The model explains about 88.1% of the variation in wins.

Question 6: Predict runs scored using OBP, SLG, and BA

Answer

RunsReg_full <- lm(RS ~ OBP + SLG + BA, data = moneyball)
summary(RunsReg_full)

Call:
lm(formula = RS ~ OBP + SLG + BA, data = moneyball)

Residuals:
    Min      1Q  Median      3Q     Max 
-70.941 -17.247  -0.621  16.754  90.998 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -788.46      19.70 -40.029  < 2e-16 ***
OBP          2917.42     110.47  26.410  < 2e-16 ***
SLG          1637.93      45.99  35.612  < 2e-16 ***
BA           -368.97     130.58  -2.826  0.00482 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 24.69 on 898 degrees of freedom
Multiple R-squared:  0.9302,    Adjusted R-squared:   0.93 
F-statistic:  3989 on 3 and 898 DF,  p-value: < 2.2e-16

This model explains about 93% of the variation in runs scored. OBP and SLG are strong positive predictors.

Question 7: Remove batting average

Answer

RunsReg <- lm(RS ~ OBP + SLG, data = moneyball)
summary(RunsReg)

Call:
lm(formula = RS ~ OBP + SLG, data = moneyball)

Residuals:
    Min      1Q  Median      3Q     Max 
-70.838 -17.174  -1.108  16.770  90.036 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -804.63      18.92  -42.53   <2e-16 ***
OBP          2737.77      90.68   30.19   <2e-16 ***
SLG          1584.91      42.16   37.60   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 24.79 on 899 degrees of freedom
Multiple R-squared:  0.9296,    Adjusted R-squared:  0.9294 
F-statistic:  5934 on 2 and 899 DF,  p-value: < 2.2e-16

The reduced model is approximately:

\[ \widehat{RS} = -804.63 + 2737.77(OBP) + 1584.91(SLG) \]

The R-squared remains about 0.930, so removing batting average creates a simpler model with nearly the same performance.

Question 8: Interpret the runs-scored model

Answer

Higher OBP and SLG are associated with more runs scored. Both predictors are statistically significant, and together they explain about 92.96% of the variation in runs scored.

Question 9: Predict runs allowed

Answer

RunsAllowedReg <- lm(RA ~ OOBP + OSLG, data = moneyball)
summary(RunsAllowedReg)

Call:
lm(formula = RA ~ OOBP + OSLG, data = moneyball)

Residuals:
    Min      1Q  Median      3Q     Max 
-82.397 -15.178  -0.129  17.679  60.955 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -837.38      60.26 -13.897  < 2e-16 ***
OOBP         2913.60     291.97   9.979 4.46e-16 ***
OSLG         1514.29     175.43   8.632 2.55e-13 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 25.67 on 87 degrees of freedom
  (812 observations deleted due to missingness)
Multiple R-squared:  0.9073,    Adjusted R-squared:  0.9052 
F-statistic: 425.8 on 2 and 87 DF,  p-value: < 2.2e-16

The estimated model is approximately:

\[ \widehat{RA} = -837.38 + 2913.60(OOBP) + 1514.29(OSLG) \]

Higher opponent OBP and opponent SLG are associated with more runs allowed. The model explains about 90.7% of the variation in runs allowed for the observations used.

Question 10: Explain the missing observations

Answer

sum(is.na(moneyball$OOBP))
[1] 812
sum(is.na(moneyball$OSLG))
[1] 812

Many rows have missing values for OOBP or OSLG. R automatically removes those rows when fitting the runs-allowed model.

Question 11: Compare the models

Answer

summary(WinsReg)

Call:
lm(formula = W ~ RD, data = moneyball)

Residuals:
     Min       1Q   Median       3Q      Max 
-14.2662  -2.6509   0.1234   2.9364  11.6570 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 80.881375   0.131157  616.67   <2e-16 ***
RD           0.105766   0.001297   81.55   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.939 on 900 degrees of freedom
Multiple R-squared:  0.8808,    Adjusted R-squared:  0.8807 
F-statistic:  6651 on 1 and 900 DF,  p-value: < 2.2e-16
summary(RunsReg)

Call:
lm(formula = RS ~ OBP + SLG, data = moneyball)

Residuals:
    Min      1Q  Median      3Q     Max 
-70.838 -17.174  -1.108  16.770  90.036 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -804.63      18.92  -42.53   <2e-16 ***
OBP          2737.77      90.68   30.19   <2e-16 ***
SLG          1584.91      42.16   37.60   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 24.79 on 899 degrees of freedom
Multiple R-squared:  0.9296,    Adjusted R-squared:  0.9294 
F-statistic:  5934 on 2 and 899 DF,  p-value: < 2.2e-16
summary(RunsAllowedReg)

Call:
lm(formula = RA ~ OOBP + OSLG, data = moneyball)

Residuals:
    Min      1Q  Median      3Q     Max 
-82.397 -15.178  -0.129  17.679  60.955 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -837.38      60.26 -13.897  < 2e-16 ***
OOBP         2913.60     291.97   9.979 4.46e-16 ***
OSLG         1514.29     175.43   8.632 2.55e-13 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 25.67 on 87 degrees of freedom
  (812 observations deleted due to missingness)
Multiple R-squared:  0.9073,    Adjusted R-squared:  0.9052 
F-statistic: 425.8 on 2 and 87 DF,  p-value: < 2.2e-16

Approximate R-squared values:

  • Wins from run difference: 0.881
  • Runs scored from OBP and SLG: 0.930
  • Runs allowed from OOBP and OSLG: 0.907

All three models show strong relationships.

Final Conclusion

The analysis shows that run difference is a strong predictor of wins. OBP and SLG are strong predictors of runs scored, while opponent OBP and opponent SLG are strong predictors of runs allowed. These results support the use of statistical analysis in baseball decision-making.

LS0tCnRpdGxlOiAiTW9uZXliYWxsOiBWaWRlb3MgMiBhbmQgMyIKYXV0aG9yOiAiSnVsaW8gSGVybmFuZGV6IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgbm90ZWJvb2sgZm9sbG93cyB0aGUgTW9uZXliYWxsIGFuYWx5c2lzIGZyb20gVmlkZW9zIDIgYW5kIDMuIFRoZSBnb2FsIGlzIHRvIHVzZSBoaXN0b3JpY2FsIGJhc2ViYWxsIGRhdGEgdG8gYnVpbGQgcmVncmVzc2lvbiBtb2RlbHMgZm9yIHdpbnMsIHJ1bnMgc2NvcmVkLCBhbmQgcnVucyBhbGxvd2VkLgoKIyBRdWVzdGlvbiAxOiBSZWFkIGFuZCBpbnNwZWN0IHRoZSBiYXNlYmFsbCBkYXRhCgojIyBBbnN3ZXIKCmBgYHtyfQpiYXNlYmFsbCA8LSByZWFkLmNzdigiYmFzZWJhbGwuY3N2IikKc3RyKGJhc2ViYWxsKQpgYGAKClRoZSBkYXRhc2V0IGNvbnRhaW5zIHRlYW0sIGxlYWd1ZSwgeWVhciwgcnVucyBzY29yZWQsIHJ1bnMgYWxsb3dlZCwgd2lucywgb2ZmZW5zaXZlIHN0YXRpc3RpY3MsIHBsYXlvZmYgaW5mb3JtYXRpb24sIGFuZCBvcHBvbmVudCBzdGF0aXN0aWNzLgoKIyBRdWVzdGlvbiAyOiBDcmVhdGUgdGhlIE1vbmV5YmFsbC1lcmEgZGF0YXNldAoKIyMgQW5zd2VyCgpgYGB7cn0KbW9uZXliYWxsIDwtIHN1YnNldChiYXNlYmFsbCwgWWVhciA8IDIwMDIpCnN0cihtb25leWJhbGwpCmBgYAoKVGhpcyBrZWVwcyBvbmx5IHNlYXNvbnMgYmVmb3JlIDIwMDIsIHdoaWNoIGFyZSB0aGUgc2Vhc29ucyB1c2VkIGluIHRoZSBNb25leWJhbGwgYW5hbHlzaXMuCgojIFF1ZXN0aW9uIDM6IENvbXB1dGUgcnVuIGRpZmZlcmVuY2UKCiMjIEFuc3dlcgoKUnVuIGRpZmZlcmVuY2UgaXMgY2FsY3VsYXRlZCBhcyBydW5zIHNjb3JlZCBtaW51cyBydW5zIGFsbG93ZWQuCgpgYGB7cn0KbW9uZXliYWxsJFJEIDwtIG1vbmV5YmFsbCRSUyAtIG1vbmV5YmFsbCRSQQpzdHIobW9uZXliYWxsKQpgYGAKCkEgcG9zaXRpdmUgcnVuIGRpZmZlcmVuY2UgbWVhbnMgYSB0ZWFtIHNjb3JlZCBtb3JlIHJ1bnMgdGhhbiBpdCBhbGxvd2VkLgoKIyBRdWVzdGlvbiA0OiBFeGFtaW5lIHJ1biBkaWZmZXJlbmNlIGFuZCB3aW5zCgojIyBBbnN3ZXIKCmBgYHtyfQpwbG90KAogIG1vbmV5YmFsbCRSRCwKICBtb25leWJhbGwkVywKICB4bGFiID0gIlJ1biBEaWZmZXJlbmNlIiwKICB5bGFiID0gIldpbnMiLAogIG1haW4gPSAiUnVuIERpZmZlcmVuY2UgYW5kIFRlYW0gV2lucyIKKQpgYGAKClRoZSBzY2F0dGVycGxvdCBzaG91bGQgc2hvdyBhIHN0cm9uZyBwb3NpdGl2ZSBsaW5lYXIgcmVsYXRpb25zaGlwLgoKIyBRdWVzdGlvbiA1OiBQcmVkaWN0IHdpbnMgZnJvbSBydW4gZGlmZmVyZW5jZQoKIyMgQW5zd2VyCgpgYGB7cn0KV2luc1JlZyA8LSBsbShXIH4gUkQsIGRhdGEgPSBtb25leWJhbGwpCnN1bW1hcnkoV2luc1JlZykKYGBgCgpUaGUgZXN0aW1hdGVkIGVxdWF0aW9uIGlzIGFwcHJveGltYXRlbHk6CgpcWwpcd2lkZWhhdHtXfSA9IDgwLjg4ICsgMC4xMDYoUkQpClxdCgpUaGlzIG1lYW5zIGFib3V0IDkgdG8gMTAgYWRkaXRpb25hbCBydW5zIG9mIHJ1biBkaWZmZXJlbmNlIGFyZSBhc3NvY2lhdGVkIHdpdGggb25lIGV4dHJhIHdpbi4gVGhlIG1vZGVsIGV4cGxhaW5zIGFib3V0IDg4LjElIG9mIHRoZSB2YXJpYXRpb24gaW4gd2lucy4KCiMgUXVlc3Rpb24gNjogUHJlZGljdCBydW5zIHNjb3JlZCB1c2luZyBPQlAsIFNMRywgYW5kIEJBCgojIyBBbnN3ZXIKCmBgYHtyfQpSdW5zUmVnX2Z1bGwgPC0gbG0oUlMgfiBPQlAgKyBTTEcgKyBCQSwgZGF0YSA9IG1vbmV5YmFsbCkKc3VtbWFyeShSdW5zUmVnX2Z1bGwpCmBgYAoKVGhpcyBtb2RlbCBleHBsYWlucyBhYm91dCA5MyUgb2YgdGhlIHZhcmlhdGlvbiBpbiBydW5zIHNjb3JlZC4gT0JQIGFuZCBTTEcgYXJlIHN0cm9uZyBwb3NpdGl2ZSBwcmVkaWN0b3JzLgoKIyBRdWVzdGlvbiA3OiBSZW1vdmUgYmF0dGluZyBhdmVyYWdlCgojIyBBbnN3ZXIKCmBgYHtyfQpSdW5zUmVnIDwtIGxtKFJTIH4gT0JQICsgU0xHLCBkYXRhID0gbW9uZXliYWxsKQpzdW1tYXJ5KFJ1bnNSZWcpCmBgYAoKVGhlIHJlZHVjZWQgbW9kZWwgaXMgYXBwcm94aW1hdGVseToKClxbClx3aWRlaGF0e1JTfSA9IC04MDQuNjMgKyAyNzM3Ljc3KE9CUCkgKyAxNTg0LjkxKFNMRykKXF0KClRoZSBSLXNxdWFyZWQgcmVtYWlucyBhYm91dCAwLjkzMCwgc28gcmVtb3ZpbmcgYmF0dGluZyBhdmVyYWdlIGNyZWF0ZXMgYSBzaW1wbGVyIG1vZGVsIHdpdGggbmVhcmx5IHRoZSBzYW1lIHBlcmZvcm1hbmNlLgoKIyBRdWVzdGlvbiA4OiBJbnRlcnByZXQgdGhlIHJ1bnMtc2NvcmVkIG1vZGVsCgojIyBBbnN3ZXIKCkhpZ2hlciBPQlAgYW5kIFNMRyBhcmUgYXNzb2NpYXRlZCB3aXRoIG1vcmUgcnVucyBzY29yZWQuIEJvdGggcHJlZGljdG9ycyBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgYW5kIHRvZ2V0aGVyIHRoZXkgZXhwbGFpbiBhYm91dCA5Mi45NiUgb2YgdGhlIHZhcmlhdGlvbiBpbiBydW5zIHNjb3JlZC4KCiMgUXVlc3Rpb24gOTogUHJlZGljdCBydW5zIGFsbG93ZWQKCiMjIEFuc3dlcgoKYGBge3J9ClJ1bnNBbGxvd2VkUmVnIDwtIGxtKFJBIH4gT09CUCArIE9TTEcsIGRhdGEgPSBtb25leWJhbGwpCnN1bW1hcnkoUnVuc0FsbG93ZWRSZWcpCmBgYAoKVGhlIGVzdGltYXRlZCBtb2RlbCBpcyBhcHByb3hpbWF0ZWx5OgoKXFsKXHdpZGVoYXR7UkF9ID0gLTgzNy4zOCArIDI5MTMuNjAoT09CUCkgKyAxNTE0LjI5KE9TTEcpClxdCgpIaWdoZXIgb3Bwb25lbnQgT0JQIGFuZCBvcHBvbmVudCBTTEcgYXJlIGFzc29jaWF0ZWQgd2l0aCBtb3JlIHJ1bnMgYWxsb3dlZC4gVGhlIG1vZGVsIGV4cGxhaW5zIGFib3V0IDkwLjclIG9mIHRoZSB2YXJpYXRpb24gaW4gcnVucyBhbGxvd2VkIGZvciB0aGUgb2JzZXJ2YXRpb25zIHVzZWQuCgojIFF1ZXN0aW9uIDEwOiBFeHBsYWluIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucwoKIyMgQW5zd2VyCgpgYGB7cn0Kc3VtKGlzLm5hKG1vbmV5YmFsbCRPT0JQKSkKc3VtKGlzLm5hKG1vbmV5YmFsbCRPU0xHKSkKYGBgCgpNYW55IHJvd3MgaGF2ZSBtaXNzaW5nIHZhbHVlcyBmb3IgT09CUCBvciBPU0xHLiBSIGF1dG9tYXRpY2FsbHkgcmVtb3ZlcyB0aG9zZSByb3dzIHdoZW4gZml0dGluZyB0aGUgcnVucy1hbGxvd2VkIG1vZGVsLgoKIyBRdWVzdGlvbiAxMTogQ29tcGFyZSB0aGUgbW9kZWxzCgojIyBBbnN3ZXIKCmBgYHtyfQpzdW1tYXJ5KFdpbnNSZWcpCnN1bW1hcnkoUnVuc1JlZykKc3VtbWFyeShSdW5zQWxsb3dlZFJlZykKYGBgCgpBcHByb3hpbWF0ZSBSLXNxdWFyZWQgdmFsdWVzOgoKLSBXaW5zIGZyb20gcnVuIGRpZmZlcmVuY2U6IDAuODgxCi0gUnVucyBzY29yZWQgZnJvbSBPQlAgYW5kIFNMRzogMC45MzAKLSBSdW5zIGFsbG93ZWQgZnJvbSBPT0JQIGFuZCBPU0xHOiAwLjkwNwoKQWxsIHRocmVlIG1vZGVscyBzaG93IHN0cm9uZyByZWxhdGlvbnNoaXBzLgoKIyBGaW5hbCBDb25jbHVzaW9uCgpUaGUgYW5hbHlzaXMgc2hvd3MgdGhhdCBydW4gZGlmZmVyZW5jZSBpcyBhIHN0cm9uZyBwcmVkaWN0b3Igb2Ygd2lucy4gT0JQIGFuZCBTTEcgYXJlIHN0cm9uZyBwcmVkaWN0b3JzIG9mIHJ1bnMgc2NvcmVkLCB3aGlsZSBvcHBvbmVudCBPQlAgYW5kIG9wcG9uZW50IFNMRyBhcmUgc3Ryb25nIHByZWRpY3RvcnMgb2YgcnVucyBhbGxvd2VkLiBUaGVzZSByZXN1bHRzIHN1cHBvcnQgdGhlIHVzZSBvZiBzdGF0aXN0aWNhbCBhbmFseXNpcyBpbiBiYXNlYmFsbCBkZWNpc2lvbi1tYWtpbmcuCg==