1. Define a binary outcome variable of your choosing and define how you recode the original variable.
Proposed topic: Advserse health conditions associated with opportunity youths
Outcome variabels: Health conditions such Health status, depression, anxiety, smoking etc. The purpose of this assignment I would focus on self rated health status
2 State a research question about what factors you believe will affect your outcome variable.
Qst: Is Opportunity youth status associated with Fair/Poor Health status?
Define at least 2 predictor variables, based on your research question
– Opportunity youth status – Gender – Urban-rural status – Racial ethnicity
fit1<-lm(badhealth~opportunity_youth_cat+urban_rural,
data=data)
fit2<-lm(badhealth~opportunity_youth_cat+urban_rural,
data=data,
weights = sampweight)
fit3<-svyglm(badhealth~opportunity_youth_cat+urban_rural,
design = des,
family=gaussian)
stargazer(fit1, fit2, fit3,
style="demography", type="html",
column.labels = c("OLS", "Weights Only", "Survey Design"),
title = "Regression models for Self rated health using survey data - IPUMS Health survey",
covariate.labels=c("Opportunity youth", "Not opportunity youth", "urban", "rural"),
keep.stat="n",
model.names=F,
align=T,
ci=T)
Regression models for Self rated health using survey data - IPUMS Health survey
|
|
badhealth
|
|
OLS
|
Weights Only
|
Survey Design
|
|
Model 1
|
Model 2
|
Model 3
|
|
Opportunity youth
|
-0.077***
|
-0.060***
|
-0.060***
|
|
(-0.101, -0.054)
|
(-0.081, -0.039)
|
(-0.093, -0.026)
|
Not opportunity youth
|
-0.026*
|
-0.030**
|
-0.030
|
|
(-0.047, -0.004)
|
(-0.052, -0.008)
|
(-0.060, 0.001)
|
urban
|
0.146***
|
0.129***
|
0.129***
|
|
(0.117, 0.175)
|
(0.102, 0.156)
|
(0.089, 0.169)
|
N
|
3,771
|
3,771
|
3,771
|
|
p < .05; p < .01; p < .001
|
library(ggplot2)
library(dplyr)
coefs<-data.frame(coefs=c(coef(fit1)[-1], coef(fit3)[-1]),
mod=c(rep("Non Survey Model", 8),rep("Survey Model", 8)),
effect=rep(names(coef(fit1)[-1]), 2))
coefs%>%
ggplot()+
geom_point(aes( x=effect,
y=coefs,
group=effect,
color=effect,
shape=mod),
position=position_jitterdodge(jitter.width = 1),
size=2)+
ylab("Regression Coefficient")+
xlab("Beta")+
geom_abline(intercept = 0, slope=0)+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
ggtitle(label = "Comparison of Survey and Non-Survey Regression effects")

Analysis
sub<-data %>%
select(badhealth, opportunity_youth_cat_num, opportunity_youth_cat, race_eth,educ,whitemajority, otherminority,urban_rural, male,sampweight,male, strata) %>%
filter( complete.cases( . ))
#cat<-sample(1:nrow(sub), size = 1000, replace = FALSE)
#sub<-sub[cat, ]
#First we tell R our survey design
options(survey.lonely.psu = "adjust")
des<-svydesign(ids= ~1,
strata= ~strata,
weights= ~sampweight,
data = sub )
cat<-svyby(formula = ~badhealth,
by = ~opportunity_youth_cat,
design = des,
FUN = svymean,
na.rm=T)
svychisq(~badhealth+opportunity_youth_cat,
design = des)
##
## Pearson's X^2: Rao & Scott adjustment
##
## data: svychisq(~badhealth + opportunity_youth_cat, design = des)
## F = 25.042, ndf = 1, ddf = 3710, p-value = 5.87e-07
cat%>%
ggplot()+
geom_point(aes(x=opportunity_youth_cat,y=badhealth))+
geom_errorbar(aes(x=opportunity_youth_cat, ymin = badhealth-1.96*se,
ymax= badhealth+1.96*se),
width=.25)+
labs(title = "Percent % of Young Adults Ages 16-24 with Fair/Poor Health by Opportunity youth category",
caption = "Source: IPUMS Health Survey Data, 2019-2020 \n Calculations by Joseph Jaiyeola",
x = "Opportunity youth category",
y = "% Fair/Poor Health")+
theme_minimal()

dog<-svyby(formula = ~badhealth,
by = ~male,
design = des,
FUN = svymean,
na.rm=T)
svychisq(~badhealth+male,
design = des)
##
## Pearson's X^2: Rao & Scott adjustment
##
## data: svychisq(~badhealth + male, design = des)
## F = 3.4527, ndf = 1, ddf = 3710, p-value = 0.06323
dog%>%
ggplot()+
geom_point(aes(x=male,y=badhealth))+
geom_errorbar(aes(x=male, ymin = badhealth-1.96*se,
ymax= badhealth+1.96*se),
width=.25)+
labs(title = "Percent % of US with Fair/Poor Health by Gender",
caption = "Source: IPUMS Health Survey Data, 2019-2020 \n Calculations by Joseph Jaiyeola",
x = "Gender",
y = "% Fair/Poor Health")+
theme_minimal()

catdog<-svyby(formula = ~badhealth,
by = ~male+opportunity_youth_cat,
design = des,
FUN = svymean,
na.rm=T)
#this plot is a little more complicated, but facet_wrap() plots separate plots for groups
catdog%>%
ggplot()+
#geom_point(aes(x=educ, y = badhealth, color=race_eth, group=race_eth), position="dodge")+
geom_errorbar(aes(x=opportunity_youth_cat,y = badhealth,
ymin = badhealth-1.96*se,
ymax= badhealth+1.96*se,
color=male,
group=male),
width=.25,
position="dodge")+
#facet_wrap(~ race_eth, nrow = 3)+
labs(title = "Percent % of US with Fair/Poor Health by Gender and Oppor Youth Cat",
caption = "Source: IPUMS Health Survey Data, 2019-2020 \n Calculations by Joseph Jaiyeola",
x = "Opportunity Youth Category",
y = "% Fair/Poor Health")+
theme_minimal()

#Logit model
fit.logit<-svyglm(badhealth ~ opportunity_youth_cat + urban_rural + male + educ,
design = des,
family = binomial)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
summary(fit.logit)
##
## Call:
## svyglm(formula = badhealth ~ opportunity_youth_cat + urban_rural +
## male + educ, design = des, family = binomial)
##
## Survey design:
## svydesign(ids = ~1, strata = ~strata, weights = ~sampweight,
## data = sub)
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.2283 0.3312 -3.709 0.000211
## opportunity_youth_catNot opportunity youth -0.9007 0.2078 -4.334 1.5e-05
## urban_ruralurban -0.4207 0.2384 -1.765 0.077698
## maleMale -0.3444 0.1763 -1.953 0.050848
## educ1somehs 0.1592 0.4232 0.376 0.706758
## educ2hsgrad -0.5323 0.2878 -1.849 0.064469
## educ3somecol -0.4732 0.2911 -1.626 0.104073
## educ4colgrad -1.0339 0.3843 -2.690 0.007175
##
## (Intercept) ***
## opportunity_youth_catNot opportunity youth ***
## urban_ruralurban .
## maleMale .
## educ1somehs
## educ2hsgrad .
## educ3somecol
## educ4colgrad **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1.001159)
##
## Number of Fisher Scoring iterations: 6
library(gtsummary)
fit.logit%>%
tbl_regression(exponentiate=TRUE )
Characteristic |
OR |
95% CI |
p-value |
opportunity_youth_cat |
|
|
|
Opportunity youth |
— |
— |
|
Not opportunity youth |
0.41 |
0.27, 0.61 |
<0.001 |
urban_rural |
|
|
|
rural |
— |
— |
|
urban |
0.66 |
0.41, 1.05 |
0.078 |
male |
|
|
|
Female |
— |
— |
|
Male |
0.71 |
0.50, 1.00 |
0.051 |
educ |
|
|
|
0Prim |
— |
— |
|
1somehs |
1.17 |
0.51, 2.69 |
0.7 |
2hsgrad |
0.59 |
0.33, 1.03 |
0.064 |
3somecol |
0.62 |
0.35, 1.10 |
0.10 |
4colgrad |
0.36 |
0.17, 0.76 |
0.007 |
library(sjPlot)
plot_model(fit.logit,
axis.lim = c(.1, 10), #you may need to modify these
title = "Odds ratios for Poor Self Rated Health")

