Here the initial findings with the difference-in-differences (DiD) approach to the research question are presented and analyzed. Below, the setup chunk to be run for all the R chunks in the notebook. It loads libraries needed in the other R code chunks below. The margins package that was used to produce these results is a Github-downloaded version by @tzoltak (https://github.com/leeper/margins/issues/124).

Update from 2022: Hello, it is I from the future. I realized that I never clarified that although I repeatedly refer to a difference-in-differences design, it is impossible to verify a parallel trends assumption because this isn’t panel data, it’s simply a pooled cross-section across time. Please, do not think that by simply interacting period and treatment you’re using a DiD estimator, lol. Kindly ignore all the 172 times that I mentioned to a DiD design or estimator in this RPub. Thanks!

Note that the dataframe that will be used is the df46 dataframe as created in the other scripts in the project. It is renamed to data here so that the commands involving it are shorter.

Empirical Strategy Specification

In order to be able to explain the jump in corruption tolerance as seen by the % of people who justify corruption, a DiD design is done. The interaction of key explanatory variables (which are thought to have changed between the two periods) with the 2016 year dummy is the DiD. A general model could be specified as follows:

\[P(ctol = 1 | \mathbb{X}) = G \left \{ \beta_0 + \delta_0 y_{16} + \sum_{j=1}^k \left[ \beta_j(\text{other factors}) \right] + \sum_{i=1}^m \left[ \delta_i (y_{16} \cdot \text{key covariates})\right] \right \} \] where \(ctol\) is a dummy variable taking on values depending on the response to the LAPOP’s AB EXC18 question: “Do you think given the way things are, sometimes paying a bribe is justified?”. \(ctol=1\) is 1 when the response to EXC18 is “Yes”, “0” if the answer is “No” and the NA values reported by the AB’s databases are also taken as missing values for this analysis.

\(y_{16}\) is the 2016 year dummy, other factors are controls included in the models and the DiD estimates (\(\hat{\lambda_i}\)) are those that result from interacting the 2016 dummy with key explanatory variables that are thought to influence the jump in corruption tolerance.

Declaring the survey design

The LAPOP’s America’s Barometer is a complex-design survey with clusters and strata. Due to this, the survey design must be declared in order to produce the adequate adjustments in the data analysis, as follows:

# For all years
ab_des_ec<-svydesign(ids=~upm, 
                         strata=~estratopri, 
                         weights=~weight1500, 
                         nest=TRUE,
                         na.action = 'na.exclude',
                         data=df)

# For years 2014-2016
ab_des_ec1416<-svydesign(ids=~upm, 
                         strata=~estratopri, 
                         weights=~weight1500, 
                         nest=TRUE,
                         na.action = 'na.exclude',
                         data=df46)
# Only for 2014

ab_des_ec14<-svydesign(ids = ~ upm, 
                      strata = ~ estratopri, 
                      weights = ~ wt, 
                      nest = TRUE,
                      na.action = 'na.exclude',
                      data = df_2014)
# Only for 2016

ab_des_ec16<-svydesign(ids = ~ upm, 
                      strata = ~ estratopri, 
                      weights = ~ wt, 
                      nest = TRUE,
                      na.action = 'na.exclude',
                      data = df_2016)

Adjustments done

By far the most important and frequent adjustments that will be done with the survey design will be those regarding the calculations in regression models. So far, after using the adjustments in regression thru svyglm(), only the standard errors and the intercept are changed, as follows from the following example model.

# First an unadjusted logit model
log_age<-glm(ctol ~ year + age, 
             data = df46,
             family = binomial(link = 'logit'))
# Now the adjusted logit model
log_age_ad<-svyglm(ctol ~ year + age, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'logit'))
# Stargazer
sg_test<-stargazer(list(log_age, log_age_ad),
                   type = 'html',
                   align = T)

As it can be seen above, there is no particular change to the magnitudes of the coefficients except the intercept. This might be because the samples in both 2014 and 2016 are self-weighted. The only changes are done to account the unequal selection probability of each observation (i.e. the violation of the random sampling assumption). This seems to affect standard errors, not the coefficients.

Additionally, other adjustments to descriptive statistics are usually necessary when presenting graphs, specially. These are done using the design variables in the database and commands with the svy prefix.

How models are presented

Throughout this study, besides from always taking design effects into account, I will present all models with their corresponding average partial effects, along with their estimated \(\hat{\beta_j}\) coefficients. Naturally, tables with marginal effects only show figures for the independent variables, not for coefficients or complex functional forms.

# Compute APEs through margins
me_logage<-margins(log_age)
me_logagead<-margins(log_age_ad)

# Compute the survey-weighted logit PCPs

pcp_log_age<-hitmiss(log_age_ad)
pcp_log_age<-round(pcp_log_age, 2)
names(pcp_log_age)<-c('Total', 'y=0', 'y=1') # Give vector names to better use in tables. 

# Build a list of the marginal effects to later use with modelsummary

list_me1<-list(me_logage, me_logagead)

Below, I exemplify a table of coefficients to be shown in the paper. These tables are key for showing the effects of complex functional forms, which are otherwise not seen in APE tables. Also, the overall percent correctly predicted (PCP) will be shown, along with the PCP for each of the outcomes in the dependent variable.


stargazer(list(log_age, log_age_ad),
          type = 'html',
          model.names = F,
          add.lines = list(c('Model Type', 'LPM(unweighted)', 'Logit(survey-weighted)'), 
                           c('PCP (Total)', '', pcp_log_age[1]),
                           c('PCP(y=1)', '', pcp_log_age[2]),
                           c('PCP (y=0)', '', pcp_log_age[3])),
          keep.stat = 'n')

In occasions where it is necessary, I present an additional table with APEs. Sometimes I’ll present APEs without their estimated coefficients before. In those cases I’ll put the required model stats below, like the previous table.

modelsummary(list_me1, output = 'html', stars = c('*' = .1, '**' =0.05, '***'= 0.01))

Simple significant DiD models

These are simple, one variable DiD logit models which prove significance. They give insight into what characteristics of public opinion changed during the 2014-2016 period and which are statistically significant changes affecting corruption tolerance in the period.

# Unemployment DiD

log_unemdid<-svyglm(ctol ~ year*unem_4a, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'logit') # Logit
                   )

prob_unemdid<-svyglm(ctol ~ year*unem_4a, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'probit') # Probit
                   )

# Political Score (Higher scores means more identified with right wing)

log_polsdid<-svyglm(ctol ~ year*polscore, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'logit') # Logit
                   )

prob_polsdid<-svyglm(ctol ~ year*polscore, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'probit') # Probit
                   )

# Confidence in the president 

log_pconfdid<-svyglm(ctol ~ year*pres_conf, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'logit') # Logit
                   )

prob_pconfdid<-svyglm(ctol ~ year*pres_conf, 
                   design = ab_des_ec1416,
                   family = binomial(link = 'probit') # Logit
                   )

We would expect that if we get a significant DiD estimate these are key explanatory variables which changed for 2016 with respect to 2014 and are important drivers in how people justify acts of corruption. Below, the models are shown, for three different variables.

A significant DiD may not mean that it was a determinant factor which increased overall corruption tolerance in Ecuador. Must look at the signs first.

I now calculate PCPS and marginal effects.


# Estimate marginal effects for both probit and logit versions of all models

me_unemdid_log<-margins(log_unemdid)

me_unemdid_prob<-margins(prob_unemdid)

me_polsdid_log<-margins(log_polsdid)

me_polsdid_prob<-margins(prob_polsdid)

me_pconfdid_log<-margins(log_pconfdid)

me_pconfdid_prob<-margins(prob_pconfdid)

# Also store the logit coefficients and APEs in a list, to present further.

did_base_log<-list(log_unemdid,
                   log_polsdid,
                   log_pconfdid)

did_base_apes<-list(me_unemdid_log,
                    me_polsdid_log,
                    me_pconfdid_log)

# PCPs

pcp_ulog<-hitmiss(log_unemdid)
pcp_polslog<-hitmiss(log_polsdid)
pcp_pconflog<-hitmiss(log_pconfdid)

I present the coefficients of logit models below, along with their corresponding PCPs:

stargazer(list(log_unemdid,log_polsdid, log_pconfdid),
          type = 'html',
          align = T, 
          title = 'Base Difference in Difference Logit Models',
          keep.stat = 'n',
          omit = c('Constant'),
          model.names = F,
          digits = 2,
          add.lines = list(c('PCP', round(pcp_ulog[1],2), round(pcp_polslog[1],2), round(pcp_pconflog[1],2)),
                           c('PCP(y=0)',round(pcp_ulog[2],2), round(pcp_polslog[2],2), round(pcp_pconflog[2],2)),
                           c('PCP(y=1)',round(pcp_ulog[3],2), round(pcp_polslog[3],2), round(pcp_pconflog[3],2))))

Now, I present APEs for the logit models.


modelsummary(did_base_apes, 
             output = 'html', 
             stars = c('*' = .1, '**' =0.05, '***'= 0.01))

A note on coefficients and APEs

Its important to note than when more complex functional forms enter the regression equation, average partial effects are only calculated for the “principal” variables, meaning that no marginal effects are calculated for the DiD estimates. For example, the effect of the DiD “enters” the year APE. Consider an LPM model with unemployment:

\[P(ctol = 1 | \mathbb{X}) = \beta_0 + \delta_0 y_{16} + \beta_1 (\mu) + \delta_1 \left( y_{16} \cdot \mu \right) + u\] The partial effect of year in \(ctol\) is

\[\dfrac{\partial ctol}{\partial y_{16}} = \delta_0 + \delta_1 \mu \]

And the partial effect of unemployment in \(ctol\) is

\[\dfrac{\partial ctol }{ \partial \mu} = \beta_1 + \delta_1 y_{16}\] Thus, when considering the APEs for this model, what is actually being computed is the average of the results of these two equations for all people in the sample. There won’t be an APE for an interaction term.

In order to test for “differences across groups”, we might want to focus on the interaction term and it’s significance. If \(\delta_1>0\) in the sample, it means that there is a statistically significant difference on how the unemployed tolerate corruption between the years. We might want to know the effect as a whole, i.e. the “complete” effect of being unemployed on 2016 for corruption tolerance. This means plugging in \(y_{16}=1\) in the equation for the partial effect of unemployment \(\mu\) in corruption tolerance. This would equal looking at the quantitty \(\hat{\beta_1} + \hat{\delta_1}y_{16}\). In order to test significance for it, one can reparameterize the model or simply run a regression that only uses observations in 2016.

Unemployment and Labor Market

The significance in both the unemployment term and its interaction with the 2016 dummy say that, in any year, an unemployed individual is more likely to justify corruption. However, in 2016, this individual, while still more likely to acccept corruption than someone who is not unemployed (includes those in and out of the labor force), is less so compared to 2014.

The same seems to hold for the model that includes the employment and not in workforce dummies.

Political score

Only the DiD term is significant, meaning that a person who identifies more with the right wing is not significantly more tolerant of corruption in 2014. However, in 2016 the more to the right a person signals that they are, the more they justify corruption. This warrants more investigation as it suggests an interesting idea.

Confidence in the president

This question (B21A in the survey), asks: ¿Hasta qué punto tiene confianza usted en el presidente?, as usual, in a 1-7 scale. The directions of the effects estimated are quite interesting.

In 2014, someone that had more confidence in the president was significantly less tolerant of corruption. The DiD term is positive but smaller than the confidence term. This means that, in 2016, a person that confided in the president was still less likely to tolerate corruption relative to someone that confided less. However, they did so in a smaller way compared to 2014.

This may explain the jump in corruption tolerance, as, according to the graphs below, there is a sharp decline in people who confide in the president. Note that the way that the presidential confidence variable is dichotomized is similar to the dichotomization of similar 1-7 scaled variables in America’s Barometer’s reports (scores in 5-7 are coded as “Yes” or with value 1).

df$pres_conf_dic<-ifelse(df$pres_conf >= 5, 'Yes', 'No')

The table below shows the time series of the confidence in the president for Ecuador beginning 2006.

pres_conf<-svyby(~ pres_conf_dic, ~ year, design = ab_des_ec, svymean, na.rm = T) %>% as.data.frame()
pres_conf<-dplyr::select(pres_conf, pres_conf_dicYes, se.pres_conf_dicYes) %>% 
           rename('%Yes'=pres_conf_dicYes, 'SE'= se.pres_conf_dicYes)
pres_conf<-pres_conf[3:8,]
pres_conf

Below, the same is done to the political score variable, dividing it in left and right.

df$pol_wing2<-ifelse(df$polscore < 6, 'Left', 'Right')
polwing2<-svyby(~ pol_wing2, ~ year, design = ab_des_ec, svymean, na.rm = T) %>% as.data.frame()
polwing2

An increase in unemployment is indeed seen, however, the new unemployed justify corruption in a less extent to the unemployed in 2014. The jump in corruption tolerance could be explained by a ten point rise in the percentage of “right-wingers”, who are more likely to justify corruption. Also, since the confidence in the president decreased and for 2016 the negative effect of confidence in corruption tolerance is smaller, we can also justify the jump in corruption tolerance.

It is not exactly clear whether it is the actual politicial orientation which causes, or is relate to, justification to corrupt attitudes. We continue investigating this further.

Complex DiD Model

I now estimate a more complex model, incorporating all three previously significant DiDs and adding other control variables.

# Estimate the model through three methods

# 1. LPM

