ジニ指数って知っていますか!?

ジニ係数(ジニけいすう、: Gini coefficient)とは主に社会における所得の不平等さを測る指標である。0から1で表され、各人の所得が均一で格差が全くない状態を0、たった一人が全ての所得を独占している状態を1とする。ローレンツ曲線をもとに、1912年にイタリアの統計学者、コッラド・ジニによって考案された。それ以外にも、富の偏在性やエネルギー消費における不平等さなどに応用される。(Wikipedia)

ジニ係数のグラフ ジニ係数は、Aの面積をABの各面積の合計で割ったものに等しい。すなわち、ジニ係数 =A/(A+B)となる。また、A+B=0.5のため、2×Aにも等しい(縦軸は0と1の間の値をとるため)

ジニ電卓(GINI Calculator)

準備

最初はいつでも準備。tidyverse 以外に、(R の機能を拡張する)パッケージ DescTools を使いますから、インストールしてください。下のコードチャンクを実行してもインストールされます。インストールは初回の一回だけです。

install.packages("DescTools")

パッケージを利用するときには、ロードします。

library(tidyverse)
library(WDI)
library(DescTools)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

ジニ指数を計算して表示するプログラムです。

GINI <- function(x){
  Lc(x)[c(1,2)] |> as.tibble() |> mutate(A = p, .after = 1) |> 
  pivot_longer(-1, names_to = "name", values_to = "value") |>
  ggplot(aes(p, value, fill = name)) + 
    geom_area(position = "identity") +
    annotate("text", x = 0.25, y = 0.75, label = paste("GINI = A/(A+L) = ", round(Gini(x, unbiased = FALSE), digits = 2))) + 
    scale_y_continuous(labels = scales::percent_format(accuracy = 1))+
    scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
    labs(title = "GINI Index", x = "People", y = "Wealth", fill = "")}

x に、数の列を入れるとその分配に関する、ジニ指数を計算します。非負(マイナスではないかず)であれば、なんでも、どんな順番でも、いくつでも構いません。

下の例では、二人で、最初の人(50%)が 0 で、もう一人(50%)が 1 ですから、グラフを書くと、以下のように 0.5 になります。非常に多い数を想定しているので、これは、補正したジニ指数は1とする場合もあります。

x <- c(0,1)
GINI(x)
Warning: `as.tibble()` was deprecated in tibble 2.0.0.
Please use `as_tibble()` instead.
The signature and semantics have changed, see `?as_tibble`.

練習1. \(y\) に色々な列を入れて、ジニ指数を計算してください。

半角の数字で、カンマで区切ったものを、c() の中に入れます。

y <- c(1,2,3,4,5,6,7,8,9,10)
GINI(y)

考えてみよう

  • 5人の人を雇って働いてもらいました。全体で5万円を支払います。どのように分けるのが公平ですか。

  • 5人の人を雇って働いてもらいました。全体で5万円を支払います。一人目は朝6時から夕6時まで、二人目は朝9時から夕6時まで、三人目は昼12時から夕6時まで、四人目は午後3時から夕6時まで、五人目は夕5時から夕6時まで働きました。どのように分けるのが公平ですか。

  • 5人の人を雇って働いてもらいました。全体で5万円を支払います。働いた時間は、二番目の状況と同じです。実は、それぞれ家族がいて、その人だけが働ける人です。家族で生活するには、1万円は、ギリギリのお金です。どのように分けるのが公平ですか。

  • 5人の人を雇って働いてもらいました。全体で5万円を支払います。働いた時間は、二番目の状況と同じです。一人目は、単身でいつでも働けます。二人目は家事をし、こどもを保育園に預けてからきました。三人目は体調が悪く午前中寝てからきました。四人目はしょうがいを持っていてなかなか動けず仕事もあまりできないけれど精一杯働きました。五人目は、ヤングケアラーで家からなかなか出ることができませんでした。でも家では空いている時間はゲームもやっていました。どのように分けるのが公平ですか。

あなたが分配する責任を持っていたらどのように分配しますか。

(聖書:マタイによる福音書20章1-16節)


労働時間割で計算してみると ジニ指数は、0.36 になります。

z <- c(1/12,3/12,6/12,9/12,1)
GINI(z)

z に割合を入れると、5万円の分配を計算してくれます。端数を切り捨てた差額も表示しています。

z <- c(1/12,3/12,6/12,9/12,1)
50000/sum(z) * z
[1]  1612.903  4838.710  9677.419 14516.129 19354.839
round(50000/sum(z) * z) # 四捨五入
[1]  1613  4839  9677 14516 19355
as.integer(50000/sum(z) * z) # 切り捨て
[1]  1612  4838  9677 14516 19354
sum(round(50000/sum(z) * z))-50000 # 四捨五入の差額
[1] 0
sum(as.integer(50000/sum(z) * z)) -50000 # 切り捨ての場合の差額
[1] -3

前回(12月19日)の復習

毎回 tidyverse と WDI を使いますから、R Notebook の最初には、次のコードチャンクを作成し、実行(Run)します。

