Random intercepts model

Following up from what we were doing in practical 1, we’ll continue building up our multilevel model for school effects.


Task 1: Value-added model

Fit a model with “prior attainment” as the only covariate. According to the literature this is a “type AA” value-added model. According to the DfE, this is a school value-added model or “VA”

m1 <-lmer(ks4stand ~ ks2stand + (1|schoolID), data = valueadded, REML = F)
summary(m1)
## Linear mixed model fit by maximum likelihood  ['lmerMod']
## Formula: ks4stand ~ ks2stand + (1 | schoolID)
##    Data: valueadded
## 
##      AIC      BIC   logLik deviance df.resid 
##  94184.3  94214.5 -47088.2  94176.3    14048 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -4.8324 -0.5431  0.0227  0.5858  4.6552 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  schoolID (Intercept)  8.884   2.981   
##  Residual             44.207   6.649   
## Number of obs: 14052, groups:  schoolID, 628
## 
## Fixed effects:
##              Estimate Std. Error t value
## (Intercept) -0.110626   0.132210  -0.837
## ks2stand     0.644306   0.006298 102.298
## 
## Correlation of Fixed Effects:
##          (Intr)
## ks2stand 0.006

Question:

1.1. What is the effect of by prior attainment?

Answer: The estimate of 0.64 means that a one unit increase in the standard deviation of KS2, we can expect a 0.64 standard deviations increase in GCSE scores.



Task 2: Contextualised value-added model

Fit a model with all the available level 1 variables. In the literature, this model is called “type AA” value-added. The DfE would this model a “contextualised value-added model” or “CVA”.

m2 <- lmer(ks4stand ~ ks2stand + factor(gender) + factor(fsm) + (1|schoolID), data = valueadded, REML = F)
summary(m2)
## Linear mixed model fit by maximum likelihood  ['lmerMod']
## Formula: ks4stand ~ ks2stand + factor(gender) + factor(fsm) + (1 | schoolID)
##    Data: valueadded
## 
##      AIC      BIC   logLik deviance df.resid 
##  91571.5  91616.7 -45779.8  91559.5    13740 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.0675 -0.5341  0.0103  0.5770  4.8736 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  schoolID (Intercept)  8.984   2.997   
##  Residual             42.304   6.504   
## Number of obs: 13746, groups:  schoolID, 628
## 
## Fixed effects:
##                  Estimate Std. Error t value
## (Intercept)     -0.547500   0.148461  -3.688
## ks2stand         0.622985   0.006357  98.005
## factor(gender)1  1.911990   0.118926  16.077
## factor(fsm)1    -2.271849   0.157245 -14.448
## 
## Correlation of Fixed Effects:
##             (Intr) ks2stn fctr(g)1
## ks2stand    -0.023                
## fctr(gndr)1 -0.394 -0.033         
## factr(fsm)1 -0.215  0.183 -0.005

Questions

2.1. How much have the variances (at both levels) reduced?

Answer: The variance at the school level has not reduced, but increased ever so slightly. This is not uncommon. In practice, this means that even after controlling for sex and deprivation, there is a non-negligible remainder of variance at the school level that is not explained by the variables in our model.

On the other hand, the variance at the pupil level has reduced from 44.207 to 42.304 (from the VA model to the CVA model)

\[\frac{(44.207-42.304)}{44.207} = 0.043 \]

That reduction is the variance that is accounted for by differences in sex and FSM eligibility. These two variables explain 4.3% of the variance remaining after controlling for prior attainment.

2.2. What does this mean for the concept of value-added?

Answer: Prior attainment is not the only relevant factor when it comes to school attainment, contextual characteristics are indeed relevant and must be controlled for.



Task 3: Differential progress - Interaction effects

Question:

3.1. Do male and female pupils have different levels of progress?

m3 <- lmer(ks4stand ~ ks2stand + ks2stand*factor(gender) + factor(gender)+
           factor(fsm) + (1|schoolID), data = valueadded, REML = F)

summary(m3)
## Linear mixed model fit by maximum likelihood  ['lmerMod']
## Formula: ks4stand ~ ks2stand + ks2stand * factor(gender) + factor(gender) +  
##     factor(fsm) + (1 | schoolID)
##    Data: valueadded
## 
##      AIC      BIC   logLik deviance df.resid 
##  91571.8  91624.5 -45778.9  91557.8    13739 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.0469 -0.5340  0.0103  0.5770  4.8719 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  schoolID (Intercept)  8.976   2.996   
##  Residual             42.300   6.504   
## Number of obs: 13746, groups:  schoolID, 628
## 
## Fixed effects:
##                           Estimate Std. Error t value
## (Intercept)              -0.544662   0.148432  -3.669
## ks2stand                  0.630388   0.008533  73.874
## factor(gender)1           1.911635   0.118920  16.075
## factor(fsm)1             -2.272931   0.157238 -14.455
## ks2stand:factor(gender)1 -0.015305   0.011776  -1.300
## 
## Correlation of Fixed Effects:
##             (Intr) ks2stn fctr(g)1 fctr(f)1
## ks2stand    -0.008                         
## fctr(gndr)1 -0.394 -0.026                  
## factr(fsm)1 -0.215  0.133 -0.005           
## ks2stnd:()1 -0.015 -0.667  0.002    0.005

