NOTE ON PACKAGES: I use the following packages in this chapter. If you do not have these packages installed, you may use the script below to install them and load their libraries (just remove the “#” before the package you need to install).

#install.packages("lme4")
#install.packages("ggplot2")
#install.packages("HLMdiag")
#install.packages("DHARMa")
#install.packages("car")

#load the libraries so you have access to them in your workflow

library("lme4")
library("ggplot2")
library("HLMdiag")
library("DHARMa")
library("car") #for the Levene test which we will not discuss here
library("Matrix")

1 Preface

It is important to work within the same file environment so that data and code can be easily linked. To do so, let’s set the working directory

#setwd("set locations") 

2 CAVEAT

The following information is a best approximation of how to test assumptions of mixed and multilevel models as of November 2016. Much of the procedures described have been piecemeal put together through the concatenation of multiple sources (both refereed and not). There is by no means any sort of consensus within the field of statistics and the R community as a whole as to how to approach this topic systematically. I’ve attempted to pull in as many different ideas as feasible in my little chapter. As such, we will be using the lmer as opposed to the lme package. The lmer package is better suited for mixed designs and thus is more amenable to many different kinds of data. Unfortunately, unlike the lme package, lmer DOES NOT include a way to easily run model diagnostics. Some would suggest that if your model is a standard Multilevel Model (i.e. not mixed designs) to then just use the lme package to streamline the model building process.

3 Overview

As with any statistical manipulation, there are a specific set of assumptions under which we operate when conducting multilevel models (MLM). These assumptions are identical to those of ordinary multiple regression analyses, but the way in which we test them is quite different. In this chapter, we will examine the three most important (and most frequently violated) assumptions of MLM. To do so, let’s take a look at some sample data, fit a model, and run through how to test each assumption.

4 Build a Dataframe

Let’s create a sample dataframe with which we will run our multilevel model and then test our assumptions. Let’s say there are 10 subjects with 4 temporal-based observations (one every year) in this hypothetical scenario. Each person will have data for age, sex, average number of cigarettes smoked each week, level of nicotine dependence from the Fagerstrom Test of Nicotine Dependence (FTND), ratings of depressive symptoms from the Beck Depression Inventory (BDI), and a count variable for the total number of lifetime major depressive episodes suffered up to that point of data collection.

#Create vectors for each of the variables
Subjects <- c(rep.int(1,4),rep.int(2,4),rep.int(3,4),rep.int(4,4),rep.int(5,4),rep.int(6,4),rep.int(7,4),rep.int(8,4),rep.int(9,4),rep.int(10,4)) 
Time <- c(rep(1:4,10)) #this is for illustrative purposes only - these models are much more helpful with many different data points per subject
Age <- c(18:21, 19:22, 18:21, 20:23, 19:22, 22:25, 21:24, 19:22, 20:23, 20:23)
Sex <- c(rep("M",8),rep("F",4),rep("M",4),rep("F",12),rep("M",4),rep("F",8))
Cigarettes <- c(10,12,14,0,20,20,20,20,10,20,25,40,12,9,8,8,4,4,8,20,10,10,10,10,10,20,30,60,0,0,0,0,0,1,2,3,0,0,0,30)
Fagerstrom <- c(6,8,8,0,10,10,10,10,8,9,9,10,6,8,10,12,7,7,6,7,2,2,3,8,9,9,9,9,10,10,12,13,0,0,0,0,0,0,0,12)
BDI <- c(7,7,8,9,4,5,6,8,2,2,2,2,3,4,7,8,12,14,14,17,22,22,10,9,7,5,6,8,12,15,6,18,12,14,8,4,3,2,2,1)
Depression <- c(1,1,2,3,2,3,3,3,0,1,1,1,2,2,2,2,4,5,6,6,3,3,4,5,2,2,2,2,1,1,1,1,3,3,4,5,1,1,2,2)

#Combine the vectors into a single data frame
Cigarette.Study<-data.frame(
  subjectID = Subjects,
  Time = Time,
  Sex = Sex,
  Age = Age,
  Cigs = Cigarettes,
  FTND = Fagerstrom,
  BDI = BDI,
  Depression = Depression)

Cigarette.Study$Sex.I<-ifelse(Cigarette.Study$Sex=="M",0,1) #creates a numerical value "Sex" that we can run analyses on

Cigarette.Study
##    subjectID Time Sex Age Cigs FTND BDI Depression Sex.I
## 1          1    1   M  18   10    6   7          1     0
## 2          1    2   M  19   12    8   7          1     0
## 3          1    3   M  20   14    8   8          2     0
## 4          1    4   M  21    0    0   9          3     0
## 5          2    1   M  19   20   10   4          2     0
## 6          2    2   M  20   20   10   5          3     0
## 7          2    3   M  21   20   10   6          3     0
## 8          2    4   M  22   20   10   8          3     0
## 9          3    1   F  18   10    8   2          0     1
## 10         3    2   F  19   20    9   2          1     1
## 11         3    3   F  20   25    9   2          1     1
## 12         3    4   F  21   40   10   2          1     1
## 13         4    1   M  20   12    6   3          2     0
## 14         4    2   M  21    9    8   4          2     0
## 15         4    3   M  22    8   10   7          2     0
## 16         4    4   M  23    8   12   8          2     0
## 17         5    1   F  19    4    7  12          4     1
## 18         5    2   F  20    4    7  14          5     1
## 19         5    3   F  21    8    6  14          6     1
## 20         5    4   F  22   20    7  17          6     1
## 21         6    1   F  22   10    2  22          3     1
## 22         6    2   F  23   10    2  22          3     1
## 23         6    3   F  24   10    3  10          4     1
## 24         6    4   F  25   10    8   9          5     1
## 25         7    1   F  21   10    9   7          2     1
## 26         7    2   F  22   20    9   5          2     1
## 27         7    3   F  23   30    9   6          2     1
## 28         7    4   F  24   60    9   8          2     1
## 29         8    1   M  19    0   10  12          1     0
## 30         8    2   M  20    0   10  15          1     0
## 31         8    3   M  21    0   12   6          1     0
## 32         8    4   M  22    0   13  18          1     0
## 33         9    1   F  20    0    0  12          3     1
## 34         9    2   F  21    1    0  14          3     1
## 35         9    3   F  22    2    0   8          4     1
## 36         9    4   F  23    3    0   4          5     1
## 37        10    1   F  20    0    0   3          1     1
## 38        10    2   F  21    0    0   2          1     1
## 39        10    3   F  22    0    0   2          2     1
## 40        10    4   F  23   30   12   1          2     1
#Check the structure of that data frame
str(Cigarette.Study)
## 'data.frame':    40 obs. of  9 variables:
##  $ subjectID : num  1 1 1 1 2 2 2 2 3 3 ...
##  $ Time      : int  1 2 3 4 1 2 3 4 1 2 ...
##  $ Sex       : Factor w/ 2 levels "F","M": 2 2 2 2 2 2 2 2 1 1 ...
##  $ Age       : int  18 19 20 21 19 20 21 22 18 19 ...
##  $ Cigs      : num  10 12 14 0 20 20 20 20 10 20 ...
##  $ FTND      : num  6 8 8 0 10 10 10 10 8 9 ...
##  $ BDI       : num  7 7 8 9 4 5 6 8 2 2 ...
##  $ Depression: num  1 1 2 3 2 3 3 3 0 1 ...
##  $ Sex.I     : num  0 0 0 0 0 0 0 0 1 1 ...

5 Run a Multilevel Model with our Data

Skipping all of the requisite model building steps, say we find a model predicting cigarette use based on self-reported symptoms of depression (BDI), Time, BDI by Time interaction (BDI*Time), FTND score, with a random intercept for each person, an independently varying FTND score for each person, and depressive episodes by sex fits the data the best and explains the most amount of variance.

Model.F<-lmer(Cigs ~ Time*BDI+FTND
                +(1|subjectID) + (0+FTND|subjectID), #random effects for subject ID and (+) FTND by (|) subject, which are allowed to vary independently from eachother (the 1 and 0 notation)
              data=Cigarette.Study, REML=FALSE)

5.1 Examine results, what do they mean?

summary(Model.F) #summarizes the results of the model - somehow in the "knitting process" significance stars have been lost - R code suggests a significant effect of time and FTND score
## Linear mixed model fit by maximum likelihood t-tests use Satterthwaite
##   approximations to degrees of freedom [lmerMod]
## Formula: 
## Cigs ~ Time * BDI + FTND + (1 | subjectID) + (0 + FTND | subjectID)
##    Data: Cigarette.Study
## 
##      AIC      BIC   logLik deviance df.resid 
##    301.0    314.5   -142.5    285.0       32 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -1.8308 -0.5259 -0.1275  0.3722  3.8984 
## 
## Random effects:
##  Groups      Name        Variance Std.Dev.
##  subjectID   (Intercept)  0.0000  0.0000  
##  subjectID.1 FTND         0.8168  0.9038  
##  Residual                50.7145  7.1214  
## Number of obs: 40, groups:  subjectID, 10
## 
## Fixed effects:
##             Estimate Std. Error      df t value Pr(>|t|)   
## (Intercept)  -9.5672     5.5833 33.5800  -1.714  0.09583 . 
## Time          4.6197     2.0078 35.8700   2.301  0.02732 * 
## BDI           0.6027     0.4960 32.9900   1.215  0.23288   
## FTND          1.4208     0.4367 20.3300   3.253  0.00392 **
## Time:BDI     -0.2105     0.2019 35.5900  -1.043  0.30416   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##          (Intr) Time   BDI    FTND  
## Time     -0.813                     
## BDI      -0.822  0.728              
## FTND     -0.251 -0.026  0.090       
## Time:BDI  0.704 -0.850 -0.851 -0.068
ranef(Model.F) #examines the random effects (i.e things that are allowed to vary across units, in this case each representing our subject-level effect of FTND for our 10 participants)
## $subjectID
##    (Intercept)        FTND
## 1            0  0.03600961
## 2            0  0.32130460
## 3            0  0.85639494
## 4            0 -0.67526169
## 5            0 -0.35541807
## 6            0 -0.32064855
## 7            0  1.38356895
## 8            0 -1.49504433
## 9            0  0.00000000
## 10           0  0.24909453

The first thing to note is that p values are not reported by default. This is because the lme and lmer packages were written in large part by Doug Bates from the University of Wisconsin-Madison. Dr. Bates is not a fan of p value and subsequently chose not to display it in his packages. Our results suggest that both time and Fagerstrom scores are predictive of cigarette use …. But, given our small sample size (and see Maas & Hox 2005 for an exhaustive discussion on minimal sample sizes), can we be assured that the assumptions under which we operate to conduct such analyses are being met?

6 Assumptions

6.1 Assumption 1 - Linearity

A regression analysis is meant to fit the best rectilinear line that explains the most data given your set of parameters. Therefore, the base models rely on the assumption that your data follows a straight line (though the models can be expanded to handle curvilinear data).

6.1.1 How do you test this assumption?

Graphically, plotting the model residuals (the difference between the observed value and the model-estimated value) vs the predictor is one simple way to test. If a pattern emerges (anything that looks non-random), a higher order term may need to be included or you may need to mathematically transform a predictor/response. In R, we’ll use the simple plot function to compare the model-predicted values to the observed ones.

Plot.Model.F.Linearity<-plot(resid(Model.F),Cigarettes) #resid() calls for the residuals of the model, Cigarettes was our initial outcome variables - we're plotting the residuals vs observered

Looks pretty random so we probably haven’t violated this assumption (see Fox 2008 for a discussion about the utility of significance vs visual testing; essentially they argue that significance tests don’t offer you additional information that your naked eye can’t already detect). Let’s look at assumption #2

6.2 Assumption 2 Homogeneity of Variance

Regression models assume that variance of the residuals is equal across groups. In this case, the groups we’re referring to are at the individual (i.e. subject) level.

6.2.1 How do you test this assumption?

R is an excellent program for extracting and storing your model residuals. After we have them in place, we can do a simple ANOVA to determine if they’re different for each person. This procedure is a variation of “Levene’s Test”. Essentially, we’ll extract the residuals from the model, place them in our original table, take their absolute value, and then square them (for a more robust analysis with respect to issues of normality, see Glaser 2006). Finally we’ll take a look at the ANOVA of the between subjects residuals. Let’s give it a shot below:

#for this portion of the analysis, we need to revisit about statistical significance - since the assumption is that the variance is not going to differ, we would hope to see NO STATISTICAL DIFFERENCES in the following procedure (i.e. p>0.05) to confirm that -


Cigarette.Study$Model.F.Res<- residuals(Model.F) #extracts the residuals and places them in a new column in our original data table
Cigarette.Study$Abs.Model.F.Res <-abs(Cigarette.Study$Model.F.Res) #creates a new column with the absolute value of the residuals
Cigarette.Study$Model.F.Res2 <- Cigarette.Study$Abs.Model.F.Res^2 #squares the absolute values of the residuals to provide the more robust estimate
Levene.Model.F <- lm(Model.F.Res2 ~ subjectID, data=Cigarette.Study) #ANOVA of the squared residuals
anova(Levene.Model.F) #displays the results
## Analysis of Variance Table
## 
## Response: Model.F.Res2
##           Df Sum Sq Mean Sq F value Pr(>F)
## subjectID  1   1624  1623.5  0.1044 0.7484
## Residuals 38 590881 15549.5

6.2.2 What do the results mean?

Since the p value is greater than 0.05, we can say that the variance of the residuals is equal and therefore the assumption of homoscedasticity is met Note: R does have built-in or package made Levene (and less the flexible Bartlett) tests, but I couldn’t figure out how to implement them with respect to lmer. Feel free to explore these options on your own.

6.2.3 How about a visual solution?

Plot.Model.F <- plot(Model.F) #creates a fitted vs residual plot
Plot.Model.F

There seems to be even spread around the centered line, but I prefer the Levene’s test as I’m not entirely sure what this graph is supposed to look like

6.3 Assumption 3: The residuals of the model are normally distributed.

Regression models don’t require that outcome variables need to be normally distributed (see: Logistic or Poisson regression models), however MLM assume that the residuals of the analysis ARE normally distributed.

6.3.1 How do you test this assumption?

QQ plots (which are easily obtained in standard regression modeling in R) can provide an estimation of where the standardized residuals lie with respect to normal quantiles. Strong deviation from the provided line indicates that the residuals themselves are not normally distributed.

##qq plot (similar to a diagnostic plot provided by the lm function) for an estimation of the linearity of the residuals
require("lattice")
## Loading required package: lattice
## 
## Attaching package: 'lattice'
## The following object is masked from 'package:boot':
## 
##     melanoma
qqmath(Model.F, id=0.05) #id: identifies values that may be exerting undue influence on the model (i.e. outliers)

There is some deviation from from the expected normal line towards the tails, but overall the line looks straight and therefore pretty normal and suggests that the assumption is not violated. See http://data.library.virginia.edu/diagnostic-plots/ and https://www.r-bloggers.com/model-validation-interpreting-residual-plots/ for more information regarding these visual tests.

7 What if the assumption of normality is violated?

7.1 Transform!

Transformations can be done to improve the relative normality of the data. Most commonly used transformations are log/ln. Let’s create log(10) transformed outcome variables to see if it improves the normality of the residuals.

Cigarette.Study$Cig.Plus.1 <- Cigarettes+1
Cigarette.Study$Cig.Log <- log10(Cigarette.Study$Cig.Plus.1)

str(Cigarette.Study)
## 'data.frame':    40 obs. of  14 variables:
##  $ subjectID      : num  1 1 1 1 2 2 2 2 3 3 ...
##  $ Time           : int  1 2 3 4 1 2 3 4 1 2 ...
##  $ Sex            : Factor w/ 2 levels "F","M": 2 2 2 2 2 2 2 2 1 1 ...
##  $ Age            : int  18 19 20 21 19 20 21 22 18 19 ...
##  $ Cigs           : num  10 12 14 0 20 20 20 20 10 20 ...
##  $ FTND           : num  6 8 8 0 10 10 10 10 8 9 ...
##  $ BDI            : num  7 7 8 9 4 5 6 8 2 2 ...
##  $ Depression     : num  1 1 2 3 2 3 3 3 0 1 ...
##  $ Sex.I          : num  0 0 0 0 0 0 0 0 1 1 ...
##  $ Model.F.Res    : num  3.461 -0.599 -1.717 -6.759 5.957 ...
##  $ Abs.Model.F.Res: num  3.461 0.599 1.717 6.759 5.957 ...
##  $ Model.F.Res2   : num  11.977 0.359 2.948 45.686 35.491 ...
##  $ Cig.Plus.1     : num  11 13 15 1 21 21 21 21 11 21 ...
##  $ Cig.Log        : num  1.04 1.11 1.18 0 1.32 ...
Model.F.2<-lmer(Cig.Log ~ Time*BDI+FTND
                +(1|subjectID) + (0+FTND|subjectID),
              data=Cigarette.Study, REML=FALSE)

summary(Model.F.2) #summarizes the results of the model
## Linear mixed model fit by maximum likelihood t-tests use Satterthwaite
##   approximations to degrees of freedom [lmerMod]
## Formula: 
## Cig.Log ~ Time * BDI + FTND + (1 | subjectID) + (0 + FTND | subjectID)
##    Data: Cigarette.Study
## 
##      AIC      BIC   logLik deviance df.resid 
##     26.4     39.9     -5.2     10.4       32 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -1.67228 -0.56209 -0.02675  0.38253  1.75817 
## 
## Random effects:
##  Groups      Name        Variance Std.Dev.
##  subjectID   (Intercept) 0.198703 0.44576 
##  subjectID.1 FTND        0.004817 0.06941 
##  Residual                0.020319 0.14254 
## Number of obs: 40, groups:  subjectID, 10
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)  
## (Intercept)  0.406378   0.224780 16.878000   1.808   0.0885 .
## Time         0.066599   0.046013 24.283000   1.447   0.1606  
## BDI         -0.006330   0.013984 29.952000  -0.453   0.6541  
## FTND         0.050544   0.028589  8.707000   1.768   0.1120  
## Time:BDI     0.002459   0.004594 24.535000   0.535   0.5972  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##          (Intr) Time   BDI    FTND  
## Time     -0.415                     
## BDI      -0.550  0.678              
## FTND     -0.294 -0.102  0.036       
## Time:BDI  0.433 -0.853 -0.795  0.001
ranef(Model.F.2) #examines the random effects
## $subjectID
##    (Intercept)         FTND
## 1  -0.53631688  0.096595673
## 2   0.06984188  0.016932654
## 3  -0.02110366  0.038008571
## 4   0.61464581 -0.073006166
## 5   0.02039356 -0.002722592
## 6   0.54319687 -0.069215794
## 7   0.12787324  0.027901740
## 8  -0.09585722 -0.092767359
## 9  -0.21146375  0.000000000
## 10 -0.51120985  0.058273274

