Maps!
######
base_url <- "https://datacatalog.cookcountyil.gov/resource/tx2p-k2g9.json"
### Pulls from parcel universe online ###
nbh_pins <- GET(
base_url,
query = list(
tax_year = 2021,
# ward_num = 49,
# property_city = "ROGERS PARK",
`$select` = paste0(c("pin", "pin10",
"class",
"township_code", "township_name",
"nbhd_code", "census_puma_geoid",
"triad_name"
),
collapse = ","),
`$limit` = 500000000L
)
)
nbh_pins2 <- fromJSON(rawToChar(nbh_pins$content))
head(nbh_pins2)
######
### Pulls from PTAXSIM database downloaded on your computer ###
# There are 1,864,594 pins taxed by Cook County in 2021.
cook_pins <- DBI::dbGetQuery(
ptaxsim_db_conn,
glue_sql(
"SELECT DISTINCT pin, class, tax_code_num
FROM pin
WHERE tax_code_num IN ({cook_tax_codes$tax_code_num*})
AND year = 2021
",
.con = ptaxsim_db_conn
))
# finds all pins within a municipality
pin_data <- lookup_pin(2021, cook_pins$pin) %>%
left_join(cook_pins, by = c("pin", "class")) %>%
mutate(class_1dig = str_sub(class, 1, 1))
### Joins the neighborhood codes to the PINs with tax codes (matches by PIN and property class) ###
pin_data <- left_join(pin_data, nbh_pins2, by = c("pin", "class"))
pin_data <- pin_data %>%
# first 2 digits of the 5-digit neighborhood are for the township
mutate(township = str_sub(nbhd_code,1,2),
nbhd_3 = str_sub(nbhd_code, 3,5)) %>%
left_join(class_dict, by = c("class" = "class_code")) # add property class descriptions
pin_data %>% head()
# TC_MC_PC = tax code major class PIN count
TC_MC_sums <- pin_data %>%
group_by(tax_code_num, major_class_code) %>%
summarize(TC_MC_PC = n(),
TC_MC_AV = sum(av),
TC_MC_EAV = sum(eav),
Total_Exemptions = sum(exe_homeowner+exe_senior +exe_freeze + exe_longtime_homeowner +exe_disabled + exe_vet_returning + exe_vet_dis_lt50+ exe_vet_dis_50_69 + exe_vet_dis_ge70 + exe_abate, na.rm = TRUE),
GHE_only = sum(exe_homeowner, na.rm = TRUE),
)
TC_MC_sums <- right_join(cook_tax_codes, TC_MC_sums)
TC_MC_sums
TC_MC_sums %>% write_csv("./Output/7_TC_MC_summaries.csv")
incentive_pins <- parcel_data %>%
filter(class>599 & class < 900) %>%
mutate(pin10 = str_sub(pin,1, 10)) %>%
left_join(muni_tax_codes)
residential_pins <- parcel_data %>%
filter(class>199 & class < 300) %>%
mutate(pin10 = str_sub(pin,1, 10)) %>%
left_join(muni_tax_codes)
# PINs that have incentive property classes
# Have muni name, taxcodes, neighborhoods, etc. with PIN data
write_csv(incentive_pins, "./Output/7_output_incentive_pins.csv")
write_csv(residential_pins, "./Output/7_output_residential_pins.csv")
incentive_pins <- read_csv("./Output/7_output_incentive_classes.csv")
residential_pins <- read_csv("./Output/7_output_residential_pins.csv")
TC_MC_sums <- read_csv("./Output/7_TC_MC_summaries.csv")
#
# ### Class 8 Only ###
# table1 <- incentive_classes %>%
# filter(class > 799 & class < 900) %>%
# group_by(township_name, agency_name, major_class_code) %>%
# summarize(av = sum(av)) %>%
# pivot_wider(id_cols = c(township_name, agency_name),
# names_from = "major_class_code",
# values_from = "av") %>%
# rename(Class8_AV = `8`)
#
# table2 <- incentive_classes %>%
# filter(class > 799 & class < 900) %>%
# group_by(township_name, agency_name, major_class_code) %>%
# summarize(pincount = n()) %>%
# pivot_wider(id_cols = c(township_name, agency_name),
# names_from = "major_class_code",
# values_from = "pincount") %>%
# rename(Class8_pincount = `8`)
#
# ### Table of Incentive Class AV and PIN count for each Muni ###
# left_join(table1, table2)
#### Makes the Same thing as line 184-203!!!:
incentive_pins %>%
left_join(nicknames, by = "agency_name") %>%
reframe(Class8_PINcount = n(),
Class8_MuniAV = sum(av),
.by=c(clean_name)) %>%
rename(
Municipality = clean_name) %>%
mutate(Municipality = ifelse(is.na(Municipality), "Unincorporated", Municipality)) %>%
arrange(Municipality)
# incentive_classes %>%
# left_join(nicknames) %>%
# filter(class > 599 & class < 900) %>%
# group_by(township_name, clean_name, major_class_code) %>%
# summarize(pincount = n()) %>%
# pivot_wider(id_cols = c(township_name, clean_name),
# names_from = "major_class_code",
# values_from = "pincount") %>%
# select( Municipality = clean_name,
# Township = township_name,
# "6A", "6B", "6C", "7A", "7B", "8") %>%
# mutate(Municipality = ifelse(is.na(Municipality), "Unincorporated", Municipality)) %>%
# arrange(Municipality)
incentive_pins %>%
left_join(nicknames) %>%
filter(class > 599 & class < 900) %>%
group_by(clean_name, major_class_code) %>%
summarize(pincount = n()) %>%
pivot_wider(id_cols = clean_name,
names_from = "major_class_code",
values_from = "pincount") %>%
select( Municipality = clean_name,
"6A", "6B", "6C", "7A", "7B", "8") %>%
mutate(Municipality = ifelse(is.na(Municipality), "Unincorporated", Municipality)) %>%
arrange(Municipality)
residential_pins %>%
left_join(nicknames) %>%
reframe(
Class2_PINcount = n(),
Class2_MuniAV = sum(av),
Total_Exemptions = sum(exe_homeowner+exe_senior +exe_freeze + exe_longtime_homeowner +exe_disabled + exe_vet_returning + exe_vet_dis_lt50+ exe_vet_dis_50_69 + exe_vet_dis_ge70 + exe_abate, na.rm = TRUE),
GHE = sum(exe_homeowner, na.rm = TRUE),
.by=c(clean_name)) %>%
rename(
Municipality = clean_name) %>%
mutate(Municipality = ifelse(is.na(Municipality), "Unincorporated", Municipality)) %>%
arrange(Municipality)
nbh_pincounts <- incentive_pins %>%
group_by(nbhd_code, class) %>%
dplyr::summarize(pin_count = n(),
av = sum(av)) %>%
mutate(class_1dig = str_sub(class, 1, 1))
nbh_pincounts_majorclass <- incentive_pins %>%
group_by(major_class_code, major_class_type, nbhd_code) %>%
dplyr::summarize(pin_count = n(),
av = sum(av))
# table(nbh_pincounts_majorclass$major_class_code)
incentives_props <- nbh_pincounts_majorclass %>%
filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8", "9")) %>%
mutate(nbhd_code = as.character(nbhd_code))
fig_nbhd_pincount <- incentives_props %>%
group_by(nbhd_code) %>%
summarize(pin_count = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Number of PINs with Incentives in Assessor Neighborhoods",
caption = "Count of 14 digit PINs") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
show.limits=TRUE,
nice.breaks = TRUE,
na.value = NA,
name = "Pin Count")
fig_nbhd_AV <- incentives_props %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name != "City") %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Assessed Value of Properties in
Assessor Neighborhoods",
caption = "Different classes of properties have different assessment levels.
Some change over time.") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
show.limits=TRUE,
nice.breaks = FALSE,
# limits = c(0, 90000000),
na.value = NA,
name = "AV",
label = scales::dollar)
fig_nbhd_Chicago_AV <- incentives_props %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name == "City") %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Assessed Value of Properties in
Assessor Neighborhoods",
caption = "Different classes of properties have different assessment levels.
Some change over time.") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
show.limits=TRUE,
nice.breaks = FALSE,
# limits = c(0, 90000000),
na.value = NA,
name = "AV",
label = scales::dollar)
fig_nbhd_Chicago_AV

nbh_pincounts_class <- incentive_pins %>%
group_by(nbhd_code, class) %>%
dplyr::summarize(pin_count = n(),
av = sum(av)) %>%
mutate(class_1dig = str_sub(class, 1, 1))
nbh_pincounts_majorclass <- incentive_pins %>%
group_by(major_class_code, major_class_type, nbhd_code) %>%
dplyr::summarize(pin_count = n(),
av = sum(av))
# table(nbh_pincounts_majorclass$major_class_code)
incentives_props <- nbh_pincounts_majorclass %>%
filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8")) %>%
mutate(nbhd_code = as.character(nbhd_code))
fig_nbhd_C7AV <- incentives_props %>%
filter(major_class_code %in% c("7A", "7B", "7C") ) %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name != "City") %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 7 Properties - Assessed Value",
subtitle = "AV of Buildings with Incentives in Assessor Neighborhoods",
caption = "Over $90 million in Chicago") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_nbhd_C7_Chicago_AV <- incentives_props %>%
filter(major_class_code %in% c("7A", "7B", "7C") ) %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name == "City") %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 7 Properties - Assessed Value",
subtitle = "AV of Buildings with Incentives in Assessor Neighborhoods",
caption = "Over $90 million in Chicago") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_nbhd_C7_PC <- incentives_props %>%
filter(major_class_code %in% c("7A", "7B", "7C") ) %>%
group_by(nbhd_code) %>%
summarize(pincount = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name != "City") %>%
ggplot(aes(fill = pincount)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 7 Properties",
subtitle = "# of Buildings with Class 7 Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
show.limits=TRUE,
na.value = NA,
name = "Pin Count")
fig_nbhd_C7_Chicago_PC <- incentives_props %>%
filter(major_class_code %in% c("7A", "7B", "7C") ) %>%
group_by(nbhd_code) %>%
summarize(pincount = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name == "City") %>%
ggplot(aes(fill = pincount)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 7 Properties in Chicago",
subtitle = "# of Buildings with Class 7 Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
show.limits=TRUE,
na.value = NA,
name = "Pin Count")
fig_nbhd_C6_AV <- incentives_props %>%
filter(major_class_code %in% c("6A", "6B", "6C") ) %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 6 Properties",
subtitle = "AV of Buildings with Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_nbhd_C6_Chicago_AV <- incentives_props %>%
filter(major_class_code %in% c("6A", "6B", "6C") ) %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name == "City") %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 6 Properties",
subtitle = "AV of Buildings with Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_nbhd_C6_PC <- incentives_props %>%
filter(major_class_code %in% c("6A", "6B", "6C") ) %>%
group_by(nbhd_code) %>%
summarize(pin_count= round(sum(pin_count)), digits = 0) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 6 Properties",
subtitle = "# of Buildings with Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "Pin Count")
fig_nbhd_C6_Chicago_PC <- incentives_props %>%
filter(major_class_code %in% c("6A", "6B", "6C") ) %>%
group_by(nbhd_code) %>%
summarize(pin_count= round(sum(pin_count)), digits = 0) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
filter(triad_name == "City") %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Class 6 Properties",
subtitle = "# of Buildings with Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "Pin Count")
All Incentive Types Together
# Add in names that merge with Muni shapefile names
muni_pincounts_majorclass <- incentive_pins %>%
left_join(nicknames) %>%
group_by(clean_name, major_class_code, major_class_type, agency_name, shpfile_name) %>%
dplyr::summarize(pin_count = n(),
av = sum(av))
# table(muni_pincounts_majorclass$major_class_code) # Number of Munis with these major classes
fig_muni_AV <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8")) %>%
filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(av = sum(av)) %>%
filter(!is.na(shpfile_name) ) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Any Type of Incentive Class",
subtitle = "AV of Buildings with Incentives in Municipalities (Except Chicago).
Chicago has around $500 million in AV from properties with incentives.") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
# nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
limits = c(0, 90000000),
name = "AV ($)",
label = scales::dollar)
fig_muni_AV
fig_nbhd_AV
fig_muni_pincount <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8")) %>%
filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(pin_count = round(sum(pin_count)) ) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Incentive Clases",
subtitle = "# of Buildings with Incentives in Municipalities (Except Chicago)") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
# nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "# PINs")
fig_muni_pincount
fig_nbhd_pincount


Class 6 Incentives
Class 6A: Industrial Incentive
Class 6B: Industrial Incentive - Designed to encourage industrial
development throughout Cook County by offering a real estate tax
incentive for the development of new industrial facilities, the
rehabilitation of existing industrial structures, and the industrial
reutilization of abandoned buildings.
Class 6C: Industrial Brownfield
fig_muni_C6_AV <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("6A", "6B", "6C")) %>%
filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(av = sum(av)) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Class 6 Incentives",
subtitle = "Assessed Value in Municipalities (Except Chicago)") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
# nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_muni_C6_PC <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("6A", "6B", "6C")) %>%
# filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(pin_count = sum(pin_count)) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Class 6 Incentives",
subtitle = "# of Buildings with Incentives in Municipalities") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "# PINs")
fig_muni_C6_AV
fig_nbhd_C6_AV
fig_muni_C6_PC
fig_nbhd_C6_PC




Class 7 Incentives
Class 7A(B): Intended to encourage commercial projects in areas
determined to be “in need of commercial development.These projects have
total development costs, exclusive of land, that DO NOT EXCEED(DO
EXCEED) two million and would not be economically feasible without the
incentive.
fig_muni_C7_AV <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("7A", "7B", "7C")) %>%
filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(av = sum(av)) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Assessed Value of Properties with Class 7 Incentives",
subtitle = "in Municipalities (Except Chicago)") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_muni_C7_PC <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("7A", "7B", "7C")) %>%
filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(pin_count = sum(pin_count)) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Class 7 Incentives",
subtitle = "# of Buildings with Incentives in Municipalities (Except Chicago)") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
# nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "# PINs")
fig_muni_C7_AV
fig_nbhd_C7AV
fig_muni_C7_PC
fig_nbhd_C7_PC




Class 8 Incentives
Class 8: Designed to encourage industrial and commercial development
in areas of the county which are experiencing severe economic
stagnation.
Class 8 properties exist in places besides the 5 townships:
Bloom, Bremen, Calumet, Rich, Thornton
fig_nbhd_C8_PC <- incentives_props %>%
filter(major_class_code == "8") %>%
group_by(nbhd_code)%>%
summarize(pin_count = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Class 8 Properties",
subtitle = "Number of PINs with Incentives in Assessor Neighborhoods",
caption = "Count of 14 digit PINs") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "Count")
fig_nbhd_C8 <- incentives_props %>%
filter(major_class_code == "8") %>%
group_by(nbhd_code) %>%
summarize(av = sum(av)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
# color = "black",
lwd = .1) +
labs(title = "Class 8 Properties",
subtitle = "AV of Buildings with Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
limits = c(0, 13000000),
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_muni_C8_AV <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("8")) %>%
filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(av = sum(av)) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Class 8 Incentives",
subtitle = "# of Buildings with Incentives in Municipalities (Except Chicago)") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "AV ($)",
label = scales::dollar)
fig_muni_C8_PC <- muni_pincounts_majorclass %>%
filter(major_class_code %in% c("8")) %>%
# filter(clean_name != "Chicago") %>%
group_by(shpfile_name)%>%
summarize(pin_count = sum(pin_count)) %>%
filter(!is.na(shpfile_name)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = pin_count)) +
geom_sf(aes(geometry = geometry),
color = "black",
lwd = .05)+
labs(title = "Properties with Class 8 Incentives",
subtitle = "# of Buildings with Incentives in Municipalities") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
# nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "# PINs")
fig_muni_C8_PC
fig_nbhd_C8_PC


