1 Data processing

pacman::p_load(
  tidyverse,
  janitor,
  summarytools,
  DataExplorer,
  readxl,
  effsize)

theme_set(theme_bw())

1.1 import data base

library(readxl)
ds <- read_excel("C:/Users/luisf/Dropbox/Puc-Rio/Consultoria - Marco Hallos/Modificado - AMBS Tabela Pedida Examinadores 31 05 2021 Oficial.xlsx")

1.2 backup

backup <- ds

1.3 clean names

Modificação dos nomes das variáveis

ds <- clean_names(ds)

1.4 ajustes das variáveis

1.5 Email do avaliador no caso a pessoa que avaliou o seu lider

criar nova variável e verificar se cada email aparece 2 ou mais vezes

ds <- ds %>% 
  mutate(email_avaliador = email)

ds %>% count(email_avaliador)
NA

Formato do email - tirar letras maúsculas

ds <- ds %>% 
  mutate(email_avaliador = tolower(email_avaliador))

1.6 Gênero do avaliador

gênero = 1 é Masculino. gênero = 2 é feminino.

ds <- ds %>% 
  mutate(sexo_avaliador= factor(if_else(genero_avaliador == 1, "male", "female")))

ds %>% count(genero_avaliador)
ds %>% count(sexo_avaliador) 

1.7 Idade do gestor

ds <- ds %>% 
  mutate(idade = idadegestor)

ds %>% count(idade)
mean(ds$idade, na.rm=T)

1.8 tempo da intervenção

valor 1 equivale ao período anterior à intervenção valor 2 e 3 equivalem ao período posterior à intervenção a diferença entre 2 e 3 é que 2 é pouco tempo após a intervenção e 3 é um tempo maior após a intervenção

Transformar em fator

ds <- ds %>% 
  mutate(tempo = if_else(versao == 1,"pre","post"))

ds <- ds %>% 
  mutate(tempo = factor(tempo, levels=c("pre","post")))

ds %>% count(tempo, versao)

1.9 Email do lider

criar nova variável e verificar se cada email aparece 2 ou mais vezes

ds <- ds %>% 
  mutate(email_lider = lider)

ds %>% 
  count(email_lider) %>% 
  arrange(desc(n))
NA

Formato do email - tirar letras maúsculas

ds <- ds %>% 
  mutate(email_lider = tolower(email_lider))

ds %>% count(email_lider) %>% 
  arrange(desc(n))

1.10 Gênero do lider

gênero = 1 é Masculino. gênero = 2 é feminino.

ds <- ds %>% 
  mutate(sexo_lider= factor(if_else(
                            genero_lider == 1,"male","female")))

ds %>% count(genero_lider)
ds %>% count(sexo_lider)
NA

1.11 Geração do Lider

Baby Boomers – 1945 – 1964 54 a 73 anos = 1 Geração X – 1965 – 1984 34 a 53 anos = 2 Geração Y – 1985 – 1999 19 a 33 anos = 3 Geração Z – 2000 – Atual Menos que 19 anos = 4

ds <- ds %>% 
  mutate(geracao = as.factor(geracao))
ds %>% count(geracao)

1.12 Senioridade do lider

ds %>% 
  distinct(email_lider, .keep_all = T) %>% #tira duplicado
  count(senioridade) %>% 
  mutate(prop = n/sum(n))
ds %>% 
    distinct(email_lider, .keep_all = T) %>% #tira duplicado
  count(geracao) %>% 
  mutate(prop = n/sum(n))

1.13 scales

1.14 Missing data within scales

ds %>% select(starts_with("v"), -versao) %>% 
  DataExplorer::plot_missing()

1.15 Compute totals

ds <- ds %>% 
  mutate(self_awareness = rowMeans(select(., v03, v07, v12, v18))) %>% 
  mutate(tranformational = rowMeans(select(., v01, v05, v09, v11, v13, v15, v17))) %>%
  mutate(emotional_intel = rowMeans(select(.,   v02, v04, v06, v08, v10, v14, v16, v19))) %>%
  mutate(lmx = rowMeans(select(., v20:v26))) 

Done!

2 Manuscript

3 Research question

3.1 Efeito da intervenção

ds %>% 
  select(email_lider, tempo,self_awareness:lmx)
ds %>% 
  select(email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(email_lider, tempo)) %>%
  mutate(name = case_when(
    name == "self_awareness" ~ "Self awareness",
    name == "tranformational" ~ "Tranformational",
    name == "emotional_intel" ~ "Emotional Intelligence",
    name == "lmx" ~ "LMX")) %>% 
  ggplot(., aes(x=tempo, y = value, group = email_lider, color = email_lider)) +
  stat_summary(geom = "line", fun = "mean") +
  stat_summary(geom = "errorbar", width = 0.1) +
  facet_wrap(~name) +
  labs(x = "", y = "") +
  theme(legend.position = "none")

3.2 Overall growth

3.3 Plot

ds %>% 
  select(email_lider, tempo,self_awareness:lmx) %>% 
  #mutate(self_awareness = scale(self_awareness)) %>% 
  #mutate(tranformational = scale(tranformational)) %>% 
  #mutate(emotional_intel = scale(emotional_intel)) %>% 
  #mutate(lmx = scale(lmx)) %>% 
  pivot_longer(-c(email_lider, tempo)) %>% 
    mutate(name = case_when(
    name == "self_awareness" ~ "Self awareness",
    name == "tranformational" ~ "Tranformational",
    name == "emotional_intel" ~ "Emotional Intelligence",
    name == "lmx" ~ "LMX")) %>% 
  ggplot(., aes(x=tempo, y = value, group = name, color = name)) +
  labs(x = "", color = "Variável", y = "Resultado") +
  stat_summary(geom = "line", fun = "mean", size = 1.5) +
  stat_summary(geom = "errorbar", width = 0.1) 

3.4 Correlation

ds %>% 
  split(.$tempo) %>% 
  map(select, self_awareness:lmx) %>% 
  map(cor)
library(igraph)
library(corrr)

cor_graph <- ds %>% 
  select(tempo,self_awareness:lmx) %>% #select all variables of intereset
  mutate(tempo = if_else(tempo == "pre",".Pre","Post")) %>% #for alignment and order
  rename("Self Awareness" = self_awareness) %>% 
  rename("Transformational" = tranformational) %>% 
  rename("Emotional Intelligence" = emotional_intel) %>% 
  rename("LMX" = lmx) %>% 
  group_by(tempo) %>% #group by age
  nest() %>% #create specific dataset to each age intervla
  mutate(data = map(data, purrr::compose(stretch, correlate))) %>% #run correlation 
  unnest(cols = -tempo) %>% 
  select(x, y, r, tempo) %>% 
  graph_from_data_frame(directed = FALSE)
library(ggraph)
ggraph(cor_graph, layout = "kk") +
  geom_edge_link(aes(edge_alpha = abs(r), color = r), edge_width = 5) +
  guides(edge_alpha = "none") +
  scale_edge_colour_gradientn(limits = c(-1, 1), colors = heat.colors(5)) +
  geom_node_point(color = "black", size = 4) +
  geom_node_text(aes(label = name), repel = TRUE) +
  facet_edges(~tempo) +
  theme_minimal() 

out_t_test <- ds %>%   
  ungroup() %>% 
  select(email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(email_lider, tempo)) %>% 
  group_by(name) %>% 
  summarise(x = list(t.test(value ~ tempo, paired=T))) 

out_t_test$x
ds %>%   
  select(email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(email_lider, tempo)) %>% 
  filter(name == "emotional_intel") %>% 
  {t.test(value ~ tempo, paired = T, data = .)}
  

3.5 paired t

 ds %>%
   select(email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(email_lider, tempo)) %>% 
  split(.$name) %>%
  map(~t.test(value ~ tempo, paired = T,.x))
#https://stackoverflow.com/questions/51074328/perform-several-t-tests-simultaneously-on-tidy-data-in-r

3.6 effect size

 ds %>%
   select(email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(email_lider, tempo)) %>% 
  split(.$name) %>%
  map(~cohen.d(value ~ tempo, data =.))

Get the summaries

ds %>%
select(email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(email_lider, tempo)) %>% 
  arsenal::tableby(interaction(name, tempo) ~ value, data = .) %>% 
  summary() 
emotional_intel.pre (N=109) lmx.pre (N=109) self_awareness.pre (N=109) tranformational.pre (N=109) emotional_intel.post (N=109) lmx.post (N=109) self_awareness.post (N=109) tranformational.post (N=109) Total (N=872) p value
value < 0.001
   Mean (SD) 3.810 (0.721) 3.824 (0.574) 3.624 (0.658) 4.076 (0.592) 3.972 (0.597) 4.034 (0.564) 3.867 (0.608) 4.207 (0.538) 3.927 (0.630)
   Range 1.375 - 5.000 2.000 - 4.857 2.000 - 5.000 2.143 - 5.000 2.125 - 5.000 2.286 - 5.000 2.250 - 5.000 2.429 - 5.000 1.375 - 5.000

3.7 Empresas

ds <- ds %>% 
  mutate(empresa = as.factor(empresa))

ds %>% count(empresa)

