GIỚI THIỆU
Bộ dữ liệu DIAMONS là bộ dữ liệu nằm trong packages tidyverse với hơn
50000 quan sát và 10 biến cho ta biết đầy đủ thông tin về các loại kim
cương Và dưới đây là các biểu đồ biểu diễn những thông tin của bộ dữ
liệu để dễ dàng thống kê và phân tích
library(ggplot2)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ lubridate 1.9.3 ✔ tibble 3.2.1
## ✔ purrr 1.0.2 ✔ tidyr 1.3.0
## ── 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
nth <- diamonds
I. Phân tích giá cả trung bình của một số loại kim
cương
1. Hình 1.1: Biểu đồ thể hiện mức giá trung bình của kim
cương có độ trong suốt VVS1 theo màu
Kim cương có độ trong suốt VVS1 khá ổn định với mức giá trung bình
giữa các màu chênh lệch nhau không quá lớn nhưng so mức giá trung bình
thấp nhất và cao nhất cũng còn khoảng cách khá xa (gần hai lần)
nth2 <- nth %>% group_by(color,clarity) %>% summarise(n = n(),meanP = mean(price),.groups = 'drop')
nth2 %>% ggplot(aes(x= color, y= meanP)) + geom_col(data = nth2 %>% filter(clarity == 'VVS1'), fill = 'purple')

2. Hình 1.2: Biểu đồ thể hiện mức giá trung bình của kim
cương có độ trong suốt SI1 theo màu
Kim cương có độ trong suốt SI1 với mức giá giữa các màu có sự chênh
lệch khá lớn , với màu I có mức giá trung bình cao nhất (hơn 5000) gần
gấp đôi mức giá trung bình của kim cương có độ trong suốt thấp nhất màu
D
nth2 %>% ggplot(aes(x= color, y= meanP)) + geom_col(data = nth2 %>% filter(clarity == 'SI1'), fill = 'yellow')

3. Hình 1.3: Biểu đồ thể hiện mức giá trung bình của kim
cương có độ trong suốt IF theo màu
Màu D có mức giá trung bình cao đột biến so với tất cả các màu còn
lại, cao hơn gấp từ hai đến ba lần
nth2 %>% ggplot(aes(x= color, y= meanP)) + geom_col(data = nth2 %>% filter(clarity == 'IF'), fill = 'darkcyan')

4. Hình 1.4: So sánh ba biểu đồ kim cương trên
Từ ba biểu đồ trên ta có thể thấy được mức giá trung bình của các
loại kim cương khác nhau, để tìm hiểu rõ hơn sự thay đổi trong giá cả
đối với các loại kim cương khác nhau ta so sánh ba biểu đồ trên: Cụ
thể
Kim cương có độ trong suốt VVS1 nhìn chung có mức giá trung bình
thấp hơn so với các loại khác nhưng khá ổn định giữa các màu
Kim cương có độ trong suốt IF màu D có mức giá cao nhất trong các
loại, cao hơn gấp hai đến ba lần so với các loại khác, nhưng cũng là kim
cương có độ trong suốt IF mà các màu khác thì mức giá trung bình lại
thấp nhất trong các loại
Kim cương có độ trong suốt SI1 là oại có mức giá cao và ổn định
giữa các màu.
nth3 <- nth %>% group_by(color,clarity) %>% summarise(meanP = mean(price), .groups = 'drop') %>% mutate(clarity= factor(clarity, levels = c("VVS1", "IF", "SI1")))
nth3 %>% ggplot(aes(x= color, y= meanP, fill= clarity)) + geom_col(position = position_dodge())

II. Khối lượng carat trung bình của kim cương theo các yếu
tố các nhau
1. Hình 2.1: Biểu đồ khối lượng carat trung bình theo chất
lượng chế tác
Khối lượng carat trung bình của mỗi viên kim cương được tổng hợp dưới
đây theo chất lượng chế tác của chúng, cụ thể: với chất lượng Fair khối
lượng carat trung bình mỗi viên là 1.05, chất lượng Good khối lượng
carat trung bình mỗi viên là 0.85, với chất lượng Very Good khối lượng
carat trung bình mỗi viên là0.81, với chất lượng Prenium khối lượng
carat trung bình mỗi viên là0.89, với chất lượng Ideal khối lượng carat
trung bình mỗi viên 0.7
nth %>% group_by(cut) %>% summarise(m= mean(carat)) %>%
ggplot(aes(x = cut,y = m)) +
geom_col(fill='black') +
geom_text(aes(label = round(m,2)), vjust = 2, color = 'green') +
labs(x = 'Loại', y = 'Mean')

2. Hình 2.2: Biểu đồ khối lượng carat trung bình theo màu
Mỗi loại màu của kim cương có khối lượng carat khác nhau tùy loại.
Qua biểu đồ dưới ta thấy khối lượng carat trung bình của viên kim cương
màu J lớn nhất 1.16 carat và màu có khối lượng carat bé nhất là màu D và
E: 0.66 carat
nth %>% group_by(color) %>% summarise(m= mean(carat)) %>%
ggplot(aes(x = color,y = m)) +
geom_col(fill='black') +
geom_text(aes(label = round(m,2)), vjust = 2, color = 'green') +
labs(x = 'Color', y = 'Mean')

3. Hình 2.3: Biểu đồ khối lượng carat trung bình theo độ
trong suốt
Độ trong suốt của kim cương được chia làm 8 loại khác nhau và theo độ
trong suốt mỗi loại có khối lượng carat trung bình được biểu diễn bằng
biểu đồ dưới đây cụ thể: khối lượng carat trung bình của kim cương có độ
trong suốt I1 cao nhất với 1.28, kim cương có độ trong suốt VVS1 thấp
nhất với khối lượng carat trung binh là 0.5
nth %>% group_by(clarity) %>% summarise(m= mean(carat)) %>%
ggplot(aes(x = clarity,y = m)) +
geom_col(fill='black') +
geom_text(aes(label = round(m,2)), vjust = 2, color = 'green') +
labs(x = 'Độ trong suốt', y = 'Mean')

III. Tổng hợp số lượng kim cương theo các biến khác
nhau
1. Hình 3.1: Biểu đồ thể hiện số lượng kim cương theo
màu
Qua biểu đồ dưới ta có thể tổng hợp được tất cả số lượng kim cương
theo các loại màu khác nhau trong đó: cột cao nhất là kim cương có màu G
tức màu G có số lượng kim cương nhiều nhất với hơn 10500 đv; cột thấp
nhất là kim cương có màu J tức màu J có số lượng ít nhất với gần 3000
đv.
nth %>% ggplot(aes(x = color)) +
geom_bar() +
labs(x = 'Loại ', y = 'Số lượng' )+
coord_flip()

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim
cương theo từng loại màu khác nhau nhưng với câu lệnh này ta có thể
thông tin chi tiết về từng số lương kim cương như sau: kim cương màu G
có số lượng nhiều nhất 11292 đv; kim cương màu J có số lượng ít nhất
2808.
nth %>% group_by(color) %>% summarise(n = n()) %>%
ggplot(aes(color,n)) +
geom_col(fill='orange') +
geom_text(aes(label = n),vjust = 2, color = 'black') +
labs(x = 'loại ', y = 'Số lượng')

