(Load packages)

All of the prompts will be in purple text. (Or blue if its a header)

All of the grading rubrics will be in red text.

Your answers will be in black text. Hint: replace all text that says Your Text Here.

Data Description

The data for this assignment come from the Health and Retirement Study (HRS), 2022 Core (Final, Version 2.0). This assignment draws on three data files:

  • H22B_R (Section B: Demographics, respondent level)
  • H22C_R (Section C: Physical Health, respondent level)
  • H22H_H (Section H: Housing, household level)

Research Question

Record your overall research question that you will test in this assignment (hint: a research question MUST end with a question mark.)

Do perceived neighborhood safety (a household-level characteristic) and life satisfaction (an individual-level characteristic) predict self-rated health among older adults in the United States?

Hypotheses

Provide one hypothesis for a level 1 variable and one for a level 2 variable:

Level 1

Respondents who report higher life satisfaction will report better self-rated health, controlling for neighborhood safety.

Level 2

Respondents living in households whose neighborhoods are perceived as safer will report better self-rated health than respondents living in households whose neighborhoods are perceived as less safe.

2pt: provided RQ and hypotheses. 1pt: some errors. 0pt: all missing/incorrect

Answer the following questions about your data

Questions about the data:

Is this clustered data?

Yes. Respondents in the HRS are sampled within households. Response’s from people living in the same household are not independent of one another.

What is the nesting structure?

Respondents (Level 1) are nested within households (Level 2).

Individual-level identifier?

PN (Respondent Person Identification Number).

Cluster identifier?

HHID + SSUBHH together. When a couple divorces or separates, the households retain the same HHID and are distinguished only by SSUBHH. Clustering on HHID alone would incorrectly group ex-spouses who no longer share a residence, so a concatenated HHID_SSUBHH variable is constructed and used as the cluster identifier.

Level 1 variables?

  • Self-rated health (SC001)
  • Life satisfaction (SB000)

Level 2 variables?

  • Perceived neighborhood safety (SH150)

2pt: all correct answers. 1pt: > 50% correct answers. 0pt: < 50% correct answers

Variable Descriptions

Please provide brief variable descriptions of each of your variables. At a minimum, include the construct name, a description, the type of variable (nominal/categorical, ordinal/ordered categorical, continuous, etc.), and the level at which it is measured.

  1. Self-rated health (SC001)
  • Construct: Global subjective health.
  • Description: Respondents were asked, “Would you say your health is excellent, very good, good, fair, or poor?” Responses are coded 1 = Excellent, 2 = Very good, 3 = Good, 4 = Fair, 5 = Poor. For this analysis the variable is reverse-coded as health_r = 6 - SC001 so that higher scores indicate better health.
  • Type: Ordinal (ordered categorical), five points. Following standard practice in the aging and health literature, it is treated as approximately continuous so that it can serve as the outcome in a linear multilevel model.
  • Level: Level 1 (respondent)
  1. Life satisfaction (SB000)
  • Construct: Global subjective well-being.
  • Description: Respondents were asked, “Now, please think about your life-as-a-whole. How satisfied are you with it? Are you completely satisfied, very satisfied, somewhat satisfied, not very satisfied, or not at all satisfied?” Responses are coded 1 = Completely satisfied through 5 = Not at all satisfied. The variable is reverse-coded as satis_r = 6 - SB000 so that higher scores indicate greater satisfaction.
  • Type: Ordinal (ordered categorical), five points; treated as approximately continuous.
  • Level: Level 1 (respondent).
  1. Perceived neighborhood safety (SH150)
  • Construct: Household neighborhood context.
  • Description: The respondent was asked, “Would you say the safety of your neighborhood is excellent, very good, good, fair or poor?” Responses are coded 1 = Excellent through 5 = Poor. The variable is reverse-coded as safety_r = 6 - SH150 so that higher scores indicate a safer perceived neighborhood.
  • Type: Ordinal (ordered categorical), five points; treated as approximately continuous.
  • Level: Level 2 (household).

2pt: adequate description of every variable. 1pt: some variables and/or details missing. 0pt: significant parts missing

Call in Data

#Read in the data

demog  <- read_dta("H22B_R.dta")   
health <- read_dta("H22C_R.dta")   
house  <- read_dta("H22H_H.dta")

demog  <- haven::zap_labels(demog)
health <- haven::zap_labels(health)
house  <- haven::zap_labels(house)

#Create a smaller dataset with only the few variables described above

demog_sm  <- demog  %>% dplyr::select(HHID, PN, SSUBHH, SB000)
health_sm <- health %>% dplyr::select(HHID, PN, SC001)
house_sm  <- house  %>% dplyr::select(HHID, SSUBHH, SH150)

# merge the two respondent-level files on HHID + PN
resp <- merge(demog_sm, health_sm, by = c("HHID", "PN"))

# merge the household-level file on HHID + SSUBHH
dat <- merge(resp, house_sm, by = c("HHID", "SSUBHH"))

# recode HRS missing-data codes to NA
# -8 = web non-response, 8 = Don't Know, 9 = Refused
hrs_na <- function(x) ifelse(x %in% c(-8, 8, 9), NA, x)

dat <- dat %>%
  mutate(across(c(SB000, SC001, SH150), hrs_na))

# reverse-code all three so that HIGHER = BETTER on every variable
dat <- dat %>%
  mutate(
    health_r = 6 - SC001,   # 5 = Excellent health ... 1 = Poor health
    satis_r  = 6 - SB000,   # 5 = Completely satisfied ... 1 = Not at all
    safety_r = 6 - SH150    # 5 = Excellent safety ... 1 = Poor safety
  )

# build the Level 2 cluster identifier (2022 household, not original household)
dat <- dat %>%
  mutate(hhid_sub = paste0(HHID, "_", SSUBHH))

# listwise-delete cases missing
mydata <- dat %>%
  dplyr::select(hhid_sub, HHID, SSUBHH, PN, health_r, satis_r, safety_r) %>%
  filter(complete.cases(.))

#Print the first few lines of your smaller dataset ----------------------------
head(mydata) %>%
  kbl(caption = "First six rows of the analytic dataset") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
First six rows of the analytic dataset
hhid_sub HHID SSUBHH PN health_r satis_r safety_r
010001_0 010001 0 010 4 4 4
010003_0 010003 0 030 3 4 1
010004_1 010004 1 040 3 5 5
010013_1 010013 1 040 3 4 2
010038_0 010038 0 010 4 4 5
010038_0 010038 0 040 4 4 5
n_people   <- nrow(mydata)
n_clusters <- length(unique(mydata$hhid_sub))
clus_sizes <- table(table(mydata$hhid_sub))
cat("Respondents (Level 1):", n_people, "\n")
## Respondents (Level 1): 14541
cat("Households (Level 2):", n_clusters, "\n")
## Households (Level 2): 11031
cat("Average cluster size:", round(n_people / n_clusters, 2), "\n\n")
## Average cluster size: 1.32
cat("Distribution of cluster sizes:\n")
## Distribution of cluster sizes:
print(clus_sizes)
## 
##    1    2 
## 7521 3510

2pt: all below components of code present 1pt: some parts missing 0pt: significant parts missing/all missing

Data Prep and Descriptives

Distributions (full sample):

[Be sure to include all variables of interest]

#View descriptive statistics

desc <- psych::describe(mydata[, c("health_r", "satis_r", "safety_r")])

desc %>%
  kbl(digits = 2,
      caption = "Descriptive statistics for all analysis variables (reverse-coded)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Descriptive statistics for all analysis variables (reverse-coded)
vars n mean sd median trimmed mad min max range skew kurtosis se
health_r 1 14541 3.08 1.02 3 3.09 1.48 1 5 4 -0.09 -0.56 0.01
satis_r 2 14541 3.84 0.85 4 3.88 1.48 1 5 4 -0.47 0.22 0.01
safety_r 3 14541 3.78 1.07 4 3.87 1.48 1 5 4 -0.56 -0.49 0.01
#Visualizations

ggplot(mydata, aes(x = factor(health_r), fill = factor(health_r))) +
  geom_bar() +
  scale_fill_viridis_d(option = "D", guide = "none") +
  scale_x_discrete(labels = c("1\nPoor", "2\nFair", "3\nGood",
                              "4\nVery good", "5\nExcellent")) +
  labs(title = "Self-rated health (outcome, Level 1)",
       x = "Self-rated health (reverse-coded)", y = "Number of respondents") +
  theme_minimal()

ggplot(mydata, aes(x = factor(satis_r), fill = factor(satis_r))) +
  geom_bar() +
  scale_fill_viridis_d(option = "C", guide = "none") +
  scale_x_discrete(labels = c("1\nNot at all", "2\nNot very", "3\nSomewhat",
                              "4\nVery", "5\nCompletely")) +
  labs(title = "Life satisfaction (predictor, Level 1)",
       x = "Life satisfaction (reverse-coded)", y = "Number of respondents") +
  theme_minimal()

hh_level <- mydata %>%
  group_by(hhid_sub) %>%
  dplyr::summarise(safety_r = first(safety_r), .groups = "drop")

ggplot(hh_level, aes(x = factor(safety_r), fill = factor(safety_r))) +
  geom_bar() +
  scale_fill_viridis_d(option = "E", guide = "none") +
  scale_x_discrete(labels = c("1\nPoor", "2\nFair", "3\nGood",
                              "4\nVery good", "5\nExcellent")) +
  labs(title = "Perceived neighborhood safety (predictor, Level 2)",
       x = "Neighborhood safety (reverse-coded)", y = "Number of households") +
  theme_minimal()

2pt: appropriate descriptive statistics and plot of every variable 1pt: some variables missing and/or poor choice of visualization 0pt: significant parts missing/over half poor choices

Summary

Include a summary that discusses the distribution based on the plots and the skew/kurtosis (if continuous). Note whether there are likely any outliers and how you came to that conclusion.

  1. Self-rated health. Self-rated health averaged 3.08 (SD = 1.02, median = 3). The skew of −0.09 confirms the distribution is essentially symmetric, and the kurtosis of −0.56 indicates it is slightly flatter than normal. Both values fall well within the conventional thresholds of |2| for skew and |7| for kurtosis, so the variable is acceptable for treatment as approximately continuous. The mean and 5% trimmed mean are nearly identical (3.08 vs. 3.09), indicating that no extreme scores are pulling the mean. There are no outliers: the observed range is exactly 1 to 5;and the most extreme possible scores sit close to the mean in standardized terms (z = −2.04 for “Poor” and z = 1.88 for “Excellent”), well inside the |3.29| cutoff.

  2. Life satisfaction. Life satisfaction averaged 3.84 (SD = 0.85, median = 4).There’s a negative (left) skew of −0.47, reflecting a ceiling effect that is well documented for subjective well-being among older adults. Kurtosis of 0.22 is close to that of a normal distribution. Both values fall within acceptable limits, so no transformation is required. The trimmed mean (3.88) is slightly higher than the mean (3.84), consistent with the small tail of low scores pulling the mean down slightly. It’s possible to have outlier for this variable, since the lowest category (“Not at all satisfied”) falls at z = (1 − 3.84) / 0.85 = −3.34, just beyond the |3.29| threshold. Respondents choosing this category will therefore be flagged in the outlier check below.

  3. Perceived neighborhood safety. Neighborhood safety averaged 3.78 (SD = 1.07, median = 4). Kurtosis of −0.49 indicates a slightly flatter-than-normal distribution. The trimmed mean (3.87) exceeds the mean (3.78) by the largest margin of the three variables, again reflecting the thin tail of low safety ratings. There are no outliers: the lowest possible score falls at z = (1 − 3.78) / 1.07 = −2.60 and the highest at z = 1.13, both inside the cutoff.

PER VARIABLE: 1pt: summary makes sense 0pt: summary doesn’t match descriptives/visualizations or is missing. Take the average of each variables’ scores for this part of the rubric

Check for outliers and transform if needed

Note, even if your data do not show that you have outliers, choose at least one variable to fill in the code below for practice.

#Identify outliers 

mydata <- mydata %>%
  mutate(
    health_z = as.numeric(scale(health_r)),
    satis_z  = as.numeric(scale(satis_r)),
    safety_z = as.numeric(scale(safety_r))
  )

outlier_check <- data.frame(
  Variable  = c("Self-rated health", "Life satisfaction", "Neighborhood safety"),
  Min_z     = c(min(mydata$health_z), min(mydata$satis_z), min(mydata$safety_z)),
  Max_z     = c(max(mydata$health_z), max(mydata$satis_z), max(mydata$safety_z)),
  N_flagged = c(sum(abs(mydata$health_z) > 3.29),
                sum(abs(mydata$satis_z)  > 3.29),
                sum(abs(mydata$safety_z) > 3.29))
)

outlier_check %>%
  kbl(digits = 2,
      col.names = c("Variable", "Min z", "Max z", "N with |z| > 3.29"),
      caption = "Outlier screen for all analysis variables") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Outlier screen for all analysis variables
Variable Min z Max z N with |z| > 3.29
Self-rated health -2.04 1.88 0
Life satisfaction -3.34 1.36 164
Neighborhood safety -2.59 1.14 0
#Create a subset of the data that are only the outliers so we can view them

outliers <- mydata %>%
  filter(abs(satis_z) > 3.29) %>%
  dplyr::select(hhid_sub, PN, satis_r, satis_z, health_r, safety_r)

#View outliers

cat("Life satisfaction outliers:", nrow(outliers), "of", nrow(mydata),
    "respondents (", round(nrow(outliers) / nrow(mydata) * 100, 2), "% )\n\n")
## Life satisfaction outliers: 164 of 14541 respondents ( 1.13 % )
#Winsorize outliers

satis_floor   <- min(mydata$satis_r[abs(mydata$satis_z) <= 3.29])
satis_ceiling <- max(mydata$satis_r[abs(mydata$satis_z) <= 3.29])

cat("\nWinsorizing bounds: floor =", satis_floor, ", ceiling =", satis_ceiling, "\n")
## 
## Winsorizing bounds: floor = 2 , ceiling = 5
mydata <- mydata %>%
  mutate(satis_w = pmin(pmax(satis_r, satis_floor), satis_ceiling))

#Re-check Descriptive statistics (on all versions of the variable(s) just created)

psych::describe(mydata[, c("satis_r", "satis_w")]) %>%
  kbl(digits = 2,
      caption = "Life satisfaction: original, winsorized") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Life satisfaction: original, winsorized
vars n mean sd median trimmed mad min max range skew kurtosis se
satis_r 1 14541 3.84 0.85 4 3.88 1.48 1 5 4 -0.47 0.22 0.01
satis_w 2 14541 3.86 0.82 4 3.88 1.48 2 5 3 -0.23 -0.59 0.01
# re-screen the winsorized variable to confirm no cases remain beyond |3.29|
satis_w_z <- as.numeric(scale(mydata$satis_w))
cat("Winsorized variable: min z =", round(min(satis_w_z), 2),
    "| max z =", round(max(satis_w_z), 2),
    "| cases still flagged =", sum(abs(satis_w_z) > 3.29), "\n")
## Winsorized variable: min z = -2.27 | max z = 1.4 | cases still flagged = 0
#Re-plot the "final" variable you are comfortable using. ----------------------

# final analysis variable = winsorized life satisfaction
mydata <- mydata %>% mutate(satis_final = satis_w)

# before/after comparison
compare <- rbind(
  data.frame(version = "Original", value = mydata$satis_r),
  data.frame(version = "Winsorized (final)", value = mydata$satis_final)
)

ggplot(compare, aes(x = factor(value, levels = 1:5), fill = factor(value))) +
  geom_bar() +
  facet_wrap(~ version) +
  scale_fill_viridis_d(option = "C", guide = "none") +
  scale_x_discrete(drop = FALSE,
                   labels = c("1\nNot at all", "2\nNot very", "3\nSomewhat",
                              "4\nVery", "5\nCompletely")) +
  labs(title = "Life satisfaction before and after winsorizing",
       x = "Life satisfaction (reverse-coded)", y = "Number of respondents") +
  theme_minimal()

2pt: all variables checked and corrected 1pt: <50% of variables that needed to be checked and/or corrected were not done 0pt: >50% of variabels that needed to be checked and/or corrected were not done.

Summary

Include a summary that provides a justification for any data manipulations you did. Include for each variable whether or not you checked/winsorized/transformed and whether a change was needed or not, and if there was a change, whether it was successful or not.

  1. Self-rated health: Checked; no winsorizing or transformation applied.
  2. Life satisfaction: Checked and winsorized. Transformation was not needed since transforming a five-point ordinal scale would destroy the interpretability of the score: a one-unit change in a squared score has no natural verbal meaning, whereas a one-unit change in the original corresponds to moving one full response category.The manipulation was successful, re-screening confirmed no cases remained beyond |z| > 3.29.
  3. Perceived neighborhood safety: Checked; no winsorizing or transformation applied.

PER VARIABLE: 1pt: summary makes sense. 0pt: summary doesn’t match descriptives/visualizations or is missing. Take the average of each variables’ scores for this part of the rubric

Degree of Nesting:

Check the degree of nesting for each predictor variable.

#Predictor 1: Life satisfaction (Level 1)

#1. Run ICC
icc_satis <- lmer(satis_final ~ 1 + (1 | hhid_sub), data = mydata, REML = TRUE)

#extract variance coefficients
vc_satis <- as.data.frame(VarCorr(icc_satis))
vc_satis
##        grp        var1 var2      vcov     sdcor
## 1 hhid_sub (Intercept) <NA> 0.2105958 0.4589072
## 2 Residual        <NA> <NA> 0.4643973 0.6814670
#Store the random effect variances (vcov column of VarCorr object)
tau_satis   <- vc_satis$vcov[vc_satis$grp == "hhid_sub"]   # between-household
sigma_satis <- vc_satis$vcov[vc_satis$grp == "Residual"]   # within-household

#Calculate ICC
ICC_satis <- tau_satis / (tau_satis + sigma_satis)

#Convert to a %
ICC_satis_pct <- ICC_satis * 100

#Calculate % of variance due to within-household variation
within_satis_pct <- 100 - ICC_satis_pct

# PREDICTOR 2: Neighborhood safety

#1. Run ICC
icc_safety <- lmer(safety_r ~ 1 + (1 | hhid_sub), data = mydata, REML = TRUE)
## Warning in optwrap(optimizer, devfun, start, lower = lower, upper = upper, :
## convergence code -4 from nloptwrap: NLOPT_ROUNDOFF_LIMITED: Roundoff errors led
## to a breakdown of the optimization algorithm. In this case, the returned
## minimum may still be useful. (e.g. this error occurs in NEWUOA if one tries to
## achieve a tolerance too close to machine precision.)
## Warning: Model failed to converge with 1 negative eigenvalue: -1.4e-04
cat("Singular fit for safety model?", isSingular(icc_safety), "\n\n")
## Singular fit for safety model? FALSE
#extract variance coefficients
vc_safety <- as.data.frame(VarCorr(icc_safety))
vc_safety
##        grp        var1 var2         vcov        sdcor
## 1 hhid_sub (Intercept) <NA> 8.903991e-01 9.436096e-01
## 2 Residual        <NA> <NA> 2.602295e-10 1.613163e-05
#Store the random effect variances (vcov column of VarCorr object)
tau_safety   <- vc_safety$vcov[vc_safety$grp == "hhid_sub"]
sigma_safety <- vc_safety$vcov[vc_safety$grp == "Residual"]

#Calculate ICC
ICC_safety <- tau_safety / (tau_safety + sigma_safety)

#Convert to a %
ICC_safety_pct <- ICC_safety * 100

#Calculate % of variance due to within-household variation
within_safety_pct <- 100 - ICC_safety_pct

data.frame(
  Predictor = c("Life satisfaction (Level 1)", "Neighborhood safety (Level 2)"),
  Tau00     = c(tau_satis, tau_safety),
  Sigma2    = c(sigma_satis, sigma_safety),
  ICC       = c(ICC_satis, ICC_safety),
  Between   = c(ICC_satis_pct, ICC_safety_pct),
  Within    = c(within_satis_pct, within_safety_pct)
) %>%
  kbl(digits = c(0, 4, 4, 3, 1, 1),
      col.names = c("Predictor", "Between-HH variance (τ00)",
                    "Within-HH variance (σ²)", "ICC",
                    "% between households", "% within households"),
      caption = "Degree of nesting for each predictor") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Degree of nesting for each predictor
Predictor Between-HH variance (τ00) Within-HH variance (σ²) ICC % between households % within households
Life satisfaction (Level 1) 0.2106 0.4644 0.312 31.2 68.8
Neighborhood safety (Level 2) 0.8904 0.0000 1.000 100.0 0.0

Summary

Provide a brief summary of the % of within-cluster and between-cluster variance (instead of the word cluster use whatever the cluster is – like class or cohort for example).

Life satisfaction. Approximately 31.2% of the variance in life satisfaction lies between households, while the remaining 68.8% lies within households — that is, between respondents who live in the same household. Because meaningful variance exists within households, life satisfaction behaves as a genuine Level 1 variable and is appropriately modeled at the respondent level.

Perceived neighborhood safety. 100% of the variance in neighborhood safety lies between households and 0% lies within households. This is an expected result since safety was reported once per household by the designated financial/family respondent and assigned identically to every household member, so there is no within-household variation for the model to estimate. This result is the confirmation that neighborhood safety is a pure Level 2 variable.

PER VARIABLE: 1pt: summary makes sense. 0pt: summary doesn’t match descriptives/visualizations or is missing. Take the average of each variables’ scores for this part of the rubric

Check the degree of nesting for each the outcome variable.

#1. Run ICC
icc_health <- lmer(health_r ~ 1 + (1 | hhid_sub), data = mydata, REML = TRUE)

#extract variance coefficients
vc_health <- as.data.frame(VarCorr(icc_health))
vc_health
##        grp        var1 var2      vcov     sdcor
## 1 hhid_sub (Intercept) <NA> 0.2882790 0.5369162
## 2 Residual        <NA> <NA> 0.7521365 0.8672580
#Store the random effect variances (vcov column of VarCorr object)
tau_health   <- vc_health$vcov[vc_health$grp == "hhid_sub"]   # between-household
sigma_health <- vc_health$vcov[vc_health$grp == "Residual"]   # within-household

#Calculate ICC
ICC_health <- tau_health / (tau_health + sigma_health)

#Convert to a %
ICC_health_pct <- ICC_health * 100

#Calculate % of variance due to within-household variation
within_health_pct <- 100 - ICC_health_pct

data.frame(
  Outcome = "Self-rated health",
  Tau00   = tau_health,
  Sigma2  = sigma_health,
  ICC     = ICC_health,
  Between = ICC_health_pct,
  Within  = within_health_pct
) %>%
  kbl(digits = c(0, 4, 4, 3, 1, 1),
      col.names = c("Outcome", "Between-HH variance (τ00)",
                    "Within-HH variance (σ²)", "ICC",
                    "% between households", "% within households"),
      caption = "Degree of nesting for the outcome") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Degree of nesting for the outcome
Outcome Between-HH variance (τ00) Within-HH variance (σ²) ICC % between households % within households
Self-rated health 0.2883 0.7521 0.277 27.7 72.3

Summary

Provide a brief summary of the % of within-cluster and between-cluster variance (instead of the word cluster use whatever the cluster is – like class or cohort for example).

Self-rated health. Approximately 27.7% of the variance in self-rated health lies between households, while the remaining 72.3% lies within households.

2pt: summary makes sense, accurate and complete. 1pt: some errors or missing information. 0pt: many errors or missing information (e.g., over half problematic)

Centering

Discussion

Is it important to center for this analysis? For each variable, decide yes/no and if yes, then how?

Centering is important for this analysis. Neither predictor has a meaningful zero point: both are measured on 1-to-5 scales, so a score of 0 is not a possible response. Without centering, the model intercept would represent the expected self-rated health of a respondent with a life satisfaction of 0 living in a household with a neighborhood safety rating of 0. Centering relocates zero to a meaningful value so that the intercept can be interpreted.

For life satisfaction, grand-mean centering was chosen over group-mean centering for two reasons. First, it matches the research question. Hypothesis 1 asks whether people with higher life satisfaction report better health than people with lower life satisfaction in general. Second, the household structure makes group-mean centering impractical. For a single-respondent household, the household mean is the respondent’s own score, so the group-mean-centered value is exactly 0. Group-mean centering would therefore set the predictor to 0 for every single-respondent household and estimate the life satisfaction effect only from the minority of two-respondent households.

For perceived neighborhood safety, grand-mean centering is the only sensible option for a Level 2 variable. Centering changes only the meaning of the intercept, not the estimated effect of safety itself.

For self-rated health, no centering is needed. Centering the outcome would only shift the intercept without changing any slope, and it would make the intercept harder to interpret.

[list variables, choice, and justification here.]

PER VARIABLE 1pt: centering decision makes sense, justification appropriate. 0pt: missing justification and/or justification doesn’t make sense.

Center your predictors

According to your choice above, center your two predictors.

#Center Variables

# Level 1 predictor: grand mean computed across all RESPONDENTS
grand_mean_satis <- mean(mydata$satis_final, na.rm = TRUE)

# Level 2 predictor: grand mean computed across HOUSEHOLDS (one value each),
# so two-respondent households are not counted twice
hh_safety <- mydata %>%
  group_by(hhid_sub) %>%
  dplyr::summarise(safety_hh = first(safety_r), .groups = "drop")

grand_mean_safety <- mean(hh_safety$safety_hh, na.rm = TRUE)

# Create centered variables
mydata <- mydata %>%
  mutate(
    satis_gmc  = satis_final - grand_mean_satis,
    safety_gmc = safety_r    - grand_mean_safety
  )

cat("Grand mean, life satisfaction (across respondents):",
    round(grand_mean_satis, 4), "\n")
## Grand mean, life satisfaction (across respondents): 3.8562
cat("Grand mean, neighborhood safety (across households):",
    round(grand_mean_safety, 4), "\n\n")
## Grand mean, neighborhood safety (across households): 3.7319
#View the first few lines of data placing the old and new variables side by side to ensure it worked.
mydata %>%
  dplyr::select(hhid_sub, PN, satis_final, satis_gmc, safety_r, safety_gmc) %>%
  head(10) %>%
  kbl(digits = 3,
      col.names = c("Household", "PN",
                    "Life satis (original)", "Life satis (centered)",
                    "Safety (original)", "Safety (centered)"),
      caption = "Original and grand-mean-centered predictors, side by side") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Original and grand-mean-centered predictors, side by side
Household PN Life satis (original) Life satis (centered) Safety (original) Safety (centered)
010001_0 010 4 0.144 4 0.268
010003_0 030 4 0.144 1 -2.732
010004_1 040 5 1.144 5 1.268
010013_1 040 4 0.144 2 -1.732
010038_0 010 4 0.144 5 1.268
010038_0 040 4 0.144 5 1.268
010059_0 020 4 0.144 4 0.268
010059_0 030 4 0.144 4 0.268
010075_0 020 4 0.144 5 1.268
010106_0 020 4 0.144 5 1.268
# Verification: each centered variable should have a mean of 0
cat("Mean of satis_gmc across respondents (should be 0):",
    round(mean(mydata$satis_gmc), 10), "\n")
## Mean of satis_gmc across respondents (should be 0): 0
cat("Mean of safety_gmc across households (should be 0):",
    round(mean(hh_safety$safety_hh - grand_mean_safety), 10), "\n")
## Mean of safety_gmc across households (should be 0): 0

PER VARIABLE: 1pt: centered correctly and as specified. 0pt: not centered correctly according to how it was specified

Data Analysis

Unconditional Model

Run an unconditional model on your outcome.

Include the equations (with explanations) here:

Level 1 (respondent):

\[ \text{Health}_{ij} = \beta_{0j} + r_{ij}, \qquad r_{ij} \sim N(0, \sigma^2) \]

Level 2 (household):

\[ \beta_{0j} = \gamma_{00} + u_{0j}, \qquad u_{0j} \sim N(0, \tau_{00}) \]

Combined (mixed) model:

\[ \text{Health}_{ij} = \gamma_{00} + u_{0j} + r_{ij} \]

Explanations:

  • \(\text{Health}_{ij}\) is the self-rated health of respondent \(i\) in household \(j\), reverse-coded so that 1 = Poor and 5 = Excellent (higher scores indicate better health).
  • \(\beta_{0j}\) is the intercept for household \(j\). Because the model contains no predictors, it is simply the mean self-rated health of the respondents in household \(j\).
  • \(r_{ij}\) is the Level 1 residual: how far respondent \(i\)’s health rating falls from the mean of their own household. These residuals are assumed to be normally distributed with a mean of 0 and a variance of \(\sigma^2\), the within-household variance.
  • \(\gamma_{00}\) is the grand mean: the average self-rated health across all households. It is the only fixed effect in the model.
  • \(u_{0j}\) is the Level 2 residual: how far household \(j\)’s mean falls from the grand mean. These residuals are assumed to be normally distributed with a mean of 0 and a variance of \(\tau_{00}\), the between-household variance.
  • The Level 1 and Level 2 residuals are assumed to be independent of each other.
  • The combined model is obtained by substituting the Level 2 equation into the Level 1 equation. It shows that each respondent’s health rating is made up of three parts: the grand mean (\(\gamma_{00}\)), their household’s deviation from the grand mean (\(u_{0j}\)), and their own deviation from their household’s mean (\(r_{ij}\)).
  • The purpose of this model is to divide the total variance in self-rated health into its between-household (\(\tau_{00}\)) and within-household (\(\sigma^2\)) parts. These are used to compute the intraclass correlation, \(\text{ICC} = \tau_{00} / (\tau_{00} + \sigma^2)\), which shows how much respondents in the same household resemble each other. The variance components from this model also serve as the baseline for judging how much variance the predictors added in later models explain.

2pt: equations correct. 1pt: equations mostly correct. 0pt: many errors in equations.

2pt: explanations correct. 1pt: explanations mostly correct. 0pt: many errors in explanations.

# Unconditional (intercept-only) model
model0 <- lmer(health_r ~ 1 + (1 | hhid_sub), data = mydata, REML = TRUE)

summary(model0)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: health_r ~ 1 + (1 | hhid_sub)
##    Data: mydata
## 
## REML criterion at convergence: 41567.9
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -2.35104 -0.89094 -0.05737  0.77620  2.26120 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  hhid_sub (Intercept) 0.2883   0.5369  
##  Residual             0.7521   0.8673  
## Number of obs: 14541, groups:  hhid_sub, 11031
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept) 3.069e+00  8.940e-03 1.021e+04   343.3   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Variance components
vc_m0 <- as.data.frame(VarCorr(model0))
tau_m0   <- vc_m0$vcov[vc_m0$grp == "hhid_sub"]   # between-household
sigma_m0 <- vc_m0$vcov[vc_m0$grp == "Residual"]   # within-household
ICC_m0   <- tau_m0 / (tau_m0 + sigma_m0)

data.frame(
  Component = c("Between-household (τ00)", "Within-household (σ²)", "ICC"),
  Estimate  = c(tau_m0, sigma_m0, ICC_m0)
) %>%
  kbl(digits = 4, caption = "Unconditional model: variance components and ICC") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Unconditional model: variance components and ICC
Component Estimate
Between-household (τ00) 0.2883
Within-household (σ²) 0.7521
ICC 0.2771
# 95% confidence interval for the grand mean (fixed intercept)
confint(model0, parm = "(Intercept)", method = "Wald")
##              2.5 %   97.5 %
## (Intercept) 3.0513 3.086344
# Model fit (baseline for later model comparisons)
cat("AIC:", round(AIC(model0), 2), " | BIC:", round(BIC(model0), 2), "\n")
## AIC: 41573.9  | BIC: 41596.66

Summary

The unconditional model was estimated on 14,541 respondents nested within 11,031 households, an average of about 1.32 respondents per household.

Fixed effect. The estimated grand mean of self-rated health was \(\gamma_{00}\) = 3.07 (SE = 0.009, t(10,210) = 343.3, p < .001, 95% CI [3.05, 3.09]). Because self-rated health was reverse-coded so that 1 = Poor and 5 = Excellent, this means the average person in the sample rated their health at almost exactly “Good.” The narrow confidence interval reflects the large sample. The significance test indicates that the mean differs from 0. The model-based grand mean (3.07) is very slightly lower than the raw sample mean (3.08) because the multilevel model weights households rather than treating every respondent as fully independent.

Random effects. The between-household variance was \(\tau_{00}\) = 0.288 (SD = 0.537), and the within-household variance was \(\sigma^2\) = 0.752 (SD = 0.867). The resulting ICC of .28 indicates that approximately 27.7% of the variance in self-rated health lies between households and 72.3% lies within households. In other words, respondents living in the same household are noticeably more similar in their self-rated health than two randomly chosen respondents, but most of the variation is still between individuals within the same household.

This model serves as the baseline for all later models. Its variance components (\(\tau_{00}\) = 0.288, \(\sigma^2\) = 0.752) will be used to calculate how much variance is explained by life satisfaction and neighborhood safety, and its fit statistics (AIC = 41,573.9; BIC = 41,596.7) provide the reference point for model comparison.

2pt: summary makes sense, accurate and complete. 1pt: some errors or missing information. 0pt: many errors or missing information (e.g., over half problematic).

Fixed effect only

Include a level-1 predictor, but only as a fixed effect.

Include the equations (with explanations) here:

Level 1 (respondent):

\[ \text{Health}_{ij} = \beta_{0j} + \beta_{1j}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + r_{ij}, \qquad r_{ij} \sim N(0, \sigma^2) \]

Level 2 (household):

\[ \beta_{0j} = \gamma_{00} + u_{0j}, \qquad u_{0j} \sim N(0, \tau_{00}) \]

\[ \beta_{1j} = \gamma_{10} \]

Combined (mixed) model:

\[ \text{Health}_{ij} = \gamma_{00} + \gamma_{10}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + u_{0j} + r_{ij} \]

Explanations:

  • \(\text{Health}_{ij}\) is the self-rated health of respondent \(i\) in household \(j\) (1 = Poor to 5 = Excellent).
  • \((\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..})\) is respondent \(i\)’s grand-mean-centered life satisfaction: their winsorized life satisfaction score (higher = more satisfied) minus the mean across all respondents. A value of 0 represents a respondent with average life satisfaction.
  • \(\beta_{0j}\) is the intercept for household \(j\): the expected self-rated health of a respondent in household \(j\) whose life satisfaction is at the sample average.
  • \(\beta_{1j}\) is the slope for household.

2pt: equations correct 1pt: equations mostly correct 0pt: many errors in equations

2pt: explanations correct 1pt: explanations mostly correct 0pt: many errors in explanations

# Fixed-effect-only model: life satisfaction (grand-mean centered) with a
# random intercept for household but a FIXED slope
model1 <- lmer(health_r ~ satis_gmc + (1 | hhid_sub), data = mydata, REML = TRUE)

summary(model1)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: health_r ~ satis_gmc + (1 | hhid_sub)
##    Data: mydata
## 
## REML criterion at convergence: 39822.7
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.6655 -0.6615 -0.1040  0.6517  2.7753 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  hhid_sub (Intercept) 0.2021   0.4496  
##  Residual             0.7136   0.8447  
## Number of obs: 14541, groups:  hhid_sub, 11031
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept) 3.077e+00  8.307e-03 1.012e+04  370.41   <2e-16 ***
## satis_gmc   4.206e-01  9.711e-03 1.449e+04   43.31   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##           (Intr)
## satis_gmc 0.016
# 95% confidence intervals for the fixed effects
confint(model1, parm = c("(Intercept)", "satis_gmc"), method = "Wald")
##                 2.5 %    97.5 %
## (Intercept) 3.0608752 3.0934398
## satis_gmc   0.4015591 0.4396262
# Variance components
vc_m1 <- as.data.frame(VarCorr(model1))
tau_m1   <- vc_m1$vcov[vc_m1$grp == "hhid_sub"]   # between-household
sigma_m1 <- vc_m1$vcov[vc_m1$grp == "Residual"]   # within-household

# Proportional reduction in variance relative to the unconditional model
# (uses tau_m0 and sigma_m0 from the unconditional model chunk)
data.frame(
  Component   = c("Between-household (τ00)", "Within-household (σ²)"),
  Unconditional = c(tau_m0, sigma_m0),
  Model_1       = c(tau_m1, sigma_m1),
  Reduction_pct = c((tau_m0 - tau_m1) / tau_m0 * 100,
                    (sigma_m0 - sigma_m1) / sigma_m0 * 100)
) %>%
  kbl(digits = c(0, 4, 4, 1),
      col.names = c("Component", "Unconditional model", "Model 1",
                    "% reduction"),
      caption = "Variance explained by life satisfaction") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Variance explained by life satisfaction
Component Unconditional model Model 1 % reduction
Between-household (τ00) 0.2883 0.2021 29.9
Within-household (σ²) 0.7521 0.7136 5.1
# Likelihood ratio test vs. unconditional model.
# Models differing in FIXED effects must be compared with ML, not REML,
# so both are refit with REML = FALSE for this test only.
model0_ml <- lmer(health_r ~ 1 + (1 | hhid_sub), data = mydata, REML = FALSE)
model1_ml <- lmer(health_r ~ satis_gmc + (1 | hhid_sub), data = mydata, REML = FALSE)
anova(model0_ml, model1_ml)
## Data: mydata
## Models:
## model0_ml: health_r ~ 1 + (1 | hhid_sub)
## model1_ml: health_r ~ satis_gmc + (1 | hhid_sub)
##           npar   AIC   BIC logLik -2*log(L)  Chisq Df Pr(>Chisq)    
## model0_ml    3 41566 41589 -20780     41560                         
## model1_ml    4 39815 39846 -19904     39807 1752.8  1  < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Fit statistics
cat("AIC:", round(AIC(model1), 2), " | BIC:", round(BIC(model1), 2), "\n")
## AIC: 39830.65  | BIC: 39860.99

Summary

Report the findings (including interpretation with regard to units of analysis) for the fixed effect of your predictor.

The fixed effect of life satisfaction was \(\gamma_{10}\) = 0.421 (SE = 0.010, t(14,490) = 43.31, p < .001, 95% CI [0.402, 0.440]). The effect is positive and statistically significant, providing initial support for Hypothesis 1: respondents with higher life satisfaction report better self-rated health.

In the units of the variables, each one-category increase in life satisfaction (for example, moving from “somewhat satisfied” to “very satisfied”) is associated with a 0.42-point increase in self-rated health on the five-point scale. Because the winsorized life satisfaction variable ranges from 2 (“not very satisfied”) to 5 (“completely satisfied”), the difference between the least and most satisfied respondents spans three categories, corresponding to an expected difference of about 3 × 0.42 = 1.26 points in self-rated health. Relative to the spread of the outcome (SD = 1.02), a one-category increase in life satisfaction corresponds to roughly 0.41 standard deviations of self-rated health, a substantial association.

Adding life satisfaction also reduced the unexplained variance. Compared with the unconditional model, the between-household variance decreased from 0.288 to 0.202 (a 29.9% reduction) and the within-household variance decreased from 0.752 to 0.714 (a 5.1% reduction), for about a 12.0% reduction in total variance. The larger reduction at the household level is consistent with the earlier finding that life satisfaction itself clusters within households (ICC = .31): households whose members are more satisfied also tend to have better average health. Because life satisfaction was grand-mean centered, \(\gamma_{10}\) reflects a blend of these between-household differences and differences between people within the same household, rather than a purely within-household effect.

