For this practical, we will use data from a sample of the Teaching
dataset of The Longitudinal Study of Young People in England, 2004-2006
available here.
We will be fitting a series of school value-added models, which are
one of the most prominent examples of multilevel models applied in
education research.
A traditional school value-added model is a model that attempts to
isolate the “school effects” from the inherent variability/heterogeneity
of the pupils. It attempts to ascertain what schools add to the progress
of their pupils beyond what is expected of them, given their
circumstances.
Typical workflow setup and data preparation
1.1. Define a working directory
You can use any directory in your computer. As in the example
below:
setwd("C:/myfolder")
Remember to download the data to the folder you will define as
working directory, as this makes matters easier.
1.2. Load packages
You can always load packages later on, but it is a good practice to
load packages at the beginning of the session on the top of your script
or R markdown file.
In this practical, we will use the packages haven,
lme4 and ggplot2. Remember that if you haven’t
installed them before, you need to do so before you call the
library function:
install.packages("haven")
install.packages("lme4")
install.packages("ggplot2")
install.packages("dplyr")
Then you load them as such:
library(haven)
library(lme4)
library(ggplot2)
library(dplyr)
1.3. Read in data
You can download the data from the UKDS
website. There are two SPSS datasets and we will be using
the one named “lsype_15000_final_2011_05_04.sav”.
You can also download the file from the link below, but this link
will stop working by the end of the session, so make sure to register
and download the data from the UKDS if you want to continue working with
this dataset.
To read this dataset into R, we need to use the package
haven:
ype<-read_sav("https://github.com/A-mora/MLM_summer-school/raw/main/data/lsype_15000_final_2011_05_04.sav")
Select variables to use
In England and Wales, the Department for Education (DfE) publishes
periodically the so-called performance tables, in which schools are
assessed (and classified) according to the progress that their pupils
make from one stage to another. Secondary schools are judged on the GCSE
results of their pupils and the progress they made since the end of
primary, when they sat the KS2 tests.
We will select the variables: pupilid, schoolID, ks2stand (KS2
scores), ks4stand (GCSE scores), gender, fsm and indschool.
For this, we need to use the function select of the
dplyr package:
valueadded <- select(ype, pupilid, schoolID,
ks2stand, ks4stand, gender,
fsm)
Task 1: Relationship between KS2 and GCSE
Plot the relationship between KS2 and GCSE scores
plot1 <- ggplot(valueadded, aes(x=ks2stand, y=ks4stand)) +
geom_point() + geom_smooth(aes(x=ks2stand, y=ks4stand), method = "lm")
plot1

