This week, we will use schoolsmoke dataset that we worked with in class. The data are from the Television, School, and Family Smoking Prevention and Cessation Project (Flay et al. 1988; Rabe-Hesketh and Skrondal 2012, chap. 11), a schoolwide anti-smoking intervention where schools were randomly assigned into a schoolwide curricular intervention (cc = 1) or a control condition (cc = 0). 1,600 students are nested within 28 schools.

The dependent variable is the tobacco and health knowledge (THK) scale, which runs from 1-4, with higher numbers suggesting more knowledge about the risks of tobacco. We also have a group-averaged prior measure of THK (gprethk), which represents the average tobacco knowledge score across a given school. Finally, we have a set of 5 items (peer1-peer5) that are individual item responses to a 5-question Likert-type measure of each student’s perceived pressure from peers to smoke. Higher scores on these items suggest higher levels of perceived pressure from peers.

Load Some Packages to Help with the Analysis and Data Management:

suppressPackageStartupMessages(library(tidyverse))
package ‘ggplot2’ was built under R version 3.6.2package ‘tibble’ was built under R version 3.6.2package ‘tidyr’ was built under R version 3.6.2package ‘purrr’ was built under R version 3.6.2package ‘dplyr’ was built under R version 3.6.2
suppressPackageStartupMessages(library(lme4))
package ‘lme4’ was built under R version 3.6.2
suppressPackageStartupMessages(library(psych))

Load and Explore the Data

glimpse(schoolsmoke)
Rows: 1,600
Columns: 10
$ school  <dbl> 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 1…
$ thk     <dbl> 1, 2, 3, 1, 2, 2, 3, 3, 2, 2, 4, 2, 2, 3, 4, 4, 1, 3, 4, 2, 1, 3, 1, 3, 2, 4…
$ prethk  <dbl> 5, 3, 4, 0, 1, 3, 1, 2, 3, 2, 2, 2, 3, 3, 2, 3, 3, 3, 2, 1, 3, 0, 1, 0, 1, 3…
$ cc      <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ gprethk <dbl> 2.153846, 2.153846, 2.153846, 2.153846, 2.153846, 2.153846, 2.153846, 2.1538…
$ peer1   <dbl> 1, 1, 2, 3, 0, 2, 2, 2, 1, 2, 2, 4, 0, 2, 1, 0, 2, 1, 2, 4, 3, 3, 2, 1, 2, 2…
$ peer2   <dbl> 2, 4, 1, 2, 3, 1, 2, 1, 1, 2, 3, 3, 2, 2, 2, 2, 4, 1, 1, 1, 2, 2, 1, 2, 1, 3…
$ peer3   <dbl> 2, 0, 3, 2, 3, 1, 4, 2, 3, 3, 3, 0, 2, 1, 2, 2, 2, 3, 2, 1, 3, 2, 1, 4, 2, 2…
$ peer4   <dbl> 3, 1, 3, 2, 2, 2, 2, 3, 2, 4, 3, 1, 2, 2, 2, 2, 2, 2, 2, 1, 4, 0, 1, 1, 4, 1…
$ peer5   <dbl> 0, 3, 3, 2, 2, 0, 0, 4, 1, 0, 2, 1, 2, 4, 3, 4, 1, 1, 2, 0, 2, 1, 1, 3, 3, 2…

Just a little pre-cleaning here: I want to change the variable cc into a factor. It is coded as 0 and 1, so it can he used as is, but it really is a categorical variable, so I want R to know that when I run my models.

schoolsmoke.1 <- schoolsmoke %>%
  mutate(., cc.factor = as_factor(cc))

glimpse(schoolsmoke.1)  
Rows: 1,600
Columns: 11
$ school    <dbl> 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193,…
$ thk       <dbl> 1, 2, 3, 1, 2, 2, 3, 3, 2, 2, 4, 2, 2, 3, 4, 4, 1, 3, 4, 2, 1, 3, 1, 3, 2,…
$ prethk    <dbl> 5, 3, 4, 0, 1, 3, 1, 2, 3, 2, 2, 2, 3, 3, 2, 3, 3, 3, 2, 1, 3, 0, 1, 0, 1,…
$ cc        <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ gprethk   <dbl> 2.153846, 2.153846, 2.153846, 2.153846, 2.153846, 2.153846, 2.153846, 2.15…
$ peer1     <dbl> 1, 1, 2, 3, 0, 2, 2, 2, 1, 2, 2, 4, 0, 2, 1, 0, 2, 1, 2, 4, 3, 3, 2, 1, 2,…
$ peer2     <dbl> 2, 4, 1, 2, 3, 1, 2, 1, 1, 2, 3, 3, 2, 2, 2, 2, 4, 1, 1, 1, 2, 2, 1, 2, 1,…
$ peer3     <dbl> 2, 0, 3, 2, 3, 1, 4, 2, 3, 3, 3, 0, 2, 1, 2, 2, 2, 3, 2, 1, 3, 2, 1, 4, 2,…
$ peer4     <dbl> 3, 1, 3, 2, 2, 2, 2, 3, 2, 4, 3, 1, 2, 2, 2, 2, 2, 2, 2, 1, 4, 0, 1, 1, 4,…
$ peer5     <dbl> 0, 3, 3, 2, 2, 0, 0, 4, 1, 0, 2, 1, 2, 4, 3, 4, 1, 1, 2, 0, 2, 1, 1, 3, 3,…
$ cc.factor <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…