There are some Class 8 properties located in townships other than the
Class 8 five chosen for the incentives.
fig_muni_C8 <- muni_pincounts_majorclass %>%
filter(!is.na(shpfile_name)) %>%
filter(major_class_code %in% c("8")) %>%
group_by(shpfile_name)%>%
summarize(av = sum(av)) %>%
full_join(muni_shp, by = c("shpfile_name" = "MUNICIPALITY")) %>%
ggplot(aes(fill = av)) +
geom_sf(aes(geometry = geometry),color = "black", lwd = .05)+
labs(title = "Class 8 Properties",
subtitle = "AV of Buildings with Incentives in Assessor Neighborhoods") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "orange",
nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
limits = c(0, 13000000),
name = "AV ($)",
label = scales::dollar)
fig_muni_C8
fig_nbhd_C8


class8Townships = read_csv("./Output/3_Exemptions_Details_output-ClassTaxcodeExemps.csv") %>%
mutate(class_code = as.character(class_code)) %>%
filter(class_code >=800 & class_code <900) %>%
left_join(class_dict) %>%
mutate(tax_code_num = as.character(tax_code_num)) %>%
left_join(township_tax_codes) %>%
left_join(township_agency_names)%>%
distinct(agency_name)
class8Townships
Areas with lots of exemptions and incentives
aka a reduced tax base
Municpality Level
pin_data <- read_csv("./Output/4C_joined_PINs_bills_and_exemptions.csv")
muni_taxrates <- pin_data %>%
group_by(agency_name) %>%
summarize(
muni_av = sum(av, na.rm = TRUE),
muni_eav = sum(eav, na.rm = TRUE),
muni_equalized_AV = sum(equalized_AV, na.rm = TRUE),
pins_in_muni = n(),
muni_current_exemptions = sum(all_exemptions, na.rm = TRUE),
muni_HO_exemps = sum(exe_homeowner, na.rm = TRUE),
muni_comp_rate = mean(tax_code_rate, na.rm = TRUE), # Changed from first() to mean() on Nov 1
final_tax_to_dist = sum(final_tax_to_dist, na.rm = TRUE), # used as LEVY amount!!
final_tax_to_tif = sum(final_tax_to_tif, na.rm = TRUE),
tax_amt_exe = sum(tax_amt_exe, na.rm = TRUE),
tax_amt_pre_exe = sum(tax_amt_pre_exe, na.rm = TRUE),
tax_amt_post_exe = sum(tax_amt_post_exe, na.rm = TRUE),
# rpm_tif_to_cps = sum(rpm_tif_to_cps, na.rm = TRUE), # not used
# rpm_tif_to_rpm = sum(rpm_tif_to_rpm, na.rm=TRUE), # not used
# rpm_tif_to_dist = sum(rpm_tif_to_dist, na.rm=TRUE), # not used
# tif_share = mean(tif_share, na.rm=TRUE), # not used
) %>%
rename(cur_comp_TC_rate = muni_comp_rate) %>%
mutate(current_muni_taxable_eav = final_tax_to_dist/(cur_comp_TC_rate/100),
new_muni_taxable_eav = final_tax_to_dist/(cur_comp_TC_rate/100) + muni_HO_exemps) %>%
mutate(new_comp_TC_rate = (final_tax_to_dist / new_muni_taxable_eav)*100) %>%
mutate(new_comp_TC_rate = ifelse(is.nan(new_comp_TC_rate), cur_comp_TC_rate, new_comp_TC_rate)) %>%
select(agency_name, cur_comp_TC_rate, new_comp_TC_rate, current_muni_taxable_eav, new_muni_taxable_eav, everything())
muni_taxrates
prop_class_sums <- pin_data %>%
group_by(agency_name, major_class_code, major_class_type ) %>%
summarize(
av = sum(av, na.rm = TRUE),
eav = sum(eav, na.rm = TRUE),
equalized_AV = sum(equalized_AV, na.rm = TRUE),
pins_in_class = n(),
current_exemptions = sum(all_exemptions, na.rm = TRUE),
HO_exemps = sum(exe_homeowner, na.rm = TRUE),
tax_code_rate = mean(tax_code_rate, na.rm = TRUE), # Changed from first() to mean() on Nov 1
final_tax_to_dist = sum(final_tax_to_dist, na.rm = TRUE), # used as LEVY amount!!
final_tax_to_tif = sum(final_tax_to_tif, na.rm = TRUE),
tax_amt_exe = sum(tax_amt_exe, na.rm = TRUE),
tax_amt_pre_exe = sum(tax_amt_pre_exe, na.rm = TRUE),
tax_amt_post_exe = sum(tax_amt_post_exe, na.rm = TRUE),
rpm_tif_to_cps = sum(rpm_tif_to_cps, na.rm = TRUE), # not used
rpm_tif_to_rpm = sum(rpm_tif_to_rpm, na.rm=TRUE), # not used
rpm_tif_to_dist = sum(rpm_tif_to_dist, na.rm=TRUE), # not used
tif_share = mean(tif_share, na.rm=TRUE), # not used
) %>%
mutate(total_bill_current = final_tax_to_dist + final_tax_to_tif) %>%
rename(cur_comp_TC_rate = tax_code_rate) %>%
mutate(current_taxable_eav = final_tax_to_dist/(cur_comp_TC_rate/100),
new_taxable_eav = final_tax_to_dist/(cur_comp_TC_rate/100) + HO_exemps) %>%
mutate(new_comp_TC_rate = (final_tax_to_dist / new_taxable_eav)*100) %>%
mutate(new_comp_TC_rate = ifelse(is.nan(new_comp_TC_rate), cur_comp_TC_rate, new_comp_TC_rate)) %>%
select(agency_name, major_class_code, HO_exemps, current_exemptions, pins_in_class, current_taxable_eav, new_taxable_eav, everything())
# muni level by major_class summary
prop_class_sums
Neighborhood level join
nbh_major_class <- read_csv("./Output/8_Current_Taxrates_per_nbh_by_majorclass.csv")
nbh_major_class
# neighborhoods with incentive properties
incentives_props <- nbh_major_class %>%
filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8")) %>%
mutate(nbhd_code = as.character(nbhd_code))
#
# nbh_pincounts_class <- incentive_classes %>%
# group_by(nbhd_code, class) %>%
# dplyr::summarize(pin_count = n(),
# av = sum(av)) %>%
# mutate(class_1dig = str_sub(class, 1, 1))
#
# nbh_pincounts_majorclass <- incentive_classes %>%
# group_by(major_class_code, major_class_type, nbhd_code) %>%
# dplyr::summarize(pin_count = n(),
# av = sum(av))
# nbh_res_exemptions <- read_csv("./Output/8_nbh_sum_new_exe.csv")
nbh_taxrates <- read_csv( "./Output/8_Current_Taxrates_per_nbh.csv")
nbh_data <- left_join(nbh_pincounts_majorclass, nbh_taxrates, by = "nbhd_code")
nbh_data <- nbh_data %>%
rename(all_PINs = pin_count.x,
nbh_pins = pin_count.y) %>%
mutate(exempt_over_total_EAV = Exempt_EAV / Total_EAV,
nbhd_code = as.character(nbhd_code),
exempts_perPIN = Exempt_EAV / nbh_PINs,
incentive_projects_pct = incentive_PINs / nbh_PINs,
incentives_EAV = av * 3.0027 ,
incentives_over_total_EAV = incentives_EAV / Total_EAV) %>%
select(nbhd_code, exempt_over_total_EAV, nbh_PINs, major_class_PINs, exempts_perPIN, incentive_projects_pct, incentives_EAV, incentives_over_total_EAV, major_class_code, everything()) %>% arrange(nbhd_code)
nbh_data
# nbh_res_exemptions <- read_csv("./Output/8_nbh_sum_new_exe.csv")
nbh_taxrates <- read_csv( "./Output/8_Current_Taxrates_per_nbh.csv") %>% select(nbhd_code, pin_count, Total_EAV)
nbh_data <- left_join(nbh_major_class, nbh_taxrates, by = "nbhd_code")
nbh_data <- nbh_data %>%
rename(major_class_PINs = pin_count.x,
nbh_PINs = pin_count.y) %>%
mutate(exempt_over_total_EAV = round(Exempt_EAV / Total_EAV.y, digits = 4),
nbhd_code = as.character(nbhd_code),
exempts_perPIN = round(Exempt_EAV / nbh_PINs, digits = 0),
class_PIN_pct = major_class_PINs / nbh_PINs,
#class_EAV = round(av * 3.0027, digits = 0),
class_over_total_EAV = Total_EAV.x / Total_EAV.y) %>%
select(nbhd_code, major_class_code, exempt_over_total_EAV, nbh_PINs, major_class_PINs, exempts_perPIN, class_PIN_pct, Total_EAV.x, class_over_total_EAV, everything()) %>%
arrange(nbhd_code)
nbh_data
nbh_res <- nbh_data %>%
filter(major_class_code == 2) %>%
select(nbhd_code, major_class_code,
residential_PC = major_class_PINs,
res_EAV = Total_EAV.x,
res_exemptions = Exempt_EAV) %>%
mutate(nbhd_code = as.character(nbhd_code),
res_exe_per_res_pin = round(res_exemptions / residential_PC)
)
#nbh_data2 <- nbh_data %>% left_join(nbh_res, by = "nbhd_code") %>% select(nbhd_code, all_PINs, residential_PC, incentive_PINs, everything()) %>% mutate(exemps_per_resPIN = res_exemptions / residential_PC) %>% arrange(nbhd_code)
fig4 <- nbh_res %>%
filter(major_class_code == 2) %>%
filter(residential_PC > 4) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = res_exe_per_res_pin)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Average exemptions per Residential Class 2 PIN") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "white",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "Exemptions per PIN")
fig4

Maps
fig1 <- nbh_data %>%
filter(major_class_code == 2) %>%
#filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8")) %>%
#group_by(nbhd_code)%>%
#summarize(pin_count = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = exempt_over_total_EAV)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Exempt EAV (from Residential Exemptons) / Total EAV",
# caption = "Total EAV includes TIF and all EAV before exemptions are deducted"
) +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "forestgreen", low = "white",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "% Exempt")
fig1

fig3 <- nbh_data %>%
filter(major_class_code %in% c("6A", "6B", "6C", "7A", "7B", "8")) %>%
group_by(nbhd_code)%>%
summarize(incentives_over_total_EAV = sum(Total_EAV.x/Total_EAV.y) ) %>%
#summarize(pin_count = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = incentives_over_total_EAV)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "EAV of incentive properties / Total EAV") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "orange", low = "yellow",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "%")
fig3

fig2 <- nbh_data %>%
filter(major_class_code == "2") %>%
#group_by(nbhd_code)%>%
#summarize(pin_count = sum(pin_count)) %>%
full_join(NBHs, by = c("nbhd_code" = "town_nbhd")) %>%
ggplot(aes(fill = exempts_perPIN)) +
geom_sf(aes(geometry = geometry), color = "black") +
labs(title = "Average exemptions per PIN") +
theme_void() +
theme(axis.ticks = element_blank(), axis.text = element_blank()) +
scale_fill_steps2(
high = "darkblue", low = "white",
#nice.breaks = FALSE,
show.limits=TRUE,
na.value = NA,
name = "Exemptions per PIN")
fig2

