This notebook conducts and demonstrates the results of the
Random-effects meta-analysis performed on each healthcare system’s
Cox-proportional hazards (Cox-PH) model results.
Of note, this analysis is performed only on adult patients due to the
pediatric cohort’s low incidence of both poor health outcomes and
neurological diagnoses during COVID-19 hospitalization.
Analyze Risk via Forest Plots
Prepare data for forest plots
# adults
meta_results_adults_cns_df_forest = prepare_data_forest_plots(meta_results_adults_cns_df)
meta_results_adults_pns_df_forest = prepare_data_forest_plots(meta_results_adults_pns_df)
Tidy up results
meta_results_adults_cns_df_forest_tidy <- meta_results_adults_cns_df_forest %>%
distinct(analysis, TE.random, lower.random, upper.random,`p-value`, lower.predict, upper.predict, I2, lower.I2, upper.I2, H, lower.H, upper.H, tau2, lower.tau2, upper.tau2, CI) %>%
mutate(neuro_status = "CNS") %>%
select(neuro_status, everything())
meta_results_adults_pns_df_forest_tidy <- meta_results_adults_pns_df_forest %>%
distinct(analysis, TE.random, lower.random, upper.random,`p-value`, lower.predict, upper.predict, I2, lower.I2, upper.I2, H, lower.H, upper.H, tau2, lower.tau2, upper.tau2, CI) %>%
mutate(neuro_status = "PNS") %>%
select(neuro_status, everything())
meta_results_tidy <- rbind(meta_results_adults_cns_df_forest_tidy,
meta_results_adults_pns_df_forest_tidy)
write.csv(meta_results_tidy, "tables/Table2_meta_results.csv", row.names = FALSE)
Next, we will create a scale function to identify the min and max CI
for each healthcare system. This will help us exclude healthcare systems
with values of ‘Inf’ or very large confidence intervals.
scale_plot <- function(meta_results_df_forest, site_exclude = NULL) {
scale <- meta_results_df_forest %>%
filter(
!Site %in% site_exclude,
#!analysis %in% invalid_sites,
!CI.Low == "Inf",
!CI.High == "Inf"
) %>%
mutate(
min_est = min(CI.Low, na.rm = TRUE) - 1,
max_est = max(CI.High, na.rm = TRUE) + 1,
min_est = if_else(min_est + 1 >= -1, min(CI.Low, na.rm = TRUE)-0.1, min_est),
min_est = if_else(min_est > 1, 0.5, min_est),
max_est = if_else(max_est - 1 < 1, 1.1, max_est)) %>%
distinct(min_est, max_est)
return(scale)
}
CNS - Risk of Discharge
te.random = meta_results_adults_cns_df_forest %>%
filter(analysis == "time_first_discharge_reg_elix") %>%
distinct(TE.random) %>%
as.numeric() %>%
round(.,2)
te.random.ci_lower = meta_results_adults_cns_df_forest %>%
filter(analysis == "time_first_discharge_reg_elix") %>%
distinct(lower.random) %>%
as.numeric()
te.random.ci_upper = meta_results_adults_cns_df_forest %>%
filter(analysis == "time_first_discharge_reg_elix") %>%
distinct(upper.random) %>%
as.numeric()
length_stay_first_results <- meta_results_adults_cns_df_forest %>%
slice(grep(paste("time_first_discharge_reg_elix", collapse = "|"), analysis)) %>%
#add_row(.before = 1) %>%
add_row(.after = nrow(.)) %>%
mutate(Site = ifelse(is.na(Site), "Effect size", Site),
`Hazard Ratio` = ifelse(is.na(`Hazard Ratio`), round(te.random, 2), `Hazard Ratio`),
`p-value` = ifelse(`p-value` < 0.001, "< .001*", round(`p-value`, 3))) %>%
fill(`p-value`, .direction = "down") %>%
mutate(`p-value` = ifelse(Site == "Effect size", `p-value`, ""),
CI.Low = ifelse(Site == "Effect size", te.random.ci_lower, CI.Low),
CI.High = ifelse(Site == "Effect size", te.random.ci_upper, CI.High),
`Hazard Ratio ` = paste(`Hazard Ratio`, '(', CI.Low, ',', CI.High, ')'))
## define forest plot shapes
# shape #16 is normal circle; #18 is diamond
shapes <- rep(16, times = nrow(length_stay_first_results))
shapes[length(shapes)] <- 18
sizes <- rep(3.25, times = nrow(length_stay_first_results))
sizes[length(sizes)] <- 5
scale <- scale_plot(length_stay_first_results, site_exclude = c("ICSM"))
# note: `Hazard Ratio ` with confidence intervals has an extra space and used by `right_side_data` param
p1 <- forester(
left_side_data = length_stay_first_results %>%
select(Site) %>%
rename("Healthcare System" = "Site"),
estimate = length_stay_first_results$`Hazard Ratio`,
ci_low = length_stay_first_results$CI.Low,
ci_high = length_stay_first_results$CI.High,
right_side_data = length_stay_first_results[, c("Hazard Ratio ", "p-value")],
display = TRUE,
nudge_x = .5,
font_family = "arial",
arrows = TRUE,
arrow_labels = c("Decreased Risk", "Increased Risk"),
null_line_at = 1,
xlim = c(scale$min_est, scale$max_est),
#xbreaks = c(scale$min_est, 1, scale$max_est),
point_sizes = sizes,
point_shapes = shapes,
file_path = here::here(paste0("figures/forestplot_adult_cns_discharge.png")))
p1
CNS - Risk of Mortality
te.random = meta_results_adults_cns_df_forest %>%
filter(analysis == "deceased_reg_elix") %>%
distinct(TE.random) %>%
as.numeric() %>%
round(.,2)
te.random.ci_lower = meta_results_adults_cns_df_forest %>%
filter(analysis == "deceased_reg_elix") %>%
distinct(lower.random) %>%
as.numeric()
te.random.ci_upper = meta_results_adults_cns_df_forest %>%
filter(analysis == "deceased_reg_elix") %>%
distinct(upper.random) %>%
as.numeric()
deceased_results <- meta_results_adults_cns_df_forest %>%
slice(grep(paste("deceased_reg_elix", collapse = "|"), analysis)) %>%
#add_row(.before = 1) %>%
add_row(.after = nrow(.)) %>%
mutate(Site = ifelse(is.na(Site), "Effect size", Site),
`Hazard Ratio` = ifelse(is.na(`Hazard Ratio`), round(te.random, 2), `Hazard Ratio`),
`p-value` = ifelse(`p-value` < 0.001, "< .001*", round(`p-value`, 3))) %>%
fill(`p-value`, .direction = "down") %>%
mutate(`p-value` = ifelse(Site == "Effect size", `p-value`, ""),
CI.Low = ifelse(Site == "Effect size", te.random.ci_lower, CI.Low),
CI.High = ifelse(Site == "Effect size", te.random.ci_upper, CI.High),
`Hazard Ratio ` = paste(`Hazard Ratio`, '(', CI.Low, ',', CI.High, ')'))
## define forest plot shapes
# shape #16 is normal circle; #18 is diamond
shapes <- rep(16, times = nrow(deceased_results))
shapes[length(shapes)] <- 18
sizes <- rep(3.25, times = nrow(deceased_results))
sizes[length(sizes)] <- 5
scale <- scale_plot(deceased_results, site_exclude = c("ICSM"))
# note: `Hazard Ratio ` with confidence intervals has an extra space and used by `right_side_data` param
p2 <- forester(
left_side_data = deceased_results %>%
select(Site) %>%
rename("Healthcare System" = "Site"),
estimate = deceased_results$`Hazard Ratio`,
ci_low = deceased_results$CI.Low,
ci_high = deceased_results$CI.High,
right_side_data = deceased_results[, c("Hazard Ratio ", "p-value")],
display = TRUE,
nudge_x = .5,
font_family = "arial",
arrows = TRUE,
arrow_labels = c("Decreased Risk", "Increased Risk"),
null_line_at = 1,
xlim = c(scale$min_est, scale$max_est),
#xbreaks = c(scale$min_est, 1, scale$max_est),
point_sizes = sizes,
point_shapes = shapes,
file_path = here::here(paste0("figures/forestplot_adult_cns_mortality.png")))
p2
PNS - Risk of Discharge
te.random = meta_results_adults_pns_df_forest %>%
filter(analysis == "time_first_discharge_reg_elix") %>%
distinct(TE.random) %>%
as.numeric() %>%
round(.,2)
te.random.ci_lower = meta_results_adults_pns_df_forest %>%
filter(analysis == "time_first_discharge_reg_elix") %>%
distinct(lower.random) %>%
as.numeric()
te.random.ci_upper = meta_results_adults_pns_df_forest %>%
filter(analysis == "time_first_discharge_reg_elix") %>%
distinct(upper.random) %>%
as.numeric()
length_stay_first_results <- meta_results_adults_pns_df_forest %>%
slice(grep(paste("time_first_discharge_reg_elix", collapse = "|"), analysis)) %>%
#add_row(.before = 1) %>%
add_row(.after = nrow(.)) %>%
mutate(Site = ifelse(is.na(Site), "Effect size", Site),
`Hazard Ratio` = ifelse(is.na(`Hazard Ratio`), round(te.random, 2), `Hazard Ratio`),
`p-value` = ifelse(`p-value` < 0.001, "< .001*", round(`p-value`, 3))) %>%
fill(`p-value`, .direction = "down") %>%
mutate(`p-value` = ifelse(Site == "Effect size", `p-value`, ""),
CI.Low = ifelse(Site == "Effect size", te.random.ci_lower, CI.Low),
CI.High = ifelse(Site == "Effect size", te.random.ci_upper, CI.High),
`Hazard Ratio ` = paste(`Hazard Ratio`, '(', CI.Low, ',', CI.High, ')'))
## define forest plot shapes
# shape #16 is normal circle; #18 is diamond
shapes <- rep(16, times = nrow(length_stay_first_results))
shapes[length(shapes)] <- 18
sizes <- rep(3.25, times = nrow(length_stay_first_results))
sizes[length(sizes)] <- 5
scale <- scale_plot(length_stay_first_results, site_exclude = c("ICSM"))
# note: `Hazard Ratio ` with confidence intervals has an extra space and used by `right_side_data` param
p3 <- forester(
left_side_data = length_stay_first_results %>%
select(Site) %>%
rename("Healthcare System" = "Site"),
estimate = length_stay_first_results$`Hazard Ratio`,
ci_low = length_stay_first_results$CI.Low,
ci_high = length_stay_first_results$CI.High,
right_side_data = length_stay_first_results[, c("Hazard Ratio ", "p-value")],
display = TRUE,
nudge_x = .5,
font_family = "arial",
arrows = TRUE,
arrow_labels = c("Decreased Risk", "Increased Risk"),
null_line_at = 1,
xlim = c(scale$min_est, scale$max_est),
#xbreaks = c(scale$min_est, 1, scale$max_est),
point_sizes = sizes,
point_shapes = shapes,
file_path = here::here(paste0("figures/forestplot_adult_pns_discharge.png")))
p3
PNS - Risk of Mortality
te.random = meta_results_adults_pns_df_forest %>%
filter(analysis == "deceased_reg_elix") %>%
distinct(TE.random) %>%
as.numeric() %>%
round(.,2)
te.random.ci_lower = meta_results_adults_pns_df_forest %>%
filter(analysis == "deceased_reg_elix") %>%
distinct(lower.random) %>%
as.numeric()
te.random.ci_upper = meta_results_adults_pns_df_forest %>%
filter(analysis == "deceased_reg_elix") %>%
distinct(upper.random) %>%
as.numeric()
deceased_results <- meta_results_adults_pns_df_forest %>%
slice(grep(paste("deceased_reg_elix", collapse = "|"), analysis)) %>%
#add_row(.before = 1) %>%
add_row(.after = nrow(.)) %>%
mutate(Site = ifelse(is.na(Site), "Effect size", Site),
`Hazard Ratio` = ifelse(is.na(`Hazard Ratio`), round(te.random, 2), `Hazard Ratio`),
`p-value` = ifelse(`p-value` < 0.001, "< .001*", round(`p-value`, 3))) %>%
fill(`p-value`, .direction = "down") %>%
mutate(`p-value` = ifelse(Site == "Effect size", `p-value`, ""),
CI.Low = ifelse(Site == "Effect size", te.random.ci_lower, CI.Low),
CI.High = ifelse(Site == "Effect size", te.random.ci_upper, CI.High),
`Hazard Ratio ` = paste(`Hazard Ratio`, '(', CI.Low, ',', CI.High, ')'))
## define forest plot shapes
# shape #16 is normal circle; #18 is diamond
shapes <- rep(16, times = nrow(deceased_results))
shapes[length(shapes)] <- 18
sizes <- rep(3.25, times = nrow(deceased_results))
sizes[length(sizes)] <- 5
scale <- scale_plot(deceased_results, site_exclude = c("ICSM", "HPG23"))
# note: `Hazard Ratio ` with confidence intervals has an extra space and used by `right_side_data` param
p4 <- forester(
left_side_data = deceased_results %>%
select(Site) %>%
rename("Healthcare System" = "Site"),
estimate = deceased_results$`Hazard Ratio`,
ci_low = deceased_results$CI.Low,
ci_high = deceased_results$CI.High,
right_side_data = deceased_results[, c("Hazard Ratio ", "p-value")],
display = TRUE,
nudge_x = .5,
font_family = "arial",
arrows = TRUE,
arrow_labels = c("Decreased Risk", "Increased Risk"),
null_line_at = 1,
xlim = c(scale$min_est, scale$max_est),
#xbreaks = c(scale$min_est, 1, scale$max_est),
point_sizes = sizes,
point_shapes = shapes,
file_path = here::here(paste0("figures/forestplot_adult_pns_mortality.png")))
p4
LS0tDQp0aXRsZTogIk1ldGEtQW5hbHlzaXM6IENveC1QSCBNb2RlbHMiDQpkYXRlOiAiMDQvMTEvMjAyMyINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHNwYWNlbGFiDQotLS0NCg0KVGhpcyBub3RlYm9vayBjb25kdWN0cyBhbmQgZGVtb25zdHJhdGVzIHRoZSByZXN1bHRzIG9mIHRoZSBSYW5kb20tZWZmZWN0cyBtZXRhLWFuYWx5c2lzIHBlcmZvcm1lZCBvbiBlYWNoIGhlYWx0aGNhcmUgc3lzdGVtJ3MgQ294LXByb3BvcnRpb25hbCBoYXphcmRzIChDb3gtUEgpIG1vZGVsIHJlc3VsdHMuDQoNCk9mIG5vdGUsIHRoaXMgYW5hbHlzaXMgaXMgcGVyZm9ybWVkIG9ubHkgb24gYWR1bHQgcGF0aWVudHMgZHVlIHRvIHRoZSBwZWRpYXRyaWMgY29ob3J0J3MgbG93IGluY2lkZW5jZSBvZiBib3RoIHBvb3IgaGVhbHRoIG91dGNvbWVzIGFuZCBuZXVyb2xvZ2ljYWwgZGlhZ25vc2VzIGR1cmluZyBDT1ZJRC0xOSBob3NwaXRhbGl6YXRpb24uDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobWV0YWZvcikNCmxpYnJhcnkobWV0YSkNCmxpYnJhcnkoY293cGxvdCkNCnNvdXJjZSgiUi9mb3Jlc3Rlcl9jdXN0b20uUiIpDQpzb3VyY2UoIlIvYW5hbHl6ZV9zdXJ2aXZhbC5SIikNCmBgYA0KDQojICoqSW1wb3J0IERhdGEgZnJvbSBlYWNoIEhlYWx0aGNhcmUgc3lzdGVtKioNCg0KRWFjaCBwYXJ0aWNpcGF0aW5nIGhlYWx0aGNhcmUgc3lzdGVtIHJhbiB0aGUgYW5hbHlzaXMgbG9jYWxseSBvbiBwYXRpZW50IGxldmVsIGRhdGEgdXNpbmcgb3VyIFtjdXN0b21pemVkIFIgcGFja2FnZV0oaHR0cHM6Ly9naXRodWIuY29tL2NvdmlkY2xpbmljYWwvUGhhc2UyLjFOZXVyb1JQYWNrYWdlKS4gVGhlIG91dHB1dCBvZiBlYWNoIGxvY2FsIGFuYWx5c2lzIGNvbnNpc3RlZCBvZiBvbmx5IHRoZSBzdW1tYXJ5IHJlc3VsdHMgKHJhdGhlciB0aGFuIHBhdGllbnQgbGV2ZWwgZGF0YSkuIFRoZSBtb2RlbCBzdW1tYXJ5IHJlc3VsdHMgZnJvbSBlYWNoIGhlYWx0aGNhcmUgc3lzdGVtIHdlcmUgdGhlbiBhZ2dyZWdhdGVkIGFuZCBhcmUgaW1wb3J0ZWQgYW5kIHRoZW4gY29tYmluZWQgdXNpbmcgdGhlIGZvbGxvd2luZyBjb2RlOg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyByZWFkIGluIGZpbGVzIGZyb20gcmVzdWx0cyBmb2xkZXIgDQojIHRoaXMgZm9sZGVyIGNvbnRhaW5zIGFsbCBvZiB0aGUgbG9jYWwgaGVhbHRoY2FyZSBzeXN0ZW0gbGV2ZWwgYW5hbHlzZXMNCnJkYXMgPC0gbGlzdC5maWxlcygNCiAgcGF0aCA9ICJyZXN1bHRzIiwNCiAgcGF0dGVybiA9ICIucmRhIiwNCiAgZnVsbC5uYW1lcyA9IFRSVUUNCikNCmZvciAocmRhIGluIHJkYXMpIHsNCiAgbG9hZChyZGEpDQp9DQoNCnJtKHJkYXMsIHJkYSkNCg0KIyBjcmVhdGUgYSBsaXN0IG9mIHBhcnRpY2lwYXRpbmcgaGVhbHRoY2FyZSBzeXN0ZW1zIGZyb20gb3VyIHN0dWR5IHRyYWNraW5nIHNwcmVhZHNoZWV0DQpzaXRlX2dvb2dsZV91cmwgPC0gImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFlcGNZTmRfMGpDVU1rdE9IZjhtejV2NjUxenkxSkFMRDZQZ3pvYnJHV0RZL2VkaXQ/dXNwPXNoYXJpbmciDQoNCiMgbG9hZCBzaXRlIHBhcmFtZXRlcnMNCnNpdGVfcGFyYW1zIDwtIGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoc2l0ZV9nb29nbGVfdXJsLCBzaGVldCA9IDEpDQpzaXRlX2F2YWlscyA8LSBnb29nbGVzaGVldHM0OjpyZWFkX3NoZWV0KHNpdGVfZ29vZ2xlX3VybCwgc2hlZXQgPSAyKQ0KDQojIGZpbHRlciB0aGUgbGlzdCBvZiBzaXRlcyB3aG8gcmFuIHRoZSBhbmFseXNpcw0Kc29ydGVkX3NpdGVzIDwtIHNpdGVfYXZhaWxzICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGRhdGVfdjRfcmVjZWl2ZWQpKSAlPiUNCiAgcHVsbChzaXRlaWQpICU+JQ0KICBwYXN0ZSgicmVzdWx0cyIsIHNlcCA9ICJfIikNCg0KIyBsaXN0IHNpdGVzIHdpdGhvdXQgcmFjZQ0Kc2l0ZXNfd29fcmFjZSA8LSBzaXRlX3BhcmFtcyAlPiUNCiAgZmlsdGVyKCFpbmNsdWRlX3JhY2UpICU+JQ0KICBwdWxsKHNpdGVpZCkNCg0KIyBjb21iaW5lIGFsbCByZGEgZmlsZXMgd2l0aCAncmVzdWx0cycgaW4gbmFtZQ0KcmVzdWx0cyA8LSBtZ2V0KGxzKHBhdHRlcm4gPSAicmVzdWx0cyIpKQ0KDQojIyByZWFkIGluIHB0IGNvdW50cw0KcHRfY291bnRzX2RmIDwtIHJlYWQuY3N2KCd0YWJsZXMvc2l0ZV9wdF9jb3VudHMuY3N2JykNCmBgYA0KIyAqKlByZS1wcm9jZXNzaW5nKioNCg0KIyMgRGVmaW5lIHBhcmFtZXRlcnMgdG8gc3BlY2lmeSBtb2RlbHMgdG8gZXZhbHVhdGUNCg0KRHVyaW5nIHRoZSBsb2NhbGx5IHJ1biBhbmFseXNpcywgZWFjaCBoZWFsdGhjYXJlIHN5c3RlbSByYW4gYSBzZXJpZXMgb2YgQ294LVBIIG1vZGVscyBpbiBvcmRlciB0byBwZXJmb3JtIHN1cHBsZW1lbnRhcnkgYW5hbHlzaXMgdG8gZXZhbHVhdGUgdGhlIG9wdGltYWwgY29tb3JiaWRpdHkgYWRqdXN0bWVudCBtZXRob2QgYW5kIGNlbnNvcmluZyBjdXRvZmYgcG9pbnQuDQoNCmBgYHtyfQ0Kb3V0Y29tZXMgPC0gYygidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiLCAiZGVjZWFzZWRfcmVnX2VsaXgiKQ0KDQpjb21vcmJfYWRqIDwtIGMoImxwY2EiLCAic2NvcmUiLCAiaW5kIikNCg0KY2Vuc29yX2N1dCA8LSBjKCIzMCIsICI2MCIsICI5MCIpDQpgYGANCg0KIyMgSWRlbnRpZnkgc2l0ZXMgdG8gaW5jbHVkZSBpbiB0aGUgYW5hbHlzaXMNCg0KSW4gdGhpcyBhbmFseXNpcywgd2Ugb25seSBpbmNsdWRlZCBhIGhlYWx0aGNhcmUgc3lzdGVtIGlmIHRoZXkgaGFkIFw+PSAzIGFkdWx0IHBhdGllbnRzIHdpdGggYSBuZXVyb2xvZ2ljYWwgZGlhZ25vc2lzLg0KDQpgYGB7cn0NCnNpdGVzX2FkdWx0IDwtIHB0X2NvdW50c19kZiAlPiUgDQogIGZpbHRlcihwb3B1bGF0aW9uID09ICJBZHVsdCIpICU+JSANCiAgbXV0YXRlKG5ldXJvX3N1bSA9IG5fdmFyX0NlbnRyYWwgKyBuX3Zhcl9QZXJpcGhlcmFsKSAlPiUgDQogIGZpbHRlcighbmV1cm9fc3VtIDwgMykgJT4lIA0KICBkaXN0aW5jdChzaXRlKSAlPiUgDQogIG11dGF0ZShzaXRlID0gZ3N1YigiX3Jlc3VsdHMiLCAiIiwgc2l0ZSkpDQpgYGANCg0KIyAqKlJhbmRvbS1FZmZlY3RzIE1ldGEtQW5hbHlzaXMqKg0KDQojIyBHZXQgQ294LVBIIG1vZGVsIHJlc3VsdHMNCg0KVGhpcyBub3RlYm9vayBzcGVjaWZpZXMgdGhlIHBhcmFtZXRlcnMgdG8gbG9hZCBpbiB0aGUgQ294LVBIIHJlc3VsdHMgdXNpbmcgYSBgY2Vuc29yX2N1dG9mZmA9JzkwJyAoZGF5cyBzaW5jZSBpbml0aWFsIGhvc3BpdGFsaXphdGlvbikgYW5kIHRoZSBgY29tb3JiX21ldGhvZGA9J2luZCcgd2hpY2ggYWRqdXN0cyBmb3IgcGF0aWVudCBjb21vcmJpZGl0eSBidXJkZW4gYnkgdHJlYXRpbmcgZWFjaCBpbmRpdmlkdWFsIGNvbW9yYmlkaXR5IG9mIHRoZSBFbGl4aGF1c2VyIENvbW9yYmlkaXR5IEluZGV4IGFzIGFuIGluZGl2aWR1YWwgbW9kZWwgY292YXJpYXRlIChiaW5hcnkgdmFyaWFibGUgaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCB0aGUgcGF0aWVudCBwcmV2aW91c2x5IHdhcyBkaWFnbm9zZWQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBjb21vcmJpZGl0eSkuDQoNCmBgYHtyfQ0KY294X3Jlc3VsdHNfYWR1bHRzIDwtIGxpc3QoKQ0KDQpmb3IgKG91dGNvbWVfaSBpbiBvdXRjb21lcykgew0KICBjb3hfcmVzdWx0c19hZHVsdHNbW291dGNvbWVfaV1dIDwtDQogICAgcmVzdWx0cyAlPiUNCiAgICBsYXBwbHkoZ2V0X2NveF9yb3csIHBvcHVsYXRpb24gPSAiYWR1bHRzIiwgY29tb3JiX21ldGhvZCA9ICJpbmQiLCBjZW5zb3JfY3V0b2ZmID0gIjkwIiwgb3V0Y29tZSA9IG91dGNvbWVfaSkgJT4lDQogICAgYmluZF9yb3dzKCkgJT4lDQogICAgbXV0YXRlKG91dGNvbWUgPSBvdXRjb21lX2kpDQp9DQpgYGANCg0KIyMgUmFuZG9tLWVmZmVjdHMgbWV0YS1hbmFseXNpcyAtIENOUw0KDQpOZXh0LCB3ZSB3aWxsIHBlcmZvcm0gYSByYW5kb20tZWZmZWN0cyBtZXRhLWFuYWx5c2lzIHRvIGV2YWx1YXRlIHRoZSByaXNrIG9mIG1vcnRhbGl0eSBvciBwcm9sb25nZWQgaG9zcGl0YWwgc3RheSBpbiB0aGUgQ05TIGdyb3VwIHZzIHRoZSBOTkMgZ3JvdXAuIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsIGNvbXB1dGUgdGhlIHJhbmRvbS1lZmZlY3RzIG1vZGVsIGZvciBlYWNoIG91dGNvbWUgKG1vcnRhbGl0eSBhbmQgZGlzY2hhcmdlKS4NCg0KTm90ZXM6DQoNCi0gICBTZXQgYHNtID0gIkhSImAgd2hlbiBlc3RpbWF0ZSBpcyBsb2dIUiAod2hpY2ggaXMgY29lZiBpbiBvdXIgbW9kZWwpLg0KDQogICAgLSAgIFNlYXJjaCBsb2dIUiBpbiBbY3Jhbl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL21ldGEvbWV0YS5wZGYpIHRvIHNlZSBhbiBleGFtcGxlDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIyBhZHVsdHMgDQptZXRhX3Jlc3VsdHNfYWR1bHRzX2NucyA8LSBsaXN0KCkNCg0KZm9yIChvdXRjb21lX2kgaW4gb3V0Y29tZXMpIHsNCiAgbWV0YV9yZXN1bHRzX2FkdWx0c19jbnNbW291dGNvbWVfaV1dIDwtDQogICAgY294X3Jlc3VsdHNfYWR1bHRzW1tvdXRjb21lX2ldXSAlPiUNCiAgICBmaWx0ZXIoc2l0ZSAlaW4lIHNpdGVzX2FkdWx0JHNpdGUpICU+JSANCiAgICBiaW5kX3Jvd3MoKSAlPiUNCiAgICBkYXRhLmZyYW1lKCkgJT4lDQogICAgZmlsdGVyKHZhcmlhYmxlID09ICJuZXVyb19wb3N0Q2VudHJhbCIpICU+JQ0KICAgIG1ldGFnZW4oDQogICAgICBURSA9IGNvZWYsDQogICAgICBzZVRFID0gc2UuY29lZi4sDQogICAgICBkYXRhID0gLiwNCiAgICAgIHNtID0gIkhSIiwgIyBoYXphcmQgcmF0aW9zDQogICAgICBjb21iLnJhbmRvbSA9IFRSVUUsDQogICAgICBjb21iLmZpeGVkID0gRkFMU0UsDQogICAgICBtZXRob2QudGF1ID0gIkRMIiwgIyBkZWZhdWx0IHRhdSBtZXRob2QNCiAgICAgIGhha24gPSBGQUxTRSwNCiAgICAgIHByZWRpY3Rpb24gPSBUUlVFLA0KICAgICAgc3R1ZGxhYiA9IHNpdGUNCiAgICApDQp9DQpgYGANCg0KIyMgUmFuZG9tLWVmZmVjdHMgbWV0YS1hbmFseXNpcyAtIFBOUw0KDQpOZXh0LCB3ZSB3aWxsIHBlcmZvcm0gYSByYW5kb20tZWZmZWN0cyBtZXRhLWFuYWx5c2lzIHRvIGV2YWx1YXRlIHRoZSByaXNrIG9mIG1vcnRhbGl0eSBvciBwcm9sb25nZWQgaG9zcGl0YWwgc3RheSBpbiB0aGUgUE5TIGdyb3VwIHZzIHRoZSBOTkMgZ3JvdXAuIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsIGNvbXB1dGUgdGhlIHJhbmRvbS1lZmZlY3RzIG1vZGVsIGZvciBlYWNoIG91dGNvbWUgKG1vcnRhbGl0eSBhbmQgZGlzY2hhcmdlKS4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMjIGFkdWx0cw0KbWV0YV9yZXN1bHRzX2FkdWx0c19wbnMgPC0gbGlzdCgpDQoNCmZvciAob3V0Y29tZV9pIGluIG91dGNvbWVzKSB7DQogIG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zW1tvdXRjb21lX2ldXSA8LQ0KICAgIGNveF9yZXN1bHRzX2FkdWx0c1tbb3V0Y29tZV9pXV0gJT4lDQogICAgZmlsdGVyKHNpdGUgJWluJSBzaXRlc19hZHVsdCRzaXRlKSAlPiUgDQogICAgYmluZF9yb3dzKCkgJT4lDQogICAgZGF0YS5mcmFtZSgpICU+JQ0KICAgIGZpbHRlcih2YXJpYWJsZSA9PSAibmV1cm9fcG9zdFBlcmlwaGVyYWwiKSAlPiUNCiAgICBtZXRhZ2VuKA0KICAgICAgVEUgPSBjb2VmLA0KICAgICAgc2VURSA9IHNlLmNvZWYuLA0KICAgICAgZGF0YSA9IC4sDQogICAgICBzbSA9ICJIUiIsICMgaGF6YXJkIHJhdGlvcw0KICAgICAgY29tYi5yYW5kb20gPSBUUlVFLA0KICAgICAgY29tYi5maXhlZCA9IEZBTFNFLA0KICAgICAgbWV0aG9kLnRhdSA9ICJETCIsICMgZGVmYXVsdCB0YXUgbWV0aG9kDQogICAgICBoYWtuID0gRkFMU0UsDQogICAgICBwcmVkaWN0aW9uID0gVFJVRSwNCiAgICAgIHN0dWRsYWIgPSBzaXRlDQogICAgKQ0KfQ0KYGBgDQoNCiMjIEZvcm1hdCBtZXRhLWFuYWx5c2lzIHJlc3VsdHMNCg0KSGVyZSB3ZSB3aWxsIGZvcm1hdCB0aGUgb3V0cHV0IG9mIHRoZSBtZXRhLWFuYWx5c2lzIGZvciBib3RoIENOUyBhbmQgUE5TIG1vZGVscw0KDQpgYGB7cn0NCiMgY25zDQptZXRhX3Jlc3VsdHNfYWR1bHRzX2Nuc19kZiA8LSBmb3JtYXRfbWV0YShtZXRhX3Jlc3VsdHNfYWR1bHRzX2NucykNCg0KIyBwbnMNCm1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmIDwtIGZvcm1hdF9tZXRhKG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zKQ0KYGBgDQoNCiMjIFNhdmUgbW9kZWwgd2VpZ2h0cyB0byBnZW5lcmF0ZSB0aGUgc3Vydml2YWwgY3VydmVzDQoNCk5leHQsIHdlIHdpbGwgc2F2ZSB0aGUgbW9kZWwgd2VpZ2h0cyBmb3IgZWFjaCBoZWFsdGhjYXJlIHN5c3RlbSBpbiBvcmRlciB0byBoZWxwIHVzIGdlbmVyYXRlIHRoZSBhc3NvY2lhdGVkIHN1cnZpdmFsIGN1cnZlcyBpbiBvdXIgZG93bnN0cmVhbSBhbmFseXNpcy4NCg0KVGhlIGJlbmVmaXQgb2YgdGhlIHJhbmRvbS1lZmZlY3RzIG1vZGVsIGlzIHRoYXQgaXQgYWxsb3dzIHVzIHRvIHdlaWdodCBlYWNoIGhlYWx0aGNhcmUgc3lzdGVtIGJ5IGNvbnNpZGVyaW5nIHRoZSBoZWFsdGhjYXJlIHN5c3RlbSB2YXJpYW5jZSAke3NeMn0kIGFuZCB0aGUgYmV0d2VlbiBoZWFsdGhjYXJlIHN5c3RlbSB2YXJpYW5jZSAkdGF1XjIkLg0KDQoqKjQuMS4yLjEgRXN0aW1hdG9ycyBvZiB0aGUgQmV0d2Vlbi1TdHVkeSBIZXRlcm9nZW5laXR5OioqIDxodHRwczovL2Jvb2tkb3duLm9yZy9NYXRoaWFzSGFycmVyL0RvaW5nX01ldGFfQW5hbHlzaXNfaW5fUi9wb29saW5nLWVzLmh0bWw+DQoNCj4gImludmVyc2Ugb2YgdGhlIHZhcmlhbmNlIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSB3ZWlnaHQgb2YgZWFjaCBzdHVkeSINCj4NCj4gLSAgICp3aGVyZSAic3R1ZHkiIGluIG91ciBhbmFseXNpcyBpcyB0aGUgaGVhbHRoY2FyZSBzeXN0ZW0qDQo+DQo+IEZvciByYW5kb20gZWZmZWN0cywgdGhlIGNhbGN1bGF0aW9uIGlzIHBlcmZvcm1lZCBieSBjYWxjdWxhdGluZyBhbiBhZGp1c3RlZCByYW5kb20tZWZmZWN0cyB3ZWlnaHQgd+KIl2sgZm9yIGVhY2ggb2JzZXJ2YXRpb24uIFdoZXJlIGsgaXMgdGhlIGhlYWx0aGNhcmUgc3lzdGVtOg0KDQokd14qX2sgPSBcZnJhY3sxfXtzXjIgKyB0YXVeMn0kDQoNCmBgYHtyfQ0KIyBzYXZlIGFsbCBjbnMgd2VpZ2h0cw0KZm9yIChvdXRjb21lX2kgaW4gb3V0Y29tZXMpIHsNCiAgDQogIHNhdmVfd2VpZ2h0cyhtZXRhX3Jlc3VsdHNfZGYgPSBtZXRhX3Jlc3VsdHNfYWR1bHRzX2Nuc19kZiwNCiAgICAgICAgICAgICAgIHBvcHVsYXRpb24gPSAiYWR1bHRzIiwgDQogICAgICAgICAgICAgICBvdXRjb21lID0gb3V0Y29tZV9pLCANCiAgICAgICAgICAgICAgIGNvbW9yYl9tZXRob2QgPSAiaW5kIiwgDQogICAgICAgICAgICAgICBjZW5zb3JfY3V0b2ZmID0gIjkwIiwNCiAgICAgICAgICAgICAgIGNuc19wbnMgPSAiQ05TIikNCn0NCg0KDQojIHNhdmUgYWxsIHBucyB3ZWlnaHRzDQpmb3IgKG91dGNvbWVfaSBpbiBvdXRjb21lcykgew0KICANCiAgc2F2ZV93ZWlnaHRzKG1ldGFfcmVzdWx0c19kZiA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmLA0KICAgICAgICAgICAgICAgcG9wdWxhdGlvbiA9ICJhZHVsdHMiLCANCiAgICAgICAgICAgICAgIG91dGNvbWUgPSBvdXRjb21lX2ksIA0KICAgICAgICAgICAgICAgY29tb3JiX21ldGhvZCA9ICJpbmQiLCANCiAgICAgICAgICAgICAgIGNlbnNvcl9jdXRvZmYgPSAiOTAiLA0KICAgICAgICAgICAgICAgY25zX3BucyA9ICJQTlMiKQ0KfQ0KYGBgDQoNCiMgKipBbmFseXplIFJpc2sgdmlhIEZvcmVzdCBQbG90cyoqDQoNCioqUHJlcGFyZSBkYXRhIGZvciBmb3Jlc3QgcGxvdHMqKg0KDQpgYGB7cn0NCiMgYWR1bHRzDQptZXRhX3Jlc3VsdHNfYWR1bHRzX2Nuc19kZl9mb3Jlc3QgPSBwcmVwYXJlX2RhdGFfZm9yZXN0X3Bsb3RzKG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmKQ0KbWV0YV9yZXN1bHRzX2FkdWx0c19wbnNfZGZfZm9yZXN0ID0gcHJlcGFyZV9kYXRhX2ZvcmVzdF9wbG90cyhtZXRhX3Jlc3VsdHNfYWR1bHRzX3Buc19kZikNCmBgYA0KDQoqKlRpZHkgdXAgcmVzdWx0cyoqDQoNCmBgYHtyfQ0KbWV0YV9yZXN1bHRzX2FkdWx0c19jbnNfZGZfZm9yZXN0X3RpZHkgPC0gbWV0YV9yZXN1bHRzX2FkdWx0c19jbnNfZGZfZm9yZXN0ICU+JSANCiAgZGlzdGluY3QoYW5hbHlzaXMsIFRFLnJhbmRvbSwgbG93ZXIucmFuZG9tLCB1cHBlci5yYW5kb20sYHAtdmFsdWVgLCBsb3dlci5wcmVkaWN0LCB1cHBlci5wcmVkaWN0LCBJMiwgbG93ZXIuSTIsIHVwcGVyLkkyLCBILCBsb3dlci5ILCB1cHBlci5ILCB0YXUyLCBsb3dlci50YXUyLCB1cHBlci50YXUyLCBDSSkgJT4lIA0KICBtdXRhdGUobmV1cm9fc3RhdHVzID0gIkNOUyIpICU+JSANCiAgc2VsZWN0KG5ldXJvX3N0YXR1cywgZXZlcnl0aGluZygpKQ0KDQptZXRhX3Jlc3VsdHNfYWR1bHRzX3Buc19kZl9mb3Jlc3RfdGlkeSA8LSBtZXRhX3Jlc3VsdHNfYWR1bHRzX3Buc19kZl9mb3Jlc3QgJT4lIA0KICBkaXN0aW5jdChhbmFseXNpcywgVEUucmFuZG9tLCBsb3dlci5yYW5kb20sIHVwcGVyLnJhbmRvbSxgcC12YWx1ZWAsIGxvd2VyLnByZWRpY3QsIHVwcGVyLnByZWRpY3QsIEkyLCBsb3dlci5JMiwgdXBwZXIuSTIsIEgsIGxvd2VyLkgsIHVwcGVyLkgsIHRhdTIsIGxvd2VyLnRhdTIsIHVwcGVyLnRhdTIsIENJKSAlPiUgDQogIG11dGF0ZShuZXVyb19zdGF0dXMgPSAiUE5TIikgJT4lIA0KICBzZWxlY3QobmV1cm9fc3RhdHVzLCBldmVyeXRoaW5nKCkpDQoNCm1ldGFfcmVzdWx0c190aWR5IDwtIHJiaW5kKG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdF90aWR5LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdF90aWR5KQ0KDQp3cml0ZS5jc3YobWV0YV9yZXN1bHRzX3RpZHksICJ0YWJsZXMvVGFibGUyX21ldGFfcmVzdWx0cy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQpOZXh0LCB3ZSB3aWxsIGNyZWF0ZSBhIHNjYWxlIGZ1bmN0aW9uIHRvIGlkZW50aWZ5IHRoZSBtaW4gYW5kIG1heCBDSSBmb3IgZWFjaCBoZWFsdGhjYXJlIHN5c3RlbS4gVGhpcyB3aWxsIGhlbHAgdXMgZXhjbHVkZSBoZWFsdGhjYXJlIHN5c3RlbXMgd2l0aCB2YWx1ZXMgb2YgJ0luZicgb3IgdmVyeSBsYXJnZSBjb25maWRlbmNlIGludGVydmFscy4NCg0KYGBge3J9DQpzY2FsZV9wbG90IDwtIGZ1bmN0aW9uKG1ldGFfcmVzdWx0c19kZl9mb3Jlc3QsIHNpdGVfZXhjbHVkZSA9IE5VTEwpIHsNCiAgc2NhbGUgPC0gbWV0YV9yZXN1bHRzX2RmX2ZvcmVzdCAlPiUNCiAgICBmaWx0ZXIoDQogICAgICAhU2l0ZSAlaW4lIHNpdGVfZXhjbHVkZSwNCiAgICAgICMhYW5hbHlzaXMgJWluJSBpbnZhbGlkX3NpdGVzLA0KICAgICAgIUNJLkxvdyA9PSAiSW5mIiwNCiAgICAgICFDSS5IaWdoID09ICJJbmYiDQogICAgKSAlPiUNCiAgICBtdXRhdGUoDQogICAgICBtaW5fZXN0ID0gbWluKENJLkxvdywgbmEucm0gPSBUUlVFKSAtIDEsDQogICAgICBtYXhfZXN0ID0gbWF4KENJLkhpZ2gsIG5hLnJtID0gVFJVRSkgKyAxLA0KICAgICAgbWluX2VzdCA9IGlmX2Vsc2UobWluX2VzdCArIDEgPj0gLTEsIG1pbihDSS5Mb3csIG5hLnJtID0gVFJVRSktMC4xLCBtaW5fZXN0KSwNCiAgICAgIG1pbl9lc3QgPSBpZl9lbHNlKG1pbl9lc3QgPiAxLCAwLjUsIG1pbl9lc3QpLA0KICAgICAgbWF4X2VzdCA9IGlmX2Vsc2UobWF4X2VzdCAtIDEgPCAxLCAxLjEsIG1heF9lc3QpKSAlPiUNCiAgICBkaXN0aW5jdChtaW5fZXN0LCBtYXhfZXN0KQ0KDQogIHJldHVybihzY2FsZSkNCn0NCmBgYA0KDQojIyBDTlMgLSBSaXNrIG9mIERpc2NoYXJnZQ0KDQpgYGB7ciBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRlLnJhbmRvbSA9IG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KFRFLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgJT4lIA0KICByb3VuZCguLDIpDQoNCnRlLnJhbmRvbS5jaV9sb3dlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KGxvd2VyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCnRlLnJhbmRvbS5jaV91cHBlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KHVwcGVyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCmxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMgPC0gbWV0YV9yZXN1bHRzX2FkdWx0c19jbnNfZGZfZm9yZXN0ICU+JQ0KICBzbGljZShncmVwKHBhc3RlKCJ0aW1lX2ZpcnN0X2Rpc2NoYXJnZV9yZWdfZWxpeCIsIGNvbGxhcHNlID0gInwiKSwgYW5hbHlzaXMpKSAlPiUgDQogICNhZGRfcm93KC5iZWZvcmUgPSAxKSAlPiUNCiAgYWRkX3JvdyguYWZ0ZXIgPSBucm93KC4pKSAlPiUgDQogIG11dGF0ZShTaXRlID0gaWZlbHNlKGlzLm5hKFNpdGUpLCAiRWZmZWN0IHNpemUiLCBTaXRlKSwNCiAgICAgICAgIGBIYXphcmQgUmF0aW9gID0gaWZlbHNlKGlzLm5hKGBIYXphcmQgUmF0aW9gKSwgcm91bmQodGUucmFuZG9tLCAyKSwgYEhhemFyZCBSYXRpb2ApLA0KICAgICAgICAgYHAtdmFsdWVgID0gaWZlbHNlKGBwLXZhbHVlYCA8IDAuMDAxLCAiPCAuMDAxKiIsIHJvdW5kKGBwLXZhbHVlYCwgMykpKSAlPiUgDQogIGZpbGwoYHAtdmFsdWVgLCAuZGlyZWN0aW9uID0gImRvd24iKSAlPiUgDQogIG11dGF0ZShgcC12YWx1ZWAgPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCBgcC12YWx1ZWAsICIiKSwNCiAgICAgICAgIENJLkxvdyA9IGlmZWxzZShTaXRlID09ICJFZmZlY3Qgc2l6ZSIsIHRlLnJhbmRvbS5jaV9sb3dlciwgQ0kuTG93KSwNCiAgICAgICAgIENJLkhpZ2ggPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCB0ZS5yYW5kb20uY2lfdXBwZXIsIENJLkhpZ2gpLA0KICAgICAgICAgYEhhemFyZCBSYXRpbyBgID0gcGFzdGUoYEhhemFyZCBSYXRpb2AsICcoJywgQ0kuTG93LCAnLCcsIENJLkhpZ2gsICcpJykpDQoNCg0KIyMgZGVmaW5lIGZvcmVzdCBwbG90IHNoYXBlcw0KIyBzaGFwZSAjMTYgaXMgbm9ybWFsIGNpcmNsZTsgIzE4IGlzIGRpYW1vbmQNCnNoYXBlcyA8LSByZXAoMTYsIHRpbWVzID0gbnJvdyhsZW5ndGhfc3RheV9maXJzdF9yZXN1bHRzKSkNCnNoYXBlc1tsZW5ndGgoc2hhcGVzKV0gPC0gMTgNCnNpemVzIDwtIHJlcCgzLjI1LCB0aW1lcyA9IG5yb3cobGVuZ3RoX3N0YXlfZmlyc3RfcmVzdWx0cykpDQpzaXplc1tsZW5ndGgoc2l6ZXMpXSA8LSA1DQpzY2FsZSA8LSBzY2FsZV9wbG90KGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMsIHNpdGVfZXhjbHVkZSA9IGMoIklDU00iKSkNCg0KIyBub3RlOiBgSGF6YXJkIFJhdGlvIGAgd2l0aCBjb25maWRlbmNlIGludGVydmFscyBoYXMgYW4gZXh0cmEgc3BhY2UgYW5kIHVzZWQgYnkgYHJpZ2h0X3NpZGVfZGF0YWAgcGFyYW0NCnAxIDwtIGZvcmVzdGVyKA0KICBsZWZ0X3NpZGVfZGF0YSA9IGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMgJT4lIA0KICAgIHNlbGVjdChTaXRlKSAlPiUgDQogICAgcmVuYW1lKCJIZWFsdGhjYXJlIFN5c3RlbSIgPSAiU2l0ZSIpLA0KICBlc3RpbWF0ZSA9IGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMkYEhhemFyZCBSYXRpb2AsDQogIGNpX2xvdyA9IGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMkQ0kuTG93LA0KICBjaV9oaWdoID0gbGVuZ3RoX3N0YXlfZmlyc3RfcmVzdWx0cyRDSS5IaWdoLA0KICByaWdodF9zaWRlX2RhdGEgPSBsZW5ndGhfc3RheV9maXJzdF9yZXN1bHRzWywgYygiSGF6YXJkIFJhdGlvICIsICJwLXZhbHVlIildLA0KICBkaXNwbGF5ID0gVFJVRSwNCiAgbnVkZ2VfeCA9IC41LA0KICBmb250X2ZhbWlseSA9ICJhcmlhbCIsDQogIGFycm93cyA9IFRSVUUsDQogIGFycm93X2xhYmVscyA9IGMoIkRlY3JlYXNlZCBSaXNrIiwgIkluY3JlYXNlZCBSaXNrIiksDQogIG51bGxfbGluZV9hdCA9IDEsDQogIHhsaW0gPSBjKHNjYWxlJG1pbl9lc3QsIHNjYWxlJG1heF9lc3QpLA0KICAjeGJyZWFrcyA9IGMoc2NhbGUkbWluX2VzdCwgMSwgc2NhbGUkbWF4X2VzdCksDQogIHBvaW50X3NpemVzID0gc2l6ZXMsDQogIHBvaW50X3NoYXBlcyA9IHNoYXBlcywNCiAgZmlsZV9wYXRoID0gaGVyZTo6aGVyZShwYXN0ZTAoImZpZ3VyZXMvZm9yZXN0cGxvdF9hZHVsdF9jbnNfZGlzY2hhcmdlLnBuZyIpKSkNCg0KcDENCmBgYA0KDQojIyBDTlMgLSBSaXNrIG9mIE1vcnRhbGl0eQ0KDQpgYGB7ciBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRlLnJhbmRvbSA9IG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAiZGVjZWFzZWRfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KFRFLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgJT4lIA0KICByb3VuZCguLDIpDQoNCnRlLnJhbmRvbS5jaV9sb3dlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAiZGVjZWFzZWRfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KGxvd2VyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCnRlLnJhbmRvbS5jaV91cHBlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfY25zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAiZGVjZWFzZWRfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KHVwcGVyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCmRlY2Vhc2VkX3Jlc3VsdHMgPC0gbWV0YV9yZXN1bHRzX2FkdWx0c19jbnNfZGZfZm9yZXN0ICU+JQ0KICBzbGljZShncmVwKHBhc3RlKCJkZWNlYXNlZF9yZWdfZWxpeCIsIGNvbGxhcHNlID0gInwiKSwgYW5hbHlzaXMpKSAlPiUgDQogICNhZGRfcm93KC5iZWZvcmUgPSAxKSAlPiUNCiAgYWRkX3JvdyguYWZ0ZXIgPSBucm93KC4pKSAlPiUgDQogIG11dGF0ZShTaXRlID0gaWZlbHNlKGlzLm5hKFNpdGUpLCAiRWZmZWN0IHNpemUiLCBTaXRlKSwNCiAgICAgICAgIGBIYXphcmQgUmF0aW9gID0gaWZlbHNlKGlzLm5hKGBIYXphcmQgUmF0aW9gKSwgcm91bmQodGUucmFuZG9tLCAyKSwgYEhhemFyZCBSYXRpb2ApLA0KICAgICAgICAgYHAtdmFsdWVgID0gaWZlbHNlKGBwLXZhbHVlYCA8IDAuMDAxLCAiPCAuMDAxKiIsIHJvdW5kKGBwLXZhbHVlYCwgMykpKSAlPiUgDQogIGZpbGwoYHAtdmFsdWVgLCAuZGlyZWN0aW9uID0gImRvd24iKSAlPiUgDQogIG11dGF0ZShgcC12YWx1ZWAgPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCBgcC12YWx1ZWAsICIiKSwNCiAgICAgICAgIENJLkxvdyA9IGlmZWxzZShTaXRlID09ICJFZmZlY3Qgc2l6ZSIsIHRlLnJhbmRvbS5jaV9sb3dlciwgQ0kuTG93KSwNCiAgICAgICAgIENJLkhpZ2ggPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCB0ZS5yYW5kb20uY2lfdXBwZXIsIENJLkhpZ2gpLA0KICAgICAgICAgYEhhemFyZCBSYXRpbyBgID0gcGFzdGUoYEhhemFyZCBSYXRpb2AsICcoJywgQ0kuTG93LCAnLCcsIENJLkhpZ2gsICcpJykpDQoNCg0KIyMgZGVmaW5lIGZvcmVzdCBwbG90IHNoYXBlcw0KIyBzaGFwZSAjMTYgaXMgbm9ybWFsIGNpcmNsZTsgIzE4IGlzIGRpYW1vbmQNCnNoYXBlcyA8LSByZXAoMTYsIHRpbWVzID0gbnJvdyhkZWNlYXNlZF9yZXN1bHRzKSkNCnNoYXBlc1tsZW5ndGgoc2hhcGVzKV0gPC0gMTgNCnNpemVzIDwtIHJlcCgzLjI1LCB0aW1lcyA9IG5yb3coZGVjZWFzZWRfcmVzdWx0cykpDQpzaXplc1tsZW5ndGgoc2l6ZXMpXSA8LSA1DQpzY2FsZSA8LSBzY2FsZV9wbG90KGRlY2Vhc2VkX3Jlc3VsdHMsIHNpdGVfZXhjbHVkZSA9IGMoIklDU00iKSkNCg0KIyBub3RlOiBgSGF6YXJkIFJhdGlvIGAgd2l0aCBjb25maWRlbmNlIGludGVydmFscyBoYXMgYW4gZXh0cmEgc3BhY2UgYW5kIHVzZWQgYnkgYHJpZ2h0X3NpZGVfZGF0YWAgcGFyYW0NCnAyIDwtIGZvcmVzdGVyKA0KICBsZWZ0X3NpZGVfZGF0YSA9IGRlY2Vhc2VkX3Jlc3VsdHMgJT4lIA0KICAgIHNlbGVjdChTaXRlKSAlPiUgDQogICAgcmVuYW1lKCJIZWFsdGhjYXJlIFN5c3RlbSIgPSAiU2l0ZSIpLA0KICBlc3RpbWF0ZSA9IGRlY2Vhc2VkX3Jlc3VsdHMkYEhhemFyZCBSYXRpb2AsDQogIGNpX2xvdyA9IGRlY2Vhc2VkX3Jlc3VsdHMkQ0kuTG93LA0KICBjaV9oaWdoID0gZGVjZWFzZWRfcmVzdWx0cyRDSS5IaWdoLA0KICByaWdodF9zaWRlX2RhdGEgPSBkZWNlYXNlZF9yZXN1bHRzWywgYygiSGF6YXJkIFJhdGlvICIsICJwLXZhbHVlIildLA0KICBkaXNwbGF5ID0gVFJVRSwNCiAgbnVkZ2VfeCA9IC41LA0KICBmb250X2ZhbWlseSA9ICJhcmlhbCIsDQogIGFycm93cyA9IFRSVUUsDQogIGFycm93X2xhYmVscyA9IGMoIkRlY3JlYXNlZCBSaXNrIiwgIkluY3JlYXNlZCBSaXNrIiksDQogIG51bGxfbGluZV9hdCA9IDEsDQogIHhsaW0gPSBjKHNjYWxlJG1pbl9lc3QsIHNjYWxlJG1heF9lc3QpLA0KICAjeGJyZWFrcyA9IGMoc2NhbGUkbWluX2VzdCwgMSwgc2NhbGUkbWF4X2VzdCksDQogIHBvaW50X3NpemVzID0gc2l6ZXMsDQogIHBvaW50X3NoYXBlcyA9IHNoYXBlcywNCiAgZmlsZV9wYXRoID0gaGVyZTo6aGVyZShwYXN0ZTAoImZpZ3VyZXMvZm9yZXN0cGxvdF9hZHVsdF9jbnNfbW9ydGFsaXR5LnBuZyIpKSkNCg0KcDINCmBgYA0KDQojIyBQTlMgLSBSaXNrIG9mIERpc2NoYXJnZQ0KDQpgYGB7ciBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRlLnJhbmRvbSA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KFRFLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgJT4lIA0KICByb3VuZCguLDIpDQoNCnRlLnJhbmRvbS5jaV9sb3dlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KGxvd2VyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCnRlLnJhbmRvbS5jaV91cHBlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAidGltZV9maXJzdF9kaXNjaGFyZ2VfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KHVwcGVyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCmxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMgPC0gbWV0YV9yZXN1bHRzX2FkdWx0c19wbnNfZGZfZm9yZXN0ICU+JQ0KICBzbGljZShncmVwKHBhc3RlKCJ0aW1lX2ZpcnN0X2Rpc2NoYXJnZV9yZWdfZWxpeCIsIGNvbGxhcHNlID0gInwiKSwgYW5hbHlzaXMpKSAlPiUgDQogICNhZGRfcm93KC5iZWZvcmUgPSAxKSAlPiUNCiAgYWRkX3JvdyguYWZ0ZXIgPSBucm93KC4pKSAlPiUgDQogIG11dGF0ZShTaXRlID0gaWZlbHNlKGlzLm5hKFNpdGUpLCAiRWZmZWN0IHNpemUiLCBTaXRlKSwNCiAgICAgICAgIGBIYXphcmQgUmF0aW9gID0gaWZlbHNlKGlzLm5hKGBIYXphcmQgUmF0aW9gKSwgcm91bmQodGUucmFuZG9tLCAyKSwgYEhhemFyZCBSYXRpb2ApLA0KICAgICAgICAgYHAtdmFsdWVgID0gaWZlbHNlKGBwLXZhbHVlYCA8IDAuMDAxLCAiPCAuMDAxKiIsIHJvdW5kKGBwLXZhbHVlYCwgMykpKSAlPiUgDQogIGZpbGwoYHAtdmFsdWVgLCAuZGlyZWN0aW9uID0gImRvd24iKSAlPiUgDQogIG11dGF0ZShgcC12YWx1ZWAgPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCBgcC12YWx1ZWAsICIiKSwNCiAgICAgICAgIENJLkxvdyA9IGlmZWxzZShTaXRlID09ICJFZmZlY3Qgc2l6ZSIsIHRlLnJhbmRvbS5jaV9sb3dlciwgQ0kuTG93KSwNCiAgICAgICAgIENJLkhpZ2ggPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCB0ZS5yYW5kb20uY2lfdXBwZXIsIENJLkhpZ2gpLA0KICAgICAgICAgYEhhemFyZCBSYXRpbyBgID0gcGFzdGUoYEhhemFyZCBSYXRpb2AsICcoJywgQ0kuTG93LCAnLCcsIENJLkhpZ2gsICcpJykpDQoNCg0KIyMgZGVmaW5lIGZvcmVzdCBwbG90IHNoYXBlcw0KIyBzaGFwZSAjMTYgaXMgbm9ybWFsIGNpcmNsZTsgIzE4IGlzIGRpYW1vbmQNCnNoYXBlcyA8LSByZXAoMTYsIHRpbWVzID0gbnJvdyhsZW5ndGhfc3RheV9maXJzdF9yZXN1bHRzKSkNCnNoYXBlc1tsZW5ndGgoc2hhcGVzKV0gPC0gMTgNCnNpemVzIDwtIHJlcCgzLjI1LCB0aW1lcyA9IG5yb3cobGVuZ3RoX3N0YXlfZmlyc3RfcmVzdWx0cykpDQpzaXplc1tsZW5ndGgoc2l6ZXMpXSA8LSA1DQpzY2FsZSA8LSBzY2FsZV9wbG90KGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMsIHNpdGVfZXhjbHVkZSA9IGMoIklDU00iKSkNCg0KIyBub3RlOiBgSGF6YXJkIFJhdGlvIGAgd2l0aCBjb25maWRlbmNlIGludGVydmFscyBoYXMgYW4gZXh0cmEgc3BhY2UgYW5kIHVzZWQgYnkgYHJpZ2h0X3NpZGVfZGF0YWAgcGFyYW0NCnAzIDwtIGZvcmVzdGVyKA0KICBsZWZ0X3NpZGVfZGF0YSA9IGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMgJT4lIA0KICAgIHNlbGVjdChTaXRlKSAlPiUgDQogICAgcmVuYW1lKCJIZWFsdGhjYXJlIFN5c3RlbSIgPSAiU2l0ZSIpLA0KICBlc3RpbWF0ZSA9IGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMkYEhhemFyZCBSYXRpb2AsDQogIGNpX2xvdyA9IGxlbmd0aF9zdGF5X2ZpcnN0X3Jlc3VsdHMkQ0kuTG93LA0KICBjaV9oaWdoID0gbGVuZ3RoX3N0YXlfZmlyc3RfcmVzdWx0cyRDSS5IaWdoLA0KICByaWdodF9zaWRlX2RhdGEgPSBsZW5ndGhfc3RheV9maXJzdF9yZXN1bHRzWywgYygiSGF6YXJkIFJhdGlvICIsICJwLXZhbHVlIildLA0KICBkaXNwbGF5ID0gVFJVRSwNCiAgbnVkZ2VfeCA9IC41LA0KICBmb250X2ZhbWlseSA9ICJhcmlhbCIsDQogIGFycm93cyA9IFRSVUUsDQogIGFycm93X2xhYmVscyA9IGMoIkRlY3JlYXNlZCBSaXNrIiwgIkluY3JlYXNlZCBSaXNrIiksDQogIG51bGxfbGluZV9hdCA9IDEsDQogIHhsaW0gPSBjKHNjYWxlJG1pbl9lc3QsIHNjYWxlJG1heF9lc3QpLA0KICAjeGJyZWFrcyA9IGMoc2NhbGUkbWluX2VzdCwgMSwgc2NhbGUkbWF4X2VzdCksDQogIHBvaW50X3NpemVzID0gc2l6ZXMsDQogIHBvaW50X3NoYXBlcyA9IHNoYXBlcywNCiAgZmlsZV9wYXRoID0gaGVyZTo6aGVyZShwYXN0ZTAoImZpZ3VyZXMvZm9yZXN0cGxvdF9hZHVsdF9wbnNfZGlzY2hhcmdlLnBuZyIpKSkNCg0KcDMNCmBgYA0KDQojIyBQTlMgLSBSaXNrIG9mIE1vcnRhbGl0eQ0KDQpgYGB7ciBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRlLnJhbmRvbSA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAiZGVjZWFzZWRfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KFRFLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgJT4lIA0KICByb3VuZCguLDIpDQoNCnRlLnJhbmRvbS5jaV9sb3dlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAiZGVjZWFzZWRfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KGxvd2VyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCnRlLnJhbmRvbS5jaV91cHBlciA9IG1ldGFfcmVzdWx0c19hZHVsdHNfcG5zX2RmX2ZvcmVzdCAlPiUgDQogIGZpbHRlcihhbmFseXNpcyA9PSAiZGVjZWFzZWRfcmVnX2VsaXgiKSAlPiUgDQogIGRpc3RpbmN0KHVwcGVyLnJhbmRvbSkgJT4lIA0KICBhcy5udW1lcmljKCkgDQoNCmRlY2Vhc2VkX3Jlc3VsdHMgPC0gbWV0YV9yZXN1bHRzX2FkdWx0c19wbnNfZGZfZm9yZXN0ICU+JQ0KICBzbGljZShncmVwKHBhc3RlKCJkZWNlYXNlZF9yZWdfZWxpeCIsIGNvbGxhcHNlID0gInwiKSwgYW5hbHlzaXMpKSAlPiUgDQogICNhZGRfcm93KC5iZWZvcmUgPSAxKSAlPiUNCiAgYWRkX3JvdyguYWZ0ZXIgPSBucm93KC4pKSAlPiUgDQogIG11dGF0ZShTaXRlID0gaWZlbHNlKGlzLm5hKFNpdGUpLCAiRWZmZWN0IHNpemUiLCBTaXRlKSwNCiAgICAgICAgIGBIYXphcmQgUmF0aW9gID0gaWZlbHNlKGlzLm5hKGBIYXphcmQgUmF0aW9gKSwgcm91bmQodGUucmFuZG9tLCAyKSwgYEhhemFyZCBSYXRpb2ApLA0KICAgICAgICAgYHAtdmFsdWVgID0gaWZlbHNlKGBwLXZhbHVlYCA8IDAuMDAxLCAiPCAuMDAxKiIsIHJvdW5kKGBwLXZhbHVlYCwgMykpKSAlPiUgDQogIGZpbGwoYHAtdmFsdWVgLCAuZGlyZWN0aW9uID0gImRvd24iKSAlPiUgDQogIG11dGF0ZShgcC12YWx1ZWAgPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCBgcC12YWx1ZWAsICIiKSwNCiAgICAgICAgIENJLkxvdyA9IGlmZWxzZShTaXRlID09ICJFZmZlY3Qgc2l6ZSIsIHRlLnJhbmRvbS5jaV9sb3dlciwgQ0kuTG93KSwNCiAgICAgICAgIENJLkhpZ2ggPSBpZmVsc2UoU2l0ZSA9PSAiRWZmZWN0IHNpemUiLCB0ZS5yYW5kb20uY2lfdXBwZXIsIENJLkhpZ2gpLA0KICAgICAgICAgYEhhemFyZCBSYXRpbyBgID0gcGFzdGUoYEhhemFyZCBSYXRpb2AsICcoJywgQ0kuTG93LCAnLCcsIENJLkhpZ2gsICcpJykpDQoNCg0KIyMgZGVmaW5lIGZvcmVzdCBwbG90IHNoYXBlcw0KIyBzaGFwZSAjMTYgaXMgbm9ybWFsIGNpcmNsZTsgIzE4IGlzIGRpYW1vbmQNCnNoYXBlcyA8LSByZXAoMTYsIHRpbWVzID0gbnJvdyhkZWNlYXNlZF9yZXN1bHRzKSkNCnNoYXBlc1tsZW5ndGgoc2hhcGVzKV0gPC0gMTgNCnNpemVzIDwtIHJlcCgzLjI1LCB0aW1lcyA9IG5yb3coZGVjZWFzZWRfcmVzdWx0cykpDQpzaXplc1tsZW5ndGgoc2l6ZXMpXSA8LSA1DQpzY2FsZSA8LSBzY2FsZV9wbG90KGRlY2Vhc2VkX3Jlc3VsdHMsIHNpdGVfZXhjbHVkZSA9IGMoIklDU00iLCAiSFBHMjMiKSkNCg0KIyBub3RlOiBgSGF6YXJkIFJhdGlvIGAgd2l0aCBjb25maWRlbmNlIGludGVydmFscyBoYXMgYW4gZXh0cmEgc3BhY2UgYW5kIHVzZWQgYnkgYHJpZ2h0X3NpZGVfZGF0YWAgcGFyYW0NCnA0IDwtIGZvcmVzdGVyKA0KICBsZWZ0X3NpZGVfZGF0YSA9IGRlY2Vhc2VkX3Jlc3VsdHMgJT4lIA0KICAgIHNlbGVjdChTaXRlKSAlPiUgDQogICAgcmVuYW1lKCJIZWFsdGhjYXJlIFN5c3RlbSIgPSAiU2l0ZSIpLA0KICBlc3RpbWF0ZSA9IGRlY2Vhc2VkX3Jlc3VsdHMkYEhhemFyZCBSYXRpb2AsDQogIGNpX2xvdyA9IGRlY2Vhc2VkX3Jlc3VsdHMkQ0kuTG93LA0KICBjaV9oaWdoID0gZGVjZWFzZWRfcmVzdWx0cyRDSS5IaWdoLA0KICByaWdodF9zaWRlX2RhdGEgPSBkZWNlYXNlZF9yZXN1bHRzWywgYygiSGF6YXJkIFJhdGlvICIsICJwLXZhbHVlIildLA0KICBkaXNwbGF5ID0gVFJVRSwNCiAgbnVkZ2VfeCA9IC41LA0KICBmb250X2ZhbWlseSA9ICJhcmlhbCIsDQogIGFycm93cyA9IFRSVUUsDQogIGFycm93X2xhYmVscyA9IGMoIkRlY3JlYXNlZCBSaXNrIiwgIkluY3JlYXNlZCBSaXNrIiksDQogIG51bGxfbGluZV9hdCA9IDEsDQogIHhsaW0gPSBjKHNjYWxlJG1pbl9lc3QsIHNjYWxlJG1heF9lc3QpLA0KICAjeGJyZWFrcyA9IGMoc2NhbGUkbWluX2VzdCwgMSwgc2NhbGUkbWF4X2VzdCksDQogIHBvaW50X3NpemVzID0gc2l6ZXMsDQogIHBvaW50X3NoYXBlcyA9IHNoYXBlcywNCiAgZmlsZV9wYXRoID0gaGVyZTo6aGVyZShwYXN0ZTAoImZpZ3VyZXMvZm9yZXN0cGxvdF9hZHVsdF9wbnNfbW9ydGFsaXR5LnBuZyIpKSkNCg0KcDQNCmBgYA0K