Answer: Judging by the interaction effect between sex and prior attainment, there is not enough evidence to conclude that female pupils (gender = 1) more or less progress than male pupils (gender = 0) at the same level of prior attainment.

3.2. Do FSM eligible pupils make more or less progress?

m4 <- lmer(ks4stand ~ ks2stand + ks2stand*factor(fsm) + factor(gender)+
           factor(fsm) + (1|schoolID), data = valueadded, REML = F)

summary(m4)
## Linear mixed model fit by maximum likelihood  ['lmerMod']
## Formula: ks4stand ~ ks2stand + ks2stand * factor(fsm) + factor(gender) +  
##     factor(fsm) + (1 | schoolID)
##    Data: valueadded
## 
##      AIC      BIC   logLik deviance df.resid 
##  91556.1  91608.8 -45771.0  91542.1    13739 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.0963 -0.5351  0.0088  0.5752  4.8744 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  schoolID (Intercept)  8.962   2.994   
##  Residual             42.253   6.500   
## Number of obs: 13746, groups:  schoolID, 628
## 
## Fixed effects:
##                       Estimate Std. Error t value
## (Intercept)           -0.56386    0.14836  -3.801
## ks2stand               0.63557    0.00703  90.410
## factor(fsm)1          -2.51428    0.16752 -15.009
## factor(gender)1        1.91338    0.11885  16.099
## ks2stand:factor(fsm)1 -0.06332    0.01516  -4.178
## 
## Correlation of Fixed Effects:
##             (Intr) ks2stn fctr(f)1 fctr(g)1
## ks2stand    -0.033                         
## factr(fsm)1 -0.193  0.007                  
## fctr(gndr)1 -0.394 -0.028 -0.005           
## ks2stnd:()1  0.026 -0.428  0.346   -0.003

Answer: Judging by the interaction effect between fsm and prior attainment, there is evidence to conclude that fsm pupils (fsm = 1) make significantly less progress than non-fsm pupils (fsm = 0) at the same level of prior attainment.



Task 4: School-level variables

One of the strengths of MLM is that we can evaluate the effect of multiple variables at different levels on the outcome of interest. Adding higher-level variables is done in the same way as any other individual-level variable.

We can easily create a new school-level variable from the dataset we have if we aggregate pupil-level data. The code below uses the function mutate of the dplyr package to create a new variable that represents the percentage of pupils eligible for free school meals in each school:

valueadded <- valueadded %>%
  group_by(schoolID) %>%
  mutate(schoolfsm = mean(fsm, na.rm = T)*100)

You can inspect the results by clicking on the object valueadded that is in your Environment tab.

After that, we’re ready to fit the model with schoolfsm.

m5 <- lmer(ks4stand ~ ks2stand + schoolfsm + (1|schoolID), data = valueadded, REML = F)

summary(m5)
## Linear mixed model fit by maximum likelihood  ['lmerMod']
## Formula: ks4stand ~ ks2stand + schoolfsm + (1 | schoolID)
##    Data: valueadded
## 
##      AIC      BIC   logLik deviance df.resid 
##  94182.1  94219.8 -47086.0  94172.1    14047 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -4.8302 -0.5454  0.0223  0.5870  4.6542 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  schoolID (Intercept)  8.832   2.972   
##  Residual             44.203   6.649   
## Number of obs: 14052, groups:  schoolID, 628
## 
## Fixed effects:
##              Estimate Std. Error t value
## (Intercept)  0.191653   0.196889   0.973
## ks2stand     0.642585   0.006354 101.130
## schoolfsm   -0.014478   0.007003  -2.067
## 
## Correlation of Fixed Effects:
##           (Intr) ks2stn
## ks2stand  -0.095       
## schoolfsm -0.742  0.133

Question:

4.1. What is the effect of the percentage of FSM eligible pupils on GCSE scores?

Answer: For every 1% increase in the percentage of FSM eligible pupils in a school, there is a decrease of 0.014 standard deviations in GCSE scores. This is a very small but statistically significant effect.



Task 5: School-specific VA estimates

Plotting the higher-level residuals can be helpful to identify groups that have higher or lower than average effect on the individual-level outcome. In the case of school performance, the residuals can be thought of as the effect uniquely attributable to the school on the progress of their pupils.

To plot the residuals with this purpose, we can use a “caterpillar plot”.

u0 <- ranef(m1, condVar = TRUE) # These are the residuals from model "m1"

u0se <- sqrt(attr(u0[[1]], "postVar")[1,,]) # These are the standard errors of the residuals

schoolid <- as.numeric(rownames(u0[[1]])) # This is to create school identifiers

