W1 はじめに

W1.1 事前準備1

 このページは、データ解析環境Rを用いた作図実習を含みます。実習に取り組みたい方は、こちらのリンク先の「R1.010 R本体とRStudioとパッケージのインストール」および「R1.020 RStudioの基本的な利用法」を一通り行っておいて下さい。以下は、リンク先のスクショです。①、②の順に各自のOS用のものを行ってください(約3時間)。RまたはRStudioの基本的な利用法が理解できていれば、ここはスキップしてもかまいません

W1.2 事前準備2

 ここでは、ggsankeyfiertidyverseopenxlsxのインストールを行います。3つのパッケージは、以下のコピペでインストールできます。openxlsxは、xlsx形式ファイルの読込時に必要なパッケージです。

if (!require("BiocManager", quietly = TRUE))     # BiocManagerパッケージがインストールされてなければ...
    install.packages("BiocManager")              # BiocManagerをインストールせよ
BiocManager::install("ggsankeyfier", update=F)   # パッケージのインストール(ggsankeyfier)
BiocManager::install("tidyverse", update=F)      # パッケージのインストール(tidyverse)
BiocManager::install("openxlsx", update=F)       # パッケージのインストール(openxlsx)

W1.3 エラー遭遇時の対処法

 ここはエラーに遭遇したヒト用の補足情報です。R本体のバージョンが古いと、上記スクリプトではうまくいかないことがあります。例えば、2025年4月3日現在のR本体の最新版は4.4.3ですが、バージョンが4.3.0以下ですとおそらくコケます。1つの対処法は、R本体のバージョンを上げて上記をやり直すことです。そしてもう1つの対処法は、現在利用中のRのままで以下を実行することです。

install.packages("ggsankeyfier", repos = "https://cloud.r-project.org/")
install.packages("tidyverse", repos = "https://cloud.r-project.org/")
install.packages("openxlsx", repos = "https://cloud.r-project.org/")

W2 サンキー図の具体例

 図1は、以下のスクリプトをコピペ実行すれば得られます。

W2.1 図1a タイタニック号沈没事故

 入力ファイル(JSLAB26_titanic.csv)は、ウィキペディアのタイタニック号沈没事故の犠牲者と生存者の内訳データから自作しています(W7.1)。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_titanic.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("Outcome", "Sex", "Passengers"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto")         # 描画時の位置情報(ノード間の縦幅間隔は自動)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Freq)*0.025             # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto",        # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        nudge_x = 0.06,          # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = nudge_val_y)   # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto",        # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        nudge_x = 0.06,          # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = -nudge_val_y)  # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)

# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g + 
      geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) + 
      geom_text(aes(label = Freq), stat = "sankeynode", position = pos2, hjust = 0, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W2.2 図1b 仮想薬剤応答解析結果

 入力ファイル(JSLAB26_medical.csv)は、W7.2で作成しています。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_medical.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("年齢", "病院", "種類", "結果"), # 描画させたいカテゴリ名情報
              values_from = "頻度")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto",         # 描画時の位置情報(ノード間の縦幅間隔は自動)
                       order = "as_is")          # 描画時の位置情報(ノード名の並びはそのまま)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = 頻度,             # matomeのstage列と頻度列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$頻度)*0.025             # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto",        # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        order = "as_is",         # ノード名情報描画時の位置情報(項目名の並びはそのまま)
                        nudge_x = 0.06,          # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = nudge_val_y)   # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto",        # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        order = "as_is",         # ノード名情報描画時の位置情報(項目名の並びはそのまま)
                        nudge_x = 0.06,          # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = -nudge_val_y)  # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)

# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g + 
      geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) + 
      geom_text(aes(label = 頻度), stat = "sankeynode", position = pos2, hjust = 0, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W2.3 図1c 遺伝子クラスタリング結果

 入力ファイルは、連載第19回のW13で作成したものです。これは、拡張子がcsvではなく、複数のファイルに分かれているものを別々に読み込んで、tibble形式にする手順の例になります。

in_f1 <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/MBCdeg_K3.xlsx" # 入力ファイル名
in_f2 <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/MBCdeg_K4.xlsx" # 入力ファイル名
in_f3 <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/MBCdeg_K5.xlsx" # 入力ファイル名

# 必要なパッケージをロード
library(openxlsx)                                # パッケージの読込
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
hoge1 <- read.xlsx(in_f1)                        # in_f1で指定したファイルの読込
hoge2 <- read.xlsx(in_f2)                        # in_f1で指定したファイルの読込
hoge3 <- read.xlsx(in_f3)                        # in_f1で指定したファイルの読込

# 前処理(必要な列のみの抽出)
res_K3 <- hoge1$`cls$cluster`                    # cls$cluster列のみを抽出
res_K4 <- hoge2$`cls$cluster`                    # cls$cluster列のみを抽出
res_K5 <- hoge3$`cls$cluster`                    # cls$cluster列のみを抽出

# 前処理(項目情報を見やすくするため"cluster"という文字列を連結)
cls_K3 <- str_c("cluster", res_K3)               # クラスタ番号の左側に文字列"cluster"を連結
cls_K4 <- str_c("cluster", res_K4)               # クラスタ番号の左側に文字列"cluster"を連結
cls_K5 <- str_c("cluster", res_K5)               # クラスタ番号の左側に文字列"cluster"を連結

# 前処理(tibble形式への変換)
data <- tibble(K3 = cls_K3,                      # cls_K3を列名をK3としてtibble形式で格納
               K4 = cls_K4,                      # cls_K4を列名をK4としてtibble形式で格納
               K5 = cls_K5,                      # cls_K5を列名をK5としてtibble形式で格納
               Freq = rep(1, nrow(hoge1)))       # 要素が全て1からなるベクトルを、列名をFreqとしてtibble形式で格納

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("K3", "K4", "K5"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto",         # 描画時の位置情報(ノード間の縦幅間隔は自動)
                       order = "as_is")          # 描画時の位置情報(ノード名の並びはそのまま)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Freq)*0.025             # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto",        # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        order = "as_is",         # ノード名情報描画時の位置情報(項目名の並びはそのまま)
                        nudge_x = 0.06,          # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = nudge_val_y)   # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto",        # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        order = "as_is",         # ノード名情報描画時の位置情報(項目名の並びはそのまま)
                        nudge_x = 0.06,          # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = -nudge_val_y)  # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)

# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g + 
      geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) + 
      geom_text(aes(label = Freq), stat = "sankeynode", position = pos2, hjust = 0, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W2.4 図1d メタゲノム系統推定結果

 入力ファイル(output_JSLAB24.xlsx)は、連載第24回のW4.4.3で作成したものです。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/output_JSLAB24.xlsx" # 入力ファイル名

# 必要なパッケージをロード
library(openxlsx)                                # パッケージの読込
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
hoge <- read.xlsx(in_f)                          # in_fで指定したファイルの読込

# 前処理(tibble形式への変換とフィルタリング)
data <- tibble(Phylum = hoge$Phylum,             # Phylum列の情報を列名をPhylumとしてtibble形式で格納
               Class = hoge$Class,               # Class列の情報を列名をClassとしてtibble形式で格納
               Order = hoge$Order,               # Order列の情報を列名をOrderとしてtibble形式で格納
               Family = hoge$Family,             # Family列の情報を列名をFamilyとしてtibble形式で格納
               Genus = hoge$Genus,               # Genus列の情報を列名をGenusとしてtibble形式で格納
               Species = hoge$Species,           # Species列の情報を列名をSpeciesとしてtibble形式で格納
               Freq = hoge$SRR6325813)           # SRR6325813列の情報を列名をFreqとしてtibble形式で格納
data.sub <- subset(data, Freq >= 300)            # Freq列が300以上の行のみ抽出

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data.sub,                   # 入力はdata.sub
              stages_from = c("Phylum", "Class", "Order", "Family", "Genus", "Species"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto")         # 描画時の位置情報(ノード間の縦幅間隔は自動)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
pos1 <- position_sankey(v_space = "auto",        # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        nudge_x = 0.06)          # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)

# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g + 
      geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 3) 

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15, hjust = 0)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W3 グラフ理論

  • グラフ理論
  • ggsankeyfier
    このページから見えているReference manualというところにあるggsankeyfier.pdfを開いて”edge”や”node”で文字列検索すると、多数ヒットすることがわかります。

W4 エッジの値

 図3は、以下のスクリプトをコピペ実行すれば得られます。

W4.1 図3a

 図1aとの違いは「作図2」の部分のみです。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_titanic.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("Outcome", "Sex", "Passengers"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto")         # 描画時の位置情報(ノード間の縦幅間隔は自動)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2(基本形gをベースとして、エッジに付随する情報を追加した結果をg2に格納)
# v_space = "auto"は、縦幅間隔は自動にせよという指令
# direction = "forward"は、エッジの向きを順方向(左から右)で描画せよという指令
# stat = "sankeyedge"は、描画するのがエッジ情報だという指令
# label = Freqは、描画するのがエッジの値だという指令
# position = pos3は、微調整用情報としてpos3を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令
pos3 <- position_sankey(v_space = "auto", direction = "forward")
g2 <- g + geom_text(aes(label = Freq), stat = "sankeyedge", position = pos3, hjust = 0, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W4.2 図3b

 W4.1との違いは、「作図2」中のdirection = "backward"hjust = 1の部分のみです。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_titanic.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("Outcome", "Sex", "Passengers"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto")         # 描画時の位置情報(ノード間の縦幅間隔は自動)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2(基本形gをベースとして、エッジに付随する情報を追加した結果をg2に格納)
# v_space = "auto"は、縦幅間隔は自動にせよという指令
# direction = "backward"は、エッジの向きを逆方向(右から左)で描画せよという指令
# stat = "sankeyedge"は、描画するのがエッジ情報だという指令
# label = Freqは、描画するのがエッジの値だという指令
# position = pos3は、微調整用情報としてpos3を利用せよという指令
# hjust = 1は、文字を右揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令
pos3 <- position_sankey(v_space = "auto", direction = "backward")
g2 <- g + geom_text(aes(label = Freq), stat = "sankeyedge", position = pos3, hjust = 1, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W5 情報の細分化

W5.1 図4

 入力ファイル(JSLAB26_titanic2.csv)は、W7.3で作成しています。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_titanic2.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("結末", "性別", "乗客"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto")         # 描画時の位置情報(ノード間の縦幅間隔は自動)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- 33                               # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto",        # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        nudge_x = 0.06,          # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = nudge_val_y)   # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto",        # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
                        nudge_x = 0.06,          # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = -nudge_val_y)  # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)

# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g + 
      geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) + 
      geom_text(aes(label = Freq), stat = "sankeynode", position = pos2, hjust = 0, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.position = 'none',            # 凡例を消す
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W5.2 図5

 以下のスクリプトをコピペ実行すれば得られます。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_titanic2.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("結末", "性別", "乗客"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto",         # 描画時の位置情報(ノード間の縦幅間隔は自動)
                       order = "as_is",          # 描画時の位置情報(ノード名の並びはそのまま)
                       align = "justify")        # 描画時の位置情報(カテゴリ間の高さは同じ)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos) +              # ノード情報を追加
  geom_sankeyedge(position = pos)                # エッジ情報を追加

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g + theme_minimal() +                      # 背景を白に変更
      theme(panel.grid = element_blank(),        # グリッド線を消す
            legend.text = element_text(size=12), # 凡例のサイズは12
            axis.title = element_blank(),        # 軸のタイトルを消す
            axis.text.y = element_blank(),       # y軸のメモリ表示を消す
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6 積み上げ棒グラフとベン図

 入力ファイル(JSLAB26_titanic.csv)は、図1aのものと同じです。

in_f <- "https://www.iu.a.u-tokyo.ac.jp/kadota/book/JSLAB26_titanic.csv" # 入力ファイル名

# 必要なパッケージをロード
library(tidyverse)                               # パッケージの読込
library(ggsankeyfier)                            # パッケージの読込

# 入力ファイルの読み込み
data <- read_csv(in_f)                           # in_fで指定したファイルの読込

# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer(                   # long型データへの変換
              data = data,                       # 入力はdataオブジェクト   
              stages_from = c("Outcome", "Sex", "Passengers"), # 描画させたいカテゴリ名情報
              values_from = "Freq")              # 頻度をカウントしたい列名情報

# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey()                         # 描画時の位置情報(ノード間の縦幅間隔は自動)
g <- ggplot(data = matome,                       # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
  mapping = aes(x = stage, y = Freq,             # matomeのstage列とFreq列をx軸とy軸として利用
                group = node, fill = node,       # groupとfillは、matome内のnode列で行う(変更不要)
                edge_id = edge_id,               # edge_idはmatome内のedge_id列(変更不要)
                connector = connector)) +        # connectorはmatome内のconnector列(変更不要)
  geom_sankeynode(position = pos)              # ノード情報を追加

# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Freq)*0.025             # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(nudge_x = 0.06,          # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = nudge_val_y)   # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(nudge_x = 0.06,          # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
                        nudge_y = -nudge_val_y)  # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)

# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g + 
      geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) + 
      geom_text(aes(label = Freq), stat = "sankeynode", position = pos2, hjust = 0, size = 4)

# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() +                     # 背景を白に変更
      theme(legend.position = 'none',            # 凡例を消す
            axis.title.x = element_blank(),      # 軸のタイトルを消す
            axis.title.y = element_text(size = 15),# y軸タイトルはサイズ15にせよ
            axis.text.y = element_text(size = 10), # y軸名はサイズ10にせよ
            axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W7 補足(入力ファイル作成コード)

W7.1 図1aの入力ファイル

 タイタニック号沈没事故の犠牲者と生存者の内訳から、以下のような感じでべた書きで入力ファイル(JSLAB26_titanic.csv)を作成しています。

data <- NULL
# Children
data <- rbind(data, t(replicate(5, c("Survivor", "Child", "1st-class"))))
data <- rbind(data, t(replicate(1, c("Casualty", "Child", "1st-class"))))
data <- rbind(data, t(replicate(24, c("Survivor", "Child", "2nd-class"))))
data <- rbind(data, t(replicate(27, c("Survivor", "Child", "3rd-class"))))
data <- rbind(data, t(replicate(52, c("Casualty", "Child", "3rd-class"))))

# Female
data <- rbind(data, t(replicate(20, c("Survivor", "Female", "Crew"))))
data <- rbind(data, t(replicate(3, c("Casualty", "Female", "Crew"))))
data <- rbind(data, t(replicate(140, c("Survivor", "Female", "1st-class"))))
data <- rbind(data, t(replicate(4, c("Casualty", "Female", "1st-class"))))
data <- rbind(data, t(replicate(80, c("Survivor", "Female", "2nd-class"))))
data <- rbind(data, t(replicate(13, c("Casualty", "Female", "2nd-class"))))
data <- rbind(data, t(replicate(76, c("Survivor", "Female", "3rd-class"))))
data <- rbind(data, t(replicate(89, c("Casualty", "Female", "3rd-class"))))

# Male
data <- rbind(data, t(replicate(192, c("Survivor", "Male", "Crew"))))
data <- rbind(data, t(replicate(693, c("Casualty", "Male", "Crew"))))
data <- rbind(data, t(replicate(57, c("Survivor", "Male", "1st-class"))))
data <- rbind(data, t(replicate(118, c("Casualty", "Male", "1st-class"))))
data <- rbind(data, t(replicate(14, c("Survivor", "Male", "2nd-class"))))
data <- rbind(data, t(replicate(154, c("Casualty", "Male", "2nd-class"))))
data <- rbind(data, t(replicate(75, c("Survivor", "Male", "3rd-class"))))
data <- rbind(data, t(replicate(387, c("Casualty", "Male", "3rd-class"))))

# Add Freq
data <- cbind(data, rep(1, nrow(data)))
colnames(data) <- c("Outcome", "Sex", "Passengers", "Freq")

# Output
write.csv(x = data, file = "JSLAB26_titanic.csv", row.names = F)

W7.2 図1bの入力ファイル

data <- NULL
# under20
data <- rbind(data, t(replicate(5, c("20歳未満", "A病院", "薬剤1", "有効"))))
data <- rbind(data, t(replicate(8, c("20歳未満", "A病院", "薬剤1", "無効"))))
data <- rbind(data, t(replicate(2, c("20歳未満", "A病院", "薬剤1", "不明"))))
data <- rbind(data, t(replicate(2, c("20歳未満", "A病院", "薬剤2", "有効"))))
data <- rbind(data, t(replicate(2, c("20歳未満", "A病院", "薬剤2", "無効"))))
data <- rbind(data, t(replicate(10, c("20歳未満", "A病院", "薬剤2", "不明"))))
data <- rbind(data, t(replicate(2, c("20歳未満", "A病院", "偽薬", "有効"))))
data <- rbind(data, t(replicate(4, c("20歳未満", "A病院", "偽薬", "不明"))))
data <- rbind(data, t(replicate(3, c("20歳未満", "A病院", "偽薬", "無効"))))

# 成人
data <- rbind(data, t(replicate(15, c("20-65歳", "A病院", "薬剤1", "有効"))))
data <- rbind(data, t(replicate(22, c("20-65歳", "A病院", "薬剤1", "無効"))))
data <- rbind(data, t(replicate(7, c("20-65歳", "A病院", "薬剤1", "不明"))))
data <- rbind(data, t(replicate(11, c("20-65歳", "A病院", "薬剤2", "有効"))))
data <- rbind(data, t(replicate(17, c("20-65歳", "A病院", "薬剤2", "無効"))))
data <- rbind(data, t(replicate(15, c("20-65歳", "A病院", "薬剤2", "不明"))))
data <- rbind(data, t(replicate(2, c("20-65歳", "A病院", "偽薬", "有効"))))
data <- rbind(data, t(replicate(12, c("20-65歳", "A病院", "偽薬", "無効"))))
data <- rbind(data, t(replicate(10, c("20-65歳", "A病院", "偽薬", "不明"))))
data <- rbind(data, t(replicate(10, c("20-65歳", "B病院", "薬剤1", "有効"))))
data <- rbind(data, t(replicate(12, c("20-65歳", "B病院", "薬剤1", "無効"))))
data <- rbind(data, t(replicate(9, c("20-65歳", "B病院", "薬剤1", "不明"))))
data <- rbind(data, t(replicate(8, c("20-65歳", "B病院", "薬剤2", "有効"))))
data <- rbind(data, t(replicate(3, c("20-65歳", "B病院", "薬剤2", "無効"))))
data <- rbind(data, t(replicate(4, c("20-65歳", "B病院", "薬剤2", "不明"))))

# 高齢者
data <- rbind(data, t(replicate(5, c("65歳以上", "B病院", "薬剤1", "有効"))))
data <- rbind(data, t(replicate(8, c("65歳以上", "B病院", "薬剤1", "無効"))))
data <- rbind(data, t(replicate(2, c("65歳以上", "B病院", "薬剤1", "不明"))))
data <- rbind(data, t(replicate(2, c("65歳以上", "B病院", "薬剤2", "有効"))))
data <- rbind(data, t(replicate(2, c("65歳以上", "B病院", "薬剤2", "無効"))))
data <- rbind(data, t(replicate(10, c("65歳以上", "B病院", "薬剤2", "不明"))))
data <- rbind(data, t(replicate(8, c("65歳以上", "B病院", "偽薬", "無効"))))
data <- rbind(data, t(replicate(4, c("65歳以上", "B病院", "偽薬", "不明"))))

# Add Freq
data <- cbind(data, rep(1, nrow(data)))
colnames(data) <- c("年齢", "病院", "種類", "結果", "頻度")

# Output
write.csv(x = data, file = "JSLAB26_medical.csv", row.names = F)

W7.3 図4の入力ファイル

data <- NULL
# Children
data <- rbind(data, t(replicate(5, c("生存者", "1等船客の子供", "1等船客"))))
data <- rbind(data, t(replicate(1, c("犠牲者", "1等船客の子供", "1等船客"))))
data <- rbind(data, t(replicate(24, c("生存者", "2等船客の子供", "2等船客"))))
data <- rbind(data, t(replicate(27, c("生存者", "3等船客の子供", "3等船客"))))
data <- rbind(data, t(replicate(52, c("犠牲者", "3等船客の子供", "3等船客"))))

# Female
data <- rbind(data, t(replicate(20, c("生存者", "女性乗員", "乗員"))))
data <- rbind(data, t(replicate(3, c("犠牲者", "女性乗員", "乗員"))))
data <- rbind(data, t(replicate(140, c("生存者", "1等船客の女性", "1等船客"))))
data <- rbind(data, t(replicate(4, c("犠牲者", "1等船客の女性", "1等船客"))))
data <- rbind(data, t(replicate(80, c("生存者", "2等船客の女性", "2等船客"))))
data <- rbind(data, t(replicate(13, c("犠牲者", "2等船客の女性", "2等船客"))))
data <- rbind(data, t(replicate(76, c("生存者", "3等船客の女性", "3等船客"))))
data <- rbind(data, t(replicate(89, c("犠牲者", "3等船客の女性", "3等船客"))))

# Male
data <- rbind(data, t(replicate(192, c("生存者", "男性乗員", "乗員"))))
data <- rbind(data, t(replicate(693, c("犠牲者", "男性乗員", "乗員"))))
data <- rbind(data, t(replicate(57, c("生存者", "1等船客の男性", "1等船客"))))
data <- rbind(data, t(replicate(118, c("犠牲者", "1等船客の男性", "1等船客"))))
data <- rbind(data, t(replicate(14, c("生存者", "2等船客の男性", "2等船客"))))
data <- rbind(data, t(replicate(154, c("犠牲者", "2等船客の男性", "2等船客"))))
data <- rbind(data, t(replicate(75, c("生存者", "3等船客の男性", "3等船客"))))
data <- rbind(data, t(replicate(387, c("犠牲者", "3等船客の男性", "3等船客"))))

# Add Freq
data <- cbind(data, rep(1, nrow(data)))
colnames(data) <- c("結末", "性別", "乗客", "Freq")

# Output
write.csv(x = data, file = "JSLAB26_titanic2.csv", row.names = F)
LS0tDQp0aXRsZTogIlvnrKwyNuWbnl0oaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9yX3NlcTIuaHRtbCNib29rX0pTTEFCXzI2KeOBruOCpuOCp+ODluizh+aWmSINCmRhdGU6ICfmnIDntYLmm7TmlrA6IGByIGZvcm1hdChTeXMuRGF0ZSgpLCAiJVkvJW0vJWQiKWAnDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCi0tLQ0KYGBge3Iga2xpcHB5LCBlY2hvPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQprbGlwcHk6OmtsaXBweSgpDQpgYGANCg0KIyBXMSDjga/jgZjjgoHjgasNCg0KLSBbZ2dzYW5rZXlmaWVyXShodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPWdnc2Fua2V5ZmllcikNCi0gW+mAo+i8ieesrDIw5ZueXShodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyMC5odG1sKQ0KDQojIyBXMS4xIOS6i+WJjea6luWCmTENCuOAgOOBk+OBruODmuODvOOCuOOBr+OAgVvjg4fjg7zjgr/op6PmnpDnkrDlooNSXShodHRwczovL3d3dy5yLXByb2plY3Qub3JnLynjgpLnlKjjgYTjgZ/kvZzlm7Plrp/nv5LjgpLlkKvjgb/jgb7jgZnjgIIqKuWun+e/kuOBq+WPluOCiue1hOOBv+OBn+OBhOaWuSoq44Gv44CBW+OBk+OBoeOCieOBruODquODs+OCr+WFiF0oaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL3RleHRib29rL2FwcGVuZGl4Lmh0bWwp44Gu44CMUjEuMDEwIFLmnKzkvZPjgahSU3R1ZGlv44Go44OR44OD44Kx44O844K444Gu44Kk44Oz44K544OI44O844Or44CN44GK44KI44Gz44CMUjEuMDIwIFJTdHVkaW/jga7ln7rmnKznmoTjgarliKnnlKjms5XjgI3jgpLkuIDpgJrjgorooYzjgaPjgabjgYrjgYTjgabkuIvjgZXjgYTjgILku6XkuIvjga/jgIFb44Oq44Oz44Kv5YWIXShodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAvdGV4dGJvb2svYXBwZW5kaXguaHRtbCnjga7jgrnjgq/jgrfjg6fjgafjgZnjgILikaDjgIHikaHjga7poIbjgavlkIToh6rjga5PU+eUqOOBruOCguOBruOCkuihjOOBo+OBpuOBj+OBoOOBleOBhO+8iOe0hDPmmYLplpPvvInjgIIqKlLjgb7jgZ/jga9SU3R1ZGlv44Gu5Z+65pys55qE44Gq5Yip55So5rOV44GM55CG6Kej44Gn44GN44Gm44GE44KM44Gw44CB44GT44GT44Gv44K544Kt44OD44OX44GX44Gm44KC44GL44G+44GE44G+44Gb44KTKirjgIINCg0KIVtdKGh0dHBzOi8vd3d3Lml1LmEudS10b2t5by5hYy5qcC9rYWRvdGEvYm9vay9SaW5zdGFsbC5wbmcpe3dpZHRoPSI2MDAifQ0KDQojIyBXMS4yIOS6i+WJjea6luWCmTINCuOAgOOBk+OBk+OBp+OBr+OAgVtnZ3NhbmtleWZpZXJdKGh0dHBzOi8vQ1JBTi5SLXByb2plY3Qub3JnL3BhY2thZ2U9Z2dzYW5rZXlmaWVyKeOBqFt0aWR5dmVyc2VdKGh0dHBzOi8vd3d3LnRpZHl2ZXJzZS5vcmcvKeOBqFtvcGVueGxzeF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvcGFja2FnZT1vcGVueGxzeCnjga7jgqTjg7Pjgrnjg4jjg7zjg6vjgpLooYzjgYTjgb7jgZnjgIIz44Gk44Gu44OR44OD44Kx44O844K444Gv44CB5Lul5LiL44Gu44Kz44OU44Oa44Gn44Kk44Oz44K544OI44O844Or44Gn44GN44G+44GZ44CCW29wZW54bHN4XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy9wYWNrYWdlPW9wZW54bHN4KeOBr+OAgXhsc3jlvaLlvI/jg5XjgqHjgqTjg6vjga7oqq3ovrzmmYLjgavlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgafjgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPUZBTFNFLCBjb21tZW50PSIifQ0KaWYgKCFyZXF1aXJlKCJCaW9jTWFuYWdlciIsIHF1aWV0bHkgPSBUUlVFKSkgICAgICMgQmlvY01hbmFnZXLjg5Hjg4PjgrHjg7zjgrjjgYzjgqTjg7Pjgrnjg4jjg7zjg6vjgZXjgozjgabjgarjgZHjgozjgbAuLi4NCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJCaW9jTWFuYWdlciIpICAgICAgICAgICAgICAjIEJpb2NNYW5hZ2Vy44KS44Kk44Oz44K544OI44O844Or44Gb44KIDQpCaW9jTWFuYWdlcjo6aW5zdGFsbCgiZ2dzYW5rZXlmaWVyIiwgdXBkYXRlPUYpICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7jgqTjg7Pjgrnjg4jjg7zjg6vvvIhnZ3NhbmtleWZpZXLvvIkNCkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJ0aWR5dmVyc2UiLCB1cGRhdGU9RikgICAgICAjIOODkeODg+OCseODvOOCuOOBruOCpOODs+OCueODiOODvOODq++8iHRpZHl2ZXJzZe+8iQ0KQmlvY01hbmFnZXI6Omluc3RhbGwoIm9wZW54bHN4IiwgdXBkYXRlPUYpICAgICAgICMg44OR44OD44Kx44O844K444Gu44Kk44Oz44K544OI44O844Or77yIb3Blbnhsc3jvvIkNCmBgYA0KDQojIyBXMS4zIOOCqOODqeODvOmBremBh+aZguOBruWvvuWHpuazlQ0K44CA44GT44GT44Gv44Ko44Op44O844Gr6YGt6YGH44GX44Gf44OS44OI55So44Gu6KOc6Laz5oOF5aCx44Gn44GZ44CCUuacrOS9k+OBruODkOODvOOCuOODp+ODs+OBjOWPpOOBhOOBqOOAgeS4iuiomOOCueOCr+ODquODl+ODiOOBp+OBr+OBhuOBvuOBj+OBhOOBi+OBquOBhOOBk+OBqOOBjOOBguOCiuOBvuOBmeOAguS+i+OBiOOBsOOAgTIwMjXlubQ05pyIM+aXpeePvuWcqOOBrlLmnKzkvZPjga7mnIDmlrDniYjjga80LjQuM+OBp+OBmeOBjOOAgeODkOODvOOCuOODp+ODs+OBjDQuMy4w5Lul5LiL44Gn44GZ44Go44GK44Gd44KJ44GP44Kz44Kx44G+44GZ44CCKiox44Gk44Gu5a++5Yem5rOV44Gv44CBUuacrOS9k+OBruODkOODvOOCuOODp+ODs+OCkuS4iuOBkuOBpuS4iuiomOOCkuOChOOCiuebtOOBmeOBk+OBqCoq44Gn44GZ44CC44Gd44GX44Gm44KC44GGMeOBpOOBruWvvuWHpuazleOBr+OAgSoq54++5Zyo5Yip55So5Lit44GuUuOBruOBvuOBvuOBp+S7peS4i+OCkuWun+ihjOOBmeOCi+OBk+OBqCoq44Gn44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRSwgY29tbWVudD0iIn0NCmluc3RhbGwucGFja2FnZXMoImdnc2Fua2V5ZmllciIsIHJlcG9zID0gImh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZy8iKQ0KaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgcmVwb3MgPSAiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnLyIpDQppbnN0YWxsLnBhY2thZ2VzKCJvcGVueGxzeCIsIHJlcG9zID0gImh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZy8iKQ0KYGBgDQoNCiMgVzIg44K144Oz44Kt44O85Zuz44Gu5YW35L2T5L6LDQrjgIDlm7Mx44Gv44CB5Lul5LiL44Gu44K544Kv44Oq44OX44OI44KS44Kz44OU44Oa5a6f6KGM44GZ44KM44Gw5b6X44KJ44KM44G+44GZ44CCDQoNCiMjIFcyLjEg5ZuzMWEg44K/44Kk44K/44OL44OD44Kv5Y+35rKI5rKh5LqL5pWFDQrjgIDlhaXlipvjg5XjgqHjgqTjg6vvvIhbSlNMQUIyNl90aXRhbmljLmNzdl0oaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL0pTTEFCMjZfdGl0YW5pYy5jc3Yp77yJ44Gv44CB44Km44Kj44Kt44Oa44OH44Kj44Ki44GuW+OCv+OCpOOCv+ODi+ODg+OCr+WPt+ayiOayoeS6i+aVhV0oaHR0cHM6Ly9qYS53aWtpcGVkaWEub3JnL3dpa2kvJUUzJTgyJUJGJUUzJTgyJUE0JUUzJTgyJUJGJUUzJTgzJThCJUUzJTgzJTgzJUUzJTgyJUFGJUU1JThGJUI3JUU2JUIyJTg4JUU2JUIyJUExJUU0JUJBJThCJUU2JTk1JTg1KeOBrueKoOeJsuiAheOBqOeUn+WtmOiAheOBruWGheios+ODh+ODvOOCv+OBi+OCieiHquS9nOOBl+OBpuOBhOOBvuOBme+8iFc3LjHvvInjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRX0NCmluX2YgPC0gImh0dHBzOi8vd3d3Lml1LmEudS10b2t5by5hYy5qcC9rYWRvdGEvYm9vay9KU0xBQjI2X3RpdGFuaWMuY3N2IiAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiT3V0Y29tZSIsICJTZXgiLCAiUGFzc2VuZ2VycyIpLCAjIOaPj+eUu+OBleOBm+OBn+OBhOOCq+ODhuOCtOODquWQjeaDheWgsQ0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9ICJGcmVxIikgICAgICAgICAgICAgICMg6aC75bqm44KS44Kr44Km44Oz44OI44GX44Gf44GE5YiX5ZCN5oOF5aCxDQoNCiMg5L2c5ZuzMe+8iOOCteODs+OCreODvOWbs+OBruWfuuacrOW9ouOBvuOBp+S9nOaIkOOBl+OBn+e1kOaenOOCkmfjgavmoLzntI3vvIkNCnBvcyA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIikgICAgICAgICAjIOaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXEsICAgICAgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVx5YiX44KSeOi7uOOBqHnou7jjgajjgZfjgabliKnnlKgNCiAgICAgICAgICAgICAgICBncm91cCA9IG5vZGUsIGZpbGwgPSBub2RlLCAgICAgICAjIGdyb3Vw44GoZmlsbOOBr+OAgW1hdG9tZeWGheOBrm5vZGXliJfjgafooYzjgYbvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBlZGdlX2lkID0gZWRnZV9pZCwgICAgICAgICAgICAgICAjIGVkZ2VfaWTjga9tYXRvbWXlhoXjga5lZGdlX2lk5YiX77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgY29ubmVjdG9yID0gY29ubmVjdG9yKSkgKyAgICAgICAgIyBjb25uZWN0b3Ljga9tYXRvbWXlhoXjga5jb25uZWN0b3LliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgZ2VvbV9zYW5rZXlub2RlKHBvc2l0aW9uID0gcG9zKSArICAgICAgICAgICAgICAjIOODjuODvOODieaDheWgseOCkui/veWKoA0KICBnZW9tX3NhbmtleWVkZ2UocG9zaXRpb24gPSBwb3MpICAgICAgICAgICAgICAgICMg44Ko44OD44K45oOF5aCx44KS6L+95YqgDQoNCiMg5L2c5ZuzMi0x77yI44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS5o+P55S744GZ44KL6Zqb44Gr5Yip55So44GZ44KL5b6u6Kq/5pW055So44Gu44OR44Op44Oh44O844K/5L2c5oiQ77yJDQojIHnou7jjga7pq5jjgZXjga/lhaXlipvjg5XjgqHjgqTjg6vjga7ooYzmlbDmrKHnrKzjgarjga7jgafjgIFucm93KGRhdGEp44Gu5L2VJeeoi+W6puS4iuS4i+OBq+OBmuOCieOBmeOBi+OBqOOBhOOBhuaEn+OBmOOBruioiOeul+OCkuOBl+OBpuOBhOOCiw0KIyBudWRnZV9444GobnVkZ2VfeeOBr+OAgXjou7jjgah56Lu444Gd44KM44Ge44KM44Gu5pa55ZCR44Gr5bCR44GX44Ga44KJ44GX44Gf44GE5YCk44Gn44GZ77yIbnVkZ2Xjga/lsI/nqoHjgY/jgajjgYTjgYbmhI/lkbPvvIkNCm51ZGdlX3ZhbF95IDwtIHN1bShkYXRhJEZyZXEpKjAuMDI1ICAgICAgICAgICAg44CAIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSAtbnVkZ2VfdmFsX3kpICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4i+OBq+OBmuOCieOBme+8iQ0KDQojIOS9nOWbszItMu+8iOWfuuacrOW9omfjgpLjg5njg7zjgrnjgajjgZfjgabjgIHjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLov73liqDjgZfjgZ/ntZDmnpzjgpJnMuOBq+agvOe0je+8iQ0KIyBzdGF0ID0gInNhbmtleW5vZGUi44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5oOF5aCx44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gbm9kZeOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieWQjeOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IEZyZXHjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4njgavku5jpmo/jgZnjgovpoLvluqblgKTjgaDjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3Mx44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMeOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczLjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3My44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIGhqdXN0ID0gMOOBr+OAgeaWh+Wtl+OCkuW3puaPg+OBiOOBp+aPj+eUu+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOODh+ODleOCqeODq+ODiOOBr+S4reWkruaPg+OBiO+8iQ0KIyBzaXplID0gNOOBr+OAgeOCteOCpOOCujTjgavjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjgZPjga7lgKTjgavlv5zjgZjjgaZudWRnZV9544KC6YGp5a6c6Kq/5pW044GZ44KL77yJDQpnMiA8LSBnICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbm9kZSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMSwgaGp1c3QgPSAwLCBzaXplID0gNCkgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBGcmVxKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcm0obGlzdCA9IGxzKCkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kq44OW44K444Kn44Kv44OI44Gu5YWo5raI5Y67DQpgYGANCg0KIyMgVzIuMiDlm7MxYiDku67mg7PolqzliaTlv5znrZTop6PmnpDntZDmnpwNCuOAgOWFpeWKm+ODleOCoeOCpOODq++8iFtKU0xBQjI2X21lZGljYWwuY3N2XShodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNl9tZWRpY2FsLmNzdinvvInjga/jgIFXNy4y44Gn5L2c5oiQ44GX44Gm44GE44G+44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUV9DQppbl9mIDwtICJodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNl9tZWRpY2FsLmNzdiIgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIuW5tOm9oiIsICLnl4XpmaIiLCAi56iu6aGeIiwgIue1kOaenCIpLCAjIOaPj+eUu+OBleOBm+OBn+OBhOOCq+ODhuOCtOODquWQjeaDheWgsQ0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9ICLpoLvluqYiKSAgICAgICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gImFzX2lzIikgICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nlkI3jga7kuKbjgbPjga/jgZ3jga7jgb7jgb7vvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSDpoLvluqYsICAgICAgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgajpoLvluqbliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEk6aC75bqmKSowLjAyNSAgICAgICAgICAgIOOAgCMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9ICJhc19pcyIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjpoIXnm67lkI3jga7kuKbjgbPjga/jgZ3jga7jgb7jgb7vvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSAiYXNfaXMiLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI6aCF55uu5ZCN44Gu5Lim44Gz44Gv44Gd44Gu44G+44G+77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IOmgu+W6piksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnJtKGxpc3QgPSBscygpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOOBruWFqOa2iOWOuw0KYGBgDQoNCiMjIFcyLjMg5ZuzMWMg6YG65Lyd5a2Q44Kv44Op44K544K/44Oq44Oz44Kw57WQ5p6cDQrjgIDlhaXlipvjg5XjgqHjgqTjg6vjga/jgIFb6YCj6LyJ56ysMTnlm55dKGh0dHBzOi8vd3d3Lml1LmEudS10b2t5by5hYy5qcC9rYWRvdGEvcl9zZXEyLmh0bWwjYm9va19KU0xBQl8xOSnjga5XMTPjgafkvZzmiJDjgZfjgZ/jgoLjga7jgafjgZnjgILjgZPjgozjga/jgIHmi6HlvLXlrZDjgYxjc3bjgafjga/jgarjgY/jgIHopIfmlbDjga7jg5XjgqHjgqTjg6vjgavliIbjgYvjgozjgabjgYTjgovjgoLjga7jgpLliKXjgIXjgavoqq3jgb/ovrzjgpPjgafjgIFgdGliYmxlYOW9ouW8j+OBq+OBmeOCi+aJi+mghuOBruS+i+OBq+OBquOCiuOBvuOBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KaW5fZjEgPC0gImh0dHBzOi8vd3d3Lml1LmEudS10b2t5by5hYy5qcC9rYWRvdGEvYm9vay9NQkNkZWdfSzMueGxzeCIgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCmluX2YyIDwtICJodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svTUJDZGVnX0s0Lnhsc3giICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQppbl9mMyA8LSAiaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL01CQ2RlZ19LNS54bHN4IiAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeShvcGVueGxzeCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCmxpYnJhcnkoZ2dzYW5rZXlmaWVyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KDQojIOWFpeWKm+ODleOCoeOCpOODq+OBruiqreOBv+i+vOOBvw0KaG9nZTEgPC0gcmVhZC54bHN4KGluX2YxKSAgICAgICAgICAgICAgICAgICAgICAgICMgaW5fZjHjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCmhvZ2UyIDwtIHJlYWQueGxzeChpbl9mMikgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2Yx44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQpob2dlMyA8LSByZWFkLnhsc3goaW5fZjMpICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9mMeOBp+aMh+WumuOBl+OBn+ODleOCoeOCpOODq+OBruiqrei+vA0KDQojIOWJjeWHpueQhu+8iOW/heimgeOBquWIl+OBruOBv+OBruaKveWHuu+8iQ0KcmVzX0szIDwtIGhvZ2UxJGBjbHMkY2x1c3RlcmAgICAgICAgICAgICAgICAgICAgICMgY2xzJGNsdXN0ZXLliJfjga7jgb/jgpLmir3lh7oNCnJlc19LNCA8LSBob2dlMiRgY2xzJGNsdXN0ZXJgICAgICAgICAgICAgICAgICAgICAjIGNscyRjbHVzdGVy5YiX44Gu44G/44KS5oq95Ye6DQpyZXNfSzUgPC0gaG9nZTMkYGNscyRjbHVzdGVyYCAgICAgICAgICAgICAgICAgICAgIyBjbHMkY2x1c3RlcuWIl+OBruOBv+OCkuaKveWHug0KDQojIOWJjeWHpueQhu+8iOmgheebruaDheWgseOCkuimi+OChOOBmeOBj+OBmeOCi+OBn+OCgSJjbHVzdGVyIuOBqOOBhOOBhuaWh+Wtl+WIl+OCkumAo+e1kO+8iQ0KY2xzX0szIDwtIHN0cl9jKCJjbHVzdGVyIiwgcmVzX0szKSAgICAgICAgICAgICAgICMg44Kv44Op44K544K/55Wq5Y+344Gu5bem5YG044Gr5paH5a2X5YiXImNsdXN0ZXIi44KS6YCj57WQDQpjbHNfSzQgPC0gc3RyX2MoImNsdXN0ZXIiLCByZXNfSzQpICAgICAgICAgICAgICAgIyDjgq/jg6njgrnjgr/nlarlj7fjga7lt6blgbTjgavmloflrZfliJciY2x1c3RlciLjgpLpgKPntZANCmNsc19LNSA8LSBzdHJfYygiY2x1c3RlciIsIHJlc19LNSkgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+eVquWPt+OBruW3puWBtOOBq+aWh+Wtl+WIlyJjbHVzdGVyIuOCkumAo+e1kA0KDQojIOWJjeWHpueQhu+8iHRpYmJsZeW9ouW8j+OBuOOBruWkieaPm++8iQ0KZGF0YSA8LSB0aWJibGUoSzMgPSBjbHNfSzMsICAgICAgICAgICAgICAgICAgICAgICMgY2xzX0sz44KS5YiX5ZCN44KSSzPjgajjgZfjgaZ0aWJibGXlvaLlvI/jgafmoLzntI0NCiAgICAgICAgICAgICAgIEs0ID0gY2xzX0s0LCAgICAgICAgICAgICAgICAgICAgICAjIGNsc19LNOOCkuWIl+WQjeOCkks044Go44GX44GmdGliYmxl5b2i5byP44Gn5qC857SNDQogICAgICAgICAgICAgICBLNSA9IGNsc19LNSwgICAgICAgICAgICAgICAgICAgICAgIyBjbHNfSzXjgpLliJflkI3jgpJLNeOBqOOBl+OBpnRpYmJsZeW9ouW8j+OBp+agvOe0jQ0KICAgICAgICAgICAgICAgRnJlcSA9IHJlcCgxLCBucm93KGhvZ2UxKSkpICAgICAgICMg6KaB57Sg44GM5YWo44GmMeOBi+OCieOBquOCi+ODmeOCr+ODiOODq+OCkuOAgeWIl+WQjeOCkkZyZXHjgajjgZfjgaZ0aWJibGXlvaLlvI/jgafmoLzntI0NCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcSIpICAgICAgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSAiYXNfaXMiKSAgICAgICAgICAjIOaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieWQjeOBruS4puOBs+OBr+OBneOBruOBvuOBvu+8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXEsICAgICAgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVx5YiX44KSeOi7uOOBqHnou7jjgajjgZfjgabliKnnlKgNCiAgICAgICAgICAgICAgICBncm91cCA9IG5vZGUsIGZpbGwgPSBub2RlLCAgICAgICAjIGdyb3Vw44GoZmlsbOOBr+OAgW1hdG9tZeWGheOBrm5vZGXliJfjgafooYzjgYbvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBlZGdlX2lkID0gZWRnZV9pZCwgICAgICAgICAgICAgICAjIGVkZ2VfaWTjga9tYXRvbWXlhoXjga5lZGdlX2lk5YiX77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgY29ubmVjdG9yID0gY29ubmVjdG9yKSkgKyAgICAgICAgIyBjb25uZWN0b3Ljga9tYXRvbWXlhoXjga5jb25uZWN0b3LliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgZ2VvbV9zYW5rZXlub2RlKHBvc2l0aW9uID0gcG9zKSArICAgICAgICAgICAgICAjIOODjuODvOODieaDheWgseOCkui/veWKoA0KICBnZW9tX3NhbmtleWVkZ2UocG9zaXRpb24gPSBwb3MpICAgICAgICAgICAgICAgICMg44Ko44OD44K45oOF5aCx44KS6L+95YqgDQoNCiMg5L2c5ZuzMi0x77yI44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS5o+P55S744GZ44KL6Zqb44Gr5Yip55So44GZ44KL5b6u6Kq/5pW055So44Gu44OR44Op44Oh44O844K/5L2c5oiQ77yJDQojIHnou7jjga7pq5jjgZXjga/lhaXlipvjg5XjgqHjgqTjg6vjga7ooYzmlbDmrKHnrKzjgarjga7jgafjgIFucm93KGRhdGEp44Gu5L2VJeeoi+W6puS4iuS4i+OBq+OBmuOCieOBmeOBi+OBqOOBhOOBhuaEn+OBmOOBruioiOeul+OCkuOBl+OBpuOBhOOCiw0KIyBudWRnZV9444GobnVkZ2VfeeOBr+OAgXjou7jjgah56Lu444Gd44KM44Ge44KM44Gu5pa55ZCR44Gr5bCR44GX44Ga44KJ44GX44Gf44GE5YCk44Gn44GZ77yIbnVkZ2Xjga/lsI/nqoHjgY/jgajjgYTjgYbmhI/lkbPvvIkNCm51ZGdlX3ZhbF95IDwtIHN1bShkYXRhJEZyZXEpKjAuMDI1ICAgICAgICAgICAg44CAIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gImFzX2lzIiwgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOmgheebruWQjeOBruS4puOBs+OBr+OBneOBruOBvuOBvu+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9ICJhc19pcyIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjpoIXnm67lkI3jga7kuKbjgbPjga/jgZ3jga7jgb7jgb7vvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnJtKGxpc3QgPSBscygpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOOBruWFqOa2iOWOuw0KYGBgDQoNCiMjIFcyLjQg5ZuzMWQg44Oh44K/44Ky44OO44Og57O757Wx5o6o5a6a57WQ5p6cDQrjgIDlhaXlipvjg5XjgqHjgqTjg6vvvIhbb3V0cHV0X0pTTEFCMjQueGxzeF0oaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL291dHB1dF9KU0xBQjI0Lnhsc3gp77yJ44Gv44CBW+mAo+i8ieesrDI05ZueXShodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNC5odG1sKeOBrlc0LjQuM+OBp+S9nOaIkOOBl+OBn+OCguOBruOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KaW5fZiA8LSAiaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL291dHB1dF9KU0xBQjI0Lnhsc3giICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQoNCiMg5b+F6KaB44Gq44OR44OD44Kx44O844K444KS44Ot44O844OJDQpsaWJyYXJ5KG9wZW54bHN4KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpob2dlIDwtIHJlYWQueGxzeChpbl9mKSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yIdGliYmxl5b2i5byP44G444Gu5aSJ5o+b44Go44OV44Kj44Or44K/44Oq44Oz44Kw77yJDQpkYXRhIDwtIHRpYmJsZShQaHlsdW0gPSBob2dlJFBoeWx1bSwgICAgICAgICAgICAgIyBQaHlsdW3liJfjga7mg4XloLHjgpLliJflkI3jgpJQaHlsdW3jgajjgZfjgaZ0aWJibGXlvaLlvI/jgafmoLzntI0NCiAgICAgICAgICAgICAgIENsYXNzID0gaG9nZSRDbGFzcywgICAgICAgICAgICAgICAjIENsYXNz5YiX44Gu5oOF5aCx44KS5YiX5ZCN44KSQ2xhc3PjgajjgZfjgaZ0aWJibGXlvaLlvI/jgafmoLzntI0NCiAgICAgICAgICAgICAgIE9yZGVyID0gaG9nZSRPcmRlciwgICAgICAgICAgICAgICAjIE9yZGVy5YiX44Gu5oOF5aCx44KS5YiX5ZCN44KST3JkZXLjgajjgZfjgaZ0aWJibGXlvaLlvI/jgafmoLzntI0NCiAgICAgICAgICAgICAgIEZhbWlseSA9IGhvZ2UkRmFtaWx5LCAgICAgICAgICAgICAjIEZhbWlseeWIl+OBruaDheWgseOCkuWIl+WQjeOCkkZhbWlseeOBqOOBl+OBpnRpYmJsZeW9ouW8j+OBp+agvOe0jQ0KICAgICAgICAgICAgICAgR2VudXMgPSBob2dlJEdlbnVzLCAgICAgICAgICAgICAgICMgR2VudXPliJfjga7mg4XloLHjgpLliJflkI3jgpJHZW51c+OBqOOBl+OBpnRpYmJsZeW9ouW8j+OBp+agvOe0jQ0KICAgICAgICAgICAgICAgU3BlY2llcyA9IGhvZ2UkU3BlY2llcywgICAgICAgICAgICMgU3BlY2llc+WIl+OBruaDheWgseOCkuWIl+WQjeOCklNwZWNpZXPjgajjgZfjgaZ0aWJibGXlvaLlvI/jgafmoLzntI0NCiAgICAgICAgICAgICAgIEZyZXEgPSBob2dlJFNSUjYzMjU4MTMpICAgICAgICAgICAjIFNSUjYzMjU4MTPliJfjga7mg4XloLHjgpLliJflkI3jgpJGcmVx44Go44GX44GmdGliYmxl5b2i5byP44Gn5qC857SNDQpkYXRhLnN1YiA8LSBzdWJzZXQoZGF0YSwgRnJlcSA+PSAzMDApICAgICAgICAgICAgIyBGcmVx5YiX44GMMzAw5Lul5LiK44Gu6KGM44Gu44G/5oq95Ye6DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YS5zdWIsICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YS5zdWINCiAgICAgICAgICAgICAgc3RhZ2VzX2Zyb20gPSBjKCJQaHlsdW0iLCAiQ2xhc3MiLCAiT3JkZXIiLCAiRmFtaWx5IiwgIkdlbnVzIiwgIlNwZWNpZXMiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcSIpICAgICAgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIpICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxLCAgICAgICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlceWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2KSAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSAzKSANCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGhqdXN0ID0gMCkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcm0obGlzdCA9IGxzKCkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kq44OW44K444Kn44Kv44OI44Gu5YWo5raI5Y67DQpgYGANCg0KIyBXMyDjgrDjg6njg5XnkIboq5YNCg0KLSBb44Kw44Op44OV55CG6KuWXShodHRwczovL2phLndpa2lwZWRpYS5vcmcvd2lraS8lRTMlODIlQjAlRTMlODMlQTklRTMlODMlOTUlRTclOTAlODYlRTglQUIlOTYpDQotIFtnZ3NhbmtleWZpZXJdKGh0dHBzOi8vQ1JBTi5SLXByb2plY3Qub3JnL3BhY2thZ2U9Z2dzYW5rZXlmaWVyKSAgDQrjgZPjga7jg5rjg7zjgrjjgYvjgonopovjgYjjgabjgYTjgotSZWZlcmVuY2UgbWFudWFs44Go44GE44GG44Go44GT44KN44Gr44GC44KLW2dnc2Fua2V5Zmllci5wZGZdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9nZ3NhbmtleWZpZXIvZ2dzYW5rZXlmaWVyLnBkZinjgpLplovjgYTjgaYiZWRnZSLjgoQibm9kZSLjgafmloflrZfliJfmpJzntKLjgZnjgovjgajjgIHlpJrmlbDjg5Ljg4Pjg4jjgZnjgovjgZPjgajjgYzjgo/jgYvjgorjgb7jgZnjgIINCg0KIyBXNCDjgqjjg4Pjgrjjga7lgKQNCuOAgOWbszPjga/jgIHku6XkuIvjga7jgrnjgq/jg6rjg5fjg4jjgpLjgrPjg5Tjg5rlrp/ooYzjgZnjgozjgbDlvpfjgonjgozjgb7jgZnjgIINCg0KIyMgVzQuMSDlm7MzYQ0K44CA5ZuzMWHjgajjga7pgZXjgYTjga/jgIzkvZzlm7My44CN44Gu6YOo5YiG44Gu44G/44Gn44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUV9DQppbl9mIDwtICJodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNl90aXRhbmljLmNzdiIgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIk91dGNvbWUiLCAiU2V4IiwgIlBhc3NlbmdlcnMiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcSIpICAgICAgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIpICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxLCAgICAgICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlceWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44Ko44OD44K444Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgdl9zcGFjZSA9ICJhdXRvIuOBr+OAgee4puW5hemWk+malOOBr+iHquWLleOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBkaXJlY3Rpb24gPSAiZm9yd2FyZCLjga/jgIHjgqjjg4Pjgrjjga7lkJHjgY3jgpLpoIbmlrnlkJHvvIjlt6bjgYvjgonlj7PvvInjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgc3RhdCA9ICJzYW5rZXllZGdlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOOCqOODg+OCuOaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IEZyZXHjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjgqjjg4Pjgrjjga7lgKTjgaDjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3Mz44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zM+OCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5LukDQpwb3MzIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCBkaXJlY3Rpb24gPSAiZm9yd2FyZCIpDQpnMiA8LSBnICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXEpLCBzdGF0ID0gInNhbmtleWVkZ2UiLCBwb3NpdGlvbiA9IHBvczMsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpDQoNCiMg5L2c5ZuzM++8iGcy44KS44OZ44O844K544Go44GX44Gm44CB6IOM5pmv44KE5Yeh5L6L44Gq44Gp44KS5raI44GZ44Gq44Gp44Gu6Kq/5pW044KS6KGM44Gj44Gf57WQ5p6c44KSZzPjgavmoLzntI3vvIkNCmczIDwtIGcyICsgdGhlbWVfbWluaW1hbCgpICsgICAgICAgICAgICAgICAgICAgICAjIOiDjOaZr+OCkueZveOBq+WkieabtA0KICAgICAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg44Kw44Oq44OD44OJ57ea44KS5raI44GZDQogICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScsICAgICAgICAgICAgIyDlh6HkvovjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOi7uOOBruOCv+OCpOODiOODq+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICMgeei7uOOBruODoeODouODquihqOekuuOCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgIyB46Lu477yI44Kr44OG44K044Oq5ZCN77yJ44Gv44K144Kk44K6MTXjgavjgZvjgogNCmczDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpybShsaXN0ID0gbHMoKSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjgqrjg5bjgrjjgqfjgq/jg4jjga7lhajmtojljrsNCmBgYA0KDQojIyBXNC4yIOWbszNiDQrjgIBXNC4x44Go44Gu6YGV44GE44Gv44CB44CM5L2c5ZuzMuOAjeS4reOBrmBkaXJlY3Rpb24gPSAiYmFja3dhcmQiYOOBqGBoanVzdCA9IDFg44Gu6YOo5YiG44Gu44G/44Gn44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUV9DQppbl9mIDwtICJodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNl90aXRhbmljLmNzdiIgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIk91dGNvbWUiLCAiU2V4IiwgIlBhc3NlbmdlcnMiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcSIpICAgICAgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIpICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxLCAgICAgICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlceWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44Ko44OD44K444Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgdl9zcGFjZSA9ICJhdXRvIuOBr+OAgee4puW5hemWk+malOOBr+iHquWLleOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBkaXJlY3Rpb24gPSAiYmFja3dhcmQi44Gv44CB44Ko44OD44K444Gu5ZCR44GN44KS6YCG5pa55ZCR77yI5Y+z44GL44KJ5bem77yJ44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5LukDQojIHN0YXQgPSAic2Fua2V5ZWRnZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjgqjjg4Pjgrjmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44Ko44OD44K444Gu5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zM+OBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczPjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAx44Gv44CB5paH5a2X44KS5Y+z5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pA0KcG9zMyA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgZGlyZWN0aW9uID0gImJhY2t3YXJkIikNCmcyIDwtIGcgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcSksIHN0YXQgPSAic2Fua2V5ZWRnZSIsIHBvc2l0aW9uID0gcG9zMywgaGp1c3QgPSAxLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnJtKGxpc3QgPSBscygpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOOBruWFqOa2iOWOuw0KYGBgDQoNCiMgVzUg5oOF5aCx44Gu57Sw5YiG5YyWDQoNCiMjIFc1LjEg5ZuzNA0K44CA5YWl5Yqb44OV44Kh44Kk44Or77yIW0pTTEFCMjZfdGl0YW5pYzIuY3N2XShodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNl90aXRhbmljMi5jc3Yp77yJ44Gv44CBVzcuM+OBp+S9nOaIkOOBl+OBpuOBhOOBvuOBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OS40fQ0KaW5fZiA8LSAiaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL0pTTEFCMjZfdGl0YW5pYzIuY3N2IiAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygi57WQ5pyrIiwgIuaAp+WIpSIsICLkuZflrqIiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcSIpICAgICAgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIpICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxLCAgICAgICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlceWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSAzMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOOAgCMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IG51ZGdlX3ZhbF95KSAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiK44Gr44Ga44KJ44GZ77yJDQpwb3MyIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnJtKGxpc3QgPSBscygpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOOBruWFqOa2iOWOuw0KYGBgDQoNCiMjIFc1LjIg5ZuzNQ0K44CA5Lul5LiL44Gu44K544Kv44Oq44OX44OI44KS44Kz44OU44Oa5a6f6KGM44GZ44KM44Gw5b6X44KJ44KM44G+44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fQ0KaW5fZiA8LSAiaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL0pTTEFCMjZfdGl0YW5pYzIuY3N2IiAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygi57WQ5pyrIiwgIuaAp+WIpSIsICLkuZflrqIiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcSIpICAgICAgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSAiYXNfaXMiLCAgICAgICAgICAjIOaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieWQjeOBruS4puOBs+OBr+OBneOBruOBvuOBvu+8iQ0KICAgICAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJqdXN0aWZ5IikgICAgICAgICMg5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44Kr44OG44K044Oq6ZaT44Gu6auY44GV44Gv5ZCM44GY77yJDQpnIDwtIGdncGxvdChkYXRhID0gbWF0b21lLCAgICAgICAgICAgICAgICAgICAgICAgIyBnZ3Bsb3TplqLmlbDlrp/ooYzntZDmnpzjgpJn44Gr5qC857SN44CC5YWl5Yqb44GvbWF0b21l44Kq44OW44K444Kn44Kv44OIDQogIG1hcHBpbmcgPSBhZXMoeCA9IHN0YWdlLCB5ID0gRnJlcSwgICAgICAgICAgICAgIyBtYXRvbWXjga5zdGFnZeWIl+OBqEZyZXHliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZyArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLCAjIOWHoeS+i+OBruOCteOCpOOCuuOBrzEyDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcm0obGlzdCA9IGxzKCkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kq44OW44K444Kn44Kv44OI44Gu5YWo5raI5Y67DQpgYGANCg0KIyBXNiDnqY3jgb/kuIrjgZLmo5LjgrDjg6njg5Xjgajjg5njg7Plm7MNCuOAgOWFpeWKm+ODleOCoeOCpOODq++8iFtKU0xBQjI2X3RpdGFuaWMuY3N2XShodHRwczovL3d3dy5pdS5hLnUtdG9reW8uYWMuanAva2Fkb3RhL2Jvb2svSlNMQUIyNl90aXRhbmljLmNzdinvvInjga/jgIHlm7MxYeOBruOCguOBruOBqOWQjOOBmOOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KaW5fZiA8LSAiaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9ib29rL0pTTEFCMjZfdGl0YW5pYy5jc3YiICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQoNCiMg5b+F6KaB44Gq44OR44OD44Kx44O844K444KS44Ot44O844OJDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCmxpYnJhcnkoZ2dzYW5rZXlmaWVyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KDQojIOWFpeWKm+ODleOCoeOCpOODq+OBruiqreOBv+i+vOOBvw0KZGF0YSA8LSByZWFkX2Nzdihpbl9mKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW5fZuOBp+aMh+WumuOBl+OBn+ODleOCoeOCpOODq+OBruiqrei+vA0KDQojIOWJjeWHpueQhu+8iOaPj+eUu+OBleOBm+OBn+OBhOWIl+aDheWgseOBruaKveWHuuOBqGxvbmflnovjgbjjga7lpInmj5sNCm1hdG9tZSA8LSBwaXZvdF9zdGFnZXNfbG9uZ2VyKCAgICAgICAgICAgICAgICAgICAjIGxvbmflnovjg4fjg7zjgr/jgbjjga7lpInmj5sNCiAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+OBr2RhdGHjgqrjg5bjgrjjgqfjgq/jg4ggICANCiAgICAgICAgICAgICAgc3RhZ2VzX2Zyb20gPSBjKCJPdXRjb21lIiwgIlNleCIsICJQYXNzZW5nZXJzIiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXEiKSAgICAgICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSgpICAgICAgICAgICAgICAgICAgICAgICAgICMg5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQpnIDwtIGdncGxvdChkYXRhID0gbWF0b21lLCAgICAgICAgICAgICAgICAgICAgICAgIyBnZ3Bsb3TplqLmlbDlrp/ooYzntZDmnpzjgpJn44Gr5qC857SN44CC5YWl5Yqb44GvbWF0b21l44Kq44OW44K444Kn44Kv44OIDQogIG1hcHBpbmcgPSBhZXMoeCA9IHN0YWdlLCB5ID0gRnJlcSwgICAgICAgICAgICAgIyBtYXRvbWXjga5zdGFnZeWIl+OBqEZyZXHliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICAgICAgICAgICAgICAjIOODjuODvOODieaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxKSowLjAyNSAgICAgICAgICAgIOOAgCMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkobnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkobnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSAtbnVkZ2VfdmFsX3kpICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4i+OBq+OBmuOCieOBme+8iQ0KDQojIOS9nOWbszItMu+8iOWfuuacrOW9omfjgpLjg5njg7zjgrnjgajjgZfjgabjgIHjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLov73liqDjgZfjgZ/ntZDmnpzjgpJnMuOBq+agvOe0je+8iQ0KIyBzdGF0ID0gInNhbmtleW5vZGUi44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5oOF5aCx44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gbm9kZeOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieWQjeOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IEZyZXHjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4njgavku5jpmo/jgZnjgovpoLvluqblgKTjgaDjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3Mx44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMeOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczLjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3My44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIGhqdXN0ID0gMOOBr+OAgeaWh+Wtl+OCkuW3puaPg+OBiOOBp+aPj+eUu+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOODh+ODleOCqeODq+ODiOOBr+S4reWkruaPg+OBiO+8iQ0KIyBzaXplID0gNOOBr+OAgeOCteOCpOOCujTjgavjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjgZPjga7lgKTjgavlv5zjgZjjgaZudWRnZV9544KC6YGp5a6c6Kq/5pW044GZ44KL77yJDQpnMiA8LSBnICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbm9kZSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMSwgaGp1c3QgPSAwLCBzaXplID0gNCkgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBGcmVxKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwjIHnou7jjgr/jgqTjg4jjg6vjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgIyB56Lu45ZCN44Gv44K144Kk44K6MTDjgavjgZvjgogNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMgVzcg6KOc6Laz77yI5YWl5Yqb44OV44Kh44Kk44Or5L2c5oiQ44Kz44O844OJ77yJDQojIyBXNy4xIOWbszFh44Gu5YWl5Yqb44OV44Kh44Kk44OrDQrjgIBb44K/44Kk44K/44OL44OD44Kv5Y+35rKI5rKh5LqL5pWFXShodHRwczovL2phLndpa2lwZWRpYS5vcmcvd2lraS8lRTMlODIlQkYlRTMlODIlQTQlRTMlODIlQkYlRTMlODMlOEIlRTMlODMlODMlRTMlODIlQUYlRTUlOEYlQjclRTYlQjIlODglRTYlQjIlQTElRTQlQkElOEIlRTYlOTUlODUp44Gu54qg54my6ICF44Go55Sf5a2Y6ICF44Gu5YaF6Kiz44GL44KJ44CB5Lul5LiL44Gu44KI44GG44Gq5oSf44GY44Gn44G544Gf5pu444GN44Gn5YWl5Yqb44OV44Kh44Kk44Or77yIW0pTTEFCMjZfdGl0YW5pYy5jc3ZdKGh0dHBzOi8vd3d3Lml1LmEudS10b2t5by5hYy5qcC9rYWRvdGEvYm9vay9KU0xBQjI2X3RpdGFuaWMuY3N2Ke+8ieOCkuS9nOaIkOOBl+OBpuOBhOOBvuOBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KZGF0YSA8LSBOVUxMDQojIENoaWxkcmVuDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDUsIGMoIlN1cnZpdm9yIiwgIkNoaWxkIiwgIjFzdC1jbGFzcyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDEsIGMoIkNhc3VhbHR5IiwgIkNoaWxkIiwgIjFzdC1jbGFzcyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDI0LCBjKCJTdXJ2aXZvciIsICJDaGlsZCIsICIybmQtY2xhc3MiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgyNywgYygiU3Vydml2b3IiLCAiQ2hpbGQiLCAiM3JkLWNsYXNzIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoNTIsIGMoIkNhc3VhbHR5IiwgIkNoaWxkIiwgIjNyZC1jbGFzcyIpKSkpDQoNCiMgRmVtYWxlDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDIwLCBjKCJTdXJ2aXZvciIsICJGZW1hbGUiLCAiQ3JldyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDMsIGMoIkNhc3VhbHR5IiwgIkZlbWFsZSIsICJDcmV3IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTQwLCBjKCJTdXJ2aXZvciIsICJGZW1hbGUiLCAiMXN0LWNsYXNzIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoNCwgYygiQ2FzdWFsdHkiLCAiRmVtYWxlIiwgIjFzdC1jbGFzcyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDgwLCBjKCJTdXJ2aXZvciIsICJGZW1hbGUiLCAiMm5kLWNsYXNzIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTMsIGMoIkNhc3VhbHR5IiwgIkZlbWFsZSIsICIybmQtY2xhc3MiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg3NiwgYygiU3Vydml2b3IiLCAiRmVtYWxlIiwgIjNyZC1jbGFzcyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDg5LCBjKCJDYXN1YWx0eSIsICJGZW1hbGUiLCAiM3JkLWNsYXNzIikpKSkNCg0KIyBNYWxlDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDE5MiwgYygiU3Vydml2b3IiLCAiTWFsZSIsICJDcmV3IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoNjkzLCBjKCJDYXN1YWx0eSIsICJNYWxlIiwgIkNyZXciKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg1NywgYygiU3Vydml2b3IiLCAiTWFsZSIsICIxc3QtY2xhc3MiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxMTgsIGMoIkNhc3VhbHR5IiwgIk1hbGUiLCAiMXN0LWNsYXNzIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTQsIGMoIlN1cnZpdm9yIiwgIk1hbGUiLCAiMm5kLWNsYXNzIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTU0LCBjKCJDYXN1YWx0eSIsICJNYWxlIiwgIjJuZC1jbGFzcyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDc1LCBjKCJTdXJ2aXZvciIsICJNYWxlIiwgIjNyZC1jbGFzcyIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDM4NywgYygiQ2FzdWFsdHkiLCAiTWFsZSIsICIzcmQtY2xhc3MiKSkpKQ0KDQojIEFkZCBGcmVxDQpkYXRhIDwtIGNiaW5kKGRhdGEsIHJlcCgxLCBucm93KGRhdGEpKSkNCmNvbG5hbWVzKGRhdGEpIDwtIGMoIk91dGNvbWUiLCAiU2V4IiwgIlBhc3NlbmdlcnMiLCAiRnJlcSIpDQoNCiMgT3V0cHV0DQp3cml0ZS5jc3YoeCA9IGRhdGEsIGZpbGUgPSAiSlNMQUIyNl90aXRhbmljLmNzdiIsIHJvdy5uYW1lcyA9IEYpDQpgYGANCg0KIyMgVzcuMiDlm7MxYuOBruWFpeWKm+ODleOCoeOCpOODqw0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KZGF0YSA8LSBOVUxMDQojIHVuZGVyMjANCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoNSwgYygiMjDmrbPmnKrmuoAiLCAiQeeXhemZoiIsICLolqzliaQxIiwgIuacieWKuSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDgsIGMoIjIw5q2z5pyq5rqAIiwgIkHnl4XpmaIiLCAi6Jas5YmkMSIsICLnhKHlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgyLCBjKCIyMOats+acqua6gCIsICJB55eF6ZmiIiwgIuiWrOWJpDEiLCAi5LiN5piOIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMiwgYygiMjDmrbPmnKrmuoAiLCAiQeeXhemZoiIsICLolqzliaQyIiwgIuacieWKuSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDIsIGMoIjIw5q2z5pyq5rqAIiwgIkHnl4XpmaIiLCAi6Jas5YmkMiIsICLnhKHlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxMCwgYygiMjDmrbPmnKrmuoAiLCAiQeeXhemZoiIsICLolqzliaQyIiwgIuS4jeaYjiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDIsIGMoIjIw5q2z5pyq5rqAIiwgIkHnl4XpmaIiLCAi5YG96JasIiwgIuacieWKuSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDQsIGMoIjIw5q2z5pyq5rqAIiwgIkHnl4XpmaIiLCAi5YG96JasIiwgIuS4jeaYjiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDMsIGMoIjIw5q2z5pyq5rqAIiwgIkHnl4XpmaIiLCAi5YG96JasIiwgIueEoeWKuSIpKSkpDQoNCiMg5oiQ5Lq6DQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDE1LCBjKCIyMC02NeatsyIsICJB55eF6ZmiIiwgIuiWrOWJpDEiLCAi5pyJ5Yq5IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMjIsIGMoIjIwLTY15q2zIiwgIkHnl4XpmaIiLCAi6Jas5YmkMSIsICLnhKHlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg3LCBjKCIyMC02NeatsyIsICJB55eF6ZmiIiwgIuiWrOWJpDEiLCAi5LiN5piOIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTEsIGMoIjIwLTY15q2zIiwgIkHnl4XpmaIiLCAi6Jas5YmkMiIsICLmnInlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxNywgYygiMjAtNjXmrbMiLCAiQeeXhemZoiIsICLolqzliaQyIiwgIueEoeWKuSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDE1LCBjKCIyMC02NeatsyIsICJB55eF6ZmiIiwgIuiWrOWJpDIiLCAi5LiN5piOIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMiwgYygiMjAtNjXmrbMiLCAiQeeXhemZoiIsICLlgb3olqwiLCAi5pyJ5Yq5IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTIsIGMoIjIwLTY15q2zIiwgIkHnl4XpmaIiLCAi5YG96JasIiwgIueEoeWKuSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDEwLCBjKCIyMC02NeatsyIsICJB55eF6ZmiIiwgIuWBveiWrCIsICLkuI3mmI4iKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxMCwgYygiMjAtNjXmrbMiLCAiQueXhemZoiIsICLolqzliaQxIiwgIuacieWKuSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDEyLCBjKCIyMC02NeatsyIsICJC55eF6ZmiIiwgIuiWrOWJpDEiLCAi54Sh5Yq5IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoOSwgYygiMjAtNjXmrbMiLCAiQueXhemZoiIsICLolqzliaQxIiwgIuS4jeaYjiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDgsIGMoIjIwLTY15q2zIiwgIkLnl4XpmaIiLCAi6Jas5YmkMiIsICLmnInlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgzLCBjKCIyMC02NeatsyIsICJC55eF6ZmiIiwgIuiWrOWJpDIiLCAi54Sh5Yq5IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoNCwgYygiMjAtNjXmrbMiLCAiQueXhemZoiIsICLolqzliaQyIiwgIuS4jeaYjiIpKSkpDQoNCiMg6auY6b2i6ICFDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDUsIGMoIjY15q2z5Lul5LiKIiwgIkLnl4XpmaIiLCAi6Jas5YmkMSIsICLmnInlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg4LCBjKCI2Neats+S7peS4iiIsICJC55eF6ZmiIiwgIuiWrOWJpDEiLCAi54Sh5Yq5IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMiwgYygiNjXmrbPku6XkuIoiLCAiQueXhemZoiIsICLolqzliaQxIiwgIuS4jeaYjiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDIsIGMoIjY15q2z5Lul5LiKIiwgIkLnl4XpmaIiLCAi6Jas5YmkMiIsICLmnInlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgyLCBjKCI2Neats+S7peS4iiIsICJC55eF6ZmiIiwgIuiWrOWJpDIiLCAi54Sh5Yq5IikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTAsIGMoIjY15q2z5Lul5LiKIiwgIkLnl4XpmaIiLCAi6Jas5YmkMiIsICLkuI3mmI4iKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg4LCBjKCI2Neats+S7peS4iiIsICJC55eF6ZmiIiwgIuWBveiWrCIsICLnhKHlirkiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg0LCBjKCI2Neats+S7peS4iiIsICJC55eF6ZmiIiwgIuWBveiWrCIsICLkuI3mmI4iKSkpKQ0KDQojIEFkZCBGcmVxDQpkYXRhIDwtIGNiaW5kKGRhdGEsIHJlcCgxLCBucm93KGRhdGEpKSkNCmNvbG5hbWVzKGRhdGEpIDwtIGMoIuW5tOm9oiIsICLnl4XpmaIiLCAi56iu6aGeIiwgIue1kOaenCIsICLpoLvluqYiKQ0KDQojIE91dHB1dA0Kd3JpdGUuY3N2KHggPSBkYXRhLCBmaWxlID0gIkpTTEFCMjZfbWVkaWNhbC5jc3YiLCByb3cubmFtZXMgPSBGKQ0KYGBgDQoNCiMjIFc3LjMg5ZuzNOOBruWFpeWKm+ODleOCoeOCpOODqw0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KZGF0YSA8LSBOVUxMDQojIENoaWxkcmVuDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDUsIGMoIueUn+WtmOiAhSIsICIx562J6Ii55a6i44Gu5a2Q5L6bIiwgIjHnrYnoiLnlrqIiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxLCBjKCLniqDnibLogIUiLCAiMeetieiIueWuouOBruWtkOS+myIsICIx562J6Ii55a6iIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMjQsIGMoIueUn+WtmOiAhSIsICIy562J6Ii55a6i44Gu5a2Q5L6bIiwgIjLnrYnoiLnlrqIiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgyNywgYygi55Sf5a2Y6ICFIiwgIjPnrYnoiLnlrqLjga7lrZDkvpsiLCAiM+etieiIueWuoiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDUyLCBjKCLniqDnibLogIUiLCAiM+etieiIueWuouOBruWtkOS+myIsICIz562J6Ii55a6iIikpKSkNCg0KIyBGZW1hbGUNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMjAsIGMoIueUn+WtmOiAhSIsICLlpbPmgKfkuZflk6EiLCAi5LmX5ZOhIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMywgYygi54qg54my6ICFIiwgIuWls+aAp+S5l+WToSIsICLkuZflk6EiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxNDAsIGMoIueUn+WtmOiAhSIsICIx562J6Ii55a6i44Gu5aWz5oCnIiwgIjHnrYnoiLnlrqIiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg0LCBjKCLniqDnibLogIUiLCAiMeetieiIueWuouOBruWls+aApyIsICIx562J6Ii55a6iIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoODAsIGMoIueUn+WtmOiAhSIsICIy562J6Ii55a6i44Gu5aWz5oCnIiwgIjLnrYnoiLnlrqIiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgxMywgYygi54qg54my6ICFIiwgIjLnrYnoiLnlrqLjga7lpbPmgKciLCAiMuetieiIueWuoiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDc2LCBjKCLnlJ/lrZjogIUiLCAiM+etieiIueWuouOBruWls+aApyIsICIz562J6Ii55a6iIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoODksIGMoIueKoOeJsuiAhSIsICIz562J6Ii55a6i44Gu5aWz5oCnIiwgIjPnrYnoiLnlrqIiKSkpKQ0KDQojIE1hbGUNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTkyLCBjKCLnlJ/lrZjogIUiLCAi55S35oCn5LmX5ZOhIiwgIuS5l+WToSIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDY5MywgYygi54qg54my6ICFIiwgIueUt+aAp+S5l+WToSIsICLkuZflk6EiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSg1NywgYygi55Sf5a2Y6ICFIiwgIjHnrYnoiLnlrqLjga7nlLfmgKciLCAiMeetieiIueWuoiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDExOCwgYygi54qg54my6ICFIiwgIjHnrYnoiLnlrqLjga7nlLfmgKciLCAiMeetieiIueWuoiIpKSkpDQpkYXRhIDwtIHJiaW5kKGRhdGEsIHQocmVwbGljYXRlKDE0LCBjKCLnlJ/lrZjogIUiLCAiMuetieiIueWuouOBrueUt+aApyIsICIy562J6Ii55a6iIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoMTU0LCBjKCLniqDnibLogIUiLCAiMuetieiIueWuouOBrueUt+aApyIsICIy562J6Ii55a6iIikpKSkNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdChyZXBsaWNhdGUoNzUsIGMoIueUn+WtmOiAhSIsICIz562J6Ii55a6i44Gu55S35oCnIiwgIjPnrYnoiLnlrqIiKSkpKQ0KZGF0YSA8LSByYmluZChkYXRhLCB0KHJlcGxpY2F0ZSgzODcsIGMoIueKoOeJsuiAhSIsICIz562J6Ii55a6i44Gu55S35oCnIiwgIjPnrYnoiLnlrqIiKSkpKQ0KDQojIEFkZCBGcmVxDQpkYXRhIDwtIGNiaW5kKGRhdGEsIHJlcCgxLCBucm93KGRhdGEpKSkNCmNvbG5hbWVzKGRhdGEpIDwtIGMoIue1kOacqyIsICLmgKfliKUiLCAi5LmX5a6iIiwgIkZyZXEiKQ0KDQojIE91dHB1dA0Kd3JpdGUuY3N2KHggPSBkYXRhLCBmaWxlID0gIkpTTEFCMjZfdGl0YW5pYzIuY3N2Iiwgcm93Lm5hbWVzID0gRikNCmBgYA0K