See above: the variable cc.factor is just cc converted into a factor, which is great.

Question 1: Calculating Scale Scores and Checking Reliability

Calculate a composite scale score using the 5 peer pressure items (peer1-peer5). Estimate Cronbach’s alpha for this scale and report and interpret the results. Should we incorporate this measure into our analysis going forward?

peer_items <- schoolsmoke.1 %>% 
  select(., peer1:peer5)

alpha(peer_items)
Some items were negatively correlated with the total scale and probably 
should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' option
Some items ( peer3 peer4 ) were negatively correlated with the total scale and 
probably should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' option
NaNs produced

Reliability analysis   
Call: alpha(x = peer_items)

 
ABCDEFGHIJ0123456789
 
 
raw_alpha
<dbl>
std.alpha
<dbl>
G6(smc)
<dbl>
average_r
<dbl>
S/N
<dbl>
ase
<dbl>
mean
<dbl>
-0.07008044-0.06942871-0.05112059-0.01315507-0.06492130.042301821.986875

 lower alpha upper     95% confidence boundaries
-0.15 -0.07 0.01 

 Reliability if an item is dropped:
ABCDEFGHIJ0123456789
 
 
raw_alpha
<dbl>
std.alpha
<dbl>
G6(smc)
<dbl>
average_r
<dbl>
S/N
<dbl>
alpha se
<dbl>
peer1-0.03913683-0.038972919-0.026723214-0.0094665262-0.0375110060.04240944
peer2-0.08177458-0.081228564-0.057324613-0.0191410415-0.0751261730.04416833
peer30.001471130.0019883480.0041327940.00049782930.0019923090.04078108
peer4-0.07196642-0.071719431-0.050868479-0.0170146471-0.0669199690.04375667
peer5-0.08870233-0.088059383-0.061271710-0.0206509625-0.0809325160.04446153

 Item statistics 
ABCDEFGHIJ0123456789
 
 
n
<dbl>
raw.r
<dbl>
std.r
<dbl>
r.cor
<dbl>
r.drop
<dbl>
mean
<dbl>
sd
<dbl>
peer116000.42855590.4251198NaN-0.0382857591.9887501.101423
peer216000.44719660.4517904NaN-0.0085959441.9750001.081715
peer316000.40041080.3976501NaN-0.0671507841.9618751.098829
peer416000.44657590.4459284NaN-0.0155827332.0150001.095114
peer516000.45365140.4559530NaN-0.0039613191.9937501.087175

Non missing response frequency for each item
         0    1    2    3    4 miss
peer1 0.10 0.22 0.38 0.20 0.10    0
peer2 0.11 0.18 0.43 0.18 0.09    0
peer3 0.10 0.23 0.38 0.18 0.10    0
peer4 0.10 0.20 0.40 0.20 0.10    0
peer5 0.10 0.20 0.40 0.20 0.10    0

Wow, this alpha looks terrible! Pretty much 0. I would definitely NOT recommend using these items as a composite scale score for peer pressure. Notice, above, that you get a warning that some items were negatively correlated with the total scale. Sometimes, this happens when items are not reversed. You can add the check.keys=TRUE option to the alpha function to check this. But here, not knowing the individual item stems, and just based on the overall crumminess of the alpha score, I would chalk this up to being a bad scale and move on!

Question 2: Null Model

Treating “thk” as the DV, and “school” as the level-2 clustering variable (we will ignore classroom clustering for now- stay tuned!), estimate a null model. Compute, report, and interpret the ICC, as well as the likelihood ratio test at the bottom of the output. Is it worth conducting MLM on these data?

model.null <- lmer(thk ~  (1|school), REML = FALSE, data = schoolsmoke.1)
summary(model.null)
Linear mixed model fit by maximum likelihood  ['lmerMod']
Formula: thk ~ (1 | school)
   Data: schoolsmoke.1

     AIC      BIC   logLik deviance df.resid 
  4833.0   4849.1  -2413.5   4827.0     1597 

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-1.9039 -0.7734  0.0693  0.9240  1.7430 

Random effects:
 Groups   Name        Variance Std.Dev.
 school   (Intercept) 0.09438  0.3072  
 Residual             1.16219  1.0780  
Number of obs: 1600, groups:  school, 28

Fixed effects:
            Estimate Std. Error t value
(Intercept)  2.60750    0.06538   39.88

We can pull the Level 1 and Level 2 variance estimates from the table above to calculate an ICC:


null.ICC <- 0.09438 /(0.09438  + 1.16219 )
null.ICC
[1] 0.07510923

