Giới thiệu nội
dung
Ta sẽ dùng package “ggplot2” để trực quan hoá dữ liệu của bộ dataset
“diamonds”. Ta dùng barchart để biểu diễn các dữ liệu.
Package
“ggplot2”
Package này sẽ giúp ta tạo ra những biểu đồ có chất lượng cao và có
thể điều chỉnh theo ý của bản thân. Câu lệnh tạo ra biểu đồ trong
“ggplot2” có các thành phần cơ bản như sau:
- Hàm ggplot() để nhập dữ liệu và tạo khung cho biểu đồ
- Hàm aes() để ánh xạ các biến vào trong biểu đồ
- Để tạo ra được 1 biểu đồ thì ta cần các layer biểu diễn dữ liệu. Và
các layer có tên hàm bắt đầu bằng “geom_”.
Dữ liệu
diamond
Ta sẽ tạo bar chart từ bộ dữ liệu “diamonds”. Và sau đây là 1 số
thông tin về bộ dữ liệu “diamonds”.
Thông
tin
Cấu trúc của bộ dữ
liệu
library(tidyverse)
t <- diamonds
str(t)
## tibble [53,940 × 10] (S3: tbl_df/tbl/data.frame)
## $ carat : num [1:53940] 0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
## $ cut : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
## $ color : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
## $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
## $ depth : num [1:53940] 61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
## $ table : num [1:53940] 55 61 65 58 58 57 57 55 61 61 ...
## $ price : int [1:53940] 326 326 327 334 335 336 336 337 337 338 ...
## $ x : num [1:53940] 3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
## $ y : num [1:53940] 3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
## $ z : num [1:53940] 2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...
Giải thích kết
quả
tibble [53,940 × 10]: Dữ liệu có cấu trúc là dataframe. Bộ dữ
liệu có 53940 quan sát và 10 biến.
$ carat: Tên biến là “carat”. Đây biến về khối lượng của viên kim
cương với đơn vị carat.
$ cut: Tên biến là “cut”. Đây là biến thể hiện chất lượng của
viên kim cương sau khi cắt
$ color: Tên biến là “color”. Đây là biến thể hiện màu sắc của
viên kim cương
$ clarity: Tên biến là “clarity”. Đây là biến thể hiện độ trong
suố của viên kim cương
$ depth: Tên biến là “depth”. Đây là biến về chiều cao của viên
kim cương
$ table: Tên biến là “table”. Đây là biến về diện tích của mặt
phẳng trên đỉnh viên kim cương
$ price: Tên biến là “price”. Đây là biến về giá của viên kim
cương
$ x: Tên biến là “x”. Đây là biến về độ dài đường kính lớn nhất
của viên kim cương.
$ y: Tên biến là “y”. Đây là biến về độ dài đường kính nhỏ nhất
của viên kim cương
$ z: Tên biến là “z”. Đây là biến về độ sâu của viên kim
cương
Biểu
đồ
Biểu đồ tần số theo
biến cut
Biểu đồ
t %>%ggplot(aes(x= cut)) +
geom_bar() +
theme_bw() +
labs(x="Chất lượng",y="Số lượng",title = ("Biếu đồ số lượng kim cương theo chất lượng" ))

Giải thích
Nhìn vào biểu đồ ta thấy được cột “Ideal” có số lượng cao nhất và cột
“Fair” là cột có số lượng ít nhất. Số lượng chênh lệch của cột “Ideal”
và “Fair” chênh lệch lớn. Số lượng giữa cột “Very Good” và cột “Premium”
khá nhỏ.
Kết luận: Nếu chất lượng càng tăng thì số lượng các viên kim
cương tăng. Chứng tỏ kỹ thuật cắt của thợ đang rất tốt.
Biểu đồ tần số theo
biến color
Biểu đồ
t %>% ggplot(aes(x = color)) +
geom_bar() +
theme_bw() +
labs(x="Màu",y="Số lượng", title = "Biểu đồ số lượng kim cương theo màu sắc")

Giải thích
Ta thấy được cột màu “G” có số lượng nhiều nhất và cột màu “J” có số
lượng ít nhất. Chênh lệch số lượng giữa cột màu “G” và cột màu “J” khá
lớn. Cột màu “E”, cột màu “F” và cột màu “H” chênh lệch số lượng không
quá nhiều nhưng cột màu “H” lệch nhiều hơn so với 2 cột kia.
Kết luận: Có 4 màu phổ thông đó là “E”,“F”,“G”,“H” trong đó
màu phổ thông nhất là màu “G”. Màu hiếm nhất là màu “J”
Biểu đồ tần số theo
biến clarity
Biểu đồ
t %>% ggplot(aes(x = clarity)) +
geom_bar() +
theme_bw() +
labs(x="Màu",y="Số lượng", title = "Biểu đồ số lượng kim cương theo độ trong suốt")

Giải thích
Ta thấy cột “I2”(kim cương có lẫn nhiều tạp chất) có số lượng ít nhất
và cột “SI1”(kim cương lẫn ít tạp chất) có số lượng lớn nhất. Ta thấy
được cột “SI2” và cột “VS2” có số lượng chênh lệch nhau khá nhỏ. Cột
“SI2” và cột”VS1” chênh lệch cũng khá nhỏ.
Kết luận: Số lượng kim cương sẽ tăng lên từ kim cương có
nhiều tạp chất đến kim cương có ít tạp chất. Bắt đầu giảm dần đến kim
cương không có lẫn tạp chất nào.
Biểu đồ số lượng kim
cương theo chất lượng và màu sắc
Biểu đồ
t %>% group_by(cut,color) %>% summarise(n=n()) %>%
ggplot(aes(x=cut,y=n,fill = color))+
geom_col(position = "dodge") +
theme_bw()+
labs(x="Chất lượng",y="Số lượng",title = "Biểu đồ số lượng kim cương theo chất lượng và màu sắc")

Giải thích
Ta thấy được ở mọi chất lượng thì kim cương màu J luôn có số lượng ít
nhất. Ở chất lượng Fair thì các viên kim cương màu F,G,H có số lượng
tương đồng. Ở chất lượng Good thì màu E có số lượng nhiều nhất. Ở chất
lượng Very Good thì màu E có số lượng nhiều nhất. Ở chất lượng Premium
và Ideal thì màu G có số lượng cao nhất và vượt trội hơn so với các màu
khác.
Biểu đồ số lượng kim
cương theo độ trong suốt và màu sắc
Biểu đồ
t %>% group_by(clarity,color) %>% summarise(n=n()) %>%
ggplot(aes(x=clarity,y=n,fill=color))+
geom_col(position = "dodge")+
theme_bw()+
labs(x="Độ trong suốt",y="Số lượng",title = "Biểu đồ số lượng kim cương theo độ trong suốt và màu sắc")

Giải thích
Ta thấy được ở mỗi độ trong suốt của kim cương thì màu J luôn thấp
nhất. Với độ tinh khiết là SI2,SI1,VS2 thì màu E có số lượng nhiều nhất.
Với độ tinh khiết VS1, VVS1 và IF thì màu G có số lượng nhiều nhất và
vượt trội hơn so với các màu khác.
Biểu đồ về khối lượng
trung bình của kim cương theo chất lượng
Biểu đồ
t %>% 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="red"))+
theme_bw()+
labs(x="Chất lượng ",y="Khối lượng trung bình",title = "Biểu đồ khối lượng trung bình kim cương theo chất lượng")

Giải thích
Ta thấy được ở chất lượng Fair thì viên kim cương có khối lượng trung
bình cao nhất và nhỏ nhất là ở chất lượng Ideal. Ta thấy được khối lượng
trung bình ở chất lượng Good, Very Good, Premium chênh lệch nhau khá
nhỏ.
Kết luận: Ta thấy được những viên kim cương có chất lượng cắt
càng tốt thì khối lượng càng nhỏ.
Biểu đồ về giá trung
bình của kim cương theo chất lượng
Biểu đồ
t %>% group_by(cut) %>% summarise(m=mean(price)) %>%
ggplot(aes(x=cut,y=m))+
geom_col(position = "dodge",fill="green")+
theme_bw()+
geom_text(aes(label=round(m,2)),vjust=2,color="red")+
labs(x="Chất lượng",y="Giá trung bình",title = "Biểu đồ giá trung bình theo chất lượng")

Giải thích
Ta thấy được viên kim cương có chất lượng Premium có giá trung bình
cao nhất và nhỏ nhất là viên kim cương có chất lượng Ideal.Giá trung
bình ở chất lượng Good và Very Good có gần bằng với nhau.
Kết luận: Giá của viên kim cương không phụ thuộc nhiều vào
chất lượng cắt của viên kim cương. Như ta thấy viên kim cương ở chất
lượng Fair có giá lớn hơn viên kim cương ở chất lượng
Ideal.
Biểu đồ độ lệch chuẩn
của giá kim cương theo chất lượng
Biểu đồ
t %>% group_by(cut) %>% summarise(sd=sd(price)) %>%
ggplot(aes(x=cut,y=sd)) +
geom_col(position = "dodge")+
theme_bw()+
geom_text(aes(label=round(sd,2)),vjust=2,color="white")+
labs(x="Chất lượng",y="Độ biến động giá",title = "Biểu đồ độ biến động của giá theo chất lượng")

Giải thích
Ta thấy được độ biến động giá của viên kim cương có chất lượng
Premium là cao nhất và thấp nhất là Fair. Những viên kim cương có chất
lượng Fair và Good thì độ biến động giá gần bằng với nhau.
Kết luận: Khi chất lượng tăng thì độ biến độ giá cũng tăng
theo nhưng những viên kim cương có chất lượng Ideal thì ngoại
lệ.
Biểu đồ giá trung
bình của kim cương theo màu sắc
Biểu đồ
t %>% group_by(color) %>% summarise(m=mean(price)) %>%
ggplot(aes(x=color,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m)),vjust=2,color="white")+
labs(x="Màu sắc",y="Giá trung bình",title = "Biểu đồ giá trung bình của kim cương theo màu sắc")

