1 TÌM HIểU VÀ CHUẨN BỊ DỮ LIỆU

1.1 Đọc và làm quen với dữ liệu

Bộ dữ liệu này là phiên bản rút gọn từ tập dữ liệu Bank Marketing, được trích xuất từ một chiến dịch tiếp thị qua điện thoại của một ngân hàng tại Bồ Đào Nha. Mục tiêu ban đầu là dự đoán khả năng khách hàng đăng ký gửi tiền có kỳ hạn. Trong bản rút gọn này, chỉ giữ lại 8 biến đầu vào có tính mô tả và liên quan cao.

  • Số dòng (quan sát): 4521
  • Số cột (biến): 8
# Đọc thư viện cần thiết
library(xlsx)
## Warning: package 'xlsx' was built under R version 4.4.3
# Đọc dữ liệu từ file Excel
dataDT <- read.xlsx("D:/PTDLDT/data.xlsx", sheetIndex = 1, header = TRUE)

# Loại bỏ các dòng chứa NA (nếu có)
dataDT <- na.omit(dataDT)

# Kiểm tra cấu trúc dữ liệu
str(dataDT)
## 'data.frame':    4521 obs. of  8 variables:
##  $ age      : num  30 33 35 30 59 35 36 39 41 43 ...
##  $ job      : chr  "unemployed" "services" "management" "management" ...
##  $ marital  : chr  "married" "married" "single" "married" ...
##  $ education: chr  "primary" "secondary" "tertiary" "tertiary" ...
##  $ default  : chr  "no" "no" "no" "no" ...
##  $ housing  : chr  "no" "yes" "yes" "yes" ...
##  $ loan     : chr  "no" "yes" "no" "yes" ...
##  $ contact  : chr  "cellular" "cellular" "cellular" "unknown" ...
dataDT$job      <- as.factor(dataDT$job)
dataDT$marital   <- as.factor(dataDT$marital)
dataDT$education <- as.factor(dataDT$education)
dataDT$default   <- as.factor(dataDT$default)
dataDT$housing   <- as.factor(dataDT$housing)
dataDT$loan      <- as.factor(dataDT$loan)
dataDT$contact   <- as.factor(dataDT$contact)

1.2 Danh sách các biến

Tên biến Kiểu dữ liệu Mô tả
Age Numeric Tuổi của khách hàng
Job Categorical (factor) Nghề nghiệp (unemployed, services, management, …)
Marital Categorical (factor) Tình trạng hôn nhân (single, married, divorced)
Education Categorical (factor) Trình độ học vấn (primary, secondary, tertiary, unknown)
Default Binary (yes/no) Khách hàng có nợ xấu không
Housing Binary (yes/no) Khách hàng có khoản vay mua nhà không
Loan Binary (yes/no) Khách hàng có khoản vay cá nhân không
Contact Categorical (factor) Hình thức liên hệ gần nhất (telephone hoặc cellular)

Tạo bộ dữ liệu chỉ có biến định tính

# Tạo bộ dữ liệu chỉ chứa các biến định tính 
data1 <- dataDT[, sapply(dataDT, is.factor)]

# Xem trước dữ liệu mới
str(data1)
## 'data.frame':    4521 obs. of  7 variables:
##  $ job      : Factor w/ 12 levels "admin.","blue-collar",..: 11 8 5 5 2 5 7 10 3 8 ...
##  $ marital  : Factor w/ 3 levels "divorced","married",..: 2 2 3 2 2 3 2 2 2 2 ...
##  $ education: Factor w/ 4 levels "primary","secondary",..: 1 2 3 3 2 3 3 2 3 1 ...
##  $ default  : Factor w/ 2 levels "no","yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ housing  : Factor w/ 2 levels "no","yes": 1 2 2 2 2 1 2 2 2 2 ...
##  $ loan     : Factor w/ 2 levels "no","yes": 1 2 1 2 1 1 1 1 1 2 ...
##  $ contact  : Factor w/ 3 levels "cellular","telephone",..: 1 1 1 3 3 1 1 1 3 1 ...
head(data1)

2 PHÂN TÍCH MÔ TẢ MỘT BIẾN ĐỊNH TÍNH

2.1 Biến Job

Lập bảng tần số và tần suất

#Bảng tần số
table(data1$job)
## 
##        admin.   blue-collar  entrepreneur     housemaid    management 
##           478           946           168           112           969 
##       retired self-employed      services       student    technician 
##           230           183           417            84           768 
##    unemployed       unknown 
##           128            38
#Bảng tần suất
table(data1$job)/sum(table(data1$job))
## 
##        admin.   blue-collar  entrepreneur     housemaid    management 
##    0.10572882    0.20924574    0.03715992    0.02477328    0.21433311 
##       retired self-employed      services       student    technician 
##    0.05087370    0.04047777    0.09223623    0.01857996    0.16987392 
##    unemployed       unknown 
##    0.02831232    0.00840522

Vẽ biểu đồ cột

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(ggplot2)

# Tạo bảng tần số cho biến job
freq1 <- table(data1$job)

# Chuyển thành data frame
job_freq <- as.data.frame(freq1)
colnames(job_freq) <- c("Job", "Count")

# Vẽ biểu đồ cột
ggplot(job_freq, aes(x = Job, y = Count)) +
  geom_col(fill = "#6495ED", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5, color = "black") +
  labs(title = "Tần số theo nghề nghiệp", x = "Nghề nghiệp", y = "Số lượng") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  theme(plot.title = element_text(hjust = 0.5)) 

Dựa vào bảng tần số và biểu đồ trên, ta có các nhận định sau:

  • Nghề nghiệp phổ biến nhất là management với 969 người, chiếm khoảng 21.4% tổng số mẫu.

  • Theo sau là blue-collar (946 người, ~20.9%) và technician (768 người, ~17.0%).

  • Các nhóm nghề ít phổ biến hơn gồm: student (84 người, ~1.9%) và unknown (38 người, ~0.8%).

  • Tổng cộng, ba nhóm nghề chiếm tỷ lệ cao nhất (management, blue-collar, technician) đã chiếm hơn 59% toàn bộ dữ liệu.

Kết luận:

Phân bố nghề nghiệp không đều, cho thấy các khách hàng trong dữ liệu chủ yếu đến từ các ngành quản lý, lao động phổ thông và kỹ thuật viên.

2.2 Biến Marital

Lập bảng tần số và tần suất

# Bảng tần số
table(data1$marital)
## 
## divorced  married   single 
##      528     2797     1196
# Bảng tần suất
prop.table(table(data1$marital))
## 
##  divorced   married    single 
## 0.1167883 0.6186684 0.2645432

Vẽ biểu đồ cột

# Biểu đồ cột
library(ggplot2)
freq_marital <- as.data.frame(table(data1$marital))
colnames(freq_marital) <- c("Marital", "Count")

ggplot(freq_marital, aes(x = Marital, y = Count)) +
  geom_col(fill = "#6495ED", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5) +
  labs(title = "Tần số theo tình trạng hôn nhân", x = "Tình trạng hôn nhân", y = "Số lượng") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số và tần suất của biến marital, ta có các nhận định sau:

  • Nhóm kết hôn (married) chiếm tỷ lệ cao nhất, với 2,797 người, tương ứng khoảng 61.9% tổng số mẫu. Đây là nhóm chiếm ưu thế vượt trội.

  • Nhóm độc thân (single) chiếm 1,196 người (~26.5%), đứng thứ hai về tần suất.

  • Nhóm ly hôn (divorced) chỉ chiếm 528 người (~11.7%), là nhóm có số lượng thấp nhất.

Kết luận:

Phân bố tình trạng hôn nhân trong tập dữ liệu này khá chênh lệch, với phần lớn khách hàng là người đã kết hôn. Điều này có thể phản ánh xu hướng hoặc cấu trúc dân số của khách hàng trong tập dữ liệu.

2.3 Biến Education

Lập bảng tần số và tần suất

table(data1$education)
## 
##   primary secondary  tertiary   unknown 
##       678      2306      1350       187
prop.table(table(data1$education))
## 
##    primary  secondary   tertiary    unknown 
## 0.14996682 0.51006415 0.29860650 0.04136253

Vẽ biểu đồ cột

freq_edu <- as.data.frame(table(data1$education))
colnames(freq_edu) <- c("Education", "Count")

ggplot(freq_edu, aes(x = Education, y = Count)) +
  geom_col(fill = "#FF9966", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5) +
  labs(title = "Tần số theo trình độ học vấn", x = "Trình độ", y = "Số lượng") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số và tần suất của biến education, ta có các nhận định sau:

  • Nhóm có trình độ học vấn secondary chiếm tỷ lệ cao nhất, với 2,306 người, tương ứng khoảng 51.0% tổng số mẫu. Đây là nhóm chiếm ưu thế vượt trội.

  • Nhóm có trình độ tertiary (đại học, sau đại học) có 1,350 người, chiếm khoảng 29.8%, đứng thứ hai về tần suất.

  • Nhóm primary có 678 người, tương ứng khoảng 15.0% tổng số mẫu.

  • Nhóm unknown (không rõ trình độ học vấn) chỉ chiếm 187 người, tương ứng 4.1%, là nhóm có số lượng thấp nhất.

Kết luận:

Phân bố trình độ học vấn trong tập dữ liệu cho thấy phần lớn khách hàng có trình độ học vấn trung học. Điều này có thể phản ánh cấu trúc trình độ học vấn phổ biến trong nhóm khách hàng được khảo sát, đồng thời là yếu tố cần xem xét trong các phân tích liên quan đến hành vi tiêu dùng hoặc khả năng tiếp cận dịch vụ.

2.4 Biến Default

Lập bảng tần số và tần suất

table(data1$default)
## 
##   no  yes 
## 4445   76
prop.table(table(data1$default))
## 
##         no        yes 
## 0.98318956 0.01681044

Vẽ biểu đồ cột

freq_default <- as.data.frame(table(data1$default))
colnames(freq_default) <- c("Default", "Count")

ggplot(freq_default, aes(x = Default, y = Count)) +
  geom_col(fill = "#F08080", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5) +
  labs(title = "Tần số nợ tín dụng xấu", x = "Default", y = "Số lượng") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số và tần suất của biến default, ta có các nhận định sau:

  • Nhóm không có nợ tín dụng xấu (no) chiếm số lượng lớn nhất với 4,445 người, tương ứng khoảng 98.4% tổng số mẫu. Đây là nhóm chiếm ưu thế gần như tuyệt đối.

  • Nhóm có nợ tín dụng xấu (yes) chỉ có 76 người, chiếm tỷ lệ rất nhỏ, khoảng 1.7%.

Kết luận:

Phân bố nợ tín dụng xấu trong tập dữ liệu cho thấy phần lớn khách hàng không có lịch sử nợ xấu. Điều này phản ánh chất lượng tín dụng tương đối tốt của nhóm khách hàng được khảo sát,

2.5 Biến Housing

Lập bảng tần số và tần suất

table(data1$housing)
## 
##   no  yes 
## 1962 2559
prop.table(table(data1$housing))
## 
##        no       yes 
## 0.4339748 0.5660252

Vẽ biểu đồ cột

freq_housing <- as.data.frame(table(data1$housing))
colnames(freq_housing) <- c("Housing", "Count")

ggplot(freq_housing, aes(x = Housing, y = Count)) +
  geom_col(fill = "#66CDAA", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5) +
  labs(title = "Tần số vay mua nhà", x = "Vay nhà", y = "Số lượng") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số và tần suất của biến housing, ta có các nhận định sau:

  • Nhóm có vay mua nhà (yes) chiếm tỷ lệ cao hơn với 2,559 người, tương ứng khoảng 56.6% tổng số mẫu. Đây là nhóm chiếm tỷ trọng lớn trong tập dữ liệu.

  • Nhóm không vay mua nhà (no) có 1,962 người, chiếm khoảng 43.4%.

Kết luận:

Phân bố dữ liệu cho thấy phần lớn khách hàng trong tập dữ liệu có khoản vay mua nhà. Điều này có thể phản ánh nhu cầu về nhà ở cũng như mức độ tiếp cận tín dụng mua bất động sản của khách hàng trong tập mẫu.

2.6 Biến Loan

Lập bảng tần số và tần suất

table(data1$loan)
## 
##   no  yes 
## 3830  691
prop.table(table(data1$loan))
## 
##        no       yes 
## 0.8471577 0.1528423

Vẽ biểu đồ cột

freq_loan <- as.data.frame(table(data1$loan))
colnames(freq_loan) <- c("Loan", "Count")

ggplot(freq_loan, aes(x = Loan, y = Count)) +
  geom_col(fill = "#9370DB", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5) +
  labs(title = "Tần số vay tiêu dùng", x = "Vay tiêu dùng", y = "Số lượng") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số và tần suất của biến loan, ta có các nhận định sau:

  • Nhóm không vay tiêu dùng (no) chiếm số lượng lớn vượt trội với 3.830 người, tương ứng khoảng 84.7% tổng số mẫu. Đây là nhóm chiếm ưu thế rõ rệt.

  • Nhóm có vay tiêu dùng (yes) chỉ có 691 người, chiếm khoảng 15.3%.

Kết luận:

Phân bố vay tiêu dùng cho thấy đa số khách hàng không sử dụng hình thức vay tiêu dùng, phản ánh sự thận trọng trong chi tiêu hoặc tiếp cận hạn chế với loại hình tín dụng này. Yếu tố này có thể đóng vai trò trong việc xác định mức độ tiêu dùng cá nhân và khả năng tiếp cận tín dụng tiêu dùng trong nghiên cứu hành vi tài chính.

2.7 Biến Contact

Lập bảng tần số và tần suất

table(data1$contact)
## 
##  cellular telephone   unknown 
##      2896       301      1324
prop.table(table(data1$contact))
## 
##   cellular  telephone    unknown 
## 0.64056625 0.06657819 0.29285556

Vẽ biểu đồ cột

freq_contact <- as.data.frame(table(data1$contact))
colnames(freq_contact) <- c("Contact", "Count")

ggplot(freq_contact, aes(x = Contact, y = Count)) +
  geom_col(fill = "#FFD700", color = "black") +
  geom_text(aes(label = Count), vjust = -0.5) +
  labs(title = "Tần số phương thức liên hệ", x = "Phương thức", y = "Số lượng") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số và tần suất của biến contact, ta có các nhận định sau:

Nhóm liên hệ qua điện thoại di động (cellular) chiếm số lượng lớn nhất với 2.896 người, tương ứng khoảng 64.1% tổng số mẫu. Đây là phương thức liên hệ phổ biến nhất.

Nhóm không rõ phương thức liên hệ (unknown) gồm 1.324 người, chiếm khoảng 29.3%.

