Figure 5.1: Illustrative Examples: Political Development, Power-Sharing and Foreign Aid Flows in the DRC and Liberia

# Libraries
library(tidyverse)
library(foreign)
library(countrycode)
library(cowplot)
library(tikzDevice)

# Read Data
load("./data/diss_df.rda")
aid <- read.dta("./data/aiddata_full.dta")
ucdp_cy <- read_csv("./data/133280_onset2012csv.csv")

p4 <- haven::read_spss("./data/p4v2012.sav")
names(p4)[2] <- "GWNo"
# Polity IV treats Serbia as Yugoslavia at some periods. 
# I change it back to Serbia
p4[p4$GWNo == 347 & p4$year > 1991, "GWNo"] <- 345


# Prepare UCDP data

# load two small helper function to determine pre- and post-conflict years
ag_seq <- function(x) {
  runs <- cumsum(c(0, diff(x) != 1 ))
  return(runs)
}

source("./functions/identifyPostConflictYears.R")

# load and wrangle ucdp data
ucdp_cy <- ucdp_cy %>% 
  arrange(gwno, year) %>% 
  group_by(gwno) %>% 
  mutate(iso2c = countrycode(gwno, "cown", "iso2c"),
         ucdp_dummy = ifelse(incidencev412 == 1, 1, 0),
         pc = pcIdentifier(ucdp_dummy),
         pc = ifelse(pc == 2, 1, 0),
         conflict_ep_id = cumsum(c(ifelse(first(ucdp_dummy) == 1, 
                                          1, 0), 
                                 diff(ucdp_dummy) != 0)), 
         conflict_ep_id = as.numeric(ifelse(ucdp_dummy == 1, 
                                            conflict_ep_id, 
                                            NA)),
         peace_ep_id = cumsum(c(ifelse(first(pc) == 2, 
                                       2, 1), 
                                diff(pc) != 0)),
         peace_ep_id = as.numeric(ifelse(pc == 1, peace_ep_id, NA)))%>% 
  group_by(gwno, conflict_ep_id) %>% 
  mutate(conflict_year = -1 * rev(cumsum(ucdp_dummy == 1))) %>% 
  group_by(gwno, peace_ep_id) %>% 
  mutate(peace_year = cumsum(pc == 1)) %>% 
  group_by(gwno) %>% 
  mutate(conf_and_peace_years = conflict_year + peace_year)

# Merge in Aid data
ucdp_cy <- left_join(ucdp_cy, 
                     aid, 
                     by = c("iso2c" = "iso2", "year")) %>% 
  filter(year >= 1989) %>% 
  dplyr::rename(wb_AidGNI = DT_ODA_ODAT_GN_ZS,
                wb_AidPC = DT_ODA_ODAT_PC_ZS,
                wb_AidGmentXP = DT_ODA_ODAT_XP_ZS,
                oecd_Aid = aid_oecd_commitment2011USD,
                oecd_Aid_mill = aid_oecd_commitment2011USD_mill,
                aiddata_Aid = commitment_amount_usd_constant)


# Prepare data, i.e. subset UCDP data with only the countries in my sample etc.
ucdp_cy_diss_df <- ucdp_cy %>% 
  filter(gwno %in% unique(diss_df$GWNo)) %>% 
  group_by(recipient) %>% 
  mutate(mean_aid_gdp = mean(aiddata_Aid / GDP, na.rm = T)) %>% 
  ungroup() %>% 
  # mutate(ordered_recipient_by_aidmean = factor(recipient, 
  #                                              levels = recipient[order(mean_aid_gdp, 
  #                                                                                  decreasing = T)])) %>% 
  left_join(., diss_df[, c("GWNo", "year", "cabinetINC", "cabinetCOUNT", "seniorCOUNT", "nonseniorCOUNT")],
            by = c("gwno" = "GWNo", "year")) %>% 
  left_join(., p4[, c("GWNo", "year", "polity2")], by = c("gwno" = "GWNo", "year")) %>% 
  filter(year <= 2010)



# define function that generates illustrative country plots 
plot_country_example <- function(country, year_min, year_max) {

  
# Aid Plot
cntry_illustration_plot <- ucdp_cy_diss_df %>% 
  filter(recipient == country & year >= year_min & year <= year_max) %>% 
  ggplot(., aes(x = year, y = aiddata_Aid / GDP * 100)) +

  # Add conflict years to aid plot
  geom_bar(data = ucdp_cy_diss_df %>% filter(incidencev412 == 1 &
                                                 recipient == country &
                                                 year >= year_min & year <= year_max),
           aes(x = year, y = Inf),
           fill = "#de2d26", 
           alpha = 0.2, stat = "identity", width = 1) +
  geom_bar(stat = "identity",
           position = "dodge", 
           color = "black", 
           fill = "#969696", width = 1) +
  scale_x_continuous(breaks = year_min:year_max) +
  labs(x = "", y = "Aid / GDP")

# Polity Plot
cntry_illustration_polity <- ucdp_cy_diss_df %>% 
  filter(recipient == country & year >= year_min & year <= year_max) %>% 
  ggplot(., aes(x = year, y = polity2)) +
  geom_bar(stat = "identity", position = "dodge", color = "white", fill = "white", width = 1) +
  
  # Add conflict years to polity plot
  geom_bar(data = ucdp_cy_diss_df %>% filter(incidencev412 == 1 &
                                                 recipient == country &
                                                 year >= year_min & year <= year_max),
           aes(x = year, y = Inf),
           fill = "#de2d26", alpha = 0.2, stat = "identity", width = 1) +

  geom_point() + geom_line() + 
  scale_x_continuous(breaks = year_min:year_max) +
  labs(x = "", y = "Polity 2")

# Power-Sharing Plot
cntry_illustration_ps <- ucdp_cy_diss_df %>% 
  filter(recipient == country & year >= year_min & year <= year_max) %>% 
  dplyr::select(year, seniorCOUNT, nonseniorCOUNT) %>% 
  gather(key, value, -year) %>% 
  mutate(value = ifelse(is.na(value), 0, value)) %>% 
  ggplot(., aes(x = year, y =  value, fill = factor(key))) +
  geom_bar(stat = "identity", 
           position = "stack", color = "black", width = 1) +
  scale_fill_manual("", 
                    values = c("#bdc9e1", "#045a8d"),
                    labels = c("Nonsenior rebel seats", "Senior rebel seats")) + 
  
  # Add conflict years to ps plot
  geom_bar(data = ucdp_cy_diss_df %>% filter(incidencev412 == 1 &
                                                 recipient == country &
                                                 year >= year_min & year <= year_max),
           aes(x = year, y = Inf),
           fill = "#de2d26", alpha = 0.2, stat = "identity", width = 1) +
  scale_x_continuous(breaks = year_min:year_max) +
  labs(x = "", y = "Number of Rebel Seats \n in Power-Sharing \nGovernment") +
  theme(legend.position = "bottom", legend.direction = "vertical")

# combine plot output
cowplot::plot_grid(cntry_illustration_plot, 
                   cntry_illustration_polity, 
                   cntry_illustration_ps,
                   nrow = 3, 
                   align = "v" )

}

# 
# # Output for manuscript
# # Liberia
# options( tikzDocumentDeclaration = "\\documentclass[15pt]{article}" )
# tikz("../figures/Liberia_illu.tex", height = 7, width = 5, pointsize = 7)
# plot_country_example("Liberia", 2000, 2010)
# dev.off()
# 
# # DRC
# options( tikzDocumentDeclaration = "\\documentclass[15pt]{article}" )
# tikz("../figures/DRC_illu.tex", height = 7, width = 5, pointsize = 7)
# plot_country_example("Congo, Dem. Rep.", 2000, 2010)
# dev.off()

# Output for Replication Archive
plot_grid(plot_country_example("Liberia", 2000, 2010), 
          plot_country_example("Congo, Dem. Rep.", 2000, 2010), 
          ncol = 2, 
          labels = c("Liberia", "DRC"), 
          vjust = -5,
          hjust = -7,
          scale = 0.9)

Figure 5.2: Foreign Aid and Polity Scores in Country-Years With and Without Power-Sharing Governments

# Libraries
library(tidyverse)
library(tikzDevice)

# Load Data
load("./data/diss_df.rda")

# Labels for easier plotting
diss_df$cabinetINClabel <- ifelse(diss_df$cabinetINC == 1, "Power-Sharing", 
                                    "No \nPower-Sharing")

# generate scatterplot, divided by power-sharing
aidps_democ_plot <- ggplot(diss_df, aes(x = log(aiddata_AidGDP), 
                                            y = polity2_t2))  +
  geom_point(size = 1.7, alpha = 0.5) +
  geom_smooth(method = "lm") +
  # geom_rug() +
  theme_bw() +
  labs(x = "Aid / GDP (log)", y = "Polity score at t2") +
  facet_wrap( ~ cabinetINClabel) 

# output plot for manuscript
# options(tikzDocumentDeclaration = "\\documentclass[11pt]{article}" )
# tikz("../figures/aidps_democ_plot.tex", height = 3.5)
# print(aidps_democ_plot)
# dev.off()

# output for replication archive
print(aidps_democ_plot)

Figure 5.3: Temporal Dynamics of the Interactive Effect between Power-Sharing and Foreign Aid

# Libraries
library(tidyverse)
library(cowplot)
library(lfe)
library(tikzDevice)

# Data
load("./data/diss_df.rda")

# Prepare data frame for multiple plots
polity_vars <- list(
  polity2_t1 = diss_df,
  polity2_t2 = diss_df, 
  polity2_t3 = diss_df, 
  polity2_t4 = diss_df, 
  polity2_t5 = diss_df, 
  fh_t1 = diss_df,
  fh_t2 = diss_df, 
  fh_t3 = diss_df, 
  fh_t4 = diss_df, 
  fh_t5 = diss_df
)

# create data frame with list column
polity_vars <- enframe(polity_vars)

# define function that will be applied to every data frame in the list column
main_model <- function(lead_type, data) {
  data <- as.data.frame(data)
  data$lead_var <- data[, grep(lead_type, names(data), value =T)]
  
  if(grepl("fh", lead_type)) {
      model <- lfe::felm(lead_var ~
                       cabinetCOUNT *
                       aiddata_AidGDP_ln +
                       log(GDP_per_capita) +
                       ln_pop +
                       conf_intens +
                       nonstate +
                       WBnatres +
                       fh | 0 | 0 | GWNo,
                       data=data)
    return(model)
  } else {
    model <- lfe::felm(lead_var ~
                       cabinetCOUNT *
                       aiddata_AidGDP_ln +
                       log(GDP_per_capita) +
                       ln_pop +
                       conf_intens +
                       nonstate +
                       WBnatres +
                       polity2 | 0 | 0 | GWNo,
                       data=data)
    return(model)
  }
}


# fit models & post-process data for plotting
model_all <- polity_vars %>% 
  mutate(model = map2(name, value, ~ main_model(.x, .y))) 

model_out <- model_all %>% 
  mutate(coef = map(model, broom::tidy)) %>% 
  unnest(coef) %>% 
  # keep only interaction term coefs
  filter(term == "cabinetCOUNT:aiddata_AidGDP_ln") %>% 
  mutate(dem_score = ifelse(grepl("polity", name), "Polity", "Freedom House")) %>% 
  dplyr::select(dem_score, name, estimate, std.error) %>% 
  group_by(dem_score) %>% 
  mutate(name = 1:5)

temp_dyn_democ <- model_out
save(temp_dyn_democ, file = "./data/temp_dyn_democ.rda")

temp_dynamics_plot <- ggplot(model_out, 
       aes(x = name, 
           y = estimate, 
           group = dem_score, color = dem_score)) +
  geom_point( size = 1.7, 
       position = position_dodge(width = .5)) + 
  geom_errorbar(aes(ymin = estimate - 1.67 * std.error, 
                    ymax = estimate + 1.67 * std.error), 
                width = 0, 
       position = position_dodge(width = .5)) +
  geom_hline(yintercept = 0, linetype = 2) +
  facet_wrap(~dem_score, nrow = 2, scales = "free_y") + 
  scale_color_brewer("",palette = "Set1") +
  theme_bw() + 
  labs(x = "Year after t0", y = "Estimate of Interaction Coefficient \n between Power-Sharing (cabinet)\n and Aid/GDP (log)") +
  theme(legend.position = "none")

# Output for manuscript
# options(tikzDocumentDeclaration = "\\documentclass[11pt]{article}" )
# tikz("../figures/temp_dynamics_plot.tex", height = 3.5)
# print(temp_dynamics_plot)
# dev.off()

# Output for replication archive
print(temp_dynamics_plot)

Figure 5.4: Marginal Effects of Power-Sharing and Foreign Aid on Post-Conflict Democratization

# Libraries
library(gridExtra)
library(Cairo)
library(tikzDevice)
library(reshape)


# Polity DV + cabineINC
model_polity_cabinc <- ols(polity2_t2 ~  
                        cabinetINC * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 ,
                      data=diss_df, x=T, y=T)
model_polity_cabinc <- robcov(model_polity_cabinc, diss_df$GWNo)

# Polity DV + cabCOUNT
model_polity_cabcount <- ols(polity2_t2 ~  
                        cabinetCOUNT * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 ,
                      data=diss_df, x=T, y=T)
model_polity_cabcount <- robcov(model_polity_cabcount, diss_df$GWNo)


# source interaction plot function to plot marginal effects
source("./functions//interaction_plots.R")

# Output for manuscript
# options( tikzDocumentDeclaration = "\\documentclass[11pt]{article}" )
# tikz("../figures/interaction.tex", height = 3.5)
# 
# # Output for replication archive
# par(mfrow=c(1,3),
#     mar = c(5, 7, 4, 0.5),
#     cex.lab = 1.3,
#     cex.axis = 1.3,
#     mgp = c(3.5, 1, 0))
# 
# interaction_plot_continuous(model_polity_cabcount, 
#                             "cabinetCOUNT", "aiddata_AidGDP_ln", "cabinetCOUNT * aiddata_AidGDP_ln", 
#                             title = "", 
#                             ylab = "Marginal effect of Power-Sharing (cabinet) \n on political development", 
#                             xlab = "a) Aid / GDP (Log)\n", 
#                             conf = .90)
# interaction_plot_continuous(model_polity_cabcount, 
#                             "aiddata_AidGDP_ln", "cabinetCOUNT", "cabinetCOUNT * aiddata_AidGDP_ln", 
#                             title = "", 
#                             ylab = "Marginal effect of Aid\n on political development",
#                             xlab = "b) Power-Sharing \n(Number of rebel seats)",
#                             conf = .90)
# interaction_plot_binary(model_polity_cabinc, 
#                              "aiddata_AidGDP_ln","cabinetINC", "cabinetINC * aiddata_AidGDP_ln", 
#                             title = "", 
#                             ylab = "Marginal effect of Aid\n on political development",
#                             xlab = "c) Power-Sharing \n(1 = Yes, 0 = No)",
#                             conf = .90)
# dev.off()

# Output for replication archive
par(mfrow=c(1,3),
    mar = c(5, 7, 4, 0.5),
    cex.lab = 1.3,
    cex.axis = 1.3,
    mgp = c(3.5, 1, 0))

interaction_plot_continuous(model_polity_cabcount, 
                            "cabinetCOUNT", "aiddata_AidGDP_ln", "cabinetCOUNT * aiddata_AidGDP_ln", 
                            title = "", 
                            ylab = "Marginal effect of Power-Sharing (cabinet) \n on political development", 
                            xlab = "a) Aid / GDP (Log)\n", 
                            conf = .90)
interaction_plot_continuous(model_polity_cabcount, 
                            "aiddata_AidGDP_ln", "cabinetCOUNT", "cabinetCOUNT * aiddata_AidGDP_ln", 
                            title = "", 
                            ylab = "Marginal effect of Aid\n on political development",
                            xlab = "b) Power-Sharing \n(Number of rebel seats)",
                            conf = .90)
interaction_plot_binary(model_polity_cabinc, 
                             "aiddata_AidGDP_ln","cabinetINC", "cabinetINC * aiddata_AidGDP_ln", 
                            title = "", 
                            ylab = "Marginal effect of Aid\n on political development",
                            xlab = "c) Power-Sharing \n(1 = Yes, 0 = No)",
                            conf = .90)

Figure 5.5: Model Predictions for the Effect of Power-Sharing and Foreign Aid on Post-Conflict Democratization

# Libraries
library(tidyverse)
library(rms)
library(gridExtra)
library(tikzDevice)

# Load data
load("data/diss_df.rda")

# to predict substantive effects from this model, we need to define data 
# distribution
diss_df$conflictID <- NULL
datadist_diss_df <- datadist(diss_df); options(datadist='datadist_diss_df')

# replicate Model from above Polity DV + cabCOUNT
model_polity_cabcount <- ols(polity2_t2 ~  
                        cabinetCOUNT * 
                        aiddata_AidGDP_ln +
                        ln_gdp_pc +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 ,
                      data=diss_df, x=T, y=T)
model_polity_cabcount <- robcov(model_polity_cabcount, diss_df$GWNo)

# Start predictions for aid
prediction_democ_aid <- Predict(model_polity_cabcount, 
                           cabinetCOUNT = c(0, 10), # no / much power-sharing
                           aiddata_AidGDP_ln = seq(-5.7, 5.17, 0.1),# range of aid
                           polity2 = 2.6,
                           conf.int = 0.9) 

subs_effects_pchng_aid <- ggplot(data.frame(prediction_democ_aid), 
                                    aes(x = exp(aiddata_AidGDP_ln), 
                                        y = yhat, 
                                        group = as.factor(cabinetCOUNT))) + 
  geom_line( color = "black", size = 1) + 
  geom_ribbon(aes(ymax = upper, 
                  ymin = lower, 
                  fill = as.factor(cabinetCOUNT)), 
              alpha = 0.7) +
  scale_fill_manual(values = c("#b3cde3", "#e41a1c"), 
                    name = "Number of Rebels \nin the Power-Sharing Coalition:") +
  theme_bw() +
  theme(text = element_text(size=8)) +
  labs(x = "Aid / GDP", 
       y = "Predicted Polity Scores") +
  theme(legend.position = "bottom") 

# Predictions power-sharing
prediction_democ_ps <- Predict(model_polity_cabcount, 
                              cabinetCOUNT = seq(0, 10, 1), 
                              aiddata_AidGDP_ln = c(0, 3.4),
                              polity2 = 2.6,
                              conf.int = 0.9)

prediction_democ_ps$aiddata_AidGDP_ln <- round(exp(prediction_democ_ps$aiddata_AidGDP_ln))


subs_effects_pchng_ps <- ggplot(data.frame(prediction_democ_ps), 
                                           aes(x = cabinetCOUNT, 
                                               y = yhat, 
                                               group = as.factor(aiddata_AidGDP_ln))) + 
  geom_line( color = "black", size = 1) + 
  geom_ribbon(aes(ymax = upper, 
                  ymin = lower, 
                  fill = as.factor(aiddata_AidGDP_ln)), 
              alpha = 0.7) +
  scale_fill_manual(values = c("#b3cde3", "#e41a1c"), 
                    name = "Aid in per cent of GDP:") +
  theme_bw() +
  scale_x_continuous(breaks = seq(0, 10, 2)) +
  theme(text = element_text(size=8)) +
  labs(x = "Power-Sharing (No. of rebel seats in government)", 
       y = "Predicted Polity Scores") +
  theme(legend.position = "bottom") 

# output prediction plots


# output plot for predicted VDEM election quality variables 

 
# options( tikzDocumentDeclaration = "\\documentclass[11pt]{article}" )
# tikz("../figures/aidps_pchng.tex", height = 4.5, width = 6.5)
# grid.arrange(subs_effects_pchng_ps,
#              subs_effects_pchng_aid,
#              nrow = 1)
# dev.off()

grid.arrange(subs_effects_pchng_ps, 
             subs_effects_pchng_aid, 
             nrow = 1)

Figure 5.6: Mechanisms: Variation in Types of Power-Sharing and Aid

# Libraries
library(tidyverse)
library(rms)
library(plm)
library(lfe)
library(tidyverse)
library(tikzDevice)

# Load data
load("./data/diss_df.rda")

# Estimate Models
model_polity_cabinc <- felm(polity2_t2 ~  
                        cabinetINC * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 | 0 | 0 | GWNo,
                      data=diss_df)

# Polity DV + seniorINC
model_polity_senior <- lfe::felm(polity2_t2 ~  
                        seniorINC * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 | 0 | 0 | GWNo ,
                      data=diss_df)

# Polity DV + nonseniorINC
model_polity_nonsenior <- felm(polity2_t2 ~  
                        nonseniorINC * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 | 0 | 0 | GWNo,
                      data=diss_df)

# DGA * PS
model_polity_cabinc_dga <- felm(polity2_t2 ~  
                        cabinetINC * log(dga_gdp_zero + 1) +
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 | 0 | 0 | GWNo,
                      data=diss_df)

model_polity_cabinc_programaid <- felm(polity2_t2 ~  
                        cabinetINC * log(program_aid_gdp_zero + 1) +
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 | 0 | 0 | GWNo,
                      data=diss_df)

model_polity_cabinc_budget <- felm(polity2_t2 ~  
                        cabinetINC * log(commodity_aid_gdp_zero + 1) +
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 | 0 | 0 | GWNo,
                      data=diss_df)

mechanism_models <- list("Cabinet PS (Baseline)" = model_polity_cabinc, 
                         "Senior PS" = model_polity_senior, 
                         "Nonsenior PS" = model_polity_nonsenior, 
                         "DGA" = model_polity_cabinc_dga, 
                         "Program Aid"= model_polity_cabinc_programaid, 
                         "Budget Aid" = model_polity_cabinc_budget) %>% 
  enframe() %>% 
  mutate(tidymodel = map(value, broom::tidy)) %>% 
  unnest(tidymodel) %>% 
  filter(grepl(":", term)) %>% 
  mutate(name = forcats::fct_relevel(name, c("Cabinet PS (Baseline)", 
                                      "Senior PS", 
                                      "Nonsenior PS", 
                                      "DGA", 
                                      "Program Aid", 
                                      "Budget Aid")))
mechanism_models_democ <- mechanism_models
save(mechanism_models_democ, file= "./data/mechanism_models_democ.rda")

mechanims_democ_models_plot <- ggplot(mechanism_models, aes(x = name, y = estimate) ) +
  geom_point() +
  geom_errorbar(aes(ymin = estimate - 1.67 * std.error, 
                    ymax = estimate + 1.67 * std.error), 
                width = 0) +
  theme_bw() +
  theme(axis.title.y = element_text(size = 10)) +
  geom_hline(yintercept = 0, linetype = 2) +
  labs(x = "", y = "Coefficient Estimate of Interaction between \n Different Types of Power-Sharing (binary) \n and Different Aid Types")

# Output for manuscript
# options(tikzDocumentDeclaration = "\\documentclass[11pt]{article}" )
# tikz("../figures/mechanims_democ_models_plot.tex", height = 2.75)
# print(mechanims_democ_models_plot)
# dev.off()

# Output for replication archive
print(mechanims_democ_models_plot)

Figure 5.7 & Table B.5: Covariate Balance Before and After Matching

# Libraries
library(dplyr)
library(MatchIt)
library(texreg)
library(rms)
library(tidyr)
library(ggrepel) # needed for variable labels
library(ggplot2)
library(tikzDevice)
library(xtable)

# Load data 
load("./data/diss_df.rda")

# select relevant variables
match_democ_data <- diss_df %>% 
  ungroup() %>% 
  dplyr::select(cabinetINC, cabinetCOUNT, seniorINC,
                seniorCOUNT, nonseniorINC, nonseniorCOUNT,
                aiddata_AidGDP, population, nonstate,
                WBnatres, fh, GDP_per_capita, conf_intens,
                aiddata_AidGDP_ln, 
                GWNo, year, 
                 polity2, polity2_t2, # check 
                fh, fh_t2, 
                pc_period, Location, ln_pop, ln_gdp_pc)

# keep only complete cases (necessary for matching)
match_democ_data <- match_democ_data[complete.cases(match_democ_data), ]

# generate pretreatment controls: control variables in first post-conflict year
match_democ_data <- match_democ_data %>% 
  arrange(GWNo, pc_period, year) %>% 
  group_by(GWNo, pc_period) %>% 
  mutate(match_aiddata_AidGDP_ln = first(aiddata_AidGDP_ln),
         match_pop = first(population),
         match_gdp = first(GDP_per_capita),
         match_nonstate = first(nonstate),
         match_WBnatres = first(WBnatres),
         match_polity = first(polity2), 
         match_fh = first(fh))

# explicitly convert to data frame
match_democ_data <- as.data.frame(match_democ_data)

# 1.1 Perform matching algorithm ------------------------------------------

set.seed(123)
match_democ_res <- matchit(cabinetINC ~
                          match_aiddata_AidGDP_ln +
                          log(match_gdp) +
                          log(match_pop) +
                          conf_intens + # conf_intens is already pre-treatment
                          match_nonstate +
                          log(match_WBnatres + 1)  +
                          match_polity,
                        method = "nearest",
                        distance = "mahalanobis",
                        ratio = 2,
                        data = match_democ_data)

# extract data
match_democ_df <- match.data(match_democ_res)

# Balance Improvement Plot ------------------------------------------------

balance_improvement <- summary(match_democ_res)$reduction
row.names(balance_improvement) <- c("Aid / GDP (log)", 
                                    "GDP / PC (log)",
                                    "Population (log)", 
                                    "Conflict Intensity",
                                    "Nonstate Conflict",
                                    "Nat. Res. Rents (log)", 
                                    "Regime Type (Polity)")

balance_improvement <- data.frame(variable = row.names(balance_improvement), 
                                  percent_balance_improvement = round(balance_improvement[, 1], 2))


