第2週

12/14(TH) 所得と富の不平等の現状1

       所得と富の不平等の現状2

講義では、第2週、第3週とWorld Inequality report 2022を使って、所得と富の不平等について議論します。

12/19(TU) Rでデータサイエンス2:人口の少子高齢化  [Main]・[授業]

People- Population dynamics

総人口 Population, total:SP.POP.TOTL [Link]

出生率(千人)Birth rate, crude (per 1,000 people):SP.DYN.CBRT.IN [Link]

死亡率(千人)Death rate, crude (per 1,000 people):SP.DYN.CDRT.IN [Link]

若年労働人口率 Age dependency ratio, young (% of working-age population):SP.POP.DPND.YG [Link]

高齢者労働人口率 Age dependency ratio, old (% of working-age population):SP.POP.DPND.OL [Link to Metadata]

内容

トピック:人口の少子高齢化

library(tidyverse)
library(WDI)
df_pop <- WDI(indicator = c(pop = "SP.POP.TOTL",
                            birth_rate = "SP.DYN.CBRT.IN",
                            death_rate = "SP.DYN.CDRT.IN",
                            young = "SP.POP.DPND.YG",
                            old = "SP.POP.DPND.OL"))
write_csv(df_pop, "data/pop.csv")
df_pop <- read_csv("data/pop.csv")
Rows: 16758 Columns: 9── Column specification ───────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): country, iso2c, iso3c
dbl (6): year, pop, birth_rate, death_rate, young, old
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
df_pop

それぞれ十分なデータがあるかチェック

df_pop_long <- df_pop |> 
  pivot_longer(5:9, names_to = "name", values_to = "value")
df_pop_long |> 
  group_by(year, name) |> drop_na(value) |>
  summarize(num = n()) |> arrange(desc(year))
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
df_pop_long |> 
  group_by(year, name) |> drop_na(value) |>
  summarize(num = n()) |> 
  ggplot(aes(year, num, col = name)) + geom_line() +
  labs(title = "各指標の年毎のデータ数", y = "データ数", x = "年")
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.

253から265の国・地域のデータがあり、問題なし

df_pop_extra <- WDI(indicator = c(pop = "SP.POP.TOTL",
                            birth_rate = "SP.DYN.CBRT.IN",
                            death_rate = "SP.DYN.CDRT.IN",
                            young = "SP.POP.DPND.YG",
                            old = "SP.POP.DPND.OL"), extra = TRUE)
write_csv(df_pop_extra, "data/pop_extra.csv")
df_pop_extra <- read_csv("data/pop_extra.csv")
str(df_pop_extra)
glimpse(df_pop_extra)

いくつかの文字ベクトルの内容確認

df_pop_extra |> select(region, income, lending, status) |> lapply(unique)
REGION <- df_pop_extra |> filter(region %in% c("Aggregates", NA)) |> distinct(iso2c) |> pull()
length(REGION)

他の指定の仕方と比較

REGION1 <- df_pop_extra |> filter(region %in% c("Aggregates")) |> distinct(iso2c) |> pull()
length(REGION1)
df_pop_extra |> filter(region == "Aggregates") |> distinct(iso2c) |> pull() |> identical(REGION1)
df_pop %>% filter(iso2c %in% REGION) %>% distinct(country, iso2c)

Czechia, CZ, Not classified, Viet Nam, VN

df_pop_extra |> distinct(country, iso2c)
df_pop_extra |> filter(iso2c %in% c("CZ","VN"))
length(REGION)
REGION <- REGION[!(REGION %in% c("CZ","VN"))] |> sort()
length(REGION)
REGION
df_pop |> filter(iso2c %in% REGION) |> distinct(country, iso2c)
df_pop |> filter(!(iso2c %in% REGION)) |> 
  distinct(country, iso2c) |> arrange(country)
dput(REGION)
length(REGION)
df_pop_extra |> filter(!(iso2c %in% REGION)) |> 
  select(region, income, lending, status) |> lapply(unique)
df_pop_extra |> filter(!(iso2c %in% REGION)) |> 
  select(region, income, lending, status) |> lapply(unique) |> dput()
df_pop_extra |> filter(!(iso2c %in% REGION)) |> 
  filter(is.na(region)) |> distinct(country, iso2c)
df_pop_extra |> filter(!(iso2c %in% REGION)) |> 
  filter(income %in% c("Not classified", NA)) |> distinct(country, iso2c, income)
df_pop_extra |> filter(!(iso2c %in% REGION)) |> 
  filter(lending %in% c("Not classified", NA)) |> distinct(country, iso2c, lending)

World Bank Country and Lending Groups [Link]

How does the World Bank classify countries? [Link]

World Bank Group country classifications by income level for FY24 (July 1, 2023- June 30, 2024) [Link]

Operational lending categories

Economies are also divided into IDA, IBRD, and Blend categories based on the operational policies of the World Bank.International Development Association (IDA) countries are those with low per capita incomes that lack the financial ability to borrow from the International Bank for Reconstruction and Development (IBRD). Blend countries are eligible for IDA loans but are also eligible for IBRD loans because they are financially creditworthy.

df_pop_extra |> filter(country == "China") |> select(country, year, income, lending)

総人口

総人口 Population, total:SP.POP.TOTL [Link]

df_pop |> filter(country == "World") |> 
  ggplot(aes(year, pop)) + geom_line() + 
  labs(title = "世界の人口")
df_pop |> filter(country == "Japan") |> 
  ggplot(aes(year, pop)) + geom_line() +
  labs(title = "日本の人口")
COUNTRY <- "Germany"
df_pop |> filter(country == "France") |> 
  ggplot(aes(year, pop)) + geom_line() +
  labs(title = "ドイツの人口")
df_pop |> filter(!(iso2c %in% REGION)) |> filter(year == 2022) |> 
  arrange(desc(pop))
df_pop |> filter(!(iso2c %in% REGION)) |> filter(year == 2022) |> 
  arrange(desc(pop)) |> slice_head(n=10)
pop_top11 <- df_pop |> filter(!(iso2c %in% REGION)) |> filter(year == 2022) |> 
  arrange(desc(pop)) |> slice_head(n=11) |> pull(iso2c)
pop_top11
dput(pop_top11)
df_pop |> filter(iso2c %in% pop_top11) |>
  ggplot(aes(year, pop, color = iso2c)) + geom_line()
