Raven Shan


Introduction

For this assignment, I will be utilizing a dataset retrieved from the Bristol University website, which can be accessed through this link. The study was conducted on 3,435 Scottish students who attended 148 primary schools and 19 secondary schools. The outcome variable of interest is the students’ verbal reasoning scores from tests they took upon entering secondary school.

This assignment involves examining information on 2 conceptual levels; the first level is the student or individual, and the 2nd level I selected was the primary school. To do so, I will be conducting several different regression models starting with complete-pooling and no-pooling models, then random intercept and random slope models using the lme4 package.

This assignment has two objectives. First, it seeks to examine how students’ verbal reasoning scores fluctuate as a function of their gender. In other words, what is the effect of the student’s gender on their scores? Does one gender score higher than the other? If so, to what extent? The second objective is to examine the role that the student’s primary school plays in this analysis. This will provide meaningful context as students within the same school tend to be more similar than students that are not. It is necessary to reflect this added complexity. Further in my analysis, I will also be incorporating another independent variable, social class, to my regression model to examine its impact.


Data and Variables

The variables used in this analysis are as follows:

str(studentdataset)
'data.frame':   3435 obs. of  4 variables:
 $ vr_score: num  11 0 -14 -6 -30 -17 -17 -11 -9 -19 ...
 $ primID  : num  1 1 1 1 1 1 1 1 1 1 ...
 $ sex     : int  0 1 0 0 1 1 1 0 0 0 ...
 $ class   : num  0 0 0 20 0 0 0 0 0 0 ...

Complete-Pooling Model

First, I conducted a complete-pooling model. This model is oversimplified as it treats all students and their circumstances the same, and disregards any school-level factors that may provide further insight.

This complete-pooling model estimates the effect of a student’s gender on their verbal reasoning test score. The results suggest that on average, females score higher than males by 2.55 points. Males receive an average verbal reading test score of -3.45. The relationship is statistically significant. However, as previously stated, this model is not ideal as it does not take into account important between-school differences.

cpooling <- lm(vr_score ~ sex, data = studentdataset)
summary(cpooling)

Call:
lm(formula = vr_score ~ sex, data = studentdataset)

Residuals:
    Min      1Q  Median      3Q     Max 
-29.097  -9.097  -0.097   8.903  43.456 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -3.4560     0.3173 -10.891  < 2e-16 ***
sex           2.5527     0.4516   5.652 1.71e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 13.23 on 3433 degrees of freedom
Multiple R-squared:  0.009221,  Adjusted R-squared:  0.008932 
F-statistic: 31.95 on 1 and 3433 DF,  p-value: 1.712e-08

No-Pooling Model

Next, I conducted a no-pooling model. The no-pooling model has its shortcomings as separate regression models must be conducted for each school. In this case, this would require conducting 148 different regression models (as determined by the output below), which is clearly too complicated and cumbersome. Instead, to make the process more practical, I will use some dyplr tools to plot 148 estimated intercepts and then 148 estimated slopes, which will ultimately allow me to examine the distribution of the parameters.

length(unique(studentdataset$primID))
[1] 148

Intercept

The intercept histogram below shows the average verbal reading test scores for boys in each of 148 different schools. Each school has its own unique intercept. The results range from -30 to approximately 28.

dcoef <- studentdataset %>% 
    group_by(primID) %>% 
    do(mod = lm(vr_score ~ sex, data = .))
coef <- dcoef %>% do(data.frame(intc = coef(.$mod)[1]))
ggplot(coef, aes(x = intc)) + geom_histogram()

Slope

Next, I used the slope to examine the estimated gender differences in verbal reasoning test scores among the 148 different primary schools. The results range from around -27 to 40.

dcoef <- studentdataset %>% 
    group_by(primID) %>% 
    do(mod = lm(vr_score ~ sex, data = .))
coef <- dcoef %>% do(data.frame(sexc = coef(.$mod)[2]))
ggplot(coef, aes(x = sexc)) + geom_histogram()

After examining the distribution of both the estimated intercepts and slopes, it appears to be some between-school variation that warrants further examination.


Partial-Pooling/Multilevel Modeling

It is clear that the previous approaches are not sufficient. The complete-pooling model ignores 2nd level context, while the no-pooling model requires extreme measures. Instead, the most efficient and effective method of simplifying this multilevel data for better understanding is the partial-pooling model. They key to this model is its ability to normalize a skewed distribution, making it that much easier to analyze.

Multilevel Model 1: Random Intercept Model

Here, the intercept represents the standard deviation of the (hypothetical) normal distribution. It can only be assumed that the regression intercept between the 148 schools in this dataset are normally distributed with a mean of 0 and a standard deviation of 4.14. Still, this method is insufficient as it does not allow the gender difference in verbal reasoning scores to vary between primary schools.

m1_lme <- lme4::lmer(vr_score ~ sex + (1|primID), data = studentdataset)
summary(m1_lme)
Linear mixed model fit by REML ['lmerMod']
Formula: vr_score ~ sex + (1 | primID)
   Data: studentdataset

REML criterion at convergence: 27318.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.7758 -0.6878  0.0160  0.6513  3.2733 

Random effects:
 Groups   Name        Variance Std.Dev.
 primID   (Intercept)  17.18    4.145  
 Residual             158.86   12.604  
Number of obs: 3435, groups:  primID, 148

Fixed effects:
            Estimate Std. Error t value
(Intercept)  -3.4151     0.4852  -7.039
sex           2.4311     0.4356   5.581

Correlation of Fixed Effects:
    (Intr)
sex -0.445

Multilevel Model 2: Random Slope Model

The limitation in the previous (random intercept) model was that it did not allow for gender differences to fluctuate among primary schools. To make this possible, instead, I utilized the random slope model and replaced the 1 with the variable sex. This allows me to estimate both the random intercept for each school as well as the random slope for sex differences for each school.

In the model below, I now have the standard deviation for the normal distribution for the sex slope. The first step is to examine the fixed effects in order to determine the common trend among schools. The intercept suggests that for those who came from a typical primary school, the average verbal reasoning test score for boys is -3.41. In this same typical school, girls tend to score higher by 2.42 points. Then, to determine the predicted verbal reasoning score for a particular primary school (instead of just the overall trend), I would need to evaluate not only the fixed effects, but also the random effects. The random effects produce one unique numerical value for each primary school, which can then be added to the fixed effects or common trend.