plot_balanceimpr <- data.frame(`All Data` = abs(summary(match_democ_res, 
                                                        standardize = T)$sum.all$`Std. Mean Diff.`), 
                               `Matched Data` = abs(summary(match_democ_res, 
                                                            standardize = T)$sum.matched$`Std. Mean Diff.`),
                               cov = balance_improvement$variable) %>% 
  gather(key, value, -cov) %>% 
  filter(!is.nan(value) & !is.infinite(value)) %>% 
  mutate(key = gsub("\\.", " ", key))

# Plot balance improvement
plot_balanceimpr_out <- plot_balanceimpr %>% 
  ggplot(., aes(x = key, y = value)) + 
  geom_point(size = 2.5) + 
  geom_line(aes(group = cov),
            linemitre = 2, size = 0.6) + 
  geom_hline(yintercept = 0.25, aes(group = key)) +
  geom_label_repel(data = plot_balanceimpr %>% filter(key == "All Data"),
                   aes(label = cov),
                   nudge_x = -.3) +
  theme_bw() +
  labs( x = "", y = "Absolute Standardized Difference in Means")

# output balance improvement plot
# options( tikzDocumentDeclaration = "\\documentclass[11pt]{article}" )
# tikz("../figures/match_democ_balanceimpr.tex", height = 5)
# print(plot_balanceimpr_out)
# dev.off()

# Output for replication archive
print(plot_balanceimpr_out)

#### Estimate Models on Matched Sample #####

model_democ_matched <- ols(polity2_t2 ~  
                             cabinetINC *
                             aiddata_AidGDP_ln +
                             log(GDP_per_capita) +
                             log(population) +
                             conf_intens +
                             nonstate + 
                             WBnatres + 
                             polity2
                           ,
                           data=match_democ_df , x=T, y=T)
model_democ_matched <- rms::robcov(model_democ_matched, match_democ_df$GWNo)

model_democ_matched_fh <- ols(fh_t2 ~  
                             cabinetINC *
                             aiddata_AidGDP_ln +
                             log(GDP_per_capita) +
                             log(population) +
                             conf_intens +
                               nonstate + 
                               WBnatres + 
                               polity2                           ,
                             data=match_democ_df , x=T, y=T)
model_democ_matched_fh <- rms::robcov(model_democ_matched_fh, match_democ_df$GWNo)

## Order of coefficients in output table
name_map <- list(cabinetINC = "Power-Sharing (binary)",
                 "cabinetINC * aiddata_AidGDP_ln" = "Power-Sharing (binary) * Aid", 
                 aiddata_AidGDP_ln = "Aid / GDP (log)",
                 GDP_per_capita = "GDP p/c",
                 population = "Population",
                 conf_intens = "Conflict Intensity",
                 nonstate = "Non-State Violence",
                 WBnatres = "Nat. Res. Rents",
                 polity2 = "Regime Type")

source("./functions/will_lowe_texreg_reorder.R")

# Model list
model_list <- list(model_democ_matched, model_democ_matched_fh)

oldnames <- all.varnames.dammit(model_list)
ror <- build.ror(oldnames, name_map)

# Output for replication archive
# texreg(l = model_list,
#         stars = c(0.001, 0.01, 0.05, 0.1),
#         symbol = "+",
#         table = F,
#         booktabs = T,
#         use.packages = F,
#         dcolumn = T,
#         file = "../output/democ_matching_results.tex",
#         custom.model.names = c("(1) Polity",
#                                "(2) Freedom House"),
#         custom.coef.names = ror$ccn,
#         omit.coef = ror$oc,
#         reorder.coef = unique(ror$rc),
#         include.lr = F)

# Output for replication archive
htmlreg(l = model_list,
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        caption = "", 
        table = F,
        booktabs = T,
        use.packages = F,
        dcolumn = T,
        custom.model.names = c("(1) Polity", 
                               "(2) Freedom House"),
        custom.coef.names = ror$ccn, 
        omit.coef = ror$oc, 
        reorder.coef = unique(ror$rc),
        star.symbol = "\\*", 
        include.lr = F)
(1) Polity (2) Freedom House
Power-Sharing (binary) -2.01* -1.08**
(0.86) (0.35)
Power-Sharing (binary) * Aid 1.15*** 0.50***
(0.33) (0.14)
Aid / GDP (log) -0.36 -0.12
(0.24) (0.10)
GDP p/c -0.04 0.20
(0.27) (0.14)
Population -0.04 -0.01
(0.12) (0.09)
Conflict Intensity 0.15 -0.44
(0.42) (0.37)
Non-State Violence -0.91 -0.83*
(0.56) (0.33)
Nat. Res. Rents -0.02 -0.01
(0.01) (0.01)
Regime Type 0.80*** 0.18***
(0.08) (0.03)
Num. obs. 108 108
R2 0.79 0.62
Adj. R2 0.77 0.59
***p < 0.001, **p < 0.01, *p < 0.05, +p < 0.1

Figure 5.8: The The Relationship between Foreign Aid and Aid (Instrumented)

# load libraries
library(AER)
library(ivpack)
library(lmtest)
library(tikzDevice)


# load data with instrument; this gives "instrument_df" data frame
load(file = "./data/instrumentedAid2.RData")
load("./data/diss_df.rda")

diss_df_iv <- merge(diss_df, 
                      instrument_df, 
                      by = c("iso2c", "year"), all.x = TRUE)


# subset only complete.cases / necessary for cluster.robust.se()
iv_na <- na.omit(diss_df_iv[, c("polity_chng", 
                               "cabinetCOUNT", 
                               "cabinetINC", 
                               "aiddata_Aid",
                               "aiddata_AidGDP_ln",
                               "aiddata_AidPC_ln",
                               "fh",
                               "fh_chng",
                               "GDP_per_capita", 
                               "population", 
                               "conf_intens", 
                               "WBnatres", 
                               "polity2", 
                               "polity2_t2",
                               "total_sum_except", 
                               "year", 
                               "GWNo", 
                               "GDP",
                               "nonstate")])


# 3.1 Plot Z_it against aid -----------------------------------------------

plot_democ_aid_iv <- ggplot(iv_na, aes(x = log(total_sum_except), 
                                       y = log(aiddata_Aid))) +
  geom_point(alpha = 0.7, size = 3) + 
  geom_smooth(method = "lm") +
  theme_bw() + 
  labs(x = "Aid (instrumented) Log",
       y = "Aid (AidData) Log ")


# Output Manuscript
# options( tikzDocumentDeclaration = "\\documentclass[10pt]{article}" )
# tikz("../figures/aid_instr_democ.tex", height = 4)
# print(plot_democ_aid_iv)
# dev.off()

# Output Replication Archive
print(plot_democ_aid_iv)

Table 5.1: Individual Effects of Power-Sharing and Foreign Aid on Post-Conflict Political Development

# Libraries
library(texreg)
library(rms)

# Load data
load("./data/diss_df.rda")

# specify vector with control vars
controlvars <- c("log(aiddata_AidGDP)",
                 "log(GDP_per_capita)",
                 "ln_pop",
                 "conf_intens", 
                 "nonstate",
                 "WBnatres",
                 "polity2")
#### Power-Sharing only Models ####

# PS only + cabinetCOUNT
model_ps <- ols(formula(paste0("polity2_t2 ~ cabinetCOUNT + ", 
                               paste0(controlvars, collapse = " + "))),
                data = diss_df, x = T, y = T)
model_ps <- robcov(model_ps, diss_df$GWNo)

# PS only + seniorCOUNT
model_seniorCOUNT <- ols(formula(paste0("polity2_t2 ~ seniorCOUNT + ", 
                                        paste0(controlvars, collapse = " + "))),
                         data = diss_df, x = T, y = T)
model_seniorCOUNT <- robcov(model_seniorCOUNT, diss_df$GWNo)

# PS only + nonseniorCOUNT
model_nonseniorCOUNT <- ols(formula(paste0("polity2_t2 ~ nonseniorCOUNT + ", 
                                           paste0(controlvars, collapse = " + "))),
                            data = diss_df, x = T, y = T)
model_nonseniorCOUNT <- robcov(model_nonseniorCOUNT, diss_df$GWNo)

#### Aid-only Models ####

# DGA
model_gov_aid <- ols(formula(paste0("polity2_t2 ~ cabinetCOUNT + log(dga_gdp_zero + 1) + ", 
                                    paste0(controlvars, collapse = " + ")))
                     ,
                     data=diss_df, x=T, y=T)
model_gov_aid <- robcov(model_gov_aid, diss_df$GWNo)


# Program Aid
model_program_aid <- ols(formula(paste0("polity2_t2 ~ cabinetCOUNT + log(program_aid_gdp_zero + 1) + ", 
                                        paste0(controlvars, collapse = " + ")))
                         ,
                         data=diss_df, x=T, y=T)
model_program_aid <- robcov(model_program_aid, diss_df$GWNo)


# Budget Aid
model_commodity_aid <- ols(formula(paste0("polity2_t2 ~ cabinetCOUNT + log(commodity_aid_gdp_zero + 1) + ", 
                                          paste0(controlvars, collapse = " + ")))
                           ,
                           data=diss_df, x=T, y=T)
model_commodity_aid <- robcov(model_commodity_aid, diss_df$GWNo)


# Output table for manuscript
source("functions/extract_ols_custom.R")
source("./functions/custom_texreg.R")
environment(custom_texreg) <- asNamespace('texreg')
# 
custom_texreg(l = list(model_ps,
                       model_seniorCOUNT,
                       model_nonseniorCOUNT,
                       model_gov_aid,
                       model_program_aid,
                       model_commodity_aid),
              file = "../output/ind_effects_democ.tex",
              reorder.coef = c(1, 9, 10, 11:13, 2:8),
              stars = c(0.001, 0.01, 0.05, 0.1),
              symbol = "+",
              # custom.multicol = T,
              custom.coef.names = c("Intercept",
                                    "Power-Sharing (cabinet)",
                                    "Aid / GDP (log)",
                                    "GDP p/c (log)",
                                    "Population (log)",
                                    "Conflict intensity",
                                    "Non-State Violence",
                                    "Nat. res. rents",
                                    "Regime Type (Polity)",
                                    "Power-Sharing (senior)",
                                    "Power-Sharing (nonsenior)",
                                    "Democracy Aid/GDP (log)",
                                    "Program Aid/GDP (log)",
                                    "Budget Aid/GDP (log)"),
              omit.coef = "Intercept",
              table = FALSE,
              dcolumn = T,
              groups = list("Power-Sharing" = 1:3, "Aid" = 4:7, "Controls"  = 8:13),
              booktabs = T,
              use.packages = F,
              center = TRUE,
              include.cluster = T, 
              include.lr = F, 
              include.rsquared = F)
# custom.model.names = c(" \\multicolumn{3}{c}{ \\textbf{Power-Sharing}} & \\multicolumn{3}{c}{ \\textbf{Foreign Aid}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7} & \\multicolumn{1}{c}{(1)  }",
#                        "\\multicolumn{1}{c}{(2)  }",
#                        "\\multicolumn{1}{c}{(3)  }",
#                        "\\multicolumn{1}{c}{(4)  }",
#                        "\\multicolumn{1}{c}{(5)   }",
#                        "\\multicolumn{1}{c}{(6)   }"))
# 

# Output table for replication archive

htmlreg(l = list(model_ps, 
                 model_seniorCOUNT, 
                 model_nonseniorCOUNT, 
                 model_gov_aid, 
                 model_program_aid, 
                 model_commodity_aid), 
        reorder.coef = c(1, 9, 10, 11:13, 2:8),
        # file = "./output/psresults.tex",
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        caption = "", 
        custom.multicol = T,
        custom.coef.names = c("Intercept",
                              "Power-Sharing (cabinet)",
                              "Aid / GDP (log)",
                              "GDP p/c (log)",
                              "Population (log)",
                              "Conflict intensity",
                              "Non-State Violence",
                              "Nat. res. rents",
                              "Regime Type (Polity)",
                              "Power-Sharing (senior)",
                              "Power-Sharing (nonsenior)", 
                              "Democracy Aid/GDP (log)", 
                              "Program Aid/GDP (log)", 
                              "Budget Aid/GDP (log)"),
        omit.coef = "Intercept",
        groups = list("Power-Sharing" = 1:3, "Aid" = 4:7, "Controls"  = 8:13),
        table = FALSE, 
        dcolumn = T,
        booktabs = T,
        use.packages = F,
        center = TRUE,
        star.symbol = "\\*", 
        include.lr = F)
Model 1 Model 2 Model 3 Model 4 Model 5 Model 6
Power-Sharing
     Power-Sharing (cabinet) 0.10* 0.10* 0.10* 0.10*
(0.05) (0.05) (0.05) (0.05)
     Power-Sharing (senior) 0.31*
(0.13)
     Power-Sharing (nonsenior) 0.14+
(0.08)
Aid
     Democracy Aid/GDP (log) 0.49
(0.40)
     Program Aid/GDP (log) 0.33
(0.44)
     Budget Aid/GDP (log) 0.06
(0.24)
     Aid / GDP (log) -0.03 -0.02 -0.02 -0.10 -0.12 -0.05
(0.14) (0.14) (0.14) (0.18) (0.20) (0.14)
Controls
     GDP p/c (log) -0.12 -0.12 -0.12 -0.10 -0.02 -0.12
(0.31) (0.31) (0.31) (0.31) (0.35) (0.32)
     Population (log) -0.02 -0.02 -0.02 -0.02 0.01 -0.02
(0.11) (0.11) (0.11) (0.11) (0.12) (0.11)
     Conflict intensity 0.19 0.17 0.20 0.04 0.16 0.17
(0.45) (0.45) (0.45) (0.44) (0.44) (0.46)
     Non-State Violence -0.38 -0.35 -0.38 -0.25 -0.33 -0.36
(0.52) (0.52) (0.52) (0.52) (0.53) (0.51)
     Nat. res. rents -0.04* -0.04* -0.03* -0.04* -0.03* -0.04*
(0.02) (0.02) (0.02) (0.02) (0.02) (0.02)
     Regime Type (Polity) 0.82*** 0.82*** 0.82*** 0.81*** 0.82*** 0.82***
(0.07) (0.07) (0.07) (0.07) (0.07) (0.07)
Num. obs. 263 263 263 263 263 263
Adj. R2 0.76 0.76 0.76 0.76 0.76 0.76
***p < 0.001, **p < 0.01, *p < 0.05, +p < 0.1

Table 5.2: Interaction Effects of Power-Sharing and Foreign Aid on Post-Conflict Political Development

# Libraries
library(tidyverse)
library(rms)
# library(texreg)

# load 
load("./data/diss_df.rda")

# to predict substantive effects from this model, we need to define data 
# distribution
diss_df$conflictID <- NULL
datadist_diss_df <- datadist(diss_df); options(datadist='datadist_diss_df')

# Polity DV + cabineINC
model_polity_cabinc <- ols(polity2_t2 ~  
                        cabinetINC * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 ,
                      data=diss_df, x=T, y=T)
model_polity_cabinc <- robcov(model_polity_cabinc, diss_df$GWNo)

# Polity DV + cabCOUNT
model_polity_cabcount <- ols(polity2_t2 ~  
                        cabinetCOUNT * 
                        aiddata_AidGDP_ln +
                        log(GDP_per_capita) +
                        ln_pop +
                        conf_intens +
                        nonstate + 
                        WBnatres +
                        polity2 ,
                      data=diss_df, x=T, y=T)
model_polity_cabcount <- robcov(model_polity_cabcount, diss_df$GWNo)

# FH + cabINC
model_fh_cabinc <- ols(fh_t2 ~  
                      cabinetINC * aiddata_AidGDP_ln +
                      log(GDP_per_capita) +
                      ln_pop +
                      conf_intens +
                      nonstate + 
                      WBnatres +
                      fh, x= T, y = T,
                    data=diss_df)
model_fh_cabinc <- robcov(model_fh_cabinc, diss_df$GWNo)

# FH + cabcount
model_fh_cabcount <- ols(fh_t2 ~  
                      cabinetCOUNT * aiddata_AidGDP_ln +
                      log(GDP_per_capita) +
                      ln_pop +
                      conf_intens +
                      nonstate + 
                      WBnatres +
                      fh ,
                    data=diss_df, x=T, y=T)
model_fh_cabcount <- robcov(model_fh_cabcount, diss_df$GWNo)

# tex output
source("functions/extract_ols_custom.R")
source("./functions/custom_texreg.R")
environment(custom_texreg) <- asNamespace('texreg')
# 
custom_texreg(l=list(model_polity_cabinc,
                     model_polity_cabcount,
                     model_fh_cabinc,
                     model_fh_cabcount),
              file = "../output/mainresults2.tex",
              stars = c(0.001, 0.01, 0.05, 0.1),
              custom.note = "%stars",
              center = TRUE,
              symbol = "+",
              reorder.coef = c(1, 9:11, 2:8, 12),
        custom.coef.names = c("Intercept",
                              "Power-sharing (binary)",
                              "Aid / GDP (log)",
                              "GDP p/c (log)",
                              "Population (log)",
                              "Conflict intensity",
                              "Non-State Violence",
                              "Nat. res. rents",
                              "Polity",
                              "Power-sharing (binary) * Aid",
                              "Power-sharing (cabinet)",
                              "Power-sharing (cabinet) * Aid",
                              "Freedom House"),
        omit.coef = "Intercept",
        table = FALSE,
        custom.multicol = T,
        dcolumn = T,
        booktabs = T,
        include.rsquared = F, 
        include.cluster = T,
        use.packages = F,
        custom.model.names = c("\\multicolumn{2}{c}{\\textbf{Polity}} & \\multicolumn{2}{c}{\\textbf{Freedom House}} \\\\ \\cmidrule(r){2-3} \\cmidrule(l){4-5} & \\multicolumn{1}{c}{(1)}",
                               "\\multicolumn{1}{c}{(2) }",
                               "\\multicolumn{1}{c}{(3) }",
                               "\\multicolumn{1}{c}{(4) }"))


# output replication archive
htmlreg(l=list(model_polity_cabinc, 
                     model_polity_cabcount, 
                     model_fh_cabinc,
                     model_fh_cabcount),
              # file = "../output/mainresults.tex",
              stars = c(0.001, 0.01, 0.05, 0.1),
              # custom.note = "%stars",
              center = TRUE,
              symbol = "+",
              reorder.coef = c(1, 9:11, 2:8, 12),
        custom.coef.names = c("Intercept",
                              "Power-sharing (binary)",
                              "Aid / GDP (log)",
                              "GDP p/c (log)",
                              "Population (log)",
                              "Conflict intensity",
                              "Non-State Violence",
                              "Nat. res. rents",
                              "Polity",
                              "Power-sharing (binary) * Aid",
                              "Power-sharing (cabinet)",
                              "Power-sharing (cabinet) * Aid",
                              "Freedom House"),
        omit.coef = "Intercept",
        table = FALSE, 
        custom.multicol = T, 
        dcolumn = T,
        booktabs = T,
        use.packages = F,
        star.symbol = "\\*", 
        include.lr = F)
Statistical models
Model 1 Model 2 Model 3 Model 4
Power-sharing (binary) -1.08+ -0.26+
(0.63) (0.16)
Power-sharing (binary) * Aid 0.81*** 0.12+
(0.24) (0.07)
Power-sharing (cabinet) -0.17+ -0.05+
(0.09) (0.03)
Power-sharing (cabinet) * Aid 0.11*** 0.02*
(0.03) (0.01)
Aid / GDP (log) -0.05 -0.02 -0.03 -0.03
(0.14) (0.14) (0.04) (0.04)
GDP p/c (log) -0.09 -0.08 -0.10+ -0.10+
(0.31) (0.31) (0.06) (0.06)
Population (log) 0.01 -0.02 0.01 0.00
(0.11) (0.11) (0.03) (0.03)
Conflict intensity 0.16 0.09 -0.07 -0.07
(0.45) (0.46) (0.09) (0.09)
Non-State Violence -0.37 -0.45 -0.36*** -0.38***
(0.50) (0.50) (0.11) (0.11)
Nat. res. rents -0.03* -0.04* -0.01+ -0.01*
(0.02) (0.02) (0.00) (0.00)
Polity 0.82*** 0.82***
(0.07) (0.07)
Freedom House 0.87*** 0.87***
(0.04) (0.04)
Num. obs. 263 263 272 272
Adj. R2 0.76 0.76 0.80 0.80
***p < 0.001, **p < 0.01, *p < 0.05, +p < 0.1

Table 5.3: Robustness Checks

# Libraries
library(tidyverse)
library(rms)
library(plm)
library(texreg)
library(countrycode)
library(texreg)

# Load Data
load("./data/diss_df.rda")

# Models

# Fractionalization
democ_model_elf <- ols(polity2_t2 ~
                         cabinetCOUNT * aiddata_AidGDP_ln +
                         ln_gdp_pc +
                         ln_pop +
                         conf_intens+
                         nonstate +
                         WBnatres +
                         polity2 +
                         Ethnic,
                       data=diss_df,
                       x = T, y = T)
democ_model_elf <- robcov(democ_model_elf, diss_df$GWNo)

# PKO
democ_model_pko <- ols(polity2_t2 ~
                         cabinetCOUNT * aiddata_AidGDP_ln +
                         ln_gdp_pc +
                         ln_pop +
                         conf_intens+
                         nonstate +
                         WBnatres +
                         polity2 +
                         DS_ordinal,
                       data=diss_df,
                       x = T, y = T)
democ_model_pko <- robcov(democ_model_pko, diss_df$GWNo)

# Cabinet Size

library(readxl)
cnts <- read_excel("./data/CNTSDATA.xls")

DEFINEDNAME: 21 00 00 01 0b 00 00 00 01 00 00 00 00 00 00 0d 3b 00 00 00 00 e5 3b 00 00 c1 00 DEFINEDNAME: 21 00 00 01 0b 00 00 00 01 00 00 00 00 00 00 0d 3b 00 00 00 00 e5 3b 00 00 c1 00 DEFINEDNAME: 21 00 00 01 0b 00 00 00 01 00 00 00 00 00 00 0d 3b 00 00 00 00 e5 3b 00 00 c1 00 DEFINEDNAME: 21 00 00 01 0b 00 00 00 01 00 00 00 00 00 00 0d 3b 00 00 00 00 e5 3b 00 00 c1 00

cnts <- cnts %>% filter(year >= 1989)

cnts$iso3c <- countrycode(cnts$country, "country.name", "iso3c")
cnts <- cnts %>% filter(country != "SOMALILAND")

testcabsize <- left_join(diss_df, cnts[, c("iso3c", "year", "polit10")])

testcabsize$ps_share <- testcabsize$cabinetCOUNT / testcabsize$polit10 * 100

model_cabsize <- ols(polity2_t2 ~
                       ps_share *
                       aiddata_AidGDP_ln +
                       ln_gdp_pc +
                       ln_pop +
                       conf_intens +
                       nonstate +
                       WBnatres +
                       polity2,
                     data = testcabsize, x = T, y = T)
model_cabsize <- robcov(model_cabsize, testcabsize$GWNo)

# Random Effects
country_re_democ <- plm(polity2_t2 ~
                  cabinetCOUNT +
                  aiddata_AidGDP_ln +
                  cabinetCOUNT * aiddata_AidGDP_ln +
                  ln_gdp_pc +
                  ln_pop +
                  conf_intens+
                  nonstate +
                  WBnatres +
                  polity2 ,
                data=diss_df, model = "random", index =c("GWNo", "year"))

series conflictID is NA and has been removed series conflictdummy, newconflictinyearv412, onset1v412, onset2v412, onset5v412, onset8v412, onset20v412, maxintyearv412, govonlyv412, terronlyv412, bothgovterrv412, sumconfv412, pcyears, is.pc, codingend are constants and have been removed

country_re_democ$vcov  <- vcovHC(country_re_democ, cluster="group")


# Region Fixed Effects
diss_df$region <- countrycode(diss_df$Location, "country.name", "region")
diss_df$country_year <- paste0(diss_df$Location, diss_df$year, sep = "-")

region_fe_democ <- plm(polity2_t2 ~
                     cabinetCOUNT * aiddata_AidGDP_ln +
                     ln_gdp_pc +
                     ln_pop +
                     conf_intens+
                     nonstate +
                     WBnatres +
                     polity2 ,
                   data=diss_df, 
                   model = "within", 
                   index =c("region", "country_year"))

series conflictID is NA and has been removed series conflictdummy, newconflictinyearv412, onset1v412, onset2v412, onset5v412, onset8v412, onset20v412, maxintyearv412, govonlyv412, terronlyv412, bothgovterrv412, sumconfv412, pcyears, is.pc, codingend are constants and have been removed

region_fe_democ$vcov  <- vcovHC(region_fe_democ, cluster="group")

# Country FE 
country_fe_democ <- plm(polity2_t2 ~
                     cabinetCOUNT * aiddata_AidGDP_ln +
                     ln_gdp_pc +
                     ln_pop +
                     conf_intens+
                     nonstate +
                     WBnatres +
                     polity2 ,
                   data=diss_df, 
                   model = "within", 
                   index =c("GWNo", "year"))

series conflictID is NA and has been removed series conflictdummy, newconflictinyearv412, onset1v412, onset2v412, onset5v412, onset8v412, onset20v412, maxintyearv412, govonlyv412, terronlyv412, bothgovterrv412, sumconfv412, pcyears, is.pc, codingend are constants and have been removed

country_fe_democ$vcov  <- vcovHC(country_fe_democ, cluster="group")