2. Hình 3.2: Biểu đồ thể hiện số lượng kim cương theo chất
lượng chế tác
Qua biểu đồ dưới ta có thể tổng hợp được tất cả số lượng kim cương
theo chất lượng chế tác khác nhau cụ thể: số lượng kim cương tăng dần
theo mức độ chất lượng từ thấp đến cao, cột cao nhất với chất lượng
Ideal có hơn 20000 đv kim cương; cột thấp nhất với chất lượng Fair có
gần 2500 đv kim cương.
nth %>% ggplot(aes(x = cut)) +
geom_bar() +
labs(x = 'Loại', y = 'Số lượng')+
coord_flip()

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim
cương theo chất lương chế tác nhưng với câu lệnh này ta có thể thông tin
chi tiết về từng số lương kim cương như sau: kim cương có chất lượng
Fair, Good, Very Good, Prenium, Ideal có số lượng lần lượt là 1610,
4906, 12082, 13791, 21551.Với số lượng tỉ lệ thuận với chất lượng chế
tác của kim cương
nth %>% group_by(cut ) %>% summarise(n = n()) %>%
ggplot(aes(cut,n)) +
geom_col(fill='orange') +
geom_text(aes(label = n),vjust = 2, color = 'black') +
labs(x = 'loại ', y = 'Số lượng')

3. Hình 3.3: Biểu đồ thể hiện số lượng kim cương theo độ
trong suốt
Qua biểu đồ dưới đây ta tổng hợp được số lượng kim cương theo mức độ
trong suốt từng loại cụ thể: kim cương loại Sl1 có số lương cao nhất với
hơn 15000 đv, kim cương loại I1 thấp nhất với gần 1250 đv.
nth %>% ggplot(aes(x = clarity)) +
geom_bar() +
labs(x = 'Loại', y = 'Số lượng') +
coord_flip()

Cũng như loại biểu đồ trên biểu đồ dưới đây tổng hợp số lương kim
cương theo độ trong suốt nhưng với câu lệnh này ta có thể thông tin chi
tiết về từng số lương kim cương như sau: kim cương có độ trong suốt Sl1
có số lượng nhiều nhất 13065 đv và kim cương có độ trong suốt I1 có số
lượng ít nhất 741 đv.
nth %>% group_by(clarity ) %>% summarise(n = n()) %>%
ggplot(aes(clarity,n)) +
geom_col(fill='orange') +
geom_text(aes(label = n),vjust = 2, color = 'black') +
labs(x = 'Loại ', y = 'Số lượng')

IV. Phần trăm lượng kim cương theo các loại kim cương khác
nhau
1. Hình 4.1 Biểu đồ tỉ lệ phần trăm kim cương theo
màu
Biểu đồ dưới đây thể hiện tỉ lệ phần trăm số lượng kim cương theo màu
cụ thể: kim cương màu D chiếm 12.56%, kim cương màu E chiếm 18.16.%, kim
cương màu F chiếm 17.69%, kim cương màu G chiếm 20.93%, kim cương màu H
chiếm 15.39%, kim cương màu I chiếm 10.05%, kim cương màu J chiếm thấp
nhất 5.21%
nth %>% group_by(color) %>% summarise(n = n()) %>%
ggplot(aes(color,n)) +
geom_col(fill='dark blue') +
geom_text(aes(label = percent(n/length(nth$carat))),vjust = 2, color = 'white') +
labs(x = 'Loại', y = 'Số lượng')

2. Hình 4.2 Biểu đồ tỉ lệ phần trăm kim cương theo chất
lượng chế tác
Biểu đồ dưới đây thể hiện tỉ lệ phần trăm số lượng kim cương theo
chất lượng chế tác cụ thể: chiếm tỉ lệ cao nhất là số lương kim cương có
chất lượng chế tác Ideal với 40%, thấp nhất là tỉ lệ số lượng kim cương
có chất lượng chế tác fair 3%
nth %>% group_by(cut) %>% summarise(n = n()) %>%
ggplot(aes(cut,n)) +
geom_col(fill='dark blue') +
geom_text(aes(label = percent(n/length(nth$carat))),vjust = 2, color = 'white') +
labs(x = 'Loại', y = 'Số lượng')

3. Hình 4.3 Biểu đồ tỉ lệ phần trăm kim cương theo độ trong
suốt
Biểu đồ dưới đây thể hiện tỉ lệ phần trăm số lượng kim cương theo độ
trong suốt cụ thể: kim cương có độ trong suốt Sl1 cao nhất chiếm 24.2 %,
và kim cương có độ trong suốt thấp nhất chỉ chiếm 1.4%
nth %>% group_by(clarity) %>% summarise(n = n()) %>%
ggplot(aes(clarity,n)) +
geom_col(fill='dark blue') +
geom_text(aes(label = percent(n/length(nth$carat))),vjust = 2, color = 'white') +
labs(x = 'Loại', y = 'Số lượng')

V. So sánh số lượng giữa các loại kim cương ngẫu
nhiên
1. Hình 5.1: Biểu đồ so sánh số lượng kim cương theo chất
tác có màu D và J
Qua biểu đồ ta thấy có sự chênh lệch khá lớn giữa hai màu kim cương
,cột màu vàng là kim cương màu D có số lượng gấp đôi kim cương màu J là
cột màu đen theo từng laoij kim cương có độ chế tac khác nhau.
th <- nth %>% group_by(cut, color) %>% summarise(n = n(),.groups='drop')
th %>% ggplot(aes(x = cut, y = n)) +
geom_col(data = th %>% filter(color == 'D'), fill = 'yellow') +
geom_col(data = th %>% filter(color == 'J'), fill = 'black')

2. Hình 5.2: Biểu đồ so sánh số lượng kim cương theo chất
lượng chế tác có độ trong suốt VS2 và IF
Biểu đồ dưới đây thể hiện hai loại kim cương khác nhau: cột màu vàng
thể hiện kim cương có độ trong suốt VS2, cột màu đen thể hiện kim cương
có độ trong suốt IF được thống kê theo chất lương chế tác
Quan sát biểu đồ cho ta thấy rõ sự cách biệt lớn về số lượng của hai
loại kim cương trên: kim cương có độ trong suốt VS2 có số lương gấp 6
đến 8 lần so với số lượng kim cương có độ trong suốt IF => chứng tỏ
trên thị trường loại kim cương có độ trong suốt IF không đc phổ biến
chiếm thị phần nhỏ trên tổng số.
th1 <- nth %>% group_by(cut, clarity) %>% summarise(n = n(),.groups='drop')
th1 %>% ggplot(aes(x = cut, y = n)) +
geom_col(data = th1 %>% filter(clarity == 'VS2'), fill = 'yellow') +
geom_col(data = th1 %>% filter(clarity == 'IF'), fill = 'black')

3. Hình 5.3: Biểu đồ so sánh số lượng kim cương theo màu có
độ trong suốt VS1 và VS2
Theo các màu kim cương thống kê dưới đây cho thấy sự so sánh giữa hai
loại kim cương có độ trong suốt VS1 và VS2.
So với các loại kim cương so sánh trước thì hai loại này có sự chênh
lệch nhưng không cao . Giữa các màu khác nhau số lượng cũng khá đồng đều
cả hai loại VS1 và VS2.
th2 <- nth %>% group_by(clarity, color) %>% summarise(n = n(), .groups='drop')
th2 %>% ggplot(aes(x = color, y = n)) +
geom_col(data = th2 %>% filter(clarity == 'VS2'), fill = 'yellow') +
geom_col(data = th2 %>% filter(clarity == 'VS1'), fill = 'black')

VI. So sánh theo nhóm kim cương theo số lượng
1. Hình 6.1: Biểu đồ so sánh nhóm kim cương theo màu và chất
lượng chế tác
Bằng các câu lệnh dưới ta có nhóm biểu đồ thể hiện số lượng kim cương
theo từng loại chế tác khác nhau từ đó có thể dễ dàng quan sát so sánh
giữa các màu của loại chế tác này với màu của loại chế tác kia
nth %>% group_by(cut,color) %>% summarise(n=n(),.groups = 'drop') %>%
ggplot(aes(x = color,y = n)) +
geom_col(fill="pink") +
facet_wrap(~cut) +
labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so
sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label =
n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một
cách cụ thể.
nth %>% group_by(cut,color) %>% summarise(n=n(),.groups = 'drop') %>%
ggplot(aes(x = color,y = n)) +
geom_col( fill= 'brown') +
facet_wrap(~cut) +
geom_text(aes(label = n),vjust = 2, color = 'white') +
labs(x = 'Loại', y = 'Số lượng')

