Dataset
The dataset is data from the 2021 National Health Interview Adult
Survey. The survey contained questions related to household and family
composition, demographics about the survey taker, satisfaction with
life, health insurance, medication, immunization, preventive screenings,
and multiple health problems such as hypertension, cardiovascular
conditions, cancer, vision, hearing, mobility, and more.
This survey is important in following the health of American’s based
on many different factors of their lives. Looking at previous surveys
can also help to see trends in Americans’ health.
For the data used, responses of “refused”,“don’t know” and “not
ascertained” were filtered out as these responses had a tendency to be
much smaller than the others and were not helpful for what was being
looked at.
Columns
General Health
1. Excellent
2. Very Good
3. Good
4. Fair
5. Poor
Life Satisfaction
1. Very Satisfied
2. Satisfied
3. Dissatisfied
4. Very Dissatisfied
Race (Single and Multiple Race Groups)
1. White only
2. Black/African American only
3. Asian only
4. AIAN only (American Indians and Alaska Natives)
5. AIAN and any other group
6. Other
7. Hispanic who did not identify with one of the other categories
Education Level
0. Never attended/Kindergarten only
1. Grade 1-11
2. 12th grade, nodiploma
3. GED or equivalent
4. High School Graduate
5. Some college, nodegree
6. Associate degree: occupational, technical, or vocational program
7. Associate degree: academic program
8. Bachelor's degree
9. Master's degree
10. Professional School or Doctoral degree
BMI
1. Underweight
2. Normal
3. Overweight
4. Obese
Vision
Do you wear glasses or contact lenses?
1. Yes
2. No
Do you have difficulty seeing?
1. No difficulty
2. Some difficulty
3. A lot of difficulty
4. Cannot do at all
Cancer
Separate columns for each type of cancer.
Number of reported types of cancer.
0. No cancer
1-3. 1 to 3
4. 4 or more
Demographics
Looking at demographics can help to give a bit of an idea about what
sort of data we should look at.
Sex
dfSexFilter <- adult22 %>%
filter(SEX_A == 1 | SEX_A == 2)
dfSexFilter <-
dfSexFilter |>
group_by(dfSexFilter$SEX_A) |>
mutate(Sex_Status = ifelse(SEX_A == 1,
"Male",
"Female")) |>
ungroup()
ggplot(dfSexFilter, aes(x = Sex_Status, fill=Sex_Status)) + xlab("Sex") +
geom_bar()

Age
The far right bar, 85, is for those who are 85+.
dfAgeFilter <- adult22 %>%
filter(AGEP_A < 86)
ggplot(dfAgeFilter, aes(x = AGEP_A)) + xlab("Age") +
geom_bar()

The largest group based on age were those that were 85 or older.
Education Level
dfEduFilter <- adult22 %>%
filter(EDUCP_A < 97)
dfEduFilter <-
dfEduFilter |>
group_by(dfEduFilter$EDUCP_A) |>
mutate(Edu_Status = ifelse(EDUCP_A == 1,
"Grade 1-11",
ifelse(EDUCP_A == 2,
"12th Grade, no Diploma",
ifelse(EDUCP_A == 3,
"GED or Equivalent",
ifelse(EDUCP_A == 4,
"High School Graduate",
ifelse(EDUCP_A == 5,
"Some College, no Degree",
ifelse(EDUCP_A == 6,
"Associate degree: occupational, technical, or vocational program",
ifelse(EDUCP_A == 7,
"Associate degree: academic program",
ifelse(EDUCP_A == 8,
"Bachelor's degree",
ifelse(EDUCP_A == 9,
"Master's degree ",
ifelse(EDUCP_A == 10,
"Professional School or Doctoral degree",
ifelse(EDUCP_A == 97,
"Refused",
"Don't Know")))))))))))) |>
ungroup()
dfEduFilter$Edu_Status <- factor(dfEduFilter$Edu_Status, levels = c("Grade 1-11", "12th Grade, no Diploma", "GED or Equivalent","High School Graduate", "Some College, no Degree", "Associate degree: occupational, technical, or vocational program", "Associate degree: academic program", "Bachelor's degree", "Master's degree ", "Professional School or Doctoral degree", "Refused", "Don't Know"))
ggplot(dfEduFilter, aes(x = EDUCP_A, fill=Edu_Status)) +
geom_bar() + theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank()) + xlab("Education Level")

Race
dfRaceFilter <- adult22 %>%
filter(RACEALLP_A <= 8 )
dfRaceFilter2 <- dfRaceFilter %>%
filter(RACEALLP_A != 7 )
dfRaceFilter2 <-
dfRaceFilter2 |>
group_by(dfRaceFilter2$RACEALLP_A) |>
mutate(Race = ifelse(RACEALLP_A == 1,
"White",
ifelse(RACEALLP_A == 2,
"African American/Black",
ifelse(RACEALLP_A == 3,
"Asian",
ifelse(RACEALLP_A == 4,
"AIAN*",
ifelse(RACEALLP_A == 5,
"AIAN + Other Group",
ifelse(RACEALLP_A == 6,
"Other",
ifelse(RACEALLP_A == 8,
"Hispanic**",
"Don't Know")))))))) |>
ungroup()
ggplot(dfRaceFilter2, aes(x = Race, fill=Race)) +
geom_bar() + theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())

There was a much larger amount of those who identified as white who
took the survey.
General Physical Health
dfGHFilter <- adult22 %>%
filter(PHSTAT_A < '7')
ggplot(dfGHFilter, aes(x = factor(PHSTAT_A))) + scale_x_discrete(labels=c("Excellent", "Very Good", "Good", "Fair", "Poor")) +
geom_bar() +
xlab("General Physical Health")

NA
NA
NA
Most people put their General Physical Health in the more positive
side (Excellent, Very good, Good) side of the scale.
Life Satisfaction
dfFilteredLS <- adult22 %>%
filter(LSATIS4_A < '5')
ggplot(dfFilteredLS, aes(x = factor(LSATIS4_A))) + scale_x_discrete(labels=c("Very Satisfied", "Satisfied", "Dissatisfied", "Very Dissatisfied")) +
geom_bar() +
xlab("Life Satisfaction")

NA
NA
NA
NA
Most people considered themselves to be positively satisfied with
life. The difference between the positive and negative side of the scale
was larger than for General Physical Health.
BMI
BMI can often be contributed to health and certain levels can be
contributed to health issues. However, BMI is fundamentally flawed as it
does not take into consideration muscle fat. For example, a body builder
could be considered to have an “overweight” BMI, but would be much
healthier than someone who had mostly non-muscle fat.
Histogram
hist(dfFilteredBMI$BMICAT_A)

The distribution was relatively equal, except for the Underweight
category, so there was a potential for this category to cause
problems.
Bootstrap
This is to help us get a better idea of the average Life Satisfaction
and General Physical Health based on a person’s BMI category, by
creating samples.
dfFilteredLSBMI <- adult22 %>%
filter(BMICAT_A < 5 & LSATIS4_A <5)
dfFilteredPHBMI <- adult22 %>%
filter(BMICAT_A < 5 & PHSTAT_A <7)
boot_ci <- function (v, func = median, conf = 0.95, n_iter = 100) {
boot_func <- \(x, i) func(x[i])
b <- boot(v, boot_func, R = n_iter)
b <- boot.ci(b, conf = conf, type = "perc")
return(c("lower" = b$percent[4],
"upper" = b$percent[5]))
}
Bootstrap: Life Satisfaction vs BMI
df_ciLS <- dfFilteredLSBMI |>
group_by(BMICAT_A) |>
summarise(ci_lower = boot_ci(LSATIS4_A, mean)['lower'],
mean_LS = mean(LSATIS4_A),
ci_upper = boot_ci(LSATIS4_A, mean)['upper'])
df_ciLS |>
ggplot() +
geom_errorbarh(mapping = aes(y = BMICAT_A,
xmin=ci_lower, xmax=ci_upper,
color = '95% C.I.'), height = 0.5) +
geom_point(mapping = aes(x = mean_LS, y = BMICAT_A,
color = 'Group Mean'),
shape = '|',
size = 5) +
scale_color_manual(values=c('black', 'red')) +
theme_minimal() +
labs(title = "Life Satisfaction by BMI Category",
x = "Life Satisfaction",
y = "BMI Category",
color = '')

Category 1, underweight, seems to have a much larger range than the
other 3, which like stated above, could be an issue because of how small
the distribution was.
Bootstrap: General Physical Health vs BMI
df_ciPH <- dfFilteredPHBMI |>
group_by(BMICAT_A) |>
summarise(ci_lower = boot_ci(PHSTAT_A, mean)['lower'],
mean_PH = mean(PHSTAT_A),
ci_upper = boot_ci(PHSTAT_A, mean)['upper'])
df_ciPH |>
ggplot() +
geom_errorbarh(mapping = aes(y = BMICAT_A,
xmin=ci_lower, xmax=ci_upper,
color = '95% C.I.'), height = 0.5) +
geom_point(mapping = aes(x = mean_PH, y = BMICAT_A,
color = 'Group Mean'),
shape = '|',
size = 5) +
scale_color_manual(values=c('black', 'red')) +
theme_minimal() +
labs(title = "General Health by BMI Category",
x = "General Health",
y = "BMI Category",
color = '')

There were way less people in the underweight BMI (1) than the other
categories, similar to the issue in Life Satisfaction, so that group
does not give as much information, or as accurate of information as the
others and was removed for the graphs below.
General Health by BMI Status
dfBMIGH <- adult22 %>%
filter(PHSTAT_A < 7)
dfNormalBMI <- dfBMIGH %>%
filter(BMICAT_A == 2 )
dfOverBMI <- dfBMIGH %>%
filter(BMICAT_A == 3 )
dfObeseBMI <- dfBMIGH %>%
filter(BMICAT_A == 4 )
BMIGH <- data.frame(
Status = c(2, 3, 4),
Physical_Health= c( mean(dfNormalBMI$PHSTAT_A), mean(dfOverBMI$PHSTAT_A), mean(dfObeseBMI$PHSTAT_A)))
ggplot(BMIGH, aes(x = factor(Status), y = Physical_Health)) +
geom_point() +
scale_x_discrete(labels= c( "Normal", "Overweight", "Obese")) +
xlab("BMI Status") +
ylab("Average General Physical Health")

NA
NA
Life Satisfaction by BMI Status
dfBMILS <- adult22 %>%
filter(LSATIS4_A < 5)
dfNormalBMILS <- dfBMILS %>%
filter(BMICAT_A == 2 )
dfOverBMILS <- dfBMILS %>%
filter(BMICAT_A == 3 )
dfObeseBMILS <- dfBMILS %>%
filter(BMICAT_A == 4 )
BMILS <- data.frame(
Status = c(2, 3, 4),
Life_Satis= c( mean(dfNormalBMILS$LSATIS4_A), mean(dfOverBMILS$LSATIS4_A), mean(dfObeseBMILS$LSATIS4_A)))
ggplot(BMILS, aes(x = factor(Status), y = Life_Satis)) +
geom_point() +
scale_x_discrete(labels= c("Normal", "Overweight", "Obese")) +
xlab("BMI Status") +
ylab("Average Life Satisfaction")

NA
NA
Education Level
Vs General Physical Health
dfFilteredEdu <- dfGHFilter %>%
filter(EDUCP_A < 97)
df_ciEdu <- dfFilteredEdu |>
group_by(EDUCP_A) |>
summarise(ci_lower = boot_ci(PHSTAT_A, mean)['lower'],
mean_PH = mean(PHSTAT_A),
ci_upper = boot_ci(PHSTAT_A, mean)['upper'])
df_ciEdu |>
ggplot() +
geom_errorbarh(mapping = aes(y = EDUCP_A,
xmin=ci_lower, xmax=ci_upper,
color = '95% C.I.'), height = 0.5) +
geom_point(mapping = aes(x = mean_PH, y = EDUCP_A,
color = 'Group Mean'),
shape = '|',
size = 5) +
scale_color_manual(values=c('black', 'red')) +
theme_minimal() +
labs(title = "General Physical Health by Education",
x = "Physical Health",
y = "Education",
color = '')

We can see that as a person’s education level decreases, their
average physical health generally decreases, however it was still in the
same physical health category. There seems to be a few groups forming,
such as the bottom 3, the middle 4, and the top 3.
Vs Life Satisfaction
dfFilteredEduLS <- dfFilteredLS %>%
filter(EDUCP_A < 97)
df_ciEduLS <- dfFilteredEduLS |>
group_by(EDUCP_A) |>
summarise(ci_lower = boot_ci(LSATIS4_A, mean)['lower'],
mean_LS = mean(LSATIS4_A),
ci_upper = boot_ci(LSATIS4_A, mean)['upper'])
df_ciEduLS |>
ggplot() +
geom_errorbarh(mapping = aes(y = EDUCP_A,
xmin=ci_lower, xmax=ci_upper,
color = '95% C.I.'), height = 0.5) +
geom_point(mapping = aes(x = mean_LS, y = EDUCP_A,
color = 'Group Mean'),
shape = '|',
size = 5) +
scale_color_manual(values=c('black', 'red')) +
theme_minimal() +
labs(title = "Life Satisfaction by Education",
x = "Life Satisfaction",
y = "Education",
color = '')

Similar to general health, there is a trend of as education level
decreases, life satisfaction decreases.
Vision
dfFilteredVis <- adult22 %>%
filter(VISIONDF_A <4)
hist(dfFilteredVis$VISIONDF_A)

hist(dfFilteredVis$WEARGLSS_A)

Vision vs General Physical Health
dfGlasses <- adult22 %>%
filter(PHSTAT_A < 5)
dfNoGlasses <- dfGlasses %>%
filter(WEARGLSS_A == '2')
dfWearGlasses <- dfGlasses %>%
filter(WEARGLSS_A== '1' )
WearGlasses <- data.frame(
Status = c(1, 2),
Gen_Health= c(mean(dfWearGlasses$PHSTAT_A), mean(dfNoGlasses$PHSTAT_A)))
ggplot(WearGlasses, aes(x = factor(Status), y = Gen_Health)) +
geom_point() +
scale_x_discrete(labels= c("Wear Glasses/Contacts", "No Glasses/Contacts")) +
xlab("")+
ylab("Average Physical Health")

dfVision <- dfFilteredVis %>%
filter(PHSTAT_A < 5)
dfNoneVis <- dfVision %>%
filter(VISIONDF_A == '1')
dfSomeVis <- dfVision %>%
filter(VISIONDF_A== '2' )
dfAlotVis <- dfVision %>%
filter(VISIONDF_A== '3' )
dfCannotVis <- dfVision %>%
filter(VISIONDF_A== '4' )
VisDifficulty <- data.frame(
Status = c(1, 2,3,4),
Gen_Health= c(mean(dfNoneVis$PHSTAT_A), mean(dfSomeVis$PHSTAT_A), mean(dfAlotVis$PHSTAT_A), mean(dfCannotVis$PHSTAT_A)))
ggplot(VisDifficulty, aes(x = factor(Status), y = Gen_Health)) +
geom_point() +
scale_x_discrete(labels= c("None", "Some", "A Lot","Cannot See")) +
xlab("Difficulty Seeing") +
ylab("Average Physical Health")