df_pop |> filter(country %in% c("South Asia", "Europe & Central Asia", "Middle East & North Africa", 
"East Asia & Pacific", "Sub-Saharan Africa", "Latin America & Caribbean", "North America")) |>
  ggplot(aes(year, pop, color = country)) + geom_line()
df_pop |> filter(country %in% c("South Asia", "Europe & Central Asia", "Middle East & North Africa", 
"East Asia & Pacific", "Sub-Saharan Africa", "Latin America & Caribbean", "North America")) |> 
  distinct(iso2c) |> pull() |> dput()
df_pop |> filter(country %in% c("South Asia", "Europe & Central Asia", "Middle East & North Africa", 
"East Asia & Pacific", "Sub-Saharan Africa", "Latin America & Caribbean", "North America")) |> filter(year == 2022) |> arrange(desc(pop))
df_pop |> filter(iso2c %in% pop_top11) |> 
  filter(!(iso2c %in% c("CN", "IN"))) |> 
  ggplot(aes(year, pop, color = country)) + geom_line()
df_pop |> filter(iso2c %in% pop_top11) |> 
  filter(!(iso2c %in% c("CN", "IN"))) |> 
  ggplot(aes(year, pop, color = factor(iso2c, levels = pop_top11))) + geom_line() + labs(color = "iso2c")

出生率と死亡率

出生率(千人)Birth rate, crude (per 1,000 people):SP.DYN.CBRT.IN [Link]

死亡率(千人)Death rate, crude (per 1,000 people):SP.DYN.CDRT.IN [Link]

df_pop_long |> filter(name %in% c("birth_rate", "death_rate")) |>
  filter(country == "World") |> 
  ggplot(aes(year, value, col = name)) + geom_line()
