library("ggplot2")

Example 16.1

The annual bonuses ($1,000s) of six employees with different years of experience were recorded as follows. We wish to determine the straight-line relationship between annual bonus and years of experience.

Récupérer les données

years=1:6
bonus=c(6,1,9,5,17,12)
bonusdata=data.frame(years,bonus)

Représenter les données par un nuage de points

Représenter la droite des moindres carrés avec ggplot

Calcul manuel des coefficients de la régression

round(b0,3)
[1] 0.933

Les résidus

sum(e)
[1] -3.108624e-15

Représentation graphique des résidus (ou erreurs)

Illustration des moindres carrés

To be done

Faire une régression avec la fonction lm()

lm signifie linear models ## Effectuer la régression

LM$coefficients[2]
   years 
2.114286 

Les sorties de la régression

LM$fitted.values ## Les valeurs ajustés (ychap_i=b0+b1x_i) i.e. les ordonnées sur la droite 
        1         2         3         4         5         6 
 3.047619  5.161905  7.276190  9.390476 11.504762 13.619048 

Un bilan de la régression avec summary()

summary(LM)

Call:
lm(formula = bonus ~ years, data = bonusdata)

Residuals:
     1      2      3      4      5      6 
 2.952 -4.162  1.724 -4.390  5.495 -1.619 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.9333     4.1920   0.223    0.835
years         2.1143     1.0764   1.964    0.121

Residual standard error: 4.503 on 4 degrees of freedom
Multiple R-squared:  0.491, Adjusted R-squared:  0.3637 
F-statistic: 3.858 on 1 and 4 DF,  p-value: 0.121

Une présentation des résultats plus professionnelle avec Stargazer()

##stargazer(LM,type = "latex")
summary(LM)

Call:
lm(formula = bonus ~ years, data = bonusdata)

Residuals:
     1      2      3      4      5      6 
 2.952 -4.162  1.724 -4.390  5.495 -1.619 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.9333     4.1920   0.223    0.835
years         2.1143     1.0764   1.964    0.121

Residual standard error: 4.503 on 4 degrees of freedom
Multiple R-squared:  0.491, Adjusted R-squared:  0.3637 
F-statistic: 3.858 on 1 and 4 DF,  p-value: 0.121
5*(var(bonusdata$bonus)-
    (cov(bonusdata$years,bonusdata$bonus))^2/var(bonusdata$years))
[1] 81.10476
summary(LM)

Call:
lm(formula = bonus ~ years, data = bonusdata)

Residuals:
     1      2      3      4      5      6 
 2.952 -4.162  1.724 -4.390  5.495 -1.619 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.9333     4.1920   0.223    0.835
years         2.1143     1.0764   1.964    0.121

Residual standard error: 4.503 on 4 degrees of freedom
Multiple R-squared:  0.491, Adjusted R-squared:  0.3637 
F-statistic: 3.858 on 1 and 4 DF,  p-value: 0.121
sqrt(sum((LM$residuals)^2)/98) ## Calculer l'estimation de l'écart-type des erreurs formule p. 650 SSE/(n-2)
[1] 0.3264886

Odometer Reading and Prices of Used Toyota Camrys—Part 2

Find the standard error of estimate for Example 16.2 and describe what it tells you about the model’s fit.

SLM=summary(LM)
SLM$sigma

SSE=sum((LM$residuals)^2)
sqrt(SSE/98)

## Estimation de l’écart de b1

SLM$sigma/sqrt(99*var(data$Odometer))
[1] 0.004974639
SLM

