Data Cleaning and Transformation
#################################################################
## Library ##
#################################################################
pkgs = c("tidyverse",
"ddplot",
"countrycode",
"showtext",
"ggpubr")
installed_pkgs = pkgs %in% rownames(installed.packages())
if (any(installed_pkgs == FALSE)) {
install.packages[!installed_pkgs]
}
invisible(lapply(pkgs, library, character.only = TRUE))
rm(installed_pkgs, pkgs)
font_add_google("Ubuntu", "ub")
##################################################################
## Helper Functions ## thanx for helpin
##################################################################
fetch_data = function(url,path) {
url = url
path = path
download.file(url,path)
read.csv(path)
}
dark_theme = function() {
theme(
# add border 1)
panel.border = element_rect(
colour = "slategrey",
fill = NA,
linetype = 2
),
# color background 2)
panel.background = element_rect(fill = "white"),
# modify grid 3)
panel.grid.major.x = element_line(
colour = "#cf2e2e",
linetype = 3,
size = 0.5
),
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
# modify text, axis and colour 4) and 5)
axis.text = element_text(
colour = "white",
face = "italic",
family = "sans"
),
axis.title = element_text(colour = "white", family = "sans"),
axis.ticks = element_line(colour = "white"),
plot.background = element_rect(fill = "#cf2e2e"),
plot.title = element_text(family = "sans", hjust = .5, size = 16),
plot.subtitle = element_text(family = "sans", hjust = .5, size = 12),
legend.background = element_rect(fill = "#cf2e2e"),
legend.text = element_text(color = "white", family = "sans", size = 10),
legend.key = element_rect(fill = "#cf2e2e"),
# legend at the bottom 6)
legend.position = "bottom"
)
}
wss = function(k) {
kmeans(b, k, nstart = 10 )$tot.withinss
}
options(scipen=999)
##########################################################################
## Download latest John Hopkins global Covid-19 cases & vaccines data ##
##########################################################################
##### CASES
jh_global_covid = fetch_data(url = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv",
path = "data/covid-jh.csv" ## fetch latest github data
) %>%
select(-c(Lat, Long)) %>% # be gone lat long
# select(-1) %>%
rename(Country = 2) %>%
mutate(Country = ifelse(Province.State == "French Guiana" & Country == "France", "French Guiana", Country)) %>%
mutate(Country = ifelse(Province.State == "French Polynesia" & Country == "France", "French Polynesia", Country)) %>%
mutate(Country = ifelse(Province.State == "Guadeloupe" & Country == "France", "Guadeloupe", Country)) %>%
mutate(Country = ifelse(Province.State == "Martinique" & Country == "France", "Martinique", Country)) %>%
mutate(Country = ifelse(Province.State == "Mayotte" & Country == "France", "Mayotte", Country)) %>%
mutate(Country = ifelse(Province.State == "New Caledonia" & Country == "France", "New Caledonia", Country)) %>%
mutate(Country = ifelse(Province.State == "Reunion" & Country == "France", "Reunion", Country)) %>%
mutate(Country = ifelse(Province.State == "Saint Barthelemy" & Country == "France", "Saint Barthelemy", Country)) %>%
mutate(Country = ifelse(Province.State == "Saint Pierre and Miquelon" & Country == "France", "Saint Pierre and Miquelon", Country)) %>%
mutate(Country = ifelse(Province.State == "St Martin" & Country == "France", "St Martin", Country)) %>%
mutate(Country = ifelse(Province.State == "Wallis and Futuna" & Country == "France", "Wallis and Futuna", Country)) %>%
mutate(Country = ifelse(Province.State == "Curacao" & Country == "Netherlands", "Curacao", Country)) %>%
mutate(Country = ifelse(Province.State == "Sint Maarten" & Country == "Netherlands", " Sint Maarten", Country)) %>%
mutate(Country = ifelse(Province.State == "Aruba" & Country == "Netherlands", "Aruba", Country)) %>%
mutate(Country = ifelse(Province.State == "Bonaire, Sint Eustatius and Saba" & Country == "Netherlands", "Bonaire, Sint Eustatius and Saba", Country)) %>%
mutate(Country = ifelse(Province.State == "Anguilla" & Country == "United Kingdom", "Anguilla", Country)) %>%
mutate(Country = ifelse(Province.State == "Bermuda" & Country == "United Kingdom", "Bermuda", Country)) %>%
mutate(Country = ifelse(Province.State == "British Virgin Islands" & Country == "United Kingdom", "British Virgin Islands", Country)) %>%
mutate(Country = ifelse(Province.State == "Cayman Islands" & Country == "United Kingdom", "Cayman Islands", Country)) %>%
mutate(Country = ifelse(Province.State == "Channel Islands" & Country == "United Kingdom", "Channel Islands", Country)) %>%
mutate(Country = ifelse(Province.State == "Gibraltar" & Country == "United Kingdom", "Gibraltar", Country)) %>%
mutate(Country = ifelse(Province.State == "Montserrat" & Country == "United Kingdom", "Montserrat", Country)) %>%
mutate(Country = ifelse(Province.State == "Turks and Caicos Islands" & Country == "United Kingdom", "Turks and Caicos Islands", Country)) %>%
select(-c(Province.State)) %>%
pivot_longer(!Country, names_to = "Date", values_to = "cases") %>%
mutate(Date = paste0(sub('.', '', Date))) %>%
filter(Date == "2.22.22") %>%
select(-c(Date)) %>%
mutate(Country = case_when(
Country == "US" ~ "USA",
Country == "The Bahamas" ~ "Bahamas",
Country == "Taiwan*" ~ "Taiwan",
Country == "Korea, South" ~ "South Korea",
Country == "Congo (Kinshasa)" ~ "Democratic Republic of the Congo",
Country == "Congo (Brazzaville)" ~ "Republic of the Congo",
Country == "Czechia" ~ "Czech Republic",
Country == "Wallis and Futuna" ~ "Wallis and Futuna Islands",
Country == "Bonaire, Sint Eustatius and Saba" ~ "Bonaire",
TRUE ~ Country
))
jh_global_covid = aggregate(. ~ Country, jh_global_covid, FUN = sum)
# > head(jh_global_covid)
# Country cases
# 1 Afghanistan 172716
# 2 Albania 270455
# 3 Algeria 264365
# 4 Andorra 37820
# 5 Angola 98671
# 6 Antarctica 11
#### VACCINES
jh_vaccine = fetch_data(url = "https://raw.githubusercontent.com/govex/COVID-19/master/data_tables/vaccine_data/global_data/vaccine_data_global.csv",
path = "data/js-vac.csv") %>%
select(Province_State,Country_Region, Doses_admin,People_partially_vaccinated,People_fully_vaccinated,Date) %>%
select(-c(Date)) %>%
rename(Country = Country_Region) %>%
mutate(
Country = ifelse(
Province_State == "French Guiana" &
Country == "France",
"French Guiana",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "French Polynesia" &
Country == "France",
"French Polynesia",
Country
)
) %>%
mutate(Country = ifelse(
Province_State == "Guadeloupe" &
Country == "France",
"Guadeloupe",
Country
)) %>%
mutate(Country = ifelse(
Province_State == "Martinique" &
Country == "France",
"Martinique",
Country
)) %>%
mutate(Country = ifelse(
Province_State == "Mayotte" &
Country == "France",
"Mayotte",
Country
)) %>%
mutate(
Country = ifelse(
Province_State == "New Caledonia" &
Country == "France",
"New Caledonia",
Country
)
) %>%
mutate(Country = ifelse(
Province_State == "Reunion" &
Country == "France",
"Reunion",
Country
)) %>%
mutate(
Country = ifelse(
Province_State == "Saint Barthelemy" &
Country == "France",
"Saint Barthelemy",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Saint Pierre and Miquelon" &
Country == "France",
"Saint Pierre and Miquelon",
Country
)
) %>%
mutate(Country = ifelse(
Province_State == "St Martin" &
Country == "France",
"St Martin",
Country
)) %>%
mutate(
Country = ifelse(
Province_State == "Wallis and Futuna" &
Country == "France",
"Wallis and Futuna",
Country
)
) %>%
mutate(Country = ifelse(
Province_State == "Curacao" &
Country == "Netherlands",
"Curacao",
Country
)) %>%
mutate(
Country = ifelse(
Province_State == "Sint Maarten" &
Country == "Netherlands",
" Sint Maarten",
Country
)
) %>%
mutate(Country = ifelse(
Province_State == "Aruba" &
Country == "Netherlands",
"Aruba",
Country
)) %>%
mutate(
Country = ifelse(
Province_State == "Bonaire, Sint Eustatius and Saba" &
Country == "Netherlands",
"Bonaire, Sint Eustatius and Saba",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Anguilla" &
Country == "United Kingdom",
"Anguilla",
Country
)
) %>%
mutate(Country = ifelse(
Province_State == "Bermuda" &
Country == "United Kingdom",
"Bermuda",
Country
)) %>%
mutate(
Country = ifelse(
Province_State == "British Virgin Islands" &
Country == "United Kingdom",
"British Virgin Islands",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Cayman Islands" &
Country == "United Kingdom",
"Cayman Islands",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Channel Islands" &
Country == "United Kingdom",
"Channel Islands",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Gibraltar" &
Country == "United Kingdom",
"Gibraltar",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Montserrat" &
Country == "United Kingdom",
"Montserrat",
Country
)
) %>%
mutate(
Country = ifelse(
Province_State == "Turks and Caicos Islands" &
Country == "United Kingdom",
"Turks and Caicos Islands",
Country
)
) %>%
mutate(
Country = case_when(
Country == "US" ~ "USA",
Country == "The Bahamas" ~ "Bahamas",
Country == "Taiwan*" ~ "Taiwan",
Country == "Korea, South" ~ "South Korea",
Country == "Congo (Kinshasa)" ~ "Democratic Republic of the Congo",
Country == "Congo (Brazzaville)" ~ "Republic of the Congo",
Country == "Czechia" ~ "Czech Republic",
Country == "Wallis and Futuna" ~ "Wallis and Futuna Islands",
Country == "Bonaire, Sint Eustatius and Saba" ~ "Bonaire",
TRUE ~ Country
)
) %>%
select(-c(Province_State))
jh_vaccine = aggregate(. ~ Country, jh_vaccine, FUN = sum)
# > head(jh_vaccine)
# Country Doses_admin People_partially_vaccinated People_fully_vaccinated
# 1 Afghanistan 5535254 4907058 4231984
# 2 Albania 2707658 1269746 1196277
# 3 Algeria 13461201 7456361 6076272
# 4 Andorra 142420 57797 53250
# 5 Angola 15505389 10591264 5448403
# 6 Antigua and Barbuda 124726 63492 60963
##################################################################
## GISAID Global Monthly Data ##
##################################################################
gisaid = readxl::read_xlsx("../../../Downloads/gisaid_monthly_submissions_global_2022-02-21.xlsx") %>%
rename(Country = ...1) %>%
mutate(Country = case_when(
Country == "US" ~ "USA",
Country == "The Bahamas" ~ "Bahamas",
TRUE ~ Country
)) %>%
pivot_longer(!Country, names_to = "Date", values_to = "Count") %>%
filter(Date != "country_total") %>%
mutate(Date = paste0(substr(Date, 4, 8), "/", substr(Date, 1, 2))) %>%
filter(Country != "monthly total:")
gisaid$GISAID.total.Submissions = ave(gisaid$Count, gisaid$Country, FUN = cumsum)
latest_gisaid = gisaid %>% filter(Date == "2022/02") %>% arrange(desc(GISAID.total.Submissions))
#################################################################
## Join Data ##
#################################################################
main_df = read.csv("../../../Downloads/summary-data-countries (1).csv") %>%
rename(Country = ï..Country) %>%
mutate(
Country = case_when(
Country == "State of Palestine" ~ "Palestine",
Country == "Viet Nam" ~ "Vietnam",
TRUE ~ Country
)
) %>%
right_join(latest_gisaid) %>%
select(-c(Date, Raw.reads.submitted, Count)) %>%
rename(C19DP.total.Submissions = Sequences.submitted) %>%
left_join(jh_global_covid) %>%
left_join(jh_vaccine) %>%
na.omit(cases) %>%
mutate("Genomes per confirmed cases (GISAID)" = GISAID.total.Submissions / cases) %>%
mutate("Genomes per confirmed cases (C19DP)" = C19DP.total.Submissions / cases) %>%
mutate("Genomes per confirmed full vaccine (GISAID)" = GISAID.total.Submissions / cases) %>%
mutate("Genomes per confirmed full vaccine (C19DP)" = C19DP.total.Submissions / cases)
main_df$continent = countrycode(sourcevar = main_df[, "Country"],
origin = "country.name",
destination = "continent")
LS0tDQp0aXRsZTogIlRSVVNUIFByaW5jaXBsZXMgZm9yIFNBUlMtQ29WLTIgZGlnaXRhbCByZXBvc2l0b3JpZXM6IGEgY2FzZSBzdHVkeSBvZiBHSVNBSUQgYW5kIHRoZSBDb3ZpZC0xOSBEYXRhIFBvcnRhbCAiDQphdXRob3I6ICJOYXRoYW5hZWwgU2hlZWhhbiAmIFNhYmluYSBMZW9uZWxsaSINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCi0tLQ0KLS0tDQoNCiMjIFRSVVNUIFByaW5jaXBsZXMNCg0KIkFzIGluZm9ybWF0aW9uIGFuZCBjb21tdW5pY2F0aW9uIHRlY2hub2xvZ3kgaGFzIGJlY29tZSBwZXJ2YXNpdmUgaW4gb3VyIHNvY2lldHksIHdlIGFyZSBpbmNyZWFzaW5nbHkgZGVwZW5kZW50IG9uIGJvdGggZGlnaXRhbCBkYXRhIGFuZCByZXBvc2l0b3JpZXMgdGhhdCBwcm92aWRlIGFjY2VzcyB0byBhbmQgZW5hYmxlIHRoZSB1c2Ugb2Ygc3VjaCByZXNvdXJjZXMuIFJlcG9zaXRvcmllcyBtdXN0IGVhcm4gdGhlIHRydXN0IG9mIHRoZSBjb21tdW5pdGllcyB0aGV5IGludGVuZCB0byBzZXJ2ZSBhbmQgZGVtb25zdHJhdGUgdGhhdCB0aGV5IGFyZSByZWxpYWJsZSBhbmQgY2FwYWJsZSBvZiBhcHByb3ByaWF0ZWx5IG1hbmFnaW5nIHRoZSBkYXRhIHRoZXkgaG9sZC4iIChMaW4gZXQgYWwuIDIwMjApDQoNCiMjIyMgVHJhbnNwYXJlbmN5DQotIFRvIGJlIHRyYW5zcGFyZW50IGFib3V0IHNwZWNpZmljIHJlcG9zaXRvcnkgc2VydmljZXMgYW5kIGRhdGEgaG9sZGluZ3MgdGhhdCBhcmUgdmVyaWZpYWJsZSBieSBwdWJsaWNseSBhY2Nlc3NpYmxlIGV2aWRlbmNlLg0KDQojIyMjIFJlc3BvbnNpYmlsaXR5DQotIFRvIGJlIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGUgYXV0aGVudGljaXR5IGFuZCBpbnRlZ3JpdHkgb2YgZGF0YSBob2xkaW5ncyBhbmQgZm9yIHRoZSByZWxpYWJpbGl0eSBhbmQgcGVyc2lzdGVuY2Ugb2YgaXRzIHNlcnZpY2UuDQoNCiMjIyMgVXNlciBGb2N1cwkNCi0gVG8gZW5zdXJlIHRoYXQgdGhlIGRhdGEgbWFuYWdlbWVudCBub3JtcyBhbmQgZXhwZWN0YXRpb25zIG9mIHRhcmdldCB1c2VyIGNvbW11bml0aWVzIGFyZSBtZXQuDQoNCiMjIyMgU3VzdGFpbmFiaWxpdHkJDQotIFRvIHN1c3RhaW4gc2VydmljZXMgYW5kIHByZXNlcnZlIGRhdGEgaG9sZGluZ3MgZm9yIHRoZSBsb25nLXRlcm0uDQoNCiMjIyMgVGVjaG5vbG9neQkNCi0gVG8gcHJvdmlkZSBpbmZyYXN0cnVjdHVyZSBhbmQgY2FwYWJpbGl0aWVzIHRvIHN1cHBvcnQgc2VjdXJlLCBwZXJzaXN0ZW50LCBhbmQgcmVsaWFibGUgc2VydmljZXMuDQoNCiMgRGF0YSBDbGVhbmluZyBhbmQgVHJhbnNmb3JtYXRpb24NCg0KYGBge3IgZXZhbD1UUlVFfQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlicmFyeSAgICAgICAgICAgICAgICAgICAgICAgICAgICMjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KcGtncyA9IGMoInRpZHl2ZXJzZSIsDQogICAgICAgICAiZGRwbG90IiwNCiAgICAgICAgICJjb3VudHJ5Y29kZSIsDQogICAgICAgICAic2hvd3RleHQiLA0KICAgICAgICAgImdncHViciIpDQppbnN0YWxsZWRfcGtncyA9IHBrZ3MgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkNCmlmIChhbnkoaW5zdGFsbGVkX3BrZ3MgPT0gRkFMU0UpKSB7DQogIGluc3RhbGwucGFja2FnZXNbIWluc3RhbGxlZF9wa2dzXQ0KfQ0KaW52aXNpYmxlKGxhcHBseShwa2dzLCBsaWJyYXJ5LCBjaGFyYWN0ZXIub25seSA9IFRSVUUpKQ0Kcm0oaW5zdGFsbGVkX3BrZ3MsIHBrZ3MpDQpmb250X2FkZF9nb29nbGUoIlVidW50dSIsICJ1YiIpDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjICAgICAgICAgICAgICAgICAgICAgICBIZWxwZXIgRnVuY3Rpb25zICAgICAgICAgICAgICAgICAgICAgICAjIyB0aGFueCBmb3IgaGVscGluDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmZldGNoX2RhdGEgPSBmdW5jdGlvbih1cmwscGF0aCkgew0KIHVybCA9IHVybA0KIHBhdGggPSBwYXRoDQogZG93bmxvYWQuZmlsZSh1cmwscGF0aCkNCiByZWFkLmNzdihwYXRoKQ0KfQ0KZGFya190aGVtZSA9IGZ1bmN0aW9uKCkgew0KICB0aGVtZSgNCiAgICAjIGFkZCBib3JkZXIgMSkNCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoDQogICAgICBjb2xvdXIgPSAic2xhdGVncmV5IiwNCiAgICAgIGZpbGwgPSBOQSwNCiAgICAgIGxpbmV0eXBlID0gMg0KICAgICksDQogICAgIyBjb2xvciBiYWNrZ3JvdW5kIDIpDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiksDQogICAgIyBtb2RpZnkgZ3JpZCAzKQ0KICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfbGluZSgNCiAgICAgIGNvbG91ciA9ICIjY2YyZTJlIiwNCiAgICAgIGxpbmV0eXBlID0gMywNCiAgICAgIHNpemUgPSAwLjUNCiAgICApLA0KICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICMgbW9kaWZ5IHRleHQsIGF4aXMgYW5kIGNvbG91ciA0KSBhbmQgNSkNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoDQogICAgICBjb2xvdXIgPSAid2hpdGUiLA0KICAgICAgZmFjZSA9ICJpdGFsaWMiLA0KICAgICAgZmFtaWx5ID0gInNhbnMiDQogICAgKSwNCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJ3aGl0ZSIsIGZhbWlseSA9ICJzYW5zIiksDQogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAid2hpdGUiKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjY2YyZTJlIiksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2FucyIsIGhqdXN0ID0gLjUsIHNpemUgPSAxNiksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2FucyIsIGhqdXN0ID0gLjUsIHNpemUgPSAxMiksDQogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjY2YyZTJlIiksDQogICAgbGVnZW5kLnRleHQgID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIndoaXRlIiwgZmFtaWx5ID0gInNhbnMiLCBzaXplID0gMTApLA0KICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjY2YyZTJlIiksDQogICAgIyBsZWdlbmQgYXQgdGhlIGJvdHRvbSA2KQ0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iDQogICkNCn0NCndzcyA9IGZ1bmN0aW9uKGspIHsNCiAga21lYW5zKGIsIGssIG5zdGFydCA9IDEwICkkdG90LndpdGhpbnNzDQp9DQpvcHRpb25zKHNjaXBlbj05OTkpDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMgIERvd25sb2FkIGxhdGVzdCBKb2huIEhvcGtpbnMgZ2xvYmFsIENvdmlkLTE5IGNhc2VzICYgdmFjY2luZXMgZGF0YSAgIyMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyMjIyBDQVNFUw0KamhfZ2xvYmFsX2NvdmlkID0gZmV0Y2hfZGF0YSh1cmwgPSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5L21hc3Rlci9jc3NlX2NvdmlkXzE5X2RhdGEvY3NzZV9jb3ZpZF8xOV90aW1lX3Nlcmllcy90aW1lX3Nlcmllc19jb3ZpZDE5X2NvbmZpcm1lZF9nbG9iYWwuY3N2IiwNCiAgICAgICAgICAgcGF0aCA9ICJkYXRhL2NvdmlkLWpoLmNzdiIgIyMgZmV0Y2ggbGF0ZXN0IGdpdGh1YiBkYXRhDQogICAgICAgICAgICkgJT4lDQogIHNlbGVjdCgtYyhMYXQsIExvbmcpKSAlPiUgIyBiZSBnb25lIGxhdCBsb25nDQogICMgc2VsZWN0KC0xKSAlPiUNCiAgcmVuYW1lKENvdW50cnkgPSAyKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoUHJvdmluY2UuU3RhdGUgPT0gIkZyZW5jaCBHdWlhbmEiICYgQ291bnRyeSA9PSAiRnJhbmNlIiwgIkZyZW5jaCBHdWlhbmEiLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJGcmVuY2ggUG9seW5lc2lhIiAmIENvdW50cnkgPT0gIkZyYW5jZSIsICJGcmVuY2ggUG9seW5lc2lhIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiR3VhZGVsb3VwZSIgJiBDb3VudHJ5ID09ICJGcmFuY2UiLCAiR3VhZGVsb3VwZSIsIENvdW50cnkpKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoUHJvdmluY2UuU3RhdGUgPT0gIk1hcnRpbmlxdWUiICYgQ291bnRyeSA9PSAiRnJhbmNlIiwgIk1hcnRpbmlxdWUiLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJNYXlvdHRlIiAmIENvdW50cnkgPT0gIkZyYW5jZSIsICJNYXlvdHRlIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiTmV3IENhbGVkb25pYSIgJiBDb3VudHJ5ID09ICJGcmFuY2UiLCAiTmV3IENhbGVkb25pYSIsIENvdW50cnkpKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoUHJvdmluY2UuU3RhdGUgPT0gIlJldW5pb24iICYgQ291bnRyeSA9PSAiRnJhbmNlIiwgIlJldW5pb24iLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJTYWludCBCYXJ0aGVsZW15IiAmIENvdW50cnkgPT0gIkZyYW5jZSIsICJTYWludCBCYXJ0aGVsZW15IiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiU2FpbnQgUGllcnJlIGFuZCBNaXF1ZWxvbiIgJiBDb3VudHJ5ID09ICJGcmFuY2UiLCAiU2FpbnQgUGllcnJlIGFuZCBNaXF1ZWxvbiIsIENvdW50cnkpKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoUHJvdmluY2UuU3RhdGUgPT0gIlN0IE1hcnRpbiIgJiBDb3VudHJ5ID09ICJGcmFuY2UiLCAiU3QgTWFydGluIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiV2FsbGlzIGFuZCBGdXR1bmEiICYgQ291bnRyeSA9PSAiRnJhbmNlIiwgIldhbGxpcyBhbmQgRnV0dW5hIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiQ3VyYWNhbyIgJiBDb3VudHJ5ID09ICJOZXRoZXJsYW5kcyIsICJDdXJhY2FvIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiU2ludCBNYWFydGVuIiAmIENvdW50cnkgPT0gIk5ldGhlcmxhbmRzIiwgIglTaW50IE1hYXJ0ZW4iLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJBcnViYSIgJiBDb3VudHJ5ID09ICJOZXRoZXJsYW5kcyIsICJBcnViYSIsIENvdW50cnkpKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoUHJvdmluY2UuU3RhdGUgPT0gIkJvbmFpcmUsIFNpbnQgRXVzdGF0aXVzIGFuZCBTYWJhIiAmIENvdW50cnkgPT0gIk5ldGhlcmxhbmRzIiwgIkJvbmFpcmUsIFNpbnQgRXVzdGF0aXVzIGFuZCBTYWJhIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiQW5ndWlsbGEiICYgQ291bnRyeSA9PSAiVW5pdGVkIEtpbmdkb20iLCAiQW5ndWlsbGEiLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJCZXJtdWRhIiAmIENvdW50cnkgPT0gIlVuaXRlZCBLaW5nZG9tIiwgIkJlcm11ZGEiLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJCcml0aXNoIFZpcmdpbiBJc2xhbmRzIiAmIENvdW50cnkgPT0gIlVuaXRlZCBLaW5nZG9tIiwgIkJyaXRpc2ggVmlyZ2luIElzbGFuZHMiLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJDYXltYW4gSXNsYW5kcyIgJiBDb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIsICJDYXltYW4gSXNsYW5kcyIsIENvdW50cnkpKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoUHJvdmluY2UuU3RhdGUgPT0gIkNoYW5uZWwgSXNsYW5kcyIgJiBDb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIsICJDaGFubmVsIElzbGFuZHMiLCBDb3VudHJ5KSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKFByb3ZpbmNlLlN0YXRlID09ICJHaWJyYWx0YXIiICYgQ291bnRyeSA9PSAiVW5pdGVkIEtpbmdkb20iLCAiR2licmFsdGFyIiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiTW9udHNlcnJhdCIgJiBDb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIsICJNb250c2VycmF0IiwgQ291bnRyeSkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZShQcm92aW5jZS5TdGF0ZSA9PSAiVHVya3MgYW5kIENhaWNvcyBJc2xhbmRzIiAmIENvdW50cnkgPT0gIlVuaXRlZCBLaW5nZG9tIiwgIlR1cmtzIGFuZCBDYWljb3MgSXNsYW5kcyIsIENvdW50cnkpKSAlPiUNCiAgc2VsZWN0KC1jKFByb3ZpbmNlLlN0YXRlKSkgJT4lDQogIHBpdm90X2xvbmdlcighQ291bnRyeSwgbmFtZXNfdG8gPSAiRGF0ZSIsIHZhbHVlc190byA9ICJjYXNlcyIpICU+JQ0KICBtdXRhdGUoRGF0ZSA9IHBhc3RlMChzdWIoJy4nLCAnJywgRGF0ZSkpKSAlPiUNCiAgZmlsdGVyKERhdGUgPT0gIjIuMjIuMjIiKSAlPiUNCiAgc2VsZWN0KC1jKERhdGUpKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBjYXNlX3doZW4oDQogICAgQ291bnRyeSA9PSAiVVMiIH4gIlVTQSIsDQogICAgQ291bnRyeSA9PSAiVGhlIEJhaGFtYXMiIH4gIkJhaGFtYXMiLA0KICAgIENvdW50cnkgPT0gIlRhaXdhbioiIH4gIlRhaXdhbiIsDQogICAgQ291bnRyeSA9PSAiS29yZWEsIFNvdXRoIiB+ICJTb3V0aCBLb3JlYSIsDQogICAgQ291bnRyeSA9PSAiQ29uZ28gKEtpbnNoYXNhKSIgfiAiRGVtb2NyYXRpYyBSZXB1YmxpYyBvZiB0aGUgQ29uZ28iLA0KICAgIENvdW50cnkgPT0gIkNvbmdvIChCcmF6emF2aWxsZSkiIH4gIlJlcHVibGljIG9mIHRoZSBDb25nbyIsDQogICAgQ291bnRyeSA9PSAiQ3plY2hpYSIgfiAiQ3plY2ggUmVwdWJsaWMiLA0KICAgIENvdW50cnkgPT0gIldhbGxpcyBhbmQgRnV0dW5hIiB+ICJXYWxsaXMgYW5kIEZ1dHVuYSBJc2xhbmRzIiwNCiAgICBDb3VudHJ5ID09ICJCb25haXJlLCBTaW50IEV1c3RhdGl1cyBhbmQgU2FiYSIgfiAiQm9uYWlyZSIsDQogICAgVFJVRSB+IENvdW50cnkNCiAgKSkNCg0KamhfZ2xvYmFsX2NvdmlkID0gYWdncmVnYXRlKC4gfiBDb3VudHJ5LCBqaF9nbG9iYWxfY292aWQsICBGVU4gPSBzdW0pDQojID4gaGVhZChqaF9nbG9iYWxfY292aWQpDQojIENvdW50cnkgIGNhc2VzDQojIDEgQWZnaGFuaXN0YW4gMTcyNzE2DQojIDIgICAgIEFsYmFuaWEgMjcwNDU1DQojIDMgICAgIEFsZ2VyaWEgMjY0MzY1DQojIDQgICAgIEFuZG9ycmEgIDM3ODIwDQojIDUgICAgICBBbmdvbGEgIDk4NjcxDQojIDYgIEFudGFyY3RpY2EgICAgIDExDQoNCiMjIyMgVkFDQ0lORVMNCmpoX3ZhY2NpbmUgPSBmZXRjaF9kYXRhKHVybCA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vZ292ZXgvQ09WSUQtMTkvbWFzdGVyL2RhdGFfdGFibGVzL3ZhY2NpbmVfZGF0YS9nbG9iYWxfZGF0YS92YWNjaW5lX2RhdGFfZ2xvYmFsLmNzdiIsDQogICAgICAgICAgIHBhdGggPSAiZGF0YS9qcy12YWMuY3N2IikgJT4lDQogIHNlbGVjdChQcm92aW5jZV9TdGF0ZSxDb3VudHJ5X1JlZ2lvbiwgRG9zZXNfYWRtaW4sUGVvcGxlX3BhcnRpYWxseV92YWNjaW5hdGVkLFBlb3BsZV9mdWxseV92YWNjaW5hdGVkLERhdGUpICU+JQ0KICBzZWxlY3QoLWMoRGF0ZSkpICU+JQ0KICByZW5hbWUoQ291bnRyeSA9IENvdW50cnlfUmVnaW9uKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiRnJlbmNoIEd1aWFuYSIgJg0KICAgICAgICBDb3VudHJ5ID09ICJGcmFuY2UiLA0KICAgICAgIkZyZW5jaCBHdWlhbmEiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiRnJlbmNoIFBvbHluZXNpYSIgJg0KICAgICAgICBDb3VudHJ5ID09ICJGcmFuY2UiLA0KICAgICAgIkZyZW5jaCBQb2x5bmVzaWEiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoDQogICAgUHJvdmluY2VfU3RhdGUgPT0gIkd1YWRlbG91cGUiICYNCiAgICAgIENvdW50cnkgPT0gIkZyYW5jZSIsDQogICAgIkd1YWRlbG91cGUiLA0KICAgIENvdW50cnkNCiAgKSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKA0KICAgIFByb3ZpbmNlX1N0YXRlID09ICJNYXJ0aW5pcXVlIiAmDQogICAgICBDb3VudHJ5ID09ICJGcmFuY2UiLA0KICAgICJNYXJ0aW5pcXVlIiwNCiAgICBDb3VudHJ5DQogICkpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZSgNCiAgICBQcm92aW5jZV9TdGF0ZSA9PSAiTWF5b3R0ZSIgJg0KICAgICAgQ291bnRyeSA9PSAiRnJhbmNlIiwNCiAgICAiTWF5b3R0ZSIsDQogICAgQ291bnRyeQ0KICApKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiTmV3IENhbGVkb25pYSIgJg0KICAgICAgICBDb3VudHJ5ID09ICJGcmFuY2UiLA0KICAgICAgIk5ldyBDYWxlZG9uaWEiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoDQogICAgUHJvdmluY2VfU3RhdGUgPT0gIlJldW5pb24iICYNCiAgICAgIENvdW50cnkgPT0gIkZyYW5jZSIsDQogICAgIlJldW5pb24iLA0KICAgIENvdW50cnkNCiAgKSkgJT4lDQogIG11dGF0ZSgNCiAgICBDb3VudHJ5ID0gaWZlbHNlKA0KICAgICAgUHJvdmluY2VfU3RhdGUgPT0gIlNhaW50IEJhcnRoZWxlbXkiICYNCiAgICAgICAgQ291bnRyeSA9PSAiRnJhbmNlIiwNCiAgICAgICJTYWludCBCYXJ0aGVsZW15IiwNCiAgICAgIENvdW50cnkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICBDb3VudHJ5ID0gaWZlbHNlKA0KICAgICAgUHJvdmluY2VfU3RhdGUgPT0gIlNhaW50IFBpZXJyZSBhbmQgTWlxdWVsb24iICYNCiAgICAgICAgQ291bnRyeSA9PSAiRnJhbmNlIiwNCiAgICAgICJTYWludCBQaWVycmUgYW5kIE1pcXVlbG9uIiwNCiAgICAgIENvdW50cnkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKA0KICAgIFByb3ZpbmNlX1N0YXRlID09ICJTdCBNYXJ0aW4iICYNCiAgICAgIENvdW50cnkgPT0gIkZyYW5jZSIsDQogICAgIlN0IE1hcnRpbiIsDQogICAgQ291bnRyeQ0KICApKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiV2FsbGlzIGFuZCBGdXR1bmEiICYNCiAgICAgICAgQ291bnRyeSA9PSAiRnJhbmNlIiwNCiAgICAgICJXYWxsaXMgYW5kIEZ1dHVuYSIsDQogICAgICBDb3VudHJ5DQogICAgKQ0KICApICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGlmZWxzZSgNCiAgICBQcm92aW5jZV9TdGF0ZSA9PSAiQ3VyYWNhbyIgJg0KICAgICAgQ291bnRyeSA9PSAiTmV0aGVybGFuZHMiLA0KICAgICJDdXJhY2FvIiwNCiAgICBDb3VudHJ5DQogICkpICU+JQ0KICBtdXRhdGUoDQogICAgQ291bnRyeSA9IGlmZWxzZSgNCiAgICAgIFByb3ZpbmNlX1N0YXRlID09ICJTaW50IE1hYXJ0ZW4iICYNCiAgICAgICAgQ291bnRyeSA9PSAiTmV0aGVybGFuZHMiLA0KICAgICAgIglTaW50IE1hYXJ0ZW4iLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKENvdW50cnkgPSBpZmVsc2UoDQogICAgUHJvdmluY2VfU3RhdGUgPT0gIkFydWJhIiAmDQogICAgICBDb3VudHJ5ID09ICJOZXRoZXJsYW5kcyIsDQogICAgIkFydWJhIiwNCiAgICBDb3VudHJ5DQogICkpICU+JQ0KICBtdXRhdGUoDQogICAgQ291bnRyeSA9IGlmZWxzZSgNCiAgICAgIFByb3ZpbmNlX1N0YXRlID09ICJCb25haXJlLCBTaW50IEV1c3RhdGl1cyBhbmQgU2FiYSIgJg0KICAgICAgICBDb3VudHJ5ID09ICJOZXRoZXJsYW5kcyIsDQogICAgICAiQm9uYWlyZSwgU2ludCBFdXN0YXRpdXMgYW5kIFNhYmEiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiQW5ndWlsbGEiICYNCiAgICAgICAgQ291bnRyeSA9PSAiVW5pdGVkIEtpbmdkb20iLA0KICAgICAgIkFuZ3VpbGxhIiwNCiAgICAgIENvdW50cnkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gaWZlbHNlKA0KICAgIFByb3ZpbmNlX1N0YXRlID09ICJCZXJtdWRhIiAmDQogICAgICBDb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIsDQogICAgIkJlcm11ZGEiLA0KICAgIENvdW50cnkNCiAgKSkgJT4lDQogIG11dGF0ZSgNCiAgICBDb3VudHJ5ID0gaWZlbHNlKA0KICAgICAgUHJvdmluY2VfU3RhdGUgPT0gIkJyaXRpc2ggVmlyZ2luIElzbGFuZHMiICYNCiAgICAgICAgQ291bnRyeSA9PSAiVW5pdGVkIEtpbmdkb20iLA0KICAgICAgIkJyaXRpc2ggVmlyZ2luIElzbGFuZHMiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiQ2F5bWFuIElzbGFuZHMiICYNCiAgICAgICAgQ291bnRyeSA9PSAiVW5pdGVkIEtpbmdkb20iLA0KICAgICAgIkNheW1hbiBJc2xhbmRzIiwNCiAgICAgIENvdW50cnkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICBDb3VudHJ5ID0gaWZlbHNlKA0KICAgICAgUHJvdmluY2VfU3RhdGUgPT0gIkNoYW5uZWwgSXNsYW5kcyIgJg0KICAgICAgICBDb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIsDQogICAgICAiQ2hhbm5lbCBJc2xhbmRzIiwNCiAgICAgIENvdW50cnkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICBDb3VudHJ5ID0gaWZlbHNlKA0KICAgICAgUHJvdmluY2VfU3RhdGUgPT0gIkdpYnJhbHRhciIgJg0KICAgICAgICBDb3VudHJ5ID09ICJVbml0ZWQgS2luZ2RvbSIsDQogICAgICAiR2licmFsdGFyIiwNCiAgICAgIENvdW50cnkNCiAgICApDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICBDb3VudHJ5ID0gaWZlbHNlKA0KICAgICAgUHJvdmluY2VfU3RhdGUgPT0gIk1vbnRzZXJyYXQiICYNCiAgICAgICAgQ291bnRyeSA9PSAiVW5pdGVkIEtpbmdkb20iLA0KICAgICAgIk1vbnRzZXJyYXQiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBpZmVsc2UoDQogICAgICBQcm92aW5jZV9TdGF0ZSA9PSAiVHVya3MgYW5kIENhaWNvcyBJc2xhbmRzIiAmDQogICAgICAgIENvdW50cnkgPT0gIlVuaXRlZCBLaW5nZG9tIiwNCiAgICAgICJUdXJrcyBhbmQgQ2FpY29zIElzbGFuZHMiLA0KICAgICAgQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBjYXNlX3doZW4oDQogICAgICBDb3VudHJ5ID09ICJVUyIgfiAiVVNBIiwNCiAgICAgIENvdW50cnkgPT0gIlRoZSBCYWhhbWFzIiB+ICJCYWhhbWFzIiwNCiAgICAgIENvdW50cnkgPT0gIlRhaXdhbioiIH4gIlRhaXdhbiIsDQogICAgICBDb3VudHJ5ID09ICJLb3JlYSwgU291dGgiIH4gIlNvdXRoIEtvcmVhIiwNCiAgICAgIENvdW50cnkgPT0gIkNvbmdvIChLaW5zaGFzYSkiIH4gIkRlbW9jcmF0aWMgUmVwdWJsaWMgb2YgdGhlIENvbmdvIiwNCiAgICAgIENvdW50cnkgPT0gIkNvbmdvIChCcmF6emF2aWxsZSkiIH4gIlJlcHVibGljIG9mIHRoZSBDb25nbyIsDQogICAgICBDb3VudHJ5ID09ICJDemVjaGlhIiB+ICJDemVjaCBSZXB1YmxpYyIsDQogICAgICBDb3VudHJ5ID09ICJXYWxsaXMgYW5kIEZ1dHVuYSIgfiAiV2FsbGlzIGFuZCBGdXR1bmEgSXNsYW5kcyIsDQogICAgICBDb3VudHJ5ID09ICJCb25haXJlLCBTaW50IEV1c3RhdGl1cyBhbmQgU2FiYSIgfiAiQm9uYWlyZSIsDQogICAgICBUUlVFIH4gQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgc2VsZWN0KC1jKFByb3ZpbmNlX1N0YXRlKSkNCg0KamhfdmFjY2luZSA9IGFnZ3JlZ2F0ZSguIH4gQ291bnRyeSwgamhfdmFjY2luZSwgRlVOID0gc3VtKQ0KIyA+IGhlYWQoamhfdmFjY2luZSkNCiMgQ291bnRyeSBEb3Nlc19hZG1pbiBQZW9wbGVfcGFydGlhbGx5X3ZhY2NpbmF0ZWQgUGVvcGxlX2Z1bGx5X3ZhY2NpbmF0ZWQNCiMgMSAgICAgICAgIEFmZ2hhbmlzdGFuICAgICA1NTM1MjU0ICAgICAgICAgICAgICAgICAgICAgNDkwNzA1OCAgICAgICAgICAgICAgICAgNDIzMTk4NA0KIyAyICAgICAgICAgICAgIEFsYmFuaWEgICAgIDI3MDc2NTggICAgICAgICAgICAgICAgICAgICAxMjY5NzQ2ICAgICAgICAgICAgICAgICAxMTk2Mjc3DQojIDMgICAgICAgICAgICAgQWxnZXJpYSAgICAxMzQ2MTIwMSAgICAgICAgICAgICAgICAgICAgIDc0NTYzNjEgICAgICAgICAgICAgICAgIDYwNzYyNzINCiMgNCAgICAgICAgICAgICBBbmRvcnJhICAgICAgMTQyNDIwICAgICAgICAgICAgICAgICAgICAgICA1Nzc5NyAgICAgICAgICAgICAgICAgICA1MzI1MA0KIyA1ICAgICAgICAgICAgICBBbmdvbGEgICAgMTU1MDUzODkgICAgICAgICAgICAgICAgICAgIDEwNTkxMjY0ICAgICAgICAgICAgICAgICA1NDQ4NDAzDQojIDYgQW50aWd1YSBhbmQgQmFyYnVkYSAgICAgIDEyNDcyNiAgICAgICAgICAgICAgICAgICAgICAgNjM0OTIgICAgICAgICAgICAgICAgICAgNjA5NjMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMgICAgICAgICAgICAgICAgICBHSVNBSUQgR2xvYmFsIE1vbnRobHkgRGF0YSAgICAgICAgICAgICAgICAgICMjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmdpc2FpZCA9IHJlYWR4bDo6cmVhZF94bHN4KCIuLi8uLi8uLi9Eb3dubG9hZHMvZ2lzYWlkX21vbnRobHlfc3VibWlzc2lvbnNfZ2xvYmFsXzIwMjItMDItMjEueGxzeCIpICU+JQ0KICByZW5hbWUoQ291bnRyeSA9IC4uLjEpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGNhc2Vfd2hlbigNCiAgICBDb3VudHJ5ID09ICJVUyIgfiAiVVNBIiwNCiAgICBDb3VudHJ5ID09ICJUaGUgQmFoYW1hcyIgfiAiQmFoYW1hcyIsDQogICAgVFJVRSB+IENvdW50cnkNCiAgKSkgICU+JQ0KICBwaXZvdF9sb25nZXIoIUNvdW50cnksIG5hbWVzX3RvID0gIkRhdGUiLCB2YWx1ZXNfdG8gPSAiQ291bnQiKSAlPiUNCiAgZmlsdGVyKERhdGUgIT0gImNvdW50cnlfdG90YWwiKSAlPiUNCiAgbXV0YXRlKERhdGUgPSBwYXN0ZTAoc3Vic3RyKERhdGUsIDQsIDgpLCAiLyIsIHN1YnN0cihEYXRlLCAxLCAyKSkpICU+JQ0KICBmaWx0ZXIoQ291bnRyeSAhPSAibW9udGhseSB0b3RhbDoiKQ0KDQpnaXNhaWQkR0lTQUlELnRvdGFsLlN1Ym1pc3Npb25zID0gYXZlKGdpc2FpZCRDb3VudCwgZ2lzYWlkJENvdW50cnksIEZVTiA9IGN1bXN1bSkNCg0KbGF0ZXN0X2dpc2FpZCA9IGdpc2FpZCAlPiUgZmlsdGVyKERhdGUgPT0gIjIwMjIvMDIiKSAlPiUgYXJyYW5nZShkZXNjKEdJU0FJRC50b3RhbC5TdWJtaXNzaW9ucykpDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjICAgICAgICAgICAgICAgICAgICAgICAgICBKb2luIERhdGEgICAgICAgICAgICAgICAgICAgICAgICAgICMjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KbWFpbl9kZiA9IHJlYWQuY3N2KCIuLi8uLi8uLi9Eb3dubG9hZHMvc3VtbWFyeS1kYXRhLWNvdW50cmllcyAoMSkuY3N2IikgJT4lDQogIHJlbmFtZShDb3VudHJ5ID0gIMOvLi5Db3VudHJ5KSAlPiUNCiAgbXV0YXRlKA0KICAgIENvdW50cnkgPSBjYXNlX3doZW4oDQogICAgICBDb3VudHJ5ID09ICJTdGF0ZSBvZiBQYWxlc3RpbmUiIH4gIlBhbGVzdGluZSIsDQogICAgICBDb3VudHJ5ID09ICJWaWV0IE5hbSIgfiAiVmlldG5hbSIsDQogICAgICBUUlVFIH4gQ291bnRyeQ0KICAgICkNCiAgKSAlPiUNCiAgcmlnaHRfam9pbihsYXRlc3RfZ2lzYWlkKSAgJT4lDQogIHNlbGVjdCgtYyhEYXRlLCBSYXcucmVhZHMuc3VibWl0dGVkLCBDb3VudCkpICU+JQ0KICByZW5hbWUoQzE5RFAudG90YWwuU3VibWlzc2lvbnMgPSBTZXF1ZW5jZXMuc3VibWl0dGVkKSAlPiUNCiAgbGVmdF9qb2luKGpoX2dsb2JhbF9jb3ZpZCkgJT4lDQogIGxlZnRfam9pbihqaF92YWNjaW5lKSAlPiUNCiAgbmEub21pdChjYXNlcykgJT4lDQogIG11dGF0ZSgiR2Vub21lcyBwZXIgY29uZmlybWVkIGNhc2VzIChHSVNBSUQpIiA9IEdJU0FJRC50b3RhbC5TdWJtaXNzaW9ucyAvIGNhc2VzKSAlPiUNCiAgbXV0YXRlKCJHZW5vbWVzIHBlciBjb25maXJtZWQgY2FzZXMgKEMxOURQKSIgPSAgQzE5RFAudG90YWwuU3VibWlzc2lvbnMgLyBjYXNlcykgJT4lDQogIG11dGF0ZSgiR2Vub21lcyBwZXIgY29uZmlybWVkIGZ1bGwgdmFjY2luZSAoR0lTQUlEKSIgPSBHSVNBSUQudG90YWwuU3VibWlzc2lvbnMgLyBjYXNlcykgJT4lDQogIG11dGF0ZSgiR2Vub21lcyBwZXIgY29uZmlybWVkIGZ1bGwgdmFjY2luZSAoQzE5RFApIiA9ICBDMTlEUC50b3RhbC5TdWJtaXNzaW9ucyAvIGNhc2VzKQ0KDQptYWluX2RmJGNvbnRpbmVudCA9IGNvdW50cnljb2RlKHNvdXJjZXZhciA9IG1haW5fZGZbLCAiQ291bnRyeSJdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW4gPSAiY291bnRyeS5uYW1lIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24gPSAiY29udGluZW50IikNCmBgYA0KDQojIFJlcHJvZHVjaW5nOiBBIHJhY2UgYWdhaW5zdCB0aW1lIChSb21hbm8gYW5kIE1lbG8gMjAyMSkNCg0KIyBHSVNBSUQNCg0KYGBge3IgZXZhbD1UUlVFLCBmaWcud2lkdGg9MTIsZmlnLmhlaWdodD04LCBlY2hvPUZBTFNFfQ0KcD1nZ3Bsb3QobWFpbl9kZiwgYWVzKChHSVNBSUQudG90YWwuU3VibWlzc2lvbnMpLCAobWFpbl9kZiRjYXNlcykpKSArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gY29udGluZW50LHNpemUgPSBgR2Vub21lcyBwZXIgY29uZmlybWVkIGNhc2VzIChHSVNBSUQpYCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDc1IC8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwKSArIGdlb21fdGV4dCgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMobGFiZWwgPSBDb3VudHJ5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRpbmVudCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IDAuMDYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSArIGRhcmtfdGhlbWUoKSArICAgbGFicygNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gIlNlcXVlbmNlZCBHZW5vbWVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gIkNvbmZpcm1lZCBDYXNlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ29uZmlybWVkIENvdmlkLTE5IENhc2VzIHZzLiBcblNlcXVlbmNlZCBHZW5vbWVzIGluIHRoZSBHSVNBSUQgT3BlbiBkYXRhYmFzZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdGlvbiA9ICJcbkZpZy4gMTogVGhlIHByb3BvcnRpb24gb2YgZ2xvYmFsIFNBUlMtQ29WLTIgY2FzZXMgc2VxdWVuY2VkIGFuZCBzaGFyZWQgb24gdGhlIEdJU0FJRCBkYXRhYmFzZSB1bnRpbCBGZWJ1YXJ5IDIyIDIwMjJcbiBUaGUgc2l6ZSBvZiBlYWNoIGNpcmNsZSBpcyBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZiBTQVJTLUNvVi0yIGdlbm9tZXMgc2VxdWVuY2VkIHBlciBudW1iZXIgb2YgY29uZmlybWVkIGNhc2VzLiBDb3VudHJpZXMgYXJlIGNvbG9yZWQgYnkgY29udGluZW50LlxuXG5TQVJTLUNvVi0yIERhdGE6IEpvaG4gSG9wa2lucyINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAgKyBzY2FsZV95X2xvZzEwKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX3J1Zyhjb2w9cmdiKC41LDAsMCxhbHBoYT0uMikpICsgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG9yZGVyID0gMiksY29sID0gZ3VpZGVfbGVnZW5kKG9yZGVyID0gMSkpDQoNCnANCiMgDQojIGMxOWRwX3Bsb3QgPSBnZ2FycmFuZ2UoYzE5ZHBfMSxjMTlkcF8yKQ0KIyBjMTlkcF9wbG90DQoNCmBgYA0KYGBge3IgZXZhbD1UUlVFLCBmaWcud2lkdGg9MTIsZmlnLmhlaWdodD04LCBlY2hvPUZBTFNFfQ0KDQpnaXNhaWRfMiA9IGdncGxvdChtYWluX2RmLCBhZXMoKEdJU0FJRC50b3RhbC5TdWJtaXNzaW9ucyksIChtYWluX2RmJFBlb3BsZV9mdWxseV92YWNjaW5hdGVkKSkpICsgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBjb250aW5lbnQsc2l6ZSA9IGBHZW5vbWVzIHBlciBjb25maXJtZWQgZnVsbCB2YWNjaW5lIChHSVNBSUQpYCksIGFscGhhID0gNzUgLw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMDApICsgZ2VvbV90ZXh0KA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcygNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gQ291bnRyeSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udGluZW50DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gMC4wNg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsgZGFya190aGVtZSgpICsgICBsYWJzKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2VxdWVuY2VkIEdlbm9tZXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAiUGVvcGxlIEZ1bGx5IFZhY2NpbmF0ZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlBlb3BsZSBGdWxseSBWYWNjaW5hdGVkIHZzLiBcblNlcXVlbmNlZCBHZW5vbWVzIGluIHRoZSBHSVNBSUQgT3BlbiBEYXRhYmFzZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdGlvbiA9ICJcbkZpZy4gMjogVGhlIHByb3BvcnRpb24gb2YgcGVvcGxlIGZ1bGx5IHZhY2NpbmF0ZWQgYW5kIGdsb2JhbCBTQVJTLUNvVi0yIGNhc2VzIHNlcXVlbmNlZCBhbmQgc2hhcmVkIG9uIHRoZSBHSVNBSUQgZGF0YWJhc2UgdW50aWwgRmVidWFyeSAyOCAyMDIyXG4gVGhlIHNpemUgb2YgZWFjaCBjaXJjbGUgaXMgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2YgU0FSUy1Db1YtMiBnZW5vbWVzIHNlcXVlbmNlZCBwZXIgbnVtYmVyIG9mIGNvbmZpcm1lZCBjYXNlcy4gQ291bnRyaWVzIGFyZSBjb2xvcmVkIGJ5IGNvbnRpbmVudC5cblxuU0FSUy1Db1YtMiBEYXRhOiBKb2huIEhvcGtpbnMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICArIHNjYWxlX3lfbG9nMTAoKSArIHNjYWxlX3hfbG9nMTAoKSArIGdlb21fcnVnKGNvbD1yZ2IoLjUsMCwwLGFscGhhPS4yKSkgKyBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3JkZXIgPSAyKSxjb2wgPSBndWlkZV9sZWdlbmQob3JkZXIgPSAxKSkNCg0KZ2lzYWlkXzINCg0KICAgICAgDQpgYGANCg0KIyMgQmFyIENoYXJ0IFJhY2UgKENvdW50cmllcyB3aXRoIGdyZWF0ZXIgdGhhbiA1MDAwIHNlcXVlbmNlIHN1Ym1pc3Npb25zKQ0KYGBge3IgZXZhbD1UUlVFLCBmaWcud2lkdGg9MTIsZmlnLmhlaWdodD04LCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQpjb3VudHJpZXMgPSBtYWluX2RmICU+JSBmaWx0ZXIoR0lTQUlELnRvdGFsLlN1Ym1pc3Npb25zID4gNTAwMCkgJT4lIHNlbGVjdChDb3VudHJ5KQ0KZ2lzYWlkX2JhcnBsb3QgPSBpbm5lcl9qb2luKGdpc2FpZCxjb3VudHJpZXMpDQpnaXNhaWRfYmFycGxvdCAlPiUNCiAgYmFyQ2hhcnRSYWNlKA0KICAgIHggPSAiR0lTQUlELnRvdGFsLlN1Ym1pc3Npb25zIiwNCiAgICB5ID0gIkNvdW50cnkiLA0KICAgIHRpbWUgPSAiRGF0ZSIsDQogICAgeXRpdGxlID0gIkNvdW50cnkiLA0KICAgIHh0aXRsZSA9ICJDb3VudCAobiBzdWJtaXNzaW9ucykiLA0KICAgIHRpdGxlID0gIkdsb2JhbCBHSVNBSUQgRXBpQ292IERhdGFiYXNlIFN1Ym1pc3Npb25zIiwNCiAgICBwYWRkaW5nV2lkdGggPSAwLjEsDQogICAgeEZvbnRTaXplID0gMTAsDQogICAgeUZvbnRTaXplID0gMTAsDQogICAgeHRpY2tzID0gMTIsDQogICAgeHRpdGxlRm9udFNpemUgPSAxNCwNCiAgICB5dGl0bGVGb250U2l6ZSA9IDE0LA0KICAgIHRpdGxlRm9udFNpemUgPSAyMiwNCiAgICBzdHJva2UgPSAiYmxhY2siLA0KICAgIHN0cm9rZVdpZHRoID0gTlVMTCwNCiAgICBmb250ID0gImdvY2hpIiwNCiAgICBiZ2NvbCA9ICIjY2YyZTJlIiwNCiAgICBwYW5lbGNvbCA9ICIjZmNiOTAwIiwNCiAgICB4Z3JpZGxpbmVjb2wgPSAiIzhlZDFmYyIsDQogICAgb3BhY2l0eSA9IDEsDQogICAgdGltZUxhYmVsID0gVFJVRSwNCiAgICB0aW1lTGFiZWxPcHRzID0gbGlzdChzaXplID0gMjgsIHByZWZpeCA9ICIiLCBzdWZmaXggPSAiIiwgeE9mZnNldCA9IDAuNSwgeU9mZnNldCA9IDEpLA0KICAgIHdpZHRoID0gTlVMTCwNCiAgICBoZWlnaHQgPSBOVUxMDQogICkNCmBgYA0KDQojIENvdmlkLTE5IERhdGEgUG9ydGFsIGNvbXBhcmlzb24NCmBgYHtyIGV2YWw9VFJVRSwgZmlnLndpZHRoPTEyLGZpZy5oZWlnaHQ9OCwgZWNobz1GQUxTRX0NCg0KIyMjIw0KYzE5ZHBfMSA9IGdncGxvdChtYWluX2RmLCBhZXMoQzE5RFAudG90YWwuU3VibWlzc2lvbnMsIGNhc2VzKSkgKyBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGNvbnRpbmVudCxzaXplPWBHZW5vbWVzIHBlciBjb25maXJtZWQgY2FzZXMgKEMxOURQKWApLGFscGhhID0gNzUgLw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMDApICsgZ2VvbV90ZXh0KA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhsYWJlbCA9IENvdW50cnksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udGluZW50KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gMC4wNg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsgZGFya190aGVtZSgpICsgICBsYWJzKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2VxdWVuY2VkIEdlbm9tZXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAiQ29uZmlybWVkIENhc2VzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDb25maXJtZWQgQ292aWQtMTkgQ2FzZXMgdnMuIFxuU2VxdWVuY2VkIEdlbm9tZXMgaW4gdGhlIENvdmlkLTE5IERhdGEgUG9ydGFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0aW9uID0gIlxuRmlnLiAzOiBUaGUgcHJvcG9ydGlvbiBvZiBnbG9iYWwgU0FSUy1Db1YtMiBjYXNlcyBzZXF1ZW5jZWQgYW5kIHNoYXJlZCBvbiB0aGUgQzE5RFAgZGF0YWJhc2UgdW50aWwgRmVidWFyeSAyOCAyMDIyXG4gVGhlIHNpemUgb2YgZWFjaCBjaXJjbGUgaXMgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2YgU0FSUy1Db1YtMiBnZW5vbWVzIHNlcXVlbmNlZCBwZXIgbnVtYmVyIG9mIGNvbmZpcm1lZCBjYXNlcy4gQ291bnRyaWVzIGFyZSBjb2xvcmVkIGJ5IGNvbnRpbmVudC5cblxuU0FSUy1Db1YtMiBEYXRhOiBKb2huIEhvcGtpbnMiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgICsgc2NhbGVfeV9sb2cxMCgpICsgc2NhbGVfeF9sb2cxMCgpICsgZ2VvbV9ydWcoY29sPXJnYiguNSwwLDAsYWxwaGE9LjIpKSAgKyBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3JkZXIgPSAyKSxjb2wgPSBndWlkZV9sZWdlbmQob3JkZXIgPSAxKSkNCg0KYzE5ZHBfMQ0KDQoNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGZpZy53aWR0aD0xMixmaWcuaGVpZ2h0PTgsIGVjaG89RkFMU0V9DQoNCiMjIyMNCmMxOWRwXzI9Z2dwbG90KG1haW5fZGYsIGFlcygoQzE5RFAudG90YWwuU3VibWlzc2lvbnMpLCAobWFpbl9kZiRQZW9wbGVfZnVsbHlfdmFjY2luYXRlZCkpKSArIGdlb21fcG9pbnQoYWVzKHNpemU9YEdlbm9tZXMgcGVyIGNvbmZpcm1lZCBmdWxsIHZhY2NpbmUgKEMxOURQKWAsY29sb3IgPSBjb250aW5lbnQpLCBhbHBoYSA9IDc1IC8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwMCkgKyBnZW9tX3RleHQoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcygNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IENvdW50cnksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250aW5lbnQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IDAuMDYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgKyBkYXJrX3RoZW1lKCkgKyAgIGxhYnMoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2VxdWVuY2VkIEdlbm9tZXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gIlBlb3BsZSBGdWxseSBWYWNjaW5hdGVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiUGVvcGxlIEZ1bGx5IFZhY2NpbmF0ZWQgdnMuIFxuU2VxdWVuY2VkIEdlbm9tZXMgaW4gdGhlIENvdmlkLTE5IERhdGEgUG9ydGFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdGlvbiA9ICJcbkZpZy4gNDogVGhlIHByb3BvcnRpb24gb2YgcGVvcGxlIGZ1bGx5IHZhY2NpbmF0ZWQgYW5kIGdsb2JhbCBTQVJTLUNvVi0yIGNhc2VzIHNlcXVlbmNlZCBhbmQgc2hhcmVkIG9uIHRoZSBDMTlEUCBkYXRhYmFzZSB1bnRpbCBGZWJ1YXJ5IDI4IDIwMjJcbiBUaGUgc2l6ZSBvZiBlYWNoIGNpcmNsZSBpcyBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZiBTQVJTLUNvVi0yIGdlbm9tZXMgc2VxdWVuY2VkIHBlciBudW1iZXIgb2YgY29uZmlybWVkIGNhc2VzLiBDb3VudHJpZXMgYXJlIGNvbG9yZWQgYnkgY29udGluZW50LlxuXG5TQVJTLUNvVi0yIERhdGE6IEpvaG4gSG9wa2lucyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICArIHNjYWxlX3lfbG9nMTAoKSArIHNjYWxlX3hfbG9nMTAoKSArIGdlb21fcnVnKGNvbD1yZ2IoLjUsMCwwLGFscGhhPS4yKSkgICArIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvcmRlciA9IDIpLGNvbCA9IGd1aWRlX2xlZ2VuZChvcmRlciA9IDEpKQ0KDQoNCmMxOWRwXzINCg0KDQpgYGANCg==