1 Background Information

Mixed models are especially useful when working with a within-subjects design because it works around the ANOVA assumption that data points are independent of one another. In a within subjects design, one participant provides multiple data points and those data will correlate with one another because they come from the same participant. Therefore, using a mixed model allows you to systematically account for item-level variability (within subjects) and subject-level variability (within groups).

When to Use? – Studies that obtain multiple measurements over time (longitudinal, time-series) or multiple trials per participant (within subjects) lend themselves well to mixed model analyses.

The following example will illustrate the logic behind mixed effects models.

1.1 Example: National Pizza Study

Let’s say that we are interested in examining the effect of pizza consumption on people’s moods. Each participant provided an average number of pizzas consumed, and measurements are collected at 15 timepoints

  • Hypothetical sample size, n = 30
  • DV: Mood rating (scale)
  • IV1: Pizza consumption
  • IV2: Time points (Weeks, 1-10)

Here is some hypothetical data (code used to generate data can be found here):

##   time subject    pizza      mood
## 1    1       1 26.01455  76.58837
## 2    2       1 36.27042 104.24614
## 3    3       1 33.86071  99.88899
## 4    4       1 28.90242  85.24618
## 5    5       1 27.87595  82.93232
## 6    6       1 27.90510  83.87483

NOTE - This is a within-subjects study. All participants are providing multiple measurements.

1.2 Important Terminology

Below are some important terms to know for understanding the statistical concepts used in mixed models:

1.2.1 Crossed & Nested Designs

Crossed designs refer to the within-subject variables (i.e. timepoint, condition, etc.). Crossed designs occur when multiple measurements are associated with multiple grouping variables. In a completely crossed design, all subjects provide responses for all conditions/time-points.

  • Pizza study: We have subjects providing responses at 10 time points. Thus, we have a crossed design.

Nested designs refer to the between-subject variable. Generally this is a higher-level variable that subjects or items are grouped under.

  • Pizza study: Not nested.

1.2.2 Fixed v. Random Effects

Fixed effects are, essentially, your predictor variables. This is the effect you are interested in after accounting for random variability (hence, fixed).

  • Pizza study: The fixed effects are PIZZA consumption and TIME, because we’re interested in the effect of pizza consumption on MOOD, and if this effect varies over TIME.

Random effects are best defined as noise in your data. These are effects that arise from uncontrollable variability within the sample. Subject level variability is often a random effect.

  • Pizza study: Controlling for random effects of subject, pizza consumption, and effect of time on subject, all of which vary across participants.

NOTE - Predictor variables can be both fixed (i.e. causing a main effect/interaction) and random (i.e. causing variance/variability in responses). When building your models, you can treat your predictor as a fixed & random factor.

1.2.3 Slopes v. Intercepts:

To better understand slopes and intercepts it maybe helpful to imagine plotting the relationship between the IVs and DV for each subject.

Intercepts: The baseline relationship between IV & DV. Fixed effects are plotted as intercepts to reflect the baseline level of your DV.

  • Random intercepts: Variability in baseline measurements

    • Pizza Study: Different baseline levels of pizza consumption across subjects
  • Fixed intercepts: Baseline variance is not affected

    • Pizza study:

Slope: The strength of the relationship between IV & DV (controlling for randomness), which represent random effects. You should expect to see differences in the slopes of your random factors.

  • Pizza study: The strength of the relationship between pizza consumption and mood will vary from person to person, resulting in random slopes per subject. Because subjects start at

Note: If 2 variables share a lot of variance, the random intercepts and slopes may be correlated with one another. This can be accounted for in random structures as well.

Hypotheses For Study Random effects: - “Subjects” will have their own intercepts. - Subjects’ slope will vary by pizza consumption intercepts, and by timepoint intercepts. - The slopes and intercepts of pizza consumption and time will be correlated (shared variance) Fixed effects: - Expecting there to be an overall main effect of pizza consumption over time. - Expecting interaction such that more pizza over time predicts mood.

2 Setting up data in R

  • Coding: Recode your variable (mean-centered, effects) as best suited for your data.
  • Long Format : Refer to TidyR chapter
  • Packages: Make sure you have the following packages downloaded:
library (lmerTest) # Mixed model package by Douglas Bates, comes w/ pvalues! 
library (texreg) #Helps us make tables of the mixed models
library (afex) # Easy ANOVA package to compare model fits
library (plyr) # Data manipulator package
library (ggplot2) # GGplot package for visualizing data

3 Modeling Procedure

Modeling conventions differ by field, but this example will begin by fitting the null model first, then building up hierarchically.

3.1 Random effects structure

The null model will be fit to the maximal likelihood estimate. The random effects structure reflects YOUR understanding of where to expect variance, and how nested data will interact with that variance. The general syntax is as follows:

(1 + IV | unit level)  
(1 + IV.1*IV.2 | unit level)

#or

(0 + IV | unit level)
(0 + IV.1*IV.2 | unit level)

When there is a 1 before the line, you are accounting for random intercepts (varying baseline levels) in your variable. A O indicates the variable has a fixed intercept and not a random one. These are a few hypothetical random effects structures:

  • (1| subject) = Random intercepts and slopes for subjects (different baselines, different average effect per subject).
  • (1 + pizza |subject) = The effect of pizza will vary between subjects. Random intercepts for pizza consumption, random slopes for subjects influenced by pizza consumption.
  • (1 + pizza | subject) + (0 + time| subject) = Subjects have random intercepts and slopes as influenced by pizza consumption. Time slopes can vary as function of the subject, but variance between pizza consumption and time as independent
  • (1 + pizza + time | subject) = Same as above, but variance between pizza consumption and time are SHARED (pizza consumption has relationship with time that varies by subject).
  • `(1 + pizza * time | subject) = Each subject can have their intercept, random slopes influenced by pizza and time, and their interaction between pizza and time. IMPORTANTLY, all random slopes and intercepts can be correlated.

3.1.1 Fitting Best Random Effects Structure

The lmer package can be used for modeling, and the general syntax is as follows: ``` modelname <- lmer (dv ~ 1 + IV +(randomeffects), data = data.name, REML = FALSE)