library(emmeans)
rg<-ref_grid(fit.logit)
marg_logit<-emmeans(object = rg,
specs = c( "opportunity_youth_cat", "urban_rural", "male", "educ"),
type="response" )
knitr::kable(marg_logit, digits = 4)
Opportunity youth |
rural |
Female |
0Prim |
0.2265 |
0.0580 |
Inf |
0.1327 |
0.3591 |
Not opportunity youth |
rural |
Female |
0Prim |
0.1063 |
0.0311 |
Inf |
0.0590 |
0.1842 |
Opportunity youth |
urban |
Female |
0Prim |
0.1612 |
0.0431 |
Inf |
0.0933 |
0.2642 |
Not opportunity youth |
urban |
Female |
0Prim |
0.0724 |
0.0193 |
Inf |
0.0426 |
0.1206 |
Opportunity youth |
rural |
Male |
0Prim |
0.1718 |
0.0449 |
Inf |
0.1005 |
0.2781 |
Not opportunity youth |
rural |
Male |
0Prim |
0.0777 |
0.0211 |
Inf |
0.0452 |
0.1306 |
Opportunity youth |
urban |
Male |
0Prim |
0.1199 |
0.0335 |
Inf |
0.0681 |
0.2024 |
Not opportunity youth |
urban |
Male |
0Prim |
0.0524 |
0.0133 |
Inf |
0.0317 |
0.0855 |
Opportunity youth |
rural |
Female |
1somehs |
0.2556 |
0.0797 |
Inf |
0.1312 |
0.4383 |
Not opportunity youth |
rural |
Female |
1somehs |
0.1224 |
0.0440 |
Inf |
0.0588 |
0.2376 |
Opportunity youth |
urban |
Female |
1somehs |
0.1840 |
0.0591 |
Inf |
0.0944 |
0.3278 |
Not opportunity youth |
urban |
Female |
1somehs |
0.0839 |
0.0278 |
Inf |
0.0431 |
0.1570 |
Opportunity youth |
rural |
Male |
1somehs |
0.1957 |
0.0653 |
Inf |
0.0973 |
0.3544 |
Not opportunity youth |
rural |
Male |
1somehs |
0.0900 |
0.0322 |
Inf |
0.0437 |
0.1762 |
Opportunity youth |
urban |
Male |
1somehs |
0.1377 |
0.0476 |
Inf |
0.0678 |
0.2596 |
Not opportunity youth |
urban |
Male |
1somehs |
0.0609 |
0.0204 |
Inf |
0.0313 |
0.1154 |
Opportunity youth |
rural |
Female |
2hsgrad |
0.1467 |
0.0341 |
Inf |
0.0916 |
0.2268 |
Not opportunity youth |
rural |
Female |
2hsgrad |
0.0653 |
0.0170 |
Inf |
0.0389 |
0.1076 |
Opportunity youth |
urban |
Female |
2hsgrad |
0.1014 |
0.0198 |
Inf |
0.0687 |
0.1474 |
Not opportunity youth |
urban |
Female |
2hsgrad |
0.0439 |
0.0078 |
Inf |
0.0309 |
0.0618 |
Opportunity youth |
rural |
Male |
2hsgrad |
0.1086 |
0.0266 |
Inf |
0.0664 |
0.1726 |
Not opportunity youth |
rural |
Male |
2hsgrad |
0.0472 |
0.0118 |
Inf |
0.0288 |
0.0764 |
Opportunity youth |
urban |
Male |
2hsgrad |
0.0741 |
0.0164 |
Inf |
0.0476 |
0.1135 |
Not opportunity youth |
urban |
Male |
2hsgrad |
0.0315 |
0.0057 |
Inf |
0.0221 |
0.0447 |
Opportunity youth |
rural |
Female |
3somecol |
0.1543 |
0.0390 |
Inf |
0.0921 |
0.2469 |
Not opportunity youth |
rural |
Female |
3somecol |
0.0690 |
0.0178 |
Inf |
0.0413 |
0.1131 |
Opportunity youth |
urban |
Female |
3somecol |
0.1070 |
0.0216 |
Inf |
0.0714 |
0.1571 |
Not opportunity youth |
urban |
Female |
3somecol |
0.0464 |
0.0065 |
Inf |
0.0352 |
0.0610 |
Opportunity youth |
rural |
Male |
3somecol |
0.1145 |
0.0324 |
Inf |
0.0646 |
0.1949 |
Not opportunity youth |
rural |
Male |
3somecol |
0.0499 |
0.0134 |
Inf |
0.0293 |
0.0837 |
Opportunity youth |
urban |
Male |
3somecol |
0.0782 |
0.0195 |
Inf |
0.0476 |
0.1260 |
Not opportunity youth |
urban |
Male |
3somecol |
0.0333 |
0.0059 |
Inf |
0.0235 |
0.0471 |
Opportunity youth |
rural |
Female |
4colgrad |
0.0943 |
0.0328 |
Inf |
0.0468 |
0.1809 |
Not opportunity youth |
rural |
Female |
4colgrad |
0.0406 |
0.0145 |
Inf |
0.0200 |
0.0807 |
Opportunity youth |
urban |
Female |
4colgrad |
0.0640 |
0.0200 |
Inf |
0.0344 |
0.1161 |
Not opportunity youth |
urban |
Female |
4colgrad |
0.0270 |
0.0077 |
Inf |
0.0154 |
0.0470 |
Opportunity youth |
rural |
Male |
4colgrad |
0.0687 |
0.0255 |
Inf |
0.0327 |
0.1386 |
Not opportunity youth |
rural |
Male |
4colgrad |
0.0291 |
0.0106 |
Inf |
0.0142 |
0.0587 |
Opportunity youth |
urban |
Male |
4colgrad |
0.0462 |
0.0160 |
Inf |
0.0233 |
0.0897 |
Not opportunity youth |
urban |
Male |
4colgrad |
0.0193 |
0.0059 |
Inf |
0.0106 |
0.0349 |
Generate predicted probabilities for some “interesting” cases from your analysis, to highlight the effects from the model and your stated research question
comps<-as.data.frame(marg_logit)
comps[comps$opportunity_youth_cat=="Opportunity youth" & comps$educ == "4colgrad" & comps$urban_rural == "urban" , ]
comps[comps$opportunity_youth_cat=="Not opportunity youth" & comps$educ == "4colgrad" & comps$urban_rural == "urban" , ]
According to the model, holding staying in a urban environment and being a college grad constant, opportunity youths have higher probability of reporting fair/poor self health rating compared to connected youth. And this is this for both male and female
LS0tCnRpdGxlOiAiQXNzaWdubWVudCAzIgphdXRob3I6ICJKb3NlcGggSmFpeWVvbGEiCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDoKICAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgoKIyAxLiBEZWZpbmUgYSBiaW5hcnkgb3V0Y29tZSB2YXJpYWJsZSBvZiB5b3VyIGNob29zaW5nIGFuZCBkZWZpbmUgaG93IHlvdSByZWNvZGUgdGhlIG9yaWdpbmFsIHZhcmlhYmxlLgoKUHJvcG9zZWQgdG9waWM6IEFkdnNlcnNlIGhlYWx0aCBjb25kaXRpb25zIGFzc29jaWF0ZWQgd2l0aCBvcHBvcnR1bml0eSB5b3V0aHMKCk91dGNvbWUgdmFyaWFiZWxzOiBIZWFsdGggY29uZGl0aW9ucyBzdWNoICBIZWFsdGggc3RhdHVzLCBkZXByZXNzaW9uLCBhbnhpZXR5LCBzbW9raW5nIGV0Yy4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBhc3NpZ25tZW50IEkgd291bGQgZm9jdXMgb24gKioqc2VsZiByYXRlZCBoZWFsdGggc3RhdHVzKioqCgojIDIgU3RhdGUgYSByZXNlYXJjaCBxdWVzdGlvbiBhYm91dCB3aGF0IGZhY3RvcnMgeW91IGJlbGlldmUgd2lsbCBhZmZlY3QgeW91ciBvdXRjb21lIHZhcmlhYmxlLgoKUXN0OiBJcyBPcHBvcnR1bml0eSB5b3V0aCBzdGF0dXMgYXNzb2NpYXRlZCB3aXRoIEZhaXIvUG9vciBIZWFsdGggc3RhdHVzPwoKIyBEZWZpbmUgYXQgbGVhc3QgMiBwcmVkaWN0b3IgdmFyaWFibGVzLCBiYXNlZCBvbiB5b3VyIHJlc2VhcmNoIHF1ZXN0aW9uCgotLSBPcHBvcnR1bml0eSB5b3V0aCBzdGF0dXMKLS0gR2VuZGVyCi0tIFVyYmFuLXJ1cmFsIHN0YXR1cwotLSBSYWNpYWwgZXRobmljaXR5CgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShzdGFyZ2F6ZXIpCmxpYnJhcnkoc3VydmV5KQpsaWJyYXJ5KGNhcikKbGlicmFyeShxdWVzdGlvbnIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3J2eXIpCmBgYAoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoaXB1bXNyKQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmRkaSA8LSByZWFkX2lwdW1zX2RkaSgibmhpc18wMDAwMi54bWwiKQpkYXRhIDwtIHJlYWRfaXB1bXNfbWljcm8oZGRpKQpkYXRhPC0gaGF2ZW46OnphcF9sYWJlbHMoZGF0YSkKYGBgCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpuYW1lcyhkYXRhKSA8LSB0b2xvd2VyKGdzdWIocGF0dGVybiA9ICJfIixyZXBsYWNlbWVudCA9ICAiIix4ID0gIG5hbWVzKGRhdGEpKSkKYGBgCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KI3NleApkYXRhJG1hbGU8LWFzLmZhY3RvcihpZmVsc2UoZGF0YSRzZXg9PTEsICJNYWxlIiwgIkZlbWFsZSIpKQoKCiNyYWNlL2V0aG5pY2l0eQpkYXRhJHdoaXRlbWFqb3JpdHk8LSBjYXI6OlJlY29kZShkYXRhJGhpc3ByYWNlLAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjAyPTE7IDk5PU5BOyBlbHNlPTAiKQoKZGF0YSRvdGhlcm1pbm9yaXR5PC0gY2FyOjpSZWNvZGUoZGF0YSRoaXNwcmFjZSwKICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9ImMoMSwzLDQsNSw2LDcpPTE7IDk5PU5BOyBlbHNlPTAiKQoKZGF0YSRyYWNlX2V0aDwtY2FyOjpSZWNvZGUoZGF0YSRoaXNwcmFjZSwKcmVjb2Rlcz0iMDI9J3doaXRlbWFqb3JpdHknOyBjKDEsMyw0LDUsNiw3KT0nb3RoZXJtaW5vcml0eSc7ZWxzZT1OQSIsCmFzLmZhY3RvciA9IFQpCmRhdGEkcmFjZV9ldGg8LXJlbGV2ZWwoZGF0YSRyYWNlX2V0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICByZWYgPSAid2hpdGVtYWpvcml0eSIpCgoKI2VkdWNhdGlvbiBsZXZlbAoKCgpkYXRhJGVkdWM8LSBjYXI6OlJlY29kZShkYXRhJGVkdWMsCiAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjEwMjoxMDM9JzBQcmltJzsgMTE2PScxc29tZWhzJzsgMjAxOjIwMj0nMmhzZ3JhZCc7IDMwMTozMDM9JzNzb21lY29sJzsgNDAwOjUwMz0nNGNvbGdyYWQnOzk5Nzo5OTk9TkE7MDAwPU5BIiwKICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkZWR1YzwtZmN0X3JlbGV2ZWwoZGF0YSRlZHVjLCcwUHJpbScsJzFzb21laHMnLCcyaHNncmFkJywnM3NvbWVjb2wnLCc0Y29sZ3JhZCcgKSAKCiNVcmJhbi1ydXJhbCBjbGFzc2lmaWNhdGlvbgoKCmRhdGEkdXJiYW5fcnVyYWw8LSBjYXI6OlJlY29kZShkYXRhJHVyYnJybCwKICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMTozPSd1cmJhbic7IDQ9J3J1cmFsJzswMDA9TkEiLAogICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSR1cmJhbl9ydXJhbDwtcmVsZXZlbChkYXRhJHVyYmFuX3J1cmFsLCByZWY9J3J1cmFsJykgCgoKZGF0YSRydXJhbDwtIGNhcjo6UmVjb2RlKGRhdGEkaGlzcHJhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iND0xOyA5OT1OQTsgZWxzZT0wIikKCmRhdGEkdXJiYW48LSBjYXI6OlJlY29kZShkYXRhJGhpc3ByYWNlLAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjE6Mz0xOyA5OT1OQTsgZWxzZT0wIikKCgoKCiNlbXBsb3ltZW50IHN0YXR1cwoKCmRhdGEkdW5lbXBsb3k8LSBjYXI6OlJlY29kZShkYXRhJGVtcHN0YXQsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMjAwPTE7IDAwPU5BOyA5OTk9TkE7IGVsc2U9MCIpCgoKZGF0YSRlbXBsb3lfc3RhdHVzPC0gY2FyOjpSZWNvZGUoZGF0YSRlbXBzdGF0LAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjEwMD0nRW1wbG95ZWQnOyAyMDA9J3VuZW1wbG95ZWQnO2Vsc2U9TkEiLAogICAgICAgICAgICAgICAgICAgICAgIGFzLmZhY3Rvcj1UKQpkYXRhJGVtcGxveV9zdGF0dXM8LXJlbGV2ZWwoZGF0YSRlbXBsb3lfc3RhdHVzLCByZWY9J0VtcGxveWVkJykKCgojIGN1cnJlbnRseSBpbiBzY2hvb2wKCmRhdGEkbm9uX3NjaG9vbGluZzwtIGNhcjo6UmVjb2RlKGRhdGEkc2Nob29sbm93LAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjE9MTsgMD1OQTsgNzo5PU5BOyBlbHNlPTAiKQoKZGF0YSRzY2hvb2xzdGF0dXM8LSBjYXI6OlJlY29kZShkYXRhJHNjaG9vbG5vdywKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIxPSdubyc7IDI9J3llcyc7ZWxzZT1OQSIsCiAgICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkc2Nob29sc3RhdHVzPC1yZWxldmVsKGRhdGEkc2Nob29sc3RhdHVzLCByZWY9J25vJykKCmRhdGE8LWRhdGElPiUKICBmaWx0ZXIoY29tcGxldGUuY2FzZXModW5lbXBsb3ksbm9uX3NjaG9vbGluZykpCgoKIyBtZXJnaW5nIHNjaG9vbGluZyBhbmQgd29ya2luZwoKZGF0YSRvcHBvcnR1bml0eV95b3V0aCA8LSBwYXN0ZSggZGF0YSR1bmVtcGxveSwgZGF0YSRub25fc2Nob29saW5nLCBzZXAgPSIiKQoKCmRhdGEkb3Bwb3J0dW5pdHlfeW91dGhfY2F0X251bTwtIGNhcjo6UmVjb2RlKGRhdGEkb3Bwb3J0dW5pdHlfeW91dGgsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMTE9MTsgMDA6MTA9MDtlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9RikKCgpkYXRhJG9wcG9ydHVuaXR5X3lvdXRoX2NhdDwtIGNhcjo6UmVjb2RlKGRhdGEkb3Bwb3J0dW5pdHlfeW91dGgsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMTE9J09wcG9ydHVuaXR5IHlvdXRoJzswMDoxMD0nTm90IG9wcG9ydHVuaXR5IHlvdXRoJztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRvcHBvcnR1bml0eV95b3V0aF9jYXQ8LXJlbGV2ZWwoZGF0YSRvcHBvcnR1bml0eV95b3V0aF9jYXQsIHJlZj0nT3Bwb3J0dW5pdHkgeW91dGgnKQoKZGF0YSRub25fb3Bwb3J0dW5pdHlfeW91dGhfY2F0X251bTwtIGNhcjo6UmVjb2RlKGRhdGEkb3Bwb3J0dW5pdHlfeW91dGhfY2F0X251bSwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIwPTE7IDk5PU5BOyBlbHNlPTAiKQoKI2luY29tZSBncm91cGluZwoKZGF0YSRmYW1pbHlpbmNvbWUgPC0gZGF0YSRpbmNmYW0wN29uCgojIGJvcm4gaW4gdGhlIFVTCgpkYXRhJHVzYm9ybjwtIGNhcjo6UmVjb2RlKGRhdGEkdXNib3JuLAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjIwPTE7IDk3Ojk4PU5BOyBlbHNlPTAiKQoKIyBVUyBDaXRpemVuCmRhdGEkY2l0aXplbjwtIGNhcjo6UmVjb2RlKGRhdGEkY2l0aXplbiwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIyPTE7IDg6OT1OQTsgZWxzZT0wIikKCiNsYXN0IGVtcGxveWVkCgoKCmRhdGEkZW1wbG95ZWRsYXN0PC0gY2FyOjpSZWNvZGUoZGF0YSRlbXBsYXN0LAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjE9J1dpdGhpbiBwYXN0IDEybW9udGhzJzsgMj0nMS01eWVhcnMgYWdvJzsgMz0nb3ZlciA1eWVhcnMgYWdvJzsgND0nbmV2ZXIgd29ya2VkJztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRlbXBsb3llZGxhc3Q8LXJlbGV2ZWwoZGF0YSRlbXBsb3llZGxhc3QsIHJlZj0nMS01eWVhcnMgYWdvJykKCgojSEVBTFRIIFZBUklBQkxFUwoKI1Bvb3Igb3IgZmFpciBzZWxmIHJhdGVkIGhlYWx0aApkYXRhJGJhZGhlYWx0aDwtY2FyOjpSZWNvZGUoZGF0YSRoZWFsdGgsIHJlY29kZXM9IjQ6NT0xOyAxOjM9MDsgZWxzZT1OQSIpCgoKI3BsYWNlIGZvciBtZWRpY2FsIGNhcmUKCgpkYXRhJG1lZGljYWxwbGFjZTwtIGNhcjo6UmVjb2RlKGRhdGEkdXN1YWxwbCwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIxPSdubyc7IDI6Mzo9J3llcyc7ZWxzZT1OQSIsCiAgICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkbWVkaWNhbHBsYWNlPC1yZWxldmVsKGRhdGEkbWVkaWNhbHBsYWNlLCByZWY9J25vJykKCgojIGRlbGF5ZWQgbWVkaWNhbCBjYXJlIGR1ZSB0byBjb3N0CgoKZGF0YSRtZWRpY2FsX2NhcmVfY29zdDwtIGNhcjo6UmVjb2RlKGRhdGEkZGVsYXljb3N0LAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjI9J3llcyc7IDE9J25vJztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRtZWRpY2FsX2NhcmVfY29zdDwtcmVsZXZlbChkYXRhJG1lZGljYWxfY2FyZV9jb3N0LCByZWY9J3llcycpCgojIHdvcnJpZWQgYWJvdXQgcGF5aW5nIG1lZGljYWwgYmlsbHMKCgpkYXRhJG1lZGljYWxfYmlsbF93b3JyaWVkPC0gY2FyOjpSZWNvZGUoZGF0YSR3b3JtZWRiaWxsLAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjE9J3Zlcnkgd29ycmllZCc7IDI9J3NvbWV3aGF0IHdvcnJpZWQnOyAzPSdub3QgYXQgYWxsJztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRtZWRpY2FsX2JpbGxfd29ycmllZDwtcmVsZXZlbChkYXRhJG1lZGljYWxfYmlsbF93b3JyaWVkLCByZWY9J3Zlcnkgd29ycmllZCcpCgojIHVuYWJsZSB0byBwYXkgbWVkaWNhbCBiaWxscwoKCmRhdGEkbWVkaWNhbF9iaWxsX3VuYWJsZXRvcGF5PC0gY2FyOjpSZWNvZGUoZGF0YSRoaXVuYWJsZXBheSwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIxPSdubyc7IDI9J3llcyc7ZWxzZT1OQSIsCiAgICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkbWVkaWNhbF9iaWxsX3VuYWJsZXRvcGF5PC1yZWxldmVsKGRhdGEkbWVkaWNhbF9iaWxsX3VuYWJsZXRvcGF5LCByZWY9J3llcycpCgoKIyBoZWFsdGggaW5zdXJhbmNlIGNvdmVyYWdlCgoKZGF0YSRoZWFsdGhpbnN1cmFjZV9jb3ZlcmFnZTwtIGNhcjo6UmVjb2RlKGRhdGEkaGlub3Rjb3ZlLAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjE9J25vLCBoYXMgY292ZXJhZ2UnOyAyPSd5ZXMsIG5vIGNvdmVyYWdlJztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRoZWFsdGhpbnN1cmFjZV9jb3ZlcmFnZTwtcmVsZXZlbChkYXRhJGhlYWx0aGluc3VyYWNlX2NvdmVyYWdlLCByZWY9J3llcywgbm8gY292ZXJhZ2UnKQoKIyBkb250IGhhdmUgaGVhbHRoIGluc3VyYW5jZSBjdXogb2YgY29zdAoKCmRhdGEkbm9oZWFsdGhpbnN1cmFjZV9jb3N0PC0gY2FyOjpSZWNvZGUoZGF0YSRoaW5vY29zdHIsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMT0nbm8nOyAyPSd5ZXMnO2Vsc2U9TkEiLAogICAgICAgICAgICAgICAgICAgICAgIGFzLmZhY3Rvcj1UKQpkYXRhJG5vaGVhbHRoaW5zdXJhY2VfY29zdDwtcmVsZXZlbChkYXRhJG5vaGVhbHRoaW5zdXJhY2VfY29zdCwgcmVmPSd5ZXMnKQoKIyB1c2VkIG1lZGljYXRpb24gaW4gdGhlIHBhc3QgeWVhcgoKCmRhdGEkdXNlZG1lZGljYXRpb25zPC0gY2FyOjpSZWNvZGUoZGF0YSRwcmVtZWR5ciwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIxPSdubyc7IDI9J3llcyc7ZWxzZT1OQSIsCiAgICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkdXNlZG1lZGljYXRpb25zPC1yZWxldmVsKGRhdGEkdXNlZG1lZGljYXRpb25zLCByZWY9J3llcycpCgoKIyBpZiB0aGV5IHNtb2tlZAoKCmRhdGEkc21va2VfZnJlcXVlbnRseTwtIGNhcjo6UmVjb2RlKGRhdGEkc21va2ZyZXFub3csCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMT0nbm8nOyAyOjM9J3NvbWVkYXlzL2V2ZXJ5ZGF5JztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRzbW9rZV9mcmVxdWVudGx5PC1yZWxldmVsKGRhdGEkc21va2VfZnJlcXVlbnRseSwgcmVmPSdzb21lZGF5cy9ldmVyeWRheScpCgojIHNtb2tlZCB1cCB0byAxMDAgY2lnYXJyZXRoIGluIGxpZmUgdGltZQoKCmRhdGEkc21va2VfMTAwY2lnPC0gY2FyOjpSZWNvZGUoZGF0YSRzbW9rZXYsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMT0nbm8nOyAyPSd5ZXMnO2Vsc2U9TkEiLAogICAgICAgICAgICAgICAgICAgICAgIGFzLmZhY3Rvcj1UKQpkYXRhJHNtb2tlXzEwMGNpZzwtcmVsZXZlbChkYXRhJHNtb2tlXzEwMGNpZywgcmVmPSd5ZXMnKQoKCiNNZW50YWwgaGVhbHRoCgojIGV2ZXIgaGFkIGFueGlldHkgZGlzb3JlZGVyCgoKZGF0YSRhbnhpZXR5X2Rpc29yZWRlcjwtIGNhcjo6UmVjb2RlKGRhdGEkYW54aWV0eWV2LAogICAgICAgICAgICAgICAgICAgICAgIHJlY29kZXM9IjE9J25vJzsgMj0neWVzJztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRhbnhpZXR5X2Rpc29yZWRlcjwtcmVsZXZlbChkYXRhJGFueGlldHlfZGlzb3JlZGVyLCByZWY9J3llcycpCgojIG1lZGljYXRpb24gZm9yIHdvcnJ5aW5nCgoKZGF0YSRtZWRpY2F0aW9uX2Zvcl93b3JyeTwtIGNhcjo6UmVjb2RlKGRhdGEkd29ycngsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMT0nbm8nOyAyPSd5ZXMnO2Vsc2U9TkEiLAogICAgICAgICAgICAgICAgICAgICAgIGFzLmZhY3Rvcj1UKQpkYXRhJG1lZGljYXRpb25fZm9yX3dvcnJ5PC1yZWxldmVsKGRhdGEkbWVkaWNhdGlvbl9mb3Jfd29ycnksIHJlZj0neWVzJykKCgojIG1lZGljYXRpb24gZm9yIGRlcHJlc3Npb24KCgoKZGF0YSRtZWRpY2F0aW9uX2Zvcl9kZXByZXNzaW9uPC0gY2FyOjpSZWNvZGUoZGF0YSRkZXByeCwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIxPSdubyc7IDI9J3llcyc7ZWxzZT1OQSIsCiAgICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkbWVkaWNhdGlvbl9mb3JfZGVwcmVzc2lvbjwtcmVsZXZlbChkYXRhJG1lZGljYXRpb25fZm9yX2RlcHJlc3Npb24sIHJlZj0neWVzJykKCiMgbGV2ZWwgb2Ygd29ycnkKCgoKZGF0YSRsZXZlbF9vZl93b3JyeTwtIGNhcjo6UmVjb2RlKGRhdGEkd29yZmVlbGV2bCwKICAgICAgICAgICAgICAgICAgICAgICByZWNvZGVzPSIxPSdhbG90JzsgMj0nYSBsaXR0bGUnOyAzPSdidHcgbGl0dGxlIGFuZCBhbG90JztlbHNlPU5BIiwKICAgICAgICAgICAgICAgICAgICAgICBhcy5mYWN0b3I9VCkKZGF0YSRsZXZlbF9vZl93b3JyeTwtcmVsZXZlbChkYXRhJGxldmVsX29mX3dvcnJ5LCByZWY9J2Fsb3QnKQoKCiMgbGV2ZWwgb2YgZGVwcmVzc2lvbgoKCgpkYXRhJGxldmVsX29mX2RlcHJlc3Npb248LSBjYXI6OlJlY29kZShkYXRhJGRlcGZlZWxldmwsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjb2Rlcz0iMT0nYWxvdCc7IDI9J2EgbGl0dGxlJzsgMz0nYnR3IGxpdHRsZSBhbmQgYWxvdCc7ZWxzZT1OQSIsCiAgICAgICAgICAgICAgICAgICAgICAgYXMuZmFjdG9yPVQpCmRhdGEkbGV2ZWxfb2ZfZGVwcmVzc2lvbjwtcmVsZXZlbChkYXRhJGxldmVsX29mX2RlcHJlc3Npb24sIHJlZj0nYWxvdCcpCgoKCgpgYGAKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpkYXRhIDwtIGRhdGElPiUKZmlsdGVyKGFnZSA+PTE2ICYgYWdlPD0yNCkKCmRhdGE8LWRhdGElPiUKICBmaWx0ZXIoaXMubmEoYmFkaGVhbHRoKT09RikKYGBgCgoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CnRhYmxlKGRhdGEkb3Bwb3J0dW5pdHlfeW91dGhfY2F0KQpgYGAKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQp0YWJsZShkYXRhJG9wcG9ydHVuaXR5X3lvdXRoX2NhdCwgZGF0YSRyYWNlX2V0aCkKYGBgCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KdGFibGUoZGF0YSRvcHBvcnR1bml0eV95b3V0aF9jYXQsIGRhdGEkYmFkaGVhbHRoKQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CjEwMCpwcm9wLnRhYmxlKHRhYmxlKGRhdGEkYmFkaGVhbHRoLCBkYXRhJG9wcG9ydHVuaXR5X3lvdXRoX2NhdCApLCBtYXJnaW49MikKYGBgCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0Kb3B0aW9ucyhzdXJ2ZXkubG9uZWx5LnBzdSA9ICJhZGp1c3QiKQoKZGVzPC1zdnlkZXNpZ24oaWRzPX4xLCBzdHJhdGE9fnN0cmF0YSwgd2VpZ2h0cz1+c2FtcHdlaWdodCwgZGF0YSA9IGRhdGEgKQpkZXMKYGBgCgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KI2NvdW50cwpjYXQ8LXd0ZC50YWJsZShkYXRhJGJhZGhlYWx0aCwKICAgICAgICAgICAgICAgZGF0YSRvcHBvcnR1bml0eV95b3V0aF9jYXQsCiAgICAgICAgICAgICAgIHdlaWdodHMgPSBkYXRhJHNhbXB3ZWlnaHQpCgojcHJvcG9ydGlvbnMKcHJvcC50YWJsZSgKICBjYXQsCiAgbWFyZ2luPTIpCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KI2NvbXBhcmUgdGhhdCB3aXRoIHRoZSBvcmlnaW5hbCwgdW53ZWlnaHRlZCBwcm9wb3J0aW9ucwpwcm9wLnRhYmxlKHRhYmxlKGRhdGEkYmFkaGVhbHRoLAogICAgICAgICAgICAgICAgIGRhdGEkb3Bwb3J0dW5pdHlfeW91dGhfY2F0KSwKICAgICAgICAgICBtYXJnaW49MikKYGBgCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpjYXQ8LXN2eWJ5KGZvcm11bGEgPSB+YmFkaGVhbHRoLAogICAgICAgICAgIGJ5PX5vcHBvcnR1bml0eV95b3V0aF9jYXQsCiAgICAgICAgICAgZGVzaWduID0gZGVzLAogICAgICAgICAgIEZVTj1zdnltZWFuKQoKc3Z5Y2hpc3EofmJhZGhlYWx0aCtzZXgsIGRlc2lnbiA9IGRlcykKYGBgCgoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjprYWJsZShjYXQsCiAgICAgIGNhcHRpb24gPSAiU3VydmV5IEVzdGltYXRlcyBvZiBQb29yIFNSSCBieSBPcHBvcnR1bml0eSBZb3V0aHMiLAogICAgICBhbGlnbiA9ICdjJywgIAogICAgICBmb3JtYXQgPSAiaHRtbCIpCmBgYAoKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpzdi50YWJsZTwtc3Z5YnkoZm9ybXVsYSA9IH5iYWRoZWFsdGgsCiAgICAgICAgICAgICAgICBieSA9IH5vcHBvcnR1bml0eV95b3V0aF9jYXQsCiAgICAgICAgICAgICAgICBkZXNpZ24gPSBkZXMsCiAgICAgICAgICAgICAgICBGVU4gPSBzdnltZWFuLAogICAgICAgICAgICAgICAgbmEucm09VCkKCgprbml0cjo6a2FibGUoc3YudGFibGUsCiAgICAgIGNhcHRpb24gPSAiU3VydmV5IEVzdGltYXRlcyBvZiBQb29yIFNSSCBieSBPcHBvcnR1bml0eSBZb3V0aHMiLAogICAgICBhbGlnbiA9ICdjJywgIAogICAgICBmb3JtYXQgPSAiaHRtbCIpCmBgYAoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CiNNYWtlIGEgc3VydmV5IGRlc2lnbiB0aGF0IGlzIHJhbmRvbSBzYW1wbGluZyAtIG5vIHN1cnZleSBpbmZvcm1hdGlvbgpub2Rlczwtc3Z5ZGVzaWduKGlkcyA9IH4xLCAgd2VpZ2h0cyA9IH4xLCBkYXRhID0gZGF0YSkKCnN2LnRhYmxlPC1zdnlieShmb3JtdWxhID0gfmZhY3RvcihiYWRoZWFsdGgpLAogICAgICAgICAgICAgICAgYnkgPSB+b3Bwb3J0dW5pdHlfeW91dGhfY2F0LAogICAgICAgICAgICAgICAgZGVzaWduID0gbm9kZXMsCiAgICAgICAgICAgICAgICBGVU4gPSBzdnltZWFuLAogICAgICAgICAgICAgICAgbmEucm09VCkKYGBgCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQprbml0cjo6a2FibGUoc3YudGFibGUsCiAgICAgIGNhcHRpb24gPSAiRXN0aW1hdGVzIG9mIFBvb3IgU1JIIGJ5IE9wcG9ydHVuaXR5IHlvdXRoIC0gTm8gc3VydmV5IGRlc2lnbiIsCiAgICAgIGFsaWduID0gJ2MnLCAgCiAgICAgIGZvcm1hdCA9ICJodG1sIikKYGBgCgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShzcnZ5cikKCmRhdGElPiUKICBhc19zdXJ2ZXlfZGVzaWduKHN0cmF0YSA9IHN0cmF0YSwKICAgICAgICAgICAgICAgICAgIHdlaWdodHMgPSBzYW1wd2VpZ2h0KSU+JQogIGdyb3VwX2J5KG9wcG9ydHVuaXR5X3lvdXRoX2NhdCklPiUKICBzdW1tYXJpc2UobWVhbl9iaCA9IHN1cnZleV9tZWFuKGJhZGhlYWx0aCwgbmEucm09VCkpJT4lCiAgdW5ncm91cCgpCmBgYAoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZ3RzdW1tYXJ5KQoKZGF0YSU+JQogIGFzX3N1cnZleV9kZXNpZ24oIHN0cmF0YSA9c3RyYXRhLAogICAgICAgICAgICAgICAgICAgIHdlaWdodHMgPSBzYW1wd2VpZ2h0KSU+JQogIHNlbGVjdChiYWRoZWFsdGgsIG9wcG9ydHVuaXR5X3lvdXRoX2NhdCklPiUKICB0Ymxfc3Z5c3VtbWFyeShieSA9IG9wcG9ydHVuaXR5X3lvdXRoX2NhdCwgCiAgICAgICAgICAgICAgbGFiZWwgPSBsaXN0KGJhZGhlYWx0aCA9ICJGYWlyL1Bvb3IgSGVhbHRoIikpJT4lCiAgYWRkX3AoKSU+JQogIGFkZF9uKCkKYGBgCgoKCmBgYHtyfQpmaXQxPC1sbShiYWRoZWFsdGh+b3Bwb3J0dW5pdHlfeW91dGhfY2F0K3VyYmFuX3J1cmFsLAogICAgICAgICBkYXRhPWRhdGEpCmBgYAoKYGBge3J9CmZpdDI8LWxtKGJhZGhlYWx0aH5vcHBvcnR1bml0eV95b3V0aF9jYXQrdXJiYW5fcnVyYWwsCiAgICAgICAgIGRhdGE9ZGF0YSwKICAgICAgICAgd2VpZ2h0cyA9IHNhbXB3ZWlnaHQpCmBgYAoKYGBge3J9CmZpdDM8LXN2eWdsbShiYWRoZWFsdGh+b3Bwb3J0dW5pdHlfeW91dGhfY2F0K3VyYmFuX3J1cmFsLAogICAgICAgICAgICAgZGVzaWduID0gZGVzLCAKICAgICAgICAgICAgIGZhbWlseT1nYXVzc2lhbikKYGBgCgoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQpzdGFyZ2F6ZXIoZml0MSwgZml0MiwgZml0MywKICAgICAgICAgIHN0eWxlPSJkZW1vZ3JhcGh5IiwgdHlwZT0iaHRtbCIsCiAgICAgICAgICBjb2x1bW4ubGFiZWxzID0gYygiT0xTIiwgIldlaWdodHMgT25seSIsICJTdXJ2ZXkgRGVzaWduIiksCiAgICAgICAgICB0aXRsZSA9ICJSZWdyZXNzaW9uIG1vZGVscyBmb3IgU2VsZiByYXRlZCBoZWFsdGggdXNpbmcgc3VydmV5IGRhdGEgLSBJUFVNUyBIZWFsdGggc3VydmV5IiwgCiAgICAgICAgICBjb3ZhcmlhdGUubGFiZWxzPWMoIk9wcG9ydHVuaXR5IHlvdXRoIiwgIk5vdCBvcHBvcnR1bml0eSB5b3V0aCIsICJ1cmJhbiIsICJydXJhbCIpLAogICAgICAgICAgCiAgICAgICAgICBrZWVwLnN0YXQ9Im4iLAogICAgICAgICAgbW9kZWwubmFtZXM9RiwgCiAgICAgICAgICBhbGlnbj1ULAogICAgICAgICAgY2k9VCkKYGBgCgoKCgpgYGB7cn0KCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKY29lZnM8LWRhdGEuZnJhbWUoY29lZnM9Yyhjb2VmKGZpdDEpWy0xXSwgY29lZihmaXQzKVstMV0pLAogICAgICAgICAgICAgICAgICBtb2Q9YyhyZXAoIk5vbiBTdXJ2ZXkgTW9kZWwiLCA4KSxyZXAoIlN1cnZleSBNb2RlbCIsIDgpKSwKICAgICAgICAgICAgICAgICAgZWZmZWN0PXJlcChuYW1lcyhjb2VmKGZpdDEpWy0xXSksIDIpKQoKY29lZnMlPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3BvaW50KGFlcyggeD1lZmZlY3QsCiAgICAgICAgICAgICAgICAgIHk9Y29lZnMsCiAgICAgICAgICAgICAgICAgIGdyb3VwPWVmZmVjdCwKICAgICAgICAgICAgICAgICAgY29sb3I9ZWZmZWN0LAogICAgICAgICAgICAgICAgICBzaGFwZT1tb2QpLAogICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gMSksCiAgICAgICAgICAgICBzaXplPTIpKwogIHlsYWIoIlJlZ3Jlc3Npb24gQ29lZmZpY2llbnQiKSsKICB4bGFiKCJCZXRhIikrCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGU9MCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgZ2d0aXRsZShsYWJlbCA9ICJDb21wYXJpc29uIG9mIFN1cnZleSBhbmQgTm9uLVN1cnZleSBSZWdyZXNzaW9uIGVmZmVjdHMiKQoKCmBgYAoKCiMgQW5hbHlzaXMKCmBgYHtyfQpzdWI8LWRhdGEgJT4lCiAgc2VsZWN0KGJhZGhlYWx0aCwgb3Bwb3J0dW5pdHlfeW91dGhfY2F0X251bSwgb3Bwb3J0dW5pdHlfeW91dGhfY2F0LCByYWNlX2V0aCxlZHVjLHdoaXRlbWFqb3JpdHksIG90aGVybWlub3JpdHksdXJiYW5fcnVyYWwsIG1hbGUsc2FtcHdlaWdodCxtYWxlLCBzdHJhdGEpICU+JQogIGZpbHRlciggY29tcGxldGUuY2FzZXMoIC4gKSkKCgojY2F0PC1zYW1wbGUoMTpucm93KHN1YiksIHNpemUgPSAxMDAwLCByZXBsYWNlID0gRkFMU0UpCgojc3ViPC1zdWJbY2F0LCBdCgojRmlyc3Qgd2UgdGVsbCBSIG91ciBzdXJ2ZXkgZGVzaWduCm9wdGlvbnMoc3VydmV5LmxvbmVseS5wc3UgPSAiYWRqdXN0IikKZGVzPC1zdnlkZXNpZ24oaWRzPSB+MSwKICAgICAgICAgICAgICAgc3RyYXRhPSB+c3RyYXRhLAogICAgICAgICAgICAgICB3ZWlnaHRzPSB+c2FtcHdlaWdodCwKICAgICAgICAgICAgICAgZGF0YSA9IHN1YiApCmBgYAoKYGBge3J9CmNhdDwtc3Z5YnkoZm9ybXVsYSA9IH5iYWRoZWFsdGgsCiAgICAgICAgICAgYnkgPSB+b3Bwb3J0dW5pdHlfeW91dGhfY2F0LAogICAgICAgICAgIGRlc2lnbiA9IGRlcywKICAgICAgICAgICBGVU4gPSBzdnltZWFuLAogICAgICAgICAgIG5hLnJtPVQpCgpzdnljaGlzcSh+YmFkaGVhbHRoK29wcG9ydHVuaXR5X3lvdXRoX2NhdCwKICAgICAgICAgZGVzaWduID0gZGVzKQpgYGAKCgpgYGB7cn0KY2F0JT4lCiAgZ2dwbG90KCkrCiAgZ2VvbV9wb2ludChhZXMoeD1vcHBvcnR1bml0eV95b3V0aF9jYXQseT1iYWRoZWFsdGgpKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh4PW9wcG9ydHVuaXR5X3lvdXRoX2NhdCwgeW1pbiA9IGJhZGhlYWx0aC0xLjk2KnNlLCAKICAgICAgICAgICAgICAgICAgICB5bWF4PSBiYWRoZWFsdGgrMS45NipzZSksCiAgICAgICAgICAgICAgICB3aWR0aD0uMjUpKwogICBsYWJzKHRpdGxlID0gIlBlcmNlbnQgJSBvZiBZb3VuZyBBZHVsdHMgQWdlcyAxNi0yNCB3aXRoIEZhaXIvUG9vciBIZWFsdGggYnkgT3Bwb3J0dW5pdHkgeW91dGggY2F0ZWdvcnkiLCAKICAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSVBVTVMgSGVhbHRoIFN1cnZleSBEYXRhLCAyMDE5LTIwMjAgXG4gQ2FsY3VsYXRpb25zIGJ5IEpvc2VwaCBKYWl5ZW9sYSIsCiAgICAgICB4ID0gIk9wcG9ydHVuaXR5IHlvdXRoIGNhdGVnb3J5IiwKICAgICAgIHkgPSAiJSAgRmFpci9Qb29yIEhlYWx0aCIpKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCmBgYHtyfQpkb2c8LXN2eWJ5KGZvcm11bGEgPSB+YmFkaGVhbHRoLAogICAgICAgICAgIGJ5ID0gfm1hbGUsIAogICAgICAgICAgIGRlc2lnbiA9IGRlcywgCiAgICAgICAgICAgRlVOID0gc3Z5bWVhbiwKICAgICAgICAgICBuYS5ybT1UKQoKc3Z5Y2hpc3EofmJhZGhlYWx0aCttYWxlLAogICAgICAgICBkZXNpZ24gPSBkZXMpCmBgYAoKCmBgYHtyfQpkb2clPiUKICBnZ3Bsb3QoKSsKICBnZW9tX3BvaW50KGFlcyh4PW1hbGUseT1iYWRoZWFsdGgpKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh4PW1hbGUsIHltaW4gPSBiYWRoZWFsdGgtMS45NipzZSwgCiAgICAgICAgICAgICAgICAgICAgeW1heD0gYmFkaGVhbHRoKzEuOTYqc2UpLAogICAgICAgICAgICAgICAgd2lkdGg9LjI1KSsKICAgbGFicyh0aXRsZSA9ICJQZXJjZW50ICUgb2YgVVMgIHdpdGggRmFpci9Qb29yIEhlYWx0aCBieSBHZW5kZXIiLCAKICAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSVBVTVMgSGVhbHRoIFN1cnZleSBEYXRhLCAyMDE5LTIwMjAgXG4gQ2FsY3VsYXRpb25zIGJ5IEpvc2VwaCBKYWl5ZW9sYSIsCiAgICAgICB4ID0gIkdlbmRlciIsCiAgICAgICB5ID0gIiUgIEZhaXIvUG9vciBIZWFsdGgiKSsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgoKCmBgYHtyfQpjYXRkb2c8LXN2eWJ5KGZvcm11bGEgPSB+YmFkaGVhbHRoLAogICAgICAgICAgICAgIGJ5ID0gfm1hbGUrb3Bwb3J0dW5pdHlfeW91dGhfY2F0LAogICAgICAgICAgICAgIGRlc2lnbiA9IGRlcywKICAgICAgICAgICAgICBGVU4gPSBzdnltZWFuLAogICAgICAgICAgICAgIG5hLnJtPVQpCgojdGhpcyBwbG90IGlzIGEgbGl0dGxlIG1vcmUgY29tcGxpY2F0ZWQsIGJ1dCBmYWNldF93cmFwKCkgcGxvdHMgc2VwYXJhdGUgcGxvdHMgZm9yIGdyb3VwcwoKY2F0ZG9nJT4lCiAgZ2dwbG90KCkrCiAgI2dlb21fcG9pbnQoYWVzKHg9ZWR1YywgeSA9IGJhZGhlYWx0aCwgY29sb3I9cmFjZV9ldGgsIGdyb3VwPXJhY2VfZXRoKSwgcG9zaXRpb249ImRvZGdlIikrIAogIGdlb21fZXJyb3JiYXIoYWVzKHg9b3Bwb3J0dW5pdHlfeW91dGhfY2F0LHkgPSBiYWRoZWFsdGgsCiAgICAgICAgICAgICAgICAgICAgeW1pbiA9IGJhZGhlYWx0aC0xLjk2KnNlLCAKICAgICAgICAgICAgICAgICAgIHltYXg9IGJhZGhlYWx0aCsxLjk2KnNlLAogICAgICAgICAgICAgICAgICAgY29sb3I9bWFsZSwKICAgICAgICAgICAgICAgICAgIGdyb3VwPW1hbGUpLAogICAgICAgICAgICAgICAgd2lkdGg9LjI1LAogICAgICAgICAgICAgICAgcG9zaXRpb249ImRvZGdlIikrCiAgI2ZhY2V0X3dyYXAofiByYWNlX2V0aCwgbnJvdyA9IDMpKwogIGxhYnModGl0bGUgPSAiUGVyY2VudCAlIG9mIFVTICB3aXRoIEZhaXIvUG9vciBIZWFsdGggYnkgR2VuZGVyIGFuZCBPcHBvciBZb3V0aCBDYXQiLCAKICAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSVBVTVMgSGVhbHRoIFN1cnZleSBEYXRhLCAyMDE5LTIwMjAgXG4gQ2FsY3VsYXRpb25zIGJ5IEpvc2VwaCBKYWl5ZW9sYSIsCiAgICAgICB4ID0gIk9wcG9ydHVuaXR5IFlvdXRoIENhdGVnb3J5IiwKICAgICAgIHkgPSAiJSAgRmFpci9Qb29yIEhlYWx0aCIpKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCmBgYHtyfQojTG9naXQgbW9kZWwKZml0LmxvZ2l0PC1zdnlnbG0oYmFkaGVhbHRoIH4gb3Bwb3J0dW5pdHlfeW91dGhfY2F0ICsgdXJiYW5fcnVyYWwgKyBtYWxlICArIGVkdWMsIAogICAgICAgICAgICAgICAgICBkZXNpZ24gPSBkZXMsCiAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGZpdC5sb2dpdCkKYGBgCgpgYGB7cn0KbGlicmFyeShndHN1bW1hcnkpCmZpdC5sb2dpdCU+JQogIHRibF9yZWdyZXNzaW9uKGV4cG9uZW50aWF0ZT1UUlVFICkKYGBgCgpgYGB7cn0KbGlicmFyeShzalBsb3QpCnBsb3RfbW9kZWwoZml0LmxvZ2l0LAogICAgICAgICAgIGF4aXMubGltID0gYyguMSwgMTApLCAjeW91IG1heSBuZWVkIHRvIG1vZGlmeSB0aGVzZQogICAgICAgICAgIHRpdGxlID0gIk9kZHMgcmF0aW9zIGZvciBQb29yIFNlbGYgUmF0ZWQgSGVhbHRoIikKYGBgCgpgYGB7cn0KbGlicmFyeShlbW1lYW5zKQpyZzwtcmVmX2dyaWQoZml0LmxvZ2l0KQoKbWFyZ19sb2dpdDwtZW1tZWFucyhvYmplY3QgPSByZywKICAgICAgICAgICAgICBzcGVjcyA9IGMoICJvcHBvcnR1bml0eV95b3V0aF9jYXQiLCAidXJiYW5fcnVyYWwiLCAibWFsZSIsICAiZWR1YyIpLAogICAgICAgICAgICAgIHR5cGU9InJlc3BvbnNlIiApCgprbml0cjo6a2FibGUobWFyZ19sb2dpdCwgIGRpZ2l0cyA9IDQpCmBgYAoKIyBHZW5lcmF0ZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBmb3Igc29tZSDigJxpbnRlcmVzdGluZ+KAnSBjYXNlcyBmcm9tIHlvdXIgYW5hbHlzaXMsIHRvIGhpZ2hsaWdodCB0aGUgZWZmZWN0cyBmcm9tIHRoZSBtb2RlbCBhbmQgeW91ciBzdGF0ZWQgcmVzZWFyY2ggcXVlc3Rpb24KCgpgYGB7cn0KY29tcHM8LWFzLmRhdGEuZnJhbWUobWFyZ19sb2dpdCkKCmNvbXBzW2NvbXBzJG9wcG9ydHVuaXR5X3lvdXRoX2NhdD09Ik9wcG9ydHVuaXR5IHlvdXRoIiAmIGNvbXBzJGVkdWMgPT0gIjRjb2xncmFkIiAmIGNvbXBzJHVyYmFuX3J1cmFsID09ICJ1cmJhbiIgLCBdCmBgYAoKYGBge3J9CmNvbXBzW2NvbXBzJG9wcG9ydHVuaXR5X3lvdXRoX2NhdD09Ik5vdCBvcHBvcnR1bml0eSB5b3V0aCIgJiBjb21wcyRlZHVjID09ICI0Y29sZ3JhZCIgJiBjb21wcyR1cmJhbl9ydXJhbCA9PSAidXJiYW4iICwgXQpgYGAKCgogCgpBY2NvcmRpbmcgdG8gdGhlIG1vZGVsLCBob2xkaW5nIHN0YXlpbmcgaW4gYSB1cmJhbiBlbnZpcm9ubWVudCBhbmQgYmVpbmcgYSBjb2xsZWdlIGdyYWQgY29uc3RhbnQsIG9wcG9ydHVuaXR5IHlvdXRocyBoYXZlIGhpZ2hlciBwcm9iYWJpbGl0eSBvZiByZXBvcnRpbmcgZmFpci9wb29yIHNlbGYgaGVhbHRoIHJhdGluZyBjb21wYXJlZCB0byBjb25uZWN0ZWQgeW91dGguIEFuZCB0aGlzIGlzIHRoaXMgZm9yIGJvdGggbWFsZSBhbmQgZmVtYWxlIAo=