Nhóm liên hệ qua điện thoại bàn (telephone) chỉ có 301 người, chiếm khoảng 6.7%.

Kết luận:

Phân bố phương thức liên hệ cho thấy điện thoại di động là kênh liên lạc chủ đạo trong dữ liệu, phản ánh xu hướng sử dụng công nghệ di động phổ biến trong xã hội hiện nay.

3 ƯỚC LƯỢNG KHOẢNG VÀ KIỂM ĐỊNH GIẢ THUYẾT CHO TỶ LỆ

3.1 Kiểm định hai phía

3.1.1 Biến Loan

3.1.1.1 Mục tiêu

Thực hiện kiểm định để xác định xem tỷ lệ khách hàng có vay tiêu dùng (loan = "yes") trong tập dữ liệu có khác biệt so với 20% hay không.

3.1.1.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có vay tiêu dùng
sumLoan <- sum(dataDT$loan == "yes")

# Tổng số khách hàng
sumTotal <- length(dataDT$loan)

# Tỷ lệ mẫu
p_hat <- sumLoan / sumTotal
p_hat
## [1] 0.1528423

3.1.1.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p = 0.20 (Tỷ lệ khách hàng có vay tiêu dùng bằng 20%)
  • H1: p ≠ 0.20 (Tỷ lệ khách hàng có vay tiêu dùng khác 20%)

Tiến hành kiểm định hai phía với mức ý nghĩa α = 0.05.

