1 Giới thiệu

Bộ dữ liệu được rút gọn từ một chiến dịch marketing qua điện thoại của một ngân hàng tại Bồ Đào Nha. Dữ liệu ban đầu nhằm phục vụ cho việc dự đoán khả năng khách hàng đăng ký gửi tiền có kỳ hạn. Tuy nhiên, trong nghiên cứu này, tác giả tập trung vào hai biến định tính quan trọng có liên quan đến hành vi tài chính của khách hàng, đó là:

  • loan: Khách hàng có vay tiêu dùng hay không (yes/no)

Hai biến này được chọn làm biến phụ thuộc, với mục tiêu phân tích xem các yếu tố nhân khẩu học và đặc điểm khách hàng như:

  • Nghề nghiệp (job)
  • Tình trạng hôn nhân (marital)
  • Trình độ học vấn (education)
  • Tình trạng nợ quá hạn (default)
  • Hình thức liên hệ (contact)
  • Tình trạng vay mua nhà của khách hàng (housing)

… có ảnh hưởng như thế nào đến quyết định vay tiêu dùng của khách hàng.

Thông qua việc sử dụng các công cụ phân tích dữ liệu định tính như: bảng tần số, biểu đồ minh họa, kiểm định Chi bình phương, phân tích tỷ số chênh lệch (Odds Ratio) và rủi ro tương đối (Relative Risk), bài nghiên cứu sẽ làm rõ các yếu tố quan trọng ảnh hưởng đến hành vi tài chính của khách hàng.

1.1 Đọc và khám phá dữ liệu

data <- read.xlsx("D:/PTDLDT/data.xlsx", sheetIndex = 1, header = TRUE)

data <- data %>%
  mutate(
    loan = as.factor(loan),
    housing = as.factor(housing),
    job = as.factor(job),
    marital = as.factor(marital),
    education = as.factor(education),
    default = as.factor(default),
    contact = as.factor(contact)
  )
str(data)
## 'data.frame':    4521 obs. of  8 variables:
##  $ age      : num  30 33 35 30 59 35 36 39 41 43 ...
##  $ 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 ...
summary(data)
##       age                 job          marital         education    default   
##  Min.   :19.00   management :969   divorced: 528   primary  : 678   no :4445  
##  1st Qu.:33.00   blue-collar:946   married :2797   secondary:2306   yes:  76  
##  Median :39.00   technician :768   single  :1196   tertiary :1350             
##  Mean   :41.17   admin.     :478                   unknown  : 187             
##  3rd Qu.:49.00   services   :417                                              
##  Max.   :87.00   retired    :230                                              
##                  (Other)    :713                                              
##  housing     loan           contact    
##  no :1962   no :3830   cellular :2896  
##  yes:2559   yes: 691   telephone: 301  
##                        unknown  :1324  
##                                        
##                                        
##                                        
## 

1.2 Mô tả các biến

Tên biến Kiểu dữ liệu Số lượng giá trị duy nhất Mô tả nội dung
age Numeric 67 Tuổi của khách hàng (từ 19 đến 87 tuổi).
job Character 12 Nghề nghiệp của khách hàng như: management, blue-collar, services, student, retired, unemployed,…
marital Character 3 Tình trạng hôn nhân: single, married, divorced.
education Character 4 Trình độ học vấn: primary, secondary, tertiary, unknown.
default Character 2 Khách hàng có nợ tín dụng quá hạn không? (yes, no)
housing Character 2 Khách hàng có vay mua nhà không? (yes, no)
loan Character 2 Khách hàng có vay tiêu dùng không? (yes, no)
contact Character 3 Hình thức liên hệ: cellular, telephone, unknown

Nhận xét

Bộ dữ liệu gồm 8 biến và 4251 quan sát, được chia thành hai nhóm chính: biến định lượng và biến định tính.

  • Biến định lượng: Chỉ có một biến duy nhất là biến định lượng, đó là biến age. Đây là biến đo lường tuổi của khách hàng, có kiểu số (numeric), có thể sử dụng để tính toán trung bình, độ lệch chuẩn, phân phối, v.v. Biến này mang thông tin liên tục và có thể dùng cho các phương pháp phân tích định lượng như hồi quy tuyến tính hoặc phân tích phương sai.

  • Các biến định tính: Có bảy biến còn lại thuộc loại biến định tính. Các biến này mang thông tin dạng danh mục (categorical), không dùng để tính toán trực tiếp mà thường được phân tích bằng cách đếm tần số, tỷ lệ, hoặc dùng các phương pháp thống kê cho dữ liệu định tính như kiểm định Chi bình phương, tính Odds Ratio, Relative Risk,…

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

library(dplyr)

# Tạo bộ dữ liệu chỉ chứa các biến định tính
data1 <- data %>%
  dplyr::select(job, marital, education, default, housing, loan, contact)

# 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 Thống kê mô tả biến nghiên cứu

2.1 Thống mô tả biến phụ thuộc

2.1.1 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))

Vẽ biểu đồ tròn

# Tạo bảng tần suất
loan_freq <- table(data1$loan)
loan_prop <- prop.table(loan_freq)

# Chuyển thành data frame để dùng ggplot2
loan_df <- as.data.frame(loan_prop)
colnames(loan_df) <- c("Loan", "Proportion")

# Tính phần trăm để hiển thị nhãn
loan_df$Percent <- paste0(round(loan_df$Proportion * 100, 1), "%")

# Vẽ biểu đồ tròn bằng ggplot2
ggplot(loan_df, aes(x = "", y = Proportion, fill = Loan)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  geom_text(aes(label = Percent), position = position_stack(vjust = 0.5)) +
  labs(title = "Tỷ lệ vay tiêu dùng", x = NULL, y = NULL) +
  theme_void()+
  theme(plot.title = element_text(hjust = 0.5))

Dựa vào bảng tần số, tần suất và biểu đồ 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.2 Thống kê mô tả biến độc lập

2.2.1 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))

# Tạo bảng tần suất
housing_freq <- table(data1$housing)
housing_prop <- prop.table(housing_freq)

# Chuyển sang data frame để vẽ với ggplot2
housing_df <- as.data.frame(housing_prop)
colnames(housing_df) <- c("Housing", "Proportion")

# Thêm cột phần trăm để làm nhãn
housing_df$Percent <- paste0(round(housing_df$Proportion * 100, 1), "%")

# Vẽ biểu đồ tròn
ggplot(housing_df, aes(x = "", y = Proportion, fill = Housing)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  geom_text(aes(label = Percent), position = position_stack(vjust = 0.5)) +
  labs(title = "tỷ lệ vay mua nhà", x = NULL, y = NULL) +
  theme_void()

theme(plot.title = element_text(hjust = 0.5))
## List of 1
##  $ plot.title:List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0.5
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  - attr(*, "class")= chr [1:2] "theme" "gg"
##  - attr(*, "complete")= logi FALSE
##  - attr(*, "validate")= logi TRUE

Dựa vào bảng tần số, tần suất và biểu đồ 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.2.2 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)

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.3 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.2.4 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.2.5 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.

3 Kiểm định chi bình phương

Kiểm định Chi bình phương (Chi-squared test) được sử dụng để kiểm tra xem có mối liên hệ thống kê giữa hai biến phân loại (categorical variables) hay không. Trong bối cảnh này, ta kiểm tra xem các yếu tố như housing, marital, education, default, v.v. có ảnh hưởng đến quyết định vay tiêu dùng (loan) hay không.

3.1 Kiểm định giữa loan và housing

Giả thuyết kiểm định

  • H0: Không có mối liên hệ giữa loan và housing
  • H1: Có mối liên hệ giữa loan và housing
# Thực hiện kiểm định Chi bình phương
table_loan_housing <- table(data1$loan, data1$housing)
chisq_housing <- chisq.test(table_loan_housing)
chisq_housing
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_loan_housing
## X-squared = 1.4374, df = 1, p-value = 0.2306

3.2 Kiểm định giữa loan và job

Giả thuyết kiểm định

  • H0: Không có mối liên hệ giữa nghề nghiệp và khả năng vay tiêu dùng.
  • H1: Có mối liên hệ giữa nghề nghiệp và khả năng vay tiêu dùng.
# Thực hiện kiểm định Chi bình phương
table_loan_job <- table(data1$loan, data1$job)
chisq_job <- chisq.test(table_loan_job)
chisq_job
## 
##  Pearson's Chi-squared test
## 
## data:  table_loan_job
## X-squared = 47.191, df = 11, p-value = 1.989e-06

3.3 Kiểm định giữa loan và education

Giả thuyết kiểm định

  • H0: Không có mối liên hệ giữa trình độ học vấn và quyết định vay tiêu dùng.
  • H1: Có mối liên hệ giữa trình độ học vấn và quyết định vay tiêu dùng.
table_loan_edu <- table(data1$loan, data1$education)
chisq_edu <- chisq.test(table_loan_edu)
chisq_edu
## 
##  Pearson's Chi-squared test
## 
## data:  table_loan_edu
## X-squared = 39.798, df = 3, p-value = 1.176e-08

3.4 Kiểm định giữa loan và default

Giả thuyết kiểm định

  • H0: Không có mối liên hệ giữa tình trạng nợ quá hạn và việc vay tiêu dùng.
  • H1: Có mối liên hệ giữa tình trạng nợ quá hạn và việc vay tiêu dùng.
table_loan_default <- table(data1$loan, data1$default)
chisq_edu <- chisq.test(table_loan_default)
chisq_edu
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_loan_default
## X-squared = 17.157, df = 1, p-value = 3.441e-05

3.5 Kiểm định giữa loan và marital

Giả thuyết kiểm định

  • H0: Không có mối liên hệ giữa tình trạng hôn nhân và việc vay tiêu dùng.
  • H1: Có mối liên hệ giữa tình trạng hôn nhân và việc vay tiêu dùng.
table_loan_marital <- table(data1$loan, data1$marital)
chisq_edu <- chisq.test(table_loan_marital)
chisq_edu
## 
##  Pearson's Chi-squared test
## 
## data:  table_loan_marital
## X-squared = 10.88, df = 2, p-value = 0.004339

Thông qua kết quả kiểm định chỉ có 1 biến housing là không có mối liên hệ với biến loan, 4 biến độc lập còn lại đều có mối liên hệ với biến phụ thuộc là loan. Tiếp theo đó ta sẽ phân tích sâu về tình trạng vay tiêu dùng với 4 biến độc lập là: job, education, marital và default thông qua relative risk và oddratio.

4 Phân tích sâu hành vi vay tiêu dùng với Relative Risk và Odds Ratio

Sau khi kiểm định Chi bình phương, 4 biến định tính gồm: education, default, marital, và job được xác định là có mối liên hệ thống kê với biến phụ thuộc loan. Chúng ta tiếp tục đặt ra các câu hỏi nghiên cứu cụ thể và phân tích sâu hơn bằng Relative RiskOdds Ratio.

4.1 Education – Trình độ học vấn

Liệu khách hàng có trình độ học vấn cao (tertiary) có xu hướng vay tiêu dùng cao hơn so với những người không có học vấn cao hoặc không rõ học vấn không?

4.1.1 Gộp dữ liệu và tạo bảng tần số

data1$edu_grouped <- ifelse(data1$education == "tertiary", "high", 
                            ifelse(data1$education %in% c("primary", "secondary"), "low", NA))
table_edu_grouped <- table(data1$loan, data1$edu_grouped)
table_edu_grouped
##      
##       high  low
##   no  1176 2474
##   yes  174  510
data1 <- na.omit(data1)

4.1.2 Vẽ đồ thị phân tích

df_edu_grouped <- as.data.frame(table_edu_grouped)
colnames(df_edu_grouped) <- c("Loan", "Edu_Grouped", "Count")

