1 Giới thiệu

1.1 Cài và Load bộ dữ liệu vào R

install.packages("tidyverse", repos="https://cran.rstudio.com/")
## Installing package into 'C:/Users/ASUS/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'tidyverse' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\ASUS\AppData\Local\Temp\RtmpucrkLZ\downloaded_packages
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
a <- diamonds

Giải thích các câu lệnh - Install.packages(“tidyverse”): Dòng này sẽ cài đặt gói “tidyverse” vào trong môi trường R - library(tidyverse): Dòng này sẽ tải gói “tidyverse” vào bộ nhớ để sử dụng bất kỳ chức năng nào từ tidyverse - library(scales): Dòng này tải gói “scales” vào bộ nhớ làm việc. “Scales” là một gói trong “tidyverse” được sử dụng để tạo và tùy chỉnh các biểu đồ. - a <- diamonds: Dòng này tải dữ liệu diamonds từ gói dữ liệu mẫu trong tidyverse và gán vào obj a

Kết quả là: Có một obj a bao gồm 53940 obs. of 10 variables

1.2 Thông tin cơ bản của bộ dữ liệu

is.data.frame(a)
## [1] TRUE
length(a)
## [1] 10
names(a)
##  [1] "carat"   "cut"     "color"   "clarity" "depth"   "table"   "price"  
##  [8] "x"       "y"       "z"
dim(a)
## [1] 53940    10
library(skimr)
skim(a)
Data summary
Name a
Number of rows 53940
Number of columns 10
_______________________
Column type frequency:
factor 3
numeric 7
________________________
Group variables None

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
cut 0 1 TRUE 5 Ide: 21551, Pre: 13791, Ver: 12082, Goo: 4906
color 0 1 TRUE 7 G: 11292, E: 9797, F: 9542, H: 8304
clarity 0 1 TRUE 8 SI1: 13065, VS2: 12258, SI2: 9194, VS1: 8171

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
carat 0 1 0.80 0.47 0.2 0.40 0.70 1.04 5.01 ▇▂▁▁▁
depth 0 1 61.75 1.43 43.0 61.00 61.80 62.50 79.00 ▁▁▇▁▁
table 0 1 57.46 2.23 43.0 56.00 57.00 59.00 95.00 ▁▇▁▁▁
price 0 1 3932.80 3989.44 326.0 950.00 2401.00 5324.25 18823.00 ▇▂▁▁▁
x 0 1 5.73 1.12 0.0 4.71 5.70 6.54 10.74 ▁▁▇▃▁
y 0 1 5.73 1.14 0.0 4.72 5.71 6.54 58.90 ▇▁▁▁▁
z 0 1 3.54 0.71 0.0 2.91 3.53 4.04 31.80 ▇▁▁▁▁

2 Vẽ Đồ Thị Dạng Bar Chart

2.1 Đồ Thị 1: Đồ thị thể hiện số lượng kim cương theo từng biến cut, color, clarity

a %>% ggplot(aes(x = cut)) +
    geom_bar() +
    labs(x = 'Loại', y = 'Số lượng')

Giải Thích Câu Lệnh: - a %>% ggplot(aes(x = cut)): Dòng này sử dụng toán tử %>% từ gói dplyr để chuyển đổi dữ liệu trong a thành một luồng dữ liệu và đưa vào ggplot2. Trong hàm ggplot(), aes(x = cut) thiết lập một mối quan hệ giữa dữ liệu và các tham số trên trục x, trong trường hợp này là cut, là một biến trong diamonds chứa thông tin về các loại kim cương. - Hàm geom_bar() được sử dụng để tạo ra các cột dựa trên số lần xuất hiện của mỗi giá trị của biến cut - labs(x = ‘Loại’, y = ‘Số lượng’): Dòng này sử dụng hàm labs() để đặt tên cho trục x và trục y của biểu đồ. Trong trường hợp này, trục x được gán nhãn là “Loại” và trục y được gán nhãn là “Số lượng”

2.2 Đồ Thị 2: Đồ thị biểu thị số lượng các quan sát cho từng màu sắc của kim cương

a %>% ggplot(aes(x = color)) +
    geom_bar() +
    labs(x = 'Màu', y = 'Số lượng')

Giải Thích Câu Lệnh: - a %>% ggplot(aes(x = color)): Dòng này sử dụng toán tử %>% từ gói dplyr để chuyển đổi dữ liệu trong a thành một luồng dữ liệu và đưa vào ggplot2. Trong hàm ggplot(), aes(x = color) thiết lập một mối quan hệ giữa dữ liệu và các tham số trên trục x, trong trường hợp này là color, là một biến trong diamonds chứa thông tin về các màu sắc của kim cương. - Hàm geom_bar() được sử dụng để tạo ra các cột dựa trên số lần xuất hiện của mỗi giá trị của biến color - labs(x = ‘Màu’, y = ‘Số lượng’): Dòng này sử dụng hàm labs() để đặt tên cho trục x và trục y của biểu đồ. Trong trường hợp này, trục x được gán nhãn là “Màu” và trục y được gán nhãn là “Số lượng”

2.3 Đồ Thị 3: Đồ thị thể hiện mối quan hệ giữa độ trong của viên kim cương (clarity) và số lượng các viên kim cương

a %>% ggplot(aes(x = clarity)) +
    geom_bar() +
    labs(x = 'Mức độ tinh khiết', y = 'Số lượng')

Giải Thích Câu Lệnh: - a %>% ggplot(aes(x = clarity)): Dòng này sử dụng toán tử %>% từ gói dplyr để chuyển đổi dữ liệu trong a thành một luồng dữ liệu và đưa vào ggplot2. Trong hàm ggplot(), aes(x = clarity) thiết lập một mối quan hệ giữa dữ liệu và các tham số trên trục x, trong trường hợp này là clarity, là một biến trong diamonds chứa thông tin về mức độ tinh khiết của kim cương. - Hàm geom_bar() được sử dụng để tạo ra các cột dựa trên số lần xuất hiện của mỗi giá trị của biến clarity - labs(x = ‘Mức độ tinh khiết’, y = ‘Số lượng’): Dòng này sử dụng hàm labs() để đặt tên cho trục x và trục y của biểu đồ. Trong trường hợp này, trục x được gán nhãn là “Mức độ tinh khiết” và trục y được gán nhãn là “Số lượng”

2.4 Đồ Thị 4: Biểu đồ cột với chú thích số lượng theo từng biến: cut, color, clarity

a %>% group_by(cut) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='red') +
    geom_text(aes(label = n),vjust = 2, color = 'black') +
    labs(x = 'Loại', y = 'Số lượng')

