1. Defining malnutrition
1.1. Prerequisites
library(tidyverse)
library(zscorer)
library(readr)
library(dplyr)
library (lubridate)
library (ggplot2)
library (rmarkdown)
library(openxlsx)
PSFI_df_malnutrition <- read_csv("Ben_cut_4_27.csv")
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
date_present = as.POSIXct(date_present, format = "%d%b%Y:%H:%M:%S", tz = "UTC"),
dob = mdy(dob),
age_days_exact = as.numeric(difftime(date_present, dob, units = "days"))
)
summary(PSFI_df_malnutrition$age_days_exact)
Min. 1st Qu. Median Mean 3rd Qu. Max.
32.03 289.19 604.61 1124.44 1461.64 5452.40
View(PSFI_df_malnutrition)
1.2. Anthroprometric analysis
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(age_years = age_days_exact / 365.25)
summary(PSFI_df_malnutrition$age_years)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.08768 0.79176 1.65535 3.07854 4.00176 14.92786
PSFI_df_malnutrition %>%
filter(case_control == 1) %>%
select(ht, wt, age_years, muac) %>%
summary()
ht wt age_years muac
Min. : 20.00 Min. : 3.20 Min. : 0.08768 Min. : 9.00
1st Qu.: 67.00 1st Qu.: 7.00 1st Qu.: 0.73436 1st Qu.:14.00
Median : 78.00 Median : 9.50 Median : 1.40141 Median :15.00
Mean : 85.23 Mean :12.17 Mean : 2.83539 Mean :15.38
3rd Qu.: 98.00 3rd Qu.:14.00 3rd Qu.: 3.49267 3rd Qu.:17.00
Max. :192.00 Max. :72.00 Max. :14.92786 Max. :27.00
NAs :1 NAs :2
# Layout to split the screen
layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
# Draw the boxplot and the histogram
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$ht[PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(0,200), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$ht[PSFI_df_malnutrition$case_control == 1]
, breaks=40 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Height (cm)", xlim=c(0,200))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$wt[PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(0,80), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$wt[PSFI_df_malnutrition$case_control == 1]
, breaks=40 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Weight (kg)", xlim=c(0,80))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$muac[PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(5,30), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$muac[PSFI_df_malnutrition$case_control == 1]
, breaks=20 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Mid-upper arm circumference (cm)", xlim=c(5,30))
abline(v = 11.5, col = "red", lwd = 2, lty = 2) # severe
abline(v = 12.5, col = "blue", lwd = 2, lty = 2) # moderate

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$age_years[PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(0,15), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$age_years[PSFI_df_malnutrition$case_control == 1]
, breaks=40 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Age (years)", xlim=c(0,15))

1.3. Z-scorer
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(sex_who = if_else(sex == 1, 1, 2))
summary(PSFI_df_malnutrition$sex_who)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 1.000 1.000 1.427 2.000 2.000
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
age_group = case_when(
age_days_exact < 5 * 365.25 ~ 0L,
age_days_exact >= 5 * 365.25 ~ 1L,
TRUE ~ NA_integer_
)
)
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
wflz = addWGSR(
data = .,
sex = "sex_who",
firstPart = "wt",
secondPart = "ht",
index = "wfl"
)$wflz,
wfhz = addWGSR(
data = .,
sex = "sex_who",
firstPart = "wt",
secondPart = "ht",
index = "wfh"
)$wfhz,
baz = addWGSR(
data = .,
sex = "sex_who",
firstPart = "wt",
secondPart = "ht",
thirdPart = "age_days_exact",
index = "bfa"
)$bfaz,
)
==================================================================================
==================================================================================
==================================================================================
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
muacz = case_when(
muac >= 12.5 ~ 0,
muac >= 11.5 & muac < 12.5 ~ -2.5,
muac < 11.5 ~ -4,
TRUE ~ NA_real_
)
)
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
zscore_unified = case_when(
age_group == 0 & ht >= 45 & ht < 65 ~ wflz,
age_group == 0 & ht >= 65 & ht < 120 ~ wfhz,
age_group == 0 & (ht < 45 | ht >= 120 | is.na(ht)) ~ muacz,
age_group == 1 ~ baz,
TRUE ~ NA_real_
)
)
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
malnutrition = case_when(
is.na(zscore_unified) ~ NA_integer_,
zscore_unified < -3 ~ 2L,
zscore_unified >= -3 & zscore_unified < -2 ~ 1L,
TRUE ~ 0L
)
)
PSFI_df_malnutrition <- PSFI_df_malnutrition %>%
mutate(
malnutrition_source = case_when(
age_group == 0 & ht >= 45 & ht < 65 ~ "WFL",
age_group == 0 & ht >= 65 & ht < 120 ~ "WFH",
age_group == 0 & (ht < 45 | ht >= 120 | is.na(ht)) ~ "MUAC",
age_group == 1 ~ "BFA",
TRUE ~ NA_character_
)
)
1.4 Z score check
subset_baz <- PSFI_df_malnutrition %>%
filter(age_group == 1 & case_control == 1) %>%
pull(baz)
summary(subset_baz)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-11.0000 -2.1325 -0.4700 -0.2723 1.1300 32.6700
length(subset_baz)
[1] 128
sum(subset_baz < -5, na.rm = TRUE)
[1] 6
sum(subset_baz > 5, na.rm = TRUE)
[1] 5
subset_wfhz <- PSFI_df_malnutrition %>%
filter(age_group == 0 & ht >= 65 & ht < 120 & case_control == 1) %>%
pull(wfhz)
summary(subset_wfhz)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-10.5900 -2.4175 -0.8900 -0.9841 0.7500 12.8800
length(subset_wfhz)
[1] 478
sum(subset_wfhz < -5, na.rm = TRUE)
[1] 36
sum(subset_wfhz > 5, na.rm = TRUE)
[1] 3
subset_wflz <- PSFI_df_malnutrition %>%
filter(age_group == 0 & ht >= 45 & ht < 65 & case_control == 1) %>%
pull(wflz)
summary(subset_wflz)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-4.9000 -1.0075 0.8800 0.9719 2.4400 13.7700
length(subset_wflz)
[1] 136
sum(subset_wflz < -5, na.rm = TRUE)
[1] 0
sum(subset_wflz > 5, na.rm = TRUE)
[1] 10
layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$baz[PSFI_df_malnutrition$age_group == 1 & PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(-12,33), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$baz[PSFI_df_malnutrition$age_group == 1 & PSFI_df_malnutrition$case_control == 1]
, breaks=50 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="BMI for age (z-score)", xlim=c(-12,33))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$baz[PSFI_df_malnutrition$age_group == 1 & PSFI_df_malnutrition$case_control == 1 & PSFI_df_malnutrition$baz > -5 & PSFI_df_malnutrition$baz <5] , horizontal=TRUE , ylim=c(-5,5), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$baz[PSFI_df_malnutrition$age_group == 1 & PSFI_df_malnutrition$case_control == 1 & PSFI_df_malnutrition$baz > -5 & PSFI_df_malnutrition$baz <5]
, breaks=50 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="BMI for age (z-score with outlier treshold at 5)", xlim=c(-5,5))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$wfhz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 65 & PSFI_df_malnutrition$ht < 120 & PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(-11,13), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$wfhz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 65 & PSFI_df_malnutrition$ht < 120 & PSFI_df_malnutrition$case_control == 1]
, breaks=50 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Weight-for-height (z-score)", xlim=c(-11,13))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$wfhz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 65 & PSFI_df_malnutrition$ht < 120 & PSFI_df_malnutrition$case_control == 1 & PSFI_df_malnutrition$wfhz > -5 & PSFI_df_malnutrition$wfhz <5] , horizontal=TRUE , ylim=c(-5,5), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$wfhz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 65 & PSFI_df_malnutrition$ht < 120 & PSFI_df_malnutrition$case_control == 1 & PSFI_df_malnutrition$wfhz > -5 & PSFI_df_malnutrition$wfhz <5]
, breaks=50 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Weight-for-height (z-score with outlier treshold at 5)", xlim=c(-5,5))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$wflz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 45 & PSFI_df_malnutrition$ht < 65 & PSFI_df_malnutrition$case_control == 1] , horizontal=TRUE , ylim=c(-5,14), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$wflz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 45 & PSFI_df_malnutrition$ht < 65 & PSFI_df_malnutrition$case_control == 1]
, breaks=50 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Weight for length (z-score)", xlim=c(-5,14))

layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(1,8))
par(mar=c(0, 3.1, 1.1, 2.1))
boxplot(PSFI_df_malnutrition$wflz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 45 & PSFI_df_malnutrition$ht < 65 & PSFI_df_malnutrition$case_control == 1 & PSFI_df_malnutrition$wflz > -5 & PSFI_df_malnutrition$wflz <5] , horizontal=TRUE , ylim=c(-5,5), xaxt="n" , col=rgb(0.8,0.8,0,0.5) , frame=F)
par(mar=c(4, 3.1, 1.1, 2.1))
hist(PSFI_df_malnutrition$wflz[PSFI_df_malnutrition$age_group == 0 & PSFI_df_malnutrition$ht >= 45 & PSFI_df_malnutrition$ht < 65 & PSFI_df_malnutrition$case_control == 1& PSFI_df_malnutrition$wflz > -5 & PSFI_df_malnutrition$wflz <5]
, breaks=50 , col=rgb(1,0.8,0.8,1) , border=F , main="" , xlab="Weight for length (z-score with outlier treshold at 5)", xlim=c(-5,5))

## muac is not based on z-score, but rather if it is <115mm, between 115-125 or >125mm
PSFI_df_malnutrition %>%
filter(case_control == 1 & age_group == 0 & (ht < 45 | ht >= 120 | is.na(ht))) %>%
drop_na(muacz) %>%
mutate(
malnutrition_status = case_when(
muacz < -3 ~ "Severe malnutrition",
muacz >= -3 & muacz < -2 ~ "Moderate malnutrition",
muacz >= -2 ~ "No malnutrition",
TRUE ~ NA_character_
)
) %>%
ggplot(aes(x = malnutrition_status)) +
geom_bar() +
labs(
x = "Malnutrition status based on MUAC",
y = "N"
)

1.5 Data check
PSFI_df_malnutrition%>%
group_by(malnutrition) %>%
summarize(
malnutrition_missing = sum(is.na(malnutrition)),
mort_inhosp_missing = sum(is.na(mort_inhosp)), #103 mort_inhosp_miissing = controls
)
PSFI_df_malnutrition %>%
filter (case_control == 1) %>%
group_by(malnutrition_source) %>%
summarize(
count_malnut = n()
)
# NA due to child with height of 20 cm (under WHO curve for wfh/wfl) and 38 days old (too young for MUAC)
PSFI_df_malnutrition %>%
filter (case_control == 1) %>%
group_by(malnutrition) %>%
summarize(
count_malnut = n()
)
PSFI_df_malnutrition %>%
drop_na(malnutrition, mort_inhosp) %>%
ggplot(aes(x = factor(malnutrition))) +
geom_bar() +
labs(
x = "Malnutrition",
y = "N"
)