ggplot(df_edu_grouped, aes(x = Edu_Grouped, y = Count, fill = Loan)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Phân bố vay tiêu dùng theo trình độ học vấn",
    x = "Trình độ học vấn",
    y = "Số lượng",
    fill = "Vay tiêu dùng"
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

4.1.3 Tính Relative Risk và Odd Ratio

mat_edu_grouped <- matrix(c(
  sum(data1$loan == "no" & data1$edu_grouped == "low"),
  sum(data1$loan == "no" & data1$edu_grouped == "high"),
  sum(data1$loan == "yes" & data1$edu_grouped == "low"),
  sum(data1$loan == "yes" & data1$edu_grouped == "high")
),
byrow = TRUE, nrow = 2,
dimnames = list(Loan = c("no", "yes"), Education = c("low", "high")))  

mat_edu_grouped
##      Education
## Loan   low high
##   no  2474 1176
##   yes  510  174
rr_edu_grouped <- riskratio(mat_edu_grouped)
rr_edu_grouped$measure
##      risk ratio with 95% C.I.
## Loan   estimate     lower     upper
##   no  1.0000000        NA        NA
##   yes 0.7895483 0.6886984 0.9051661
or_edu_grouped <- oddsratio(mat_edu_grouped)
or_edu_grouped$measure
##      odds ratio with 95% C.I.
## Loan   estimate     lower     upper
##   no  1.0000000        NA        NA
##   yes 0.7181725 0.5952221 0.8629916

Trong phân tích mối quan hệ giữa trình độ học vấn và hành vi vay tiêu dùng, tác giả phân chia khách hàng thành hai nhóm:

  • Nhóm có học vấn cao: khách hàng có trình độ tertiary

  • Nhóm học vấn thấp: bao gồm trình độ primary và secondary

Sau khi tính toán Relative Risk (RR) và Odds Ratio (OR) để so sánh xác suất và khả năng vay tiêu dùng giữa hai nhóm, kết quả cho thấy cả RR và OR đều nhỏ hơn 1 điều đó có nghĩa là khách hàng có học vấn cao có xu hướng vay tiêu dùng ít hơn nhóm học vấn thấp.

Cụ thể:

  • Nguy cơ tương đối (RR) là 0.7895483, tức là xác suất vay tiêu dùng của nhóm học vấn cao chỉ bằng 78.95% so với nhóm học vấn thấp.
  • Tỷ số chênh (OR) là 0.7181725, nghĩa là odds vay tiêu dùng của nhóm học vấn cao chỉ bằng 71.82% so với nhóm học vấn thấp.

4.2 Default – Nợ tín dụng quá hạn

4.2.1 Gộp dữ liệu và tạo bảng tần số

table_default <- table(data1$loan, data1$default)
table_default
##      
##         no  yes
##   no  3601   49
##   yes  660   24

4.2.2 Vẽ đồ thị phân tích

df_default <- as.data.frame(table_default)
colnames(df_default) <- c("Loan", "Default", "Count")

ggplot(df_default, aes(x = Default, y = Count, fill = Loan)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Phân bố vay tiêu dùng theo trạng thái nợ tín dụng",
    x = "Nợ tín dụng",
    y = "Số lượng",
    fill = "Vay tiêu dùng"
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

4.2.3 Tính Relative Risk và Odd Ratio

# Tạo ma trận với nhóm 'yes' (vay tiêu dùng) làm dòng thứ nhất = nhóm tham chiếu
mat_default <- matrix(c(
  sum(data1$loan == "yes" & data1$default == "yes"),  # a
  sum(data1$loan == "yes" & data1$default == "no"),   # b
  sum(data1$loan == "no" & data1$default == "yes"),   # c
  sum(data1$loan == "no" & data1$default == "no")     # d
),
byrow = TRUE, nrow = 2,
dimnames = list(Loan = c("yes", "no"), Default = c("yes", "no")))

mat_default
##      Default
## Loan  yes   no
##   yes  24  660
##   no   49 3601
# Tính RR và OR với nhóm 'yes' làm tham chiếu
rr_default <- riskratio(mat_default)
rr_default$measure
##      risk ratio with 95% C.I.
## Loan  estimate    lower    upper
##   yes 1.000000       NA       NA
##   no  1.022451 1.007447 1.037678
or_default <- oddsratio(mat_default)
or_default$measure
##      odds ratio with 95% C.I.
## Loan  estimate    lower    upper
##   yes 1.000000       NA       NA
##   no  2.680628 1.604802 4.358874

Trong phân tích này, tác giả xem xét mối liên hệ giữa hành vi vay tiêu dùng (loan) và tình trạng nợ tín dụng quá hạn (default). Nhóm có vay tiêu dùng được chọn làm nhóm tham chiếu, nhằm so sánh nguy cơ và khả năng nợ tín dụng ở nhóm không vay.

Kết quả như sau:

  • Nguy cơ tương đối (Relative Risk – RR) của nhóm không vay so với nhóm có vay là 1.022451 → Điều này có nghĩa là xác suất nợ tín dụng quá hạn ở nhóm không vay cao hơn 2.25% so với nhóm có vay.

  • Tỷ số chênh (Odds Ratio – OR) giữa hai nhóm là 2.680628 → Diễn giải rằng khả năng nợ tín dụng quá hạn (odds) ở nhóm không vay cao gấp 2.68 lần so với nhóm có vay.

Tóm lại, cả RR và OR đều lớn hơn 1 và có ý nghĩa thống kê, cho thấy nhóm khách hàng không vay tiêu dùng có nguy cơ và khả năng nợ tín dụng quá hạn cao hơn đáng kể so với nhóm có vay tiêu dùng.

4.3 Marital – Tình trạng hôn nhân

Khách hàng đã kết hôn có xu hướng vay tiêu dùng khác với người chưa kết hôn không?

4.3.1 Gộp dữ liệu và tạo bảng tần số

data1$marital_grouped <- ifelse(data1$marital == "married", "married", "others")
table_marital <- table(data1$loan, data1$marital_grouped)
table_marital
##      
##       married others
##   no     2232   1418
##   yes     448    236

4.3.2 Vẽ đồ thị phân tích

df_marital <- as.data.frame(table_marital)
colnames(df_marital) <- c("Loan", "Marital", "Count")

ggplot(df_marital, aes(x = Marital, y = Count, fill = Loan)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Phân bố vay tiêu dùng theo tình trạng hôn nhân",
    x = "Tình trạng hôn nhân",
    y = "Số lượng",
    fill = "Vay tiêu dùng"
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

4.3.3 Tính Relative Risk và Odd Ratio

mat_marital <- matrix(c(
  sum(data1$loan == "yes" & data1$marital_grouped == "married"),
  sum(data1$loan == "yes" & data1$marital_grouped == "others"),
  sum(data1$loan == "no" & data1$marital_grouped == "married"),
  sum(data1$loan == "no" & data1$marital_grouped == "others")
),
byrow = TRUE, nrow = 2,
dimnames = list(Loan = c("yes", "no"), Marital = c("married", "others")))

mat_marital
##      Marital
## Loan  married others
##   yes     448    236
##   no     2232   1418
rr_marital <- riskratio(mat_marital)
rr_marital$measure
##      risk ratio with 95% C.I.
## Loan  estimate   lower    upper
##   yes 1.000000      NA       NA
##   no  1.125972 1.00769 1.258137
or_marital <- oddsratio(mat_marital)
or_marital$measure
##      odds ratio with 95% C.I.
## Loan  estimate    lower    upper
##   yes 1.000000       NA       NA
##   no  1.205617 1.016948 1.432372

Trong phân tích này, khách hàng được chia thành hai nhóm: đã kết hôn (married) và khác (others – bao gồm độc thân, ly hôn…). Nhóm khách hàng có vay tiêu dùng (Loan = yes) được chọn làm nhóm tham chiếu.

Kết quả cho thấy

  • Nguy cơ tương đối (RR) của nhóm không vay tiêu dùng so với nhóm vay tiêu dùng là 1.126, nghĩa là xác suất không vay tiêu dùng của nhóm chưa kết hôn cao hơn 12.6% so với nhóm đã kết hôn. Khoảng tin cậy 95% là [1.008 ; 1.258], cho thấy sự khác biệt có ý nghĩa thống kê.

  • Tương tự, tỷ số chênh (OR) là 1.2056, tức là odds không vay tiêu dùng của nhóm chưa kết hôn cao hơn khoảng 20.56% so với nhóm đã kết hôn. Khoảng tin cậy 95% là [1.017 ; 1.432], tiếp tục khẳng định kết quả có ý nghĩa thống kê.

Như vậy, khách hàng đã kết hôn có xu hướng vay tiêu dùng nhiều hơn so với nhóm chưa kết hôn.

4.4 Job – Nghề nghiệp

Liệu nhóm người thất nghiệp có xu hướng vay tiêu dùng khác biệt so với các nhóm nghề còn lại không?

4.4.1 Gộp dữ liệu và tạo bảng tần số

data1$job_grouped <- ifelse(data1$job == "unemployed", "unemployed", "others")
table_job <- table(data1$loan, data1$job_grouped)
table_job
##      
##       others unemployed
##   no    3537        113
##   yes    671         13

4.4.2 Vẽ đồ thị phân tích

df_job <- as.data.frame(table_job)
colnames(df_job) <- c("Loan", "Job_Group", "Count")

ggplot(df_job, aes(x = Job_Group, y = Count, fill = Loan)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Phân bố vay tiêu dùng theo nghề nghiệp (thất nghiệp vs còn lại)",
    x = "Nhóm nghề nghiệp",
    y = "Số lượng",
    fill = "Vay tiêu dùng"
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

4.4.3 Tính Relative Risk và Odd Ratio

mat_job <- matrix(c(
  sum(data1$loan == "yes" & data1$job_grouped == "unemployed"),
  sum(data1$loan == "no" & data1$job_grouped == "unemployed"),
  sum(data1$loan == "yes" & data1$job_grouped == "others"),
  sum(data1$loan == "no" & data1$job_grouped == "others")
),
byrow = TRUE, nrow = 2,
dimnames = list(Loan = c("yes", "no"), Job = c("unemployed", "others")))

mat_job
##      Job
## Loan  unemployed others
##   yes         13    113
##   no         671   3537
rr_job <- riskratio(mat_job)
rr_job$measure
##      risk ratio with 95% C.I.
## Loan   estimate     lower     upper
##   yes 1.0000000        NA        NA
##   no  0.9372413 0.8820711 0.9958623
or_job <- oddsratio(mat_job)
or_job$measure
##      odds ratio with 95% C.I.
## Loan   estimate     lower    upper
##   yes 1.0000000        NA       NA
##   no  0.6131379 0.3264265 1.055025

Trong phân tích này, khách hàng được chia thành hai nhóm nghề nghiệp: thất nghiệp (unemployed) và các nhóm nghề còn lại (others). Nhóm khách hàng có vay tiêu dùng (Loan = yes) được chọn làm nhóm tham chiếu.

Kết quả cho thấy

  • Nguy cơ tương đối (RR) là 0.9372, nghĩa là xác suất không vay tiêu dùng của nhóm còn lại chỉ bằng 93.72% so với nhóm thất nghiệp. Khoảng tin cậy 95% là [0.8821 ; 0.9959], cho thấy sự khác biệt có ý nghĩa thống kê.

  • Trong khi đó, tỷ số chênh (OR) là 0.6131, tức là odds không vay tiêu dùng của nhóm nghề nghiệp còn lại thấp hơn khoảng 38.7% so với nhóm thất nghiệp. Tuy nhiên, khoảng tin cậy 95% là [0.3264 ; 1.0550], có chứa 1, nên kết quả này chưa đủ bằng chứng để kết luận có sự khác biệt thống kê ở mức ý nghĩa 5%.

Như vậy, có thể kết luận rằng nhóm khách hàng thất nghiệp có xu hướng không vay tiêu dùng cao hơn so với các nhóm nghề còn lại, và sự khác biệt này có ý nghĩa thống kê khi xét theo RR, nhưng chưa rõ ràng theo OR.


5 Hồi quy Logistic

Sau khi thực hiện phân tích nguy cơ tương đối (Relative Risk) và tỷ số chênh (Odds Ratio) để khám phá mối liên hệ giữa hành vi vay tiêu dùng với từng biến độc lập, bước tiếp theo là xây dựng mô hình hồi quy logistic nhằm đánh giá đồng thời tác động của các yếu tố này đến khả năng vay tiêu dùng của khách hàng.

# Hồi quy logistic
model_logit <- glm(loan ~ job + education + marital + default,
                   data = data1,
                   family = binomial)

# Tóm tắt kết quả
summary(model_logit)
## 
## Call:
## glm(formula = loan ~ job + education + marital + default, family = binomial, 
##     data = data1)
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)        -1.58836    0.20458  -7.764 8.22e-15 ***
## jobblue-collar     -0.08718    0.15435  -0.565 0.572185    
## jobentrepreneur     0.44778    0.22476   1.992 0.046340 *  
## jobhousemaid       -0.60363    0.34688  -1.740 0.081833 .  
## jobmanagement      -0.33188    0.17955  -1.848 0.064543 .  
## jobretired         -0.28758    0.23024  -1.249 0.211644    
## jobself-employed   -0.09880    0.23845  -0.414 0.678629    
## jobservices        -0.11508    0.17553  -0.656 0.512067    
## jobstudent         -2.58693    1.01624  -2.546 0.010909 *  
## jobtechnician      -0.21448    0.15634  -1.372 0.170112    
## jobunemployed      -0.68802    0.31788  -2.164 0.030430 *  
## jobunknown         -1.51908    1.03125  -1.473 0.140740    
## educationsecondary  0.33074    0.13543   2.442 0.014601 *  
## educationtertiary   0.05984    0.17065   0.351 0.725858    
## maritalmarried     -0.07152    0.12961  -0.552 0.581097    
## maritalsingle      -0.33498    0.14894  -2.249 0.024508 *  
## defaultyes          0.93740    0.25773   3.637 0.000276 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 3779.6  on 4333  degrees of freedom
## Residual deviance: 3698.3  on 4317  degrees of freedom
## AIC: 3732.3
## 
## Number of Fisher Scoring iterations: 6

Trong mô hình hồi quy logistic, mỗi hệ số (coefficient) phản ánh log odds của khả năng xảy ra sự kiện quan tâm (ở đây là vay tiêu dùng) khi biến độc lập thay đổi, so với nhóm tham chiếu và giữ các biến khác không đổi. Các hệ số dương cho thấy xác suất vay tăng, trong khi hệ số âm cho thấy xác suất vay giảm.

Biến education – Trình độ học vấn

  • educationsecondary (hệ số = 0.331, p = 0.015): → So với khách hàng học tiểu học, nhóm có trình độ trung học có log odds vay tiêu dùng cao hơn 0.331 đơn vị. → Nếu chuyển đổi sang odds ratio: exp(0.331) ≈ 1.39, nghĩa là nhóm học vấn trung học có odds vay cao hơn 39% so với nhóm học vấn tiểu học. → Kết luận: Trình độ học vấn trung học có ảnh hưởng tích cực và có ý nghĩa thống kê đến hành vi vay tiêu dùng.

  • educationtertiary (hệ số = 0.060, p = 0.726): → Khác biệt không có ý nghĩa thống kê. Odds của nhóm có trình độ đại học không khác đáng kể so với nhóm tiểu học.

Biến job – Nghề nghiệp

Biến này gồm nhiều nhóm so sánh với nhóm tham chiếu là “admin.”:

  • jobentrepreneur (hệ số = 0.448, p = 0.046): → Log odds vay tăng 0.448 so với nhóm admin → odds tăng khoảng 56.5% (exp(0.448) ≈ 1.565). → Kết luận: Người tự doanh có xu hướng vay cao hơn nhân viên hành chính và sự khác biệt có ý nghĩa thống kê.

  • jobstudent (hệ số = -2.587, p = 0.011): → Hệ số âm lớn và có ý nghĩa thống kê: odds vay giảm khoảng 92% (exp(-2.587) ≈ 0.075). → Kết luận: Sinh viên có xác suất vay tiêu dùng thấp hơn rất nhiều, đây là kết quả có ý nghĩa thực tiễn mạnh.

  • jobunemployed (hệ số = -0.688, p = 0.030): → Giảm odds vay tiêu dùng khoảng 50% (exp(-0.688) ≈ 0.503). → Kết luận: Người thất nghiệp cũng có xu hướng vay thấp hơn, với mức giảm có ý nghĩa thống kê.

Các nhóm khác như blue-collar, retired, housemaid, technician, unknown… đều không có hệ số ý nghĩa thống kê (p > 0.05), tức là không có bằng chứng mạnh mẽ cho thấy họ khác biệt về hành vi vay so với nhóm admin.

Biến marital – Tình trạng hôn nhân

Nhóm tham chiếu là đã ly hôn (divorced):

  • maritalsingle (hệ số = -0.335, p = 0.025): → Odds giảm khoảng 28% (exp(-0.335) ≈ 0.715). → Người độc thân có xu hướng vay tiêu dùng thấp hơn so với người đã ly hôn, và sự khác biệt này có ý nghĩa thống kê.

  • married (hệ số = -0.072, p = 0.581): → Không có ý nghĩa thống kê → không thể kết luận có sự khác biệt với người ly hôn.

Biến default – Nợ tín dụng quá hạn

defaultyes (hệ số = 0.937, p < 0.001): → Là một trong những biến quan trọng nhất của mô hình. → Odds tăng gấp 2.55 lần so với người không nợ (exp(0.937) ≈ 2.552). → Kết luận: Khách hàng có lịch sử nợ xấu có khả năng vay cao hơn nhiều — điều này có thể phản ánh sự lặp lại hành vi tài chính rủi ro, hoặc chiến lược nhắm mục tiêu khách hàng nhiều rủi ro của ngân hàng.

6 Tổng kết kết quả hồi quy logistic và giả thuyết thống kê

Mô hình hồi quy logistic được xây dựng để phân tích các yếu tố ảnh hưởng đến khả năng vay tiêu dùng (loan). Trong đó, các biến độc lập gồm: job, education, marital, và default.

Đối với mỗi biến giải thích (biến độc lập), giả thuyết thống kê được đặt ra như sau:

  • Giả thuyết không (H₀): Hệ số hồi quy bằng 0 (biến độc lập không ảnh hưởng đến xác suất vay tiêu dùng).
  • Giả thuyết đối (H₁): Hệ số hồi quy khác 0 (biến độc lập có ảnh hưởng đến xác suất vay tiêu dùng).

Kết quả mô hình chỉ ra một số biến có ý nghĩa thống kê, tức là có bằng chứng để bác bỏ H₀ ở mức ý nghĩa 5%:

6.1 Các biến có ảnh hưởng đáng kể đến hành vi vay tiêu dùng:

  • defaultyes (p = 0.0003):
    → Bác bỏ H₀. Khách hàng có nợ tín dụng quá hạn có xác suất vay tiêu dùng cao hơn đáng kể.
    → OR > 1 cho thấy tăng khả năng vay.

  • jobstudent (p = 0.0109):
    → Bác bỏ H₀. Nhóm sinh viên có xác suất vay tiêu dùng thấp hơn nhiều so với nhóm nghề nghiệp tham chiếu (admin).
    → OR < 1 cho thấy giảm khả năng vay.

  • jobunemployed (p = 0.0304):
    → Bác bỏ H₀. Người thất nghiệp ít có khả năng vay tiêu dùng hơn.
    → OR < 1, phản ánh sự hạn chế tiếp cận tín dụng.

  • jobentrepreneur (p = 0.0463):
    → Bác bỏ H₀. Nhóm doanh nhân có khả năng vay tiêu dùng cao hơn.

  • educationsecondary (p = 0.0146):
    → Bác bỏ H₀. Trình độ học vấn trung học làm tăng xác suất vay tiêu dùng so với tiểu học.

  • maritalsingle (p = 0.0245):
    → Bác bỏ H₀. Nhóm độc thân có xu hướng vay ít hơn so với nhóm ly hôn (tham chiếu).

6.2 Các biến không có ý nghĩa thống kê (p > 0.05)

  • Các biến như jobblue-collar, jobretired, educationtertiary, maritalmarried không đủ bằng chứng để bác bỏ H₀. Điều này có nghĩa là chưa có cơ sở thống kê để khẳng định những biến này ảnh hưởng đến xác suất vay tiêu dùng trong mô hình.

7 Hồi quy Probit

Sau khi thực hiện mô hình hồi quy logistic, tác giả tiếp tục triển khai mô hình hồi quy Probit nhằm kiểm tra độ nhất quán và tính nhạy của các kết quả. Mô hình Probit sử dụng hàm liên kết phân phối chuẩn tích lũy để mô phỏng xác suất khách hàng vay tiêu dùng (loan = yes) dựa trên các biến độc lập như nghề nghiệp, trình độ học vấn, tình trạng hôn nhân và lịch sử nợ xấu (default).

Giả thuyết thống kê

Đối với từng biến độc lập trong mô hình, ta kiểm định:

  • H₀: Biến không có ảnh hưởng đến xác suất vay tiêu dùng
  • H₁: Biến có ảnh hưởng đến xác suất vay tiêu dùng

Mức ý nghĩa sử dụng là 5% (α = 0.05). Nếu p-value < 0.05, ta bác bỏ H₀.

7.0.1 Kết quả mô hình Probit

# Chạy mô hình probit
model_probit <- glm(loan ~ job + education + marital + default,
                    data = data1,
                    family = binomial(link = "probit"))

# Hiển thị kết quả
summary(model_probit)
## 
## Call:
## glm(formula = loan ~ job + education + marital + default, family = binomial(link = "probit"), 
##     data = data1)
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)        -0.95148    0.11423  -8.330  < 2e-16 ***
## jobblue-collar     -0.04945    0.08733  -0.566 0.571234    
## jobentrepreneur     0.25600    0.13113   1.952 0.050907 .  
## jobhousemaid       -0.32254    0.18134  -1.779 0.075288 .  
## jobmanagement      -0.18647    0.09917  -1.880 0.060054 .  
## jobretired         -0.16692    0.12751  -1.309 0.190520    
## jobself-employed   -0.06293    0.13357  -0.471 0.637561    
## jobservices        -0.06470    0.09927  -0.652 0.514542    
## jobstudent         -1.19238    0.39451  -3.022 0.002507 ** 
## jobtechnician      -0.12132    0.08785  -1.381 0.167308    
## jobunemployed      -0.37298    0.16658  -2.239 0.025157 *  
## jobunknown         -0.76093    0.46589  -1.633 0.102407    
## educationsecondary  0.18140    0.07419   2.445 0.014476 *  
## educationtertiary   0.03537    0.09280   0.381 0.703059    
## maritalmarried     -0.03876    0.07259  -0.534 0.593391    
## maritalsingle      -0.18677    0.08238  -2.267 0.023374 *  
## defaultyes          0.54800    0.15588   3.516 0.000439 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 3779.6  on 4333  degrees of freedom
## Residual deviance: 3698.3  on 4317  degrees of freedom
## AIC: 3732.3
## 
## Number of Fisher Scoring iterations: 6

8 Thống kê mô tả

loan_tab <- table(data$loan)
barplot(loan_tab, col = c("skyblue", "orange"), main = "Phân bố vay tiêu dùng", ylab = "Số lượng")

prop.table(loan_tab)
## 
##        no       yes 
## 0.8471577 0.1528423

9 Phân tích Chi bình phương, RR, OR

# Kiểm định Chi bình phương
chisq.test(table(data$loan, data$education))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$loan, data$education)
## X-squared = 39.798, df = 3, p-value = 1.176e-08
chisq.test(table(data$loan, data$housing))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(data$loan, data$housing)
## X-squared = 1.4374, df = 1, p-value = 0.2306
chisq.test(table(data$loan, data$marital))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$loan, data$marital)
## X-squared = 10.88, df = 2, p-value = 0.004339
# Relative Risk và Odds Ratio
rr1 <- riskratio(table(data$loan, data$housing))
rr2 <- riskratio(table(data$loan, data$default))

# Gộp education lại làm nhóm high/low
data$edu_bin <- ifelse(data$education == "tertiary", "high", "low")
rr3 <- riskratio(table(data$loan, data$edu_bin))

rr1
## $data
##        
##           no  yes Total
##   no    1677 2153  3830
##   yes    285  406   691
##   Total 1962 2559  4521
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate     lower    upper
##   no  1.000000        NA       NA
##   yes 1.045208 0.9760694 1.119244
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes   0.214876    0.2266007  0.2147536
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
rr2
## $data
##        
##           no yes Total
##   no    3779  51  3830
##   yes    666  25   691
##   Total 4445  76  4521
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 2.717006 1.695398 4.354211
## 
## $p.value
##      two-sided
##         midp.exact fisher.exact   chi.square
##   no            NA           NA           NA
##   yes 0.0001173576 0.0001325964 1.686155e-05
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
rr3
## $data
##        
##         high  low Total
##   no    1176 2654  3830
##   yes    174  517   691
##   Total 1350 3171  4521
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 1.079718 1.028993 1.132943
## 
## $p.value
##      two-sided
##        midp.exact fisher.exact  chi.square
##   no           NA           NA          NA
##   yes 0.003151701  0.003325888 0.003495297
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

