library(tidyverse)
library(ggstance)
library(broom)
library(countrycode)
library(pander)
library(stargazer)
library(skimr)
library(here)
# By default, R uses polynomial contrasts for ordered factors in linear models
# options("contrasts")
# So make ordered factors use treatment contrasts instead
options(contrasts = rep("contr.treatment", 2))
# Or do it on a single variable:
# contrasts(df$x) <- "contr.treatment"
# Load pre-cleaned data
edb_clean <- read_rds(file.path(here(), "output", "data", "edb_clean.rds"))
edb_reforms <- read_rds(file.path(here(), "output", "data", "edb_reforms.rds"))
# Load helpful functions
source(file.path(here(), "lib", "model_stuff.R"))
source(file.path(here(), "lib", "graphics_stuff.R"))
Variable descriptions
Description of variables used in analysis
sb_days |
Number of days required to start a business |
World Bank |
sb_cost |
Cost (% of income per capita) of starting a business |
World Bank |
sb_capital |
Paid-in minimum capital (% of income per capita) required to start a business |
World Bank |
sb_proced |
Number of procedures required for an entrepreneur to legally operate a business |
World Bank |
con_proced |
Number of procedures required to resolve a dispute |
World Bank |
con_days |
Number of days required for the process of dispute resolution |
World Bank |
gdp |
GDP (constant 2005 USD) |
World Development Indicators |
gdpcap |
GDP per capita |
World Development Indicators |
gdpgrowth |
GDP growth |
World Development Indicators |
pop_ln |
Log of population |
World Development Indicators |
polity |
Polity IV score |
Polity IV Project |
inttot |
Magnitude of international conflict |
Center for Systemic Peace |
civtot |
Magnitude of civil conflict |
Center for Systemic Peace |
loan_ln |
Log of the sum of all loans from the IBRD since 2005, constant for all years |
|
Variable summaries
The small inline histograms in this table will only display correctly when they use a font that supports block elements, such as DejaVu Sans or Arial.
edb_summary_stats <- edb_clean %>%
select(one_of(edb_summary_base$Variable)) %>%
gather(Variable, value) %>%
filter(!is.na(value)) %>%
group_by(Variable) %>%
summarize(N = n(),
Mean = mean(value),
`Std. Dev` = sd(value),
Min = min(value),
Max = max(value),
Distribution = inline_hist(value))
edb_summary <- edb_summary_base %>%
left_join(edb_summary_stats, by = "Variable") %>%
mutate(Variable = paste0("`", Variable, "`")) %>%
select(-Definition, -Source)
caption <- "Summary statistics of variables used in analysis"
tbl_edb_summary <- pandoc.table.return(edb_summary, caption = caption,
big.mark = ",", split.tables = Inf,
justify = "lcccccc")
cat(tbl_edb_summary)
Summary statistics of variables used in analysis
sb_days |
2,368 |
39.55 |
52.8 |
0.5 |
697 |
▇▁▁▁▁▁▁▁ |
sb_cost |
2,368 |
57.27 |
123.1 |
0 |
1,540 |
▇▁▁▁▁▁▁▁ |
sb_capital |
2,258 |
114.2 |
434.5 |
0 |
7,445 |
▇▁▁▁▁▁▁▁ |
sb_proced |
2,368 |
8.55 |
3.474 |
1 |
20 |
▂▃▇▅▃▂▁▁ |
con_proced |
2,339 |
36.77 |
8.006 |
0 |
62 |
▁▁▁▃▇▇▂▁ |
con_days |
2,338 |
590.8 |
313.3 |
7 |
1,800 |
▂▆▇▃▁▁▁▁ |
gdp |
2,468 |
264,872,882,270 |
1,122,476,616,993 |
97,813,220 |
14,450,329,106,512 |
▇▁▁▁▁▁▁▁ |
gdpcap |
2,480 |
10,591 |
16,385 |
108 |
113,739 |
▇▁▁▁▁▁▁▁ |
gdpgrowth |
2,468 |
2.476 |
5.478 |
-62.47 |
102.8 |
▁▁▂▇▁▁▁▁ |
pop_ln |
2,512 |
15.56 |
2.068 |
9.861 |
21.03 |
▁▂▂▆▇▅▂▁ |
polity |
2,138 |
3.918 |
6.238 |
-10 |
10 |
▁▂▁▂▁▂▃▇ |
inttot |
2,182 |
0.06279 |
0.4875 |
0 |
6 |
▇▁▁▁▁▁▁▁ |
civtot |
2,182 |
0.4216 |
1.279 |
0 |
9 |
▇▁▁▁▁▁▁▁ |
loan_ln |
3,016 |
13.97 |
10.78 |
0 |
26.46 |
▇▁▁▁▁▂▇▃ |
List of countries in initial 2001 report
* indicates country has an EDB reform committee by 2015
edb_bureaus <- read_csv(file.path(here(), "output", "data", "edb_bureaus.csv"))
country_names <- edb_clean %>%
filter(in_2001 == 1) %>%
group_by(ccode) %>%
summarize(Country = first(country_name)) %>%
ungroup() %>%
mutate(has_committee = ifelse(ccode %in% edb_bureaus$cowcode, "\\*", "")) %>%
arrange(Country) %>%
mutate(Country = paste0(Country, has_committee)) %>%
select(Country)
caption <- "Countries in 2001 report"
tbl_countries <- pandoc.table.return(matrix(c(country_names$Country, rep(NA, 2)),
ncol = 4), caption = caption,
split.tables = Inf, missing = "", justify = "llll")
cat(tbl_countries)
Countries in 2001 report
Albania |
Ecuador |
Madagascar |
Slovakia |
Algeria* |
Egypt |
Malawi* |
Slovenia |
Argentina |
Ethiopia |
Malaysia* |
South Africa |
Armenia |
Finland |
Mali* |
South Korea* |
Australia |
France |
Mexico* |
Spain |
Austria |
Georgia* |
Moldova* |
Sri Lanka* |
Azerbaijan* |
Germany |
Mongolia |
Sweden |
Bangladesh |
Ghana |
Morocco* |
Switzerland |
Belarus |
Greece |
Mozambique |
Syria |
Belgium |
Guatemala* |
Nepal |
Taiwan |
Benin |
Honduras |
Netherlands |
Tanzania |
Bhutan |
Hong Kong SAR China |
New Zealand |
Thailand |
Bolivia |
Hungary |
Nicaragua |
Tunisia |
Bosnia & Herzegovina |
India |
Niger |
Turkey |
Botswana* |
Indonesia* |
Nigeria* |
Uganda |
Bulgaria |
Iran |
Norway |
Ukraine* |
Burkina Faso |
Ireland |
Pakistan |
United Arab Emirates* |
Cameroon |
Israel |
Panama* |
United Kingdom* |
Canada |
Italy |
Peru* |
United States |
Chile* |
Jamaica |
Philippines* |
Uruguay |
China |
Japan |
Poland* |
Uzbekistan* |
Colombia* |
Jordan |
Portugal |
Venezuela |
Costa Rica* |
Kazakhstan* |
Romania |
Vietnam |
Côte d’Ivoire* |
Kenya* |
Russia* |
Yemen |
Croatia* |
Kyrgyzstan* |
Saudi Arabia* |
Zambia* |
Czechia* |
Latvia |
Senegal |
Zimbabwe |
Denmark |
Lebanon |
Serbia |
|
Dominican Republic* |
Lithuania |
Singapore |
|
How control variables relate to being in the sample and to the outcomes
Model A1
edb_in_2001 <- edb_clean %>%
filter(year > 2000) %>%
group_by(ccode) %>%
mutate(in_2001_lead = lead(in_2001),
in_2001_lead = factor(in_2001_lead, levels = 0:1,
labels = c("Not in 2001", "In 2001")))
model_in_2001 <- glm(in_2001_lead ~ gdpcap_ln + gdpgrowth + polity + pop_ln +
inttot + civtot + loan_ln,
data = edb_in_2001, family = binomial(link = "logit"))
model_in_2001_robust <- robust_clusterify(model_in_2001, edb_in_2001, "ccode") %>%
magrittr::use_series(coefs) %>% tidy()
model_in_2001_out <- stargazer(model_in_2001, type = "html", dep.var.caption = "",
dep.var.labels = "in\\_2001\\_lead",
se = list(model_in_2001_robust$std.error),
notes = c("Logistic regression model. Robust standard errors clustered by country.",
"Models include countries present in the 2001 EDB report."))
|
|
in_2001_lead
|
|
gdpcap_ln
|
0.688**
|
|
(0.268)
|
|
|
gdpgrowth
|
0.012
|
|
(0.024)
|
|
|
polity
|
0.124***
|
|
(0.040)
|
|
|
pop_ln
|
1.635***
|
|
(0.479)
|
|
|
inttot
|
-0.527*
|
|
(0.307)
|
|
|
civtot
|
-0.586**
|
|
(0.251)
|
|
|
loan_ln
|
0.037
|
|
(0.035)
|
|
|
Constant
|
-31.163***
|
|
(9.261)
|
|
|
|
Observations
|
1,921
|
Log Likelihood
|
-678.778
|
Akaike Inf. Crit.
|
1,373.555
|
|
Note:
|
*p<0.1; **p<0.05; ***p<0.01
|
|
Logistic regression model. Robust standard errors clustered by country.
|
|
Models include countries present in the 2001 EDB report.
|
Models A2–A5
# This function generates an R formula based on a given outcome and its lead.
# Given "sb_days_ln", it will create and run "sb_days_ln_lead ~ sb_days_ln + ..."
run_leaded_ols_check <- function(outcome, df) {
outcome_lead <- paste0(outcome, "_lead")
form <- as.formula(paste0(outcome_lead, " ~ ", outcome,
" + gdpcap_ln + gdpgrowth + polity + ",
"pop_ln + inttot + civtot + loan_ln"))
lm(form, data = df)
}
# Define all the models that need to be run
models_to_run <- data_frame(outcome = c("sb_days_ln", "sb_proced",
"sb_cost_ln", "sb_capital_ln"),
grouping = 1) # Temporary variable for joining
edb_checks <- edb_clean %>%
filter(year > 2000, in_2001 == 1) %>%
mutate(grouping = 1) %>%
group_by(ccode) %>%
mutate_at(vars(sb_days_ln, sb_proced, sb_cost_ln, sb_capital_ln),
funs(lead = lead(.))) %>%
group_by(grouping) %>%
nest() %>%
right_join(models_to_run, by = "grouping")
# Run all the models within the data frame
edb_checks_models <- edb_checks %>%
mutate(model = pmap(.l = list(outcome, data), run_leaded_ols_check),
# Add robust clustered SEs
robust_se = pmap(.l = list(model, data, "ccode"), robust_clusterify),
# Add a data frame of model parameters with correct SEs
tidy_robust = robust_se %>% map(~ tidy(.$coef)),
ses_only = tidy_robust %>% map(~ .$std.error))
edb_checks_models_out <- stargazer(edb_checks_models$model, type = "html",
dep.var.caption = "",
se = edb_checks_models$ses_only,
notes = c("OLS models. Robust standard errors clustered by country.",
"Models include countries present in the 2001 EDB report."),
keep.stat = c("n", "rsq", "adj.rsq"))
|
|
sb_days_ln_lead
|
sb_proced_lead
|
sb_cost_ln_lead
|
sb_capital_ln_lead
|
|
(1)
|
(2)
|
(3)
|
(4)
|
|
sb_days_ln
|
0.911***
|
|
|
|
|
(0.014)
|
|
|
|
|
|
|
|
|
sb_proced
|
|
0.929***
|
|
|
|
|
(0.015)
|
|
|
|
|
|
|
|
sb_cost_ln
|
|
|
0.941***
|
|
|
|
|
(0.010)
|
|
|
|
|
|
|
sb_capital_ln
|
|
|
|
0.915***
|
|
|
|
|
(0.011)
|
|
|
|
|
|
gdpcap_ln
|
-0.025**
|
-0.045
|
-0.051***
|
-0.042*
|
|
(0.011)
|
(0.044)
|
(0.013)
|
(0.023)
|
|
|
|
|
|
gdpgrowth
|
-0.007***
|
-0.020***
|
-0.014***
|
-0.004
|
|
(0.002)
|
(0.007)
|
(0.002)
|
(0.006)
|
|
|
|
|
|
polity
|
0.0002
|
0.003
|
0.003*
|
0.012***
|
|
(0.001)
|
(0.006)
|
(0.001)
|
(0.004)
|
|
|
|
|
|
pop_ln
|
0.011
|
0.074***
|
0.011*
|
0.007
|
|
(0.007)
|
(0.025)
|
(0.006)
|
(0.014)
|
|
|
|
|
|
inttot
|
-0.006
|
0.039
|
0.011
|
-0.003
|
|
(0.015)
|
(0.062)
|
(0.010)
|
(0.027)
|
|
|
|
|
|
civtot
|
0.006
|
0.021
|
0.003
|
-0.004
|
|
(0.005)
|
(0.030)
|
(0.007)
|
(0.017)
|
|
|
|
|
|
loan_ln
|
-0.001
|
0.002
|
-0.001
|
-0.003
|
|
(0.001)
|
(0.006)
|
(0.001)
|
(0.003)
|
|
|
|
|
|
Constant
|
0.247
|
-0.533
|
0.359**
|
0.232
|
|
(0.168)
|
(0.537)
|
(0.166)
|
(0.319)
|
|
|
|
|
|
|
Observations
|
1,310
|
1,310
|
1,310
|
1,209
|
R2
|
0.887
|
0.912
|
0.957
|
0.895
|
Adjusted R2
|
0.887
|
0.911
|
0.957
|
0.894
|
|
Note:
|
*p<0.1; **p<0.05; ***p<0.01
|
|
OLS models. Robust standard errors clustered by country.
|
|
Models include countries present in the 2001 EDB report.
|
Starting a Business indicators
Not generated with this script.
Enforcing Contracts indicators
Not generated with this script.
Country fixed effects for OLS models
Table D1: “Ranked” coefficients with and without country fixed effects
# All the FE models to be run
country_fe_models <- expand.grid(outcome = c("sb_proced", "sb_days_ln",
"sb_cost_ln", "sb_capital_ln",
"con_proced", "con_days"),
controls = c("Main",
"Main + `civtot_lag` + `inttot_lag` + `loan_ln_lag`",
"Main + `civtot_lag` + `inttot_lag` + `loan_bin_lag`",
"Main + fixed effects",
"Main - 2001", "Main - 2001 & 2002"),
stringsAsFactors = FALSE) %>%
mutate(country_fe = controls %in% c("Main + fixed effects", "Main - 2001", "Main - 2001 & 2002"),
df_to_use = case_when(
controls == "Main - 2001" ~ "Drop 2001",
controls == "Main - 2001 & 2002" ~ "Drop 2002",
TRUE ~ "Full"
))
# Nest filtered data into a data frame
data_to_use <- tribble(
~df_to_use, ~data,
"Full", edb_clean %>% filter(year > 2000, in_2004 == 1),
"Drop 2001", edb_clean %>% filter(year > 2001, in_2004 == 1),
"Drop 2002", edb_clean %>% filter(year > 2002, in_2004 == 1)
)
# Combine filtered data with all model parameters
country_fe_models_full <- data_to_use %>%
right_join(country_fe_models, by = "df_to_use") %>%
select(-df_to_use)
# Build and run a bunch of different models based on parameters that determine
# what controls to add and whether or not to include country fixed effects
run_country_fe_models <- function(outcome, controls, country_fe, df) {
main_controls <- "gdpcap_ln_lag + gdpgrowth_lag + polity_lag + pop_ln_lag"
if (str_detect(controls, "loan_ln_lag")) {
additional_controls <- " + civtot_lag + inttot_lag + loan_ln_lag"
} else if (str_detect(controls, "loan_bin_lag")) {
additional_controls <- " + civtot_lag + inttot_lag + loan_bin_lag"
} else {
additional_controls <- ""
}
if (country_fe) {
country <- " + as.factor(ccode)"
} else {
country <- ""
}
form <- paste0(outcome, " ~ ", paste0(outcome, "_lag"), " + ranked_lag + ",
main_controls, additional_controls, country) %>%
as.formula()
lm(form, data = df)
}
# Run all the models within the data frame
country_fe_models_all <- country_fe_models_full %>%
mutate(model = pmap(.l = list(outcome, controls, country_fe, data),
run_country_fe_models),
# Add robust clustered SEs
robust_se = pmap(.l = list(model, data, "ccode"), robust_clusterify),
# Add model summary statistics
glance = model %>% map(glance),
# Add a data frame of model parameters with correct SEs
tidy_robust = robust_se %>% map(~ tidy(.$coef)),
ses_only = tidy_robust %>% map(~ .$std.error))
# Make tiny data frame indicating if model had country fixed effects
fixed_effects_country <- country_fe_models %>%
select(controls, country_fe) %>%
distinct() %>%
mutate(country_fe = ifelse(country_fe, "Yes", "No")) %>%
spread(controls, country_fe) %>%
mutate(Outcome = "Fixed country effects")
# Display all the ranked coefficients
ranked_coefs_country <- country_fe_models_all %>%
# Spread out the model results
unnest(tidy_robust) %>%
filter(str_detect(term, "ranked")) %>%
# Clean up the estimates and add stars
mutate(value = paste0(sprintf("%.3f", round(estimate, 3)), p_stars(p.value)),
outcome = factor(outcome, levels = unique(country_fe_models$outcome),
labels = paste0("`", unique(country_fe_models$outcome), "`"),
ordered = TRUE),
controls = factor(controls, levels = unique(country_fe_models$controls),
ordered = TRUE)) %>%
# Get rid of extra columns
select(Outcome = outcome, controls, value) %>%
spread(controls, value) %>%
bind_rows(fixed_effects_country)
Summary of coefficients for the lagged “Ranked” variable with and without country fixed effects
sb_proced |
-0.233*** |
-0.247*** |
-0.251*** |
-0.237** |
-0.237** |
-0.225** |
sb_days_ln |
-0.029 |
-0.027 |
-0.029 |
-0.061** |
-0.061** |
-0.057** |
sb_cost_ln |
-0.074*** |
-0.078*** |
-0.079*** |
-0.064** |
-0.064** |
-0.046* |
sb_capital_ln |
-0.003 |
0.005 |
0.003 |
-0.032 |
-0.032 |
-0.032 |
con_proced |
-1.339*** |
-1.293*** |
-1.279*** |
-0.045 |
-0.045 |
-0.204*** |
con_days |
-67.590*** |
-67.839*** |
-67.357*** |
-9.040* |
-9.040* |
-14.108** |
Fixed country effects |
No |
No |
No |
Yes |
Yes |
Yes |
Note: Main controls are gdpcap_ln_lag
, gdpgrowth_lag
, polity_lag
, and pop_ln_lag
Table D2: Sub-indicators for “Starting a Business” with and without country fixed effects
sb_fe <- country_fe_models_all %>%
filter(str_detect(outcome, "sb_"),
controls %in% c("Main + fixed effects",
"Main + `civtot_lag` + `inttot_lag` + `loan_bin_lag`")) %>%
mutate(outcome = fct_inorder(outcome, ordered = TRUE)) %>%
arrange(outcome)
sb_country_fe_models_out <- stargazer(sb_fe$model, type = "html",
dep.var.caption = "",
se = sb_fe$ses_only,
notes = c("OLS models. Robust standard errors clustered by country.",
"Models include countries present in the 2004 EDB report."),
keep.stat = c("n", "rsq", "adj.rsq"),
add.lines = list(c("Country fixed effects",
rep(c("No", "Yes"), 4))),
omit = "ccode")
|
|
sb_proced
|
sb_days_ln
|
sb_cost_ln
|
sb_capital_ln
|
|
(1)
|
(2)
|
(3)
|
(4)
|
(5)
|
(6)
|
(7)
|
(8)
|
|
sb_proced_lag
|
0.920***
|
0.741***
|
|
|
|
|
|
|
|
(0.013)
|
(0.026)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sb_days_ln_lag
|
|
|
0.931***
|
0.751***
|
|
|
|
|
|
|
|
(0.011)
|
(0.022)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sb_cost_ln_lag
|
|
|
|
|
0.948***
|
0.695***
|
|
|
|
|
|
|
|
(0.009)
|
(0.041)
|
|
|
|
|
|
|
|
|
|
|
|
sb_capital_ln_lag
|
|
|
|
|
|
|
0.924***
|
0.742***
|
|
|
|
|
|
|
|
(0.009)
|
(0.025)
|
|
|
|
|
|
|
|
|
|
ranked_lag
|
-0.251***
|
-0.237**
|
-0.029
|
-0.061**
|
-0.079***
|
-0.064**
|
0.003
|
-0.032
|
|
(0.069)
|
(0.096)
|
(0.019)
|
(0.029)
|
(0.018)
|
(0.029)
|
(0.045)
|
(0.063)
|
|
|
|
|
|
|
|
|
|
gdpcap_ln_lag
|
-0.017
|
-0.420***
|
-0.015
|
-0.125***
|
-0.027**
|
-0.232***
|
-0.030*
|
-0.224**
|
|
(0.037)
|
(0.152)
|
(0.009)
|
(0.043)
|
(0.012)
|
(0.044)
|
(0.018)
|
(0.106)
|
|
|
|
|
|
|
|
|
|
gdpgrowth_lag
|
-0.021***
|
-0.008
|
-0.007***
|
-0.005***
|
-0.013***
|
-0.007***
|
-0.008
|
0.002
|
|
(0.006)
|
(0.007)
|
(0.002)
|
(0.002)
|
(0.002)
|
(0.002)
|
(0.005)
|
(0.006)
|
|
|
|
|
|
|
|
|
|
polity_lag
|
-0.005
|
-0.020
|
-0.002
|
-0.005
|
0.0004
|
-0.011*
|
0.004
|
0.018
|
|
(0.006)
|
(0.018)
|
(0.001)
|
(0.005)
|
(0.001)
|
(0.006)
|
(0.004)
|
(0.019)
|
|
|
|
|
|
|
|
|
|
pop_ln_lag
|
0.041*
|
-1.244**
|
0.006
|
-0.172
|
0.008
|
-0.416***
|
-0.009
|
-0.294
|
|
(0.024)
|
(0.540)
|
(0.006)
|
(0.116)
|
(0.005)
|
(0.158)
|
(0.012)
|
(0.688)
|
|
|
|
|
|
|
|
|
|
civtot_lag
|
0.028
|
|
0.004
|
|
0.004
|
|
0.014
|
|
|
(0.026)
|
|
(0.005)
|
|
(0.006)
|
|
(0.014)
|
|
|
|
|
|
|
|
|
|
|
inttot_lag
|
0.076*
|
|
-0.004
|
|
0.031**
|
|
-0.087
|
|
|
(0.041)
|
|
(0.016)
|
|
(0.012)
|
|
(0.118)
|
|
|
|
|
|
|
|
|
|
|
loan_bin_lag
|
0.103
|
|
-0.006
|
|
0.036
|
|
-0.063
|
|
|
(0.119)
|
|
(0.029)
|
|
(0.032)
|
|
(0.058)
|
|
|
|
|
|
|
|
|
|
|
Constant
|
0.038
|
30.747***
|
0.204
|
5.258**
|
0.213
|
10.979***
|
0.432*
|
7.993
|
|
(0.457)
|
(10.189)
|
(0.137)
|
(2.340)
|
(0.159)
|
(3.055)
|
(0.258)
|
(12.806)
|
|
|
|
|
|
|
|
|
|
|
Country fixed effects
|
No
|
Yes
|
No
|
Yes
|
No
|
Yes
|
No
|
Yes
|
Observations
|
1,659
|
1,660
|
1,659
|
1,660
|
1,659
|
1,660
|
1,558
|
1,559
|
R2
|
0.909
|
0.926
|
0.902
|
0.919
|
0.963
|
0.970
|
0.904
|
0.918
|
Adjusted R2
|
0.909
|
0.919
|
0.902
|
0.911
|
0.963
|
0.968
|
0.903
|
0.910
|
|
Note:
|
*p<0.1; **p<0.05; ***p<0.01
|
|
OLS models. Robust standard errors clustered by country.
|
|
Models include countries present in the 2004 EDB report.
|
Table D3: Sub-indicators for “Enforcing Contracts” with and without country fixed effects
con_fe <- country_fe_models_all %>%
filter(str_detect(outcome, "con_"),
controls %in% c("Main + fixed effects",
"Main + `civtot_lag` + `inttot_lag` + `loan_bin_lag`")) %>%
mutate(outcome = fct_inorder(outcome, ordered = TRUE)) %>%
arrange(outcome)
con_country_fe_models_out <- stargazer(con_fe$model, type = "html",
dep.var.caption = "",
se = con_fe$ses_only,
notes = c("OLS models. Robust standard errors clustered by country.",
"Models include countries present in the 2004 EDB report."),
keep.stat = c("n", "rsq", "adj.rsq"),
add.lines = list(c("Country fixed effects",
rep(c("No", "Yes"), 4))),
omit = "ccode")
|
|
con_proced
|
con_days
|
|
(1)
|
(2)
|
(3)
|
(4)
|
|
con_proced_lag
|
0.708***
|
0.379***
|
|
|
|
(0.023)
|
(0.027)
|
|
|
|
|
|
|
|
con_days_lag
|
|
|
0.903***
|
0.451***
|
|
|
|
(0.015)
|
(0.035)
|
|
|
|
|
|
ranked_lag
|
-1.279***
|
-0.045
|
-67.357***
|
-9.040*
|
|
(0.258)
|
(0.122)
|
(5.427)
|
(4.990)
|
|
|
|
|
|
gdpcap_ln_lag
|
-0.383***
|
0.200
|
-5.263
|
3.433
|
|
(0.145)
|
(0.269)
|
(3.237)
|
(7.930)
|
|
|
|
|
|
gdpgrowth_lag
|
-0.038
|
0.011
|
-2.627***
|
-0.920
|
|
(0.024)
|
(0.015)
|
(0.676)
|
(0.589)
|
|
|
|
|
|
polity_lag
|
-0.112***
|
0.044
|
1.219**
|
-0.785
|
|
(0.039)
|
(0.048)
|
(0.525)
|
(1.765)
|
|
|
|
|
|
pop_ln_lag
|
0.023
|
-0.361
|
2.358
|
-48.999
|
|
(0.109)
|
(1.008)
|
(2.561)
|
(33.737)
|
|
|
|
|
|
civtot_lag
|
0.208**
|
|
9.935**
|
|
|
(0.101)
|
|
(4.295)
|
|
|
|
|
|
|
inttot_lag
|
0.292
|
|
-2.168
|
|
|
(0.393)
|
|
(3.915)
|
|
|
|
|
|
|
loan_bin_lag
|
-0.371
|
|
3.842
|
|
|
(0.487)
|
|
(11.148)
|
|
|
|
|
|
|
Constant
|
15.702***
|
24.570
|
124.001***
|
1,127.757*
|
|
(2.421)
|
(18.769)
|
(42.007)
|
(645.682)
|
|
|
|
|
|
|
Country fixed effects
|
No
|
Yes
|
No
|
Yes
|
Observations
|
1,634
|
1,635
|
1,633
|
1,634
|
R2
|
0.725
|
0.830
|
0.868
|
0.924
|
Adjusted R2
|
0.723
|
0.814
|
0.867
|
0.917
|
|
Note:
|
*p<0.1; **p<0.05; ***p<0.01
|
|
OLS models. Robust standard errors clustered by country.
|
|
Models include countries present in the 2004 EDB report.
|
Year fixed effects for OLS models
Table E1: “Ranked” coefficients with and without year fixed effects
# All the FE models to be run
year_fe_models <- expand.grid(outcome = c("sb_proced", "sb_days_ln",
"sb_cost_ln", "sb_capital_ln",
"con_proced", "con_days"),
controls = c("Main",
"Main + `civtot_lag` + `inttot_lag` + `loan_ln_lag`",
"Main + `civtot_lag` + `inttot_lag` + `loan_bin_lag`",
"Main + fixed effects",
"Main - 2001", "Main - 2001 & 2002"),
stringsAsFactors = FALSE) %>%
mutate(year_fe = controls %in% c("Main + fixed effects", "Main - 2001", "Main - 2001 & 2002"),
df_to_use = case_when(
controls == "Main - 2001" ~ "Drop 2001",
controls == "Main - 2001 & 2002" ~ "Drop 2002",
TRUE ~ "Full"
))
# Nest filtered data into a data frame
data_to_use <- tribble(
~df_to_use, ~data,
"Full", edb_clean %>% filter(year > 2000, in_2004 == 1),
"Drop 2001", edb_clean %>% filter(year > 2001, in_2004 == 1),
"Drop 2002", edb_clean %>% filter(year > 2002, in_2004 == 1)
)
# Combine filtered data with all model parameters
year_fe_models_full <- data_to_use %>%
right_join(year_fe_models, by = "df_to_use") %>%
select(-df_to_use)
# Build and run a bunch of different models based on parameters that determine
# what controls to add and whether or not to include country fixed effects
run_year_fe_models <- function(outcome, controls, year_fe, df) {
main_controls <- "gdpcap_ln_lag + gdpgrowth_lag + polity_lag + pop_ln_lag"
if (str_detect(controls, "loan_ln_lag")) {
additional_controls <- " + civtot_lag + inttot_lag + loan_ln_lag"
} else if (str_detect(controls, "loan_bin_lag")) {
additional_controls <- " + civtot_lag + inttot_lag + loan_bin_lag"
} else {
additional_controls <- ""
}
if (year_fe) {
year <- " + as.factor(year)"
} else {
year <- ""
}
form <- paste0(outcome, " ~ ", paste0(outcome, "_lag"), " + ranked_lag + ",
main_controls, additional_controls, year) %>%
as.formula()
lm(form, data = df)
}
# Run all the models within the data frame
year_fe_models_all <- year_fe_models_full %>%
mutate(model = pmap(.l = list(outcome, controls, year_fe, data),
run_year_fe_models),
# Add robust clustered SEs
robust_se = pmap(.l = list(model, data, "ccode"), robust_clusterify),
# Add model summary statistics
glance = model %>% map(glance),
# Add a data frame of model parameters with correct SEs
tidy_robust = robust_se %>% map(~ tidy(.$coef)),
ses_only = tidy_robust %>% map(~ .$std.error))
# Make tiny data frame indicating if model had country fixed effects
fixed_effects_year <- year_fe_models %>%
select(controls, year_fe) %>%
distinct() %>%
mutate(year_fe = ifelse(year_fe, "Yes", "No")) %>%
spread(controls, year_fe) %>%
mutate(Outcome = "Fixed year effects")
# Display all the ranked coefficients
ranked_coefs_year <- year_fe_models_all %>%
# Spread out the model results
unnest(tidy_robust) %>%
filter(str_detect(term, "ranked")) %>%
# Clean up the estimates and add stars
mutate(value = paste0(sprintf("%.3f", round(estimate, 3)), p_stars(p.value)),
outcome = factor(outcome, levels = unique(year_fe_models$outcome),
labels = paste0("`", unique(year_fe_models$outcome), "`"),
ordered = TRUE),
controls = factor(controls, levels = unique(year_fe_models$controls),
ordered = TRUE)) %>%
# Get rid of extra columns
select(Outcome = outcome, controls, value) %>%
spread(controls, value) %>%
bind_rows(fixed_effects_year)
Summary of coefficients for the lagged “Ranked” variable with and without country fixed effects
sb_proced |
-0.233*** |
-0.247*** |
-0.251*** |
0.102 |
0.102 |
0.109 |
sb_days_ln |
-0.029 |
-0.027 |
-0.029 |
0.053 |
0.053 |
0.058 |
sb_cost_ln |
-0.074*** |
-0.078*** |
-0.079*** |
0.033 |
0.033 |
0.034 |
sb_capital_ln |
-0.003 |
0.005 |
0.003 |
0.320 |
0.320 |
0.320 |
con_proced |
-1.339*** |
-1.293*** |
-1.279*** |
0.348 |
0.348 |
0.395 |
con_days |
-67.590*** |
-67.839*** |
-67.357*** |
-1.605 |
-1.605 |
-1.585 |
Fixed year effects |
No |
No |
No |
Yes |
Yes |
Yes |
Note: Main controls are gdpcap_ln_lag
, gdpgrowth_lag
, polity_lag
, and pop_ln_lag
Table E2: Sub-indicators for “Starting a Business” with and without year fixed effects
sb_fe_year <- year_fe_models_all %>%
filter(str_detect(outcome, "sb_"),
controls %in% c("Main + fixed effects",
"Main + `civtot_lag` + `inttot_lag` + `loan_bin_lag`")) %>%
mutate(outcome = fct_inorder(outcome, ordered = TRUE)) %>%
arrange(outcome)
sb_year_fe_models_out <- stargazer(sb_fe_year$model, type = "html",
dep.var.caption = "",
se = sb_fe_year$ses_only,
notes = c("OLS models. Robust standard errors clustered by country.",
"Models include countries present in the 2004 EDB report."),
keep.stat = c("n", "rsq", "adj.rsq"),
add.lines = list(c("Year fixed effects",
rep(c("No", "Yes"), 4))),
omit = "year")
|
|
sb_proced
|
sb_days_ln
|
sb_cost_ln
|
sb_capital_ln
|
|
(1)
|
(2)
|
(3)
|
(4)
|
(5)
|
(6)
|
(7)
|
(8)
|
|
sb_proced_lag
|
0.920***
|
0.920***
|
|
|
|
|
|
|
|
(0.013)
|
(0.015)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sb_days_ln_lag
|
|
|
0.931***
|
0.932***
|
|
|
|
|
|
|
|
(0.011)
|
(0.012)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sb_cost_ln_lag
|
|
|
|
|
0.948***
|
0.950***
|
|
|
|
|
|
|
|
(0.009)
|
(0.009)
|
|
|
|
|
|
|
|
|
|
|
|
sb_capital_ln_lag
|
|
|
|
|
|
|
0.924***
|
0.926***
|
|
|
|
|
|
|
|
(0.009)
|
(0.009)
|
|
|
|
|
|
|
|
|
|
ranked_lag
|
-0.251***
|
0.102
|
-0.029
|
0.053
|
-0.079***
|
0.033
|
0.003
|
0.320
|
|
(0.069)
|
(0.335)
|
(0.019)
|
(0.083)
|
(0.018)
|
(0.052)
|
(0.045)
|
(0.281)
|
|
|
|
|
|
|
|
|
|
gdpcap_ln_lag
|
-0.017
|
-0.038*
|
-0.015
|
-0.014**
|
-0.027**
|
-0.032***
|
-0.030*
|
-0.017
|
|
(0.037)
|
(0.022)
|
(0.009)
|
(0.006)
|
(0.012)
|
(0.009)
|
(0.018)
|
(0.012)
|
|
|
|
|
|
|
|
|
|
gdpgrowth_lag
|
-0.021***
|
-0.020***
|
-0.007***
|
-0.007***
|
-0.013***
|
-0.011***
|
-0.008
|
-0.009*
|
|
(0.006)
|
(0.006)
|
(0.002)
|
(0.002)
|
(0.002)
|
(0.002)
|
(0.005)
|
(0.005)
|
|
|
|
|
|
|
|
|
|
polity_lag
|
-0.005
|
-0.006
|
-0.002
|
-0.002*
|
0.0004
|
0.0001
|
0.004
|
0.004
|
|
(0.006)
|
(0.006)
|
(0.001)
|
(0.001)
|
(0.001)
|
(0.001)
|
(0.004)
|
(0.004)
|
|
|
|
|
|
|
|
|
|
pop_ln_lag
|
0.041*
|
0.058**
|
0.006
|
0.008*
|
0.008
|
0.011**
|
-0.009
|
-0.003
|
|
(0.024)
|
(0.023)
|
(0.006)
|
(0.005)
|
(0.005)
|
(0.005)
|
(0.012)
|
(0.011)
|
|
|
|
|
|
|
|
|
|
civtot_lag
|
0.028
|
|
0.004
|
|
0.004
|
|
0.014
|
|
|
(0.026)
|
|
(0.005)
|
|
(0.006)
|
|
(0.014)
|
|
|
|
|
|
|
|
|
|
|
inttot_lag
|
0.076*
|
|
-0.004
|
|
0.031**
|
|
-0.087
|
|
|
(0.041)
|
|
(0.016)
|
|
(0.012)
|
|
(0.118)
|
|
|
|
|
|
|
|
|
|
|
loan_bin_lag
|
0.103
|
|
-0.006
|
|
0.036
|
|
-0.063
|
|
|
(0.119)
|
|
(0.029)
|
|
(0.032)
|
|
(0.058)
|
|
|
|
|
|
|
|
|
|
|
Constant
|
0.038
|
-0.095
|
0.204
|
0.112
|
0.213
|
0.257*
|
0.432*
|
-0.004
|
|
(0.457)
|
(0.426)
|
(0.137)
|
(0.121)
|
(0.159)
|
(0.140)
|
(0.258)
|
(0.238)
|
|
|
|
|
|
|
|
|
|
|
Year fixed effects
|
No
|
Yes
|
No
|
Yes
|
No
|
Yes
|
No
|
Yes
|
Observations
|
1,659
|
1,660
|
1,659
|
1,660
|
1,659
|
1,660
|
1,558
|
1,559
|
R2
|
0.909
|
0.910
|
0.902
|
0.903
|
0.963
|
0.963
|
0.904
|
0.906
|
Adjusted R2
|
0.909
|
0.909
|
0.902
|
0.902
|
0.963
|
0.963
|
0.903
|
0.905
|
|
Note:
|
*p<0.1; **p<0.05; ***p<0.01
|
|
OLS models. Robust standard errors clustered by country.
|
|
Models include countries present in the 2004 EDB report.
|
Table E3: Sub-indicators for “Enforcing Contracts” with and without year fixed effects
con_fe_year <- year_fe_models_all %>%
filter(str_detect(outcome, "con_"),
controls %in% c("Main + fixed effects",
"Main + `civtot_lag` + `inttot_lag` + `loan_bin_lag`")) %>%
mutate(outcome = fct_inorder(outcome, ordered = TRUE)) %>%
arrange(outcome)
con_year_fe_models_out <- stargazer(con_fe_year$model, type = "html",
dep.var.caption = "",
se = con_fe_year$ses_only,
notes = c("OLS models. Robust standard errors clustered by country.",
"Models include countries present in the 2004 EDB report."),
keep.stat = c("n", "rsq", "adj.rsq"),
add.lines = list(c("Year fixed effects",
rep(c("No", "Yes"), 4))),
omit = "year")
|
|
con_proced
|
con_days
|
|
(1)
|
(2)
|
(3)
|
(4)
|
|
con_proced_lag
|
0.708***
|
0.780***
|
|
|
|
(0.023)
|
(0.032)
|
|
|
|
|
|
|
|
con_days_lag
|
|
|
0.903***
|
0.971***
|
|
|
|
(0.015)
|
(0.008)
|
|
|
|
|
|
ranked_lag
|
-1.279***
|
0.348
|
-67.357***
|
-1.605
|
|
(0.258)
|
(0.506)
|
(5.427)
|
(3.386)
|
|
|
|
|
|
gdpcap_ln_lag
|
-0.383***
|
-0.167
|
-5.263
|
-3.550**
|
|
(0.145)
|
(0.104)
|
(3.237)
|
(1.559)
|
|
|
|
|
|
gdpgrowth_lag
|
-0.038
|
-0.016
|
-2.627***
|
-1.292***
|
|
(0.024)
|
(0.025)
|
(0.676)
|
(0.463)
|
|
|
|
|
|
polity_lag
|
-0.112***
|
-0.083**
|
1.219**
|
0.573
|
|
(0.039)
|
(0.032)
|
(0.525)
|
(0.376)
|
|
|
|
|
|
pop_ln_lag
|
0.023
|
0.124
|
2.358
|
3.673**
|
|
(0.109)
|
(0.087)
|
(2.561)
|
(1.839)
|
|
|
|
|
|
civtot_lag
|
0.208**
|
|
9.935**
|
|
|
(0.101)
|
|
(4.295)
|
|
|
|
|
|
|
inttot_lag
|
0.292
|
|
-2.168
|
|
|
(0.393)
|
|
(3.915)
|
|
|
|
|
|
|
loan_bin_lag
|
-0.371
|
|
3.842
|
|
|
(0.487)
|
|
(11.148)
|
|
|
|
|
|
|
Constant
|
15.702***
|
4.800***
|
124.001***
|
17.250
|
|
(2.421)
|
(1.757)
|
(42.007)
|
(35.766)
|
|
|
|
|
|
|
Year fixed effects
|
No
|
Yes
|
No
|
Yes
|
Observations
|
1,634
|
1,635
|
1,633
|
1,634
|
R2
|
0.725
|
0.836
|
0.868
|
0.923
|
Adjusted R2
|
0.723
|
0.834
|
0.867
|
0.922
|
|
Note:
|
*p<0.1; **p<0.05; ***p<0.01
|
|
OLS models. Robust standard errors clustered by country.
|
|
Models include countries present in the 2004 EDB report.
|
India experiment survey text
Not generated with this script.
Investor experiment survey text
Not generated with this script.
LS0tCnRpdGxlOiAiQXBwZW5kaXggYW5hbHlzaXMiCmF1dGhvcjogIkFuZHJldyBIZWlzcyIKZGF0ZTogIkxhc3QgcnVuOiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCICVlLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgbWVzc2FnZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGNhY2hlID0gRkFMU0UsIGZpZy5yZXRpbmEgPSAyLAogICAgICAgICAgICAgICAgICAgICAgdGlkeS5vcHRzID0gbGlzdCh3aWR0aC5jdXRvZmYgPSAxMjApLCAgIyBGb3IgY29kZQogICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAxMjApICAjIEZvciBvdXRwdXQKYGBgCgpgYGB7ciBsb2FkLWxpYnJhcmllcy1kYXRhLWZ1bmN0aW9ucywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dzdGFuY2UpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoY291bnRyeWNvZGUpCmxpYnJhcnkocGFuZGVyKQpsaWJyYXJ5KHN0YXJnYXplcikKbGlicmFyeShza2ltcikKbGlicmFyeShoZXJlKQoKIyBCeSBkZWZhdWx0LCBSIHVzZXMgcG9seW5vbWlhbCBjb250cmFzdHMgZm9yIG9yZGVyZWQgZmFjdG9ycyBpbiBsaW5lYXIgbW9kZWxzCiMgb3B0aW9ucygiY29udHJhc3RzIikgCiMgU28gbWFrZSBvcmRlcmVkIGZhY3RvcnMgdXNlIHRyZWF0bWVudCBjb250cmFzdHMgaW5zdGVhZApvcHRpb25zKGNvbnRyYXN0cyA9IHJlcCgiY29udHIudHJlYXRtZW50IiwgMikpCiMgT3IgZG8gaXQgb24gYSBzaW5nbGUgdmFyaWFibGU6CiMgY29udHJhc3RzKGRmJHgpIDwtICJjb250ci50cmVhdG1lbnQiCgojIExvYWQgcHJlLWNsZWFuZWQgZGF0YQplZGJfY2xlYW4gPC0gcmVhZF9yZHMoZmlsZS5wYXRoKGhlcmUoKSwgIm91dHB1dCIsICJkYXRhIiwgImVkYl9jbGVhbi5yZHMiKSkKZWRiX3JlZm9ybXMgPC0gcmVhZF9yZHMoZmlsZS5wYXRoKGhlcmUoKSwgIm91dHB1dCIsICJkYXRhIiwgImVkYl9yZWZvcm1zLnJkcyIpKQoKIyBMb2FkIGhlbHBmdWwgZnVuY3Rpb25zCnNvdXJjZShmaWxlLnBhdGgoaGVyZSgpLCAibGliIiwgIm1vZGVsX3N0dWZmLlIiKSkKc291cmNlKGZpbGUucGF0aChoZXJlKCksICJsaWIiLCAiZ3JhcGhpY3Nfc3R1ZmYuUiIpKQpgYGAKCgojIFZhcmlhYmxlIGRlc2NyaXB0aW9ucwoKYGBge3IgdGJsLXZhcnMtZGVzY3JpcHRpb24sIHJlc3VsdHM9ImFzaXMiLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQplZGJfc3VtbWFyeV9iYXNlIDwtIHJlYWRfY3N2KGZpbGUucGF0aChoZXJlKCksICJkYXRhX3JhdyIsICJ2YXJpYWJsZS1zdW1tYXJ5LWJhc2UuY3N2IikpCgplZGJfdmFyX2Rlc2NyaXB0aW9ucyA8LSBlZGJfc3VtbWFyeV9iYXNlICU+JQogIG11dGF0ZShWYXJpYWJsZSA9IHBhc3RlMCgiYCIsIFZhcmlhYmxlLCAiYCIpKQoKY2FwdGlvbiA8LSAiRGVzY3JpcHRpb24gb2YgdmFyaWFibGVzIHVzZWQgaW4gYW5hbHlzaXMiCgp0YmxfdmFyX2Rlc2NyaXB0aW9ucyA8LSBwYW5kb2MudGFibGUucmV0dXJuKGVkYl92YXJfZGVzY3JpcHRpb25zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0aW9uID0gY2FwdGlvbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQudGFibGVzID0gSW5mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1c3RpZnkgPSAibGxsIiwgbWlzc2luZyA9ICIiKQoKY2F0KHRibF92YXJfZGVzY3JpcHRpb25zKQpjYXQodGJsX3Zhcl9kZXNjcmlwdGlvbnMsIAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV92YXJfZGVzYy5tZCIpKQpgYGAKCgojIFZhcmlhYmxlIHN1bW1hcmllcwoKVGhlIHNtYWxsIGlubGluZSBoaXN0b2dyYW1zIGluIHRoaXMgdGFibGUgd2lsbCBvbmx5IGRpc3BsYXkgY29ycmVjdGx5IHdoZW4gdGhleSB1c2UgYSBmb250IHRoYXQgc3VwcG9ydHMgYmxvY2sgZWxlbWVudHMsIHN1Y2ggYXMgW0RlamFWdSBTYW5zXShodHRwczovL2RlamF2dS1mb250cy5naXRodWIuaW8vKSBvciBBcmlhbC4KCmBgYHtyIHRibC12YXJzLXN1bW1hcnksIHJlc3VsdHM9ImFzaXMiLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQplZGJfc3VtbWFyeV9zdGF0cyA8LSBlZGJfY2xlYW4gJT4lCiAgc2VsZWN0KG9uZV9vZihlZGJfc3VtbWFyeV9iYXNlJFZhcmlhYmxlKSkgJT4lCiAgZ2F0aGVyKFZhcmlhYmxlLCB2YWx1ZSkgJT4lCiAgZmlsdGVyKCFpcy5uYSh2YWx1ZSkpICU+JQogIGdyb3VwX2J5KFZhcmlhYmxlKSAlPiUKICBzdW1tYXJpemUoTiA9IG4oKSwKICAgICAgICAgICAgTWVhbiA9IG1lYW4odmFsdWUpLAogICAgICAgICAgICBgU3RkLiBEZXZgID0gc2QodmFsdWUpLAogICAgICAgICAgICBNaW4gPSBtaW4odmFsdWUpLAogICAgICAgICAgICBNYXggPSBtYXgodmFsdWUpLAogICAgICAgICAgICBEaXN0cmlidXRpb24gPSBpbmxpbmVfaGlzdCh2YWx1ZSkpIAoKZWRiX3N1bW1hcnkgPC0gZWRiX3N1bW1hcnlfYmFzZSAlPiUKICBsZWZ0X2pvaW4oZWRiX3N1bW1hcnlfc3RhdHMsIGJ5ID0gIlZhcmlhYmxlIikgJT4lCiAgbXV0YXRlKFZhcmlhYmxlID0gcGFzdGUwKCJgIiwgVmFyaWFibGUsICJgIikpICU+JQogIHNlbGVjdCgtRGVmaW5pdGlvbiwgLVNvdXJjZSkKCmNhcHRpb24gPC0gIlN1bW1hcnkgc3RhdGlzdGljcyBvZiB2YXJpYWJsZXMgdXNlZCBpbiBhbmFseXNpcyIKCnRibF9lZGJfc3VtbWFyeSA8LSBwYW5kb2MudGFibGUucmV0dXJuKGVkYl9zdW1tYXJ5LCBjYXB0aW9uID0gY2FwdGlvbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpZy5tYXJrID0gIiwiLCBzcGxpdC50YWJsZXMgPSBJbmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1c3RpZnkgPSAibGNjY2NjYyIpCgpjYXQodGJsX2VkYl9zdW1tYXJ5KQpjYXQodGJsX2VkYl9zdW1tYXJ5LCAKICAgIGZpbGUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgInRhYmxlcyIsICJhcHBfdGFibGVfdmFyX3N1bW1hcnkubWQiKSkKYGBgCgoKIyBMaXN0IG9mIGNvdW50cmllcyBpbiBpbml0aWFsIDIwMDEgcmVwb3J0CgpcKiBpbmRpY2F0ZXMgY291bnRyeSBoYXMgYW4gRURCIHJlZm9ybSBjb21taXR0ZWUgYnkgMjAxNQoKYGBge3IgdGJsLWNvdW50cmllcywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iYXNpcyJ9CmVkYl9idXJlYXVzIDwtIHJlYWRfY3N2KGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAiZGF0YSIsICJlZGJfYnVyZWF1cy5jc3YiKSkKCmNvdW50cnlfbmFtZXMgPC0gZWRiX2NsZWFuICU+JQogIGZpbHRlcihpbl8yMDAxID09IDEpICU+JQogIGdyb3VwX2J5KGNjb2RlKSAlPiUgCiAgc3VtbWFyaXplKENvdW50cnkgPSBmaXJzdChjb3VudHJ5X25hbWUpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoaGFzX2NvbW1pdHRlZSA9IGlmZWxzZShjY29kZSAlaW4lIGVkYl9idXJlYXVzJGNvd2NvZGUsICJcXCoiLCAiIikpICU+JQogIGFycmFuZ2UoQ291bnRyeSkgJT4lCiAgbXV0YXRlKENvdW50cnkgPSBwYXN0ZTAoQ291bnRyeSwgaGFzX2NvbW1pdHRlZSkpICU+JQogIHNlbGVjdChDb3VudHJ5KQoKY2FwdGlvbiA8LSAiQ291bnRyaWVzIGluIDIwMDEgcmVwb3J0IgoKdGJsX2NvdW50cmllcyA8LSBwYW5kb2MudGFibGUucmV0dXJuKG1hdHJpeChjKGNvdW50cnlfbmFtZXMkQ291bnRyeSwgcmVwKE5BLCAyKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2wgPSA0KSwgY2FwdGlvbiA9IGNhcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdC50YWJsZXMgPSBJbmYsIG1pc3NpbmcgPSAiIiwganVzdGlmeSA9ICJsbGxsIikKCmNhdCh0YmxfY291bnRyaWVzKQpjYXQodGJsX2NvdW50cmllcywgCiAgICBmaWxlID0gZmlsZS5wYXRoKGhlcmUoKSwgIm91dHB1dCIsICJ0YWJsZXMiLCAiYXBwX3RhYmxlX2NvdW50cmllcy5tZCIpKQpgYGAKCgojIEhvdyBjb250cm9sIHZhcmlhYmxlcyByZWxhdGUgdG8gYmVpbmcgaW4gdGhlIHNhbXBsZSBhbmQgdG8gdGhlIG91dGNvbWVzCgojIyBNb2RlbCBBMQoKYGBge3IgbW9kZWwtaW4tMjAwMSwgcmVzdWx0cz0iaGlkZSJ9CmVkYl9pbl8yMDAxIDwtIGVkYl9jbGVhbiAlPiUKICBmaWx0ZXIoeWVhciA+IDIwMDApICU+JQogIGdyb3VwX2J5KGNjb2RlKSAlPiUKICBtdXRhdGUoaW5fMjAwMV9sZWFkID0gbGVhZChpbl8yMDAxKSwKICAgICAgICAgaW5fMjAwMV9sZWFkID0gZmFjdG9yKGluXzIwMDFfbGVhZCwgbGV2ZWxzID0gMDoxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk5vdCBpbiAyMDAxIiwgIkluIDIwMDEiKSkpCgptb2RlbF9pbl8yMDAxIDwtIGdsbShpbl8yMDAxX2xlYWQgfiBnZHBjYXBfbG4gKyBnZHBncm93dGggKyBwb2xpdHkgKyBwb3BfbG4gKyAKICAgICAgICAgICAgICAgICAgICAgICAgaW50dG90ICsgY2l2dG90ICsgbG9hbl9sbiwgCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZWRiX2luXzIwMDEsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkgCgptb2RlbF9pbl8yMDAxX3JvYnVzdCA8LSByb2J1c3RfY2x1c3RlcmlmeShtb2RlbF9pbl8yMDAxLCBlZGJfaW5fMjAwMSwgImNjb2RlIikgJT4lCiAgbWFncml0dHI6OnVzZV9zZXJpZXMoY29lZnMpICU+JSB0aWR5KCkKCm1vZGVsX2luXzIwMDFfb3V0IDwtIHN0YXJnYXplcihtb2RlbF9pbl8yMDAxLCB0eXBlID0gImh0bWwiLCBkZXAudmFyLmNhcHRpb24gPSAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcC52YXIubGFiZWxzID0gImluXFxfMjAwMVxcX2xlYWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2UgPSBsaXN0KG1vZGVsX2luXzIwMDFfcm9idXN0JHN0ZC5lcnJvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9IGMoIkxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwuIFJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgY2x1c3RlcmVkIGJ5IGNvdW50cnkuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vZGVscyBpbmNsdWRlIGNvdW50cmllcyBwcmVzZW50IGluIHRoZSAyMDAxIEVEQiByZXBvcnQuIikpCmBgYAoKYGBge3IgdGJsLW1vZGVsLWluLTIwMDEsIHJlc3VsdHM9ImFzaXMifQpjYXQocGFzdGUoZXNjYXBlX3N0YXJzKG1vZGVsX2luXzIwMDFfb3V0KSwgY29sbGFwc2UgPSAiXG4iKSwgIlxuIikKY2F0KHBhc3RlKG1vZGVsX2luXzIwMDFfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF9tb2RlbF9BMS5odG1sIikpCmBgYAoKIyMgTW9kZWxzIEEy4oCTQTUKCmBgYHtyIG1vZGVsLWNoZWNrLXNiLCByZXN1bHRzPSJoaWRlIn0KIyBUaGlzIGZ1bmN0aW9uIGdlbmVyYXRlcyBhbiBSIGZvcm11bGEgYmFzZWQgb24gYSBnaXZlbiBvdXRjb21lIGFuZCBpdHMgbGVhZC4gCiMgR2l2ZW4gInNiX2RheXNfbG4iLCBpdCB3aWxsIGNyZWF0ZSBhbmQgcnVuICJzYl9kYXlzX2xuX2xlYWQgfiBzYl9kYXlzX2xuICsgLi4uIgpydW5fbGVhZGVkX29sc19jaGVjayA8LSBmdW5jdGlvbihvdXRjb21lLCBkZikgewogIG91dGNvbWVfbGVhZCA8LSBwYXN0ZTAob3V0Y29tZSwgIl9sZWFkIikKICAKICBmb3JtIDwtIGFzLmZvcm11bGEocGFzdGUwKG91dGNvbWVfbGVhZCwgIiB+ICIsIG91dGNvbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICIgKyBnZHBjYXBfbG4gKyBnZHBncm93dGggKyBwb2xpdHkgKyAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAicG9wX2xuICsgaW50dG90ICsgY2l2dG90ICsgbG9hbl9sbiIpKQogIAogIGxtKGZvcm0sIGRhdGEgPSBkZikKfQoKIyBEZWZpbmUgYWxsIHRoZSBtb2RlbHMgdGhhdCBuZWVkIHRvIGJlIHJ1bgptb2RlbHNfdG9fcnVuIDwtIGRhdGFfZnJhbWUob3V0Y29tZSA9IGMoInNiX2RheXNfbG4iLCAic2JfcHJvY2VkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzYl9jb3N0X2xuIiwgInNiX2NhcGl0YWxfbG4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gMSkgICMgVGVtcG9yYXJ5IHZhcmlhYmxlIGZvciBqb2luaW5nCgplZGJfY2hlY2tzIDwtIGVkYl9jbGVhbiAlPiUKICBmaWx0ZXIoeWVhciA+IDIwMDAsIGluXzIwMDEgPT0gMSkgJT4lCiAgbXV0YXRlKGdyb3VwaW5nID0gMSkgJT4lCiAgZ3JvdXBfYnkoY2NvZGUpICU+JQogIG11dGF0ZV9hdCh2YXJzKHNiX2RheXNfbG4sIHNiX3Byb2NlZCwgc2JfY29zdF9sbiwgc2JfY2FwaXRhbF9sbiksCiAgICAgICAgICAgIGZ1bnMobGVhZCA9IGxlYWQoLikpKSAlPiUKICBncm91cF9ieShncm91cGluZykgJT4lCiAgbmVzdCgpICU+JQogIHJpZ2h0X2pvaW4obW9kZWxzX3RvX3J1biwgYnkgPSAiZ3JvdXBpbmciKQoKIyBSdW4gYWxsIHRoZSBtb2RlbHMgd2l0aGluIHRoZSBkYXRhIGZyYW1lCmVkYl9jaGVja3NfbW9kZWxzIDwtIGVkYl9jaGVja3MgJT4lCiAgbXV0YXRlKG1vZGVsID0gcG1hcCgubCA9IGxpc3Qob3V0Y29tZSwgZGF0YSksIHJ1bl9sZWFkZWRfb2xzX2NoZWNrKSwKICAgICAgICAgIyBBZGQgcm9idXN0IGNsdXN0ZXJlZCBTRXMKICAgICAgICAgcm9idXN0X3NlID0gcG1hcCgubCA9IGxpc3QobW9kZWwsIGRhdGEsICJjY29kZSIpLCByb2J1c3RfY2x1c3RlcmlmeSksCiAgICAgICAgICMgQWRkIGEgZGF0YSBmcmFtZSBvZiBtb2RlbCBwYXJhbWV0ZXJzIHdpdGggY29ycmVjdCBTRXMKICAgICAgICAgdGlkeV9yb2J1c3QgPSByb2J1c3Rfc2UgJT4lIG1hcCh+IHRpZHkoLiRjb2VmKSksCiAgICAgICAgIHNlc19vbmx5ID0gdGlkeV9yb2J1c3QgJT4lIG1hcCh+IC4kc3RkLmVycm9yKSkKCmVkYl9jaGVja3NfbW9kZWxzX291dCA8LSBzdGFyZ2F6ZXIoZWRiX2NoZWNrc19tb2RlbHMkbW9kZWwsIHR5cGUgPSAiaHRtbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcC52YXIuY2FwdGlvbiA9ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlID0gZWRiX2NoZWNrc19tb2RlbHMkc2VzX29ubHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90ZXMgPSBjKCJPTFMgbW9kZWxzLiBSb2J1c3Qgc3RhbmRhcmQgZXJyb3JzIGNsdXN0ZXJlZCBieSBjb3VudHJ5LiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNb2RlbHMgaW5jbHVkZSBjb3VudHJpZXMgcHJlc2VudCBpbiB0aGUgMjAwMSBFREIgcmVwb3J0LiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXAuc3RhdCA9IGMoIm4iLCAicnNxIiwgImFkai5yc3EiKSkKYGBgCgpgYGB7ciB0YmwtbW9kZWwtY2hlY2stc2IsIHJlc3VsdHM9ImFzaXMifQpjYXQocGFzdGUoZXNjYXBlX3N0YXJzKGVkYl9jaGVja3NfbW9kZWxzX291dCksIGNvbGxhcHNlID0gIlxuIiksICJcbiIpCmNhdChwYXN0ZShlZGJfY2hlY2tzX21vZGVsc19vdXQsIGNvbGxhcHNlID0gIlxuIiksICJcbiIsCiAgICBmaWxlID0gZmlsZS5wYXRoKGhlcmUoKSwgIm91dHB1dCIsICJ0YWJsZXMiLCAiYXBwX21vZGVsc19BMi01Lmh0bWwiKSkKYGBgCgoKIyBTdGFydGluZyBhIEJ1c2luZXNzIGluZGljYXRvcnMKCipOb3QgZ2VuZXJhdGVkIHdpdGggdGhpcyBzY3JpcHQuKgoKCiMgRW5mb3JjaW5nIENvbnRyYWN0cyBpbmRpY2F0b3JzCgoqTm90IGdlbmVyYXRlZCB3aXRoIHRoaXMgc2NyaXB0LioKCgojIFBvbGljeSByZWZvcm06IE9MUyBtb2RlbHMKCmBgYHtyIG1vZGVscy1vbHMtYWxsfQojIERlZmluZSBhbGwgdGhlIG1vZGVscyB0aGF0IG5lZWQgdG8gYmUgcnVuCm1vZGVsc190b19ydW4gPC0gZXhwYW5kLmdyaWQoeWVhciA9IDIwMDM6MjAxMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRjb21lID0gYygic2JfcHJvY2VkIiwgInNiX2RheXNfbG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzYl9jb3N0X2xuIiwgInNiX2NhcGl0YWxfbG4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cGluZyA9IGMoIkFsbCBjb3VudHJpZXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIEVEQiByZWZvcm0gY29tbWl0dGVlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVjaWFsIEVEQiByZWZvcm0gY29tbWl0dGVlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKIyBBcyBpbiB0aGUgcGFwZXIgYW5hbHlzaXMsIHRoaXMgZnVuY3Rpb24gZ2VuZXJhdGVzIGFuIFIgbW9kZWwgZm9ybXVsYSBiYXNlZCBvbgojIHRoZSBuYW1lIG9mIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgYW5kIHRoZSB5ZWFyIHByb3ZpZGVkLiBpLmUuLCBnaXZlbgojICJzYl9wcm9jZWQiIGFuZCAiMjAwNSIsIGl0IHdpbGwgY3JlYXRlIHRoZSBmb3JtdWxhICJzYl9wcm9jZWQgfiBzYl9wcm9jZWRfbGFnCiMgKyByYW5rZWRfMjAwNSIgYW5kIHJ1biB0aGUgbW9kZWwKcnVuX2xhZ2dlZF9vbHNfbW9kZWwgPC0gZnVuY3Rpb24ob3V0Y29tZSwgeWVhciwgZGYpIHsKICBvdXRjb21lX2xhZyA8LSBwYXN0ZTAob3V0Y29tZSwgIl9sYWciKQogIHllYXJfdmFyaWFibGUgPC0gcGFzdGUwKCJyYW5rZWRfIiwgeWVhcikKCiAgZm9ybSA8LSBhcy5mb3JtdWxhKHBhc3RlMChvdXRjb21lLCAiIH4gIiwgb3V0Y29tZV9sYWcsICIgKyAiLCB5ZWFyX3ZhcmlhYmxlKSkKCiAgbG0oZm9ybSwgZGF0YSA9IGRmKQp9CgpkZnNfc3BsaXQgPC0gZWRiX2NsZWFuICU+JQogIGZpbHRlcihpbl8yMDAxID09IDEpICU+JQogIGdyb3VwX2J5KGhhc19idXJlYXUpICU+JQogIG5lc3QoKSAlPiUKICBtdXRhdGUoaGFzX2J1cmVhdSA9IGFzLmNoYXJhY3RlcihoYXNfYnVyZWF1KSkgJT4lCiAgcmVuYW1lKGdyb3VwaW5nID0gaGFzX2J1cmVhdSkKCmRmX2FsbCA8LSBlZGJfY2xlYW4gJT4lCiAgZmlsdGVyKGluXzIwMDEgPT0gMSkgJT4lCiAgbXV0YXRlKGdyb3VwaW5nID0gIkFsbCBjb3VudHJpZXMiKSAlPiUKICBncm91cF9ieShncm91cGluZykgJT4lCiAgbmVzdCgpCgptb2RlbHNfdG9fcnVuX2Z1bGwgPC0gYmluZF9yb3dzKGRmc19zcGxpdCwgZGZfYWxsKSAlPiUKICByaWdodF9qb2luKG1vZGVsc190b19ydW4sIGJ5ID0gImdyb3VwaW5nIikKCiMgUnVuIGFsbCB0aGUgbW9kZWxzIHdpdGhpbiB0aGUgZGF0YSBmcmFtZQpvbHNfbW9kZWxzX2xhZ2dlZCA8LSBtb2RlbHNfdG9fcnVuX2Z1bGwgJT4lCiAgbXV0YXRlKG1vZGVsID0gcG1hcCgubCA9IGxpc3Qob3V0Y29tZSwgeWVhciwgZGF0YSksIHJ1bl9sYWdnZWRfb2xzX21vZGVsKSwKICAgICAgICAgIyBBZGQgcm9idXN0IGNsdXN0ZXJlZCBTRXMKICAgICAgICAgcm9idXN0X3NlID0gcG1hcCgubCA9IGxpc3QobW9kZWwsIGRhdGEsICJjY29kZSIpLCByb2J1c3RfY2x1c3RlcmlmeSksCiAgICAgICAgICMgQWRkIG1vZGVsIHN1bW1hcnkgc3RhdGlzdGljcwogICAgICAgICBnbGFuY2UgPSBtb2RlbCAlPiUgbWFwKGdsYW5jZSksCiAgICAgICAgICMgQWRkIGEgZGF0YSBmcmFtZSBvZiBtb2RlbCBwYXJhbWV0ZXJzIHdpdGggY29ycmVjdCBTRXMKICAgICAgICAgdGlkeV9yb2J1c3QgPSByb2J1c3Rfc2UgJT4lIG1hcCh+IHRpZHkoLiRjb2VmKSksCiAgICAgICAgIHNlc19vbmx5ID0gdGlkeV9yb2J1c3QgJT4lIG1hcCh+IC4kc3RkLmVycm9yKSkKCiMgRXh0cmFjdCB0aGUgcmFua2luZyBjb2VmZmljaWVudHMgZnJvbSBhbGwgbW9kZWxzCm9sc19jb2VmcyA8LSBvbHNfbW9kZWxzX2xhZ2dlZCAlPiUKICAjIFNwcmVhZCBvdXQgdGhlIG1vZGVsIHJlc3VsdHMKICB1bm5lc3QodGlkeV9yb2J1c3QpICU+JQogICMgT25seSBsb29rIGF0IHRoZSByYW5rZWQqIGNvZWZmaWNpZW50cwogIGZpbHRlcihzdHJfZGV0ZWN0KHRlcm0sICJyYW5rZWQiKSkgJT4lCiAgIyBDbGVhbiB1cCB0aGUgZXN0aW1hdGVzLCBsYWJlbHMsIGFuZCBhZGQgc3RhcnMKICBtdXRhdGUodmFsdWUgPSBwYXN0ZTAoc3ByaW50ZigiJS4zZiIsIHJvdW5kKGVzdGltYXRlLCAzKSksIHBfc3RhcnMocC52YWx1ZSkpLAogICAgICAgICB0ZXJtID0gc3RyX3JlcGxhY2UodGVybSwgIlxcLlxcZCtUUlVFIiwgIiIpKSAlPiUKICAjIEdldCByaWQgb2YgZXh0cmEgY29sdW1ucwogIHNlbGVjdCgtYyhlc3RpbWF0ZSwgc3RkLmVycm9yLCBzdGF0aXN0aWMsIHAudmFsdWUpKSAlPiUKICBzcHJlYWQob3V0Y29tZSwgdmFsdWUpICU+JQogICMgR2l2ZSB0YWJsZSBjbGVhbiBjb2x1bW4gbmFtZXMKICBzZWxlY3QoU3Vic2V0ID0gZ3JvdXBpbmcsIFllYXIgPSB5ZWFyLAogICAgICAgICBQcm9jZWR1cmVzID0gc2JfcHJvY2VkLCBgQ29zdCAobG9nKWAgPSBzYl9jb3N0X2xuLAogICAgICAgICBgRGF5cyAobG9nKWAgPSBzYl9kYXlzX2xuLCBgQ2FwaXRhbCAobG9nKWAgPSBzYl9jYXBpdGFsX2xuKQpgYGAKCgojIyBUYWJsZSAzIGZyb20gdGhlIHBhcGVyOiBzdW1tYXJ5IG9mIGNvZWZmaWNpZW50cyBmb3IgOCBPTFMgbW9kZWxzCgpGdWxsIG1vZGVscyBpbiB0YWJsZXMgQjHigJMzIGJlbG93LgoKYGBge3IgdGJsLW9scy1pbi1wYXBlciwgcmVzdWx0cz0iYXNpcyJ9CnRibF9vbHNfcGFwZXIgPC0gb2xzX2NvZWZzICU+JQogIGZpbHRlcihTdWJzZXQgPT0gIkFsbCBjb3VudHJpZXMiLCBZZWFyICVpbiUgYygyMDA1LCAyMDA2KSkKCmNhcHRpb24gPC0gJ1N1bW1hcnkgb2YgzrJ+Mn4gY29lZmZpY2llbnRzIChpLmUuICJyYW5rZWRfMjAweCIpIGZvciBkaWZmZXJlbmNlIG1vZGVscycKCnRibF9vbHMgPC0gcGFuZG9jLnRhYmxlLnJldHVybih0Ymxfb2xzX3BhcGVyLCBjYXB0aW9uID0gY2FwdGlvbikKCmNhdCh0Ymxfb2xzKQpjYXQodGJsX29scywgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV9vbHMubWQiKSkKYGBgCgojIyBUYWJsZSBCMTogMjAwNSBhbmFseXNpcywgZnVsbCBPTFMgbW9kZWxzCgpgYGB7ciB0Ymwtb2xzLTIwMDUtMjAwNiwgcmVzdWx0cz0iaGlkZSJ9CnRibF9vbHNfMjAwNSA8LSBvbHNfbW9kZWxzX2xhZ2dlZCAlPiUKICBmaWx0ZXIoZ3JvdXBpbmcgPT0gIkFsbCBjb3VudHJpZXMiLCB5ZWFyID09IDIwMDUpCgp0Ymxfb2xzXzIwMDVfb3V0IDwtIHN0YXJnYXplcih0Ymxfb2xzXzIwMDUkbW9kZWwsIHR5cGUgPSAiaHRtbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXAudmFyLmNhcHRpb24gPSAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2UgPSB0Ymxfb2xzXzIwMDUkc2VzX29ubHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGVzID0gYygiT0xTIG1vZGVscy4gUm9idXN0IHN0YW5kYXJkIGVycm9ycyBjbHVzdGVyZWQgYnkgY291bnRyeS4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNb2RlbHMgaW5jbHVkZSBjb3VudHJpZXMgcHJlc2VudCBpbiB0aGUgMjAwMSBFREIgcmVwb3J0LiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwLnN0YXQgPSBjKCJuIiwgInJzcSIsICJhZGoucnNxIikpCgp0Ymxfb2xzXzIwMDYgPC0gb2xzX21vZGVsc19sYWdnZWQgJT4lCiAgZmlsdGVyKGdyb3VwaW5nID09ICJBbGwgY291bnRyaWVzIiwgeWVhciA9PSAyMDA2KQoKdGJsX29sc18yMDA2X291dCA8LSBzdGFyZ2F6ZXIodGJsX29sc18yMDA2JG1vZGVsLCB0eXBlID0gImh0bWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwLnZhci5jYXB0aW9uID0gIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlID0gdGJsX29sc18yMDA2JHNlc19vbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9IGMoIk9MUyBtb2RlbHMuIFJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgY2x1c3RlcmVkIGJ5IGNvdW50cnkuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9kZWxzIGluY2x1ZGUgY291bnRyaWVzIHByZXNlbnQgaW4gdGhlIDIwMDEgRURCIHJlcG9ydC4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcC5zdGF0ID0gYygibiIsICJyc3EiLCAiYWRqLnJzcSIpKQpgYGAKCmBgYHtyIHRibC1vbHMtMjAwNSwgcmVzdWx0cz0iYXNpcyJ9CmNhdChwYXN0ZShlc2NhcGVfc3RhcnModGJsX29sc18yMDA1X291dCksIGNvbGxhcHNlID0gIlxuIiksICJcbiIpCmNhdChwYXN0ZSh0Ymxfb2xzXzIwMDVfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF9tb2RlbHNfQjEuaHRtbCIpKQpgYGAKCiMjIFRhYmxlIEIyOiAyMDA2IGFuYWx5c2lzLCBmdWxsIE9MUyBtb2RlbHMKCmBgYHtyIHRibC1vbHMtMjAwNiwgcmVzdWx0cz0iYXNpcyJ9CmNhdChwYXN0ZShlc2NhcGVfc3RhcnModGJsX29sc18yMDA2X291dCksIGNvbGxhcHNlID0gIlxuIiksICJcbiIpCmNhdChwYXN0ZSh0Ymxfb2xzXzIwMDZfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF9tb2RlbHNfQjIuaHRtbCIpKQpgYGAKCiMjIFRhYmxlIEIzOiBDdXRwb2ludHMgYXQgZXZlcnkgcG9zc2libGUgeWVhciwgT0xTIG1vZGVscwoKYGBge3IgdGJsLW9scy1hbGwsIHJlc3VsdHM9ImFzaXMifQpjYXB0aW9uIDwtICdTdW1tYXJ5IG9mIM6yfjJ+IGNvZWZmaWNpZW50cyAoaS5lLiAicmFua2VkLjIwMHgiKSBmb3IgZGlmZmVyZW5jZSBtb2RlbHMgZm9yIGFsbCB5ZWFycycKCnRibF9vbHNfYWxsIDwtIHBhbmRvYy50YWJsZS5yZXR1cm4ob2xzX2NvZWZzLCBjYXB0aW9uID0gY2FwdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGl0LnRhYmxlcyA9IEluZiwgbWlzc2luZyA9ICLigJQiKQoKY2F0KHRibF9vbHNfYWxsKQpjYXQodGJsX29sc19hbGwsIAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF9tb2RlbHNfQjNfYWxsLm1kIikpCmBgYAoKCiMgUG9saWN5IHJlZm9ybTogSVRTIG1vZGVscwoKYGBge3IgbW9kZWxzLWl0cy1hbGx9CnJ1bl9pdHNfbW9kZWwgPC0gZnVuY3Rpb24ob3V0Y29tZSwgeWVhciwgZGYpIHsKICB5ZWFyX3ZhcmlhYmxlIDwtIHBhc3RlMCgicmFua2VkXyIsIHllYXIpCiAgeWVhcl9jZW50ZXJlZCA8LSBwYXN0ZTAoInllYXJfY2VudGVyZWRfIiwgeWVhcikKICAKICBmb3JtIDwtIGFzLmZvcm11bGEocGFzdGUwKG91dGNvbWUsICIgfiAiLCB5ZWFyX2NlbnRlcmVkLCAiICsgIiwgeWVhcl92YXJpYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgKyAiLCB5ZWFyX2NlbnRlcmVkLCAiICogIiwgeWVhcl92YXJpYWJsZSkpCiAgCiAgbG0oZm9ybSwgZGF0YSA9IGRmKQp9CgojIFJ1biBhbGwgdGhlIG1vZGVscyB3aXRoaW4gdGhlIGRhdGEgZnJhbWUKaXRzX21vZGVsc19sYWdnZWQgPC0gbW9kZWxzX3RvX3J1bl9mdWxsICU+JQogIG11dGF0ZShtb2RlbCA9IHBtYXAoLmwgPSBsaXN0KG91dGNvbWUsIHllYXIsIGRhdGEpLCBydW5faXRzX21vZGVsKSwKICAgICAgICAgIyBBZGQgcm9idXN0IGNsdXN0ZXJlZCBTRXMKICAgICAgICAgcm9idXN0X3NlID0gcG1hcCgubCA9IGxpc3QobW9kZWwsIGRhdGEsICJjY29kZSIpLCByb2J1c3RfY2x1c3RlcmlmeSksCiAgICAgICAgICMgQWRkIG1vZGVsIHN1bW1hcnkgc3RhdGlzdGljcwogICAgICAgICBnbGFuY2UgPSBtb2RlbCAlPiUgbWFwKGdsYW5jZSksCiAgICAgICAgICMgQWRkIGEgZGF0YSBmcmFtZSBvZiBtb2RlbCBwYXJhbWV0ZXJzIHdpdGggY29ycmVjdCBTRXMKICAgICAgICAgdGlkeV9yb2J1c3QgPSByb2J1c3Rfc2UgJT4lIG1hcCh+IHRpZHkoLiRjb2VmKSksCiAgICAgICAgIHNlc19vbmx5ID0gdGlkeV9yb2J1c3QgJT4lIG1hcCh+IC4kc3RkLmVycm9yKSkKCiMgRXh0cmFjdCB0aGUgcmFua2luZyBjb2VmZmljaWVudHMgZnJvbSBhbGwgbW9kZWxzCml0c19jb2VmcyA8LSBpdHNfbW9kZWxzX2xhZ2dlZCAlPiUKICAjIFNwcmVhZCBvdXQgdGhlIG1vZGVsIHJlc3VsdHMKICB1bm5lc3QodGlkeV9yb2J1c3QpICU+JQogICMgT25seSBsb29rIGF0IHRoZSBjb2VmZmljaWVudHMgZnJvbSBpbnRlcmFjdGlvbiB0ZXJtcyAodGhleSBoYXZlICI6IiBpbiB0aGVpciBuYW1lcykKICBmaWx0ZXIoc3RyX2RldGVjdCh0ZXJtLCAiOiIpKSAlPiUKICAjIENsZWFuIHVwIHRoZSBlc3RpbWF0ZXMsIGxhYmVscywgYW5kIGFkZCBzdGFycwogIG11dGF0ZSh2YWx1ZSA9IHBhc3RlMChzcHJpbnRmKCIlLjNmIiwgcm91bmQoZXN0aW1hdGUsIDMpKSwgcF9zdGFycyhwLnZhbHVlKSksCiAgICAgICAgIHRlcm0gPSBzdHJfcmVwbGFjZSh0ZXJtLCAiKC4rKVxcLlxcZCs6KC4rKVxcLlxcZCtUUlVFIiwgIlxcMSDDlyBcXDIiKSkgJT4lCiAgIyBHZXQgcmlkIG9mIGV4dHJhIGNvbHVtbnMKICBzZWxlY3QoLWMoZXN0aW1hdGUsIHN0ZC5lcnJvciwgc3RhdGlzdGljLCBwLnZhbHVlKSkgJT4lCiAgc3ByZWFkKG91dGNvbWUsIHZhbHVlKSAlPiUKICAjIEdpdmUgdGFibGUgY2xlYW4gY29sdW1uIG5hbWVzCiAgc2VsZWN0KFN1YnNldCA9IGdyb3VwaW5nLCBZZWFyID0geWVhciwKICAgICAgICAgUHJvY2VkdXJlcyA9IHNiX3Byb2NlZCwgYENvc3QgKGxvZylgID0gc2JfY29zdF9sbiwKICAgICAgICAgYERheXMgKGxvZylgID0gc2JfZGF5c19sbiwgYENhcGl0YWwgKGxvZylgID0gc2JfY2FwaXRhbF9sbikKYGBgCgojIyBUYWJsZSA0IGZyb20gdGhlIHBhcGVyOiBzdW1tYXJ5IG9mIGNvZWZmaWNpZW50cyBmb3IgOCBJVFMgbW9kZWxzCgpGdWxsIG1vZGVscyBpbiB0YWJsZXMgQzHigJMzIGJlbG93LgoKYGBge3IgdGJsLWl0cy1pbi1wYXBlciwgcmVzdWx0cz0iYXNpcyJ9CnRibF9pdHNfcGFwZXIgPC0gaXRzX2NvZWZzICU+JQogIGZpbHRlcihTdWJzZXQgPT0gIkFsbCBjb3VudHJpZXMiLCBZZWFyICVpbiUgYygyMDA1LCAyMDA2KSkKCmNhcHRpb24gPC0gJ1N1bW1hcnkgb2YgzrJ+M34gY29lZmZpY2llbnRzIChpLmUuICJ5ZWFyLmNlbnRlcmVkLjIwMHggw5cgcmFua2VkLjIwMHgiKSBmb3IgSVRTIG1vZGVscycKCnRibF9pdHMgPC0gcGFuZG9jLnRhYmxlLnJldHVybih0YmxfaXRzX3BhcGVyLCBjYXB0aW9uID0gY2FwdGlvbikKCmNhdCh0YmxfaXRzKQpjYXQodGJsX2l0cywgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV9pdHMubWQiKSkKYGBgCgojIyBUYWJsZSBDMTogMjAwNSBhbmFseXNpcywgZnVsbCBJVFMgbW9kZWxzCgpgYGB7ciB0YmwtaXRzLTIwMDUtMjAwNiwgcmVzdWx0cz0iaGlkZSJ9CnRibF9pdHNfMjAwNSA8LSBpdHNfbW9kZWxzX2xhZ2dlZCAlPiUKICBmaWx0ZXIoZ3JvdXBpbmcgPT0gIkFsbCBjb3VudHJpZXMiLCB5ZWFyID09IDIwMDUpCgp0YmxfaXRzXzIwMDVfb3V0IDwtIHN0YXJnYXplcih0YmxfaXRzXzIwMDUkbW9kZWwsIHR5cGUgPSAiaHRtbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXAudmFyLmNhcHRpb24gPSAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2UgPSB0YmxfaXRzXzIwMDUkc2VzX29ubHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGVzID0gYygiSVRTIG1vZGVscy4gUm9idXN0IHN0YW5kYXJkIGVycm9ycyBjbHVzdGVyZWQgYnkgY291bnRyeS4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNb2RlbHMgaW5jbHVkZSBjb3VudHJpZXMgcHJlc2VudCBpbiB0aGUgMjAwMSBFREIgcmVwb3J0LiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwLnN0YXQgPSBjKCJuIiwgInJzcSIsICJhZGoucnNxIikpCgp0YmxfaXRzXzIwMDYgPC0gaXRzX21vZGVsc19sYWdnZWQgJT4lCiAgZmlsdGVyKGdyb3VwaW5nID09ICJBbGwgY291bnRyaWVzIiwgeWVhciA9PSAyMDA2KQoKdGJsX2l0c18yMDA2X291dCA8LSBzdGFyZ2F6ZXIodGJsX2l0c18yMDA2JG1vZGVsLCB0eXBlID0gImh0bWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwLnZhci5jYXB0aW9uID0gIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlID0gdGJsX2l0c18yMDA2JHNlc19vbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9IGMoIklUUyBtb2RlbHMuIFJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgY2x1c3RlcmVkIGJ5IGNvdW50cnkuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9kZWxzIGluY2x1ZGUgY291bnRyaWVzIHByZXNlbnQgaW4gdGhlIDIwMDEgRURCIHJlcG9ydC4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcC5zdGF0ID0gYygibiIsICJyc3EiLCAiYWRqLnJzcSIpKQpgYGAKCmBgYHtyIHRibC1pdHMtMjAwNSwgcmVzdWx0cz0iYXNpcyJ9CmNhdChwYXN0ZShlc2NhcGVfc3RhcnModGJsX2l0c18yMDA1X291dCksIGNvbGxhcHNlID0gIlxuIiksICJcbiIpCmNhdChwYXN0ZSh0YmxfaXRzXzIwMDVfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF9tb2RlbHNfQzEuaHRtbCIpKQpgYGAKCiMjIFRhYmxlIEMyOiAyMDA2IGFuYWx5c2lzLCBmdWxsIElUUyBtb2RlbHMKCmBgYHtyIHRibC1pdHMtMjAwNiwgcmVzdWx0cz0iYXNpcyJ9CmNhdChwYXN0ZShlc2NhcGVfc3RhcnModGJsX2l0c18yMDA2X291dCksIGNvbGxhcHNlID0gIlxuIiksICJcbiIpCmNhdChwYXN0ZSh0YmxfaXRzXzIwMDZfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF9tb2RlbHNfQzIuaHRtbCIpKQpgYGAKCiMjIFRhYmxlIEMzOiBDdXRwb2ludHMgYXQgZXZlcnkgcG9zc2libGUgeWVhciwgSVRTIG1vZGVscwoKYGBge3IgdGJsLWl0cy1hbGwsIHJlc3VsdHM9ImFzaXMifQpjYXB0aW9uIDwtICdTdW1tYXJ5IG9mIM6yfjN+IGNvZWZmaWNpZW50cyAoaS5lLiAieWVhci5jZW50ZXJlZC4yMDB4IMOXIHJhbmtlZC4yMDB4IikgZm9yIElUUyBtb2RlbHMgZm9yIGFsbCB5ZWFycycKCnRibF9pdHNfYWxsIDwtIHBhbmRvYy50YWJsZS5yZXR1cm4oaXRzX2NvZWZzLCBjYXB0aW9uID0gY2FwdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdC50YWJsZXMgPSBJbmYsIG1pc3NpbmcgPSAi4oCUIikKCmNhdCh0YmxfaXRzX2FsbCkKY2F0KHRibF9pdHNfYWxsLCAKICAgIGZpbGUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgInRhYmxlcyIsICJhcHBfbW9kZWxzX0MzX2FsbC5tZCIpKQpgYGAKCgojIENvdW50cnkgZml4ZWQgZWZmZWN0cyBmb3IgT0xTIG1vZGVscwoKIyMgVGFibGUgRDE6ICJSYW5rZWQiIGNvZWZmaWNpZW50cyB3aXRoIGFuZCB3aXRob3V0IGNvdW50cnkgZml4ZWQgZWZmZWN0cwoKYGBge3IgcmFua2VkLWNvdW50cnktZmUsIHdhcm5pbmc9RkFMU0V9CiMgQWxsIHRoZSBGRSBtb2RlbHMgdG8gYmUgcnVuCmNvdW50cnlfZmVfbW9kZWxzIDwtIGV4cGFuZC5ncmlkKG91dGNvbWUgPSBjKCJzYl9wcm9jZWQiLCAic2JfZGF5c19sbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzYl9jb3N0X2xuIiwgInNiX2NhcGl0YWxfbG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29uX3Byb2NlZCIsICJjb25fZGF5cyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGMoIk1haW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWluICsgYGNpdnRvdF9sYWdgICsgYGludHRvdF9sYWdgICsgYGxvYW5fbG5fbGFnYCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1haW4gKyBgY2l2dG90X2xhZ2AgKyBgaW50dG90X2xhZ2AgKyBgbG9hbl9iaW5fbGFnYCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1haW4gKyBmaXhlZCBlZmZlY3RzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWluIC0gMjAwMSIsICJNYWluIC0gMjAwMSAmIDIwMDIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKSAlPiUKICBtdXRhdGUoY291bnRyeV9mZSA9IGNvbnRyb2xzICVpbiUgYygiTWFpbiArIGZpeGVkIGVmZmVjdHMiLCAiTWFpbiAtIDIwMDEiLCAiTWFpbiAtIDIwMDEgJiAyMDAyIiksCiAgICAgICAgIGRmX3RvX3VzZSA9IGNhc2Vfd2hlbigKICAgICAgICAgICBjb250cm9scyA9PSAiTWFpbiAtIDIwMDEiIH4gIkRyb3AgMjAwMSIsCiAgICAgICAgICAgY29udHJvbHMgPT0gIk1haW4gLSAyMDAxICYgMjAwMiIgfiAiRHJvcCAyMDAyIiwKICAgICAgICAgICBUUlVFIH4gIkZ1bGwiIAogICAgICAgICApKQoKIyBOZXN0IGZpbHRlcmVkIGRhdGEgaW50byBhIGRhdGEgZnJhbWUKZGF0YV90b191c2UgPC0gdHJpYmJsZSgKICB+ZGZfdG9fdXNlLCAgfmRhdGEsCiAgIkZ1bGwiLCAgICAgIGVkYl9jbGVhbiAlPiUgZmlsdGVyKHllYXIgPiAyMDAwLCBpbl8yMDA0ID09IDEpLAogICJEcm9wIDIwMDEiLCBlZGJfY2xlYW4gJT4lIGZpbHRlcih5ZWFyID4gMjAwMSwgaW5fMjAwNCA9PSAxKSwKICAiRHJvcCAyMDAyIiwgZWRiX2NsZWFuICU+JSBmaWx0ZXIoeWVhciA+IDIwMDIsIGluXzIwMDQgPT0gMSkKKQoKIyBDb21iaW5lIGZpbHRlcmVkIGRhdGEgd2l0aCBhbGwgbW9kZWwgcGFyYW1ldGVycwpjb3VudHJ5X2ZlX21vZGVsc19mdWxsIDwtIGRhdGFfdG9fdXNlICU+JQogIHJpZ2h0X2pvaW4oY291bnRyeV9mZV9tb2RlbHMsIGJ5ID0gImRmX3RvX3VzZSIpICU+JQogIHNlbGVjdCgtZGZfdG9fdXNlKQoKIyBCdWlsZCBhbmQgcnVuIGEgYnVuY2ggb2YgZGlmZmVyZW50IG1vZGVscyBiYXNlZCBvbiBwYXJhbWV0ZXJzIHRoYXQgZGV0ZXJtaW5lCiMgd2hhdCBjb250cm9scyB0byBhZGQgYW5kIHdoZXRoZXIgb3Igbm90IHRvIGluY2x1ZGUgY291bnRyeSBmaXhlZCBlZmZlY3RzCnJ1bl9jb3VudHJ5X2ZlX21vZGVscyA8LSBmdW5jdGlvbihvdXRjb21lLCBjb250cm9scywgY291bnRyeV9mZSwgZGYpIHsKICBtYWluX2NvbnRyb2xzIDwtICJnZHBjYXBfbG5fbGFnICsgZ2RwZ3Jvd3RoX2xhZyArIHBvbGl0eV9sYWcgKyBwb3BfbG5fbGFnIgogIAogIGlmIChzdHJfZGV0ZWN0KGNvbnRyb2xzLCAibG9hbl9sbl9sYWciKSkgewogICAgYWRkaXRpb25hbF9jb250cm9scyA8LSAiICsgY2l2dG90X2xhZyArIGludHRvdF9sYWcgKyBsb2FuX2xuX2xhZyIKICB9IGVsc2UgaWYgKHN0cl9kZXRlY3QoY29udHJvbHMsICJsb2FuX2Jpbl9sYWciKSkgewogICAgYWRkaXRpb25hbF9jb250cm9scyA8LSAiICsgY2l2dG90X2xhZyArIGludHRvdF9sYWcgKyBsb2FuX2Jpbl9sYWciCiAgfSBlbHNlIHsKICAgIGFkZGl0aW9uYWxfY29udHJvbHMgPC0gIiIKICB9CiAgCiAgaWYgKGNvdW50cnlfZmUpIHsKICAgIGNvdW50cnkgPC0gIiArIGFzLmZhY3RvcihjY29kZSkiCiAgfSBlbHNlIHsKICAgIGNvdW50cnkgPC0gIiIKICB9CgogIGZvcm0gPC0gcGFzdGUwKG91dGNvbWUsICIgfiAiLCBwYXN0ZTAob3V0Y29tZSwgIl9sYWciKSwgIiArIHJhbmtlZF9sYWcgKyAiLCAKICAgICAgICAgICAgICAgICBtYWluX2NvbnRyb2xzLCBhZGRpdGlvbmFsX2NvbnRyb2xzLCBjb3VudHJ5KSAlPiUKICAgIGFzLmZvcm11bGEoKQoKICBsbShmb3JtLCBkYXRhID0gZGYpCn0KCiMgUnVuIGFsbCB0aGUgbW9kZWxzIHdpdGhpbiB0aGUgZGF0YSBmcmFtZQpjb3VudHJ5X2ZlX21vZGVsc19hbGwgPC0gY291bnRyeV9mZV9tb2RlbHNfZnVsbCAlPiUKICBtdXRhdGUobW9kZWwgPSBwbWFwKC5sID0gbGlzdChvdXRjb21lLCBjb250cm9scywgY291bnRyeV9mZSwgZGF0YSksIAogICAgICAgICAgICAgICAgICAgICAgcnVuX2NvdW50cnlfZmVfbW9kZWxzKSwKICAgICAgICAgIyBBZGQgcm9idXN0IGNsdXN0ZXJlZCBTRXMKICAgICAgICAgcm9idXN0X3NlID0gcG1hcCgubCA9IGxpc3QobW9kZWwsIGRhdGEsICJjY29kZSIpLCByb2J1c3RfY2x1c3RlcmlmeSksCiAgICAgICAgICMgQWRkIG1vZGVsIHN1bW1hcnkgc3RhdGlzdGljcwogICAgICAgICBnbGFuY2UgPSBtb2RlbCAlPiUgbWFwKGdsYW5jZSksCiAgICAgICAgICMgQWRkIGEgZGF0YSBmcmFtZSBvZiBtb2RlbCBwYXJhbWV0ZXJzIHdpdGggY29ycmVjdCBTRXMKICAgICAgICAgdGlkeV9yb2J1c3QgPSByb2J1c3Rfc2UgJT4lIG1hcCh+IHRpZHkoLiRjb2VmKSksCiAgICAgICAgIHNlc19vbmx5ID0gdGlkeV9yb2J1c3QgJT4lIG1hcCh+IC4kc3RkLmVycm9yKSkKCiMgTWFrZSB0aW55IGRhdGEgZnJhbWUgaW5kaWNhdGluZyBpZiBtb2RlbCBoYWQgY291bnRyeSBmaXhlZCBlZmZlY3RzCmZpeGVkX2VmZmVjdHNfY291bnRyeSA8LSBjb3VudHJ5X2ZlX21vZGVscyAlPiUKICBzZWxlY3QoY29udHJvbHMsIGNvdW50cnlfZmUpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgbXV0YXRlKGNvdW50cnlfZmUgPSBpZmVsc2UoY291bnRyeV9mZSwgIlllcyIsICJObyIpKSAlPiUKICBzcHJlYWQoY29udHJvbHMsIGNvdW50cnlfZmUpICU+JQogIG11dGF0ZShPdXRjb21lID0gIkZpeGVkIGNvdW50cnkgZWZmZWN0cyIpCgojIERpc3BsYXkgYWxsIHRoZSByYW5rZWQgY29lZmZpY2llbnRzCnJhbmtlZF9jb2Vmc19jb3VudHJ5IDwtIGNvdW50cnlfZmVfbW9kZWxzX2FsbCAlPiUKICAjIFNwcmVhZCBvdXQgdGhlIG1vZGVsIHJlc3VsdHMKICB1bm5lc3QodGlkeV9yb2J1c3QpICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KHRlcm0sICJyYW5rZWQiKSkgJT4lCiAgIyBDbGVhbiB1cCB0aGUgZXN0aW1hdGVzIGFuZCBhZGQgc3RhcnMKICBtdXRhdGUodmFsdWUgPSBwYXN0ZTAoc3ByaW50ZigiJS4zZiIsIHJvdW5kKGVzdGltYXRlLCAzKSksIHBfc3RhcnMocC52YWx1ZSkpLAogICAgICAgICBvdXRjb21lID0gZmFjdG9yKG91dGNvbWUsIGxldmVscyA9IHVuaXF1ZShjb3VudHJ5X2ZlX21vZGVscyRvdXRjb21lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBwYXN0ZTAoImAiLCB1bmlxdWUoY291bnRyeV9mZV9tb2RlbHMkb3V0Y29tZSksICJgIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBjb250cm9scyA9IGZhY3Rvcihjb250cm9scywgbGV2ZWxzID0gdW5pcXVlKGNvdW50cnlfZmVfbW9kZWxzJGNvbnRyb2xzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICAjIEdldCByaWQgb2YgZXh0cmEgY29sdW1ucwogIHNlbGVjdChPdXRjb21lID0gb3V0Y29tZSwgY29udHJvbHMsIHZhbHVlKSAlPiUKICBzcHJlYWQoY29udHJvbHMsIHZhbHVlKSAlPiUKICBiaW5kX3Jvd3MoZml4ZWRfZWZmZWN0c19jb3VudHJ5KQpgYGAKCmBgYHtyIHRibC1jb3VudHJ5LWZlLXJhbmtlZCwgcmVzdWx0cz0iYXNpcyJ9CmNhcHRpb24gPC0gJ1N1bW1hcnkgb2YgY29lZmZpY2llbnRzIGZvciB0aGUgbGFnZ2VkICJSYW5rZWQiIHZhcmlhYmxlIHdpdGggYW5kIHdpdGhvdXQgY291bnRyeSBmaXhlZCBlZmZlY3RzJwoKdGJsX2NvdW50cnlfZmUgPC0gcGFuZG9jLnRhYmxlLnJldHVybihyYW5rZWRfY29lZnNfY291bnRyeSwgY2FwdGlvbiA9IGNhcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQudGFibGVzID0gSW5mKQoKY2F0KHRibF9jb3VudHJ5X2ZlKQpjYXQodGJsX2NvdW50cnlfZmUsIAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV9EMS5tZCIpKQpgYGAKCipOb3RlKjogTWFpbiBjb250cm9scyBhcmUgYGdkcGNhcF9sbl9sYWdgLCBgZ2RwZ3Jvd3RoX2xhZ2AsIGBwb2xpdHlfbGFnYCwgYW5kIGBwb3BfbG5fbGFnYAoKCiMjIFRhYmxlIEQyOiBTdWItaW5kaWNhdG9ycyBmb3IgIlN0YXJ0aW5nIGEgQnVzaW5lc3MiIHdpdGggYW5kIHdpdGhvdXQgY291bnRyeSBmaXhlZCBlZmZlY3RzCgpgYGB7ciBzYi1jb3VudHJ5LWZlLCByZXN1bHRzPSJoaWRlIn0Kc2JfZmUgPC0gY291bnRyeV9mZV9tb2RlbHNfYWxsICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KG91dGNvbWUsICJzYl8iKSwKICAgICAgICAgY29udHJvbHMgJWluJSBjKCJNYWluICsgZml4ZWQgZWZmZWN0cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIk1haW4gKyBgY2l2dG90X2xhZ2AgKyBgaW50dG90X2xhZ2AgKyBgbG9hbl9iaW5fbGFnYCIpKSAlPiUKICBtdXRhdGUob3V0Y29tZSA9IGZjdF9pbm9yZGVyKG91dGNvbWUsIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgYXJyYW5nZShvdXRjb21lKQoKc2JfY291bnRyeV9mZV9tb2RlbHNfb3V0IDwtIHN0YXJnYXplcihzYl9mZSRtb2RlbCwgdHlwZSA9ICJodG1sIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwLnZhci5jYXB0aW9uID0gIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2UgPSBzYl9mZSRzZXNfb25seSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9IGMoIk9MUyBtb2RlbHMuIFJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgY2x1c3RlcmVkIGJ5IGNvdW50cnkuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vZGVscyBpbmNsdWRlIGNvdW50cmllcyBwcmVzZW50IGluIHRoZSAyMDA0IEVEQiByZXBvcnQuIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcC5zdGF0ID0gYygibiIsICJyc3EiLCAiYWRqLnJzcSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5saW5lcyA9IGxpc3QoYygiQ291bnRyeSBmaXhlZCBlZmZlY3RzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcChjKCJObyIsICJZZXMiKSwgNCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbWl0ID0gImNjb2RlIikKYGBgCgpgYGB7ciB0Ymwtc2ItY291bnRyeS1mZSwgcmVzdWx0cz0iYXNpcyJ9CmNhdChwYXN0ZShlc2NhcGVfc3RhcnMoc2JfY291bnRyeV9mZV9tb2RlbHNfb3V0KSwgY29sbGFwc2UgPSAiXG4iKSwgIlxuIikKY2F0KHBhc3RlKHNiX2NvdW50cnlfZmVfbW9kZWxzX291dCwgY29sbGFwc2UgPSAiXG4iKSwgIlxuIiwKICAgIGZpbGUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgInRhYmxlcyIsICJhcHBfdGFibGVfRDIuaHRtbCIpKQpgYGAKCiMjIFRhYmxlIEQzOiBTdWItaW5kaWNhdG9ycyBmb3IgIkVuZm9yY2luZyBDb250cmFjdHMiIHdpdGggYW5kIHdpdGhvdXQgY291bnRyeSBmaXhlZCBlZmZlY3RzCgpgYGB7ciBjb24tY291bnRyeS1mZSwgcmVzdWx0cz0iaGlkZSJ9CmNvbl9mZSA8LSBjb3VudHJ5X2ZlX21vZGVsc19hbGwgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3Qob3V0Y29tZSwgImNvbl8iKSwKICAgICAgICAgY29udHJvbHMgJWluJSBjKCJNYWluICsgZml4ZWQgZWZmZWN0cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIk1haW4gKyBgY2l2dG90X2xhZ2AgKyBgaW50dG90X2xhZ2AgKyBgbG9hbl9iaW5fbGFnYCIpKSAlPiUKICBtdXRhdGUob3V0Y29tZSA9IGZjdF9pbm9yZGVyKG91dGNvbWUsIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgYXJyYW5nZShvdXRjb21lKQoKY29uX2NvdW50cnlfZmVfbW9kZWxzX291dCA8LSBzdGFyZ2F6ZXIoY29uX2ZlJG1vZGVsLCB0eXBlID0gImh0bWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwLnZhci5jYXB0aW9uID0gIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlID0gY29uX2ZlJHNlc19vbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9IGMoIk9MUyBtb2RlbHMuIFJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgY2x1c3RlcmVkIGJ5IGNvdW50cnkuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNb2RlbHMgaW5jbHVkZSBjb3VudHJpZXMgcHJlc2VudCBpbiB0aGUgMjAwNCBFREIgcmVwb3J0LiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwLnN0YXQgPSBjKCJuIiwgInJzcSIsICJhZGoucnNxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5saW5lcyA9IGxpc3QoYygiQ291bnRyeSBmaXhlZCBlZmZlY3RzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXAoYygiTm8iLCAiWWVzIiksIDQpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9taXQgPSAiY2NvZGUiKQpgYGAKCmBgYHtyIHRibC1jb24tY291bnRyeS1mZSwgcmVzdWx0cz0iYXNpcyJ9CmNhdChwYXN0ZShlc2NhcGVfc3RhcnMoY29uX2NvdW50cnlfZmVfbW9kZWxzX291dCksIGNvbGxhcHNlID0gIlxuIiksICJcbiIpCmNhdChwYXN0ZShjb25fY291bnRyeV9mZV9tb2RlbHNfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV9EMy5odG1sIikpCmBgYAoKCiMgWWVhciBmaXhlZCBlZmZlY3RzIGZvciBPTFMgbW9kZWxzCgojIyBUYWJsZSBFMTogIlJhbmtlZCIgY29lZmZpY2llbnRzIHdpdGggYW5kIHdpdGhvdXQgeWVhciBmaXhlZCBlZmZlY3RzCgpgYGB7ciByYW5rZWQteWVhci1mZSwgd2FybmluZz1GQUxTRX0KIyBBbGwgdGhlIEZFIG1vZGVscyB0byBiZSBydW4KeWVhcl9mZV9tb2RlbHMgPC0gZXhwYW5kLmdyaWQob3V0Y29tZSA9IGMoInNiX3Byb2NlZCIsICJzYl9kYXlzX2xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNiX2Nvc3RfbG4iLCAic2JfY2FwaXRhbF9sbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb25fcHJvY2VkIiwgImNvbl9kYXlzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gYygiTWFpbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1haW4gKyBgY2l2dG90X2xhZ2AgKyBgaW50dG90X2xhZ2AgKyBgbG9hbl9sbl9sYWdgIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbiArIGBjaXZ0b3RfbGFnYCArIGBpbnR0b3RfbGFnYCArIGBsb2FuX2Jpbl9sYWdgIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbiArIGZpeGVkIGVmZmVjdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1haW4gLSAyMDAxIiwgIk1haW4gLSAyMDAxICYgMjAwMiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpICU+JQogIG11dGF0ZSh5ZWFyX2ZlID0gY29udHJvbHMgJWluJSBjKCJNYWluICsgZml4ZWQgZWZmZWN0cyIsICJNYWluIC0gMjAwMSIsICJNYWluIC0gMjAwMSAmIDIwMDIiKSwKICAgICAgICAgZGZfdG9fdXNlID0gY2FzZV93aGVuKAogICAgICAgICAgIGNvbnRyb2xzID09ICJNYWluIC0gMjAwMSIgfiAiRHJvcCAyMDAxIiwKICAgICAgICAgICBjb250cm9scyA9PSAiTWFpbiAtIDIwMDEgJiAyMDAyIiB+ICJEcm9wIDIwMDIiLAogICAgICAgICAgIFRSVUUgfiAiRnVsbCIgCiAgICAgICAgICkpCgojIE5lc3QgZmlsdGVyZWQgZGF0YSBpbnRvIGEgZGF0YSBmcmFtZQpkYXRhX3RvX3VzZSA8LSB0cmliYmxlKAogIH5kZl90b191c2UsICB+ZGF0YSwKICAiRnVsbCIsICAgICAgZWRiX2NsZWFuICU+JSBmaWx0ZXIoeWVhciA+IDIwMDAsIGluXzIwMDQgPT0gMSksCiAgIkRyb3AgMjAwMSIsIGVkYl9jbGVhbiAlPiUgZmlsdGVyKHllYXIgPiAyMDAxLCBpbl8yMDA0ID09IDEpLAogICJEcm9wIDIwMDIiLCBlZGJfY2xlYW4gJT4lIGZpbHRlcih5ZWFyID4gMjAwMiwgaW5fMjAwNCA9PSAxKQopCgojIENvbWJpbmUgZmlsdGVyZWQgZGF0YSB3aXRoIGFsbCBtb2RlbCBwYXJhbWV0ZXJzCnllYXJfZmVfbW9kZWxzX2Z1bGwgPC0gZGF0YV90b191c2UgJT4lCiAgcmlnaHRfam9pbih5ZWFyX2ZlX21vZGVscywgYnkgPSAiZGZfdG9fdXNlIikgJT4lCiAgc2VsZWN0KC1kZl90b191c2UpCgojIEJ1aWxkIGFuZCBydW4gYSBidW5jaCBvZiBkaWZmZXJlbnQgbW9kZWxzIGJhc2VkIG9uIHBhcmFtZXRlcnMgdGhhdCBkZXRlcm1pbmUKIyB3aGF0IGNvbnRyb2xzIHRvIGFkZCBhbmQgd2hldGhlciBvciBub3QgdG8gaW5jbHVkZSBjb3VudHJ5IGZpeGVkIGVmZmVjdHMKcnVuX3llYXJfZmVfbW9kZWxzIDwtIGZ1bmN0aW9uKG91dGNvbWUsIGNvbnRyb2xzLCB5ZWFyX2ZlLCBkZikgewogIG1haW5fY29udHJvbHMgPC0gImdkcGNhcF9sbl9sYWcgKyBnZHBncm93dGhfbGFnICsgcG9saXR5X2xhZyArIHBvcF9sbl9sYWciCiAgCiAgaWYgKHN0cl9kZXRlY3QoY29udHJvbHMsICJsb2FuX2xuX2xhZyIpKSB7CiAgICBhZGRpdGlvbmFsX2NvbnRyb2xzIDwtICIgKyBjaXZ0b3RfbGFnICsgaW50dG90X2xhZyArIGxvYW5fbG5fbGFnIgogIH0gZWxzZSBpZiAoc3RyX2RldGVjdChjb250cm9scywgImxvYW5fYmluX2xhZyIpKSB7CiAgICBhZGRpdGlvbmFsX2NvbnRyb2xzIDwtICIgKyBjaXZ0b3RfbGFnICsgaW50dG90X2xhZyArIGxvYW5fYmluX2xhZyIKICB9IGVsc2UgewogICAgYWRkaXRpb25hbF9jb250cm9scyA8LSAiIgogIH0KICAKICBpZiAoeWVhcl9mZSkgewogICAgeWVhciA8LSAiICsgYXMuZmFjdG9yKHllYXIpIgogIH0gZWxzZSB7CiAgICB5ZWFyIDwtICIiCiAgfQoKICBmb3JtIDwtIHBhc3RlMChvdXRjb21lLCAiIH4gIiwgcGFzdGUwKG91dGNvbWUsICJfbGFnIiksICIgKyByYW5rZWRfbGFnICsgIiwgCiAgICAgICAgICAgICAgICAgbWFpbl9jb250cm9scywgYWRkaXRpb25hbF9jb250cm9scywgeWVhcikgJT4lCiAgICBhcy5mb3JtdWxhKCkKCiAgbG0oZm9ybSwgZGF0YSA9IGRmKQp9CgojIFJ1biBhbGwgdGhlIG1vZGVscyB3aXRoaW4gdGhlIGRhdGEgZnJhbWUKeWVhcl9mZV9tb2RlbHNfYWxsIDwtIHllYXJfZmVfbW9kZWxzX2Z1bGwgJT4lCiAgbXV0YXRlKG1vZGVsID0gcG1hcCgubCA9IGxpc3Qob3V0Y29tZSwgY29udHJvbHMsIHllYXJfZmUsIGRhdGEpLCAKICAgICAgICAgICAgICAgICAgICAgIHJ1bl95ZWFyX2ZlX21vZGVscyksCiAgICAgICAgICMgQWRkIHJvYnVzdCBjbHVzdGVyZWQgU0VzCiAgICAgICAgIHJvYnVzdF9zZSA9IHBtYXAoLmwgPSBsaXN0KG1vZGVsLCBkYXRhLCAiY2NvZGUiKSwgcm9idXN0X2NsdXN0ZXJpZnkpLAogICAgICAgICAjIEFkZCBtb2RlbCBzdW1tYXJ5IHN0YXRpc3RpY3MKICAgICAgICAgZ2xhbmNlID0gbW9kZWwgJT4lIG1hcChnbGFuY2UpLAogICAgICAgICAjIEFkZCBhIGRhdGEgZnJhbWUgb2YgbW9kZWwgcGFyYW1ldGVycyB3aXRoIGNvcnJlY3QgU0VzCiAgICAgICAgIHRpZHlfcm9idXN0ID0gcm9idXN0X3NlICU+JSBtYXAofiB0aWR5KC4kY29lZikpLAogICAgICAgICBzZXNfb25seSA9IHRpZHlfcm9idXN0ICU+JSBtYXAofiAuJHN0ZC5lcnJvcikpCgojIE1ha2UgdGlueSBkYXRhIGZyYW1lIGluZGljYXRpbmcgaWYgbW9kZWwgaGFkIGNvdW50cnkgZml4ZWQgZWZmZWN0cwpmaXhlZF9lZmZlY3RzX3llYXIgPC0geWVhcl9mZV9tb2RlbHMgJT4lCiAgc2VsZWN0KGNvbnRyb2xzLCB5ZWFyX2ZlKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIG11dGF0ZSh5ZWFyX2ZlID0gaWZlbHNlKHllYXJfZmUsICJZZXMiLCAiTm8iKSkgJT4lCiAgc3ByZWFkKGNvbnRyb2xzLCB5ZWFyX2ZlKSAlPiUKICBtdXRhdGUoT3V0Y29tZSA9ICJGaXhlZCB5ZWFyIGVmZmVjdHMiKQoKIyBEaXNwbGF5IGFsbCB0aGUgcmFua2VkIGNvZWZmaWNpZW50cwpyYW5rZWRfY29lZnNfeWVhciA8LSB5ZWFyX2ZlX21vZGVsc19hbGwgJT4lCiAgIyBTcHJlYWQgb3V0IHRoZSBtb2RlbCByZXN1bHRzCiAgdW5uZXN0KHRpZHlfcm9idXN0KSAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdCh0ZXJtLCAicmFua2VkIikpICU+JQogICMgQ2xlYW4gdXAgdGhlIGVzdGltYXRlcyBhbmQgYWRkIHN0YXJzCiAgbXV0YXRlKHZhbHVlID0gcGFzdGUwKHNwcmludGYoIiUuM2YiLCByb3VuZChlc3RpbWF0ZSwgMykpLCBwX3N0YXJzKHAudmFsdWUpKSwKICAgICAgICAgb3V0Y29tZSA9IGZhY3RvcihvdXRjb21lLCBsZXZlbHMgPSB1bmlxdWUoeWVhcl9mZV9tb2RlbHMkb3V0Y29tZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcGFzdGUwKCJgIiwgdW5pcXVlKHllYXJfZmVfbW9kZWxzJG91dGNvbWUpLCAiYCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgY29udHJvbHMgPSBmYWN0b3IoY29udHJvbHMsIGxldmVscyA9IHVuaXF1ZSh5ZWFyX2ZlX21vZGVscyRjb250cm9scyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgIyBHZXQgcmlkIG9mIGV4dHJhIGNvbHVtbnMKICBzZWxlY3QoT3V0Y29tZSA9IG91dGNvbWUsIGNvbnRyb2xzLCB2YWx1ZSkgJT4lCiAgc3ByZWFkKGNvbnRyb2xzLCB2YWx1ZSkgJT4lCiAgYmluZF9yb3dzKGZpeGVkX2VmZmVjdHNfeWVhcikKYGBgCgpgYGB7ciB0YmwteWVhci1mZS1yYW5rZWQsIHJlc3VsdHM9ImFzaXMifQpjYXB0aW9uIDwtICdTdW1tYXJ5IG9mIGNvZWZmaWNpZW50cyBmb3IgdGhlIGxhZ2dlZCAiUmFua2VkIiB2YXJpYWJsZSB3aXRoIGFuZCB3aXRob3V0IGNvdW50cnkgZml4ZWQgZWZmZWN0cycKCnRibF95ZWFyX2ZlIDwtIHBhbmRvYy50YWJsZS5yZXR1cm4ocmFua2VkX2NvZWZzX3llYXIsIGNhcHRpb24gPSBjYXB0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGl0LnRhYmxlcyA9IEluZikKCmNhdCh0YmxfeWVhcl9mZSkKY2F0KHRibF95ZWFyX2ZlLCAKICAgIGZpbGUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgInRhYmxlcyIsICJhcHBfdGFibGVfRTEubWQiKSkKYGBgCgoqTm90ZSo6IE1haW4gY29udHJvbHMgYXJlIGBnZHBjYXBfbG5fbGFnYCwgYGdkcGdyb3d0aF9sYWdgLCBgcG9saXR5X2xhZ2AsIGFuZCBgcG9wX2xuX2xhZ2AKCiMjIFRhYmxlIEUyOiBTdWItaW5kaWNhdG9ycyBmb3IgIlN0YXJ0aW5nIGEgQnVzaW5lc3MiIHdpdGggYW5kIHdpdGhvdXQgeWVhciBmaXhlZCBlZmZlY3RzCgpgYGB7ciBzYi15ZWFyLWZlLCByZXN1bHRzPSJoaWRlIn0Kc2JfZmVfeWVhciA8LSB5ZWFyX2ZlX21vZGVsc19hbGwgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3Qob3V0Y29tZSwgInNiXyIpLAogICAgICAgICBjb250cm9scyAlaW4lIGMoIk1haW4gKyBmaXhlZCBlZmZlY3RzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbiArIGBjaXZ0b3RfbGFnYCArIGBpbnR0b3RfbGFnYCArIGBsb2FuX2Jpbl9sYWdgIikpICU+JQogIG11dGF0ZShvdXRjb21lID0gZmN0X2lub3JkZXIob3V0Y29tZSwgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBhcnJhbmdlKG91dGNvbWUpCgpzYl95ZWFyX2ZlX21vZGVsc19vdXQgPC0gc3RhcmdhemVyKHNiX2ZlX3llYXIkbW9kZWwsIHR5cGUgPSAiaHRtbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcC52YXIuY2FwdGlvbiA9ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlID0gc2JfZmVfeWVhciRzZXNfb25seSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9IGMoIk9MUyBtb2RlbHMuIFJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgY2x1c3RlcmVkIGJ5IGNvdW50cnkuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vZGVscyBpbmNsdWRlIGNvdW50cmllcyBwcmVzZW50IGluIHRoZSAyMDA0IEVEQiByZXBvcnQuIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcC5zdGF0ID0gYygibiIsICJyc3EiLCAiYWRqLnJzcSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5saW5lcyA9IGxpc3QoYygiWWVhciBmaXhlZCBlZmZlY3RzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcChjKCJObyIsICJZZXMiKSwgNCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbWl0ID0gInllYXIiKQpgYGAKCmBgYHtyIHRibC1zYi15ZWFyLWZlLCByZXN1bHRzPSJhc2lzIn0KY2F0KHBhc3RlKGVzY2FwZV9zdGFycyhzYl95ZWFyX2ZlX21vZGVsc19vdXQpLCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iKQpjYXQocGFzdGUoc2JfeWVhcl9mZV9tb2RlbHNfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV9FMi5odG1sIikpCmBgYAoKIyMgVGFibGUgRTM6IFN1Yi1pbmRpY2F0b3JzIGZvciAiRW5mb3JjaW5nIENvbnRyYWN0cyIgd2l0aCBhbmQgd2l0aG91dCB5ZWFyIGZpeGVkIGVmZmVjdHMKCmBgYHtyIGNvbi15ZWFyLWZlLCByZXN1bHRzPSJoaWRlIn0KY29uX2ZlX3llYXIgPC0geWVhcl9mZV9tb2RlbHNfYWxsICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KG91dGNvbWUsICJjb25fIiksCiAgICAgICAgIGNvbnRyb2xzICVpbiUgYygiTWFpbiArIGZpeGVkIGVmZmVjdHMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICJNYWluICsgYGNpdnRvdF9sYWdgICsgYGludHRvdF9sYWdgICsgYGxvYW5fYmluX2xhZ2AiKSkgJT4lCiAgbXV0YXRlKG91dGNvbWUgPSBmY3RfaW5vcmRlcihvdXRjb21lLCBvcmRlcmVkID0gVFJVRSkpICU+JQogIGFycmFuZ2Uob3V0Y29tZSkKCmNvbl95ZWFyX2ZlX21vZGVsc19vdXQgPC0gc3RhcmdhemVyKGNvbl9mZV95ZWFyJG1vZGVsLCB0eXBlID0gImh0bWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwLnZhci5jYXB0aW9uID0gIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlID0gY29uX2ZlX3llYXIkc2VzX29ubHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGVzID0gYygiT0xTIG1vZGVscy4gUm9idXN0IHN0YW5kYXJkIGVycm9ycyBjbHVzdGVyZWQgYnkgY291bnRyeS4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vZGVscyBpbmNsdWRlIGNvdW50cmllcyBwcmVzZW50IGluIHRoZSAyMDA0IEVEQiByZXBvcnQuIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXAuc3RhdCA9IGMoIm4iLCAicnNxIiwgImFkai5yc3EiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkLmxpbmVzID0gbGlzdChjKCJZZWFyIGZpeGVkIGVmZmVjdHMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcChjKCJObyIsICJZZXMiKSwgNCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb21pdCA9ICJ5ZWFyIikKYGBgCgpgYGB7ciB0YmwtY29uLXllYXItZmUsIHJlc3VsdHM9ImFzaXMifQpjYXQocGFzdGUoZXNjYXBlX3N0YXJzKGNvbl95ZWFyX2ZlX21vZGVsc19vdXQpLCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iKQpjYXQocGFzdGUoY29uX3llYXJfZmVfbW9kZWxzX291dCwgY29sbGFwc2UgPSAiXG4iKSwgIlxuIiwKICAgIGZpbGUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgInRhYmxlcyIsICJhcHBfdGFibGVfRTMuaHRtbCIpKQpgYGAKCgojIERlc2NyaXB0aW9uIG9mIFJlZm9ybSBDb2RpbmcKCipOb3QgZ2VuZXJhdGVkIHdpdGggdGhpcyBzY3JpcHQuKgoKCiMgV2hhdCBleHBsYWlucyByZWZvcm0gY29tbWl0dGVlcz8KCiMjIFRhYmxlIEYxOiBDb3JyZWxhdGVzIG9mIHJlZm9ybSBjb21taXR0ZWUgcHJlc2VuY2UKCmBgYHtyIHJlZm9ybS1jb21taXR0ZWUtcHJlc2VuY2UsIHJlc3VsdHM9ImhpZGUifQptb2RlbF9jb21taXR0ZWUgPSBnbG0oaGFzX2J1cmVhdSB+IHBfZWRiX3JhbmsgKyBpY3JnX2luZGV4ICsgCiAgICAgICAgICAgICAgICAgICAgICAgIGdkcGNhcCArIGdkcGdyb3d0aCArIGZkaV9pbnBlciArIHRyYWRlICsgbG9nMXAoaWJyZCkgKwogICAgICAgICAgICAgICAgICAgICAgICBwb2xpdHkgKyB5cnNvZmZjLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGZpbHRlcihlZGJfY2xlYW4sIHllYXIgPT0gMjAwOCksCiAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IikpCgptb2RlbF9jb21taXR0ZWVfcm9idXN0IDwtIHJvYnVzdF9jbHVzdGVyaWZ5KG1vZGVsX2NvbW1pdHRlZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGVkYl9jbGVhbiwgeWVhciA9PSAyMDA4KSwgImNjb2RlIikgJT4lCiAgbWFncml0dHI6OnVzZV9zZXJpZXMoY29lZnMpICU+JSB0aWR5KCkKCm1vZGVsX2NvbW1pdHRlZV9vdXQgPC0gc3RhcmdhemVyKG1vZGVsX2NvbW1pdHRlZSwgdHlwZSA9ICJodG1sIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcC52YXIuY2FwdGlvbiA9ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXAudmFyLmxhYmVscyA9ICJoYXNcXF9idXJlYXUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZSA9IGxpc3QobW9kZWxfY29tbWl0dGVlX3JvYnVzdCRzdGQuZXJyb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlcyA9ICJMb2dzaXRpYyByZWdyZXNzaW9uIG1vZGVsLiBZZWFyIHJlc3RyaWN0ZWQgdG8gMjAwOC4gUm9idXN0IHN0YW5kYXJkIGVycm9ycyBjbHVzdGVyZWQgYnkgY291bnRyeS4iKQpgYGAKCmBgYHtyIHRibC1yZWZvcm0tY29tbWl0dGVlLXByZXNlbmNlLCByZXN1bHRzPSJhc2lzIn0KY2F0KHBhc3RlKGVzY2FwZV9zdGFycyhtb2RlbF9jb21taXR0ZWVfb3V0KSwgY29sbGFwc2UgPSAiXG4iKSwgIlxuIikKY2F0KHBhc3RlKG1vZGVsX2NvbW1pdHRlZV9vdXQsIGNvbGxhcHNlID0gIlxuIiksICJcbiIsCiAgICBmaWxlID0gZmlsZS5wYXRoKGhlcmUoKSwgIm91dHB1dCIsICJ0YWJsZXMiLCAiYXBwX3RhYmxlX0YxLmh0bWwiKSkKYGBgCgojIyBGaWd1cmUgRjE6IENvcnJlbGF0ZXMgb2YgcmVmb3JtIGNvbW1pdHRlZSBwcmVzZW5jZQoKQ29lZmZpY2llbnRzIGZyb20gVGFibGUgRjEKCmBgYHtyIGZpZy1yZWZvcm0tY29tbWl0dGVlLXByZXNlbmNlLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjb21taXR0ZWVfdGlkeV9yb2J1c3QgPC0gbW9kZWxfY29tbWl0dGVlX3JvYnVzdCAlPiUKICBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKSAlPiUKICBtdXRhdGUoY29uZi5sb3cgPSBlc3RpbWF0ZSAtIHN0ZC5lcnJvciAqIHFub3JtKDAuOTc1KSwKICAgICAgICAgY29uZi5oaWdoID0gZXN0aW1hdGUgKyBzdGQuZXJyb3IgKiBxbm9ybSgwLjk3NSkpICU+JQogIG11dGF0ZV9hdCh2YXJzKGVzdGltYXRlLCBjb25mLmxvdywgY29uZi5oaWdoKSwKICAgICAgICAgICAgZnVucyhleHAgPSBleHAoLikpKSAlPiUKICBtdXRhdGUodGVybSA9IGZjdF9pbm9yZGVyKHRlcm0sIG9yZGVyZWQgPSBUUlVFKSkKCnBsb3RfbW9kZWxfY29tbWl0dGVlIDwtIGdncGxvdChjb21taXR0ZWVfdGlkeV9yb2J1c3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBlc3RpbWF0ZV9leHAsIHkgPSBmY3RfcmV2KHRlcm0pKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGNvbG91ciA9ICJibGFjayIpICsKICBnZW9tX3BvaW50cmFuZ2VoKGFlcyh4bWluID0gY29uZi5sb3dfZXhwLCB4bWF4ID0gY29uZi5oaWdoX2V4cCksIHNpemUgPSAwLjUpICsgCiAgbGFicyh4ID0gIk9kZHMgcmF0aW8iLCB5ID0gTlVMTCkgKwogIHRoZW1lX2VkYigpCnBsb3RfbW9kZWxfY29tbWl0dGVlCgpnZ3NhdmUocGxvdF9tb2RlbF9jb21taXR0ZWUsIAogICAgICAgZmlsZW5hbWUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgImZpZ3VyZXMiLCAiYXBwX2NvbW1pdHRlZV9wcmVzZW5jZS5wZGYiKSwKICAgICAgIHdpZHRoID0gNiwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iLCBkZXZpY2UgPSBjYWlyb19wZGYpCmdnc2F2ZShwbG90X21vZGVsX2NvbW1pdHRlZSwgCiAgICAgICBmaWxlbmFtZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAiZmlndXJlcyIsICJhcHBfY29tbWl0dGVlX3ByZXNlbmNlLnBuZyIpLAogICAgICAgd2lkdGggPSA2LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsIHR5cGUgPSAiY2Fpcm8iLCBkcGkgPSAzMDApCmBgYAoKIyMgVGFibGUgRjI6IENvcnJlbGF0ZXMgb2YgY29udHJvbCB2YXJpYWJsZXMgZnJvbSBNb2RlbHMgQTHigJNBNQoKYGBge3IgdGJsLXNpZy1zdW1tYXJ5LWExLWE1LCByZXN1bHRzPSJhc2lzIn0KZWRiX2NoZWNrc19hMl9hNSA8LSBlZGJfY2hlY2tzX21vZGVscyAlPiUKICB1bm5lc3QodGlkeV9yb2J1c3QpICU+JSBzZWxlY3QoLWdyb3VwaW5nKQoKZWRiX2NoZWNrc19hMSA8LSBtb2RlbF9pbl8yMDAxX3JvYnVzdCAlPiUgbXV0YXRlKG91dGNvbWUgPSAiaW5fMjAwMSIpCgptb2RlbF9uYW1lcyA8LSB0cmliYmxlKAogIH5tb2RlbCwgfm91dGNvbWUsCiAgIkEiLCAgICAiaW5fMjAwMSIsCiAgIkIiLCAgICAic2JfZGF5c19sbiIsCiAgIkMiLCAgICAic2JfcHJvY2VkIiwKICAiRCIsICAgICJzYl9jb3N0X2xuIiwKICAiRSIsICAgICJzYl9jYXBpdGFsX2xuIgopICU+JQogIG11dGF0ZShuYW1lX2NsZWFuID0gcGFzdGUwKCJNb2RlbCAiLCBtb2RlbCwgIjxicj4iLCAiYCIsIG91dGNvbWUsICJgIikpCgplZGJfY2hlY2tzX3NpZ25pZmljYW5jZSA8LSBiaW5kX3Jvd3MoZWRiX2NoZWNrc19hMSwgZWRiX2NoZWNrc19hMl9hNSkgJT4lCiAgbGVmdF9qb2luKG1vZGVsX25hbWVzLCBieSA9ICJvdXRjb21lIikgJT4lCiAgZmlsdGVyKHRlcm0gIT0gIihJbnRlcmNlcHQpIiwgIXN0cl9kZXRlY3QodGVybSwgInNiXyIpKSAlPiUKICBtdXRhdGUoc2lnbmlmaWNhbmNlID0gY2FzZV93aGVuKAogICAgcC52YWx1ZSA8IDAuMTAgJiBzaWduKGVzdGltYXRlKSA9PSAxIH4gIisiLAogICAgcC52YWx1ZSA8IDAuMTAgJiBzaWduKGVzdGltYXRlKSA9PSAtMSB+ICLiiJIiLAogICAgVFJVRSB+ICIiCiAgKSkgJT4lCiAgbXV0YXRlKHRlcm0gPSBwYXN0ZTAoImAiLCB0ZXJtLCAiYCIpLAogICAgICAgICB0ZXJtID0gZmN0X2lub3JkZXIodGVybSwgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBzZWxlY3QoYCBgID0gdGVybSwgc2lnbmlmaWNhbmNlLCBuYW1lX2NsZWFuKSAlPiUKICBzcHJlYWQobmFtZV9jbGVhbiwgc2lnbmlmaWNhbmNlKQoKY2FwdGlvbiA8LSAiQ29ycmVsYXRlcyBvZiByZWxldmFudCB2YXJpYWJsZXMgd2l0aCBzZWxlY3Rpb24gaW50byAyMDAxIHNhbXBsZSBhbmQgd2l0aCBvdXRjb21lcyIKCnRibF9lZGJfY2hlY2tzX3NpZyA8LSBwYW5kb2MudGFibGUucmV0dXJuKGVkYl9jaGVja3Nfc2lnbmlmaWNhbmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdGlvbiA9IGNhcHRpb24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdC50YWJsZXMgPSBJbmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1c3RpZnkgPSAibGNjY2NjIiwgbWlzc2luZyA9ICIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSAibXVsdGlsaW5lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcC5saW5lLmJyZWFrcyA9IFRSVUUpCgpjYXQodGJsX2VkYl9jaGVja3Nfc2lnKQpjYXQodGJsX2VkYl9jaGVja3Nfc2lnLCAKICAgIGZpbGUgPSBmaWxlLnBhdGgoaGVyZSgpLCAib3V0cHV0IiwgInRhYmxlcyIsICJhcHBfdGFibGVfRjIubWQiKSkKYGBgCgoqTm90ZSo6IEEgbmVnYXRpdmUgY29lZmZpY2llbnQgZm9yIHRoZSBvdXRjb21lIHZhcmlhYmxlcyBpbmRpY2F0ZXMgaW1wcm92ZW1lbnRzLgoKRm9yIG1vZGVscyBhbmQgbWVhc3VyZXMsIHNlZSBzZWN0aW9uICJIb3cgY29udHJvbCB2YXJpYWJsZXMgcmVsYXRlIHRvIGJlaW5nIGluIHRoZSBzYW1wbGUgYW5kIHRvIHRoZSBvdXRjb21lcyIgYWJvdmUuCgoKIyMgVGFibGUgRjM6IFJhbmtpbmdzIGluIDIwMDUgYW5kIDIwMTQKCmBgYHtyIHJlZm9ybS1jb21taXR0ZWUtMjAwNS0yMDE0LCByZXN1bHRzPSJoaWRlIn0KZWRiX3JhbmtpbmdzIDwtIGVkYl9jbGVhbiAlPiUKICBzZWxlY3QoY2NvZGUsIHllYXIsIHBfZWRiX3JhbmssIGhhc19idXJlYXUpICU+JQogIGZpbHRlcih5ZWFyICVpbiUgYygyMDA1LCAyMDE0KSkgJT4lCiAgc3ByZWFkKHllYXIsIHBfZWRiX3JhbmspICU+JQogIG11dGF0ZShjaGFuZ2VfaW5fcmFua2luZyA9IGAyMDE0YCAtIGAyMDA1YCkKCm1vZGVsX3JhbmtpbmdzIDwtIGxtKGAyMDE0YCB+IGAyMDA1YCArIGhhc19idXJlYXUsCiAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBlZGJfcmFua2luZ3MpCgptb2RlbF9yYW5raW5nc19pbnRlcmFjdGlvbiA8LSBsbShgMjAxNGAgfiBgMjAwNWAgKyBoYXNfYnVyZWF1ICsgYDIwMDVgICogaGFzX2J1cmVhdSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGVkYl9yYW5raW5ncykKCm1vZGVsX3JhbmtpbmdzX2NoYW5nZSA8LSBsbShjaGFuZ2VfaW5fcmFua2luZyB+IGhhc19idXJlYXUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZWRiX3JhbmtpbmdzKQoKdmFyX2xhYnMgPC0gYygiMjAwNSByYW5raW5nIiwgIkhhcyByZWZvcm0gY29tbWl0dGVlIiwKICAgICAgICAgICAgICAiMjAwNSByYW5raW5nIMOXIGhhcyByZWZvcm0gY29tbWl0dGVlIikKCm1vZGVsX3JhbmtpbmdzX291dCA8LSBzdGFyZ2F6ZXIobW9kZWxfcmFua2luZ3MsIG1vZGVsX3JhbmtpbmdzX2ludGVyYWN0aW9uLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbF9yYW5raW5nc19jaGFuZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJodG1sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXAudmFyLmNhcHRpb24gPSAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXAudmFyLmxhYmVscyA9IGMoIjIwMTQiLCAiQ2hhbmdlIGluIHJhbmtpbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3ZhcmlhdGUubGFiZWxzID0gdmFyX2xhYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90ZXMgPSAiT0xTIG1vZGVscy4gTm9uLXJvYnVzdCBzdGFuZGFyZCBlcnJvcnMuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwLnN0YXQgPSBjKCJuIiwgInJzcSIsICJhZGoucnNxIikpCmBgYAoKYGBge3IgdGJsLXJlZm9ybS1jb21taXR0ZWUtMjAwNS0yMDE0LCByZXN1bHRzPSJhc2lzIn0KY2F0KHBhc3RlKGVzY2FwZV9zdGFycyhtb2RlbF9yYW5raW5nc19vdXQpLCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iKQpjYXQocGFzdGUobW9kZWxfcmFua2luZ3Nfb3V0LCBjb2xsYXBzZSA9ICJcbiIpLCAiXG4iLAogICAgZmlsZSA9IGZpbGUucGF0aChoZXJlKCksICJvdXRwdXQiLCAidGFibGVzIiwgImFwcF90YWJsZV9GMy5odG1sIikpCmBgYAoKCiMgSW5kaWEgZXhwZXJpbWVudCBzdXJ2ZXkgdGV4dAoKKk5vdCBnZW5lcmF0ZWQgd2l0aCB0aGlzIHNjcmlwdC4qCgoKIyBJbnZlc3RvciBleHBlcmltZW50IHN1cnZleSB0ZXh0CgoqTm90IGdlbmVyYXRlZCB3aXRoIHRoaXMgc2NyaXB0LioK