PHẦN 1: CHUẨN BỊ VÀ TÌM HIỂU DỮ LIỆU
1.1 Đọc dữ liệu
Sử dụng câu lệnh read.csv() để nhập dữ liệu với
D:/download/SupermarketTransactions.csv
là đường link của file dữ liệu SupermarketTransactions.csv. Tạm
gọi bộ dữ liệu này là st.
st <- read.csv("D:/download/SupermarketTransactions.csv")
table(st$Homeowner,st$AnnualIncome)
##
## $10K - $30K $110K - $130K $130K - $150K $150K + $30K - $50K $50K - $70K
## N 1359 119 136 48 2087 1063
## Y 1731 524 624 225 2514 1307
##
## $70K - $90K $90K - $110K
## N 686 117
## Y 1023 496
1.2 Làm quen với dữ liệu
Cấu trúc của dữ liệu (Data Structure) hay cấu trúc nội tại của dữ
liệu là cách tổ chức bên trong dữ liệu đó. Một trong những hàm có thể
cho biết được cấu trúc của dữ liệu trong R là hàm str(), hàm str() cho biết kiểu dữ liệu, số
lượng phần tử bên trong dữ liệu, tên các cột và các phần tử đầu tiên
trong các cột.
str(st)
## 'data.frame': 14059 obs. of 16 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ PurchaseDate : chr "12/18/2007" "12/20/2007" "12/21/2007" "12/21/2007" ...
## $ CustomerID : int 7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
## $ Gender : chr "F" "M" "F" "M" ...
## $ MaritalStatus : chr "S" "M" "M" "M" ...
## $ Homeowner : chr "Y" "Y" "N" "Y" ...
## $ Children : int 2 5 2 3 3 3 2 2 3 1 ...
## $ AnnualIncome : chr "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
## $ City : chr "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
## $ StateorProvince : chr "CA" "CA" "WA" "OR" ...
## $ Country : chr "USA" "USA" "USA" "USA" ...
## $ ProductFamily : chr "Food" "Food" "Food" "Food" ...
## $ ProductDepartment: chr "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
## $ ProductCategory : chr "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
## $ UnitsSold : int 5 5 3 4 4 3 4 6 1 2 ...
## $ Revenue : num 27.38 14.9 5.52 4.44 14 ...
Giải thích kết quả:
'data.frame': 14059 obs. of 16 variables:: Dữ
liệu là một data frame (dữ liệu dạng bảng) với 14059 quan sát và 16
biến.
Danh sách các biến bao gồm: X, PurchaseDate, CustomerID, Gender,
MaritalStatus, Homeowner, Children, AnnualIncome, City, StateorProvine,
Country, ProductFamily, ProductDepartment, ProductCategory, UnitSold,
Revenue.
chr, int, num là định dạng
của từng biến. Cụ thể chr là character có
nghĩa là dạng kí tự, int là integer có nghĩa
là dạng số nguyên còn num nghĩa là number có
nghĩa là dạng số.
Các biến có định dạng chr bao gồm: PurchaseDate,
Gender, MaritalStatus, Homeowner, AnnualIncome, City, StateorProvine,
Country, ProductFamily, ProductDepartment, ProductCategory.
Các biến có định dạng là int bao gồm: X, CustomerID,
Children, UnitSold.
Biến có định dạng là num là biến Revenue.
Trong khám phá dữ liệu, việc hiển thị dòng đầu và dòng cuối của dữ
liệu là một bước giúp ta có thể xem sơ lược nội dung của dữ liệu, phát
hiện lỗi hoặc các giá trị bất thường (nếu có) và có thể kiểm tra xem dữ
liệu nhập từ file có chính xác là dữ liệu ta cần tìm hay không. Để thực
hiện, ta sử dụng hàm head() và tail() trong R. Trong đó hàm
head() là để hiển thị 6
dòng đầu của bộ dữ liệu còn hàm tail() là để hiển thị 6 dòng
cuối của dữ liệu.
head(st)
tail(st)
Trong các bộ dữ liệu, giá trị NA (Not Available) nghĩa là giá trị bị
thiếu (missing value) hoặc giá trị không có sẵn. NA khiến cho việc tính
toán bên trong dữ liệu trở nên khó khăn, khiến các ước lượng trở nên sai
lệch và làm giảm chất lượng khi trực quan hóa dữ liệu. Để kiểm tra rằng
trong bộ dữ liệu có các giá trị NA hay không, ta có thể sử dụng hàm
is.na() kết hợp với hàm
sum() để xem xét có bao
nhiêu giá trị NA trong bộ dữ liệu.
sum(is.na(st))
## [1] 0
Kết quả cho thấy số giá trị NA trong bộ dữ liệu này là 0. Vì thế ta
không cần phải sử dụng các phương pháp để xử lý dữ liệu nếu dữ liệu có
giá trị là NA.
Biến phân loại là loại biến trong dữ liệu mà các giá trị của nó đại
diện cho nhóm, loại, hay danh mục riêng biệt, không có ý nghĩa số học
như cộng trừ nhân chia. Chuyển các biến về kiểu factor là
một thao tác quan trọng giúp R hiểu và xử lý đúng bản chất của dữ liệu,
mô hình hóa chính xác và tránh lỗi logic trong phân tích. Để chuyển đổi
các biến về loại factor, ta sử dụng hàm as.factor(). Trong bộ dữ liệu
SupermarketTransactions.csv, ta
thấy được có nhiều biến thuộc phân loại là factor bao gồm:
Gender, MaritalStatus, Homeowner, AnnualIncome, City, StateorProvine,
Country, ProductFamily, ProductDepartment, ProductCategory. Để chuyển
đổi chúng về dạng factor, ta thực hiện như sau:
st$Gender <- as.factor(st$Gender)
st$MaritalStatus <- as.factor(st$MaritalStatus)
st$Homeowner <- as.factor(st$Homeowner)
st$AnnualIncome <- as.factor(st$AnnualIncome)
st$City <- as.factor(st$City)
st$StateorProvince <- as.factor(st$StateorProvince)
st$ProductFamily <- as.factor(st$ProductFamily)
st$ProductDepartment <- as.factor(st$ProductDepartment)
st$ProductCategory <- as.factor(st$ProductCategory)
Sau khi đã chuyển đổi các biến để phân loại về factor,
ta có thể sẵn sàng dùng dữ liệu này để tiến hành các bước phân tích tiếp
theo.
PHẦN 2: PHÂN TÍCH VÀ MÔ TẢ CÁC BIẾN ĐỊNH TÍNH
Các biến định tính được hiểu là các biến không được biểu diễn thành
số, vì thế trong phân tích, đặc biệt là phân tích thống kê, ta không thể
sử dụng thao tác thống kê mô tả thông thường. Thay vào đó, việc tính tần
số và tần suất cũng như trực quan hóa chúng là công cụ hữu hiệu hơn.
Dưới đây là kết quả thống kê tần số, tần suất và đồ thị để trực quan hóa
các biến định tính.
2.1 Biến Gender
2.1.1 Thống kê tần số, tần suất
Trong bộ dữ liệu SupermarketTransactions.csv,
Gender là biến nhằm mô tả
giới tính của khách hàng, dữ liệu của biến này gồm 2 phân loại là M
(viết tắt cho Male - Nam) và F (viết tắt cho Female - Nữ). Để tính tần
số bên trong bộ dữ liệu này, ta sử dụng câu lệnh table() và để tính tần suất, ta
tiến hành chia tần số cho tổng số lượng quan sát của dữ liệu.
Bên dưới là là các câu lệnh được sử dụng để tính tần số và tần suất
của biến Gender, cụ thể:
table() trả về kết quả là
tần số của biến Gender;
prop.table() trả về kết
quả là tần suất của Gender. Với
Category là phân loại dữ liệu bên trong Gender, Frequency
là tần số và Percentage (đơn vị: %) là tần suất. Ta có bảng
tần số tần suất cho Gender
như sau:
# Lập bảng tần số
gender_f <- table(st$Gender)
# Lập bảng tần suất
gender_p <- prop.table(gender_f)*100
# Kết hợp thành một bảng
gender <- data.frame(
Category = names(gender_f),
Frequency = as.vector(gender_f),
Percentage = round(as.vector(gender_p), 2)
)
gender
2.1.2 Trực quan hóa dữ liệu
Trực quan hóa dữ liệu là một khâu đóng vai trò rất quan trọng trong
phân tích dữ liệu, nó không chỉ giúp việc hiểu dữ liệu trở nên dễ dàng
mà còn đóng vai trò hỗ trợ trong việc thể hiện kết quả phân tích một
cách trực quan và dễ hiểu nhất. Một trong những cách trực quan hóa dữ
liệu phổ biến nhất là vẽ biểu đồ, đối với biến Gender thể hiện giới tính, biểu
đồ tròn là một dạng biểu đồ hợp lý thể hiện phân bố và tỷ lệ phần trăm
giới tính của các khách hàng.
Để vẽ biểu đồ, ta sử dụng câu lệnh ggplot() với các yếu tố như
sau:
ggplot(data = gender, aes(x = '', y = Frequency, fill = Category)):
sử dụng bộ dữ liệu là gender để vẽ biểu đồ. Trong biểu đồ tròn, cột x là
rỗng nên ta có x = '', cột y thể hiện tần số nên ta có
y = Frequency và fill = Category là sử dụng
màu sắc khác nhau cho từng nhóm.
geom_col(): tạo các cột (col) với chiều cao tương
ứng với Frequency
coord_polar('y'): Chuyển biểu đồ cột sang biểu đồ
tròn (pie chart) bằng cách sử dụng hệ tọa độ tròn (polar coordinates),
'y' tức là lấy trục y (chiều
cao của cột) để làm góc quay trong hình tròn.
geom_text(aes(label = percent(Frequency/length(st$Gender))), position = position_stack(vjust = 0.5)):
thêm nhãn là các văn bản (text) vào biểu đồ, ở đây text là tỷ lệ phần
trăm của tần số (Frequency) chia cho tổng số quan sát
(length(st$Gender)) với vị trí
(position = position_stack(vjust = 0.5)) là ở giữa từng
vùng của biểu đồ.
labs(title = 'Figure 1: Gender of Customers'): tên
của biểu đồ là “Figure 1: Gender of Customers” hay
“Hình 1: Giới tính của Khách hàng”.
scale_fill_brewer(palette = "Set3"): Màu của biểu đồ
là bảng màu (color pallete) số 3 ("Set3")
trong thư viện.
theme(plot.title = element_text(hjust = 0.5, face = 'bold')):
Tên biểu đồ (plot.title) được căn chính giữa và in
đậm.
Kết quả sử dụng câu lệnh để trực quan hóa các dữ liệu trong Gender như sau:
ggplot(data = gender, aes(x = '', y = Frequency, fill = Category)) +
geom_col() +
coord_polar('y') +
geom_text(aes(label = percent(Frequency/length(st$Gender))), position = position_stack(vjust = 0.5)) +
labs(title = 'Figure 1: Gender of Customers') +
scale_fill_brewer(palette = "Set3") +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

Nhận xét: Kết quả thống kê cho thấy tổng số người
tham gia là 14059 (6889 nam và 7170 nữ). Trong đó, nam giới (M) chiếm
6889 (49%), trong khi nữ giới (F) chiếm 7170 (51%). Tỷ lệ này phản ánh
sự cân bằng tương đối giữa hai giới, với nữ nhiều hơn nam một chút
(chênh lệch 2%). Dữ liệu cho thấy mẫu nghiên cứu có tính đại diện tốt về
giới tính, không có sự chênh lệch quá lớn giữa nam và nữ.
2.2 Biến MaritalStatus
Tương tự với Gender, ta
cũng lập bảng tần số, tần suất cho MaritalStatus và trực quan hóa
nó. MaritalStatus là biến
thể hiện tình trạng hôn nhân của các khách hàng với các thành phần là M
(Married - Đã kết hôn) và S (Single - Độc thân).
2.2.1 Thống kê tần số, tần suất
Ta có bảng tần số, tần suất của MaritalStatus như sau:
# Lập bảng tần số
ms_f <- table(st$MaritalStatus)
# Lập bảng tần suất
ms_p <- prop.table(ms_f)*100
# Kết hợp thành một bảng
ms <- data.frame(
Category = names(ms_f),
Frequency = as.vector(ms_f),
Percentage = round(as.vector(ms_p), 2)
)
ms
2.2.2 Trực quan hóa dữ liệu
ggplot(data = ms, aes(x = '', y = Frequency, fill = Category)) +
geom_col() +
coord_polar('y') +
geom_text(aes(label = percent(Frequency/length(st$MaritalStatus))), position = position_stack(vjust = 0.5)) +
labs(title = 'Figure 2: Marital Status of Customers') +
scale_fill_brewer(palette = "Set3") +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

Nhận xét: Kết quả cho thấy không có sự khác biệt
đáng kể về tỷ lệ khách hàng đã kết hôn và chưa kết hôn. Cụ thể 48.84%
tổng số khách hàng (6866 khách hàng) đã kết hôn và 51.16% tổng số khách
hàng (7193 khách hàng) chưa kết hôn. Tỷ lệ chênh lệch giữa số khách hàng
đã kết hôn và chưa kết hôn chỉ khoảng 2.32%, phản ánh sự phân bố đồng
đều giữa hai nhóm đối tượng này trong mẫu nghiên cứu. Kết quả này có thể
gợi ý rằng mẫu khảo sát có tính đại diện tốt hoặc phản ánh xu hướng cân
bằng trong tình trạng hôn nhân của quần thể nghiên cứu.
2.3 Biến Homeowner
Homeowner là biến thể
hiện rằng các khách hàng đã sở hữu nhà ở hay chưa, các thành phần là Y
(Yes - Có, đã sở hữu nhà) và N (No - Chưa, chưa sở hữu nhà).
2.3.1 Thống kê tần số, tần suất
Ta có bảng tần số, tần suất như sau:
# Lập bảng tần số
ho_f <- table(st$Homeowner)
# Lập bảng tần suất
ho_p <- prop.table(ho_f)*100
# Kết hợp thành một bảng
ho <- data.frame(
Category = names(ho_f),
Frequency = as.vector(ho_f),
Percentage = round(as.vector(ho_p), 2)
)
ho
2.3.2 Trực quan hóa dữ liệu
ggplot(data = ho, aes(x = '', y = Frequency, fill = Category)) +
geom_col() +
coord_polar('y') +
geom_text(aes(label = percent(Frequency/length(st$MaritalStatus))), position = position_stack(vjust = 0.5)) +
labs(title = 'Figure 3: Housing Status of Customers ') +
scale_fill_brewer(palette = "Set3") +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

Nhận xét: Kết quả cho thấy số lượng khách hàng đã sở
hữu nhà ở chiếm ưu thế khá lớn (khoảng 60% tổng số khách hàng hay 8444
khách hàng đã sở hữu nhà) còn số khách hàng chưa sở hữu nhà chiếm ưu thế
ít hơn (gần 40% tổng số khách hàng hay 5615 khách hàng chưa sở hữu nhà).
Điều này phản ánh rằng đa số các khách hàng đều đã sở hữu nhà riêng và
có chênh lệch tương đối đáng kể (khoảng 20%) so với các khách hàng chưa
sở hữu nhà cho thấy xu hướng sở hữu nhà cao và chiếm ưu thế.
2.4 Biến AnnualIncome
AnnualIncome là biến
thể hiện thu nhập hàng năm của khách hàng với các thành phần bao
gồm:
10K - 30K: Mức thu nhập trong khoảng 10k USD đến 30k USD
30K - 50K: Mức thu nhập trong khoảng 30k USD đến 50k USD
50K - 70K: Mức thu nhập trong khoảng 50k USD đến 70k USD
70K - 90K: Mức thu nhập trong khoảng 70k USD đến 90k USD
90K - 110K: Mức thu nhập trong khoảng 90k USD đến 110k
USD
110K - 130K: Mức thu nhập trong khoảng 110k USD đến 130k
USD
130K - 150K: Mức thu nhập trong khoảng 130k USD đến 150k
USD
150K+: Mức thu nhập hơn 150K USD.
Từ đây ta có thể phân loại thu nhập của khách hàng ra thành 3 loại,
bao gồm:
Nhóm có thu nhập thấp: khoảng 10k - 50K USD hằng năm
Nhóm có thu nhập trung bình: khoảng 50K - 110K USD hằng
năm
Nhóm có thu nhập cao: khoảng 110K - hơn 150K USD hằng
năm.
2.4.1 Thống kê tần số, tần suất
# Lập bảng tần số
ai_f <- table(st$AnnualIncome)
# Lập bảng tần suất
ai_p <- prop.table(ai_f)*100
# Kết hợp thành một bảng
ai <- data.frame(
Category = names(ai_f),
Frequency = as.vector(ai_f),
Percentage = round(as.vector(ai_p), 2)
)
ai
2.4.2 Trực quan hóa dữ liệu
Ở đây, khi biến AnnualIncome đã có quá nhiều
biểu hiện, việc sử dụng công cụ trực quan hóa là biểu đồ tròn trở nên
khá khó để nhìn nên ta sử dụng biểu đồ cột. Để vẽ biểu đồ cột, ta tiếp
tục sử dụng câu lệnh ggplot() với các yếu tố như
sau:
ggplot(st, aes(x = AnnualIncome)): Vẽ biểu đồ với dữ
liệu được sử dụng là dữ liệu [st]{style-“color:blue”} và
trục hoành là Annual Income.
geom_bar(fill = '#558'): Tạo biểu đồ cột với màu của
cột là màu có mã Hex là #558
geom_text(aes(label = after_stat(count)), stat = "count", vjust = -0.3, size = 3.5):
Hiển thị ký tự trên từng cột của biểu đồ là tần số (số lượng) của các
biểu hiện trong biến AnnualIncome với vị trí là nằm
trên mỗi cột và kích cỡ là 3.5.
labs(title = "Figure 4: Annual Income of Customers", x = "Annual Income", y = "Frequency"):
Tên của biểu đồ là “Figure 1: Annual Income of
Customers với trục tung là”Frequency” và trục
hoành là “Annual Income”.
theme(axis.text.x = element_text(angle = 45, hjust = 1), plot.title = element_text(hjust = 0.5, face = "bold")):
Tên biểu đồ (plot.title) được căn chính giữa và in đậm, tên
của từng biểu hiện ở trục hoành (axis.text.x) được xoay 90
độ và căn lề phải để tránh chồng chữ.
ggplot(st, aes(x = AnnualIncome)) +
geom_bar(fill = '#558') +
geom_text(
aes(label = after_stat(count)),
stat = "count",
vjust = -0.3,
size = 3.5
) +
labs(title = "Figure 4: Annual Income of Customers", x = "Annual Income", y = "Frequency") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
plot.title = element_text(hjust = 0.5, face = "bold"))

Nhận xét: Biến Annual Income cho ta thấy được có
4601 khách hàng (tức là 32.73% tổng số khách hàng) có mức thu nhập từ
khoảng 30K - 50K USD hằng năm và chiếm tỷ lệ nhiều nhất. Nhóm khách hàng
có thu nhập từ khoảng 10K - 30K USD hằng năm đứng thứ hai với tỷ lệ là
21.98% tương đương với 3090 khách hàng. Điều này cho thấy rằng nhóm
khách hàng có thu nhập thấp chiếm ưu thế với tổng cộng là 7091 khách
hàng, khoảng 54.71% số khách hàng.
Tiếp đến là nhóm có thu nhập trung bình, tổng cộng có 4692 khách
hàng, khoảng 33.38% số khách hàng có thu nhập trung bình. Cụ thể là số
khách hàng có thu nhập trung bình thấp (50K - 70K USD) chiếm tỷ lệ
16.86% và chiếm tỷ lệ cao nhất trong nhóm trung bình, tiếp đến là khách
có thu nhập trung bình (70K - 90K USD) chiếm tỷ lệ cao thứ hai trong
nhóm này, khoảng 12.16%. Cuối cùng là nhóm khách có thu nhập trung bình
cao (90K - 110K USD) chiếm tỷ lệ thấp nhất nhóm, chỉ khoảng 4.36% với
613 khách hàng.
Cuối cùng là nhóm có thu nhập cao (110K - hơn 150K USD hằng năm), đây
là nhóm chiếm tỷ lệ thấp nhất với chỉ 11.91% trong tổng số khách hàng
(1676 khách hàng). Cụ thể trong nhóm này, số khách hàng có thu nhập ở
mức 110K - 130K chiếm khoảng 4.57%, đứng thứ hai nhóm này. Dẫn đầu nhóm
này là tệp khách có thu nhập từ 130K - 150K hằng năm, khoảng 5.41% trong
tổng số khách hàng. Cuối cùng là nhóm khách có thu nhập hơn 150K USD
hằng năm, đây là nhóm khách có thu nhập cao nhất và chiếm tỷ lệ ít
nhất.
Thông qua bảng tần số và biểu đồ, ta có thể biết được rằng tệp khách
hàng chủ yếu ở đây là nhóm khách hàng có thu nhập thấp đến trung bình,
càng có thu nhập cao, việc mua sắm hay đi siêu thị càng ít đi.
2.5 Biến City
Trong bộ dữ liệu SupermarketTransactions.csv, biến
City đại diện cho thành
phố nơi khách hàng đang sinh sống. Trong biến này có bao gồm 23 biểu
hiện, tương đương với 23 thành phố mà các khách hàng trong file dữ liệu
đang sinh sống.
2.5.1 Thống kê tần số, tần suất
# Lập bảng tần số
c_f <- table(st$City)
# Lập bảng tần suất
c_p <- prop.table(c_f)*100
# Kết hợp thành một bảng
city <- data.frame(
Category = names(c_f),
Frequency = as.vector(c_f),
Percentage = round(as.vector(c_p), 2)
)
city
2.5.2 Trực quan hóa dữ liệu
ggplot(st, aes(x = City)) +
geom_bar(fill = "#558") +
geom_text(
aes(label = after_stat(count)),
stat = "count",
vjust = -0.3,
size = 3.5
) +
labs(title = "Figure 5: Current City of Customers", x = "City", y = "Frequency") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
plot.title = element_text(hjust = 0.5, face = "bold"))