Questions:
1.1 What can you observe in the plot?
Answer: The relationship between KS2 and GCSE scores
is as expected: in general, the better the KS2 score, the better the
GCSE score. Nevertheless, there is plenty of variability.
1.2 How correlated are KS2 and GCSE scores?
Answer: Obtain the correlation between scores. This
indicates a moderate positive correlation as hinted by the previous
plot.
cor(valueadded$ks2stand, valueadded$ks4stand, use="comp")
## [1] 0.6714863
Task 2: Variance components (empty) model
Fit an empty multilevel model of pupils within schools
library(lme4)
We will use the lmer functions, which stands for “linear
mixed effects regression”. The basic syntax follows the conventions of
most R packages running regression. You specify an outcome regressed
~ on variables. Each variable you add needs to be preceded
by a + sign. You specify the data.
Note that we will use Maximum Likelihood (ML), not Restricted Maximum
Likelihood (REML). REML is the default in lmer, so we need to specify
REML = FALSE
Random effects are added within brackets after the fixed effects.
1 indicates that the constant is allowed to vary freely.
The random effects are specified like this: (1|level2id).
If you want to want random slopes, you specify
(1 + variable|level2id)
m0 <- lmer(ks4stand ~ 1 + (1|schoolID), data = valueadded, REML = F)
summary(m0)
## Linear mixed model fit by maximum likelihood ['lmerMod']
## Formula: ks4stand ~ 1 + (1 | schoolID)
## Data: valueadded
##
## AIC BIC logLik deviance df.resid
## 111792.8 111815.7 -55893.4 111786.8 15401
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.7751 -0.6241 0.0163 0.6378 4.0338
##
## Random effects:
## Groups Name Variance Std.Dev.
## schoolID (Intercept) 24.33 4.932
## Residual 75.85 8.709
## Number of obs: 15404, groups: schoolID, 657
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) -0.1125 0.2057 -0.547
This model is called “type 0” value-added model in the literature
Question
2.1. What is the proportion of variation that lies between schools in
the empty model?
Answer: You should use the following equation:
\[VPC = \frac{\sigma_u^2}{\sigma_u^2 +
\sigma_e^2}\] where \(\sigma_u^2\) is the variance at the school
level and \(\sigma_e^2\) is the
variance at the pupil level.
Replacing the values:
\[VPC = \frac{24.33}{24.33 + 75.85} =
24.28 \]
2.2. What does that value mean?
Answer: Approximately 24% of the total variance can
be attributed to differences between schools.
Task 3: Is the MLM better than a single-level model?
To assess the statistical significance of the MLM, we need to compare
it to a single-level model. To fit a single-level model, we type:
single <- lm(ks4stand ~ 1 , data = valueadded)
summary(single)
##
## Call:
## lm(formula = ks4stand ~ 1, data = valueadded)
##
## Residuals:
## Min 1Q Median 3Q Max
## -23.026 -7.026 -0.026 6.974 38.974
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.02577 0.07999 0.322 0.747
##
## Residual standard error: 9.928 on 15403 degrees of freedom
## (366 observations deleted due to missingness)
These results are not very interesting in themselves, so we move on
extract the loglikelihood and compare to the MLM.
L1 <- as.numeric(logLik(single)) # store this as numerical to re-use
L2 <- as.numeric(logLik(m0))
(D <- 2*(L2-L1)) # this is the deviance, we put it within brackets to print it immediately
## [1] 2641.369
pchisq(q=D, df=1, lower.tail=F) # To find the p-value
## [1] 0
Question
3.1. Is the addition of the school level statistically
significant?
Answer: Yes it is! Even if you hadn’t done the
loglikelihood test, the VPC of 24% is strong evidence of the relevance
of school effects.
3.2. What does this mean in practice?
Answer: It means that it is extremely important to
control for the rather large variability between schools in your
models.
LS0tDQp0aXRsZTogIkludHJvIHRvIE1MTTogUHJhY3RpY2FsIDEiDQphdXRob3I6IFBhdHJpY2lvIFRyb25jb3NvIGFuZCBBbmEgTW9yYWxlcy1Hw7NtZXoNCmRhdGU6ICJKdW5lIDIwMjQiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGhpZ2hsaWdodGVyOiBudWxsDQogICAgdGhlbWU6IGNvc21vDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGZvbnRzaXplOiAxMnB0DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KDQpGb3IgdGhpcyBwcmFjdGljYWwsIHdlIHdpbGwgdXNlIGRhdGEgZnJvbSBhIHNhbXBsZSBvZiB0aGUgVGVhY2hpbmcgZGF0YXNldCBvZiBUaGUgTG9uZ2l0dWRpbmFsIFN0dWR5IG9mIFlvdW5nIFBlb3BsZSBpbiBFbmdsYW5kLCAyMDA0LTIwMDYNCmF2YWlsYWJsZSBbKipoZXJlKipdKGh0dHBzOi8vYmV0YS51a2RhdGFzZXJ2aWNlLmFjLnVrL2RhdGFjYXRhbG9ndWUvc3R1ZGllcy9zdHVkeT9pZD02NjYwKS4NCg0KV2Ugd2lsbCBiZSBmaXR0aW5nIGEgc2VyaWVzIG9mIHNjaG9vbCB2YWx1ZS1hZGRlZCBtb2RlbHMsIHdoaWNoIGFyZSBvbmUgb2YgdGhlIG1vc3QgcHJvbWluZW50IGV4YW1wbGVzIG9mIG11bHRpbGV2ZWwgbW9kZWxzIGFwcGxpZWQgaW4gZWR1Y2F0aW9uIHJlc2VhcmNoLg0KDQpBIHRyYWRpdGlvbmFsIHNjaG9vbCB2YWx1ZS1hZGRlZCBtb2RlbCBpcyBhIG1vZGVsIHRoYXQgYXR0ZW1wdHMgdG8gaXNvbGF0ZSB0aGUgInNjaG9vbCBlZmZlY3RzIiBmcm9tIHRoZSBpbmhlcmVudCB2YXJpYWJpbGl0eS9oZXRlcm9nZW5laXR5IG9mIHRoZSBwdXBpbHMuIEl0IGF0dGVtcHRzIHRvIGFzY2VydGFpbiB3aGF0IHNjaG9vbHMgYWRkIHRvIHRoZSBwcm9ncmVzcyBvZiB0aGVpciBwdXBpbHMgYmV5b25kIHdoYXQgaXMgZXhwZWN0ZWQgb2YgdGhlbSwgZ2l2ZW4gdGhlaXIgY2lyY3Vtc3RhbmNlcy4NCg0KPGJyPg0KDQoqKioNCg0KIyBUeXBpY2FsIHdvcmtmbG93IHNldHVwIGFuZCBkYXRhIHByZXBhcmF0aW9uDQoNCiMjIDEuMS4gRGVmaW5lIGEgd29ya2luZyBkaXJlY3RvcnkNCg0KWW91IGNhbiB1c2UgYW55IGRpcmVjdG9yeSBpbiB5b3VyIGNvbXB1dGVyLiBBcyBpbiB0aGUgZXhhbXBsZSBiZWxvdzoNCg0KYGBge3IsIGV2YWw9Rn0NCnNldHdkKCJDOi9teWZvbGRlciIpDQpgYGANCg0KUmVtZW1iZXIgdG8gZG93bmxvYWQgdGhlIGRhdGEgdG8gdGhlIGZvbGRlciB5b3Ugd2lsbCBkZWZpbmUgYXMgd29ya2luZyBkaXJlY3RvcnksIGFzIHRoaXMgbWFrZXMgbWF0dGVycyBlYXNpZXIuDQoNCiMjIDEuMi4gTG9hZCBwYWNrYWdlcw0KDQpZb3UgY2FuIGFsd2F5cyBsb2FkIHBhY2thZ2VzIGxhdGVyIG9uLCBidXQgaXQgaXMgYSBnb29kIHByYWN0aWNlIHRvIGxvYWQgcGFja2FnZXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2Vzc2lvbiBvbiB0aGUgdG9wIG9mIHlvdXIgc2NyaXB0IG9yIFIgbWFya2Rvd24gZmlsZS4NCg0KSW4gdGhpcyBwcmFjdGljYWwsIHdlIHdpbGwgdXNlIHRoZSBwYWNrYWdlcyBgaGF2ZW5gLCBgbG1lNGAgYW5kIGBnZ3Bsb3QyYC4gUmVtZW1iZXIgdGhhdCBpZiB5b3UgaGF2ZW4ndCBpbnN0YWxsZWQgdGhlbSBiZWZvcmUsIHlvdSBuZWVkIHRvIGRvIHNvIGJlZm9yZSB5b3UgY2FsbCB0aGUgYGxpYnJhcnlgIGZ1bmN0aW9uOg0KDQpgYGB7fQ0KaW5zdGFsbC5wYWNrYWdlcygiaGF2ZW4iKQ0KaW5zdGFsbC5wYWNrYWdlcygibG1lNCIpDQppbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCmluc3RhbGwucGFja2FnZXMoImRwbHlyIikNCmBgYA0KDQpUaGVuIHlvdSBsb2FkIHRoZW0gYXMgc3VjaDoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KbGlicmFyeShoYXZlbikNCmxpYnJhcnkobG1lNCkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KIyMgMS4zLiBSZWFkIGluIGRhdGEgDQoNCllvdSBjYW4gZG93bmxvYWQgdGhlIGRhdGEgZnJvbSAgdGhlIFsqKlVLRFMgd2Vic2l0ZSoqXShodHRwczovL2JldGEudWtkYXRhc2VydmljZS5hYy51ay9kYXRhY2F0YWxvZ3VlL3N0dWRpZXMvc3R1ZHk/aWQ9NjY2MCkuIFRoZXJlIGFyZSB0d28gU1BTUyBkYXRhc2V0cyBhbmQgd2Ugd2lsbCBiZSB1c2luZyB0aGUgb25lIG5hbWVkICJsc3lwZV8xNTAwMF9maW5hbF8yMDExXzA1XzA0LnNhdiIuDQoNCllvdSBjYW4gYWxzbyBkb3dubG9hZCB0aGUgZmlsZSBmcm9tIHRoZSBsaW5rIGJlbG93LCBidXQgdGhpcyBsaW5rIHdpbGwgc3RvcCB3b3JraW5nIGJ5IHRoZSBlbmQgb2YgdGhlIHNlc3Npb24sIHNvIG1ha2Ugc3VyZSB0byByZWdpc3RlciBhbmQgZG93bmxvYWQgdGhlIGRhdGEgZnJvbSB0aGUgVUtEUyBpZiB5b3Ugd2FudCB0byBjb250aW51ZSB3b3JraW5nIHdpdGggdGhpcyBkYXRhc2V0Lg0KDQpUbyByZWFkIHRoaXMgZGF0YXNldCBpbnRvIFIsIHdlIG5lZWQgdG8gdXNlIHRoZSBwYWNrYWdlIGBoYXZlbmA6DQoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KeXBlPC1yZWFkX3NhdigiaHR0cHM6Ly9naXRodWIuY29tL0EtbW9yYS9NTE1fc3VtbWVyLXNjaG9vbC9yYXcvbWFpbi9kYXRhL2xzeXBlXzE1MDAwX2ZpbmFsXzIwMTFfMDVfMDQuc2F2IikNCmBgYA0KDQo8YnI+DQoNCioqKg0KDQojIyBTZWxlY3QgdmFyaWFibGVzIHRvIHVzZQ0KDQpJbiBFbmdsYW5kIGFuZCBXYWxlcywgdGhlIERlcGFydG1lbnQgZm9yIEVkdWNhdGlvbiAoRGZFKSBwdWJsaXNoZXMgcGVyaW9kaWNhbGx5IHRoZSBzby1jYWxsZWQgcGVyZm9ybWFuY2UgdGFibGVzLCBpbiB3aGljaCBzY2hvb2xzIGFyZSBhc3Nlc3NlZCAoYW5kIGNsYXNzaWZpZWQpIGFjY29yZGluZyB0byB0aGUgcHJvZ3Jlc3MgdGhhdCB0aGVpciBwdXBpbHMgbWFrZSBmcm9tIG9uZSBzdGFnZSB0byBhbm90aGVyLiBTZWNvbmRhcnkgc2Nob29scyBhcmUganVkZ2VkIG9uIHRoZSBHQ1NFIHJlc3VsdHMgb2YgdGhlaXIgcHVwaWxzIGFuZCB0aGUgcHJvZ3Jlc3MgdGhleSBtYWRlIHNpbmNlIHRoZSBlbmQgb2YgcHJpbWFyeSwgd2hlbiB0aGV5IHNhdCB0aGUgS1MyIHRlc3RzLg0KDQpXZSB3aWxsIHNlbGVjdCB0aGUgdmFyaWFibGVzOiBwdXBpbGlkLCBzY2hvb2xJRCwga3Myc3RhbmQgKEtTMiBzY29yZXMpLCBrczRzdGFuZCAoR0NTRSBzY29yZXMpLCBnZW5kZXIsIGZzbSBhbmQgaW5kc2Nob29sLg0KDQpGb3IgdGhpcywgd2UgbmVlZCB0byB1c2UgdGhlIGZ1bmN0aW9uIGBzZWxlY3RgIG9mIHRoZSBgZHBseXJgIHBhY2thZ2U6DQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0KdmFsdWVhZGRlZCA8LSBzZWxlY3QoeXBlLCBwdXBpbGlkLCBzY2hvb2xJRCwgDQogICAgICAgICAgICAgICAgICAgICBrczJzdGFuZCwga3M0c3RhbmQsIGdlbmRlciwgDQogICAgICAgICAgICAgICAgICAgICBmc20pIA0KDQpgYGANCg0KPGJyPg0KDQoqKioNCg0KIyBUYXNrIDE6IFJlbGF0aW9uc2hpcCBiZXR3ZWVuIEtTMiBhbmQgR0NTRQ0KDQpQbG90IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBLUzIgYW5kIEdDU0Ugc2NvcmVzDQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0KcGxvdDEgPC0gZ2dwbG90KHZhbHVlYWRkZWQsIGFlcyh4PWtzMnN0YW5kLCB5PWtzNHN0YW5kKSkgKw0KZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgoYWVzKHg9a3Myc3RhbmQsIHk9a3M0c3RhbmQpLCBtZXRob2QgPSAibG0iKQ0KDQpwbG90MQ0KDQpgYGANCg0KIyMjIFF1ZXN0aW9uczoNCg0KMS4xIFdoYXQgY2FuIHlvdSBvYnNlcnZlIGluIHRoZSBwbG90Pw0KDQoqKkFuc3dlcjoqKiBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gS1MyIGFuZCBHQ1NFIHNjb3JlcyBpcyBhcyBleHBlY3RlZDogaW4gZ2VuZXJhbCwgdGhlIGJldHRlciB0aGUgS1MyIHNjb3JlLCB0aGUgYmV0dGVyIHRoZSBHQ1NFIHNjb3JlLiBOZXZlcnRoZWxlc3MsIHRoZXJlIGlzIHBsZW50eSBvZiB2YXJpYWJpbGl0eS4NCg0KMS4yIEhvdyBjb3JyZWxhdGVkIGFyZSBLUzIgYW5kIEdDU0Ugc2NvcmVzPw0KDQoqKkFuc3dlcjoqKiBPYnRhaW4gdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gc2NvcmVzLiBUaGlzIGluZGljYXRlcyBhIG1vZGVyYXRlIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGFzIGhpbnRlZCBieSB0aGUgcHJldmlvdXMgcGxvdC4NCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KY29yKHZhbHVlYWRkZWQka3Myc3RhbmQsIHZhbHVlYWRkZWQka3M0c3RhbmQsIHVzZT0iY29tcCIpDQpgYGANCg0KPGJyPg0KDQoqKioNCg0KIyBUYXNrIDI6IFZhcmlhbmNlIGNvbXBvbmVudHMgKGVtcHR5KSBtb2RlbA0KDQpGaXQgYW4gZW1wdHkgbXVsdGlsZXZlbCBtb2RlbCBvZiBwdXBpbHMgd2l0aGluIHNjaG9vbHMNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KbGlicmFyeShsbWU0KQ0KYGBgDQoNCldlIHdpbGwgdXNlIHRoZSBgbG1lcmAgZnVuY3Rpb25zLCB3aGljaCBzdGFuZHMgZm9yICJsaW5lYXIgbWl4ZWQgZWZmZWN0cyByZWdyZXNzaW9uIi4NClRoZSBiYXNpYyBzeW50YXggZm9sbG93cyB0aGUgY29udmVudGlvbnMgb2YgbW9zdCBSIHBhY2thZ2VzIHJ1bm5pbmcgcmVncmVzc2lvbi4gWW91IHNwZWNpZnkgYW4gb3V0Y29tZSByZWdyZXNzZWQgYH5gIG9uIHZhcmlhYmxlcy4gRWFjaCB2YXJpYWJsZSB5b3UgYWRkIG5lZWRzIHRvIGJlIHByZWNlZGVkIGJ5IGEgYCtgIHNpZ24uIFlvdSBzcGVjaWZ5IHRoZSBkYXRhLg0KDQpOb3RlIHRoYXQgd2Ugd2lsbCB1c2UgTWF4aW11bSBMaWtlbGlob29kIChNTCksIG5vdCBSZXN0cmljdGVkIE1heGltdW0gTGlrZWxpaG9vZCAoUkVNTCkuIFJFTUwgaXMgdGhlIGRlZmF1bHQgaW4gbG1lciwgc28gd2UgbmVlZCB0byBzcGVjaWZ5IGBSRU1MID0gRkFMU0VgDQoNClJhbmRvbSBlZmZlY3RzIGFyZSBhZGRlZCB3aXRoaW4gYnJhY2tldHMgYWZ0ZXIgdGhlIGZpeGVkIGVmZmVjdHMuIGAxYCBpbmRpY2F0ZXMgdGhhdCB0aGUgY29uc3RhbnQgaXMgYWxsb3dlZCB0byB2YXJ5IGZyZWVseS4gVGhlIHJhbmRvbSBlZmZlY3RzIGFyZSBzcGVjaWZpZWQgbGlrZSB0aGlzOiBgKDF8bGV2ZWwyaWQpYC4gSWYgeW91IHdhbnQgdG8gd2FudCByYW5kb20gc2xvcGVzLCB5b3Ugc3BlY2lmeSBgKDEgKyB2YXJpYWJsZXxsZXZlbDJpZClgDQoNCg0KYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GfQ0KDQptMCA8LSBsbWVyKGtzNHN0YW5kIH4gMSArICgxfHNjaG9vbElEKSwgZGF0YSA9IHZhbHVlYWRkZWQsIFJFTUwgPSBGKQ0KDQpzdW1tYXJ5KG0wKQ0KDQpgYGANCg0KVGhpcyBtb2RlbCBpcyBjYWxsZWQgInR5cGUgMCIgdmFsdWUtYWRkZWQgbW9kZWwgaW4gdGhlIGxpdGVyYXR1cmUNCg0KIyMjIFF1ZXN0aW9uDQoNCjIuMS4gV2hhdCBpcyB0aGUgcHJvcG9ydGlvbiBvZiB2YXJpYXRpb24gdGhhdCBsaWVzIGJldHdlZW4gc2Nob29scyBpbiB0aGUgZW1wdHkgbW9kZWw/DQoNCioqQW5zd2VyOioqIFlvdSBzaG91bGQgdXNlIHRoZSBmb2xsb3dpbmcgZXF1YXRpb246DQoNCiQkVlBDID0gXGZyYWN7XHNpZ21hX3VeMn17XHNpZ21hX3VeMiArIFxzaWdtYV9lXjJ9JCQNCndoZXJlICRcc2lnbWFfdV4yJCBpcyB0aGUgdmFyaWFuY2UgYXQgdGhlIHNjaG9vbCBsZXZlbCBhbmQgJFxzaWdtYV9lXjIkIGlzIHRoZSB2YXJpYW5jZSBhdCB0aGUgcHVwaWwgbGV2ZWwuDQoNClJlcGxhY2luZyB0aGUgdmFsdWVzOg0KDQokJFZQQyA9IFxmcmFjezI0LjMzfXsyNC4zMyArIDc1Ljg1fSA9IDI0LjI4ICQkDQoNCjIuMi4gV2hhdCBkb2VzIHRoYXQgdmFsdWUgbWVhbj8NCg0KKipBbnN3ZXI6KiogQXBwcm94aW1hdGVseSAyNCUgb2YgdGhlIHRvdGFsIHZhcmlhbmNlIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIGRpZmZlcmVuY2VzIGJldHdlZW4gc2Nob29scy4NCg0KPGJyPg0KDQojIFRhc2sgMzogSXMgdGhlIE1MTSBiZXR0ZXIgdGhhbiBhIHNpbmdsZS1sZXZlbCBtb2RlbD8NCg0KVG8gYXNzZXNzIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIE1MTSwgd2UgbmVlZCB0byBjb21wYXJlIGl0IHRvIGEgc2luZ2xlLWxldmVsIG1vZGVsLiBUbyBmaXQgYSBzaW5nbGUtbGV2ZWwgbW9kZWwsIHdlIHR5cGU6DQoNCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9Rn0NCg0Kc2luZ2xlIDwtIGxtKGtzNHN0YW5kIH4gMSAsIGRhdGEgPSB2YWx1ZWFkZGVkKQ0KDQpzdW1tYXJ5KHNpbmdsZSkNCg0KYGBgDQoNClRoZXNlIHJlc3VsdHMgYXJlIG5vdCB2ZXJ5IGludGVyZXN0aW5nIGluIHRoZW1zZWx2ZXMsIHNvIHdlIG1vdmUgb24gZXh0cmFjdCB0aGUgbG9nbGlrZWxpaG9vZCBhbmQgY29tcGFyZSB0byB0aGUgTUxNLg0KDQpgYGB7ciwgd2FybmluZz1GLCBtZXNzYWdlPUZ9DQoNCkwxIDwtIGFzLm51bWVyaWMobG9nTGlrKHNpbmdsZSkpICMgc3RvcmUgdGhpcyBhcyBudW1lcmljYWwgdG8gcmUtdXNlDQpMMiA8LSBhcy5udW1lcmljKGxvZ0xpayhtMCkpDQoNCihEIDwtIDIqKEwyLUwxKSkgIyB0aGlzIGlzIHRoZSBkZXZpYW5jZSwgd2UgcHV0IGl0IHdpdGhpbiBicmFja2V0cyB0byBwcmludCBpdCBpbW1lZGlhdGVseQ0KDQpwY2hpc3EocT1ELCBkZj0xLCBsb3dlci50YWlsPUYpICMgVG8gZmluZCB0aGUgcC12YWx1ZQ0KDQpgYGANCg0KIyMjIFF1ZXN0aW9uDQoNCjMuMS4gSXMgdGhlIGFkZGl0aW9uIG9mIHRoZSBzY2hvb2wgbGV2ZWwgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudD8NCg0KKipBbnN3ZXI6KiogWWVzIGl0IGlzISBFdmVuIGlmIHlvdSBoYWRuJ3QgZG9uZSB0aGUgbG9nbGlrZWxpaG9vZCB0ZXN0LCB0aGUgVlBDIG9mIDI0JSBpcyBzdHJvbmcgZXZpZGVuY2Ugb2YgdGhlIHJlbGV2YW5jZSBvZiBzY2hvb2wgZWZmZWN0cy4NCg0KMy4yLiBXaGF0IGRvZXMgdGhpcyBtZWFuIGluIHByYWN0aWNlPw0KDQoqKkFuc3dlcjoqKiBJdCBtZWFucyB0aGF0IGl0IGlzIGV4dHJlbWVseSBpbXBvcnRhbnQgdG8gY29udHJvbCBmb3IgdGhlIHJhdGhlciBsYXJnZSB2YXJpYWJpbGl0eSBiZXR3ZWVuIHNjaG9vbHMgaW4geW91ciBtb2RlbHMuDQoNCioqKg==