10 Hồi quy Logistic

model_logit <- glm(loan ~ age + job + marital + education + default + housing + contact,
                   data = data, family = binomial(link = "logit"))
summary(model_logit)
## 
## Call:
## glm(formula = loan ~ age + job + marital + education + default + 
##     housing + contact, family = binomial(link = "logit"), data = data)
## 
## Coefficients:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)        -1.178525   0.329099  -3.581 0.000342 ***
## age                -0.007839   0.005196  -1.509 0.131399    
## jobblue-collar     -0.103687   0.154434  -0.671 0.501966    
## jobentrepreneur     0.426384   0.223481   1.908 0.056401 .  
## jobhousemaid       -0.411495   0.327034  -1.258 0.208296    
## jobmanagement      -0.307045   0.178470  -1.720 0.085355 .  
## jobretired         -0.185252   0.249837  -0.741 0.458396    
## jobself-employed   -0.088828   0.238548  -0.372 0.709618    
## jobservices        -0.112180   0.174801  -0.642 0.521030    
## jobstudent         -2.734139   1.016134  -2.691 0.007130 ** 
## jobtechnician      -0.214554   0.155763  -1.377 0.168378    
## jobunemployed      -0.697566   0.317785  -2.195 0.028157 *  
## jobunknown         -1.670462   1.028412  -1.624 0.104309    
## maritalmarried     -0.067450   0.129712  -0.520 0.603064    
## maritalsingle      -0.388726   0.156069  -2.491 0.012748 *  
## educationsecondary  0.296682   0.137480   2.158 0.030927 *  
## educationtertiary  -0.002919   0.173300  -0.017 0.986561    
## educationunknown   -1.297147   0.406230  -3.193 0.001407 ** 
## defaultyes          0.978165   0.253887   3.853 0.000117 ***
## housingyes         -0.037839   0.090870  -0.416 0.677115    
## contacttelephone    0.013655   0.176674   0.077 0.938392    
## contactunknown     -0.100777   0.096938  -1.040 0.298524    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 3866.4  on 4520  degrees of freedom
## Residual deviance: 3753.7  on 4499  degrees of freedom
## AIC: 3797.7
## 
## Number of Fisher Scoring iterations: 6

11 Hồi quy Probit

model_probit <- glm(loan ~ age + job + marital + education + default + housing + contact,
                    data = data, family = binomial(link = "probit"))
summary(model_probit)
## 
## Call:
## glm(formula = loan ~ age + job + marital + education + default + 
##     housing + contact, family = binomial(link = "probit"), data = data)
## 
## Coefficients:
##                      Estimate Std. Error z value Pr(>|z|)    
## (Intercept)        -0.7271617  0.1821922  -3.991 6.57e-05 ***
## age                -0.0043173  0.0028555  -1.512 0.130554    
## jobblue-collar     -0.0619725  0.0870289  -0.712 0.476408    
## jobentrepreneur     0.2379582  0.1295090   1.837 0.066153 .  
## jobhousemaid       -0.2108010  0.1734828  -1.215 0.224323    
## jobmanagement      -0.1695078  0.0982353  -1.726 0.084432 .  
## jobretired         -0.1119851  0.1375354  -0.814 0.415515    
## jobself-employed   -0.0542759  0.1331695  -0.408 0.683589    
## jobservices        -0.0619023  0.0986216  -0.628 0.530217    
## jobstudent         -1.2599311  0.3931070  -3.205 0.001350 ** 
## jobtechnician      -0.1199374  0.0872809  -1.374 0.169394    
## jobunemployed      -0.3772845  0.1663065  -2.269 0.023292 *  
## jobunknown         -0.8183526  0.4494684  -1.821 0.068651 .  
## maritalmarried     -0.0348699  0.0722885  -0.482 0.629542    
## maritalsingle      -0.2126583  0.0860073  -2.473 0.013415 *  
## educationsecondary  0.1610728  0.0752378   2.141 0.032286 *  
## educationtertiary  -0.0021571  0.0940543  -0.023 0.981702    
## educationunknown   -0.6380585  0.1868779  -3.414 0.000639 ***
## defaultyes          0.5735549  0.1531773   3.744 0.000181 ***
## housingyes         -0.0188070  0.0500329  -0.376 0.706996    
## contacttelephone   -0.0003741  0.0972035  -0.004 0.996929    
## contactunknown     -0.0546517  0.0533416  -1.025 0.305570    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 3866.4  on 4520  degrees of freedom
## Residual deviance: 3754.0  on 4499  degrees of freedom
## AIC: 3798
## 
## Number of Fisher Scoring iterations: 6

12 Đánh giá mô hình

p_logit <- predict(model_logit, type = "response")
roc_logit <- roc(data$loan, p_logit)
plot(roc_logit, col = "blue", main = "ROC Curve: Logistic vs Probit")
auc(roc_logit)
## Area under the curve: 0.6139
p_probit <- predict(model_probit, type = "response")
roc_probit <- roc(data$loan, p_probit)
lines(roc_probit, col = "red")
legend("bottomright", legend = c("Logistic", "Probit"), col = c("blue", "red"), lty = 1)

13 Bảng so sánh Logistic và Probit