Call:
lm(formula = Price ~ Odometer, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.68679 -0.27263  0.00521  0.23210  0.70071 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 17.248727   0.182093   94.72   <2e-16 ***
Odometer    -0.066861   0.004975  -13.44   <2e-16 ***
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3265 on 98 degrees of freedom
Multiple R-squared:  0.6483,    Adjusted R-squared:  0.6447 
F-statistic: 180.6 on 1 and 98 DF,  p-value: < 2.2e-16

Calcul de p-value du test de nullité de la pente

qt(0.025,98,lower.tail=F)*
SLM$sigma/(sqrt(99*var(data$Odometer))
)
[1] 0.009872009

EXAMPLE 16. 5 Measuring the Strength of the Linear Relationship between Odometer Reading and Price of Used Toyota Camrys

Find the coefficient of determination for Example 16.2 and describe what this statistic tells you about the regression model.

SLM$r.squared
(cor(data$Price,data$Odometer))^2

This statistic tells us that 64.83% of the variation in the auction selling prices is explained by the variation in the odometer readings.

ANOVA=anova(LM)
sum(ANOVA[,2])
99*var(data$Price)
ANOVA[1,2]/(99*var(data$Price))

EXAMPLE 16.7 Predicting the Price and Estimating the Mean Price of Used Toyota Camrys

  1. A used-car dealer is about to bid on a 3-year-old Toyota Camry equipped with all the standard features and with 40,000 (\(x_g\) ⫽ 40) miles on the odometer. To help him decide how much to bid, he needs to predict the selling price.
xg=data.frame(Odometer = c(40))

PREDICT=predict.lm(LM,xg,interval = "prediction")
SLM$coefficients[,1]%*%c(1,40)
?predict.lm
PREDICT[1]-PREDICT[2]
  1. The used-car dealer mentioned in part (a) has an opportunity to bid on a lot of cars offered by a rental company. The rental company has 250 Toyota Camrys all equipped with standard features. All the cars in this lot have about 40,000 (xg ⫽ 40) miles on their odometers. The dealer would like an estimate of the selling price of all the cars in the lot.
PREDICTEXP=predict.lm(LM,xg,interval = "confidence")
PREDICTEXP[1]-PREDICTEXP[2]
PREDICTEXP[3]-PREDICTEXP[1]

Avec les matrices

Si on note \[ Y=\begin{bmatrix} y_1\\ \vdots\\ y_n \\ \end{bmatrix} \text{ et } X=\begin{bmatrix} 1 & x_1\\ \vdots & \vdots \\ 1 & x_n \\ \end{bmatrix}, \] on obtient les estimateurs grâce à un clcul matriciel \[ \begin{bmatrix} b_0 \\ b_1 \end{bmatrix}= (X^tX)^{-1}X^tY, \]\[ X^t=\begin{bmatrix} 1 &\cdots& 1 \\ 1 & \cdots &x_n \\ \end{bmatrix}, \] est la matrice transposée de \(X\).

X=matrix(c(rep(1,100),data$Odometer),nrow = 100,ncol=2)
dim(X)
Y=matrix(data$Price,nrow = 100,ncol=1)
solve(t(X)%*%X)%*%t(X)%*%Y

SLM$coefficients

La matice de variance-covariance de \((b_0,b_1)\) est donnée par

\[ \sigma^2(X^tX)^{-1}. \] Comme \(\sigma^2\) est incommu, on l’estime ce qui donne



SLM$sigma

sqrt(sum((SLM$residuals)^2)/98)
(SLM$sigma)^2*solve(t(X)%*%X)

(SLM$coefficients[2,2])^2

vcov(LM)

Un peu d’algèbre

On rappelle que la méthode de moindres carrés va résoudre le programme suivant

\[ \min_{b_0,b_1} \sum (y_i-\hat{y_i})^2,\text{ avec } \hat{y_i}=b_0+b_1 x_i. \]

Par dérivation par rapport à \(b_0\) et \(b_1\) on obtient les deux condition du premier ordre suivantes (on notera que \(\partial \hat{y}_i/\partial b_1= x_i\))

\[ \begin{equation} \begin{cases} \sum x_i(y_i-\hat{y_i})=0;\\ \sum (y_i-\hat{y_i})=0. \end{cases} \end{equation} \]

La première condition vous dit que les erreurs sont de moyenne zero et la seconde que la variable des erreurs et la variables explicative ne sont pas corrélés.

On peut réécrire ces deux conditions ainsi \[ \begin{equation} \begin{cases} \sum (x_i-\bar{x})(y_i-\hat{y_i})=0;\\ \sum (y_i-\hat{y_i})=0. \end{cases} \end{equation} \]

On remarquera que \(\bar{y}=\bar{\hat{y}}\).

Pour fini, en replaçant \(b_0\) et \(b_1\) par leurs valeurs optimales, on trouve

\[ SSE=\sum (y_i-\hat{y_i})^2=\sum (y_i-\bar{y}+ \bar{y}-\hat{y_i})^2, \] ce qui donne

\[ SSE=\sum [y_i-\bar{y}-b_1(x_i-\bar{x})] ^2. \] En développant, on trouve

\[ SSE=\sum (y_i-\bar{y})^2-2b_1\sum(x_i-\bar{x})(y_i-\bar{y})+b^2_1\sum (x_i-\bar{x})^2. \]

En remarquant que

\[ b^2_1\sum (x_i-\bar{x})^2=b_1\sum(x_i-\bar{x})(y_i-\bar{y}), \] On obtient

\[ SSE=\sum (y_i-\bar{y})^2-b_1\sum(x_i-\bar{x})(y_i-\bar{y}). \]

En utilisant la valeur de \(b_1\), on trouve

\[ SSE=\sum (y_i-\bar{y})^2-\frac{[ \sum(x_i-\bar{x})(y_i-\bar{y}) ]^2}{\sum (x_i-\bar{x})^2} \]

On a aussi

\[ SSE=(1-R^2)\sum (y_i-\bar{y})^2. \]\[ R^2=\frac{[ \sum(x_i-\bar{x})(y_i-\bar{y}) ]^2}{\sum (x_i-\bar{x})^2\sum (y_i-\bar{y})^2}=\frac{s^2_{xy}}{s_{x}s_{y}}. \] On a aussi

\[ R^2=1-\frac{SSE }{\sum (y_i-\bar{y})^2}, \]

En remarquant qye \[ \sum(y_i-\bar{y })^2=\sum(y_i-\hat{y }_i)^2+\sum(\hat{y }_i-\bar{y })^2=SSE+\sum(\hat{y }_i-\bar{y })^2, \] On a aussi \[ R^2=\frac{\sum (y_i-\bar{y})^2-SSE }{\sum (y_i-\bar{y})^2}=\frac{\sum(\hat{y }_i-\bar{y })^2 }{\sum (y_i-\bar{y})^2}. \]

\(R^2\) devientb la part de variance expliquée par le modèle.

LS0tCnRpdGxlOiAiQ2hhcGl0cmUgNiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoImdncGxvdDIiKQpgYGAKCiMjIEV4YW1wbGUgMTYuMQoKVGhlIGFubnVhbCBib251c2VzICgkMSwwMDBzKSBvZiBzaXggZW1wbG95ZWVzIHdpdGggZGlmZmVyZW50IHllYXJzIG9mIGV4cGVyaWVuY2Ugd2VyZSByZWNvcmRlZCBhcyBmb2xsb3dzLiBXZSB3aXNoIHRvIGRldGVybWluZSB0aGUgc3RyYWlnaHQtbGluZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhbm51YWwgYm9udXMgYW5kIHllYXJzIG9mIGV4cGVyaWVuY2UuCgojIFLDqWN1cMOpcmVyIGxlcyBkb25uw6llcwoKCmBgYHtyfQp5ZWFycz0xOjYKYm9udXM9Yyg2LDEsOSw1LDE3LDEyKQpib251c2RhdGE9ZGF0YS5mcmFtZSh5ZWFycyxib251cykKYGBgCgojIFJlcHLDqXNlbnRlciBsZXMgZG9ubsOpZXMgcGFyIHVuIG51YWdlIGRlIHBvaW50cwoKYGBge3J9ClBQPC1nZ3Bsb3QoYm9udXNkYXRhLCBhZXMoeD15ZWFycywgeT1ib251cykpKyBnZW9tX3BvaW50KCkrZ2d0aXRsZSgiQm9udXMgRGF0YSIpClBQCmBgYAoKIyBSZXByw6lzZW50ZXIgbGEgZHJvaXRlIGRlcyBtb2luZHJlcyBjYXJyw6lzIGF2ZWMgZ2dwbG90CgpgYGB7cn0KUFA8LVBQK2dlb21fc21vb3RoKG1ldGhvZD0nbG0nLHNlPUZBTFNFKQoKYGBgCiMjIENhbGN1bCBtYW51ZWwgZGVzIGNvZWZmaWNpZW50cyBkZSBsYSByw6lncmVzc2lvbgoKYGBge3J9CmIxPC1jb3YoeCx5KS92YXIoeCkKcm91bmQoYjEsMykKYjA8LW1lYW4oeSktYjEqbWVhbih4KQpyb3VuZChiMCwzKQpgYGAKIyMgTGVzIHLDqXNpZHVzCgpgYGB7cn0KZTwteS1iMC1iMSp4CnN1bShlKQpzdW0oZV4yKQpgYGAKCiMjIFJlcHLDqXNlbnRhdGlvbiBncmFwaGlxdWUgZGVzIHLDqXNpZHVzIChvdSBlcnJldXJzKQoKYGBge3J9ClBQK2dlb21fc2VnbWVudChhZXMoeCA9IHllYXJzLCB5ID0gYm9udXMsIHhlbmQgPSB5ZWFycywgeWVuZCA9IGIwK2IxKnllYXJzKSkKICAKYGBgCgoKCgojIElsbHVzdHJhdGlvbiBkZXMgbW9pbmRyZXMgY2FycsOpcwpUbyBiZSBkb25lCgpgYGB7cn0KYjA9MwpiMT0xCnk9Ym9udXMKeD15ZWFycwoKClNTIDwtIGZ1bmN0aW9uKGIwLGIxKSB7CnN1bSgoeS0oYjArYjEqeCkpXjIpCn0KU1MoMCwyKQoKY3VydmUoZXhwLHhsaW0gPSBjKDAsMTApKQpgYGAKIyBGYWlyZSB1bmUgcsOpZ3Jlc3Npb24gYXZlYyBsYSBmb25jdGlvbiBsbSgpIAoKIGxtIHNpZ25pZmllIGxpbmVhciBtb2RlbHMKIyMgRWZmZWN0dWVyIGxhIHLDqWdyZXNzaW9uIApgYGB7cn0KTE08LWxtKGJvbnVzfnllYXJzLGRhdGE9Ym9udXNkYXRhKQoKCmBgYAojIyBMZXMgc29ydGllcyBkZSBsYSByw6lncmVzc2lvbgpgYGB7cn0KTE0kY29lZmZpY2llbnRzICMjIExlcyBjb2VmZmljaWVudHMgZGUgbGEgcsOpZ3Jlc3Npb24KTE0kY29lZmZpY2llbnRzWzFdICMjIEludGVyY2VwdCBiMApMTSRjb2VmZmljaWVudHNbMl0gIyMgc2xvcGUgYjEKTE0kcmVzaWR1YWxzICMjIExlcyByw6lzaWR1cyAoIGVfaSkKTE0kZml0dGVkLnZhbHVlcyAjIyBMZXMgdmFsZXVycyBhanVzdMOpcyAoeWNoYXBfaT1iMCtiMXhfaSkgaS5lLiBsZXMgb3Jkb25uw6llcyBzdXIgbGEgZHJvaXRlIApgYGAKIyBVbiBiaWxhbiBkZSBsYSByw6lncmVzc2lvbiBhdmVjIHN1bW1hcnkoKQoKYGBge3J9CnN1bW1hcnkoTE0pCmBgYAoKIyBVbmUgcHLDqXNlbnRhdGlvbiBkZXMgcsOpc3VsdGF0cyBwbHVzIHByb2Zlc3Npb25uZWxsZSBhdmVjIFN0YXJnYXplcigpCgoKYGBge3Isd2FybmluZz1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygic3RhcmdhemVyIikKc3RhcmdhemVyKExNLHR5cGUgPSAidGV4dCIpCiMjc3RhcmdhemVyKExNLHR5cGUgPSAibGF0ZXgiKQpzdW1tYXJ5KExNKQpgYGAKYGBge3J9ClNTRQpzdW0oKExNJHJlc2lkdWFscyleMikKNSoodmFyKGJvbnVzZGF0YSRib251cyktCiAgICAoY292KGJvbnVzZGF0YSR5ZWFycyxib251c2RhdGEkYm9udXMpKV4yL3Zhcihib251c2RhdGEkeWVhcnMpKQoKYGBgCgoKYGBge3J9ClBQPWdncGxvdChib251c2RhdGEsIGFlcyh4PXllYXJzLCB5PWJvbnVzKSkrIGdlb21fcG9pbnQoKQpQUD1QUCsKUFA9UFArCmIxPWNvdih5ZWFycyxib251cykvdmFyKHllYXJzKQpiMD1tZWFuKGJvbnVzKS1iMSptZWFuKHllYXJzKSAgICAgICAgICAgICAgICAKUFA9UFArZ2VvbV9zZWdtZW50KGFlcyh4ID0geWVhcnMsIHkgPSBib251cywgeGVuZCA9IHllYXJzLCB5ZW5kID0gYjArYjEqeWVhcnMpKQpQUCAgICAgICAgICAgICAgICAKTE09bG0oYm9udXN+eWVhcnMsZGF0YT1ib251c2RhdGEpCnN1bW1hcnkoTE0pCnllbmQ9TE0kZml0dGVkLnZhbHVlcwp4ZW5kPWJvbnVzZGF0YSR5ZWFycwpQUD1QUCtnZW9tX3NlZ21lbnQoYWVzKHggPSB5ZWFycywgeSA9IGJvbnVzLCB4ZW5kID0geWVhcnMsIHllbmQgPSB5ZW5kKSkKUFArZ2VvbV9wb2ludChhZXMoeD14ZW5kLHk9eWVuZCksY29sb3I9InJlZCIpClBQClNTRT1zdW0oKExNJHJlc2lkdWFscyleMikKc3FydChTU0UvKDYtMikpCnN1bW1hcnkoTE0pCgpgYGAKYGBge3Isd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkeGwpCmRhdGEgPC0gcmVhZF9leGNlbCgiWG0xNi0wMi54bHN4IikKTE09bG0oUHJpY2V+T2RvbWV0ZXIsZGF0YT1kYXRhKSAjIyBGYWlyZSB1bmUgcsOpZ3Jlc3Npb24Kc3RhcmdhemVyKExNLHR5cGU9InRleHQiKSAjIyBQcsOpc2VudGVyIGxhIHLDqWdyZXNzaW9uIGRhbnMgdW4gdGFibGVhdQpzcXJ0KHN1bSgoTE0kcmVzaWR1YWxzKV4yKS85OCkgIyMgQ2FsY3VsZXIgbCdlc3RpbWF0aW9uIGRlIGwnw6ljYXJ0LXR5cGUgZGVzIGVycmV1cnMgZm9ybXVsZSBwLiA2NTAgU1NFLyhuLTIpClNMTT1zdW1tYXJ5KExNKSAKU0xNJHNpZ21hICMgRXh0YWlyZSBsJ2VzdGltYXRpb24gZGUgbCfDqWNhcnQtdHlwZSBkZXMgZXJyZXVycyBkZSBzdW1tYXJ5CmBgYAoKCiMjIE9kb21ldGVyIFJlYWRpbmcgYW5kIFByaWNlcyBvZiBVc2VkIFRveW90YSBDYW1yeXPigJRQYXJ0IDIKRmluZCB0aGUgc3RhbmRhcmQgZXJyb3Igb2YgZXN0aW1hdGUgZm9yIEV4YW1wbGUgMTYuMiBhbmQgZGVzY3JpYmUgd2hhdCBpdCB0ZWxscyB5b3UgYWJvdXQgdGhlIG1vZGVs4oCZcyBmaXQuCgoKYGBge3J9ClNMTT1zdW1tYXJ5KExNKQpTTE0kc2lnbWEKClNTRT1zdW0oKExNJHJlc2lkdWFscyleMikKc3FydChTU0UvOTgpCgoKYGBgCiAKICMjIEVzdGltYXRpb24gZGUgbCfDqWNhcnQgZGUgYjEKIApgYGB7cn0KU0xNJHNpZ21hL3NxcnQoOTkqdmFyKGRhdGEkT2RvbWV0ZXIpKQpTTE0KYGBgCgojIyBDYWxjdWwgZGUgcC12YWx1ZSBkdSB0ZXN0IGRlIG51bGxpdMOpIGRlIGxhIHBlbnRlCgpgYGB7cn0KMipwdCgxMy40NCw5OCxsb3dlci50YWlsID0gRikKMipwdCgtMTMuNDQsOTgpCkxNJGNvZWZmaWNpZW50c1syXQpxdCgwLjAyNSw5OCxsb3dlci50YWlsPUYpKgpTTE0kc2lnbWEvKHNxcnQoOTkqdmFyKGRhdGEkT2RvbWV0ZXIpKQopCiAgICAgCgpgYGAKCgoKCiMjIEV4YW1wbGUgMTYuNCBBcmUgT2RvbWV0ZXIgUmVhZGluZyBhbmQgUHJpY2Ugb2YgVXNlZCBUb3lvdGEgQ2FtcnlzIFJlbGF0ZWQ/CgpUZXN0IHRvIGRldGVybWluZSB3aGV0aGVyIHRoZXJlIGlzIGVub3VnaCBldmlkZW5jZSBpbiBFeGFtcGxlIDE2LjIgdG8gaW5mZXIgdGhhdCB0aGVyZSBpcyBhIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgYXVjdGlvbiBwcmljZSBhbmQgdGhlIG9kb21ldGVyIHJlYWRpbmcgZm9yIGFsbCAzLXllYXItb2xkIFRveW90YSBDYW1yeXMuIFVzZSBhIDUlIHNpZ25pZmljYW5jZSBsZXZlbC4KCk9uIHZhIHRlc3RlciBsJ2h5cHRow6hzZSAKCiQkCkhfMDpcOlxiZXRhXzE9MCBcdGV4dHsgY29udHJlIH0gSF8xOlw6XGJldGFfMVxuZXEgMC4gCiQkCk9uIHRyb3V2ZSAKYGBge3J9ClNMTSRjb2VmZmljaWVudHNbMiwxXSAjIyBiMQpTTE0kY29lZmZpY2llbnRzWzIsMl0gIyMgc19iMQp0PVNMTSRjb2VmZmljaWVudHNbMiwzXSAjIyB0ClNMTSRjb2VmZmljaWVudHNbMiw0XQoyKnB0KGFicyh0KSw5OCxsb3dlci50YWlsID0gRkFMU0UpCmBgYAoKIyMgRVhBTVBMRSAxNi4gNSBNZWFzdXJpbmcgdGhlIFN0cmVuZ3RoIG9mIHRoZSBMaW5lYXIgUmVsYXRpb25zaGlwIGJldHdlZW4gT2RvbWV0ZXIgUmVhZGluZyBhbmQgUHJpY2Ugb2YgVXNlZCBUb3lvdGEgQ2FtcnlzCkZpbmQgdGhlIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24gZm9yIEV4YW1wbGUgMTYuMiBhbmQgZGVzY3JpYmUgd2hhdCB0aGlzIHN0YXRpc3RpYyB0ZWxscyB5b3UgYWJvdXQgdGhlIHJlZ3Jlc3Npb24gbW9kZWwuCmBgYHtyfQpTTE0kci5zcXVhcmVkCihjb3IoZGF0YSRQcmljZSxkYXRhJE9kb21ldGVyKSleMgpgYGAKVGhpcyBzdGF0aXN0aWMgdGVsbHMgdXMgdGhhdCA2NC44MyUgb2YgdGhlIHZhcmlhdGlvbiBpbiB0aGUgYXVjdGlvbiBzZWxsaW5nIHByaWNlcyBpcyBleHBsYWluZWQgYnkgdGhlIHZhcmlhdGlvbiBpbiB0aGUgb2RvbWV0ZXIgcmVhZGluZ3MuCgoKYGBge3J9CkFOT1ZBPWFub3ZhKExNKQpzdW0oQU5PVkFbLDJdKQo5OSp2YXIoZGF0YSRQcmljZSkKQU5PVkFbMSwyXS8oOTkqdmFyKGRhdGEkUHJpY2UpKQoKYGBgCgojIyBFWEFNUExFIDE2LjcgUHJlZGljdGluZyB0aGUgUHJpY2UgYW5kIEVzdGltYXRpbmcgdGhlIE1lYW4gUHJpY2Ugb2YgVXNlZCBUb3lvdGEgQ2FtcnlzIAphLiBBIHVzZWQtY2FyIGRlYWxlciBpcyBhYm91dCB0byBiaWQgb24gYSAzLXllYXItb2xkIFRveW90YSBDYW1yeSBlcXVpcHBlZCB3aXRoIGFsbCB0aGUKc3RhbmRhcmQgZmVhdHVyZXMgYW5kIHdpdGggNDAsMDAwICgkeF9nJCDiq70gNDApIG1pbGVzIG9uIHRoZSBvZG9tZXRlci4gVG8gaGVscCBoaW0gZGVjaWRlIGhvdyBtdWNoIHRvIGJpZCwgaGUgbmVlZHMgdG8gcHJlZGljdCB0aGUgc2VsbGluZyBwcmljZS4KCmBgYHtyfQp4Zz1kYXRhLmZyYW1lKE9kb21ldGVyID0gYyg0MCkpCgpQUkVESUNUPXByZWRpY3QubG0oTE0seGcsaW50ZXJ2YWwgPSAicHJlZGljdGlvbiIpClNMTSRjb2VmZmljaWVudHNbLDFdJSolYygxLDQwKQo/cHJlZGljdC5sbQpQUkVESUNUWzFdLVBSRURJQ1RbMl0KCmBgYAoKCgpiLiBUaGUgdXNlZC1jYXIgZGVhbGVyIG1lbnRpb25lZCBpbiBwYXJ0IChhKSBoYXMgYW4gb3Bwb3J0dW5pdHkgdG8gYmlkIG9uIGEgbG90IG9mIGNhcnMgb2ZmZXJlZCBieSBhIHJlbnRhbCBjb21wYW55LiBUaGUgcmVudGFsIGNvbXBhbnkgaGFzIDI1MCBUb3lvdGEgQ2FtcnlzIGFsbCBlcXVpcHBlZCB3aXRoIHN0YW5kYXJkIGZlYXR1cmVzLiBBbGwgdGhlIGNhcnMgaW4gdGhpcyBsb3QgaGF2ZSBhYm91dCA0MCwwMDAgKHhnIOKrvSA0MCkgbWlsZXMgb24gdGhlaXIgb2RvbWV0ZXJzLiBUaGUgZGVhbGVyIHdvdWxkIGxpa2UgYW4gZXN0aW1hdGUgb2YgdGhlIHNlbGxpbmcgcHJpY2Ugb2YgYWxsIHRoZSBjYXJzIGluIHRoZSBsb3QuCmBgYHtyfQpQUkVESUNURVhQPXByZWRpY3QubG0oTE0seGcsaW50ZXJ2YWwgPSAiY29uZmlkZW5jZSIpClBSRURJQ1RFWFBbMV0tUFJFRElDVEVYUFsyXQpQUkVESUNURVhQWzNdLVBSRURJQ1RFWFBbMV0KCmBgYAoKCiMgQXZlYyBsZXMgbWF0cmljZXMKClNpIG9uIG5vdGUgCiQkClk9XGJlZ2lue2JtYXRyaXh9CnlfMVxcClx2ZG90c1xcCnlfbiBcXApcZW5ke2JtYXRyaXh9IFx0ZXh0eyBldCB9Clg9XGJlZ2lue2JtYXRyaXh9CjEgJiB4XzFcXApcdmRvdHMgJiBcdmRvdHMgXFwKMSAmIHhfbiBcXApcZW5ke2JtYXRyaXh9LAokJApvbiBvYnRpZW50IGxlcyBlc3RpbWF0ZXVycyBncsOiY2Ugw6AgdW4gY2xjdWwgbWF0cmljaWVsCiQkClxiZWdpbntibWF0cml4fQpiXzAgXFwKYl8xClxlbmR7Ym1hdHJpeH09CihYXnRYKV57LTF9WF50WSwKJCQKb8O5CiQkClhedD1cYmVnaW57Ym1hdHJpeH0KMSAmXGNkb3RzJiAxIFxcCjEgJiBcY2RvdHMgJnhfbiBcXApcZW5ke2JtYXRyaXh9LAokJAplc3QgbGEgbWF0cmljZSB0cmFuc3Bvc8OpZSBkZSAkWCQuCgpgYGB7cn0KWD1tYXRyaXgoYyhyZXAoMSwxMDApLGRhdGEkT2RvbWV0ZXIpLG5yb3cgPSAxMDAsbmNvbD0yKQpkaW0oWCkKWT1tYXRyaXgoZGF0YSRQcmljZSxucm93ID0gMTAwLG5jb2w9MSkKc29sdmUodChYKSUqJVgpJSoldChYKSUqJVkKClNMTSRjb2VmZmljaWVudHMKCgpgYGAKCkxhIG1hdGljZSBkZSB2YXJpYW5jZS1jb3ZhcmlhbmNlIGRlICQoYl8wLGJfMSkkIGVzdCBkb25uw6llIHBhcgoKJCQKXHNpZ21hXjIoWF50WCleey0xfS4KJCQKQ29tbWUgJFxzaWdtYV4yJCBlc3QgaW5jb21tdSwgb24gbCdlc3RpbWUgY2UgcXVpIGRvbm5lIAoKYGBge3J9CgoKU0xNJHNpZ21hCgpzcXJ0KHN1bSgoU0xNJHJlc2lkdWFscyleMikvOTgpCmBgYAoKYGBge3J9CihTTE0kc2lnbWEpXjIqc29sdmUodChYKSUqJVgpCgooU0xNJGNvZWZmaWNpZW50c1syLDJdKV4yCgp2Y292KExNKQoKYGBgCgoKIyBVbiBwZXUgZCdhbGfDqGJyZQoKT24gcmFwcGVsbGUgcXVlIGxhIG3DqXRob2RlIGRlIG1vaW5kcmVzIGNhcnLDqXMgdmEgcsOpc291ZHJlIGxlIHByb2dyYW1tZSBzdWl2YW50IAoKJCQKXG1pbl97Yl8wLGJfMX0gXHN1bSAoeV9pLVxoYXR7eV9pfSleMixcdGV4dHsgYXZlYyB9IFxoYXR7eV9pfT1iXzArYl8xIHhfaS4KJCQKClBhciBkw6lyaXZhdGlvbiBwYXIgcmFwcG9ydCDDoCAkYl8wJCBldCAkYl8xJCBvbiBvYnRpZW50IGxlcyBkZXV4IGNvbmRpdGlvbiBkdSBwcmVtaWVyIG9yZHJlIHN1aXZhbnRlcyAob24gbm90ZXJhIHF1ZSAkXHBhcnRpYWwgXGhhdHt5fV9pL1xwYXJ0aWFsIGJfMT0geF9pJCkKCgokJApcYmVnaW57ZXF1YXRpb259ClxiZWdpbntjYXNlc30KXHN1bSB4X2koeV9pLVxoYXR7eV9pfSk9MDtcXApcc3VtICh5X2ktXGhhdHt5X2l9KT0wLgpcZW5ke2Nhc2VzfQpcZW5ke2VxdWF0aW9ufQokJAoKTGEgcHJlbWnDqHJlIGNvbmRpdGlvbiB2b3VzIGRpdCBxdWUgbGVzIGVycmV1cnMgc29udCBkZSBtb3llbm5lIHplcm8gZXQgbGEgc2Vjb25kZSBxdWUgbGEgdmFyaWFibGUgZGVzIGVycmV1cnMgZXQgbGEgdmFyaWFibGVzIGV4cGxpY2F0aXZlIG5lIHNvbnQgcGFzIGNvcnLDqWzDqXMuCgpPbiBwZXV0IHLDqcOpY3JpcmUgY2VzIGRldXggY29uZGl0aW9ucyBhaW5zaQokJApcYmVnaW57ZXF1YXRpb259ClxiZWdpbntjYXNlc30KXHN1bSAoeF9pLVxiYXJ7eH0pKHlfaS1caGF0e3lfaX0pPTA7XFwKXHN1bSAoeV9pLVxoYXR7eV9pfSk9MC4KXGVuZHtjYXNlc30KXGVuZHtlcXVhdGlvbn0KJCQKCgpPbiByZW1hcnF1ZXJhIHF1ZSAkXGJhcnt5fT1cYmFye1xoYXR7eX19JC4gCgoKUG91ciBmaW5pLCBlbiByZXBsYcOnYW50ICRiXzAkIGV0ICRiXzEkIHBhciBsZXVycyB2YWxldXJzIG9wdGltYWxlcywgb24gdHJvdXZlIAoKJCQKU1NFPVxzdW0gKHlfaS1caGF0e3lfaX0pXjI9XHN1bSAoeV9pLVxiYXJ7eX0rIFxiYXJ7eX0tXGhhdHt5X2l9KV4yLAokJApjZSBxdWkgZG9ubmUKCiQkClNTRT1cc3VtIFt5X2ktXGJhcnt5fS1iXzEoeF9pLVxiYXJ7eH0pXSBeMi4KJCQKRW4gZMOpdmVsb3BwYW50LCBvbiB0cm91dmUKCiQkClNTRT1cc3VtICh5X2ktXGJhcnt5fSleMi0yYl8xXHN1bSh4X2ktXGJhcnt4fSkoeV9pLVxiYXJ7eX0pK2JeMl8xXHN1bSAoeF9pLVxiYXJ7eH0pXjIuCiQkCgpFbiByZW1hcnF1YW50IHF1ZSAKCiQkCmJeMl8xXHN1bSAoeF9pLVxiYXJ7eH0pXjI9Yl8xXHN1bSh4X2ktXGJhcnt4fSkoeV9pLVxiYXJ7eX0pLAokJApPbiBvYnRpZW50IAoKJCQKU1NFPVxzdW0gKHlfaS1cYmFye3l9KV4yLWJfMVxzdW0oeF9pLVxiYXJ7eH0pKHlfaS1cYmFye3l9KS4KJCQKCkVuIHV0aWxpc2FudCBsYSB2YWxldXIgZGUgJGJfMSQsIG9uIHRyb3V2ZSAKCiQkClNTRT1cc3VtICh5X2ktXGJhcnt5fSleMi1cZnJhY3tbIFxzdW0oeF9pLVxiYXJ7eH0pKHlfaS1cYmFye3l9KSBdXjJ9e1xzdW0gKHhfaS1cYmFye3h9KV4yfQokJAoKT24gYSBhdXNzaQoKJCQKU1NFPSgxLVJeMilcc3VtICh5X2ktXGJhcnt5fSleMi4KJCQKb8O5CiQkClJeMj1cZnJhY3tbIFxzdW0oeF9pLVxiYXJ7eH0pKHlfaS1cYmFye3l9KSBdXjJ9e1xzdW0gKHhfaS1cYmFye3h9KV4yXHN1bSAoeV9pLVxiYXJ7eX0pXjJ9PVxmcmFje3NeMl97eHl9fXtzX3t4fXNfe3l9fS4KJCQKT24gYSBhdXNzaSAKCiQkClJeMj0xLVxmcmFje1NTRSB9e1xzdW0gKHlfaS1cYmFye3l9KV4yfSwKJCQKCkVuIHJlbWFycXVhbnQgcXllIAokJApcc3VtKHlfaS1cYmFye3kgfSleMj1cc3VtKHlfaS1caGF0e3kgfV9pKV4yK1xzdW0oXGhhdHt5IH1faS1cYmFye3kgfSleMj1TU0UrXHN1bShcaGF0e3kgfV9pLVxiYXJ7eSB9KV4yLAokJApPbiBhIGF1c3NpCiQkClJeMj1cZnJhY3tcc3VtICh5X2ktXGJhcnt5fSleMi1TU0UgfXtcc3VtICh5X2ktXGJhcnt5fSleMn09XGZyYWN7XHN1bShcaGF0e3kgfV9pLVxiYXJ7eSB9KV4yIH17XHN1bSAoeV9pLVxiYXJ7eX0pXjJ9LgokJAoKJFJeMiQgZGV2aWVudGIgbGEgcGFydCBkZSB2YXJpYW5jZSBleHBsaXF1w6llIHBhciBsZSBtb2TDqGxlLg==