Phân tích dữ
liệu
Gọi bộ dữ liệu ggplot2 để dùng hiệu quả hơn cho các phép
tính
options(repos = c(CRAN = "http://cran.rstudio.com/"))
install.packages("ggplot2")
## Installing package into 'C:/Users/a/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'ggplot2' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\a\AppData\Local\Temp\Rtmp21MBeg\downloaded_packages
library(ggplot2)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(scales)
library(DT)
Trước hết tôi sẽ gán bộ dữ liệu cho biến cụ thể
ck <- ChickWeight
Biểu đồ thể hiện số
lượng gà theo Diet
ck %>% group_by(Diet) %>% summarise(n = n()) %>%
ggplot( aes( x = as.factor(Diet), y = n)) +
geom_col(fill = 'skyblue') +
geom_text(aes(label = n), vjust = 1, color = 'red') +
xlab('Số thứ tự Chick') +
ylab('Số lượng gà') +
labs(title = 'Biểu đồ số lượng gà theo loại khẩu phần của gà con')

- Nhìn vào ta thấy biểu đồ thể hiện số lượng gà con trên mỗi chế độ
dinh dưỡng
- Loại dinh dưỡng 1 nhiều nhất có 220 con, loại 2 có 120 con, loại 3
có 120 con, loại 4 có 118 con là ít nhất nhưng không đáng kể
Biểu đồ thể hiện
Trọng lượng gà trung bình theo Diet
ck %>% group_by(Diet) %>% summarise(avg = mean(weight)) %>%
ggplot(aes(x = as.factor(Diet), y = avg)) +
geom_col(fill = 'yellow') +
geom_text(aes(label = round(avg,2)), vjust = 1, color = 'red') +
labs( x = 'loại Diet', y = 'Trọng lượng gà con trung bình (gram)', title = 'trọng lượng gà con trung bình theo Diet') +
coord_flip()

- Biểu đồ thể hiện trọng lượng gà trung bình theo từng loại Diet
- Loại 1 thấp nhất với trọng lượng trung bình xấp xỉ 102.65, tiếp đó
là loại 2 là 122.52, loại 4 là 135.26 và cao nhất là loại 4 với trọng
lượng trung bình đạt 142.95
Biểu độ phân tích
trung tâm cân nặng ( theo từng Diet)
ck %>% group_by(Diet) %>% summarise(m= median(weight)) %>%
ggplot(aes(x = Diet,y = m)) +
geom_col(position = 'dodge', fill = 'pink', color = 'black') +
geom_text(aes(label = round(m,2)), vjust = 2, color = 'red') +
labs(x = 'Loại dinh dưỡng', y = 'Trung vị', title ='Trung vị theo cân nặng từng loại dinh dưỡng')

- Biểu độ cho ta thấy được trung vị, từng có 50% phần tử bên trong nhỏ
hơn và số còn lại lớn hơn. Tức với mỗi từng loại dinh dưỡng, trung vị
theo cân nặng sẽ khác nhau.
- với loại dinh dưỡng 1, có khoảng 50% số kg được ghi nhận là nhỏ hơn
88, 50% số kg được ghi nhân là lớn hơn 88, theo đó thi loại 2 là 104.5,
loại 3 là 125.5 và loại dinh dưỡng 4 là 129.5
Biểu đồ thể hiện
tương quan giữa weight và Diet
ck %>% ggplot(aes(x = weight, y = Time, color = Diet)) +
geom_point() +
labs( x = 'cân nặng gà con', y = 'Thời gian quan sát', title = 'Tương quan giữa gà con và cân nặng theo loại dinh dưỡng')

- Biểu độ cho ta thấy tượng quan giữa cân nặng gà con theo thời gian
quan sát chúng theo từng loại dinh dưỡng
- Ta thấy được cân nặng gà con càng lớn thì thòi gian quan sát cũng
phải lâu, tùy theo loại dinh dưỡng có ảnh hưởng tới cân nặng của gà
con
- Mật độ dinh dưỡng của loại 4, 1 phân bổ rất dày với gà con trong
khoảng 0 đến 200 gam.
Biểu đồ thể hiện số
lượng Diet theo Pie chart
ck %>% group_by(Diet) %>% summarise(n=n()) %>%
ggplot(aes(x= '', y=n, fill = Diet))+
geom_col(color = 'black', width = 1) +
coord_polar('y') +
geom_text(aes(x = 1.4, label = n), position = position_stack(vjust = .5)) +
labs( title = 'Số lượng Diet') +
theme_void()

- Biểu đồ cho ta thấy số lượng gà con của từng loại dinh dưỡng nhưng ở
dạng Pie chart
- với loại 1 là 220 con là lớn nhất và loại 4 là ít nhất với 118
con
Biểu đồ density thể
hiện weight và Diet theo số lượng
ck %>% ggplot( aes(x = weight, fill = as.factor(Diet))) +
geom_density(alpha = 0.5) +
labs(title = "Density plot của trọng lượng gà con theo loại khẩu phần", x = "Trọng lượng (grams)", y = "Mật độ") +
scale_fill_discrete(name = "Loại khẩu phần")

- Biểu đồ cho ta thấy sự phân bố trọng lượng trong mỗi nhóm với từng
loại khẩu phần dinh dưỡng cho gà con riêng biệt
- Mật độ loại một chiếm rất cao và dày trong khoảng từ 100 đến nửa
200g rồi làm giảm một cách rõ rệt, tiếp đó là loại 2 và xuống lần tới
loại 3,4
- Khoang có sự chênh lệnh quá lớn từ khoảng nửa 100 đến 200g trở đi
của khẩu phần 1, 2, 3, Loại dinh dưỡng 4 ảnh hưởng lớn đến cân nặng từ
100 đến 200g của gà con
Biểu đồ thể hiện mật
độ trọng trọng lượng gà con (Density plot)
ck %>% ggplot( aes(x = weight, fill = as.factor(Diet))) +
geom_density(alpha = 0.5) +
facet_wrap(~Diet) +
labs(title = "Density plot của trọng lượng gà con theo loại khẩu phần", x = "Trọng lượng (grams)", y = "Mật độ") +
scale_fill_discrete(name = "Loại khẩu phần")

- Tương tự như biểu đồ trên, mỗi phần nhỏ chỉ ra mật độ trọng lượng
khi cho các loại khẩu phần riêng biệt đối với gà con
- Loại khẩu phần 1 với trọng lượng gà con 100g đổ lại rất nhiều
Biểu đồ thể hiện số
lượng gà theo Diet
ck %>% group_by(Diet) %>% summarise(n = n()) %>%
ggplot(aes(x = '', y = n,fill = Diet)) +
geom_col( color = 'black' ) +
geom_text(aes(label = n),position = position_stack(vjust = 1)) +
labs( y = 'số lượng', title = 'số lượng gà con cho mỗi chế độ dinh dưỡng')