You will see there are three additional objects in your environment. To put them together in one dataset, we do the following:

school_resid <- cbind(schoolid, u0[[1]], u0se)

colnames(school_resid) <- c("schoolid","u0","u0se")

# Then we sort the residuals in ascending order:

school_resid <- school_resid[order(school_resid$u0), ] 

# And we create a new column (variable) containing the ranks:

school_resid <- cbind(school_resid, c(1:dim(school_resid)[1]))

colnames(school_resid)[4] <- "u0rank" # This is to give a name to the new column containing the ranks

After all this, we end up with a new dataset school_resid containing the school value-added estimates. We can plot with ggplot2 as such:

school_VA_plot <- ggplot(school_resid, aes(x = u0rank, y = u0)) + 
  geom_point(stat = "identity") +
  geom_errorbar(aes(ymin = u0 - 1.96*u0se, ymax = u0 + 1.96*u0se)) +
  geom_hline(yintercept = 0,size = 1.2, alpha = 0.7,colour = "#EF3B2C", linetype = "twodash") +
  xlab("Rank of residuals") +
  ylab("School VA estimates") +
  theme_bw()

school_VA_plot

In the plot above, the red line at y=0 represents the overall national average. Each school is represented by a point and a vertical segment, which represent the average school-specific effect and its 95% confidence interval (respectively). Schools on the left-hand side of the distribution that do not overlap with the national average line are said to be “significantly underperforming”; whereas those on the right-hand side that do not overlap the red line are “significantly overperforming”. All schools that do overlap are those that can be thought of as “performing as expected”.

NB: This is not the only tool to make such judgements about school performance; a comprehensive accountability system would involve also school inspections and qualitative judgements.


Task 6: School predicted lines

You could plot predictions for each school:

valueadded2 <- filter(valueadded, !is.na(ks4stand) & !is.na(ks2stand)) # this filter is necessary to avoid issues with missing values

valueadded2$pred <- fitted(m1)

school_plot <- ggplot(valueadded2, aes(x = ks2stand, y = pred, group = factor(schoolID))) + 
  geom_smooth(method = "lm", colour = "black") +
  xlab("Standardised KS2 score") +
  ylab("Predicted KS4 score") +
  theme_bw()

school_plot

In the plot above, each line represents a school. As you can see, there is a lot of variability across schools. Lines are parallel because we haven’t allowed the effect of KS2 scores to vary across schools; this is a random intercepts model. You can compare this plot with the first one we did in practical 1, where the single-level regression line was clearly not enough to represent the extreme variability in scores. The MLM can account for that variability across schools and hence the multiple regression lines seen here are a much better representation of the observed data.

