To demonstrate centering, contrast coding, and two-level crossed
models, we’re going to use a few different datasets.
Please download the following datasets from my github:
- sample data_two_level (1).sav
- lab5_anova_contrasts.sav
- DyadicLongitudinal_ExampleDataset_RM3.csv
- ViagraCovariate.dat
- sample data_week4.sav
Continuous predictors: centering
Let’s say you’re interested in the effect of perceived social support
on anxiety. Anxiety can vary both between- and within-person. The
question is, are you interested in the within-person effect (how does
receiving more social support than I typically do influence my anxiety?)
or between-person (how anxious are people who received more social
support on average?). We can actually look at both by centering our
predictors in different ways.
- uncentered (raw)
- centering on a sample value (same for everyone):
typically, grand-mean centered (centered on sample mean), but can center
on another relevant value (e.g., centering on the first timepoint for
the “time” variable).
- person-level centering (different for everyone):
typically, person-mean centering (subtracting each individual’s mean
from their own scores), but could centering on another person-level
variable (e.g., first Sunday for each person when participants start
daily diaries on different days of the week). Only relevant for
time-varying variables
Centering on a sample value (same for everyone)
- Fixed intercept reflects whatever you set 0 to be for the whole
sample
- Fixed regression estimates (fixed slopes) are identical to
uncentered
Person-level centering (different for everyone)
- Fixed intercept reflects whatever 0 is for each participant (e.g.,
each participant’s mean)
- Fixed regression estimates (fixed slopes) will be different
- expected change in outcome corresponding to a 1 unit change in a
predictor relative to each participant’s centered value (e.g., their own
average)
Example: Amie slept 6 hours last night, but she usually
sleeps 9 hours. Kate slept 6 hours last night and she usually sleeps 6
hours. When person-mean centering, 6 hours for Amie is a deficit of 3
hours but average (0) for Kate.
With more complex data structures:
• You can unconfound effects for any random factor
• Example: ESM data with momentary assessments nested within days within people
• Within-day and between-day effects
• Times when I am more angry than usual that day
• Days when I am more angry than I usually am
• Within-person and between-person effects (You could do this across all momentary assessments, ignoring day)
• Times I am more angry than I usually am across the whole study
• People who are more angry than the average person in the sample
OR you could have all 3 levels:
• Each momentary assessment deviation from that day’s mean
• Each day’s mean from the person’s overall mean
• Person’s overall mean
• This provides all three ways of looking at the data:
• Times when I am more angry than usual that day
• Days when I am more angry than I usual am
• People who are more angry than the average person in the sample
Creating centered variables
DATASET 1: Revisiting the roommate data
df_roommate<-read_sav("/Users/kareenadelrosario/Desktop/everything/2_areas/spring 2024/person perception/sample data_two_level.sav")
## # A tibble: 6 × 658
## Dyad partnum Participant_ID day dayR dorm awish sloppy_roommate
## <dbl> <dbl> <dbl> <dbl> <dbl+lbl> <dbl> <dbl> <dbl>
## 1 1 1 1 10 -1 1 1 2
## 2 1 1 1 11 1 1 2 1
## 3 6 1 6 10 -1 1 NA 1
## 4 6 1 6 11 1 1 1 1
## 5 7 1 7 10 -1 1 1 1
## 6 7 1 7 11 1 1 1 1
## # ℹ 650 more variables: sloppy_roommateC <dbl>, first_similarN <dbl>,
## # first_similarN_low <dbl>, first_similarN_high <dbl>, genderN <dbl>,
## # EXAMPLE_VARS_END_HERE <dbl>, dayC <dbl>, contrast1 <dbl>, contrast2 <dbl>,
## # raceN <dbl>, praceN <dbl>, daybeg <dbl>, awhitemin_pwhitemin <dbl>,
## # prace_think <chr>, race_think <chr>, dyad_type_JESP <dbl>, pa <dbl>,
## # I2 <dbl>, OBS_ID <dbl>, ahurt_comp <dbl>, aphurt_comp <dbl>,
## # pahurt_comp <dbl>, pid1 <dbl>, length <dbl>, pcheck <chr>, …
Centering roommate messiness in roommate data
df_mess <- df_roommate %>%
mutate(proom_mess_GMC = proom_mess - mean(proom_mess, na.rm = TRUE)) %>% # grand mean centered
group_by(Participant_ID) %>%
mutate(proom_mess_PC = proom_mess - mean(proom_mess, na.rm = TRUE)) %>% # person centered
ungroup() %>%
mutate(proom_mess_BPC = proom_mess_GMC - proom_mess_PC)
# dayR must be an integer
df_mess$dayR_int <- as.integer(as.factor(df_mess$dayR))
model_mess <- gls(awish ~ proom_mess_GMC + proom_mess_PC,
data = df_mess,
correlation = corSymm(form = ~ dayR_int | Participant_ID),
weights=varIdent(form=~1|dayR_int),
method = "REML",
na.action = na.omit)
summary(model_mess)
## Generalized least squares fit by REML
## Model: awish ~ proom_mess_GMC + proom_mess_PC
## Data: df_mess
## AIC BIC logLik
## 392.0479 408.672 -190.0239
##
## Correlation Structure: General
## Formula: ~dayR_int | Participant_ID
## Parameter estimate(s):
## Correlation:
## 1
## 2 0.731
## Variance function:
## Structure: Different standard deviations per stratum
## Formula: ~1 | dayR_int
## Parameter estimates:
## 1 2
## 1.000000 1.264524
##
## Coefficients:
## Value Std.Error t-value p-value
## (Intercept) 1.5087665 0.1522062 9.912652 0.0000
## proom_mess_GMC 0.0737453 0.1028680 0.716892 0.4749
## proom_mess_PC -0.1281800 0.1448588 -0.884862 0.3780
##
## Correlation:
## (Intr) p__GMC
## proom_mess_GMC 0.017
## proom_mess_PC -0.019 -0.709
##
## Standardized residuals:
## Min Q1 Med Q3 Max
## -0.7252142 -0.3673895 -0.3324373 -0.2905358 4.5930239
##
## Residual standard error: 1.209577
## Degrees of freedom: 121 total; 118 residual
Categorical predictors: contrast coding
To demonstrate contrast coding, we’re going to use a different
dataset
DATASET 2: Sadness by 3-level condition and gender
df<- read_sav("/Users/kareenadelrosario/Desktop/local r code/regression_code/lab5_anova_contrasts.sav")
Predictors:
- condition_3Level: 1, 2, 3
- genderR: -1, 1
Change variable class
df.short <- df %>%
mutate(condition_3Level = as.factor(condition_3Level),
genderR = as.factor(genderR))
# check class
class(df.short$condition_3Level)
## [1] "factor"
## [1] "factor"
Dummy coding
This is the most common form of contrast coding. In dummy coding, one
level of the categorical variable is chosen as a reference group. For
example, if you have a variable “Race” with three levels (White, Black,
Asian), you can create two dummy variables: the effect of being Black
and the effect of being Asian. The reference group (White) gets coded as
0 in both new variables. The intercept represents the mean outcome for
the reference group.
White = 1 Black = 2 Asian = 3
White |
0 |
0 |
Black |
1 |
0 |
Asian |
0 |
1 |
Dummy 1: outcome for Black participants vs
reference (White)
Dummy 2: outcome for Asian participants vs reference (White)
Intercept = average sleep quality when predictor is zero (sleep for
White participants)
Effects coding
Unlike dummy coding, where the reference category is represented by
all 0’s, effects coding doesn’t leave out one category as the reference.
Instead, categories are coded with numbers that balance out, such that
the sum of codes for each categorical level across all coded variables
equals zero. This balance allows the model’s intercept to represent the
grand mean. You would use this coding scheme if you wanted to compare
the mean of each group to the grand mean. The reference group gets -1
for both effects.
The sum of your contrasts should = 0.
White |
1 |
0 |
Black |
0 |
1 |
Asian |
-1 |
-1 |
Effect 1: compares the effect of White to the
overall mean
Effect 2: compares the effect of Black to the overall mean
Intercept = grand mean across all categories of race
tldr; Dummy coding gives us the “simple effects,” comparing
different levels to a reference group while effects coding
gives us the “main effects,” comparing different levels to the group
mean
How are our variables coded?
contrasts(df.short$genderR)
## 1
## -1 0
## 1 1
Identifiers:
Contrasts:
How does this impact our interpretation of the
intercept?
- Average sadness after the interaction for women (when genderR =
0)
contrasts(df.short$condition_3Level)
## 2 3
## 1 0 0
## 2 1 0
## 3 0 1
Identifiers:
1 = Control dyad
2 = Sad actor
3 = Sad partner
Contrasts:
FIRST EFFECT: what is the effect of sad actor vs control
condition?
SECOND EFFECT: what is the effect of sad partner vs control
condition?
Contrast coding in R
# effect-code
contr.sum(2)
## [,1]
## 1 1
## 2 -1
## [,1] [,2]
## 1 1 0
## 2 0 1
## 3 -1 -1
# dummy code
contr.treatment(2)
## 2
## 1 0
## 2 1
## 2 3
## 1 0 0
## 2 1 0
## 3 0 1
Apply contrasts (effect code)
contrasts(df.short$genderR) <- contr.sum(2)
contrasts(df.short$condition_3Level) <- contr.sum(3)
# alternative: custom effects coding
effectContrasts <- cbind(c(1, 0, -1), c(0, 1, -1))
model_shortcut <- lm(avg_sad_int ~ genderR*condition_3Level, data = df.short)
summary(model_shortcut)
##
## Call:
## lm(formula = avg_sad_int ~ genderR * condition_3Level, data = df.short)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.2738 -0.2167 -0.1576 -0.1111 2.0595
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.1972874 0.0309211 38.721 <2e-16 ***
## genderR1 -0.0550935 0.0309211 -1.782 0.0762 .
## condition_3Level1 0.0184052 0.0388069 0.474 0.6358
## condition_3Level2 0.0149933 0.0460489 0.326 0.7450
## genderR1:condition_3Level1 -0.0030233 0.0388069 -0.078 0.9380
## genderR1:condition_3Level2 0.0007076 0.0460489 0.015 0.9878
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4279 on 222 degrees of freedom
## (2 observations deleted due to missingness)
## Multiple R-squared: 0.02079, Adjusted R-squared: -0.001268
## F-statistic: 0.9425 on 5 and 222 DF, p-value: 0.4543
Apply contrasts (dummy code)
contrasts(df.short$genderR) <- contr.treatment(2)
contrasts(df.short$condition_3Level) <- contr.treatment(3)
# alternative: custom dummy coding
dummyContrasts <- cbind(c(0,1,0), c(0, 0, 1))
model_shortcut2 <- lm(avg_sad_int ~ genderR*condition_3Level, data = df.short)
summary(model_shortcut2)
##
## Call:
## lm(formula = avg_sad_int ~ genderR * condition_3Level, data = df.short)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.2738 -0.2167 -0.1576 -0.1111 2.0595
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.157576 0.057697 20.063 <2e-16 ***
## genderR2 0.116234 0.081230 1.431 0.154
## condition_3Level2 0.000319 0.090261 0.004 0.997
## condition_3Level3 -0.046465 0.089574 -0.519 0.604
## genderR2:condition_3Level2 -0.007462 0.143426 -0.052 0.959
## genderR2:condition_3Level3 -0.010678 0.142995 -0.075 0.941
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4279 on 222 degrees of freedom
## (2 observations deleted due to missingness)
## Multiple R-squared: 0.02079, Adjusted R-squared: -0.001268
## F-statistic: 0.9425 on 5 and 222 DF, p-value: 0.4543
Summary of intercepts
The intercept represents the dependent variable when all predictors
are zero
raw (no centering): 0 here can vary quite a bit
depending on what your predictors are. It may not be
meaningful.
dummy-coding: 0 is the reference group. The intercept is
the average DV for the reference group.
effects-coding: 0 is the grand mean. The intercept is
the DV when all predictors are averaged. Let’s say we coded women -1 and
men 1. The intercept would be the DV regardless of gender (averaging
across gender).
grand-mean centering: 0 is the grand mean. The intercept
is the expected DV at the average level of the predictors.
person-mean centering: 0 is the person’s average for
that predictor. So, the intercept would be ‘the expected level of
anxiety (DV) when you sleep your average amount’
Two-level crossed model
DATASET 3: Intellectual humility measured 3x courtesy of Kate
Thorson & Amie Gordon
# load in our example data
rm_df <- read.csv("/Users/kareenadelrosario/Downloads/DyadicLongitudinal_ExampleDataset_RM3.csv")
964 people reported on their intellectual humility (IH) at three time
points: pre (before the first conversation), post (after the last
conversation), and follow-up (one month after the last conversation). We
are going to use these data to ask whether IH changes across the three
time points.
Here are the variables we’re interested in:
- IH: intellectual humility, reported at three time
points
- time: time, pre = 1; post = 2; follow-up = 3
- id: unique ID number for each person
- timecontrast1_pre_post: pre = 0, post = 1,
follow-up = 0
- timecontrast2_pre_followup: pre = 0, post = 0,
follow-up = 1
TIME • 1: pre • 2: post • 3:
follow-up
Our predictors are timecontrast1_pre_post,
timecontrast2_pre_followup, and
time.
- Predictors:
- timecontrast1_pre_post,
- timecontrast2_pre_followup,
- time,
- timecontrast1_pre_post x time,
- timecontrast2_pre_followup x time
- Error variance for time1, time2, time3
Analysis steps
Before we jump into the analysis, let’s take a step back and go
through some pre-analyses to figure out:
- whether we need to account for nonindependence in the first
place
- build our model
Intraclass Correlation Coefficient (ICC)
Sometimes used to “justify” nonindependent analyses. ICC indexes the
similarity between time points for a particular outcome. Technically, it
represents the proportion of the total variance in an outcome that is
explained by mean differences between subjects. An ICC of 1 would mean
that all of the variability in the DV is between subjects. In repeated
self-report data, it’s common to have ICCs between .2-.4.
Calculating an ICC:
- Run an MLM with no predictors (i.e., a null model)
- Use person as a random factor
- Using the output, calculate the ICC as the following:
Run null model with nlme
library(haven) # read SPSS and SAS files
library(reghelper) # for ICC command
null_model_lme <- lme(IH ~ 1,
data = rm_df,
random = ~ 1 | id,
method = "REML",
na.action = na.omit)
summary(null_model_lme)
## Linear mixed-effects model fit by REML
## Data: rm_df
## AIC BIC logLik
## 5807.233 5824.256 -2900.616
##
## Random effects:
## Formula: ~1 | id
## (Intercept) Residual
## StdDev: 0.6476011 0.7498407
##
## Fixed effects: IH ~ 1
## Value Std.Error DF t-value p-value
## (Intercept) 5.70632 0.02681951 1217 212.7675 0
##
## Standardized Within-Group Residuals:
## Min Q1 Med Q3 Max
## -5.6254028 -0.3335210 0.1209683 0.5563851 2.5299155
##
## Number of Observations: 2154
## Number of Groups: 937
## [1] 0.4272276
Run null model with lme4
library(lme4)
null_model_lmer <- lmer(IH ~ 1 +
(1 |id),
data=rm_df)
summary(null_model_lmer)
## Linear mixed model fit by REML ['lmerMod']
## Formula: IH ~ 1 + (1 | id)
## Data: rm_df
##
## REML criterion at convergence: 5801.2
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -5.6254 -0.3335 0.1210 0.5564 2.5299
##
## Random effects:
## Groups Name Variance Std.Dev.
## id (Intercept) 0.4194 0.6476
## Residual 0.5623 0.7498
## Number of obs: 2154, groups: id, 937
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 5.70632 0.02682 212.8
Here’s the ICC equation:
ICC= between−dyad variance (random intercept variance)total variance (random intercept variance + residual variance)
id_variance <- 0.4194
residual <- 0.5623
# calculating ICC
id_variance / (id_variance + residual)
## [1] 0.4272181
What is our takeaway from the ICC?
Two-level crossed model with individual repeated measures
This will be a marginal model– we’re going to adjust for
nonindependence by providing a variance-covariance structure to the
residuals. This approach is useful for repeated measure with 3 or 4 time
points.
In other words, this will model the nonindependence with a
covariance (adjust for nonindependence by correlating
the residuals between dyad members. This allows for both positive and
negative nonindependence).
Output
- Fixed parameter estimates
- Error covariance: are the two time points’ errors
related ot each other?
- Error variance: is there significant variance that
is unexplained by the other components in the model?
Residual structure
We’re estimating 6 parameters:
• 3 variances
• Variance at pre
• Variance at post
• Variance at followup
• 3 within-person covariances at different time points
• Within-person covariance between pre and post
• Within-person covariance between pre and follow-up
• Within-person covariance between post and follow-up
For reference, here is the SPSS syntax:
MIXED IH WITH timecontrast1_pre_post timecontrast2_pre_followup
/FIXED = timecontrast1_pre_post timecontrast2_pre_followup |
SSTYPE(3)
/METHOD = REML
/PRINT = G TESTCOV SOLUTION
/REPEATED time | subject(Participant_ID) COVTYPE(UN).
Weighted by day (each day has its own variance)
# dayR must be an integer
rm_df$time <- as.integer(as.factor(rm_df$time))
model1 <- gls(IH ~ timecontrast1_pre_post + timecontrast2_pre_followup,
data = rm_df,
correlation = corSymm(form = ~ time | id),
weights=varIdent(form=~1|time),
method = "REML",
na.action = na.omit)
summary(model1)
## Generalized least squares fit by REML
## Model: IH ~ timecontrast1_pre_post + timecontrast2_pre_followup
## Data: rm_df
## AIC BIC logLik
## 5648.821 5699.884 -2815.411
##
## Correlation Structure: General
## Formula: ~time | id
## Parameter estimate(s):
## Correlation:
## 1 2
## 2 0.447
## 3 0.501 0.499
## Variance function:
## Structure: Different standard deviations per stratum
## Formula: ~1 | time
## Parameter estimates:
## 1 2 3
## 1.0000000 0.9362196 0.7794307
##
## Coefficients:
## Value Std.Error t-value p-value
## (Intercept) 5.498933 0.03363166 163.50465 0
## timecontrast1_pre_post 0.388216 0.03496641 11.10255 0
## timecontrast2_pre_followup 0.352448 0.04193941 8.40374 0
##
## Correlation:
## (Intr) tmc1__
## timecontrast1_pre_post -0.560
## timecontrast2_pre_followup -0.489 0.435
##
## Standardized residuals:
## Min Q1 Med Q3 Max
## -5.0706050 -0.4379075 0.1170871 0.6358563 1.4580824
##
## Residual standard error: 1.02948
## Degrees of freedom: 2154 total; 2151 residual
getVarCov(model1, individual = "58")
## Marginal variance covariance matrix
## [,1] [,2] [,3]
## [1,] 1.05980 0.44320 0.41387
## [2,] 0.44320 0.92895 0.38554
## [3,] 0.41387 0.38554 0.64386
## Standard Deviations: 1.0295 0.96382 0.80241
Two-level crossed model with distinguishable dyads
We’re estimating 21 parameters:
• 3 variances
• Variance at pre
• Variance at post
• Variance at followup
• 3 within-dyad covariances at the same time point
• Within-dyad covariance between pre ratings
• Within-dyad covariance between post ratings
• Within-dyad covariance between follow-up ratings
• 3 within-person covariances at different time points
• Within-person covariance between pre and post
• Within-person covariance between pre and follow-up
• Within-person covariance between post and follow-up
• 3 within-dyad covariances at different time points
• Within-dyad covariance between pre and post
• Within-dyad covariance between pre and follow-up
• Within-dyad covariance between post and follow-up
model <- gls(IH ~ timecontrast1_pre_post + timecontrast2_pre_followup + party +
party*timecontrast1_pre_post +
party*timecontrast2_pre_followup,
data = rm_df,
correlation = corSymm(form = ~ RM | dyad),
weights=varIdent(form=~1|RM),
method = "REML",
na.action = na.omit)
# omnibus test
anova(model, type = "marginal")
## Denom. DF: 2148
## numDF F-value p-value
## (Intercept) 1 25041.583 <.0001
## timecontrast1_pre_post 1 115.434 <.0001
## timecontrast2_pre_followup 1 67.907 <.0001
## party 1 0.072 0.7878
## timecontrast1_pre_post:party 1 0.367 0.5446
## timecontrast2_pre_followup:party 1 0.085 0.7702
SAS Omnibus output