指標について

  • GINI index (World Bank estimate);SI.POV.GINI [Link]

    • Gini index measures the extent to which the distribution of income (or, in some cases, consumption expenditure) among individuals or households within an economy deviates from a perfectly equal distribution. A Lorenz curve plots the cumulative percentages of total income received against the cumulative number of recipients, starting with the poorest individual or household. The Gini index measures the area between the Lorenz curve and a hypothetical line of absolute equality, expressed as a percentage of the maximum area under the line. Thus a Gini index of 0 represents perfect equality, while an index of 100 implies perfect inequality.

    • ジニ指数は、経済内の個人または世帯間の所得(または場合によっては消費支出)の分布が、完全に平等な分布からどの程度逸脱しているかを測定する。ローレンツ曲線は、最も貧しい個人または世帯から始まり、受給者の累積数に対する総所得の累積割合をプロットしたものである。ジニ指数は、ローレンツ曲線と絶対的平等の仮想線との間の面積を測定するもので、線の下の最大面積の百分率で表される。したがって、ジニ指数0は完全な平等を表し、指数100は完全な不平等を意味する。

ジニ指数の分布

最初に準備をしてあるので、パッケージのロードは不要です。

library(tidyverse)
library(WDI)

データの読み込み

何度も読み込まなくて良いように、保存もしておきます。今回は、extra=TRUE として、地域(region)や、所得レベル(income)も含めてあります。

df_gini_index <- WDI(indicator = c(gini = "SI.POV.GINI"), 
                     extra = TRUE)
write_csv(df_gini_index, "data/gini_index.csv")
df_gini_index <- read_csv("data/gini_index.csv")
Rows: 16758 Columns: 13── Column specification ─────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr  (7): country, iso2c, iso3c, region, capital, income, lending
dbl  (4): year, gini, longitude, latitude
lgl  (1): status
date (1): lastupdated
ℹ 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.

データの確認

head(df_gini_index) または、df_gini_index でも確認可能です。

df_gini_index

必要な変数のみ選択

列の選択は、select を使います。

df_gini_index_rev <- df_gini_index |> 
  select(country, iso2c, year, gini, region, income)
df_gini_index_rev

日本のジニ指数

gini の値が、NA だと意味がないので、その部分は、drop_na(gini) で削除しておきます。

df_gini_index_rev |> filter(country == "Japan") |> drop_na(gini)

練習2. 日本(Japan)を、世界(World)にしてみるとどうなりますか。

各年のジニ指数のデータの数

ggplot(aes(year)) + geom_bar()

df_gini_index_rev |> drop_na(gini) |> 
  ggplot(aes(year)) + geom_bar()

2013年のジニ指数(gini)の(度数)分布

ヒストグラムで表示

df_gini_index_rev |> filter(year == 2013) |> drop_na(gini) |> 
  ggplot(aes(gini)) + geom_histogram()

練習3. bins の値を変えてみてみましょう。

df_gini_index_rev |> filter(year == 2013) |> drop_na(gini) |> 
  ggplot(aes(gini)) + geom_histogram(bins = 10)

練習4. binwidth の値を変えてみてみましょう。

df_gini_index_rev |> filter(year == 2013) |> drop_na(gini) |> 
  ggplot(aes(gini)) + geom_histogram(binwidth = 5)

地域ごとのデータ数

df_gini_index_rev |> filter(year == 2013) |> drop_na(gini) |> 
  ggplot(aes(gini, fill = region)) + geom_histogram(bins = 10, col = "black", linewidth = 0.2)

練習5. どんなことがわかりますか。bins や、binwidth を変えても良いですよ。

df_gini_index_rev |> filter(year == 2013) |> drop_na(gini) |> 
  ggplot(aes(gini, fill = income)) + geom_histogram(bins = 10, col = "black", linewidth = 0.2)

所得階層ごとのデータ数

INCOME <- c("Low income", "Lower middle income", "Upper middle income", 
"High income")
df_gini_index_rev |> filter(year == 2013) |> drop_na(gini) |> 
  ggplot(aes(gini, fill = factor(income, levels = INCOME))) + geom_histogram(bins = 10, col = "black", linewidth = 0.2) + 
  labs(fill = "Income level")

練習6. どんなことがわかりますか。bins や、binwidth を変えても良いですよ。

参考:それぞれの地域ごとの所得レベルによる国の数

df_gini_index_rev |> filter(!(iso2c %in% REGION)) |> 
  distinct(iso2c, region, income) |> 
  group_by(region, income) |> summarize(number_of_countries = n())
`summarise()` has grouped output by 'region'. You can override using the `.groups` argument.

課題

練習1 から練習6.

提出はしなくて良いですが、ぜひ実際に手を動かして実行してください。

参考文献

  1. 「みんなのデータサイエンス - Data Science for All」[はじめてのデータサイエンス]

    • 導入として、GDP(国内総生産)のデータを使って説明しています。
  2. Posit Recipes(旧 Posit Primers): The Basics 対話型の演習サイトの最初 [Link]

  3. Posit Cheat Sheet. 早見表です。印刷して使うために、PDF も提供しています。[Site Link]

  4. DataCamp Cheat Sheet: Tidyverse for Biginners. データサイエンスの教育をしている会社の早見表の一つです。基本が簡単にまとまっています。[Link]