m2_lme <- lme4::lmer(vr_score ~ sex + (sex|primID), data = studentdataset)
summary(m2_lme)
Linear mixed model fit by REML ['lmerMod']
Formula: vr_score ~ sex + (sex | primID)
   Data: studentdataset

REML criterion at convergence: 27316.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.7209 -0.6960  0.0181  0.6564  3.2969 

Random effects:
 Groups   Name        Variance Std.Dev. Corr
 primID   (Intercept)  14.3734  3.7912      
          sex           0.5389  0.7341  1.00
 Residual             158.7140 12.5982      
Number of obs: 3435, groups:  primID, 148

Fixed effects:
            Estimate Std. Error t value
(Intercept)  -3.4109     0.4600  -7.415
sex           2.4275     0.4404   5.512

Correlation of Fixed Effects:
    (Intr)
sex -0.348

Multilevel Model 3: Adding another covariate

The following model incorporates the student-level independent variable, social class (“class”). The results suggests that the student’s social class has a statistically significant effect on their verbal reasoning score. In a typical school, one unit increase in social class increases the student’s score by 0.18.

m3_lme <- lme4::lmer(vr_score ~ sex + class + (sex|primID), data = studentdataset)
summary(m3_lme)
Linear mixed model fit by REML ['lmerMod']
Formula: vr_score ~ sex + class + (sex | primID)
   Data: studentdataset

REML criterion at convergence: 27239

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.6305 -0.7052  0.0000  0.6574  3.4535 

Random effects:
 Groups   Name        Variance Std.Dev. Corr
 primID   (Intercept)  11.8464  3.4419      
          sex           0.4674  0.6837  1.00
 Residual             155.6067 12.4742      
Number of obs: 3435, groups:  primID, 148

Fixed effects:
            Estimate Std. Error t value
(Intercept)  -4.7455     0.4592 -10.333
sex           2.5692     0.4355   5.899
class         0.1879     0.0203   9.253

Correlation of Fixed Effects:
      (Intr) sex   
sex   -0.369       
class -0.314  0.033

Multilevel Model 4: Incorporating an interaction term

The following model tests the interaction between sex and social class. In other words, I am testing whether sex differences in verbal reasoning scores depend on the students’ social class. The results show no statistical significance.

m4_lme <- lmer(vr_score ~ sex*class + (sex|primID), data = studentdataset)
summary(m4_lme)
Linear mixed model fit by REML t-tests use Satterthwaite approximations to
  degrees of freedom [lmerMod]
Formula: vr_score ~ sex * class + (sex | primID)
   Data: studentdataset

REML criterion at convergence: 27243.5

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.6438 -0.7071  0.0014  0.6592  3.4485 

Random effects:
 Groups   Name        Variance Std.Dev. Corr
 primID   (Intercept)  11.9412  3.4556      
          sex           0.4267  0.6533  1.00
 Residual             155.6528 12.4761      
Number of obs: 3435, groups:  primID, 148

Fixed effects:
              Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)   -4.69805    0.47891  174.00000  -9.810  < 2e-16 ***
sex            2.47238    0.51179 1891.00000   4.831 1.47e-06 ***
class          0.18124    0.02745 3166.00000   6.602 4.75e-11 ***
sex:class      0.01423    0.03959 3350.00000   0.360    0.719    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
          (Intr) sex    class 
sex       -0.451              
class     -0.409  0.375       
sex:class  0.277 -0.526 -0.673

Model Selection

Based on the AIC values, the third multilevel model proves to be the best fitting.

AIC(cpooling, m1_lme, m2_lme, m3_lme, m4_lme)
htmlreg(list(cpooling, m1_lme, m2_lme, m3_lme, m4_lme))
Statistical models
Model 1 Model 2 Model 3 Model 4 Model 5
(Intercept) -3.46*** -3.42*** -3.41*** -4.75*** -4.70***
(0.32) (0.49) (0.46) (0.46) (0.48)
sex 2.55*** 2.43*** 2.43*** 2.57*** 2.47***
(0.45) (0.44) (0.44) (0.44) (0.51)
class 0.19*** 0.18***
(0.02) (0.03)
sex:class 0.01
(0.04)
R2 0.01
Adj. R2 0.01
Num. obs. 3435 3435 3435 3435 3435
RMSE 13.23
AIC 27326.83 27328.78 27252.96 27259.45
BIC 27351.39 27365.63 27295.95 27308.59
Log Likelihood -13659.41 -13658.39 -13619.48 -13621.73
Num. groups: primID 148 148 148 148
Var: primID (Intercept) 17.18 14.37 11.85 11.94
Var: Residual 158.86 158.71 155.61 155.65
Var: primID sex 0.54 0.47 0.43
Cov: primID (Intercept) sex 2.78 2.35 2.26
p < 0.001, p < 0.01, p < 0.05

Random Effects Simulation with merTools

##estimating the model
m5_mer <- lme4::lmer(vr_score ~ sex + class + (1|primID), data = studentdataset)
fastdisp(m5_mer)
lme4::lmer(formula = vr_score ~ sex + class + (1 | primID), data = studentdataset)
            coef.est coef.se
(Intercept) -4.75     0.48  
sex          2.57     0.43  
class        0.19     0.02  

Error terms:
 Groups   Name        Std.Dev.
 primID   (Intercept)  3.77   
 Residual             12.48   
---
number of obs: 3435, groups: primID, 148
AIC = 27250.6

The following code produces a dataframe with estimates of the values of each of the random effects.

reEx <- REsim(m5_mer)
head(reEx)
p1 <- plotREsim(reEx)
p1

As the above graph depicts, there is nearly equal variation in both directions. The primary school effect ranges from about -7 to 8.


Next, I generated confidence intervals, which provides a range of values that is expected to contain the value of parameters of interest. If we compare the output below with the estimates, this is indeed the case.

confint.merMod(m5_mer,method="profile")
Computing profile confidence intervals ...
                 2.5 %     97.5 %
.sig01       3.0749544  4.5249501
.sigma      12.1807868 12.7834904
(Intercept) -5.6947345 -3.8067922
sex          1.7248589  3.4159230
class        0.1485141  0.2286467

Overall, there is not a considerably wide variation in the random effects.


Centering Covariates

