世界開発指標(World Development Indicators)[Link]
貧困と不平等(Poverty and Inequality)
所得または消費の分配(Distribution of income or
consumption)
GINI 指数 (世界銀行推計):SI.POV.GINI [Link]
下位 10% が占める所得シェア:SI.DST.FRST.10 [Link]
下位 20% が占める所得シェア:SI.DST.FRST.20 [Link]
2番目の 20% が占める収入シェア:SI.DST.02ND.20 [Link]
3番目の 20% が占める収入シェア :SI.DST.03RD.20 [Link]
4番目の 20% が占める収入シェア:SI.DST.04TH.20 [Link]
上位 20% が占める収入シェア:SI.DST.05TH.20 [Link]
上位 10% が占める収入シェア:SI.DST.10TH.10 [Link]
データの読み込み
df_gini <- WDI(indicator = c(gini = "SI.POV.GINI",
`0-10` = "SI.DST.FRST.10",
`0-20` = "SI.DST.FRST.20",
`20-40` = "SI.DST.02ND.20",
`40-60` = "SI.DST.03RD.20",
`60-80` = "SI.DST.04TH.20",
`80-100` = "SI.DST.05TH.20",
`90-100` = "SI.DST.10TH.10"))
保存と読み込み
何度もダウンロードしなくて良いように、保存したものを読み込みます。
write_csv(df_gini, "data/gini.csv")
df_gini <- read_csv("data/gini.csv")
Rows: 16758 Columns: 12── Column specification ─────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): country, iso2c, iso3c
dbl (9): year, gini, 0-10, 0-20, 20-40, 40-60, 60-80, 80-100, 90-100
ℹ 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.
gini が NA ではない値のもののみ表示します
df_gini |> drop_na(gini)
整えられた(tidy)データ
階級(levels)を変数として扱うために、このように変形しました。
どのくらい GINI のデータがあるか確かめる
df_gini |> drop_na(gini) |>
ggplot(aes(year)) + geom_bar()
実際には、次のような計算をして、棒グラフで表示しています。
group_by(year)
年ごとにグループとする
summarize(n = n())
それぞれのグループごとのデータを数えます。直前に、drop_na(gini)
としてあるので、gini
が NA
ではないデータの数を数えています。
棒グラフ:ggplot(aes(year, n)) + geom_col()
すなわち、次のものと同じです。
df_gini |> group_by(year) |> drop_na(gini) |>
summarize(n = n()) |>
ggplot(aes(year, n)) + geom_col()
実際のデータの個数
df_gini_long |>
group_by(year, levels) |> drop_na(value) |>
summarize(num = n()) |> distinct(year, num) |> arrange(desc(year))
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
2022年にデータが存在する7つの国名を表示
df_gini_long |> filter(year == 2022) |> drop_na(value) |>
distinct(country, gini) |> arrange(gini)
7カ国のいくつかについて調べる
x = levels
とし、y = value
とするところで、Long にした効果が出ています。
COUNTRY_GINI <- "Bhutan"
YEAR_GINI <- 2022
df_gini_long |> filter(levels != "gini") |>
filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
ggplot(aes(levels, value)) + geom_col()
COUNTRY_GINI <- "Bangladesh"
YEAR_GINI <- 2022
df_gini_long |> filter(levels != "gini") |>
filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
ggplot(aes(levels, value)) + geom_col()
COUNTRY_GINI <- "Costa Rica"
YEAR_GINI <- 2022
df_gini_long |> filter(levels != "gini") |>
filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
ggplot(aes(levels, value)) + geom_col()
練習1. Indonesia, El Salvador, Paraguay, Ecuador
のいずれかについてグラフを描いてみましょう。
並べて描いてみましょう
ジニ指数は小さいほうから、Bhutan, Bangladesh, Indonesia, El Salvador,
Paraguay, Equador, Costa Rica でした。
df_gini_long |> filter(year == 2022) |>
filter(levels != "gini") |> drop_na(value) |>
ggplot(aes(levels, value)) + geom_col() + facet_wrap(~country)
考えてみよう
最後下がっているのは正常?
どのように表示するのがよいのだろうか。
これらの図をみて、ジニ指数の大きさについてわかりますか。
このデータから、ジニ指数を計算するには、どうしたら良いのだろうか。
ジニ指数の計算
Derivation of the Lorenz curve and Gini coefficient for global income
in 2011 [リンク]
ジニ指数を計算するために変換
df_gini_calc <- df_gini |>
mutate(`0` = 0, `10` = `0-10`, `20` = `0-20`,
`30` = `0-20`+`20-40`/2, `40` = `0-20` + `20-40`,
`50` = `0-20` + `20-40` + `40-60`/2,
`60` = `0-20` + `20-40` + `40-60`,
`70` = `0-20` + `20-40` + `40-60` + `60-80`/2,
`80` = `0-20` + `20-40` + `40-60` + `60-80`,
`90` = `0-20` + `20-40` + `40-60` + `60-80` + `80-100`-`90-100`,
`100` = 100) |>
select(-c(`0-10`:`90-100`)) # 不必要な部分を消去
df_gini_calc %>% drop_na()
縦長の Long Table に変換
df_gini_calc_long <- df_gini_calc |> pivot_longer(`0`:`100`, names_to = "classes", values_to = "cumulative_share") |> mutate(classes = as.numeric(classes))
df_gini_calc_long %>% drop_na()
確認
df_gini_calc_long |> filter(country == "Bangladesh") |>
filter(year == 2022) |> ggplot() +
geom_line(aes(classes, cumulative_share)) +
geom_segment(aes(x = 0, y = 0, xend = 100, yend = 100), color = 'red') +
scale_x_continuous(breaks = seq(0,100,by=20)) +
scale_y_continuous(breaks = seq(0,100,by=20)) #+
#annotate("text", x = 10, y = 80, label = gini)
4カ国をジニ指数順にならべた棒グラフ
COUNTRIES_GINI <- c("Bhutan", "Bangladesh","Indonesia","Costa Rica")
YEAR_GINI <- 2022
df_gini_long |>
filter(country %in% COUNTRIES_GINI, year == YEAR_GINI) |>
ggplot(aes(levels, value, fill = factor(country, levels = COUNTRIES_GINI))) + geom_col(position = "dodge") + labs(fill = "")
練習2. 7カ国すべてについて、80-100 と、90-100
の部分だけ、表示できないでしょうか。(難:答えは一番下)
2000年のジニ指数と90%以上の割合の相関
df_gini |>
filter(year == 2000) |> drop_na(gini) |>
ggplot(aes(gini, `90-100`)) + geom_point() +
geom_smooth(formula = 'y ~ x', method = "lm")
練習3.
2000年(または他の年の)ジニ指数と80%以上の割合の相関
参考文献
「みんなのデータサイエンス - Data Science for All」[はじめてのデータサイエンス]
- 導入として、GDP(国内総生産)のデータを使って説明しています。
Posit Recipes(旧 Posit Primers): The Basics
対話型の演習サイトの最初 [Link]
Posit Cheat Sheet. 早見表です。印刷して使うために、PDF
も提供しています。[Site
Link]
DataCamp Cheat Sheet: Tidyverse for Biginners.
データサイエンスの教育をしている会社の早見表の一つです。基本が簡単にまとまっています。[Link]
練習2の答え
SEVEN_COUNTRIES <- c("Bhutan", "Bangladesh","Indonesia","El Salvador", "Paraguay", "Equador", "Costa Rica")
YEAR_GINI <- 2022
df_gini_long |>
filter(country %in% SEVEN_COUNTRIES, year == YEAR_GINI) |>
filter(levels %in% c('80-100','90-100')) |>
ggplot(aes(levels, value, fill = factor(country, levels = SEVEN_COUNTRIES))) + geom_col(position = "dodge", col = "black", linewidth = 0.2) + labs(fill = "")
LS0tCnRpdGxlOiAi44K444OL5oyH5pWw44Go5omA5b6X5YiG5biDIgphdXRob3I6ICJILiBTdXp1a2kiCmRhdGU6ICIyMDI05bm0MeaciDnml6UiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0Ci0tLQoKIyMg5LiW55WM6ZaL55m65oyH5qiZ77yIV29ybGQgRGV2ZWxvcG1lbnQgSW5kaWNhdG9yc++8iVtbTGlua10oaHR0cHM6Ly9kYXRhdG9waWNzLndvcmxkYmFuay5vcmcvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy8pXQoKIyMjIyAqKuiyp+WbsOOBqOS4jeW5s+etie+8iFBvdmVydHkgYW5kIEluZXF1YWxpdHnvvIkqKgoKKirmiYDlvpfjgb7jgZ/jga/mtojosrvjga7liIbphY3vvIhEaXN0cmlidXRpb24gb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9u77yJKioKCkdJTkkg5oyH5pWwICjkuJbnlYzpioDooYzmjqjoqIgp77yaU0kuUE9WLkdJTkkgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuUE9WLkdJTkkpXQoK5LiL5L2NIDEwJSDjgYzljaDjgoHjgovmiYDlvpfjgrfjgqfjgqLvvJpTSS5EU1QuRlJTVC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC5GUlNULjEwKV0KCuS4i+S9jSAyMCUg44GM5Y2g44KB44KL5omA5b6X44K344Kn44Ki77yaU0kuRFNULkZSU1QuMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuRlJTVC4yMCldCgoy55Wq55uu44GuIDIwJSDjgYzljaDjgoHjgovlj47lhaXjgrfjgqfjgqLvvJpTSS5EU1QuMDJORC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC4wMk5ELjIwKV0KCjPnlarnm67jga4gMjAlIOOBjOWNoOOCgeOCi+WPjuWFpeOCt+OCp+OCoiDvvJpTSS5EU1QuMDNSRC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMDNSRC4yMCldCgo055Wq55uu44GuIDIwJSDjgYzljaDjgoHjgovlj47lhaXjgrfjgqfjgqLvvJpTSS5EU1QuMDRUSC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC4wNFRILjIwKV0KCuS4iuS9jSAyMCUg44GM5Y2g44KB44KL5Y+O5YWl44K344Kn44Ki77yaU0kuRFNULjA1VEguMjAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjA1VEguMjApXQoK5LiK5L2NIDEwJSDjgYzljaDjgoHjgovlj47lhaXjgrfjgqfjgqLvvJpTSS5EU1QuMTBUSC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMTBUSC4xMCldCgojIyDliY3lm57vvIgxMuaciDE55pel77yJ44Gu5b6p57+SCgotICAg44OR44OD44Kx44O844K477yIUGFja2FnZe+8ieOBruWIqeeUqO+8mgoKICAgIC0gICDjgqTjg7Pjgrnjg4jjg7zjg6vvvIhpbnN0YWxsYXRpb27vvInvvJpUb29scyBcPiBJbnN0YWxsIFBhY2thZ2VzCgogICAgLSAgIOODreODvOODie+8iGxvYWTvvIlgbGlicmFyeSh0aWR5dmVyc2UpOyBsaWJyYXJ5KFdESSk7IGxpYnJhcnkoc2hvd3RleHQpYAoKLSAgIOODh+ODvOOCv+OBruWPluW+l++8mmBXREkoaW5kaWNhdG9yID0gYyhwb3AgPSAiU1AuUE9QLlRPVEwiKSlgCgotICAg54m55a6a44Gu6KGM44Gu5Y+W5b6X77yaYGZpbHRlcigpLCBkcm9wX25hKCksIGRpc3RpbmN0KClgCgotICAg5oqY44KM57ea44Kw44Op44OVCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcG9wKSArIGdlb21fbGluZSgpYAoKICAgIC0gICBgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHBvcCwgY29sID0gY291bnRyeSkgKyBnZW9tX2xpbmUoKWAKCiMjIOS7iuWbnuOBrua8lOe/kuOBruWGheWuuQoKLSAgIOODkeODg+OCseODvOOCuO+8iFBhY2thZ2XvvInjgqTjg7Pjgrnjg4jjg7zjg6vvvIjjgrPjg7Pjg5Tjg6Xjg7zjgr/jgavlhaXjgozjgabjgYrjgY/vvInvvJpgRGVzY1Rvb2xzYAoKLSAgIOODkeODg+OCseODvOOCuOOBruODreODvOODie+8iOOBmeOBkOS9v+OBiOOCi+OCiOOBhuOBq+OBmeOCi++8ie+8mmB0aWR5dmVyc2VgLCBgV0RJYCwgYERlc2NUb29sc2AKCi0gICDjg4fjg7zjgr/jga7lj5blvpfvvJpgV0RJKClgCgotICAg54m55a6a44Gu5p2h5Lu244Gr44GC44Gj44Gf6KGM44KS6YG45oqe77yaYGZpbHRlcigpYAoKLSAgIOaWsOOBl+OBhOWIl+OCkuS7luOBruWIl+OBi+OCieioiOeul+OBl+OBpuWKoOOBiOOCi++8mmBtdXRhdGUoKWAKCi0gICDpoIbnlarjgavjgIHlpInlvaLjgIHoppbopprljJbjgarjganjgpLjgZnjgovjgZ/jgoHjga7jg5HjgqTjg5fvvJpgfD5gIO+8iOOBvuOBn+OBr+OAgWAlPiVg77yJCgotICAg44OS44K544OI44Kw44Op44Og77yI5bqm5pWw5YiG5biD77yJ77yaZ2dwbG90KC4uLikgKyBnZW9tX2hpc3RvZ3JhbSgpCgotICAg5qOS44Kw44Op44OV77yaZ2dwbG90KC4uLikgKyBnZW9tX2NvbCgpLCBnZ3Bsb3QoLi4uKSArIGdlb21fYmFyKCkKCiMjIyDmjIfmqJnjgavjgaTjgYTjgaYKCuS9leOBruODh+ODvOOCv+OBi+OAgeWkieaVsOOBr+OBqeOBruOCiOOBhuOBquOCguOBruOBi+OAgeWumue+qeOBr++8n+OBquOBqeOAgeeiuuiqjeOAguODh+ODvOOCv+OBrlVSTCDjgpLoqJjpjLLjgZnjgovjga7jgoLjgZ/jgYTjgZvjgaTjgIIKCi0gICBHSU5JIGluZGV4IChXb3JsZCBCYW5rIGVzdGltYXRlKe+8m1NJLlBPVi5HSU5JIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NJLlBPVi5HSU5JKV0KCiAgICAtICAgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgZXh0ZW50IHRvIHdoaWNoIHRoZSBkaXN0cmlidXRpb24gb2YgaW5jb21lIChvciwgaW4gc29tZSBjYXNlcywgY29uc3VtcHRpb24gZXhwZW5kaXR1cmUpIGFtb25nIGluZGl2aWR1YWxzIG9yIGhvdXNlaG9sZHMgd2l0aGluIGFuIGVjb25vbXkgZGV2aWF0ZXMgZnJvbSBhIHBlcmZlY3RseSBlcXVhbCBkaXN0cmlidXRpb24uIEEgTG9yZW56IGN1cnZlIHBsb3RzIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzIG9mIHRvdGFsIGluY29tZSByZWNlaXZlZCBhZ2FpbnN0IHRoZSBjdW11bGF0aXZlIG51bWJlciBvZiByZWNpcGllbnRzLCBzdGFydGluZyB3aXRoIHRoZSBwb29yZXN0IGluZGl2aWR1YWwgb3IgaG91c2Vob2xkLiBUaGUgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgYXJlYSBiZXR3ZWVuIHRoZSBMb3JlbnogY3VydmUgYW5kIGEgaHlwb3RoZXRpY2FsIGxpbmUgb2YgYWJzb2x1dGUgZXF1YWxpdHksIGV4cHJlc3NlZCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIG1heGltdW0gYXJlYSB1bmRlciB0aGUgbGluZS4gVGh1cyBhIEdpbmkgaW5kZXggb2YgMCByZXByZXNlbnRzIHBlcmZlY3QgZXF1YWxpdHksIHdoaWxlIGFuIGluZGV4IG9mIDEwMCBpbXBsaWVzIHBlcmZlY3QgaW5lcXVhbGl0eS4KCiAgICAtICAg44K444OL5oyH5pWw44Gv44CB57WM5riI5YaF44Gu5YCL5Lq644G+44Gf44Gv5LiW5biv6ZaT44Gu5omA5b6X77yI44G+44Gf44Gv5aC05ZCI44Gr44KI44Gj44Gm44Gv5raI6LK75pSv5Ye677yJ44Gu5YiG5biD44GM44CB5a6M5YWo44Gr5bmz562J44Gq5YiG5biD44GL44KJ44Gp44Gu56iL5bqm6YC46ISx44GX44Gm44GE44KL44GL44KS5ris5a6a44GZ44KL44CC44Ot44O844Os44Oz44OE5puy57ea44Gv44CB5pyA44KC6LKn44GX44GE5YCL5Lq644G+44Gf44Gv5LiW5biv44GL44KJ5aeL44G+44KK44CB5Y+X57Wm6ICF44Gu57Sv56mN5pWw44Gr5a++44GZ44KL57eP5omA5b6X44Gu57Sv56mN5Ymy5ZCI44KS44OX44Ot44OD44OI44GX44Gf44KC44Gu44Gn44GC44KL44CC44K444OL5oyH5pWw44Gv44CB44Ot44O844Os44Oz44OE5puy57ea44Go57W25a++55qE5bmz562J44Gu5Luu5oOz57ea44Go44Gu6ZaT44Gu6Z2i56mN44KS5ris5a6a44GZ44KL44KC44Gu44Gn44CB57ea44Gu5LiL44Gu5pyA5aSn6Z2i56mN44Gu55m+5YiG546H44Gn6KGo44GV44KM44KL44CC44GX44Gf44GM44Gj44Gm44CB44K444OL5oyH5pWwMOOBr+WujOWFqOOBquW5s+etieOCkuihqOOBl+OAgeaMh+aVsDEwMOOBr+WujOWFqOOBquS4jeW5s+etieOCkuaEj+WRs+OBmeOCi+OAggoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGxvd2VzdCAxMCXvvJpTSS5EU1QuRlJTVC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC5GUlNULjEwKV0KCiAgICAtICAgUGVyY2VudGFnZSBzaGFyZSBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb24gaXMgdGhlIHNoYXJlIHRoYXQgYWNjcnVlcyB0byBzdWJncm91cHMgb2YgcG9wdWxhdGlvbiBpbmRpY2F0ZWQgYnkgZGVjaWxlcyBvciBxdWludGlsZXMuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBruWJsuWQiOOBr+OAgeODh+OCt+ODq+OBvuOBn+OBr+S6lOWIhuS9jeaVsOOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+eZuueUn+OBmeOCi+WJsuWQiOOBp+OBmeOAggoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGxvd2VzdCAyMCXvvJpTSS5EU1QuRlJTVC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC5GUlNULjIwKV0KCiAgICAtICAgUGVyY2VudGFnZSBzaGFyZSBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb24gaXMgdGhlIHNoYXJlIHRoYXQgYWNjcnVlcyB0byBzdWJncm91cHMgb2YgcG9wdWxhdGlvbiBpbmRpY2F0ZWQgYnkgZGVjaWxlcyBvciBxdWludGlsZXMuIFBlcmNlbnRhZ2Ugc2hhcmVzIGJ5IHF1aW50aWxlIG1heSBub3Qgc3VtIHRvIDEwMCBiZWNhdXNlIG9mIHJvdW5kaW5nLgoKICAgIC0gICDmiYDlvpfjgb7jgZ/jga/mtojosrvjga7libLlkIjjga/jgIHjg4fjgrfjg6vjgb7jgZ/jga/kupTliIbkvY3mlbDjgafnpLrjgZXjgozjgovkurrlj6Pjga7jgrXjg5bjgrDjg6vjg7zjg5fjgavnmbrnlJ/jgZnjgovlibLlkIjjgafjgZnjgILkupTliIbkvY3mlbDjgavjgojjgovjgrfjgqfjgqLjga7libLlkIjjga/jgIHlm5vmjajkupTlhaXjga7jgZ/jgoExMDDjgavjgarjgonjgarjgYTloLTlkIjjgYzjgYLjgorjgb7jgZnjgIIoQXBwbGUpCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgc2Vjb25kIDIwJe+8mlNJLkRTVC4wMk5ELjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhYmFuay53b3JsZGJhbmsub3JnL21ldGFkYXRhZ2xvc3Nhcnkvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy9zZXJpZXMvU0kuRFNULjAyTkQuMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBq+WNoOOCgeOCi+WJsuWQiOOBr+OAgTEw5YiG5L2N44G+44Gf44GvNeWIhuS9jeOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+W4sOWxnuOBmeOCi+WJsuWQiOOBp+OBguOCi+OAguWbm+aNqOS6lOWFpeOBrumWouS/guS4iuOAgeS6lOWIhuS9jemajue0muWIpeOBruWJsuWQiOOBruWQiOioiOOBjDEwMOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCi+OAgu+8iERlZXBM77yJCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgdGhpcmQgMjAl77yaU0kuRFNULjAzUkQuMjAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjAzUkQuMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBq+WNoOOCgeOCi+WJsuWQiOOBr+OAgTEw5YiG5L2N44G+44Gf44GvNeWIhuS9jeOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+W4sOWxnuOBmeOCi+WJsuWQiOOBp+OBguOCi+OAguWbm+aNqOS6lOWFpeOBrumWouS/guS4iuOAgeS6lOWIhuS9jemajue0muWIpeOBruWJsuWQiOOBruWQiOioiOOBjDEwMOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCi+OAgu+8iERlZXBM77yJCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgZm91cnRoIDIwJe+8mlNJLkRTVC4wNFRILjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhYmFuay53b3JsZGJhbmsub3JnL21ldGFkYXRhZ2xvc3Nhcnkvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy9zZXJpZXMvU0kuRFNULjA0VEguMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBruWJsuWQiOOBr+OAgeWNgeWIhuS9jeaVsOOBvuOBn+OBr+S6lOWIhuS9jeaVsOOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+eUn+OBmOOCi+WJsuWQiOOBp+OBmeOAguWbm+aNqOS6lOWFpeOBruOBn+OCgeOAgeS6lOWIhuS9jeWIpeOBruWJsuWQiOOBruWQiOioiOOBjCAxMDAg44Gr44Gq44KJ44Gq44GE5aC05ZCI44GM44GC44KK44G+44GZ44CCKEdvb2dsZSkKCi0gICBJbmNvbWUgc2hhcmUgaGVsZCBieSBoaWdoZXN0IDIwJe+8mlNJLkRTVC4wNVRILjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NJLkRTVC4wNVRILjIwKV0KCiAgICAtICAgUGVyY2VudGFnZSBzaGFyZSBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb24gaXMgdGhlIHNoYXJlIHRoYXQgYWNjcnVlcyB0byBzdWJncm91cHMgb2YgcG9wdWxhdGlvbiBpbmRpY2F0ZWQgYnkgZGVjaWxlcyBvciBxdWludGlsZXMuIFBlcmNlbnRhZ2Ugc2hhcmVzIGJ5IHF1aW50aWxlIG1heSBub3Qgc3VtIHRvIDEwMCBiZWNhdXNlIG9mIHJvdW5kaW5nLgoKICAgIC0gICDmiYDlvpfjgb7jgZ/jga/mtojosrvjga7libLlkIjjga/jgIHljYHliIbkvY3mlbDjgb7jgZ/jga/kupTliIbkvY3mlbDjgafnpLrjgZXjgozjgovkurrlj6Pjga7jgrXjg5bjgrDjg6vjg7zjg5fjgavnlJ/jgZjjgovlibLlkIjjgafjgZnjgILlm5vmjajkupTlhaXjga7jgZ/jgoHjgIHkupTliIbkvY3liKXjga7libLlkIjjga7lkIjoqIjjgYwgMTAwIOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCiuOBvuOBmeOAggoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGhpZ2hlc3QgMTAl77yaU0kuRFNULjEwVEguMTAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjEwVEguMTApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4KCiAgICAtICAg5omA5b6X44G+44Gf44Gv5raI6LK744Gu5Ymy5ZCI44Gv44CB5Y2B5YiG5L2N5pWw44G+44Gf44Gv5LqU5YiG5L2N5pWw44Gn56S644GV44KM44KL5Lq65Y+j44Gu44K144OW44Kw44Or44O844OX44Gr55Sf44GY44KL5Ymy5ZCI44Gn44GZ44CCCgojIyDmupblgpkKCuavjuWbniBgdGlkeXZlcnNlYCDjgaggYFdESWAg44GoIGBEZXNjVG9vbHNgIOOCkuS9v+OBhOOBvuOBmeOBi+OCieOAgVIgTm90ZWJvb2sg44Gu5pyA5Yid44Gr44Gv44CB5qyh44Gu44Kz44O844OJ44OB44Oj44Oz44Kv44KS5L2c5oiQ44GX44CB5a6f6KGM77yIUnVu77yJ44GX44G+44GZ44CC44GT44KM44KJ44Gu77yI5qmf6IO944KS5ouh5by144GZ44KL77yJ44OR44OD44Kx44O844K444GM44Kk44Oz44K544OI44O844Or44GV44KM44Gm44GE44Gq44GE5aC05ZCI44Gv44CB44Kk44Oz44K544OI44O844Or44GX44G+44GZ44CCVG9vbHNcPkluc3RhbGwgUGFja2FnZXMgLi4uCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoV0RJKQpsaWJyYXJ5KERlc2NUb29scykKYGBgCgojIyDjg4fjg7zjgr/jga7oqq3jgb/ovrzjgb8KCmBgYHtyIGV2YWwgPSBGQUxTRX0KZGZfZ2luaSA8LSBXREkoaW5kaWNhdG9yID0gYyhnaW5pID0gIlNJLlBPVi5HSU5JIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAwLTEwYCA9ICJTSS5EU1QuRlJTVC4xMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgMC0yMGAgPSAiU0kuRFNULkZSU1QuMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDIwLTQwYCA9ICJTSS5EU1QuMDJORC4yMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgNDAtNjBgID0gIlNJLkRTVC4wM1JELjIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGA2MC04MGAgPSAiU0kuRFNULjA0VEguMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDgwLTEwMGAgPSAiU0kuRFNULjA1VEguMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDkwLTEwMGAgPSAiU0kuRFNULjEwVEguMTAiKSkKYGBgCgoKCiMjIyDkv53lrZjjgajoqq3jgb/ovrzjgb8KCuS9leW6puOCguODgOOCpuODs+ODreODvOODieOBl+OBquOBj+OBpuiJr+OBhOOCiOOBhuOBq+OAgeS/neWtmOOBl+OBn+OCguOBruOCkuiqreOBv+i+vOOBv+OBvuOBmeOAggoKYGBge3IgZXZhbCA9IEZBTFNFfQp3cml0ZV9jc3YoZGZfZ2luaSwgImRhdGEvZ2luaS5jc3YiKQpgYGAKCmBgYHtyfQpkZl9naW5pIDwtIHJlYWRfY3N2KCJkYXRhL2dpbmkuY3N2IikKYGBgCiMjIyDjg4fjg7zjgr/jga7norroqo0KCmBgYHtyfQpkZl9naW5pCmBgYAoKIyMjIGdpbmkg44GMIE5BIOOBp+OBr+OBquOBhOWApOOBruOCguOBruOBruOBv+ihqOekuuOBl+OBvuOBmQoKYGBge3J9CmRmX2dpbmkgfD4gZHJvcF9uYShnaW5pKQpgYGAKCiMjIyDlpInlvaLvvJrlkITpmo7ntJrjga7lgKTjgpLnuKbjgavkuKbjgbnjgIHnuKbplbflvaLlvI/jga7ooajjgavjgZfjgb7jgZnjgIJMb25nIGZvcm1hdAoKYHBpdm90X2xvbmdlcihjb2xzLCBuYW1lc190byA9ICIiLCB2YWx1ZXNfdG8gPSAiIilgIOOBq+OBpOOBhOOBpuOBr+OBhOOBmuOCjOiqrOaYjuOBl+OBvuOBmeOAguOBk+OBk+OBp+OBr+OAgeODrOODmeODq+OBq+WIhuOBkeOCieOCjOOBn+OCguOBruOCkiBsZXZlbHMg44Go44GE44GG5ZCN44Gu5YiX44Gr44Os44OZ44Or44KS44CBdmFsdWUg44Go44GE44GG5ZCN44Gu5YiX44Gr44CB44Gd44Gu5YCk44KS5Lim44G544Gf44KC44Gu44Go44GX44G+44GZ44CCCgpgYGB7cn0KZGZfZ2luaV9sb25nIDwtIGRmX2dpbmkgfD4gCiAgcGl2b3RfbG9uZ2VyKGAwLTEwYDpgOTAtMTAwYCwgbmFtZXNfdG8gPSAibGV2ZWxzIiwgdmFsdWVzX3RvID0gInZhbHVlIikKZGZfZ2luaV9sb25nCmBgYAoKIyMjIOaVtOOBiOOCieOCjOOBn++8iHRpZHnvvInjg4fjg7zjgr8KCi0gICDlkITliJfjga/jgbLjgajjgaTjga7lpInmlbAKCi0gICDlkITooYzjga/jgbLjgajjgaTjga7oprPmuKzlgKQKCumajue0mu+8iGxldmVsc++8ieOCkuWkieaVsOOBqOOBl+OBpuaJseOBhuOBn+OCgeOBq+OAgeOBk+OBruOCiOOBhuOBq+WkieW9ouOBl+OBvuOBl+OBn+OAggoKIVtdKGh0dHBzOi8vaWN1LWhzdXp1a2kuZ2l0aHViLmlvL2RhNHIvZGF0YS90aWR5LTEucG5nKQoKIyMjIOOBqeOBruOBj+OCieOBhCBHSU5JIOOBruODh+ODvOOCv+OBjOOBguOCi+OBi+eiuuOBi+OCgeOCiwoKYGBge3J9CmRmX2dpbmkgfD4gZHJvcF9uYShnaW5pKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIpKSArIGdlb21fYmFyKCkKYGBgCgrlrp/pmpvjgavjga/jgIHmrKHjga7jgojjgYbjgaroqIjnrpfjgpLjgZfjgabjgIHmo5LjgrDjg6njg5XjgafooajnpLrjgZfjgabjgYTjgb7jgZnjgIIKCi0gICBgZ3JvdXBfYnkoeWVhcilgIOW5tOOBlOOBqOOBq+OCsOODq+ODvOODl+OBqOOBmeOCiwoKLSAgIGBzdW1tYXJpemUobiA9IG4oKSlgIOOBneOCjOOBnuOCjOOBruOCsOODq+ODvOODl+OBlOOBqOOBruODh+ODvOOCv+OCkuaVsOOBiOOBvuOBmeOAguebtOWJjeOBq+OAgWBkcm9wX25hKGdpbmkpYCDjgajjgZfjgabjgYLjgovjga7jgafjgIFgZ2luaWAg44GMIE5BIOOBp+OBr+OBquOBhOODh+ODvOOCv+OBruaVsOOCkuaVsOOBiOOBpuOBhOOBvuOBmeOAggoKLSAgIOajkuOCsOODqeODle+8mmBnZ3Bsb3QoYWVzKHllYXIsIG4pKSArIGdlb21fY29sKClgCgrjgZnjgarjgo/jgaHjgIHmrKHjga7jgoLjga7jgajlkIzjgZjjgafjgZnjgIIKCmBgYHtyfQpkZl9naW5pIHw+IGdyb3VwX2J5KHllYXIpIHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgc3VtbWFyaXplKG4gPSBuKCkpIHw+CiAgZ2dwbG90KGFlcyh5ZWFyLCBuKSkgKyBnZW9tX2NvbCgpCmBgYAoKIyMjIOWun+mam+OBruODh+ODvOOCv+OBruWAi+aVsAoKYGBge3J9CmRmX2dpbmlfbG9uZyB8PiAKICBncm91cF9ieSh5ZWFyLCBsZXZlbHMpIHw+IGRyb3BfbmEodmFsdWUpIHw+CiAgc3VtbWFyaXplKG51bSA9IG4oKSkgfD4gZGlzdGluY3QoeWVhciwgbnVtKSB8PiBhcnJhbmdlKGRlc2MoeWVhcikpCmBgYAoKIyMjIDIwMjLlubTjgavjg4fjg7zjgr/jgYzlrZjlnKjjgZnjgos344Gk44Gu5Zu95ZCN44KS6KGo56S6CgpgYGB7cn0KZGZfZ2luaV9sb25nIHw+IGZpbHRlcih5ZWFyID09IDIwMjIpIHw+IGRyb3BfbmEodmFsdWUpIHw+CiAgZGlzdGluY3QoY291bnRyeSwgZ2luaSkgfD4gYXJyYW5nZShnaW5pKQpgYGAKCiMjIyDvvJfjgqvlm73jga7jgYTjgY/jgaTjgYvjgavjgaTjgYTjgaboqr/jgbnjgosKCmB4ID0gbGV2ZWxzYCDjgajjgZfjgIFgeSA9IHZhbHVlYCDjgajjgZnjgovjgajjgZPjgo3jgafjgIFMb25nIOOBq+OBl+OBn+WKueaenOOBjOWHuuOBpuOBhOOBvuOBmeOAggoKYGBge3J9CkNPVU5UUllfR0lOSSA8LSAiQmh1dGFuIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKGxldmVscyAhPSAiZ2luaSIpIHw+CiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgpgYGB7cn0KQ09VTlRSWV9HSU5JIDwtICJCYW5nbGFkZXNoIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKGxldmVscyAhPSAiZ2luaSIpIHw+CiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgpgYGB7cn0KQ09VTlRSWV9HSU5JIDwtICJDb3N0YSBSaWNhIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKGxldmVscyAhPSAiZ2luaSIpIHw+CiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgoqKue3tOe/kjEu44CASW5kb25lc2lhLCBFbCBTYWx2YWRvciwgUGFyYWd1YXksIEVjdWFkb3Ig44Gu44GE44Ga44KM44GL44Gr44Gk44GE44Gm44Kw44Op44OV44KS5o+P44GE44Gm44G/44G+44GX44KH44GG44CCKioKCmBgYHtyfQoKYGBgCgojIyMg5Lim44G544Gm5o+P44GE44Gm44G/44G+44GX44KH44GGCgrjgrjjg4vmjIfmlbDjga/lsI/jgZXjgYTjgbvjgYbjgYvjgonjgIFCaHV0YW4sIEJhbmdsYWRlc2gsIEluZG9uZXNpYSwgRWwgU2FsdmFkb3IsIFBhcmFndWF5LCBFcXVhZG9yLCBDb3N0YSBSaWNhIOOBp+OBl+OBn+OAggoKYGBge3J9CmRmX2dpbmlfbG9uZyB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiAKICBmaWx0ZXIobGV2ZWxzICE9ICJnaW5pIikgfD4gIGRyb3BfbmEodmFsdWUpIHw+CiAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpICsgZmFjZXRfd3JhcCh+Y291bnRyeSkKYGBgCgojIyMg6ICD44GI44Gm44G/44KI44GGCgoxLiAg5pyA5b6M5LiL44GM44Gj44Gm44GE44KL44Gu44Gv5q2j5bi477yfCgoyLiAg44Gp44Gu44KI44GG44Gr6KGo56S644GZ44KL44Gu44GM44KI44GE44Gu44Gg44KN44GG44GL44CCCgozLiAg44GT44KM44KJ44Gu5Zuz44KS44G/44Gm44CB44K444OL5oyH5pWw44Gu5aSn44GN44GV44Gr44Gk44GE44Gm44KP44GL44KK44G+44GZ44GL44CCCgo0LiAg44GT44Gu44OH44O844K/44GL44KJ44CB44K444OL5oyH5pWw44KS6KiI566X44GZ44KL44Gr44Gv44CB44Gp44GG44GX44Gf44KJ6Imv44GE44Gu44Gg44KN44GG44GL44CCCgojIyDjgrjjg4vmjIfmlbDjga7oqIjnrpcKCkRlcml2YXRpb24gb2YgdGhlIExvcmVueiBjdXJ2ZSBhbmQgR2luaSBjb2VmZmljaWVudCBmb3IgZ2xvYmFsIGluY29tZSBpbiAyMDExIFtb44Oq44Oz44KvXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9HaW5pX2NvZWZmaWNpZW50KV0KCiMjIyDjgrjjg4vmjIfmlbDjgpLoqIjnrpfjgZnjgovjgZ/jgoHjgavlpInmj5sKCmBgYHtyfQpkZl9naW5pX2NhbGMgPC0gZGZfZ2luaSB8PiAKICBtdXRhdGUoYDBgID0gMCwgYDEwYCA9IGAwLTEwYCwgYDIwYCA9IGAwLTIwYCwKICAgICAgICAgYDMwYCA9IGAwLTIwYCtgMjAtNDBgLzIsIGA0MGAgPSBgMC0yMGAgKyBgMjAtNDBgLCAKICAgICAgICAgYDUwYCA9IGAwLTIwYCArIGAyMC00MGAgKyBgNDAtNjBgLzIsIAogICAgICAgICBgNjBgID0gYDAtMjBgICsgYDIwLTQwYCArIGA0MC02MGAsIAogICAgICAgICBgNzBgID0gYDAtMjBgICsgYDIwLTQwYCArIGA0MC02MGAgKyBgNjAtODBgLzIsICAKICAgICAgICAgYDgwYCA9IGAwLTIwYCArIGAyMC00MGAgKyBgNDAtNjBgICsgYDYwLTgwYCwgCiAgICAgICAgIGA5MGAgPSBgMC0yMGAgKyBgMjAtNDBgICsgYDQwLTYwYCArIGA2MC04MGAgKyBgODAtMTAwYC1gOTAtMTAwYCwKICAgICAgICAgYDEwMGAgPSAxMDApIHw+CiAgc2VsZWN0KC1jKGAwLTEwYDpgOTAtMTAwYCkpICMg5LiN5b+F6KaB44Gq6YOo5YiG44KS5raI5Y67CmRmX2dpbmlfY2FsYyAlPiUgZHJvcF9uYSgpIApgYGAKCiMjIyDnuKbplbfjga4gTG9uZyBUYWJsZSDjgavlpInmj5sKCmBgYHtyfQpkZl9naW5pX2NhbGNfbG9uZyA8LSBkZl9naW5pX2NhbGMgfD4gIHBpdm90X2xvbmdlcihgMGA6YDEwMGAsIG5hbWVzX3RvID0gImNsYXNzZXMiLCB2YWx1ZXNfdG8gPSAiY3VtdWxhdGl2ZV9zaGFyZSIpIHw+IG11dGF0ZShjbGFzc2VzID0gYXMubnVtZXJpYyhjbGFzc2VzKSkKZGZfZ2luaV9jYWxjX2xvbmcgJT4lIGRyb3BfbmEoKSAKYGBgCgojIyMg56K66KqNCgpgYGB7cn0KZGZfZ2luaV9jYWxjX2xvbmcgfD4gZmlsdGVyKGNvdW50cnkgPT0gIkJhbmdsYWRlc2giKSB8PiAKICBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoY2xhc3NlcywgY3VtdWxhdGl2ZV9zaGFyZSkpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwgeSA9IDAsIHhlbmQgPSAxMDAsIHllbmQgPSAxMDApLCBjb2xvciA9ICdyZWQnKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwxMDAsYnk9MjApKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwxMDAsYnk9MjApKSAjKwogICNhbm5vdGF0ZSgidGV4dCIsIHggPSAxMCwgeSA9IDgwLCBsYWJlbCA9IGdpbmkpCmBgYAoKIyMjIO+8lOOCq+WbveOCkuOCuOODi+aMh+aVsOmghuOBq+OBquOCieOBueOBn+ajkuOCsOODqeODlQoKYGBge3J9CkNPVU5UUklFU19HSU5JIDwtIGMoIkJodXRhbiIsICJCYW5nbGFkZXNoIiwiSW5kb25lc2lhIiwiQ29zdGEgUmljYSIpCllFQVJfR0lOSSA8LSAyMDIyCmRmX2dpbmlfbG9uZyB8PiAKICBmaWx0ZXIoY291bnRyeSAlaW4lIENPVU5UUklFU19HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUsIGZpbGwgPSBmYWN0b3IoY291bnRyeSwgbGV2ZWxzID0gQ09VTlRSSUVTX0dJTkkpKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsgbGFicyhmaWxsID0gIiIpCmBgYAoKKirnt7Tnv5IyLiDvvJfjgqvlm73jgZnjgbnjgabjgavjgaTjgYTjgabjgIE4MC0xMDAg44Go44CBOTAtMTAwIOOBrumDqOWIhuOBoOOBkeOAgeihqOekuuOBp+OBjeOBquOBhOOBp+OBl+OCh+OBhuOBi+OAgu+8iOmbo++8muetlOOBiOOBr+S4gOeVquS4i++8iSoqCgpgYGB7cn0KCmBgYAoKKioyMDAw5bm044Gu44K444OL5oyH5pWw44GoOTDvvIXku6XkuIrjga7libLlkIjjga7nm7jplqIqKgoKYGBge3J9CmRmX2dpbmkgfD4gCiAgZmlsdGVyKHllYXIgPT0gMjAwMCkgfD4gZHJvcF9uYShnaW5pKSB8PgogIGdncGxvdChhZXMoZ2luaSwgYDkwLTEwMGApKSArIGdlb21fcG9pbnQoKSArIAogIGdlb21fc21vb3RoKGZvcm11bGEgPSAneSB+IHgnLCBtZXRob2QgPSAibG0iKQpgYGAKCioq57e057+SMy4gMjAwMOW5tO+8iOOBvuOBn+OBr+S7luOBruW5tOOBru+8ieOCuOODi+aMh+aVsOOBqDgw77yF5Lul5LiK44Gu5Ymy5ZCI44Gu55u46ZaiKioKCmBgYHtyfQoKYGBgCgojIyDlvqnnv5IKCi0gICDjg5Hjg4PjgrHjg7zjgrjvvIhQYWNrYWdl77yJ44Gu5Yip55So77yaCgogICAgLSAgIOOCpOODs+OCueODiOODvOODq++8iGluc3RhbGxhdGlvbu+8ie+8mlRvb2xzIFw+IEluc3RhbGwgUGFja2FnZXMKCiAgICAtICAg44Ot44O844OJ77yIbG9hZO+8iWBsaWJyYXJ5KHRpZHl2ZXJzZSk7IGxpYnJhcnkoV0RJKTsgbGlicmFyeShEZXNjVG9vbHMpYAoKLSAgIOODh+ODvOOCv+OBruWPluW+l++8mmBgIFdESShpbmRpY2F0b3IgPSBjKGdpbmkgPSAiU0kuUE9WLkdJTkkiLGAwLTEwYCA9ICJTSS5EU1QuRlJTVC4xMCIsLi4uLGA5MC0xMDBgID0gIlNJLkRTVC4xMFRILjEwIikpIGBgCgotICAg54m55a6a44Gu6KGM44Gu5Y+W5b6X77yaYGZpbHRlcigpLCBkcm9wX25hKCksIGRpc3RpbmN0KClgCgotICAg5qOS44Kw44Op44OVCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHllYXIpKSArIGdlb21fYmFyKClgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKClgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHggPSBsZXZlbHMsIHkgPSB2YWx1ZSwgZmlsbCA9IGNvdW50cnkpKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIilgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHggPSBnaW5pLCBmaWxsID0gcmVnaW9uKSkgKyBnZW9tX2hpc3RvZ3JhbSgpYAoKLSAgIOaVo+W4g+Wbs++8iCvlm57luLDnm7Tnt5rvvIkKCiAgICAtICAgYGdncGxvdChhZXMoZ2luaSwgOTAtMTAwKSkgKyBnZW9tX3BvaW50KClgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKGdpbmksIDgwLTEwMCkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9ICd5IH4geCcsIG1ldGhvZCA9ICJsbSIpYAoKIyMg6Kqy6aGMCgoqKue3tOe/kjEg44GL44KJ57e057+SMy4qKgoK5o+Q5Ye644Gv44GX44Gq44GP44Gm6Imv44GE44Gn44GZ44GM44CB44Gc44Gy5a6f6Zqb44Gr5omL44KS5YuV44GL44GX44Gm5a6f6KGM44GX44Gm44GP44Gg44GV44GE44CCCgojIyDlj4LogIPmlofnjK4KCjEuICDjgIzjgb/jgpPjgarjga7jg4fjg7zjgr/jgrXjgqTjgqjjg7PjgrkgLSBEYXRhIFNjaWVuY2UgZm9yIEFsbOOAjVtb44Gv44GY44KB44Gm44Gu44OH44O844K/44K144Kk44Ko44Oz44K5XShodHRwczovL2ljdS1oc3V6dWtpLmdpdGh1Yi5pby9kczRhai9maXJzdC1leGFtcGxlLmh0bWwjZmlyc3QtZXhhbXBsZSldCgogICAgLSAgIOWwjuWFpeOBqOOBl+OBpuOAgUdEUO+8iOWbveWGhee3j+eUn+eUo++8ieOBruODh+ODvOOCv+OCkuS9v+OBo+OBpuiqrOaYjuOBl+OBpuOBhOOBvuOBmeOAggoKMi4gIFBvc2l0IFJlY2lwZXPvvIjml6cgUG9zaXQgUHJpbWVyc++8iTogVGhlIEJhc2ljcyDlr77oqbHlnovjga7mvJTnv5LjgrXjgqTjg4jjga7mnIDliJ0gW1tMaW5rXShodHRwczovL3Bvc2l0LmNsb3VkL2xlYXJuL3JlY2lwZXMpXQoKMy4gIFBvc2l0IENoZWF0IFNoZWV0LiDml6nopovooajjgafjgZnjgILljbDliLfjgZfjgabkvb/jgYbjgZ/jgoHjgavjgIFQREYg44KC5o+Q5L6b44GX44Gm44GE44G+44GZ44CCW1tTaXRlIExpbmtdKGh0dHBzOi8vcnN0dWRpby5naXRodWIuaW8vY2hlYXRzaGVldHMvKV0KCjQuICBEYXRhQ2FtcCBDaGVhdCBTaGVldDogVGlkeXZlcnNlIGZvciBCaWdpbm5lcnMuIOODh+ODvOOCv+OCteOCpOOCqOODs+OCueOBruaVmeiCsuOCkuOBl+OBpuOBhOOCi+S8muekvuOBruaXqeimi+ihqOOBruS4gOOBpOOBp+OBmeOAguWfuuacrOOBjOewoeWNmOOBq+OBvuOBqOOBvuOBo+OBpuOBhOOBvuOBmeOAgltbTGlua10oaHR0cHM6Ly9pbWFnZXMuZGF0YWNhbXAuY29tL2ltYWdlL3VwbG9hZC92MTY3NjMwMjY5Ny9NYXJrZXRpbmcvQmxvZy9UaWR5dmVyc2VfQ2hlYXRfU2hlZXQucGRmKV0KCjwhLS0gIyMg5Y+C6ICD77yRIC0tPgoKPCEtLSDpmo7ntJrjgpIgMTAlIOWIu+OBv+OBq+e1seS4gOOBl+OAgUxvbmcg5b2i5byP44Gr5aSJ5o+b44CCIC0tPgoKPCEtLSBgYGB7cn0gLS0+CjwhLS0gZGZfZ2luaV9yZXYgPC0gZGZfZ2luaSB8PiAgLS0+CjwhLS0gICBtdXRhdGUoYDAtMTBgID0gYDAtMTBgLCBgMTAtMjBgID0gYDAtMjBgLWAwLTEwYCxgMjAtMzBgID0gYDIwLTQwYC8yLCBgMzAtNDBgID0gYDIwLTQwYC8yLCBgNDAtNTBgID0gYDQwLTYwYC8yLCBgNTAtNjBgID0gYDQwLTYwYC8yLCBgNjAtNzBgID0gYDYwLTgwYC8yLCBgNzAtODBgPWA2MC04MGAvMiwgYDgwLTkwYCA9IGA4MC0xMDBgLWA5MC0xMDBgLCBgOTAtMTAwYCA9IGA5MC0xMDBgKSB8PiAgLS0+CjwhLS0gICBzZWxlY3QoLWMoYDAtMjBgLCBgMjAtNDBgLGA0MC02MGAsYDYwLTgwYCwgYDgwLTEwMGApKSB8PiAgLS0+CjwhLS0gICBzZWxlY3QoMTo2LCA4OjE1LCA3KSAgLS0+CjwhLS0gZGZfZ2luaV9yZXYgJT4lIGRyb3BfbmEoKSAtLT4KPCEtLSBgYGAgLS0+Cgo8IS0tIGBgYHtyfSAtLT4KPCEtLSBkZl9naW5pX3Jldl9sb25nIDwtIGRmX2dpbmlfcmV2IHw+IHBpdm90X2xvbmdlcig2OjE1LCBuYW1lc190byA9ICJsZXZlbHMiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAtLT4KPCEtLSBkZl9naW5pX3Jldl9sb25nIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS0gYGBge3IgZmlnLmhlaWdodD05LCBmaWcud2lkdGg9OH0gLS0+CjwhLS0gZGZfZ2luaV9yZXZfbG9uZyB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiBkcm9wX25hKGdpbmkpIHw+IC0tPgo8IS0tICAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpICsgIC0tPgo8IS0tICAgZmFjZXRfd3JhcCh+Y291bnRyeSwgbmNvbCA9IDIpIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS0gIyMg5Y+C6ICD77ySIC0tPgoKPCEtLSDmm7Lnt5rjga7kuIvjga7pnaLnqY3jgpLoqIjnrpfjgZnjgovjgIBBVUMg44KS5Yip55So44GX44Gm44CB44K444OL5L+C5pWw44KS6KiI566X44CCIC0tPgoKPCEtLSBBcmVhIFVuZGVyIHRoZSBDdXJ2ZTogW1vjg6rjg7Pjgq9dKGh0dHBzOi8vc2VhcmNoLnItcHJvamVjdC5vcmcvQ1JBTi9yZWZtYW5zL0Rlc2NUb29scy9odG1sL0FVQy5odG1sKV0gLS0+Cgo8IS0tIDxodHRwczovL3JkcnIuaW8vY3Jhbi9EZXNjVG9vbHMvZi8+IC0tPgoKPCEtLSBgYGB7cn0gLS0+CjwhLS0gZGZfZ2luaV9jYWxjX2xvbmcgfD4gZ3JvdXBfYnkoY291bnRyeSwgeWVhcikgfD4gIC0tPgo8IS0tICAgZHJvcF9uYShnaW5pKSB8PiAtLT4KPCEtLSAgIHJlZnJhbWUoZ2luaSwgZ2luaV9zcGxpbmUgPSByb3VuZCgxMDAtQVVDKGNsYXNzZXMsIGN1bXVsYXRpdmVfc2hhcmUsIG1ldGhvZCA9ICJzcGxpbmUiKS81MCwgZGlnaXRzID0gMSksIGdpbmlfdHJhcGV6b2lkID0gcm91bmQoMTAwLUFVQyhjbGFzc2VzLCBjdW11bGF0aXZlX3NoYXJlKS81MCwgZGlnaXRzID0gMSkpIHw+ICAtLT4KPCEtLSAgIGRpc3RpbmN0KGNvdW50cnksIHllYXIsIGdpbmksIGdpbmlfc3BsaW5lLCBnaW5pX3RyYXBlem9pZCkgLS0+CjwhLS0gYGBgIC0tPgoKIyMjIOe3tOe/kjLjga7nrZTjgYgKCmBgYHtyfQpTRVZFTl9DT1VOVFJJRVMgPC0gYygiQmh1dGFuIiwgIkJhbmdsYWRlc2giLCJJbmRvbmVzaWEiLCJFbCBTYWx2YWRvciIsICJQYXJhZ3VheSIsICJFcXVhZG9yIiwgIkNvc3RhIFJpY2EiKQpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gCiAgZmlsdGVyKGNvdW50cnkgJWluJSBTRVZFTl9DT1VOVFJJRVMsIHllYXIgPT0gWUVBUl9HSU5JKSB8PgogIGZpbHRlcihsZXZlbHMgJWluJSBjKCc4MC0xMDAnLCc5MC0xMDAnKSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUsIGZpbGwgPSBmYWN0b3IoY291bnRyeSwgbGV2ZWxzID0gU0VWRU5fQ09VTlRSSUVTKSkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiLCBjb2wgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjIpICsgbGFicyhmaWxsID0gIiIpCmBgYAo=