23:39:04, 02 - 03 - 2024

1 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.

1.1 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_”.

1.2 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”.

1.3 Thông tin

1.3.1 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 ...

1.3.2 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

2 Biểu đồ

2.1 Biểu đồ tần số theo biến cut

2.1.1 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" ))

2.1.2 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.

2.2 Biểu đồ tần số theo biến color

2.2.1 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")

2.2.2 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”

2.3 Biểu đồ tần số theo biến clarity

2.3.1 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")

2.3.2 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.

2.4 Biểu đồ số lượng kim cương theo chất lượng và màu sắc

2.4.1 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")

2.4.2 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.

2.5 Biểu đồ số lượng kim cương theo độ trong suốt và màu sắc

2.5.1 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")

2.5.2 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.

2.6 Biểu đồ về khối lượng trung bình của kim cương theo chất lượng

2.6.1 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")

2.6.2 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ỏ.

2.7 Biểu đồ về giá trung bình của kim cương theo chất lượng

2.7.1 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")

2.7.2 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.

2.8 Biểu đồ độ lệch chuẩn của giá kim cương theo chất lượng

2.8.1 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")

2.8.2 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ệ.

2.9 Biểu đồ giá trung bình của kim cương theo màu sắc

2.9.1 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")

2.9.2 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

2.9.3 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")

2.9.4 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

2.10 Biểu đồ tần suất của kim cương theo màu sắc

2.10.1 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")

2.10.2 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.

2.11 Biểu đồ giá trung bình kim cương theo màu sắc và chất lượng

2.11.1 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")

2.11.2 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.

2.12 Biểu đồ Số lượng theo mức giá và theo màu sắc

2.12.1 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")

2.12.2 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.

2.13 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()

2.13.1 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.

2.14 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á")

2.14.1 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

2.15 Biểu đồ độ lệch chuẩn của khối lượng theo màu sắc

2.15.1 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()

2.15.2 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.

2.16 Biểu đồ độ lệch theo mức giá

2.16.1 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.

2.17 Biểu đồ trung vị khối lượng kim cương theo màu sắc

2.17.1 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()

2.17.2 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

2.18 Biểu đồ trung vị khối lượng kim cương theo mức giá

2.18.1 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á")

2.18.2 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.

2.19 Biểu đồ trung vị của giá theo màu sắc

2.19.1 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()

2.19.2 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

2.20 Biểu đồ trung vị của giá theo chất lượng và màu sắc

2.20.1 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()

2.20.2 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.

2.21 Biểu đồ độ lệch chuẩn của giá theo chất lượng mà màu sắc

2.21.1 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()

2.21.2 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.

2.22 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()

2.22.1 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

2.23 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()

2.23.1 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

2.23.2 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")

2.23.3 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

2.24 Biểu đồ trung bình đường kính lớn nhất theo mức giá

2.24.1 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á")

2.24.2 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

2.25 Biểu đồ đường kính nhỏ nhất theo mức giá

2.25.1 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á")

2.25.2 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

2.26 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

2.27 Biểu đồ đường kính lớn nhất trung bình theo chất lượng

2.27.1 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")

2.27.2 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

2.28 Biểu đồ đường kính nhỏ nhất trung bình theo chất lượng

2.28.1 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")

2.28.2 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