lpm_incd<-svyglm(ctol~ year*(unem2_4a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
             corrper, 
             design = ab_des_ec1416)
# 2. Probit

prob_incd<-svyglm(ctol~ year*(unem2_4a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
               corrper, 
               design = ab_des_ec1416,
               family = binomial(link = 'probit') )
# 3. Logit 

log_incd<-svyglm(ctol~ year*(unem2_4a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
              corrper, 
              design = ab_des_ec1416,
              family = binomial(link = 'logit'))

I calculate the corresponding average partial effects below.


me_lpmc<-margins(lpm_incd)
me_probc<-margins(prob_incd)
me_logc<-margins(log_incd)

# Also compute PCPS

pcp_probc<-hitmiss(prob_incd)
pcp_probc<-round(pcp_probc, 4)
pcp_logc<-hitmiss(log_incd)
pcp_logc<-round(pcp_logc, 4)

# Store both models in a list

complex_did_all<-list(log_incd,
                      prob_incd)

# Store APEs in a list

me_complex_didall<-list(me_lpmc,
                        me_probc,
                        me_logc)

Below the model is presented through survey-weighted least squares, logit and probit procedures. The PCPs for each outcome and the overall one are also presented.

stargazer(list(lpm_incd, prob_incd, log_incd),
          model.names  = F,
          add.lines = list(c('Model Type', 'LPM', 'Probit (W)', 'Logit(W)'),
                           c('PCP', '', pcp_probc[1], pcp_logc[1]),
                           c('PCP (y=1)', '', pcp_probc[2], pcp_logc[2]),
                           c('PCP (y=0)', '', pcp_probc[3], pcp_logc[3])),
          type = 'html')

Now, I present APEs for these models.

modelsummary(me_complex_didall, 
             output = 'markdown', 
             stars = c('*' = .1, '**' =0.05, '***'= 0.01))

The most important finding is that the year dummy (2016) is lost, meaning that, once accounting for all the factors included in the model, observations from 2016 are not more likely to justify corruption. Age, once again, is a negative factor on corruption tolerance: a person which is older will be less likely to justify corruption.

Interest in politics is indeed significant. The sign on it means that a person with more interest in politics is supposedly less tolerant of corruption, which is not what was previously found out.

Gender, education, urban/rural settings, external political efficiency, perceptions of corruption (which is made comparable between 2014 and 2016) prove to not be significant for justification of bribes.

Overall, unemployment seems to have the expected effect: a person which is unemployed is more likely to justify corruption than someone not unemployed (including those which are not in the labor force). Its overall effect, including its DiD estimate show that while the unemployed is always more tolerant of corruption, the unemployed in 2016 seemed to be less so compared to 2014.

The political score which ranks individuals left to right shows that overall, the people who identified more with the right wing were more tolerant of corruption, but only so in 2016, not in 2014.

Finally and perhaps most importantly, the people who trusted the president in both years were significantly less likely to justify corruption. However, in 2016 they were somewhat less rejecting of corruption tolerance compared to 2014. The jump in corruption tolerance could be partially explained by this fact, considering that in 2016 the drop in the confidence to the president was large.

Sadly, the PCP for the outcome of interest is quite low. I hope to improve this as I add more significant variables to the model.

Testing out new variables

Below, we try adding more variables to the model and also try out simpler ones. For simplicity, I only take into account the logit models below.

Religion

Hurtado suggests being christian might promote industriousness, which in a way may help reject corruption. I add religious variables as categorized below:

df$rlg<-ifelse(df$q3c == 1, 'Catholic',
               ifelse(df$q3c == 2 | df$q3c == 5, 'Christian',
                      ifelse(df$q3c == 3 | df$q3c == 4 | df$q3c == 77, 'Other',
                      ifelse(df$q3c == 6 | df$q3c == 12, 'JW/MOR', 'Atheist'))))

Where JW/MOR means those categorized as Jehova’s Witnesses and Mormons.

Preliminary results for this regression are presented below:

svyglm(ctol~ year*(unem2_4a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
             corrper + rlg, 
             design = ab_des_ec1416,
             family = quasibinomial(link = 'logit')) %>% summary()

The political efficacy variable gains some significance here, suggesting a downward bias. However, no religious group seems so far to have a significant difference from atheists. For now Hurtado’s hypothesis does not seem to expand to corruption tolerance. Below, a simple model using only the year dummy and the religion groups:

svyglm(ctol~ year + rlg, 
       design = ab_des_ec1416,
       family = quasibinomial(link = 'logit')) %>% summary()

Also not significant, so not even a spurious correlation is found. It might be that the religious groups are not important for corruption tolerance.

The importance of religion in the individual’s life is now considered in the complex model.

Economic variables

The databases available for free do not include the wealth quintiles analysis, which forces me to only consider economic situation as they answer it:

idio2 Question: Do you think that your economic situation is better than, the same as, or worse than it was 12 months ago?

As expected, this question shows how must of the people in the 2016 sample report that their economic situation is worse. The same is seen from a question asking specifically about income.

Adding this to the model, we get the following:

svyglm(ctol~ year*(unem2_4a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
             corrper + econ_sit, 
             design = ab_des_ec1416,
             family = quasibinomial(link = 'logit')) %>% summary()

Exposure to corruption

LAPOPs AB often includes corruption “victimization” in its empirical analyses. My own version of this variable is exposure to corruption, which will equal 1 if the individual reports having been offered or having paid a bribe in any of the several questions regarding corruption on the dataset. At this moment, only 2012 thru 2019 have more or less reliable figures for this number.

Including this variable in the models yields the following:

correxp_complex<-svyglm(ctol~ year*(unem2_4a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 +                                pint_dic + corrper + corr_exp, 
                        design = ab_des_ec1416,
                        family = quasibinomial(link = 'logit'))
summary(correxp_complex)

It would seem that this variable is quite important, so it must stay in models. Average partial effects below.

me_correxpc<-margins(correxp_complex)
modelsummary(me_correxpc, 
             output = 'html', 
             stars= c('*' = .1, '**' =0.05, '***'= 0.01))

Politization

Politization, as defined by the LAPOP 2019 report, implies that the people inside a country start to identify more with political wings. This means a lower percentage of non responses to the question that asks people to identify with a score in a political range.

There is an important change in politization between 2014 and 2016, as suggested by its time series. Below I include this dummy in the model previously estimated. In order to get the estimate, however, I must drop the political score independent variable from the model, and interact year with this dummy instead.

svyglm(ctol~ year*(unem2_4a + pres_conf + plscr_na) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
             corrper + corr_exp, 
             design = ab_des_ec1416,
             family = quasibinomial(link = 'logit')) %>% summary()

Not really significant, we lose more by deleting the political score variable than what we gain from adding the politization variable.

Political groups rather than scores

I replace the political score variable with political groups as defined in the LAPOP report.

svyglm(ctol~ year*(unem2_4a + pres_conf + pol_group) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
             corrper + corr_exp, 
             design = ab_des_ec1416,
             family = quasibinomial(link = 'logit')) %>% summary()

It is rather weird that the interactions with all political groups and the year are not significant. Try again with a right wing dummy.


svyglm(ctol~ year*(unem2_4a + pres_conf + rwing) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + 
             corrper + corr_exp, 
             design = ab_des_ec1416,
             family = quasibinomial(link = 'logit')) %>% summary()

Still not significant. Why only significant with the actual political score variable. Might there be a problem in assuming it is a continous predictor?

Labor Market Variables

I replace the unemployment dummy to include a factor with 3 groups: Employed, Not Employed and not in the workforce. Not being in the workforce implies that the respondent is either retired, unable to work in some way, a student or working the home.

svyglm(ctol~ year*(work_2a + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper +            corr_exp, 
       design = ab_des_ec1416,
       family = quasibinomial(link = 'logit')) %>% summary()

Results seem to be equal considering people who are not in the workforce. Interesting to know that employed peoples and those not in the workforce have no significant differences in corruption tolerance.

Now I do the same analysis, but adding occupation in either the private or public sector. I restore the unemployment dummy. In this codification the variable will mean 1 if the individual works in the public sector, and 0 if he works in the private sector as employee, a self-employed or an owner/partner. Note that we can no longer have a general labor market DiD.

svyglm(ctol~ year*(privpub + pres_conf + polscore ) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
       corr_exp , 
       design = ab_des_ec1416,
       family = quasibinomial(link = 'logit')) %>% summary()

Seems to have no effect. Now consider doing the same for all four sectors. Doesn’t really matter which one is the base sector.

svyglm(ctol~ year*(ocup_sec + pres_conf + polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
       corr_exp, 
       design = ab_des_ec1416,
       family = quasibinomial(link = 'logit')) %>% summary()

The unpaid part has significant changes, however, it is a very small part of the sample. Considering the following tabulation:


tab_unpaid<-table(df46$year, df46$ocup_sec) %>% prop.table(margin = 1)
tab_unpaid<-tab_unpaid[6:7,] *100
tab_unpaid

Socio-Demographic

Consider the new survey respondents in 2016. This is people who only now are answering the survey, meaning people with 16 and 17. Add a dummy variable and an interaction with year to the regression to compare both groups on both years. If this population think significantly different from the rest, they could be the reason why in 2016 corruption tolerance goes up by so much.

new_age_did<-svyglm(ctol~ year*(unem2_4a + pres_conf + polscore + new) + age + gndr + ed + ur + eff1 + eff2 + 
                    prot3 + pint_dic + corrper + corr_exp, 
                    design = ab_des_ec1416,
                    family = quasibinomial(link = 'logit'))
summary(new_age_did)

Seems interesting, very large magnitudes but seems that seem to cancel each other out, which means that in 2014 under 18 respondents deeply rejected corruption, but in 2016 they started to justify it much more, leaving a net effect of 0 for under 18 respondents for 2016. Compute APEs:


ape_newage_complex<-margins(new_age_did)

modelsummary(ape_newage_complex,
             output = 'html',
             stars = c('*' = .1, '**' =0.05, '***'= 0.01))

Significant negative APE for new respondents… Not quite what would be expected. Needs further analysis. Estimate a DiD on its own for this variable:

new_age_did_s<-svyglm(ctol~ year*new + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                      corr_exp + pres_conf + polscore + unem2_4a, 
                      design = ab_des_ec1416,
                      family = quasibinomial(link = 'logit'))
summary(new_age_did_s)

Not too different from what we’ve seen before. APEs:


me_newdid_s<-margins(new_age_did_s)

modelsummary(me_newdid_s,
             output = 'html',
             stars = c('*' = .1, '**' =0.05, '***'= 0.01))

Same thing. Estimate cross-sectional models for this variable and compare the net effects.

# 2014 New Age DiD
new_age_did_14<-svyglm(ctol~ new + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                      corr_exp + pres_conf + polscore + unem2_4a, 
                      design = ab_des_ec14,
                      family = quasibinomial(link = 'logit'))
summary(new_age_did_14)

# 2016 New Age DiD

new_age_did_16<-svyglm(ctol~ new + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                      corr_exp + pres_conf + polscore + unem2_4a, 
                      design = ab_des_ec16,
                      family = quasibinomial(link = 'logit'))
summary(new_age_did_14)

# APEs

age_did_me14<-margins(new_age_did_14)
age_did_me16<-margins(new_age_did_16)

Compare both models, side by side:


stargazer(new_age_did_14, new_age_did_16,
          type = 'html',
          add.lines = c('Year', '2014', '2016'))

Now present APEs:


modelsummary(list(age_did_me14, age_did_me16),
             output = 'markdown',
             stars= c('*' = .1, '**' =0.05, '***'= 0.01))

This might have much to do with the frequency of people under 18 in the samples, much like the unpaid workers. Consider the following tabulation:

tab_new_age<-table(df$year, df$new) %>% prop.table(margin = 1)
tab_new_age<-tab_new_age *100 

In 2016 there is an increase of 4.65 percentage points of the total sample who are underage respondents. Meaning that in 2016 there are more young people overall. This increases even more for 2019.

Now, let’s check how this people respond to the survey.


# Subset dataframe for the underage respondents

df_new<-subset(df, df$new == 1)

# Tabulate and see what are the %'s of corruption tolerance

tab_new_ctol<-table(df_new$year, df_new$ctol) %>% prop.table(margin = 1)
tab_new_ctol

Previously, they all rejected corruption, and now about 30% of them now justify corruption, which is intuitive considering the signs of the interaction of this variable with year. This, however, may not mean a change in underlying public opinion. There is too little data to have a sensible conclusion.

Separation of DiDs

I separate each DiD with the complex model with corruption exposure.


# Logit: 

# Unemployment

unem_did_log_c<-svyglm(ctol~ year*(unem2_4a) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       polscore + pres_conf,
                       design = ab_des_ec1416,
                       family = binomial(link = 'logit'))

# Political Score

pols_did_log_c<-svyglm(ctol~ year*(polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       unem2_4a + pres_conf,
                       design = ab_des_ec1416,
                       family = binomial(link = 'logit'))

# Presidential Confidence

presc_did_log_c<-svyglm(ctol~ year*(pres_conf) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp +
                        unem2_4a + polscore,
                        design = ab_des_ec1416,
                        family = binomial(link = 'logit'))

# Probit: 

# Unemployment

unem_did_prob_c<-svyglm(ctol~ year*(unem2_4a) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       polscore + pres_conf,
                        design = ab_des_ec1416,
                        family = binomial(link = 'probit'))

# Political Score

pols_did_prob_c<-svyglm(ctol~ year*(polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       unem2_4a + pres_conf,
                       design = ab_des_ec1416,
                       family = binomial(link = 'probit'))

# Presidential Confidence

presc_did_prob_c<-svyglm(ctol~ year*(pres_conf) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp +
                        unem2_4a + polscore,
                        design = ab_des_ec1416,
                        family = binomial(link = 'probit'))

# PCPS

pcp_unemcl<-hitmiss(unem_did_log_c)
pcp_polscl<-hitmiss(pols_did_log_c)
pcp_pconfcl<-hitmiss(presc_did_log_c)
pcp_unemcp<-hitmiss(unem_did_prob_c)
pcp_polscp<-hitmiss(pols_did_prob_c)
pcp_pconfcp<-hitmiss(presc_did_prob_c)

Present the coefficients below:

stargazer(list(unem_did_log_c, pols_did_log_c, presc_did_log_c),
          type = 'html')

APEs estimated below:


# Estimate APES

me_unemcs_l<-margins(unem_did_log_c)
me_unemcs_p<-margins(unem_did_prob_c)

me_polscs_l<-margins(pols_did_log_c)
me_polscs_p<-margins(pols_did_prob_c)

me_prescs_l<-margins(presc_did_log_c)
me_prescs_p<-margins(presc_did_prob_c)

# List MEs of logit models, to show them later: 

mes_separate_dids<-list(me_unemcs_l,
                        me_polscs_l, 
                        me_prescs_p)

Presentation of APEs below:

modelsummary(mes_separate_dids,
             output = 'markdown',
             stars= c('*' = .1, '**' =0.05, '***'= 0.01))

Hypothesis testing

Unemployment

I want to test and know about the net effect of unemployment in 2016 to corruption tolerance. For that, I want to first do a joint hypothesis test of the interaction coefficient with unemployment and year, as well as the sole unemployment coefficient. Must perform a Waldt test, which is the only test that works in surveys.

terms_unem<-c('unem2_4a', 'year2016:unem2_4a')

regTermTest(unem_did_log_c, terms_unem, method = 'Wald')

It is thus confirmed that unemployment is important for corruption tolerance. The fact that the interaction term is significant means that there is indeed a difference in slopes across time for unemployed workers.

Now, must check if the total effect for unemployment in 2016 is significant. I will run two different models with the interaction term, one for each year and compare coefficients.


# 2014 
unem_did_log_14<-svyglm(ctol ~ unem2_4a + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       polscore + pres_conf,
                       design = ab_des_ec14,
                       family = binomial(link = 'logit'))
# 2016 
unem_did_log_16<-svyglm(ctol ~ unem2_4a + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       polscore + pres_conf,
                       design = ab_des_ec16,
                       family = binomial(link = 'logit'))

stargazer(unem_did_log_14, unem_did_log_16,
          type = 'text',
          add.lines = list(c('Year', '2014','2016')))

The net effect for unemployment is null, thus in 2016 unemployed people rejected corruption less than those in 2014. Does not successfully explain the jump in corruption tolerance. Present the APEs below:


me_unem2014<-margins(unem_did_log_14)
me_unem2016<-margins(unem_did_log_16)

me_unemcross<-list(me_unem2014,
                   me_unem2016)

modelsummary(me_unemcross,
             output = 'html',
             stars= c('*' = .1, '**' =0.05, '***'= 0.01))

Political Wing Score

I repeat the same analysis, but now for the polscore variable.

terms_polscore<-c('polscore', 'year2016:polscore')

regTermTest(pols_did_log_c, terms_unem, method = 'Wald')

It is possible that political score in a model with solely the political score as our DiD, is not significant at all to corruption justification. However, in the complex model that does include all variables, we may not see the same thing. Test:

regTermTest(log_incd, terms_polscore, method = 'Wald')

The same, however our Wald test is slightly larger in this case. Still could be biased toward zero from omitted variables.

Try to test the net effect comparing the cross-sectional regressions, as seen in the previous code chunk. Interestingly, in 2016 this effect is significant, which does, in a way, explain the corruption tolerance jump. If people that identify as more right-wingers start justifying corruption more, and the amount of people like this starts to increase, the hypothetical jump is explained.

Now try with political groups. The base is the center.


pols_dis_group<-svyglm(ctol~ year*(pol_group) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp                          + unem2_4a + pres_conf, 
                       design = ab_des_ec1416,
                       family = quasibinomial(link = 'logit'))
pols_dis_group %>% summary()

No significance. It is very unstable. Run regressions like these for both years.


pols_dis_group14<-svyglm(ctol ~ pol_group + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                         corr_exp + unem2_4a + pres_conf, 
                         design = ab_des_ec14,
                         family = quasibinomial(link = 'logit'))

pols_dis_group16<-svyglm(ctol ~  pol_group + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                         corr_exp + unem2_4a + pres_conf, 
                         design = ab_des_ec16,
                         family = quasibinomial(link = 'logit'))

stargazer(pols_dis_group14, pols_dis_group16,
          type = 'text',
          add.lines = list(c('Year', '2014','2016')))

There only seems to be some marginal significance for leftists: they justified corruption less in 2016, which could explain the jump since there were less leftists. APES below:


me_polsgroup14<-margins(pols_dis_group14)
me_polsgroup16<-margins(pols_dis_group16)

me_polsgroups<-list(me_polsgroup14,
                    me_polsgroup16)

modelsummary(me_polsgroups,
             output = 'html',
             stars= c('*' = .1, '**' =0.05, '***'= 0.01))

Confidence in the president

Do the same for the pres_conf variable.

terms_pconf<-c('pres_conf', 'year2016:pres_conf')

regTermTest(presc_did_log_c, terms_pconf, method = 'Wald')

The different cross sections show that people who confided in the president only rejected corruption in 2014. Beginning 2016, they stopped acting so zealous. This also justifies corruption tolerance.

New variables with separate DiDs

Approval Rating (President)

I will now consider the job approval ratings of the president across time. First, I’ll test for the correlation between this and confidence in the president and the political score variable


cor(df46$pres_aprov, df46$pres_conf, use = 'complete.obs')
cor(df46$pres_aprov, df46$polscore, use = 'complete.obs')
cor(df46$pres_conf, df46$polscore, use = 'complete.obs')

There is indeed a high correlation, but not perfect with confidence in the president. Interesting to see that political score does not mean approval with the president.

It will probably induce a lot multicollinearity to include both confidence in the president and approval of the president’s job performance. Below, however, we try to do so.


# Logit: 

# Unemployment

unem_did_log_c2<-svyglm(ctol~ year*(unem2_4a) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       polscore + pres_conf + pres_aprov,
                       design = ab_des_ec1416,
                       family = binomial(link = 'logit'))

# Political Score

pols_did_log_c2<-svyglm(ctol~ year*(polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       unem2_4a + pres_conf + pres_aprov,
                       design = ab_des_ec1416,
                       family = binomial(link = 'logit'))

# Presidential Confidence

presc_did_log_c2<-svyglm(ctol~ year*(pres_conf) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp +
                        unem2_4a + polscore + pres_aprov,
                        design = ab_des_ec1416,
                        family = binomial(link = 'logit'))

# Probit: 

# Unemployment

unem_did_prob_c2<-svyglm(ctol~ year*(unem2_4a) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                        polscore + pres_conf + pres_aprov,
                        design = ab_des_ec1416,
                        family = binomial(link = 'probit'))

# Political Score

pols_did_prob_c2<-svyglm(ctol~ year*(polscore) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + corr_exp + 
                       unem2_4a + pres_conf + pres_aprov,
                       design = ab_des_ec1416,
                       family = binomial(link = 'probit'))

# Presidential Confidence

presc_did_prob_c2<-svyglm(ctol~ year*(pres_conf) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                         corr_exp + unem2_4a + polscore + pres_aprov,
                         design = ab_des_ec1416,
                         family = binomial(link = 'probit'))

# Make a list of the logit models

logit_complex2_sepdid<-
  list(unem_did_log_c2,
       pols_did_log_c2,
       presc_did_log_c2)

# PCPS

pcp_unemcl2<-hitmiss(unem_did_log_c2)
pcp_polscl2<-hitmiss(pols_did_log_c2)
pcp_pconfcl2<-hitmiss(presc_did_log_c2)
pcp_unemcp2<-hitmiss(unem_did_prob_c2)
pcp_polscp2<-hitmiss(pols_did_prob_c2)
pcp_pconfcp2<-hitmiss(presc_did_prob_c2)

stargazer(logit_complex2_sepdid,
          type = 'text'
          )

It does nothing to the models. Try an interaction with year, a sole DiD model.


aprov_did_logdid<-svyglm(ctol~ year*(pres_aprov) + age + gndr + ed + ur + eff1 + eff2 + prot3 + pint_dic + corrper + 
                         corr_exp + unem2_4a + pres_conf + polscore,
                         design = ab_des_ec1416,
                         family = binomial(link = 'probit')) 
summary(aprov_did_logdid)

It does work as a DiD on its own, in a similar way that the confidence DiD works. Try joining both, and replacing presidential job approval with


aprov_didb_logdid<-svyglm(ctol~ year*(pres_aprov + pres_conf) + age + gndr + ed + ur + eff1 + eff2 + 
                          prot3 + pint_dic + corrper + corr_exp + unem2_4a  + polscore,
                          design = ab_des_ec1416,
                          family = binomial(link = 'logit')) 


aprov_did_logdid_noconf<-svyglm(ctol~ year*(pres_aprov ) + age + gndr + ed + ur + eff1 + eff2 + 
                                prot3 + pint_dic + corrper + corr_exp + unem2_4a  + polscore,
                                design = ab_des_ec1416,
                                family = binomial(link = 'logit')) 

hitmiss(aprov_didb_logdid)
hitmiss(aprov_did_logdid_noconf)

stargazer(aprov_didb_logdid, aprov_did_logdid_noconf,
          type = 'text')

Compute APES for all of these models, and then compare.


ape_didu_aprov<-margins(unem_did_log_c2)
ape_didp_aprov<-margins(pols_did_log_c2)
ape_didc_aprov<-margins(presc_did_log_c2)
ape_aprov_did<-margins(aprov_did_logdid)
ape_aprov_didb<-margins(aprov_didb_logdid)
ape_aprov_dids<-margins(aprov_did_logdid_noconf)

apes_did_aprov<-
  list(ape_didu_aprov,
       ape_didp_aprov,
       ape_didc_aprov,
       ape_aprov_did,
       ape_aprov_didb,
       ape_aprov_dids)

modelsummary(apes_did_aprov, 
             output = 'markdown',
             stars = c('*' = .1, '**' =0.05, '***'= 0.01))
LS0tDQp0aXRsZTogIlByZWxpbWluYXJ5IExBUE9QJ3MgQUIgU3R1ZHktIEF0dGl0dWRlcyBvbiBDb3JydXB0aW9uIEVjdWFkb3IgMjAxNC0yMDE2Ig0KYXV0aG9yOiAiRGFuaWVsIFPDoW5jaGV6Ig0KZGF0ZTogIjIwMjEvMDgvMTYiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQpzdWJ0aXRsZTogVVNGUSBFY29ub21pY3MgVW5kZXJncmFkdWF0ZSBUaGVzaXMNCi0tLQ0KDQpIZXJlIHRoZSBpbml0aWFsIGZpbmRpbmdzIHdpdGggdGhlIGRpZmZlcmVuY2UtaW4tZGlmZmVyZW5jZXMgKERpRCkgYXBwcm9hY2ggdG8gdGhlIHJlc2VhcmNoIHF1ZXN0aW9uIGFyZSBwcmVzZW50ZWQgYW5kIGFuYWx5emVkLiBCZWxvdywgdGhlIHNldHVwIGNodW5rIHRvIGJlIHJ1biBmb3IgYWxsIHRoZSBSIGNodW5rcyBpbiB0aGUgbm90ZWJvb2suIEl0IGxvYWRzIGxpYnJhcmllcyBuZWVkZWQgaW4gdGhlIG90aGVyIFIgY29kZSBjaHVua3MgYmVsb3cuIFRoZSBgbWFyZ2luc2AgcGFja2FnZSB0aGF0IHdhcyB1c2VkIHRvIHByb2R1Y2UgdGhlc2UgcmVzdWx0cyBpcyBhIEdpdGh1Yi1kb3dubG9hZGVkIHZlcnNpb24gYnkgQHR6b2x0YWsgKDxodHRwczovL2dpdGh1Yi5jb20vbGVlcGVyL21hcmdpbnMvaXNzdWVzLzEyND4pLg0KDQpVcGRhdGUgZnJvbSAyMDIyOiBIZWxsbywgaXQgaXMgSSBmcm9tIHRoZSBmdXR1cmUuIEkgcmVhbGl6ZWQgdGhhdCBJIG5ldmVyIGNsYXJpZmllZCB0aGF0IGFsdGhvdWdoIEkgcmVwZWF0ZWRseSByZWZlciB0byBhIGRpZmZlcmVuY2UtaW4tZGlmZmVyZW5jZXMgZGVzaWduLCBpdCBpcyBpbXBvc3NpYmxlIHRvIHZlcmlmeSBhIHBhcmFsbGVsIHRyZW5kcyBhc3N1bXB0aW9uIGJlY2F1c2UgdGhpcyBpc24ndCBwYW5lbCBkYXRhLCBpdCdzIHNpbXBseSBhIHBvb2xlZCBjcm9zcy1zZWN0aW9uIGFjcm9zcyB0aW1lLiBQbGVhc2UsIGRvIG5vdCB0aGluayB0aGF0IGJ5IHNpbXBseSBpbnRlcmFjdGluZyBwZXJpb2QgYW5kIHRyZWF0bWVudCB5b3UncmUgdXNpbmcgYSBEaUQgZXN0aW1hdG9yLCBsb2wuIEtpbmRseSBpZ25vcmUgYWxsIHRoZSAxNzIgdGltZXMgdGhhdCBJIG1lbnRpb25lZCB0byBhIERpRCBkZXNpZ24gb3IgZXN0aW1hdG9yIGluIHRoaXMgUlB1Yi4gVGhhbmtzIQ0KDQpgYGB7ciBzZXR1cCwgd2FybmluZyA9IEYsIHJlc3VsdHMgPSAnaGlkZSd9DQojIExvYWQgbGlicmFyaWVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyBUaWR5dmVyc2U6IHRpZHlyLCBnZ3Bsb3QsIGV0Yy4NCmxpYnJhcnkoc3VydmV5KSAjIFRvIGNvbnRyb2wgZm9yIHN1cnZleSBkZXNpZ24gZWZmZWN0cw0KbGlicmFyeShzdGFyZ2F6ZXIpICMgRm9yIHJlZ3Jlc3Npb24gdGFibGVzDQpsaWJyYXJ5KGdnZWZmZWN0cykgIyBGb3IgY2FsY3VsYXRpb24gb2YgYXZlcmFnZSBwYXJ0aWFsIGVmZmVjdHMNCmxpYnJhcnkocHNjbCkgIyBGb3IgcGVyY2VudCBjb3JyZWN0bHkgcHJlZGljdGVkDQpsaWJyYXJ5KG1hcmdpbnMpICMgRm9yIGF2ZXJhZ2UgcGFydGlhbCBlZmZlY3RzIChzdXJ2ZXkgZnJpZW5kbHkpDQpsaWJyYXJ5KG1meCkgIyBBUEVzLCBmcmllbmRsaWVyIGZvciBub24tc3VydmV5IG9iamVjdHMNCmxpYnJhcnkocGVyZm9ybWFuY2UpICMgUENQDQpsaWJyYXJ5KGxtdGVzdCkgIyBGb3IgdmFyaW91cyBjb21tYW5kcywgc3BlY2lhbGx5IHJlZ2FyZGluZyBoZXRlcm9za2VkYXN0aWNpdHkuIA0KbGlicmFyeShvcGVueGxzeCkgIyBUbyB3cml0ZSBYTCB3b3JrYm9va3MNCmxpYnJhcnkobWFyZ2luYWxlZmZlY3RzKSAjIEZvciBBTUVzIHdpdGhvdXQgc3VydmV5IHdlaWdodGluZw0KbGlicmFyeShtb2RlbHN1bW1hcnkpICMgRm9yIEFNRSB0YWJsZXMNCmxpYnJhcnkoY2FyKSAjIENvbXBhbmlvbiB0byBhcHBsaWVkIHJlZ3Jlc3Npb24sIGZvciBoeXBvdGhlc2lzIHRlc3RpbmcNCmxpYnJhcnkobG10ZXN0KSAjIEZvciBpbmZlcmVuY2UsIGxpa2VsaWhvb2QgcmF0aW9zLiANCmBgYA0KDQpOb3RlIHRoYXQgdGhlIGRhdGFmcmFtZSB0aGF0IHdpbGwgYmUgdXNlZCBpcyB0aGUgYGRmNDZgIGRhdGFmcmFtZSBhcyBjcmVhdGVkIGluIHRoZSBvdGhlciBzY3JpcHRzIGluIHRoZSBwcm9qZWN0LiBJdCBpcyByZW5hbWVkIHRvIGBkYXRhYCBoZXJlIHNvIHRoYXQgdGhlIGNvbW1hbmRzIGludm9sdmluZyBpdCBhcmUgc2hvcnRlci4NCg0KIyMgRW1waXJpY2FsIFN0cmF0ZWd5IFNwZWNpZmljYXRpb24NCg0KSW4gb3JkZXIgdG8gYmUgYWJsZSB0byBleHBsYWluIHRoZSBqdW1wIGluIGNvcnJ1cHRpb24gdG9sZXJhbmNlIGFzIHNlZW4gYnkgdGhlICUgb2YgcGVvcGxlIHdobyBqdXN0aWZ5IGNvcnJ1cHRpb24sIGEgRGlEIGRlc2lnbiBpcyBkb25lLiBUaGUgaW50ZXJhY3Rpb24gb2Yga2V5IGV4cGxhbmF0b3J5IHZhcmlhYmxlcyAod2hpY2ggYXJlIHRob3VnaHQgdG8gaGF2ZSBjaGFuZ2VkIGJldHdlZW4gdGhlIHR3byBwZXJpb2RzKSB3aXRoIHRoZSAyMDE2IHllYXIgZHVtbXkgaXMgdGhlIERpRC4gQSBnZW5lcmFsIG1vZGVsIGNvdWxkIGJlIHNwZWNpZmllZCBhcyBmb2xsb3dzOg0KDQokJFAoY3RvbCA9IDEgfCBcbWF0aGJie1h9KSA9IEcgXGxlZnQgXHsgXGJldGFfMCArIFxkZWx0YV8wIHlfezE2fSArIFxzdW1fe2o9MX1eayBcbGVmdFsgXGJldGFfaihcdGV4dHtvdGhlciBmYWN0b3JzfSkgXHJpZ2h0XSArIFxzdW1fe2k9MX1ebSBcbGVmdFsgXGRlbHRhX2kgKHlfezE2fSBcY2RvdCBcdGV4dHtrZXkgY292YXJpYXRlc30pXHJpZ2h0XSBccmlnaHQgXH0gJCQgd2hlcmUgJGN0b2wkIGlzIGEgZHVtbXkgdmFyaWFibGUgdGFraW5nIG9uIHZhbHVlcyBkZXBlbmRpbmcgb24gdGhlIHJlc3BvbnNlIHRvIHRoZSBMQVBPUCdzIEFCIEVYQzE4IHF1ZXN0aW9uOiAiRG8geW91IHRoaW5rIGdpdmVuIHRoZSB3YXkgdGhpbmdzIGFyZSwgc29tZXRpbWVzIHBheWluZyBhIGJyaWJlIGlzIGp1c3RpZmllZD8iLiAkY3RvbD0xJCBpcyAxIHdoZW4gdGhlIHJlc3BvbnNlIHRvIEVYQzE4IGlzICJZZXMiLCAiMCIgaWYgdGhlIGFuc3dlciBpcyAiTm8iIGFuZCB0aGUgTkEgdmFsdWVzIHJlcG9ydGVkIGJ5IHRoZSBBQidzIGRhdGFiYXNlcyBhcmUgYWxzbyB0YWtlbiBhcyBtaXNzaW5nIHZhbHVlcyBmb3IgdGhpcyBhbmFseXNpcy4NCg0KJHlfezE2fSQgaXMgdGhlIDIwMTYgeWVhciBkdW1teSwgb3RoZXIgZmFjdG9ycyBhcmUgY29udHJvbHMgaW5jbHVkZWQgaW4gdGhlIG1vZGVscyBhbmQgdGhlIERpRCBlc3RpbWF0ZXMgKCRcaGF0e1xsYW1iZGFfaX0kKSBhcmUgdGhvc2UgdGhhdCByZXN1bHQgZnJvbSBpbnRlcmFjdGluZyB0aGUgMjAxNiBkdW1teSB3aXRoIGtleSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgdGhhdCBhcmUgdGhvdWdodCB0byBpbmZsdWVuY2UgdGhlIGp1bXAgaW4gY29ycnVwdGlvbiB0b2xlcmFuY2UuDQoNCiMjIERlY2xhcmluZyB0aGUgc3VydmV5IGRlc2lnbg0KDQpUaGUgTEFQT1AncyBBbWVyaWNhJ3MgQmFyb21ldGVyIGlzIGEgY29tcGxleC1kZXNpZ24gc3VydmV5IHdpdGggY2x1c3RlcnMgYW5kIHN0cmF0YS4gRHVlIHRvIHRoaXMsIHRoZSBzdXJ2ZXkgZGVzaWduIG11c3QgYmUgZGVjbGFyZWQgaW4gb3JkZXIgdG8gcHJvZHVjZSB0aGUgYWRlcXVhdGUgYWRqdXN0bWVudHMgaW4gdGhlIGRhdGEgYW5hbHlzaXMsIGFzIGZvbGxvd3M6DQoNCmBgYHtyIHN1cnZleS1kZXNpZ259DQojIEZvciBhbGwgeWVhcnMNCmFiX2Rlc19lYzwtc3Z5ZGVzaWduKGlkcz1+dXBtLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGE9fmVzdHJhdG9wcmksIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHdlaWdodHM9fndlaWdodDE1MDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3Q9VFJVRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBuYS5hY3Rpb24gPSAnbmEuZXhjbHVkZScsDQogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kZikNCg0KIyBGb3IgeWVhcnMgMjAxNC0yMDE2DQphYl9kZXNfZWMxNDE2PC1zdnlkZXNpZ24oaWRzPX51cG0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0YT1+ZXN0cmF0b3ByaSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0cz1+d2VpZ2h0MTUwMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgbmVzdD1UUlVFLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG5hLmFjdGlvbiA9ICduYS5leGNsdWRlJywNCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRmNDYpDQojIE9ubHkgZm9yIDIwMTQNCg0KYWJfZGVzX2VjMTQ8LXN2eWRlc2lnbihpZHMgPSB+IHVwbSwgDQogICAgICAgICAgICAgICAgICAgICAgc3RyYXRhID0gfiBlc3RyYXRvcHJpLCANCiAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHRzID0gfiB3dCwgDQogICAgICAgICAgICAgICAgICAgICAgbmVzdCA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgbmEuYWN0aW9uID0gJ25hLmV4Y2x1ZGUnLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl8yMDE0KQ0KIyBPbmx5IGZvciAyMDE2DQoNCmFiX2Rlc19lYzE2PC1zdnlkZXNpZ24oaWRzID0gfiB1cG0sIA0KICAgICAgICAgICAgICAgICAgICAgIHN0cmF0YSA9IH4gZXN0cmF0b3ByaSwgDQogICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0cyA9IH4gd3QsIA0KICAgICAgICAgICAgICAgICAgICAgIG5lc3QgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgICAgIG5hLmFjdGlvbiA9ICduYS5leGNsdWRlJywNCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfMjAxNikNCg0KYGBgDQoNCiMjIyBBZGp1c3RtZW50cyBkb25lDQoNCkJ5IGZhciB0aGUgbW9zdCBpbXBvcnRhbnQgYW5kIGZyZXF1ZW50IGFkanVzdG1lbnRzIHRoYXQgd2lsbCBiZSBkb25lIHdpdGggdGhlIHN1cnZleSBkZXNpZ24gd2lsbCBiZSB0aG9zZSByZWdhcmRpbmcgdGhlIGNhbGN1bGF0aW9ucyBpbiByZWdyZXNzaW9uIG1vZGVscy4gU28gZmFyLCBhZnRlciB1c2luZyB0aGUgYWRqdXN0bWVudHMgaW4gcmVncmVzc2lvbiB0aHJ1IGBzdnlnbG0oKWAsIG9ubHkgdGhlIHN0YW5kYXJkIGVycm9ycyBhbmQgdGhlIGludGVyY2VwdCBhcmUgY2hhbmdlZCwgYXMgZm9sbG93cyBmcm9tIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSBtb2RlbC4NCg0KYGBge3IgdGVzdHJlZ3MsIHdhcm5pbmcgPSBGfQ0KIyBGaXJzdCBhbiB1bmFkanVzdGVkIGxvZ2l0IG1vZGVsDQpsb2dfYWdlPC1nbG0oY3RvbCB+IHllYXIgKyBhZ2UsIA0KICAgICAgICAgICAgIGRhdGEgPSBkZjQ2LA0KICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCiMgTm93IHRoZSBhZGp1c3RlZCBsb2dpdCBtb2RlbA0KbG9nX2FnZV9hZDwtc3Z5Z2xtKGN0b2wgfiB5ZWFyICsgYWdlLCANCiAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCmBgYA0KDQpgYGB7ciB0ZXN0X3RhYmxlcywgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0nYXNpcycsIGFsaWduID0gJ2NlbnRlcicsIGZpZy5hbGlnbj0gJ2NlbnRlcid9DQojIFN0YXJnYXplcg0Kc2dfdGVzdDwtc3RhcmdhemVyKGxpc3QobG9nX2FnZSwgbG9nX2FnZV9hZCksDQogICAgICAgICAgICAgICAgICAgdHlwZSA9ICdodG1sJywNCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9IFQpDQpgYGANCg0KYGBge3Igc2hvdy1yZXN1bHRzLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZ9DQpzdGFyZ2F6ZXIobGlzdChsb2dfYWdlLCBsb2dfYWdlX2FkKSwgdHlwZSA9ICd0ZXh0JykNCmBgYA0KDQpBcyBpdCBjYW4gYmUgc2VlbiBhYm92ZSwgdGhlcmUgaXMgbm8gcGFydGljdWxhciBjaGFuZ2UgdG8gdGhlIG1hZ25pdHVkZXMgb2YgdGhlIGNvZWZmaWNpZW50cyBleGNlcHQgdGhlIGludGVyY2VwdC4gVGhpcyBtaWdodCBiZSBiZWNhdXNlIHRoZSBzYW1wbGVzIGluIGJvdGggMjAxNCBhbmQgMjAxNiBhcmUgc2VsZi13ZWlnaHRlZC4gVGhlIG9ubHkgY2hhbmdlcyBhcmUgZG9uZSB0byBhY2NvdW50IHRoZSB1bmVxdWFsIHNlbGVjdGlvbiBwcm9iYWJpbGl0eSBvZiBlYWNoIG9ic2VydmF0aW9uIChpLmUuIHRoZSB2aW9sYXRpb24gb2YgdGhlIHJhbmRvbSBzYW1wbGluZyBhc3N1bXB0aW9uKS4gVGhpcyBzZWVtcyB0byBhZmZlY3Qgc3RhbmRhcmQgZXJyb3JzLCBub3QgdGhlIGNvZWZmaWNpZW50cy4NCg0KQWRkaXRpb25hbGx5LCBvdGhlciBhZGp1c3RtZW50cyB0byBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGFyZSB1c3VhbGx5IG5lY2Vzc2FyeSB3aGVuIHByZXNlbnRpbmcgZ3JhcGhzLCBzcGVjaWFsbHkuIFRoZXNlIGFyZSBkb25lIHVzaW5nIHRoZSBkZXNpZ24gdmFyaWFibGVzIGluIHRoZSBkYXRhYmFzZSBhbmQgY29tbWFuZHMgd2l0aCB0aGUgYHN2eWAgcHJlZml4Lg0KDQojIyBIb3cgbW9kZWxzIGFyZSBwcmVzZW50ZWQNCg0KVGhyb3VnaG91dCB0aGlzIHN0dWR5LCBiZXNpZGVzIGZyb20gYWx3YXlzIHRha2luZyBkZXNpZ24gZWZmZWN0cyBpbnRvIGFjY291bnQsIEkgd2lsbCBwcmVzZW50IGFsbCBtb2RlbHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nICphdmVyYWdlIHBhcnRpYWwgZWZmZWN0cyosIGFsb25nIHdpdGggdGhlaXIgZXN0aW1hdGVkICRcaGF0e1xiZXRhX2p9JCBjb2VmZmljaWVudHMuIE5hdHVyYWxseSwgdGFibGVzIHdpdGggbWFyZ2luYWwgZWZmZWN0cyBvbmx5IHNob3cgZmlndXJlcyBmb3IgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcywgbm90IGZvciBjb2VmZmljaWVudHMgb3IgY29tcGxleCBmdW5jdGlvbmFsIGZvcm1zLg0KDQpgYGB7ciBjYWxjdWxhdGlvbnNfZXhhbXBsZSwgd2FybmluZyA9IEYsIG1lc3NhZ2UgPSBGLCByZXN1bHRzID0gJ2FzaXMnfQ0KIyBDb21wdXRlIEFQRXMgdGhyb3VnaCBtYXJnaW5zDQptZV9sb2dhZ2U8LW1hcmdpbnMobG9nX2FnZSkNCm1lX2xvZ2FnZWFkPC1tYXJnaW5zKGxvZ19hZ2VfYWQpDQoNCiMgQ29tcHV0ZSB0aGUgc3VydmV5LXdlaWdodGVkIGxvZ2l0IFBDUHMNCg0KcGNwX2xvZ19hZ2U8LWhpdG1pc3MobG9nX2FnZV9hZCkNCnBjcF9sb2dfYWdlPC1yb3VuZChwY3BfbG9nX2FnZSwgMikNCm5hbWVzKHBjcF9sb2dfYWdlKTwtYygnVG90YWwnLCAneT0wJywgJ3k9MScpICMgR2l2ZSB2ZWN0b3IgbmFtZXMgdG8gYmV0dGVyIHVzZSBpbiB0YWJsZXMuIA0KDQojIEJ1aWxkIGEgbGlzdCBvZiB0aGUgbWFyZ2luYWwgZWZmZWN0cyB0byBsYXRlciB1c2Ugd2l0aCBtb2RlbHN1bW1hcnkNCg0KbGlzdF9tZTE8LWxpc3QobWVfbG9nYWdlLCBtZV9sb2dhZ2VhZCkNCg0KYGBgDQoNCkJlbG93LCBJIGV4ZW1wbGlmeSBhIHRhYmxlIG9mIGNvZWZmaWNpZW50cyB0byBiZSBzaG93biBpbiB0aGUgcGFwZXIuIFRoZXNlIHRhYmxlcyBhcmUga2V5IGZvciBzaG93aW5nIHRoZSBlZmZlY3RzIG9mIGNvbXBsZXggZnVuY3Rpb25hbCBmb3Jtcywgd2hpY2ggYXJlIG90aGVyd2lzZSBub3Qgc2VlbiBpbiBBUEUgdGFibGVzLiBBbHNvLCB0aGUgb3ZlcmFsbCBwZXJjZW50IGNvcnJlY3RseSBwcmVkaWN0ZWQgKFBDUCkgd2lsbCBiZSBzaG93biwgYWxvbmcgd2l0aCB0aGUgUENQIGZvciBlYWNoIG9mIHRoZSBvdXRjb21lcyBpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLg0KDQpgYGB7ciBjb2VmX2V4X3Nob3csIHdhcm5pbmcgPSBGLCByZXN1bHRzID0gJ2FzaXMnfQ0KDQpzdGFyZ2F6ZXIobGlzdChsb2dfYWdlLCBsb2dfYWdlX2FkKSwNCiAgICAgICAgICB0eXBlID0gJ2h0bWwnLA0KICAgICAgICAgIG1vZGVsLm5hbWVzID0gRiwNCiAgICAgICAgICBhZGQubGluZXMgPSBsaXN0KGMoJ01vZGVsIFR5cGUnLCAnTFBNKHVud2VpZ2h0ZWQpJywgJ0xvZ2l0KHN1cnZleS13ZWlnaHRlZCknKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjKCdQQ1AgKFRvdGFsKScsICcnLCBwY3BfbG9nX2FnZVsxXSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjKCdQQ1AoeT0xKScsICcnLCBwY3BfbG9nX2FnZVsyXSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjKCdQQ1AgKHk9MCknLCAnJywgcGNwX2xvZ19hZ2VbM10pKSwNCiAgICAgICAgICBrZWVwLnN0YXQgPSAnbicpDQoNCmBgYA0KDQpgYGB7ciBjb2VmX2V4X3Nob3dfdGV4dCwgd2FybmluZyA9IEYsIGluY2x1ZGUgPSBGfQ0Kc3RhcmdhemVyKGxpc3QobG9nX2FnZSwgbG9nX2FnZV9hZCksDQogICAgICAgICAgdHlwZSA9ICd0ZXh0JywNCiAgICAgICAgICBtb2RlbC5uYW1lcyA9IEYsDQogICAgICAgICAgYWRkLmxpbmVzID0gbGlzdChjKCdNb2RlbCBUeXBlJywgJ0xQTSh1bndlaWdodGVkKScsICdMb2dpdChzdXJ2ZXktd2VpZ2h0ZWQpJyksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnUENQIChUb3RhbCknLCAnJywgcGNwX2xvZ19hZ2VbMV0pLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnUENQKHk9MSknLCAnJywgcGNwX2xvZ19hZ2VbMl0pLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnUENQICh5PTApJywgJycsIHBjcF9sb2dfYWdlWzNdKSksDQogICAgICAgICAga2VlcC5zdGF0ID0gJ24nKQ0KYGBgDQoNCkluIG9jY2FzaW9ucyB3aGVyZSBpdCBpcyBuZWNlc3NhcnksIEkgcHJlc2VudCBhbiBhZGRpdGlvbmFsIHRhYmxlIHdpdGggQVBFcy4gU29tZXRpbWVzIEknbGwgcHJlc2VudCBBUEVzIHdpdGhvdXQgdGhlaXIgZXN0aW1hdGVkIGNvZWZmaWNpZW50cyBiZWZvcmUuIEluIHRob3NlIGNhc2VzIEknbGwgcHV0IHRoZSByZXF1aXJlZCBtb2RlbCBzdGF0cyBiZWxvdywgbGlrZSB0aGUgcHJldmlvdXMgdGFibGUuDQoNCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnfQ0KbW9kZWxzdW1tYXJ5KGxpc3RfbWUxLCBvdXRwdXQgPSAnaHRtbCcsIHN0YXJzID0gYygnKicgPSAuMSwgJyoqJyA9MC4wNSwgJyoqKic9IDAuMDEpKQ0KYGBgDQoNCiMjIFNpbXBsZSBzaWduaWZpY2FudCBEaUQgbW9kZWxzDQoNClRoZXNlIGFyZSBzaW1wbGUsIG9uZSB2YXJpYWJsZSBEaUQgbG9naXQgbW9kZWxzIHdoaWNoIHByb3ZlIHNpZ25pZmljYW5jZS4gVGhleSBnaXZlIGluc2lnaHQgaW50byB3aGF0IGNoYXJhY3RlcmlzdGljcyBvZiBwdWJsaWMgb3BpbmlvbiBjaGFuZ2VkIGR1cmluZyB0aGUgMjAxNC0yMDE2IHBlcmlvZCBhbmQgd2hpY2ggYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgY2hhbmdlcyBhZmZlY3RpbmcgY29ycnVwdGlvbiB0b2xlcmFuY2UgaW4gdGhlIHBlcmlvZC4NCg0KYGBge3Igc2ltcGxlX2RpZCwgd2FybmluZyA9IEZ9DQojIFVuZW1wbG95bWVudCBEaUQNCg0KbG9nX3VuZW1kaWQ8LXN2eWdsbShjdG9sIH4geWVhcip1bmVtXzRhLCANCiAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSAjIExvZ2l0DQogICAgICAgICAgICAgICAgICAgKQ0KDQpwcm9iX3VuZW1kaWQ8LXN2eWdsbShjdG9sIH4geWVhcip1bmVtXzRhLCANCiAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAncHJvYml0JykgIyBQcm9iaXQNCiAgICAgICAgICAgICAgICAgICApDQoNCiMgUG9saXRpY2FsIFNjb3JlIChIaWdoZXIgc2NvcmVzIG1lYW5zIG1vcmUgaWRlbnRpZmllZCB3aXRoIHJpZ2h0IHdpbmcpDQoNCmxvZ19wb2xzZGlkPC1zdnlnbG0oY3RvbCB+IHllYXIqcG9sc2NvcmUsIA0KICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpICMgTG9naXQNCiAgICAgICAgICAgICAgICAgICApDQoNCnByb2JfcG9sc2RpZDwtc3Z5Z2xtKGN0b2wgfiB5ZWFyKnBvbHNjb3JlLCANCiAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAncHJvYml0JykgIyBQcm9iaXQNCiAgICAgICAgICAgICAgICAgICApDQoNCiMgQ29uZmlkZW5jZSBpbiB0aGUgcHJlc2lkZW50IA0KDQpsb2dfcGNvbmZkaWQ8LXN2eWdsbShjdG9sIH4geWVhcipwcmVzX2NvbmYsIA0KICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpICMgTG9naXQNCiAgICAgICAgICAgICAgICAgICApDQoNCnByb2JfcGNvbmZkaWQ8LXN2eWdsbShjdG9sIH4geWVhcipwcmVzX2NvbmYsIA0KICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSAjIExvZ2l0DQogICAgICAgICAgICAgICAgICAgKQ0KDQpgYGANCg0KV2Ugd291bGQgZXhwZWN0IHRoYXQgaWYgd2UgZ2V0IGEgc2lnbmlmaWNhbnQgRGlEIGVzdGltYXRlIHRoZXNlIGFyZSBrZXkgZXhwbGFuYXRvcnkgdmFyaWFibGVzIHdoaWNoIGNoYW5nZWQgZm9yIDIwMTYgd2l0aCByZXNwZWN0IHRvIDIwMTQgYW5kIGFyZSBpbXBvcnRhbnQgZHJpdmVycyBpbiBob3cgcGVvcGxlIGp1c3RpZnkgYWN0cyBvZiBjb3JydXB0aW9uLiBCZWxvdywgdGhlIG1vZGVscyBhcmUgc2hvd24sIGZvciB0aHJlZSBkaWZmZXJlbnQgdmFyaWFibGVzLg0KDQpBIHNpZ25pZmljYW50IERpRCBtYXkgbm90IG1lYW4gdGhhdCBpdCB3YXMgYSBkZXRlcm1pbmFudCBmYWN0b3Igd2hpY2ggaW5jcmVhc2VkIG92ZXJhbGwgY29ycnVwdGlvbiB0b2xlcmFuY2UgaW4gRWN1YWRvci4gTXVzdCBsb29rIGF0IHRoZSBzaWducyBmaXJzdC4NCg0KSSBub3cgY2FsY3VsYXRlIFBDUFMgYW5kIG1hcmdpbmFsIGVmZmVjdHMuDQoNCmBgYHtyIGRpZF9iYXNlX21lLCB3YXJuaW5nID0gRn0NCg0KIyBFc3RpbWF0ZSBtYXJnaW5hbCBlZmZlY3RzIGZvciBib3RoIHByb2JpdCBhbmQgbG9naXQgdmVyc2lvbnMgb2YgYWxsIG1vZGVscw0KDQptZV91bmVtZGlkX2xvZzwtbWFyZ2lucyhsb2dfdW5lbWRpZCkNCg0KbWVfdW5lbWRpZF9wcm9iPC1tYXJnaW5zKHByb2JfdW5lbWRpZCkNCg0KbWVfcG9sc2RpZF9sb2c8LW1hcmdpbnMobG9nX3BvbHNkaWQpDQoNCm1lX3BvbHNkaWRfcHJvYjwtbWFyZ2lucyhwcm9iX3BvbHNkaWQpDQoNCm1lX3Bjb25mZGlkX2xvZzwtbWFyZ2lucyhsb2dfcGNvbmZkaWQpDQoNCm1lX3Bjb25mZGlkX3Byb2I8LW1hcmdpbnMocHJvYl9wY29uZmRpZCkNCg0KIyBBbHNvIHN0b3JlIHRoZSBsb2dpdCBjb2VmZmljaWVudHMgYW5kIEFQRXMgaW4gYSBsaXN0LCB0byBwcmVzZW50IGZ1cnRoZXIuDQoNCmRpZF9iYXNlX2xvZzwtbGlzdChsb2dfdW5lbWRpZCwNCiAgICAgICAgICAgICAgICAgICBsb2dfcG9sc2RpZCwNCiAgICAgICAgICAgICAgICAgICBsb2dfcGNvbmZkaWQpDQoNCmRpZF9iYXNlX2FwZXM8LWxpc3QobWVfdW5lbWRpZF9sb2csDQogICAgICAgICAgICAgICAgICAgIG1lX3BvbHNkaWRfbG9nLA0KICAgICAgICAgICAgICAgICAgICBtZV9wY29uZmRpZF9sb2cpDQoNCiMgUENQcw0KDQpwY3BfdWxvZzwtaGl0bWlzcyhsb2dfdW5lbWRpZCkNCnBjcF9wb2xzbG9nPC1oaXRtaXNzKGxvZ19wb2xzZGlkKQ0KcGNwX3Bjb25mbG9nPC1oaXRtaXNzKGxvZ19wY29uZmRpZCkNCmBgYA0KDQpJIHByZXNlbnQgdGhlIGNvZWZmaWNpZW50cyBvZiBsb2dpdCBtb2RlbHMgYmVsb3csIGFsb25nIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBQQ1BzOg0KDQpgYGB7ciBzdGdfZGlkYmFzZSwgd2FybmluZyA9IEYsIHJlc3VsdHMgPSAnYXNpcyd9DQpzdGFyZ2F6ZXIobGlzdChsb2dfdW5lbWRpZCxsb2dfcG9sc2RpZCwgbG9nX3Bjb25mZGlkKSwNCiAgICAgICAgICB0eXBlID0gJ2h0bWwnLA0KICAgICAgICAgIGFsaWduID0gVCwgDQogICAgICAgICAgdGl0bGUgPSAnQmFzZSBEaWZmZXJlbmNlIGluIERpZmZlcmVuY2UgTG9naXQgTW9kZWxzJywNCiAgICAgICAgICBrZWVwLnN0YXQgPSAnbicsDQogICAgICAgICAgb21pdCA9IGMoJ0NvbnN0YW50JyksDQogICAgICAgICAgbW9kZWwubmFtZXMgPSBGLA0KICAgICAgICAgIGRpZ2l0cyA9IDIsDQogICAgICAgICAgYWRkLmxpbmVzID0gbGlzdChjKCdQQ1AnLCByb3VuZChwY3BfdWxvZ1sxXSwyKSwgcm91bmQocGNwX3BvbHNsb2dbMV0sMiksIHJvdW5kKHBjcF9wY29uZmxvZ1sxXSwyKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjKCdQQ1AoeT0wKScscm91bmQocGNwX3Vsb2dbMl0sMiksIHJvdW5kKHBjcF9wb2xzbG9nWzJdLDIpLCByb3VuZChwY3BfcGNvbmZsb2dbMl0sMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnUENQKHk9MSknLHJvdW5kKHBjcF91bG9nWzNdLDIpLCByb3VuZChwY3BfcG9sc2xvZ1szXSwyKSwgcm91bmQocGNwX3Bjb25mbG9nWzNdLDIpKSkpDQpgYGANCg0KYGBge3Igc3RnX2RpZGJhc2VfdGV4dCwgaW5jbHVkZSA9IEZ9DQpzdGFyZ2F6ZXIobGlzdChsb2dfdW5lbWRpZCxsb2dfcG9sc2RpZCwgbG9nX3Bjb25mZGlkKSwNCiAgICAgICAgICB0eXBlID0gJ3RleHQnLA0KICAgICAgICAgIGFsaWduID0gVCwgDQogICAgICAgICAgdGl0bGUgPSAnQmFzZSBEaWZmZXJlbmNlIGluIERpZmZlcmVuY2UgTG9naXQgTW9kZWxzJywNCiAgICAgICAgICBrZWVwLnN0YXQgPSAnbicsDQogICAgICAgICAgbW9kZWwubmFtZXMgPSBGLA0KICAgICAgICAgIGRpZ2l0cyA9IDIsDQogICAgICAgICAgYWRkLmxpbmVzID0gbGlzdChjKCdQQ1AnLCByb3VuZChwY3BfdWxvZ1sxXSwyKSwgcm91bmQocGNwX3BvbHNsb2dbMV0sMiksIHJvdW5kKHBjcF9wY29uZmxvZ1sxXSwyKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjKCdQQ1AoeT0wKScscm91bmQocGNwX3Vsb2dbMl0sMiksIHJvdW5kKHBjcF9wb2xzbG9nWzJdLDIpLCByb3VuZChwY3BfcGNvbmZsb2dbMl0sMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnUENQKHk9MSknLHJvdW5kKHBjcF91bG9nWzNdLDIpLCByb3VuZChwY3BfcG9sc2xvZ1szXSwyKSwgcm91bmQocGNwX3Bjb25mbG9nWzNdLDIpKSkpDQogICANCmBgYA0KDQpOb3csIEkgcHJlc2VudCBBUEVzIGZvciB0aGUgbG9naXQgbW9kZWxzLg0KDQpgYGB7ciBkaWRfYmFzZV9hcGVzLCByZXN1bHRzID0gJ2FzaXMnfQ0KDQptb2RlbHN1bW1hcnkoZGlkX2Jhc2VfYXBlcywgDQogICAgICAgICAgICAgb3V0cHV0ID0gJ2h0bWwnLCANCiAgICAgICAgICAgICBzdGFycyA9IGMoJyonID0gLjEsICcqKicgPTAuMDUsICcqKionPSAwLjAxKSkNCg0KYGBgDQoNCiMjIyBBIG5vdGUgb24gY29lZmZpY2llbnRzIGFuZCBBUEVzDQoNCkl0cyBpbXBvcnRhbnQgdG8gbm90ZSB0aGFuIHdoZW4gbW9yZSBjb21wbGV4IGZ1bmN0aW9uYWwgZm9ybXMgZW50ZXIgdGhlIHJlZ3Jlc3Npb24gZXF1YXRpb24sIGF2ZXJhZ2UgcGFydGlhbCBlZmZlY3RzIGFyZSBvbmx5IGNhbGN1bGF0ZWQgZm9yIHRoZSAicHJpbmNpcGFsIiB2YXJpYWJsZXMsIG1lYW5pbmcgdGhhdCBubyBtYXJnaW5hbCBlZmZlY3RzIGFyZSBjYWxjdWxhdGVkIGZvciB0aGUgRGlEIGVzdGltYXRlcy4gRm9yIGV4YW1wbGUsIHRoZSBlZmZlY3Qgb2YgdGhlIERpRCAiZW50ZXJzIiB0aGUgeWVhciBBUEUuIENvbnNpZGVyIGFuIExQTSBtb2RlbCB3aXRoIHVuZW1wbG95bWVudDoNCg0KJCRQKGN0b2wgPSAxIHwgXG1hdGhiYntYfSkgPSBcYmV0YV8wICsgXGRlbHRhXzAgeV97MTZ9ICsgXGJldGFfMSAoXG11KSArIFxkZWx0YV8xIFxsZWZ0KCB5X3sxNn0gXGNkb3QgXG11IFxyaWdodCkgKyB1JCQgVGhlIHBhcnRpYWwgZWZmZWN0IG9mIHllYXIgaW4gJGN0b2wkIGlzDQoNCiQkXGRmcmFje1xwYXJ0aWFsIGN0b2x9e1xwYXJ0aWFsIHlfezE2fX0gPSBcZGVsdGFfMCArIFxkZWx0YV8xIFxtdSAkJA0KDQpBbmQgdGhlIHBhcnRpYWwgZWZmZWN0IG9mIHVuZW1wbG95bWVudCBpbiAkY3RvbCQgaXMNCg0KJCRcZGZyYWN7XHBhcnRpYWwgY3RvbCB9eyBccGFydGlhbCBcbXV9ID0gXGJldGFfMSArIFxkZWx0YV8xIHlfezE2fSQkIFRodXMsIHdoZW4gY29uc2lkZXJpbmcgdGhlIEFQRXMgZm9yIHRoaXMgbW9kZWwsIHdoYXQgaXMgYWN0dWFsbHkgYmVpbmcgY29tcHV0ZWQgaXMgdGhlIGF2ZXJhZ2Ugb2YgdGhlIHJlc3VsdHMgb2YgdGhlc2UgdHdvIGVxdWF0aW9ucyBmb3IgYWxsIHBlb3BsZSBpbiB0aGUgc2FtcGxlLiBUaGVyZSB3b24ndCBiZSBhbiBBUEUgZm9yIGFuIGludGVyYWN0aW9uIHRlcm0uDQoNCkluIG9yZGVyIHRvIHRlc3QgZm9yICJkaWZmZXJlbmNlcyBhY3Jvc3MgZ3JvdXBzIiwgd2UgbWlnaHQgd2FudCB0byBmb2N1cyBvbiB0aGUgaW50ZXJhY3Rpb24gdGVybSBhbmQgaXQncyBzaWduaWZpY2FuY2UuIElmICRcZGVsdGFfMT4wJCBpbiB0aGUgc2FtcGxlLCBpdCBtZWFucyB0aGF0IHRoZXJlIGlzIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIG9uIGhvdyB0aGUgdW5lbXBsb3llZCB0b2xlcmF0ZSBjb3JydXB0aW9uIGJldHdlZW4gdGhlIHllYXJzLiBXZSBtaWdodCB3YW50IHRvIGtub3cgdGhlIGVmZmVjdCBhcyBhIHdob2xlLCBpLmUuIHRoZSAiY29tcGxldGUiIGVmZmVjdCBvZiBiZWluZyB1bmVtcGxveWVkIG9uIDIwMTYgZm9yIGNvcnJ1cHRpb24gdG9sZXJhbmNlLiBUaGlzIG1lYW5zIHBsdWdnaW5nIGluICR5X3sxNn09MSQgaW4gdGhlIGVxdWF0aW9uIGZvciB0aGUgcGFydGlhbCBlZmZlY3Qgb2YgdW5lbXBsb3ltZW50ICRcbXUkIGluIGNvcnJ1cHRpb24gdG9sZXJhbmNlLiBUaGlzIHdvdWxkIGVxdWFsIGxvb2tpbmcgYXQgdGhlIHF1YW50aXR0eSAkXGhhdHtcYmV0YV8xfSArIFxoYXR7XGRlbHRhXzF9eV97MTZ9JC4gSW4gb3JkZXIgdG8gdGVzdCBzaWduaWZpY2FuY2UgZm9yIGl0LCBvbmUgY2FuIHJlcGFyYW1ldGVyaXplIHRoZSBtb2RlbCBvciBzaW1wbHkgcnVuIGEgcmVncmVzc2lvbiB0aGF0IG9ubHkgdXNlcyBvYnNlcnZhdGlvbnMgaW4gMjAxNi4NCg0KIyMjIFVuZW1wbG95bWVudCBhbmQgTGFib3IgTWFya2V0DQoNClRoZSBzaWduaWZpY2FuY2UgaW4gYm90aCB0aGUgdW5lbXBsb3ltZW50IHRlcm0gYW5kIGl0cyBpbnRlcmFjdGlvbiB3aXRoIHRoZSAyMDE2IGR1bW15IHNheSB0aGF0LCBpbiBhbnkgeWVhciwgYW4gdW5lbXBsb3llZCBpbmRpdmlkdWFsIGlzIG1vcmUgbGlrZWx5IHRvIGp1c3RpZnkgY29ycnVwdGlvbi4gSG93ZXZlciwgaW4gMjAxNiwgdGhpcyBpbmRpdmlkdWFsLCB3aGlsZSBzdGlsbCBtb3JlIGxpa2VseSB0byBhY2NjZXB0IGNvcnJ1cHRpb24gdGhhbiBzb21lb25lIHdobyBpcyBub3QgdW5lbXBsb3llZCAoaW5jbHVkZXMgdGhvc2UgaW4gYW5kIG91dCBvZiB0aGUgbGFib3IgZm9yY2UpLCBpcyBsZXNzIHNvIGNvbXBhcmVkIHRvIDIwMTQuDQoNClRoZSBzYW1lIHNlZW1zIHRvIGhvbGQgZm9yIHRoZSBtb2RlbCB0aGF0IGluY2x1ZGVzIHRoZSBlbXBsb3ltZW50IGFuZCBub3QgaW4gd29ya2ZvcmNlIGR1bW1pZXMuDQoNCiMjIyBQb2xpdGljYWwgc2NvcmUNCg0KT25seSB0aGUgRGlEIHRlcm0gaXMgc2lnbmlmaWNhbnQsIG1lYW5pbmcgdGhhdCBhIHBlcnNvbiB3aG8gaWRlbnRpZmllcyBtb3JlIHdpdGggdGhlIHJpZ2h0IHdpbmcgaXMgbm90IHNpZ25pZmljYW50bHkgbW9yZSB0b2xlcmFudCBvZiBjb3JydXB0aW9uIGluIDIwMTQuIEhvd2V2ZXIsIGluIDIwMTYgdGhlIG1vcmUgdG8gdGhlIHJpZ2h0IGEgcGVyc29uIHNpZ25hbHMgdGhhdCB0aGV5IGFyZSwgdGhlIG1vcmUgdGhleSBqdXN0aWZ5IGNvcnJ1cHRpb24uIFRoaXMgd2FycmFudHMgbW9yZSBpbnZlc3RpZ2F0aW9uIGFzIGl0IHN1Z2dlc3RzIGFuIGludGVyZXN0aW5nIGlkZWEuDQoNCiMjIyBDb25maWRlbmNlIGluIHRoZSBwcmVzaWRlbnQNCg0KVGhpcyBxdWVzdGlvbiAoQjIxQSBpbiB0aGUgc3VydmV5KSwgYXNrczogKsK/SGFzdGEgcXXDqSBwdW50byB0aWVuZSBjb25maWFuemEgdXN0ZWQgZW4gZWwgcHJlc2lkZW50ZT8qLCBhcyB1c3VhbCwgaW4gYSAxLTcgc2NhbGUuIFRoZSBkaXJlY3Rpb25zIG9mIHRoZSBlZmZlY3RzIGVzdGltYXRlZCBhcmUgcXVpdGUgaW50ZXJlc3RpbmcuDQoNCkluIDIwMTQsIHNvbWVvbmUgdGhhdCBoYWQgbW9yZSBjb25maWRlbmNlIGluIHRoZSBwcmVzaWRlbnQgd2FzIHNpZ25pZmljYW50bHkgbGVzcyB0b2xlcmFudCBvZiBjb3JydXB0aW9uLiBUaGUgRGlEIHRlcm0gaXMgcG9zaXRpdmUgYnV0IHNtYWxsZXIgdGhhbiB0aGUgY29uZmlkZW5jZSB0ZXJtLiBUaGlzIG1lYW5zIHRoYXQsIGluIDIwMTYsIGEgcGVyc29uIHRoYXQgY29uZmlkZWQgaW4gdGhlIHByZXNpZGVudCB3YXMgc3RpbGwgbGVzcyBsaWtlbHkgdG8gdG9sZXJhdGUgY29ycnVwdGlvbiByZWxhdGl2ZSB0byBzb21lb25lIHRoYXQgY29uZmlkZWQgbGVzcy4gSG93ZXZlciwgdGhleSBkaWQgc28gaW4gYSBzbWFsbGVyIHdheSBjb21wYXJlZCB0byAyMDE0Lg0KDQpUaGlzIG1heSBleHBsYWluIHRoZSBqdW1wIGluIGNvcnJ1cHRpb24gdG9sZXJhbmNlLCBhcywgYWNjb3JkaW5nIHRvIHRoZSBncmFwaHMgYmVsb3csIHRoZXJlIGlzIGEgc2hhcnAgZGVjbGluZSBpbiBwZW9wbGUgd2hvIGNvbmZpZGUgaW4gdGhlIHByZXNpZGVudC4gTm90ZSB0aGF0IHRoZSB3YXkgdGhhdCB0aGUgcHJlc2lkZW50aWFsIGNvbmZpZGVuY2UgdmFyaWFibGUgaXMgZGljaG90b21pemVkIGlzIHNpbWlsYXIgdG8gdGhlIGRpY2hvdG9taXphdGlvbiBvZiBzaW1pbGFyIDEtNyBzY2FsZWQgdmFyaWFibGVzIGluIEFtZXJpY2EncyBCYXJvbWV0ZXIncyByZXBvcnRzIChzY29yZXMgaW4gNS03IGFyZSBjb2RlZCBhcyAiWWVzIiBvciB3aXRoIHZhbHVlIDEpLg0KDQpgYGB7ciBwcmVzX2NvbmZfZGljLCBldmFsPUZBTFNFfQ0KZGYkcHJlc19jb25mX2RpYzwtaWZlbHNlKGRmJHByZXNfY29uZiA+PSA1LCAnWWVzJywgJ05vJykNCmBgYA0KDQpUaGUgdGFibGUgYmVsb3cgc2hvd3MgdGhlIHRpbWUgc2VyaWVzIG9mIHRoZSBjb25maWRlbmNlIGluIHRoZSBwcmVzaWRlbnQgZm9yIEVjdWFkb3IgYmVnaW5uaW5nIDIwMDYuDQoNCmBgYHtyIHBjb25mX3RpbWV9DQpwcmVzX2NvbmY8LXN2eWJ5KH4gcHJlc19jb25mX2RpYywgfiB5ZWFyLCBkZXNpZ24gPSBhYl9kZXNfZWMsIHN2eW1lYW4sIG5hLnJtID0gVCkgJT4lIGFzLmRhdGEuZnJhbWUoKQ0KcHJlc19jb25mPC1kcGx5cjo6c2VsZWN0KHByZXNfY29uZiwgcHJlc19jb25mX2RpY1llcywgc2UucHJlc19jb25mX2RpY1llcykgJT4lIA0KICAgICAgICAgICByZW5hbWUoJyVZZXMnPXByZXNfY29uZl9kaWNZZXMsICdTRSc9IHNlLnByZXNfY29uZl9kaWNZZXMpDQpwcmVzX2NvbmY8LXByZXNfY29uZlszOjgsXQ0KcHJlc19jb25mDQpgYGANCg0KQmVsb3csIHRoZSBzYW1lIGlzIGRvbmUgdG8gdGhlIHBvbGl0aWNhbCBzY29yZSB2YXJpYWJsZSwgZGl2aWRpbmcgaXQgaW4gbGVmdCBhbmQgcmlnaHQuDQoNCmBgYHtyIGRpY19wb2xzY29yZSwgZXZhbCA9IEZ9DQpkZiRwb2xfd2luZzI8LWlmZWxzZShkZiRwb2xzY29yZSA8IDYsICdMZWZ0JywgJ1JpZ2h0JykNCmBgYA0KDQpgYGB7ciBwb2xzY29yZV90aW1lfQ0KcG9sd2luZzI8LXN2eWJ5KH4gcG9sX3dpbmcyLCB+IHllYXIsIGRlc2lnbiA9IGFiX2Rlc19lYywgc3Z5bWVhbiwgbmEucm0gPSBUKSAlPiUgYXMuZGF0YS5mcmFtZSgpDQpwb2x3aW5nMg0KYGBgDQoNCkFuIGluY3JlYXNlIGluIHVuZW1wbG95bWVudCBpcyBpbmRlZWQgc2VlbiwgaG93ZXZlciwgdGhlIG5ldyB1bmVtcGxveWVkIGp1c3RpZnkgY29ycnVwdGlvbiBpbiBhIGxlc3MgZXh0ZW50IHRvIHRoZSB1bmVtcGxveWVkIGluIDIwMTQuIFRoZSBqdW1wIGluIGNvcnJ1cHRpb24gdG9sZXJhbmNlIGNvdWxkIGJlIGV4cGxhaW5lZCBieSBhIHRlbiBwb2ludCByaXNlIGluIHRoZSBwZXJjZW50YWdlIG9mICJyaWdodC13aW5nZXJzIiwgd2hvIGFyZSBtb3JlIGxpa2VseSB0byBqdXN0aWZ5IGNvcnJ1cHRpb24uIEFsc28sIHNpbmNlIHRoZSBjb25maWRlbmNlIGluIHRoZSBwcmVzaWRlbnQgZGVjcmVhc2VkIGFuZCBmb3IgMjAxNiB0aGUgbmVnYXRpdmUgZWZmZWN0IG9mIGNvbmZpZGVuY2UgaW4gY29ycnVwdGlvbiB0b2xlcmFuY2UgaXMgc21hbGxlciwgd2UgY2FuIGFsc28ganVzdGlmeSB0aGUganVtcCBpbiBjb3JydXB0aW9uIHRvbGVyYW5jZS4NCg0KSXQgaXMgbm90IGV4YWN0bHkgY2xlYXIgd2hldGhlciBpdCBpcyB0aGUgYWN0dWFsIHBvbGl0aWNpYWwgb3JpZW50YXRpb24gd2hpY2ggY2F1c2VzLCBvciBpcyByZWxhdGUgdG8sIGp1c3RpZmljYXRpb24gdG8gY29ycnVwdCBhdHRpdHVkZXMuIFdlIGNvbnRpbnVlIGludmVzdGlnYXRpbmcgdGhpcyBmdXJ0aGVyLg0KDQojIyBDb21wbGV4IERpRCBNb2RlbA0KDQpJIG5vdyBlc3RpbWF0ZSBhIG1vcmUgY29tcGxleCBtb2RlbCwgaW5jb3Jwb3JhdGluZyBhbGwgdGhyZWUgcHJldmlvdXNseSBzaWduaWZpY2FudCBEaURzIGFuZCBhZGRpbmcgb3RoZXIgY29udHJvbCB2YXJpYWJsZXMuDQoNCmBgYHtyIGRpZF9jb21wbGV4X21vZGVsLCB3YXJuaW5nID0gRn0NCiMgRXN0aW1hdGUgdGhlIG1vZGVsIHRocm91Z2ggdGhyZWUgbWV0aG9kcw0KDQojIDEuIExQTQ0KDQpscG1faW5jZDwtc3Z5Z2xtKGN0b2x+IHllYXIqKHVuZW0yXzRhICsgcHJlc19jb25mICsgcG9sc2NvcmUpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyANCiAgICAgICAgICAgICBjb3JycGVyLCANCiAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2KQ0KIyAyLiBQcm9iaXQNCg0KcHJvYl9pbmNkPC1zdnlnbG0oY3RvbH4geWVhcioodW5lbTJfNGEgKyBwcmVzX2NvbmYgKyBwb2xzY29yZSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIA0KICAgICAgICAgICAgICAgY29ycnBlciwgDQogICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSApDQojIDMuIExvZ2l0IA0KDQpsb2dfaW5jZDwtc3Z5Z2xtKGN0b2x+IHllYXIqKHVuZW0yXzRhICsgcHJlc19jb25mICsgcG9sc2NvcmUpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyANCiAgICAgICAgICAgICAgY29ycnBlciwgDQogICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCmBgYA0KDQpJIGNhbGN1bGF0ZSB0aGUgY29ycmVzcG9uZGluZyBhdmVyYWdlIHBhcnRpYWwgZWZmZWN0cyBiZWxvdy4NCg0KYGBge3IgY29tcGxleF9tb2RlbF9hcGVzLCB3YXJuaW5nID0gRn0NCg0KbWVfbHBtYzwtbWFyZ2lucyhscG1faW5jZCkNCm1lX3Byb2JjPC1tYXJnaW5zKHByb2JfaW5jZCkNCm1lX2xvZ2M8LW1hcmdpbnMobG9nX2luY2QpDQoNCiMgQWxzbyBjb21wdXRlIFBDUFMNCg0KcGNwX3Byb2JjPC1oaXRtaXNzKHByb2JfaW5jZCkNCnBjcF9wcm9iYzwtcm91bmQocGNwX3Byb2JjLCA0KQ0KcGNwX2xvZ2M8LWhpdG1pc3MobG9nX2luY2QpDQpwY3BfbG9nYzwtcm91bmQocGNwX2xvZ2MsIDQpDQoNCiMgU3RvcmUgYm90aCBtb2RlbHMgaW4gYSBsaXN0DQoNCmNvbXBsZXhfZGlkX2FsbDwtbGlzdChsb2dfaW5jZCwNCiAgICAgICAgICAgICAgICAgICAgICBwcm9iX2luY2QpDQoNCiMgU3RvcmUgQVBFcyBpbiBhIGxpc3QNCg0KbWVfY29tcGxleF9kaWRhbGw8LWxpc3QobWVfbHBtYywNCiAgICAgICAgICAgICAgICAgICAgICAgIG1lX3Byb2JjLA0KICAgICAgICAgICAgICAgICAgICAgICAgbWVfbG9nYykNCg0KYGBgDQoNCkJlbG93IHRoZSBtb2RlbCBpcyBwcmVzZW50ZWQgdGhyb3VnaCBzdXJ2ZXktd2VpZ2h0ZWQgbGVhc3Qgc3F1YXJlcywgbG9naXQgYW5kIHByb2JpdCBwcm9jZWR1cmVzLiBUaGUgUENQcyBmb3IgZWFjaCBvdXRjb21lIGFuZCB0aGUgb3ZlcmFsbCBvbmUgYXJlIGFsc28gcHJlc2VudGVkLg0KDQpgYGB7ciBwcmVzZW50X2NvbXBsZXhfbW9kZWwsIHJlc3VsdHMgPSAnYXNpcyd9DQpzdGFyZ2F6ZXIobGlzdChscG1faW5jZCwgcHJvYl9pbmNkLCBsb2dfaW5jZCksDQogICAgICAgICAgbW9kZWwubmFtZXMgID0gRiwNCiAgICAgICAgICBhZGQubGluZXMgPSBsaXN0KGMoJ01vZGVsIFR5cGUnLCAnTFBNJywgJ1Byb2JpdCAoVyknLCAnTG9naXQoVyknKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1BDUCcsICcnLCBwY3BfcHJvYmNbMV0sIHBjcF9sb2djWzFdKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1BDUCAoeT0xKScsICcnLCBwY3BfcHJvYmNbMl0sIHBjcF9sb2djWzJdKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1BDUCAoeT0wKScsICcnLCBwY3BfcHJvYmNbM10sIHBjcF9sb2djWzNdKSksDQogICAgICAgICAgdHlwZSA9ICdodG1sJykNCmBgYA0KDQpgYGB7ciBjbW9kZWxfdGV4dCwgaW5jbHVkZSA9IEZ9DQpzdGFyZ2F6ZXIobGlzdChscG1faW5jZCwgcHJvYl9pbmNkLCBsb2dfaW5jZCksDQogICAgICAgICAgbW9kZWwubmFtZXMgID0gRiwNCiAgICAgICAgICBhZGQubGluZXMgPSBsaXN0KGMoJ01vZGVsIFR5cGUnLCAnTFBNJywgJ1Byb2JpdCAoVyknLCAnTG9naXQoVyknKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1BDUCcsICcnLCBwY3BfcHJvYmNbMV0sIHBjcF9sb2djWzFdKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1BDUCAoeT0wKScsICcnLCBwY3BfcHJvYmNbMl0sIHBjcF9sb2djWzJdKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1BDUCAoeT0xKScsICcnLCBwY3BfcHJvYmNbM10sIHBjcF9sb2djWzNdKSksDQogICAgICAgICAgdHlwZSA9ICd0ZXh0JykNCmBgYA0KDQpOb3csIEkgcHJlc2VudCBBUEVzIGZvciB0aGVzZSBtb2RlbHMuDQoNCmBgYHtyLCByZXN1bHRzID0gJ2FzaXMnLCBpbmNsdWRlID0gVH0NCm1vZGVsc3VtbWFyeShtZV9jb21wbGV4X2RpZGFsbCwgDQogICAgICAgICAgICAgb3V0cHV0ID0gJ21hcmtkb3duJywgDQogICAgICAgICAgICAgc3RhcnMgPSBjKCcqJyA9IC4xLCAnKionID0wLjA1LCAnKioqJz0gMC4wMSkpDQpgYGANCg0KVGhlIG1vc3QgaW1wb3J0YW50IGZpbmRpbmcgaXMgdGhhdCB0aGUgeWVhciBkdW1teSAoMjAxNikgaXMgbG9zdCwgbWVhbmluZyB0aGF0LCBvbmNlIGFjY291bnRpbmcgZm9yIGFsbCB0aGUgZmFjdG9ycyBpbmNsdWRlZCBpbiB0aGUgbW9kZWwsIG9ic2VydmF0aW9ucyBmcm9tIDIwMTYgYXJlIG5vdCBtb3JlIGxpa2VseSB0byBqdXN0aWZ5IGNvcnJ1cHRpb24uIEFnZSwgb25jZSBhZ2FpbiwgaXMgYSBuZWdhdGl2ZSBmYWN0b3Igb24gY29ycnVwdGlvbiB0b2xlcmFuY2U6IGEgcGVyc29uIHdoaWNoIGlzIG9sZGVyIHdpbGwgYmUgbGVzcyBsaWtlbHkgdG8ganVzdGlmeSBjb3JydXB0aW9uLg0KDQpJbnRlcmVzdCBpbiBwb2xpdGljcyBpcyBpbmRlZWQgc2lnbmlmaWNhbnQuIFRoZSBzaWduIG9uIGl0IG1lYW5zIHRoYXQgYSBwZXJzb24gd2l0aCBtb3JlIGludGVyZXN0IGluIHBvbGl0aWNzIGlzIHN1cHBvc2VkbHkgbGVzcyB0b2xlcmFudCBvZiBjb3JydXB0aW9uLCB3aGljaCBpcyBub3Qgd2hhdCB3YXMgcHJldmlvdXNseSBmb3VuZCBvdXQuDQoNCkdlbmRlciwgZWR1Y2F0aW9uLCB1cmJhbi9ydXJhbCBzZXR0aW5ncywgZXh0ZXJuYWwgcG9saXRpY2FsIGVmZmljaWVuY3ksIHBlcmNlcHRpb25zIG9mIGNvcnJ1cHRpb24gKHdoaWNoIGlzIG1hZGUgY29tcGFyYWJsZSBiZXR3ZWVuIDIwMTQgYW5kIDIwMTYpIHByb3ZlIHRvIG5vdCBiZSBzaWduaWZpY2FudCBmb3IganVzdGlmaWNhdGlvbiBvZiBicmliZXMuDQoNCk92ZXJhbGwsIHVuZW1wbG95bWVudCBzZWVtcyB0byBoYXZlIHRoZSBleHBlY3RlZCBlZmZlY3Q6IGEgcGVyc29uIHdoaWNoIGlzIHVuZW1wbG95ZWQgaXMgbW9yZSBsaWtlbHkgdG8ganVzdGlmeSBjb3JydXB0aW9uIHRoYW4gc29tZW9uZSBub3QgdW5lbXBsb3llZCAoaW5jbHVkaW5nIHRob3NlIHdoaWNoIGFyZSBub3QgaW4gdGhlIGxhYm9yIGZvcmNlKS4gSXRzIG92ZXJhbGwgZWZmZWN0LCBpbmNsdWRpbmcgaXRzIERpRCBlc3RpbWF0ZSBzaG93IHRoYXQgd2hpbGUgdGhlIHVuZW1wbG95ZWQgaXMgYWx3YXlzIG1vcmUgdG9sZXJhbnQgb2YgY29ycnVwdGlvbiwgdGhlIHVuZW1wbG95ZWQgaW4gMjAxNiBzZWVtZWQgdG8gYmUgbGVzcyBzbyBjb21wYXJlZCB0byAyMDE0Lg0KDQpUaGUgcG9saXRpY2FsIHNjb3JlIHdoaWNoIHJhbmtzIGluZGl2aWR1YWxzIGxlZnQgdG8gcmlnaHQgc2hvd3MgdGhhdCBvdmVyYWxsLCB0aGUgcGVvcGxlIHdobyBpZGVudGlmaWVkIG1vcmUgd2l0aCB0aGUgcmlnaHQgd2luZyB3ZXJlIG1vcmUgdG9sZXJhbnQgb2YgY29ycnVwdGlvbiwgYnV0IG9ubHkgc28gaW4gMjAxNiwgbm90IGluIDIwMTQuDQoNCkZpbmFsbHkgYW5kIHBlcmhhcHMgbW9zdCBpbXBvcnRhbnRseSwgdGhlIHBlb3BsZSB3aG8gdHJ1c3RlZCB0aGUgcHJlc2lkZW50IGluIGJvdGggeWVhcnMgd2VyZSBzaWduaWZpY2FudGx5IGxlc3MgbGlrZWx5IHRvIGp1c3RpZnkgY29ycnVwdGlvbi4gSG93ZXZlciwgaW4gMjAxNiB0aGV5IHdlcmUgc29tZXdoYXQgbGVzcyByZWplY3Rpbmcgb2YgY29ycnVwdGlvbiB0b2xlcmFuY2UgY29tcGFyZWQgdG8gMjAxNC4gVGhlIGp1bXAgaW4gY29ycnVwdGlvbiB0b2xlcmFuY2UgY291bGQgYmUgcGFydGlhbGx5IGV4cGxhaW5lZCBieSB0aGlzIGZhY3QsIGNvbnNpZGVyaW5nIHRoYXQgaW4gMjAxNiB0aGUgZHJvcCBpbiB0aGUgY29uZmlkZW5jZSB0byB0aGUgcHJlc2lkZW50IHdhcyBsYXJnZS4NCg0KU2FkbHksIHRoZSBQQ1AgZm9yIHRoZSBvdXRjb21lIG9mIGludGVyZXN0IGlzIHF1aXRlIGxvdy4gSSBob3BlIHRvIGltcHJvdmUgdGhpcyBhcyBJIGFkZCBtb3JlIHNpZ25pZmljYW50IHZhcmlhYmxlcyB0byB0aGUgbW9kZWwuDQoNCiMjIFRlc3Rpbmcgb3V0IG5ldyB2YXJpYWJsZXMNCg0KQmVsb3csIHdlIHRyeSBhZGRpbmcgbW9yZSB2YXJpYWJsZXMgdG8gdGhlIG1vZGVsIGFuZCBhbHNvIHRyeSBvdXQgc2ltcGxlciBvbmVzLiBGb3Igc2ltcGxpY2l0eSwgSSBvbmx5IHRha2UgaW50byBhY2NvdW50IHRoZSBsb2dpdCBtb2RlbHMgYmVsb3cuDQoNCiMjIyBSZWxpZ2lvbg0KDQpIdXJ0YWRvIHN1Z2dlc3RzIGJlaW5nIGNocmlzdGlhbiBtaWdodCBwcm9tb3RlIGluZHVzdHJpb3VzbmVzcywgd2hpY2ggaW4gYSB3YXkgbWF5IGhlbHAgcmVqZWN0IGNvcnJ1cHRpb24uIEkgYWRkIHJlbGlnaW91cyB2YXJpYWJsZXMgYXMgY2F0ZWdvcml6ZWQgYmVsb3c6DQoNCmBgYHtyIHJlbGdfY2xhc3MsIGV2YWwgPSBGfQ0KZGYkcmxnPC1pZmVsc2UoZGYkcTNjID09IDEsICdDYXRob2xpYycsDQogICAgICAgICAgICAgICBpZmVsc2UoZGYkcTNjID09IDIgfCBkZiRxM2MgPT0gNSwgJ0NocmlzdGlhbicsDQogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRmJHEzYyA9PSAzIHwgZGYkcTNjID09IDQgfCBkZiRxM2MgPT0gNzcsICdPdGhlcicsDQogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRmJHEzYyA9PSA2IHwgZGYkcTNjID09IDEyLCAnSlcvTU9SJywgJ0F0aGVpc3QnKSkpKQ0KYGBgDQoNCldoZXJlIGBKVy9NT1JgIG1lYW5zIHRob3NlIGNhdGVnb3JpemVkIGFzIEplaG92YSdzIFdpdG5lc3NlcyBhbmQgTW9ybW9ucy4NCg0KUHJlbGltaW5hcnkgcmVzdWx0cyBmb3IgdGhpcyByZWdyZXNzaW9uIGFyZSBwcmVzZW50ZWQgYmVsb3c6DQoNCmBgYHtyIHJsZ19ncm91cHN9DQpzdnlnbG0oY3RvbH4geWVhcioodW5lbTJfNGEgKyBwcmVzX2NvbmYgKyBwb2xzY29yZSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIA0KICAgICAgICAgICAgIGNvcnJwZXIgKyBybGcsIA0KICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpICU+JSBzdW1tYXJ5KCkNCg0KYGBgDQoNClRoZSBwb2xpdGljYWwgZWZmaWNhY3kgdmFyaWFibGUgZ2FpbnMgc29tZSBzaWduaWZpY2FuY2UgaGVyZSwgc3VnZ2VzdGluZyBhIGRvd253YXJkIGJpYXMuIEhvd2V2ZXIsIG5vIHJlbGlnaW91cyBncm91cCBzZWVtcyBzbyBmYXIgdG8gaGF2ZSBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgZnJvbSBhdGhlaXN0cy4gRm9yIG5vdyBIdXJ0YWRvJ3MgaHlwb3RoZXNpcyBkb2VzIG5vdCBzZWVtIHRvIGV4cGFuZCB0byBjb3JydXB0aW9uIHRvbGVyYW5jZS4gQmVsb3csIGEgc2ltcGxlIG1vZGVsIHVzaW5nIG9ubHkgdGhlIHllYXIgZHVtbXkgYW5kIHRoZSByZWxpZ2lvbiBncm91cHM6DQoNCmBgYHtyIHJsZ19ncm91cHNfc2ltcGxlfQ0Kc3Z5Z2xtKGN0b2x+IHllYXIgKyBybGcsIA0KICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQpBbHNvIG5vdCBzaWduaWZpY2FudCwgc28gbm90IGV2ZW4gYSBzcHVyaW91cyBjb3JyZWxhdGlvbiBpcyBmb3VuZC4gSXQgbWlnaHQgYmUgdGhhdCB0aGUgcmVsaWdpb3VzIGdyb3VwcyBhcmUgbm90IGltcG9ydGFudCBmb3IgY29ycnVwdGlvbiB0b2xlcmFuY2UuDQoNClRoZSBpbXBvcnRhbmNlIG9mIHJlbGlnaW9uIGluIHRoZSBpbmRpdmlkdWFsJ3MgbGlmZSBpcyBub3cgY29uc2lkZXJlZCBpbiB0aGUgY29tcGxleCBtb2RlbC4NCg0KIyMjIEVjb25vbWljIHZhcmlhYmxlcw0KDQpUaGUgZGF0YWJhc2VzIGF2YWlsYWJsZSBmb3IgZnJlZSBkbyBub3QgaW5jbHVkZSB0aGUgd2VhbHRoIHF1aW50aWxlcyBhbmFseXNpcywgd2hpY2ggZm9yY2VzIG1lIHRvIG9ubHkgY29uc2lkZXIgZWNvbm9taWMgc2l0dWF0aW9uIGFzIHRoZXkgYW5zd2VyIGl0Og0KDQoqKmlkaW8yIFF1ZXN0aW9uOioqICpEbyB5b3UgdGhpbmsgdGhhdCB5b3VyIGVjb25vbWljIHNpdHVhdGlvbiBpcyBiZXR0ZXIgdGhhbiwgdGhlIHNhbWUgYXMsIG9yIHdvcnNlIHRoYW4gaXQgd2FzIDEyIG1vbnRocyBhZ28/Kg0KDQpBcyBleHBlY3RlZCwgdGhpcyBxdWVzdGlvbiBzaG93cyBob3cgbXVzdCBvZiB0aGUgcGVvcGxlIGluIHRoZSAyMDE2IHNhbXBsZSByZXBvcnQgdGhhdCB0aGVpciBlY29ub21pYyBzaXR1YXRpb24gaXMgd29yc2UuIFRoZSBzYW1lIGlzIHNlZW4gZnJvbSBhIHF1ZXN0aW9uIGFza2luZyBzcGVjaWZpY2FsbHkgYWJvdXQgaW5jb21lLg0KDQpBZGRpbmcgdGhpcyB0byB0aGUgbW9kZWwsIHdlIGdldCB0aGUgZm9sbG93aW5nOg0KDQpgYGB7ciBlY25fY29tcGxleH0NCnN2eWdsbShjdG9sfiB5ZWFyKih1bmVtMl80YSArIHByZXNfY29uZiArIHBvbHNjb3JlKSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgDQogICAgICAgICAgICAgY29ycnBlciArIGVjb25fc2l0LCANCiAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgIGZhbWlseSA9IHF1YXNpYmlub21pYWwobGluayA9ICdsb2dpdCcpKSAlPiUgc3VtbWFyeSgpDQpgYGANCg0KIyMjIEV4cG9zdXJlIHRvIGNvcnJ1cHRpb24NCg0KTEFQT1BzIEFCIG9mdGVuIGluY2x1ZGVzIGNvcnJ1cHRpb24gInZpY3RpbWl6YXRpb24iIGluIGl0cyBlbXBpcmljYWwgYW5hbHlzZXMuIE15IG93biB2ZXJzaW9uIG9mIHRoaXMgdmFyaWFibGUgaXMgZXhwb3N1cmUgdG8gY29ycnVwdGlvbiwgd2hpY2ggd2lsbCBlcXVhbCAxIGlmIHRoZSBpbmRpdmlkdWFsIHJlcG9ydHMgaGF2aW5nIGJlZW4gb2ZmZXJlZCBvciBoYXZpbmcgcGFpZCBhIGJyaWJlIGluIGFueSBvZiB0aGUgc2V2ZXJhbCBxdWVzdGlvbnMgcmVnYXJkaW5nIGNvcnJ1cHRpb24gb24gdGhlIGRhdGFzZXQuIEF0IHRoaXMgbW9tZW50LCBvbmx5IDIwMTIgdGhydSAyMDE5IGhhdmUgbW9yZSBvciBsZXNzIHJlbGlhYmxlIGZpZ3VyZXMgZm9yIHRoaXMgbnVtYmVyLg0KDQpJbmNsdWRpbmcgdGhpcyB2YXJpYWJsZSBpbiB0aGUgbW9kZWxzIHlpZWxkcyB0aGUgZm9sbG93aW5nOg0KDQpgYGB7ciBjb3JyZXhwX2NvbXBsZXh9DQpjb3JyZXhwX2NvbXBsZXg8LXN2eWdsbShjdG9sfiB5ZWFyKih1bmVtMl80YSArIHByZXNfY29uZiArIHBvbHNjb3JlKSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCwgDQogICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpDQpzdW1tYXJ5KGNvcnJleHBfY29tcGxleCkNCmBgYA0KDQpJdCB3b3VsZCBzZWVtIHRoYXQgdGhpcyB2YXJpYWJsZSBpcyBxdWl0ZSBpbXBvcnRhbnQsIHNvIGl0IG11c3Qgc3RheSBpbiBtb2RlbHMuIEF2ZXJhZ2UgcGFydGlhbCBlZmZlY3RzIGJlbG93Lg0KDQpgYGB7ciBhcGVzX2NvcnJleHBfY29tcGxleCwgcmVzdWx0cyA9ICdhc2lzJ30NCm1lX2NvcnJleHBjPC1tYXJnaW5zKGNvcnJleHBfY29tcGxleCkNCm1vZGVsc3VtbWFyeShtZV9jb3JyZXhwYywgDQogICAgICAgICAgICAgb3V0cHV0ID0gJ2h0bWwnLCANCiAgICAgICAgICAgICBzdGFycz0gYygnKicgPSAuMSwgJyoqJyA9MC4wNSwgJyoqKic9IDAuMDEpKQ0KYGBgDQoNCiMjIyBQb2xpdGl6YXRpb24NCg0KUG9saXRpemF0aW9uLCBhcyBkZWZpbmVkIGJ5IHRoZSBMQVBPUCAyMDE5IHJlcG9ydCwgaW1wbGllcyB0aGF0IHRoZSBwZW9wbGUgaW5zaWRlIGEgY291bnRyeSBzdGFydCB0byBpZGVudGlmeSBtb3JlIHdpdGggcG9saXRpY2FsIHdpbmdzLiBUaGlzIG1lYW5zIGEgbG93ZXIgcGVyY2VudGFnZSBvZiBub24gcmVzcG9uc2VzIHRvIHRoZSBxdWVzdGlvbiB0aGF0IGFza3MgcGVvcGxlIHRvIGlkZW50aWZ5IHdpdGggYSBzY29yZSBpbiBhIHBvbGl0aWNhbCByYW5nZS4NCg0KVGhlcmUgaXMgYW4gaW1wb3J0YW50IGNoYW5nZSBpbiBwb2xpdGl6YXRpb24gYmV0d2VlbiAyMDE0IGFuZCAyMDE2LCBhcyBzdWdnZXN0ZWQgYnkgaXRzIHRpbWUgc2VyaWVzLiBCZWxvdyBJIGluY2x1ZGUgdGhpcyBkdW1teSBpbiB0aGUgbW9kZWwgcHJldmlvdXNseSBlc3RpbWF0ZWQuIEluIG9yZGVyIHRvIGdldCB0aGUgZXN0aW1hdGUsIGhvd2V2ZXIsIEkgbXVzdCBkcm9wIHRoZSBwb2xpdGljYWwgc2NvcmUgaW5kZXBlbmRlbnQgdmFyaWFibGUgZnJvbSB0aGUgbW9kZWwsIGFuZCBpbnRlcmFjdCB5ZWFyIHdpdGggdGhpcyBkdW1teSBpbnN0ZWFkLg0KDQpgYGB7ciBwbHR6dGlvbl9jb21wbGV4fQ0Kc3Z5Z2xtKGN0b2x+IHllYXIqKHVuZW0yXzRhICsgcHJlc19jb25mICsgcGxzY3JfbmEpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyANCiAgICAgICAgICAgICBjb3JycGVyICsgY29ycl9leHAsIA0KICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQpOb3QgcmVhbGx5IHNpZ25pZmljYW50LCB3ZSBsb3NlIG1vcmUgYnkgZGVsZXRpbmcgdGhlIHBvbGl0aWNhbCBzY29yZSB2YXJpYWJsZSB0aGFuIHdoYXQgd2UgZ2FpbiBmcm9tIGFkZGluZyB0aGUgcG9saXRpemF0aW9uIHZhcmlhYmxlLg0KDQojIyMgUG9saXRpY2FsIGdyb3VwcyByYXRoZXIgdGhhbiBzY29yZXMNCg0KSSByZXBsYWNlIHRoZSBwb2xpdGljYWwgc2NvcmUgdmFyaWFibGUgd2l0aCBwb2xpdGljYWwgZ3JvdXBzIGFzIGRlZmluZWQgaW4gdGhlIExBUE9QIHJlcG9ydC4NCg0KYGBge3IgcG9sZ3JvdXBfY29tcGxleH0NCnN2eWdsbShjdG9sfiB5ZWFyKih1bmVtMl80YSArIHByZXNfY29uZiArIHBvbF9ncm91cCkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIA0KICAgICAgICAgICAgIGNvcnJwZXIgKyBjb3JyX2V4cCwgDQogICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICBmYW1pbHkgPSBxdWFzaWJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkgJT4lIHN1bW1hcnkoKQ0KYGBgDQoNCkl0IGlzIHJhdGhlciB3ZWlyZCB0aGF0IHRoZSBpbnRlcmFjdGlvbnMgd2l0aCBhbGwgcG9saXRpY2FsIGdyb3VwcyBhbmQgdGhlIHllYXIgYXJlIG5vdCBzaWduaWZpY2FudC4gVHJ5IGFnYWluIHdpdGggYSByaWdodCB3aW5nIGR1bW15Lg0KDQpgYGB7ciBwb2xfd2luZ3JpZ2h0fQ0KDQpzdnlnbG0oY3RvbH4geWVhcioodW5lbTJfNGEgKyBwcmVzX2NvbmYgKyByd2luZykgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIA0KICAgICAgICAgICAgIGNvcnJwZXIgKyBjb3JyX2V4cCwgDQogICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICBmYW1pbHkgPSBxdWFzaWJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkgJT4lIHN1bW1hcnkoKQ0KYGBgDQoNClN0aWxsIG5vdCBzaWduaWZpY2FudC4gV2h5IG9ubHkgc2lnbmlmaWNhbnQgd2l0aCB0aGUgYWN0dWFsIHBvbGl0aWNhbCBzY29yZSB2YXJpYWJsZS4gTWlnaHQgdGhlcmUgYmUgYSBwcm9ibGVtIGluIGFzc3VtaW5nIGl0IGlzIGEgY29udGlub3VzIHByZWRpY3Rvcj8NCg0KIyMjIExhYm9yIE1hcmtldCBWYXJpYWJsZXMNCg0KSSByZXBsYWNlIHRoZSB1bmVtcGxveW1lbnQgZHVtbXkgdG8gaW5jbHVkZSBhIGZhY3RvciB3aXRoIDMgZ3JvdXBzOiBFbXBsb3llZCwgTm90IEVtcGxveWVkIGFuZCBub3QgaW4gdGhlIHdvcmtmb3JjZS4gTm90IGJlaW5nIGluIHRoZSB3b3JrZm9yY2UgaW1wbGllcyB0aGF0IHRoZSByZXNwb25kZW50IGlzIGVpdGhlciByZXRpcmVkLCB1bmFibGUgdG8gd29yayBpbiBzb21lIHdheSwgYSBzdHVkZW50IG9yIHdvcmtpbmcgdGhlIGhvbWUuDQoNCmBgYHtyIHdvcmsyX2NvbXBsZXh9DQpzdnlnbG0oY3RvbH4geWVhciood29ya18yYSArIHByZXNfY29uZiArIHBvbHNjb3JlKSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArICAgICAgICAgICAgY29ycl9leHAsIA0KICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQpSZXN1bHRzIHNlZW0gdG8gYmUgZXF1YWwgY29uc2lkZXJpbmcgcGVvcGxlIHdobyBhcmUgbm90IGluIHRoZSB3b3JrZm9yY2UuIEludGVyZXN0aW5nIHRvIGtub3cgdGhhdCBlbXBsb3llZCBwZW9wbGVzIGFuZCB0aG9zZSBub3QgaW4gdGhlIHdvcmtmb3JjZSBoYXZlIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGluIGNvcnJ1cHRpb24gdG9sZXJhbmNlLg0KDQpOb3cgSSBkbyB0aGUgc2FtZSBhbmFseXNpcywgYnV0IGFkZGluZyBvY2N1cGF0aW9uIGluIGVpdGhlciB0aGUgcHJpdmF0ZSBvciBwdWJsaWMgc2VjdG9yLiBJIHJlc3RvcmUgdGhlIHVuZW1wbG95bWVudCBkdW1teS4gSW4gdGhpcyBjb2RpZmljYXRpb24gdGhlIHZhcmlhYmxlIHdpbGwgbWVhbiAxIGlmIHRoZSBpbmRpdmlkdWFsIHdvcmtzIGluIHRoZSBwdWJsaWMgc2VjdG9yLCBhbmQgMCBpZiBoZSB3b3JrcyBpbiB0aGUgcHJpdmF0ZSBzZWN0b3IgYXMgZW1wbG95ZWUsIGEgc2VsZi1lbXBsb3llZCBvciBhbiBvd25lci9wYXJ0bmVyLiBOb3RlIHRoYXQgd2UgY2FuIG5vIGxvbmdlciBoYXZlIGEgZ2VuZXJhbCBsYWJvciBtYXJrZXQgRGlELg0KDQpgYGB7ciB3b3JrX3NlY19jfQ0Kc3Z5Z2xtKGN0b2x+IHllYXIqKHByaXZwdWIgKyBwcmVzX2NvbmYgKyBwb2xzY29yZSApICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgDQogICAgICAgY29ycl9leHAgLCANCiAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgIGZhbWlseSA9IHF1YXNpYmlub21pYWwobGluayA9ICdsb2dpdCcpKSAlPiUgc3VtbWFyeSgpDQpgYGANCg0KU2VlbXMgdG8gaGF2ZSBubyBlZmZlY3QuIE5vdyBjb25zaWRlciBkb2luZyB0aGUgc2FtZSBmb3IgYWxsIGZvdXIgc2VjdG9ycy4gRG9lc24ndCByZWFsbHkgbWF0dGVyIHdoaWNoIG9uZSBpcyB0aGUgYmFzZSBzZWN0b3IuDQoNCmBgYHtyIHdvcmtfc2VjMV9jfQ0Kc3Z5Z2xtKGN0b2x+IHllYXIqKG9jdXBfc2VjICsgcHJlc19jb25mICsgcG9sc2NvcmUpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgDQogICAgICAgY29ycl9leHAsIA0KICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQpUaGUgdW5wYWlkIHBhcnQgaGFzIHNpZ25pZmljYW50IGNoYW5nZXMsIGhvd2V2ZXIsIGl0IGlzIGEgdmVyeSBzbWFsbCBwYXJ0IG9mIHRoZSBzYW1wbGUuIENvbnNpZGVyaW5nIHRoZSBmb2xsb3dpbmcgdGFidWxhdGlvbjoNCg0KYGBge3IgdW5wYWlkX3RhYn0NCg0KdGFiX3VucGFpZDwtdGFibGUoZGY0NiR5ZWFyLCBkZjQ2JG9jdXBfc2VjKSAlPiUgcHJvcC50YWJsZShtYXJnaW4gPSAxKQ0KdGFiX3VucGFpZDwtdGFiX3VucGFpZFs2OjcsXSAqMTAwDQp0YWJfdW5wYWlkDQoNCmBgYA0KDQojIyMgU29jaW8tRGVtb2dyYXBoaWMNCg0KQ29uc2lkZXIgdGhlIG5ldyBzdXJ2ZXkgcmVzcG9uZGVudHMgaW4gMjAxNi4gVGhpcyBpcyBwZW9wbGUgd2hvIG9ubHkgbm93IGFyZSBhbnN3ZXJpbmcgdGhlIHN1cnZleSwgbWVhbmluZyBwZW9wbGUgd2l0aCAxNiBhbmQgMTcuIEFkZCBhIGR1bW15IHZhcmlhYmxlIGFuZCBhbiBpbnRlcmFjdGlvbiB3aXRoIHllYXIgdG8gdGhlIHJlZ3Jlc3Npb24gdG8gY29tcGFyZSBib3RoIGdyb3VwcyBvbiBib3RoIHllYXJzLiBJZiB0aGlzIHBvcHVsYXRpb24gdGhpbmsgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgZnJvbSB0aGUgcmVzdCwgdGhleSBjb3VsZCBiZSB0aGUgcmVhc29uIHdoeSBpbiAyMDE2IGNvcnJ1cHRpb24gdG9sZXJhbmNlIGdvZXMgdXAgYnkgc28gbXVjaC4NCg0KYGBge3IgbmV3LCB3YXJuaW5nID0gRn0NCm5ld19hZ2VfZGlkPC1zdnlnbG0oY3RvbH4geWVhcioodW5lbTJfNGEgKyBwcmVzX2NvbmYgKyBwb2xzY29yZSArIG5ldykgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgDQogICAgICAgICAgICAgICAgICAgIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgY29ycl9leHAsIA0KICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBxdWFzaWJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCnN1bW1hcnkobmV3X2FnZV9kaWQpDQpgYGANCg0KU2VlbXMgaW50ZXJlc3RpbmcsIHZlcnkgbGFyZ2UgbWFnbml0dWRlcyBidXQgc2VlbXMgdGhhdCBzZWVtIHRvIGNhbmNlbCBlYWNoIG90aGVyIG91dCwgd2hpY2ggbWVhbnMgdGhhdCBpbiAyMDE0IHVuZGVyIDE4IHJlc3BvbmRlbnRzIGRlZXBseSByZWplY3RlZCBjb3JydXB0aW9uLCBidXQgaW4gMjAxNiB0aGV5IHN0YXJ0ZWQgdG8ganVzdGlmeSBpdCBtdWNoIG1vcmUsIGxlYXZpbmcgYSBuZXQgZWZmZWN0IG9mIDAgZm9yIHVuZGVyIDE4IHJlc3BvbmRlbnRzIGZvciAyMDE2LiBDb21wdXRlIEFQRXM6DQoNCmBgYHtyIGFwZXNfbmV3LCByZXN1bHRzID0gJ2FzaXMnfQ0KDQphcGVfbmV3YWdlX2NvbXBsZXg8LW1hcmdpbnMobmV3X2FnZV9kaWQpDQoNCm1vZGVsc3VtbWFyeShhcGVfbmV3YWdlX2NvbXBsZXgsDQogICAgICAgICAgICAgb3V0cHV0ID0gJ2h0bWwnLA0KICAgICAgICAgICAgIHN0YXJzID0gYygnKicgPSAuMSwgJyoqJyA9MC4wNSwgJyoqKic9IDAuMDEpKQ0KYGBgDQoNClNpZ25pZmljYW50IG5lZ2F0aXZlIEFQRSBmb3IgbmV3IHJlc3BvbmRlbnRzLi4uIE5vdCBxdWl0ZSB3aGF0IHdvdWxkIGJlIGV4cGVjdGVkLiBOZWVkcyBmdXJ0aGVyIGFuYWx5c2lzLiBFc3RpbWF0ZSBhIERpRCBvbiBpdHMgb3duIGZvciB0aGlzIHZhcmlhYmxlOg0KDQpgYGB7ciBuZXdfYWdlX2RpZF9zZXB9DQpuZXdfYWdlX2RpZF9zPC1zdnlnbG0oY3RvbH4geWVhcipuZXcgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyANCiAgICAgICAgICAgICAgICAgICAgICBjb3JyX2V4cCArIHByZXNfY29uZiArIHBvbHNjb3JlICsgdW5lbTJfNGEsIA0KICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpDQpzdW1tYXJ5KG5ld19hZ2VfZGlkX3MpDQpgYGANCg0KTm90IHRvbyBkaWZmZXJlbnQgZnJvbSB3aGF0IHdlJ3ZlIHNlZW4gYmVmb3JlLiBBUEVzOg0KDQpgYGB7ciBuZXdfYWdlX2FwZSwgcmVzdWx0cyA9ICdhc2lzJ30NCg0KbWVfbmV3ZGlkX3M8LW1hcmdpbnMobmV3X2FnZV9kaWRfcykNCg0KbW9kZWxzdW1tYXJ5KG1lX25ld2RpZF9zLA0KICAgICAgICAgICAgIG91dHB1dCA9ICdodG1sJywNCiAgICAgICAgICAgICBzdGFycyA9IGMoJyonID0gLjEsICcqKicgPTAuMDUsICcqKionPSAwLjAxKSkNCg0KYGBgDQoNClNhbWUgdGhpbmcuIEVzdGltYXRlIGNyb3NzLXNlY3Rpb25hbCBtb2RlbHMgZm9yIHRoaXMgdmFyaWFibGUgYW5kIGNvbXBhcmUgdGhlIG5ldCBlZmZlY3RzLg0KDQpgYGB7ciBuZXdfYWdlX3llYXJjcm9zc30NCiMgMjAxNCBOZXcgQWdlIERpRA0KbmV3X2FnZV9kaWRfMTQ8LXN2eWdsbShjdG9sfiBuZXcgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyANCiAgICAgICAgICAgICAgICAgICAgICBjb3JyX2V4cCArIHByZXNfY29uZiArIHBvbHNjb3JlICsgdW5lbTJfNGEsIA0KICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0LA0KICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IHF1YXNpYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0Kc3VtbWFyeShuZXdfYWdlX2RpZF8xNCkNCg0KIyAyMDE2IE5ldyBBZ2UgRGlEDQoNCm5ld19hZ2VfZGlkXzE2PC1zdnlnbG0oY3RvbH4gbmV3ICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgDQogICAgICAgICAgICAgICAgICAgICAgY29ycl9leHAgKyBwcmVzX2NvbmYgKyBwb2xzY29yZSArIHVuZW0yXzRhLCANCiAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNiwNCiAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBxdWFzaWJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCnN1bW1hcnkobmV3X2FnZV9kaWRfMTQpDQoNCiMgQVBFcw0KDQphZ2VfZGlkX21lMTQ8LW1hcmdpbnMobmV3X2FnZV9kaWRfMTQpDQphZ2VfZGlkX21lMTY8LW1hcmdpbnMobmV3X2FnZV9kaWRfMTYpDQoNCmBgYA0KDQpDb21wYXJlIGJvdGggbW9kZWxzLCBzaWRlIGJ5IHNpZGU6DQoNCmBgYHtyIG5ld19hZ2VfZGlkX2Nyb3NzXzIsIHJlc3VsdHMgPSAnYXNpcyd9DQoNCnN0YXJnYXplcihuZXdfYWdlX2RpZF8xNCwgbmV3X2FnZV9kaWRfMTYsDQogICAgICAgICAgdHlwZSA9ICdodG1sJywNCiAgICAgICAgICBhZGQubGluZXMgPSBjKCdZZWFyJywgJzIwMTQnLCAnMjAxNicpKQ0KDQpgYGANCg0KTm93IHByZXNlbnQgQVBFczoNCg0KYGBge3IgbmV3X2FnZV9jcm9zc19hcGUsIHJlc3VsdHMgPSAnYXNpcyd9DQoNCm1vZGVsc3VtbWFyeShsaXN0KGFnZV9kaWRfbWUxNCwgYWdlX2RpZF9tZTE2KSwNCiAgICAgICAgICAgICBvdXRwdXQgPSAnbWFya2Rvd24nLA0KICAgICAgICAgICAgIHN0YXJzPSBjKCcqJyA9IC4xLCAnKionID0wLjA1LCAnKioqJz0gMC4wMSkpDQoNCmBgYA0KDQpUaGlzIG1pZ2h0IGhhdmUgbXVjaCB0byBkbyB3aXRoIHRoZSBmcmVxdWVuY3kgb2YgcGVvcGxlIHVuZGVyIDE4IGluIHRoZSBzYW1wbGVzLCBtdWNoIGxpa2UgdGhlIHVucGFpZCB3b3JrZXJzLiBDb25zaWRlciB0aGUgZm9sbG93aW5nIHRhYnVsYXRpb246DQoNCmBgYHtyIHRhYnVfbmV3X2FnZX0NCnRhYl9uZXdfYWdlPC10YWJsZShkZiR5ZWFyLCBkZiRuZXcpICU+JSBwcm9wLnRhYmxlKG1hcmdpbiA9IDEpDQp0YWJfbmV3X2FnZTwtdGFiX25ld19hZ2UgKjEwMCANCmBgYA0KDQpJbiAyMDE2IHRoZXJlIGlzIGFuIGluY3JlYXNlIG9mIGByIHJvdW5kKHRhYl9uZXdfYWdlWzcsMl0gLSB0YWJfbmV3X2FnZVs2LDJdLDIpYCBwZXJjZW50YWdlIHBvaW50cyBvZiB0aGUgdG90YWwgc2FtcGxlIHdobyBhcmUgdW5kZXJhZ2UgcmVzcG9uZGVudHMuIE1lYW5pbmcgdGhhdCBpbiAyMDE2IHRoZXJlIGFyZSBtb3JlIHlvdW5nIHBlb3BsZSBvdmVyYWxsLiBUaGlzIGluY3JlYXNlcyBldmVuIG1vcmUgZm9yIDIwMTkuDQoNCk5vdywgbGV0J3MgY2hlY2sgaG93IHRoaXMgcGVvcGxlIHJlc3BvbmQgdG8gdGhlIHN1cnZleS4NCg0KYGBge3IgbmV3X2FnZV9jdG9sfQ0KDQojIFN1YnNldCBkYXRhZnJhbWUgZm9yIHRoZSB1bmRlcmFnZSByZXNwb25kZW50cw0KDQpkZl9uZXc8LXN1YnNldChkZiwgZGYkbmV3ID09IDEpDQoNCiMgVGFidWxhdGUgYW5kIHNlZSB3aGF0IGFyZSB0aGUgJSdzIG9mIGNvcnJ1cHRpb24gdG9sZXJhbmNlDQoNCnRhYl9uZXdfY3RvbDwtdGFibGUoZGZfbmV3JHllYXIsIGRmX25ldyRjdG9sKSAlPiUgcHJvcC50YWJsZShtYXJnaW4gPSAxKQ0KdGFiX25ld19jdG9sDQoNCmBgYA0KDQpQcmV2aW91c2x5LCB0aGV5IGFsbCByZWplY3RlZCBjb3JydXB0aW9uLCBhbmQgbm93IGFib3V0IDMwJSBvZiB0aGVtIG5vdyBqdXN0aWZ5IGNvcnJ1cHRpb24sIHdoaWNoIGlzIGludHVpdGl2ZSBjb25zaWRlcmluZyB0aGUgc2lnbnMgb2YgdGhlIGludGVyYWN0aW9uIG9mIHRoaXMgdmFyaWFibGUgd2l0aCB5ZWFyLiBUaGlzLCBob3dldmVyLCBtYXkgbm90IG1lYW4gYSBjaGFuZ2UgaW4gdW5kZXJseWluZyBwdWJsaWMgb3Bpbmlvbi4gVGhlcmUgaXMgdG9vIGxpdHRsZSBkYXRhIHRvIGhhdmUgYSBzZW5zaWJsZSBjb25jbHVzaW9uLg0KDQojIyMgU2VwYXJhdGlvbiBvZiBEaURzDQoNCkkgc2VwYXJhdGUgZWFjaCBEaUQgd2l0aCB0aGUgY29tcGxleCBtb2RlbCB3aXRoIGNvcnJ1cHRpb24gZXhwb3N1cmUuDQoNCmBgYHtyIHNlcGFyYXRlZCBEaURzLCB3YXJuaW5nID0gRn0NCg0KIyBMb2dpdDogDQoNCiMgVW5lbXBsb3ltZW50DQoNCnVuZW1fZGlkX2xvZ19jPC1zdnlnbG0oY3RvbH4geWVhcioodW5lbTJfNGEpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgY29ycl9leHAgKyANCiAgICAgICAgICAgICAgICAgICAgICAgcG9sc2NvcmUgKyBwcmVzX2NvbmYsDQogICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCg0KIyBQb2xpdGljYWwgU2NvcmUNCg0KcG9sc19kaWRfbG9nX2M8LXN2eWdsbShjdG9sfiB5ZWFyKihwb2xzY29yZSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArIA0KICAgICAgICAgICAgICAgICAgICAgICB1bmVtMl80YSArIHByZXNfY29uZiwNCiAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0KDQojIFByZXNpZGVudGlhbCBDb25maWRlbmNlDQoNCnByZXNjX2RpZF9sb2dfYzwtc3Z5Z2xtKGN0b2x+IHllYXIqKHByZXNfY29uZikgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArDQogICAgICAgICAgICAgICAgICAgICAgICB1bmVtMl80YSArIHBvbHNjb3JlLA0KICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCg0KIyBQcm9iaXQ6IA0KDQojIFVuZW1wbG95bWVudA0KDQp1bmVtX2RpZF9wcm9iX2M8LXN2eWdsbShjdG9sfiB5ZWFyKih1bmVtMl80YSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArIA0KICAgICAgICAgICAgICAgICAgICAgICBwb2xzY29yZSArIHByZXNfY29uZiwNCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ3Byb2JpdCcpKQ0KDQojIFBvbGl0aWNhbCBTY29yZQ0KDQpwb2xzX2RpZF9wcm9iX2M8LXN2eWdsbShjdG9sfiB5ZWFyKihwb2xzY29yZSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArIA0KICAgICAgICAgICAgICAgICAgICAgICB1bmVtMl80YSArIHByZXNfY29uZiwNCiAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSkNCg0KIyBQcmVzaWRlbnRpYWwgQ29uZmlkZW5jZQ0KDQpwcmVzY19kaWRfcHJvYl9jPC1zdnlnbG0oY3RvbH4geWVhcioocHJlc19jb25mKSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArIGNvcnJfZXhwICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHVuZW0yXzRhICsgcG9sc2NvcmUsDQogICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdwcm9iaXQnKSkNCg0KIyBQQ1BTDQoNCnBjcF91bmVtY2w8LWhpdG1pc3ModW5lbV9kaWRfbG9nX2MpDQpwY3BfcG9sc2NsPC1oaXRtaXNzKHBvbHNfZGlkX2xvZ19jKQ0KcGNwX3Bjb25mY2w8LWhpdG1pc3MocHJlc2NfZGlkX2xvZ19jKQ0KcGNwX3VuZW1jcDwtaGl0bWlzcyh1bmVtX2RpZF9wcm9iX2MpDQpwY3BfcG9sc2NwPC1oaXRtaXNzKHBvbHNfZGlkX3Byb2JfYykNCnBjcF9wY29uZmNwPC1oaXRtaXNzKHByZXNjX2RpZF9wcm9iX2MpDQoNCmBgYA0KDQpQcmVzZW50IHRoZSBjb2VmZmljaWVudHMgYmVsb3c6DQoNCmBgYHtyIHN0YXJnYXplcl9kaWRfc2VwLCByZXN1bHRzID0gJ2FzaXMnfQ0Kc3RhcmdhemVyKGxpc3QodW5lbV9kaWRfbG9nX2MsIHBvbHNfZGlkX2xvZ19jLCBwcmVzY19kaWRfbG9nX2MpLA0KICAgICAgICAgIHR5cGUgPSAnaHRtbCcpDQpgYGANCg0KYGBge3Igc3RhcmdhemVyX2NvbXBsZXhfc2VwX3QsIGluY2x1ZGUgPSBGfQ0Kc3RhcmdhemVyKGxpc3QodW5lbV9kaWRfbG9nX2MsIHBvbHNfZGlkX2xvZ19jLCBwcmVzY19kaWRfbG9nX2MpLA0KICAgICAgICAgIHR5cGUgPSAndGV4dCcpDQoNCmBgYA0KDQpBUEVzIGVzdGltYXRlZCBiZWxvdzoNCg0KYGBge3IgYXBlc19kaWRfc2VwLCB3YXJuaW5nID0gRn0NCg0KIyBFc3RpbWF0ZSBBUEVTDQoNCm1lX3VuZW1jc19sPC1tYXJnaW5zKHVuZW1fZGlkX2xvZ19jKQ0KbWVfdW5lbWNzX3A8LW1hcmdpbnModW5lbV9kaWRfcHJvYl9jKQ0KDQptZV9wb2xzY3NfbDwtbWFyZ2lucyhwb2xzX2RpZF9sb2dfYykNCm1lX3BvbHNjc19wPC1tYXJnaW5zKHBvbHNfZGlkX3Byb2JfYykNCg0KbWVfcHJlc2NzX2w8LW1hcmdpbnMocHJlc2NfZGlkX2xvZ19jKQ0KbWVfcHJlc2NzX3A8LW1hcmdpbnMocHJlc2NfZGlkX3Byb2JfYykNCg0KIyBMaXN0IE1FcyBvZiBsb2dpdCBtb2RlbHMsIHRvIHNob3cgdGhlbSBsYXRlcjogDQoNCm1lc19zZXBhcmF0ZV9kaWRzPC1saXN0KG1lX3VuZW1jc19sLA0KICAgICAgICAgICAgICAgICAgICAgICAgbWVfcG9sc2NzX2wsIA0KICAgICAgICAgICAgICAgICAgICAgICAgbWVfcHJlc2NzX3ApDQoNCmBgYA0KDQpQcmVzZW50YXRpb24gb2YgQVBFcyBiZWxvdzoNCg0KYGBge3IgYXBlc19zZXBfZGlkLCByZXN1bHRzID0gJ2FzaXMnfQ0KbW9kZWxzdW1tYXJ5KG1lc19zZXBhcmF0ZV9kaWRzLA0KICAgICAgICAgICAgIG91dHB1dCA9ICdtYXJrZG93bicsDQogICAgICAgICAgICAgc3RhcnM9IGMoJyonID0gLjEsICcqKicgPTAuMDUsICcqKionPSAwLjAxKSkNCg0KYGBgDQoNCiMjIEh5cG90aGVzaXMgdGVzdGluZw0KDQojIyMgVW5lbXBsb3ltZW50DQoNCkkgd2FudCB0byB0ZXN0IGFuZCBrbm93IGFib3V0IHRoZSBuZXQgZWZmZWN0IG9mIHVuZW1wbG95bWVudCBpbiAyMDE2IHRvIGNvcnJ1cHRpb24gdG9sZXJhbmNlLiBGb3IgdGhhdCwgSSB3YW50IHRvIGZpcnN0IGRvIGEgam9pbnQgaHlwb3RoZXNpcyB0ZXN0IG9mIHRoZSBpbnRlcmFjdGlvbiBjb2VmZmljaWVudCB3aXRoIHVuZW1wbG95bWVudCBhbmQgeWVhciwgYXMgd2VsbCBhcyB0aGUgc29sZSB1bmVtcGxveW1lbnQgY29lZmZpY2llbnQuIE11c3QgcGVyZm9ybSBhIFdhbGR0IHRlc3QsIHdoaWNoIGlzIHRoZSBvbmx5IHRlc3QgdGhhdCB3b3JrcyBpbiBzdXJ2ZXlzLg0KDQpgYGB7ciB3YWxkX3VuZW19DQp0ZXJtc191bmVtPC1jKCd1bmVtMl80YScsICd5ZWFyMjAxNjp1bmVtMl80YScpDQoNCnJlZ1Rlcm1UZXN0KHVuZW1fZGlkX2xvZ19jLCB0ZXJtc191bmVtLCBtZXRob2QgPSAnV2FsZCcpDQoNCmBgYA0KDQpJdCBpcyB0aHVzIGNvbmZpcm1lZCB0aGF0IHVuZW1wbG95bWVudCBpcyBpbXBvcnRhbnQgZm9yIGNvcnJ1cHRpb24gdG9sZXJhbmNlLiBUaGUgZmFjdCB0aGF0IHRoZSBpbnRlcmFjdGlvbiB0ZXJtIGlzIHNpZ25pZmljYW50IG1lYW5zIHRoYXQgdGhlcmUgaXMgaW5kZWVkIGEgZGlmZmVyZW5jZSBpbiBzbG9wZXMgYWNyb3NzIHRpbWUgZm9yIHVuZW1wbG95ZWQgd29ya2Vycy4NCg0KTm93LCBtdXN0IGNoZWNrIGlmIHRoZSB0b3RhbCBlZmZlY3QgZm9yIHVuZW1wbG95bWVudCBpbiAyMDE2IGlzIHNpZ25pZmljYW50LiBJIHdpbGwgcnVuIHR3byBkaWZmZXJlbnQgbW9kZWxzIHdpdGggdGhlIGludGVyYWN0aW9uIHRlcm0sIG9uZSBmb3IgZWFjaCB5ZWFyIGFuZCBjb21wYXJlIGNvZWZmaWNpZW50cy4NCg0KYGBge3IgdW5lbV9jcm9zc19zZWN0aW9uLCByZXN1bHRzID0gJ2FzaXMnfQ0KDQojIDIwMTQgDQp1bmVtX2RpZF9sb2dfMTQ8LXN2eWdsbShjdG9sIH4gdW5lbTJfNGEgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArIA0KICAgICAgICAgICAgICAgICAgICAgICBwb2xzY29yZSArIHByZXNfY29uZiwNCiAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQsDQogICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkNCiMgMjAxNiANCnVuZW1fZGlkX2xvZ18xNjwtc3Z5Z2xtKGN0b2wgfiB1bmVtMl80YSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArIGNvcnJfZXhwICsgDQogICAgICAgICAgICAgICAgICAgICAgIHBvbHNjb3JlICsgcHJlc19jb25mLA0KICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0KDQpzdGFyZ2F6ZXIodW5lbV9kaWRfbG9nXzE0LCB1bmVtX2RpZF9sb2dfMTYsDQogICAgICAgICAgdHlwZSA9ICd0ZXh0JywNCiAgICAgICAgICBhZGQubGluZXMgPSBsaXN0KGMoJ1llYXInLCAnMjAxNCcsJzIwMTYnKSkpDQoNCmBgYA0KDQpUaGUgbmV0IGVmZmVjdCBmb3IgdW5lbXBsb3ltZW50IGlzIG51bGwsIHRodXMgaW4gMjAxNiB1bmVtcGxveWVkIHBlb3BsZSByZWplY3RlZCBjb3JydXB0aW9uIGxlc3MgdGhhbiB0aG9zZSBpbiAyMDE0LiBEb2VzIG5vdCBzdWNjZXNzZnVsbHkgZXhwbGFpbiB0aGUganVtcCBpbiBjb3JydXB0aW9uIHRvbGVyYW5jZS4gUHJlc2VudCB0aGUgQVBFcyBiZWxvdzoNCg0KYGBge3IgdW5lbV9jcm9zc19hcGVzLCByZXN1bHRzID0gJ2FzaXMnfQ0KDQptZV91bmVtMjAxNDwtbWFyZ2lucyh1bmVtX2RpZF9sb2dfMTQpDQptZV91bmVtMjAxNjwtbWFyZ2lucyh1bmVtX2RpZF9sb2dfMTYpDQoNCm1lX3VuZW1jcm9zczwtbGlzdChtZV91bmVtMjAxNCwNCiAgICAgICAgICAgICAgICAgICBtZV91bmVtMjAxNikNCg0KbW9kZWxzdW1tYXJ5KG1lX3VuZW1jcm9zcywNCiAgICAgICAgICAgICBvdXRwdXQgPSAnaHRtbCcsDQogICAgICAgICAgICAgc3RhcnM9IGMoJyonID0gLjEsICcqKicgPTAuMDUsICcqKionPSAwLjAxKSkNCg0KYGBgDQoNCiMjIyBQb2xpdGljYWwgV2luZyBTY29yZQ0KDQpJIHJlcGVhdCB0aGUgc2FtZSBhbmFseXNpcywgYnV0IG5vdyBmb3IgdGhlIGBwb2xzY29yZWAgdmFyaWFibGUuDQoNCmBgYHtyIHdhbGRfcG9sc2NvcmV9DQp0ZXJtc19wb2xzY29yZTwtYygncG9sc2NvcmUnLCAneWVhcjIwMTY6cG9sc2NvcmUnKQ0KDQpyZWdUZXJtVGVzdChwb2xzX2RpZF9sb2dfYywgdGVybXNfdW5lbSwgbWV0aG9kID0gJ1dhbGQnKQ0KDQpgYGANCg0KSXQgaXMgcG9zc2libGUgdGhhdCBwb2xpdGljYWwgc2NvcmUgaW4gYSBtb2RlbCB3aXRoIHNvbGVseSB0aGUgcG9saXRpY2FsIHNjb3JlIGFzIG91ciBEaUQsIGlzIG5vdCBzaWduaWZpY2FudCBhdCBhbGwgdG8gY29ycnVwdGlvbiBqdXN0aWZpY2F0aW9uLiBIb3dldmVyLCBpbiB0aGUgY29tcGxleCBtb2RlbCB0aGF0IGRvZXMgaW5jbHVkZSBhbGwgdmFyaWFibGVzLCB3ZSBtYXkgbm90IHNlZSB0aGUgc2FtZSB0aGluZy4gVGVzdDoNCg0KYGBge3Igd2FsZF9wb2xzY29yZV9hbGx9DQpyZWdUZXJtVGVzdChsb2dfaW5jZCwgdGVybXNfcG9sc2NvcmUsIG1ldGhvZCA9ICdXYWxkJykNCmBgYA0KDQpUaGUgc2FtZSwgaG93ZXZlciBvdXIgV2FsZCB0ZXN0IGlzIHNsaWdodGx5IGxhcmdlciBpbiB0aGlzIGNhc2UuIFN0aWxsIGNvdWxkIGJlIGJpYXNlZCB0b3dhcmQgemVybyBmcm9tIG9taXR0ZWQgdmFyaWFibGVzLg0KDQpUcnkgdG8gdGVzdCB0aGUgbmV0IGVmZmVjdCBjb21wYXJpbmcgdGhlIGNyb3NzLXNlY3Rpb25hbCByZWdyZXNzaW9ucywgYXMgc2VlbiBpbiB0aGUgcHJldmlvdXMgY29kZSBjaHVuay4gSW50ZXJlc3RpbmdseSwgaW4gMjAxNiB0aGlzIGVmZmVjdCBpcyBzaWduaWZpY2FudCwgd2hpY2ggZG9lcywgaW4gYSB3YXksIGV4cGxhaW4gdGhlIGNvcnJ1cHRpb24gdG9sZXJhbmNlIGp1bXAuIElmIHBlb3BsZSB0aGF0IGlkZW50aWZ5IGFzIG1vcmUgcmlnaHQtd2luZ2VycyBzdGFydCBqdXN0aWZ5aW5nIGNvcnJ1cHRpb24gbW9yZSwgYW5kIHRoZSBhbW91bnQgb2YgcGVvcGxlIGxpa2UgdGhpcyBzdGFydHMgdG8gaW5jcmVhc2UsIHRoZSBoeXBvdGhldGljYWwganVtcCBpcyBleHBsYWluZWQuDQoNCk5vdyB0cnkgd2l0aCBwb2xpdGljYWwgZ3JvdXBzLiBUaGUgYmFzZSBpcyB0aGUgY2VudGVyLg0KDQpgYGB7ciBwb2xzX2RpZHNfZ3JvdXB9DQoNCnBvbHNfZGlzX2dyb3VwPC1zdnlnbG0oY3RvbH4geWVhcioocG9sX2dyb3VwKSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArIGNvcnJfZXhwICAgICAgICAgICAgICAgICAgICAgICAgICArIHVuZW0yXzRhICsgcHJlc19jb25mLCANCiAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpDQpwb2xzX2Rpc19ncm91cCAlPiUgc3VtbWFyeSgpDQoNCmBgYA0KDQpObyBzaWduaWZpY2FuY2UuIEl0IGlzIHZlcnkgdW5zdGFibGUuIFJ1biByZWdyZXNzaW9ucyBsaWtlIHRoZXNlIGZvciBib3RoIHllYXJzLg0KDQpgYGB7ciBwb2xzX2RpZHNfZ3JvdXBfY3Jvc3MsIHJlc3VsdHMgPSAnYXNpcyd9DQoNCnBvbHNfZGlzX2dyb3VwMTQ8LXN2eWdsbShjdG9sIH4gcG9sX2dyb3VwICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29ycl9leHAgKyB1bmVtMl80YSArIHByZXNfY29uZiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQsDQogICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gcXVhc2liaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpDQoNCnBvbHNfZGlzX2dyb3VwMTY8LXN2eWdsbShjdG9sIH4gIHBvbF9ncm91cCArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJfZXhwICsgdW5lbTJfNGEgKyBwcmVzX2NvbmYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IHF1YXNpYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0KDQpzdGFyZ2F6ZXIocG9sc19kaXNfZ3JvdXAxNCwgcG9sc19kaXNfZ3JvdXAxNiwNCiAgICAgICAgICB0eXBlID0gJ3RleHQnLA0KICAgICAgICAgIGFkZC5saW5lcyA9IGxpc3QoYygnWWVhcicsICcyMDE0JywnMjAxNicpKSkNCmBgYA0KDQpUaGVyZSBvbmx5IHNlZW1zIHRvIGJlIHNvbWUgbWFyZ2luYWwgc2lnbmlmaWNhbmNlIGZvciBsZWZ0aXN0czogdGhleSBqdXN0aWZpZWQgY29ycnVwdGlvbiBsZXNzIGluIDIwMTYsIHdoaWNoIGNvdWxkIGV4cGxhaW4gdGhlIGp1bXAgc2luY2UgdGhlcmUgd2VyZSBsZXNzIGxlZnRpc3RzLiBBUEVTIGJlbG93Og0KDQpgYGB7ciBwb2xzX2dyb3VwX2Nyb3NzX2FwZXMsIHJlc3VsdHMgPSAnYXNpcyd9DQoNCm1lX3BvbHNncm91cDE0PC1tYXJnaW5zKHBvbHNfZGlzX2dyb3VwMTQpDQptZV9wb2xzZ3JvdXAxNjwtbWFyZ2lucyhwb2xzX2Rpc19ncm91cDE2KQ0KDQptZV9wb2xzZ3JvdXBzPC1saXN0KG1lX3BvbHNncm91cDE0LA0KICAgICAgICAgICAgICAgICAgICBtZV9wb2xzZ3JvdXAxNikNCg0KbW9kZWxzdW1tYXJ5KG1lX3BvbHNncm91cHMsDQogICAgICAgICAgICAgb3V0cHV0ID0gJ2h0bWwnLA0KICAgICAgICAgICAgIHN0YXJzPSBjKCcqJyA9IC4xLCAnKionID0wLjA1LCAnKioqJz0gMC4wMSkpDQoNCmBgYA0KDQojIyMjIENvbmZpZGVuY2UgaW4gdGhlIHByZXNpZGVudA0KDQpEbyB0aGUgc2FtZSBmb3IgdGhlIGBwcmVzX2NvbmZgIHZhcmlhYmxlLg0KDQpgYGB7ciB3YWxkX3ByZXNfY29uZl9hbGx9DQp0ZXJtc19wY29uZjwtYygncHJlc19jb25mJywgJ3llYXIyMDE2OnByZXNfY29uZicpDQoNCnJlZ1Rlcm1UZXN0KHByZXNjX2RpZF9sb2dfYywgdGVybXNfcGNvbmYsIG1ldGhvZCA9ICdXYWxkJykNCg0KYGBgDQoNClRoZSBkaWZmZXJlbnQgY3Jvc3Mgc2VjdGlvbnMgc2hvdyB0aGF0IHBlb3BsZSB3aG8gY29uZmlkZWQgaW4gdGhlIHByZXNpZGVudCBvbmx5IHJlamVjdGVkIGNvcnJ1cHRpb24gaW4gMjAxNC4gQmVnaW5uaW5nIDIwMTYsIHRoZXkgc3RvcHBlZCBhY3Rpbmcgc28gemVhbG91cy4gVGhpcyBhbHNvIGp1c3RpZmllcyBjb3JydXB0aW9uIHRvbGVyYW5jZS4NCg0KIyMgTmV3IHZhcmlhYmxlcyB3aXRoIHNlcGFyYXRlIERpRHMNCg0KIyMjIEFwcHJvdmFsIFJhdGluZyAoUHJlc2lkZW50KQ0KDQpJIHdpbGwgbm93IGNvbnNpZGVyIHRoZSBqb2IgYXBwcm92YWwgcmF0aW5ncyBvZiB0aGUgcHJlc2lkZW50IGFjcm9zcyB0aW1lLiBGaXJzdCwgSSdsbCB0ZXN0IGZvciB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGlzIGFuZCBjb25maWRlbmNlIGluIHRoZSBwcmVzaWRlbnQgYW5kIHRoZSBwb2xpdGljYWwgc2NvcmUgdmFyaWFibGUNCg0KYGBge3IgY29ycl9wcmVzX2NvbmZhcH0NCg0KY29yKGRmNDYkcHJlc19hcHJvdiwgZGY0NiRwcmVzX2NvbmYsIHVzZSA9ICdjb21wbGV0ZS5vYnMnKQ0KY29yKGRmNDYkcHJlc19hcHJvdiwgZGY0NiRwb2xzY29yZSwgdXNlID0gJ2NvbXBsZXRlLm9icycpDQpjb3IoZGY0NiRwcmVzX2NvbmYsIGRmNDYkcG9sc2NvcmUsIHVzZSA9ICdjb21wbGV0ZS5vYnMnKQ0KDQpgYGANCg0KVGhlcmUgaXMgaW5kZWVkIGEgaGlnaCBjb3JyZWxhdGlvbiwgYnV0IG5vdCBwZXJmZWN0IHdpdGggY29uZmlkZW5jZSBpbiB0aGUgcHJlc2lkZW50LiBJbnRlcmVzdGluZyB0byBzZWUgdGhhdCBwb2xpdGljYWwgc2NvcmUgZG9lcyBub3QgbWVhbiBhcHByb3ZhbCB3aXRoIHRoZSBwcmVzaWRlbnQuDQoNCkl0IHdpbGwgcHJvYmFibHkgaW5kdWNlIGEgbG90IG11bHRpY29sbGluZWFyaXR5IHRvIGluY2x1ZGUgYm90aCBjb25maWRlbmNlIGluIHRoZSBwcmVzaWRlbnQgYW5kIGFwcHJvdmFsIG9mIHRoZSBwcmVzaWRlbnQncyBqb2IgcGVyZm9ybWFuY2UuIEJlbG93LCBob3dldmVyLCB3ZSB0cnkgdG8gZG8gc28uDQoNCmBgYHtyIHByZXNfYXByb3YsIHdhcm5pbmcgPSBGfQ0KDQojIExvZ2l0OiANCg0KIyBVbmVtcGxveW1lbnQNCg0KdW5lbV9kaWRfbG9nX2MyPC1zdnlnbG0oY3RvbH4geWVhcioodW5lbTJfNGEpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgY29ycl9leHAgKyANCiAgICAgICAgICAgICAgICAgICAgICAgcG9sc2NvcmUgKyBwcmVzX2NvbmYgKyBwcmVzX2Fwcm92LA0KICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpDQoNCiMgUG9saXRpY2FsIFNjb3JlDQoNCnBvbHNfZGlkX2xvZ19jMjwtc3Z5Z2xtKGN0b2x+IHllYXIqKHBvbHNjb3JlKSArIGFnZSArIGduZHIgKyBlZCArIHVyICsgZWZmMSArIGVmZjIgKyBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArIGNvcnJfZXhwICsgDQogICAgICAgICAgICAgICAgICAgICAgIHVuZW0yXzRhICsgcHJlc19jb25mICsgcHJlc19hcHJvdiwNCiAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0KDQojIFByZXNpZGVudGlhbCBDb25maWRlbmNlDQoNCnByZXNjX2RpZF9sb2dfYzI8LXN2eWdsbShjdG9sfiB5ZWFyKihwcmVzX2NvbmYpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgY29ycl9leHAgKw0KICAgICAgICAgICAgICAgICAgICAgICAgdW5lbTJfNGEgKyBwb2xzY29yZSArIHByZXNfYXByb3YsDQogICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQ0KDQojIFByb2JpdDogDQoNCiMgVW5lbXBsb3ltZW50DQoNCnVuZW1fZGlkX3Byb2JfYzI8LXN2eWdsbShjdG9sfiB5ZWFyKih1bmVtMl80YSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArIA0KICAgICAgICAgICAgICAgICAgICAgICAgcG9sc2NvcmUgKyBwcmVzX2NvbmYgKyBwcmVzX2Fwcm92LA0KICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAncHJvYml0JykpDQoNCiMgUG9saXRpY2FsIFNjb3JlDQoNCnBvbHNfZGlkX3Byb2JfYzI8LXN2eWdsbShjdG9sfiB5ZWFyKihwb2xzY29yZSkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyBjb3JyX2V4cCArIA0KICAgICAgICAgICAgICAgICAgICAgICB1bmVtMl80YSArIHByZXNfY29uZiArIHByZXNfYXByb3YsDQogICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAncHJvYml0JykpDQoNCiMgUHJlc2lkZW50aWFsIENvbmZpZGVuY2UNCg0KcHJlc2NfZGlkX3Byb2JfYzI8LXN2eWdsbShjdG9sfiB5ZWFyKihwcmVzX2NvbmYpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29ycl9leHAgKyB1bmVtMl80YSArIHBvbHNjb3JlICsgcHJlc19hcHJvdiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSBhYl9kZXNfZWMxNDE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAncHJvYml0JykpDQoNCiMgTWFrZSBhIGxpc3Qgb2YgdGhlIGxvZ2l0IG1vZGVscw0KDQpsb2dpdF9jb21wbGV4Ml9zZXBkaWQ8LQ0KICBsaXN0KHVuZW1fZGlkX2xvZ19jMiwNCiAgICAgICBwb2xzX2RpZF9sb2dfYzIsDQogICAgICAgcHJlc2NfZGlkX2xvZ19jMikNCg0KIyBQQ1BTDQoNCnBjcF91bmVtY2wyPC1oaXRtaXNzKHVuZW1fZGlkX2xvZ19jMikNCnBjcF9wb2xzY2wyPC1oaXRtaXNzKHBvbHNfZGlkX2xvZ19jMikNCnBjcF9wY29uZmNsMjwtaGl0bWlzcyhwcmVzY19kaWRfbG9nX2MyKQ0KcGNwX3VuZW1jcDI8LWhpdG1pc3ModW5lbV9kaWRfcHJvYl9jMikNCnBjcF9wb2xzY3AyPC1oaXRtaXNzKHBvbHNfZGlkX3Byb2JfYzIpDQpwY3BfcGNvbmZjcDI8LWhpdG1pc3MocHJlc2NfZGlkX3Byb2JfYzIpDQoNCg0KYGBgDQoNCmBgYHtyIHByZXNlbnRfY29lZnNfYzJ9DQoNCnN0YXJnYXplcihsb2dpdF9jb21wbGV4Ml9zZXBkaWQsDQogICAgICAgICAgdHlwZSA9ICd0ZXh0Jw0KICAgICAgICAgICkNCg0KYGBgDQoNCkl0IGRvZXMgbm90aGluZyB0byB0aGUgbW9kZWxzLiBUcnkgYW4gaW50ZXJhY3Rpb24gd2l0aCB5ZWFyLCBhIHNvbGUgRGlEIG1vZGVsLg0KDQpgYGB7ciBkaWRfc29sZV9wYXByb3YsIHdhcm5pbmcgPSBGfQ0KDQphcHJvdl9kaWRfbG9nZGlkPC1zdnlnbG0oY3RvbH4geWVhcioocHJlc19hcHJvdikgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgcHJvdDMgKyBwaW50X2RpYyArIGNvcnJwZXIgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyX2V4cCArIHVuZW0yXzRhICsgcHJlc19jb25mICsgcG9sc2NvcmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ3Byb2JpdCcpKSANCnN1bW1hcnkoYXByb3ZfZGlkX2xvZ2RpZCkNCg0KYGBgDQoNCkl0IGRvZXMgd29yayBhcyBhIERpRCBvbiBpdHMgb3duLCBpbiBhIHNpbWlsYXIgd2F5IHRoYXQgdGhlIGNvbmZpZGVuY2UgRGlEIHdvcmtzLiBUcnkgam9pbmluZyBib3RoLCBhbmQgcmVwbGFjaW5nIHByZXNpZGVudGlhbCBqb2IgYXBwcm92YWwgd2l0aA0KDQpgYGB7ciBkaWRfYm90aF9jb25mYXByb3YsIHdhcm5pbmcgPSBGfQ0KDQphcHJvdl9kaWRiX2xvZ2RpZDwtc3Z5Z2xtKGN0b2x+IHllYXIqKHByZXNfYXByb3YgKyBwcmVzX2NvbmYpICsgYWdlICsgZ25kciArIGVkICsgdXIgKyBlZmYxICsgZWZmMiArIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90MyArIHBpbnRfZGljICsgY29ycnBlciArIGNvcnJfZXhwICsgdW5lbTJfNGEgICsgcG9sc2NvcmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IGFiX2Rlc19lYzE0MTYsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSkgDQoNCg0KYXByb3ZfZGlkX2xvZ2RpZF9ub2NvbmY8LXN2eWdsbShjdG9sfiB5ZWFyKihwcmVzX2Fwcm92ICkgKyBhZ2UgKyBnbmRyICsgZWQgKyB1ciArIGVmZjEgKyBlZmYyICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3QzICsgcGludF9kaWMgKyBjb3JycGVyICsgY29ycl9leHAgKyB1bmVtMl80YSAgKyBwb2xzY29yZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gYWJfZGVzX2VjMTQxNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKSANCg0KaGl0bWlzcyhhcHJvdl9kaWRiX2xvZ2RpZCkNCmhpdG1pc3MoYXByb3ZfZGlkX2xvZ2RpZF9ub2NvbmYpDQoNCnN0YXJnYXplcihhcHJvdl9kaWRiX2xvZ2RpZCwgYXByb3ZfZGlkX2xvZ2RpZF9ub2NvbmYsDQogICAgICAgICAgdHlwZSA9ICd0ZXh0JykNCg0KYGBgDQoNCkNvbXB1dGUgQVBFUyBmb3IgYWxsIG9mIHRoZXNlIG1vZGVscywgYW5kIHRoZW4gY29tcGFyZS4NCg0KYGBge3IgbWVzX2Fwcm92YWxtb2RlbHN9DQoNCmFwZV9kaWR1X2Fwcm92PC1tYXJnaW5zKHVuZW1fZGlkX2xvZ19jMikNCmFwZV9kaWRwX2Fwcm92PC1tYXJnaW5zKHBvbHNfZGlkX2xvZ19jMikNCmFwZV9kaWRjX2Fwcm92PC1tYXJnaW5zKHByZXNjX2RpZF9sb2dfYzIpDQphcGVfYXByb3ZfZGlkPC1tYXJnaW5zKGFwcm92X2RpZF9sb2dkaWQpDQphcGVfYXByb3ZfZGlkYjwtbWFyZ2lucyhhcHJvdl9kaWRiX2xvZ2RpZCkNCmFwZV9hcHJvdl9kaWRzPC1tYXJnaW5zKGFwcm92X2RpZF9sb2dkaWRfbm9jb25mKQ0KDQphcGVzX2RpZF9hcHJvdjwtDQogIGxpc3QoYXBlX2RpZHVfYXByb3YsDQogICAgICAgYXBlX2RpZHBfYXByb3YsDQogICAgICAgYXBlX2RpZGNfYXByb3YsDQogICAgICAgYXBlX2Fwcm92X2RpZCwNCiAgICAgICBhcGVfYXByb3ZfZGlkYiwNCiAgICAgICBhcGVfYXByb3ZfZGlkcykNCg0KbW9kZWxzdW1tYXJ5KGFwZXNfZGlkX2Fwcm92LCANCiAgICAgICAgICAgICBvdXRwdXQgPSAnbWFya2Rvd24nLA0KICAgICAgICAgICAgIHN0YXJzID0gYygnKicgPSAuMSwgJyoqJyA9MC4wNSwgJyoqKic9IDAuMDEpKQ0KDQoNCmBgYA==