Notice we have lost the effects of FTND and Time due to the transformation.. Not looking good!

Let’s take a look at the QQ plot with the new model

qqmath(Model.F.2, id=0.05) #id: identifies values that may be exerting undue influence on the model (i.e. outliers)

Made it much worse… You can try other transformations (natural log, square root, etc), but there is ongoing debate as to whether or not these values should be transformed as it makes interpretation of results very difficult. In this case, since we lost the effect of FTND, it may be ok to leave as is.

8 Additional tools at your disposal

8.1 “HLMdiag”

https://cran.rstudio.com/web/packages/HLMdiag/index.html

HLMdiag is the dissertation of Adam Loy and is a useful to assess not only leverage and traditional deletion diagnostics (Cook’s distance, covratio, covtrace, and MDFFITS) but also convenience functions and graphics for residual analysis. At this time, only 2-level models are supported and it has not been updated since November of 2015, so if the other packages it requires are changed, you may have difficulties using this going forward. I’ll briefly discuss select functions below:

#case_delete() #iteratively delete groups corresponding to the levels of a hierarchical linear model, using lmer to fit the models for each deleted case

#covratio() #calculate measures of the change in the covariance matrices for the fixed effects based on the deletion of an observation, or group of observations,

#diagnostics() #is used to compute deletion diagnostics for a hierarchical linear model based on the building blocks returned by case_delete.