Nhận xét: Ta thấy Salem dẫn đầu với 1.386 khách
(tương đương với khoảng 9.86%), gấp đôi so với nhiều thành phố khác,
trong khi Guadalajara chỉ có 75 khách (khoảng 0.53% tổng số khách hàng).
Các thành phố lớn như Los Angeles 926, Seattle 922, và San Diego 866
cũng có lượng khách hàng cao, phản ánh quy mô dân số và sức hút thị
trường. Ngược lại, một số thành phố như San Francisco 130 và Mexico City
194 lại có số khách thấp bất thường dù là trung tâm kinh tế, có thể do
hạn chế trong chiến lược kinh doanh hoặc thu thập dữ liệu. Dữ liệu tần
suất và tần số cho thấy sự chênh lệch rõ rệt giữa các thành phố.
2.6 Biến StateorProvine
StateorProvine là biến
thể hiện bang hoặc tỉnh nơi mà khách hàng đang sinh sống. Cụ thể biến
StateorProvine này bao gồm
10 biểu hiện thể hiện 10 bang mà tất cả các khách hàng hiện đang sinh
sống.
2.6.1 Thống kê tần số, tần suất
# Lập bảng tần số
sop_f <- table(st$StateorProvince)
# Lập bảng tần suất
sop_p <- prop.table(sop_f)*100
# Kết hợp thành một bảng
sop <- data.frame(
Category = names(sop_f),
Frequency = as.vector(sop_f),
Percentage = round(as.vector(sop_p), 2)
)
sop
2.6.2 Trực quan hóa dữ liệu
ggplot(st, aes(x = StateorProvince)) +
geom_bar(fill = "#558") +
geom_text(
aes(label = after_stat(count)),
stat = "count",
vjust = -0.3,
size = 3.5
) +
labs(title = "Figure 6: Current State or Provine of Customers", x = "State or Provine", y = "Frequency") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
plot.title = element_text(hjust = 0.5, face = "bold"))

Nhận xét: Dữ liệu thống kê theo bang/tỉnh cho thấy
sự chênh lệch đáng kể giữa các khu vực. WA dẫn đầu với con số ấn tượng
4.567 khách hàng (khoảng 32.48% trên tổng số khách hàng), cao gần gấp
đôi so với OR (2262 khách hàng hay 16.09%) và CA (2733 khách hàng hay
19.44%). Các bang CA (2733 khách hàng hay 19.44%), OR (2262 khách hàng
hay 16.09%), Zacatecas (1297 khách hàng hay 9.23%) nằm ở mức trung bình
trung bình, trong khi đó Guerrero với 383 khách hàng (2.72%), BC (809
khách hàng - 5.75%), DF (815 khách hàng - 5.8%), Veracruz (464 khách
hàng - 3.3%) và Yutacan (654 khách hàng - 4.65%) ở mức khá thấp. Đặc
biệt là Jalisco với chỉ 75 khách hàng (khoảng 0.53%) - thấp nhất trong
tất cả các khu vực được thống kê. Sự khác biệt lớn này có thể phản ánh
sự không đồng đều về quy mô dân số, mức độ hoạt động kinh tế hoặc các
yếu tố đặc thù khác của từng vùng.
2.7 Biến Country
Biến Country trong bộ
dữ liệu SupermarketTransactions.csv thể
hiện quốc gia mà khách hàng đang sinh sống. Cụ thể bao gồm 3 quốc gia là
USA (Hoa Kỳ), Mexico và Canada.
2.7.1 Thống kê tần số, tần suất
# Lập bảng tần số
co_f <- table(st$Country)
# Lập bảng tần suất
co_p <- prop.table(co_f)*100
# Kết hợp thành một bảng
country <- data.frame(
Category = names(co_f),
Frequency = as.vector(co_f),
Percentage = round(as.vector(co_p), 2)
)
country
2.7.2 Trực quan hóa dữ liệu
ggplot(data = country, aes(x = '', y = Frequency, fill = Category)) +
geom_col() +
coord_polar('y') +
geom_text(aes(label = percent(Frequency/length(st$MaritalStatus))), position = position_stack(vjust = 0.5)) + labs(title = 'Figure 7: Current Country of Customers') +
scale_fill_brewer(palette = "Set2") +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

Nhận xét: Dữ liệu cho thấy rằng đa số các hoạt động
giao dịch đều diễn ra ở Hoa Kỳ với 9562 khách hàng (khoảng 68% trên tổng
số), đứng thứ hai là Mexico với 3688 khách hàng (khoảng 26% trên tổng
số) và khiêm tốn nhất là Canada với 809 khách hàng (với chỉ 6% trên tổng
số).
2.8 Biến ProductFamily
ProductFamily (Nhóm sản
phẩm) là biến thể hiện nhóm các sản phẩm được mua chủ yếu ở siêu thị.
Các nhóm sản phẩm ở đây bao gồm 3 nhóm là Drink (Đồ uống), Food (Thực
phẩm) và Non-consumable (Phi tiêu dùng).
2.8.1 Thống kê tần số, tần suất
# Lập bảng tần số
pf_f <- table(st$ProductFamily)
# Lập bảng tần suất
pf_p <- prop.table(pf_f)*100
# Kết hợp thành một bảng
pf <- data.frame(
Category = names(pf_f),
Frequency = as.vector(pf_f),
Percentage = round(as.vector(pf_p), 2)
)
pf
2.8.2 Trực quan hóa dữ liệu
ggplot(data = pf, aes(x = '', y = Frequency, fill = Category)) +
geom_col() +
coord_polar('y') +
geom_text(aes(label = percent(Frequency/length(st$MaritalStatus))), position = position_stack(vjust = 0.5)) +
labs(title = 'Figure 8: Consumption by Product Family') +
scale_fill_brewer(palette = "Set2") +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

Nhận xét: Dữ liệu tần suất và tần số các nhóm sản
phẩm cho thấy sự chênh lệch rõ rệt giữa các danh mục. Nhóm Thực phẩm
(Food) chiếm ưu thế tuyệt đối với 72.22%, trở thành nhóm sản phẩm chủ
đạo trong hệ thống. Trong khi đó, nhóm Phi tiêu dùng (Non-Consumable)
đạt 18.89%, và nhóm Đồ uống (Drink) có tần suất thấp nhất, chỉ chiếm
8.89%. Sự phân bố này phản ánh rõ nhu cầu tiêu dùng tập trung chủ yếu
vào các sản phẩm thực phẩm, gấp hơn 3 lần so với nhóm phi tiêu dùng và
gấp 8 lần so với đồ uống. Điều này có thể xuất phát từ đặc điểm kinh
doanh của cửa hàng hoặc thói quen mua sắm của khách hàng.
2.9 Biến ProductDepartment
ProductDepartment là
biến thể hiện danh mục các sản phẩm được tiêu thụ tại siêu thị bao gồm
22 biểu hiện tương ứng với 22 danh mục sản phẩm.
2.9.1 Thống kê tần số, tần suất
# Lập bảng tần số
pd_f <- table(st$ProductDepartment)
# Lập bảng tần suất
pd_p <- prop.table(pd_f)*100
# Kết hợp thành một bảng
pd <- data.frame(
Category = names(pd_f),
Frequency = as.vector(pd_f),
Percentage = round(as.vector(pd_p), 2)
)
pd
2.9.2 Trực quan hóa dữ liệu
ggplot(st, aes(x = ProductDepartment)) +
geom_bar(fill = "#558") +
geom_text(
aes(label = after_stat(count)),
stat = "count",
vjust = -0.3,
size = 3.5
) +
labs(title = "Figure 9: Consumption by Product Department", x = "Product Department", y = "Frequency") +
theme_minimal() +
theme( axis.text.x = element_text(angle = 90, hjust = 1),
plot.title = element_text(hjust = 0.5, face = "bold"))

Nhận xét: Dữ liệu tần số tiêu thụ sản phẩm cho thấy
sự phân bố không đồng đều giữa các danh mục. Nhóm Produce (sản phẩm tươi
sống) dẫn đầu với tần suất cao nhất (1994, khoảng 14.18%), tiếp theo là
Household (đồ gia dụng - 1420) và Frozen Foods (đồ đông lạnh - 1382),
phản ánh nhu cầu thiết yếu hàng ngày của người tiêu dùng. Các nhóm Snack
Foods (đồ ăn vặt - 1600) và Dairy (chế phẩm từ sữa - 903) cũng có tần
suất đáng kể, cho thấy xu hướng tiêu dùng đồ ăn nhẹ và sản phẩm từ sữa.
Đáng chú ý, một số nhóm có tần suất thấp như Carousel (các sản phẩm bán
tại quầy thu ngân - 59), Seafood (hải sản - 102) và Alcoholic Beverages
(thức uống có cồn - 356), có thể do đặc thù ngành hàng hoặc hạn chế
trong chính sách bán hàng. Sự chênh lệch lớn giữa nhóm cao nhất (Produce
- 1994) và thấp nhất (Carousel - 59) cho thấy sự tập trung chủ yếu vào
các mặt hàng thiết yếu, trong khi nhóm hàng đặc biệt hoặc không thiết
yếu có tần suất tiêu thụ thấp hơn rõ rệt. Dữ liệu này giúp nhà quản lý
xác định được nhóm sản phẩm cần ưu tiên phát triển và những mặt hàng cần
có chiến lược tiếp thị phù hợp để tăng doanh số.
2.10 Biến ProductCategory
ProductCategory là biến
thể hiện phân loại nhóm hàng hóa được tiêu thụ tại siêu thị, cụ thể bao
gồm 45 nhóm hàng đại diện cho 45 biểu hiệu của biến ProductCategory trong bộ dữ liệu
SupermarketTransactions.csv.
2.10.1 Thống kê tần số, tần suất
# Lập bảng tần số
pc_f <- table(st$ProductCategory)
# Lập bảng tần suất
pc_p <- prop.table(pc_f)*100
# Kết hợp thành một bảng
pc <- data.frame(
Category = names(pc_f),
Frequency = as.vector(pc_f),
Percentage = round(as.vector(pc_p), 2)
)
pc
2.10.2 Trực quan hóa dữ liệu
ggplot(st, aes(x = ProductCategory)) +
geom_bar(fill = "#558") +
labs(title = "Figure 10: Consumption by Product Category", x = "Product Category", y = "Frequency") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
plot.title = element_text(hjust = 0.5, face = "bold"))