The estimated ICC was .08. This is above the .05 threshold we typically set for requiring MLM. This means that 8% of the variation in tobacco prevention knowledge occurs between schools, and 98% occurs within schools.

lmerTest::rand(model.null)
ANOVA-like table for random-effects: Single term deletions

Model:
thk ~ (1 | school)
             npar  logLik    AIC   LRT Df Pr(>Chisq)    
<none>          3 -2413.5 4833.0                        
(1 | school)    2 -2445.6 4895.2 64.16  1  1.147e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

The LRT confirms the need for MLM - the model that includes a random intercept for school represents a significant improvement (p<.001) over the model that does not include a random intercept.

Interpret the estimated fixed effect of the intercept in the null model. What is this number measuring- what does it mean?

The intercept in the null model was estimated to be 2.61. In this case, we are measuring the average student score on the tobacco prevention scale, after adjusting for the nesting of students within schools.

Question 3: Adding a Level-1 Covariate

3. Now, add “prethk” as a level one covariate. Interpret the coefficient estimate. Report what happens to the level-1 and level-2 variances of our random terms. Do they go up or down, and by how much? What does this mean?

model.1 <- lmer(thk ~ prethk + (1|school), REML = FALSE, data = schoolsmoke.1)
summary(model.1)
Linear mixed model fit by maximum likelihood  ['lmerMod']
Formula: thk ~ prethk + (1 | school)
   Data: schoolsmoke.1

     AIC      BIC   logLik deviance df.resid 
  4733.5   4755.0  -2362.7   4725.5     1596 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.12273 -0.82727  0.03082  0.83756  2.15165 

Random effects:
 Groups   Name        Variance Std.Dev.
 school   (Intercept) 0.07519  0.2742  
 Residual             1.09321  1.0456  
Number of obs: 1600, groups:  school, 28

Fixed effects:
            Estimate Std. Error t value
(Intercept)  2.15164    0.07414   29.02
prethk       0.21747    0.02122   10.25

Correlation of Fixed Effects:
       (Intr)
prethk -0.598

The estimate for prethk = 0.22, and it is statistically significant (t = 10.25). In practical terms, this means that as a student’s pretest tobacco prevention score increases by 1 unit, we would predict their post score (thk) to increase by about .22 points.

Both the level 1 and level 2 variances decreased at least a bit compared to the null model. The L1 (student) variance decreased from 1.16 to 1.09, and the L2 (school) variance decreased from .09 to about .08. What does this mean? As significant predictors are added to the model, we expect the variance to decrease- predictors explain previously unexplained variance in our outcome, making these estimates smaller.

Question 4: Adding Level-2 Covariates

4. Finally, add “cc” and “gprethk” as level-2 predictors to your model. Interpret the results. Explain how the estimates for prethk and gprethk are related to one another, and also explain what this suggests about the impact of school context on an individual student’s knowledge. Report what happens to the level-1 and level-2 variances of our random terms. Do they go up or down, and by how much?

model.2 <- lmer(thk ~ prethk + cc.factor + gprethk + (1|school), REML = FALSE, data = schoolsmoke.1)
summary(model.2)
Linear mixed model fit by maximum likelihood  ['lmerMod']
Formula: thk ~ prethk + cc.factor + gprethk + (1 | school)
   Data: schoolsmoke.1

     AIC      BIC   logLik deviance df.resid 
  4712.6   4744.9  -2350.3   4700.6     1594 

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.23332 -0.79567  0.02374  0.79254  2.16704 

Random effects:
 Groups   Name        Variance Std.Dev.
 school   (Intercept) 0.01734  0.1317  
 Residual             1.09334  1.0456  
Number of obs: 1600, groups:  school, 28

Fixed effects:
            Estimate Std. Error t value
(Intercept)  1.07609    0.25478   4.224
prethk       0.21260    0.02138   9.944
cc.factor1   0.43075    0.07554   5.702
gprethk      0.41835    0.11930   3.507

Correlation of Fixed Effects:
           (Intr) prethk cc.fc1
prethk      0.000              
cc.factor1 -0.288  0.000       
gprethk    -0.963 -0.179  0.148

The estimates for cc (t = 5.70) and gprethk (t = 3.51) are both positive and statisically significant. They are also very similar in magnitude. Students who attend schools that received the tobacco prevention curriculum (cc = 1) are predicted to have tobacco prevention knowledge scores that are about .43 points higher compared to students who attend schools that did not receive the curriculum. Students who attend schools that have one unit higher school average tobacco prevention scores (maybe a stronger school culture around tobacco prevention) are predicted to score about .42 points higher on their individual thk score.

This suggests that school context may be quite important in preventing tobacco use. Schools with prevention curricula, as well as schools where students on average tend to know more about tobacco prevention, both seem to have a positive impact on tobaco prevention knowledge for individual students.

Only the 2 variance decreased compared to model 1. The L1 (student) variance remained at about 1.09, and the L2 (school) variance decreased from .09 to about .02. This is a significant decrease in school level variability (that’s a good thing). Why no change at L1? The addition of L2 predictors like cc can only explain variation at the school level (they have no within-school variability).