#HLMresid() #extracts residuals from a hierarchical linear model fit using lmer. Can provide a variety of different types of residuals based upon the specifications when you call the function

#leverage() #calculates the leverage of a hierarchical linear model fit

#mdffits() #calculate measures of the change in the fixed effects estimates based on the deletetion of an observation, or group of observations

8.2 “DHARMa”

https://cran.r-project.org/web/packages/DHARMa/vignettes/DHARMa.html

DHARMa was created by Florian Hartig in 2016 and creates readily interpretable residuals for generalized linear (mixed) models that are standardized to values between 0 and 1, and that can be interpreted as intuitively as residuals for the linear model. This is achieved by a simulation-based approach, similar to the Bayesian p-value or the parametric bootstrap, that tranforms the residuals to a standardized scale. I’ll provide some basic functions and their purposes below:

#simulateResiduals() #creates scaled (quantile) residuals through a default 250 simulations (which can be modified)

#plotSimulatedResiduals #provides qqplot and residuals vs predicted plots to determine deviations from normality

#Goodness of fit tests:
#testUniformity()
#testOverdispersion()
#testZeroinflation()
#testTemporalAutocorrelation()
#testSpatialAutocorrelation()

9 13.7 References

These have been excellent resources in illuminating theory and then implementing procedures

  1. Baayen, R. H., Davidson, D. J., & Bates, D. M. (2008). Mixed-effects modeling with crossed random effects for subjects and items. Journal of Memory and Language, 59(4), 390-412. doi:10.1016/j.jml.2007.12.005
  2. Barr, D. J., Levy, R., Scheepers, C., & Tily, H. J. (2013). Random effects structure for confirmatory hypothesis testing: Keep it maximal. Journal of Memory and Language, 68(3), 255-278.
  3. Bartlett, M. S. (1937). Properties of sufficiency and statistical tests. Proceedings of the Royal Society of London Series A 160, 268–282.
  4. Bates, D. M. (2006). [R] lmer, p-values and all that. https://stat.ethz.ch/pipermail/r-help/2006-May/094765.html
  5. Bates, D. M. (2008). [R-sig-ME] mcmcsamp can’t handle random effects syntax. https://stat.ethz.ch/pipermail/r-sig-mixed-models/2008q3/001409.html
  6. Dunn, K. P., and Smyth, G. K. (1996). Randomized quantile residuals. Journal of Computational and Graphical Statistics 5, 1-10.
  7. Fox, J. (2008). Applied Regression Analysis and Generalized Linear Models 2nd Edition. Thousand Oaks, CA: SAGE.
  8. Gelman, A., & Hill, J. (2007). Data analysis using regression and multilevel/hierarchical models. New York: Cambridge University Press.
  9. Glaser, R. E. (2006). Levene’s Robust Test of Homogeneity of Variances. Encyclopedia of Statistical Sciences. 6.
  10. Gurka, M. J., Edwards, L. J., Muller, K. E. and Kupper, L. L. (2006), Extending the Box–Cox transformation to the linear mixed model. Journal of the Royal Statistical Society: Series A (Statistics in Society), 169: 273–288. doi:10.1111/j.1467-985X.2005.00391.x
  11. Maas, C. J. M., & Hox, J. J. (2005). Sufficient sample sizes for multilevel modeling. Methodology, 1(3), 86-92
  12. Pinheiro, J. C., Bates, D. M., (2000). Mixed-effects models in S and S-plus. New York, NY: Springer.
  13. Snijders, T. A. B., & Bosker, R. J. (1999). Multilevel analysis: An introduction to basic and advanced multilevel modeling. London: Sage.
  14. van der Laan, M., & Rose, S. (2010). Statistics ready for a revolution. Amstat News. Retrieved October 7, 2011, from http://magazine.amstat.org/blog/2010/09/01/statrevolution/
  15. Verbeke, G., & Lesaffre, E. (1997). The effect of misspecifying the random-effects distribution in linear mixed models for longitudinal data. Computational Statistics & Data Analysis, 23, 541-556.