- Biểu đồ thể hiện cho ta thấy số lượng gà con theo từng loại dinh
dưỡng, các số liệu được chồng theo một cột và tùy theo số lượng mà độ
dày khác nhau
- Loại dinh dưỡng 1 có độ dày chiếm ưu thế, số lượng nhiều nhất, 3
loại kia không chênh lệch đáng kể
Biểu đồ thể hiện
tương quan giữa cân nặng gà con và loại dinh dưỡng theo Diet
ck %>% ggplot(aes(x = weight, y = Time, color = Diet)) +
geom_point() +
labs( x = 'cân nặng gà con', y = 'Thời gian quan sát', title = 'Tương quan giữa gà con và cân nặng theo loại dinh dưỡng') +
geom_smooth(method = 'lm', color = 'black')
## `geom_smooth()` using formula = 'y ~ x'

- Đường trend line có xu hướng lên trên, mối tương quan dương giữa các
dữ liệu
- Với cân nặng gà con lớn, phải bổ sung dinh dưỡng theo đó mà thời
gian quan sát cũng sẽ phải tăng lên
Biểu đồ thể hiện tỷ
lệ dinh dưỡng theo Diet
ck %>% group_by(Diet) %>% summarise(n = n()) %>%
ggplot(aes(Diet,n)) +
geom_col(fill='green') +
geom_text(aes(label = percent(n/length(ck$Diet))),vjust = 2, color = 'red') +
labs(x = 'Loại dinh dưỡng', y = 'Số lượng', title = 'Tỷ lệ loại dinh dưỡng')

- Biểu đồ cho ta thấy phần trăm số lượng gà con trong mỗi loại dinh
dưỡng được nuôi
- Loại dinh dưỡng số 1 có số lượng gà con chiếm 38.6%, loại dinh dưỡng
số 2,3 có 20.76% tổng số lượng gà con, còn lại là loại dinh dưỡng số 4
số lượng gà con chiếm 20.42%.
Biểu đồ thể hiện
Tương quan giữa cân nặng gà con và thời gian quan sát theo loại
Diet
ck %>% ggplot(aes(x = weight, y = Time, color = Diet)) +
geom_point() +
labs( x = 'cân nặng gà con', y = 'Thời gian quan sát', title = 'Tương quan giữa gà con và cân nặng theo loại dinh dưỡng') +
geom_smooth(method = 'lm', color = 'green') +
facet_wrap(~Diet)
## `geom_smooth()` using formula = 'y ~ x'

- Cân nặng gà con tùy theo từng loại dinh dưỡng có xu hướng tăng theo
thời gian quan sát
Biểu đồ thể hiện
lượng cân nặng trung bình theo Diet ( Dạng Pie )
ck %>% group_by(Diet) %>% summarise(n=mean(weight)) %>%
ggplot(aes(x= '', y=n, fill = Diet))+
geom_col(color = 'black', width = 1) +
coord_polar('y') +
geom_text(aes(x = 1.3, label = round(n,2)), position = position_stack(vjust = .5)) +
labs( title = 'Trọng lượng trung bình') +
theme_void()

- Biểu đồ thể hiện trọng lượng gà con trung bình theo từng loại dinh
dưỡng
- Loại 1 có trọng lượng trung bình là 102.65, loại 2 là 122.62, loại 3
là 142.95, loại 4 là 135.26
Biểu đồ thể hiện
thời gian trung bình theo Diet ( dạng Pie )
ck %>% group_by(Diet) %>% summarise(n=mean(Time)) %>%
ggplot(aes(x= '', y=n, fill = Diet))+
geom_col(color = 'black', width = 1) +
coord_polar('y') +
geom_text(aes(x = 1.3, label = round(n,2)), position = position_stack(vjust = .5)) +
labs( title = 'Thời gian trung bình') +
theme_bw()

- Thời gian quan sát trung bình của gà con theo từng loại dinh
dưỡng
- Loại dinh dưỡng 1 có thời gian quan sát trung bình là 10.48, loại 2
là 10.92, loại 3 là 10.92 còn loại 4 là 10.75
Biểu đồ thể hiện tần
suất xuất hiện trọng lượng gà con
ck %>% ggplot(aes(x = weight)) +
geom_histogram(binwidth = 50, fill = "skyblue", color = "black", aes(y=..count..)) +
labs(x = "Trọng lượng (g)", y = "Tần suất") +
ggtitle("Phân phối của trọng lượng gà con") +
theme_bw()

- Biểu đồ cho thấy tần suất suất hiện các chỉ số trọng lượng gà
con
- tần suất xuất hiện của trọng lượng dưới 100g xuất hiện nhiều nhất
hơn 200 lần và giảm dần
Biểu đồ phân phối
trong lượng gà con với tần suất (theo Diet)
ck %>% ggplot(aes(x = weight)) +
geom_histogram(binwidth = 50, fill = "skyblue", color = "black", aes(y=..count..)) +
labs(x = "Trọng lượng (g)", y = "Tần suất") +
facet_wrap(~Diet) +
ggtitle("Phân phối của trọng lượng gà con")

- Biểu đồ cho ra thấy chỉ số xuất hiện của các chỉ số trọng lượng gà
con được phân ra theo loại dinh dưỡng
Biểu đồ thể hiện tần
suất xuất hiện các mốc thời gian quan sát
ck %>% ggplot(aes(x = Time)) +
geom_histogram(binwidth = 3, fill = "red", color = "black", aes(y=..count..)) +
labs(x = "Thời gian (h)", y = "Tần suất") +
ggtitle("Phân phối của thời gian theo dõi gà con") +
theme_bw()

- Biểu đố cho ta thấy các tần suất các khoảng thời gian xuất hiện
- Khoảng thời gian xuất hiện nhiều nhất từ 0 đến 5 và giảm dần về
20
Biểu đồ thể hiện
trọng lượng gà con theo thời gian (line)
ggplot(ChickWeight, aes(x = Time, y = weight, color = Chick)) +
geom_line() +
labs(x = "Thời gian (ngày)", y = "Trọng lượng (g)", color = "Gà") +
ggtitle("Biểu đồ đường của trọng lượng gà theo thời gian") +
theme_bw()

