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=