3.8 Plots

ds %>% 
  filter(tempo == "pre") %>% 
  ggstatsplot::ggbetweenstats(
    data = .,
    x = empresa,
    y = lmx,
    xlab = "Empresas",
    ylab = "LMX",
    pairwise.comparisons = FALSE,
    results.subtitle = FALSE,
    title = "Resultados médios antes da intervenção"
)

ds %>% 
  filter(tempo == "pre") %>% 
  arsenal::tableby(empresa ~lmx, data = .) %>% 
  summary()
1 (N=47) 3 (N=18) 4 (N=44) Total (N=109) p value
lmx 0.154
   Mean (SD) 3.927 (0.474) 3.627 (0.658) 3.795 (0.623) 3.824 (0.574)
   Range 2.857 - 4.857 2.000 - 4.714 2.286 - 4.857 2.000 - 4.857
ds %>% 
  select(empresa, email_lider, tempo,self_awareness:lmx) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
      mutate(name = case_when(
    name == "self_awareness" ~ "Self awareness",
    name == "tranformational" ~ "Tranformational",
    name == "emotional_intel" ~ "Emotional Intelligence",
    name == "lmx" ~ "LMX")) %>% 
  ggplot(., aes(x=tempo, y = value, group = name, color = name)) +
  stat_summary(geom = "line", fun = "mean", size = 1.5) +
  stat_summary(geom = "errorbar", width = 0.1, size = 1) +
  labs(x="", y = "Resultado", color = "Variável") +
  theme(legend.position = "bottom") +
  facet_wrap(~empresa)

ds %>% 
  select(empresa, email_lider, tempo,self_awareness:lmx) %>% 
  mutate_at(vars(self_awareness:lmx), ~scale(.)) %>% 

  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  mutate(name = case_when(
    name == "self_awareness" ~ "Self awareness",
    name == "tranformational" ~ "Tranformational",
    name == "emotional_intel" ~ "Emotional Intelligence",
    name == "lmx" ~ "LMX")) %>% 
  ggplot(., aes(x=tempo, y = value, group = name, color = name)) +
  stat_summary(geom = "line", fun = "mean", size = 1.5) +
  stat_summary(geom = "errorbar", width = 0.1, size = 1) +
  labs(x="", y = "Resultado", color = "Variável") +
  theme(legend.position = "bottom") +
  facet_wrap(~empresa)

ds %>% 
  filter(tempo == "post") %>% 
  ggstatsplot::ggbetweenstats(
    data = .,
    x = empresa,
    y = lmx,
        xlab = "Empresas",
    ylab = "LMX",
    pairwise.comparisons = FALSE,
    results.subtitle = FALSE,
    title = "Resultados médios após da intervenção"
)

3.9 paired T - Self-awareness em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo,self_awareness) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~t.test(value ~ tempo, paired = T,.x))

3.10 Média e desvio - Self-awareness em função do tempo e por empresa

ds %>%
select(empresa, email_lider, tempo,self_awareness) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  arsenal::tableby(interaction(tempo, empresa) ~ value, data = .) %>% 
  summary() 
pre.1 (N=47) post.1 (N=47) pre.3 (N=18) post.3 (N=18) pre.4 (N=44) post.4 (N=44) Total (N=218) p value
value 0.039
   Mean (SD) 3.649 (0.753) 3.979 (0.667) 3.472 (0.781) 3.819 (0.427) 3.659 (0.476) 3.767 (0.596) 3.745 (0.644)
   Range 2.000 - 5.000 2.250 - 5.000 2.000 - 4.500 3.250 - 4.750 2.250 - 4.250 2.250 - 4.750 2.000 - 5.000

3.11 cohen d - Self awareness em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo, self_awareness) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~cohen.d(value ~ tempo, data =.))

3.12 paired T - Tranformational em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo,tranformational) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~t.test(value ~ tempo, paired = T,.x))

3.13 Média e desvio - Tranformational em função do tempo e por empresa

ds %>%
select(empresa, email_lider, tempo, tranformational) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  arsenal::tableby(interaction(tempo, empresa) ~ value, data = .) %>% 
  summary() 
pre.1 (N=47) post.1 (N=47) pre.3 (N=18) post.3 (N=18) pre.4 (N=44) post.4 (N=44) Total (N=218) p value
value 0.228
   Mean (SD) 4.143 (0.571) 4.310 (0.525) 4.000 (0.679) 4.095 (0.523) 4.036 (0.583) 4.143 (0.551) 4.142 (0.568)
   Range 2.857 - 5.000 2.714 - 5.000 2.857 - 5.000 3.143 - 4.857 2.143 - 5.000 2.429 - 5.000 2.143 - 5.000

3.14 cohen d - Tranformational em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo, tranformational) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~cohen.d(value ~ tempo, data =.))

3.15 paired T - Emotional Intelligence em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo, emotional_intel) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~t.test(value ~ tempo, paired = T,.x))

3.16 Média e desvio - Emotional Intelligence em função do tempo e por empresa

ds %>%
select(empresa, email_lider, tempo, emotional_intel) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  arsenal::tableby(interaction(tempo, empresa) ~ value, data = .) %>% 
  summary() 
pre.1 (N=47) post.1 (N=47) pre.3 (N=18) post.3 (N=18) pre.4 (N=44) post.4 (N=44) Total (N=218) p value
value 0.193
   Mean (SD) 3.739 (0.879) 4.008 (0.610) 3.736 (0.696) 3.757 (0.714) 3.915 (0.516) 4.023 (0.520) 3.891 (0.665)
   Range 1.375 - 5.000 2.750 - 5.000 2.375 - 4.750 2.125 - 4.750 2.625 - 4.875 2.625 - 5.000 1.375 - 5.000

3.17 cohen d - Emotional Intelligence em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo, emotional_intel) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~cohen.d(value ~ tempo, data =.))

3.18 paired T - lmx em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo, lmx) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~t.test(value ~ tempo, paired = T,.x))

3.19 Média e desvio - lmx em função do tempo e por empresa

ds %>%
select(empresa, email_lider, tempo, lmx) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  arsenal::tableby(interaction(tempo, empresa) ~ value, data = .) %>% 
  summary() 
pre.1 (N=47) post.1 (N=47) pre.3 (N=18) post.3 (N=18) pre.4 (N=44) post.4 (N=44) Total (N=218) p value
value 0.006
   Mean (SD) 3.927 (0.474) 4.170 (0.528) 3.627 (0.658) 3.857 (0.470) 3.795 (0.623) 3.961 (0.613) 3.929 (0.578)
   Range 2.857 - 4.857 3.143 - 5.000 2.000 - 4.714 2.857 - 4.857 2.286 - 4.857 2.286 - 5.000 2.000 - 5.000

3.20 cohen d - lmx em função do tempo e por empresa

 ds %>%
   select(empresa,email_lider, tempo, lmx) %>% 
  pivot_longer(-c(empresa, email_lider, tempo)) %>% 
  split(.$empresa,) %>%
  map(~cohen.d(value ~ tempo, data =.))

3.21 Modelo hierárquico

ds %>% 
  distinct(email_lider, .keep_all = TRUE) %>% 
  count(sexo_lider) %>% 
  mutate(prop = n/sum(n)) %>% 
  adorn_totals()
library(lme4)
library(lmerTest)
mod_hier_self <- lmer(self_awareness ~ factor(tempo) + (1|email_lider), data = ds)
mod_hier_trans <- lmer(tranformational ~ factor(tempo) + (1|email_lider), data = ds)
mod_hier_intel <- lmer(emotional_intel ~ factor(tempo) + (1|email_lider), data = ds)
mod_hier_lmx <- lmer(lmx ~ factor(tempo) + (1|email_lider), data = ds)
anova(mod_hier_self, type = 3, ddf = "Satterthwaite")
anova(mod_hier_trans, type = 3, ddf = "Satterthwaite")
anova(mod_hier_intel, type = 3, ddf = "Satterthwaite")
anova(mod_hier_lmx, type = 3, ddf = "Satterthwaite")

3.22 Mediation (1)

3.23 Create a wide data

ds_wide <- ds  %>% 
  select(email_lider, email_avaliador, tempo, self_awareness:lmx) %>% 
   pivot_wider(names_from = c(tempo), values_from=c(self_awareness:lmx))  %>% 
  unchop(everything())

#jonatan teixeira avalou duas pessoas

#old code
#ds_long <- ds %>% 
#  select(email_lider, email_avaliador, tempo, self_awareness, lmx) %>% 
#   pivot_wider(names_from = c(tempo), values_from=c(self_awareness, lmx),
#                values_fn = list(. = list))  %>% 
#  unchop(everything())
library(lavaan)
model <- ' # direct effect
             lmx_post ~ c*self_awareness_pre
           # mediator
             self_awareness_post ~ a*self_awareness_pre
             lmx_post ~ b*self_awareness_post
           # indirect effect (a*b)
             ab := a*b
           # total effect
             total := c + (a*b)'

fit <- sem(model, data = ds_wide)
semPlot::semPaths(fit, "par",
             sizeMan = 15, sizeInt = 15, sizeLat = 15,
             edge.label.cex=1.5,
             fade=FALSE, rotation = 2)