Vision vs Life Satisfaction
dfGlassesLS <- adult22 %>%
filter(LSATIS4_A < 7)
dfNoGlassesLS <- dfGlassesLS %>%
filter(WEARGLSS_A == '2')
dfWearGlassesLS <- dfGlassesLS %>%
filter(WEARGLSS_A== '1' )
WearGlassesLS <- data.frame(
Status = c(1, 2),
Life_Satis= c(mean(dfWearGlassesLS$LSATIS4_A), mean(dfNoGlassesLS$LSATIS4_A)))
ggplot(WearGlassesLS, aes(x = factor(Status), y = Life_Satis)) +
geom_point() +
scale_x_discrete(labels= c("Wear Glasses/Contacts", "No Glasses/Contacts")) +
xlab("")+
ylab("Average Life Satisfaction")

Difficulty Seeing and Life Satisfaction
dfVisionLS <- dfFilteredVis %>%
filter(LSATIS4_A < 7)
dfNoneVisLS <- dfVisionLS %>%
filter(VISIONDF_A == '1')
dfSomeVisLS <- dfVisionLS %>%
filter(VISIONDF_A== '2' )
dfAlotVisLS <- dfVisionLS %>%
filter(VISIONDF_A== '3' )
dfCannotVisLS <- dfVisionLS %>%
filter(VISIONDF_A== '4' )
VisDifficultyLS <- data.frame(
Status = c(1, 2,3,4),
Life_Satis= c(mean(dfNoneVisLS$LSATIS4_A), mean(dfSomeVisLS$LSATIS4_A), mean(dfAlotVisLS$LSATIS4_A), mean(dfCannotVisLS$LSATIS4_A)))
ggplot(VisDifficultyLS, aes(x = factor(Status), y = Life_Satis)) +
geom_point() +
scale_x_discrete(labels= c("None", "Some", "A Lot","Cannot See")) +
xlab("Difficulty Seeing") +
ylab("Average Life Satisfaction")

For both physical health and life satisfaction, there was a decrease
for those who wear glasses/contacts. Since people can be split into
positive and negative life satisfaction, we can try a binary
response.
dfVisionAll <- dfFilteredVis %>%
filter(WEARGLSS_A< '3' )
dfVisionAllLS <-
dfVisionAll |>
group_by(dfVisionAll$LSATIS4_A) |>
mutate(LifeSatis_Status = ifelse(LSATIS4_A == 1,
0,
ifelse(LSATIS4_A == 2,
0,
1))) |>
ungroup()
model <- glm(LifeSatis_Status ~ VISIONDF_A, data = dfVisionAllLS,
family = binomial(link = 'logit'))
model$coefficients
(Intercept) VISIONDF_A
-4.325735 1.004927
sigmoid <- \(x) 1 / (1 + exp(-(-4.325735 + 1.004927 * x)))
dfVisionAllLS |>
ggplot(mapping = aes(x = VISIONDF_A, y = LifeSatis_Status)) +
geom_jitter(width = 0, height = 0.1, shape = 'O', size = 3) +
geom_function(fun = sigmoid, color = 'blue', linewidth = 1) +
labs(title = "Life Satisfaction Binary Response - Difficulty Seeing") +
scale_y_continuous(breaks = c(0, 1)) +
theme_minimal()

Between Positive Life Satisfaction(0) and Negative Life
Satisfaction(1). We can see that there is a small increase in
probability that as someone’s vision gets worst, the life satisfaction
will become more negative.
Smoking
Smoking, Life Satisfaction, and General Health
- Current, every day smoker
- Current, some days smoker
- Former smoker
- Non-Smoker
dfFilteredLSSmoke <- dfFilteredLS %>%
filter(SMKCIGST_A < 5)
dfFilteredLSSmoke |>
ggplot(mapping = aes(x = SMKCIGST_A, y = LSATIS4_A)) +
geom_point(size = 2) +
geom_smooth(method = "lm", se = FALSE, color = 'darkblue') +
theme_minimal() + xlab("Smoking Status") + ylab("Life Satisfaction")

dfFilteredPHSmoke <- dfGHFilter %>%
filter(SMKCIGST_A < 5)
dfFilteredPHSmoke |>
ggplot(mapping = aes(x = SMKCIGST_A, y = PHSTAT_A)) +
geom_point(size = 2) +
geom_smooth(method = "lm", se = FALSE, color = 'darkblue') +
theme_minimal() + xlab("Smoking Status") + ylab("General Health")

NA
NA
There is a bit of a decrease in life satisfaction and general health
the more someone smokes.
Smoking and Lung Cancer - Binary Response
We can split people up into someone who has smoked and someone who
has not smoked, so we can try a binary response.
dfSmokeCan <- adult22 %>%
filter(SMKCIGST_A < 5 & LUNGCAN_A <3)
dfSmokeCan <-
dfSmokeCan |>
group_by(dfSmokeCan$SMKCIGST_A) |>
mutate(Smoke = ifelse(SMKCIGST_A == "4",
0,
1)) |>
ungroup()
model <- glm(Smoke ~ LUNGCAN_A, data = dfSmokeCan,
family = binomial(link = 'logit'))
model$coefficients
(Intercept) LUNGCAN_A
3.264507 -1.755153
sigmoid <- \(x) 1 / (1 + exp(-(3.264507 -1.755153 * x)))
dfSmokeCan |>
ggplot(mapping = aes(x = LUNGCAN_A, y = Smoke)) +
geom_jitter(width = 0, height = 0.1, shape = 'O', size = 3) +
geom_function(fun = sigmoid, color = 'blue', linewidth = 1) +
labs(title = "Binary Response: Lung Cancer and Smoking") +
scale_y_continuous(breaks = c(0, 1)) +
theme_minimal()

This graph shows that for those who have lung cancer (1), there is a
higher probability of them being a smoker or former smoker(1).
100 Cigarettes Smoked and Lung Cancer - Binary Response
We can also split the smokers up into those who have smoked 100
cigarettes, and those who have not.
dfSmoke100 <- adult22 %>%
filter(SMKEV_A < 3 & LUNGCAN_A <3)
dfSmoke100Can <-
dfSmoke100 |>
group_by(dfSmoke100$SMKEV_A) |>
mutate(Smoke_100 = ifelse(SMKEV_A == "2",
0,
1)) |>
ungroup()
model <- glm(Smoke_100 ~ LUNGCAN_A, data = dfSmoke100Can,
family = binomial(link = 'logit'))
model$coefficients
(Intercept) LUNGCAN_A
3.263094 -1.753740
sigmoid <- \(x) 1 / (1 + exp(-(3.263094 -1.753740 * x)))
dfSmoke100Can |>
ggplot(mapping = aes(x = LUNGCAN_A, y = Smoke_100)) +
geom_jitter(width = 0, height = 0.1, shape = 'O', size = 3) +
geom_function(fun = sigmoid, color = 'blue', linewidth = 1) +
labs(title = "Binary Response: Lung Cancer and Smoked 100 Cigarettes") +
scale_y_continuous(breaks = c(0, 1)) +
theme_minimal()

This graph shows that for those who have lung cancer (1), there is a
higher probability of them having smoked 100 cigarettes(1). The model is
extremely close to the previous model. So, how many of the smokers with
lung cancer smoked 100 cigarettes?
LungCan <- nrow(dfSmoke100[dfSmoke100$LUNGCAN_A == '1',])
Smoked100 <- nrow(dfSmoke100[dfSmoke100$SMKEV_A == '1',])
Smoked100Can <- nrow(dfSmoke100[dfSmoke100$SMKEV_A == '1' & dfSmoke100$LUNGCAN_A == '1', ])
NotSmoked100Can <- nrow(dfSmoke100[dfSmoke100$SMKEV_A == '2' & dfSmoke100$LUNGCAN_A == '1', ])
LungCan
[1] 116
Smoked100Can
[1] 95
95/116*100
[1] 81.89655
Smoked100
[1] 1511
NotSmoked100Can
[1] 21
95/1511*100
[1] 6.287227
Out of 116 people who stated they have lung cancer, 95 people, or
81.9% had smoked at least 100 cigarettes. But out of 1511 people who
have smoked at least 100 cigarettes, only 21, or 6.3% have lung
cancer.
Covid
Month of last Covid vaccine for those who got it for the first
time.
fCovidVax <- adult22
dfCovidVaxFirst <- dfCovidVax %>%
filter(CVDVAC1M_A != 'NA' & CVDVAC1Y_A !='NA')
dfCovidVaxLast <- dfCovidVax %>%
filter(CVDVAC2M_A != 'NA' & CVDVAC2Y_A !='NA')
dfCovidVaxFirst$LastCovidVaxFirstTime <- with(dfCovidVaxFirst, sprintf("%d-01-%02d", CVDVAC1M_A, CVDVAC1Y_A))
dfCovidVaxLast$LastCovidVaxNotFirstTime <- with(dfCovidVaxLast, sprintf("%d-01-%02d", CVDVAC2M_A, CVDVAC2Y_A))
dfCovidVaxFirst_ <- dfCovidVaxFirst %>%
filter(CVDDIAG_A < 3)
dfCovidVaxLast_ <- dfCovidVaxLast %>%
filter(CVDDIAG_A < 3)
dfCovidVaxFirst1 <- dfCovidVaxFirst_ |>
select(LastCovidVaxFirstTime, CVDDIAG_A)
dfCovidVaxLast1 <- dfCovidVaxLast_ |>
select(LastCovidVaxNotFirstTime, CVDDIAG_A)
dftransf <- dfCovidVaxFirst1 |>
select(LastCovidVaxFirstTime, CVDDIAG_A)
dftransf['date']<- as.Date(dftransf$LastCovidVaxFirstTime, format="%m-%d-%Y")
dftransfilt <- dftransf %>% filter(!is.na(date))
dfFirstV <- dftransfilt |>
select(date, CVDDIAG_A)
dffirstVCount<- dfFirstV %>% group_by(date) %>%tally()
dfMerge <- merge(dffirstVCount, dfFirstVSum, by = "date", all.x=TRUE, all.y=TRUE)
dfMerge['percent'] = dfMerge['Frequency']/dfMerge['n']
dfMerge <- dfMerge %>% filter(percent >.0000001)
dfMerge |>
ggplot(mapping = aes(x = date, y = n)) +
geom_line() +
labs(title = "Date of First Covid Vaccine") +
theme_hc() +
scale_x_date(date_labels = "%Y (%b)") + ylab("Number of People")

The first vaccine came out in Dec 2021, which is around where the
graph starts to increase. There was an increase in April and May 2021.
In June 2021 when it started to decrease, there was a slowdown in people
getting the vaccine and a record low number of cases.
Source: https://www.kff.org/coronavirus-covid-19/poll-finding/kff-covid-19-vaccine-monitor-june-2021/
On September 9 2021, Biden made an announcement requiring federal
employees to be vaccinated by the end of January 2022, which is around
the time of the largest peak between Sept 2021 and January 2022.
Source: https://www.whitehouse.gov/briefing-room/presidential-actions/2021/09/09/executive-order-on-requiring-coronavirus-disease-2019-vaccination-for-federal-employees/
Cancer
Cancer by Sex
Told has cancer.
dfFemale = adult22 %>%
filter(SEX_A == 2)
dfFemaleCan = dfFemale %>%
filter(CANEV_A == 1)
dfMale = adult22 %>%
filter(SEX_A == 1)
dfMaleCan = dfMale %>%
filter(CANEV_A == 1)
TotalF <- nrow(dfFemale)
TotalM <- nrow(dfMale)
PercentF <- (nrow(dfFemaleCan)/nrow(dfFemale))*100
PercentM <- (nrow(dfMaleCan)/nrow(dfMale))*100
PercentCan <- data.frame(
Sex = c("Female", "Male"),
Percent= c((PercentF), (PercentM)))
ggplot(PercentCan, aes(x = Sex, y=Percent)) +
geom_point()

Percent by Type of Cancer
dfCan <- adult22 %>%
filter(NUMCAN_A < 7 & NUMCAN_A !=0)
dfBlad <- dfCan %>%
filter(BLADDCAN_A == 1)
dfBlood <- dfCan %>%
filter(BLOODCAN_A == 1)
dfBrain <- dfCan %>%
filter(BRAINCAN_A == 1)
dfBone <- dfCan %>%
filter(BONECAN_A == 1)
dfBreast <- dfCan %>%
filter(BREASCAN_A == 1)
dfCervical <- dfCan %>%
filter(CERVICAN_A == 1)
dfEsoph <- dfCan %>%
filter(BLADDCAN_A == 1)
dfGall <- dfCan %>%
filter(ESOPHCAN_A == 1)
dfLarynx <- dfCan %>%
filter(LARYNCAN_A == 1)
dfLeuk <- dfCan %>%
filter(LEUKECAN_A == 1)
dfLiver <- dfCan %>%
filter(LIVERCAN_A == 1)
dfLung <- dfCan %>%
filter(LUNGCAN_A == 1)
dfLymph <- dfCan %>%
filter(LYMPHCAN_A == 1)
dfMela <- dfCan %>%
filter(MELANCAN_A == 1)
dfMouth <- dfCan %>%
filter(MOUTHCAN_A == 1)
dfOvary <- dfCan %>%
filter(OVARYCAN_A == 1)
dfPanc <- dfCan %>%
filter(PANCRCAN_A== 1)
dfProst <- dfCan %>%
filter(PROSTCAN_A == 1)
dfSkinMela <- dfCan %>%
filter(SKNMCAN_A == 1)
dfSkinNoMela <- dfCan %>%
filter(SKNNMCAN_A == 1)
dfSkinUnknown <- dfCan %>%
filter(SKNDKCAN_A == 1)
dfStomach <- dfCan %>%
filter(STOMACAN_A == 1)
dfThroat <- dfCan %>%
filter(THROACAN_A == 1)
dfThyroid <- dfCan %>%
filter(THYROCAN_A == 1)
dfUterus <- dfCan %>%
filter(UTERUCAN_A == 1)
dfHandNeck <- dfCan %>%
filter(HDNCKCAN_A == 1)
dfColRec <- dfCan %>%
filter(COLRCCAN_A == 1)
dfOther <- dfCan %>%
filter(OTHERCANP_A == 1)
TBladF <- nrow(dfBlad %>%
filter(SEX_A == 2))/TotalF*100
TBloodF <- nrow(dfBlood %>%
filter(SEX_A == 2))/TotalF*100
TBoneF <- nrow(dfBone %>%
filter(SEX_A == 2))/TotalF*100
TBrainF <- nrow(dfBrain %>%
filter(SEX_A == 2))/TotalF*100
TBreastF <- nrow(dfBreast %>%
filter(SEX_A == 2))/TotalF*100
TEsophF <- nrow(dfEsoph %>%
filter(SEX_A == 2))/TotalF*100
TCervF <- nrow(dfCervical %>%
filter(SEX_A == 2))/TotalF*100
TGallF <- nrow(dfGall %>%
filter(SEX_A == 2))/TotalF*100
TLarynxF <- nrow(dfLarynx %>%
filter(SEX_A == 2))/TotalF*100
TLeukF <- nrow(dfLeuk %>%
filter(SEX_A == 2))/TotalF*100
TLungF <- nrow(dfLung %>%
filter(SEX_A == 2))/TotalF*100
TLiverF <- nrow(dfLiver %>%
filter(SEX_A == 2))/TotalF*100
TMelaF <- nrow(dfMela %>%
filter(SEX_A == 2))/TotalF*100
TMouthF <- nrow(dfMouth %>%
filter(SEX_A == 2))/TotalF*100
TOvaryF <- nrow(dfOvary %>%
filter(SEX_A == 2))/TotalF*100
TPancF <- nrow(dfBlad %>%
filter(SEX_A == 2))/TotalF*100
TSkinMelaF <- nrow(dfSkinMela %>%
filter(SEX_A == 2))/TotalF*100
TSkinNoMelaF <- nrow(dfSkinNoMela %>%
filter(SEX_A == 2))/TotalF*100
TSkinUnknownF <- nrow(dfSkinUnknown %>%
filter(SEX_A == 2))/TotalF*100
TStomachF <- nrow(dfStomach %>%
filter(SEX_A == 2))/TotalF*100
TThyroidF <- nrow(dfThyroid %>%
filter(SEX_A == 2))/TotalF*100
TThroatF <- nrow(dfThroat %>%
filter(SEX_A == 2))/TotalF*100
TUterusF <- nrow(dfUterus %>%
filter(SEX_A == 2))/TotalF*100
THandNeckF <- nrow(dfHandNeck %>%
filter(SEX_A == 2))/TotalF*100
TColRecF <- nrow(dfColRec %>%
filter(SEX_A == 2))/TotalF*100
TOtherF <- nrow(dfOther %>%
filter(SEX_A == 2))/TotalF*100
Cancer Among Females
CancerF <- data.frame(
Cancer = c("Bladder", "Blood","Brain","Bone","Breast","Esophagus","Cervical","GallBladder","Larynx","Leukemia","Lung","Liver","Melanoma","Mouth","Ovarian","Pancreas","Skin Melanoma","Skin-Not Melanoma","Skin-Unknown","Stomach","Thyroid","Throat","Uterus","Hand and Neck","ColonRectal","Other"),
Percent= c((TBladF), (TBloodF),(TBrainF),(TBoneF),(TBreastF),(TEsophF),(TCervF),(TGallF),(TLarynxF),(TLeukF),(TLungF),(TLiverF),(TMelaF),(TMouthF),(TOvaryF),(TPancF),(TSkinMelaF),(TSkinNoMelaF),(TSkinUnknownF),(TStomachF),(TThyroidF),(TThroatF),(TUterusF),(THandNeckF),(TColRecF),(TOtherF)))
ggplot(CancerF, aes(x = Percent, y=Cancer)) +
geom_point() + labs(title = "Cancer Among Females")

