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=