LS0tDQp0aXRsZTogIkludHJvIHRvIE1MTTogUHJhY3RpY2FsIDIiDQphdXRob3I6IFBhdHJpY2lvIFRyb25jb3NvIGFuZCBBbmEgTW9yYWxlcy1Hw7NtZXoNCmRhdGU6ICJKdW5lIDIwMjQiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGhpZ2hsaWdodGVyOiBudWxsDQogICAgdGhlbWU6IGNvc21vDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGZvbnRzaXplOiAxMnB0DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpsaWJyYXJ5KGhhdmVuKQ0KbGlicmFyeShsbWU0KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCnlwZTwtcmVhZF9zYXYoImh0dHBzOi8vZ2l0aHViLmNvbS9BLW1vcmEvTUxNX3N1bW1lci1zY2hvb2wvcmF3L21haW4vZGF0YS9sc3lwZV8xNTAwMF9maW5hbF8yMDExXzA1XzA0LnNhdiIpDQp2YWx1ZWFkZGVkIDwtIHNlbGVjdCh5cGUsIHB1cGlsaWQsIHNjaG9vbElELCANCiAgICAgICAgICAgICAgICAgICAgIGtzMnN0YW5kLCBrczRzdGFuZCwgZ2VuZGVyLCANCiAgICAgICAgICAgICAgICAgICAgIGZzbSkNCmBgYA0KIyBSYW5kb20gaW50ZXJjZXB0cyBtb2RlbA0KDQpGb2xsb3dpbmcgdXAgZnJvbSB3aGF0IHdlIHdlcmUgZG9pbmcgaW4gcHJhY3RpY2FsIDEsIHdlJ2xsIGNvbnRpbnVlIGJ1aWxkaW5nIHVwIG91ciBtdWx0aWxldmVsIG1vZGVsIGZvciBzY2hvb2wgZWZmZWN0cy4NCg0KKioqDQoNCiMgVGFzayAxOiBWYWx1ZS1hZGRlZCBtb2RlbA0KDQpGaXQgYSBtb2RlbCB3aXRoICJwcmlvciBhdHRhaW5tZW50IiBhcyB0aGUgb25seSBjb3ZhcmlhdGUuIEFjY29yZGluZyB0byB0aGUgbGl0ZXJhdHVyZSB0aGlzIGlzIGEgInR5cGUgQUEiIHZhbHVlLWFkZGVkIG1vZGVsLiBBY2NvcmRpbmcgdG8gdGhlIERmRSwgdGhpcyBpcyBhIHNjaG9vbCB2YWx1ZS1hZGRlZCBtb2RlbCBvciAiVkEiDQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0KbTEgPC1sbWVyKGtzNHN0YW5kIH4ga3Myc3RhbmQgKyAoMXxzY2hvb2xJRCksIGRhdGEgPSB2YWx1ZWFkZGVkLCBSRU1MID0gRikNCnN1bW1hcnkobTEpDQpgYGANCg0KIyMjIFF1ZXN0aW9uOg0KDQoxLjEuIFdoYXQgaXMgdGhlIGVmZmVjdCBvZiBieSBwcmlvciBhdHRhaW5tZW50Pw0KDQoqKkFuc3dlcjoqKiBUaGUgZXN0aW1hdGUgb2YgMC42NCBtZWFucyB0aGF0IGEgb25lIHVuaXQgaW5jcmVhc2UgaW4gdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBLUzIsIHdlIGNhbiBleHBlY3QgYSAwLjY0IHN0YW5kYXJkIGRldmlhdGlvbnMgaW5jcmVhc2UgaW4gR0NTRSBzY29yZXMuDQoNCjxicj4NCg0KKioqDQoNCiMgVGFzayAyOiBDb250ZXh0dWFsaXNlZCB2YWx1ZS1hZGRlZCBtb2RlbA0KDQpGaXQgYSBtb2RlbCB3aXRoIGFsbCB0aGUgYXZhaWxhYmxlIGxldmVsIDEgdmFyaWFibGVzLiBJbiB0aGUgbGl0ZXJhdHVyZSwgdGhpcyBtb2RlbCBpcyBjYWxsZWQgInR5cGUgQUEiIHZhbHVlLWFkZGVkLiBUaGUgRGZFIHdvdWxkIHRoaXMgbW9kZWwgYSAiY29udGV4dHVhbGlzZWQgdmFsdWUtYWRkZWQgbW9kZWwiIG9yICJDVkEiLg0KDQpgYGB7ciwgd2FybmluZz1GLCBtZXNzYWdlPUZ9DQoNCm0yIDwtIGxtZXIoa3M0c3RhbmQgfiBrczJzdGFuZCArIGZhY3RvcihnZW5kZXIpICsgZmFjdG9yKGZzbSkgKyAoMXxzY2hvb2xJRCksIGRhdGEgPSB2YWx1ZWFkZGVkLCBSRU1MID0gRikNCnN1bW1hcnkobTIpDQpgYGANCg0KIyMjIFF1ZXN0aW9ucw0KDQoyLjEuIEhvdyBtdWNoIGhhdmUgdGhlIHZhcmlhbmNlcyAoYXQgYm90aCBsZXZlbHMpIHJlZHVjZWQ/DQoNCioqQW5zd2VyOioqIFRoZSB2YXJpYW5jZSBhdCB0aGUgc2Nob29sIGxldmVsIGhhcyBub3QgcmVkdWNlZCwgYnV0IGluY3JlYXNlZCBldmVyIHNvIHNsaWdodGx5LiBUaGlzIGlzIG5vdCB1bmNvbW1vbi4gSW4gcHJhY3RpY2UsIHRoaXMgbWVhbnMgdGhhdCBldmVuIGFmdGVyIGNvbnRyb2xsaW5nIGZvciBzZXggYW5kIGRlcHJpdmF0aW9uLCB0aGVyZSBpcyBhIG5vbi1uZWdsaWdpYmxlIHJlbWFpbmRlciBvZiB2YXJpYW5jZSBhdCB0aGUgc2Nob29sIGxldmVsIHRoYXQgaXMgbm90IGV4cGxhaW5lZCBieSB0aGUgdmFyaWFibGVzIGluIG91ciBtb2RlbC4NCg0KT24gdGhlIG90aGVyIGhhbmQsIHRoZSB2YXJpYW5jZSBhdCB0aGUgcHVwaWwgbGV2ZWwgaGFzIHJlZHVjZWQgZnJvbSA0NC4yMDcgdG8gNDIuMzA0IChmcm9tIHRoZSBWQSBtb2RlbCB0byB0aGUgQ1ZBIG1vZGVsKQ0KDQokJFxmcmFjeyg0NC4yMDctNDIuMzA0KX17NDQuMjA3fSA9IDAuMDQzICQkDQoNClRoYXQgcmVkdWN0aW9uIGlzIHRoZSB2YXJpYW5jZSB0aGF0IGlzIGFjY291bnRlZCBmb3IgYnkgZGlmZmVyZW5jZXMgaW4gc2V4IGFuZCBGU00gZWxpZ2liaWxpdHkuIFRoZXNlIHR3byB2YXJpYWJsZXMgZXhwbGFpbiA0LjMlIG9mIHRoZSB2YXJpYW5jZSByZW1haW5pbmcgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHByaW9yIGF0dGFpbm1lbnQuDQoNCjIuMi4gV2hhdCBkb2VzIHRoaXMgbWVhbiBmb3IgdGhlIGNvbmNlcHQgb2YgdmFsdWUtYWRkZWQ/DQoNCioqQW5zd2VyOioqIFByaW9yIGF0dGFpbm1lbnQgaXMgbm90IHRoZSBvbmx5IHJlbGV2YW50IGZhY3RvciB3aGVuIGl0IGNvbWVzIHRvIHNjaG9vbCBhdHRhaW5tZW50LCBjb250ZXh0dWFsIGNoYXJhY3RlcmlzdGljcyBhcmUgaW5kZWVkIHJlbGV2YW50IGFuZCBtdXN0IGJlIGNvbnRyb2xsZWQgZm9yLg0KDQo8YnI+DQoNCioqKg0KDQojIFRhc2sgMzogRGlmZmVyZW50aWFsIHByb2dyZXNzIC0gSW50ZXJhY3Rpb24gZWZmZWN0cw0KDQojIyMgUXVlc3Rpb246DQoNCjMuMS4gRG8gbWFsZSBhbmQgZmVtYWxlIHB1cGlscyBoYXZlIGRpZmZlcmVudCBsZXZlbHMgb2YgcHJvZ3Jlc3M/DQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCm0zIDwtIGxtZXIoa3M0c3RhbmQgfiBrczJzdGFuZCArIGtzMnN0YW5kKmZhY3RvcihnZW5kZXIpICsgZmFjdG9yKGdlbmRlcikrDQogICAgICAgICAgIGZhY3Rvcihmc20pICsgKDF8c2Nob29sSUQpLCBkYXRhID0gdmFsdWVhZGRlZCwgUkVNTCA9IEYpDQoNCnN1bW1hcnkobTMpDQpgYGANCg0KKipBbnN3ZXI6KiogSnVkZ2luZyBieSB0aGUgaW50ZXJhY3Rpb24gZWZmZWN0IGJldHdlZW4gc2V4IGFuZCBwcmlvciBhdHRhaW5tZW50LCB0aGVyZSBpcyBub3QgZW5vdWdoIGV2aWRlbmNlIHRvIGNvbmNsdWRlIHRoYXQgZmVtYWxlIHB1cGlscyAoZ2VuZGVyID0gMSkgbW9yZSBvciBsZXNzIHByb2dyZXNzIHRoYW4gbWFsZSBwdXBpbHMgKGdlbmRlciA9IDApIGF0IHRoZSBzYW1lIGxldmVsIG9mIHByaW9yIGF0dGFpbm1lbnQuIA0KDQozLjIuIERvIEZTTSBlbGlnaWJsZSBwdXBpbHMgbWFrZSBtb3JlIG9yIGxlc3MgcHJvZ3Jlc3M/DQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCm00IDwtIGxtZXIoa3M0c3RhbmQgfiBrczJzdGFuZCArIGtzMnN0YW5kKmZhY3Rvcihmc20pICsgZmFjdG9yKGdlbmRlcikrDQogICAgICAgICAgIGZhY3Rvcihmc20pICsgKDF8c2Nob29sSUQpLCBkYXRhID0gdmFsdWVhZGRlZCwgUkVNTCA9IEYpDQoNCnN1bW1hcnkobTQpDQpgYGANCg0KKipBbnN3ZXI6KiogSnVkZ2luZyBieSB0aGUgaW50ZXJhY3Rpb24gZWZmZWN0IGJldHdlZW4gZnNtIGFuZCBwcmlvciBhdHRhaW5tZW50LCB0aGVyZSBpcyBldmlkZW5jZSB0byBjb25jbHVkZSB0aGF0IGZzbSBwdXBpbHMgKGZzbSA9IDEpIG1ha2Ugc2lnbmlmaWNhbnRseSAqKmxlc3MgcHJvZ3Jlc3MqKiB0aGFuIG5vbi1mc20gcHVwaWxzIChmc20gPSAwKSBhdCB0aGUgc2FtZSBsZXZlbCBvZiBwcmlvciBhdHRhaW5tZW50LiANCg0KPGJyPg0KDQoqKioNCg0KIyBUYXNrIDQ6IFNjaG9vbC1sZXZlbCB2YXJpYWJsZXMNCg0KT25lIG9mIHRoZSBzdHJlbmd0aHMgb2YgTUxNIGlzIHRoYXQgd2UgY2FuIGV2YWx1YXRlIHRoZSBlZmZlY3Qgb2YgbXVsdGlwbGUgdmFyaWFibGVzIGF0IGRpZmZlcmVudCBsZXZlbHMgb24gdGhlIG91dGNvbWUgb2YgaW50ZXJlc3QuIEFkZGluZyBoaWdoZXItbGV2ZWwgdmFyaWFibGVzIGlzIGRvbmUgaW4gdGhlIHNhbWUgd2F5IGFzIGFueSBvdGhlciBpbmRpdmlkdWFsLWxldmVsIHZhcmlhYmxlLg0KDQpXZSBjYW4gZWFzaWx5IGNyZWF0ZSBhIG5ldyBzY2hvb2wtbGV2ZWwgdmFyaWFibGUgZnJvbSB0aGUgZGF0YXNldCB3ZSBoYXZlIGlmIHdlIGFnZ3JlZ2F0ZSBwdXBpbC1sZXZlbCBkYXRhLiBUaGUgY29kZSBiZWxvdyB1c2VzIHRoZSBmdW5jdGlvbiBgbXV0YXRlYCBvZiB0aGUgYGRwbHlyYCBwYWNrYWdlIHRvIGNyZWF0ZSBhIG5ldyB2YXJpYWJsZSB0aGF0IHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgcHVwaWxzIGVsaWdpYmxlIGZvciBmcmVlIHNjaG9vbCBtZWFscyBpbiBlYWNoIHNjaG9vbDoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KdmFsdWVhZGRlZCA8LSB2YWx1ZWFkZGVkICU+JQ0KICBncm91cF9ieShzY2hvb2xJRCkgJT4lDQogIG11dGF0ZShzY2hvb2xmc20gPSBtZWFuKGZzbSwgbmEucm0gPSBUKSoxMDApDQpgYGANCg0KWW91IGNhbiBpbnNwZWN0IHRoZSByZXN1bHRzIGJ5IGNsaWNraW5nIG9uIHRoZSBvYmplY3QgYHZhbHVlYWRkZWRgIHRoYXQgaXMgaW4geW91ciBFbnZpcm9ubWVudCB0YWIuDQoNCkFmdGVyIHRoYXQsIHdlJ3JlIHJlYWR5IHRvIGZpdCB0aGUgbW9kZWwgd2l0aCBgc2Nob29sZnNtYC4NCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KbTUgPC0gbG1lcihrczRzdGFuZCB+IGtzMnN0YW5kICsgc2Nob29sZnNtICsgKDF8c2Nob29sSUQpLCBkYXRhID0gdmFsdWVhZGRlZCwgUkVNTCA9IEYpDQoNCnN1bW1hcnkobTUpDQpgYGANCg0KIyMjIFF1ZXN0aW9uOg0KDQo0LjEuIFdoYXQgaXMgdGhlIGVmZmVjdCBvZiB0aGUgcGVyY2VudGFnZSBvZiBGU00gZWxpZ2libGUgcHVwaWxzIG9uIEdDU0Ugc2NvcmVzPw0KDQoqKkFuc3dlcjoqKiBGb3IgZXZlcnkgMSUgaW5jcmVhc2UgaW4gdGhlIHBlcmNlbnRhZ2Ugb2YgRlNNIGVsaWdpYmxlIHB1cGlscyBpbiBhIHNjaG9vbCwgdGhlcmUgaXMgYSBkZWNyZWFzZSBvZiAwLjAxNCBzdGFuZGFyZCBkZXZpYXRpb25zIGluIEdDU0Ugc2NvcmVzLiBUaGlzIGlzIGEgdmVyeSBzbWFsbCBidXQgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBlZmZlY3QuDQoNCjxicj4NCg0KKioqDQoNCiMgVGFzayA1OiBTY2hvb2wtc3BlY2lmaWMgVkEgZXN0aW1hdGVzDQoNClBsb3R0aW5nIHRoZSBoaWdoZXItbGV2ZWwgcmVzaWR1YWxzIGNhbiBiZSBoZWxwZnVsIHRvIGlkZW50aWZ5IGdyb3VwcyB0aGF0IGhhdmUgaGlnaGVyIG9yIGxvd2VyIHRoYW4gYXZlcmFnZSBlZmZlY3Qgb24gdGhlIGluZGl2aWR1YWwtbGV2ZWwgb3V0Y29tZS4gSW4gdGhlIGNhc2Ugb2Ygc2Nob29sIHBlcmZvcm1hbmNlLCB0aGUgcmVzaWR1YWxzIGNhbiBiZSB0aG91Z2h0IG9mIGFzIHRoZSBlZmZlY3QgdW5pcXVlbHkgYXR0cmlidXRhYmxlIHRvIHRoZSBzY2hvb2wgb24gdGhlIHByb2dyZXNzIG9mIHRoZWlyIHB1cGlscy4NCg0KVG8gcGxvdCB0aGUgcmVzaWR1YWxzIHdpdGggdGhpcyBwdXJwb3NlLCB3ZSBjYW4gdXNlIGEgImNhdGVycGlsbGFyIHBsb3QiLg0KDQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0KdTAgPC0gcmFuZWYobTEsIGNvbmRWYXIgPSBUUlVFKSAjIFRoZXNlIGFyZSB0aGUgcmVzaWR1YWxzIGZyb20gbW9kZWwgIm0xIg0KDQp1MHNlIDwtIHNxcnQoYXR0cih1MFtbMV1dLCAicG9zdFZhciIpWzEsLF0pICMgVGhlc2UgYXJlIHRoZSBzdGFuZGFyZCBlcnJvcnMgb2YgdGhlIHJlc2lkdWFscw0KDQpzY2hvb2xpZCA8LSBhcy5udW1lcmljKHJvd25hbWVzKHUwW1sxXV0pKSAjIFRoaXMgaXMgdG8gY3JlYXRlIHNjaG9vbCBpZGVudGlmaWVycw0KYGBgDQoNCllvdSB3aWxsIHNlZSB0aGVyZSBhcmUgdGhyZWUgYWRkaXRpb25hbCBvYmplY3RzIGluIHlvdXIgZW52aXJvbm1lbnQuIFRvIHB1dCB0aGVtIHRvZ2V0aGVyIGluIG9uZSBkYXRhc2V0LCB3ZSBkbyB0aGUgZm9sbG93aW5nOg0KDQpgYGB7ciwgd2FybmluZz1GLCBtZXNzYWdlPUZ9DQoNCnNjaG9vbF9yZXNpZCA8LSBjYmluZChzY2hvb2xpZCwgdTBbWzFdXSwgdTBzZSkNCg0KY29sbmFtZXMoc2Nob29sX3Jlc2lkKSA8LSBjKCJzY2hvb2xpZCIsInUwIiwidTBzZSIpDQoNCiMgVGhlbiB3ZSBzb3J0IHRoZSByZXNpZHVhbHMgaW4gYXNjZW5kaW5nIG9yZGVyOg0KDQpzY2hvb2xfcmVzaWQgPC0gc2Nob29sX3Jlc2lkW29yZGVyKHNjaG9vbF9yZXNpZCR1MCksIF0gDQoNCiMgQW5kIHdlIGNyZWF0ZSBhIG5ldyBjb2x1bW4gKHZhcmlhYmxlKSBjb250YWluaW5nIHRoZSByYW5rczoNCg0Kc2Nob29sX3Jlc2lkIDwtIGNiaW5kKHNjaG9vbF9yZXNpZCwgYygxOmRpbShzY2hvb2xfcmVzaWQpWzFdKSkNCg0KY29sbmFtZXMoc2Nob29sX3Jlc2lkKVs0XSA8LSAidTByYW5rIiAjIFRoaXMgaXMgdG8gZ2l2ZSBhIG5hbWUgdG8gdGhlIG5ldyBjb2x1bW4gY29udGFpbmluZyB0aGUgcmFua3MNCmBgYA0KDQpBZnRlciBhbGwgdGhpcywgd2UgZW5kIHVwIHdpdGggYSBuZXcgZGF0YXNldCBgc2Nob29sX3Jlc2lkYCBjb250YWluaW5nIHRoZSBzY2hvb2wgdmFsdWUtYWRkZWQgZXN0aW1hdGVzLiBXZSBjYW4gcGxvdCB3aXRoIGBnZ3Bsb3QyYCBhcyBzdWNoOg0KDQpgYGB7ciwgd2FybmluZz1GLCBtZXNzYWdlPUZ9DQpzY2hvb2xfVkFfcGxvdCA8LSBnZ3Bsb3Qoc2Nob29sX3Jlc2lkLCBhZXMoeCA9IHUwcmFuaywgeSA9IHUwKSkgKyANCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gdTAgLSAxLjk2KnUwc2UsIHltYXggPSB1MCArIDEuOTYqdTBzZSkpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCxzaXplID0gMS4yLCBhbHBoYSA9IDAuNyxjb2xvdXIgPSAiI0VGM0IyQyIsIGxpbmV0eXBlID0gInR3b2Rhc2giKSArDQogIHhsYWIoIlJhbmsgb2YgcmVzaWR1YWxzIikgKw0KICB5bGFiKCJTY2hvb2wgVkEgZXN0aW1hdGVzIikgKw0KICB0aGVtZV9idygpDQoNCnNjaG9vbF9WQV9wbG90DQoNCmBgYA0KDQpJbiB0aGUgcGxvdCBhYm92ZSwgdGhlIHJlZCBsaW5lIGF0IGB5PTBgIHJlcHJlc2VudHMgdGhlIG92ZXJhbGwgbmF0aW9uYWwgYXZlcmFnZS4gRWFjaCBzY2hvb2wgaXMgcmVwcmVzZW50ZWQgYnkgYSBwb2ludCBhbmQgYSB2ZXJ0aWNhbCBzZWdtZW50LCB3aGljaCByZXByZXNlbnQgdGhlIGF2ZXJhZ2Ugc2Nob29sLXNwZWNpZmljIGVmZmVjdCBhbmQgaXRzIDk1JSBjb25maWRlbmNlIGludGVydmFsIChyZXNwZWN0aXZlbHkpLiBTY2hvb2xzIG9uIHRoZSBsZWZ0LWhhbmQgc2lkZSBvZiB0aGUgZGlzdHJpYnV0aW9uIHRoYXQgZG8gbm90IG92ZXJsYXAgd2l0aCB0aGUgbmF0aW9uYWwgYXZlcmFnZSBsaW5lIGFyZSBzYWlkIHRvIGJlICJzaWduaWZpY2FudGx5IHVuZGVycGVyZm9ybWluZyI7IHdoZXJlYXMgdGhvc2Ugb24gdGhlIHJpZ2h0LWhhbmQgc2lkZSB0aGF0IGRvIG5vdCBvdmVybGFwIHRoZSByZWQgbGluZSBhcmUgInNpZ25pZmljYW50bHkgb3ZlcnBlcmZvcm1pbmciLiBBbGwgc2Nob29scyB0aGF0IGRvIG92ZXJsYXAgYXJlIHRob3NlIHRoYXQgY2FuIGJlIHRob3VnaHQgb2YgYXMgInBlcmZvcm1pbmcgYXMgZXhwZWN0ZWQiLiANCg0KKipOQjoqKiBUaGlzIGlzIG5vdCB0aGUgb25seSB0b29sIHRvIG1ha2Ugc3VjaCBqdWRnZW1lbnRzIGFib3V0IHNjaG9vbCBwZXJmb3JtYW5jZTsgYSBjb21wcmVoZW5zaXZlIGFjY291bnRhYmlsaXR5IHN5c3RlbSB3b3VsZCBpbnZvbHZlIGFsc28gc2Nob29sIGluc3BlY3Rpb25zIGFuZCBxdWFsaXRhdGl2ZSBqdWRnZW1lbnRzLg0KDQoqKioNCg0KIyBUYXNrIDY6IFNjaG9vbCBwcmVkaWN0ZWQgbGluZXMNCg0KWW91IGNvdWxkIHBsb3QgcHJlZGljdGlvbnMgZm9yIGVhY2ggc2Nob29sOg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KDQp2YWx1ZWFkZGVkMiA8LSBmaWx0ZXIodmFsdWVhZGRlZCwgIWlzLm5hKGtzNHN0YW5kKSAmICFpcy5uYShrczJzdGFuZCkpICMgdGhpcyBmaWx0ZXIgaXMgbmVjZXNzYXJ5IHRvIGF2b2lkIGlzc3VlcyB3aXRoIG1pc3NpbmcgdmFsdWVzDQoNCnZhbHVlYWRkZWQyJHByZWQgPC0gZml0dGVkKG0xKQ0KDQpzY2hvb2xfcGxvdCA8LSBnZ3Bsb3QodmFsdWVhZGRlZDIsIGFlcyh4ID0ga3Myc3RhbmQsIHkgPSBwcmVkLCBncm91cCA9IGZhY3RvcihzY2hvb2xJRCkpKSArIA0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArDQogIHhsYWIoIlN0YW5kYXJkaXNlZCBLUzIgc2NvcmUiKSArDQogIHlsYWIoIlByZWRpY3RlZCBLUzQgc2NvcmUiKSArDQogIHRoZW1lX2J3KCkNCg0Kc2Nob29sX3Bsb3QNCg0KYGBgDQoNCkluIHRoZSBwbG90IGFib3ZlLCBlYWNoIGxpbmUgcmVwcmVzZW50cyBhIHNjaG9vbC4gQXMgeW91IGNhbiBzZWUsIHRoZXJlIGlzIGEgbG90IG9mIHZhcmlhYmlsaXR5IGFjcm9zcyBzY2hvb2xzLiANCkxpbmVzIGFyZSBwYXJhbGxlbCBiZWNhdXNlIHdlIGhhdmVuJ3QgYWxsb3dlZCB0aGUgZWZmZWN0IG9mIEtTMiBzY29yZXMgdG8gdmFyeSBhY3Jvc3Mgc2Nob29sczsgdGhpcyBpcyBhIGByYW5kb20gaW50ZXJjZXB0cyBtb2RlbGAuIFlvdSBjYW4gY29tcGFyZSB0aGlzIHBsb3Qgd2l0aCB0aGUgZmlyc3Qgb25lIHdlIGRpZCBpbiBwcmFjdGljYWwgMSwgd2hlcmUgdGhlIHNpbmdsZS1sZXZlbCByZWdyZXNzaW9uIGxpbmUgd2FzIGNsZWFybHkgbm90IGVub3VnaCB0byByZXByZXNlbnQgdGhlIGV4dHJlbWUgdmFyaWFiaWxpdHkgaW4gc2NvcmVzLiBUaGUgTUxNIGNhbiBhY2NvdW50IGZvciB0aGF0IHZhcmlhYmlsaXR5IGFjcm9zcyBzY2hvb2xzIGFuZCBoZW5jZSB0aGUgbXVsdGlwbGUgcmVncmVzc2lvbiBsaW5lcyBzZWVuIGhlcmUgYXJlIGEgbXVjaCBiZXR0ZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9ic2VydmVkIGRhdGEu