# Kiểm định tỷ lệ 1 mẫu với tỷ lệ giả định là 0.20
prop.test(x = sumLoan, n = sumTotal, p = 0.20, conf.level = 0.95, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumLoan out of sumTotal, null probability 0.2
## X-squared = 62.543, df = 1, p-value = 2.607e-15
## alternative hypothesis: true p is not equal to 0.2
## 95 percent confidence interval:
##  0.1425409 0.1637393
## sample estimates:
##         p 
## 0.1528423

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 62.543

  • Giá trị p (p-value): 2.607e-15 (tức là ≈ 0.000)

  • Khoảng tin cậy 95% cho tỷ lệ thực: [0.1425409, 0.1637393]

  • Ước lượng tỷ lệ từ mẫu (p̂): 0.1528423

Kết luận: Với mức ý nghĩa 5%, có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng có vay tiêu dùng khác 20%.

3.1.2 Biến Housing

3.1.2.1 Mục tiêu

Thực hiện kiểm định để xác định xem tỷ lệ khách hàng có vay mua nhà (Housing = “yes”) trong tập dữ liệu có khác biệt so với 60% hay không.

3.1.2.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có vay mua nhà
sumHousing <- sum(dataDT$housing == "yes")

# Tổng số khách hàng
nHousing <- length(dataDT$housing)

# Tỷ lệ mẫu
p_hat_housing <- sumHousing / nHousing
p_hat_housing
## [1] 0.5660252

3.1.2.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p = 0.60 (Tỷ lệ khách hàng vay mua nhà bằng 60%)
  • H1: p ≠ 0.60 (Tỷ lệ khách hàng vay mua nhà khác 60%)

Tiến hành kiểm định hai phía với mức ý nghĩa α = 0.05.

# Kiểm định tỷ lệ 1 mẫu với tỷ lệ giả định là 0.60
prop.test(x = sumHousing, n = nHousing, p = 0.60, conf.level = 0.95, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumHousing out of nHousing, null probability 0.6
## X-squared = 21.603, df = 1, p-value = 3.354e-06
## alternative hypothesis: true p is not equal to 0.6
## 95 percent confidence interval:
##  0.5514171 0.5805203
## sample estimates:
##         p 
## 0.5660252

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 21.603

  • Bậc tự do (df): 1

  • Giá trị p (p-value): 3.354e-06 ≈ 0.000003354

  • Khoảng tin cậy 95% cho tỷ lệ thực: [0.541471, 0.5805203]

  • Ước lượng tỷ lệ từ mẫu (p̂): 0.5660252

Kết luận: Với mức ý nghĩa 5%, có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng vay mua nhà khác 60%.

3.1.3 Biến Default

3.1.3.1 Mục tiêu

Thực hiện kiểm định để xác định xem tỷ lệ khách hàng có nợ quá hạn (Default = “yes”) trong tập dữ liệu có khác biệt so với 5% hay không.

3.1.3.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có nợ quá hạn
sumDefault <- sum(dataDT$default == "yes")

# Tổng số khách hàng
nDefault <- length(dataDT$default)

# Tỷ lệ mẫu
p_hat_default <- sumDefault / nDefault
p_hat_default
## [1] 0.01681044

3.1.3.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p = 0.05 (Tỷ lệ khách hàng nợ quá hạn bằng 5%)
  • H1: p ≠ 0.05 (Tỷ lệ khách hàng nợ quá hạn khác 5%)

Tiến hành kiểm định hai phía với mức ý nghĩa α = 0.05.

# Kiểm định tỷ lệ 1 mẫu với tỷ lệ giả định là 0.05
prop.test(x = sumDefault, n = nDefault, p = 0.05, conf.level = 0.95, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumDefault out of nDefault, null probability 0.05
## X-squared = 104.15, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.05
## 95 percent confidence interval:
##  0.01335392 0.02111144
## sample estimates:
##          p 
## 0.01681044

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 104.15

  • Bậc tự do (df): 1

  • Giá trị p (p-value): < 2.2e-16 (rất gần bằng 0)

  • Khoảng tin cậy 95% cho tỷ lệ thực: [0.01335392, 0.02111444]

  • Tỷ lệ ước lượng từ mẫu (p̂): 0.01681044 (≈ 1.68%)

Kết luận: Với mức ý nghĩa 5%, có đủ bằng chứng để kết luận rằng tỷ lệ khách hàng nợ quá hạn không bằng 5%.

3.1.4 Biến Education

3.1.4.1 Mục tiêu

Thực hiện kiểm định để xác định xem tỷ lệ khách hàng có trình độ tiểu học (Education = “primary”) trong tập dữ liệu có khác biệt so với 25% hay không.

3.1.4.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có trình độ đại học
sumEdu <- sum(dataDT$education == "primary")

# Tổng số khách hàng
nEdu <- length(dataDT$education)

# Tỷ lệ mẫu
p_hat_edu <- sumEdu / nEdu
p_hat_edu
## [1] 0.1499668

3.1.4.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p = 0.25 (Tỷ lệ khách hàng có trình độ tiểu học bằng 25%)
  • H1: p ≠ 0.25 (Tỷ lệ khách hàng có trình độ tiểu học khác 25%)

Tiến hành kiểm định hai phía với mức ý nghĩa α = 0.05.

# Kiểm định tỷ lệ 1 mẫu với tỷ lệ giả định là 0.25
prop.test(x = sumEdu, n = nEdu, p = 0.25, conf.level = 0.95, correct = TRUE)
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumEdu out of nEdu, null probability 0.25
## X-squared = 240.75, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.25
## 95 percent confidence interval:
##  0.1397493 0.1607850
## sample estimates:
##         p 
## 0.1499668

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 240.75

  • Bậc tự do (df): 1

  • Giá trị p (p-value): < 2.2e-16 (≈ 0 – cực kỳ nhỏ)

  • Khoảng tin cậy 95% cho tỷ lệ thực: [0.1397493, 0.1607850]

  • Tỷ lệ ước lượng từ mẫu (p̂): 0.1499668 (~14.99%)

Kết luận: Vì p-value < 0.05, nên có đủ cơ sở bác bỏ giả thuyết H₀. Vậy nên có đủ bằng chứng để khẳng định tỷ lệ khách hàng có trình độ tiểu học khác 25%.

3.2 Kiểm định một phía

3.2.1 Biến Loan

3.2.1.1 Mục tiêu

Xác định xem tỷ lệ khách hàng có vay tiêu dùng (loan = "yes") lớn hơn 20% hay không.

3.2.1.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có vay tiêu dùng
sumLoan <- sum(dataDT$loan == "yes")

# Tổng số khách hàng
sumTotal <- length(dataDT$loan)

# Tỷ lệ mẫu
p_hat <- sumLoan / sumTotal
p_hat
## [1] 0.1528423

3.2.1.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p ≤ 0.20 (Tỷ lệ khách hàng vay tiêu dùng không lớn hơn 20%)
  • H1: p > 0.20 (Tỷ lệ khách hàng vay tiêu dùng lớn hơn 20%)

Tiến hành kiểm định một phía với mức ý nghĩa α = 0.05.

# Kiểm định một phía: p > 0.20
prop.test(x = sumLoan, n = sumTotal, p = 0.20,
          conf.level = 0.95, correct = TRUE, alternative = "greater")
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumLoan out of sumTotal, null probability 0.2
## X-squared = 62.543, df = 1, p-value = 1
## alternative hypothesis: true p is greater than 0.2
## 95 percent confidence interval:
##  0.1441395 1.0000000
## sample estimates:
##         p 
## 0.1528423

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 62.543

  • Bậc tự do (df): 1

  • p-value: 1

  • Khoảng tin cậy 95% cho p (một phía): [0.1441395, 1.0000000]

  • Tỷ lệ mẫu ước lượng (p̂): 0.1528423 (~15.28%)

Kết luận: Với mức ý nghĩa 5%, không có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng vay tiêu dùng lớn hơn 20%.

3.2.2 Biến Housing

3.2.2.1 Mục tiêu

Xác định xem tỷ lệ khách hàng có vay mua nhà (housing = “yes”) nhỏ hơn 60% hay không.

3.2.2.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có vay mua nhà
sumHousing <- sum(dataDT$housing == "yes")

# Tổng số khách hàng
nHousing <- length(dataDT$housing)

# Tỷ lệ mẫu
p_hat_housing <- sumHousing / nHousing
p_hat_housing
## [1] 0.5660252

3.2.2.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p ≥ 0.60 (Tỷ lệ khách hàng vay mua nhà không nhỏ hơn 60%)
  • H1: p < 0.60 (Tỷ lệ khách hàng vay mua nhà nhỏ hơn 60%)

Tiến hành kiểm định một phía với mức ý nghĩa α = 0.05.

# Kiểm định một phía: p < 0.60
prop.test(x = sumHousing, n = nHousing, p = 0.60,
          conf.level = 0.95, correct = TRUE, alternative = "less")
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumHousing out of nHousing, null probability 0.6
## X-squared = 21.603, df = 1, p-value = 1.677e-06
## alternative hypothesis: true p is less than 0.6
## 95 percent confidence interval:
##  0.0000000 0.5782167
## sample estimates:
##         p 
## 0.5660252

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 21.603

  • Bậc tự do (df): 1

  • Giá trị p (p-value): 1.677e-06 (≈ 0.000001677 – rất nhỏ)

  • Tỷ lệ ước lượng từ mẫu (p̂): 0.5660252 (~56.60%)

  • Khoảng tin cậy 95% cho p (một phía): [0.0000000, 0.5782167]

Kết luận: Với mức ý nghĩa 5%, Có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng vay mua nhà nhỏ hơn 60%.

3.2.3 Biến Default

3.2.3.1 Mục tiêu

Xác định xem tỷ lệ khách hàng có nợ quá hạn (default = “yes”) lớn hơn 5% hay không.

3.2.3.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có nợ quá hạn
sumDefault <- sum(dataDT$default == "yes")

# Tổng số khách hàng
nDefault <- length(dataDT$default)

# Tỷ lệ mẫu
p_hat_default <- sumDefault / nDefault
p_hat_default
## [1] 0.01681044

3.2.3.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p ≤ 0.05 (Tỷ lệ nợ quá hạn không lớn hơn 5%)
  • H1: p > 0.05 (Tỷ lệ nợ quá hạn lớn hơn 5%)

Tiến hành kiểm định một phía với mức ý nghĩa α = 0.05.

# Kiểm định một phía: p > 0.05
prop.test(x = sumDefault, n = nDefault, p = 0.05,
          conf.level = 0.95, correct = TRUE, alternative = "greater")
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumDefault out of nDefault, null probability 0.05
## X-squared = 104.15, df = 1, p-value = 1
## alternative hypothesis: true p is greater than 0.05
## 95 percent confidence interval:
##  0.01384174 1.00000000
## sample estimates:
##          p 
## 0.01681044

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 104.15

  • Bậc tự do (df): 1

  • p-value: 1

  • Tỷ lệ ước lượng từ mẫu (p̂): 0.0168 (≈ 1.68%)

  • Khoảng tin cậy 95% cho p (một phía trên): [0.0138, 1.0000]

Kết luận: Vì p-value = 1 > 0.05, Không có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng nợ quá hạn lớn hơn 5%.

3.2.4 Biến Education

3.2.4.1 Mục tiêu

Xác định xem tỷ lệ khách hàng có trình độ tiểu học (education = “primary”) nhỏ hơn 25% hay không.

3.2.4.2 Tính toán tỷ lệ mẫu

# Số lượng khách hàng có trình độ đại học
sumEdu <- sum(dataDT$education == "primary")

# Tổng số khách hàng
nEdu <- length(dataDT$education)

# Tỷ lệ mẫu
p_hat_edu <- sumEdu / nEdu
p_hat_edu
## [1] 0.1499668

3.2.4.3 Kiểm định tỷ lệ 1 mẫu

Giả thuyết kiểm định

  • H0: p ≥ 0.25 (Tỷ lệ có trình độ tiểu học không nhỏ hơn 25%)
  • H1: p < 0.25 (Tỷ lệ có trình độ tiểu học nhỏ hơn 25%)

Tiến hành kiểm định một phía với mức ý nghĩa α = 0.05.

# Kiểm định một phía: p < 0.25
prop.test(x = sumEdu, n = nEdu, p = 0.25,
          conf.level = 0.95, correct = TRUE, alternative = "less")
## 
##  1-sample proportions test with continuity correction
## 
## data:  sumEdu out of nEdu, null probability 0.25
## X-squared = 240.75, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is less than 0.25
## 95 percent confidence interval:
##  0.0000000 0.1590235
## sample estimates:
##         p 
## 0.1499668

Kết quả kiểm định:

  • Giá trị thống kê (X-squared): 240.75

  • Bậc tự do (df): 1

  • p-value: < 2.2e-16 (rất nhỏ ≈ 0)

  • Tỷ lệ mẫu (p̂): 0.1499668 (~14.99%)

  • Khoảng tin cậy 95% (một phía trên): [0.0000000, 0.1590235]

Kết luận: Với mức ý nghĩa α = 0.05, do p-value = 2.2e-16 < 0.05, ta bác bỏ giả thuyết H₀.Có đủ bằng chứng thống kê để khẳng định rằng tỷ lệ khách hàng có trình độ tiểu học nhỏ hơn 25%.

4 PHÂN TÍCH MỐI QUAN HỆ GIỮA HAI BIẾN ĐỊNH TÍNH

4.1 Housing vs Loan

4.1.1 Mục tiêu

Việc có nhà hay không ảnh hưởng thế nào đến khả năng vay tiền.

Bảng tần số

table_housing_loan <- table(dataDT$housing, dataDT$loan)
table_housing_loan
##      
##         no  yes
##   no  1677  285
##   yes 2153  406

Vẽ biểu đồ

table_housing_loan <- table(dataDT$housing, dataDT$loan)

library(ggplot2)
ggplot(dataDT, aes(x = housing, fill = loan)) +
  geom_bar(position = "dodge") +
  labs(title = "Tình trạng nhà cửa và vay tiêu dùng",
       x = "Tình trạng nhà cửa", y = "Số lượng") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Dựa trên bảng tần số và biểu đồ, ta nhận thấy rằng:

  • Trong số những khách hàng không vay mua nhà, có 285 người vay tiêu dùng, chiếm khoảng 14,5%.

  • Trong khi đó, với nhóm khách hàng có vay mua nhà, có 406 người vay tiêu dùng, chiếm khoảng 15,9%.

Điều này cho thấy rằng tỷ lệ vay tiêu dùng ở nhóm có vay mua nhà cao hơn một chút so với nhóm không vay mua nhà. Biểu đồ cũng minh họa rõ sự chênh lệch nhỏ này khi cột màu xanh (vay tiêu dùng) ở nhóm “yes” (vay mua nhà) cao hơn so với nhóm “no”.

Tuy sự khác biệt là không quá lớn, nhưng nó có thể gợi ý rằng khách hàng vay mua nhà có xu hướng vay thêm tiêu dùng nhiều hơn. Để khẳng định chắc chắn mối quan hệ này có ý nghĩa thống kê hay không, ta cần thực hiện thêm kiểm định thống kê phù hợp

4.1.2 Tính Hiệu Hai Tỷ Lệ

prop_table <- prop.table(table_housing_loan, margin = 1)
prop_table
##      
##              no       yes
##   no  0.8547401 0.1452599
##   yes 0.8413443 0.1586557
diff_prop <- prop_table["yes", "yes"] - prop_table["no", "yes"]
diff_prop
## [1] 0.01339579

4.1.3 Tính Relative Risk (RR)

library(epitools)
rr_result <- riskratio(table_housing_loan)
rr_result$measure
##      risk ratio with 95% C.I.
##       estimate     lower    upper
##   no  1.000000        NA       NA
##   yes 1.092219 0.9499327 1.255819

Giải thích:

  • RR = 1.092 nghĩa là nhóm khách hàng có nhà có nguy cơ vay tiêu dùng cao hơn khoảng 9,2% so với nhóm không có nhà.

  • Nói cách khác, dù có sự chênh lệch nhẹ, ta không thể khẳng định chắc chắn rằng nhóm vay mua nhà có xu hướng vay tiêu dùng nhiều hơn so với nhóm còn lại.

Mặc dù khách hàng có nhà nhà có tỷ lệ vay tiêu dùng cao hơn một chút (RR > 1), nhưng sự khác biệt này chưa đủ để khẳng định có ý nghĩa thống kê. Để đưa ra kết luận chắc chắn, cần thêm dữ liệu hoặc kiểm định bổ sung như kiểm định chi bình phương.

4.1.4 Tính Odds Ratio (OR)

or_result <- oddsratio(table_housing_loan)
or_result$measure
##      odds ratio with 95% C.I.
##       estimate     lower    upper
##   no  1.000000        NA       NA
##   yes 1.109426 0.9417053 1.308516
or_result$conf.int
## NULL

Giải thích:

  • Giá trị Odds Ratio (OR) cho nhóm khách hàng có nhà là 1.109, tức là xác suất vay tiêu dùng của họ cao hơn khoảng 10,9% so với nhóm không có nhà.

4.1.5 Kiểm định Chi bình phương

Giả thuyết kiểm định

  • H0: housing và loan độc lập nhau.
  • H1: Có mối liên hệ giữa housing và loan.
chisq.test(table_housing_loan)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_housing_loan
## X-squared = 1.4374, df = 1, p-value = 0.2306

Kết quả kiểm định:

  • Giá trị thống kê Chi-squared = 1.4374

  • Bậc tự do (df) = 1

  • Giá trị p-value = 0.2306

Kết luận: Với p-value = 0.2306, lớn hơn mức ý nghĩa thường dùng là 0.05, ta không đủ bằng chứng để bác bỏ giả thuyết H₀.Nói cách khác, dữ liệu không cho thấy mối liên hệ có ý nghĩa thống kê giữa việc khách hàng vay mua nhà và việc họ vay tiêu dùng.

4.2 Education vs Job

4.2.1 Mục tiêu

Xác định xem trình độ học vấn (education) có liên quan đến nghề nghiệp (job) hay không.

4.2.2 Bảng tần số

table_edu_job <- table(dataDT$education, dataDT$job)
table_edu_job
##            
##             admin. blue-collar entrepreneur housemaid management retired
##   primary       17         369           26        57         39      80
##   secondary    393         524           58        28        116     105
##   tertiary      51          12           73        22        787      31
##   unknown       17          41           11         5         27      14
##            
##             self-employed services student technician unemployed unknown
##   primary              15       25       2         15         26       7
##   secondary            76      363      47        520         68       8
##   tertiary             88       16      19        211         32       8
##   unknown               4       13      16         22          2      15

4.2.3 Vẽ biểu đồ

library(ggplot2)

ggplot(dataDT, aes(x = education, fill = job)) +
  geom_bar(position = "dodge") +
  labs(title = "Phân phối nghề nghiệp theo trình độ học vấn",
       x = "Trình độ học vấn", y = "Số lượng") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5))

Dựa trên bảng tần số và biểu đồ phân phối nghề nghiệp theo trình độ học vấn, ta có thể rút ra các nhận xét sau:

  • Trình độ học vấn phổ biến nhất là “secondary” (trung học) với số lượng áp đảo ở hầu hết các nhóm nghề, đặc biệt là:

    • blue-collar (lao động chân tay) với 524 người.

    • technician (kỹ thuật viên) với 520 người.

    • services (dịch vụ) với 363 người.

  • Những người có trình độ “tertiary” (đại học hoặc cao hơn) chủ yếu làm các công việc:

    • management (quản lý): 787 người – nhóm nghề chiếm tỷ lệ cao nhất trong bậc học này.

    • technician: 211 người.

    • admin.: 51 người, ít hơn nhưng vẫn đáng kể.

  • Trình độ “primary” (tiểu học) tập trung nhiều nhất ở nhóm:

    • blue-collar: 369 người, phản ánh đặc điểm nghề nghiệp không yêu cầu trình độ học vấn cao.

    • services: 25 người, thấp hơn đáng kể.

  • Người có học vấn “unknown” phân bổ ít và không rõ ràng, phổ biến nhất là ở nhóm services và blue-collar, nhưng số lượng tương đối nhỏ.

Biểu đồ cho thấy mối quan hệ rõ ràng giữa trình độ học vấn và loại công việc. Trình độ học vấn càng cao (như tertiary), tỷ lệ làm các công việc chuyên môn cao (management, technician, admin.) càng nhiều. Trình độ học vấn thấp hơn (primary, secondary) thường gắn với các công việc lao động phổ thông hoặc kỹ thuật

Có sự phân hóa nghề nghiệp rõ rệt theo trình độ học vấn. Việc nâng cao trình độ học vấn có thể giúp cá nhân tiếp cận các công việc chuyên môn và quản lý với mức độ chuyên môn hóa cao hơn. không yêu cầu chuyên môn cao (blue-collar, services).

4.2.4 Kiểm định Chi bình phương

Giả thuyết kiểm định

  • H0: education và job độc lập nhau.
  • H1: Có mối liên hệ giữa education và job.
chisq.test(table_edu_job)
## Warning in chisq.test(table_edu_job): Chi-squared approximation may be
## incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  table_edu_job
## X-squared = 2840, df = 33, p-value < 2.2e-16

Kết quả kiểm định:

  • Giá trị Chi-squared = 2840

  • Bậc tự do (df) = 33

  • p-value < 2.2e-16

Kết luận: Với p-value < 0.05 ta bác bỏ giả thuyết H₀.Điều này có nghĩa là có mối liên hệ có ý nghĩa thống kê giữa trình độ học vấn và nghề nghiệp của khách hàng.

LS0tDQp0aXRsZTogIk5oaeG7h20gVuG7pSA0Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBlbmNvZGluZzogVVRGLTgNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogeWVzDQogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCi0tLQ0KDQo8c3R5bGU+DQovKiBJbiDEkeG6rW0gdG/DoG4gYuG7mSB0acOqdSDEkeG7gSAqLw0KaDEsIGgyLCBoMywgaDQsIGg1LCBoNiB7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KPC9zdHlsZT4NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KDQojICoqVMOMTSBISeG7g1UgVsOAIENIVeG6qE4gQuG7iiBE4buuIExJ4buGVSoqIA0KDQojIyAqKsSQ4buNYyB2w6AgbMOgbSBxdWVuIHbhu5tpIGThu68gbGnhu4d1KioNCg0KQuG7mSBk4buvIGxp4buHdSBuw6B5IGzDoCBwaGnDqm4gYuG6o24gcsO6dCBn4buNbiB04burIHThuq1wIGThu68gbGnhu4d1IEJhbmsgTWFya2V0aW5nLCDEkcaw4bujYyB0csOtY2ggeHXhuqV0IHThu6sgbeG7mXQgY2hp4bq/biBk4buLY2ggdGnhur9wIHRo4buLIHF1YSDEkWnhu4duIHRob+G6oWkgY+G7p2EgbeG7mXQgbmfDom4gaMOgbmcgdOG6oWkgQuG7kyDEkMOgbyBOaGEuIE3hu6VjIHRpw6p1IGJhbiDEkeG6p3UgbMOgIGThu7EgxJFvw6FuIGto4bqjIG7Eg25nIGtow6FjaCBow6BuZyDEkcSDbmcga8O9IGfhu61pIHRp4buBbiBjw7Mga+G7syBo4bqhbi4gVHJvbmcgYuG6o24gcsO6dCBn4buNbiBuw6B5LCBjaOG7iSBnaeG7ryBs4bqhaSA4IGJp4bq/biDEkeG6p3UgdsOgbyBjw7MgdMOtbmggbcO0IHThuqMgdsOgIGxpw6puIHF1YW4gY2FvLg0KDQotICoqU+G7kSBkw7JuZyAocXVhbiBzw6F0KToqKiA0NTIxDQotICoqU+G7kSBj4buZdCAoYmnhur9uKToqKiA4DQoNCmBgYHtyfQ0KIyDEkOG7jWMgdGjGsCB2aeG7h24gY+G6p24gdGhp4bq/dA0KbGlicmFyeSh4bHN4KQ0KDQojIMSQ4buNYyBk4buvIGxp4buHdSB04burIGZpbGUgRXhjZWwNCmRhdGFEVCA8LSByZWFkLnhsc3goIkQ6L1BURExEVC9kYXRhLnhsc3giLCBzaGVldEluZGV4ID0gMSwgaGVhZGVyID0gVFJVRSkNCg0KIyBMb+G6oWkgYuG7jyBjw6FjIGTDsm5nIGNo4bupYSBOQSAobuG6v3UgY8OzKQ0KZGF0YURUIDwtIG5hLm9taXQoZGF0YURUKQ0KDQojIEtp4buDbSB0cmEgY+G6pXUgdHLDumMgZOG7ryBsaeG7h3UNCnN0cihkYXRhRFQpDQoNCmRhdGFEVCRqb2IgICAgICA8LSBhcy5mYWN0b3IoZGF0YURUJGpvYikNCmRhdGFEVCRtYXJpdGFsICAgPC0gYXMuZmFjdG9yKGRhdGFEVCRtYXJpdGFsKQ0KZGF0YURUJGVkdWNhdGlvbiA8LSBhcy5mYWN0b3IoZGF0YURUJGVkdWNhdGlvbikNCmRhdGFEVCRkZWZhdWx0ICAgPC0gYXMuZmFjdG9yKGRhdGFEVCRkZWZhdWx0KQ0KZGF0YURUJGhvdXNpbmcgICA8LSBhcy5mYWN0b3IoZGF0YURUJGhvdXNpbmcpDQpkYXRhRFQkbG9hbiAgICAgIDwtIGFzLmZhY3RvcihkYXRhRFQkbG9hbikNCmRhdGFEVCRjb250YWN0ICAgPC0gYXMuZmFjdG9yKGRhdGFEVCRjb250YWN0KQ0KDQpgYGANCg0KIyMgKipEYW5oIHPDoWNoIGPDoWMgYmnhur9uKioNCg0KfCBUw6puIGJp4bq/biAgIHwgS2nhu4N1IGThu68gbGnhu4d1ICAgICAgIHwgTcO0IHThuqMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQp8IGBBZ2VgICAgICAgfCBOdW1lcmljICAgICAgICAgICAgfCBUdeG7lWkgY+G7p2Ega2jDoWNoIGjDoG5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IGBKb2JgICAgICAgfCBDYXRlZ29yaWNhbCAoZmFjdG9yKSB8IE5naOG7gSBuZ2hp4buHcCAodW5lbXBsb3llZCwgc2VydmljZXMsIG1hbmFnZW1lbnQsIC4uLikgICAgICAgICAgICAgICAgICB8DQp8IGBNYXJpdGFsYCAgfCBDYXRlZ29yaWNhbCAoZmFjdG9yKSB8IFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiAoc2luZ2xlLCBtYXJyaWVkLCBkaXZvcmNlZCkgICAgICAgICAgICAgICAgICAgICB8DQp8IGBFZHVjYXRpb25gfCBDYXRlZ29yaWNhbCAoZmFjdG9yKSB8IFRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiAocHJpbWFyeSwgc2Vjb25kYXJ5LCB0ZXJ0aWFyeSwgdW5rbm93bikgICAgICAgICAgICAgfA0KfCBgRGVmYXVsdGAgIHwgQmluYXJ5ICh5ZXMvbm8pICAgIHwgS2jDoWNoIGjDoG5nIGPDsyBu4bujIHjhuqV1IGtow7RuZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IGBIb3VzaW5nYCAgfCBCaW5hcnkgKHllcy9ubykgICAgfCBLaMOhY2ggaMOgbmcgY8OzIGtob+G6o24gdmF5IG11YSBuaMOgIGtow7RuZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBgTG9hbmAgICAgIHwgQmluYXJ5ICh5ZXMvbm8pICAgIHwgS2jDoWNoIGjDoG5nIGPDsyBraG/huqNuIHZheSBjw6EgbmjDom4ga2jDtG5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IGBDb250YWN0YCAgfCBDYXRlZ29yaWNhbCAoZmFjdG9yKSB8IEjDrG5oIHRo4bupYyBsacOqbiBo4buHIGfhuqduIG5o4bqldCAodGVsZXBob25lIGhv4bq3YyBjZWxsdWxhcikgICAgICAgICAgICAgICAgfA0KDQoNCioqVOG6oW8gYuG7mSBk4buvIGxp4buHdSBjaOG7iSBjw7MgYmnhur9uIMSR4buLbmggdMOtbmgqKg0KDQpgYGB7cn0NCiMgVOG6oW8gYuG7mSBk4buvIGxp4buHdSBjaOG7iSBjaOG7qWEgY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCANCmRhdGExIDwtIGRhdGFEVFssIHNhcHBseShkYXRhRFQsIGlzLmZhY3RvcildDQoNCiMgWGVtIHRyxrDhu5tjIGThu68gbGnhu4d1IG3hu5tpDQpzdHIoZGF0YTEpDQpoZWFkKGRhdGExKQ0KYGBgDQoNCg0KLS0tDQoNCiMgKipQSMOCTiBUw41DSCBNw5QgVOG6oiBN4buYVCBCSeG6vk4gxJDhu4pOSCBUw41OSCoqIA0KDQojIyAqKkJp4bq/biBKb2IqKg0KDQoqKkzhuq1wIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQqKg0KDQpgYGB7cn0NCiNC4bqjbmcgdOG6p24gc+G7kQ0KdGFibGUoZGF0YTEkam9iKQ0KI0LhuqNuZyB04bqnbiBzdeG6pXQNCnRhYmxlKGRhdGExJGpvYikvc3VtKHRhYmxlKGRhdGExJGpvYikpDQpgYGANCg0KKipW4bq9IGJp4buDdSDEkeG7kyBj4buZdCoqDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgVOG6oW8gYuG6o25nIHThuqduIHPhu5EgY2hvIGJp4bq/biBqb2INCmZyZXExIDwtIHRhYmxlKGRhdGExJGpvYikNCg0KIyBDaHV54buDbiB0aMOgbmggZGF0YSBmcmFtZQ0Kam9iX2ZyZXEgPC0gYXMuZGF0YS5mcmFtZShmcmVxMSkNCmNvbG5hbWVzKGpvYl9mcmVxKSA8LSBjKCJKb2IiLCAiQ291bnQiKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0DQpnZ3Bsb3Qoam9iX2ZyZXEsIGFlcyh4ID0gSm9iLCB5ID0gQ291bnQpKSArDQogIGdlb21fY29sKGZpbGwgPSAiIzY0OTVFRCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIlThuqduIHPhu5EgdGhlbyBuZ2jhu4EgbmdoaeG7h3AiLCB4ID0gIk5naOG7gSBuZ2hp4buHcCIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSANCmBgYA0KDQoqKkThu7FhIHbDoG8gYuG6o25nIHThuqduIHPhu5EgdsOgIGJp4buDdSDEkeG7kyB0csOqbiwgdGEgY8OzIGPDoWMgbmjhuq1uIMSR4buLbmggc2F1OioqDQoNCg0KLSBOZ2jhu4EgbmdoaeG7h3AgcGjhu5UgYmnhur9uIG5o4bqldCBsw6AgbWFuYWdlbWVudCB24bubaSA5NjkgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgMjEuNCUgdOG7lW5nIHPhu5EgbeG6q3UuDQoNCi0gVGhlbyBzYXUgbMOgIGJsdWUtY29sbGFyICg5NDYgbmfGsOG7nWksIH4yMC45JSkgdsOgIHRlY2huaWNpYW4gKDc2OCBuZ8aw4budaSwgfjE3LjAlKS4NCg0KLSBDw6FjIG5ow7NtIG5naOG7gSDDrXQgcGjhu5UgYmnhur9uIGjGoW4gZ+G7k206IHN0dWRlbnQgKDg0IG5nxrDhu51pLCB+MS45JSkgdsOgIHVua25vd24gKDM4IG5nxrDhu51pLCB+MC44JSkuDQoNCi0gVOG7lW5nIGPhu5luZywgYmEgbmjDs20gbmdo4buBIGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQgKG1hbmFnZW1lbnQsIGJsdWUtY29sbGFyLCB0ZWNobmljaWFuKSDEkcOjIGNoaeG6v20gaMahbiA1OSUgdG/DoG4gYuG7mSBk4buvIGxp4buHdS4NCg0KKipL4bq/dCBsdeG6rW46KioNCg0KUGjDom4gYuG7kSBuZ2jhu4EgbmdoaeG7h3Aga2jDtG5nIMSR4buBdSwgY2hvIHRo4bqleSBjw6FjIGtow6FjaCBow6BuZyB0cm9uZyBk4buvIGxp4buHdSBjaOG7pyB54bq/dSDEkeG6v24gdOG7qyBjw6FjIG5nw6BuaCBxdeG6o24gbMO9LCBsYW8gxJHhu5luZyBwaOG7lSB0aMO0bmcgdsOgIGvhu7kgdGh14bqtdCB2acOqbi4gDQoNCg0KDQoNCiMjICoqQmnhur9uIE1hcml0YWwqKg0KDQoqKkzhuq1wIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQqKg0KDQpgYGB7cn0NCiMgQuG6o25nIHThuqduIHPhu5ENCnRhYmxlKGRhdGExJG1hcml0YWwpDQojIELhuqNuZyB04bqnbiBzdeG6pXQNCnByb3AudGFibGUodGFibGUoZGF0YTEkbWFyaXRhbCkpDQpgYGANCg0KKipW4bq9IGJp4buDdSDEkeG7kyBj4buZdCoqDQoNCmBgYHtyfQ0KIyBCaeG7g3UgxJHhu5MgY+G7mXQNCmxpYnJhcnkoZ2dwbG90MikNCmZyZXFfbWFyaXRhbCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGExJG1hcml0YWwpKQ0KY29sbmFtZXMoZnJlcV9tYXJpdGFsKSA8LSBjKCJNYXJpdGFsIiwgIkNvdW50IikNCg0KZ2dwbG90KGZyZXFfbWFyaXRhbCwgYWVzKHggPSBNYXJpdGFsLCB5ID0gQ291bnQpKSArDQogIGdlb21fY29sKGZpbGwgPSAiIzY0OTVFRCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUpICsNCiAgbGFicyh0aXRsZSA9ICJU4bqnbiBz4buRIHRoZW8gdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIiwgeCA9ICJUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4iLCB5ID0gIlPhu5EgbMaw4bujbmciKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCioqROG7sWEgdsOgbyBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0IGPhu6dhIGJp4bq/biBtYXJpdGFsLCB0YSBjw7MgY8OhYyBuaOG6rW4gxJHhu4tuaCBzYXU6KioNCg0KLSBOaMOzbSBr4bq/dCBow7RuIChtYXJyaWVkKSBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0LCB24bubaSAyLDc5NyBuZ8aw4budaSwgdMawxqFuZyDhu6luZyBraG/huqNuZyA2MS45JSB04buVbmcgc+G7kSBt4bqrdS4gxJDDonkgbMOgIG5ow7NtIGNoaeG6v20gxrB1IHRo4bq/IHbGsOG7o3QgdHLhu5lpLg0KDQotIE5ow7NtIMSR4buZYyB0aMOibiAoc2luZ2xlKSBjaGnhur9tIDEsMTk2IG5nxrDhu51pICh+MjYuNSUpLCDEkeG7qW5nIHRo4bupIGhhaSB24buBIHThuqduIHN14bqldC4NCg0KLSBOaMOzbSBseSBow7RuIChkaXZvcmNlZCkgY2jhu4kgY2hp4bq/bSA1MjggbmfGsOG7nWkgKH4xMS43JSksIGzDoCBuaMOzbSBjw7Mgc+G7kSBsxrDhu6NuZyB0aOG6pXAgbmjhuqV0Lg0KDQoqKkvhur90IGx14bqtbjoqKg0KDQpQaMOibiBi4buRIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiB0cm9uZyB04bqtcCBk4buvIGxp4buHdSBuw6B5IGtow6EgY2jDqm5oIGzhu4djaCwgduG7m2kgcGjhuqduIGzhu5tuIGtow6FjaCBow6BuZyBsw6AgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuLiDEkGnhu4F1IG7DoHkgY8OzIHRo4buDIHBo4bqjbiDDoW5oIHh1IGjGsOG7m25nIGhv4bq3YyBj4bqldSB0csO6YyBkw6JuIHPhu5EgY+G7p2Ega2jDoWNoIGjDoG5nIHRyb25nIHThuq1wIGThu68gbGnhu4d1Lg0KDQoNCg0KIyMgKipCaeG6v24gRWR1Y2F0aW9uKioNCg0KKipM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0KioNCg0KYGBge3J9DQp0YWJsZShkYXRhMSRlZHVjYXRpb24pDQpwcm9wLnRhYmxlKHRhYmxlKGRhdGExJGVkdWNhdGlvbikpDQpgYGANCg0KKipW4bq9IGJp4buDdSDEkeG7kyBj4buZdCoqDQoNCmBgYHtyfQ0KZnJlcV9lZHUgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShkYXRhMSRlZHVjYXRpb24pKQ0KY29sbmFtZXMoZnJlcV9lZHUpIDwtIGMoIkVkdWNhdGlvbiIsICJDb3VudCIpDQoNCmdncGxvdChmcmVxX2VkdSwgYWVzKHggPSBFZHVjYXRpb24sIHkgPSBDb3VudCkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjRkY5OTY2IiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuNSkgKw0KICBsYWJzKHRpdGxlID0gIlThuqduIHPhu5EgdGhlbyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4iLCB4ID0gIlRyw6xuaCDEkeG7mSIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KDQoqKkThu7FhIHbDoG8gYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCBj4bunYSBiaeG6v24gZWR1Y2F0aW9uLCB0YSBjw7MgY8OhYyBuaOG6rW4gxJHhu4tuaCBzYXU6KioNCg0KLSBOaMOzbSBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHNlY29uZGFyeSBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0LCB24bubaSAyLDMwNiBuZ8aw4budaSwgdMawxqFuZyDhu6luZyBraG/huqNuZyA1MS4wJSB04buVbmcgc+G7kSBt4bqrdS4gxJDDonkgbMOgIG5ow7NtIGNoaeG6v20gxrB1IHRo4bq/IHbGsOG7o3QgdHLhu5lpLg0KDQotIE5ow7NtIGPDsyB0csOsbmggxJHhu5kgdGVydGlhcnkgKMSR4bqhaSBo4buNYywgc2F1IMSR4bqhaSBo4buNYykgY8OzIDEsMzUwIG5nxrDhu51pLCBjaGnhur9tIGtob+G6o25nIDI5LjglLCDEkeG7qW5nIHRo4bupIGhhaSB24buBIHThuqduIHN14bqldC4NCg0KLSBOaMOzbSBwcmltYXJ5IGPDsyA2NzggbmfGsOG7nWksIHTGsMahbmcg4bupbmcga2hv4bqjbmcgMTUuMCUgdOG7lW5nIHPhu5EgbeG6q3UuDQoNCi0gTmjDs20gdW5rbm93biAoa2jDtG5nIHLDtSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4pIGNo4buJIGNoaeG6v20gMTg3IG5nxrDhu51pLCB0xrDGoW5nIOG7qW5nIDQuMSUsIGzDoCBuaMOzbSBjw7Mgc+G7kSBsxrDhu6NuZyB0aOG6pXAgbmjhuqV0Lg0KDQoqKkvhur90IGx14bqtbjoqKg0KDQpQaMOibiBi4buRIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiB0cm9uZyB04bqtcCBk4buvIGxp4buHdSBjaG8gdGjhuqV5IHBo4bqnbiBs4bubbiBraMOhY2ggaMOgbmcgY8OzIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiB0cnVuZyBo4buNYy4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBwaOG6o24gw6FuaCBj4bqldSB0csO6YyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gcGjhu5UgYmnhur9uIHRyb25nIG5ow7NtIGtow6FjaCBow6BuZyDEkcaw4bujYyBraOG6o28gc8OhdCwgxJHhu5NuZyB0aOG7nWkgbMOgIHnhur91IHThu5EgY+G6p24geGVtIHjDqXQgdHJvbmcgY8OhYyBwaMOibiB0w61jaCBsacOqbiBxdWFuIMSR4bq/biBow6BuaCB2aSB0acOqdSBkw7luZyBob+G6t2Mga2jhuqMgbsSDbmcgdGnhur9wIGPhuq1uIGThu4tjaCB24bulLg0KDQojIyAqKkJp4bq/biBEZWZhdWx0KioNCg0KKipM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0KioNCg0KYGBge3J9DQp0YWJsZShkYXRhMSRkZWZhdWx0KQ0KcHJvcC50YWJsZSh0YWJsZShkYXRhMSRkZWZhdWx0KSkNCmBgYA0KDQoqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0KioNCg0KYGBge3J9DQpmcmVxX2RlZmF1bHQgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShkYXRhMSRkZWZhdWx0KSkNCmNvbG5hbWVzKGZyZXFfZGVmYXVsdCkgPC0gYygiRGVmYXVsdCIsICJDb3VudCIpDQoNCmdncGxvdChmcmVxX2RlZmF1bHQsIGFlcyh4ID0gRGVmYXVsdCwgeSA9IENvdW50KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiNGMDgwODAiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41KSArDQogIGxhYnModGl0bGUgPSAiVOG6p24gc+G7kSBu4bujIHTDrW4gZOG7pW5nIHjhuqV1IiwgeCA9ICJEZWZhdWx0IiwgeSA9ICJT4buRIGzGsOG7o25nIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCmBgYA0KDQoqKkThu7FhIHbDoG8gYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCBj4bunYSBiaeG6v24gZGVmYXVsdCwgdGEgY8OzIGPDoWMgbmjhuq1uIMSR4buLbmggc2F1OioqDQoNCi0gTmjDs20ga2jDtG5nIGPDsyBu4bujIHTDrW4gZOG7pW5nIHjhuqV1IChubykgY2hp4bq/bSBz4buRIGzGsOG7o25nIGzhu5tuIG5o4bqldCB24bubaSA0LDQ0NSBuZ8aw4budaSwgdMawxqFuZyDhu6luZyBraG/huqNuZyA5OC40JSB04buVbmcgc+G7kSBt4bqrdS4gxJDDonkgbMOgIG5ow7NtIGNoaeG6v20gxrB1IHRo4bq/IGfhuqduIG5oxrAgdHV54buHdCDEkeG7kWkuDQoNCi0gTmjDs20gY8OzIG7hu6MgdMOtbiBk4bulbmcgeOG6pXUgKHllcykgY2jhu4kgY8OzIDc2IG5nxrDhu51pLCBjaGnhur9tIHThu7cgbOG7hyBy4bqldCBuaOG7jywga2hv4bqjbmcgMS43JS4NCg0KKipL4bq/dCBsdeG6rW46KioNCg0KUGjDom4gYuG7kSBu4bujIHTDrW4gZOG7pW5nIHjhuqV1IHRyb25nIHThuq1wIGThu68gbGnhu4d1IGNobyB0aOG6pXkgcGjhuqduIGzhu5tuIGtow6FjaCBow6BuZyBraMO0bmcgY8OzIGzhu4tjaCBz4butIG7hu6MgeOG6pXUuIMSQaeG7gXUgbsOgeSBwaOG6o24gw6FuaCBjaOG6pXQgbMaw4bujbmcgdMOtbiBk4bulbmcgdMawxqFuZyDEkeG7kWkgdOG7kXQgY+G7p2EgbmjDs20ga2jDoWNoIGjDoG5nIMSRxrDhu6NjIGto4bqjbyBzw6F0LA0KDQoNCiMjICoqQmnhur9uIEhvdXNpbmcqKg0KDQoqKkzhuq1wIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQqKg0KDQpgYGB7cn0NCnRhYmxlKGRhdGExJGhvdXNpbmcpDQpwcm9wLnRhYmxlKHRhYmxlKGRhdGExJGhvdXNpbmcpKQ0KDQpgYGANCg0KKipW4bq9IGJp4buDdSDEkeG7kyBj4buZdCoqDQoNCmBgYHtyfQ0KZnJlcV9ob3VzaW5nIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YTEkaG91c2luZykpDQpjb2xuYW1lcyhmcmVxX2hvdXNpbmcpIDwtIGMoIkhvdXNpbmciLCAiQ291bnQiKQ0KDQpnZ3Bsb3QoZnJlcV9ob3VzaW5nLCBhZXMoeCA9IEhvdXNpbmcsIHkgPSBDb3VudCkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjNjZDREFBIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuNSkgKw0KICBsYWJzKHRpdGxlID0gIlThuqduIHPhu5EgdmF5IG11YSBuaMOgIiwgeCA9ICJWYXkgbmjDoCIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KKipE4buxYSB2w6BvIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIGhvdXNpbmcsIHRhIGPDsyBjw6FjIG5o4bqtbiDEkeG7i25oIHNhdToqKg0KDQotIE5ow7NtIGPDsyB2YXkgbXVhIG5ow6AgKHllcykgY2hp4bq/bSB04bu3IGzhu4cgY2FvIGjGoW4gduG7m2kgMiw1NTkgbmfGsOG7nWksIHTGsMahbmcg4bupbmcga2hv4bqjbmcgNTYuNiUgdOG7lW5nIHPhu5EgbeG6q3UuIMSQw6J5IGzDoCBuaMOzbSBjaGnhur9tIHThu7cgdHLhu41uZyBs4bubbiB0cm9uZyB04bqtcCBk4buvIGxp4buHdS4NCg0KLSBOaMOzbSBraMO0bmcgdmF5IG11YSBuaMOgIChubykgY8OzIDEsOTYyIG5nxrDhu51pLCBjaGnhur9tIGtob+G6o25nIDQzLjQlLg0KDQoqKkvhur90IGx14bqtbjoqKg0KDQpQaMOibiBi4buRIGThu68gbGnhu4d1IGNobyB0aOG6pXkgcGjhuqduIGzhu5tuIGtow6FjaCBow6BuZyB0cm9uZyB04bqtcCBk4buvIGxp4buHdSBjw7Mga2hv4bqjbiB2YXkgbXVhIG5ow6AuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgcGjhuqNuIMOhbmggbmh1IGPhuqd1IHbhu4EgbmjDoCDhu58gY8WpbmcgbmjGsCBt4bupYyDEkeG7mSB0aeG6v3AgY+G6rW4gdMOtbiBk4bulbmcgbXVhIGLhuqV0IMSR4buZbmcgc+G6o24gY+G7p2Ega2jDoWNoIGjDoG5nIHRyb25nIHThuq1wIG3huqt1Lg0KDQojIyAqKkJp4bq/biBMb2FuKioNCg0KKipM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0KioNCg0KYGBge3J9DQp0YWJsZShkYXRhMSRsb2FuKQ0KcHJvcC50YWJsZSh0YWJsZShkYXRhMSRsb2FuKSkNCmBgYA0KDQoqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0KioNCg0KYGBge3J9DQpmcmVxX2xvYW4gPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShkYXRhMSRsb2FuKSkNCmNvbG5hbWVzKGZyZXFfbG9hbikgPC0gYygiTG9hbiIsICJDb3VudCIpDQoNCmdncGxvdChmcmVxX2xvYW4sIGFlcyh4ID0gTG9hbiwgeSA9IENvdW50KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiM5MzcwREIiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41KSArDQogIGxhYnModGl0bGUgPSAiVOG6p24gc+G7kSB2YXkgdGnDqnUgZMO5bmciLCB4ID0gIlZheSB0acOqdSBkw7luZyIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KKipE4buxYSB2w6BvIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIGxvYW4sIHRhIGPDsyBjw6FjIG5o4bqtbiDEkeG7i25oIHNhdToqKg0KDQotIE5ow7NtIGtow7RuZyB2YXkgdGnDqnUgZMO5bmcgKG5vKSBjaGnhur9tIHPhu5EgbMaw4bujbmcgbOG7m24gdsaw4bujdCB0cuG7mWkgduG7m2kgMy44MzAgbmfGsOG7nWksIHTGsMahbmcg4bupbmcga2hv4bqjbmcgODQuNyUgdOG7lW5nIHPhu5EgbeG6q3UuIMSQw6J5IGzDoCBuaMOzbSBjaGnhur9tIMawdSB0aOG6vyByw7UgcuG7h3QuDQoNCi0gTmjDs20gY8OzIHZheSB0acOqdSBkw7luZyAoeWVzKSBjaOG7iSBjw7MgNjkxIG5nxrDhu51pLCBjaGnhur9tIGtob+G6o25nIDE1LjMlLg0KDQoqKkvhur90IGx14bqtbjoqKg0KDQpQaMOibiBi4buRIHZheSB0acOqdSBkw7luZyBjaG8gdGjhuqV5IMSRYSBz4buRIGtow6FjaCBow6BuZyBraMO0bmcgc+G7rSBk4bulbmcgaMOsbmggdGjhu6ljIHZheSB0acOqdSBkw7luZywgcGjhuqNuIMOhbmggc+G7sSB0aOG6rW4gdHLhu41uZyB0cm9uZyBjaGkgdGnDqnUgaG/hurdjIHRp4bq/cCBj4bqtbiBo4bqhbiBjaOG6vyB24bubaSBsb+G6oWkgaMOsbmggdMOtbiBk4bulbmcgbsOgeS4gWeG6v3UgdOG7kSBuw6B5IGPDsyB0aOG7gyDEkcOzbmcgdmFpIHRyw7IgdHJvbmcgdmnhu4djIHjDoWMgxJHhu4tuaCBt4bupYyDEkeG7mSB0acOqdSBkw7luZyBjw6EgbmjDom4gdsOgIGto4bqjIG7Eg25nIHRp4bq/cCBj4bqtbiB0w61uIGThu6VuZyB0acOqdSBkw7luZyB0cm9uZyBuZ2hpw6puIGPhu6l1IGjDoG5oIHZpIHTDoGkgY2jDrW5oLg0KDQojIyAqKkJp4bq/biBDb250YWN0KioNCg0KKipM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0KioNCg0KYGBge3J9DQp0YWJsZShkYXRhMSRjb250YWN0KQ0KcHJvcC50YWJsZSh0YWJsZShkYXRhMSRjb250YWN0KSkNCg0KYGBgDQoNCioqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQqKg0KDQpgYGB7cn0NCmZyZXFfY29udGFjdCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGExJGNvbnRhY3QpKQ0KY29sbmFtZXMoZnJlcV9jb250YWN0KSA8LSBjKCJDb250YWN0IiwgIkNvdW50IikNCg0KZ2dwbG90KGZyZXFfY29udGFjdCwgYWVzKHggPSBDb250YWN0LCB5ID0gQ291bnQpKSArDQogIGdlb21fY29sKGZpbGwgPSAiI0ZGRDcwMCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUpICsNCiAgbGFicyh0aXRsZSA9ICJU4bqnbiBz4buRIHBoxrDGoW5nIHRo4bupYyBsacOqbiBo4buHIiwgeCA9ICJQaMawxqFuZyB0aOG7qWMiLCB5ID0gIlPhu5EgbMaw4bujbmciKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCioqROG7sWEgdsOgbyBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0IGPhu6dhIGJp4bq/biBjb250YWN0LCB0YSBjw7MgY8OhYyBuaOG6rW4gxJHhu4tuaCBzYXU6KioNCg0KTmjDs20gbGnDqm4gaOG7hyBxdWEgxJFp4buHbiB0aG/huqFpIGRpIMSR4buZbmcgKGNlbGx1bGFyKSBjaGnhur9tIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0IHbhu5tpIDIuODk2IG5nxrDhu51pLCB0xrDGoW5nIOG7qW5nIGtob+G6o25nIDY0LjElIHThu5VuZyBz4buRIG3huqt1LiDEkMOieSBsw6AgcGjGsMahbmcgdGjhu6ljIGxpw6puIGjhu4cgcGjhu5UgYmnhur9uIG5o4bqldC4NCg0KTmjDs20ga2jDtG5nIHLDtSBwaMawxqFuZyB0aOG7qWMgbGnDqm4gaOG7hyAodW5rbm93bikgZ+G7k20gMS4zMjQgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgMjkuMyUuDQoNCk5ow7NtIGxpw6puIGjhu4cgcXVhIMSRaeG7h24gdGhv4bqhaSBiw6BuICh0ZWxlcGhvbmUpIGNo4buJIGPDsyAzMDEgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgNi43JS4NCg0KKipL4bq/dCBsdeG6rW46KioNCg0KUGjDom4gYuG7kSBwaMawxqFuZyB0aOG7qWMgbGnDqm4gaOG7hyBjaG8gdGjhuqV5IMSRaeG7h24gdGhv4bqhaSBkaSDEkeG7mW5nIGzDoCBrw6puaCBsacOqbiBs4bqhYyBjaOG7pyDEkeG6oW8gdHJvbmcgZOG7ryBsaeG7h3UsIHBo4bqjbiDDoW5oIHh1IGjGsOG7m25nIHPhu60gZOG7pW5nIGPDtG5nIG5naOG7hyBkaSDEkeG7mW5nIHBo4buVIGJp4bq/biB0cm9uZyB4w6MgaOG7mWkgaGnhu4duIG5heS4gDQoNCiMgKirGr+G7mkMgTMav4buiTkcgS0hP4bqiTkcgVsOAIEtJ4buCTSDEkOG7ik5IIEdJ4bqiIFRIVVnhur5UIENITyBU4bu2IEzhu4YqKiANCg0KIyMgKipLaeG7g20gxJHhu4tuaCBoYWkgcGjDrWEqKg0KDQojIyMgKipCaeG6v24gTG9hbioqDQoNCiMjIyMgKipN4bulYyB0acOqdSoqDQoNClRo4buxYyBoaeG7h24ga2nhu4NtIMSR4buLbmggxJHhu4MgeMOhYyDEkeG7i25oIHhlbSAqKnThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHZheSB0acOqdSBkw7luZyAoYGxvYW4gPSAieWVzImApKiogdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgY8OzIGtow6FjIGJp4buHdCBzbyB24bubaSAyMCUgaGF5IGtow7RuZy4NCg0KIyMjIyAqKlTDrW5oIHRvw6FuIHThu7cgbOG7hyBt4bqrdSoqDQoNCmBgYHtyfQ0KIyBT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBjw7MgdmF5IHRpw6p1IGTDuW5nDQpzdW1Mb2FuIDwtIHN1bShkYXRhRFQkbG9hbiA9PSAieWVzIikNCg0KIyBU4buVbmcgc+G7kSBraMOhY2ggaMOgbmcNCnN1bVRvdGFsIDwtIGxlbmd0aChkYXRhRFQkbG9hbikNCg0KIyBU4bu3IGzhu4cgbeG6q3UNCnBfaGF0IDwtIHN1bUxvYW4gLyBzdW1Ub3RhbA0KcF9oYXQNCmBgYA0KDQoNCiMjIyMgKipLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdSoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotICoqSDA6KiogcCA9IDAuMjAgKFThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHZheSB0acOqdSBkw7luZyBi4bqxbmcgMjAlKQ0KLSAqKkgxOioqIHAg4omgIDAuMjAgKFThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHZheSB0acOqdSBkw7luZyBraMOhYyAyMCUpDQoNClRp4bq/biBow6BuaCBraeG7g20gxJHhu4tuaCBoYWkgcGjDrWEgduG7m2kgbeG7qWMgw70gbmdoxKlhIM6xID0gMC4wNS4NCg0KYGBge3J9DQojIEtp4buDbSDEkeG7i25oIHThu7cgbOG7hyAxIG3huqt1IHbhu5tpIHThu7cgbOG7hyBnaeG6oyDEkeG7i25oIGzDoCAwLjIwDQpwcm9wLnRlc3QoeCA9IHN1bUxvYW4sIG4gPSBzdW1Ub3RhbCwgcCA9IDAuMjAsIGNvbmYubGV2ZWwgPSAwLjk1LCBjb3JyZWN0ID0gVFJVRSkNCmBgYA0KDQoqKkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOioqDQoNCi0gR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiAoWC1zcXVhcmVkKTogNjIuNTQzDQoNCi0gR2nDoSB0cuG7iyBwIChwLXZhbHVlKTogMi42MDdlLTE1ICh04bupYyBsw6Ag4omIIDAuMDAwKQ0KDQotIEtob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIHThu7cgbOG7hyB0aOG7sWM6IFswLjE0MjU0MDksIDAuMTYzNzM5M10NCg0KLSDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHThu6sgbeG6q3UgKHDMgik6IDAuMTUyODQyMw0KDQoqKkvhur90IGx14bqtbjoqKiBW4bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHZheSB0acOqdSBkw7luZyBraMOhYyAyMCUuDQoNCiMjIyAqKkJp4bq/biBIb3VzaW5nKioNCg0KIyMjIyAqKk3hu6VjIHRpw6p1KioNCg0KVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCDEkeG7gyB4w6FjIMSR4buLbmggeGVtIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHZheSBtdWEgbmjDoCAoSG91c2luZyA9ICJ5ZXMiKSB0cm9uZyB04bqtcCBk4buvIGxp4buHdSBjw7Mga2jDoWMgYmnhu4d0IHNvIHbhu5tpIDYwJSBoYXkga2jDtG5nLg0KDQojIyMjICoqVMOtbmggdG/DoW4gdOG7tyBs4buHIG3huqt1KioNCg0KYGBge3J9DQojIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGPDsyB2YXkgbXVhIG5ow6ANCnN1bUhvdXNpbmcgPC0gc3VtKGRhdGFEVCRob3VzaW5nID09ICJ5ZXMiKQ0KDQojIFThu5VuZyBz4buRIGtow6FjaCBow6BuZw0KbkhvdXNpbmcgPC0gbGVuZ3RoKGRhdGFEVCRob3VzaW5nKQ0KDQojIFThu7cgbOG7hyBt4bqrdQ0KcF9oYXRfaG91c2luZyA8LSBzdW1Ib3VzaW5nIC8gbkhvdXNpbmcNCnBfaGF0X2hvdXNpbmcNCmBgYA0KDQoNCiMjIyMgKipLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdSoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotICoqSDA6KiogcCA9IDAuNjAgKFThu7cgbOG7hyBraMOhY2ggaMOgbmcgdmF5IG11YSBuaMOgIGLhurFuZyA2MCUpDQotICoqSDE6KiogcCDiiaAgMC42MCAoVOG7tyBs4buHIGtow6FjaCBow6BuZyB2YXkgbXVhIG5ow6Aga2jDoWMgNjAlKQ0KDQpUaeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggaGFpIHBow61hIHbhu5tpIG3hu6ljIMO9IG5naMSpYSDOsSA9IDAuMDUuDQoNCmBgYHtyfQ0KIyBLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdSB24bubaSB04bu3IGzhu4cgZ2nhuqMgxJHhu4tuaCBsw6AgMC42MA0KcHJvcC50ZXN0KHggPSBzdW1Ib3VzaW5nLCBuID0gbkhvdXNpbmcsIHAgPSAwLjYwLCBjb25mLmxldmVsID0gMC45NSwgY29ycmVjdCA9IFRSVUUpDQpgYGANCg0KKipL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaDoqKg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogKFgtc3F1YXJlZCk6IDIxLjYwMw0KDQotIELhuq1jIHThu7EgZG8gKGRmKTogMQ0KDQotIEdpw6EgdHLhu4sgcCAocC12YWx1ZSk6IDMuMzU0ZS0wNiDiiYggMC4wMDAwMDMzNTQNCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgdGjhu7FjOiBbMC41NDE0NzEsIDAuNTgwNTIwM10NCg0KLSDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHThu6sgbeG6q3UgKHDMgik6IDAuNTY2MDI1Mg0KDQoqKkvhur90IGx14bqtbjoqKiBW4bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgdmF5IG11YSBuaMOgIGtow6FjIDYwJS4NCg0KIyMjICoqQmnhur9uIERlZmF1bHQqKg0KDQojIyMjICoqTeG7pWMgdGnDqnUqKg0KDQpUaOG7sWMgaGnhu4duIGtp4buDbSDEkeG7i25oIMSR4buDIHjDoWMgxJHhu4tuaCB4ZW0gdOG7tyBs4buHIGtow6FjaCBow6BuZyBjw7MgbuG7oyBxdcOhIGjhuqFuIChEZWZhdWx0ID0gInllcyIpIHRyb25nIHThuq1wIGThu68gbGnhu4d1IGPDsyBraMOhYyBiaeG7h3Qgc28gduG7m2kgNSUgaGF5IGtow7RuZy4NCg0KIyMjIyAqKlTDrW5oIHRvw6FuIHThu7cgbOG7hyBt4bqrdSoqDQoNCmBgYHtyfQ0KIyBT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyBjw7MgbuG7oyBxdcOhIGjhuqFuDQpzdW1EZWZhdWx0IDwtIHN1bShkYXRhRFQkZGVmYXVsdCA9PSAieWVzIikNCg0KIyBU4buVbmcgc+G7kSBraMOhY2ggaMOgbmcNCm5EZWZhdWx0IDwtIGxlbmd0aChkYXRhRFQkZGVmYXVsdCkNCg0KIyBU4bu3IGzhu4cgbeG6q3UNCnBfaGF0X2RlZmF1bHQgPC0gc3VtRGVmYXVsdCAvIG5EZWZhdWx0DQpwX2hhdF9kZWZhdWx0DQpgYGANCg0KDQojIyMjICoqS2nhu4NtIMSR4buLbmggdOG7tyBs4buHIDEgbeG6q3UqKg0KDQoqKkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oKioNCg0KLSAqKkgwOioqIHAgPSAwLjA1IChU4bu3IGzhu4cga2jDoWNoIGjDoG5nIG7hu6MgcXXDoSBo4bqhbiBi4bqxbmcgNSUpDQotICoqSDE6KiogcCDiiaAgMC4wNSAoVOG7tyBs4buHIGtow6FjaCBow6BuZyBu4bujIHF1w6EgaOG6oW4ga2jDoWMgNSUpDQoNClRp4bq/biBow6BuaCBraeG7g20gxJHhu4tuaCBoYWkgcGjDrWEgduG7m2kgbeG7qWMgw70gbmdoxKlhIM6xID0gMC4wNS4NCg0KYGBge3J9DQojIEtp4buDbSDEkeG7i25oIHThu7cgbOG7hyAxIG3huqt1IHbhu5tpIHThu7cgbOG7hyBnaeG6oyDEkeG7i25oIGzDoCAwLjA1DQpwcm9wLnRlc3QoeCA9IHN1bURlZmF1bHQsIG4gPSBuRGVmYXVsdCwgcCA9IDAuMDUsIGNvbmYubGV2ZWwgPSAwLjk1LCBjb3JyZWN0ID0gVFJVRSkNCmBgYA0KDQoqKkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOioqDQoNCi0gR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiAoWC1zcXVhcmVkKTogMTA0LjE1DQoNCi0gQuG6rWMgdOG7sSBkbyAoZGYpOiAxDQoNCi0gR2nDoSB0cuG7iyBwIChwLXZhbHVlKTogPCAyLjJlLTE2IChy4bqldCBn4bqnbiBi4bqxbmcgMCkNCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgdGjhu7FjOiBbMC4wMTMzNTM5MiwgMC4wMjExMTQ0NF0NCg0KLSBU4bu3IGzhu4cgxrDhu5tjIGzGsOG7o25nIHThu6sgbeG6q3UgKHDMgik6IDAuMDE2ODEwNDQgKOKJiCAxLjY4JSkNCg0KKipL4bq/dCBsdeG6rW46KiogVuG7m2kgbeG7qWMgw70gbmdoxKlhIDUlLCBjw7MgxJHhu6cgYuG6sW5nIGNo4bupbmcgxJHhu4Mga+G6v3QgbHXhuq1uIHLhurFuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG7hu6MgcXXDoSBo4bqhbiBraMO0bmcgYuG6sW5nIDUlLg0KDQoNCiMjIyAqKkJp4bq/biBFZHVjYXRpb24qKg0KDQojIyMjICoqTeG7pWMgdGnDqnUqKg0KDQpUaOG7sWMgaGnhu4duIGtp4buDbSDEkeG7i25oIMSR4buDIHjDoWMgxJHhu4tuaCB4ZW0gdOG7tyBs4buHIGtow6FjaCBow6BuZyBjw7MgdHLDrG5oIMSR4buZIHRp4buDdSBo4buNYyAoRWR1Y2F0aW9uID0gInByaW1hcnkiKSB0cm9uZyB04bqtcCBk4buvIGxp4buHdSBjw7Mga2jDoWMgYmnhu4d0IHNvIHbhu5tpIDI1JSBoYXkga2jDtG5nLg0KDQojIyMjICoqVMOtbmggdG/DoW4gdOG7tyBs4buHIG3huqt1KioNCg0KYGBge3J9DQojIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgxJHhuqFpIGjhu41jDQpzdW1FZHUgPC0gc3VtKGRhdGFEVCRlZHVjYXRpb24gPT0gInByaW1hcnkiKQ0KDQojIFThu5VuZyBz4buRIGtow6FjaCBow6BuZw0KbkVkdSA8LSBsZW5ndGgoZGF0YURUJGVkdWNhdGlvbikNCg0KIyBU4bu3IGzhu4cgbeG6q3UNCnBfaGF0X2VkdSA8LSBzdW1FZHUgLyBuRWR1DQpwX2hhdF9lZHUNCmBgYA0KDQoNCiMjIyMgKipLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdSoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotICoqSDA6KiogcCA9IDAuMjUgKFThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHRyw6xuaCDEkeG7mSB0aeG7g3UgaOG7jWMgYuG6sW5nIDI1JSkNCi0gKipIMToqKiBwIOKJoCAwLjI1IChU4bu3IGzhu4cga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgdGnhu4N1IGjhu41jIGtow6FjIDI1JSkNCg0KVGnhur9uIGjDoG5oIGtp4buDbSDEkeG7i25oIGhhaSBwaMOtYSB24bubaSBt4bupYyDDvSBuZ2jEqWEgzrEgPSAwLjA1Lg0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmggdOG7tyBs4buHIDEgbeG6q3UgduG7m2kgdOG7tyBs4buHIGdp4bqjIMSR4buLbmggbMOgIDAuMjUNCnByb3AudGVzdCh4ID0gc3VtRWR1LCBuID0gbkVkdSwgcCA9IDAuMjUsIGNvbmYubGV2ZWwgPSAwLjk1LCBjb3JyZWN0ID0gVFJVRSkNCmBgYA0KDQoqKkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOioqDQoNCi0gR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiAoWC1zcXVhcmVkKTogMjQwLjc1DQoNCi0gQuG6rWMgdOG7sSBkbyAoZGYpOiAxDQoNCi0gR2nDoSB0cuG7iyBwIChwLXZhbHVlKTogPCAyLjJlLTE2ICjiiYggMCDigJMgY+G7sWMga+G7syBuaOG7jykNCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgdGjhu7FjOiBbMC4xMzk3NDkzLCAwLjE2MDc4NTBdDQoNCi0gVOG7tyBs4buHIMaw4bubYyBsxrDhu6NuZyB04burIG3huqt1IChwzIIpOiAwLjE0OTk2NjggKH4xNC45OSUpDQoNCioqS+G6v3QgbHXhuq1uOioqIFbDrCBwLXZhbHVlIDwgMC4wNSwgbsOqbiBjw7MgxJHhu6cgY8ahIHPhu58gYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuIFbhuq15IG7Dqm4gY8OzIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGto4bqzbmcgxJHhu4tuaCB04bu3IGzhu4cga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgdGnhu4N1IGjhu41jIGtow6FjIDI1JS4NCg0KIyMgKipLaeG7g20gxJHhu4tuaCBt4buZdCBwaMOtYSoqDQoNCiMjIyAqKkJp4bq/biBMb2FuKioNCg0KIyMjIyAqKk3hu6VjIHRpw6p1KioNCg0KWMOhYyDEkeG7i25oIHhlbSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIGPDsyB2YXkgdGnDqnUgZMO5bmcgKGBsb2FuID0gInllcyJgKSBs4bubbiBoxqFuIDIwJSBoYXkga2jDtG5nLg0KDQojIyMjICoqVMOtbmggdG/DoW4gdOG7tyBs4buHIG3huqt1KioNCg0KYGBge3J9DQojIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGPDsyB2YXkgdGnDqnUgZMO5bmcNCnN1bUxvYW4gPC0gc3VtKGRhdGFEVCRsb2FuID09ICJ5ZXMiKQ0KDQojIFThu5VuZyBz4buRIGtow6FjaCBow6BuZw0Kc3VtVG90YWwgPC0gbGVuZ3RoKGRhdGFEVCRsb2FuKQ0KDQojIFThu7cgbOG7hyBt4bqrdQ0KcF9oYXQgPC0gc3VtTG9hbiAvIHN1bVRvdGFsDQpwX2hhdA0KYGBgDQoNCg0KIyMjIyAqKktp4buDbSDEkeG7i25oIHThu7cgbOG7hyAxIG3huqt1KioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaCoqDQoNCi0gKipIMDoqKiBwIOKJpCAwLjIwIChU4bu3IGzhu4cga2jDoWNoIGjDoG5nIHZheSB0acOqdSBkw7luZyBraMO0bmcgbOG7m24gaMahbiAyMCUpDQotICoqSDE6KiogcCA+IDAuMjAgKFThu7cgbOG7hyBraMOhY2ggaMOgbmcgdmF5IHRpw6p1IGTDuW5nIGzhu5tuIGjGoW4gMjAlKQ0KDQpUaeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggbeG7mXQgcGjDrWEgduG7m2kgbeG7qWMgw70gbmdoxKlhIM6xID0gMC4wNS4NCg0KYGBge3J9DQojIEtp4buDbSDEkeG7i25oIG3hu5l0IHBow61hOiBwID4gMC4yMA0KcHJvcC50ZXN0KHggPSBzdW1Mb2FuLCBuID0gc3VtVG90YWwsIHAgPSAwLjIwLA0KICAgICAgICAgIGNvbmYubGV2ZWwgPSAwLjk1LCBjb3JyZWN0ID0gVFJVRSwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIpDQpgYGANCg0KKipL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaDoqKg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogKFgtc3F1YXJlZCk6IDYyLjU0Mw0KDQotIELhuq1jIHThu7EgZG8gKGRmKTogMQ0KDQotIHAtdmFsdWU6IDENCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyBwICht4buZdCBwaMOtYSk6IFswLjE0NDEzOTUsIDEuMDAwMDAwMF0NCg0KLSBU4bu3IGzhu4cgbeG6q3UgxrDhu5tjIGzGsOG7o25nIChwzIIpOiAwLjE1Mjg0MjMgKH4xNS4yOCUpDQoNCioqS+G6v3QgbHXhuq1uOioqDQpW4bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIGtow7RuZyBjw7MgxJHhu6cgYuG6sW5nIGNo4bupbmcgdGjhu5FuZyBrw6ogxJHhu4Mga+G6v3QgbHXhuq1uIHLhurFuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHZheSB0acOqdSBkw7luZyBs4bubbiBoxqFuIDIwJS4NCg0KIyMjICoqQmnhur9uIEhvdXNpbmcqKg0KDQojIyMjICoqTeG7pWMgdGnDqnUqKg0KDQpYw6FjIMSR4buLbmggeGVtIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHZheSBtdWEgbmjDoCAoaG91c2luZyA9ICJ5ZXMiKSBuaOG7jyBoxqFuIDYwJSBoYXkga2jDtG5nLg0KDQojIyMjICoqVMOtbmggdG/DoW4gdOG7tyBs4buHIG3huqt1KioNCg0KYGBge3J9DQojIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGPDsyB2YXkgbXVhIG5ow6ANCnN1bUhvdXNpbmcgPC0gc3VtKGRhdGFEVCRob3VzaW5nID09ICJ5ZXMiKQ0KDQojIFThu5VuZyBz4buRIGtow6FjaCBow6BuZw0KbkhvdXNpbmcgPC0gbGVuZ3RoKGRhdGFEVCRob3VzaW5nKQ0KDQojIFThu7cgbOG7hyBt4bqrdQ0KcF9oYXRfaG91c2luZyA8LSBzdW1Ib3VzaW5nIC8gbkhvdXNpbmcNCnBfaGF0X2hvdXNpbmcNCmBgYA0KDQoNCiMjIyMgKipLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdSoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotICoqSDA6KiogcCDiiaUgMC42MCAoVOG7tyBs4buHIGtow6FjaCBow6BuZyB2YXkgbXVhIG5ow6Aga2jDtG5nIG5o4buPIGjGoW4gNjAlKQ0KLSAqKkgxOioqIHAgPCAwLjYwIChU4bu3IGzhu4cga2jDoWNoIGjDoG5nIHZheSBtdWEgbmjDoCBuaOG7jyBoxqFuIDYwJSkNCg0KVGnhur9uIGjDoG5oIGtp4buDbSDEkeG7i25oIG3hu5l0IHBow61hIHbhu5tpIG3hu6ljIMO9IG5naMSpYSDOsSA9IDAuMDUuDQoNCmBgYHtyfQ0KIyBLaeG7g20gxJHhu4tuaCBt4buZdCBwaMOtYTogcCA8IDAuNjANCnByb3AudGVzdCh4ID0gc3VtSG91c2luZywgbiA9IG5Ib3VzaW5nLCBwID0gMC42MCwNCiAgICAgICAgICBjb25mLmxldmVsID0gMC45NSwgY29ycmVjdCA9IFRSVUUsIGFsdGVybmF0aXZlID0gImxlc3MiKQ0KYGBgDQoNCioqS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmg6KioNCg0KLSBHacOhIHRy4buLIHRo4buRbmcga8OqIChYLXNxdWFyZWQpOiAyMS42MDMNCg0KLSBC4bqtYyB04buxIGRvIChkZik6IDENCg0KLSBHacOhIHRy4buLIHAgKHAtdmFsdWUpOiAxLjY3N2UtMDYgKOKJiCAwLjAwMDAwMTY3NyDigJMgcuG6pXQgbmjhu48pDQoNCi0gVOG7tyBs4buHIMaw4bubYyBsxrDhu6NuZyB04burIG3huqt1IChwzIIpOiAwLjU2NjAyNTIgKH41Ni42MCUpDQoNCi0gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gcCAobeG7mXQgcGjDrWEpOiBbMC4wMDAwMDAwLCAwLjU3ODIxNjddDQoNCkvhur90IGx14bqtbjogVuG7m2kgbeG7qWMgw70gbmdoxKlhIDUlLCBDw7MgxJHhu6cgYuG6sW5nIGNo4bupbmcgdGjhu5FuZyBrw6ogxJHhu4Mga+G6v3QgbHXhuq1uIHLhurFuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHZheSBtdWEgbmjDoCBuaOG7jyBoxqFuIDYwJS4NCg0KIyMjICoqQmnhur9uIERlZmF1bHQqKg0KDQojIyMjICoqTeG7pWMgdGnDqnUqKg0KDQpYw6FjIMSR4buLbmggeGVtIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIG7hu6MgcXXDoSBo4bqhbiAoZGVmYXVsdCA9ICJ5ZXMiKSBs4bubbiBoxqFuIDUlIGhheSBraMO0bmcuDQoNCiMjIyMgKipUw61uaCB0b8OhbiB04bu3IGzhu4cgbeG6q3UqKg0KDQpgYGB7cn0NCiMgU+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgY8OzIG7hu6MgcXXDoSBo4bqhbg0Kc3VtRGVmYXVsdCA8LSBzdW0oZGF0YURUJGRlZmF1bHQgPT0gInllcyIpDQoNCiMgVOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nDQpuRGVmYXVsdCA8LSBsZW5ndGgoZGF0YURUJGRlZmF1bHQpDQoNCiMgVOG7tyBs4buHIG3huqt1DQpwX2hhdF9kZWZhdWx0IDwtIHN1bURlZmF1bHQgLyBuRGVmYXVsdA0KcF9oYXRfZGVmYXVsdA0KYGBgDQoNCg0KIyMjIyAqKktp4buDbSDEkeG7i25oIHThu7cgbOG7hyAxIG3huqt1KioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaCoqDQoNCi0gKipIMDoqKiBwIOKJpCAwLjA1IChU4bu3IGzhu4cgbuG7oyBxdcOhIGjhuqFuIGtow7RuZyBs4bubbiBoxqFuIDUlKQ0KLSAqKkgxOioqIHAgPiAwLjA1IChU4bu3IGzhu4cgbuG7oyBxdcOhIGjhuqFuIGzhu5tuIGjGoW4gNSUpDQoNClRp4bq/biBow6BuaCBraeG7g20gxJHhu4tuaCBt4buZdCBwaMOtYSB24bubaSBt4bupYyDDvSBuZ2jEqWEgzrEgPSAwLjA1Lg0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmggbeG7mXQgcGjDrWE6IHAgPiAwLjA1DQpwcm9wLnRlc3QoeCA9IHN1bURlZmF1bHQsIG4gPSBuRGVmYXVsdCwgcCA9IDAuMDUsDQogICAgICAgICAgY29uZi5sZXZlbCA9IDAuOTUsIGNvcnJlY3QgPSBUUlVFLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikNCmBgYA0KDQoqKkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOioqDQoNCi0gR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiAoWC1zcXVhcmVkKTogMTA0LjE1DQoNCi0gQuG6rWMgdOG7sSBkbyAoZGYpOiAxDQoNCi0gcC12YWx1ZTogMQ0KDQotIFThu7cgbOG7hyDGsOG7m2MgbMaw4bujbmcgdOG7qyBt4bqrdSAocMyCKTogMC4wMTY4ICjiiYggMS42OCUpDQoNCi0gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gcCAobeG7mXQgcGjDrWEgdHLDqm4pOiBbMC4wMTM4LCAxLjAwMDBdDQoNCg0KS+G6v3QgbHXhuq1uOiBWw6wgcC12YWx1ZSA9IDEgPiAwLjA1LCBLaMO0bmcgY8OzIMSR4bunIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIMSR4buDIGvhur90IGx14bqtbiBy4bqxbmcgdOG7tyBs4buHIGtow6FjaCBow6BuZyBu4bujIHF1w6EgaOG6oW4gbOG7m24gaMahbiA1JS4gDQoNCg0KIyMjICoqQmnhur9uIEVkdWNhdGlvbioqDQoNCiMjIyMgKipN4bulYyB0acOqdSoqDQoNCljDoWMgxJHhu4tuaCB4ZW0gdOG7tyBs4buHIGtow6FjaCBow6BuZyBjw7MgdHLDrG5oIMSR4buZIHRp4buDdSBo4buNYyAoZWR1Y2F0aW9uID0gInByaW1hcnkiKSBuaOG7jyBoxqFuIDI1JSBoYXkga2jDtG5nLg0KDQojIyMjICoqVMOtbmggdG/DoW4gdOG7tyBs4buHIG3huqt1KioNCg0KYGBge3J9DQojIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgxJHhuqFpIGjhu41jDQpzdW1FZHUgPC0gc3VtKGRhdGFEVCRlZHVjYXRpb24gPT0gInByaW1hcnkiKQ0KDQojIFThu5VuZyBz4buRIGtow6FjaCBow6BuZw0KbkVkdSA8LSBsZW5ndGgoZGF0YURUJGVkdWNhdGlvbikNCg0KIyBU4bu3IGzhu4cgbeG6q3UNCnBfaGF0X2VkdSA8LSBzdW1FZHUgLyBuRWR1DQpwX2hhdF9lZHUNCmBgYA0KDQoNCiMjIyMgKipLaeG7g20gxJHhu4tuaCB04bu3IGzhu4cgMSBt4bqrdSoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotICoqSDA6KiogcCDiiaUgMC4yNSAoVOG7tyBs4buHIGPDsyB0csOsbmggxJHhu5kgdGnhu4N1IGjhu41jIGtow7RuZyBuaOG7jyBoxqFuIDI1JSkNCi0gKipIMToqKiBwIDwgMC4yNSAoVOG7tyBs4buHIGPDsyB0csOsbmggxJHhu5kgdGnhu4N1IGjhu41jIG5o4buPIGjGoW4gMjUlKQ0KDQpUaeG6v24gaMOgbmgga2nhu4NtIMSR4buLbmggbeG7mXQgcGjDrWEgduG7m2kgbeG7qWMgw70gbmdoxKlhIM6xID0gMC4wNS4NCg0KYGBge3J9DQojIEtp4buDbSDEkeG7i25oIG3hu5l0IHBow61hOiBwIDwgMC4yNQ0KcHJvcC50ZXN0KHggPSBzdW1FZHUsIG4gPSBuRWR1LCBwID0gMC4yNSwNCiAgICAgICAgICBjb25mLmxldmVsID0gMC45NSwgY29ycmVjdCA9IFRSVUUsIGFsdGVybmF0aXZlID0gImxlc3MiKQ0KYGBgDQoNCioqS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmg6KioNCg0KLSBHacOhIHRy4buLIHRo4buRbmcga8OqIChYLXNxdWFyZWQpOiAyNDAuNzUNCg0KLSBC4bqtYyB04buxIGRvIChkZik6IDENCg0KLSBwLXZhbHVlOiA8IDIuMmUtMTYgKHLhuqV0IG5o4buPIOKJiCAwKQ0KDQotIFThu7cgbOG7hyBt4bqrdSAocMyCKTogMC4xNDk5NjY4ICh+MTQuOTklKQ0KDQotIEtob+G6o25nIHRpbiBj4bqteSA5NSUgKG3hu5l0IHBow61hIHRyw6puKTogWzAuMDAwMDAwMCwgMC4xNTkwMjM1XQ0KDQoqKkvhur90IGx14bqtbjoqKiBW4bubaSBt4bupYyDDvSBuZ2jEqWEgzrEgPSAwLjA1LCBkbyBwLXZhbHVlID0gMi4yZS0xNiA8IDAuMDUsIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALkPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBraOG6s25nIMSR4buLbmggcuG6sW5nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgY8OzIHRyw6xuaCDEkeG7mSB0aeG7g3UgaOG7jWMgbmjhu48gaMahbiAyNSUuDQoNCg0KDQojICoqUEjDgk4gVMONQ0ggTeG7kEkgUVVBTiBI4buGIEdJ4buuQSBIQUkgQknhur5OIMSQ4buKTkggVMONTkgqKiANCg0KIyMgKipIb3VzaW5nIHZzIExvYW4qKg0KDQojIyMgKipN4bulYyB0acOqdSoqDQoNClZp4buHYyBjw7MgbmjDoCBoYXkga2jDtG5nIOG6o25oIGjGsOG7n25nIHRo4bq/IG7DoG8gxJHhur9uIGto4bqjIG7Eg25nIHZheSB0aeG7gW4uDQoNCg0KKipC4bqjbmcgdOG6p24gc+G7kSoqDQoNCmBgYHtyfQ0KdGFibGVfaG91c2luZ19sb2FuIDwtIHRhYmxlKGRhdGFEVCRob3VzaW5nLCBkYXRhRFQkbG9hbikNCnRhYmxlX2hvdXNpbmdfbG9hbg0KYGBgDQoNCioqVuG6vSBiaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCnRhYmxlX2hvdXNpbmdfbG9hbiA8LSB0YWJsZShkYXRhRFQkaG91c2luZywgZGF0YURUJGxvYW4pDQoNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkYXRhRFQsIGFlcyh4ID0gaG91c2luZywgZmlsbCA9IGxvYW4pKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIlTDrG5oIHRy4bqhbmcgbmjDoCBj4butYSB2w6AgdmF5IHRpw6p1IGTDuW5nIiwNCiAgICAgICB4ID0gIlTDrG5oIHRy4bqhbmcgbmjDoCBj4butYSIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KDQoqKkThu7FhIHRyw6puIGLhuqNuZyB04bqnbiBz4buRIHbDoCBiaeG7g3UgxJHhu5MsIHRhIG5o4bqtbiB0aOG6pXkgcuG6sW5nOioqDQoNCi0gVHJvbmcgc+G7kSBuaOG7r25nIGtow6FjaCBow6BuZyBraMO0bmcgdmF5IG11YSBuaMOgLCBjw7MgMjg1IG5nxrDhu51pIHZheSB0acOqdSBkw7luZywgY2hp4bq/bSBraG/huqNuZyAxNCw1JS4NCg0KLSBUcm9uZyBraGkgxJHDsywgduG7m2kgbmjDs20ga2jDoWNoIGjDoG5nIGPDsyB2YXkgbXVhIG5ow6AsIGPDsyA0MDYgbmfGsOG7nWkgdmF5IHRpw6p1IGTDuW5nLCBjaGnhur9tIGtob+G6o25nIDE1LDklLg0KDQrEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBy4bqxbmcgdOG7tyBs4buHIHZheSB0acOqdSBkw7luZyDhu58gbmjDs20gY8OzIHZheSBtdWEgbmjDoCBjYW8gaMahbiBt4buZdCBjaMO6dCBzbyB24bubaSBuaMOzbSBraMO0bmcgdmF5IG11YSBuaMOgLiBCaeG7g3UgxJHhu5MgY8WpbmcgbWluaCBo4buNYSByw7Ugc+G7sSBjaMOqbmggbOG7h2NoIG5o4buPIG7DoHkga2hpIGPhu5l0IG3DoHUgeGFuaCAodmF5IHRpw6p1IGTDuW5nKSDhu58gbmjDs20gInllcyIgKHZheSBtdWEgbmjDoCkgY2FvIGjGoW4gc28gduG7m2kgbmjDs20gIm5vIi4NCg0KVHV5IHPhu7Ega2jDoWMgYmnhu4d0IGzDoCBraMO0bmcgcXXDoSBs4bubbiwgbmjGsG5nIG7DsyBjw7MgdGjhu4MgZ+G7o2kgw70gcuG6sW5nIGtow6FjaCBow6BuZyB2YXkgbXVhIG5ow6AgY8OzIHh1IGjGsOG7m25nIHZheSB0aMOqbSB0acOqdSBkw7luZyBuaGnhu4F1IGjGoW4uIMSQ4buDIGto4bqzbmcgxJHhu4tuaCBjaOG6r2MgY2jhuq9uIG3hu5FpIHF1YW4gaOG7hyBuw6B5IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogaGF5IGtow7RuZywgdGEgY+G6p24gdGjhu7FjIGhp4buHbiB0aMOqbSBraeG7g20gxJHhu4tuaCB0aOG7kW5nIGvDqiBwaMO5IGjhu6NwDQoNCg0KIyMjICoqVMOtbmggSGnhu4d1IEhhaSBU4bu3IEzhu4cqKg0KDQpgYGB7cn0NCnByb3BfdGFibGUgPC0gcHJvcC50YWJsZSh0YWJsZV9ob3VzaW5nX2xvYW4sIG1hcmdpbiA9IDEpDQpwcm9wX3RhYmxlDQoNCmRpZmZfcHJvcCA8LSBwcm9wX3RhYmxlWyJ5ZXMiLCAieWVzIl0gLSBwcm9wX3RhYmxlWyJubyIsICJ5ZXMiXQ0KZGlmZl9wcm9wDQpgYGANCg0KIyMjICoqVMOtbmggUmVsYXRpdmUgUmlzayAoUlIpKioNCg0KYGBge3J9DQpsaWJyYXJ5KGVwaXRvb2xzKQ0KcnJfcmVzdWx0IDwtIHJpc2tyYXRpbyh0YWJsZV9ob3VzaW5nX2xvYW4pDQpycl9yZXN1bHQkbWVhc3VyZQ0KYGBgDQoNCioqR2nhuqNpIHRow61jaDoqKg0KDQotIFJSID0gMS4wOTIgbmdoxKlhIGzDoCBuaMOzbSBraMOhY2ggaMOgbmcgY8OzIG5ow6AgY8OzIG5ndXkgY8ahIHZheSB0acOqdSBkw7luZyBjYW8gaMahbiBraG/huqNuZyA5LDIlIHNvIHbhu5tpIG5ow7NtIGtow7RuZyBjw7MgbmjDoC4NCg0KLSBOw7NpIGPDoWNoIGtow6FjLCBkw7kgY8OzIHPhu7EgY2jDqm5oIGzhu4djaCBuaOG6uSwgdGEga2jDtG5nIHRo4buDIGto4bqzbmcgxJHhu4tuaCBjaOG6r2MgY2jhuq9uIHLhurFuZyBuaMOzbSB2YXkgbXVhIG5ow6AgY8OzIHh1IGjGsOG7m25nIHZheSB0acOqdSBkw7luZyBuaGnhu4F1IGjGoW4gc28gduG7m2kgbmjDs20gY8OybiBs4bqhaS4NCg0KDQpN4bq3YyBkw7kga2jDoWNoIGjDoG5nIGPDsyBuaMOgIG5ow6AgY8OzIHThu7cgbOG7hyB2YXkgdGnDqnUgZMO5bmcgY2FvIGjGoW4gbeG7mXQgY2jDunQgKFJSID4gMSksIG5oxrBuZyBz4buxIGtow6FjIGJp4buHdCBuw6B5IGNoxrBhIMSR4bunIMSR4buDIGto4bqzbmcgxJHhu4tuaCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLiDEkOG7gyDEkcawYSByYSBr4bq/dCBsdeG6rW4gY2jhuq9jIGNo4bqvbiwgY+G6p24gdGjDqm0gZOG7ryBsaeG7h3UgaG/hurdjIGtp4buDbSDEkeG7i25oIGLhu5Ugc3VuZyBuaMawIGtp4buDbSDEkeG7i25oIGNoaSBiw6xuaCBwaMawxqFuZy4NCg0KDQojIyMgKipUw61uaCBPZGRzIFJhdGlvIChPUikqKg0KDQpgYGB7cn0NCm9yX3Jlc3VsdCA8LSBvZGRzcmF0aW8odGFibGVfaG91c2luZ19sb2FuKQ0Kb3JfcmVzdWx0JG1lYXN1cmUNCm9yX3Jlc3VsdCRjb25mLmludA0KYGBgDQoNCioqR2nhuqNpIHRow61jaDoqKg0KDQotIEdpw6EgdHLhu4sgT2RkcyBSYXRpbyAoT1IpIGNobyBuaMOzbSBraMOhY2ggaMOgbmcgY8OzIG5ow6AgbMOgIDEuMTA5LCB04bupYyBsw6AgeMOhYyBzdeG6pXQgdmF5IHRpw6p1IGTDuW5nIGPhu6dhIGjhu40gY2FvIGjGoW4ga2hv4bqjbmcgMTAsOSUgc28gduG7m2kgbmjDs20ga2jDtG5nIGPDsyBuaMOgLg0KDQoNCiMjIyAqKktp4buDbSDEkeG7i25oIENoaSBiw6xuaCBwaMawxqFuZyoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotIEgwOiBob3VzaW5nIHbDoCBsb2FuIMSR4buZYyBs4bqtcCBuaGF1Lg0KLSBIMTogQ8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGhvdXNpbmcgdsOgIGxvYW4uDQoNCmBgYHtyfQ0KY2hpc3EudGVzdCh0YWJsZV9ob3VzaW5nX2xvYW4pDQpgYGANCg0KKipL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaDoqKg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpLXNxdWFyZWQgPSAxLjQzNzQNCg0KLSBC4bqtYyB04buxIGRvIChkZikgPSAxDQoNCi0gR2nDoSB0cuG7iyBwLXZhbHVlID0gMC4yMzA2DQoNCioqS+G6v3QgbHXhuq1uOioqIFbhu5tpIHAtdmFsdWUgPSAwLjIzMDYsIGzhu5tuIGjGoW4gbeG7qWMgw70gbmdoxKlhIHRoxrDhu51uZyBkw7luZyBsw6AgMC4wNSwgdGEga2jDtG5nIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALk7Ds2kgY8OhY2gga2jDoWMsIGThu68gbGnhu4d1IGtow7RuZyBjaG8gdGjhuqV5IG3hu5FpIGxpw6puIGjhu4cgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBnaeG7r2Egdmnhu4djIGtow6FjaCBow6BuZyB2YXkgbXVhIG5ow6AgdsOgIHZp4buHYyBo4buNIHZheSB0acOqdSBkw7luZy4NCg0KDQojIyAqKkVkdWNhdGlvbiB2cyBKb2IqKg0KDQojIyMgKipN4bulYyB0acOqdSoqDQoNCljDoWMgxJHhu4tuaCB4ZW0gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIChlZHVjYXRpb24pIGPDsyBsacOqbiBxdWFuIMSR4bq/biBuZ2jhu4EgbmdoaeG7h3AgKGpvYikgaGF5IGtow7RuZy4NCg0KDQojIyMgKipC4bqjbmcgdOG6p24gc+G7kSoqDQoNCmBgYHtyfQ0KdGFibGVfZWR1X2pvYiA8LSB0YWJsZShkYXRhRFQkZWR1Y2F0aW9uLCBkYXRhRFQkam9iKQ0KdGFibGVfZWR1X2pvYg0KYGBgDQoNCiMjIyAqKlbhur0gYmnhu4N1IMSR4buTKioNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdChkYXRhRFQsIGFlcyh4ID0gZWR1Y2F0aW9uLCBmaWxsID0gam9iKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBwaOG7kWkgbmdo4buBIG5naGnhu4dwIHRoZW8gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIiwNCiAgICAgICB4ID0gIlRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KKipE4buxYSB0csOqbiBi4bqjbmcgdOG6p24gc+G7kSB2w6AgYmnhu4N1IMSR4buTIHBow6JuIHBo4buRaSBuZ2jhu4EgbmdoaeG7h3AgdGhlbyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4sIHRhIGPDsyB0aOG7gyByw7p0IHJhIGPDoWMgbmjhuq1uIHjDqXQgc2F1OioqDQoNCi0gVHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHBo4buVIGJp4bq/biBuaOG6pXQgbMOgIOKAnHNlY29uZGFyeeKAnSAodHJ1bmcgaOG7jWMpIHbhu5tpIHPhu5EgbMaw4bujbmcgw6FwIMSR4bqjbyDhu58gaOG6p3UgaOG6v3QgY8OhYyBuaMOzbSBuZ2jhu4EsIMSR4bq3YyBiaeG7h3QgbMOgOg0KDQogIC0gYmx1ZS1jb2xsYXIgKGxhbyDEkeG7mW5nIGNow6JuIHRheSkgduG7m2kgNTI0IG5nxrDhu51pLg0KDQogIC0gdGVjaG5pY2lhbiAoa+G7uSB0aHXhuq10IHZpw6puKSB24bubaSA1MjAgbmfGsOG7nWkuDQoNCiAgLSBzZXJ2aWNlcyAoZOG7i2NoIHbhu6UpIHbhu5tpIDM2MyBuZ8aw4budaS4NCg0KLSBOaOG7r25nIG5nxrDhu51pIGPDsyB0csOsbmggxJHhu5kg4oCcdGVydGlhcnnigJ0gKMSR4bqhaSBo4buNYyBob+G6t2MgY2FvIGjGoW4pIGNo4bunIHnhur91IGzDoG0gY8OhYyBjw7RuZyB2aeG7h2M6DQoNCiAgLSBtYW5hZ2VtZW50IChxdeG6o24gbMO9KTogNzg3IG5nxrDhu51pIOKAkyBuaMOzbSBuZ2jhu4EgY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCB0cm9uZyBi4bqtYyBo4buNYyBuw6B5Lg0KDQogIC0gdGVjaG5pY2lhbjogMjExIG5nxrDhu51pLg0KDQogIC0gYWRtaW4uOiA1MSBuZ8aw4budaSwgw610IGjGoW4gbmjGsG5nIHbhuqtuIMSRw6FuZyBr4buDLg0KDQotIFRyw6xuaCDEkeG7mSDigJxwcmltYXJ54oCdICh0aeG7g3UgaOG7jWMpIHThuq1wIHRydW5nIG5oaeG7gXUgbmjhuqV0IOG7nyBuaMOzbToNCg0KICAtIGJsdWUtY29sbGFyOiAzNjkgbmfGsOG7nWksIHBo4bqjbiDDoW5oIMSR4bq3YyDEkWnhu4NtIG5naOG7gSBuZ2hp4buHcCBraMO0bmcgecOqdSBj4bqndSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gY2FvLg0KDQogIC0gc2VydmljZXM6IDI1IG5nxrDhu51pLCB0aOG6pXAgaMahbiDEkcOhbmcga+G7gy4NCg0KLSBOZ8aw4budaSBjw7MgaOG7jWMgduG6pW4g4oCcdW5rbm93buKAnSBwaMOibiBi4buVIMOtdCB2w6Aga2jDtG5nIHLDtSByw6BuZywgcGjhu5UgYmnhur9uIG5o4bqldCBsw6Ag4bufIG5ow7NtIHNlcnZpY2VzIHbDoCBibHVlLWNvbGxhciwgbmjGsG5nIHPhu5EgbMaw4bujbmcgdMawxqFuZyDEkeG7kWkgbmjhu48uDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IG3hu5FpIHF1YW4gaOG7hyByw7UgcsOgbmcgZ2nhu69hIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiB2w6AgbG/huqFpIGPDtG5nIHZp4buHYy4gVHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIGPDoG5nIGNhbyAobmjGsCB0ZXJ0aWFyeSksIHThu7cgbOG7hyBsw6BtIGPDoWMgY8O0bmcgdmnhu4djIGNodXnDqm4gbcO0biBjYW8gKG1hbmFnZW1lbnQsIHRlY2huaWNpYW4sIGFkbWluLikgY8Ogbmcgbmhp4buBdS4gVHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHRo4bqlcCBoxqFuIChwcmltYXJ5LCBzZWNvbmRhcnkpIHRoxrDhu51uZyBn4bqvbiB24bubaSBjw6FjIGPDtG5nIHZp4buHYyBsYW8gxJHhu5luZyBwaOG7lSB0aMO0bmcgaG/hurdjIGvhu7kgdGh14bqtdCANCg0KQ8OzIHPhu7EgcGjDom4gaMOzYSBuZ2jhu4EgbmdoaeG7h3AgcsO1IHLhu4d0IHRoZW8gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuLiBWaeG7h2MgbsOibmcgY2FvIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiBjw7MgdGjhu4MgZ2nDunAgY8OhIG5ow6JuIHRp4bq/cCBj4bqtbiBjw6FjIGPDtG5nIHZp4buHYyBjaHV5w6puIG3DtG4gdsOgIHF14bqjbiBsw70gduG7m2kgbeG7qWMgxJHhu5kgY2h1ecOqbiBtw7RuIGjDs2EgY2FvIGjGoW4uIGtow7RuZyB5w6p1IGPhuqd1IGNodXnDqm4gbcO0biBjYW8gKGJsdWUtY29sbGFyLCBzZXJ2aWNlcykuDQoNCg0KIyMjICoqS2nhu4NtIMSR4buLbmggQ2hpIGLDrG5oIHBoxrDGoW5nKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaCoqDQoNCi0gSDA6IGVkdWNhdGlvbiB2w6Agam9iIMSR4buZYyBs4bqtcCBuaGF1Lg0KLSBIMTogQ8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGVkdWNhdGlvbiB2w6Agam9iLg0KDQpgYGB7cn0NCmNoaXNxLnRlc3QodGFibGVfZWR1X2pvYikNCmBgYA0KDQoqKkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOioqDQoNCi0gR2nDoSB0cuG7iyBDaGktc3F1YXJlZCA9IDI4NDANCg0KLSBC4bqtYyB04buxIGRvIChkZikgPSAzMw0KDQotIHAtdmFsdWUgPCAyLjJlLTE2DQoNCioqS+G6v3QgbHXhuq1uOioqIFbhu5tpIHAtdmFsdWUgPCAwLjA1IHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALsSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBjw7MgbeG7kWkgbGnDqm4gaOG7hyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIGdp4buvYSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gdsOgIG5naOG7gSBuZ2hp4buHcCBj4bunYSBraMOhY2ggaMOgbmcuDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==