PSFI_df_malnutrition%>%
filter (case_control == 1) %>%
count(malnutrition, mort_inhosp) %>%
group_by(malnutrition) %>%
mutate(prop = n / sum(n))
PSFI_df_malnutrition %>%
drop_na(mort_inhosp, malnutrition) %>% #only cases & minus the one previously mentioned NA
ggplot +
(aes(x = factor(malnutrition), fill = factor(mort_inhosp))) +
geom_bar(stat = "count", position = "fill") +
labs(
x = "Malnutrition",
y = "Proportion",
fill = "Mortality"
)

PSFI_df_malnutrition %>%
count(malnutrition, case_control) %>%
group_by(malnutrition) %>%
mutate(prop = n / sum(n))
PSFI_df_malnutrition %>%
drop_na(malnutrition) %>%
ggplot +
(aes(x = factor(malnutrition), fill = factor(case_control))) +
geom_bar(stat = "count", position = "fill") +
labs(
x = "Malnutrition",
y = "Proportion",
fill = "Case/Control"
)

write.xlsx(PSFI_df_malnutrition, file = "PSFI_final_malnutrition.xlsx")
LS0tCnRpdGxlOiAiVGhlIERvdWJsZSBCdXJkZW4gb2YgTWFsbnV0cml0aW9uIGFuZCBQZWRpYXRyaWMgU2Vwc2lzIGluIFRhbnphbmlhIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKIyAxLiBEZWZpbmluZyBtYWxudXRyaXRpb24KCiMjIDEuMS4gUHJlcmVxdWlzaXRlcwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHpzY29yZXIpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkgKGx1YnJpZGF0ZSkKbGlicmFyeSAoZ2dwbG90MikKbGlicmFyeSAocm1hcmtkb3duKQpsaWJyYXJ5KG9wZW54bHN4KQpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSByZWFkX2NzdigiQmVuX2N1dF80XzI3LmNzdiIpCmBgYAoKYGBge3J9CiAgUFNGSV9kZl9tYWxudXRyaXRpb24gPC0gUFNGSV9kZl9tYWxudXRyaXRpb24gJT4lCiAgbXV0YXRlKAogICAgZGF0ZV9wcmVzZW50ID0gYXMuUE9TSVhjdChkYXRlX3ByZXNlbnQsIGZvcm1hdCA9ICIlZCViJVk6JUg6JU06JVMiLCB0eiA9ICJVVEMiKSwKICAgIGRvYiA9IG1keShkb2IpLAogICAgYWdlX2RheXNfZXhhY3QgPSBhcy5udW1lcmljKGRpZmZ0aW1lKGRhdGVfcHJlc2VudCwgZG9iLCB1bml0cyA9ICJkYXlzIikpCiAgKQogIAogIApzdW1tYXJ5KFBTRklfZGZfbWFsbnV0cml0aW9uJGFnZV9kYXlzX2V4YWN0KQpgYGAKCmBgYHtyfQpWaWV3KFBTRklfZGZfbWFsbnV0cml0aW9uKQoKYGBgCgojIyAxLjIuIEFudGhyb3Byb21ldHJpYyBhbmFseXNpcwoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uIDwtIFBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIG11dGF0ZShhZ2VfeWVhcnMgPSBhZ2VfZGF5c19leGFjdCAvIDM2NS4yNSkKCnN1bW1hcnkoUFNGSV9kZl9tYWxudXRyaXRpb24kYWdlX3llYXJzKQpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBmaWx0ZXIoY2FzZV9jb250cm9sID09IDEpICU+JQogIHNlbGVjdChodCwgd3QsIGFnZV95ZWFycywgbXVhYykgJT4lCiAgc3VtbWFyeSgpCmBgYAoKYGBge3J9CiMgTGF5b3V0IHRvIHNwbGl0IHRoZSBzY3JlZW4KbGF5b3V0KG1hdCA9IG1hdHJpeChjKDEsMiksMiwxLCBieXJvdz1UUlVFKSwgIGhlaWdodCA9IGMoMSw4KSkKIAojIERyYXcgdGhlIGJveHBsb3QgYW5kIHRoZSBoaXN0b2dyYW0gCnBhcihtYXI9YygwLCAzLjEsIDEuMSwgMi4xKSkKYm94cGxvdChQU0ZJX2RmX21hbG51dHJpdGlvbiRodFtQU0ZJX2RmX21hbG51dHJpdGlvbiRjYXNlX2NvbnRyb2wgPT0gMV0gLCBob3Jpem9udGFsPVRSVUUgLCB5bGltPWMoMCwyMDApLCB4YXh0PSJuIiAsIGNvbD1yZ2IoMC44LDAuOCwwLDAuNSkgLCBmcmFtZT1GKQpwYXIobWFyPWMoNCwgMy4xLCAxLjEsIDIuMSkpCmhpc3QoUFNGSV9kZl9tYWxudXRyaXRpb24kaHRbUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDFdCiAgICAgLCBicmVha3M9NDAgLCBjb2w9cmdiKDEsMC44LDAuOCwxKSAsIGJvcmRlcj1GICwgbWFpbj0iIiAsIHhsYWI9IkhlaWdodCAoY20pIiwgeGxpbT1jKDAsMjAwKSkKYGBgCgpgYGB7cn0KbGF5b3V0KG1hdCA9IG1hdHJpeChjKDEsMiksMiwxLCBieXJvdz1UUlVFKSwgIGhlaWdodCA9IGMoMSw4KSkKIHBhcihtYXI9YygwLCAzLjEsIDEuMSwgMi4xKSkKYm94cGxvdChQU0ZJX2RmX21hbG51dHJpdGlvbiR3dFtQU0ZJX2RmX21hbG51dHJpdGlvbiRjYXNlX2NvbnRyb2wgPT0gMV0gLCBob3Jpem9udGFsPVRSVUUgLCB5bGltPWMoMCw4MCksIHhheHQ9Im4iICwgY29sPXJnYigwLjgsMC44LDAsMC41KSAsIGZyYW1lPUYpCnBhcihtYXI9Yyg0LCAzLjEsIDEuMSwgMi4xKSkKaGlzdChQU0ZJX2RmX21hbG51dHJpdGlvbiR3dFtQU0ZJX2RmX21hbG51dHJpdGlvbiRjYXNlX2NvbnRyb2wgPT0gMV0KICAgICAsIGJyZWFrcz00MCAsIGNvbD1yZ2IoMSwwLjgsMC44LDEpICwgYm9yZGVyPUYgLCBtYWluPSIiICwgeGxhYj0iV2VpZ2h0IChrZykiLCB4bGltPWMoMCw4MCkpCmBgYAoKYGBge3J9CmxheW91dChtYXQgPSBtYXRyaXgoYygxLDIpLDIsMSwgYnlyb3c9VFJVRSksICBoZWlnaHQgPSBjKDEsOCkpCnBhcihtYXI9YygwLCAzLjEsIDEuMSwgMi4xKSkKYm94cGxvdChQU0ZJX2RmX21hbG51dHJpdGlvbiRtdWFjW1BTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxXSAsIGhvcml6b250YWw9VFJVRSAsIHlsaW09Yyg1LDMwKSwgeGF4dD0ibiIgLCBjb2w9cmdiKDAuOCwwLjgsMCwwLjUpICwgZnJhbWU9RikKcGFyKG1hcj1jKDQsIDMuMSwgMS4xLCAyLjEpKQpoaXN0KFBTRklfZGZfbWFsbnV0cml0aW9uJG11YWNbUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDFdCiAgICAgLCBicmVha3M9MjAgLCBjb2w9cmdiKDEsMC44LDAuOCwxKSAsIGJvcmRlcj1GICwgbWFpbj0iIiAsIHhsYWI9Ik1pZC11cHBlciBhcm0gY2lyY3VtZmVyZW5jZSAoY20pIiwgeGxpbT1jKDUsMzApKQphYmxpbmUodiA9IDExLjUsIGNvbCA9ICJyZWQiLCBsd2QgPSAyLCBsdHkgPSAyKSAgICMgc2V2ZXJlCmFibGluZSh2ID0gMTIuNSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsdHkgPSAyKSAgIyBtb2RlcmF0ZQpgYGAKCmBgYHtyfQpsYXlvdXQobWF0ID0gbWF0cml4KGMoMSwyKSwyLDEsIGJ5cm93PVRSVUUpLCAgaGVpZ2h0ID0gYygxLDgpKQogcGFyKG1hcj1jKDAsIDMuMSwgMS4xLCAyLjEpKQpib3hwbG90KFBTRklfZGZfbWFsbnV0cml0aW9uJGFnZV95ZWFyc1tQU0ZJX2RmX21hbG51dHJpdGlvbiRjYXNlX2NvbnRyb2wgPT0gMV0gLCBob3Jpem9udGFsPVRSVUUgLCB5bGltPWMoMCwxNSksIHhheHQ9Im4iICwgY29sPXJnYigwLjgsMC44LDAsMC41KSAsIGZyYW1lPUYpCnBhcihtYXI9Yyg0LCAzLjEsIDEuMSwgMi4xKSkKaGlzdChQU0ZJX2RmX21hbG51dHJpdGlvbiRhZ2VfeWVhcnNbUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDFdCiAgICAgLCBicmVha3M9NDAgLCBjb2w9cmdiKDEsMC44LDAuOCwxKSAsIGJvcmRlcj1GICwgbWFpbj0iIiAsIHhsYWI9IkFnZSAoeWVhcnMpIiwgeGxpbT1jKDAsMTUpKQpgYGAKCiMjIDEuMy4gWi1zY29yZXIKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBtdXRhdGUoc2V4X3dobyA9IGlmX2Vsc2Uoc2V4ID09IDEsIDEsIDIpKQoKc3VtbWFyeShQU0ZJX2RmX21hbG51dHJpdGlvbiRzZXhfd2hvKQpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBtdXRhdGUoCiAgICBhZ2VfZ3JvdXAgPSBjYXNlX3doZW4oCiAgICAgIGFnZV9kYXlzX2V4YWN0IDwgNSAqIDM2NS4yNSB+IDBMLAogICAgICBhZ2VfZGF5c19leGFjdCA+PSA1ICogMzY1LjI1IH4gMUwsCiAgICAgIFRSVUUgfiBOQV9pbnRlZ2VyXwogICAgKQogICkKCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uIDwtIFBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIG11dGF0ZSgKICAgIHdmbHogPSBhZGRXR1NSKAogICAgICBkYXRhID0gLiwKICAgICAgc2V4ID0gInNleF93aG8iLAogICAgICBmaXJzdFBhcnQgPSAid3QiLAogICAgICBzZWNvbmRQYXJ0ID0gImh0IiwKICAgICAgaW5kZXggPSAid2ZsIgogICAgKSR3Zmx6LAogICAgCiAgICB3Zmh6ID0gYWRkV0dTUigKICAgICAgZGF0YSA9IC4sCiAgICAgIHNleCA9ICJzZXhfd2hvIiwKICAgICAgZmlyc3RQYXJ0ID0gInd0IiwKICAgICAgc2Vjb25kUGFydCA9ICJodCIsCiAgICAgIGluZGV4ID0gIndmaCIKICAgICkkd2ZoeiwKICAgIAogICAgYmF6ID0gYWRkV0dTUigKICAgICAgZGF0YSA9IC4sCiAgICAgIHNleCA9ICJzZXhfd2hvIiwKICAgICAgZmlyc3RQYXJ0ID0gInd0IiwKICAgICAgc2Vjb25kUGFydCA9ICJodCIsCiAgICAgIHRoaXJkUGFydCA9ICJhZ2VfZGF5c19leGFjdCIsCiAgICAgIGluZGV4ID0gImJmYSIKICAgICkkYmZheiwKICApCgpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBtdXRhdGUoCiAgICBtdWFjeiA9IGNhc2Vfd2hlbigKICAgICAgbXVhYyA+PSAxMi41IH4gMCwKICAgICAgbXVhYyA+PSAxMS41ICYgbXVhYyA8IDEyLjUgfiAtMi41LAogICAgICBtdWFjIDwgMTEuNSB+IC00LAogICAgICBUUlVFIH4gTkFfcmVhbF8KICAgICkKICApCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uIDwtIFBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIG11dGF0ZSgKICAgIHpzY29yZV91bmlmaWVkID0gY2FzZV93aGVuKAogICAgICBhZ2VfZ3JvdXAgPT0gMCAmIGh0ID49IDQ1ICYgaHQgPCA2NSB+IHdmbHosCiAgICAgIGFnZV9ncm91cCA9PSAwICYgaHQgPj0gNjUgJiBodCA8IDEyMCB+IHdmaHosCiAgICAgIGFnZV9ncm91cCA9PSAwICYgKGh0IDwgNDUgfCBodCA+PSAxMjAgfCBpcy5uYShodCkpIH4gbXVhY3osCiAgICAgIGFnZV9ncm91cCA9PSAxIH4gYmF6LAogICAgICBUUlVFIH4gTkFfcmVhbF8KICAgICkKICApCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uIDwtIFBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIG11dGF0ZSgKICAgIG1hbG51dHJpdGlvbiA9IGNhc2Vfd2hlbigKICBpcy5uYSh6c2NvcmVfdW5pZmllZCkgfiBOQV9pbnRlZ2VyXywKICB6c2NvcmVfdW5pZmllZCA8IC0zIH4gMkwsCiAgenNjb3JlX3VuaWZpZWQgPj0gLTMgJiB6c2NvcmVfdW5pZmllZCA8IC0yIH4gMUwsCiAgVFJVRSB+IDBMCiAgICApCiAgKQpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiA8LSBQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBtdXRhdGUoCiAgICBtYWxudXRyaXRpb25fc291cmNlID0gY2FzZV93aGVuKAogICAgICBhZ2VfZ3JvdXAgPT0gMCAmIGh0ID49IDQ1ICYgaHQgPCA2NSAgfiAiV0ZMIiwKICAgICAgYWdlX2dyb3VwID09IDAgJiBodCA+PSA2NSAmIGh0IDwgMTIwIH4gIldGSCIsCiAgICAgIGFnZV9ncm91cCA9PSAwICYgKGh0IDwgNDUgfCBodCA+PSAxMjAgfCBpcy5uYShodCkpIH4gIk1VQUMiLAogICAgICBhZ2VfZ3JvdXAgPT0gMSB+ICJCRkEiLAogICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXwogICAgKQogICkKYGBgCgojIyAxLjQgWiBzY29yZSBjaGVjawoKYGBge3J9CnN1YnNldF9iYXogPC0gUFNGSV9kZl9tYWxudXRyaXRpb24gJT4lCiAgZmlsdGVyKGFnZV9ncm91cCA9PSAxICYgY2FzZV9jb250cm9sID09IDEpICU+JQogIHB1bGwoYmF6KQoKc3VtbWFyeShzdWJzZXRfYmF6KQpsZW5ndGgoc3Vic2V0X2JheikKc3VtKHN1YnNldF9iYXogPCAtNSwgbmEucm0gPSBUUlVFKQpzdW0oc3Vic2V0X2JheiA+IDUsIG5hLnJtID0gVFJVRSkKYGBgCgpgYGB7cn0Kc3Vic2V0X3dmaHogPC0gUFNGSV9kZl9tYWxudXRyaXRpb24gJT4lCiAgZmlsdGVyKGFnZV9ncm91cCA9PSAwICYgaHQgPj0gNjUgJiBodCA8IDEyMCAmIGNhc2VfY29udHJvbCA9PSAxKSAlPiUKICBwdWxsKHdmaHopCgpzdW1tYXJ5KHN1YnNldF93Zmh6KQpsZW5ndGgoc3Vic2V0X3dmaHopCnN1bShzdWJzZXRfd2ZoeiA8IC01LCBuYS5ybSA9IFRSVUUpCnN1bShzdWJzZXRfd2ZoeiA+IDUsIG5hLnJtID0gVFJVRSkKCmBgYAoKYGBge3J9CnN1YnNldF93Zmx6IDwtIFBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIGZpbHRlcihhZ2VfZ3JvdXAgPT0gMCAmIGh0ID49IDQ1ICYgaHQgPCA2NSAmIGNhc2VfY29udHJvbCA9PSAxKSAlPiUKICBwdWxsKHdmbHopCgpzdW1tYXJ5KHN1YnNldF93Zmx6KQpsZW5ndGgoc3Vic2V0X3dmbHopCnN1bShzdWJzZXRfd2ZseiA8IC01LCBuYS5ybSA9IFRSVUUpCnN1bShzdWJzZXRfd2ZseiA+IDUsIG5hLnJtID0gVFJVRSkKYGBgCmBgYHtyfQpsYXlvdXQobWF0ID0gbWF0cml4KGMoMSwyKSwyLDEsIGJ5cm93PVRSVUUpLCAgaGVpZ2h0ID0gYygxLDgpKQogcGFyKG1hcj1jKDAsIDMuMSwgMS4xLCAyLjEpKQpib3hwbG90KFBTRklfZGZfbWFsbnV0cml0aW9uJGJheltQU0ZJX2RmX21hbG51dHJpdGlvbiRhZ2VfZ3JvdXAgPT0gMSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxXSAsIGhvcml6b250YWw9VFJVRSAsIHlsaW09YygtMTIsMzMpLCB4YXh0PSJuIiAsIGNvbD1yZ2IoMC44LDAuOCwwLDAuNSkgLCBmcmFtZT1GKQpwYXIobWFyPWMoNCwgMy4xLCAxLjEsIDIuMSkpCmhpc3QoUFNGSV9kZl9tYWxudXRyaXRpb24kYmF6W1BTRklfZGZfbWFsbnV0cml0aW9uJGFnZV9ncm91cCA9PSAxICYgUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDFdCiAgICAgLCBicmVha3M9NTAgLCBjb2w9cmdiKDEsMC44LDAuOCwxKSAsIGJvcmRlcj1GICwgbWFpbj0iIiAsIHhsYWI9IkJNSSBmb3IgYWdlICh6LXNjb3JlKSIsIHhsaW09YygtMTIsMzMpKQpgYGAKCmBgYHtyfQpsYXlvdXQobWF0ID0gbWF0cml4KGMoMSwyKSwyLDEsIGJ5cm93PVRSVUUpLCAgaGVpZ2h0ID0gYygxLDgpKQogcGFyKG1hcj1jKDAsIDMuMSwgMS4xLCAyLjEpKQpib3hwbG90KFBTRklfZGZfbWFsbnV0cml0aW9uJGJheltQU0ZJX2RmX21hbG51dHJpdGlvbiRhZ2VfZ3JvdXAgPT0gMSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxICYgUFNGSV9kZl9tYWxudXRyaXRpb24kYmF6ID4gLTUgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRiYXogPDVdICwgaG9yaXpvbnRhbD1UUlVFICwgeWxpbT1jKC01LDUpLCB4YXh0PSJuIiAsIGNvbD1yZ2IoMC44LDAuOCwwLDAuNSkgLCBmcmFtZT1GKQpwYXIobWFyPWMoNCwgMy4xLCAxLjEsIDIuMSkpCmhpc3QoUFNGSV9kZl9tYWxudXRyaXRpb24kYmF6W1BTRklfZGZfbWFsbnV0cml0aW9uJGFnZV9ncm91cCA9PSAxICYgUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDEgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRiYXogPiAtNSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGJheiA8NV0KICAgICAsIGJyZWFrcz01MCAsIGNvbD1yZ2IoMSwwLjgsMC44LDEpICwgYm9yZGVyPUYgLCBtYWluPSIiICwgeGxhYj0iQk1JIGZvciBhZ2UgKHotc2NvcmUgd2l0aCBvdXRsaWVyIHRyZXNob2xkIGF0IDUpIiwgeGxpbT1jKC01LDUpKQpgYGAKCmBgYHtyfQpsYXlvdXQobWF0ID0gbWF0cml4KGMoMSwyKSwyLDEsIGJ5cm93PVRSVUUpLCAgaGVpZ2h0ID0gYygxLDgpKQogcGFyKG1hcj1jKDAsIDMuMSwgMS4xLCAyLjEpKQpib3hwbG90KFBTRklfZGZfbWFsbnV0cml0aW9uJHdmaHpbUFNGSV9kZl9tYWxudXRyaXRpb24kYWdlX2dyb3VwID09IDAgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRodCA+PSA2NSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGh0IDwgMTIwICYgUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDFdICwgaG9yaXpvbnRhbD1UUlVFICwgeWxpbT1jKC0xMSwxMyksIHhheHQ9Im4iICwgY29sPXJnYigwLjgsMC44LDAsMC41KSAsIGZyYW1lPUYpCnBhcihtYXI9Yyg0LCAzLjEsIDEuMSwgMi4xKSkKaGlzdChQU0ZJX2RmX21hbG51dHJpdGlvbiR3Zmh6W1BTRklfZGZfbWFsbnV0cml0aW9uJGFnZV9ncm91cCA9PSAwICYgUFNGSV9kZl9tYWxudXRyaXRpb24kaHQgPj0gNjUgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRodCA8IDEyMCAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxXQogICAgICwgYnJlYWtzPTUwICwgY29sPXJnYigxLDAuOCwwLjgsMSkgLCBib3JkZXI9RiAsIG1haW49IiIgLCB4bGFiPSJXZWlnaHQtZm9yLWhlaWdodCAoei1zY29yZSkiLCB4bGltPWMoLTExLDEzKSkKYGBgCmBgYHtyfQpsYXlvdXQobWF0ID0gbWF0cml4KGMoMSwyKSwyLDEsIGJ5cm93PVRSVUUpLCAgaGVpZ2h0ID0gYygxLDgpKQogcGFyKG1hcj1jKDAsIDMuMSwgMS4xLCAyLjEpKQpib3hwbG90KFBTRklfZGZfbWFsbnV0cml0aW9uJHdmaHpbUFNGSV9kZl9tYWxudXRyaXRpb24kYWdlX2dyb3VwID09IDAgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRodCA+PSA2NSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGh0IDwgMTIwICYgUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDEgICYgUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZoeiA+IC01ICYgUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZoeiA8NV0gLCBob3Jpem9udGFsPVRSVUUgLCB5bGltPWMoLTUsNSksIHhheHQ9Im4iICwgY29sPXJnYigwLjgsMC44LDAsMC41KSAsIGZyYW1lPUYpCnBhcihtYXI9Yyg0LCAzLjEsIDEuMSwgMi4xKSkKaGlzdChQU0ZJX2RmX21hbG51dHJpdGlvbiR3Zmh6W1BTRklfZGZfbWFsbnV0cml0aW9uJGFnZV9ncm91cCA9PSAwICYgUFNGSV9kZl9tYWxudXRyaXRpb24kaHQgPj0gNjUgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRodCA8IDEyMCAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxICYgUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZoeiA+IC01ICYgUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZoeiA8NV0KICAgICAsIGJyZWFrcz01MCAsIGNvbD1yZ2IoMSwwLjgsMC44LDEpICwgYm9yZGVyPUYgLCBtYWluPSIiICwgeGxhYj0iV2VpZ2h0LWZvci1oZWlnaHQgKHotc2NvcmUgd2l0aCBvdXRsaWVyIHRyZXNob2xkIGF0IDUpIiwgeGxpbT1jKC01LDUpKQpgYGAKCmBgYHtyfQpsYXlvdXQobWF0ID0gbWF0cml4KGMoMSwyKSwyLDEsIGJ5cm93PVRSVUUpLCAgaGVpZ2h0ID0gYygxLDgpKQogcGFyKG1hcj1jKDAsIDMuMSwgMS4xLCAyLjEpKQpib3hwbG90KFBTRklfZGZfbWFsbnV0cml0aW9uJHdmbHpbUFNGSV9kZl9tYWxudXRyaXRpb24kYWdlX2dyb3VwID09IDAgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRodCA+PSA0NSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGh0IDwgNjUgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRjYXNlX2NvbnRyb2wgPT0gMV0gLCBob3Jpem9udGFsPVRSVUUgLCB5bGltPWMoLTUsMTQpLCB4YXh0PSJuIiAsIGNvbD1yZ2IoMC44LDAuOCwwLDAuNSkgLCBmcmFtZT1GKQpwYXIobWFyPWMoNCwgMy4xLCAxLjEsIDIuMSkpCmhpc3QoUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZseltQU0ZJX2RmX21hbG51dHJpdGlvbiRhZ2VfZ3JvdXAgPT0gMCAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGh0ID49IDQ1ICYgUFNGSV9kZl9tYWxudXRyaXRpb24kaHQgPCA2NSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxXQogICAgICwgYnJlYWtzPTUwICwgY29sPXJnYigxLDAuOCwwLjgsMSkgLCBib3JkZXI9RiAsIG1haW49IiIgLCB4bGFiPSJXZWlnaHQgZm9yIGxlbmd0aCAoei1zY29yZSkiLCB4bGltPWMoLTUsMTQpKQpgYGAKYGBge3J9CmxheW91dChtYXQgPSBtYXRyaXgoYygxLDIpLDIsMSwgYnlyb3c9VFJVRSksICBoZWlnaHQgPSBjKDEsOCkpCiBwYXIobWFyPWMoMCwgMy4xLCAxLjEsIDIuMSkpCmJveHBsb3QoUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZseltQU0ZJX2RmX21hbG51dHJpdGlvbiRhZ2VfZ3JvdXAgPT0gMCAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGh0ID49IDQ1ICYgUFNGSV9kZl9tYWxudXRyaXRpb24kaHQgPCA2NSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJGNhc2VfY29udHJvbCA9PSAxICYgUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZseiA+IC01ICYgUFNGSV9kZl9tYWxudXRyaXRpb24kd2ZseiA8NV0gLCBob3Jpem9udGFsPVRSVUUgLCB5bGltPWMoLTUsNSksIHhheHQ9Im4iICwgY29sPXJnYigwLjgsMC44LDAsMC41KSAsIGZyYW1lPUYpCnBhcihtYXI9Yyg0LCAzLjEsIDEuMSwgMi4xKSkKaGlzdChQU0ZJX2RmX21hbG51dHJpdGlvbiR3Zmx6W1BTRklfZGZfbWFsbnV0cml0aW9uJGFnZV9ncm91cCA9PSAwICYgUFNGSV9kZl9tYWxudXRyaXRpb24kaHQgPj0gNDUgJiBQU0ZJX2RmX21hbG51dHJpdGlvbiRodCA8IDY1ICYgUFNGSV9kZl9tYWxudXRyaXRpb24kY2FzZV9jb250cm9sID09IDEmIFBTRklfZGZfbWFsbnV0cml0aW9uJHdmbHogPiAtNSAmIFBTRklfZGZfbWFsbnV0cml0aW9uJHdmbHogPDVdCiAgICAgLCBicmVha3M9NTAgLCBjb2w9cmdiKDEsMC44LDAuOCwxKSAsIGJvcmRlcj1GICwgbWFpbj0iIiAsIHhsYWI9IldlaWdodCBmb3IgbGVuZ3RoICh6LXNjb3JlIHdpdGggb3V0bGllciB0cmVzaG9sZCBhdCA1KSIsIHhsaW09YygtNSw1KSkgCmBgYAoKYGBge3J9CiMjIG11YWMgaXMgbm90IGJhc2VkIG9uIHotc2NvcmUsIGJ1dCByYXRoZXIgaWYgaXQgaXMgPDExNW1tLCBiZXR3ZWVuIDExNS0xMjUgb3IgPjEyNW1tClBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIGZpbHRlcihjYXNlX2NvbnRyb2wgPT0gMSAmIGFnZV9ncm91cCA9PSAwICYgKGh0IDwgNDUgfCBodCA+PSAxMjAgfCBpcy5uYShodCkpKSAlPiUKICBkcm9wX25hKG11YWN6KSAlPiUKICBtdXRhdGUoCiAgICBtYWxudXRyaXRpb25fc3RhdHVzID0gY2FzZV93aGVuKAogICAgICBtdWFjeiA8IC0zIH4gIlNldmVyZSBtYWxudXRyaXRpb24iLAogICAgICBtdWFjeiA+PSAtMyAmIG11YWN6IDwgLTIgfiAiTW9kZXJhdGUgbWFsbnV0cml0aW9uIiwKICAgICAgbXVhY3ogPj0gLTIgfiAiTm8gbWFsbnV0cml0aW9uIiwKICAgICAgVFJVRSB+IE5BX2NoYXJhY3Rlcl8KICAgICkKICApICU+JQogIGdncGxvdChhZXMoeCA9IG1hbG51dHJpdGlvbl9zdGF0dXMpKSArCiAgZ2VvbV9iYXIoKSArCiAgbGFicygKICAgIHggPSAiTWFsbnV0cml0aW9uIHN0YXR1cyBiYXNlZCBvbiBNVUFDIiwKICAgIHkgPSAiTiIKICApCmBgYAoKCiMjIDEuNSBEYXRhIGNoZWNrCgpgYGB7cn0KUFNGSV9kZl9tYWxudXRyaXRpb24lPiUKICBncm91cF9ieShtYWxudXRyaXRpb24pICU+JQogIHN1bW1hcml6ZSgKICAgIG1hbG51dHJpdGlvbl9taXNzaW5nID0gc3VtKGlzLm5hKG1hbG51dHJpdGlvbikpLAogICAgbW9ydF9pbmhvc3BfbWlzc2luZyA9IHN1bShpcy5uYShtb3J0X2luaG9zcCkpLCAjMTAzIG1vcnRfaW5ob3NwX21paXNzaW5nICA9IGNvbnRyb2xzCiAgKQpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBmaWx0ZXIgKGNhc2VfY29udHJvbCA9PSAxKSAlPiUKICBncm91cF9ieShtYWxudXRyaXRpb25fc291cmNlKSAlPiUKICBzdW1tYXJpemUoCiAgICBjb3VudF9tYWxudXQgPSBuKCkKICApCgojIE5BIGR1ZSB0byBjaGlsZCB3aXRoIGhlaWdodCBvZiAyMCBjbSAodW5kZXIgV0hPIGN1cnZlIGZvciB3Zmgvd2ZsKSBhbmQgMzggZGF5cyBvbGQgKHRvbyB5b3VuZyBmb3IgTVVBQykKYGBgCgpgYGB7cn0KUFNGSV9kZl9tYWxudXRyaXRpb24gJT4lCiAgZmlsdGVyIChjYXNlX2NvbnRyb2wgPT0gMSkgJT4lCiAgZ3JvdXBfYnkobWFsbnV0cml0aW9uKSAlPiUKICBzdW1tYXJpemUoCiAgICBjb3VudF9tYWxudXQgPSBuKCkKICApCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIGRyb3BfbmEobWFsbnV0cml0aW9uLCBtb3J0X2luaG9zcCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKG1hbG51dHJpdGlvbikpKSArCiAgZ2VvbV9iYXIoKSArCiAgbGFicygKICAgIHggPSAiTWFsbnV0cml0aW9uIiwKICAgIHkgPSAiTiIKICApCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uJT4lCiAgZmlsdGVyIChjYXNlX2NvbnRyb2wgPT0gMSkgJT4lCiAgY291bnQobWFsbnV0cml0aW9uLCBtb3J0X2luaG9zcCkgJT4lCiAgZ3JvdXBfYnkobWFsbnV0cml0aW9uKSAlPiUKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obikpCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIGRyb3BfbmEobW9ydF9pbmhvc3AsIG1hbG51dHJpdGlvbikgJT4lICNvbmx5IGNhc2VzICYgbWludXMgdGhlIG9uZSBwcmV2aW91c2x5IG1lbnRpb25lZCBOQQogIGdncGxvdCArCiAgKGFlcyh4ID0gZmFjdG9yKG1hbG51dHJpdGlvbiksIGZpbGwgPSBmYWN0b3IobW9ydF9pbmhvc3ApKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiY291bnQiLCBwb3NpdGlvbiA9ICJmaWxsIikgKwogIGxhYnMoCiAgICB4ID0gIk1hbG51dHJpdGlvbiIsCiAgICB5ID0gIlByb3BvcnRpb24iLAogICAgZmlsbCA9ICJNb3J0YWxpdHkiCiAgKQpgYGAKCmBgYHtyfQpQU0ZJX2RmX21hbG51dHJpdGlvbiAlPiUKICBjb3VudChtYWxudXRyaXRpb24sIGNhc2VfY29udHJvbCkgJT4lCiAgZ3JvdXBfYnkobWFsbnV0cml0aW9uKSAlPiUKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obikpCmBgYAoKYGBge3J9ClBTRklfZGZfbWFsbnV0cml0aW9uICU+JQogIGRyb3BfbmEobWFsbnV0cml0aW9uKSAlPiUKICBnZ3Bsb3QgKwogIChhZXMoeCA9IGZhY3RvcihtYWxudXRyaXRpb24pLCBmaWxsID0gZmFjdG9yKGNhc2VfY29udHJvbCkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJjb3VudCIsIHBvc2l0aW9uID0gImZpbGwiKSArCiAgbGFicygKICAgIHggPSAiTWFsbnV0cml0aW9uIiwKICAgIHkgPSAiUHJvcG9ydGlvbiIsCiAgICBmaWxsID0gIkNhc2UvQ29udHJvbCIKICApCmBgYAoKYGBge3J9CndyaXRlLnhsc3goUFNGSV9kZl9tYWxudXRyaXRpb24sIGZpbGUgPSAiUFNGSV9maW5hbF9tYWxudXRyaXRpb24ueGxzeCIpCmBgYAo=