Giải thích câu lệnh - a %>% group_by(cut) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến cut, sau đó tính tổng số lượng các mẫu trong mỗi nhóm.

  • ggplot(aes(cut,n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và số lượng trên trục y.

  • geom_col(fill=‘red’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền đỏ.

  • geom_text(aes(label = n),vjust = 2, color = ‘black’): Thêm các nhãn số lượng lên trên các cột. Các nhãn này được lấy từ giá trị của biến n và được căn chỉnh dọc (vjust = 2) và màu chữ là đen (color = ‘black’).

  • labs(x = ‘Loại’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Loại” và trục y là “Số lượng”.

2.5 Đồ Thị 5: Đồ thị thể hiện mối quan hệ giữa màu sắc của viên kim cương (color) và số lượng các viên kim cương(chú thích số lượng)

a %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='green') +
    geom_text(aes(label = n),vjust = 2, color = 'red') +
    labs(x = 'Màu', y = 'Số lượng')

Giải thích câu lệnh - a %>% group_by(color) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến color, sau đó tính tổng số lượng các mẫu trong mỗi nhóm.

  • ggplot(aes(color,n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và số lượng trên trục y.

  • geom_col(fill=‘green’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền xanh lá cây.

  • geom_text(aes(label = n),vjust = 2, color = ‘red’): Thêm các nhãn số lượng lên trên các cột. Các nhãn này được lấy từ giá trị của biến n và được căn chỉnh dọc (vjust = 2) và màu chữ là đỏ (color = ‘red’).

  • labs(x = ‘Màu’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Màu” và trục y là “Số lượng”.

2.6 Đồ Thị 6: Đồ thị thể hiện mối quan hệ giữa độ trong của viên kim cương (clarity) và số lượng các viên kim cương(chú thích số lượng)

a %>% group_by(clarity) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='yellow') +
    geom_text(aes(label = n),vjust = 1, color = 'red') +
    labs(x = 'Mức độ tinh khiết', y = 'Số lượng')

Giải thích câu lệnh - a %>% group_by(clarity) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến clarity, sau đó tính tổng số lượng các mẫu trong mỗi nhóm.

  • ggplot(aes(clarity,n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến clarity trên trục x và số lượng trên trục y.

  • geom_col(fill=‘yellow’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền vàng.

  • geom_text(aes(label = n),vjust = 1, color = ‘red’): Thêm các nhãn số lượng lên trên các cột. Các nhãn này được lấy từ giá trị của biến n và được căn chỉnh dọc (vjust = 1) và màu chữ là đổ (color = ‘red’).

  • labs(x = ‘Mức độ tinh khiết’, y = ‘Số lượng’) Đặt nhãn cho trục x là “Mức độ tinh khiết” và trục y là “Số lượng”.

2.7 Đồ Thị 7: Đồ thị thể hiện số lượng kim cương theo từng biến: color, cut, clarity và thể hiện tỷ lệ phần trăm trên tổng số viên kim cương

a %>% group_by(cut) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='green') +
    geom_text(aes(label = scales::percent(n/length(a$carat))),vjust = 1, color = 'red') +
    labs(x = 'Loại', y = 'Số lượng')

Giải thích câu lệnh: - a %>% group_by(cut) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến cut, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(cut,n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và số lượng trên trục y.

  • geom_col(fill=‘green’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền là màu xanh lá cây.

  • **geom_text(aes(label = scales::percent(n/length(a\(carat))),vjust = 1, color = 'red'):** Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này là tỉ lệ phần trăm của số lượng mẫu trong mỗi nhóm so với tổng số lượng mẫu (được tính bằng n/length(d\)carat)). Các nhãn được căn chỉnh dọc (vjust = 1) và được định dạng màu đỏ.

  • labs(x = ‘Loại’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Loại” và trục y là “Số lượng”.

2.8 Đồ Thị 8: Đồ thị thể hiện mối quan hệ giữa màu sắc của viên kim cương (color) và số lượng các viên kim cương đồng thời thể hiện tỷ lệ phần trăm của các viên kim cương trên tổng số viên kim cương

a %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='black') +
    geom_text(aes(label = scales::percent(n/length(a$depth))),vjust = 1, color = 'white') +
    labs(x = 'Màu', y = 'Số lượng')

Giải thích câu lệnh: - a %>% group_by(color) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến color, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(color,n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và số lượng trên trục y.

  • geom_col(fill=‘black’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền là màu đen.

  • **geom_text(aes(label = scales::percent(n/length(a\(depth))),vjust = 1, color = 'white'):** Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này là tỉ lệ phần trăm của số lượng mẫu trong mỗi nhóm so với tổng số lượng mẫu (được tính bằng n/length(a\)depth)). Các nhãn được căn chỉnh dọc (vjust = 1) và được định dạng màu trắng.

  • labs(x = ‘Màu’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Màu” và trục y là “Số lượng”.

2.9 Đồ Thị 9: Đồ thị thể hiện mối quan hệ giữa độ trong của viên kim cương (clarity) và số lượng các viên kim cương đồng thời thể hiện tỷ lệ phần trăm của các viên kim cương trên tổng số viên kim cương

a %>% group_by(clarity) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='violet') +
    geom_text(aes(label = scales::percent(n/length(a$price))),vjust = 1, color = 'black') +
    labs(x = 'Mức độ tinh khiết', y = 'Số lượng')

Giải thích câu lệnh: - a %>% group_by(clarity) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến clarity, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(clarity,n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến clarity trên trục x và số lượng trên trục y.

  • geom_col(fill=‘violet’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền là màu tím.

  • **geom_text(aes(label = scales::percent(n/length(a\(price))),vjust = 1, color = 'black'):** Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này là tỉ lệ phần trăm của số lượng mẫu trong mỗi nhóm so với tổng số lượng mẫu (được tính bằng n/length(a\)price)). Các nhãn được căn chỉnh dọc (vjust = 1) và được định dạng màu đen.

  • labs(x = ‘Mức độ tinh khiết’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Mức độ tinh khiết” và trục y là “Số lượng”.

2.10 Đồ Thị 10: Biểu đồ cột kép theo mặt cắt (cut) phân tách theo màu sắc (color)

a %>% group_by(cut,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_text(aes(label = n),vjust = 1, color = 'green') +
    labs(x = 'Loại', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích câu lệnh : - a %>% group_by(cut, color) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến cut và color, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(x = cut, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và số lượng trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ. Với tham số position = ‘dodge’, các cột được vẽ cách xa nhau, mỗi nhóm cột tương ứng với một giá trị của biến color.

  • facet_wrap(~color): Chia biểu đồ thành nhiều “panes” (phần nhỏ) dựa trên giá trị của biến color, tức là tạo ra nhiều biểu đồ con, mỗi biểu đồ con cho một giá trị riêng của biến color.

  • geom_text(aes(label = n), vjust = 1, color = ‘green’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này được lấy từ biến n và được căn chỉnh dọc (vjust = 1) và định dạng màu chữ là màu xanh lá cây.

  • labs(x = ‘Loại’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Loại” và trục y là “Số lượng”.

2.11 Đồ Thị 11: Biểu đồ cột kép theo mặt cắt (cut) phân tách theo độ trong(clarity)

a %>% group_by(cut,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_text(aes(label = n),vjust = 1, color = 'red') +
    labs(x = 'Loại', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích câu lệnh : - a %>% group_by(cut, clarity) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến cut và clarity, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(x = cut, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và số lượng trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ. Với tham số position = ‘dodge’, các cột được vẽ cách xa nhau, mỗi nhóm cột tương ứng với một giá trị của biến clarity.

  • facet_wrap(~clarity): Chia biểu đồ thành nhiều “panes” (phần nhỏ) dựa trên giá trị của biến clarity, tức là tạo ra nhiều biểu đồ con, mỗi biểu đồ con cho một giá trị riêng của biến clarity.

  • geom_text(aes(label = n), vjust = 1, color = ‘red’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này được lấy từ biến n và được căn chỉnh dọc (vjust = 1) và định dạng màu chữ là màu đỏ.

  • labs(x = ‘Loại’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Loại” và trục y là “Số lượng”.

2.12 Đồ Thị 12: Biểu đồ cột kép theo màu sắc (color) và phân tách theo độ trong (clarity)

a %>% group_by(color,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_text(aes(label = n),vjust = 1, color = 'white') +
    labs(x = 'Màu', y = 'Số lượng')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Giải thích câu lệnh : - a %>% group_by(color, clarity) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến color và clarity, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(x = color, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và số lượng trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ. Với tham số position = ‘dodge’, các cột được vẽ cách xa nhau, mỗi nhóm cột tương ứng với một giá trị của biến clarity.

  • facet_wrap(~clarity): Chia biểu đồ thành nhiều “panes” (phần nhỏ) dựa trên giá trị của biến clarity, tức là tạo ra nhiều biểu đồ con, mỗi biểu đồ con cho một giá trị riêng của biến clarity.

  • geom_text(aes(label = n), vjust = 1, color = ‘white’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này được lấy từ biến n và được căn chỉnh dọc (vjust = 1) và định dạng màu chữ là màu trắng.

  • labs(x = ‘Màu’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Màu” và trục y là “Số lượng”.

2.13 Đồ Thị 13: Biểu đồ cột kép theo theo độ trong (clarity) và phân tách theo màu sắc (color)

a %>% group_by(color,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_text(aes(label = n),vjust = 1, color = 'black') +
    labs(x = 'Mức độ tinh khiết', y = 'Số lượng')
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.

Giải thích câu lệnh : - a %>% group_by(color, clarity) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến color và clarity, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(x = clarity, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến clarity trên trục x và số lượng trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ. Với tham số position = ‘dodge’, các cột được vẽ cách xa nhau, mỗi nhóm cột tương ứng với một giá trị của biến color.

  • facet_wrap(~color): Chia biểu đồ thành nhiều “panes” (phần nhỏ) dựa trên giá trị của biến color, tức là tạo ra nhiều biểu đồ con, mỗi biểu đồ con cho một giá trị riêng của biến color.

  • geom_text(aes(label = n), vjust = 1, color = ‘black’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này được lấy từ biến n và được căn chỉnh dọc (vjust = 1) và định dạng màu chữ là màu đen.

  • labs(x = ‘Mức độ tinh khiết’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Mức độ tinh khiết” và trục y là “Số lượng”.

2.14 Đồ Thị 14: Biểu đồ cột kép theo màu sắc (color) và phân tách theo mặt cắt (cut)

a %>% group_by(cut,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = color,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_text(aes(label = n),vjust = 1, color = 'violet') +
    labs(x = 'Màu', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích câu lệnh : - a %>% group_by(cut, color) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến cut và color, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(x = color, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và số lượng trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ. Với tham số position = ‘dodge’, các cột được vẽ cách xa nhau, mỗi nhóm cột tương ứng với một giá trị của biến cut.

  • facet_wrap(~cut): Chia biểu đồ thành nhiều “panes” (phần nhỏ) dựa trên giá trị của biến color, tức là tạo ra nhiều biểu đồ con, mỗi biểu đồ con cho một giá trị riêng của biến cut.

  • geom_text(aes(label = n), vjust = 1, color = ‘violet’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này được lấy từ biến n và được căn chỉnh dọc (vjust = 1) và định dạng màu chữ là màu tím.

  • labs(x = ‘Màu’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Màu” và trục y là “Số lượng”.

2.15 Đồ Thị 15: Biểu đồ cột kép theo theo độ trong (clarity) và phân tách theo mặt cắt (cut)

a %>% group_by(cut,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~cut) +
    geom_text(aes(label = n),vjust = 1, color = 'red') +
    labs(x = 'Loại', y = 'Số lượng')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích câu lệnh : - a %>% group_by(cut, clarity) %>% summarise(n = n()): Nhóm dữ liệu trong a theo giá trị của biến cut và clarity, sau đó tính tổng số lượng các mẫu trong mỗi nhóm và lưu vào biến n.

  • ggplot(aes(x = clarity, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến clarity trên trục x và số lượng trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ. Với tham số position = ‘dodge’, các cột được vẽ cách xa nhau, mỗi nhóm cột tương ứng với một giá trị của biến cut.

  • facet_wrap(~cut): Chia biểu đồ thành nhiều “panes” (phần nhỏ) dựa trên giá trị của biến cut, tức là tạo ra nhiều biểu đồ con, mỗi biểu đồ con cho một giá trị riêng của biến cut.

  • geom_text(aes(label = n), vjust = 1, color = ‘red’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Các nhãn này được lấy từ biến n và được căn chỉnh dọc (vjust = 1) và định dạng màu chữ là màu đỏ.

  • labs(x = ‘Loại’, y = ‘Số lượng’): Đặt nhãn cho trục x là “Loại” và trục y là “Số lượng”.

2.16 Đồ Thị 16: Biểu đồ cột thể hiện trung bình trọng lượng carat theo chất lượng cắt (cut)

a %>% group_by(cut) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Mean')

Giải thích câu lệnh : - a %>% group_by(cut) %>% summarise(m= mean(carat)): Nhóm dữ liệu trong a theo các giá trị của biến cut, sau đó tính trung bình (mean()) của trọng lượng kim cương (carat) trong mỗi nhóm và lưu vào biến m.

  • ggplot(aes(x = cut, y = m)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và giá trị trung bình (m) trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ, với các cột được sắp xếp cạnh nhau theo giá trị của biến cut. Tham số position = ‘dodge’ được sử dụng để sắp xếp các cột cạnh nhau.

  • geom_text(aes(label = round(m,2)), vjust = 2, color = ‘white’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Giá trị của các nhãn là giá trị trung bình của trọng lượng kim cương được làm tròn với hai chữ số sau dấu thập phân (round(m,2)). Các nhãn này được căn chỉnh dọc (vjust = 2) và được màu chữ là màu trắng để phản ánh trên nền cột.

  • labs(x = ‘Loại’, y = ‘Mean’): Đặt nhãn cho trục x là “Loại” và trục y là “Mean” (Trung bình).

2.17 Đồ Thị 17: Biểu đồ cột thể hiện trung bình trọng lượng carat theo màu sắc (color)

a %>% group_by(color) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = color,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'red') +
    labs(x = 'Màu', y = 'Mean')

Giải thích câu lệnh : - a %>% group_by(color) %>% summarise(m= mean(carat)): Nhóm dữ liệu trong a theo các giá trị của biến color, sau đó tính trung bình (mean()) của trọng lượng kim cương (carat) trong mỗi nhóm và lưu vào biến m.

  • ggplot(aes(x = color, y = m)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và giá trị trung bình (m) trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ, với các cột được sắp xếp cạnh nhau theo giá trị của biến color. Tham số position = ‘dodge’ được sử dụng để sắp xếp các cột cạnh nhau.

  • geom_text(aes(label = round(m,2)), vjust = 2, color = ‘red’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Giá trị của các nhãn là giá trị trung bình của trọng lượng kim cương được làm tròn với hai chữ số sau dấu thập phân (round(m,2)). Các nhãn này được căn chỉnh dọc (vjust = 2) và được màu chữ là màu đỏ để phản ánh trên nền cột.

  • labs(x = ‘Màu’, y = ‘Mean’): Đặt nhãn cho trục x là “Màu” và trục y là “Mean” (Trung bình).

2.18 Đồ Thị 18: Biểu đồ cột thể hiện trung bình trọng lượng carat theo độ tinh khiết (color)

a %>% group_by(clarity) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = clarity,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'blue') +
    labs(x = 'Mức Độ Tinh Khiết', y = 'Mean')

2.19 Đồ Thị 19: Biểu đồ cột thể hiện trung bình giá thành theo chất lượng cắt (cut)

a %>% group_by(cut) %>% summarise(mp= mean(price)) %>%
  ggplot(aes(x = cut,y = mp)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(mp,2)), vjust = 2, color = 'white') +
    labs(x = 'Loại', y = 'Mean Price')

Giải thích câu lệnh : - a %>% group_by(cut) %>% summarise(mp= mean(price)): Nhóm dữ liệu trong a theo các giá trị của biến cut, sau đó tính trung bình (mean()) của giá kim cương (price) trong mỗi nhóm và lưu vào biến mp.

  • ggplot(aes(x = cut, y = mp)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và giá trị trung bình (mp) trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ, với các cột được sắp xếp cạnh nhau theo giá trị của biến cut. Tham số position = ‘dodge’ được sử dụng để sắp xếp các cột cạnh nhau.

  • geom_text(aes(label = round(mp,2)), vjust = 2, color = ‘white’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Giá trị của các nhãn là giá trị trung bình của giá kim cương được làm tròn với hai chữ số sau dấu thập phân (round(mp,2)). Các nhãn này được căn chỉnh dọc (vjust = 2) và được màu chữ là màu trắng để phản ánh trên nền cột.

  • labs(x = ‘Loại’, y = ‘Mean Price’): Đặt nhãn cho trục x là “Loại” và trục y là “Mean Price” (Giá Trung bình).

2.20 Đồ Thị 20: Biểu đồ cột thể hiện trung bình giá thành theo màu sắc (color)

a %>% group_by(color) %>% summarise(mp= mean(price)) %>%
  ggplot(aes(x = color,y = mp)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(mp,2)), vjust = 2, color = 'red') +
    labs(x = 'Màu', y = 'Mean Price')

Giải thích câu lệnh : - a %>% group_by(color) %>% summarise(mp= mean(price)): Nhóm dữ liệu trong a theo các giá trị của biến color, sau đó tính trung bình (mean()) của giá kim cương (price) trong mỗi nhóm và lưu vào biến mp.

  • ggplot(aes(x = color, y = mp)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và giá trị trung bình (mp) trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ, với các cột được sắp xếp cạnh nhau theo giá trị của biến color. Tham số position = ‘dodge’ được sử dụng để sắp xếp các cột cạnh nhau.

  • geom_text(aes(label = round(mp,2)), vjust = 2, color = ‘red’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Giá trị của các nhãn là giá trị trung bình của giá kim cương được làm tròn với hai chữ số sau dấu thập phân (round(mp,2)). Các nhãn này được căn chỉnh dọc (vjust = 2) và được màu chữ là màu đỏ để phản ánh trên nền cột.

  • labs(x = ‘Màu’, y = ‘Mean Price’): Đặt nhãn cho trục x là “Màu” và trục y là “Mean Price” (Giá Trung bình).

2.21 Đồ Thị 21: Biểu đồ cột thể hiện trung bình giá thành theo độ trong (clarity)

a %>% group_by(clarity) %>% summarise(mp= mean(price)) %>%
  ggplot(aes(x = clarity,y = mp)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(mp,2)), vjust = 2, color = 'blue') +
    labs(x = 'Mức Độ Tinh Khiết', y = 'Mean')

Giải thích câu lệnh : - a %>% group_by(clarity) %>% summarise(mp= mean(price)): Nhóm dữ liệu trong a theo các giá trị của biến clarity, sau đó tính trung bình (mean()) của giá kim cương (price) trong mỗi nhóm và lưu vào biến mp.

  • ggplot(aes(x = clarrity, y = mp)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến clarity trên trục x và giá trị trung bình (mp) trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ, với các cột được sắp xếp cạnh nhau theo giá trị của biến clarity. Tham số position = ‘dodge’ được sử dụng để sắp xếp các cột cạnh nhau.

  • geom_text(aes(label = round(mp,2)), vjust = 2, color = ‘blue’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Giá trị của các nhãn là giá trị trung bình của giá kim cương được làm tròn với hai chữ số sau dấu thập phân (round(mp,2)). Các nhãn này được căn chỉnh dọc (vjust = 2) và được màu chữ là màu xanh dương để phản ánh trên nền cột.

  • labs(x = ‘Mức độ tinh khiết’, y = ‘Mean Price’): Đặt nhãn cho trục x là “Mức độ tinh khiết” và trục y là “Mean Price” (Giá Trung bình).

2.22 Đồ Thị 22: Biểu đồ cột thể hiện trung bình độ sâu của vết cắt (depth) theo độ trong(clarity)

a %>% group_by(clarity) %>% summarise(md= mean(depth)) %>%
  ggplot(aes(x = clarity,y = md)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(md,2)), vjust = 2, color = 'blue') +
    labs(x = 'Mức Độ Tinh Khiết', y = 'Mean')

Giải thích câu lệnh: - a %>% group_by(clarity) %>% summarise(md= mean(depth)): Nhóm dữ liệu trong a theo các giá trị của biến clarity, sau đó tính trung bình (mean()) của chiều cao (depth) trong mỗi nhóm và lưu vào biến md.

  • ggplot(aes(x = clarity, y = md)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến clarity trên trục x và giá trị trung bình (md) trên trục y.

  • geom_col(position = ‘dodge’): Thêm một layer biểu đồ cột vào khung biểu đồ, với các cột được sắp xếp cạnh nhau theo giá trị của biến clarity. Tham số position = ‘dodge’ được sử dụng để sắp xếp các cột cạnh nhau.

  • geom_text(aes(label = round(md,2)), vjust = 2, color = ‘blue’): Thêm các nhãn số liệu lên trên đỉnh của mỗi cột. Giá trị của các nhãn là giá trị trung bình của chiều cao được làm tròn với hai chữ số sau dấu thập phân (round(md,2)). Các nhãn này được căn chỉnh dọc (vjust = 2) và được màu chữ là màu xanh dương để phản ánh trên nền cột.

  • labs(x = ‘Mức độ tinh khiết’, y = ‘Mean Depth’): Đặt nhãn cho trục x là “Mức độ tinh khiết” và trục y là “Mean Depth” (Trung bình chiều cao).

2.23 Đồ Thị 23: Đồ thị so sánh số lượng viên kim cương giữa 2 màu theo chất lượng cắt (cut)

a1 <- a %>% group_by(cut, color) %>% summarise(n = n())
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
a %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = a1 %>% filter(color == 'I'), fill = 'black') +
  geom_col(data = a1 %>% filter(color == 'J'), fill = 'red')

Giải thích câu lệnh: - a1 <- a %>% group_by(cut, color) %>% summarise(n = n()): Tạo một bộ dữ liệu mới a1 bằng cách nhóm dữ liệu trong a theo các giá trị của biến cut và color, sau đó tính số lượng mẫu trong mỗi nhóm và lưu vào biến n.

  • a %>% ggplot(aes(x = cut, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến cut trên trục x và số lượng (n) trên trục y.

  • (data = a1 %>% filter(color == ‘I’), fill = ‘black’): Thêm một layer biểu đồ cột vào khung biểu đồ, với dữ liệu được lấy từ a1 sau khi lọc ra những dòng có giá trị của biến color là ‘I’. Các cột này sẽ được tô màu đen.

  • geom_col(data = a1 %>% filter(color == ‘J’), fill = ‘red’): Thêm một layer biểu đồ cột vào khung biểu đồ, với dữ liệu được lấy từ a1 sau khi lọc ra những dòng có giá trị của biến color là ‘J’. Các cột này sẽ được tô màu đỏ.

2.24 Đồ Thị 24: Đồ thị thể hiện mối quan hệ giữa trọng lượng và số lượng của các viên kim cương

a2 <- a %>% mutate(caratC = cut(carat,5, label = c('rất nhỏ', 'nhỏ','vừa','lớn','rất lớn')))
a2 %>% ggplot(aes(x = caratC)) +
  geom_bar(fill = 'red')

Giải thích câu lệnh : - a2 <- a %>% mutate(caratC = cut(carat,5, label = c(‘rất nhỏ’, ‘nhỏ’,‘vừa’,‘lớn’,‘rất lớn’))): Tạo một bộ dữ liệu mới a2 từ bộ dữ liệu a. Trong bộ dữ liệu này, một biến mới được thêm vào là caratC. Biến này được tạo ra bằng cách chia biến carat thành 5 nhóm sử dụng hàm cut(). Nhãn của các nhóm được đặt lần lượt là ‘rất nhỏ’, ‘nhỏ’, ‘vừa’, ‘lớn’, ‘rất lớn’.

  • a2 %>% ggplot(aes(x = caratC)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến caratC trên trục x.

  • geom_bar(fill = ‘red’): Thêm một layer biểu đồ cột vào khung biểu đồ với màu nền là màu đỏ. Mỗi cột trong biểu đồ này đại diện cho số lượng mẫu trong mỗi nhóm của biến caratC.

2.25 Đồ Thị 25:

a3 <- a %>% group_by(color, clarity) %>% summarise(n = n())
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.
a %>% ggplot(aes(x = clarity, y = n)) +
  geom_col(data = a3 %>% filter(clarity == 'VS1'), fill = 'blue') +
  geom_col(data = a3 %>% filter(clarity == 'VS2'), fill = 'red')

Giải thích dữ liệu: - a3 <- a %>% group_by(color, clarity) %>% summarise(n = n()): Tạo một bộ dữ liệu mới a3 bằng cách nhóm dữ liệu trong a theo các giá trị của biến color và clarity, sau đó tính số lượng mẫu trong mỗi nhóm và lưu vào biến n.

  • a %>% ggplot(aes(x = color, y = n)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến color trên trục x và số lượng (n) trên trục y.

  • geom_col(data = a3 %>% filter(clarity == ‘I1’), fill = ‘blue’): Thêm một layer biểu đồ cột vào khung biểu đồ, với dữ liệu được lấy từ a3 sau khi lọc ra những dòng có giá trị của biến clarity là ‘I1’. Các cột này sẽ được tô màu xanh lam.

  • geom_col(data = a3 %>% filter(clarity == ‘VS2’), fill = ‘red’): Thêm một layer biểu đồ cột vào khung biểu đồ, với dữ liệu được lấy từ a3 sau khi lọc ra những dòng có giá trị của biến clarity là ‘VS2’. Các cột này sẽ được tô màu đỏ.

2.26 Đồ Thị 26: Đồ thị thể hiện Giá của các viên Kim cương

a %>% ggplot(aes(x = price)) +
  geom_histogram(binwidth = 500, fill = 'green', color = 'red')

Giải thích câu lệnh: - a %>% ggplot(aes(x = price)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến price trên trục x.

  • geom_histogram(binwidth = 500, fill = ‘green’, color = ‘red’): Thêm một layer biểu đồ histogram vào khung biểu đồ. Các thanh histogram được tạo ra với chiều rộng của mỗi biến là 500 (đơn vị giá). Màu nền của histogram được tô màu xanh lá cây (fill = ‘green’) và màu viền của histogram được tô màu đỏ (color = ‘red’).

2.27 Đồ Thị 27: Đồ thị thể hiện độ sâu của vết cắt của các viên kim cương

a %>% ggplot(aes(x = depth)) +
  geom_histogram(binwidth = 1, fill = 'violet', color = 'black')

Giải thích câu lệnh: - a %>% ggplot(aes(x = depth)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến depth trên trục x.

  • geom_histogram(binwidth = 1, fill = ‘violet’, color = ‘black’): Thêm một layer biểu đồ histogram vào khung biểu đồ. Các thanh histogram được tạo ra với chiều rộng của mỗi biến là 1 đơn vị. Màu nền của histogram được tô màu tím (fill = ‘violet’) và màu viền của histogram được tô màu đen (color = ‘black’).

2.28 Đồ Thị 28: Đồ Thị thể hiện giá của các viên kim cương có phân loại theo màu sắc

a %>% ggplot(aes(x = price, fill = color)) +
  geom_histogram(binwidth = 2000)

Giải thích câu lệnh: - a %>% ggplot(aes(x = price, fill = color)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến price trên trục x và sử dụng biến color để tạo các nhóm màu sắc.

  • geom_histogram(binwidth = 2000): Thêm một layer biểu đồ histogram vào khung biểu đồ. Các thanh histogram được tạo ra với chiều rộng của mỗi biến là 2000 đơn vị giá. Các nhóm màu sắc sẽ phân biệt các thanh histogram dựa trên giá trị của biến color.

2.29 Đồ Thị 29: so sánh phân phối độ sâu của kim cương cho từng màu sắc khác nhau.

a %>% ggplot(aes(x = depth, fill = color)) +
  geom_histogram(binwidth = 2)

Giải thích câu lệnh: - a %>% ggplot(aes(x = depth, fill = color)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến depth trên trục x và sử dụng biến color để tạo các nhóm màu sắc.

  • geom_histogram(binwidth = 2): Thêm một layer biểu đồ histogram vào khung biểu đồ. Các thanh histogram được tạo ra với chiều rộng của mỗi biến là 2 đơn vị độ sâu. Các nhóm màu sắc sẽ phân biệt các thanh histogram dựa trên giá trị của biến color.

2.30 Đồ Thị 30: phân phối của giá kim cương (biến “price”) dựa trên màu sắc của chúng (biến “color”).

a %>% ggplot(aes(x = price)) +
  geom_histogram(binwidth = 500, fill = 'black', color = 'white') +
  facet_wrap(~color)

Giải thích câu lệnh: - a %>% ggplot(aes(x = price)): Tạo một khung biểu đồ mới, thiết lập mối quan hệ giữa biến price trên trục x.

  • geom_histogram(binwidth = 500, fill = ‘black’, color = ‘white’): Thêm một layer biểu đồ histogram vào khung biểu đồ. Các thanh histogram được tạo ra với chiều rộng của mỗi biến là 500 đơn vị giá. Màu nền của histogram được tô màu đen (fill = ‘black’) và màu viền của histogram được tô màu trắng (color = ‘white’).

  • facet_wrap(~color): Tạo các biểu đồ con (facets) dựa trên biến color, tức là mỗi biểu đồ con sẽ hiển thị dữ liệu cho một mức của biến color.

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA0Ig0KYXV0aG9yOiBMw6JtIFRo4bqjbyBNeSANCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRoZW1lOiAiZGVmYXVsdCINCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICB0b2NfZGVwdGg6IDINCi0tLQ0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyAqKkdp4bubaSB0aGnhu4d1KioNCg0KIyMgKipDw6BpIHbDoCBMb2FkIGLhu5kgZOG7ryBsaeG7h3UgdsOgbyBSKioNCg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiLCByZXBvcz0iaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tLyIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KYSA8LSBkaWFtb25kcw0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6FjIGPDonUgbOG7h25oKioNCiAgLSAqKkluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpKio6IETDsm5nIG7DoHkgc+G6vSBjw6BpIMSR4bq3dCBnw7NpICJ0aWR5dmVyc2UiIHbDoG8gdHJvbmcgbcO0aSB0csaw4budbmcgUiANCiAgLSAqKmxpYnJhcnkodGlkeXZlcnNlKToqKiBEw7JuZyBuw6B5IHPhur0gdOG6o2kgZ8OzaSAidGlkeXZlcnNlIiB2w6BvIGLhu5kgbmjhu5sgxJHhu4Mgc+G7rSBk4bulbmcgYuG6pXQga+G7syBjaOG7qWMgbsSDbmcgbsOgbyB04burIHRpZHl2ZXJzZQ0KICAtICoqbGlicmFyeShzY2FsZXMpOioqIETDsm5nIG7DoHkgdOG6o2kgZ8OzaSAic2NhbGVzIiB2w6BvIGLhu5kgbmjhu5sgbMOgbSB2aeG7h2MuICJTY2FsZXMiIGzDoCBt4buZdCBnw7NpIHRyb25nICJ0aWR5dmVyc2UiIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHThuqFvIHbDoCB0w7l5IGNo4buJbmggY8OhYyBiaeG7g3UgxJHhu5MuDQogIC0gKiphIDwtIGRpYW1vbmRzOioqIETDsm5nIG7DoHkgdOG6o2kgZOG7ryBsaeG7h3UgZGlhbW9uZHMgdOG7qyBnw7NpIGThu68gbGnhu4d1IG3huqt1IHRyb25nIHRpZHl2ZXJzZSB2w6AgZ8OhbiB2w6BvIG9iaiBhDQogDQoqKkvhur90IHF14bqjIGzDoDoqKiBDw7MgbeG7mXQgb2JqIGEgYmFvIGfhu5NtIDUzOTQwIG9icy4gb2YgMTAgdmFyaWFibGVzDQoNCiMjICoqVGjDtG5nIHRpbiBjxqEgYuG6o24gY+G7p2EgYuG7mSBk4buvIGxp4buHdSoqDQoNCmBgYHtyfQ0KaXMuZGF0YS5mcmFtZShhKQ0KbGVuZ3RoKGEpDQpuYW1lcyhhKQ0KZGltKGEpDQpsaWJyYXJ5KHNraW1yKQ0Kc2tpbShhKQ0KYGBgDQoNCiMgKipW4bq9IMSQ4buTIFRo4buLIEThuqFuZyBCYXIgQ2hhcnQqKg0KDQojIyDEkOG7kyBUaOG7iyAxOiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBiaeG6v24gY3V0LCBjb2xvciwgY2xhcml0eQ0KDQpgYGB7cn0NCmEgJT4lIGdncGxvdChhZXMoeCA9IGN1dCkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQoqKkdp4bqjaSBUaMOtY2ggQ8OidSBM4buHbmg6KioNCiAtICoqYSAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0KSkqKjogRMOybmcgbsOgeSBz4butIGThu6VuZyB0b8OhbiB04butICU+JSB04burIGfDs2kgZHBseXIgxJHhu4MgY2h1eeG7g24gxJHhu5VpIGThu68gbGnhu4d1IHRyb25nIGEgdGjDoG5oIG3hu5l0IGx14buTbmcgZOG7ryBsaeG7h3UgdsOgIMSRxrBhIHbDoG8gZ2dwbG90Mi4gVHJvbmcgaMOgbSBnZ3Bsb3QoKSwgYWVzKHggPSBjdXQpIHRoaeG6v3QgbOG6rXAgbeG7mXQgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBk4buvIGxp4buHdSB2w6AgY8OhYyB0aGFtIHPhu5EgdHLDqm4gdHLhu6VjIHgsIHRyb25nIHRyxrDhu51uZyBo4bujcCBuw6B5IGzDoCBjdXQsIGzDoCBt4buZdCBiaeG6v24gdHJvbmcgZGlhbW9uZHMgY2jhu6lhIHRow7RuZyB0aW4gduG7gSBjw6FjIGxv4bqhaSBraW0gY8awxqFuZy4NCiAtICoqSMOgbSBnZW9tX2JhcigpKiogxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgdOG6oW8gcmEgY8OhYyBj4buZdCBk4buxYSB0csOqbiBz4buRIGzhuqduIHh14bqldCBoaeG7h24gY+G7p2EgbeG7l2kgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0DQogLSAqKmxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKToqKiBEw7JuZyBuw6B5IHPhu60gZOG7pW5nIGjDoG0gKipsYWJzKCkqKiDEkeG7gyDEkeG6t3QgdMOqbiBjaG8gdHLhu6VjIHggdsOgIHRy4bulYyB5IGPhu6dhIGJp4buDdSDEkeG7ky4gVHJvbmcgdHLGsOG7nW5nIGjhu6NwIG7DoHksIHRy4bulYyB4IMSRxrDhu6NjIGfDoW4gbmjDo24gbMOgICoqIkxv4bqhaSIqKiB2w6AgdHLhu6VjIHkgxJHGsOG7o2MgZ8OhbiBuaMOjbiBsw6AgKioiU+G7kSBsxrDhu6NuZyIqKg0KDQojIyDEkOG7kyBUaOG7iyAyOiDEkOG7kyB0aOG7iyBiaeG7g3UgdGjhu4sgc+G7kSBsxrDhu6NuZyBjw6FjIHF1YW4gc8OhdCBjaG8gdOG7q25nIG3DoHUgc+G6r2MgY+G7p2Ega2ltIGPGsMahbmcNCg0KYGBge3J9DQphICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvcikpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgVGjDrWNoIEPDonUgTOG7h25oOioqDQogLSAqKmEgJT4lIGdncGxvdChhZXMoeCA9IGNvbG9yKSkqKjogRMOybmcgbsOgeSBz4butIGThu6VuZyB0b8OhbiB04butICU+JSB04burIGfDs2kgZHBseXIgxJHhu4MgY2h1eeG7g24gxJHhu5VpIGThu68gbGnhu4d1IHRyb25nIGEgdGjDoG5oIG3hu5l0IGx14buTbmcgZOG7ryBsaeG7h3UgdsOgIMSRxrBhIHbDoG8gZ2dwbG90Mi4gVHJvbmcgaMOgbSBnZ3Bsb3QoKSwgYWVzKHggPSBjb2xvcikgdGhp4bq/dCBs4bqtcCBt4buZdCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGThu68gbGnhu4d1IHbDoCBjw6FjIHRoYW0gc+G7kSB0csOqbiB0cuG7pWMgeCwgdHJvbmcgdHLGsOG7nW5nIGjhu6NwIG7DoHkgbMOgIGNvbG9yLCBsw6AgbeG7mXQgYmnhur9uIHRyb25nIGRpYW1vbmRzIGNo4bupYSB0aMO0bmcgdGluIHbhu4EgY8OhYyBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nLg0KIC0gKipIw6BtIGdlb21fYmFyKCkqKiDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyB04bqhbyByYSBjw6FjIGPhu5l0IGThu7FhIHRyw6puIHPhu5EgbOG6p24geHXhuqV0IGhp4buHbiBj4bunYSBt4buXaSBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvcg0KIC0gKipsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpOioqIETDsm5nIG7DoHkgc+G7rSBk4bulbmcgaMOgbSAqKmxhYnMoKSoqIMSR4buDIMSR4bq3dCB0w6puIGNobyB0cuG7pWMgeCB2w6AgdHLhu6VjIHkgY+G7p2EgYmnhu4N1IMSR4buTLiBUcm9uZyB0csaw4budbmcgaOG7o3AgbsOgeSwgdHLhu6VjIHggxJHGsOG7o2MgZ8OhbiBuaMOjbiBsw6AgKioiTcOgdSIqKiB2w6AgdHLhu6VjIHkgxJHGsOG7o2MgZ8OhbiBuaMOjbiBsw6AgKioiU+G7kSBsxrDhu6NuZyIqKg0KDQojIyDEkOG7kyBUaOG7iyAzOiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIGdp4buvYSDEkeG7mSB0cm9uZyBj4bunYSB2acOqbiBraW0gY8awxqFuZyAoY2xhcml0eSkgdsOgIHPhu5EgbMaw4bujbmcgY8OhYyB2acOqbiBraW0gY8awxqFuZw0KDQpgYGB7cn0NCmEgJT4lIGdncGxvdChhZXMoeCA9IGNsYXJpdHkpKSArDQogICAgZ2VvbV9iYXIoKSArDQogICAgbGFicyh4ID0gJ03hu6ljIMSR4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgVGjDrWNoIEPDonUgTOG7h25oOioqDQogLSAqKmEgJT4lIGdncGxvdChhZXMoeCA9IGNsYXJpdHkpKSoqOiBEw7JuZyBuw6B5IHPhu60gZOG7pW5nIHRvw6FuIHThu60gJT4lIHThu6sgZ8OzaSBkcGx5ciDEkeG7gyBjaHV54buDbiDEkeG7lWkgZOG7ryBsaeG7h3UgdHJvbmcgYSB0aMOgbmggbeG7mXQgbHXhu5NuZyBk4buvIGxp4buHdSB2w6AgxJHGsGEgdsOgbyBnZ3Bsb3QyLiBUcm9uZyBow6BtIGdncGxvdCgpLCBhZXMoeCA9IGNsYXJpdHkpIHRoaeG6v3QgbOG6rXAgbeG7mXQgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBk4buvIGxp4buHdSB2w6AgY8OhYyB0aGFtIHPhu5EgdHLDqm4gdHLhu6VjIHgsIHRyb25nIHRyxrDhu51uZyBo4bujcCBuw6B5IGzDoCBjbGFyaXR5LCBsw6AgbeG7mXQgYmnhur9uIHRyb25nIGRpYW1vbmRzIGNo4bupYSB0aMO0bmcgdGluIHbhu4EgbeG7qWMgxJHhu5kgdGluaCBraGnhur90IGPhu6dhIGtpbSBjxrDGoW5nLg0KIC0gKipIw6BtIGdlb21fYmFyKCkqKiDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyB04bqhbyByYSBjw6FjIGPhu5l0IGThu7FhIHRyw6puIHPhu5EgbOG6p24geHXhuqV0IGhp4buHbiBj4bunYSBt4buXaSBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5DQogLSAqKmxhYnMoeCA9ICdN4bupYyDEkeG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKToqKiBEw7JuZyBuw6B5IHPhu60gZOG7pW5nIGjDoG0gKipsYWJzKCkqKiDEkeG7gyDEkeG6t3QgdMOqbiBjaG8gdHLhu6VjIHggdsOgIHRy4bulYyB5IGPhu6dhIGJp4buDdSDEkeG7ky4gVHJvbmcgdHLGsOG7nW5nIGjhu6NwIG7DoHksIHRy4bulYyB4IMSRxrDhu6NjIGfDoW4gbmjDo24gbMOgICoqIk3hu6ljIMSR4buZIHRpbmgga2hp4bq/dCIqKiB2w6AgdHLhu6VjIHkgxJHGsOG7o2MgZ8OhbiBuaMOjbiBsw6AgKioiU+G7kSBsxrDhu6NuZyIqKg0KDQojIyDEkOG7kyBUaOG7iyA0OiBCaeG7g3UgxJHhu5MgY+G7mXQgduG7m2kgY2jDuiB0aMOtY2ggc+G7kSBsxrDhu6NuZyB0aGVvIHThu6tuZyBiaeG6v246IGN1dCwgY29sb3IsIGNsYXJpdHkNCg0KYGBge3J9DQphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY3V0LG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0ncmVkJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCoqDQotICoqYSAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQsIHNhdSDEkcOzIHTDrW5oIHThu5VuZyBz4buRIGzGsOG7o25nIGPDoWMgbeG6q3UgdHJvbmcgbeG7l2kgbmjDs20uDQoNCi0gKipnZ3Bsb3QoYWVzKGN1dCxuKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGN1dCB0csOqbiB0cuG7pWMgeCB2w6Agc+G7kSBsxrDhu6NuZyB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKGZpbGw9J3JlZCcpOioqIFRow6ptIG3hu5l0IGxheWVyIGJp4buDdSDEkeG7kyBj4buZdCB2w6BvIGtodW5nIGJp4buDdSDEkeG7kyB24bubaSBtw6B1IG7hu4FuIMSR4buPLg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnYmxhY2snKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbMaw4bujbmcgbMOqbiB0csOqbiBjw6FjIGPhu5l0LiBDw6FjIG5ow6NuIG7DoHkgxJHGsOG7o2MgbOG6pXkgdOG7qyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBuIHbDoCDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMikgdsOgIG3DoHUgY2jhu68gbMOgIMSRZW4gKGNvbG9yID0gJ2JsYWNrJykuDQoNCi0gKipsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJyk6KiogxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCBsw6AgKioiTG/huqFpIioqIHbDoCB0cuG7pWMgeSBsw6AgKioiU+G7kSBsxrDhu6NuZyIqKi4NCg0KIyMgxJDhu5MgVGjhu4sgNTogxJDhu5MgdGjhu4sgdGjhu4MgaGnhu4duIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgbcOgdSBz4bqvYyBj4bunYSB2acOqbiBraW0gY8awxqFuZyAoY29sb3IpIHbDoCBz4buRIGzGsOG7o25nIGPDoWMgdmnDqm4ga2ltIGPGsMahbmcoY2jDuiB0aMOtY2ggc+G7kSBsxrDhu6NuZykNCg0KYGBge3J9DQphICU+JSBncm91cF9ieShjb2xvcikgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjb2xvcixuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2dyZWVuJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ3JlZCcpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCoqDQotICoqYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLCBzYXUgxJHDsyB0w61uaCB04buVbmcgc+G7kSBsxrDhu6NuZyBjw6FjIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtLg0KDQotICoqZ2dwbG90KGFlcyhjb2xvcixuKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGNvbG9yIHRyw6puIHRy4bulYyB4IHbDoCBz4buRIGzGsOG7o25nIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2woZmlsbD0nZ3JlZW4nKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MgduG7m2kgbcOgdSBu4buBbiB4YW5oIGzDoSBjw6J5Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGzGsOG7o25nIGzDqm4gdHLDqm4gY8OhYyBj4buZdC4gQ8OhYyBuaMOjbiBuw6B5IMSRxrDhu6NjIGzhuqV5IHThu6sgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gbiB2w6AgxJHGsOG7o2MgY8SDbiBjaOG7iW5oIGThu41jICh2anVzdCA9IDIpIHbDoCBtw6B1IGNo4buvIGzDoCDEkeG7jyAoY29sb3IgPSAncmVkJykuDQoNCi0gKipsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3DoHUiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJT4buRIGzGsOG7o25nIioqLg0KDQojIyDEkOG7kyBUaOG7iyA2OiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIGdp4buvYSDEkeG7mSB0cm9uZyBj4bunYSB2acOqbiBraW0gY8awxqFuZyAoY2xhcml0eSkgdsOgIHPhu5EgbMaw4bujbmcgY8OhYyB2acOqbiBraW0gY8awxqFuZyhjaMO6IHRow61jaCBz4buRIGzGsOG7o25nKQ0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY2xhcml0eSxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J3llbGxvdycpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAxLCBjb2xvciA9ICdyZWQnKSArDQogICAgbGFicyh4ID0gJ03hu6ljIMSR4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oKioNCi0gKiphICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5LCBzYXUgxJHDsyB0w61uaCB04buVbmcgc+G7kSBsxrDhu6NuZyBjw6FjIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtLg0KDQotICoqZ2dwbG90KGFlcyhjbGFyaXR5LG4pKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY2xhcml0eSB0csOqbiB0cuG7pWMgeCB2w6Agc+G7kSBsxrDhu6NuZyB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKGZpbGw9J3llbGxvdycpOioqIFRow6ptIG3hu5l0IGxheWVyIGJp4buDdSDEkeG7kyBj4buZdCB2w6BvIGtodW5nIGJp4buDdSDEkeG7kyB24bubaSBtw6B1IG7hu4FuIHbDoG5nLg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMSwgY29sb3IgPSAncmVkJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGzGsOG7o25nIGzDqm4gdHLDqm4gY8OhYyBj4buZdC4gQ8OhYyBuaMOjbiBuw6B5IMSRxrDhu6NjIGzhuqV5IHThu6sgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gbiB2w6AgxJHGsOG7o2MgY8SDbiBjaOG7iW5oIGThu41jICh2anVzdCA9IDEpIHbDoCBtw6B1IGNo4buvIGzDoCDEkeG7lSAoY29sb3IgPSAncmVkJykuDQoNCi0gKipsYWJzKHggPSAnTeG7qWMgxJHhu5kgdGluaCBraGnhur90JywgeSA9ICdT4buRIGzGsOG7o25nJykqKiDEkOG6t3QgbmjDo24gY2hvIHRy4bulYyB4IGzDoCAqKiJN4bupYyDEkeG7mSB0aW5oIGtoaeG6v3QiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJT4buRIGzGsOG7o25nIioqLg0KDQojIyDEkOG7kyBUaOG7iyA3OiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBiaeG6v246IGNvbG9yLCBjdXQsIGNsYXJpdHkgdsOgIHRo4buDIGhp4buHbiB04bu3IGzhu4cgcGjhuqduIHRyxINtIHRyw6puIHThu5VuZyBz4buRIHZpw6puIGtpbSBjxrDGoW5nDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2dyZWVuJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQobi9sZW5ndGgoYSRjYXJhdCkpKSx2anVzdCA9IDEsIGNvbG9yID0gJ3JlZCcpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmg6KioNCi0gKiphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dCwgc2F1IMSRw7MgdMOtbmggdOG7lW5nIHPhu5EgbMaw4bujbmcgY8OhYyBt4bqrdSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBuLg0KDQotICoqZ2dwbG90KGFlcyhjdXQsbikpOioqIFThuqFvIG3hu5l0IGtodW5nIGJp4buDdSDEkeG7kyBt4bubaSwgdGhp4bq/dCBs4bqtcCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBjdXQgdHLDqm4gdHLhu6VjIHggdsOgIHPhu5EgbMaw4bujbmcgdHLDqm4gdHLhu6VjIHkuDQoNCi0gKipnZW9tX2NvbChmaWxsPSdncmVlbicpOiAqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MgduG7m2kgbcOgdSBu4buBbiBsw6AgbcOgdSB4YW5oIGzDoSBjw6J5Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChuL2xlbmd0aChhJGNhcmF0KSkpLHZqdXN0ID0gMSwgY29sb3IgPSAncmVkJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEPDoWMgbmjDo24gbsOgeSBsw6AgdOG7iSBs4buHIHBo4bqnbiB0csSDbSBj4bunYSBz4buRIGzGsOG7o25nIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIHNvIHbhu5tpIHThu5VuZyBz4buRIGzGsOG7o25nIG3huqt1ICjEkcaw4bujYyB0w61uaCBi4bqxbmcgbi9sZW5ndGgoZCRjYXJhdCkpLiBDw6FjIG5ow6NuIMSRxrDhu6NjIGPEg24gY2jhu4luaCBk4buNYyAodmp1c3QgPSAxKSB2w6AgxJHGsOG7o2MgxJHhu4tuaCBk4bqhbmcgbcOgdSDEkeG7jy4NCg0KLSAqKmxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKToqKiDEkOG6t3QgbmjDo24gY2hvIHRy4bulYyB4IGzDoCAqKiJMb+G6oWkiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJT4buRIGzGsOG7o25nIioqLg0KDQojIyDEkOG7kyBUaOG7iyA4OiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIGdp4buvYSBtw6B1IHPhuq9jIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIChjb2xvcikgdsOgIHPhu5EgbMaw4bujbmcgY8OhYyB2acOqbiBraW0gY8awxqFuZyDEkeG7k25nIHRo4budaSB0aOG7gyBoaeG7h24gdOG7tyBs4buHIHBo4bqnbiB0csSDbSBj4bunYSBjw6FjIHZpw6puIGtpbSBjxrDGoW5nIHRyw6puIHThu5VuZyBz4buRIHZpw6puIGtpbSBjxrDGoW5nDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY29sb3IsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdibGFjaycpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KG4vbGVuZ3RoKGEkZGVwdGgpKSksdmp1c3QgPSAxLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oOioqDQotICoqYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLCBzYXUgxJHDsyB0w61uaCB04buVbmcgc+G7kSBsxrDhu6NuZyBjw6FjIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIHbDoCBsxrB1IHbDoG8gYmnhur9uIG4uDQoNCi0gKipnZ3Bsb3QoYWVzKGNvbG9yLG4pKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY29sb3IgdHLDqm4gdHLhu6VjIHggdsOgIHPhu5EgbMaw4bujbmcgdHLDqm4gdHLhu6VjIHkuDQoNCi0gKipnZW9tX2NvbChmaWxsPSdibGFjaycpOiAqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MgduG7m2kgbcOgdSBu4buBbiBsw6AgbcOgdSDEkWVuLg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChuL2xlbmd0aChhJGRlcHRoKSkpLHZqdXN0ID0gMSwgY29sb3IgPSAnd2hpdGUnKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbGnhu4d1IGzDqm4gdHLDqm4gxJHhu4luaCBj4bunYSBt4buXaSBj4buZdC4gQ8OhYyBuaMOjbiBuw6B5IGzDoCB04buJIGzhu4cgcGjhuqduIHRyxINtIGPhu6dhIHPhu5EgbMaw4bujbmcgbeG6q3UgdHJvbmcgbeG7l2kgbmjDs20gc28gduG7m2kgdOG7lW5nIHPhu5EgbMaw4bujbmcgbeG6q3UgKMSRxrDhu6NjIHTDrW5oIGLhurFuZyBuL2xlbmd0aChhJGRlcHRoKSkuIEPDoWMgbmjDo24gxJHGsOG7o2MgY8SDbiBjaOG7iW5oIGThu41jICh2anVzdCA9IDEpIHbDoCDEkcaw4bujYyDEkeG7i25oIGThuqFuZyBtw6B1IHRy4bqvbmcuDQoNCi0gKipsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3DoHUiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJT4buRIGzGsOG7o25nIioqLg0KDQojIyDEkOG7kyBUaOG7iyA5OiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIGdp4buvYSDEkeG7mSB0cm9uZyBj4bunYSB2acOqbiBraW0gY8awxqFuZyAoY2xhcml0eSkgdsOgIHPhu5EgbMaw4bujbmcgY8OhYyB2acOqbiBraW0gY8awxqFuZyDEkeG7k25nIHRo4budaSB0aOG7gyBoaeG7h24gdOG7tyBs4buHIHBo4bqnbiB0csSDbSBj4bunYSBjw6FjIHZpw6puIGtpbSBjxrDGoW5nIHRyw6puIHThu5VuZyBz4buRIHZpw6puIGtpbSBjxrDGoW5nDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjbGFyaXR5LG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0ndmlvbGV0JykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQobi9sZW5ndGgoYSRwcmljZSkpKSx2anVzdCA9IDEsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdN4bupYyDEkeG7mSB0aW5oIGtoaeG6v3QnLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNsYXJpdHksIHNhdSDEkcOzIHTDrW5oIHThu5VuZyBz4buRIGzGsOG7o25nIGPDoWMgbeG6q3UgdHJvbmcgbeG7l2kgbmjDs20gdsOgIGzGsHUgdsOgbyBiaeG6v24gbi4NCg0KLSAqKmdncGxvdChhZXMoY2xhcml0eSxuKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGNsYXJpdHkgdHLDqm4gdHLhu6VjIHggdsOgIHPhu5EgbMaw4bujbmcgdHLDqm4gdHLhu6VjIHkuDQoNCi0gKipnZW9tX2NvbChmaWxsPSd2aW9sZXQnKTogKiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTIHbhu5tpIG3DoHUgbuG7gW4gbMOgIG3DoHUgdMOtbS4NCg0KLSAqKmdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQobi9sZW5ndGgoYSRwcmljZSkpKSx2anVzdCA9IDEsIGNvbG9yID0gJ2JsYWNrJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEPDoWMgbmjDo24gbsOgeSBsw6AgdOG7iSBs4buHIHBo4bqnbiB0csSDbSBj4bunYSBz4buRIGzGsOG7o25nIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIHNvIHbhu5tpIHThu5VuZyBz4buRIGzGsOG7o25nIG3huqt1ICjEkcaw4bujYyB0w61uaCBi4bqxbmcgbi9sZW5ndGgoYSRwcmljZSkpLiBDw6FjIG5ow6NuIMSRxrDhu6NjIGPEg24gY2jhu4luaCBk4buNYyAodmp1c3QgPSAxKSB2w6AgxJHGsOG7o2MgxJHhu4tuaCBk4bqhbmcgbcOgdSDEkWVuLg0KDQotICoqbGFicyh4ID0gJ03hu6ljIMSR4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3hu6ljIMSR4buZIHRpbmgga2hp4bq/dCIqKiB2w6AgdHLhu6VjIHkgbMOgICoqIlPhu5EgbMaw4bujbmciKiouDQoNCiMjIMSQ4buTIFRo4buLIDEwOiBCaeG7g3UgxJHhu5MgY+G7mXQga8OpcCB0aGVvIG3hurd0IGPhuq90IChjdXQpIHBow6JuIHTDoWNoIHRoZW8gbcOgdSBz4bqvYyAoY29sb3IpDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmNvbG9yKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMSwgY29sb3IgPSAnZ3JlZW4nKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oIDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dCB2w6AgY29sb3IsIHNhdSDEkcOzIHTDrW5oIHThu5VuZyBz4buRIGzGsOG7o25nIGPDoWMgbeG6q3UgdHJvbmcgbeG7l2kgbmjDs20gdsOgIGzGsHUgdsOgbyBiaeG6v24gbi4NCg0KLSAqKmdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY3V0IHRyw6puIHRy4bulYyB4IHbDoCBz4buRIGzGsOG7o25nIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MuIFbhu5tpIHRoYW0gc+G7kSBwb3NpdGlvbiA9ICdkb2RnZScsIGPDoWMgY+G7mXQgxJHGsOG7o2MgduG6vSBjw6FjaCB4YSBuaGF1LCBt4buXaSBuaMOzbSBj4buZdCB0xrDGoW5nIOG7qW5nIHbhu5tpIG3hu5l0IGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLg0KDQotICoqZmFjZXRfd3JhcCh+Y29sb3IpOioqIENoaWEgYmnhu4N1IMSR4buTIHRow6BuaCBuaGnhu4F1ICJwYW5lcyIgKHBo4bqnbiBuaOG7jykgZOG7sWEgdHLDqm4gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY29sb3IsIHThu6ljIGzDoCB04bqhbyByYSBuaGnhu4F1IGJp4buDdSDEkeG7kyBjb24sIG3hu5dpIGJp4buDdSDEkeG7kyBjb24gY2hvIG3hu5l0IGdpw6EgdHLhu4sgcmnDqm5nIGPhu6dhIGJp4bq/biBjb2xvci4NCg0KLSAqKmdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgdmp1c3QgPSAxLCBjb2xvciA9ICdncmVlbicpOioqIFRow6ptIGPDoWMgbmjDo24gc+G7kSBsaeG7h3UgbMOqbiB0csOqbiDEkeG7iW5oIGPhu6dhIG3hu5dpIGPhu5l0LiBDw6FjIG5ow6NuIG7DoHkgxJHGsOG7o2MgbOG6pXkgdOG7qyBiaeG6v24gbiB2w6AgxJHGsOG7o2MgY8SDbiBjaOG7iW5oIGThu41jICh2anVzdCA9IDEpIHbDoCDEkeG7i25oIGThuqFuZyBtw6B1IGNo4buvIGzDoCBtw6B1IHhhbmggbMOhIGPDonkuDQoNCi0gKipsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJyk6KiogxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCBsw6AgKioiTG/huqFpIioqIHbDoCB0cuG7pWMgeSBsw6AgKioiU+G7kSBsxrDhu6NuZyIqKi4NCg0KIyMgxJDhu5MgVGjhu4sgMTE6IEJp4buDdSDEkeG7kyBj4buZdCBrw6lwIHRoZW8gbeG6t3QgY+G6r3QgKGN1dCkgcGjDom4gdMOhY2ggdGhlbyDEkeG7mSB0cm9uZyhjbGFyaXR5KQ0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGN1dCxjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmNsYXJpdHkpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAxLCBjb2xvciA9ICdyZWQnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oIDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGN1dCwgY2xhcml0eSkgJT4lIHN1bW1hcmlzZShuID0gbigpKToqKiBOaMOzbSBk4buvIGxp4buHdSB0cm9uZyBhIHRoZW8gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0IHbDoCBjbGFyaXR5LCBzYXUgxJHDsyB0w61uaCB04buVbmcgc+G7kSBsxrDhu6NuZyBjw6FjIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIHbDoCBsxrB1IHbDoG8gYmnhur9uIG4uDQoNCi0gKipnZ3Bsb3QoYWVzKHggPSBjdXQsIHkgPSBuKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGN1dCB0csOqbiB0cuG7pWMgeCB2w6Agc+G7kSBsxrDhu6NuZyB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBW4bubaSB0aGFtIHPhu5EgcG9zaXRpb24gPSAnZG9kZ2UnLCBjw6FjIGPhu5l0IMSRxrDhu6NjIHbhur0gY8OhY2ggeGEgbmhhdSwgbeG7l2kgbmjDs20gY+G7mXQgdMawxqFuZyDhu6luZyB24bubaSBt4buZdCBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5Lg0KDQotICoqZmFjZXRfd3JhcCh+Y2xhcml0eSk6KiogQ2hpYSBiaeG7g3UgxJHhu5MgdGjDoG5oIG5oaeG7gXUgInBhbmVzIiAocGjhuqduIG5o4buPKSBk4buxYSB0csOqbiBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5LCB04bupYyBsw6AgdOG6oW8gcmEgbmhp4buBdSBiaeG7g3UgxJHhu5MgY29uLCBt4buXaSBiaeG7g3UgxJHhu5MgY29uIGNobyBt4buZdCBnacOhIHRy4buLIHJpw6puZyBj4bunYSBiaeG6v24gY2xhcml0eS4NCg0KLSAqKmdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgdmp1c3QgPSAxLCBjb2xvciA9ICdyZWQnKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbGnhu4d1IGzDqm4gdHLDqm4gxJHhu4luaCBj4bunYSBt4buXaSBj4buZdC4gQ8OhYyBuaMOjbiBuw6B5IMSRxrDhu6NjIGzhuqV5IHThu6sgYmnhur9uIG4gdsOgIMSRxrDhu6NjIGPEg24gY2jhu4luaCBk4buNYyAodmp1c3QgPSAxKSB2w6AgxJHhu4tuaCBk4bqhbmcgbcOgdSBjaOG7ryBsw6AgbcOgdSDEkeG7jy4NCg0KLSAqKmxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKToqKiDEkOG6t3QgbmjDo24gY2hvIHRy4bulYyB4IGzDoCAqKiJMb+G6oWkiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJT4buRIGzGsOG7o25nIioqLg0KDQojIyDEkOG7kyBUaOG7iyAxMjogQmnhu4N1IMSR4buTIGPhu5l0IGvDqXAgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikgdsOgIHBow6JuIHTDoWNoIHRoZW8gxJHhu5kgdHJvbmcgKGNsYXJpdHkpDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY29sb3IsY2xhcml0eSkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmNsYXJpdHkpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAxLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oIDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGNvbG9yLCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciB2w6AgY2xhcml0eSwgc2F1IMSRw7MgdMOtbmggdOG7lW5nIHPhu5EgbMaw4bujbmcgY8OhYyBt4bqrdSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBuLg0KDQotICoqZ2dwbG90KGFlcyh4ID0gY29sb3IsIHkgPSBuKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGNvbG9yIHRyw6puIHRy4bulYyB4IHbDoCBz4buRIGzGsOG7o25nIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MuIFbhu5tpIHRoYW0gc+G7kSBwb3NpdGlvbiA9ICdkb2RnZScsIGPDoWMgY+G7mXQgxJHGsOG7o2MgduG6vSBjw6FjaCB4YSBuaGF1LCBt4buXaSBuaMOzbSBj4buZdCB0xrDGoW5nIOG7qW5nIHbhu5tpIG3hu5l0IGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNsYXJpdHkuDQoNCi0gKipmYWNldF93cmFwKH5jbGFyaXR5KToqKiBDaGlhIGJp4buDdSDEkeG7kyB0aMOgbmggbmhp4buBdSAicGFuZXMiIChwaOG6p24gbmjhu48pIGThu7FhIHRyw6puIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNsYXJpdHksIHThu6ljIGzDoCB04bqhbyByYSBuaGnhu4F1IGJp4buDdSDEkeG7kyBjb24sIG3hu5dpIGJp4buDdSDEkeG7kyBjb24gY2hvIG3hu5l0IGdpw6EgdHLhu4sgcmnDqm5nIGPhu6dhIGJp4bq/biBjbGFyaXR5Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdCA9IDEsIGNvbG9yID0gJ3doaXRlJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBs4bqleSB04burIGJp4bq/biBuIHbDoCDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMSkgdsOgIMSR4buLbmggZOG6oW5nIG3DoHUgY2jhu68gbMOgIG3DoHUgdHLhuq9uZy4NCg0KLSAqKmxhYnMoeCA9ICdNw6B1JywgeSA9ICdT4buRIGzGsOG7o25nJyk6KiogxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCBsw6AgKioiTcOgdSIqKiB2w6AgdHLhu6VjIHkgbMOgICoqIlPhu5EgbMaw4bujbmciKiouDQoNCg0KIyMgxJDhu5MgVGjhu4sgMTM6IEJp4buDdSDEkeG7kyBj4buZdCBrw6lwIHRoZW8gdGhlbyDEkeG7mSB0cm9uZyAoY2xhcml0eSkgdsOgIHBow6JuIHTDoWNoIHRoZW8gbcOgdSBz4bqvYyAoY29sb3IpDQoNCg0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGNvbG9yLGNsYXJpdHkpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjbGFyaXR5LHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmNvbG9yKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMSwgY29sb3IgPSAnYmxhY2snKSArDQogICAgbGFicyh4ID0gJ03hu6ljIMSR4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oIDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGNvbG9yLCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciB2w6AgY2xhcml0eSwgc2F1IMSRw7MgdMOtbmggdOG7lW5nIHPhu5EgbMaw4bujbmcgY8OhYyBt4bqrdSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBuLg0KDQotICoqZ2dwbG90KGFlcyh4ID0gY2xhcml0eSwgeSA9IG4pKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY2xhcml0eSB0csOqbiB0cuG7pWMgeCB2w6Agc+G7kSBsxrDhu6NuZyB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBW4bubaSB0aGFtIHPhu5EgcG9zaXRpb24gPSAnZG9kZ2UnLCBjw6FjIGPhu5l0IMSRxrDhu6NjIHbhur0gY8OhY2ggeGEgbmhhdSwgbeG7l2kgbmjDs20gY+G7mXQgdMawxqFuZyDhu6luZyB24bubaSBt4buZdCBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvci4NCg0KLSAqKmZhY2V0X3dyYXAofmNvbG9yKToqKiBDaGlhIGJp4buDdSDEkeG7kyB0aMOgbmggbmhp4buBdSAicGFuZXMiIChwaOG6p24gbmjhu48pIGThu7FhIHRyw6puIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLCB04bupYyBsw6AgdOG6oW8gcmEgbmhp4buBdSBiaeG7g3UgxJHhu5MgY29uLCBt4buXaSBiaeG7g3UgxJHhu5MgY29uIGNobyBt4buZdCBnacOhIHRy4buLIHJpw6puZyBj4bunYSBiaeG6v24gY29sb3IuDQoNCi0gKipnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gMSwgY29sb3IgPSAnYmxhY2snKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbGnhu4d1IGzDqm4gdHLDqm4gxJHhu4luaCBj4bunYSBt4buXaSBj4buZdC4gQ8OhYyBuaMOjbiBuw6B5IMSRxrDhu6NjIGzhuqV5IHThu6sgYmnhur9uIG4gdsOgIMSRxrDhu6NjIGPEg24gY2jhu4luaCBk4buNYyAodmp1c3QgPSAxKSB2w6AgxJHhu4tuaCBk4bqhbmcgbcOgdSBjaOG7ryBsw6AgbcOgdSDEkWVuLg0KDQotICoqbGFicyh4ID0gJ03hu6ljIMSR4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnU+G7kSBsxrDhu6NuZycpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3hu6ljIMSR4buZIHRpbmgga2hp4bq/dCIqKiB2w6AgdHLhu6VjIHkgbMOgICoqIlPhu5EgbMaw4bujbmciKiouDQoNCg0KIyMgxJDhu5MgVGjhu4sgMTQ6IEJp4buDdSDEkeG7kyBj4buZdCBrw6lwIHRoZW8gbcOgdSBz4bqvYyAoY29sb3IpIHbDoCBwaMOibiB0w6FjaCB0aGVvIG3hurd0IGPhuq90IChjdXQpDQoNCg0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGN1dCxjb2xvcikgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGZhY2V0X3dyYXAofmN1dCkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDEsIGNvbG9yID0gJ3Zpb2xldCcpICsNCiAgICBsYWJzKHggPSAnTcOgdScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oIDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dCB2w6AgY29sb3IsIHNhdSDEkcOzIHTDrW5oIHThu5VuZyBz4buRIGzGsOG7o25nIGPDoWMgbeG6q3UgdHJvbmcgbeG7l2kgbmjDs20gdsOgIGzGsHUgdsOgbyBiaeG6v24gbi4NCg0KLSAqKmdncGxvdChhZXMoeCA9IGNvbG9yLCB5ID0gbikpOioqIFThuqFvIG3hu5l0IGtodW5nIGJp4buDdSDEkeG7kyBt4bubaSwgdGhp4bq/dCBs4bqtcCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBjb2xvciB0csOqbiB0cuG7pWMgeCB2w6Agc+G7kSBsxrDhu6NuZyB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBW4bubaSB0aGFtIHPhu5EgcG9zaXRpb24gPSAnZG9kZ2UnLCBjw6FjIGPhu5l0IMSRxrDhu6NjIHbhur0gY8OhY2ggeGEgbmhhdSwgbeG7l2kgbmjDs20gY+G7mXQgdMawxqFuZyDhu6luZyB24bubaSBt4buZdCBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQuDQoNCi0gKipmYWNldF93cmFwKH5jdXQpOioqIENoaWEgYmnhu4N1IMSR4buTIHRow6BuaCBuaGnhu4F1ICJwYW5lcyIgKHBo4bqnbiBuaOG7jykgZOG7sWEgdHLDqm4gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY29sb3IsIHThu6ljIGzDoCB04bqhbyByYSBuaGnhu4F1IGJp4buDdSDEkeG7kyBjb24sIG3hu5dpIGJp4buDdSDEkeG7kyBjb24gY2hvIG3hu5l0IGdpw6EgdHLhu4sgcmnDqm5nIGPhu6dhIGJp4bq/biBjdXQuDQoNCi0gKipnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gMSwgY29sb3IgPSAndmlvbGV0Jyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBs4bqleSB04burIGJp4bq/biBuIHbDoCDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMSkgdsOgIMSR4buLbmggZOG6oW5nIG3DoHUgY2jhu68gbMOgIG3DoHUgdMOtbS4NCg0KLSAqKmxhYnMoeCA9ICdNw6B1JywgeSA9ICdT4buRIGzGsOG7o25nJyk6KiogxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCBsw6AgKioiTcOgdSIqKiB2w6AgdHLhu6VjIHkgbMOgICoqIlPhu5EgbMaw4bujbmciKiouDQoNCg0KIyMgxJDhu5MgVGjhu4sgMTU6IEJp4buDdSDEkeG7kyBj4buZdCBrw6lwIHRoZW8gdGhlbyDEkeG7mSB0cm9uZyAoY2xhcml0eSkgdsOgIHBow6JuIHTDoWNoIHRoZW8gbeG6t3QgY+G6r3QgKGN1dCkNCg0KYGBge3J9DQphICU+JSBncm91cF9ieShjdXQsY2xhcml0eSkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y3V0KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMSwgY29sb3IgPSAncmVkJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCA6KioNCi0gKiphICU+JSBncm91cF9ieShjdXQsIGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogTmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dCB2w6AgY2xhcml0eSwgc2F1IMSRw7MgdMOtbmggdOG7lW5nIHPhu5EgbMaw4bujbmcgY8OhYyBt4bqrdSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBuLg0KDQotICoqZ2dwbG90KGFlcyh4ID0gY2xhcml0eSwgeSA9IG4pKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY2xhcml0eSB0csOqbiB0cuG7pWMgeCB2w6Agc+G7kSBsxrDhu6NuZyB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBW4bubaSB0aGFtIHPhu5EgcG9zaXRpb24gPSAnZG9kZ2UnLCBjw6FjIGPhu5l0IMSRxrDhu6NjIHbhur0gY8OhY2ggeGEgbmhhdSwgbeG7l2kgbmjDs20gY+G7mXQgdMawxqFuZyDhu6luZyB24bubaSBt4buZdCBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQuDQoNCi0gKipmYWNldF93cmFwKH5jdXQpOioqIENoaWEgYmnhu4N1IMSR4buTIHRow6BuaCBuaGnhu4F1ICJwYW5lcyIgKHBo4bqnbiBuaOG7jykgZOG7sWEgdHLDqm4gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0LCB04bupYyBsw6AgdOG6oW8gcmEgbmhp4buBdSBiaeG7g3UgxJHhu5MgY29uLCBt4buXaSBiaeG7g3UgxJHhu5MgY29uIGNobyBt4buZdCBnacOhIHRy4buLIHJpw6puZyBj4bunYSBiaeG6v24gY3V0Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdCA9IDEsIGNvbG9yID0gJ3JlZCcpOioqIFRow6ptIGPDoWMgbmjDo24gc+G7kSBsaeG7h3UgbMOqbiB0csOqbiDEkeG7iW5oIGPhu6dhIG3hu5dpIGPhu5l0LiBDw6FjIG5ow6NuIG7DoHkgxJHGsOG7o2MgbOG6pXkgdOG7qyBiaeG6v24gbiB2w6AgxJHGsOG7o2MgY8SDbiBjaOG7iW5oIGThu41jICh2anVzdCA9IDEpIHbDoCDEkeG7i25oIGThuqFuZyBtw6B1IGNo4buvIGzDoCBtw6B1IMSR4buPLg0KDQotICoqbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIkxv4bqhaSIqKiB2w6AgdHLhu6VjIHkgbMOgICoqIlPhu5EgbMaw4bujbmciKiouDQoNCiMjIMSQ4buTIFRo4buLIDE2OiBCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkNCg0KYGBge3J9DQphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3doaXRlJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ01lYW4nKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCA6KioNCi0gKiphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBjw6FjIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dCwgc2F1IMSRw7MgdMOtbmggdHJ1bmcgYsOsbmggKG1lYW4oKSkgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBraW0gY8awxqFuZyAoY2FyYXQpIHRyb25nIG3hu5dpIG5ow7NtIHbDoCBsxrB1IHbDoG8gYmnhur9uIG0uDQoNCi0gKipnZ3Bsb3QoYWVzKHggPSBjdXQsIHkgPSBtKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGN1dCB0csOqbiB0cuG7pWMgeCB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAobSkgdHLDqm4gdHLhu6VjIHkuDQoNCi0gKipnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpOioqIFRow6ptIG3hu5l0IGxheWVyIGJp4buDdSDEkeG7kyBj4buZdCB2w6BvIGtodW5nIGJp4buDdSDEkeG7kywgduG7m2kgY8OhYyBj4buZdCDEkcaw4bujYyBz4bqvcCB44bq/cCBj4bqhbmggbmhhdSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dC4gVGhhbSBz4buRIHBvc2l0aW9uID0gJ2RvZGdlJyDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBz4bqvcCB44bq/cCBjw6FjIGPhu5l0IGPhuqFuaCBuaGF1Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3doaXRlJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEdpw6EgdHLhu4sgY+G7p2EgY8OhYyBuaMOjbiBsw6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGtpbSBjxrDGoW5nIMSRxrDhu6NjIGzDoG0gdHLDsm4gduG7m2kgaGFpIGNo4buvIHPhu5Egc2F1IGThuqV1IHRo4bqtcCBwaMOibiAocm91bmQobSwyKSkuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMikgdsOgIMSRxrDhu6NjIG3DoHUgY2jhu68gbMOgIG3DoHUgdHLhuq9uZyDEkeG7gyBwaOG6o24gw6FuaCB0csOqbiBu4buBbiBj4buZdC4NCg0KLSAqKmxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ01lYW4nKToqKiDEkOG6t3QgbmjDo24gY2hvIHRy4bulYyB4IGzDoCAqKiJMb+G6oWkiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJNZWFuIioqIChUcnVuZyBiw6xuaCkuDQoNCiMjIMSQ4buTIFRo4buLIDE3OiBCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyBtw6B1IHPhuq9jIChjb2xvcikNCg0KDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJykgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdNZWFuJykNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmggOioqDQotICoqYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBjw6FjIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLCBzYXUgxJHDsyB0w61uaCB0cnVuZyBiw6xuaCAobWVhbigpKSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGtpbSBjxrDGoW5nIChjYXJhdCkgdHJvbmcgbeG7l2kgbmjDs20gdsOgIGzGsHUgdsOgbyBiaeG6v24gbS4NCg0KLSAqKmdncGxvdChhZXMoeCA9IGNvbG9yLCB5ID0gbSkpOioqIFThuqFvIG3hu5l0IGtodW5nIGJp4buDdSDEkeG7kyBt4bubaSwgdGhp4bq/dCBs4bqtcCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBjb2xvciB0csOqbiB0cuG7pWMgeCB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAobSkgdHLDqm4gdHLhu6VjIHkuDQoNCi0gKipnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpOioqIFRow6ptIG3hu5l0IGxheWVyIGJp4buDdSDEkeG7kyBj4buZdCB2w6BvIGtodW5nIGJp4buDdSDEkeG7kywgduG7m2kgY8OhYyBj4buZdCDEkcaw4bujYyBz4bqvcCB44bq/cCBj4bqhbmggbmhhdSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLiBUaGFtIHPhu5EgcG9zaXRpb24gPSAnZG9kZ2UnIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHPhuq9wIHjhur9wIGPDoWMgY+G7mXQgY+G6oW5oIG5oYXUuDQoNCi0gKipnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEdpw6EgdHLhu4sgY+G7p2EgY8OhYyBuaMOjbiBsw6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGtpbSBjxrDGoW5nIMSRxrDhu6NjIGzDoG0gdHLDsm4gduG7m2kgaGFpIGNo4buvIHPhu5Egc2F1IGThuqV1IHRo4bqtcCBwaMOibiAocm91bmQobSwyKSkuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMikgdsOgIMSRxrDhu6NjIG3DoHUgY2jhu68gbMOgIG3DoHUgxJHhu48gxJHhu4MgcGjhuqNuIMOhbmggdHLDqm4gbuG7gW4gY+G7mXQuDQoNCi0gKipsYWJzKHggPSAnTcOgdScsIHkgPSAnTWVhbicpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3DoHUiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJNZWFuIioqIChUcnVuZyBiw6xuaCkuDQoNCiMjIMSQ4buTIFRo4buLIDE4OiBCaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGhlbyDEkeG7mSB0aW5oIGtoaeG6v3QgKGNvbG9yKQ0KDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2JsdWUnKSArDQogICAgbGFicyh4ID0gJ03hu6ljIMSQ4buZIFRpbmggS2hp4bq/dCcsIHkgPSAnTWVhbicpDQpgYGANCg0KIyMgxJDhu5MgVGjhu4sgMTk6IEJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gdHJ1bmcgYsOsbmggZ2nDoSB0aMOgbmggdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKGN1dCkNCg0KYGBge3J9DQphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobXA9IG1lYW4ocHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtcCkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobXAsMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3doaXRlJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ01lYW4gUHJpY2UnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCA6KioNCi0gKiphICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobXA9IG1lYW4ocHJpY2UpKToqKiBOaMOzbSBk4buvIGxp4buHdSB0cm9uZyBhIHRoZW8gY8OhYyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQsIHNhdSDEkcOzIHTDrW5oIHRydW5nIGLDrG5oIChtZWFuKCkpIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgKHByaWNlKSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBtcC4NCg0KLSAqKmdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG1wKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGN1dCB0csOqbiB0cuG7pWMgeCB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAobXApIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MsIHbhu5tpIGPDoWMgY+G7mXQgxJHGsOG7o2Mgc+G6r3AgeOG6v3AgY+G6oW5oIG5oYXUgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQuIFRoYW0gc+G7kSBwb3NpdGlvbiA9ICdkb2RnZScgxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4Mgc+G6r3AgeOG6v3AgY8OhYyBj4buZdCBj4bqhbmggbmhhdS4NCg0KLSAqKmdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtcCwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbGnhu4d1IGzDqm4gdHLDqm4gxJHhu4luaCBj4bunYSBt4buXaSBj4buZdC4gR2nDoSB0cuG7iyBj4bunYSBjw6FjIG5ow6NuIGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgxJHGsOG7o2MgbMOgbSB0csOybiB24bubaSBoYWkgY2jhu68gc+G7kSBzYXUgZOG6pXUgdGjhuq1wIHBow6JuIChyb3VuZChtcCwyKSkuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMikgdsOgIMSRxrDhu6NjIG3DoHUgY2jhu68gbMOgIG3DoHUgdHLhuq9uZyDEkeG7gyBwaOG6o24gw6FuaCB0csOqbiBu4buBbiBj4buZdC4NCg0KLSAqKmxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ01lYW4gUHJpY2UnKToqKiDEkOG6t3QgbmjDo24gY2hvIHRy4bulYyB4IGzDoCAqKiJMb+G6oWkiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJNZWFuIFByaWNlIioqIChHacOhIFRydW5nIGLDrG5oKS4NCg0KIyMgxJDhu5MgVGjhu4sgMjA6IEJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gdHJ1bmcgYsOsbmggZ2nDoSB0aMOgbmggdGhlbyBtw6B1IHPhuq9jIChjb2xvcikNCg0KDQoNCmBgYHtyfQ0KYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobXA9IG1lYW4ocHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG1wKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtcCwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAncmVkJykgKw0KICAgIGxhYnMoeCA9ICdNw6B1JywgeSA9ICdNZWFuIFByaWNlJykNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmggOioqDQotICoqYSAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobXA9IG1lYW4ocHJpY2UpKToqKiBOaMOzbSBk4buvIGxp4buHdSB0cm9uZyBhIHRoZW8gY8OhYyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciwgc2F1IMSRw7MgdMOtbmggdHJ1bmcgYsOsbmggKG1lYW4oKSkgY+G7p2EgZ2nDoSBraW0gY8awxqFuZyAocHJpY2UpIHRyb25nIG3hu5dpIG5ow7NtIHbDoCBsxrB1IHbDoG8gYmnhur9uIG1wLg0KDQotICoqZ2dwbG90KGFlcyh4ID0gY29sb3IsIHkgPSBtcCkpOioqIFThuqFvIG3hu5l0IGtodW5nIGJp4buDdSDEkeG7kyBt4bubaSwgdGhp4bq/dCBs4bqtcCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBjb2xvciB0csOqbiB0cuG7pWMgeCB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAobXApIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MsIHbhu5tpIGPDoWMgY+G7mXQgxJHGsOG7o2Mgc+G6r3AgeOG6v3AgY+G6oW5oIG5oYXUgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvci4gVGhhbSBz4buRIHBvc2l0aW9uID0gJ2RvZGdlJyDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBz4bqvcCB44bq/cCBjw6FjIGPhu5l0IGPhuqFuaCBuaGF1Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG1wLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdyZWQnKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbGnhu4d1IGzDqm4gdHLDqm4gxJHhu4luaCBj4bunYSBt4buXaSBj4buZdC4gR2nDoSB0cuG7iyBj4bunYSBjw6FjIG5ow6NuIGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgxJHGsOG7o2MgbMOgbSB0csOybiB24bubaSBoYWkgY2jhu68gc+G7kSBzYXUgZOG6pXUgdGjhuq1wIHBow6JuIChyb3VuZChtcCwyKSkuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMikgdsOgIMSRxrDhu6NjIG3DoHUgY2jhu68gbMOgIG3DoHUgxJHhu48gxJHhu4MgcGjhuqNuIMOhbmggdHLDqm4gbuG7gW4gY+G7mXQuDQoNCi0gKipsYWJzKHggPSAnTcOgdScsIHkgPSAnTWVhbiBQcmljZScpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3DoHUiKiogdsOgIHRy4bulYyB5IGzDoCAqKiJNZWFuIFByaWNlIioqIChHacOhIFRydW5nIGLDrG5oKS4NCg0KIyMgxJDhu5MgVGjhu4sgMjE6IEJp4buDdSDEkeG7kyBj4buZdCB0aOG7gyBoaeG7h24gdHJ1bmcgYsOsbmggZ2nDoSB0aMOgbmggdGhlbyDEkeG7mSB0cm9uZyAoY2xhcml0eSkNCg0KYGBge3J9DQphICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG1wPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG1wKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtcCwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnYmx1ZScpICsNCiAgICBsYWJzKHggPSAnTeG7qWMgxJDhu5kgVGluaCBLaGnhur90JywgeSA9ICdNZWFuJykNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmggOioqDQotICoqYSAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtcD0gbWVhbihwcmljZSkpOioqIE5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBjw6FjIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNsYXJpdHksIHNhdSDEkcOzIHTDrW5oIHRydW5nIGLDrG5oIChtZWFuKCkpIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgKHByaWNlKSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBtcC4NCg0KLSAqKmdncGxvdChhZXMoeCA9IGNsYXJyaXR5LCB5ID0gbXApKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY2xhcml0eSB0csOqbiB0cuG7pWMgeCB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAobXApIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MsIHbhu5tpIGPDoWMgY+G7mXQgxJHGsOG7o2Mgc+G6r3AgeOG6v3AgY+G6oW5oIG5oYXUgdGhlbyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5LiBUaGFtIHPhu5EgcG9zaXRpb24gPSAnZG9kZ2UnIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHPhuq9wIHjhur9wIGPDoWMgY+G7mXQgY+G6oW5oIG5oYXUuDQoNCi0gKipnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobXAsMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2JsdWUnKToqKiBUaMOqbSBjw6FjIG5ow6NuIHPhu5EgbGnhu4d1IGzDqm4gdHLDqm4gxJHhu4luaCBj4bunYSBt4buXaSBj4buZdC4gR2nDoSB0cuG7iyBj4bunYSBjw6FjIG5ow6NuIGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6Ega2ltIGPGsMahbmcgxJHGsOG7o2MgbMOgbSB0csOybiB24bubaSBoYWkgY2jhu68gc+G7kSBzYXUgZOG6pXUgdGjhuq1wIHBow6JuIChyb3VuZChtcCwyKSkuIEPDoWMgbmjDo24gbsOgeSDEkcaw4bujYyBjxINuIGNo4buJbmggZOG7jWMgKHZqdXN0ID0gMikgdsOgIMSRxrDhu6NjIG3DoHUgY2jhu68gbMOgIG3DoHUgeGFuaCBkxrDGoW5nIMSR4buDIHBo4bqjbiDDoW5oIHRyw6puIG7hu4FuIGPhu5l0Lg0KDQotICoqbGFicyh4ID0gJ03hu6ljIMSR4buZIHRpbmgga2hp4bq/dCcsIHkgPSAnTWVhbiBQcmljZScpOioqIMSQ4bq3dCBuaMOjbiBjaG8gdHLhu6VjIHggbMOgICoqIk3hu6ljIMSR4buZIHRpbmgga2hp4bq/dCIqKiB2w6AgdHLhu6VjIHkgbMOgICoqIk1lYW4gUHJpY2UiKiogKEdpw6EgVHJ1bmcgYsOsbmgpLg0KDQojIyDEkOG7kyBUaOG7iyAyMjogQmnhu4N1IMSR4buTIGPhu5l0IHRo4buDIGhp4buHbiB0cnVuZyBiw6xuaCDEkeG7mSBzw6J1IGPhu6dhIHbhur90IGPhuq90IChkZXB0aCkgdGhlbyDEkeG7mSB0cm9uZyhjbGFyaXR5KQ0KDQpgYGB7cn0NCmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobWQ9IG1lYW4oZGVwdGgpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbWQpKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG1kLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdibHVlJykgKw0KICAgIGxhYnMoeCA9ICdN4bupYyDEkOG7mSBUaW5oIEtoaeG6v3QnLCB5ID0gJ01lYW4nKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaDoqKg0KLSAqKmEgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobWQ9IG1lYW4oZGVwdGgpKToqKiBOaMOzbSBk4buvIGxp4buHdSB0cm9uZyBhIHRoZW8gY8OhYyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5LCBzYXUgxJHDsyB0w61uaCB0cnVuZyBiw6xuaCAobWVhbigpKSBj4bunYSBjaGnhu4F1IGNhbyAoZGVwdGgpIHRyb25nIG3hu5dpIG5ow7NtIHbDoCBsxrB1IHbDoG8gYmnhur9uIG1kLg0KDQotICoqZ2dwbG90KGFlcyh4ID0gY2xhcml0eSwgeSA9IG1kKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGNsYXJpdHkgdHLDqm4gdHLhu6VjIHggdsOgIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1kKSB0csOqbiB0cuG7pWMgeS4NCg0KLSAqKmdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLCB24bubaSBjw6FjIGPhu5l0IMSRxrDhu6NjIHPhuq9wIHjhur9wIGPhuqFuaCBuaGF1IHRoZW8gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY2xhcml0eS4gVGhhbSBz4buRIHBvc2l0aW9uID0gJ2RvZGdlJyDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBz4bqvcCB44bq/cCBjw6FjIGPhu5l0IGPhuqFuaCBuaGF1Lg0KDQotICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG1kLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdibHVlJyk6KiogVGjDqm0gY8OhYyBuaMOjbiBz4buRIGxp4buHdSBsw6puIHRyw6puIMSR4buJbmggY+G7p2EgbeG7l2kgY+G7mXQuIEdpw6EgdHLhu4sgY+G7p2EgY8OhYyBuaMOjbiBsw6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBjaGnhu4F1IGNhbyDEkcaw4bujYyBsw6BtIHRyw7JuIHbhu5tpIGhhaSBjaOG7ryBz4buRIHNhdSBk4bqldSB0aOG6rXAgcGjDom4gKHJvdW5kKG1kLDIpKS4gQ8OhYyBuaMOjbiBuw6B5IMSRxrDhu6NjIGPEg24gY2jhu4luaCBk4buNYyAodmp1c3QgPSAyKSB2w6AgxJHGsOG7o2MgbcOgdSBjaOG7ryBsw6AgbcOgdSB4YW5oIGTGsMahbmcgxJHhu4MgcGjhuqNuIMOhbmggdHLDqm4gbuG7gW4gY+G7mXQuDQoNCi0gKipsYWJzKHggPSAnTeG7qWMgxJHhu5kgdGluaCBraGnhur90JywgeSA9ICdNZWFuIERlcHRoJyk6KiogxJDhurd0IG5ow6NuIGNobyB0cuG7pWMgeCBsw6AgKioiTeG7qWMgxJHhu5kgdGluaCBraGnhur90IioqIHbDoCB0cuG7pWMgeSBsw6AgKioiTWVhbiBEZXB0aCIqKiAoVHJ1bmcgYsOsbmggY2hp4buBdSBjYW8pLg0KDQojIyDEkOG7kyBUaOG7iyAyMzogxJDhu5MgdGjhu4sgc28gc8Ohbmggc+G7kSBsxrDhu6NuZyB2acOqbiBraW0gY8awxqFuZyBnaeG7r2EgMiBtw6B1IHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IChjdXQpDQoNCmBgYHtyfQ0KYTEgPC0gYSAlPiUgZ3JvdXBfYnkoY3V0LCBjb2xvcikgJT4lIHN1bW1hcmlzZShuID0gbigpKQ0KYSAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0LCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZGF0YSA9IGExICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0knKSwgZmlsbCA9ICdibGFjaycpICsNCiAgZ2VvbV9jb2woZGF0YSA9IGExICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0onKSwgZmlsbCA9ICdyZWQnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaDoqKg0KLSAqKmExIDwtIGEgJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSk6KiogVOG6oW8gbeG7mXQgYuG7mSBk4buvIGxp4buHdSBt4bubaSBhMSBi4bqxbmcgY8OhY2ggbmjDs20gZOG7ryBsaeG7h3UgdHJvbmcgYSB0aGVvIGPDoWMgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0IHbDoCBjb2xvciwgc2F1IMSRw7MgdMOtbmggc+G7kSBsxrDhu6NuZyBt4bqrdSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgbMawdSB2w6BvIGJp4bq/biBuLg0KDQotICoqYSAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0LCB5ID0gbikpOioqIFThuqFvIG3hu5l0IGtodW5nIGJp4buDdSDEkeG7kyBt4bubaSwgdGhp4bq/dCBs4bqtcCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBjdXQgdHLDqm4gdHLhu6VjIHggdsOgIHPhu5EgbMaw4bujbmcgKG4pIHRyw6puIHRy4bulYyB5Lg0KDQotICoqKGRhdGEgPSBhMSAlPiUgZmlsdGVyKGNvbG9yID09ICdJJyksIGZpbGwgPSAnYmxhY2snKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MsIHbhu5tpIGThu68gbGnhu4d1IMSRxrDhu6NjIGzhuqV5IHThu6sgYTEgc2F1IGtoaSBs4buNYyByYSBuaOG7r25nIGTDsm5nIGPDsyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciBsw6AgJ0knLiBDw6FjIGPhu5l0IG7DoHkgc+G6vSDEkcaw4bujYyB0w7QgbcOgdSDEkWVuLg0KDQotICoqZ2VvbV9jb2woZGF0YSA9IGExICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0onKSwgZmlsbCA9ICdyZWQnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MsIHbhu5tpIGThu68gbGnhu4d1IMSRxrDhu6NjIGzhuqV5IHThu6sgYTEgc2F1IGtoaSBs4buNYyByYSBuaOG7r25nIGTDsm5nIGPDsyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciBsw6AgJ0onLiBDw6FjIGPhu5l0IG7DoHkgc+G6vSDEkcaw4bujYyB0w7QgbcOgdSDEkeG7jy4NCg0KIyMgxJDhu5MgVGjhu4sgMjQ6IMSQ4buTIHRo4buLIHRo4buDIGhp4buHbiBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIHRy4buNbmcgbMaw4bujbmcgdsOgIHPhu5EgbMaw4bujbmcgY+G7p2EgY8OhYyB2acOqbiBraW0gY8awxqFuZw0KDQpgYGB7cn0NCmEyIDwtIGEgJT4lIG11dGF0ZShjYXJhdEMgPSBjdXQoY2FyYXQsNSwgbGFiZWwgPSBjKCdy4bqldCBuaOG7jycsICduaOG7jycsJ3bhu6thJywnbOG7m24nLCdy4bqldCBs4bubbicpKSkNCmEyICU+JSBnZ3Bsb3QoYWVzKHggPSBjYXJhdEMpKSArDQogIGdlb21fYmFyKGZpbGwgPSAncmVkJykNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmggOioqDQotICoqYTIgPC0gYSAlPiUgbXV0YXRlKGNhcmF0QyA9IGN1dChjYXJhdCw1LCBsYWJlbCA9IGMoJ3LhuqV0IG5o4buPJywgJ25o4buPJywnduG7q2EnLCds4bubbicsJ3LhuqV0IGzhu5tuJykpKToqKiBU4bqhbyBt4buZdCBi4buZIGThu68gbGnhu4d1IG3hu5tpIGEyIHThu6sgYuG7mSBk4buvIGxp4buHdSBhLiBUcm9uZyBi4buZIGThu68gbGnhu4d1IG7DoHksIG3hu5l0IGJp4bq/biBt4bubaSDEkcaw4bujYyB0aMOqbSB2w6BvIGzDoCBjYXJhdEMuIEJp4bq/biBuw6B5IMSRxrDhu6NjIHThuqFvIHJhIGLhurFuZyBjw6FjaCBjaGlhIGJp4bq/biBjYXJhdCB0aMOgbmggNSBuaMOzbSBz4butIGThu6VuZyBow6BtIGN1dCgpLiBOaMOjbiBj4bunYSBjw6FjIG5ow7NtIMSRxrDhu6NjIMSR4bq3dCBs4bqnbiBsxrDhu6N0IGzDoCAncuG6pXQgbmjhu48nLCAnbmjhu48nLCAnduG7q2EnLCAnbOG7m24nLCAncuG6pXQgbOG7m24nLg0KDQotICoqYTIgJT4lIGdncGxvdChhZXMoeCA9IGNhcmF0QykpOioqIFThuqFvIG3hu5l0IGtodW5nIGJp4buDdSDEkeG7kyBt4bubaSwgdGhp4bq/dCBs4bqtcCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBjYXJhdEMgdHLDqm4gdHLhu6VjIHguDQoNCi0gKipnZW9tX2JhcihmaWxsID0gJ3JlZCcpOioqIFRow6ptIG3hu5l0IGxheWVyIGJp4buDdSDEkeG7kyBj4buZdCB2w6BvIGtodW5nIGJp4buDdSDEkeG7kyB24bubaSBtw6B1IG7hu4FuIGzDoCBtw6B1IMSR4buPLiBN4buXaSBj4buZdCB0cm9uZyBiaeG7g3UgxJHhu5MgbsOgeSDEkeG6oWkgZGnhu4duIGNobyBz4buRIGzGsOG7o25nIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIGPhu6dhIGJp4bq/biBjYXJhdEMuDQoNCiMjIMSQ4buTIFRo4buLIDI1OiANCmBgYHtyfQ0KYTMgPC0gYSAlPiUgZ3JvdXBfYnkoY29sb3IsIGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkNCmEgJT4lIGdncGxvdChhZXMoeCA9IGNsYXJpdHksIHkgPSBuKSkgKw0KICBnZW9tX2NvbChkYXRhID0gYTMgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzEnKSwgZmlsbCA9ICdibHVlJykgKw0KICBnZW9tX2NvbChkYXRhID0gYTMgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzInKSwgZmlsbCA9ICdyZWQnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBk4buvIGxp4buHdToqKg0KLSAqKmEzIDwtIGEgJT4lIGdyb3VwX2J5KGNvbG9yLCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpOioqIFThuqFvIG3hu5l0IGLhu5kgZOG7ryBsaeG7h3UgbeG7m2kgYTMgYuG6sW5nIGPDoWNoIG5ow7NtIGThu68gbGnhu4d1IHRyb25nIGEgdGhlbyBjw6FjIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yIHbDoCBjbGFyaXR5LCBzYXUgxJHDsyB0w61uaCBz4buRIGzGsOG7o25nIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIHbDoCBsxrB1IHbDoG8gYmnhur9uIG4uDQoNCi0gKiphICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvciwgeSA9IG4pKToqKiBU4bqhbyBt4buZdCBraHVuZyBiaeG7g3UgxJHhu5MgbeG7m2ksIHRoaeG6v3QgbOG6rXAgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBiaeG6v24gY29sb3IgdHLDqm4gdHLhu6VjIHggdsOgIHPhu5EgbMaw4bujbmcgKG4pIHRyw6puIHRy4bulYyB5Lg0KDQotICoqZ2VvbV9jb2woZGF0YSA9IGEzICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnSTEnKSwgZmlsbCA9ICdibHVlJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGPhu5l0IHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLCB24bubaSBk4buvIGxp4buHdSDEkcaw4bujYyBs4bqleSB04burIGEzIHNhdSBraGkgbOG7jWMgcmEgbmjhu69uZyBkw7JuZyBjw7MgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY2xhcml0eSBsw6AgJ0kxJy4gQ8OhYyBj4buZdCBuw6B5IHPhur0gxJHGsOG7o2MgdMO0IG3DoHUgeGFuaCBsYW0uDQoNCi0gKipnZW9tX2NvbChkYXRhID0gYTMgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzInKSwgZmlsbCA9ICdyZWQnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgY+G7mXQgdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MsIHbhu5tpIGThu68gbGnhu4d1IMSRxrDhu6NjIGzhuqV5IHThu6sgYTMgc2F1IGtoaSBs4buNYyByYSBuaOG7r25nIGTDsm5nIGPDsyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5IGzDoCAnVlMyJy4gQ8OhYyBj4buZdCBuw6B5IHPhur0gxJHGsOG7o2MgdMO0IG3DoHUgxJHhu48uDQoNCiMjIMSQ4buTIFRo4buLIDI2OiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gR2nDoSBj4bunYSBjw6FjIHZpw6puIEtpbSBjxrDGoW5nDQoNCg0KDQpgYGAge3J9DQphICU+JSBnZ3Bsb3QoYWVzKHggPSBwcmljZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1MDAsIGZpbGwgPSAnZ3JlZW4nLCBjb2xvciA9ICdyZWQnKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaDoqKg0KLSAqKmEgJT4lIGdncGxvdChhZXMoeCA9IHByaWNlKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIHByaWNlIHRyw6puIHRy4bulYyB4Lg0KDQotICoqZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1MDAsIGZpbGwgPSAnZ3JlZW4nLCBjb2xvciA9ICdyZWQnKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgaGlzdG9ncmFtIHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBDw6FjIHRoYW5oIGhpc3RvZ3JhbSDEkcaw4bujYyB04bqhbyByYSB24bubaSBjaGnhu4F1IHLhu5luZyBj4bunYSBt4buXaSBiaeG6v24gbMOgIDUwMCAoxJHGoW4gduG7iyBnacOhKS4gTcOgdSBu4buBbiBj4bunYSBoaXN0b2dyYW0gxJHGsOG7o2MgdMO0IG3DoHUgeGFuaCBsw6EgY8OieSAoZmlsbCA9ICdncmVlbicpIHbDoCBtw6B1IHZp4buBbiBj4bunYSBoaXN0b2dyYW0gxJHGsOG7o2MgdMO0IG3DoHUgxJHhu48gKGNvbG9yID0gJ3JlZCcpLg0KDQoNCiMjIMSQ4buTIFRo4buLIDI3OiDEkOG7kyB0aOG7iyB0aOG7gyBoaeG7h24gxJHhu5kgc8OidSBj4bunYSB24bq/dCBj4bqvdCBj4bunYSBjw6FjIHZpw6puIGtpbSBjxrDGoW5nDQoNCmBgYCB7cn0NCmEgJT4lIGdncGxvdChhZXMoeCA9IGRlcHRoKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAndmlvbGV0JywgY29sb3IgPSAnYmxhY2snKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaDoqKg0KLSAqKmEgJT4lIGdncGxvdChhZXMoeCA9IGRlcHRoKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGRlcHRoIHRyw6puIHRy4bulYyB4Lg0KDQotICoqZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBmaWxsID0gJ3Zpb2xldCcsIGNvbG9yID0gJ2JsYWNrJyk6KiogVGjDqm0gbeG7mXQgbGF5ZXIgYmnhu4N1IMSR4buTIGhpc3RvZ3JhbSB2w6BvIGtodW5nIGJp4buDdSDEkeG7ky4gQ8OhYyB0aGFuaCBoaXN0b2dyYW0gxJHGsOG7o2MgdOG6oW8gcmEgduG7m2kgY2hp4buBdSBy4buZbmcgY+G7p2EgbeG7l2kgYmnhur9uIGzDoCAxIMSRxqFuIHbhu4suIE3DoHUgbuG7gW4gY+G7p2EgaGlzdG9ncmFtIMSRxrDhu6NjIHTDtCBtw6B1IHTDrW0gKGZpbGwgPSAndmlvbGV0JykgdsOgIG3DoHUgdmnhu4FuIGPhu6dhIGhpc3RvZ3JhbSDEkcaw4bujYyB0w7QgbcOgdSDEkWVuIChjb2xvciA9ICdibGFjaycpLg0KDQojIyDEkOG7kyBUaOG7iyAyODogxJDhu5MgVGjhu4sgdGjhu4MgaGnhu4duIGdpw6EgY+G7p2EgY8OhYyB2acOqbiBraW0gY8awxqFuZyBjw7MgcGjDom4gbG/huqFpIHRoZW8gbcOgdSBz4bqvYw0KDQpgYGB7cn0NCmEgJT4lIGdncGxvdChhZXMoeCA9IHByaWNlLCBmaWxsID0gY29sb3IpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMjAwMCkNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmg6KioNCi0gKiphICU+JSBnZ3Bsb3QoYWVzKHggPSBwcmljZSwgZmlsbCA9IGNvbG9yKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIHByaWNlIHRyw6puIHRy4bulYyB4IHbDoCBz4butIGThu6VuZyBiaeG6v24gY29sb3IgxJHhu4MgdOG6oW8gY8OhYyBuaMOzbSBtw6B1IHPhuq9jLg0KDQotICoqZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAyMDAwKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgaGlzdG9ncmFtIHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBDw6FjIHRoYW5oIGhpc3RvZ3JhbSDEkcaw4bujYyB04bqhbyByYSB24bubaSBjaGnhu4F1IHLhu5luZyBj4bunYSBt4buXaSBiaeG6v24gbMOgIDIwMDAgxJHGoW4gduG7iyBnacOhLiBDw6FjIG5ow7NtIG3DoHUgc+G6r2Mgc+G6vSBwaMOibiBiaeG7h3QgY8OhYyB0aGFuaCBoaXN0b2dyYW0gZOG7sWEgdHLDqm4gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY29sb3IuDQoNCg0KIyMgxJDhu5MgVGjhu4sgMjk6IHNvIHPDoW5oIHBow6JuIHBo4buRaSDEkeG7mSBzw6J1IGPhu6dhIGtpbSBjxrDGoW5nIGNobyB04burbmcgbcOgdSBz4bqvYyBraMOhYyBuaGF1Lg0KDQpgYGB7cn0NCmEgJT4lIGdncGxvdChhZXMoeCA9IGRlcHRoLCBmaWxsID0gY29sb3IpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMikNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmg6KioNCi0gKiphICU+JSBnZ3Bsb3QoYWVzKHggPSBkZXB0aCwgZmlsbCA9IGNvbG9yKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGRlcHRoIHRyw6puIHRy4bulYyB4IHbDoCBz4butIGThu6VuZyBiaeG6v24gY29sb3IgxJHhu4MgdOG6oW8gY8OhYyBuaMOzbSBtw6B1IHPhuq9jLg0KDQotICoqZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAyKToqKiBUaMOqbSBt4buZdCBsYXllciBiaeG7g3UgxJHhu5MgaGlzdG9ncmFtIHbDoG8ga2h1bmcgYmnhu4N1IMSR4buTLiBDw6FjIHRoYW5oIGhpc3RvZ3JhbSDEkcaw4bujYyB04bqhbyByYSB24bubaSBjaGnhu4F1IHLhu5luZyBj4bunYSBt4buXaSBiaeG6v24gbMOgIDIgxJHGoW4gduG7iyDEkeG7mSBzw6J1LiBDw6FjIG5ow7NtIG3DoHUgc+G6r2Mgc+G6vSBwaMOibiBiaeG7h3QgY8OhYyB0aGFuaCBoaXN0b2dyYW0gZOG7sWEgdHLDqm4gZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY29sb3IuDQoNCiMjIMSQ4buTIFRo4buLIDMwOiBwaMOibiBwaOG7kWkgY+G7p2EgZ2nDoSBraW0gY8awxqFuZyAoYmnhur9uICJwcmljZSIpIGThu7FhIHRyw6puIG3DoHUgc+G6r2MgY+G7p2EgY2jDum5nIChiaeG6v24gImNvbG9yIikuDQoNCmBgYHtyfQ0KYSAlPiUgZ2dwbG90KGFlcyh4ID0gcHJpY2UpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gNTAwLCBmaWxsID0gJ2JsYWNrJywgY29sb3IgPSAnd2hpdGUnKSArDQogIGZhY2V0X3dyYXAofmNvbG9yKQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaDoqKg0KLSAqKmEgJT4lIGdncGxvdChhZXMoeCA9IHByaWNlKSk6KiogVOG6oW8gbeG7mXQga2h1bmcgYmnhu4N1IMSR4buTIG3hu5tpLCB0aGnhur90IGzhuq1wIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIHByaWNlIHRyw6puIHRy4bulYyB4Lg0KDQotICoqZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1MDAsIGZpbGwgPSAnYmxhY2snLCBjb2xvciA9ICd3aGl0ZScpOioqIFRow6ptIG3hu5l0IGxheWVyIGJp4buDdSDEkeG7kyBoaXN0b2dyYW0gdsOgbyBraHVuZyBiaeG7g3UgxJHhu5MuIEPDoWMgdGhhbmggaGlzdG9ncmFtIMSRxrDhu6NjIHThuqFvIHJhIHbhu5tpIGNoaeG7gXUgcuG7mW5nIGPhu6dhIG3hu5dpIGJp4bq/biBsw6AgNTAwIMSRxqFuIHbhu4sgZ2nDoS4gTcOgdSBu4buBbiBj4bunYSBoaXN0b2dyYW0gxJHGsOG7o2MgdMO0IG3DoHUgxJFlbiAoZmlsbCA9ICdibGFjaycpIHbDoCBtw6B1IHZp4buBbiBj4bunYSBoaXN0b2dyYW0gxJHGsOG7o2MgdMO0IG3DoHUgdHLhuq9uZyAoY29sb3IgPSAnd2hpdGUnKS4NCg0KLSAqKmZhY2V0X3dyYXAofmNvbG9yKToqKiBU4bqhbyBjw6FjIGJp4buDdSDEkeG7kyBjb24gKGZhY2V0cykgZOG7sWEgdHLDqm4gYmnhur9uIGNvbG9yLCB04bupYyBsw6AgbeG7l2kgYmnhu4N1IMSR4buTIGNvbiBz4bq9IGhp4buDbiB0aOG7iyBk4buvIGxp4buHdSBjaG8gbeG7mXQgbeG7qWMgY+G7p2EgYmnhur9uIGNvbG9yLg==