Using the modelsummary and broom.mixed Packages to Organize Your Results:

library(modelsummary)
package ‘modelsummary’ was built under R version 3.6.2
Attaching package: ‘modelsummary’

The following object is masked from ‘package:psych’:

    SD
library(broom.mixed)
package ‘broom.mixed’ was built under R version 3.6.2Package version inconsistency detected.
TMB was built with Matrix version 1.2.18
Current Matrix version is 1.2.17
Please re-install 'TMB' from source using install.packages('TMB', type = 'source') or ask CRAN for a binary version of 'TMB' matching CRAN's 'Matrix' packageRegistered S3 method overwritten by 'broom.mixed':
  method      from 
  tidy.gamlss broom
models <- list(model.null, model.1, model.2)
modelsummary(models, output = "markdown")
Model 1 Model 2 Model 3
(Intercept) 2.607 2.152 1.076
(0.065) (0.074) (0.255)
sd__(Intercept) 0.307 0.274 0.132
sd__Observation 1.078 1.046 1.046
prethk 0.217 0.213
(0.021) (0.021)
cc.factor1 0.431
(0.076)
gprethk 0.418
(0.119)
AIC 4833.0 4733.5 4712.6
BIC 4849.1 4755.0 4744.9
Log.Lik. -2413.500 -2362.747 -2350.308

Not required, but a summary table is a great way to tie everything together!

