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ể chrcharacter có nghĩa là dạng kí tự, intinteger 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()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 = Frequencyfill = 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 4: PHÂN TÍCH MỐI QUAN HỆ GIỮA CÁC BIẾN ĐỊNH TÍNH

4.1 ProductDepartment và AnnualIncome

4.1.1 Bảng tần suất chéo

pd_ai <- table(st$AnnualIncome,st$ProductDepartment)
df_pd_ai <- as.data.frame(pd_ai)
colnames(df_pd_ai) <- c("Annual Income", "Product Department", "Frequency")
df_pd_ai

4.1.2 Trực quan hóa dữ liệu

Nhóm có thu nhập thấp:

# Phân loại nhóm có thu nhập thấp
low_income <- pd_ai[row.names(pd_ai) %in% c("$10K - $30K","$30K - $50K"), ]
low_income_df <- as.data.frame(low_income)
colnames(low_income_df) <- c("Annual Income", "Product Department", "Frequency")
# Vẽ biểu đồ
ggplot(low_income_df, aes(x = `Annual Income`, y = Frequency, fill = `Product Department`)) +
  geom_col(position = position_dodge()) +
  facet_wrap(~`Product Department`) +
  labs(title = 'Figure 11: Product Department by Low Income', 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óm có thu nhập trung bình:

# Phân loại nhóm có thu nhập trung bình
mid_income <- pd_ai[row.names(pd_ai) %in% c("$50K - $70K","$70K - $90K", "$90K - $110K"), ]
mid_income_df <- as.data.frame(mid_income)
colnames(mid_income_df) <- c("Annual Income", "Product Department", "Frequency")
# Vẽ biểu đồ
ggplot(mid_income_df, aes(x = `Annual Income`, y = Frequency, fill = `Product Department`)) +
  geom_col(position = position_dodge()) +
  facet_wrap(~`Product Department`) +
  labs(title = 'Figure 12: Product Department by Middle Income', 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óm có thu nhập cao:

# Phân loại nhóm có thu nhập cao
high_income <- pd_ai[row.names(pd_ai) %in% c("$110K - $130K","$130K - $150K","$150K +"), ]
high_income_df <- as.data.frame(high_income)
colnames(high_income_df) <- c("Annual Income", "Product Department", "Frequency")
# Vẽ biểu đồ
ggplot(high_income_df, aes(x = `Annual Income`, y = Frequency, fill = `Product Department`)) +
  geom_col(position = position_dodge()) +
  facet_wrap(~`Product Department`) +
  labs(title = 'Figure 13: Product Department by High Income', 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"))

4.1.3 Nhận xét

Kết quả cho thấy ở nhóm có thu nhập thấp, trung bình hay cao thì đều tiêu thụ số lượng lớn nông sản tươi (Produce), thực phẩm đông lạnh (Frozen Food), thức ăn vặt (Snack Foods), đồ gia dụng (Household), đồ làm bánh (Banking Good), đồ uống (Beverages), chế phẩm từ sữa (Dairy), những danh mục khác thì mua rất ít.

4.1.4 Kiểm định Chi-Bình phương

Tệp khách hàng có thu nhập thấp

chisq.test(low_income)
## 
##  Pearson's Chi-squared test
## 
## data:  low_income
## X-squared = 30.633, df = 21, p-value = 0.07998

Tệp khách hàng có thu nhập trung bình

chisq.test(mid_income)
## Warning in chisq.test(mid_income): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  mid_income
## X-squared = 54.535, df = 42, p-value = 0.093

Tệp khách hàng có thu nhập cao

chisq.test(high_income)
## Warning in chisq.test(high_income): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  high_income
## X-squared = 42.133, df = 42, p-value = 0.4652

Đặt giả thuyết

\[ \left\{ \begin{array}{ll} H_0: & \text{Không có mối quan hệ giữa hai biến phân loại } \\ H_1: & \text{Có tồn tại mối quan hệ giữa hai biến phân loại } \end{array} \right. \]

  • Đối với tệp khách hàng có thu nhập thấp, kết quả kiểm định cho thấy giá trị p_value = 0.07998 > 5% nhưng nhỏ hơn 10%. Điều này cho thấy có bằng chứng để bác bỏ \(H_0\), tuy nhiên bằng chứng này không đủ mạnh. Vì thế ta chấp nhận \(H_0\), nghĩa là không có mối quan hệ nào giữa các loại hàng hóa và các khách hàng có thu nhập thấp.

  • Tương tự với tệp khách có thu nhập trung bình. Ta thấy p_value = 0.093 > 5% nhưng vẫn nhỏ hơn 10%. Vì thế ta chấp nhận \(H_0\), nghĩa là không có mối quan hệ nào giữa các loại hàng hóa và các khách hàng có thu nhập trung bình.

  • Đối với tệp khách hàng có thu nhập cao. Ta thấy p_value = 0.4652 > 5%, vì thế ta có thể bác bỏ \(H_0\), nghĩa là có tồn tại mối quan hệ giữa việc mua hàng hóa đối với tệp khách hàng có thu nhập cao.

4.2 Gender và ProductFamily

4.1.1 Bảng tần suất chéo

gender_pd <- table(st$ProductDepartment,st$Gender)
df_gender_pd <- as.data.frame(gender_pd)
colnames(df_gender_pd) <- c("Product Department", "Gender", "Frequency")
df_gender_pd

4.1.2 Trực quan hóa dữ liệu

ggplot(df_gender_pd, aes(x = `Product Department`, y = Frequency, fill = Gender)) +
  geom_col(position = position_dodge()) +
  labs(title = 'Figure 14: Gender distribution by Product Department', x = 'Product Department', y = 'Frequency') +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal() +
    theme(axis.text.x = element_text(angle = 90, hjust = 1),
        plot.title = element_text(hjust = 0.5, face = "bold"))

4.1.3 Nhận xét

Kết quả cho thấy các sản phẩm được mua bởi nam và nữ không có quá nhiều sự chênh lệch. Các loại sản phẩm được mua bởi nam nhiều hơn bao gồm Baking Goods, Dairy, Household, Produce, Starchy Food. Còn lại được mua nhiều hơn bởi nữ.

4.1.4 Kiểm định Chi-Bình phương

chisq.test(gender_pd)
## 
##  Pearson's Chi-squared test
## 
## data:  gender_pd
## X-squared = 33.586, df = 21, p-value = 0.04011

Đặt giả thuyết:

\[ \left\{ \begin{array}{ll} H_0: & \text{Không có mối quan hệ giữa hai biến phân loại } \\ H_1: & \text{Có tồn tại mối quan hệ giữa hai biến phân loại } \end{array} \right. \]

Ta thấy kết quả kiểm định cho ra giá trị p_value = 0.04011 < 5%, nghĩa là ta bác bỏ \(H_0\). Vậy mối quan hệ giữa loại sản phẩm mà khách hàng mua và giới tính là có liên quan đến nhau.

4.3 MaritalStatus và ProductFamily

4.1.1 Bảng tần suất chéo

ms_pf <- table(st$ProductFamily,st$MaritalStatus)
df_ms_pf <- as.data.frame(ms_pf)
colnames(df_ms_pf) <- c("Product Family","Marital Status", "Frequency")
df_ms_pf

4.1.2 Trực quan hóa dữ liệu

ggplot(df_ms_pf, aes(x = `Marital Status`, y = Frequency, fill = `Product Family`)) +
  geom_col(position = position_dodge()) +
  labs(title = 'Figure 13: Product Family distribution by Marital Status', x = 'Marital Status', y = 'Frequency') +
  scale_fill_brewer(palette = "Set3") +
  theme_minimal() +
    theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

4.1.3 Nhận xét

Tình trạng hôn nhân và nhóm sản phẩm khách hàng mua dường như không có nhiều chênh lệch.

4.1.4 Kiểm định Chi-Bình phương

chisq.test(ms_pf)
## 
##  Pearson's Chi-squared test
## 
## data:  ms_pf
## X-squared = 1.1617, df = 2, p-value = 0.5594

Đặt giả thuyết:

\[ \left\{ \begin{array}{ll} H_0: & \text{Không có mối quan hệ giữa hai biến phân loại } \\ H_1: & \text{Có tồn tại mối quan hệ giữa hai biến phân loại } \end{array} \right. \]

Kết quả kiểm định cho thấy rằng giá trị p_value = 0.5594 > 5%, điều này cho thấy không đủ cơ sở để bác bỏ \(H_0\), nghĩa là tình trạng hôn nhân và nhóm sản phẩm mua vào hoàn toàn không có mối liên hệ nào.

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==