2. Hình 6.2: Biểu đồ so sánh nhóm kim cương theo độ trong
suốt và chất lượng chế tác
Bằng các câu lệnh dưới ta có nhóm biểu đồ thể hiện số lượng kim cương
theo từng loại chế tác khác nhau từ đó có thể dễ dàng quan sát so sánh
giữa các loại độ trong suốt kim cương của loại chế tác này với các loại
độ trong suốt của loại chế tác kia
nth %>% group_by(cut,clarity) %>% summarise(n=n(),.groups = 'drop') %>%
ggplot(aes(x = clarity,y = n)) +
geom_col(fill="pink") +
facet_wrap(~cut) +
labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so
sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label =
n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một
cách cụ thể.
nth %>% group_by(clarity,cut) %>% summarise(n=n(),.groups = 'drop') %>%
ggplot(aes(x = clarity,y = n)) +
geom_col( fill= 'brown') +
facet_wrap(~ cut) +
geom_text(aes(label = n),vjust = 2, color = 'white') +
labs(x = 'Loại', y = 'Số lượng')

3. Hình 6.3: Biểu đồ so sánh nhóm kim cương theo màu và độ
trong suốt
Bằng các câu lệnh dưới ta có nhóm biểu đồ thể hiện số lượng kim cương
theo từng loại trong suốt khác nhau từ đó có thể dễ dàng quan sát so
sánh giữa các màu của loại trong suốt này với màu của loại trong suốt
kia
nth %>% group_by(clarity,color) %>% summarise(n=n(),.groups = 'drop') %>%
ggplot(aes(x = color,y = n)) +
geom_col(fill="pink") +
facet_wrap(~clarity) +
labs(x = 'Loại', y = 'Số lượng')

Cũng như biểu đồ trên biểu đồ dưới đây cũng giúp ta quan sát và so
sánh những vần đề trên nhưng với câu lệnh geom_text(aes(label =
n),vjust = 2, color = ‘white’) ta có thể thấy rõ số liệu một
cách cụ thể.
nth %>% group_by(clarity,color) %>% summarise(n=n(),.groups = 'drop') %>%
ggplot(aes(x = color,y = n)) +
geom_col( fill= 'brown') +
facet_wrap(~clarity) +
geom_text(aes(label = n),vjust = 2, color = 'white') +
labs(x = 'Loại', y = 'Số lượng')

VII. So sánh nhóm kim cương theo mức giá trung
bình
1. Hình 7.1: biểu đồ so sánh nhóm kim cương (màu và chất
lượng chế tác)
Biểu đồ nhóm sau là thống kê mức giá trung bình của từng loại kim
cương chế tác theo tất cả các màu có đầy đủ số liệu trên từng biểu
đồ
nth %>% group_by(cut,color) %>% summarise(m = mean(price),.groups = 'drop') %>%
ggplot(aes(x = color,y = m)) +
geom_col(position = 'dodge') +
facet_wrap(~cut ) +
geom_text(aes(label = round(m))) +
labs(x = 'Color ', y = 'Số lượng')

2. Hình 7.2: biểu đồ so sánh nhóm kim cương (độ trong suốt
và chất lượng chế tác)
Biểu đồ nhóm sau là thống kê mức giá trung bình của từng loại kim
cương chế tác theo tất cả các độ trong suốt có đầy đủ số liệu trên từng
biểu đồ
nth %>% group_by(cut,clarity) %>% summarise(m = mean(price), .groups = 'drop') %>%
ggplot(aes(x = clarity,y = m)) +
geom_col(position = 'dodge') +
facet_wrap(~cut ) +
geom_text(aes(label = round(m))) +
labs(x = 'clarity ', y = 'Số lượng')

3. Hình 7.3: biểu đồ so sánh nhóm kim cương (màu và độ trong
suốt )
Biểu đồ nhóm sau là thống kê mức giá trung bình của từng loại kim
cương có độ trong suốt khác nhau theo tất cả các màu có đầy đủ số liệu
trên từng biểu đồ
nth %>% group_by(clarity,color) %>% summarise(m = mean(price), .groups='drop') %>%
ggplot(aes(x = color,y = m)) +
geom_col(position = 'dodge') +
facet_wrap(~clarity) +
geom_text(aes(label = round(m))) +
labs(x = 'Color ', y = 'Số lượng')

VIII. Phân tích số lượng kim cương theo mức giá và khối
lượng carat
1. Hình 8.1: BIểu đồ phân tích số lượng kim cương theo mức
giá
Biểu đồ sau giúp ta phân chia khối lượng carat của kim cương thành 5
loại khác nhau theo mức độ từ bé đến lớn đồng thời từ đó thống kê số
lượng theo nhóm cừa chia. Cụ thể: đối với các loại kim cương có khối
lượng carat nhỏ nhất lại chiếm thị phần lớn nhất trong tổng số kim cương
đặc biệt với hai loại là lớn và rất lớn lại không có trên thống kê.
Như vậy trên thị tường hiện nay thống kê số kim cương có khối lượng
carat nhỏ khá phổ biến nhưng loại khối lượng carat lớn lại rất hiếm và
hầu như không có.
nt <-nth %>% mutate(Carat = cut(carat,5, label = c('rất nhỏ', 'nhỏ','vừa','lớn','rất lớn')))
nt %>% ggplot(aes(x = Carat)) +
geom_bar(fill = 'purple')

2. Hình 8.2: BIểu đồ phân tích số lượng kim cương theo mức
giá
Với những câu lệnh sau ta có thể phân bổ mức gia thành 5 mức độ tăng
dần và mỗi mức độ dưới đây đều được thống kê lại với số lượng khác nhau.
Cụ thể: mức giá rất nhỏ chiếm phần lớn số lượng kim cương trên thị
trường còn với mức giá lớn và rất lớn số lượng kim cương hiếm chiếm tỉ
trọng rất nhỏ trên tổng số
nt1 <- nth %>% mutate(Price = cut(price,5, label = c('rất thấp ', 'thấp','tb','cao','rất cao')))
nt1 %>% ggplot(aes(x = Price)) +
geom_bar(fill = 'purple')