Biểu đồ thể hiện mật
độ của trọng lượng gà ( violin plot)
ck %>% ggplot(aes(x = as.factor(Diet), y = weight, fill = as.factor(Diet))) +
geom_violin() +
labs(x = "chế độ dinh dưỡng", y = "Trọng lượng (g)") +
ggtitle("Biểu đồ violin plot của trọng lượng gà") +
theme_bw()

- Biểu đồ cho ta thấy mật độ phân phối của trọng lượng các gà con theo
từng chế độ dinh dưỡng
- ở chế độ dinh dưỡng 1 thì có mật độ phân phối trọng lượng dưới 100g
nhiều nhất, cả 4 loại đều có xu hướng giảm dần, trọng lượng các lớn thì
càng ít, lớn nhất có thể đạt được ở khẩu phần dinh dưỡng số 3
Biểu đồ thể hiện mật
độ trọng lượng qua các mốc
ck %>%
ggplot(aes(x = Time, y = weight)) +
geom_violin(fill = "skyblue", color = "black") +
labs(x = "Thời gian", y = "Trọng lượng (g)",
title = "Sự phát triển của trọng lượng gà con theo thời gian") +
theme_bw()

- Biểu đồ cho ta thấy mật độ phân phối của trọng lượng, trọng lượng
càng lớn và ít
Biểu đồ phân phối
trọng lượng dạng Boxplot
ck %>% ggplot(aes(x = factor(Diet), y = weight, fill = factor(Diet))) +
geom_boxplot() +
labs(x = "Loại khẩu phần", y = "Trọng lượng gà con", fill = "Loại khẩu phần") +
ggtitle("Biểu đồ Boxplot của trọng lượng gà con theo loại khẩu phần")