In the code below, I am centering the independent variable, ‘class’, which turns the mean value to 0 (Ideally, centering variables is best for models with interaction terms). I then refit the model and create a table to compare coefficients between the first model (with the original ‘class’ variable) and the second model (with the centered ‘class’ variable).

studentdataset %<>% mutate(c_class = class - mean(class))
m3_lme2 <- lmer(vr_score ~ sex + (sex|primID) + c_class, data = studentdataset)
htmlreg(list(m3_lme, m3_lme2))
Statistical models
Model 1 Model 2
(Intercept) -4.75*** -3.46***
(0.46) (0.44)
sex 2.57*** 2.57***
(0.44) (0.44)
class 0.19***
(0.02)
c_class 0.19***
(0.02)
AIC 27252.96 27252.96
BIC 27295.95 27295.95
Log Likelihood -13619.48 -13619.48
Num. obs. 3435 3435
Num. groups: primID 148 148
Var: primID (Intercept) 11.85 11.85
Var: primID sex 0.47 0.47
Cov: primID (Intercept) sex 2.35 2.35
Var: Residual 155.61 155.61
p < 0.001, p < 0.01, p < 0.05

Based on the above table, although some coefficients differ, the AIC and BIC values are the exact same, indicating both models fit the data equally well. Essentially, the interpretation and fitness remains the same despite the covariate being centered in the latter model.


Intra-class Correlation (ICC)

The intra-class correlation (ICC) indicates how strongly the 2nd level effect is. The random effect for the intercept, 17.61, represents the amount of variation that exists at the primary school level. The residual value (160.19) represents the amount of variation at the student level.

m0_lme <-lme4::lmer(vr_score ~ 1 + (1|primID), data = studentdataset)
summary(m0_lme)
Linear mixed model fit by REML ['lmerMod']
Formula: vr_score ~ 1 + (1 | primID)
   Data: studentdataset

REML criterion at convergence: 27350

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.8374 -0.6762 -0.0034  0.6627  3.2920 

Random effects:
 Groups   Name        Variance Std.Dev.
 primID   (Intercept)  17.61    4.196  
 Residual             160.19   12.657  
Number of obs: 3435, groups:  primID, 148

Fixed effects:
            Estimate Std. Error t value
(Intercept)  -2.2113     0.4388  -5.039

The ICC is obtained by first adding the school variance and the residual variance, then dividing the school variance by the number obtained in the previous computation: 17.61/(17.61+160.19) =0.099. An ICC value of .099 suggests that nearly 10% of the variation in students’ verbal reasoning test scores can be attributed to differences between primary schools. Ultimately, while the primary school does contribute to a degree, the majority of the variation is due to individual-level differences between students.