Because the data are cross-sectional and both variables are subjective self-reports, this coefficient describes an association, not a causal effect; part of it may reflect a shared tendency to rate oneself positively or negatively on both measures.

Report the findings (including interpretation with regard to units of analysis) for your intercept term.

The intercept was \(\gamma_{00}\) = 3.08 (SE = 0.008, t(10,120) = 370.41, p < .001, 95% CI [3.06, 3.09]). Because life satisfaction was grand-mean centered, a value of 0 on the predictor represents a respondent with average life satisfaction. The intercept is therefore the expected self-rated health of a respondent with average life satisfaction, which is about 3.08 on the five-point scale — almost exactly “Good” health.

The intercept is essentially unchanged from the unconditional model (3.07). This is expected: centering the predictor at its mean places the intercept at approximately the overall mean of the outcome, so adding a centered predictor changes the slope information in the model but not the baseline level. The very small shift (0.008 points) arises because the grand mean used for centering was computed across respondents, while the multilevel model weights households, so the two averages differ slightly. The near-zero correlation between the intercept and slope estimates (r = .016) further confirms that centering worked as intended, separating the estimate of the baseline level from the estimate of the life satisfaction effect.

2pt: summary makes sense, accurate and complete 1pt: some errors or missing information 0pt: many errors or missing information (e.g., over half problematic)

Random Slope

Now include the random effect for your level 1 predictor.

Include the equations (with explanations) here:

Level 1 (respondent):

\[ \text{Health}_{ij} = \beta_{0j} + \beta_{1j}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + r_{ij}, \qquad r_{ij} \sim N(0, \sigma^2) \]

Level 2 (household):

\[ \beta_{0j} = \gamma_{00} + u_{0j} \]

\[ \beta_{1j} = \gamma_{10} + u_{1j} \]

Combined (mixed) model:

\[ \text{Health}_{ij} = \gamma_{00} + \gamma_{10}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + u_{0j} + u_{1j}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + r_{ij} \]

Explanations:

  • The Level 1 equation is unchanged from the previous model: self-rated health is predicted by a household-specific intercept (\(\beta_{0j}\)), a household-specific slope for grand-mean-centered life satisfaction (\(\beta_{1j}\)), and a respondent-level residual (\(r_{ij}\)) with variance \(\sigma^2\).
  • The only change is in the second Level 2 equation. In the previous model the slope was fixed (\(\beta_{1j} = \gamma_{10}\)). Here a random term, \(u_{1j}\), is added, so the slope is now allowed to vary across households. The model no longer assumes that the relationship between life satisfaction and self-rated health is
  • Identification problem in these data: estimating a random slope gives each household two random effects (\(u_{0j}\) and \(u_{1j}\)). With 14,541 respondents in 11,031 households, this model requires 22,062 random effects — more than the number of observations — so lme4 refuses to fit it under its default settings because the random effects and residual variance cannot be separately identified. Most households contain a single respondent and provide no information about their own slope, and even a two-respondent household supplies only as many observations as random effects. The model was therefore fit with this check overridden solely to inspect the estimates; the results are interpreted as evidence about whether a random slope is supportable in these data, not as a trustworthy estimate of slope variation.

2pt: equations correct. 1pt: equations mostly correct. 0pt: many errors in equations

2pt: explanations correct. 1pt: explanations mostly correct. 0pt: many errors in explanations

# 1. Attempt the random slope model with default settings.
#    lme4 refuses to fit it; the error is captured and printed so it appears
#    in the knitted document as evidence for the decision below.
# ---------------------------------------------------------------------------

default_attempt <- tryCatch(
  lmer(health_r ~ satis_gmc + (1 + satis_gmc | hhid_sub),
       data = mydata, REML = TRUE),
  error = function(e) conditionMessage(e)
)

if (is.character(default_attempt)) {
  cat("Default fit stopped with the following error:\n\n", default_attempt, "\n\n")
}
## Default fit stopped with the following error:
## 
##  number of observations (=14541) <= number of random effects (=22062) for term (1 + satis_gmc | hhid_sub); the random-effects parameters and the residual variance (or scale parameter) are probably unidentifiable
# Why: each household gets TWO random effects (intercept + slope)
n_obs <- nrow(mydata)
n_hh  <- n_distinct(mydata$hhid_sub)
cat("Observations:", n_obs, "\n")
## Observations: 14541
cat("Households:", n_hh, "\n")
## Households: 11031
cat("Random effects requested (2 per household):", 2 * n_hh, "\n\n")
## Random effects requested (2 per household): 22062
# How much information is available to estimate a household-specific slope?
# A slope requires 2+ respondents in the household who DIFFER in life satisfaction.
slope_info <- mydata %>%
  group_by(hhid_sub) %>%
  dplyr::summarise(n = n(),
                   n_satis_values = n_distinct(satis_final),
                   .groups = "drop")

cat("Households with 1 respondent:", sum(slope_info$n == 1), "\n")
## Households with 1 respondent: 7521
cat("Households with 2+ respondents:", sum(slope_info$n >= 2), "\n")
## Households with 2+ respondents: 3510
cat("Households with 2+ respondents who differ in life satisfaction:",
    sum(slope_info$n >= 2 & slope_info$n_satis_values > 1), "\n\n")
## Households with 2+ respondents who differ in life satisfaction: 1929
# ---------------------------------------------------------------------------
# 2. Override the check to see the estimates. This does NOT solve the
#    identification problem; it only lets lme4 run so the result can be shown.
# ---------------------------------------------------------------------------

model2 <- lmer(health_r ~ satis_gmc + (1 + satis_gmc | hhid_sub),
               data = mydata, REML = TRUE,
               control = lmerControl(optimizer = "bobyqa",
                                     check.nobs.vs.nRE = "ignore"))

summary(model2)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: health_r ~ satis_gmc + (1 + satis_gmc | hhid_sub)
##    Data: mydata
## Control: lmerControl(optimizer = "bobyqa", check.nobs.vs.nRE = "ignore")
## 
## REML criterion at convergence: 39767.8
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.5486 -0.6785 -0.1128  0.6558  2.6518 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev. Corr 
##  hhid_sub (Intercept) 0.18678  0.4322        
##           satis_gmc   0.08285  0.2878   0.24 
##  Residual             0.67413  0.8211        
## Number of obs: 14541, groups:  hhid_sub, 11031
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept) 3.085e+00  8.301e-03 9.992e+03  371.67   <2e-16 ***
## satis_gmc   4.273e-01  1.016e-02 5.369e+03   42.07   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##           (Intr)
## satis_gmc 0.063
cat("\nSingular fit?", isSingular(model2), "\n\n")
## 
## Singular fit? FALSE
# Variance components
vc_m2 <- as.data.frame(VarCorr(model2))

tau00_m2 <- vc_m2$vcov[vc_m2$grp == "hhid_sub" & vc_m2$var1 == "(Intercept)" & is.na(vc_m2$var2)]
tau11_m2 <- vc_m2$vcov[vc_m2$grp == "hhid_sub" & vc_m2$var1 == "satis_gmc"   & is.na(vc_m2$var2)]
tau01_m2 <- vc_m2$vcov[vc_m2$grp == "hhid_sub" & !is.na(vc_m2$var2)]
cor01_m2 <- vc_m2$sdcor[vc_m2$grp == "hhid_sub" & !is.na(vc_m2$var2)]
sigma_m2 <- vc_m2$vcov[vc_m2$grp == "Residual"]

data.frame(
  Parameter = c("Intercept variance (τ00)", "Slope variance (τ11)",
                "Intercept-slope covariance (τ01)",
                "Intercept-slope correlation", "Residual variance (σ²)"),
  Model_1 = c(tau_m1, NA, NA, NA, sigma_m1),
  Model_2 = c(tau00_m2, tau11_m2, tau01_m2, cor01_m2, sigma_m2)
) %>%
  kbl(digits = 4,
      col.names = c("Parameter", "Model 1 (fixed slope)", "Model 2 (random slope)"),
      caption = "Random effects: fixed-slope vs. random-slope model") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Random effects: fixed-slope vs. random-slope model
Parameter Model 1 (fixed slope) Model 2 (random slope)
Intercept variance (τ00) 0.2021 0.1868
Slope variance (τ11) NA 0.0829
Intercept-slope covariance (τ01) NA 0.0298
Intercept-slope correlation NA 0.2395
Residual variance (σ²) 0.7136 0.6741
# ---------------------------------------------------------------------------
# 3. Compare with the fixed-slope model. Same fixed effects, so REML fits
#    can be compared directly (refit = FALSE). df = 2 (adds τ11 and τ01).
# ---------------------------------------------------------------------------

anova(model1, model2, refit = FALSE)
## Data: mydata
## Models:
## model1: health_r ~ satis_gmc + (1 | hhid_sub)
## model2: health_r ~ satis_gmc + (1 + satis_gmc | hhid_sub)
##        npar   AIC   BIC logLik -2*log(L)  Chisq Df Pr(>Chisq)    
## model1    4 39831 39861 -19911     39823                         
## model2    6 39780 39825 -19884     39768 54.806  2  1.256e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("\nModel 1 AIC:", round(AIC(model1), 2), " | BIC:", round(BIC(model1), 2), "\n")
## 
## Model 1 AIC: 39830.65  | BIC: 39860.99
cat("Model 2 AIC:", round(AIC(model2), 2), " | BIC:", round(BIC(model2), 2), "\n")
## Model 2 AIC: 39779.85  | BIC: 39825.36

Report the findings for the random effects (both intercept and slope of the predictor).

Allowing the effect of life satisfaction to vary across households produced a random intercept variance of \(\tau_{00}\) = 0.187 (SD = 0.432), a random slope variance of \(\tau_{11}\) = 0.083 (SD = 0.288), an intercept–slope correlation of r = .24 (\(\tau_{01}\) = 0.030), and a residual variance of \(\sigma^2\) = 0.674 (SD = 0.821). The model did not return a singular fit, although it could only be estimated after overriding lme4’s default check, because it requires 22,062 household-level random effects (an intercept and a slope for each of 11,031 households) but has only 14,541 observations.

Random intercept. The intercept variance describes how much households differ in the expected self-rated health of a respondent with average life satisfaction. Assuming normality, about 95% of household intercepts fall within 3.085 ± 1.96(0.432), or roughly 2.24 to 3.93 on the five-point scale — from just above “Fair” to nearly “Very good.” The intercept variance decreased from 0.202 in the fixed-slope model to 0.187, as part of the between-household variation previously attributed to intercepts is now attributed to differences in slopes.

Random slope. The slope variance describes how much the association between life satisfaction and self-rated health differs across households. The average slope was \(\gamma_{10}\) = 0.427, and about 95% of household slopes would be expected to fall within 0.427 ± 1.96(0.288), or roughly −0.14 to 0.99. Taken at face value, this implies that the association ranges from slightly negative in some households to nearly one full health category per satisfaction category in others, and that about 7% of households would show a negative association — higher life satisfaction paired with worse self-rated health. The intercept–slope correlation of .24 indicates that households with higher average health tend to show a somewhat stronger association between life satisfaction and health.

The residual variance also decreased, from 0.714 in the fixed-slope model to 0.674 (a 5.5% reduction). Adding the random slope improved model fit, \(\chi^2\)(2) = 54.81, p < .001, with AIC decreasing from 39,830.7 to 39,779.9 and BIC from 39,861.0 to 39,825.4. The two models were compared using their REML fits because they have identical fixed effects. The fixed effects themselves were nearly unchanged: the intercept moved from 3.08 to 3.09 and the life satisfaction effect from 0.421 to 0.427 (SE = 0.010, t(5,369) = 42.07, p < .001)..

Report whether or not you should retain the random slope.

The random slope was dropped, and the fixed-slope model was carried forward, despite the statistically significant improvement in fit. This decision rests on the structure of the data rather than on the test statistic.

First, the model is not properly identified. lme4 refused to fit it under its default settings because the number of random effects (22,062) exceeds the number of observations (14,541). Most households contain a single respondent, and a household-specific slope cannot be estimated from one data point; even a two-respondent household supplies only as many observations as it has random effects. The model could only be estimated by overriding this safeguard, so its variance estimates cannot be treated as reliable measures of household-level slope variation.

Second, with households this small, a random slope cannot be distinguished from a simpler explanation: that self-rated health is simply more variable at some levels of life satisfaction than at others (residual heteroscedasticity). A random slope model implies that the total variance of the outcome changes with the predictor, following \(\tau_{00} + 2\tau_{01}x + \tau_{11}x^2 + \sigma^2\), where \(x\) is centered life satisfaction. Using the estimates above, the implied variance of self-rated health is about 0.86 for a respondent with average life satisfaction but rises to roughly 1.03–1.04 for respondents at either end of the scale (“not very satisfied” or “completely satisfied”). The fit improvement is therefore consistent with health ratings being more spread out among respondents with extreme satisfaction scores, which a random slope can absorb even when slopes do not actually differ across households. With so few multi-respondent households, the model cannot tell these explanations apart.

Third, the estimates are substantively implausible when read as household slope variation. They imply that about 7% of households have a negative association between life satisfaction and self-rated health, which is difficult to interpret and more likely reflects the model fitting the variance pattern described above than real households in which greater satisfaction accompanies worse health.

Fourth, dropping the random slope does not change the substantive conclusions. The fixed effect of life satisfaction was nearly identical in both models (0.421 vs. 0.427), with a similar standard error and the same significance, so the test of Hypothesis 1 does not depend on this choice.

Because the random slope is not identifiable in these data, cannot be interpreted as household-level slope variation, and has no bearing on the fixed effects of interest, the simpler random-intercept model is retained. The next model therefore adds the Level 2 predictor with a random intercept only. This is noted as a limitation: the data cannot test whether the association between life satisfaction and health differs across households, and a sample with larger clusters would be needed to do so.

2pt: summary makes sense, accurate and complete. 1pt: some errors or missing information. 0pt: many errors or missing information (e.g., over half problematic)

Add a level 2 predictor

Based on the decision you made above, either keep or drop the random slope, and add a level 2 predictor.

Include the equations (with explanations) here:

Based on the decision above, the random slope for life satisfaction was dropped, and the model retains a random intercept only. Perceived neighborhood safety is added as a predictor of the household intercept.

Level 1 (respondent):

\[ \text{Health}_{ij} = \beta_{0j} + \beta_{1j}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + r_{ij}, \qquad r_{ij} \sim N(0, \sigma^2) \]

Level 2 (household):

\[ \beta_{0j} = \gamma_{00} + \gamma_{01}(\text{Safety}_{j} - \overline{\text{Safety}}_{.}) + u_{0j}, \qquad u_{0j} \sim N(0, \tau_{00}) \]

\[ \beta_{1j} = \gamma_{10} \]

Combined (mixed) model:

\[ \text{Health}_{ij} = \gamma_{00} + \gamma_{01}(\text{Safety}_{j} - \overline{\text{Safety}}_{.}) + \gamma_{10}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + u_{0j} + r_{ij} \]

Explanations:

  • \(\text{Health}_{ij}\) is the self-rated health of respondent \(i\) in household \(j\) (1 = Poor to 5 = Excellent).
  • \((\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..})\) is respondent \(i\)’s grand-mean-centered life satisfaction (winsorized; higher = more satisfied). It carries the subscript \(ij\) because it varies across respondents, including between respondents in the same household.
  • \((\text{Safety}_{j} - \overline{\text{Safety}}_{.})\) is household \(j\)’s grand-mean-centered perceived neighborhood safety (higher = safer), centered at the mean across households. It carries only the subscript \(j\) because it varies across households but is identical for all respondents within a household (ICC = 1.00). This is why it appears in the Level 2 intercept equation rather than the Level 1 equation: a household-level variable can explain differences between household means, but not differences between people within the same household.
  • \(\beta_{0j}\) is the intercept for household \(j\): the expected self-rated health of a respondent with average life satisfaction in that household. It is now predicted by the household’s neighborhood safety.
  • \(\beta_{1j}\) is the slope of life satisfaction. The equation \(\beta_{1j} = \gamma_{10}\) contains no random term, reflecting the decision to drop the random slope: the life satisfaction effect is constrained to be the same in every household.
  • \(\gamma_{00}\) is the fixed intercept: the expected self-rated health of a respondent with average life satisfaction living in a household with average perceived neighborhood safety.
  • \(\gamma_{01}\) is the fixed effect of neighborhood safety: the expected change in a household’s mean self-rated health for each one-category increase in perceived neighborhood safety, holding life satisfaction constant.
  • \(\gamma_{10}\) is the fixed effect of life satisfaction: the expected change in self-rated health for each one-category increase in life satisfaction, holding neighborhood safety constant.
  • \(u_{0j}\) is the random intercept: the part of household \(j\)’s mean health not explained by its neighborhood safety. Its variance, \(\tau_{00}\), is now the residual between-household variance. Comparing it with \(\tau_{00}\) from the previous model shows how much between-household variance neighborhood safety explains.
  • \(r_{ij}\) is the Level 1 residual, with variance \(\sigma^2\) representing the remaining within-household variance. Because neighborhood safety does not vary within households, adding it should leave \(\sigma^2\) essentially unchanged.
  • The combined model is obtained by substituting both Level 2 equations into the Level 1 equation. It contains three fixed effects (\(\gamma_{00}\), \(\gamma_{01}\), \(\gamma_{10}\)) and two random terms (\(u_{0j}\), \(r_{ij}\)). No cross-level interaction is included, since no hypothesis was made about neighborhood safety changing the strength of the life satisfaction effect..

2pt: equations correct. 1pt: equations mostly correct. 0pt: many errors in equations

2pt: explanations correct. 1pt: explanations mostly correct. 0pt: many errors in explanations

Map your hypotheses to your final model:

Hypothesis 1 (Level 1): Respondents who report higher life satisfaction will report better self-rated health.

This hypothesis maps onto \(\gamma_{10}\), the fixed effect of grand-mean-centered life satisfaction in the combined model. Because both variables are coded so that higher values mean more of the construct (more satisfied, better health), Hypothesis 1 is supported if \(\gamma_{10}\) is positive and significantly different from 0. A positive value means that, holding neighborhood safety constant, respondents with higher life satisfaction are expected to report better health. The null hypothesis is \(H_0: \gamma_{10} = 0\).

Hypothesis 2 (Level 2): Respondents living in households whose neighborhoods are perceived as safer will report better self-rated health.

This hypothesis maps onto \(\gamma_{01}\), the fixed effect of grand-mean-centered neighborhood safety in the Level 2 intercept equation. Because safety is coded so that higher values mean a safer neighborhood, Hypothesis 2 is supported if \(\gamma_{01}\) is positive and significantly different from 0. A positive value means that, holding life satisfaction constant, households in neighborhoods perceived as safer have higher average self-rated health. The null hypothesis is \(H_0: \gamma_{01} = 0\).

The remaining parameters are not tied to a hypothesis. \(\gamma_{00}\) describes the baseline level of health for a respondent at the average of both predictors, and the variance components \(\tau_{00}\) and \(\sigma^2\) describe the remaining unexplained variation between and within households. No hypothesis was made about variation in the life satisfaction slope, which was dropped from the model, or about a cross-level interaction, which is not included.

2pt: all hypotheses are mapped correctly. 1pt: mapping mostly correct. 0pt: many errors or missing

# Final model: random intercept only (random slope dropped), with the
# Level 1 predictor (life satisfaction) and the Level 2 predictor
# (neighborhood safety), both grand-mean centered
model3 <- lmer(health_r ~ satis_gmc + safety_gmc + (1 | hhid_sub),
               data = mydata, REML = TRUE)

summary(model3)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: health_r ~ satis_gmc + safety_gmc + (1 | hhid_sub)
##    Data: mydata
## 
## REML criterion at convergence: 39004.9
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -2.79715 -0.57891  0.03206  0.61791  2.93943 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  hhid_sub (Intercept) 0.1501   0.3875  
##  Residual             0.7111   0.8433  
## Number of obs: 14541, groups:  hhid_sub, 11031
## 
## Fixed effects:
##              Estimate Std. Error        df t value Pr(>|t|)    
## (Intercept) 3.070e+00  7.993e-03 1.005e+04  384.16   <2e-16 ***
## satis_gmc   3.710e-01  9.592e-03 1.447e+04   38.68   <2e-16 ***
## safety_gmc  2.217e-01  7.569e-03 1.061e+04   29.28   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##            (Intr) sts_gm
## satis_gmc   0.019       
## safety_gmc -0.034 -0.184
# 95% confidence intervals for the fixed effects
confint(model3, parm = c("(Intercept)", "satis_gmc", "safety_gmc"),
        method = "Wald")
##                 2.5 %    97.5 %
## (Intercept) 3.0547722 3.0861028
## satis_gmc   0.3521677 0.3897666
## safety_gmc  0.2068171 0.2364867
# Variance components
vc_m3 <- as.data.frame(VarCorr(model3))
tau_m3   <- vc_m3$vcov[vc_m3$grp == "hhid_sub"]   # between-household
sigma_m3 <- vc_m3$vcov[vc_m3$grp == "Residual"]   # within-household

# Variance explained, compared with both the unconditional model (model 0)
# and the life-satisfaction-only model (model 1)
data.frame(
  Component = c("Between-household (τ00)", "Within-household (σ²)"),
  Model_0   = c(tau_m0,   sigma_m0),
  Model_1   = c(tau_m1,   sigma_m1),
  Model_3   = c(tau_m3,   sigma_m3),
  vs_M0_pct = c((tau_m0 - tau_m3) / tau_m0 * 100,
                (sigma_m0 - sigma_m3) / sigma_m0 * 100),
  vs_M1_pct = c((tau_m1 - tau_m3) / tau_m1 * 100,
                (sigma_m1 - sigma_m3) / sigma_m1 * 100)
) %>%
  kbl(digits = c(0, 4, 4, 4, 1, 1),
      col.names = c("Component", "Model 0", "Model 1", "Model 3",
                    "% reduction vs. Model 0", "% reduction vs. Model 1"),
      caption = "Variance components and proportion of variance explained") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Variance components and proportion of variance explained
Component Model 0 Model 1 Model 3 % reduction vs. Model 0 % reduction vs. Model 1
Between-household (τ00) 0.2883 0.2021 0.1501 47.9 25.7
Within-household (σ²) 0.7521 0.7136 0.7111 5.5 0.3
# Likelihood ratio test: does adding neighborhood safety improve fit
# over the life-satisfaction-only model? The models differ in FIXED
# effects, so both are refit with ML for this comparison.
model1_ml <- lmer(health_r ~ satis_gmc + (1 | hhid_sub),
                  data = mydata, REML = FALSE)
model3_ml <- lmer(health_r ~ satis_gmc + safety_gmc + (1 | hhid_sub),
                  data = mydata, REML = FALSE)
anova(model1_ml, model3_ml)
## Data: mydata
## Models:
## model1_ml: health_r ~ satis_gmc + (1 | hhid_sub)
## model3_ml: health_r ~ satis_gmc + safety_gmc + (1 | hhid_sub)
##           npar   AIC   BIC logLik -2*log(L) Chisq Df Pr(>Chisq)    
## model1_ml    4 39815 39846 -19904     39807                        
## model3_ml    5 38992 39030 -19491     38982 825.8  1  < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Fit comparison across the random-intercept models (ML fits, so AIC/BIC
# are comparable across models with different fixed effects). Model 2
# (random slope) is omitted because it was dropped.
model0_ml <- lmer(health_r ~ 1 + (1 | hhid_sub), data = mydata, REML = FALSE)