LS0tDQp0aXRsZTogIk5ISeG7hk0gVuG7pCA0Ig0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJUg6JU06JVMsICVkIC0gJW0gLSAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICBudW1iZXIgc2VjdGlvbjogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZSANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyMgKipHSeG7mkkgVEhJ4buGVSoqIA0KQuG7mSBk4buvIGxp4buHdSAgRElBTU9OUyBsw6AgYuG7mSBk4buvIGxp4buHdSBu4bqxbSB0cm9uZyBwYWNrYWdlcyB0aWR5dmVyc2UgduG7m2kgaMahbiA1MDAwMCBxdWFuIHPDoXQgdsOgIDEwIGJp4bq/biBjaG8gdGEgYmnhur90IMSR4bqneSDEkeG7pyB0aMO0bmcgdGluIHbhu4EgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcNClbDoCBkxrDhu5tpIMSRw6J5IGzDoCBjw6FjIGJp4buDdSDEkeG7kyBiaeG7g3UgZGnhu4VuIG5o4buvbmcgdGjDtG5nIHRpbiBj4bunYSBi4buZIGThu68gbGnhu4d1IMSR4buDIGThu4UgZMOgbmcgdGjhu5FuZyBrw6ogdsOgIHBow6JuIHTDrWNoIA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShzY2FsZXMpDQpudGggPC0gZGlhbW9uZHMNCmBgYA0KDQojIyAqKkkuIFBow6JuIHTDrWNoIGdpw6EgY+G6oyB0cnVuZyBiw6xuaCBj4bunYSBt4buZdCBz4buRIGxv4bqhaSBraW0gY8awxqFuZyoqDQoNCiMjIyAqKjEuIEjDrG5oIDEuMTogQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlZTMSB0aGVvIG3DoHUqKg0KDQpLaW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZWUzEga2jDoSDhu5VuIMSR4buLbmggduG7m2kgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBnaeG7r2EgY8OhYyBtw6B1IGNow6puaCBs4buHY2ggbmhhdSBraMO0bmcgcXXDoSBs4bubbiBuaMawbmcgc28gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCB0aOG6pXAgbmjhuqV0IHbDoCBjYW8gbmjhuqV0IGPFqW5nIGPDsm4ga2hv4bqjbmcgY8OhY2gga2jDoSB4YSAoZ+G6p24gaGFpIGzhuqduKQ0KDQpgYGB7cn0NCm50aDIgPC0gbnRoICU+JSBncm91cF9ieShjb2xvcixjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksbWVhblAgPSBtZWFuKHByaWNlKSwuZ3JvdXBzID0gJ2Ryb3AnKQ0KbnRoMiAlPiUgZ2dwbG90KGFlcyh4PSBjb2xvciwgeT0gbWVhblApKSArIGdlb21fY29sKGRhdGEgPSBudGgyICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnVlZTMScpLCBmaWxsID0gJ3B1cnBsZScpDQpgYGANCg0KIyMjICoqMi4gSMOsbmggMS4yOiBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBTSTEgdGhlbyBtw6B1KioNCg0KS2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBTSTEgduG7m2kgbeG7qWMgZ2nDoSBnaeG7r2EgY8OhYyBtw6B1IGPDsyBz4buxIGNow6puaCBs4buHY2gga2jDoSBs4bubbiAsIHbhu5tpIG3DoHUgSSBjw7MgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBjYW8gbmjhuqV0IChoxqFuIDUwMDApIGfhuqduIGfhuqVwIMSRw7RpIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCB0aOG6pXAgbmjhuqV0IG3DoHUgRCANCg0KYGBge3J9DQpudGgyICU+JSBnZ3Bsb3QoYWVzKHg9IGNvbG9yLCB5PSBtZWFuUCkpICsgZ2VvbV9jb2woZGF0YSA9IG50aDIgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdTSTEnKSwgZmlsbCA9ICd5ZWxsb3cnKQ0KYGBgDQoNCiMjIyAqKjMuIEjDrG5oIDEuMzogQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSUYgdGhlbyBtw6B1KioNCg0KTcOgdSBEIGPDsyBt4bupYyBnacOhIHRydW5nIGLDrG5oIGNhbyDEkeG7mXQgYmnhur9uIHNvIHbhu5tpIHThuqV0IGPhuqMgY8OhYyBtw6B1IGPDsm4gbOG6oWksIGNhbyBoxqFuIGfhuqVwIHThu6sgIGhhaSDEkeG6v24gYmEgbOG6p24gDQoNCmBgYHtyfQ0KbnRoMiAlPiUgZ2dwbG90KGFlcyh4PSBjb2xvciwgeT0gbWVhblApKSArIGdlb21fY29sKGRhdGEgPSBudGgyICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnSUYnKSwgZmlsbCA9ICdkYXJrY3lhbicpDQpgYGANCg0KIyMjICoqNC4gSMOsbmggMS40OiBTbyBzw6FuaCBiYSBiaeG7g3UgxJHhu5Mga2ltIGPGsMahbmcgdHLDqm4qKg0KDQpU4burIGJhIGJp4buDdSDEkeG7kyB0csOqbiB0YSBjw7MgdGjhu4MgdGjhuqV5IMSRxrDhu6NjIG3hu6ljIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2EgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcga2jDoWMgbmhhdSwgxJHhu4MgdMOsbSBoaeG7g3UgcsO1IGjGoW4gc+G7sSB0aGF5IMSR4buVaSB0cm9uZyBnacOhIGPhuqMgxJHhu5FpIHbhu5tpIGPDoWMgbG/huqFpIGtpbSBjxrDGoW5nIGtow6FjIG5oYXUgdGEgc28gc8OhbmggYmEgYmnhu4N1IMSR4buTIHRyw6puOiBD4bulIHRo4buDDQoNCiogS2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWVlMxIG5ow6xuIGNodW5nIGPDsyBt4bupYyBnacOhIHRydW5nIGLDrG5oIHRo4bqlcCBoxqFuIHNvIHbhu5tpIGPDoWMgbG/huqFpIGtow6FjIG5oxrBuZyBraMOhIOG7lW4gxJHhu4tuaCBnaeG7r2EgY8OhYyBtw6B1IA0KDQoqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSUYgbcOgdSBEIGPDsyBt4bupYyBnacOhIGNhbyBuaOG6pXQgdHJvbmcgY8OhYyBsb+G6oWksIGNhbyBoxqFuIGfhuqVwIGhhaSDEkeG6v24gYmEgbOG6p24gc28gduG7m2kgY8OhYyBsb+G6oWkga2jDoWMsIG5oxrBuZyBjxaluZyBsw6Aga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJRiBtw6AgY8OhYyBtw6B1IGtow6FjIHRow6wgbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBs4bqhaSB0aOG6pXAgbmjhuqV0IHRyb25nIGPDoWMgbG/huqFpDQoNCiAqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgU0kxIGzDoCBv4bqhaSBjw7MgbeG7qWMgZ2nDoSBjYW8gdsOgIOG7lW4gxJHhu4tuaCBnaeG7r2EgY8OhYyBtw6B1Lg0KDQoNCmBgYHtyfQ0KbnRoMyA8LSBudGggJT4lIGdyb3VwX2J5KGNvbG9yLGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobWVhblAgPSBtZWFuKHByaWNlKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIG11dGF0ZShjbGFyaXR5PSBmYWN0b3IoY2xhcml0eSwgbGV2ZWxzID0gYygiVlZTMSIsICJJRiIsICJTSTEiKSkpDQoNCm50aDMgJT4lIGdncGxvdChhZXMoeD0gY29sb3IsIHk9IG1lYW5QLCBmaWxsPSBjbGFyaXR5KSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpDQpgYGAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCg0KDQojIyAqKklJLiBLaOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjw6FjIHnhur91IHThu5EgY8OhYyBuaGF1KioNCg0KIyMjICoqMS4gSMOsbmggMi4xOiBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKiANCkto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBj4bunYSBt4buXaSB2acOqbiBraW0gY8awxqFuZyDEkcaw4bujYyB04buVbmcgaOG7o3AgZMaw4bubaSDEkcOieSB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGPhu6dhIGNow7puZywgY+G7pSB0aOG7gzogduG7m2kgY2jhuqV0IGzGsOG7o25nIEZhaXIga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIG3hu5dpIHZpw6puIGzDoCAxLjA1LCBjaOG6pXQgbMaw4bujbmcgR29vZCBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggbeG7l2kgdmnDqm4gbMOgIDAuODUsIHbhu5tpIGNo4bqldCBsxrDhu6NuZyBWZXJ5IEdvb2Qga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIG3hu5dpIHZpw6puIGzDoDAuODEsIHbhu5tpIGNo4bqldCBsxrDhu6NuZyBQcmVuaXVtIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCBt4buXaSB2acOqbiBsw6AwLjg5LCB24bubaSBjaOG6pXQgbMaw4bujbmcgSWRlYWwga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIG3hu5dpIHZpw6puICAwLjcNCg0KYGBge3J9DQpudGggJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChmaWxsPSdibGFjaycpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnZ3JlZW4nKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnTWVhbicpDQpgYGANCg0KIyMjICoqMi4gSMOsbmggMi4yOiBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gbcOgdSAqKiANCk3hu5dpIGxv4bqhaSBtw6B1IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQga2jDoWMgbmhhdSB0w7l5IGxv4bqhaS4gUXVhIGJp4buDdSDEkeG7kyBkxrDhu5tpIHRhIHRo4bqleSBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBKIGzhu5tuIG5o4bqldCAxLjE2IGNhcmF0IHbDoCBtw6B1IGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQgYsOpIG5o4bqldCBsw6AgbcOgdSBEIHbDoCBFOiAwLjY2IGNhcmF0ICANCg0KYGBge3J9DQpudGggJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nYmxhY2snKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2dyZWVuJykgKw0KICAgIGxhYnMoeCA9ICdDb2xvcicsIHkgPSAnTWVhbicpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggMi4zOiBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IHRydW5nIGLDrG5oIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0ICoqIA0KxJDhu5kgdHJvbmcgc3Xhu5F0IGPhu6dhIGtpbSBjxrDGoW5nIMSRxrDhu6NjIGNoaWEgbMOgbSA4IGxv4bqhaSBraMOhYyBuaGF1IHbDoCB0aGVvIMSR4buZIHRyb25nIHN14buRdCBt4buXaSBsb+G6oWkgY8OzIGto4buRaSBsxrDhu6NuZyBjYXJhdCB0cnVuZyBiw6xuaCDEkcaw4bujYyBiaeG7g3UgZGnhu4VuIGLhurFuZyBiaeG7g3UgxJHhu5MgZMaw4bubaSDEkcOieSBj4bulIHRo4buDOiBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJMSBjYW8gbmjhuqV0IHbhu5tpIDEuMjgsICBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZWUzEgdGjhuqVwIG5o4bqldCB24bubaSBraOG7kWkgbMaw4bujbmcgY2FyYXQgdHJ1bmcgYmluaCBsw6AgMC41IA0KDQpgYGB7cn0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSkgJT4lIHN1bW1hcmlzZShtPSBtZWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG0pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nYmxhY2snKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ2dyZWVuJykgKw0KICAgIGxhYnMoeCA9ICfEkOG7mSB0cm9uZyBzdeG7kXQnLCB5ID0gJ01lYW4nKQ0KYGBgDQoNCg0KIyMgKipJSUkuIFThu5VuZyBo4bujcCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY8OhYyBiaeG6v24gIGtow6FjIG5oYXUqKg0KDQojIyMgKioxLiBIw6xuaCAzLjE6IEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3DoHUqKg0KUXVhIGJp4buDdSDEkeG7kyBkxrDhu5tpIHRhIGPDsyB0aOG7gyB04buVbmcgaOG7o3AgxJHGsOG7o2MgdOG6pXQgY+G6oyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY8OhYyBsb+G6oWkgbcOgdSBraMOhYyBuaGF1IHRyb25nIMSRw7M6IGPhu5l0IGNhbyBuaOG6pXQgbMOgIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEcgdOG7qWMgbcOgdSBHIGPDsyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIG5oaeG7gXUgbmjhuqV0IHbhu5tpIGjGoW4gMTA1MDAgxJF2OyBj4buZdCB0aOG6pXAgbmjhuqV0IGzDoCBraW0gY8awxqFuZyBjw7MgbcOgdSBKIHThu6ljIG3DoHUgSiBjw7Mgc+G7kSBsxrDhu6NuZyDDrXQgbmjhuqV0IHbhu5tpIGfhuqduIDMwMDAgxJF2LiANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvcikpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpICcsIHkgPSAnU+G7kSBsxrDhu6NuZycgKSsNCiAgICBjb29yZF9mbGlwKCkNCmBgYCANCg0KQ8WpbmcgbmjGsCBsb+G6oWkgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IHThu5VuZyBo4bujcCBz4buRIGzGsMahbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIG3DoHUga2jDoWMgbmhhdSBuaMawbmcgduG7m2kgY8OidSBs4buHbmggbsOgeSB0YSBjw7MgdGjhu4MgdGjDtG5nIHRpbiBjaGkgdGnhur90IHbhu4EgdOG7q25nIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyBuaMawIHNhdToga2ltIGPGsMahbmcgbcOgdSBHIGPDsyBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0IDExMjkyIMSRdjsga2ltIGPGsMahbmcgbcOgdSBKIGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQgMjgwOC4gDQoNCmBgYHtyLCBlY2hvID0gVFJVRSB9DQpudGggJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGNvbG9yLG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nb3JhbmdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdsb+G6oWkgICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQoNCmBgYA0KDQojIyMgKioyLiBIw6xuaCAzLjI6IEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjKioNClF1YSBiaeG7g3UgxJHhu5MgZMaw4bubaSB0YSBjw7MgdGjhu4MgdOG7lW5nIGjhu6NwIMSRxrDhu6NjIHThuqV0IGPhuqMgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGtow6FjIG5oYXUgY+G7pSB0aOG7gzogc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0xINuZyBk4bqnbiB0aGVvIG3hu6ljIMSR4buZIGNo4bqldCBsxrDhu6NuZyAgdOG7qyB0aOG6pXAgxJHhur9uIGNhbywgY+G7mXQgY2FvIG5o4bqldCB24bubaSBjaOG6pXQgbMaw4bujbmcgSWRlYWwgY8OzIGjGoW4gIDIwMDAwIMSRdiBraW0gY8awxqFuZzsgY+G7mXQgdGjhuqVwIG5o4bqldCB24bubaSBjaOG6pXQgbMaw4bujbmcgRmFpciBjw7MgZ+G6p24gMjUwMCDEkXYga2ltIGPGsMahbmcuDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0KSkgKw0KICAgIGdlb21fYmFyKCkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKSsNCiAgICBjb29yZF9mbGlwKCkNCmBgYCANCg0KQ8WpbmcgbmjGsCBsb+G6oWkgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IHThu5VuZyBo4bujcCBz4buRIGzGsMahbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMawxqFuZyBjaOG6vyB0w6FjIG5oxrBuZyB24bubaSBjw6J1IGzhu4duaCBuw6B5IHRhIGPDsyB0aOG7gyB0aMO0bmcgdGluIGNoaSB0aeG6v3QgduG7gSB04burbmcgc+G7kSBsxrDGoW5nIGtpbSBjxrDGoW5nIG5oxrAgc2F1OiBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIEZhaXIsIEdvb2QsIFZlcnkgR29vZCwgUHJlbml1bSwgSWRlYWwgY8OzIHPhu5EgbMaw4bujbmcgbOG6p24gbMaw4bujdCBsw6AgMTYxMCwgNDkwNiwgMTIwODIsIDEzNzkxLCAyMTU1MS5W4bubaSBz4buRIGzGsOG7o25nIHThu4kgbOG7hyB0aHXhuq1uIHbhu5tpIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGPhu6dhIGtpbSBjxrDGoW5nICANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBncm91cF9ieShjdXQgKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J29yYW5nZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnbG/huqFpICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQojIyMgKiozLiBIw6xuaCAzLjM6IEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCoqDQpRdWEgYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGEgdOG7lW5nIGjhu6NwIMSRxrDhu6NjIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBt4bupYyDEkeG7mSB0cm9uZyBzdeG7kXQgdOG7q25nIGxv4bqhaSBj4bulIHRo4buDOiBraW0gY8awxqFuZyBsb+G6oWkgU2wxIGPDsyBz4buRIGzGsMahbmcgY2FvIG5o4bqldCB24bubaSBoxqFuIDE1MDAwIMSRdiwga2ltIGPGsMahbmcgbG/huqFpIEkxIHRo4bqlcCBuaOG6pXQgduG7m2kgZ+G6p24gMTI1MCDEkXYuDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykgKw0KICAgIGNvb3JkX2ZsaXAoKQ0KYGBgIA0KDQpDxaluZyBuaMawIGxv4bqhaSBiaeG7g3UgxJHhu5MgdHLDqm4gYmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdOG7lW5nIGjhu6NwIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCBuaMawbmcgduG7m2kgY8OidSBs4buHbmggbsOgeSB0YSBjw7MgdGjhu4MgdGjDtG5nIHRpbiBjaGkgdGnhur90IHbhu4EgdOG7q25nIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyBuaMawIHNhdToga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBTbDEgY8OzIHPhu5EgbMaw4bujbmcgbmhp4buBdSBuaOG6pXQgMTMwNjUgxJF2IHbDoCBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IEkxIGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQgNzQxIMSRdi4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBncm91cF9ieShjbGFyaXR5ICkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjbGFyaXR5LG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0nb3JhbmdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWkgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyAqKklWLiBQaOG6p24gdHLEg20gbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjw6FjIGxv4bqhaSBraW0gY8awxqFuZyBraMOhYyBuaGF1KioNCg0KIyMjICoqMS4gSMOsbmggNC4xIEJp4buDdSDEkeG7kyB04buJIGzhu4cgcGjhuqduIHRyxINtIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSoqIA0KQmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGjhu4MgaGnhu4duIHThu4kgbOG7hyBwaOG6p24gdHLEg20gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3DoHUgY+G7pSB0aOG7gzoga2ltIGPGsMahbmcgbcOgdSBEIGNoaeG6v20gMTIuNTYlLCBraW0gY8awxqFuZyBtw6B1IEUgY2hp4bq/bSAxOC4xNi4lLCBraW0gY8awxqFuZyBtw6B1IEYgY2hp4bq/bSAxNy42OSUsIGtpbSBjxrDGoW5nIG3DoHUgRyBjaGnhur9tIDIwLjkzJSwga2ltIGPGsMahbmcgbcOgdSBIIGNoaeG6v20gMTUuMzklLCAga2ltIGPGsMahbmcgbcOgdSBJIGNoaeG6v20gMTAuMDUlLCBraW0gY8awxqFuZyBtw6B1IEogY2hp4bq/bSB0aOG6pXAgbmjhuqV0IDUuMjElIA0KDQpgYGB7ciwgZWNobyA9IFRSVUV9IA0KbnRoICU+JSBncm91cF9ieShjb2xvcikgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjb2xvcixuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2RhcmsgYmx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aChudGgkY2FyYXQpKSksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA0LjIgQmnhu4N1IMSR4buTIHThu4kgbOG7hyBwaOG6p24gdHLEg20ga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYyoqIA0KQmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGjhu4MgaGnhu4duIHThu4kgbOG7hyBwaOG6p24gdHLEg20gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyBjaOG6vyB0w6FjIGPhu6UgdGjhu4M6IGNoaeG6v20gdOG7iSBs4buHIGNhbyBuaOG6pXQgbMOgIHPhu5EgbMawxqFuZyBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMgSWRlYWwgduG7m2kgNDAlLCB0aOG6pXAgbmjhuqV0IGzDoCB04buJIGzhu4cgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMgZmFpciAzJQ0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudGggJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdkYXJrIGJsdWUnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQobi9sZW5ndGgobnRoJGNhcmF0KSkpLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggNC4zIEJp4buDdSDEkeG7kyB04buJIGzhu4cgcGjhuqduIHRyxINtIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0KiogDQpCaeG7g3UgxJHhu5MgZMaw4bubaSDEkcOieSB0aOG7gyBoaeG7h24gdOG7iSBs4buHIHBo4bqnbiB0csSDbSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0IGPhu6UgdGjhu4M6IGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgU2wxIGNhbyBuaOG6pXQgY2hp4bq/bSAyNC4yICUsIHbDoCBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IHRo4bqlcCBuaOG6pXQgY2jhu4kgY2hp4bq/bSAxLjQlIA0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudGggJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY2xhcml0eSxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2RhcmsgYmx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChuL2xlbmd0aChudGgkY2FyYXQpKSksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyAqKlYuIFNvIHPDoW5oIHPhu5EgbMaw4bujbmcgZ2nhu69hIGPDoWMgbG/huqFpICBraW0gY8awxqFuZyBuZ+G6q3Ugbmhpw6puKioNCg0KIyMjICoqMS4gSMOsbmggNS4xOiBCaeG7g3UgxJHhu5Mgc28gc8Ohbmggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGNo4bqldCB0w6FjIGPDsyBtw6B1IEQgdsOgIEoqKg0KDQpRdWEgYmnhu4N1IMSR4buTIHRhIHRo4bqleSBjw7Mgc+G7sSBjaMOqbmggbOG7h2NoIGtow6EgbOG7m24gZ2nhu69hIGhhaSBtw6B1IGtpbSBjxrDGoW5nICxj4buZdCBtw6B1IHbDoG5nIGzDoCBraW0gY8awxqFuZyBtw6B1IEQgY8OzIHPhu5EgbMaw4bujbmcgZ+G6pXAgxJHDtGkga2ltIGPGsMahbmcgIG3DoHUgSiBsw6AgY+G7mXQgbcOgdSDEkWVuIHRoZW8gdOG7q25nIGxhb2lqIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSBjaOG6vyB0YWMga2jDoWMgbmhhdS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KdGggPC0gbnRoICU+JSBncm91cF9ieShjdXQsIGNvbG9yKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksLmdyb3Vwcz0nZHJvcCcpDQp0aCAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0LCB5ID0gbikpICsgDQogIGdlb21fY29sKGRhdGEgPSB0aCAlPiUgZmlsdGVyKGNvbG9yID09ICdEJyksIGZpbGwgPSAneWVsbG93JykgKw0KICBnZW9tX2NvbChkYXRhID0gdGggJT4lIGZpbHRlcihjb2xvciA9PSAnSicpLCBmaWxsID0gJ2JsYWNrJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA1LjI6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMgY8OzIMSR4buZIHRyb25nIHN14buRdCBWUzIgdsOgIElGKioNCg0KQmnhu4N1IMSR4buTIGTGsOG7m2kgxJHDonkgdGjhu4MgaGnhu4duIGhhaSBsb+G6oWkga2ltIGPGsMahbmcga2jDoWMgbmhhdTogY+G7mXQgbcOgdSB2w6BuZyB0aOG7gyBoaeG7h24ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWUzIsIGPhu5l0IG3DoHUgxJFlbiB0aOG7gyBoaeG7h24ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJRiDEkcaw4bujYyB0aOG7kW5nIGvDqiB0aGVvIGNo4bqldCBsxrDGoW5nIGNo4bq/IHTDoWMgDQoNClF1YW4gc8OhdCBiaeG7g3UgxJHhu5MgY2hvIHRhIHRo4bqleSByw7Ugc+G7sSBjw6FjaCBiaeG7h3QgbOG7m24gduG7gSBz4buRIGzGsOG7o25nIGPhu6dhIGhhaSBsb+G6oWkga2ltIGPGsMahbmcgdHLDqm46IGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgVlMyIGPDsyBz4buRIGzGsMahbmcgZ+G6pXAgNiDEkeG6v24gOCBs4bqnbiBzbyB24bubaSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQgSUYgPT4gY2jhu6luZyB04buPIHRyw6puIHRo4buLIHRyxrDhu51uZyBsb+G6oWkga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBJRiBraMO0bmcgxJFjIHBo4buVIGJp4bq/biBjaGnhur9tIHRo4buLIHBo4bqnbiBuaOG7jyB0csOqbiB04buVbmcgc+G7kS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KdGgxIDwtIG50aCAlPiUgZ3JvdXBfYnkoY3V0LCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksLmdyb3Vwcz0nZHJvcCcpDQp0aDEgJT4lIGdncGxvdChhZXMoeCA9IGN1dCwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSB0aDEgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzInKSwgZmlsbCA9ICd5ZWxsb3cnKSArDQogIGdlb21fY29sKGRhdGEgPSB0aDEgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdJRicpLCBmaWxsID0gJ2JsYWNrJykNCmBgYA0KDQojIyMgKiozLiBIw6xuaCA1LjM6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFZTMSB2w6AgVlMyKioNCg0KVGhlbyBjw6FjIG3DoHUga2ltIGPGsMahbmcgdGjhu5FuZyBrw6ogZMaw4bubaSDEkcOieSBjaG8gdGjhuqV5IHPhu7Egc28gc8OhbmggZ2nhu69hIGhhaSBsb+G6oWkga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIHN14buRdCBWUzEgdsOgIFZTMi4NCg0KU28gduG7m2kgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcgc28gc8OhbmggdHLGsOG7m2MgdGjDrCBoYWkgbG/huqFpIG7DoHkgY8OzIHPhu7EgY2jDqm5oIGzhu4djaCBuaMawbmcga2jDtG5nIGNhbyAuIEdp4buvYSBjw6FjIG3DoHUga2jDoWMgbmhhdSBz4buRIGzGsOG7o25nIGPFqW5nIGtow6EgxJHhu5NuZyDEkeG7gXUgY+G6oyBoYWkgbG/huqFpIFZTMSB2w6AgVlMyLiANCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KdGgyIDwtIG50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSwgLmdyb3Vwcz0nZHJvcCcpDQp0aDIgJT4lIGdncGxvdChhZXMoeCA9IGNvbG9yLCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHRoMiAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1ZTMicpLCBmaWxsID0gJ3llbGxvdycpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHRoMiAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1ZTMScpLCBmaWxsID0gJ2JsYWNrJykNCmBgYA0KDQojIyAqKlZJLiBTbyBzw6FuaCB0aGVvIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gc+G7kSBsxrDhu6NuZyoqDQoNCiMjIyAqKjEuIEjDrG5oIDYuMTogQmnhu4N1IMSR4buTIHNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSB2w6AgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKg0KDQpC4bqxbmcgY8OhYyBjw6J1IGzhu4duaCBkxrDhu5tpIHRhIGPDsyBuaMOzbSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIGNo4bq/IHTDoWMga2jDoWMgbmhhdSB04burIMSRw7MgY8OzIHRo4buDIGThu4UgZMOgbmcgcXVhbiBzw6F0IHNvIHPDoW5oIGdp4buvYSBjw6FjIG3DoHUgY+G7p2EgbG/huqFpIGNo4bq/IHTDoWMgbsOgeSB24bubaSBtw6B1IGPhu6dhIGxv4bqhaSBjaOG6vyB0w6FjIGtpYQ0KDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpLC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSJwaW5rIikgKw0KICAgIGZhY2V0X3dyYXAofmN1dCkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkPFqW5nIG5oxrAgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IGPFqW5nIGdpw7pwIHRhIHF1YW4gc8OhdCB2w6Agc28gc8Ohbmggbmjhu69uZyB24bqnbiDEkeG7gSB0csOqbiBuaMawbmcgduG7m2kgY8OidSBs4buHbmggKipnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpKiogdGEgY8OzIHRo4buDIHRo4bqleSByw7Ugc+G7kSBsaeG7h3UgbeG7mXQgY8OhY2ggY+G7pSB0aOG7gy4NCg0KYGBge3IsIGVjaG8gPSBUUlVFfQ0KbnRoICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKCBmaWxsPSAnYnJvd24nKSArDQogICAgZmFjZXRfd3JhcCh+Y3V0KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KDQojIyMgKioyLiBIw6xuaCA2LjI6IEJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCB2w6AgY2jhuqV0IGzGsOG7o25nIGNo4bq/IHTDoWMqKg0KDQpC4bqxbmcgY8OhYyBjw6J1IGzhu4duaCBkxrDhu5tpIHRhIGPDsyBuaMOzbSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIGNo4bq/IHTDoWMga2jDoWMgbmhhdSB04burIMSRw7MgY8OzIHRo4buDIGThu4UgZMOgbmcgcXVhbiBzw6F0IHNvIHPDoW5oIGdp4buvYSBjw6FjIGxv4bqhaSDEkeG7mSB0cm9uZyBzdeG7kXQga2ltIGPGsMahbmcgY+G7p2EgbG/huqFpIGNo4bq/IHTDoWMgbsOgeSB24bubaSBjw6FjIGxv4bqhaSDEkeG7mSB0cm9uZyBzdeG7kXQgY+G7p2EgbG/huqFpIGNo4bq/IHTDoWMga2lhDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNsYXJpdHkpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2woZmlsbD0icGluayIpICsNCiAgICBmYWNldF93cmFwKH5jdXQpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQpDxaluZyBuaMawIGJp4buDdSDEkeG7kyB0csOqbiBiaeG7g3UgxJHhu5MgZMaw4bubaSDEkcOieSBjxaluZyBnacO6cCB0YSBxdWFuIHPDoXQgdsOgIHNvIHPDoW5oIG5o4buvbmcgduG6p24gxJHhu4EgdHLDqm4gbmjGsG5nIHbhu5tpIGPDonUgbOG7h25oICoqZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSoqIHRhIGPDsyB0aOG7gyB0aOG6pXkgcsO1IHPhu5EgbGnhu4d1IG3hu5l0IGPDoWNoIGPhu6UgdGjhu4MuDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjdXQpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNsYXJpdHkseSA9IG4pKSArDQogICAgZ2VvbV9jb2woIGZpbGw9ICdicm93bicpICsNCiAgICBmYWNldF93cmFwKH4gY3V0KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggNi4zOiBCaeG7g3UgxJHhu5Mgc28gc8OhbmggbmjDs20ga2ltIGPGsMahbmcgdGhlbyBtw6B1IHbDoCDEkeG7mSB0cm9uZyBzdeG7kXQqKg0KDQpC4bqxbmcgY8OhYyBjw6J1IGzhu4duaCBkxrDhu5tpIHRhIGPDsyBuaMOzbSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyB04burbmcgbG/huqFpIHRyb25nIHN14buRdCBraMOhYyBuaGF1IHThu6sgxJHDsyBjw7MgdGjhu4MgZOG7hSBkw6BuZyBxdWFuIHPDoXQgc28gc8OhbmggZ2nhu69hIGPDoWMgbcOgdSBj4bunYSBsb+G6oWkgdHJvbmcgc3Xhu5F0IG7DoHkgduG7m2kgbcOgdSBj4bunYSBsb+G6oWkgdHJvbmcgc3Xhu5F0IGtpYQ0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudGggJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCksLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIGdncGxvdChhZXMoeCA9IGNvbG9yLHkgPSBuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9InBpbmsiKSArDQogICAgZmFjZXRfd3JhcCh+Y2xhcml0eSkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQoNCkPFqW5nIG5oxrAgYmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSDEkeG7kyBkxrDhu5tpIMSRw6J5IGPFqW5nIGdpw7pwIHRhIHF1YW4gc8OhdCB2w6Agc28gc8Ohbmggbmjhu69uZyB24bqnbiDEkeG7gSB0csOqbiBuaMawbmcgduG7m2kgY8OidSBs4buHbmggKipnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpKiogdGEgY8OzIHRo4buDIHRo4bqleSByw7Ugc+G7kSBsaeG7h3UgbeG7mXQgY8OhY2ggY+G7pSB0aOG7gy4gDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvcikgJT4lIHN1bW1hcmlzZShuPW4oKSwuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG4pKSArDQogICAgZ2VvbV9jb2woIGZpbGw9ICdicm93bicpICsNCiAgICBmYWNldF93cmFwKH5jbGFyaXR5KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMgKipWSUkuIFNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIHRoZW8gbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCoqDQoNCiMjIyAqKjEuIEjDrG5oIDcuMTogYmnhu4N1IMSR4buTIHNvIHPDoW5oIG5ow7NtIGtpbSBjxrDGoW5nIChtw6B1IHbDoCBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYykqKg0KDQpCaeG7g3UgxJHhu5MgbmjDs20gc2F1IGzDoCB0aOG7kW5nIGvDqiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIHThu6tuZyBsb+G6oWkga2ltIGPGsMahbmcgY2jhur8gdMOhYyB0aGVvIHThuqV0IGPhuqMgY8OhYyBtw6B1IGPDsyDEkeG6p3kgxJHhu6cgc+G7kSBsaeG7h3UgIHRyw6puIHThu6tuZyBiaeG7g3UgxJHhu5MgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSwuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y3V0ICkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtKSkpICsNCiAgICBsYWJzKHggPSAnQ29sb3IgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA3LjI6IGJp4buDdSDEkeG7kyBzbyBzw6FuaCBuaMOzbSBraW0gY8awxqFuZyAoxJHhu5kgdHJvbmcgc3Xhu5F0IHbDoCBjaOG6pXQgbMaw4bujbmcgY2jhur8gdMOhYykqKg0KDQpCaeG7g3UgxJHhu5MgbmjDs20gc2F1IGzDoCB0aOG7kW5nIGvDqiBt4bupYyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIHThu6tuZyBsb+G6oWkga2ltIGPGsMahbmcgY2jhur8gdMOhYyB0aGVvIHThuqV0IGPhuqMgY8OhYyDEkeG7mSB0cm9uZyBzdeG7kXQgIGPDsyDEkeG6p3kgxJHhu6cgc+G7kSBsaeG7h3UgIHRyw6puIHThu6tuZyBiaeG7g3UgxJHhu5MgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY3V0LGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobSA9IG1lYW4ocHJpY2UpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jdXQgKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0pKSkgKw0KICAgIGxhYnMoeCA9ICdjbGFyaXR5ICcsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCg0KIyMjICoqMy4gSMOsbmggNy4zOiBiaeG7g3UgxJHhu5Mgc28gc8OhbmggbmjDs20ga2ltIGPGsMahbmcgKG3DoHUgdsOgIMSR4buZIHRyb25nIHN14buRdCApKioNCg0KQmnhu4N1IMSR4buTIG5ow7NtIHNhdSBsw6AgdGjhu5FuZyBrw6ogbeG7qWMgZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSB04burbmcgbG/huqFpIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0cm9uZyBzdeG7kXQga2jDoWMgbmhhdSB0aGVvIHThuqV0IGPhuqMgY8OhYyBtw6B1IGPDsyDEkeG6p3kgxJHhu6cgc+G7kSBsaeG7h3UgIHRyw6puIHThu6tuZyBiaeG7g3UgxJHhu5MgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50aCAlPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvcikgJT4lIHN1bW1hcmlzZShtID0gbWVhbihwcmljZSksIC5ncm91cHM9J2Ryb3AnKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY29sb3IseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y2xhcml0eSkgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtKSkpICsNCiAgICBsYWJzKHggPSAnQ29sb3IgJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KDQojIyAqKlZJSUkuIFBow6JuIHTDrWNoIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyAgbeG7qWMgZ2nDoSB2w6Aga2jhu5FpIGzGsOG7o25nIGNhcmF0KioNCg0KIyMjICoqMS4gSMOsbmggOC4xOiBCSeG7g3UgxJHhu5MgcGjDom4gdMOtY2ggc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3hu6ljIGdpw6EqKg0KDQpCaeG7g3UgxJHhu5Mgc2F1IGdpw7pwIHRhIHBow6JuIGNoaWEga2jhu5FpIGzGsOG7o25nIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nIHRow6BuaCA1IGxv4bqhaSBraMOhYyBuaGF1IHRoZW8gbeG7qWMgxJHhu5kgdOG7qyBiw6kgxJHhur9uIGzhu5tuIMSR4buTbmcgdGjhu51pIHThu6sgxJHDsyB0aOG7kW5nIGvDqiBz4buRIGzGsOG7o25nIHRoZW8gbmjDs20gY+G7q2EgY2hpYS4gQ+G7pSB0aOG7gzogxJHhu5FpIHbhu5tpIGPDoWMgbG/huqFpIGtpbSBjxrDGoW5nIGPDsyBraOG7kWkgbMaw4bujbmcgY2FyYXQgbmjhu48gbmjhuqV0IGzhuqFpIGNoaeG6v20gdGjhu4sgcGjhuqduIGzhu5tuIG5o4bqldCB0cm9uZyB04buVbmcgc+G7kSBraW0gY8awxqFuZyDEkeG6t2MgYmnhu4d0IHbhu5tpIGhhaSBsb+G6oWkgbMOgIGzhu5tuIHbDoCBy4bqldCBs4bubbiBs4bqhaSBraMO0bmcgY8OzIHRyw6puIHRo4buRbmcga8OqLg0KDQpOaMawIHbhuq15IHRyw6puIHRo4buLIHTGsOG7nW5nIGhp4buHbiBuYXkgdGjhu5FuZyBrw6ogc+G7kSBraW0gY8awxqFuZyBjw7Mga2jhu5FpIGzGsOG7o25nIGNhcmF0IG5o4buPIGtow6EgcGjhu5UgYmnhur9uIG5oxrBuZyBsb+G6oWkga2jhu5FpIGzGsOG7o25nIGNhcmF0IGzhu5tuIGzhuqFpIHLhuqV0IGhp4bq/bSB2w6AgaOG6p3UgbmjGsCBraMO0bmcgY8OzLg0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQpudCA8LW50aCAlPiUgbXV0YXRlKENhcmF0ID0gY3V0KGNhcmF0LDUsIGxhYmVsID0gYygncuG6pXQgbmjhu48nLCAnbmjhu48nLCd24burYScsJ2zhu5tuJywncuG6pXQgbOG7m24nKSkpDQpudCAlPiUgZ2dwbG90KGFlcyh4ID0gQ2FyYXQpKSArDQogIGdlb21fYmFyKGZpbGwgPSAncHVycGxlJykNCmBgYA0KDQojIyMgKioyLiBIw6xuaCA4LjI6IEJJ4buDdSDEkeG7kyBwaMOibiB0w61jaCBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbeG7qWMgZ2nDoSoqDQoNClbhu5tpIG5o4buvbmcgY8OidSBs4buHbmggc2F1IHRhIGPDsyB0aOG7gyBwaMOibiBi4buVIG3hu6ljIGdpYSB0aMOgbmggNSBt4bupYyDEkeG7mSB0xINuZyBk4bqnbiB2w6AgbeG7l2kgbeG7qWMgxJHhu5kgZMaw4bubaSDEkcOieSDEkeG7gXUgxJHGsOG7o2MgdGjhu5FuZyBrw6ogbOG6oWkgduG7m2kgc+G7kSBsxrDhu6NuZyBraMOhYyBuaGF1LiBD4bulIHRo4buDOiBt4bupYyBnacOhIHLhuqV0IG5o4buPIGNoaeG6v20gcGjhuqduIGzhu5tuIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdHLDqm4gdGjhu4sgdHLGsOG7nW5nIGPDsm4gduG7m2kgbeG7qWMgZ2nDoSBs4bubbiB2w6AgcuG6pXQgbOG7m24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBoaeG6v20gY2hp4bq/bSB04buJIHRy4buNbmcgcuG6pXQgbmjhu48gdHLDqm4gdOG7lW5nIHPhu5EgDQoNCmBgYHtyLCBlY2hvID0gVFJVRX0NCm50MSA8LSBudGggJT4lIG11dGF0ZShQcmljZSA9IGN1dChwcmljZSw1LCBsYWJlbCA9IGMoJ3LhuqV0IHRo4bqlcCAnLCAndGjhuqVwJywndGInLCdjYW8nLCdy4bqldCBjYW8nKSkpDQpudDEgJT4lIGdncGxvdChhZXMoeCA9IFByaWNlKSkgKw0KICBnZW9tX2JhcihmaWxsID0gJ3B1cnBsZScpDQoNCmBgYA0KDQo=