LS0tDQp0aXRsZTogIkNoYXB0ZXIgMTg6IFRlc3RpbmcgdGhlIEFzc3VtcHRpb25zIG9mIE11bHRpbGV2ZWwgTW9kZWxzIg0KYXV0aG9yOiAiTWljaGFlbCBQYWxtZXJpIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUNCiAgICBmb250c2l6ZTogOHB0DQogICAgdG9jOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCi0tLQ0KDQpOT1RFIE9OIFBBQ0tBR0VTOiBJIHVzZSB0aGUgZm9sbG93aW5nIHBhY2thZ2VzIGluIHRoaXMgY2hhcHRlci4gIElmIHlvdSBkbyBub3QgaGF2ZSB0aGVzZSBwYWNrYWdlcyBpbnN0YWxsZWQsIHlvdSBtYXkgdXNlIHRoZSBzY3JpcHQgYmVsb3cgdG8gaW5zdGFsbCB0aGVtIGFuZCBsb2FkIHRoZWlyIGxpYnJhcmllcyAoanVzdCByZW1vdmUgdGhlICIjIiBiZWZvcmUgdGhlIHBhY2thZ2UgeW91IG5lZWQgdG8gaW5zdGFsbCkuDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfSANCg0KI2luc3RhbGwucGFja2FnZXMoImxtZTQiKQ0KI2luc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KI2luc3RhbGwucGFja2FnZXMoIkhMTWRpYWciKQ0KI2luc3RhbGwucGFja2FnZXMoIkRIQVJNYSIpDQojaW5zdGFsbC5wYWNrYWdlcygiY2FyIikNCg0KI2xvYWQgdGhlIGxpYnJhcmllcyBzbyB5b3UgaGF2ZSBhY2Nlc3MgdG8gdGhlbSBpbiB5b3VyIHdvcmtmbG93DQoNCmxpYnJhcnkoImxtZTQiKQ0KbGlicmFyeSgiZ2dwbG90MiIpDQpsaWJyYXJ5KCJITE1kaWFnIikNCmxpYnJhcnkoIkRIQVJNYSIpDQpsaWJyYXJ5KCJjYXIiKSAjZm9yIHRoZSBMZXZlbmUgdGVzdCB3aGljaCB3ZSB3aWxsIG5vdCBkaXNjdXNzIGhlcmUNCmxpYnJhcnkoIk1hdHJpeCIpDQpgYGANCg0KI1ByZWZhY2UgDQpJdCBpcyBpbXBvcnRhbnQgdG8gd29yayB3aXRoaW4gdGhlIHNhbWUgZmlsZSBlbnZpcm9ubWVudCBzbyB0aGF0IGRhdGEgYW5kIGNvZGUgY2FuIGJlIGVhc2lseSBsaW5rZWQuIFRvIGRvIHNvLCBsZXQncyBzZXQgdGhlIHdvcmtpbmcgZGlyZWN0b3J5DQpgYGB7cn0NCiNzZXR3ZCgic2V0IGxvY2F0aW9ucyIpIA0KYGBgDQoNCiMgQ0FWRUFUDQpUaGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIGlzIGEgYmVzdCBhcHByb3hpbWF0aW9uIG9mIGhvdyB0byB0ZXN0IGFzc3VtcHRpb25zIG9mIG1peGVkIGFuZCBtdWx0aWxldmVsIG1vZGVscyBhcyBvZiBOb3ZlbWJlciAyMDE2LiBNdWNoIG9mIHRoZSBwcm9jZWR1cmVzIGRlc2NyaWJlZCBoYXZlIGJlZW4gcGllY2VtZWFsIHB1dCB0b2dldGhlciB0aHJvdWdoIHRoZSBjb25jYXRlbmF0aW9uIG9mIG11bHRpcGxlIHNvdXJjZXMgKGJvdGggcmVmZXJlZWQgYW5kIG5vdCkuIFRoZXJlIGlzIGJ5IG5vIG1lYW5zIGFueSBzb3J0IG9mIGNvbnNlbnN1cyB3aXRoaW4gdGhlIGZpZWxkIG9mIHN0YXRpc3RpY3MgYW5kIHRoZSBSIGNvbW11bml0eSBhcyBhIHdob2xlIGFzIHRvIGhvdyB0byBhcHByb2FjaCB0aGlzIHRvcGljIHN5c3RlbWF0aWNhbGx5LiBJJ3ZlIGF0dGVtcHRlZCB0byBwdWxsIGluIGFzIG1hbnkgZGlmZmVyZW50IGlkZWFzIGFzIGZlYXNpYmxlIGluIG15IGxpdHRsZSBjaGFwdGVyLiBBcyBzdWNoLCB3ZSB3aWxsIGJlIHVzaW5nIHRoZSAqbG1lciogYXMgb3Bwb3NlZCB0byB0aGUgKmxtZSogcGFja2FnZS4gVGhlICpsbWVyKiBwYWNrYWdlIGlzIGJldHRlciBzdWl0ZWQgZm9yIG1peGVkIGRlc2lnbnMgYW5kIHRodXMgaXMgbW9yZSBhbWVuYWJsZSB0byBtYW55IGRpZmZlcmVudCBraW5kcyBvZiBkYXRhLiBVbmZvcnR1bmF0ZWx5LCB1bmxpa2UgdGhlICpsbWUqIHBhY2thZ2UsICpsbWVyKiBET0VTIE5PVCBpbmNsdWRlIGEgd2F5IHRvIGVhc2lseSBydW4gbW9kZWwgZGlhZ25vc3RpY3MuIFNvbWUgd291bGQgc3VnZ2VzdCB0aGF0IGlmIHlvdXIgbW9kZWwgaXMgYSBzdGFuZGFyZCBNdWx0aWxldmVsIE1vZGVsIChpLmUuIG5vdCBtaXhlZCBkZXNpZ25zKSB0byB0aGVuIGp1c3QgdXNlIHRoZSAqbG1lKiBwYWNrYWdlIHRvIHN0cmVhbWxpbmUgdGhlIG1vZGVsIGJ1aWxkaW5nIHByb2Nlc3MuDQoNCg0KIyBPdmVydmlldw0KQXMgd2l0aCBhbnkgc3RhdGlzdGljYWwgbWFuaXB1bGF0aW9uLCB0aGVyZSBhcmUgYSBzcGVjaWZpYyBzZXQgb2YgYXNzdW1wdGlvbnMgdW5kZXIgd2hpY2ggd2Ugb3BlcmF0ZSB3aGVuIGNvbmR1Y3RpbmcgbXVsdGlsZXZlbCBtb2RlbHMgKE1MTSkuIFRoZXNlIGFzc3VtcHRpb25zIGFyZSBpZGVudGljYWwgdG8gdGhvc2Ugb2Ygb3JkaW5hcnkgbXVsdGlwbGUgcmVncmVzc2lvbiBhbmFseXNlcywgYnV0IHRoZSB3YXkgaW4gd2hpY2ggd2UgdGVzdCB0aGVtIGlzIHF1aXRlIGRpZmZlcmVudC4gSW4gdGhpcyBjaGFwdGVyLCB3ZSB3aWxsIGV4YW1pbmUgdGhlIHRocmVlIG1vc3QgaW1wb3J0YW50IChhbmQgbW9zdCBmcmVxdWVudGx5IHZpb2xhdGVkKSBhc3N1bXB0aW9ucyBvZiBNTE0uIFRvIGRvIHNvLCBsZXQncyB0YWtlIGEgbG9vayBhdCBzb21lIHNhbXBsZSBkYXRhLCBmaXQgYSBtb2RlbCwgYW5kIHJ1biB0aHJvdWdoIGhvdyB0byB0ZXN0IGVhY2ggYXNzdW1wdGlvbi4NCg0KIyBCdWlsZCBhIERhdGFmcmFtZQ0KTGV0J3MgY3JlYXRlIGEgc2FtcGxlIGRhdGFmcmFtZSB3aXRoIHdoaWNoIHdlIHdpbGwgcnVuIG91ciBtdWx0aWxldmVsIG1vZGVsIGFuZCB0aGVuIHRlc3Qgb3VyIGFzc3VtcHRpb25zLiBMZXQncyBzYXkgdGhlcmUgYXJlIDEwIHN1YmplY3RzIHdpdGggNCB0ZW1wb3JhbC1iYXNlZCBvYnNlcnZhdGlvbnMgKG9uZSBldmVyeSB5ZWFyKSBpbiB0aGlzIGh5cG90aGV0aWNhbCBzY2VuYXJpby4gRWFjaCBwZXJzb24gd2lsbCBoYXZlIGRhdGEgZm9yIGFnZSwgc2V4LCBhdmVyYWdlIG51bWJlciBvZiBjaWdhcmV0dGVzIHNtb2tlZCBlYWNoIHdlZWssIGxldmVsIG9mIG5pY290aW5lIGRlcGVuZGVuY2UgZnJvbSB0aGUgRmFnZXJzdHJvbSBUZXN0IG9mIE5pY290aW5lIERlcGVuZGVuY2UgKEZUTkQpLCByYXRpbmdzIG9mIGRlcHJlc3NpdmUgc3ltcHRvbXMgZnJvbSB0aGUgQmVjayBEZXByZXNzaW9uIEludmVudG9yeSAoQkRJKSwgYW5kIGEgY291bnQgdmFyaWFibGUgZm9yIHRoZSB0b3RhbCBudW1iZXIgb2YgbGlmZXRpbWUgbWFqb3IgZGVwcmVzc2l2ZSBlcGlzb2RlcyBzdWZmZXJlZCB1cCB0byB0aGF0IHBvaW50IG9mIGRhdGEgY29sbGVjdGlvbi4NCmBgYHtyfQ0KI0NyZWF0ZSB2ZWN0b3JzIGZvciBlYWNoIG9mIHRoZSB2YXJpYWJsZXMNClN1YmplY3RzIDwtIGMocmVwLmludCgxLDQpLHJlcC5pbnQoMiw0KSxyZXAuaW50KDMsNCkscmVwLmludCg0LDQpLHJlcC5pbnQoNSw0KSxyZXAuaW50KDYsNCkscmVwLmludCg3LDQpLHJlcC5pbnQoOCw0KSxyZXAuaW50KDksNCkscmVwLmludCgxMCw0KSkgDQpUaW1lIDwtIGMocmVwKDE6NCwxMCkpICN0aGlzIGlzIGZvciBpbGx1c3RyYXRpdmUgcHVycG9zZXMgb25seSAtIHRoZXNlIG1vZGVscyBhcmUgbXVjaCBtb3JlIGhlbHBmdWwgd2l0aCBtYW55IGRpZmZlcmVudCBkYXRhIHBvaW50cyBwZXIgc3ViamVjdA0KQWdlIDwtIGMoMTg6MjEsIDE5OjIyLCAxODoyMSwgMjA6MjMsIDE5OjIyLCAyMjoyNSwgMjE6MjQsIDE5OjIyLCAyMDoyMywgMjA6MjMpDQpTZXggPC0gYyhyZXAoIk0iLDgpLHJlcCgiRiIsNCkscmVwKCJNIiw0KSxyZXAoIkYiLDEyKSxyZXAoIk0iLDQpLHJlcCgiRiIsOCkpDQpDaWdhcmV0dGVzIDwtIGMoMTAsMTIsMTQsMCwyMCwyMCwyMCwyMCwxMCwyMCwyNSw0MCwxMiw5LDgsOCw0LDQsOCwyMCwxMCwxMCwxMCwxMCwxMCwyMCwzMCw2MCwwLDAsMCwwLDAsMSwyLDMsMCwwLDAsMzApDQpGYWdlcnN0cm9tIDwtIGMoNiw4LDgsMCwxMCwxMCwxMCwxMCw4LDksOSwxMCw2LDgsMTAsMTIsNyw3LDYsNywyLDIsMyw4LDksOSw5LDksMTAsMTAsMTIsMTMsMCwwLDAsMCwwLDAsMCwxMikNCkJESSA8LSBjKDcsNyw4LDksNCw1LDYsOCwyLDIsMiwyLDMsNCw3LDgsMTIsMTQsMTQsMTcsMjIsMjIsMTAsOSw3LDUsNiw4LDEyLDE1LDYsMTgsMTIsMTQsOCw0LDMsMiwyLDEpDQpEZXByZXNzaW9uIDwtIGMoMSwxLDIsMywyLDMsMywzLDAsMSwxLDEsMiwyLDIsMiw0LDUsNiw2LDMsMyw0LDUsMiwyLDIsMiwxLDEsMSwxLDMsMyw0LDUsMSwxLDIsMikNCg0KI0NvbWJpbmUgdGhlIHZlY3RvcnMgaW50byBhIHNpbmdsZSBkYXRhIGZyYW1lDQpDaWdhcmV0dGUuU3R1ZHk8LWRhdGEuZnJhbWUoDQogIHN1YmplY3RJRCA9IFN1YmplY3RzLA0KICBUaW1lID0gVGltZSwNCiAgU2V4ID0gU2V4LA0KICBBZ2UgPSBBZ2UsDQogIENpZ3MgPSBDaWdhcmV0dGVzLA0KICBGVE5EID0gRmFnZXJzdHJvbSwNCiAgQkRJID0gQkRJLA0KICBEZXByZXNzaW9uID0gRGVwcmVzc2lvbikNCg0KQ2lnYXJldHRlLlN0dWR5JFNleC5JPC1pZmVsc2UoQ2lnYXJldHRlLlN0dWR5JFNleD09Ik0iLDAsMSkgI2NyZWF0ZXMgYSBudW1lcmljYWwgdmFsdWUgIlNleCIgdGhhdCB3ZSBjYW4gcnVuIGFuYWx5c2VzIG9uDQoNCkNpZ2FyZXR0ZS5TdHVkeQ0KDQoNCiNDaGVjayB0aGUgc3RydWN0dXJlIG9mIHRoYXQgZGF0YSBmcmFtZQ0Kc3RyKENpZ2FyZXR0ZS5TdHVkeSkNCmBgYA0KDQojIFJ1biBhIE11bHRpbGV2ZWwgTW9kZWwgd2l0aCBvdXIgRGF0YQ0KU2tpcHBpbmcgYWxsIG9mIHRoZSByZXF1aXNpdGUgbW9kZWwgYnVpbGRpbmcgc3RlcHMsIHNheSB3ZSBmaW5kIGEgbW9kZWwgcHJlZGljdGluZyBjaWdhcmV0dGUgdXNlIGJhc2VkIG9uIHNlbGYtcmVwb3J0ZWQgc3ltcHRvbXMgb2YgZGVwcmVzc2lvbiAoQkRJKSwgVGltZSwgQkRJIGJ5IFRpbWUgaW50ZXJhY3Rpb24gKEJESSpUaW1lKSwgRlRORCBzY29yZSwgd2l0aCBhIHJhbmRvbSBpbnRlcmNlcHQgZm9yIGVhY2ggcGVyc29uLCBhbiBpbmRlcGVuZGVudGx5IHZhcnlpbmcgRlRORCBzY29yZSBmb3IgZWFjaCBwZXJzb24sIGFuZCBkZXByZXNzaXZlIGVwaXNvZGVzIGJ5IHNleCBmaXRzIHRoZSBkYXRhIHRoZSBiZXN0IGFuZCBleHBsYWlucyB0aGUgbW9zdCBhbW91bnQgb2YgdmFyaWFuY2UuDQpgYGB7cn0NCk1vZGVsLkY8LWxtZXIoQ2lncyB+IFRpbWUqQkRJK0ZUTkQNCiAgICAgICAgICAgICAgICArKDF8c3ViamVjdElEKSArICgwK0ZUTkR8c3ViamVjdElEKSwgI3JhbmRvbSBlZmZlY3RzIGZvciBzdWJqZWN0IElEIGFuZCAoKykgRlRORCBieSAofCkgc3ViamVjdCwgd2hpY2ggYXJlIGFsbG93ZWQgdG8gdmFyeSBpbmRlcGVuZGVudGx5IGZyb20gZWFjaG90aGVyICh0aGUgMSBhbmQgMCBub3RhdGlvbikNCiAgICAgICAgICAgICAgZGF0YT1DaWdhcmV0dGUuU3R1ZHksIFJFTUw9RkFMU0UpDQpgYGANCg0KDQojIyBFeGFtaW5lIHJlc3VsdHMsIHdoYXQgZG8gdGhleSBtZWFuPw0KYGBge3J9DQpzdW1tYXJ5KE1vZGVsLkYpICNzdW1tYXJpemVzIHRoZSByZXN1bHRzIG9mIHRoZSBtb2RlbCAtIHNvbWVob3cgaW4gdGhlICJrbml0dGluZyBwcm9jZXNzIiBzaWduaWZpY2FuY2Ugc3RhcnMgaGF2ZSBiZWVuIGxvc3QgLSBSIGNvZGUgc3VnZ2VzdHMgYSBzaWduaWZpY2FudCBlZmZlY3Qgb2YgdGltZSBhbmQgRlRORCBzY29yZQ0KcmFuZWYoTW9kZWwuRikgI2V4YW1pbmVzIHRoZSByYW5kb20gZWZmZWN0cyAoaS5lIHRoaW5ncyB0aGF0IGFyZSBhbGxvd2VkIHRvIHZhcnkgYWNyb3NzIHVuaXRzLCBpbiB0aGlzIGNhc2UgZWFjaCByZXByZXNlbnRpbmcgb3VyIHN1YmplY3QtbGV2ZWwgZWZmZWN0IG9mIEZUTkQgZm9yIG91ciAxMCBwYXJ0aWNpcGFudHMpDQpgYGANClRoZSBmaXJzdCB0aGluZyB0byBub3RlIGlzIHRoYXQgcCB2YWx1ZXMgYXJlIG5vdCByZXBvcnRlZCBieSBkZWZhdWx0LiBUaGlzIGlzIGJlY2F1c2UgdGhlICpsbWUqIGFuZCAqbG1lciogcGFja2FnZXMgd2VyZSB3cml0dGVuIGluIGxhcmdlIHBhcnQgYnkgRG91ZyBCYXRlcyBmcm9tIHRoZSBVbml2ZXJzaXR5IG9mIFdpc2NvbnNpbi1NYWRpc29uLiBEci4gQmF0ZXMgaXMgbm90IGEgZmFuIG9mIHAgdmFsdWUgYW5kIHN1YnNlcXVlbnRseSBjaG9zZSBub3QgdG8gZGlzcGxheSBpdCBpbiBoaXMgcGFja2FnZXMuIE91ciByZXN1bHRzIHN1Z2dlc3QgdGhhdCBib3RoIHRpbWUgYW5kIEZhZ2Vyc3Ryb20gc2NvcmVzIGFyZSBwcmVkaWN0aXZlIG9mIGNpZ2FyZXR0ZSB1c2UgLi4uLiBCdXQsIGdpdmVuIG91ciBzbWFsbCBzYW1wbGUgc2l6ZSAoYW5kIHNlZSBNYWFzICYgSG94IDIwMDUgZm9yIGFuIGV4aGF1c3RpdmUgZGlzY3Vzc2lvbiBvbiBtaW5pbWFsIHNhbXBsZSBzaXplcyksIGNhbiB3ZSBiZSBhc3N1cmVkIHRoYXQgdGhlIGFzc3VtcHRpb25zIHVuZGVyIHdoaWNoIHdlIG9wZXJhdGUgdG8gY29uZHVjdCBzdWNoIGFuYWx5c2VzIGFyZSBiZWluZyBtZXQ/DQoNCiMgQXNzdW1wdGlvbnMNCiMjIEFzc3VtcHRpb24gMSAtIExpbmVhcml0eQ0KQSByZWdyZXNzaW9uIGFuYWx5c2lzIGlzIG1lYW50IHRvIGZpdCB0aGUgYmVzdCByZWN0aWxpbmVhciBsaW5lIHRoYXQgZXhwbGFpbnMgdGhlIG1vc3QgZGF0YSBnaXZlbiB5b3VyIHNldCBvZiBwYXJhbWV0ZXJzLiBUaGVyZWZvcmUsIHRoZSBiYXNlIG1vZGVscyByZWx5IG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQgeW91ciBkYXRhIGZvbGxvd3MgYSBzdHJhaWdodCBsaW5lICh0aG91Z2ggdGhlIG1vZGVscyBjYW4gYmUgZXhwYW5kZWQgdG8gaGFuZGxlIGN1cnZpbGluZWFyIGRhdGEpLg0KDQojIyNIb3cgZG8geW91IHRlc3QgdGhpcyBhc3N1bXB0aW9uPw0KR3JhcGhpY2FsbHksIHBsb3R0aW5nIHRoZSBtb2RlbCByZXNpZHVhbHMgKHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIG9ic2VydmVkIHZhbHVlIGFuZCB0aGUgbW9kZWwtZXN0aW1hdGVkIHZhbHVlKSB2cyB0aGUgcHJlZGljdG9yIGlzIG9uZSBzaW1wbGUgd2F5IHRvIHRlc3QuIElmIGEgcGF0dGVybiBlbWVyZ2VzIChhbnl0aGluZyB0aGF0IGxvb2tzIG5vbi1yYW5kb20pLCBhIGhpZ2hlciBvcmRlciB0ZXJtIG1heSBuZWVkIHRvIGJlIGluY2x1ZGVkIG9yIHlvdSBtYXkgbmVlZCB0byBtYXRoZW1hdGljYWxseSB0cmFuc2Zvcm0gYSBwcmVkaWN0b3IvcmVzcG9uc2UuIEluIFIsIHdlJ2xsIHVzZSB0aGUgc2ltcGxlIHBsb3QgZnVuY3Rpb24gdG8gY29tcGFyZSB0aGUgbW9kZWwtcHJlZGljdGVkIHZhbHVlcyB0byB0aGUgb2JzZXJ2ZWQgb25lcy4NCmBgYHtyfQ0KUGxvdC5Nb2RlbC5GLkxpbmVhcml0eTwtcGxvdChyZXNpZChNb2RlbC5GKSxDaWdhcmV0dGVzKSAjcmVzaWQoKSBjYWxscyBmb3IgdGhlIHJlc2lkdWFscyBvZiB0aGUgbW9kZWwsIENpZ2FyZXR0ZXMgd2FzIG91ciBpbml0aWFsIG91dGNvbWUgdmFyaWFibGVzIC0gd2UncmUgcGxvdHRpbmcgdGhlIHJlc2lkdWFscyB2cyBvYnNlcnZlcmVkDQpgYGANCg0KTG9va3MgcHJldHR5IHJhbmRvbSBzbyB3ZSBwcm9iYWJseSBoYXZlbid0IHZpb2xhdGVkIHRoaXMgYXNzdW1wdGlvbiAoc2VlIEZveCAyMDA4IGZvciBhIGRpc2N1c3Npb24gYWJvdXQgdGhlIHV0aWxpdHkgb2Ygc2lnbmlmaWNhbmNlIHZzIHZpc3VhbCB0ZXN0aW5nOyBlc3NlbnRpYWxseSB0aGV5IGFyZ3VlIHRoYXQgc2lnbmlmaWNhbmNlIHRlc3RzIGRvbid0IG9mZmVyIHlvdSBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRoYXQgeW91ciBuYWtlZCBleWUgY2FuJ3QgYWxyZWFkeSBkZXRlY3QpLiBMZXQncyBsb29rIGF0IGFzc3VtcHRpb24gIzINCg0KIyMgQXNzdW1wdGlvbiAyIEhvbW9nZW5laXR5IG9mIFZhcmlhbmNlDQpSZWdyZXNzaW9uIG1vZGVscyBhc3N1bWUgdGhhdCB2YXJpYW5jZSBvZiB0aGUgcmVzaWR1YWxzIGlzIGVxdWFsIGFjcm9zcyBncm91cHMuIEluIHRoaXMgY2FzZSwgdGhlIGdyb3VwcyB3ZSdyZSByZWZlcnJpbmcgdG8gYXJlIGF0IHRoZSBpbmRpdmlkdWFsIChpLmUuIHN1YmplY3QpIGxldmVsLiAgDQoNCiMjI0hvdyBkbyB5b3UgdGVzdCB0aGlzIGFzc3VtcHRpb24/DQpSIGlzIGFuIGV4Y2VsbGVudCBwcm9ncmFtIGZvciBleHRyYWN0aW5nIGFuZCBzdG9yaW5nIHlvdXIgbW9kZWwgcmVzaWR1YWxzLiBBZnRlciB3ZSBoYXZlIHRoZW0gaW4gcGxhY2UsIHdlIGNhbiBkbyBhIHNpbXBsZSBBTk9WQSB0byBkZXRlcm1pbmUgaWYgdGhleSdyZSBkaWZmZXJlbnQgZm9yIGVhY2ggcGVyc29uLiBUaGlzIHByb2NlZHVyZSBpcyBhIHZhcmlhdGlvbiBvZiAiTGV2ZW5lJ3MgVGVzdCIuIEVzc2VudGlhbGx5LCB3ZSdsbCBleHRyYWN0IHRoZSByZXNpZHVhbHMgZnJvbSB0aGUgbW9kZWwsIHBsYWNlIHRoZW0gaW4gb3VyIG9yaWdpbmFsIHRhYmxlLCB0YWtlIHRoZWlyIGFic29sdXRlIHZhbHVlLCBhbmQgdGhlbiBzcXVhcmUgdGhlbSAoZm9yIGEgbW9yZSByb2J1c3QgYW5hbHlzaXMgd2l0aCByZXNwZWN0IHRvIGlzc3VlcyBvZiBub3JtYWxpdHksIHNlZSBHbGFzZXIgMjAwNikuIEZpbmFsbHkgd2UnbGwgdGFrZSBhIGxvb2sgYXQgdGhlIEFOT1ZBIG9mIHRoZSBiZXR3ZWVuIHN1YmplY3RzIHJlc2lkdWFscy4gTGV0J3MgZ2l2ZSBpdCBhIHNob3QgYmVsb3c6DQpgYGB7cn0NCiNmb3IgdGhpcyBwb3J0aW9uIG9mIHRoZSBhbmFseXNpcywgd2UgbmVlZCB0byByZXZpc2l0IGFib3V0IHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSAtIHNpbmNlIHRoZSBhc3N1bXB0aW9uIGlzIHRoYXQgdGhlIHZhcmlhbmNlIGlzIG5vdCBnb2luZyB0byBkaWZmZXIsIHdlIHdvdWxkIGhvcGUgdG8gc2VlIE5PIFNUQVRJU1RJQ0FMIERJRkZFUkVOQ0VTIGluIHRoZSBmb2xsb3dpbmcgcHJvY2VkdXJlIChpLmUuIHA+MC4wNSkgdG8gY29uZmlybSB0aGF0IC0NCg0KDQpDaWdhcmV0dGUuU3R1ZHkkTW9kZWwuRi5SZXM8LSByZXNpZHVhbHMoTW9kZWwuRikgI2V4dHJhY3RzIHRoZSByZXNpZHVhbHMgYW5kIHBsYWNlcyB0aGVtIGluIGEgbmV3IGNvbHVtbiBpbiBvdXIgb3JpZ2luYWwgZGF0YSB0YWJsZQ0KQ2lnYXJldHRlLlN0dWR5JEFicy5Nb2RlbC5GLlJlcyA8LWFicyhDaWdhcmV0dGUuU3R1ZHkkTW9kZWwuRi5SZXMpICNjcmVhdGVzIGEgbmV3IGNvbHVtbiB3aXRoIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgcmVzaWR1YWxzDQpDaWdhcmV0dGUuU3R1ZHkkTW9kZWwuRi5SZXMyIDwtIENpZ2FyZXR0ZS5TdHVkeSRBYnMuTW9kZWwuRi5SZXNeMiAjc3F1YXJlcyB0aGUgYWJzb2x1dGUgdmFsdWVzIG9mIHRoZSByZXNpZHVhbHMgdG8gcHJvdmlkZSB0aGUgbW9yZSByb2J1c3QgZXN0aW1hdGUNCkxldmVuZS5Nb2RlbC5GIDwtIGxtKE1vZGVsLkYuUmVzMiB+IHN1YmplY3RJRCwgZGF0YT1DaWdhcmV0dGUuU3R1ZHkpICNBTk9WQSBvZiB0aGUgc3F1YXJlZCByZXNpZHVhbHMNCmFub3ZhKExldmVuZS5Nb2RlbC5GKSAjZGlzcGxheXMgdGhlIHJlc3VsdHMNCmBgYA0KIyMjV2hhdCBkbyB0aGUgcmVzdWx0cyBtZWFuPw0KU2luY2UgdGhlIHAgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDAuMDUsIHdlIGNhbiBzYXkgdGhhdCB0aGUgdmFyaWFuY2Ugb2YgdGhlIHJlc2lkdWFscyBpcyBlcXVhbCBhbmQgdGhlcmVmb3JlIHRoZSBhc3N1bXB0aW9uIG9mIGhvbW9zY2VkYXN0aWNpdHkgaXMgbWV0DQpOb3RlOiBSIGRvZXMgaGF2ZSBidWlsdC1pbiBvciBwYWNrYWdlIG1hZGUgTGV2ZW5lIChhbmQgbGVzcyB0aGUgZmxleGlibGUgQmFydGxldHQpIHRlc3RzLCBidXQgSSBjb3VsZG4ndCBmaWd1cmUgb3V0IGhvdyB0byBpbXBsZW1lbnQgdGhlbSB3aXRoIHJlc3BlY3QgdG8gKmxtZXIqLiBGZWVsIGZyZWUgdG8gZXhwbG9yZSB0aGVzZSBvcHRpb25zIG9uIHlvdXIgb3duLg0KDQoNCiMjI0hvdyBhYm91dCBhIHZpc3VhbCBzb2x1dGlvbj8NCmBgYHtyfQ0KUGxvdC5Nb2RlbC5GIDwtIHBsb3QoTW9kZWwuRikgI2NyZWF0ZXMgYSBmaXR0ZWQgdnMgcmVzaWR1YWwgcGxvdA0KUGxvdC5Nb2RlbC5GDQpgYGANClRoZXJlIHNlZW1zIHRvIGJlIGV2ZW4gc3ByZWFkIGFyb3VuZCB0aGUgY2VudGVyZWQgbGluZSwgYnV0IEkgcHJlZmVyIHRoZSBMZXZlbmUncyB0ZXN0IGFzIEknbSBub3QgZW50aXJlbHkgc3VyZSB3aGF0IHRoaXMgZ3JhcGggaXMgc3VwcG9zZWQgdG8gbG9vayBsaWtlDQoNCg0KIyMgQXNzdW1wdGlvbiAzOiBUaGUgcmVzaWR1YWxzIG9mIHRoZSBtb2RlbCBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQpSZWdyZXNzaW9uIG1vZGVscyBkb24ndCByZXF1aXJlIHRoYXQgb3V0Y29tZSB2YXJpYWJsZXMgbmVlZCB0byBiZSBub3JtYWxseSBkaXN0cmlidXRlZCAoc2VlOiBMb2dpc3RpYyBvciBQb2lzc29uIHJlZ3Jlc3Npb24gbW9kZWxzKSwgaG93ZXZlciBNTE0gYXNzdW1lIHRoYXQgdGhlIHJlc2lkdWFscyBvZiB0aGUgYW5hbHlzaXMgQVJFIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KDQojIyNIb3cgZG8geW91IHRlc3QgdGhpcyBhc3N1bXB0aW9uPw0KUVEgcGxvdHMgKHdoaWNoIGFyZSBlYXNpbHkgb2J0YWluZWQgaW4gc3RhbmRhcmQgcmVncmVzc2lvbiBtb2RlbGluZyBpbiBSKSBjYW4gcHJvdmlkZSBhbiBlc3RpbWF0aW9uIG9mIHdoZXJlIHRoZSBzdGFuZGFyZGl6ZWQgcmVzaWR1YWxzIGxpZSB3aXRoIHJlc3BlY3QgdG8gbm9ybWFsIHF1YW50aWxlcy4gU3Ryb25nIGRldmlhdGlvbiBmcm9tIHRoZSBwcm92aWRlZCBsaW5lIGluZGljYXRlcyB0aGF0IHRoZSByZXNpZHVhbHMgdGhlbXNlbHZlcyBhcmUgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KYGBge3J9DQojI3FxIHBsb3QgKHNpbWlsYXIgdG8gYSBkaWFnbm9zdGljIHBsb3QgcHJvdmlkZWQgYnkgdGhlIGxtIGZ1bmN0aW9uKSBmb3IgYW4gZXN0aW1hdGlvbiBvZiB0aGUgbGluZWFyaXR5IG9mIHRoZSByZXNpZHVhbHMNCnJlcXVpcmUoImxhdHRpY2UiKQ0KcXFtYXRoKE1vZGVsLkYsIGlkPTAuMDUpICNpZDogaWRlbnRpZmllcyB2YWx1ZXMgdGhhdCBtYXkgYmUgZXhlcnRpbmcgdW5kdWUgaW5mbHVlbmNlIG9uIHRoZSBtb2RlbCAoaS5lLiBvdXRsaWVycykNCmBgYA0KDQpUaGVyZSBpcyBzb21lIGRldmlhdGlvbiBmcm9tIGZyb20gdGhlIGV4cGVjdGVkIG5vcm1hbCBsaW5lIHRvd2FyZHMgdGhlIHRhaWxzLCBidXQgb3ZlcmFsbCB0aGUgbGluZSBsb29rcyBzdHJhaWdodCBhbmQgdGhlcmVmb3JlIHByZXR0eSBub3JtYWwgYW5kIHN1Z2dlc3RzIHRoYXQgdGhlIGFzc3VtcHRpb24gaXMgbm90IHZpb2xhdGVkLiBTZWUgaHR0cDovL2RhdGEubGlicmFyeS52aXJnaW5pYS5lZHUvZGlhZ25vc3RpYy1wbG90cy8gYW5kIGh0dHBzOi8vd3d3LnItYmxvZ2dlcnMuY29tL21vZGVsLXZhbGlkYXRpb24taW50ZXJwcmV0aW5nLXJlc2lkdWFsLXBsb3RzLyBmb3IgbW9yZSBpbmZvcm1hdGlvbiByZWdhcmRpbmcgdGhlc2UgdmlzdWFsIHRlc3RzLg0KDQojIFdoYXQgaWYgdGhlIGFzc3VtcHRpb24gb2Ygbm9ybWFsaXR5IGlzIHZpb2xhdGVkPw0KIyMgVHJhbnNmb3JtIQ0KVHJhbnNmb3JtYXRpb25zIGNhbiBiZSBkb25lIHRvIGltcHJvdmUgdGhlIHJlbGF0aXZlIG5vcm1hbGl0eSBvZiB0aGUgZGF0YS4gTW9zdCBjb21tb25seSB1c2VkIHRyYW5zZm9ybWF0aW9ucyBhcmUgbG9nL2xuLiBMZXQncyBjcmVhdGUgbG9nKDEwKSB0cmFuc2Zvcm1lZCBvdXRjb21lIHZhcmlhYmxlcyB0byBzZWUgaWYgaXQgaW1wcm92ZXMgdGhlIG5vcm1hbGl0eSBvZiB0aGUgcmVzaWR1YWxzLg0KYGBge3J9DQpDaWdhcmV0dGUuU3R1ZHkkQ2lnLlBsdXMuMSA8LSBDaWdhcmV0dGVzKzENCkNpZ2FyZXR0ZS5TdHVkeSRDaWcuTG9nIDwtIGxvZzEwKENpZ2FyZXR0ZS5TdHVkeSRDaWcuUGx1cy4xKQ0KDQpzdHIoQ2lnYXJldHRlLlN0dWR5KQ0KDQoNCk1vZGVsLkYuMjwtbG1lcihDaWcuTG9nIH4gVGltZSpCREkrRlRORA0KICAgICAgICAgICAgICAgICsoMXxzdWJqZWN0SUQpICsgKDArRlRORHxzdWJqZWN0SUQpLA0KICAgICAgICAgICAgICBkYXRhPUNpZ2FyZXR0ZS5TdHVkeSwgUkVNTD1GQUxTRSkNCg0Kc3VtbWFyeShNb2RlbC5GLjIpICNzdW1tYXJpemVzIHRoZSByZXN1bHRzIG9mIHRoZSBtb2RlbA0KDQpyYW5lZihNb2RlbC5GLjIpICNleGFtaW5lcyB0aGUgcmFuZG9tIGVmZmVjdHMNCmBgYA0KTm90aWNlIHdlIGhhdmUgbG9zdCB0aGUgZWZmZWN0cyBvZiBGVE5EIGFuZCBUaW1lIGR1ZSB0byB0aGUgdHJhbnNmb3JtYXRpb24uLiBOb3QgbG9va2luZyBnb29kIQ0KDQpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgUVEgcGxvdCB3aXRoIHRoZSBuZXcgbW9kZWwNCmBgYHtyfQ0KcXFtYXRoKE1vZGVsLkYuMiwgaWQ9MC4wNSkgI2lkOiBpZGVudGlmaWVzIHZhbHVlcyB0aGF0IG1heSBiZSBleGVydGluZyB1bmR1ZSBpbmZsdWVuY2Ugb24gdGhlIG1vZGVsIChpLmUuIG91dGxpZXJzKQ0KYGBgDQoNCk1hZGUgaXQgbXVjaCB3b3JzZS4uLiBZb3UgY2FuIHRyeSBvdGhlciB0cmFuc2Zvcm1hdGlvbnMgKG5hdHVyYWwgbG9nLCBzcXVhcmUgcm9vdCwgZXRjKSwgYnV0IHRoZXJlIGlzIG9uZ29pbmcgZGViYXRlIGFzIHRvIHdoZXRoZXIgb3Igbm90IHRoZXNlIHZhbHVlcyBzaG91bGQgYmUgdHJhbnNmb3JtZWQgYXMgaXQgbWFrZXMgaW50ZXJwcmV0YXRpb24gb2YgcmVzdWx0cyB2ZXJ5IGRpZmZpY3VsdC4gSW4gdGhpcyBjYXNlLCBzaW5jZSB3ZSBsb3N0IHRoZSBlZmZlY3Qgb2YgRlRORCwgaXQgbWF5IGJlIG9rIHRvIGxlYXZlIGFzIGlzLg0KDQojIEFkZGl0aW9uYWwgdG9vbHMgYXQgeW91ciBkaXNwb3NhbCANCiMjICJITE1kaWFnIiANCg0KaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tL3dlYi9wYWNrYWdlcy9ITE1kaWFnL2luZGV4Lmh0bWwNCg0KSExNZGlhZyBpcyB0aGUgZGlzc2VydGF0aW9uIG9mIEFkYW0gTG95IGFuZCBpcyBhIHVzZWZ1bCB0byBhc3Nlc3Mgbm90IG9ubHkgbGV2ZXJhZ2UgYW5kIHRyYWRpdGlvbmFsIGRlbGV0aW9uIGRpYWdub3N0aWNzIChDb29rJ3MgZGlzdGFuY2UsIGNvdnJhdGlvLCBjb3Z0cmFjZSwgYW5kIE1ERkZJVFMpIGJ1dCBhbHNvIGNvbnZlbmllbmNlIGZ1bmN0aW9ucyBhbmQgZ3JhcGhpY3MgZm9yIHJlc2lkdWFsIGFuYWx5c2lzLiBBdCB0aGlzIHRpbWUsIG9ubHkgMi1sZXZlbCBtb2RlbHMgYXJlIHN1cHBvcnRlZCBhbmQgaXQgaGFzIG5vdCBiZWVuIHVwZGF0ZWQgc2luY2UgTm92ZW1iZXIgb2YgMjAxNSwgc28gaWYgdGhlIG90aGVyIHBhY2thZ2VzIGl0IHJlcXVpcmVzIGFyZSBjaGFuZ2VkLCB5b3UgbWF5IGhhdmUgZGlmZmljdWx0aWVzIHVzaW5nIHRoaXMgZ29pbmcgZm9yd2FyZC4gSSdsbCBicmllZmx5IGRpc2N1c3Mgc2VsZWN0IGZ1bmN0aW9ucyBiZWxvdzoNCmBgYHtyfQ0KI2Nhc2VfZGVsZXRlKCkgI2l0ZXJhdGl2ZWx5IGRlbGV0ZSBncm91cHMgY29ycmVzcG9uZGluZyB0byB0aGUgbGV2ZWxzIG9mIGEgaGllcmFyY2hpY2FsIGxpbmVhciBtb2RlbCwgdXNpbmcgbG1lciB0byBmaXQgdGhlIG1vZGVscyBmb3IgZWFjaCBkZWxldGVkIGNhc2UNCg0KI2NvdnJhdGlvKCkgI2NhbGN1bGF0ZSBtZWFzdXJlcyBvZiB0aGUgY2hhbmdlIGluIHRoZSBjb3ZhcmlhbmNlIG1hdHJpY2VzIGZvciB0aGUgZml4ZWQgZWZmZWN0cyBiYXNlZCBvbiB0aGUgZGVsZXRpb24gb2YgYW4gb2JzZXJ2YXRpb24sIG9yIGdyb3VwIG9mIG9ic2VydmF0aW9ucywNCg0KI2RpYWdub3N0aWNzKCkgI2lzIHVzZWQgdG8gY29tcHV0ZSBkZWxldGlvbiBkaWFnbm9zdGljcyBmb3IgYSBoaWVyYXJjaGljYWwgbGluZWFyIG1vZGVsIGJhc2VkIG9uIHRoZSBidWlsZGluZyBibG9ja3MgcmV0dXJuZWQgYnkgY2FzZV9kZWxldGUuDQoNCiNITE1yZXNpZCgpICNleHRyYWN0cyByZXNpZHVhbHMgZnJvbSBhIGhpZXJhcmNoaWNhbCBsaW5lYXIgbW9kZWwgZml0IHVzaW5nIGxtZXIuIENhbiBwcm92aWRlIGEgdmFyaWV0eSBvZiBkaWZmZXJlbnQgdHlwZXMgb2YgcmVzaWR1YWxzIGJhc2VkIHVwb24gdGhlIHNwZWNpZmljYXRpb25zIHdoZW4geW91IGNhbGwgdGhlIGZ1bmN0aW9uDQoNCiNsZXZlcmFnZSgpICNjYWxjdWxhdGVzIHRoZSBsZXZlcmFnZSBvZiBhIGhpZXJhcmNoaWNhbCBsaW5lYXIgbW9kZWwgZml0DQoNCiNtZGZmaXRzKCkgI2NhbGN1bGF0ZSBtZWFzdXJlcyBvZiB0aGUgY2hhbmdlIGluIHRoZSBmaXhlZCBlZmZlY3RzIGVzdGltYXRlcyBiYXNlZCBvbiB0aGUgZGVsZXRldGlvbiBvZiBhbiBvYnNlcnZhdGlvbiwgb3IgZ3JvdXAgb2Ygb2JzZXJ2YXRpb25zDQpgYGANCg0KIyMgIkRIQVJNYSIgDQoNCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9ESEFSTWEvdmlnbmV0dGVzL0RIQVJNYS5odG1sDQoNCkRIQVJNYSB3YXMgY3JlYXRlZCBieSBGbG9yaWFuIEhhcnRpZyBpbiAyMDE2IGFuZCBjcmVhdGVzIHJlYWRpbHkgaW50ZXJwcmV0YWJsZSByZXNpZHVhbHMgZm9yICpnZW5lcmFsaXplZCogbGluZWFyIChtaXhlZCkgbW9kZWxzIHRoYXQgYXJlIHN0YW5kYXJkaXplZCB0byB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxLCBhbmQgdGhhdCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgaW50dWl0aXZlbHkgYXMgcmVzaWR1YWxzIGZvciB0aGUgbGluZWFyIG1vZGVsLiBUaGlzIGlzIGFjaGlldmVkIGJ5IGEgc2ltdWxhdGlvbi1iYXNlZCBhcHByb2FjaCwgc2ltaWxhciB0byB0aGUgQmF5ZXNpYW4gcC12YWx1ZSBvciB0aGUgcGFyYW1ldHJpYyBib290c3RyYXAsIHRoYXQgdHJhbmZvcm1zIHRoZSByZXNpZHVhbHMgdG8gYSBzdGFuZGFyZGl6ZWQgc2NhbGUuIEknbGwgcHJvdmlkZSBzb21lIGJhc2ljIGZ1bmN0aW9ucyBhbmQgdGhlaXIgcHVycG9zZXMgYmVsb3c6DQpgYGB7cn0NCiNzaW11bGF0ZVJlc2lkdWFscygpICNjcmVhdGVzIHNjYWxlZCAocXVhbnRpbGUpIHJlc2lkdWFscyB0aHJvdWdoIGEgZGVmYXVsdCAyNTAgc2ltdWxhdGlvbnMgKHdoaWNoIGNhbiBiZSBtb2RpZmllZCkNCg0KI3Bsb3RTaW11bGF0ZWRSZXNpZHVhbHMgI3Byb3ZpZGVzIHFxcGxvdCBhbmQgcmVzaWR1YWxzIHZzIHByZWRpY3RlZCBwbG90cyB0byBkZXRlcm1pbmUgZGV2aWF0aW9ucyBmcm9tIG5vcm1hbGl0eQ0KDQojR29vZG5lc3Mgb2YgZml0IHRlc3RzOg0KI3Rlc3RVbmlmb3JtaXR5KCkNCiN0ZXN0T3ZlcmRpc3BlcnNpb24oKQ0KI3Rlc3RaZXJvaW5mbGF0aW9uKCkNCiN0ZXN0VGVtcG9yYWxBdXRvY29ycmVsYXRpb24oKQ0KI3Rlc3RTcGF0aWFsQXV0b2NvcnJlbGF0aW9uKCkNCg0KYGBgDQoNCg0KIzEzLjcgUmVmZXJlbmNlcw0KDQpUaGVzZSBoYXZlIGJlZW4gZXhjZWxsZW50IHJlc291cmNlcyBpbiBpbGx1bWluYXRpbmcgdGhlb3J5IGFuZCB0aGVuIGltcGxlbWVudGluZyBwcm9jZWR1cmVzDQoNCjEuIEJhYXllbiwgUi4gSC4sIERhdmlkc29uLCBELiBKLiwgJiBCYXRlcywgRC4gTS4gKDIwMDgpLiBNaXhlZC1lZmZlY3RzIG1vZGVsaW5nIHdpdGggY3Jvc3NlZCByYW5kb20gZWZmZWN0cyBmb3Igc3ViamVjdHMgYW5kIGl0ZW1zLiBKb3VybmFsIG9mIE1lbW9yeSBhbmQgTGFuZ3VhZ2UsIDU5KDQpLCAzOTAtNDEyLiBkb2k6MTAuMTAxNi9qLmptbC4yMDA3LjEyLjAwNQ0KMi4gQmFyciwgRC4gSi4sIExldnksIFIuLCBTY2hlZXBlcnMsIEMuLCAmIFRpbHksIEguIEouICgyMDEzKS4gUmFuZG9tIGVmZmVjdHMgc3RydWN0dXJlIGZvciBjb25maXJtYXRvcnkgaHlwb3RoZXNpcyB0ZXN0aW5nOiBLZWVwIGl0IG1heGltYWwuIEpvdXJuYWwgb2YgTWVtb3J5IGFuZCBMYW5ndWFnZSwgNjgoMyksIDI1NS0yNzguDQozLiBCYXJ0bGV0dCwgTS4gUy4gKDE5MzcpLiBQcm9wZXJ0aWVzIG9mIHN1ZmZpY2llbmN5IGFuZCBzdGF0aXN0aWNhbCB0ZXN0cy4gUHJvY2VlZGluZ3Mgb2YgdGhlIFJveWFsIFNvY2lldHkgb2YgTG9uZG9uIFNlcmllcyBBIDE2MCwgMjY44oCTMjgyLg0KNC4gQmF0ZXMsIEQuIE0uICgyMDA2KS4gW1JdIGxtZXIsIHAtdmFsdWVzIGFuZCBhbGwgdGhhdC4gaHR0cHM6Ly9zdGF0LmV0aHouY2gvcGlwZXJtYWlsL3ItaGVscC8yMDA2LU1heS8wOTQ3NjUuaHRtbA0KNS4gQmF0ZXMsIEQuIE0uICgyMDA4KS4gW1Itc2lnLU1FXSBtY21jc2FtcCBjYW4ndCBoYW5kbGUgcmFuZG9tIGVmZmVjdHMgc3ludGF4LiBodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1zaWctbWl4ZWQtbW9kZWxzLzIwMDhxMy8wMDE0MDkuaHRtbA0KNi4gRHVubiwgSy4gUC4sIGFuZCBTbXl0aCwgRy4gSy4gKDE5OTYpLiBSYW5kb21pemVkIHF1YW50aWxlIHJlc2lkdWFscy4gSm91cm5hbCBvZiBDb21wdXRhdGlvbmFsIGFuZCBHcmFwaGljYWwgU3RhdGlzdGljcyA1LCAxLTEwLg0KNy4gRm94LCBKLiAoMjAwOCkuIEFwcGxpZWQgUmVncmVzc2lvbiBBbmFseXNpcyBhbmQgR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVscyAybmQgRWRpdGlvbi4gVGhvdXNhbmQgT2FrcywgQ0E6IFNBR0UuDQo4LiBHZWxtYW4sIEEuLCAmIEhpbGwsIEouICgyMDA3KS4gRGF0YSBhbmFseXNpcyB1c2luZyByZWdyZXNzaW9uIGFuZCBtdWx0aWxldmVsL2hpZXJhcmNoaWNhbCBtb2RlbHMuIE5ldyBZb3JrOiBDYW1icmlkZ2UgVW5pdmVyc2l0eSBQcmVzcy4NCjkuIEdsYXNlciwgUi4gRS4gKDIwMDYpLiBMZXZlbmUncyBSb2J1c3QgVGVzdCBvZiBIb21vZ2VuZWl0eSBvZiBWYXJpYW5jZXMuIEVuY3ljbG9wZWRpYSBvZiBTdGF0aXN0aWNhbCBTY2llbmNlcy4gNi4NCjEwLiBHdXJrYSwgTS4gSi4sIEVkd2FyZHMsIEwuIEouLCBNdWxsZXIsIEsuIEUuIGFuZCBLdXBwZXIsIEwuIEwuICgyMDA2KSwgRXh0ZW5kaW5nIHRoZSBCb3jigJNDb3ggdHJhbnNmb3JtYXRpb24gdG8gdGhlIGxpbmVhciBtaXhlZCBtb2RlbC4gSm91cm5hbCBvZiB0aGUgUm95YWwgU3RhdGlzdGljYWwgU29jaWV0eTogU2VyaWVzIEEgKFN0YXRpc3RpY3MgaW4gU29jaWV0eSksIDE2OTogMjcz4oCTMjg4LiBkb2k6MTAuMTExMS9qLjE0NjctOTg1WC4yMDA1LjAwMzkxLngNCjExLiBNYWFzLCBDLiBKLiBNLiwgJiBIb3gsIEouIEouICgyMDA1KS4gU3VmZmljaWVudCBzYW1wbGUgc2l6ZXMgZm9yIG11bHRpbGV2ZWwgbW9kZWxpbmcuIE1ldGhvZG9sb2d5LCAxKDMpLCA4Ni05Mg0KMTIuIFBpbmhlaXJvLCBKLiBDLiwgQmF0ZXMsIEQuIE0uLCAoMjAwMCkuIE1peGVkLWVmZmVjdHMgbW9kZWxzIGluIFMgYW5kIFMtcGx1cy4gTmV3IFlvcmssIE5ZOiBTcHJpbmdlci4NCjEzLiBTbmlqZGVycywgVC4gQS4gQi4sICYgQm9za2VyLCBSLiBKLiAoMTk5OSkuIE11bHRpbGV2ZWwgYW5hbHlzaXM6IEFuIGludHJvZHVjdGlvbiB0byBiYXNpYyBhbmQgYWR2YW5jZWQgbXVsdGlsZXZlbCBtb2RlbGluZy4gTG9uZG9uOiBTYWdlLg0KMTQuIHZhbiBkZXIgTGFhbiwgTS4sICYgUm9zZSwgUy4gKDIwMTApLiBTdGF0aXN0aWNzIHJlYWR5IGZvciBhIHJldm9sdXRpb24uIEFtc3RhdCBOZXdzLiBSZXRyaWV2ZWQgT2N0b2JlciA3LCAyMDExLCBmcm9tIGh0dHA6Ly9tYWdhemluZS5hbXN0YXQub3JnL2Jsb2cvMjAxMC8wOS8wMS9zdGF0cmV2b2x1dGlvbi8NCjE1LiBWZXJiZWtlLCBHLiwgJiBMZXNhZmZyZSwgRS4gKDE5OTcpLiBUaGUgZWZmZWN0IG9mIG1pc3NwZWNpZnlpbmcgdGhlIHJhbmRvbS1lZmZlY3RzIGRpc3RyaWJ1dGlvbiBpbiBsaW5lYXIgbWl4ZWQgbW9kZWxzIGZvciBsb25naXR1ZGluYWwgZGF0YS4gQ29tcHV0YXRpb25hbCBTdGF0aXN0aWNzICYgRGF0YSBBbmFseXNpcywgMjMsIDU0MS01NTYuDQoNCjxzY3JpcHQ+DQogIChmdW5jdGlvbihpLHMsbyxnLHIsYSxtKXtpWydHb29nbGVBbmFseXRpY3NPYmplY3QnXT1yO2lbcl09aVtyXXx8ZnVuY3Rpb24oKXsNCiAgKGlbcl0ucT1pW3JdLnF8fFtdKS5wdXNoKGFyZ3VtZW50cyl9LGlbcl0ubD0xKm5ldyBEYXRlKCk7YT1zLmNyZWF0ZUVsZW1lbnQobyksDQogIG09cy5nZXRFbGVtZW50c0J5VGFnTmFtZShvKVswXTthLmFzeW5jPTE7YS5zcmM9ZzttLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsbSkNCiAgfSkod2luZG93LGRvY3VtZW50LCdzY3JpcHQnLCdodHRwczovL3d3dy5nb29nbGUtYW5hbHl0aWNzLmNvbS9hbmFseXRpY3MuanMnLCdnYScpOw0KDQogIGdhKCdjcmVhdGUnLCAnVUEtOTg4Nzg3OTMtMScsICdhdXRvJyk7DQogIGdhKCdzZW5kJywgJ3BhZ2V2aWV3Jyk7DQoNCjwvc2NyaXB0Pg0KDQo=