summary(fit)
psych::mediate(lmx_post ~ self_awareness_pre + (self_awareness_post), data = ds_wide) 

3.24 Mediation (2)

model <- 'lmx_post ~ self_awareness_pre+lmx_pre
          self_awareness_post ~ self_awareness_pre
          lmx_post ~ self_awareness_post
          lmx_pre ~~ 0*self_awareness_pre'


fit <- sem(model, data = ds_wide)
summary(fit)
semPlot::semPaths(fit, "par",
             sizeMan = 15, sizeInt = 15, sizeLat = 15,
             edge.label.cex=1.5,
             fade=FALSE, rotation = 2)

3.25 Regressao (apos reunião)

3.26 create a wide data

ds_wide <- ds  %>% 
  select(email_lider, email_avaliador, tempo, self_awareness:lmx) %>% 
   pivot_wider(names_from = c(tempo), values_from=c(self_awareness:lmx))  %>% 
  unchop(everything())

#jonatan teixeira avalou duas pessoas

3.27 create change variables

ds_wide  <- ds_wide  %>% 
  mutate(delta_self_awareness = self_awareness_post - self_awareness_pre)

ds_wide  <- ds_wide  %>% 
  mutate(delta_tranformational = tranformational_post - tranformational_pre)

ds_wide  <- ds_wide  %>% 
  mutate(delta_emotional_intel = emotional_intel_post - emotional_intel_pre)

ds_wide  <- ds_wide  %>% 
  mutate(delta_lmx = lmx_post - lmx_pre)

ds_wide  %>% select(lmx_post,lmx_pre, delta_lmx)

3.28 linear regression (via function)

reg_aut <- function(var) {
  #model_formula <- formula(paste0(var, "~ self_awareness_pre"))
  lm(paste0(var, "~ delta_self_awareness"), data = ds_wide) %>% olsrr::ols_regress()
}

Emotional intelligence

reg_aut("delta_emotional_intel")

Transformational

reg_aut("delta_tranformational")

LMX

reg_aut("delta_lmx")

3.29 Plots

ggplot(ds_wide,aes(x = delta_self_awareness, y = delta_tranformational )) +
  geom_jitter() +
  geom_smooth(method = "lm") +
  theme_bw() + labs(x = "Self Awareness", y = "Tranformational") +
  ggpubr::stat_cor(method = "pearson")

ggplot(ds_wide,aes(x = delta_self_awareness, y = delta_emotional_intel )) +
  geom_jitter() +
  geom_smooth(method = "lm") +
  theme_bw() + labs(x = "Self Awareness", y = "Emotional intelligence") +
   ggpubr::stat_cor(method = "pearson")

ggplot(ds_wide,aes(x = delta_self_awareness, y = delta_lmx )) +
  geom_jitter() +
  geom_smooth(method = "lm") +
  theme_bw() + labs(x = "Self Awareness", y = "LMX") +
  ggpubr::stat_cor(method = "pearson")

4 Fixing inconsistencies

psych::mediate(lmx_post ~ self_awareness_pre + (self_awareness_post), data = ds_wide2) 

Done!