LS0tCnRpdGxlOiAiR0lOSSDjgaPjgabkvZXvvJ8iCmF1dGhvcjogIkguIFN1enVraSIKZGF0ZTogIjIwMjTlubQx5pyIOeaXpSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgojIyDjgrjjg4vmjIfmlbDjgaPjgabnn6XjgaPjgabjgYTjgb7jgZnjgYvvvIHvvJ8KCioq44K444OL5L+C5pWwKirvvIjjgrjjg4vjgZHjgYTjgZnjgYbjgIFb6IuxXShodHRwczovL2phLndpa2lwZWRpYS5vcmcvd2lraS8lRTglOEIlQjElRTglQUElOUUgIuiLseiqniIpOsKgR2luaSBjb2VmZmljaWVudO+8ieOBqOOBr+S4u+OBq+ekvuS8muOBq+OBiuOBkeOCi+aJgOW+l+OBruS4jeW5s+etieOBleOCkua4rOOCi+aMh+aomeOBp+OBguOCi+OAgjDjgYvjgokx44Gn6KGo44GV44KM44CB5ZCE5Lq644Gu5omA5b6X44GM5Z2H5LiA44Gn5qC85beu44GM5YWo44GP44Gq44GE54q25oWL44KSMOOAgeOBn+OBo+OBn+S4gOS6uuOBjOWFqOOBpuOBruaJgOW+l+OCkueLrOWNoOOBl+OBpuOBhOOCi+eKtuaFi+OCkjHjgajjgZnjgovjgILjg63jg7zjg6zjg7Pjg4Tmm7Lnt5rjgpLjgoLjgajjgavjgIExOTEy5bm044Gr44Kk44K/44Oq44Ki44Gu57Wx6KiI5a2m6ICF44CB44Kz44OD44Op44OJ44O744K444OL44Gr44KI44Gj44Gm6ICD5qGI44GV44KM44Gf44CC44Gd44KM5Lul5aSW44Gr44KC44CB5a+M44Gu5YGP5Zyo5oCn44KE44Ko44ON44Or44Ku44O85raI6LK744Gr44GK44GR44KL5LiN5bmz562J44GV44Gq44Gp44Gr5b+c55So44GV44KM44KL44CC77yIV2lraXBlZGlh77yJCgohW10oaW1hZ2VzL2NsaXBib2FyZC03MTk4ODY4NTUucG5nKQoK44K444OL5L+C5pWw44Gu44Kw44Op44OVIOOCuOODi+S/guaVsOOBr+OAgSpBKuOBrumdouepjeOCkipBKuOBqCpCKuOBruWQhOmdouepjeOBruWQiOioiOOBp+WJsuOBo+OBn+OCguOBruOBq+etieOBl+OBhOOAguOBmeOBquOCj+OBoeOAgeOCuOODi+S/guaVsCA9KkEqL++8iCpBKisqQirvvInjgajjgarjgovjgILjgb7jgZ/jgIEqQSorKkIqPTAuNeOBruOBn+OCgeOAgTLDlypBKuOBq+OCguetieOBl+OBhO+8iOe4pui7uOOBrzDjgagx44Gu6ZaT44Gu5YCk44KS44Go44KL44Gf44KB77yJCgojIyDjgrjjg4vpm7vljZPvvIhHSU5JIENhbGN1bGF0b3LvvIkKCiMjIyDmupblgpkKCuacgOWIneOBr+OBhOOBpOOBp+OCgua6luWCmeOAgmB0aWR5dmVyc2VgIOS7peWkluOBq+OAge+8iFIg44Gu5qmf6IO944KS5ouh5by144GZ44KL77yJ44OR44OD44Kx44O844K4IGBEZXNjVG9vbHNgIOOCkuS9v+OBhOOBvuOBmeOBi+OCieOAgeOCpOODs+OCueODiOODvOODq+OBl+OBpuOBj+OBoOOBleOBhOOAguS4i+OBruOCs+ODvOODieODgeODo+ODs+OCr+OCkuWun+ihjOOBl+OBpuOCguOCpOODs+OCueODiOODvOODq+OBleOCjOOBvuOBmeOAguOCpOODs+OCueODiOODvOODq+OBr+WIneWbnuOBruS4gOWbnuOBoOOBkeOBp+OBmeOAggoKYGBge3IgZXZhbD1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygiRGVzY1Rvb2xzIikKYGBgCgrjg5Hjg4PjgrHjg7zjgrjjgpLliKnnlKjjgZnjgovjgajjgY3jgavjga/jgIHjg63jg7zjg4njgZfjgb7jgZnjgIIKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShXREkpCmxpYnJhcnkoRGVzY1Rvb2xzKQpgYGAKCuOCuOODi+aMh+aVsOOCkuioiOeul+OBl+OBpuihqOekuuOBmeOCi+ODl+ODreOCsOODqeODoOOBp+OBmeOAggoKYGBge3J9CkdJTkkgPC0gZnVuY3Rpb24oeCl7CiAgTGMoeClbYygxLDIpXSB8PiBhcy50aWJibGUoKSB8PiBtdXRhdGUoQSA9IHAsIC5hZnRlciA9IDEpIHw+IAogIHBpdm90X2xvbmdlcigtMSwgbmFtZXNfdG8gPSAibmFtZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpIHw+CiAgZ2dwbG90KGFlcyhwLCB2YWx1ZSwgZmlsbCA9IG5hbWUpKSArIAogICAgZ2VvbV9hcmVhKHBvc2l0aW9uID0gImlkZW50aXR5IikgKwogICAgYW5ub3RhdGUoInRleHQiLCB4ID0gMC4yNSwgeSA9IDAuNzUsIGxhYmVsID0gcGFzdGUoIkdJTkkgPSBBLyhBK0wpID0gIiwgcm91bmQoR2luaSh4LCB1bmJpYXNlZCA9IEZBTFNFKSwgZGlnaXRzID0gMikpKSArIAogICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkrCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgICBsYWJzKHRpdGxlID0gIkdJTkkgSW5kZXgiLCB4ID0gIlBlb3BsZSIsIHkgPSAiV2VhbHRoIiwgZmlsbCA9ICIiKX0KYGBgCgp4IOOBq+OAgeaVsOOBruWIl+OCkuWFpeOCjOOCi+OBqOOBneOBruWIhumFjeOBq+mWouOBmeOCi+OAgeOCuOODi+aMh+aVsOOCkuioiOeul+OBl+OBvuOBmeOAgumdnuiyoO+8iOODnuOCpOODiuOCueOBp+OBr+OBquOBhOOBi+OBmu+8ieOBp+OBguOCjOOBsOOAgeOBquOCk+OBp+OCguOAgeOBqeOCk+OBqumghueVquOBp+OCguOAgeOBhOOBj+OBpOOBp+OCguani+OBhOOBvuOBm+OCk+OAggoK5LiL44Gu5L6L44Gn44Gv44CB5LqM5Lq644Gn44CB5pyA5Yid44Gu5Lq677yINTAl77yJ44GMIDAg44Gn44CB44KC44GG5LiA5Lq677yINTAl77yJ44GMIDEg44Gn44GZ44GL44KJ44CB44Kw44Op44OV44KS5pu444GP44Go44CB5Lul5LiL44Gu44KI44GG44GrIDAuNSDjgavjgarjgorjgb7jgZnjgILpnZ7luLjjgavlpJrjgYTmlbDjgpLmg7PlrprjgZfjgabjgYTjgovjga7jgafjgIHjgZPjgozjga/jgIHoo5zmraPjgZfjgZ/jgrjjg4vmjIfmlbDjga8x44Go44GZ44KL5aC05ZCI44KC44GC44KK44G+44GZ44CCCgpgYGB7cn0KeCA8LSBjKDAsMSkKR0lOSSh4KQpgYGAKCioq57e057+SMS4qKiAkeSQgKirjgavoibLjgIXjgarliJfjgpLlhaXjgozjgabjgIHjgrjjg4vmjIfmlbDjgpLoqIjnrpfjgZfjgabjgY/jgaDjgZXjgYTjgIIqKgoK5Y2K6KeS44Gu5pWw5a2X44Gn44CB44Kr44Oz44Oe44Gn5Yy65YiH44Gj44Gf44KC44Gu44KS44CBYGMoKWAg44Gu5Lit44Gr5YWl44KM44G+44GZ44CCCgpgYGB7cn0KeSA8LSBjKDEsMiwzLDQsNSw2LDcsOCw5LDEwKQpHSU5JKHkpCmBgYAoKIyMjIOiAg+OBiOOBpuOBv+OCiOOBhgoKLSAgIO+8leS6uuOBruS6uuOCkumbh+OBo+OBpuWDjeOBhOOBpuOCguOCieOBhOOBvuOBl+OBn+OAguWFqOS9k+OBpzXkuIflhobjgpLmlK/miZXjgYTjgb7jgZnjgILjganjga7jgojjgYbjgavliIbjgZHjgovjga7jgYzlhazlubPjgafjgZnjgYvjgIIKCi0gICDvvJXkurrjga7kurrjgpLpm4fjgaPjgablg43jgYTjgabjgoLjgonjgYTjgb7jgZfjgZ/jgILlhajkvZPjgac15LiH5YaG44KS5pSv5omV44GE44G+44GZ44CC5LiA5Lq655uu44Gv5pydNuaZguOBi+OCieWklTbmmYLjgb7jgafjgIHkuozkurrnm67jga/mnJ055pmC44GL44KJ5aSVNuaZguOBvuOBp+OAgeS4ieS6uuebruOBr+aYvDEy5pmC44GL44KJ5aSVNuaZguOBvuOBp+OAgeWbm+S6uuebruOBr+WNiOW+jDPmmYLjgYvjgonlpJU25pmC44G+44Gn44CB5LqU5Lq655uu44Gv5aSVNeaZguOBi+OCieWklTbmmYLjgb7jgaflg43jgY3jgb7jgZfjgZ/jgILjganjga7jgojjgYbjgavliIbjgZHjgovjga7jgYzlhazlubPjgafjgZnjgYvjgIIKCi0gICDvvJXkurrjga7kurrjgpLpm4fjgaPjgablg43jgYTjgabjgoLjgonjgYTjgb7jgZfjgZ/jgILlhajkvZPjgac15LiH5YaG44KS5pSv5omV44GE44G+44GZ44CC5YON44GE44Gf5pmC6ZaT44Gv44CB5LqM55Wq55uu44Gu54q25rOB44Go5ZCM44GY44Gn44GZ44CC5a6f44Gv44CB44Gd44KM44Ge44KM5a625peP44GM44GE44Gm44CB44Gd44Gu5Lq644Gg44GR44GM5YON44GR44KL5Lq644Gn44GZ44CC5a625peP44Gn55Sf5rS744GZ44KL44Gr44Gv44CBMeS4h+WGhuOBr+OAgeOCruODquOCruODquOBruOBiumHkeOBp+OBmeOAguOBqeOBruOCiOOBhuOBq+WIhuOBkeOCi+OBruOBjOWFrOW5s+OBp+OBmeOBi+OAggoKLSAgIO+8leS6uuOBruS6uuOCkumbh+OBo+OBpuWDjeOBhOOBpuOCguOCieOBhOOBvuOBl+OBn+OAguWFqOS9k+OBpzXkuIflhobjgpLmlK/miZXjgYTjgb7jgZnjgILlg43jgYTjgZ/mmYLplpPjga/jgIHkuoznlarnm67jga7nirbms4HjgajlkIzjgZjjgafjgZnjgILkuIDkurrnm67jga/jgIHljZjouqvjgafjgYTjgaTjgafjgoLlg43jgZHjgb7jgZnjgILkuozkurrnm67jga/lrrbkuovjgpLjgZfjgIHjgZPjganjgoLjgpLkv53ogrLlnJLjgavpoJDjgZHjgabjgYvjgonjgY3jgb7jgZfjgZ/jgILkuInkurrnm67jga/kvZPoqr/jgYzmgqrjgY/ljYjliY3kuK3lr53jgabjgYvjgonjgY3jgb7jgZfjgZ/jgILlm5vkurrnm67jga/jgZfjgofjgYbjgYzjgYTjgpLmjIHjgaPjgabjgYTjgabjgarjgYvjgarjgYvli5XjgZHjgZrku5XkuovjgoLjgYLjgb7jgorjgafjgY3jgarjgYTjgZHjgozjgannsr7kuIDmna/lg43jgY3jgb7jgZfjgZ/jgILkupTkurrnm67jga/jgIHjg6Tjg7PjgrDjgrHjgqLjg6njg7zjgaflrrbjgYvjgonjgarjgYvjgarjgYvlh7rjgovjgZPjgajjgYzjgafjgY3jgb7jgZvjgpPjgafjgZfjgZ/jgILjgafjgoLlrrbjgafjga/nqbrjgYTjgabjgYTjgovmmYLplpPjga/jgrLjg7zjg6DjgoLjgoTjgaPjgabjgYTjgb7jgZfjgZ/jgILjganjga7jgojjgYbjgavliIbjgZHjgovjga7jgYzlhazlubPjgafjgZnjgYvjgIIKCuOBguOBquOBn+OBjOWIhumFjeOBmeOCi+iyrOS7u+OCkuaMgeOBo+OBpuOBhOOBn+OCieOBqeOBruOCiOOBhuOBq+WIhumFjeOBl+OBvuOBmeOBi+OAggoK77yI6IGW5pu477ya44Oe44K/44Kk44Gr44KI44KL56aP6Z+z5pu4MjDnq6AxLTE256+A77yJCgpcCuWKtOWDjeaZgumWk+WJsuOBp+ioiOeul+OBl+OBpuOBv+OCi+OBqCDjgrjjg4vmjIfmlbDjga/jgIEwLjM2IOOBq+OBquOCiuOBvuOBmeOAggoKYGBge3J9CnogPC0gYygxLzEyLDMvMTIsNi8xMiw5LzEyLDEpCkdJTkkoeikKYGBgCgp6IOOBq+WJsuWQiOOCkuWFpeOCjOOCi+OBqOOAgTXkuIflhobjga7liIbphY3jgpLoqIjnrpfjgZfjgabjgY/jgozjgb7jgZnjgILnq6/mlbDjgpLliIfjgormjajjgabjgZ/lt67poY3jgoLooajnpLrjgZfjgabjgYTjgb7jgZnjgIIKCmBgYHtyfQp6IDwtIGMoMS8xMiwzLzEyLDYvMTIsOS8xMiwxKQo1MDAwMC9zdW0oeikgKiB6CnJvdW5kKDUwMDAwL3N1bSh6KSAqIHopICMg5Zub5o2o5LqU5YWlCmFzLmludGVnZXIoNTAwMDAvc3VtKHopICogeikgIyDliIfjgormjajjgaYKc3VtKHJvdW5kKDUwMDAwL3N1bSh6KSAqIHopKS01MDAwMCAjIOWbm+aNqOS6lOWFpeOBruW3rumhjQpzdW0oYXMuaW50ZWdlcig1MDAwMC9zdW0oeikgKiB6KSkgLTUwMDAwICMg5YiH44KK5o2o44Gm44Gu5aC05ZCI44Gu5beu6aGNCmBgYAoKIyMg5YmN5Zue77yIMTLmnIgxOeaXpe+8ieOBruW+qee/kgoKLSAgIOODkeODg+OCseODvOOCuO+8iFBhY2thZ2XvvInjga7liKnnlKjvvJoKCiAgICAtICAg44Kk44Oz44K544OI44O844Or77yIaW5zdGFsbGF0aW9u77yJ77yaVG9vbHMgXD4gSW5zdGFsbCBQYWNrYWdlcwoKICAgIC0gICDjg63jg7zjg4nvvIhsb2Fk77yJYGxpYnJhcnkodGlkeXZlcnNlKTsgbGlicmFyeShXREkpOyBsaWJyYXJ5KHNob3d0ZXh0KWAKCi0gICDjg4fjg7zjgr/jga7lj5blvpfvvJpgV0RJKGluZGljYXRvciA9IGMocG9wID0gIlNQLlBPUC5UT1RMIikpYAoKLSAgIOeJueWumuOBruihjOOBruWPluW+l++8mmBmaWx0ZXIoKSwgZHJvcF9uYSgpLCBkaXN0aW5jdCgpYAoKLSAgIOaKmOOCjOe3muOCsOODqeODlQoKICAgIC0gICBgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHBvcCkgKyBnZW9tX2xpbmUoKWAKCiAgICAtICAgYGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBwb3AsIGNvbCA9IGNvdW50cnkpICsgZ2VvbV9saW5lKClgCgrmr47lm54gdGlkeXZlcnNlIOOBqCBXREkg44KS5L2/44GE44G+44GZ44GL44KJ44CBUiBOb3RlYm9vayDjga7mnIDliJ3jgavjga/jgIHmrKHjga7jgrPjg7zjg4njg4Hjg6Pjg7Pjgq/jgpLkvZzmiJDjgZfjgIHlrp/ooYzvvIhSdW7vvInjgZfjgb7jgZnjgIIKCiMjIyDmjIfmqJnjgavjgaTjgYTjgaYKCi0gICBHSU5JIGluZGV4IChXb3JsZCBCYW5rIGVzdGltYXRlKe+8m1NJLlBPVi5HSU5JIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NJLlBPVi5HSU5JKV0KCiAgICAtICAgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgZXh0ZW50IHRvIHdoaWNoIHRoZSBkaXN0cmlidXRpb24gb2YgaW5jb21lIChvciwgaW4gc29tZSBjYXNlcywgY29uc3VtcHRpb24gZXhwZW5kaXR1cmUpIGFtb25nIGluZGl2aWR1YWxzIG9yIGhvdXNlaG9sZHMgd2l0aGluIGFuIGVjb25vbXkgZGV2aWF0ZXMgZnJvbSBhIHBlcmZlY3RseSBlcXVhbCBkaXN0cmlidXRpb24uIEEgTG9yZW56IGN1cnZlIHBsb3RzIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzIG9mIHRvdGFsIGluY29tZSByZWNlaXZlZCBhZ2FpbnN0IHRoZSBjdW11bGF0aXZlIG51bWJlciBvZiByZWNpcGllbnRzLCBzdGFydGluZyB3aXRoIHRoZSBwb29yZXN0IGluZGl2aWR1YWwgb3IgaG91c2Vob2xkLiBUaGUgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgYXJlYSBiZXR3ZWVuIHRoZSBMb3JlbnogY3VydmUgYW5kIGEgaHlwb3RoZXRpY2FsIGxpbmUgb2YgYWJzb2x1dGUgZXF1YWxpdHksIGV4cHJlc3NlZCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIG1heGltdW0gYXJlYSB1bmRlciB0aGUgbGluZS4gVGh1cyBhIEdpbmkgaW5kZXggb2YgMCByZXByZXNlbnRzIHBlcmZlY3QgZXF1YWxpdHksIHdoaWxlIGFuIGluZGV4IG9mIDEwMCBpbXBsaWVzIHBlcmZlY3QgaW5lcXVhbGl0eS4KCiAgICAtICAg44K444OL5oyH5pWw44Gv44CB57WM5riI5YaF44Gu5YCL5Lq644G+44Gf44Gv5LiW5biv6ZaT44Gu5omA5b6X77yI44G+44Gf44Gv5aC05ZCI44Gr44KI44Gj44Gm44Gv5raI6LK75pSv5Ye677yJ44Gu5YiG5biD44GM44CB5a6M5YWo44Gr5bmz562J44Gq5YiG5biD44GL44KJ44Gp44Gu56iL5bqm6YC46ISx44GX44Gm44GE44KL44GL44KS5ris5a6a44GZ44KL44CC44Ot44O844Os44Oz44OE5puy57ea44Gv44CB5pyA44KC6LKn44GX44GE5YCL5Lq644G+44Gf44Gv5LiW5biv44GL44KJ5aeL44G+44KK44CB5Y+X57Wm6ICF44Gu57Sv56mN5pWw44Gr5a++44GZ44KL57eP5omA5b6X44Gu57Sv56mN5Ymy5ZCI44KS44OX44Ot44OD44OI44GX44Gf44KC44Gu44Gn44GC44KL44CC44K444OL5oyH5pWw44Gv44CB44Ot44O844Os44Oz44OE5puy57ea44Go57W25a++55qE5bmz562J44Gu5Luu5oOz57ea44Go44Gu6ZaT44Gu6Z2i56mN44KS5ris5a6a44GZ44KL44KC44Gu44Gn44CB57ea44Gu5LiL44Gu5pyA5aSn6Z2i56mN44Gu55m+5YiG546H44Gn6KGo44GV44KM44KL44CC44GX44Gf44GM44Gj44Gm44CB44K444OL5oyH5pWwMOOBr+WujOWFqOOBquW5s+etieOCkuihqOOBl+OAgeaMh+aVsDEwMOOBr+WujOWFqOOBquS4jeW5s+etieOCkuaEj+WRs+OBmeOCi+OAggoKIyMg44K444OL5oyH5pWw44Gu5YiG5biDCgrmnIDliJ3jgavmupblgpnjgpLjgZfjgabjgYLjgovjga7jgafjgIHjg5Hjg4PjgrHjg7zjgrjjga7jg63jg7zjg4njga/kuI3opoHjgafjgZnjgIIKCmBgYHtyIGV2YWw9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KFdESSkKYGBgCgojIyMg44OH44O844K/44Gu6Kqt44G/6L6844G/CgrkvZXluqbjgoLoqq3jgb/ovrzjgb7jgarjgY/jgaboia/jgYTjgojjgYbjgavjgIHkv53lrZjjgoLjgZfjgabjgYrjgY3jgb7jgZnjgILku4rlm57jga/jgIFleHRyYT1UUlVFIOOBqOOBl+OBpuOAgeWcsOWfn++8iHJlZ2lvbu+8ieOChOOAgeaJgOW+l+ODrOODmeODq++8iGluY29tZe+8ieOCguWQq+OCgeOBpuOBguOCiuOBvuOBmeOAggoKYGBge3IgZXZhbCA9IEZBTFNFfQpkZl9naW5pX2luZGV4IDwtIFdESShpbmRpY2F0b3IgPSBjKGdpbmkgPSAiU0kuUE9WLkdJTkkiKSwgCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhID0gVFJVRSkKYGBgCgpgYGB7ciBldmFsID0gRkFMU0V9CndyaXRlX2NzdihkZl9naW5pX2luZGV4LCAiZGF0YS9naW5pX2luZGV4LmNzdiIpCmBgYAoKYGBge3J9CmRmX2dpbmlfaW5kZXggPC0gcmVhZF9jc3YoImRhdGEvZ2luaV9pbmRleC5jc3YiKQpgYGAKCiMjIyDjg4fjg7zjgr/jga7norroqo0KCmBoZWFkKGRmX2dpbmlfaW5kZXgpYCDjgb7jgZ/jga/jgIFgZGZfZ2luaV9pbmRleGAg44Gn44KC56K66KqN5Y+v6IO944Gn44GZ44CCCgpgYGB7cn0KZGZfZ2luaV9pbmRleApgYGAKCiMjIyDlv4XopoHjgarlpInmlbDjga7jgb/pgbjmip4KCuWIl+OBrumBuOaKnuOBr+OAgWBzZWxlY3RgIOOCkuS9v+OBhOOBvuOBmeOAggoKYGBge3J9CmRmX2dpbmlfaW5kZXhfcmV2IDwtIGRmX2dpbmlfaW5kZXggfD4gCiAgc2VsZWN0KGNvdW50cnksIGlzbzJjLCB5ZWFyLCBnaW5pLCByZWdpb24sIGluY29tZSkKZGZfZ2luaV9pbmRleF9yZXYKYGBgCgojIyMg5pel5pys44Gu44K444OL5oyH5pWwCgpnaW5pIOOBruWApOOBjOOAgU5BIOOBoOOBqOaEj+WRs+OBjOOBquOBhOOBruOBp+OAgeOBneOBrumDqOWIhuOBr+OAgWRyb3BfbmEoZ2luaSkg44Gn5YmK6Zmk44GX44Gm44GK44GN44G+44GZ44CCCgpgYGB7cn0KZGZfZ2luaV9pbmRleF9yZXYgfD4gZmlsdGVyKGNvdW50cnkgPT0gIkphcGFuIikgfD4gZHJvcF9uYShnaW5pKQpgYGAKCioq57e057+SMi7jgIDml6XmnKzvvIhKYXBhbu+8ieOCkuOAgeS4lueVjO+8iFdvcmxk77yJ44Gr44GX44Gm44G/44KL44Go44Gp44GG44Gq44KK44G+44GZ44GL44CCKioKCi0gICAKCiMjIyAqKuWQhOW5tOOBruOCuOODi+aMh+aVsOOBruODh+ODvOOCv+OBruaVsCoqCgpgZ2dwbG90KGFlcyh5ZWFyKSkgKyBnZW9tX2JhcigpYAoKYGBge3J9CmRmX2dpbmlfaW5kZXhfcmV2IHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgZ2dwbG90KGFlcyh5ZWFyKSkgKyBnZW9tX2JhcigpCmBgYAoKIyMjICoqMjAxM+W5tOOBruOCuOODi+aMh+aVsO+8iGdpbmnvvInjga7vvIjluqbmlbDvvInliIbluIMqKgoKKirjg5Ljgrnjg4jjgrDjg6njg6DjgafooajnpLoqKgoKYGBge3J9CmRmX2dpbmlfaW5kZXhfcmV2IHw+IGZpbHRlcih5ZWFyID09IDIwMTMpIHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgZ2dwbG90KGFlcyhnaW5pKSkgKyBnZW9tX2hpc3RvZ3JhbSgpCmBgYAoKKirnt7Tnv5IzLiBgYmluc2Ag44Gu5YCk44KS5aSJ44GI44Gm44G/44Gm44G/44G+44GX44KH44GG44CCKioKCmBgYHtyfQpkZl9naW5pX2luZGV4X3JldiB8PiBmaWx0ZXIoeWVhciA9PSAyMDEzKSB8PiBkcm9wX25hKGdpbmkpIHw+IAogIGdncGxvdChhZXMoZ2luaSkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwKQpgYGAKCioq57e057+SNC4gYGJpbndpZHRoYCDjga7lgKTjgpLlpInjgYjjgabjgb/jgabjgb/jgb7jgZfjgofjgYbjgIIqKgoKYGBge3J9CmRmX2dpbmlfaW5kZXhfcmV2IHw+IGZpbHRlcih5ZWFyID09IDIwMTMpIHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgZ2dwbG90KGFlcyhnaW5pKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUpCmBgYAoKIyMjIOWcsOWfn+OBlOOBqOOBruODh+ODvOOCv+aVsAoKYGBge3J9CmRmX2dpbmlfaW5kZXhfcmV2IHw+IGZpbHRlcih5ZWFyID09IDIwMTMpIHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgZ2dwbG90KGFlcyhnaW5pLCBmaWxsID0gcmVnaW9uKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAsIGNvbCA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuMikKYGBgCgoqKue3tOe/kjUu44CA44Gp44KT44Gq44GT44Go44GM44KP44GL44KK44G+44GZ44GL44CCYGJpbnNgIOOChOOAgWBiaW53aWR0aGAg44KS5aSJ44GI44Gm44KC6Imv44GE44Gn44GZ44KI44CCKioKCi0gICAKCmBgYHtyfQpkZl9naW5pX2luZGV4X3JldiB8PiBmaWx0ZXIoeWVhciA9PSAyMDEzKSB8PiBkcm9wX25hKGdpbmkpIHw+IAogIGdncGxvdChhZXMoZ2luaSwgZmlsbCA9IGluY29tZSkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwLCBjb2wgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjIpCmBgYAoKIyMjIOaJgOW+l+majuWxpOOBlOOBqOOBruODh+ODvOOCv+aVsAoKYGBge3J9CklOQ09NRSA8LSBjKCJMb3cgaW5jb21lIiwgIkxvd2VyIG1pZGRsZSBpbmNvbWUiLCAiVXBwZXIgbWlkZGxlIGluY29tZSIsIAoiSGlnaCBpbmNvbWUiKQpkZl9naW5pX2luZGV4X3JldiB8PiBmaWx0ZXIoeWVhciA9PSAyMDEzKSB8PiBkcm9wX25hKGdpbmkpIHw+IAogIGdncGxvdChhZXMoZ2luaSwgZmlsbCA9IGZhY3RvcihpbmNvbWUsIGxldmVscyA9IElOQ09NRSkpKSArIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCwgY29sID0gImJsYWNrIiwgbGluZXdpZHRoID0gMC4yKSArIAogIGxhYnMoZmlsbCA9ICJJbmNvbWUgbGV2ZWwiKQpgYGAKCioq57e057+SNi7jgIDjganjgpPjgarjgZPjgajjgYzjgo/jgYvjgorjgb7jgZnjgYvjgIJgYmluc2Ag44KE44CBYGJpbndpZHRoYCDjgpLlpInjgYjjgabjgoLoia/jgYTjgafjgZnjgojjgIIqKgoKLSAgIAoKIyMjIOWPguiAg++8muOBneOCjOOBnuOCjOOBruWcsOWfn+OBlOOBqOOBruaJgOW+l+ODrOODmeODq+OBq+OCiOOCi+WbveOBruaVsAoKYGBge3J9CmRmX2dpbmlfaW5kZXhfcmV2IHw+IGZpbHRlcighKGlzbzJjICVpbiUgUkVHSU9OKSkgfD4gCiAgZGlzdGluY3QoaXNvMmMsIHJlZ2lvbiwgaW5jb21lKSB8PiAKICBncm91cF9ieShyZWdpb24sIGluY29tZSkgfD4gc3VtbWFyaXplKG51bWJlcl9vZl9jb3VudHJpZXMgPSBuKCkpCmBgYAoKIyMg6Kqy6aGMCgoqKue3tOe/kjEg44GL44KJ57e057+SNi4qKgoK5o+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+OBpuOBhOOBvuOBmeOAgltbTGlua10oaHR0cHM6Ly9pbWFnZXMuZGF0YWNhbXAuY29tL2ltYWdlL3VwbG9hZC92MTY3NjMwMjY5Ny9NYXJrZXRpbmcvQmxvZy9UaWR5dmVyc2VfQ2hlYXRfU2hlZXQucGRmKV0K