```

You can name each model whatever you want, but note that the name of the dataframe containing your data is specified in each model. Keep REML = FALSE.

First, however, we need to specify the random effects term that best fits the data. Try out different structures, and use the anova function to find the best fitting random effects structure. This function compares the fit of the model to see how fit has improved with additional items. You can also visualize your data to see what fits. ### Insert ggplot2 reference.

nullmodel1 <- lmer( mood ~ 1 + (1|subject), data = pizzadata, REML=FALSE)
nullmodel2 <- lmer( mood ~ 1 + (1 + pizza |subject), data = pizzadata, REML=FALSE)
nullmodel3 <- lmer( mood ~ 1 + (1 + pizza * time |subject), data = pizzadata, REML=FALSE)
## Warning in optwrap(optimizer, devfun, getStart(start, rho$lower, rho$pp), :
## convergence code 1 from bobyqa: bobyqa -- maximum number of function
## evaluations exceeded
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control
## $checkConv, : Model failed to converge with max|grad| = 4.09077 (tol =
## 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : Model is nearly unidentifiable: very large eigenvalue
##  - Rescale variables?;Model is nearly unidentifiable: large eigenvalue ratio
##  - Rescale variables?
anova (nullmodel1, nullmodel2, nullmodel3)
## Data: pizzadata
## Models:
## object: mood ~ 1 + (1 | subject)
## ..1: mood ~ 1 + (1 + pizza | subject)
## ..2: mood ~ 1 + (1 + pizza * time | subject)
##        Df    AIC    BIC   logLik deviance   Chisq Chi Df Pr(>Chisq)    
## object  3 2564.3 2575.4 -1279.15   2558.3                              
## ..1     5 1945.2 1963.7  -967.59   1935.2 623.116      2  < 2.2e-16 ***
## ..2    12 1923.2 1967.6  -949.58   1899.2  36.027      7  7.166e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Refer to the p-values in the output to see whether there was an improvement in fit. Because there was an improvement in between model 1 and model 2, but NO improvement between model 2 and model 3, we can proceed using the best fit model, nullmodel2, as our random effects structure for the rest of the analyses.

3.2 Fixed effects

Specific predictors can now be introduced into our model by specifying the DV followed by the predictor, random effects, and the dataframe.

Model 1 - Pizza consumption predict mood (main effect):

m1=lmer(mood ~ pizza + (1 + pizza + time |subject), data=pizzadata, REML = FALSE)
summary(m1)
## Linear mixed model fit by maximum likelihood t-tests use Satterthwaite
##   approximations to degrees of freedom [lmerMod]
## Formula: mood ~ pizza + (1 + pizza + time | subject)
##    Data: pizzadata
## 
##      AIC      BIC   logLik deviance df.resid 
##   1848.7   1882.0   -915.4   1830.7      291 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.8112 -0.2712  0.0753  0.3161  2.3965 
## 
## Random effects:
##  Groups   Name        Variance  Std.Dev. Corr       
##  subject  (Intercept)  8.492055 2.91411             
##           pizza        0.227560 0.47703  -0.43      
##           time         0.003765 0.06136  -0.73 -0.30
##  Residual             16.177224 4.02209             
## Number of obs: 300, groups:  subject, 30
## 
## Fixed effects:
##             Estimate Std. Error      df t value Pr(>|t|)    
## (Intercept)  -3.0745     1.5974 34.1100  -1.925   0.0626 .  
## pizza         3.0179     0.1007 30.6000  29.975   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##       (Intr)
## pizza -0.608

This model appears to show pizza consumption as a positive predictor of mood, as indicated by a posi

Random effects:

  • SD reflects the amount of variation. Check correlation between intercept and slope (i.e. if intercept increases, slope increases).

Fixed effects

  • Check estimates for beta value – time has a significant effect, improvement in mood by about 1 point over time.
  • Check correlation of fixed effects – if too high, this may imply multicollinearity

Model 2 – Pizza consumption and timepoints included as predictors of mood.

m2= lmer(mood ~ pizza + time + (1 + pizza + time |subject), data=pizzadata, REML = FALSE)
summary(m2)
## Linear mixed model fit by maximum likelihood t-tests use Satterthwaite
##   approximations to degrees of freedom [lmerMod]
## Formula: mood ~ pizza + time + (1 + pizza + time | subject)
##    Data: pizzadata
## 
##      AIC      BIC   logLik deviance df.resid 
##   1838.7   1875.8   -909.4   1818.7      290 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -2.58338 -0.34750  0.03691  0.27202  2.67350 
## 
## Random effects:
##  Groups   Name        Variance  Std.Dev. Corr       
##  subject  (Intercept) 2.371e+00 1.5398              
##           pizza       2.342e-01 0.4840   -0.85      
##           time        2.788e-04 0.0167    0.28 -0.74
##  Residual             1.562e+01 3.9517              
## Number of obs: 300, groups:  subject, 30
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept)  -0.69151    1.64377  28.43000  -0.421 0.677146    
## pizza         3.00716    0.10126  30.52000  29.698  < 2e-16 ***
## time         -0.28278    0.08025 261.23000  -3.524 0.000502 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##       (Intr) pizza 
## pizza -0.585       
## time  -0.380  0.037
m2= lmer(mood ~ pizza + time + (1 + pizza + time |subject), data=pizzadata, REML = FALSE)
summary(m2)
## Linear mixed model fit by maximum likelihood t-tests use Satterthwaite
##   approximations to degrees of freedom [lmerMod]
## Formula: mood ~ pizza + time + (1 + pizza + time | subject)
##    Data: pizzadata
## 
##      AIC      BIC   logLik deviance df.resid 
##   1838.7   1875.8   -909.4   1818.7      290 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -2.58338 -0.34750  0.03691  0.27202  2.67350 
## 
## Random effects:
##  Groups   Name        Variance  Std.Dev. Corr       
##  subject  (Intercept) 2.371e+00 1.5398              
##           pizza       2.342e-01 0.4840   -0.85      
##           time        2.788e-04 0.0167    0.28 -0.74
##  Residual             1.562e+01 3.9517              
## Number of obs: 300, groups:  subject, 30
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept)  -0.69151    1.64377  28.43000  -0.421 0.677146    
## pizza         3.00716    0.10126  30.52000  29.698  < 2e-16 ***
## time         -0.28278    0.08025 261.23000  -3.524 0.000502 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##       (Intr) pizza 
## pizza -0.585       
## time  -0.380  0.037

Results show significant effects of both pizza consumption and time on mood! Do they interact?

Model 3 – Including an interaction term between pizza consumption and time (pizza consumption varies over time)

m3 = lmer(mood ~ pizza*time + (1 + pizza + time |subject), data=pizzadata, REML = FALSE)
summary(m3)
## Linear mixed model fit by maximum likelihood t-tests use Satterthwaite
##   approximations to degrees of freedom [lmerMod]
## Formula: mood ~ pizza * time + (1 + pizza + time | subject)
##    Data: pizzadata
## 
##      AIC      BIC   logLik deviance df.resid 
##   1838.3   1879.0   -908.1   1816.3      289 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -2.75864 -0.37286  0.05657  0.28274  2.58913 
## 
## Random effects:
##  Groups   Name        Variance  Std.Dev. Corr       
##  subject  (Intercept) 12.354060 3.51483             
##           pizza        0.239391 0.48928  -0.52      
##           time         0.002575 0.05074  -0.82 -0.06
##  Residual             15.272630 3.90802             
## Number of obs: 300, groups:  subject, 30
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept)   4.01103    3.36380 160.29000   1.192   0.2349    
## pizza         2.84985    0.14023  95.05000  20.323   <2e-16 ***
## time         -1.17445    0.54915 266.07000  -2.139   0.0334 *  
## pizza:time    0.03016    0.01833 265.56000   1.645   0.1011    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##            (Intr) pizza  time  
## pizza      -0.811              
## time       -0.877  0.685       
## pizza:time  0.856 -0.686 -0.989

Results show that while pizza consumption and time are still significant main predictors, their interaction term did not reach significance.

3.3 Comparing Model Fit

The ANOVA function allows you to compute Chi-squares between each model to see the improvement in model fit. The effects package should also include p-values in the output.

anova (m1, m2, m3)
## Data: pizzadata
## Models:
## object: mood ~ pizza + (1 + pizza + time | subject)
## ..1: mood ~ pizza + time + (1 + pizza + time | subject)
## ..2: mood ~ pizza * time + (1 + pizza + time | subject)
##        Df    AIC    BIC  logLik deviance   Chisq Chi Df Pr(>Chisq)    
## object  9 1848.7 1882.0 -915.35   1830.7                              
## ..1    10 1838.7 1875.8 -909.37   1818.7 11.9663      1  0.0005417 ***
## ..2    11 1838.3 1879.0 -908.14   1816.3  2.4546      1  0.1171829    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

As you can see by the p-values, while there is an improvement in fit from model 1 to model 2, model 3 did not explain more variance. As such, model 2 appears to be the best fit.

We can now conclude that after controlling for random effects, more pizza consumption does lead to improvements in mood over time, but there is no interaction with time.

This concludes the tutorial on mixed effects models. Below are references for additional information # References Checking assumptions More theory here, here, and here. Effects coding Simulating data

LS0tDQp0aXRsZTogIkNoYXB0ZXIgMTc6IE1peGVkIEVmZmVjdHMgTW9kZWxpbmciDQphdXRob3I6ICJTdXNobWl0YSBTaHJpa2FudGgiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQ0KICAgIGZvbnRzaXplOiA4cHQNCiAgICB0b2M6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQ0KYGBgDQoNCiMgQmFja2dyb3VuZCBJbmZvcm1hdGlvbg0KTWl4ZWQgbW9kZWxzIGFyZSBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIHdvcmtpbmcgd2l0aCBhIHdpdGhpbi1zdWJqZWN0cyBkZXNpZ24gYmVjYXVzZSBpdCB3b3JrcyBhcm91bmQgdGhlIEFOT1ZBIGFzc3VtcHRpb24gdGhhdCBkYXRhIHBvaW50cyBhcmUgaW5kZXBlbmRlbnQgb2YgIG9uZSBhbm90aGVyLiBJbiBhIHdpdGhpbiBzdWJqZWN0cyBkZXNpZ24sIG9uZSBwYXJ0aWNpcGFudCBwcm92aWRlcyBtdWx0aXBsZSBkYXRhIHBvaW50cyBhbmQgdGhvc2UgZGF0YSB3aWxsIGNvcnJlbGF0ZSB3aXRoIG9uZSBhbm90aGVyIGJlY2F1c2UgdGhleSBjb21lIGZyb20gdGhlIHNhbWUgcGFydGljaXBhbnQuIFRoZXJlZm9yZSwgdXNpbmcgYSBtaXhlZCBtb2RlbCBhbGxvd3MgeW91IHRvIHN5c3RlbWF0aWNhbGx5IGFjY291bnQgZm9yIGl0ZW0tbGV2ZWwgdmFyaWFiaWxpdHkgKHdpdGhpbiBzdWJqZWN0cykgYW5kIHN1YmplY3QtbGV2ZWwgdmFyaWFiaWxpdHkgKHdpdGhpbiBncm91cHMpLg0KDQoqKldoZW4gdG8gVXNlPyoqIC0tIFN0dWRpZXMgdGhhdCBvYnRhaW4gbXVsdGlwbGUgbWVhc3VyZW1lbnRzIG92ZXIgdGltZSAobG9uZ2l0dWRpbmFsLCB0aW1lLXNlcmllcykgb3IgbXVsdGlwbGUgdHJpYWxzIHBlciBwYXJ0aWNpcGFudCAod2l0aGluIHN1YmplY3RzKSBsZW5kIHRoZW1zZWx2ZXMgd2VsbCB0byBtaXhlZCBtb2RlbCBhbmFseXNlcy4NCg0KVGhlIGZvbGxvd2luZyBleGFtcGxlIHdpbGwgaWxsdXN0cmF0ZSB0aGUgbG9naWMgYmVoaW5kIG1peGVkIGVmZmVjdHMgbW9kZWxzLg0KDQojIyBFeGFtcGxlOiBOYXRpb25hbCBQaXp6YSBTdHVkeQ0KTGV0J3Mgc2F5IHRoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4gZXhhbWluaW5nIHRoZSBlZmZlY3Qgb2YgcGl6emEgY29uc3VtcHRpb24gb24gcGVvcGxlJ3MgbW9vZHMuIEVhY2ggcGFydGljaXBhbnQgcHJvdmlkZWQgYW4gYXZlcmFnZSBudW1iZXIgb2YgcGl6emFzIGNvbnN1bWVkLCBhbmQgbWVhc3VyZW1lbnRzIGFyZSBjb2xsZWN0ZWQgYXQgMTUgdGltZXBvaW50cyANCg0KLSBIeXBvdGhldGljYWwgc2FtcGxlIHNpemUsICoqbiA9IDMwKioNCi0gKipEVioqOiBNb29kIHJhdGluZyAoc2NhbGUpDQotICoqSVYxKio6IFBpenphIGNvbnN1bXB0aW9uIA0KLSAqKklWMioqOiBUaW1lIHBvaW50cyAoV2Vla3MsIDEtMTApDQoNCkhlcmUgaXMgc29tZSBoeXBvdGhldGljYWwgZGF0YSAoY29kZSB1c2VkIHRvIGdlbmVyYXRlIGRhdGEgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vUkludGVyZXN0ZWQvU0lNVUxBVElPTlNfYW5kX1BST09GUy9ibG9iL21hc3Rlci9BdGhsZXRlcyUyMG1peGVkJTIwZWZmZWN0cykpOiANCg0KYGBge3IgaW5jbHVkZSA9IEZBTFNFfQ0KDQpybShsaXN0ID0gbHMoKSkNCnNldC5zZWVkKDApDQpsaWJyYXJ5KGxtZTQpDQpsaWJyYXJ5KG12dG5vcm0pDQoNCnN1YmplY3RzID0gMzANCnRpbWUgPSAxMA0KIA0KaSA9IDAuMiANCnMgPSAwLjUgDQpyID0gMC41DQpjb3YubWF0cml4MTwtICBtYXRyaXgoYyhpXjIsIHIgKiBpICogcywgciAqIGkgKiBzLCBzXjIpLCBucm93ID0gMiwgYnlyb3cgPSBUKQ0KDQpyZXF1aXJlKG12dG5vcm0pDQpyYW5kb20uZWZmZWN0c19zdWJqZWN0cyA8LSAgcm12bm9ybShzdWJqZWN0cywgbWVhbiA9IGMoMCwgMCksIHNpZ21hID0gY292Lm1hdHJpeDEpDQpzdWJqZWN0cy5kZiA9IGRhdGEuZnJhbWUoc3ViamVjdCAgPSBjKDE6c3ViamVjdHMpKSANCnN1YmplY3RzLmRmJGFscGhhX3N1YmplY3RzID0gMSArIHJhbmRvbS5lZmZlY3RzX3N1YmplY3RzWywgMV0NCnN1YmplY3RzLmRmJGJldGFfc3ViamVjdHMgPSAgMiArIHJhbmRvbS5lZmZlY3RzX3N1YmplY3RzWywgMl0NCg0KaSA9ICAgMC44ICAgDQpzID0gICAwLjIgDQpyID0gLTAuMDEgICANCihjb3YubWF0cml4MiA8LSAgbWF0cml4KGMoaV4yLCByICogaSAqIHMsIHIgKiBpICogcywgc14yKSwgbnJvdyA9IDIsIGJ5cm93ID0gVCkpDQoNCnJhbmRvbS5lZmZlY3RzX3RpbWUgPC0gIHJtdm5vcm0odGltZSwgbWVhbiA9IGMoMCwgMCksIHNpZ21hID0gY292Lm1hdHJpeDIpDQoNCnRpbWUuZGYgPSBkYXRhLmZyYW1lKHRpbWUgID0gYygxOnRpbWUpKSANCnRpbWUuZGYkYWxwaGFfdGltZSAgID0gICAgLTEgKyByYW5kb20uZWZmZWN0c190aW1lWywgMV0NCnRpbWUuZGYkYmV0YV90aW1lICAgID0gICAgIDEgKyByYW5kb20uZWZmZWN0c190aW1lWywgMl0NCnN1bW1hcnkodGltZS5kZiRiZXRhX3RpbWUpIA0Kc2QodGltZS5kZiRiZXRhX3RpbWUpICAgICANCnN1bW1hcnkodGltZS5kZiRhbHBoYV90aW1lKQ0Kc2QodGltZS5kZiRhbHBoYV90aW1lKQ0KY29yKHRpbWUuZGYkYWxwaGFfdGltZSwgdGltZS5kZiRiZXRhX3RpbWUpIA0KDQpvYnNlcnZhdGlvbnMgPC0gc3ViamVjdHMgKiB0aW1lDQpvYnNlcnZhdGlvbnMuZGYgPC0gIGRhdGEuZnJhbWUoDQogIHN1YmplY3QgPSBzb3J0KHJlcChjKDE6c3ViamVjdHMpLCB0aW1lKSksDQogIHRpbWUgPSByZXAoYygxOnRpbWUpLCBzdWJqZWN0cyksIA0KICBwaXp6YSA9IHJlcChybm9ybShzdWJqZWN0cyAqIHRpbWUsIDMwLCA1KSkpDQpkYXQxICAgPC0gIG1lcmdlKHN1YmplY3RzLmRmLCBvYnNlcnZhdGlvbnMuZGYpDQpkYXQyICAgPC0gIG1lcmdlKGRhdDEsIHRpbWUuZGYpDQpkYXQzICAgPC0gIGRhdDJbd2l0aChkYXQyLCBvcmRlcihzdWJqZWN0LHRpbWUpKSwgXQ0Kcm93bmFtZXMoZGF0MykgICA8LSAgMTpucm93KGRhdDMpDQoNCg0KZGYgPC0gIHdpdGhpbihkYXQzLCANCiAgICAgICAgICAgICAgbW9vZCA8LSAgYWxwaGFfc3ViamVjdHMgKyBwaXp6YSAqIGJldGFfc3ViamVjdHMgKw0KICAgICAgICAgICAgICAgIGFscGhhX3RpbWUgICAgKyBwaXp6YSAqIGJldGFfdGltZSAgICArDQogICAgICAgICAgICAgICAgMC43NSAqIHJub3JtKG4gPSBvYnNlcnZhdGlvbnMpKSANCg0KaGVhZChkZikNCnBpenphZGF0YSA8LSBkZlssLWMoMyw0LDYsNyldDQpgYGANCg0KDQpgYGB7ciBlY2hvID0gRkFMU0V9DQpoZWFkKHBpenphZGF0YSkNCg0KYGBgDQoNCioqTk9URSoqIC0gVGhpcyBpcyBhIHdpdGhpbi1zdWJqZWN0cyBzdHVkeS4gQWxsIHBhcnRpY2lwYW50cyBhcmUgcHJvdmlkaW5nIG11bHRpcGxlIG1lYXN1cmVtZW50cy4gDQoNCiMjIEltcG9ydGFudCBUZXJtaW5vbG9neSANCkJlbG93IGFyZSBzb21lIGltcG9ydGFudCB0ZXJtcyB0byBrbm93IGZvciB1bmRlcnN0YW5kaW5nIHRoZSBzdGF0aXN0aWNhbCBjb25jZXB0cyB1c2VkIGluIG1peGVkIG1vZGVsczoNCg0KIyMjQ3Jvc3NlZCAmIE5lc3RlZCBEZXNpZ25zDQoqKkNyb3NzZWQgZGVzaWducyoqIHJlZmVyIHRvIHRoZSAqd2l0aGluLXN1YmplY3QqIHZhcmlhYmxlcyAoaS5lLiB0aW1lcG9pbnQsIGNvbmRpdGlvbiwgZXRjLikuIENyb3NzZWQgZGVzaWducyBvY2N1ciB3aGVuIG11bHRpcGxlIG1lYXN1cmVtZW50cyBhcmUgYXNzb2NpYXRlZCB3aXRoIG11bHRpcGxlIGdyb3VwaW5nIHZhcmlhYmxlcy4gSW4gYSBjb21wbGV0ZWx5IGNyb3NzZWQgZGVzaWduLCBhbGwgc3ViamVjdHMgcHJvdmlkZSByZXNwb25zZXMgZm9yIGFsbCBjb25kaXRpb25zL3RpbWUtcG9pbnRzLg0KDQogIC0gUGl6emEgc3R1ZHk6IFdlIGhhdmUgc3ViamVjdHMgcHJvdmlkaW5nIHJlc3BvbnNlcyBhdCAxMCB0aW1lIHBvaW50cy4gVGh1cywgd2UgaGF2ZSBhIGNyb3NzZWQgZGVzaWduLiANCiAgDQoqKk5lc3RlZCBkZXNpZ25zKiogcmVmZXIgdG8gdGhlICpiZXR3ZWVuLXN1YmplY3QqIHZhcmlhYmxlLiBHZW5lcmFsbHkgdGhpcyBpcyBhIGhpZ2hlci1sZXZlbCB2YXJpYWJsZSB0aGF0IHN1YmplY3RzIG9yIGl0ZW1zIGFyZSBncm91cGVkIHVuZGVyLg0KICANCiAgLSBQaXp6YSBzdHVkeTogTm90IG5lc3RlZC4NCg0KIyMjRml4ZWQgdi4gUmFuZG9tIEVmZmVjdHMNCioqRml4ZWQgZWZmZWN0cyoqIGFyZSwgZXNzZW50aWFsbHksIHlvdXIgcHJlZGljdG9yIHZhcmlhYmxlcy4gVGhpcyBpcyB0aGUgZWZmZWN0IHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBhZnRlciBhY2NvdW50aW5nIGZvciByYW5kb20gdmFyaWFiaWxpdHkgKGhlbmNlLCBmaXhlZCkuIA0KIA0KICAtIFBpenphIHN0dWR5OiBUaGUgZml4ZWQgZWZmZWN0cyBhcmUgUElaWkEgY29uc3VtcHRpb24gYW5kIFRJTUUsIGJlY2F1c2Ugd2UncmUgaW50ZXJlc3RlZCBpbiB0aGUgZWZmZWN0IG9mIHBpenphIGNvbnN1bXB0aW9uIG9uIE1PT0QsIGFuZCBpZiB0aGlzIGVmZmVjdCB2YXJpZXMgb3ZlciBUSU1FLiANCiAgDQoqKlJhbmRvbSBlZmZlY3RzKiogYXJlIGJlc3QgZGVmaW5lZCBhcyBub2lzZSBpbiB5b3VyIGRhdGEuIFRoZXNlIGFyZSBlZmZlY3RzIHRoYXQgYXJpc2UgZnJvbSB1bmNvbnRyb2xsYWJsZSB2YXJpYWJpbGl0eSB3aXRoaW4gdGhlIHNhbXBsZS4gKlN1YmplY3QqIGxldmVsIHZhcmlhYmlsaXR5IGlzIG9mdGVuIGEgcmFuZG9tIGVmZmVjdC4NCiANCiAgLSBQaXp6YSBzdHVkeTogQ29udHJvbGxpbmcgZm9yIHJhbmRvbSBlZmZlY3RzIG9mIHN1YmplY3QsIHBpenphIGNvbnN1bXB0aW9uLCBhbmQgZWZmZWN0IG9mIHRpbWUgb24gc3ViamVjdCwgYWxsIG9mIHdoaWNoIHZhcnkgYWNyb3NzIHBhcnRpY2lwYW50cy4gDQoNCioqTk9URSoqIC0gUHJlZGljdG9yIHZhcmlhYmxlcyBjYW4gYmUgYm90aCBmaXhlZCAoaS5lLiBjYXVzaW5nIGEgbWFpbiBlZmZlY3QvaW50ZXJhY3Rpb24pIGFuZCByYW5kb20gKGkuZS4gY2F1c2luZyB2YXJpYW5jZS92YXJpYWJpbGl0eSBpbiByZXNwb25zZXMpLiBXaGVuIGJ1aWxkaW5nIHlvdXIgbW9kZWxzLCB5b3UgY2FuIHRyZWF0IHlvdXIgcHJlZGljdG9yIGFzIGEgZml4ZWQgJiByYW5kb20gZmFjdG9yLiANCg0KIyMjIFNsb3BlcyB2LiBJbnRlcmNlcHRzOiANClRvIGJldHRlciB1bmRlcnN0YW5kIHNsb3BlcyBhbmQgaW50ZXJjZXB0cyBpdCBtYXliZSBoZWxwZnVsIHRvIGltYWdpbmUgcGxvdHRpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBJVnMgYW5kIERWIGZvciBlYWNoIHN1YmplY3QuDQoNCioqSW50ZXJjZXB0cyoqOiBUaGUgYmFzZWxpbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gSVYgJiBEVi4gRml4ZWQgZWZmZWN0cyBhcmUgcGxvdHRlZCBhcyBpbnRlcmNlcHRzIHRvIHJlZmxlY3QgdGhlIGJhc2VsaW5lIGxldmVsIG9mIHlvdXIgRFYuDQogIA0KICAtCVJhbmRvbSBpbnRlcmNlcHRzOiBWYXJpYWJpbGl0eSBpbiBiYXNlbGluZSBtZWFzdXJlbWVudHMgDQogICAgICANCiAgICAgICogUGl6emEgU3R1ZHk6IERpZmZlcmVudCBiYXNlbGluZSBsZXZlbHMgb2YgcGl6emEgY29uc3VtcHRpb24gYWNyb3NzIHN1YmplY3RzDQogICAgICANCiAgLSBGaXhlZCBpbnRlcmNlcHRzOiBCYXNlbGluZSB2YXJpYW5jZSBpcyBub3QgYWZmZWN0ZWQNCiAgDQogICAgICAqIFBpenphIHN0dWR5OiANCg0KKipTbG9wZSoqOiBUaGUgc3RyZW5ndGggb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIElWICYgRFYgKGNvbnRyb2xsaW5nIGZvciByYW5kb21uZXNzKSwgd2hpY2ggcmVwcmVzZW50IHJhbmRvbSBlZmZlY3RzLiBZb3Ugc2hvdWxkIGV4cGVjdCB0byBzZWUgZGlmZmVyZW5jZXMgaW4gdGhlIHNsb3BlcyBvZiB5b3VyIHJhbmRvbSBmYWN0b3JzLiANCiAgDQogIC0gUGl6emEgc3R1ZHk6IFRoZSBzdHJlbmd0aCBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gcGl6emEgY29uc3VtcHRpb24gYW5kIG1vb2Qgd2lsbCB2YXJ5IGZyb20gcGVyc29uIHRvIHBlcnNvbiwgcmVzdWx0aW5nIGluIHJhbmRvbSBzbG9wZXMgcGVyIHN1YmplY3QuIEJlY2F1c2Ugc3ViamVjdHMgc3RhcnQgYXQgIA0KDQoqKk5vdGUqKjogSWYgMiB2YXJpYWJsZXMgc2hhcmUgYSBsb3Qgb2YgdmFyaWFuY2UsIHRoZSByYW5kb20gaW50ZXJjZXB0cyBhbmQgc2xvcGVzIG1heSBiZSBjb3JyZWxhdGVkIHdpdGggb25lIGFub3RoZXIuIFRoaXMgY2FuIGJlIGFjY291bnRlZCBmb3IgaW4gcmFuZG9tIHN0cnVjdHVyZXMgYXMgd2VsbC4gDQoNCioqSHlwb3RoZXNlcyBGb3IgU3R1ZHkqKg0KUmFuZG9tIGVmZmVjdHM6IA0KLSAiU3ViamVjdHMiIHdpbGwgaGF2ZSB0aGVpciBvd24gaW50ZXJjZXB0cy4gDQotIFN1YmplY3RzJyBzbG9wZSB3aWxsIHZhcnkgYnkgcGl6emEgY29uc3VtcHRpb24gaW50ZXJjZXB0cywgYW5kIGJ5IHRpbWVwb2ludCBpbnRlcmNlcHRzLiANCi0gVGhlIHNsb3BlcyBhbmQgaW50ZXJjZXB0cyBvZiBwaXp6YSBjb25zdW1wdGlvbiBhbmQgdGltZSB3aWxsIGJlIGNvcnJlbGF0ZWQgKHNoYXJlZCB2YXJpYW5jZSkNCkZpeGVkIGVmZmVjdHM6IA0KLSBFeHBlY3RpbmcgdGhlcmUgdG8gYmUgYW4gb3ZlcmFsbCBtYWluIGVmZmVjdCBvZiBwaXp6YSBjb25zdW1wdGlvbiBvdmVyIHRpbWUuIA0KLSBFeHBlY3RpbmcgaW50ZXJhY3Rpb24gc3VjaCB0aGF0IG1vcmUgcGl6emEgb3ZlciB0aW1lIHByZWRpY3RzIG1vb2QuIA0KDQojIFNldHRpbmcgdXAgZGF0YSBpbiBSIA0KLSAqKkNvZGluZyoqOiBSZWNvZGUgeW91ciB2YXJpYWJsZSAobWVhbi1jZW50ZXJlZCwgZWZmZWN0cykgYXMgYmVzdCBzdWl0ZWQgZm9yIHlvdXIgZGF0YS4gDQotICoqTG9uZyBGb3JtYXQqKiA6IFJlZmVyIHRvIFtUaWR5UiBjaGFwdGVyXShodHRwOi8vYWRlbW9zLnBlb3BsZS51aWMuZWR1L0NoYXB0ZXI5Lmh0bWwpIA0KLSAqKlBhY2thZ2VzKio6IE1ha2Ugc3VyZSB5b3UgaGF2ZSB0aGUgZm9sbG93aW5nIHBhY2thZ2VzIGRvd25sb2FkZWQ6IA0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCg0KbGlicmFyeSAobG1lclRlc3QpICMgTWl4ZWQgbW9kZWwgcGFja2FnZSBieSBEb3VnbGFzIEJhdGVzLCBjb21lcyB3LyBwdmFsdWVzISANCmxpYnJhcnkgKHRleHJlZykgI0hlbHBzIHVzIG1ha2UgdGFibGVzIG9mIHRoZSBtaXhlZCBtb2RlbHMNCmxpYnJhcnkgKGFmZXgpICMgRWFzeSBBTk9WQSBwYWNrYWdlIHRvIGNvbXBhcmUgbW9kZWwgZml0cw0KbGlicmFyeSAocGx5cikgIyBEYXRhIG1hbmlwdWxhdG9yIHBhY2thZ2UNCmxpYnJhcnkgKGdncGxvdDIpICMgR0dwbG90IHBhY2thZ2UgZm9yIHZpc3VhbGl6aW5nIGRhdGENCg0KYGBgDQoNCg0KI01vZGVsaW5nIFByb2NlZHVyZQ0KTW9kZWxpbmcgY29udmVudGlvbnMgZGlmZmVyIGJ5IGZpZWxkLCBidXQgdGhpcyBleGFtcGxlIHdpbGwgYmVnaW4gYnkgZml0dGluZyB0aGUgbnVsbCBtb2RlbCBmaXJzdCwgdGhlbiBidWlsZGluZyB1cCBoaWVyYXJjaGljYWxseS4NCiANCg0KIyMgUmFuZG9tIGVmZmVjdHMgc3RydWN0dXJlDQpUaGUgKm51bGwgbW9kZWwqIHdpbGwgYmUgZml0IHRvIHRoZSBbbWF4aW1hbCBsaWtlbGlob29kIGVzdGltYXRlXShodHRwOi8vbG1lNC5yLWZvcmdlLnItcHJvamVjdC5vcmcvbE1Nd1IvbHJncHJ0LnBkZikuIFRoZSByYW5kb20gZWZmZWN0cyBzdHJ1Y3R1cmUgcmVmbGVjdHMgWU9VUiB1bmRlcnN0YW5kaW5nIG9mIHdoZXJlIHRvIGV4cGVjdCB2YXJpYW5jZSwgYW5kIGhvdyBuZXN0ZWQgZGF0YSB3aWxsIGludGVyYWN0IHdpdGggdGhhdCB2YXJpYW5jZS4gVGhlIGdlbmVyYWwgc3ludGF4IGlzIGFzIGZvbGxvd3M6DQoNCmBgYCANCigxICsgSVYgfCB1bml0IGxldmVsKSAgDQooMSArIElWLjEqSVYuMiB8IHVuaXQgbGV2ZWwpDQoNCiNvcg0KDQooMCArIElWIHwgdW5pdCBsZXZlbCkNCigwICsgSVYuMSpJVi4yIHwgdW5pdCBsZXZlbCkNCg0KYGBgDQpXaGVuIHRoZXJlIGlzIGEgMSBiZWZvcmUgdGhlIGxpbmUsIHlvdSBhcmUgYWNjb3VudGluZyBmb3IgcmFuZG9tIGludGVyY2VwdHMgKHZhcnlpbmcgYmFzZWxpbmUgbGV2ZWxzKSBpbiB5b3VyIHZhcmlhYmxlLiBBIE8gaW5kaWNhdGVzIHRoZSB2YXJpYWJsZSBoYXMgYSBmaXhlZCBpbnRlcmNlcHQgYW5kIG5vdCBhIHJhbmRvbSBvbmUuICBUaGVzZSBhcmUgYSBmZXcgaHlwb3RoZXRpY2FsIHJhbmRvbSBlZmZlY3RzIHN0cnVjdHVyZXM6DQoNCiAgLSBgYGAoMXwgc3ViamVjdClgYGAgPSBSYW5kb20gaW50ZXJjZXB0cyBhbmQgc2xvcGVzIGZvciBzdWJqZWN0cyAoZGlmZmVyZW50IGJhc2VsaW5lcywgZGlmZmVyZW50IGF2ZXJhZ2UgZWZmZWN0IHBlciBzdWJqZWN0KS4NCiAgLSBgYGAoMSArIHBpenphIHxzdWJqZWN0KWBgYCA9IFRoZSBlZmZlY3Qgb2YgcGl6emEgd2lsbCB2YXJ5ICpiZXR3ZWVuKiBzdWJqZWN0cy4gUmFuZG9tIGludGVyY2VwdHMgZm9yIHBpenphIGNvbnN1bXB0aW9uLCByYW5kb20gc2xvcGVzDQpmb3Igc3ViamVjdHMgaW5mbHVlbmNlZCBieSBwaXp6YSBjb25zdW1wdGlvbi4gDQogIC0gYGBgICgxICsgcGl6emEgfCBzdWJqZWN0KSArICgwICsgdGltZXwgc3ViamVjdClgYGAgPSBTdWJqZWN0cyBoYXZlIHJhbmRvbSBpbnRlcmNlcHRzIGFuZCBzbG9wZXMgYXMgaW5mbHVlbmNlZCBieSBwaXp6YSBjb25zdW1wdGlvbi4gVGltZSBzbG9wZXMgY2FuIHZhcnkgYXMgZnVuY3Rpb24gb2YgdGhlIHN1YmplY3QsIGJ1dCB2YXJpYW5jZSBiZXR3ZWVuIHBpenphIGNvbnN1bXB0aW9uIGFuZCB0aW1lIGFzIGluZGVwZW5kZW50DQogIC0gYGBgICgxICsgcGl6emEgKyB0aW1lIHwgc3ViamVjdClgYGAgPSBTYW1lIGFzIGFib3ZlLCBidXQgdmFyaWFuY2UgYmV0d2VlbiBwaXp6YSBjb25zdW1wdGlvbiBhbmQgdGltZSBhcmUgU0hBUkVEIChwaXp6YSBjb25zdW1wdGlvbiBoYXMgcmVsYXRpb25zaGlwIHdpdGggdGltZSB0aGF0IHZhcmllcyBieSBzdWJqZWN0KS4gDQogIC0gYGBgICgxICsgcGl6emEgKiB0aW1lIHwgc3ViamVjdClgYCA9ICBFYWNoIHN1YmplY3QgY2FuIGhhdmUgdGhlaXIgaW50ZXJjZXB0LCByYW5kb20gc2xvcGVzIGluZmx1ZW5jZWQgYnkgcGl6emEgYW5kIHRpbWUsIGFuZCB0aGVpciBpbnRlcmFjdGlvbiBiZXR3ZWVuIHBpenphIGFuZCB0aW1lLiBJTVBPUlRBTlRMWSwgYWxsIHJhbmRvbSBzbG9wZXMgYW5kIGludGVyY2VwdHMgY2FuIGJlICpjb3JyZWxhdGVkKi4gDQogIA0KIyMjIEZpdHRpbmcgQmVzdCBSYW5kb20gRWZmZWN0cyBTdHJ1Y3R1cmUNClRoZSBgYGBsbWVyYGBgIHBhY2thZ2UgY2FuIGJlIHVzZWQgZm9yIG1vZGVsaW5nLCBhbmQgdGhlIGdlbmVyYWwgc3ludGF4IGlzIGFzIGZvbGxvd3M6IA0KIGBgYA0KIG1vZGVsbmFtZSA8LSBsbWVyIChkdiB+IDEgKyBJViArKHJhbmRvbWVmZmVjdHMpLCBkYXRhID0gZGF0YS5uYW1lLCBSRU1MID0gRkFMU0UpDQogDQogYGBgDQoNCllvdSBjYW4gbmFtZSBlYWNoIG1vZGVsIHdoYXRldmVyIHlvdSB3YW50LCBidXQgbm90ZSB0aGF0IHRoZSBuYW1lIG9mIHRoZSBkYXRhZnJhbWUgY29udGFpbmluZyB5b3VyIGRhdGEgaXMgc3BlY2lmaWVkIGluIGVhY2ggbW9kZWwuIEtlZXAgYGBgIFJFTUwgPSBGQUxTRSBgYGAuIA0KDQpGaXJzdCwgaG93ZXZlciwgd2UgbmVlZCB0byBzcGVjaWZ5IHRoZSByYW5kb20gZWZmZWN0cyB0ZXJtIHRoYXQgYmVzdCBmaXRzIHRoZSBkYXRhLiBUcnkgb3V0IGRpZmZlcmVudCBzdHJ1Y3R1cmVzLCBhbmQgdXNlIHRoZSBgYGBhbm92YWBgYCBmdW5jdGlvbiB0byBmaW5kIHRoZSBiZXN0IGZpdHRpbmcgcmFuZG9tIGVmZmVjdHMgc3RydWN0dXJlLiBUaGlzIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBmaXQgb2YgdGhlIG1vZGVsIHRvIHNlZSBob3cgZml0IGhhcyBpbXByb3ZlZCB3aXRoIGFkZGl0aW9uYWwgaXRlbXMuIFlvdSBjYW4gYWxzbyAqKnZpc3VhbGl6ZSB5b3VyIGRhdGEqKiB0byBzZWUgd2hhdCBmaXRzLiAjIyMgSW5zZXJ0IGdncGxvdDIgcmVmZXJlbmNlLiAgDQoNCmBgYCB7ciBlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFfQ0KbnVsbG1vZGVsMSA8LSBsbWVyKCBtb29kIH4gMSArICgxfHN1YmplY3QpLCBkYXRhID0gcGl6emFkYXRhLCBSRU1MPUZBTFNFKQ0KbnVsbG1vZGVsMiA8LSBsbWVyKCBtb29kIH4gMSArICgxICsgcGl6emEgfHN1YmplY3QpLCBkYXRhID0gcGl6emFkYXRhLCBSRU1MPUZBTFNFKQ0KbnVsbG1vZGVsMyA8LSBsbWVyKCBtb29kIH4gMSArICgxICsgcGl6emEgKiB0aW1lIHxzdWJqZWN0KSwgZGF0YSA9IHBpenphZGF0YSwgUkVNTD1GQUxTRSkNCg0KYW5vdmEgKG51bGxtb2RlbDEsIG51bGxtb2RlbDIsIG51bGxtb2RlbDMpDQpgYGANCg0KUmVmZXIgdG8gdGhlIHAtdmFsdWVzIGluIHRoZSBvdXRwdXQgdG8gc2VlIHdoZXRoZXIgdGhlcmUgd2FzIGFuIGltcHJvdmVtZW50IGluIGZpdC4gQmVjYXVzZSB0aGVyZSB3YXMgYW4gaW1wcm92ZW1lbnQgaW4gYmV0d2VlbiBtb2RlbCAxIGFuZCBtb2RlbCAyLCBidXQgTk8gaW1wcm92ZW1lbnQgYmV0d2VlbiBtb2RlbCAyIGFuZCBtb2RlbCAzLCB3ZSBjYW4gcHJvY2VlZCB1c2luZyB0aGUgYmVzdCBmaXQgbW9kZWwsIGBudWxsbW9kZWwyYCwgYXMgb3VyIHJhbmRvbSBlZmZlY3RzIHN0cnVjdHVyZSBmb3IgdGhlIHJlc3Qgb2YgdGhlIGFuYWx5c2VzLiANCg0KIyMgRml4ZWQgZWZmZWN0cw0KU3BlY2lmaWMgcHJlZGljdG9ycyBjYW4gbm93IGJlIGludHJvZHVjZWQgaW50byBvdXIgbW9kZWwgYnkgc3BlY2lmeWluZyB0aGUgRFYgZm9sbG93ZWQgYnkgdGhlIHByZWRpY3RvciwgcmFuZG9tIGVmZmVjdHMsIGFuZCB0aGUgZGF0YWZyYW1lLiANCg0KKipNb2RlbCAxKiogLSBQaXp6YSBjb25zdW1wdGlvbiBwcmVkaWN0IG1vb2QgKG1haW4gZWZmZWN0KTogDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIGVycm9yID0gRkFMU0V9DQptMT1sbWVyKG1vb2QgfiBwaXp6YSArICgxICsgcGl6emEgKyB0aW1lIHxzdWJqZWN0KSwgZGF0YT1waXp6YWRhdGEsIFJFTUwgPSBGQUxTRSkNCnN1bW1hcnkobTEpDQoNCmBgYA0KDQpUaGlzIG1vZGVsIGFwcGVhcnMgdG8gc2hvdyBwaXp6YSBjb25zdW1wdGlvbiBhcyBhIHBvc2l0aXZlIHByZWRpY3RvciBvZiBtb29kLCBhcyBpbmRpY2F0ZWQgYnkgYSBwb3NpDQoNClJhbmRvbSBlZmZlY3RzOiANCg0KICAtIFNEIHJlZmxlY3RzIHRoZSBhbW91bnQgb2YgdmFyaWF0aW9uLiBDaGVjayBjb3JyZWxhdGlvbiBiZXR3ZWVuIGludGVyY2VwdCBhbmQgc2xvcGUgKGkuZS4gaWYgaW50ZXJjZXB0IGluY3JlYXNlcywgc2xvcGUgaW5jcmVhc2VzKS4gDQogICAgDQpGaXhlZCBlZmZlY3RzDQoNCiAgLSBDaGVjayBlc3RpbWF0ZXMgZm9yIGJldGEgdmFsdWUgLS0gdGltZSBoYXMgYSBzaWduaWZpY2FudCBlZmZlY3QsIGltcHJvdmVtZW50IGluIG1vb2QgYnkgYWJvdXQgMSBwb2ludCBvdmVyIHRpbWUuIA0KICAtIENoZWNrIGNvcnJlbGF0aW9uIG9mIGZpeGVkIGVmZmVjdHMgLS0gaWYgdG9vIGhpZ2gsIHRoaXMgbWF5IGltcGx5IFttdWx0aWNvbGxpbmVhcml0eV0oaHR0cDovL2FkZW1vcy5wZW9wbGUudWljLmVkdS9DaGFwdGVyMTMuaHRtbCkNCg0KKipNb2RlbCAyKiogLS0gUGl6emEgY29uc3VtcHRpb24gYW5kIHRpbWVwb2ludHMgaW5jbHVkZWQgYXMgcHJlZGljdG9ycyBvZiBtb29kLiANCmBgYHtyIGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIGVycm9yID0gRkFMU0V9DQptMj0gbG1lcihtb29kIH4gcGl6emEgKyB0aW1lICsgKDEgKyBwaXp6YSArIHRpbWUgfHN1YmplY3QpLCBkYXRhPXBpenphZGF0YSwgUkVNTCA9IEZBTFNFKQ0Kc3VtbWFyeShtMikNCg0KYGBgDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIGVycm9yID0gRkFMU0V9DQptMj0gbG1lcihtb29kIH4gcGl6emEgKyB0aW1lICsgKDEgKyBwaXp6YSArIHRpbWUgfHN1YmplY3QpLCBkYXRhPXBpenphZGF0YSwgUkVNTCA9IEZBTFNFKQ0Kc3VtbWFyeShtMikNCg0KYGBgDQoNClJlc3VsdHMgc2hvdyBzaWduaWZpY2FudCBlZmZlY3RzIG9mIGJvdGggcGl6emEgY29uc3VtcHRpb24gYW5kIHRpbWUgb24gbW9vZCEgRG8gdGhleSBpbnRlcmFjdD8gDQoNCioqTW9kZWwgMyoqIC0tIEluY2x1ZGluZyBhbiBpbnRlcmFjdGlvbiB0ZXJtIGJldHdlZW4gcGl6emEgY29uc3VtcHRpb24gYW5kIHRpbWUgKHBpenphIGNvbnN1bXB0aW9uIHZhcmllcyBvdmVyIHRpbWUpDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIGVycm9yID0gRkFMU0V9DQptMyA9IGxtZXIobW9vZCB+IHBpenphKnRpbWUgKyAoMSArIHBpenphICsgdGltZSB8c3ViamVjdCksIGRhdGE9cGl6emFkYXRhLCBSRU1MID0gRkFMU0UpDQpzdW1tYXJ5KG0zKQ0KDQpgYGANCg0KUmVzdWx0cyBzaG93IHRoYXQgd2hpbGUgcGl6emEgY29uc3VtcHRpb24gYW5kIHRpbWUgYXJlIHN0aWxsIHNpZ25pZmljYW50IG1haW4gcHJlZGljdG9ycywgdGhlaXIgaW50ZXJhY3Rpb24gdGVybSBkaWQgbm90IHJlYWNoIHNpZ25pZmljYW5jZS4gDQoNCiMjIENvbXBhcmluZyBNb2RlbCBGaXQgDQpUaGUgQU5PVkEgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byBjb21wdXRlIENoaS1zcXVhcmVzIGJldHdlZW4gZWFjaCBtb2RlbCB0byBzZWUgdGhlIGltcHJvdmVtZW50IGluIG1vZGVsIGZpdC4gVGhlIGBlZmZlY3RzYCBwYWNrYWdlIHNob3VsZCBhbHNvIGluY2x1ZGUgcC12YWx1ZXMgaW4gdGhlIG91dHB1dC4gDQoNCmBgYHtyIGVjaG8gPSBUUlVFfQ0KDQphbm92YSAobTEsIG0yLCBtMykNCg0KYGBgDQoNCkFzIHlvdSBjYW4gc2VlIGJ5IHRoZSBwLXZhbHVlcywgd2hpbGUgdGhlcmUgaXMgYW4gaW1wcm92ZW1lbnQgaW4gZml0IGZyb20gbW9kZWwgMSB0byBtb2RlbCAyLCBtb2RlbCAzIGRpZCBub3QgZXhwbGFpbiBtb3JlIHZhcmlhbmNlLiBBcyBzdWNoLCBtb2RlbCAyIGFwcGVhcnMgdG8gYmUgdGhlIGJlc3QgZml0Lg0KDQpXZSBjYW4gbm93IGNvbmNsdWRlIHRoYXQgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHJhbmRvbSBlZmZlY3RzLCBtb3JlIHBpenphIGNvbnN1bXB0aW9uIGRvZXMgbGVhZCB0byBpbXByb3ZlbWVudHMgaW4gbW9vZCBvdmVyIHRpbWUsIGJ1dCB0aGVyZSBpcyBubyBpbnRlcmFjdGlvbiB3aXRoIHRpbWUuIA0KDQpUaGlzIGNvbmNsdWRlcyB0aGUgdHV0b3JpYWwgb24gbWl4ZWQgZWZmZWN0cyBtb2RlbHMuIEJlbG93IGFyZSByZWZlcmVuY2VzIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIA0KIyBSZWZlcmVuY2VzIA0KW0NoZWNraW5nIGFzc3VtcHRpb25zXShodHRwOi8vYWRlbW9zLnBlb3BsZS51aWMuZWR1L0NoYXB0ZXIxOC5odG1sKQ0KW01vcmUgdGhlb3J5IGhlcmVdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L35oc2VsdG1hbi8zMDkvQm9vay9jaGFwdGVyMTUucGRmKSwgW2hlcmVdKGh0dHA6Ly9qYWtld2VzdGZhbGwub3JnL21pc2MvQkRCMjAwOC5wZGYpLCBhbmQgW2hlcmVdKGh0dHA6Ly93d3cuYm9kb3dpbnRlci5jb20vdHV0b3JpYWwvYndfTE1FX3R1dG9yaWFsMi5wZGYpLg0KW0VmZmVjdHMgY29kaW5nXShodHRwOi8vd3d3Lm1hcnRpam53aWVsaW5nLm5sL1Ivc2hlZXRzLnBkZikNCltTaW11bGF0aW5nIGRhdGFdKGh0dHA6Ly9hbnl0aGluZ2J1dHJiaXRyYXJ5LmJsb2dzcG90LmluLzIwMTIvMTAvaGllcmFyY2hpY2FsLWxpbmVhci1tb2RlbHMtYW5kLWxtZXIuaHRtbCkNCg0KPHNjcmlwdD4NCiAgKGZ1bmN0aW9uKGkscyxvLGcscixhLG0pe2lbJ0dvb2dsZUFuYWx5dGljc09iamVjdCddPXI7aVtyXT1pW3JdfHxmdW5jdGlvbigpew0KICAoaVtyXS5xPWlbcl0ucXx8W10pLnB1c2goYXJndW1lbnRzKX0saVtyXS5sPTEqbmV3IERhdGUoKTthPXMuY3JlYXRlRWxlbWVudChvKSwNCiAgbT1zLmdldEVsZW1lbnRzQnlUYWdOYW1lKG8pWzBdO2EuYXN5bmM9MTthLnNyYz1nO20ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoYSxtKQ0KICB9KSh3aW5kb3csZG9jdW1lbnQsJ3NjcmlwdCcsJ2h0dHBzOi8vd3d3Lmdvb2dsZS1hbmFseXRpY3MuY29tL2FuYWx5dGljcy5qcycsJ2dhJyk7DQoNCiAgZ2EoJ2NyZWF0ZScsICdVQS05ODg3ODc5My0xJywgJ2F1dG8nKTsNCiAgZ2EoJ3NlbmQnLCAncGFnZXZpZXcnKTsNCg0KPC9zY3JpcHQ+DQo=