- Biểu đồ cho thấy các giá trị như trung vị, tứ phân vị và các giá trị
ngoại vi có thể xuất hiện
LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSA1Ig0KYXV0aG9yOiAiTMO9IFbEqW5oIE5naGkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdG9jOiB0cnVlDQogIHdvcmRfZG9jdW1lbnQ6DQogICAgIHRvYzogdHJ1ZQ0KICAgICB0b2NfZGVwdGg6ICcyJw0KICBwZGZfZG9jdW1lbnQ6DQogICAgbGF0ZXhfZW5naW5lOiB4ZWxhdGV4DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyAqVOG7lW5nIHF1YW4gduG7gSBi4buZIGThu68gbGnhu4d1Kg0KDQoNCi0gQuG7mSBk4buxIGxp4buHdSAqQ2hpY2tlbldlaWdodCogYmFvIGfhu5NtIGPDoWMgY+G7mXQgc2F1Og0KICAgDQogICAtICBXZWlnaHQgKFRy4buNbmcgbMaw4bujbmcpOiBCaeG6v24gbsOgeSDEkW8gbMaw4budbmcgdHLhu41uZyBsxrDhu6NuZyBj4bunYSBnw6AgY29uIHbDoCDEkcaw4bujYyBnaGkgbOG6oWkgYuG6sW5nIMSRxqFuIHbhu4sgZ3JhbXMuIFRy4buNbmcgbMaw4bujbmcgY+G7p2EgZ8OgIGNvbiDEkcaw4bujYyB0aGVvIGTDtWkgcXVhIHRo4budaSBnaWFuIMSR4buDIMSRbyBsxrDhu51uZyBz4buxIHBow6F0IHRyaeG7g24gdsOgIHTEg25nIHRyxrDhu59uZyBj4bunYSBjaMO6bmcuDQoNCiAgIC0gIFRpbWUgKFRo4budaSBnaWFuKTogQmnhur9uIG7DoHkgdGjhu4MgaGnhu4duIHRo4budaSBnaWFuIHF1YW4gc8OhdCwgdGjGsOG7nW5nIMSRxrDhu6NjIMSRbyBi4bqxbmcgxJHGoW4gduG7iyBuZ8OgeS4gTsOzIGNobyBiaeG6v3Qga2hv4bqjbmcgdGjhu51pIGdpYW4gbcOgIG3hu5dpIHF1YW4gc8OhdCB0cuG7jW5nIGzGsOG7o25nIMSRxrDhu6NjIHRo4buxYyBoaeG7h24uDQoNCiAgIC0gIENoaWNrIChDb24gZ8OgKTogxJDDonkgbMOgIHPhu5EgdGjhu6kgdOG7sSBj4bunYSB04burbmcgY29uIGfDoCB0cm9uZyBi4buZIGThu68gbGnhu4d1LiBN4buXaSBjb24gZ8OgIGPDsyBt4buZdCBz4buRIHRo4bupIHThu7EgZHV5IG5o4bqldCDEkeG7gyBwaMOibiBiaeG7h3QgY2jDum5nLg0KDQogICAtICBEaWV0IChDaOG6vyDEkeG7mSBkaW5oIGTGsOG7oW5nKTogQmnhur9uIG7DoHkgY2jhu4kgcmEgbG/huqFpIGNo4bq/IMSR4buZIGRpbmggZMaw4buhbmcgbcOgIG3hu5dpIGNvbiBnw6AgxJHGsOG7o2MgY3VuZyBj4bqlcC4gQ8OzIGLhu5FuIGxv4bqhaSBjaOG6vyDEkeG7mSBkaW5oIGTGsOG7oW5nIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UsIHRoxrDhu51uZyDEkcaw4bujYyDEkcOhbmggc+G7kSB04burIDEgxJHhur9uIDQuDQogICANCiMgKlBow6JuIHTDrWNoIGThu68gbGnhu4d1Kg0KDQpH4buNaSBi4buZIGThu68gbGnhu4d1ICpnZ3Bsb3QyKiDEkeG7gyBkw7luZyBoaeG7h3UgcXXhuqMgaMahbiBjaG8gY8OhYyBwaMOpcCB0w61uaA0KDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0Kb3B0aW9ucyhyZXBvcyA9IGMoQ1JBTiA9ICJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCmluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShEVCkNCmBgYA0KDQpUcsaw4bubYyBo4bq/dCB0w7RpIHPhur0gZ8OhbiBi4buZIGThu68gbGnhu4d1IGNobyBiaeG6v24gY+G7pSB0aOG7gw0KDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgPC0gQ2hpY2tXZWlnaHQNCmBgYA0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgZ8OgIHRoZW8gRGlldA0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KDQpjayAgJT4lIGdyb3VwX2J5KERpZXQpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIA0KIGdncGxvdCggYWVzKCB4ID0gYXMuZmFjdG9yKERpZXQpLCB5ID0gbikpICsgDQogIGdlb21fY29sKGZpbGwgPSAnc2t5Ymx1ZScpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgdmp1c3QgPSAxLCBjb2xvciA9ICdyZWQnKSArIA0KICB4bGFiKCdT4buRIHRo4bupIHThu7EgQ2hpY2snKSArIA0KICB5bGFiKCdT4buRIGzGsOG7o25nIGfDoCcpICsgDQogIGxhYnModGl0bGUgPSAnQmnhu4N1IMSR4buTIHPhu5EgbMaw4bujbmcgZ8OgIHRoZW8gbG/huqFpIGto4bqpdSBwaOG6p24gY+G7p2EgZ8OgIGNvbicpIA0KYGBgDQogDQotIE5ow6xuIHbDoG8gdGEgdGjhuqV5IGJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBnw6AgY29uIHRyw6puIG3hu5dpIGNo4bq/IMSR4buZIGRpbmggZMaw4buhbmcNCi0gTG/huqFpIGRpbmggZMaw4buhbmcgMSBuaGnhu4F1IG5o4bqldCBjw7MgMjIwIGNvbiwgbG/huqFpIDIgY8OzIDEyMCBjb24sIGxv4bqhaSAzIGPDsyAxMjAgY29uLCBsb+G6oWkgNCBjw7MgMTE4IGNvbiBsw6Agw610IG5o4bqldCBuaMawbmcga2jDtG5nIMSRw6FuZyBr4buDDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gVHLhu41uZyBsxrDhu6NuZyBnw6AgdHJ1bmcgYsOsbmggdGhlbyBEaWV0DQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShhdmcgPSBtZWFuKHdlaWdodCkpICU+JSANCiAgIGdncGxvdChhZXMoeCA9IGFzLmZhY3RvcihEaWV0KSwgeSA9IGF2ZykpICsgDQogIGdlb21fY29sKGZpbGwgPSAneWVsbG93JykgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGF2ZywyKSksIHZqdXN0ID0gMSwgY29sb3IgPSAncmVkJykgKyANCiAgbGFicyggeCA9ICdsb+G6oWkgRGlldCcsIHkgPSAnVHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIHRydW5nIGLDrG5oICAoZ3JhbSknLCB0aXRsZSA9ICd0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdHJ1bmcgYsOsbmggdGhlbyBEaWV0JykgKyANCiAgY29vcmRfZmxpcCgpIA0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB0cuG7jW5nIGzGsOG7o25nIGfDoCB0cnVuZyBiw6xuaCB0aGVvIHThu6tuZyBsb+G6oWkgRGlldA0KLSBMb+G6oWkgMSB0aOG6pXAgbmjhuqV0IHbhu5tpIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggeOG6pXAgeOG7iSAxMDIuNjUsIHRp4bq/cCDEkcOzIGzDoCBsb+G6oWkgMiBsw6AgMTIyLjUyLCBsb+G6oWkgNCBsw6AgMTM1LjI2IHbDoCBjYW8gbmjhuqV0IGzDoCBsb+G6oWkgNCB24bubaSB0cuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oIMSR4bqhdCAxNDIuOTUNCg0KIyMgQmnhu4N1IMSR4buZIHBow6JuIHTDrWNoIHRydW5nIHTDom0gY8OibiBu4bq3bmcgKCB0aGVvIHThu6tuZyBEaWV0KQ0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdyb3VwX2J5KERpZXQpICU+JSBzdW1tYXJpc2UobT0gbWVkaWFuKHdlaWdodCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gRGlldCx5ID0gbSkpICsgDQogIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbCA9ICdwaW5rJywgY29sb3IgPSAnYmxhY2snKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdyZWQnKSArIA0KICBsYWJzKHggPSAnTG/huqFpIGRpbmggZMaw4buhbmcnLCB5ID0gJ1RydW5nIHbhu4snLCB0aXRsZSA9J1RydW5nIHbhu4sgdGhlbyBjw6JuIG7hurduZyB04burbmcgbG/huqFpIGRpbmggZMaw4buhbmcnKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buZIGNobyB0YSB0aOG6pXkgxJHGsOG7o2MgdHJ1bmcgduG7iywgdOG7q25nIGPDsyA1MCUgcGjhuqduIHThu60gYsOqbiB0cm9uZyBuaOG7jyBoxqFuIHbDoCBz4buRIGPDsm4gbOG6oWkgbOG7m24gaMahbi4gVOG7qWMgduG7m2kgbeG7l2kgdOG7q25nIGxv4bqhaSBkaW5oIGTGsOG7oW5nLCB0cnVuZyB24buLIHRoZW8gY8OibiBu4bq3bmcgc+G6vSBraMOhYyBuaGF1Lg0KLSB24bubaSBsb+G6oWkgZGluaCBkxrDhu6FuZyAxLCBjw7Mga2hv4bqjbmcgNTAlIHPhu5Ega2cgxJHGsOG7o2MgZ2hpIG5o4bqtbiBsw6Agbmjhu48gaMahbiA4OCwgNTAlIHPhu5Ega2cgxJHGsOG7o2MgZ2hpIG5ow6JuIGzDoCBs4bubbiBoxqFuIDg4LCB0aGVvIMSRw7MgdGhpIGxv4bqhaSAyIGzDoCAxMDQuNSwgbG/huqFpIDMgbMOgIDEyNS41IHbDoCBsb+G6oWkgZGluaCBkxrDhu6FuZyA0IGzDoCAxMjkuNQ0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHTGsMahbmcgcXVhbiBnaeG7r2Egd2VpZ2h0IHbDoCBEaWV0DQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ2dwbG90KGFlcyh4ID0gd2VpZ2h0LCB5ID0gVGltZSwgY29sb3IgPSBEaWV0KSkgKyANCiAgZ2VvbV9wb2ludCgpICsNCiAgbGFicyggeCA9ICdjw6JuIG7hurduZyBnw6AgY29uJywgeSA9ICdUaOG7nWkgZ2lhbiBxdWFuIHPDoXQnLCB0aXRsZSA9ICdUxrDGoW5nIHF1YW4gZ2nhu69hIGfDoCBjb24gdsOgIGPDom4gbuG6t25nIHRoZW8gbG/huqFpIGRpbmggZMaw4buhbmcnKSANCmBgYA0KDQotICBCaeG7g3UgxJHhu5kgY2hvIHRhIHRo4bqleSB0xrDhu6NuZyBxdWFuIGdp4buvYSBjw6JuIG7hurduZyBnw6AgY29uIHRoZW8gdGjhu51pIGdpYW4gcXVhbiBzw6F0IGNow7puZyB0aGVvIHThu6tuZyBsb+G6oWkgZGluaCBkxrDhu6FuZw0KLSAgVGEgdGjhuqV5IMSRxrDhu6NjIGPDom4gbuG6t25nIGfDoCBjb24gY8OgbmcgbOG7m24gdGjDrCB0aMOyaSBnaWFuIHF1YW4gc8OhdCBjxaluZyBwaOG6o2kgbMOidSwgdMO5eSB0aGVvIGxv4bqhaSBkaW5oIGTGsOG7oW5nIGPDsyDhuqNuaCBoxrDhu59uZyB04bubaSBjw6JuIG7hurduZyBj4bunYSBnw6AgY29uDQotICBN4bqtdCDEkeG7mSBkaW5oIGTGsOG7oW5nIGPhu6dhIGxv4bqhaSA0LCAxIHBow6JuIGLhu5UgcuG6pXQgZMOgeSB24bubaSBnw6AgY29uIHRyb25nIGtob+G6o25nIDAgxJHhur9uIDIwMCBnYW0uDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gc+G7kSBsxrDhu6NuZyBEaWV0IHRoZW8gUGllIGNoYXJ0DQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9ICcnLCB5PW4sIGZpbGwgPSBEaWV0KSkrIA0KICBnZW9tX2NvbChjb2xvciA9ICdibGFjaycsIHdpZHRoID0gMSkgKyANCiAgY29vcmRfcG9sYXIoJ3knKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDEuNCwgbGFiZWwgPSBuKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IC41KSkgKyANCiAgbGFicyggdGl0bGUgPSAnU+G7kSBsxrDhu6NuZyBEaWV0JykgKw0KICB0aGVtZV92b2lkKCkgDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgY2hvIHRhIHRo4bqleSBz4buRIGzGsOG7o25nIGfDoCBjb24gY+G7p2EgdOG7q25nIGxv4bqhaSBkaW5oIGTGsOG7oW5nIG5oxrBuZyDhu58gZOG6oW5nIFBpZSBjaGFydA0KLSB24bubaSBsb+G6oWkgMSBsw6AgMjIwIGNvbiBsw6AgbOG7m24gbmjhuqV0IHbDoCBsb+G6oWkgNCBsw6Agw610IG5o4bqldCB24bubaSAxMTggY29uDQoNCiMjIEJp4buDdSDEkeG7kyBkZW5zaXR5IHRo4buDIGhp4buHbiB3ZWlnaHQgdsOgIERpZXQgdGhlbyBz4buRIGzGsOG7o25nDQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ2dwbG90KCBhZXMoeCA9IHdlaWdodCwgZmlsbCA9IGFzLmZhY3RvcihEaWV0KSkpICsNCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArICANCiAgbGFicyh0aXRsZSA9ICJEZW5zaXR5IHBsb3QgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIHRoZW8gbG/huqFpIGto4bqpdSBwaOG6p24iLCB4ID0gIlRy4buNbmcgbMaw4bujbmcgKGdyYW1zKSIsIHkgPSAiTeG6rXQgxJHhu5kiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZSA9ICJMb+G6oWkga2jhuql1IHBo4bqnbiIpIA0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIGNobyB0YSB0aOG6pXkgc+G7sSBwaMOibiBi4buRIHRy4buNbmcgbMaw4bujbmcgdHJvbmcgbeG7l2kgbmjDs20gduG7m2kgdOG7q25nIGxv4bqhaSBraOG6qXUgcGjhuqduIGRpbmggZMaw4buhbmcgY2hvIGfDoCBjb24gcmnDqm5nIGJp4buHdA0KLSBN4bqtdCDEkeG7mSBsb+G6oWkgbeG7mXQgY2hp4bq/bSBy4bqldCBjYW8gdsOgIGTDoHkgdHJvbmcga2hv4bqjbmcgdOG7qyAxMDAgxJHhur9uIG7hu61hIDIwMGcgcuG7k2kgbMOgbSBnaeG6o20gbeG7mXQgY8OhY2ggcsO1IHLhu4d0LCB0aeG6v3AgxJHDsyBsw6AgbG/huqFpIDIgdsOgIHh14buRbmcgbOG6p24gdOG7m2kgbG/huqFpIDMsNA0KLSBLaG9hbmcgY8OzIHPhu7EgY2jDqm5oIGzhu4duaCBxdcOhIGzhu5tuIHThu6sga2hv4bqjbmcgbuG7rWEgMTAwIMSR4bq/biAyMDBnIHRy4bufIMSRaSBj4bunYSBraOG6qXUgcGjhuqduIDEsIDIsIDMsIExv4bqhaSBkaW5oIGTGsOG7oW5nIDQg4bqjbmggaMaw4bufbmcgbOG7m24gxJHhur9uIGPDom4gbuG6t25nIHThu6sgMTAwIMSR4bq/biAyMDBnIGPhu6dhIGfDoCBjb24NCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBt4bqtdCDEkeG7mSB0cuG7jW5nIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiAoRGVuc2l0eSBwbG90KQ0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBhdHRyLnNvdXJjZT0nLm51bWJlckxpbmVzJ30NCmNrICU+JSBnZ3Bsb3QoIGFlcyh4ID0gd2VpZ2h0LCBmaWxsID0gYXMuZmFjdG9yKERpZXQpKSkgKw0KICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUpICsgIA0KICBmYWNldF93cmFwKH5EaWV0KSArIA0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgcGxvdCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdGhlbyBsb+G6oWkga2jhuql1IHBo4bqnbiIsIHggPSAiVHLhu41uZyBsxrDhu6NuZyAoZ3JhbXMpIiwgeSA9ICJN4bqtdCDEkeG7mSIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIkxv4bqhaSBraOG6qXUgcGjhuqduIikgDQpgYGANCg0KLSBUxrDGoW5nIHThu7EgbmjGsCBiaeG7g3UgxJHhu5MgdHLDqm4sIG3hu5dpIHBo4bqnbiBuaOG7jyBjaOG7iSByYSBt4bqtdCDEkeG7mSB0cuG7jW5nIGzGsOG7o25nIGtoaSBjaG8gY8OhYyBsb+G6oWkga2jhuql1IHBo4bqnbiByacOqbmcgYmnhu4d0IMSR4buRaSB24bubaSBnw6AgY29uDQotIExv4bqhaSBraOG6qXUgcGjhuqduIDEgduG7m2kgdHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIDEwMGcgxJHhu5UgbOG6oWkgcuG6pXQgbmhp4buBdQ0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgZ8OgIHRoZW8gRGlldA0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdyb3VwX2J5KERpZXQpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSAnJywgeSA9IG4sZmlsbCA9IERpZXQpKSArIA0KICBnZW9tX2NvbCggY29sb3IgPSAnYmxhY2snICkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAxKSkgKw0KICBsYWJzKCB5ID0gJ3Phu5EgbMaw4bujbmcnLCB0aXRsZSA9ICdz4buRIGzGsOG7o25nIGfDoCBjb24gY2hvIG3hu5dpIGNo4bq/IMSR4buZIGRpbmggZMaw4buhbmcnKSANCmBgYA0KDQotIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gY2hvIHRhIHRo4bqleSBz4buRIGzGsOG7o25nIGfDoCBjb24gdGhlbyB04burbmcgbG/huqFpIGRpbmggZMaw4buhbmcsIGPDoWMgc+G7kSBsaeG7h3UgxJHGsOG7o2MgY2jhu5NuZyB0aGVvIG3hu5l0IGPhu5l0IHbDoCB0w7l5IHRoZW8gc+G7kSBsxrDhu6NuZyBtw6AgxJHhu5kgZMOgeSBraMOhYyBuaGF1DQotIExv4bqhaSBkaW5oIGTGsOG7oW5nIDEgY8OzIMSR4buZIGTDoHkgY2hp4bq/bSDGsHUgdGjhur8sIHPhu5EgbMaw4bujbmcgbmhp4buBdSBuaOG6pXQsIDMgbG/huqFpIGtpYSBraMO0bmcgY2jDqm5oIGzhu4djaCDEkcOhbmcga+G7gw0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHTGsMahbmcgcXVhbiBnaeG7r2EgY8OibiBu4bq3bmcgZ8OgIGNvbiB2w6AgbG/huqFpIGRpbmggZMaw4buhbmcgdGhlbyBEaWV0DQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ2dwbG90KGFlcyh4ID0gd2VpZ2h0LCB5ID0gVGltZSwgY29sb3IgPSBEaWV0KSkgKw0KICBnZW9tX3BvaW50KCkgKyANCiAgbGFicyggeCA9ICdjw6JuIG7hurduZyBnw6AgY29uJywgeSA9ICdUaOG7nWkgZ2lhbiBxdWFuIHPDoXQnLCB0aXRsZSA9ICdUxrDGoW5nIHF1YW4gZ2nhu69hIGfDoCBjb24gdsOgIGPDom4gbuG6t25nIHRoZW8gbG/huqFpIGRpbmggZMaw4buhbmcnKSArIA0KZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3IgPSAnYmxhY2snKQ0KYGBgDQoNCi0gxJDGsOG7nW5nIHRyZW5kIGxpbmUgY8OzIHh1IGjGsOG7m25nIGzDqm4gdHLDqm4sIG3hu5FpIHTGsMahbmcgcXVhbiBkxrDGoW5nIGdp4buvYSBjw6FjIGThu68gbGnhu4d1DQotIFbhu5tpIGPDom4gbuG6t25nIGfDoCBjb24gbOG7m24sIHBo4bqjaSBi4buVIHN1bmcgZGluaCBkxrDhu6FuZyB0aGVvIMSRw7MgbcOgIHRo4budaSBnaWFuIHF1YW4gc8OhdCBjxaluZyBz4bq9IHBo4bqjaSB0xINuZyBsw6puDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gdOG7tyBs4buHIGRpbmggZMaw4buhbmcgdGhlbyBEaWV0IA0KICANCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ3JvdXBfYnkoRGlldCkgJT4lIHN1bW1hcmlzZShuID0gbigpKSAlPiUgIA0KICBnZ3Bsb3QoYWVzKERpZXQsbikpICsgDQogIGdlb21fY29sKGZpbGw9J2dyZWVuJykgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQobi9sZW5ndGgoY2skRGlldCkpKSx2anVzdCA9IDIsIGNvbG9yID0gJ3JlZCcpICsgDQogIGxhYnMoeCA9ICdMb+G6oWkgZGluaCBkxrDhu6FuZycsIHkgPSAnU+G7kSBsxrDhu6NuZycsIHRpdGxlID0gJ1Thu7cgbOG7hyBsb+G6oWkgZGluaCBkxrDhu6FuZycpIA0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIGNobyB0YSB0aOG6pXkgcGjhuqduIHRyxINtIHPhu5EgbMaw4bujbmcgZ8OgIGNvbiB0cm9uZyBt4buXaSBsb+G6oWkgZGluaCBkxrDhu6FuZyDEkcaw4bujYyBudcO0aQ0KLSBMb+G6oWkgZGluaCBkxrDhu6FuZyBz4buRIDEgY8OzIHPhu5EgbMaw4bujbmcgZ8OgIGNvbiBjaGnhur9tIDM4LjYlLCBsb+G6oWkgZGluaCBkxrDhu6FuZyBz4buRIDIsMyBjw7MgMjAuNzYlIHThu5VuZyBz4buRIGzGsOG7o25nIGfDoCBjb24sIGPDsm4gbOG6oWkgbMOgIGxv4bqhaSBkaW5oIGTGsOG7oW5nIHPhu5EgNCBz4buRIGzGsOG7o25nIGfDoCBjb24gY2hp4bq/bSAyMC40MiUuDQoNCiMjIEJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gVMawxqFuZyBxdWFuIGdp4buvYSBjw6JuIG7hurduZyBnw6AgY29uIHbDoCB0aOG7nWkgZ2lhbiBxdWFuIHPDoXQgdGhlbyBsb+G6oWkgRGlldA0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdncGxvdChhZXMoeCA9IHdlaWdodCwgeSA9IFRpbWUsIGNvbG9yID0gRGlldCkpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBsYWJzKCB4ID0gJ2PDom4gbuG6t25nIGfDoCBjb24nLCB5ID0gJ1Ro4budaSBnaWFuIHF1YW4gc8OhdCcsIHRpdGxlID0gJ1TGsMahbmcgcXVhbiBnaeG7r2EgZ8OgIGNvbiB2w6AgY8OibiBu4bq3bmcgdGhlbyBsb+G6oWkgZGluaCBkxrDhu6FuZycpICsgIA0KZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgY29sb3IgPSAnZ3JlZW4nKSArDQogIGZhY2V0X3dyYXAofkRpZXQpIA0KYGBgDQoNCi0gQ8OibiBu4bq3bmcgZ8OgIGNvbiB0w7l5IHRoZW8gdOG7q25nIGxv4bqhaSBkaW5oIGTGsOG7oW5nIGPDsyB4dSBoxrDhu5tuZyB0xINuZyB0aGVvIHRo4budaSBnaWFuIHF1YW4gc8OhdA0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIGzGsOG7o25nIGPDom4gbuG6t25nIHRydW5nIGLDrG5oIHRoZW8gRGlldCAoIEThuqFuZyBQaWUgKQ0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdyb3VwX2J5KERpZXQpICU+JSBzdW1tYXJpc2Uobj1tZWFuKHdlaWdodCkpICU+JSANCiAgZ2dwbG90KGFlcyh4PSAnJywgeT1uLCBmaWxsID0gRGlldCkpKyANCiAgZ2VvbV9jb2woY29sb3IgPSAnYmxhY2snLCB3aWR0aCA9IDEpICsgDQogIGNvb3JkX3BvbGFyKCd5JykgKyANCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMS4zLCBsYWJlbCA9IHJvdW5kKG4sMikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gLjUpKSArIA0KICBsYWJzKCB0aXRsZSA9ICdUcuG7jW5nIGzGsOG7o25nIHRydW5nIGLDrG5oJykgKyANCiAgdGhlbWVfdm9pZCgpIA0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24gdHJ1bmcgYsOsbmggdGhlbyB04burbmcgbG/huqFpIGRpbmggZMaw4buhbmcNCi0gTG/huqFpIDEgY8OzIHRy4buNbmcgbMaw4bujbmcgdHJ1bmcgYsOsbmggbMOgIDEwMi42NSwgbG/huqFpIDIgbMOgIDEyMi42MiwgbG/huqFpIDMgbMOgIDE0Mi45NSwgbG/huqFpIDQgbMOgIDEzNS4yNg0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHRo4budaSBnaWFuIHRydW5nIGLDrG5oIHRoZW8gRGlldCAoIGThuqFuZyBQaWUgKQ0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdyb3VwX2J5KERpZXQpICU+JSBzdW1tYXJpc2Uobj1tZWFuKFRpbWUpKSAlPiUgDQogIGdncGxvdChhZXMoeD0gJycsIHk9biwgZmlsbCA9IERpZXQpKSsgDQogIGdlb21fY29sKGNvbG9yID0gJ2JsYWNrJywgd2lkdGggPSAxKSArIA0KICBjb29yZF9wb2xhcigneScpICsgDQogIGdlb21fdGV4dChhZXMoeCA9IDEuMywgbGFiZWwgPSByb3VuZChuLDIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IC41KSkgKw0KICBsYWJzKCB0aXRsZSA9ICdUaOG7nWkgZ2lhbiB0cnVuZyBiw6xuaCcpICsgDQogIHRoZW1lX2J3KCkgIA0KYGBgDQoNCi0gVGjhu51pIGdpYW4gcXVhbiBzw6F0IHRydW5nIGLDrG5oIGPhu6dhIGfDoCBjb24gdGhlbyB04burbmcgbG/huqFpIGRpbmggZMaw4buhbmcNCi0gTG/huqFpIGRpbmggZMaw4buhbmcgMSBjw7MgdGjhu51pIGdpYW4gcXVhbiBzw6F0IHRydW5nIGLDrG5oIGzDoCAxMC40OCwgbG/huqFpIDIgbMOgIDEwLjkyLCBsb+G6oWkgMyBsw6AgMTAuOTIgY8OybiBsb+G6oWkgNCBsw6AgMTAuNzUNCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB04bqnbiBzdeG6pXQgeHXhuqV0IGhp4buHbiB0cuG7jW5nIGzGsOG7o25nIGfDoCBjb24NCg0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBhdHRyLnNvdXJjZT0nLm51bWJlckxpbmVzJ30NCmNrICU+JSBnZ3Bsb3QoYWVzKHggPSB3ZWlnaHQpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUwLCBmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFlcyh5PS4uY291bnQuLikpICsNCiAgbGFicyh4ID0gIlRy4buNbmcgbMaw4bujbmcgKGcpIiwgeSA9ICJU4bqnbiBzdeG6pXQiKSArIA0KICBnZ3RpdGxlKCJQaMOibiBwaOG7kWkgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIikgKw0KICB0aGVtZV9idygpIA0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgdOG6p24gc3XhuqV0IHN14bqldCBoaeG7h24gY8OhYyBjaOG7iSBz4buRIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbg0KLSB04bqnbiBzdeG6pXQgeHXhuqV0IGhp4buHbiBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGTGsOG7m2kgMTAwZyB4deG6pXQgaGnhu4duIG5oaeG7gXUgbmjhuqV0IGjGoW4gMjAwIGzhuqduIHbDoCBnaeG6o20gZOG6p24NCg0KIyMgQmnhu4N1IMSR4buTIHBow6JuIHBo4buRaSB0cm9uZyBsxrDhu6NuZyBnw6AgY29uIHbhu5tpIHThuqduIHN14bqldCAgKHRoZW8gRGlldCkNCg0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBhdHRyLnNvdXJjZT0nLm51bWJlckxpbmVzJ30NCmNrICU+JSBnZ3Bsb3QoYWVzKHggPSB3ZWlnaHQpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUwLCBmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFlcyh5PS4uY291bnQuLikpICsgDQogIGxhYnMoeCA9ICJUcuG7jW5nIGzGsOG7o25nIChnKSIsIHkgPSAiVOG6p24gc3XhuqV0IikgKyANCiAgZmFjZXRfd3JhcCh+RGlldCkgKyANCiAgZ2d0aXRsZSgiUGjDom4gcGjhu5FpIGPhu6dhIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiIpIA0KYGBgDQoNCi0gIEJp4buDdSDEkeG7kyBjaG8gcmEgdGjhuqV5IGNo4buJIHPhu5EgeHXhuqV0IGhp4buHbiBj4bunYSBjw6FjIGNo4buJIHPhu5EgdHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIMSRxrDhu6NjIHBow6JuIHJhIHRoZW8gbG/huqFpIGRpbmggZMaw4buhbmcNCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiB04bqnbiBzdeG6pXQgeHXhuqV0IGhp4buHbiBjw6FjIG3hu5FjIHRo4budaSBnaWFuIHF1YW4gc8OhdA0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdncGxvdChhZXMoeCA9IFRpbWUpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDMsIGZpbGwgPSAicmVkIiwgY29sb3IgPSAiYmxhY2siLCBhZXMoeT0uLmNvdW50Li4pKSArIA0KICBsYWJzKHggPSAiVGjhu51pIGdpYW4gKGgpIiwgeSA9ICJU4bqnbiBzdeG6pXQiKSArDQogIGdndGl0bGUoIlBow6JuIHBo4buRaSBj4bunYSB0aOG7nWkgZ2lhbiB0aGVvIGTDtWkgZ8OgIGNvbiIpICsgDQogIHRoZW1lX2J3KCkgDQpgYGANCg0KLSBCaeG7g3UgxJHhu5EgY2hvIHRhIHRo4bqleSBjw6FjIHThuqduIHN14bqldCBjw6FjICBraG/huqNuZyB0aOG7nWkgZ2lhbiB4deG6pXQgaGnhu4duDQotIEtob+G6o25nIHRo4budaSBnaWFuIHh14bqldCBoaeG7h24gbmhp4buBdSBuaOG6pXQgdOG7qyAwIMSR4bq/biA1IHbDoCBnaeG6o20gZOG6p24gduG7gSAyMA0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiB0aGVvIHRo4budaSBnaWFuIChsaW5lKQ0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBhdHRyLnNvdXJjZT0nLm51bWJlckxpbmVzJ30NCmdncGxvdChDaGlja1dlaWdodCwgYWVzKHggPSBUaW1lLCB5ID0gd2VpZ2h0LCBjb2xvciA9IENoaWNrKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnMoeCA9ICJUaOG7nWkgZ2lhbiAobmfDoHkpIiwgeSA9ICJUcuG7jW5nIGzGsOG7o25nIChnKSIsIGNvbG9yID0gIkfDoCIpICsNCiAgZ2d0aXRsZSgiQmnhu4N1IMSR4buTIMSRxrDhu51uZyBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCB0aGVvIHRo4budaSBnaWFuIikgKw0KICB0aGVtZV9idygpDQpgYGANCg0KIyMgQmnhu4N1IMSR4buTIHRo4buDIGhp4buHbiBt4bqtdCDEkeG7mSBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGfDoCAoIHZpb2xpbiBwbG90KQ0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnfQ0KY2sgJT4lIGdncGxvdChhZXMoeCA9IGFzLmZhY3RvcihEaWV0KSwgeSA9IHdlaWdodCwgZmlsbCA9IGFzLmZhY3RvcihEaWV0KSkpICsgDQogIGdlb21fdmlvbGluKCkgKyANCiAgbGFicyh4ID0gImNo4bq/IMSR4buZIGRpbmggZMaw4buhbmciLCB5ID0gIlRy4buNbmcgbMaw4bujbmcgKGcpIikgKw0KICBnZ3RpdGxlKCJCaeG7g3UgxJHhu5MgdmlvbGluIHBsb3QgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBnw6AiKSArIA0KICB0aGVtZV9idygpDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgY2hvIHRhIHRo4bqleSBt4bqtdCDEkeG7mSBwaMOibiBwaOG7kWkgY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBjw6FjIGfDoCBjb24gdGhlbyB04burbmcgY2jhur8gxJHhu5kgZGluaCBkxrDhu6FuZw0KLSDhu58gY2jhur8gxJHhu5kgZGluaCBkxrDhu6FuZyAxIHRow6wgY8OzIG3huq10IMSR4buZIHBow6JuIHBo4buRaSB0cuG7jW5nIGzGsOG7o25nIGTGsOG7m2kgMTAwZyBuaGnhu4F1IG5o4bqldCwgY+G6oyA0IGxv4bqhaSDEkeG7gXUgY8OzIHh1IGjGsOG7m25nIGdp4bqjbSBk4bqnbiwgdHLhu41uZyBsxrDhu6NuZyBjw6FjIGzhu5tuIHRow6wgY8Ogbmcgw610LCBs4bubbiBuaOG6pXQgY8OzIHRo4buDIMSR4bqhdCDEkcaw4bujYyDhu58ga2jhuql1IHBo4bqnbiBkaW5oIGTGsOG7oW5nIHPhu5EgMw0KDQojIyBCaeG7g3UgxJHhu5MgdGjhu4MgaGnhu4duIG3huq10IMSR4buZIHRy4buNbmcgbMaw4bujbmcgcXVhIGPDoWMgbeG7kWMgDQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgDQogIGdncGxvdChhZXMoeCA9IFRpbWUsIHkgPSB3ZWlnaHQpKSArDQogIGdlb21fdmlvbGluKGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHggPSAiVGjhu51pIGdpYW4iLCB5ID0gIlRy4buNbmcgbMaw4bujbmcgKGcpIiwNCiAgICAgICB0aXRsZSA9ICJT4buxIHBow6F0IHRyaeG7g24gY+G7p2EgdHLhu41uZyBsxrDhu6NuZyBnw6AgY29uICB0aGVvIHRo4budaSBnaWFuIikgKyANCiAgdGhlbWVfYncoKQ0KYGBgDQoNCi0gQmnhu4N1IMSR4buTIGNobyB0YSB0aOG6pXkgbeG6rXQgxJHhu5kgcGjDom4gcGjhu5FpIGPhu6dhIHRy4buNbmcgbMaw4bujbmcsIHRy4buNbmcgbMaw4bujbmcgY8OgbmcgbOG7m24gdsOgIMOtdCANCg0KIyMgQmnhu4N1IMSR4buTIHBow6JuIHBo4buRaSB0cuG7jW5nIGzGsOG7o25nIGThuqFuZyBCb3hwbG90DQoNCmBgYHtyIG1lc3NhZ2U9VFJVRSwgd2FybmluZz1GQUxTRSwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9DQpjayAlPiUgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKERpZXQpLCB5ID0gd2VpZ2h0LCBmaWxsID0gZmFjdG9yKERpZXQpKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGxhYnMoeCA9ICJMb+G6oWkga2jhuql1IHBo4bqnbiIsIHkgPSAiVHLhu41uZyBsxrDhu6NuZyBnw6AgY29uIiwgZmlsbCA9ICJMb+G6oWkga2jhuql1IHBo4bqnbiIpICsgDQogIGdndGl0bGUoIkJp4buDdSDEkeG7kyBCb3hwbG90IGPhu6dhIHRy4buNbmcgbMaw4bujbmcgZ8OgIGNvbiB0aGVvIGxv4bqhaSBraOG6qXUgcGjhuqduIikgDQpgYGANCg0KLSBCaeG7g3UgxJHhu5MgY2hvIHRo4bqleSBjw6FjIGdpw6EgdHLhu4sgbmjGsCB0cnVuZyB24buLLCB04bupIHBow6JuIHbhu4sgdsOgIGPDoWMgZ2nDoSB0cuG7iyBuZ2/huqFpIHZpIGPDsyB0aOG7gyB4deG6pXQgaGnhu4duDQoNCg0KDQo=