stargazer(model_logit, model_probit, type = "text", title = "So sánh hồi quy logistic & probit")
## 
## So sánh hồi quy logistic & probit
## ===============================================
##                        Dependent variable:     
##                    ----------------------------
##                                loan            
##                       logistic       probit    
##                         (1)            (2)     
## -----------------------------------------------
## age                    -0.008        -0.004    
##                       (0.005)        (0.003)   
##                                                
## jobblue-collar         -0.104        -0.062    
##                       (0.154)        (0.087)   
##                                                
## jobentrepreneur        0.426*        0.238*    
##                       (0.223)        (0.130)   
##                                                
## jobhousemaid           -0.411        -0.211    
##                       (0.327)        (0.173)   
##                                                
## jobmanagement         -0.307*        -0.170*   
##                       (0.178)        (0.098)   
##                                                
## jobretired             -0.185        -0.112    
##                       (0.250)        (0.138)   
##                                                
## jobself-employed       -0.089        -0.054    
##                       (0.239)        (0.133)   
##                                                
## jobservices            -0.112        -0.062    
##                       (0.175)        (0.099)   
##                                                
## jobstudent           -2.734***      -1.260***  
##                       (1.016)        (0.393)   
##                                                
## jobtechnician          -0.215        -0.120    
##                       (0.156)        (0.087)   
##                                                
## jobunemployed         -0.698**      -0.377**   
##                       (0.318)        (0.166)   
##                                                
## jobunknown             -1.670        -0.818*   
##                       (1.028)        (0.449)   
##                                                
## maritalmarried         -0.067        -0.035    
##                       (0.130)        (0.072)   
##                                                
## maritalsingle         -0.389**      -0.213**   
##                       (0.156)        (0.086)   
##                                                
## educationsecondary    0.297**        0.161**   
##                       (0.137)        (0.075)   
##                                                
## educationtertiary      -0.003        -0.002    
##                       (0.173)        (0.094)   
##                                                
## educationunknown     -1.297***      -0.638***  
##                       (0.406)        (0.187)   
##                                                
## defaultyes            0.978***      0.574***   
##                       (0.254)        (0.153)   
##                                                
## housingyes             -0.038        -0.019    
##                       (0.091)        (0.050)   
##                                                
## contacttelephone       0.014         -0.0004   
##                       (0.177)        (0.097)   
##                                                
## contactunknown         -0.101        -0.055    
##                       (0.097)        (0.053)   
##                                                
## Constant             -1.179***      -0.727***  
##                       (0.329)        (0.182)   
##                                                
## -----------------------------------------------
## Observations           4,521          4,521    
## Log Likelihood       -1,876.863    -1,876.992  
## Akaike Inf. Crit.    3,797.725      3,797.984  
## ===============================================
## Note:               *p<0.1; **p<0.05; ***p<0.01
LS0tDQp0aXRsZTogIk5oaeG7h20gVuG7pSA2Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHllcw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQotLS0NCg0KPHN0eWxlPg0KLyogSW4gxJHhuq1tIHRvw6BuIGLhu5kgdGnDqnUgxJHhu4EgKi8NCmgxLCBoMiwgaDMsIGg0LCBoNSwgaDYgew0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkobm5ldCkNCmxpYnJhcnkocHNjbCkNCmxpYnJhcnkocFJPQykNCmxpYnJhcnkoTUFTUykNCmxpYnJhcnkoZXBpdG9vbHMpDQpsaWJyYXJ5KHN0YXJnYXplcikNCmxpYnJhcnkoeGxzeCkNCmBgYA0KDQojICoqR2nhu5tpIHRoaeG7h3UqKg0KDQpC4buZIGThu68gbGnhu4d1IMSRxrDhu6NjIHLDunQgZ+G7jW4gdOG7qyBt4buZdCBjaGnhur9uIGThu4tjaCBtYXJrZXRpbmcgcXVhIMSRaeG7h24gdGhv4bqhaSBj4bunYSBt4buZdCBuZ8OibiBow6BuZyB04bqhaSBC4buTIMSQw6BvIE5oYS4gROG7ryBsaeG7h3UgYmFuIMSR4bqndSBuaOG6sW0gcGjhu6VjIHbhu6UgY2hvIHZp4buHYyBk4buxIMSRb8OhbiBraOG6oyBuxINuZyBraMOhY2ggaMOgbmcgxJHEg25nIGvDvSBn4butaSB0aeG7gW4gY8OzIGvhu7MgaOG6oW4uIFR1eSBuaGnDqm4sIHRyb25nIG5naGnDqm4gY+G7qXUgbsOgeSwgdMOhYyBnaeG6oyB04bqtcCB0cnVuZyB2w6BvIGhhaSBiaeG6v24gxJHhu4tuaCB0w61uaCBxdWFuIHRy4buNbmcgY8OzIGxpw6puIHF1YW4gxJHhur9uIGjDoG5oIHZpIHTDoGkgY2jDrW5oIGPhu6dhIGtow6FjaCBow6BuZywgxJHDsyBsw6A6DQoNCi0gKipgbG9hbmAqKjogS2jDoWNoIGjDoG5nIGPDsyB2YXkgdGnDqnUgZMO5bmcgaGF5IGtow7RuZyAoeWVzL25vKQ0KDQpIYWkgYmnhur9uIG7DoHkgxJHGsOG7o2MgY2jhu41uIGzDoG0gKipiaeG6v24gcGjhu6UgdGh14buZYyoqLCB24bubaSBt4bulYyB0acOqdSBwaMOibiB0w61jaCB4ZW0gKipjw6FjIHnhur91IHThu5EgbmjDom4ga2jhuql1IGjhu41jIHbDoCDEkeG6t2MgxJFp4buDbSBraMOhY2ggaMOgbmcqKiBuaMawOg0KDQotIE5naOG7gSBuZ2hp4buHcCAoYGpvYmApDQotIFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiAoYG1hcml0YWxgKQ0KLSBUcsOsbmggxJHhu5kgaOG7jWMgduG6pW4gKGBlZHVjYXRpb25gKQ0KLSBUw6xuaCB0cuG6oW5nIG7hu6MgcXXDoSBo4bqhbiAoYGRlZmF1bHRgKQ0KLSBIw6xuaCB0aOG7qWMgbGnDqm4gaOG7hyAoYGNvbnRhY3RgKQ0KLSBUw6xuaCB0cuG6oW5nIHZheSBtdWEgbmjDoCBj4bunYSBraMOhY2ggaMOgbmcgKGBob3VzaW5nYCkNCg0KLi4uIGPDsyDhuqNuaCBoxrDhu59uZyBuaMawIHRo4bq/IG7DoG8gxJHhur9uIHF1eeG6v3QgxJHhu4tuaCAqKnZheSB0acOqdSBkw7luZyoqIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KVGjDtG5nIHF1YSB2aeG7h2Mgc+G7rSBk4bulbmcgY8OhYyBjw7RuZyBj4bulIHBow6JuIHTDrWNoIGThu68gbGnhu4d1IMSR4buLbmggdMOtbmggbmjGsDogYuG6o25nIHThuqduIHPhu5EsIGJp4buDdSDEkeG7kyBtaW5oIGjhu41hLCBraeG7g20gxJHhu4tuaCBDaGkgYsOsbmggcGjGsMahbmcsIHBow6JuIHTDrWNoIHThu7cgc+G7kSBjaMOqbmggbOG7h2NoIChPZGRzIFJhdGlvKSB2w6AgcuG7p2kgcm8gdMawxqFuZyDEkeG7kWkgKFJlbGF0aXZlIFJpc2spLCBiw6BpIG5naGnDqm4gY+G7qXUgc+G6vSBsw6BtIHLDtSBjw6FjIHnhur91IHThu5EgcXVhbiB0cuG7jW5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBow6BuaCB2aSB0w6BpIGNow61uaCBj4bunYSBraMOhY2ggaMOgbmcuDQoNCiMjICoqxJDhu41jIHbDoCBraMOhbSBwaMOhIGThu68gbGnhu4d1KioNCg0KYGBge3J9DQpkYXRhIDwtIHJlYWQueGxzeCgiRDovUFRETERUL2RhdGEueGxzeCIsIHNoZWV0SW5kZXggPSAxLCBoZWFkZXIgPSBUUlVFKQ0KDQpkYXRhIDwtIGRhdGEgJT4lDQogIG11dGF0ZSgNCiAgICBsb2FuID0gYXMuZmFjdG9yKGxvYW4pLA0KICAgIGhvdXNpbmcgPSBhcy5mYWN0b3IoaG91c2luZyksDQogICAgam9iID0gYXMuZmFjdG9yKGpvYiksDQogICAgbWFyaXRhbCA9IGFzLmZhY3RvcihtYXJpdGFsKSwNCiAgICBlZHVjYXRpb24gPSBhcy5mYWN0b3IoZWR1Y2F0aW9uKSwNCiAgICBkZWZhdWx0ID0gYXMuZmFjdG9yKGRlZmF1bHQpLA0KICAgIGNvbnRhY3QgPSBhcy5mYWN0b3IoY29udGFjdCkNCiAgKQ0Kc3RyKGRhdGEpDQpzdW1tYXJ5KGRhdGEpDQpgYGANCg0KDQojIyAqKk3DtCB04bqjIGPDoWMgYmnhur9uKioNCg0KfCBUw6puIGJp4bq/biAgICB8IEtp4buDdSBk4buvIGxp4buHdSB8IFPhu5EgbMaw4bujbmcgZ2nDoSB0cuG7iyBkdXkgbmjhuqV0IHwgTcO0IHThuqMgbuG7mWkgZHVuZyB8DQp8LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18DQp8IGBhZ2VgICAgICAgIHwgTnVtZXJpYyAgICAgIHwgNjcgICAgICAgICAgICAgICAgICAgICAgICAgfCBUdeG7lWkgY+G7p2Ega2jDoWNoIGjDoG5nICh04burIDE5IMSR4bq/biA4NyB0deG7lWkpLiB8DQp8IGBqb2JgICAgICAgIHwgQ2hhcmFjdGVyICAgIHwgMTIgICAgICAgICAgICAgICAgICAgICAgICAgfCBOZ2jhu4EgbmdoaeG7h3AgY+G7p2Ega2jDoWNoIGjDoG5nIG5oxrA6IGBtYW5hZ2VtZW50YCwgYGJsdWUtY29sbGFyYCwgYHNlcnZpY2VzYCwgYHN0dWRlbnRgLCBgcmV0aXJlZGAsIGB1bmVtcGxveWVkYCwuLi4gfA0KfCBgbWFyaXRhbGAgICB8IENoYXJhY3RlciAgICB8IDMgICAgICAgICAgICAgICAgICAgICAgICAgIHwgVMOsbmggdHLhuqFuZyBow7RuIG5ow6JuOiBgc2luZ2xlYCwgYG1hcnJpZWRgLCBgZGl2b3JjZWRgLiB8DQp8IGBlZHVjYXRpb25gIHwgQ2hhcmFjdGVyICAgIHwgNCAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUcsOsbmggxJHhu5kgaOG7jWMgduG6pW46IGBwcmltYXJ5YCwgYHNlY29uZGFyeWAsIGB0ZXJ0aWFyeWAsIGB1bmtub3duYC4gfA0KfCBgZGVmYXVsdGAgICB8IENoYXJhY3RlciAgICB8IDIgICAgICAgICAgICAgICAgICAgICAgICAgIHwgS2jDoWNoIGjDoG5nIGPDsyBu4bujIHTDrW4gZOG7pW5nIHF1w6EgaOG6oW4ga2jDtG5nPyAoYHllc2AsIGBub2ApIHwNCnwgYGhvdXNpbmdgICAgfCBDaGFyYWN0ZXIgICAgfCAyICAgICAgICAgICAgICAgICAgICAgICAgICB8IEtow6FjaCBow6BuZyBjw7MgdmF5IG11YSBuaMOgIGtow7RuZz8gKGB5ZXNgLCBgbm9gKSB8DQp8IGBsb2FuYCAgICAgIHwgQ2hhcmFjdGVyICAgIHwgMiAgICAgICAgICAgICAgICAgICAgICAgICAgfCBLaMOhY2ggaMOgbmcgY8OzIHZheSB0acOqdSBkw7luZyBraMO0bmc/IChgeWVzYCwgYG5vYCkgfA0KfCBgY29udGFjdGAgICB8IENoYXJhY3RlciAgICB8IDMgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSMOsbmggdGjhu6ljIGxpw6puIGjhu4c6IGBjZWxsdWxhcmAsIGB0ZWxlcGhvbmVgLCBgdW5rbm93bmAgfA0KDQoNCioqTmjhuq1uIHjDqXQqKg0KDQpC4buZIGThu68gbGnhu4d1IGfhu5NtIDggYmnhur9uIHbDoCA0MjUxIHF1YW4gc8OhdCwgxJHGsOG7o2MgY2hpYSB0aMOgbmggaGFpIG5ow7NtIGNow61uaDogYmnhur9uIMSR4buLbmggbMaw4bujbmcgdsOgIGJp4bq/biDEkeG7i25oIHTDrW5oLg0KDQotICoqQmnhur9uIMSR4buLbmggbMaw4bujbmc6KiogQ2jhu4kgY8OzIG3hu5l0IGJp4bq/biBkdXkgbmjhuqV0IGzDoCBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZywgxJHDsyBsw6AgYmnhur9uIGFnZS4gxJDDonkgbMOgIGJp4bq/biDEkW8gbMaw4budbmcgdHXhu5VpIGPhu6dhIGtow6FjaCBow6BuZywgY8OzIGtp4buDdSBz4buRIChudW1lcmljKSwgY8OzIHRo4buDIHPhu60gZOG7pW5nIMSR4buDIHTDrW5oIHRvw6FuIHRydW5nIGLDrG5oLCDEkeG7mSBs4buHY2ggY2h14bqpbiwgcGjDom4gcGjhu5FpLCB2LnYuIEJp4bq/biBuw6B5IG1hbmcgdGjDtG5nIHRpbiBsacOqbiB04bulYyB2w6AgY8OzIHRo4buDIGTDuW5nIGNobyBjw6FjIHBoxrDGoW5nIHBow6FwIHBow6JuIHTDrWNoIMSR4buLbmggbMaw4bujbmcgbmjGsCBo4buTaSBxdXkgdHV54bq/biB0w61uaCBob+G6t2MgcGjDom4gdMOtY2ggcGjGsMahbmcgc2FpLg0KDQotICoqQ8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaDoqKiBDw7MgYuG6o3kgYmnhur9uIGPDsm4gbOG6oWkgdGh14buZYyBsb+G6oWkgYmnhur9uIMSR4buLbmggdMOtbmguIEPDoWMgYmnhur9uIG7DoHkgbWFuZyB0aMO0bmcgdGluIGThuqFuZyBkYW5oIG3hu6VjIChjYXRlZ29yaWNhbCksIGtow7RuZyBkw7luZyDEkeG7gyB0w61uaCB0b8OhbiB0cuG7sWMgdGnhur9wIG3DoCB0aMaw4budbmcgxJHGsOG7o2MgcGjDom4gdMOtY2ggYuG6sW5nIGPDoWNoIMSR4bq/bSB04bqnbiBz4buRLCB04bu3IGzhu4csIGhv4bq3YyBkw7luZyBjw6FjIHBoxrDGoW5nIHBow6FwIHRo4buRbmcga8OqIGNobyBk4buvIGxp4buHdSDEkeG7i25oIHTDrW5oIG5oxrAga2nhu4NtIMSR4buLbmggQ2hpIGLDrG5oIHBoxrDGoW5nLCB0w61uaCBPZGRzIFJhdGlvLCBSZWxhdGl2ZSBSaXNrLC4uLg0KDQoqKlThuqFvIGLhu5kgZOG7ryBsaeG7h3UgY2jhu4kgY8OzIGJp4bq/biDEkeG7i25oIHTDrW5oKioNCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KDQojIFThuqFvIGLhu5kgZOG7ryBsaeG7h3UgY2jhu4kgY2jhu6lhIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmgNCmRhdGExIDwtIGRhdGEgJT4lDQogIGRwbHlyOjpzZWxlY3Qoam9iLCBtYXJpdGFsLCBlZHVjYXRpb24sIGRlZmF1bHQsIGhvdXNpbmcsIGxvYW4sIGNvbnRhY3QpDQoNCiMgWGVtIHRyxrDhu5tjIGThu68gbGnhu4d1IG3hu5tpDQpzdHIoZGF0YTEpDQpoZWFkKGRhdGExKQ0KYGBgDQoNCi0tLQ0KDQojICoqVGjhu5FuZyBrw6ogbcO0IHThuqMgYmnhur9uIG5naGnDqm4gY+G7qXUqKg0KDQojIyAqKlRo4buRbmcgbcO0IHThuqMgYmnhur9uIHBo4bulIHRodeG7mWMqKg0KDQojIyMgKipCaeG6v24gTG9hbioqDQoNCioqTOG6rXAgYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KdGFibGUoZGF0YTEkbG9hbikNCnByb3AudGFibGUodGFibGUoZGF0YTEkbG9hbikpDQpgYGANCg0KDQoqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0KioNCg0KYGBge3J9DQpmcmVxX2xvYW4gPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShkYXRhMSRsb2FuKSkNCmNvbG5hbWVzKGZyZXFfbG9hbikgPC0gYygiTG9hbiIsICJDb3VudCIpDQoNCmdncGxvdChmcmVxX2xvYW4sIGFlcyh4ID0gTG9hbiwgeSA9IENvdW50KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiM5MzcwREIiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41KSArDQogIGxhYnModGl0bGUgPSAiVOG6p24gc+G7kSB2YXkgdGnDqnUgZMO5bmciLCB4ID0gIlZheSB0acOqdSBkw7luZyIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KDQoqKlbhur0gYmnhu4N1IMSR4buTIHRyw7JuKioNCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQNCmxvYW5fZnJlcSA8LSB0YWJsZShkYXRhMSRsb2FuKQ0KbG9hbl9wcm9wIDwtIHByb3AudGFibGUobG9hbl9mcmVxKQ0KDQojIENodXnhu4NuIHRow6BuaCBkYXRhIGZyYW1lIMSR4buDIGTDuW5nIGdncGxvdDINCmxvYW5fZGYgPC0gYXMuZGF0YS5mcmFtZShsb2FuX3Byb3ApDQpjb2xuYW1lcyhsb2FuX2RmKSA8LSBjKCJMb2FuIiwgIlByb3BvcnRpb24iKQ0KDQojIFTDrW5oIHBo4bqnbiB0csSDbSDEkeG7gyBoaeG7g24gdGjhu4sgbmjDo24NCmxvYW5fZGYkUGVyY2VudCA8LSBwYXN0ZTAocm91bmQobG9hbl9kZiRQcm9wb3J0aW9uICogMTAwLCAxKSwgIiUiKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIHRyw7JuIGLhurFuZyBnZ3Bsb3QyDQpnZ3Bsb3QobG9hbl9kZiwgYWVzKHggPSAiIiwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBMb2FuKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxKSArDQogIGNvb3JkX3BvbGFyKCJ5IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gUGVyY2VudCksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHZheSB0acOqdSBkw7luZyIsIHggPSBOVUxMLCB5ID0gTlVMTCkgKw0KICB0aGVtZV92b2lkKCkrDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCg0KKipE4buxYSB2w6BvIGLhuqNuZyB04bqnbiBz4buRLCB04bqnbiBzdeG6pXQgdsOgIGJp4buDdSDEkeG7kyBj4bunYSBiaeG6v24gbG9hbiwgdGEgY8OzIGPDoWMgbmjhuq1uIMSR4buLbmggc2F1OioqDQoNCi0gTmjDs20ga2jDtG5nIHZheSB0acOqdSBkw7luZyAobm8pIGNoaeG6v20gc+G7kSBsxrDhu6NuZyBs4bubbiB2xrDhu6N0IHRy4buZaSB24bubaSAzLjgzMCBuZ8aw4budaSwgdMawxqFuZyDhu6luZyBraG/huqNuZyA4NC43JSB04buVbmcgc+G7kSBt4bqrdS4gxJDDonkgbMOgIG5ow7NtIGNoaeG6v20gxrB1IHRo4bq/IHLDtSBy4buHdC4NCg0KLSBOaMOzbSBjw7MgdmF5IHRpw6p1IGTDuW5nICh5ZXMpIGNo4buJIGPDsyA2OTEgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgMTUuMyUuDQoNCioqS+G6v3QgbHXhuq1uOioqDQoNClBow6JuIGLhu5EgdmF5IHRpw6p1IGTDuW5nIGNobyB0aOG6pXkgxJFhIHPhu5Ega2jDoWNoIGjDoG5nIGtow7RuZyBz4butIGThu6VuZyBow6xuaCB0aOG7qWMgdmF5IHRpw6p1IGTDuW5nLCBwaOG6o24gw6FuaCBz4buxIHRo4bqtbiB0cuG7jW5nIHRyb25nIGNoaSB0acOqdSBob+G6t2MgdGnhur9wIGPhuq1uIGjhuqFuIGNo4bq/IHbhu5tpIGxv4bqhaSBow6xuaCB0w61uIGThu6VuZyBuw6B5LiBZ4bq/dSB04buRIG7DoHkgY8OzIHRo4buDIMSRw7NuZyB2YWkgdHLDsiB0cm9uZyB2aeG7h2MgeMOhYyDEkeG7i25oIG3hu6ljIMSR4buZIHRpw6p1IGTDuW5nIGPDoSBuaMOibiB2w6Aga2jhuqMgbsSDbmcgdGnhur9wIGPhuq1uIHTDrW4gZOG7pW5nIHRpw6p1IGTDuW5nIHRyb25nIG5naGnDqm4gY+G7qXUgaMOgbmggdmkgdMOgaSBjaMOtbmguDQoNCg0KDQojIyAqKlRo4buRbmcga8OqIG3DtCB04bqjIGJp4bq/biDEkeG7mWMgbOG6rXAqKg0KDQojIyMgKipCaeG6v24gSG91c2luZyoqDQoNCioqTOG6rXAgYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KdGFibGUoZGF0YTEkaG91c2luZykNCnByb3AudGFibGUodGFibGUoZGF0YTEkaG91c2luZykpDQpgYGANCg0KDQoqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0KioNCg0KYGBge3J9DQpmcmVxX2hvdXNpbmcgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShkYXRhMSRob3VzaW5nKSkNCmNvbG5hbWVzKGZyZXFfaG91c2luZykgPC0gYygiSG91c2luZyIsICJDb3VudCIpDQoNCmdncGxvdChmcmVxX2hvdXNpbmcsIGFlcyh4ID0gSG91c2luZywgeSA9IENvdW50KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiM2NkNEQUEiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC41KSArDQogIGxhYnModGl0bGUgPSAiVOG6p24gc+G7kSB2YXkgbXVhIG5ow6AiLCB4ID0gIlZheSBuaMOgIiwgeSA9ICJT4buRIGzGsOG7o25nIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0DQpob3VzaW5nX2ZyZXEgPC0gdGFibGUoZGF0YTEkaG91c2luZykNCmhvdXNpbmdfcHJvcCA8LSBwcm9wLnRhYmxlKGhvdXNpbmdfZnJlcSkNCg0KIyBDaHV54buDbiBzYW5nIGRhdGEgZnJhbWUgxJHhu4MgduG6vSB24bubaSBnZ3Bsb3QyDQpob3VzaW5nX2RmIDwtIGFzLmRhdGEuZnJhbWUoaG91c2luZ19wcm9wKQ0KY29sbmFtZXMoaG91c2luZ19kZikgPC0gYygiSG91c2luZyIsICJQcm9wb3J0aW9uIikNCg0KIyBUaMOqbSBj4buZdCBwaOG6p24gdHLEg20gxJHhu4MgbMOgbSBuaMOjbg0KaG91c2luZ19kZiRQZXJjZW50IDwtIHBhc3RlMChyb3VuZChob3VzaW5nX2RmJFByb3BvcnRpb24gKiAxMDAsIDEpLCAiJSIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgdHLDsm4NCmdncGxvdChob3VzaW5nX2RmLCBhZXMoeCA9ICIiLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEhvdXNpbmcpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBQZXJjZW50KSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICsNCiAgbGFicyh0aXRsZSA9ICJ04bu3IGzhu4cgdmF5IG11YSBuaMOgIiwgeCA9IE5VTEwsIHkgPSBOVUxMKSArDQogIHRoZW1lX3ZvaWQoKQ0KdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KKipE4buxYSB2w6BvIGLhuqNuZyB04bqnbiBz4buRLCB04bqnbiBzdeG6pXQgdsOgIGJp4buDdSDEkeG7kyBj4bunYSBiaeG6v24gaG91c2luZywgdGEgY8OzIGPDoWMgbmjhuq1uIMSR4buLbmggc2F1OioqDQoNCi0gTmjDs20gY8OzIHZheSBtdWEgbmjDoCAoeWVzKSBjaGnhur9tIHThu7cgbOG7hyBjYW8gaMahbiB24bubaSAyLDU1OSBuZ8aw4budaSwgdMawxqFuZyDhu6luZyBraG/huqNuZyA1Ni42JSB04buVbmcgc+G7kSBt4bqrdS4gxJDDonkgbMOgIG5ow7NtIGNoaeG6v20gdOG7tyB0cuG7jW5nIGzhu5tuIHRyb25nIHThuq1wIGThu68gbGnhu4d1Lg0KDQotIE5ow7NtIGtow7RuZyB2YXkgbXVhIG5ow6AgKG5vKSBjw7MgMSw5NjIgbmfGsOG7nWksIGNoaeG6v20ga2hv4bqjbmcgNDMuNCUuDQoNCioqS+G6v3QgbHXhuq1uOioqDQoNClBow6JuIGLhu5EgZOG7ryBsaeG7h3UgY2hvIHRo4bqleSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIHRyb25nIHThuq1wIGThu68gbGnhu4d1IGPDsyBraG/huqNuIHZheSBtdWEgbmjDoC4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBwaOG6o24gw6FuaCBuaHUgY+G6p3UgduG7gSBuaMOgIOG7nyBjxaluZyBuaMawIG3hu6ljIMSR4buZIHRp4bq/cCBj4bqtbiB0w61uIGThu6VuZyBtdWEgYuG6pXQgxJHhu5luZyBz4bqjbiBj4bunYSBraMOhY2ggaMOgbmcgdHJvbmcgdOG6rXAgbeG6q3UuDQoNCg0KIyMjICoqQmnhur9uIEpvYioqDQoNCioqTOG6rXAgYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KI0LhuqNuZyB04bqnbiBz4buRDQp0YWJsZShkYXRhMSRqb2IpDQojQuG6o25nIHThuqduIHN14bqldA0KdGFibGUoZGF0YTEkam9iKS9zdW0odGFibGUoZGF0YTEkam9iKSkNCmBgYA0KDQoqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0KioNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc+G7kSBjaG8gYmnhur9uIGpvYg0KZnJlcTEgPC0gdGFibGUoZGF0YTEkam9iKQ0KDQojIENodXnhu4NuIHRow6BuaCBkYXRhIGZyYW1lDQpqb2JfZnJlcSA8LSBhcy5kYXRhLmZyYW1lKGZyZXExKQ0KY29sbmFtZXMoam9iX2ZyZXEpIDwtIGMoIkpvYiIsICJDb3VudCIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQNCmdncGxvdChqb2JfZnJlcSwgYWVzKHggPSBKb2IsIHkgPSBDb3VudCkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjNjQ5NUVEIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiVOG6p24gc+G7kSB0aGVvIG5naOG7gSBuZ2hp4buHcCIsIHggPSAiTmdo4buBIG5naGnhu4dwIiwgeSA9ICJT4buRIGzGsOG7o25nIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpIA0KYGBgDQoNCioqROG7sWEgdsOgbyBi4bqjbmcgdOG6p24gc+G7kSB2w6AgYmnhu4N1IMSR4buTIHRyw6puLCB0YSBjw7MgY8OhYyBuaOG6rW4gxJHhu4tuaCBzYXU6KioNCg0KDQotIE5naOG7gSBuZ2hp4buHcCBwaOG7lSBiaeG6v24gbmjhuqV0IGzDoCBtYW5hZ2VtZW50IHbhu5tpIDk2OSBuZ8aw4budaSwgY2hp4bq/bSBraG/huqNuZyAyMS40JSB04buVbmcgc+G7kSBt4bqrdS4NCg0KLSBUaGVvIHNhdSBsw6AgYmx1ZS1jb2xsYXIgKDk0NiBuZ8aw4budaSwgfjIwLjklKSB2w6AgdGVjaG5pY2lhbiAoNzY4IG5nxrDhu51pLCB+MTcuMCUpLg0KDQotIEPDoWMgbmjDs20gbmdo4buBIMOtdCBwaOG7lSBiaeG6v24gaMahbiBn4buTbTogc3R1ZGVudCAoODQgbmfGsOG7nWksIH4xLjklKSB2w6AgdW5rbm93biAoMzggbmfGsOG7nWksIH4wLjglKS4NCg0KLSBU4buVbmcgY+G7mW5nLCBiYSBuaMOzbSBuZ2jhu4EgY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCAobWFuYWdlbWVudCwgYmx1ZS1jb2xsYXIsIHRlY2huaWNpYW4pIMSRw6MgY2hp4bq/bSBoxqFuIDU5JSB0b8OgbiBi4buZIGThu68gbGnhu4d1Lg0KDQoqKkvhur90IGx14bqtbjoqKg0KDQpQaMOibiBi4buRIG5naOG7gSBuZ2hp4buHcCBraMO0bmcgxJHhu4F1LCBjaG8gdGjhuqV5IGPDoWMga2jDoWNoIGjDoG5nIHRyb25nIGThu68gbGnhu4d1IGNo4bunIHnhur91IMSR4bq/biB04burIGPDoWMgbmfDoG5oIHF14bqjbiBsw70sIGxhbyDEkeG7mW5nIHBo4buVIHRow7RuZyB2w6Aga+G7uSB0aHXhuq10IHZpw6puLiANCg0KDQojIyMgKipCaeG6v24gTWFyaXRhbCoqDQoNCioqTOG6rXAgYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KIyBC4bqjbmcgdOG6p24gc+G7kQ0KdGFibGUoZGF0YTEkbWFyaXRhbCkNCiMgQuG6o25nIHThuqduIHN14bqldA0KcHJvcC50YWJsZSh0YWJsZShkYXRhMSRtYXJpdGFsKSkNCmBgYA0KDQoqKlbhur0gYmnhu4N1IMSR4buTIGPhu5l0KioNCg0KYGBge3J9DQojIEJp4buDdSDEkeG7kyBj4buZdA0KbGlicmFyeShnZ3Bsb3QyKQ0KZnJlcV9tYXJpdGFsIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YTEkbWFyaXRhbCkpDQpjb2xuYW1lcyhmcmVxX21hcml0YWwpIDwtIGMoIk1hcml0YWwiLCAiQ291bnQiKQ0KDQpnZ3Bsb3QoZnJlcV9tYXJpdGFsLCBhZXMoeCA9IE1hcml0YWwsIHkgPSBDb3VudCkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjNjQ5NUVEIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuNSkgKw0KICBsYWJzKHRpdGxlID0gIlThuqduIHPhu5EgdGhlbyB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4iLCB4ID0gIlTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiIsIHkgPSAiU+G7kSBsxrDhu6NuZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KKipE4buxYSB2w6BvIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIG1hcml0YWwsIHRhIGPDsyBjw6FjIG5o4bqtbiDEkeG7i25oIHNhdToqKg0KDQotIE5ow7NtIGvhur90IGjDtG4gKG1hcnJpZWQpIGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQsIHbhu5tpIDIsNzk3IG5nxrDhu51pLCB0xrDGoW5nIOG7qW5nIGtob+G6o25nIDYxLjklIHThu5VuZyBz4buRIG3huqt1LiDEkMOieSBsw6AgbmjDs20gY2hp4bq/bSDGsHUgdGjhur8gdsaw4bujdCB0cuG7mWkuDQoNCi0gTmjDs20gxJHhu5ljIHRow6JuIChzaW5nbGUpIGNoaeG6v20gMSwxOTYgbmfGsOG7nWkgKH4yNi41JSksIMSR4bupbmcgdGjhu6kgaGFpIHbhu4EgdOG6p24gc3XhuqV0Lg0KDQotIE5ow7NtIGx5IGjDtG4gKGRpdm9yY2VkKSBjaOG7iSBjaGnhur9tIDUyOCBuZ8aw4budaSAofjExLjclKSwgbMOgIG5ow7NtIGPDsyBz4buRIGzGsOG7o25nIHRo4bqlcCBuaOG6pXQuDQoNCg0KKipL4bq/dCBsdeG6rW46KioNCg0KUGjDom4gYuG7kSB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgbsOgeSBraMOhIGNow6puaCBs4buHY2gsIHbhu5tpIHBo4bqnbiBs4bubbiBraMOhY2ggaMOgbmcgbMOgIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0bi4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBwaOG6o24gw6FuaCB4dSBoxrDhu5tuZyBob+G6t2MgY+G6pXUgdHLDumMgZMOibiBz4buRIGPhu6dhIGtow6FjaCBow6BuZyB0cm9uZyB04bqtcCBk4buvIGxp4buHdS4NCg0KIyMjICoqQmnhur9uIEVkdWNhdGlvbioqDQoNCioqTOG6rXAgYuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KdGFibGUoZGF0YTEkZWR1Y2F0aW9uKQ0KcHJvcC50YWJsZSh0YWJsZShkYXRhMSRlZHVjYXRpb24pKQ0KYGBgDQoNCioqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQqKg0KDQpgYGB7cn0NCmZyZXFfZWR1IDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YTEkZWR1Y2F0aW9uKSkNCmNvbG5hbWVzKGZyZXFfZWR1KSA8LSBjKCJFZHVjYXRpb24iLCAiQ291bnQiKQ0KDQpnZ3Bsb3QoZnJlcV9lZHUsIGFlcyh4ID0gRWR1Y2F0aW9uLCB5ID0gQ291bnQpKSArDQogIGdlb21fY29sKGZpbGwgPSAiI0ZGOTk2NiIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUpICsNCiAgbGFicyh0aXRsZSA9ICJU4bqnbiBz4buRIHRoZW8gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIiwgeCA9ICJUcsOsbmggxJHhu5kiLCB5ID0gIlPhu5EgbMaw4bujbmciKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCg0KKipE4buxYSB2w6BvIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIGVkdWNhdGlvbiwgdGEgY8OzIGPDoWMgbmjhuq1uIMSR4buLbmggc2F1OioqDQoNCi0gTmjDs20gY8OzIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiBzZWNvbmRhcnkgY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCwgduG7m2kgMiwzMDYgbmfGsOG7nWksIHTGsMahbmcg4bupbmcga2hv4bqjbmcgNTEuMCUgdOG7lW5nIHPhu5EgbeG6q3UuIMSQw6J5IGzDoCBuaMOzbSBjaGnhur9tIMawdSB0aOG6vyB2xrDhu6N0IHRy4buZaS4NCg0KLSBOaMOzbSBjw7MgdHLDrG5oIMSR4buZIHRlcnRpYXJ5ICjEkeG6oWkgaOG7jWMsIHNhdSDEkeG6oWkgaOG7jWMpIGPDsyAxLDM1MCBuZ8aw4budaSwgY2hp4bq/bSBraG/huqNuZyAyOS44JSwgxJHhu6luZyB0aOG7qSBoYWkgduG7gSB04bqnbiBzdeG6pXQuDQoNCi0gTmjDs20gcHJpbWFyeSBjw7MgNjc4IG5nxrDhu51pLCB0xrDGoW5nIOG7qW5nIGtob+G6o25nIDE1LjAlIHThu5VuZyBz4buRIG3huqt1Lg0KDQotIE5ow7NtIHVua25vd24gKGtow7RuZyByw7UgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuKSBjaOG7iSBjaGnhur9tIDE4NyBuZ8aw4budaSwgdMawxqFuZyDhu6luZyA0LjElLCBsw6AgbmjDs20gY8OzIHPhu5EgbMaw4bujbmcgdGjhuqVwIG5o4bqldC4NCg0KKipL4bq/dCBsdeG6rW46KioNCg0KUGjDom4gYuG7kSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgY2hvIHRo4bqleSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gdHJ1bmcgaOG7jWMuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgcGjhuqNuIMOhbmggY+G6pXUgdHLDumMgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHBo4buVIGJp4bq/biB0cm9uZyBuaMOzbSBraMOhY2ggaMOgbmcgxJHGsOG7o2Mga2jhuqNvIHPDoXQsIMSR4buTbmcgdGjhu51pIGzDoCB54bq/dSB04buRIGPhuqduIHhlbSB4w6l0IHRyb25nIGPDoWMgcGjDom4gdMOtY2ggbGnDqm4gcXVhbiDEkeG6v24gaMOgbmggdmkgdGnDqnUgZMO5bmcgaG/hurdjIGto4bqjIG7Eg25nIHRp4bq/cCBj4bqtbiBk4buLY2ggduG7pS4NCg0KIyMjICoqQmnhur9uIERlZmF1bHQqKg0KDQoqKkzhuq1wIGLhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQqKg0KDQpgYGB7cn0NCnRhYmxlKGRhdGExJGRlZmF1bHQpDQpwcm9wLnRhYmxlKHRhYmxlKGRhdGExJGRlZmF1bHQpKQ0KYGBgDQoNCioqVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQqKg0KDQpgYGB7cn0NCmZyZXFfZGVmYXVsdCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGExJGRlZmF1bHQpKQ0KY29sbmFtZXMoZnJlcV9kZWZhdWx0KSA8LSBjKCJEZWZhdWx0IiwgIkNvdW50IikNCg0KZ2dwbG90KGZyZXFfZGVmYXVsdCwgYWVzKHggPSBEZWZhdWx0LCB5ID0gQ291bnQpKSArDQogIGdlb21fY29sKGZpbGwgPSAiI0YwODA4MCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjUpICsNCiAgbGFicyh0aXRsZSA9ICJU4bqnbiBz4buRIG7hu6MgdMOtbiBk4bulbmcgeOG6pXUiLCB4ID0gIkRlZmF1bHQiLCB5ID0gIlPhu5EgbMaw4bujbmciKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCioqROG7sWEgdsOgbyBi4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0IGPhu6dhIGJp4bq/biBkZWZhdWx0LCB0YSBjw7MgY8OhYyBuaOG6rW4gxJHhu4tuaCBzYXU6KioNCg0KLSBOaMOzbSBraMO0bmcgY8OzIG7hu6MgdMOtbiBk4bulbmcgeOG6pXUgKG5vKSBjaGnhur9tIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0IHbhu5tpIDQsNDQ1IG5nxrDhu51pLCB0xrDGoW5nIOG7qW5nIGtob+G6o25nIDk4LjQlIHThu5VuZyBz4buRIG3huqt1LiDEkMOieSBsw6AgbmjDs20gY2hp4bq/bSDGsHUgdGjhur8gZ+G6p24gbmjGsCB0dXnhu4d0IMSR4buRaS4NCg0KLSBOaMOzbSBjw7MgbuG7oyB0w61uIGThu6VuZyB44bqldSAoeWVzKSBjaOG7iSBjw7MgNzYgbmfGsOG7nWksIGNoaeG6v20gdOG7tyBs4buHIHLhuqV0IG5o4buPLCBraG/huqNuZyAxLjclLg0KDQoqKkvhur90IGx14bqtbjoqKg0KDQpQaMOibiBi4buRIG7hu6MgdMOtbiBk4bulbmcgeOG6pXUgdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgY2hvIHRo4bqleSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbOG7i2NoIHPhu60gbuG7oyB44bqldS4gxJBp4buBdSBuw6B5IHBo4bqjbiDDoW5oIGNo4bqldCBsxrDhu6NuZyB0w61uIGThu6VuZyB0xrDGoW5nIMSR4buRaSB04buRdCBj4bunYSBuaMOzbSBraMOhY2ggaMOgbmcgxJHGsOG7o2Mga2jhuqNvIHPDoXQuDQoNCiMgKipLaeG7g20gxJHhu4tuaCBjaGkgYsOsbmggcGjGsMahbmcqKg0KDQpLaeG7g20gxJHhu4tuaCBDaGkgYsOsbmggcGjGsMahbmcgKENoaS1zcXVhcmVkIHRlc3QpIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIGtp4buDbSB0cmEgeGVtIGPDsyBt4buRaSBsacOqbiBo4buHIHRo4buRbmcga8OqIGdp4buvYSBoYWkgYmnhur9uIHBow6JuIGxv4bqhaSAoY2F0ZWdvcmljYWwgdmFyaWFibGVzKSBoYXkga2jDtG5nLiBUcm9uZyBi4buRaSBj4bqjbmggbsOgeSwgdGEga2nhu4NtIHRyYSB4ZW0gY8OhYyB54bq/dSB04buRIG5oxrAgaG91c2luZywgbWFyaXRhbCwgZWR1Y2F0aW9uLCBkZWZhdWx0LCB2LnYuIGPDsyDhuqNuaCBoxrDhu59uZyDEkeG6v24gcXV54bq/dCDEkeG7i25oIHZheSB0acOqdSBkw7luZyAobG9hbikgaGF5IGtow7RuZy4NCg0KIyMgKipLaeG7g20gxJHhu4tuaCBnaeG7r2EgbG9hbiB2w6AgaG91c2luZyoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotIEgwOiBLaMO0bmcgY8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGxvYW4gdsOgIGhvdXNpbmcNCi0gSDE6IEPDsyBt4buRaSBsacOqbiBo4buHIGdp4buvYSBsb2FuIHbDoCBob3VzaW5nDQoNCmBgYHtyfQ0KIyBUaOG7sWMgaGnhu4duIGtp4buDbSDEkeG7i25oIENoaSBiw6xuaCBwaMawxqFuZw0KdGFibGVfbG9hbl9ob3VzaW5nIDwtIHRhYmxlKGRhdGExJGxvYW4sIGRhdGExJGhvdXNpbmcpDQpjaGlzcV9ob3VzaW5nIDwtIGNoaXNxLnRlc3QodGFibGVfbG9hbl9ob3VzaW5nKQ0KY2hpc3FfaG91c2luZw0KYGBgDQoNCiMjICoqS2nhu4NtIMSR4buLbmggZ2nhu69hIGxvYW4gdsOgIGpvYioqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotIEgwOiBLaMO0bmcgY8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIG5naOG7gSBuZ2hp4buHcCB2w6Aga2jhuqMgbsSDbmcgdmF5IHRpw6p1IGTDuW5nLg0KLSBIMTogQ8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIG5naOG7gSBuZ2hp4buHcCB2w6Aga2jhuqMgbsSDbmcgdmF5IHRpw6p1IGTDuW5nLg0KDQpgYGB7cn0NCiMgVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBDaGkgYsOsbmggcGjGsMahbmcNCnRhYmxlX2xvYW5fam9iIDwtIHRhYmxlKGRhdGExJGxvYW4sIGRhdGExJGpvYikNCmNoaXNxX2pvYiA8LSBjaGlzcS50ZXN0KHRhYmxlX2xvYW5fam9iKQ0KY2hpc3Ffam9iDQpgYGANCg0KDQojIyAqKktp4buDbSDEkeG7i25oIGdp4buvYSBsb2FuIHbDoCBlZHVjYXRpb24qKg0KDQoqKkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oKioNCg0KLSBIMDogS2jDtG5nIGPDsyBt4buRaSBsacOqbiBo4buHIGdp4buvYSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gdsOgIHF1eeG6v3QgxJHhu4tuaCB2YXkgdGnDqnUgZMO5bmcuDQotIEgxOiBDw7MgbeG7kWkgbGnDqm4gaOG7hyBnaeG7r2EgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHbDoCBxdXnhur90IMSR4buLbmggdmF5IHRpw6p1IGTDuW5nLg0KDQpgYGB7cn0NCnRhYmxlX2xvYW5fZWR1IDwtIHRhYmxlKGRhdGExJGxvYW4sIGRhdGExJGVkdWNhdGlvbikNCmNoaXNxX2VkdSA8LSBjaGlzcS50ZXN0KHRhYmxlX2xvYW5fZWR1KQ0KY2hpc3FfZWR1DQpgYGANCg0KIyMgKipLaeG7g20gxJHhu4tuaCBnaeG7r2EgbG9hbiB2w6AgZGVmYXVsdCoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotIEgwOiBLaMO0bmcgY8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIHTDrG5oIHRy4bqhbmcgbuG7oyBxdcOhIGjhuqFuIHbDoCB2aeG7h2MgdmF5IHRpw6p1IGTDuW5nLg0KLSBIMTogQ8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIHTDrG5oIHRy4bqhbmcgbuG7oyBxdcOhIGjhuqFuIHbDoCB2aeG7h2MgdmF5IHRpw6p1IGTDuW5nLg0KDQpgYGB7cn0NCnRhYmxlX2xvYW5fZGVmYXVsdCA8LSB0YWJsZShkYXRhMSRsb2FuLCBkYXRhMSRkZWZhdWx0KQ0KY2hpc3FfZWR1IDwtIGNoaXNxLnRlc3QodGFibGVfbG9hbl9kZWZhdWx0KQ0KY2hpc3FfZWR1DQpgYGANCg0KIyMgKipLaeG7g20gxJHhu4tuaCBnaeG7r2EgbG9hbiB2w6AgbWFyaXRhbCoqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQotIEgwOiBLaMO0bmcgY8OzIG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiB2w6Agdmnhu4djIHZheSB0acOqdSBkw7luZy4NCi0gSDE6IEPDsyBt4buRaSBsacOqbiBo4buHIGdp4buvYSB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdsOgIHZp4buHYyB2YXkgdGnDqnUgZMO5bmcuDQoNCmBgYHtyfQ0KdGFibGVfbG9hbl9tYXJpdGFsIDwtIHRhYmxlKGRhdGExJGxvYW4sIGRhdGExJG1hcml0YWwpDQpjaGlzcV9lZHUgPC0gY2hpc3EudGVzdCh0YWJsZV9sb2FuX21hcml0YWwpDQpjaGlzcV9lZHUNCmBgYA0KDQpUaMO0bmcgcXVhIGvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIGNo4buJIGPDsyAxIGJp4bq/biBgaG91c2luZ2AgbMOgIGtow7RuZyBjw7MgbeG7kWkgbGnDqm4gaOG7hyB24bubaSBiaeG6v24gYGxvYW5gLCA0IGJp4bq/biDEkeG7mWMgbOG6rXAgY8OybiBs4bqhaSDEkeG7gXUgY8OzIG3hu5FpIGxpw6puIGjhu4cgduG7m2kgYmnhur9uIHBo4bulIHRodeG7mWMgbMOgIGBsb2FuYC4gVGnhur9wIHRoZW8gxJHDsyB0YSBz4bq9IHBow6JuIHTDrWNoIHPDonUgduG7gSB0w6xuaCB0cuG6oW5nIHZheSB0acOqdSBkw7luZyB24bubaSA0IGJp4bq/biDEkeG7mWMgbOG6rXAgbMOgOiBqb2IsIGVkdWNhdGlvbiwgbWFyaXRhbCB2w6AgZGVmYXVsdCB0aMO0bmcgcXVhIHJlbGF0aXZlIHJpc2sgdsOgIG9kZHJhdGlvLg0KDQojICoqUGjDom4gdMOtY2ggc8OidSBow6BuaCB2aSB2YXkgdGnDqnUgZMO5bmcgduG7m2kgUmVsYXRpdmUgUmlzayB2w6AgT2RkcyBSYXRpbyoqDQoNClNhdSBraGkga2nhu4NtIMSR4buLbmggQ2hpIGLDrG5oIHBoxrDGoW5nLCA0IGJp4bq/biDEkeG7i25oIHTDrW5oIGfhu5NtOiBgZWR1Y2F0aW9uYCwgYGRlZmF1bHRgLCBgbWFyaXRhbGAsIHbDoCBgam9iYCDEkcaw4bujYyB4w6FjIMSR4buLbmggbMOgIGPDsyBt4buRaSBsacOqbiBo4buHIHRo4buRbmcga8OqIHbhu5tpIGJp4bq/biBwaOG7pSB0aHXhu5ljIGBsb2FuYC4gQ2jDum5nIHRhIHRp4bq/cCB04bulYyDEkeG6t3QgcmEgKipjw6FjIGPDonUgaOG7j2kgbmdoacOqbiBj4bupdSBj4bulIHRo4buDKiogdsOgIHBow6JuIHTDrWNoIHPDonUgaMahbiBi4bqxbmcgKipSZWxhdGl2ZSBSaXNrKiogdsOgICoqT2RkcyBSYXRpbyoqLg0KDQojIyAqKkVkdWNhdGlvbiDigJMgVHLDrG5oIMSR4buZIGjhu41jIHbhuqVuKioNCg0KTGnhu4d1IGtow6FjaCBow6BuZyBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIGNhbyAodGVydGlhcnkpIGPDsyB4dSBoxrDhu5tuZyB2YXkgdGnDqnUgZMO5bmcgY2FvIGjGoW4gc28gduG7m2kgbmjhu69uZyBuZ8aw4budaSBraMO0bmcgY8OzIGjhu41jIHbhuqVuIGNhbyBob+G6t2Mga2jDtG5nIHLDtSBo4buNYyB24bqlbiBraMO0bmc/DQoNCg0KIyMjICoqR+G7mXAgZOG7ryBsaeG7h3UgdsOgIHThuqFvIGLhuqNuZyB04bqnbiBz4buRKioNCg0KYGBge3J9DQpkYXRhMSRlZHVfZ3JvdXBlZCA8LSBpZmVsc2UoZGF0YTEkZWR1Y2F0aW9uID09ICJ0ZXJ0aWFyeSIsICJoaWdoIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRhdGExJGVkdWNhdGlvbiAlaW4lIGMoInByaW1hcnkiLCAic2Vjb25kYXJ5IiksICJsb3ciLCBOQSkpDQp0YWJsZV9lZHVfZ3JvdXBlZCA8LSB0YWJsZShkYXRhMSRsb2FuLCBkYXRhMSRlZHVfZ3JvdXBlZCkNCnRhYmxlX2VkdV9ncm91cGVkDQpkYXRhMSA8LSBuYS5vbWl0KGRhdGExKQ0KYGBgDQoNCg0KIyMjICoqVuG6vSDEkeG7kyB0aOG7iyBwaMOibiB0w61jaCoqDQpgYGB7cn0NCmRmX2VkdV9ncm91cGVkIDwtIGFzLmRhdGEuZnJhbWUodGFibGVfZWR1X2dyb3VwZWQpDQpjb2xuYW1lcyhkZl9lZHVfZ3JvdXBlZCkgPC0gYygiTG9hbiIsICJFZHVfR3JvdXBlZCIsICJDb3VudCIpDQoNCmdncGxvdChkZl9lZHVfZ3JvdXBlZCwgYWVzKHggPSBFZHVfR3JvdXBlZCwgeSA9IENvdW50LCBmaWxsID0gTG9hbikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlBow6JuIGLhu5EgdmF5IHRpw6p1IGTDuW5nIHRoZW8gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIiwNCiAgICB4ID0gIlRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiIsDQogICAgeSA9ICJT4buRIGzGsOG7o25nIiwNCiAgICBmaWxsID0gIlZheSB0acOqdSBkw7luZyINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCg0KIyMjICoqVMOtbmggUmVsYXRpdmUgUmlzayB2w6AgT2RkIFJhdGlvKioNCg0KYGBge3J9DQptYXRfZWR1X2dyb3VwZWQgPC0gbWF0cml4KGMoDQogIHN1bShkYXRhMSRsb2FuID09ICJubyIgJiBkYXRhMSRlZHVfZ3JvdXBlZCA9PSAibG93IiksDQogIHN1bShkYXRhMSRsb2FuID09ICJubyIgJiBkYXRhMSRlZHVfZ3JvdXBlZCA9PSAiaGlnaCIpLA0KICBzdW0oZGF0YTEkbG9hbiA9PSAieWVzIiAmIGRhdGExJGVkdV9ncm91cGVkID09ICJsb3ciKSwNCiAgc3VtKGRhdGExJGxvYW4gPT0gInllcyIgJiBkYXRhMSRlZHVfZ3JvdXBlZCA9PSAiaGlnaCIpDQopLA0KYnlyb3cgPSBUUlVFLCBucm93ID0gMiwNCmRpbW5hbWVzID0gbGlzdChMb2FuID0gYygibm8iLCAieWVzIiksIEVkdWNhdGlvbiA9IGMoImxvdyIsICJoaWdoIikpKSAgDQoNCm1hdF9lZHVfZ3JvdXBlZA0KDQpycl9lZHVfZ3JvdXBlZCA8LSByaXNrcmF0aW8obWF0X2VkdV9ncm91cGVkKQ0KcnJfZWR1X2dyb3VwZWQkbWVhc3VyZQ0KDQpvcl9lZHVfZ3JvdXBlZCA8LSBvZGRzcmF0aW8obWF0X2VkdV9ncm91cGVkKQ0Kb3JfZWR1X2dyb3VwZWQkbWVhc3VyZQ0KDQpgYGANCg0KVHJvbmcgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gdsOgIGjDoG5oIHZpIHZheSB0acOqdSBkw7luZywgdMOhYyBnaeG6oyBwaMOibiBjaGlhIGtow6FjaCBow6BuZyB0aMOgbmggaGFpIG5ow7NtOg0KDQotIE5ow7NtIGPDsyBo4buNYyB24bqlbiBjYW86IGtow6FjaCBow6BuZyBjw7MgdHLDrG5oIMSR4buZIHRlcnRpYXJ5DQoNCi0gTmjDs20gaOG7jWMgduG6pW4gdGjhuqVwOiBiYW8gZ+G7k20gdHLDrG5oIMSR4buZIHByaW1hcnkgdsOgIHNlY29uZGFyeQ0KDQpTYXUga2hpIHTDrW5oIHRvw6FuIFJlbGF0aXZlIFJpc2sgKFJSKSB2w6AgT2RkcyBSYXRpbyAoT1IpIMSR4buDIHNvIHPDoW5oIHjDoWMgc3XhuqV0IHbDoCBraOG6oyBuxINuZyB2YXkgdGnDqnUgZMO5bmcgZ2nhu69hIGhhaSBuaMOzbSwga+G6v3QgcXXhuqMgY2hvIHRo4bqleSBj4bqjIFJSIHbDoCBPUiDEkeG7gXUgbmjhu48gaMahbiAxIMSRaeG7gXUgxJHDsyBjw7MgbmdoxKlhIGzDoCBraMOhY2ggaMOgbmcgY8OzIGjhu41jIHbhuqVuIGNhbyBjw7MgeHUgaMaw4bubbmcgdmF5IHRpw6p1IGTDuW5nIMOtdCBoxqFuIG5ow7NtIGjhu41jIHbhuqVuIHRo4bqlcC4NCg0KQ+G7pSB0aOG7gzoNCg0KLSBOZ3V5IGPGoSB0xrDGoW5nIMSR4buRaSAoUlIpIGzDoCAwLjc4OTU0ODMsIHThu6ljIGzDoCB4w6FjIHN14bqldCB2YXkgdGnDqnUgZMO5bmcgY+G7p2EgbmjDs20gaOG7jWMgduG6pW4gY2FvIGNo4buJIGLhurFuZyA3OC45NSUgc28gduG7m2kgbmjDs20gaOG7jWMgduG6pW4gdGjhuqVwLg0KLSBU4bu3IHPhu5EgY2jDqm5oIChPUikgbMOgIDAuNzE4MTcyNSwgbmdoxKlhIGzDoCBvZGRzIHZheSB0acOqdSBkw7luZyBj4bunYSBuaMOzbSBo4buNYyB24bqlbiBjYW8gY2jhu4kgYuG6sW5nIDcxLjgyJSBzbyB24bubaSBuaMOzbSBo4buNYyB24bqlbiB0aOG6pXAuDQoNCg0KDQojIyAqKkRlZmF1bHQg4oCTIE7hu6MgdMOtbiBk4bulbmcgcXXDoSBo4bqhbioqDQoNCiMjIyAqKkfhu5lwIGThu68gbGnhu4d1IHbDoCB04bqhbyBi4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCnRhYmxlX2RlZmF1bHQgPC0gdGFibGUoZGF0YTEkbG9hbiwgZGF0YTEkZGVmYXVsdCkNCnRhYmxlX2RlZmF1bHQNCmBgYA0KDQojIyMgKipW4bq9IMSR4buTIHRo4buLIHBow6JuIHTDrWNoKioNCmBgYHtyfQ0KZGZfZGVmYXVsdCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlX2RlZmF1bHQpDQpjb2xuYW1lcyhkZl9kZWZhdWx0KSA8LSBjKCJMb2FuIiwgIkRlZmF1bHQiLCAiQ291bnQiKQ0KDQpnZ3Bsb3QoZGZfZGVmYXVsdCwgYWVzKHggPSBEZWZhdWx0LCB5ID0gQ291bnQsIGZpbGwgPSBMb2FuKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUGjDom4gYuG7kSB2YXkgdGnDqnUgZMO5bmcgdGhlbyB0cuG6oW5nIHRow6FpIG7hu6MgdMOtbiBk4bulbmciLA0KICAgIHggPSAiTuG7oyB0w61uIGThu6VuZyIsDQogICAgeSA9ICJT4buRIGzGsOG7o25nIiwNCiAgICBmaWxsID0gIlZheSB0acOqdSBkw7luZyINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCiMjIyAqKlTDrW5oIFJlbGF0aXZlIFJpc2sgdsOgIE9kZCBSYXRpbyoqDQoNCmBgYHtyfQ0KIyBU4bqhbyBtYSB0cuG6rW4gduG7m2kgbmjDs20gJ3llcycgKHZheSB0acOqdSBkw7luZykgbMOgbSBkw7JuZyB0aOG7qSBuaOG6pXQgPSBuaMOzbSB0aGFtIGNoaeG6v3UNCm1hdF9kZWZhdWx0IDwtIG1hdHJpeChjKA0KICBzdW0oZGF0YTEkbG9hbiA9PSAieWVzIiAmIGRhdGExJGRlZmF1bHQgPT0gInllcyIpLCAgIyBhDQogIHN1bShkYXRhMSRsb2FuID09ICJ5ZXMiICYgZGF0YTEkZGVmYXVsdCA9PSAibm8iKSwgICAjIGINCiAgc3VtKGRhdGExJGxvYW4gPT0gIm5vIiAmIGRhdGExJGRlZmF1bHQgPT0gInllcyIpLCAgICMgYw0KICBzdW0oZGF0YTEkbG9hbiA9PSAibm8iICYgZGF0YTEkZGVmYXVsdCA9PSAibm8iKSAgICAgIyBkDQopLA0KYnlyb3cgPSBUUlVFLCBucm93ID0gMiwNCmRpbW5hbWVzID0gbGlzdChMb2FuID0gYygieWVzIiwgIm5vIiksIERlZmF1bHQgPSBjKCJ5ZXMiLCAibm8iKSkpDQoNCm1hdF9kZWZhdWx0DQoNCiMgVMOtbmggUlIgdsOgIE9SIHbhu5tpIG5ow7NtICd5ZXMnIGzDoG0gdGhhbSBjaGnhur91DQpycl9kZWZhdWx0IDwtIHJpc2tyYXRpbyhtYXRfZGVmYXVsdCkNCnJyX2RlZmF1bHQkbWVhc3VyZQ0KDQpvcl9kZWZhdWx0IDwtIG9kZHNyYXRpbyhtYXRfZGVmYXVsdCkNCm9yX2RlZmF1bHQkbWVhc3VyZQ0KDQpgYGANCg0KDQpUcm9uZyBwaMOibiB0w61jaCBuw6B5LCB0w6FjIGdp4bqjIHhlbSB4w6l0IG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGjDoG5oIHZpIHZheSB0acOqdSBkw7luZyAobG9hbikgdsOgIHTDrG5oIHRy4bqhbmcgbuG7oyB0w61uIGThu6VuZyBxdcOhIGjhuqFuIChkZWZhdWx0KS4gTmjDs20gY8OzIHZheSB0acOqdSBkw7luZyDEkcaw4bujYyBjaOG7jW4gbMOgbSBuaMOzbSB0aGFtIGNoaeG6v3UsIG5o4bqxbSBzbyBzw6FuaCBuZ3V5IGPGoSB2w6Aga2jhuqMgbsSDbmcgbuG7oyB0w61uIGThu6VuZyDhu58gbmjDs20ga2jDtG5nIHZheS4NCg0KKipL4bq/dCBxdeG6oyBuaMawIHNhdToqKg0KDQotIE5ndXkgY8ahIHTGsMahbmcgxJHhu5FpIChSZWxhdGl2ZSBSaXNrIOKAkyBSUikgY+G7p2EgbmjDs20ga2jDtG5nIHZheSBzbyB24bubaSBuaMOzbSBjw7MgdmF5IGzDoCAxLjAyMjQ1MSDihpIgxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIHjDoWMgc3XhuqV0IG7hu6MgdMOtbiBk4bulbmcgcXXDoSBo4bqhbiDhu58gbmjDs20ga2jDtG5nIHZheSBjYW8gaMahbiAyLjI1JSBzbyB24bubaSBuaMOzbSBjw7MgdmF5Lg0KDQotIFThu7cgc+G7kSBjaMOqbmggKE9kZHMgUmF0aW8g4oCTIE9SKSBnaeG7r2EgaGFpIG5ow7NtIGzDoCAyLjY4MDYyOCDihpIgRGnhu4VuIGdp4bqjaSBy4bqxbmcga2jhuqMgbsSDbmcgbuG7oyB0w61uIGThu6VuZyBxdcOhIGjhuqFuIChvZGRzKSDhu58gbmjDs20ga2jDtG5nIHZheSBjYW8gZ+G6pXAgMi42OCBs4bqnbiBzbyB24bubaSBuaMOzbSBjw7MgdmF5Lg0KDQoNClTDs20gbOG6oWksIGPhuqMgUlIgdsOgIE9SIMSR4buBdSBs4bubbiBoxqFuIDEgdsOgIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6osIGNobyB0aOG6pXkgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyB2YXkgdGnDqnUgZMO5bmcgY8OzIG5ndXkgY8ahIHbDoCBraOG6oyBuxINuZyBu4bujIHTDrW4gZOG7pW5nIHF1w6EgaOG6oW4gY2FvIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgbmjDs20gY8OzIHZheSB0acOqdSBkw7luZy4NCg0KIyMgKipNYXJpdGFsIOKAkyBUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4qKg0KDQpLaMOhY2ggaMOgbmcgxJHDoyBr4bq/dCBow7RuIGPDsyB4dSBoxrDhu5tuZyB2YXkgdGnDqnUgZMO5bmcga2jDoWMgduG7m2kgbmfGsOG7nWkgY2jGsGEga+G6v3QgaMO0biBraMO0bmc/DQoNCiMjIyAqKkfhu5lwIGThu68gbGnhu4d1IHbDoCB04bqhbyBi4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCmRhdGExJG1hcml0YWxfZ3JvdXBlZCA8LSBpZmVsc2UoZGF0YTEkbWFyaXRhbCA9PSAibWFycmllZCIsICJtYXJyaWVkIiwgIm90aGVycyIpDQp0YWJsZV9tYXJpdGFsIDwtIHRhYmxlKGRhdGExJGxvYW4sIGRhdGExJG1hcml0YWxfZ3JvdXBlZCkNCnRhYmxlX21hcml0YWwNCmBgYA0KDQoNCiMjIyAqKlbhur0gxJHhu5MgdGjhu4sgcGjDom4gdMOtY2gqKg0KYGBge3J9DQpkZl9tYXJpdGFsIDwtIGFzLmRhdGEuZnJhbWUodGFibGVfbWFyaXRhbCkNCmNvbG5hbWVzKGRmX21hcml0YWwpIDwtIGMoIkxvYW4iLCAiTWFyaXRhbCIsICJDb3VudCIpDQoNCmdncGxvdChkZl9tYXJpdGFsLCBhZXMoeCA9IE1hcml0YWwsIHkgPSBDb3VudCwgZmlsbCA9IExvYW4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJQaMOibiBi4buRIHZheSB0acOqdSBkw7luZyB0aGVvIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiIsDQogICAgeCA9ICJUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4iLA0KICAgIHkgPSAiU+G7kSBsxrDhu6NuZyIsDQogICAgZmlsbCA9ICJWYXkgdGnDqnUgZMO5bmciDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCmBgYA0KDQoNCiMjIyAqKlTDrW5oIFJlbGF0aXZlIFJpc2sgdsOgIE9kZCBSYXRpbyoqDQoNCmBgYHtyfQ0KbWF0X21hcml0YWwgPC0gbWF0cml4KGMoDQogIHN1bShkYXRhMSRsb2FuID09ICJ5ZXMiICYgZGF0YTEkbWFyaXRhbF9ncm91cGVkID09ICJtYXJyaWVkIiksDQogIHN1bShkYXRhMSRsb2FuID09ICJ5ZXMiICYgZGF0YTEkbWFyaXRhbF9ncm91cGVkID09ICJvdGhlcnMiKSwNCiAgc3VtKGRhdGExJGxvYW4gPT0gIm5vIiAmIGRhdGExJG1hcml0YWxfZ3JvdXBlZCA9PSAibWFycmllZCIpLA0KICBzdW0oZGF0YTEkbG9hbiA9PSAibm8iICYgZGF0YTEkbWFyaXRhbF9ncm91cGVkID09ICJvdGhlcnMiKQ0KKSwNCmJ5cm93ID0gVFJVRSwgbnJvdyA9IDIsDQpkaW1uYW1lcyA9IGxpc3QoTG9hbiA9IGMoInllcyIsICJubyIpLCBNYXJpdGFsID0gYygibWFycmllZCIsICJvdGhlcnMiKSkpDQoNCm1hdF9tYXJpdGFsDQoNCnJyX21hcml0YWwgPC0gcmlza3JhdGlvKG1hdF9tYXJpdGFsKQ0KcnJfbWFyaXRhbCRtZWFzdXJlDQoNCm9yX21hcml0YWwgPC0gb2Rkc3JhdGlvKG1hdF9tYXJpdGFsKQ0Kb3JfbWFyaXRhbCRtZWFzdXJlDQoNCmBgYA0KDQpUcm9uZyBwaMOibiB0w61jaCBuw6B5LCBraMOhY2ggaMOgbmcgxJHGsOG7o2MgY2hpYSB0aMOgbmggaGFpIG5ow7NtOiDEkcOjIGvhur90IGjDtG4gKG1hcnJpZWQpIHbDoCBraMOhYyAob3RoZXJzIOKAkyBiYW8gZ+G7k20gxJHhu5ljIHRow6JuLCBseSBow7Ru4oCmKS4gTmjDs20ga2jDoWNoIGjDoG5nIGPDsyB2YXkgdGnDqnUgZMO5bmcgKExvYW4gPSB5ZXMpIMSRxrDhu6NjIGNo4buNbiBsw6BtIG5ow7NtIHRoYW0gY2hp4bq/dS4NCg0KKipL4bq/dCBxdeG6oyBjaG8gdGjhuqV5KiogDQoNCi0gTmd1eSBjxqEgdMawxqFuZyDEkeG7kWkgKFJSKSBj4bunYSBuaMOzbSBraMO0bmcgdmF5IHRpw6p1IGTDuW5nIHNvIHbhu5tpIG5ow7NtIHZheSB0acOqdSBkw7luZyBsw6AgMS4xMjYsIG5naMSpYSBsw6AgeMOhYyBzdeG6pXQga2jDtG5nIHZheSB0acOqdSBkw7luZyBj4bunYSBuaMOzbSBjaMawYSBr4bq/dCBow7RuIGNhbyBoxqFuIDEyLjYlIHNvIHbhu5tpIG5ow7NtIMSRw6Mga+G6v3QgaMO0bi4gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBsw6AgWzEuMDA4IDsgMS4yNThdLCBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCi0gVMawxqFuZyB04buxLCB04bu3IHPhu5EgY2jDqm5oIChPUikgbMOgIDEuMjA1NiwgdOG7qWMgbMOgIG9kZHMga2jDtG5nIHZheSB0acOqdSBkw7luZyBj4bunYSBuaMOzbSBjaMawYSBr4bq/dCBow7RuIGNhbyBoxqFuIGtob+G6o25nIDIwLjU2JSBzbyB24bubaSBuaMOzbSDEkcOjIGvhur90IGjDtG4uIEtob+G6o25nIHRpbiBj4bqteSA5NSUgbMOgIFsxLjAxNyA7IDEuNDMyXSwgdGnhur9wIHThu6VjIGto4bqzbmcgxJHhu4tuaCBr4bq/dCBxdeG6oyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLg0KDQpOaMawIHbhuq15LCBraMOhY2ggaMOgbmcgxJHDoyBr4bq/dCBow7RuIGPDsyB4dSBoxrDhu5tuZyB2YXkgdGnDqnUgZMO5bmcgbmhp4buBdSBoxqFuIHNvIHbhu5tpIG5ow7NtIGNoxrBhIGvhur90IGjDtG4uDQoNCiMjICoqSm9iIOKAkyBOZ2jhu4EgbmdoaeG7h3AqKg0KDQpMaeG7h3UgbmjDs20gbmfGsOG7nWkgdGjhuqV0IG5naGnhu4dwIGPDsyB4dSBoxrDhu5tuZyB2YXkgdGnDqnUgZMO5bmcga2jDoWMgYmnhu4d0IHNvIHbhu5tpIGPDoWMgbmjDs20gbmdo4buBIGPDsm4gbOG6oWkga2jDtG5nPw0KDQojIyMgKipH4buZcCBk4buvIGxp4buHdSB2w6AgdOG6oW8gYuG6o25nIHThuqduIHPhu5EqKg0KYGBge3J9DQpkYXRhMSRqb2JfZ3JvdXBlZCA8LSBpZmVsc2UoZGF0YTEkam9iID09ICJ1bmVtcGxveWVkIiwgInVuZW1wbG95ZWQiLCAib3RoZXJzIikNCnRhYmxlX2pvYiA8LSB0YWJsZShkYXRhMSRsb2FuLCBkYXRhMSRqb2JfZ3JvdXBlZCkNCnRhYmxlX2pvYg0KYGBgDQoNCg0KIyMjICoqVuG6vSDEkeG7kyB0aOG7iyBwaMOibiB0w61jaCoqDQpgYGB7cn0NCmRmX2pvYiA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlX2pvYikNCmNvbG5hbWVzKGRmX2pvYikgPC0gYygiTG9hbiIsICJKb2JfR3JvdXAiLCAiQ291bnQiKQ0KDQpnZ3Bsb3QoZGZfam9iLCBhZXMoeCA9IEpvYl9Hcm91cCwgeSA9IENvdW50LCBmaWxsID0gTG9hbikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlBow6JuIGLhu5EgdmF5IHRpw6p1IGTDuW5nIHRoZW8gbmdo4buBIG5naGnhu4dwICh0aOG6pXQgbmdoaeG7h3AgdnMgY8OybiBs4bqhaSkiLA0KICAgIHggPSAiTmjDs20gbmdo4buBIG5naGnhu4dwIiwNCiAgICB5ID0gIlPhu5EgbMaw4bujbmciLA0KICAgIGZpbGwgPSAiVmF5IHRpw6p1IGTDuW5nIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KDQoNCiMjIyAqKlTDrW5oIFJlbGF0aXZlIFJpc2sgdsOgIE9kZCBSYXRpbyoqDQoNCmBgYHtyfQ0KbWF0X2pvYiA8LSBtYXRyaXgoYygNCiAgc3VtKGRhdGExJGxvYW4gPT0gInllcyIgJiBkYXRhMSRqb2JfZ3JvdXBlZCA9PSAidW5lbXBsb3llZCIpLA0KICBzdW0oZGF0YTEkbG9hbiA9PSAibm8iICYgZGF0YTEkam9iX2dyb3VwZWQgPT0gInVuZW1wbG95ZWQiKSwNCiAgc3VtKGRhdGExJGxvYW4gPT0gInllcyIgJiBkYXRhMSRqb2JfZ3JvdXBlZCA9PSAib3RoZXJzIiksDQogIHN1bShkYXRhMSRsb2FuID09ICJubyIgJiBkYXRhMSRqb2JfZ3JvdXBlZCA9PSAib3RoZXJzIikNCiksDQpieXJvdyA9IFRSVUUsIG5yb3cgPSAyLA0KZGltbmFtZXMgPSBsaXN0KExvYW4gPSBjKCJ5ZXMiLCAibm8iKSwgSm9iID0gYygidW5lbXBsb3llZCIsICJvdGhlcnMiKSkpDQoNCm1hdF9qb2INCg0KcnJfam9iIDwtIHJpc2tyYXRpbyhtYXRfam9iKQ0KcnJfam9iJG1lYXN1cmUNCg0Kb3Jfam9iIDwtIG9kZHNyYXRpbyhtYXRfam9iKQ0Kb3Jfam9iJG1lYXN1cmUNCmBgYA0KDQoNClRyb25nIHBow6JuIHTDrWNoIG7DoHksIGtow6FjaCBow6BuZyDEkcaw4bujYyBjaGlhIHRow6BuaCBoYWkgbmjDs20gbmdo4buBIG5naGnhu4dwOiB0aOG6pXQgbmdoaeG7h3AgKHVuZW1wbG95ZWQpIHbDoCBjw6FjIG5ow7NtIG5naOG7gSBjw7JuIGzhuqFpIChvdGhlcnMpLiBOaMOzbSBraMOhY2ggaMOgbmcgY8OzIHZheSB0acOqdSBkw7luZyAoTG9hbiA9IHllcykgxJHGsOG7o2MgY2jhu41uIGzDoG0gbmjDs20gdGhhbSBjaGnhur91Lg0KDQoqKkvhur90IHF14bqjIGNobyB0aOG6pXkqKg0KDQotIE5ndXkgY8ahIHTGsMahbmcgxJHhu5FpIChSUikgbMOgIDAuOTM3MiwgbmdoxKlhIGzDoCB4w6FjIHN14bqldCBraMO0bmcgdmF5IHRpw6p1IGTDuW5nIGPhu6dhIG5ow7NtIGPDsm4gbOG6oWkgY2jhu4kgYuG6sW5nIDkzLjcyJSBzbyB24bubaSBuaMOzbSB0aOG6pXQgbmdoaeG7h3AuIEtob+G6o25nIHRpbiBj4bqteSA5NSUgbMOgIFswLjg4MjEgOyAwLjk5NTldLCBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCi0gVHJvbmcga2hpIMSRw7MsIHThu7cgc+G7kSBjaMOqbmggKE9SKSBsw6AgMC42MTMxLCB04bupYyBsw6Agb2RkcyBraMO0bmcgdmF5IHRpw6p1IGTDuW5nIGPhu6dhIG5ow7NtIG5naOG7gSBuZ2hp4buHcCBjw7JuIGzhuqFpIHRo4bqlcCBoxqFuIGtob+G6o25nIDM4LjclIHNvIHbhu5tpIG5ow7NtIHRo4bqldCBuZ2hp4buHcC4gVHV5IG5oacOqbiwga2hv4bqjbmcgdGluIGPhuq15IDk1JSBsw6AgWzAuMzI2NCA7IDEuMDU1MF0sIGPDsyBjaOG7qWEgMSwgbsOqbiBr4bq/dCBxdeG6oyBuw6B5IGNoxrBhIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGvhur90IGx14bqtbiBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgdGjhu5FuZyBrw6og4bufIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KTmjGsCB24bqteSwgY8OzIHRo4buDIGvhur90IGx14bqtbiBy4bqxbmcgbmjDs20ga2jDoWNoIGjDoG5nIHRo4bqldCBuZ2hp4buHcCBjw7MgeHUgaMaw4bubbmcga2jDtG5nIHZheSB0acOqdSBkw7luZyBjYW8gaMahbiBzbyB24bubaSBjw6FjIG5ow7NtIG5naOG7gSBjw7JuIGzhuqFpLCB2w6Agc+G7sSBraMOhYyBiaeG7h3QgbsOgeSBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIGtoaSB4w6l0IHRoZW8gUlIsIG5oxrBuZyBjaMawYSByw7UgcsOgbmcgdGhlbyBPUi4NCg0KDQotLS0NCg0KIyAqKkjhu5NpIHF1eSBMb2dpc3RpYyoqDQoNClNhdSBraGkgdGjhu7FjIGhp4buHbiBwaMOibiB0w61jaCBuZ3V5IGPGoSB0xrDGoW5nIMSR4buRaSAoUmVsYXRpdmUgUmlzaykgdsOgIHThu7cgc+G7kSBjaMOqbmggKE9kZHMgUmF0aW8pIMSR4buDIGtow6FtIHBow6EgbeG7kWkgbGnDqm4gaOG7hyBnaeG7r2EgaMOgbmggdmkgdmF5IHRpw6p1IGTDuW5nIHbhu5tpIHThu6tuZyBiaeG6v24gxJHhu5ljIGzhuq1wLCBixrDhu5tjIHRp4bq/cCB0aGVvIGzDoCB4w6J5IGThu7FuZyBtw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljIG5o4bqxbSDEkcOhbmggZ2nDoSDEkeG7k25nIHRo4budaSB0w6FjIMSR4buZbmcgY+G7p2EgY8OhYyB54bq/dSB04buRIG7DoHkgxJHhur9uIGto4bqjIG7Eg25nIHZheSB0acOqdSBkw7luZyBj4bunYSBraMOhY2ggaMOgbmcuDQoNCg0KYGBge3J9DQojIEjhu5NpIHF1eSBsb2dpc3RpYw0KbW9kZWxfbG9naXQgPC0gZ2xtKGxvYW4gfiBqb2IgKyBlZHVjYXRpb24gKyBtYXJpdGFsICsgZGVmYXVsdCwNCiAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YTEsDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwpDQoNCiMgVMOzbSB04bqvdCBr4bq/dCBxdeG6ow0Kc3VtbWFyeShtb2RlbF9sb2dpdCkNCmBgYA0KDQpUcm9uZyBtw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljLCBt4buXaSBo4buHIHPhu5EgKGNvZWZmaWNpZW50KSBwaOG6o24gw6FuaCBsb2cgb2RkcyBj4bunYSBraOG6oyBuxINuZyB44bqjeSByYSBz4buxIGtp4buHbiBxdWFuIHTDom0gKOG7nyDEkcOieSBsw6AgdmF5IHRpw6p1IGTDuW5nKSBraGkgYmnhur9uIMSR4buZYyBs4bqtcCB0aGF5IMSR4buVaSwgc28gduG7m2kgbmjDs20gdGhhbSBjaGnhur91IHbDoCBnaeG7ryBjw6FjIGJp4bq/biBraMOhYyBraMO0bmcgxJHhu5VpLiBDw6FjIGjhu4cgc+G7kSBkxrDGoW5nIGNobyB0aOG6pXkgeMOhYyBzdeG6pXQgdmF5IHTEg25nLCB0cm9uZyBraGkgaOG7hyBz4buRIMOibSBjaG8gdGjhuqV5IHjDoWMgc3XhuqV0IHZheSBnaeG6o20uDQoNCioqQmnhur9uIGVkdWNhdGlvbiDigJMgVHLDrG5oIMSR4buZIGjhu41jIHbhuqVuKioNCg0KLSBlZHVjYXRpb25zZWNvbmRhcnkgKGjhu4cgc+G7kSA9IDAuMzMxLCBwID0gMC4wMTUpOg0K4oaSIFNvIHbhu5tpIGtow6FjaCBow6BuZyBo4buNYyB0aeG7g3UgaOG7jWMsIG5ow7NtIGPDsyB0csOsbmggxJHhu5kgdHJ1bmcgaOG7jWMgY8OzIGxvZyBvZGRzIHZheSB0acOqdSBkw7luZyBjYW8gaMahbiAwLjMzMSDEkcahbiB24buLLg0K4oaSIE7hur91IGNodXnhu4NuIMSR4buVaSBzYW5nIG9kZHMgcmF0aW86IGV4cCgwLjMzMSkg4omIIDEuMzksIG5naMSpYSBsw6AgbmjDs20gaOG7jWMgduG6pW4gdHJ1bmcgaOG7jWMgY8OzIG9kZHMgdmF5IGNhbyBoxqFuIDM5JSBzbyB24bubaSBuaMOzbSBo4buNYyB24bqlbiB0aeG7g3UgaOG7jWMuDQrihpIgS+G6v3QgbHXhuq1uOiBUcsOsbmggxJHhu5kgaOG7jWMgduG6pW4gdHJ1bmcgaOG7jWMgY8OzIOG6o25oIGjGsOG7n25nIHTDrWNoIGPhu7FjIHbDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIMSR4bq/biBow6BuaCB2aSB2YXkgdGnDqnUgZMO5bmcuDQoNCi0gZWR1Y2F0aW9udGVydGlhcnkgKGjhu4cgc+G7kSA9IDAuMDYwLCBwID0gMC43MjYpOg0K4oaSIEtow6FjIGJp4buHdCBraMO0bmcgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4gT2RkcyBj4bunYSBuaMOzbSBjw7MgdHLDrG5oIMSR4buZIMSR4bqhaSBo4buNYyBraMO0bmcga2jDoWMgxJHDoW5nIGvhu4Mgc28gduG7m2kgbmjDs20gdGnhu4N1IGjhu41jLg0KDQoNCioqQmnhur9uIGpvYiDigJMgTmdo4buBIG5naGnhu4dwKioNCg0KQmnhur9uIG7DoHkgZ+G7k20gbmhp4buBdSBuaMOzbSBzbyBzw6FuaCB24bubaSBuaMOzbSB0aGFtIGNoaeG6v3UgbMOgIOKAnGFkbWluLuKAnToNCg0KLSBqb2JlbnRyZXByZW5ldXIgKGjhu4cgc+G7kSA9IDAuNDQ4LCBwID0gMC4wNDYpOg0K4oaSIExvZyBvZGRzIHZheSB0xINuZyAwLjQ0OCBzbyB24bubaSBuaMOzbSBhZG1pbiDihpIgb2RkcyB0xINuZyBraG/huqNuZyA1Ni41JSAoZXhwKDAuNDQ4KSDiiYggMS41NjUpLg0K4oaSIEvhur90IGx14bqtbjogTmfGsOG7nWkgdOG7sSBkb2FuaCBjw7MgeHUgaMaw4bubbmcgdmF5IGNhbyBoxqFuIG5ow6JuIHZpw6puIGjDoG5oIGNow61uaCB2w6Agc+G7sSBraMOhYyBiaeG7h3QgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4NCg0KLSBqb2JzdHVkZW50ICho4buHIHPhu5EgPSAtMi41ODcsIHAgPSAwLjAxMSk6DQrihpIgSOG7hyBz4buRIMOibSBs4bubbiB2w6AgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqjogb2RkcyB2YXkgZ2nhuqNtIGtob+G6o25nIDkyJSAoZXhwKC0yLjU4Nykg4omIIDAuMDc1KS4NCuKGkiBL4bq/dCBsdeG6rW46IFNpbmggdmnDqm4gY8OzIHjDoWMgc3XhuqV0IHZheSB0acOqdSBkw7luZyB0aOG6pXAgaMahbiBy4bqldCBuaGnhu4F1LCDEkcOieSBsw6Aga+G6v3QgcXXhuqMgY8OzIMO9IG5naMSpYSB0aOG7sWMgdGnhu4VuIG3huqFuaC4NCg0KLSBqb2J1bmVtcGxveWVkICho4buHIHPhu5EgPSAtMC42ODgsIHAgPSAwLjAzMCk6DQrihpIgR2nhuqNtIG9kZHMgdmF5IHRpw6p1IGTDuW5nIGtob+G6o25nIDUwJSAoZXhwKC0wLjY4OCkg4omIIDAuNTAzKS4NCuKGkiBL4bq/dCBsdeG6rW46IE5nxrDhu51pIHRo4bqldCBuZ2hp4buHcCBjxaluZyBjw7MgeHUgaMaw4bubbmcgdmF5IHRo4bqlcCBoxqFuLCB24bubaSBt4bupYyBnaeG6o20gY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4NCg0KQ8OhYyBuaMOzbSBraMOhYyBuaMawIGJsdWUtY29sbGFyLCByZXRpcmVkLCBob3VzZW1haWQsIHRlY2huaWNpYW4sIHVua25vd24uLi4gxJHhu4F1IGtow7RuZyBjw7MgaOG7hyBz4buRIMO9IG5naMSpYSB0aOG7kW5nIGvDqiAocCA+IDAuMDUpLCB04bupYyBsw6Aga2jDtG5nIGPDsyBi4bqxbmcgY2jhu6luZyBt4bqhbmggbeG6vSBjaG8gdGjhuqV5IGjhu40ga2jDoWMgYmnhu4d0IHbhu4EgaMOgbmggdmkgdmF5IHNvIHbhu5tpIG5ow7NtIGFkbWluLg0KDQoNCioqQmnhur9uIG1hcml0YWwg4oCTIFTDrG5oIHRy4bqhbmcgaMO0biBuaMOibioqDQoNCk5ow7NtIHRoYW0gY2hp4bq/dSBsw6AgxJHDoyBseSBow7RuIChkaXZvcmNlZCk6DQoNCi0gbWFyaXRhbHNpbmdsZSAoaOG7hyBz4buRID0gLTAuMzM1LCBwID0gMC4wMjUpOg0K4oaSIE9kZHMgZ2nhuqNtIGtob+G6o25nIDI4JSAoZXhwKC0wLjMzNSkg4omIIDAuNzE1KS4NCuKGkiBOZ8aw4budaSDEkeG7mWMgdGjDom4gY8OzIHh1IGjGsOG7m25nIHZheSB0acOqdSBkw7luZyB0aOG6pXAgaMahbiBzbyB24bubaSBuZ8aw4budaSDEkcOjIGx5IGjDtG4sIHbDoCBz4buxIGtow6FjIGJp4buHdCBuw6B5IGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCi0gbWFycmllZCAoaOG7hyBz4buRID0gLTAuMDcyLCBwID0gMC41ODEpOg0K4oaSIEtow7RuZyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIOKGkiBraMO0bmcgdGjhu4Mga+G6v3QgbHXhuq1uIGPDsyBz4buxIGtow6FjIGJp4buHdCB24bubaSBuZ8aw4budaSBseSBow7RuLg0KDQoNCioqQmnhur9uIGRlZmF1bHQg4oCTIE7hu6MgdMOtbiBk4bulbmcgcXXDoSBo4bqhbioqDQoNCmRlZmF1bHR5ZXMgKGjhu4cgc+G7kSA9IDAuOTM3LCBwIDwgMC4wMDEpOg0K4oaSIEzDoCBt4buZdCB0cm9uZyBuaOG7r25nIGJp4bq/biBxdWFuIHRy4buNbmcgbmjhuqV0IGPhu6dhIG3DtCBow6xuaC4NCuKGkiBPZGRzIHTEg25nIGfhuqVwIDIuNTUgbOG6p24gc28gduG7m2kgbmfGsOG7nWkga2jDtG5nIG7hu6MgKGV4cCgwLjkzNykg4omIIDIuNTUyKS4NCuKGkiBL4bq/dCBsdeG6rW46IEtow6FjaCBow6BuZyBjw7MgbOG7i2NoIHPhu60gbuG7oyB44bqldSBjw7Mga2jhuqMgbsSDbmcgdmF5IGNhbyBoxqFuIG5oaeG7gXUg4oCUIMSRaeG7gXUgbsOgeSBjw7MgdGjhu4MgcGjhuqNuIMOhbmggc+G7sSBs4bq3cCBs4bqhaSBow6BuaCB2aSB0w6BpIGNow61uaCBy4bunaSBybywgaG/hurdjIGNoaeG6v24gbMaw4bujYyBuaOG6r20gbeG7pWMgdGnDqnUga2jDoWNoIGjDoG5nIG5oaeG7gXUgcuG7p2kgcm8gY+G7p2EgbmfDom4gaMOgbmcuDQoNCg0KIyAqKlThu5VuZyBr4bq/dCBr4bq/dCBxdeG6oyBo4buTaSBxdXkgbG9naXN0aWMgdsOgIGdp4bqjIHRodXnhur90IHRo4buRbmcga8OqKioNCg0KTcO0IGjDrG5oIGjhu5NpIHF1eSBsb2dpc3RpYyDEkcaw4bujYyB4w6J5IGThu7FuZyDEkeG7gyBwaMOibiB0w61jaCBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcgxJHhur9uIGto4bqjIG7Eg25nIHZheSB0acOqdSBkw7luZyAoYGxvYW5gKS4gVHJvbmcgxJHDsywgY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wIGfhu5NtOiBgam9iYCwgYGVkdWNhdGlvbmAsIGBtYXJpdGFsYCwgdsOgIGBkZWZhdWx0YC4NCg0KxJDhu5FpIHbhu5tpIG3hu5dpIGJp4bq/biBnaeG6o2kgdGjDrWNoIChiaeG6v24gxJHhu5ljIGzhuq1wKSwgZ2nhuqMgdGh1eeG6v3QgdGjhu5FuZyBrw6ogxJHGsOG7o2MgxJHhurd0IHJhIG5oxrAgc2F1Og0KDQotICoqR2nhuqMgdGh1eeG6v3Qga2jDtG5nIChI4oKAKSoqOiBI4buHIHPhu5EgaOG7k2kgcXV5IGLhurFuZyAwIChiaeG6v24gxJHhu5ljIGzhuq1wIGtow7RuZyDhuqNuaCBoxrDhu59uZyDEkeG6v24geMOhYyBzdeG6pXQgdmF5IHRpw6p1IGTDuW5nKS4NCi0gKipHaeG6oyB0aHV54bq/dCDEkeG7kWkgKEjigoEpKio6IEjhu4cgc+G7kSBo4buTaSBxdXkga2jDoWMgMCAoYmnhur9uIMSR4buZYyBs4bqtcCBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIHjDoWMgc3XhuqV0IHZheSB0acOqdSBkw7luZykuDQoNCkvhur90IHF14bqjIG3DtCBow6xuaCBjaOG7iSByYSBt4buZdCBz4buRIGJp4bq/biBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLCB04bupYyBsw6AgY8OzIGLhurFuZyBjaOG7qW5nIMSR4buDIGLDoWMgYuG7jyBI4oKAIOG7nyBt4bupYyDDvSBuZ2jEqWEgNSU6DQoNCiMjICoqQ8OhYyBiaeG6v24gY8OzIOG6o25oIGjGsOG7n25nIMSRw6FuZyBr4buDIMSR4bq/biBow6BuaCB2aSB2YXkgdGnDqnUgZMO5bmc6KioNCg0KLSAqKmRlZmF1bHR5ZXMqKiAoKnAgPSAwLjAwMDMqKTogIA0KICDihpIgQsOhYyBi4buPIEjigoAuIEtow6FjaCBow6BuZyBjw7MgbuG7oyB0w61uIGThu6VuZyBxdcOhIGjhuqFuIGPDsyB4w6FjIHN14bqldCB2YXkgdGnDqnUgZMO5bmcgY2FvIGjGoW4gxJHDoW5nIGvhu4MuICANCiAg4oaSIE9SID4gMSBjaG8gdGjhuqV5ICoqdMSDbmcga2jhuqMgbsSDbmcgdmF5KiouDQoNCi0gKipqb2JzdHVkZW50KiogKCpwID0gMC4wMTA5Kik6ICANCiAg4oaSIELDoWMgYuG7jyBI4oKALiBOaMOzbSBzaW5oIHZpw6puIGPDsyB4w6FjIHN14bqldCB2YXkgdGnDqnUgZMO5bmcgdGjhuqVwIGjGoW4gbmhp4buBdSBzbyB24bubaSBuaMOzbSBuZ2jhu4EgbmdoaeG7h3AgdGhhbSBjaGnhur91IChhZG1pbikuICANCiAg4oaSIE9SIDwgMSBjaG8gdGjhuqV5ICoqZ2nhuqNtIGto4bqjIG7Eg25nIHZheSoqLg0KDQotICoqam9idW5lbXBsb3llZCoqICgqcCA9IDAuMDMwNCopOiAgDQogIOKGkiBCw6FjIGLhu48gSOKCgC4gTmfGsOG7nWkgdGjhuqV0IG5naGnhu4dwIMOtdCBjw7Mga2jhuqMgbsSDbmcgdmF5IHRpw6p1IGTDuW5nIGjGoW4uICANCiAg4oaSIE9SIDwgMSwgcGjhuqNuIMOhbmggc+G7sSBo4bqhbiBjaOG6vyB0aeG6v3AgY+G6rW4gdMOtbiBk4bulbmcuDQoNCi0gKipqb2JlbnRyZXByZW5ldXIqKiAoKnAgPSAwLjA0NjMqKTogIA0KICDihpIgQsOhYyBi4buPIEjigoAuIE5ow7NtIGRvYW5oIG5ow6JuIGPDsyBraOG6oyBuxINuZyB2YXkgdGnDqnUgZMO5bmcgY2FvIGjGoW4uDQoNCi0gKiplZHVjYXRpb25zZWNvbmRhcnkqKiAoKnAgPSAwLjAxNDYqKTogIA0KICDihpIgQsOhYyBi4buPIEjigoAuIFRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiB0cnVuZyBo4buNYyBsw6BtIHTEg25nIHjDoWMgc3XhuqV0IHZheSB0acOqdSBkw7luZyBzbyB24bubaSB0aeG7g3UgaOG7jWMuDQoNCi0gKiptYXJpdGFsc2luZ2xlKiogKCpwID0gMC4wMjQ1Kik6ICANCiAg4oaSIELDoWMgYuG7jyBI4oKALiBOaMOzbSDEkeG7mWMgdGjDom4gY8OzIHh1IGjGsOG7m25nIHZheSDDrXQgaMahbiBzbyB24bubaSBuaMOzbSBseSBow7RuICh0aGFtIGNoaeG6v3UpLg0KDQojIyAqKkPDoWMgYmnhur9uIGtow7RuZyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIChwID4gMC4wNSkqKg0KDQotIEPDoWMgYmnhur9uIG5oxrAgYGpvYmJsdWUtY29sbGFyYCwgYGpvYnJldGlyZWRgLCBgZWR1Y2F0aW9udGVydGlhcnlgLCBgbWFyaXRhbG1hcnJpZWRgIGtow7RuZyDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBiw6FjIGLhu48gSOKCgC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGNoxrBhIGPDsyBjxqEgc+G7nyB0aOG7kW5nIGvDqiDEkeG7gyBraOG6s25nIMSR4buLbmggbmjhu69uZyBiaeG6v24gbsOgeSDhuqNuaCBoxrDhu59uZyDEkeG6v24geMOhYyBzdeG6pXQgdmF5IHRpw6p1IGTDuW5nIHRyb25nIG3DtCBow6xuaC4NCg0KLS0tDQoNCiMgKipI4buTaSBxdXkgUHJvYml0KioNCg0KU2F1IGtoaSB0aOG7sWMgaGnhu4duIG3DtCBow6xuaCBo4buTaSBxdXkgbG9naXN0aWMsIHTDoWMgZ2nhuqMgdGnhur9wIHThu6VjIHRyaeG7g24ga2hhaSBtw7QgaMOsbmggKipo4buTaSBxdXkgUHJvYml0KiogbmjhurFtIGtp4buDbSB0cmEgxJHhu5kgbmjhuqV0IHF1w6FuIHbDoCB0w61uaCBuaOG6oXkgY+G7p2EgY8OhYyBr4bq/dCBxdeG6oy4gTcO0IGjDrG5oIFByb2JpdCBz4butIGThu6VuZyBow6BtIGxpw6puIGvhur90IHBow6JuIHBo4buRaSBjaHXhuqluIHTDrWNoIGzFqXkgxJHhu4MgbcO0IHBo4buPbmcgeMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nICoqdmF5IHRpw6p1IGTDuW5nKiogKGBsb2FuID0geWVzYCkgZOG7sWEgdHLDqm4gY8OhYyBiaeG6v24gxJHhu5ljIGzhuq1wIG5oxrAgbmdo4buBIG5naGnhu4dwLCB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4sIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiB2w6AgbOG7i2NoIHPhu60gbuG7oyB44bqldSAoYGRlZmF1bHRgKS4NCg0KKipHaeG6oyB0aHV54bq/dCB0aOG7kW5nIGvDqioqDQoNCsSQ4buRaSB24bubaSB04burbmcgYmnhur9uIMSR4buZYyBs4bqtcCB0cm9uZyBtw7QgaMOsbmgsIHRhIGtp4buDbSDEkeG7i25oOg0KDQotICoqSOKCgCoqOiBCaeG6v24ga2jDtG5nIGPDsyDhuqNuaCBoxrDhu59uZyDEkeG6v24geMOhYyBzdeG6pXQgdmF5IHRpw6p1IGTDuW5nDQotICoqSOKCgSoqOiBCaeG6v24gY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biB4w6FjIHN14bqldCB2YXkgdGnDqnUgZMO5bmcNCg0KTeG7qWMgw70gbmdoxKlhIHPhu60gZOG7pW5nIGzDoCA1JSAozrEgPSAwLjA1KS4gTuG6v3UgKnAtdmFsdWUqIDwgMC4wNSwgdGEgYsOhYyBi4buPIEjigoAuDQoNCiMjIyBL4bq/dCBxdeG6oyBtw7QgaMOsbmggUHJvYml0DQoNCmBgYHtyfQ0KIyBDaOG6oXkgbcO0IGjDrG5oIHByb2JpdA0KbW9kZWxfcHJvYml0IDwtIGdsbShsb2FuIH4gam9iICsgZWR1Y2F0aW9uICsgbWFyaXRhbCArIGRlZmF1bHQsDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhMSwNCiAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICJwcm9iaXQiKSkNCg0KIyBIaeG7g24gdGjhu4sga+G6v3QgcXXhuqMNCnN1bW1hcnkobW9kZWxfcHJvYml0KQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KIyAqKlRo4buRbmcga8OqIG3DtCB04bqjKioNCg0KYGBge3J9DQpsb2FuX3RhYiA8LSB0YWJsZShkYXRhJGxvYW4pDQpiYXJwbG90KGxvYW5fdGFiLCBjb2wgPSBjKCJza3libHVlIiwgIm9yYW5nZSIpLCBtYWluID0gIlBow6JuIGLhu5EgdmF5IHRpw6p1IGTDuW5nIiwgeWxhYiA9ICJT4buRIGzGsOG7o25nIikNCnByb3AudGFibGUobG9hbl90YWIpDQpgYGANCg0KIyAqKlBow6JuIHTDrWNoIENoaSBiw6xuaCBwaMawxqFuZywgUlIsIE9SKioNCg0KYGBge3J9DQojIEtp4buDbSDEkeG7i25oIENoaSBiw6xuaCBwaMawxqFuZw0KY2hpc3EudGVzdCh0YWJsZShkYXRhJGxvYW4sIGRhdGEkZWR1Y2F0aW9uKSkNCmNoaXNxLnRlc3QodGFibGUoZGF0YSRsb2FuLCBkYXRhJGhvdXNpbmcpKQ0KY2hpc3EudGVzdCh0YWJsZShkYXRhJGxvYW4sIGRhdGEkbWFyaXRhbCkpDQoNCiMgUmVsYXRpdmUgUmlzayB2w6AgT2RkcyBSYXRpbw0KcnIxIDwtIHJpc2tyYXRpbyh0YWJsZShkYXRhJGxvYW4sIGRhdGEkaG91c2luZykpDQpycjIgPC0gcmlza3JhdGlvKHRhYmxlKGRhdGEkbG9hbiwgZGF0YSRkZWZhdWx0KSkNCg0KIyBH4buZcCBlZHVjYXRpb24gbOG6oWkgbMOgbSBuaMOzbSBoaWdoL2xvdw0KZGF0YSRlZHVfYmluIDwtIGlmZWxzZShkYXRhJGVkdWNhdGlvbiA9PSAidGVydGlhcnkiLCAiaGlnaCIsICJsb3ciKQ0KcnIzIDwtIHJpc2tyYXRpbyh0YWJsZShkYXRhJGxvYW4sIGRhdGEkZWR1X2JpbikpDQoNCnJyMQ0KcnIyDQpycjMNCmBgYA0KDQojICoqSOG7k2kgcXV5IExvZ2lzdGljKioNCg0KYGBge3J9DQptb2RlbF9sb2dpdCA8LSBnbG0obG9hbiB+IGFnZSArIGpvYiArIG1hcml0YWwgKyBlZHVjYXRpb24gKyBkZWZhdWx0ICsgaG91c2luZyArIGNvbnRhY3QsDQogICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkNCnN1bW1hcnkobW9kZWxfbG9naXQpDQpgYGANCg0KIyAqKkjhu5NpIHF1eSBQcm9iaXQqKg0KDQpgYGB7cn0NCm1vZGVsX3Byb2JpdCA8LSBnbG0obG9hbiB+IGFnZSArIGpvYiArIG1hcml0YWwgKyBlZHVjYXRpb24gKyBkZWZhdWx0ICsgaG91c2luZyArIGNvbnRhY3QsDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gInByb2JpdCIpKQ0Kc3VtbWFyeShtb2RlbF9wcm9iaXQpDQpgYGANCg0KIyAqKsSQw6FuaCBnacOhIG3DtCBow6xuaCoqDQoNCmBgYHtyfQ0KcF9sb2dpdCA8LSBwcmVkaWN0KG1vZGVsX2xvZ2l0LCB0eXBlID0gInJlc3BvbnNlIikNCnJvY19sb2dpdCA8LSByb2MoZGF0YSRsb2FuLCBwX2xvZ2l0KQ0KcGxvdChyb2NfbG9naXQsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJST0MgQ3VydmU6IExvZ2lzdGljIHZzIFByb2JpdCIpDQphdWMocm9jX2xvZ2l0KQ0KDQpwX3Byb2JpdCA8LSBwcmVkaWN0KG1vZGVsX3Byb2JpdCwgdHlwZSA9ICJyZXNwb25zZSIpDQpyb2NfcHJvYml0IDwtIHJvYyhkYXRhJGxvYW4sIHBfcHJvYml0KQ0KbGluZXMocm9jX3Byb2JpdCwgY29sID0gInJlZCIpDQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiTG9naXN0aWMiLCAiUHJvYml0IiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEpDQpgYGANCg0KIyAqKkLhuqNuZyBzbyBzw6FuaCBMb2dpc3RpYyB2w6AgUHJvYml0KioNCg0KYGBge3J9DQpzdGFyZ2F6ZXIobW9kZWxfbG9naXQsIG1vZGVsX3Byb2JpdCwgdHlwZSA9ICJ0ZXh0IiwgdGl0bGUgPSAiU28gc8OhbmggaOG7k2kgcXV5IGxvZ2lzdGljICYgcHJvYml0IikNCmBgYA0K