LS0tCnRpdGxlOiAnTXVsdGlsZXZlbCBNb2RlbGluZywgTW9kdWxlIDQgQ29udGVudCBSZXZpZXcgS2V5JwphdXRob3I6ICdEci4gQnJvZGEnCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClRoaXMgd2Vlaywgd2Ugd2lsbCB1c2Ugc2Nob29sc21va2UgZGF0YXNldCB0aGF0IHdlIHdvcmtlZCB3aXRoIGluIGNsYXNzLiBUaGUgZGF0YSBhcmUgZnJvbSB0aGUgVGVsZXZpc2lvbiwgU2Nob29sLCBhbmQgRmFtaWx5IFNtb2tpbmcgUHJldmVudGlvbiBhbmQgQ2Vzc2F0aW9uIFByb2plY3QgKEZsYXkgZXQgYWwuIDE5ODg7IFJhYmUtSGVza2V0aCBhbmQgU2tyb25kYWwgMjAxMiwgY2hhcC4gMTEpLCBhIHNjaG9vbHdpZGUgYW50aS1zbW9raW5nIGludGVydmVudGlvbiB3aGVyZSBzY2hvb2xzIHdlcmUgcmFuZG9tbHkgYXNzaWduZWQgaW50byBhIHNjaG9vbHdpZGUgY3VycmljdWxhciBpbnRlcnZlbnRpb24gKGBjY2AgPSAxKSBvciBhIGNvbnRyb2wgY29uZGl0aW9uIChgY2NgID0gMCkuIDEsNjAwIHN0dWRlbnRzIGFyZSBuZXN0ZWQgd2l0aGluIDI4IHNjaG9vbHMuCgpUaGUgZGVwZW5kZW50IHZhcmlhYmxlIGlzIHRoZSB0b2JhY2NvIGFuZCBoZWFsdGgga25vd2xlZGdlIChUSEspIHNjYWxlLCB3aGljaCBydW5zIGZyb20gMS00LCB3aXRoIGhpZ2hlciBudW1iZXJzIHN1Z2dlc3RpbmcgbW9yZSBrbm93bGVkZ2UgYWJvdXQgdGhlIHJpc2tzIG9mIHRvYmFjY28uIFdlIGFsc28gaGF2ZSBhIGdyb3VwLWF2ZXJhZ2VkIHByaW9yIG1lYXN1cmUgb2YgVEhLIChgZ3ByZXRoa2ApLCB3aGljaCByZXByZXNlbnRzIHRoZSBhdmVyYWdlIHRvYmFjY28ga25vd2xlZGdlIHNjb3JlIGFjcm9zcyBhIGdpdmVuIHNjaG9vbC4gRmluYWxseSwgd2UgaGF2ZSBhIHNldCBvZiA1IGl0ZW1zIChgcGVlcjFgLWBwZWVyNWApIHRoYXQgYXJlIGluZGl2aWR1YWwgaXRlbSByZXNwb25zZXMgdG8gYSA1LXF1ZXN0aW9uIExpa2VydC10eXBlIG1lYXN1cmUgb2YgZWFjaCBzdHVkZW504oCZcyBwZXJjZWl2ZWQgcHJlc3N1cmUgZnJvbSBwZWVycyB0byBzbW9rZS4gSGlnaGVyIHNjb3JlcyBvbiB0aGVzZSBpdGVtcyBzdWdnZXN0IGhpZ2hlciBsZXZlbHMgb2YgcGVyY2VpdmVkIHByZXNzdXJlIGZyb20gcGVlcnMuCgojIExvYWQgU29tZSBQYWNrYWdlcyB0byBIZWxwIHdpdGggdGhlIEFuYWx5c2lzIGFuZCBEYXRhIE1hbmFnZW1lbnQ6CmBgYHtyfQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShsbWU0KSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkocHN5Y2gpKQoKYGBgCgojIExvYWQgYW5kIEV4cGxvcmUgdGhlIERhdGEKYGBge3J9CgpzY2hvb2xzbW9rZSA8LSBoYXZlbjo6cmVhZF9kdGEoInNjaG9vbHNtb2tlLmR0YSIpCmdsaW1wc2Uoc2Nob29sc21va2UpCgpgYGAKCkp1c3QgYSBsaXR0bGUgcHJlLWNsZWFuaW5nIGhlcmU6IEkgd2FudCB0byBjaGFuZ2UgdGhlIHZhcmlhYmxlIGBjY2AgaW50byBhIGZhY3Rvci4gSXQgaXMgY29kZWQgYXMgMCBhbmQgMSwgc28gaXQgY2FuIGhlIHVzZWQgYXMgaXMsIGJ1dCBpdCByZWFsbHkgaXMgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSwgc28gSSB3YW50IFIgdG8ga25vdyB0aGF0IHdoZW4gSSBydW4gbXkgbW9kZWxzLgoKYGBge3J9CnNjaG9vbHNtb2tlLjEgPC0gc2Nob29sc21va2UgJT4lCiAgbXV0YXRlKC4sIGNjLmZhY3RvciA9IGFzX2ZhY3RvcihjYykpCgpnbGltcHNlKHNjaG9vbHNtb2tlLjEpICAKYGBgCgpTZWUgYWJvdmU6IHRoZSB2YXJpYWJsZSBgY2MuZmFjdG9yYCBpcyBqdXN0IGBjY2AgY29udmVydGVkIGludG8gYSBmYWN0b3IsIHdoaWNoIGlzIGdyZWF0LgoKIyBRdWVzdGlvbiAxOiBDYWxjdWxhdGluZyBTY2FsZSBTY29yZXMgYW5kIENoZWNraW5nIFJlbGlhYmlsaXR5CgpDYWxjdWxhdGUgYSBjb21wb3NpdGUgc2NhbGUgc2NvcmUgdXNpbmcgdGhlIDUgcGVlciBwcmVzc3VyZSBpdGVtcyAocGVlcjEtcGVlcjUpLiBFc3RpbWF0ZSBDcm9uYmFjaOKAmXMgYWxwaGEgZm9yIHRoaXMgc2NhbGUgYW5kIHJlcG9ydCBhbmQgaW50ZXJwcmV0IHRoZSByZXN1bHRzLiBTaG91bGQgd2UgaW5jb3Jwb3JhdGUgdGhpcyBtZWFzdXJlIGludG8gb3VyIGFuYWx5c2lzIGdvaW5nIGZvcndhcmQ/CgpgYGB7cn0KcGVlcl9pdGVtcyA8LSBzY2hvb2xzbW9rZS4xICU+JSAKICBzZWxlY3QoLiwgcGVlcjE6cGVlcjUpCgphbHBoYShwZWVyX2l0ZW1zKQpgYGAKCldvdywgdGhpcyBhbHBoYSBsb29rcyB0ZXJyaWJsZSEgUHJldHR5IG11Y2ggMC4gSSB3b3VsZCBkZWZpbml0ZWx5IE5PVCByZWNvbW1lbmQgdXNpbmcgdGhlc2UgaXRlbXMgYXMgYSBjb21wb3NpdGUgc2NhbGUgc2NvcmUgZm9yIHBlZXIgcHJlc3N1cmUuIE5vdGljZSwgYWJvdmUsIHRoYXQgeW91IGdldCBhIHdhcm5pbmcgdGhhdCBzb21lIGl0ZW1zIHdlcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggdGhlIHRvdGFsIHNjYWxlLiBTb21ldGltZXMsIHRoaXMgaGFwcGVucyB3aGVuIGl0ZW1zIGFyZSBub3QgcmV2ZXJzZWQuIFlvdSBjYW4gYWRkIHRoZSBgY2hlY2sua2V5cz1UUlVFYCBvcHRpb24gdG8gdGhlIGBhbHBoYWAgZnVuY3Rpb24gdG8gY2hlY2sgdGhpcy4gQnV0IGhlcmUsIG5vdCBrbm93aW5nIHRoZSBpbmRpdmlkdWFsIGl0ZW0gc3RlbXMsIGFuZCBqdXN0IGJhc2VkIG9uIHRoZSBvdmVyYWxsIGNydW1taW5lc3Mgb2YgdGhlIGFscGhhIHNjb3JlLCBJIHdvdWxkIGNoYWxrIHRoaXMgdXAgdG8gYmVpbmcgYSBiYWQgc2NhbGUgYW5kIG1vdmUgb24hCgojIFF1ZXN0aW9uIDI6IE51bGwgTW9kZWwKCipUcmVhdGluZyDigJx0aGvigJ0gYXMgdGhlIERWLCBhbmQg4oCcc2Nob29s4oCdIGFzIHRoZSBsZXZlbC0yIGNsdXN0ZXJpbmcgdmFyaWFibGUgKHdlIHdpbGwgaWdub3JlIGNsYXNzcm9vbSBjbHVzdGVyaW5nIGZvciBub3ctIHN0YXkgdHVuZWQhKSwgZXN0aW1hdGUgYSBudWxsIG1vZGVsLiBDb21wdXRlLCByZXBvcnQsIGFuZCBpbnRlcnByZXQgdGhlIElDQywgYXMgd2VsbCBhcyB0aGUgbGlrZWxpaG9vZCByYXRpbyB0ZXN0IGF0IHRoZSBib3R0b20gb2YgdGhlIG91dHB1dC4gIElzIGl0IHdvcnRoIGNvbmR1Y3RpbmcgTUxNIG9uIHRoZXNlIGRhdGE/KgoKYGBge3J9Cm1vZGVsLm51bGwgPC0gbG1lcih0aGsgfiAgKDF8c2Nob29sKSwgUkVNTCA9IEZBTFNFLCBkYXRhID0gc2Nob29sc21va2UuMSkKc3VtbWFyeShtb2RlbC5udWxsKQpgYGAgIAoKV2UgY2FuIHB1bGwgdGhlIExldmVsIDEgYW5kIExldmVsIDIgdmFyaWFuY2UgZXN0aW1hdGVzIGZyb20gdGhlIHRhYmxlIGFib3ZlIHRvIGNhbGN1bGF0ZSBhbiBJQ0M6CgpgYGB7cn0KCm51bGwuSUNDIDwtIDAuMDk0MzggLygwLjA5NDM4ICArIDEuMTYyMTkgKQpudWxsLklDQwoKYGBgCgpUaGUgZXN0aW1hdGVkIElDQyB3YXMgLjA4LiBUaGlzIGlzIGFib3ZlIHRoZSAuMDUgdGhyZXNob2xkIHdlIHR5cGljYWxseSBzZXQgZm9yIHJlcXVpcmluZyBNTE0uIFRoaXMgbWVhbnMgdGhhdCA4JSBvZiB0aGUgdmFyaWF0aW9uIGluIHRvYmFjY28gcHJldmVudGlvbiBrbm93bGVkZ2Ugb2NjdXJzIGJldHdlZW4gc2Nob29scywgYW5kIDk4JSBvY2N1cnMgd2l0aGluIHNjaG9vbHMuCgpgYGB7cn0KbG1lclRlc3Q6OnJhbmQobW9kZWwubnVsbCkKYGBgCgpUaGUgTFJUIGNvbmZpcm1zIHRoZSBuZWVkIGZvciBNTE0gLSB0aGUgbW9kZWwgdGhhdCBpbmNsdWRlcyBhIHJhbmRvbSBpbnRlcmNlcHQgZm9yIHNjaG9vbCByZXByZXNlbnRzIGEgc2lnbmlmaWNhbnQgaW1wcm92ZW1lbnQgKCpwKjwuMDAxKSBvdmVyIHRoZSBtb2RlbCB0aGF0IGRvZXMgbm90IGluY2x1ZGUgYSByYW5kb20gaW50ZXJjZXB0LgoKKkludGVycHJldCB0aGUgZXN0aW1hdGVkIGZpeGVkIGVmZmVjdCBvZiB0aGUgaW50ZXJjZXB0IGluIHRoZSBudWxsIG1vZGVsLiAgV2hhdCBpcyB0aGlzIG51bWJlciBtZWFzdXJpbmctIHdoYXQgZG9lcyBpdCBtZWFuPyoKClRoZSBpbnRlcmNlcHQgaW4gdGhlIG51bGwgbW9kZWwgd2FzIGVzdGltYXRlZCB0byBiZSAyLjYxLiBJbiB0aGlzIGNhc2UsIHdlIGFyZSBtZWFzdXJpbmcgdGhlIGF2ZXJhZ2Ugc3R1ZGVudCBzY29yZSBvbiB0aGUgdG9iYWNjbyBwcmV2ZW50aW9uIHNjYWxlLCBhZnRlciBhZGp1c3RpbmcgZm9yIHRoZSBuZXN0aW5nIG9mIHN0dWRlbnRzIHdpdGhpbiBzY2hvb2xzLgogIAojIFF1ZXN0aW9uIDM6IEFkZGluZyBhIExldmVsLTEgQ292YXJpYXRlCgoqMy4gIE5vdywgYWRkIOKAnHByZXRoa+KAnSBhcyBhIGxldmVsIG9uZSBjb3ZhcmlhdGUuIEludGVycHJldCB0aGUgY29lZmZpY2llbnQgZXN0aW1hdGUuIFJlcG9ydCB3aGF0IGhhcHBlbnMgdG8gdGhlIGxldmVsLTEgYW5kIGxldmVsLTIgdmFyaWFuY2VzIG9mIG91ciByYW5kb20gdGVybXMuIERvIHRoZXkgZ28gdXAgb3IgZG93biwgYW5kIGJ5IGhvdyBtdWNoPyBXaGF0IGRvZXMgdGhpcyBtZWFuPyoKCmBgYHtyfQptb2RlbC4xIDwtIGxtZXIodGhrIH4gcHJldGhrICsgKDF8c2Nob29sKSwgUkVNTCA9IEZBTFNFLCBkYXRhID0gc2Nob29sc21va2UuMSkKc3VtbWFyeShtb2RlbC4xKQpgYGAKClRoZSBlc3RpbWF0ZSBmb3IgYHByZXRoa2AgPSAwLjIyLCBhbmQgaXQgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAoKnQqID0gMTAuMjUpLiBJbiBwcmFjdGljYWwgdGVybXMsIHRoaXMgbWVhbnMgdGhhdCBhcyBhIHN0dWRlbnQncyBwcmV0ZXN0IHRvYmFjY28gcHJldmVudGlvbiBzY29yZSBpbmNyZWFzZXMgYnkgMSB1bml0LCB3ZSB3b3VsZCBwcmVkaWN0IHRoZWlyIHBvc3Qgc2NvcmUgKGB0aGtgKSB0byBpbmNyZWFzZSBieSBhYm91dCAuMjIgcG9pbnRzLiAKCkJvdGggdGhlIGxldmVsIDEgYW5kIGxldmVsIDIgdmFyaWFuY2VzIGRlY3JlYXNlZCBhdCBsZWFzdCBhIGJpdCBjb21wYXJlZCB0byB0aGUgbnVsbCBtb2RlbC4gVGhlIEwxIChzdHVkZW50KSB2YXJpYW5jZSBkZWNyZWFzZWQgZnJvbSAxLjE2IHRvIDEuMDksIGFuZCB0aGUgTDIgKHNjaG9vbCkgdmFyaWFuY2UgZGVjcmVhc2VkIGZyb20gLjA5IHRvIGFib3V0IC4wOC4gV2hhdCBkb2VzIHRoaXMgbWVhbj8gQXMgc2lnbmlmaWNhbnQgcHJlZGljdG9ycyBhcmUgYWRkZWQgdG8gdGhlIG1vZGVsLCB3ZSBleHBlY3QgdGhlIHZhcmlhbmNlIHRvIGRlY3JlYXNlLSBwcmVkaWN0b3JzIGV4cGxhaW4gcHJldmlvdXNseSB1bmV4cGxhaW5lZCB2YXJpYW5jZSBpbiBvdXIgb3V0Y29tZSwgbWFraW5nIHRoZXNlIGVzdGltYXRlcyBzbWFsbGVyLgoKIyBRdWVzdGlvbiA0OiBBZGRpbmcgTGV2ZWwtMiBDb3ZhcmlhdGVzCgoqNC4gIEZpbmFsbHksIGFkZCDigJxjY+KAnSBhbmQg4oCcZ3ByZXRoa+KAnSBhcyBsZXZlbC0yIHByZWRpY3RvcnMgdG8geW91ciBtb2RlbC4gSW50ZXJwcmV0IHRoZSByZXN1bHRzLiBFeHBsYWluIGhvdyB0aGUgZXN0aW1hdGVzIGZvciBwcmV0aGsgYW5kIGdwcmV0aGsgYXJlIHJlbGF0ZWQgdG8gb25lIGFub3RoZXIsIGFuZCBhbHNvIGV4cGxhaW4gd2hhdCB0aGlzIHN1Z2dlc3RzIGFib3V0IHRoZSBpbXBhY3Qgb2Ygc2Nob29sIGNvbnRleHQgb24gYW4gaW5kaXZpZHVhbCBzdHVkZW504oCZcyBrbm93bGVkZ2UuIFJlcG9ydCB3aGF0IGhhcHBlbnMgdG8gdGhlIGxldmVsLTEgYW5kIGxldmVsLTIgdmFyaWFuY2VzIG9mIG91ciByYW5kb20gdGVybXMuIERvIHRoZXkgZ28gdXAgb3IgZG93biwgYW5kIGJ5IGhvdyBtdWNoPyoKCmBgYHtyfQptb2RlbC4yIDwtIGxtZXIodGhrIH4gcHJldGhrICsgY2MuZmFjdG9yICsgZ3ByZXRoayArICgxfHNjaG9vbCksIFJFTUwgPSBGQUxTRSwgZGF0YSA9IHNjaG9vbHNtb2tlLjEpCnN1bW1hcnkobW9kZWwuMikKYGBgCgpUaGUgZXN0aW1hdGVzIGZvciBgY2NgICgqdCogPSA1LjcwKSBhbmQgYGdwcmV0aGtgICgqdCogPSAzLjUxKSBhcmUgYm90aCBwb3NpdGl2ZSBhbmQgc3RhdGlzaWNhbGx5IHNpZ25pZmljYW50LiBUaGV5IGFyZSBhbHNvIHZlcnkgc2ltaWxhciBpbiBtYWduaXR1ZGUuIFN0dWRlbnRzIHdobyBhdHRlbmQgc2Nob29scyB0aGF0IHJlY2VpdmVkIHRoZSB0b2JhY2NvIHByZXZlbnRpb24gY3VycmljdWx1bSAoYGNjYCA9IDEpIGFyZSBwcmVkaWN0ZWQgdG8gaGF2ZSB0b2JhY2NvIHByZXZlbnRpb24ga25vd2xlZGdlIHNjb3JlcyB0aGF0IGFyZSBhYm91dCAuNDMgcG9pbnRzIGhpZ2hlciBjb21wYXJlZCB0byBzdHVkZW50cyB3aG8gYXR0ZW5kIHNjaG9vbHMgdGhhdCBkaWQgbm90IHJlY2VpdmUgdGhlIGN1cnJpY3VsdW0uIFN0dWRlbnRzIHdobyBhdHRlbmQgc2Nob29scyB0aGF0IGhhdmUgb25lIHVuaXQgaGlnaGVyIHNjaG9vbCBhdmVyYWdlIHRvYmFjY28gcHJldmVudGlvbiBzY29yZXMgKG1heWJlIGEgc3Ryb25nZXIgc2Nob29sIGN1bHR1cmUgYXJvdW5kIHRvYmFjY28gcHJldmVudGlvbikgYXJlIHByZWRpY3RlZCB0byBzY29yZSBhYm91dCAuNDIgcG9pbnRzIGhpZ2hlciBvbiB0aGVpciBpbmRpdmlkdWFsIGB0aGtgIHNjb3JlLgoKVGhpcyBzdWdnZXN0cyB0aGF0IHNjaG9vbCBjb250ZXh0IG1heSBiZSBxdWl0ZSBpbXBvcnRhbnQgaW4gcHJldmVudGluZyB0b2JhY2NvIHVzZS4gU2Nob29scyB3aXRoIHByZXZlbnRpb24gY3VycmljdWxhLCBhcyB3ZWxsIGFzIHNjaG9vbHMgd2hlcmUgc3R1ZGVudHMgb24gYXZlcmFnZSB0ZW5kIHRvIGtub3cgbW9yZSBhYm91dCB0b2JhY2NvIHByZXZlbnRpb24sIGJvdGggc2VlbSB0byBoYXZlIGEgcG9zaXRpdmUgaW1wYWN0IG9uIHRvYmFjbyBwcmV2ZW50aW9uIGtub3dsZWRnZSBmb3IgaW5kaXZpZHVhbCBzdHVkZW50cy4KCk9ubHkgdGhlIDIgdmFyaWFuY2UgZGVjcmVhc2VkIGNvbXBhcmVkIHRvIG1vZGVsIDEuIFRoZSBMMSAoc3R1ZGVudCkgdmFyaWFuY2UgcmVtYWluZWQgYXQgYWJvdXQgMS4wOSwgYW5kIHRoZSBMMiAoc2Nob29sKSB2YXJpYW5jZSBkZWNyZWFzZWQgZnJvbSAuMDkgdG8gYWJvdXQgLjAyLiBUaGlzIGlzIGEgc2lnbmlmaWNhbnQgZGVjcmVhc2UgaW4gc2Nob29sIGxldmVsIHZhcmlhYmlsaXR5ICh0aGF0J3MgYSBnb29kIHRoaW5nKS4gV2h5IG5vIGNoYW5nZSBhdCBMMT8gVGhlIGFkZGl0aW9uIG9mIEwyIHByZWRpY3RvcnMgbGlrZSBgY2NgIGNhbiBvbmx5IGV4cGxhaW4gdmFyaWF0aW9uIGF0IHRoZSBzY2hvb2wgbGV2ZWwgKHRoZXkgaGF2ZSBubyB3aXRoaW4tc2Nob29sIHZhcmlhYmlsaXR5KS4KCiMgVXNpbmcgdGhlIGBtb2RlbHN1bW1hcnlgIGFuZCBgYnJvb20ubWl4ZWRgIFBhY2thZ2VzIHRvIE9yZ2FuaXplIFlvdXIgUmVzdWx0czoKYGBge3J9CmxpYnJhcnkobW9kZWxzdW1tYXJ5KQpsaWJyYXJ5KGJyb29tLm1peGVkKQoKbW9kZWxzIDwtIGxpc3QobW9kZWwubnVsbCwgbW9kZWwuMSwgbW9kZWwuMikKbW9kZWxzdW1tYXJ5KG1vZGVscywgb3V0cHV0ID0gIm1hcmtkb3duIikKYGBgCgpOb3QgcmVxdWlyZWQsIGJ1dCBhIHN1bW1hcnkgdGFibGUgaXMgYSBncmVhdCB3YXkgdG8gdGllIGV2ZXJ5dGhpbmcgdG9nZXRoZXIhCgo=