Giải thích
Ta thấy được những viên kim cương có màu J thì có giá trung bình cao
nhất và thấp nhất là màu E.
Kết luận: Màu sắc của viên kim cương có ảnh hưởng mạnh tới
giá của kim cương ## Biểu dồ giá trung bình của kim cương theo
độ trong suốt
Biểu đồ
t %>% group_by(clarity) %>% summarise(m=mean(price)) %>%
ggplot(aes(x=clarity,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
labs(x="Độ trong suốt",y="Giá trung bình",title = "Biểu đồ giá trung bình theo độ trong suốt")

Giải thích
Viên kim cương có độ trong suốt SI2 có giá cao nhất và nhỏ nhất là
VVS1. Các viên kim cương có độ trong SI1,VS2,VS1 thì có giá gần bằng
nhau.
Kết luận: Độ trong suốt của kim cương có ảnh hưởng ít tới giá
của kim cương
Biểu đồ tần suất của
kim cương theo màu sắc
Biểu đồ
t %>% group_by(color) %>% summarise(n=n()) %>%
ggplot(aes(x=color,y=n)) +
geom_col(position = "dodge")+
theme_bw()+
geom_text(aes(label=scales::percent(n/length(t$carat))),vjust=2,color="white")+
labs(x="Chất lượng")

Giải thích
Ta thấy được những viên kim cương màu G có tỷ lệ xuất hiện trong tự
nhiên cao nhất và thấp nhất là viên kim cương có màu J. Ta thấy được tỷ
xuất hiện của màu E và F gần như nhau.
Kết luận: Vậy việc khai thác được viên kim cương có màu G khá
cao và khai thác được viên kim cương màu J khá thấp.
Biểu đồ giá trung
bình kim cương theo màu sắc và chất lượng
Biểu đồ
t %>% group_by(cut,color) %>% summarise(m=mean(price)) %>%
ggplot(aes(x=cut,y=m,fill=color)) +
geom_col(position = "dodge")+
theme_bw()+
labs(x="Chất lượng",y="Giá trung bình",title = "Biểu đồ giá trung bình theo màu sắc và chất lượng")

Giải thích
Ta thấy được những viên kim cương có chất lượng Fair, Good, Very Good
thì màu H có giá cao nhất và những viên kim cương có chất lượng Premium,
Ideal thì màu J có giá cao nhất.
Biểu đồ Số lượng
theo mức giá và theo màu sắc
Biểu đồ
t %>% mutate(pl=cut(price,3,labels = c("Vừa","Cao","Rất cao"))) %>%
group_by(pl,color) %>% summarise(n=n()) %>%
ggplot(aes(x=pl,y=n,fill=color))+
geom_col(position = "dodge")+
theme_bw()+
labs(x="Mức giá",y="Số lượng",title = "Biểu đồ số lượng theo mức giá và màu sắc")

Giải thích
Ở mọi mức giá thì màu G có số lượng nhiều nhất và màu J có số lượng
ít nhất.
Biểu đồ khối lượng
trung bình theo màu sắc
t %>% 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="white")+
labs(x="Màu sắc",y="Khối lượng trung bình")+
theme_bw()

Giải thích
Ta thấy được màu J là màu có khối lượng lớn nhất và màu D, E là màu
có khối lượng nhỏ nhất.
Kết luận: Nguyên nhân kim cương màu J có giá cao nhất là do
màu J có khối lượng nặng hơn những màu khác.
Biểu đồ khối lượng
trung bình theo mức giá
t %>% mutate(pl=cut(carat,3,labels = c("Vừa ","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(m=mean(carat)) %>%
ggplot(aes(x=pl,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
labs(x="Mức giá",y="Khối lượng trung bình",title = "Biểu đồ khối lượng trung bình theo mức giá")

Giải thích
Ta thấy được ở mức giá rất cao thì khối lượng của viên kim cương lớn
nhất và ở mức giá vừa thì viên kim cương có khối lượng nhỏ nhất.
Kết luận: Vậy giá của những viên kim cương sẽ phụ thuộc vào
khối lượng
Biểu đồ độ lệch
chuẩn của khối lượng theo màu sắc
Biểu đồ
t %>% group_by(color) %>% summarise(sd=sd(carat)) %>%
ggplot(aes(x=color,y=sd))+
geom_col(position = "dodge")+
geom_text(aes(label=round(sd,2)),vjust=2,color="white")+
labs(x="Màu sắc",y="Độ biến động khối lượng",title = "Biểu đồ độ biến động khối lượng theo màu sắc")+
theme_bw()

Giải thích
Ta thấy được biến động về khối lượng của những viên kim cương màu J
là lớn nhất, viên kim cương màu D thì có độ biến động về khối lượng nhỏ
nhất. Vì vậy những viên kim cương màu J có khối lượng nhiều hơn mọi màu
khác.
Biểu đồ độ lệch theo
mức giá
Biểu đồ
t %>% mutate(pl=cut(carat,3,labels = c("Vừa ","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(sd=sd(carat)) %>%
ggplot(aes(x=pl,y=sd))+
geom_col(position = "dodge")+
geom_text(aes(label=round(sd,2)),vjust=2,color="white")+
labs(x="Mức giá",y="Độ biến động khối lượng",title = "Biểu đồ biến động khối lượng theo mức giá")

##Giải thích Ta thấy được những viên kim cương có mức rất cao có độ
biến động lớn nhất và những viên kim cương có mức giá cao có độ biến
động nhỏ nhất.
Biểu đồ trung vị
khối lượng kim cương theo màu sắc
Biểu đồ
t %>% group_by(color) %>% summarise(me=median(carat)) %>%
ggplot(aes(x=color,y=me))+
geom_col(position = "dodge")+
geom_text(aes(label=round(me,2)),vjust=2,color="white")+
labs(x="Màu sắc",y="Giá trị trung vị",title = "Biểu đồ trung vị khối lượng theo màu sắc")+
theme_bw()

Giải thích
Những viên kim cương có màu J thì có giá trị trung vị lớn nhất và nhỏ
nhất là 2 màu D,E. Hai màu F,G có trung bị bằng với nhau.
Kết Luận: Có tới 50% viên kim cương màu J lớn hơn 1.11 carat
vì vậy giá của những viên kim cương màu J rất cao
Biểu đồ trung vị
khối lượng kim cương theo mức giá
Biểu đồ
t %>% mutate(pl=cut(carat,3,labels = c("Vừa ","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(me=median(carat)) %>%
ggplot(aes(x=pl,y=me))+
geom_col(position = "dodge")+
geom_text(aes(label=round(me,2)),vjust=2,color="white")+
labs(x="Mức giá",y="Giá trị trung vị",title = "Biểu đồ trung vị khối lượng kim cương theo mức giá")

Giải thích
Những viên kim cương có mức giá cao thì có giá trị trung vị cao nhất
và những viên kim cương có mức giá vừa thì có trung vị thấp nhất.
Kết luận: Ta biết được có tới 50% viên kim cương có mức giá
cao có khối lượng hơn 4 carat.
Biểu đồ trung vị của
giá theo màu sắc
Biểu đồ
t %>% group_by(color) %>% summarise(me=median(price)) %>%
ggplot(aes(x=color,y=me))+
geom_col(position = "dodge")+
geom_text(aes(label=round(me,2)),vjust=2,color="white")+
labs(x="Màu sắc",y="Giá trị trung vị",title = "Biểu đồ trung vị của giá theo màu sắc")+
theme_bw()

Giải thích
Những viên kim cương màu J có giá trị trung vị cao nhất và màu E có
giá trị trung vị thấp nhất.
Kết luận: Ta biết được có tới 50% viên kim cương màu J có giá
hơn 4234
Biểu đồ trung vị của
giá theo chất lượng và màu sắc
Biểu đồ
t %>% group_by(cut,color) %>% summarise(me=median(price)) %>%
ggplot(aes(x=cut,y=me,fill=color))+
geom_col(position = "dodge")+
labs(x="Màu sắc",y="Giá trị trung vị",title = "Biểu đồ trung vị của giá theo màu sắc")+
theme_bw()

Giải thích
Ta thấy được ở chất lượng Fair thì màu H có giá trị trung vị cao
nhất. Ở các chất lượng thì màu J có giá trị trung vị cao nhất.
Biểu đồ độ lệch
chuẩn của giá theo chất lượng mà màu sắc
Biểu đồ
t %>% group_by(cut,color) %>% summarise(sd=sd(price)) %>%
ggplot(aes(x=cut,y=sd,fill=color))+
geom_col(position = "dodge")+
labs(x="Màu sắc",y="Độ biến động về giá",title = "Biểu đồ độ biến động về giá theo chất lượng và màu sắc")+
theme_bw()

Giải thích
Ở chất lượng Fair thì viên kim cương có màu J có độ biến động cao
nhất. Ở các chất lượng khác thì màu I có độ biến động cao nhất.
Biểu độ độ lệch
chuẩn của giá theo độ trong suốt và màu sắc
t %>% group_by(clarity,color) %>% summarise(sd=sd(price)) %>%
ggplot(aes(x=clarity,y=sd,fill=color))+
geom_col(position = "dodge")+
labs(x="Độ trong suốt",y="Độ biến động về giá",title = "Biểu đồ độ biến động về giá theo độ trong suốt và màu sắc")+
theme_bw()

Giải thích
Ở độ trong suốt I1,VS1,VVS2,VVS! thì màu J có độ biến động giá cao
nhất. Ở độ trong suố SI2,SI1,VS2 thì màu I có độ biến động cao nhất. Ở
độ trong suốt IF thì màu D có độ biến động cao nhất
Biểu đồ chiều cao
trung bình của kim cương theo mức giá
t %>% mutate(pl=cut(carat,3,labels = c("Vừa ","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(m=mean(depth)) %>%
ggplot(aes(x=pl,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
labs(x="Mức giá",y="Chiều cao trung bình",title = "Biểu đồ chiều cao trung bình kim cương theo mức giá")+
theme_bw()

Giải thích
Ta thấy được ở các mức giá thì chiều cao trung bình gần như bằng
nhau.
Kết luận: Vậy chiều cao của viên kim cương sẽ không ảnh hưởng
về giá của kim cương ## Biểu đồ chiều cao trung bình của kim
cương theo chất lượng
Biểu đồ
t %>% group_by(cut) %>% summarise(m=mean(depth)) %>%
ggplot(aes(x=cut,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
labs(x="Chất lượng",y="Chiều cao trung bình",title = "Biểu đồ chiều cao trung bình của kim cương theo chất lượng")

Giải thích
Ta thấy được ở các chất lượng khác nhau nhưng chiều cao vẫn có giá
trị gần bằng với nhau
Kết luận: Vậy chiều cao của những viên kim cương không chênh
lệch nhau quá nhiều
Biểu đồ trung bình
đường kính lớn nhất theo mức giá
Biểu đồ
t %>% mutate(pl=cut(price,3,labels = c("Vừa","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(m=mean(x)) %>%
ggplot(aes(x=pl,y=m)) +
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
theme_bw()+
labs(x="Mức giá",y="Đường kính trung bình",title = "Biểu đồ đường kính lớn nhất trung bình theo mức giá")

Giải thích
Ta thấy được những viên kim cương ở mức giá rất cao có đường kính to
nhất và những viên kim cương ở mức giá vừa có đường kính nhỏ nhất.
Kết luận: Vậy đường kinh lớn nhất của viên kim cương có ảnh
hưởng tới giá của viên kim cương
Biểu đồ đường kính
nhỏ nhất theo mức giá
Biểu đồ
t %>% mutate(pl=cut(price,3,labels = c("Vừa","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(m=mean(y)) %>%
ggplot(aes(x=pl,y=m)) +
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
theme_bw()+
labs(x="Mức giá",y="Đường kính trung bình",title = "Biểu đồ đường kính nhỏ nhất trung bình theo mức giá")

Giải thích
Ta thấy được những viên kim cương ở mức giá rất cao có đường kính to
nhất và những viên kim cương ở mức giá vừa có đường kính nhỏ nhất.
Kết luận: Vậy đường kinh nhỏ nhất của viên kim cương có ảnh
hưởng tới giá của viên kim cương
Biểu đồ chiều sâu
trung bình theo mức giá
t %>% mutate(pl=cut(price,3,labels = c("Vừa","Cao","Rất cao"))) %>% group_by(pl) %>%
summarise(m=mean(z)) %>%
ggplot(aes(x=pl,y=m)) +
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
theme_bw()+
labs(x="Mức giá",y="Chiều sâu trung bình",title = "Biểu đồ chiều sâu trung bình theo mức giá")

###Giải thích Ta thấy được những viên kim cương ở mức giá rất cao thì
có chiều sâu cao nhất và những viên kim cương có mức giá vừa thì có
chiều sâu thấp nhất.
Kết luận: Vậy chiều sâu của viên kim cương có ảnh hưởng tới
giá của viên kim cương
Biểu đồ đường kính
lớn nhất trung bình theo chất lượng
Biểu đồ
t %>% group_by(cut) %>% summarise(m=mean(x)) %>%
ggplot(aes(x=cut,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
labs(x="Chất lượng",y="Đường kính trung bình",title = "Biểu đồ đường kính lớn nhất trung bình của kim cương theo chất lượng")

Giải thích
Ta thấy được ở mọi chất lượng thì đường kính của viên kim cương không
chênh lệch quá nhiều với nhau.
Kết luận: Vậy những viên kim cương chất lượng Fair thì có thể
có giá cao hơn những viên kim cương có chất lượng tốt hơn
khác
Biểu đồ đường kính
nhỏ nhất trung bình theo chất lượng
Biểu đồ
t %>% group_by(cut) %>% summarise(m=mean(y)) %>%
ggplot(aes(x=cut,y=m))+
geom_col(position = "dodge")+
geom_text(aes(label=round(m,2)),vjust=2,color="white")+
labs(x="Chất lượng",y="Đường kính trung bình",title = "Biểu đồ đường kính nhỏ nhất trung bình của kim cương theo chất lượng")

Giải thích
Ta thấy được đường kính của những viên kim cương ở những chất lượng
khác nhau thì không chênh lệch quá nhiều. Nhưng ta thấy rằng những viên
kim cương chất lượng Fair có đường kính lớn hơn những viên kim cương có
chất lượng Ideal. Điều này dẫn tới những viên kim cương chất lượng Fair
có giá cao hơn những viên kim cương chất lượng Ideal.
LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA0Ig0KYXV0aG9yOiAiTMO9IFbEqW5oIE5naGkiDQpkYXRlOiANCm91dHB1dDogDQogICAgDQogICAgaHRtbF9kb2N1bWVudDogDQogICAgICB0b2M6IHllcw0KICAgICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KLS0tDQpgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWANCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCiMgKipHaeG7m2kgdGhp4buHdSBu4buZaSBkdW5nKiogDQpUYSBz4bq9IGTDuW5nIHBhY2thZ2UgImdncGxvdDIiIMSR4buDIHRy4buxYyBxdWFuIGhvw6EgZOG7ryBsaeG7h3UgY+G7p2EgYuG7mSBkYXRhc2V0ICJkaWFtb25kcyIuIFRhIGTDuW5nIGJhcmNoYXJ0IMSR4buDIGJp4buDdSBkaeG7hW4gY8OhYyBk4buvIGxp4buHdS4NCg0KIyMgKipQYWNrYWdlICJnZ3Bsb3QyIioqIA0KUGFja2FnZSBuw6B5IHPhur0gZ2nDunAgdGEgdOG6oW8gcmEgbmjhu69uZyBiaeG7g3UgxJHhu5MgY8OzIGNo4bqldCBsxrDhu6NuZyBjYW8gdsOgIGPDsyB0aOG7gyDEkWnhu4F1IGNo4buJbmggdGhlbyDDvSBj4bunYSBi4bqjbiB0aMOibi4gQ8OidSBs4buHbmggdOG6oW8gcmEgYmnhu4N1IMSR4buTIHRyb25nICJnZ3Bsb3QyIiBjw7MgY8OhYyB0aMOgbmggcGjhuqduIGPGoSBi4bqjbiBuaMawIHNhdToNCg0KLSBIw6BtIGdncGxvdCgpIMSR4buDIG5o4bqtcCBk4buvIGxp4buHdSB2w6AgdOG6oW8ga2h1bmcgY2hvIGJp4buDdSDEkeG7kw0KLSBIw6BtIGFlcygpIMSR4buDIMOhbmggeOG6oSBjw6FjIGJp4bq/biB2w6BvIHRyb25nIGJp4buDdSDEkeG7kw0KLSDEkOG7gyB04bqhbyByYSDEkcaw4bujYyAxIGJp4buDdSDEkeG7kyB0aMOsIHRhIGPhuqduIGPDoWMgbGF5ZXIgYmnhu4N1IGRp4buFbiBk4buvIGxp4buHdS4gVsOgIGPDoWMgbGF5ZXINCmPDsyB0w6puIGjDoG0gYuG6r3QgxJHhuqd1IGLhurFuZyAiZ2VvbV8iLg0KDQojIyAqKkThu68gbGnhu4d1IGRpYW1vbmQqKg0KDQpUYSBz4bq9IHThuqFvIGJhciBjaGFydCB04burIGLhu5kgZOG7ryBsaeG7h3UgImRpYW1vbmRzIi4gVsOgIHNhdSDEkcOieSBsw6AgMSBz4buRIHRow7RuZyB0aW4gduG7gSBi4buZIA0KZOG7ryBsaeG7h3UgImRpYW1vbmRzIi4NCg0KIyMgVGjDtG5nIHRpbiAgey50YWJzZXR9DQoNCiMjIyBD4bqldSB0csO6YyBj4bunYSBi4buZIGThu68gbGnhu4d1IA0KDQpgYGB7cixtZXNzYWdlID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCnQgPC0gZGlhbW9uZHMNCnN0cih0KQ0KYGBgDQojIyMgR2nhuqNpIHRow61jaCBr4bq/dCBxdeG6ow0KDQotIHRpYmJsZSBbNTMsOTQwIMOXIDEwXTogROG7ryBsaeG7h3UgY8OzIGPhuqV1IHRyw7pjIGzDoCBkYXRhZnJhbWUuIELhu5kgZOG7ryBsaeG7h3UgY8OzIDUzOTQwIHF1YW4gDQpzw6F0IHbDoCAxMCBiaeG6v24uDQoNCg0KLSAkIGNhcmF0OiBUw6puIGJp4bq/biBsw6AgImNhcmF0Ii4gxJDDonkgYmnhur9uIHbhu4Ega2jhu5FpIGzGsOG7o25nIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIA0KduG7m2kgxJHGoW4gduG7iyBjYXJhdC4NCg0KDQotICQgY3V0OiBUw6puIGJp4bq/biBsw6AgImN1dCIuIMSQw6J5IGzDoCBiaeG6v24gdGjhu4MgaGnhu4duIGNo4bqldCBsxrDhu6NuZyBj4bunYSB2acOqbiBraW0gY8awxqFuZyANCnNhdSBraGkgY+G6r3QNCg0KDQotICQgY29sb3I6IFTDqm4gYmnhur9uIGzDoCAiY29sb3IiLiDEkMOieSBsw6AgYmnhur9uIHRo4buDIGhp4buHbiBtw6B1IHPhuq9jIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nDQoNCg0KLSAkIGNsYXJpdHk6IFTDqm4gYmnhur9uIGzDoCAiY2xhcml0eSIuIMSQw6J5IGzDoCBiaeG6v24gdGjhu4MgaGnhu4duIMSR4buZIHRyb25nIHN14buRIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nDQoNCg0KLSAkIGRlcHRoOiBUw6puIGJp4bq/biBsw6AgImRlcHRoIi4gxJDDonkgbMOgIGJp4bq/biB24buBIGNoaeG7gXUgY2FvIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nDQoNCg0KLSAkIHRhYmxlOiBUw6puIGJp4bq/biBsw6AgInRhYmxlIi4gxJDDonkgbMOgIGJp4bq/biB24buBIGRp4buHbiB0w61jaCBj4bunYSBt4bq3dCBwaOG6s25nIHRyw6puIMSR4buJbmggdmnDqm4ga2ltIGPGsMahbmcNCg0KDQotICQgcHJpY2U6IFTDqm4gYmnhur9uIGzDoCAicHJpY2UiLiDEkMOieSBsw6AgYmnhur9uIHbhu4EgZ2nDoSBj4bunYSB2acOqbiBraW0gY8awxqFuZw0KDQoNCi0gJCB4OiBUw6puIGJp4bq/biBsw6AgIngiLiDEkMOieSBsw6AgYmnhur9uIHbhu4EgxJHhu5kgZMOgaSDEkcaw4budbmcga8OtbmggbOG7m24gbmjhuqV0IGPhu6dhIHZpw6puIGtpbSANCmPGsMahbmcuDQoNCg0KLSAkIHk6IFTDqm4gYmnhur9uIGzDoCAieSIuIMSQw6J5IGzDoCBiaeG6v24gduG7gSDEkeG7mSBkw6BpIMSRxrDhu51uZyBrw61uaCBuaOG7jyBuaOG6pXQgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcNCg0KDQotICQgejogVMOqbiBiaeG6v24gbMOgICJ6Ii4gxJDDonkgbMOgIGJp4bq/biB24buBIMSR4buZIHPDonUgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcNCg0KDQoNCiMgKipCaeG7g3UgxJHhu5MqKg0KDQojIyBCaeG7g3UgxJHhu5MgdOG6p24gc+G7kSB0aGVvIGJp4bq/biBjdXQgDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyfQ0KdCAlPiVnZ3Bsb3QoYWVzKHg9IGN1dCkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICB0aGVtZV9idygpICsNCiAgICBsYWJzKHg9IkNo4bqldCBsxrDhu6NuZyIseT0iU+G7kSBsxrDhu6NuZyIsdGl0bGUgPSAoIkJp4bq/dSDEkeG7kyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIiApKQ0KICAgIA0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpOaMOsbiB2w6BvIGJp4buDdSDEkeG7kyB0YSB0aOG6pXkgxJHGsOG7o2MgY+G7mXQgIklkZWFsIiBjw7Mgc+G7kSBsxrDhu6NuZyBjYW8gbmjhuqV0IHbDoCBj4buZdCAiRmFpciIgbMOgIGPhu5l0IGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQuIFPhu5EgbMaw4bujbmcgY2jDqm5oIGzhu4djaCBj4bunYSBj4buZdCAiSWRlYWwiIHbDoCAiRmFpciIgY2jDqm5oIGzhu4djaCBs4bubbi4gU+G7kSBsxrDhu6NuZyBnaeG7r2EgY+G7mXQgIlZlcnkgR29vZCIgdsOgIGPhu5l0ICJQcmVtaXVtIiBraMOhIG5o4buPLiANCg0KKipL4bq/dCBsdeG6rW46IE7hur91IGNo4bqldCBsxrDhu6NuZyBjw6BuZyB0xINuZyB0aMOsIHPhu5EgbMaw4bujbmcgY8OhYyB2acOqbiBraW0gY8awxqFuZyB0xINuZy4gQ2jhu6luZyB04buPIGvhu7kgdGh14bqtdCBj4bqvdCBj4bunYSB0aOG7oyDEkWFuZyBy4bqldCB04buRdC4qKg0KDQoNCiMjIEJp4buDdSDEkeG7kyB04bqnbiBz4buRIHRoZW8gYmnhur9uIGNvbG9yIA0KDQojIyMgQmnhu4N1IMSR4buTIA0KYGBge3J9DQp0ICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvcikpICsNCiAgICBnZW9tX2JhcigpICsgDQogICAgdGhlbWVfYncoKSArIA0KICAgIGxhYnMoeD0iTcOgdSIseT0iU+G7kSBsxrDhu6NuZyIsIHRpdGxlID0gIkJp4buDdSDEkeG7kyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBz4bqvYyIpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyBj4buZdCBtw6B1ICJHIiBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCB2w6AgY+G7mXQgbcOgdSAiSiIgY8OzIHPhu5EgbMaw4bujbmcgw610IG5o4bqldC4gQ2jDqm5oIGzhu4djaCBz4buRIGzGsOG7o25nIGdp4buvYSBj4buZdCBtw6B1ICJHIiB2w6AgY+G7mXQgbcOgdSAiSiIga2jDoSBs4bubbi4gQ+G7mXQgbcOgdSAiRSIsIGPhu5l0IG3DoHUgIkYiIHbDoCBj4buZdCBtw6B1ICJIIiBjaMOqbmggbOG7h2NoIHPhu5EgbMaw4bujbmcga2jDtG5nIHF1w6Egbmhp4buBdSBuaMawbmcgY+G7mXQgbcOgdSAiSCIgbOG7h2NoIG5oaeG7gXUgaMahbiBzbyB24bubaSAyIGPhu5l0IGtpYS4gDQoNCioqS+G6v3QgbHXhuq1uOiBDw7MgNCBtw6B1IHBo4buVIHRow7RuZyDEkcOzIGzDoCAiRSIsIkYiLCJHIiwiSCIgdHJvbmcgxJHDsyBtw6B1IHBo4buVIHRow7RuZyBuaOG6pXQgbMOgIG3DoHUgIkciLiBNw6B1IGhp4bq/bSBuaOG6pXQgbMOgIG3DoHUgIkoiKioNCg0KIyMgQmnhu4N1IMSR4buTIHThuqduIHPhu5EgdGhlbyBiaeG6v24gY2xhcml0eSANCg0KIyMjIEJp4buDdSDEkeG7kyANCmBgYHtyfQ0KdCAlPiUgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSkpICsNCiAgICBnZW9tX2JhcigpICsgDQogICAgdGhlbWVfYncoKSArIA0KICAgIGxhYnMoeD0iTcOgdSIseT0iU+G7kSBsxrDhu6NuZyIsIHRpdGxlID0gIkJp4buDdSDEkeG7kyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0IikNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaCANClRhIHRo4bqleSBj4buZdCAiSTIiKGtpbSBjxrDGoW5nIGPDsyBs4bqrbiBuaGnhu4F1IHThuqFwIGNo4bqldCkgY8OzIHPhu5EgbMaw4bujbmcgw610IG5o4bqldCB2w6AgY+G7mXQgIlNJMSIoa2ltIGPGsMahbmcgbOG6q24gw610IHThuqFwIGNo4bqldCkgY8OzIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0LiBUYSB0aOG6pXkgxJHGsOG7o2MgY+G7mXQgIlNJMiIgdsOgIGPhu5l0ICJWUzIiIGPDsyBz4buRIGzGsOG7o25nIGNow6puaCBs4buHY2ggbmhhdSBraMOhIG5o4buPLiBD4buZdCAiU0kyIiB2w6AgY+G7mXQiVlMxIiBjaMOqbmggbOG7h2NoIGPFqW5nIGtow6Egbmjhu48uDQoNCioqS+G6v3QgbHXhuq1uOiBT4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHPhur0gdMSDbmcgbMOqbiB04burIGtpbSBjxrDGoW5nIGPDsyBuaGnhu4F1IHThuqFwIGNo4bqldCDEkeG6v24ga2ltIGPGsMahbmcgY8OzIMOtdCB04bqhcCBjaOG6pXQuIELhuq90IMSR4bqndSBnaeG6o20gZOG6p24gxJHhur9uIGtpbSBjxrDGoW5nIGtow7RuZyBjw7MgbOG6q24gdOG6oXAgY2jhuqV0IG7DoG8uKioNCg0KIyMgQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgdsOgIG3DoHUgc+G6r2MgDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyIG1lc3NhZ2U9Riwgd2FybmluZz1GfQ0KdCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4PWN1dCx5PW4sZmlsbCA9IGNvbG9yKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICAgdGhlbWVfYncoKSsNCiAgICBsYWJzKHg9IkNo4bqldCBsxrDhu6NuZyIseT0iU+G7kSBsxrDhu6NuZyIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgdsOgIG3DoHUgc+G6r2MiKQ0KYGBgDQoNCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyDhu58gbeG7jWkgY2jhuqV0IGzGsOG7o25nIHRow6wga2ltIGPGsMahbmcgbcOgdSBKIGx1w7RuIGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQuIOG7niBjaOG6pXQgbMaw4bujbmcgRmFpciB0aMOsIGPDoWMgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBGLEcsSCBjw7Mgc+G7kSBsxrDhu6NuZyB0xrDGoW5nIMSR4buTbmcuIOG7niBjaOG6pXQgbMaw4bujbmcgR29vZCB0aMOsIG3DoHUgRSBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldC4g4bueIGNo4bqldCBsxrDhu6NuZyBWZXJ5IEdvb2QgdGjDrCBtw6B1IEUgY8OzIHPhu5EgbMaw4bujbmcgbmhp4buBdSBuaOG6pXQuIOG7niBjaOG6pXQgbMaw4bujbmcgUHJlbWl1bSB2w6AgSWRlYWwgdGjDrCBtw6B1IEcgY8OzIHPhu5EgbMaw4bujbmcgY2FvIG5o4bqldCB2w6Agdsaw4bujdCB0cuG7mWkgaMahbiBzbyB24bubaSBjw6FjIG3DoHUga2jDoWMuDQogDQojIyBCaeG7g3UgxJHhu5Mgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCB2w6AgbcOgdSBz4bqvYyANCg0KIyMjIEJp4buDdSDEkeG7kw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnQgJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y2xhcml0eSx5PW4sZmlsbD1jb2xvcikpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgdGhlbWVfYncoKSsNCiAgICBsYWJzKHg9IsSQ4buZIHRyb25nIHN14buRdCIseT0iU+G7kSBsxrDhu6NuZyIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQgdsOgIG3DoHUgc+G6r2MiKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2Mg4bufIG3hu5dpIMSR4buZIHRyb25nIHN14buRdCBj4bunYSBraW0gY8awxqFuZyB0aMOsIG3DoHUgSiBsdcO0biB0aOG6pXAgbmjhuqV0LiBW4bubaSDEkeG7mSB0aW5oIGtoaeG6v3QgbMOgIFNJMixTSTEsVlMyIHRow6wgbcOgdSBFIGPDsyBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0LiBW4bubaSDEkeG7mSB0aW5oIGtoaeG6v3QgVlMxLCBWVlMxIHbDoCBJRiB0aMOsIG3DoHUgRyBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCB2w6Agdsaw4bujdCB0cuG7mWkgaMahbiBzbyB24bubaSBjw6FjIG3DoHUga2jDoWMuDQoNCiMjIEJp4buDdSDEkeG7kyB24buBIGto4buRaSBsxrDhu6NuZyB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZw0KDQojIyMgQmnhu4N1IMSR4buTDQoNCmBgYHtyfQ0KdCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09bWVhbihjYXJhdCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y3V0LHk9bSkpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtLDIpLHZqdXN0PTIsY29sb3I9InJlZCIpKSsNCiAgICB0aGVtZV9idygpKw0KICAgIGxhYnMoeD0iQ2jhuqV0IGzGsOG7o25nICIseT0iS2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIix0aXRsZSA9ICJCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIikNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0KVGEgdGjhuqV5IMSRxrDhu6NjIOG7nyBjaOG6pXQgbMaw4bujbmcgRmFpciB0aMOsIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBraOG7kWkgbMaw4bujbmcgdHJ1bmcgYsOsbmggY2FvIG5o4bqldCB2w6Agbmjhu48gbmjhuqV0IGzDoCDhu58gY2jhuqV0IGzGsOG7o25nIElkZWFsLiBUYSB0aOG6pXkgxJHGsOG7o2Mga2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIOG7nyBjaOG6pXQgbMaw4bujbmcgR29vZCwgVmVyeSBHb29kLCBQcmVtaXVtIGNow6puaCBs4buHY2ggbmhhdSBraMOhIG5o4buPLg0KDQoqKkvhur90IGx14bqtbjogVGEgdGjhuqV5IMSRxrDhu6NjIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBjw6BuZyB04buRdCB0aMOsIGto4buRaSBsxrDhu6NuZyBjw6BuZyBuaOG7jy4qKg0KDQojIyBCaeG7g3UgxJHhu5MgduG7gSBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyfQ0KdCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09bWVhbihwcmljZSkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y3V0LHk9bSkpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIixmaWxsPSJncmVlbiIpKw0KICAgIHRoZW1lX2J3KCkrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtLDIpKSx2anVzdD0yLGNvbG9yPSJyZWQiKSsNCiAgICBsYWJzKHg9IkNo4bqldCBsxrDhu6NuZyIseT0iR2nDoSB0cnVuZyBiw6xuaCIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIGdpw6EgdHJ1bmcgYsOsbmggdGhlbyBjaOG6pXQgbMaw4bujbmciKQ0KICAgIA0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2MgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBQcmVtaXVtIGPDsyBnacOhIHRydW5nIGLDrG5oIGNhbyBuaOG6pXQgdsOgIG5o4buPIG5o4bqldCBsw6AgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBJZGVhbC5HacOhIHRydW5nIGLDrG5oIOG7nyBjaOG6pXQgbMaw4bujbmcgR29vZCB2w6AgVmVyeSBHb29kIGPDsyBn4bqnbiBi4bqxbmcgduG7m2kgbmhhdS4NCg0KKipL4bq/dCBsdeG6rW46IEdpw6EgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcga2jDtG5nIHBo4bulIHRodeG7mWMgbmhp4buBdSB2w6BvIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBj4bunYSB2acOqbiBraW0gY8awxqFuZy4gTmjGsCB0YSB0aOG6pXkgdmnDqm4ga2ltIGPGsMahbmcg4bufIGNo4bqldCBsxrDhu6NuZyBGYWlyIGPDsyBnacOhIGzhu5tuIGjGoW4gdmnDqm4ga2ltIGPGsMahbmcg4bufIGNo4bqldCBsxrDhu6NuZyBJZGVhbC4qKg0KDQojIyBCaeG7g3UgxJHhu5MgxJHhu5kgbOG7h2NoIGNodeG6qW4gY+G7p2EgZ2nDoSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZw0KDQojIyMgQmnhu4N1IMSR4buTDQpgYGB7cn0NCnQgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShzZD1zZChwcmljZSkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y3V0LHk9c2QpKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICB0aGVtZV9idygpKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9cm91bmQoc2QsMikpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJDaOG6pXQgbMaw4bujbmciLHk9IsSQ4buZIGJp4bq/biDEkeG7mW5nIGdpw6EiLHRpdGxlID0gIkJp4buDdSDEkeG7kyDEkeG7mSBiaeG6v24gxJHhu5luZyBj4bunYSBnacOhIHRoZW8gY2jhuqV0IGzGsOG7o25nIikNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0KVGEgdGjhuqV5IMSRxrDhu6NjIMSR4buZIGJp4bq/biDEkeG7mW5nIGdpw6EgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBQcmVtaXVtIGzDoCBjYW8gbmjhuqV0IHbDoCB0aOG6pXAgbmjhuqV0IGzDoCBGYWlyLiBOaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgRmFpciB2w6AgR29vZCB0aMOsIMSR4buZIGJp4bq/biDEkeG7mW5nIGdpw6EgZ+G6p24gYuG6sW5nIHbhu5tpIG5oYXUuDQoNCioqS+G6v3QgbHXhuq1uOiBLaGkgY2jhuqV0IGzGsOG7o25nIHTEg25nIHRow6wgxJHhu5kgYmnhur9uIMSR4buZIGdpw6EgY8WpbmcgdMSDbmcgdGhlbyBuaMawbmcgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIElkZWFsIHRow6wgbmdv4bqhaSBs4buHLioqDQoNCiMjIEJp4buDdSDEkeG7kyBnacOhIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBz4bqvYw0KDQojIyMgQmnhu4N1IMSR4buTDQpgYGB7cn0NCnQgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG09bWVhbihwcmljZSkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y29sb3IseT1tKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKG0pKSx2anVzdD0yLGNvbG9yPSJ3aGl0ZSIpKw0KICAgIGxhYnMoeD0iTcOgdSBz4bqvYyIseT0iR2nDoSB0cnVuZyBiw6xuaCIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBtw6B1IHPhuq9jIikNCg0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2Mgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgbcOgdSBKIHRow6wgY8OzIGdpw6EgdHJ1bmcgYsOsbmggY2FvIG5o4bqldCB2w6AgdGjhuqVwIG5o4bqldCBsw6AgbcOgdSBFLg0KDQoqKkvhur90IGx14bqtbjogTcOgdSBz4bqvYyBj4bunYSB2acOqbiBraW0gY8awxqFuZyBjw7Mg4bqjbmggaMaw4bufbmcgbeG6oW5oIHThu5tpIGdpw6EgY+G7p2Ega2ltIGPGsMahbmcgKioNCiMjIEJp4buDdSBk4buTIGdpw6EgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQNCg0KIyMjIEJp4buDdSDEkeG7kw0KYGBge3J9DQp0ICU+JSBncm91cF9ieShjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG09bWVhbihwcmljZSkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y2xhcml0eSx5PW0pKSsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9cm91bmQobSwyKSksdmp1c3Q9Mixjb2xvcj0id2hpdGUiKSsNCiAgICBsYWJzKHg9IsSQ4buZIHRyb25nIHN14buRdCIseT0iR2nDoSB0cnVuZyBiw6xuaCIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIGdpw6EgdHJ1bmcgYsOsbmggdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQiKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpWacOqbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgdHJvbmcgc3Xhu5F0IFNJMiBjw7MgZ2nDoSBjYW8gbmjhuqV0IHbDoCBuaOG7jyBuaOG6pXQgbMOgIFZWUzEuIEPDoWMgdmnDqm4ga2ltIGPGsMahbmcgY8OzIMSR4buZIHRyb25nIFNJMSxWUzIsVlMxIHRow6wgY8OzIGdpw6EgZ+G6p24gYuG6sW5nIG5oYXUuDQoNCioqS+G6v3QgbHXhuq1uOiDEkOG7mSB0cm9uZyBzdeG7kXQgY+G7p2Ega2ltIGPGsMahbmcgY8OzIOG6o25oIGjGsOG7n25nIMOtdCB04bubaSBnacOhIGPhu6dhIGtpbSBjxrDGoW5nKioNCg0KIyMgQmnhu4N1IMSR4buTIHThuqduIHN14bqldCBj4bunYSBraW0gY8awxqFuZyB0aGVvIG3DoHUgc+G6r2MgDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyfQ0KdCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y29sb3IseT1uKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgdGhlbWVfYncoKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXNjYWxlczo6cGVyY2VudChuL2xlbmd0aCh0JGNhcmF0KSkpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJDaOG6pXQgbMaw4bujbmciKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2Mgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBtw6B1IEcgY8OzIHThu7cgbOG7hyB4deG6pXQgaGnhu4duIHRyb25nIHThu7Egbmhpw6puIGNhbyBuaOG6pXQgdsOgIHRo4bqlcCBuaOG6pXQgbMOgIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEouIFRhIHRo4bqleSDEkcaw4bujYyB04bu3IHh14bqldCBoaeG7h24gY+G7p2EgbcOgdSBFIHbDoCBGIGfhuqduIG5oxrAgbmhhdS4NCg0KKipL4bq/dCBsdeG6rW46IFbhuq15IHZp4buHYyBraGFpIHRow6FjIMSRxrDhu6NjIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEcga2jDoSBjYW8gdsOgIGtoYWkgdGjDoWMgxJHGsOG7o2MgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBKIGtow6EgdGjhuqVwLioqDQoNCiMjIEJp4buDdSDEkeG7kyBnacOhIHRydW5nIGLDrG5oIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBz4bqvYyB2w6AgY2jhuqV0IGzGsOG7o25nDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQp0ICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2UobT1tZWFuKHByaWNlKSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1jdXQseT1tLGZpbGw9Y29sb3IpKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICB0aGVtZV9idygpKw0KICAgIGxhYnMoeD0iQ2jhuqV0IGzGsOG7o25nIix5PSJHacOhIHRydW5nIGLDrG5oIix0aXRsZSA9ICJCaeG7g3UgxJHhu5MgZ2nDoSB0cnVuZyBiw6xuaCB0aGVvIG3DoHUgc+G6r2MgdsOgIGNo4bqldCBsxrDhu6NuZyIpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgRmFpciwgR29vZCwgVmVyeSBHb29kIHRow6wgbcOgdSBIIGPDsyBnacOhIGNhbyBuaOG6pXQgdsOgIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBQcmVtaXVtLCBJZGVhbCB0aMOsIG3DoHUgSiBjw7MgZ2nDoSBjYW8gbmjhuqV0Lg0KDQoNCiMjIEJp4buDdSDEkeG7kyBT4buRIGzGsOG7o25nIHRoZW8gbeG7qWMgZ2nDoSB2w6AgdGhlbyBtw6B1IHPhuq9jDQoNCiMjIyBCaeG7g3UgxJHhu5MgDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdCAlPiUgbXV0YXRlKHBsPWN1dChwcmljZSwzLGxhYmVscyA9IGMoIlbhu6thIiwiQ2FvIiwiUuG6pXQgY2FvIikpKSAlPiUgDQogICAgZ3JvdXBfYnkocGwsY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9cGwseT1uLGZpbGw9Y29sb3IpKSsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICAgIHRoZW1lX2J3KCkrDQogICAgbGFicyh4PSJN4bupYyBnacOhIix5PSJT4buRIGzGsOG7o25nIix0aXRsZSA9ICJCaeG7g3UgxJHhu5Mgc+G7kSBsxrDhu6NuZyB0aGVvIG3hu6ljIGdpw6EgdsOgIG3DoHUgc+G6r2MiKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQrhu54gbeG7jWkgbeG7qWMgZ2nDoSB0aMOsIG3DoHUgRyBjw7Mgc+G7kSBsxrDhu6NuZyBuaGnhu4F1IG5o4bqldCB2w6AgbcOgdSBKIGPDsyBz4buRIGzGsOG7o25nIMOtdCBuaOG6pXQuDQoNCiMjIEJp4buDdSDEkeG7kyBraOG7kWkgbMaw4bujbmcgdHJ1bmcgYsOsbmggdGhlbyBtw6B1IHPhuq9jDQpgYGB7cn0NCnQgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG09bWVhbihjYXJhdCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y29sb3IseT1tKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKG0sMikpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJNw6B1IHPhuq9jIix5PSJLaOG7kWkgbMaw4bujbmcgdHJ1bmcgYsOsbmgiKSsNCiAgICB0aGVtZV9idygpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyBtw6B1IEogbMOgIG3DoHUgY8OzIGto4buRaSBsxrDhu6NuZyBs4bubbiBuaOG6pXQgdsOgIG3DoHUgRCwgRSBsw6AgbcOgdSBjw7Mga2jhu5FpIGzGsOG7o25nIG5o4buPIG5o4bqldC4gDQoNCioqS+G6v3QgbHXhuq1uOiBOZ3V5w6puIG5ow6JuIGtpbSBjxrDGoW5nIG3DoHUgSiBjw7MgZ2nDoSBjYW8gbmjhuqV0IGzDoCBkbyBtw6B1IEogY8OzIGto4buRaSBsxrDhu6NuZyBu4bq3bmcgaMahbiBuaOG7r25nIG3DoHUga2jDoWMuKioNCg0KDQojIyBCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIHRoZW8gbeG7qWMgZ2nDoQ0KYGBge3J9DQp0ICU+JSBtdXRhdGUocGw9Y3V0KGNhcmF0LDMsbGFiZWxzID0gYygiVuG7q2EgIiwiQ2FvIiwiUuG6pXQgY2FvIikpKSAlPiUgZ3JvdXBfYnkocGwpICU+JQ0KICAgIHN1bW1hcmlzZShtPW1lYW4oY2FyYXQpKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4PXBsLHk9bSkpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtLDIpKSx2anVzdD0yLGNvbG9yPSJ3aGl0ZSIpKw0KICAgIGxhYnMoeD0iTeG7qWMgZ2nDoSIseT0iS2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIix0aXRsZSA9ICJCaeG7g3UgxJHhu5Mga2jhu5FpIGzGsOG7o25nIHRydW5nIGLDrG5oIHRoZW8gbeG7qWMgZ2nDoSIpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyDhu58gbeG7qWMgZ2nDoSBy4bqldCBjYW8gdGjDrCBraOG7kWkgbMaw4bujbmcgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgbOG7m24gbmjhuqV0IHbDoCDhu58gbeG7qWMgZ2nDoSB24burYSB0aMOsIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBraOG7kWkgbMaw4bujbmcgbmjhu48gbmjhuqV0Lg0KDQoqKkvhur90IGx14bqtbjogVuG6rXkgZ2nDoSBj4bunYSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIHPhur0gcGjhu6UgdGh14buZYyB2w6BvIGto4buRaSBsxrDhu6NuZyoqDQoNCiMjIEJp4buDdSDEkeG7kyDEkeG7mSBs4buHY2ggY2h14bqpbiBj4bunYSBraOG7kWkgbMaw4bujbmcgdGhlbyBtw6B1IHPhuq9jDQoNCiMjIyBCaeG7g3UgxJHhu5MgDQpgYGB7cn0NCnQgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKHNkPXNkKGNhcmF0KSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1jb2xvcix5PXNkKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKHNkLDIpKSx2anVzdD0yLGNvbG9yPSJ3aGl0ZSIpKw0KICAgIGxhYnMoeD0iTcOgdSBz4bqvYyIseT0ixJDhu5kgYmnhur9uIMSR4buZbmcga2jhu5FpIGzGsOG7o25nIix0aXRsZSA9ICJCaeG7g3UgxJHhu5MgxJHhu5kgYmnhur9uIMSR4buZbmcga2jhu5FpIGzGsOG7o25nIHRoZW8gbcOgdSBz4bqvYyIpKw0KICAgIHRoZW1lX2J3KCkNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0KVGEgdGjhuqV5IMSRxrDhu6NjIGJp4bq/biDEkeG7mW5nIHbhu4Ega2jhu5FpIGzGsOG7o25nIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBKIGzDoCBs4bubbiBuaOG6pXQsIHZpw6puIGtpbSBjxrDGoW5nIG3DoHUgRCB0aMOsIGPDsyDEkeG7mSBiaeG6v24gxJHhu5luZyB24buBIGto4buRaSBsxrDhu6NuZyBuaOG7jyBuaOG6pXQuIFbDrCB24bqteSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIG3DoHUgSiBjw7Mga2jhu5FpIGzGsOG7o25nIG5oaeG7gXUgaMahbiBt4buNaSBtw6B1IGtow6FjLg0KDQojIyBCaeG7g3UgxJHhu5MgxJHhu5kgbOG7h2NoIHRoZW8gbeG7qWMgZ2nDoQ0KDQojIyMgQmnhu4N1IMSR4buTDQpgYGB7cn0NCnQgJT4lIG11dGF0ZShwbD1jdXQoY2FyYXQsMyxsYWJlbHMgPSBjKCJW4burYSAiLCJDYW8iLCJS4bqldCBjYW8iKSkpICU+JSBncm91cF9ieShwbCkgJT4lDQogICAgc3VtbWFyaXNlKHNkPXNkKGNhcmF0KSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1wbCx5PXNkKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKHNkLDIpKSx2anVzdD0yLGNvbG9yPSJ3aGl0ZSIpKw0KICAgIGxhYnMoeD0iTeG7qWMgZ2nDoSIseT0ixJDhu5kgYmnhur9uIMSR4buZbmcga2jhu5FpIGzGsOG7o25nIix0aXRsZSA9ICJCaeG7g3UgxJHhu5MgYmnhur9uIMSR4buZbmcga2jhu5FpIGzGsOG7o25nIHRoZW8gbeG7qWMgZ2nDoSIpDQpgYGANCg0KIyNHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2Mgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgbeG7qWMgcuG6pXQgY2FvIGPDsyDEkeG7mSBiaeG6v24gxJHhu5luZyBs4bubbiBuaOG6pXQgdsOgIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIG3hu6ljIGdpw6EgY2FvIGPDsyDEkeG7mSBiaeG6v24gxJHhu5luZyBuaOG7jyBuaOG6pXQuIA0KDQojIyBCaeG7g3UgxJHhu5MgdHJ1bmcgduG7iyBraOG7kWkgbMaw4bujbmcgIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBz4bqvYw0KDQojIyMgQmnhu4N1IMSR4buTDQpgYGB7cn0NCnQgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG1lPW1lZGlhbihjYXJhdCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y29sb3IseT1tZSkpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtZSwyKSksdmp1c3Q9Mixjb2xvcj0id2hpdGUiKSsNCiAgICBsYWJzKHg9Ik3DoHUgc+G6r2MiLHk9Ikdpw6EgdHLhu4sgdHJ1bmcgduG7iyIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIHRydW5nIHbhu4sga2jhu5FpIGzGsOG7o25nIHRoZW8gbcOgdSBz4bqvYyIpKw0KICAgIHRoZW1lX2J3KCkNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0KTmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgbcOgdSBKIHRow6wgY8OzIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBs4bubbiBuaOG6pXQgdsOgIG5o4buPIG5o4bqldCBsw6AgMiBtw6B1IEQsRS4gSGFpIG3DoHUgRixHIGPDsyB0cnVuZyBi4buLIGLhurFuZyB24bubaSBuaGF1Lg0KDQoqKkvhur90IEx14bqtbjogQ8OzIHThu5tpIDUwJSB2acOqbiBraW0gY8awxqFuZyBtw6B1IEogbOG7m24gaMahbiAxLjExIGNhcmF0IHbDrCB24bqteSBnacOhIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBKIHLhuqV0IGNhbyoqDQoNCiMjIEJp4buDdSDEkeG7kyB0cnVuZyB24buLIGto4buRaSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3hu6ljIGdpw6ENCg0KIyMjIEJp4buDdSDEkeG7kw0KYGBge3J9DQp0ICU+JSBtdXRhdGUocGw9Y3V0KGNhcmF0LDMsbGFiZWxzID0gYygiVuG7q2EgIiwiQ2FvIiwiUuG6pXQgY2FvIikpKSAlPiUgZ3JvdXBfYnkocGwpICU+JQ0KICAgIHN1bW1hcmlzZShtZT1tZWRpYW4oY2FyYXQpKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4PXBsLHk9bWUpKSsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9cm91bmQobWUsMikpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJN4bupYyBnacOhIix5PSJHacOhIHRy4buLIHRydW5nIHbhu4siLHRpdGxlID0gIkJp4buDdSDEkeG7kyB0cnVuZyB24buLIGto4buRaSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3hu6ljIGdpw6EiKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpOaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBt4bupYyBnacOhIGNhbyB0aMOsIGPDsyBnacOhIHRy4buLIHRydW5nIHbhu4sgY2FvIG5o4bqldCB2w6Agbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgbeG7qWMgZ2nDoSB24burYSB0aMOsIGPDsyB0cnVuZyB24buLIHRo4bqlcCBuaOG6pXQuDQoNCioqS+G6v3QgbHXhuq1uOiBUYSBiaeG6v3QgxJHGsOG7o2MgY8OzIHThu5tpIDUwJSB2acOqbiBraW0gY8awxqFuZyBjw7MgbeG7qWMgZ2nDoSBjYW8gY8OzIGto4buRaSBsxrDhu6NuZyBoxqFuIDQgY2FyYXQuKioNCg0KIyMgQmnhu4N1IMSR4buTIHRydW5nIHbhu4sgY+G7p2EgZ2nDoSB0aGVvIG3DoHUgc+G6r2MgDQoNCiMjIyBCaeG7g3UgxJHhu5MgDQpgYGB7cn0NCnQgJT4lIGdyb3VwX2J5KGNvbG9yKSAlPiUgc3VtbWFyaXNlKG1lPW1lZGlhbihwcmljZSkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y29sb3IseT1tZSkpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtZSwyKSksdmp1c3Q9Mixjb2xvcj0id2hpdGUiKSsNCiAgICBsYWJzKHg9Ik3DoHUgc+G6r2MiLHk9Ikdpw6EgdHLhu4sgdHJ1bmcgduG7iyIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIHRydW5nIHbhu4sgY+G7p2EgZ2nDoSB0aGVvIG3DoHUgc+G6r2MiKSsNCiAgICB0aGVtZV9idygpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNCk5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgbcOgdSBKIGPDsyBnacOhIHRy4buLIHRydW5nIHbhu4sgY2FvIG5o4bqldCB2w6AgbcOgdSBFIGPDsyBnacOhIHRy4buLIHRydW5nIHbhu4sgdGjhuqVwIG5o4bqldC4NCg0KKipL4bq/dCBsdeG6rW46IFRhIGJp4bq/dCDEkcaw4bujYyBjw7MgdOG7m2kgNTAlIHZpw6puIGtpbSBjxrDGoW5nIG3DoHUgSiBjw7MgZ2nDoSBoxqFuIDQyMzQqKg0KDQojIyBCaeG7g3UgxJHhu5MgdHJ1bmcgduG7iyBj4bunYSBnacOhIHRoZW8gY2jhuqV0IGzGsOG7o25nIHbDoCBtw6B1IHPhuq9jDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG1lPW1lZGlhbihwcmljZSkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9Y3V0LHk9bWUsZmlsbD1jb2xvcikpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgbGFicyh4PSJNw6B1IHPhuq9jIix5PSJHacOhIHRy4buLIHRydW5nIHbhu4siLHRpdGxlID0gIkJp4buDdSDEkeG7kyB0cnVuZyB24buLIGPhu6dhIGdpw6EgdGhlbyBtw6B1IHPhuq9jIikrDQogICAgdGhlbWVfYncoKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2Mg4bufIGNo4bqldCBsxrDhu6NuZyBGYWlyIHRow6wgbcOgdSBIIGPDsyBnacOhIHRy4buLIHRydW5nIHbhu4sgY2FvIG5o4bqldC4g4bueIGPDoWMgY2jhuqV0IGzGsOG7o25nIHRow6wgbcOgdSBKIGPDsyBnacOhIHRy4buLIHRydW5nIHbhu4sgY2FvIG5o4bqldC4NCg0KIyMgQmnhu4N1IMSR4buTIMSR4buZIGzhu4djaCBjaHXhuqluIGPhu6dhIGdpw6EgdGhlbyBjaOG6pXQgbMaw4bujbmcgbcOgIG3DoHUgc+G6r2MNCg0KIyMjIEJp4buDdSDEkeG7kyANCmBgYHtyICxtZXNzYWdlPUZBTFNFfQ0KdCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKHNkPXNkKHByaWNlKSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1jdXQseT1zZCxmaWxsPWNvbG9yKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBsYWJzKHg9Ik3DoHUgc+G6r2MiLHk9IsSQ4buZIGJp4bq/biDEkeG7mW5nIHbhu4EgZ2nDoSIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIMSR4buZIGJp4bq/biDEkeG7mW5nIHbhu4EgZ2nDoSB0aGVvIGNo4bqldCBsxrDhu6NuZyB2w6AgbcOgdSBz4bqvYyIpKw0KICAgIHRoZW1lX2J3KCkNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0K4bueIGNo4bqldCBsxrDhu6NuZyBGYWlyIHRow6wgdmnDqm4ga2ltIGPGsMahbmcgY8OzIG3DoHUgSiBjw7MgxJHhu5kgYmnhur9uIMSR4buZbmcgY2FvIG5o4bqldC4g4bueIGPDoWMgY2jhuqV0IGzGsOG7o25nIGtow6FjIHRow6wgbcOgdSBJIGPDsyDEkeG7mSBiaeG6v24gxJHhu5luZyBjYW8gbmjhuqV0Lg0KDQojIyBCaeG7g3UgxJHhu5kgxJHhu5kgbOG7h2NoIGNodeG6qW4gY+G7p2EgZ2nDoSB0aGVvIMSR4buZIHRyb25nIHN14buRdCB2w6AgbcOgdSBz4bqvYw0KYGBge3IgLG1lc3NhZ2U9RkFMU0V9DQp0ICU+JSBncm91cF9ieShjbGFyaXR5LGNvbG9yKSAlPiUgc3VtbWFyaXNlKHNkPXNkKHByaWNlKSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1jbGFyaXR5LHk9c2QsZmlsbD1jb2xvcikpKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgbGFicyh4PSLEkOG7mSB0cm9uZyBzdeG7kXQiLHk9IsSQ4buZIGJp4bq/biDEkeG7mW5nIHbhu4EgZ2nDoSIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIMSR4buZIGJp4bq/biDEkeG7mW5nIHbhu4EgZ2nDoSB0aGVvIMSR4buZIHRyb25nIHN14buRdCB2w6AgbcOgdSBz4bqvYyIpKw0KICAgIHRoZW1lX2J3KCkNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0K4bueIMSR4buZIHRyb25nIHN14buRdCBJMSxWUzEsVlZTMixWVlMhIHRow6wgbcOgdSBKIGPDsyDEkeG7mSBiaeG6v24gxJHhu5luZyBnacOhIGNhbyBuaOG6pXQuIOG7niDEkeG7mSB0cm9uZyBzdeG7kSBTSTIsU0kxLFZTMiB0aMOsIG3DoHUgSSBjw7MgxJHhu5kgYmnhur9uIMSR4buZbmcgY2FvIG5o4bqldC4g4bueIMSR4buZIHRyb25nIHN14buRdCBJRiB0aMOsIG3DoHUgRCBjw7MgxJHhu5kgYmnhur9uIMSR4buZbmcgY2FvIG5o4bqldCANCg0KDQojIyBCaeG7g3UgxJHhu5MgY2hp4buBdSBjYW8gdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBt4bupYyBnacOhDQpgYGB7cn0NCnQgJT4lIG11dGF0ZShwbD1jdXQoY2FyYXQsMyxsYWJlbHMgPSBjKCJW4burYSAiLCJDYW8iLCJS4bqldCBjYW8iKSkpICU+JSBncm91cF9ieShwbCkgJT4lDQogICAgc3VtbWFyaXNlKG09bWVhbihkZXB0aCkpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9cGwseT1tKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKG0sMikpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJN4bupYyBnacOhIix5PSJDaGnhu4F1IGNhbyB0cnVuZyBiw6xuaCIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIGNoaeG7gXUgY2FvIHRydW5nIGLDrG5oIGtpbSBjxrDGoW5nIHRoZW8gbeG7qWMgZ2nDoSIpKw0KICAgIHRoZW1lX2J3KCkNCmBgYA0KDQojIyMgR2nhuqNpIHRow61jaA0KVGEgdGjhuqV5IMSRxrDhu6NjIOG7nyBjw6FjIG3hu6ljIGdpw6EgdGjDrCBjaGnhu4F1IGNhbyB0cnVuZyBiw6xuaCBn4bqnbiBuaMawIGLhurFuZyBuaGF1Lg0KDQoqKkvhur90IGx14bqtbjogVuG6rXkgY2hp4buBdSBjYW8gY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgc+G6vSBraMO0bmcg4bqjbmggaMaw4bufbmcgduG7gSBnacOhIGPhu6dhIGtpbSBjxrDGoW5nKioNCiMjIEJp4buDdSDEkeG7kyBjaGnhu4F1IGNhbyB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyANCg0KIyMjIEJp4buDdSDEkeG7kw0KYGBge3J9DQp0ICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobT1tZWFuKGRlcHRoKSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1jdXQseT1tKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKG0sMikpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJDaOG6pXQgbMaw4bujbmciLHk9IkNoaeG7gXUgY2FvIHRydW5nIGLDrG5oIix0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY2hp4buBdSBjYW8gdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmciKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2Mg4bufIGPDoWMgY2jhuqV0IGzGsOG7o25nIGtow6FjIG5oYXUgbmjGsG5nIGNoaeG7gXUgY2FvIHbhuqtuIGPDsyBnacOhIHRy4buLIGfhuqduIGLhurFuZyB24bubaSBuaGF1IA0KDQoqKkvhur90IGx14bqtbjogVuG6rXkgY2hp4buBdSBjYW8gY+G7p2Egbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBraMO0bmcgY2jDqm5oIGzhu4djaCBuaGF1IHF1w6Egbmhp4buBdSoqDQoNCiMjIEJp4buDdSDEkeG7kyB0cnVuZyBiw6xuaCDEkcaw4budbmcga8OtbmggbOG7m24gbmjhuqV0IHRoZW8gbeG7qWMgZ2nDoQ0KDQojIyMgQmnhu4N1IMSR4buTIA0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCAsbWVzc2FnZT1GQUxTRX0NCnQgJT4lIG11dGF0ZShwbD1jdXQocHJpY2UsMyxsYWJlbHMgPSBjKCJW4burYSIsIkNhbyIsIlLhuqV0IGNhbyIpKSkgJT4lIGdyb3VwX2J5KHBsKSAlPiUgDQogICAgc3VtbWFyaXNlKG09bWVhbih4KSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1wbCx5PW0pKSArIA0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtLDIpKSx2anVzdD0yLGNvbG9yPSJ3aGl0ZSIpKw0KICAgIHRoZW1lX2J3KCkrDQogICAgbGFicyh4PSJN4bupYyBnacOhIix5PSLEkMaw4budbmcga8OtbmggdHJ1bmcgYsOsbmgiLHRpdGxlID0gIkJp4buDdSDEkeG7kyDEkcaw4budbmcga8OtbmggbOG7m24gbmjhuqV0IHRydW5nIGLDrG5oIHRoZW8gbeG7qWMgZ2nDoSIpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIOG7nyBt4bupYyBnacOhIHLhuqV0IGNhbyBjw7MgxJHGsOG7nW5nIGvDrW5oIHRvIG5o4bqldCB2w6Agbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyDhu58gbeG7qWMgZ2nDoSB24burYSBjw7MgxJHGsOG7nW5nIGvDrW5oIG5o4buPIG5o4bqldC4NCg0KKipL4bq/dCBsdeG6rW46IFbhuq15IMSRxrDhu51uZyBraW5oIGzhu5tuIG5o4bqldCBj4bunYSB2acOqbiBraW0gY8awxqFuZyBjw7Mg4bqjbmggaMaw4bufbmcgdOG7m2kgZ2nDoSBj4bunYSB2acOqbiBraW0gY8awxqFuZyoqDQoNCiMjIEJp4buDdSDEkeG7kyDEkcaw4budbmcga8Otbmggbmjhu48gbmjhuqV0IHRoZW8gbeG7qWMgZ2nDoQ0KDQojIyMgQmnhu4N1IMSR4buTDQpgYGB7cn0NCnQgJT4lIG11dGF0ZShwbD1jdXQocHJpY2UsMyxsYWJlbHMgPSBjKCJW4burYSIsIkNhbyIsIlLhuqV0IGNhbyIpKSkgJT4lIGdyb3VwX2J5KHBsKSAlPiUgDQogICAgc3VtbWFyaXNlKG09bWVhbih5KSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1wbCx5PW0pKSArIA0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtLDIpKSx2anVzdD0yLGNvbG9yPSJ3aGl0ZSIpKw0KICAgIHRoZW1lX2J3KCkrDQogICAgbGFicyh4PSJN4bupYyBnacOhIix5PSLEkMaw4budbmcga8OtbmggdHJ1bmcgYsOsbmgiLHRpdGxlID0gIkJp4buDdSDEkeG7kyDEkcaw4budbmcga8Otbmggbmjhu48gbmjhuqV0IHRydW5nIGLDrG5oIHRoZW8gbeG7qWMgZ2nDoSIpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIOG7nyBt4bupYyBnacOhIHLhuqV0IGNhbyBjw7MgxJHGsOG7nW5nIGvDrW5oIHRvIG5o4bqldCB2w6Agbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyDhu58gbeG7qWMgZ2nDoSB24burYSBjw7MgxJHGsOG7nW5nIGvDrW5oIG5o4buPIG5o4bqldC4NCg0KKipL4bq/dCBsdeG6rW46IFbhuq15IMSRxrDhu51uZyBraW5oIG5o4buPIG5o4bqldCBj4bunYSB2acOqbiBraW0gY8awxqFuZyBjw7Mg4bqjbmggaMaw4bufbmcgdOG7m2kgZ2nDoSBj4bunYSB2acOqbiBraW0gY8awxqFuZyoqDQoNCiMjIEJp4buDdSDEkeG7kyBjaGnhu4F1IHPDonUgdHJ1bmcgYsOsbmggdGhlbyBt4bupYyBnacOhIA0KYGBge3J9DQp0ICU+JSBtdXRhdGUocGw9Y3V0KHByaWNlLDMsbGFiZWxzID0gYygiVuG7q2EiLCJDYW8iLCJS4bqldCBjYW8iKSkpICU+JSBncm91cF9ieShwbCkgJT4lIA0KICAgIHN1bW1hcmlzZShtPW1lYW4oeikpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHg9cGwseT1tKSkgKyANCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9cm91bmQobSwyKSksdmp1c3Q9Mixjb2xvcj0id2hpdGUiKSsNCiAgICB0aGVtZV9idygpKw0KICAgIGxhYnMoeD0iTeG7qWMgZ2nDoSIseT0iQ2hp4buBdSBzw6J1IHRydW5nIGLDrG5oIix0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY2hp4buBdSBzw6J1IHRydW5nIGLDrG5oIHRoZW8gbeG7qWMgZ2nDoSIpDQpgYGANCg0KIyMjR2nhuqNpIHRow61jaA0KVGEgdGjhuqV5IMSRxrDhu6NjIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcg4bufIG3hu6ljIGdpw6EgcuG6pXQgY2FvIHRow6wgY8OzIGNoaeG7gXUgc8OidSBjYW8gbmjhuqV0IHbDoCBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBt4bupYyBnacOhIHbhu6thIHRow6wgY8OzIGNoaeG7gXUgc8OidSB0aOG6pXAgbmjhuqV0Lg0KDQoqKkvhur90IGx14bqtbjogVuG6rXkgY2hp4buBdSBzw6J1IGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDhuqNuaCBoxrDhu59uZyB04bubaSBnacOhIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nKioNCg0KIyMgQmnhu4N1IMSR4buTIMSRxrDhu51uZyBrw61uaCBs4bubbiBuaOG6pXQgdHJ1bmcgYsOsbmggdGhlbyBjaOG6pXQgbMaw4bujbmcNCg0KIyMjIEJp4buDdSDEkeG7kw0KYGBge3J9DQp0ICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobT1tZWFuKHgpKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4PWN1dCx5PW0pKSsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9cm91bmQobSwyKSksdmp1c3Q9Mixjb2xvcj0id2hpdGUiKSsNCiAgICBsYWJzKHg9IkNo4bqldCBsxrDhu6NuZyIseT0ixJDGsOG7nW5nIGvDrW5oIHRydW5nIGLDrG5oIix0aXRsZSA9ICJCaeG7g3UgxJHhu5MgxJHGsOG7nW5nIGvDrW5oIGzhu5tuIG5o4bqldCB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyIpDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gNClRhIHRo4bqleSDEkcaw4bujYyDhu58gbeG7jWkgY2jhuqV0IGzGsOG7o25nIHRow6wgxJHGsOG7nW5nIGvDrW5oIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIGtow7RuZyBjaMOqbmggbOG7h2NoIHF1w6Egbmhp4buBdSB24bubaSBuaGF1Lg0KDQoqKkvhur90IGx14bqtbjogVuG6rXkgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjaOG6pXQgbMaw4bujbmcgRmFpciB0aMOsIGPDsyB0aOG7gyBjw7MgZ2nDoSBjYW8gaMahbiBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgdOG7kXQgaMahbiBraMOhYyoqDQoNCiMjIEJp4buDdSDEkeG7kyDEkcaw4budbmcga8Otbmggbmjhu48gbmjhuqV0IHRydW5nIGLDrG5oIHRoZW8gY2jhuqV0IGzGsOG7o25nDQoNCiMjIyBCaeG7g3UgxJHhu5MNCmBgYHtyfQ0KdCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09bWVhbih5KSkgJT4lIA0KICAgIGdncGxvdChhZXMoeD1jdXQseT1tKSkrDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPXJvdW5kKG0sMikpLHZqdXN0PTIsY29sb3I9IndoaXRlIikrDQogICAgbGFicyh4PSJDaOG6pXQgbMaw4bujbmciLHk9IsSQxrDhu51uZyBrw61uaCB0cnVuZyBiw6xuaCIsdGl0bGUgPSAiQmnhu4N1IMSR4buTIMSRxrDhu51uZyBrw61uaCBuaOG7jyBuaOG6pXQgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmciKQ0KYGBgDQoNCiMjIyBHaeG6o2kgdGjDrWNoDQpUYSB0aOG6pXkgxJHGsOG7o2MgxJHGsOG7nW5nIGvDrW5oIGPhu6dhIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcg4bufIG5o4buvbmcgY2jhuqV0IGzGsOG7o25nIGtow6FjIG5oYXUgdGjDrCBraMO0bmcgY2jDqm5oIGzhu4djaCBxdcOhIG5oaeG7gXUuIE5oxrBuZyB0YSB0aOG6pXkgcuG6sW5nIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY2jhuqV0IGzGsOG7o25nIEZhaXIgY8OzIMSRxrDhu51uZyBrw61uaCBs4bubbiBoxqFuIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBJZGVhbC4gxJBp4buBdSBuw6B5IGThuqtuIHThu5tpIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY2jhuqV0IGzGsOG7o25nIEZhaXIgY8OzIGdpw6EgY2FvIGjGoW4gbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjaOG6pXQgbMaw4bujbmcgSWRlYWwuDQoNCg0K