df_pop_long |> filter(name %in% c("birth_rate", "death_rate")) |>
  filter(iso2c %in% c("BD", "BR", "CN", "ID", "NG", "JP")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line()
df_pop_long |> filter(name %in% c("birth_rate", "death_rate")) |>
  filter(iso2c %in% c("Z4", "Z7", "ZJ", "ZQ", "XU", "8S", "ZG")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line()
df_pop_extra |> 
  filter(!(iso2c %in% REGION)) |> filter(year == 2020) |> 
  filter(!(income %in% c(NA, "Not classified"))) |>
  drop_na(birth_rate, death_rate) |>
  ggplot(aes(birth_rate,death_rate,col=income)) + geom_point()
df_pop_extra |> 
  filter(!(iso2c %in% REGION)) |> 
  filter(year %in% c(1960, 1990, 2020)) |> 
  filter(!(income %in% c(NA, "Not classified"))) |>
  drop_na(birth_rate, death_rate) |>
  ggplot(aes(birth_rate,death_rate,col=income)) + geom_point() + 
  facet_wrap(~ year) + theme(legend.position = "bottom") +
  labs(col = "")

Google Public Data Explorer: Link

扶養家族の労働人口に対する割合

若年労働人口率 Age dependency ratio, young (% of working-age population):SP.POP.DPND.YG [Link]

Age dependency ratio, young, is the ratio of younger dependents–people younger than 15–to the working-age population–those ages 15-64. Data are shown as the proportion of dependents per 100 working-age population.

年齢別扶養比率(若年)は、15歳未満の扶養家族の、15歳から64歳までの生産年齢人口に対する比率である。データは、生産年齢人口100人当たりの扶養家族の割合で示されている。

高齢者労働人口率 Age dependency ratio, old (% of working-age population):SP.POP.DPND.OL [Link to Metadata]

Age dependency ratio, old, is the ratio of older dependents–people older than 64–to the working-age population–those ages 15-64. Data are shown as the proportion of dependents per 100 working-age population.

年齢別扶養比率(高齢)は、生産年齢人口(15~64歳)に対する高齢扶養家族(64歳以上)の比率。データは、生産年齢人口100人当たりの扶養家族の割合で示されている。

df_pop_long |> filter(name %in% c("young", "old")) |>
  filter(country == "World") |> 
  ggplot(aes(year, value, col = name)) + geom_line()
df_pop_long |> filter(name %in% c("young", "old")) |>
  filter(iso2c %in% c("BD", "BR", "CN", "ID", "NG", "JP")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line()
df_pop_extra |> 
  filter(!(iso2c %in% REGION)) |> filter(year == 2020) |> 
  filter(!(income %in% c(NA, "Not classified"))) |>
  drop_na(young, old) |>
  ggplot(aes(young, old, col=income)) + geom_point()
df_pop_extra |> 
  filter(region == "Sub-Saharan Africa") |> filter(year == 2020) |> 
  drop_na(young, old) |>
  ggplot(aes(young, old, col=income)) + geom_point()
df_pop_long |> filter(name %in% c("young", "old")) |>
  filter(iso2c %in% c("US", "GB", "CN", "DE", "FR", "JP", "IN")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line()
df_pop_long |> filter(name %in% c("young", "old")) |>
  filter(country %in% c("South Asia", "Europe & Central Asia", "Middle East & North Africa", 
"East Asia & Pacific", "Sub-Saharan Africa", "Latin America & Caribbean", "North America")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line() + labs(title = "地域別の労働人口に対する高齢・若年扶養率(%)", 
       subtitle = "実線:高齢者、点線:若年者", x = "", col = "", linetype = "")
df_pop_long |> filter(name %in% c("young", "old")) |>
  filter(country %in% c("South Asia", "Europe & Central Asia", "Middle East & North Africa", 
"East Asia & Pacific", "Sub-Saharan Africa", "Latin America & Caribbean", "North America")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line() + facet_wrap(~country) + theme(legend.position = "none") +
  labs(title = "地域別の労働人口に対する高齢・若年扶養率(%)", 
       subtitle = "実線:高齢者、点線:若年者", x = "", y = "")

Default is fig. width = 7 and fig. height = 5

df_pop_long |> filter(name %in% c("young", "old")) |>
  filter(country %in% c("South Asia", "Europe & Central Asia", "Middle East & North Africa", 
"East Asia & Pacific", "Sub-Saharan Africa", "Latin America & Caribbean", "North America")) |> 
  ggplot(aes(year, value, col = country, linetype = name)) + 
  geom_line() + facet_wrap(~country, 2,4) + theme(legend.position = "none") +
  labs(title = "地域別の労働人口に対する高齢・若年扶養率(%)", 
       subtitle = "実線:高齢者、点線:若年者", x = "", y = "")
LS0tCnRpdGxlOiAiR0VTIDAwMSDmvJTnv5IyIgphdXRob3I6ICJILiBTdXp1a2kiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgojIyDnrKwy6YCxCgoxMi8xNChUSCnjgIDmiYDlvpfjgajlr4zjga7kuI3lubPnrYnjga7nj77nirbvvJEKCuOAgOOAgOOAgOOAgOOAgCDCoOaJgOW+l+OBqOWvjOOBruS4jeW5s+etieOBruePvueKtu+8kgoK6Kyb576p44Gn44Gv44CB56ysMumAseOAgeesrDPpgLHjgahXb3JsZCBJbmVxdWFsaXR5IHJlcG9ydCAyMDIy44KS5L2/44Gj44Gm44CB5omA5b6X44Go5a+M44Gu5LiN5bmz562J44Gr44Gk44GE44Gm6K2w6KuW44GX44G+44GZ44CCCgoxMi8xOShUVSnjgIBS44Gn44OH44O844K/44K144Kk44Ko44Oz44K5Mu+8muS6uuWPo+OBruWwkeWtkOmrmOm9ouWMluOAgCBbW01haW5dKGh0dHBzOi8vZHMtc2wuZ2l0aHViLmlvL2ludHJvMnIvZ2VzMDAxL2dlczAwMS1tYWluLm5iLmh0bWwpXeODu1vmjojmpa1dCgoqKlBlb3BsZS0gUG9wdWxhdGlvbiBkeW5hbWljcyoqCgrnt4/kurrlj6PjgIBQb3B1bGF0aW9uLCB0b3RhbO+8mlNQLlBPUC5UT1RMIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NQLlBPUC5UT1RMKV0KCuWHuueUn+eOh++8iOWNg+S6uu+8iUJpcnRoIHJhdGUsIGNydWRlIChwZXIgMSwwMDAgcGVvcGxlKe+8mlNQLkRZTi5DQlJULklOIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NQLkRZTi5DQlJULklOKV0KCuatu+S6oeeOh++8iOWNg+S6uu+8iURlYXRoIHJhdGUsIGNydWRlIChwZXIgMSwwMDAgcGVvcGxlKe+8mlNQLkRZTi5DRFJULklOIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NQLkRZTi5DRFJULklOKV0KCuiLpeW5tOWKtOWDjeS6uuWPo+eOh+OAgEFnZSBkZXBlbmRlbmN5IHJhdGlvLCB5b3VuZyAoJSBvZiB3b3JraW5nLWFnZSBwb3B1bGF0aW9uKe+8mlNQLlBPUC5EUE5ELllHIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NQLlBPUC5EUE5ELllHKV0KCumrmOm9ouiAheWKtOWDjeS6uuWPo+eOh+OAgEFnZSBkZXBlbmRlbmN5IHJhdGlvLCBvbGQgKCUgb2Ygd29ya2luZy1hZ2UgcG9wdWxhdGlvbinvvJpTUC5QT1AuRFBORC5PTCBbW0xpbmsgdG8gTWV0YWRhdGFdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L2hlYWx0aC1udXRyaXRpb24tYW5kLXBvcHVsYXRpb24tc3RhdGlzdGljcy9zZXJpZXMvU1AuUE9QLkRQTkQuT0wpXQoKIyMg5YaF5a65CgotICAgUGFja2FnZe+8mnRpZHl2ZXJzZSwgV0RJCgotICAg44OH44O844K/44Gu5Y+W5b6XCgotICAg54m55a6a44Gu6KGM44Gu5Y+W5b6X77yaZmlsdGVyCgotICAg5oqY44KM57ea44Kw44Op44OVCgotICAg5pWj5biD5ZuzCgojIyMg44OI44OU44OD44Kv77ya5Lq65Y+j44Gu5bCR5a2Q6auY6b2i5YyWCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoV0RJKQpgYGAKCmBgYHtyIGV2YWwgPSBGQUxTRX0KZGZfcG9wIDwtIFdESShpbmRpY2F0b3IgPSBjKHBvcCA9ICJTUC5QT1AuVE9UTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXJ0aF9yYXRlID0gIlNQLkRZTi5DQlJULklOIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYXRoX3JhdGUgPSAiU1AuRFlOLkNEUlQuSU4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeW91bmcgPSAiU1AuUE9QLkRQTkQuWUciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkID0gIlNQLlBPUC5EUE5ELk9MIikpCmBgYAoKYGBge3IgZXZhbCA9IEZBTFNFfQp3cml0ZV9jc3YoZGZfcG9wLCAiZGF0YS9wb3AuY3N2IikKYGBgCgpgYGB7cn0KZGZfcG9wIDwtIHJlYWRfY3N2KCJkYXRhL3BvcC5jc3YiKQpgYGAKCmBgYHtyfQpkZl9wb3AKYGBgCgojIyMjIOOBneOCjOOBnuOCjOWNgeWIhuOBquODh+ODvOOCv+OBjOOBguOCi+OBi+ODgeOCp+ODg+OCrwoKYGBge3J9CmRmX3BvcF9sb25nIDwtIGRmX3BvcCB8PiAKICBwaXZvdF9sb25nZXIoNTo5LCBuYW1lc190byA9ICJuYW1lIiwgdmFsdWVzX3RvID0gInZhbHVlIikKYGBgCgpgYGB7cn0KZGZfcG9wX2xvbmcgfD4gCiAgZ3JvdXBfYnkoeWVhciwgbmFtZSkgfD4gZHJvcF9uYSh2YWx1ZSkgfD4KICBzdW1tYXJpemUobnVtID0gbigpKSB8PiBhcnJhbmdlKGRlc2MoeWVhcikpCmBgYAoKYGBge3J9CmRmX3BvcF9sb25nIHw+IAogIGdyb3VwX2J5KHllYXIsIG5hbWUpIHw+IGRyb3BfbmEodmFsdWUpIHw+CiAgc3VtbWFyaXplKG51bSA9IG4oKSkgfD4gCiAgZ2dwbG90KGFlcyh5ZWFyLCBudW0sIGNvbCA9IG5hbWUpKSArIGdlb21fbGluZSgpICsKICBsYWJzKHRpdGxlID0gIuWQhOaMh+aomeOBruW5tOavjuOBruODh+ODvOOCv+aVsCIsIHkgPSAi44OH44O844K/5pWwIiwgeCA9ICLlubQiKQpgYGAKCjI1M+OBi+OCiTI2NeOBruWbveODu+WcsOWfn+OBruODh+ODvOOCv+OBjOOBguOCiuOAgeWVj+mhjOOBquOBlwoKYGBge3IgZXZhbCA9IEZBTFNFfQpkZl9wb3BfZXh0cmEgPC0gV0RJKGluZGljYXRvciA9IGMocG9wID0gIlNQLlBPUC5UT1RMIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpcnRoX3JhdGUgPSAiU1AuRFlOLkNCUlQuSU4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVhdGhfcmF0ZSA9ICJTUC5EWU4uQ0RSVC5JTiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5b3VuZyA9ICJTUC5QT1AuRFBORC5ZRyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGQgPSAiU1AuUE9QLkRQTkQuT0wiKSwgZXh0cmEgPSBUUlVFKQpgYGAKCmBgYHtyIGV2YWwgPSBGQUxTRX0Kd3JpdGVfY3N2KGRmX3BvcF9leHRyYSwgImRhdGEvcG9wX2V4dHJhLmNzdiIpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSA8LSByZWFkX2NzdigiZGF0YS9wb3BfZXh0cmEuY3N2IikKYGBgCgpgYGB7cn0Kc3RyKGRmX3BvcF9leHRyYSkKYGBgCgpgYGB7cn0KZ2xpbXBzZShkZl9wb3BfZXh0cmEpCmBgYAoK44GE44GP44Gk44GL44Gu5paH5a2X44OZ44Kv44OI44Or44Gu5YaF5a6556K66KqNCgpgYGB7cn0KZGZfcG9wX2V4dHJhIHw+IHNlbGVjdChyZWdpb24sIGluY29tZSwgbGVuZGluZywgc3RhdHVzKSB8PiBsYXBwbHkodW5pcXVlKQpgYGAKCmBgYHtyfQpSRUdJT04gPC0gZGZfcG9wX2V4dHJhIHw+IGZpbHRlcihyZWdpb24gJWluJSBjKCJBZ2dyZWdhdGVzIiwgTkEpKSB8PiBkaXN0aW5jdChpc28yYykgfD4gcHVsbCgpCmxlbmd0aChSRUdJT04pCmBgYAoKIyMjIyDku5bjga7mjIflrprjga7ku5Xmlrnjgajmr5TovIMKCmBgYHtyfQpSRUdJT04xIDwtIGRmX3BvcF9leHRyYSB8PiBmaWx0ZXIocmVnaW9uICVpbiUgYygiQWdncmVnYXRlcyIpKSB8PiBkaXN0aW5jdChpc28yYykgfD4gcHVsbCgpCmxlbmd0aChSRUdJT04xKQpgYGAKCmBgYHtyfQpkZl9wb3BfZXh0cmEgfD4gZmlsdGVyKHJlZ2lvbiA9PSAiQWdncmVnYXRlcyIpIHw+IGRpc3RpbmN0KGlzbzJjKSB8PiBwdWxsKCkgfD4gaWRlbnRpY2FsKFJFR0lPTjEpCmBgYAoKYGBge3J9CmRmX3BvcCAlPiUgZmlsdGVyKGlzbzJjICVpbiUgUkVHSU9OKSAlPiUgZGlzdGluY3QoY291bnRyeSwgaXNvMmMpCmBgYAoKQ3plY2hpYSwgQ1osIE5vdCBjbGFzc2lmaWVkLCBWaWV0IE5hbSwgVk4KCmBgYHtyfQpkZl9wb3BfZXh0cmEgfD4gZGlzdGluY3QoY291bnRyeSwgaXNvMmMpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiBmaWx0ZXIoaXNvMmMgJWluJSBjKCJDWiIsIlZOIikpCmBgYAoKYGBge3J9Cmxlbmd0aChSRUdJT04pClJFR0lPTiA8LSBSRUdJT05bIShSRUdJT04gJWluJSBjKCJDWiIsIlZOIikpXSB8PiBzb3J0KCkKbGVuZ3RoKFJFR0lPTikKUkVHSU9OCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoaXNvMmMgJWluJSBSRUdJT04pIHw+IGRpc3RpbmN0KGNvdW50cnksIGlzbzJjKQpgYGAKCmBgYHtyfQpkZl9wb3AgfD4gZmlsdGVyKCEoaXNvMmMgJWluJSBSRUdJT04pKSB8PiAKICBkaXN0aW5jdChjb3VudHJ5LCBpc28yYykgfD4gYXJyYW5nZShjb3VudHJ5KQpgYGAKCmBgYHtyfQpkcHV0KFJFR0lPTikKbGVuZ3RoKFJFR0lPTikKYGBgCgpgYGB7cn0KZGZfcG9wX2V4dHJhIHw+IGZpbHRlcighKGlzbzJjICVpbiUgUkVHSU9OKSkgfD4gCiAgc2VsZWN0KHJlZ2lvbiwgaW5jb21lLCBsZW5kaW5nLCBzdGF0dXMpIHw+IGxhcHBseSh1bmlxdWUpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiBmaWx0ZXIoIShpc28yYyAlaW4lIFJFR0lPTikpIHw+IAogIHNlbGVjdChyZWdpb24sIGluY29tZSwgbGVuZGluZywgc3RhdHVzKSB8PiBsYXBwbHkodW5pcXVlKSB8PiBkcHV0KCkKYGBgCgpgYGB7cn0KZGZfcG9wX2V4dHJhIHw+IGZpbHRlcighKGlzbzJjICVpbiUgUkVHSU9OKSkgfD4gCiAgZmlsdGVyKGlzLm5hKHJlZ2lvbikpIHw+IGRpc3RpbmN0KGNvdW50cnksIGlzbzJjKQpgYGAKCmBgYHtyfQpkZl9wb3BfZXh0cmEgfD4gZmlsdGVyKCEoaXNvMmMgJWluJSBSRUdJT04pKSB8PiAKICBmaWx0ZXIoaW5jb21lICVpbiUgYygiTm90IGNsYXNzaWZpZWQiLCBOQSkpIHw+IGRpc3RpbmN0KGNvdW50cnksIGlzbzJjLCBpbmNvbWUpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiBmaWx0ZXIoIShpc28yYyAlaW4lIFJFR0lPTikpIHw+IAogIGZpbHRlcihsZW5kaW5nICVpbiUgYygiTm90IGNsYXNzaWZpZWQiLCBOQSkpIHw+IGRpc3RpbmN0KGNvdW50cnksIGlzbzJjLCBsZW5kaW5nKQpgYGAKCldvcmxkIEJhbmsgQ291bnRyeSBhbmQgTGVuZGluZyBHcm91cHMgW1tMaW5rXShodHRwczovL2RhdGFoZWxwZGVzay53b3JsZGJhbmsub3JnL2tub3dsZWRnZWJhc2UvYXJ0aWNsZXMvOTA2NTE5LXdvcmxkLWJhbmstY291bnRyeS1hbmQtbGVuZGluZy1ncm91cHMpXQoKSG93IGRvZXMgdGhlIFdvcmxkIEJhbmsgY2xhc3NpZnkgY291bnRyaWVzPyBbW0xpbmtdKGh0dHBzOi8vZGF0YWhlbHBkZXNrLndvcmxkYmFuay5vcmcva25vd2xlZGdlYmFzZS9hcnRpY2xlcy8zNzg4MzQtaG93LWRvZXMtdGhlLXdvcmxkLWJhbmstY2xhc3NpZnktY291bnRyaWVzKV0KCldvcmxkIEJhbmsgR3JvdXAgY291bnRyeSBjbGFzc2lmaWNhdGlvbnMgYnkgaW5jb21lIGxldmVsIGZvciBGWTI0IChKdWx5IDEsIDIwMjMtIEp1bmUgMzAsIDIwMjQpIFtbTGlua10oaHR0cHM6Ly9ibG9ncy53b3JsZGJhbmsub3JnL29wZW5kYXRhL25ldy13b3JsZC1iYW5rLWdyb3VwLWNvdW50cnktY2xhc3NpZmljYXRpb25zLWluY29tZS1sZXZlbC1meTI0KV0KCioqT3BlcmF0aW9uYWwgbGVuZGluZyBjYXRlZ29yaWVzKioKCkVjb25vbWllcyBhcmUgYWxzbyBkaXZpZGVkIGludG8gSURBLCBJQlJELCBhbmQgQmxlbmTCoGNhdGVnb3JpZXMgYmFzZWQgb24gdGhlwqBbb3BlcmF0aW9uYWwgcG9saWNpZXNdKGh0dHBzOi8vcG9saWNpZXMud29ybGRiYW5rLm9yZy9zaXRlcy9wcGYzL1BhZ2VzL01hbnVhbHMvT3BlcmF0aW9uYWwlMjBNYW51YWwuYXNweCAiTGluazogaHR0cHM6Ly9wb2xpY2llcy53b3JsZGJhbmsub3JnL3NpdGVzL3BwZjMvUGFnZXMvTWFudWFscy9PcGVyYXRpb25hbCUyME1hbnVhbC5hc3B4IinCoG9mIHRoZSBXb3JsZCBCYW5rLlsgXShodHRwOi8vaWRhLndvcmxkYmFuay5vcmcvYWJvdXQvd2hhdC1pZGEpW0ludGVybmF0aW9uYWwgRGV2ZWxvcG1lbnQgQXNzb2NpYXRpb27CoF0oaHR0cDovL2lkYS53b3JsZGJhbmsub3JnL2Fib3V0L3doYXQtaWRhICJMaW5rOiBodHRwOi8vaWRhLndvcmxkYmFuay5vcmcvYWJvdXQvd2hhdC1pZGEiKShJREEpIGNvdW50cmllcyBhcmUgdGhvc2Ugd2l0aCBsb3cgcGVyIGNhcGl0YSBpbmNvbWVzIHRoYXQgbGFjayB0aGUgZmluYW5jaWFsIGFiaWxpdHkgdG8gYm9ycm93IGZyb20gdGhlwqBbSW50ZXJuYXRpb25hbCBCYW5rIGZvciBSZWNvbnN0cnVjdGlvbiBhbmQgRGV2ZWxvcG1lbnRdKGh0dHA6Ly9nby53b3JsZGJhbmsub3JnL1NEVUhWR0U1UzAgIkxpbms6IGh0dHA6Ly9nby53b3JsZGJhbmsub3JnL1NEVUhWR0U1UzAiKcKgKElCUkQpLiBCbGVuZCBjb3VudHJpZXMgYXJlIGVsaWdpYmxlIGZvciBJREEgbG9hbnMgYnV0IGFyZSBhbHNvIGVsaWdpYmxlIGZvciBJQlJEIGxvYW5zIGJlY2F1c2UgdGhleSBhcmUgZmluYW5jaWFsbHkgY3JlZGl0d29ydGh5LgoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiBmaWx0ZXIoY291bnRyeSA9PSAiQ2hpbmEiKSB8PiBzZWxlY3QoY291bnRyeSwgeWVhciwgaW5jb21lLCBsZW5kaW5nKQpgYGAKCiMjIyDnt4/kurrlj6MKCue3j+S6uuWPo+OAgFBvcHVsYXRpb24sIHRvdGFs77yaU1AuUE9QLlRPVEwgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU1AuUE9QLlRPVEwpXQoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoY291bnRyeSA9PSAiV29ybGQiKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHBvcCkpICsgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gIuS4lueVjOOBruS6uuWPoyIpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoY291bnRyeSA9PSAiSmFwYW4iKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHBvcCkpICsgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAi5pel5pys44Gu5Lq65Y+jIikKYGBgCgpgYGB7cn0KQ09VTlRSWSA8LSAiR2VybWFueSIKZGZfcG9wIHw+IGZpbHRlcihjb3VudHJ5ID09ICJGcmFuY2UiKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHBvcCkpICsgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAi44OJ44Kk44OE44Gu5Lq65Y+jIikKYGBgCgpgYGB7cn0KZGZfcG9wIHw+IGZpbHRlcighKGlzbzJjICVpbiUgUkVHSU9OKSkgfD4gZmlsdGVyKHllYXIgPT0gMjAyMikgfD4gCiAgYXJyYW5nZShkZXNjKHBvcCkpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoIShpc28yYyAlaW4lIFJFR0lPTikpIHw+IGZpbHRlcih5ZWFyID09IDIwMjIpIHw+IAogIGFycmFuZ2UoZGVzYyhwb3ApKSB8PiBzbGljZV9oZWFkKG49MTApCmBgYAoKYGBge3J9CnBvcF90b3AxMSA8LSBkZl9wb3AgfD4gZmlsdGVyKCEoaXNvMmMgJWluJSBSRUdJT04pKSB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiAKICBhcnJhbmdlKGRlc2MocG9wKSkgfD4gc2xpY2VfaGVhZChuPTExKSB8PiBwdWxsKGlzbzJjKQpwb3BfdG9wMTEKZHB1dChwb3BfdG9wMTEpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoaXNvMmMgJWluJSBwb3BfdG9wMTEpIHw+CiAgZ2dwbG90KGFlcyh5ZWFyLCBwb3AsIGNvbG9yID0gaXNvMmMpKSArIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoY291bnRyeSAlaW4lIGMoIlNvdXRoIEFzaWEiLCAiRXVyb3BlICYgQ2VudHJhbCBBc2lhIiwgIk1pZGRsZSBFYXN0ICYgTm9ydGggQWZyaWNhIiwgCiJFYXN0IEFzaWEgJiBQYWNpZmljIiwgIlN1Yi1TYWhhcmFuIEFmcmljYSIsICJMYXRpbiBBbWVyaWNhICYgQ2FyaWJiZWFuIiwgIk5vcnRoIEFtZXJpY2EiKSkgfD4KICBnZ3Bsb3QoYWVzKHllYXIsIHBvcCwgY29sb3IgPSBjb3VudHJ5KSkgKyBnZW9tX2xpbmUoKQpgYGAKCmBgYHtyfQpkZl9wb3AgfD4gZmlsdGVyKGNvdW50cnkgJWluJSBjKCJTb3V0aCBBc2lhIiwgIkV1cm9wZSAmIENlbnRyYWwgQXNpYSIsICJNaWRkbGUgRWFzdCAmIE5vcnRoIEFmcmljYSIsIAoiRWFzdCBBc2lhICYgUGFjaWZpYyIsICJTdWItU2FoYXJhbiBBZnJpY2EiLCAiTGF0aW4gQW1lcmljYSAmIENhcmliYmVhbiIsICJOb3J0aCBBbWVyaWNhIikpIHw+IAogIGRpc3RpbmN0KGlzbzJjKSB8PiBwdWxsKCkgfD4gZHB1dCgpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoY291bnRyeSAlaW4lIGMoIlNvdXRoIEFzaWEiLCAiRXVyb3BlICYgQ2VudHJhbCBBc2lhIiwgIk1pZGRsZSBFYXN0ICYgTm9ydGggQWZyaWNhIiwgCiJFYXN0IEFzaWEgJiBQYWNpZmljIiwgIlN1Yi1TYWhhcmFuIEFmcmljYSIsICJMYXRpbiBBbWVyaWNhICYgQ2FyaWJiZWFuIiwgIk5vcnRoIEFtZXJpY2EiKSkgfD4gZmlsdGVyKHllYXIgPT0gMjAyMikgfD4gYXJyYW5nZShkZXNjKHBvcCkpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoaXNvMmMgJWluJSBwb3BfdG9wMTEpIHw+IAogIGZpbHRlcighKGlzbzJjICVpbiUgYygiQ04iLCAiSU4iKSkpIHw+IAogIGdncGxvdChhZXMoeWVhciwgcG9wLCBjb2xvciA9IGNvdW50cnkpKSArIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CmRmX3BvcCB8PiBmaWx0ZXIoaXNvMmMgJWluJSBwb3BfdG9wMTEpIHw+IAogIGZpbHRlcighKGlzbzJjICVpbiUgYygiQ04iLCAiSU4iKSkpIHw+IAogIGdncGxvdChhZXMoeWVhciwgcG9wLCBjb2xvciA9IGZhY3Rvcihpc28yYywgbGV2ZWxzID0gcG9wX3RvcDExKSkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKGNvbG9yID0gImlzbzJjIikKYGBgCgojIyMg5Ye655Sf546H44Go5q275Lqh546HCgrlh7rnlJ/njofvvIjljYPkurrvvIlCaXJ0aCByYXRlLCBjcnVkZSAocGVyIDEsMDAwIHBlb3BsZSnvvJpTUC5EWU4uQ0JSVC5JTiBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TUC5EWU4uQ0JSVC5JTildCgrmrbvkuqHnjofvvIjljYPkurrvvIlEZWF0aCByYXRlLCBjcnVkZSAocGVyIDEsMDAwIHBlb3BsZSnvvJpTUC5EWU4uQ0RSVC5JTiBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TUC5EWU4uQ0RSVC5JTildCgpgYGB7cn0KZGZfcG9wX2xvbmcgfD4gZmlsdGVyKG5hbWUgJWluJSBjKCJiaXJ0aF9yYXRlIiwgImRlYXRoX3JhdGUiKSkgfD4KICBmaWx0ZXIoY291bnRyeSA9PSAiV29ybGQiKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2wgPSBuYW1lKSkgKyBnZW9tX2xpbmUoKQpgYGAKCmBgYHtyfQpkZl9wb3BfbG9uZyB8PiBmaWx0ZXIobmFtZSAlaW4lIGMoImJpcnRoX3JhdGUiLCAiZGVhdGhfcmF0ZSIpKSB8PgogIGZpbHRlcihpc28yYyAlaW4lIGMoIkJEIiwgIkJSIiwgIkNOIiwgIklEIiwgIk5HIiwgIkpQIikpIHw+IAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbCA9IGNvdW50cnksIGxpbmV0eXBlID0gbmFtZSkpICsgCiAgZ2VvbV9saW5lKCkKYGBgCgpgYGB7cn0KZGZfcG9wX2xvbmcgfD4gZmlsdGVyKG5hbWUgJWluJSBjKCJiaXJ0aF9yYXRlIiwgImRlYXRoX3JhdGUiKSkgfD4KICBmaWx0ZXIoaXNvMmMgJWluJSBjKCJaNCIsICJaNyIsICJaSiIsICJaUSIsICJYVSIsICI4UyIsICJaRyIpKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2wgPSBjb3VudHJ5LCBsaW5ldHlwZSA9IG5hbWUpKSArIAogIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiAKICBmaWx0ZXIoIShpc28yYyAlaW4lIFJFR0lPTikpIHw+IGZpbHRlcih5ZWFyID09IDIwMjApIHw+IAogIGZpbHRlcighKGluY29tZSAlaW4lIGMoTkEsICJOb3QgY2xhc3NpZmllZCIpKSkgfD4KICBkcm9wX25hKGJpcnRoX3JhdGUsIGRlYXRoX3JhdGUpIHw+CiAgZ2dwbG90KGFlcyhiaXJ0aF9yYXRlLGRlYXRoX3JhdGUsY29sPWluY29tZSkpICsgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiAKICBmaWx0ZXIoIShpc28yYyAlaW4lIFJFR0lPTikpIHw+IAogIGZpbHRlcih5ZWFyICVpbiUgYygxOTYwLCAxOTkwLCAyMDIwKSkgfD4gCiAgZmlsdGVyKCEoaW5jb21lICVpbiUgYyhOQSwgIk5vdCBjbGFzc2lmaWVkIikpKSB8PgogIGRyb3BfbmEoYmlydGhfcmF0ZSwgZGVhdGhfcmF0ZSkgfD4KICBnZ3Bsb3QoYWVzKGJpcnRoX3JhdGUsZGVhdGhfcmF0ZSxjb2w9aW5jb21lKSkgKyBnZW9tX3BvaW50KCkgKyAKICBmYWNldF93cmFwKH4geWVhcikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGxhYnMoY29sID0gIiIpCmBgYAoKR29vZ2xlIFB1YmxpYyBEYXRhIEV4cGxvcmVyOiBbTGlua10oaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9wdWJsaWNkYXRhL2V4cGxvcmU/ZHM9ZDVibmNwcGpvZjhmOV8mY3R5cGU9YiZzdHJhaWw9ZmFsc2UmYmNzPWQmbnNlbG09cyZtZXRfeT1zcF9keW5fY2RydF9pbiZzY2FsZV95PWxpbiZpbmRfeT1mYWxzZSZtZXRfeD1TUF9EWU5fQ0JSVF9JTiZzY2FsZV94PWxpbiZpbmRfeD1mYWxzZSZkaW1wX2M9Y291bnRyeTpyZWdpb24maWZkaW09Y291bnRyeSZ0dW5pdD1ZJnBpdD0xNTEyNDg2MDAwMDAwJmluZD1mYWxzZSZpY2ZnKQoKIyMjIOaJtumkiuWutuaXj+OBruWKtOWDjeS6uuWPo+OBq+WvvuOBmeOCi+WJsuWQiAoK6Iul5bm05Yq05YON5Lq65Y+j546H44CAQWdlIGRlcGVuZGVuY3kgcmF0aW8sIHlvdW5nICglIG9mIHdvcmtpbmctYWdlIHBvcHVsYXRpb24p77yaU1AuUE9QLkRQTkQuWUcgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU1AuUE9QLkRQTkQuWUcpXQoKQWdlIGRlcGVuZGVuY3kgcmF0aW8sIHlvdW5nLCBpcyB0aGUgcmF0aW8gb2YgeW91bmdlciBkZXBlbmRlbnRzLS1wZW9wbGUgeW91bmdlciB0aGFuIDE1LS10byB0aGUgd29ya2luZy1hZ2UgcG9wdWxhdGlvbi0tdGhvc2UgYWdlcyAxNS02NC4gRGF0YSBhcmUgc2hvd24gYXMgdGhlIHByb3BvcnRpb24gb2YgZGVwZW5kZW50cyBwZXIgMTAwIHdvcmtpbmctYWdlIHBvcHVsYXRpb24uCgrlubTpvaLliKXmibbppIrmr5TnjofvvIjoi6XlubTvvInjga/jgIExNeats+acqua6gOOBruaJtumkiuWutuaXj+OBruOAgTE15q2z44GL44KJNjTmrbPjgb7jgafjga7nlJ/nlKPlubTpvaLkurrlj6Pjgavlr77jgZnjgovmr5TnjofjgafjgYLjgovjgILjg4fjg7zjgr/jga/jgIHnlJ/nlKPlubTpvaLkurrlj6MxMDDkurrlvZPjgZ/jgorjga7mibbppIrlrrbml4/jga7libLlkIjjgafnpLrjgZXjgozjgabjgYTjgovjgIIKCumrmOm9ouiAheWKtOWDjeS6uuWPo+eOh+OAgEFnZSBkZXBlbmRlbmN5IHJhdGlvLCBvbGQgKCUgb2Ygd29ya2luZy1hZ2UgcG9wdWxhdGlvbinvvJpTUC5QT1AuRFBORC5PTCBbW0xpbmsgdG8gTWV0YWRhdGFdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L2hlYWx0aC1udXRyaXRpb24tYW5kLXBvcHVsYXRpb24tc3RhdGlzdGljcy9zZXJpZXMvU1AuUE9QLkRQTkQuT0wpXQoKQWdlIGRlcGVuZGVuY3kgcmF0aW8sIG9sZCwgaXMgdGhlIHJhdGlvIG9mIG9sZGVyIGRlcGVuZGVudHMtLXBlb3BsZSBvbGRlciB0aGFuIDY0LS10byB0aGUgd29ya2luZy1hZ2UgcG9wdWxhdGlvbi0tdGhvc2UgYWdlcyAxNS02NC4gRGF0YSBhcmUgc2hvd24gYXMgdGhlIHByb3BvcnRpb24gb2YgZGVwZW5kZW50cyBwZXIgMTAwIHdvcmtpbmctYWdlIHBvcHVsYXRpb24uCgrlubTpvaLliKXmibbppIrmr5TnjofvvIjpq5jpvaLvvInjga/jgIHnlJ/nlKPlubTpvaLkurrlj6PvvIgxNe+9njY05q2z77yJ44Gr5a++44GZ44KL6auY6b2i5om26aSK5a625peP77yINjTmrbPku6XkuIrvvInjga7mr5TnjofjgILjg4fjg7zjgr/jga/jgIHnlJ/nlKPlubTpvaLkurrlj6MxMDDkurrlvZPjgZ/jgorjga7mibbppIrlrrbml4/jga7libLlkIjjgafnpLrjgZXjgozjgabjgYTjgovjgIIKCmBgYHtyfQpkZl9wb3BfbG9uZyB8PiBmaWx0ZXIobmFtZSAlaW4lIGMoInlvdW5nIiwgIm9sZCIpKSB8PgogIGZpbHRlcihjb3VudHJ5ID09ICJXb3JsZCIpIHw+IAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbCA9IG5hbWUpKSArIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CmRmX3BvcF9sb25nIHw+IGZpbHRlcihuYW1lICVpbiUgYygieW91bmciLCAib2xkIikpIHw+CiAgZmlsdGVyKGlzbzJjICVpbiUgYygiQkQiLCAiQlIiLCAiQ04iLCAiSUQiLCAiTkciLCAiSlAiKSkgfD4gCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sID0gY291bnRyeSwgbGluZXR5cGUgPSBuYW1lKSkgKyAKICBnZW9tX2xpbmUoKQpgYGAKCmBgYHtyfQpkZl9wb3BfZXh0cmEgfD4gCiAgZmlsdGVyKCEoaXNvMmMgJWluJSBSRUdJT04pKSB8PiBmaWx0ZXIoeWVhciA9PSAyMDIwKSB8PiAKICBmaWx0ZXIoIShpbmNvbWUgJWluJSBjKE5BLCAiTm90IGNsYXNzaWZpZWQiKSkpIHw+CiAgZHJvcF9uYSh5b3VuZywgb2xkKSB8PgogIGdncGxvdChhZXMoeW91bmcsIG9sZCwgY29sPWluY29tZSkpICsgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9CmRmX3BvcF9leHRyYSB8PiAKICBmaWx0ZXIocmVnaW9uID09ICJTdWItU2FoYXJhbiBBZnJpY2EiKSB8PiBmaWx0ZXIoeWVhciA9PSAyMDIwKSB8PiAKICBkcm9wX25hKHlvdW5nLCBvbGQpIHw+CiAgZ2dwbG90KGFlcyh5b3VuZywgb2xkLCBjb2w9aW5jb21lKSkgKyBnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KZGZfcG9wX2xvbmcgfD4gZmlsdGVyKG5hbWUgJWluJSBjKCJ5b3VuZyIsICJvbGQiKSkgfD4KICBmaWx0ZXIoaXNvMmMgJWluJSBjKCJVUyIsICJHQiIsICJDTiIsICJERSIsICJGUiIsICJKUCIsICJJTiIpKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2wgPSBjb3VudHJ5LCBsaW5ldHlwZSA9IG5hbWUpKSArIAogIGdlb21fbGluZSgpCmBgYAoKYGBge3J9CmRmX3BvcF9sb25nIHw+IGZpbHRlcihuYW1lICVpbiUgYygieW91bmciLCAib2xkIikpIHw+CiAgZmlsdGVyKGNvdW50cnkgJWluJSBjKCJTb3V0aCBBc2lhIiwgIkV1cm9wZSAmIENlbnRyYWwgQXNpYSIsICJNaWRkbGUgRWFzdCAmIE5vcnRoIEFmcmljYSIsIAoiRWFzdCBBc2lhICYgUGFjaWZpYyIsICJTdWItU2FoYXJhbiBBZnJpY2EiLCAiTGF0aW4gQW1lcmljYSAmIENhcmliYmVhbiIsICJOb3J0aCBBbWVyaWNhIikpIHw+IAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbCA9IGNvdW50cnksIGxpbmV0eXBlID0gbmFtZSkpICsgCiAgZ2VvbV9saW5lKCkgKyBsYWJzKHRpdGxlID0gIuWcsOWfn+WIpeOBruWKtOWDjeS6uuWPo+OBq+WvvuOBmeOCi+mrmOm9ouODu+iLpeW5tOaJtumkiueOh++8iO+8he+8iSIsIAogICAgICAgc3VidGl0bGUgPSAi5a6f57ea77ya6auY6b2i6ICF44CB54K557ea77ya6Iul5bm06ICFIiwgeCA9ICIiLCBjb2wgPSAiIiwgbGluZXR5cGUgPSAiIikKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD03fQpkZl9wb3BfbG9uZyB8PiBmaWx0ZXIobmFtZSAlaW4lIGMoInlvdW5nIiwgIm9sZCIpKSB8PgogIGZpbHRlcihjb3VudHJ5ICVpbiUgYygiU291dGggQXNpYSIsICJFdXJvcGUgJiBDZW50cmFsIEFzaWEiLCAiTWlkZGxlIEVhc3QgJiBOb3J0aCBBZnJpY2EiLCAKIkVhc3QgQXNpYSAmIFBhY2lmaWMiLCAiU3ViLVNhaGFyYW4gQWZyaWNhIiwgIkxhdGluIEFtZXJpY2EgJiBDYXJpYmJlYW4iLCAiTm9ydGggQW1lcmljYSIpKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2wgPSBjb3VudHJ5LCBsaW5ldHlwZSA9IG5hbWUpKSArIAogIGdlb21fbGluZSgpICsgZmFjZXRfd3JhcCh+Y291bnRyeSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKHRpdGxlID0gIuWcsOWfn+WIpeOBruWKtOWDjeS6uuWPo+OBq+WvvuOBmeOCi+mrmOm9ouODu+iLpeW5tOaJtumkiueOh++8iO+8he+8iSIsIAogICAgICAgc3VidGl0bGUgPSAi5a6f57ea77ya6auY6b2i6ICF44CB54K557ea77ya6Iul5bm06ICFIiwgeCA9ICIiLCB5ID0gIiIpCmBgYAoKRGVmYXVsdCBpc8KgKipmaWcuKirCoCoqd2lkdGggPSA3IGFuZCBmaWcuKirCoCoqaGVpZ2h0ID0gNSoqCgpgYGB7cn0KZGZfcG9wX2xvbmcgfD4gZmlsdGVyKG5hbWUgJWluJSBjKCJ5b3VuZyIsICJvbGQiKSkgfD4KICBmaWx0ZXIoY291bnRyeSAlaW4lIGMoIlNvdXRoIEFzaWEiLCAiRXVyb3BlICYgQ2VudHJhbCBBc2lhIiwgIk1pZGRsZSBFYXN0ICYgTm9ydGggQWZyaWNhIiwgCiJFYXN0IEFzaWEgJiBQYWNpZmljIiwgIlN1Yi1TYWhhcmFuIEFmcmljYSIsICJMYXRpbiBBbWVyaWNhICYgQ2FyaWJiZWFuIiwgIk5vcnRoIEFtZXJpY2EiKSkgfD4gCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sID0gY291bnRyeSwgbGluZXR5cGUgPSBuYW1lKSkgKyAKICBnZW9tX2xpbmUoKSArIGZhY2V0X3dyYXAofmNvdW50cnksIDIsNCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKHRpdGxlID0gIuWcsOWfn+WIpeOBruWKtOWDjeS6uuWPo+OBq+WvvuOBmeOCi+mrmOm9ouODu+iLpeW5tOaJtumkiueOh++8iO+8he+8iSIsIAogICAgICAgc3VidGl0bGUgPSAi5a6f57ea77ya6auY6b2i6ICF44CB54K557ea77ya6Iul5bm06ICFIiwgeCA9ICIiLCB5ID0gIiIpCmBgYAo=