Cancer Among Males
TBladM <- nrow(dfBlad %>%
filter(SEX_A == 1))/TotalM*100
TBloodM <- nrow(dfBlood %>%
filter(SEX_A == 1))/TotalM*100
TBoneM <- nrow(dfBone %>%
filter(SEX_A == 1))/TotalM*100
TBrainM <- nrow(dfBrain %>%
filter(SEX_A == 1))/TotalM*100
TBreastM <- nrow(dfBreast %>%
filter(SEX_A == 1))/TotalM*100
TEsophM <- nrow(dfEsoph %>%
filter(SEX_A == 1))/TotalM*100
TGallM <- nrow(dfGall %>%
filter(SEX_A == 1))/TotalM*100
TLarynxM <- nrow(dfLarynx %>%
filter(SEX_A == 1))/TotalM*100
TLeukM <- nrow(dfLeuk %>%
filter(SEX_A == 1))/TotalM*100
TLungM <- nrow(dfLung %>%
filter(SEX_A == 1))/TotalM*100
TLiverM <- nrow(dfLiver %>%
filter(SEX_A == 1))/TotalM*100
TMelaM <- nrow(dfMela %>%
filter(SEX_A == 1))/TotalM*100
TMouthM <- nrow(dfMouth %>%
filter(SEX_A == 1))/TotalM*100
TPancM <- nrow(dfPanc %>%
filter(SEX_A == 1))/TotalM*100
TProstM <- nrow(dfProst %>%
filter(SEX_A == 1))/TotalM*100
TSkinMelaM <- nrow(dfSkinMela %>%
filter(SEX_A == 1))/TotalM*100
TSkinNoMelaM <- nrow(dfSkinNoMela %>%
filter(SEX_A == 1))/TotalM*100
TSkinUnknownM <- nrow(dfSkinUnknown %>%
filter(SEX_A == 1))/TotalM*100
TStomachM <- nrow(dfStomach %>%
filter(SEX_A == 1))/TotalM*100
TThyroidM <- nrow(dfThyroid %>%
filter(SEX_A == 1))/TotalM*100
TThroatM <- nrow(dfThroat %>%
filter(SEX_A == 1))/TotalM*100
THandNeckM <- nrow(dfHandNeck %>%
filter(SEX_A == 1))/TotalM*100
TColRecM <- nrow(dfColRec %>%
filter(SEX_A == 1))/TotalM*100
TOtherM <- nrow(dfOther %>%
filter(SEX_A == 1))/TotalM*100
CancerM <- data.frame(
Cancer = c("Bladder", "Blood","Brain","Bone","Breast","Esophagus","GallBladder","Larynx","Leukemia","Lung","Liver","Melanoma","Mouth","Pancreas","Skin Melanoma","Skin-Not Melanoma","Skin-Unknown","Stomach","Thyroid","Throat","Hand and Neck","ColonRectal","Other"),
Percent= c((TBladM), (TBloodM),(TBrainM),(TBoneM),(TBreastM),(TEsophM),(TGallM),(TLarynxM),(TLeukM),(TLungM),(TLiverM),(TMelaM),(TMouthM),(TPancM),(TSkinMelaM),(TSkinNoMelaM),(TSkinUnknownM),(TStomachM),(TThyroidM),(TThroatM),(THandNeckM),(TColRecM),(TOtherM)))
ggplot(CancerM, aes(x = Percent, y=Cancer)) +
geom_point() + labs(title = "Cancer Among Males")

Cancer Among Both
df_Canmerge <- merge(CancerF,CancerM,by="Cancer", all.x = TRUE)
names(df_Canmerge)[names(df_Canmerge) == "Percent.x"] <- "Female"
names(df_Canmerge)[names(df_Canmerge) == "Percent.y"] <- "Male"
dfCancerMerged <- melt(df_Canmerge, id.vars="Cancer")
names(dfCancerMerged)[names(dfCancerMerged) == "value"] <- "Percent"
names(dfCancerMerged)[names(dfCancerMerged) == "variable"] <- "Sex"
ggplot(dfCancerMerged, aes(Percent,Cancer, col=Sex)) +
geom_point() + labs(title = "Cancer Among Males and Females")