Nhận xét: Dữ liệu tần suất tiêu thụ sản phẩm thể
hiện sự phân hóa rõ rệt giữa các nhóm hàng. Vegetables (12.29) và Snack
Foods (11.38) dẫn đầu với tần suất vượt trội, phản ánh nhu cầu thiết yếu
về rau củ tươi và đồ ăn vặt tiện lợi trong thói quen tiêu dùng. Các mặt
hàng chủ lực khác như Dairy (6.42), Meat (5.41) và Fruit (5.44) cũng duy
trì tần suất cao, trong khi nhóm Jams and Jellies (4.18) và Baking Goods
(3.44) chiếm vị trí trung bình. Đặc biệt, nhóm Canned Oysters (0.25),
Canned Anchovies (0.31) và Miscellaneous (0.30) có tần suất thấp nhất,
chỉ bằng 1/50 so với nhóm dẫn đầu, cho thấy đây là những mặt hàng ngách
hoặc ít được ưa chuộng. Sự chênh lệch đáng kể giữa các nhóm hàng (từ
0.25 đến 12.29) gợi ý rằng:
Các sản phẩm tươi sống và thiết yếu luôn chiếm ưu thế
Đồ hộp và hàng đặc sản có phạm vi tiêu thụ hẹp
Nhóm đồ uống (Beer and Wine: 2.53, Hot Beverages: 1.61) có tiềm
năng phát triển thêm
Phân tích này cung cấp cơ sở để tối ưu hóa cơ cấu hàng hóa, tập trung
nguồn lực vào nhóm có tần suất cao đồng thời cân nhắc giảm bớt mặt hàng
có hiệu suất thấp để nâng cao hiệu quả kinh doanh tổng thể.
PHẦN 3: ƯỚC LƯỢNG KHOẢNG VÀ KIỂM ĐỊNH GIẢ THUYẾT CHO TỶ
LỆ
Trong thống kê suy diễn, việc ước lượng khoảng và kiểm định giả
thuyết cho tỷ lệ là một bước quan trọng, đặc biệt là trong trường hợp
muốn đưa ra kết luận về quần thể dựa trên mẫu. Khi khảo sát, ta chỉ lấy
một mẫu nhỏ từ quần thể lớn, mà mẫu đại diện cho quần thể nên ta cần ước
lượng được khoảng tin cậy cho tỷ lệ thật sự bên ngoài quần thể. Ngoài ra
ước lượng khoảng còn đưa ra được một khoảng tin cậy thể hiện độ chính
xác của tỷ lệ.
3.1 Country - USA
Việc ước lượng khoảng tin cậy cho tỷ lệ khách hàng đến từ “USA” trong
biến Country là cần thiết
nhằm suy ra tỷ lệ thật sự của nhóm này trong toàn bộ quần thể khách
hàng, chứ không chỉ dựa vào tỷ lệ quan sát được từ mẫu. Do dữ liệu thu
thập chỉ là một phần nhỏ của quần thể, nên tỷ lệ “USA” trong mẫu có thể
dao động do ngẫu nhiên. Thông qua khoảng tin cậy, ta có thể xác định một
khoảng giá trị hợp lý mà trong đó, với một mức độ tin cậy (thường là
95%), tỷ lệ thật sự của khách hàng đến từ Mỹ có khả năng nằm trong đó.
Điều này có thể giúp cho các nhà quản lý có thể có căn cứ trong việc đẩy
mạnh vào thị trường Mỹ hơn các thị trường khác do đa số khách hàng đến
từ Mỹ.
Ước lượng khoảng tin cậy: Với số lượng khách hàng
đến từ Mỹ là 9562 trên tổng số khách hàng là 14059, ta có kết quả ước
lượng khoảng tin cậy với độ tin cậy 95% như sau:
# Số lượng khách hàng đến từ "USA"
usa <- sum(st$Country == "USA")
# Tổng số khách hàng
total <- length(st$Country)
# Kiểm định tỷ lệ 1 mẫu
prop.test(usa, total, p = 0.68, conf.level = 0.95)
##
## 1-sample proportions test with continuity correction
##
## data: usa out of total, null probability 0.68
## X-squared = 0.00062251, df = 1, p-value = 0.9801
## alternative hypothesis: true p is not equal to 0.68
## 95 percent confidence interval:
## 0.6723397 0.6878289
## sample estimates:
## p
## 0.6801337
Kết luận:
Đặt giả thuyết: \[
\left\{
\begin{array}{ll}
H_0: & \text{Tỷ lệ thực số khách hàng đến từ USA } = 0.68 \\
H_1: & \text{Tỷ lệ thực số khách hàng đến từ USA } \ne 0.68
\end{array}
\right.
\]
Ta thấy giá trị p_value = 0.9801 > 5% nên ta không đủ cơ sở để bác
bỏ \(H_0\), nghĩa là tỷ lệ số khách
hàng đến từ USA trong thực tế là 68%. Ngoài ra, ta có thể ước lượng số
khách hàng đến từ USA trong thực tế với độ tin cậy 95% nằm trong khoảng
từ 67.23% đến 68.78%.
Kiểm định abc
3.2 ProductFamily - Food
Việc ước lượng khoảng tin cậy cho tỷ lệ họ sản phẩm là “Food” trong
biến ProductFamily là cần
thiết. Kết quả của ước lượng này có thể giúp các nhà quản lý xác định
được có nên đẩy mạnh phát triển các sản phẩm thuộc họ “Food” hay không
thông qua tỷ lệ được ước lượng. Nếu tỷ lệ là đúng, việc đẩy mạnh vào
phát triển sản phẩm thuộc họ thức ăn sẽ giúp tăng doanh thu của các siêu
thị vì đa số các khách hàng đến để mua thức ăn.
Ước lượng khoảng tin cậy: Với số loại thực phẩm
thuộc “Food” là 10153 trên tổng số là 14059, ta có kết quả ước lượng
khoảng tin cậy với độ tin cậy 95% như sau:
# Số lượng thực phẩm là "Food"
food <- sum(st$ProductFamily == "Food")
# Kiểm định tỷ lệ 1 mẫu
prop.test(food, total, p = 0.72, conf.level = 0.95)
##
## 1-sample proportions test with continuity correction
##
## data: food out of total, null probability 0.72
## X-squared = 0.31796, df = 1, p-value = 0.5728
## alternative hypothesis: true p is not equal to 0.72
## 95 percent confidence interval:
## 0.7146709 0.7295489
## sample estimates:
## p
## 0.7221709
Kết luận:
Đặt giả thuyết: \[
\left\{
\begin{array}{ll}
H_0: & \text{Tỷ lệ thực tế khách hàng mua thực phẩm } = 0.72 \\
H_1: & \text{Tỷ lệ thực tế khách hàng mua thực phẩm } \ne 0.72
\end{array}
\right.
\]
Ta thấy giá trị xác suất p_value = 0.5728 > 5% nghĩa là ta chấp
nhận \(H_0\), khi đó ta kết luận rằng
tỷ lệ khách hàng mua thực phẩm trong thực tế là khoảng 72%. Ngoài ra ta
còn ước lượng trong thực tế, số lượng thực phẩm chiếm khoảng 71.47% đến
72.95% với mức ý nghĩa 5%.
3.3 AnnualIncome - $10K - $50K
Việc ước lượng khoảng tin cậy cho khách có mức thu nhập thấp (khoảng
từ 10K đến 50K USD hằng năm) sẽ giúp siêu thị có thể có những chiến lược
quảng cáo hay bán hàng nhắm vào tệp khách hàng thường mua sắm, giúp tối
ưu doanh thu và lợi nhuận của siêu thị.
Ước lượng khoảng tin cậy:
# Số khách hàng có thu nhập trung bình
mid <- sum(st$AnnualIncome == "$30K - $50K",st$AnnualIncome == "$10K - $30K")
# Kiểm định tỷ lệ 1 mẫu
prop.test(mid, total, p = 0.55, conf.level = 0.95)
##
## 1-sample proportions test with continuity correction
##
## data: mid out of total, null probability 0.55
## X-squared = 0.48192, df = 1, p-value = 0.4876
## alternative hypothesis: true p is not equal to 0.55
## 95 percent confidence interval:
## 0.5387761 0.5553015
## sample estimates:
## p
## 0.5470517
Kết luận:
Đặt giả thuyết
\[
\left\{
\begin{array}{ll}
H_0: & \text{Tỷ lệ thực tế khách hàng có thu nhập thấp } = 0.55 \\
H_1: & \text{Tỷ lệ thực tế khách hàng có thu nhập thấp } \ne 0.55
\end{array}
\right.
\]
Ta thấy giá trị xác suất p_value = 0.4876 > 5% nghĩa là ta chấp
nhận \(H_0\), khi đó ta kết luận rằng
tỷ lệ khách hàng có thu nhập thấp trong thực tế là khoảng 55%. Ngoài ra
ta còn ước lượng trong thực tế, số lượng khách hàng có thu nhập thấp
chiếm khoảng 53.88% đến 55.53%% với mức ý nghĩa 5%.
PHẦN 5: TỔNG KẾT VÀ THẢO LUẬN
5.1 Những phát hiện chính
Kết quả ước lượng khoảng cho thấy mẫu này phản ảnh được chính xác tỷ
lệ trong thực tế. Ngoài ra các kết quả về phân tích mối quan hệ giữa hai
biến định tính cho thấy rằng có mối liên hệ giữa giới tính của khách
hàng và loại sản phẩm mà họ mua cũng như với thu nhập của khách
hàng.
5.2 Hạn chế của phân tích
Phân tích này vẫn chưa thực sự hiệu quả vì chỉ đưa ra 3 cặp biến để
phân tích mối quan hệ. Trong thực tế các biến thực chất sẽ có nhiều quan
hệ chồng chéo và phức tạp hơn chứ không chỉ giữa hai cặp biến với
nhau.
5.3 Đề xuất
Dựa trên kết quả ước lượng khoảng và phân tích mối quan hệ giữa các
biến định tính, có thể đề xuất một số giải pháp nhằm nâng cao hiệu quả
hoạt động kinh doanh của siêu thị. Thứ nhất, việc nhận thấy có sự khác
biệt trong hành vi mua sắm theo giới tính cho thấy cần xây dựng các
chiến lược tiếp thị riêng biệt cho từng nhóm giới, chẳng hạn như thiết
kế nội dung quảng cáo hoặc chương trình khuyến mãi phù hợp với thói quen
tiêu dùng của nam và nữ. Thứ hai, kết hợp giữa giới tính và mức thu nhập
để phân khúc khách hàng một cách chi tiết hơn sẽ giúp siêu thị đưa ra
các sản phẩm và mức giá phù hợp với từng nhóm đối tượng. Ngoài ra, có
thể cá nhân hóa trải nghiệm mua sắm thông qua các gợi ý sản phẩm, email
marketing hoặc ưu đãi dựa trên thông tin về giới tính và thu nhập của
khách hàng. Bên cạnh đó, việc bố trí lại không gian trưng bày sản phẩm
theo thói quen mua sắm của từng nhóm khách hàng cũng sẽ giúp cải thiện
trải nghiệm và tăng khả năng bán hàng. Cuối cùng, kết quả phân tích còn
hỗ trợ siêu thị trong việc xây dựng kế hoạch nhập hàng hợp lý, tập trung
vào những mặt hàng có nhu cầu cao theo từng nhóm khách cụ thể, từ đó
giảm thiểu hàng tồn kho và tối ưu hóa doanh thu.
5.4 Hướng nghiên cứu tiếp theo
Có thể phân tích mối quan hệ giữa nhiều biến lên một biến và nhiều
biến lên nhau để đưa ra được phân tích chính xác nhất.
LS0tDQp0aXRsZTogJyoqUFRETERUOiBCMioqJw0KYXV0aG9yOiAiTmd1eeG7hW4gVHLhuqduIEtow6FuaCBTYW4iDQpkYXRlOiAiMjAyNS0wNS0xOSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdG9jX2RlcHRoOiAyDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG89RkFMU0V9DQpib2R5IHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBzYW5zLXNlcmlmOw0KfQ0KDQpoMSwgaDIsIGgzIHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBzZXJpZjsNCiAgY29sb3I6ICMyYzNlNTA7DQp9DQpgYGANCg0KYGBge2NzcywgZWNobz1GQUxTRX0NCi8qIFTEg25nIGPhu6EgY2jhu68gdG/DoG4gYuG7mSB2xINuIGLhuqNuICovDQpib2R5IHsNCiAgZm9udC1zaXplOiAxOHB4Ow0KfQ0KDQovKiBUxINuZyBj4buhIGNo4buvIHRpw6p1IMSR4buBICovDQpoMSB7IGZvbnQtc2l6ZTogMi4yZW07IH0NCmgyIHsgZm9udC1zaXplOiAxLjhlbTsgfQ0KaDMgeyBmb250LXNpemU6IDEuNWVtOyB9DQoNCi8qIFTEg25nIGPhu6EgY2jhu68gxJFv4bqhbiB2xINuICovDQpwIHsNCiAgZm9udC1zaXplOiAxLjFlbTsNCiAgbGluZS1oZWlnaHQ6IDEuNjsgLyogVMSDbmcga2hv4bqjbmcgY8OhY2ggZMOybmcgY2hvIGThu4UgxJHhu41jICovDQp9DQoNCi8qIFTEg25nIGPhu6EgY2jhu68gY29kZSAqLw0KY29kZSB7DQogIGZvbnQtc2l6ZTogMTZweDsNCn0NCmBgYA0KDQojICoqUEjhuqZOIDE6IENIVeG6qE4gQuG7iiBWw4AgVMOMTSBISeG7glUgROG7riBMSeG7hlUqKg0KDQojIyAqKjEuMSDEkOG7jWMgZOG7ryBsaeG7h3UqKg0KDQpT4butIGThu6VuZyBjw6J1IGzhu4duaCBbYHJlYWQuY3N2KClgXXtzdHlsZT0iY29sb3I6cHVycGxlIn0gxJHhu4Mgbmjhuq1wIGThu68gbGnhu4d1IHbhu5tpIFtgRDovZG93bmxvYWQvU3VwZXJtYXJrZXRUcmFuc2FjdGlvbnMuY3N2YF17c3R5bGU9ImNvbG9yOnJlZCJ9IGzDoCDEkcaw4budbmcgbGluayBj4bunYSBmaWxlIGThu68gbGnhu4d1IFtgU3VwZXJtYXJrZXRUcmFuc2FjdGlvbnMuY3N2YF17c3R5bGU9ImNvbG9yOmJsdWUifS4gVOG6oW0gZ+G7jWkgYuG7mSBk4buvIGxp4buHdSBuw6B5IGzDoCBbYHN0YF17c3R5bGU9ImNvbG9yOmJsdWUifS4NCg0KYGBge3J9DQpzdCA8LSByZWFkLmNzdigiRDovZG93bmxvYWQvU3VwZXJtYXJrZXRUcmFuc2FjdGlvbnMuY3N2IikNCnRhYmxlKHN0JEhvbWVvd25lcixzdCRBbm51YWxJbmNvbWUpDQpgYGANCg0KIyMgKioxLjIgTMOgbSBxdWVuIHbhu5tpIGThu68gbGnhu4d1KioNCg0KQ+G6pXUgdHLDumMgY+G7p2EgZOG7ryBsaeG7h3UgKERhdGEgU3RydWN0dXJlKSBoYXkgY+G6pXUgdHLDumMgbuG7mWkgdOG6oWkgY+G7p2EgZOG7ryBsaeG7h3UgbMOgIGPDoWNoIHThu5UgY2jhu6ljIGLDqm4gdHJvbmcgZOG7ryBsaeG7h3UgxJHDsy4gTeG7mXQgdHJvbmcgbmjhu69uZyBow6BtIGPDsyB0aOG7gyBjaG8gYmnhur90IMSRxrDhu6NjIGPhuqV1IHRyw7pjIGPhu6dhIGThu68gbGnhu4d1IHRyb25nIFIgbMOgIGjDoG0gW2BzdHIoKWBde3N0eWxlPSJjb2xvcjpwdXJwbGUifSwgaMOgbSBbYHN0cigpYF17c3R5bGU9ImNvbG9yOnB1cnBsZSJ9IGNobyBiaeG6v3Qga2nhu4N1IGThu68gbGnhu4d1LCBz4buRIGzGsOG7o25nIHBo4bqnbiB04butIGLDqm4gdHJvbmcgZOG7ryBsaeG7h3UsIHTDqm4gY8OhYyBj4buZdCB2w6AgY8OhYyBwaOG6p24gdOG7rSDEkeG6p3UgdGnDqm4gdHJvbmcgY8OhYyBj4buZdC4NCg0KYGBge3J9DQpzdHIoc3QpDQpgYGANCg0KR2nhuqNpIHRow61jaCBr4bq/dCBxdeG6ozoNCg0KLSAgIGAnZGF0YS5mcmFtZSc6ICAgIDE0MDU5IG9icy4gb2YgIDE2IHZhcmlhYmxlczpgOiBE4buvIGxp4buHdSBsw6AgbeG7mXQgZGF0YSBmcmFtZSAoZOG7ryBsaeG7h3UgZOG6oW5nIGLhuqNuZykgduG7m2kgMTQwNTkgcXVhbiBzw6F0IHbDoCAxNiBiaeG6v24uDQoNCi0gICBEYW5oIHPDoWNoIGPDoWMgYmnhur9uIGJhbyBn4buTbTogWCwgUHVyY2hhc2VEYXRlLCBDdXN0b21lcklELCBHZW5kZXIsIE1hcml0YWxTdGF0dXMsIEhvbWVvd25lciwgQ2hpbGRyZW4sIEFubnVhbEluY29tZSwgQ2l0eSwgU3RhdGVvclByb3ZpbmUsIENvdW50cnksIFByb2R1Y3RGYW1pbHksIFByb2R1Y3REZXBhcnRtZW50LCBQcm9kdWN0Q2F0ZWdvcnksIFVuaXRTb2xkLCBSZXZlbnVlLg0KDQotICAgYGNocmAsIGBpbnRgLCBgbnVtYCBsw6AgxJHhu4tuaCBk4bqhbmcgY+G7p2EgdOG7q25nIGJp4bq/bi4gQ+G7pSB0aOG7gyBgY2hyYCBsw6AgYGNoYXJhY3RlcmAgY8OzIG5naMSpYSBsw6AgZOG6oW5nIGvDrSB04buxLCBgaW50YCBsw6AgYGludGVnZXJgIGPDsyBuZ2jEqWEgbMOgIGThuqFuZyBz4buRIG5ndXnDqm4gY8OybiBgbnVtYCBuZ2jEqWEgbMOgIGBudW1iZXJgIGPDsyBuZ2jEqWEgbMOgIGThuqFuZyBz4buRLg0KDQotICAgQ8OhYyBiaeG6v24gY8OzIMSR4buLbmggZOG6oW5nIGBjaHJgIGJhbyBn4buTbTogUHVyY2hhc2VEYXRlLCBHZW5kZXIsIE1hcml0YWxTdGF0dXMsIEhvbWVvd25lciwgQW5udWFsSW5jb21lLCBDaXR5LCBTdGF0ZW9yUHJvdmluZSwgQ291bnRyeSwgUHJvZHVjdEZhbWlseSwgUHJvZHVjdERlcGFydG1lbnQsIFByb2R1Y3RDYXRlZ29yeS4NCg0KLSAgIEPDoWMgYmnhur9uIGPDsyDEkeG7i25oIGThuqFuZyBsw6AgYGludGAgYmFvIGfhu5NtOiBYLCBDdXN0b21lcklELCBDaGlsZHJlbiwgVW5pdFNvbGQuDQoNCi0gICBCaeG6v24gY8OzIMSR4buLbmggZOG6oW5nIGzDoCBgbnVtYCBsw6AgYmnhur9uIFJldmVudWUuDQoNClRyb25nIGtow6FtIHBow6EgZOG7ryBsaeG7h3UsIHZp4buHYyBoaeG7g24gdGjhu4sgZMOybmcgxJHhuqd1IHbDoCBkw7JuZyBjdeG7kWkgY+G7p2EgZOG7ryBsaeG7h3UgbMOgIG3hu5l0IGLGsOG7m2MgZ2nDunAgdGEgY8OzIHRo4buDIHhlbSBzxqEgbMaw4bujYyBu4buZaSBkdW5nIGPhu6dhIGThu68gbGnhu4d1LCBwaMOhdCBoaeG7h24gbOG7l2kgaG/hurdjIGPDoWMgZ2nDoSB0cuG7iyBi4bqldCB0aMaw4budbmcgKG7hur91IGPDsykgdsOgIGPDsyB0aOG7gyBraeG7g20gdHJhIHhlbSBk4buvIGxp4buHdSBuaOG6rXAgdOG7qyBmaWxlIGPDsyBjaMOtbmggeMOhYyBsw6AgZOG7ryBsaeG7h3UgdGEgY+G6p24gdMOsbSBoYXkga2jDtG5nLiDEkOG7gyB0aOG7sWMgaGnhu4duLCB0YSBz4butIGThu6VuZyBow6BtIFtgaGVhZCgpYF17c3R5bGU9ImNvbG9yOnB1cnBsZSJ9IHbDoCBbYHRhaWwoKWBde3N0eWxlPSJjb2xvcjpwdXJwbGUifSB0cm9uZyBSLiBUcm9uZyDEkcOzIGjDoG0gW2BoZWFkKClgXXtzdHlsZT0iY29sb3I6cHVycGxlIn0gbMOgIMSR4buDIGhp4buDbiB0aOG7iyA2IGTDsm5nIMSR4bqndSBj4bunYSBi4buZIGThu68gbGnhu4d1IGPDsm4gaMOgbSBbYHRhaWwoKWBde3N0eWxlPSJjb2xvcjpwdXJwbGUifSBsw6AgxJHhu4MgaGnhu4NuIHRo4buLIDYgZMOybmcgY3Xhu5FpIGPhu6dhIGThu68gbGnhu4d1Lg0KDQpgYGB7cn0NCmhlYWQoc3QpDQpgYGANCg0KYGBge3J9DQp0YWlsKHN0KQ0KYGBgDQoNClRyb25nIGPDoWMgYuG7mSBk4buvIGxp4buHdSwgZ2nDoSB0cuG7iyBOQSAoTm90IEF2YWlsYWJsZSkgbmdoxKlhIGzDoCBnacOhIHRy4buLIGLhu4sgdGhp4bq/dSAobWlzc2luZyB2YWx1ZSkgaG/hurdjIGdpw6EgdHLhu4sga2jDtG5nIGPDsyBz4bq1bi4gTkEga2hp4bq/biBjaG8gdmnhu4djIHTDrW5oIHRvw6FuIGLDqm4gdHJvbmcgZOG7ryBsaeG7h3UgdHLhu58gbsOqbiBraMOzIGtoxINuLCBraGnhur9uIGPDoWMgxrDhu5tjIGzGsOG7o25nIHRy4bufIG7Dqm4gc2FpIGzhu4djaCB2w6AgbMOgbSBnaeG6o20gY2jhuqV0IGzGsOG7o25nIGtoaSB0cuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1LiDEkOG7gyBraeG7g20gdHJhIHLhurFuZyB0cm9uZyBi4buZIGThu68gbGnhu4d1IGPDsyBjw6FjIGdpw6EgdHLhu4sgTkEgaGF5IGtow7RuZywgdGEgY8OzIHRo4buDIHPhu60gZOG7pW5nIGjDoG0gW2Bpcy5uYSgpYF17c3R5bGU9ImNvbG9yOnB1cnBsZSJ9IGvhur90IGjhu6NwIHbhu5tpIGjDoG0gW2BzdW0oKWBde3N0eWxlPSJjb2xvcjpwdXJwbGUifSDEkeG7gyB4ZW0geMOpdCBjw7MgYmFvIG5oacOqdSBnacOhIHRy4buLIE5BIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UuDQoNCmBgYHtyfQ0Kc3VtKGlzLm5hKHN0KSkNCmBgYA0KDQpL4bq/dCBxdeG6oyBjaG8gdGjhuqV5IHPhu5EgZ2nDoSB0cuG7iyBOQSB0cm9uZyBi4buZIGThu68gbGnhu4d1IG7DoHkgbMOgIDAuIFbDrCB0aOG6vyB0YSBraMO0bmcgY+G6p24gcGjhuqNpIHPhu60gZOG7pW5nIGPDoWMgcGjGsMahbmcgcGjDoXAgxJHhu4MgeOG7rSBsw70gZOG7ryBsaeG7h3UgbuG6v3UgZOG7ryBsaeG7h3UgY8OzIGdpw6EgdHLhu4sgbMOgIE5BLg0KDQpCaeG6v24gcGjDom4gbG/huqFpIGzDoCBsb+G6oWkgYmnhur9uIHRyb25nIGThu68gbGnhu4d1IG3DoCBjw6FjIGdpw6EgdHLhu4sgY+G7p2EgbsOzIMSR4bqhaSBkaeG7h24gY2hvIG5ow7NtLCBsb+G6oWksIGhheSBkYW5oIG3hu6VjIHJpw6puZyBiaeG7h3QsIGtow7RuZyBjw7Mgw70gbmdoxKlhIHPhu5EgaOG7jWMgbmjGsCBj4buZbmcgdHLhu6sgbmjDom4gY2hpYS4gQ2h1eeG7g24gY8OhYyBiaeG6v24gduG7gSBraeG7g3UgYGZhY3RvcmAgbMOgIG3hu5l0IHRoYW8gdMOhYyBxdWFuIHRy4buNbmcgZ2nDunAgUiBoaeG7g3UgdsOgIHjhu60gbMO9IMSRw7puZyBi4bqjbiBjaOG6pXQgY+G7p2EgZOG7ryBsaeG7h3UsIG3DtCBow6xuaCBow7NhIGNow61uaCB4w6FjIHbDoCB0csOhbmggbOG7l2kgbG9naWMgdHJvbmcgcGjDom4gdMOtY2guIMSQ4buDIGNodXnhu4NuIMSR4buVaSBjw6FjIGJp4bq/biB24buBIGxv4bqhaSBgZmFjdG9yYCwgdGEgc+G7rSBk4bulbmcgaMOgbSBbYGFzLmZhY3RvcigpYF17c3R5bGU9ImNvbG9yOnB1cnBsZSJ9LiBUcm9uZyBi4buZIGThu68gbGnhu4d1IFtgU3VwZXJtYXJrZXRUcmFuc2FjdGlvbnMuY3N2YF17c3R5bGU9ImNvbG9yOmJsdWUifSwgdGEgdGjhuqV5IMSRxrDhu6NjIGPDsyBuaGnhu4F1IGJp4bq/biB0aHXhu5ljIHBow6JuIGxv4bqhaSBsw6AgYGZhY3RvcmAgYmFvIGfhu5NtOiBHZW5kZXIsIE1hcml0YWxTdGF0dXMsIEhvbWVvd25lciwgQW5udWFsSW5jb21lLCBDaXR5LCBTdGF0ZW9yUHJvdmluZSwgQ291bnRyeSwgUHJvZHVjdEZhbWlseSwgUHJvZHVjdERlcGFydG1lbnQsIFByb2R1Y3RDYXRlZ29yeS4gxJDhu4MgY2h1eeG7g24gxJHhu5VpIGNow7puZyB24buBIGThuqFuZyBgZmFjdG9yYCwgdGEgdGjhu7FjIGhp4buHbiBuaMawIHNhdToNCg0KYGBge3J9DQpzdCRHZW5kZXIgPC0gYXMuZmFjdG9yKHN0JEdlbmRlcikNCnN0JE1hcml0YWxTdGF0dXMgPC0gYXMuZmFjdG9yKHN0JE1hcml0YWxTdGF0dXMpDQpzdCRIb21lb3duZXIgPC0gYXMuZmFjdG9yKHN0JEhvbWVvd25lcikNCnN0JEFubnVhbEluY29tZSA8LSBhcy5mYWN0b3Ioc3QkQW5udWFsSW5jb21lKQ0Kc3QkQ2l0eSA8LSBhcy5mYWN0b3Ioc3QkQ2l0eSkNCnN0JFN0YXRlb3JQcm92aW5jZSA8LSBhcy5mYWN0b3Ioc3QkU3RhdGVvclByb3ZpbmNlKQ0Kc3QkUHJvZHVjdEZhbWlseSA8LSBhcy5mYWN0b3Ioc3QkUHJvZHVjdEZhbWlseSkNCnN0JFByb2R1Y3REZXBhcnRtZW50IDwtIGFzLmZhY3RvcihzdCRQcm9kdWN0RGVwYXJ0bWVudCkNCnN0JFByb2R1Y3RDYXRlZ29yeSA8LSBhcy5mYWN0b3Ioc3QkUHJvZHVjdENhdGVnb3J5KQ0KYGBgDQoNClNhdSBraGkgxJHDoyBjaHV54buDbiDEkeG7lWkgY8OhYyBiaeG6v24gxJHhu4MgcGjDom4gbG/huqFpIHbhu4EgYGZhY3RvcmAsIHRhIGPDsyB0aOG7gyBz4bq1biBzw6BuZyBkw7luZyBk4buvIGxp4buHdSBuw6B5IMSR4buDIHRp4bq/biBow6BuaCBjw6FjIGLGsOG7m2MgcGjDom4gdMOtY2ggdGnhur9wIHRoZW8uDQoNCiMgKipQSOG6pk4gMjogUEjDgk4gVMONQ0ggVsOAIE3DlCBU4bqiIEPDgUMgQknhur5OIMSQ4buKTkggVMONTkgqKg0KDQpDw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oIMSRxrDhu6NjIGhp4buDdSBsw6AgY8OhYyBiaeG6v24ga2jDtG5nIMSRxrDhu6NjIGJp4buDdSBkaeG7hW4gdGjDoG5oIHPhu5EsIHbDrCB0aOG6vyB0cm9uZyBwaMOibiB0w61jaCwgxJHhurdjIGJp4buHdCBsw6AgcGjDom4gdMOtY2ggdGjhu5FuZyBrw6osIHRhIGtow7RuZyB0aOG7gyBz4butIGThu6VuZyB0aGFvIHTDoWMgdGjhu5FuZyBrw6ogbcO0IHThuqMgdGjDtG5nIHRoxrDhu51uZy4gVGhheSB2w6BvIMSRw7MsIHZp4buHYyB0w61uaCB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQgY8WpbmcgbmjGsCB0cuG7sWMgcXVhbiBow7NhIGNow7puZyBsw6AgY8O0bmcgY+G7pSBo4buvdSBoaeG7h3UgaMahbi4gRMaw4bubaSDEkcOieSBsw6Aga+G6v3QgcXXhuqMgdGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0IHbDoCDEkeG7kyB0aOG7iyDEkeG7gyB0cuG7sWMgcXVhbiBow7NhIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmguDQoNCiMjICoqMi4xIEJp4bq/biBHZW5kZXIqKg0KDQojIyMgKioqMi4xLjEgVGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0KioqDQoNClRyb25nIGLhu5kgZOG7ryBsaeG7h3UgW2BTdXBlcm1hcmtldFRyYW5zYWN0aW9ucy5jc3ZgXXtzdHlsZT0iY29sb3I6Ymx1ZSJ9LCBbYEdlbmRlcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IGzDoCBiaeG6v24gbmjhurFtIG3DtCB04bqjIGdp4bubaSB0w61uaCBj4bunYSBraMOhY2ggaMOgbmcsIGThu68gbGnhu4d1IGPhu6dhIGJp4bq/biBuw6B5IGfhu5NtIDIgcGjDom4gbG/huqFpIGzDoCBNICh2aeG6v3QgdOG6r3QgY2hvIE1hbGUgLSBOYW0pIHbDoCBGICh2aeG6v3QgdOG6r3QgY2hvIEZlbWFsZSAtIE7hu68pLiDEkOG7gyB0w61uaCB04bqnbiBz4buRIGLDqm4gdHJvbmcgYuG7mSBk4buvIGxp4buHdSBuw6B5LCB0YSBz4butIGThu6VuZyBjw6J1IGzhu4duaCBbYHRhYmxlKClgXXtzdHlsZT0iY29sb3I6cHVycGxlIn0gdsOgIMSR4buDIHTDrW5oIHThuqduIHN14bqldCwgdGEgdGnhur9uIGjDoG5oIGNoaWEgdOG6p24gc+G7kSBjaG8gdOG7lW5nIHPhu5EgbMaw4bujbmcgcXVhbiBzw6F0IGPhu6dhIGThu68gbGnhu4d1Lg0KDQpCw6puIGTGsOG7m2kgbMOgIGzDoCBjw6FjIGPDonUgbOG7h25oIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHTDrW5oIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCBj4bunYSBiaeG6v24gW2BHZW5kZXJgXXtzdHlsZT0iY29sb3I6Z3JlZW4ifSwgY+G7pSB0aOG7gzogW2B0YWJsZSgpYF17c3R5bGU9ImNvbG9yOnB1cnBsZSJ9IHRy4bqjIHbhu4Ega+G6v3QgcXXhuqMgbMOgIHThuqduIHPhu5EgY+G7p2EgYmnhur9uIFtgR2VuZGVyYF17c3R5bGU9ImNvbG9yOmdyZWVuIn07IFtgcHJvcC50YWJsZSgpYF17c3R5bGU9ImNvbG9yOnB1cnBsZSJ9IHRy4bqjIHbhu4Ega+G6v3QgcXXhuqMgbMOgIHThuqduIHN14bqldCBj4bunYSBbYEdlbmRlcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9LiBW4bubaSBgQ2F0ZWdvcnlgIGzDoCBwaMOibiBsb+G6oWkgZOG7ryBsaeG7h3UgYsOqbiB0cm9uZyBbYEdlbmRlcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9LCBgRnJlcXVlbmN5YCBsw6AgdOG6p24gc+G7kSB2w6AgYFBlcmNlbnRhZ2VgICjEkcahbiB24buLOiAlKSBsw6AgdOG6p24gc3XhuqV0LiBUYSBjw7MgYuG6o25nIHThuqduIHPhu5EgdOG6p24gc3XhuqV0IGNobyBbYEdlbmRlcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IG5oxrAgc2F1Og0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5ENCmdlbmRlcl9mIDwtIHRhYmxlKHN0JEdlbmRlcikNCg0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc3XhuqV0DQpnZW5kZXJfcCA8LSBwcm9wLnRhYmxlKGdlbmRlcl9mKSoxMDANCg0KIyBL4bq/dCBo4bujcCB0aMOgbmggbeG7mXQgYuG6o25nDQpnZW5kZXIgPC0gZGF0YS5mcmFtZSgNCiAgQ2F0ZWdvcnkgPSBuYW1lcyhnZW5kZXJfZiksDQogIEZyZXF1ZW5jeSA9IGFzLnZlY3RvcihnZW5kZXJfZiksDQogIFBlcmNlbnRhZ2UgPSByb3VuZChhcy52ZWN0b3IoZ2VuZGVyX3ApLCAyKQ0KKQ0KZ2VuZGVyDQpgYGANCg0KIyMjICoqKjIuMS4yIFRy4buxYyBxdWFuIGjDs2EgZOG7ryBsaeG7h3UqKioNCg0KVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSBsw6AgbeG7mXQga2jDonUgxJHDs25nIHZhaSB0csOyIHLhuqV0IHF1YW4gdHLhu41uZyB0cm9uZyBwaMOibiB0w61jaCBk4buvIGxp4buHdSwgbsOzIGtow7RuZyBjaOG7iSBnacO6cCB2aeG7h2MgaGnhu4N1IGThu68gbGnhu4d1IHRy4bufIG7Dqm4gZOG7hSBkw6BuZyBtw6AgY8OybiDEkcOzbmcgdmFpIHRyw7IgaOG7lyB0cuG7oyB0cm9uZyB2aeG7h2MgdGjhu4MgaGnhu4duIGvhur90IHF14bqjIHBow6JuIHTDrWNoIG3hu5l0IGPDoWNoIHRy4buxYyBxdWFuIHbDoCBk4buFIGhp4buDdSBuaOG6pXQuIE3hu5l0IHRyb25nIG5o4buvbmcgY8OhY2ggdHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSBwaOG7lSBiaeG6v24gbmjhuqV0IGzDoCB24bq9IGJp4buDdSDEkeG7kywgxJHhu5FpIHbhu5tpIGJp4bq/biBbYEdlbmRlcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IHRo4buDIGhp4buHbiBnaeG7m2kgdMOtbmgsIGJp4buDdSDEkeG7kyB0csOybiBsw6AgbeG7mXQgZOG6oW5nIGJp4buDdSDEkeG7kyBo4bujcCBsw70gdGjhu4MgaGnhu4duIHBow6JuIGLhu5EgdsOgIHThu7cgbOG7hyBwaOG6p24gdHLEg20gZ2nhu5tpIHTDrW5oIGPhu6dhIGPDoWMga2jDoWNoIGjDoG5nLg0KDQrEkOG7gyB24bq9IGJp4buDdSDEkeG7kywgdGEgc+G7rSBk4bulbmcgY8OidSBs4buHbmggW2BnZ3Bsb3QoKWBde3N0eWxlPSJjb2xvcjpwdXJwbGUifSB24bubaSBjw6FjIHnhur91IHThu5EgbmjGsCBzYXU6DQoNCi0gICBgZ2dwbG90KGRhdGEgPSBnZW5kZXIsIGFlcyh4ID0gJycsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBDYXRlZ29yeSkpYDogc+G7rSBk4bulbmcgYuG7mSBk4buvIGxp4buHdSBsw6AgZ2VuZGVyIMSR4buDIHbhur0gYmnhu4N1IMSR4buTLiBUcm9uZyBiaeG7g3UgxJHhu5MgdHLDsm4sIGPhu5l0IHggbMOgIHLhu5duZyBuw6puIHRhIGPDsyBgeCA9ICcnYCwgY+G7mXQgeSB0aOG7gyBoaeG7h24gdOG6p24gc+G7kSBuw6puIHRhIGPDsyBgeSA9IEZyZXF1ZW5jeWAgdsOgIGBmaWxsID0gQ2F0ZWdvcnlgIGzDoCBz4butIGThu6VuZyBtw6B1IHPhuq9jIGtow6FjIG5oYXUgY2hvIHThu6tuZyBuaMOzbS4NCg0KLSAgIGBnZW9tX2NvbCgpYDogdOG6oW8gY8OhYyBj4buZdCAoY29sKSB24bubaSBjaGnhu4F1IGNhbyB0xrDGoW5nIOG7qW5nIHbhu5tpIGBGcmVxdWVuY3lgDQoNCi0gICBgY29vcmRfcG9sYXIoJ3knKWA6IENodXnhu4NuIGJp4buDdSDEkeG7kyBj4buZdCBzYW5nIGJp4buDdSDEkeG7kyB0csOybiAocGllIGNoYXJ0KSBi4bqxbmcgY8OhY2ggc+G7rSBk4bulbmcgaOG7hyB04buNYSDEkeG7mSB0csOybiAocG9sYXIgY29vcmRpbmF0ZXMpLCBbYCd5J2Bde3N0eWxlPSJjb2xvcjpyZWQifSB04bupYyBsw6AgbOG6pXkgdHLhu6VjIHkgKGNoaeG7gXUgY2FvIGPhu6dhIGPhu5l0KSDEkeG7gyBsw6BtIGfDs2MgcXVheSB0cm9uZyBow6xuaCB0csOybi4NCg0KLSAgIGBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChGcmVxdWVuY3kvbGVuZ3RoKHN0JEdlbmRlcikpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpYDogdGjDqm0gbmjDo24gbMOgIGPDoWMgdsSDbiBi4bqjbiAodGV4dCkgdsOgbyBiaeG7g3UgxJHhu5MsIOG7nyDEkcOieSB0ZXh0IGzDoCB04bu3IGzhu4cgcGjhuqduIHRyxINtIGPhu6dhIHThuqduIHPhu5EgKGBGcmVxdWVuY3lgKSBjaGlhIGNobyB04buVbmcgc+G7kSBxdWFuIHPDoXQgKGBsZW5ndGgoc3QkR2VuZGVyKWApIHbhu5tpIHbhu4sgdHLDrSAoYHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpYCkgbMOgIOG7nyBnaeG7r2EgdOG7q25nIHbDuW5nIGPhu6dhIGJp4buDdSDEkeG7ky4NCg0KLSAgIGBsYWJzKHRpdGxlID0gJ0ZpZ3VyZSAxOiBHZW5kZXIgb2YgQ3VzdG9tZXJzJylgOiB0w6puIGPhu6dhIGJp4buDdSDEkeG7kyBsw6AgIioqRmlndXJlIDE6IEdlbmRlciBvZiBDdXN0b21lcnMqKiIgaGF5ICIqKkjDrG5oIDE6IEdp4bubaSB0w61uaCBj4bunYSBLaMOhY2ggaMOgbmcqKiIuDQoNCi0gICBgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQzIilgOiBNw6B1IGPhu6dhIGJp4buDdSDEkeG7kyBsw6AgYuG6o25nIG3DoHUgKGBjb2xvciBwYWxsZXRlYCkgc+G7kSAzIChgIlNldDMiYCkgdHJvbmcgdGjGsCB2aeG7h24uDQoNCi0gICBgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICdib2xkJykpYDogVMOqbiBiaeG7g3UgxJHhu5MgKGBwbG90LnRpdGxlYCkgxJHGsOG7o2MgY8SDbiBjaMOtbmggZ2nhu69hIHbDoCBpbiDEkeG6rW0uDQoNCkvhur90IHF14bqjIHPhu60gZOG7pW5nIGPDonUgbOG7h25oIMSR4buDIHRy4buxYyBxdWFuIGjDs2EgY8OhYyBk4buvIGxp4buHdSB0cm9uZyBbYEdlbmRlcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IG5oxrAgc2F1Og0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShzY2FsZXMpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGdlbmRlciwgYWVzKHggPSAnJywgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IENhdGVnb3J5KSkgKw0KICBnZW9tX2NvbCgpICsNCiAgY29vcmRfcG9sYXIoJ3knKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KEZyZXF1ZW5jeS9sZW5ndGgoc3QkR2VuZGVyKSkpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSkgKw0KICBsYWJzKHRpdGxlID0gJ0ZpZ3VyZSAxOiBHZW5kZXIgb2YgQ3VzdG9tZXJzJykgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDMiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAnYm9sZCcpKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogS+G6v3QgcXXhuqMgdGjhu5FuZyBrw6ogY2hvIHRo4bqleSB04buVbmcgc+G7kSBuZ8aw4budaSB0aGFtIGdpYSBsw6AgMTQwNTkgKDY4ODkgbmFtIHbDoCA3MTcwIG7hu68pLiBUcm9uZyDEkcOzLCBuYW0gZ2nhu5tpIChNKSBjaGnhur9tIDY4ODkgKDQ5JSksIHRyb25nIGtoaSBu4buvIGdp4bubaSAoRikgY2hp4bq/bSA3MTcwICg1MSUpLiBU4bu3IGzhu4cgbsOgeSBwaOG6o24gw6FuaCBz4buxIGPDom4gYuG6sW5nIHTGsMahbmcgxJHhu5FpIGdp4buvYSBoYWkgZ2nhu5tpLCB24bubaSBu4buvIG5oaeG7gXUgaMahbiBuYW0gbeG7mXQgY2jDunQgKGNow6puaCBs4buHY2ggMiUpLiBE4buvIGxp4buHdSBjaG8gdGjhuqV5IG3huqt1IG5naGnDqm4gY+G7qXUgY8OzIHTDrW5oIMSR4bqhaSBkaeG7h24gdOG7kXQgduG7gSBnaeG7m2kgdMOtbmgsIGtow7RuZyBjw7Mgc+G7sSBjaMOqbmggbOG7h2NoIHF1w6EgbOG7m24gZ2nhu69hIG5hbSB2w6AgbuG7ry4NCg0KIyMgKioyLjIgQmnhur9uIE1hcml0YWxTdGF0dXMqKg0KDQpUxrDGoW5nIHThu7EgduG7m2kgW2BHZW5kZXJgXXtzdHlsZT0iY29sb3I6Z3JlZW4ifSwgdGEgY8WpbmcgbOG6rXAgYuG6o25nIHThuqduIHPhu5EsIHThuqduIHN14bqldCBjaG8gW2BNYXJpdGFsU3RhdHVzYF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gdsOgIHRy4buxYyBxdWFuIGjDs2EgbsOzLiBbYE1hcml0YWxTdGF0dXNgXXtzdHlsZT0iY29sb3I6Z3JlZW4ifSBsw6AgYmnhur9uIHRo4buDIGhp4buHbiB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gY+G7p2EgY8OhYyBraMOhY2ggaMOgbmcgduG7m2kgY8OhYyB0aMOgbmggcGjhuqduIGzDoCBNIChNYXJyaWVkIC0gxJDDoyBr4bq/dCBow7RuKSB2w6AgUyAoU2luZ2xlIC0gxJDhu5ljIHRow6JuKS4NCg0KIyMjICoqKjIuMi4xIFRo4buRbmcga8OqIHThuqduIHPhu5EsIHThuqduIHN14bqldCoqKg0KDQpUYSBjw7MgYuG6o25nIHThuqduIHPhu5EsIHThuqduIHN14bqldCBj4bunYSBbYE1hcml0YWxTdGF0dXNgXXtzdHlsZT0iY29sb3I6Z3JlZW4ifSBuaMawIHNhdToNCg0KYGBge3J9DQojIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRDQptc19mIDwtIHRhYmxlKHN0JE1hcml0YWxTdGF0dXMpDQoNCiMgTOG6rXAgYuG6o25nIHThuqduIHN14bqldA0KbXNfcCA8LSBwcm9wLnRhYmxlKG1zX2YpKjEwMA0KDQojIEvhur90IGjhu6NwIHRow6BuaCBt4buZdCBi4bqjbmcNCm1zIDwtIGRhdGEuZnJhbWUoDQogIENhdGVnb3J5ID0gbmFtZXMobXNfZiksDQogIEZyZXF1ZW5jeSA9IGFzLnZlY3Rvcihtc19mKSwNCiAgUGVyY2VudGFnZSA9IHJvdW5kKGFzLnZlY3Rvcihtc19wKSwgMikNCikNCm1zDQpgYGANCg0KIyMjICoqKjIuMi4yIFRy4buxYyBxdWFuIGjDs2EgZOG7ryBsaeG7h3UqKioNCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG1zLCBhZXMoeCA9ICcnLCB5ID0gRnJlcXVlbmN5LCBmaWxsID0gQ2F0ZWdvcnkpKSArDQogIGdlb21fY29sKCkgKw0KICBjb29yZF9wb2xhcigneScpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQoRnJlcXVlbmN5L2xlbmd0aChzdCRNYXJpdGFsU3RhdHVzKSkpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSkgKw0KICBsYWJzKHRpdGxlID0gJ0ZpZ3VyZSAyOiBNYXJpdGFsIFN0YXR1cyBvZiBDdXN0b21lcnMnKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MyIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICdib2xkJykpDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKiBL4bq/dCBxdeG6oyBjaG8gdGjhuqV5IGtow7RuZyBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgxJHDoW5nIGvhu4MgduG7gSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIMSRw6Mga+G6v3QgaMO0biB2w6AgY2jGsGEga+G6v3QgaMO0bi4gQ+G7pSB0aOG7gyA0OC44NCUgdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nICg2ODY2IGtow6FjaCBow6BuZykgxJHDoyBr4bq/dCBow7RuIHbDoCA1MS4xNiUgdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nICg3MTkzIGtow6FjaCBow6BuZykgY2jGsGEga+G6v3QgaMO0bi4gVOG7tyBs4buHIGNow6puaCBs4buHY2ggZ2nhu69hIHPhu5Ega2jDoWNoIGjDoG5nIMSRw6Mga+G6v3QgaMO0biB2w6AgY2jGsGEga+G6v3QgaMO0biBjaOG7iSBraG/huqNuZyAyLjMyJSwgcGjhuqNuIMOhbmggc+G7sSBwaMOibiBi4buRIMSR4buTbmcgxJHhu4F1IGdp4buvYSBoYWkgbmjDs20gxJHhu5FpIHTGsOG7o25nIG7DoHkgdHJvbmcgbeG6q3UgbmdoacOqbiBj4bupdS4gS+G6v3QgcXXhuqMgbsOgeSBjw7MgdGjhu4MgZ+G7o2kgw70gcuG6sW5nIG3huqt1IGto4bqjbyBzw6F0IGPDsyB0w61uaCDEkeG6oWkgZGnhu4duIHThu5F0IGhv4bq3YyBwaOG6o24gw6FuaCB4dSBoxrDhu5tuZyBjw6JuIGLhurFuZyB0cm9uZyB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gY+G7p2EgcXXhuqduIHRo4buDIG5naGnDqm4gY+G7qXUuDQoNCiMjICoqMi4zIEJp4bq/biBIb21lb3duZXIqKg0KDQpbYEhvbWVvd25lcmBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IGzDoCBiaeG6v24gdGjhu4MgaGnhu4duIHLhurFuZyBjw6FjIGtow6FjaCBow6BuZyDEkcOjIHPhu58gaOG7r3UgbmjDoCDhu58gaGF5IGNoxrBhLCBjw6FjIHRow6BuaCBwaOG6p24gbMOgIFkgKFllcyAtIEPDsywgxJHDoyBz4bufIGjhu691IG5ow6ApIHbDoCBOIChObyAtIENoxrBhLCBjaMawYSBz4bufIGjhu691IG5ow6ApLg0KDQojIyMgKioqMi4zLjEgVGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0KioqDQoNClRhIGPDsyBi4bqjbmcgdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0IG5oxrAgc2F1Og0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5ENCmhvX2YgPC0gdGFibGUoc3QkSG9tZW93bmVyKQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQNCmhvX3AgPC0gcHJvcC50YWJsZShob19mKSoxMDANCg0KIyBL4bq/dCBo4bujcCB0aMOgbmggbeG7mXQgYuG6o25nDQpobyA8LSBkYXRhLmZyYW1lKA0KICBDYXRlZ29yeSA9IG5hbWVzKGhvX2YpLA0KICBGcmVxdWVuY3kgPSBhcy52ZWN0b3IoaG9fZiksDQogIFBlcmNlbnRhZ2UgPSByb3VuZChhcy52ZWN0b3IoaG9fcCksIDIpDQopDQpobw0KYGBgDQoNCiMjIyAqKioyLjMuMiBUcuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1KioqDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBobywgYWVzKHggPSAnJywgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IENhdGVnb3J5KSkgKw0KICBnZW9tX2NvbCgpICsNCiAgY29vcmRfcG9sYXIoJ3knKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KEZyZXF1ZW5jeS9sZW5ndGgoc3QkTWFyaXRhbFN0YXR1cykpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICsNCiAgbGFicyh0aXRsZSA9ICdGaWd1cmUgMzogSG91c2luZyBTdGF0dXMgb2YgQ3VzdG9tZXJzICcpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQzIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gJ2JvbGQnKSkNCmBgYA0KDQoqKk5o4bqtbiB4w6l0OioqIEvhur90IHF14bqjIGNobyB0aOG6pXkgc+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgxJHDoyBz4bufIGjhu691IG5ow6Ag4bufIGNoaeG6v20gxrB1IHRo4bq/IGtow6EgbOG7m24gKGtob+G6o25nIDYwJSB04buVbmcgc+G7kSBraMOhY2ggaMOgbmcgaGF5IDg0NDQga2jDoWNoIGjDoG5nIMSRw6Mgc+G7nyBo4buvdSBuaMOgKSBjw7JuIHPhu5Ega2jDoWNoIGjDoG5nIGNoxrBhIHPhu58gaOG7r3UgbmjDoCBjaGnhur9tIMawdSB0aOG6vyDDrXQgaMahbiAoZ+G6p24gNDAlIHThu5VuZyBz4buRIGtow6FjaCBow6BuZyBoYXkgNTYxNSBraMOhY2ggaMOgbmcgY2jGsGEgc+G7nyBo4buvdSBuaMOgKS4gxJBp4buBdSBuw6B5IHBo4bqjbiDDoW5oIHLhurFuZyDEkWEgc+G7kSBjw6FjIGtow6FjaCBow6BuZyDEkeG7gXUgxJHDoyBz4bufIGjhu691IG5ow6AgcmnDqm5nIHbDoCBjw7MgY2jDqm5oIGzhu4djaCB0xrDGoW5nIMSR4buRaSDEkcOhbmcga+G7gyAoa2hv4bqjbmcgMjAlKSBzbyB24bubaSBjw6FjIGtow6FjaCBow6BuZyBjaMawYSBz4bufIGjhu691IG5ow6AgY2hvIHRo4bqleSB4dSBoxrDhu5tuZyBz4bufIGjhu691IG5ow6AgY2FvIHbDoCBjaGnhur9tIMawdSB0aOG6vy4NCg0KIyMgKioyLjQgQmnhur9uIEFubnVhbEluY29tZSoqDQoNCltgQW5udWFsSW5jb21lYF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gbMOgIGJp4bq/biB0aOG7gyBoaeG7h24gdGh1IG5o4bqtcCBow6BuZyBuxINtIGPhu6dhIGtow6FjaCBow6BuZyB24bubaSBjw6FjIHRow6BuaCBwaOG6p24gYmFvIGfhu5NtOg0KDQotICAgMTBLIC0gMzBLOiBN4bupYyB0aHUgbmjhuq1wIHRyb25nIGtob+G6o25nIDEwayBVU0QgxJHhur9uIDMwayBVU0QNCg0KLSAgIDMwSyAtIDUwSzogTeG7qWMgdGh1IG5o4bqtcCB0cm9uZyBraG/huqNuZyAzMGsgVVNEIMSR4bq/biA1MGsgVVNEDQoNCi0gICA1MEsgLSA3MEs6IE3hu6ljIHRodSBuaOG6rXAgdHJvbmcga2hv4bqjbmcgNTBrIFVTRCDEkeG6v24gNzBrIFVTRA0KDQotICAgNzBLIC0gOTBLOiBN4bupYyB0aHUgbmjhuq1wIHRyb25nIGtob+G6o25nIDcwayBVU0QgxJHhur9uIDkwayBVU0QNCg0KLSAgIDkwSyAtIDExMEs6IE3hu6ljIHRodSBuaOG6rXAgdHJvbmcga2hv4bqjbmcgOTBrIFVTRCDEkeG6v24gMTEwayBVU0QNCg0KLSAgIDExMEsgLSAxMzBLOiBN4bupYyB0aHUgbmjhuq1wIHRyb25nIGtob+G6o25nIDExMGsgVVNEIMSR4bq/biAxMzBrIFVTRA0KDQotICAgMTMwSyAtIDE1MEs6IE3hu6ljIHRodSBuaOG6rXAgdHJvbmcga2hv4bqjbmcgMTMwayBVU0QgxJHhur9uIDE1MGsgVVNEDQoNCi0gICAxNTBLKzogTeG7qWMgdGh1IG5o4bqtcCBoxqFuIDE1MEsgVVNELg0KDQpU4burIMSRw6J5IHRhIGPDsyB0aOG7gyBwaMOibiBsb+G6oWkgdGh1IG5o4bqtcCBj4bunYSBraMOhY2ggaMOgbmcgcmEgdGjDoG5oIDMgbG/huqFpLCBiYW8gZ+G7k206DQoNCi0gICBOaMOzbSBjw7MgdGh1IG5o4bqtcCB0aOG6pXA6IGtob+G6o25nIDEwayAtIDUwSyBVU0QgaOG6sW5nIG7Eg20NCg0KLSAgIE5ow7NtIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oOiBraG/huqNuZyA1MEsgLSAxMTBLIFVTRCBo4bqxbmcgbsSDbQ0KDQotICAgTmjDs20gY8OzIHRodSBuaOG6rXAgY2FvOiBraG/huqNuZyAxMTBLIC0gaMahbiAxNTBLIFVTRCBo4bqxbmcgbsSDbS4NCg0KIyMjICoqKjIuNC4xIFRo4buRbmcga8OqIHThuqduIHPhu5EsIHThuqduIHN14bqldCoqKg0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5ENCmFpX2YgPC0gdGFibGUoc3QkQW5udWFsSW5jb21lKQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQNCmFpX3AgPC0gcHJvcC50YWJsZShhaV9mKSoxMDANCg0KIyBL4bq/dCBo4bujcCB0aMOgbmggbeG7mXQgYuG6o25nDQphaSA8LSBkYXRhLmZyYW1lKA0KICBDYXRlZ29yeSA9IG5hbWVzKGFpX2YpLA0KICBGcmVxdWVuY3kgPSBhcy52ZWN0b3IoYWlfZiksDQogIFBlcmNlbnRhZ2UgPSByb3VuZChhcy52ZWN0b3IoYWlfcCksIDIpDQopDQphaQ0KYGBgDQoNCiMjIyAqKioyLjQuMiBUcuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1KioqDQoNCuG7niDEkcOieSwga2hpIGJp4bq/biBbYEFubnVhbEluY29tZWBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IMSRw6MgY8OzIHF1w6Egbmhp4buBdSBiaeG7g3UgaGnhu4duLCB2aeG7h2Mgc+G7rSBk4bulbmcgY8O0bmcgY+G7pSB0cuG7sWMgcXVhbiBow7NhIGzDoCBiaeG7g3UgxJHhu5MgdHLDsm4gdHLhu58gbsOqbiBraMOhIGtow7MgxJHhu4MgbmjDrG4gbsOqbiB0YSBz4butIGThu6VuZyBiaeG7g3UgxJHhu5MgY+G7mXQuIMSQ4buDIHbhur0gYmnhu4N1IMSR4buTIGPhu5l0LCB0YSB0aeG6v3AgdOG7pWMgc+G7rSBk4bulbmcgY8OidSBs4buHbmggW2BnZ3Bsb3QoKWBde3N0eWxlPSJjb2xvcjpwdXJwbGUifSB24bubaSBjw6FjIHnhur91IHThu5EgbmjGsCBzYXU6DQoNCi0gICBgZ2dwbG90KHN0LCBhZXMoeCA9IEFubnVhbEluY29tZSkpYDogVuG6vSBiaeG7g3UgxJHhu5MgduG7m2kgZOG7ryBsaeG7h3UgxJHGsOG7o2Mgc+G7rSBk4bulbmcgbMOgIGThu68gbGnhu4d1IFtgc3RgXXtzdHlsZS0iY29sb3I6Ymx1ZSJ9IHbDoCB0cuG7pWMgaG/DoG5oIGzDoCBBbm51YWwgSW5jb21lLg0KDQotICAgYGdlb21fYmFyKGZpbGwgPSAnIzU1OCcpYDogVOG6oW8gYmnhu4N1IMSR4buTIGPhu5l0IHbhu5tpIG3DoHUgY+G7p2EgY+G7mXQgbMOgIG3DoHUgY8OzIG3DoyBIZXggbMOgICM1NTgNCg0KLSAgIGBnZW9tX3RleHQoYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChjb3VudCkpLCBzdGF0ID0gImNvdW50Iiwgdmp1c3QgPSAtMC4zLCBzaXplID0gMy41KWA6IEhp4buDbiB0aOG7iyBrw70gdOG7sSB0csOqbiB04burbmcgY+G7mXQgY+G7p2EgYmnhu4N1IMSR4buTIGzDoCB04bqnbiBz4buRIChz4buRIGzGsOG7o25nKSBj4bunYSBjw6FjIGJp4buDdSBoaeG7h24gdHJvbmcgYmnhur9uIFtgQW5udWFsSW5jb21lYF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gduG7m2kgduG7iyB0csOtIGzDoCBu4bqxbSB0csOqbiBt4buXaSBj4buZdCB2w6Aga8OtY2ggY+G7oSBsw6AgMy41Lg0KDQotICAgYGxhYnModGl0bGUgPSAiRmlndXJlIDQ6IEFubnVhbCBJbmNvbWUgb2YgQ3VzdG9tZXJzIiwgeCA9ICJBbm51YWwgSW5jb21lIiwgeSA9ICJGcmVxdWVuY3kiKWA6IFTDqm4gY+G7p2EgYmnhu4N1IMSR4buTIGzDoCAiKipGaWd1cmUgMTogQW5udWFsIEluY29tZSBvZiBDdXN0b21lcnMqKiB24bubaSB0cuG7pWMgdHVuZyBsw6AgIioqRnJlcXVlbmN5KioiIHbDoCB0cuG7pWMgaG/DoG5oIGzDoCAiKipBbm51YWwgSW5jb21lKioiLg0KDQotICAgYHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpKWA6IFTDqm4gYmnhu4N1IMSR4buTIChgcGxvdC50aXRsZWApIMSRxrDhu6NjIGPEg24gY2jDrW5oIGdp4buvYSB2w6AgaW4gxJHhuq1tLCB0w6puIGPhu6dhIHThu6tuZyBiaeG7g3UgaGnhu4duIOG7nyB0cuG7pWMgaG/DoG5oIChgYXhpcy50ZXh0LnhgKSDEkcaw4bujYyB4b2F5IDkwIMSR4buZIHbDoCBjxINuIGzhu4EgcGjhuqNpIMSR4buDIHRyw6FuaCBjaOG7k25nIGNo4buvLg0KDQpgYGB7cn0NCmdncGxvdChzdCwgYWVzKHggPSBBbm51YWxJbmNvbWUpKSArIA0KICBnZW9tX2JhcihmaWxsID0gJyM1NTgnKSArDQogIGdlb21fdGV4dCgNCiAgICBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KGNvdW50KSksDQogICAgc3RhdCA9ICJjb3VudCIsDQogICAgdmp1c3QgPSAtMC4zLA0KICAgIHNpemUgPSAzLjUNCiAgKSArDQogIGxhYnModGl0bGUgPSAiRmlndXJlIDQ6IEFubnVhbCBJbmNvbWUgb2YgQ3VzdG9tZXJzIiwgeCA9ICJBbm51YWwgSW5jb21lIiwgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogQmnhur9uIEFubnVhbCBJbmNvbWUgY2hvIHRhIHRo4bqleSDEkcaw4bujYyBjw7MgNDYwMSBraMOhY2ggaMOgbmcgKHThu6ljIGzDoCAzMi43MyUgdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nKSBjw7MgbeG7qWMgdGh1IG5o4bqtcCB04burIGtob+G6o25nIDMwSyAtIDUwSyBVU0QgaOG6sW5nIG7Eg20gdsOgIGNoaeG6v20gdOG7tyBs4buHIG5oaeG7gXUgbmjhuqV0LiBOaMOzbSBraMOhY2ggaMOgbmcgY8OzIHRodSBuaOG6rXAgdOG7qyBraG/huqNuZyAxMEsgLSAzMEsgVVNEIGjhurFuZyBuxINtIMSR4bupbmcgdGjhu6kgaGFpIHbhu5tpIHThu7cgbOG7hyBsw6AgMjEuOTglIHTGsMahbmcgxJHGsMahbmcgduG7m2kgMzA5MCBraMOhY2ggaMOgbmcuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHLhurFuZyBuaMOzbSBraMOhY2ggaMOgbmcgY8OzIHRodSBuaOG6rXAgdGjhuqVwIGNoaeG6v20gxrB1IHRo4bq/IHbhu5tpIHThu5VuZyBj4buZbmcgbMOgIDcwOTEga2jDoWNoIGjDoG5nLCBraG/huqNuZyA1NC43MSUgc+G7kSBraMOhY2ggaMOgbmcuDQoNClRp4bq/cCDEkeG6v24gbMOgIG5ow7NtIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oLCB04buVbmcgY+G7mW5nIGPDsyA0NjkyIGtow6FjaCBow6BuZywga2hv4bqjbmcgMzMuMzglIHPhu5Ega2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oLiBD4bulIHRo4buDIGzDoCBz4buRIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB0cnVuZyBiw6xuaCB0aOG6pXAgKDUwSyAtIDcwSyBVU0QpIGNoaeG6v20gdOG7tyBs4buHIDE2Ljg2JSB2w6AgY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCB0cm9uZyBuaMOzbSB0cnVuZyBiw6xuaCwgdGnhur9wIMSR4bq/biBsw6Aga2jDoWNoIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oICg3MEsgLSA5MEsgVVNEKSBjaGnhur9tIHThu7cgbOG7hyBjYW8gdGjhu6kgaGFpIHRyb25nIG5ow7NtIG7DoHksIGtob+G6o25nIDEyLjE2JS4gQ3Xhu5FpIGPDuW5nIGzDoCBuaMOzbSBraMOhY2ggY8OzIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmggY2FvICg5MEsgLSAxMTBLIFVTRCkgY2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCBuaMOzbSwgY2jhu4kga2hv4bqjbmcgNC4zNiUgduG7m2kgNjEzIGtow6FjaCBow6BuZy4NCg0KQ3Xhu5FpIGPDuW5nIGzDoCBuaMOzbSBjw7MgdGh1IG5o4bqtcCBjYW8gKDExMEsgLSBoxqFuIDE1MEsgVVNEIGjhurFuZyBuxINtKSwgxJHDonkgbMOgIG5ow7NtIGNoaeG6v20gdOG7tyBs4buHIHRo4bqlcCBuaOG6pXQgduG7m2kgY2jhu4kgMTEuOTElIHRyb25nIHThu5VuZyBz4buRIGtow6FjaCBow6BuZyAoMTY3NiBraMOhY2ggaMOgbmcpLiBD4bulIHRo4buDIHRyb25nIG5ow7NtIG7DoHksIHPhu5Ega2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIOG7nyBt4bupYyAxMTBLIC0gMTMwSyBjaGnhur9tIGtob+G6o25nIDQuNTclLCDEkeG7qW5nIHRo4bupIGhhaSBuaMOzbSBuw6B5LiBE4bqrbiDEkeG6p3UgbmjDs20gbsOgeSBsw6AgdOG7h3Aga2jDoWNoIGPDsyB0aHUgbmjhuq1wIHThu6sgMTMwSyAtIDE1MEsgaOG6sW5nIG7Eg20sIGtob+G6o25nIDUuNDElIHRyb25nIHThu5VuZyBz4buRIGtow6FjaCBow6BuZy4gQ3Xhu5FpIGPDuW5nIGzDoCBuaMOzbSBraMOhY2ggY8OzIHRodSBuaOG6rXAgaMahbiAxNTBLIFVTRCBo4bqxbmcgbsSDbSwgxJHDonkgbMOgIG5ow7NtIGtow6FjaCBjw7MgdGh1IG5o4bqtcCBjYW8gbmjhuqV0IHbDoCBjaGnhur9tIHThu7cgbOG7hyDDrXQgbmjhuqV0Lg0KDQpUaMO0bmcgcXVhIGLhuqNuZyB04bqnbiBz4buRIHbDoCBiaeG7g3UgxJHhu5MsIHRhIGPDsyB0aOG7gyBiaeG6v3QgxJHGsOG7o2MgcuG6sW5nIHThu4dwIGtow6FjaCBow6BuZyBjaOG7pyB54bq/dSDhu58gxJHDonkgbMOgIG5ow7NtIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB0aOG6pXAgxJHhur9uIHRydW5nIGLDrG5oLCBjw6BuZyBjw7MgdGh1IG5o4bqtcCBjYW8sIHZp4buHYyBtdWEgc+G6r20gaGF5IMSRaSBzacOqdSB0aOG7iyBjw6BuZyDDrXQgxJFpLg0KDQojIyAqKjIuNSBCaeG6v24gQ2l0eSoqDQoNClRyb25nIGLhu5kgZOG7ryBsaeG7h3UgW2BTdXBlcm1hcmtldFRyYW5zYWN0aW9ucy5jc3ZgXXtzdHlsZT0iY29sb3I6Ymx1ZSJ9LCBiaeG6v24gW2BDaXR5YF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gxJHhuqFpIGRp4buHbiBjaG8gdGjDoG5oIHBo4buRIG7GoWkga2jDoWNoIGjDoG5nIMSRYW5nIHNpbmggc+G7kW5nLiBUcm9uZyBiaeG6v24gbsOgeSBjw7MgYmFvIGfhu5NtIDIzIGJp4buDdSBoaeG7h24sIHTGsMahbmcgxJHGsMahbmcgduG7m2kgMjMgdGjDoG5oIHBo4buRIG3DoCBjw6FjIGtow6FjaCBow6BuZyB0cm9uZyBmaWxlIGThu68gbGnhu4d1IMSRYW5nIHNpbmggc+G7kW5nLg0KDQojIyMgKioqMi41LjEgVGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0KioqDQoNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kQ0KY19mIDwtIHRhYmxlKHN0JENpdHkpDQoNCiMgTOG6rXAgYuG6o25nIHThuqduIHN14bqldA0KY19wIDwtIHByb3AudGFibGUoY19mKSoxMDANCg0KIyBL4bq/dCBo4bujcCB0aMOgbmggbeG7mXQgYuG6o25nDQpjaXR5IDwtIGRhdGEuZnJhbWUoDQogIENhdGVnb3J5ID0gbmFtZXMoY19mKSwNCiAgRnJlcXVlbmN5ID0gYXMudmVjdG9yKGNfZiksDQogIFBlcmNlbnRhZ2UgPSByb3VuZChhcy52ZWN0b3IoY19wKSwgMikNCikNCmNpdHkNCmBgYA0KDQojIyMgKioqMi41LjIgVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSoqKg0KDQpgYGB7cn0NCmdncGxvdChzdCwgYWVzKHggPSBDaXR5KSkgKyANCiAgZ2VvbV9iYXIoZmlsbCA9ICIjNTU4IikgKw0KICBnZW9tX3RleHQoDQogICAgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChjb3VudCkpLA0KICAgIHN0YXQgPSAiY291bnQiLA0KICAgIHZqdXN0ID0gLTAuMywNCiAgICBzaXplID0gMy41DQogICkgKw0KICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA1OiBDdXJyZW50IENpdHkgb2YgQ3VzdG9tZXJzIiwgeCA9ICJDaXR5IiwgeSA9ICJGcmVxdWVuY3kiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogVGEgdGjhuqV5IFNhbGVtIGThuqtuIMSR4bqndSB24bubaSAxLjM4NiBraMOhY2ggKHTGsMahbmcgxJHGsMahbmcgduG7m2kga2hv4bqjbmcgOS44NiUpLCBn4bqlcCDEkcO0aSBzbyB24bubaSBuaGnhu4F1IHRow6BuaCBwaOG7kSBraMOhYywgdHJvbmcga2hpIEd1YWRhbGFqYXJhIGNo4buJIGPDsyA3NSBraMOhY2ggKGtob+G6o25nIDAuNTMlIHThu5VuZyBz4buRIGtow6FjaCBow6BuZykuIEPDoWMgdGjDoG5oIHBo4buRIGzhu5tuIG5oxrAgTG9zIEFuZ2VsZXMgOTI2LCBTZWF0dGxlIDkyMiwgdsOgIFNhbiBEaWVnbyA4NjYgY8WpbmcgY8OzIGzGsOG7o25nIGtow6FjaCBow6BuZyBjYW8sIHBo4bqjbiDDoW5oIHF1eSBtw7QgZMOibiBz4buRIHbDoCBz4bupYyBow7p0IHRo4buLIHRyxrDhu51uZy4gTmfGsOG7o2MgbOG6oWksIG3hu5l0IHPhu5EgdGjDoG5oIHBo4buRIG5oxrAgU2FuIEZyYW5jaXNjbyAxMzAgdsOgIE1leGljbyBDaXR5IDE5NCBs4bqhaSBjw7Mgc+G7kSBraMOhY2ggdGjhuqVwIGLhuqV0IHRoxrDhu51uZyBkw7kgbMOgIHRydW5nIHTDom0ga2luaCB04bq/LCBjw7MgdGjhu4MgZG8gaOG6oW4gY2jhur8gdHJvbmcgY2hp4bq/biBsxrDhu6NjIGtpbmggZG9hbmggaG/hurdjIHRodSB0aOG6rXAgZOG7ryBsaeG7h3UuIEThu68gbGnhu4d1IHThuqduIHN14bqldCB2w6AgdOG6p24gc+G7kSBjaG8gdGjhuqV5IHPhu7EgY2jDqm5oIGzhu4djaCByw7UgcuG7h3QgZ2nhu69hIGPDoWMgdGjDoG5oIHBo4buRLg0KDQojIyAqKjIuNiBCaeG6v24gU3RhdGVvclByb3ZpbmUqKg0KDQpbYFN0YXRlb3JQcm92aW5lYF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gbMOgIGJp4bq/biB0aOG7gyBoaeG7h24gYmFuZyBob+G6t2MgdOG7iW5oIG7GoWkgbcOgIGtow6FjaCBow6BuZyDEkWFuZyBzaW5oIHPhu5FuZy4gQ+G7pSB0aOG7gyBiaeG6v24gW2BTdGF0ZW9yUHJvdmluZWBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IG7DoHkgYmFvIGfhu5NtIDEwIGJp4buDdSBoaeG7h24gdGjhu4MgaGnhu4duIDEwIGJhbmcgbcOgIHThuqV0IGPhuqMgY8OhYyBraMOhY2ggaMOgbmcgaGnhu4duIMSRYW5nIHNpbmggc+G7kW5nLg0KDQojIyMgKioqMi42LjEgVGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0KioqDQoNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kQ0Kc29wX2YgPC0gdGFibGUoc3QkU3RhdGVvclByb3ZpbmNlKQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQNCnNvcF9wIDwtIHByb3AudGFibGUoc29wX2YpKjEwMA0KDQojIEvhur90IGjhu6NwIHRow6BuaCBt4buZdCBi4bqjbmcNCnNvcCA8LSBkYXRhLmZyYW1lKA0KICBDYXRlZ29yeSA9IG5hbWVzKHNvcF9mKSwNCiAgRnJlcXVlbmN5ID0gYXMudmVjdG9yKHNvcF9mKSwNCiAgUGVyY2VudGFnZSA9IHJvdW5kKGFzLnZlY3Rvcihzb3BfcCksIDIpDQopDQpzb3ANCmBgYA0KDQojIyMgKioqMi42LjIgVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSoqKg0KDQpgYGB7cn0NCmdncGxvdChzdCwgYWVzKHggPSBTdGF0ZW9yUHJvdmluY2UpKSArIA0KICBnZW9tX2JhcihmaWxsID0gIiM1NTgiKSArDQogIGdlb21fdGV4dCgNCiAgICBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KGNvdW50KSksDQogICAgc3RhdCA9ICJjb3VudCIsDQogICAgdmp1c3QgPSAtMC4zLA0KICAgIHNpemUgPSAzLjUNCiAgKSArDQogIGxhYnModGl0bGUgPSAiRmlndXJlIDY6IEN1cnJlbnQgU3RhdGUgb3IgUHJvdmluZSBvZiBDdXN0b21lcnMiLCB4ID0gIlN0YXRlIG9yIFByb3ZpbmUiLCB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKiBE4buvIGxp4buHdSB0aOG7kW5nIGvDqiB0aGVvIGJhbmcvdOG7iW5oIGNobyB0aOG6pXkgc+G7sSBjaMOqbmggbOG7h2NoIMSRw6FuZyBr4buDIGdp4buvYSBjw6FjIGtodSB24buxYy4gV0EgZOG6q24gxJHhuqd1IHbhu5tpIGNvbiBz4buRIOG6pW4gdMaw4bujbmcgNC41Njcga2jDoWNoIGjDoG5nIChraG/huqNuZyAzMi40OCUgdHLDqm4gdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nKSwgY2FvIGfhuqduIGfhuqVwIMSRw7RpIHNvIHbhu5tpIE9SICgyMjYyIGtow6FjaCBow6BuZyBoYXkgMTYuMDklKSB2w6AgQ0EgKDI3MzMga2jDoWNoIGjDoG5nIGhheSAxOS40NCUpLiBDw6FjIGJhbmcgQ0EgKDI3MzMga2jDoWNoIGjDoG5nIGhheSAxOS40NCUpLCBPUiAoMjI2MiBraMOhY2ggaMOgbmcgaGF5IDE2LjA5JSksIFphY2F0ZWNhcyAoMTI5NyBraMOhY2ggaMOgbmcgaGF5IDkuMjMlKSBu4bqxbSDhu58gbeG7qWMgdHJ1bmcgYsOsbmggdHJ1bmcgYsOsbmgsIHRyb25nIGtoaSDEkcOzIEd1ZXJyZXJvIHbhu5tpIDM4MyBraMOhY2ggaMOgbmcgKDIuNzIlKSwgQkMgKDgwOSBraMOhY2ggaMOgbmcgLSA1Ljc1JSksIERGICg4MTUga2jDoWNoIGjDoG5nIC0gNS44JSksIFZlcmFjcnV6ICg0NjQga2jDoWNoIGjDoG5nIC0gMy4zJSkgdsOgIFl1dGFjYW4gKDY1NCBraMOhY2ggaMOgbmcgLSA0LjY1JSkg4bufIG3hu6ljIGtow6EgdGjhuqVwLiDEkOG6t2MgYmnhu4d0IGzDoCBKYWxpc2NvIHbhu5tpIGNo4buJIDc1IGtow6FjaCBow6BuZyAoa2hv4bqjbmcgMC41MyUpIC0gdGjhuqVwIG5o4bqldCB0cm9uZyB04bqldCBj4bqjIGPDoWMga2h1IHbhu7FjIMSRxrDhu6NjIHRo4buRbmcga8OqLiBT4buxIGtow6FjIGJp4buHdCBs4bubbiBuw6B5IGPDsyB0aOG7gyBwaOG6o24gw6FuaCBz4buxIGtow7RuZyDEkeG7k25nIMSR4buBdSB24buBIHF1eSBtw7QgZMOibiBz4buRLCBt4bupYyDEkeG7mSBob+G6oXQgxJHhu5luZyBraW5oIHThur8gaG/hurdjIGPDoWMgeeG6v3UgdOG7kSDEkeG6t2MgdGjDuSBraMOhYyBj4bunYSB04burbmcgdsO5bmcuDQoNCiMjICoqMi43IEJp4bq/biBDb3VudHJ5KioNCg0KQmnhur9uIFtgQ291bnRyeWBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgW2BTdXBlcm1hcmtldFRyYW5zYWN0aW9ucy5jc3ZgXXtzdHlsZT0iY29sb3I6Ymx1ZSJ9IHRo4buDIGhp4buHbiBxdeG7kWMgZ2lhIG3DoCBraMOhY2ggaMOgbmcgxJFhbmcgc2luaCBz4buRbmcuIEPhu6UgdGjhu4MgYmFvIGfhu5NtIDMgcXXhu5FjIGdpYSBsw6AgVVNBIChIb2EgS+G7syksIE1leGljbyB2w6AgQ2FuYWRhLg0KDQojIyMgKioqMi43LjEgVGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0KioqDQoNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kQ0KY29fZiA8LSB0YWJsZShzdCRDb3VudHJ5KQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQNCmNvX3AgPC0gcHJvcC50YWJsZShjb19mKSoxMDANCg0KIyBL4bq/dCBo4bujcCB0aMOgbmggbeG7mXQgYuG6o25nDQpjb3VudHJ5IDwtIGRhdGEuZnJhbWUoDQogIENhdGVnb3J5ID0gbmFtZXMoY29fZiksDQogIEZyZXF1ZW5jeSA9IGFzLnZlY3Rvcihjb19mKSwNCiAgUGVyY2VudGFnZSA9IHJvdW5kKGFzLnZlY3Rvcihjb19wKSwgMikNCikNCmNvdW50cnkNCmBgYA0KDQojIyMgKioqMi43LjIgVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSoqKg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY291bnRyeSwgYWVzKHggPSAnJywgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IENhdGVnb3J5KSkgKw0KICBnZW9tX2NvbCgpICsNCiAgY29vcmRfcG9sYXIoJ3knKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KEZyZXF1ZW5jeS9sZW5ndGgoc3QkTWFyaXRhbFN0YXR1cykpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICsgIGxhYnModGl0bGUgPSAnRmlndXJlIDc6IEN1cnJlbnQgQ291bnRyeSBvZiBDdXN0b21lcnMnKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICdib2xkJykpDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKiBE4buvIGxp4buHdSBjaG8gdGjhuqV5IHLhurFuZyDEkWEgc+G7kSBjw6FjIGhv4bqhdCDEkeG7mW5nIGdpYW8gZOG7i2NoIMSR4buBdSBkaeG7hW4gcmEg4bufIEhvYSBL4buzIHbhu5tpIDk1NjIga2jDoWNoIGjDoG5nIChraG/huqNuZyA2OCUgdHLDqm4gdOG7lW5nIHPhu5EpLCDEkeG7qW5nIHRo4bupIGhhaSBsw6AgTWV4aWNvIHbhu5tpIDM2ODgga2jDoWNoIGjDoG5nIChraG/huqNuZyAyNiUgdHLDqm4gdOG7lW5nIHPhu5EpIHbDoCBraGnDqm0gdOG7kW4gbmjhuqV0IGzDoCBDYW5hZGEgduG7m2kgODA5IGtow6FjaCBow6BuZyAoduG7m2kgY2jhu4kgNiUgdHLDqm4gdOG7lW5nIHPhu5EpLg0KDQojIyAqKjIuOCBCaeG6v24gUHJvZHVjdEZhbWlseSoqDQoNCltgUHJvZHVjdEZhbWlseWBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IChOaMOzbSBz4bqjbiBwaOG6qW0pIGzDoCBiaeG6v24gdGjhu4MgaGnhu4duIG5ow7NtIGPDoWMgc+G6o24gcGjhuqltIMSRxrDhu6NjIG11YSBjaOG7pyB54bq/dSDhu58gc2nDqnUgdGjhu4suIEPDoWMgbmjDs20gc+G6o24gcGjhuqltIOG7nyDEkcOieSBiYW8gZ+G7k20gMyBuaMOzbSBsw6AgRHJpbmsgKMSQ4buTIHXhu5FuZyksIEZvb2QgKFRo4buxYyBwaOG6qW0pIHbDoCBOb24tY29uc3VtYWJsZSAoUGhpIHRpw6p1IGTDuW5nKS4NCg0KIyMjICoqKjIuOC4xIFRo4buRbmcga8OqIHThuqduIHPhu5EsIHThuqduIHN14bqldCoqKg0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5ENCnBmX2YgPC0gdGFibGUoc3QkUHJvZHVjdEZhbWlseSkNCg0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc3XhuqV0DQpwZl9wIDwtIHByb3AudGFibGUocGZfZikqMTAwDQoNCiMgS+G6v3QgaOG7o3AgdGjDoG5oIG3hu5l0IGLhuqNuZw0KcGYgPC0gZGF0YS5mcmFtZSgNCiAgQ2F0ZWdvcnkgPSBuYW1lcyhwZl9mKSwNCiAgRnJlcXVlbmN5ID0gYXMudmVjdG9yKHBmX2YpLA0KICBQZXJjZW50YWdlID0gcm91bmQoYXMudmVjdG9yKHBmX3ApLCAyKQ0KKQ0KcGYNCmBgYA0KDQojIyMgKioqMi44LjIgVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSoqKg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gcGYsIGFlcyh4ID0gJycsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBDYXRlZ29yeSkpICsNCiAgZ2VvbV9jb2woKSArDQogIGNvb3JkX3BvbGFyKCd5JykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChGcmVxdWVuY3kvbGVuZ3RoKHN0JE1hcml0YWxTdGF0dXMpKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpKSArDQogIGxhYnModGl0bGUgPSAnRmlndXJlIDg6IENvbnN1bXB0aW9uIGJ5IFByb2R1Y3QgRmFtaWx5JykgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAnYm9sZCcpKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogROG7ryBsaeG7h3UgdOG6p24gc3XhuqV0IHbDoCB04bqnbiBz4buRIGPDoWMgbmjDs20gc+G6o24gcGjhuqltIGNobyB0aOG6pXkgc+G7sSBjaMOqbmggbOG7h2NoIHLDtSBy4buHdCBnaeG7r2EgY8OhYyBkYW5oIG3hu6VjLiBOaMOzbSBUaOG7sWMgcGjhuqltIChGb29kKSBjaGnhur9tIMawdSB0aOG6vyB0dXnhu4d0IMSR4buRaSB24bubaSA3Mi4yMiUsIHRy4bufIHRow6BuaCBuaMOzbSBz4bqjbiBwaOG6qW0gY2jhu6cgxJHhuqFvIHRyb25nIGjhu4cgdGjhu5FuZy4gVHJvbmcga2hpIMSRw7MsIG5ow7NtIFBoaSB0acOqdSBkw7luZyAoTm9uLUNvbnN1bWFibGUpIMSR4bqhdCAxOC44OSUsIHbDoCBuaMOzbSDEkOG7kyB14buRbmcgKERyaW5rKSBjw7MgdOG6p24gc3XhuqV0IHRo4bqlcCBuaOG6pXQsIGNo4buJIGNoaeG6v20gOC44OSUuIFPhu7EgcGjDom4gYuG7kSBuw6B5IHBo4bqjbiDDoW5oIHLDtSBuaHUgY+G6p3UgdGnDqnUgZMO5bmcgdOG6rXAgdHJ1bmcgY2jhu6cgeeG6v3UgdsOgbyBjw6FjIHPhuqNuIHBo4bqpbSB0aOG7sWMgcGjhuqltLCBn4bqlcCBoxqFuIDMgbOG6p24gc28gduG7m2kgbmjDs20gcGhpIHRpw6p1IGTDuW5nIHbDoCBn4bqlcCA4IGzhuqduIHNvIHbhu5tpIMSR4buTIHXhu5FuZy4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyB4deG6pXQgcGjDoXQgdOG7qyDEkeG6t2MgxJFp4buDbSBraW5oIGRvYW5oIGPhu6dhIGPhu61hIGjDoG5nIGhv4bq3YyB0aMOzaSBxdWVuIG11YSBz4bqvbSBj4bunYSBraMOhY2ggaMOgbmcuDQoNCiMjICoqMi45IEJp4bq/biBQcm9kdWN0RGVwYXJ0bWVudCoqDQoNCltgUHJvZHVjdERlcGFydG1lbnRgXXtzdHlsZT0iY29sb3I6Z3JlZW4ifSBsw6AgYmnhur9uIHRo4buDIGhp4buHbiBkYW5oIG3hu6VjIGPDoWMgc+G6o24gcGjhuqltIMSRxrDhu6NjIHRpw6p1IHRo4bulIHThuqFpIHNpw6p1IHRo4buLIGJhbyBn4buTbSAyMiBiaeG7g3UgaGnhu4duIHTGsMahbmcg4bupbmcgduG7m2kgMjIgZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0uDQoNCiMjIyAqKioyLjkuMSBUaOG7kW5nIGvDqiB04bqnbiBz4buRLCB04bqnbiBzdeG6pXQqKioNCg0KYGBge3J9DQojIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRDQpwZF9mIDwtIHRhYmxlKHN0JFByb2R1Y3REZXBhcnRtZW50KQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQNCnBkX3AgPC0gcHJvcC50YWJsZShwZF9mKSoxMDANCg0KIyBL4bq/dCBo4bujcCB0aMOgbmggbeG7mXQgYuG6o25nDQpwZCA8LSBkYXRhLmZyYW1lKA0KICBDYXRlZ29yeSA9IG5hbWVzKHBkX2YpLA0KICBGcmVxdWVuY3kgPSBhcy52ZWN0b3IocGRfZiksDQogIFBlcmNlbnRhZ2UgPSByb3VuZChhcy52ZWN0b3IocGRfcCksIDIpDQopDQpwZA0KYGBgDQoNCiMjIyAqKioyLjkuMiBUcuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1KioqDQoNCmBgYHtyfQ0KZ2dwbG90KHN0LCBhZXMoeCA9IFByb2R1Y3REZXBhcnRtZW50KSkgKyANCiAgZ2VvbV9iYXIoZmlsbCA9ICIjNTU4IikgKw0KICBnZW9tX3RleHQoDQogICAgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChjb3VudCkpLA0KICAgIHN0YXQgPSAiY291bnQiLA0KICAgIHZqdXN0ID0gLTAuMywNCiAgICBzaXplID0gMy41DQogICkgKw0KICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA5OiBDb25zdW1wdGlvbiBieSBQcm9kdWN0IERlcGFydG1lbnQiLCB4ID0gIlByb2R1Y3QgRGVwYXJ0bWVudCIsIHkgPSAiRnJlcXVlbmN5IikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSggYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwNCiAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogROG7ryBsaeG7h3UgdOG6p24gc+G7kSB0acOqdSB0aOG7pSBz4bqjbiBwaOG6qW0gY2hvIHRo4bqleSBz4buxIHBow6JuIGLhu5Ega2jDtG5nIMSR4buTbmcgxJHhu4F1IGdp4buvYSBjw6FjIGRhbmggbeG7pWMuIE5ow7NtIFByb2R1Y2UgKHPhuqNuIHBo4bqpbSB0xrDGoWkgc+G7kW5nKSBk4bqrbiDEkeG6p3UgduG7m2kgdOG6p24gc3XhuqV0IGNhbyBuaOG6pXQgKDE5OTQsIGtob+G6o25nIDE0LjE4JSksIHRp4bq/cCB0aGVvIGzDoCBIb3VzZWhvbGQgKMSR4buTIGdpYSBk4bulbmcgLSAxNDIwKSB2w6AgRnJvemVuIEZvb2RzICjEkeG7kyDEkcO0bmcgbOG6oW5oIC0gMTM4MiksIHBo4bqjbiDDoW5oIG5odSBj4bqndSB0aGnhur90IHnhur91IGjDoG5nIG5nw6B5IGPhu6dhIG5nxrDhu51pIHRpw6p1IGTDuW5nLiBDw6FjIG5ow7NtIFNuYWNrIEZvb2RzICjEkeG7kyDEg24gduG6t3QgLSAxNjAwKSB2w6AgRGFpcnkgKGNo4bq/IHBo4bqpbSB04burIHPhu69hIC0gOTAzKSBjxaluZyBjw7MgdOG6p24gc3XhuqV0IMSRw6FuZyBr4buDLCBjaG8gdGjhuqV5IHh1IGjGsOG7m25nIHRpw6p1IGTDuW5nIMSR4buTIMSDbiBuaOG6uSB2w6Agc+G6o24gcGjhuqltIHThu6sgc+G7r2EuIMSQw6FuZyBjaMO6IMO9LCBt4buZdCBz4buRIG5ow7NtIGPDsyB04bqnbiBzdeG6pXQgdGjhuqVwIG5oxrAgQ2Fyb3VzZWwgKGPDoWMgc+G6o24gcGjhuqltIGLDoW4gdOG6oWkgcXXhuqd5IHRodSBuZ8OibiAtIDU5KSwgU2VhZm9vZCAoaOG6o2kgc+G6o24gLSAxMDIpIHbDoCBBbGNvaG9saWMgQmV2ZXJhZ2VzICh0aOG7qWMgdeG7kW5nIGPDsyBj4buTbiAtIDM1NiksIGPDsyB0aOG7gyBkbyDEkeG6t2MgdGjDuSBuZ8OgbmggaMOgbmcgaG/hurdjIGjhuqFuIGNo4bq/IHRyb25nIGNow61uaCBzw6FjaCBiw6FuIGjDoG5nLiBT4buxIGNow6puaCBs4buHY2ggbOG7m24gZ2nhu69hIG5ow7NtIGNhbyBuaOG6pXQgKFByb2R1Y2UgLSAxOTk0KSB2w6AgdGjhuqVwIG5o4bqldCAoQ2Fyb3VzZWwgLSA1OSkgY2hvIHRo4bqleSBz4buxIHThuq1wIHRydW5nIGNo4bunIHnhur91IHbDoG8gY8OhYyBt4bq3dCBow6BuZyB0aGnhur90IHnhur91LCB0cm9uZyBraGkgbmjDs20gaMOgbmcgxJHhurdjIGJp4buHdCBob+G6t2Mga2jDtG5nIHRoaeG6v3QgeeG6v3UgY8OzIHThuqduIHN14bqldCB0acOqdSB0aOG7pSB0aOG6pXAgaMahbiByw7UgcuG7h3QuIEThu68gbGnhu4d1IG7DoHkgZ2nDunAgbmjDoCBxdeG6o24gbMO9IHjDoWMgxJHhu4tuaCDEkcaw4bujYyBuaMOzbSBz4bqjbiBwaOG6qW0gY+G6p24gxrB1IHRpw6puIHBow6F0IHRyaeG7g24gdsOgIG5o4buvbmcgbeG6t3QgaMOgbmcgY+G6p24gY8OzIGNoaeG6v24gbMaw4bujYyB0aeG6v3AgdGjhu4sgcGjDuSBo4bujcCDEkeG7gyB0xINuZyBkb2FuaCBz4buRLg0KDQojIyAqKjIuMTAgQmnhur9uIFByb2R1Y3RDYXRlZ29yeSoqDQoNCltgUHJvZHVjdENhdGVnb3J5YF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gbMOgIGJp4bq/biB0aOG7gyBoaeG7h24gcGjDom4gbG/huqFpIG5ow7NtIGjDoG5nIGjDs2EgxJHGsOG7o2MgdGnDqnUgdGjhu6UgdOG6oWkgc2nDqnUgdGjhu4ssIGPhu6UgdGjhu4MgYmFvIGfhu5NtIDQ1IG5ow7NtIGjDoG5nIMSR4bqhaSBkaeG7h24gY2hvIDQ1IGJp4buDdSBoaeG7h3UgY+G7p2EgYmnhur9uIFtgUHJvZHVjdENhdGVnb3J5YF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gdHJvbmcgYuG7mSBk4buvIGxp4buHdSBbYFN1cGVybWFya2V0VHJhbnNhY3Rpb25zLmNzdmBde3N0eWxlPSJjb2xvcjpibHVlIn0uDQoNCiMjIyAqKioyLjEwLjEgVGjhu5FuZyBrw6ogdOG6p24gc+G7kSwgdOG6p24gc3XhuqV0KioqDQoNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kQ0KcGNfZiA8LSB0YWJsZShzdCRQcm9kdWN0Q2F0ZWdvcnkpDQoNCiMgTOG6rXAgYuG6o25nIHThuqduIHN14bqldA0KcGNfcCA8LSBwcm9wLnRhYmxlKHBjX2YpKjEwMA0KDQojIEvhur90IGjhu6NwIHRow6BuaCBt4buZdCBi4bqjbmcNCnBjIDwtIGRhdGEuZnJhbWUoDQogIENhdGVnb3J5ID0gbmFtZXMocGNfZiksDQogIEZyZXF1ZW5jeSA9IGFzLnZlY3RvcihwY19mKSwNCiAgUGVyY2VudGFnZSA9IHJvdW5kKGFzLnZlY3RvcihwY19wKSwgMikNCikNCnBjDQpgYGANCg0KIyMjICoqKjIuMTAuMiBUcuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1KioqDQoNCmBgYHtyfQ0KZ2dwbG90KHN0LCBhZXMoeCA9IFByb2R1Y3RDYXRlZ29yeSkpICsgDQogIGdlb21fYmFyKGZpbGwgPSAiIzU1OCIpICsNCiAgbGFicyh0aXRsZSA9ICJGaWd1cmUgMTA6IENvbnN1bXB0aW9uIGJ5IFByb2R1Y3QgQ2F0ZWdvcnkiLCB4ID0gIlByb2R1Y3QgQ2F0ZWdvcnkiLCB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKiBE4buvIGxp4buHdSB04bqnbiBzdeG6pXQgdGnDqnUgdGjhu6Ugc+G6o24gcGjhuqltIHRo4buDIGhp4buHbiBz4buxIHBow6JuIGjDs2EgcsO1IHLhu4d0IGdp4buvYSBjw6FjIG5ow7NtIGjDoG5nLiBWZWdldGFibGVzICgxMi4yOSkgdsOgIFNuYWNrIEZvb2RzICgxMS4zOCkgZOG6q24gxJHhuqd1IHbhu5tpIHThuqduIHN14bqldCB2xrDhu6N0IHRy4buZaSwgcGjhuqNuIMOhbmggbmh1IGPhuqd1IHRoaeG6v3QgeeG6v3UgduG7gSByYXUgY+G7pyB0xrDGoWkgdsOgIMSR4buTIMSDbiB24bq3dCB0aeG7h24gbOG7o2kgdHJvbmcgdGjDs2kgcXVlbiB0acOqdSBkw7luZy4gQ8OhYyBt4bq3dCBow6BuZyBjaOG7pyBs4buxYyBraMOhYyBuaMawIERhaXJ5ICg2LjQyKSwgTWVhdCAoNS40MSkgdsOgIEZydWl0ICg1LjQ0KSBjxaluZyBkdXkgdHLDrCB04bqnbiBzdeG6pXQgY2FvLCB0cm9uZyBraGkgbmjDs20gSmFtcyBhbmQgSmVsbGllcyAoNC4xOCkgdsOgIEJha2luZyBHb29kcyAoMy40NCkgY2hp4bq/bSB24buLIHRyw60gdHJ1bmcgYsOsbmguIMSQ4bq3YyBiaeG7h3QsIG5ow7NtIENhbm5lZCBPeXN0ZXJzICgwLjI1KSwgQ2FubmVkIEFuY2hvdmllcyAoMC4zMSkgdsOgIE1pc2NlbGxhbmVvdXMgKDAuMzApIGPDsyB04bqnbiBzdeG6pXQgdGjhuqVwIG5o4bqldCwgY2jhu4kgYuG6sW5nIDEvNTAgc28gduG7m2kgbmjDs20gZOG6q24gxJHhuqd1LCBjaG8gdGjhuqV5IMSRw6J5IGzDoCBuaOG7r25nIG3hurd0IGjDoG5nIG5nw6FjaCBob+G6t2Mgw610IMSRxrDhu6NjIMawYSBjaHXhu5luZy4gU+G7sSBjaMOqbmggbOG7h2NoIMSRw6FuZyBr4buDIGdp4buvYSBjw6FjIG5ow7NtIGjDoG5nICh04burIDAuMjUgxJHhur9uIDEyLjI5KSBn4bujaSDDvSBy4bqxbmc6DQoNCi0gICBDw6FjIHPhuqNuIHBo4bqpbSB0xrDGoWkgc+G7kW5nIHbDoCB0aGnhur90IHnhur91IGx1w7RuIGNoaeG6v20gxrB1IHRo4bq/DQoNCi0gICDEkOG7kyBo4buZcCB2w6AgaMOgbmcgxJHhurdjIHPhuqNuIGPDsyBwaOG6oW0gdmkgdGnDqnUgdGjhu6UgaOG6uXANCg0KLSAgIE5ow7NtIMSR4buTIHXhu5FuZyAoQmVlciBhbmQgV2luZTogMi41MywgSG90IEJldmVyYWdlczogMS42MSkgY8OzIHRp4buBbSBuxINuZyBwaMOhdCB0cmnhu4NuIHRow6ptDQoNClBow6JuIHTDrWNoIG7DoHkgY3VuZyBj4bqlcCBjxqEgc+G7nyDEkeG7gyB04buRaSDGsHUgaMOzYSBjxqEgY+G6pXUgaMOgbmcgaMOzYSwgdOG6rXAgdHJ1bmcgbmd14buTbiBs4buxYyB2w6BvIG5ow7NtIGPDsyB04bqnbiBzdeG6pXQgY2FvIMSR4buTbmcgdGjhu51pIGPDom4gbmjhuq9jIGdp4bqjbSBi4bubdCBt4bq3dCBow6BuZyBjw7MgaGnhu4d1IHN14bqldCB0aOG6pXAgxJHhu4MgbsOibmcgY2FvIGhp4buHdSBxdeG6oyBraW5oIGRvYW5oIHThu5VuZyB0aOG7gy4NCg0KIyAqKlBI4bqmTiAzOiDGr+G7mkMgTMav4buiTkcgS0hP4bqiTkcgVsOAIEtJ4buCTSDEkOG7ik5IIEdJ4bqiIFRIVVnhur5UIENITyBU4bu2IEzhu4YqKg0KDQpUcm9uZyB0aOG7kW5nIGvDqiBzdXkgZGnhu4VuLCB2aeG7h2MgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHbDoCBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCBjaG8gdOG7tyBs4buHIGzDoCBt4buZdCBixrDhu5tjIHF1YW4gdHLhu41uZywgxJHhurdjIGJp4buHdCBsw6AgdHJvbmcgdHLGsOG7nW5nIGjhu6NwIG114buRbiDEkcawYSByYSBr4bq/dCBsdeG6rW4gduG7gSBxdeG6p24gdGjhu4MgZOG7sWEgdHLDqm4gbeG6q3UuIEtoaSBraOG6o28gc8OhdCwgdGEgY2jhu4kgbOG6pXkgbeG7mXQgbeG6q3Ugbmjhu48gdOG7qyBxdeG6p24gdGjhu4MgbOG7m24sIG3DoCBt4bqrdSDEkeG6oWkgZGnhu4duIGNobyBxdeG6p24gdGjhu4MgbsOqbiB0YSBj4bqnbiDGsOG7m2MgbMaw4bujbmcgxJHGsOG7o2Mga2hv4bqjbmcgdGluIGPhuq15IGNobyB04bu3IGzhu4cgdGjhuq10IHPhu7EgYsOqbiBuZ2/DoGkgcXXhuqduIHRo4buDLiBOZ2/DoGkgcmEgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIGPDsm4gxJHGsGEgcmEgxJHGsOG7o2MgbeG7mXQga2hv4bqjbmcgdGluIGPhuq15IHRo4buDIGhp4buHbiDEkeG7mSBjaMOtbmggeMOhYyBj4bunYSB04bu3IGzhu4cuDQoNCiMjICoqMy4xIENvdW50cnkgLSBVU0EqKg0KDQpWaeG7h2MgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSBjaG8gdOG7tyBs4buHIGtow6FjaCBow6BuZyDEkeG6v24gdOG7qyAiVVNBIiB0cm9uZyBiaeG6v24gW2BDb3VudHJ5YF17c3R5bGU9ImNvbG9yOmdyZWVuIn0gbMOgIGPhuqduIHRoaeG6v3QgbmjhurFtIHN1eSByYSB04bu3IGzhu4cgdGjhuq10IHPhu7EgY+G7p2EgbmjDs20gbsOgeSB0cm9uZyB0b8OgbiBi4buZIHF14bqnbiB0aOG7gyBraMOhY2ggaMOgbmcsIGNo4bupIGtow7RuZyBjaOG7iSBk4buxYSB2w6BvIHThu7cgbOG7hyBxdWFuIHPDoXQgxJHGsOG7o2MgdOG7qyBt4bqrdS4gRG8gZOG7ryBsaeG7h3UgdGh1IHRo4bqtcCBjaOG7iSBsw6AgbeG7mXQgcGjhuqduIG5o4buPIGPhu6dhIHF14bqnbiB0aOG7gywgbsOqbiB04bu3IGzhu4cgIlVTQSIgdHJvbmcgbeG6q3UgY8OzIHRo4buDIGRhbyDEkeG7mW5nIGRvIG5n4bqrdSBuaGnDqm4uIFRow7RuZyBxdWEga2hv4bqjbmcgdGluIGPhuq15LCB0YSBjw7MgdGjhu4MgeMOhYyDEkeG7i25oIG3hu5l0IGtob+G6o25nIGdpw6EgdHLhu4sgaOG7o3AgbMO9IG3DoCB0cm9uZyDEkcOzLCB24bubaSBt4buZdCBt4bupYyDEkeG7mSB0aW4gY+G6rXkgKHRoxrDhu51uZyBsw6AgOTUlKSwgdOG7tyBs4buHIHRo4bqtdCBz4buxIGPhu6dhIGtow6FjaCBow6BuZyDEkeG6v24gdOG7qyBN4bu5IGPDsyBraOG6oyBuxINuZyBu4bqxbSB0cm9uZyDEkcOzLiDEkGnhu4F1IG7DoHkgY8OzIHRo4buDIGdpw7pwIGNobyBjw6FjIG5ow6AgcXXhuqNuIGzDvSBjw7MgdGjhu4MgY8OzIGPEg24gY+G7qSB0cm9uZyB2aeG7h2MgxJHhuql5IG3huqFuaCB2w6BvIHRo4buLIHRyxrDhu51uZyBN4bu5IGjGoW4gY8OhYyB0aOG7iyB0csaw4budbmcga2jDoWMgZG8gxJFhIHPhu5Ega2jDoWNoIGjDoG5nIMSR4bq/biB04burIE3hu7kuDQoNCioqxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteToqKiBW4bubaSBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyDEkeG6v24gdOG7qyBN4bu5IGzDoCA5NTYyIHRyw6puIHThu5VuZyBz4buRIGtow6FjaCBow6BuZyBsw6AgMTQwNTksIHRhIGPDsyBr4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcga2hv4bqjbmcgdGluIGPhuq15IHbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgbmjGsCBzYXU6DQoNCmBgYHtyfQ0KIyBT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyDEkeG6v24gdOG7qyAiVVNBIg0KdXNhIDwtIHN1bShzdCRDb3VudHJ5ID09ICJVU0EiKQ0KIyBU4buVbmcgc+G7kSBraMOhY2ggaMOgbmcNCnRvdGFsIDwtIGxlbmd0aChzdCRDb3VudHJ5KQ0KIyBLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdQ0KcHJvcC50ZXN0KHVzYSwgdG90YWwsIHAgPSAwLjY4LCBjb25mLmxldmVsID0gMC45NSkNCmBgYA0KDQoqKkvhur90IGx14bqtbjoqKg0KDQrEkOG6t3QgZ2nhuqMgdGh1eeG6v3Q6DQokJA0KXGxlZnRcew0KXGJlZ2lue2FycmF5fXtsbH0NCkhfMDogJiBcdGV4dHtU4bu3IGzhu4cgdGjhu7FjIHPhu5Ega2jDoWNoIGjDoG5nIMSR4bq/biB04burIFVTQSB9ID0gMC42OCBcXA0KSF8xOiAmIFx0ZXh0e1Thu7cgbOG7hyB0aOG7sWMgc+G7kSBraMOhY2ggaMOgbmcgxJHhur9uIHThu6sgVVNBIH0gXG5lIDAuNjgNClxlbmR7YXJyYXl9DQpccmlnaHQuDQokJA0KDQpUYSB0aOG6pXkgZ2nDoSB0cuG7iyBwX3ZhbHVlID0gMC45ODAxID4gNSUgbsOqbiB0YSBraMO0bmcgxJHhu6cgY8ahIHPhu58gxJHhu4MgYsOhYyBi4buPICRIXzAkLCBuZ2jEqWEgbMOgIHThu7cgbOG7hyBz4buRIGtow6FjaCBow6BuZyDEkeG6v24gdOG7qyBVU0EgdHJvbmcgdGjhu7FjIHThur8gbMOgIDY4JS4gTmdvw6BpIHJhLCB0YSBjw7MgdGjhu4MgxrDhu5tjIGzGsOG7o25nIHPhu5Ega2jDoWNoIGjDoG5nIMSR4bq/biB04burIFVTQSB0cm9uZyB0aOG7sWMgdOG6vyB24bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgNjcuMjMlIMSR4bq/biA2OC43OCUuDQoNCioqS2nhu4NtIMSR4buLbmggYWJjKioNCg0KIyMgKiozLjIgUHJvZHVjdEZhbWlseSAtIEZvb2QqKg0KDQpWaeG7h2MgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSBjaG8gdOG7tyBs4buHIGjhu40gc+G6o24gcGjhuqltIGzDoCAiRm9vZCIgdHJvbmcgYmnhur9uIFtgUHJvZHVjdEZhbWlseWBde3N0eWxlPSJjb2xvcjpncmVlbiJ9IGzDoCBj4bqnbiB0aGnhur90LiBL4bq/dCBxdeG6oyBj4bunYSDGsOG7m2MgbMaw4bujbmcgbsOgeSBjw7MgdGjhu4MgZ2nDunAgY8OhYyBuaMOgIHF14bqjbiBsw70geMOhYyDEkeG7i25oIMSRxrDhu6NjIGPDsyBuw6puIMSR4bqpeSBt4bqhbmggcGjDoXQgdHJp4buDbiBjw6FjIHPhuqNuIHBo4bqpbSB0aHXhu5ljIGjhu40gIkZvb2QiIGhheSBraMO0bmcgdGjDtG5nIHF1YSB04bu3IGzhu4cgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nLiBO4bq/dSB04bu3IGzhu4cgbMOgIMSRw7puZywgdmnhu4djIMSR4bqpeSBt4bqhbmggdsOgbyBwaMOhdCB0cmnhu4NuIHPhuqNuIHBo4bqpbSB0aHXhu5ljIGjhu40gdGjhu6ljIMSDbiBz4bq9IGdpw7pwIHTEg25nIGRvYW5oIHRodSBj4bunYSBjw6FjIHNpw6p1IHRo4buLIHbDrCDEkWEgc+G7kSBjw6FjIGtow6FjaCBow6BuZyDEkeG6v24gxJHhu4MgbXVhIHRo4bupYyDEg24uDQoNCioqxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteToqKiBW4bubaSBz4buRIGxv4bqhaSB0aOG7sWMgcGjhuqltIHRodeG7mWMgIkZvb2QiIGzDoCAxMDE1MyB0csOqbiB04buVbmcgc+G7kSBsw6AgMTQwNTksIHRhIGPDsyBr4bq/dCBxdeG6oyDGsOG7m2MgbMaw4bujbmcga2hv4bqjbmcgdGluIGPhuq15IHbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgbmjGsCBzYXU6DQoNCmBgYHtyfQ0KIyBT4buRIGzGsOG7o25nIHRo4buxYyBwaOG6qW0gbMOgICJGb29kIg0KZm9vZCA8LSBzdW0oc3QkUHJvZHVjdEZhbWlseSA9PSAiRm9vZCIpDQojIEtp4buDbSDEkeG7i25oIHThu7cgbOG7hyAxIG3huqt1DQpwcm9wLnRlc3QoZm9vZCwgdG90YWwsIHAgPSAwLjcyLCBjb25mLmxldmVsID0gMC45NSkNCmBgYA0KDQoqKkvhur90IGx14bqtbjoqKg0KDQrEkOG6t3QgZ2nhuqMgdGh1eeG6v3Q6DQokJA0KXGxlZnRcew0KXGJlZ2lue2FycmF5fXtsbH0NCkhfMDogJiBcdGV4dHtU4bu3IGzhu4cgdGjhu7FjIHThur8ga2jDoWNoIGjDoG5nIG11YSB0aOG7sWMgcGjhuqltIH0gPSAwLjcyIFxcDQpIXzE6ICYgXHRleHR7VOG7tyBs4buHIHRo4buxYyB04bq/IGtow6FjaCBow6BuZyBtdWEgdGjhu7FjIHBo4bqpbSB9IFxuZSAwLjcyDQpcZW5ke2FycmF5fQ0KXHJpZ2h0Lg0KJCQNCg0KVGEgdGjhuqV5IGdpw6EgdHLhu4sgeMOhYyBzdeG6pXQgcF92YWx1ZSA9IDAuNTcyOCA+IDUlIG5naMSpYSBsw6AgdGEgY2jhuqVwIG5o4bqtbiAkSF8wJCwga2hpIMSRw7MgdGEga+G6v3QgbHXhuq1uIHLhurFuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG11YSB0aOG7sWMgcGjhuqltIHRyb25nIHRo4buxYyB04bq/IGzDoCBraG/huqNuZyA3MiUuIE5nb8OgaSByYSB0YSBjw7JuIMaw4bubYyBsxrDhu6NuZyB0cm9uZyB0aOG7sWMgdOG6vywgc+G7kSBsxrDhu6NuZyB0aOG7sWMgcGjhuqltIGNoaeG6v20ga2hv4bqjbmcgNzEuNDclIMSR4bq/biA3Mi45NSUgduG7m2kgbeG7qWMgw70gbmdoxKlhIDUlLg0KDQojIyAqKjMuMyBBbm51YWxJbmNvbWUgLSBcJDEwSyAtIFwkNTBLKioNCg0KVmnhu4djIMaw4bubYyBsxrDhu6NuZyBraG/huqNuZyB0aW4gY+G6rXkgY2hvIGtow6FjaCBjw7MgbeG7qWMgdGh1IG5o4bqtcCB0aOG6pXAgKGtob+G6o25nIHThu6sgMTBLIMSR4bq/biA1MEsgVVNEIGjhurFuZyBuxINtKSBz4bq9IGdpw7pwIHNpw6p1IHRo4buLIGPDsyB0aOG7gyBjw7Mgbmjhu69uZyBjaGnhur9uIGzGsOG7o2MgcXXhuqNuZyBjw6FvIGhheSBiw6FuIGjDoG5nIG5o4bqvbSB2w6BvIHThu4dwIGtow6FjaCBow6BuZyB0aMaw4budbmcgbXVhIHPhuq9tLCBnacO6cCB04buRaSDGsHUgZG9hbmggdGh1IHbDoCBs4bujaSBuaHXhuq1uIGPhu6dhIHNpw6p1IHRo4buLLg0KDQoqKsav4bubYyBsxrDhu6NuZyBraG/huqNuZyB0aW4gY+G6rXk6KioNCg0KYGBge3J9DQojIFPhu5Ega2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oDQptaWQgPC0gc3VtKHN0JEFubnVhbEluY29tZSA9PSAiJDMwSyAtICQ1MEsiLHN0JEFubnVhbEluY29tZSA9PSAiJDEwSyAtICQzMEsiKQ0KIyBLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdQ0KcHJvcC50ZXN0KG1pZCwgdG90YWwsIHAgPSAwLjU1LCBjb25mLmxldmVsID0gMC45NSkNCmBgYA0KDQoqKkvhur90IGx14bqtbjoqKg0KDQrEkOG6t3QgZ2nhuqMgdGh1eeG6v3QNCg0KJCQNClxsZWZ0XHsNClxiZWdpbnthcnJheX17bGx9DQpIXzA6ICYgXHRleHR7VOG7tyBs4buHIHRo4buxYyB04bq/IGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB0aOG6pXAgfSA9IDAuNTUgXFwNCkhfMTogJiBcdGV4dHtU4bu3IGzhu4cgdGjhu7FjIHThur8ga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHRo4bqlcCB9IFxuZSAwLjU1DQpcZW5ke2FycmF5fQ0KXHJpZ2h0Lg0KJCQNCg0KVGEgdGjhuqV5IGdpw6EgdHLhu4sgeMOhYyBzdeG6pXQgcF92YWx1ZSA9IDAuNDg3NiA+IDUlIG5naMSpYSBsw6AgdGEgY2jhuqVwIG5o4bqtbiAkSF8wJCwga2hpIMSRw7MgdGEga+G6v3QgbHXhuq1uIHLhurFuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHRo4bqlcCB0cm9uZyB0aOG7sWMgdOG6vyBsw6Aga2hv4bqjbmcgNTUlLiBOZ2/DoGkgcmEgdGEgY8OybiDGsOG7m2MgbMaw4bujbmcgdHJvbmcgdGjhu7FjIHThur8sIHPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHRo4bqlcCBjaGnhur9tIGtob+G6o25nIDUzLjg4JSDEkeG6v24gNTUuNTMlJSB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUuDQoNCiMgKipQSOG6pk4gNDogUEjDgk4gVMONQ0ggTeG7kEkgUVVBTiBI4buGIEdJ4buuQSBDw4FDIEJJ4bq+TiDEkOG7ik5IIFTDjU5IKioNCg0KIyMgKio0LjEgUHJvZHVjdERlcGFydG1lbnQgdsOgIEFubnVhbEluY29tZSoqDQoNCiMjIyAqKio0LjEuMSBC4bqjbmcgdOG6p24gc3XhuqV0IGNow6lvKioqDQoNCmBgYHtyfQ0KcGRfYWkgPC0gdGFibGUoc3QkQW5udWFsSW5jb21lLHN0JFByb2R1Y3REZXBhcnRtZW50KQ0KZGZfcGRfYWkgPC0gYXMuZGF0YS5mcmFtZShwZF9haSkNCmNvbG5hbWVzKGRmX3BkX2FpKSA8LSBjKCJBbm51YWwgSW5jb21lIiwgIlByb2R1Y3QgRGVwYXJ0bWVudCIsICJGcmVxdWVuY3kiKQ0KZGZfcGRfYWkNCmBgYA0KDQojIyMgKioqNC4xLjIgVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSoqKg0KDQoqKipOaMOzbSBjw7MgdGh1IG5o4bqtcCB0aOG6pXA6KioqDQoNCmBgYHtyfQ0KIyBQaMOibiBsb+G6oWkgbmjDs20gY8OzIHRodSBuaOG6rXAgdGjhuqVwDQpsb3dfaW5jb21lIDwtIHBkX2FpW3Jvdy5uYW1lcyhwZF9haSkgJWluJSBjKCIkMTBLIC0gJDMwSyIsIiQzMEsgLSAkNTBLIiksIF0NCmxvd19pbmNvbWVfZGYgPC0gYXMuZGF0YS5mcmFtZShsb3dfaW5jb21lKQ0KY29sbmFtZXMobG93X2luY29tZV9kZikgPC0gYygiQW5udWFsIEluY29tZSIsICJQcm9kdWN0IERlcGFydG1lbnQiLCAiRnJlcXVlbmN5IikNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdChsb3dfaW5jb21lX2RmLCBhZXMoeCA9IGBBbm51YWwgSW5jb21lYCwgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IGBQcm9kdWN0IERlcGFydG1lbnRgKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsNCiAgZmFjZXRfd3JhcCh+YFByb2R1Y3QgRGVwYXJ0bWVudGApICsNCiAgbGFicyh0aXRsZSA9ICdGaWd1cmUgMTE6IFByb2R1Y3QgRGVwYXJ0bWVudCBieSBMb3cgSW5jb21lJywgeCA9ICdQcm9kdWN0IERlcGFydG1lbnQnLCB5PSdGcmVxdWVuY3knKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpKQ0KYGBgDQoNCioqKk5ow7NtIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oOioqKg0KDQpgYGB7cn0NCiMgUGjDom4gbG/huqFpIG5ow7NtIGPDsyB0aHUgbmjhuq1wIHRydW5nIGLDrG5oDQptaWRfaW5jb21lIDwtIHBkX2FpW3Jvdy5uYW1lcyhwZF9haSkgJWluJSBjKCIkNTBLIC0gJDcwSyIsIiQ3MEsgLSAkOTBLIiwgIiQ5MEsgLSAkMTEwSyIpLCBdDQptaWRfaW5jb21lX2RmIDwtIGFzLmRhdGEuZnJhbWUobWlkX2luY29tZSkNCmNvbG5hbWVzKG1pZF9pbmNvbWVfZGYpIDwtIGMoIkFubnVhbCBJbmNvbWUiLCAiUHJvZHVjdCBEZXBhcnRtZW50IiwgIkZyZXF1ZW5jeSIpDQojIFbhur0gYmnhu4N1IMSR4buTDQpnZ3Bsb3QobWlkX2luY29tZV9kZiwgYWVzKHggPSBgQW5udWFsIEluY29tZWAsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBgUHJvZHVjdCBEZXBhcnRtZW50YCkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArDQogIGZhY2V0X3dyYXAofmBQcm9kdWN0IERlcGFydG1lbnRgKSArDQogIGxhYnModGl0bGUgPSAnRmlndXJlIDEyOiBQcm9kdWN0IERlcGFydG1lbnQgYnkgTWlkZGxlIEluY29tZScsIHggPSAnUHJvZHVjdCBEZXBhcnRtZW50JywgeT0nRnJlcXVlbmN5JykgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSkNCmBgYA0KDQoqKipOaMOzbSBjw7MgdGh1IG5o4bqtcCBjYW86KioqDQoNCmBgYHtyfQ0KIyBQaMOibiBsb+G6oWkgbmjDs20gY8OzIHRodSBuaOG6rXAgY2FvDQpoaWdoX2luY29tZSA8LSBwZF9haVtyb3cubmFtZXMocGRfYWkpICVpbiUgYygiJDExMEsgLSAkMTMwSyIsIiQxMzBLIC0gJDE1MEsiLCIkMTUwSyArIiksIF0NCmhpZ2hfaW5jb21lX2RmIDwtIGFzLmRhdGEuZnJhbWUoaGlnaF9pbmNvbWUpDQpjb2xuYW1lcyhoaWdoX2luY29tZV9kZikgPC0gYygiQW5udWFsIEluY29tZSIsICJQcm9kdWN0IERlcGFydG1lbnQiLCAiRnJlcXVlbmN5IikNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdChoaWdoX2luY29tZV9kZiwgYWVzKHggPSBgQW5udWFsIEluY29tZWAsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBgUHJvZHVjdCBEZXBhcnRtZW50YCkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArDQogIGZhY2V0X3dyYXAofmBQcm9kdWN0IERlcGFydG1lbnRgKSArDQogIGxhYnModGl0bGUgPSAnRmlndXJlIDEzOiBQcm9kdWN0IERlcGFydG1lbnQgYnkgSGlnaCBJbmNvbWUnLCB4ID0gJ1Byb2R1Y3QgRGVwYXJ0bWVudCcsIHk9J0ZyZXF1ZW5jeScpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpDQpgYGANCg0KIyMjICoqKjQuMS4zIE5o4bqtbiB4w6l0KioqDQoNCkvhur90IHF14bqjIGNobyB0aOG6pXkg4bufIG5ow7NtIGPDsyB0aHUgbmjhuq1wIHRo4bqlcCwgdHJ1bmcgYsOsbmggaGF5IGNhbyB0aMOsIMSR4buBdSB0acOqdSB0aOG7pSBz4buRIGzGsOG7o25nIGzhu5tuIG7DtG5nIHPhuqNuIHTGsMahaSAoUHJvZHVjZSksIHRo4buxYyBwaOG6qW0gxJHDtG5nIGzhuqFuaCAoRnJvemVuIEZvb2QpLCB0aOG7qWMgxINuIHbhurd0IChTbmFjayBGb29kcyksIMSR4buTIGdpYSBk4bulbmcgKEhvdXNlaG9sZCksIMSR4buTIGzDoG0gYsOhbmggKEJhbmtpbmcgR29vZCksIMSR4buTIHXhu5FuZyAoQmV2ZXJhZ2VzKSwgY2jhur8gcGjhuqltIHThu6sgc+G7r2EgKERhaXJ5KSwgbmjhu69uZyBkYW5oIG3hu6VjIGtow6FjIHRow6wgbXVhIHLhuqV0IMOtdC4NCg0KIyMjICoqKjQuMS40IEtp4buDbSDEkeG7i25oIENoaS1Cw6xuaCBwaMawxqFuZyoqKg0KDQoqKlThu4dwIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB0aOG6pXAqKg0KDQpgYGB7cn0NCmNoaXNxLnRlc3QobG93X2luY29tZSkNCmBgYA0KDQoqKlThu4dwIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB0cnVuZyBiw6xuaCoqDQoNCmBgYHtyfQ0KY2hpc3EudGVzdChtaWRfaW5jb21lKQ0KYGBgDQoNCg0KKipU4buHcCBraMOhY2ggaMOgbmcgY8OzIHRodSBuaOG6rXAgY2FvKioNCg0KYGBge3J9DQpjaGlzcS50ZXN0KGhpZ2hfaW5jb21lKQ0KYGBgDQoNCsSQ4bq3dCBnaeG6oyB0aHV54bq/dA0KDQokJA0KXGxlZnRcew0KXGJlZ2lue2FycmF5fXtsbH0NCkhfMDogJiBcdGV4dHtLaMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgaGFpIGJp4bq/biBwaMOibiBsb+G6oWkgfSBcXA0KSF8xOiAmIFx0ZXh0e0PDsyB04buTbiB04bqhaSBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGhhaSBiaeG6v24gcGjDom4gbG/huqFpIH0NClxlbmR7YXJyYXl9DQpccmlnaHQuDQokJA0KDQotIMSQ4buRaSB24bubaSB04buHcCBraMOhY2ggaMOgbmcgY8OzIHRodSBuaOG6rXAgdGjhuqVwLCBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBjaG8gdGjhuqV5IGdpw6EgdHLhu4sgcF92YWx1ZSA9IDAuMDc5OTggPiA1JSBuaMawbmcgbmjhu48gaMahbiAxMCUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGPDsyBi4bqxbmcgY2jhu6luZyDEkeG7gyBiw6FjIGLhu48gJEhfMCQsIHR1eSBuaGnDqm4gYuG6sW5nIGNo4bupbmcgbsOgeSBraMO0bmcgxJHhu6cgbeG6oW5oLiBWw6wgdGjhur8gdGEgY2jhuqVwIG5o4bqtbiAkSF8wJCwgbmdoxKlhIGzDoCBraMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyBuw6BvIGdp4buvYSBjw6FjIGxv4bqhaSBow6BuZyBow7NhIHbDoCBjw6FjIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB0aOG6pXAuDQoNCi0gVMawxqFuZyB04buxIHbhu5tpIHThu4dwIGtow6FjaCBjw7MgdGh1IG5o4bqtcCB0cnVuZyBiw6xuaC4gVGEgdGjhuqV5IHBfdmFsdWUgPSAwLjA5MyA+IDUlIG5oxrBuZyB24bqrbiBuaOG7jyBoxqFuIDEwJS4gVsOsIHRo4bq/IHRhIGNo4bqlcCBuaOG6rW4gJEhfMCQsIG5naMSpYSBsw6Aga2jDtG5nIGPDsyBt4buRaSBxdWFuIGjhu4cgbsOgbyBnaeG7r2EgY8OhYyBsb+G6oWkgaMOgbmcgaMOzYSB2w6AgY8OhYyBraMOhY2ggaMOgbmcgY8OzIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmguDQoNCi0gxJDhu5FpIHbhu5tpIHThu4dwIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCBjYW8uIFRhIHRo4bqleSBwX3ZhbHVlID0gMC40NjUyID4gNSUsIHbDrCB0aOG6vyB0YSBjw7MgdGjhu4MgYsOhYyBi4buPICRIXzAkLCBuZ2jEqWEgbMOgIGPDsyB04buTbiB04bqhaSBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIHZp4buHYyBtdWEgaMOgbmcgaMOzYSDEkeG7kWkgduG7m2kgdOG7h3Aga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIGNhby4NCg0KIyMgKio0LjIgR2VuZGVyIHbDoCBQcm9kdWN0RmFtaWx5KioNCg0KIyMjICoqKjQuMS4xIELhuqNuZyB04bqnbiBzdeG6pXQgY2jDqW8qKioNCg0KYGBge3J9DQpnZW5kZXJfcGQgPC0gdGFibGUoc3QkUHJvZHVjdERlcGFydG1lbnQsc3QkR2VuZGVyKQ0KZGZfZ2VuZGVyX3BkIDwtIGFzLmRhdGEuZnJhbWUoZ2VuZGVyX3BkKQ0KY29sbmFtZXMoZGZfZ2VuZGVyX3BkKSA8LSBjKCJQcm9kdWN0IERlcGFydG1lbnQiLCAiR2VuZGVyIiwgIkZyZXF1ZW5jeSIpDQpkZl9nZW5kZXJfcGQNCmBgYA0KDQojIyMgKioqNC4xLjIgVHLhu7FjIHF1YW4gaMOzYSBk4buvIGxp4buHdSoqKg0KDQpgYGB7cn0NCmdncGxvdChkZl9nZW5kZXJfcGQsIGFlcyh4ID0gYFByb2R1Y3QgRGVwYXJ0bWVudGAsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBHZW5kZXIpKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKw0KICBsYWJzKHRpdGxlID0gJ0ZpZ3VyZSAxNDogR2VuZGVyIGRpc3RyaWJ1dGlvbiBieSBQcm9kdWN0IERlcGFydG1lbnQnLCB4ID0gJ1Byb2R1Y3QgRGVwYXJ0bWVudCcsIHkgPSAnRnJlcXVlbmN5JykgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpDQpgYGANCg0KIyMjICoqKjQuMS4zIE5o4bqtbiB4w6l0KioqDQoNCkvhur90IHF14bqjIGNobyB0aOG6pXkgY8OhYyBz4bqjbiBwaOG6qW0gxJHGsOG7o2MgbXVhIGLhu59pIG5hbSB2w6AgbuG7ryBraMO0bmcgY8OzIHF1w6Egbmhp4buBdSBz4buxIGNow6puaCBs4buHY2guIEPDoWMgbG/huqFpIHPhuqNuIHBo4bqpbSDEkcaw4bujYyBtdWEgYuG7n2kgbmFtIG5oaeG7gXUgaMahbiBiYW8gZ+G7k20gQmFraW5nIEdvb2RzLCBEYWlyeSwgSG91c2Vob2xkLCBQcm9kdWNlLCBTdGFyY2h5IEZvb2QuIEPDsm4gbOG6oWkgxJHGsOG7o2MgbXVhIG5oaeG7gXUgaMahbiBi4bufaSBu4buvLg0KDQojIyMgKioqNC4xLjQgS2nhu4NtIMSR4buLbmggQ2hpLULDrG5oIHBoxrDGoW5nKioqDQoNCmBgYHtyfQ0KY2hpc3EudGVzdChnZW5kZXJfcGQpDQpgYGANCg0KxJDhurd0IGdp4bqjIHRodXnhur90Og0KDQokJA0KXGxlZnRcew0KXGJlZ2lue2FycmF5fXtsbH0NCkhfMDogJiBcdGV4dHtLaMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgaGFpIGJp4bq/biBwaMOibiBsb+G6oWkgfSBcXA0KSF8xOiAmIFx0ZXh0e0PDsyB04buTbiB04bqhaSBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGhhaSBiaeG6v24gcGjDom4gbG/huqFpIH0NClxlbmR7YXJyYXl9DQpccmlnaHQuDQokJA0KDQpUYSB0aOG6pXkga+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggY2hvIHJhIGdpw6EgdHLhu4sgcF92YWx1ZSA9IDAuMDQwMTEgPCA1JSwgbmdoxKlhIGzDoCB0YSBiw6FjIGLhu48gJEhfMCQuIFbhuq15IG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgbG/huqFpIHPhuqNuIHBo4bqpbSBtw6Aga2jDoWNoIGjDoG5nIG11YSB2w6AgZ2nhu5tpIHTDrW5oIGzDoCBjw7MgbGnDqm4gcXVhbiDEkeG6v24gbmhhdS4NCg0KIyMgKio0LjMgTWFyaXRhbFN0YXR1cyB2w6AgUHJvZHVjdEZhbWlseSoqDQoNCiMjIyAqKio0LjEuMSBC4bqjbmcgdOG6p24gc3XhuqV0IGNow6lvKioqDQoNCmBgYHtyfQ0KbXNfcGYgPC0gdGFibGUoc3QkUHJvZHVjdEZhbWlseSxzdCRNYXJpdGFsU3RhdHVzKQ0KZGZfbXNfcGYgPC0gYXMuZGF0YS5mcmFtZShtc19wZikNCmNvbG5hbWVzKGRmX21zX3BmKSA8LSBjKCJQcm9kdWN0IEZhbWlseSIsIk1hcml0YWwgU3RhdHVzIiwgIkZyZXF1ZW5jeSIpDQpkZl9tc19wZg0KYGBgDQoNCiMjIyAqKio0LjEuMiBUcuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1KioqDQoNCmBgYHtyfQ0KZ2dwbG90KGRmX21zX3BmLCBhZXMoeCA9IGBNYXJpdGFsIFN0YXR1c2AsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBgUHJvZHVjdCBGYW1pbHlgKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsNCiAgbGFicyh0aXRsZSA9ICdGaWd1cmUgMTM6IFByb2R1Y3QgRmFtaWx5IGRpc3RyaWJ1dGlvbiBieSBNYXJpdGFsIFN0YXR1cycsIHggPSAnTWFyaXRhbCBTdGF0dXMnLCB5ID0gJ0ZyZXF1ZW5jeScpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAnYm9sZCcpKQ0KYGBgDQoNCiMjIyAqKio0LjEuMyBOaOG6rW4geMOpdCoqKg0KDQpUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdsOgIG5ow7NtIHPhuqNuIHBo4bqpbSBraMOhY2ggaMOgbmcgbXVhIGTGsOG7nW5nIG5oxrAga2jDtG5nIGPDsyBuaGnhu4F1IGNow6puaCBs4buHY2guDQoNCiMjIyAqKio0LjEuNCBLaeG7g20gxJHhu4tuaCBDaGktQsOsbmggcGjGsMahbmcqKioNCg0KYGBge3J9DQpjaGlzcS50ZXN0KG1zX3BmKQ0KYGBgDQoNCsSQ4bq3dCBnaeG6oyB0aHV54bq/dDoNCg0KJCQNClxsZWZ0XHsNClxiZWdpbnthcnJheX17bGx9DQpIXzA6ICYgXHRleHR7S2jDtG5nIGPDsyBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGhhaSBiaeG6v24gcGjDom4gbG/huqFpIH0gXFwNCkhfMTogJiBcdGV4dHtDw7MgdOG7k24gdOG6oWkgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBoYWkgYmnhur9uIHBow6JuIGxv4bqhaSB9DQpcZW5ke2FycmF5fQ0KXHJpZ2h0Lg0KJCQNCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggY2hvIHRo4bqleSBy4bqxbmcgZ2nDoSB0cuG7iyBwX3ZhbHVlID0gMC41NTk0ID4gNSUsIMSRaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGtow7RuZyDEkeG7pyBjxqEgc+G7nyDEkeG7gyBiw6FjIGLhu48gJEhfMCQsIG5naMSpYSBsw6AgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIHbDoCBuaMOzbSBz4bqjbiBwaOG6qW0gbXVhIHbDoG8gaG/DoG4gdG/DoG4ga2jDtG5nIGPDsyBt4buRaSBsacOqbiBo4buHIG7DoG8uDQoNCiMgKipQSOG6pk4gNTogVOG7lE5HIEvhur5UIFbDgCBUSOG6ok8gTFXhuqxOKioNCg0KIyMgKio1LjEgTmjhu69uZyBwaMOhdCBoaeG7h24gY2jDrW5oKioNCg0KS+G6v3QgcXXhuqMgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIGNobyB0aOG6pXkgbeG6q3UgbsOgeSBwaOG6o24g4bqjbmggxJHGsOG7o2MgY2jDrW5oIHjDoWMgdOG7tyBs4buHIHRyb25nIHRo4buxYyB04bq/LiBOZ2/DoGkgcmEgY8OhYyBr4bq/dCBxdeG6oyB24buBIHBow6JuIHTDrWNoIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgaGFpIGJp4bq/biDEkeG7i25oIHTDrW5oIGNobyB0aOG6pXkgcuG6sW5nIGPDsyBt4buRaSBsacOqbiBo4buHIGdp4buvYSBnaeG7m2kgdMOtbmggY+G7p2Ega2jDoWNoIGjDoG5nIHbDoCBsb+G6oWkgc+G6o24gcGjhuqltIG3DoCBo4buNIG11YSBjxaluZyBuaMawIHbhu5tpIHRodSBuaOG6rXAgY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQojIyAqKjUuMiBI4bqhbiBjaOG6vyBj4bunYSBwaMOibiB0w61jaCoqDQoNClBow6JuIHTDrWNoIG7DoHkgduG6q24gY2jGsGEgdGjhu7FjIHPhu7EgaGnhu4d1IHF14bqjIHbDrCBjaOG7iSDEkcawYSByYSAzIGPhurdwIGJp4bq/biDEkeG7gyBwaMOibiB0w61jaCBt4buRaSBxdWFuIGjhu4cuIFRyb25nIHRo4buxYyB04bq/IGPDoWMgYmnhur9uIHRo4buxYyBjaOG6pXQgc+G6vSBjw7Mgbmhp4buBdSBxdWFuIGjhu4cgY2jhu5NuZyBjaMOpbyB2w6AgcGjhu6ljIHThuqFwIGjGoW4gY2jhu6kga2jDtG5nIGNo4buJIGdp4buvYSBoYWkgY+G6t3AgYmnhur9uIHbhu5tpIG5oYXUuDQoNCiMjICoqNS4zIMSQ4buBIHh14bqldCoqDQoNCkThu7FhIHRyw6puIGvhur90IHF14bqjIMaw4bubYyBsxrDhu6NuZyBraG/huqNuZyB2w6AgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oLCBjw7MgdGjhu4MgxJHhu4EgeHXhuqV0IG3hu5l0IHPhu5EgZ2nhuqNpIHBow6FwIG5o4bqxbSBuw6JuZyBjYW8gaGnhu4d1IHF14bqjIGhv4bqhdCDEkeG7mW5nIGtpbmggZG9hbmggY+G7p2Egc2nDqnUgdGjhu4suIFRo4bupIG5o4bqldCwgdmnhu4djIG5o4bqtbiB0aOG6pXkgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IHRyb25nIGjDoG5oIHZpIG11YSBz4bqvbSB0aGVvIGdp4bubaSB0w61uaCBjaG8gdGjhuqV5IGPhuqduIHjDonkgZOG7sW5nIGPDoWMgY2hp4bq/biBsxrDhu6NjIHRp4bq/cCB0aOG7iyByacOqbmcgYmnhu4d0IGNobyB04burbmcgbmjDs20gZ2nhu5tpLCBjaOG6s25nIGjhuqFuIG5oxrAgdGhp4bq/dCBr4bq/IG7hu5lpIGR1bmcgcXXhuqNuZyBjw6FvIGhv4bq3YyBjaMawxqFuZyB0csOsbmgga2h1eeG6v24gbcOjaSBwaMO5IGjhu6NwIHbhu5tpIHRow7NpIHF1ZW4gdGnDqnUgZMO5bmcgY+G7p2EgbmFtIHbDoCBu4buvLiBUaOG7qSBoYWksIGvhur90IGjhu6NwIGdp4buvYSBnaeG7m2kgdMOtbmggdsOgIG3hu6ljIHRodSBuaOG6rXAgxJHhu4MgcGjDom4ga2jDumMga2jDoWNoIGjDoG5nIG3hu5l0IGPDoWNoIGNoaSB0aeG6v3QgaMahbiBz4bq9IGdpw7pwIHNpw6p1IHRo4buLIMSRxrBhIHJhIGPDoWMgc+G6o24gcGjhuqltIHbDoCBt4bupYyBnacOhIHBow7kgaOG7o3AgduG7m2kgdOG7q25nIG5ow7NtIMSR4buRaSB0xrDhu6NuZy4gTmdvw6BpIHJhLCBjw7MgdGjhu4MgY8OhIG5ow6JuIGjDs2EgdHLhuqNpIG5naGnhu4dtIG11YSBz4bqvbSB0aMO0bmcgcXVhIGPDoWMgZ+G7o2kgw70gc+G6o24gcGjhuqltLCBlbWFpbCBtYXJrZXRpbmcgaG/hurdjIMawdSDEkcOjaSBk4buxYSB0csOqbiB0aMO0bmcgdGluIHbhu4EgZ2nhu5tpIHTDrW5oIHbDoCB0aHUgbmjhuq1wIGPhu6dhIGtow6FjaCBow6BuZy4gQsOqbiBj4bqhbmggxJHDsywgdmnhu4djIGLhu5EgdHLDrSBs4bqhaSBraMO0bmcgZ2lhbiB0csawbmcgYsOgeSBz4bqjbiBwaOG6qW0gdGhlbyB0aMOzaSBxdWVuIG11YSBz4bqvbSBj4bunYSB04burbmcgbmjDs20ga2jDoWNoIGjDoG5nIGPFqW5nIHPhur0gZ2nDunAgY+G6o2kgdGhp4buHbiB0cuG6o2kgbmdoaeG7h20gdsOgIHTEg25nIGto4bqjIG7Eg25nIGLDoW4gaMOgbmcuIEN14buRaSBjw7luZywga+G6v3QgcXXhuqMgcGjDom4gdMOtY2ggY8OybiBo4buXIHRy4bujIHNpw6p1IHRo4buLIHRyb25nIHZp4buHYyB4w6J5IGThu7FuZyBr4bq/IGhv4bqhY2ggbmjhuq1wIGjDoG5nIGjhu6NwIGzDvSwgdOG6rXAgdHJ1bmcgdsOgbyBuaOG7r25nIG3hurd0IGjDoG5nIGPDsyBuaHUgY+G6p3UgY2FvIHRoZW8gdOG7q25nIG5ow7NtIGtow6FjaCBj4bulIHRo4buDLCB04burIMSRw7MgZ2nhuqNtIHRoaeG7g3UgaMOgbmcgdOG7k24ga2hvIHbDoCB04buRaSDGsHUgaMOzYSBkb2FuaCB0aHUuDQoNCiMjICoqNS40IEjGsOG7m25nIG5naGnDqm4gY+G7qXUgdGnhur9wIHRoZW8qKg0KDQpDw7MgdGjhu4MgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBuaGnhu4F1IGJp4bq/biBsw6puIG3hu5l0IGJp4bq/biB2w6Agbmhp4buBdSBiaeG6v24gbMOqbiBuaGF1IMSR4buDIMSRxrBhIHJhIMSRxrDhu6NjIHBow6JuIHTDrWNoIGNow61uaCB4w6FjIG5o4bqldC4NCg==