LS0tDQp0aXRsZTogIlNvYyA3MTIgSG9tZXdvcmsgIzhiIC0gUmFuZG9tIEVmZmVjdHMgTW9kZWwvTXVsdGlsZXZlbCBNb2RlbCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoqUmF2ZW4gU2hhbioNCg0KLS0tDQoNCiMjSW50cm9kdWN0aW9uDQoNCkZvciB0aGlzIGFzc2lnbm1lbnQsIEkgd2lsbCBiZSB1dGlsaXppbmcgYSBkYXRhc2V0IHJldHJpZXZlZCBmcm9tIHRoZSBCcmlzdG9sIFVuaXZlcnNpdHkgd2Vic2l0ZSwgd2hpY2ggY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhpcyBbbGlua10od3d3LmJyaXN0b2wuYWMudWsvY21tL2xlYXJuaW5nL21tc29mdHdhcmUvZGF0YS1yZXYuaHRtbCNsZXYteGMpLiBUaGUgc3R1ZHkgd2FzIGNvbmR1Y3RlZCBvbiAzLDQzNSBTY290dGlzaCBzdHVkZW50cyB3aG8gYXR0ZW5kZWQgMTQ4IHByaW1hcnkgc2Nob29scyBhbmQgMTkgc2Vjb25kYXJ5IHNjaG9vbHMuIFRoZSBvdXRjb21lIHZhcmlhYmxlIG9mIGludGVyZXN0IGlzIHRoZSBzdHVkZW50cycgdmVyYmFsIHJlYXNvbmluZyBzY29yZXMgZnJvbSB0ZXN0cyB0aGV5IHRvb2sgdXBvbiBlbnRlcmluZyBzZWNvbmRhcnkgc2Nob29sLg0KDQpUaGlzIGFzc2lnbm1lbnQgaW52b2x2ZXMgZXhhbWluaW5nIGluZm9ybWF0aW9uIG9uIDIgY29uY2VwdHVhbCBsZXZlbHM7IHRoZSBmaXJzdCBsZXZlbCBpcyB0aGUgc3R1ZGVudCBvciBpbmRpdmlkdWFsLCBhbmQgdGhlIDJuZCBsZXZlbCBJIHNlbGVjdGVkIHdhcyB0aGUgcHJpbWFyeSBzY2hvb2wuIFRvIGRvIHNvLCBJIHdpbGwgYmUgY29uZHVjdGluZyBzZXZlcmFsIGRpZmZlcmVudCByZWdyZXNzaW9uIG1vZGVscyBzdGFydGluZyB3aXRoIGNvbXBsZXRlLXBvb2xpbmcgYW5kIG5vLXBvb2xpbmcgbW9kZWxzLCB0aGVuIHJhbmRvbSBpbnRlcmNlcHQgYW5kIHJhbmRvbSBzbG9wZSBtb2RlbHMgdXNpbmcgdGhlICpsbWU0KiBwYWNrYWdlLg0KDQpUaGlzIGFzc2lnbm1lbnQgaGFzIHR3byBvYmplY3RpdmVzLiBGaXJzdCwgaXQgc2Vla3MgdG8gZXhhbWluZSBob3cgc3R1ZGVudHMnIHZlcmJhbCByZWFzb25pbmcgc2NvcmVzIGZsdWN0dWF0ZSBhcyBhIGZ1bmN0aW9uIG9mIHRoZWlyIGdlbmRlci4gSW4gb3RoZXIgd29yZHMsIHdoYXQgaXMgdGhlIGVmZmVjdCBvZiB0aGUgc3R1ZGVudCdzIGdlbmRlciBvbiB0aGVpciBzY29yZXM/IERvZXMgb25lIGdlbmRlciBzY29yZSBoaWdoZXIgdGhhbiB0aGUgb3RoZXI/IElmIHNvLCB0byB3aGF0IGV4dGVudD8gVGhlIHNlY29uZCBvYmplY3RpdmUgaXMgdG8gZXhhbWluZSB0aGUgcm9sZSB0aGF0IHRoZSBzdHVkZW50J3MgcHJpbWFyeSBzY2hvb2wgcGxheXMgaW4gdGhpcyBhbmFseXNpcy4gVGhpcyB3aWxsIHByb3ZpZGUgbWVhbmluZ2Z1bCBjb250ZXh0IGFzIHN0dWRlbnRzIHdpdGhpbiB0aGUgc2FtZSBzY2hvb2wgdGVuZCB0byBiZSBtb3JlIHNpbWlsYXIgdGhhbiBzdHVkZW50cyB0aGF0IGFyZSBub3QuIEl0IGlzIG5lY2Vzc2FyeSB0byByZWZsZWN0IHRoaXMgYWRkZWQgY29tcGxleGl0eS4gRnVydGhlciBpbiBteSBhbmFseXNpcywgSSB3aWxsIGFsc28gYmUgaW5jb3Jwb3JhdGluZyBhbm90aGVyIGluZGVwZW5kZW50IHZhcmlhYmxlLCBzb2NpYWwgY2xhc3MsIHRvIG15IHJlZ3Jlc3Npb24gbW9kZWwgdG8gZXhhbWluZSBpdHMgaW1wYWN0LiANCg0KLS0tDQoNCiMjRGF0YSBhbmQgVmFyaWFibGVzIA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxpYnJhcnkobmxtZSkNCmxpYnJhcnkobG1lNCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoaGF2ZW4pDQpsaWJyYXJ5KGxtZXJUZXN0KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0ZXhyZWcpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KHJlYWRyKQ0KWDJsZXZfeGMgPC0gcmVhZF9jc3YoIkM6L1VzZXJzL1JhdmVuL0Rlc2t0b3AvZGF0YXNldHMvMmxldi14Yy50eHQiKQ0KYGBgDQoNCmBgYHtyLGVjaG89RkFMU0V9DQpkYXRhc2V0PC1yZWFkLnRhYmxlKCJDOi9Vc2Vycy9SYXZlbi9EZXNrdG9wL2RhdGFzZXRzLzJsZXYteGMudHh0IikNCm5hbWVzKGRhdGFzZXQpDQpgYGANCg0KYGBge3IsZWNobz1GQUxTRX0NCnN0dWRlbnRkYXRhc2V0IDwtIHJlbmFtZShkYXRhc2V0LCAidnJfc2NvcmUiID0gVjEsICJwcmltSUQiID0gVjMsICJzZXgiID0gVjQsICJjbGFzcyIgPSBWNSkNCnN0dWRlbnRkYXRhc2V0JHNleCA8LSBhcy5pbnRlZ2VyKHN0dWRlbnRkYXRhc2V0JHNleCkNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnN0dWRlbnRkYXRhc2V0PC0gc2VsZWN0KHN0dWRlbnRkYXRhc2V0LCB2cl9zY29yZSwgcHJpbUlELCBzZXgsIGNsYXNzKQ0KYGBgDQoNClRoZSB2YXJpYWJsZXMgdXNlZCBpbiB0aGlzIGFuYWx5c2lzIGFyZSBhcyBmb2xsb3dzOg0KDQoqICoqdnJfc2NvcmUqKjogVGhpcyB2YXJpYWJsZSBzZXJ2ZXMgYXMgdGhlIG91dGNvbWUgdmFyaWFibGUgb2YgaW50ZXJlc3QuIEl0IGNvbnRhaW5zIGVhY2ggc3R1ZGVudCdzIHZlcmJhbCByZWFzb25pbmcgdGVzdCBzY29yZS4NCiogKipwcmltSUQqKjogVGhlIHByaW1hcnkgc2Nob29sIGlkZW50aWZ5aW5nIGNvZGUNCiogKipzZXgqKjogVGhpcyBiaW5hcnkgdmFyaWFibGUgcmVwcmVzZW50cyB0aGUgc3R1ZGVudHMgc2V4ICgwID0gbWFsZSwgMSA9IGZlbWFsZSkuDQoqICoqY2xhc3MqKjogVGhpcyB2YXJpYWJsZSBtZWFzdXJlcyB0aGUgc3R1ZGVudHMnIHNvY2lhbCBjbGFzcyB1c2luZyBhIGNvbnRpbnVvdXMgc2NhbGUgc2NvcmUgKGZyb20gbG93IHRvIGhpZ2ggc29jaWFsIGNsYXNzKS4gDQoNCmBgYHtyfQ0Kc3RyKHN0dWRlbnRkYXRhc2V0KQ0KYGBgDQoNCi0tLQ0KDQojI0NvbXBsZXRlLVBvb2xpbmcgTW9kZWwNCg0KRmlyc3QsIEkgY29uZHVjdGVkIGEgY29tcGxldGUtcG9vbGluZyBtb2RlbC4gVGhpcyBtb2RlbCBpcyBvdmVyc2ltcGxpZmllZCBhcyBpdCB0cmVhdHMgYWxsIHN0dWRlbnRzIGFuZCB0aGVpciBjaXJjdW1zdGFuY2VzIHRoZSBzYW1lLCBhbmQgZGlzcmVnYXJkcyBhbnkgc2Nob29sLWxldmVsIGZhY3RvcnMgdGhhdCBtYXkgcHJvdmlkZSBmdXJ0aGVyIGluc2lnaHQuDQoNClRoaXMgY29tcGxldGUtcG9vbGluZyBtb2RlbCBlc3RpbWF0ZXMgdGhlIGVmZmVjdCBvZiBhIHN0dWRlbnQncyBnZW5kZXIgb24gdGhlaXIgdmVyYmFsIHJlYXNvbmluZyB0ZXN0IHNjb3JlLiBUaGUgcmVzdWx0cyBzdWdnZXN0IHRoYXQgb24gYXZlcmFnZSwgZmVtYWxlcyBzY29yZSBoaWdoZXIgdGhhbiBtYWxlcyBieSAyLjU1IHBvaW50cy4gTWFsZXMgcmVjZWl2ZSBhbiBhdmVyYWdlIHZlcmJhbCByZWFkaW5nIHRlc3Qgc2NvcmUgb2YgLTMuNDUuIFRoZSByZWxhdGlvbnNoaXAgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gSG93ZXZlciwgYXMgcHJldmlvdXNseSBzdGF0ZWQsIHRoaXMgbW9kZWwgaXMgbm90IGlkZWFsIGFzIGl0IGRvZXMgbm90IHRha2UgaW50byBhY2NvdW50IGltcG9ydGFudCBiZXR3ZWVuLXNjaG9vbCBkaWZmZXJlbmNlcy4NCmBgYHtyfQ0KY3Bvb2xpbmcgPC0gbG0odnJfc2NvcmUgfiBzZXgsIGRhdGEgPSBzdHVkZW50ZGF0YXNldCkNCnN1bW1hcnkoY3Bvb2xpbmcpDQpgYGANCg0KLS0tDQoNCiMjTm8tUG9vbGluZyBNb2RlbA0KDQpOZXh0LCBJIGNvbmR1Y3RlZCBhIG5vLXBvb2xpbmcgbW9kZWwuIFRoZSBuby1wb29saW5nIG1vZGVsIGhhcyBpdHMgc2hvcnRjb21pbmdzIGFzIHNlcGFyYXRlIHJlZ3Jlc3Npb24gbW9kZWxzIG11c3QgYmUgY29uZHVjdGVkIGZvciBlYWNoIHNjaG9vbC4gSW4gdGhpcyBjYXNlLCB0aGlzIHdvdWxkIHJlcXVpcmUgY29uZHVjdGluZyAxNDggZGlmZmVyZW50IHJlZ3Jlc3Npb24gbW9kZWxzIChhcyBkZXRlcm1pbmVkIGJ5IHRoZSBvdXRwdXQgYmVsb3cpLCB3aGljaCBpcyBjbGVhcmx5IHRvbyBjb21wbGljYXRlZCBhbmQgY3VtYmVyc29tZS4gSW5zdGVhZCwgdG8gbWFrZSB0aGUgcHJvY2VzcyBtb3JlIHByYWN0aWNhbCwgSSB3aWxsIHVzZSBzb21lIGR5cGxyIHRvb2xzIHRvIHBsb3QgMTQ4IGVzdGltYXRlZCBpbnRlcmNlcHRzIGFuZCB0aGVuIDE0OCBlc3RpbWF0ZWQgc2xvcGVzLCB3aGljaCB3aWxsIHVsdGltYXRlbHkgYWxsb3cgbWUgdG8gZXhhbWluZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBwYXJhbWV0ZXJzLiANCg0KYGBge3J9DQpsZW5ndGgodW5pcXVlKHN0dWRlbnRkYXRhc2V0JHByaW1JRCkpDQpgYGANCg0KIyMjSW50ZXJjZXB0DQoNClRoZSBpbnRlcmNlcHQgaGlzdG9ncmFtIGJlbG93IHNob3dzIHRoZSBhdmVyYWdlIHZlcmJhbCByZWFkaW5nIHRlc3Qgc2NvcmVzIGZvciBib3lzIGluIGVhY2ggb2YgMTQ4IGRpZmZlcmVudCBzY2hvb2xzLiBFYWNoIHNjaG9vbCBoYXMgaXRzIG93biB1bmlxdWUgaW50ZXJjZXB0LiBUaGUgcmVzdWx0cyByYW5nZSBmcm9tIC0zMCB0byBhcHByb3hpbWF0ZWx5IDI4Lg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCmBgYA0KDQoNCmBgYHtyfQ0KZGNvZWYgPC0gc3R1ZGVudGRhdGFzZXQgJT4lIA0KICAgIGdyb3VwX2J5KHByaW1JRCkgJT4lIA0KICAgIGRvKG1vZCA9IGxtKHZyX3Njb3JlIH4gc2V4LCBkYXRhID0gLikpDQpjb2VmIDwtIGRjb2VmICU+JSBkbyhkYXRhLmZyYW1lKGludGMgPSBjb2VmKC4kbW9kKVsxXSkpDQpnZ3Bsb3QoY29lZiwgYWVzKHggPSBpbnRjKSkgKyBnZW9tX2hpc3RvZ3JhbSgpDQpgYGANCg0KIyMjU2xvcGUNCg0KTmV4dCwgSSB1c2VkIHRoZSBzbG9wZSB0byBleGFtaW5lIHRoZSBlc3RpbWF0ZWQgZ2VuZGVyIGRpZmZlcmVuY2VzIGluIHZlcmJhbCByZWFzb25pbmcgdGVzdCBzY29yZXMgYW1vbmcgdGhlIDE0OCBkaWZmZXJlbnQgcHJpbWFyeSBzY2hvb2xzLiBUaGUgcmVzdWx0cyByYW5nZSBmcm9tIGFyb3VuZCAtMjcgdG8gNDAuDQpgYGB7cn0NCmRjb2VmIDwtIHN0dWRlbnRkYXRhc2V0ICU+JSANCiAgICBncm91cF9ieShwcmltSUQpICU+JSANCiAgICBkbyhtb2QgPSBsbSh2cl9zY29yZSB+IHNleCwgZGF0YSA9IC4pKQ0KY29lZiA8LSBkY29lZiAlPiUgZG8oZGF0YS5mcmFtZShzZXhjID0gY29lZiguJG1vZClbMl0pKQ0KZ2dwbG90KGNvZWYsIGFlcyh4ID0gc2V4YykpICsgZ2VvbV9oaXN0b2dyYW0oKQ0KYGBgDQoNCkFmdGVyIGV4YW1pbmluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIGJvdGggdGhlIGVzdGltYXRlZCBpbnRlcmNlcHRzIGFuZCBzbG9wZXMsIGl0IGFwcGVhcnMgdG8gYmUgc29tZSBiZXR3ZWVuLXNjaG9vbCB2YXJpYXRpb24gdGhhdCB3YXJyYW50cyBmdXJ0aGVyIGV4YW1pbmF0aW9uLiAgDQoNCi0tLQ0KDQojI1BhcnRpYWwtUG9vbGluZy9NdWx0aWxldmVsIE1vZGVsaW5nDQoNCkl0IGlzIGNsZWFyIHRoYXQgdGhlIHByZXZpb3VzIGFwcHJvYWNoZXMgYXJlIG5vdCBzdWZmaWNpZW50LiBUaGUgY29tcGxldGUtcG9vbGluZyBtb2RlbCBpZ25vcmVzIDJuZCBsZXZlbCBjb250ZXh0LCB3aGlsZSB0aGUgbm8tcG9vbGluZyBtb2RlbCByZXF1aXJlcyBleHRyZW1lIG1lYXN1cmVzLiBJbnN0ZWFkLCB0aGUgbW9zdCBlZmZpY2llbnQgYW5kIGVmZmVjdGl2ZSBtZXRob2Qgb2Ygc2ltcGxpZnlpbmcgdGhpcyBtdWx0aWxldmVsIGRhdGEgZm9yIGJldHRlciB1bmRlcnN0YW5kaW5nIGlzIHRoZSBwYXJ0aWFsLXBvb2xpbmcgbW9kZWwuIFRoZXkga2V5IHRvIHRoaXMgbW9kZWwgaXMgaXRzIGFiaWxpdHkgdG8gbm9ybWFsaXplIGEgc2tld2VkIGRpc3RyaWJ1dGlvbiwgbWFraW5nIGl0IHRoYXQgbXVjaCBlYXNpZXIgdG8gYW5hbHl6ZS4gDQoNCiMjI011bHRpbGV2ZWwgTW9kZWwgMTogUmFuZG9tIEludGVyY2VwdCBNb2RlbA0KDQpIZXJlLCB0aGUgaW50ZXJjZXB0IHJlcHJlc2VudHMgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgKGh5cG90aGV0aWNhbCkgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gSXQgY2FuIG9ubHkgYmUgYXNzdW1lZCB0aGF0IHRoZSByZWdyZXNzaW9uIGludGVyY2VwdCBiZXR3ZWVuIHRoZSAxNDggc2Nob29scyBpbiB0aGlzIGRhdGFzZXQgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHdpdGggYSBtZWFuIG9mIDAgYW5kIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDQuMTQuIFN0aWxsLCB0aGlzIG1ldGhvZCBpcyBpbnN1ZmZpY2llbnQgYXMgaXQgZG9lcyBub3QgYWxsb3cgdGhlIGdlbmRlciBkaWZmZXJlbmNlIGluIHZlcmJhbCByZWFzb25pbmcgc2NvcmVzIHRvIHZhcnkgYmV0d2VlbiBwcmltYXJ5IHNjaG9vbHMuDQoNCmBgYHtyfQ0KbTFfbG1lIDwtIGxtZTQ6OmxtZXIodnJfc2NvcmUgfiBzZXggKyAoMXxwcmltSUQpLCBkYXRhID0gc3R1ZGVudGRhdGFzZXQpDQpzdW1tYXJ5KG0xX2xtZSkNCmBgYA0KDQotLS0NCg0KIyMjIE11bHRpbGV2ZWwgTW9kZWwgMjogUmFuZG9tIFNsb3BlIE1vZGVsDQoNClRoZSBsaW1pdGF0aW9uIGluIHRoZSBwcmV2aW91cyAocmFuZG9tIGludGVyY2VwdCkgbW9kZWwgd2FzIHRoYXQgaXQgZGlkIG5vdCBhbGxvdyBmb3IgZ2VuZGVyIGRpZmZlcmVuY2VzIHRvIGZsdWN0dWF0ZSBhbW9uZyBwcmltYXJ5IHNjaG9vbHMuIFRvIG1ha2UgdGhpcyBwb3NzaWJsZSwgaW5zdGVhZCwgSSB1dGlsaXplZCB0aGUgcmFuZG9tIHNsb3BlIG1vZGVsIGFuZCByZXBsYWNlZCB0aGUgMSB3aXRoIHRoZSB2YXJpYWJsZSBzZXguIFRoaXMgYWxsb3dzIG1lIHRvIGVzdGltYXRlICpib3RoKiB0aGUgcmFuZG9tIGludGVyY2VwdCBmb3IgZWFjaCBzY2hvb2wgYXMgd2VsbCBhcyB0aGUgcmFuZG9tIHNsb3BlIGZvciBzZXggZGlmZmVyZW5jZXMgZm9yIGVhY2ggc2Nob29sLiANCg0KSW4gdGhlIG1vZGVsIGJlbG93LCBJIG5vdyBoYXZlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gZm9yIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGZvciB0aGUgc2V4IHNsb3BlLiBUaGUgZmlyc3Qgc3RlcCBpcyB0byBleGFtaW5lIHRoZSBmaXhlZCBlZmZlY3RzIGluIG9yZGVyIHRvIGRldGVybWluZSB0aGUgY29tbW9uIHRyZW5kIGFtb25nIHNjaG9vbHMuIFRoZSBpbnRlcmNlcHQgc3VnZ2VzdHMgdGhhdCBmb3IgdGhvc2Ugd2hvIGNhbWUgZnJvbSBhIHR5cGljYWwgcHJpbWFyeSBzY2hvb2wsIHRoZSBhdmVyYWdlIHZlcmJhbCByZWFzb25pbmcgdGVzdCBzY29yZSBmb3IgYm95cyBpcyAtMy40MS4gSW4gdGhpcyBzYW1lIHR5cGljYWwgc2Nob29sLCBnaXJscyB0ZW5kIHRvIHNjb3JlIGhpZ2hlciBieSAyLjQyIHBvaW50cy4gVGhlbiwgdG8gZGV0ZXJtaW5lIHRoZSBwcmVkaWN0ZWQgdmVyYmFsIHJlYXNvbmluZyBzY29yZSBmb3IgYSBwYXJ0aWN1bGFyIHByaW1hcnkgc2Nob29sIChpbnN0ZWFkIG9mIGp1c3QgdGhlIG92ZXJhbGwgdHJlbmQpLCBJIHdvdWxkIG5lZWQgdG8gZXZhbHVhdGUgbm90IG9ubHkgdGhlIGZpeGVkIGVmZmVjdHMsIGJ1dCBhbHNvIHRoZSByYW5kb20gZWZmZWN0cy4gVGhlIHJhbmRvbSBlZmZlY3RzIHByb2R1Y2Ugb25lIHVuaXF1ZSBudW1lcmljYWwgdmFsdWUgZm9yIGVhY2ggcHJpbWFyeSBzY2hvb2wsIHdoaWNoIGNhbiB0aGVuIGJlIGFkZGVkIHRvIHRoZSBmaXhlZCBlZmZlY3RzIG9yIGNvbW1vbiB0cmVuZC4gDQoNCmBgYHtyfQ0KbTJfbG1lIDwtIGxtZTQ6OmxtZXIodnJfc2NvcmUgfiBzZXggKyAoc2V4fHByaW1JRCksIGRhdGEgPSBzdHVkZW50ZGF0YXNldCkNCnN1bW1hcnkobTJfbG1lKQ0KYGBgDQoNCi0tLQ0KDQojIyNNdWx0aWxldmVsIE1vZGVsIDM6IEFkZGluZyBhbm90aGVyIGNvdmFyaWF0ZQ0KDQpUaGUgZm9sbG93aW5nIG1vZGVsIGluY29ycG9yYXRlcyB0aGUgc3R1ZGVudC1sZXZlbCBpbmRlcGVuZGVudCB2YXJpYWJsZSwgc29jaWFsIGNsYXNzICgiY2xhc3MiKS4gVGhlIHJlc3VsdHMgc3VnZ2VzdHMgdGhhdCB0aGUgc3R1ZGVudCdzIHNvY2lhbCBjbGFzcyBoYXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGVmZmVjdCBvbiB0aGVpciB2ZXJiYWwgcmVhc29uaW5nIHNjb3JlLiBJbiBhIHR5cGljYWwgc2Nob29sLCBvbmUgdW5pdCBpbmNyZWFzZSBpbiBzb2NpYWwgY2xhc3MgaW5jcmVhc2VzIHRoZSBzdHVkZW50J3Mgc2NvcmUgYnkgMC4xOC4NCmBgYHtyfQ0KbTNfbG1lIDwtIGxtZTQ6OmxtZXIodnJfc2NvcmUgfiBzZXggKyBjbGFzcyArIChzZXh8cHJpbUlEKSwgZGF0YSA9IHN0dWRlbnRkYXRhc2V0KQ0Kc3VtbWFyeShtM19sbWUpDQpgYGANCg0KLS0tDQoNCiMjI011bHRpbGV2ZWwgTW9kZWwgNDogSW5jb3Jwb3JhdGluZyBhbiBpbnRlcmFjdGlvbiB0ZXJtDQoNClRoZSBmb2xsb3dpbmcgbW9kZWwgdGVzdHMgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gc2V4IGFuZCBzb2NpYWwgY2xhc3MuIEluIG90aGVyIHdvcmRzLCBJIGFtIHRlc3Rpbmcgd2hldGhlciBzZXggZGlmZmVyZW5jZXMgaW4gdmVyYmFsIHJlYXNvbmluZyBzY29yZXMgZGVwZW5kIG9uIHRoZSBzdHVkZW50cycgc29jaWFsIGNsYXNzLiBUaGUgcmVzdWx0cyBzaG93IG5vIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZS4gDQoNCmBgYHtyfQ0KbTRfbG1lIDwtIGxtZXIodnJfc2NvcmUgfiBzZXgqY2xhc3MgKyAoc2V4fHByaW1JRCksIGRhdGEgPSBzdHVkZW50ZGF0YXNldCkNCnN1bW1hcnkobTRfbG1lKQ0KYGBgDQoNCi0tLQ0KDQojI01vZGVsIFNlbGVjdGlvbg0KDQpCYXNlZCBvbiB0aGUgQUlDIHZhbHVlcywgdGhlIHRoaXJkIG11bHRpbGV2ZWwgbW9kZWwgcHJvdmVzIHRvIGJlIHRoZSBiZXN0IGZpdHRpbmcuDQpgYGB7cn0NCkFJQyhjcG9vbGluZywgbTFfbG1lLCBtMl9sbWUsIG0zX2xtZSwgbTRfbG1lKQ0KYGBgDQoNCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQ0KaHRtbHJlZyhsaXN0KGNwb29saW5nLCBtMV9sbWUsIG0yX2xtZSwgbTNfbG1lLCBtNF9sbWUpKQ0KYGBgDQoNCi0tLQ0KDQojIyBSYW5kb20gRWZmZWN0cyBTaW11bGF0aW9uIHdpdGggbWVyVG9vbHMgIA0KDQpgYGB7cn0NCiMjZXN0aW1hdGluZyB0aGUgbW9kZWwNCm01X21lciA8LSBsbWU0OjpsbWVyKHZyX3Njb3JlIH4gc2V4ICsgY2xhc3MgKyAoMXxwcmltSUQpLCBkYXRhID0gc3R1ZGVudGRhdGFzZXQpDQpmYXN0ZGlzcChtNV9tZXIpDQpgYGANCg0KVGhlIGZvbGxvd2luZyBjb2RlIHByb2R1Y2VzIGEgZGF0YWZyYW1lIHdpdGggZXN0aW1hdGVzIG9mIHRoZSB2YWx1ZXMgb2YgZWFjaCBvZiB0aGUgcmFuZG9tIGVmZmVjdHMuDQpgYGB7cn0NCnJlRXggPC0gUkVzaW0obTVfbWVyKQ0KaGVhZChyZUV4KQ0KYGBgDQoNCmBgYHtyfQ0KIyNwbG90dGluZyB0aGUgcmFuZG9tIGVmZmVjdHMNCnAxIDwtIHBsb3RSRXNpbShyZUV4KQ0KcDENCmBgYA0KDQpBcyB0aGUgYWJvdmUgZ3JhcGggZGVwaWN0cywgdGhlcmUgaXMgbmVhcmx5IGVxdWFsIHZhcmlhdGlvbiBpbiBib3RoIGRpcmVjdGlvbnMuIFRoZSBwcmltYXJ5IHNjaG9vbCBlZmZlY3QgcmFuZ2VzIGZyb20gYWJvdXQgLTcgdG8gOC4gDQoNCi0tLQ0KDQpOZXh0LCBJIGdlbmVyYXRlZCBjb25maWRlbmNlIGludGVydmFscywgd2hpY2ggcHJvdmlkZXMgYSByYW5nZSBvZiB2YWx1ZXMgdGhhdCBpcyBleHBlY3RlZCB0byBjb250YWluIHRoZSB2YWx1ZSBvZiBwYXJhbWV0ZXJzIG9mIGludGVyZXN0LiBJZiB3ZSBjb21wYXJlIHRoZSBvdXRwdXQgYmVsb3cgd2l0aCB0aGUgZXN0aW1hdGVzLCB0aGlzIGlzIGluZGVlZCB0aGUgY2FzZS4NCg0KYGBge3J9DQpjb25maW50Lm1lck1vZChtNV9tZXIsbWV0aG9kPSJwcm9maWxlIikNCmBgYA0KDQpPdmVyYWxsLCB0aGVyZSBpcyBub3QgYSBjb25zaWRlcmFibHkgd2lkZSB2YXJpYXRpb24gaW4gdGhlIHJhbmRvbSBlZmZlY3RzLiANCg0KLS0tDQoNCiMjQ2VudGVyaW5nIENvdmFyaWF0ZXMNCg0KSW4gdGhlIGNvZGUgYmVsb3csIEkgYW0gY2VudGVyaW5nIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZSwgJ2NsYXNzJywgd2hpY2ggdHVybnMgdGhlIG1lYW4gdmFsdWUgdG8gMCAoSWRlYWxseSwgY2VudGVyaW5nIHZhcmlhYmxlcyBpcyBiZXN0IGZvciBtb2RlbHMgd2l0aCBpbnRlcmFjdGlvbiB0ZXJtcykuIEkgdGhlbiByZWZpdCB0aGUgbW9kZWwgYW5kIGNyZWF0ZSBhIHRhYmxlIHRvIGNvbXBhcmUgY29lZmZpY2llbnRzIGJldHdlZW4gdGhlIGZpcnN0IG1vZGVsICh3aXRoIHRoZSBvcmlnaW5hbCAnY2xhc3MnIHZhcmlhYmxlKSBhbmQgdGhlIHNlY29uZCBtb2RlbCAod2l0aCB0aGUgY2VudGVyZWQgJ2NsYXNzJyB2YXJpYWJsZSkuIA0KYGBge3J9DQpzdHVkZW50ZGF0YXNldCAlPD4lIG11dGF0ZShjX2NsYXNzID0gY2xhc3MgLSBtZWFuKGNsYXNzKSkNCmBgYA0KDQoNCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQ0KbTNfbG1lMiA8LSBsbWVyKHZyX3Njb3JlIH4gc2V4ICsgKHNleHxwcmltSUQpICsgY19jbGFzcywgZGF0YSA9IHN0dWRlbnRkYXRhc2V0KQ0KaHRtbHJlZyhsaXN0KG0zX2xtZSwgbTNfbG1lMikpDQpgYGANCg0KQmFzZWQgb24gdGhlIGFib3ZlIHRhYmxlLCBhbHRob3VnaCBzb21lIGNvZWZmaWNpZW50cyBkaWZmZXIsIHRoZSBBSUMgYW5kIEJJQyB2YWx1ZXMgYXJlIHRoZSBleGFjdCBzYW1lLCBpbmRpY2F0aW5nIGJvdGggbW9kZWxzIGZpdCB0aGUgZGF0YSBlcXVhbGx5IHdlbGwuIEVzc2VudGlhbGx5LCB0aGUgaW50ZXJwcmV0YXRpb24gYW5kIGZpdG5lc3MgcmVtYWlucyB0aGUgc2FtZSBkZXNwaXRlIHRoZSBjb3ZhcmlhdGUgYmVpbmcgY2VudGVyZWQgaW4gdGhlIGxhdHRlciBtb2RlbC4gIA0KDQotLS0NCg0KIyNJbnRyYS1jbGFzcyBDb3JyZWxhdGlvbiAoSUNDKQ0KDQpUaGUgaW50cmEtY2xhc3MgY29ycmVsYXRpb24gKElDQykgaW5kaWNhdGVzIGhvdyBzdHJvbmdseSB0aGUgMm5kIGxldmVsIGVmZmVjdCBpcy4gVGhlIHJhbmRvbSBlZmZlY3QgZm9yIHRoZSBpbnRlcmNlcHQsIDE3LjYxLCByZXByZXNlbnRzIHRoZSBhbW91bnQgb2YgdmFyaWF0aW9uIHRoYXQgZXhpc3RzIGF0IHRoZSBwcmltYXJ5IHNjaG9vbCBsZXZlbC4gVGhlIHJlc2lkdWFsIHZhbHVlICgxNjAuMTkpIHJlcHJlc2VudHMgdGhlIGFtb3VudCBvZiB2YXJpYXRpb24gYXQgdGhlIHN0dWRlbnQgbGV2ZWwuIA0KDQpgYGB7cn0NCm0wX2xtZSA8LWxtZTQ6OmxtZXIodnJfc2NvcmUgfiAxICsgKDF8cHJpbUlEKSwgZGF0YSA9IHN0dWRlbnRkYXRhc2V0KQ0Kc3VtbWFyeShtMF9sbWUpDQpgYGANCg0KVGhlIElDQyBpcyBvYnRhaW5lZCBieSBmaXJzdCBhZGRpbmcgdGhlIHNjaG9vbCB2YXJpYW5jZSBhbmQgdGhlIHJlc2lkdWFsIHZhcmlhbmNlLCB0aGVuIGRpdmlkaW5nIHRoZSBzY2hvb2wgdmFyaWFuY2UgYnkgdGhlIG51bWJlciBvYnRhaW5lZCBpbiB0aGUgcHJldmlvdXMgY29tcHV0YXRpb246IDE3LjYxLygxNy42MSsxNjAuMTkpID0qKjAuMDk5KiouIEFuIElDQyB2YWx1ZSBvZiAuMDk5IHN1Z2dlc3RzIHRoYXQgbmVhcmx5IDEwJSAgb2YgdGhlIHZhcmlhdGlvbiBpbiBzdHVkZW50cycgdmVyYmFsIHJlYXNvbmluZyB0ZXN0IHNjb3JlcyBjYW4gYmUgYXR0cmlidXRlZCB0byBkaWZmZXJlbmNlcyBiZXR3ZWVuIHByaW1hcnkgc2Nob29scy4gVWx0aW1hdGVseSwgd2hpbGUgdGhlIHByaW1hcnkgc2Nob29sIGRvZXMgY29udHJpYnV0ZSB0byBhIGRlZ3JlZSwgdGhlIG1ham9yaXR5IG9mIHRoZSB2YXJpYXRpb24gaXMgZHVlIHRvIGluZGl2aWR1YWwtbGV2ZWwgZGlmZmVyZW5jZXMgYmV0d2VlbiBzdHVkZW50cy4NCg0K