Print covariance parameter estimates
## Marginal variance covariance matrix
## [,1] [,2] [,3] [,4]
## [1,] 1.08010000 0.446180 0.073189 -0.00016797
## [2,] 0.44618000 0.961690 0.049031 0.05365500
## [3,] 0.07318900 0.049031 1.041300 0.43985000
## [4,] -0.00016797 0.053655 0.439850 0.89507000
## Standard Deviations: 1.0393 0.98066 1.0205 0.94608
getVarCov(model, individual = 2)
## Marginal variance covariance matrix
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1.08010000 0.446180 0.3666300 0.073189 -0.00016797 0.0633330
## [2,] 0.44618000 0.961690 0.3452600 0.049031 0.05365500 0.0865530
## [3,] 0.36663000 0.345260 0.6338600 -0.049843 -0.10210000 0.0034325
## [4,] 0.07318900 0.049031 -0.0498430 1.041300 0.43985000 0.4533000
## [5,] -0.00016797 0.053655 -0.1021000 0.439850 0.89507000 0.4190200
## [6,] 0.06333300 0.086553 0.0034325 0.453300 0.41902000 0.6540700
## Standard Deviations: 1.0393 0.98066 0.79616 1.0205 0.94608 0.80874
SAS Covariance output

What can we learn from this?
Your turn!
Contrast coding
DATASET 4: Andy Field’s Viagra Data
v_df <- read.delim("/Users/kareenadelrosario/Desktop/everything/2_areas/spring 2024/person perception/Viagra.dat")
## person dose libido
## 1 1 1 3
## 2 2 1 2
## 3 3 1 1
## 4 4 1 1
## 5 5 1 4
## 6 6 2 5
- Use contrast coding so that the intercept represents the average
libido across all participants.
- Code the variables so that the intercept represents the average
libido for the control group.
- Code the variables so that the first contrast compares the treatment
group (Low + High) to the control group and the second contrast compares
the control to the low dose group.
Centering & Two-Level Crossed Model (with dyads!)
Now, we’ll follow the same steps with the Roommate data we’ve been
working with. Use the roommate df to test whether people are more
comfortable expressing themselves (pexpress) are happier (phappy).
Here are some other variables you’ll need dayR Dyad RM
partnum
- Are the data nonindependent? (do we actually need to use MLM)
- Are people who are more comfortable expressing themselves
happier?
- Are people happier if they feel more comfortable expressing
themselves than they typically do?
DATASET 5: More Roommate Data
Note this is a different file than what we’ve been using.
library(haven)
roommate_df <- read_sav("/Users/kareenadelrosario/Desktop/everything/2_areas/spring 2024/person perception/sample data_1.sav")
In this analysis, our grouping/subject variable is “Dyad” and our
repeated variable is “RM”. For reference, here is the SPSS syntax:
MIXED DV WITH IV
/FIXED = IV
/PRINT = SOLUTION TESTCOV
/REPEATED =RM | SUBJECT (Dyad) COVTYPE (UNR).
For R, the equivalent to COVTYPE (UNR) is correlation = corSymm.
LS0tCnRpdGxlOiAiUGVyc29uIFBlcmNlcHRpb246IENlbnRlcmluZyBhbmQgY29udHJhc3QgY29kaW5nIGZvciBNTE0iCmF1dGhvcjogIkthcmVlbmEgZGVsIFJvc2FyaW8iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBoaWdobGlnaHQ6IGFycm93CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29sbGFwc2VkOiB0cnVlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCgpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHRpZHlyKSAKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobmxtZSkKbGlicmFyeShoYXZlbikKYGBgCgoKVG8gZGVtb25zdHJhdGUgY2VudGVyaW5nLCBjb250cmFzdCBjb2RpbmcsIGFuZCB0d28tbGV2ZWwgY3Jvc3NlZCBtb2RlbHMsIHdlJ3JlIGdvaW5nIHRvIHVzZSBhIGZldyBkaWZmZXJlbnQgZGF0YXNldHMuIAoKUGxlYXNlIGRvd25sb2FkIHRoZSBmb2xsb3dpbmcgZGF0YXNldHMgZnJvbSBteSBnaXRodWI6CgogIDEuIHNhbXBsZSBkYXRhX3R3b19sZXZlbCAoMSkuc2F2CiAgMi4gbGFiNV9hbm92YV9jb250cmFzdHMuc2F2CiAgMy4gRHlhZGljTG9uZ2l0dWRpbmFsX0V4YW1wbGVEYXRhc2V0X1JNMy5jc3YKICA0LiBWaWFncmFDb3ZhcmlhdGUuZGF0CiAgNS4gc2FtcGxlIGRhdGFfd2VlazQuc2F2CgoKLS0tLS0tLS0tLS0tLS0tCgojIENvbnRpbnVvdXMgcHJlZGljdG9yczogY2VudGVyaW5nCgoKTGV0J3Mgc2F5IHlvdSdyZSBpbnRlcmVzdGVkIGluIHRoZSBlZmZlY3Qgb2YgcGVyY2VpdmVkIHNvY2lhbCBzdXBwb3J0IG9uIGFueGlldHkuIEFueGlldHkgY2FuIHZhcnkgYm90aCBiZXR3ZWVuLSBhbmQgd2l0aGluLXBlcnNvbi4gVGhlIHF1ZXN0aW9uIGlzLCBhcmUgeW91IGludGVyZXN0ZWQgaW4gdGhlIHdpdGhpbi1wZXJzb24gZWZmZWN0IChob3cgZG9lcyByZWNlaXZpbmcgbW9yZSBzb2NpYWwgc3VwcG9ydCB0aGFuIEkgdHlwaWNhbGx5IGRvIGluZmx1ZW5jZSBteSBhbnhpZXR5Pykgb3IgYmV0d2Vlbi1wZXJzb24gKGhvdyBhbnhpb3VzIGFyZSBwZW9wbGUgd2hvIHJlY2VpdmVkIG1vcmUgc29jaWFsIHN1cHBvcnQgb24gYXZlcmFnZT8pLiBXZSBjYW4gYWN0dWFsbHkgbG9vayBhdCBib3RoIGJ5IGNlbnRlcmluZyBvdXIgcHJlZGljdG9ycyBpbiBkaWZmZXJlbnQgd2F5cy4gCgotICoqdW5jZW50ZXJlZCAocmF3KSoqCi0gKipjZW50ZXJpbmcgb24gYSBzYW1wbGUgdmFsdWUgKHNhbWUgZm9yIGV2ZXJ5b25lKToqKiB0eXBpY2FsbHksIGdyYW5kLW1lYW4gY2VudGVyZWQgKGNlbnRlcmVkIG9uIHNhbXBsZSBtZWFuKSwgYnV0IGNhbiBjZW50ZXIgb24gYW5vdGhlciByZWxldmFudCB2YWx1ZSAoZS5nLiwgY2VudGVyaW5nIG9uIHRoZSBmaXJzdCB0aW1lcG9pbnQgZm9yIHRoZSDigJx0aW1l4oCdIHZhcmlhYmxlKS4KLSAqKnBlcnNvbi1sZXZlbCBjZW50ZXJpbmcgKGRpZmZlcmVudCBmb3IgZXZlcnlvbmUpKio6IHR5cGljYWxseSwgcGVyc29uLW1lYW4gY2VudGVyaW5nIChzdWJ0cmFjdGluZyBlYWNoIGluZGl2aWR1YWzigJlzIG1lYW4gZnJvbSB0aGVpciBvd24gc2NvcmVzKSwgYnV0IGNvdWxkIGNlbnRlcmluZyBvbiBhbm90aGVyIHBlcnNvbi1sZXZlbCB2YXJpYWJsZSAoZS5nLiwgZmlyc3QgU3VuZGF5IGZvciBlYWNoIHBlcnNvbiB3aGVuIHBhcnRpY2lwYW50cyBzdGFydCBkYWlseQpkaWFyaWVzIG9uIGRpZmZlcmVudCBkYXlzIG9mIHRoZSB3ZWVrKS4gT25seSByZWxldmFudCBmb3IgdGltZS12YXJ5aW5nIHZhcmlhYmxlcwoKCkNlbnRlcmluZyBvbiBhIHNhbXBsZSB2YWx1ZSAoc2FtZSBmb3IgZXZlcnlvbmUpIAogICAgCiAgMS4gRml4ZWQgaW50ZXJjZXB0IHJlZmxlY3RzIHdoYXRldmVyIHlvdSBzZXQgMCB0byBiZSBmb3IgdGhlIHdob2xlIHNhbXBsZQogIDIuIEZpeGVkIHJlZ3Jlc3Npb24gZXN0aW1hdGVzIChmaXhlZCBzbG9wZXMpIGFyZSBpZGVudGljYWwgdG8gdW5jZW50ZXJlZAoKUGVyc29uLWxldmVsIGNlbnRlcmluZyAoZGlmZmVyZW50IGZvciBldmVyeW9uZSkKICAgIAogIDEuIEZpeGVkIGludGVyY2VwdCByZWZsZWN0cyB3aGF0ZXZlciAwIGlzIGZvciBlYWNoIHBhcnRpY2lwYW50IChlLmcuLCBlYWNoIHBhcnRpY2lwYW504oCZcyBtZWFuKQogIDIuIEZpeGVkIHJlZ3Jlc3Npb24gZXN0aW1hdGVzIChmaXhlZCBzbG9wZXMpIHdpbGwgYmUgZGlmZmVyZW50CiAgICAgIC0gZXhwZWN0ZWQgY2hhbmdlIGluIG91dGNvbWUgY29ycmVzcG9uZGluZyB0byBhIDEgdW5pdCBjaGFuZ2UgaW4gYSBwcmVkaWN0b3IgcmVsYXRpdmUgdG8gZWFjaCBwYXJ0aWNpcGFudOKAmXMgY2VudGVyZWQgdmFsdWUgKGUuZy4sIHRoZWlyIG93biBhdmVyYWdlKQoKKipFeGFtcGxlOiBBbWllIHNsZXB0IDYgaG91cnMgbGFzdCBuaWdodCwgYnV0IHNoZSB1c3VhbGx5IHNsZWVwcyA5IGhvdXJzLiBLYXRlIHNsZXB0IDYgaG91cnMgbGFzdCBuaWdodCBhbmQgc2hlIHVzdWFsbHkgc2xlZXBzIDYgaG91cnMuIFdoZW4gcGVyc29uLW1lYW4gY2VudGVyaW5nLCA2IGhvdXJzIGZvciBBbWllIGlzIGEgZGVmaWNpdCBvZiAzIGhvdXJzIGJ1dCBhdmVyYWdlICgwKSBmb3IgS2F0ZS4qKgoKICAgIFdpdGggbW9yZSBjb21wbGV4IGRhdGEgc3RydWN0dXJlczoKICAgIOKAoiBZb3UgY2FuIHVuY29uZm91bmQgZWZmZWN0cyBmb3IgYW55IHJhbmRvbSBmYWN0b3IKICAgIOKAoiBFeGFtcGxlOiBFU00gZGF0YSB3aXRoIG1vbWVudGFyeSBhc3Nlc3NtZW50cyBuZXN0ZWQgd2l0aGluIGRheXMgd2l0aGluIHBlb3BsZQogICAgICDigKIgV2l0aGluLWRheSBhbmQgYmV0d2Vlbi1kYXkgZWZmZWN0cwogICAgICAgIOKAoiBUaW1lcyB3aGVuIEkgYW0gbW9yZSBhbmdyeSB0aGFuIHVzdWFsIHRoYXQgZGF5CiAgICAgICAg4oCiIERheXMgd2hlbiBJIGFtIG1vcmUgYW5ncnkgdGhhbiBJIHVzdWFsbHkgYW0KICAgICAg4oCiIFdpdGhpbi1wZXJzb24gYW5kIGJldHdlZW4tcGVyc29uIGVmZmVjdHMgKFlvdSBjb3VsZCBkbyB0aGlzIGFjcm9zcyBhbGwgbW9tZW50YXJ5IGFzc2Vzc21lbnRzLCBpZ25vcmluZyBkYXkpCiAgICAgICAg4oCiIFRpbWVzIEkgYW0gbW9yZSBhbmdyeSB0aGFuIEkgdXN1YWxseSBhbSBhY3Jvc3MgdGhlIHdob2xlIHN0dWR5CiAgICAgICAg4oCiIFBlb3BsZSB3aG8gYXJlIG1vcmUgYW5ncnkgdGhhbiB0aGUgYXZlcmFnZSBwZXJzb24gaW4gdGhlIHNhbXBsZQoKICAgIE9SIHlvdSBjb3VsZCBoYXZlIGFsbCAzIGxldmVsczoKICAgIOKAoiBFYWNoIG1vbWVudGFyeSBhc3Nlc3NtZW50IGRldmlhdGlvbiBmcm9tIHRoYXQgZGF54oCZcyBtZWFuCiAgICDigKIgRWFjaCBkYXnigJlzIG1lYW4gZnJvbSB0aGUgcGVyc29u4oCZcyBvdmVyYWxsIG1lYW4KICAgIOKAoiBQZXJzb27igJlzIG92ZXJhbGwgbWVhbgogICAgICDigKIgVGhpcyBwcm92aWRlcyBhbGwgdGhyZWUgd2F5cyBvZiBsb29raW5nIGF0IHRoZSBkYXRhOgogICAgICAgIOKAoiBUaW1lcyB3aGVuIEkgYW0gbW9yZSBhbmdyeSB0aGFuIHVzdWFsIHRoYXQgZGF5CiAgICAgICAg4oCiIERheXMgd2hlbiBJIGFtIG1vcmUgYW5ncnkgdGhhbiBJIHVzdWFsIGFtCiAgICAgICAg4oCiIFBlb3BsZSB3aG8gYXJlIG1vcmUgYW5ncnkgdGhhbiB0aGUgYXZlcmFnZSBwZXJzb24gaW4gdGhlIHNhbXBsZQogICAgICAgIAojIyBDcmVhdGluZyBjZW50ZXJlZCB2YXJpYWJsZXMKCgoqREFUQVNFVCAxOiBSZXZpc2l0aW5nIHRoZSByb29tbWF0ZSBkYXRhKgoKYGBge3J9CmRmX3Jvb21tYXRlPC1yZWFkX3NhdigiL1VzZXJzL2thcmVlbmFkZWxyb3NhcmlvL0Rlc2t0b3AvZXZlcnl0aGluZy8yX2FyZWFzL3NwcmluZyAyMDI0L3BlcnNvbiBwZXJjZXB0aW9uL3NhbXBsZSBkYXRhX3R3b19sZXZlbC5zYXYiKQpgYGAKCmBgYHtyfQpoZWFkKGRmX3Jvb21tYXRlKQpgYGAKCiMjIyMgQ2VudGVyaW5nIHJvb21tYXRlIG1lc3NpbmVzcyBpbiByb29tbWF0ZSBkYXRhCgpgYGB7cn0KZGZfbWVzcyA8LSBkZl9yb29tbWF0ZSAlPiUgCiAgbXV0YXRlKHByb29tX21lc3NfR01DID0gcHJvb21fbWVzcyAtIG1lYW4ocHJvb21fbWVzcywgbmEucm0gPSBUUlVFKSkgJT4lICMgZ3JhbmQgbWVhbiBjZW50ZXJlZAogIGdyb3VwX2J5KFBhcnRpY2lwYW50X0lEKSAlPiUgCiAgbXV0YXRlKHByb29tX21lc3NfUEMgPSBwcm9vbV9tZXNzIC0gbWVhbihwcm9vbV9tZXNzLCBuYS5ybSA9IFRSVUUpKSAlPiUgIyBwZXJzb24gY2VudGVyZWQKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZShwcm9vbV9tZXNzX0JQQyA9IHByb29tX21lc3NfR01DIC0gcHJvb21fbWVzc19QQykKCgojIGRheVIgbXVzdCBiZSBhbiBpbnRlZ2VyCmRmX21lc3MkZGF5Ul9pbnQgPC0gYXMuaW50ZWdlcihhcy5mYWN0b3IoZGZfbWVzcyRkYXlSKSkKYGBgCgpgYGB7cn0KbW9kZWxfbWVzcyA8LSBnbHMoYXdpc2ggfiBwcm9vbV9tZXNzX0dNQyArIHByb29tX21lc3NfUEMsCiAgICAgICAgICAgICBkYXRhID0gZGZfbWVzcywKICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yU3ltbShmb3JtID0gfiBkYXlSX2ludCB8IFBhcnRpY2lwYW50X0lEKSwKICAgICAgICAgICAgIHdlaWdodHM9dmFySWRlbnQoZm9ybT1+MXxkYXlSX2ludCksCiAgICAgICAgICAgICBtZXRob2QgPSAiUkVNTCIsCiAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0KQoKc3VtbWFyeShtb2RlbF9tZXNzKQpgYGAKCgojIyMgV2hhdCdzIHRoZSBkaWZmZXJlbmNlPwoKIyBDYXRlZ29yaWNhbCBwcmVkaWN0b3JzOiBjb250cmFzdCBjb2RpbmcKClRvIGRlbW9uc3RyYXRlIGNvbnRyYXN0IGNvZGluZywgd2UncmUgZ29pbmcgdG8gdXNlIGEgZGlmZmVyZW50IGRhdGFzZXQKCgoqREFUQVNFVCAyOiBTYWRuZXNzIGJ5IDMtbGV2ZWwgY29uZGl0aW9uIGFuZCBnZW5kZXIqCgpgYGB7cn0KZGY8LSByZWFkX3NhdigiL1VzZXJzL2thcmVlbmFkZWxyb3NhcmlvL0Rlc2t0b3AvbG9jYWwgciBjb2RlL3JlZ3Jlc3Npb25fY29kZS9sYWI1X2Fub3ZhX2NvbnRyYXN0cy5zYXYiKQpgYGAKCgpQcmVkaWN0b3JzOgoKLSBjb25kaXRpb25fM0xldmVsOiAxLCAyLCAzCi0gZ2VuZGVyUjogLTEsIDEKCiMjIyBDaGFuZ2UgdmFyaWFibGUgY2xhc3MKYGBge3J9CmRmLnNob3J0IDwtIGRmICU+JSAKICBtdXRhdGUoY29uZGl0aW9uXzNMZXZlbCA9IGFzLmZhY3Rvcihjb25kaXRpb25fM0xldmVsKSwKICAgICAgICAgZ2VuZGVyUiA9IGFzLmZhY3RvcihnZW5kZXJSKSkKCiMgY2hlY2sgY2xhc3MKY2xhc3MoZGYuc2hvcnQkY29uZGl0aW9uXzNMZXZlbCkKY2xhc3MoZGYuc2hvcnQkZ2VuZGVyUikKYGBgCgojIyMgRHVtbXkgY29kaW5nCgpUaGlzIGlzIHRoZSBtb3N0IGNvbW1vbiBmb3JtIG9mIGNvbnRyYXN0IGNvZGluZy4gSW4gZHVtbXkgY29kaW5nLCBvbmUgbGV2ZWwgb2YgdGhlIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGlzIGNob3NlbiBhcyBhIHJlZmVyZW5jZSBncm91cC4gRm9yIGV4YW1wbGUsIGlmIHlvdSBoYXZlIGEgdmFyaWFibGUgIlJhY2UiIHdpdGggdGhyZWUgbGV2ZWxzIChXaGl0ZSwgQmxhY2ssIEFzaWFuKSwgeW91IGNhbiBjcmVhdGUgdHdvIGR1bW15IHZhcmlhYmxlczogdGhlIGVmZmVjdCBvZiBiZWluZyBCbGFjayBhbmQgdGhlIGVmZmVjdCBvZiBiZWluZyBBc2lhbi4gVGhlIHJlZmVyZW5jZSBncm91cCAoV2hpdGUpIGdldHMgY29kZWQgYXMgMCBpbiBib3RoIG5ldyB2YXJpYWJsZXMuIFRoZSBpbnRlcmNlcHQgcmVwcmVzZW50cyB0aGUgbWVhbiBvdXRjb21lIGZvciB0aGUgcmVmZXJlbmNlIGdyb3VwLiAKCldoaXRlID0gMQpCbGFjayA9IDIKQXNpYW4gPSAzCgoKfCBSYWNlICB8IER1bW15MSB8IER1bW15MiB8CnwtLS0tLS0tfC0tLS0tLS0tfC0tLS0tLS0tfAp8IFdoaXRlIHwgMCAgICAgIHwgMCAgICAgIHwKfCBCbGFjayB8IDEgICAgICB8IDAgICAgICB8CnwgQXNpYW4gfCAwICAgICAgfCAxICAgICAgfAoKfCBEdW1teSAxOiBvdXRjb21lIGZvciBCbGFjayBwYXJ0aWNpcGFudHMgdnMgcmVmZXJlbmNlIChXaGl0ZSkKfCBEdW1teSAyOiBvdXRjb21lIGZvciBBc2lhbiBwYXJ0aWNpcGFudHMgdnMgcmVmZXJlbmNlIChXaGl0ZSkKfCBJbnRlcmNlcHQgPSBhdmVyYWdlIHNsZWVwIHF1YWxpdHkgd2hlbiBwcmVkaWN0b3IgaXMgemVybyAoc2xlZXAgZm9yIFdoaXRlIHBhcnRpY2lwYW50cykKCiMjIyBFZmZlY3RzIGNvZGluZwoKVW5saWtlIGR1bW15IGNvZGluZywgd2hlcmUgdGhlIHJlZmVyZW5jZSBjYXRlZ29yeSBpcyByZXByZXNlbnRlZCBieSBhbGwgMCdzLCBlZmZlY3RzIGNvZGluZyBkb2Vzbid0IGxlYXZlIG91dCBvbmUgY2F0ZWdvcnkgYXMgdGhlIHJlZmVyZW5jZS4gSW5zdGVhZCwgY2F0ZWdvcmllcyBhcmUgY29kZWQgd2l0aCBudW1iZXJzIHRoYXQgYmFsYW5jZSBvdXQsIHN1Y2ggdGhhdCB0aGUgc3VtIG9mIGNvZGVzIGZvciBlYWNoIGNhdGVnb3JpY2FsIGxldmVsIGFjcm9zcyBhbGwgY29kZWQgdmFyaWFibGVzIGVxdWFscyB6ZXJvLiBUaGlzIGJhbGFuY2UgYWxsb3dzIHRoZSBtb2RlbCdzIGludGVyY2VwdCB0byByZXByZXNlbnQgdGhlIGdyYW5kIG1lYW4uIFlvdSB3b3VsZCB1c2UgdGhpcyBjb2Rpbmcgc2NoZW1lIGlmIHlvdSB3YW50ZWQgdG8gY29tcGFyZSB0aGUgbWVhbiBvZiBlYWNoIGdyb3VwIHRvIHRoZSBncmFuZCBtZWFuLiBUaGUgcmVmZXJlbmNlIGdyb3VwIGdldHMgLTEgZm9yIGJvdGggZWZmZWN0cy4KClRoZSBzdW0gb2YgeW91ciBjb250cmFzdHMgc2hvdWxkID0gMC4KCnwgUmFjZSAgfEVmZmVjdDEgfEVmZmVjdDIgfAp8Oi0tLS0tLXw6LS0tLS0tLXw6LS0tLS0tLXwKfCBXaGl0ZSB8IDEgICAgICB8IDAgICAgICB8CnwgQmxhY2sgfCAwICAgICAgfCAxICAgICAgfAp8IEFzaWFuIHwgLTEgICAgIHwgLTEgICAgIHwKCgp8IEVmZmVjdCAxOiBjb21wYXJlcyB0aGUgZWZmZWN0IG9mIFdoaXRlIHRvIHRoZSBvdmVyYWxsIG1lYW4KfCBFZmZlY3QgMjogY29tcGFyZXMgdGhlIGVmZmVjdCBvZiBCbGFjayB0byB0aGUgb3ZlcmFsbCBtZWFuCnwgSW50ZXJjZXB0ID0gZ3JhbmQgbWVhbiBhY3Jvc3MgYWxsIGNhdGVnb3JpZXMgb2YgcmFjZSAKCgoqKnRsZHI7IER1bW15IGNvZGluZyBnaXZlcyB1cyB0aGUgInNpbXBsZSBlZmZlY3RzLCIgY29tcGFyaW5nIGRpZmZlcmVudCBsZXZlbHMgdG8gYSAqcmVmZXJlbmNlIGdyb3VwKiB3aGlsZSBlZmZlY3RzIGNvZGluZyBnaXZlcyB1cyB0aGUgIm1haW4gZWZmZWN0cywiIGNvbXBhcmluZyBkaWZmZXJlbnQgbGV2ZWxzIHRvIHRoZSAqZ3JvdXAgbWVhbiogKioKCiMjIEhvdyBhcmUgb3VyIHZhcmlhYmxlcyBjb2RlZD8KCmBgYHtyfQpjb250cmFzdHMoZGYuc2hvcnQkZ2VuZGVyUikKYGBgCgoqKklkZW50aWZpZXJzOioqCgoqIC0xID0gRmVtYWxlCgoqIDEgPSBNYWxlCgo8YnI+CgoqKkNvbnRyYXN0czoqKgoKKiAwID0gRmVtYWxlCgoqIDEgPSBNYWxlCgoqKkhvdyBkb2VzIHRoaXMgaW1wYWN0IG91ciBpbnRlcnByZXRhdGlvbiBvZiB0aGUgaW50ZXJjZXB0PyoqCgoqIEF2ZXJhZ2Ugc2FkbmVzcyBhZnRlciB0aGUgaW50ZXJhY3Rpb24gZm9yIHdvbWVuICh3aGVuIGdlbmRlclIgPSAwKQoKYGBge3J9CmNvbnRyYXN0cyhkZi5zaG9ydCRjb25kaXRpb25fM0xldmVsKQpgYGAKCgoqKklkZW50aWZpZXJzOioqCgoqIDEgPSBDb250cm9sIGR5YWQKCiogMiA9IFNhZCBhY3RvcgoKKiAzID0gU2FkIHBhcnRuZXIKCjxicj4KCioqQ29udHJhc3RzOioqCgpGSVJTVCBFRkZFQ1Q6IHdoYXQgaXMgdGhlIGVmZmVjdCBvZiBzYWQgYWN0b3IgdnMgY29udHJvbCBjb25kaXRpb24/CgpTRUNPTkQgRUZGRUNUOiB3aGF0IGlzIHRoZSBlZmZlY3Qgb2Ygc2FkIHBhcnRuZXIgdnMgY29udHJvbCBjb25kaXRpb24/Cgo8YnI+CgojIyBDb250cmFzdCBjb2RpbmcgaW4gUgoKYGBge3J9CiMgZWZmZWN0LWNvZGUKY29udHIuc3VtKDIpCmNvbnRyLnN1bSgzKQpgYGAKCmBgYHtyfQojIGR1bW15IGNvZGUKY29udHIudHJlYXRtZW50KDIpCmNvbnRyLnRyZWF0bWVudCgzKQpgYGAKCiMjIyBBcHBseSBjb250cmFzdHMgKGVmZmVjdCBjb2RlKQoKYGBge3J9CmNvbnRyYXN0cyhkZi5zaG9ydCRnZW5kZXJSKSA8LSBjb250ci5zdW0oMikKY29udHJhc3RzKGRmLnNob3J0JGNvbmRpdGlvbl8zTGV2ZWwpIDwtIGNvbnRyLnN1bSgzKQoKIyBhbHRlcm5hdGl2ZTogY3VzdG9tIGVmZmVjdHMgY29kaW5nCmVmZmVjdENvbnRyYXN0cyA8LSBjYmluZChjKDEsIDAsIC0xKSwgYygwLCAxLCAtMSkpCmBgYAoKYGBge3J9Cm1vZGVsX3Nob3J0Y3V0IDwtIGxtKGF2Z19zYWRfaW50IH4gZ2VuZGVyUipjb25kaXRpb25fM0xldmVsLCBkYXRhID0gZGYuc2hvcnQpCgpzdW1tYXJ5KG1vZGVsX3Nob3J0Y3V0KQpgYGAKCiMjIyBBcHBseSBjb250cmFzdHMgKGR1bW15IGNvZGUpCgpgYGB7cn0KY29udHJhc3RzKGRmLnNob3J0JGdlbmRlclIpIDwtIGNvbnRyLnRyZWF0bWVudCgyKQpjb250cmFzdHMoZGYuc2hvcnQkY29uZGl0aW9uXzNMZXZlbCkgPC0gY29udHIudHJlYXRtZW50KDMpCgojIGFsdGVybmF0aXZlOiBjdXN0b20gZHVtbXkgY29kaW5nCmR1bW15Q29udHJhc3RzIDwtIGNiaW5kKGMoMCwxLDApLCBjKDAsIDAsIDEpKQpgYGAKCmBgYHtyfQptb2RlbF9zaG9ydGN1dDIgPC0gbG0oYXZnX3NhZF9pbnQgfiBnZW5kZXJSKmNvbmRpdGlvbl8zTGV2ZWwsIGRhdGEgPSBkZi5zaG9ydCkKCnN1bW1hcnkobW9kZWxfc2hvcnRjdXQyKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0KCiMjIyBTdW1tYXJ5IG9mIGludGVyY2VwdHMKCgpUaGUgaW50ZXJjZXB0IHJlcHJlc2VudHMgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSB3aGVuIGFsbCBwcmVkaWN0b3JzIGFyZSB6ZXJvCgotICpyYXcgKG5vIGNlbnRlcmluZyk6KiAwIGhlcmUgY2FuIHZhcnkgcXVpdGUgYSBiaXQgZGVwZW5kaW5nIG9uIHdoYXQgeW91ciBwcmVkaWN0b3JzIGFyZS4gSXQgbWF5IG5vdCBiZSBtZWFuaW5nZnVsLgoKLSAqZHVtbXktY29kaW5nOiogMCBpcyB0aGUgcmVmZXJlbmNlIGdyb3VwLiBUaGUgaW50ZXJjZXB0IGlzIHRoZSBhdmVyYWdlIERWIGZvciB0aGUgcmVmZXJlbmNlIGdyb3VwLgoKLSAqZWZmZWN0cy1jb2Rpbmc6KiAwIGlzIHRoZSBncmFuZCBtZWFuLiBUaGUgaW50ZXJjZXB0IGlzIHRoZSBEViB3aGVuIGFsbCBwcmVkaWN0b3JzIGFyZSBhdmVyYWdlZC4gTGV0J3Mgc2F5IHdlIGNvZGVkIHdvbWVuIC0xIGFuZCBtZW4gMS4gVGhlIGludGVyY2VwdCB3b3VsZCBiZSB0aGUgRFYgcmVnYXJkbGVzcyBvZiBnZW5kZXIgKGF2ZXJhZ2luZyBhY3Jvc3MgZ2VuZGVyKS4KCi0gKmdyYW5kLW1lYW4gY2VudGVyaW5nOiogMCBpcyB0aGUgZ3JhbmQgbWVhbi4gVGhlIGludGVyY2VwdCBpcyB0aGUgZXhwZWN0ZWQgRFYgYXQgdGhlIGF2ZXJhZ2UgbGV2ZWwgb2YgdGhlIHByZWRpY3RvcnMuIAoKLSAqcGVyc29uLW1lYW4gY2VudGVyaW5nOiogMCBpcyB0aGUgcGVyc29uJ3MgYXZlcmFnZSBmb3IgdGhhdCBwcmVkaWN0b3IuIFNvLCB0aGUgaW50ZXJjZXB0IHdvdWxkIGJlICd0aGUgZXhwZWN0ZWQgbGV2ZWwgb2YgYW54aWV0eSAoRFYpIHdoZW4geW91IHNsZWVwIHlvdXIgYXZlcmFnZSBhbW91bnQnCgoKLS0tLS0tCgojIFR3by1sZXZlbCBjcm9zc2VkIG1vZGVsCgoqREFUQVNFVCAzOiBJbnRlbGxlY3R1YWwgaHVtaWxpdHkgbWVhc3VyZWQgM3ggY291cnRlc3kgb2YgS2F0ZSBUaG9yc29uICYgQW1pZSBHb3Jkb24qCgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KIyBsb2FkIGluIG91ciBleGFtcGxlIGRhdGEKcm1fZGYgPC0gcmVhZC5jc3YoIi9Vc2Vycy9rYXJlZW5hZGVscm9zYXJpby9Eb3dubG9hZHMvRHlhZGljTG9uZ2l0dWRpbmFsX0V4YW1wbGVEYXRhc2V0X1JNMy5jc3YiKQpgYGAKCjk2NCBwZW9wbGUgcmVwb3J0ZWQgb24gdGhlaXIgaW50ZWxsZWN0dWFsIGh1bWlsaXR5IChJSCkgYXQgdGhyZWUgdGltZSBwb2ludHM6IHByZSAoYmVmb3JlIHRoZSBmaXJzdCBjb252ZXJzYXRpb24pLCBwb3N0IChhZnRlciB0aGUgbGFzdCBjb252ZXJzYXRpb24pLCBhbmQgZm9sbG93LXVwIChvbmUgbW9udGggYWZ0ZXIgdGhlIGxhc3QgY29udmVyc2F0aW9uKS4gV2UgYXJlIGdvaW5nIHRvIHVzZSB0aGVzZSBkYXRhIHRvIGFzayB3aGV0aGVyIElIIGNoYW5nZXMgYWNyb3NzIHRoZSB0aHJlZSB0aW1lIHBvaW50cy4KCgoqKkhlcmUgYXJlIHRoZSB2YXJpYWJsZXMgd2UncmUgaW50ZXJlc3RlZCBpbjoqKiAKCi0gKipJSCoqOiBpbnRlbGxlY3R1YWwgaHVtaWxpdHksIHJlcG9ydGVkIGF0IHRocmVlIHRpbWUgcG9pbnRzCi0gKip0aW1lKio6IHRpbWUsIHByZSA9IDE7IHBvc3QgPSAyOyBmb2xsb3ctdXAgPSAzCi0gKippZCoqOiB1bmlxdWUgSUQgbnVtYmVyIGZvciBlYWNoIHBlcnNvbgotICoqdGltZWNvbnRyYXN0MV9wcmVfcG9zdCoqOiBwcmUgPSAwLCBwb3N0ID0gMSwgZm9sbG93LXVwID0gMAotICoqdGltZWNvbnRyYXN0Ml9wcmVfZm9sbG93dXAqKjogcHJlID0gMCwgcG9zdCA9IDAsIGZvbGxvdy11cCA9IDEKCjxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj5USU1FPC9zcGFuPgrigKIgMTogcHJlCuKAoiAyOiBwb3N0CuKAoiAzOiBmb2xsb3ctdXAKCgpPdXIgcHJlZGljdG9ycyBhcmUgKip0aW1lY29udHJhc3QxX3ByZV9wb3N0KiosICoqdGltZWNvbnRyYXN0Ml9wcmVfZm9sbG93dXAqKiwgYW5kICoqdGltZS4qKgoKKiBQcmVkaWN0b3JzOiAKICArIHRpbWVjb250cmFzdDFfcHJlX3Bvc3QsIAogICsgdGltZWNvbnRyYXN0Ml9wcmVfZm9sbG93dXAsIAogICsgdGltZSwgCiAgKyB0aW1lY29udHJhc3QxX3ByZV9wb3N0IHggdGltZSwgCiAgKyB0aW1lY29udHJhc3QyX3ByZV9mb2xsb3d1cCB4IHRpbWUKCgoqIEVycm9yIHZhcmlhbmNlIGZvciB0aW1lMSwgdGltZTIsIHRpbWUzCgotLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEFuYWx5c2lzIHN0ZXBzCgpCZWZvcmUgd2UganVtcCBpbnRvIHRoZSBhbmFseXNpcywgbGV0J3MgdGFrZSBhIHN0ZXAgYmFjayBhbmQgZ28gdGhyb3VnaCBzb21lIHByZS1hbmFseXNlcyB0byBmaWd1cmUgb3V0OgoKMS4gd2hldGhlciB3ZSBuZWVkIHRvIGFjY291bnQgZm9yIG5vbmluZGVwZW5kZW5jZSBpbiB0aGUgZmlyc3QgcGxhY2UKMi4gYnVpbGQgb3VyIG1vZGVsCgotLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEludHJhY2xhc3MgQ29ycmVsYXRpb24gQ29lZmZpY2llbnQgKElDQykKClNvbWV0aW1lcyB1c2VkIHRvICJqdXN0aWZ5IiBub25pbmRlcGVuZGVudCBhbmFseXNlcy4gSUNDIGluZGV4ZXMgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiB0aW1lIHBvaW50cyBmb3IgYSBwYXJ0aWN1bGFyIG91dGNvbWUuIFRlY2huaWNhbGx5LCBpdCByZXByZXNlbnRzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSB0b3RhbCB2YXJpYW5jZSBpbiBhbiBvdXRjb21lIHRoYXQgaXMgZXhwbGFpbmVkIGJ5IG1lYW4gZGlmZmVyZW5jZXMgYmV0d2VlbiBzdWJqZWN0cy4gQW4gSUNDIG9mIDEgd291bGQgbWVhbiB0aGF0IGFsbCBvZiB0aGUgdmFyaWFiaWxpdHkgaW4gdGhlIERWIGlzIGJldHdlZW4gc3ViamVjdHMuIEluIHJlcGVhdGVkIHNlbGYtcmVwb3J0IGRhdGEsIGl0J3MgY29tbW9uIHRvIGhhdmUgSUNDcyBiZXR3ZWVuIC4yLS40LgoKQ2FsY3VsYXRpbmcgYW4gSUNDOgoKMS4gUnVuIGFuIE1MTSB3aXRoIG5vIHByZWRpY3RvcnMgKGkuZS4sIGEgbnVsbCBtb2RlbCkKMi4gVXNlIHBlcnNvbiBhcyBhIHJhbmRvbSBmYWN0b3IKMy4gVXNpbmcgdGhlIG91dHB1dCwgY2FsY3VsYXRlIHRoZSBJQ0MgYXMgdGhlIGZvbGxvd2luZzoKCiMjIyMgUnVuIG51bGwgbW9kZWwgd2l0aCBubG1lCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShoYXZlbikgIyByZWFkIFNQU1MgYW5kIFNBUyBmaWxlcwpsaWJyYXJ5KHJlZ2hlbHBlcikgIyBmb3IgSUNDIGNvbW1hbmQKCgpudWxsX21vZGVsX2xtZSA8LSBsbWUoSUggfiAxLAogICAgICAgICAgICAgZGF0YSA9IHJtX2RmLAogICAgICAgICAgICAgcmFuZG9tID0gfiAxIHwgaWQsCiAgICAgICAgICAgICBtZXRob2QgPSAiUkVNTCIsCiAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0KQoKc3VtbWFyeShudWxsX21vZGVsX2xtZSkKCklDQyhudWxsX21vZGVsX2xtZSkKYGBgCgojIyMjIFJ1biBudWxsIG1vZGVsIHdpdGggbG1lNAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkobG1lNCkKCm51bGxfbW9kZWxfbG1lciA8LSBsbWVyKElIIH4gMSArIAogICAgICAgICAgICAgICAgICAgICgxIHxpZCksIAogICAgICAgICAgICAgICAgICBkYXRhPXJtX2RmKQoKc3VtbWFyeShudWxsX21vZGVsX2xtZXIpCmBgYAoKKipIZXJlJ3MgdGhlIElDQyBlcXVhdGlvbjoqKgoKJCRJQ0MgPSBcZnJhYyB7XCBiZXR3ZWVuLWR5YWRcIHZhcmlhbmNlXCAocmFuZG9tXCBpbnRlcmNlcHRcIHZhcmlhbmNlKX0ge3RvdGFsXCB2YXJpYW5jZVwgKHJhbmRvbSBcIGludGVyY2VwdFwgdmFyaWFuY2VcICtcIHJlc2lkdWFsXCB2YXJpYW5jZSl9ICQkCmBgYHtyfQppZF92YXJpYW5jZSA8LSAwLjQxOTQKcmVzaWR1YWwgPC0gMC41NjIzCgojIGNhbGN1bGF0aW5nIElDQwppZF92YXJpYW5jZSAvIChpZF92YXJpYW5jZSArIHJlc2lkdWFsKQpgYGAKCiMjIyBXaGF0IGlzIG91ciB0YWtlYXdheSBmcm9tIHRoZSBJQ0M/CgoKCi0tLS0tLS0tLS0tLS0tCgojIyBUd28tbGV2ZWwgY3Jvc3NlZCBtb2RlbCB3aXRoIGluZGl2aWR1YWwgcmVwZWF0ZWQgbWVhc3VyZXMKCgpUaGlzIHdpbGwgYmUgYSBtYXJnaW5hbCBtb2RlbOKAkyB3ZeKAmXJlIGdvaW5nIHRvIGFkanVzdCBmb3Igbm9uaW5kZXBlbmRlbmNlIGJ5IHByb3ZpZGluZyBhIHZhcmlhbmNlLWNvdmFyaWFuY2Ugc3RydWN0dXJlIHRvIHRoZSByZXNpZHVhbHMuIFRoaXMgYXBwcm9hY2ggaXMgdXNlZnVsIGZvciByZXBlYXRlZCBtZWFzdXJlIHdpdGggMyBvciA0IHRpbWUgcG9pbnRzLgoKCkluIG90aGVyIHdvcmRzLCB0aGlzIHdpbGwgbW9kZWwgdGhlIG5vbmluZGVwZW5kZW5jZSB3aXRoIGEgKipjb3ZhcmlhbmNlKiogKGFkanVzdCBmb3Igbm9uaW5kZXBlbmRlbmNlIGJ5IGNvcnJlbGF0aW5nIHRoZSByZXNpZHVhbHMgYmV0d2VlbiBkeWFkIG1lbWJlcnMuIFRoaXMgYWxsb3dzIGZvciBib3RoIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBub25pbmRlcGVuZGVuY2UpLiAKCgojIyMgT3V0cHV0CgoxLiBGaXhlZCBwYXJhbWV0ZXIgZXN0aW1hdGVzCjIuICoqRXJyb3IgY292YXJpYW5jZSoqOiBhcmUgdGhlIHR3byB0aW1lIHBvaW50cycgZXJyb3JzIHJlbGF0ZWQgb3QgZWFjaCBvdGhlcj8KMy4gKipFcnJvciB2YXJpYW5jZSoqOiBpcyB0aGVyZSBzaWduaWZpY2FudCB2YXJpYW5jZSB0aGF0IGlzIHVuZXhwbGFpbmVkIGJ5IHRoZSBvdGhlciBjb21wb25lbnRzIGluIHRoZSBtb2RlbD8KCiMjIyBSZXNpZHVhbCBzdHJ1Y3R1cmUKCioqV2UncmUgZXN0aW1hdGluZyA2IHBhcmFtZXRlcnM6KioKCiAgICDigKIgMyB2YXJpYW5jZXMKICAgICAg4oCiIFZhcmlhbmNlIGF0IHByZQogICAgICDigKIgVmFyaWFuY2UgYXQgcG9zdAogICAgICDigKIgVmFyaWFuY2UgYXQgZm9sbG93dXAKICAgICAgCiAgICDigKIgMyB3aXRoaW4tcGVyc29uIGNvdmFyaWFuY2VzIGF0IGRpZmZlcmVudCB0aW1lIHBvaW50cwogICAgICDigKIgV2l0aGluLXBlcnNvbiBjb3ZhcmlhbmNlIGJldHdlZW4gcHJlIGFuZCBwb3N0CiAgICAgIOKAoiBXaXRoaW4tcGVyc29uIGNvdmFyaWFuY2UgYmV0d2VlbiBwcmUgYW5kIGZvbGxvdy11cAogICAgICDigKIgV2l0aGluLXBlcnNvbiBjb3ZhcmlhbmNlIGJldHdlZW4gcG9zdCBhbmQgZm9sbG93LXVwCgoKRm9yIHJlZmVyZW5jZSwgaGVyZSBpcyB0aGUgU1BTUyBzeW50YXg6CgoKICAgIE1JWEVEIElIIFdJVEggdGltZWNvbnRyYXN0MV9wcmVfcG9zdCB0aW1lY29udHJhc3QyX3ByZV9mb2xsb3d1cAogICAgL0ZJWEVEID0gdGltZWNvbnRyYXN0MV9wcmVfcG9zdCB0aW1lY29udHJhc3QyX3ByZV9mb2xsb3d1cCB8CiAgICBTU1RZUEUoMykKICAgIC9NRVRIT0QgPSBSRU1MCiAgICAvUFJJTlQgPSBHIFRFU1RDT1YgU09MVVRJT04KICAgIC9SRVBFQVRFRCB0aW1lIHwgc3ViamVjdChQYXJ0aWNpcGFudF9JRCkgQ09WVFlQRShVTikuCiAgICAKIyMjIyBXZWlnaHRlZCBieSBkYXkgKGVhY2ggZGF5IGhhcyBpdHMgb3duIHZhcmlhbmNlKQoKYGBge3J9CiMgZGF5UiBtdXN0IGJlIGFuIGludGVnZXIKcm1fZGYkdGltZSA8LSBhcy5pbnRlZ2VyKGFzLmZhY3RvcihybV9kZiR0aW1lKSkKCm1vZGVsMSA8LSBnbHMoSUggfiB0aW1lY29udHJhc3QxX3ByZV9wb3N0ICsgdGltZWNvbnRyYXN0Ml9wcmVfZm9sbG93dXAsCiAgICAgICAgICAgICBkYXRhID0gcm1fZGYsCiAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvclN5bW0oZm9ybSA9IH4gdGltZSB8IGlkKSwgCiAgICAgICAgICAgICB3ZWlnaHRzPXZhcklkZW50KGZvcm09fjF8dGltZSksCiAgICAgICAgICAgICBtZXRob2QgPSAiUkVNTCIsCiAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0KQoKc3VtbWFyeShtb2RlbDEpCmBgYAoKYGBge3J9CmdldFZhckNvdihtb2RlbDEsIGluZGl2aWR1YWwgPSAiNTgiKQpgYGAKCgojIyBUd28tbGV2ZWwgY3Jvc3NlZCBtb2RlbCB3aXRoIGRpc3Rpbmd1aXNoYWJsZSBkeWFkcwoKKipXZSdyZSBlc3RpbWF0aW5nIDIxIHBhcmFtZXRlcnM6KioKCiAgICDigKIgMyB2YXJpYW5jZXMKICAgICAg4oCiIFZhcmlhbmNlIGF0IHByZQogICAgICDigKIgVmFyaWFuY2UgYXQgcG9zdAogICAgICDigKIgVmFyaWFuY2UgYXQgZm9sbG93dXAKICAKICAgIOKAoiAzIHdpdGhpbi1keWFkIGNvdmFyaWFuY2VzIGF0IHRoZSBzYW1lIHRpbWUgcG9pbnQKICAgICAg4oCiIFdpdGhpbi1keWFkIGNvdmFyaWFuY2UgYmV0d2VlbiBwcmUgcmF0aW5ncwogICAgICDigKIgV2l0aGluLWR5YWQgY292YXJpYW5jZSBiZXR3ZWVuIHBvc3QgcmF0aW5ncwogICAgICDigKIgV2l0aGluLWR5YWQgY292YXJpYW5jZSBiZXR3ZWVuIGZvbGxvdy11cCByYXRpbmdzCiAgCiAgICDigKIgMyB3aXRoaW4tcGVyc29uIGNvdmFyaWFuY2VzIGF0IGRpZmZlcmVudCB0aW1lIHBvaW50cwogICAgICDigKIgV2l0aGluLXBlcnNvbiBjb3ZhcmlhbmNlIGJldHdlZW4gcHJlIGFuZCBwb3N0CiAgICAgIOKAoiBXaXRoaW4tcGVyc29uIGNvdmFyaWFuY2UgYmV0d2VlbiBwcmUgYW5kIGZvbGxvdy11cAogICAgICDigKIgV2l0aGluLXBlcnNvbiBjb3ZhcmlhbmNlIGJldHdlZW4gcG9zdCBhbmQgZm9sbG93LXVwCiAgCiAgICDigKIgMyB3aXRoaW4tZHlhZCBjb3ZhcmlhbmNlcyBhdCBkaWZmZXJlbnQgdGltZSBwb2ludHMKICAgICAg4oCiIFdpdGhpbi1keWFkIGNvdmFyaWFuY2UgYmV0d2VlbiBwcmUgYW5kIHBvc3QKICAgICAg4oCiIFdpdGhpbi1keWFkIGNvdmFyaWFuY2UgYmV0d2VlbiBwcmUgYW5kIGZvbGxvdy11cAogICAgICDigKIgV2l0aGluLWR5YWQgY292YXJpYW5jZSBiZXR3ZWVuIHBvc3QgYW5kIGZvbGxvdy11cAoKYGBge3J9Cm1vZGVsIDwtIGdscyhJSCB+IHRpbWVjb250cmFzdDFfcHJlX3Bvc3QgKyB0aW1lY29udHJhc3QyX3ByZV9mb2xsb3d1cCArIHBhcnR5ICsgCiAgICAgICAgICAgICAgIHBhcnR5KnRpbWVjb250cmFzdDFfcHJlX3Bvc3QgKwogICAgICAgICAgICAgICAgcGFydHkqdGltZWNvbnRyYXN0Ml9wcmVfZm9sbG93dXAsCiAgICAgICAgICAgICBkYXRhID0gcm1fZGYsCiAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvclN5bW0oZm9ybSA9IH4gUk0gfCBkeWFkKSwKICAgICAgICAgICAgIHdlaWdodHM9dmFySWRlbnQoZm9ybT1+MXxSTSksCiAgICAgICAgICAgICBtZXRob2QgPSAiUkVNTCIsCiAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0KQoKIyBvbW5pYnVzIHRlc3QKYW5vdmEobW9kZWwsIHR5cGUgPSAibWFyZ2luYWwiKQpgYGAKCiMjIyMgU0FTIE9tbmlidXMgb3V0cHV0CgpgYGB7ciBlY2hvPUZBTFNFLCBvdXQud2lkdGg9JzgwJSd9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCdwcDJfb21uaWJ1cy5wbmcnKQpgYGAKCgojIyMjIFByaW50IGNvdmFyaWFuY2UgcGFyYW1ldGVyIGVzdGltYXRlcwoKYGBge3J9CmdldFZhckNvdihtb2RlbCkKZ2V0VmFyQ292KG1vZGVsLCBpbmRpdmlkdWFsID0gMikKYGBgCgojIyMjIFNBUyBDb3ZhcmlhbmNlIG91dHB1dAoKYGBge3IgZWNobz1GQUxTRSwgb3V0LndpZHRoPSc4MCUnfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygncHAyX2NvdmFyaWFuY2UucG5nJykKYGBgCgojIyMgV2hhdCBjYW4gd2UgbGVhcm4gZnJvbSB0aGlzPwoKCgotLS0tLS0tLS0tLS0tCgojIFlvdXIgdHVybiEKCiMjIENvbnRyYXN0IGNvZGluZwoKCipEQVRBU0VUIDQ6IEFuZHkgRmllbGQncyBWaWFncmEgRGF0YSoKCmBgYHtyfQp2X2RmIDwtIHJlYWQuZGVsaW0oIi9Vc2Vycy9rYXJlZW5hZGVscm9zYXJpby9EZXNrdG9wL2V2ZXJ5dGhpbmcvMl9hcmVhcy9zcHJpbmcgMjAyNC9wZXJzb24gcGVyY2VwdGlvbi9WaWFncmEuZGF0IikKYGBgCgpgYGB7cn0KaGVhZCh2X2RmKQpgYGAKCjEuIFVzZSBjb250cmFzdCBjb2Rpbmcgc28gdGhhdCB0aGUgaW50ZXJjZXB0IHJlcHJlc2VudHMgdGhlIGF2ZXJhZ2UgbGliaWRvIGFjcm9zcyBhbGwgcGFydGljaXBhbnRzLgoyLiBDb2RlIHRoZSB2YXJpYWJsZXMgc28gdGhhdCB0aGUgaW50ZXJjZXB0IHJlcHJlc2VudHMgdGhlIGF2ZXJhZ2UgbGliaWRvIGZvciB0aGUgY29udHJvbCBncm91cC4KMy4gQ29kZSB0aGUgdmFyaWFibGVzIHNvIHRoYXQgdGhlIGZpcnN0IGNvbnRyYXN0IGNvbXBhcmVzIHRoZSB0cmVhdG1lbnQgZ3JvdXAgKExvdyArIEhpZ2gpIHRvIHRoZSBjb250cm9sIGdyb3VwIGFuZCB0aGUgc2Vjb25kIGNvbnRyYXN0IGNvbXBhcmVzIHRoZSBjb250cm9sIHRvIHRoZSBsb3cgZG9zZSBncm91cC4KCiMjIENlbnRlcmluZyAmIFR3by1MZXZlbCBDcm9zc2VkIE1vZGVsICh3aXRoIGR5YWRzISkKCk5vdywgd2UnbGwgZm9sbG93IHRoZSBzYW1lIHN0ZXBzIHdpdGggdGhlIFJvb21tYXRlIGRhdGEgd2UndmUgYmVlbiB3b3JraW5nIHdpdGguIFVzZSB0aGUgcm9vbW1hdGUgZGYgdG8gdGVzdCB3aGV0aGVyIHBlb3BsZSBhcmUgbW9yZSBjb21mb3J0YWJsZSBleHByZXNzaW5nIHRoZW1zZWx2ZXMgKHBleHByZXNzKSBhcmUgaGFwcGllciAocGhhcHB5KS4KCkhlcmUgYXJlIHNvbWUgb3RoZXIgdmFyaWFibGVzIHlvdSdsbCBuZWVkCioqZGF5UiBEeWFkIFJNIHBhcnRudW0qKiAKCjEuIEFyZSB0aGUgZGF0YSBub25pbmRlcGVuZGVudD8gKGRvIHdlIGFjdHVhbGx5IG5lZWQgdG8gdXNlIE1MTSkKMi4gQXJlIHBlb3BsZSB3aG8gYXJlIG1vcmUgY29tZm9ydGFibGUgZXhwcmVzc2luZyB0aGVtc2VsdmVzIGhhcHBpZXI/CjMuIEFyZSBwZW9wbGUgaGFwcGllciBpZiB0aGV5IGZlZWwgbW9yZSBjb21mb3J0YWJsZSBleHByZXNzaW5nIHRoZW1zZWx2ZXMgdGhhbiB0aGV5IHR5cGljYWxseSBkbz8KCgoqREFUQVNFVCA1OiBNb3JlIFJvb21tYXRlIERhdGEqCgpOb3RlIHRoaXMgaXMgYSBkaWZmZXJlbnQgZmlsZSB0aGFuIHdoYXQgd2UndmUgYmVlbiB1c2luZy4KCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9CmxpYnJhcnkoaGF2ZW4pCgpyb29tbWF0ZV9kZiA8LSByZWFkX3NhdigiL1VzZXJzL2thcmVlbmFkZWxyb3NhcmlvL0Rlc2t0b3AvZXZlcnl0aGluZy8yX2FyZWFzL3NwcmluZyAyMDI0L3BlcnNvbiBwZXJjZXB0aW9uL3NhbXBsZSBkYXRhXzEuc2F2IikKYGBgCgpJbiB0aGlzIGFuYWx5c2lzLCBvdXIgZ3JvdXBpbmcvc3ViamVjdCB2YXJpYWJsZSBpcyAiRHlhZCIgYW5kIG91ciByZXBlYXRlZCB2YXJpYWJsZSBpcyAiUk0iLiBGb3IgcmVmZXJlbmNlLCBoZXJlIGlzIHRoZSBTUFNTIHN5bnRheDoKCiAgICBNSVhFRCBEViBXSVRIIElWIAogICAgIC9GSVhFRCA9IElWIAogICAgIC9QUklOVCA9IFNPTFVUSU9OIFRFU1RDT1YKICAgICAvUkVQRUFURUQgPVJNIHwgU1VCSkVDVCAoRHlhZCkgQ09WVFlQRSAoVU5SKS4KCgpGb3IgUiwgdGhlIGVxdWl2YWxlbnQgdG8gQ09WVFlQRSAoVU5SKSBpcyBjb3JyZWxhdGlvbiA9IGNvclN5bW0uIAoKCg==