LS0tDQp0aXRsZTogIkluY2VudGl2ZSBQcm9wZXJ0aWVzIGluIENvb2sgQ291bnR5LCBJTCINCmF1dGhvcjogIkFXTSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShwdGF4c2ltKQ0KbGlicmFyeShEQkkpDQpsaWJyYXJ5KGh0dHIpDQpsaWJyYXJ5KGpzb25saXRlKQ0KbGlicmFyeShnbHVlKQ0KbGlicmFyeShzZikNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KDQoNCg0KcHRheHNpbV9kYl9jb25uIDwtIERCSTo6ZGJDb25uZWN0KFJTUUxpdGU6OlNRTGl0ZSgpLCAiLi9wdGF4c2ltLmRiL3B0YXhzaW0tMjAyMS4wLjQuZGIiKQ0KDQojIGxpbmsgdG8gdGhlIEFQSSBvdXRwdXQgYXMgYSBKU09OIGZpbGUNCm11bmlfc2hwIDwtIHJlYWRfc2YoImh0dHBzOi8vZ2lzLmNvb2tjb3VudHlpbC5nb3YvdHJhZGl0aW9uYWwvcmVzdC9zZXJ2aWNlcy9wb2xpdGljYWxCb3VuZGFyeS9NYXBTZXJ2ZXIvMi9xdWVyeT9vdXRGaWVsZHM9KiZ3aGVyZT0xJTNEMSZmPWdlb2pzb24iKQ0KDQojbXVuaV9zaHAgPC0gcmVhZF9qc29uKCJtdW5pX3NocC5qc29uIikNCm5pY2tuYW1lcyA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi4vTmVjZXNzYXJ5X0ZpbGVzL211bmlfc2hvcnRuYW1lcy54bHN4IikNCg0KY2xhc3NfZGljdCA8LSByZWFkX2NzdigiLi9OZWNlc3NhcnlfRmlsZXMvY2xhc3NfZGljdF9leHBhbmRlZC5jc3YiKSAlPiUgDQogIG11dGF0ZShjbGFzc19jb2RlID0gYXMuY2hhcmFjdGVyKGNsYXNzX2NvZGUpKQ0KDQpOQkhzIDwtIHJlYWRfc2YoImh0dHBzOi8vZGF0YWNhdGFsb2cuY29va2NvdW50eWlsLmdvdi9yZXNvdXJjZS9wY2R3LXB4dGcuZ2VvanNvbiIpDQoNCg0KDQojIGhhcyBFQVYgdmFsdWVzLCBleHRlbnNpb25zIGJ5IGFnZW5jeV9udW0NCmFnZW5jeV9kdCA8LSBEQkk6OmRiR2V0UXVlcnkoDQogIHB0YXhzaW1fZGJfY29ubiwNCiAgIlNFTEVDVCAqDQogIEZST00gYWdlbmN5DQogIFdIRVJFIHllYXIgPSAyMDIxDQogICINCikNCg0KY29va19hZ2VuY3lfbmFtZXMgPC0gREJJOjpkYkdldFF1ZXJ5KA0KICBwdGF4c2ltX2RiX2Nvbm4sDQogICJTRUxFQ1QgRElTVElOQ1QgYWdlbmN5X251bSwgYWdlbmN5X25hbWUNCiAgRlJPTSBhZ2VuY3lfaW5mbw0KICAiDQopDQoNCiANCg0KDQojIGhhcyBhbGwgdGF4IGNvZGVzIGFuZCB0aGUgdGF4aW5nIGFnZW5jeSB0aGF0IHRheGVzIHRoZW0uIFRheCBjb2RlIHJhdGVzIGFuZCBhZ2VuY3kgcmF0ZXMuIA0KY29va190YXhfY29kZXMgPC0gREJJOjpkYkdldFF1ZXJ5KA0KICBwdGF4c2ltX2RiX2Nvbm4sDQogIGdsdWVfc3FsKCINCiAgU0VMRUNUIERJU1RJTkNUIHRheF9jb2RlX251bSwgdGF4X2NvZGVfcmF0ZQ0KICBGUk9NIHRheF9jb2RlDQogIFdIRVJFIGFnZW5jeV9udW0gSU4gKHtjb29rX2FnZW5jeV9uYW1lcyRhZ2VuY3lfbnVtKn0pDQogIEFORCB5ZWFyID0gMjAyMQ0KICAiLA0KICAuY29uID0gcHRheHNpbV9kYl9jb25uDQogICkNCikNCg0KDQptdW5pX2FnZW5jeV9uYW1lcyA8LSBEQkk6OmRiR2V0UXVlcnkoDQogIHB0YXhzaW1fZGJfY29ubiwNCiAgIlNFTEVDVCBESVNUSU5DVCBhZ2VuY3lfbnVtLCBhZ2VuY3lfbmFtZSwgbWlub3JfdHlwZQ0KICBGUk9NIGFnZW5jeV9pbmZvDQogIFdIRVJFIG1pbm9yX3R5cGUgPSAnTVVOSScNCiAgT1IgYWdlbmN5X251bSA9ICcwMjAwNjAwMDAnICANCg0KICAiDQopDQoNCm11bmlfdGF4X2NvZGVzIDwtIERCSTo6ZGJHZXRRdWVyeSgNCiAgcHRheHNpbV9kYl9jb25uLA0KICBnbHVlX3NxbCgiDQogIFNFTEVDVCBhZ2VuY3lfbnVtLCB0YXhfY29kZV9udW0sIHRheF9jb2RlX3JhdGUNCiAgRlJPTSB0YXhfY29kZQ0KICBXSEVSRSBhZ2VuY3lfbnVtIElOICh7bXVuaV9hZ2VuY3lfbmFtZXMkYWdlbmN5X251bSp9KQ0KICBBTkQgeWVhciA9IDIwMjENCiAgIiwNCiAgLmNvbiA9IHB0YXhzaW1fZGJfY29ubg0KICApDQopDQoNCm11bmlfdGF4X2NvZGVzIDwtIG11bmlfdGF4X2NvZGVzICU+JSBsZWZ0X2pvaW4obXVuaV9hZ2VuY3lfbmFtZXMpDQoNCmBgYA0KDQojIE1hcHMhDQoNCjwhLS1Bc3Nlc3NvciBuZWlnaGJvcmhvb2RzIGFyZSA1IGRpZ2l0czogZmlyc3QgMiBmb3IgdGhlIHRvd25zaGlwLCBsYXN0IDMgYXJlIGZvciB0aGUgbmVpZ2hib3Job29kIHdpdGhpbiB0aGUgdG93bnNoaXAuIFRoZXNlIGRvIG5vdCByZXNlbWJsZSB0aGUgbmVpZ2hib3Job29kcyB0aGF0IG1hbnkgb2YgdXMgbWF5IHRoaW5rIG9mIGJ1dCBhcmUgaW5zdGVhZCBvZiBncm91cHMgb2YgcHJvcGVydGllcyB3aXRoIHNpbWlsYXIgY2hhcmFjdGVyaXN0aWNzICoqKHRoYXQgYXJlIHRheGVkIGluIHNpbWlsYXIgcmF0ZXM/IGRvdWJsZSBjaGVjaykqKi0tPg0KDQo8IS0tUHVsbCBwaW5zLCBuZWlnaGJvcmhvb2QgY29kZXMsIHByb3BlcnR5IGNsYXNzLCBhc3Nlc3NtZW50IHRyaWFkLCBhbmQgb3RoZXIgdmFyaWFibGVzIGZyb20gUGFyY2VsIFVuaXZlcnNlIHVzaW5nIHRoZSBHRVQoKSBjb21tYW5kLiBQdWxscyBkYXRhIGZyb20gb25saW5lIEFQSSwgbm90IFBUQVhTSU0gZGF0YWJhc2UuIEkgYW0gdXNpbmcgdGhpcyBpbnN0ZWFkIG9mIFBUQVhTSU0gYmVjYXVzZSBuZWlnaGJvcmhvb2QgY29kZXMgYXJlIG5vdCBpbmNsdWRlZCBpbiBQVEFYU0lNIHRhYmxlczogVGF4IGNvZGVzIGFyZSB0aGUgc21hbGxlc3QgdW5pdCBvZiBtZWFzdXJlbWVudC4gKipOT1RFOiBUYXggY29kZXMgYW5kIG5laWdoYm9yaG9vZHMgZG8gbm90IHNoYXJlIGJvcmRlcnMgYW5kIHRheCBjb2RlcyBtYXkgbm90IHJlcHJlc2VudCBhIGNvbnRpbnVvdXMgYXJlYSBvZiBsYW5kLiAgKiotLT4NCg0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KIyMjIyMjDQpiYXNlX3VybCA8LSAiaHR0cHM6Ly9kYXRhY2F0YWxvZy5jb29rY291bnR5aWwuZ292L3Jlc291cmNlL3R4MnAtazJnOS5qc29uIg0KDQoNCg0KIyMjIFB1bGxzIGZyb20gcGFyY2VsIHVuaXZlcnNlIG9ubGluZSAjIyMgDQpuYmhfcGlucyA8LSBHRVQoDQogIGJhc2VfdXJsLA0KICBxdWVyeSA9IGxpc3QoDQogICAgdGF4X3llYXIgPSAyMDIxLA0KICMgICB3YXJkX251bSA9IDQ5LA0KICAgIyBwcm9wZXJ0eV9jaXR5ID0gIlJPR0VSUyBQQVJLIiwNCiAgICBgJHNlbGVjdGAgPSBwYXN0ZTAoYygicGluIiwgInBpbjEwIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgImNsYXNzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgInRvd25zaGlwX2NvZGUiLCAidG93bnNoaXBfbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIm5iaGRfY29kZSIsICJjZW5zdXNfcHVtYV9nZW9pZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgInRyaWFkX25hbWUiIA0KICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICBjb2xsYXBzZSA9ICIsIiksDQogICBgJGxpbWl0YCA9IDUwMDAwMDAwMEwNCiAgKQ0KKQ0KDQpuYmhfcGluczIgPC0gZnJvbUpTT04ocmF3VG9DaGFyKG5iaF9waW5zJGNvbnRlbnQpKQ0KaGVhZChuYmhfcGluczIpDQoNCg0KDQoNCiMjIyMjIw0KIyMjIFB1bGxzIGZyb20gUFRBWFNJTSBkYXRhYmFzZSBkb3dubG9hZGVkIG9uIHlvdXIgY29tcHV0ZXIgIyMjIA0KDQojIFRoZXJlIGFyZSAxLDg2NCw1OTQgcGlucyB0YXhlZCBieSBDb29rIENvdW50eSBpbiAyMDIxLg0KY29va19waW5zIDwtIERCSTo6ZGJHZXRRdWVyeSgNCiAgcHRheHNpbV9kYl9jb25uLA0KICBnbHVlX3NxbCgNCiAgIlNFTEVDVCBESVNUSU5DVCBwaW4sIGNsYXNzLCB0YXhfY29kZV9udW0NCiAgRlJPTSBwaW4NCiAgV0hFUkUgdGF4X2NvZGVfbnVtIElOICh7Y29va190YXhfY29kZXMkdGF4X2NvZGVfbnVtKn0pDQogIEFORCB5ZWFyID0gMjAyMQ0KICAiLA0KICAuY29uID0gcHRheHNpbV9kYl9jb25uDQopKQ0KDQojIGZpbmRzIGFsbCBwaW5zIHdpdGhpbiBhIG11bmljaXBhbGl0eQ0KcGluX2RhdGEgPC0gbG9va3VwX3BpbigyMDIxLCBjb29rX3BpbnMkcGluKSAlPiUNCiAgbGVmdF9qb2luKGNvb2tfcGlucywgYnkgPSBjKCJwaW4iLCAiY2xhc3MiKSkgJT4lIA0KICBtdXRhdGUoY2xhc3NfMWRpZyA9IHN0cl9zdWIoY2xhc3MsIDEsIDEpKQ0KDQojIyMgSm9pbnMgdGhlIG5laWdoYm9yaG9vZCBjb2RlcyB0byB0aGUgUElOcyB3aXRoIHRheCBjb2RlcyAobWF0Y2hlcyBieSBQSU4gYW5kIHByb3BlcnR5IGNsYXNzKSAjIyMNCnBpbl9kYXRhIDwtIGxlZnRfam9pbihwaW5fZGF0YSwgbmJoX3BpbnMyLCBieSA9IGMoInBpbiIsICJjbGFzcyIpKQ0KDQpwaW5fZGF0YSA8LSBwaW5fZGF0YSAlPiUgDQogICMgZmlyc3QgMiBkaWdpdHMgb2YgdGhlIDUtZGlnaXQgbmVpZ2hib3Job29kIGFyZSBmb3IgdGhlIHRvd25zaGlwDQogIG11dGF0ZSh0b3duc2hpcCA9IHN0cl9zdWIobmJoZF9jb2RlLDEsMiksDQogICAgICAgICBuYmhkXzMgPSBzdHJfc3ViKG5iaGRfY29kZSwgMyw1KSkgJT4lIA0KICBsZWZ0X2pvaW4oY2xhc3NfZGljdCwgYnkgPSBjKCJjbGFzcyIgPSAiY2xhc3NfY29kZSIpKSAjIGFkZCBwcm9wZXJ0eSBjbGFzcyBkZXNjcmlwdGlvbnMNCg0KcGluX2RhdGEgJT4lIGhlYWQoKQ0KDQojIFRDX01DX1BDID0gdGF4IGNvZGUgbWFqb3IgY2xhc3MgUElOIGNvdW50DQpUQ19NQ19zdW1zIDwtIHBpbl9kYXRhICU+JSANCiAgZ3JvdXBfYnkodGF4X2NvZGVfbnVtLCBtYWpvcl9jbGFzc19jb2RlKSAlPiUNCiAgc3VtbWFyaXplKFRDX01DX1BDID0gbigpLA0KICAgICAgICAgICAgVENfTUNfQVYgPSBzdW0oYXYpLA0KICAgICAgICAgICAgVENfTUNfRUFWID0gc3VtKGVhdiksDQogICAgICAgICAgICBUb3RhbF9FeGVtcHRpb25zID0gc3VtKGV4ZV9ob21lb3duZXIrZXhlX3NlbmlvciArZXhlX2ZyZWV6ZSArIGV4ZV9sb25ndGltZV9ob21lb3duZXIgK2V4ZV9kaXNhYmxlZCArIGV4ZV92ZXRfcmV0dXJuaW5nICsgZXhlX3ZldF9kaXNfbHQ1MCsgZXhlX3ZldF9kaXNfNTBfNjkgKyBleGVfdmV0X2Rpc19nZTcwICsgZXhlX2FiYXRlLCBuYS5ybSA9IFRSVUUpLA0KICAgIEdIRV9vbmx5ID0gc3VtKGV4ZV9ob21lb3duZXIsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICApDQpUQ19NQ19zdW1zIDwtIHJpZ2h0X2pvaW4oY29va190YXhfY29kZXMsIFRDX01DX3N1bXMpDQpUQ19NQ19zdW1zDQoNClRDX01DX3N1bXMgJT4lIHdyaXRlX2NzdigiLi9PdXRwdXQvN19UQ19NQ19zdW1tYXJpZXMuY3N2IikNCg0KaW5jZW50aXZlX3BpbnMgPC0gcGFyY2VsX2RhdGEgJT4lIA0KICBmaWx0ZXIoY2xhc3M+NTk5ICYgY2xhc3MgPCA5MDApICU+JSAgDQogIG11dGF0ZShwaW4xMCA9IHN0cl9zdWIocGluLDEsIDEwKSkgICU+JSANCiAgbGVmdF9qb2luKG11bmlfdGF4X2NvZGVzKQ0KDQpyZXNpZGVudGlhbF9waW5zIDwtIHBhcmNlbF9kYXRhICU+JSANCiAgZmlsdGVyKGNsYXNzPjE5OSAmIGNsYXNzIDwgMzAwKSAlPiUgIA0KICBtdXRhdGUocGluMTAgPSBzdHJfc3ViKHBpbiwxLCAxMCkpICAlPiUgDQogIGxlZnRfam9pbihtdW5pX3RheF9jb2RlcykNCg0KDQojIFBJTnMgdGhhdCBoYXZlIGluY2VudGl2ZSBwcm9wZXJ0eSBjbGFzc2VzDQojIEhhdmUgbXVuaSBuYW1lLCB0YXhjb2RlcywgbmVpZ2hib3Job29kcywgZXRjLiB3aXRoIFBJTiBkYXRhDQp3cml0ZV9jc3YoaW5jZW50aXZlX3BpbnMsICIuL091dHB1dC83X291dHB1dF9pbmNlbnRpdmVfcGlucy5jc3YiKQ0Kd3JpdGVfY3N2KHJlc2lkZW50aWFsX3BpbnMsICIuL091dHB1dC83X291dHB1dF9yZXNpZGVudGlhbF9waW5zLmNzdiIpDQpgYGANCg0KDQoNCmBgYHtyIH0NCmluY2VudGl2ZV9waW5zIDwtIHJlYWRfY3N2KCIuL091dHB1dC83X291dHB1dF9pbmNlbnRpdmVfY2xhc3Nlcy5jc3YiKQ0KDQpyZXNpZGVudGlhbF9waW5zIDwtIHJlYWRfY3N2KCIuL091dHB1dC83X291dHB1dF9yZXNpZGVudGlhbF9waW5zLmNzdiIpDQoNClRDX01DX3N1bXMgPC0gcmVhZF9jc3YoIi4vT3V0cHV0LzdfVENfTUNfc3VtbWFyaWVzLmNzdiIpDQojIA0KIyAjIyMgQ2xhc3MgOCBPbmx5ICMjIyANCiMgdGFibGUxIDwtIGluY2VudGl2ZV9jbGFzc2VzICU+JSANCiMgICBmaWx0ZXIoY2xhc3MgPiA3OTkgJiBjbGFzcyA8IDkwMCkgJT4lIA0KIyAgIGdyb3VwX2J5KHRvd25zaGlwX25hbWUsIGFnZW5jeV9uYW1lLCBtYWpvcl9jbGFzc19jb2RlKSAlPiUNCiMgICBzdW1tYXJpemUoYXYgPSBzdW0oYXYpKSAlPiUNCiMgICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyh0b3duc2hpcF9uYW1lLCBhZ2VuY3lfbmFtZSksIA0KIyAgICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSAibWFqb3JfY2xhc3NfY29kZSIsIA0KIyAgICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gImF2IikgJT4lDQojICAgcmVuYW1lKENsYXNzOF9BViA9IGA4YCkNCiMgDQojIHRhYmxlMiA8LSBpbmNlbnRpdmVfY2xhc3NlcyAlPiUgDQojICAgZmlsdGVyKGNsYXNzID4gNzk5ICYgY2xhc3MgPCA5MDApICU+JSANCiMgICBncm91cF9ieSh0b3duc2hpcF9uYW1lLCBhZ2VuY3lfbmFtZSwgbWFqb3JfY2xhc3NfY29kZSkgJT4lDQojICAgc3VtbWFyaXplKHBpbmNvdW50ID0gbigpKSAlPiUNCiMgICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyh0b3duc2hpcF9uYW1lLCBhZ2VuY3lfbmFtZSksIA0KIyAgICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSAibWFqb3JfY2xhc3NfY29kZSIsIA0KIyAgICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gInBpbmNvdW50IikgJT4lDQojICAgcmVuYW1lKENsYXNzOF9waW5jb3VudCA9IGA4YCkNCiMgDQojICMjIyBUYWJsZSBvZiBJbmNlbnRpdmUgQ2xhc3MgQVYgYW5kIFBJTiBjb3VudCBmb3IgZWFjaCBNdW5pICMjIyANCiMgbGVmdF9qb2luKHRhYmxlMSwgdGFibGUyKQ0KDQojIyMjIE1ha2VzIHRoZSBTYW1lIHRoaW5nIGFzIGxpbmUgMTg0LTIwMyEhIToNCmluY2VudGl2ZV9waW5zICU+JSANCiAgbGVmdF9qb2luKG5pY2tuYW1lcywgYnkgPSAiYWdlbmN5X25hbWUiKSAlPiUgDQogIHJlZnJhbWUoQ2xhc3M4X1BJTmNvdW50ID0gbigpLA0KICAgICAgICAgIENsYXNzOF9NdW5pQVYgPSBzdW0oYXYpLA0KICAgICAgICAgIC5ieT1jKGNsZWFuX25hbWUpKSAlPiUgDQogIHJlbmFtZSgNCiAgICAgICAgIE11bmljaXBhbGl0eSA9IGNsZWFuX25hbWUpICU+JQ0KICAgIG11dGF0ZShNdW5pY2lwYWxpdHkgPSBpZmVsc2UoaXMubmEoTXVuaWNpcGFsaXR5KSwgIlVuaW5jb3Jwb3JhdGVkIiwgTXVuaWNpcGFsaXR5KSkgJT4lDQogIGFycmFuZ2UoTXVuaWNpcGFsaXR5KQ0KDQoNCiMgaW5jZW50aXZlX2NsYXNzZXMgJT4lIA0KIyAgIGxlZnRfam9pbihuaWNrbmFtZXMpICU+JQ0KIyAgIGZpbHRlcihjbGFzcyA+IDU5OSAmIGNsYXNzIDwgOTAwKSAlPiUgDQojICAgZ3JvdXBfYnkodG93bnNoaXBfbmFtZSwgY2xlYW5fbmFtZSwgbWFqb3JfY2xhc3NfY29kZSkgJT4lDQojICAgc3VtbWFyaXplKHBpbmNvdW50ID0gbigpKSAlPiUNCiMgICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyh0b3duc2hpcF9uYW1lLCBjbGVhbl9uYW1lKSwgDQojICAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9ICJtYWpvcl9jbGFzc19jb2RlIiwgDQojICAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAicGluY291bnQiKSAlPiUNCiMgICBzZWxlY3QoIE11bmljaXBhbGl0eSA9IGNsZWFuX25hbWUsDQojICAgICAgICAgICBUb3duc2hpcCA9IHRvd25zaGlwX25hbWUsDQojICAgICAgICAgICAiNkEiLCAiNkIiLCAiNkMiLCAiN0EiLCAiN0IiLCAiOCIpICU+JSANCiMgICBtdXRhdGUoTXVuaWNpcGFsaXR5ID0gaWZlbHNlKGlzLm5hKE11bmljaXBhbGl0eSksICJVbmluY29ycG9yYXRlZCIsIE11bmljaXBhbGl0eSkpICU+JQ0KIyAgIGFycmFuZ2UoTXVuaWNpcGFsaXR5KQ0KDQppbmNlbnRpdmVfcGlucyAlPiUgDQogIGxlZnRfam9pbihuaWNrbmFtZXMpICU+JQ0KICBmaWx0ZXIoY2xhc3MgPiA1OTkgJiBjbGFzcyA8IDkwMCkgJT4lIA0KICBncm91cF9ieShjbGVhbl9uYW1lLCBtYWpvcl9jbGFzc19jb2RlKSAlPiUNCiAgc3VtbWFyaXplKHBpbmNvdW50ID0gbigpKSAlPiUNCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGNsZWFuX25hbWUsIA0KICAgICAgICAgICAgICBuYW1lc19mcm9tID0gIm1ham9yX2NsYXNzX2NvZGUiLCANCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAicGluY291bnQiKSAlPiUNCiAgc2VsZWN0KCBNdW5pY2lwYWxpdHkgPSBjbGVhbl9uYW1lLA0KICAgICAgICAgICI2QSIsICI2QiIsICI2QyIsICI3QSIsICI3QiIsICI4IikgJT4lIA0KICBtdXRhdGUoTXVuaWNpcGFsaXR5ID0gaWZlbHNlKGlzLm5hKE11bmljaXBhbGl0eSksICJVbmluY29ycG9yYXRlZCIsIE11bmljaXBhbGl0eSkpICU+JQ0KICBhcnJhbmdlKE11bmljaXBhbGl0eSkNCg0KYGBgDQoNCmBgYHtyfQ0KcmVzaWRlbnRpYWxfcGlucyAlPiUgDQogIGxlZnRfam9pbihuaWNrbmFtZXMpICU+JSANCiAgcmVmcmFtZSgNCiAgICBDbGFzczJfUElOY291bnQgPSBuKCksDQogICAgICAgICAgQ2xhc3MyX011bmlBViA9IHN1bShhdiksDQogICAgVG90YWxfRXhlbXB0aW9ucyA9IHN1bShleGVfaG9tZW93bmVyK2V4ZV9zZW5pb3IgK2V4ZV9mcmVlemUgKyBleGVfbG9uZ3RpbWVfaG9tZW93bmVyICtleGVfZGlzYWJsZWQgKyBleGVfdmV0X3JldHVybmluZyArIGV4ZV92ZXRfZGlzX2x0NTArIGV4ZV92ZXRfZGlzXzUwXzY5ICsgZXhlX3ZldF9kaXNfZ2U3MCArIGV4ZV9hYmF0ZSwgbmEucm0gPSBUUlVFKSwNCiAgICBHSEUgPSBzdW0oZXhlX2hvbWVvd25lciwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAuYnk9YyhjbGVhbl9uYW1lKSkgJT4lIA0KICByZW5hbWUoDQogICAgICAgICBNdW5pY2lwYWxpdHkgPSBjbGVhbl9uYW1lKSAlPiUNCiAgICBtdXRhdGUoTXVuaWNpcGFsaXR5ID0gaWZlbHNlKGlzLm5hKE11bmljaXBhbGl0eSksICJVbmluY29ycG9yYXRlZCIsIE11bmljaXBhbGl0eSkpICU+JQ0KICBhcnJhbmdlKE11bmljaXBhbGl0eSkNCmBgYA0KDQoNCmBgYHtyIG5iaGQtYWxsY2xhc3Nlc30NCm5iaF9waW5jb3VudHMgPC0gaW5jZW50aXZlX3BpbnMgJT4lIA0KICBncm91cF9ieShuYmhkX2NvZGUsIGNsYXNzKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShwaW5fY291bnQgPSBuKCksDQogICAgICAgICAgICBhdiA9IHN1bShhdikpICU+JQ0KICBtdXRhdGUoY2xhc3NfMWRpZyA9IHN0cl9zdWIoY2xhc3MsIDEsIDEpKQ0KDQpuYmhfcGluY291bnRzX21ham9yY2xhc3MgPC0gaW5jZW50aXZlX3BpbnMgJT4lIA0KICBncm91cF9ieShtYWpvcl9jbGFzc19jb2RlLCBtYWpvcl9jbGFzc190eXBlLCBuYmhkX2NvZGUpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXplKHBpbl9jb3VudCA9IG4oKSwNCiAgICAgICAgICAgIGF2ID0gc3VtKGF2KSkNCg0KIyB0YWJsZShuYmhfcGluY291bnRzX21ham9yY2xhc3MkbWFqb3JfY2xhc3NfY29kZSkNCg0KDQppbmNlbnRpdmVzX3Byb3BzIDwtIG5iaF9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiNkEiLCAiNkIiLCAiNkMiLCAiN0EiLCAiN0IiLCAiOCIsICI5IikpICU+JQ0KICBtdXRhdGUobmJoZF9jb2RlID0gYXMuY2hhcmFjdGVyKG5iaGRfY29kZSkpDQoNCg0KZmlnX25iaGRfcGluY291bnQgPC0gaW5jZW50aXZlc19wcm9wcyAlPiUgDQogIGdyb3VwX2J5KG5iaGRfY29kZSkgJT4lDQogIHN1bW1hcml6ZShwaW5fY291bnQgPSBzdW0ocGluX2NvdW50KSkgJT4lDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBwaW5fY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwgY29sb3IgPSAiYmxhY2siKSArIA0KICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiBQSU5zIHdpdGggSW5jZW50aXZlcyBpbiBBc3Nlc3NvciBOZWlnaGJvcmhvb2RzIiwgDQogIGNhcHRpb24gPSAiQ291bnQgb2YgMTQgZGlnaXQgUElOcyIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCnNjYWxlX2ZpbGxfc3RlcHMyKA0KICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogIHNob3cubGltaXRzPVRSVUUsDQogIG5pY2UuYnJlYWtzID0gVFJVRSwNCm5hLnZhbHVlID0gTkEsDQogIG5hbWUgPSAiUGluIENvdW50IikNCg0KDQpmaWdfbmJoZF9BViA8LSBpbmNlbnRpdmVzX3Byb3BzICU+JSANCiAgZ3JvdXBfYnkobmJoZF9jb2RlKSAlPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSkgJT4lDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICBmaWx0ZXIodHJpYWRfbmFtZSAhPSAiQ2l0eSIpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBhdikpICsgDQogIGdlb21fc2YoYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpLCBjb2xvciA9ICJibGFjayIpICsgDQogIGxhYnModGl0bGUgPSAiQXNzZXNzZWQgVmFsdWUgb2YgUHJvcGVydGllcyBpbiANCiAgICAgICBBc3Nlc3NvciBOZWlnaGJvcmhvb2RzIiwgDQogICAgICAgY2FwdGlvbiA9ICJEaWZmZXJlbnQgY2xhc3NlcyBvZiBwcm9wZXJ0aWVzIGhhdmUgZGlmZmVyZW50IGFzc2Vzc21lbnQgbGV2ZWxzLiANCiAgU29tZSBjaGFuZ2Ugb3ZlciB0aW1lLiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIyBsaW1pdHMgPSBjKDAsIDkwMDAwMDAwKSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiQVYiLA0KICAgIGxhYmVsID0gc2NhbGVzOjpkb2xsYXIpDQoNCg0KDQpmaWdfbmJoZF9DaGljYWdvX0FWIDwtIGluY2VudGl2ZXNfcHJvcHMgJT4lIA0KICBncm91cF9ieShuYmhkX2NvZGUpICU+JQ0KICBzdW1tYXJpemUoYXYgPSBzdW0oYXYpKSAlPiUNCiAgZnVsbF9qb2luKE5CSHMsIGJ5ID0gYygibmJoZF9jb2RlIiA9ICJ0b3duX25iaGQiKSkgJT4lDQogIGZpbHRlcih0cmlhZF9uYW1lID09ICJDaXR5IikgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGF2KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksIGNvbG9yID0gImJsYWNrIikgKyANCiAgbGFicyh0aXRsZSA9ICJBc3Nlc3NlZCBWYWx1ZSBvZiBQcm9wZXJ0aWVzIGluIA0KICAgICAgIEFzc2Vzc29yIE5laWdoYm9yaG9vZHMiLCANCiAgICAgICBjYXB0aW9uID0gIkRpZmZlcmVudCBjbGFzc2VzIG9mIHByb3BlcnRpZXMgaGF2ZSBkaWZmZXJlbnQgYXNzZXNzbWVudCBsZXZlbHMuIA0KICBTb21lIGNoYW5nZSBvdmVyIHRpbWUuIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHNjYWxlX2ZpbGxfc3RlcHMyKA0KICAgIGhpZ2ggPSAiZGFya2JsdWUiLCBsb3cgPSAib3JhbmdlIiwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5pY2UuYnJlYWtzID0gRkFMU0UsDQogICAjIGxpbWl0cyA9IGMoMCwgOTAwMDAwMDApLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICJBViIsDQogICAgbGFiZWwgPSBzY2FsZXM6OmRvbGxhcikNCg0KZmlnX25iaGRfQ2hpY2Fnb19BVg0KYGBgDQoNCmBgYHtyIG5oYmQtY2xhc3M2YW5kN30NCm5iaF9waW5jb3VudHNfY2xhc3MgPC0gaW5jZW50aXZlX3BpbnMgJT4lIA0KICBncm91cF9ieShuYmhkX2NvZGUsIGNsYXNzKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShwaW5fY291bnQgPSBuKCksDQogICAgICAgICAgICBhdiA9IHN1bShhdikpICU+JQ0KICBtdXRhdGUoY2xhc3NfMWRpZyA9IHN0cl9zdWIoY2xhc3MsIDEsIDEpKQ0KDQpuYmhfcGluY291bnRzX21ham9yY2xhc3MgPC0gaW5jZW50aXZlX3BpbnMgJT4lIA0KICBncm91cF9ieShtYWpvcl9jbGFzc19jb2RlLCBtYWpvcl9jbGFzc190eXBlLCBuYmhkX2NvZGUpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXplKHBpbl9jb3VudCA9IG4oKSwNCiAgICAgICAgICAgIGF2ID0gc3VtKGF2KSkNCg0KIyB0YWJsZShuYmhfcGluY291bnRzX21ham9yY2xhc3MkbWFqb3JfY2xhc3NfY29kZSkNCg0KDQppbmNlbnRpdmVzX3Byb3BzIDwtIG5iaF9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiNkEiLCAiNkIiLCAiNkMiLCAiN0EiLCAiN0IiLCAiOCIpKSAlPiUNCiAgbXV0YXRlKG5iaGRfY29kZSA9IGFzLmNoYXJhY3RlcihuYmhkX2NvZGUpKQ0KDQpmaWdfbmJoZF9DN0FWIDwtIGluY2VudGl2ZXNfcHJvcHMgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjdBIiwgIjdCIiwgIjdDIikgKSAlPiUgDQogIGdyb3VwX2J5KG5iaGRfY29kZSkgJT4lDQogIHN1bW1hcml6ZShhdiA9IHN1bShhdikpICU+JQ0KICBmdWxsX2pvaW4oTkJIcywgYnkgPSBjKCJuYmhkX2NvZGUiID0gInRvd25fbmJoZCIpKSAlPiUNCiAgZmlsdGVyKHRyaWFkX25hbWUgIT0gIkNpdHkiKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gYXYpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiQ2xhc3MgNyBQcm9wZXJ0aWVzIC0gQXNzZXNzZWQgVmFsdWUiLA0KICAgICAgIHN1YnRpdGxlID0gIkFWIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIsDQogICAgICAgY2FwdGlvbiA9ICJPdmVyICQ5MCBtaWxsaW9uIGluIENoaWNhZ28iKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJvcmFuZ2UiLA0KICAgIG5pY2UuYnJlYWtzID0gRkFMU0UsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiQVYgKCQpIiwNCiAgICBsYWJlbCA9IHNjYWxlczo6ZG9sbGFyKQ0KDQpmaWdfbmJoZF9DN19DaGljYWdvX0FWIDwtIGluY2VudGl2ZXNfcHJvcHMgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjdBIiwgIjdCIiwgIjdDIikgKSAlPiUgDQogIGdyb3VwX2J5KG5iaGRfY29kZSkgJT4lDQogIHN1bW1hcml6ZShhdiA9IHN1bShhdikpICU+JQ0KICBmdWxsX2pvaW4oTkJIcywgYnkgPSBjKCJuYmhkX2NvZGUiID0gInRvd25fbmJoZCIpKSAlPiUNCiAgZmlsdGVyKHRyaWFkX25hbWUgPT0gIkNpdHkiKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gYXYpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiQ2xhc3MgNyBQcm9wZXJ0aWVzIC0gQXNzZXNzZWQgVmFsdWUiLA0KICAgICAgIHN1YnRpdGxlID0gIkFWIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIsDQogICAgICAgY2FwdGlvbiA9ICJPdmVyICQ5MCBtaWxsaW9uIGluIENoaWNhZ28iKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJvcmFuZ2UiLA0KICAgIG5pY2UuYnJlYWtzID0gRkFMU0UsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiQVYgKCQpIiwNCiAgICBsYWJlbCA9IHNjYWxlczo6ZG9sbGFyKQ0KDQoNCg0KZmlnX25iaGRfQzdfUEMgPC0gaW5jZW50aXZlc19wcm9wcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiN0EiLCAiN0IiLCAiN0MiKSApICU+JQ0KICBncm91cF9ieShuYmhkX2NvZGUpICU+JQ0KICBzdW1tYXJpemUocGluY291bnQgPSBzdW0ocGluX2NvdW50KSkgJT4lIA0KICBmdWxsX2pvaW4oTkJIcywgYnkgPSBjKCJuYmhkX2NvZGUiID0gInRvd25fbmJoZCIpKSAlPiUNCiAgICBmaWx0ZXIodHJpYWRfbmFtZSAhPSAiQ2l0eSIpICU+JQ0KDQogIGdncGxvdChhZXMoZmlsbCA9IHBpbmNvdW50KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksDQogICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgIGx3ZCA9IC4wNSkrIA0KICBsYWJzKHRpdGxlID0gIkNsYXNzIDcgUHJvcGVydGllcyIsDQogICAgICAgc3VidGl0bGUgPSAiIyBvZiBCdWlsZGluZ3Mgd2l0aCBDbGFzcyA3IEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiUGluIENvdW50IikNCg0KZmlnX25iaGRfQzdfQ2hpY2Fnb19QQyA8LSBpbmNlbnRpdmVzX3Byb3BzICU+JSANCiAgZmlsdGVyKG1ham9yX2NsYXNzX2NvZGUgJWluJSBjKCI3QSIsICI3QiIsICI3QyIpICkgJT4lDQogIGdyb3VwX2J5KG5iaGRfY29kZSkgJT4lDQogIHN1bW1hcml6ZShwaW5jb3VudCA9IHN1bShwaW5fY291bnQpKSAlPiUgDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICAgIGZpbHRlcih0cmlhZF9uYW1lID09ICJDaXR5IikgJT4lDQoNCiAgZ2dwbG90KGFlcyhmaWxsID0gcGluY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiQ2xhc3MgNyBQcm9wZXJ0aWVzIGluIENoaWNhZ28iLA0KICAgICAgIHN1YnRpdGxlID0gIiMgb2YgQnVpbGRpbmdzIHdpdGggQ2xhc3MgNyBJbmNlbnRpdmVzIGluIEFzc2Vzc29yIE5laWdoYm9yaG9vZHMiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJvcmFuZ2UiLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIlBpbiBDb3VudCIpDQoNCmZpZ19uYmhkX0M2X0FWIDwtIGluY2VudGl2ZXNfcHJvcHMgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjZBIiwgIjZCIiwgIjZDIikgKSAlPiUNCiAgZ3JvdXBfYnkobmJoZF9jb2RlKSAlPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSkgJT4lDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBhdikpICsgDQogIGdlb21fc2YoYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpLA0KICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwNCiAgICAgICAgICBsd2QgPSAuMDUpKyANCiAgbGFicyh0aXRsZSA9ICJDbGFzcyA2IFByb3BlcnRpZXMiLA0KICAgICAgIHN1YnRpdGxlID0gIkFWIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICJBViAoJCkiLA0KICAgIGxhYmVsID0gc2NhbGVzOjpkb2xsYXIpDQoNCmZpZ19uYmhkX0M2X0NoaWNhZ29fQVYgPC0gaW5jZW50aXZlc19wcm9wcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiNkEiLCAiNkIiLCAiNkMiKSApICU+JQ0KICBncm91cF9ieShuYmhkX2NvZGUpICU+JQ0KICBzdW1tYXJpemUoYXYgPSBzdW0oYXYpKSAlPiUNCiAgZnVsbF9qb2luKE5CSHMsIGJ5ID0gYygibmJoZF9jb2RlIiA9ICJ0b3duX25iaGQiKSkgJT4lDQogIGZpbHRlcih0cmlhZF9uYW1lID09ICJDaXR5IikgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGF2KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksDQogICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgIGx3ZCA9IC4wNSkrIA0KICBsYWJzKHRpdGxlID0gIkNsYXNzIDYgUHJvcGVydGllcyIsDQogICAgICAgc3VidGl0bGUgPSAiQVYgb2YgQnVpbGRpbmdzIHdpdGggSW5jZW50aXZlcyBpbiBBc3Nlc3NvciBOZWlnaGJvcmhvb2RzIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHNjYWxlX2ZpbGxfc3RlcHMyKA0KICAgIGhpZ2ggPSAiZGFya2JsdWUiLCBsb3cgPSAib3JhbmdlIiwNCiAgICBuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIkFWICgkKSIsDQogICAgbGFiZWwgPSBzY2FsZXM6OmRvbGxhcikNCiAgDQpmaWdfbmJoZF9DNl9QQyA8LSBpbmNlbnRpdmVzX3Byb3BzICU+JSANCiAgZmlsdGVyKG1ham9yX2NsYXNzX2NvZGUgJWluJSBjKCI2QSIsICI2QiIsICI2QyIpICkgJT4lDQogIGdyb3VwX2J5KG5iaGRfY29kZSkgJT4lDQogIHN1bW1hcml6ZShwaW5fY291bnQ9IHJvdW5kKHN1bShwaW5fY291bnQpKSwgZGlnaXRzID0gMCkgJT4lDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBwaW5fY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiQ2xhc3MgNiBQcm9wZXJ0aWVzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIjIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgI25pY2UuYnJlYWtzID0gRkFMU0UsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiUGluIENvdW50IikNCg0KZmlnX25iaGRfQzZfQ2hpY2Fnb19QQyA8LSBpbmNlbnRpdmVzX3Byb3BzICU+JSANCiAgZmlsdGVyKG1ham9yX2NsYXNzX2NvZGUgJWluJSBjKCI2QSIsICI2QiIsICI2QyIpICkgJT4lDQogIGdyb3VwX2J5KG5iaGRfY29kZSkgJT4lDQogIHN1bW1hcml6ZShwaW5fY291bnQ9IHJvdW5kKHN1bShwaW5fY291bnQpKSwgZGlnaXRzID0gMCkgJT4lDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICBmaWx0ZXIodHJpYWRfbmFtZSA9PSAiQ2l0eSIpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBwaW5fY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiQ2xhc3MgNiBQcm9wZXJ0aWVzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIjIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgI25pY2UuYnJlYWtzID0gRkFMU0UsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiUGluIENvdW50IikNCmBgYA0KDQoNCg0KIyMgQWxsIEluY2VudGl2ZSBUeXBlcyBUb2dldGhlcg0KDQpgYGB7ciBtdW5pLWFsbHRvZ2V0aGVyLCBvdXQud2lkdGg9ICI1MCUiLCBmaWcuc2hvdz0naG9sZCcsIGZpZy5jYXA9ICJBbGwgSW5jZW50aXZlIFByb3BlcnR5IENsYXNzZXM6IE11bmljaXBhbGl0eSBsZXZlbCBhbmQgQXNzZXNzb3IgTmVpZ2hib3Job29kIGxldmVsIn0NCg0KDQojIEFkZCBpbiBuYW1lcyB0aGF0IG1lcmdlIHdpdGggTXVuaSBzaGFwZWZpbGUgbmFtZXMNCm11bmlfcGluY291bnRzX21ham9yY2xhc3MgPC0gaW5jZW50aXZlX3BpbnMgJT4lIA0KICBsZWZ0X2pvaW4obmlja25hbWVzKSAlPiUNCiAgZ3JvdXBfYnkoY2xlYW5fbmFtZSwgbWFqb3JfY2xhc3NfY29kZSwgbWFqb3JfY2xhc3NfdHlwZSwgYWdlbmN5X25hbWUsIHNocGZpbGVfbmFtZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUocGluX2NvdW50ID0gbigpLA0KICAgICAgICAgICAgYXYgPSBzdW0oYXYpKQ0KDQojIHRhYmxlKG11bmlfcGluY291bnRzX21ham9yY2xhc3MkbWFqb3JfY2xhc3NfY29kZSkgIyBOdW1iZXIgb2YgTXVuaXMgd2l0aCB0aGVzZSBtYWpvciBjbGFzc2VzDQoNCg0KZmlnX211bmlfQVYgPC0gbXVuaV9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiNkEiLCAiNkIiLCAiNkMiLCAiN0EiLCAiN0IiLCAiOCIpKSAlPiUNCiAgZmlsdGVyKGNsZWFuX25hbWUgIT0gIkNoaWNhZ28iKSAlPiUgDQogIGdyb3VwX2J5KHNocGZpbGVfbmFtZSklPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNocGZpbGVfbmFtZSkgKSAlPiUgDQogIGZ1bGxfam9pbihtdW5pX3NocCwgYnkgPSBjKCJzaHBmaWxlX25hbWUiID0gIk1VTklDSVBBTElUWSIpKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gYXYpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiUHJvcGVydGllcyB3aXRoIEFueSBUeXBlIG9mIEluY2VudGl2ZSBDbGFzcyIsDQogICAgICAgc3VidGl0bGUgPSAiQVYgb2YgQnVpbGRpbmdzIHdpdGggSW5jZW50aXZlcyBpbiBNdW5pY2lwYWxpdGllcyAoRXhjZXB0IENoaWNhZ28pLg0KICAgICAgIENoaWNhZ28gaGFzIGFyb3VuZCAkNTAwIG1pbGxpb24gaW4gQVYgZnJvbSBwcm9wZXJ0aWVzIHdpdGggaW5jZW50aXZlcy4iKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJvcmFuZ2UiLA0KICAjICBuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgbGltaXRzID0gYygwLCA5MDAwMDAwMCksDQogICAgbmFtZSA9ICJBViAoJCkiLA0KICAgIGxhYmVsID0gc2NhbGVzOjpkb2xsYXIpDQoNCmZpZ19tdW5pX0FWDQpmaWdfbmJoZF9BVg0KYGBgDQoNCg0KYGBge3IgbXVuaS1waW5jb3VudCwgb3V0LndpZHRoPSAiNTAlIiwgZmlnLnNob3c9J2hvbGQnfQ0KZmlnX211bmlfcGluY291bnQgPC0gbXVuaV9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiNkEiLCAiNkIiLCAiNkMiLCAiN0EiLCAiN0IiLCAiOCIpKSAlPiUNCiAgZmlsdGVyKGNsZWFuX25hbWUgIT0gIkNoaWNhZ28iKSAlPiUgDQogIGdyb3VwX2J5KHNocGZpbGVfbmFtZSklPiUNCiAgc3VtbWFyaXplKHBpbl9jb3VudCA9IHJvdW5kKHN1bShwaW5fY291bnQpKSApICU+JSANCiAgZmlsdGVyKCFpcy5uYShzaHBmaWxlX25hbWUpKSAlPiUgDQogIGZ1bGxfam9pbihtdW5pX3NocCwgYnkgPSBjKCJzaHBmaWxlX25hbWUiID0gIk1VTklDSVBBTElUWSIpKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gcGluX2NvdW50KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksDQogICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgIGx3ZCA9IC4wNSkrIA0KICBsYWJzKHRpdGxlID0gIlByb3BlcnRpZXMgd2l0aCBJbmNlbnRpdmUgQ2xhc2VzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIjIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gTXVuaWNpcGFsaXRpZXMgKEV4Y2VwdCBDaGljYWdvKSIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICMgIG5pY2UuYnJlYWtzID0gRkFMU0UsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiIyBQSU5zIikNCg0KDQpmaWdfbXVuaV9waW5jb3VudA0KZmlnX25iaGRfcGluY291bnQNCmBgYA0KDQojIyBDbGFzcyA2IEluY2VudGl2ZXMNCg0KQ2xhc3MgNkE6IEluZHVzdHJpYWwgSW5jZW50aXZlDQoNCkNsYXNzIDZCOiBJbmR1c3RyaWFsIEluY2VudGl2ZSAtIERlc2lnbmVkIHRvIGVuY291cmFnZSBpbmR1c3RyaWFsIGRldmVsb3BtZW50IHRocm91Z2hvdXQgQ29vayBDb3VudHkgYnkgb2ZmZXJpbmcgYSByZWFsIGVzdGF0ZSB0YXggaW5jZW50aXZlIGZvciB0aGUgZGV2ZWxvcG1lbnQgb2YgbmV3IGluZHVzdHJpYWwgZmFjaWxpdGllcywgdGhlIHJlaGFiaWxpdGF0aW9uIG9mIGV4aXN0aW5nIGluZHVzdHJpYWwgc3RydWN0dXJlcywgYW5kIHRoZSBpbmR1c3RyaWFsIHJldXRpbGl6YXRpb24gb2YgYWJhbmRvbmVkIGJ1aWxkaW5ncy4NCg0KQ2xhc3MgNkM6IEluZHVzdHJpYWwgQnJvd25maWVsZA0KDQpgYGB7ciBvdXQud2lkdGg9ICI1MCUiLCBmaWcuc2hvdz0naG9sZCd9DQoNCmZpZ19tdW5pX0M2X0FWIDwtIG11bmlfcGluY291bnRzX21ham9yY2xhc3MgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjZBIiwgIjZCIiwgIjZDIikpICU+JQ0KICBmaWx0ZXIoY2xlYW5fbmFtZSAhPSAiQ2hpY2FnbyIpICU+JSANCiAgZ3JvdXBfYnkoc2hwZmlsZV9uYW1lKSU+JQ0KICBzdW1tYXJpemUoYXYgPSBzdW0oYXYpKSAlPiUgDQogIGZpbHRlcighaXMubmEoc2hwZmlsZV9uYW1lKSkgJT4lIA0KICBmdWxsX2pvaW4obXVuaV9zaHAsIGJ5ID0gYygic2hwZmlsZV9uYW1lIiA9ICJNVU5JQ0lQQUxJVFkiKSkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGF2KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksDQogICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgIGx3ZCA9IC4wNSkrIA0KICBsYWJzKHRpdGxlID0gIlByb3BlcnRpZXMgd2l0aCBDbGFzcyA2IEluY2VudGl2ZXMiLA0KICAgICAgIHN1YnRpdGxlID0gIkFzc2Vzc2VkIFZhbHVlIGluIE11bmljaXBhbGl0aWVzIChFeGNlcHQgQ2hpY2FnbykiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJvcmFuZ2UiLA0KICAgIyBuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIkFWICgkKSIsDQogIGxhYmVsID0gc2NhbGVzOjpkb2xsYXIpDQoNCg0KDQpmaWdfbXVuaV9DNl9QQyA8LSBtdW5pX3BpbmNvdW50c19tYWpvcmNsYXNzICU+JSANCiAgZmlsdGVyKG1ham9yX2NsYXNzX2NvZGUgJWluJSBjKCI2QSIsICI2QiIsICI2QyIpKSAlPiUNCiAjIGZpbHRlcihjbGVhbl9uYW1lICE9ICJDaGljYWdvIikgJT4lIA0KICBncm91cF9ieShzaHBmaWxlX25hbWUpJT4lDQogIHN1bW1hcml6ZShwaW5fY291bnQgPSBzdW0ocGluX2NvdW50KSkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNocGZpbGVfbmFtZSkpICU+JSANCiAgZnVsbF9qb2luKG11bmlfc2hwLCBieSA9IGMoInNocGZpbGVfbmFtZSIgPSAiTVVOSUNJUEFMSVRZIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBwaW5fY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiUHJvcGVydGllcyB3aXRoIENsYXNzIDYgSW5jZW50aXZlcyIsDQogICAgICAgc3VidGl0bGUgPSAiIyBvZiBCdWlsZGluZ3Mgd2l0aCBJbmNlbnRpdmVzIGluIE11bmljaXBhbGl0aWVzIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHNjYWxlX2ZpbGxfc3RlcHMyKA0KICAgIGhpZ2ggPSAiZGFya2JsdWUiLCBsb3cgPSAib3JhbmdlIiwNCiAgICBuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIiMgUElOcyIpDQoNCmZpZ19tdW5pX0M2X0FWDQpmaWdfbmJoZF9DNl9BVg0KDQpmaWdfbXVuaV9DNl9QQw0KZmlnX25iaGRfQzZfUEMNCg0KDQoNCmBgYA0KDQoNCiMjIENsYXNzIDcgSW5jZW50aXZlcw0KDQpDbGFzcyA3QShCKTogSW50ZW5kZWQgdG8gZW5jb3VyYWdlIGNvbW1lcmNpYWwgcHJvamVjdHMgaW4gYXJlYXMgZGV0ZXJtaW5lZCB0byBiZSAiaW4gbmVlZCBvZiBjb21tZXJjaWFsIGRldmVsb3BtZW50LlRoZXNlIHByb2plY3RzIGhhdmUgdG90YWwgZGV2ZWxvcG1lbnQgY29zdHMsIGV4Y2x1c2l2ZSBvZiBsYW5kLCB0aGF0IERPIE5PVCBFWENFRUQoRE8gRVhDRUVEKSB0d28gbWlsbGlvbiBhbmQgd291bGQgbm90IGJlIGVjb25vbWljYWxseSBmZWFzaWJsZSB3aXRob3V0IHRoZSBpbmNlbnRpdmUuDQoNCg0KDQpgYGB7ciBvdXQud2lkdGg9ICI1MCUiLCBmaWcuc2hvdz0naG9sZCd9DQoNCg0KZmlnX211bmlfQzdfQVYgPC0gbXVuaV9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiN0EiLCAiN0IiLCAiN0MiKSkgJT4lDQogIGZpbHRlcihjbGVhbl9uYW1lICE9ICJDaGljYWdvIikgJT4lIA0KICBncm91cF9ieShzaHBmaWxlX25hbWUpJT4lDQogIHN1bW1hcml6ZShhdiA9IHN1bShhdikpICU+JSANCiAgZmlsdGVyKCFpcy5uYShzaHBmaWxlX25hbWUpKSAlPiUgDQogIGZ1bGxfam9pbihtdW5pX3NocCwgYnkgPSBjKCJzaHBmaWxlX25hbWUiID0gIk1VTklDSVBBTElUWSIpKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gYXYpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiQXNzZXNzZWQgVmFsdWUgb2YgUHJvcGVydGllcyB3aXRoIENsYXNzIDcgSW5jZW50aXZlcyIsDQogICAgICAgc3VidGl0bGUgPSAiaW4gTXVuaWNpcGFsaXRpZXMgKEV4Y2VwdCBDaGljYWdvKSIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICJBViAoJCkiLA0KICBsYWJlbCA9IHNjYWxlczo6ZG9sbGFyKQ0KDQoNCmZpZ19tdW5pX0M3X1BDIDwtIG11bmlfcGluY291bnRzX21ham9yY2xhc3MgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjdBIiwgIjdCIiwgIjdDIikpICU+JQ0KICBmaWx0ZXIoY2xlYW5fbmFtZSAhPSAiQ2hpY2FnbyIpICU+JSANCiAgZ3JvdXBfYnkoc2hwZmlsZV9uYW1lKSU+JQ0KICBzdW1tYXJpemUocGluX2NvdW50ID0gc3VtKHBpbl9jb3VudCkpICU+JSANCiAgZmlsdGVyKCFpcy5uYShzaHBmaWxlX25hbWUpKSAlPiUgDQogIGZ1bGxfam9pbihtdW5pX3NocCwgYnkgPSBjKCJzaHBmaWxlX25hbWUiID0gIk1VTklDSVBBTElUWSIpKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gcGluX2NvdW50KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksDQogICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgIGx3ZCA9IC4wNSkrIA0KICBsYWJzKHRpdGxlID0gIlByb3BlcnRpZXMgd2l0aCBDbGFzcyA3IEluY2VudGl2ZXMiLA0KICAgICAgIHN1YnRpdGxlID0gIiMgb2YgQnVpbGRpbmdzIHdpdGggSW5jZW50aXZlcyBpbiBNdW5pY2lwYWxpdGllcyAoRXhjZXB0IENoaWNhZ28pIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHNjYWxlX2ZpbGxfc3RlcHMyKA0KICAgIGhpZ2ggPSAiZGFya2JsdWUiLCBsb3cgPSAib3JhbmdlIiwNCiAgIyAgbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICIjIFBJTnMiKQ0KDQpmaWdfbXVuaV9DN19BVg0KZmlnX25iaGRfQzdBVg0KDQoNCg0KZmlnX211bmlfQzdfUEMNCmZpZ19uYmhkX0M3X1BDDQpgYGANCg0KDQojIyBDbGFzcyA4IEluY2VudGl2ZXMNCg0KDQpDbGFzcyA4OiBEZXNpZ25lZCB0byBlbmNvdXJhZ2UgaW5kdXN0cmlhbCBhbmQgY29tbWVyY2lhbCBkZXZlbG9wbWVudCBpbiBhcmVhcyBvZiB0aGUgY291bnR5IHdoaWNoIGFyZSBleHBlcmllbmNpbmcgc2V2ZXJlIGVjb25vbWljIHN0YWduYXRpb24uDQoNCg0KQ2xhc3MgOCBwcm9wZXJ0aWVzIGV4aXN0IGluIHBsYWNlcyBiZXNpZGVzIHRoZSA1IHRvd25zaGlwczoNCg0KQmxvb20sIEJyZW1lbiwgQ2FsdW1ldCwgUmljaCwgVGhvcm50b24gIA0KDQoNCmBgYHtyIGNsYXNzOCwgb3V0LndpZHRoPSAiNTAlIiwgZmlnLnNob3c9J2hvbGQnfQ0KZmlnX25iaGRfQzhfUEMgPC0gaW5jZW50aXZlc19wcm9wcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlID09ICI4IikgJT4lDQogIGdyb3VwX2J5KG5iaGRfY29kZSklPiUNCiAgc3VtbWFyaXplKHBpbl9jb3VudCA9IHN1bShwaW5fY291bnQpKSAlPiUgDQogIGZ1bGxfam9pbihOQkhzLCBieSA9IGMoIm5iaGRfY29kZSIgPSAidG93bl9uYmhkIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBwaW5fY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwgY29sb3IgPSAiYmxhY2siKSArIA0KICBsYWJzKHRpdGxlID0gIkNsYXNzIDggUHJvcGVydGllcyIsDQogICAgICAgc3VidGl0bGUgPSAiTnVtYmVyIG9mIFBJTnMgd2l0aCBJbmNlbnRpdmVzIGluIEFzc2Vzc29yIE5laWdoYm9yaG9vZHMiLCANCiAgICAgICBjYXB0aW9uID0gIkNvdW50IG9mIDE0IGRpZ2l0IFBJTnMiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJvcmFuZ2UiLA0KICAgICNuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIkNvdW50IikNCg0KDQpmaWdfbmJoZF9DOCA8LSBpbmNlbnRpdmVzX3Byb3BzICU+JSANCiAgZmlsdGVyKG1ham9yX2NsYXNzX2NvZGUgPT0gIjgiKSAlPiUNCiAgZ3JvdXBfYnkobmJoZF9jb2RlKSAlPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSkgJT4lIA0KICBmdWxsX2pvaW4oTkJIcywgYnkgPSBjKCJuYmhkX2NvZGUiID0gInRvd25fbmJoZCIpKSAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gYXYpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICMgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgIGx3ZCA9IC4xKSAgKw0KICBsYWJzKHRpdGxlID0gIkNsYXNzIDggUHJvcGVydGllcyIsDQogICAgICAgc3VidGl0bGUgPSAiQVYgb2YgQnVpbGRpbmdzIHdpdGggSW5jZW50aXZlcyBpbiBBc3Nlc3NvciBOZWlnaGJvcmhvb2RzIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHNjYWxlX2ZpbGxfc3RlcHMyKA0KICAgIGhpZ2ggPSAiZGFya2JsdWUiLCBsb3cgPSAib3JhbmdlIiwNCiAgICBuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbGltaXRzID0gYygwLCAxMzAwMDAwMCksDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIkFWICgkKSIsDQogICAgbGFiZWwgPSBzY2FsZXM6OmRvbGxhcikNCg0KZmlnX211bmlfQzhfQVYgPC0gbXVuaV9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiOCIpKSAlPiUNCiAgZmlsdGVyKGNsZWFuX25hbWUgIT0gIkNoaWNhZ28iKSAlPiUgDQogIGdyb3VwX2J5KHNocGZpbGVfbmFtZSklPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNocGZpbGVfbmFtZSkpICU+JSANCiAgZnVsbF9qb2luKG11bmlfc2hwLCBieSA9IGMoInNocGZpbGVfbmFtZSIgPSAiTVVOSUNJUEFMSVRZIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBhdikpICsgDQogIGdlb21fc2YoYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpLA0KICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwNCiAgICAgICAgICBsd2QgPSAuMDUpKyANCiAgbGFicyh0aXRsZSA9ICJQcm9wZXJ0aWVzIHdpdGggQ2xhc3MgOCBJbmNlbnRpdmVzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIjIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gTXVuaWNpcGFsaXRpZXMgKEV4Y2VwdCBDaGljYWdvKSIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICJBViAoJCkiLA0KICBsYWJlbCA9IHNjYWxlczo6ZG9sbGFyKQ0KDQoNCg0KZmlnX211bmlfQzhfUEMgPC0gbXVuaV9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiOCIpKSAlPiUNCiAjIGZpbHRlcihjbGVhbl9uYW1lICE9ICJDaGljYWdvIikgJT4lIA0KICBncm91cF9ieShzaHBmaWxlX25hbWUpJT4lDQogIHN1bW1hcml6ZShwaW5fY291bnQgPSBzdW0ocGluX2NvdW50KSkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNocGZpbGVfbmFtZSkpICU+JSANCiAgZnVsbF9qb2luKG11bmlfc2hwLCBieSA9IGMoInNocGZpbGVfbmFtZSIgPSAiTVVOSUNJUEFMSVRZIikpICU+JQ0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBwaW5fY291bnQpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwNCiAgICAgICAgICBjb2xvciA9ICJibGFjayIsDQogICAgICAgICAgbHdkID0gLjA1KSsgDQogIGxhYnModGl0bGUgPSAiUHJvcGVydGllcyB3aXRoIENsYXNzIDggSW5jZW50aXZlcyIsDQogICAgICAgc3VidGl0bGUgPSAiIyBvZiBCdWlsZGluZ3Mgd2l0aCBJbmNlbnRpdmVzIGluIE11bmljaXBhbGl0aWVzIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUoYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHNjYWxlX2ZpbGxfc3RlcHMyKA0KICAgIGhpZ2ggPSAiZGFya2JsdWUiLCBsb3cgPSAib3JhbmdlIiwNCiAgIyAgbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICIjIFBJTnMiKQ0KDQpmaWdfbXVuaV9DOF9QQw0KZmlnX25iaGRfQzhfUEMNCg0KDQoNCmBgYA0KDQo+IFRoZXJlIGFyZSBzb21lIENsYXNzIDggcHJvcGVydGllcyBsb2NhdGVkIGluIHRvd25zaGlwcyBvdGhlciB0aGFuIHRoZSBDbGFzcyA4IGZpdmUgY2hvc2VuIGZvciB0aGUgaW5jZW50aXZlcy4NCg0KDQpgYGB7ciBjbGFzczgtMiwgb3V0LndpZHRoPSAiNTAlIiwgZmlnLnNob3c9J2hvbGQnfQ0KZmlnX211bmlfQzggPC0gbXVuaV9waW5jb3VudHNfbWFqb3JjbGFzcyAlPiUgDQogICBmaWx0ZXIoIWlzLm5hKHNocGZpbGVfbmFtZSkpICU+JSANCg0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjgiKSkgJT4lDQogIGdyb3VwX2J5KHNocGZpbGVfbmFtZSklPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSkgJT4lIA0KICBmdWxsX2pvaW4obXVuaV9zaHAsIGJ5ID0gYygic2hwZmlsZV9uYW1lIiA9ICJNVU5JQ0lQQUxJVFkiKSkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGF2KSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksY29sb3IgPSAiYmxhY2siLCBsd2QgPSAuMDUpKyANCiAgbGFicyh0aXRsZSA9ICJDbGFzcyA4IFByb3BlcnRpZXMiLA0KICAgICAgIHN1YnRpdGxlID0gIkFWIG9mIEJ1aWxkaW5ncyB3aXRoIEluY2VudGl2ZXMgaW4gQXNzZXNzb3IgTmVpZ2hib3Job29kcyIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIm9yYW5nZSIsDQogICAgbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbGltaXRzID0gYygwLCAxMzAwMDAwMCksDQogICAgbmFtZSA9ICJBViAoJCkiLA0KICAgIGxhYmVsID0gc2NhbGVzOjpkb2xsYXIpDQoNCmZpZ19tdW5pX0M4DQpmaWdfbmJoZF9DOA0KDQpgYGANCg0KDQoNCmBgYHtyIGV2YWw9RkFMU0V9DQpjbGFzczhUb3duc2hpcHMgPSByZWFkX2NzdigiLi9PdXRwdXQvM19FeGVtcHRpb25zX0RldGFpbHNfb3V0cHV0LUNsYXNzVGF4Y29kZUV4ZW1wcy5jc3YiKSAlPiUgDQogIG11dGF0ZShjbGFzc19jb2RlID0gYXMuY2hhcmFjdGVyKGNsYXNzX2NvZGUpKSAlPiUNCiAgZmlsdGVyKGNsYXNzX2NvZGUgPj04MDAgJiBjbGFzc19jb2RlIDw5MDApICU+JQ0KICBsZWZ0X2pvaW4oY2xhc3NfZGljdCkgJT4lDQogIG11dGF0ZSh0YXhfY29kZV9udW0gPSBhcy5jaGFyYWN0ZXIodGF4X2NvZGVfbnVtKSkgJT4lDQogIGxlZnRfam9pbih0b3duc2hpcF90YXhfY29kZXMpICU+JQ0KICBsZWZ0X2pvaW4odG93bnNoaXBfYWdlbmN5X25hbWVzKSU+JSANCiAgZGlzdGluY3QoYWdlbmN5X25hbWUpIA0KDQpjbGFzczhUb3duc2hpcHMNCmBgYA0KDQojIENoaWNhZ28gU3BlY2lmaWMgR3JhcGhzDQoNCmBgYHtyIG91dC53aWR0aD0gIjUwJSIsIGZpZy5zaG93PSdob2xkJ30NCg0KIyBmaWdfbmJoZF9DaGljYWdvX0FWIEFsbCBpbmNlbnRpdmVzDQoNCmZpZ19uYmhkX0M2X0NoaWNhZ29fQVYNCmZpZ19uYmhkX0M2X0NoaWNhZ29fUEMNCmZpZ19uYmhkX0M3X0NoaWNhZ29fQVYNCmZpZ19uYmhkX0M3X0NoaWNhZ29fUEMNCmBgYA0KDQojIFRhYmxlcw0KDQpgYGB7cn0NCg0KaW5jZW50aXZlX3BpbnMgJT4lIA0KICBncm91cF9ieShhZ2VuY3lfbmFtZSwgbWFqb3JfY2xhc3NfdHlwZSkgJT4lDQogIHN1bW1hcml6ZShhdiA9IHN1bShhdiksDQogICAgICAgICAgICMgcGlucyA9IG4oKQ0KICAgICAgICAgICApICU+JQ0KICBwaXZvdF93aWRlcihpZF9jb2xzID0gYWdlbmN5X25hbWUsIG5hbWVzX2Zyb20gPSAibWFqb3JfY2xhc3NfdHlwZSIsIHZhbHVlc19mcm9tID0gImF2IikNCiAgDQppbmNlbnRpdmVfcGlucyAlPiUgDQogIGdyb3VwX2J5KGFnZW5jeV9uYW1lLCBtYWpvcl9jbGFzc190eXBlKSAlPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSwNCiAgICAgICAgICAgIHBpbnMgPSBuKCkpICU+JQ0KICBwaXZvdF93aWRlcihpZF9jb2xzID0gYWdlbmN5X25hbWUsIG5hbWVzX2Zyb20gPSAibWFqb3JfY2xhc3NfdHlwZSIsIHZhbHVlc19mcm9tID0gInBpbnMiKQ0KDQppbmNlbnRpdmVfcGlucyAlPiUgDQogIGdyb3VwX2J5KGFnZW5jeV9uYW1lLCBtYWpvcl9jbGFzc190eXBlLCBtYWpvcl9jbGFzc19jb2RlKSAlPiUNCiAgc3VtbWFyaXplKGF2ID0gc3VtKGF2KSwNCiAgICAgICAgICAgIHBpbnMgPSBuKCkpICU+JQ0KICBwaXZvdF93aWRlcihpZF9jb2xzID0gYWdlbmN5X25hbWUsIG5hbWVzX2Zyb20gPSAibWFqb3JfY2xhc3NfY29kZSIsIHZhbHVlc19mcm9tID0gImF2IikNCg0KaW5jZW50aXZlX3BpbnMgJT4lIA0KICBncm91cF9ieShhZ2VuY3lfbmFtZSwgbWFqb3JfY2xhc3NfdHlwZSwgbWFqb3JfY2xhc3NfY29kZSkgJT4lDQogIHN1bW1hcml6ZShhdiA9IHN1bShhdiksDQogICAgICAgICAgICBwaW5zID0gbigpKSAlPiUNCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGFnZW5jeV9uYW1lLCBuYW1lc19mcm9tID0gIm1ham9yX2NsYXNzX2NvZGUiLCB2YWx1ZXNfZnJvbSA9ICJwaW5zIikNCg0KDQoNCiMgIyBCeSBNdW5pIGFuZCBQcm9wZXJ0eSBDbGFzcw0KIyBpbmNlbnRpdmVfY2xhc3NlcyAlPiUgDQojICAgICBtdXRhdGUodGF4X2NvZGVfbnVtID0gYXMuY2hhcmFjdGVyKHRheF9jb2RlX251bSkpICU+JSANCiMgICBsZWZ0X2pvaW4obXVuaV90YXhfY29kZXMpICU+JQ0KIyAgIG11dGF0ZSh0YXhfY29kZV9udW0gPSBhcy5jaGFyYWN0ZXIodGF4X2NvZGVfbnVtKSkgJT4lIA0KIyAgIGxlZnRfam9pbihtdW5pX2FnZW5jeV9uYW1lcykgJT4lDQojICAgZ3JvdXBfYnkoYWdlbmN5X251bSwgY2xhc3MpICU+JQ0KIyAgIGRwbHlyOjpzdW1tYXJpemUocGluX2NvdW50ID0gbigpLA0KIyAgICAgICAgICAgICBhdiA9IHN1bShhdikpICU+JQ0KIyAgIG11dGF0ZShjbGFzc18xZGlnID0gc3RyX3N1YihjbGFzcywgMSwgMSkpDQoNCg0KIyBCeSBNdW5pIGFuZCBNYWpvciBQcm9wZXJ0eSBDbGFzcw0KaW5jZW50aXZlX3BpbnMgJT4lIA0KICAgIG11dGF0ZSh0YXhfY29kZV9udW0gPSBhcy5jaGFyYWN0ZXIodGF4X2NvZGVfbnVtKSkgJT4lIA0KICBsZWZ0X2pvaW4obXVuaV90YXhfY29kZXMpICU+JQ0KICAgIG11dGF0ZSh0YXhfY29kZV9udW0gPSBhcy5jaGFyYWN0ZXIodGF4X2NvZGVfbnVtKSkgJT4lIA0KICBsZWZ0X2pvaW4obXVuaV9hZ2VuY3lfbmFtZXMpICU+JQ0KICBncm91cF9ieShhZ2VuY3lfbnVtLCBtYWpvcl9jbGFzc19jb2RlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShwaW5fY291bnQgPSBuKCksDQogICAgICAgICAgICBhdiA9IHN1bShhdikpDQpgYGANCg0KIyBBcmVhcyB3aXRoIGxvdHMgb2YgZXhlbXB0aW9ucyBhbmQgaW5jZW50aXZlcyANCg0KYWthIGEgcmVkdWNlZCB0YXggYmFzZQ0KDQojIyBNdW5pY3BhbGl0eSBMZXZlbCANCg0KYGBge3J9DQpwaW5fZGF0YSA8LSByZWFkX2NzdigiLi9PdXRwdXQvNENfam9pbmVkX1BJTnNfYmlsbHNfYW5kX2V4ZW1wdGlvbnMuY3N2IikNCmBgYA0KDQoNCmBgYHtyfQ0KbXVuaV90YXhyYXRlcyA8LSBwaW5fZGF0YSAlPiUgDQogIGdyb3VwX2J5KGFnZW5jeV9uYW1lKSAlPiUNCiAgc3VtbWFyaXplKA0KICAgIG11bmlfYXYgPSBzdW0oYXYsIG5hLnJtID0gVFJVRSksDQogICAgbXVuaV9lYXYgPSBzdW0oZWF2LCBuYS5ybSA9IFRSVUUpLA0KICAgIG11bmlfZXF1YWxpemVkX0FWID0gc3VtKGVxdWFsaXplZF9BViwgbmEucm0gPSBUUlVFKSwNCiAgICBwaW5zX2luX211bmkgPSBuKCksDQogICAgbXVuaV9jdXJyZW50X2V4ZW1wdGlvbnMgPSBzdW0oYWxsX2V4ZW1wdGlvbnMsIG5hLnJtID0gVFJVRSksDQogICAgbXVuaV9IT19leGVtcHMgPSBzdW0oZXhlX2hvbWVvd25lciwgbmEucm0gPSBUUlVFKSwNCiAgICBtdW5pX2NvbXBfcmF0ZSA9IG1lYW4odGF4X2NvZGVfcmF0ZSwgbmEucm0gPSBUUlVFKSwgIyBDaGFuZ2VkIGZyb20gZmlyc3QoKSB0byBtZWFuKCkgb24gTm92IDENCiAgICBmaW5hbF90YXhfdG9fZGlzdCA9IHN1bShmaW5hbF90YXhfdG9fZGlzdCwgbmEucm0gPSBUUlVFKSwgIyB1c2VkIGFzIExFVlkgYW1vdW50ISEgDQogICAgZmluYWxfdGF4X3RvX3RpZiA9IHN1bShmaW5hbF90YXhfdG9fdGlmLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRheF9hbXRfZXhlID0gc3VtKHRheF9hbXRfZXhlLCBuYS5ybSA9IFRSVUUpLCANCiAgICB0YXhfYW10X3ByZV9leGUgPSBzdW0odGF4X2FtdF9wcmVfZXhlLCBuYS5ybSA9IFRSVUUpLCANCiAgICB0YXhfYW10X3Bvc3RfZXhlID0gc3VtKHRheF9hbXRfcG9zdF9leGUsIG5hLnJtID0gVFJVRSksDQogICAgIyBycG1fdGlmX3RvX2NwcyA9IHN1bShycG1fdGlmX3RvX2NwcywgbmEucm0gPSBUUlVFKSwgIyBub3QgdXNlZA0KICAgICMgcnBtX3RpZl90b19ycG0gPSBzdW0ocnBtX3RpZl90b19ycG0sIG5hLnJtPVRSVUUpLCAjIG5vdCB1c2VkDQogICAgIyBycG1fdGlmX3RvX2Rpc3QgPSBzdW0ocnBtX3RpZl90b19kaXN0LCBuYS5ybT1UUlVFKSwgIyBub3QgdXNlZA0KICAgICMgdGlmX3NoYXJlID0gbWVhbih0aWZfc2hhcmUsIG5hLnJtPVRSVUUpLCAjIG5vdCB1c2VkDQogICkgJT4lDQogIA0KICByZW5hbWUoY3VyX2NvbXBfVENfcmF0ZSA9IG11bmlfY29tcF9yYXRlKSAlPiUNCiAgbXV0YXRlKGN1cnJlbnRfbXVuaV90YXhhYmxlX2VhdiA9IGZpbmFsX3RheF90b19kaXN0LyhjdXJfY29tcF9UQ19yYXRlLzEwMCksDQogICAgICAgICBuZXdfbXVuaV90YXhhYmxlX2VhdiA9IGZpbmFsX3RheF90b19kaXN0LyhjdXJfY29tcF9UQ19yYXRlLzEwMCkgKyBtdW5pX0hPX2V4ZW1wcykgJT4lDQogIG11dGF0ZShuZXdfY29tcF9UQ19yYXRlID0gKGZpbmFsX3RheF90b19kaXN0IC8gbmV3X211bmlfdGF4YWJsZV9lYXYpKjEwMCkgJT4lDQogIG11dGF0ZShuZXdfY29tcF9UQ19yYXRlID0gaWZlbHNlKGlzLm5hbihuZXdfY29tcF9UQ19yYXRlKSwgY3VyX2NvbXBfVENfcmF0ZSwgbmV3X2NvbXBfVENfcmF0ZSkpICU+JQ0KICBzZWxlY3QoYWdlbmN5X25hbWUsIGN1cl9jb21wX1RDX3JhdGUsIG5ld19jb21wX1RDX3JhdGUsIGN1cnJlbnRfbXVuaV90YXhhYmxlX2VhdiwgbmV3X211bmlfdGF4YWJsZV9lYXYsIGV2ZXJ5dGhpbmcoKSkNCg0KbXVuaV90YXhyYXRlcyANCmBgYA0KDQpgYGB7cn0NCnByb3BfY2xhc3Nfc3VtcyA8LSBwaW5fZGF0YSAlPiUgDQogIGdyb3VwX2J5KGFnZW5jeV9uYW1lLCBtYWpvcl9jbGFzc19jb2RlLCBtYWpvcl9jbGFzc190eXBlICkgICU+JQ0KICANCiAgc3VtbWFyaXplKA0KICAgIGF2ID0gc3VtKGF2LCBuYS5ybSA9IFRSVUUpLA0KICAgIGVhdiA9IHN1bShlYXYsIG5hLnJtID0gVFJVRSksDQogICAgZXF1YWxpemVkX0FWID0gc3VtKGVxdWFsaXplZF9BViwgbmEucm0gPSBUUlVFKSwNCiAgICBwaW5zX2luX2NsYXNzID0gbigpLA0KICAgIGN1cnJlbnRfZXhlbXB0aW9ucyA9IHN1bShhbGxfZXhlbXB0aW9ucywgbmEucm0gPSBUUlVFKSwNCiAgICBIT19leGVtcHMgPSBzdW0oZXhlX2hvbWVvd25lciwgbmEucm0gPSBUUlVFKSwNCiAgICB0YXhfY29kZV9yYXRlID0gbWVhbih0YXhfY29kZV9yYXRlLCBuYS5ybSA9IFRSVUUpLCAjIENoYW5nZWQgZnJvbSBmaXJzdCgpIHRvIG1lYW4oKSBvbiBOb3YgMQ0KICAgIGZpbmFsX3RheF90b19kaXN0ID0gc3VtKGZpbmFsX3RheF90b19kaXN0LCBuYS5ybSA9IFRSVUUpLCAjIHVzZWQgYXMgTEVWWSBhbW91bnQhISANCiAgICBmaW5hbF90YXhfdG9fdGlmID0gc3VtKGZpbmFsX3RheF90b190aWYsIG5hLnJtID0gVFJVRSksDQogICAgdGF4X2FtdF9leGUgPSBzdW0odGF4X2FtdF9leGUsIG5hLnJtID0gVFJVRSksIA0KICAgIHRheF9hbXRfcHJlX2V4ZSA9IHN1bSh0YXhfYW10X3ByZV9leGUsIG5hLnJtID0gVFJVRSksIA0KICAgIHRheF9hbXRfcG9zdF9leGUgPSBzdW0odGF4X2FtdF9wb3N0X2V4ZSwgbmEucm0gPSBUUlVFKSwNCiAgICBycG1fdGlmX3RvX2NwcyA9IHN1bShycG1fdGlmX3RvX2NwcywgbmEucm0gPSBUUlVFKSwgIyBub3QgdXNlZA0KICAgIHJwbV90aWZfdG9fcnBtID0gc3VtKHJwbV90aWZfdG9fcnBtLCBuYS5ybT1UUlVFKSwgIyBub3QgdXNlZA0KICAgIHJwbV90aWZfdG9fZGlzdCA9IHN1bShycG1fdGlmX3RvX2Rpc3QsIG5hLnJtPVRSVUUpLCAjIG5vdCB1c2VkDQogICAgdGlmX3NoYXJlID0gbWVhbih0aWZfc2hhcmUsIG5hLnJtPVRSVUUpLCAjIG5vdCB1c2VkDQogICkgJT4lDQogIA0KICBtdXRhdGUodG90YWxfYmlsbF9jdXJyZW50ID0gZmluYWxfdGF4X3RvX2Rpc3QgKyBmaW5hbF90YXhfdG9fdGlmKSAlPiUNCiAgcmVuYW1lKGN1cl9jb21wX1RDX3JhdGUgPSB0YXhfY29kZV9yYXRlKSAlPiUNCiAgbXV0YXRlKGN1cnJlbnRfdGF4YWJsZV9lYXYgPSBmaW5hbF90YXhfdG9fZGlzdC8oY3VyX2NvbXBfVENfcmF0ZS8xMDApLA0KICAgICAgICAgbmV3X3RheGFibGVfZWF2ID0gZmluYWxfdGF4X3RvX2Rpc3QvKGN1cl9jb21wX1RDX3JhdGUvMTAwKSArIEhPX2V4ZW1wcykgJT4lDQogIG11dGF0ZShuZXdfY29tcF9UQ19yYXRlID0gKGZpbmFsX3RheF90b19kaXN0IC8gbmV3X3RheGFibGVfZWF2KSoxMDApICU+JQ0KICBtdXRhdGUobmV3X2NvbXBfVENfcmF0ZSA9IGlmZWxzZShpcy5uYW4obmV3X2NvbXBfVENfcmF0ZSksIGN1cl9jb21wX1RDX3JhdGUsIG5ld19jb21wX1RDX3JhdGUpKSAlPiUNCiAgc2VsZWN0KGFnZW5jeV9uYW1lLCBtYWpvcl9jbGFzc19jb2RlLCBIT19leGVtcHMsIGN1cnJlbnRfZXhlbXB0aW9ucywgcGluc19pbl9jbGFzcywgY3VycmVudF90YXhhYmxlX2VhdiwgbmV3X3RheGFibGVfZWF2LCAgZXZlcnl0aGluZygpKQ0KDQojIG11bmkgbGV2ZWwgYnkgbWFqb3JfY2xhc3Mgc3VtbWFyeQ0KcHJvcF9jbGFzc19zdW1zIA0KDQoNCmBgYA0KYGBge3IgbXVuaWxldmVsLWV4ZW1wdGlvbnMsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIHByb3BfY2xhc3Nfc3VtcyBpcyBhdCBtdW5pIGxldmVsDQpyZXNfZXhlbXB0c19wZXJfcGluIDwtIHByb3BfY2xhc3Nfc3VtcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlID09ICIyIikgJT4lICMgQ2xhc3MgMiByZXNpZGVudGlhbCBvbmx5DQogIG11dGF0ZShhdmdfR0hFZXhlX3BlclBJTiA9IEhPX2V4ZW1wcy9waW5zX2luX2NsYXNzLA0KICAgICAgICAgYXZnX2FsbGV4ZV9wZXJQSU4gPSBjdXJyZW50X2V4ZW1wdGlvbnMgLyBwaW5zX2luX2NsYXNzKSAlPiUgDQogIHNlbGVjdChhZ2VuY3lfbmFtZSwgYXZnX0dIRWV4ZV9wZXJQSU4sIGF2Z19hbGxleGVfcGVyUElOKQ0KZXhlbXB0c19wZXJfcGluDQoNCg0KIyBDbGFzczJfZGF0YSBpcyBhbHNvIGF0IE11bmkgTGV2ZWwNCkNsYXNzMl9kYXRhIDwtIHJlYWRfY3N2KCIuL091dHB1dC81Yl9DbGFzczJfYnVyZGVuc2hpZnQuY3N2IikNCg0KcmVzaWRlbnRpYWxfZGF0YSA8LSBDbGFzczJfZGF0YSAlPiUgDQogIG11dGF0ZShleGVtcHRpb25zX3Blcl9yZXNQSU4gPSBDMl9jdXJyZW50X0dIRS8gQzJfUENfcGVybXVuaSApICAlPiUNCiAgc2VsZWN0KGNsZWFuX25hbWUsIGV4ZW1wdGlvbnNfcGVyX3Jlc1BJTiwgQzJfRUFWX3BjdCkNCmBgYA0KDQoNCiMjIE5laWdoYm9yaG9vZCBsZXZlbCBqb2luDQoNCmBgYHtyfQ0KDQpuYmhfbWFqb3JfY2xhc3MgPC0gcmVhZF9jc3YoIi4vT3V0cHV0LzhfQ3VycmVudF9UYXhyYXRlc19wZXJfbmJoX2J5X21ham9yY2xhc3MuY3N2IikNCm5iaF9tYWpvcl9jbGFzcw0KDQoNCiMgbmVpZ2hib3Job29kcyB3aXRoIGluY2VudGl2ZSBwcm9wZXJ0aWVzDQppbmNlbnRpdmVzX3Byb3BzIDwtIG5iaF9tYWpvcl9jbGFzcyAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlICVpbiUgYygiNkEiLCAiNkIiLCAiNkMiLCAiN0EiLCAiN0IiLCAiOCIpKSAlPiUNCiAgbXV0YXRlKG5iaGRfY29kZSA9IGFzLmNoYXJhY3RlcihuYmhkX2NvZGUpKQ0KIyANCiMgbmJoX3BpbmNvdW50c19jbGFzcyA8LSBpbmNlbnRpdmVfY2xhc3NlcyAlPiUgDQojICAgZ3JvdXBfYnkobmJoZF9jb2RlLCBjbGFzcykgJT4lDQojICAgZHBseXI6OnN1bW1hcml6ZShwaW5fY291bnQgPSBuKCksDQojICAgICAgICAgICAgIGF2ID0gc3VtKGF2KSkgJT4lDQojICAgbXV0YXRlKGNsYXNzXzFkaWcgPSBzdHJfc3ViKGNsYXNzLCAxLCAxKSkNCiMgDQojIG5iaF9waW5jb3VudHNfbWFqb3JjbGFzcyA8LSBpbmNlbnRpdmVfY2xhc3NlcyAlPiUgDQojICAgZ3JvdXBfYnkobWFqb3JfY2xhc3NfY29kZSwgbWFqb3JfY2xhc3NfdHlwZSwgbmJoZF9jb2RlKSAlPiUNCiMgICBkcGx5cjo6c3VtbWFyaXplKHBpbl9jb3VudCA9IG4oKSwNCiMgICAgICAgICAgICAgYXYgPSBzdW0oYXYpKQ0KDQoNCmBgYA0KDQoNCmBgYHtyIGV2YWw9RkFMU0V9DQoNCg0KDQojIG5iaF9yZXNfZXhlbXB0aW9ucyA8LSByZWFkX2NzdigiLi9PdXRwdXQvOF9uYmhfc3VtX25ld19leGUuY3N2IikgDQpuYmhfdGF4cmF0ZXMgPC0gcmVhZF9jc3YoICIuL091dHB1dC84X0N1cnJlbnRfVGF4cmF0ZXNfcGVyX25iaC5jc3YiKQ0KDQoNCm5iaF9kYXRhIDwtIGxlZnRfam9pbihuYmhfcGluY291bnRzX21ham9yY2xhc3MsIG5iaF90YXhyYXRlcywgYnkgPSAibmJoZF9jb2RlIikNCg0KDQpuYmhfZGF0YSA8LSBuYmhfZGF0YSAlPiUgDQogIHJlbmFtZShhbGxfUElOcyA9IHBpbl9jb3VudC54LA0KICAgICAgICAgbmJoX3BpbnMgPSBwaW5fY291bnQueSkgICU+JQ0KICBtdXRhdGUoZXhlbXB0X292ZXJfdG90YWxfRUFWID0gRXhlbXB0X0VBViAvIFRvdGFsX0VBViwNCiAgICAgICAgIG5iaGRfY29kZSA9IGFzLmNoYXJhY3RlcihuYmhkX2NvZGUpLA0KICAgICAgICAgZXhlbXB0c19wZXJQSU4gPSBFeGVtcHRfRUFWIC8gbmJoX1BJTnMsDQogICAgICAgICBpbmNlbnRpdmVfcHJvamVjdHNfcGN0ID0gaW5jZW50aXZlX1BJTnMgLyBuYmhfUElOcywNCiAgICAgICAgIGluY2VudGl2ZXNfRUFWID0gYXYgKiAzLjAwMjcgLA0KICAgICAgICAgaW5jZW50aXZlc19vdmVyX3RvdGFsX0VBViA9IGluY2VudGl2ZXNfRUFWIC8gVG90YWxfRUFWKSAlPiUNCiAgc2VsZWN0KG5iaGRfY29kZSwgZXhlbXB0X292ZXJfdG90YWxfRUFWLCBuYmhfUElOcywgbWFqb3JfY2xhc3NfUElOcywgZXhlbXB0c19wZXJQSU4sIGluY2VudGl2ZV9wcm9qZWN0c19wY3QsIGluY2VudGl2ZXNfRUFWLCBpbmNlbnRpdmVzX292ZXJfdG90YWxfRUFWLCBtYWpvcl9jbGFzc19jb2RlLCBldmVyeXRoaW5nKCkpICU+JSBhcnJhbmdlKG5iaGRfY29kZSkNCg0KbmJoX2RhdGENCg0KYGBgDQoNCg0KDQpgYGB7cn0NCiMgbmJoX3Jlc19leGVtcHRpb25zIDwtIHJlYWRfY3N2KCIuL091dHB1dC84X25iaF9zdW1fbmV3X2V4ZS5jc3YiKSANCm5iaF90YXhyYXRlcyA8LSByZWFkX2NzdiggIi4vT3V0cHV0LzhfQ3VycmVudF9UYXhyYXRlc19wZXJfbmJoLmNzdiIpICU+JSBzZWxlY3QobmJoZF9jb2RlLCBwaW5fY291bnQsIFRvdGFsX0VBVikNCg0KDQpuYmhfZGF0YSA8LSBsZWZ0X2pvaW4obmJoX21ham9yX2NsYXNzLCBuYmhfdGF4cmF0ZXMsIGJ5ID0gIm5iaGRfY29kZSIpDQoNCg0KbmJoX2RhdGEgPC0gbmJoX2RhdGEgJT4lIA0KICByZW5hbWUobWFqb3JfY2xhc3NfUElOcyA9IHBpbl9jb3VudC54LA0KICAgICAgICAgbmJoX1BJTnMgPSBwaW5fY291bnQueSkgICU+JQ0KICBtdXRhdGUoZXhlbXB0X292ZXJfdG90YWxfRUFWID0gcm91bmQoRXhlbXB0X0VBViAvIFRvdGFsX0VBVi55LCBkaWdpdHMgPSA0KSwNCiAgICAgICAgIG5iaGRfY29kZSA9IGFzLmNoYXJhY3RlcihuYmhkX2NvZGUpLA0KICAgICAgICAgZXhlbXB0c19wZXJQSU4gPSByb3VuZChFeGVtcHRfRUFWIC8gbmJoX1BJTnMsIGRpZ2l0cyA9IDApLA0KICAgICAgICAgY2xhc3NfUElOX3BjdCA9IG1ham9yX2NsYXNzX1BJTnMgLyBuYmhfUElOcywNCiAgICAgICAgICNjbGFzc19FQVYgPSByb3VuZChhdiAqIDMuMDAyNywgZGlnaXRzID0gMCksDQogICAgICAgICBjbGFzc19vdmVyX3RvdGFsX0VBViA9IFRvdGFsX0VBVi54IC8gVG90YWxfRUFWLnkpICU+JQ0KICBzZWxlY3QobmJoZF9jb2RlLCBtYWpvcl9jbGFzc19jb2RlLCBleGVtcHRfb3Zlcl90b3RhbF9FQVYsIG5iaF9QSU5zLCBtYWpvcl9jbGFzc19QSU5zLCBleGVtcHRzX3BlclBJTiwgY2xhc3NfUElOX3BjdCwgVG90YWxfRUFWLngsIGNsYXNzX292ZXJfdG90YWxfRUFWLCBldmVyeXRoaW5nKCkpICU+JSANCiAgYXJyYW5nZShuYmhkX2NvZGUpDQoNCm5iaF9kYXRhDQpgYGANCg0KDQpgYGB7cn0NCm5iaF9yZXMgPC0gbmJoX2RhdGEgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSA9PSAyKSAlPiUgDQogIHNlbGVjdChuYmhkX2NvZGUsIG1ham9yX2NsYXNzX2NvZGUsIA0KICAgICAgICAgcmVzaWRlbnRpYWxfUEMgPSBtYWpvcl9jbGFzc19QSU5zLCANCiAgICAgICAgIHJlc19FQVYgPSBUb3RhbF9FQVYueCwgDQogICAgICAgICByZXNfZXhlbXB0aW9ucyA9IEV4ZW1wdF9FQVYpICU+JQ0KICBtdXRhdGUobmJoZF9jb2RlID0gYXMuY2hhcmFjdGVyKG5iaGRfY29kZSksDQogICAgICAgICByZXNfZXhlX3Blcl9yZXNfcGluID0gcm91bmQocmVzX2V4ZW1wdGlvbnMgLyByZXNpZGVudGlhbF9QQykNCiAgKQ0KICANCiAgDQojbmJoX2RhdGEyIDwtIG5iaF9kYXRhICU+JSBsZWZ0X2pvaW4obmJoX3JlcywgYnkgPSAibmJoZF9jb2RlIikgJT4lIHNlbGVjdChuYmhkX2NvZGUsIGFsbF9QSU5zLCByZXNpZGVudGlhbF9QQywgaW5jZW50aXZlX1BJTnMsIGV2ZXJ5dGhpbmcoKSkgJT4lIG11dGF0ZShleGVtcHNfcGVyX3Jlc1BJTiA9IHJlc19leGVtcHRpb25zIC8gcmVzaWRlbnRpYWxfUEMpICU+JSBhcnJhbmdlKG5iaGRfY29kZSkNCg0KDQpmaWc0IDwtIG5iaF9yZXMgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAgPT0gMikgJT4lDQogIGZpbHRlcihyZXNpZGVudGlhbF9QQyA+IDQpICU+JSANCiAgZnVsbF9qb2luKE5CSHMsIGJ5ID0gYygibmJoZF9jb2RlIiA9ICJ0b3duX25iaGQiKSkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IHJlc19leGVfcGVyX3Jlc19waW4pKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwgY29sb3IgPSAiYmxhY2siKSArIA0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgZXhlbXB0aW9ucyBwZXIgUmVzaWRlbnRpYWwgQ2xhc3MgMiBQSU4iKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfZmlsbF9zdGVwczIoDQogICAgaGlnaCA9ICJkYXJrYmx1ZSIsIGxvdyA9ICJ3aGl0ZSIsDQogICAgI25pY2UuYnJlYWtzID0gRkFMU0UsDQogICAgc2hvdy5saW1pdHM9VFJVRSwNCiAgICBuYS52YWx1ZSA9IE5BLA0KICAgIG5hbWUgPSAiRXhlbXB0aW9ucyBwZXIgUElOIikNCg0KZmlnNA0KYGBgDQoNCiMjIE1hcHMNCg0KYGBge3J9DQpmaWcxIDwtIG5iaF9kYXRhICU+JSANCiAgZmlsdGVyKG1ham9yX2NsYXNzX2NvZGUgPT0gMikgJT4lDQogICNmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjZBIiwgIjZCIiwgIjZDIiwgIjdBIiwgIjdCIiwgIjgiKSkgJT4lDQogICNncm91cF9ieShuYmhkX2NvZGUpJT4lDQogICNzdW1tYXJpemUocGluX2NvdW50ID0gc3VtKHBpbl9jb3VudCkpICU+JSANCiAgZnVsbF9qb2luKE5CSHMsIGJ5ID0gYygibmJoZF9jb2RlIiA9ICJ0b3duX25iaGQiKSkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGV4ZW1wdF9vdmVyX3RvdGFsX0VBVikpICsgDQogIGdlb21fc2YoYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpLCBjb2xvciA9ICJibGFjayIpICsgDQogIGxhYnModGl0bGUgPSAiRXhlbXB0IEVBViAoZnJvbSBSZXNpZGVudGlhbCBFeGVtcHRvbnMpIC8gVG90YWwgRUFWIiwNCiAgICAgICMgY2FwdGlvbiA9ICJUb3RhbCBFQVYgaW5jbHVkZXMgVElGIGFuZCBhbGwgRUFWIGJlZm9yZSBleGVtcHRpb25zIGFyZSBkZWR1Y3RlZCINCiAgICAgICApICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImZvcmVzdGdyZWVuIiwgbG93ID0gIndoaXRlIiwNCiAgICAjbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICIlIEV4ZW1wdCIpDQoNCmZpZzENCg0KDQoNCmZpZzMgPC0gbmJoX2RhdGEgJT4lIA0KICBmaWx0ZXIobWFqb3JfY2xhc3NfY29kZSAlaW4lIGMoIjZBIiwgIjZCIiwgIjZDIiwgIjdBIiwgIjdCIiwgIjgiKSkgJT4lDQogIGdyb3VwX2J5KG5iaGRfY29kZSklPiUNCiAgc3VtbWFyaXplKGluY2VudGl2ZXNfb3Zlcl90b3RhbF9FQVYgPSBzdW0oVG90YWxfRUFWLngvVG90YWxfRUFWLnkpICkgJT4lDQogICNzdW1tYXJpemUocGluX2NvdW50ID0gc3VtKHBpbl9jb3VudCkpICU+JSANCiAgZnVsbF9qb2luKE5CSHMsIGJ5ID0gYygibmJoZF9jb2RlIiA9ICJ0b3duX25iaGQiKSkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGluY2VudGl2ZXNfb3Zlcl90b3RhbF9FQVYpKSArIA0KICBnZW9tX3NmKGFlcyhnZW9tZXRyeSA9IGdlb21ldHJ5KSwgY29sb3IgPSAiYmxhY2siKSArIA0KICBsYWJzKHRpdGxlID0gIkVBViBvZiBpbmNlbnRpdmUgcHJvcGVydGllcyAvIFRvdGFsIEVBViIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gIm9yYW5nZSIsIGxvdyA9ICJ5ZWxsb3ciLA0KICAgICNuaWNlLmJyZWFrcyA9IEZBTFNFLA0KICAgIHNob3cubGltaXRzPVRSVUUsDQogICAgbmEudmFsdWUgPSBOQSwNCiAgICBuYW1lID0gIiUiKQ0KDQpmaWczDQoNCg0KZmlnMiA8LSBuYmhfZGF0YSAlPiUgDQogIGZpbHRlcihtYWpvcl9jbGFzc19jb2RlID09ICIyIikgJT4lDQogICNncm91cF9ieShuYmhkX2NvZGUpJT4lDQogICNzdW1tYXJpemUocGluX2NvdW50ID0gc3VtKHBpbl9jb3VudCkpICU+JSANCiAgZnVsbF9qb2luKE5CSHMsIGJ5ID0gYygibmJoZF9jb2RlIiA9ICJ0b3duX25iaGQiKSkgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IGV4ZW1wdHNfcGVyUElOKSkgKyANCiAgZ2VvbV9zZihhZXMoZ2VvbWV0cnkgPSBnZW9tZXRyeSksIGNvbG9yID0gImJsYWNrIikgKyANCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIGV4ZW1wdGlvbnMgcGVyIFBJTiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBzY2FsZV9maWxsX3N0ZXBzMigNCiAgICBoaWdoID0gImRhcmtibHVlIiwgbG93ID0gIndoaXRlIiwNCiAgICAjbmljZS5icmVha3MgPSBGQUxTRSwNCiAgICBzaG93LmxpbWl0cz1UUlVFLA0KICAgIG5hLnZhbHVlID0gTkEsDQogICAgbmFtZSA9ICJFeGVtcHRpb25zIHBlciBQSU4iKQ0KDQpmaWcyDQpgYGANCg0K