Both males and females had a higher percentage for Skin-Not Melanoma
cancer. The highest percentage for cancer was breast cancer in
females.In many of the cancer categories, females had a slightly lower
percentage.
Summary
While many of the ways to stay healthy are commonly known and
advertised, it is interesting to look at the data to get a more specific
idea. While many of these did not have much of a difference between
categories, there is some information that can be gained that follow
many of the health ideas we already know. These include
- It is less healthier, mentally and physically, for you to smoke.
Smoking at least 100 cigarettes can make this worst and if you end up
with lung cancer, it could be contributed to you smoking.
- Cancer is important to watch out for, and there are some
specifically that are more common based on your sex and overall more
common.
- While it is mostly unavoidable, those who have difficulty seeing can
have worst life satisfaction, so if you can get it fixed by surgery or
glasses/contacts, it will be helpful.
- It is better to for your mental and physical health to stay around a
normal BMI. However, this could be argued based on if your weight comes
from non-muscle fat or muscle fat.
- A higher education could potentially lead you to feel more satisfied
and have better health.
LS0tCnRpdGxlOiAiMjAyMSBOYXRpb25hbCBIZWFsdGggSW50ZXJ2aWV3IEFkdWx0IFN1cnZleSIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBtYXJrZG93bjogCiAgICB3cmFwOiA3MgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCgogYWR1bHQyMiA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvRGF0YURpdmUvYWR1bHQyMi5jc3YiKQogCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdhcG1pbmRlcikKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KGVmZnNpemUpCmxpYnJhcnkocHdyc3MpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkobGluZGlhKQpsaWJyYXJ5KGJvb3QpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KHh0cykKbGlicmFyeSh0c2liYmxlKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShyZXNoYXBlMikKCgoKIGFkdWx0MjJfcmF3IDwtIGFkdWx0MjIKIApgYGAKCiMgRGF0YXNldAoKVGhlIGRhdGFzZXQgaXMgZGF0YSBmcm9tIHRoZSAyMDIxIE5hdGlvbmFsIEhlYWx0aCBJbnRlcnZpZXcgQWR1bHQKU3VydmV5LiBUaGUgc3VydmV5IGNvbnRhaW5lZCBxdWVzdGlvbnMgcmVsYXRlZCB0byBob3VzZWhvbGQgYW5kIGZhbWlseQpjb21wb3NpdGlvbiwgZGVtb2dyYXBoaWNzIGFib3V0IHRoZSBzdXJ2ZXkgdGFrZXIsIHNhdGlzZmFjdGlvbiB3aXRoCmxpZmUsIGhlYWx0aCBpbnN1cmFuY2UsIG1lZGljYXRpb24sIGltbXVuaXphdGlvbiwgcHJldmVudGl2ZSBzY3JlZW5pbmdzLAphbmQgbXVsdGlwbGUgaGVhbHRoIHByb2JsZW1zIHN1Y2ggYXMgaHlwZXJ0ZW5zaW9uLCBjYXJkaW92YXNjdWxhcgpjb25kaXRpb25zLCBjYW5jZXIsIHZpc2lvbiwgaGVhcmluZywgbW9iaWxpdHksIGFuZCBtb3JlLgoKVGhpcyBzdXJ2ZXkgaXMgaW1wb3J0YW50IGluIGZvbGxvd2luZyB0aGUgaGVhbHRoIG9mIEFtZXJpY2FuJ3MgYmFzZWQgb24KbWFueSBkaWZmZXJlbnQgZmFjdG9ycyBvZiB0aGVpciBsaXZlcy4gTG9va2luZyBhdCBwcmV2aW91cyBzdXJ2ZXlzIGNhbgphbHNvIGhlbHAgdG8gc2VlIHRyZW5kcyBpbiBBbWVyaWNhbnMnIGhlYWx0aC4KCkZvciB0aGUgZGF0YSB1c2VkLCByZXNwb25zZXMgb2YgInJlZnVzZWQiLCJkb24ndCBrbm93IiBhbmQgIm5vdAphc2NlcnRhaW5lZCIgd2VyZSBmaWx0ZXJlZCBvdXQgYXMgdGhlc2UgcmVzcG9uc2VzIGhhZCBhIHRlbmRlbmN5IHRvIGJlCm11Y2ggc21hbGxlciB0aGFuIHRoZSBvdGhlcnMgYW5kIHdlcmUgbm90IGhlbHBmdWwgZm9yIHdoYXQgd2FzIGJlaW5nCmxvb2tlZCBhdC4KCiMgQ29sdW1ucwoKIyMjIEdlbmVyYWwgSGVhbHRoCgpgYGAgICAgICAgICAKMS4gRXhjZWxsZW50IAoyLiBWZXJ5IEdvb2QgCjMuIEdvb2QgCjQuIEZhaXIgCjUuIFBvb3IgCmBgYAoKIyMjIExpZmUgU2F0aXNmYWN0aW9uCgpgYGAgICAgICAgICAKMS4gVmVyeSBTYXRpc2ZpZWQgCjIuIFNhdGlzZmllZCAKMy4gRGlzc2F0aXNmaWVkIAo0LiBWZXJ5IERpc3NhdGlzZmllZApgYGAKCiMjIyBSYWNlIChTaW5nbGUgYW5kIE11bHRpcGxlIFJhY2UgR3JvdXBzKQoKYGBgICAgICAgICAgCjEuICBXaGl0ZSBvbmx5CjIuICBCbGFjay9BZnJpY2FuIEFtZXJpY2FuIG9ubHkKMy4gIEFzaWFuIG9ubHkKNC4gIEFJQU4gb25seSAoQW1lcmljYW4gSW5kaWFucyBhbmQgQWxhc2thIE5hdGl2ZXMpCjUuICBBSUFOIGFuZCBhbnkgb3RoZXIgZ3JvdXAKNi4gIE90aGVyCjcuICBIaXNwYW5pYyB3aG8gZGlkIG5vdCBpZGVudGlmeSB3aXRoIG9uZSBvZiB0aGUgb3RoZXIgY2F0ZWdvcmllcwpgYGAKCiMjIyBFZHVjYXRpb24gTGV2ZWwKCmBgYCAgICAgICAgIAowLiBOZXZlciBhdHRlbmRlZC9LaW5kZXJnYXJ0ZW4gb25seSAKMS4gR3JhZGUgMS0xMSAKMi4gMTJ0aCBncmFkZSwgbm9kaXBsb21hIAozLiBHRUQgb3IgZXF1aXZhbGVudCAKNC4gSGlnaCBTY2hvb2wgR3JhZHVhdGUgCjUuIFNvbWUgY29sbGVnZSwgbm9kZWdyZWUgCjYuIEFzc29jaWF0ZSBkZWdyZWU6IG9jY3VwYXRpb25hbCwgdGVjaG5pY2FsLCBvciB2b2NhdGlvbmFsIHByb2dyYW0gCjcuIEFzc29jaWF0ZSBkZWdyZWU6IGFjYWRlbWljIHByb2dyYW0gCjguIEJhY2hlbG9yJ3MgZGVncmVlIAo5LiBNYXN0ZXIncyBkZWdyZWUgCjEwLiBQcm9mZXNzaW9uYWwgU2Nob29sIG9yIERvY3RvcmFsIGRlZ3JlZQpgYGAKCiMjIyBCTUkKCmBgYCAgICAgICAgIAoxLiBVbmRlcndlaWdodCAKMi4gTm9ybWFsIAozLiBPdmVyd2VpZ2h0IAo0LiBPYmVzZQpgYGAKCiMgVmlzaW9uCgpgYGAgICAgICAgICAKRG8geW91IHdlYXIgZ2xhc3NlcyBvciBjb250YWN0IGxlbnNlcz8KMS4gWWVzIAoyLiBObwpgYGAKCmBgYCAgICAgICAgIApEbyB5b3UgaGF2ZSBkaWZmaWN1bHR5IHNlZWluZz8gCjEuIE5vIGRpZmZpY3VsdHkgCjIuIFNvbWUgZGlmZmljdWx0eSAKMy4gQSBsb3Qgb2YgZGlmZmljdWx0eSAKNC4gQ2Fubm90IGRvIGF0IGFsbApgYGAKCiMjIyBDYW5jZXIKCmBgYCAgICAgICAgIApTZXBhcmF0ZSBjb2x1bW5zIGZvciBlYWNoIHR5cGUgb2YgY2FuY2VyLgoKTnVtYmVyIG9mIHJlcG9ydGVkIHR5cGVzIG9mIGNhbmNlci4gCjAuIE5vIGNhbmNlciAKMS0zLiAxIHRvIDMgCjQuIDQgb3IgbW9yZQpgYGAKCiMgRGVtb2dyYXBoaWNzCgpMb29raW5nIGF0IGRlbW9ncmFwaGljcyBjYW4gaGVscCB0byBnaXZlIGEgYml0IG9mIGFuIGlkZWEgYWJvdXQgd2hhdApzb3J0IG9mIGRhdGEgd2Ugc2hvdWxkIGxvb2sgYXQuCgojIyMgU2V4CgpgYGB7cn0KCmRmU2V4RmlsdGVyIDwtIGFkdWx0MjIgJT4lIAogIGZpbHRlcihTRVhfQSA9PSAxIHwgU0VYX0EgPT0gMikKCmRmU2V4RmlsdGVyIDwtCiAgZGZTZXhGaWx0ZXIgfD4KICAgIGdyb3VwX2J5KGRmU2V4RmlsdGVyJFNFWF9BKSB8PgogICAgbXV0YXRlKFNleF9TdGF0dXMgPSBpZmVsc2UoU0VYX0EgPT0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSIpKSB8PgoKICB1bmdyb3VwKCkKZ2dwbG90KGRmU2V4RmlsdGVyLCBhZXMoeCA9IFNleF9TdGF0dXMsIGZpbGw9U2V4X1N0YXR1cykpICsgeGxhYigiU2V4IikgKwogIGdlb21fYmFyKCkKYGBgCgojIyMgQWdlCgpUaGUgZmFyIHJpZ2h0IGJhciwgODUsIGlzIGZvciB0aG9zZSB3aG8gYXJlIDg1Ky4KCmBgYHtyfQoKCmRmQWdlRmlsdGVyIDwtIGFkdWx0MjIgJT4lIAogIGZpbHRlcihBR0VQX0EgPCA4NikKCmdncGxvdChkZkFnZUZpbHRlciwgYWVzKHggPSBBR0VQX0EpKSArIHhsYWIoIkFnZSIpICsKICBnZW9tX2JhcigpCmBgYAoKVGhlIGxhcmdlc3QgZ3JvdXAgYmFzZWQgb24gYWdlIHdlcmUgdGhvc2UgdGhhdCB3ZXJlIDg1IG9yIG9sZGVyLgoKIyMjIEVkdWNhdGlvbiBMZXZlbAoKYGBge3J9CmRmRWR1RmlsdGVyIDwtIGFkdWx0MjIgJT4lIAogIGZpbHRlcihFRFVDUF9BIDwgOTcpCgoKZGZFZHVGaWx0ZXIgPC0KICBkZkVkdUZpbHRlciB8PgogICAgZ3JvdXBfYnkoZGZFZHVGaWx0ZXIkRURVQ1BfQSkgfD4KICAgIG11dGF0ZShFZHVfU3RhdHVzID0gaWZlbHNlKEVEVUNQX0EgPT0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JhZGUgMS0xMSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEVEVUNQX0EgPT0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEydGggR3JhZGUsIG5vIERpcGxvbWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRURVQ1BfQSA9PSAzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR0VEIG9yIEVxdWl2YWxlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRURVQ1BfQSA9PSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSGlnaCBTY2hvb2wgR3JhZHVhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRURVQ1BfQSA9PSA1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU29tZSBDb2xsZWdlLCBubyBEZWdyZWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRURVQ1BfQSA9PSA2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXNzb2NpYXRlIGRlZ3JlZTogb2NjdXBhdGlvbmFsLCB0ZWNobmljYWwsIG9yIHZvY2F0aW9uYWwgcHJvZ3JhbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShFRFVDUF9BID09IDcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3NvY2lhdGUgZGVncmVlOiBhY2FkZW1pYyBwcm9ncmFtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEVEVUNQX0EgPT0gOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhY2hlbG9yJ3MgZGVncmVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEVEVUNQX0EgPT0gOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hc3RlcidzIGRlZ3JlZSAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRURVQ1BfQSA9PSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByb2Zlc3Npb25hbCBTY2hvb2wgb3IgRG9jdG9yYWwgZGVncmVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEVEVUNQX0EgPT0gOTcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWZ1c2VkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRG9uJ3QgS25vdyIpKSkpKSkpKSkpKSkgfD4gCnVuZ3JvdXAoKQogIAogIApkZkVkdUZpbHRlciRFZHVfU3RhdHVzIDwtIGZhY3RvcihkZkVkdUZpbHRlciRFZHVfU3RhdHVzLCBsZXZlbHMgPSBjKCJHcmFkZSAxLTExIiwgIjEydGggR3JhZGUsIG5vIERpcGxvbWEiLCAiR0VEIG9yIEVxdWl2YWxlbnQiLCJIaWdoIFNjaG9vbCBHcmFkdWF0ZSIsICJTb21lIENvbGxlZ2UsIG5vIERlZ3JlZSIsICJBc3NvY2lhdGUgZGVncmVlOiBvY2N1cGF0aW9uYWwsIHRlY2huaWNhbCwgb3Igdm9jYXRpb25hbCBwcm9ncmFtIiwgIkFzc29jaWF0ZSBkZWdyZWU6IGFjYWRlbWljIHByb2dyYW0iLCAiQmFjaGVsb3IncyBkZWdyZWUiLCAiTWFzdGVyJ3MgZGVncmVlICIsICJQcm9mZXNzaW9uYWwgU2Nob29sIG9yIERvY3RvcmFsIGRlZ3JlZSIsICJSZWZ1c2VkIiwgIkRvbid0IEtub3ciKSkKCmdncGxvdChkZkVkdUZpbHRlciwgYWVzKHggPSBFRFVDUF9BLCBmaWxsPUVkdV9TdGF0dXMpKSArCiAgZ2VvbV9iYXIoKSArIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICsgeGxhYigiRWR1Y2F0aW9uIExldmVsIikKCmBgYAoKIyMjIFJhY2UKCmBgYHtyfQpkZlJhY2VGaWx0ZXIgPC0gYWR1bHQyMiAlPiUgCiAgZmlsdGVyKFJBQ0VBTExQX0EgPD0gOCApCgpkZlJhY2VGaWx0ZXIyIDwtIGRmUmFjZUZpbHRlciAgJT4lIAogIGZpbHRlcihSQUNFQUxMUF9BICE9IDcgKQoKCmRmUmFjZUZpbHRlcjIgPC0KICBkZlJhY2VGaWx0ZXIyIHw+CiAgICBncm91cF9ieShkZlJhY2VGaWx0ZXIyJFJBQ0VBTExQX0EpIHw+CiAgICBtdXRhdGUoUmFjZSA9IGlmZWxzZShSQUNFQUxMUF9BID09IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldoaXRlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoUkFDRUFMTFBfQSA9PSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWZyaWNhbiBBbWVyaWNhbi9CbGFjayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShSQUNFQUxMUF9BID09IDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc2lhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShSQUNFQUxMUF9BID09IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBSUFOKiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShSQUNFQUxMUF9BID09IDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBSUFOICsgT3RoZXIgR3JvdXAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoUkFDRUFMTFBfQSA9PSA2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3RoZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoUkFDRUFMTFBfQSA9PSA4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSGlzcGFuaWMqKiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRvbid0IEtub3ciKSkpKSkpKSkgfD4gCnVuZ3JvdXAoKQogIApnZ3Bsb3QoZGZSYWNlRmlsdGVyMiwgYWVzKHggPSBSYWNlLCBmaWxsPVJhY2UpKSArCiAgZ2VvbV9iYXIoKSArIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpCgpgYGAKClRoZXJlIHdhcyBhIG11Y2ggbGFyZ2VyIGFtb3VudCBvZiB0aG9zZSB3aG8gaWRlbnRpZmllZCBhcyB3aGl0ZSB3aG8gdG9vawp0aGUgc3VydmV5LgoKIyMjIEdlbmVyYWwgUGh5c2ljYWwgSGVhbHRoCgpgYGB7cn0KCmRmR0hGaWx0ZXIgPC0gYWR1bHQyMiAlPiUgCiAgZmlsdGVyKFBIU1RBVF9BIDwgJzcnKQoKZ2dwbG90KGRmR0hGaWx0ZXIsIGFlcyh4ID0gZmFjdG9yKFBIU1RBVF9BKSkpICsgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiRXhjZWxsZW50IiwgIlZlcnkgR29vZCIsICJHb29kIiwgIkZhaXIiLCAiUG9vciIpKSArCiAgZ2VvbV9iYXIoKSArIAogIHhsYWIoIkdlbmVyYWwgUGh5c2ljYWwgSGVhbHRoIikKYGBgCgpNb3N0IHBlb3BsZSBwdXQgdGhlaXIgR2VuZXJhbCBQaHlzaWNhbCBIZWFsdGggaW4gdGhlIG1vcmUgcG9zaXRpdmUgc2lkZQooRXhjZWxsZW50LCBWZXJ5IGdvb2QsIEdvb2QpIHNpZGUgb2YgdGhlIHNjYWxlLgoKIyMjIExpZmUgU2F0aXNmYWN0aW9uCgpgYGB7cn0KCmRmRmlsdGVyZWRMUyA8LSBhZHVsdDIyICU+JSAKICBmaWx0ZXIoTFNBVElTNF9BIDwgJzUnKQoKCmdncGxvdChkZkZpbHRlcmVkTFMsIGFlcyh4ID0gZmFjdG9yKExTQVRJUzRfQSkpKSArIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIlZlcnkgU2F0aXNmaWVkIiwgIlNhdGlzZmllZCIsICJEaXNzYXRpc2ZpZWQiLCAiVmVyeSBEaXNzYXRpc2ZpZWQiKSkgKwogIGdlb21fYmFyKCkgKwogIHhsYWIoIkxpZmUgU2F0aXNmYWN0aW9uIikKCmBgYAoKTW9zdCBwZW9wbGUgY29uc2lkZXJlZCB0aGVtc2VsdmVzIHRvIGJlIHBvc2l0aXZlbHkgc2F0aXNmaWVkIHdpdGggbGlmZS4KVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHNpZGUgb2YgdGhlIHNjYWxlIHdhcwpsYXJnZXIgdGhhbiBmb3IgR2VuZXJhbCBQaHlzaWNhbCBIZWFsdGguCgojIEJNSQoKQk1JIGNhbiBvZnRlbiBiZSBjb250cmlidXRlZCB0byBoZWFsdGggYW5kIGNlcnRhaW4gbGV2ZWxzIGNhbiBiZQpjb250cmlidXRlZCB0byBoZWFsdGggaXNzdWVzLiBIb3dldmVyLCBCTUkgaXMgZnVuZGFtZW50YWxseSBmbGF3ZWQgYXMgaXQKZG9lcyBub3QgdGFrZSBpbnRvIGNvbnNpZGVyYXRpb24gbXVzY2xlIGZhdC4gRm9yIGV4YW1wbGUsIGEgYm9keSBidWlsZGVyCmNvdWxkIGJlIGNvbnNpZGVyZWQgdG8gaGF2ZSBhbiAib3ZlcndlaWdodCIgQk1JLCBidXQgd291bGQgYmUgbXVjaApoZWFsdGhpZXIgdGhhbiBzb21lb25lIHdobyBoYWQgbW9zdGx5IG5vbi1tdXNjbGUgZmF0LgoKIyMjIEhpc3RvZ3JhbQoKYGBge3J9Cmhpc3QoZGZGaWx0ZXJlZEJNSSRCTUlDQVRfQSkKYGBgCgpUaGUgZGlzdHJpYnV0aW9uIHdhcyByZWxhdGl2ZWx5IGVxdWFsLCBleGNlcHQgZm9yIHRoZSBVbmRlcndlaWdodApjYXRlZ29yeSwgc28gdGhlcmUgd2FzIGEgcG90ZW50aWFsIGZvciB0aGlzIGNhdGVnb3J5IHRvIGNhdXNlIHByb2JsZW1zLgoKIyMjIEJvb3RzdHJhcAoKVGhpcyBpcyB0byBoZWxwIHVzIGdldCBhIGJldHRlciBpZGVhIG9mIHRoZSBhdmVyYWdlIExpZmUgU2F0aXNmYWN0aW9uCmFuZCBHZW5lcmFsIFBoeXNpY2FsIEhlYWx0aCBiYXNlZCBvbiBhIHBlcnNvbidzIEJNSSBjYXRlZ29yeSwgYnkKY3JlYXRpbmcgc2FtcGxlcy4KCmBgYHtyfQoKZGZGaWx0ZXJlZExTQk1JIDwtIGFkdWx0MjIgJT4lCiAgZmlsdGVyKEJNSUNBVF9BIDwgNSAmIExTQVRJUzRfQSA8NSkKCmRmRmlsdGVyZWRQSEJNSSA8LSBhZHVsdDIyICU+JQogIGZpbHRlcihCTUlDQVRfQSA8IDUgJiBQSFNUQVRfQSA8NykKCmJvb3RfY2kgPC0gZnVuY3Rpb24gKHYsIGZ1bmMgPSBtZWRpYW4sIGNvbmYgPSAwLjk1LCBuX2l0ZXIgPSAxMDApIHsKICBib290X2Z1bmMgPC0gXCh4LCBpKSBmdW5jKHhbaV0pCiAgCiAgYiA8LSBib290KHYsIGJvb3RfZnVuYywgUiA9IG5faXRlcikKICBiIDwtIGJvb3QuY2koYiwgY29uZiA9IGNvbmYsIHR5cGUgPSAicGVyYyIpCiAgCiAgcmV0dXJuKGMoImxvd2VyIiA9IGIkcGVyY2VudFs0XSwKICAgICAgICAgICAidXBwZXIiID0gYiRwZXJjZW50WzVdKSkKfQpgYGAKCiMjIyMgQm9vdHN0cmFwOiBMaWZlIFNhdGlzZmFjdGlvbiB2cyBCTUkKCmBgYHtyfQpkZl9jaUxTIDwtIGRmRmlsdGVyZWRMU0JNSSB8PgogIGdyb3VwX2J5KEJNSUNBVF9BKSB8PgogIHN1bW1hcmlzZShjaV9sb3dlciA9IGJvb3RfY2koTFNBVElTNF9BLCBtZWFuKVsnbG93ZXInXSwKICAgICAgICAgICAgbWVhbl9MUyA9IG1lYW4oTFNBVElTNF9BKSwKICAgICAgICAgICAgY2lfdXBwZXIgPSBib290X2NpKExTQVRJUzRfQSwgbWVhbilbJ3VwcGVyJ10pCgpgYGAKCmBgYHtyfQoKZGZfY2lMUyB8PgogIGdncGxvdCgpICsKICBnZW9tX2Vycm9yYmFyaChtYXBwaW5nID0gYWVzKHkgPSBCTUlDQVRfQSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWluPWNpX2xvd2VyLCB4bWF4PWNpX3VwcGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAnOTUlIEMuSS4nKSwgaGVpZ2h0ID0gMC41KSArCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBtZWFuX0xTLCB5ID0gQk1JQ0FUX0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJ0dyb3VwIE1lYW4nKSwKICAgICAgICAgICAgIHNoYXBlID0gJ3wnLAogICAgICAgICAgICAgc2l6ZSA9IDUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ2JsYWNrJywgJ3JlZCcpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHRpdGxlID0gIkxpZmUgU2F0aXNmYWN0aW9uIGJ5IEJNSSBDYXRlZ29yeSIsCiAgICAgICB4ID0gIkxpZmUgU2F0aXNmYWN0aW9uIiwKICAgICAgIHkgPSAiQk1JIENhdGVnb3J5IiwKICAgICAgIGNvbG9yID0gJycpCmBgYAoKQ2F0ZWdvcnkgMSwgdW5kZXJ3ZWlnaHQsIHNlZW1zIHRvIGhhdmUgYSBtdWNoIGxhcmdlciByYW5nZSB0aGFuIHRoZQpvdGhlciAzLCB3aGljaCBsaWtlIHN0YXRlZCBhYm92ZSwgY291bGQgYmUgYW4gaXNzdWUgYmVjYXVzZSBvZiBob3cgc21hbGwKdGhlIGRpc3RyaWJ1dGlvbiB3YXMuCgojIyMjIEJvb3RzdHJhcDogR2VuZXJhbCBQaHlzaWNhbCBIZWFsdGggdnMgQk1JCgpgYGB7cn0KZGZfY2lQSCA8LSBkZkZpbHRlcmVkUEhCTUkgfD4KICBncm91cF9ieShCTUlDQVRfQSkgfD4KICBzdW1tYXJpc2UoY2lfbG93ZXIgPSBib290X2NpKFBIU1RBVF9BLCBtZWFuKVsnbG93ZXInXSwKICAgICAgICAgICAgbWVhbl9QSCA9IG1lYW4oUEhTVEFUX0EpLAogICAgICAgICAgICBjaV91cHBlciA9IGJvb3RfY2koUEhTVEFUX0EsIG1lYW4pWyd1cHBlciddKQoKYGBgCgpgYGB7cn0KCmRmX2NpUEggfD4KICBnZ3Bsb3QoKSArCiAgZ2VvbV9lcnJvcmJhcmgobWFwcGluZyA9IGFlcyh5ID0gQk1JQ0FUX0EsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1pbj1jaV9sb3dlciwgeG1heD1jaV91cHBlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJzk1JSBDLkkuJyksIGhlaWdodCA9IDAuNSkgKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gbWVhbl9QSCwgeSA9IEJNSUNBVF9BLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICdHcm91cCBNZWFuJyksCiAgICAgICAgICAgICBzaGFwZSA9ICd8JywKICAgICAgICAgICAgIHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdibGFjaycsICdyZWQnKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJHZW5lcmFsIEhlYWx0aCBieSBCTUkgQ2F0ZWdvcnkiLAogICAgICAgeCA9ICJHZW5lcmFsIEhlYWx0aCIsCiAgICAgICB5ID0gIkJNSSBDYXRlZ29yeSIsCiAgICAgICBjb2xvciA9ICcnKQpgYGAKClRoZXJlIHdlcmUgd2F5IGxlc3MgcGVvcGxlIGluIHRoZSB1bmRlcndlaWdodCBCTUkgKDEpIHRoYW4gdGhlIG90aGVyCmNhdGVnb3JpZXMsIHNpbWlsYXIgdG8gdGhlIGlzc3VlIGluIExpZmUgU2F0aXNmYWN0aW9uLCBzbyB0aGF0IGdyb3VwCmRvZXMgbm90IGdpdmUgYXMgbXVjaCBpbmZvcm1hdGlvbiwgb3IgYXMgYWNjdXJhdGUgb2YgaW5mb3JtYXRpb24gYXMgdGhlCm90aGVycyBhbmQgd2FzIHJlbW92ZWQgZm9yIHRoZSBncmFwaHMgYmVsb3cuCgojIyMgR2VuZXJhbCBIZWFsdGggYnkgQk1JIFN0YXR1cwoKYGBge3J9CgpkZkJNSUdIIDwtIGFkdWx0MjIgJT4lCiAgZmlsdGVyKFBIU1RBVF9BIDwgNykKCmRmTm9ybWFsQk1JIDwtIGRmQk1JR0ggJT4lCiAgZmlsdGVyKEJNSUNBVF9BID09IDIgKQoKZGZPdmVyQk1JIDwtIGRmQk1JR0ggJT4lCiAgZmlsdGVyKEJNSUNBVF9BID09IDMgKQoKZGZPYmVzZUJNSSA8LSBkZkJNSUdIICU+JQogIGZpbHRlcihCTUlDQVRfQSA9PSA0ICkKCkJNSUdIIDwtIGRhdGEuZnJhbWUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgU3RhdHVzICA9IGMoMiwgMywgNCksICAgICAgIAogICBQaHlzaWNhbF9IZWFsdGg9IGMoIG1lYW4oZGZOb3JtYWxCTUkkUEhTVEFUX0EpLCBtZWFuKGRmT3ZlckJNSSRQSFNUQVRfQSksIG1lYW4oZGZPYmVzZUJNSSRQSFNUQVRfQSkpKQoKZ2dwbG90KEJNSUdILCBhZXMoeCA9IGZhY3RvcihTdGF0dXMpLCB5ID0gUGh5c2ljYWxfSGVhbHRoKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPSBjKCAiTm9ybWFsIiwgIk92ZXJ3ZWlnaHQiLCAiT2Jlc2UiKSkgKwogIHhsYWIoIkJNSSBTdGF0dXMiKSArCiAgeWxhYigiQXZlcmFnZSBHZW5lcmFsIFBoeXNpY2FsIEhlYWx0aCIpCgoKYGBgCgojIyMgTGlmZSBTYXRpc2ZhY3Rpb24gYnkgQk1JIFN0YXR1cwoKYGBge3J9CgpkZkJNSUxTIDwtIGFkdWx0MjIgJT4lCiAgZmlsdGVyKExTQVRJUzRfQSA8IDUpCgpkZk5vcm1hbEJNSUxTIDwtIGRmQk1JTFMgJT4lCiAgZmlsdGVyKEJNSUNBVF9BID09IDIgKQoKZGZPdmVyQk1JTFMgPC0gZGZCTUlMUyAlPiUKICBmaWx0ZXIoQk1JQ0FUX0EgPT0gMyApCgpkZk9iZXNlQk1JTFMgPC0gZGZCTUlMUyAlPiUKICBmaWx0ZXIoQk1JQ0FUX0EgPT0gNCApCgpCTUlMUyA8LSBkYXRhLmZyYW1lKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgIFN0YXR1cyAgPSBjKDIsIDMsIDQpLCAgICAgICAKICAgTGlmZV9TYXRpcz0gYyggbWVhbihkZk5vcm1hbEJNSUxTJExTQVRJUzRfQSksIG1lYW4oZGZPdmVyQk1JTFMkTFNBVElTNF9BKSwgbWVhbihkZk9iZXNlQk1JTFMkTFNBVElTNF9BKSkpCgpnZ3Bsb3QoQk1JTFMsIGFlcyh4ID0gZmFjdG9yKFN0YXR1cyksIHkgPSBMaWZlX1NhdGlzKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPSBjKCJOb3JtYWwiLCAiT3ZlcndlaWdodCIsICJPYmVzZSIpKSArCiAgeGxhYigiQk1JIFN0YXR1cyIpICsKICB5bGFiKCJBdmVyYWdlIExpZmUgU2F0aXNmYWN0aW9uIikKCgpgYGAKCiMgRWR1Y2F0aW9uIExldmVsCgojIyMgVnMgR2VuZXJhbCBQaHlzaWNhbCBIZWFsdGgKCmBgYHtyfQoKZGZGaWx0ZXJlZEVkdSA8LSBkZkdIRmlsdGVyICU+JQogIGZpbHRlcihFRFVDUF9BIDwgOTcpCgpkZl9jaUVkdSA8LSBkZkZpbHRlcmVkRWR1IHw+CiAgZ3JvdXBfYnkoRURVQ1BfQSkgfD4KICBzdW1tYXJpc2UoY2lfbG93ZXIgPSBib290X2NpKFBIU1RBVF9BLCBtZWFuKVsnbG93ZXInXSwKICAgICAgICAgICAgbWVhbl9QSCA9IG1lYW4oUEhTVEFUX0EpLAogICAgICAgICAgICBjaV91cHBlciA9IGJvb3RfY2koUEhTVEFUX0EsIG1lYW4pWyd1cHBlciddKQoKCmRmX2NpRWR1IHw+CiAgZ2dwbG90KCkgKwogIGdlb21fZXJyb3JiYXJoKG1hcHBpbmcgPSBhZXMoeSA9IEVEVUNQX0EsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1pbj1jaV9sb3dlciwgeG1heD1jaV91cHBlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJzk1JSBDLkkuJyksIGhlaWdodCA9IDAuNSkgKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gbWVhbl9QSCwgeSA9IEVEVUNQX0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJ0dyb3VwIE1lYW4nKSwKICAgICAgICAgICAgIHNoYXBlID0gJ3wnLAogICAgICAgICAgICAgc2l6ZSA9IDUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ2JsYWNrJywgJ3JlZCcpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHRpdGxlID0gIkdlbmVyYWwgUGh5c2ljYWwgSGVhbHRoIGJ5IEVkdWNhdGlvbiIsCiAgICAgICB4ID0gIlBoeXNpY2FsIEhlYWx0aCIsCiAgICAgICB5ID0gIkVkdWNhdGlvbiIsCiAgICAgICBjb2xvciA9ICcnKQpgYGAKCldlIGNhbiBzZWUgdGhhdCBhcyBhIHBlcnNvbidzIGVkdWNhdGlvbiBsZXZlbCBkZWNyZWFzZXMsIHRoZWlyIGF2ZXJhZ2UKcGh5c2ljYWwgaGVhbHRoIGdlbmVyYWxseSBkZWNyZWFzZXMsIGhvd2V2ZXIgaXQgd2FzIHN0aWxsIGluIHRoZSBzYW1lCnBoeXNpY2FsIGhlYWx0aCBjYXRlZ29yeS4gVGhlcmUgc2VlbXMgdG8gYmUgYSBmZXcgZ3JvdXBzIGZvcm1pbmcsIHN1Y2gKYXMgdGhlIGJvdHRvbSAzLCB0aGUgbWlkZGxlIDQsIGFuZCB0aGUgdG9wIDMuCgojIyBWcyBMaWZlIFNhdGlzZmFjdGlvbgoKYGBge3J9CgpkZkZpbHRlcmVkRWR1TFMgPC0gZGZGaWx0ZXJlZExTICU+JQogIGZpbHRlcihFRFVDUF9BIDwgOTcpCgpkZl9jaUVkdUxTIDwtIGRmRmlsdGVyZWRFZHVMUyB8PgogIGdyb3VwX2J5KEVEVUNQX0EpIHw+CiAgc3VtbWFyaXNlKGNpX2xvd2VyID0gYm9vdF9jaShMU0FUSVM0X0EsIG1lYW4pWydsb3dlciddLAogICAgICAgICAgICBtZWFuX0xTID0gbWVhbihMU0FUSVM0X0EpLAogICAgICAgICAgICBjaV91cHBlciA9IGJvb3RfY2koTFNBVElTNF9BLCBtZWFuKVsndXBwZXInXSkKCgpkZl9jaUVkdUxTIHw+CiAgZ2dwbG90KCkgKwogIGdlb21fZXJyb3JiYXJoKG1hcHBpbmcgPSBhZXMoeSA9IEVEVUNQX0EsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1pbj1jaV9sb3dlciwgeG1heD1jaV91cHBlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJzk1JSBDLkkuJyksIGhlaWdodCA9IDAuNSkgKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gbWVhbl9MUywgeSA9IEVEVUNQX0EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJ0dyb3VwIE1lYW4nKSwKICAgICAgICAgICAgIHNoYXBlID0gJ3wnLAogICAgICAgICAgICAgc2l6ZSA9IDUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ2JsYWNrJywgJ3JlZCcpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHRpdGxlID0gIkxpZmUgU2F0aXNmYWN0aW9uIGJ5IEVkdWNhdGlvbiIsCiAgICAgICB4ID0gIkxpZmUgU2F0aXNmYWN0aW9uIiwKICAgICAgIHkgPSAiRWR1Y2F0aW9uIiwKICAgICAgIGNvbG9yID0gJycpCmBgYAoKU2ltaWxhciB0byBnZW5lcmFsIGhlYWx0aCwgdGhlcmUgaXMgYSB0cmVuZCBvZiBhcyBlZHVjYXRpb24gbGV2ZWwKZGVjcmVhc2VzLCBsaWZlIHNhdGlzZmFjdGlvbiBkZWNyZWFzZXMuCgojIFZpc2lvbgoKYGBge3J9CmRmRmlsdGVyZWRWaXMgPC0gYWR1bHQyMiAlPiUKICBmaWx0ZXIoVklTSU9OREZfQSA8NCkKCmhpc3QoZGZGaWx0ZXJlZFZpcyRWSVNJT05ERl9BKQoKaGlzdChkZkZpbHRlcmVkVmlzJFdFQVJHTFNTX0EpCmBgYAoKIyMjIFZpc2lvbiB2cyBHZW5lcmFsIFBoeXNpY2FsIEhlYWx0aAoKYGBge3J9CmRmR2xhc3NlcyA8LSBhZHVsdDIyICU+JQogIGZpbHRlcihQSFNUQVRfQSA8IDUpCgpkZk5vR2xhc3NlcyA8LSBkZkdsYXNzZXMgJT4lCiAgZmlsdGVyKFdFQVJHTFNTX0EgPT0gJzInKQoKZGZXZWFyR2xhc3NlcyA8LSBkZkdsYXNzZXMgJT4lCiAgZmlsdGVyKFdFQVJHTFNTX0E9PSAnMScgKQoKV2VhckdsYXNzZXMgPC0gZGF0YS5mcmFtZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICBTdGF0dXMgID0gYygxLCAyKSwgICAgICAgCiAgIEdlbl9IZWFsdGg9IGMobWVhbihkZldlYXJHbGFzc2VzJFBIU1RBVF9BKSwgbWVhbihkZk5vR2xhc3NlcyRQSFNUQVRfQSkpKQoKCmdncGxvdChXZWFyR2xhc3NlcywgYWVzKHggPSBmYWN0b3IoU3RhdHVzKSwgeSA9IEdlbl9IZWFsdGgpKSArIAogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9IGMoIldlYXIgR2xhc3Nlcy9Db250YWN0cyIsICJObyBHbGFzc2VzL0NvbnRhY3RzIikpICsKICB4bGFiKCIiKSsKICB5bGFiKCJBdmVyYWdlIFBoeXNpY2FsIEhlYWx0aCIpCmBgYAoKYGBge3J9CmRmVmlzaW9uIDwtIGRmRmlsdGVyZWRWaXMgJT4lCiAgZmlsdGVyKFBIU1RBVF9BIDwgNSkKCmRmTm9uZVZpcyA8LSBkZlZpc2lvbiAlPiUKICBmaWx0ZXIoVklTSU9OREZfQSA9PSAnMScpCgpkZlNvbWVWaXMgPC0gZGZWaXNpb24gJT4lCiAgZmlsdGVyKFZJU0lPTkRGX0E9PSAnMicgKQoKZGZBbG90VmlzIDwtIGRmVmlzaW9uICU+JQogIGZpbHRlcihWSVNJT05ERl9BPT0gJzMnICkKCmRmQ2Fubm90VmlzIDwtIGRmVmlzaW9uICU+JQogIGZpbHRlcihWSVNJT05ERl9BPT0gJzQnICkKClZpc0RpZmZpY3VsdHkgPC0gZGF0YS5mcmFtZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICBTdGF0dXMgID0gYygxLCAyLDMsNCksICAgICAgIAogICBHZW5fSGVhbHRoPSBjKG1lYW4oZGZOb25lVmlzJFBIU1RBVF9BKSwgbWVhbihkZlNvbWVWaXMkUEhTVEFUX0EpLCBtZWFuKGRmQWxvdFZpcyRQSFNUQVRfQSksIG1lYW4oZGZDYW5ub3RWaXMkUEhTVEFUX0EpKSkKCgpnZ3Bsb3QoVmlzRGlmZmljdWx0eSwgYWVzKHggPSBmYWN0b3IoU3RhdHVzKSwgeSA9IEdlbl9IZWFsdGgpKSArIAogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9IGMoIk5vbmUiLCAiU29tZSIsICJBIExvdCIsIkNhbm5vdCBTZWUiKSkgKwogIHhsYWIoIkRpZmZpY3VsdHkgU2VlaW5nIikgKwogIHlsYWIoIkF2ZXJhZ2UgUGh5c2ljYWwgSGVhbHRoIikKYGBgCgojIyMgVmlzaW9uIHZzIExpZmUgU2F0aXNmYWN0aW9uCgpgYGB7cn0KZGZHbGFzc2VzTFMgPC0gYWR1bHQyMiAlPiUKICBmaWx0ZXIoTFNBVElTNF9BIDwgNykKCmRmTm9HbGFzc2VzTFMgPC0gZGZHbGFzc2VzTFMgJT4lCiAgZmlsdGVyKFdFQVJHTFNTX0EgPT0gJzInKQoKZGZXZWFyR2xhc3Nlc0xTIDwtIGRmR2xhc3Nlc0xTICU+JQogIGZpbHRlcihXRUFSR0xTU19BPT0gJzEnICkKCldlYXJHbGFzc2VzTFMgPC0gZGF0YS5mcmFtZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICBTdGF0dXMgID0gYygxLCAyKSwgICAgICAgCiAgIExpZmVfU2F0aXM9IGMobWVhbihkZldlYXJHbGFzc2VzTFMkTFNBVElTNF9BKSwgbWVhbihkZk5vR2xhc3Nlc0xTJExTQVRJUzRfQSkpKQoKCmdncGxvdChXZWFyR2xhc3Nlc0xTLCBhZXMoeCA9IGZhY3RvcihTdGF0dXMpLCB5ID0gTGlmZV9TYXRpcykpICsgCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz0gYygiV2VhciBHbGFzc2VzL0NvbnRhY3RzIiwgIk5vIEdsYXNzZXMvQ29udGFjdHMiKSkgKwogIHhsYWIoIiIpKwogIHlsYWIoIkF2ZXJhZ2UgTGlmZSBTYXRpc2ZhY3Rpb24iKQpgYGAKCiMjIyBEaWZmaWN1bHR5IFNlZWluZyBhbmQgTGlmZSBTYXRpc2ZhY3Rpb24KCmBgYHtyfQpkZlZpc2lvbkxTIDwtIGRmRmlsdGVyZWRWaXMgJT4lCiAgZmlsdGVyKExTQVRJUzRfQSA8IDcpCgpkZk5vbmVWaXNMUyA8LSBkZlZpc2lvbkxTICU+JQogIGZpbHRlcihWSVNJT05ERl9BID09ICcxJykKCmRmU29tZVZpc0xTIDwtIGRmVmlzaW9uTFMgJT4lCiAgZmlsdGVyKFZJU0lPTkRGX0E9PSAnMicgKQoKZGZBbG90VmlzTFMgPC0gZGZWaXNpb25MUyAlPiUKICBmaWx0ZXIoVklTSU9OREZfQT09ICczJyApCgpkZkNhbm5vdFZpc0xTIDwtIGRmVmlzaW9uTFMgJT4lCiAgZmlsdGVyKFZJU0lPTkRGX0E9PSAnNCcgKQoKVmlzRGlmZmljdWx0eUxTIDwtIGRhdGEuZnJhbWUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgU3RhdHVzICA9IGMoMSwgMiwzLDQpLCAgICAgICAKICAgTGlmZV9TYXRpcz0gYyhtZWFuKGRmTm9uZVZpc0xTJExTQVRJUzRfQSksIG1lYW4oZGZTb21lVmlzTFMkTFNBVElTNF9BKSwgbWVhbihkZkFsb3RWaXNMUyRMU0FUSVM0X0EpLCBtZWFuKGRmQ2Fubm90VmlzTFMkTFNBVElTNF9BKSkpCgoKZ2dwbG90KFZpc0RpZmZpY3VsdHlMUywgYWVzKHggPSBmYWN0b3IoU3RhdHVzKSwgeSA9IExpZmVfU2F0aXMpKSArIAogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9IGMoIk5vbmUiLCAiU29tZSIsICJBIExvdCIsIkNhbm5vdCBTZWUiKSkgKwogIHhsYWIoIkRpZmZpY3VsdHkgU2VlaW5nIikgKwogIHlsYWIoIkF2ZXJhZ2UgTGlmZSBTYXRpc2ZhY3Rpb24iKQpgYGAKCkZvciBib3RoIHBoeXNpY2FsIGhlYWx0aCBhbmQgbGlmZSBzYXRpc2ZhY3Rpb24sIHRoZXJlIHdhcyBhIGRlY3JlYXNlIGZvcgp0aG9zZSB3aG8gd2VhciBnbGFzc2VzL2NvbnRhY3RzLiBTaW5jZSBwZW9wbGUgY2FuIGJlIHNwbGl0IGludG8gcG9zaXRpdmUKYW5kIG5lZ2F0aXZlIGxpZmUgc2F0aXNmYWN0aW9uLCB3ZSBjYW4gdHJ5IGEgYmluYXJ5IHJlc3BvbnNlLgoKYGBge3J9CmRmVmlzaW9uQWxsIDwtIGRmRmlsdGVyZWRWaXMgJT4lCiAgZmlsdGVyKFdFQVJHTFNTX0E8ICczJyApCgpkZlZpc2lvbkFsbExTIDwtCiAgZGZWaXNpb25BbGwgfD4KICAgIGdyb3VwX2J5KGRmVmlzaW9uQWxsJExTQVRJUzRfQSkgfD4KICAgIG11dGF0ZShMaWZlU2F0aXNfU3RhdHVzID0gaWZlbHNlKExTQVRJUzRfQSA9PSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShMU0FUSVM0X0EgPT0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSkpKSB8PiAKICB1bmdyb3VwKCkKCm1vZGVsIDwtIGdsbShMaWZlU2F0aXNfU3RhdHVzIH4gVklTSU9OREZfQSwgZGF0YSA9IGRmVmlzaW9uQWxsTFMsCiAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ2xvZ2l0JykpCgptb2RlbCRjb2VmZmljaWVudHMKCgoKYGBgCgpgYGB7cn0Kc2lnbW9pZCA8LSBcKHgpIDEgLyAoMSArIGV4cCgtKC00LjMyNTczNSArIDEuMDA0OTI3ICogeCkpKQoKZGZWaXNpb25BbGxMUyB8PgogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBWSVNJT05ERl9BLCB5ID0gTGlmZVNhdGlzX1N0YXR1cykpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAsIGhlaWdodCA9IDAuMSwgc2hhcGUgPSAnTycsIHNpemUgPSAzKSArCiAgZ2VvbV9mdW5jdGlvbihmdW4gPSBzaWdtb2lkLCBjb2xvciA9ICdibHVlJywgbGluZXdpZHRoID0gMSkgKwogIGxhYnModGl0bGUgPSAiTGlmZSBTYXRpc2ZhY3Rpb24gQmluYXJ5IFJlc3BvbnNlIC0gRGlmZmljdWx0eSBTZWVpbmciKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMSkpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpCZXR3ZWVuIFBvc2l0aXZlIExpZmUgU2F0aXNmYWN0aW9uKDApIGFuZCBOZWdhdGl2ZSBMaWZlIFNhdGlzZmFjdGlvbigxKS4KV2UgY2FuIHNlZSB0aGF0IHRoZXJlIGlzIGEgc21hbGwgaW5jcmVhc2UgaW4gcHJvYmFiaWxpdHkgdGhhdCBhcwpzb21lb25lJ3MgdmlzaW9uIGdldHMgd29yc3QsIHRoZSBsaWZlIHNhdGlzZmFjdGlvbiB3aWxsIGJlY29tZSBtb3JlCm5lZ2F0aXZlLgoKIyBTbW9raW5nCgojIyMgU21va2luZywgTGlmZSBTYXRpc2ZhY3Rpb24sIGFuZCBHZW5lcmFsIEhlYWx0aAoKMS4gIEN1cnJlbnQsIGV2ZXJ5IGRheSBzbW9rZXIKMi4gIEN1cnJlbnQsIHNvbWUgZGF5cyBzbW9rZXIKMy4gIEZvcm1lciBzbW9rZXIKNC4gIE5vbi1TbW9rZXIKCmBgYHtyfQoKZGZGaWx0ZXJlZExTU21va2UgPC0gZGZGaWx0ZXJlZExTICU+JQogIGZpbHRlcihTTUtDSUdTVF9BIDwgNSkKCgpkZkZpbHRlcmVkTFNTbW9rZSB8PgogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBTTUtDSUdTVF9BLCB5ID0gTFNBVElTNF9BKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2xvciA9ICdkYXJrYmx1ZScpICsgCiAgdGhlbWVfbWluaW1hbCgpICsgeGxhYigiU21va2luZyBTdGF0dXMiKSArIHlsYWIoIkxpZmUgU2F0aXNmYWN0aW9uIikKICAKCmRmRmlsdGVyZWRQSFNtb2tlIDwtIGRmR0hGaWx0ZXIgJT4lCiAgZmlsdGVyKFNNS0NJR1NUX0EgPCA1KQoKCmRmRmlsdGVyZWRQSFNtb2tlIHw+CiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeCA9IFNNS0NJR1NUX0EsIHkgPSBQSFNUQVRfQSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAnZGFya2JsdWUnKSArIAogIHRoZW1lX21pbmltYWwoKSArIHhsYWIoIlNtb2tpbmcgU3RhdHVzIikgKyB5bGFiKCJHZW5lcmFsIEhlYWx0aCIpCgoKYGBgCgpUaGVyZSBpcyBhIGJpdCBvZiBhIGRlY3JlYXNlIGluIGxpZmUgc2F0aXNmYWN0aW9uIGFuZCBnZW5lcmFsIGhlYWx0aCB0aGUKbW9yZSBzb21lb25lIHNtb2tlcy4KCiMjIyBTbW9raW5nIGFuZCBMdW5nIENhbmNlciAtIEJpbmFyeSBSZXNwb25zZQoKV2UgY2FuIHNwbGl0IHBlb3BsZSB1cCBpbnRvIHNvbWVvbmUgd2hvIGhhcyBzbW9rZWQgYW5kIHNvbWVvbmUgd2hvIGhhcwpub3Qgc21va2VkLCBzbyB3ZSBjYW4gdHJ5IGEgYmluYXJ5IHJlc3BvbnNlLgoKYGBge3J9CgpkZlNtb2tlQ2FuIDwtIGFkdWx0MjIgJT4lCiAgZmlsdGVyKFNNS0NJR1NUX0EgPCA1ICYgTFVOR0NBTl9BIDwzKQoKZGZTbW9rZUNhbiA8LQogIGRmU21va2VDYW4gfD4KICAgIGdyb3VwX2J5KGRmU21va2VDYW4kU01LQ0lHU1RfQSkgfD4KICAgIG11dGF0ZShTbW9rZSA9IGlmZWxzZShTTUtDSUdTVF9BID09ICI0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKSkgfD4gCiAgdW5ncm91cCgpCgptb2RlbCA8LSBnbG0oU21va2UgfiBMVU5HQ0FOX0EsIGRhdGEgPSBkZlNtb2tlQ2FuLAogICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQoKbW9kZWwkY29lZmZpY2llbnRzCgpgYGAKCmBgYHtyfQpzaWdtb2lkIDwtIFwoeCkgMSAvICgxICsgZXhwKC0oMy4yNjQ1MDcgLTEuNzU1MTUzICogeCkpKQoKZGZTbW9rZUNhbiB8PgogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBMVU5HQ0FOX0EsIHkgPSBTbW9rZSkpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAsIGhlaWdodCA9IDAuMSwgc2hhcGUgPSAnTycsIHNpemUgPSAzKSArCiAgZ2VvbV9mdW5jdGlvbihmdW4gPSBzaWdtb2lkLCBjb2xvciA9ICdibHVlJywgbGluZXdpZHRoID0gMSkgKwogIGxhYnModGl0bGUgPSAiQmluYXJ5IFJlc3BvbnNlOiBMdW5nIENhbmNlciBhbmQgU21va2luZyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxKSkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKClRoaXMgZ3JhcGggc2hvd3MgdGhhdCBmb3IgdGhvc2Ugd2hvIGhhdmUgbHVuZyBjYW5jZXIgKDEpLCB0aGVyZSBpcyBhCmhpZ2hlciBwcm9iYWJpbGl0eSBvZiB0aGVtIGJlaW5nIGEgc21va2VyIG9yIGZvcm1lciBzbW9rZXIoMSkuCgojIyMgMTAwIENpZ2FyZXR0ZXMgU21va2VkIGFuZCBMdW5nIENhbmNlciAtIEJpbmFyeSBSZXNwb25zZQoKV2UgY2FuIGFsc28gc3BsaXQgdGhlIHNtb2tlcnMgdXAgaW50byB0aG9zZSB3aG8gaGF2ZSBzbW9rZWQgMTAwCmNpZ2FyZXR0ZXMsIGFuZCB0aG9zZSB3aG8gaGF2ZSBub3QuCgpgYGB7cn0KZGZTbW9rZTEwMCA8LSBhZHVsdDIyICU+JQogIGZpbHRlcihTTUtFVl9BIDwgMyAmIExVTkdDQU5fQSA8MykKCmRmU21va2UxMDBDYW4gPC0KICBkZlNtb2tlMTAwIHw+CiAgICBncm91cF9ieShkZlNtb2tlMTAwJFNNS0VWX0EpIHw+CiAgICBtdXRhdGUoU21va2VfMTAwID0gaWZlbHNlKFNNS0VWX0EgPT0gIjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpKSB8PiAKICB1bmdyb3VwKCkKCm1vZGVsIDwtIGdsbShTbW9rZV8xMDAgfiBMVU5HQ0FOX0EsIGRhdGEgPSBkZlNtb2tlMTAwQ2FuLAogICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpKQoKbW9kZWwkY29lZmZpY2llbnRzCgpgYGAKCmBgYHtyfQpzaWdtb2lkIDwtIFwoeCkgMSAvICgxICsgZXhwKC0oMy4yNjMwOTQgLTEuNzUzNzQwICogeCkpKQoKZGZTbW9rZTEwMENhbiB8PgogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBMVU5HQ0FOX0EsIHkgPSBTbW9rZV8xMDApKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLCBoZWlnaHQgPSAwLjEsIHNoYXBlID0gJ08nLCBzaXplID0gMykgKwogIGdlb21fZnVuY3Rpb24oZnVuID0gc2lnbW9pZCwgY29sb3IgPSAnYmx1ZScsIGxpbmV3aWR0aCA9IDEpICsKICBsYWJzKHRpdGxlID0gIkJpbmFyeSBSZXNwb25zZTogTHVuZyBDYW5jZXIgYW5kIFNtb2tlZCAxMDAgQ2lnYXJldHRlcyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxKSkgKwogIHRoZW1lX21pbmltYWwoKQoKYGBgCgpUaGlzIGdyYXBoIHNob3dzIHRoYXQgZm9yIHRob3NlIHdobyBoYXZlIGx1bmcgY2FuY2VyICgxKSwgdGhlcmUgaXMgYQpoaWdoZXIgcHJvYmFiaWxpdHkgb2YgdGhlbSBoYXZpbmcgc21va2VkIDEwMCBjaWdhcmV0dGVzKDEpLiBUaGUgbW9kZWwgaXMKZXh0cmVtZWx5IGNsb3NlIHRvIHRoZSBwcmV2aW91cyBtb2RlbC4gU28sIGhvdyBtYW55IG9mIHRoZSBzbW9rZXJzIHdpdGgKbHVuZyBjYW5jZXIgc21va2VkIDEwMCBjaWdhcmV0dGVzPwoKYGBge3J9Ckx1bmdDYW4gPC0gbnJvdyhkZlNtb2tlMTAwW2RmU21va2UxMDAkTFVOR0NBTl9BID09ICcxJyxdKQpTbW9rZWQxMDAgPC0gbnJvdyhkZlNtb2tlMTAwW2RmU21va2UxMDAkU01LRVZfQSA9PSAnMScsXSkKU21va2VkMTAwQ2FuIDwtIG5yb3coZGZTbW9rZTEwMFtkZlNtb2tlMTAwJFNNS0VWX0EgPT0gJzEnICYgZGZTbW9rZTEwMCRMVU5HQ0FOX0EgPT0gJzEnLCBdKQpOb3RTbW9rZWQxMDBDYW4gPC0gbnJvdyhkZlNtb2tlMTAwW2RmU21va2UxMDAkU01LRVZfQSA9PSAnMicgJiBkZlNtb2tlMTAwJExVTkdDQU5fQSA9PSAnMScsIF0pCgpMdW5nQ2FuClNtb2tlZDEwMENhbgo5NS8xMTYqMTAwClNtb2tlZDEwMApOb3RTbW9rZWQxMDBDYW4KOTUvMTUxMSoxMDAKYGBgCgpPdXQgb2YgMTE2IHBlb3BsZSB3aG8gc3RhdGVkIHRoZXkgaGF2ZSBsdW5nIGNhbmNlciwgOTUgcGVvcGxlLCBvciA4MS45JQpoYWQgc21va2VkIGF0IGxlYXN0IDEwMCBjaWdhcmV0dGVzLiBCdXQgb3V0IG9mIDE1MTEgcGVvcGxlIHdobyBoYXZlCnNtb2tlZCBhdCBsZWFzdCAxMDAgY2lnYXJldHRlcywgb25seSAyMSwgb3IgNi4zJSBoYXZlIGx1bmcgY2FuY2VyLgoKIyBDb3ZpZAoKTW9udGggb2YgbGFzdCBDb3ZpZCB2YWNjaW5lIGZvciB0aG9zZSB3aG8gZ290IGl0IGZvciB0aGUgZmlyc3QgdGltZS4KCmBgYHtyfQpmQ292aWRWYXggPC0gYWR1bHQyMgoKZGZDb3ZpZFZheEZpcnN0IDwtIGRmQ292aWRWYXggJT4lCiAgZmlsdGVyKENWRFZBQzFNX0EgIT0gJ05BJyAmIENWRFZBQzFZX0EgIT0nTkEnKQoKZGZDb3ZpZFZheExhc3QgPC0gZGZDb3ZpZFZheCAlPiUKICBmaWx0ZXIoQ1ZEVkFDMk1fQSAhPSAnTkEnICYgQ1ZEVkFDMllfQSAhPSdOQScpCgpkZkNvdmlkVmF4Rmlyc3QkTGFzdENvdmlkVmF4Rmlyc3RUaW1lIDwtIHdpdGgoZGZDb3ZpZFZheEZpcnN0LCBzcHJpbnRmKCIlZC0wMS0lMDJkIiwgQ1ZEVkFDMU1fQSwgQ1ZEVkFDMVlfQSkpCgpkZkNvdmlkVmF4TGFzdCRMYXN0Q292aWRWYXhOb3RGaXJzdFRpbWUgPC0gd2l0aChkZkNvdmlkVmF4TGFzdCwgc3ByaW50ZigiJWQtMDEtJTAyZCIsIENWRFZBQzJNX0EsIENWRFZBQzJZX0EpKQoKZGZDb3ZpZFZheEZpcnN0XyA8LSBkZkNvdmlkVmF4Rmlyc3QgJT4lCiAgZmlsdGVyKENWRERJQUdfQSA8IDMpCgpkZkNvdmlkVmF4TGFzdF8gPC0gZGZDb3ZpZFZheExhc3QgJT4lCiAgZmlsdGVyKENWRERJQUdfQSA8IDMpCgpkZkNvdmlkVmF4Rmlyc3QxIDwtIGRmQ292aWRWYXhGaXJzdF8gfD4KICBzZWxlY3QoTGFzdENvdmlkVmF4Rmlyc3RUaW1lLCBDVkRESUFHX0EpCgpkZkNvdmlkVmF4TGFzdDEgPC0gZGZDb3ZpZFZheExhc3RfIHw+CiAgc2VsZWN0KExhc3RDb3ZpZFZheE5vdEZpcnN0VGltZSwgQ1ZERElBR19BKQoKZGZ0cmFuc2YgPC0gZGZDb3ZpZFZheEZpcnN0MSB8PgogIHNlbGVjdChMYXN0Q292aWRWYXhGaXJzdFRpbWUsIENWRERJQUdfQSkKCmRmdHJhbnNmWydkYXRlJ108LSBhcy5EYXRlKGRmdHJhbnNmJExhc3RDb3ZpZFZheEZpcnN0VGltZSwgZm9ybWF0PSIlbS0lZC0lWSIpCgpkZnRyYW5zZmlsdCA8LSBkZnRyYW5zZiAlPiUgZmlsdGVyKCFpcy5uYShkYXRlKSkKCmRmRmlyc3RWIDwtIGRmdHJhbnNmaWx0IHw+CiAgc2VsZWN0KGRhdGUsIENWRERJQUdfQSkKCmRmZmlyc3RWQ291bnQ8LSBkZkZpcnN0ViAlPiUgZ3JvdXBfYnkoZGF0ZSkgJT4ldGFsbHkoKSAKCmRmTWVyZ2UgPC0gbWVyZ2UoZGZmaXJzdFZDb3VudCwgZGZGaXJzdFZTdW0sIGJ5ID0gImRhdGUiLCBhbGwueD1UUlVFLCBhbGwueT1UUlVFKQoKZGZNZXJnZVsncGVyY2VudCddID0gZGZNZXJnZVsnRnJlcXVlbmN5J10vZGZNZXJnZVsnbiddCgpkZk1lcmdlIDwtIGRmTWVyZ2UgJT4lIGZpbHRlcihwZXJjZW50ID4uMDAwMDAwMSkKCmBgYAoKYGBge3J9CmRmTWVyZ2UgfD4KICBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4ID0gZGF0ZSwgeSA9IG4pKSArCiAgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAiRGF0ZSBvZiBGaXJzdCBDb3ZpZCBWYWNjaW5lIikgKwogIHRoZW1lX2hjKCkgKwogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlWSAoJWIpIikgKyB5bGFiKCJOdW1iZXIgb2YgUGVvcGxlIikKCmBgYAoKVGhlIGZpcnN0IHZhY2NpbmUgY2FtZSBvdXQgaW4gRGVjIDIwMjEsIHdoaWNoIGlzIGFyb3VuZCB3aGVyZSB0aGUgZ3JhcGgKc3RhcnRzIHRvIGluY3JlYXNlLiBUaGVyZSB3YXMgYW4gaW5jcmVhc2UgaW4gQXByaWwgYW5kIE1heSAyMDIxLiBJbiBKdW5lCjIwMjEgd2hlbiBpdCBzdGFydGVkIHRvIGRlY3JlYXNlLCB0aGVyZSB3YXMgYSBzbG93ZG93biBpbiBwZW9wbGUgZ2V0dGluZwp0aGUgdmFjY2luZSBhbmQgYSByZWNvcmQgbG93IG51bWJlciBvZiBjYXNlcy4KClNvdXJjZToKPGh0dHBzOi8vd3d3LmtmZi5vcmcvY29yb25hdmlydXMtY292aWQtMTkvcG9sbC1maW5kaW5nL2tmZi1jb3ZpZC0xOS12YWNjaW5lLW1vbml0b3ItanVuZS0yMDIxLz4KCk9uIFNlcHRlbWJlciA5IDIwMjEsIEJpZGVuIG1hZGUgYW4gYW5ub3VuY2VtZW50IHJlcXVpcmluZyBmZWRlcmFsCmVtcGxveWVlcyB0byBiZSB2YWNjaW5hdGVkIGJ5IHRoZSBlbmQgb2YgSmFudWFyeSAyMDIyLCB3aGljaCBpcyBhcm91bmQKdGhlIHRpbWUgb2YgdGhlIGxhcmdlc3QgcGVhayBiZXR3ZWVuIFNlcHQgMjAyMSBhbmQgSmFudWFyeSAyMDIyLgoKU291cmNlOgo8aHR0cHM6Ly93d3cud2hpdGVob3VzZS5nb3YvYnJpZWZpbmctcm9vbS9wcmVzaWRlbnRpYWwtYWN0aW9ucy8yMDIxLzA5LzA5L2V4ZWN1dGl2ZS1vcmRlci1vbi1yZXF1aXJpbmctY29yb25hdmlydXMtZGlzZWFzZS0yMDE5LXZhY2NpbmF0aW9uLWZvci1mZWRlcmFsLWVtcGxveWVlcy8+CgojIENhbmNlcgoKIyMjIENhbmNlciBieSBTZXgKCiMjIyMgVG9sZCBoYXMgY2FuY2VyLgoKYGBge3J9CgpkZkZlbWFsZSA9IGFkdWx0MjIgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpCgpkZkZlbWFsZUNhbiA9IGRmRmVtYWxlICU+JQogIGZpbHRlcihDQU5FVl9BID09IDEpCgpkZk1hbGUgPSBhZHVsdDIyICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKQoKZGZNYWxlQ2FuID0gZGZNYWxlICU+JQogIGZpbHRlcihDQU5FVl9BID09IDEpCgpUb3RhbEYgPC0gbnJvdyhkZkZlbWFsZSkKVG90YWxNIDwtIG5yb3coZGZNYWxlKQpQZXJjZW50RiA8LSAobnJvdyhkZkZlbWFsZUNhbikvbnJvdyhkZkZlbWFsZSkpKjEwMApQZXJjZW50TSA8LSAobnJvdyhkZk1hbGVDYW4pL25yb3coZGZNYWxlKSkqMTAwCgpQZXJjZW50Q2FuIDwtIGRhdGEuZnJhbWUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgU2V4ICA9IGMoIkZlbWFsZSIsICJNYWxlIiksICAgICAgIAogICBQZXJjZW50PSBjKChQZXJjZW50RiksIChQZXJjZW50TSkpKQoKZ2dwbG90KFBlcmNlbnRDYW4sIGFlcyh4ID0gU2V4LCB5PVBlcmNlbnQpKSArCiAgZ2VvbV9wb2ludCgpCmBgYAoKIyMjIyBQZXJjZW50IGJ5IFR5cGUgb2YgQ2FuY2VyCgpgYGB7cn0KZGZDYW4gPC0gYWR1bHQyMiAlPiUKICBmaWx0ZXIoTlVNQ0FOX0EgPCA3ICYgTlVNQ0FOX0EgIT0wKQoKZGZCbGFkIDwtIGRmQ2FuICU+JQogIGZpbHRlcihCTEFERENBTl9BID09IDEpCgpkZkJsb29kIDwtIGRmQ2FuICU+JQogIGZpbHRlcihCTE9PRENBTl9BID09IDEpCgpkZkJyYWluIDwtIGRmQ2FuICU+JQogIGZpbHRlcihCUkFJTkNBTl9BID09IDEpCgpkZkJvbmUgPC0gZGZDYW4gJT4lCiAgZmlsdGVyKEJPTkVDQU5fQSA9PSAxKQoKZGZCcmVhc3QgPC0gZGZDYW4gJT4lCiAgZmlsdGVyKEJSRUFTQ0FOX0EgPT0gMSkKCmRmQ2VydmljYWwgPC0gZGZDYW4gJT4lCiAgZmlsdGVyKENFUlZJQ0FOX0EgPT0gMSkKCmRmRXNvcGggPC0gZGZDYW4gJT4lCiAgZmlsdGVyKEJMQUREQ0FOX0EgPT0gMSkKCmRmR2FsbCA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoRVNPUEhDQU5fQSA9PSAxKQoKZGZMYXJ5bnggPC0gZGZDYW4gJT4lCiAgZmlsdGVyKExBUllOQ0FOX0EgPT0gMSkKCmRmTGV1ayA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoTEVVS0VDQU5fQSA9PSAxKQoKZGZMaXZlciA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoTElWRVJDQU5fQSA9PSAxKQoKZGZMdW5nIDwtIGRmQ2FuICU+JQogIGZpbHRlcihMVU5HQ0FOX0EgPT0gMSkKCmRmTHltcGggPC0gZGZDYW4gJT4lCiAgZmlsdGVyKExZTVBIQ0FOX0EgPT0gMSkKCmRmTWVsYSA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoTUVMQU5DQU5fQSA9PSAxKQoKZGZNb3V0aCA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoTU9VVEhDQU5fQSA9PSAxKQoKZGZPdmFyeSA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoT1ZBUllDQU5fQSA9PSAxKQoKZGZQYW5jIDwtIGRmQ2FuICU+JQogIGZpbHRlcihQQU5DUkNBTl9BPT0gMSkKCmRmUHJvc3QgPC0gZGZDYW4gJT4lCiAgZmlsdGVyKFBST1NUQ0FOX0EgPT0gMSkKCmRmU2tpbk1lbGEgPC0gZGZDYW4gJT4lCiAgZmlsdGVyKFNLTk1DQU5fQSA9PSAxKQoKZGZTa2luTm9NZWxhIDwtIGRmQ2FuICU+JQogIGZpbHRlcihTS05OTUNBTl9BID09IDEpCgpkZlNraW5Vbmtub3duIDwtIGRmQ2FuICU+JQogIGZpbHRlcihTS05ES0NBTl9BID09IDEpCgpkZlN0b21hY2ggPC0gZGZDYW4gJT4lCiAgZmlsdGVyKFNUT01BQ0FOX0EgPT0gMSkKCmRmVGhyb2F0IDwtIGRmQ2FuICU+JQogIGZpbHRlcihUSFJPQUNBTl9BID09IDEpCgpkZlRoeXJvaWQgPC0gZGZDYW4gJT4lCiAgZmlsdGVyKFRIWVJPQ0FOX0EgPT0gMSkKCmRmVXRlcnVzIDwtIGRmQ2FuICU+JQogIGZpbHRlcihVVEVSVUNBTl9BID09IDEpCgpkZkhhbmROZWNrIDwtIGRmQ2FuICU+JQogIGZpbHRlcihIRE5DS0NBTl9BID09IDEpCgpkZkNvbFJlYyA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoQ09MUkNDQU5fQSA9PSAxKQoKZGZPdGhlciA8LSBkZkNhbiAlPiUKICBmaWx0ZXIoT1RIRVJDQU5QX0EgPT0gMSkKCmBgYAoKYGBge3J9ClRCbGFkRiA8LSBucm93KGRmQmxhZCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVEJsb29kRiA8LSBucm93KGRmQmxvb2QgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRCb25lRiA8LSBucm93KGRmQm9uZSAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVEJyYWluRiA8LSBucm93KGRmQnJhaW4gJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRCcmVhc3RGIDwtIG5yb3coZGZCcmVhc3QgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRFc29waEYgPC0gbnJvdyhkZkVzb3BoICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUQ2VydkYgPC0gbnJvdyhkZkNlcnZpY2FsICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUR2FsbEYgPC0gbnJvdyhkZkdhbGwgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRMYXJ5bnhGIDwtIG5yb3coZGZMYXJ5bnggJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRMZXVrRiA8LSBucm93KGRmTGV1ayAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVEx1bmdGIDwtIG5yb3coZGZMdW5nICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUTGl2ZXJGIDwtIG5yb3coZGZMaXZlciAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVE1lbGFGIDwtIG5yb3coZGZNZWxhICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUTW91dGhGIDwtIG5yb3coZGZNb3V0aCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVE92YXJ5RiA8LSBucm93KGRmT3ZhcnkgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRQYW5jRiA8LSBucm93KGRmQmxhZCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVFNraW5NZWxhRiA8LSBucm93KGRmU2tpbk1lbGEgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRTa2luTm9NZWxhRiA8LSBucm93KGRmU2tpbk5vTWVsYSAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVFNraW5Vbmtub3duRiA8LSBucm93KGRmU2tpblVua25vd24gJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwClRTdG9tYWNoRiA8LSBucm93KGRmU3RvbWFjaCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVFRoeXJvaWRGIDwtIG5yb3coZGZUaHlyb2lkICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUVGhyb2F0RiA8LSBucm93KGRmVGhyb2F0ICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUVXRlcnVzRiA8LSBucm93KGRmVXRlcnVzICU+JQogIGZpbHRlcihTRVhfQSA9PSAyKSkvVG90YWxGKjEwMApUSGFuZE5lY2tGIDwtIG5yb3coZGZIYW5kTmVjayAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVENvbFJlY0YgPC0gbnJvdyhkZkNvbFJlYyAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMikpL1RvdGFsRioxMDAKVE90aGVyRiA8LSBucm93KGRmT3RoZXIgJT4lCiAgZmlsdGVyKFNFWF9BID09IDIpKS9Ub3RhbEYqMTAwCmBgYAoKIyMjIyMgQ2FuY2VyIEFtb25nIEZlbWFsZXMKCmBgYHtyfQpDYW5jZXJGIDwtIGRhdGEuZnJhbWUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgQ2FuY2VyICA9IGMoIkJsYWRkZXIiLCAiQmxvb2QiLCJCcmFpbiIsIkJvbmUiLCJCcmVhc3QiLCJFc29waGFndXMiLCJDZXJ2aWNhbCIsIkdhbGxCbGFkZGVyIiwiTGFyeW54IiwiTGV1a2VtaWEiLCJMdW5nIiwiTGl2ZXIiLCJNZWxhbm9tYSIsIk1vdXRoIiwiT3ZhcmlhbiIsIlBhbmNyZWFzIiwiU2tpbiBNZWxhbm9tYSIsIlNraW4tTm90IE1lbGFub21hIiwiU2tpbi1Vbmtub3duIiwiU3RvbWFjaCIsIlRoeXJvaWQiLCJUaHJvYXQiLCJVdGVydXMiLCJIYW5kIGFuZCBOZWNrIiwiQ29sb25SZWN0YWwiLCJPdGhlciIpLCAgICAgICAKICAgUGVyY2VudD0gYygoVEJsYWRGKSwgKFRCbG9vZEYpLChUQnJhaW5GKSwoVEJvbmVGKSwoVEJyZWFzdEYpLChURXNvcGhGKSwoVENlcnZGKSwoVEdhbGxGKSwoVExhcnlueEYpLChUTGV1a0YpLChUTHVuZ0YpLChUTGl2ZXJGKSwoVE1lbGFGKSwoVE1vdXRoRiksKFRPdmFyeUYpLChUUGFuY0YpLChUU2tpbk1lbGFGKSwoVFNraW5Ob01lbGFGKSwoVFNraW5Vbmtub3duRiksKFRTdG9tYWNoRiksKFRUaHlyb2lkRiksKFRUaHJvYXRGKSwoVFV0ZXJ1c0YpLChUSGFuZE5lY2tGKSwoVENvbFJlY0YpLChUT3RoZXJGKSkpCgpnZ3Bsb3QoQ2FuY2VyRiwgYWVzKHggPSBQZXJjZW50LCB5PUNhbmNlcikpICsKICBnZW9tX3BvaW50KCkgKyBsYWJzKHRpdGxlID0gIkNhbmNlciBBbW9uZyBGZW1hbGVzIikKYGBgCgojIyMjIyBDYW5jZXIgQW1vbmcgTWFsZXMKCmBgYHtyfQpUQmxhZE0gPC0gbnJvdyhkZkJsYWQgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRCbG9vZE0gPC0gbnJvdyhkZkJsb29kICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApUQm9uZU0gPC0gbnJvdyhkZkJvbmUgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRCcmFpbk0gPC0gbnJvdyhkZkJyYWluICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApUQnJlYXN0TSA8LSBucm93KGRmQnJlYXN0ICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApURXNvcGhNIDwtIG5yb3coZGZFc29waCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMSkpL1RvdGFsTSoxMDAKVEdhbGxNIDwtIG5yb3coZGZHYWxsICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApUTGFyeW54TSA8LSBucm93KGRmTGFyeW54ICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApUTGV1a00gPC0gbnJvdyhkZkxldWsgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRMdW5nTSA8LSBucm93KGRmTHVuZyAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMSkpL1RvdGFsTSoxMDAKVExpdmVyTSA8LSBucm93KGRmTGl2ZXIgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRNZWxhTSA8LSBucm93KGRmTWVsYSAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMSkpL1RvdGFsTSoxMDAKVE1vdXRoTSA8LSBucm93KGRmTW91dGggJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRQYW5jTSA8LSBucm93KGRmUGFuYyAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMSkpL1RvdGFsTSoxMDAKVFByb3N0TSA8LSBucm93KGRmUHJvc3QgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRTa2luTWVsYU0gPC0gbnJvdyhkZlNraW5NZWxhICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApUU2tpbk5vTWVsYU0gPC0gbnJvdyhkZlNraW5Ob01lbGEgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRTa2luVW5rbm93bk0gPC0gbnJvdyhkZlNraW5Vbmtub3duICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApUU3RvbWFjaE0gPC0gbnJvdyhkZlN0b21hY2ggJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRUaHlyb2lkTSA8LSBucm93KGRmVGh5cm9pZCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMSkpL1RvdGFsTSoxMDAKVFRocm9hdE0gPC0gbnJvdyhkZlRocm9hdCAlPiUKICBmaWx0ZXIoU0VYX0EgPT0gMSkpL1RvdGFsTSoxMDAKVEhhbmROZWNrTSA8LSBucm93KGRmSGFuZE5lY2sgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRDb2xSZWNNIDwtIG5yb3coZGZDb2xSZWMgJT4lCiAgZmlsdGVyKFNFWF9BID09IDEpKS9Ub3RhbE0qMTAwClRPdGhlck0gPC0gbnJvdyhkZk90aGVyICU+JQogIGZpbHRlcihTRVhfQSA9PSAxKSkvVG90YWxNKjEwMApgYGAKCmBgYHtyfQpDYW5jZXJNIDwtIGRhdGEuZnJhbWUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgQ2FuY2VyICA9IGMoIkJsYWRkZXIiLCAiQmxvb2QiLCJCcmFpbiIsIkJvbmUiLCJCcmVhc3QiLCJFc29waGFndXMiLCJHYWxsQmxhZGRlciIsIkxhcnlueCIsIkxldWtlbWlhIiwiTHVuZyIsIkxpdmVyIiwiTWVsYW5vbWEiLCJNb3V0aCIsIlBhbmNyZWFzIiwiU2tpbiBNZWxhbm9tYSIsIlNraW4tTm90IE1lbGFub21hIiwiU2tpbi1Vbmtub3duIiwiU3RvbWFjaCIsIlRoeXJvaWQiLCJUaHJvYXQiLCJIYW5kIGFuZCBOZWNrIiwiQ29sb25SZWN0YWwiLCJPdGhlciIpLCAgICAgICAKICAgUGVyY2VudD0gYygoVEJsYWRNKSwgKFRCbG9vZE0pLChUQnJhaW5NKSwoVEJvbmVNKSwoVEJyZWFzdE0pLChURXNvcGhNKSwoVEdhbGxNKSwoVExhcnlueE0pLChUTGV1a00pLChUTHVuZ00pLChUTGl2ZXJNKSwoVE1lbGFNKSwoVE1vdXRoTSksKFRQYW5jTSksKFRTa2luTWVsYU0pLChUU2tpbk5vTWVsYU0pLChUU2tpblVua25vd25NKSwoVFN0b21hY2hNKSwoVFRoeXJvaWRNKSwoVFRocm9hdE0pLChUSGFuZE5lY2tNKSwoVENvbFJlY00pLChUT3RoZXJNKSkpCgpnZ3Bsb3QoQ2FuY2VyTSwgYWVzKHggPSBQZXJjZW50LCB5PUNhbmNlcikpICsKICBnZW9tX3BvaW50KCkgKyBsYWJzKHRpdGxlID0gIkNhbmNlciBBbW9uZyBNYWxlcyIpCmBgYAoKIyMjIyMgQ2FuY2VyIEFtb25nIEJvdGgKCmBgYHtyfQpkZl9DYW5tZXJnZSA8LSBtZXJnZShDYW5jZXJGLENhbmNlck0sYnk9IkNhbmNlciIsIGFsbC54ID0gVFJVRSkgCgpuYW1lcyhkZl9DYW5tZXJnZSlbbmFtZXMoZGZfQ2FubWVyZ2UpID09ICJQZXJjZW50LngiXSA8LSAiRmVtYWxlIgpuYW1lcyhkZl9DYW5tZXJnZSlbbmFtZXMoZGZfQ2FubWVyZ2UpID09ICJQZXJjZW50LnkiXSA8LSAiTWFsZSIKCmBgYAoKYGBge3J9CmRmQ2FuY2VyTWVyZ2VkIDwtIG1lbHQoZGZfQ2FubWVyZ2UsIGlkLnZhcnM9IkNhbmNlciIpCm5hbWVzKGRmQ2FuY2VyTWVyZ2VkKVtuYW1lcyhkZkNhbmNlck1lcmdlZCkgPT0gInZhbHVlIl0gPC0gIlBlcmNlbnQiCm5hbWVzKGRmQ2FuY2VyTWVyZ2VkKVtuYW1lcyhkZkNhbmNlck1lcmdlZCkgPT0gInZhcmlhYmxlIl0gPC0gIlNleCIKCmdncGxvdChkZkNhbmNlck1lcmdlZCwgYWVzKFBlcmNlbnQsQ2FuY2VyLCBjb2w9U2V4KSkgKyAKICBnZW9tX3BvaW50KCkgKyBsYWJzKHRpdGxlID0gIkNhbmNlciBBbW9uZyBNYWxlcyBhbmQgRmVtYWxlcyIpCgpgYGAKCkJvdGggbWFsZXMgYW5kIGZlbWFsZXMgaGFkIGEgaGlnaGVyIHBlcmNlbnRhZ2UgZm9yIFNraW4tTm90IE1lbGFub21hCmNhbmNlci4gVGhlIGhpZ2hlc3QgcGVyY2VudGFnZSBmb3IgY2FuY2VyIHdhcyBicmVhc3QgY2FuY2VyIGluCmZlbWFsZXMuSW4gbWFueSBvZiB0aGUgY2FuY2VyIGNhdGVnb3JpZXMsIGZlbWFsZXMgaGFkIGEgc2xpZ2h0bHkgbG93ZXIKcGVyY2VudGFnZS4KCiMgU3VtbWFyeQoKV2hpbGUgbWFueSBvZiB0aGUgd2F5cyB0byBzdGF5IGhlYWx0aHkgYXJlIGNvbW1vbmx5IGtub3duIGFuZAphZHZlcnRpc2VkLCBpdCBpcyBpbnRlcmVzdGluZyB0byBsb29rIGF0IHRoZSBkYXRhIHRvIGdldCBhIG1vcmUgc3BlY2lmaWMKaWRlYS4gV2hpbGUgbWFueSBvZiB0aGVzZSBkaWQgbm90IGhhdmUgbXVjaCBvZiBhIGRpZmZlcmVuY2UgYmV0d2VlbgpjYXRlZ29yaWVzLCB0aGVyZSBpcyBzb21lIGluZm9ybWF0aW9uIHRoYXQgY2FuIGJlIGdhaW5lZCB0aGF0IGZvbGxvdwptYW55IG9mIHRoZSBoZWFsdGggaWRlYXMgd2UgYWxyZWFkeSBrbm93LiBUaGVzZSBpbmNsdWRlCgoxLiAgSXQgaXMgbGVzcyBoZWFsdGhpZXIsIG1lbnRhbGx5IGFuZCBwaHlzaWNhbGx5LCBmb3IgeW91IHRvIHNtb2tlLgogICAgU21va2luZyBhdCBsZWFzdCAxMDAgY2lnYXJldHRlcyBjYW4gbWFrZSB0aGlzIHdvcnN0IGFuZCBpZiB5b3UgZW5kCiAgICB1cCB3aXRoIGx1bmcgY2FuY2VyLCBpdCBjb3VsZCBiZSBjb250cmlidXRlZCB0byB5b3Ugc21va2luZy4KMi4gIENhbmNlciBpcyBpbXBvcnRhbnQgdG8gd2F0Y2ggb3V0IGZvciwgYW5kIHRoZXJlIGFyZSBzb21lCiAgICBzcGVjaWZpY2FsbHkgdGhhdCBhcmUgbW9yZSBjb21tb24gYmFzZWQgb24geW91ciBzZXggYW5kIG92ZXJhbGwgbW9yZQogICAgY29tbW9uLgozLiAgV2hpbGUgaXQgaXMgbW9zdGx5IHVuYXZvaWRhYmxlLCB0aG9zZSB3aG8gaGF2ZSBkaWZmaWN1bHR5IHNlZWluZyBjYW4KICAgIGhhdmUgd29yc3QgbGlmZSBzYXRpc2ZhY3Rpb24sIHNvIGlmIHlvdSBjYW4gZ2V0IGl0IGZpeGVkIGJ5IHN1cmdlcnkKICAgIG9yIGdsYXNzZXMvY29udGFjdHMsIGl0IHdpbGwgYmUgaGVscGZ1bC4KNC4gIEl0IGlzIGJldHRlciB0byBmb3IgeW91ciBtZW50YWwgYW5kIHBoeXNpY2FsIGhlYWx0aCB0byBzdGF5IGFyb3VuZCBhCiAgICBub3JtYWwgQk1JLiBIb3dldmVyLCB0aGlzIGNvdWxkIGJlIGFyZ3VlZCBiYXNlZCBvbiBpZiB5b3VyIHdlaWdodAogICAgY29tZXMgZnJvbSBub24tbXVzY2xlIGZhdCBvciBtdXNjbGUgZmF0Lgo1LiAgQSBoaWdoZXIgZWR1Y2F0aW9uIGNvdWxkIHBvdGVudGlhbGx5IGxlYWQgeW91IHRvIGZlZWwgbW9yZSBzYXRpc2ZpZWQKICAgIGFuZCBoYXZlIGJldHRlciBoZWFsdGguCg==