## Order of coefficients in output table
name_map_robustness <- list(cabinetCOUNT = "PS (cabinet)",
                            "cabinetCOUNT * aiddata_AidGDP_ln" = "PS (cabinet) * Aid", 
                            "cabinetCOUNT:aiddata_AidGDP_ln" = "PS (cabinet) * Aid",
                            ps_share = "PS (cabinet share)",
                            "ps_share * aiddata_AidGDP_ln" = "PS (cabinet share) * Aid",
                            aiddata_AidGDP_ln = "Aid / GDP (log)",
                            ln_gdp_pc = "GDP p/c",
                            ln_pop = "Population",
                            conf_intens = "Conflict Intensity",
                            nonstate = "Non-State Violence",
                            WBnatres = "Nat. Res. Rents",
                            polity2 = "Polity",
                            Ethnic = "Ethnic Frac.",
                            DS_ordinal = "UN PKO")

source("./functions/will_lowe_texreg_reorder.R")

# Model list
rob_models <- list(democ_model_elf,
     democ_model_pko,
     model_cabsize,
     country_re_democ,
     region_fe_democ,
     country_fe_democ)

oldnames <- all.varnames.dammit(rob_models)
ror <- build.ror(oldnames, name_map_robustness)



# Output manuscript
# 
# source("./functions/custom_texreg.R")
# environment(custom_texreg) <- asNamespace('texreg')
# 
custom_texreg(l = rob_models,
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        table = F,
        booktabs = T,
        use.packages = F,
        dcolumn = T,
        file = "../output/robustness.tex",
        custom.model.names = c("(1) ELF",
                               "(2) PKO",
                               "(3) Cab. Size",
                               "(4) RE",
                               "(5) Region FE",
                               "(6) Country FE"),
        custom.coef.names = ror$ccn,
        omit.coef = ror$oc,
        include.rsquared = F,
        include.cluster = T,
        reorder.coef = unique(ror$rc),
        star.symbol = "\\*",
        include.lr = F, include.variance = F)

# Output replication archive
htmlreg(l = rob_models,
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        table = F,
        booktabs = T,
        use.packages = F,
        dcolumn = T,
        # file = "../output/robustness.tex",
        custom.model.names = c("(1) ELF", 
                               "(2) PKO", 
                               "(3) Cabinet Size", 
                               "(4) Random Effects", 
                               "(5) Region FE", 
                               "(6) Country FE"),
        custom.coef.names = ror$ccn, 
        omit.coef = ror$oc, 
          include.rsquared = F,
        include.cluster = T,
        caption = "", 
        reorder.coef = unique(ror$rc),
        star.symbol = "\\*", 
        include.lr = F, include.variance = F)
(1) ELF (2) PKO (3) Cabinet Size (4) Random Effects (5) Region FE (6) Country FE
PS (cabinet) -0.17+ -0.19+ -0.17+ -0.15 -0.14
(0.10) (0.10) (0.10) (0.18) (0.09)
PS (cabinet) * Aid 0.11*** 0.11*** 0.09** 0.11* 0.06*
(0.03) (0.03) (0.03) (0.04) (0.03)
PS (cabinet share) -0.03
(0.04)
PS (cabinet share) * Aid 0.03*
(0.01)
Aid / GDP (log) -0.02 -0.03 -0.19 -0.03 0.11 0.05
(0.14) (0.15) (0.17) (0.17) (0.22) (0.21)
GDP p/c -0.08 -0.06 -0.01 0.11 -0.14 -0.36
(0.31) (0.32) (0.37) (0.30) (0.31) (0.50)
Population -0.02 -0.02 -0.08 -0.04 0.11 0.66
(0.11) (0.11) (0.14) (0.14) (0.14) (2.88)
Conflict Intensity 0.09 0.05 0.27 0.62 0.18 3.31*
(0.47) (0.44) (0.62) (0.52) (0.50) (1.44)
Non-State Violence -0.45 -0.43 -0.12 -0.51 -0.59 -0.87
(0.52) (0.50) (0.66) (0.48) (0.61) (0.59)
Nat. Res. Rents -0.04* -0.04* -0.05* -0.03* -0.03* 0.02
(0.02) (0.02) (0.02) (0.02) (0.01) (0.02)
Polity 0.82*** 0.82*** 0.76*** 0.71*** 0.67*** 0.46**
(0.07) (0.07) (0.08) (0.09) (0.09) (0.15)
Ethnic Frac. 0.00
(0.79)
UN PKO 0.08
(0.12)
Num. obs. 263 263 204 263 263 263
Countries 44 44 40
Adj. R2 0.76 0.76 0.74 0.64 0.58 0.37
***p < 0.001, **p < 0.01, *p < 0.05, +p < 0.1

Table 5.4: Additional Aid Lags

# Libraries
library(tidyverse)
library(rms)
library(texreg)

# load 
load("./data/diss_df.rda")


# Estimate models with time lags -------------------------------------

# 1 year lag
lag1_pchng <- ols(polity2_t2 ~  
                    cabinetCOUNT * aiddata_AidGDP_ln_tmin1 +
                    log(GDP_per_capita) +
                    log(population) +
                    conf_intens +
                    nonstate + 
                    WBnatres +
                    polity2,
                  data=diss_df, x=T, y=T)
lag1_pchng <- robcov(lag1_pchng, diss_df$GWNo)


lag1_fhchng <- ols(fh_t2 ~  
                     cabinetCOUNT * aiddata_AidGDP_ln_tmin1 +
                     log(GDP_per_capita) +
                     log(population) +
                     conf_intens +
                     nonstate + 
                     WBnatres +
                     fh ,
                   data=diss_df, x=T, y=T)
lag1_fhchng <- robcov(lag1_fhchng, diss_df$GWNo)


# 2 years aid lag
lag2_pchng <- ols(polity2_t2 ~  
                    cabinetCOUNT * aiddata_AidGDP_ln_tmin2 +
                    log(GDP_per_capita) +
                    log(population) +
                    conf_intens +
                    nonstate + 
                    WBnatres +
                    polity2,
                  data=diss_df, x=T, y=T)
lag2_pchng <- robcov(lag2_pchng, diss_df$GWNo)

lag2_fhchng <- ols(fh_t2 ~  
                     cabinetCOUNT * aiddata_AidGDP_ln_tmin2 +
                     log(GDP_per_capita) +
                     log(population) +
                     conf_intens +
                     nonstate + 
                     WBnatres +
                     fh ,
                   data=diss_df, x=T, y=T)
lag2_fhchng <- robcov(lag2_fhchng, diss_df$GWNo)


#### Model Output ####


## Order of coefficients in output table
name_map <- list(cabinetCOUNT = "Power-Sharing (cabinet)",
                 aiddata_AidGDP_ln_tmin1   = "Aid / GDP (log)",
                 aiddata_AidGDP_ln_tmin2   = "Aid / GDP (log)",
                 "cabinetCOUNT * aiddata_AidGDP_ln_tmin1" = "Power-Sharing (cabinet) * Aid", 
                 "cabinetCOUNT * aiddata_AidGDP_ln_tmin2" = "Power-Sharing (cabinet) * Aid", 
                 GDP_per_capita = "GDP p/c",
                 population = "Population",
                 conf_intens = "Conflict Intensity",
                 nonstate = "Non-State Violence",
                 WBnatres = "Nat. Res. Rents",
                 
                 polity2 = "Regime Type (Polity)",
                 fh = "Regime Type (FH)")

source("./functions/will_lowe_texreg_reorder.R")

# Model list
model_list <- list(lag1_pchng,lag2_pchng, lag1_fhchng, lag2_fhchng)

oldnames <- all.varnames.dammit(model_list)
ror <- build.ror(oldnames, name_map)


# 
# # Output for Manuscript
# 
source("./functions/custom_texreg.R")
environment(custom_texreg) <- asNamespace('texreg')

# 
custom_texreg(l = model_list,
       file = "../output/laggedresults2.tex",
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        table = F,
        booktabs = T,
        use.packages = F,
        dcolumn = T,
        custom.model.names = c("\\multicolumn{2}{c}{\\textbf{Polity}} & \\multicolumn{2}{c}{\\textbf{Freedom House}} \\\\ \\cmidrule(r){2-3} \\cmidrule(l){4-5} & \\multicolumn{1}{c}{(1) 1 year}",
                              "\\multicolumn{1}{c}{(2)  2 years}",
                              "\\multicolumn{1}{c}{(3)  1 year}",
                              "\\multicolumn{1}{c}{(4)  2 years}"),
        custom.coef.names = ror$ccn,
        omit.coef = ror$oc,
        reorder.coef = unique(ror$rc),
               custom.multicol = T,
  include.rsquared = F,
        include.cluster = T,
        include.lr = F)

# Output for Replication Archive
htmlreg(l = model_list,
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        table = F,
        booktabs = T,
        use.packages = F,
        caption = "", 
        dcolumn = T,
        custom.coef.names = ror$ccn, 
        omit.coef = ror$oc, 
        reorder.coef = unique(ror$rc),
        star.symbol = "\\*", 
        include.lr = F)
Model 1 Model 2 Model 3 Model 4
Power-Sharing (cabinet) -0.09 -0.05 -0.06** -0.08*
(0.09) (0.11) (0.02) (0.03)
Aid / GDP (log) -0.08 -0.01 -0.06 0.04
(0.15) (0.14) (0.04) (0.04)
Power-Sharing (cabinet) * Aid 0.08* 0.06+ 0.03*** 0.03**
(0.03) (0.03) (0.01) (0.01)
GDP p/c 0.15 0.29 -0.08 0.05
(0.34) (0.34) (0.07) (0.08)
Population -0.15 -0.29* -0.00 -0.00
(0.10) (0.12) (0.04) (0.03)
Conflict Intensity 0.12 -0.06 0.01 0.00
(0.41) (0.42) (0.08) (0.10)
Non-State Violence 0.29 0.33 -0.32** -0.22*
(0.52) (0.44) (0.11) (0.11)
Nat. Res. Rents -0.04+ -0.03 -0.01 -0.00
(0.02) (0.02) (0.00) (0.01)
Regime Type (Polity) 0.84*** 0.86***
(0.07) (0.07)
Regime Type (FH) 0.90*** 0.92***
(0.04) (0.03)
Num. obs. 202 141 209 146
Adj. R2 0.79 0.81 0.83 0.85
***p < 0.001, **p < 0.01, *p < 0.05, +p < 0.1

Table 5.6: 2SLS Second Stage Results

# load libraries
library(AER)
library(ivpack)
library(lmtest)
library(lfe)
library(tikzDevice)

# load data with instrument; this gives "instrument_df" data frame
load(file = "./data/instrumentedAid2.RData")
load("./data/diss_df.rda")

diss_df_iv <- merge(diss_df, 
                      instrument_df, 
                      by = c("iso2c", "year"), all.x = TRUE)


# subset only complete.cases / necessary for cluster.robust.se()
iv_na <- na.omit(diss_df_iv[, c("polity_chng", 
                               "cabinetCOUNT", 
                               "cabinetINC", 
                               "aiddata_Aid",
                               "aiddata_AidGDP_ln",
                               "aiddata_AidPC_ln",
                               "fh",
                               "fh_t2",
                               "GDP_per_capita", 
                               "population", 
                               "conf_intens", 
                               "WBnatres", 
                               "polity2", 
                               "polity2_t2",
                               "total_sum_except", 
                               "year", 
                               "GWNo", 
                               "GDP",
                               "nonstate")])

# to proceed with IV estimation I first hard-code the instrument
iv_na$instr_aid_gdp_ln <- log(iv_na$total_sum_except / iv_na$GDP)

# data transformation for Stata
iv_na$ln_gdp_pc <- log(iv_na$GDP_per_capita)
iv_na$ln_pop <- log(iv_na$population)

# and save data to Stata format
foreign::write.dta(iv_na, "./data/iv_na_democ.dta")

iv_na$cabinetCOUNTxaid_ln <- iv_na$cabinetCOUNT * iv_na$aiddata_AidGDP_ln
iv_na$cabinetCOUNTxaid_ln_instr <- iv_na$cabinetCOUNT * iv_na$instr_aid_gdp_ln

# IV for Polity
democ_pchng_iv <- lfe::felm(polity2_t2 ~ 
                          cabinetCOUNT + 
                          log(GDP_per_capita) +
                          log(population) +
                          nonstate +
                          conf_intens +
                          WBnatres +
                          polity2 
                          | 0 | (cabinetCOUNTxaid_ln|aiddata_AidGDP_ln ~ 
                                   cabinetCOUNTxaid_ln_instr + instr_aid_gdp_ln) | GWNo,
                          data = iv_na)


# IV for FH
democ_fhchng_iv <- lfe::felm(fh_t2 ~ 
                          cabinetCOUNT + 
                          log(GDP_per_capita) +
                          log(population) +
                          nonstate +
                          conf_intens +
                          WBnatres +
                          fh 
                          | 0 | (cabinetCOUNTxaid_ln|aiddata_AidGDP_ln ~ 
                                   cabinetCOUNTxaid_ln_instr + instr_aid_gdp_ln) | GWNo,
                          data = iv_na)

# Output Second Stage Results

## Order of coefficients in output table
name_map <- list(cabinetCOUNT = "Power-Sharing (cabinet)",
                 "`aiddata_AidGDP_ln(fit)`" = "Aid / GDP (log)",
                 "`cabinetCOUNTxaid_ln(fit)`" = "Power-Sharing (cabinet) * Aid", 
                 "log(GDP_per_capita)" = "GDP p/c",
                 "log(population)" = "Population",
                 conf_intens = "Conflict Intensity",
                 nonstate = "Non-State Violence",
                 WBnatres = "Nat. Res. Rents",
                 polity2 = "Regime Type",
                 fh = "Regime Type")

source("./functions/will_lowe_texreg_reorder.R")

# Model list
model_list <- list(democ_pchng_iv, 
                   democ_fhchng_iv)

oldnames <- all.varnames.dammit(model_list)
ror <- build.ror(oldnames, name_map)

# Output for Manuscript

# library(texreg)
# source("./functions/extract_felm_custom.R")
# # # options(expressions = 1500)
# setMethod("extract", signature = className("felm", "lfe"),
#     definition = extract.felm.custom)

source("./functions/custom_texreg.R")
environment(custom_texreg) <- asNamespace('texreg')
# 
# # library(texreg)
# custom_texreg(l = model_list,
#               file = "../output/ivresults_democ.tex",
#         stars = c(0.001, 0.01, 0.05, 0.1),
# 
#         add.lines = list(c("Kleibergen-Paap rk Wald F statistic",
#                            "40.651",
#                            "40.651"),
#                          c("Adj. R$^2$",
#                            round(summary(democ_pchng_iv)$adj.r.squared, 2),
#                            round(summary(democ_fhchng_iv)$adj.r.squared, 2))),
#         symbol = "+",
#         table = F,
#         booktabs = T,
#         use.packages = F,
#         dcolumn = T,
#         custom.model.names = c("(1) Polity",
#                                "(2) Freedom House"),
# 
#         custom.coef.map = name_map,
# 
#         include.lr = F,
#         include.rsquared = F,
#         include.adjrs = F)


# Replication Archive Output
texreg::htmlreg(l = model_list,
        stars = c(0.001, 0.01, 0.05, 0.1),
        symbol = "+",
        table = F,
        booktabs = T,
        use.packages = F,
        caption = "", 
        dcolumn = T,
        custom.model.names = c("(1) Polity", 
                               "(2) Freedom House"),
        # custom.coef.map = name_map,
        custom.coef.names = ror$ccn, 
        omit.coef = ror$oc,
        reorder.coef = unique(ror$rc),
        star.symbol = "\\*", 
        include.lr = F)
