Giới thiệu bộ dữ liệu diamonds

-Bộ dữ liệu có 10 biến và 53940 quan sát

library(tidyverse)
library(scales)
T <- diamonds
names(T)
##  [1] "carat"   "cut"     "color"   "clarity" "depth"   "table"   "price"  
##  [8] "x"       "y"       "z"

Phân tích biểu đồ của bộ dữ liệu diamonds

Biểu đồ với dữ liệu cut

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

Biểu đồ trên biểu diễn số lượng của 5 loại mặt cắt của kim cương từ loại thấp đến cao, như:

-Loại Fair có khoảng 2000 viên

-Loại Good có khoảng 5000 viên

-Loại Very Good có khoảng 12000 viên

-Loại Premium có khoảng 13000 viên

-Loại Ideal có khoảng hơn 20000 viên

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

Đây cũng là một biểu đồ biểu diễn tương tự biểu đồ số 1 nhưng khác là nó được trình bày theo chiều ngang

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

Biểu đồ này đã được thêm vào số liệu cụ thể cùng với màu sắc để dễ dàng phân biệt

Biều đồ phân phối của carat

T %>% group_by(color) %>% summarise(n = n()) %>%
  ggplot(aes(color,n)) +
    geom_col(fill='lightblue') +
    geom_text(aes(label = n),vjust = 2, color = 'white') +
    labs(x = 'Loại Màu Sắc', y = 'Số lượng')

Biểu đồ trên biểu diễn số lượng của 7 loại màu sắc của kim cương từ loại ‘D’ đến ‘J’, như:

-Màu D có khoảng 6775 viên

-Màu E có khoảng 9797 viên

-Màu F có khoảng 9542 viên

-Màu G có khoảng 11292 viên

-Màu H có khoảng 8304 viên

-Màu I có khoảng 5422 viên

-Màu J có khoảng 2808 viên

Ta thấy được Màu G chiếm tỷ lệ nhiều trong biểu đồ trên

Biểu đồ số lượng kim cương theo loại clarity

T %>% group_by(clarity) %>% summarise(n = n()) %>%
  ggplot(aes(clarity,n)) +
    geom_col(fill='lightblue') +
    geom_text(aes(label = n),vjust = 2, color = 'white') +
    labs(x = 'Độ Trong Suốt', y = 'Số lượng')

Biểu đồ thể hiện số lượng kim cương được xếp theo độ trong suốt từ “I1” tới “IF”

Biểu đồ tỷ lệ phần trăm số lượng kim cương theo loại cut:

T %>% group_by(cut) %>% summarise(n = n()) %>%
  ggplot(aes(cut,n)) +
    geom_col(fill='lightgrey') +
      geom_text(aes(label = percent(n/length(T$carat))),vjust = 2, color = 'black') +
    labs(x = 'Loại', y = 'Số lượng')

Biểu đồ này biểu diễn tỷ lệ phần trăm số lượng kim cương theo chất lượng cắt

Biểu đồ số lượng kim cương theo loại color với chất lượng cắt:

T %>% group_by(cut,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    labs(x = 'Loại', y = 'Số lượng')

Do có 7 loại màu của kim cương nên chúng ta có 7 biểu đồ nhỏ được xếp tương ứng và mỗi biểu đồ thể hiện số lượng và theo từng chất lượng cắt từ Fair tới Ideal

Biểu đồ số lượng kim cương theo loại color với chất lượng cắt:

T %>% group_by(cut,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_text(aes(label = n),vjust = 2, color = 'blue') +
    labs(x = 'Loại', y = 'Số lượng')

Do có 7 loại màu của kim cương nên chúng ta có 7 biểu đồ nhỏ được xếp tương ứng và mỗi biểu đồ thể hiện số lượng và theo từng chất lượng cắt từ Fair tới Ideal nhưng nó có thêm số trên mỗi cột trong mỗi biểu đồ

biểu đồ cột hiển thị giá trị trung bình của biến carat theo từng nhóm cut.

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 = 'white') +
    labs(x = 'Cut', y = 'Carat')

Biểu đồ thể hiện giá trị carat trung bình của kim cương được xếp theo từng loại chất lượng mặt cắt

Biểu đồ thể hiện giá trung bình của kim cương theo từng màu và chất lượng cắt

T %>% group_by(cut,color) %>% summarise(m = mean(price)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_text(aes(label = round(m))) +
    labs(x = 'Cut', y = 'Số lượng')

Biểu đồ biểu diễn giá trị trung bình của kim cương theo từng chất lượng cắt và sắp theo từng màu từ D tới J

Biểu đồ thể hiện tổng trọng lượng kim cương theo màu sắc:

ggplot(T, aes(x = color, y = carat)) +
  geom_bar(stat = "summary", fun = "sum")

Biểu đồ cột hiển thị tổng của biến carat theo từng giá trị của biến color. Mỗi cột trong biểu đồ đại diện cho một giá trị của biến color, và chiều cao của cột biểu thị giá trị tổng tương ứng của biến carat.

Biểu đồ giá trị trung bình (mean) của biến price theo từng giá trị của biến cut

ggplot(T, aes(x = cut, y = price)) +
  geom_bar(stat = "summary", fun = "mean")

Biểu đồ cột hiển thị giá trị trung bình của biến price theo từng giá trị của biến cut. Mỗi cột trong biểu đồ biểu thị một giá trị của biến cut, và chiều cao của cột biểu thị giá trị trung bình tương ứng của biến price.

Biểu đồ thể hiện giá trị kim cương lớn nhất theo độ trong:

ggplot(diamonds, aes(x = clarity, y = price)) +
  geom_bar(stat = "summary", fun = max)

Biểu đồ cột hiển thị giá trị lớn nhất của biến price theo từng giá trị của biến clarity. Mỗi cột trong biểu đồ biểu thị một giá trị của biến clarity, và chiều cao của cột biểu thị giá trị lớn nhất tương ứng của biến price.

Biểu đồ thể hiện giá trị kim cương nhỏ nhất theo màu sắc:

ggplot(diamonds, aes(x = color, y = price)) +
  geom_bar(stat = "summary", fun = min)

Biểu đồ cột hiển thị giá trị nhỏ nhất của biến price theo từng giá trị của biến color. Mỗi cột trong biểu đồ biểu thị một giá trị của biến color, và chiều cao của cột biểu thị giá trị nhỏ nhất tương ứng của biến price.

Biểu đồ thể hiện tỷ lệ các loại cắt kim cương theo màu sắc:

ggplot(diamonds, aes(x = color, fill = cut)) +
  geom_bar(position = "fill")

Biểu đồ cột hiển thị phần trăm tương đối của từng giá trị của biến cut theo từng giá trị của biến color. Mỗi cột trong biểu đồ biểu thị một giá trị của biến color, và màu sắc của các phần trong cột biểu thị giá trị của biến cut.

Biểu đồ thể hiện tổng giá trị kim cương theo loại cắt và màu sắc:

ggplot(diamonds, aes(x = cut, fill = color, y = price)) +
  geom_bar(position = "stack", stat = "summary", fun = "sum")

Biểu đồ này cho thấy tổng giá trị kim cương theo từng loại cắt và màu sắc, với các cột được xếp chồng lên nhau.

Biểu đồ thể hiện giá trị trung bình kim cương theo loại cắt và độ trong:

ggplot(diamonds, aes(x = cut, fill = clarity, y = price)) +
  geom_bar(position = "stack", stat = "summary", fun = "mean")

Biểu đồ cột, trong đó mỗi cột biểu thị một giá trị của biến cut. Các phần trong cột sẽ được tô màu theo giá trị của biến clarity, và chiều cao của cột biểu thị giá trị trung bình của biến price trong mỗi nhóm

Biểu đồ thể hiện số lượng kim cương theo kích thước và màu sắc:

ggplot(diamonds, aes(x = carat, fill = color)) +
  geom_bar(binwidth = 0.5)

Biểu đồ này cho thấy số lượng kim cương theo kích thước và màu sắc, với các cột được nhóm lại theo khoảng kích thước 0.5 và màu sắc tương ứng.

Biểu đồ thể hiện số lượng kim cương theo kích thước và loại cắt:

T5 <- subset(T, cut == "Ideal" & color == "J")
ggplot(T5, aes(x = carat)) +
  geom_bar(fill = "lightyellow", color = "black", alpha = 0.8) +
  labs(title = "Biểu đồ cột của dữ liệu diamonds (màu J)",
       x = "Carat",
       y = "Số Lượng") +
  theme_minimal()

Biểu đồ này cho thấy số lượng kim cương theo loại cắt là Ideal và có màu là J, với các cột được nhóm lại theo độ lớn tương ứng.

Biểu đồ thể hiện giá trị trung bình kim cương theo loại cắt và màu sắc:

ggplot(diamonds, aes(x = cut, fill = color, y = price)) +
  stat_summary(fun = "mean", geom = "bar")

Biểu đồ này cho thấy số lượng kim cương theo từng màu sắc và loại cắt, với các cột được xếp chồng lên nhau.

Biểu đồ thể hiện giá trị trung bình kim cương theo màu sắc và độ trong:

ggplot(diamonds, aes(x = color, fill = clarity, y = price)) +
  geom_bar(position = "stack", stat = "summary", fun = "mean")

Biểu đồ này cho thấy giá trị trung bình của kim cương theo từng màu sắc và độ trong, với các cột được xếp chồng lên nhau.

Biểu đồ thể hiện số lượng kim cương theo kích thước và màu sắc:

T4 <- subset(T,color == "J", depth)
ggplot(T4, aes(x = depth)) +
  geom_bar(fill = "steelblue", color = "black", alpha = 1) +
  labs(title = "Biểu đồ cột của dữ liệu diamonds",
       x = "Depth",
       y = "Số lượng") +
  theme_minimal()

Biểu đồ này cho thấy số lượng kim cương có màu sắc là J theo loại Depth và các cột được nhóm lại

Biểu đồ thể hiện số lượng kim cương theo biến Carat

T$carat <- as.numeric(T$carat)
T <- T %>% mutate(caratC = cut(carat, breaks = c(0, 0.5, 1, 1.5, 2, Inf), 
            labels = c('rất nhỏ', 'nhỏ', 'vừa', 'lớn', 'rất lớn'))) 
T %>% ggplot(aes(x = caratC)) +
  geom_bar(fill = 'lightblue')

Biểu đồ cột, trong đó mỗi cột biểu thị một nhóm dựa trên giá trị của biến carat. Màu sắc của các cột sẽ là ‘lightblue’.

Biểu đồ thể hiện số lượng kim cương theo độ trong

ggplot(diamonds, aes(x = clarity)) +
  geom_bar(fill = "steelblue", color = "black", alpha = 0.8) +
  labs(title = "Biểu đồ cột của dữ liệu diamonds",
       x = "Clarity",
       y = "Số lượng") +
  theme_minimal()

biểu đồ cột với các cột được tô màu “steelblue”, có viền màu đen và mờ. Tiêu đề của biểu đồ là “Biểu đồ cột của dữ liệu diamonds”, trục x có nhãn “Clarity” và trục y có nhãn “Số lượng”. Giao diện của biểu đồ là tối giản.

Biểu đồ trung bình trọng lượng diamond theo màu sắc

T %>% ggplot(mapping = aes(x = cut, fill = color)) +
  geom_bar() +
  scale_fill_manual(values = sort(unique(diamonds$color)))+
   labs(title = "Biểu đồ số lượng kim cương chia theo màu sắc",x = 'Loại', y = 'Số lượng')

Biểu đồ cột với các cột biểu thị số lượng theo biến cut, và màu sắc của các cột sẽ được xác định bởi biến color. Giá trị màu sắc được sắp xếp theo thứ tự tăng dần. Tiêu đề của biểu đồ là “Biểu đồ số lượng kim cương chia theo màu sắc”, trục x có nhãn “Loại” và trục y có nhãn “Số lượng”.

Biểu đồ trung bình trọng lượng diamond 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 = 'green') +
    labs(title = "Biểu đồ mean của kim cương theo màu sắc",x = 'Màu', y = 'Mean')

Biểu đồ cột với các cột biểu thị giá trị trung bình của biến carat theo từng màu sắc. Các cột sẽ được xếp chồng lên nhau. Văn bản với giá trị trung bình làm tròn đến 2 chữ số thập phân sẽ được hiển thị trên các cột và có màu sắc xanh lá cây. Tiêu đề của biểu đồ là “Biểu đồ mean của kim cương theo màu sắc”, trục x có nhãn “Màu” và trục y có nhãn “Mean”.

Biểu đồ số lượng kim cương theo chất lượng cắt và độ trong suốt theo từng màu xếp cạnh nhau

ggplot(data= T) +
  geom_bar(mapping = aes(x = cut, fill = clarity), position = "dodge")

Biểu đồ cột với các cột biểu thị số lượng theo biến cut. Màu sắc của các cột sẽ được xác định bởi biến clarity. Các cột sẽ được xếp chồng lên nhau theo từng nhóm biến cut.

Biểu đồ số lượng theo từng loại Clarity của kim cương có màu D

T2 <- subset(T, color == "D")
ggplot(T2, aes(x = clarity)) +
  geom_bar(fill = "lightyellow", color = "black", alpha = 0.8) +
  labs(title = "Biểu đồ cột của dữ liệu diamonds (màu D)",
       x = "Clarity",
       y = "Số lượng") +
  theme_minimal()

Biểu đồ trên cung cấp cho ta thấy được số lượng của cái viên kim cương có màu là D theo từng loại Clarity khác nhau

Biểu đồ số lượng theo từng loại Clarity của kim cương có màu I

T3 <- subset(T, color == "I")
ggplot(T3, aes(x = clarity)) +
  geom_bar(fill = "lightpink", color = "black", alpha = 0.8) +
  labs(title = "Biểu đồ cột của dữ liệu diamonds (màu I)",
       x = "Clarity",
       y = "Số lượng") +
  theme_minimal()

Biểu đồ trên cung cấp cho ta thấy được số lượng của cái viên kim cương có màu là I theo từng loại Clarity khác nhau

LS0tDQp0aXRsZTogIk5oaeG7h20gVuG7pSA0Ig0KYXV0aG9yOiAiTmFtIFRoacOqbiINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6IA0KIGh0bWxfZG9jdW1lbnQ6IA0KICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICB0b2NfZmxvYXQ6IHRydWUNCiAgIHRvYzogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkNCmBgYA0KKipHaeG7m2kgdGhp4buHdSBi4buZIGThu68gbGnhu4d1IGRpYW1vbmRzKio8cD4NCi1C4buZIGThu68gbGnhu4d1IGPDsyAxMCBiaeG6v24gdsOgIDUzOTQwIHF1YW4gc8OhdA0KDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHNjYWxlcykNClQgPC0gZGlhbW9uZHMNCm5hbWVzKFQpDQpgYGANCiMgKipQaMOibiB0w61jaCBiaeG7g3UgxJHhu5MgY+G7p2EgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcyoqDQojIyBCaeG7g3UgxJHhu5MgduG7m2kgZOG7ryBsaeG7h3UgY3V0DQpgYGB7cn0NClQgJT4lIGdncGxvdChhZXMoeCA9IGN1dCkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIHRyw6puIGJp4buDdSBkaeG7hW4gc+G7kSBsxrDhu6NuZyBj4bunYSA1IGxv4bqhaSBt4bq3dCBj4bqvdCBj4bunYSBraW0gY8awxqFuZyB04burIGxv4bqhaSB0aOG6pXAgxJHhur9uIGNhbywgbmjGsDo8cD4NCiAgLUxv4bqhaSBGYWlyIGPDsyBraG/huqNuZyAyMDAwIHZpw6puPHA+DQogIC1Mb+G6oWkgR29vZCBjw7Mga2hv4bqjbmcgNTAwMCB2acOqbjxwPg0KICAtTG/huqFpIFZlcnkgR29vZCBjw7Mga2hv4bqjbmcgMTIwMDAgdmnDqm48cD4NCiAgLUxv4bqhaSBQcmVtaXVtIGPDsyBraG/huqNuZyAxMzAwMCB2acOqbjxwPg0KICAtTG/huqFpIElkZWFsIGPDsyBraG/huqNuZyBoxqFuIDIwMDAwIHZpw6puPHA+DQoNCmBgYHtyfQ0KVCAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0KSkgKw0KICAgIGdlb21fYmFyKCkgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKSArDQogICAgY29vcmRfZmxpcCgpDQpgYGANCiA8cD4gxJDDonkgY8WpbmcgbMOgIG3hu5l0IGJp4buDdSDEkeG7kyBiaeG7g3UgZGnhu4VuIHTGsMahbmcgdOG7sSBiaeG7g3UgxJHhu5Mgc+G7kSAxIG5oxrBuZyBraMOhYyBsw6AgbsOzIMSRxrDhu6NjIHRyw6xuaCBiw6B5IHRoZW8gY2hp4buBdSBuZ2FuZw0KDQpgYGB7cn0NClQgJT4lIGdyb3VwX2J5KGN1dCkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhjdXQsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdsaWdodHBpbmsnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpDQpgYGANCiA8cD5CaeG7g3UgxJHhu5MgbsOgeSDEkcOjIMSRxrDhu6NjIHRow6ptIHbDoG8gc+G7kSBsaeG7h3UgY+G7pSB0aOG7gyBjw7luZyB24bubaSBtw6B1IHPhuq9jIMSR4buDIGThu4UgZMOgbmcgcGjDom4gYmnhu4d0IA0KIA0KIyMgQmnhu4F1IMSR4buTIHBow6JuICBwaOG7kWkgY+G7p2EgY2FyYXQNCmBgYHtyfQ0KVCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY29sb3IsbikpICsNCiAgICBnZW9tX2NvbChmaWxsPSdsaWdodGJsdWUnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMiwgY29sb3IgPSAnd2hpdGUnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaSBNw6B1IFPhuq9jJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KPHA+IEJp4buDdSDEkeG7kyB0csOqbiBiaeG7g3UgZGnhu4VuIHPhu5EgbMaw4bujbmcgY+G7p2EgNyBsb+G6oWkgbcOgdSBz4bqvYyBj4bunYSBraW0gY8awxqFuZyB04burIGxv4bqhaSAnRCcgxJHhur9uICdKJywgbmjGsDo8cD4NCiAgIC1Nw6B1IEQgY8OzIGtob+G6o25nIDY3NzUgdmnDqm48cD4NCiAgIC1Nw6B1IEUgY8OzIGtob+G6o25nIDk3OTcgdmnDqm48cD4NCiAgIC1Nw6B1IEYgY8OzIGtob+G6o25nIDk1NDIgdmnDqm48cD4NCiAgIC1Nw6B1IEcgY8OzIGtob+G6o25nIDExMjkyIHZpw6puPHA+DQogICAtTcOgdSBIIGPDsyBraG/huqNuZyA4MzA0IHZpw6puPHA+DQogICAtTcOgdSBJIGPDsyBraG/huqNuZyA1NDIyIHZpw6puPHA+DQogICAtTcOgdSBKIGPDsyBraG/huqNuZyAyODA4IHZpw6puPHA+DQogIFRhIHRo4bqleSDEkcaw4bujYyBNw6B1IEcgY2hp4bq/bSB04bu3IGzhu4cgbmhp4buBdSB0cm9uZyBiaeG7g3UgxJHhu5MgdHLDqm4NCiAgDQojIyBCaeG7g3UgxJHhu5Mgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGxv4bqhaSBjbGFyaXR5DQpgYGB7cn0NClQgJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoY2xhcml0eSxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Ymx1ZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICd3aGl0ZScpICsNCiAgICBsYWJzKHggPSAnxJDhu5kgVHJvbmcgU3Xhu5F0JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIMSRxrDhu6NjIHjhur9wIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0IHThu6sgIkkxIiB04bubaSAiSUYiDQoNCiMjICBCaeG7g3UgxJHhu5MgdOG7tyBs4buHIHBo4bqnbiB0csSDbSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gbG/huqFpIGN1dDoNCmBgYHtyfQ0KVCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKGN1dCxuKSkgKw0KICAgIGdlb21fY29sKGZpbGw9J2xpZ2h0Z3JleScpICsNCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KG4vbGVuZ3RoKFQkY2FyYXQpKSksdmp1c3QgPSAyLCBjb2xvciA9ICdibGFjaycpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIG7DoHkgYmnhu4N1IGRp4buFbiB04bu3IGzhu4cgcGjhuqduIHRyxINtIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgY+G6r3QNCg0KIyMgQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBsb+G6oWkgY29sb3IgduG7m2kgY2jhuqV0IGzGsOG7o25nIGPhuq90Og0KYGBge3J9DQpUICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG4pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y29sb3IpICsNCiAgICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KPHA+IERvIGPDsyA3IGxv4bqhaSBtw6B1IGPhu6dhIGtpbSBjxrDGoW5nIG7Dqm4gY2jDum5nIHRhIGPDsyA3IGJp4buDdSDEkeG7kyBuaOG7jyDEkcaw4bujYyB44bq/cCB0xrDGoW5nIOG7qW5nIHbDoCBt4buXaSBiaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgdsOgIHRoZW8gdOG7q25nIGNo4bqldCBsxrDhu6NuZyBj4bqvdCB04burIEZhaXIgdOG7m2kgSWRlYWw8cD4NCg0KIyMgQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBsb+G6oWkgY29sb3IgduG7m2kgY2jhuqV0IGzGsOG7o25nIGPhuq90Og0KYGBge3J9DQpUICU+JSBncm91cF9ieShjdXQsY29sb3IpICU+JSBzdW1tYXJpc2Uobj1uKCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG4pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZmFjZXRfd3JhcCh+Y29sb3IpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksdmp1c3QgPSAyLCBjb2xvciA9ICdibHVlJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQo8cD4gRG8gY8OzIDcgbG/huqFpIG3DoHUgY+G7p2Ega2ltIGPGsMahbmcgbsOqbiBjaMO6bmcgdGEgY8OzIDcgYmnhu4N1IMSR4buTIG5o4buPIMSRxrDhu6NjIHjhur9wIHTGsMahbmcg4bupbmcgdsOgIG3hu5dpIGJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyB2w6AgdGhlbyB04burbmcgY2jhuqV0IGzGsOG7o25nIGPhuq90IHThu6sgRmFpciB04bubaSBJZGVhbCBuaMawbmcgbsOzIGPDsyB0aMOqbSBz4buRIHRyw6puIG3hu5dpIGPhu5l0IHRyb25nIG3hu5dpIGJp4buDdSDEkeG7kzxwPg0KDQoNCiMjIGJp4buDdSDEkeG7kyBj4buZdCBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24gY2FyYXQgdGhlbyB04burbmcgbmjDs20gY3V0Lg0KYGBge3J9DQpUICU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjdXQseSA9IG0pKSArDQogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAnZG9kZ2UnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKG0sMikpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3doaXRlJykgKw0KICAgIGxhYnMoeCA9ICdDdXQnLCB5ID0gJ0NhcmF0JykNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBnacOhIHRy4buLIGNhcmF0IHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIMSRxrDhu6NjIHjhur9wIHRoZW8gdOG7q25nIGxv4bqhaSBjaOG6pXQgbMaw4bujbmcgbeG6t3QgY+G6r3Q8cD4NCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBtw6B1IHbDoCBjaOG6pXQgbMaw4bujbmcgY+G6r3QNCmBgYHtyfQ0KVCAlPiUgZ3JvdXBfYnkoY3V0LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jb2xvcikgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtKSkpICsNCiAgICBsYWJzKHggPSAnQ3V0JywgeSA9ICdT4buRIGzGsOG7o25nJykNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIGJp4buDdSBkaeG7hW4gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgdsOgIHPhuq9wIHRoZW8gdOG7q25nIG3DoHUgdOG7qyBEIHThu5tpIEo8cD4NCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB04buVbmcgdHLhu41uZyBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIG3DoHUgc+G6r2M6DQpgYGB7cn0NCmdncGxvdChULCBhZXMoeCA9IGNvbG9yLCB5ID0gY2FyYXQpKSArDQogIGdlb21fYmFyKHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9ICJzdW0iKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgY+G7mXQgaGnhu4NuIHRo4buLIHThu5VuZyBj4bunYSBiaeG6v24gY2FyYXQgdGhlbyB04burbmcgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY29sb3IuIE3hu5dpIGPhu5l0IHRyb25nIGJp4buDdSDEkeG7kyDEkeG6oWkgZGnhu4duIGNobyBt4buZdCBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciwgdsOgIGNoaeG7gXUgY2FvIGPhu6dhIGPhu5l0IGJp4buDdSB0aOG7iyBnacOhIHRy4buLIHThu5VuZyB0xrDGoW5nIOG7qW5nIGPhu6dhIGJp4bq/biBjYXJhdC48cD4NCg0KIyMgQmnhu4N1IMSR4buTIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1lYW4pIGPhu6dhIGJp4bq/biBwcmljZSB0aGVvIHThu6tuZyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQNCmBgYHtyfQ0KZ2dwbG90KFQsIGFlcyh4ID0gY3V0LCB5ID0gcHJpY2UpKSArDQogIGdlb21fYmFyKHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9ICJtZWFuIikNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIGPhu5l0IGhp4buDbiB0aOG7iyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biBwcmljZSB0aGVvIHThu6tuZyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjdXQuIE3hu5dpIGPhu5l0IHRyb25nIGJp4buDdSDEkeG7kyBiaeG7g3UgdGjhu4sgbeG7mXQgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0LCB2w6AgY2hp4buBdSBjYW8gY+G7p2EgY+G7mXQgYmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggdMawxqFuZyDhu6luZyBj4bunYSBiaeG6v24gcHJpY2UuPHA+DQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyBraW0gY8awxqFuZyBs4bubbiBuaOG6pXQgdGhlbyDEkeG7mSB0cm9uZzoNCmBgYHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGNsYXJpdHksIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gbWF4KQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgY+G7mXQgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IGPhu6dhIGJp4bq/biBwcmljZSB0aGVvIHThu6tuZyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbGFyaXR5LiBN4buXaSBj4buZdCB0cm9uZyBiaeG7g3UgxJHhu5MgYmnhu4N1IHRo4buLIG3hu5l0IGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNsYXJpdHksIHbDoCBjaGnhu4F1IGNhbyBj4bunYSBj4buZdCBiaeG7g3UgdGjhu4sgZ2nDoSB0cuG7iyBs4bubbiBuaOG6pXQgdMawxqFuZyDhu6luZyBj4bunYSBiaeG6v24gcHJpY2UuPHA+DQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyBraW0gY8awxqFuZyBuaOG7jyBuaOG6pXQgdGhlbyBtw6B1IHPhuq9jOg0KYGBge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY29sb3IsIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gbWluKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgY+G7mXQgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGPhu6dhIGJp4bq/biBwcmljZSB0aGVvIHThu6tuZyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvci4gTeG7l2kgY+G7mXQgdHJvbmcgYmnhu4N1IMSR4buTIGJp4buDdSB0aOG7iyBt4buZdCBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjb2xvciwgdsOgIGNoaeG7gXUgY2FvIGPhu6dhIGPhu5l0IGJp4buDdSB0aOG7iyBnacOhIHRy4buLIG5o4buPIG5o4bqldCB0xrDGoW5nIOG7qW5nIGPhu6dhIGJp4bq/biBwcmljZS48cD4NCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB04bu3IGzhu4cgY8OhYyBsb+G6oWkgY+G6r3Qga2ltIGPGsMahbmcgdGhlbyBtw6B1IHPhuq9jOg0KYGBge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY29sb3IsIGZpbGwgPSBjdXQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgY+G7mXQgaGnhu4NuIHRo4buLIHBo4bqnbiB0csSDbSB0xrDGoW5nIMSR4buRaSBj4bunYSB04burbmcgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0IHRoZW8gdOG7q25nIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLiBN4buXaSBj4buZdCB0cm9uZyBiaeG7g3UgxJHhu5MgYmnhu4N1IHRo4buLIG3hu5l0IGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNvbG9yLCB2w6AgbcOgdSBz4bqvYyBj4bunYSBjw6FjIHBo4bqnbiB0cm9uZyBj4buZdCBiaeG7g3UgdGjhu4sgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gY3V0Lg0KDQoNCg0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHThu5VuZyBnacOhIHRy4buLIGtpbSBjxrDGoW5nIHRoZW8gbG/huqFpIGPhuq90IHbDoCBtw6B1IHPhuq9jOg0KYGBge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY3V0LCBmaWxsID0gY29sb3IsIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0ID0gInN1bW1hcnkiLCBmdW4gPSAic3VtIikNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIG7DoHkgY2hvIHRo4bqleSB04buVbmcgZ2nDoSB0cuG7iyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBsb+G6oWkgY+G6r3QgdsOgIG3DoHUgc+G6r2MsIHbhu5tpIGPDoWMgY+G7mXQgxJHGsOG7o2MgeOG6v3AgY2jhu5NuZyBsw6puIG5oYXUuDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBraW0gY8awxqFuZyB0aGVvIGxv4bqhaSBj4bqvdCB2w6AgxJHhu5kgdHJvbmc6DQpgYGB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjdXQsIGZpbGwgPSBjbGFyaXR5LCB5ID0gcHJpY2UpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gIm1lYW4iKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgY+G7mXQsIHRyb25nIMSRw7MgbeG7l2kgY+G7mXQgYmnhu4N1IHRo4buLIG3hu5l0IGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGN1dC4gQ8OhYyBwaOG6p24gdHJvbmcgY+G7mXQgc+G6vSDEkcaw4bujYyB0w7QgbcOgdSB0aGVvIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIGNsYXJpdHksIHbDoCBjaGnhu4F1IGNhbyBj4bunYSBj4buZdCBiaeG7g3UgdGjhu4sgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24gcHJpY2UgdHJvbmcgbeG7l2kgbmjDs208cD4NCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8ga8OtY2ggdGjGsOG7m2MgdsOgIG3DoHUgc+G6r2M6IA0KYGBge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY2FyYXQsIGZpbGwgPSBjb2xvcikpICsNCiAgZ2VvbV9iYXIoYmlud2lkdGggPSAwLjUpDQpgYGANCjxwPkJp4buDdSDEkeG7kyBuw6B5IGNobyB0aOG6pXkgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGvDrWNoIHRoxrDhu5tjIHbDoCBtw6B1IHPhuq9jLCB24bubaSBjw6FjIGPhu5l0IMSRxrDhu6NjIG5ow7NtIGzhuqFpIHRoZW8ga2hv4bqjbmcga8OtY2ggdGjGsOG7m2MgMC41IHbDoCBtw6B1IHPhuq9jIHTGsMahbmcg4bupbmcuDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGvDrWNoIHRoxrDhu5tjIHbDoCBsb+G6oWkgY+G6r3Q6IA0KYGBge3J9DQpUNSA8LSBzdWJzZXQoVCwgY3V0ID09ICJJZGVhbCIgJiBjb2xvciA9PSAiSiIpDQpnZ3Bsb3QoVDUsIGFlcyh4ID0gY2FyYXQpKSArDQogIGdlb21fYmFyKGZpbGwgPSAibGlnaHR5ZWxsb3ciLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IGPhu6dhIGThu68gbGnhu4d1IGRpYW1vbmRzIChtw6B1IEopIiwNCiAgICAgICB4ID0gIkNhcmF0IiwNCiAgICAgICB5ID0gIlPhu5EgTMaw4bujbmciKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgbsOgeSBjaG8gdGjhuqV5IHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBsb+G6oWkgY+G6r3QgbMOgIElkZWFsIHbDoCBjw7MgbcOgdSBsw6AgSiwgduG7m2kgY8OhYyBj4buZdCDEkcaw4bujYyBuaMOzbSBs4bqhaSB0aGVvIMSR4buZIGzhu5tuIHTGsMahbmcg4bupbmcuDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBraW0gY8awxqFuZyB0aGVvIGxv4bqhaSBj4bqvdCB2w6AgbcOgdSBz4bqvYzogDQpgYGB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjdXQsIGZpbGwgPSBjb2xvciwgeSA9IHByaWNlKSkgKw0KICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gImJhciIpDQpgYGANCjxwPkJp4buDdSDEkeG7kyBuw6B5IGNobyB0aOG6pXkgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIHThu6tuZyBtw6B1IHPhuq9jIHbDoCBsb+G6oWkgY+G6r3QsIHbhu5tpIGPDoWMgY+G7mXQgxJHGsOG7o2MgeOG6v3AgY2jhu5NuZyBsw6puIG5oYXUuDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBraW0gY8awxqFuZyB0aGVvIG3DoHUgc+G6r2MgdsOgIMSR4buZIHRyb25nOg0KYGBge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY29sb3IsIGZpbGwgPSBjbGFyaXR5LCB5ID0gcHJpY2UpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gIm1lYW4iKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgbsOgeSBjaG8gdGjhuqV5IGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyB04burbmcgbcOgdSBz4bqvYyB2w6AgxJHhu5kgdHJvbmcsIHbhu5tpIGPDoWMgY+G7mXQgxJHGsOG7o2MgeOG6v3AgY2jhu5NuZyBsw6puIG5oYXUuPHA+DQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGvDrWNoIHRoxrDhu5tjIHbDoCBtw6B1IHPhuq9jOg0KYGBge3J9DQpUNCA8LSBzdWJzZXQoVCxjb2xvciA9PSAiSiIsIGRlcHRoKQ0KZ2dwbG90KFQ0LCBhZXMoeCA9IGRlcHRoKSkgKw0KICBnZW9tX2JhcihmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAxKSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IGPhu6dhIGThu68gbGnhu4d1IGRpYW1vbmRzIiwNCiAgICAgICB4ID0gIkRlcHRoIiwNCiAgICAgICB5ID0gIlPhu5EgbMaw4bujbmciKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgbsOgeSBjaG8gdGjhuqV5IHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY8OzIG3DoHUgc+G6r2MgbMOgIEogdGhlbyBsb+G6oWkgRGVwdGggdsOgIGPDoWMgY+G7mXQgxJHGsOG7o2MgbmjDs20gbOG6oWkgDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyB0aGVvIGJp4bq/biBDYXJhdA0KYGBge3J9DQpUJGNhcmF0IDwtIGFzLm51bWVyaWMoVCRjYXJhdCkNClQgPC0gVCAlPiUgbXV0YXRlKGNhcmF0QyA9IGN1dChjYXJhdCwgYnJlYWtzID0gYygwLCAwLjUsIDEsIDEuNSwgMiwgSW5mKSwgDQogICAgICAgICAgICBsYWJlbHMgPSBjKCdy4bqldCBuaOG7jycsICduaOG7jycsICd24burYScsICds4bubbicsICdy4bqldCBs4bubbicpKSkgDQpUICU+JSBnZ3Bsb3QoYWVzKHggPSBjYXJhdEMpKSArDQogIGdlb21fYmFyKGZpbGwgPSAnbGlnaHRibHVlJykNCmBgYA0KPHA+Qmnhu4N1IMSR4buTIGPhu5l0LCB0cm9uZyDEkcOzIG3hu5dpIGPhu5l0IGJp4buDdSB0aOG7iyBt4buZdCBuaMOzbSBk4buxYSB0csOqbiBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjYXJhdC4gTcOgdSBz4bqvYyBj4bunYSBjw6FjIGPhu5l0IHPhur0gbMOgICdsaWdodGJsdWUnLjxwPg0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyDEkeG7mSB0cm9uZw0KYGBge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY2xhcml0eSkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IGPhu6dhIGThu68gbGnhu4d1IGRpYW1vbmRzIiwNCiAgICAgICB4ID0gIkNsYXJpdHkiLA0KICAgICAgIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCjxwPmJp4buDdSDEkeG7kyBj4buZdCB24bubaSBjw6FjIGPhu5l0IMSRxrDhu6NjIHTDtCBtw6B1ICJzdGVlbGJsdWUiLCBjw7Mgdmnhu4FuIG3DoHUgxJFlbiB2w6AgbeG7nS4gVGnDqnUgxJHhu4EgY+G7p2EgYmnhu4N1IMSR4buTIGzDoCAiQmnhu4N1IMSR4buTIGPhu5l0IGPhu6dhIGThu68gbGnhu4d1IGRpYW1vbmRzIiwgdHLhu6VjIHggY8OzIG5ow6NuICJDbGFyaXR5IiB2w6AgdHLhu6VjIHkgY8OzIG5ow6NuICJT4buRIGzGsOG7o25nIi4gR2lhbyBkaeG7h24gY+G7p2EgYmnhu4N1IMSR4buTIGzDoCB04buRaSBnaeG6o24uPHA+DQoNCiMjIEJp4buDdSDEkeG7kyB0cnVuZyBiw6xuaCB0cuG7jW5nIGzGsOG7o25nIGRpYW1vbmQgdGhlbyBtw6B1IHPhuq9jDQpgYGB7cn0NClQgJT4lIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBjdXQsIGZpbGwgPSBjb2xvcikpICsNCiAgZ2VvbV9iYXIoKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNvcnQodW5pcXVlKGRpYW1vbmRzJGNvbG9yKSkpKw0KICAgbGFicyh0aXRsZSA9ICJCaeG7g3UgxJHhu5Mgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjaGlhIHRoZW8gbcOgdSBz4bqvYyIseCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKQ0KYGBgDQo8cD5CaeG7g3UgxJHhu5MgY+G7mXQgduG7m2kgY8OhYyBj4buZdCBiaeG7g3UgdGjhu4sgc+G7kSBsxrDhu6NuZyB0aGVvIGJp4bq/biBjdXQsIHbDoCBtw6B1IHPhuq9jIGPhu6dhIGPDoWMgY+G7mXQgc+G6vSDEkcaw4bujYyB4w6FjIMSR4buLbmggYuG7n2kgYmnhur9uIGNvbG9yLiBHacOhIHRy4buLIG3DoHUgc+G6r2MgxJHGsOG7o2Mgc+G6r3AgeOG6v3AgdGhlbyB0aOG7qSB04buxIHTEg25nIGThuqduLiBUacOqdSDEkeG7gSBj4bunYSBiaeG7g3UgxJHhu5MgbMOgICJCaeG7g3UgxJHhu5Mgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjaGlhIHRoZW8gbcOgdSBz4bqvYyIsIHRy4bulYyB4IGPDsyBuaMOjbiAiTG/huqFpIiB2w6AgdHLhu6VjIHkgY8OzIG5ow6NuICJT4buRIGzGsOG7o25nIi48cD4NCg0KIyMgQmnhu4N1IMSR4buTIHRydW5nIGLDrG5oIHRy4buNbmcgbMaw4bujbmcgZGlhbW9uZCB0aGVvIG3DoHUgc+G6r2MNCmBgYHtyfQ0KVCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobT0gbWVhbihjYXJhdCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBjb2xvcix5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAnZ3JlZW4nKSArDQogICAgbGFicyh0aXRsZSA9ICJCaeG7g3UgxJHhu5MgbWVhbiBj4bunYSBraW0gY8awxqFuZyB0aGVvIG3DoHUgc+G6r2MiLHggPSAnTcOgdScsIHkgPSAnTWVhbicpDQpgYGANCjxwPkJp4buDdSDEkeG7kyBj4buZdCB24bubaSBjw6FjIGPhu5l0IGJp4buDdSB0aOG7iyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biBjYXJhdCB0aGVvIHThu6tuZyBtw6B1IHPhuq9jLiBDw6FjIGPhu5l0IHPhur0gxJHGsOG7o2MgeOG6v3AgY2jhu5NuZyBsw6puIG5oYXUuIFbEg24gYuG6o24gduG7m2kgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIHPhur0gxJHGsOG7o2MgaGnhu4NuIHRo4buLIHRyw6puIGPDoWMgY+G7mXQgdsOgIGPDsyBtw6B1IHPhuq9jIHhhbmggbMOhIGPDonkuIFRpw6p1IMSR4buBIGPhu6dhIGJp4buDdSDEkeG7kyBsw6AgIkJp4buDdSDEkeG7kyBtZWFuIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gbcOgdSBz4bqvYyIsIHRy4bulYyB4IGPDsyBuaMOjbiAiTcOgdSIgdsOgIHRy4bulYyB5IGPDsyBuaMOjbiAiTWVhbiIuPHA+DQoNCiMjIEJp4buDdSDEkeG7kyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IHbDoCDEkeG7mSB0cm9uZyBzdeG7kXQgdGhlbyB04burbmcgbcOgdSB44bq/cCBj4bqhbmggbmhhdQ0KYGBge3J9DQpnZ3Bsb3QoZGF0YT0gVCkgKw0KICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBjdXQsIGZpbGwgPSBjbGFyaXR5KSwgcG9zaXRpb24gPSAiZG9kZ2UiKQ0KDQpgYGANCjxwPkJp4buDdSDEkeG7kyBj4buZdCB24bubaSBjw6FjIGPhu5l0IGJp4buDdSB0aOG7iyBz4buRIGzGsOG7o25nIHRoZW8gYmnhur9uIGN1dC4gTcOgdSBz4bqvYyBj4bunYSBjw6FjIGPhu5l0IHPhur0gxJHGsOG7o2MgeMOhYyDEkeG7i25oIGLhu59pIGJp4bq/biBjbGFyaXR5LiBDw6FjIGPhu5l0IHPhur0gxJHGsOG7o2MgeOG6v3AgY2jhu5NuZyBsw6puIG5oYXUgdGhlbyB04burbmcgbmjDs20gYmnhur9uIGN1dC48cD4NCg0KIyMgQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcgdGhlbyB04burbmcgbG/huqFpIENsYXJpdHkgY+G7p2Ega2ltIGPGsMahbmcgY8OzIG3DoHUgRA0KYGBge3J9DQpUMiA8LSBzdWJzZXQoVCwgY29sb3IgPT0gIkQiKQ0KZ2dwbG90KFQyLCBhZXMoeCA9IGNsYXJpdHkpKSArDQogIGdlb21fYmFyKGZpbGwgPSAibGlnaHR5ZWxsb3ciLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIGPhu5l0IGPhu6dhIGThu68gbGnhu4d1IGRpYW1vbmRzIChtw6B1IEQpIiwNCiAgICAgICB4ID0gIkNsYXJpdHkiLA0KICAgICAgIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCjxwPiBCaeG7g3UgxJHhu5MgdHLDqm4gY3VuZyBj4bqlcCBjaG8gdGEgdGjhuqV5IMSRxrDhu6NjIHPhu5EgbMaw4bujbmcgY+G7p2EgY8OhaSB2acOqbiBraW0gY8awxqFuZyBjw7MgbcOgdSBsw6AgRCB0aGVvIHThu6tuZyBsb+G6oWkgQ2xhcml0eSBraMOhYyBuaGF1IA0KDQoNCiMjIEJp4buDdSDEkeG7kyBz4buRIGzGsOG7o25nIHRoZW8gdOG7q25nIGxv4bqhaSBDbGFyaXR5IGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBtw6B1IEkNCmBgYHtyfQ0KVDMgPC0gc3Vic2V0KFQsIGNvbG9yID09ICJJIikNCmdncGxvdChUMywgYWVzKHggPSBjbGFyaXR5KSkgKw0KICBnZW9tX2JhcihmaWxsID0gImxpZ2h0cGluayIsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjgpICsNCiAgbGFicyh0aXRsZSA9ICJCaeG7g3UgxJHhu5MgY+G7mXQgY+G7p2EgZOG7ryBsaeG7h3UgZGlhbW9uZHMgKG3DoHUgSSkiLA0KICAgICAgIHggPSAiQ2xhcml0eSIsDQogICAgICAgeSA9ICJT4buRIGzGsOG7o25nIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KPHA+IEJp4buDdSDEkeG7kyB0csOqbiBjdW5nIGPhuqVwIGNobyB0YSB0aOG6pXkgxJHGsOG7o2Mgc+G7kSBsxrDhu6NuZyBj4bunYSBjw6FpIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBtw6B1IGzDoCBJIHRoZW8gdOG7q25nIGxv4bqhaSBDbGFyaXR5IGtow6FjIG5oYXUgDQo=