data.frame(
  Model = c("Model 0: Unconditional",
            "Model 1: + Life satisfaction",
            "Model 3: + Neighborhood safety"),
  AIC = c(AIC(model0_ml), AIC(model1_ml), AIC(model3_ml)),
  BIC = c(BIC(model0_ml), BIC(model1_ml), BIC(model3_ml)),
  logLik = c(as.numeric(logLik(model0_ml)),
             as.numeric(logLik(model1_ml)),
             as.numeric(logLik(model3_ml)))
) %>%
  kbl(digits = 1, caption = "Model fit comparison (ML estimation)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Model fit comparison (ML estimation)
Model AIC BIC logLik
Model 0: Unconditional 41566.3 41589.1 -20780.2
Model 1: + Life satisfaction 39815.5 39845.8 -19903.7
Model 3: + Neighborhood safety 38991.7 39029.6 -19490.8

Summary

Report the findings (including interpretation with regard to units of analysis) for your intercept term, the fixed effect of the level 1 predictor, and the level 2 predictor.

The final model included grand-mean-centered life satisfaction at Level 1 and grand-mean-centered perceived neighborhood safety at Level 2, with a random intercept for household. It was estimated on 14,541 respondents nested within 11,031 households.

Intercept (\(\gamma_{00}\)). The intercept was 3.07 (SE = 0.008, t(10,050) = 384.16, p < .001, 95% CI [3.05, 3.09]). Because both predictors were grand-mean centered, this is the expected self-rated health of a respondent with average life satisfaction living in a household with average perceived neighborhood safety: about 3.07 on the five-point scale, or almost exactly “Good” health. The intercept is essentially unchanged from the previous models (3.07 in the unconditional model and 3.08 in the life-satisfaction-only model), as expected when predictors are centered at their means. The small shift reflects that neighborhood safety was centered at its mean across households rather than across respondents. As before, the significance test only shows that the intercept differs from 0, which is not substantively meaningful since 0 is not a possible health score.

Life satisfaction (\(\gamma_{10}\), Level 1). The fixed effect of life satisfaction was 0.371 (SE = 0.010, t(14,470) = 38.68, p < .001, 95% CI [0.352, 0.390]). Holding neighborhood safety constant, each one-category increase in life satisfaction (for example, from “somewhat satisfied” to “very satisfied”) is associated with a 0.37-point increase in self-rated health. Across the three-category range of the winsorized variable, from “not very satisfied” to “completely satisfied,” this corresponds to an expected difference of about 1.11 points — more than one full health category, such as the difference between “Fair” and “Good.” Hypothesis 1 was supported.

The life satisfaction effect decreased by about 12% after neighborhood safety was added (from 0.421 to 0.371). The negative correlation between the two fixed-effect estimates (r = −.18) indicates that the predictors themselves are positively related: respondents in households with safer-perceived neighborhoods also tend to be more satisfied with life. Part of the association between life satisfaction and health in the previous model therefore reflected differences in neighborhood safety. Because life satisfaction was grand-mean centered and 31% of its variance lies between households, its coefficient blends within- and between-household differences, and it is this between-household portion that neighborhood safety partly absorbs. Even so, life satisfaction remains a strong and independent predictor of self-rated health.

Neighborhood safety (\(\gamma_{01}\), Level 2). The fixed effect of neighborhood safety was 0.222 (SE = 0.008, t(10,610) = 29.28, p < .001, 95% CI [0.207, 0.237]). Holding life satisfaction constant, each one-category increase in a household’s perceived neighborhood safety (for example, from “good” to “very good”) is associated with a 0.22-point increase in the expected self-rated health of the respondents living there. Across the full four-category range of the scale, from “poor” to “excellent” safety, this corresponds to an expected difference of about 0.89 points in self-rated health — nearly one full health category. Because neighborhood safety is a household-level variable, this effect describes differences between households: households in neighborhoods perceived as safer have higher average self-rated health. Hypothesis 2 was supported.

Variance explained. 25.7% of between-household variance uniquely explained by safety, 47.9% explained by both predictors together, and 5.5% of within-household variance explained relative to the unconditional model. As expected for a household-level predictor, the within-household variance was essentially unchanged by adding neighborhood safety (0.714 to 0.711, a 0.3% reduction), since a variable that is identical for both members of a household cannot explain differences between them.

2pt: summary makes sense, accurate and complete. 1pt: some errors or missing information. 0pt: many errors or missing information (e.g., over half problematic)

Write-up

Choose the final model that answers your research questions and tests your hypotheses.

Write a present study section, analytic strategy (that includes the equations and explanations), and results section based on that model below (HINT: see week 4 files for example).

Present Study

Self-rated health — a person’s own global assessment of whether their health is excellent, very good, good, fair, or poor — is one of the most widely used health measures in research on aging, and it is known to predict later morbidity and mortality. Because it reflects both physical condition and how people perceive their lives, it is plausibly shaped by factors at more than one level. At the individual level, a person’s overall sense of well-being may color how they evaluate their own health. At the household level, the residential environment people share — including how safe their neighborhood feels — may affect health through stress, opportunities for physical activity, and social engagement.

These two influences are measured at different levels by design. Life satisfaction is reported by each respondent about themselves and can differ between two people living in the same household. Perceived neighborhood safety describes where a household lives, is reported once per household, and is the same for everyone in it. Because respondents who share a household are likely to resemble each other in their health, and because one predictor exists only at the household level, a multilevel model is needed to estimate both effects correctly.

The present study asks: Do perceived neighborhood safety (a household-level characteristic) and life satisfaction (an individual-level characteristic) predict self-rated health among older adults in the United States? Two hypotheses were tested:

  • Hypothesis 1 (Level 1): Respondents who report higher life satisfaction will report better self-rated health.
  • Hypothesis 2 (Level 2): Respondents living in households whose neighborhoods are perceived as safer will report better self-rated health.

Data come from the 2022 Core (Final, Version 2.0) public release of the Health and Retirement Study (HRS), a nationally representative longitudinal study of Americans over age 50 conducted by the University of Michigan’s Institute for Social Research. Three files were merged: Section B (Demographics; H22B_R) and Section C (Physical Health; H22C_R), both with one record per respondent, and Section H (Housing; H22H_H), with one record per household. The analytic sample consisted of 14,541 respondents nested within 11,031 households, an average of about 1.32 respondents per household.

Analytic Strategy

Measures. The outcome, self-rated health (SC001), asked respondents whether their health was excellent, very good, good, fair, or poor. The Level 1 predictor, life satisfaction (SB000), asked respondents how satisfied they were with their life as a whole, from completely satisfied to not at all satisfied. The Level 2 predictor, perceived neighborhood safety (SH150), asked the household’s financial/family respondent to rate the safety of their neighborhood from excellent to poor; this single answer applies to every respondent in the household. All three items were originally coded 1 (best) to 5 (worst) and were reverse-coded (6 minus the original score) so that higher values indicate better health, greater satisfaction, and a safer neighborhood. All three were treated as approximately continuous.

Data preparation. HRS missing-data codes (−8 = web non-response, 8 = don’t know, 9 = refused) were set to missing, and respondents missing any of the three variables were removed listwise. The two respondent files were merged by household and person identifiers (HHID, PN), and the housing file was merged by household and sub-household identifiers (HHID, SSUBHH). The cluster identifier was created by combining HHID and SSUBHH, because HHID alone groups together households that split after a divorce or separation, even though their members no longer live together.

Outliers were screened using standardized scores (|z| > 3.29). No cases were flagged for self-rated health or neighborhood safety. For life satisfaction, the lowest category (“not at all satisfied”) fell at z = −3.34, so all 164 respondents in that category were flagged. These were legitimate responses, so rather than deleting them, they were winsorized to the nearest non-flagged value (recoded from 1 to 2); after winsorizing, no cases exceeded the cutoff. No transformations were applied, because all skewness and kurtosis values were within conventional limits (|skew| ≤ 0.56, |kurtosis| ≤ 0.56).

Centering. Both predictors were grand-mean centered so that the intercept would represent a meaningful value, since 0 is not a possible score on either scale. Life satisfaction was centered at its mean across respondents. Grand-mean centering was chosen over group-mean centering because the hypothesis concerns differences between people in general rather than differences relative to one’s own household partner, and because most households contain only one respondent, for whom a group-mean-centered score would always be 0. Neighborhood safety was centered at its mean across households, so that two-respondent households were not counted twice. The outcome was not centered.

Estimation. Two-level linear mixed models were estimated in R using the lmer() function from the lme4 and lmerTest packages, with restricted maximum likelihood (REML) estimation and Satterthwaite degrees of freedom for tests of fixed effects. Models that differed in their fixed effects were compared with likelihood ratio tests after refitting with maximum likelihood (ML), since REML likelihoods are not comparable across different fixed effects. Models that differed only in their random effects were compared using their REML fits.

Model building. Models were built in four steps. First, an unconditional (intercept-only) model divided the variance in self-rated health into between-household and within-household parts, and the intraclass correlation (ICC) was calculated to assess the degree of clustering. Second, life satisfaction was added as a fixed effect. Third, a random slope for life satisfaction was tested to see whether its effect varied across households. Fourth, based on the result of that test, neighborhood safety was added to the Level 2 intercept equation.

The random slope was not retained. With two random effects per household, the model required 22,062 random effects but had only 14,541 observations, so lme4 would not fit it under its default settings, because the household-level slope variance could not be separately identified. When the model was estimated with this check overridden, it fit better, \(\chi^2\)(2) = 54.81, p < .001. However, with most households contributing only one respondent, a random slope cannot be distinguished from self-rated health simply being more variable at the extremes of life satisfaction, and the estimates implied that about 7% of households had a negative association, which is not substantively plausible. The fixed effect of life satisfaction was nearly identical with and without the random slope (0.427 vs. 0.421). A random-intercept model was therefore used for the final model.

Final model. The final model was:

Level 1 (respondent):

\[ \text{Health}_{ij} = \beta_{0j} + \beta_{1j}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + r_{ij}, \qquad r_{ij} \sim N(0, \sigma^2) \]

Level 2 (household):

\[ \beta_{0j} = \gamma_{00} + \gamma_{01}(\text{Safety}_{j} - \overline{\text{Safety}}_{.}) + u_{0j}, \qquad u_{0j} \sim N(0, \tau_{00}) \]

\[ \beta_{1j} = \gamma_{10} \]

Combined:

\[ \text{Health}_{ij} = \gamma_{00} + \gamma_{01}(\text{Safety}_{j} - \overline{\text{Safety}}_{.}) + \gamma_{10}(\text{LifeSat}_{ij} - \overline{\text{LifeSat}}_{..}) + u_{0j} + r_{ij} \]

Here, \(\text{Health}_{ij}\) is the self-rated health of respondent \(i\) in household \(j\). \(\gamma_{00}\) is the expected self-rated health of a respondent with average life satisfaction in a household with average neighborhood safety. \(\gamma_{10}\) is the fixed effect of life satisfaction, constrained to be the same in every household. \(\gamma_{01}\) is the fixed effect of neighborhood safety; because safety has only a \(j\) subscript — it varies between households but not within them — it predicts the household intercept rather than appearing in the Level 1 equation. \(u_{0j}\) is the part of household \(j\)’s mean health not explained by neighborhood safety, with variance \(\tau_{00}\) (residual between-household variance), and \(r_{ij}\) is the respondent’s deviation from their household’s expected value, with variance \(\sigma^2\) (within-household variance). Hypothesis 1 is tested by \(\gamma_{10}\) and Hypothesis 2 by \(\gamma_{01}\); each is supported if the coefficient is positive and significantly different from 0.

Results

Descriptive statistics. Self-rated health averaged 3.08 (SD = 1.02), close to “good,” and was roughly symmetric (skew = −0.09, kurtosis = −0.56). Life satisfaction averaged 3.84 (SD = 0.85) before winsorizing and was mildly negatively skewed (skew = −0.47, kurtosis = 0.22), reflecting that most respondents reported being very or completely satisfied. Neighborhood safety averaged 3.78 (SD = 1.07) and was also mildly negatively skewed (skew = −0.56, kurtosis = −0.49), as most respondents described their neighborhood as safe.

Degree of nesting. In the unconditional model, the grand mean of self-rated health was \(\gamma_{00}\) = 3.07 (SE = 0.009, 95% CI [3.05, 3.09]). The between-household variance was \(\tau_{00}\) = 0.288 and the within-household variance was \(\sigma^2\) = 0.752, giving an ICC of .28: about 27.7% of the variance in self-rated health was between households and 72.3% was within households. For the predictors, 31.2% of the variance in life satisfaction was between households (ICC = .31), confirming that it varies meaningfully within households and belongs at Level 1, while 100% of the variance in neighborhood safety was between households (ICC = 1.00), confirming that it is a purely household-level variable.

Life satisfaction only. Adding life satisfaction produced a fixed effect of \(\gamma_{10}\) = 0.421 (SE = 0.010, t(14,490) = 43.31, p < .001) and significantly improved fit over the unconditional model, \(\chi^2\)(1) = 1752.8, p < .001. It reduced the between-household variance by 29.9% (to 0.202) and the within-household variance by 5.1% (to 0.714).

Final model. Results for the final model are shown in Table 1. The intercept was \(\gamma_{00}\) = 3.07 (SE = 0.008, t(10,050) = 384.16, p < .001, 95% CI [3.05, 3.09]): a respondent with average life satisfaction in a household with average neighborhood safety is expected to rate their health as almost exactly “good.”

Consistent with Hypothesis 1, life satisfaction positively predicted self-rated health, \(\gamma_{10}\) = 0.371 (SE = 0.010, t(14,470) = 38.68, p < .001, 95% CI [0.352, 0.390]). Holding neighborhood safety constant, each one-category increase in life satisfaction was associated with a 0.37-point increase in self-rated health. Across the full range of the winsorized scale (from “not very satisfied” to “completely satisfied”), this amounts to an expected difference of about 1.11 points — more than one full health category. This effect was about 12% smaller than in the model without neighborhood safety (0.421), indicating that respondents in safer-perceived neighborhoods also tend to be more satisfied, so part of the earlier association reflected neighborhood differences.

Consistent with Hypothesis 2, neighborhood safety positively predicted self-rated health, \(\gamma_{01}\) = 0.222 (SE = 0.008, t(10,610) = 29.28, p < .001, 95% CI [0.207, 0.237]). Holding life satisfaction constant, each one-category increase in a household’s perceived neighborhood safety was associated with a 0.22-point increase in the expected self-rated health of its residents. Across the full range of the scale (from “poor” to “excellent”), this amounts to an expected difference of about 0.89 points, nearly one full health category.

Adding neighborhood safety significantly improved fit over the life-satisfaction-only model, \(\chi^2\)(1) = 825.8, p < .001. It reduced the between-household variance by 25.7% (from 0.202 to 0.150), while the within-household variance was essentially unchanged (0.714 to 0.711, a 0.3% reduction), as expected for a variable that is the same for everyone in a household. Compared with the unconditional model, the two predictors together explained 47.9% of the between-household variance and 5.5% of the within-household variance. The residual ICC was .17, meaning about 17% of the remaining unexplained variance lies between households. Scaled residuals were roughly symmetric (−2.80 to 2.94), with none beyond ±3.

Table 1. Multilevel models predicting self-rated health (N = 14,541 respondents in 11,031 households)

Model 0: Unconditional Model 1: + Life satisfaction Model 3: + Neighborhood safety
Fixed effects Estimate (SE) Estimate (SE) Estimate (SE)
Intercept (\(\gamma_{00}\)) 3.069 (0.009)*** 3.077 (0.008)*** 3.070 (0.008)***
Life satisfaction (\(\gamma_{10}\)) 0.421 (0.010)*** 0.371 (0.010)***
Neighborhood safety (\(\gamma_{01}\)) 0.222 (0.008)***
Random effects
Between-household variance (\(\tau_{00}\)) 0.288 0.202 0.150
Within-household variance (\(\sigma^2\)) 0.752 0.714 0.711
ICC .28 .22 .17

Note. Both predictors are grand-mean centered. All variables are coded so that higher values indicate better health, greater life satisfaction, and a safer neighborhood. The random slope model (Model 2) is not shown because the random slope was dropped. *** p < .001.

Summary and limitations. Both hypotheses were supported. Older adults who were more satisfied with their lives rated their health more positively, and households in neighborhoods perceived as safer had better average self-rated health, with each association holding when the other was controlled. Several limitations should be noted. First, the data are cross-sectional, so these are associations, not causal effects; for example, poorer health may lower life satisfaction rather than the reverse. Second, all three measures are single-item self-reports, and the association between life satisfaction and self-rated health may partly reflect a general tendency to rate things positively or negatively. Third, neighborhood safety was reported by one household member and applied to all members; for that respondent, it is also a self-report from the same person who rated their own health. Fourth, households are small (about 1.32 respondents on average), which prevented testing whether the life satisfaction effect differs across households. Finally, the analysis did not apply the HRS survey weights, so the estimates describe this sample rather than the U.S. population of older adults.

Graded on a scale of 1-10: 10pt: TA could replicate the findings based on the write-up, clear description, accurate. 5pt: Parts missing, if this were a paper there might be minor revisions requested to understand the analysis. 0pt: Many errors/very unclear/incorrect/missing.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMSINCmF1dGhvcjogIlBIVSBLSEFORyBCVUkiDQpkYXRlOiAiRHVlIDIwMjYtMDktMjEiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiB0cnVlDQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQ0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogc2VudGVuY2UNCi0tLQ0KDQooTG9hZCBwYWNrYWdlcykNCg0KW0FsbCBvZiB0aGUgcHJvbXB0cyB3aWxsIGJlIGluIHB1cnBsZSB0ZXh0LiAoT3IgYmx1ZSBpZiBpdHMgYSBoZWFkZXIpXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpbQWxsIG9mIHRoZSBncmFkaW5nIHJ1YnJpY3Mgd2lsbCBiZSBpbiByZWQgdGV4dC5de3N0eWxlPSJjb2xvcjogcmVkOyJ9DQoNCllvdXIgYW5zd2VycyB3aWxsIGJlIGluIGJsYWNrIHRleHQuDQpIaW50OiByZXBsYWNlIGFsbCB0ZXh0IHRoYXQgc2F5cyBZb3VyIFRleHQgSGVyZS4NCg0KYGBge3IsIGluY2x1ZGU9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQoNCiNmb3IgY2FsbGluZyBpbiBkYXRhDQpsaWJyYXJ5KGhhdmVuKQ0KDQojZm9yIHByZXR0eSBvdXRwdXQgYW5kIGRhdGEgdml6DQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHZpcmlkaXMpDQoNCiNmb3Igc3RhdGlzdGljcyBhbmQgbW9kZWxzDQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShwbHlyKQ0KbGlicmFyeShsbWVyVGVzdCkNCg0KI2ZvciBjZW50ZXJpbmcNCmxpYnJhcnkoZHBseXIpDQoNCmBgYA0KDQojIERhdGEgRGVzY3JpcHRpb24NCg0KVGhlIGRhdGEgZm9yIHRoaXMgYXNzaWdubWVudCBjb21lIGZyb20gdGhlIEhlYWx0aCBhbmQgUmV0aXJlbWVudCBTdHVkeSAoSFJTKSwgMjAyMiBDb3JlIChGaW5hbCwgVmVyc2lvbiAyLjApLiBUaGlzIGFzc2lnbm1lbnQgZHJhd3Mgb24gdGhyZWUgZGF0YSBmaWxlczoNCg0KLSBIMjJCX1IgKFNlY3Rpb24gQjogRGVtb2dyYXBoaWNzLCByZXNwb25kZW50IGxldmVsKQ0KLSBIMjJDX1IgKFNlY3Rpb24gQzogUGh5c2ljYWwgSGVhbHRoLCByZXNwb25kZW50IGxldmVsKQ0KLSBIMjJIX0ggKFNlY3Rpb24gSDogSG91c2luZywgaG91c2Vob2xkIGxldmVsKQ0KDQojIFJlc2VhcmNoIFF1ZXN0aW9uDQoNCltSZWNvcmQgeW91ciBvdmVyYWxsIHJlc2VhcmNoIHF1ZXN0aW9uIHRoYXQgeW91IHdpbGwgdGVzdCBpbiB0aGlzIGFzc2lnbm1lbnQgKGhpbnQ6IGEgcmVzZWFyY2ggcXVlc3Rpb24gTVVTVCBlbmQgd2l0aCBhIHF1ZXN0aW9uIG1hcmsuKV17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KRG8gcGVyY2VpdmVkIG5laWdoYm9yaG9vZCBzYWZldHkgKGEgaG91c2Vob2xkLWxldmVsIGNoYXJhY3RlcmlzdGljKSBhbmQgbGlmZSBzYXRpc2ZhY3Rpb24gKGFuIGluZGl2aWR1YWwtbGV2ZWwgY2hhcmFjdGVyaXN0aWMpIHByZWRpY3Qgc2VsZi1yYXRlZCBoZWFsdGggYW1vbmcgb2xkZXIgYWR1bHRzIGluIHRoZSBVbml0ZWQgU3RhdGVzPw0KDQojIyBIeXBvdGhlc2VzDQoNCltQcm92aWRlIG9uZSBoeXBvdGhlc2lzIGZvciBhIGxldmVsIDEgdmFyaWFibGUgYW5kIG9uZSBmb3IgYSBsZXZlbCAyIHZhcmlhYmxlOl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KWypMZXZlbCAxKl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KUmVzcG9uZGVudHMgd2hvIHJlcG9ydCBoaWdoZXIgbGlmZSBzYXRpc2ZhY3Rpb24gd2lsbCByZXBvcnQgYmV0dGVyIHNlbGYtcmF0ZWQgaGVhbHRoLCBjb250cm9sbGluZyBmb3IgbmVpZ2hib3Job29kIHNhZmV0eS4NCg0KWypMZXZlbCAyKl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KUmVzcG9uZGVudHMgbGl2aW5nIGluIGhvdXNlaG9sZHMgd2hvc2UgbmVpZ2hib3Job29kcyBhcmUgcGVyY2VpdmVkIGFzIHNhZmVyIHdpbGwgcmVwb3J0IGJldHRlciBzZWxmLXJhdGVkIGhlYWx0aCB0aGFuIHJlc3BvbmRlbnRzIGxpdmluZyBpbiBob3VzZWhvbGRzIHdob3NlIG5laWdoYm9yaG9vZHMgYXJlIHBlcmNlaXZlZCBhcyBsZXNzIHNhZmUuDQoNClsycHQ6IHByb3ZpZGVkIFJRIGFuZCBoeXBvdGhlc2VzLiAxcHQ6IHNvbWUgZXJyb3JzLiAwcHQ6IGFsbCBtaXNzaW5nL2luY29ycmVjdF17c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KIyMgQW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zIGFib3V0IHlvdXIgZGF0YQ0KDQpbKipRdWVzdGlvbnMgYWJvdXQgdGhlIGRhdGE6Kipde3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCltJcyB0aGlzIGNsdXN0ZXJlZCBkYXRhP117c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KWWVzLiBSZXNwb25kZW50cyBpbiB0aGUgSFJTIGFyZSBzYW1wbGVkIHdpdGhpbiBob3VzZWhvbGRzLiBSZXNwb25zZSdzIGZyb20gcGVvcGxlIGxpdmluZyBpbiB0aGUgc2FtZSBob3VzZWhvbGQgYXJlIG5vdCBpbmRlcGVuZGVudCBvZiBvbmUgYW5vdGhlci4NCg0KW1doYXQgaXMgdGhlIG5lc3Rpbmcgc3RydWN0dXJlP117c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KUmVzcG9uZGVudHMgKExldmVsIDEpIGFyZSBuZXN0ZWQgd2l0aGluIGhvdXNlaG9sZHMgKExldmVsIDIpLg0KDQpbSW5kaXZpZHVhbC1sZXZlbCBpZGVudGlmaWVyP117c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KUE4gKFJlc3BvbmRlbnQgUGVyc29uIElkZW50aWZpY2F0aW9uIE51bWJlcikuDQoNCltDbHVzdGVyIGlkZW50aWZpZXI/XXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpISElEICsgU1NVQkhIIHRvZ2V0aGVyLiBXaGVuIGEgY291cGxlIGRpdm9yY2VzIG9yIHNlcGFyYXRlcywgdGhlIGhvdXNlaG9sZHMgcmV0YWluIHRoZSBzYW1lIEhISUQgYW5kIGFyZSBkaXN0aW5ndWlzaGVkIG9ubHkgYnkgU1NVQkhILiBDbHVzdGVyaW5nIG9uIEhISUQgYWxvbmUgd291bGQgaW5jb3JyZWN0bHkgZ3JvdXAgZXgtc3BvdXNlcyB3aG8gbm8gbG9uZ2VyIHNoYXJlIGEgcmVzaWRlbmNlLCBzbyBhIGNvbmNhdGVuYXRlZCBISElEX1NTVUJISCB2YXJpYWJsZSBpcyBjb25zdHJ1Y3RlZCBhbmQgdXNlZCBhcyB0aGUgY2x1c3RlciBpZGVudGlmaWVyLg0KDQpbTGV2ZWwgMSB2YXJpYWJsZXM/XXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQotIFNlbGYtcmF0ZWQgaGVhbHRoIChTQzAwMSkNCi0gTGlmZSBzYXRpc2ZhY3Rpb24gKFNCMDAwKQ0KDQpbTGV2ZWwgMiB2YXJpYWJsZXM/XXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQotIFBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5IChTSDE1MCkNCg0KWzJwdDogYWxsIGNvcnJlY3QgYW5zd2Vycy4gMXB0OiBcPiA1MCUgY29ycmVjdCBhbnN3ZXJzLiAwcHQ6IFw8IDUwJSBjb3JyZWN0IGFuc3dlcnNde3N0eWxlPSJjb2xvcjogcmVkOyJ9DQoNCiMjIFZhcmlhYmxlIERlc2NyaXB0aW9ucw0KDQpbUGxlYXNlIHByb3ZpZGUgYnJpZWYgdmFyaWFibGUgZGVzY3JpcHRpb25zIG9mIGVhY2ggb2YgeW91ciB2YXJpYWJsZXMuIEF0IGEgbWluaW11bSwgaW5jbHVkZSB0aGUgY29uc3RydWN0IG5hbWUsIGEgZGVzY3JpcHRpb24sIHRoZSB0eXBlIG9mIHZhcmlhYmxlIChub21pbmFsL2NhdGVnb3JpY2FsLCBvcmRpbmFsL29yZGVyZWQgY2F0ZWdvcmljYWwsIGNvbnRpbnVvdXMsIGV0Yy4pLCBhbmQgdGhlIGxldmVsIGF0IHdoaWNoIGl0IGlzIG1lYXN1cmVkLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KMS4gU2VsZi1yYXRlZCBoZWFsdGggKFNDMDAxKQ0KDQotIENvbnN0cnVjdDogR2xvYmFsIHN1YmplY3RpdmUgaGVhbHRoLg0KLSBEZXNjcmlwdGlvbjogUmVzcG9uZGVudHMgd2VyZSBhc2tlZCwgIldvdWxkIHlvdSBzYXkgeW91ciBoZWFsdGggaXMgZXhjZWxsZW50LCB2ZXJ5IGdvb2QsIGdvb2QsIGZhaXIsIG9yIHBvb3I/IiBSZXNwb25zZXMgYXJlIGNvZGVkIDEgPSBFeGNlbGxlbnQsIDIgPSBWZXJ5IGdvb2QsIDMgPSBHb29kLCA0ID0gRmFpciwgNSA9IFBvb3IuIEZvciB0aGlzIGFuYWx5c2lzIHRoZSB2YXJpYWJsZSBpcyByZXZlcnNlLWNvZGVkIGFzIGBoZWFsdGhfciA9IDYgLSBTQzAwMWAgc28gdGhhdCBoaWdoZXIgc2NvcmVzIGluZGljYXRlIGJldHRlciBoZWFsdGguDQotIFR5cGU6IE9yZGluYWwgKG9yZGVyZWQgY2F0ZWdvcmljYWwpLCBmaXZlIHBvaW50cy4gRm9sbG93aW5nIHN0YW5kYXJkIHByYWN0aWNlIGluIHRoZSBhZ2luZyBhbmQgaGVhbHRoIGxpdGVyYXR1cmUsIGl0IGlzIHRyZWF0ZWQgYXMgYXBwcm94aW1hdGVseSBjb250aW51b3VzIHNvIHRoYXQgaXQgY2FuIHNlcnZlIGFzIHRoZSBvdXRjb21lIGluIGEgbGluZWFyIG11bHRpbGV2ZWwgbW9kZWwuIA0KLSBMZXZlbDogTGV2ZWwgMSAocmVzcG9uZGVudCkNCg0KMi4gTGlmZSBzYXRpc2ZhY3Rpb24gKFNCMDAwKQ0KDQotIENvbnN0cnVjdDogR2xvYmFsIHN1YmplY3RpdmUgd2VsbC1iZWluZy4NCi0gRGVzY3JpcHRpb246IFJlc3BvbmRlbnRzIHdlcmUgYXNrZWQsICJOb3csIHBsZWFzZSB0aGluayBhYm91dCB5b3VyIGxpZmUtYXMtYS13aG9sZS4gSG93IHNhdGlzZmllZCBhcmUgeW91IHdpdGggaXQ/IEFyZSB5b3UgY29tcGxldGVseSBzYXRpc2ZpZWQsIHZlcnkgc2F0aXNmaWVkLCBzb21ld2hhdCBzYXRpc2ZpZWQsIG5vdCB2ZXJ5IHNhdGlzZmllZCwgb3Igbm90IGF0IGFsbCBzYXRpc2ZpZWQ/IiBSZXNwb25zZXMgYXJlIGNvZGVkIDEgPSBDb21wbGV0ZWx5IHNhdGlzZmllZCB0aHJvdWdoIDUgPSBOb3QgYXQgYWxsIHNhdGlzZmllZC4gVGhlIHZhcmlhYmxlIGlzIHJldmVyc2UtY29kZWQgYXMgYHNhdGlzX3IgPSA2IC0gU0IwMDBgIHNvIHRoYXQgaGlnaGVyIHNjb3JlcyBpbmRpY2F0ZSBncmVhdGVyIHNhdGlzZmFjdGlvbi4NCi0gVHlwZTogT3JkaW5hbCAob3JkZXJlZCBjYXRlZ29yaWNhbCksIGZpdmUgcG9pbnRzOyB0cmVhdGVkIGFzIGFwcHJveGltYXRlbHkgY29udGludW91cy4NCi0gTGV2ZWw6IExldmVsIDEgKHJlc3BvbmRlbnQpLg0KDQozLiBQZXJjZWl2ZWQgbmVpZ2hib3Job29kIHNhZmV0eSAoU0gxNTApIA0KDQotIENvbnN0cnVjdDogSG91c2Vob2xkIG5laWdoYm9yaG9vZCBjb250ZXh0Lg0KLSBEZXNjcmlwdGlvbjogVGhlIHJlc3BvbmRlbnQgd2FzIGFza2VkLCAiV291bGQgeW91IHNheSB0aGUgc2FmZXR5IG9mIHlvdXIgbmVpZ2hib3Job29kIGlzIGV4Y2VsbGVudCwgdmVyeSBnb29kLCBnb29kLCBmYWlyIG9yIHBvb3I/IiBSZXNwb25zZXMgYXJlIGNvZGVkIDEgPSBFeGNlbGxlbnQgdGhyb3VnaCA1ID0gUG9vci4gVGhlIHZhcmlhYmxlIGlzIHJldmVyc2UtY29kZWQgYXMgYHNhZmV0eV9yID0gNiAtIFNIMTUwYCBzbyB0aGF0IGhpZ2hlciBzY29yZXMgaW5kaWNhdGUgYSBzYWZlciBwZXJjZWl2ZWQgbmVpZ2hib3Job29kLg0KLSBUeXBlOiBPcmRpbmFsIChvcmRlcmVkIGNhdGVnb3JpY2FsKSwgZml2ZSBwb2ludHM7IHRyZWF0ZWQgYXMgYXBwcm94aW1hdGVseSBjb250aW51b3VzLg0KLSBMZXZlbDogTGV2ZWwgMiAoaG91c2Vob2xkKS4NCg0KWzJwdDogYWRlcXVhdGUgZGVzY3JpcHRpb24gb2YgZXZlcnkgdmFyaWFibGUuIDFwdDogc29tZSB2YXJpYWJsZXMgYW5kL29yIGRldGFpbHMgbWlzc2luZy4gMHB0OiBzaWduaWZpY2FudCBwYXJ0cyBtaXNzaW5nXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQojIENhbGwgaW4gRGF0YQ0KDQpgYGB7cn0NCg0KI1JlYWQgaW4gdGhlIGRhdGENCg0KZGVtb2cgIDwtIHJlYWRfZHRhKCJIMjJCX1IuZHRhIikgICANCmhlYWx0aCA8LSByZWFkX2R0YSgiSDIyQ19SLmR0YSIpICAgDQpob3VzZSAgPC0gcmVhZF9kdGEoIkgyMkhfSC5kdGEiKQ0KDQpkZW1vZyAgPC0gaGF2ZW46OnphcF9sYWJlbHMoZGVtb2cpDQpoZWFsdGggPC0gaGF2ZW46OnphcF9sYWJlbHMoaGVhbHRoKQ0KaG91c2UgIDwtIGhhdmVuOjp6YXBfbGFiZWxzKGhvdXNlKQ0KDQojQ3JlYXRlIGEgc21hbGxlciBkYXRhc2V0IHdpdGggb25seSB0aGUgZmV3IHZhcmlhYmxlcyBkZXNjcmliZWQgYWJvdmUNCg0KZGVtb2dfc20gIDwtIGRlbW9nICAlPiUgZHBseXI6OnNlbGVjdChISElELCBQTiwgU1NVQkhILCBTQjAwMCkNCmhlYWx0aF9zbSA8LSBoZWFsdGggJT4lIGRwbHlyOjpzZWxlY3QoSEhJRCwgUE4sIFNDMDAxKQ0KaG91c2Vfc20gIDwtIGhvdXNlICAlPiUgZHBseXI6OnNlbGVjdChISElELCBTU1VCSEgsIFNIMTUwKQ0KDQojIG1lcmdlIHRoZSB0d28gcmVzcG9uZGVudC1sZXZlbCBmaWxlcyBvbiBISElEICsgUE4NCnJlc3AgPC0gbWVyZ2UoZGVtb2dfc20sIGhlYWx0aF9zbSwgYnkgPSBjKCJISElEIiwgIlBOIikpDQoNCiMgbWVyZ2UgdGhlIGhvdXNlaG9sZC1sZXZlbCBmaWxlIG9uIEhISUQgKyBTU1VCSEgNCmRhdCA8LSBtZXJnZShyZXNwLCBob3VzZV9zbSwgYnkgPSBjKCJISElEIiwgIlNTVUJISCIpKQ0KDQojIHJlY29kZSBIUlMgbWlzc2luZy1kYXRhIGNvZGVzIHRvIE5BDQojIC04ID0gd2ViIG5vbi1yZXNwb25zZSwgOCA9IERvbid0IEtub3csIDkgPSBSZWZ1c2VkDQpocnNfbmEgPC0gZnVuY3Rpb24oeCkgaWZlbHNlKHggJWluJSBjKC04LCA4LCA5KSwgTkEsIHgpDQoNCmRhdCA8LSBkYXQgJT4lDQogIG11dGF0ZShhY3Jvc3MoYyhTQjAwMCwgU0MwMDEsIFNIMTUwKSwgaHJzX25hKSkNCg0KIyByZXZlcnNlLWNvZGUgYWxsIHRocmVlIHNvIHRoYXQgSElHSEVSID0gQkVUVEVSIG9uIGV2ZXJ5IHZhcmlhYmxlDQpkYXQgPC0gZGF0ICU+JQ0KICBtdXRhdGUoDQogICAgaGVhbHRoX3IgPSA2IC0gU0MwMDEsICAgIyA1ID0gRXhjZWxsZW50IGhlYWx0aCAuLi4gMSA9IFBvb3IgaGVhbHRoDQogICAgc2F0aXNfciAgPSA2IC0gU0IwMDAsICAgIyA1ID0gQ29tcGxldGVseSBzYXRpc2ZpZWQgLi4uIDEgPSBOb3QgYXQgYWxsDQogICAgc2FmZXR5X3IgPSA2IC0gU0gxNTAgICAgIyA1ID0gRXhjZWxsZW50IHNhZmV0eSAuLi4gMSA9IFBvb3Igc2FmZXR5DQogICkNCg0KIyBidWlsZCB0aGUgTGV2ZWwgMiBjbHVzdGVyIGlkZW50aWZpZXIgKDIwMjIgaG91c2Vob2xkLCBub3Qgb3JpZ2luYWwgaG91c2Vob2xkKQ0KZGF0IDwtIGRhdCAlPiUNCiAgbXV0YXRlKGhoaWRfc3ViID0gcGFzdGUwKEhISUQsICJfIiwgU1NVQkhIKSkNCg0KIyBsaXN0d2lzZS1kZWxldGUgY2FzZXMgbWlzc2luZw0KbXlkYXRhIDwtIGRhdCAlPiUNCiAgZHBseXI6OnNlbGVjdChoaGlkX3N1YiwgSEhJRCwgU1NVQkhILCBQTiwgaGVhbHRoX3IsIHNhdGlzX3IsIHNhZmV0eV9yKSAlPiUNCiAgZmlsdGVyKGNvbXBsZXRlLmNhc2VzKC4pKQ0KDQojUHJpbnQgdGhlIGZpcnN0IGZldyBsaW5lcyBvZiB5b3VyIHNtYWxsZXIgZGF0YXNldCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpoZWFkKG15ZGF0YSkgJT4lDQogIGtibChjYXB0aW9uID0gIkZpcnN0IHNpeCByb3dzIG9mIHRoZSBhbmFseXRpYyBkYXRhc2V0IikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkNCg0Kbl9wZW9wbGUgICA8LSBucm93KG15ZGF0YSkNCm5fY2x1c3RlcnMgPC0gbGVuZ3RoKHVuaXF1ZShteWRhdGEkaGhpZF9zdWIpKQ0KY2x1c19zaXplcyA8LSB0YWJsZSh0YWJsZShteWRhdGEkaGhpZF9zdWIpKQ0KY2F0KCJSZXNwb25kZW50cyAoTGV2ZWwgMSk6Iiwgbl9wZW9wbGUsICJcbiIpDQpjYXQoIkhvdXNlaG9sZHMgKExldmVsIDIpOiIsIG5fY2x1c3RlcnMsICJcbiIpDQpjYXQoIkF2ZXJhZ2UgY2x1c3RlciBzaXplOiIsIHJvdW5kKG5fcGVvcGxlIC8gbl9jbHVzdGVycywgMiksICJcblxuIikNCmNhdCgiRGlzdHJpYnV0aW9uIG9mIGNsdXN0ZXIgc2l6ZXM6XG4iKQ0KcHJpbnQoY2x1c19zaXplcykNCg0KDQpgYGANCg0KWzJwdDogYWxsIGJlbG93IGNvbXBvbmVudHMgb2YgY29kZSBwcmVzZW50IDFwdDogc29tZSBwYXJ0cyBtaXNzaW5nIDBwdDogc2lnbmlmaWNhbnQgcGFydHMgbWlzc2luZy9hbGwgbWlzc2luZ117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KIyBEYXRhIFByZXAgYW5kIERlc2NyaXB0aXZlcw0KDQojIyBEaXN0cmlidXRpb25zIChmdWxsIHNhbXBsZSk6DQoNCltbQmUgc3VyZSB0byBpbmNsdWRlIGFsbCB2YXJpYWJsZXMgb2YgaW50ZXJlc3RdXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCg0KI1ZpZXcgZGVzY3JpcHRpdmUgc3RhdGlzdGljcw0KDQpkZXNjIDwtIHBzeWNoOjpkZXNjcmliZShteWRhdGFbLCBjKCJoZWFsdGhfciIsICJzYXRpc19yIiwgInNhZmV0eV9yIildKQ0KDQpkZXNjICU+JQ0KICBrYmwoZGlnaXRzID0gMiwNCiAgICAgIGNhcHRpb24gPSAiRGVzY3JpcHRpdmUgc3RhdGlzdGljcyBmb3IgYWxsIGFuYWx5c2lzIHZhcmlhYmxlcyAocmV2ZXJzZS1jb2RlZCkiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQojVmlzdWFsaXphdGlvbnMNCg0KZ2dwbG90KG15ZGF0YSwgYWVzKHggPSBmYWN0b3IoaGVhbHRoX3IpLCBmaWxsID0gZmFjdG9yKGhlYWx0aF9yKSkpICsNCiAgZ2VvbV9iYXIoKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJEIiwgZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCIxXG5Qb29yIiwgIjJcbkZhaXIiLCAiM1xuR29vZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNFxuVmVyeSBnb29kIiwgIjVcbkV4Y2VsbGVudCIpKSArDQogIGxhYnModGl0bGUgPSAiU2VsZi1yYXRlZCBoZWFsdGggKG91dGNvbWUsIExldmVsIDEpIiwNCiAgICAgICB4ID0gIlNlbGYtcmF0ZWQgaGVhbHRoIChyZXZlcnNlLWNvZGVkKSIsIHkgPSAiTnVtYmVyIG9mIHJlc3BvbmRlbnRzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KZ2dwbG90KG15ZGF0YSwgYWVzKHggPSBmYWN0b3Ioc2F0aXNfciksIGZpbGwgPSBmYWN0b3Ioc2F0aXNfcikpKSArDQogIGdlb21fYmFyKCkgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAiQyIsIGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiMVxuTm90IGF0IGFsbCIsICIyXG5Ob3QgdmVyeSIsICIzXG5Tb21ld2hhdCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNFxuVmVyeSIsICI1XG5Db21wbGV0ZWx5IikpICsNCiAgbGFicyh0aXRsZSA9ICJMaWZlIHNhdGlzZmFjdGlvbiAocHJlZGljdG9yLCBMZXZlbCAxKSIsDQogICAgICAgeCA9ICJMaWZlIHNhdGlzZmFjdGlvbiAocmV2ZXJzZS1jb2RlZCkiLCB5ID0gIk51bWJlciBvZiByZXNwb25kZW50cyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmhoX2xldmVsIDwtIG15ZGF0YSAlPiUNCiAgZ3JvdXBfYnkoaGhpZF9zdWIpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXNlKHNhZmV0eV9yID0gZmlyc3Qoc2FmZXR5X3IpLCAuZ3JvdXBzID0gImRyb3AiKQ0KDQpnZ3Bsb3QoaGhfbGV2ZWwsIGFlcyh4ID0gZmFjdG9yKHNhZmV0eV9yKSwgZmlsbCA9IGZhY3RvcihzYWZldHlfcikpKSArDQogIGdlb21fYmFyKCkgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAiRSIsIGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiMVxuUG9vciIsICIyXG5GYWlyIiwgIjNcbkdvb2QiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjRcblZlcnkgZ29vZCIsICI1XG5FeGNlbGxlbnQiKSkgKw0KICBsYWJzKHRpdGxlID0gIlBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5IChwcmVkaWN0b3IsIExldmVsIDIpIiwNCiAgICAgICB4ID0gIk5laWdoYm9yaG9vZCBzYWZldHkgKHJldmVyc2UtY29kZWQpIiwgeSA9ICJOdW1iZXIgb2YgaG91c2Vob2xkcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQpbMnB0OiBhcHByb3ByaWF0ZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGFuZCBwbG90IG9mIGV2ZXJ5IHZhcmlhYmxlIDFwdDogc29tZSB2YXJpYWJsZXMgbWlzc2luZyBhbmQvb3IgcG9vciBjaG9pY2Ugb2YgdmlzdWFsaXphdGlvbiAwcHQ6IHNpZ25pZmljYW50IHBhcnRzIG1pc3Npbmcvb3ZlciBoYWxmIHBvb3IgY2hvaWNlc117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KWypTdW1tYXJ5Kl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW0luY2x1ZGUgYSBzdW1tYXJ5IHRoYXQgZGlzY3Vzc2VzIHRoZSBkaXN0cmlidXRpb24gYmFzZWQgb24gdGhlIHBsb3RzIGFuZCB0aGUgc2tldy9rdXJ0b3NpcyAoaWYgY29udGludW91cykuIE5vdGUgd2hldGhlciB0aGVyZSBhcmUgbGlrZWx5IGFueSBvdXRsaWVycyBhbmQgaG93IHlvdSBjYW1lIHRvIHRoYXQgY29uY2x1c2lvbi5de3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCjEuIFNlbGYtcmF0ZWQgaGVhbHRoLiBTZWxmLXJhdGVkIGhlYWx0aCBhdmVyYWdlZCAzLjA4IChTRCA9IDEuMDIsIG1lZGlhbiA9IDMpLiBUaGUgc2tldyBvZiDiiJIwLjA5IGNvbmZpcm1zIHRoZSBkaXN0cmlidXRpb24gaXMgZXNzZW50aWFsbHkgc3ltbWV0cmljLCBhbmQgdGhlIGt1cnRvc2lzIG9mIOKIkjAuNTYgaW5kaWNhdGVzIGl0IGlzIHNsaWdodGx5IGZsYXR0ZXIgdGhhbiBub3JtYWwuIEJvdGggdmFsdWVzIGZhbGwgd2VsbCB3aXRoaW4gdGhlIGNvbnZlbnRpb25hbCB0aHJlc2hvbGRzIG9mIHwyfCBmb3Igc2tldyBhbmQgfDd8IGZvciBrdXJ0b3Npcywgc28gdGhlIHZhcmlhYmxlIGlzIGFjY2VwdGFibGUgZm9yIHRyZWF0bWVudCBhcyBhcHByb3hpbWF0ZWx5IGNvbnRpbnVvdXMuIFRoZSBtZWFuIGFuZCA1JSB0cmltbWVkIG1lYW4gYXJlIG5lYXJseSBpZGVudGljYWwgKDMuMDggdnMuIDMuMDkpLCBpbmRpY2F0aW5nIHRoYXQgbm8gZXh0cmVtZSBzY29yZXMgYXJlIHB1bGxpbmcgdGhlIG1lYW4uIFRoZXJlIGFyZSBubyBvdXRsaWVyczogdGhlIG9ic2VydmVkIHJhbmdlIGlzIGV4YWN0bHkgMSB0byA1O2FuZCB0aGUgbW9zdCBleHRyZW1lIHBvc3NpYmxlIHNjb3JlcyBzaXQgY2xvc2UgdG8gdGhlIG1lYW4gaW4gc3RhbmRhcmRpemVkIHRlcm1zICh6ID0g4oiSMi4wNCBmb3IgIlBvb3IiIGFuZCB6ID0gMS44OCBmb3IgIkV4Y2VsbGVudCIpLCB3ZWxsIGluc2lkZSB0aGUgfDMuMjl8IGN1dG9mZi4NCg0KMi4gTGlmZSBzYXRpc2ZhY3Rpb24uIExpZmUgc2F0aXNmYWN0aW9uIGF2ZXJhZ2VkIDMuODQgKFNEID0gMC44NSwgbWVkaWFuID0gNCkuVGhlcmUncyBhIG5lZ2F0aXZlIChsZWZ0KSBza2V3IG9mIOKIkjAuNDcsIHJlZmxlY3RpbmcgYSBjZWlsaW5nIGVmZmVjdCB0aGF0IGlzIHdlbGwgZG9jdW1lbnRlZCBmb3Igc3ViamVjdGl2ZSB3ZWxsLWJlaW5nIGFtb25nIG9sZGVyIGFkdWx0cy4gS3VydG9zaXMgb2YgMC4yMiBpcyBjbG9zZSB0byB0aGF0IG9mIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gQm90aCB2YWx1ZXMgZmFsbCB3aXRoaW4gYWNjZXB0YWJsZSBsaW1pdHMsIHNvIG5vIHRyYW5zZm9ybWF0aW9uIGlzIHJlcXVpcmVkLiBUaGUgdHJpbW1lZCBtZWFuICgzLjg4KSBpcyBzbGlnaHRseSBoaWdoZXIgdGhhbiB0aGUgbWVhbiAoMy44NCksIGNvbnNpc3RlbnQgd2l0aCB0aGUgc21hbGwgdGFpbCBvZiBsb3cgc2NvcmVzIHB1bGxpbmcgdGhlIG1lYW4gZG93biBzbGlnaHRseS4gSXQncyBwb3NzaWJsZSB0byBoYXZlIG91dGxpZXIgZm9yIHRoaXMgdmFyaWFibGUsIHNpbmNlIHRoZSBsb3dlc3QgY2F0ZWdvcnkgKCJOb3QgYXQgYWxsIHNhdGlzZmllZCIpIGZhbGxzIGF0IHogPSAoMSDiiJIgMy44NCkgLyAwLjg1ID0g4oiSMy4zNCwganVzdCBiZXlvbmQgdGhlIHwzLjI5fCB0aHJlc2hvbGQuIFJlc3BvbmRlbnRzIGNob29zaW5nIHRoaXMgY2F0ZWdvcnkgd2lsbCB0aGVyZWZvcmUgYmUgZmxhZ2dlZCBpbiB0aGUgb3V0bGllciBjaGVjayBiZWxvdy4NCg0KMy4gUGVyY2VpdmVkIG5laWdoYm9yaG9vZCBzYWZldHkuIE5laWdoYm9yaG9vZCBzYWZldHkgYXZlcmFnZWQgMy43OCAoU0QgPSAxLjA3LCBtZWRpYW4gPSA0KS4gS3VydG9zaXMgb2Yg4oiSMC40OSBpbmRpY2F0ZXMgYSBzbGlnaHRseSBmbGF0dGVyLXRoYW4tbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlIHRyaW1tZWQgbWVhbiAoMy44NykgZXhjZWVkcyB0aGUgbWVhbiAoMy43OCkgYnkgdGhlIGxhcmdlc3QgbWFyZ2luIG9mIHRoZSB0aHJlZSB2YXJpYWJsZXMsIGFnYWluIHJlZmxlY3RpbmcgdGhlIHRoaW4gdGFpbCBvZiBsb3cgc2FmZXR5IHJhdGluZ3MuIFRoZXJlIGFyZSBubyBvdXRsaWVyczogdGhlIGxvd2VzdCBwb3NzaWJsZSBzY29yZSBmYWxscyBhdCB6ID0gKDEg4oiSIDMuNzgpIC8gMS4wNyA9IOKIkjIuNjAgYW5kIHRoZSBoaWdoZXN0IGF0IHogPSAxLjEzLCBib3RoIGluc2lkZSB0aGUgY3V0b2ZmLg0KDQpbUEVSIFZBUklBQkxFOiAxcHQ6IHN1bW1hcnkgbWFrZXMgc2Vuc2UgMHB0OiBzdW1tYXJ5IGRvZXNuJ3QgbWF0Y2ggZGVzY3JpcHRpdmVzL3Zpc3VhbGl6YXRpb25zIG9yIGlzIG1pc3NpbmcuIFRha2UgdGhlIGF2ZXJhZ2Ugb2YgZWFjaCB2YXJpYWJsZXMnIHNjb3JlcyBmb3IgdGhpcyBwYXJ0IG9mIHRoZSBydWJyaWNde3N0eWxlPSJjb2xvcjogcmVkOyJ9DQoNCiMjIENoZWNrIGZvciBvdXRsaWVycyBhbmQgdHJhbnNmb3JtIGlmIG5lZWRlZA0KDQpbKk5vdGUsIGV2ZW4gaWYgeW91ciBkYXRhIGRvIG5vdCBzaG93IHRoYXQgeW91IGhhdmUgb3V0bGllcnMsIGNob29zZSBhdCBsZWFzdCBvbmUgdmFyaWFibGUgdG8gZmlsbCBpbiB0aGUgY29kZSBiZWxvdyBmb3IgcHJhY3RpY2UuKl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiNJZGVudGlmeSBvdXRsaWVycyANCg0KbXlkYXRhIDwtIG15ZGF0YSAlPiUNCiAgbXV0YXRlKA0KICAgIGhlYWx0aF96ID0gYXMubnVtZXJpYyhzY2FsZShoZWFsdGhfcikpLA0KICAgIHNhdGlzX3ogID0gYXMubnVtZXJpYyhzY2FsZShzYXRpc19yKSksDQogICAgc2FmZXR5X3ogPSBhcy5udW1lcmljKHNjYWxlKHNhZmV0eV9yKSkNCiAgKQ0KDQpvdXRsaWVyX2NoZWNrIDwtIGRhdGEuZnJhbWUoDQogIFZhcmlhYmxlICA9IGMoIlNlbGYtcmF0ZWQgaGVhbHRoIiwgIkxpZmUgc2F0aXNmYWN0aW9uIiwgIk5laWdoYm9yaG9vZCBzYWZldHkiKSwNCiAgTWluX3ogICAgID0gYyhtaW4obXlkYXRhJGhlYWx0aF96KSwgbWluKG15ZGF0YSRzYXRpc196KSwgbWluKG15ZGF0YSRzYWZldHlfeikpLA0KICBNYXhfeiAgICAgPSBjKG1heChteWRhdGEkaGVhbHRoX3opLCBtYXgobXlkYXRhJHNhdGlzX3opLCBtYXgobXlkYXRhJHNhZmV0eV96KSksDQogIE5fZmxhZ2dlZCA9IGMoc3VtKGFicyhteWRhdGEkaGVhbHRoX3opID4gMy4yOSksDQogICAgICAgICAgICAgICAgc3VtKGFicyhteWRhdGEkc2F0aXNfeikgID4gMy4yOSksDQogICAgICAgICAgICAgICAgc3VtKGFicyhteWRhdGEkc2FmZXR5X3opID4gMy4yOSkpDQopDQoNCm91dGxpZXJfY2hlY2sgJT4lDQogIGtibChkaWdpdHMgPSAyLA0KICAgICAgY29sLm5hbWVzID0gYygiVmFyaWFibGUiLCAiTWluIHoiLCAiTWF4IHoiLCAiTiB3aXRoIHx6fCA+IDMuMjkiKSwNCiAgICAgIGNhcHRpb24gPSAiT3V0bGllciBzY3JlZW4gZm9yIGFsbCBhbmFseXNpcyB2YXJpYWJsZXMiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQojQ3JlYXRlIGEgc3Vic2V0IG9mIHRoZSBkYXRhIHRoYXQgYXJlIG9ubHkgdGhlIG91dGxpZXJzIHNvIHdlIGNhbiB2aWV3IHRoZW0NCg0Kb3V0bGllcnMgPC0gbXlkYXRhICU+JQ0KICBmaWx0ZXIoYWJzKHNhdGlzX3opID4gMy4yOSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoaGhpZF9zdWIsIFBOLCBzYXRpc19yLCBzYXRpc196LCBoZWFsdGhfciwgc2FmZXR5X3IpDQoNCiNWaWV3IG91dGxpZXJzDQoNCmNhdCgiTGlmZSBzYXRpc2ZhY3Rpb24gb3V0bGllcnM6IiwgbnJvdyhvdXRsaWVycyksICJvZiIsIG5yb3cobXlkYXRhKSwNCiAgICAicmVzcG9uZGVudHMgKCIsIHJvdW5kKG5yb3cob3V0bGllcnMpIC8gbnJvdyhteWRhdGEpICogMTAwLCAyKSwgIiUgKVxuXG4iKQ0KDQojV2luc29yaXplIG91dGxpZXJzDQoNCnNhdGlzX2Zsb29yICAgPC0gbWluKG15ZGF0YSRzYXRpc19yW2FicyhteWRhdGEkc2F0aXNfeikgPD0gMy4yOV0pDQpzYXRpc19jZWlsaW5nIDwtIG1heChteWRhdGEkc2F0aXNfclthYnMobXlkYXRhJHNhdGlzX3opIDw9IDMuMjldKQ0KDQpjYXQoIlxuV2luc29yaXppbmcgYm91bmRzOiBmbG9vciA9Iiwgc2F0aXNfZmxvb3IsICIsIGNlaWxpbmcgPSIsIHNhdGlzX2NlaWxpbmcsICJcbiIpDQoNCm15ZGF0YSA8LSBteWRhdGEgJT4lDQogIG11dGF0ZShzYXRpc193ID0gcG1pbihwbWF4KHNhdGlzX3IsIHNhdGlzX2Zsb29yKSwgc2F0aXNfY2VpbGluZykpDQoNCiNSZS1jaGVjayBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIChvbiBhbGwgdmVyc2lvbnMgb2YgdGhlIHZhcmlhYmxlKHMpIGp1c3QgY3JlYXRlZCkNCg0KcHN5Y2g6OmRlc2NyaWJlKG15ZGF0YVssIGMoInNhdGlzX3IiLCAic2F0aXNfdyIpXSkgJT4lDQogIGtibChkaWdpdHMgPSAyLA0KICAgICAgY2FwdGlvbiA9ICJMaWZlIHNhdGlzZmFjdGlvbjogb3JpZ2luYWwsIHdpbnNvcml6ZWQiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQojIHJlLXNjcmVlbiB0aGUgd2luc29yaXplZCB2YXJpYWJsZSB0byBjb25maXJtIG5vIGNhc2VzIHJlbWFpbiBiZXlvbmQgfDMuMjl8DQpzYXRpc193X3ogPC0gYXMubnVtZXJpYyhzY2FsZShteWRhdGEkc2F0aXNfdykpDQpjYXQoIldpbnNvcml6ZWQgdmFyaWFibGU6IG1pbiB6ID0iLCByb3VuZChtaW4oc2F0aXNfd196KSwgMiksDQogICAgInwgbWF4IHogPSIsIHJvdW5kKG1heChzYXRpc193X3opLCAyKSwNCiAgICAifCBjYXNlcyBzdGlsbCBmbGFnZ2VkID0iLCBzdW0oYWJzKHNhdGlzX3dfeikgPiAzLjI5KSwgIlxuIikNCg0KI1JlLXBsb3QgdGhlICJmaW5hbCIgdmFyaWFibGUgeW91IGFyZSBjb21mb3J0YWJsZSB1c2luZy4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIGZpbmFsIGFuYWx5c2lzIHZhcmlhYmxlID0gd2luc29yaXplZCBsaWZlIHNhdGlzZmFjdGlvbg0KbXlkYXRhIDwtIG15ZGF0YSAlPiUgbXV0YXRlKHNhdGlzX2ZpbmFsID0gc2F0aXNfdykNCg0KIyBiZWZvcmUvYWZ0ZXIgY29tcGFyaXNvbg0KY29tcGFyZSA8LSByYmluZCgNCiAgZGF0YS5mcmFtZSh2ZXJzaW9uID0gIk9yaWdpbmFsIiwgdmFsdWUgPSBteWRhdGEkc2F0aXNfciksDQogIGRhdGEuZnJhbWUodmVyc2lvbiA9ICJXaW5zb3JpemVkIChmaW5hbCkiLCB2YWx1ZSA9IG15ZGF0YSRzYXRpc19maW5hbCkNCikNCg0KZ2dwbG90KGNvbXBhcmUsIGFlcyh4ID0gZmFjdG9yKHZhbHVlLCBsZXZlbHMgPSAxOjUpLCBmaWxsID0gZmFjdG9yKHZhbHVlKSkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGZhY2V0X3dyYXAofiB2ZXJzaW9uKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJDIiwgZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShkcm9wID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMVxuTm90IGF0IGFsbCIsICIyXG5Ob3QgdmVyeSIsICIzXG5Tb21ld2hhdCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNFxuVmVyeSIsICI1XG5Db21wbGV0ZWx5IikpICsNCiAgbGFicyh0aXRsZSA9ICJMaWZlIHNhdGlzZmFjdGlvbiBiZWZvcmUgYW5kIGFmdGVyIHdpbnNvcml6aW5nIiwNCiAgICAgICB4ID0gIkxpZmUgc2F0aXNmYWN0aW9uIChyZXZlcnNlLWNvZGVkKSIsIHkgPSAiTnVtYmVyIG9mIHJlc3BvbmRlbnRzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNClsycHQ6IGFsbCB2YXJpYWJsZXMgY2hlY2tlZCBhbmQgY29ycmVjdGVkIDFwdDogXDw1MCUgb2YgdmFyaWFibGVzIHRoYXQgbmVlZGVkIHRvIGJlIGNoZWNrZWQgYW5kL29yIGNvcnJlY3RlZCB3ZXJlIG5vdCBkb25lIDBwdDogXD41MCUgb2YgdmFyaWFiZWxzIHRoYXQgbmVlZGVkIHRvIGJlIGNoZWNrZWQgYW5kL29yIGNvcnJlY3RlZCB3ZXJlIG5vdCBkb25lLl17c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KWypTdW1tYXJ5Kl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW0luY2x1ZGUgYSBzdW1tYXJ5IHRoYXQgcHJvdmlkZXMgYSBqdXN0aWZpY2F0aW9uIGZvciBhbnkgZGF0YSBtYW5pcHVsYXRpb25zIHlvdSBkaWQuIEluY2x1ZGUgZm9yIGVhY2ggdmFyaWFibGUgd2hldGhlciBvciBub3QgeW91IGNoZWNrZWQvd2luc29yaXplZC90cmFuc2Zvcm1lZCBhbmQgd2hldGhlciBhIGNoYW5nZSB3YXMgbmVlZGVkIG9yIG5vdCwgYW5kIGlmIHRoZXJlIHdhcyBhIGNoYW5nZSwgd2hldGhlciBpdCB3YXMgc3VjY2Vzc2Z1bCBvciBub3QuXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQoxLiBTZWxmLXJhdGVkIGhlYWx0aDogQ2hlY2tlZDsgbm8gd2luc29yaXppbmcgb3IgdHJhbnNmb3JtYXRpb24gYXBwbGllZC4gDQoyLiBMaWZlIHNhdGlzZmFjdGlvbjogQ2hlY2tlZCBhbmQgd2luc29yaXplZC4gVHJhbnNmb3JtYXRpb24gd2FzIG5vdCBuZWVkZWQgc2luY2UgdHJhbnNmb3JtaW5nIGEgZml2ZS1wb2ludCBvcmRpbmFsIHNjYWxlIHdvdWxkIGRlc3Ryb3kgdGhlIGludGVycHJldGFiaWxpdHkgb2YgdGhlIHNjb3JlOiBhIG9uZS11bml0IGNoYW5nZSBpbiBhIHNxdWFyZWQgc2NvcmUgaGFzIG5vIG5hdHVyYWwgdmVyYmFsIG1lYW5pbmcsIHdoZXJlYXMgYSBvbmUtdW5pdCBjaGFuZ2UgaW4gdGhlIG9yaWdpbmFsIGNvcnJlc3BvbmRzIHRvIG1vdmluZyBvbmUgZnVsbCByZXNwb25zZSBjYXRlZ29yeS5UaGUgbWFuaXB1bGF0aW9uIHdhcyBzdWNjZXNzZnVsLCByZS1zY3JlZW5pbmcgY29uZmlybWVkIG5vIGNhc2VzIHJlbWFpbmVkIGJleW9uZCB8enwgPiAzLjI5Lg0KMy4gUGVyY2VpdmVkIG5laWdoYm9yaG9vZCBzYWZldHk6IENoZWNrZWQ7IG5vIHdpbnNvcml6aW5nIG9yIHRyYW5zZm9ybWF0aW9uIGFwcGxpZWQuDQoNCltQRVIgVkFSSUFCTEU6IDFwdDogc3VtbWFyeSBtYWtlcyBzZW5zZS4gMHB0OiBzdW1tYXJ5IGRvZXNuJ3QgbWF0Y2ggZGVzY3JpcHRpdmVzL3Zpc3VhbGl6YXRpb25zIG9yIGlzIG1pc3NpbmcuIFRha2UgdGhlIGF2ZXJhZ2Ugb2YgZWFjaCB2YXJpYWJsZXMnIHNjb3JlcyBmb3IgdGhpcyBwYXJ0IG9mIHRoZSBydWJyaWNde3N0eWxlPSJjb2xvcjogcmVkOyJ9DQoNCiMjIERlZ3JlZSBvZiBOZXN0aW5nOg0KDQojIyMgQ2hlY2sgdGhlIGRlZ3JlZSBvZiBuZXN0aW5nIGZvciBlYWNoIHByZWRpY3RvciB2YXJpYWJsZS4NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiNQcmVkaWN0b3IgMTogTGlmZSBzYXRpc2ZhY3Rpb24gKExldmVsIDEpDQoNCiMxLiBSdW4gSUNDDQppY2Nfc2F0aXMgPC0gbG1lcihzYXRpc19maW5hbCB+IDEgKyAoMSB8IGhoaWRfc3ViKSwgZGF0YSA9IG15ZGF0YSwgUkVNTCA9IFRSVUUpDQoNCiNleHRyYWN0IHZhcmlhbmNlIGNvZWZmaWNpZW50cw0KdmNfc2F0aXMgPC0gYXMuZGF0YS5mcmFtZShWYXJDb3JyKGljY19zYXRpcykpDQp2Y19zYXRpcw0KDQojU3RvcmUgdGhlIHJhbmRvbSBlZmZlY3QgdmFyaWFuY2VzICh2Y292IGNvbHVtbiBvZiBWYXJDb3JyIG9iamVjdCkNCnRhdV9zYXRpcyAgIDwtIHZjX3NhdGlzJHZjb3ZbdmNfc2F0aXMkZ3JwID09ICJoaGlkX3N1YiJdICAgIyBiZXR3ZWVuLWhvdXNlaG9sZA0Kc2lnbWFfc2F0aXMgPC0gdmNfc2F0aXMkdmNvdlt2Y19zYXRpcyRncnAgPT0gIlJlc2lkdWFsIl0gICAjIHdpdGhpbi1ob3VzZWhvbGQNCg0KI0NhbGN1bGF0ZSBJQ0MNCklDQ19zYXRpcyA8LSB0YXVfc2F0aXMgLyAodGF1X3NhdGlzICsgc2lnbWFfc2F0aXMpDQoNCiNDb252ZXJ0IHRvIGEgJQ0KSUNDX3NhdGlzX3BjdCA8LSBJQ0Nfc2F0aXMgKiAxMDANCg0KI0NhbGN1bGF0ZSAlIG9mIHZhcmlhbmNlIGR1ZSB0byB3aXRoaW4taG91c2Vob2xkIHZhcmlhdGlvbg0Kd2l0aGluX3NhdGlzX3BjdCA8LSAxMDAgLSBJQ0Nfc2F0aXNfcGN0DQoNCiMgUFJFRElDVE9SIDI6IE5laWdoYm9yaG9vZCBzYWZldHkNCg0KIzEuIFJ1biBJQ0MNCmljY19zYWZldHkgPC0gbG1lcihzYWZldHlfciB+IDEgKyAoMSB8IGhoaWRfc3ViKSwgZGF0YSA9IG15ZGF0YSwgUkVNTCA9IFRSVUUpDQpjYXQoIlNpbmd1bGFyIGZpdCBmb3Igc2FmZXR5IG1vZGVsPyIsIGlzU2luZ3VsYXIoaWNjX3NhZmV0eSksICJcblxuIikNCg0KI2V4dHJhY3QgdmFyaWFuY2UgY29lZmZpY2llbnRzDQp2Y19zYWZldHkgPC0gYXMuZGF0YS5mcmFtZShWYXJDb3JyKGljY19zYWZldHkpKQ0KdmNfc2FmZXR5DQoNCiNTdG9yZSB0aGUgcmFuZG9tIGVmZmVjdCB2YXJpYW5jZXMgKHZjb3YgY29sdW1uIG9mIFZhckNvcnIgb2JqZWN0KQ0KdGF1X3NhZmV0eSAgIDwtIHZjX3NhZmV0eSR2Y292W3ZjX3NhZmV0eSRncnAgPT0gImhoaWRfc3ViIl0NCnNpZ21hX3NhZmV0eSA8LSB2Y19zYWZldHkkdmNvdlt2Y19zYWZldHkkZ3JwID09ICJSZXNpZHVhbCJdDQoNCiNDYWxjdWxhdGUgSUNDDQpJQ0Nfc2FmZXR5IDwtIHRhdV9zYWZldHkgLyAodGF1X3NhZmV0eSArIHNpZ21hX3NhZmV0eSkNCg0KI0NvbnZlcnQgdG8gYSAlDQpJQ0Nfc2FmZXR5X3BjdCA8LSBJQ0Nfc2FmZXR5ICogMTAwDQoNCiNDYWxjdWxhdGUgJSBvZiB2YXJpYW5jZSBkdWUgdG8gd2l0aGluLWhvdXNlaG9sZCB2YXJpYXRpb24NCndpdGhpbl9zYWZldHlfcGN0IDwtIDEwMCAtIElDQ19zYWZldHlfcGN0DQoNCmRhdGEuZnJhbWUoDQogIFByZWRpY3RvciA9IGMoIkxpZmUgc2F0aXNmYWN0aW9uIChMZXZlbCAxKSIsICJOZWlnaGJvcmhvb2Qgc2FmZXR5IChMZXZlbCAyKSIpLA0KICBUYXUwMCAgICAgPSBjKHRhdV9zYXRpcywgdGF1X3NhZmV0eSksDQogIFNpZ21hMiAgICA9IGMoc2lnbWFfc2F0aXMsIHNpZ21hX3NhZmV0eSksDQogIElDQyAgICAgICA9IGMoSUNDX3NhdGlzLCBJQ0Nfc2FmZXR5KSwNCiAgQmV0d2VlbiAgID0gYyhJQ0Nfc2F0aXNfcGN0LCBJQ0Nfc2FmZXR5X3BjdCksDQogIFdpdGhpbiAgICA9IGMod2l0aGluX3NhdGlzX3BjdCwgd2l0aGluX3NhZmV0eV9wY3QpDQopICU+JQ0KICBrYmwoZGlnaXRzID0gYygwLCA0LCA0LCAzLCAxLCAxKSwNCiAgICAgIGNvbC5uYW1lcyA9IGMoIlByZWRpY3RvciIsICJCZXR3ZWVuLUhIIHZhcmlhbmNlICjPhDAwKSIsDQogICAgICAgICAgICAgICAgICAgICJXaXRoaW4tSEggdmFyaWFuY2UgKM+DwrIpIiwgIklDQyIsDQogICAgICAgICAgICAgICAgICAgICIlIGJldHdlZW4gaG91c2Vob2xkcyIsICIlIHdpdGhpbiBob3VzZWhvbGRzIiksDQogICAgICBjYXB0aW9uID0gIkRlZ3JlZSBvZiBuZXN0aW5nIGZvciBlYWNoIHByZWRpY3RvciIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLCBmdWxsX3dpZHRoID0gRkFMU0UpDQpgYGANCg0KWypTdW1tYXJ5Kl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW1Byb3ZpZGUgYSBicmllZiBzdW1tYXJ5IG9mIHRoZSAlIG9mIHdpdGhpbi1jbHVzdGVyIGFuZCBiZXR3ZWVuLWNsdXN0ZXIgdmFyaWFuY2UgKGluc3RlYWQgb2YgdGhlIHdvcmQgY2x1c3RlciB1c2Ugd2hhdGV2ZXIgdGhlIGNsdXN0ZXIgaXMgLS0gbGlrZSBjbGFzcyBvciBjb2hvcnQgZm9yIGV4YW1wbGUpLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KTGlmZSBzYXRpc2ZhY3Rpb24uIEFwcHJveGltYXRlbHkgMzEuMiUgb2YgdGhlIHZhcmlhbmNlIGluIGxpZmUgc2F0aXNmYWN0aW9uIGxpZXMgYmV0d2VlbiBob3VzZWhvbGRzLCB3aGlsZSB0aGUgcmVtYWluaW5nIDY4LjglIGxpZXMgd2l0aGluIGhvdXNlaG9sZHMg4oCUIHRoYXQgaXMsIGJldHdlZW4gcmVzcG9uZGVudHMgd2hvIGxpdmUgaW4gdGhlIHNhbWUgaG91c2Vob2xkLiBCZWNhdXNlIG1lYW5pbmdmdWwgdmFyaWFuY2UgZXhpc3RzIHdpdGhpbiBob3VzZWhvbGRzLCBsaWZlIHNhdGlzZmFjdGlvbiBiZWhhdmVzIGFzIGEgZ2VudWluZSBMZXZlbCAxIHZhcmlhYmxlIGFuZCBpcyBhcHByb3ByaWF0ZWx5IG1vZGVsZWQgYXQgdGhlIHJlc3BvbmRlbnQgbGV2ZWwuDQoNClBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5LiAxMDAlIG9mIHRoZSB2YXJpYW5jZSBpbiBuZWlnaGJvcmhvb2Qgc2FmZXR5IGxpZXMgYmV0d2VlbiBob3VzZWhvbGRzIGFuZCAwJSBsaWVzIHdpdGhpbiBob3VzZWhvbGRzLiBUaGlzIGlzIGFuIGV4cGVjdGVkIHJlc3VsdCBzaW5jZSBzYWZldHkgd2FzIHJlcG9ydGVkIG9uY2UgcGVyIGhvdXNlaG9sZCBieSB0aGUgZGVzaWduYXRlZCBmaW5hbmNpYWwvZmFtaWx5IHJlc3BvbmRlbnQgYW5kIGFzc2lnbmVkIGlkZW50aWNhbGx5IHRvIGV2ZXJ5IGhvdXNlaG9sZCBtZW1iZXIsIHNvIHRoZXJlIGlzIG5vIHdpdGhpbi1ob3VzZWhvbGQgdmFyaWF0aW9uIGZvciB0aGUgbW9kZWwgdG8gZXN0aW1hdGUuIFRoaXMgcmVzdWx0IGlzIHRoZSBjb25maXJtYXRpb24gdGhhdCBuZWlnaGJvcmhvb2Qgc2FmZXR5IGlzIGEgcHVyZSBMZXZlbCAyIHZhcmlhYmxlLiANCg0KW1BFUiBWQVJJQUJMRTogMXB0OiBzdW1tYXJ5IG1ha2VzIHNlbnNlLiAwcHQ6IHN1bW1hcnkgZG9lc24ndCBtYXRjaCBkZXNjcmlwdGl2ZXMvdmlzdWFsaXphdGlvbnMgb3IgaXMgbWlzc2luZy4gVGFrZSB0aGUgYXZlcmFnZSBvZiBlYWNoIHZhcmlhYmxlcycgc2NvcmVzIGZvciB0aGlzIHBhcnQgb2YgdGhlIHJ1YnJpY117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KIyMjIENoZWNrIHRoZSBkZWdyZWUgb2YgbmVzdGluZyBmb3IgZWFjaCB0aGUgb3V0Y29tZSB2YXJpYWJsZS4NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiMxLiBSdW4gSUNDDQppY2NfaGVhbHRoIDwtIGxtZXIoaGVhbHRoX3IgfiAxICsgKDEgfCBoaGlkX3N1YiksIGRhdGEgPSBteWRhdGEsIFJFTUwgPSBUUlVFKQ0KDQojZXh0cmFjdCB2YXJpYW5jZSBjb2VmZmljaWVudHMNCnZjX2hlYWx0aCA8LSBhcy5kYXRhLmZyYW1lKFZhckNvcnIoaWNjX2hlYWx0aCkpDQp2Y19oZWFsdGgNCg0KI1N0b3JlIHRoZSByYW5kb20gZWZmZWN0IHZhcmlhbmNlcyAodmNvdiBjb2x1bW4gb2YgVmFyQ29yciBvYmplY3QpDQp0YXVfaGVhbHRoICAgPC0gdmNfaGVhbHRoJHZjb3ZbdmNfaGVhbHRoJGdycCA9PSAiaGhpZF9zdWIiXSAgICMgYmV0d2Vlbi1ob3VzZWhvbGQNCnNpZ21hX2hlYWx0aCA8LSB2Y19oZWFsdGgkdmNvdlt2Y19oZWFsdGgkZ3JwID09ICJSZXNpZHVhbCJdICAgIyB3aXRoaW4taG91c2Vob2xkDQoNCiNDYWxjdWxhdGUgSUNDDQpJQ0NfaGVhbHRoIDwtIHRhdV9oZWFsdGggLyAodGF1X2hlYWx0aCArIHNpZ21hX2hlYWx0aCkNCg0KI0NvbnZlcnQgdG8gYSAlDQpJQ0NfaGVhbHRoX3BjdCA8LSBJQ0NfaGVhbHRoICogMTAwDQoNCiNDYWxjdWxhdGUgJSBvZiB2YXJpYW5jZSBkdWUgdG8gd2l0aGluLWhvdXNlaG9sZCB2YXJpYXRpb24NCndpdGhpbl9oZWFsdGhfcGN0IDwtIDEwMCAtIElDQ19oZWFsdGhfcGN0DQoNCmRhdGEuZnJhbWUoDQogIE91dGNvbWUgPSAiU2VsZi1yYXRlZCBoZWFsdGgiLA0KICBUYXUwMCAgID0gdGF1X2hlYWx0aCwNCiAgU2lnbWEyICA9IHNpZ21hX2hlYWx0aCwNCiAgSUNDICAgICA9IElDQ19oZWFsdGgsDQogIEJldHdlZW4gPSBJQ0NfaGVhbHRoX3BjdCwNCiAgV2l0aGluICA9IHdpdGhpbl9oZWFsdGhfcGN0DQopICU+JQ0KICBrYmwoZGlnaXRzID0gYygwLCA0LCA0LCAzLCAxLCAxKSwNCiAgICAgIGNvbC5uYW1lcyA9IGMoIk91dGNvbWUiLCAiQmV0d2Vlbi1ISCB2YXJpYW5jZSAoz4QwMCkiLA0KICAgICAgICAgICAgICAgICAgICAiV2l0aGluLUhIIHZhcmlhbmNlICjPg8KyKSIsICJJQ0MiLA0KICAgICAgICAgICAgICAgICAgICAiJSBiZXR3ZWVuIGhvdXNlaG9sZHMiLCAiJSB3aXRoaW4gaG91c2Vob2xkcyIpLA0KICAgICAgY2FwdGlvbiA9ICJEZWdyZWUgb2YgbmVzdGluZyBmb3IgdGhlIG91dGNvbWUiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQpgYGANCg0KWypTdW1tYXJ5Kl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW1Byb3ZpZGUgYSBicmllZiBzdW1tYXJ5IG9mIHRoZSAlIG9mIHdpdGhpbi1jbHVzdGVyIGFuZCBiZXR3ZWVuLWNsdXN0ZXIgdmFyaWFuY2UgKGluc3RlYWQgb2YgdGhlIHdvcmQgY2x1c3RlciB1c2Ugd2hhdGV2ZXIgdGhlIGNsdXN0ZXIgaXMgLS0gbGlrZSBjbGFzcyBvciBjb2hvcnQgZm9yIGV4YW1wbGUpLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KU2VsZi1yYXRlZCBoZWFsdGguIEFwcHJveGltYXRlbHkgMjcuNyUgb2YgdGhlIHZhcmlhbmNlIGluIHNlbGYtcmF0ZWQgaGVhbHRoIGxpZXMgYmV0d2VlbiBob3VzZWhvbGRzLCB3aGlsZSB0aGUgcmVtYWluaW5nIDcyLjMlIGxpZXMgd2l0aGluIGhvdXNlaG9sZHMuIA0KDQpbMnB0OiBzdW1tYXJ5IG1ha2VzIHNlbnNlLCBhY2N1cmF0ZSBhbmQgY29tcGxldGUuIDFwdDogc29tZSBlcnJvcnMgb3IgbWlzc2luZyBpbmZvcm1hdGlvbi4gMHB0OiBtYW55IGVycm9ycyBvciBtaXNzaW5nIGluZm9ybWF0aW9uIChlLmcuLCBvdmVyIGhhbGYgcHJvYmxlbWF0aWMpXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQojIyBDZW50ZXJpbmcNCg0KWyoqRGlzY3Vzc2lvbioqXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpbSXMgaXQgaW1wb3J0YW50IHRvIGNlbnRlciBmb3IgdGhpcyBhbmFseXNpcz8gRm9yIGVhY2ggdmFyaWFibGUsIGRlY2lkZSB5ZXMvbm8gYW5kIGlmIHllcywgdGhlbiBob3c/XXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpDZW50ZXJpbmcgaXMgaW1wb3J0YW50IGZvciB0aGlzIGFuYWx5c2lzLiBOZWl0aGVyIHByZWRpY3RvciBoYXMgYSBtZWFuaW5nZnVsIHplcm8gcG9pbnQ6IGJvdGggYXJlIG1lYXN1cmVkIG9uIDEtdG8tNSBzY2FsZXMsIHNvIGEgc2NvcmUgb2YgMCBpcyBub3QgYSBwb3NzaWJsZSByZXNwb25zZS4gV2l0aG91dCBjZW50ZXJpbmcsIHRoZSBtb2RlbCBpbnRlcmNlcHQgd291bGQgcmVwcmVzZW50IHRoZSBleHBlY3RlZCBzZWxmLXJhdGVkIGhlYWx0aCBvZiBhIHJlc3BvbmRlbnQgd2l0aCBhIGxpZmUgc2F0aXNmYWN0aW9uIG9mIDAgbGl2aW5nIGluIGEgaG91c2Vob2xkIHdpdGggYSBuZWlnaGJvcmhvb2Qgc2FmZXR5IHJhdGluZyBvZiAwLiBDZW50ZXJpbmcgcmVsb2NhdGVzIHplcm8gdG8gYSBtZWFuaW5nZnVsIHZhbHVlIHNvIHRoYXQgdGhlIGludGVyY2VwdCBjYW4gYmUgaW50ZXJwcmV0ZWQuDQoNCkZvciBsaWZlIHNhdGlzZmFjdGlvbiwgZ3JhbmQtbWVhbiBjZW50ZXJpbmcgd2FzIGNob3NlbiBvdmVyIGdyb3VwLW1lYW4gY2VudGVyaW5nIGZvciB0d28gcmVhc29ucy4gRmlyc3QsIGl0IG1hdGNoZXMgdGhlIHJlc2VhcmNoIHF1ZXN0aW9uLiBIeXBvdGhlc2lzIDEgYXNrcyB3aGV0aGVyIHBlb3BsZSB3aXRoIGhpZ2hlciBsaWZlIHNhdGlzZmFjdGlvbiByZXBvcnQgYmV0dGVyIGhlYWx0aCB0aGFuIHBlb3BsZSB3aXRoIGxvd2VyIGxpZmUgc2F0aXNmYWN0aW9uIGluIGdlbmVyYWwuIFNlY29uZCwgdGhlIGhvdXNlaG9sZCBzdHJ1Y3R1cmUgbWFrZXMgZ3JvdXAtbWVhbiBjZW50ZXJpbmcgaW1wcmFjdGljYWwuIEZvciBhIHNpbmdsZS1yZXNwb25kZW50IGhvdXNlaG9sZCwgdGhlIGhvdXNlaG9sZCBtZWFuIGlzIHRoZSByZXNwb25kZW50J3Mgb3duIHNjb3JlLCBzbyB0aGUgZ3JvdXAtbWVhbi1jZW50ZXJlZCB2YWx1ZSBpcyBleGFjdGx5IDAuIEdyb3VwLW1lYW4gY2VudGVyaW5nIHdvdWxkIHRoZXJlZm9yZSBzZXQgdGhlIHByZWRpY3RvciB0byAwIGZvciBldmVyeSBzaW5nbGUtcmVzcG9uZGVudCBob3VzZWhvbGQgYW5kIGVzdGltYXRlIHRoZSBsaWZlIHNhdGlzZmFjdGlvbiBlZmZlY3Qgb25seSBmcm9tIHRoZSBtaW5vcml0eSBvZiB0d28tcmVzcG9uZGVudCBob3VzZWhvbGRzLg0KDQpGb3IgcGVyY2VpdmVkIG5laWdoYm9yaG9vZCBzYWZldHksIGdyYW5kLW1lYW4gY2VudGVyaW5nIGlzIHRoZSBvbmx5IHNlbnNpYmxlIG9wdGlvbiBmb3IgYSBMZXZlbCAyIHZhcmlhYmxlLiBDZW50ZXJpbmcgY2hhbmdlcyBvbmx5IHRoZSBtZWFuaW5nIG9mIHRoZSBpbnRlcmNlcHQsIG5vdCB0aGUgZXN0aW1hdGVkIGVmZmVjdCBvZiBzYWZldHkgaXRzZWxmLg0KDQpGb3Igc2VsZi1yYXRlZCBoZWFsdGgsIG5vIGNlbnRlcmluZyBpcyBuZWVkZWQuIENlbnRlcmluZyB0aGUgb3V0Y29tZSB3b3VsZCBvbmx5IHNoaWZ0IHRoZSBpbnRlcmNlcHQgd2l0aG91dCBjaGFuZ2luZyBhbnkgc2xvcGUsIGFuZCBpdCB3b3VsZCBtYWtlIHRoZSBpbnRlcmNlcHQgaGFyZGVyIHRvIGludGVycHJldC4NCg0KW2xpc3QgdmFyaWFibGVzLCBjaG9pY2UsIGFuZCBqdXN0aWZpY2F0aW9uIGhlcmUuXQ0KDQpbUEVSIFZBUklBQkxFIDFwdDogY2VudGVyaW5nIGRlY2lzaW9uIG1ha2VzIHNlbnNlLCBqdXN0aWZpY2F0aW9uIGFwcHJvcHJpYXRlLiAwcHQ6IG1pc3NpbmcganVzdGlmaWNhdGlvbiBhbmQvb3IganVzdGlmaWNhdGlvbiBkb2Vzbid0IG1ha2Ugc2Vuc2UuXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQpbKipDZW50ZXIgeW91ciBwcmVkaWN0b3JzKipde3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCltBY2NvcmRpbmcgdG8geW91ciBjaG9pY2UgYWJvdmUsIGNlbnRlciB5b3VyIHR3byBwcmVkaWN0b3JzLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiNDZW50ZXIgVmFyaWFibGVzDQoNCiMgTGV2ZWwgMSBwcmVkaWN0b3I6IGdyYW5kIG1lYW4gY29tcHV0ZWQgYWNyb3NzIGFsbCBSRVNQT05ERU5UUw0KZ3JhbmRfbWVhbl9zYXRpcyA8LSBtZWFuKG15ZGF0YSRzYXRpc19maW5hbCwgbmEucm0gPSBUUlVFKQ0KDQojIExldmVsIDIgcHJlZGljdG9yOiBncmFuZCBtZWFuIGNvbXB1dGVkIGFjcm9zcyBIT1VTRUhPTERTIChvbmUgdmFsdWUgZWFjaCksDQojIHNvIHR3by1yZXNwb25kZW50IGhvdXNlaG9sZHMgYXJlIG5vdCBjb3VudGVkIHR3aWNlDQpoaF9zYWZldHkgPC0gbXlkYXRhICU+JQ0KICBncm91cF9ieShoaGlkX3N1YikgJT4lDQogIGRwbHlyOjpzdW1tYXJpc2Uoc2FmZXR5X2hoID0gZmlyc3Qoc2FmZXR5X3IpLCAuZ3JvdXBzID0gImRyb3AiKQ0KDQpncmFuZF9tZWFuX3NhZmV0eSA8LSBtZWFuKGhoX3NhZmV0eSRzYWZldHlfaGgsIG5hLnJtID0gVFJVRSkNCg0KIyBDcmVhdGUgY2VudGVyZWQgdmFyaWFibGVzDQpteWRhdGEgPC0gbXlkYXRhICU+JQ0KICBtdXRhdGUoDQogICAgc2F0aXNfZ21jICA9IHNhdGlzX2ZpbmFsIC0gZ3JhbmRfbWVhbl9zYXRpcywNCiAgICBzYWZldHlfZ21jID0gc2FmZXR5X3IgICAgLSBncmFuZF9tZWFuX3NhZmV0eQ0KICApDQoNCmNhdCgiR3JhbmQgbWVhbiwgbGlmZSBzYXRpc2ZhY3Rpb24gKGFjcm9zcyByZXNwb25kZW50cyk6IiwNCiAgICByb3VuZChncmFuZF9tZWFuX3NhdGlzLCA0KSwgIlxuIikNCmNhdCgiR3JhbmQgbWVhbiwgbmVpZ2hib3Job29kIHNhZmV0eSAoYWNyb3NzIGhvdXNlaG9sZHMpOiIsDQogICAgcm91bmQoZ3JhbmRfbWVhbl9zYWZldHksIDQpLCAiXG5cbiIpDQoNCiNWaWV3IHRoZSBmaXJzdCBmZXcgbGluZXMgb2YgZGF0YSBwbGFjaW5nIHRoZSBvbGQgYW5kIG5ldyB2YXJpYWJsZXMgc2lkZSBieSBzaWRlIHRvIGVuc3VyZSBpdCB3b3JrZWQuDQpteWRhdGEgJT4lDQogIGRwbHlyOjpzZWxlY3QoaGhpZF9zdWIsIFBOLCBzYXRpc19maW5hbCwgc2F0aXNfZ21jLCBzYWZldHlfciwgc2FmZXR5X2dtYykgJT4lDQogIGhlYWQoMTApICU+JQ0KICBrYmwoZGlnaXRzID0gMywNCiAgICAgIGNvbC5uYW1lcyA9IGMoIkhvdXNlaG9sZCIsICJQTiIsDQogICAgICAgICAgICAgICAgICAgICJMaWZlIHNhdGlzIChvcmlnaW5hbCkiLCAiTGlmZSBzYXRpcyAoY2VudGVyZWQpIiwNCiAgICAgICAgICAgICAgICAgICAgIlNhZmV0eSAob3JpZ2luYWwpIiwgIlNhZmV0eSAoY2VudGVyZWQpIiksDQogICAgICBjYXB0aW9uID0gIk9yaWdpbmFsIGFuZCBncmFuZC1tZWFuLWNlbnRlcmVkIHByZWRpY3RvcnMsIHNpZGUgYnkgc2lkZSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLCBmdWxsX3dpZHRoID0gRkFMU0UpDQoNCiMgVmVyaWZpY2F0aW9uOiBlYWNoIGNlbnRlcmVkIHZhcmlhYmxlIHNob3VsZCBoYXZlIGEgbWVhbiBvZiAwDQpjYXQoIk1lYW4gb2Ygc2F0aXNfZ21jIGFjcm9zcyByZXNwb25kZW50cyAoc2hvdWxkIGJlIDApOiIsDQogICAgcm91bmQobWVhbihteWRhdGEkc2F0aXNfZ21jKSwgMTApLCAiXG4iKQ0KY2F0KCJNZWFuIG9mIHNhZmV0eV9nbWMgYWNyb3NzIGhvdXNlaG9sZHMgKHNob3VsZCBiZSAwKToiLA0KICAgIHJvdW5kKG1lYW4oaGhfc2FmZXR5JHNhZmV0eV9oaCAtIGdyYW5kX21lYW5fc2FmZXR5KSwgMTApLCAiXG4iKQ0KYGBgDQoNCltQRVIgVkFSSUFCTEU6IDFwdDogY2VudGVyZWQgY29ycmVjdGx5IGFuZCBhcyBzcGVjaWZpZWQuIDBwdDogbm90IGNlbnRlcmVkIGNvcnJlY3RseSBhY2NvcmRpbmcgdG8gaG93IGl0IHdhcyBzcGVjaWZpZWRde3N0eWxlPSJjb2xvcjogcmVkOyJ9DQoNCiMgRGF0YSBBbmFseXNpcw0KDQojIyBVbmNvbmRpdGlvbmFsIE1vZGVsDQoNCltSdW4gYW4gdW5jb25kaXRpb25hbCBtb2RlbCBvbiB5b3VyIG91dGNvbWUuXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpbSW5jbHVkZSB0aGUgZXF1YXRpb25zICh3aXRoIGV4cGxhbmF0aW9ucykgaGVyZTpde3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCkxldmVsIDEgKHJlc3BvbmRlbnQpOg0KDQokJA0KXHRleHR7SGVhbHRofV97aWp9ID0gXGJldGFfezBqfSArIHJfe2lqfSwgXHFxdWFkIHJfe2lqfSBcc2ltIE4oMCwgXHNpZ21hXjIpDQokJA0KDQpMZXZlbCAyIChob3VzZWhvbGQpOg0KDQokJA0KXGJldGFfezBqfSA9IFxnYW1tYV97MDB9ICsgdV97MGp9LCBccXF1YWQgdV97MGp9IFxzaW0gTigwLCBcdGF1X3swMH0pDQokJA0KDQpDb21iaW5lZCAobWl4ZWQpIG1vZGVsOg0KDQokJA0KXHRleHR7SGVhbHRofV97aWp9ID0gXGdhbW1hX3swMH0gKyB1X3swan0gKyByX3tpan0NCiQkDQoNCkV4cGxhbmF0aW9uczoNCg0KLSAkXHRleHR7SGVhbHRofV97aWp9JCBpcyB0aGUgc2VsZi1yYXRlZCBoZWFsdGggb2YgcmVzcG9uZGVudCAkaSQgaW4gaG91c2Vob2xkICRqJCwgcmV2ZXJzZS1jb2RlZCBzbyB0aGF0IDEgPSBQb29yIGFuZCA1ID0gRXhjZWxsZW50IChoaWdoZXIgc2NvcmVzIGluZGljYXRlIGJldHRlciBoZWFsdGgpLg0KLSAkXGJldGFfezBqfSQgaXMgdGhlIGludGVyY2VwdCBmb3IgaG91c2Vob2xkICRqJC4gQmVjYXVzZSB0aGUgbW9kZWwgY29udGFpbnMgbm8gcHJlZGljdG9ycywgaXQgaXMgc2ltcGx5IHRoZSBtZWFuIHNlbGYtcmF0ZWQgaGVhbHRoIG9mIHRoZSByZXNwb25kZW50cyBpbiBob3VzZWhvbGQgJGokLg0KLSAkcl97aWp9JCBpcyB0aGUgTGV2ZWwgMSByZXNpZHVhbDogaG93IGZhciByZXNwb25kZW50ICRpJCdzIGhlYWx0aCByYXRpbmcgZmFsbHMgZnJvbSB0aGUgbWVhbiBvZiB0aGVpciBvd24gaG91c2Vob2xkLiBUaGVzZSByZXNpZHVhbHMgYXJlIGFzc3VtZWQgdG8gYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCBhIG1lYW4gb2YgMCBhbmQgYSB2YXJpYW5jZSBvZiAkXHNpZ21hXjIkLCB0aGUgKip3aXRoaW4taG91c2Vob2xkIHZhcmlhbmNlKiouDQotICRcZ2FtbWFfezAwfSQgaXMgdGhlIGdyYW5kIG1lYW46IHRoZSBhdmVyYWdlIHNlbGYtcmF0ZWQgaGVhbHRoIGFjcm9zcyBhbGwgaG91c2Vob2xkcy4gSXQgaXMgdGhlIG9ubHkgZml4ZWQgZWZmZWN0IGluIHRoZSBtb2RlbC4NCi0gJHVfezBqfSQgaXMgdGhlIExldmVsIDIgcmVzaWR1YWw6IGhvdyBmYXIgaG91c2Vob2xkICRqJCdzIG1lYW4gZmFsbHMgZnJvbSB0aGUgZ3JhbmQgbWVhbi4gVGhlc2UgcmVzaWR1YWxzIGFyZSBhc3N1bWVkIHRvIGJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHdpdGggYSBtZWFuIG9mIDAgYW5kIGEgdmFyaWFuY2Ugb2YgJFx0YXVfezAwfSQsIHRoZSAqKmJldHdlZW4taG91c2Vob2xkIHZhcmlhbmNlKiouDQotIFRoZSBMZXZlbCAxIGFuZCBMZXZlbCAyIHJlc2lkdWFscyBhcmUgYXNzdW1lZCB0byBiZSBpbmRlcGVuZGVudCBvZiBlYWNoIG90aGVyLg0KLSBUaGUgY29tYmluZWQgbW9kZWwgaXMgb2J0YWluZWQgYnkgc3Vic3RpdHV0aW5nIHRoZSBMZXZlbCAyIGVxdWF0aW9uIGludG8gdGhlIExldmVsIDEgZXF1YXRpb24uIEl0IHNob3dzIHRoYXQgZWFjaCByZXNwb25kZW50J3MgaGVhbHRoIHJhdGluZyBpcyBtYWRlIHVwIG9mIHRocmVlIHBhcnRzOiB0aGUgZ3JhbmQgbWVhbiAoJFxnYW1tYV97MDB9JCksIHRoZWlyIGhvdXNlaG9sZCdzIGRldmlhdGlvbiBmcm9tIHRoZSBncmFuZCBtZWFuICgkdV97MGp9JCksIGFuZCB0aGVpciBvd24gZGV2aWF0aW9uIGZyb20gdGhlaXIgaG91c2Vob2xkJ3MgbWVhbiAoJHJfe2lqfSQpLg0KLSBUaGUgcHVycG9zZSBvZiB0aGlzIG1vZGVsIGlzIHRvIGRpdmlkZSB0aGUgdG90YWwgdmFyaWFuY2UgaW4gc2VsZi1yYXRlZCBoZWFsdGggaW50byBpdHMgYmV0d2Vlbi1ob3VzZWhvbGQgKCRcdGF1X3swMH0kKSBhbmQgd2l0aGluLWhvdXNlaG9sZCAoJFxzaWdtYV4yJCkgcGFydHMuIFRoZXNlIGFyZSB1c2VkIHRvIGNvbXB1dGUgdGhlIGludHJhY2xhc3MgY29ycmVsYXRpb24sICRcdGV4dHtJQ0N9ID0gXHRhdV97MDB9IC8gKFx0YXVfezAwfSArIFxzaWdtYV4yKSQsIHdoaWNoIHNob3dzIGhvdyBtdWNoIHJlc3BvbmRlbnRzIGluIHRoZSBzYW1lIGhvdXNlaG9sZCByZXNlbWJsZSBlYWNoIG90aGVyLiBUaGUgdmFyaWFuY2UgY29tcG9uZW50cyBmcm9tIHRoaXMgbW9kZWwgYWxzbyBzZXJ2ZSBhcyB0aGUgYmFzZWxpbmUgZm9yIGp1ZGdpbmcgaG93IG11Y2ggdmFyaWFuY2UgdGhlIHByZWRpY3RvcnMgYWRkZWQgaW4gbGF0ZXIgbW9kZWxzIGV4cGxhaW4uDQoNClsycHQ6IGVxdWF0aW9ucyBjb3JyZWN0LiAxcHQ6IGVxdWF0aW9ucyBtb3N0bHkgY29ycmVjdC4gMHB0OiBtYW55IGVycm9ycyBpbiBlcXVhdGlvbnNde3N0eWxlPSJjb2xvcjogcmVkOyJ9Lg0KDQpbMnB0OiBleHBsYW5hdGlvbnMgY29ycmVjdC4gMXB0OiBleHBsYW5hdGlvbnMgbW9zdGx5IGNvcnJlY3QuIDBwdDogbWFueSBlcnJvcnMgaW4gZXhwbGFuYXRpb25zXXtzdHlsZT0iY29sb3I6IHJlZDsifS4NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiMgVW5jb25kaXRpb25hbCAoaW50ZXJjZXB0LW9ubHkpIG1vZGVsDQptb2RlbDAgPC0gbG1lcihoZWFsdGhfciB+IDEgKyAoMSB8IGhoaWRfc3ViKSwgZGF0YSA9IG15ZGF0YSwgUkVNTCA9IFRSVUUpDQoNCnN1bW1hcnkobW9kZWwwKQ0KDQojIFZhcmlhbmNlIGNvbXBvbmVudHMNCnZjX20wIDwtIGFzLmRhdGEuZnJhbWUoVmFyQ29ycihtb2RlbDApKQ0KdGF1X20wICAgPC0gdmNfbTAkdmNvdlt2Y19tMCRncnAgPT0gImhoaWRfc3ViIl0gICAjIGJldHdlZW4taG91c2Vob2xkDQpzaWdtYV9tMCA8LSB2Y19tMCR2Y292W3ZjX20wJGdycCA9PSAiUmVzaWR1YWwiXSAgICMgd2l0aGluLWhvdXNlaG9sZA0KSUNDX20wICAgPC0gdGF1X20wIC8gKHRhdV9tMCArIHNpZ21hX20wKQ0KDQpkYXRhLmZyYW1lKA0KICBDb21wb25lbnQgPSBjKCJCZXR3ZWVuLWhvdXNlaG9sZCAoz4QwMCkiLCAiV2l0aGluLWhvdXNlaG9sZCAoz4PCsikiLCAiSUNDIiksDQogIEVzdGltYXRlICA9IGModGF1X20wLCBzaWdtYV9tMCwgSUNDX20wKQ0KKSAlPiUNCiAga2JsKGRpZ2l0cyA9IDQsIGNhcHRpb24gPSAiVW5jb25kaXRpb25hbCBtb2RlbDogdmFyaWFuY2UgY29tcG9uZW50cyBhbmQgSUNDIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkNCg0KIyA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIGdyYW5kIG1lYW4gKGZpeGVkIGludGVyY2VwdCkNCmNvbmZpbnQobW9kZWwwLCBwYXJtID0gIihJbnRlcmNlcHQpIiwgbWV0aG9kID0gIldhbGQiKQ0KDQojIE1vZGVsIGZpdCAoYmFzZWxpbmUgZm9yIGxhdGVyIG1vZGVsIGNvbXBhcmlzb25zKQ0KY2F0KCJBSUM6Iiwgcm91bmQoQUlDKG1vZGVsMCksIDIpLCAiIHwgQklDOiIsIHJvdW5kKEJJQyhtb2RlbDApLCAyKSwgIlxuIikNCmBgYA0KDQpbKlN1bW1hcnkqXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpUaGUgdW5jb25kaXRpb25hbCBtb2RlbCB3YXMgZXN0aW1hdGVkIG9uIDE0LDU0MSByZXNwb25kZW50cyBuZXN0ZWQgd2l0aGluIDExLDAzMSBob3VzZWhvbGRzLCBhbiBhdmVyYWdlIG9mIGFib3V0IDEuMzIgcmVzcG9uZGVudHMgcGVyIGhvdXNlaG9sZC4NCg0KKipGaXhlZCBlZmZlY3QuKiogVGhlIGVzdGltYXRlZCBncmFuZCBtZWFuIG9mIHNlbGYtcmF0ZWQgaGVhbHRoIHdhcyAkXGdhbW1hX3swMH0kID0gMy4wNyAoKlNFKiA9IDAuMDA5LCAqdCooMTAsMjEwKSA9IDM0My4zLCAqcCogPCAuMDAxLCA5NSUgQ0kgWzMuMDUsIDMuMDldKS4gQmVjYXVzZSBzZWxmLXJhdGVkIGhlYWx0aCB3YXMgcmV2ZXJzZS1jb2RlZCBzbyB0aGF0IDEgPSBQb29yIGFuZCA1ID0gRXhjZWxsZW50LCB0aGlzIG1lYW5zIHRoZSBhdmVyYWdlIHBlcnNvbiBpbiB0aGUgc2FtcGxlIHJhdGVkIHRoZWlyIGhlYWx0aCBhdCBhbG1vc3QgZXhhY3RseSAiR29vZC4iIFRoZSBuYXJyb3cgY29uZmlkZW5jZSBpbnRlcnZhbCByZWZsZWN0cyB0aGUgbGFyZ2Ugc2FtcGxlLiBUaGUgc2lnbmlmaWNhbmNlIHRlc3QgIGluZGljYXRlcyB0aGF0IHRoZSBtZWFuIGRpZmZlcnMgZnJvbSAwLiBUaGUgbW9kZWwtYmFzZWQgZ3JhbmQgbWVhbiAoMy4wNykgaXMgdmVyeSBzbGlnaHRseSBsb3dlciB0aGFuIHRoZSByYXcgc2FtcGxlIG1lYW4gKDMuMDgpIGJlY2F1c2UgdGhlIG11bHRpbGV2ZWwgbW9kZWwgd2VpZ2h0cyBob3VzZWhvbGRzIHJhdGhlciB0aGFuIHRyZWF0aW5nIGV2ZXJ5IHJlc3BvbmRlbnQgYXMgZnVsbHkgaW5kZXBlbmRlbnQuDQoNCioqUmFuZG9tIGVmZmVjdHMuKiogVGhlIGJldHdlZW4taG91c2Vob2xkIHZhcmlhbmNlIHdhcyAkXHRhdV97MDB9JCA9IDAuMjg4ICgqU0QqID0gMC41MzcpLCBhbmQgdGhlIHdpdGhpbi1ob3VzZWhvbGQgdmFyaWFuY2Ugd2FzICRcc2lnbWFeMiQgPSAwLjc1MiAoKlNEKiA9IDAuODY3KS4gVGhlIHJlc3VsdGluZyBJQ0Mgb2YgLjI4IGluZGljYXRlcyB0aGF0IGFwcHJveGltYXRlbHkgKioyNy43JSBvZiB0aGUgdmFyaWFuY2UgaW4gc2VsZi1yYXRlZCBoZWFsdGggbGllcyBiZXR3ZWVuIGhvdXNlaG9sZHMqKiBhbmQgKio3Mi4zJSBsaWVzIHdpdGhpbiBob3VzZWhvbGRzKiouIEluIG90aGVyIHdvcmRzLCByZXNwb25kZW50cyBsaXZpbmcgaW4gdGhlIHNhbWUgaG91c2Vob2xkIGFyZSBub3RpY2VhYmx5IG1vcmUgc2ltaWxhciBpbiB0aGVpciBzZWxmLXJhdGVkIGhlYWx0aCB0aGFuIHR3byByYW5kb21seSBjaG9zZW4gcmVzcG9uZGVudHMsIGJ1dCBtb3N0IG9mIHRoZSB2YXJpYXRpb24gaXMgc3RpbGwgYmV0d2VlbiBpbmRpdmlkdWFscyB3aXRoaW4gdGhlIHNhbWUgaG91c2Vob2xkLg0KDQpUaGlzIG1vZGVsIHNlcnZlcyBhcyB0aGUgYmFzZWxpbmUgZm9yIGFsbCBsYXRlciBtb2RlbHMuIEl0cyB2YXJpYW5jZSBjb21wb25lbnRzICgkXHRhdV97MDB9JCA9IDAuMjg4LCAkXHNpZ21hXjIkID0gMC43NTIpIHdpbGwgYmUgdXNlZCB0byBjYWxjdWxhdGUgaG93IG11Y2ggdmFyaWFuY2UgaXMgZXhwbGFpbmVkIGJ5IGxpZmUgc2F0aXNmYWN0aW9uIGFuZCBuZWlnaGJvcmhvb2Qgc2FmZXR5LCBhbmQgaXRzIGZpdCBzdGF0aXN0aWNzIChBSUMgPSA0MSw1NzMuOTsgQklDID0gNDEsNTk2LjcpIHByb3ZpZGUgdGhlIHJlZmVyZW5jZSBwb2ludCBmb3IgbW9kZWwgY29tcGFyaXNvbi4NCg0KWzJwdDogc3VtbWFyeSBtYWtlcyBzZW5zZSwgYWNjdXJhdGUgYW5kIGNvbXBsZXRlLiAxcHQ6IHNvbWUgZXJyb3JzIG9yIG1pc3NpbmcgaW5mb3JtYXRpb24uIDBwdDogbWFueSBlcnJvcnMgb3IgbWlzc2luZyBpbmZvcm1hdGlvbiAoZS5nLiwgb3ZlciBoYWxmIHByb2JsZW1hdGljKS5de3N0eWxlPSJjb2xvcjogcmVkOyJ9DQoNCiMjIEZpeGVkIGVmZmVjdCBvbmx5DQoNCltJbmNsdWRlIGEgbGV2ZWwtMSBwcmVkaWN0b3IsIGJ1dCBvbmx5IGFzIGEgZml4ZWQgZWZmZWN0Ll17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW0luY2x1ZGUgdGhlIGVxdWF0aW9ucyAod2l0aCBleHBsYW5hdGlvbnMpIGhlcmU6XXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpMZXZlbCAxIChyZXNwb25kZW50KToNCg0KJCQNClx0ZXh0e0hlYWx0aH1fe2lqfSA9IFxiZXRhX3swan0gKyBcYmV0YV97MWp9KFx0ZXh0e0xpZmVTYXR9X3tpan0gLSBcb3ZlcmxpbmV7XHRleHR7TGlmZVNhdH19X3suLn0pICsgcl97aWp9LCBccXF1YWQgcl97aWp9IFxzaW0gTigwLCBcc2lnbWFeMikNCiQkDQoNCioqTGV2ZWwgMiAoaG91c2Vob2xkKToqKg0KDQokJA0KXGJldGFfezBqfSA9IFxnYW1tYV97MDB9ICsgdV97MGp9LCBccXF1YWQgdV97MGp9IFxzaW0gTigwLCBcdGF1X3swMH0pDQokJA0KDQokJA0KXGJldGFfezFqfSA9IFxnYW1tYV97MTB9DQokJA0KDQoqKkNvbWJpbmVkIChtaXhlZCkgbW9kZWw6KioNCg0KJCQNClx0ZXh0e0hlYWx0aH1fe2lqfSA9IFxnYW1tYV97MDB9ICsgXGdhbW1hX3sxMH0oXHRleHR7TGlmZVNhdH1fe2lqfSAtIFxvdmVybGluZXtcdGV4dHtMaWZlU2F0fX1fey4ufSkgKyB1X3swan0gKyByX3tpan0NCiQkDQoNCkV4cGxhbmF0aW9uczoNCg0KLSAkXHRleHR7SGVhbHRofV97aWp9JCBpcyB0aGUgc2VsZi1yYXRlZCBoZWFsdGggb2YgcmVzcG9uZGVudCAkaSQgaW4gaG91c2Vob2xkICRqJCAoMSA9IFBvb3IgdG8gNSA9IEV4Y2VsbGVudCkuDQotICQoXHRleHR7TGlmZVNhdH1fe2lqfSAtIFxvdmVybGluZXtcdGV4dHtMaWZlU2F0fX1fey4ufSkkIGlzIHJlc3BvbmRlbnQgJGkkJ3MgZ3JhbmQtbWVhbi1jZW50ZXJlZCBsaWZlIHNhdGlzZmFjdGlvbjogdGhlaXIgd2luc29yaXplZCBsaWZlIHNhdGlzZmFjdGlvbiBzY29yZSAoaGlnaGVyID0gbW9yZSBzYXRpc2ZpZWQpIG1pbnVzIHRoZSBtZWFuIGFjcm9zcyBhbGwgcmVzcG9uZGVudHMuIEEgdmFsdWUgb2YgMCByZXByZXNlbnRzIGEgcmVzcG9uZGVudCB3aXRoIGF2ZXJhZ2UgbGlmZSBzYXRpc2ZhY3Rpb24uDQotICRcYmV0YV97MGp9JCBpcyB0aGUgaW50ZXJjZXB0IGZvciBob3VzZWhvbGQgJGokOiB0aGUgZXhwZWN0ZWQgc2VsZi1yYXRlZCBoZWFsdGggb2YgYSByZXNwb25kZW50IGluIGhvdXNlaG9sZCAkaiQgd2hvc2UgbGlmZSBzYXRpc2ZhY3Rpb24gaXMgYXQgdGhlIHNhbXBsZSBhdmVyYWdlLg0KLSAkXGJldGFfezFqfSQgaXMgdGhlIHNsb3BlIGZvciBob3VzZWhvbGQuDQoNClsycHQ6IGVxdWF0aW9ucyBjb3JyZWN0IDFwdDogZXF1YXRpb25zIG1vc3RseSBjb3JyZWN0IDBwdDogbWFueSBlcnJvcnMgaW4gZXF1YXRpb25zXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQpbMnB0OiBleHBsYW5hdGlvbnMgY29ycmVjdCAxcHQ6IGV4cGxhbmF0aW9ucyBtb3N0bHkgY29ycmVjdCAwcHQ6IG1hbnkgZXJyb3JzIGluIGV4cGxhbmF0aW9uc117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQojIEZpeGVkLWVmZmVjdC1vbmx5IG1vZGVsOiBsaWZlIHNhdGlzZmFjdGlvbiAoZ3JhbmQtbWVhbiBjZW50ZXJlZCkgd2l0aCBhDQojIHJhbmRvbSBpbnRlcmNlcHQgZm9yIGhvdXNlaG9sZCBidXQgYSBGSVhFRCBzbG9wZQ0KbW9kZWwxIDwtIGxtZXIoaGVhbHRoX3IgfiBzYXRpc19nbWMgKyAoMSB8IGhoaWRfc3ViKSwgZGF0YSA9IG15ZGF0YSwgUkVNTCA9IFRSVUUpDQoNCnN1bW1hcnkobW9kZWwxKQ0KDQojIDk1JSBjb25maWRlbmNlIGludGVydmFscyBmb3IgdGhlIGZpeGVkIGVmZmVjdHMNCmNvbmZpbnQobW9kZWwxLCBwYXJtID0gYygiKEludGVyY2VwdCkiLCAic2F0aXNfZ21jIiksIG1ldGhvZCA9ICJXYWxkIikNCg0KIyBWYXJpYW5jZSBjb21wb25lbnRzDQp2Y19tMSA8LSBhcy5kYXRhLmZyYW1lKFZhckNvcnIobW9kZWwxKSkNCnRhdV9tMSAgIDwtIHZjX20xJHZjb3ZbdmNfbTEkZ3JwID09ICJoaGlkX3N1YiJdICAgIyBiZXR3ZWVuLWhvdXNlaG9sZA0Kc2lnbWFfbTEgPC0gdmNfbTEkdmNvdlt2Y19tMSRncnAgPT0gIlJlc2lkdWFsIl0gICAjIHdpdGhpbi1ob3VzZWhvbGQNCg0KIyBQcm9wb3J0aW9uYWwgcmVkdWN0aW9uIGluIHZhcmlhbmNlIHJlbGF0aXZlIHRvIHRoZSB1bmNvbmRpdGlvbmFsIG1vZGVsDQojICh1c2VzIHRhdV9tMCBhbmQgc2lnbWFfbTAgZnJvbSB0aGUgdW5jb25kaXRpb25hbCBtb2RlbCBjaHVuaykNCmRhdGEuZnJhbWUoDQogIENvbXBvbmVudCAgID0gYygiQmV0d2Vlbi1ob3VzZWhvbGQgKM+EMDApIiwgIldpdGhpbi1ob3VzZWhvbGQgKM+DwrIpIiksDQogIFVuY29uZGl0aW9uYWwgPSBjKHRhdV9tMCwgc2lnbWFfbTApLA0KICBNb2RlbF8xICAgICAgID0gYyh0YXVfbTEsIHNpZ21hX20xKSwNCiAgUmVkdWN0aW9uX3BjdCA9IGMoKHRhdV9tMCAtIHRhdV9tMSkgLyB0YXVfbTAgKiAxMDAsDQogICAgICAgICAgICAgICAgICAgIChzaWdtYV9tMCAtIHNpZ21hX20xKSAvIHNpZ21hX20wICogMTAwKQ0KKSAlPiUNCiAga2JsKGRpZ2l0cyA9IGMoMCwgNCwgNCwgMSksDQogICAgICBjb2wubmFtZXMgPSBjKCJDb21wb25lbnQiLCAiVW5jb25kaXRpb25hbCBtb2RlbCIsICJNb2RlbCAxIiwNCiAgICAgICAgICAgICAgICAgICAgIiUgcmVkdWN0aW9uIiksDQogICAgICBjYXB0aW9uID0gIlZhcmlhbmNlIGV4cGxhaW5lZCBieSBsaWZlIHNhdGlzZmFjdGlvbiIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLCBmdWxsX3dpZHRoID0gRkFMU0UpDQoNCiMgTGlrZWxpaG9vZCByYXRpbyB0ZXN0IHZzLiB1bmNvbmRpdGlvbmFsIG1vZGVsLg0KIyBNb2RlbHMgZGlmZmVyaW5nIGluIEZJWEVEIGVmZmVjdHMgbXVzdCBiZSBjb21wYXJlZCB3aXRoIE1MLCBub3QgUkVNTCwNCiMgc28gYm90aCBhcmUgcmVmaXQgd2l0aCBSRU1MID0gRkFMU0UgZm9yIHRoaXMgdGVzdCBvbmx5Lg0KbW9kZWwwX21sIDwtIGxtZXIoaGVhbHRoX3IgfiAxICsgKDEgfCBoaGlkX3N1YiksIGRhdGEgPSBteWRhdGEsIFJFTUwgPSBGQUxTRSkNCm1vZGVsMV9tbCA8LSBsbWVyKGhlYWx0aF9yIH4gc2F0aXNfZ21jICsgKDEgfCBoaGlkX3N1YiksIGRhdGEgPSBteWRhdGEsIFJFTUwgPSBGQUxTRSkNCmFub3ZhKG1vZGVsMF9tbCwgbW9kZWwxX21sKQ0KDQojIEZpdCBzdGF0aXN0aWNzDQpjYXQoIkFJQzoiLCByb3VuZChBSUMobW9kZWwxKSwgMiksICIgfCBCSUM6Iiwgcm91bmQoQklDKG1vZGVsMSksIDIpLCAiXG4iKQ0KDQoNCmBgYA0KDQpbKlN1bW1hcnkqXXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQpbUmVwb3J0IHRoZSBmaW5kaW5ncyAoaW5jbHVkaW5nIGludGVycHJldGF0aW9uIHdpdGggcmVnYXJkIHRvIHVuaXRzIG9mIGFuYWx5c2lzKSBmb3IgdGhlIGZpeGVkIGVmZmVjdCBvZiB5b3VyIHByZWRpY3Rvci5de3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNClRoZSBmaXhlZCBlZmZlY3Qgb2YgbGlmZSBzYXRpc2ZhY3Rpb24gd2FzICRcZ2FtbWFfezEwfSQgPSAwLjQyMSAoKlNFKiA9IDAuMDEwLCAqdCooMTQsNDkwKSA9IDQzLjMxLCAqcCogPCAuMDAxLCA5NSUgQ0kgWzAuNDAyLCAwLjQ0MF0pLiBUaGUgZWZmZWN0IGlzIHBvc2l0aXZlIGFuZCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LCBwcm92aWRpbmcgaW5pdGlhbCBzdXBwb3J0IGZvciBIeXBvdGhlc2lzIDE6IHJlc3BvbmRlbnRzIHdpdGggaGlnaGVyIGxpZmUgc2F0aXNmYWN0aW9uIHJlcG9ydCBiZXR0ZXIgc2VsZi1yYXRlZCBoZWFsdGguDQoNCkluIHRoZSB1bml0cyBvZiB0aGUgdmFyaWFibGVzLCAqKmVhY2ggb25lLWNhdGVnb3J5IGluY3JlYXNlIGluIGxpZmUgc2F0aXNmYWN0aW9uIChmb3IgZXhhbXBsZSwgbW92aW5nIGZyb20gInNvbWV3aGF0IHNhdGlzZmllZCIgdG8gInZlcnkgc2F0aXNmaWVkIikgaXMgYXNzb2NpYXRlZCB3aXRoIGEgMC40Mi1wb2ludCBpbmNyZWFzZSBpbiBzZWxmLXJhdGVkIGhlYWx0aCoqIG9uIHRoZSBmaXZlLXBvaW50IHNjYWxlLiBCZWNhdXNlIHRoZSB3aW5zb3JpemVkIGxpZmUgc2F0aXNmYWN0aW9uIHZhcmlhYmxlIHJhbmdlcyBmcm9tIDIgKCJub3QgdmVyeSBzYXRpc2ZpZWQiKSB0byA1ICgiY29tcGxldGVseSBzYXRpc2ZpZWQiKSwgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgbGVhc3QgYW5kIG1vc3Qgc2F0aXNmaWVkIHJlc3BvbmRlbnRzIHNwYW5zIHRocmVlIGNhdGVnb3JpZXMsIGNvcnJlc3BvbmRpbmcgdG8gYW4gZXhwZWN0ZWQgZGlmZmVyZW5jZSBvZiBhYm91dCAzIMOXIDAuNDIgPSAqKjEuMjYgcG9pbnRzKiogaW4gc2VsZi1yYXRlZCBoZWFsdGguIFJlbGF0aXZlIHRvIHRoZSBzcHJlYWQgb2YgdGhlIG91dGNvbWUgKCpTRCogPSAxLjAyKSwgYSBvbmUtY2F0ZWdvcnkgaW5jcmVhc2UgaW4gbGlmZSBzYXRpc2ZhY3Rpb24gY29ycmVzcG9uZHMgdG8gcm91Z2hseSAwLjQxIHN0YW5kYXJkIGRldmlhdGlvbnMgb2Ygc2VsZi1yYXRlZCBoZWFsdGgsIGEgc3Vic3RhbnRpYWwgYXNzb2NpYXRpb24uDQoNCkFkZGluZyBsaWZlIHNhdGlzZmFjdGlvbiBhbHNvIHJlZHVjZWQgdGhlIHVuZXhwbGFpbmVkIHZhcmlhbmNlLiBDb21wYXJlZCB3aXRoIHRoZSB1bmNvbmRpdGlvbmFsIG1vZGVsLCB0aGUgYmV0d2Vlbi1ob3VzZWhvbGQgdmFyaWFuY2UgZGVjcmVhc2VkIGZyb20gMC4yODggdG8gMC4yMDIgKGEgKioyOS45JSByZWR1Y3Rpb24qKikgYW5kIHRoZSB3aXRoaW4taG91c2Vob2xkIHZhcmlhbmNlIGRlY3JlYXNlZCBmcm9tIDAuNzUyIHRvIDAuNzE0IChhICoqNS4xJSByZWR1Y3Rpb24qKiksIGZvciBhYm91dCBhIDEyLjAlIHJlZHVjdGlvbiBpbiB0b3RhbCB2YXJpYW5jZS4gVGhlIGxhcmdlciByZWR1Y3Rpb24gYXQgdGhlIGhvdXNlaG9sZCBsZXZlbCBpcyBjb25zaXN0ZW50IHdpdGggdGhlIGVhcmxpZXIgZmluZGluZyB0aGF0IGxpZmUgc2F0aXNmYWN0aW9uIGl0c2VsZiBjbHVzdGVycyB3aXRoaW4gaG91c2Vob2xkcyAoSUNDID0gLjMxKTogaG91c2Vob2xkcyB3aG9zZSBtZW1iZXJzIGFyZSBtb3JlIHNhdGlzZmllZCBhbHNvIHRlbmQgdG8gaGF2ZSBiZXR0ZXIgYXZlcmFnZSBoZWFsdGguIEJlY2F1c2UgbGlmZSBzYXRpc2ZhY3Rpb24gd2FzIGdyYW5kLW1lYW4gY2VudGVyZWQsICRcZ2FtbWFfezEwfSQgcmVmbGVjdHMgYSBibGVuZCBvZiB0aGVzZSBiZXR3ZWVuLWhvdXNlaG9sZCBkaWZmZXJlbmNlcyBhbmQgZGlmZmVyZW5jZXMgYmV0d2VlbiBwZW9wbGUgd2l0aGluIHRoZSBzYW1lIGhvdXNlaG9sZCwgcmF0aGVyIHRoYW4gYSBwdXJlbHkgd2l0aGluLWhvdXNlaG9sZCBlZmZlY3QuDQoNCkJlY2F1c2UgdGhlIGRhdGEgYXJlIGNyb3NzLXNlY3Rpb25hbCBhbmQgYm90aCB2YXJpYWJsZXMgYXJlIHN1YmplY3RpdmUgc2VsZi1yZXBvcnRzLCB0aGlzIGNvZWZmaWNpZW50IGRlc2NyaWJlcyBhbiBhc3NvY2lhdGlvbiwgbm90IGEgY2F1c2FsIGVmZmVjdDsgcGFydCBvZiBpdCBtYXkgcmVmbGVjdCBhIHNoYXJlZCB0ZW5kZW5jeSB0byByYXRlIG9uZXNlbGYgcG9zaXRpdmVseSBvciBuZWdhdGl2ZWx5IG9uIGJvdGggbWVhc3VyZXMuDQoNCltSZXBvcnQgdGhlIGZpbmRpbmdzIChpbmNsdWRpbmcgaW50ZXJwcmV0YXRpb24gd2l0aCByZWdhcmQgdG8gdW5pdHMgb2YgYW5hbHlzaXMpIGZvciB5b3VyIGludGVyY2VwdCB0ZXJtLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KVGhlIGludGVyY2VwdCB3YXMgJFxnYW1tYV97MDB9JCA9IDMuMDggKCpTRSogPSAwLjAwOCwgKnQqKDEwLDEyMCkgPSAzNzAuNDEsICpwKiA8IC4wMDEsIDk1JSBDSSBbMy4wNiwgMy4wOV0pLiBCZWNhdXNlIGxpZmUgc2F0aXNmYWN0aW9uIHdhcyBncmFuZC1tZWFuIGNlbnRlcmVkLCBhIHZhbHVlIG9mIDAgb24gdGhlIHByZWRpY3RvciByZXByZXNlbnRzIGEgcmVzcG9uZGVudCB3aXRoIGF2ZXJhZ2UgbGlmZSBzYXRpc2ZhY3Rpb24uIFRoZSBpbnRlcmNlcHQgaXMgdGhlcmVmb3JlICoqdGhlIGV4cGVjdGVkIHNlbGYtcmF0ZWQgaGVhbHRoIG9mIGEgcmVzcG9uZGVudCB3aXRoIGF2ZXJhZ2UgbGlmZSBzYXRpc2ZhY3Rpb24qKiwgd2hpY2ggaXMgYWJvdXQgMy4wOCBvbiB0aGUgZml2ZS1wb2ludCBzY2FsZSDigJQgYWxtb3N0IGV4YWN0bHkgIkdvb2QiIGhlYWx0aC4NCg0KVGhlIGludGVyY2VwdCBpcyBlc3NlbnRpYWxseSB1bmNoYW5nZWQgZnJvbSB0aGUgdW5jb25kaXRpb25hbCBtb2RlbCAoMy4wNykuIFRoaXMgaXMgZXhwZWN0ZWQ6IGNlbnRlcmluZyB0aGUgcHJlZGljdG9yIGF0IGl0cyBtZWFuIHBsYWNlcyB0aGUgaW50ZXJjZXB0IGF0IGFwcHJveGltYXRlbHkgdGhlIG92ZXJhbGwgbWVhbiBvZiB0aGUgb3V0Y29tZSwgc28gYWRkaW5nIGEgY2VudGVyZWQgcHJlZGljdG9yIGNoYW5nZXMgdGhlIHNsb3BlIGluZm9ybWF0aW9uIGluIHRoZSBtb2RlbCBidXQgbm90IHRoZSBiYXNlbGluZSBsZXZlbC4gVGhlIHZlcnkgc21hbGwgc2hpZnQgKDAuMDA4IHBvaW50cykgYXJpc2VzIGJlY2F1c2UgdGhlIGdyYW5kIG1lYW4gdXNlZCBmb3IgY2VudGVyaW5nIHdhcyBjb21wdXRlZCBhY3Jvc3MgcmVzcG9uZGVudHMsIHdoaWxlIHRoZSBtdWx0aWxldmVsIG1vZGVsIHdlaWdodHMgaG91c2Vob2xkcywgc28gdGhlIHR3byBhdmVyYWdlcyBkaWZmZXIgc2xpZ2h0bHkuIFRoZSBuZWFyLXplcm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW50ZXJjZXB0IGFuZCBzbG9wZSBlc3RpbWF0ZXMgKCpyKiA9IC4wMTYpIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBjZW50ZXJpbmcgd29ya2VkIGFzIGludGVuZGVkLCBzZXBhcmF0aW5nIHRoZSBlc3RpbWF0ZSBvZiB0aGUgYmFzZWxpbmUgbGV2ZWwgZnJvbSB0aGUgZXN0aW1hdGUgb2YgdGhlIGxpZmUgc2F0aXNmYWN0aW9uIGVmZmVjdC4gDQoNClsycHQ6IHN1bW1hcnkgbWFrZXMgc2Vuc2UsIGFjY3VyYXRlIGFuZCBjb21wbGV0ZSAxcHQ6IHNvbWUgZXJyb3JzIG9yIG1pc3NpbmcgaW5mb3JtYXRpb24gMHB0OiBtYW55IGVycm9ycyBvciBtaXNzaW5nIGluZm9ybWF0aW9uIChlLmcuLCBvdmVyIGhhbGYgcHJvYmxlbWF0aWMpXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQojIyBSYW5kb20gU2xvcGUNCg0KW05vdyBpbmNsdWRlIHRoZSByYW5kb20gZWZmZWN0IGZvciB5b3VyIGxldmVsIDEgcHJlZGljdG9yLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW0luY2x1ZGUgdGhlIGVxdWF0aW9ucyAod2l0aCBleHBsYW5hdGlvbnMpIGhlcmU6XXtzdHlsZT0iY29sb3I6IHB1cnBsZTsifQ0KDQoqKkxldmVsIDEgKHJlc3BvbmRlbnQpOioqDQoNCiQkDQpcdGV4dHtIZWFsdGh9X3tpan0gPSBcYmV0YV97MGp9ICsgXGJldGFfezFqfShcdGV4dHtMaWZlU2F0fV97aWp9IC0gXG92ZXJsaW5le1x0ZXh0e0xpZmVTYXR9fV97Li59KSArIHJfe2lqfSwgXHFxdWFkIHJfe2lqfSBcc2ltIE4oMCwgXHNpZ21hXjIpDQokJA0KDQoqKkxldmVsIDIgKGhvdXNlaG9sZCk6KioNCg0KJCQNClxiZXRhX3swan0gPSBcZ2FtbWFfezAwfSArIHVfezBqfQ0KJCQNCg0KJCQNClxiZXRhX3sxan0gPSBcZ2FtbWFfezEwfSArIHVfezFqfQ0KJCQNCg0KKipDb21iaW5lZCAobWl4ZWQpIG1vZGVsOioqDQoNCiQkDQpcdGV4dHtIZWFsdGh9X3tpan0gPSBcZ2FtbWFfezAwfSArIFxnYW1tYV97MTB9KFx0ZXh0e0xpZmVTYXR9X3tpan0gLSBcb3ZlcmxpbmV7XHRleHR7TGlmZVNhdH19X3suLn0pICsgdV97MGp9ICsgdV97MWp9KFx0ZXh0e0xpZmVTYXR9X3tpan0gLSBcb3ZlcmxpbmV7XHRleHR7TGlmZVNhdH19X3suLn0pICsgcl97aWp9DQokJA0KDQoqKkV4cGxhbmF0aW9uczoqKg0KDQotIFRoZSBMZXZlbCAxIGVxdWF0aW9uIGlzIHVuY2hhbmdlZCBmcm9tIHRoZSBwcmV2aW91cyBtb2RlbDogc2VsZi1yYXRlZCBoZWFsdGggaXMgcHJlZGljdGVkIGJ5IGEgaG91c2Vob2xkLXNwZWNpZmljIGludGVyY2VwdCAoJFxiZXRhX3swan0kKSwgYSBob3VzZWhvbGQtc3BlY2lmaWMgc2xvcGUgZm9yIGdyYW5kLW1lYW4tY2VudGVyZWQgbGlmZSBzYXRpc2ZhY3Rpb24gKCRcYmV0YV97MWp9JCksIGFuZCBhIHJlc3BvbmRlbnQtbGV2ZWwgcmVzaWR1YWwgKCRyX3tpan0kKSB3aXRoIHZhcmlhbmNlICRcc2lnbWFeMiQuDQotIFRoZSBvbmx5IGNoYW5nZSBpcyBpbiB0aGUgc2Vjb25kIExldmVsIDIgZXF1YXRpb24uIEluIHRoZSBwcmV2aW91cyBtb2RlbCB0aGUgc2xvcGUgd2FzIGZpeGVkICgkXGJldGFfezFqfSA9IFxnYW1tYV97MTB9JCkuIEhlcmUgYSByYW5kb20gdGVybSwgJHVfezFqfSQsIGlzIGFkZGVkLCBzbyAqKnRoZSBzbG9wZSBpcyBub3cgYWxsb3dlZCB0byB2YXJ5IGFjcm9zcyBob3VzZWhvbGRzKiouIFRoZSBtb2RlbCBubyBsb25nZXIgYXNzdW1lcyB0aGF0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBsaWZlIHNhdGlzZmFjdGlvbiBhbmQgc2VsZi1yYXRlZCBoZWFsdGggaXMNCi0gKipJZGVudGlmaWNhdGlvbiBwcm9ibGVtIGluIHRoZXNlIGRhdGE6KiogZXN0aW1hdGluZyBhIHJhbmRvbSBzbG9wZSBnaXZlcyBlYWNoIGhvdXNlaG9sZCB0d28gcmFuZG9tIGVmZmVjdHMgKCR1X3swan0kIGFuZCAkdV97MWp9JCkuIFdpdGggMTQsNTQxIHJlc3BvbmRlbnRzIGluIDExLDAzMSBob3VzZWhvbGRzLCB0aGlzIG1vZGVsIHJlcXVpcmVzIDIyLDA2MiByYW5kb20gZWZmZWN0cyDigJQgbW9yZSB0aGFuIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIOKAlCBzbyBsbWU0IHJlZnVzZXMgdG8gZml0IGl0IHVuZGVyIGl0cyBkZWZhdWx0IHNldHRpbmdzIGJlY2F1c2UgdGhlIHJhbmRvbSBlZmZlY3RzIGFuZCByZXNpZHVhbCB2YXJpYW5jZSBjYW5ub3QgYmUgc2VwYXJhdGVseSBpZGVudGlmaWVkLiBNb3N0IGhvdXNlaG9sZHMgY29udGFpbiBhIHNpbmdsZSByZXNwb25kZW50IGFuZCBwcm92aWRlIG5vIGluZm9ybWF0aW9uIGFib3V0IHRoZWlyIG93biBzbG9wZSwgYW5kIGV2ZW4gYSB0d28tcmVzcG9uZGVudCBob3VzZWhvbGQgc3VwcGxpZXMgb25seSBhcyBtYW55IG9ic2VydmF0aW9ucyBhcyByYW5kb20gZWZmZWN0cy4gVGhlIG1vZGVsIHdhcyB0aGVyZWZvcmUgZml0IHdpdGggdGhpcyBjaGVjayBvdmVycmlkZGVuIHNvbGVseSB0byBpbnNwZWN0IHRoZSBlc3RpbWF0ZXM7IHRoZSByZXN1bHRzIGFyZSBpbnRlcnByZXRlZCBhcyBldmlkZW5jZSBhYm91dCB3aGV0aGVyIGEgcmFuZG9tIHNsb3BlIGlzIHN1cHBvcnRhYmxlIGluIHRoZXNlIGRhdGEsIG5vdCBhcyBhIHRydXN0d29ydGh5IGVzdGltYXRlIG9mIHNsb3BlIHZhcmlhdGlvbi4NCg0KWzJwdDogZXF1YXRpb25zIGNvcnJlY3QuIDFwdDogZXF1YXRpb25zIG1vc3RseSBjb3JyZWN0LiAwcHQ6IG1hbnkgZXJyb3JzIGluIGVxdWF0aW9uc117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KWzJwdDogZXhwbGFuYXRpb25zIGNvcnJlY3QuIDFwdDogZXhwbGFuYXRpb25zIG1vc3RseSBjb3JyZWN0LiAwcHQ6IG1hbnkgZXJyb3JzIGluIGV4cGxhbmF0aW9uc117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiMgMS4gQXR0ZW1wdCB0aGUgcmFuZG9tIHNsb3BlIG1vZGVsIHdpdGggZGVmYXVsdCBzZXR0aW5ncy4NCiMgICAgbG1lNCByZWZ1c2VzIHRvIGZpdCBpdDsgdGhlIGVycm9yIGlzIGNhcHR1cmVkIGFuZCBwcmludGVkIHNvIGl0IGFwcGVhcnMNCiMgICAgaW4gdGhlIGtuaXR0ZWQgZG9jdW1lbnQgYXMgZXZpZGVuY2UgZm9yIHRoZSBkZWNpc2lvbiBiZWxvdy4NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmRlZmF1bHRfYXR0ZW1wdCA8LSB0cnlDYXRjaCgNCiAgbG1lcihoZWFsdGhfciB+IHNhdGlzX2dtYyArICgxICsgc2F0aXNfZ21jIHwgaGhpZF9zdWIpLA0KICAgICAgIGRhdGEgPSBteWRhdGEsIFJFTUwgPSBUUlVFKSwNCiAgZXJyb3IgPSBmdW5jdGlvbihlKSBjb25kaXRpb25NZXNzYWdlKGUpDQopDQoNCmlmIChpcy5jaGFyYWN0ZXIoZGVmYXVsdF9hdHRlbXB0KSkgew0KICBjYXQoIkRlZmF1bHQgZml0IHN0b3BwZWQgd2l0aCB0aGUgZm9sbG93aW5nIGVycm9yOlxuXG4iLCBkZWZhdWx0X2F0dGVtcHQsICJcblxuIikNCn0NCg0KIyBXaHk6IGVhY2ggaG91c2Vob2xkIGdldHMgVFdPIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQgKyBzbG9wZSkNCm5fb2JzIDwtIG5yb3cobXlkYXRhKQ0Kbl9oaCAgPC0gbl9kaXN0aW5jdChteWRhdGEkaGhpZF9zdWIpDQpjYXQoIk9ic2VydmF0aW9uczoiLCBuX29icywgIlxuIikNCmNhdCgiSG91c2Vob2xkczoiLCBuX2hoLCAiXG4iKQ0KY2F0KCJSYW5kb20gZWZmZWN0cyByZXF1ZXN0ZWQgKDIgcGVyIGhvdXNlaG9sZCk6IiwgMiAqIG5faGgsICJcblxuIikNCg0KIyBIb3cgbXVjaCBpbmZvcm1hdGlvbiBpcyBhdmFpbGFibGUgdG8gZXN0aW1hdGUgYSBob3VzZWhvbGQtc3BlY2lmaWMgc2xvcGU/DQojIEEgc2xvcGUgcmVxdWlyZXMgMisgcmVzcG9uZGVudHMgaW4gdGhlIGhvdXNlaG9sZCB3aG8gRElGRkVSIGluIGxpZmUgc2F0aXNmYWN0aW9uLg0Kc2xvcGVfaW5mbyA8LSBteWRhdGEgJT4lDQogIGdyb3VwX2J5KGhoaWRfc3ViKSAlPiUNCiAgZHBseXI6OnN1bW1hcmlzZShuID0gbigpLA0KICAgICAgICAgICAgICAgICAgIG5fc2F0aXNfdmFsdWVzID0gbl9kaXN0aW5jdChzYXRpc19maW5hbCksDQogICAgICAgICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikNCg0KY2F0KCJIb3VzZWhvbGRzIHdpdGggMSByZXNwb25kZW50OiIsIHN1bShzbG9wZV9pbmZvJG4gPT0gMSksICJcbiIpDQpjYXQoIkhvdXNlaG9sZHMgd2l0aCAyKyByZXNwb25kZW50czoiLCBzdW0oc2xvcGVfaW5mbyRuID49IDIpLCAiXG4iKQ0KY2F0KCJIb3VzZWhvbGRzIHdpdGggMisgcmVzcG9uZGVudHMgd2hvIGRpZmZlciBpbiBsaWZlIHNhdGlzZmFjdGlvbjoiLA0KICAgIHN1bShzbG9wZV9pbmZvJG4gPj0gMiAmIHNsb3BlX2luZm8kbl9zYXRpc192YWx1ZXMgPiAxKSwgIlxuXG4iKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAyLiBPdmVycmlkZSB0aGUgY2hlY2sgdG8gc2VlIHRoZSBlc3RpbWF0ZXMuIFRoaXMgZG9lcyBOT1Qgc29sdmUgdGhlDQojICAgIGlkZW50aWZpY2F0aW9uIHByb2JsZW07IGl0IG9ubHkgbGV0cyBsbWU0IHJ1biBzbyB0aGUgcmVzdWx0IGNhbiBiZSBzaG93bi4NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCm1vZGVsMiA8LSBsbWVyKGhlYWx0aF9yIH4gc2F0aXNfZ21jICsgKDEgKyBzYXRpc19nbWMgfCBoaGlkX3N1YiksDQogICAgICAgICAgICAgICBkYXRhID0gbXlkYXRhLCBSRU1MID0gVFJVRSwNCiAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVjay5ub2JzLnZzLm5SRSA9ICJpZ25vcmUiKSkNCg0Kc3VtbWFyeShtb2RlbDIpDQoNCmNhdCgiXG5TaW5ndWxhciBmaXQ/IiwgaXNTaW5ndWxhcihtb2RlbDIpLCAiXG5cbiIpDQoNCiMgVmFyaWFuY2UgY29tcG9uZW50cw0KdmNfbTIgPC0gYXMuZGF0YS5mcmFtZShWYXJDb3JyKG1vZGVsMikpDQoNCnRhdTAwX20yIDwtIHZjX20yJHZjb3ZbdmNfbTIkZ3JwID09ICJoaGlkX3N1YiIgJiB2Y19tMiR2YXIxID09ICIoSW50ZXJjZXB0KSIgJiBpcy5uYSh2Y19tMiR2YXIyKV0NCnRhdTExX20yIDwtIHZjX20yJHZjb3ZbdmNfbTIkZ3JwID09ICJoaGlkX3N1YiIgJiB2Y19tMiR2YXIxID09ICJzYXRpc19nbWMiICAgJiBpcy5uYSh2Y19tMiR2YXIyKV0NCnRhdTAxX20yIDwtIHZjX20yJHZjb3ZbdmNfbTIkZ3JwID09ICJoaGlkX3N1YiIgJiAhaXMubmEodmNfbTIkdmFyMildDQpjb3IwMV9tMiA8LSB2Y19tMiRzZGNvclt2Y19tMiRncnAgPT0gImhoaWRfc3ViIiAmICFpcy5uYSh2Y19tMiR2YXIyKV0NCnNpZ21hX20yIDwtIHZjX20yJHZjb3ZbdmNfbTIkZ3JwID09ICJSZXNpZHVhbCJdDQoNCmRhdGEuZnJhbWUoDQogIFBhcmFtZXRlciA9IGMoIkludGVyY2VwdCB2YXJpYW5jZSAoz4QwMCkiLCAiU2xvcGUgdmFyaWFuY2UgKM+EMTEpIiwNCiAgICAgICAgICAgICAgICAiSW50ZXJjZXB0LXNsb3BlIGNvdmFyaWFuY2UgKM+EMDEpIiwNCiAgICAgICAgICAgICAgICAiSW50ZXJjZXB0LXNsb3BlIGNvcnJlbGF0aW9uIiwgIlJlc2lkdWFsIHZhcmlhbmNlICjPg8KyKSIpLA0KICBNb2RlbF8xID0gYyh0YXVfbTEsIE5BLCBOQSwgTkEsIHNpZ21hX20xKSwNCiAgTW9kZWxfMiA9IGModGF1MDBfbTIsIHRhdTExX20yLCB0YXUwMV9tMiwgY29yMDFfbTIsIHNpZ21hX20yKQ0KKSAlPiUNCiAga2JsKGRpZ2l0cyA9IDQsDQogICAgICBjb2wubmFtZXMgPSBjKCJQYXJhbWV0ZXIiLCAiTW9kZWwgMSAoZml4ZWQgc2xvcGUpIiwgIk1vZGVsIDIgKHJhbmRvbSBzbG9wZSkiKSwNCiAgICAgIGNhcHRpb24gPSAiUmFuZG9tIGVmZmVjdHM6IGZpeGVkLXNsb3BlIHZzLiByYW5kb20tc2xvcGUgbW9kZWwiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAzLiBDb21wYXJlIHdpdGggdGhlIGZpeGVkLXNsb3BlIG1vZGVsLiBTYW1lIGZpeGVkIGVmZmVjdHMsIHNvIFJFTUwgZml0cw0KIyAgICBjYW4gYmUgY29tcGFyZWQgZGlyZWN0bHkgKHJlZml0ID0gRkFMU0UpLiBkZiA9IDIgKGFkZHMgz4QxMSBhbmQgz4QwMSkuDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQphbm92YShtb2RlbDEsIG1vZGVsMiwgcmVmaXQgPSBGQUxTRSkNCg0KY2F0KCJcbk1vZGVsIDEgQUlDOiIsIHJvdW5kKEFJQyhtb2RlbDEpLCAyKSwgIiB8IEJJQzoiLCByb3VuZChCSUMobW9kZWwxKSwgMiksICJcbiIpDQpjYXQoIk1vZGVsIDIgQUlDOiIsIHJvdW5kKEFJQyhtb2RlbDIpLCAyKSwgIiB8IEJJQzoiLCByb3VuZChCSUMobW9kZWwyKSwgMiksICJcbiIpDQoNCmBgYA0KW1JlcG9ydCB0aGUgZmluZGluZ3MgZm9yIHRoZSByYW5kb20gZWZmZWN0cyAoYm90aCBpbnRlcmNlcHQgYW5kIHNsb3BlIG9mIHRoZSBwcmVkaWN0b3IpLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KQWxsb3dpbmcgdGhlIGVmZmVjdCBvZiBsaWZlIHNhdGlzZmFjdGlvbiB0byB2YXJ5IGFjcm9zcyBob3VzZWhvbGRzIHByb2R1Y2VkIGEgcmFuZG9tIGludGVyY2VwdCB2YXJpYW5jZSBvZiAkXHRhdV97MDB9JCA9IDAuMTg3ICgqU0QqID0gMC40MzIpLCBhIHJhbmRvbSBzbG9wZSB2YXJpYW5jZSBvZiAkXHRhdV97MTF9JCA9IDAuMDgzICgqU0QqID0gMC4yODgpLCBhbiBpbnRlcmNlcHTigJNzbG9wZSBjb3JyZWxhdGlvbiBvZiAqciogPSAuMjQgKCRcdGF1X3swMX0kID0gMC4wMzApLCBhbmQgYSByZXNpZHVhbCB2YXJpYW5jZSBvZiAkXHNpZ21hXjIkID0gMC42NzQgKCpTRCogPSAwLjgyMSkuIFRoZSBtb2RlbCBkaWQgbm90IHJldHVybiBhIHNpbmd1bGFyIGZpdCwgYWx0aG91Z2ggaXQgY291bGQgb25seSBiZSBlc3RpbWF0ZWQgYWZ0ZXIgb3ZlcnJpZGluZyBsbWU0J3MgZGVmYXVsdCBjaGVjaywgYmVjYXVzZSBpdCByZXF1aXJlcyAyMiwwNjIgaG91c2Vob2xkLWxldmVsIHJhbmRvbSBlZmZlY3RzIChhbiBpbnRlcmNlcHQgYW5kIGEgc2xvcGUgZm9yIGVhY2ggb2YgMTEsMDMxIGhvdXNlaG9sZHMpIGJ1dCBoYXMgb25seSAxNCw1NDEgb2JzZXJ2YXRpb25zLg0KDQoqKlJhbmRvbSBpbnRlcmNlcHQuKiogVGhlIGludGVyY2VwdCB2YXJpYW5jZSBkZXNjcmliZXMgaG93IG11Y2ggaG91c2Vob2xkcyBkaWZmZXIgaW4gdGhlIGV4cGVjdGVkIHNlbGYtcmF0ZWQgaGVhbHRoIG9mIGEgcmVzcG9uZGVudCB3aXRoIGF2ZXJhZ2UgbGlmZSBzYXRpc2ZhY3Rpb24uIEFzc3VtaW5nIG5vcm1hbGl0eSwgYWJvdXQgOTUlIG9mIGhvdXNlaG9sZCBpbnRlcmNlcHRzIGZhbGwgd2l0aGluIDMuMDg1IMKxIDEuOTYoMC40MzIpLCBvciByb3VnaGx5ICoqMi4yNCB0byAzLjkzKiogb24gdGhlIGZpdmUtcG9pbnQgc2NhbGUg4oCUIGZyb20ganVzdCBhYm92ZSAiRmFpciIgdG8gbmVhcmx5ICJWZXJ5IGdvb2QuIiBUaGUgaW50ZXJjZXB0IHZhcmlhbmNlIGRlY3JlYXNlZCBmcm9tIDAuMjAyIGluIHRoZSBmaXhlZC1zbG9wZSBtb2RlbCB0byAwLjE4NywgYXMgcGFydCBvZiB0aGUgYmV0d2Vlbi1ob3VzZWhvbGQgdmFyaWF0aW9uIHByZXZpb3VzbHkgYXR0cmlidXRlZCB0byBpbnRlcmNlcHRzIGlzIG5vdyBhdHRyaWJ1dGVkIHRvIGRpZmZlcmVuY2VzIGluIHNsb3Blcy4NCg0KKipSYW5kb20gc2xvcGUuKiogVGhlIHNsb3BlIHZhcmlhbmNlIGRlc2NyaWJlcyBob3cgbXVjaCB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBsaWZlIHNhdGlzZmFjdGlvbiBhbmQgc2VsZi1yYXRlZCBoZWFsdGggZGlmZmVycyBhY3Jvc3MgaG91c2Vob2xkcy4gVGhlIGF2ZXJhZ2Ugc2xvcGUgd2FzICRcZ2FtbWFfezEwfSQgPSAwLjQyNywgYW5kIGFib3V0IDk1JSBvZiBob3VzZWhvbGQgc2xvcGVzIHdvdWxkIGJlIGV4cGVjdGVkIHRvIGZhbGwgd2l0aGluIDAuNDI3IMKxIDEuOTYoMC4yODgpLCBvciByb3VnaGx5ICoq4oiSMC4xNCB0byAwLjk5KiouIFRha2VuIGF0IGZhY2UgdmFsdWUsIHRoaXMgaW1wbGllcyB0aGF0IHRoZSBhc3NvY2lhdGlvbiByYW5nZXMgZnJvbSBzbGlnaHRseSBuZWdhdGl2ZSBpbiBzb21lIGhvdXNlaG9sZHMgdG8gbmVhcmx5IG9uZSBmdWxsIGhlYWx0aCBjYXRlZ29yeSBwZXIgc2F0aXNmYWN0aW9uIGNhdGVnb3J5IGluIG90aGVycywgYW5kIHRoYXQgYWJvdXQgNyUgb2YgaG91c2Vob2xkcyB3b3VsZCBzaG93IGEgbmVnYXRpdmUgYXNzb2NpYXRpb24g4oCUIGhpZ2hlciBsaWZlIHNhdGlzZmFjdGlvbiBwYWlyZWQgd2l0aCB3b3JzZSBzZWxmLXJhdGVkIGhlYWx0aC4gVGhlIGludGVyY2VwdOKAk3Nsb3BlIGNvcnJlbGF0aW9uIG9mIC4yNCBpbmRpY2F0ZXMgdGhhdCBob3VzZWhvbGRzIHdpdGggaGlnaGVyIGF2ZXJhZ2UgaGVhbHRoIHRlbmQgdG8gc2hvdyBhIHNvbWV3aGF0IHN0cm9uZ2VyIGFzc29jaWF0aW9uIGJldHdlZW4gbGlmZSBzYXRpc2ZhY3Rpb24gYW5kIGhlYWx0aC4NCg0KVGhlIHJlc2lkdWFsIHZhcmlhbmNlIGFsc28gZGVjcmVhc2VkLCBmcm9tIDAuNzE0IGluIHRoZSBmaXhlZC1zbG9wZSBtb2RlbCB0byAwLjY3NCAoYSA1LjUlIHJlZHVjdGlvbikuIEFkZGluZyB0aGUgcmFuZG9tIHNsb3BlIGltcHJvdmVkIG1vZGVsIGZpdCwgJFxjaGleMiQoMikgPSA1NC44MSwgKnAqIDwgLjAwMSwgd2l0aCBBSUMgZGVjcmVhc2luZyBmcm9tIDM5LDgzMC43IHRvIDM5LDc3OS45IGFuZCBCSUMgZnJvbSAzOSw4NjEuMCB0byAzOSw4MjUuNC4gVGhlIHR3byBtb2RlbHMgd2VyZSBjb21wYXJlZCB1c2luZyB0aGVpciBSRU1MIGZpdHMgYmVjYXVzZSB0aGV5IGhhdmUgaWRlbnRpY2FsIGZpeGVkIGVmZmVjdHMuIFRoZSBmaXhlZCBlZmZlY3RzIHRoZW1zZWx2ZXMgd2VyZSBuZWFybHkgdW5jaGFuZ2VkOiB0aGUgaW50ZXJjZXB0IG1vdmVkIGZyb20gMy4wOCB0byAzLjA5IGFuZCB0aGUgbGlmZSBzYXRpc2ZhY3Rpb24gZWZmZWN0IGZyb20gMC40MjEgdG8gMC40MjcgKCpTRSogPSAwLjAxMCwgKnQqKDUsMzY5KSA9IDQyLjA3LCAqcCogPCAuMDAxKS4uDQoNCltSZXBvcnQgd2hldGhlciBvciBub3QgeW91IHNob3VsZCByZXRhaW4gdGhlIHJhbmRvbSBzbG9wZS5de3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCioqVGhlIHJhbmRvbSBzbG9wZSB3YXMgZHJvcHBlZCoqLCBhbmQgdGhlIGZpeGVkLXNsb3BlIG1vZGVsIHdhcyBjYXJyaWVkIGZvcndhcmQsIGRlc3BpdGUgdGhlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW1wcm92ZW1lbnQgaW4gZml0LiBUaGlzIGRlY2lzaW9uIHJlc3RzIG9uIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGEgcmF0aGVyIHRoYW4gb24gdGhlIHRlc3Qgc3RhdGlzdGljLg0KDQpGaXJzdCwgdGhlIG1vZGVsIGlzIG5vdCBwcm9wZXJseSBpZGVudGlmaWVkLiBsbWU0IHJlZnVzZWQgdG8gZml0IGl0IHVuZGVyIGl0cyBkZWZhdWx0IHNldHRpbmdzIGJlY2F1c2UgdGhlIG51bWJlciBvZiByYW5kb20gZWZmZWN0cyAoMjIsMDYyKSBleGNlZWRzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zICgxNCw1NDEpLiBNb3N0IGhvdXNlaG9sZHMgY29udGFpbiBhIHNpbmdsZSByZXNwb25kZW50LCBhbmQgYSBob3VzZWhvbGQtc3BlY2lmaWMgc2xvcGUgY2Fubm90IGJlIGVzdGltYXRlZCBmcm9tIG9uZSBkYXRhIHBvaW50OyBldmVuIGEgdHdvLXJlc3BvbmRlbnQgaG91c2Vob2xkIHN1cHBsaWVzIG9ubHkgYXMgbWFueSBvYnNlcnZhdGlvbnMgYXMgaXQgaGFzIHJhbmRvbSBlZmZlY3RzLiBUaGUgbW9kZWwgY291bGQgb25seSBiZSBlc3RpbWF0ZWQgYnkgb3ZlcnJpZGluZyB0aGlzIHNhZmVndWFyZCwgc28gaXRzIHZhcmlhbmNlIGVzdGltYXRlcyBjYW5ub3QgYmUgdHJlYXRlZCBhcyByZWxpYWJsZSBtZWFzdXJlcyBvZiBob3VzZWhvbGQtbGV2ZWwgc2xvcGUgdmFyaWF0aW9uLg0KDQpTZWNvbmQsIHdpdGggaG91c2Vob2xkcyB0aGlzIHNtYWxsLCBhIHJhbmRvbSBzbG9wZSBjYW5ub3QgYmUgZGlzdGluZ3Vpc2hlZCBmcm9tIGEgc2ltcGxlciBleHBsYW5hdGlvbjogdGhhdCBzZWxmLXJhdGVkIGhlYWx0aCBpcyBzaW1wbHkgbW9yZSB2YXJpYWJsZSBhdCBzb21lIGxldmVscyBvZiBsaWZlIHNhdGlzZmFjdGlvbiB0aGFuIGF0IG90aGVycyAocmVzaWR1YWwgaGV0ZXJvc2NlZGFzdGljaXR5KS4gQSByYW5kb20gc2xvcGUgbW9kZWwgaW1wbGllcyB0aGF0IHRoZSB0b3RhbCB2YXJpYW5jZSBvZiB0aGUgb3V0Y29tZSBjaGFuZ2VzIHdpdGggdGhlIHByZWRpY3RvciwgZm9sbG93aW5nICRcdGF1X3swMH0gKyAyXHRhdV97MDF9eCArIFx0YXVfezExfXheMiArIFxzaWdtYV4yJCwgd2hlcmUgJHgkIGlzIGNlbnRlcmVkIGxpZmUgc2F0aXNmYWN0aW9uLiBVc2luZyB0aGUgZXN0aW1hdGVzIGFib3ZlLCB0aGUgaW1wbGllZCB2YXJpYW5jZSBvZiBzZWxmLXJhdGVkIGhlYWx0aCBpcyBhYm91dCAwLjg2IGZvciBhIHJlc3BvbmRlbnQgd2l0aCBhdmVyYWdlIGxpZmUgc2F0aXNmYWN0aW9uIGJ1dCByaXNlcyB0byByb3VnaGx5IDEuMDPigJMxLjA0IGZvciByZXNwb25kZW50cyBhdCBlaXRoZXIgZW5kIG9mIHRoZSBzY2FsZSAoIm5vdCB2ZXJ5IHNhdGlzZmllZCIgb3IgImNvbXBsZXRlbHkgc2F0aXNmaWVkIikuIFRoZSBmaXQgaW1wcm92ZW1lbnQgaXMgdGhlcmVmb3JlIGNvbnNpc3RlbnQgd2l0aCBoZWFsdGggcmF0aW5ncyBiZWluZyBtb3JlIHNwcmVhZCBvdXQgYW1vbmcgcmVzcG9uZGVudHMgd2l0aCBleHRyZW1lIHNhdGlzZmFjdGlvbiBzY29yZXMsIHdoaWNoIGEgcmFuZG9tIHNsb3BlIGNhbiBhYnNvcmIgZXZlbiB3aGVuIHNsb3BlcyBkbyBub3QgYWN0dWFsbHkgZGlmZmVyIGFjcm9zcyBob3VzZWhvbGRzLiBXaXRoIHNvIGZldyBtdWx0aS1yZXNwb25kZW50IGhvdXNlaG9sZHMsIHRoZSBtb2RlbCBjYW5ub3QgdGVsbCB0aGVzZSBleHBsYW5hdGlvbnMgYXBhcnQuDQoNClRoaXJkLCB0aGUgZXN0aW1hdGVzIGFyZSBzdWJzdGFudGl2ZWx5IGltcGxhdXNpYmxlIHdoZW4gcmVhZCBhcyBob3VzZWhvbGQgc2xvcGUgdmFyaWF0aW9uLiBUaGV5IGltcGx5IHRoYXQgYWJvdXQgNyUgb2YgaG91c2Vob2xkcyBoYXZlIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24gYmV0d2VlbiBsaWZlIHNhdGlzZmFjdGlvbiBhbmQgc2VsZi1yYXRlZCBoZWFsdGgsIHdoaWNoIGlzIGRpZmZpY3VsdCB0byBpbnRlcnByZXQgYW5kIG1vcmUgbGlrZWx5IHJlZmxlY3RzIHRoZSBtb2RlbCBmaXR0aW5nIHRoZSB2YXJpYW5jZSBwYXR0ZXJuIGRlc2NyaWJlZCBhYm92ZSB0aGFuIHJlYWwgaG91c2Vob2xkcyBpbiB3aGljaCBncmVhdGVyIHNhdGlzZmFjdGlvbiBhY2NvbXBhbmllcyB3b3JzZSBoZWFsdGguDQoNCkZvdXJ0aCwgZHJvcHBpbmcgdGhlIHJhbmRvbSBzbG9wZSBkb2VzIG5vdCBjaGFuZ2UgdGhlIHN1YnN0YW50aXZlIGNvbmNsdXNpb25zLiBUaGUgZml4ZWQgZWZmZWN0IG9mIGxpZmUgc2F0aXNmYWN0aW9uIHdhcyBuZWFybHkgaWRlbnRpY2FsIGluIGJvdGggbW9kZWxzICgwLjQyMSB2cy4gMC40MjcpLCB3aXRoIGEgc2ltaWxhciBzdGFuZGFyZCBlcnJvciBhbmQgdGhlIHNhbWUgc2lnbmlmaWNhbmNlLCBzbyB0aGUgdGVzdCBvZiBIeXBvdGhlc2lzIDEgZG9lcyBub3QgZGVwZW5kIG9uIHRoaXMgY2hvaWNlLg0KDQpCZWNhdXNlIHRoZSByYW5kb20gc2xvcGUgaXMgbm90IGlkZW50aWZpYWJsZSBpbiB0aGVzZSBkYXRhLCBjYW5ub3QgYmUgaW50ZXJwcmV0ZWQgYXMgaG91c2Vob2xkLWxldmVsIHNsb3BlIHZhcmlhdGlvbiwgYW5kIGhhcyBubyBiZWFyaW5nIG9uIHRoZSBmaXhlZCBlZmZlY3RzIG9mIGludGVyZXN0LCB0aGUgc2ltcGxlciByYW5kb20taW50ZXJjZXB0IG1vZGVsIGlzIHJldGFpbmVkLiBUaGUgbmV4dCBtb2RlbCB0aGVyZWZvcmUgYWRkcyB0aGUgTGV2ZWwgMiBwcmVkaWN0b3Igd2l0aCBhIHJhbmRvbSBpbnRlcmNlcHQgb25seS4gVGhpcyBpcyBub3RlZCBhcyBhIGxpbWl0YXRpb246IHRoZSBkYXRhIGNhbm5vdCB0ZXN0IHdoZXRoZXIgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gbGlmZSBzYXRpc2ZhY3Rpb24gYW5kIGhlYWx0aCBkaWZmZXJzIGFjcm9zcyBob3VzZWhvbGRzLCBhbmQgYSBzYW1wbGUgd2l0aCBsYXJnZXIgY2x1c3RlcnMgd291bGQgYmUgbmVlZGVkIHRvIGRvIHNvLg0KDQpbMnB0OiBzdW1tYXJ5IG1ha2VzIHNlbnNlLCBhY2N1cmF0ZSBhbmQgY29tcGxldGUuIDFwdDogc29tZSBlcnJvcnMgb3IgbWlzc2luZyBpbmZvcm1hdGlvbi4gMHB0OiBtYW55IGVycm9ycyBvciBtaXNzaW5nIGluZm9ybWF0aW9uIChlLmcuLCBvdmVyIGhhbGYgcHJvYmxlbWF0aWMpXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQojIyBBZGQgYSBsZXZlbCAyIHByZWRpY3Rvcg0KDQpbQmFzZWQgb24gdGhlIGRlY2lzaW9uIHlvdSBtYWRlIGFib3ZlLCBlaXRoZXIga2VlcCBvciBkcm9wIHRoZSByYW5kb20gc2xvcGUsIGFuZCBhZGQgYSBsZXZlbCAyIHByZWRpY3Rvci5de3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCltJbmNsdWRlIHRoZSBlcXVhdGlvbnMgKHdpdGggZXhwbGFuYXRpb25zKSBoZXJlOl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KQmFzZWQgb24gdGhlIGRlY2lzaW9uIGFib3ZlLCB0aGUgcmFuZG9tIHNsb3BlIGZvciBsaWZlIHNhdGlzZmFjdGlvbiB3YXMgZHJvcHBlZCwgYW5kIHRoZSBtb2RlbCByZXRhaW5zIGEgcmFuZG9tIGludGVyY2VwdCBvbmx5LiBQZXJjZWl2ZWQgbmVpZ2hib3Job29kIHNhZmV0eSBpcyBhZGRlZCBhcyBhIHByZWRpY3RvciBvZiB0aGUgaG91c2Vob2xkIGludGVyY2VwdC4NCg0KKipMZXZlbCAxIChyZXNwb25kZW50KToqKg0KDQokJA0KXHRleHR7SGVhbHRofV97aWp9ID0gXGJldGFfezBqfSArIFxiZXRhX3sxan0oXHRleHR7TGlmZVNhdH1fe2lqfSAtIFxvdmVybGluZXtcdGV4dHtMaWZlU2F0fX1fey4ufSkgKyByX3tpan0sIFxxcXVhZCByX3tpan0gXHNpbSBOKDAsIFxzaWdtYV4yKQ0KJCQNCg0KKipMZXZlbCAyIChob3VzZWhvbGQpOioqDQoNCiQkDQpcYmV0YV97MGp9ID0gXGdhbW1hX3swMH0gKyBcZ2FtbWFfezAxfShcdGV4dHtTYWZldHl9X3tqfSAtIFxvdmVybGluZXtcdGV4dHtTYWZldHl9fV97Ln0pICsgdV97MGp9LCBccXF1YWQgdV97MGp9IFxzaW0gTigwLCBcdGF1X3swMH0pDQokJA0KDQokJA0KXGJldGFfezFqfSA9IFxnYW1tYV97MTB9DQokJA0KDQoqKkNvbWJpbmVkIChtaXhlZCkgbW9kZWw6KioNCg0KJCQNClx0ZXh0e0hlYWx0aH1fe2lqfSA9IFxnYW1tYV97MDB9ICsgXGdhbW1hX3swMX0oXHRleHR7U2FmZXR5fV97an0gLSBcb3ZlcmxpbmV7XHRleHR7U2FmZXR5fX1fey59KSArIFxnYW1tYV97MTB9KFx0ZXh0e0xpZmVTYXR9X3tpan0gLSBcb3ZlcmxpbmV7XHRleHR7TGlmZVNhdH19X3suLn0pICsgdV97MGp9ICsgcl97aWp9DQokJA0KDQoqKkV4cGxhbmF0aW9uczoqKg0KDQotICRcdGV4dHtIZWFsdGh9X3tpan0kIGlzIHRoZSBzZWxmLXJhdGVkIGhlYWx0aCBvZiByZXNwb25kZW50ICRpJCBpbiBob3VzZWhvbGQgJGokICgxID0gUG9vciB0byA1ID0gRXhjZWxsZW50KS4NCi0gJChcdGV4dHtMaWZlU2F0fV97aWp9IC0gXG92ZXJsaW5le1x0ZXh0e0xpZmVTYXR9fV97Li59KSQgaXMgcmVzcG9uZGVudCAkaSQncyBncmFuZC1tZWFuLWNlbnRlcmVkIGxpZmUgc2F0aXNmYWN0aW9uICh3aW5zb3JpemVkOyBoaWdoZXIgPSBtb3JlIHNhdGlzZmllZCkuIEl0IGNhcnJpZXMgdGhlIHN1YnNjcmlwdCAkaWokIGJlY2F1c2UgaXQgdmFyaWVzIGFjcm9zcyByZXNwb25kZW50cywgaW5jbHVkaW5nIGJldHdlZW4gcmVzcG9uZGVudHMgaW4gdGhlIHNhbWUgaG91c2Vob2xkLg0KLSAkKFx0ZXh0e1NhZmV0eX1fe2p9IC0gXG92ZXJsaW5le1x0ZXh0e1NhZmV0eX19X3sufSkkIGlzIGhvdXNlaG9sZCAkaiQncyBncmFuZC1tZWFuLWNlbnRlcmVkIHBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5IChoaWdoZXIgPSBzYWZlciksIGNlbnRlcmVkIGF0IHRoZSBtZWFuIGFjcm9zcyBob3VzZWhvbGRzLiBJdCBjYXJyaWVzIG9ubHkgdGhlIHN1YnNjcmlwdCAkaiQgYmVjYXVzZSBpdCB2YXJpZXMgYWNyb3NzIGhvdXNlaG9sZHMgYnV0IGlzIGlkZW50aWNhbCBmb3IgYWxsIHJlc3BvbmRlbnRzIHdpdGhpbiBhIGhvdXNlaG9sZCAoSUNDID0gMS4wMCkuIFRoaXMgaXMgd2h5IGl0IGFwcGVhcnMgaW4gdGhlICoqTGV2ZWwgMiBpbnRlcmNlcHQgZXF1YXRpb24qKiByYXRoZXIgdGhhbiB0aGUgTGV2ZWwgMSBlcXVhdGlvbjogYSBob3VzZWhvbGQtbGV2ZWwgdmFyaWFibGUgY2FuIGV4cGxhaW4gZGlmZmVyZW5jZXMgYmV0d2VlbiBob3VzZWhvbGQgbWVhbnMsIGJ1dCBub3QgZGlmZmVyZW5jZXMgYmV0d2VlbiBwZW9wbGUgd2l0aGluIHRoZSBzYW1lIGhvdXNlaG9sZC4NCi0gJFxiZXRhX3swan0kIGlzIHRoZSBpbnRlcmNlcHQgZm9yIGhvdXNlaG9sZCAkaiQ6IHRoZSBleHBlY3RlZCBzZWxmLXJhdGVkIGhlYWx0aCBvZiBhIHJlc3BvbmRlbnQgd2l0aCBhdmVyYWdlIGxpZmUgc2F0aXNmYWN0aW9uIGluIHRoYXQgaG91c2Vob2xkLiBJdCBpcyBub3cgcHJlZGljdGVkIGJ5IHRoZSBob3VzZWhvbGQncyBuZWlnaGJvcmhvb2Qgc2FmZXR5Lg0KLSAkXGJldGFfezFqfSQgaXMgdGhlIHNsb3BlIG9mIGxpZmUgc2F0aXNmYWN0aW9uLiBUaGUgZXF1YXRpb24gJFxiZXRhX3sxan0gPSBcZ2FtbWFfezEwfSQgY29udGFpbnMgbm8gcmFuZG9tIHRlcm0sIHJlZmxlY3RpbmcgdGhlIGRlY2lzaW9uIHRvIGRyb3AgdGhlIHJhbmRvbSBzbG9wZTogdGhlIGxpZmUgc2F0aXNmYWN0aW9uIGVmZmVjdCBpcyBjb25zdHJhaW5lZCB0byBiZSB0aGUgc2FtZSBpbiBldmVyeSBob3VzZWhvbGQuDQotICRcZ2FtbWFfezAwfSQgaXMgdGhlIGZpeGVkIGludGVyY2VwdDogdGhlIGV4cGVjdGVkIHNlbGYtcmF0ZWQgaGVhbHRoIG9mIGEgcmVzcG9uZGVudCB3aXRoIGF2ZXJhZ2UgbGlmZSBzYXRpc2ZhY3Rpb24gbGl2aW5nIGluIGEgaG91c2Vob2xkIHdpdGggYXZlcmFnZSBwZXJjZWl2ZWQgbmVpZ2hib3Job29kIHNhZmV0eS4NCi0gJFxnYW1tYV97MDF9JCBpcyB0aGUgZml4ZWQgZWZmZWN0IG9mIG5laWdoYm9yaG9vZCBzYWZldHk6IHRoZSBleHBlY3RlZCBjaGFuZ2UgaW4gYSBob3VzZWhvbGQncyBtZWFuIHNlbGYtcmF0ZWQgaGVhbHRoIGZvciBlYWNoIG9uZS1jYXRlZ29yeSBpbmNyZWFzZSBpbiBwZXJjZWl2ZWQgbmVpZ2hib3Job29kIHNhZmV0eSwgaG9sZGluZyBsaWZlIHNhdGlzZmFjdGlvbiBjb25zdGFudC4NCi0gJFxnYW1tYV97MTB9JCBpcyB0aGUgZml4ZWQgZWZmZWN0IG9mIGxpZmUgc2F0aXNmYWN0aW9uOiB0aGUgZXhwZWN0ZWQgY2hhbmdlIGluIHNlbGYtcmF0ZWQgaGVhbHRoIGZvciBlYWNoIG9uZS1jYXRlZ29yeSBpbmNyZWFzZSBpbiBsaWZlIHNhdGlzZmFjdGlvbiwgaG9sZGluZyBuZWlnaGJvcmhvb2Qgc2FmZXR5IGNvbnN0YW50Lg0KLSAkdV97MGp9JCBpcyB0aGUgcmFuZG9tIGludGVyY2VwdDogdGhlIHBhcnQgb2YgaG91c2Vob2xkICRqJCdzIG1lYW4gaGVhbHRoIG5vdCBleHBsYWluZWQgYnkgaXRzIG5laWdoYm9yaG9vZCBzYWZldHkuIEl0cyB2YXJpYW5jZSwgJFx0YXVfezAwfSQsIGlzIG5vdyB0aGUgKipyZXNpZHVhbCBiZXR3ZWVuLWhvdXNlaG9sZCB2YXJpYW5jZSoqLiBDb21wYXJpbmcgaXQgd2l0aCAkXHRhdV97MDB9JCBmcm9tIHRoZSBwcmV2aW91cyBtb2RlbCBzaG93cyBob3cgbXVjaCBiZXR3ZWVuLWhvdXNlaG9sZCB2YXJpYW5jZSBuZWlnaGJvcmhvb2Qgc2FmZXR5IGV4cGxhaW5zLg0KLSAkcl97aWp9JCBpcyB0aGUgTGV2ZWwgMSByZXNpZHVhbCwgd2l0aCB2YXJpYW5jZSAkXHNpZ21hXjIkIHJlcHJlc2VudGluZyB0aGUgcmVtYWluaW5nICoqd2l0aGluLWhvdXNlaG9sZCB2YXJpYW5jZSoqLiBCZWNhdXNlIG5laWdoYm9yaG9vZCBzYWZldHkgZG9lcyBub3QgdmFyeSB3aXRoaW4gaG91c2Vob2xkcywgYWRkaW5nIGl0IHNob3VsZCBsZWF2ZSAkXHNpZ21hXjIkIGVzc2VudGlhbGx5IHVuY2hhbmdlZC4NCi0gVGhlIGNvbWJpbmVkIG1vZGVsIGlzIG9idGFpbmVkIGJ5IHN1YnN0aXR1dGluZyBib3RoIExldmVsIDIgZXF1YXRpb25zIGludG8gdGhlIExldmVsIDEgZXF1YXRpb24uIEl0IGNvbnRhaW5zIHRocmVlIGZpeGVkIGVmZmVjdHMgKCRcZ2FtbWFfezAwfSQsICRcZ2FtbWFfezAxfSQsICRcZ2FtbWFfezEwfSQpIGFuZCB0d28gcmFuZG9tIHRlcm1zICgkdV97MGp9JCwgJHJfe2lqfSQpLiBObyBjcm9zcy1sZXZlbCBpbnRlcmFjdGlvbiBpcyBpbmNsdWRlZCwgc2luY2Ugbm8gaHlwb3RoZXNpcyB3YXMgbWFkZSBhYm91dCBuZWlnaGJvcmhvb2Qgc2FmZXR5IGNoYW5naW5nIHRoZSBzdHJlbmd0aCBvZiB0aGUgbGlmZSBzYXRpc2ZhY3Rpb24gZWZmZWN0Li4NCg0KWzJwdDogZXF1YXRpb25zIGNvcnJlY3QuIDFwdDogZXF1YXRpb25zIG1vc3RseSBjb3JyZWN0LiAwcHQ6IG1hbnkgZXJyb3JzIGluIGVxdWF0aW9uc117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KWzJwdDogZXhwbGFuYXRpb25zIGNvcnJlY3QuIDFwdDogZXhwbGFuYXRpb25zIG1vc3RseSBjb3JyZWN0LiAwcHQ6IG1hbnkgZXJyb3JzIGluIGV4cGxhbmF0aW9uc117c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KW01hcCB5b3VyIGh5cG90aGVzZXMgdG8geW91ciBmaW5hbCBtb2RlbDpde3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCioqSHlwb3RoZXNpcyAxIChMZXZlbCAxKToqKiBSZXNwb25kZW50cyB3aG8gcmVwb3J0IGhpZ2hlciBsaWZlIHNhdGlzZmFjdGlvbiB3aWxsIHJlcG9ydCBiZXR0ZXIgc2VsZi1yYXRlZCBoZWFsdGguDQoNClRoaXMgaHlwb3RoZXNpcyBtYXBzIG9udG8gJFxnYW1tYV97MTB9JCwgdGhlIGZpeGVkIGVmZmVjdCBvZiBncmFuZC1tZWFuLWNlbnRlcmVkIGxpZmUgc2F0aXNmYWN0aW9uIGluIHRoZSBjb21iaW5lZCBtb2RlbC4gQmVjYXVzZSBib3RoIHZhcmlhYmxlcyBhcmUgY29kZWQgc28gdGhhdCBoaWdoZXIgdmFsdWVzIG1lYW4gbW9yZSBvZiB0aGUgY29uc3RydWN0IChtb3JlIHNhdGlzZmllZCwgYmV0dGVyIGhlYWx0aCksIEh5cG90aGVzaXMgMSBpcyBzdXBwb3J0ZWQgaWYgJFxnYW1tYV97MTB9JCBpcyAqKnBvc2l0aXZlIGFuZCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIDAqKi4gQSBwb3NpdGl2ZSB2YWx1ZSBtZWFucyB0aGF0LCBob2xkaW5nIG5laWdoYm9yaG9vZCBzYWZldHkgY29uc3RhbnQsIHJlc3BvbmRlbnRzIHdpdGggaGlnaGVyIGxpZmUgc2F0aXNmYWN0aW9uIGFyZSBleHBlY3RlZCB0byByZXBvcnQgYmV0dGVyIGhlYWx0aC4gVGhlIG51bGwgaHlwb3RoZXNpcyBpcyAkSF8wOiBcZ2FtbWFfezEwfSA9IDAkLg0KDQoqKkh5cG90aGVzaXMgMiAoTGV2ZWwgMik6KiogUmVzcG9uZGVudHMgbGl2aW5nIGluIGhvdXNlaG9sZHMgd2hvc2UgbmVpZ2hib3Job29kcyBhcmUgcGVyY2VpdmVkIGFzIHNhZmVyIHdpbGwgcmVwb3J0IGJldHRlciBzZWxmLXJhdGVkIGhlYWx0aC4NCg0KVGhpcyBoeXBvdGhlc2lzIG1hcHMgb250byAkXGdhbW1hX3swMX0kLCB0aGUgZml4ZWQgZWZmZWN0IG9mIGdyYW5kLW1lYW4tY2VudGVyZWQgbmVpZ2hib3Job29kIHNhZmV0eSBpbiB0aGUgTGV2ZWwgMiBpbnRlcmNlcHQgZXF1YXRpb24uIEJlY2F1c2Ugc2FmZXR5IGlzIGNvZGVkIHNvIHRoYXQgaGlnaGVyIHZhbHVlcyBtZWFuIGEgc2FmZXIgbmVpZ2hib3Job29kLCBIeXBvdGhlc2lzIDIgaXMgc3VwcG9ydGVkIGlmICRcZ2FtbWFfezAxfSQgaXMgKipwb3NpdGl2ZSBhbmQgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgZnJvbSAwKiouIEEgcG9zaXRpdmUgdmFsdWUgbWVhbnMgdGhhdCwgaG9sZGluZyBsaWZlIHNhdGlzZmFjdGlvbiBjb25zdGFudCwgaG91c2Vob2xkcyBpbiBuZWlnaGJvcmhvb2RzIHBlcmNlaXZlZCBhcyBzYWZlciBoYXZlIGhpZ2hlciBhdmVyYWdlIHNlbGYtcmF0ZWQgaGVhbHRoLiBUaGUgbnVsbCBoeXBvdGhlc2lzIGlzICRIXzA6IFxnYW1tYV97MDF9ID0gMCQuDQoNClRoZSByZW1haW5pbmcgcGFyYW1ldGVycyBhcmUgbm90IHRpZWQgdG8gYSBoeXBvdGhlc2lzLiAkXGdhbW1hX3swMH0kIGRlc2NyaWJlcyB0aGUgYmFzZWxpbmUgbGV2ZWwgb2YgaGVhbHRoIGZvciBhIHJlc3BvbmRlbnQgYXQgdGhlIGF2ZXJhZ2Ugb2YgYm90aCBwcmVkaWN0b3JzLCBhbmQgdGhlIHZhcmlhbmNlIGNvbXBvbmVudHMgJFx0YXVfezAwfSQgYW5kICRcc2lnbWFeMiQgZGVzY3JpYmUgdGhlIHJlbWFpbmluZyB1bmV4cGxhaW5lZCB2YXJpYXRpb24gYmV0d2VlbiBhbmQgd2l0aGluIGhvdXNlaG9sZHMuIE5vIGh5cG90aGVzaXMgd2FzIG1hZGUgYWJvdXQgdmFyaWF0aW9uIGluIHRoZSBsaWZlIHNhdGlzZmFjdGlvbiBzbG9wZSwgd2hpY2ggd2FzIGRyb3BwZWQgZnJvbSB0aGUgbW9kZWwsIG9yIGFib3V0IGEgY3Jvc3MtbGV2ZWwgaW50ZXJhY3Rpb24sIHdoaWNoIGlzIG5vdCBpbmNsdWRlZC4NCg0KWzJwdDogYWxsIGh5cG90aGVzZXMgYXJlIG1hcHBlZCBjb3JyZWN0bHkuIDFwdDogbWFwcGluZyBtb3N0bHkgY29ycmVjdC4gMHB0OiBtYW55IGVycm9ycyBvciBtaXNzaW5nXXtzdHlsZT0iY29sb3I6IHJlZDsifQ0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCg0KIyBGaW5hbCBtb2RlbDogcmFuZG9tIGludGVyY2VwdCBvbmx5IChyYW5kb20gc2xvcGUgZHJvcHBlZCksIHdpdGggdGhlDQojIExldmVsIDEgcHJlZGljdG9yIChsaWZlIHNhdGlzZmFjdGlvbikgYW5kIHRoZSBMZXZlbCAyIHByZWRpY3Rvcg0KIyAobmVpZ2hib3Job29kIHNhZmV0eSksIGJvdGggZ3JhbmQtbWVhbiBjZW50ZXJlZA0KbW9kZWwzIDwtIGxtZXIoaGVhbHRoX3IgfiBzYXRpc19nbWMgKyBzYWZldHlfZ21jICsgKDEgfCBoaGlkX3N1YiksDQogICAgICAgICAgICAgICBkYXRhID0gbXlkYXRhLCBSRU1MID0gVFJVRSkNCg0Kc3VtbWFyeShtb2RlbDMpDQoNCiMgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgZml4ZWQgZWZmZWN0cw0KY29uZmludChtb2RlbDMsIHBhcm0gPSBjKCIoSW50ZXJjZXB0KSIsICJzYXRpc19nbWMiLCAic2FmZXR5X2dtYyIpLA0KICAgICAgICBtZXRob2QgPSAiV2FsZCIpDQoNCiMgVmFyaWFuY2UgY29tcG9uZW50cw0KdmNfbTMgPC0gYXMuZGF0YS5mcmFtZShWYXJDb3JyKG1vZGVsMykpDQp0YXVfbTMgICA8LSB2Y19tMyR2Y292W3ZjX20zJGdycCA9PSAiaGhpZF9zdWIiXSAgICMgYmV0d2Vlbi1ob3VzZWhvbGQNCnNpZ21hX20zIDwtIHZjX20zJHZjb3ZbdmNfbTMkZ3JwID09ICJSZXNpZHVhbCJdICAgIyB3aXRoaW4taG91c2Vob2xkDQoNCiMgVmFyaWFuY2UgZXhwbGFpbmVkLCBjb21wYXJlZCB3aXRoIGJvdGggdGhlIHVuY29uZGl0aW9uYWwgbW9kZWwgKG1vZGVsIDApDQojIGFuZCB0aGUgbGlmZS1zYXRpc2ZhY3Rpb24tb25seSBtb2RlbCAobW9kZWwgMSkNCmRhdGEuZnJhbWUoDQogIENvbXBvbmVudCA9IGMoIkJldHdlZW4taG91c2Vob2xkICjPhDAwKSIsICJXaXRoaW4taG91c2Vob2xkICjPg8KyKSIpLA0KICBNb2RlbF8wICAgPSBjKHRhdV9tMCwgICBzaWdtYV9tMCksDQogIE1vZGVsXzEgICA9IGModGF1X20xLCAgIHNpZ21hX20xKSwNCiAgTW9kZWxfMyAgID0gYyh0YXVfbTMsICAgc2lnbWFfbTMpLA0KICB2c19NMF9wY3QgPSBjKCh0YXVfbTAgLSB0YXVfbTMpIC8gdGF1X20wICogMTAwLA0KICAgICAgICAgICAgICAgIChzaWdtYV9tMCAtIHNpZ21hX20zKSAvIHNpZ21hX20wICogMTAwKSwNCiAgdnNfTTFfcGN0ID0gYygodGF1X20xIC0gdGF1X20zKSAvIHRhdV9tMSAqIDEwMCwNCiAgICAgICAgICAgICAgICAoc2lnbWFfbTEgLSBzaWdtYV9tMykgLyBzaWdtYV9tMSAqIDEwMCkNCikgJT4lDQogIGtibChkaWdpdHMgPSBjKDAsIDQsIDQsIDQsIDEsIDEpLA0KICAgICAgY29sLm5hbWVzID0gYygiQ29tcG9uZW50IiwgIk1vZGVsIDAiLCAiTW9kZWwgMSIsICJNb2RlbCAzIiwNCiAgICAgICAgICAgICAgICAgICAgIiUgcmVkdWN0aW9uIHZzLiBNb2RlbCAwIiwgIiUgcmVkdWN0aW9uIHZzLiBNb2RlbCAxIiksDQogICAgICBjYXB0aW9uID0gIlZhcmlhbmNlIGNvbXBvbmVudHMgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2UgZXhwbGFpbmVkIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkNCg0KIyBMaWtlbGlob29kIHJhdGlvIHRlc3Q6IGRvZXMgYWRkaW5nIG5laWdoYm9yaG9vZCBzYWZldHkgaW1wcm92ZSBmaXQNCiMgb3ZlciB0aGUgbGlmZS1zYXRpc2ZhY3Rpb24tb25seSBtb2RlbD8gVGhlIG1vZGVscyBkaWZmZXIgaW4gRklYRUQNCiMgZWZmZWN0cywgc28gYm90aCBhcmUgcmVmaXQgd2l0aCBNTCBmb3IgdGhpcyBjb21wYXJpc29uLg0KbW9kZWwxX21sIDwtIGxtZXIoaGVhbHRoX3IgfiBzYXRpc19nbWMgKyAoMSB8IGhoaWRfc3ViKSwNCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBteWRhdGEsIFJFTUwgPSBGQUxTRSkNCm1vZGVsM19tbCA8LSBsbWVyKGhlYWx0aF9yIH4gc2F0aXNfZ21jICsgc2FmZXR5X2dtYyArICgxIHwgaGhpZF9zdWIpLA0KICAgICAgICAgICAgICAgICAgZGF0YSA9IG15ZGF0YSwgUkVNTCA9IEZBTFNFKQ0KYW5vdmEobW9kZWwxX21sLCBtb2RlbDNfbWwpDQoNCiMgRml0IGNvbXBhcmlzb24gYWNyb3NzIHRoZSByYW5kb20taW50ZXJjZXB0IG1vZGVscyAoTUwgZml0cywgc28gQUlDL0JJQw0KIyBhcmUgY29tcGFyYWJsZSBhY3Jvc3MgbW9kZWxzIHdpdGggZGlmZmVyZW50IGZpeGVkIGVmZmVjdHMpLiBNb2RlbCAyDQojIChyYW5kb20gc2xvcGUpIGlzIG9taXR0ZWQgYmVjYXVzZSBpdCB3YXMgZHJvcHBlZC4NCm1vZGVsMF9tbCA8LSBsbWVyKGhlYWx0aF9yIH4gMSArICgxIHwgaGhpZF9zdWIpLCBkYXRhID0gbXlkYXRhLCBSRU1MID0gRkFMU0UpDQoNCmRhdGEuZnJhbWUoDQogIE1vZGVsID0gYygiTW9kZWwgMDogVW5jb25kaXRpb25hbCIsDQogICAgICAgICAgICAiTW9kZWwgMTogKyBMaWZlIHNhdGlzZmFjdGlvbiIsDQogICAgICAgICAgICAiTW9kZWwgMzogKyBOZWlnaGJvcmhvb2Qgc2FmZXR5IiksDQogIEFJQyA9IGMoQUlDKG1vZGVsMF9tbCksIEFJQyhtb2RlbDFfbWwpLCBBSUMobW9kZWwzX21sKSksDQogIEJJQyA9IGMoQklDKG1vZGVsMF9tbCksIEJJQyhtb2RlbDFfbWwpLCBCSUMobW9kZWwzX21sKSksDQogIGxvZ0xpayA9IGMoYXMubnVtZXJpYyhsb2dMaWsobW9kZWwwX21sKSksDQogICAgICAgICAgICAgYXMubnVtZXJpYyhsb2dMaWsobW9kZWwxX21sKSksDQogICAgICAgICAgICAgYXMubnVtZXJpYyhsb2dMaWsobW9kZWwzX21sKSkpDQopICU+JQ0KICBrYmwoZGlnaXRzID0gMSwgY2FwdGlvbiA9ICJNb2RlbCBmaXQgY29tcGFyaXNvbiAoTUwgZXN0aW1hdGlvbikiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQpgYGANCg0KWypTdW1tYXJ5Kl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KW1JlcG9ydCB0aGUgZmluZGluZ3MgKGluY2x1ZGluZyBpbnRlcnByZXRhdGlvbiB3aXRoIHJlZ2FyZCB0byB1bml0cyBvZiBhbmFseXNpcykgZm9yIHlvdXIgaW50ZXJjZXB0IHRlcm0sIHRoZSBmaXhlZCBlZmZlY3Qgb2YgdGhlIGxldmVsIDEgcHJlZGljdG9yLCBhbmQgdGhlIGxldmVsIDIgcHJlZGljdG9yLl17c3R5bGU9ImNvbG9yOiBwdXJwbGU7In0NCg0KVGhlIGZpbmFsIG1vZGVsIGluY2x1ZGVkIGdyYW5kLW1lYW4tY2VudGVyZWQgbGlmZSBzYXRpc2ZhY3Rpb24gYXQgTGV2ZWwgMSBhbmQgZ3JhbmQtbWVhbi1jZW50ZXJlZCBwZXJjZWl2ZWQgbmVpZ2hib3Job29kIHNhZmV0eSBhdCBMZXZlbCAyLCB3aXRoIGEgcmFuZG9tIGludGVyY2VwdCBmb3IgaG91c2Vob2xkLiBJdCB3YXMgZXN0aW1hdGVkIG9uIDE0LDU0MSByZXNwb25kZW50cyBuZXN0ZWQgd2l0aGluIDExLDAzMSBob3VzZWhvbGRzLg0KDQoqKkludGVyY2VwdCAoJFxnYW1tYV97MDB9JCkuKiogVGhlIGludGVyY2VwdCB3YXMgMy4wNyAoKlNFKiA9IDAuMDA4LCAqdCooMTAsMDUwKSA9IDM4NC4xNiwgKnAqIDwgLjAwMSwgOTUlIENJIFszLjA1LCAzLjA5XSkuIEJlY2F1c2UgYm90aCBwcmVkaWN0b3JzIHdlcmUgZ3JhbmQtbWVhbiBjZW50ZXJlZCwgdGhpcyBpcyAqKnRoZSBleHBlY3RlZCBzZWxmLXJhdGVkIGhlYWx0aCBvZiBhIHJlc3BvbmRlbnQgd2l0aCBhdmVyYWdlIGxpZmUgc2F0aXNmYWN0aW9uIGxpdmluZyBpbiBhIGhvdXNlaG9sZCB3aXRoIGF2ZXJhZ2UgcGVyY2VpdmVkIG5laWdoYm9yaG9vZCBzYWZldHkqKjogYWJvdXQgMy4wNyBvbiB0aGUgZml2ZS1wb2ludCBzY2FsZSwgb3IgYWxtb3N0IGV4YWN0bHkgIkdvb2QiIGhlYWx0aC4gVGhlIGludGVyY2VwdCBpcyBlc3NlbnRpYWxseSB1bmNoYW5nZWQgZnJvbSB0aGUgcHJldmlvdXMgbW9kZWxzICgzLjA3IGluIHRoZSB1bmNvbmRpdGlvbmFsIG1vZGVsIGFuZCAzLjA4IGluIHRoZSBsaWZlLXNhdGlzZmFjdGlvbi1vbmx5IG1vZGVsKSwgYXMgZXhwZWN0ZWQgd2hlbiBwcmVkaWN0b3JzIGFyZSBjZW50ZXJlZCBhdCB0aGVpciBtZWFucy4gVGhlIHNtYWxsIHNoaWZ0IHJlZmxlY3RzIHRoYXQgbmVpZ2hib3Job29kIHNhZmV0eSB3YXMgY2VudGVyZWQgYXQgaXRzIG1lYW4gYWNyb3NzIGhvdXNlaG9sZHMgcmF0aGVyIHRoYW4gYWNyb3NzIHJlc3BvbmRlbnRzLiBBcyBiZWZvcmUsIHRoZSBzaWduaWZpY2FuY2UgdGVzdCBvbmx5IHNob3dzIHRoYXQgdGhlIGludGVyY2VwdCBkaWZmZXJzIGZyb20gMCwgd2hpY2ggaXMgbm90IHN1YnN0YW50aXZlbHkgbWVhbmluZ2Z1bCBzaW5jZSAwIGlzIG5vdCBhIHBvc3NpYmxlIGhlYWx0aCBzY29yZS4NCg0KKipMaWZlIHNhdGlzZmFjdGlvbiAoJFxnYW1tYV97MTB9JCwgTGV2ZWwgMSkuKiogVGhlIGZpeGVkIGVmZmVjdCBvZiBsaWZlIHNhdGlzZmFjdGlvbiB3YXMgMC4zNzEgKCpTRSogPSAwLjAxMCwgKnQqKDE0LDQ3MCkgPSAzOC42OCwgKnAqIDwgLjAwMSwgOTUlIENJIFswLjM1MiwgMC4zOTBdKS4gKipIb2xkaW5nIG5laWdoYm9yaG9vZCBzYWZldHkgY29uc3RhbnQsIGVhY2ggb25lLWNhdGVnb3J5IGluY3JlYXNlIGluIGxpZmUgc2F0aXNmYWN0aW9uIChmb3IgZXhhbXBsZSwgZnJvbSAic29tZXdoYXQgc2F0aXNmaWVkIiB0byAidmVyeSBzYXRpc2ZpZWQiKSBpcyBhc3NvY2lhdGVkIHdpdGggYSAwLjM3LXBvaW50IGluY3JlYXNlIGluIHNlbGYtcmF0ZWQgaGVhbHRoLioqIEFjcm9zcyB0aGUgdGhyZWUtY2F0ZWdvcnkgcmFuZ2Ugb2YgdGhlIHdpbnNvcml6ZWQgdmFyaWFibGUsIGZyb20gIm5vdCB2ZXJ5IHNhdGlzZmllZCIgdG8gImNvbXBsZXRlbHkgc2F0aXNmaWVkLCIgdGhpcyBjb3JyZXNwb25kcyB0byBhbiBleHBlY3RlZCBkaWZmZXJlbmNlIG9mIGFib3V0IDEuMTEgcG9pbnRzIOKAlCBtb3JlIHRoYW4gb25lIGZ1bGwgaGVhbHRoIGNhdGVnb3J5LCBzdWNoIGFzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gIkZhaXIiIGFuZCAiR29vZC4iICoqSHlwb3RoZXNpcyAxIHdhcyBzdXBwb3J0ZWQuKioNCg0KVGhlIGxpZmUgc2F0aXNmYWN0aW9uIGVmZmVjdCBkZWNyZWFzZWQgYnkgYWJvdXQgMTIlIGFmdGVyIG5laWdoYm9yaG9vZCBzYWZldHkgd2FzIGFkZGVkIChmcm9tIDAuNDIxIHRvIDAuMzcxKS4gVGhlIG5lZ2F0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHR3byBmaXhlZC1lZmZlY3QgZXN0aW1hdGVzICgqciogPSDiiJIuMTgpIGluZGljYXRlcyB0aGF0IHRoZSBwcmVkaWN0b3JzIHRoZW1zZWx2ZXMgYXJlIHBvc2l0aXZlbHkgcmVsYXRlZDogcmVzcG9uZGVudHMgaW4gaG91c2Vob2xkcyB3aXRoIHNhZmVyLXBlcmNlaXZlZCBuZWlnaGJvcmhvb2RzIGFsc28gdGVuZCB0byBiZSBtb3JlIHNhdGlzZmllZCB3aXRoIGxpZmUuIFBhcnQgb2YgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gbGlmZSBzYXRpc2ZhY3Rpb24gYW5kIGhlYWx0aCBpbiB0aGUgcHJldmlvdXMgbW9kZWwgdGhlcmVmb3JlIHJlZmxlY3RlZCBkaWZmZXJlbmNlcyBpbiBuZWlnaGJvcmhvb2Qgc2FmZXR5LiBCZWNhdXNlIGxpZmUgc2F0aXNmYWN0aW9uIHdhcyBncmFuZC1tZWFuIGNlbnRlcmVkIGFuZCAzMSUgb2YgaXRzIHZhcmlhbmNlIGxpZXMgYmV0d2VlbiBob3VzZWhvbGRzLCBpdHMgY29lZmZpY2llbnQgYmxlbmRzIHdpdGhpbi0gYW5kIGJldHdlZW4taG91c2Vob2xkIGRpZmZlcmVuY2VzLCBhbmQgaXQgaXMgdGhpcyBiZXR3ZWVuLWhvdXNlaG9sZCBwb3J0aW9uIHRoYXQgbmVpZ2hib3Job29kIHNhZmV0eSBwYXJ0bHkgYWJzb3Jicy4gRXZlbiBzbywgbGlmZSBzYXRpc2ZhY3Rpb24gcmVtYWlucyBhIHN0cm9uZyBhbmQgaW5kZXBlbmRlbnQgcHJlZGljdG9yIG9mIHNlbGYtcmF0ZWQgaGVhbHRoLg0KDQoqKk5laWdoYm9yaG9vZCBzYWZldHkgKCRcZ2FtbWFfezAxfSQsIExldmVsIDIpLioqIFRoZSBmaXhlZCBlZmZlY3Qgb2YgbmVpZ2hib3Job29kIHNhZmV0eSB3YXMgMC4yMjIgKCpTRSogPSAwLjAwOCwgKnQqKDEwLDYxMCkgPSAyOS4yOCwgKnAqIDwgLjAwMSwgOTUlIENJIFswLjIwNywgMC4yMzddKS4gKipIb2xkaW5nIGxpZmUgc2F0aXNmYWN0aW9uIGNvbnN0YW50LCBlYWNoIG9uZS1jYXRlZ29yeSBpbmNyZWFzZSBpbiBhIGhvdXNlaG9sZCdzIHBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5IChmb3IgZXhhbXBsZSwgZnJvbSAiZ29vZCIgdG8gInZlcnkgZ29vZCIpIGlzIGFzc29jaWF0ZWQgd2l0aCBhIDAuMjItcG9pbnQgaW5jcmVhc2UgaW4gdGhlIGV4cGVjdGVkIHNlbGYtcmF0ZWQgaGVhbHRoIG9mIHRoZSByZXNwb25kZW50cyBsaXZpbmcgdGhlcmUuKiogQWNyb3NzIHRoZSBmdWxsIGZvdXItY2F0ZWdvcnkgcmFuZ2Ugb2YgdGhlIHNjYWxlLCBmcm9tICJwb29yIiB0byAiZXhjZWxsZW50IiBzYWZldHksIHRoaXMgY29ycmVzcG9uZHMgdG8gYW4gZXhwZWN0ZWQgZGlmZmVyZW5jZSBvZiBhYm91dCAwLjg5IHBvaW50cyBpbiBzZWxmLXJhdGVkIGhlYWx0aCDigJQgbmVhcmx5IG9uZSBmdWxsIGhlYWx0aCBjYXRlZ29yeS4gQmVjYXVzZSBuZWlnaGJvcmhvb2Qgc2FmZXR5IGlzIGEgaG91c2Vob2xkLWxldmVsIHZhcmlhYmxlLCB0aGlzIGVmZmVjdCBkZXNjcmliZXMgZGlmZmVyZW5jZXMgYmV0d2VlbiBob3VzZWhvbGRzOiBob3VzZWhvbGRzIGluIG5laWdoYm9yaG9vZHMgcGVyY2VpdmVkIGFzIHNhZmVyIGhhdmUgaGlnaGVyIGF2ZXJhZ2Ugc2VsZi1yYXRlZCBoZWFsdGguICoqSHlwb3RoZXNpcyAyIHdhcyBzdXBwb3J0ZWQuKioNCg0KKipWYXJpYW5jZSBleHBsYWluZWQuKiogMjUuNyUgb2YgYmV0d2Vlbi1ob3VzZWhvbGQgdmFyaWFuY2UgdW5pcXVlbHkgZXhwbGFpbmVkIGJ5IHNhZmV0eSwgNDcuOSUgZXhwbGFpbmVkIGJ5IGJvdGggcHJlZGljdG9ycyB0b2dldGhlciwgYW5kIDUuNSUgb2Ygd2l0aGluLWhvdXNlaG9sZCB2YXJpYW5jZSBleHBsYWluZWQgcmVsYXRpdmUgdG8gdGhlIHVuY29uZGl0aW9uYWwgbW9kZWwuIEFzIGV4cGVjdGVkIGZvciBhIGhvdXNlaG9sZC1sZXZlbCBwcmVkaWN0b3IsIHRoZSB3aXRoaW4taG91c2Vob2xkIHZhcmlhbmNlIHdhcyBlc3NlbnRpYWxseSB1bmNoYW5nZWQgYnkgYWRkaW5nIG5laWdoYm9yaG9vZCBzYWZldHkgKDAuNzE0IHRvIDAuNzExLCBhIDAuMyUgcmVkdWN0aW9uKSwgc2luY2UgYSB2YXJpYWJsZSB0aGF0IGlzIGlkZW50aWNhbCBmb3IgYm90aCBtZW1iZXJzIG9mIGEgaG91c2Vob2xkIGNhbm5vdCBleHBsYWluIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlbS4NCg0KWzJwdDogc3VtbWFyeSBtYWtlcyBzZW5zZSwgYWNjdXJhdGUgYW5kIGNvbXBsZXRlLiAxcHQ6IHNvbWUgZXJyb3JzIG9yIG1pc3NpbmcgaW5mb3JtYXRpb24uIDBwdDogbWFueSBlcnJvcnMgb3IgbWlzc2luZyBpbmZvcm1hdGlvbiAoZS5nLiwgb3ZlciBoYWxmIHByb2JsZW1hdGljKV17c3R5bGU9ImNvbG9yOiByZWQ7In0NCg0KIyBXcml0ZS11cA0KDQpbQ2hvb3NlIHRoZSBmaW5hbCBtb2RlbCB0aGF0IGFuc3dlcnMgeW91ciByZXNlYXJjaCBxdWVzdGlvbnMgYW5kIHRlc3RzIHlvdXIgaHlwb3RoZXNlcy5de3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCltXcml0ZSBhIHByZXNlbnQgc3R1ZHkgc2VjdGlvbiwgYW5hbHl0aWMgc3RyYXRlZ3kgKHRoYXQgaW5jbHVkZXMgdGhlIGVxdWF0aW9ucyBhbmQgZXhwbGFuYXRpb25zKSwgYW5kIHJlc3VsdHMgc2VjdGlvbiBiYXNlZCBvbiB0aGF0IG1vZGVsIGJlbG93IChISU5UOiBzZWUgd2VlayA0IGZpbGVzIGZvciBleGFtcGxlKS5de3N0eWxlPSJjb2xvcjogcHVycGxlOyJ9DQoNCiMjIFByZXNlbnQgU3R1ZHkNCg0KU2VsZi1yYXRlZCBoZWFsdGgg4oCUIGEgcGVyc29uJ3Mgb3duIGdsb2JhbCBhc3Nlc3NtZW50IG9mIHdoZXRoZXIgdGhlaXIgaGVhbHRoIGlzIGV4Y2VsbGVudCwgdmVyeSBnb29kLCBnb29kLCBmYWlyLCBvciBwb29yIOKAlCBpcyBvbmUgb2YgdGhlIG1vc3Qgd2lkZWx5IHVzZWQgaGVhbHRoIG1lYXN1cmVzIGluIHJlc2VhcmNoIG9uIGFnaW5nLCBhbmQgaXQgaXMga25vd24gdG8gcHJlZGljdCBsYXRlciBtb3JiaWRpdHkgYW5kIG1vcnRhbGl0eS4gQmVjYXVzZSBpdCByZWZsZWN0cyBib3RoIHBoeXNpY2FsIGNvbmRpdGlvbiBhbmQgaG93IHBlb3BsZSBwZXJjZWl2ZSB0aGVpciBsaXZlcywgaXQgaXMgcGxhdXNpYmx5IHNoYXBlZCBieSBmYWN0b3JzIGF0IG1vcmUgdGhhbiBvbmUgbGV2ZWwuIEF0IHRoZSBpbmRpdmlkdWFsIGxldmVsLCBhIHBlcnNvbidzIG92ZXJhbGwgc2Vuc2Ugb2Ygd2VsbC1iZWluZyBtYXkgY29sb3IgaG93IHRoZXkgZXZhbHVhdGUgdGhlaXIgb3duIGhlYWx0aC4gQXQgdGhlIGhvdXNlaG9sZCBsZXZlbCwgdGhlIHJlc2lkZW50aWFsIGVudmlyb25tZW50IHBlb3BsZSBzaGFyZSDigJQgaW5jbHVkaW5nIGhvdyBzYWZlIHRoZWlyIG5laWdoYm9yaG9vZCBmZWVscyDigJQgbWF5IGFmZmVjdCBoZWFsdGggdGhyb3VnaCBzdHJlc3MsIG9wcG9ydHVuaXRpZXMgZm9yIHBoeXNpY2FsIGFjdGl2aXR5LCBhbmQgc29jaWFsIGVuZ2FnZW1lbnQuDQoNClRoZXNlIHR3byBpbmZsdWVuY2VzIGFyZSBtZWFzdXJlZCBhdCBkaWZmZXJlbnQgbGV2ZWxzIGJ5IGRlc2lnbi4gTGlmZSBzYXRpc2ZhY3Rpb24gaXMgcmVwb3J0ZWQgYnkgZWFjaCByZXNwb25kZW50IGFib3V0IHRoZW1zZWx2ZXMgYW5kIGNhbiBkaWZmZXIgYmV0d2VlbiB0d28gcGVvcGxlIGxpdmluZyBpbiB0aGUgc2FtZSBob3VzZWhvbGQuIFBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5IGRlc2NyaWJlcyB3aGVyZSBhIGhvdXNlaG9sZCBsaXZlcywgaXMgcmVwb3J0ZWQgb25jZSBwZXIgaG91c2Vob2xkLCBhbmQgaXMgdGhlIHNhbWUgZm9yIGV2ZXJ5b25lIGluIGl0LiBCZWNhdXNlIHJlc3BvbmRlbnRzIHdobyBzaGFyZSBhIGhvdXNlaG9sZCBhcmUgbGlrZWx5IHRvIHJlc2VtYmxlIGVhY2ggb3RoZXIgaW4gdGhlaXIgaGVhbHRoLCBhbmQgYmVjYXVzZSBvbmUgcHJlZGljdG9yIGV4aXN0cyBvbmx5IGF0IHRoZSBob3VzZWhvbGQgbGV2ZWwsIGEgbXVsdGlsZXZlbCBtb2RlbCBpcyBuZWVkZWQgdG8gZXN0aW1hdGUgYm90aCBlZmZlY3RzIGNvcnJlY3RseS4NCg0KVGhlIHByZXNlbnQgc3R1ZHkgYXNrczogKipEbyBwZXJjZWl2ZWQgbmVpZ2hib3Job29kIHNhZmV0eSAoYSBob3VzZWhvbGQtbGV2ZWwgY2hhcmFjdGVyaXN0aWMpIGFuZCBsaWZlIHNhdGlzZmFjdGlvbiAoYW4gaW5kaXZpZHVhbC1sZXZlbCBjaGFyYWN0ZXJpc3RpYykgcHJlZGljdCBzZWxmLXJhdGVkIGhlYWx0aCBhbW9uZyBvbGRlciBhZHVsdHMgaW4gdGhlIFVuaXRlZCBTdGF0ZXM/KiogVHdvIGh5cG90aGVzZXMgd2VyZSB0ZXN0ZWQ6DQoNCi0gKipIeXBvdGhlc2lzIDEgKExldmVsIDEpOioqIFJlc3BvbmRlbnRzIHdobyByZXBvcnQgaGlnaGVyIGxpZmUgc2F0aXNmYWN0aW9uIHdpbGwgcmVwb3J0IGJldHRlciBzZWxmLXJhdGVkIGhlYWx0aC4NCi0gKipIeXBvdGhlc2lzIDIgKExldmVsIDIpOioqIFJlc3BvbmRlbnRzIGxpdmluZyBpbiBob3VzZWhvbGRzIHdob3NlIG5laWdoYm9yaG9vZHMgYXJlIHBlcmNlaXZlZCBhcyBzYWZlciB3aWxsIHJlcG9ydCBiZXR0ZXIgc2VsZi1yYXRlZCBoZWFsdGguDQoNCkRhdGEgY29tZSBmcm9tIHRoZSAyMDIyIENvcmUgKEZpbmFsLCBWZXJzaW9uIDIuMCkgcHVibGljIHJlbGVhc2Ugb2YgdGhlIEhlYWx0aCBhbmQgUmV0aXJlbWVudCBTdHVkeSAoSFJTKSwgYSBuYXRpb25hbGx5IHJlcHJlc2VudGF0aXZlIGxvbmdpdHVkaW5hbCBzdHVkeSBvZiBBbWVyaWNhbnMgb3ZlciBhZ2UgNTAgY29uZHVjdGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mIE1pY2hpZ2FuJ3MgSW5zdGl0dXRlIGZvciBTb2NpYWwgUmVzZWFyY2guIFRocmVlIGZpbGVzIHdlcmUgbWVyZ2VkOiBTZWN0aW9uIEIgKERlbW9ncmFwaGljczsgSDIyQl9SKSBhbmQgU2VjdGlvbiBDIChQaHlzaWNhbCBIZWFsdGg7IEgyMkNfUiksIGJvdGggd2l0aCBvbmUgcmVjb3JkIHBlciByZXNwb25kZW50LCBhbmQgU2VjdGlvbiBIIChIb3VzaW5nOyBIMjJIX0gpLCB3aXRoIG9uZSByZWNvcmQgcGVyIGhvdXNlaG9sZC4gVGhlIGFuYWx5dGljIHNhbXBsZSBjb25zaXN0ZWQgb2YgMTQsNTQxIHJlc3BvbmRlbnRzIG5lc3RlZCB3aXRoaW4gMTEsMDMxIGhvdXNlaG9sZHMsIGFuIGF2ZXJhZ2Ugb2YgYWJvdXQgMS4zMiByZXNwb25kZW50cyBwZXIgaG91c2Vob2xkLg0KDQojIyBBbmFseXRpYyBTdHJhdGVneQ0KDQoqKk1lYXN1cmVzLioqIFRoZSBvdXRjb21lLCAqc2VsZi1yYXRlZCBoZWFsdGgqIChgU0MwMDFgKSwgYXNrZWQgcmVzcG9uZGVudHMgd2hldGhlciB0aGVpciBoZWFsdGggd2FzIGV4Y2VsbGVudCwgdmVyeSBnb29kLCBnb29kLCBmYWlyLCBvciBwb29yLiBUaGUgTGV2ZWwgMSBwcmVkaWN0b3IsICpsaWZlIHNhdGlzZmFjdGlvbiogKGBTQjAwMGApLCBhc2tlZCByZXNwb25kZW50cyBob3cgc2F0aXNmaWVkIHRoZXkgd2VyZSB3aXRoIHRoZWlyIGxpZmUgYXMgYSB3aG9sZSwgZnJvbSBjb21wbGV0ZWx5IHNhdGlzZmllZCB0byBub3QgYXQgYWxsIHNhdGlzZmllZC4gVGhlIExldmVsIDIgcHJlZGljdG9yLCAqcGVyY2VpdmVkIG5laWdoYm9yaG9vZCBzYWZldHkqIChgU0gxNTBgKSwgYXNrZWQgdGhlIGhvdXNlaG9sZCdzIGZpbmFuY2lhbC9mYW1pbHkgcmVzcG9uZGVudCB0byByYXRlIHRoZSBzYWZldHkgb2YgdGhlaXIgbmVpZ2hib3Job29kIGZyb20gZXhjZWxsZW50IHRvIHBvb3I7IHRoaXMgc2luZ2xlIGFuc3dlciBhcHBsaWVzIHRvIGV2ZXJ5IHJlc3BvbmRlbnQgaW4gdGhlIGhvdXNlaG9sZC4gQWxsIHRocmVlIGl0ZW1zIHdlcmUgb3JpZ2luYWxseSBjb2RlZCAxIChiZXN0KSB0byA1ICh3b3JzdCkgYW5kIHdlcmUgcmV2ZXJzZS1jb2RlZCAoNiBtaW51cyB0aGUgb3JpZ2luYWwgc2NvcmUpIHNvIHRoYXQgaGlnaGVyIHZhbHVlcyBpbmRpY2F0ZSBiZXR0ZXIgaGVhbHRoLCBncmVhdGVyIHNhdGlzZmFjdGlvbiwgYW5kIGEgc2FmZXIgbmVpZ2hib3Job29kLiBBbGwgdGhyZWUgd2VyZSB0cmVhdGVkIGFzIGFwcHJveGltYXRlbHkgY29udGludW91cy4NCg0KKipEYXRhIHByZXBhcmF0aW9uLioqIEhSUyBtaXNzaW5nLWRhdGEgY29kZXMgKOKIkjggPSB3ZWIgbm9uLXJlc3BvbnNlLCA4ID0gZG9uJ3Qga25vdywgOSA9IHJlZnVzZWQpIHdlcmUgc2V0IHRvIG1pc3NpbmcsIGFuZCByZXNwb25kZW50cyBtaXNzaW5nIGFueSBvZiB0aGUgdGhyZWUgdmFyaWFibGVzIHdlcmUgcmVtb3ZlZCBsaXN0d2lzZS4gVGhlIHR3byByZXNwb25kZW50IGZpbGVzIHdlcmUgbWVyZ2VkIGJ5IGhvdXNlaG9sZCBhbmQgcGVyc29uIGlkZW50aWZpZXJzIChgSEhJRGAsIGBQTmApLCBhbmQgdGhlIGhvdXNpbmcgZmlsZSB3YXMgbWVyZ2VkIGJ5IGhvdXNlaG9sZCBhbmQgc3ViLWhvdXNlaG9sZCBpZGVudGlmaWVycyAoYEhISURgLCBgU1NVQkhIYCkuIFRoZSBjbHVzdGVyIGlkZW50aWZpZXIgd2FzIGNyZWF0ZWQgYnkgY29tYmluaW5nIGBISElEYCBhbmQgYFNTVUJISGAsIGJlY2F1c2UgYEhISURgIGFsb25lIGdyb3VwcyB0b2dldGhlciBob3VzZWhvbGRzIHRoYXQgc3BsaXQgYWZ0ZXIgYSBkaXZvcmNlIG9yIHNlcGFyYXRpb24sIGV2ZW4gdGhvdWdoIHRoZWlyIG1lbWJlcnMgbm8gbG9uZ2VyIGxpdmUgdG9nZXRoZXIuDQoNCk91dGxpZXJzIHdlcmUgc2NyZWVuZWQgdXNpbmcgc3RhbmRhcmRpemVkIHNjb3JlcyAofCp6KnwgPiAzLjI5KS4gTm8gY2FzZXMgd2VyZSBmbGFnZ2VkIGZvciBzZWxmLXJhdGVkIGhlYWx0aCBvciBuZWlnaGJvcmhvb2Qgc2FmZXR5LiBGb3IgbGlmZSBzYXRpc2ZhY3Rpb24sIHRoZSBsb3dlc3QgY2F0ZWdvcnkgKCJub3QgYXQgYWxsIHNhdGlzZmllZCIpIGZlbGwgYXQgKnoqID0g4oiSMy4zNCwgc28gYWxsIDE2NCByZXNwb25kZW50cyBpbiB0aGF0IGNhdGVnb3J5IHdlcmUgZmxhZ2dlZC4gVGhlc2Ugd2VyZSBsZWdpdGltYXRlIHJlc3BvbnNlcywgc28gcmF0aGVyIHRoYW4gZGVsZXRpbmcgdGhlbSwgdGhleSB3ZXJlIHdpbnNvcml6ZWQgdG8gdGhlIG5lYXJlc3Qgbm9uLWZsYWdnZWQgdmFsdWUgKHJlY29kZWQgZnJvbSAxIHRvIDIpOyBhZnRlciB3aW5zb3JpemluZywgbm8gY2FzZXMgZXhjZWVkZWQgdGhlIGN1dG9mZi4gTm8gdHJhbnNmb3JtYXRpb25zIHdlcmUgYXBwbGllZCwgYmVjYXVzZSBhbGwgc2tld25lc3MgYW5kIGt1cnRvc2lzIHZhbHVlcyB3ZXJlIHdpdGhpbiBjb252ZW50aW9uYWwgbGltaXRzICh8c2tld3wg4omkIDAuNTYsIHxrdXJ0b3Npc3wg4omkIDAuNTYpLg0KDQoqKkNlbnRlcmluZy4qKiBCb3RoIHByZWRpY3RvcnMgd2VyZSBncmFuZC1tZWFuIGNlbnRlcmVkIHNvIHRoYXQgdGhlIGludGVyY2VwdCB3b3VsZCByZXByZXNlbnQgYSBtZWFuaW5nZnVsIHZhbHVlLCBzaW5jZSAwIGlzIG5vdCBhIHBvc3NpYmxlIHNjb3JlIG9uIGVpdGhlciBzY2FsZS4gTGlmZSBzYXRpc2ZhY3Rpb24gd2FzIGNlbnRlcmVkIGF0IGl0cyBtZWFuIGFjcm9zcyByZXNwb25kZW50cy4gR3JhbmQtbWVhbiBjZW50ZXJpbmcgd2FzIGNob3NlbiBvdmVyIGdyb3VwLW1lYW4gY2VudGVyaW5nIGJlY2F1c2UgdGhlIGh5cG90aGVzaXMgY29uY2VybnMgZGlmZmVyZW5jZXMgYmV0d2VlbiBwZW9wbGUgaW4gZ2VuZXJhbCByYXRoZXIgdGhhbiBkaWZmZXJlbmNlcyByZWxhdGl2ZSB0byBvbmUncyBvd24gaG91c2Vob2xkIHBhcnRuZXIsIGFuZCBiZWNhdXNlIG1vc3QgaG91c2Vob2xkcyBjb250YWluIG9ubHkgb25lIHJlc3BvbmRlbnQsIGZvciB3aG9tIGEgZ3JvdXAtbWVhbi1jZW50ZXJlZCBzY29yZSB3b3VsZCBhbHdheXMgYmUgMC4gTmVpZ2hib3Job29kIHNhZmV0eSB3YXMgY2VudGVyZWQgYXQgaXRzIG1lYW4gYWNyb3NzIGhvdXNlaG9sZHMsIHNvIHRoYXQgdHdvLXJlc3BvbmRlbnQgaG91c2Vob2xkcyB3ZXJlIG5vdCBjb3VudGVkIHR3aWNlLiBUaGUgb3V0Y29tZSB3YXMgbm90IGNlbnRlcmVkLg0KDQoqKkVzdGltYXRpb24uKiogVHdvLWxldmVsIGxpbmVhciBtaXhlZCBtb2RlbHMgd2VyZSBlc3RpbWF0ZWQgaW4gUiB1c2luZyB0aGUgYGxtZXIoKWAgZnVuY3Rpb24gZnJvbSB0aGUgKipsbWU0KiogYW5kICoqbG1lclRlc3QqKiBwYWNrYWdlcywgd2l0aCByZXN0cmljdGVkIG1heGltdW0gbGlrZWxpaG9vZCAoUkVNTCkgZXN0aW1hdGlvbiBhbmQgU2F0dGVydGh3YWl0ZSBkZWdyZWVzIG9mIGZyZWVkb20gZm9yIHRlc3RzIG9mIGZpeGVkIGVmZmVjdHMuIE1vZGVscyB0aGF0IGRpZmZlcmVkIGluIHRoZWlyIGZpeGVkIGVmZmVjdHMgd2VyZSBjb21wYXJlZCB3aXRoIGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMgYWZ0ZXIgcmVmaXR0aW5nIHdpdGggbWF4aW11bSBsaWtlbGlob29kIChNTCksIHNpbmNlIFJFTUwgbGlrZWxpaG9vZHMgYXJlIG5vdCBjb21wYXJhYmxlIGFjcm9zcyBkaWZmZXJlbnQgZml4ZWQgZWZmZWN0cy4gTW9kZWxzIHRoYXQgZGlmZmVyZWQgb25seSBpbiB0aGVpciByYW5kb20gZWZmZWN0cyB3ZXJlIGNvbXBhcmVkIHVzaW5nIHRoZWlyIFJFTUwgZml0cy4NCg0KKipNb2RlbCBidWlsZGluZy4qKiBNb2RlbHMgd2VyZSBidWlsdCBpbiBmb3VyIHN0ZXBzLiBGaXJzdCwgYW4gdW5jb25kaXRpb25hbCAoaW50ZXJjZXB0LW9ubHkpIG1vZGVsIGRpdmlkZWQgdGhlIHZhcmlhbmNlIGluIHNlbGYtcmF0ZWQgaGVhbHRoIGludG8gYmV0d2Vlbi1ob3VzZWhvbGQgYW5kIHdpdGhpbi1ob3VzZWhvbGQgcGFydHMsIGFuZCB0aGUgaW50cmFjbGFzcyBjb3JyZWxhdGlvbiAoSUNDKSB3YXMgY2FsY3VsYXRlZCB0byBhc3Nlc3MgdGhlIGRlZ3JlZSBvZiBjbHVzdGVyaW5nLiBTZWNvbmQsIGxpZmUgc2F0aXNmYWN0aW9uIHdhcyBhZGRlZCBhcyBhIGZpeGVkIGVmZmVjdC4gVGhpcmQsIGEgcmFuZG9tIHNsb3BlIGZvciBsaWZlIHNhdGlzZmFjdGlvbiB3YXMgdGVzdGVkIHRvIHNlZSB3aGV0aGVyIGl0cyBlZmZlY3QgdmFyaWVkIGFjcm9zcyBob3VzZWhvbGRzLiBGb3VydGgsIGJhc2VkIG9uIHRoZSByZXN1bHQgb2YgdGhhdCB0ZXN0LCBuZWlnaGJvcmhvb2Qgc2FmZXR5IHdhcyBhZGRlZCB0byB0aGUgTGV2ZWwgMiBpbnRlcmNlcHQgZXF1YXRpb24uDQoNClRoZSByYW5kb20gc2xvcGUgd2FzIG5vdCByZXRhaW5lZC4gV2l0aCB0d28gcmFuZG9tIGVmZmVjdHMgcGVyIGhvdXNlaG9sZCwgdGhlIG1vZGVsIHJlcXVpcmVkIDIyLDA2MiByYW5kb20gZWZmZWN0cyBidXQgaGFkIG9ubHkgMTQsNTQxIG9ic2VydmF0aW9ucywgc28gbG1lNCB3b3VsZCBub3QgZml0IGl0IHVuZGVyIGl0cyBkZWZhdWx0IHNldHRpbmdzLCBiZWNhdXNlIHRoZSBob3VzZWhvbGQtbGV2ZWwgc2xvcGUgdmFyaWFuY2UgY291bGQgbm90IGJlIHNlcGFyYXRlbHkgaWRlbnRpZmllZC4gV2hlbiB0aGUgbW9kZWwgd2FzIGVzdGltYXRlZCB3aXRoIHRoaXMgY2hlY2sgb3ZlcnJpZGRlbiwgaXQgZml0IGJldHRlciwgJFxjaGleMiQoMikgPSA1NC44MSwgKnAqIDwgLjAwMS4gSG93ZXZlciwgd2l0aCBtb3N0IGhvdXNlaG9sZHMgY29udHJpYnV0aW5nIG9ubHkgb25lIHJlc3BvbmRlbnQsIGEgcmFuZG9tIHNsb3BlIGNhbm5vdCBiZSBkaXN0aW5ndWlzaGVkIGZyb20gc2VsZi1yYXRlZCBoZWFsdGggc2ltcGx5IGJlaW5nIG1vcmUgdmFyaWFibGUgYXQgdGhlIGV4dHJlbWVzIG9mIGxpZmUgc2F0aXNmYWN0aW9uLCBhbmQgdGhlIGVzdGltYXRlcyBpbXBsaWVkIHRoYXQgYWJvdXQgNyUgb2YgaG91c2Vob2xkcyBoYWQgYSBuZWdhdGl2ZSBhc3NvY2lhdGlvbiwgd2hpY2ggaXMgbm90IHN1YnN0YW50aXZlbHkgcGxhdXNpYmxlLiBUaGUgZml4ZWQgZWZmZWN0IG9mIGxpZmUgc2F0aXNmYWN0aW9uIHdhcyBuZWFybHkgaWRlbnRpY2FsIHdpdGggYW5kIHdpdGhvdXQgdGhlIHJhbmRvbSBzbG9wZSAoMC40MjcgdnMuIDAuNDIxKS4gQSByYW5kb20taW50ZXJjZXB0IG1vZGVsIHdhcyB0aGVyZWZvcmUgdXNlZCBmb3IgdGhlIGZpbmFsIG1vZGVsLg0KDQoqKkZpbmFsIG1vZGVsLioqIFRoZSBmaW5hbCBtb2RlbCB3YXM6DQoNCkxldmVsIDEgKHJlc3BvbmRlbnQpOg0KDQokJA0KXHRleHR7SGVhbHRofV97aWp9ID0gXGJldGFfezBqfSArIFxiZXRhX3sxan0oXHRleHR7TGlmZVNhdH1fe2lqfSAtIFxvdmVybGluZXtcdGV4dHtMaWZlU2F0fX1fey4ufSkgKyByX3tpan0sIFxxcXVhZCByX3tpan0gXHNpbSBOKDAsIFxzaWdtYV4yKQ0KJCQNCg0KTGV2ZWwgMiAoaG91c2Vob2xkKToNCg0KJCQNClxiZXRhX3swan0gPSBcZ2FtbWFfezAwfSArIFxnYW1tYV97MDF9KFx0ZXh0e1NhZmV0eX1fe2p9IC0gXG92ZXJsaW5le1x0ZXh0e1NhZmV0eX19X3sufSkgKyB1X3swan0sIFxxcXVhZCB1X3swan0gXHNpbSBOKDAsIFx0YXVfezAwfSkNCiQkDQoNCiQkDQpcYmV0YV97MWp9ID0gXGdhbW1hX3sxMH0NCiQkDQoNCkNvbWJpbmVkOg0KDQokJA0KXHRleHR7SGVhbHRofV97aWp9ID0gXGdhbW1hX3swMH0gKyBcZ2FtbWFfezAxfShcdGV4dHtTYWZldHl9X3tqfSAtIFxvdmVybGluZXtcdGV4dHtTYWZldHl9fV97Ln0pICsgXGdhbW1hX3sxMH0oXHRleHR7TGlmZVNhdH1fe2lqfSAtIFxvdmVybGluZXtcdGV4dHtMaWZlU2F0fX1fey4ufSkgKyB1X3swan0gKyByX3tpan0NCiQkDQoNCkhlcmUsICRcdGV4dHtIZWFsdGh9X3tpan0kIGlzIHRoZSBzZWxmLXJhdGVkIGhlYWx0aCBvZiByZXNwb25kZW50ICRpJCBpbiBob3VzZWhvbGQgJGokLiAkXGdhbW1hX3swMH0kIGlzIHRoZSBleHBlY3RlZCBzZWxmLXJhdGVkIGhlYWx0aCBvZiBhIHJlc3BvbmRlbnQgd2l0aCBhdmVyYWdlIGxpZmUgc2F0aXNmYWN0aW9uIGluIGEgaG91c2Vob2xkIHdpdGggYXZlcmFnZSBuZWlnaGJvcmhvb2Qgc2FmZXR5LiAkXGdhbW1hX3sxMH0kIGlzIHRoZSBmaXhlZCBlZmZlY3Qgb2YgbGlmZSBzYXRpc2ZhY3Rpb24sIGNvbnN0cmFpbmVkIHRvIGJlIHRoZSBzYW1lIGluIGV2ZXJ5IGhvdXNlaG9sZC4gJFxnYW1tYV97MDF9JCBpcyB0aGUgZml4ZWQgZWZmZWN0IG9mIG5laWdoYm9yaG9vZCBzYWZldHk7IGJlY2F1c2Ugc2FmZXR5IGhhcyBvbmx5IGEgJGokIHN1YnNjcmlwdCDigJQgaXQgdmFyaWVzIGJldHdlZW4gaG91c2Vob2xkcyBidXQgbm90IHdpdGhpbiB0aGVtIOKAlCBpdCBwcmVkaWN0cyB0aGUgaG91c2Vob2xkIGludGVyY2VwdCByYXRoZXIgdGhhbiBhcHBlYXJpbmcgaW4gdGhlIExldmVsIDEgZXF1YXRpb24uICR1X3swan0kIGlzIHRoZSBwYXJ0IG9mIGhvdXNlaG9sZCAkaiQncyBtZWFuIGhlYWx0aCBub3QgZXhwbGFpbmVkIGJ5IG5laWdoYm9yaG9vZCBzYWZldHksIHdpdGggdmFyaWFuY2UgJFx0YXVfezAwfSQgKHJlc2lkdWFsIGJldHdlZW4taG91c2Vob2xkIHZhcmlhbmNlKSwgYW5kICRyX3tpan0kIGlzIHRoZSByZXNwb25kZW50J3MgZGV2aWF0aW9uIGZyb20gdGhlaXIgaG91c2Vob2xkJ3MgZXhwZWN0ZWQgdmFsdWUsIHdpdGggdmFyaWFuY2UgJFxzaWdtYV4yJCAod2l0aGluLWhvdXNlaG9sZCB2YXJpYW5jZSkuIEh5cG90aGVzaXMgMSBpcyB0ZXN0ZWQgYnkgJFxnYW1tYV97MTB9JCBhbmQgSHlwb3RoZXNpcyAyIGJ5ICRcZ2FtbWFfezAxfSQ7IGVhY2ggaXMgc3VwcG9ydGVkIGlmIHRoZSBjb2VmZmljaWVudCBpcyBwb3NpdGl2ZSBhbmQgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgZnJvbSAwLg0KDQojIyBSZXN1bHRzDQoNCioqRGVzY3JpcHRpdmUgc3RhdGlzdGljcy4qKiBTZWxmLXJhdGVkIGhlYWx0aCBhdmVyYWdlZCAzLjA4ICgqU0QqID0gMS4wMiksIGNsb3NlIHRvICJnb29kLCIgYW5kIHdhcyByb3VnaGx5IHN5bW1ldHJpYyAoc2tldyA9IOKIkjAuMDksIGt1cnRvc2lzID0g4oiSMC41NikuIExpZmUgc2F0aXNmYWN0aW9uIGF2ZXJhZ2VkIDMuODQgKCpTRCogPSAwLjg1KSBiZWZvcmUgd2luc29yaXppbmcgYW5kIHdhcyBtaWxkbHkgbmVnYXRpdmVseSBza2V3ZWQgKHNrZXcgPSDiiJIwLjQ3LCBrdXJ0b3NpcyA9IDAuMjIpLCByZWZsZWN0aW5nIHRoYXQgbW9zdCByZXNwb25kZW50cyByZXBvcnRlZCBiZWluZyB2ZXJ5IG9yIGNvbXBsZXRlbHkgc2F0aXNmaWVkLiBOZWlnaGJvcmhvb2Qgc2FmZXR5IGF2ZXJhZ2VkIDMuNzggKCpTRCogPSAxLjA3KSBhbmQgd2FzIGFsc28gbWlsZGx5IG5lZ2F0aXZlbHkgc2tld2VkIChza2V3ID0g4oiSMC41Niwga3VydG9zaXMgPSDiiJIwLjQ5KSwgYXMgbW9zdCByZXNwb25kZW50cyBkZXNjcmliZWQgdGhlaXIgbmVpZ2hib3Job29kIGFzIHNhZmUuDQoNCioqRGVncmVlIG9mIG5lc3RpbmcuKiogSW4gdGhlIHVuY29uZGl0aW9uYWwgbW9kZWwsIHRoZSBncmFuZCBtZWFuIG9mIHNlbGYtcmF0ZWQgaGVhbHRoIHdhcyAkXGdhbW1hX3swMH0kID0gMy4wNyAoKlNFKiA9IDAuMDA5LCA5NSUgQ0kgWzMuMDUsIDMuMDldKS4gVGhlIGJldHdlZW4taG91c2Vob2xkIHZhcmlhbmNlIHdhcyAkXHRhdV97MDB9JCA9IDAuMjg4IGFuZCB0aGUgd2l0aGluLWhvdXNlaG9sZCB2YXJpYW5jZSB3YXMgJFxzaWdtYV4yJCA9IDAuNzUyLCBnaXZpbmcgYW4gSUNDIG9mIC4yODogYWJvdXQgMjcuNyUgb2YgdGhlIHZhcmlhbmNlIGluIHNlbGYtcmF0ZWQgaGVhbHRoIHdhcyBiZXR3ZWVuIGhvdXNlaG9sZHMgYW5kIDcyLjMlIHdhcyB3aXRoaW4gaG91c2Vob2xkcy4gRm9yIHRoZSBwcmVkaWN0b3JzLCAzMS4yJSBvZiB0aGUgdmFyaWFuY2UgaW4gbGlmZSBzYXRpc2ZhY3Rpb24gd2FzIGJldHdlZW4gaG91c2Vob2xkcyAoSUNDID0gLjMxKSwgY29uZmlybWluZyB0aGF0IGl0IHZhcmllcyBtZWFuaW5nZnVsbHkgd2l0aGluIGhvdXNlaG9sZHMgYW5kIGJlbG9uZ3MgYXQgTGV2ZWwgMSwgd2hpbGUgMTAwJSBvZiB0aGUgdmFyaWFuY2UgaW4gbmVpZ2hib3Job29kIHNhZmV0eSB3YXMgYmV0d2VlbiBob3VzZWhvbGRzIChJQ0MgPSAxLjAwKSwgY29uZmlybWluZyB0aGF0IGl0IGlzIGEgcHVyZWx5IGhvdXNlaG9sZC1sZXZlbCB2YXJpYWJsZS4NCg0KKipMaWZlIHNhdGlzZmFjdGlvbiBvbmx5LioqIEFkZGluZyBsaWZlIHNhdGlzZmFjdGlvbiBwcm9kdWNlZCBhIGZpeGVkIGVmZmVjdCBvZiAkXGdhbW1hX3sxMH0kID0gMC40MjEgKCpTRSogPSAwLjAxMCwgKnQqKDE0LDQ5MCkgPSA0My4zMSwgKnAqIDwgLjAwMSkgYW5kIHNpZ25pZmljYW50bHkgaW1wcm92ZWQgZml0IG92ZXIgdGhlIHVuY29uZGl0aW9uYWwgbW9kZWwsICRcY2hpXjIkKDEpID0gMTc1Mi44LCAqcCogPCAuMDAxLiBJdCByZWR1Y2VkIHRoZSBiZXR3ZWVuLWhvdXNlaG9sZCB2YXJpYW5jZSBieSAyOS45JSAodG8gMC4yMDIpIGFuZCB0aGUgd2l0aGluLWhvdXNlaG9sZCB2YXJpYW5jZSBieSA1LjElICh0byAwLjcxNCkuDQoNCioqRmluYWwgbW9kZWwuKiogUmVzdWx0cyBmb3IgdGhlIGZpbmFsIG1vZGVsIGFyZSBzaG93biBpbiBUYWJsZSAxLiBUaGUgaW50ZXJjZXB0IHdhcyAkXGdhbW1hX3swMH0kID0gMy4wNyAoKlNFKiA9IDAuMDA4LCAqdCooMTAsMDUwKSA9IDM4NC4xNiwgKnAqIDwgLjAwMSwgOTUlIENJIFszLjA1LCAzLjA5XSk6IGEgcmVzcG9uZGVudCB3aXRoIGF2ZXJhZ2UgbGlmZSBzYXRpc2ZhY3Rpb24gaW4gYSBob3VzZWhvbGQgd2l0aCBhdmVyYWdlIG5laWdoYm9yaG9vZCBzYWZldHkgaXMgZXhwZWN0ZWQgdG8gcmF0ZSB0aGVpciBoZWFsdGggYXMgYWxtb3N0IGV4YWN0bHkgImdvb2QuIg0KDQpDb25zaXN0ZW50IHdpdGggKipIeXBvdGhlc2lzIDEqKiwgbGlmZSBzYXRpc2ZhY3Rpb24gcG9zaXRpdmVseSBwcmVkaWN0ZWQgc2VsZi1yYXRlZCBoZWFsdGgsICRcZ2FtbWFfezEwfSQgPSAwLjM3MSAoKlNFKiA9IDAuMDEwLCAqdCooMTQsNDcwKSA9IDM4LjY4LCAqcCogPCAuMDAxLCA5NSUgQ0kgWzAuMzUyLCAwLjM5MF0pLiBIb2xkaW5nIG5laWdoYm9yaG9vZCBzYWZldHkgY29uc3RhbnQsIGVhY2ggb25lLWNhdGVnb3J5IGluY3JlYXNlIGluIGxpZmUgc2F0aXNmYWN0aW9uIHdhcyBhc3NvY2lhdGVkIHdpdGggYSAwLjM3LXBvaW50IGluY3JlYXNlIGluIHNlbGYtcmF0ZWQgaGVhbHRoLiBBY3Jvc3MgdGhlIGZ1bGwgcmFuZ2Ugb2YgdGhlIHdpbnNvcml6ZWQgc2NhbGUgKGZyb20gIm5vdCB2ZXJ5IHNhdGlzZmllZCIgdG8gImNvbXBsZXRlbHkgc2F0aXNmaWVkIiksIHRoaXMgYW1vdW50cyB0byBhbiBleHBlY3RlZCBkaWZmZXJlbmNlIG9mIGFib3V0IDEuMTEgcG9pbnRzIOKAlCBtb3JlIHRoYW4gb25lIGZ1bGwgaGVhbHRoIGNhdGVnb3J5LiBUaGlzIGVmZmVjdCB3YXMgYWJvdXQgMTIlIHNtYWxsZXIgdGhhbiBpbiB0aGUgbW9kZWwgd2l0aG91dCBuZWlnaGJvcmhvb2Qgc2FmZXR5ICgwLjQyMSksIGluZGljYXRpbmcgdGhhdCByZXNwb25kZW50cyBpbiBzYWZlci1wZXJjZWl2ZWQgbmVpZ2hib3Job29kcyBhbHNvIHRlbmQgdG8gYmUgbW9yZSBzYXRpc2ZpZWQsIHNvIHBhcnQgb2YgdGhlIGVhcmxpZXIgYXNzb2NpYXRpb24gcmVmbGVjdGVkIG5laWdoYm9yaG9vZCBkaWZmZXJlbmNlcy4NCg0KQ29uc2lzdGVudCB3aXRoICoqSHlwb3RoZXNpcyAyKiosIG5laWdoYm9yaG9vZCBzYWZldHkgcG9zaXRpdmVseSBwcmVkaWN0ZWQgc2VsZi1yYXRlZCBoZWFsdGgsICRcZ2FtbWFfezAxfSQgPSAwLjIyMiAoKlNFKiA9IDAuMDA4LCAqdCooMTAsNjEwKSA9IDI5LjI4LCAqcCogPCAuMDAxLCA5NSUgQ0kgWzAuMjA3LCAwLjIzN10pLiBIb2xkaW5nIGxpZmUgc2F0aXNmYWN0aW9uIGNvbnN0YW50LCBlYWNoIG9uZS1jYXRlZ29yeSBpbmNyZWFzZSBpbiBhIGhvdXNlaG9sZCdzIHBlcmNlaXZlZCBuZWlnaGJvcmhvb2Qgc2FmZXR5IHdhcyBhc3NvY2lhdGVkIHdpdGggYSAwLjIyLXBvaW50IGluY3JlYXNlIGluIHRoZSBleHBlY3RlZCBzZWxmLXJhdGVkIGhlYWx0aCBvZiBpdHMgcmVzaWRlbnRzLiBBY3Jvc3MgdGhlIGZ1bGwgcmFuZ2Ugb2YgdGhlIHNjYWxlIChmcm9tICJwb29yIiB0byAiZXhjZWxsZW50IiksIHRoaXMgYW1vdW50cyB0byBhbiBleHBlY3RlZCBkaWZmZXJlbmNlIG9mIGFib3V0IDAuODkgcG9pbnRzLCBuZWFybHkgb25lIGZ1bGwgaGVhbHRoIGNhdGVnb3J5Lg0KDQpBZGRpbmcgbmVpZ2hib3Job29kIHNhZmV0eSBzaWduaWZpY2FudGx5IGltcHJvdmVkIGZpdCBvdmVyIHRoZSBsaWZlLXNhdGlzZmFjdGlvbi1vbmx5IG1vZGVsLCAkXGNoaV4yJCgxKSA9IDgyNS44LCAqcCogPCAuMDAxLiBJdCByZWR1Y2VkIHRoZSBiZXR3ZWVuLWhvdXNlaG9sZCB2YXJpYW5jZSBieSAyNS43JSAoZnJvbSAwLjIwMiB0byAwLjE1MCksIHdoaWxlIHRoZSB3aXRoaW4taG91c2Vob2xkIHZhcmlhbmNlIHdhcyBlc3NlbnRpYWxseSB1bmNoYW5nZWQgKDAuNzE0IHRvIDAuNzExLCBhIDAuMyUgcmVkdWN0aW9uKSwgYXMgZXhwZWN0ZWQgZm9yIGEgdmFyaWFibGUgdGhhdCBpcyB0aGUgc2FtZSBmb3IgZXZlcnlvbmUgaW4gYSBob3VzZWhvbGQuIENvbXBhcmVkIHdpdGggdGhlIHVuY29uZGl0aW9uYWwgbW9kZWwsIHRoZSB0d28gcHJlZGljdG9ycyB0b2dldGhlciBleHBsYWluZWQgNDcuOSUgb2YgdGhlIGJldHdlZW4taG91c2Vob2xkIHZhcmlhbmNlIGFuZCA1LjUlIG9mIHRoZSB3aXRoaW4taG91c2Vob2xkIHZhcmlhbmNlLiBUaGUgcmVzaWR1YWwgSUNDIHdhcyAuMTcsIG1lYW5pbmcgYWJvdXQgMTclIG9mIHRoZSByZW1haW5pbmcgdW5leHBsYWluZWQgdmFyaWFuY2UgbGllcyBiZXR3ZWVuIGhvdXNlaG9sZHMuIFNjYWxlZCByZXNpZHVhbHMgd2VyZSByb3VnaGx5IHN5bW1ldHJpYyAo4oiSMi44MCB0byAyLjk0KSwgd2l0aCBub25lIGJleW9uZCDCsTMuDQoNCioqVGFibGUgMS4qKiAqTXVsdGlsZXZlbCBtb2RlbHMgcHJlZGljdGluZyBzZWxmLXJhdGVkIGhlYWx0aCAoTiA9IDE0LDU0MSByZXNwb25kZW50cyBpbiAxMSwwMzEgaG91c2Vob2xkcykqDQoNCnwgfCBNb2RlbCAwOiBVbmNvbmRpdGlvbmFsIHwgTW9kZWwgMTogKyBMaWZlIHNhdGlzZmFjdGlvbiB8IE1vZGVsIDM6ICsgTmVpZ2hib3Job29kIHNhZmV0eSB8DQp8LS0tfC0tLXwtLS18LS0tfA0KfCAqKkZpeGVkIGVmZmVjdHMqKiB8ICpFc3RpbWF0ZSAoU0UpKiB8ICpFc3RpbWF0ZSAoU0UpKiB8ICpFc3RpbWF0ZSAoU0UpKiB8DQp8IEludGVyY2VwdCAoJFxnYW1tYV97MDB9JCkgfCAzLjA2OSAoMC4wMDkpXCpcKlwqIHwgMy4wNzcgKDAuMDA4KVwqXCpcKiB8IDMuMDcwICgwLjAwOClcKlwqXCogfA0KfCBMaWZlIHNhdGlzZmFjdGlvbiAoJFxnYW1tYV97MTB9JCkgfCDigJQgfCAwLjQyMSAoMC4wMTApXCpcKlwqIHwgMC4zNzEgKDAuMDEwKVwqXCpcKiB8DQp8IE5laWdoYm9yaG9vZCBzYWZldHkgKCRcZ2FtbWFfezAxfSQpIHwg4oCUIHwg4oCUIHwgMC4yMjIgKDAuMDA4KVwqXCpcKiB8DQp8ICoqUmFuZG9tIGVmZmVjdHMqKiB8IHwgfCB8DQp8IEJldHdlZW4taG91c2Vob2xkIHZhcmlhbmNlICgkXHRhdV97MDB9JCkgfCAwLjI4OCB8IDAuMjAyIHwgMC4xNTAgfA0KfCBXaXRoaW4taG91c2Vob2xkIHZhcmlhbmNlICgkXHNpZ21hXjIkKSB8IDAuNzUyIHwgMC43MTQgfCAwLjcxMSB8DQp8IElDQyB8IC4yOCB8IC4yMiB8IC4xNyB8DQoNCg0KKk5vdGUuKiBCb3RoIHByZWRpY3RvcnMgYXJlIGdyYW5kLW1lYW4gY2VudGVyZWQuIEFsbCB2YXJpYWJsZXMgYXJlIGNvZGVkIHNvIHRoYXQgaGlnaGVyIHZhbHVlcyBpbmRpY2F0ZSBiZXR0ZXIgaGVhbHRoLCBncmVhdGVyIGxpZmUgc2F0aXNmYWN0aW9uLCBhbmQgYSBzYWZlciBuZWlnaGJvcmhvb2QuIFRoZSByYW5kb20gc2xvcGUgbW9kZWwgKE1vZGVsIDIpIGlzIG5vdCBzaG93biBiZWNhdXNlIHRoZSByYW5kb20gc2xvcGUgd2FzIGRyb3BwZWQuIFwqXCpcKiAqcCogPCAuMDAxLg0KDQoqKlN1bW1hcnkgYW5kIGxpbWl0YXRpb25zLioqIEJvdGggaHlwb3RoZXNlcyB3ZXJlIHN1cHBvcnRlZC4gT2xkZXIgYWR1bHRzIHdobyB3ZXJlIG1vcmUgc2F0aXNmaWVkIHdpdGggdGhlaXIgbGl2ZXMgcmF0ZWQgdGhlaXIgaGVhbHRoIG1vcmUgcG9zaXRpdmVseSwgYW5kIGhvdXNlaG9sZHMgaW4gbmVpZ2hib3Job29kcyBwZXJjZWl2ZWQgYXMgc2FmZXIgaGFkIGJldHRlciBhdmVyYWdlIHNlbGYtcmF0ZWQgaGVhbHRoLCB3aXRoIGVhY2ggYXNzb2NpYXRpb24gaG9sZGluZyB3aGVuIHRoZSBvdGhlciB3YXMgY29udHJvbGxlZC4gU2V2ZXJhbCBsaW1pdGF0aW9ucyBzaG91bGQgYmUgbm90ZWQuIEZpcnN0LCB0aGUgZGF0YSBhcmUgY3Jvc3Mtc2VjdGlvbmFsLCBzbyB0aGVzZSBhcmUgYXNzb2NpYXRpb25zLCBub3QgY2F1c2FsIGVmZmVjdHM7IGZvciBleGFtcGxlLCBwb29yZXIgaGVhbHRoIG1heSBsb3dlciBsaWZlIHNhdGlzZmFjdGlvbiByYXRoZXIgdGhhbiB0aGUgcmV2ZXJzZS4gU2Vjb25kLCBhbGwgdGhyZWUgbWVhc3VyZXMgYXJlIHNpbmdsZS1pdGVtIHNlbGYtcmVwb3J0cywgYW5kIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIGxpZmUgc2F0aXNmYWN0aW9uIGFuZCBzZWxmLXJhdGVkIGhlYWx0aCBtYXkgcGFydGx5IHJlZmxlY3QgYSBnZW5lcmFsIHRlbmRlbmN5IHRvIHJhdGUgdGhpbmdzIHBvc2l0aXZlbHkgb3IgbmVnYXRpdmVseS4gVGhpcmQsIG5laWdoYm9yaG9vZCBzYWZldHkgd2FzIHJlcG9ydGVkIGJ5IG9uZSBob3VzZWhvbGQgbWVtYmVyIGFuZCBhcHBsaWVkIHRvIGFsbCBtZW1iZXJzOyBmb3IgdGhhdCByZXNwb25kZW50LCBpdCBpcyBhbHNvIGEgc2VsZi1yZXBvcnQgZnJvbSB0aGUgc2FtZSBwZXJzb24gd2hvIHJhdGVkIHRoZWlyIG93biBoZWFsdGguIEZvdXJ0aCwgaG91c2Vob2xkcyBhcmUgc21hbGwgKGFib3V0IDEuMzIgcmVzcG9uZGVudHMgb24gYXZlcmFnZSksIHdoaWNoIHByZXZlbnRlZCB0ZXN0aW5nIHdoZXRoZXIgdGhlIGxpZmUgc2F0aXNmYWN0aW9uIGVmZmVjdCBkaWZmZXJzIGFjcm9zcyBob3VzZWhvbGRzLiBGaW5hbGx5LCB0aGUgYW5hbHlzaXMgZGlkIG5vdCBhcHBseSB0aGUgSFJTIHN1cnZleSB3ZWlnaHRzLCBzbyB0aGUgZXN0aW1hdGVzIGRlc2NyaWJlIHRoaXMgc2FtcGxlIHJhdGhlciB0aGFuIHRoZSBVLlMuIHBvcHVsYXRpb24gb2Ygb2xkZXIgYWR1bHRzLg0KDQpbR3JhZGVkIG9uIGEgc2NhbGUgb2YgMS0xMDogMTBwdDogVEEgY291bGQgcmVwbGljYXRlIHRoZSBmaW5kaW5ncyBiYXNlZCBvbiB0aGUgd3JpdGUtdXAsIGNsZWFyIGRlc2NyaXB0aW9uLCBhY2N1cmF0ZS4gNXB0OiBQYXJ0cyBtaXNzaW5nLCBpZiB0aGlzIHdlcmUgYSBwYXBlciB0aGVyZSBtaWdodCBiZSBtaW5vciByZXZpc2lvbnMgcmVxdWVzdGVkIHRvIHVuZGVyc3RhbmQgdGhlIGFuYWx5c2lzLiAwcHQ6IE1hbnkgZXJyb3JzL3ZlcnkgdW5jbGVhci9pbmNvcnJlY3QvbWlzc2luZy5de3N0eWxlPSJjb2xvcjogcmVkOyJ9DQo=