LS0tDQp0aXRsZTogIk1hcmNvIEhhbGxvcyINCmF1dGhvcjoNCi0gTHVpcyBBbnVuY2lhw6fDo28NCi0gTHVjYXMgQmFycm96bw0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6IGNlcnVsZWFuIA0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtyIGdsb2JhbCBvcHRpb25zLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXMgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZSA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9ICJoaWRlIikNCmBgYA0KDQojIERhdGEgcHJvY2Vzc2luZyANCg0KYGBgIHtyIHBhY2thZ2VzIH0NCnBhY21hbjo6cF9sb2FkKA0KICB0aWR5dmVyc2UsDQogIGphbml0b3IsDQogIHN1bW1hcnl0b29scywNCiAgRGF0YUV4cGxvcmVyLA0KICByZWFkeGwsDQogIGVmZnNpemUpDQoNCnRoZW1lX3NldCh0aGVtZV9idygpKQ0KYGBgDQoNCg0KIyMgaW1wb3J0IGRhdGEgYmFzZQ0KDQpgYGB7cn0NCmxpYnJhcnkocmVhZHhsKQ0KZHMgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvbHVpc2YvRHJvcGJveC9QdWMtUmlvL0NvbnN1bHRvcmlhIC0gTWFyY28gSGFsbG9zL01vZGlmaWNhZG8gLSBBTUJTIFRhYmVsYSBQZWRpZGEgRXhhbWluYWRvcmVzIDMxIDA1IDIwMjEgT2ZpY2lhbC54bHN4IikNCmBgYA0KDQoNCiMjIGJhY2t1cCAgICANCg0KYGBge3J9DQpiYWNrdXAgPC0gZHMNCmBgYA0KDQojIyBjbGVhbiBuYW1lcw0KDQo+IE1vZGlmaWNhw6fDo28gZG9zIG5vbWVzIGRhcyB2YXJpw6F2ZWlzDQoNCmBgYHtyfQ0KZHMgPC0gY2xlYW5fbmFtZXMoZHMpDQpgYGANCg0KIyMgYWp1c3RlcyBkYXMgdmFyacOhdmVpcw0KDQojIyBFbWFpbCAgZG8gYXZhbGlhZG9yIG5vIGNhc28gYSBwZXNzb2EgcXVlIGF2YWxpb3UgbyBzZXUgbGlkZXINCg0KPiBjcmlhciBub3ZhIHZhcmnDoXZlbCBlIHZlcmlmaWNhciBzZSBjYWRhIGVtYWlsIGFwYXJlY2UgMiBvdSBtYWlzIHZlemVzDQoNCmBgYHtyfQ0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUoZW1haWxfYXZhbGlhZG9yID0gZW1haWwpDQoNCmRzICU+JSBjb3VudChlbWFpbF9hdmFsaWFkb3IpDQoNCmBgYA0KDQo+IEZvcm1hdG8gZG8gZW1haWwgLSB0aXJhciBsZXRyYXMgbWHDunNjdWxhcw0KDQpgYGB7cn0NCmRzIDwtIGRzICU+JSANCiAgbXV0YXRlKGVtYWlsX2F2YWxpYWRvciA9IHRvbG93ZXIoZW1haWxfYXZhbGlhZG9yKSkNCmBgYA0KDQoNCiMjIEfDqm5lcm8gZG8gYXZhbGlhZG9yDQoNCj4gZ8OqbmVybyA9IDEgw6kgTWFzY3VsaW5vLiANCiAgZ8OqbmVybyA9IDIgw6kgZmVtaW5pbm8uDQoNCmBgYHtyfQ0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUoc2V4b19hdmFsaWFkb3I9IGZhY3RvcihpZl9lbHNlKGdlbmVyb19hdmFsaWFkb3IgPT0gMSwgIm1hbGUiLCAiZmVtYWxlIikpKQ0KDQpkcyAlPiUgY291bnQoZ2VuZXJvX2F2YWxpYWRvcikNCmRzICU+JSBjb3VudChzZXhvX2F2YWxpYWRvcikgDQpgYGANCg0KIyMgSWRhZGUgZG8gZ2VzdG9yDQoNCmBgYHtyfQ0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUoaWRhZGUgPSBpZGFkZWdlc3RvcikNCg0KZHMgJT4lIGNvdW50KGlkYWRlKQ0KbWVhbihkcyRpZGFkZSwgbmEucm09VCkNCmBgYA0KDQojIyB0ZW1wbyBkYSBpbnRlcnZlbsOnw6NvDQoNCj4gdmFsb3IgMSBlcXVpdmFsZSBhbyBwZXLDrW9kbyBhbnRlcmlvciDDoCBpbnRlcnZlbsOnw6NvDQogIHZhbG9yIDIgZSAzIGVxdWl2YWxlbSBhbyBwZXLDrW9kbyBwb3N0ZXJpb3Igw6AgaW50ZXJ2ZW7Dp8Ojbw0KICBhIGRpZmVyZW7Dp2EgZW50cmUgMiBlIDMgw6kgcXVlIDIgw6kgcG91Y28gdGVtcG8gYXDDs3MgYSBpbnRlcnZlbsOnw6NvIGUgMyDDqSB1bSB0ZW1wbyBtYWlvciBhcMOzcyBhIGludGVydmVuw6fDo28NCg0KPiBUcmFuc2Zvcm1hciBlbSBmYXRvciANCg0KYGBge3J9DQpkcyA8LSBkcyAlPiUgDQogIG11dGF0ZSh0ZW1wbyA9IGlmX2Vsc2UodmVyc2FvID09IDEsInByZSIsInBvc3QiKSkNCg0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUodGVtcG8gPSBmYWN0b3IodGVtcG8sIGxldmVscz1jKCJwcmUiLCJwb3N0IikpKQ0KDQpkcyAlPiUgY291bnQodGVtcG8sIHZlcnNhbykNCmBgYA0KDQoNCiMjIEVtYWlsIGRvIGxpZGVyIA0KDQo+IGNyaWFyIG5vdmEgdmFyacOhdmVsIGUgdmVyaWZpY2FyIHNlIGNhZGEgZW1haWwgYXBhcmVjZSAyIG91IG1haXMgdmV6ZXMNCg0KYGBge3J9DQpkcyA8LSBkcyAlPiUgDQogIG11dGF0ZShlbWFpbF9saWRlciA9IGxpZGVyKQ0KDQpkcyAlPiUgDQogIGNvdW50KGVtYWlsX2xpZGVyKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCg0KYGBgDQoNCj4gRm9ybWF0byBkbyBlbWFpbCAtIHRpcmFyIGxldHJhcyBtYcO6c2N1bGFzDQoNCmBgYHtyfQ0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUoZW1haWxfbGlkZXIgPSB0b2xvd2VyKGVtYWlsX2xpZGVyKSkNCg0KZHMgJT4lIGNvdW50KGVtYWlsX2xpZGVyKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCmBgYA0KDQojIyBHw6puZXJvIGRvIGxpZGVyDQoNCj4gZ8OqbmVybyA9IDEgw6kgTWFzY3VsaW5vLiANCiAgZ8OqbmVybyA9IDIgw6kgZmVtaW5pbm8uDQoNCmBgYHtyfQ0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUoc2V4b19saWRlcj0gZmFjdG9yKGlmX2Vsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJvX2xpZGVyID09IDEsIm1hbGUiLCJmZW1hbGUiKSkpDQoNCmRzICU+JSBjb3VudChnZW5lcm9fbGlkZXIpDQpkcyAlPiUgY291bnQoc2V4b19saWRlcikNCg0KYGBgDQoNCg0KDQojIyBHZXJhw6fDo28gZG8gTGlkZXINCg0KPkJhYnkgQm9vbWVycyDigJMgMTk0NSDigJMgMTk2NAk1NCBhIDczIGFub3MgPQkxDQogR2VyYcOnw6NvIFgg4oCTIDE5NjUg4oCTIDE5ODQJMzQgYSA1MyBhbm9zID0JMg0KIEdlcmHDp8OjbyBZIOKAkyAxOTg1IOKAkyAxOTk5CTE5IGEgMzMgYW5vcyA9CTMNCiBHZXJhw6fDo28gWiDigJMgMjAwMCDigJMgQXR1YWwJTWVub3MgcXVlIDE5IGFub3MJPSA0DQoNCmBgYHtyfQ0KZHMgPC0gZHMgJT4lIA0KICBtdXRhdGUoZ2VyYWNhbyA9IGFzLmZhY3RvcihnZXJhY2FvKSkNCmRzICU+JSBjb3VudChnZXJhY2FvKQ0KYGBgDQoNCg0KDQojIyBTZW5pb3JpZGFkZSBkbyBsaWRlciANCg0KYGBge3J9DQpkcyAlPiUgDQogIGRpc3RpbmN0KGVtYWlsX2xpZGVyLCAua2VlcF9hbGwgPSBUKSAlPiUgI3RpcmEgZHVwbGljYWRvDQogIGNvdW50KHNlbmlvcmlkYWRlKSAlPiUgDQogIG11dGF0ZShwcm9wID0gbi9zdW0obikpDQpgYGANCg0KDQpgYGB7cn0NCmRzICU+JSANCiAgICBkaXN0aW5jdChlbWFpbF9saWRlciwgLmtlZXBfYWxsID0gVCkgJT4lICN0aXJhIGR1cGxpY2Fkbw0KICBjb3VudChnZXJhY2FvKSAlPiUgDQogIG11dGF0ZShwcm9wID0gbi9zdW0obikpDQpgYGANCg0KDQojIyAgc2NhbGVzDQoNCiMjIE1pc3NpbmcgZGF0YSB3aXRoaW4gc2NhbGVzDQoNCmBgYHtyfQ0KZHMgJT4lIHNlbGVjdChzdGFydHNfd2l0aCgidiIpLCAtdmVyc2FvKSAlPiUgDQogIERhdGFFeHBsb3Jlcjo6cGxvdF9taXNzaW5nKCkNCmBgYA0KDQojIyBDb21wdXRlIHRvdGFscw0KDQpgYGB7cn0NCmRzIDwtIGRzICU+JSANCiAgbXV0YXRlKHNlbGZfYXdhcmVuZXNzID0gcm93TWVhbnMoc2VsZWN0KC4sIHYwMywgdjA3LCB2MTIsIHYxOCkpKSAlPiUgDQogIG11dGF0ZSh0cmFuZm9ybWF0aW9uYWwgPSByb3dNZWFucyhzZWxlY3QoLiwgdjAxLCB2MDUsIHYwOSwgdjExLCB2MTMsIHYxNSwgdjE3KSkpICU+JQ0KICBtdXRhdGUoZW1vdGlvbmFsX2ludGVsID0gcm93TWVhbnMoc2VsZWN0KC4sIAl2MDIsIHYwNCwgdjA2LCB2MDgsIHYxMCwgdjE0LCB2MTYsIHYxOSkpKSAlPiUNCiAgbXV0YXRlKGxteCA9IHJvd01lYW5zKHNlbGVjdCguLCB2MjA6djI2KSkpIA0KDQpgYGANCg0KPiBEb25lIQ0KDQojIE1hbnVzY3JpcHQNCg0KIyBSZXNlYXJjaCBxdWVzdGlvbg0KDQojIyBFZmVpdG8gZGEgaW50ZXJ2ZW7Dp8OjbyANCg0KDQpgYGB7cn0NCmRzICU+JSANCiAgc2VsZWN0KGVtYWlsX2xpZGVyLCB0ZW1wbyxzZWxmX2F3YXJlbmVzczpsbXgpDQpgYGANCg0KDQpgYGB7cn0NCmRzICU+JSANCiAgc2VsZWN0KGVtYWlsX2xpZGVyLCB0ZW1wbyxzZWxmX2F3YXJlbmVzczpsbXgpICU+JSANCiAgcGl2b3RfbG9uZ2VyKC1jKGVtYWlsX2xpZGVyLCB0ZW1wbykpICU+JQ0KICBtdXRhdGUobmFtZSA9IGNhc2Vfd2hlbigNCiAgICBuYW1lID09ICJzZWxmX2F3YXJlbmVzcyIgfiAiU2VsZiBhd2FyZW5lc3MiLA0KICAgIG5hbWUgPT0gInRyYW5mb3JtYXRpb25hbCIgfiAiVHJhbmZvcm1hdGlvbmFsIiwNCiAgICBuYW1lID09ICJlbW90aW9uYWxfaW50ZWwiIH4gIkVtb3Rpb25hbCBJbnRlbGxpZ2VuY2UiLA0KICAgIG5hbWUgPT0gImxteCIgfiAiTE1YIikpICU+JSANCiAgZ2dwbG90KC4sIGFlcyh4PXRlbXBvLCB5ID0gdmFsdWUsIGdyb3VwID0gZW1haWxfbGlkZXIsIGNvbG9yID0gZW1haWxfbGlkZXIpKSArDQogIHN0YXRfc3VtbWFyeShnZW9tID0gImxpbmUiLCBmdW4gPSAibWVhbiIpICsNCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAiZXJyb3JiYXIiLCB3aWR0aCA9IDAuMSkgKw0KICBmYWNldF93cmFwKH5uYW1lKSArDQogIGxhYnMoeCA9ICIiLCB5ID0gIiIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCiMjIE92ZXJhbGwgZ3Jvd3RoDQoNCiMjIFBsb3QNCg0KYGBge3J9DQpkcyAlPiUgDQogIHNlbGVjdChlbWFpbF9saWRlciwgdGVtcG8sc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogICNtdXRhdGUoc2VsZl9hd2FyZW5lc3MgPSBzY2FsZShzZWxmX2F3YXJlbmVzcykpICU+JSANCiAgI211dGF0ZSh0cmFuZm9ybWF0aW9uYWwgPSBzY2FsZSh0cmFuZm9ybWF0aW9uYWwpKSAlPiUgDQogICNtdXRhdGUoZW1vdGlvbmFsX2ludGVsID0gc2NhbGUoZW1vdGlvbmFsX2ludGVsKSkgJT4lIA0KICAjbXV0YXRlKGxteCA9IHNjYWxlKGxteCkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKC1jKGVtYWlsX2xpZGVyLCB0ZW1wbykpICU+JSANCiAgICBtdXRhdGUobmFtZSA9IGNhc2Vfd2hlbigNCiAgICBuYW1lID09ICJzZWxmX2F3YXJlbmVzcyIgfiAiU2VsZiBhd2FyZW5lc3MiLA0KICAgIG5hbWUgPT0gInRyYW5mb3JtYXRpb25hbCIgfiAiVHJhbmZvcm1hdGlvbmFsIiwNCiAgICBuYW1lID09ICJlbW90aW9uYWxfaW50ZWwiIH4gIkVtb3Rpb25hbCBJbnRlbGxpZ2VuY2UiLA0KICAgIG5hbWUgPT0gImxteCIgfiAiTE1YIikpICU+JSANCiAgZ2dwbG90KC4sIGFlcyh4PXRlbXBvLCB5ID0gdmFsdWUsIGdyb3VwID0gbmFtZSwgY29sb3IgPSBuYW1lKSkgKw0KICBsYWJzKHggPSAiIiwgY29sb3IgPSAiVmFyacOhdmVsIiwgeSA9ICJSZXN1bHRhZG8iKSArDQogIHN0YXRfc3VtbWFyeShnZW9tID0gImxpbmUiLCBmdW4gPSAibWVhbiIsIHNpemUgPSAxLjUpICsNCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAiZXJyb3JiYXIiLCB3aWR0aCA9IDAuMSkgDQpgYGANCg0KIyMgQ29ycmVsYXRpb24NCg0KYGBge3J9DQpkcyAlPiUgDQogIHNwbGl0KC4kdGVtcG8pICU+JSANCiAgbWFwKHNlbGVjdCwgc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogIG1hcChjb3IpDQpgYGANCg0KDQpgYGB7cn0NCmxpYnJhcnkoaWdyYXBoKQ0KbGlicmFyeShjb3JycikNCg0KY29yX2dyYXBoIDwtIGRzICU+JSANCiAgc2VsZWN0KHRlbXBvLHNlbGZfYXdhcmVuZXNzOmxteCkgJT4lICNzZWxlY3QgYWxsIHZhcmlhYmxlcyBvZiBpbnRlcmVzZXQNCiAgbXV0YXRlKHRlbXBvID0gaWZfZWxzZSh0ZW1wbyA9PSAicHJlIiwiLlByZSIsIlBvc3QiKSkgJT4lICNmb3IgYWxpZ25tZW50IGFuZCBvcmRlcg0KICByZW5hbWUoIlNlbGYgQXdhcmVuZXNzIiA9IHNlbGZfYXdhcmVuZXNzKSAlPiUgDQogIHJlbmFtZSgiVHJhbnNmb3JtYXRpb25hbCIgPSB0cmFuZm9ybWF0aW9uYWwpICU+JSANCiAgcmVuYW1lKCJFbW90aW9uYWwgSW50ZWxsaWdlbmNlIiA9IGVtb3Rpb25hbF9pbnRlbCkgJT4lIA0KICByZW5hbWUoIkxNWCIgPSBsbXgpICU+JSANCiAgZ3JvdXBfYnkodGVtcG8pICU+JSAjZ3JvdXAgYnkgYWdlDQogIG5lc3QoKSAlPiUgI2NyZWF0ZSBzcGVjaWZpYyBkYXRhc2V0IHRvIGVhY2ggYWdlIGludGVydmxhDQogIG11dGF0ZShkYXRhID0gbWFwKGRhdGEsIHB1cnJyOjpjb21wb3NlKHN0cmV0Y2gsIGNvcnJlbGF0ZSkpKSAlPiUgI3J1biBjb3JyZWxhdGlvbiANCiAgdW5uZXN0KGNvbHMgPSAtdGVtcG8pICU+JSANCiAgc2VsZWN0KHgsIHksIHIsIHRlbXBvKSAlPiUgDQogIGdyYXBoX2Zyb21fZGF0YV9mcmFtZShkaXJlY3RlZCA9IEZBTFNFKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3JhcGgpDQpnZ3JhcGgoY29yX2dyYXBoLCBsYXlvdXQgPSAia2siKSArDQogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gYWJzKHIpLCBjb2xvciA9IHIpLCBlZGdlX3dpZHRoID0gNSkgKw0KICBndWlkZXMoZWRnZV9hbHBoYSA9ICJub25lIikgKw0KICBzY2FsZV9lZGdlX2NvbG91cl9ncmFkaWVudG4obGltaXRzID0gYygtMSwgMSksIGNvbG9ycyA9IGhlYXQuY29sb3JzKDUpKSArDQogIGdlb21fbm9kZV9wb2ludChjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KSArDQogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUpICsNCiAgZmFjZXRfZWRnZXMofnRlbXBvKSArDQogIHRoZW1lX21pbmltYWwoKSANCg0KYGBgDQoNCg0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFIH0NCm91dF90X3Rlc3QgPC0gZHMgJT4lICAgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChlbWFpbF9saWRlciwgdGVtcG8sc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIGdyb3VwX2J5KG5hbWUpICU+JSANCiAgc3VtbWFyaXNlKHggPSBsaXN0KHQudGVzdCh2YWx1ZSB+IHRlbXBvLCBwYWlyZWQ9VCkpKSANCg0Kb3V0X3RfdGVzdCR4DQpgYGANCg0KYGBge3J9DQpkcyAlPiUgICANCiAgc2VsZWN0KGVtYWlsX2xpZGVyLCB0ZW1wbyxzZWxmX2F3YXJlbmVzczpsbXgpICU+JSANCiAgcGl2b3RfbG9uZ2VyKC1jKGVtYWlsX2xpZGVyLCB0ZW1wbykpICU+JSANCiAgZmlsdGVyKG5hbWUgPT0gImVtb3Rpb25hbF9pbnRlbCIpICU+JSANCiAge3QudGVzdCh2YWx1ZSB+IHRlbXBvLCBwYWlyZWQgPSBULCBkYXRhID0gLil9DQogIA0KDQpgYGANCg0KIyMgcGFpcmVkIHQNCg0KYGBge3J9DQogZHMgJT4lDQogICBzZWxlY3QoZW1haWxfbGlkZXIsIHRlbXBvLHNlbGZfYXdhcmVuZXNzOmxteCkgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBzcGxpdCguJG5hbWUpICU+JQ0KICBtYXAofnQudGVzdCh2YWx1ZSB+IHRlbXBvLCBwYWlyZWQgPSBULC54KSkNCiNodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81MTA3NDMyOC9wZXJmb3JtLXNldmVyYWwtdC10ZXN0cy1zaW11bHRhbmVvdXNseS1vbi10aWR5LWRhdGEtaW4tcg0KDQpgYGANCg0KIyMgZWZmZWN0IHNpemUNCg0KYGBge3J9DQogZHMgJT4lDQogICBzZWxlY3QoZW1haWxfbGlkZXIsIHRlbXBvLHNlbGZfYXdhcmVuZXNzOmxteCkgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBzcGxpdCguJG5hbWUpICU+JQ0KICBtYXAofmNvaGVuLmQodmFsdWUgfiB0ZW1wbywgZGF0YSA9LikpDQoNCmBgYA0KDQo+IEdldCB0aGUgc3VtbWFyaWVzDQoNCg0KYGBge3J9DQpkcyAlPiUNCnNlbGVjdChlbWFpbF9saWRlciwgdGVtcG8sc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIGFyc2VuYWw6OnRhYmxlYnkoaW50ZXJhY3Rpb24obmFtZSwgdGVtcG8pIH4gdmFsdWUsIGRhdGEgPSAuKSAlPiUgDQogIHN1bW1hcnkoKSANCg0KYGBgDQoNCiMjIEVtcHJlc2FzDQoNCg0KYGBge3J9DQpkcyA8LSBkcyAlPiUgDQogIG11dGF0ZShlbXByZXNhID0gYXMuZmFjdG9yKGVtcHJlc2EpKQ0KDQpkcyAlPiUgY291bnQoZW1wcmVzYSkNCmBgYA0KDQoNCiMjIFBsb3RzDQoNCmBgYHtyfQ0KZHMgJT4lIA0KICBmaWx0ZXIodGVtcG8gPT0gInByZSIpICU+JSANCiAgZ2dzdGF0c3Bsb3Q6OmdnYmV0d2VlbnN0YXRzKA0KICAgIGRhdGEgPSAuLA0KICAgIHggPSBlbXByZXNhLA0KICAgIHkgPSBsbXgsDQogICAgeGxhYiA9ICJFbXByZXNhcyIsDQogICAgeWxhYiA9ICJMTVgiLA0KICAgIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gRkFMU0UsDQogICAgcmVzdWx0cy5zdWJ0aXRsZSA9IEZBTFNFLA0KICAgIHRpdGxlID0gIlJlc3VsdGFkb3MgbcOpZGlvcyBhbnRlcyBkYSBpbnRlcnZlbsOnw6NvIg0KKQ0KYGBgDQoNCg0KYGBge3J9DQpkcyAlPiUgDQogIGZpbHRlcih0ZW1wbyA9PSAicHJlIikgJT4lIA0KICBhcnNlbmFsOjp0YWJsZWJ5KGVtcHJlc2EgfmxteCwgZGF0YSA9IC4pICU+JSANCiAgc3VtbWFyeSgpDQpgYGANCg0KDQoNCg0KYGBge3J9DQpkcyAlPiUgDQogIHNlbGVjdChlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8sc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogICAgICBtdXRhdGUobmFtZSA9IGNhc2Vfd2hlbigNCiAgICBuYW1lID09ICJzZWxmX2F3YXJlbmVzcyIgfiAiU2VsZiBhd2FyZW5lc3MiLA0KICAgIG5hbWUgPT0gInRyYW5mb3JtYXRpb25hbCIgfiAiVHJhbmZvcm1hdGlvbmFsIiwNCiAgICBuYW1lID09ICJlbW90aW9uYWxfaW50ZWwiIH4gIkVtb3Rpb25hbCBJbnRlbGxpZ2VuY2UiLA0KICAgIG5hbWUgPT0gImxteCIgfiAiTE1YIikpICU+JSANCiAgZ2dwbG90KC4sIGFlcyh4PXRlbXBvLCB5ID0gdmFsdWUsIGdyb3VwID0gbmFtZSwgY29sb3IgPSBuYW1lKSkgKw0KICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJsaW5lIiwgZnVuID0gIm1lYW4iLCBzaXplID0gMS41KSArDQogIHN0YXRfc3VtbWFyeShnZW9tID0gImVycm9yYmFyIiwgd2lkdGggPSAwLjEsIHNpemUgPSAxKSArDQogIGxhYnMoeD0iIiwgeSA9ICJSZXN1bHRhZG8iLCBjb2xvciA9ICJWYXJpw6F2ZWwiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArDQogIGZhY2V0X3dyYXAofmVtcHJlc2EpDQpgYGANCg0KYGBge3J9DQpkcyAlPiUgDQogIHNlbGVjdChlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8sc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogIG11dGF0ZV9hdCh2YXJzKHNlbGZfYXdhcmVuZXNzOmxteCksIH5zY2FsZSguKSkgJT4lIA0KDQogIHBpdm90X2xvbmdlcigtYyhlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIG11dGF0ZShuYW1lID0gY2FzZV93aGVuKA0KICAgIG5hbWUgPT0gInNlbGZfYXdhcmVuZXNzIiB+ICJTZWxmIGF3YXJlbmVzcyIsDQogICAgbmFtZSA9PSAidHJhbmZvcm1hdGlvbmFsIiB+ICJUcmFuZm9ybWF0aW9uYWwiLA0KICAgIG5hbWUgPT0gImVtb3Rpb25hbF9pbnRlbCIgfiAiRW1vdGlvbmFsIEludGVsbGlnZW5jZSIsDQogICAgbmFtZSA9PSAibG14IiB+ICJMTVgiKSkgJT4lIA0KICBnZ3Bsb3QoLiwgYWVzKHg9dGVtcG8sIHkgPSB2YWx1ZSwgZ3JvdXAgPSBuYW1lLCBjb2xvciA9IG5hbWUpKSArDQogIHN0YXRfc3VtbWFyeShnZW9tID0gImxpbmUiLCBmdW4gPSAibWVhbiIsIHNpemUgPSAxLjUpICsNCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAiZXJyb3JiYXIiLCB3aWR0aCA9IDAuMSwgc2l6ZSA9IDEpICsNCiAgbGFicyh4PSIiLCB5ID0gIlJlc3VsdGFkbyIsIGNvbG9yID0gIlZhcmnDoXZlbCIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsNCiAgZmFjZXRfd3JhcCh+ZW1wcmVzYSkNCmBgYA0KDQoNCg0KYGBge3J9DQpkcyAlPiUgDQogIGZpbHRlcih0ZW1wbyA9PSAicG9zdCIpICU+JSANCiAgZ2dzdGF0c3Bsb3Q6OmdnYmV0d2VlbnN0YXRzKA0KICAgIGRhdGEgPSAuLA0KICAgIHggPSBlbXByZXNhLA0KICAgIHkgPSBsbXgsDQogICAgICAgIHhsYWIgPSAiRW1wcmVzYXMiLA0KICAgIHlsYWIgPSAiTE1YIiwNCiAgICBwYWlyd2lzZS5jb21wYXJpc29ucyA9IEZBTFNFLA0KICAgIHJlc3VsdHMuc3VidGl0bGUgPSBGQUxTRSwNCiAgICB0aXRsZSA9ICJSZXN1bHRhZG9zIG3DqWRpb3MgYXDDs3MgZGEgaW50ZXJ2ZW7Dp8OjbyINCikNCmBgYA0KDQoNCiMjIHBhaXJlZCBUIC0gIFNlbGYtYXdhcmVuZXNzIGVtIGZ1bsOnw6NvIGRvIHRlbXBvIGUgcG9yIGVtcHJlc2ENCg0KDQpgYGB7cn0NCiBkcyAlPiUNCiAgIHNlbGVjdChlbXByZXNhLGVtYWlsX2xpZGVyLCB0ZW1wbyxzZWxmX2F3YXJlbmVzcykgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1wcmVzYSwgZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBzcGxpdCguJGVtcHJlc2EsKSAlPiUNCiAgbWFwKH50LnRlc3QodmFsdWUgfiB0ZW1wbywgcGFpcmVkID0gVCwueCkpDQpgYGANCg0KIyMgTcOpZGlhIGUgZGVzdmlvIC0gU2VsZi1hd2FyZW5lc3MgZW0gZnVuw6fDo28gZG8gdGVtcG8gZSBwb3IgZW1wcmVzYQ0KYGBge3J9DQpkcyAlPiUNCnNlbGVjdChlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8sc2VsZl9hd2FyZW5lc3MpICU+JSANCiAgcGl2b3RfbG9uZ2VyKC1jKGVtcHJlc2EsIGVtYWlsX2xpZGVyLCB0ZW1wbykpICU+JSANCiAgYXJzZW5hbDo6dGFibGVieShpbnRlcmFjdGlvbih0ZW1wbywgZW1wcmVzYSkgfiB2YWx1ZSwgZGF0YSA9IC4pICU+JSANCiAgc3VtbWFyeSgpIA0KDQpgYGANCg0KIyMgY29oZW4gZCAtIFNlbGYgYXdhcmVuZXNzIGVtIGZ1bsOnw6NvIGRvIHRlbXBvIGUgcG9yIGVtcHJlc2ENCmBgYHtyfQ0KIGRzICU+JQ0KICAgc2VsZWN0KGVtcHJlc2EsZW1haWxfbGlkZXIsIHRlbXBvLCBzZWxmX2F3YXJlbmVzcykgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1wcmVzYSwgZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBzcGxpdCguJGVtcHJlc2EsKSAlPiUNCiAgbWFwKH5jb2hlbi5kKHZhbHVlIH4gdGVtcG8sIGRhdGEgPS4pKQ0KDQpgYGANCg0KDQojIyBwYWlyZWQgVCAtICBUcmFuZm9ybWF0aW9uYWwgZW0gZnVuw6fDo28gZG8gdGVtcG8gZSBwb3IgZW1wcmVzYQ0KYGBge3J9DQogZHMgJT4lDQogICBzZWxlY3QoZW1wcmVzYSxlbWFpbF9saWRlciwgdGVtcG8sdHJhbmZvcm1hdGlvbmFsKSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIHNwbGl0KC4kZW1wcmVzYSwpICU+JQ0KICBtYXAofnQudGVzdCh2YWx1ZSB+IHRlbXBvLCBwYWlyZWQgPSBULC54KSkNCmBgYA0KDQojIyBNw6lkaWEgZSBkZXN2aW8gLSAgVHJhbmZvcm1hdGlvbmFsIGVtIGZ1bsOnw6NvIGRvIHRlbXBvIGUgcG9yIGVtcHJlc2ENCg0KYGBge3J9DQpkcyAlPiUNCnNlbGVjdChlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8sIHRyYW5mb3JtYXRpb25hbCkgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1wcmVzYSwgZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBhcnNlbmFsOjp0YWJsZWJ5KGludGVyYWN0aW9uKHRlbXBvLCBlbXByZXNhKSB+IHZhbHVlLCBkYXRhID0gLikgJT4lIA0KICBzdW1tYXJ5KCkgDQoNCmBgYA0KDQojIyBjb2hlbiBkIC0gVHJhbmZvcm1hdGlvbmFsIGVtIGZ1bsOnw6NvIGRvIHRlbXBvIGUgcG9yIGVtcHJlc2ENCg0KYGBge3J9DQogZHMgJT4lDQogICBzZWxlY3QoZW1wcmVzYSxlbWFpbF9saWRlciwgdGVtcG8sIHRyYW5mb3JtYXRpb25hbCkgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1wcmVzYSwgZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBzcGxpdCguJGVtcHJlc2EsKSAlPiUNCiAgbWFwKH5jb2hlbi5kKHZhbHVlIH4gdGVtcG8sIGRhdGEgPS4pKQ0KDQpgYGANCg0KDQoNCiMjIHBhaXJlZCBUIC0gRW1vdGlvbmFsIEludGVsbGlnZW5jZSBlbSBmdW7Dp8OjbyBkbyB0ZW1wbyBlIHBvciBlbXByZXNhDQpgYGB7cn0NCiBkcyAlPiUNCiAgIHNlbGVjdChlbXByZXNhLGVtYWlsX2xpZGVyLCB0ZW1wbywgZW1vdGlvbmFsX2ludGVsKSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIHNwbGl0KC4kZW1wcmVzYSwpICU+JQ0KICBtYXAofnQudGVzdCh2YWx1ZSB+IHRlbXBvLCBwYWlyZWQgPSBULC54KSkNCmBgYA0KDQojIyBNw6lkaWEgZSBkZXN2aW8gLSAgRW1vdGlvbmFsIEludGVsbGlnZW5jZSBlbSBmdW7Dp8OjbyBkbyB0ZW1wbyBlIHBvciBlbXByZXNhDQoNCmBgYHtyfQ0KZHMgJT4lDQpzZWxlY3QoZW1wcmVzYSwgZW1haWxfbGlkZXIsIHRlbXBvLCBlbW90aW9uYWxfaW50ZWwpICU+JSANCiAgcGl2b3RfbG9uZ2VyKC1jKGVtcHJlc2EsIGVtYWlsX2xpZGVyLCB0ZW1wbykpICU+JSANCiAgYXJzZW5hbDo6dGFibGVieShpbnRlcmFjdGlvbih0ZW1wbywgZW1wcmVzYSkgfiB2YWx1ZSwgZGF0YSA9IC4pICU+JSANCiAgc3VtbWFyeSgpIA0KDQpgYGANCg0KIyMgY29oZW4gZCAtIEVtb3Rpb25hbCBJbnRlbGxpZ2VuY2UgZW0gZnVuw6fDo28gZG8gdGVtcG8gZSBwb3IgZW1wcmVzYQ0KDQpgYGB7cn0NCiBkcyAlPiUNCiAgIHNlbGVjdChlbXByZXNhLGVtYWlsX2xpZGVyLCB0ZW1wbywgZW1vdGlvbmFsX2ludGVsKSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIHNwbGl0KC4kZW1wcmVzYSwpICU+JQ0KICBtYXAofmNvaGVuLmQodmFsdWUgfiB0ZW1wbywgZGF0YSA9LikpDQoNCmBgYA0KDQoNCg0KIyMgcGFpcmVkIFQgLSBsbXggZW0gZnVuw6fDo28gZG8gdGVtcG8gZSBwb3IgZW1wcmVzYQ0KDQpgYGB7cn0NCiBkcyAlPiUNCiAgIHNlbGVjdChlbXByZXNhLGVtYWlsX2xpZGVyLCB0ZW1wbywgbG14KSAlPiUgDQogIHBpdm90X2xvbmdlcigtYyhlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8pKSAlPiUgDQogIHNwbGl0KC4kZW1wcmVzYSwpICU+JQ0KICBtYXAofnQudGVzdCh2YWx1ZSB+IHRlbXBvLCBwYWlyZWQgPSBULC54KSkNCmBgYA0KDQojIyBNw6lkaWEgZSBkZXN2aW8gLSAgbG14IGVtIGZ1bsOnw6NvIGRvIHRlbXBvIGUgcG9yIGVtcHJlc2ENCg0KYGBge3J9DQpkcyAlPiUNCnNlbGVjdChlbXByZXNhLCBlbWFpbF9saWRlciwgdGVtcG8sIGxteCkgJT4lIA0KICBwaXZvdF9sb25nZXIoLWMoZW1wcmVzYSwgZW1haWxfbGlkZXIsIHRlbXBvKSkgJT4lIA0KICBhcnNlbmFsOjp0YWJsZWJ5KGludGVyYWN0aW9uKHRlbXBvLCBlbXByZXNhKSB+IHZhbHVlLCBkYXRhID0gLikgJT4lIA0KICBzdW1tYXJ5KCkgDQoNCmBgYA0KDQoNCiMjIGNvaGVuIGQgLSBsbXggZW0gZnVuw6fDo28gZG8gdGVtcG8gZSBwb3IgZW1wcmVzYQ0KDQoNCmBgYHtyfQ0KIGRzICU+JQ0KICAgc2VsZWN0KGVtcHJlc2EsZW1haWxfbGlkZXIsIHRlbXBvLCBsbXgpICU+JSANCiAgcGl2b3RfbG9uZ2VyKC1jKGVtcHJlc2EsIGVtYWlsX2xpZGVyLCB0ZW1wbykpICU+JSANCiAgc3BsaXQoLiRlbXByZXNhLCkgJT4lDQogIG1hcCh+Y29oZW4uZCh2YWx1ZSB+IHRlbXBvLCBkYXRhID0uKSkNCg0KYGBgDQoNCg0KIyMgTW9kZWxvIGhpZXLDoXJxdWljbw0KDQpgYGB7cn0NCmRzICU+JSANCiAgZGlzdGluY3QoZW1haWxfbGlkZXIsIC5rZWVwX2FsbCA9IFRSVUUpICU+JSANCiAgY291bnQoc2V4b19saWRlcikgJT4lIA0KICBtdXRhdGUocHJvcCA9IG4vc3VtKG4pKSAlPiUgDQogIGFkb3JuX3RvdGFscygpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbGlicmFyeShsbWU0KQ0KbGlicmFyeShsbWVyVGVzdCkNCmBgYA0KDQoNCmBgYHtyfQ0KbW9kX2hpZXJfc2VsZiA8LSBsbWVyKHNlbGZfYXdhcmVuZXNzIH4gZmFjdG9yKHRlbXBvKSArICgxfGVtYWlsX2xpZGVyKSwgZGF0YSA9IGRzKQ0KbW9kX2hpZXJfdHJhbnMgPC0gbG1lcih0cmFuZm9ybWF0aW9uYWwgfiBmYWN0b3IodGVtcG8pICsgKDF8ZW1haWxfbGlkZXIpLCBkYXRhID0gZHMpDQptb2RfaGllcl9pbnRlbCA8LSBsbWVyKGVtb3Rpb25hbF9pbnRlbCB+IGZhY3Rvcih0ZW1wbykgKyAoMXxlbWFpbF9saWRlciksIGRhdGEgPSBkcykNCm1vZF9oaWVyX2xteCA8LSBsbWVyKGxteCB+IGZhY3Rvcih0ZW1wbykgKyAoMXxlbWFpbF9saWRlciksIGRhdGEgPSBkcykNCmBgYA0KDQoNCmBgYHtyfQ0KYW5vdmEobW9kX2hpZXJfc2VsZiwgdHlwZSA9IDMsIGRkZiA9ICJTYXR0ZXJ0aHdhaXRlIikNCmFub3ZhKG1vZF9oaWVyX3RyYW5zLCB0eXBlID0gMywgZGRmID0gIlNhdHRlcnRod2FpdGUiKQ0KYW5vdmEobW9kX2hpZXJfaW50ZWwsIHR5cGUgPSAzLCBkZGYgPSAiU2F0dGVydGh3YWl0ZSIpDQphbm92YShtb2RfaGllcl9sbXgsIHR5cGUgPSAzLCBkZGYgPSAiU2F0dGVydGh3YWl0ZSIpDQoNCg0KYGBgDQoNCg0KDQoNCiMjIE1lZGlhdGlvbiAoMSkNCg0KIyMgQ3JlYXRlIGEgd2lkZSBkYXRhDQoNCmBgYHtyfQ0KZHNfd2lkZSA8LSBkcyAgJT4lIA0KICBzZWxlY3QoZW1haWxfbGlkZXIsIGVtYWlsX2F2YWxpYWRvciwgdGVtcG8sIHNlbGZfYXdhcmVuZXNzOmxteCkgJT4lIA0KICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGModGVtcG8pLCB2YWx1ZXNfZnJvbT1jKHNlbGZfYXdhcmVuZXNzOmxteCkpICAlPiUgDQogIHVuY2hvcChldmVyeXRoaW5nKCkpDQoNCiNqb25hdGFuIHRlaXhlaXJhIGF2YWxvdSBkdWFzIHBlc3NvYXMNCg0KI29sZCBjb2RlDQojZHNfbG9uZyA8LSBkcyAlPiUgDQojICBzZWxlY3QoZW1haWxfbGlkZXIsIGVtYWlsX2F2YWxpYWRvciwgdGVtcG8sIHNlbGZfYXdhcmVuZXNzLCBsbXgpICU+JSANCiMgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gYyh0ZW1wbyksIHZhbHVlc19mcm9tPWMoc2VsZl9hd2FyZW5lc3MsIGxteCksDQojICAgICAgICAgICAgICAgIHZhbHVlc19mbiA9IGxpc3QoLiA9IGxpc3QpKSAgJT4lIA0KIyAgdW5jaG9wKGV2ZXJ5dGhpbmcoKSkNCmBgYA0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGxhdmFhbikNCm1vZGVsIDwtICcgIyBkaXJlY3QgZWZmZWN0DQogICAgICAgICAgICAgbG14X3Bvc3QgfiBjKnNlbGZfYXdhcmVuZXNzX3ByZQ0KICAgICAgICAgICAjIG1lZGlhdG9yDQogICAgICAgICAgICAgc2VsZl9hd2FyZW5lc3NfcG9zdCB+IGEqc2VsZl9hd2FyZW5lc3NfcHJlDQogICAgICAgICAgICAgbG14X3Bvc3QgfiBiKnNlbGZfYXdhcmVuZXNzX3Bvc3QNCiAgICAgICAgICAgIyBpbmRpcmVjdCBlZmZlY3QgKGEqYikNCiAgICAgICAgICAgICBhYiA6PSBhKmINCiAgICAgICAgICAgIyB0b3RhbCBlZmZlY3QNCiAgICAgICAgICAgICB0b3RhbCA6PSBjICsgKGEqYiknDQoNCmZpdCA8LSBzZW0obW9kZWwsIGRhdGEgPSBkc193aWRlKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnNlbVBsb3Q6OnNlbVBhdGhzKGZpdCwgInBhciIsDQogICAgICAgICAgICAgc2l6ZU1hbiA9IDE1LCBzaXplSW50ID0gMTUsIHNpemVMYXQgPSAxNSwNCiAgICAgICAgICAgICBlZGdlLmxhYmVsLmNleD0xLjUsDQogICAgICAgICAgICAgZmFkZT1GQUxTRSwgcm90YXRpb24gPSAyKQ0KDQpgYGANCg0KDQpgYGB7cn0NCnN1bW1hcnkoZml0KQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnBzeWNoOjptZWRpYXRlKGxteF9wb3N0IH4gc2VsZl9hd2FyZW5lc3NfcHJlICsgKHNlbGZfYXdhcmVuZXNzX3Bvc3QpLCBkYXRhID0gZHNfd2lkZSkgDQpgYGANCg0KDQoNCiMjIE1lZGlhdGlvbiAoMikNCg0KDQpgYGB7cn0NCm1vZGVsIDwtICdsbXhfcG9zdCB+IHNlbGZfYXdhcmVuZXNzX3ByZStsbXhfcHJlDQogICAgICAgICAgc2VsZl9hd2FyZW5lc3NfcG9zdCB+IHNlbGZfYXdhcmVuZXNzX3ByZQ0KICAgICAgICAgIGxteF9wb3N0IH4gc2VsZl9hd2FyZW5lc3NfcG9zdA0KICAgICAgICAgIGxteF9wcmUgfn4gMCpzZWxmX2F3YXJlbmVzc19wcmUnDQoNCg0KZml0IDwtIHNlbShtb2RlbCwgZGF0YSA9IGRzX3dpZGUpDQpgYGANCg0KYGBge3J9DQpzdW1tYXJ5KGZpdCkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCnNlbVBsb3Q6OnNlbVBhdGhzKGZpdCwgInBhciIsDQogICAgICAgICAgICAgc2l6ZU1hbiA9IDE1LCBzaXplSW50ID0gMTUsIHNpemVMYXQgPSAxNSwNCiAgICAgICAgICAgICBlZGdlLmxhYmVsLmNleD0xLjUsDQogICAgICAgICAgICAgZmFkZT1GQUxTRSwgcm90YXRpb24gPSAyKQ0KDQpgYGANCg0KDQoNCiMjIFJlZ3Jlc3NhbyAoYXBvcyByZXVuacOjbykNCg0KDQojIyBjcmVhdGUgYSB3aWRlIGRhdGENCmBgYHtyfQ0KZHNfd2lkZSA8LSBkcyAgJT4lIA0KICBzZWxlY3QoZW1haWxfbGlkZXIsIGVtYWlsX2F2YWxpYWRvciwgdGVtcG8sIHNlbGZfYXdhcmVuZXNzOmxteCkgJT4lIA0KICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGModGVtcG8pLCB2YWx1ZXNfZnJvbT1jKHNlbGZfYXdhcmVuZXNzOmxteCkpICAlPiUgDQogIHVuY2hvcChldmVyeXRoaW5nKCkpDQoNCiNqb25hdGFuIHRlaXhlaXJhIGF2YWxvdSBkdWFzIHBlc3NvYXMNCmBgYA0KDQoNCiMjIGNyZWF0ZSBjaGFuZ2UgdmFyaWFibGVzDQoNCmBgYHtyfQ0KZHNfd2lkZSAgPC0gZHNfd2lkZSAgJT4lIA0KICBtdXRhdGUoZGVsdGFfc2VsZl9hd2FyZW5lc3MgPSBzZWxmX2F3YXJlbmVzc19wb3N0IC0gc2VsZl9hd2FyZW5lc3NfcHJlKQ0KDQpkc193aWRlICA8LSBkc193aWRlICAlPiUgDQogIG11dGF0ZShkZWx0YV90cmFuZm9ybWF0aW9uYWwgPSB0cmFuZm9ybWF0aW9uYWxfcG9zdCAtIHRyYW5mb3JtYXRpb25hbF9wcmUpDQoNCmRzX3dpZGUgIDwtIGRzX3dpZGUgICU+JSANCiAgbXV0YXRlKGRlbHRhX2Vtb3Rpb25hbF9pbnRlbCA9IGVtb3Rpb25hbF9pbnRlbF9wb3N0IC0gZW1vdGlvbmFsX2ludGVsX3ByZSkNCg0KZHNfd2lkZSAgPC0gZHNfd2lkZSAgJT4lIA0KICBtdXRhdGUoZGVsdGFfbG14ID0gbG14X3Bvc3QgLSBsbXhfcHJlKQ0KDQpkc193aWRlICAlPiUgc2VsZWN0KGxteF9wb3N0LGxteF9wcmUsIGRlbHRhX2xteCkNCmBgYA0KDQojIyBsaW5lYXIgcmVncmVzc2lvbiAodmlhIGZ1bmN0aW9uKQ0KDQpgYGB7cn0NCnJlZ19hdXQgPC0gZnVuY3Rpb24odmFyKSB7DQogICNtb2RlbF9mb3JtdWxhIDwtIGZvcm11bGEocGFzdGUwKHZhciwgIn4gc2VsZl9hd2FyZW5lc3NfcHJlIikpDQogIGxtKHBhc3RlMCh2YXIsICJ+IGRlbHRhX3NlbGZfYXdhcmVuZXNzIiksIGRhdGEgPSBkc193aWRlKSAlPiUgb2xzcnI6Om9sc19yZWdyZXNzKCkNCn0NCmBgYA0KDQo+IEVtb3Rpb25hbCBpbnRlbGxpZ2VuY2UNCg0KYGBge3J9DQpyZWdfYXV0KCJkZWx0YV9lbW90aW9uYWxfaW50ZWwiKQ0KYGBgDQoNCj4gVHJhbnNmb3JtYXRpb25hbA0KDQoNCmBgYHtyfQ0KcmVnX2F1dCgiZGVsdGFfdHJhbmZvcm1hdGlvbmFsIikNCmBgYA0KDQo+IExNWA0KDQoNCmBgYHtyfQ0KcmVnX2F1dCgiZGVsdGFfbG14IikNCmBgYA0KDQoNCiMjIFBsb3RzIA0KDQpgYGB7cn0NCmdncGxvdChkc193aWRlLGFlcyh4ID0gZGVsdGFfc2VsZl9hd2FyZW5lc3MsIHkgPSBkZWx0YV90cmFuZm9ybWF0aW9uYWwgKSkgKw0KICBnZW9tX2ppdHRlcigpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKw0KICB0aGVtZV9idygpICsgbGFicyh4ID0gIlNlbGYgQXdhcmVuZXNzIiwgeSA9ICJUcmFuZm9ybWF0aW9uYWwiKSArDQogIGdncHVicjo6c3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGRzX3dpZGUsYWVzKHggPSBkZWx0YV9zZWxmX2F3YXJlbmVzcywgeSA9IGRlbHRhX2Vtb3Rpb25hbF9pbnRlbCApKSArDQogIGdlb21faml0dGVyKCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArDQogIHRoZW1lX2J3KCkgKyBsYWJzKHggPSAiU2VsZiBBd2FyZW5lc3MiLCB5ID0gIkVtb3Rpb25hbCBpbnRlbGxpZ2VuY2UiKSArDQogICBnZ3B1YnI6OnN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90KGRzX3dpZGUsYWVzKHggPSBkZWx0YV9zZWxmX2F3YXJlbmVzcywgeSA9IGRlbHRhX2xteCApKSArDQogIGdlb21faml0dGVyKCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArDQogIHRoZW1lX2J3KCkgKyBsYWJzKHggPSAiU2VsZiBBd2FyZW5lc3MiLCB5ID0gIkxNWCIpICsNCiAgZ2dwdWJyOjpzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpDQpgYGANCg0KDQoNCiMgRml4aW5nIGluY29uc2lzdGVuY2llcw0KDQpgYGB7cn0NCmRzX3dpZGUyIDwtZHMgICU+JSANCiAgc2VsZWN0KGVtYWlsX2xpZGVyLCB0ZW1wbywgc2VsZl9hd2FyZW5lc3M6bG14KSAlPiUgDQogICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gYyh0ZW1wbyksIA0KICAgICAgICAgICAgICAgdmFsdWVzX2Zyb209YyhzZWxmX2F3YXJlbmVzczpsbXgpLA0KICAgICAgICAgICAgICAgdmFsdWVzX2ZuID0gKC4gPSBtZWFuKSkgICU+JSANCiAgdW5jaG9wKGV2ZXJ5dGhpbmcoKSkNCg0KcHN5Y2g6Om1lZGlhdGUobG14X3Bvc3QgfiBzZWxmX2F3YXJlbmVzc19wcmUgKyAoc2VsZl9hd2FyZW5lc3NfcG9zdCksIGRhdGEgPSBkc193aWRlMikgDQoNCmBgYA0KDQo+IERvbmUhDQoNCg==