(1) Polity (2) Freedom House
Power-Sharing (cabinet) -0.21+ -0.11**
(0.11) (0.04)
Aid / GDP (log) 0.38 0.16**
(0.26) (0.05)
Power-Sharing (cabinet) * Aid 0.12** 0.04**
(0.04) (0.01)
GDP p/c 0.40 0.13
(0.46) (0.09)
Population 0.08 0.04
(0.15) (0.04)
Conflict Intensity -0.25 -0.22+
(0.47) (0.13)
Non-State Violence -0.38 -0.35**
(0.47) (0.11)
Nat. Res. Rents -0.04+ -0.01
(0.02) (0.00)
Regime Type 0.80*** 0.83***
(0.07) (0.04)
Num. obs. 260 260
R2 (full model) 0.76 0.78
R2 (proj model) 0.76 0.78
Adj. R2 (full model) 0.75 0.78
Adj. R2 (proj model) 0.75 0.78
***p < 0.001, **p < 0.01, *p < 0.05, +p < 0.1
LS0tDQp0aXRsZTogIkNoYXB0ZXIgNTogRGVtb2NyYXRpemF0aW9uIFNjb3JlcyINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiAiaGlkZSINCi0tLQ0KIyBGaWd1cmUgNS4xOiAgSWxsdXN0cmF0aXZlIEV4YW1wbGVzOiBQb2xpdGljYWwgRGV2ZWxvcG1lbnQsIFBvd2VyLVNoYXJpbmcgYW5kIEZvcmVpZ24gQWlkIEZsb3dzIGluIHRoZSBEUkMgYW5kIExpYmVyaWENCg0KYGBge3IsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgY2FjaGUgPSBULCBjb21tZW50cyA9IEYsIGZpZy5oZWlnaHQ9IDEwLCBmaWcud2lkdGggPSAxNSwgZGV2ID0gIkNhaXJvUE5HIn0NCg0KIyBMaWJyYXJpZXMNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShjb3VudHJ5Y29kZSkNCmxpYnJhcnkoY293cGxvdCkNCmxpYnJhcnkodGlrekRldmljZSkNCg0KIyBSZWFkIERhdGENCmxvYWQoIi4vZGF0YS9kaXNzX2RmLnJkYSIpDQphaWQgPC0gcmVhZC5kdGEoIi4vZGF0YS9haWRkYXRhX2Z1bGwuZHRhIikNCnVjZHBfY3kgPC0gcmVhZF9jc3YoIi4vZGF0YS8xMzMyODBfb25zZXQyMDEyY3N2LmNzdiIpDQoNCnA0IDwtIGhhdmVuOjpyZWFkX3Nwc3MoIi4vZGF0YS9wNHYyMDEyLnNhdiIpDQpuYW1lcyhwNClbMl0gPC0gIkdXTm8iDQojIFBvbGl0eSBJViB0cmVhdHMgU2VyYmlhIGFzIFl1Z29zbGF2aWEgYXQgc29tZSBwZXJpb2RzLiANCiMgSSBjaGFuZ2UgaXQgYmFjayB0byBTZXJiaWENCnA0W3A0JEdXTm8gPT0gMzQ3ICYgcDQkeWVhciA+IDE5OTEsICJHV05vIl0gPC0gMzQ1DQoNCg0KIyBQcmVwYXJlIFVDRFAgZGF0YQ0KDQojIGxvYWQgdHdvIHNtYWxsIGhlbHBlciBmdW5jdGlvbiB0byBkZXRlcm1pbmUgcHJlLSBhbmQgcG9zdC1jb25mbGljdCB5ZWFycw0KYWdfc2VxIDwtIGZ1bmN0aW9uKHgpIHsNCiAgcnVucyA8LSBjdW1zdW0oYygwLCBkaWZmKHgpICE9IDEgKSkNCiAgcmV0dXJuKHJ1bnMpDQp9DQoNCnNvdXJjZSgiLi9mdW5jdGlvbnMvaWRlbnRpZnlQb3N0Q29uZmxpY3RZZWFycy5SIikNCg0KIyBsb2FkIGFuZCB3cmFuZ2xlIHVjZHAgZGF0YQ0KdWNkcF9jeSA8LSB1Y2RwX2N5ICU+JSANCiAgYXJyYW5nZShnd25vLCB5ZWFyKSAlPiUgDQogIGdyb3VwX2J5KGd3bm8pICU+JSANCiAgbXV0YXRlKGlzbzJjID0gY291bnRyeWNvZGUoZ3dubywgImNvd24iLCAiaXNvMmMiKSwNCiAgICAgICAgIHVjZHBfZHVtbXkgPSBpZmVsc2UoaW5jaWRlbmNldjQxMiA9PSAxLCAxLCAwKSwNCiAgICAgICAgIHBjID0gcGNJZGVudGlmaWVyKHVjZHBfZHVtbXkpLA0KICAgICAgICAgcGMgPSBpZmVsc2UocGMgPT0gMiwgMSwgMCksDQogICAgICAgICBjb25mbGljdF9lcF9pZCA9IGN1bXN1bShjKGlmZWxzZShmaXJzdCh1Y2RwX2R1bW15KSA9PSAxLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmYodWNkcF9kdW1teSkgIT0gMCkpLCANCiAgICAgICAgIGNvbmZsaWN0X2VwX2lkID0gYXMubnVtZXJpYyhpZmVsc2UodWNkcF9kdW1teSA9PSAxLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmxpY3RfZXBfaWQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQSkpLA0KICAgICAgICAgcGVhY2VfZXBfaWQgPSBjdW1zdW0oYyhpZmVsc2UoZmlyc3QocGMpID09IDIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiwgMSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmKHBjKSAhPSAwKSksDQogICAgICAgICBwZWFjZV9lcF9pZCA9IGFzLm51bWVyaWMoaWZlbHNlKHBjID09IDEsIHBlYWNlX2VwX2lkLCBOQSkpKSU+JSANCiAgZ3JvdXBfYnkoZ3dubywgY29uZmxpY3RfZXBfaWQpICU+JSANCiAgbXV0YXRlKGNvbmZsaWN0X3llYXIgPSAtMSAqIHJldihjdW1zdW0odWNkcF9kdW1teSA9PSAxKSkpICU+JSANCiAgZ3JvdXBfYnkoZ3dubywgcGVhY2VfZXBfaWQpICU+JSANCiAgbXV0YXRlKHBlYWNlX3llYXIgPSBjdW1zdW0ocGMgPT0gMSkpICU+JSANCiAgZ3JvdXBfYnkoZ3dubykgJT4lIA0KICBtdXRhdGUoY29uZl9hbmRfcGVhY2VfeWVhcnMgPSBjb25mbGljdF95ZWFyICsgcGVhY2VfeWVhcikNCg0KIyBNZXJnZSBpbiBBaWQgZGF0YQ0KdWNkcF9jeSA8LSBsZWZ0X2pvaW4odWNkcF9jeSwgDQogICAgICAgICAgICAgICAgICAgICBhaWQsIA0KICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCJpc28yYyIgPSAiaXNvMiIsICJ5ZWFyIikpICU+JSANCiAgZmlsdGVyKHllYXIgPj0gMTk4OSkgJT4lIA0KICBkcGx5cjo6cmVuYW1lKHdiX0FpZEdOSSA9IERUX09EQV9PREFUX0dOX1pTLA0KICAgICAgICAgICAgICAgIHdiX0FpZFBDID0gRFRfT0RBX09EQVRfUENfWlMsDQogICAgICAgICAgICAgICAgd2JfQWlkR21lbnRYUCA9IERUX09EQV9PREFUX1hQX1pTLA0KICAgICAgICAgICAgICAgIG9lY2RfQWlkID0gYWlkX29lY2RfY29tbWl0bWVudDIwMTFVU0QsDQogICAgICAgICAgICAgICAgb2VjZF9BaWRfbWlsbCA9IGFpZF9vZWNkX2NvbW1pdG1lbnQyMDExVVNEX21pbGwsDQogICAgICAgICAgICAgICAgYWlkZGF0YV9BaWQgPSBjb21taXRtZW50X2Ftb3VudF91c2RfY29uc3RhbnQpDQoNCg0KIyBQcmVwYXJlIGRhdGEsIGkuZS4gc3Vic2V0IFVDRFAgZGF0YSB3aXRoIG9ubHkgdGhlIGNvdW50cmllcyBpbiBteSBzYW1wbGUgZXRjLg0KdWNkcF9jeV9kaXNzX2RmIDwtIHVjZHBfY3kgJT4lIA0KICBmaWx0ZXIoZ3dubyAlaW4lIHVuaXF1ZShkaXNzX2RmJEdXTm8pKSAlPiUgDQogIGdyb3VwX2J5KHJlY2lwaWVudCkgJT4lIA0KICBtdXRhdGUobWVhbl9haWRfZ2RwID0gbWVhbihhaWRkYXRhX0FpZCAvIEdEUCwgbmEucm0gPSBUKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICAjIG11dGF0ZShvcmRlcmVkX3JlY2lwaWVudF9ieV9haWRtZWFuID0gZmFjdG9yKHJlY2lwaWVudCwgDQogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gcmVjaXBpZW50W29yZGVyKG1lYW5fYWlkX2dkcCwgDQogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2luZyA9IFQpXSkpICU+JSANCiAgbGVmdF9qb2luKC4sIGRpc3NfZGZbLCBjKCJHV05vIiwgInllYXIiLCAiY2FiaW5ldElOQyIsICJjYWJpbmV0Q09VTlQiLCAic2VuaW9yQ09VTlQiLCAibm9uc2VuaW9yQ09VTlQiKV0sDQogICAgICAgICAgICBieSA9IGMoImd3bm8iID0gIkdXTm8iLCAieWVhciIpKSAlPiUgDQogIGxlZnRfam9pbiguLCBwNFssIGMoIkdXTm8iLCAieWVhciIsICJwb2xpdHkyIildLCBieSA9IGMoImd3bm8iID0gIkdXTm8iLCAieWVhciIpKSAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTApDQoNCg0KDQojIGRlZmluZSBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyBpbGx1c3RyYXRpdmUgY291bnRyeSBwbG90cyANCnBsb3RfY291bnRyeV9leGFtcGxlIDwtIGZ1bmN0aW9uKGNvdW50cnksIHllYXJfbWluLCB5ZWFyX21heCkgew0KDQogIA0KIyBBaWQgUGxvdA0KY250cnlfaWxsdXN0cmF0aW9uX3Bsb3QgPC0gdWNkcF9jeV9kaXNzX2RmICU+JSANCiAgZmlsdGVyKHJlY2lwaWVudCA9PSBjb3VudHJ5ICYgeWVhciA+PSB5ZWFyX21pbiAmIHllYXIgPD0geWVhcl9tYXgpICU+JSANCiAgZ2dwbG90KC4sIGFlcyh4ID0geWVhciwgeSA9IGFpZGRhdGFfQWlkIC8gR0RQICogMTAwKSkgKw0KDQogICMgQWRkIGNvbmZsaWN0IHllYXJzIHRvIGFpZCBwbG90DQogIGdlb21fYmFyKGRhdGEgPSB1Y2RwX2N5X2Rpc3NfZGYgJT4lIGZpbHRlcihpbmNpZGVuY2V2NDEyID09IDEgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2lwaWVudCA9PSBjb3VudHJ5ICYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyID49IHllYXJfbWluICYgeWVhciA8PSB5ZWFyX21heCksDQogICAgICAgICAgIGFlcyh4ID0geWVhciwgeSA9IEluZiksDQogICAgICAgICAgIGZpbGwgPSAiI2RlMmQyNiIsIA0KICAgICAgICAgICBhbHBoYSA9IDAuMiwgc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwNCiAgICAgICAgICAgcG9zaXRpb24gPSAiZG9kZ2UiLCANCiAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCANCiAgICAgICAgICAgZmlsbCA9ICIjOTY5Njk2Iiwgd2lkdGggPSAxKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSB5ZWFyX21pbjp5ZWFyX21heCkgKw0KICBsYWJzKHggPSAiIiwgeSA9ICJBaWQgLyBHRFAiKQ0KDQojIFBvbGl0eSBQbG90DQpjbnRyeV9pbGx1c3RyYXRpb25fcG9saXR5IDwtIHVjZHBfY3lfZGlzc19kZiAlPiUgDQogIGZpbHRlcihyZWNpcGllbnQgPT0gY291bnRyeSAmIHllYXIgPj0geWVhcl9taW4gJiB5ZWFyIDw9IHllYXJfbWF4KSAlPiUgDQogIGdncGxvdCguLCBhZXMoeCA9IHllYXIsIHkgPSBwb2xpdHkyKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSAid2hpdGUiLCB3aWR0aCA9IDEpICsNCiAgDQogICMgQWRkIGNvbmZsaWN0IHllYXJzIHRvIHBvbGl0eSBwbG90DQogIGdlb21fYmFyKGRhdGEgPSB1Y2RwX2N5X2Rpc3NfZGYgJT4lIGZpbHRlcihpbmNpZGVuY2V2NDEyID09IDEgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2lwaWVudCA9PSBjb3VudHJ5ICYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyID49IHllYXJfbWluICYgeWVhciA8PSB5ZWFyX21heCksDQogICAgICAgICAgIGFlcyh4ID0geWVhciwgeSA9IEluZiksDQogICAgICAgICAgIGZpbGwgPSAiI2RlMmQyNiIsIGFscGhhID0gMC4yLCBzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxKSArDQoNCiAgZ2VvbV9wb2ludCgpICsgZ2VvbV9saW5lKCkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHllYXJfbWluOnllYXJfbWF4KSArDQogIGxhYnMoeCA9ICIiLCB5ID0gIlBvbGl0eSAyIikNCg0KIyBQb3dlci1TaGFyaW5nIFBsb3QNCmNudHJ5X2lsbHVzdHJhdGlvbl9wcyA8LSB1Y2RwX2N5X2Rpc3NfZGYgJT4lIA0KICBmaWx0ZXIocmVjaXBpZW50ID09IGNvdW50cnkgJiB5ZWFyID49IHllYXJfbWluICYgeWVhciA8PSB5ZWFyX21heCkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KHllYXIsIHNlbmlvckNPVU5ULCBub25zZW5pb3JDT1VOVCkgJT4lIA0KICBnYXRoZXIoa2V5LCB2YWx1ZSwgLXllYXIpICU+JSANCiAgbXV0YXRlKHZhbHVlID0gaWZlbHNlKGlzLm5hKHZhbHVlKSwgMCwgdmFsdWUpKSAlPiUgDQogIGdncGxvdCguLCBhZXMoeCA9IHllYXIsIHkgPSAgdmFsdWUsIGZpbGwgPSBmYWN0b3Ioa2V5KSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIA0KICAgICAgICAgICBwb3NpdGlvbiA9ICJzdGFjayIsIGNvbG9yID0gImJsYWNrIiwgd2lkdGggPSAxKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKCIiLCANCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiI2JkYzllMSIsICIjMDQ1YThkIiksDQogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk5vbnNlbmlvciByZWJlbCBzZWF0cyIsICJTZW5pb3IgcmViZWwgc2VhdHMiKSkgKyANCiAgDQogICMgQWRkIGNvbmZsaWN0IHllYXJzIHRvIHBzIHBsb3QNCiAgZ2VvbV9iYXIoZGF0YSA9IHVjZHBfY3lfZGlzc19kZiAlPiUgZmlsdGVyKGluY2lkZW5jZXY0MTIgPT0gMSAmDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjaXBpZW50ID09IGNvdW50cnkgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIgPj0geWVhcl9taW4gJiB5ZWFyIDw9IHllYXJfbWF4KSwNCiAgICAgICAgICAgYWVzKHggPSB5ZWFyLCB5ID0gSW5mKSwNCiAgICAgICAgICAgZmlsbCA9ICIjZGUyZDI2IiwgYWxwaGEgPSAwLjIsIHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHllYXJfbWluOnllYXJfbWF4KSArDQogIGxhYnMoeCA9ICIiLCB5ID0gIk51bWJlciBvZiBSZWJlbCBTZWF0cyBcbiBpbiBQb3dlci1TaGFyaW5nIFxuR292ZXJubWVudCIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiKQ0KDQojIGNvbWJpbmUgcGxvdCBvdXRwdXQNCmNvd3Bsb3Q6OnBsb3RfZ3JpZChjbnRyeV9pbGx1c3RyYXRpb25fcGxvdCwgDQogICAgICAgICAgICAgICAgICAgY250cnlfaWxsdXN0cmF0aW9uX3BvbGl0eSwgDQogICAgICAgICAgICAgICAgICAgY250cnlfaWxsdXN0cmF0aW9uX3BzLA0KICAgICAgICAgICAgICAgICAgIG5yb3cgPSAzLCANCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJ2IiApDQoNCn0NCg0KIyANCiMgIyBPdXRwdXQgZm9yIG1hbnVzY3JpcHQNCiMgIyBMaWJlcmlhDQojIG9wdGlvbnMoIHRpa3pEb2N1bWVudERlY2xhcmF0aW9uID0gIlxcZG9jdW1lbnRjbGFzc1sxNXB0XXthcnRpY2xlfSIgKQ0KIyB0aWt6KCIuLi9maWd1cmVzL0xpYmVyaWFfaWxsdS50ZXgiLCBoZWlnaHQgPSA3LCB3aWR0aCA9IDUsIHBvaW50c2l6ZSA9IDcpDQojIHBsb3RfY291bnRyeV9leGFtcGxlKCJMaWJlcmlhIiwgMjAwMCwgMjAxMCkNCiMgZGV2Lm9mZigpDQojIA0KIyAjIERSQw0KIyBvcHRpb25zKCB0aWt6RG9jdW1lbnREZWNsYXJhdGlvbiA9ICJcXGRvY3VtZW50Y2xhc3NbMTVwdF17YXJ0aWNsZX0iICkNCiMgdGlreigiLi4vZmlndXJlcy9EUkNfaWxsdS50ZXgiLCBoZWlnaHQgPSA3LCB3aWR0aCA9IDUsIHBvaW50c2l6ZSA9IDcpDQojIHBsb3RfY291bnRyeV9leGFtcGxlKCJDb25nbywgRGVtLiBSZXAuIiwgMjAwMCwgMjAxMCkNCiMgZGV2Lm9mZigpDQoNCiMgT3V0cHV0IGZvciBSZXBsaWNhdGlvbiBBcmNoaXZlDQpwbG90X2dyaWQocGxvdF9jb3VudHJ5X2V4YW1wbGUoIkxpYmVyaWEiLCAyMDAwLCAyMDEwKSwgDQogICAgICAgICAgcGxvdF9jb3VudHJ5X2V4YW1wbGUoIkNvbmdvLCBEZW0uIFJlcC4iLCAyMDAwLCAyMDEwKSwgDQogICAgICAgICAgbmNvbCA9IDIsIA0KICAgICAgICAgIGxhYmVscyA9IGMoIkxpYmVyaWEiLCAiRFJDIiksIA0KICAgICAgICAgIHZqdXN0ID0gLTUsDQogICAgICAgICAgaGp1c3QgPSAtNywNCiAgICAgICAgICBzY2FsZSA9IDAuOSkNCg0KDQoNCmBgYA0KDQoNCg0KDQojIEZpZ3VyZSA1LjI6IEZvcmVpZ24gQWlkIGFuZCBQb2xpdHkgU2NvcmVzIGluIENvdW50cnktWWVhcnMgV2l0aCBhbmQgV2l0aG91dCBQb3dlci1TaGFyaW5nIEdvdmVybm1lbnRzDQoNCg0KYGBge3IsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgY2FjaGUgPSBULCBmaWcuaGVpZ2h0ID0gMy41LCBjb21tZW50cyA9IEYsIGRldiA9ICJDYWlyb1BORyJ9DQoNCiMgTGlicmFyaWVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkodGlrekRldmljZSkNCg0KIyBMb2FkIERhdGENCmxvYWQoIi4vZGF0YS9kaXNzX2RmLnJkYSIpDQoNCiMgTGFiZWxzIGZvciBlYXNpZXIgcGxvdHRpbmcNCmRpc3NfZGYkY2FiaW5ldElOQ2xhYmVsIDwtIGlmZWxzZShkaXNzX2RmJGNhYmluZXRJTkMgPT0gMSwgIlBvd2VyLVNoYXJpbmciLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBcblBvd2VyLVNoYXJpbmciKQ0KDQojIGdlbmVyYXRlIHNjYXR0ZXJwbG90LCBkaXZpZGVkIGJ5IHBvd2VyLXNoYXJpbmcNCmFpZHBzX2RlbW9jX3Bsb3QgPC0gZ2dwbG90KGRpc3NfZGYsIGFlcyh4ID0gbG9nKGFpZGRhdGFfQWlkR0RQKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwb2xpdHkyX3QyKSkgICsNCiAgZ2VvbV9wb2ludChzaXplID0gMS43LCBhbHBoYSA9IDAuNSkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArDQogICMgZ2VvbV9ydWcoKSArDQogIHRoZW1lX2J3KCkgKw0KICBsYWJzKHggPSAiQWlkIC8gR0RQIChsb2cpIiwgeSA9ICJQb2xpdHkgc2NvcmUgYXQgdDIiKSArDQogIGZhY2V0X3dyYXAoIH4gY2FiaW5ldElOQ2xhYmVsKSANCg0KIyBvdXRwdXQgcGxvdCBmb3IgbWFudXNjcmlwdA0KIyBvcHRpb25zKHRpa3pEb2N1bWVudERlY2xhcmF0aW9uID0gIlxcZG9jdW1lbnRjbGFzc1sxMXB0XXthcnRpY2xlfSIgKQ0KIyB0aWt6KCIuLi9maWd1cmVzL2FpZHBzX2RlbW9jX3Bsb3QudGV4IiwgaGVpZ2h0ID0gMy41KQ0KIyBwcmludChhaWRwc19kZW1vY19wbG90KQ0KIyBkZXYub2ZmKCkNCg0KIyBvdXRwdXQgZm9yIHJlcGxpY2F0aW9uIGFyY2hpdmUNCnByaW50KGFpZHBzX2RlbW9jX3Bsb3QpDQoNCg0KYGBgDQoNCjwhLS0gKk5vdGU6KiBJbmRpdmlkdWFsIGRhdGEgcG9pbnRzIHJlcHJlc2VudCBjb3VudHJ5LXllYXJzLiBMb3cgdmFsdWVzIG9uIHRoZSB5LWF4aXMgaW5kaWNhdGUgbW9yZSBhdXRvY3JhdGljIFBvbGl0eSAyIHNjb3JlczsgcG9zaXRpdmUgdmFsdWVzIGluZGljYXRlIG1vcmUgZGVtb2NyYXRpYyBQb2xpdHkgMiBzY29yZXMuIC0tPg0KDQoNCiMgRmlndXJlIDUuMzogVGVtcG9yYWwgRHluYW1pY3Mgb2YgdGhlIEludGVyYWN0aXZlIEVmZmVjdCBiZXR3ZWVuIFBvd2VyLVNoYXJpbmcgYW5kIEZvcmVpZ24gQWlkDQpgYGB7ciwgZmlnLmFsaWduID0gImNlbnRlciIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRiwgd2lkdGggPSA5LCBoZWlnaHQgPSA3LCBkZXYgPSAiQ2Fpcm9QTkcifQ0KDQojIExpYnJhcmllcw0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGNvd3Bsb3QpDQpsaWJyYXJ5KGxmZSkNCmxpYnJhcnkodGlrekRldmljZSkNCg0KIyBEYXRhDQpsb2FkKCIuL2RhdGEvZGlzc19kZi5yZGEiKQ0KDQojIFByZXBhcmUgZGF0YSBmcmFtZSBmb3IgbXVsdGlwbGUgcGxvdHMNCnBvbGl0eV92YXJzIDwtIGxpc3QoDQogIHBvbGl0eTJfdDEgPSBkaXNzX2RmLA0KICBwb2xpdHkyX3QyID0gZGlzc19kZiwgDQogIHBvbGl0eTJfdDMgPSBkaXNzX2RmLCANCiAgcG9saXR5Ml90NCA9IGRpc3NfZGYsIA0KICBwb2xpdHkyX3Q1ID0gZGlzc19kZiwgDQogIGZoX3QxID0gZGlzc19kZiwNCiAgZmhfdDIgPSBkaXNzX2RmLCANCiAgZmhfdDMgPSBkaXNzX2RmLCANCiAgZmhfdDQgPSBkaXNzX2RmLCANCiAgZmhfdDUgPSBkaXNzX2RmDQopDQoNCiMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCBsaXN0IGNvbHVtbg0KcG9saXR5X3ZhcnMgPC0gZW5mcmFtZShwb2xpdHlfdmFycykNCg0KIyBkZWZpbmUgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gZXZlcnkgZGF0YSBmcmFtZSBpbiB0aGUgbGlzdCBjb2x1bW4NCm1haW5fbW9kZWwgPC0gZnVuY3Rpb24obGVhZF90eXBlLCBkYXRhKSB7DQogIGRhdGEgPC0gYXMuZGF0YS5mcmFtZShkYXRhKQ0KICBkYXRhJGxlYWRfdmFyIDwtIGRhdGFbLCBncmVwKGxlYWRfdHlwZSwgbmFtZXMoZGF0YSksIHZhbHVlID1UKV0NCiAgDQogIGlmKGdyZXBsKCJmaCIsIGxlYWRfdHlwZSkpIHsNCiAgICAgIG1vZGVsIDwtIGxmZTo6ZmVsbShsZWFkX3ZhciB+DQogICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqDQogICAgICAgICAgICAgICAgICAgICAgIGFpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsNCiAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKw0KICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgICAgIGZoIHwgMCB8IDAgfCBHV05vLA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGEpDQogICAgcmV0dXJuKG1vZGVsKQ0KICB9IGVsc2Ugew0KICAgIG1vZGVsIDwtIGxmZTo6ZmVsbShsZWFkX3ZhciB+DQogICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqDQogICAgICAgICAgICAgICAgICAgICAgIGFpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsNCiAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKw0KICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgfCAwIHwgMCB8IEdXTm8sDQogICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YSkNCiAgICByZXR1cm4obW9kZWwpDQogIH0NCn0NCg0KDQojIGZpdCBtb2RlbHMgJiBwb3N0LXByb2Nlc3MgZGF0YSBmb3IgcGxvdHRpbmcNCm1vZGVsX2FsbCA8LSBwb2xpdHlfdmFycyAlPiUgDQogIG11dGF0ZShtb2RlbCA9IG1hcDIobmFtZSwgdmFsdWUsIH4gbWFpbl9tb2RlbCgueCwgLnkpKSkgDQoNCm1vZGVsX291dCA8LSBtb2RlbF9hbGwgJT4lIA0KICBtdXRhdGUoY29lZiA9IG1hcChtb2RlbCwgYnJvb206OnRpZHkpKSAlPiUgDQogIHVubmVzdChjb2VmKSAlPiUgDQogICMga2VlcCBvbmx5IGludGVyYWN0aW9uIHRlcm0gY29lZnMNCiAgZmlsdGVyKHRlcm0gPT0gImNhYmluZXRDT1VOVDphaWRkYXRhX0FpZEdEUF9sbiIpICU+JSANCiAgbXV0YXRlKGRlbV9zY29yZSA9IGlmZWxzZShncmVwbCgicG9saXR5IiwgbmFtZSksICJQb2xpdHkiLCAiRnJlZWRvbSBIb3VzZSIpKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoZGVtX3Njb3JlLCBuYW1lLCBlc3RpbWF0ZSwgc3RkLmVycm9yKSAlPiUgDQogIGdyb3VwX2J5KGRlbV9zY29yZSkgJT4lIA0KICBtdXRhdGUobmFtZSA9IDE6NSkNCg0KdGVtcF9keW5fZGVtb2MgPC0gbW9kZWxfb3V0DQpzYXZlKHRlbXBfZHluX2RlbW9jLCBmaWxlID0gIi4vZGF0YS90ZW1wX2R5bl9kZW1vYy5yZGEiKQ0KDQp0ZW1wX2R5bmFtaWNzX3Bsb3QgPC0gZ2dwbG90KG1vZGVsX291dCwgDQogICAgICAgYWVzKHggPSBuYW1lLCANCiAgICAgICAgICAgeSA9IGVzdGltYXRlLCANCiAgICAgICAgICAgZ3JvdXAgPSBkZW1fc2NvcmUsIGNvbG9yID0gZGVtX3Njb3JlKSkgKw0KICBnZW9tX3BvaW50KCBzaXplID0gMS43LCANCiAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLjUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gZXN0aW1hdGUgLSAxLjY3ICogc3RkLmVycm9yLCANCiAgICAgICAgICAgICAgICAgICAgeW1heCA9IGVzdGltYXRlICsgMS42NyAqIHN0ZC5lcnJvciksIA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMCwgDQogICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC41KSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgZmFjZXRfd3JhcCh+ZGVtX3Njb3JlLCBucm93ID0gMiwgc2NhbGVzID0gImZyZWVfeSIpICsgDQogIHNjYWxlX2NvbG9yX2JyZXdlcigiIixwYWxldHRlID0gIlNldDEiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgbGFicyh4ID0gIlllYXIgYWZ0ZXIgdDAiLCB5ID0gIkVzdGltYXRlIG9mIEludGVyYWN0aW9uIENvZWZmaWNpZW50IFxuIGJldHdlZW4gUG93ZXItU2hhcmluZyAoY2FiaW5ldClcbiBhbmQgQWlkL0dEUCAobG9nKSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQojIE91dHB1dCBmb3IgbWFudXNjcmlwdA0KIyBvcHRpb25zKHRpa3pEb2N1bWVudERlY2xhcmF0aW9uID0gIlxcZG9jdW1lbnRjbGFzc1sxMXB0XXthcnRpY2xlfSIgKQ0KIyB0aWt6KCIuLi9maWd1cmVzL3RlbXBfZHluYW1pY3NfcGxvdC50ZXgiLCBoZWlnaHQgPSAzLjUpDQojIHByaW50KHRlbXBfZHluYW1pY3NfcGxvdCkNCiMgZGV2Lm9mZigpDQoNCiMgT3V0cHV0IGZvciByZXBsaWNhdGlvbiBhcmNoaXZlDQpwcmludCh0ZW1wX2R5bmFtaWNzX3Bsb3QpDQoNCmBgYA0KDQo8IS0tICpOb3RlOiogVGhlIHBsb3Qgc2hvd3MgdGhlIGNvZWZmaWNpZW50IGZvciB0aGUgaW50ZXJhY3Rpb24gdGVybSBiZXR3ZWVuIFBvd2VyLVNoYXJpbmcgKGJpbmFyeSkgYW5kIEFpZC9HRFAgZm9yIGRpZmZlcmVudCBhbm51YWwgbGVhZHMgb2YgdGhlIGRlcGVuZGVudCB2YXJpYWJsZS4gVGhlIHgtYXhpcyBzaG93cyB0aGUgeWVhciBhZnRlciB0IDAgKGFzIGEgcmVmZXJlbmNlLCB0aGUgY29lZmZpY2llbnQgZm9yIHRoZSB5ZWFyIDIgaXMgdGhlIG9uZSByZXBvcnRlZCBpbiBUYWJsZSAxLjIpOyB0aGUgeS1heGlzIGRlcGljdHMgY29lZmZpY2llbnQgc2l6ZSB3aXRoIDkwJSBjb25maWRlbmNlIGludGVydmFscy4gVGhlIGZ1bGwgbW9kZWwgcmVzdWx0cyBmb3IgdGhpcyBwbG90IGFyZSByZXBvcnRlZCBpbiB0aGUgQXBwZW5kaXggLS0+DQoNCiMgRmlndXJlIDUuNDogTWFyZ2luYWwgRWZmZWN0cyBvZiBQb3dlci1TaGFyaW5nIGFuZCBGb3JlaWduIEFpZCBvbiBQb3N0LUNvbmZsaWN0IERlbW9jcmF0aXphdGlvbg0KDQpgYGB7ciwgZmlnLmFsaWduID0gImNlbnRlciIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRiwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodD0zLjUsICBkZXYgPSAiQ2Fpcm9QTkcifQ0KDQojIExpYnJhcmllcw0KbGlicmFyeShncmlkRXh0cmEpDQpsaWJyYXJ5KENhaXJvKQ0KbGlicmFyeSh0aWt6RGV2aWNlKQ0KbGlicmFyeShyZXNoYXBlKQ0KDQoNCiMgUG9saXR5IERWICsgY2FiaW5lSU5DDQptb2RlbF9wb2xpdHlfY2FiaW5jIDwtIG9scyhwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldElOQyAqIA0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgeD1ULCB5PVQpDQptb2RlbF9wb2xpdHlfY2FiaW5jIDwtIHJvYmNvdihtb2RlbF9wb2xpdHlfY2FiaW5jLCBkaXNzX2RmJEdXTm8pDQoNCiMgUG9saXR5IERWICsgY2FiQ09VTlQNCm1vZGVsX3BvbGl0eV9jYWJjb3VudCA8LSBvbHMocG9saXR5Ml90MiB+ICANCiAgICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqIA0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgeD1ULCB5PVQpDQptb2RlbF9wb2xpdHlfY2FiY291bnQgPC0gcm9iY292KG1vZGVsX3BvbGl0eV9jYWJjb3VudCwgZGlzc19kZiRHV05vKQ0KDQoNCiMgc291cmNlIGludGVyYWN0aW9uIHBsb3QgZnVuY3Rpb24gdG8gcGxvdCBtYXJnaW5hbCBlZmZlY3RzDQpzb3VyY2UoIi4vZnVuY3Rpb25zLy9pbnRlcmFjdGlvbl9wbG90cy5SIikNCg0KIyBPdXRwdXQgZm9yIG1hbnVzY3JpcHQNCiMgb3B0aW9ucyggdGlrekRvY3VtZW50RGVjbGFyYXRpb24gPSAiXFxkb2N1bWVudGNsYXNzWzExcHRde2FydGljbGV9IiApDQojIHRpa3ooIi4uL2ZpZ3VyZXMvaW50ZXJhY3Rpb24udGV4IiwgaGVpZ2h0ID0gMy41KQ0KIyANCiMgIyBPdXRwdXQgZm9yIHJlcGxpY2F0aW9uIGFyY2hpdmUNCiMgcGFyKG1mcm93PWMoMSwzKSwNCiMgICAgIG1hciA9IGMoNSwgNywgNCwgMC41KSwNCiMgICAgIGNleC5sYWIgPSAxLjMsDQojICAgICBjZXguYXhpcyA9IDEuMywNCiMgICAgIG1ncCA9IGMoMy41LCAxLCAwKSkNCiMgDQojIGludGVyYWN0aW9uX3Bsb3RfY29udGludW91cyhtb2RlbF9wb2xpdHlfY2FiY291bnQsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhYmluZXRDT1VOVCIsICJhaWRkYXRhX0FpZEdEUF9sbiIsICJjYWJpbmV0Q09VTlQgKiBhaWRkYXRhX0FpZEdEUF9sbiIsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiIiwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiID0gIk1hcmdpbmFsIGVmZmVjdCBvZiBQb3dlci1TaGFyaW5nIChjYWJpbmV0KSBcbiBvbiBwb2xpdGljYWwgZGV2ZWxvcG1lbnQiLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiYSkgQWlkIC8gR0RQIChMb2cpXG4iLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmYgPSAuOTApDQojIGludGVyYWN0aW9uX3Bsb3RfY29udGludW91cyhtb2RlbF9wb2xpdHlfY2FiY291bnQsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFpZGRhdGFfQWlkR0RQX2xuIiwgImNhYmluZXRDT1VOVCIsICJjYWJpbmV0Q09VTlQgKiBhaWRkYXRhX0FpZEdEUF9sbiIsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiIiwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiID0gIk1hcmdpbmFsIGVmZmVjdCBvZiBBaWRcbiBvbiBwb2xpdGljYWwgZGV2ZWxvcG1lbnQiLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICJiKSBQb3dlci1TaGFyaW5nIFxuKE51bWJlciBvZiByZWJlbCBzZWF0cykiLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZiA9IC45MCkNCiMgaW50ZXJhY3Rpb25fcGxvdF9iaW5hcnkobW9kZWxfcG9saXR5X2NhYmluYywgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFpZGRhdGFfQWlkR0RQX2xuIiwiY2FiaW5ldElOQyIsICJjYWJpbmV0SU5DICogYWlkZGF0YV9BaWRHRFBfbG4iLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIiIsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYiA9ICJNYXJnaW5hbCBlZmZlY3Qgb2YgQWlkXG4gb24gcG9saXRpY2FsIGRldmVsb3BtZW50IiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiYykgUG93ZXItU2hhcmluZyBcbigxID0gWWVzLCAwID0gTm8pIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmYgPSAuOTApDQojIGRldi5vZmYoKQ0KDQojIE91dHB1dCBmb3IgcmVwbGljYXRpb24gYXJjaGl2ZQ0KcGFyKG1mcm93PWMoMSwzKSwNCiAgICBtYXIgPSBjKDUsIDcsIDQsIDAuNSksDQogICAgY2V4LmxhYiA9IDEuMywNCiAgICBjZXguYXhpcyA9IDEuMywNCiAgICBtZ3AgPSBjKDMuNSwgMSwgMCkpDQoNCmludGVyYWN0aW9uX3Bsb3RfY29udGludW91cyhtb2RlbF9wb2xpdHlfY2FiY291bnQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYWJpbmV0Q09VTlQiLCAiYWlkZGF0YV9BaWRHRFBfbG4iLCAiY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG4iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiID0gIk1hcmdpbmFsIGVmZmVjdCBvZiBQb3dlci1TaGFyaW5nIChjYWJpbmV0KSBcbiBvbiBwb2xpdGljYWwgZGV2ZWxvcG1lbnQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gImEpIEFpZCAvIEdEUCAoTG9nKVxuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZiA9IC45MCkNCmludGVyYWN0aW9uX3Bsb3RfY29udGludW91cyhtb2RlbF9wb2xpdHlfY2FiY291bnQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhaWRkYXRhX0FpZEdEUF9sbiIsICJjYWJpbmV0Q09VTlQiLCAiY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG4iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiID0gIk1hcmdpbmFsIGVmZmVjdCBvZiBBaWRcbiBvbiBwb2xpdGljYWwgZGV2ZWxvcG1lbnQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiYikgUG93ZXItU2hhcmluZyBcbihOdW1iZXIgb2YgcmViZWwgc2VhdHMpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mID0gLjkwKQ0KaW50ZXJhY3Rpb25fcGxvdF9iaW5hcnkobW9kZWxfcG9saXR5X2NhYmluYywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhaWRkYXRhX0FpZEdEUF9sbiIsImNhYmluZXRJTkMiLCAiY2FiaW5ldElOQyAqIGFpZGRhdGFfQWlkR0RQX2xuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYiA9ICJNYXJnaW5hbCBlZmZlY3Qgb2YgQWlkXG4gb24gcG9saXRpY2FsIGRldmVsb3BtZW50IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gImMpIFBvd2VyLVNoYXJpbmcgXG4oMSA9IFllcywgMCA9IE5vKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZiA9IC45MCkNCg0KYGBgDQoNCg0KPCEtLSAqTm90ZToqICBNYXJnaW5hbCBlZmZlY3QgY2FsY3VsYXRpb25zIGJhc2VkIG9uIE1vZGVsIDIgaW4gVGFibGUgNS4yLiBEYXNoZWQgbGluZXMgaW5kaWNhdGUgOTAlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBUaGUgdW5kZXJseWluZyBoaXN0b2dyYW0gZGVwaWN0cyB0aGUgZGlzdHJpYnV0aW9uIG9mIG9ic2VydmF0aW9ucyBpbiB0aGUgc2FtcGxlIG9uIHRoZSB2YXJpYWJsZSBvbiB0aGUgeC1heGlzLiAgLS0+DQoNCg0KIyBGaWd1cmUgNS41OiBNb2RlbCBQcmVkaWN0aW9ucyBmb3IgdGhlIEVmZmVjdCBvZiBQb3dlci1TaGFyaW5nIGFuZCBGb3JlaWduIEFpZCBvbiBQb3N0LUNvbmZsaWN0IERlbW9jcmF0aXphdGlvbg0KDQpgYGB7ciwgZmlnLmFsaWduID0gImNlbnRlciIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRiwgZmlnLndpZHRoID0gNi41LCBmaWcuaGVpZ2h0ID0gNC41LCBkZXYgPSAiQ2Fpcm9QTkcifQ0KDQojIExpYnJhcmllcw0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJtcykNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeSh0aWt6RGV2aWNlKQ0KDQojIExvYWQgZGF0YQ0KbG9hZCgiZGF0YS9kaXNzX2RmLnJkYSIpDQoNCiMgdG8gcHJlZGljdCBzdWJzdGFudGl2ZSBlZmZlY3RzIGZyb20gdGhpcyBtb2RlbCwgd2UgbmVlZCB0byBkZWZpbmUgZGF0YSANCiMgZGlzdHJpYnV0aW9uDQpkaXNzX2RmJGNvbmZsaWN0SUQgPC0gTlVMTA0KZGF0YWRpc3RfZGlzc19kZiA8LSBkYXRhZGlzdChkaXNzX2RmKTsgb3B0aW9ucyhkYXRhZGlzdD0nZGF0YWRpc3RfZGlzc19kZicpDQoNCiMgcmVwbGljYXRlIE1vZGVsIGZyb20gYWJvdmUgUG9saXR5IERWICsgY2FiQ09VTlQNCm1vZGVsX3BvbGl0eV9jYWJjb3VudCA8LSBvbHMocG9saXR5Ml90MiB+ICANCiAgICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqIA0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG5fZ2RwX3BjICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgcG9saXR5MiAsDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmLCB4PVQsIHk9VCkNCm1vZGVsX3BvbGl0eV9jYWJjb3VudCA8LSByb2Jjb3YobW9kZWxfcG9saXR5X2NhYmNvdW50LCBkaXNzX2RmJEdXTm8pDQoNCiMgU3RhcnQgcHJlZGljdGlvbnMgZm9yIGFpZA0KcHJlZGljdGlvbl9kZW1vY19haWQgPC0gUHJlZGljdChtb2RlbF9wb2xpdHlfY2FiY291bnQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldENPVU5UID0gYygwLCAxMCksICMgbm8gLyBtdWNoIHBvd2VyLXNoYXJpbmcNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFpZGRhdGFfQWlkR0RQX2xuID0gc2VxKC01LjcsIDUuMTcsIDAuMSksIyByYW5nZSBvZiBhaWQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgPSAyLjYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mLmludCA9IDAuOSkgDQoNCnN1YnNfZWZmZWN0c19wY2huZ19haWQgPC0gZ2dwbG90KGRhdGEuZnJhbWUocHJlZGljdGlvbl9kZW1vY19haWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gZXhwKGFpZGRhdGFfQWlkR0RQX2xuKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHloYXQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gYXMuZmFjdG9yKGNhYmluZXRDT1VOVCkpKSArIA0KICBnZW9tX2xpbmUoIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEpICsgDQogIGdlb21fcmliYm9uKGFlcyh5bWF4ID0gdXBwZXIsIA0KICAgICAgICAgICAgICAgICAgeW1pbiA9IGxvd2VyLCANCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBhcy5mYWN0b3IoY2FiaW5ldENPVU5UKSksIA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuNykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjYjNjZGUzIiwgIiNlNDFhMWMiKSwgDQogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiTnVtYmVyIG9mIFJlYmVscyBcbmluIHRoZSBQb3dlci1TaGFyaW5nIENvYWxpdGlvbjoiKSArDQogIHRoZW1lX2J3KCkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9OCkpICsNCiAgbGFicyh4ID0gIkFpZCAvIEdEUCIsIA0KICAgICAgIHkgPSAiUHJlZGljdGVkIFBvbGl0eSBTY29yZXMiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSANCg0KIyBQcmVkaWN0aW9ucyBwb3dlci1zaGFyaW5nDQpwcmVkaWN0aW9uX2RlbW9jX3BzIDwtIFByZWRpY3QobW9kZWxfcG9saXR5X2NhYmNvdW50LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCA9IHNlcSgwLCAxMCwgMSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gPSBjKDAsIDMuNCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkyID0gMi42LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZi5pbnQgPSAwLjkpDQoNCnByZWRpY3Rpb25fZGVtb2NfcHMkYWlkZGF0YV9BaWRHRFBfbG4gPC0gcm91bmQoZXhwKHByZWRpY3Rpb25fZGVtb2NfcHMkYWlkZGF0YV9BaWRHRFBfbG4pKQ0KDQoNCnN1YnNfZWZmZWN0c19wY2huZ19wcyA8LSBnZ3Bsb3QoZGF0YS5mcmFtZShwcmVkaWN0aW9uX2RlbW9jX3BzKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBjYWJpbmV0Q09VTlQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0geWhhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gYXMuZmFjdG9yKGFpZGRhdGFfQWlkR0RQX2xuKSkpICsgDQogIGdlb21fbGluZSggY29sb3IgPSAiYmxhY2siLCBzaXplID0gMSkgKyANCiAgZ2VvbV9yaWJib24oYWVzKHltYXggPSB1cHBlciwgDQogICAgICAgICAgICAgICAgICB5bWluID0gbG93ZXIsIA0KICAgICAgICAgICAgICAgICAgZmlsbCA9IGFzLmZhY3RvcihhaWRkYXRhX0FpZEdEUF9sbikpLCANCiAgICAgICAgICAgICAgYWxwaGEgPSAwLjcpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2IzY2RlMyIsICIjZTQxYTFjIiksIA0KICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkFpZCBpbiBwZXIgY2VudCBvZiBHRFA6IikgKw0KICB0aGVtZV9idygpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMCwgMikpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTgpKSArDQogIGxhYnMoeCA9ICJQb3dlci1TaGFyaW5nIChOby4gb2YgcmViZWwgc2VhdHMgaW4gZ292ZXJubWVudCkiLCANCiAgICAgICB5ID0gIlByZWRpY3RlZCBQb2xpdHkgU2NvcmVzIikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgDQoNCiMgb3V0cHV0IHByZWRpY3Rpb24gcGxvdHMNCg0KDQojIG91dHB1dCBwbG90IGZvciBwcmVkaWN0ZWQgVkRFTSBlbGVjdGlvbiBxdWFsaXR5IHZhcmlhYmxlcyANCg0KIA0KIyBvcHRpb25zKCB0aWt6RG9jdW1lbnREZWNsYXJhdGlvbiA9ICJcXGRvY3VtZW50Y2xhc3NbMTFwdF17YXJ0aWNsZX0iICkNCiMgdGlreigiLi4vZmlndXJlcy9haWRwc19wY2huZy50ZXgiLCBoZWlnaHQgPSA0LjUsIHdpZHRoID0gNi41KQ0KIyBncmlkLmFycmFuZ2Uoc3Vic19lZmZlY3RzX3BjaG5nX3BzLA0KIyAgICAgICAgICAgICAgc3Vic19lZmZlY3RzX3BjaG5nX2FpZCwNCiMgICAgICAgICAgICAgIG5yb3cgPSAxKQ0KIyBkZXYub2ZmKCkNCg0KZ3JpZC5hcnJhbmdlKHN1YnNfZWZmZWN0c19wY2huZ19wcywgDQogICAgICAgICAgICAgc3Vic19lZmZlY3RzX3BjaG5nX2FpZCwgDQogICAgICAgICAgICAgbnJvdyA9IDEpDQoNCmBgYA0KDQoNCjwhLS0gKk5vdGU6KiBNYXJnaW5hbCBlZmZlY3RzIHNpbXVsYXRlZCB3aXRoIGFsbCBvdGhlciB2YXJpYWJsZXMgaGVsZCBhdCB0aGVpciBtZWFuL21lZGlhbiwgYmFzZWQgb24gTW9kZWwgMiBpbiBUYWJsZSAxLjIuIFRoZSBkZXBlbmRlbnQgdmFyaWFibGUgUG9saXR5IDIgYXQgdCAyIC4gVGhlIHNoYWRlZCBhcmVhcyByZXByZXNlbnQgOTAlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyb3VuZCBwcmVkaWN0ZWQgZWZmZWN0cy4gQWxsIHNpbXVsYXRpb25zIHdlcmUgY29uZHVjdGVkIHdpdGggRnJhbmsgSGFycmVsbOKAmXMgcm1zIHBhY2thZ2UgZm9yIFIgKEhhcnJlbGwgMjAxNCkuIC0tPg0KDQo8IS0tIExlZnQgUGFuZWw6IFRoZSBibHVlIChsaWdodCBncmV5KSBsaW5lIHJlcHJlc2VudHMgdGhlIHNpbXVsYXRlZCBlZmZlY3QgZm9yIGFuIGFpZCBsZXZlbCBvZiAxJSBvZiB0aGUgcmVjaXBpZW504oCZcyBHRFA7IHRoZSByZWQgbGluZSAoZGFyayBncmV5KSBmb3IgYW4gYWlkIGxldmVsIG9mIDMwJSBvZiByZWNpcGllbnQgR0RQLiAtLT4NCg0KPCEtLSBSaWdodCBQYW5lbDogVGhlIGJsdWUgKGxpZ2h0IGdyZXkpIGxpbmUgcmVwcmVzZW50cyB0aGUgc2ltdWxhdGVkIGVmZmVjdCBvZiBubyByZWJlbCBzZWF0cyBpbiB0aGUgcG9zdC1jb25mbGljdCBnb3Zlcm5tZW50IGFuZCByZWQgKGRhcmsgZ3JleSkgc2ltdWxhdGVzIHRoZSBlZmZlY3Qgb2YgMTAgcmViZWwgc2VhdHMuIFRoZSB4LWF4aXMgcmVwcmVzZW50cyB0aGUgYWN0dWFsLCBub3QgdGhlIGxvZ2dlZCB2YWx1ZSBvZiBmb3JlaWduIGFpZCAvIEdEUC4gLS0+DQoNCiMgRmlndXJlIDUuNjogTWVjaGFuaXNtczogVmFyaWF0aW9uIGluIFR5cGVzIG9mIFBvd2VyLVNoYXJpbmcgYW5kIEFpZA0KDQpgYGB7ciwgZmlnLmFsaWduID0gImNlbnRlciIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRiwgZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDQsIGRldiA9ICJDYWlyb1BORyJ9DQoNCiMgTGlicmFyaWVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocm1zKQ0KbGlicmFyeShwbG0pDQpsaWJyYXJ5KGxmZSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh0aWt6RGV2aWNlKQ0KDQojIExvYWQgZGF0YQ0KbG9hZCgiLi9kYXRhL2Rpc3NfZGYucmRhIikNCg0KIyBFc3RpbWF0ZSBNb2RlbHMNCm1vZGVsX3BvbGl0eV9jYWJpbmMgPC0gZmVsbShwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldElOQyAqIA0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgfCAwIHwgMCB8IEdXTm8sDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmKQ0KDQojIFBvbGl0eSBEViArIHNlbmlvcklOQw0KbW9kZWxfcG9saXR5X3NlbmlvciA8LSBsZmU6OmZlbG0ocG9saXR5Ml90MiB+ICANCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmlvcklOQyAqIA0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgfCAwIHwgMCB8IEdXTm8gLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZikNCg0KIyBQb2xpdHkgRFYgKyBub25zZW5pb3JJTkMNCm1vZGVsX3BvbGl0eV9ub25zZW5pb3IgPC0gZmVsbShwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc2VuaW9ySU5DICogDQogICAgICAgICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbiArDQogICAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgcG9saXR5MiB8IDAgfCAwIHwgR1dObywNCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRpc3NfZGYpDQoNCiMgREdBICogUFMNCm1vZGVsX3BvbGl0eV9jYWJpbmNfZGdhIDwtIGZlbG0ocG9saXR5Ml90MiB+ICANCiAgICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRJTkMgKiBsb2coZGdhX2dkcF96ZXJvICsgMSkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgfCAwIHwgMCB8IEdXTm8sDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmKQ0KDQptb2RlbF9wb2xpdHlfY2FiaW5jX3Byb2dyYW1haWQgPC0gZmVsbShwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldElOQyAqIGxvZyhwcm9ncmFtX2FpZF9nZHBfemVybyArIDEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGFpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhHRFBfcGVyX2NhcGl0YSkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG5fcG9wICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsNCiAgICAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsgDQogICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkyIHwgMCB8IDAgfCBHV05vLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZikNCg0KbW9kZWxfcG9saXR5X2NhYmluY19idWRnZXQgPC0gZmVsbShwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldElOQyAqIGxvZyhjb21tb2RpdHlfYWlkX2dkcF96ZXJvICsgMSkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgfCAwIHwgMCB8IEdXTm8sDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmKQ0KDQptZWNoYW5pc21fbW9kZWxzIDwtIGxpc3QoIkNhYmluZXQgUFMgKEJhc2VsaW5lKSIgPSBtb2RlbF9wb2xpdHlfY2FiaW5jLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAiU2VuaW9yIFBTIiA9IG1vZGVsX3BvbGl0eV9zZW5pb3IsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICJOb25zZW5pb3IgUFMiID0gbW9kZWxfcG9saXR5X25vbnNlbmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIkRHQSIgPSBtb2RlbF9wb2xpdHlfY2FiaW5jX2RnYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIlByb2dyYW0gQWlkIj0gbW9kZWxfcG9saXR5X2NhYmluY19wcm9ncmFtYWlkLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAiQnVkZ2V0IEFpZCIgPSBtb2RlbF9wb2xpdHlfY2FiaW5jX2J1ZGdldCkgJT4lIA0KICBlbmZyYW1lKCkgJT4lIA0KICBtdXRhdGUodGlkeW1vZGVsID0gbWFwKHZhbHVlLCBicm9vbTo6dGlkeSkpICU+JSANCiAgdW5uZXN0KHRpZHltb2RlbCkgJT4lIA0KICBmaWx0ZXIoZ3JlcGwoIjoiLCB0ZXJtKSkgJT4lIA0KICBtdXRhdGUobmFtZSA9IGZvcmNhdHM6OmZjdF9yZWxldmVsKG5hbWUsIGMoIkNhYmluZXQgUFMgKEJhc2VsaW5lKSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VuaW9yIFBTIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb25zZW5pb3IgUFMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRHQSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJvZ3JhbSBBaWQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJ1ZGdldCBBaWQiKSkpDQptZWNoYW5pc21fbW9kZWxzX2RlbW9jIDwtIG1lY2hhbmlzbV9tb2RlbHMNCnNhdmUobWVjaGFuaXNtX21vZGVsc19kZW1vYywgZmlsZT0gIi4vZGF0YS9tZWNoYW5pc21fbW9kZWxzX2RlbW9jLnJkYSIpDQoNCm1lY2hhbmltc19kZW1vY19tb2RlbHNfcGxvdCA8LSBnZ3Bsb3QobWVjaGFuaXNtX21vZGVscywgYWVzKHggPSBuYW1lLCB5ID0gZXN0aW1hdGUpICkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gZXN0aW1hdGUgLSAxLjY3ICogc3RkLmVycm9yLCANCiAgICAgICAgICAgICAgICAgICAgeW1heCA9IGVzdGltYXRlICsgMS42NyAqIHN0ZC5lcnJvciksIA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMCkgKw0KICB0aGVtZV9idygpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogIGxhYnMoeCA9ICIiLCB5ID0gIkNvZWZmaWNpZW50IEVzdGltYXRlIG9mIEludGVyYWN0aW9uIGJldHdlZW4gXG4gRGlmZmVyZW50IFR5cGVzIG9mIFBvd2VyLVNoYXJpbmcgKGJpbmFyeSkgXG4gYW5kIERpZmZlcmVudCBBaWQgVHlwZXMiKQ0KDQojIE91dHB1dCBmb3IgbWFudXNjcmlwdA0KIyBvcHRpb25zKHRpa3pEb2N1bWVudERlY2xhcmF0aW9uID0gIlxcZG9jdW1lbnRjbGFzc1sxMXB0XXthcnRpY2xlfSIgKQ0KIyB0aWt6KCIuLi9maWd1cmVzL21lY2hhbmltc19kZW1vY19tb2RlbHNfcGxvdC50ZXgiLCBoZWlnaHQgPSAyLjc1KQ0KIyBwcmludChtZWNoYW5pbXNfZGVtb2NfbW9kZWxzX3Bsb3QpDQojIGRldi5vZmYoKQ0KDQojIE91dHB1dCBmb3IgcmVwbGljYXRpb24gYXJjaGl2ZQ0KcHJpbnQobWVjaGFuaW1zX2RlbW9jX21vZGVsc19wbG90KQ0KDQpgYGAgDQoNCjwhLS0gKk5vdGU6KiBDb2VmZmljaWVudHMgZm9yIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGRpZmZlcmVudCB0eXBlcyBvZiBwb3dlci1zaGFyaW5nIGFuZCBhaWQuIFJlZmVyZW5jZSBtb2RlbCBpcyBNb2RlbCAxIGluIFRhYmxlIDUuMi4gOTAlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiAtLT4NCg0KIyBGaWd1cmUgNS43ICYgVGFibGUgQi41OiBDb3ZhcmlhdGUgQmFsYW5jZSBCZWZvcmUgYW5kIEFmdGVyIE1hdGNoaW5nDQoNCmBgYHtyLCByZXN1bHRzPSJhc2lzIiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGNhY2hlID0gVCwgY29tbWVudHMgPSBGLCBmaWcuYWxpZ249ImNlbnRlciIsIGRldiA9ICJDYWlyb1BORyJ9DQojIExpYnJhcmllcw0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoTWF0Y2hJdCkNCmxpYnJhcnkodGV4cmVnKQ0KbGlicmFyeShybXMpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShnZ3JlcGVsKSAjIG5lZWRlZCBmb3IgdmFyaWFibGUgbGFiZWxzDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpa3pEZXZpY2UpDQpsaWJyYXJ5KHh0YWJsZSkNCg0KIyBMb2FkIGRhdGEgDQpsb2FkKCIuL2RhdGEvZGlzc19kZi5yZGEiKQ0KDQojIHNlbGVjdCByZWxldmFudCB2YXJpYWJsZXMNCm1hdGNoX2RlbW9jX2RhdGEgPC0gZGlzc19kZiAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoY2FiaW5ldElOQywgY2FiaW5ldENPVU5ULCBzZW5pb3JJTkMsDQogICAgICAgICAgICAgICAgc2VuaW9yQ09VTlQsIG5vbnNlbmlvcklOQywgbm9uc2VuaW9yQ09VTlQsDQogICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFAsIHBvcHVsYXRpb24sIG5vbnN0YXRlLA0KICAgICAgICAgICAgICAgIFdCbmF0cmVzLCBmaCwgR0RQX3Blcl9jYXBpdGEsIGNvbmZfaW50ZW5zLA0KICAgICAgICAgICAgICAgIGFpZGRhdGFfQWlkR0RQX2xuLCANCiAgICAgICAgICAgICAgICBHV05vLCB5ZWFyLCANCiAgICAgICAgICAgICAgICAgcG9saXR5MiwgcG9saXR5Ml90MiwgIyBjaGVjayANCiAgICAgICAgICAgICAgICBmaCwgZmhfdDIsIA0KICAgICAgICAgICAgICAgIHBjX3BlcmlvZCwgTG9jYXRpb24sIGxuX3BvcCwgbG5fZ2RwX3BjKQ0KDQojIGtlZXAgb25seSBjb21wbGV0ZSBjYXNlcyAobmVjZXNzYXJ5IGZvciBtYXRjaGluZykNCm1hdGNoX2RlbW9jX2RhdGEgPC0gbWF0Y2hfZGVtb2NfZGF0YVtjb21wbGV0ZS5jYXNlcyhtYXRjaF9kZW1vY19kYXRhKSwgXQ0KDQojIGdlbmVyYXRlIHByZXRyZWF0bWVudCBjb250cm9sczogY29udHJvbCB2YXJpYWJsZXMgaW4gZmlyc3QgcG9zdC1jb25mbGljdCB5ZWFyDQptYXRjaF9kZW1vY19kYXRhIDwtIG1hdGNoX2RlbW9jX2RhdGEgJT4lIA0KICBhcnJhbmdlKEdXTm8sIHBjX3BlcmlvZCwgeWVhcikgJT4lIA0KICBncm91cF9ieShHV05vLCBwY19wZXJpb2QpICU+JSANCiAgbXV0YXRlKG1hdGNoX2FpZGRhdGFfQWlkR0RQX2xuID0gZmlyc3QoYWlkZGF0YV9BaWRHRFBfbG4pLA0KICAgICAgICAgbWF0Y2hfcG9wID0gZmlyc3QocG9wdWxhdGlvbiksDQogICAgICAgICBtYXRjaF9nZHAgPSBmaXJzdChHRFBfcGVyX2NhcGl0YSksDQogICAgICAgICBtYXRjaF9ub25zdGF0ZSA9IGZpcnN0KG5vbnN0YXRlKSwNCiAgICAgICAgIG1hdGNoX1dCbmF0cmVzID0gZmlyc3QoV0JuYXRyZXMpLA0KICAgICAgICAgbWF0Y2hfcG9saXR5ID0gZmlyc3QocG9saXR5MiksIA0KICAgICAgICAgbWF0Y2hfZmggPSBmaXJzdChmaCkpDQoNCiMgZXhwbGljaXRseSBjb252ZXJ0IHRvIGRhdGEgZnJhbWUNCm1hdGNoX2RlbW9jX2RhdGEgPC0gYXMuZGF0YS5mcmFtZShtYXRjaF9kZW1vY19kYXRhKQ0KDQojIDEuMSBQZXJmb3JtIG1hdGNoaW5nIGFsZ29yaXRobSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0Kc2V0LnNlZWQoMTIzKQ0KbWF0Y2hfZGVtb2NfcmVzIDwtIG1hdGNoaXQoY2FiaW5ldElOQyB+DQogICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoX2FpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKG1hdGNoX2dkcCkgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cobWF0Y2hfcG9wKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsgIyBjb25mX2ludGVucyBpcyBhbHJlYWR5IHByZS10cmVhdG1lbnQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hfbm9uc3RhdGUgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cobWF0Y2hfV0JuYXRyZXMgKyAxKSAgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaF9wb2xpdHksDQogICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAibmVhcmVzdCIsDQogICAgICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZSA9ICJtYWhhbGFub2JpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICByYXRpbyA9IDIsDQogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gbWF0Y2hfZGVtb2NfZGF0YSkNCg0KIyBleHRyYWN0IGRhdGENCm1hdGNoX2RlbW9jX2RmIDwtIG1hdGNoLmRhdGEobWF0Y2hfZGVtb2NfcmVzKQ0KDQojIEJhbGFuY2UgSW1wcm92ZW1lbnQgUGxvdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KYmFsYW5jZV9pbXByb3ZlbWVudCA8LSBzdW1tYXJ5KG1hdGNoX2RlbW9jX3JlcykkcmVkdWN0aW9uDQpyb3cubmFtZXMoYmFsYW5jZV9pbXByb3ZlbWVudCkgPC0gYygiQWlkIC8gR0RQIChsb2cpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR0RQIC8gUEMgKGxvZykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcHVsYXRpb24gKGxvZykiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25mbGljdCBJbnRlbnNpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbnN0YXRlIENvbmZsaWN0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOYXQuIFJlcy4gUmVudHMgKGxvZykiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWdpbWUgVHlwZSAoUG9saXR5KSIpDQoNCmJhbGFuY2VfaW1wcm92ZW1lbnQgPC0gZGF0YS5mcmFtZSh2YXJpYWJsZSA9IHJvdy5uYW1lcyhiYWxhbmNlX2ltcHJvdmVtZW50KSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyY2VudF9iYWxhbmNlX2ltcHJvdmVtZW50ID0gcm91bmQoYmFsYW5jZV9pbXByb3ZlbWVudFssIDFdLCAyKSkNCg0KDQpwbG90X2JhbGFuY2VpbXByIDwtIGRhdGEuZnJhbWUoYEFsbCBEYXRhYCA9IGFicyhzdW1tYXJ5KG1hdGNoX2RlbW9jX3JlcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YW5kYXJkaXplID0gVCkkc3VtLmFsbCRgU3RkLiBNZWFuIERpZmYuYCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBNYXRjaGVkIERhdGFgID0gYWJzKHN1bW1hcnkobWF0Y2hfZGVtb2NfcmVzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YW5kYXJkaXplID0gVCkkc3VtLm1hdGNoZWQkYFN0ZC4gTWVhbiBEaWZmLmApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdiA9IGJhbGFuY2VfaW1wcm92ZW1lbnQkdmFyaWFibGUpICU+JSANCiAgZ2F0aGVyKGtleSwgdmFsdWUsIC1jb3YpICU+JSANCiAgZmlsdGVyKCFpcy5uYW4odmFsdWUpICYgIWlzLmluZmluaXRlKHZhbHVlKSkgJT4lIA0KICBtdXRhdGUoa2V5ID0gZ3N1YigiXFwuIiwgIiAiLCBrZXkpKQ0KDQojIFBsb3QgYmFsYW5jZSBpbXByb3ZlbWVudA0KcGxvdF9iYWxhbmNlaW1wcl9vdXQgPC0gcGxvdF9iYWxhbmNlaW1wciAlPiUgDQogIGdncGxvdCguLCBhZXMoeCA9IGtleSwgeSA9IHZhbHVlKSkgKyANCiAgZ2VvbV9wb2ludChzaXplID0gMi41KSArIA0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gY292KSwNCiAgICAgICAgICAgIGxpbmVtaXRyZSA9IDIsIHNpemUgPSAwLjYpICsgDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMjUsIGFlcyhncm91cCA9IGtleSkpICsNCiAgZ2VvbV9sYWJlbF9yZXBlbChkYXRhID0gcGxvdF9iYWxhbmNlaW1wciAlPiUgZmlsdGVyKGtleSA9PSAiQWxsIERhdGEiKSwNCiAgICAgICAgICAgICAgICAgICBhZXMobGFiZWwgPSBjb3YpLA0KICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAtLjMpICsNCiAgdGhlbWVfYncoKSArDQogIGxhYnMoIHggPSAiIiwgeSA9ICJBYnNvbHV0ZSBTdGFuZGFyZGl6ZWQgRGlmZmVyZW5jZSBpbiBNZWFucyIpDQoNCiMgb3V0cHV0IGJhbGFuY2UgaW1wcm92ZW1lbnQgcGxvdA0KIyBvcHRpb25zKCB0aWt6RG9jdW1lbnREZWNsYXJhdGlvbiA9ICJcXGRvY3VtZW50Y2xhc3NbMTFwdF17YXJ0aWNsZX0iICkNCiMgdGlreigiLi4vZmlndXJlcy9tYXRjaF9kZW1vY19iYWxhbmNlaW1wci50ZXgiLCBoZWlnaHQgPSA1KQ0KIyBwcmludChwbG90X2JhbGFuY2VpbXByX291dCkNCiMgZGV2Lm9mZigpDQoNCiMgT3V0cHV0IGZvciByZXBsaWNhdGlvbiBhcmNoaXZlDQpwcmludChwbG90X2JhbGFuY2VpbXByX291dCkNCg0KDQojIyMjIEVzdGltYXRlIE1vZGVscyBvbiBNYXRjaGVkIFNhbXBsZSAjIyMjIw0KDQptb2RlbF9kZW1vY19tYXRjaGVkIDwtIG9scyhwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0SU5DICoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKHBvcHVsYXRpb24pICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkyDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPW1hdGNoX2RlbW9jX2RmICwgeD1ULCB5PVQpDQptb2RlbF9kZW1vY19tYXRjaGVkIDwtIHJtczo6cm9iY292KG1vZGVsX2RlbW9jX21hdGNoZWQsIG1hdGNoX2RlbW9jX2RmJEdXTm8pDQoNCm1vZGVsX2RlbW9jX21hdGNoZWRfZmggPC0gb2xzKGZoX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0SU5DICoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKHBvcHVsYXRpb24pICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkyICAgICAgICAgICAgICAgICAgICAgICAgICAgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPW1hdGNoX2RlbW9jX2RmICwgeD1ULCB5PVQpDQptb2RlbF9kZW1vY19tYXRjaGVkX2ZoIDwtIHJtczo6cm9iY292KG1vZGVsX2RlbW9jX21hdGNoZWRfZmgsIG1hdGNoX2RlbW9jX2RmJEdXTm8pDQoNCiMjIE9yZGVyIG9mIGNvZWZmaWNpZW50cyBpbiBvdXRwdXQgdGFibGUNCm5hbWVfbWFwIDwtIGxpc3QoY2FiaW5ldElOQyA9ICJQb3dlci1TaGFyaW5nIChiaW5hcnkpIiwNCiAgICAgICAgICAgICAgICAgImNhYmluZXRJTkMgKiBhaWRkYXRhX0FpZEdEUF9sbiIgPSAiUG93ZXItU2hhcmluZyAoYmluYXJ5KSAqIEFpZCIsIA0KICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbiA9ICJBaWQgLyBHRFAgKGxvZykiLA0KICAgICAgICAgICAgICAgICBHRFBfcGVyX2NhcGl0YSA9ICJHRFAgcC9jIiwNCiAgICAgICAgICAgICAgICAgcG9wdWxhdGlvbiA9ICJQb3B1bGF0aW9uIiwNCiAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgPSAiQ29uZmxpY3QgSW50ZW5zaXR5IiwNCiAgICAgICAgICAgICAgICAgbm9uc3RhdGUgPSAiTm9uLVN0YXRlIFZpb2xlbmNlIiwNCiAgICAgICAgICAgICAgICAgV0JuYXRyZXMgPSAiTmF0LiBSZXMuIFJlbnRzIiwNCiAgICAgICAgICAgICAgICAgcG9saXR5MiA9ICJSZWdpbWUgVHlwZSIpDQoNCnNvdXJjZSgiLi9mdW5jdGlvbnMvd2lsbF9sb3dlX3RleHJlZ19yZW9yZGVyLlIiKQ0KDQojIE1vZGVsIGxpc3QNCm1vZGVsX2xpc3QgPC0gbGlzdChtb2RlbF9kZW1vY19tYXRjaGVkLCBtb2RlbF9kZW1vY19tYXRjaGVkX2ZoKQ0KDQpvbGRuYW1lcyA8LSBhbGwudmFybmFtZXMuZGFtbWl0KG1vZGVsX2xpc3QpDQpyb3IgPC0gYnVpbGQucm9yKG9sZG5hbWVzLCBuYW1lX21hcCkNCg0KIyBPdXRwdXQgZm9yIHJlcGxpY2F0aW9uIGFyY2hpdmUNCiMgdGV4cmVnKGwgPSBtb2RlbF9saXN0LA0KIyAgICAgICAgIHN0YXJzID0gYygwLjAwMSwgMC4wMSwgMC4wNSwgMC4xKSwNCiMgICAgICAgICBzeW1ib2wgPSAiKyIsDQojICAgICAgICAgdGFibGUgPSBGLA0KIyAgICAgICAgIGJvb2t0YWJzID0gVCwNCiMgICAgICAgICB1c2UucGFja2FnZXMgPSBGLA0KIyAgICAgICAgIGRjb2x1bW4gPSBULA0KIyAgICAgICAgIGZpbGUgPSAiLi4vb3V0cHV0L2RlbW9jX21hdGNoaW5nX3Jlc3VsdHMudGV4IiwNCiMgICAgICAgICBjdXN0b20ubW9kZWwubmFtZXMgPSBjKCIoMSkgUG9saXR5IiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMikgRnJlZWRvbSBIb3VzZSIpLA0KIyAgICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gcm9yJGNjbiwNCiMgICAgICAgICBvbWl0LmNvZWYgPSByb3Ikb2MsDQojICAgICAgICAgcmVvcmRlci5jb2VmID0gdW5pcXVlKHJvciRyYyksDQojICAgICAgICAgaW5jbHVkZS5sciA9IEYpDQoNCiMgT3V0cHV0IGZvciByZXBsaWNhdGlvbiBhcmNoaXZlDQpodG1scmVnKGwgPSBtb2RlbF9saXN0LA0KICAgICAgICBzdGFycyA9IGMoMC4wMDEsIDAuMDEsIDAuMDUsIDAuMSksDQogICAgICAgIHN5bWJvbCA9ICIrIiwNCiAgICAgICAgY2FwdGlvbiA9ICIiLCANCiAgICAgICAgdGFibGUgPSBGLA0KICAgICAgICBib29rdGFicyA9IFQsDQogICAgICAgIHVzZS5wYWNrYWdlcyA9IEYsDQogICAgICAgIGRjb2x1bW4gPSBULA0KICAgICAgICBjdXN0b20ubW9kZWwubmFtZXMgPSBjKCIoMSkgUG9saXR5IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigyKSBGcmVlZG9tIEhvdXNlIiksDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gcm9yJGNjbiwgDQogICAgICAgIG9taXQuY29lZiA9IHJvciRvYywgDQogICAgICAgIHJlb3JkZXIuY29lZiA9IHVuaXF1ZShyb3IkcmMpLA0KICAgICAgICBzdGFyLnN5bWJvbCA9ICJcXCoiLCANCiAgICAgICAgaW5jbHVkZS5sciA9IEYpDQoNCmBgYA0KDQoNCg0KDQojIEZpZ3VyZSA1Ljg6IFRoZSBUaGUgUmVsYXRpb25zaGlwIGJldHdlZW4gRm9yZWlnbiBBaWQgYW5kIEFpZCAoSW5zdHJ1bWVudGVkKSANCmBgYHtyLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGNhY2hlID0gVCwgY29tbWVudHMgPSBGLCB3aWR0aCA9IDksIGhlaWdodCA9IDcsIGRldiA9ICJDYWlyb1BORyJ9DQoNCg0KIyBsb2FkIGxpYnJhcmllcw0KbGlicmFyeShBRVIpDQpsaWJyYXJ5KGl2cGFjaykNCmxpYnJhcnkobG10ZXN0KQ0KbGlicmFyeSh0aWt6RGV2aWNlKQ0KDQoNCiMgbG9hZCBkYXRhIHdpdGggaW5zdHJ1bWVudDsgdGhpcyBnaXZlcyAiaW5zdHJ1bWVudF9kZiIgZGF0YSBmcmFtZQ0KbG9hZChmaWxlID0gIi4vZGF0YS9pbnN0cnVtZW50ZWRBaWQyLlJEYXRhIikNCmxvYWQoIi4vZGF0YS9kaXNzX2RmLnJkYSIpDQoNCmRpc3NfZGZfaXYgPC0gbWVyZ2UoZGlzc19kZiwgDQogICAgICAgICAgICAgICAgICAgICAgaW5zdHJ1bWVudF9kZiwgDQogICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCJpc28yYyIsICJ5ZWFyIiksIGFsbC54ID0gVFJVRSkNCg0KDQojIHN1YnNldCBvbmx5IGNvbXBsZXRlLmNhc2VzIC8gbmVjZXNzYXJ5IGZvciBjbHVzdGVyLnJvYnVzdC5zZSgpDQppdl9uYSA8LSBuYS5vbWl0KGRpc3NfZGZfaXZbLCBjKCJwb2xpdHlfY2huZyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYWJpbmV0Q09VTlQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FiaW5ldElOQyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhaWRkYXRhX0FpZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFpZGRhdGFfQWlkR0RQX2xuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWlkZGF0YV9BaWRQQ19sbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZoIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmhfY2huZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdEUF9wZXJfY2FwaXRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvcHVsYXRpb24iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29uZl9pbnRlbnMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV0JuYXRyZXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9saXR5MiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb2xpdHkyX3QyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG90YWxfc3VtX2V4Y2VwdCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ5ZWFyIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdXTm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR0RQIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9uc3RhdGUiKV0pDQoNCg0KIyAzLjEgUGxvdCBaX2l0IGFnYWluc3QgYWlkIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnBsb3RfZGVtb2NfYWlkX2l2IDwtIGdncGxvdChpdl9uYSwgYWVzKHggPSBsb2codG90YWxfc3VtX2V4Y2VwdCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGxvZyhhaWRkYXRhX0FpZCkpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAzKSArIA0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArDQogIHRoZW1lX2J3KCkgKyANCiAgbGFicyh4ID0gIkFpZCAoaW5zdHJ1bWVudGVkKSBMb2ciLA0KICAgICAgIHkgPSAiQWlkIChBaWREYXRhKSBMb2cgIikNCg0KDQojIE91dHB1dCBNYW51c2NyaXB0DQojIG9wdGlvbnMoIHRpa3pEb2N1bWVudERlY2xhcmF0aW9uID0gIlxcZG9jdW1lbnRjbGFzc1sxMHB0XXthcnRpY2xlfSIgKQ0KIyB0aWt6KCIuLi9maWd1cmVzL2FpZF9pbnN0cl9kZW1vYy50ZXgiLCBoZWlnaHQgPSA0KQ0KIyBwcmludChwbG90X2RlbW9jX2FpZF9pdikNCiMgZGV2Lm9mZigpDQoNCiMgT3V0cHV0IFJlcGxpY2F0aW9uIEFyY2hpdmUNCnByaW50KHBsb3RfZGVtb2NfYWlkX2l2KQ0KDQoNCmBgYA0KDQo8IS0tICpOb3RlOiogRWFjaCBkYXRhIHBvaW50IHJlcHJlc2VudHMgb25lIGNvdW50cnkteWVhci4gVGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gYm90aCB2YXJpYWJsZXMgaXMgz4EgPSAwLjczLCAoIHAgPCAwLjAwMSApLCByZXByZXNlbnRlZCBieSB0aGUgYmx1ZSByZWdyZXNzaW9uIGxpbmUuIFRoZSBncmV5IGFyZWEgcmVwcmVzZW50cyBhIDk1JSBjb25maWRlbmNlIGJhbmQgYXJvdW5kIHRoZSByZWdyZXNzaW9uIGxpbmUgIC0tPg0KDQojIFRhYmxlIDUuMTogSW5kaXZpZHVhbCBFZmZlY3RzIG9mIFBvd2VyLVNoYXJpbmcgYW5kIEZvcmVpZ24gQWlkIG9uIFBvc3QtQ29uZmxpY3QgUG9saXRpY2FsIERldmVsb3BtZW50DQoNCmBgYHtyLCByZXN1bHRzPSJhc2lzIiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGNhY2hlID0gVCwgY29tbWVudHMgPSBGfQ0KDQojIExpYnJhcmllcw0KbGlicmFyeSh0ZXhyZWcpDQpsaWJyYXJ5KHJtcykNCg0KIyBMb2FkIGRhdGENCmxvYWQoIi4vZGF0YS9kaXNzX2RmLnJkYSIpDQoNCiMgc3BlY2lmeSB2ZWN0b3Igd2l0aCBjb250cm9sIHZhcnMNCmNvbnRyb2x2YXJzIDwtIGMoImxvZyhhaWRkYXRhX0FpZEdEUCkiLA0KICAgICAgICAgICAgICAgICAibG9nKEdEUF9wZXJfY2FwaXRhKSIsDQogICAgICAgICAgICAgICAgICJsbl9wb3AiLA0KICAgICAgICAgICAgICAgICAiY29uZl9pbnRlbnMiLCANCiAgICAgICAgICAgICAgICAgIm5vbnN0YXRlIiwNCiAgICAgICAgICAgICAgICAgIldCbmF0cmVzIiwNCiAgICAgICAgICAgICAgICAgInBvbGl0eTIiKQ0KIyMjIyBQb3dlci1TaGFyaW5nIG9ubHkgTW9kZWxzICMjIyMNCg0KIyBQUyBvbmx5ICsgY2FiaW5ldENPVU5UDQptb2RlbF9wcyA8LSBvbHMoZm9ybXVsYShwYXN0ZTAoInBvbGl0eTJfdDIgfiBjYWJpbmV0Q09VTlQgKyAiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoY29udHJvbHZhcnMsIGNvbGxhcHNlID0gIiArICIpKSksDQogICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NfZGYsIHggPSBULCB5ID0gVCkNCm1vZGVsX3BzIDwtIHJvYmNvdihtb2RlbF9wcywgZGlzc19kZiRHV05vKQ0KDQojIFBTIG9ubHkgKyBzZW5pb3JDT1VOVA0KbW9kZWxfc2VuaW9yQ09VTlQgPC0gb2xzKGZvcm11bGEocGFzdGUwKCJwb2xpdHkyX3QyIH4gc2VuaW9yQ09VTlQgKyAiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoY29udHJvbHZhcnMsIGNvbGxhcHNlID0gIiArICIpKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NfZGYsIHggPSBULCB5ID0gVCkNCm1vZGVsX3NlbmlvckNPVU5UIDwtIHJvYmNvdihtb2RlbF9zZW5pb3JDT1VOVCwgZGlzc19kZiRHV05vKQ0KDQojIFBTIG9ubHkgKyBub25zZW5pb3JDT1VOVA0KbW9kZWxfbm9uc2VuaW9yQ09VTlQgPC0gb2xzKGZvcm11bGEocGFzdGUwKCJwb2xpdHkyX3QyIH4gbm9uc2VuaW9yQ09VTlQgKyAiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoY29udHJvbHZhcnMsIGNvbGxhcHNlID0gIiArICIpKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NfZGYsIHggPSBULCB5ID0gVCkNCm1vZGVsX25vbnNlbmlvckNPVU5UIDwtIHJvYmNvdihtb2RlbF9ub25zZW5pb3JDT1VOVCwgZGlzc19kZiRHV05vKQ0KDQojIyMjIEFpZC1vbmx5IE1vZGVscyAjIyMjDQoNCiMgREdBDQptb2RlbF9nb3ZfYWlkIDwtIG9scyhmb3JtdWxhKHBhc3RlMCgicG9saXR5Ml90MiB+IGNhYmluZXRDT1VOVCArIGxvZyhkZ2FfZ2RwX3plcm8gKyAxKSArICIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKGNvbnRyb2x2YXJzLCBjb2xsYXBzZSA9ICIgKyAiKSkpDQogICAgICAgICAgICAgICAgICAgICAsDQogICAgICAgICAgICAgICAgICAgICBkYXRhPWRpc3NfZGYsIHg9VCwgeT1UKQ0KbW9kZWxfZ292X2FpZCA8LSByb2Jjb3YobW9kZWxfZ292X2FpZCwgZGlzc19kZiRHV05vKQ0KDQoNCiMgUHJvZ3JhbSBBaWQNCm1vZGVsX3Byb2dyYW1fYWlkIDwtIG9scyhmb3JtdWxhKHBhc3RlMCgicG9saXR5Ml90MiB+IGNhYmluZXRDT1VOVCArIGxvZyhwcm9ncmFtX2FpZF9nZHBfemVybyArIDEpICsgIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKGNvbnRyb2x2YXJzLCBjb2xsYXBzZSA9ICIgKyAiKSkpDQogICAgICAgICAgICAgICAgICAgICAgICAgLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgeD1ULCB5PVQpDQptb2RlbF9wcm9ncmFtX2FpZCA8LSByb2Jjb3YobW9kZWxfcHJvZ3JhbV9haWQsIGRpc3NfZGYkR1dObykNCg0KDQojIEJ1ZGdldCBBaWQNCm1vZGVsX2NvbW1vZGl0eV9haWQgPC0gb2xzKGZvcm11bGEocGFzdGUwKCJwb2xpdHkyX3QyIH4gY2FiaW5ldENPVU5UICsgbG9nKGNvbW1vZGl0eV9haWRfZ2RwX3plcm8gKyAxKSArICIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKGNvbnRyb2x2YXJzLCBjb2xsYXBzZSA9ICIgKyAiKSkpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRpc3NfZGYsIHg9VCwgeT1UKQ0KbW9kZWxfY29tbW9kaXR5X2FpZCA8LSByb2Jjb3YobW9kZWxfY29tbW9kaXR5X2FpZCwgZGlzc19kZiRHV05vKQ0KDQoNCiMgT3V0cHV0IHRhYmxlIGZvciBtYW51c2NyaXB0DQpzb3VyY2UoImZ1bmN0aW9ucy9leHRyYWN0X29sc19jdXN0b20uUiIpDQpzb3VyY2UoIi4vZnVuY3Rpb25zL2N1c3RvbV90ZXhyZWcuUiIpDQplbnZpcm9ubWVudChjdXN0b21fdGV4cmVnKSA8LSBhc05hbWVzcGFjZSgndGV4cmVnJykNCiMgDQpjdXN0b21fdGV4cmVnKGwgPSBsaXN0KG1vZGVsX3BzLA0KICAgICAgICAgICAgICAgICAgICAgICBtb2RlbF9zZW5pb3JDT1VOVCwNCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxfbm9uc2VuaW9yQ09VTlQsDQogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2dvdl9haWQsDQogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX3Byb2dyYW1fYWlkLA0KICAgICAgICAgICAgICAgICAgICAgICBtb2RlbF9jb21tb2RpdHlfYWlkKSwNCiAgICAgICAgICAgICAgZmlsZSA9ICIuLi9vdXRwdXQvaW5kX2VmZmVjdHNfZGVtb2MudGV4IiwNCiAgICAgICAgICAgICAgcmVvcmRlci5jb2VmID0gYygxLCA5LCAxMCwgMTE6MTMsIDI6OCksDQogICAgICAgICAgICAgIHN0YXJzID0gYygwLjAwMSwgMC4wMSwgMC4wNSwgMC4xKSwNCiAgICAgICAgICAgICAgc3ltYm9sID0gIisiLA0KICAgICAgICAgICAgICAjIGN1c3RvbS5tdWx0aWNvbCA9IFQsDQogICAgICAgICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gYygiSW50ZXJjZXB0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3dlci1TaGFyaW5nIChjYWJpbmV0KSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWlkIC8gR0RQIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHRFAgcC9jIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3B1bGF0aW9uIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25mbGljdCBpbnRlbnNpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbi1TdGF0ZSBWaW9sZW5jZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmF0LiByZXMuIHJlbnRzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWdpbWUgVHlwZSAoUG9saXR5KSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItU2hhcmluZyAoc2VuaW9yKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItU2hhcmluZyAobm9uc2VuaW9yKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGVtb2NyYWN5IEFpZC9HRFAgKGxvZykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByb2dyYW0gQWlkL0dEUCAobG9nKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQnVkZ2V0IEFpZC9HRFAgKGxvZykiKSwNCiAgICAgICAgICAgICAgb21pdC5jb2VmID0gIkludGVyY2VwdCIsDQogICAgICAgICAgICAgIHRhYmxlID0gRkFMU0UsDQogICAgICAgICAgICAgIGRjb2x1bW4gPSBULA0KICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KCJQb3dlci1TaGFyaW5nIiA9IDE6MywgIkFpZCIgPSA0OjcsICJDb250cm9scyIgID0gODoxMyksDQogICAgICAgICAgICAgIGJvb2t0YWJzID0gVCwNCiAgICAgICAgICAgICAgdXNlLnBhY2thZ2VzID0gRiwNCiAgICAgICAgICAgICAgY2VudGVyID0gVFJVRSwNCiAgICAgICAgICAgICAgaW5jbHVkZS5jbHVzdGVyID0gVCwgDQogICAgICAgICAgICAgIGluY2x1ZGUubHIgPSBGLCANCiAgICAgICAgICAgICAgaW5jbHVkZS5yc3F1YXJlZCA9IEYpDQojIGN1c3RvbS5tb2RlbC5uYW1lcyA9IGMoIiBcXG11bHRpY29sdW1uezN9e2N9eyBcXHRleHRiZntQb3dlci1TaGFyaW5nfX0gJiBcXG11bHRpY29sdW1uezN9e2N9eyBcXHRleHRiZntGb3JlaWduIEFpZH19IFxcXFwgXFxjbWlkcnVsZShyKXsyLTR9IFxcY21pZHJ1bGUobCl7NS03fSAmIFxcbXVsdGljb2x1bW57MX17Y317KDEpICB9IiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAiXFxtdWx0aWNvbHVtbnsxfXtjfXsoMikgIH0iLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICJcXG11bHRpY29sdW1uezF9e2N9eygzKSAgfSIsDQojICAgICAgICAgICAgICAgICAgICAgICAgIlxcbXVsdGljb2x1bW57MX17Y317KDQpICB9IiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAiXFxtdWx0aWNvbHVtbnsxfXtjfXsoNSkgICB9IiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAiXFxtdWx0aWNvbHVtbnsxfXtjfXsoNikgICB9IikpDQojIA0KDQojIE91dHB1dCB0YWJsZSBmb3IgcmVwbGljYXRpb24gYXJjaGl2ZQ0KDQpodG1scmVnKGwgPSBsaXN0KG1vZGVsX3BzLCANCiAgICAgICAgICAgICAgICAgbW9kZWxfc2VuaW9yQ09VTlQsIA0KICAgICAgICAgICAgICAgICBtb2RlbF9ub25zZW5pb3JDT1VOVCwgDQogICAgICAgICAgICAgICAgIG1vZGVsX2dvdl9haWQsIA0KICAgICAgICAgICAgICAgICBtb2RlbF9wcm9ncmFtX2FpZCwgDQogICAgICAgICAgICAgICAgIG1vZGVsX2NvbW1vZGl0eV9haWQpLCANCiAgICAgICAgcmVvcmRlci5jb2VmID0gYygxLCA5LCAxMCwgMTE6MTMsIDI6OCksDQogICAgICAgICMgZmlsZSA9ICIuL291dHB1dC9wc3Jlc3VsdHMudGV4IiwNCiAgICAgICAgc3RhcnMgPSBjKDAuMDAxLCAwLjAxLCAwLjA1LCAwLjEpLA0KICAgICAgICBzeW1ib2wgPSAiKyIsDQogICAgICAgIGNhcHRpb24gPSAiIiwgDQogICAgICAgIGN1c3RvbS5tdWx0aWNvbCA9IFQsDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gYygiSW50ZXJjZXB0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3dlci1TaGFyaW5nIChjYWJpbmV0KSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWlkIC8gR0RQIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHRFAgcC9jIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3B1bGF0aW9uIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25mbGljdCBpbnRlbnNpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbi1TdGF0ZSBWaW9sZW5jZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmF0LiByZXMuIHJlbnRzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWdpbWUgVHlwZSAoUG9saXR5KSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItU2hhcmluZyAoc2VuaW9yKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItU2hhcmluZyAobm9uc2VuaW9yKSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRlbW9jcmFjeSBBaWQvR0RQIChsb2cpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJvZ3JhbSBBaWQvR0RQIChsb2cpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQnVkZ2V0IEFpZC9HRFAgKGxvZykiKSwNCiAgICAgICAgb21pdC5jb2VmID0gIkludGVyY2VwdCIsDQogICAgICAgIGdyb3VwcyA9IGxpc3QoIlBvd2VyLVNoYXJpbmciID0gMTozLCAiQWlkIiA9IDQ6NywgIkNvbnRyb2xzIiAgPSA4OjEzKSwNCiAgICAgICAgdGFibGUgPSBGQUxTRSwgDQogICAgICAgIGRjb2x1bW4gPSBULA0KICAgICAgICBib29rdGFicyA9IFQsDQogICAgICAgIHVzZS5wYWNrYWdlcyA9IEYsDQogICAgICAgIGNlbnRlciA9IFRSVUUsDQogICAgICAgIHN0YXIuc3ltYm9sID0gIlxcKiIsIA0KICAgICAgICBpbmNsdWRlLmxyID0gRikNCg0KYGBgDQo8IS0tIE5vdGVzOiBEZXBlbmRlbnQgdmFyaWFibGUgaXMgJFx0ZXh0aXR7UG9saXR5fV97dDJ9JC4gU3RhbmRhcmQgZXJyb3JzIGNsdXN0ZXJlZCBieSBjb3VudHJ5LiBJbnRlcmNlcHQgZXN0aW1hdGVkLCBidXQgbm90IHJlcG9ydGVkLiAtLT4NCg0KPCEtLSA8cD4gJm5ic3A7IDwvcD4gLS0+DQoNCg0KDQojIFRhYmxlIDUuMjogSW50ZXJhY3Rpb24gRWZmZWN0cyBvZiBQb3dlci1TaGFyaW5nIGFuZCBGb3JlaWduIEFpZCBvbiBQb3N0LUNvbmZsaWN0IFBvbGl0aWNhbCBEZXZlbG9wbWVudA0KDQpgYGB7ciwgcmVzdWx0cz0iYXNpcyIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRn0NCiMgTGlicmFyaWVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocm1zKQ0KIyBsaWJyYXJ5KHRleHJlZykNCg0KIyBsb2FkIA0KbG9hZCgiLi9kYXRhL2Rpc3NfZGYucmRhIikNCg0KIyB0byBwcmVkaWN0IHN1YnN0YW50aXZlIGVmZmVjdHMgZnJvbSB0aGlzIG1vZGVsLCB3ZSBuZWVkIHRvIGRlZmluZSBkYXRhIA0KIyBkaXN0cmlidXRpb24NCmRpc3NfZGYkY29uZmxpY3RJRCA8LSBOVUxMDQpkYXRhZGlzdF9kaXNzX2RmIDwtIGRhdGFkaXN0KGRpc3NfZGYpOyBvcHRpb25zKGRhdGFkaXN0PSdkYXRhZGlzdF9kaXNzX2RmJykNCg0KIyBQb2xpdHkgRFYgKyBjYWJpbmVJTkMNCm1vZGVsX3BvbGl0eV9jYWJpbmMgPC0gb2xzKHBvbGl0eTJfdDIgfiAgDQogICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0SU5DICogDQogICAgICAgICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbiArDQogICAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgcG9saXR5MiAsDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmLCB4PVQsIHk9VCkNCm1vZGVsX3BvbGl0eV9jYWJpbmMgPC0gcm9iY292KG1vZGVsX3BvbGl0eV9jYWJpbmMsIGRpc3NfZGYkR1dObykNCg0KIyBQb2xpdHkgRFYgKyBjYWJDT1VOVA0KbW9kZWxfcG9saXR5X2NhYmNvdW50IDwtIG9scyhwb2xpdHkyX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldENPVU5UICogDQogICAgICAgICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbiArDQogICAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgcG9saXR5MiAsDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmLCB4PVQsIHk9VCkNCm1vZGVsX3BvbGl0eV9jYWJjb3VudCA8LSByb2Jjb3YobW9kZWxfcG9saXR5X2NhYmNvdW50LCBkaXNzX2RmJEdXTm8pDQoNCiMgRkggKyBjYWJJTkMNCm1vZGVsX2ZoX2NhYmluYyA8LSBvbHMoZmhfdDIgfiAgDQogICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldElOQyAqIGFpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsNCiAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICBmaCwgeD0gVCwgeSA9IFQsDQogICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZikNCm1vZGVsX2ZoX2NhYmluYyA8LSByb2Jjb3YobW9kZWxfZmhfY2FiaW5jLCBkaXNzX2RmJEdXTm8pDQoNCiMgRkggKyBjYWJjb3VudA0KbW9kZWxfZmhfY2FiY291bnQgPC0gb2xzKGZoX3QyIH4gIA0KICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqIGFpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsNCiAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICBmaCAsDQogICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgeD1ULCB5PVQpDQptb2RlbF9maF9jYWJjb3VudCA8LSByb2Jjb3YobW9kZWxfZmhfY2FiY291bnQsIGRpc3NfZGYkR1dObykNCg0KIyB0ZXggb3V0cHV0DQpzb3VyY2UoImZ1bmN0aW9ucy9leHRyYWN0X29sc19jdXN0b20uUiIpDQpzb3VyY2UoIi4vZnVuY3Rpb25zL2N1c3RvbV90ZXhyZWcuUiIpDQplbnZpcm9ubWVudChjdXN0b21fdGV4cmVnKSA8LSBhc05hbWVzcGFjZSgndGV4cmVnJykNCiMgDQpjdXN0b21fdGV4cmVnKGw9bGlzdChtb2RlbF9wb2xpdHlfY2FiaW5jLA0KICAgICAgICAgICAgICAgICAgICAgbW9kZWxfcG9saXR5X2NhYmNvdW50LA0KICAgICAgICAgICAgICAgICAgICAgbW9kZWxfZmhfY2FiaW5jLA0KICAgICAgICAgICAgICAgICAgICAgbW9kZWxfZmhfY2FiY291bnQpLA0KICAgICAgICAgICAgICBmaWxlID0gIi4uL291dHB1dC9tYWlucmVzdWx0czIudGV4IiwNCiAgICAgICAgICAgICAgc3RhcnMgPSBjKDAuMDAxLCAwLjAxLCAwLjA1LCAwLjEpLA0KICAgICAgICAgICAgICBjdXN0b20ubm90ZSA9ICIlc3RhcnMiLA0KICAgICAgICAgICAgICBjZW50ZXIgPSBUUlVFLA0KICAgICAgICAgICAgICBzeW1ib2wgPSAiKyIsDQogICAgICAgICAgICAgIHJlb3JkZXIuY29lZiA9IGMoMSwgOToxMSwgMjo4LCAxMiksDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gYygiSW50ZXJjZXB0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3dlci1zaGFyaW5nIChiaW5hcnkpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBaWQgLyBHRFAgKGxvZykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdEUCBwL2MgKGxvZykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcHVsYXRpb24gKGxvZykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvbmZsaWN0IGludGVuc2l0eSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm9uLVN0YXRlIFZpb2xlbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOYXQuIHJlcy4gcmVudHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvbGl0eSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItc2hhcmluZyAoYmluYXJ5KSAqIEFpZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItc2hhcmluZyAoY2FiaW5ldCkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvd2VyLXNoYXJpbmcgKGNhYmluZXQpICogQWlkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGcmVlZG9tIEhvdXNlIiksDQogICAgICAgIG9taXQuY29lZiA9ICJJbnRlcmNlcHQiLA0KICAgICAgICB0YWJsZSA9IEZBTFNFLA0KICAgICAgICBjdXN0b20ubXVsdGljb2wgPSBULA0KICAgICAgICBkY29sdW1uID0gVCwNCiAgICAgICAgYm9va3RhYnMgPSBULA0KICAgICAgICBpbmNsdWRlLnJzcXVhcmVkID0gRiwgDQogICAgICAgIGluY2x1ZGUuY2x1c3RlciA9IFQsDQogICAgICAgIHVzZS5wYWNrYWdlcyA9IEYsDQogICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9IGMoIlxcbXVsdGljb2x1bW57Mn17Y317XFx0ZXh0YmZ7UG9saXR5fX0gJiBcXG11bHRpY29sdW1uezJ9e2N9e1xcdGV4dGJme0ZyZWVkb20gSG91c2V9fSBcXFxcIFxcY21pZHJ1bGUocil7Mi0zfSBcXGNtaWRydWxlKGwpezQtNX0gJiBcXG11bHRpY29sdW1uezF9e2N9eygxKX0iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcXG11bHRpY29sdW1uezF9e2N9eygyKSB9IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXFxtdWx0aWNvbHVtbnsxfXtjfXsoMykgfSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxcbXVsdGljb2x1bW57MX17Y317KDQpIH0iKSkNCg0KDQojIG91dHB1dCByZXBsaWNhdGlvbiBhcmNoaXZlDQpodG1scmVnKGw9bGlzdChtb2RlbF9wb2xpdHlfY2FiaW5jLCANCiAgICAgICAgICAgICAgICAgICAgIG1vZGVsX3BvbGl0eV9jYWJjb3VudCwgDQogICAgICAgICAgICAgICAgICAgICBtb2RlbF9maF9jYWJpbmMsDQogICAgICAgICAgICAgICAgICAgICBtb2RlbF9maF9jYWJjb3VudCksDQogICAgICAgICAgICAgICMgZmlsZSA9ICIuLi9vdXRwdXQvbWFpbnJlc3VsdHMudGV4IiwNCiAgICAgICAgICAgICAgc3RhcnMgPSBjKDAuMDAxLCAwLjAxLCAwLjA1LCAwLjEpLA0KICAgICAgICAgICAgICAjIGN1c3RvbS5ub3RlID0gIiVzdGFycyIsDQogICAgICAgICAgICAgIGNlbnRlciA9IFRSVUUsDQogICAgICAgICAgICAgIHN5bWJvbCA9ICIrIiwNCiAgICAgICAgICAgICAgcmVvcmRlci5jb2VmID0gYygxLCA5OjExLCAyOjgsIDEyKSwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSBjKCJJbnRlcmNlcHQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvd2VyLXNoYXJpbmcgKGJpbmFyeSkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFpZCAvIEdEUCAobG9nKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR0RQIHAvYyAobG9nKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9wdWxhdGlvbiAobG9nKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29uZmxpY3QgaW50ZW5zaXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb24tU3RhdGUgVmlvbGVuY2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hdC4gcmVzLiByZW50cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9saXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3dlci1zaGFyaW5nIChiaW5hcnkpICogQWlkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3dlci1zaGFyaW5nIChjYWJpbmV0KSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG93ZXItc2hhcmluZyAoY2FiaW5ldCkgKiBBaWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZyZWVkb20gSG91c2UiKSwNCiAgICAgICAgb21pdC5jb2VmID0gIkludGVyY2VwdCIsDQogICAgICAgIHRhYmxlID0gRkFMU0UsIA0KICAgICAgICBjdXN0b20ubXVsdGljb2wgPSBULCANCiAgICAgICAgZGNvbHVtbiA9IFQsDQogICAgICAgIGJvb2t0YWJzID0gVCwNCiAgICAgICAgdXNlLnBhY2thZ2VzID0gRiwNCiAgICAgICAgc3Rhci5zeW1ib2wgPSAiXFwqIiwgDQogICAgICAgIGluY2x1ZGUubHIgPSBGKQ0KYGBgDQoNCg0KIyBUYWJsZSA1LjM6IFJvYnVzdG5lc3MgQ2hlY2tzDQpgYGB7ciwgcmVzdWx0cz0iYXNpcyIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRn0NCg0KIyBMaWJyYXJpZXMNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShybXMpDQpsaWJyYXJ5KHBsbSkNCmxpYnJhcnkodGV4cmVnKQ0KbGlicmFyeShjb3VudHJ5Y29kZSkNCmxpYnJhcnkodGV4cmVnKQ0KDQojIExvYWQgRGF0YQ0KbG9hZCgiLi9kYXRhL2Rpc3NfZGYucmRhIikNCg0KIyBNb2RlbHMNCg0KIyBGcmFjdGlvbmFsaXphdGlvbg0KZGVtb2NfbW9kZWxfZWxmIDwtIG9scyhwb2xpdHkyX3QyIH4NCiAgICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlQgKiBhaWRkYXRhX0FpZEdEUF9sbiArDQogICAgICAgICAgICAgICAgICAgICAgICAgbG5fZ2RwX3BjICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zKw0KICAgICAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgcG9saXR5MiArDQogICAgICAgICAgICAgICAgICAgICAgICAgRXRobmljLA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRpc3NfZGYsDQogICAgICAgICAgICAgICAgICAgICAgIHggPSBULCB5ID0gVCkNCmRlbW9jX21vZGVsX2VsZiA8LSByb2Jjb3YoZGVtb2NfbW9kZWxfZWxmLCBkaXNzX2RmJEdXTm8pDQoNCiMgUEtPDQpkZW1vY19tb2RlbF9wa28gPC0gb2xzKHBvbGl0eTJfdDIgfg0KICAgICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqIGFpZGRhdGFfQWlkR0RQX2xuICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBsbl9nZHBfcGMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMrDQogICAgICAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkyICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBEU19vcmRpbmFsLA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRpc3NfZGYsDQogICAgICAgICAgICAgICAgICAgICAgIHggPSBULCB5ID0gVCkNCmRlbW9jX21vZGVsX3BrbyA8LSByb2Jjb3YoZGVtb2NfbW9kZWxfcGtvLCBkaXNzX2RmJEdXTm8pDQoNCiMgQ2FiaW5ldCBTaXplDQoNCmxpYnJhcnkocmVhZHhsKQ0KY250cyA8LSByZWFkX2V4Y2VsKCIuL2RhdGEvQ05UU0RBVEEueGxzIikNCg0KY250cyA8LSBjbnRzICU+JSBmaWx0ZXIoeWVhciA+PSAxOTg5KQ0KDQpjbnRzJGlzbzNjIDwtIGNvdW50cnljb2RlKGNudHMkY291bnRyeSwgImNvdW50cnkubmFtZSIsICJpc28zYyIpDQpjbnRzIDwtIGNudHMgJT4lIGZpbHRlcihjb3VudHJ5ICE9ICJTT01BTElMQU5EIikNCg0KdGVzdGNhYnNpemUgPC0gbGVmdF9qb2luKGRpc3NfZGYsIGNudHNbLCBjKCJpc28zYyIsICJ5ZWFyIiwgInBvbGl0MTAiKV0pDQoNCnRlc3RjYWJzaXplJHBzX3NoYXJlIDwtIHRlc3RjYWJzaXplJGNhYmluZXRDT1VOVCAvIHRlc3RjYWJzaXplJHBvbGl0MTAgKiAxMDANCg0KbW9kZWxfY2Fic2l6ZSA8LSBvbHMocG9saXR5Ml90MiB+DQogICAgICAgICAgICAgICAgICAgICAgIHBzX3NoYXJlICoNCiAgICAgICAgICAgICAgICAgICAgICAgYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgICBsbl9nZHBfcGMgKw0KICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgKw0KICAgICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsNCiAgICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkyLA0KICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHRlc3RjYWJzaXplLCB4ID0gVCwgeSA9IFQpDQptb2RlbF9jYWJzaXplIDwtIHJvYmNvdihtb2RlbF9jYWJzaXplLCB0ZXN0Y2Fic2l6ZSRHV05vKQ0KDQojIFJhbmRvbSBFZmZlY3RzDQpjb3VudHJ5X3JlX2RlbW9jIDwtIHBsbShwb2xpdHkyX3QyIH4NCiAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCArDQogICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbiArDQogICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlQgKiBhaWRkYXRhX0FpZEdEUF9sbiArDQogICAgICAgICAgICAgICAgICBsbl9nZHBfcGMgKw0KICAgICAgICAgICAgICAgICAgbG5fcG9wICsNCiAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zKw0KICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKw0KICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgcG9saXR5MiAsDQogICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmLCBtb2RlbCA9ICJyYW5kb20iLCBpbmRleCA9YygiR1dObyIsICJ5ZWFyIikpDQpjb3VudHJ5X3JlX2RlbW9jJHZjb3YgIDwtIHZjb3ZIQyhjb3VudHJ5X3JlX2RlbW9jLCBjbHVzdGVyPSJncm91cCIpDQoNCg0KIyBSZWdpb24gRml4ZWQgRWZmZWN0cw0KZGlzc19kZiRyZWdpb24gPC0gY291bnRyeWNvZGUoZGlzc19kZiRMb2NhdGlvbiwgImNvdW50cnkubmFtZSIsICJyZWdpb24iKQ0KZGlzc19kZiRjb3VudHJ5X3llYXIgPC0gcGFzdGUwKGRpc3NfZGYkTG9jYXRpb24sIGRpc3NfZGYkeWVhciwgc2VwID0gIi0iKQ0KDQpyZWdpb25fZmVfZGVtb2MgPC0gcGxtKHBvbGl0eTJfdDIgfg0KICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgbG5fZ2RwX3BjICsNCiAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucysNCiAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsNCiAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgDQogICAgICAgICAgICAgICAgICAgbW9kZWwgPSAid2l0aGluIiwgDQogICAgICAgICAgICAgICAgICAgaW5kZXggPWMoInJlZ2lvbiIsICJjb3VudHJ5X3llYXIiKSkNCnJlZ2lvbl9mZV9kZW1vYyR2Y292ICA8LSB2Y292SEMocmVnaW9uX2ZlX2RlbW9jLCBjbHVzdGVyPSJncm91cCIpDQoNCiMgQ291bnRyeSBGRSANCmNvdW50cnlfZmVfZGVtb2MgPC0gcGxtKHBvbGl0eTJfdDIgfg0KICAgICAgICAgICAgICAgICAgICAgY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG4gKw0KICAgICAgICAgICAgICAgICAgICAgbG5fZ2RwX3BjICsNCiAgICAgICAgICAgICAgICAgICAgIGxuX3BvcCArDQogICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucysNCiAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsNCiAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzICsNCiAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgDQogICAgICAgICAgICAgICAgICAgbW9kZWwgPSAid2l0aGluIiwgDQogICAgICAgICAgICAgICAgICAgaW5kZXggPWMoIkdXTm8iLCAieWVhciIpKQ0KY291bnRyeV9mZV9kZW1vYyR2Y292ICA8LSB2Y292SEMoY291bnRyeV9mZV9kZW1vYywgY2x1c3Rlcj0iZ3JvdXAiKQ0KDQoNCiMjIE9yZGVyIG9mIGNvZWZmaWNpZW50cyBpbiBvdXRwdXQgdGFibGUNCm5hbWVfbWFwX3JvYnVzdG5lc3MgPC0gbGlzdChjYWJpbmV0Q09VTlQgPSAiUFMgKGNhYmluZXQpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG4iID0gIlBTIChjYWJpbmV0KSAqIEFpZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYWJpbmV0Q09VTlQ6YWlkZGF0YV9BaWRHRFBfbG4iID0gIlBTIChjYWJpbmV0KSAqIEFpZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNfc2hhcmUgPSAiUFMgKGNhYmluZXQgc2hhcmUpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHNfc2hhcmUgKiBhaWRkYXRhX0FpZEdEUF9sbiIgPSAiUFMgKGNhYmluZXQgc2hhcmUpICogQWlkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbiA9ICJBaWQgLyBHRFAgKGxvZykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxuX2dkcF9wYyA9ICJHRFAgcC9jIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbl9wb3AgPSAiUG9wdWxhdGlvbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgPSAiQ29uZmxpY3QgSW50ZW5zaXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSA9ICJOb24tU3RhdGUgVmlvbGVuY2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdCbmF0cmVzID0gIk5hdC4gUmVzLiBSZW50cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9saXR5MiA9ICJQb2xpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV0aG5pYyA9ICJFdGhuaWMgRnJhYy4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIERTX29yZGluYWwgPSAiVU4gUEtPIikNCg0Kc291cmNlKCIuL2Z1bmN0aW9ucy93aWxsX2xvd2VfdGV4cmVnX3Jlb3JkZXIuUiIpDQoNCiMgTW9kZWwgbGlzdA0Kcm9iX21vZGVscyA8LSBsaXN0KGRlbW9jX21vZGVsX2VsZiwNCiAgICAgZGVtb2NfbW9kZWxfcGtvLA0KICAgICBtb2RlbF9jYWJzaXplLA0KICAgICBjb3VudHJ5X3JlX2RlbW9jLA0KICAgICByZWdpb25fZmVfZGVtb2MsDQogICAgIGNvdW50cnlfZmVfZGVtb2MpDQoNCm9sZG5hbWVzIDwtIGFsbC52YXJuYW1lcy5kYW1taXQocm9iX21vZGVscykNCnJvciA8LSBidWlsZC5yb3Iob2xkbmFtZXMsIG5hbWVfbWFwX3JvYnVzdG5lc3MpDQoNCg0KDQojIE91dHB1dCBtYW51c2NyaXB0DQojIA0KIyBzb3VyY2UoIi4vZnVuY3Rpb25zL2N1c3RvbV90ZXhyZWcuUiIpDQojIGVudmlyb25tZW50KGN1c3RvbV90ZXhyZWcpIDwtIGFzTmFtZXNwYWNlKCd0ZXhyZWcnKQ0KIyANCmN1c3RvbV90ZXhyZWcobCA9IHJvYl9tb2RlbHMsDQogICAgICAgIHN0YXJzID0gYygwLjAwMSwgMC4wMSwgMC4wNSwgMC4xKSwNCiAgICAgICAgc3ltYm9sID0gIisiLA0KICAgICAgICB0YWJsZSA9IEYsDQogICAgICAgIGJvb2t0YWJzID0gVCwNCiAgICAgICAgdXNlLnBhY2thZ2VzID0gRiwNCiAgICAgICAgZGNvbHVtbiA9IFQsDQogICAgICAgIGZpbGUgPSAiLi4vb3V0cHV0L3JvYnVzdG5lc3MudGV4IiwNCiAgICAgICAgY3VzdG9tLm1vZGVsLm5hbWVzID0gYygiKDEpIEVMRiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigyKSBQS08iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMykgQ2FiLiBTaXplIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKDQpIFJFIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKDUpIFJlZ2lvbiBGRSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig2KSBDb3VudHJ5IEZFIiksDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gcm9yJGNjbiwNCiAgICAgICAgb21pdC5jb2VmID0gcm9yJG9jLA0KICAgICAgICBpbmNsdWRlLnJzcXVhcmVkID0gRiwNCiAgICAgICAgaW5jbHVkZS5jbHVzdGVyID0gVCwNCiAgICAgICAgcmVvcmRlci5jb2VmID0gdW5pcXVlKHJvciRyYyksDQogICAgICAgIHN0YXIuc3ltYm9sID0gIlxcKiIsDQogICAgICAgIGluY2x1ZGUubHIgPSBGLCBpbmNsdWRlLnZhcmlhbmNlID0gRikNCg0KIyBPdXRwdXQgcmVwbGljYXRpb24gYXJjaGl2ZQ0KaHRtbHJlZyhsID0gcm9iX21vZGVscywNCiAgICAgICAgc3RhcnMgPSBjKDAuMDAxLCAwLjAxLCAwLjA1LCAwLjEpLA0KICAgICAgICBzeW1ib2wgPSAiKyIsDQogICAgICAgIHRhYmxlID0gRiwNCiAgICAgICAgYm9va3RhYnMgPSBULA0KICAgICAgICB1c2UucGFja2FnZXMgPSBGLA0KICAgICAgICBkY29sdW1uID0gVCwNCiAgICAgICAgIyBmaWxlID0gIi4uL291dHB1dC9yb2J1c3RuZXNzLnRleCIsDQogICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9IGMoIigxKSBFTEYiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKDIpIFBLTyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMykgQ2FiaW5ldCBTaXplIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig0KSBSYW5kb20gRWZmZWN0cyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoNSkgUmVnaW9uIEZFIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig2KSBDb3VudHJ5IEZFIiksDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gcm9yJGNjbiwgDQogICAgICAgIG9taXQuY29lZiA9IHJvciRvYywgDQogICAgICAgICAgaW5jbHVkZS5yc3F1YXJlZCA9IEYsDQogICAgICAgIGluY2x1ZGUuY2x1c3RlciA9IFQsDQogICAgICAgIGNhcHRpb24gPSAiIiwgDQogICAgICAgIHJlb3JkZXIuY29lZiA9IHVuaXF1ZShyb3IkcmMpLA0KICAgICAgICBzdGFyLnN5bWJvbCA9ICJcXCoiLCANCiAgICAgICAgaW5jbHVkZS5sciA9IEYsIGluY2x1ZGUudmFyaWFuY2UgPSBGKQ0KDQoNCg0KYGBgDQoNCg0KIyBUYWJsZSA1LjQ6IEFkZGl0aW9uYWwgQWlkIExhZ3MNCg0KDQpgYGB7ciwgcmVzdWx0cz0iYXNpcyIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRn0NCg0KDQoNCiMgTGlicmFyaWVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocm1zKQ0KbGlicmFyeSh0ZXhyZWcpDQoNCiMgbG9hZCANCmxvYWQoIi4vZGF0YS9kaXNzX2RmLnJkYSIpDQoNCg0KIyBFc3RpbWF0ZSBtb2RlbHMgd2l0aCB0aW1lIGxhZ3MgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIDEgeWVhciBsYWcNCmxhZzFfcGNobmcgPC0gb2xzKHBvbGl0eTJfdDIgfiAgDQogICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVCAqIGFpZGRhdGFfQWlkR0RQX2xuX3RtaW4xICsNCiAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgIGxvZyhwb3B1bGF0aW9uKSArDQogICAgICAgICAgICAgICAgICAgIGNvbmZfaW50ZW5zICsNCiAgICAgICAgICAgICAgICAgICAgbm9uc3RhdGUgKyANCiAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICBwb2xpdHkyLA0KICAgICAgICAgICAgICAgICAgZGF0YT1kaXNzX2RmLCB4PVQsIHk9VCkNCmxhZzFfcGNobmcgPC0gcm9iY292KGxhZzFfcGNobmcsIGRpc3NfZGYkR1dObykNCg0KDQpsYWcxX2ZoY2huZyA8LSBvbHMoZmhfdDIgfiAgDQogICAgICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlQgKiBhaWRkYXRhX0FpZEdEUF9sbl90bWluMSArDQogICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgIGxvZyhwb3B1bGF0aW9uKSArDQogICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgZmggLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgeD1ULCB5PVQpDQpsYWcxX2ZoY2huZyA8LSByb2Jjb3YobGFnMV9maGNobmcsIGRpc3NfZGYkR1dObykNCg0KDQojIDIgeWVhcnMgYWlkIGxhZw0KbGFnMl9wY2huZyA8LSBvbHMocG9saXR5Ml90MiB+ICANCiAgICAgICAgICAgICAgICAgICAgY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG5fdG1pbjIgKw0KICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgbG9nKHBvcHVsYXRpb24pICsNCiAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgIHBvbGl0eTIsDQogICAgICAgICAgICAgICAgICBkYXRhPWRpc3NfZGYsIHg9VCwgeT1UKQ0KbGFnMl9wY2huZyA8LSByb2Jjb3YobGFnMl9wY2huZywgZGlzc19kZiRHV05vKQ0KDQpsYWcyX2ZoY2huZyA8LSBvbHMoZmhfdDIgfiAgDQogICAgICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlQgKiBhaWRkYXRhX0FpZEdEUF9sbl90bWluMiArDQogICAgICAgICAgICAgICAgICAgICBsb2coR0RQX3Blcl9jYXBpdGEpICsNCiAgICAgICAgICAgICAgICAgICAgIGxvZyhwb3B1bGF0aW9uKSArDQogICAgICAgICAgICAgICAgICAgICBjb25mX2ludGVucyArDQogICAgICAgICAgICAgICAgICAgICBub25zdGF0ZSArIA0KICAgICAgICAgICAgICAgICAgICAgV0JuYXRyZXMgKw0KICAgICAgICAgICAgICAgICAgICAgZmggLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9ZGlzc19kZiwgeD1ULCB5PVQpDQpsYWcyX2ZoY2huZyA8LSByb2Jjb3YobGFnMl9maGNobmcsIGRpc3NfZGYkR1dObykNCg0KDQojIyMjIE1vZGVsIE91dHB1dCAjIyMjDQoNCg0KIyMgT3JkZXIgb2YgY29lZmZpY2llbnRzIGluIG91dHB1dCB0YWJsZQ0KbmFtZV9tYXAgPC0gbGlzdChjYWJpbmV0Q09VTlQgPSAiUG93ZXItU2hhcmluZyAoY2FiaW5ldCkiLA0KICAgICAgICAgICAgICAgICBhaWRkYXRhX0FpZEdEUF9sbl90bWluMSAgID0gIkFpZCAvIEdEUCAobG9nKSIsDQogICAgICAgICAgICAgICAgIGFpZGRhdGFfQWlkR0RQX2xuX3RtaW4yICAgPSAiQWlkIC8gR0RQIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgImNhYmluZXRDT1VOVCAqIGFpZGRhdGFfQWlkR0RQX2xuX3RtaW4xIiA9ICJQb3dlci1TaGFyaW5nIChjYWJpbmV0KSAqIEFpZCIsIA0KICAgICAgICAgICAgICAgICAiY2FiaW5ldENPVU5UICogYWlkZGF0YV9BaWRHRFBfbG5fdG1pbjIiID0gIlBvd2VyLVNoYXJpbmcgKGNhYmluZXQpICogQWlkIiwgDQogICAgICAgICAgICAgICAgIEdEUF9wZXJfY2FwaXRhID0gIkdEUCBwL2MiLA0KICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uID0gIlBvcHVsYXRpb24iLA0KICAgICAgICAgICAgICAgICBjb25mX2ludGVucyA9ICJDb25mbGljdCBJbnRlbnNpdHkiLA0KICAgICAgICAgICAgICAgICBub25zdGF0ZSA9ICJOb24tU3RhdGUgVmlvbGVuY2UiLA0KICAgICAgICAgICAgICAgICBXQm5hdHJlcyA9ICJOYXQuIFJlcy4gUmVudHMiLA0KICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgcG9saXR5MiA9ICJSZWdpbWUgVHlwZSAoUG9saXR5KSIsDQogICAgICAgICAgICAgICAgIGZoID0gIlJlZ2ltZSBUeXBlIChGSCkiKQ0KDQpzb3VyY2UoIi4vZnVuY3Rpb25zL3dpbGxfbG93ZV90ZXhyZWdfcmVvcmRlci5SIikNCg0KIyBNb2RlbCBsaXN0DQptb2RlbF9saXN0IDwtIGxpc3QobGFnMV9wY2huZyxsYWcyX3BjaG5nLCBsYWcxX2ZoY2huZywgbGFnMl9maGNobmcpDQoNCm9sZG5hbWVzIDwtIGFsbC52YXJuYW1lcy5kYW1taXQobW9kZWxfbGlzdCkNCnJvciA8LSBidWlsZC5yb3Iob2xkbmFtZXMsIG5hbWVfbWFwKQ0KDQoNCiMgDQojICMgT3V0cHV0IGZvciBNYW51c2NyaXB0DQojIA0Kc291cmNlKCIuL2Z1bmN0aW9ucy9jdXN0b21fdGV4cmVnLlIiKQ0KZW52aXJvbm1lbnQoY3VzdG9tX3RleHJlZykgPC0gYXNOYW1lc3BhY2UoJ3RleHJlZycpDQoNCiMgDQpjdXN0b21fdGV4cmVnKGwgPSBtb2RlbF9saXN0LA0KICAgICAgIGZpbGUgPSAiLi4vb3V0cHV0L2xhZ2dlZHJlc3VsdHMyLnRleCIsDQogICAgICAgIHN0YXJzID0gYygwLjAwMSwgMC4wMSwgMC4wNSwgMC4xKSwNCiAgICAgICAgc3ltYm9sID0gIisiLA0KICAgICAgICB0YWJsZSA9IEYsDQogICAgICAgIGJvb2t0YWJzID0gVCwNCiAgICAgICAgdXNlLnBhY2thZ2VzID0gRiwNCiAgICAgICAgZGNvbHVtbiA9IFQsDQogICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9IGMoIlxcbXVsdGljb2x1bW57Mn17Y317XFx0ZXh0YmZ7UG9saXR5fX0gJiBcXG11bHRpY29sdW1uezJ9e2N9e1xcdGV4dGJme0ZyZWVkb20gSG91c2V9fSBcXFxcIFxcY21pZHJ1bGUocil7Mi0zfSBcXGNtaWRydWxlKGwpezQtNX0gJiBcXG11bHRpY29sdW1uezF9e2N9eygxKSAxIHllYXJ9IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcXG11bHRpY29sdW1uezF9e2N9eygyKSAgMiB5ZWFyc30iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxcbXVsdGljb2x1bW57MX17Y317KDMpICAxIHllYXJ9IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcXG11bHRpY29sdW1uezF9e2N9eyg0KSAgMiB5ZWFyc30iKSwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSByb3IkY2NuLA0KICAgICAgICBvbWl0LmNvZWYgPSByb3Ikb2MsDQogICAgICAgIHJlb3JkZXIuY29lZiA9IHVuaXF1ZShyb3IkcmMpLA0KICAgICAgICAgICAgICAgY3VzdG9tLm11bHRpY29sID0gVCwNCiAgaW5jbHVkZS5yc3F1YXJlZCA9IEYsDQogICAgICAgIGluY2x1ZGUuY2x1c3RlciA9IFQsDQogICAgICAgIGluY2x1ZGUubHIgPSBGKQ0KDQojIE91dHB1dCBmb3IgUmVwbGljYXRpb24gQXJjaGl2ZQ0KaHRtbHJlZyhsID0gbW9kZWxfbGlzdCwNCiAgICAgICAgc3RhcnMgPSBjKDAuMDAxLCAwLjAxLCAwLjA1LCAwLjEpLA0KICAgICAgICBzeW1ib2wgPSAiKyIsDQogICAgICAgIHRhYmxlID0gRiwNCiAgICAgICAgYm9va3RhYnMgPSBULA0KICAgICAgICB1c2UucGFja2FnZXMgPSBGLA0KICAgICAgICBjYXB0aW9uID0gIiIsIA0KICAgICAgICBkY29sdW1uID0gVCwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSByb3IkY2NuLCANCiAgICAgICAgb21pdC5jb2VmID0gcm9yJG9jLCANCiAgICAgICAgcmVvcmRlci5jb2VmID0gdW5pcXVlKHJvciRyYyksDQogICAgICAgIHN0YXIuc3ltYm9sID0gIlxcKiIsIA0KICAgICAgICBpbmNsdWRlLmxyID0gRikNCg0KDQpgYGANCg0KDQojIFRhYmxlIDUuNjogMlNMUyBTZWNvbmQgU3RhZ2UgUmVzdWx0cw0KDQpgYGB7ciwgcmVzdWx0cz0iYXNpcyIsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBjYWNoZSA9IFQsIGNvbW1lbnRzID0gRn0NCg0KDQojIGxvYWQgbGlicmFyaWVzDQpsaWJyYXJ5KEFFUikNCmxpYnJhcnkoaXZwYWNrKQ0KbGlicmFyeShsbXRlc3QpDQpsaWJyYXJ5KGxmZSkNCmxpYnJhcnkodGlrekRldmljZSkNCg0KIyBsb2FkIGRhdGEgd2l0aCBpbnN0cnVtZW50OyB0aGlzIGdpdmVzICJpbnN0cnVtZW50X2RmIiBkYXRhIGZyYW1lDQpsb2FkKGZpbGUgPSAiLi9kYXRhL2luc3RydW1lbnRlZEFpZDIuUkRhdGEiKQ0KbG9hZCgiLi9kYXRhL2Rpc3NfZGYucmRhIikNCg0KZGlzc19kZl9pdiA8LSBtZXJnZShkaXNzX2RmLCANCiAgICAgICAgICAgICAgICAgICAgICBpbnN0cnVtZW50X2RmLCANCiAgICAgICAgICAgICAgICAgICAgICBieSA9IGMoImlzbzJjIiwgInllYXIiKSwgYWxsLnggPSBUUlVFKQ0KDQoNCiMgc3Vic2V0IG9ubHkgY29tcGxldGUuY2FzZXMgLyBuZWNlc3NhcnkgZm9yIGNsdXN0ZXIucm9idXN0LnNlKCkNCml2X25hIDwtIG5hLm9taXQoZGlzc19kZl9pdlssIGMoInBvbGl0eV9jaG5nIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhYmluZXRDT1VOVCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYWJpbmV0SU5DIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFpZGRhdGFfQWlkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWlkZGF0YV9BaWRHRFBfbG4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhaWRkYXRhX0FpZFBDX2xuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaF90MiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdEUF9wZXJfY2FwaXRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvcHVsYXRpb24iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29uZl9pbnRlbnMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV0JuYXRyZXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9saXR5MiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb2xpdHkyX3QyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG90YWxfc3VtX2V4Y2VwdCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ5ZWFyIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdXTm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR0RQIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9uc3RhdGUiKV0pDQoNCiMgdG8gcHJvY2VlZCB3aXRoIElWIGVzdGltYXRpb24gSSBmaXJzdCBoYXJkLWNvZGUgdGhlIGluc3RydW1lbnQNCml2X25hJGluc3RyX2FpZF9nZHBfbG4gPC0gbG9nKGl2X25hJHRvdGFsX3N1bV9leGNlcHQgLyBpdl9uYSRHRFApDQoNCiMgZGF0YSB0cmFuc2Zvcm1hdGlvbiBmb3IgU3RhdGENCml2X25hJGxuX2dkcF9wYyA8LSBsb2coaXZfbmEkR0RQX3Blcl9jYXBpdGEpDQppdl9uYSRsbl9wb3AgPC0gbG9nKGl2X25hJHBvcHVsYXRpb24pDQoNCiMgYW5kIHNhdmUgZGF0YSB0byBTdGF0YSBmb3JtYXQNCmZvcmVpZ246OndyaXRlLmR0YShpdl9uYSwgIi4vZGF0YS9pdl9uYV9kZW1vYy5kdGEiKQ0KDQppdl9uYSRjYWJpbmV0Q09VTlR4YWlkX2xuIDwtIGl2X25hJGNhYmluZXRDT1VOVCAqIGl2X25hJGFpZGRhdGFfQWlkR0RQX2xuDQppdl9uYSRjYWJpbmV0Q09VTlR4YWlkX2xuX2luc3RyIDwtIGl2X25hJGNhYmluZXRDT1VOVCAqIGl2X25hJGluc3RyX2FpZF9nZHBfbG4NCg0KIyBJViBmb3IgUG9saXR5DQpkZW1vY19wY2huZ19pdiA8LSBsZmU6OmZlbG0ocG9saXR5Ml90MiB+IA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlQgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhwb3B1bGF0aW9uKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBvbGl0eTIgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHwgMCB8IChjYWJpbmV0Q09VTlR4YWlkX2xufGFpZGRhdGFfQWlkR0RQX2xuIH4gDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhYmluZXRDT1VOVHhhaWRfbG5faW5zdHIgKyBpbnN0cl9haWRfZ2RwX2xuKSB8IEdXTm8sDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBpdl9uYSkNCg0KDQojIElWIGZvciBGSA0KZGVtb2NfZmhjaG5nX2l2IDwtIGxmZTo6ZmVsbShmaF90MiB+IA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlQgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKEdEUF9wZXJfY2FwaXRhKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhwb3B1bGF0aW9uKSArDQogICAgICAgICAgICAgICAgICAgICAgICAgIG5vbnN0YXRlICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZl9pbnRlbnMgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICBXQm5hdHJlcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgIGZoIA0KICAgICAgICAgICAgICAgICAgICAgICAgICB8IDAgfCAoY2FiaW5ldENPVU5UeGFpZF9sbnxhaWRkYXRhX0FpZEdEUF9sbiB+IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWJpbmV0Q09VTlR4YWlkX2xuX2luc3RyICsgaW5zdHJfYWlkX2dkcF9sbikgfCBHV05vLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gaXZfbmEpDQoNCiMgT3V0cHV0IFNlY29uZCBTdGFnZSBSZXN1bHRzDQoNCiMjIE9yZGVyIG9mIGNvZWZmaWNpZW50cyBpbiBvdXRwdXQgdGFibGUNCm5hbWVfbWFwIDwtIGxpc3QoY2FiaW5ldENPVU5UID0gIlBvd2VyLVNoYXJpbmcgKGNhYmluZXQpIiwNCiAgICAgICAgICAgICAgICAgImBhaWRkYXRhX0FpZEdEUF9sbihmaXQpYCIgPSAiQWlkIC8gR0RQIChsb2cpIiwNCiAgICAgICAgICAgICAgICAgImBjYWJpbmV0Q09VTlR4YWlkX2xuKGZpdClgIiA9ICJQb3dlci1TaGFyaW5nIChjYWJpbmV0KSAqIEFpZCIsIA0KICAgICAgICAgICAgICAgICAibG9nKEdEUF9wZXJfY2FwaXRhKSIgPSAiR0RQIHAvYyIsDQogICAgICAgICAgICAgICAgICJsb2cocG9wdWxhdGlvbikiID0gIlBvcHVsYXRpb24iLA0KICAgICAgICAgICAgICAgICBjb25mX2ludGVucyA9ICJDb25mbGljdCBJbnRlbnNpdHkiLA0KICAgICAgICAgICAgICAgICBub25zdGF0ZSA9ICJOb24tU3RhdGUgVmlvbGVuY2UiLA0KICAgICAgICAgICAgICAgICBXQm5hdHJlcyA9ICJOYXQuIFJlcy4gUmVudHMiLA0KICAgICAgICAgICAgICAgICBwb2xpdHkyID0gIlJlZ2ltZSBUeXBlIiwNCiAgICAgICAgICAgICAgICAgZmggPSAiUmVnaW1lIFR5cGUiKQ0KDQpzb3VyY2UoIi4vZnVuY3Rpb25zL3dpbGxfbG93ZV90ZXhyZWdfcmVvcmRlci5SIikNCg0KIyBNb2RlbCBsaXN0DQptb2RlbF9saXN0IDwtIGxpc3QoZGVtb2NfcGNobmdfaXYsIA0KICAgICAgICAgICAgICAgICAgIGRlbW9jX2ZoY2huZ19pdikNCg0Kb2xkbmFtZXMgPC0gYWxsLnZhcm5hbWVzLmRhbW1pdChtb2RlbF9saXN0KQ0Kcm9yIDwtIGJ1aWxkLnJvcihvbGRuYW1lcywgbmFtZV9tYXApDQoNCiMgT3V0cHV0IGZvciBNYW51c2NyaXB0DQoNCiMgbGlicmFyeSh0ZXhyZWcpDQojIHNvdXJjZSgiLi9mdW5jdGlvbnMvZXh0cmFjdF9mZWxtX2N1c3RvbS5SIikNCiMgIyAjIG9wdGlvbnMoZXhwcmVzc2lvbnMgPSAxNTAwKQ0KIyBzZXRNZXRob2QoImV4dHJhY3QiLCBzaWduYXR1cmUgPSBjbGFzc05hbWUoImZlbG0iLCAibGZlIiksDQojICAgICBkZWZpbml0aW9uID0gZXh0cmFjdC5mZWxtLmN1c3RvbSkNCg0Kc291cmNlKCIuL2Z1bmN0aW9ucy9jdXN0b21fdGV4cmVnLlIiKQ0KZW52aXJvbm1lbnQoY3VzdG9tX3RleHJlZykgPC0gYXNOYW1lc3BhY2UoJ3RleHJlZycpDQojIA0KIyAjIGxpYnJhcnkodGV4cmVnKQ0KIyBjdXN0b21fdGV4cmVnKGwgPSBtb2RlbF9saXN0LA0KIyAgICAgICAgICAgICAgIGZpbGUgPSAiLi4vb3V0cHV0L2l2cmVzdWx0c19kZW1vYy50ZXgiLA0KIyAgICAgICAgIHN0YXJzID0gYygwLjAwMSwgMC4wMSwgMC4wNSwgMC4xKSwNCiMgDQojICAgICAgICAgYWRkLmxpbmVzID0gbGlzdChjKCJLbGVpYmVyZ2VuLVBhYXAgcmsgV2FsZCBGIHN0YXRpc3RpYyIsDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0MC42NTEiLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNDAuNjUxIiksDQojICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJBZGouIFIkXjIkIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQoc3VtbWFyeShkZW1vY19wY2huZ19pdikkYWRqLnIuc3F1YXJlZCwgMiksDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKHN1bW1hcnkoZGVtb2NfZmhjaG5nX2l2KSRhZGouci5zcXVhcmVkLCAyKSkpLA0KIyAgICAgICAgIHN5bWJvbCA9ICIrIiwNCiMgICAgICAgICB0YWJsZSA9IEYsDQojICAgICAgICAgYm9va3RhYnMgPSBULA0KIyAgICAgICAgIHVzZS5wYWNrYWdlcyA9IEYsDQojICAgICAgICAgZGNvbHVtbiA9IFQsDQojICAgICAgICAgY3VzdG9tLm1vZGVsLm5hbWVzID0gYygiKDEpIFBvbGl0eSIsDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKDIpIEZyZWVkb20gSG91c2UiKSwNCiMgDQojICAgICAgICAgY3VzdG9tLmNvZWYubWFwID0gbmFtZV9tYXAsDQojIA0KIyAgICAgICAgIGluY2x1ZGUubHIgPSBGLA0KIyAgICAgICAgIGluY2x1ZGUucnNxdWFyZWQgPSBGLA0KIyAgICAgICAgIGluY2x1ZGUuYWRqcnMgPSBGKQ0KDQoNCiMgUmVwbGljYXRpb24gQXJjaGl2ZSBPdXRwdXQNCnRleHJlZzo6aHRtbHJlZyhsID0gbW9kZWxfbGlzdCwNCiAgICAgICAgc3RhcnMgPSBjKDAuMDAxLCAwLjAxLCAwLjA1LCAwLjEpLA0KICAgICAgICBzeW1ib2wgPSAiKyIsDQogICAgICAgIHRhYmxlID0gRiwNCiAgICAgICAgYm9va3RhYnMgPSBULA0KICAgICAgICB1c2UucGFja2FnZXMgPSBGLA0KICAgICAgICBjYXB0aW9uID0gIiIsIA0KICAgICAgICBkY29sdW1uID0gVCwNCiAgICAgICAgY3VzdG9tLm1vZGVsLm5hbWVzID0gYygiKDEpIFBvbGl0eSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMikgRnJlZWRvbSBIb3VzZSIpLA0KICAgICAgICAjIGN1c3RvbS5jb2VmLm1hcCA9IG5hbWVfbWFwLA0KICAgICAgICBjdXN0b20uY29lZi5uYW1lcyA9IHJvciRjY24sIA0KICAgICAgICBvbWl0LmNvZWYgPSByb3Ikb2MsDQogICAgICAgIHJlb3JkZXIuY29lZiA9IHVuaXF1ZShyb3IkcmMpLA0KICAgICAgICBzdGFyLnN5bWJvbCA9ICJcXCoiLCANCiAgICAgICAgaW5jbHVkZS5sciA9IEYpDQpgYGA=