library(readr)
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(skimr)
## Warning: package 'skimr' was built under R version 4.3.3
library(psych)
## Warning: package 'psych' was built under R version 4.3.3
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(csv)
## Warning: package 'csv' was built under R version 4.3.3
library(DT)
## Warning: package 'DT' was built under R version 4.3.3
library(pander)
## Warning: package 'pander' was built under R version 4.3.3
library(formattable)
## Warning: package 'formattable' was built under R version 4.3.3
library(htmltools)
## 
## Attaching package: 'htmltools'
## The following object is masked from 'package:pander':
## 
##     p
library(DescTools)
## Warning: package 'DescTools' was built under R version 4.3.3
## 
## Attaching package: 'DescTools'
## The following objects are masked from 'package:psych':
## 
##     AUC, ICC, SD
library(epitools)

Phần 1. TÌM HIỂU VÀ CHUẨN BỊ DỮ LIỆU

1. Đọc file dữ liệu

d <- read.csv("D:/PTDLDT/Supermarket Transactions.csv")

2. Cấu trúc bộ dữ liệu

str(d)
## 'data.frame':    14059 obs. of  16 variables:
##  $ X                : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ PurchaseDate     : chr  "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
##  $ CustomerID       : int  7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
##  $ Gender           : chr  "F" "M" "F" "M" ...
##  $ MaritalStatus    : chr  "S" "M" "M" "M" ...
##  $ Homeowner        : chr  "Y" "Y" "N" "Y" ...
##  $ Children         : int  2 5 2 3 3 3 2 2 3 1 ...
##  $ AnnualIncome     : chr  "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
##  $ City             : chr  "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
##  $ StateorProvince  : chr  "CA" "CA" "WA" "OR" ...
##  $ Country          : chr  "USA" "USA" "USA" "USA" ...
##  $ ProductFamily    : chr  "Food" "Food" "Food" "Food" ...
##  $ ProductDepartment: chr  "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
##  $ ProductCategory  : chr  "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
##  $ UnitsSold        : int  5 5 3 4 4 3 4 6 1 2 ...
##  $ Revenue          : num  27.38 14.9 5.52 4.44 14 ...
  • Bộ dữ liệu data chứa tổng cộng 14.059 bản ghi với 16 biến đặc trưng.

Các biến trong bộ dữ liệu bao gồm:

  • X: biến số nguyên, có thể là chỉ số thứ tự của bản ghi.

  • PurchaseDate: ngày mua hàng, được lưu dưới dạng chuỗi ký tự với định dạng “YYYY-MM-DD”.

  • CustomerID: mã định danh khách hàng dưới dạng số nguyên.

  • Gender: giới tính khách hàng, ký hiệu bằng ký tự (F: nữ, M: nam).

  • MaritalStatus: tình trạng hôn nhân (S: độc thân, M: đã kết hôn).

  • Homeowner: trạng thái sở hữu nhà (Y: có nhà, N: không có nhà).

  • Children: số lượng con trong gia đình, kiểu số nguyên.

  • AnnualIncome: nhóm thu nhập hàng năm, được ghi dưới dạng chuỗi ký tự (ví dụ: “$30K - $50K”).

  • City: tên thành phố nơi khách hàng sinh sống.

  • StateorProvince: bang hoặc tỉnh, được lưu dưới dạng chuỗi ký tự.

  • Country: quốc gia, dưới dạng chuỗi ký tự.

  • ProductFamily: nhóm sản phẩm chính, ví dụ như Food, Drink,…

  • ProductDepartment: phòng ban sản phẩm, ví dụ như Snack Foods, Produce,…

  • ProductCategory: danh mục sản phẩm cụ thể.

  • UnitsSold: số lượng sản phẩm đã bán, kiểu số nguyên.

  • Revenue: doanh thu thu được từ giao dịch, kiểu số thực (đơn vị USD).

Việc hiểu rõ cấu trúc và kiểu dữ liệu của các biến sẽ hỗ trợ rất nhiều trong việc phân tích và xử lý dữ liệu tiếp theo.

3. Chọn các biến định tính

dldt <- c("Gender", "MaritalStatus", "Homeowner","AnnualIncome","City", "StateorProvince", "Country", "ProductFamily", "ProductDepartment", "ProductCategory")
dldt
##  [1] "Gender"            "MaritalStatus"     "Homeowner"        
##  [4] "AnnualIncome"      "City"              "StateorProvince"  
##  [7] "Country"           "ProductFamily"     "ProductDepartment"
## [10] "ProductCategory"

4. Tạo bộ dữ liệu mới chỉ chứa các biến định tính

dt <- d[, dldt]

5. Một vài dòng đầu và dòng cuối

head(dt)
##   Gender MaritalStatus Homeowner  AnnualIncome          City StateorProvince
## 1      F             S         Y   $30K - $50K   Los Angeles              CA
## 2      M             M         Y   $70K - $90K   Los Angeles              CA
## 3      F             M         N   $50K - $70K     Bremerton              WA
## 4      M             M         Y   $30K - $50K      Portland              OR
## 5      F             S         Y $130K - $150K Beverly Hills              CA
## 6      F             M         Y   $10K - $30K Beverly Hills              CA
##   Country ProductFamily ProductDepartment      ProductCategory
## 1     USA          Food       Snack Foods          Snack Foods
## 2     USA          Food           Produce           Vegetables
## 3     USA          Food       Snack Foods          Snack Foods
## 4     USA          Food            Snacks                Candy
## 5     USA         Drink         Beverages Carbonated Beverages
## 6     USA          Food              Deli          Side Dishes
tail(dt)
##       Gender MaritalStatus Homeowner AnnualIncome        City StateorProvince
## 14054      F             M         N  $10K - $30K      Yakima              WA
## 14055      F             M         Y  $10K - $30K   Bremerton              WA
## 14056      F             M         Y  $10K - $30K Walla Walla              WA
## 14057      M             S         Y  $30K - $50K    Portland              OR
## 14058      F             S         N  $50K - $70K     Spokane              WA
## 14059      M             S         N  $50K - $70K    Portland              OR
##       Country  ProductFamily ProductDepartment      ProductCategory
## 14054     USA Non-Consumable         Household       Paper Products
## 14055     USA           Food      Baking Goods         Baking Goods
## 14056     USA           Food      Frozen Foods           Vegetables
## 14057     USA          Drink         Beverages Pure Juice Beverages
## 14058     USA          Drink             Dairy                Dairy
## 14059     USA Non-Consumable         Household           Electrical

6. Kiểm tra NA

any(is.na(dt))
## [1] FALSE

Vậy bộ dữ liệu không có giá trị thiếu

7. Kiểm tra kiểu dữ liệu và đổi về factor

# Kiểm tra kiểu dữ liệu của từng biến trong dldt
sapply(dt, class) 
##            Gender     MaritalStatus         Homeowner      AnnualIncome 
##       "character"       "character"       "character"       "character" 
##              City   StateorProvince           Country     ProductFamily 
##       "character"       "character"       "character"       "character" 
## ProductDepartment   ProductCategory 
##       "character"       "character"
  • “character”, nghĩa là chuỗi ký tự (text).

  • Dựa trên kết quả kiểm tra kiểu dữ liệu, có thể thấy rằng tất cả các biến trong tập dữ liệu đều đang ở dạng chuỗi ký tự (character). Đây là dấu hiệu cho thấy dữ liệu chưa được xử lý đúng kiểu, đặc biệt là đối với các biến như AnnualIncome – lẽ ra nên ở dạng số (numeric) để phục vụ cho các phép tính thống kê hoặc phân tích định lượng. Bên cạnh đó, các biến phân loại như Gender, MaritalStatus, Homeowner, hay ProductCategory nên được chuyển sang kiểu factor để thuận tiện cho việc phân tích định tính và mô hình hóa. Việc để toàn bộ biến ở dạng chuỗi ký tự có thể gây ra nhiều hạn chế trong quá trình xử lý và phân tích dữ liệu, do đó cần thực hiện bước tiền xử lý để chuyển đổi các biến về đúng kiểu dữ liệu tương ứng.

dt <- data.frame(lapply(dt, as.factor))

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

2.1. Biến Gender

Bảng tần suất

#Lập bảng tần suất của biến Gender
table(dt$Gender)/sum(nrow(dt))
## 
##         F         M 
## 0.5099936 0.4900064

Bảng tần số

#Lập bảng tần số biến Gender
table(dt$Gender)
## 
##    F    M 
## 7170 6889

Biểu đồ

gender_freq  <- table(dt$Gender)
gender_pct   <- gender_freq / nrow(dt)
# Bước 1: Chuyển bảng sang data.frame
gender_freq <- table(dt$Gender)                     # Đếm số lượng từng nhóm giới tính (ví dụ: "M", "F"), trả về đối tượng table
gender_df <- as.data.frame(gender_freq)             # Chuyển từ table sang data.frame để xử lý dễ hơn trong ggplot2
colnames(gender_df) <- c("Gender", "Count")         # Đặt tên cột rõ ràng: "Gender" là tên nhóm, "Count" là số lượng

# Bước 2: Tính phần trăm
gender_df$Percent <- gender_df$Count / sum(gender_df$Count) * 100

# Bước 3: Tạo nhãn giống như trong pie()
gender_df$Label <- paste0(                             # Ghép chuỗi để tạo nhãn
  gender_df$Gender, " (",                              # Thêm tên giới tính và dấu mở ngoặc
  round(gender_df$Percent, 1), "%)"                    # Làm tròn phần trăm 1 chữ số và thêm dấu %
)

# Bước 4: Vẽ biểu đồ tròn bằng ggplot2
ggplot(gender_df, aes(x = "", y = Count, fill = Gender)) +  # Dữ liệu truyền vào: không chia trục x, y là số lượng, fill theo giới tính
  geom_bar(stat = "identity", width = 1) +                  # Vẽ cột với chiều cao đúng theo dữ liệu (stat = "identity"), chiều rộng 1
  coord_polar("y") +                                        # Chuyển từ biểu đồ cột sang biểu đồ tròn bằng cách dùng tọa độ cực
  theme_void() +                                            # Bỏ toàn bộ trục, đường lưới và nền để làm sạch biểu đồ
  labs(title = "Biểu đồ 1. Phân bố giới tính (Gender)") +             # Thêm tiêu đề phía trên biểu đồ
  geom_text(aes(label = Label),                             # Thêm nhãn phần trăm vào từng lát của biểu đồ
            position = position_stack(vjust = 0.5),         # Đặt vị trí nhãn ở giữa mỗi lát (vjust = 0.5 là canh giữa theo chiều dọc)
            size = 5) +                                     # Cỡ chữ của nhãn
  scale_fill_manual(values = c("F" = "lightpink",           # Gán màu hồng nhạt cho giới tính "F"
                               "M" = "lightblue"))          # Gán màu xanh nhạt cho giới tính "M"

Nhận xét:

counts <- table(dt$Gender)
diff_count <- abs(counts["F"] - counts["M"])
  • Vậy trong bộ dữ liệu này có 50.9993598 % nữ và 49.0006402% nam.

  • Trong bộ dữ liệu, số lượng nữ là 7170, số lượng nam là 6889. Sự chênh lệch về số lượng giữa nữ và nam là 281. Tuy số lượng nữ có phần nhỉnh hơn, nhưng mức chênh lệch là không đáng kể so với tổng thể dữ liệu, cho thấy cơ cấu giới tính trong bộ dữ liệu tương đối cân bằng.

2.2. Biến Homeowner

Bảng tần suất

#Lập bảng tần suất của biến Homeowner
table(dt$Homeowner)/sum(nrow(dt))
## 
##         N         Y 
## 0.3993883 0.6006117

Bảng tần số

#Lập bảng tần số biến Homeowner
table(dt$Homeowner)
## 
##    N    Y 
## 5615 8444

Biểu đồ

# Bước 1: Tạo bảng tần suất và chuyển sang data.frame
home_freq <- table(dt$Homeowner)                      # Đếm số lượng "Y" và "N"
home_df   <- as.data.frame(home_freq)                 # Chuyển sang data.frame để vẽ bằng ggplot2
colnames(home_df) <- c("Homeowner", "Count")          # Đặt lại tên cột

# Bước 2: Tính phần trăm
home_df$Percent <- home_df$Count / sum(home_df$Count) * 100  # Tính phần trăm

# Bước 3: Tạo nhãn để hiển thị trên biểu đồ
home_df$Label <- paste0(home_df$Homeowner, " (", round(home_df$Percent, 1), "%)")

# Bước 4: Vẽ biểu đồ tròn bằng ggplot2
ggplot(home_df, aes(x = "", y = Count, fill = Homeowner)) +   # Biến "fill" sẽ phân màu theo "Y"/"N"
  geom_bar(stat = "identity", width = 1) +                     # Tạo cột theo số lượng
  coord_polar("y") +                                           # Chuyển sang biểu đồ tròn
  theme_void() +                                               # Xóa trục và nền
  labs(title = "Biểu đồ 2. Tỷ lệ sở hữu nhà (Homeowner)") +               # Thêm tiêu đề
  geom_text(aes(label = Label),                                # Nhãn phần trăm trên lát cắt
            position = position_stack(vjust = 0.5),
            size = 5) +
  scale_fill_manual(values = c("Y" = "lightgreen",             # Màu cho nhóm "Y"
                               "N" = "lightcoral"))            # Màu cho nhóm "N"

Nhận xét:

counts_homeowner <- table(dt$Homeowner)
diff_homeowner <- abs(counts_homeowner["Y"] - counts_homeowner["N"])
  • Vậy trong bộ dữ liệu này có 39.9388292 % không có nhà và 60.0611708% có nhà.

  • Số lượng người sở hữu nhà là 8444, số lượng người không sở hữu là 5615.

  • Sự chênh lệch về số lượng giữa hai nhóm là 2829 người, nghĩa là số người có nhà nhiều hơn khá đáng kể so với số người không có nhà. Điều này cho thấy phần lớn khách hàng trong bộ dữ liệu thuộc nhóm đã sở hữu nhà, và sự khác biệt giữa hai nhóm là tương đối lớn, có thể ảnh hưởng đến các phân tích liên quan đến điều kiện kinh tế – xã hội.

2.3. Biến MaritalStatus

Bảng tần suất

#Lập bảng tần suất của biến MaritalStatus
table(dt$MaritalStatus)/sum(nrow(dt))
## 
##         M         S 
## 0.4883704 0.5116296

Bảng tần số

#Lập bảng tần số của biến MaritalStatus
table(dt$MaritalStatus)
## 
##    M    S 
## 6866 7193

Biểu đồ

# Bước 1: Tạo bảng tần suất và chuyển sang data.frame
mar_freq <- table(dt$MaritalStatus)                     # Đếm số lượng từng nhóm trong biến MaritalStatus
mar_df   <- as.data.frame(mar_freq)                     # Chuyển từ table sang data.frame
colnames(mar_df) <- c("MaritalStatus", "Count")         # Đặt tên cột: MaritalStatus là nhóm, Count là số lượng

# Bước 2: Tính phần trăm
mar_df$Percent <- mar_df$Count / sum(mar_df$Count) * 100  # Tính phần trăm từng nhóm

# Bước 3: Tạo nhãn hiển thị
mar_df$Label <- paste0(mar_df$MaritalStatus, " (", round(mar_df$Percent, 1), "%)")  # Ví dụ: "Single (45.7%)"

# Bước 4: Vẽ biểu đồ tròn bằng ggplot2
ggplot(mar_df, aes(x = "", y = Count, fill = MaritalStatus)) +  # x = "" để gom lại thành một vòng tròn
  geom_bar(stat = "identity", width = 1) +                       # Vẽ biểu đồ cột với chiều rộng 1 để tạo hình tròn
  coord_polar("y") +                                             # Chuyển sang tọa độ tròn (pie chart)
  theme_void() +                                                 # Loại bỏ trục, lưới, nền
  labs(title = "Biểu đồ 3. Phân bố tình trạng hôn nhân (MaritalStatus)") + # Thêm tiêu đề cho biểu đồ
  geom_text(aes(label = Label),                                  # Thêm nhãn phần trăm vào từng lát
            position = position_stack(vjust = 0.5),
            size = 5) +
  scale_fill_brewer(palette = "Pastel1")                         # Dùng bảng màu nhẹ nhàng tự động (hoặc chọn palette khác)

Nhận xét:

# Đếm số người kết hôn (M) và độc thân (S)
ms_counts <- table(dt$MaritalStatus)

# Chênh lệch về số lượng giữa hai nhóm
ms_diff <- abs(ms_counts["M"] - ms_counts["S"])
  • Vậy trong bộ dữ liệu này có 48.8370439 % đã kết hôn và 51.1629561% độc thân.

  • Cụ thể, có 6866 người đã kết hôn và 7193 người độc thân. Mặc dù nhóm độc thân có số lượng cao hơn, nhưng sự chênh lệch chỉ là 327 người – một con số khá nhỏ so với tổng thể. Do đó, có thể nhận xét rằng hai nhóm hôn nhân trong bộ dữ liệu khá cân bằng, và không có sự khác biệt đáng kể giữa số lượng người đã kết hôn và người độc thân.

2.4. Biến AnnualIncome

Bảng tần suất

# ---- bảng tỷ lệ % cho City ----
annual_prop <- prop.table(table(dt$AnnualIncome))        

# Chuyển thành data‑frame
annual_pct_df <- as.data.frame(annual_prop)
names(annual_pct_df) <- c("AnnualIncome", "Ty_le")    # đặt tên cột

# Nhân 100 để thành phần trăm
annual_pct_df$Ty_le <- round(100 * annual_pct_df$Ty_le, 2)

print(annual_pct_df)
##    AnnualIncome Ty_le
## 1   $10K - $30K 21.98
## 2 $110K - $130K  4.57
## 3 $130K - $150K  5.41
## 4       $150K +  1.94
## 5   $30K - $50K 32.73
## 6   $50K - $70K 16.86
## 7   $70K - $90K 12.16
## 8  $90K - $110K  4.36

Bảng tần số

# Bảng tần suất cho City
annual_tab <- table(dt$AnnualIncome)

# Chuyển thành data‑frame 2 cột: City và Freq
annual_df <- as.data.frame(annual_tab)
names(annual_df) <- c("AnnualIncome", "So_luong")   # đặt tên cột rõ ràng

print(annual_df)
##    AnnualIncome So_luong
## 1   $10K - $30K     3090
## 2 $110K - $130K      643
## 3 $130K - $150K      760
## 4       $150K +      273
## 5   $30K - $50K     4601
## 6   $50K - $70K     2370
## 7   $70K - $90K     1709
## 8  $90K - $110K      613

Biểu đồ

library(ggplot2)

ggplot(dt, aes(x = AnnualIncome)) +                  # đặt biến AnnualIncome lên trục X.
  geom_bar() +
  coord_flip() +                             # xoay ngang cho gọn
  labs(title = "Biểu đồ 4. Tần số theo Thu nhập",
       x = "AnnualIncome", y = "Số thu nhập")

Nhận xét:

  • Nhóm thu nhập chiếm tỷ lệ cao nhất trong bộ dữ liệu là $30K - $50K, chiếm khoảng 32.73% tổng số mẫu khảo sát. Điều này cho thấy nhóm này là tệp khách hàng chính hoặc phổ biến nhất trong tập dữ liệu.

  • Một số nhóm thu nhập khác như $150K + có tỷ lệ rất thấp, chỉ khoảng 1.94%, cho thấy mức độ xuất hiện của họ trong dữ liệu không nhiều — có thể do họ ít quan tâm đến sản phẩm, hoặc nằm ngoài phân khúc thị trường mà doanh nghiệp đang hướng tới.

  • Sự phân bố thu nhập không đều phản ánh cơ cấu khách hàng của siêu thị hoặc đơn vị khảo sát: tập trung nhiều ở các nhóm thu nhập trung bình đến trung cao, trong khi nhóm thu nhập quá thấp hoặc quá cao xuất hiện ít hơn.

  • Đây có thể là dấu hiệu để doanh nghiệp điều chỉnh chiến lược tiếp cận thị trường, như tập trung nhiều hơn vào các nhóm thu nhập đang chiếm ưu thế, hoặc mở rộng các chính sách ưu đãi để thu hút nhóm khách hàng ít phổ biến hơn.

2.5. Biến City

Bảng tần suất

# ---- bảng tỷ lệ % cho City ----
city_prop <- prop.table(table(dt$City))        # hoặc table(dt$City) / nrow(dt)

# Chuyển thành data‑frame
city_pct_df <- as.data.frame(city_prop)
names(city_pct_df) <- c("City", "Ty_le")    # đặt tên cột

# Nhân 100 để thành phần trăm
city_pct_df$Ty_le <- round(100 * city_pct_df$Ty_le, 2)

print(city_pct_df)
##             City Ty_le
## 1       Acapulco  2.72
## 2     Bellingham  1.02
## 3  Beverly Hills  5.77
## 4      Bremerton  5.93
## 5        Camacho  3.22
## 6    Guadalajara  0.53
## 7        Hidalgo  6.01
## 8    Los Angeles  6.59
## 9         Merida  4.65
## 10   Mexico City  1.38
## 11       Orizaba  3.30
## 12      Portland  6.23
## 13         Salem  9.86
## 14    San Andres  4.42
## 15     San Diego  6.16
## 16 San Francisco  0.92
## 17       Seattle  6.56
## 18       Spokane  6.22
## 19        Tacoma  8.94
## 20     Vancouver  4.50
## 21      Victoria  1.25
## 22   Walla Walla  1.14
## 23        Yakima  2.67

Bảng tần số

# Bảng tần suất cho City
city_tab <- table(dt$City)

# Chuyển thành data‑frame 2 cột: City và Freq
city_df <- as.data.frame(city_tab)
names(city_df) <- c("City", "So_luong")   # đặt tên cột rõ ràng

print(city_df)
##             City So_luong
## 1       Acapulco      383
## 2     Bellingham      143
## 3  Beverly Hills      811
## 4      Bremerton      834
## 5        Camacho      452
## 6    Guadalajara       75
## 7        Hidalgo      845
## 8    Los Angeles      926
## 9         Merida      654
## 10   Mexico City      194
## 11       Orizaba      464
## 12      Portland      876
## 13         Salem     1386
## 14    San Andres      621
## 15     San Diego      866
## 16 San Francisco      130
## 17       Seattle      922
## 18       Spokane      875
## 19        Tacoma     1257
## 20     Vancouver      633
## 21      Victoria      176
## 22   Walla Walla      160
## 23        Yakima      376

Biểu đồ

library(ggplot2)

ggplot(dt, aes(x = City)) +                  # đặt biến City lên trục X.
  geom_bar() +
  coord_flip() +                             # xoay ngang cho gọn
  labs(title = "Biểu đồ 5. Tần số giao dịch theo City",
       x = "City", y = "Số giao dịch")

Nhận xét:
- Trong bộ dữ liệu này, thành phố có tỷ lệ giao dịch cao nhất là Salem với khoảng 9.86%, tiếp theo là Tacoma (8.94%), Los Angeles (6.59%) và Seattle (6.56%).

  • Các thành phố nhỏ hơn như Hidalgo (6.01%) hoặc Guadalajara (0.53%) có tỷ lệ thấp hơn nhiều.

  • Điều này cho thấy giao dịch chủ yếu tập trung ở một số thành phố lớn với dân số hoặc hoạt động kinh tế cao hơn. Các thành phố nhỏ hơn đóng góp ít hơn vào tổng số giao dịch, có thể do quy mô thị trường nhỏ hoặc mức độ phổ biến của sản phẩm thấp.

  • Ngoài ra, việc phân bố này cũng có thể phản ánh chiến lược tiếp thị hoặc kênh phân phối mà siêu thị đang tập trung vào các khu vực đô thị lớn.

2.6. Biến StateorProvince

Bảng tần suất

#Lập bảng tần suất của biến StateorProvince
table(dt$StateorProvince)/sum(nrow(dt))
## 
##          BC          CA          DF    Guerrero     Jalisco          OR 
## 0.057543211 0.194395049 0.057969984 0.027242336 0.005334661 0.160893378 
##    Veracruz          WA     Yucatan   Zacatecas 
## 0.033003770 0.324845295 0.046518245 0.092254072

Bảng tần số

#Lập bảng tần số của biến StateorProvince
table(dt$StateorProvince)
## 
##        BC        CA        DF  Guerrero   Jalisco        OR  Veracruz        WA 
##       809      2733       815       383        75      2262       464      4567 
##   Yucatan Zacatecas 
##       654      1297

Biểu đồ

ggplot(dt, aes(x = StateorProvince)) +
  geom_bar() +
  coord_flip() +                                # xoay trục cho gọn
  labs(title = "Biều đồ 6. Tần số giao dịch theo State / Province",
       x = "State / Province",
       y = "Số giao dịch")

Nhận xét: Trong bộ dữ liệu này, bang hoặc tỉnh có tỷ lệ giao dịch lớn nhất là WA với khoảng 32.48%, tiếp theo là CA (19.44%) và OR (16.09%). Các bang như Jalisco (0.53%) và Guerrero (2.72%) chiếm tỷ lệ thấp hơn. Như vậy, dữ liệu cho thấy sự tập trung giao dịch cao ở một số bang chính.

2.7. Biến Country

Bảng tần suất

#Lập bảng tần suất của biến Country
table(dt$Country)/sum(nrow(dt))
## 
##     Canada     Mexico        USA 
## 0.05754321 0.26232307 0.68013372

Bảng tần số

#Lập bảng tần số của biến Country
table(dt$Country)
## 
## Canada Mexico    USA 
##    809   3688   9562

Biểu đồ

# Bước 1: Tạo bảng tần suất và chuyển sang data.frame
country_freq <- table(dt$Country)                      # Đếm số lượng từng quốc gia trong biến Country
country_df   <- as.data.frame(country_freq)            # Chuyển từ table sang data.frame để xử lý bằng ggplot2
colnames(country_df) <- c("Country", "Count")          # Đặt lại tên cột: "Country" là tên nhóm, "Count" là số lượng

# Bước 2: Tính phần trăm
country_df$Percent <- country_df$Count / sum(country_df$Count) * 100  # Tính phần trăm

# Bước 3: Tạo nhãn phần trăm hiển thị trên lát cắt
country_df$Label <- paste0(country_df$Country, " (", round(country_df$Percent, 1), "%)")  # Ví dụ: "USA (45.3%)"

# Bước 4: Vẽ biểu đồ tròn bằng ggplot2
ggplot(country_df, aes(x = "", y = Count, fill = Country)) +   # Không chia trục x, chia màu theo Country
  geom_bar(stat = "identity", width = 1) +                     # Vẽ cột theo số lượng, độ rộng 1 để làm hình tròn
  coord_polar("y") +                                           # Chuyển sang biểu đồ tròn
  theme_void() +                                               # Xóa trục, đường lưới và nền
  labs(title = "Biểu đồ 7. Phân bố giao dịch theo Country") +             # Tiêu đề biểu đồ
  geom_text(aes(label = Label),                                # Thêm nhãn phần trăm vào giữa lát
            position = position_stack(vjust = 0.5),
            size = 4) +
  scale_fill_brewer(palette = "Greens")                          # Tự động tạo màu dễ phân biệt giữa nhiều quốc gia

Nhận xét:

# Đếm số bản ghi theo quốc gia
cty_counts <- table(dt$Country)

# Chênh lệch về số lượng giữa quốc gia đông nhất và ít nhất
cty_diff <- max(cty_counts) - min(cty_counts)
  • Vậy trong bộ dữ liệu này có 5.7543211 % ở Canada, 26.2323067% ở Mexico và 68.0133722% ở USA.

  • Quốc gia đông nhất có 9562, quốc gia ít nhất có r min(cty_counts).

  • Sự chênh lệch giữa hai quốc gia này là 8753 người.

2.8. Biến ProductFamily

Bảng tần suất

#Lập bảng tần suất của biến ProductFamily
table(dt$ProductFamily)/sum(nrow(dt))
## 
##          Drink           Food Non-Consumable 
##     0.08891102     0.72217085     0.18891813

Bảng tần số

#Lập bảng tần số của biến ProductFamily
table(dt$ProductFamily)
## 
##          Drink           Food Non-Consumable 
##           1250          10153           2656

Biểu đồ

# Bước 1: Tạo bảng tần suất và tính tỷ lệ phần trăm
pfreq <- sort(table(dt$ProductFamily), decreasing = TRUE)   # Đếm số lượng mỗi nhóm ProductFamily và sắp xếp giảm dần
ppct  <- pfreq / nrow(dt)                                   # Tính tỷ lệ phần trăm của mỗi nhóm

# Bước 2: Chuyển sang data.frame để dùng ggplot2
product_df <- as.data.frame(pfreq)                          # Chuyển bảng tần suất sang data.frame
colnames(product_df) <- c("ProductFamily", "Count")         # Đặt tên cột: tên nhóm và số lượng
product_df$Percent <- product_df$Count / sum(product_df$Count) * 100    # Tính phần trăm từng nhóm
product_df$Label <- paste0(product_df$ProductFamily,        # Tạo nhãn hiển thị tên + phần trăm
                           " (", round(product_df$Percent, 1), "%)")

# Bước 3: Vẽ biểu đồ tròn bằng ggplot2
ggplot(product_df, aes(x = "", y = Count, fill = ProductFamily)) +  # Dữ liệu biểu đồ: y là số lượng, chia màu theo nhóm
  geom_bar(stat = "identity", width = 1) +                          # Vẽ cột (bar chart) có chiều rộng bằng 1 để tạo hình tròn
  coord_polar("y") +                                               # Chuyển bar chart thành biểu đồ tròn theo trục y
  theme_void() +                                                   # Loại bỏ trục và nền (gọn gàng hơn)
  labs(title = "Biểu đồ 8. Phân bố giao dịch theo Product Family") +          # Thêm tiêu đề cho biểu đồ
  geom_text(aes(label = Label),                                    # Thêm nhãn (label) hiển thị trong lát cắt
            position = position_stack(vjust = 0.5),                # Đặt nhãn vào giữa mỗi lát
            size = 4) +                                            # Kích thước chữ của nhãn
  scale_fill_brewer(palette = "Blues")                              

Nhận xét:

  • Trong bộ dữ liệu này, nhóm đồ uống chiếm khoảng 8.89%,
    nhóm thức ăn chiếm khoảng 72.22%, và nhóm hàng không tiêu thụ được chiếm khoảng 18.89%.

  • Về số lượng, nhóm thức ăn có 10153 giao dịch,
    nhóm đồ uống có 1250 giao dịch, và nhóm hàng không tiêu thụ được có 2656 giao dịch. Điều này cho thấy nhóm thức ăn là hạng mục chiếm ưu thế rõ rệt, với sự chênh lệch rất lớn về số lượng so với hai nhóm còn lại. Như vậy, có thể nhận xét rằng phần lớn giao dịch trong bộ dữ liệu tập trung vào các sản phẩm thực phẩm – đây là đặc điểm nổi bật trong cơ cấu mặt hàng của siêu thị này.

2.9. Biến ProductDepartment

Bảng tần suất

# Tạo bảng tần suất (hoặc tỷ lệ) rồi đổi thành data‑frame 2 cột
dep_tab <- prop.table(table(dt$ProductDepartment))   # hoặc table(dt$ProductDepartment)
dep_df  <- as.data.frame(dep_tab)                   # ← biến thành 2 cột

# Đặt tên cột ngắn gọn
names(dep_df) <- c("ProductDepartment", "Ty_le")                  # nếu là tỷ lệ %
dep_df$Ty_le  <- round(100 * dep_df$Ty_le, 2)       # nhân 100 → %

print(dep_df)
##      ProductDepartment Ty_le
## 1  Alcoholic Beverages  2.53
## 2          Baked Goods  3.02
## 3         Baking Goods  7.63
## 4            Beverages  4.84
## 5      Breakfast Foods  1.34
## 6         Canned Foods  6.95
## 7      Canned Products  0.78
## 8             Carousel  0.42
## 9             Checkout  0.58
## 10               Dairy  6.42
## 11                Deli  4.97
## 12                Eggs  1.41
## 13        Frozen Foods  9.83
## 14  Health and Hygiene  6.35
## 15           Household 10.10
## 16                Meat  0.63
## 17         Periodicals  1.44
## 18             Produce 14.18
## 19             Seafood  0.73
## 20         Snack Foods 11.38
## 21              Snacks  2.50
## 22       Starchy Foods  1.97

Bảng tần số

# Lập bảng tần số
dep_freq <- table(dt$ProductDepartment)

# Chuyển thành data‑frame 2 cột
dep_freq_df <- as.data.frame(dep_freq)
names(dep_freq_df) <- c("ProductDepartment", "So_luong")   # đặt tên cột rõ ràng

print(dep_freq_df)
##      ProductDepartment So_luong
## 1  Alcoholic Beverages      356
## 2          Baked Goods      425
## 3         Baking Goods     1072
## 4            Beverages      680
## 5      Breakfast Foods      188
## 6         Canned Foods      977
## 7      Canned Products      109
## 8             Carousel       59
## 9             Checkout       82
## 10               Dairy      903
## 11                Deli      699
## 12                Eggs      198
## 13        Frozen Foods     1382
## 14  Health and Hygiene      893
## 15           Household     1420
## 16                Meat       89
## 17         Periodicals      202
## 18             Produce     1994
## 19             Seafood      102
## 20         Snack Foods     1600
## 21              Snacks      352
## 22       Starchy Foods      277

Biểu đồ

ggplot(dt, aes(x = ProductDepartment)) +
  geom_bar() +
  coord_flip() +  # xoay ngang nhãn cho dễ đọc
  labs(title = "Biều đồ 9. Tần số giao dịch theo Product Department",
       x = "Product Department",
       y = "Số giao dịch")

Nhận xét:

  • Trong bộ dữ liệu, nhóm sản phẩm có tỷ lệ giao dịch cao nhất là Produce với 14.18%, tiếp theo là Snack Foods (11.38%) và Household (10.1%). Nhóm Frozen Foods cũng chiếm tỷ lệ đáng kể là 9.83%. Các nhóm như Carousel (0.42%) và Checkout (0.58%) có tỷ lệ thấp hơn nhiều.

2.10. Biến ProductCategory

# ----- tỷ lệ % cho ProductCategory -----
pc_prop_df <- prop.table(table(dt$ProductCategory)) |>  # hoặc table(...)/nrow(dt)
  as.data.frame() |>                                    # thành 2 cột
  setNames(c("Category", "Ty_le")) |>                   # đổi tên cột
  transform(Ty_le = round(100 * Ty_le, 2))              # nhân 100 → %

print(pc_prop_df)
##                Category Ty_le
## 1          Baking Goods  3.44
## 2     Bathroom Products  2.60
## 3         Beer and Wine  2.53
## 4                 Bread  3.02
## 5       Breakfast Foods  2.97
## 6               Candles  0.32
## 7                 Candy  2.50
## 8      Canned Anchovies  0.31
## 9          Canned Clams  0.38
## 10       Canned Oysters  0.25
## 11      Canned Sardines  0.28
## 12        Canned Shrimp  0.27
## 13          Canned Soup  2.87
## 14          Canned Tuna  0.62
## 15 Carbonated Beverages  1.10
## 16    Cleaning Supplies  1.34
## 17        Cold Remedies  0.66
## 18                Dairy  6.42
## 19        Decongestants  0.60
## 20               Drinks  0.96
## 21                 Eggs  1.41
## 22           Electrical  2.53
## 23      Frozen Desserts  2.30
## 24       Frozen Entrees  0.84
## 25                Fruit  5.44
## 26             Hardware  0.92
## 27        Hot Beverages  1.61
## 28              Hygiene  1.40
## 29     Jams and Jellies  4.18
## 30     Kitchen Products  1.54
## 31            Magazines  1.44
## 32                 Meat  5.41
## 33        Miscellaneous  0.30
## 34  Packaged Vegetables  0.34
## 35       Pain Relievers  1.37
## 36       Paper Products  2.45
## 37                Pizza  1.38
## 38     Plastic Products  1.00
## 39 Pure Juice Beverages  1.17
## 40              Seafood  0.73
## 41          Side Dishes  1.09
## 42          Snack Foods 11.38
## 43            Specialty  2.06
## 44        Starchy Foods  1.97
## 45           Vegetables 12.29
freq_df <- table(dt$ProductCategory) |>           # Tạo bảng tần suất đếm số lần xuất hiện mỗi category trong cột ProductCategory của dataframe dt
  as.data.frame() |>                               # Chuyển bảng tần suất (kiểu table) thành dataframe để dễ xử lý (2 cột: category và số lượng)
  setNames(c("Category", "So_luong"))              # Đổi tên 2 cột của dataframe thành "Category" (tên category) và "So_luong" (số lần xuất hiện)
print(freq_df)
##                Category So_luong
## 1          Baking Goods      484
## 2     Bathroom Products      365
## 3         Beer and Wine      356
## 4                 Bread      425
## 5       Breakfast Foods      417
## 6               Candles       45
## 7                 Candy      352
## 8      Canned Anchovies       44
## 9          Canned Clams       53
## 10       Canned Oysters       35
## 11      Canned Sardines       40
## 12        Canned Shrimp       38
## 13          Canned Soup      404
## 14          Canned Tuna       87
## 15 Carbonated Beverages      154
## 16    Cleaning Supplies      189
## 17        Cold Remedies       93
## 18                Dairy      903
## 19        Decongestants       85
## 20               Drinks      135
## 21                 Eggs      198
## 22           Electrical      355
## 23      Frozen Desserts      323
## 24       Frozen Entrees      118
## 25                Fruit      765
## 26             Hardware      129
## 27        Hot Beverages      226
## 28              Hygiene      197
## 29     Jams and Jellies      588
## 30     Kitchen Products      217
## 31            Magazines      202
## 32                 Meat      761
## 33        Miscellaneous       42
## 34  Packaged Vegetables       48
## 35       Pain Relievers      192
## 36       Paper Products      345
## 37                Pizza      194
## 38     Plastic Products      141
## 39 Pure Juice Beverages      165
## 40              Seafood      102
## 41          Side Dishes      153
## 42          Snack Foods     1600
## 43            Specialty      289
## 44        Starchy Foods      277
## 45           Vegetables     1728

Biểu đồ

# Vẽ biểu đồ cột tần suất ProductCategory
ggplot(dt, aes(x = reorder(ProductCategory, ProductCategory, function(x) -length(x)))) +
  geom_bar(fill = "steelblue") +
  coord_flip() +  # Xoay trục để nhãn dễ đọc hơn
  labs(title = "Biểu đồ 10. Tần suất giao dịch theo Product Category",
       x = "Product Category",
       y = "Số giao dịch") +
  theme_minimal()

Nhận xét: Trong bộ dữ liệu, nhóm sản phẩm có tỷ lệ giao dịch cao nhất là Vegetables với 12.29%, tiếp theo là Snack Foods (11.38%) và Dairy (6.42%). Các nhóm đóng hộp như Canned Oysters (0.25%) và Canned Clams (0.38%) chiếm tỷ lệ rất nhỏ, cho thấy sự ưu tiên mua hàng tươi và đồ ăn nhẹ.

Phần 3. ƯỚC LƯỢNG KHOẢNG VÀ KIỂM ĐỊNH GIẢ THUYẾT CHO TỶ LỆ (MỘT BIẾN)

Trong thống kê, khi làm việc với dữ liệu dạng nhị phân (ví dụ: có/không, nam/nữ, đạt/không đạt…), một đại lượng quan trọng thường được quan tâm là tỷ lệ (proportion) – ký hiệu là \(p\). Hai kỹ thuật phổ biến để phân tích tỷ lệ trong quần thể là ước lượng khoảng tin cậykiểm định giả thuyết.

Giả sử chúng ta có một mẫu ngẫu nhiên gồm \(n\) phần tử, trong đó có \(x\) phần tử có đặc điểm quan tâm. Khi đó, tỷ lệ mẫu được tính là:

\[ \hat{p} = \frac{x}{n} \]

Để ước lượng tỷ lệ tổng thể \(p\), ta xây dựng khoảng tin cậy với mức tin cậy \((1 - \alpha) \times 100\%\). Khi kích thước mẫu đủ lớn, khoảng tin cậy được tính như sau:

\[ \hat{p} \pm z_{\alpha/2} \cdot \sqrt{ \frac{\hat{p}(1 - \hat{p})}{n} } \]

Trong đó:

  • \(\hat{p}\): tỷ lệ mẫu
  • \(z_{\alpha/2}\): giá trị tới hạn từ phân phối chuẩn (ví dụ: với mức tin cậy 95%, \(z_{0.025} \approx 1.96\))

Mục tiêu là kiểm định giả thuyết về tỷ lệ tổng thể \(p\). Ví dụ:

  • \(H_0\): \(p = p_0\) (giả thuyết gốc)
  • \(H_1\): \(p \ne p_0\), hoặc \(p > p_0\), hoặc \(p < p_0\) (giả thuyết đối)

Thống kê kiểm định được sử dụng là:

\[ z = \frac{ \hat{p} - p_0 }{ \sqrt{ \frac{p_0 (1 - p_0)}{n} } } \]

So sánh giá trị \(z\) với giá trị tới hạn từ bảng phân phối chuẩn để đưa ra kết luận:

  • Nếu \(|z| > z_{\alpha/2}\), bác bỏ \(H_0\) (trường hợp hai phía)

  • Hoặc dùng p-value để đối chiếu với mức ý nghĩa \(\alpha\)

3.1. Gender (Nữ)

Ước lượng khoảng tin cậy

# Số người nữ (Gender = "F") và tổng số quan sát
n_female <- sum(dt$Gender == "F")
n_total  <- nrow(dt)

# Tính khoảng tin cậy 95% và kiểm định giả thuyết với tỷ lệ kỳ vọng p = 0.5
test_female <- prop.test(n_female, n_total, p = 0.5, correct = FALSE)
  • Tỷ lệ nữ trong dữ liệu là 0.51.

  • Khoảng tin cậy 95% cho tỷ lệ này là từ 0.5017 đến 0.5183.

Kiểm định giả thuyết

Giả thuyết đặt ra như sau:

  • H₀: p = 0.5 (Tỷ lệ nữ thuộc danh mục gender là 50%)

  • H₁: p ≠ 0.5 (Tỷ lệ nữ thuộc danh mục gender khác 50%)

# Kiểm định giả thuyết với prop.test
test_female <- prop.test(n_female, n_total, p = 0.5, correct = FALSE)
test_female
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_female out of n_total, null probability 0.5
## X-squared = 5.6164, df = 1, p-value = 0.01779
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5017287 0.5182531
## sample estimates:
##         p 
## 0.5099936
#Giá trị thống kê Chi-bình phương: 5.6164 với bậc tự do 1.

#Giá trị p = 0.01779.

#Khoảng tin cậy 95% cho tỉ lệ nữ trong tổng thể là từ 0.5017 đến 0.5183.

#Ước lượng tỉ lệ mẫu: 0.5099936 (~50.999%).
  • Với mức ý nghĩa \(\alpha = 0.05\), kết quả kiểm định cho thấy giá trị p là 0.0178.

  • Vì p-value nhỏ hơn 0.05, chúng ta bác bỏ giả thuyết H₀. Vậy tỷ lệ nữ khác 50% .

# test_female$p.value:  Giá trị p (p-value) từ kiểm định tỷ lệ nữ
# ifelse(...):  Hàm điều kiện trong R. Nếu điều kiện đúng thì lấy phần 2, sai thì lấy phần 3

3.2. MaritalStatus (Đã kết hôn_M)

Ước lượng khoảng tin cậy cho tỷ lệ người đã kết hôn

# Số người đã kết hôn (ký hiệu M) và tổng số quan sát
n_married <- sum(dt$MaritalStatus == "M")
n_total   <- nrow(dt)

# Tính khoảng tin cậy 95% và kiểm định giả thuyết
test_married <- prop.test(n_married, n_total, p = 0.5, correct = FALSE)
test_married
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_married out of n_total, null probability 0.5
## X-squared = 7.6057, df = 1, p-value = 0.005818
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4801120 0.4966352
## sample estimates:
##         p 
## 0.4883704
#Giá trị thống kê Chi-bình phương: 7.6057 (df=1).

#Giá trị p = 0.005818.

#Khoảng tin cậy 95% cho tỉ lệ người đã kết hôn trong tổng thể: từ 48.01% đến 49.66%.

#Tỉ lệ mẫu ước lượng: 48.84%.
#p = 0.5:   Tỷ lệ kỳ vọng trong giả thuyết không H₀ (ở đây: H₀: tỷ lệ đã kết hôn = 0.5)

#correct = FALSE:   Không dùng hiệu chỉnh liên tục (continuity correction), cho kết quả gần với lý thuyết hơn khi mẫu lớn
  • Tỷ lệ người đã kết hôn trong dữ liệu là 0.4884.

  • Khoảng tin cậy 95% cho tỷ lệ này là từ 0.4801 đến 0.4966.

# test_married$conf.int[1] → Cận dưới

# test_married$conf.int[2] → Cận trên

Kiểm định giả thuyết

Giả thuyết:

H₀: p = 0.5 (Tỷ lệ người đã kết hôn là 50%)

H₁: p ≠ 0.5 (Tỷ lệ người đã kết hôn khác 50%)

Giá trị p từ kiểm định là: p_value = 0.0058

Với mức ý nghĩa \(\alpha = 0.05\), Vì P_value < 0.05, ta bác bỏ giả thuyết H₀. Do đó, có bằng chứng thống kê cho thấy tỷ lệ người đã kết hôn khác 50% trong tổng thể.

3.3. ProductFamily (Drink)

# Đếm số sản phẩm là Food
n_drink <- sum(dt$ProductFamily == "Drink", na.rm = TRUE)

# Tổng số quan sát
n_total <- nrow(dt)

# Tỷ lệ sản phẩm Food
prop_drink <- n_drink / n_total
prop_drink
## [1] 0.08891102
  • Tỷ lệ sản phẩm Drink trong dữ liệu là 8.89%. Ước lượng khoảng tin cậy cho nhóm sản phẩm Drink

Kiểm định giả thuyết:

Giả thuyết:

  • H₀: p <= 0.09 (Tỷ lệ sản phẩm thuộc nhóm Drink là 9%)

  • H₁: p > 0.09 (Tỷ lệ sản phẩm thuộc nhóm Drink lớn hơn 9%)

test_drink <- prop.test(n_drink, n_total, p = 0.09, alternative = "greater", correct = FALSE)
# # alternative = "greater": kiểm định 1 phía, H1: tỷ lệ thực tế lớn hơn 0.09
test_drink
## 
##  1-sample proportions test without continuity correction
## 
## data:  n_drink out of n_total, null probability 0.09
## X-squared = 0.20357, df = 1, p-value = 0.6741
## alternative hypothesis: true p is greater than 0.09
## 95 percent confidence interval:
##  0.08504142 1.00000000
## sample estimates:
##          p 
## 0.08891102
#Giá trị thống kê Chi-bình phương: 0.20357 (df=1).

#Giá trị p = 0.6741.

#Khoảng tin cậy 95% cho tỉ lệ sản phẩm Drink trong tổng thể là từ 8.5% đến 100% (khoảng trên không giới hạn vì kiểm định một phía).

#Tỉ lệ mẫu ước lượng: 8.89%.
  • Khoảng tin cậy 95% cho tỷ lệ thực tế p: từ 0.0850 đến 1.0000

  • Giá trị p từ kiểm định: P_value = 0.6741.

  • Với mức ý nghĩa \(\alpha = 0.05\), 0.6741, Vì P_value > 0.05, ta không đủ cơ sở bác bỏ giả thuyết H₀.

→ Kết luận: Tỷ lệ sản phẩm Drink không lớn hơn 9%.

3.4. Country

Kiểm định:

H₀: p₁ - p₂ = 0 (tỷ lệ Mexico bằng Canada)

H₁: p₁ - p₂ < 0 (tỷ lệ Mexico nhỏ hơn Canada)

tbl <- table(dt$Country)
tbl
## 
## Canada Mexico    USA 
##    809   3688   9562
x <- c(tbl["Mexico"], tbl["Canada"])  # Số lượng khách hàng mỗi nhóm
n <- c(sum(tbl[c("Mexico", "Canada")]), sum(tbl[c("Mexico", "Canada")]))

prop.test(x = x, n = n, alternative = "less", correct = FALSE)
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  x out of n
## X-squared = 3686.3, df = 1, p-value = 1
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.0000000  0.6535284
## sample estimates:
##    prop 1    prop 2 
## 0.8201023 0.1798977
  • X-squared = 3686.3 Giá trị thống kê kiểm định chi bình phương (Chi-squared). Giá trị này rất lớn, cho thấy có sự khác biệt lớn giữa hai tỷ lệ quan sát được. Tuy nhiên, điều quan trọng là phải xem xét hướng kiểm định mới có thể đưa ra kết luận chính xác. df = 1 Số bậc tự do của kiểm định (vì so sánh 2 nhóm nên df = 1).

  • p-value = 1 Đây là xác suất để quan sát được sự chênh lệch như vậy (hoặc lớn hơn) nếu H₀ là đúng. Với p-value = 1, điều đó có nghĩa là không có bằng chứng nào ủng hộ H₁: p₁ < p₂. Kết quả này là do hướng kiểm định không phù hợp với dữ liệu thực tế.

  • alternative hypothesis: less Kiểm định 1 phía với giả thuyết đối: p₁ < p₂ (Mexico < Canada). Nhưng dữ liệu cho thấy Mexico chiếm 82%, còn Canada chỉ 18%, nên giả thuyết này ngược với thực tế, dẫn đến p-value = 1.

  • 95% confidence interval: (-1.0000000, 0.6535284) Khoảng tin cậy cho hiệu p₁ - p₂. Khoảng này bao gồm cả số 0 và phần dương lớn, cho thấy chưa đủ bằng chứng để khẳng định p₁ < p₂.

  • sample estimates:

    • prop 1 = 0.8201 Tỷ lệ khách hàng đến từ Mexico.
    • prop 2 = 0.1799 Tỷ lệ khách hàng đến từ Canada. Rõ ràng Mexico > Canada, nên việc kiểm định Mexico < Canada là không phù hợp.

Với mức ý nghĩa α = 0.05, vì p-value = 1 > 0.05, ta không bác bỏ giả thuyết H₀. Không có đủ bằng chứng thống kê để kết luận rằng tỷ lệ khách hàng Mexico thấp hơn Canada.

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

4.1. Gender và Homeowner

4.1.1. Bảng tần số

# Bảng tần số chéo (cross-tabulation) giữa Gender và Homeowner
table_gender_homeowner <- table(dt$Gender, dt$Homeowner)
table_gender_homeowner
##    
##        N    Y
##   F 2826 4344
##   M 2789 4100
diff_count <- table_gender_homeowner["F", "Y"] - table_gender_homeowner["M", "Y"]
diff_not_owner_count <-table_gender_homeowner["F", "N"]- table_gender_homeowner["M", "N"]

cat("Nữ sở hữu nhà nhiều hơn nam:", diff_count, "người")
## Nữ sở hữu nhà nhiều hơn nam: 244 người
cat("Nữ không sở hữu nhà nhiều hơn nam:", diff_not_owner_count, "người\n")
## Nữ không sở hữu nhà nhiều hơn nam: 37 người
  • Nhận xét:

    • Trong bộ dữ liệu, có 2826 nữ không sở hữu nhà và 4344 nữ sở hữu nhà. Ngoài ra, có 2789 nam không sở hữu nhà và 4100 nam sở hữu nhà.

    • Số người nữ sở hữu nhà nhiều hơn số người nam sở hữu nhà bằng 244 người.

    • Số người nữ không sở hữu nhà nhiều hơn số người nam không sở hữu nhà bằng 37 người.

# Chuyển sang dataframe
df_gh <- as.data.frame(table_gender_homeowner)
colnames(df_gh) <- c("Gender", "Homeowner", "Count")

# Vẽ biểu đồ
library(ggplot2)
ggplot(df_gh, aes(Gender, Count, fill = Homeowner)) + 
  geom_bar(stat = "identity", position = "dodge") + 
  labs(title = "Bieu do 11. So luong so huu nha theo gioi tinh",
       x = "Gioi tinh", y = "So luong", fill = "So huu nha") + 
  theme_minimal()

4.1.2. Bảng tần suất

# Tổng số mẫu
total_samples <- nrow(dt)

# Tỷ lệ tuyệt đối trên tổng số mẫu
prop_abs <- table_gender_homeowner / total_samples

# Tỷ lệ tương đối trong từng giới tính (theo hàng)
prop_by_gender <- prop.table(table_gender_homeowner, margin = 1) #tính tỷ lệ cho từng hàng, tức là chia từng giá trị trong hàng đó cho tổng của hàng đó.

# In tỷ lệ tuyệt đối trên tổng số mẫu
print("Tỷ lệ tuyệt đối (trên tổng số mẫu):")
## [1] "Tỷ lệ tuyệt đối (trên tổng số mẫu):"
print(round(prop_abs, 4))
##    
##          N      Y
##   F 0.2010 0.3090
##   M 0.1984 0.2916
  • Nhận xét:

    • Trong tổng số mẫu, tỷ lệ nữ không sở hữu nhà là 20.1%, và tỷ lệ nữ sở hữu nhà là 30.9%.
      Tương tự, tỷ lệ nam không sở hữu nhà là 19.84%, và tỷ lệ nam sở hữu nhà là 29.16%.
# In tỷ lệ tương đối trong từng giới tính
print("Tỷ lệ tương đối trong từng giới tính:")
## [1] "Tỷ lệ tương đối trong từng giới tính:"
print(round(prop_by_gender, 4))
##    
##          N      Y
##   F 0.3941 0.6059
##   M 0.4048 0.5952
  • Nhận xét:

    • Trong nhóm nữ, tỷ lệ không sở hữu nhà là 39.41% và tỷ lệ sở hữu nhà là 60.59%.
      Trong nhóm nam, tỷ lệ không sở hữu nhà là 40.48% và tỷ lệ sở hữu nhà là 59.52%.

4.1.3. Kiểm định Thống kê

Giả thuyết kiểm định:

  • H₀: Giới tính và việc sở hữu nhà là hai biến độc lập.

  • H₁: Giới tính và việc sở hữu nhà có liên quan.

Thực hiện kiểm định Chi-bình phương

chi_test <- chisq.test(table_gender_homeowner)
chi_test
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_gender_homeowner
## X-squared = 1.6344, df = 1, p-value = 0.2011
chi_sq_value <- round(chi_test$statistic, 4)
df_value <- chi_test$parameter
p_value <- round(chi_test$p.value, 4)
  • Giá trị thống kê Chi-bình phương: 1.6344

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

  • Giá trị p: p_value = 0.2011

  • Với mức ý nghĩa \(\alpha = 0.05\), vì p_value ≥ 0.05, ta không đủ cơ sở để bác bỏ giả thuyết H₀, tức là không có mối quan hệ đáng kể giữa giới tính và việc sở hữu nhà.

4.2. MaritalStatus và Homeowner

4.2.1. Bảng tần số

# Tạo bảng tần số chéo
table_marital_homeowner <- table(dt$MaritalStatus, dt$Homeowner)

# Hiển thị bảng
table_marital_homeowner
##    
##        N    Y
##   M 1719 5147
##   S 3896 3297
# Tính chênh lệch số lượng người sở hữu nhà giữa Married (M) và Single (S)
diff_owner_count <- table_marital_homeowner["M", "Y"] - table_marital_homeowner["S", "Y"]

# Tính chênh lệch số lượng người KHÔNG sở hữu nhà giữa Married (M) và Single (S)
diff_not_owner_count <- table_marital_homeowner["M", "N"] - table_marital_homeowner["S", "N"]

# In kết quả sở hữu nhà
if (diff_owner_count > 0) {
  message("Người đã kết hôn sở hữu nhiều nhà hơn người độc thân: ", diff_owner_count, " người")
} else {
  message("Người độc thân sở hữu nhiều nhà hơn người kết hôn: ", abs(diff_owner_count), " người")
}
## Người đã kết hôn sở hữu nhiều nhà hơn người độc thân: 1850 người
# In kết quả KHÔNG sở hữu nhà
if (diff_not_owner_count > 0) {
  message("Người đã kết hôn KHÔNG sở hữu nhà nhiều hơn người độc thân: ", diff_not_owner_count, " người")
} else {
  message("Người độc thân KHÔNG sở hữu nhà nhiều hơn người kết hôn: ", abs(diff_not_owner_count), " người")
}
## Người độc thân KHÔNG sở hữu nhà nhiều hơn người kết hôn: 2177 người
  • Nhận xét:

    • Trong bộ dữ liệu, có 3896 người độc thân không sở hữu nhà và 3297 người độc thân sở hữu nhà. Ngoài ra, có 1719 người đã kết hôn không sở hữu nhà và 5147 người đã kết hôn sở hữu nhà.

    • Số người đã kết hôn sở hữu nhà nhiều hơn người độc thân là 1850 người.

    • Người độc thân không sở hữu nhà nhiều hơn người đã kết hôn là 2177 người.

# Chuyển bảng tần số sang dạng data.frame dài
data_long <- as.data.frame.table(table_marital_homeowner)
colnames(data_long) <- c("MaritalStatus", "Homeowner", "Count")

# Lọc nhóm M và S luôn trong ggplot
ggplot(data_long[data_long$MaritalStatus %in% c("M", "S"), ],
       aes(x = MaritalStatus, y = Count, fill = Homeowner)) +
  geom_col(position = "dodge") +
  scale_fill_manual(values = c("N" = "#FF9999", "Y" = "#66CC99"),
                    labels = c("Khong so huu nha", "So huu nha")) +
  labs(title = "Bieu do 12. So sanh so luong nguoi so huu va khong so huu nha theo tinh trang hon nhan",
       x = "Tinh trang hon nhan",
       y = "So luong nguoi",
       fill = "So huu nha") +
  theme_minimal()

4.2.2. Bảng tần suất

# Bảng tần số giữa MaritalStatus và Homeowner
table_marital_homeowner <- table(dt$MaritalStatus, dt$Homeowner)

# Tỷ lệ tuyệt đối so với tổng số mẫu (toàn bộ dataset)
prop_abs <- table_marital_homeowner / total_samples

# Tỷ lệ theo từng hàng (trong từng MaritalStatus)
prop_by_marital <- prop.table(table_marital_homeowner, margin = 1)

# Làm tròn để dễ xem
prop_abs <- round(prop_abs, 4)
prop_by_marital <- round(prop_by_marital, 4)
# In ra bảng tỷ lệ tuyệt đối với tiêu đề
cat("=== Tỷ lệ tuyệt đối theo từng nhóm MaritalStatus và Homeowner (so với tổng số mẫu) ===\n")
## === Tỷ lệ tuyệt đối theo từng nhóm MaritalStatus và Homeowner (so với tổng số mẫu) ===
print(prop_abs)
##    
##          N      Y
##   M 0.1223 0.3661
##   S 0.2771 0.2345
cat("\n=== Tỷ lệ tương đối trong từng nhóm MaritalStatus (tỷ lệ theo hàng) ===\n")
## 
## === Tỷ lệ tương đối trong từng nhóm MaritalStatus (tỷ lệ theo hàng) ===
print(prop_by_marital)
##    
##          N      Y
##   M 0.2504 0.7496
##   S 0.5416 0.4584
  • Trong tổng số mẫu, tỷ lệ những người đã kết hôn (M) sở hữu nhà (Y) là khoảng 36.61%, và không sở hữu nhà (N) là 12.23%.

  • Ở nhóm người độc thân (S), tỷ lệ sở hữu nhà là 23.45%, và không sở hữu nhà là 27.71%.

  • Xét tỷ lệ tương đối trong từng nhóm MaritalStatus:

    • Trong nhóm M, có tới 74.96% là chủ nhà, nghĩa là phần lớn người đã kết hôn sở hữu nhà.
    • Trong nhóm S, tỷ lệ chủ nhà chỉ chiếm 45.84%, thấp hơn khá nhiều so với nhóm M.

Như vậy, ta thấy rằng người đã kết hôn có xu hướng sở hữu nhà cao hơn so với người độc thân.

4.2.3. Kiểm định Thống kê

Giả thuyết kiểm định:

  • H₀: Tình trạng hôn nhân và việc sở hữu nhà là hai biến độc lập.

  • H₁: Tình trạng hôn nhân và việc sở hữu nhà có liên quan.

# Thực hiện kiểm định Chi-bình phương
chisq_result <- chisq.test(table_marital_homeowner)

# Xem kết quả
chisq_result
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table_marital_homeowner
## X-squared = 1241.2, df = 1, p-value < 2.2e-16
# Trích xuất thông tin
# Trích xuất thông tin
chi_sq_value1 <- round(chisq_result$statistic, 4)
df_value1 <- chisq_result$parameter
p_value1 <- round(chisq_result$p.value, 4)
  • Giá trị thống kê Chi-bình phương: 1241.2177

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

  • Giá trị p: p_value = 0

  • Với mức ý nghĩa \(\alpha = 0.05\), vì p_value < 0.05, ta bác bỏ giả thuyết H₀, tức là có mối quan hệ giữa tình trạng hôn nhân và việc sở hữu nhà.

  • Nhận xét:

    • Người đã kết hôn (M) có tỷ lệ sở hữu nhà cao hơn đáng kể so với người độc thân (S).

    • Người đã kết hôn (Married - M) có tỷ lệ sở hữu nhà cao, đạt 74.96%, trong khi đó người độc thân (Single - S) chỉ có tỷ lệ sở hữu nhà là 45.84%.

    • Ngược lại, tỷ lệ không sở hữu nhà ở nhóm độc thân (54.16%) cao hơn nhiều so với nhóm đã kết hôn (25.04%).

    • Điều này phản ánh những điểm quan trọng sau:

      • Kinh tế và trách nhiệm gia đình: Người đã kết hôn thường có thu nhập ổn định hơn hoặc có sự hỗ trợ về tài chính từ cả hai vợ chồng, từ đó khả năng sở hữu nhà cũng cao hơn. Họ thường có xu hướng tìm kiếm sự ổn định lâu dài, dành sự ưu tiên cho việc mua nhà để xây dựng tổ ấm và chăm sóc con cái.

      • Lối sống và ưu tiên của người độc thân: Người độc thân có thể lựa chọn thuê nhà hoặc các hình thức lưu trú linh hoạt hơn, do không bị ràng buộc bởi trách nhiệm gia đình. Họ có thể ưu tiên các cơ hội nghề nghiệp hoặc di chuyển địa lý, nên việc sở hữu nhà không phải là ưu tiên hàng đầu.

4.3. AnnualIncome và ProductCategory

4.3.1. Bảng tần số

# Tạo bảng tần số chéo giữa AnnualIncome và ProductCategory
table_income_product <- table(dt$AnnualIncome, dt$ProductCategory)

# Hiển thị bảng tần số
table_income_product
##                
##                 Baking Goods Bathroom Products Beer and Wine Bread
##   $10K - $30K            119                85            80   108
##   $110K - $130K           18                16            14    23
##   $130K - $150K           22                19            15    24
##   $150K +                 11                 8             3    10
##   $30K - $50K            151               116           121   134
##   $50K - $70K             86                50            61    63
##   $70K - $90K             59                51            39    50
##   $90K - $110K            18                20            23    13
##                
##                 Breakfast Foods Candles Candy Canned Anchovies Canned Clams
##   $10K - $30K               111       6    76               10           12
##   $110K - $130K               7       1    16                2            1
##   $130K - $150K              28       2    19                1            3
##   $150K +                     7       1     8                1            1
##   $30K - $50K               143      21   127               14           20
##   $50K - $70K                62       7    60                8            6
##   $70K - $90K                42       7    29                6            7
##   $90K - $110K               17       0    17                2            3
##                
##                 Canned Oysters Canned Sardines Canned Shrimp Canned Soup
##   $10K - $30K                5               8             9          98
##   $110K - $130K              4               2             0          19
##   $130K - $150K              3               1             2          17
##   $150K +                    1               1             0           8
##   $30K - $50K               10              18            16         137
##   $50K - $70K                5               5             7          67
##   $70K - $90K                5               3             2          50
##   $90K - $110K               2               2             2           8
##                
##                 Canned Tuna Carbonated Beverages Cleaning Supplies
##   $10K - $30K            13                   36                47
##   $110K - $130K           3                    6                 8
##   $130K - $150K           5                    3                 7
##   $150K +                 3                    6                 4
##   $30K - $50K            28                   51                51
##   $50K - $70K            19                   20                35
##   $70K - $90K            10                   23                25
##   $90K - $110K            6                    9                12
##                
##                 Cold Remedies Dairy Decongestants Drinks Eggs Electrical
##   $10K - $30K              23   174            22     30   37         74
##   $110K - $130K             2    38             4      9    9         20
##   $130K - $150K             6    49             5      8   15         21
##   $150K +                   3    17             0      4    4          8
##   $30K - $50K              32   299            31     46   67        114
##   $50K - $70K              12   160             8     19   36         57
##   $70K - $90K              10   126            10     16   20         47
##   $90K - $110K              5    40             5      3   10         14
##                
##                 Frozen Desserts Frozen Entrees Fruit Hardware Hot Beverages
##   $10K - $30K                75             20   150       31            48
##   $110K - $130K              17             10    29        3            11
##   $130K - $150K              17              5    48       10             9
##   $150K +                     8              2    10        1             5
##   $30K - $50K               112             35   252       41            79
##   $50K - $70K                44             21   136       25            33
##   $70K - $90K                36             18   104       13            26
##   $90K - $110K               14              7    36        5            15
##                
##                 Hygiene Jams and Jellies Kitchen Products Magazines Meat
##   $10K - $30K        36              137               47        49  156
##   $110K - $130K       6               31                5        17   41
##   $130K - $150K      14               32               14         9   52
##   $150K +             4                8                3         1   14
##   $30K - $50K        62              185               74        65  253
##   $50K - $70K        37              103               51        36  115
##   $70K - $90K        29               71               20        18  100
##   $90K - $110K        9               21                3         7   30
##                
##                 Miscellaneous Packaged Vegetables Pain Relievers Paper Products
##   $10K - $30K              10                   9             42             70
##   $110K - $130K             1                   1              7             19
##   $130K - $150K             6                   1              8             17
##   $150K +                   0                   2              5              8
##   $30K - $50K               8                  20             61            101
##   $50K - $70K              14                   8             34             67
##   $70K - $90K               2                   7             30             46
##   $90K - $110K              1                   0              5             17
##                
##                 Pizza Plastic Products Pure Juice Beverages Seafood Side Dishes
##   $10K - $30K      50               41                   34      17          36
##   $110K - $130K    13                6                    9       3           2
##   $130K - $150K    12                7                    5       8           8
##   $150K +           1                2                    5       5           3
##   $30K - $50K      59               33                   52      44          53
##   $50K - $70K      31               31                   25      11          23
##   $70K - $90K      15               17                   26      12          23
##   $90K - $110K     13                4                    9       2           5
##                
##                 Snack Foods Specialty Starchy Foods Vegetables
##   $10K - $30K           329        65            70        385
##   $110K - $130K          85        13            18         74
##   $130K - $150K          83        18            15         87
##   $150K +                35         5             5         32
##   $30K - $50K           533        96            85        551
##   $50K - $70K           274        50            48        300
##   $70K - $90K           184        32            28        215
##   $90K - $110K           77        10             8         84
# 1. Tạo dip từ bảng table_income_product
dip <- as.data.frame(table_income_product)
colnames(dip) <- c("AnnualIncome", "ProductCategory", "Frequency")

# 2. Lọc Top 5 sản phẩm theo tổng số lượng mua
library(dplyr)
top_products <- dip %>%
  group_by(ProductCategory) %>%
  summarise(Total = sum(Frequency)) %>%
  arrange(desc(Total)) %>%
  slice_head(n = 5) %>%
  pull(ProductCategory)

dip_top <- dip %>% filter(ProductCategory %in% top_products)

# 3. Vẽ biểu đồ với dip_top
library(RColorBrewer)

ggplot(dip_top, aes(x = AnnualIncome, y = Frequency, fill = ProductCategory)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_fill_brewer(palette = "Set2") +   # hoặc "Dark2", "Pastel1", "Accent", ...
  labs(title = "Biểu đồ 13. Top 5 sản phẩm theo số lượng mua theo mức thu nhập",
       x = "Mức thu nhập",
       y = "Số lượng",
       fill = "Sản phẩm") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# top_products <- dip %>%
#  group_by(ProductCategory) %>%                   # Gom nhóm theo danh mục sản phẩm
#  summarise(Total = sum(Frequency)) %>%           # Tính tổng số lượng mua của từng sản phẩm
#  arrange(desc(Total)) %>%                         # Sắp xếp giảm dần theo tổng số lượng
#  slice_head(n = 5) %>%                            # Lấy 5 sản phẩm đứng đầu
#  pull(ProductCategory)                            # Lấy tên các sản phẩm này thành vector
#ggplot(dip_top, aes(...)): định nghĩa dữ liệu và mapping:

#Trục X là AnnualIncome (mức thu nhập),

#Trục Y là Frequency (số lượng mua),

#Màu cột theo ProductCategory.

#geom_bar(stat = "identity", position = "dodge"):

#stat = "identity": lấy chính giá trị Frequency để vẽ chiều cao cột,

#position = "dodge": các cột của từng loại sản phẩm sẽ đứng cạnh nhau (không chồng lên).

#scale_fill_brewer(palette = "Set2"): chọn bảng màu đẹp, nhẹ mắt từ thư viện RColorBrewer.

#labs(...): đặt tiêu đề, nhãn trục và chú thích màu.

#theme_minimal(): giao diện biểu đồ đơn giản, ít chi tiết rối mắt.

#theme(axis.text.x = element_text(angle = 45, hjust = 1)): xoay nhãn trục X 45 độ để dễ đọc, căn chỉnh hợp lý.

Dựa trên bảng tần số chéo giữa biến AnnualIncome và ProductCategory, chúng ta nhận thấy những xu hướng tiêu dùng khác nhau theo mức thu nhập:

  • Nhóm thu nhập từ $30K - $50K có số lượng giao dịch cao nhất ở hầu hết các danh mục, chẳng hạn như:

    • Snack Foods: 533 giao dịch.

    • Vegetables: 551 giao dịch.

    • Dairy: 299 giao dịch.

    • Đây có thể là do nhóm này đại diện cho tầng lớp trung lưu, có khả năng chi tiêu cao nhưng vẫn chú trọng các mặt hàng thiết yếu, phổ biến.

  • Nhóm thu nhập thấp ($10K - $30K) cũng có lượng giao dịch tương đối cao, đặc biệt trong các danh mục như:

    • Vegetables: 385 giao dịch.

    • Snack Foods: 329 giao dịch.

    • Điều này cho thấy nhu cầu mua các sản phẩm cơ bản và giá cả phải chăng vẫn rất lớn trong nhóm thu nhập thấp.

  • Nhóm thu nhập cao ($150K+ và $130K - $150K) có số lượng giao dịch thấp hơn rõ rệt:

    • Chỉ có 35 giao dịch ở Snack Foods và 32 ở Vegetables.

    • Có thể do số lượng khách thuộc nhóm này ít hơn trong tập dữ liệu hoặc hành vi tiêu dùng khác biệt (ít mua hàng tại siêu thị, ưu tiên sản phẩm cao cấp hoặc mua sắm online).

4.3.2. Bảng tần suất

## --- 2. TỶ LỆ TUYỆT ĐỐI so với toàn bộ mẫu --------------------
total_samples <- nrow(dt)
prop_abs_ip <- round(table_income_product / total_samples, 4)

cat("\n>>> Tỷ lệ tuyệt đối (trên tổng số mẫu):\n")
## 
## >>> Tỷ lệ tuyệt đối (trên tổng số mẫu):
print(prop_abs_ip)
##                
##                 Baking Goods Bathroom Products Beer and Wine  Bread
##   $10K - $30K         0.0085            0.0060        0.0057 0.0077
##   $110K - $130K       0.0013            0.0011        0.0010 0.0016
##   $130K - $150K       0.0016            0.0014        0.0011 0.0017
##   $150K +             0.0008            0.0006        0.0002 0.0007
##   $30K - $50K         0.0107            0.0083        0.0086 0.0095
##   $50K - $70K         0.0061            0.0036        0.0043 0.0045
##   $70K - $90K         0.0042            0.0036        0.0028 0.0036
##   $90K - $110K        0.0013            0.0014        0.0016 0.0009
##                
##                 Breakfast Foods Candles  Candy Canned Anchovies Canned Clams
##   $10K - $30K            0.0079  0.0004 0.0054           0.0007       0.0009
##   $110K - $130K          0.0005  0.0001 0.0011           0.0001       0.0001
##   $130K - $150K          0.0020  0.0001 0.0014           0.0001       0.0002
##   $150K +                0.0005  0.0001 0.0006           0.0001       0.0001
##   $30K - $50K            0.0102  0.0015 0.0090           0.0010       0.0014
##   $50K - $70K            0.0044  0.0005 0.0043           0.0006       0.0004
##   $70K - $90K            0.0030  0.0005 0.0021           0.0004       0.0005
##   $90K - $110K           0.0012  0.0000 0.0012           0.0001       0.0002
##                
##                 Canned Oysters Canned Sardines Canned Shrimp Canned Soup
##   $10K - $30K           0.0004          0.0006        0.0006      0.0070
##   $110K - $130K         0.0003          0.0001        0.0000      0.0014
##   $130K - $150K         0.0002          0.0001        0.0001      0.0012
##   $150K +               0.0001          0.0001        0.0000      0.0006
##   $30K - $50K           0.0007          0.0013        0.0011      0.0097
##   $50K - $70K           0.0004          0.0004        0.0005      0.0048
##   $70K - $90K           0.0004          0.0002        0.0001      0.0036
##   $90K - $110K          0.0001          0.0001        0.0001      0.0006
##                
##                 Canned Tuna Carbonated Beverages Cleaning Supplies
##   $10K - $30K        0.0009               0.0026            0.0033
##   $110K - $130K      0.0002               0.0004            0.0006
##   $130K - $150K      0.0004               0.0002            0.0005
##   $150K +            0.0002               0.0004            0.0003
##   $30K - $50K        0.0020               0.0036            0.0036
##   $50K - $70K        0.0014               0.0014            0.0025
##   $70K - $90K        0.0007               0.0016            0.0018
##   $90K - $110K       0.0004               0.0006            0.0009
##                
##                 Cold Remedies  Dairy Decongestants Drinks   Eggs Electrical
##   $10K - $30K          0.0016 0.0124        0.0016 0.0021 0.0026     0.0053
##   $110K - $130K        0.0001 0.0027        0.0003 0.0006 0.0006     0.0014
##   $130K - $150K        0.0004 0.0035        0.0004 0.0006 0.0011     0.0015
##   $150K +              0.0002 0.0012        0.0000 0.0003 0.0003     0.0006
##   $30K - $50K          0.0023 0.0213        0.0022 0.0033 0.0048     0.0081
##   $50K - $70K          0.0009 0.0114        0.0006 0.0014 0.0026     0.0041
##   $70K - $90K          0.0007 0.0090        0.0007 0.0011 0.0014     0.0033
##   $90K - $110K         0.0004 0.0028        0.0004 0.0002 0.0007     0.0010
##                
##                 Frozen Desserts Frozen Entrees  Fruit Hardware Hot Beverages
##   $10K - $30K            0.0053         0.0014 0.0107   0.0022        0.0034
##   $110K - $130K          0.0012         0.0007 0.0021   0.0002        0.0008
##   $130K - $150K          0.0012         0.0004 0.0034   0.0007        0.0006
##   $150K +                0.0006         0.0001 0.0007   0.0001        0.0004
##   $30K - $50K            0.0080         0.0025 0.0179   0.0029        0.0056
##   $50K - $70K            0.0031         0.0015 0.0097   0.0018        0.0023
##   $70K - $90K            0.0026         0.0013 0.0074   0.0009        0.0018
##   $90K - $110K           0.0010         0.0005 0.0026   0.0004        0.0011
##                
##                 Hygiene Jams and Jellies Kitchen Products Magazines   Meat
##   $10K - $30K    0.0026           0.0097           0.0033    0.0035 0.0111
##   $110K - $130K  0.0004           0.0022           0.0004    0.0012 0.0029
##   $130K - $150K  0.0010           0.0023           0.0010    0.0006 0.0037
##   $150K +        0.0003           0.0006           0.0002    0.0001 0.0010
##   $30K - $50K    0.0044           0.0132           0.0053    0.0046 0.0180
##   $50K - $70K    0.0026           0.0073           0.0036    0.0026 0.0082
##   $70K - $90K    0.0021           0.0051           0.0014    0.0013 0.0071
##   $90K - $110K   0.0006           0.0015           0.0002    0.0005 0.0021
##                
##                 Miscellaneous Packaged Vegetables Pain Relievers Paper Products
##   $10K - $30K          0.0007              0.0006         0.0030         0.0050
##   $110K - $130K        0.0001              0.0001         0.0005         0.0014
##   $130K - $150K        0.0004              0.0001         0.0006         0.0012
##   $150K +              0.0000              0.0001         0.0004         0.0006
##   $30K - $50K          0.0006              0.0014         0.0043         0.0072
##   $50K - $70K          0.0010              0.0006         0.0024         0.0048
##   $70K - $90K          0.0001              0.0005         0.0021         0.0033
##   $90K - $110K         0.0001              0.0000         0.0004         0.0012
##                
##                  Pizza Plastic Products Pure Juice Beverages Seafood
##   $10K - $30K   0.0036           0.0029               0.0024  0.0012
##   $110K - $130K 0.0009           0.0004               0.0006  0.0002
##   $130K - $150K 0.0009           0.0005               0.0004  0.0006
##   $150K +       0.0001           0.0001               0.0004  0.0004
##   $30K - $50K   0.0042           0.0023               0.0037  0.0031
##   $50K - $70K   0.0022           0.0022               0.0018  0.0008
##   $70K - $90K   0.0011           0.0012               0.0018  0.0009
##   $90K - $110K  0.0009           0.0003               0.0006  0.0001
##                
##                 Side Dishes Snack Foods Specialty Starchy Foods Vegetables
##   $10K - $30K        0.0026      0.0234    0.0046        0.0050     0.0274
##   $110K - $130K      0.0001      0.0060    0.0009        0.0013     0.0053
##   $130K - $150K      0.0006      0.0059    0.0013        0.0011     0.0062
##   $150K +            0.0002      0.0025    0.0004        0.0004     0.0023
##   $30K - $50K        0.0038      0.0379    0.0068        0.0060     0.0392
##   $50K - $70K        0.0016      0.0195    0.0036        0.0034     0.0213
##   $70K - $90K        0.0016      0.0131    0.0023        0.0020     0.0153
##   $90K - $110K       0.0004      0.0055    0.0007        0.0006     0.0060
  • Nhóm thu nhập $30K - $50K là nhóm chiếm tỷ lệ mua nhiều nhất ở hầu hết các sản phẩm, cụ thể:
    • Vegetables chiếm khoảng 0.0392 (cao nhất trong các nhóm).
    • Snack Foods chiếm khoảng 0.0379, đứng đầu toàn bộ các nhóm.
    • Fruit chiếm khoảng 0.0179.
  • Ngược lại, nhóm thu nhập cao nhất $150K + có tỷ lệ mua nhiều sản phẩm thường thấp hơn so với nhóm trung bình và thấp, ví dụ:
    • Vegetables chỉ chiếm khoảng 0.0023.
    • Snack Foods chiếm khoảng 0.0025.
  • Nhóm thu nhập thấp nhất $10K - $30K cũng duy trì tỷ lệ mua khá cao ở một số sản phẩm thiết yếu, như:
    • Fruit: khoảng 0.0107, chỉ thấp hơn nhóm $30K - $50K.
    • Vegetables: khoảng 0.0274.
  • Một số mặt hàng như Frozen Desserts có tỷ lệ mua phân bố khá đều giữa các nhóm thu nhập, ví dụ:
    • Nhóm $30K - $50K: 0.008
    • Nhóm $10K - $30K: 0.0053
    • Nhóm $150K +: 0
  • Tổng thể, nhóm thu nhập trung bình thấp ($30K - $50K) là nhóm có hoạt động mua sắm mạnh mẽ nhất, với tỷ lệ tuyệt đối cao hơn hẳn các nhóm khác ở đa số sản phẩm.
## --- 3. TỶ LỆ TƯƠNG ĐỐI theo từng hàng (từng mức thu nhập) ----
prop_by_income <- round(prop.table(table_income_product, margin = 1), 4)

cat("\n>>> Tỷ lệ tương đối trong từng nhóm thu nhập:\n")
## 
## >>> Tỷ lệ tương đối trong từng nhóm thu nhập:
print(prop_by_income)
##                
##                 Baking Goods Bathroom Products Beer and Wine  Bread
##   $10K - $30K         0.0385            0.0275        0.0259 0.0350
##   $110K - $130K       0.0280            0.0249        0.0218 0.0358
##   $130K - $150K       0.0289            0.0250        0.0197 0.0316
##   $150K +             0.0403            0.0293        0.0110 0.0366
##   $30K - $50K         0.0328            0.0252        0.0263 0.0291
##   $50K - $70K         0.0363            0.0211        0.0257 0.0266
##   $70K - $90K         0.0345            0.0298        0.0228 0.0293
##   $90K - $110K        0.0294            0.0326        0.0375 0.0212
##                
##                 Breakfast Foods Candles  Candy Canned Anchovies Canned Clams
##   $10K - $30K            0.0359  0.0019 0.0246           0.0032       0.0039
##   $110K - $130K          0.0109  0.0016 0.0249           0.0031       0.0016
##   $130K - $150K          0.0368  0.0026 0.0250           0.0013       0.0039
##   $150K +                0.0256  0.0037 0.0293           0.0037       0.0037
##   $30K - $50K            0.0311  0.0046 0.0276           0.0030       0.0043
##   $50K - $70K            0.0262  0.0030 0.0253           0.0034       0.0025
##   $70K - $90K            0.0246  0.0041 0.0170           0.0035       0.0041
##   $90K - $110K           0.0277  0.0000 0.0277           0.0033       0.0049
##                
##                 Canned Oysters Canned Sardines Canned Shrimp Canned Soup
##   $10K - $30K           0.0016          0.0026        0.0029      0.0317
##   $110K - $130K         0.0062          0.0031        0.0000      0.0295
##   $130K - $150K         0.0039          0.0013        0.0026      0.0224
##   $150K +               0.0037          0.0037        0.0000      0.0293
##   $30K - $50K           0.0022          0.0039        0.0035      0.0298
##   $50K - $70K           0.0021          0.0021        0.0030      0.0283
##   $70K - $90K           0.0029          0.0018        0.0012      0.0293
##   $90K - $110K          0.0033          0.0033        0.0033      0.0131
##                
##                 Canned Tuna Carbonated Beverages Cleaning Supplies
##   $10K - $30K        0.0042               0.0117            0.0152
##   $110K - $130K      0.0047               0.0093            0.0124
##   $130K - $150K      0.0066               0.0039            0.0092
##   $150K +            0.0110               0.0220            0.0147
##   $30K - $50K        0.0061               0.0111            0.0111
##   $50K - $70K        0.0080               0.0084            0.0148
##   $70K - $90K        0.0059               0.0135            0.0146
##   $90K - $110K       0.0098               0.0147            0.0196
##                
##                 Cold Remedies  Dairy Decongestants Drinks   Eggs Electrical
##   $10K - $30K          0.0074 0.0563        0.0071 0.0097 0.0120     0.0239
##   $110K - $130K        0.0031 0.0591        0.0062 0.0140 0.0140     0.0311
##   $130K - $150K        0.0079 0.0645        0.0066 0.0105 0.0197     0.0276
##   $150K +              0.0110 0.0623        0.0000 0.0147 0.0147     0.0293
##   $30K - $50K          0.0070 0.0650        0.0067 0.0100 0.0146     0.0248
##   $50K - $70K          0.0051 0.0675        0.0034 0.0080 0.0152     0.0241
##   $70K - $90K          0.0059 0.0737        0.0059 0.0094 0.0117     0.0275
##   $90K - $110K         0.0082 0.0653        0.0082 0.0049 0.0163     0.0228
##                
##                 Frozen Desserts Frozen Entrees  Fruit Hardware Hot Beverages
##   $10K - $30K            0.0243         0.0065 0.0485   0.0100        0.0155
##   $110K - $130K          0.0264         0.0156 0.0451   0.0047        0.0171
##   $130K - $150K          0.0224         0.0066 0.0632   0.0132        0.0118
##   $150K +                0.0293         0.0073 0.0366   0.0037        0.0183
##   $30K - $50K            0.0243         0.0076 0.0548   0.0089        0.0172
##   $50K - $70K            0.0186         0.0089 0.0574   0.0105        0.0139
##   $70K - $90K            0.0211         0.0105 0.0609   0.0076        0.0152
##   $90K - $110K           0.0228         0.0114 0.0587   0.0082        0.0245
##                
##                 Hygiene Jams and Jellies Kitchen Products Magazines   Meat
##   $10K - $30K    0.0117           0.0443           0.0152    0.0159 0.0505
##   $110K - $130K  0.0093           0.0482           0.0078    0.0264 0.0638
##   $130K - $150K  0.0184           0.0421           0.0184    0.0118 0.0684
##   $150K +        0.0147           0.0293           0.0110    0.0037 0.0513
##   $30K - $50K    0.0135           0.0402           0.0161    0.0141 0.0550
##   $50K - $70K    0.0156           0.0435           0.0215    0.0152 0.0485
##   $70K - $90K    0.0170           0.0415           0.0117    0.0105 0.0585
##   $90K - $110K   0.0147           0.0343           0.0049    0.0114 0.0489
##                
##                 Miscellaneous Packaged Vegetables Pain Relievers Paper Products
##   $10K - $30K          0.0032              0.0029         0.0136         0.0227
##   $110K - $130K        0.0016              0.0016         0.0109         0.0295
##   $130K - $150K        0.0079              0.0013         0.0105         0.0224
##   $150K +              0.0000              0.0073         0.0183         0.0293
##   $30K - $50K          0.0017              0.0043         0.0133         0.0220
##   $50K - $70K          0.0059              0.0034         0.0143         0.0283
##   $70K - $90K          0.0012              0.0041         0.0176         0.0269
##   $90K - $110K         0.0016              0.0000         0.0082         0.0277
##                
##                  Pizza Plastic Products Pure Juice Beverages Seafood
##   $10K - $30K   0.0162           0.0133               0.0110  0.0055
##   $110K - $130K 0.0202           0.0093               0.0140  0.0047
##   $130K - $150K 0.0158           0.0092               0.0066  0.0105
##   $150K +       0.0037           0.0073               0.0183  0.0183
##   $30K - $50K   0.0128           0.0072               0.0113  0.0096
##   $50K - $70K   0.0131           0.0131               0.0105  0.0046
##   $70K - $90K   0.0088           0.0099               0.0152  0.0070
##   $90K - $110K  0.0212           0.0065               0.0147  0.0033
##                
##                 Side Dishes Snack Foods Specialty Starchy Foods Vegetables
##   $10K - $30K        0.0117      0.1065    0.0210        0.0227     0.1246
##   $110K - $130K      0.0031      0.1322    0.0202        0.0280     0.1151
##   $130K - $150K      0.0105      0.1092    0.0237        0.0197     0.1145
##   $150K +            0.0110      0.1282    0.0183        0.0183     0.1172
##   $30K - $50K        0.0115      0.1158    0.0209        0.0185     0.1198
##   $50K - $70K        0.0097      0.1156    0.0211        0.0203     0.1266
##   $70K - $90K        0.0135      0.1077    0.0187        0.0164     0.1258
##   $90K - $110K       0.0082      0.1256    0.0163        0.0131     0.1370
  • Nhóm thu nhập thấp ($10K - $30K):
    • Tỷ lệ mua cao ở các nhóm sản phẩm thiết yếu như:
      • Vegetables chiếm tỷ lệ cao nhất trong các nhóm thu nhập.
      • Fruit cũng có tỷ lệ mua cao.
      • Các mặt hàng như Breakfast Foods, Dairy, và Snack Foods có tỷ lệ mua tương đối lớn, thể hiện nhu cầu tập trung vào thực phẩm cơ bản và tiện lợi.
  • Nhóm thu nhập trung bình thấp ($30K - $50K):
    • Tỷ lệ mua tương đối đồng đều và cao ở nhiều loại sản phẩm.
    • Các sản phẩm như Vegetables, Snack Foods, Fruit, Frozen Desserts được mua nhiều.
    • Mặt hàng không thiết yếu như CandlesJams and Jellies cũng có tỷ lệ mua ổn, thể hiện chi tiêu đa dạng hơn.
  • Nhóm thu nhập trung bình cao ($90K - $110K, $110K - $130K, $130K - $150K):
    • Tỷ lệ mua thực phẩm chính như Dairy, Vegetables, Fruit ổn định nhưng không vượt trội.
    • Nhóm $130K - $150K có tỷ lệ mua Fruit cao nhất.
    • Các sản phẩm đặc thù như MagazinesMeat có tỷ lệ mua tăng, phản ánh chi tiêu cho mặt hàng cao cấp hoặc đặc thù hơn.
  • Nhóm thu nhập cao ($150K+):
    • Tỷ lệ mua phân bổ đều ở nhiều mặt hàng thiết yếu.
    • Snack FoodsVegetables duy trì tỷ lệ mua cao.
    • Một số sản phẩm như Breakfast Foods có tỷ lệ mua thấp hơn, có thể do thay đổi thói quen tiêu dùng.
    • Mức mua Canned Oysters, Frozen Desserts tương đối ổn định, cho thấy đa dạng lựa chọn.
  • Một số điểm đáng chú ý:
    • Nhóm thu nhập trung bình thấp và trung bình cao có tỷ lệ mua hàng khá tương đồng nhưng nhóm cao hơn chi nhiều cho DairyMeat.
    • Các sản phẩm như Candles, Canned Anchovies, Canned Clams có tỷ lệ mua thấp ở tất cả nhóm, thể hiện đây không phải là hàng phổ biến.
    • Snack Foods luôn giữ tỷ lệ mua cao ở tất cả nhóm, đặc biệt nhóm thu nhập cao và trung bình thấp, thể hiện xu hướng tiêu dùng rộng rãi.

4.3.3. Kiểm định Thống kê

Giả thuyết kiểm định:

H₀: Hai biến AnnualIncome và ProductCategory là độc lập (không có mối liên hệ)

H₁: Hai biến AnnualIncome và ProductCategory có mối liên quan (không độc lập)

# Thực hiện kiểm định Chi-squared
chi_test1 <- chisq.test(table_income_product)
## Warning in chisq.test(table_income_product): Chi-squared approximation may be
## incorrect
# Xem kết quả
chi_test1
## 
##  Pearson's Chi-squared test
## 
## data:  table_income_product
## X-squared = 295.23, df = 308, p-value = 0.6897
chi_sq_value2 <- round(chi_test1$statistic, 4)
df_value2 <- chi_test1$parameter
p_value2 <- round(chi_test1$p.value, 4)
  • Giá trị thống kê Chi-bình phương: 295.2279

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

  • Giá trị p: p_value = 0.6897

  • Với mức ý nghĩa \(\alpha = 0.05\), vì p_value ≥ 0.05, ta không đủ cơ sở để bác bỏ giả thuyết H₀, tức là không có mối quan hệ đáng kể giữa mức thu nhập hàng năm và loại sản phẩm được mua.

Phần 5. PHÂN TÍCH BẢNG NGẪU NHIÊN 2x2

5.1. Giới thiệu

Trong phân tích thống kê định lượng, bảng ngẫu nhiên (contingency table) là một công cụ cơ bản để khảo sát mối liên hệ giữa hai biến phân loại. Trong trường hợp đơn giản nhất, bảng ngẫu nhiên 2x2 biểu diễn sự phân bố của hai biến nhị phân, giúp xác định và đo lường mối liên hệ giữa chúng. Các chỉ số như hiệu tỷ lệ (risk difference), tỷ số nguy cơ (Relative Risk - RR) và tỷ số chênh (Odds Ratio - OR) đóng vai trò quan trọng trong việc lượng hóa mối quan hệ đó. Bài viết này sẽ trình bày chi tiết cấu trúc xác suất sinh ra bảng ngẫu nhiên, phương pháp so sánh hai tỷ lệ, cách xây dựng khoảng tin cậy cho Odds Ratio, và kết thúc bằng một ví dụ thực tiễn trong lĩnh vực kinh doanh.

5.2. Cấu trúc và xác suất của bảng ngẫu nhiên

Một bảng ngẫu nhiên 2x2 là bảng tần suất đếm số quan sát thuộc vào từng tổ hợp của hai biến nhị phân:

\[ \begin{array}{|c|c|c|c|} \hline & \text{Kết quả (+)} & \text{Kết quả (–)} & \text{Tổng} \\ \hline \text{Phơi nhiễm (Yes)} & a & b & a + b \\ \hline \text{Không phơi nhiễm (No)} & c & d & c + d \\ \hline \text{Tổng cộng} & a + c & b + d & n = a + b + c + d \\ \hline \end{array} \]

Để hiểu được sự hình thành của bảng này, cần xác định mô hình xác suất sinh ra dữ liệu — trong đó phổ biến nhất là phân phối PoissonMultinomial.

5.2.1. Phân phối Poisson

Phân phối Poisson thường được sử dụng để mô hình hóa số lượng sự kiện xảy ra trong một khoảng thời gian, không gian hoặc đơn vị cụ thể. Giả sử các sự kiện xảy ra độc lập và với một tỷ lệ trung bình không đổi, mỗi ô trong bảng có thể xem là biến ngẫu nhiên Poisson:

\[ X_{ij} \sim \text{Poisson}(\lambda_{ij}) \]

Ưu điểm:

  • Phù hợp khi tổng số quan sát không cố định.

  • Áp dụng trong phân tích số sự kiện như: số lượt truy cập, số đơn hàng lỗi, v.v.

Hạn chế:

  • Không kiểm soát được tổng số mẫu (n).

5.2.2. Phân phối Multinomial

Trong trường hợp tổng số quan sát \(n\) là cố định, và mỗi quan sát rơi vào một trong bốn ô với xác suất \(p_1, p_2, p_3, p_4\), thì bảng ngẫu nhiên 2x2 có thể được mô hình hóa theo phân phối đa thức Multinomial như sau:

\[ (a, b, c, d) \sim \text{Multinomial}(n; p_1, p_2, p_3, p_4) \]

Phân phối này thường được sử dụng trong các tình huống mà dữ liệu được thu thập từ khảo sát hoặc nghiên cứu xã hội học với kích thước mẫu cố định. Khi đó, các xác suất \(p_1, p_2, p_3, p_4\) biểu diễn xác suất mà một cá thể rơi vào từng ô trong bảng 2x2.

Ưu điểm của mô hình Multinomial:

  • Kiểm soát được tổng số mẫu.

  • Phù hợp cho dữ liệu khảo sát, thử nghiệm.

So sánh giữa phân phối Poisson và Multinomial

Tiêu chí Poisson Multinomial
Tổng số mẫu Không cố định Cố định
Ứng dụng chính Số sự kiện Tần suất khảo sát
Dữ liệu phù hợp Giao dịch, lỗi, tai nạn Trả lời khảo sát, phân nhóm

5.3. Các chỉ số đo mối liên hệ

5.3.1. Hiệu tỷ lệ (Risk Difference - RD)

\[ RD = \frac{a}{a + b} - \frac{c}{c + d} \]

Ý nghĩa:

  • Đo lường chênh lệch tuyệt đối giữa xác suất xảy ra kết quả ở nhóm phơi nhiễm và nhóm không phơi nhiễm.

  • Thường được sử dụng trong đánh giá tác động của chính sách, can thiệp hoặc chương trình thí điểm, khi sự khác biệt về xác suất là quan trọng hơn so với tỷ số.

Khoảng tin cậy 95% (CI) cho RD có thể được ước lượng bằng:

\[ CI_{RD} = RD \pm Z_{1 - \alpha/2} \cdot SE_{RD} \]

Trong đó: - \(Z_{1 - \alpha/2}\) là giá trị tới hạn (thường ≈ 1.96 với 95% CI),

  • \(SE_{RD} = \sqrt{\frac{a(a+b-a)}{(a+b)^3} + \frac{c(c+d-c)}{(c+d)^3}}\)

5.3.2. Tỷ số nguy cơ (Relative Risk - RR)

\[ RR = \frac{a / (a + b)}{c / (c + d)} \]

Ý nghĩa:

  • \(RR > 1\): nguy cơ xảy ra kết quả cao hơn ở nhóm phơi nhiễm.

  • \(RR < 1\): nguy cơ xảy ra kết quả thấp hơn ở nhóm phơi nhiễm.

  • \(RR = 1\): không có mối liên hệ giữa phơi nhiễm và kết quả.

Ta thường lấy log của RR để tính khoảng tin cậy:

\[ CI_{RR} = \exp \left[ \ln(RR) \pm Z_{1 - \alpha/2} \cdot SE_{\ln(RR)} \right] \]

Trong đó:

\[ SE_{\ln(RR)} = \sqrt{ \frac{1}{a} - \frac{1}{a + b} + \frac{1}{c} - \frac{1}{c + d} } \]

Ví dụ trong kinh doanh:

  • Tỷ lệ khách mua hàng khi có khuyến mãi: \(80/100 = 0.8\)

  • Khi không có khuyến mãi: \(40/100 = 0.4\)

  • \(RR = 0.8 / 0.4 = 2\)

⇒ Khuyến mãi làm tăng gấp đôi khả năng khách mua hàng.

Hạn chế:

⚠️ Không sử dụng được trong nghiên cứu bệnh chứng (case-control) vì ta không biết nguy cơ tuyệt đối.

⚠️ Dễ gây hiểu nhầm nếu không đi kèm nguy cơ tuyệt đối. Ví dụ: RR = 2 có vẻ cao, nhưng nếu nguy cơ ban đầu là 1%, thì tăng lên 2% vẫn là rất thấp.

⚠️ Không đối xứng: Nếu đổi nhóm tham chiếu thì giá trị RR thay đổi, khác với OR.

5.3.3. Tỷ số chênh (Odds Ratio - OR)

5.3.3.1. Odds

  • Odds (tỷ số cơ hội):
    \[ \text{Odds} = \frac{p}{1 - p} \] Trong đó, \(p\) là xác suất xảy ra của một biến nhị phân (như việc sở hữu nhà).

5.3.3.1. Odds Ratio - OR

\[ OR = \frac{a / b}{c / d} = \frac{ad}{bc} \]

Hay

\[ \text{OR} = \frac{\text{Odds ở nhóm 1}}{\text{Odds ở nhóm 2}} \] OR thường dùng để đo lường mối liên hệ giữa một yếu tố và một kết quả trong bảng 2x2.

  • OR = 1: Không có sự khác biệt về odds giữa hai nhóm.

  • OR > 1: Nhóm 1 có odds xảy ra kết quả cao hơn nhóm 2.

  • OR < 1: Nhóm 1 có odds xảy ra kết quả thấp hơn nhóm 2.

Ví dụ: OR = 2 nghĩa là odds xảy ra kết quả ở nhóm 1 cao gấp 2 lần nhóm 2.

  • Lưu ý: OR khác với RR, đặc biệt khi biến phụ thuộc không hiếm gặp. Khi kết quả là hiếm (p nhỏ), thì OR ≈ RR.

Ý nghĩa:

  • OR cho biết tỷ lệ odds (tức là “xác suất chia cho 1 trừ xác suất”) giữa hai nhóm.

  • Thường được sử dụng phổ biến trong mô hình logistic regression.

  • Trong các nghiên cứu bệnh hiếm (rare disease assumption), OR xấp xỉ với RR.

Ưu điểm của Odds Ratio:

  • Dễ tính và dễ diễn giải.

  • Ổn định về mặt toán học khi sử dụng trong các mô hình hồi quy.

  • Không phụ thuộc vào tỷ lệ hiện diện trong mẫu (đặc biệt trong các thiết kế bệnh – chứng: case-control study).

5.4. Khoảng ước lượng tin cậy cho ODDS RATIO

Để xác định xem OR có ý nghĩa thống kê hay không, cần xây dựng khoảng tin cậy.

Logarithm tự nhiên của Odds Ratio:

\[ \log(OR) = \log\left( \frac{a \cdot d}{b \cdot c} \right) \]

Sai số chuẩn (Standard Error):

\[ SE = \sqrt{ \frac{1}{a} + \frac{1}{b} + \frac{1}{c} + \frac{1}{d} } \]

Khoảng tin cậy 95% cho \(\log(OR)\):

\[ \log(OR) \pm 1.96 \cdot SE \]

Lấy mũ để có khoảng tin cậy 95% cho OR:

\[ CI_{95\%} = \left[ e^{\log(OR) - 1.96 \cdot SE},\quad e^{\log(OR) + 1.96 \cdot SE} \right] \]

  • Nếu khoảng tin cậy không chứa 1, ta có thể kết luận rằng mối liên hệ có ý nghĩa thống kê ở mức ý nghĩa 5%.

5.5. Ứng dụng trong kinh doanh: HIỆU QUẢ CỦA KHUYẾN MÃI

Một công ty thương mại điện tử thử nghiệm chiến dịch khuyến mãi để kiểm tra xem liệu có ảnh hưởng đến hành vi mua hàng không. Họ lấy mẫu 200 khách hàng ngẫu nhiên và thu được bảng sau:

Mua hàng Không mua Tổng
Có khuyến mãi 80 20 100
Không khuyến mãi 40 60 100
  • Tính Odds Ratio (OR):

\[ OR = \frac{80 \cdot 60}{20 \cdot 40} = \frac{4800}{800} = 6 \]

→ Odds mua hàng khi có khuyến mãi cao gấp 6 lần so với khi không có khuyến mãi.

  • Logarithm tự nhiên của OR:

\[ \log(OR) = \log(6) \approx 1.79 \]

  • Sai số chuẩn (SE):

\[ SE = \sqrt{ \frac{1}{80} + \frac{1}{20} + \frac{1}{40} + \frac{1}{60} } \approx 0.35 \]

  • Khoảng tin cậy 95% cho OR:

\[ CI = \left[ e^{1.79 - 1.96 \cdot 0.35},\quad e^{1.79 + 1.96 \cdot 0.35} \right] \approx \left[ e^{1.11},\quad e^{2.47} \right] = [3.03,\ 11.81] \]

  • Vì khoảng tin cậy không chứa 1, có thể kết luận rằng khuyến mãi có ảnh hưởng có ý nghĩa thống kê đến hành vi mua hàng.

  • Với \(OR = 6\)\(CI = (3.03,\ 11.81)\), doanh nghiệp có thể tự tin triển khai chiến lược khuyến mãi quy mô lớn hơn.

Phần 6. SO SÁNH 2 TỶ LỆ VÀ THƯỚC ĐO MỐI LIÊN HỆ:

6.1. Hiệu hai tỷ lệ (Difference in Proportions):

6.1.1. Bảng chéo 2x2 giữa Gender và Homeowner:

# Bảng chéo giữa Gender và Homeowner
gh <- table(dt$Gender, dt$Homeowner)
addmargins(gh)
##      
##           N     Y   Sum
##   F    2826  4344  7170
##   M    2789  4100  6889
##   Sum  5615  8444 14059

\[ p_1 = P(\text{Homeowner} = Y \mid \text{Gender} = F) \quad \text{(tỷ lệ nữ sở hữu nhà)} \]

\[ p_2 = P(\text{Homeowner} = Y \mid \text{Gender} = M) \quad \text{(tỷ lệ nam sở hữu nhà)} \]

Tính hiệu hai tỷ lệ:

\[ d = p_1 - p_2 \]

Kiểm định:

H₀: p₁ - p₂ = 0 (tỷ lệ nữ sở hữu nhà bằng tỷ lệ nam sở hữu nhà)

H₁: p₁ - p₂ < 0 (Tỷ lệ nữ sở hữu nhà nhỏ hơn tỷ lệ nam sở hữu nhà )

counts <- c(gh["F", "Y"], gh["M", "Y"])   # Số người sở hữu nhà theo từng giới tính
totals <- c(sum(gh["F", ]), sum(gh["M", ]))  # Tổng số người theo từng giới tính

test <- prop.test(counts, totals, alternative = "less", correct = FALSE)
test
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts out of totals
## X-squared = 1.6788, df = 1, p-value = 0.9025
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.00000000  0.02429777
## sample estimates:
##    prop 1    prop 2 
## 0.6058577 0.5951517
  • prop 1 (p1) = 0.6059: tỷ lệ nữ sở hữu nhà khoảng 60.59%

  • prop 2 (p2) = 0.5952: tỷ lệ nam sở hữu nhà khoảng 59.52%

  • P-value = 0.9025

Giá trị p-value thu được là 0.9025, lớn hơn mức ý nghĩa 0.05. Do đó, chúng ta không đủ bằng chứng để bác bỏ giả thuyết H₀ \(H_0: p_1 - p_2 = 0\).

Điều này có nghĩa là, theo dữ liệu hiện tại, không có sự khác biệt có ý nghĩa thống kê giữa tỷ lệ sở hữu nhà của nữ và nam, và không có bằng chứng cho thấy tỷ lệ nữ sở hữu nhà thấp hơn tỷ lệ nam.

6.1.2. Bảng chéo 2x2 giữa MaritalStatus và Homeowner:

mh <- table(dt$MaritalStatus, dt$Homeowner)
mh1 <- addmargins(mh)
print(mh1)
##      
##           N     Y   Sum
##   M    1719  5147  6866
##   S    3896  3297  7193
##   Sum  5615  8444 14059

Giả thuyết kiểm định:

\[ H_0: p_1 - p_2 = 0 \quad \text{(tỷ lệ sở hữu nhà của nhóm Đã kết hôn bằng nhóm Độc thân)} \]

\[ H_1: p_1 - p_2 > 0 \quad \text{(tỷ lệ sở hữu nhà của nhóm Đã kết hôn cao hơn nhóm Độc thân)} \]

Trong đó:
- \(p_1 = P(\text{Homeowner} = Y \mid \text{MaritalStatus} = M)\) là tỷ lệ sở hữu nhà của nhóm Đã kết hôn (Married, M).
- \(p_2 = P(\text{Homeowner} = Y \mid \text{MaritalStatus} = S)\) là tỷ lệ sở hữu nhà của nhóm Độc thân (Single, S).

counts1 <- c(mh["M", "Y"], mh["S", "Y"])
totals1 <- c(sum(mh["M", ]), sum(mh["S", ]))

test1 <- prop.test(counts1, totals1, alternative = "greater", correct = FALSE)
test1
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts1 out of totals1
## X-squared = 1242.4, df = 1, p-value < 2.2e-16
## alternative hypothesis: greater
## 95 percent confidence interval:
##  0.2783377 1.0000000
## sample estimates:
##    prop 1    prop 2 
## 0.7496359 0.4583623
  • prop 1 = 0.7496: tỷ lệ sở hữu nhà của nhóm Đã kết hôn (M) là khoảng 74.96%

  • prop 2 = 0.4584: tỷ lệ sở hữu nhà của nhóm Độc thân (S) là khoảng 45.84%

  • Giá trị p-value rất nhỏ (< 2.2e-16), nhỏ hơn mức ý nghĩa 0.05, cho thấy có bằng chứng thống kê mạnh mẽ để bác bỏ giả thuyết H0. Vậy tỷ lệ sở hữu nhà của nhóm đã kết hôn nhiều hơn của nhóm độc thân.

6.1.3. Bảng chéo 2x2 giữa Gender và MaritalStatus:

# 1. Lập bảng chéo 2x2 giữa Gender và MaritalStatus
gm <- table(dt$Gender, dt$MaritalStatus)
addmargins(gm)  # Thêm hàng và cột tổng
##      
##           M     S   Sum
##   F    3602  3568  7170
##   M    3264  3625  6889
##   Sum  6866  7193 14059

Giả thuyết kiểm định

\[ H_0: p_1 - p_2 = 0 \quad \text{(Tỷ lệ đã kết hôn của nữ bằng nam)} \]

\[ H_1: p_1 - p_2 > 0 \quad \text{(Tỷ lệ đã kết hôn của nữ lớn hơn nam)} \]

Trong đó: - \(p_1 = P(\text{MaritalStatus} = M \mid \text{Gender} = F)\): tỷ lệ nữ đã kết hôn

  • \(p_2 = P(\text{MaritalStatus} = M \mid \text{Gender} = M)\): tỷ lệ nam đã kết hôn
# Trích số lượng người đã kết hôn theo giới
counts3 <- c(gm["F", "M"], gm["M", "M"])
totals3 <- c(sum(gm["F", ]), sum(gm["M", ]))

# Thực hiện kiểm định hiệu hai tỷ lệ
test3 <- prop.test(counts3, totals3, alternative = "greater", correct = FALSE)
test3
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts3 out of totals3
## X-squared = 11.479, df = 1, p-value = 0.0003519
## alternative hypothesis: greater
## 95 percent confidence interval:
##  0.01470685 1.00000000
## sample estimates:
##    prop 1    prop 2 
## 0.5023710 0.4737988

Kết quả kiểm định cho thấy:

  • Tỷ lệ nữ đã kết hôn (\(p_1\)) ≈ 50.24%

  • Tỷ lệ nam đã kết hôn (\(p_2\)) ≈ 47.38%

  • Hiệu hai tỷ lệ: \(d = p_1 - p_2 \approx 0.0286\)

  • Giá trị p-value = 0.00035

  • Khoảng tin cậy 95% cho hiệu tỷ lệ: [0.0147; 1]

p-value < 0.05, ta bác bỏ giả thuyết \(H_0\). Điều này cho thấy có bằng chứng thống kê để kết luận rằng: Tỷ lệ nữ đã kết hôn cao hơn tỷ lệ nam đã kết hôn trong tập dữ liệu khảo sát.

6.2. Tỷ số Nguy cơ (Relative Risk - RR):

6.2.1. Bảng chéo 2x2 giữa Gender và Homeowner:

gh <- table(dt$Gender, dt$Homeowner)
#Thêm tổng hàng và cột
gh1 <- addmargins(gh)
gh1
##      
##           N     Y   Sum
##   F    2826  4344  7170
##   M    2789  4100  6889
##   Sum  5615  8444 14059
riskratio(gh, method="wald")
## $data
##        
##            N    Y Total
##   F     2826 4344  7170
##   M     2789 4100  6889
##   Total 5615 8444 14059
## 
## $measure
##    risk ratio with 95% C.I.
##      estimate     lower    upper
##   F 1.0000000        NA       NA
##   M 0.9823291 0.9561812 1.009192
## 
## $p.value
##    two-sided
##     midp.exact fisher.exact chi.square
##   F         NA           NA         NA
##   M   0.195158    0.1964833  0.1950884
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Nhóm nữ (F) được chọn làm nhóm tham chiếu, nên RR = 1. Điều này có nghĩa chúng ta so sánh nguy cơ sở hữu nhà của nhóm nam (M) với nhóm nữ.

  • Nhóm nam (M) có RR = 0.9823 nghĩa là:

    • Tỷ lệ sở hữu nhà ở nam bằng khoảng 98.23% so với nữ.

` - Hay nói cách khác, nguy cơ (xác suất) sở hữu nhà của nam thấp hơn nữ khoảng 1.77%.

  • Khoảng tin cậy 95% của RR là (0.9562 – 1.0092):

    • Khoảng này bao gồm số 1, nghĩa là giá trị RR thực sự có thể là 1 (không có khác biệt).

    • Khoảng tin cậy cho ta biết mức độ chính xác của ước lượng RR; khoảng rộng và bao gồm 1 cho thấy sự không chắc chắn và thiếu bằng chứng về sự khác biệt thực sự.

Ta có giả thuyết:

H₀: Tỷ lệ sở hữu nhà ở Nam và Nữ không khác nhau, tức là RR = 1.

H₁: Tỷ lệ sở hữu nhà ở Nam và Nữ khác nhau, RR ≠ 1.

Kiểm định p-value (Nam so với Nữ) Ý nghĩa chính
midp.exact 0.1952 p-value chính xác, sử dụng phương pháp “mid-p” (một biến thể chính xác hơn Fisher)
fisher.exact 0.1965 p-value từ kiểm định Fisher chính xác (phù hợp với bảng nhỏ hoặc số liệu ít)
chi.square 0.1951 p-value từ kiểm định Chi-square (xấp xỉ, dựa trên phân phối chi bình phương)

Vì p-value > 0.05, ta không có đủ bằng chứng để nói rằng giới tính ảnh hưởng đáng kể đến khả năng sở hữu nhà.

Nói cách khác, sự khác biệt giữa nhóm Nam và nhóm Nữ về tỷ lệ sở hữu nhà không có ý nghĩa thống kê.

6.2.2. Bảng chéo 2x2 giữa MaritalStatus và Homeowner:

mh <- table(dt$MaritalStatus, dt$Homeowner)
mh1 <- addmargins(mh)
print(mh1)
##      
##           N     Y   Sum
##   M    1719  5147  6866
##   S    3896  3297  7193
##   Sum  5615  8444 14059
riskratio(mh)
## $data
##        
##            N    Y Total
##   M     1719 5147  6866
##   S     3896 3297  7193
##   Total 5615 8444 14059
## 
## $measure
##    risk ratio with 95% C.I.
##      estimate     lower     upper
##   M 1.0000000        NA        NA
##   S 0.6114466 0.5942071 0.6291862
## 
## $p.value
##    two-sided
##     midp.exact  fisher.exact    chi.square
##   M         NA            NA            NA
##   S          0 1.822183e-277 3.663022e-272
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Nhóm đã kết hôn (M) được dùng làm nhóm tham chiếu với RR = 1.

Nhóm độc thân (S) có:

  • RR = 0.6114 (khoảng tin cậy 95%: 0.5942 – 0.6292).

  • Điều này có nghĩa là người độc thân có nguy cơ sở hữu nhà thấp hơn khoảng 38.86% so với người đã kết hôn.

  • Khoảng tin cậy 95% khá hẹp và không bao gồm giá trị 1, cho thấy sự khác biệt này là rõ ràng và đáng tin cậy.

Ta thực hiện kiểm định giả thuyết như sau:

  • H₀: Tỷ lệ sở hữu nhà của người đã kết hôn và độc thân là như nhau (RR = 1).

  • H₁: Tỷ lệ sở hữu nhà của hai nhóm là khác nhau (RR ≠ 1).

Kết quả phân tích chỉ ra RR = 0.6114 với khoảng tin cậy 95% (0.5942 – 0.6292), và các kiểm định cho p-value ≈ 0 < mức ý nghĩa 0.05. Do đó, ta bác bỏ H₀ và kết luận rằng tình trạng hôn nhân có mối liên hệ thống kê rõ rệt với khả năng sở hữu nhà. Người độc thân có khả năng sở hữu nhà thấp hơn đáng kể so với người đã kết hôn.

6.2.3. Bảng chéo 2x2 giữa Gender và MaritalStatus:

# 1. Lập bảng chéo 2x2 giữa Gender và MaritalStatus
gm <- table(dt$Gender, dt$MaritalStatus)
addmargins(gm)  # Thêm hàng và cột tổng
##      
##           M     S   Sum
##   F    3602  3568  7170
##   M    3264  3625  6889
##   Sum  6866  7193 14059
# 3. Tính RR
riskratio(gm)
## $data
##        
##            M    S Total
##   F     3602 3568  7170
##   M     3264 3625  6889
##   Total 6866 7193 14059
## 
## $measure
##    risk ratio with 95% C.I.
##     estimate    lower    upper
##   F 1.000000       NA       NA
##   M 1.057417 1.023813 1.092123
## 
## $p.value
##    two-sided
##       midp.exact fisher.exact   chi.square
##   F           NA           NA           NA
##   M 0.0007045092 0.0007373895 0.0007038837
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Nam giới có nguy cơ đã kết hôn cao hơn nữ giới khoảng 5.7%. Vì RR > 1, điều này cho thấy tỷ lệ kết hôn ở nam cao hơn nữ trong dữ liệu này.

Với p-value < 0.05 và khoảng tin cậy không chứa 1, chúng ta có bằng chứng thống kê để bác bỏ giả thuyết không.
Như vậy, nam giới có tỷ lệ kết hôn cao hơn nữ giới trong bộ dữ liệu này.

6.3. Tỷ số Chênh (Odds Ratio - OR)::

6.3.1. Gender và Homeowner:

# Tính OR và khoảng tin cậy
or_gh <- OddsRatio(gh, method = "wald", conf.level = 0.95)
or_gh
## odds ratio     lwr.ci     upr.ci 
##  0.9563518  0.8939173  1.0231469
  • Kết quả phân tích Odds Ratio giữa giới tính và khả năng sở hữu nhà như sau:

    • Odds Ratio (OR) = 0.956

    • Khoảng tin cậy 95%: từ 0.894 đến 1.023

  • Diễn giải:

    • Giá trị OR = 0.956 cho thấy odds (cơ hội) sở hữu nhà của nữ thấp hơn nam khoảng 4.4%. Tuy nhiên, sự khác biệt là nhỏ.

    • Do khoảng tin cậy 95% chứa giá trị 1, nên:

      • Không có đủ bằng chứng thống kê để kết luận rằng giới tính ảnh hưởng đến odds sở hữu nhà.
  • Kết luận: Mặc dù nữ có vẻ có odds sở hữu nhà thấp hơn nam một chút, nhưng sự khác biệt không có ý nghĩa thống kê. Do đó, giới tính không phải là yếu tố ảnh hưởng rõ rệt đến khả năng sở hữu nhà trong dữ liệu hiện tại.

6.3.2. MaritalStatus và Homeowner:

# Tính OR và khoảng tin cậy
or_mh <- OddsRatio(mh, method = "wald", conf.level = 0.95)
or_mh
## odds ratio     lwr.ci     upr.ci 
##  0.2826322  0.2630929  0.3036227
  • Odds Ratio (OR) = 0.283

  • Khoảng tin cậy 95%: từ 0.263 đến 0.304

  • Diễn giải:

    • Giá trị Odds Ratio 0.283 có nghĩa là odds sở hữu nhà của nhóm người độc thân chỉ bằng khoảng 28.3% odds của nhóm người đã kết hôn. Nói cách khác, người đã kết hôn có khả năng sở hữu nhà cao hơn gần 3.5 lần so với người độc thân (vì 1/0.283≈3.53).

    • Khoảng tin cậy 95% cho Odds Ratio nằm hoàn toàn dưới 1, từ 0.263 đến 0.304, điều này cho thấy sự khác biệt về odds sở hữu nhà giữa hai nhóm là có ý nghĩa thống kê và không phải do ngẫu nhiên.

  • Kết luận:

Dữ liệu cho thấy tình trạng hôn nhân ảnh hưởng rõ ràng đến khả năng sở hữu nhà. Người đã kết hôn có odds sở hữu nhà cao hơn đáng kể so với người độc thân, và khác biệt này là có ý nghĩa thống kê với mức độ tin cậy 95%. Đây là bằng chứng cho thấy việc đã kết hôn có liên quan chặt chẽ đến khả năng sở hữu nhà trong mẫu khảo sát này.

6.3.3. Gender và MaritalStatus:

# Tính OR và khoảng tin cậy
or_gm <- OddsRatio(gm, method = "wald", conf.level = 0.95)
or_gm
## odds ratio     lwr.ci     upr.ci 
##   1.121184   1.049386   1.197893
  • Odds Ratio (OR) = 1.121

  • Khoảng tin cậy 95%: từ 1.049 đến 1.198

  • Diễn giải:

    • Giá trị Odds Ratio 1.121 có nghĩa là odds (cơ hội) đã kết hôn của nữ cao hơn odds đã kết hôn của nam khoảng 12.1%, hay nói cách khác, nữ có khả năng đã kết hôn cao hơn nam khoảng 1.12 lần.

    • Khoảng tin cậy 95% từ 1.049 đến 1.198, không chứa giá trị 1, chứng tỏ sự khác biệt này là có ý nghĩa thống kê. Điều này nghĩa là với mức tin cậy 95%, chúng ta chắc chắn rằng tỷ lệ đã kết hôn của nữ và nam không bằng nhau.

  • Kết luận:

Dữ liệu cho thấy nữ giới có odds đã kết hôn cao hơn nam giới khoảng 12%, tương đương với việc nữ có khả năng đã kết hôn gấp 1.12 lần so với nam giới.

Phần 7. TỔNG KẾT VÀ THẢO LUẬN

7.1. Tóm tắt những phát hiện chính

Dựa trên các phân tích định tính từ bộ dữ liệu 14,059 giao dịch siêu thị, một số đặc điểm nổi bật của khách hàng và hành vi mua sắm có thể rút ra như sau:

  • Cơ cấu giới tính và tình trạng hôn nhân:

    • Khách hàng nữ chiếm ưu thế nhẹ (~51%), với sự chênh lệch không lớn so với nam (~49%).

    • Người độc thân (S) và người đã kết hôn (M) có tỷ lệ gần tương đương, nhưng có sự khác biệt rõ rệt về hành vi sở hữu nhà.

  • Tình trạng sở hữu nhà:

    • Khoảng 60% khách hàng sở hữu nhà, cho thấy phần lớn là nhóm ổn định về kinh tế và chỗ ở.

    • Có mối quan hệ đáng kể giữa MaritalStatus và Homeowner: Người đã kết hôn có xu hướng sở hữu nhà nhiều hơn đáng kể (74.96%) so với người độc thân (45.84%).

  • Phân bố thu nhập:

    • Nhóm $30K - $50K chiếm tỷ lệ cao nhất (32.73%), cho thấy khách hàng chủ yếu thuộc tầng lớp trung lưu.

    • Các nhóm thu nhập cao ($150K+) rất ít (~2%), có thể do thị phần hoặc hành vi mua sắm khác biệt.

  • Địa lý:

    • Các giao dịch chủ yếu đến từ USA (68%), đặc biệt là các bang WA, CA, OR.

    • Các thành phố nổi bật gồm Salem, Tacoma, Los Angeles, chiếm tỷ trọng lớn trong tổng số giao dịch.

  • Hành vi mua sắm theo sản phẩm:

    • Thực phẩm (Food) là nhóm sản phẩm chính (72.2%), đặc biệt là:

      • Vegetables (12.29%)

      • Snack Foods (11.38%)

      • Dairy (6.42%)

    • Các sản phẩm không tiêu thụ được (Non-consumable) chiếm ~19%, và Drink chiếm khoảng 9%.

7.2. Hạn chế của phân tích

Phân tích trong báo cáo này chủ yếu tập trung vào các biến định tính và do đó còn một số hạn chế như sau:

  • Thứ nhất, phân tích chủ yếu tập trung vào các biến định tính như Gender, MaritalStatus, Homeowner, AnnualIncome (dưới dạng phân nhóm), City, ProductFamily và ProductCategory. Việc không đưa vào các biến định lượng như tuổi tác, thu nhập cụ thể (theo số), tổng mức chi tiêu, số lượng giao dịch hay tần suất mua hàng đã làm giảm độ sâu và tính định lượng của các kết luận. Những yếu tố này có thể giúp xác định rõ hơn mối quan hệ giữa đặc điểm khách hàng và hành vi tiêu dùng.

  • Thứ hai, dữ liệu có thể không cân bằng giữa các nhóm, dẫn đến sai lệch trong kết luận. Ví dụ, nhóm thu nhập rất cao hoặc một số thành phố có số lượng quan sát rất nhỏ so với toàn bộ tập dữ liệu, làm giảm tính đại diện và khả năng khái quát hóa. Việc so sánh các nhóm có quy mô khác biệt mà không điều chỉnh trọng số có thể gây hiểu lầm về mức độ ảnh hưởng của từng đặc điểm nhân khẩu học đến hành vi tiêu dùng.

  • Thứ ba, các biến được phân tích có khả năng tương quan lẫn nhau – ví dụ như thu nhập và tình trạng sở hữu nhà, hoặc thu nhập và nơi cư trú – nhưng bài phân tích chưa đánh giá các mối quan hệ chéo này. Việc không kiểm soát ảnh hưởng chéo giữa các biến khiến cho kết luận về tác động riêng lẻ của từng yếu tố có thể chưa hoàn toàn chính xác.

  • Thứ tư, yếu tố giới tính (Gender) tuy được thống kê nhưng chưa được phân tích sâu liên quan đến hành vi tiêu dùng như ưu tiên sản phẩm, mức độ chi tiêu hoặc khác biệt trong lựa chọn theo giới. Trong thực tế, giới tính thường ảnh hưởng đáng kể đến hành vi mua sắm và sở thích tiêu dùng, nên việc không khai thác kỹ khía cạnh này là một điểm thiếu sót đáng kể.

7.3. Đề xuất

Dựa trên các phân tích đã thực hiện, một số đề xuất chiến lược dành cho doanh nghiệp như sau:

  • Tập trung vào phân khúc chủ lực:

    • Các khách hàng thu nhập từ $30K - $70K chiếm tỷ trọng lớn nhất và có xu hướng tiêu dùng mạnh các sản phẩm thiết yếu như rau củ, sữa, đồ ăn nhẹ → cần ưu tiên tiếp cận nhóm này qua các chiến dịch khuyến mãi, combo sản phẩm phù hợp túi tiền.
  • Thiết kế chương trình chăm sóc riêng cho nhóm đã kết hôn sở hữu nhà:

    • Nhóm này có tỷ lệ sở hữu cao và thể hiện sự ổn định → có thể ưu tiên cho các sản phẩm gia đình, nhà bếp, và dịch vụ giao hàng định kỳ.
  • Tái cấu trúc trưng bày sản phẩm và quản lý tồn kho:

    • Tăng diện tích cho các nhóm sản phẩm bán chạy như Vegetables, Snack Foods, Dairy.

    • Rà soát các danh mục có tần suất thấp (như Canned Oysters, Candles) để tối ưu không gian và dòng tiền.

  • Phát triển thị trường theo khu vực địa lý:

    • Tăng cường tiếp thị ở các thành phố có lượng giao dịch lớn như Salem, Tacoma, Los Angeles, đồng thời khảo sát lại hiệu quả kinh doanh ở những khu vực có ít hoạt động.
  • Khuyến khích mở rộng dữ liệu trong tương lai:

    • Doanh nghiệp nên bổ sung các biến định lượng (giá trị đơn hàng, số lần mua), thời gian giao dịch và thông tin cá nhân cơ bản để hỗ trợ phân tích nâng cao, cá nhân hóa chiến lược marketing và cải thiện trải nghiệm khách hàng.

7.4. Đề xuất hướng nghiến cứu tiếp theo

  • Liệu nhóm khách hàng độc thân nhưng có thu nhập cao và sở hữu nhà có hành vi chi tiêu gần giống với nhóm đã kết hôn và thu nhập cao hay không?

    → So sánh hai nhóm có điểm chung về thu nhập và sở hữu nhà nhưng khác tình trạng hôn nhân.

  • Sự kết hợp giữa tình trạng hôn nhân và độ tuổi (nếu có) ảnh hưởng thế nào đến việc lựa chọn nhóm sản phẩm?

    → Ví dụ: Người trẻ đã kết hôn có tiêu dùng khác với người lớn tuổi đã kết hôn?

  • Khách hàng sống tại các khu vực đô thị có xu hướng chi tiêu nhiều hơn cho sản phẩm tiện lợi so với khách hàng nông thôn không?

    → Phân tích theo biến địa lý hoặc thành phố.

  • Những nhóm nhân khẩu học nào chi tiêu cao nhất cho nhóm sản phẩm không tiêu dùng được (Non-consumable)?

    → Ví dụ: Có phải người độc thân, không có nhà, thu nhập cao quan tâm nhiều hơn đến sản phẩm phi thực phẩm?

  • Có sự thay đổi nào trong tỷ trọng chi tiêu giữa các nhóm thu nhập đối với từng danh mục sản phẩm chính (Produce, Dairy, Snack Foods, v.v.)?

    → Phân tích tỷ lệ chi tiêu từng loại theo từng mức thu nhập.

LS0tDQp0aXRsZTogIkJUMiINCmF1dGhvcjogIkzDqiBUaOG7iyBOZ+G7jWMgw4FuaCINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvYzogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogJzQnDQogIHBkZl9kb2N1bWVudDoNCiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQo8c3R5bGU+DQpib2R5IHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBzYW5zLXNlcmlmOw0KICBmb250LXNpemU6IDE2cHg7DQogIHRleHQtYWxpZ246IGp1c3RpZnk7DQogIGxpbmUtaGVpZ2h0OiAxLjU7DQp9DQpoMiB7DQogIGNvbG9yOiByZWQ7DQp9DQpoMyB7DQogIGNvbG9yOiBkYXJrYmx1ZTsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHNraW1yKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoY3N2KQ0KbGlicmFyeShEVCkNCmxpYnJhcnkocGFuZGVyKQ0KbGlicmFyeShmb3JtYXR0YWJsZSkNCmxpYnJhcnkoaHRtbHRvb2xzKQ0KbGlicmFyeShEZXNjVG9vbHMpDQpsaWJyYXJ5KGVwaXRvb2xzKQ0KYGBgDQoNCg0KIyAqKlBo4bqnbiAxLiBUw4xNIEhJ4buCVSBWw4AgQ0hV4bqoTiBC4buKIEThu64gTEnhu4ZVKioNCg0KIyMgKioxLiDEkOG7jWMgZmlsZSBk4buvIGxp4buHdSoqDQpgYGB7ciwgZWNobz1UUlVFfQ0KZCA8LSByZWFkLmNzdigiRDovUFRETERUL1N1cGVybWFya2V0IFRyYW5zYWN0aW9ucy5jc3YiKQ0KYGBgDQoNCiMjICoqMi4gQ+G6pXUgdHLDumMgYuG7mSBk4buvIGxp4buHdSoqDQoNCmBgYHtyfQ0Kc3RyKGQpDQpgYGANCi0gQuG7mSBk4buvIGxp4buHdSAqKmRhdGEqKiBjaOG7qWEgdOG7lW5nIGPhu5luZyAqKjE0LjA1OSBi4bqjbiBnaGkqKiB24bubaSAqKjE2IGJp4bq/bioqIMSR4bq3YyB0csawbmcuDQoNCkPDoWMgYmnhur9uIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgYmFvIGfhu5NtOg0KDQotIGBYYDogYmnhur9uIHPhu5Egbmd1ecOqbiwgY8OzIHRo4buDIGzDoCBjaOG7iSBz4buRIHRo4bupIHThu7EgY+G7p2EgYuG6o24gZ2hpLg0KDQotIGBQdXJjaGFzZURhdGVgOiBuZ8OgeSBtdWEgaMOgbmcsIMSRxrDhu6NjIGzGsHUgZMaw4bubaSBk4bqhbmcgY2h14buXaSBrw70gdOG7sSB24bubaSDEkeG7i25oIGThuqFuZyAiWVlZWS1NTS1ERCIuDQoNCi0gYEN1c3RvbWVySURgOiBtw6MgxJHhu4tuaCBkYW5oIGtow6FjaCBow6BuZyBkxrDhu5tpIGThuqFuZyBz4buRIG5ndXnDqm4uDQoNCi0gYEdlbmRlcmA6IGdp4bubaSB0w61uaCBraMOhY2ggaMOgbmcsIGvDvSBoaeG7h3UgYuG6sW5nIGvDvSB04buxIChGOiBu4buvLCBNOiBuYW0pLg0KDQotIGBNYXJpdGFsU3RhdHVzYDogdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIChTOiDEkeG7mWMgdGjDom4sIE06IMSRw6Mga+G6v3QgaMO0bikuDQoNCi0gYEhvbWVvd25lcmA6IHRy4bqhbmcgdGjDoWkgc+G7nyBo4buvdSBuaMOgIChZOiBjw7MgbmjDoCwgTjoga2jDtG5nIGPDsyBuaMOgKS4NCg0KLSBgQ2hpbGRyZW5gOiBz4buRIGzGsOG7o25nIGNvbiB0cm9uZyBnaWEgxJHDrG5oLCBraeG7g3Ugc+G7kSBuZ3V5w6puLg0KDQotIGBBbm51YWxJbmNvbWVgOiBuaMOzbSB0aHUgbmjhuq1wIGjDoG5nIG7Eg20sIMSRxrDhu6NjIGdoaSBkxrDhu5tpIGThuqFuZyBjaHXhu5dpIGvDvSB04buxICh2w60gZOG7pTogIiQzMEsgLSAkNTBLIikuDQoNCi0gYENpdHlgOiB0w6puIHRow6BuaCBwaOG7kSBuxqFpIGtow6FjaCBow6BuZyBzaW5oIHPhu5FuZy4NCg0KLSBgU3RhdGVvclByb3ZpbmNlYDogYmFuZyBob+G6t2MgdOG7iW5oLCDEkcaw4bujYyBsxrB1IGTGsOG7m2kgZOG6oW5nIGNodeG7l2kga8O9IHThu7EuDQoNCi0gYENvdW50cnlgOiBxdeG7kWMgZ2lhLCBkxrDhu5tpIGThuqFuZyBjaHXhu5dpIGvDvSB04buxLg0KDQotIGBQcm9kdWN0RmFtaWx5YDogbmjDs20gc+G6o24gcGjhuqltIGNow61uaCwgdsOtIGThu6UgbmjGsCBGb29kLCBEcmluaywuLi4NCg0KLSBgUHJvZHVjdERlcGFydG1lbnRgOiBwaMOybmcgYmFuIHPhuqNuIHBo4bqpbSwgdsOtIGThu6UgbmjGsCBTbmFjayBGb29kcywgUHJvZHVjZSwuLi4NCg0KLSBgUHJvZHVjdENhdGVnb3J5YDogZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0gY+G7pSB0aOG7gy4NCg0KLSBgVW5pdHNTb2xkYDogc+G7kSBsxrDhu6NuZyBz4bqjbiBwaOG6qW0gxJHDoyBiw6FuLCBraeG7g3Ugc+G7kSBuZ3V5w6puLg0KDQotIGBSZXZlbnVlYDogZG9hbmggdGh1IHRodSDEkcaw4bujYyB04burIGdpYW8gZOG7i2NoLCBraeG7g3Ugc+G7kSB0aOG7sWMgKMSRxqFuIHbhu4sgVVNEKS4NCg0KVmnhu4djIGhp4buDdSByw7UgY+G6pXUgdHLDumMgdsOgIGtp4buDdSBk4buvIGxp4buHdSBj4bunYSBjw6FjIGJp4bq/biBz4bq9IGjhu5cgdHLhu6MgcuG6pXQgbmhp4buBdSB0cm9uZyB2aeG7h2MgcGjDom4gdMOtY2ggdsOgIHjhu60gbMO9IGThu68gbGnhu4d1IHRp4bq/cCB0aGVvLg0KDQojIyAqKjMuIENo4buNbiBjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oKioNCg0KYGBge3J9DQpkbGR0IDwtIGMoIkdlbmRlciIsICJNYXJpdGFsU3RhdHVzIiwgIkhvbWVvd25lciIsIkFubnVhbEluY29tZSIsIkNpdHkiLCAiU3RhdGVvclByb3ZpbmNlIiwgIkNvdW50cnkiLCAiUHJvZHVjdEZhbWlseSIsICJQcm9kdWN0RGVwYXJ0bWVudCIsICJQcm9kdWN0Q2F0ZWdvcnkiKQ0KZGxkdA0KYGBgDQoNCiMjICoqNC4gVOG6oW8gYuG7mSBk4buvIGxp4buHdSBt4bubaSBjaOG7iSBjaOG7qWEgY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCoqDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQpkdCA8LSBkWywgZGxkdF0NCmBgYA0KDQoNCiMjICoqNS4gTeG7mXQgdsOgaSBkw7JuZyDEkeG6p3UgdsOgIGTDsm5nIGN14buRaSoqDQoNCmBgYHtyfQ0KaGVhZChkdCkNCmBgYA0KDQpgYGB7cn0NCnRhaWwoZHQpDQpgYGANCg0KIyMgKio2LiBLaeG7g20gdHJhIE5BKioNCg0KYGBge3J9DQphbnkoaXMubmEoZHQpKQ0KYGBgDQpW4bqteSBi4buZIGThu68gbGnhu4d1IGtow7RuZyBjw7MgZ2nDoSB0cuG7iyB0aGnhur91DQoNCiMjICoqNy4gS2nhu4NtIHRyYSBraeG7g3UgZOG7ryBsaeG7h3UgdsOgIMSR4buVaSB24buBIGZhY3RvcioqDQpgYGB7cn0NCiMgS2nhu4NtIHRyYSBraeG7g3UgZOG7ryBsaeG7h3UgY+G7p2EgdOG7q25nIGJp4bq/biB0cm9uZyBkbGR0DQpzYXBwbHkoZHQsIGNsYXNzKSANCmBgYA0KLSAiY2hhcmFjdGVyIiwgbmdoxKlhIGzDoCBjaHXhu5dpIGvDvSB04buxICh0ZXh0KS4NCg0KLSBE4buxYSB0csOqbiBr4bq/dCBxdeG6oyBraeG7g20gdHJhIGtp4buDdSBk4buvIGxp4buHdSwgY8OzIHRo4buDIHRo4bqleSBy4bqxbmcgdOG6pXQgY+G6oyBjw6FjIGJp4bq/biB0cm9uZyB04bqtcCBk4buvIGxp4buHdSDEkeG7gXUgxJFhbmcg4bufIGThuqFuZyBjaHXhu5dpIGvDvSB04buxIChjaGFyYWN0ZXIpLiDEkMOieSBsw6AgZOG6pXUgaGnhu4d1IGNobyB0aOG6pXkgZOG7ryBsaeG7h3UgY2jGsGEgxJHGsOG7o2MgeOG7rSBsw70gxJHDum5nIGtp4buDdSwgxJHhurdjIGJp4buHdCBsw6AgxJHhu5FpIHbhu5tpIGPDoWMgYmnhur9uIG5oxrAgQW5udWFsSW5jb21lIOKAkyBs4bq9IHJhIG7Dqm4g4bufIGThuqFuZyBz4buRIChudW1lcmljKSDEkeG7gyBwaOG7pWMgduG7pSBjaG8gY8OhYyBwaMOpcCB0w61uaCB0aOG7kW5nIGvDqiBob+G6t2MgcGjDom4gdMOtY2ggxJHhu4tuaCBsxrDhu6NuZy4gQsOqbiBj4bqhbmggxJHDsywgY8OhYyBiaeG6v24gcGjDom4gbG/huqFpIG5oxrAgR2VuZGVyLCBNYXJpdGFsU3RhdHVzLCBIb21lb3duZXIsIGhheSBQcm9kdWN0Q2F0ZWdvcnkgbsOqbiDEkcaw4bujYyBjaHV54buDbiBzYW5nIGtp4buDdSBmYWN0b3IgxJHhu4MgdGh14bqtbiB0aeG7h24gY2hvIHZp4buHYyBwaMOibiB0w61jaCDEkeG7i25oIHTDrW5oIHbDoCBtw7QgaMOsbmggaMOzYS4gVmnhu4djIMSR4buDIHRvw6BuIGLhu5kgYmnhur9uIOG7nyBk4bqhbmcgY2h14buXaSBrw70gdOG7sSBjw7MgdGjhu4MgZ8OieSByYSBuaGnhu4F1IGjhuqFuIGNo4bq/IHRyb25nIHF1w6EgdHLDrG5oIHjhu60gbMO9IHbDoCBwaMOibiB0w61jaCBk4buvIGxp4buHdSwgZG8gxJHDsyBj4bqnbiB0aOG7sWMgaGnhu4duIGLGsOG7m2MgdGnhu4FuIHjhu60gbMO9IMSR4buDIGNodXnhu4NuIMSR4buVaSBjw6FjIGJp4bq/biB24buBIMSRw7puZyBraeG7g3UgZOG7ryBsaeG7h3UgdMawxqFuZyDhu6luZy4NCg0KYGBge3IsIGVjaG89VFJVRX0NCmR0IDwtIGRhdGEuZnJhbWUobGFwcGx5KGR0LCBhcy5mYWN0b3IpKQ0KYGBgDQoNCiMgKipQaOG6p24gMi4gUEjDgk4gVMONQ0ggTcOUIFThuqIgTeG7mFQgQknhur5OIMSQ4buKTkggVMONTkgqKg0KDQojIyAqKjIuMS4gQmnhur9uIEdlbmRlcioqDQoNCioqQuG6o25nIHThuqduIHN14bqldCoqDQpgYGB7cn0NCiNM4bqtcCBi4bqjbmcgdOG6p24gc3XhuqV0IGPhu6dhIGJp4bq/biBHZW5kZXINCnRhYmxlKGR0JEdlbmRlcikvc3VtKG5yb3coZHQpKQ0KYGBgDQoNCioqQuG6o25nIHThuqduIHPhu5EqKg0KYGBge3J9DQojTOG6rXAgYuG6o25nIHThuqduIHPhu5EgYmnhur9uIEdlbmRlcg0KdGFibGUoZHQkR2VuZGVyKQ0KYGBgDQoNCioqQmnhu4N1IMSR4buTKioNCg0KYGBge3J9DQpnZW5kZXJfZnJlcSAgPC0gdGFibGUoZHQkR2VuZGVyKQ0KZ2VuZGVyX3BjdCAgIDwtIGdlbmRlcl9mcmVxIC8gbnJvdyhkdCkNCmBgYA0KDQpgYGB7cn0NCiMgQsaw4bubYyAxOiBDaHV54buDbiBi4bqjbmcgc2FuZyBkYXRhLmZyYW1lDQpnZW5kZXJfZnJlcSA8LSB0YWJsZShkdCRHZW5kZXIpICAgICAgICAgICAgICAgICAgICAgIyDEkOG6v20gc+G7kSBsxrDhu6NuZyB04burbmcgbmjDs20gZ2nhu5tpIHTDrW5oICh2w60gZOG7pTogIk0iLCAiRiIpLCB0cuG6oyB24buBIMSR4buRaSB0xrDhu6NuZyB0YWJsZQ0KZ2VuZGVyX2RmIDwtIGFzLmRhdGEuZnJhbWUoZ2VuZGVyX2ZyZXEpICAgICAgICAgICAgICMgQ2h1eeG7g24gdOG7qyB0YWJsZSBzYW5nIGRhdGEuZnJhbWUgxJHhu4MgeOG7rSBsw70gZOG7hSBoxqFuIHRyb25nIGdncGxvdDINCmNvbG5hbWVzKGdlbmRlcl9kZikgPC0gYygiR2VuZGVyIiwgIkNvdW50IikgICAgICAgICAjIMSQ4bq3dCB0w6puIGPhu5l0IHLDtSByw6BuZzogIkdlbmRlciIgbMOgIHTDqm4gbmjDs20sICJDb3VudCIgbMOgIHPhu5EgbMaw4bujbmcNCg0KIyBCxrDhu5tjIDI6IFTDrW5oIHBo4bqnbiB0csSDbQ0KZ2VuZGVyX2RmJFBlcmNlbnQgPC0gZ2VuZGVyX2RmJENvdW50IC8gc3VtKGdlbmRlcl9kZiRDb3VudCkgKiAxMDANCg0KIyBCxrDhu5tjIDM6IFThuqFvIG5ow6NuIGdp4buRbmcgbmjGsCB0cm9uZyBwaWUoKQ0KZ2VuZGVyX2RmJExhYmVsIDwtIHBhc3RlMCggICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgR2jDqXAgY2h14buXaSDEkeG7gyB04bqhbyBuaMOjbg0KICBnZW5kZXJfZGYkR2VuZGVyLCAiICgiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgVGjDqm0gdMOqbiBnaeG7m2kgdMOtbmggdsOgIGThuqV1IG3hu58gbmdv4bq3Yw0KICByb3VuZChnZW5kZXJfZGYkUGVyY2VudCwgMSksICIlKSIgICAgICAgICAgICAgICAgICAgICMgTMOgbSB0csOybiBwaOG6p24gdHLEg20gMSBjaOG7ryBz4buRIHbDoCB0aMOqbSBk4bqldSAlDQopDQoNCiMgQsaw4bubYyA0OiBW4bq9IGJp4buDdSDEkeG7kyB0csOybiBi4bqxbmcgZ2dwbG90Mg0KZ2dwbG90KGdlbmRlcl9kZiwgYWVzKHggPSAiIiwgeSA9IENvdW50LCBmaWxsID0gR2VuZGVyKSkgKyAgIyBE4buvIGxp4buHdSB0cnV54buBbiB2w6BvOiBraMO0bmcgY2hpYSB0cuG7pWMgeCwgeSBsw6Agc+G7kSBsxrDhu6NuZywgZmlsbCB0aGVvIGdp4bubaSB0w61uaA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxKSArICAgICAgICAgICAgICAgICAgIyBW4bq9IGPhu5l0IHbhu5tpIGNoaeG7gXUgY2FvIMSRw7puZyB0aGVvIGThu68gbGnhu4d1IChzdGF0ID0gImlkZW50aXR5IiksIGNoaeG7gXUgcuG7mW5nIDENCiAgY29vcmRfcG9sYXIoInkiKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQ2h1eeG7g24gdOG7qyBiaeG7g3UgxJHhu5MgY+G7mXQgc2FuZyBiaeG7g3UgxJHhu5MgdHLDsm4gYuG6sW5nIGPDoWNoIGTDuW5nIHThu41hIMSR4buZIGPhu7FjDQogIHRoZW1lX3ZvaWQoKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIELhu48gdG/DoG4gYuG7mSB0cuG7pWMsIMSRxrDhu51uZyBsxrDhu5tpIHbDoCBu4buBbiDEkeG7gyBsw6BtIHPhuqFjaCBiaeG7g3UgxJHhu5MNCiAgbGFicyh0aXRsZSA9ICJCaeG7g3UgxJHhu5MgMS4gUGjDom4gYuG7kSBnaeG7m2kgdMOtbmggKEdlbmRlcikiKSArICAgICAgICAgICAgICMgVGjDqm0gdGnDqnUgxJHhu4EgcGjDrWEgdHLDqm4gYmnhu4N1IMSR4buTDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBMYWJlbCksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFRow6ptIG5ow6NuIHBo4bqnbiB0csSDbSB2w6BvIHThu6tuZyBsw6F0IGPhu6dhIGJp4buDdSDEkeG7kw0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksICAgICAgICAgIyDEkOG6t3QgduG7iyB0csOtIG5ow6NuIOG7nyBnaeG7r2EgbeG7l2kgbMOhdCAodmp1c3QgPSAwLjUgbMOgIGNhbmggZ2nhu69hIHRoZW8gY2hp4buBdSBk4buNYykNCiAgICAgICAgICAgIHNpemUgPSA1KSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQ+G7oSBjaOG7ryBj4bunYSBuaMOjbg0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJGIiA9ICJsaWdodHBpbmsiLCAgICAgICAgICAgIyBHw6FuIG3DoHUgaOG7k25nIG5o4bqhdCBjaG8gZ2nhu5tpIHTDrW5oICJGIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNIiA9ICJsaWdodGJsdWUiKSkgICAgICAgICAgIyBHw6FuIG3DoHUgeGFuaCBuaOG6oXQgY2hvIGdp4bubaSB0w61uaCAiTSINCmBgYA0KDQoNCioqTmjhuq1uIHjDqXQ6KiogDQoNCmBgYHtyfQ0KY291bnRzIDwtIHRhYmxlKGR0JEdlbmRlcikNCmRpZmZfY291bnQgPC0gYWJzKGNvdW50c1siRiJdIC0gY291bnRzWyJNIl0pDQpgYGANCg0KDQotIFbhuq15IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSBjw7MgYHIgdGFibGUoZHQkR2VuZGVyKVsxXS9zdW0obnJvdyhkdCkpKjEwMGAgXCUgbuG7ryB2w6AgIGByIHRhYmxlKGR0JEdlbmRlcilbMl0vc3VtKG5yb3coZHQpKSoxMDBgXCUgbmFtLg0KDQotIFRyb25nIGLhu5kgZOG7ryBsaeG7h3UsIHPhu5EgbMaw4bujbmcgbuG7ryBsw6AgYHIgY291bnRzWyJGIl1gLCBz4buRIGzGsOG7o25nIG5hbSBsw6AgYHIgY291bnRzWyJNIl1gLiBT4buxIGNow6puaCBs4buHY2ggduG7gSBz4buRIGzGsOG7o25nIGdp4buvYSBu4buvIHbDoCBuYW0gbMOgIGByIGRpZmZfY291bnRgLiBUdXkgc+G7kSBsxrDhu6NuZyBu4buvIGPDsyBwaOG6p24gbmjhu4luaCBoxqFuLCBuaMawbmcgbeG7qWMgY2jDqm5oIGzhu4djaCBsw6Aga2jDtG5nIMSRw6FuZyBr4buDIHNvIHbhu5tpIHThu5VuZyB0aOG7gyBk4buvIGxp4buHdSwgY2hvIHRo4bqleSBjxqEgY+G6pXUgZ2nhu5tpIHTDrW5oIHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgdMawxqFuZyDEkeG7kWkgY8OibiBi4bqxbmcuDQoNCiMjICoqMi4yLiBCaeG6v24gSG9tZW93bmVyKioNCg0KKipC4bqjbmcgdOG6p24gc3XhuqV0KioNCmBgYHtyfQ0KI0zhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIEhvbWVvd25lcg0KdGFibGUoZHQkSG9tZW93bmVyKS9zdW0obnJvdyhkdCkpDQpgYGANCg0KKipC4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCiNM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBiaeG6v24gSG9tZW93bmVyDQp0YWJsZShkdCRIb21lb3duZXIpDQpgYGANCg0KKipCaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCiMgQsaw4bubYyAxOiBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IHbDoCBjaHV54buDbiBzYW5nIGRhdGEuZnJhbWUNCmhvbWVfZnJlcSA8LSB0YWJsZShkdCRIb21lb3duZXIpICAgICAgICAgICAgICAgICAgICAgICMgxJDhur9tIHPhu5EgbMaw4bujbmcgIlkiIHbDoCAiTiINCmhvbWVfZGYgICA8LSBhcy5kYXRhLmZyYW1lKGhvbWVfZnJlcSkgICAgICAgICAgICAgICAgICMgQ2h1eeG7g24gc2FuZyBkYXRhLmZyYW1lIMSR4buDIHbhur0gYuG6sW5nIGdncGxvdDINCmNvbG5hbWVzKGhvbWVfZGYpIDwtIGMoIkhvbWVvd25lciIsICJDb3VudCIpICAgICAgICAgICMgxJDhurd0IGzhuqFpIHTDqm4gY+G7mXQNCg0KIyBCxrDhu5tjIDI6IFTDrW5oIHBo4bqnbiB0csSDbQ0KaG9tZV9kZiRQZXJjZW50IDwtIGhvbWVfZGYkQ291bnQgLyBzdW0oaG9tZV9kZiRDb3VudCkgKiAxMDAgICMgVMOtbmggcGjhuqduIHRyxINtDQoNCiMgQsaw4bubYyAzOiBU4bqhbyBuaMOjbiDEkeG7gyBoaeG7g24gdGjhu4sgdHLDqm4gYmnhu4N1IMSR4buTDQpob21lX2RmJExhYmVsIDwtIHBhc3RlMChob21lX2RmJEhvbWVvd25lciwgIiAoIiwgcm91bmQoaG9tZV9kZiRQZXJjZW50LCAxKSwgIiUpIikNCg0KIyBCxrDhu5tjIDQ6IFbhur0gYmnhu4N1IMSR4buTIHRyw7JuIGLhurFuZyBnZ3Bsb3QyDQpnZ3Bsb3QoaG9tZV9kZiwgYWVzKHggPSAiIiwgeSA9IENvdW50LCBmaWxsID0gSG9tZW93bmVyKSkgKyAgICMgQmnhur9uICJmaWxsIiBz4bq9IHBow6JuIG3DoHUgdGhlbyAiWSIvIk4iDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsgICAgICAgICAgICAgICAgICAgICAjIFThuqFvIGPhu5l0IHRoZW8gc+G7kSBsxrDhu6NuZw0KICBjb29yZF9wb2xhcigieSIpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBDaHV54buDbiBzYW5nIGJp4buDdSDEkeG7kyB0csOybg0KICB0aGVtZV92b2lkKCkgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBYw7NhIHRy4bulYyB2w6AgbuG7gW4NCiAgbGFicyh0aXRsZSA9ICJCaeG7g3UgxJHhu5MgMi4gVOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCAoSG9tZW93bmVyKSIpICsgICAgICAgICAgICAgICAjIFRow6ptIHRpw6p1IMSR4buBDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBMYWJlbCksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIE5ow6NuIHBo4bqnbiB0csSDbSB0csOqbiBsw6F0IGPhuq90DQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlkiID0gImxpZ2h0Z3JlZW4iLCAgICAgICAgICAgICAjIE3DoHUgY2hvIG5ow7NtICJZIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIiA9ICJsaWdodGNvcmFsIikpICAgICAgICAgICAgIyBNw6B1IGNobyBuaMOzbSAiTiINCmBgYA0KDQoqKk5o4bqtbiB4w6l0OioqIA0KYGBge3J9DQpjb3VudHNfaG9tZW93bmVyIDwtIHRhYmxlKGR0JEhvbWVvd25lcikNCmRpZmZfaG9tZW93bmVyIDwtIGFicyhjb3VudHNfaG9tZW93bmVyWyJZIl0gLSBjb3VudHNfaG9tZW93bmVyWyJOIl0pDQpgYGANCg0KDQotIFbhuq15IHRyb25nIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSBjw7MgYHIgdGFibGUoZHQkSG9tZW93bmVyKVsxXS9zdW0obnJvdyhkdCkpKjEwMGAgXCUga2jDtG5nIGPDsyBuaMOgIHbDoCAgYHIgdGFibGUoZHQkSG9tZW93bmVyKVsyXS9zdW0obnJvdyhkdCkpKjEwMGBcJSBjw7MgbmjDoC4NCg0KLSBT4buRIGzGsOG7o25nIG5nxrDhu51pIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgY291bnRzX2hvbWVvd25lclsiWSJdYCwgc+G7kSBsxrDhu6NuZyBuZ8aw4budaSBraMO0bmcgc+G7nyBo4buvdSBsw6AgYHIgY291bnRzX2hvbWVvd25lclsiTiJdYC4gIA0KDQotIFPhu7EgY2jDqm5oIGzhu4djaCB24buBIHPhu5EgbMaw4bujbmcgZ2nhu69hIGhhaSBuaMOzbSBsw6AgYHIgZGlmZl9ob21lb3duZXJgIG5nxrDhu51pLCBuZ2jEqWEgbMOgIHPhu5EgbmfGsOG7nWkgY8OzIG5ow6Agbmhp4buBdSBoxqFuIGtow6EgxJHDoW5nIGvhu4Mgc28gduG7m2kgc+G7kSBuZ8aw4budaSBraMO0bmcgY8OzIG5ow6AuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHBo4bqnbiBs4bubbiBraMOhY2ggaMOgbmcgdHJvbmcgYuG7mSBk4buvIGxp4buHdSB0aHXhu5ljIG5ow7NtIMSRw6Mgc+G7nyBo4buvdSBuaMOgLCB2w6Agc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIGhhaSBuaMOzbSBsw6AgdMawxqFuZyDEkeG7kWkgbOG7m24sIGPDsyB0aOG7gyDhuqNuaCBoxrDhu59uZyDEkeG6v24gY8OhYyBwaMOibiB0w61jaCBsacOqbiBxdWFuIMSR4bq/biDEkWnhu4F1IGtp4buHbiBraW5oIHThur8g4oCTIHjDoyBo4buZaS4NCg0KIyMgKioyLjMuIEJp4bq/biBNYXJpdGFsU3RhdHVzKioNCg0KKipC4bqjbmcgdOG6p24gc3XhuqV0KioNCmBgYHtyfQ0KI0zhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIE1hcml0YWxTdGF0dXMNCnRhYmxlKGR0JE1hcml0YWxTdGF0dXMpL3N1bShucm93KGR0KSkNCmBgYA0KDQoqKkLhuqNuZyB04bqnbiBz4buRKioNCmBgYHtyfQ0KI0zhuq1wIGLhuqNuZyB04bqnbiBz4buRIGPhu6dhIGJp4bq/biBNYXJpdGFsU3RhdHVzDQp0YWJsZShkdCRNYXJpdGFsU3RhdHVzKQ0KYGBgDQoNCioqQmnhu4N1IMSR4buTKioNCmBgYHtyfQ0KIyBCxrDhu5tjIDE6IFThuqFvIGLhuqNuZyB04bqnbiBzdeG6pXQgdsOgIGNodXnhu4NuIHNhbmcgZGF0YS5mcmFtZQ0KbWFyX2ZyZXEgPC0gdGFibGUoZHQkTWFyaXRhbFN0YXR1cykgICAgICAgICAgICAgICAgICAgICAjIMSQ4bq/bSBz4buRIGzGsOG7o25nIHThu6tuZyBuaMOzbSB0cm9uZyBiaeG6v24gTWFyaXRhbFN0YXR1cw0KbWFyX2RmICAgPC0gYXMuZGF0YS5mcmFtZShtYXJfZnJlcSkgICAgICAgICAgICAgICAgICAgICAjIENodXnhu4NuIHThu6sgdGFibGUgc2FuZyBkYXRhLmZyYW1lDQpjb2xuYW1lcyhtYXJfZGYpIDwtIGMoIk1hcml0YWxTdGF0dXMiLCAiQ291bnQiKSAgICAgICAgICMgxJDhurd0IHTDqm4gY+G7mXQ6IE1hcml0YWxTdGF0dXMgbMOgIG5ow7NtLCBDb3VudCBsw6Agc+G7kSBsxrDhu6NuZw0KDQojIELGsOG7m2MgMjogVMOtbmggcGjhuqduIHRyxINtDQptYXJfZGYkUGVyY2VudCA8LSBtYXJfZGYkQ291bnQgLyBzdW0obWFyX2RmJENvdW50KSAqIDEwMCAgIyBUw61uaCBwaOG6p24gdHLEg20gdOG7q25nIG5ow7NtDQoNCiMgQsaw4bubYyAzOiBU4bqhbyBuaMOjbiBoaeG7g24gdGjhu4sNCm1hcl9kZiRMYWJlbCA8LSBwYXN0ZTAobWFyX2RmJE1hcml0YWxTdGF0dXMsICIgKCIsIHJvdW5kKG1hcl9kZiRQZXJjZW50LCAxKSwgIiUpIikgICMgVsOtIGThu6U6ICJTaW5nbGUgKDQ1LjclKSINCg0KIyBCxrDhu5tjIDQ6IFbhur0gYmnhu4N1IMSR4buTIHRyw7JuIGLhurFuZyBnZ3Bsb3QyDQpnZ3Bsb3QobWFyX2RmLCBhZXMoeCA9ICIiLCB5ID0gQ291bnQsIGZpbGwgPSBNYXJpdGFsU3RhdHVzKSkgKyAgIyB4ID0gIiIgxJHhu4MgZ29tIGzhuqFpIHRow6BuaCBt4buZdCB2w7JuZyB0csOybg0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxKSArICAgICAgICAgICAgICAgICAgICAgICAjIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0IHbhu5tpIGNoaeG7gXUgcuG7mW5nIDEgxJHhu4MgdOG6oW8gaMOsbmggdHLDsm4NCiAgY29vcmRfcG9sYXIoInkiKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBDaHV54buDbiBzYW5nIHThu41hIMSR4buZIHRyw7JuIChwaWUgY2hhcnQpDQogIHRoZW1lX3ZvaWQoKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgTG/huqFpIGLhu48gdHLhu6VjLCBsxrDhu5tpLCBu4buBbg0KICBsYWJzKHRpdGxlID0gIkJp4buDdSDEkeG7kyAzLiBQaMOibiBi4buRIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiAoTWFyaXRhbFN0YXR1cykiKSArICMgVGjDqm0gdGnDqnUgxJHhu4EgY2hvIGJp4buDdSDEkeG7kw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gTGFiZWwpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFRow6ptIG5ow6NuIHBo4bqnbiB0csSDbSB2w6BvIHThu6tuZyBsw6F0DQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1KSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFzdGVsMSIpICAgICAgICAgICAgICAgICAgICAgICAgICMgRMO5bmcgYuG6o25nIG3DoHUgbmjhurkgbmjDoG5nIHThu7EgxJHhu5luZyAoaG/hurdjIGNo4buNbiBwYWxldHRlIGtow6FjKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogIA0KDQpgYGB7cn0NCiMgxJDhur9tIHPhu5EgbmfGsOG7nWkga+G6v3QgaMO0biAoTSkgdsOgIMSR4buZYyB0aMOibiAoUykNCm1zX2NvdW50cyA8LSB0YWJsZShkdCRNYXJpdGFsU3RhdHVzKQ0KDQojIENow6puaCBs4buHY2ggduG7gSBz4buRIGzGsOG7o25nIGdp4buvYSBoYWkgbmjDs20NCm1zX2RpZmYgPC0gYWJzKG1zX2NvdW50c1siTSJdIC0gbXNfY291bnRzWyJTIl0pDQpgYGANCg0KLSBW4bqteSB0cm9uZyBi4buZIGThu68gbGnhu4d1IG7DoHkgY8OzIGByIHRhYmxlKGR0JE1hcml0YWxTdGF0dXMpWzFdL3N1bShucm93KGR0KSkqMTAwYCBcJSDEkcOjIGvhur90IGjDtG4gdsOgICBgciB0YWJsZShkdCRNYXJpdGFsU3RhdHVzKVsyXS9zdW0obnJvdyhkdCkpKjEwMGBcJSDEkeG7mWMgdGjDom4uDQoNCi0gQ+G7pSB0aOG7gywgY8OzIGByIG1zX2NvdW50c1siTSJdYCBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gdsOgIGByIG1zX2NvdW50c1siUyJdYCBuZ8aw4budaSDEkeG7mWMgdGjDom4uIE3hurdjIGTDuSBuaMOzbSDEkeG7mWMgdGjDom4gY8OzIHPhu5EgbMaw4bujbmcgY2FvIGjGoW4sIG5oxrBuZyBz4buxIGNow6puaCBs4buHY2ggY2jhu4kgbMOgIGByIG1zX2RpZmZgIG5nxrDhu51pIOKAkyBt4buZdCBjb24gc+G7kSBraMOhIG5o4buPIHNvIHbhu5tpIHThu5VuZyB0aOG7gy4gRG8gxJHDsywgY8OzIHRo4buDIG5o4bqtbiB4w6l0IHLhurFuZyBoYWkgbmjDs20gaMO0biBuaMOibiB0cm9uZyBi4buZIGThu68gbGnhu4d1IGtow6EgY8OibiBi4bqxbmcsIHbDoCBraMO0bmcgY8OzIHPhu7Ega2jDoWMgYmnhu4d0IMSRw6FuZyBr4buDIGdp4buvYSBz4buRIGzGsOG7o25nIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biB2w6AgbmfGsOG7nWkgxJHhu5ljIHRow6JuLg0KDQojIyAqKjIuNC4gQmnhur9uIEFubnVhbEluY29tZSoqDQoNCioqQuG6o25nIHThuqduIHN14bqldCoqDQpgYGB7cn0NCiMgLS0tLSBi4bqjbmcgdOG7tyBs4buHICUgY2hvIENpdHkgLS0tLQ0KYW5udWFsX3Byb3AgPC0gcHJvcC50YWJsZSh0YWJsZShkdCRBbm51YWxJbmNvbWUpKSAgICAgICAgDQoNCiMgQ2h1eeG7g24gdGjDoG5oIGRhdGHigJFmcmFtZQ0KYW5udWFsX3BjdF9kZiA8LSBhcy5kYXRhLmZyYW1lKGFubnVhbF9wcm9wKQ0KbmFtZXMoYW5udWFsX3BjdF9kZikgPC0gYygiQW5udWFsSW5jb21lIiwgIlR5X2xlIikgICAgIyDEkeG6t3QgdMOqbiBj4buZdA0KDQojIE5ow6JuIDEwMCDEkeG7gyB0aMOgbmggcGjhuqduIHRyxINtDQphbm51YWxfcGN0X2RmJFR5X2xlIDwtIHJvdW5kKDEwMCAqIGFubnVhbF9wY3RfZGYkVHlfbGUsIDIpDQoNCnByaW50KGFubnVhbF9wY3RfZGYpDQpgYGANCg0KKipC4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCiMgQuG6o25nIHThuqduIHN14bqldCBjaG8gQ2l0eQ0KYW5udWFsX3RhYiA8LSB0YWJsZShkdCRBbm51YWxJbmNvbWUpDQoNCiMgQ2h1eeG7g24gdGjDoG5oIGRhdGHigJFmcmFtZSAyIGPhu5l0OiBDaXR5IHbDoCBGcmVxDQphbm51YWxfZGYgPC0gYXMuZGF0YS5mcmFtZShhbm51YWxfdGFiKQ0KbmFtZXMoYW5udWFsX2RmKSA8LSBjKCJBbm51YWxJbmNvbWUiLCAiU29fbHVvbmciKSAgICMgxJHhurd0IHTDqm4gY+G7mXQgcsO1IHLDoG5nDQoNCnByaW50KGFubnVhbF9kZikNCmBgYA0KDQoqKkJp4buDdSDEkeG7kyoqDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KZ2dwbG90KGR0LCBhZXMoeCA9IEFubnVhbEluY29tZSkpICsgICAgICAgICAgICAgICAgICAjIMSR4bq3dCBiaeG6v24gQW5udWFsSW5jb21lIGzDqm4gdHLhu6VjIFguDQogIGdlb21fYmFyKCkgKw0KICBjb29yZF9mbGlwKCkgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB4b2F5IG5nYW5nIGNobyBn4buNbg0KICBsYWJzKHRpdGxlID0gIkJp4buDdSDEkeG7kyA0LiBU4bqnbiBz4buRIHRoZW8gVGh1IG5o4bqtcCIsDQogICAgICAgeCA9ICJBbm51YWxJbmNvbWUiLCB5ID0gIlPhu5EgdGh1IG5o4bqtcCIpDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKiANCg0KLSBOaMOzbSB0aHUgbmjhuq1wIGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQgdHJvbmcgYuG7mSBk4buvIGxp4buHdSBsw6AgYHIgYW5udWFsX3BjdF9kZiRBbm51YWxJbmNvbWVbd2hpY2gubWF4KGFubnVhbF9wY3RfZGYkVHlfbGUpXWAsIGNoaeG6v20ga2hv4bqjbmcgYHIgbWF4KGFubnVhbF9wY3RfZGYkVHlfbGUpYCUgdOG7lW5nIHPhu5EgbeG6q3Uga2jhuqNvIHPDoXQuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IG5ow7NtIG7DoHkgbMOgIHThu4dwIGtow6FjaCBow6BuZyBjaMOtbmggaG/hurdjIHBo4buVIGJp4bq/biBuaOG6pXQgdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UuDQoNCi0gTeG7mXQgc+G7kSBuaMOzbSB0aHUgbmjhuq1wIGtow6FjIG5oxrAgYHIgYW5udWFsX3BjdF9kZiRBbm51YWxJbmNvbWVbd2hpY2gubWluKGFubnVhbF9wY3RfZGYkVHlfbGUpXWAgY8OzIHThu7cgbOG7hyBy4bqldCB0aOG6pXAsIGNo4buJIGtob+G6o25nIGByIG1pbihhbm51YWxfcGN0X2RmJFR5X2xlKWAlLCBjaG8gdGjhuqV5IG3hu6ljIMSR4buZIHh14bqldCBoaeG7h24gY+G7p2EgaOG7jSB0cm9uZyBk4buvIGxp4buHdSBraMO0bmcgbmhp4buBdSDigJQgY8OzIHRo4buDIGRvIGjhu40gw610IHF1YW4gdMOibSDEkeG6v24gc+G6o24gcGjhuqltLCBob+G6t2MgbuG6sW0gbmdvw6BpIHBow6JuIGtow7pjIHRo4buLIHRyxrDhu51uZyBtw6AgZG9hbmggbmdoaeG7h3AgxJFhbmcgaMaw4bubbmcgdOG7m2kuDQoNCi0gU+G7sSBwaMOibiBi4buRIHRodSBuaOG6rXAga2jDtG5nIMSR4buBdSBwaOG6o24gw6FuaCBjxqEgY+G6pXUga2jDoWNoIGjDoG5nIGPhu6dhIHNpw6p1IHRo4buLIGhv4bq3YyDEkcahbiB24buLIGto4bqjbyBzw6F0OiB04bqtcCB0cnVuZyBuaGnhu4F1IOG7nyBjw6FjIG5ow7NtIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmggxJHhur9uIHRydW5nIGNhbywgdHJvbmcga2hpIG5ow7NtIHRodSBuaOG6rXAgcXXDoSB0aOG6pXAgaG/hurdjIHF1w6EgY2FvIHh14bqldCBoaeG7h24gw610IGjGoW4uDQoNCi0gxJDDonkgY8OzIHRo4buDIGzDoCBk4bqldSBoaeG7h3UgxJHhu4MgZG9hbmggbmdoaeG7h3AgxJFp4buBdSBjaOG7iW5oIGNoaeG6v24gbMaw4bujYyB0aeG6v3AgY+G6rW4gdGjhu4sgdHLGsOG7nW5nLCBuaMawIHThuq1wIHRydW5nIG5oaeG7gXUgaMahbiB2w6BvIGPDoWMgbmjDs20gdGh1IG5o4bqtcCDEkWFuZyBjaGnhur9tIMawdSB0aOG6vywgaG/hurdjIG3hu58gcuG7mW5nIGPDoWMgY2jDrW5oIHPDoWNoIMawdSDEkcOjaSDEkeG7gyB0aHUgaMO6dCBuaMOzbSBraMOhY2ggaMOgbmcgw610IHBo4buVIGJp4bq/biBoxqFuLg0KDQojIyAqKjIuNS4gQmnhur9uIENpdHkqKg0KDQoqKkLhuqNuZyB04bqnbiBzdeG6pXQqKg0KYGBge3J9DQojIC0tLS0gYuG6o25nIHThu7cgbOG7hyAlIGNobyBDaXR5IC0tLS0NCmNpdHlfcHJvcCA8LSBwcm9wLnRhYmxlKHRhYmxlKGR0JENpdHkpKSAgICAgICAgIyBob+G6t2MgdGFibGUoZHQkQ2l0eSkgLyBucm93KGR0KQ0KDQojIENodXnhu4NuIHRow6BuaCBkYXRh4oCRZnJhbWUNCmNpdHlfcGN0X2RmIDwtIGFzLmRhdGEuZnJhbWUoY2l0eV9wcm9wKQ0KbmFtZXMoY2l0eV9wY3RfZGYpIDwtIGMoIkNpdHkiLCAiVHlfbGUiKSAgICAjIMSR4bq3dCB0w6puIGPhu5l0DQoNCiMgTmjDom4gMTAwIMSR4buDIHRow6BuaCBwaOG6p24gdHLEg20NCmNpdHlfcGN0X2RmJFR5X2xlIDwtIHJvdW5kKDEwMCAqIGNpdHlfcGN0X2RmJFR5X2xlLCAyKQ0KDQpwcmludChjaXR5X3BjdF9kZikNCmBgYA0KDQoqKkLhuqNuZyB04bqnbiBz4buRKioNCmBgYHtyfQ0KIyBC4bqjbmcgdOG6p24gc3XhuqV0IGNobyBDaXR5DQpjaXR5X3RhYiA8LSB0YWJsZShkdCRDaXR5KQ0KDQojIENodXnhu4NuIHRow6BuaCBkYXRh4oCRZnJhbWUgMiBj4buZdDogQ2l0eSB2w6AgRnJlcQ0KY2l0eV9kZiA8LSBhcy5kYXRhLmZyYW1lKGNpdHlfdGFiKQ0KbmFtZXMoY2l0eV9kZikgPC0gYygiQ2l0eSIsICJTb19sdW9uZyIpICAgIyDEkeG6t3QgdMOqbiBj4buZdCByw7UgcsOgbmcNCg0KcHJpbnQoY2l0eV9kZikNCmBgYA0KDQoqKkJp4buDdSDEkeG7kyoqDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KZ2dwbG90KGR0LCBhZXMoeCA9IENpdHkpKSArICAgICAgICAgICAgICAgICAgIyDEkeG6t3QgYmnhur9uIENpdHkgbMOqbiB0cuG7pWMgWC4NCiAgZ2VvbV9iYXIoKSArDQogIGNvb3JkX2ZsaXAoKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHhvYXkgbmdhbmcgY2hvIGfhu41uDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIDUuIFThuqduIHPhu5EgZ2lhbyBk4buLY2ggdGhlbyBDaXR5IiwNCiAgICAgICB4ID0gIkNpdHkiLCB5ID0gIlPhu5EgZ2lhbyBk4buLY2giKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogIA0KLSBUcm9uZyBi4buZIGThu68gbGnhu4d1IG7DoHksIHRow6BuaCBwaOG7kSBjw7MgdOG7tyBs4buHIGdpYW8gZOG7i2NoIGNhbyBuaOG6pXQgbMOgIFNhbGVtIHbhu5tpIGtob+G6o25nIGByIHJvdW5kKHRhYmxlKGR0JENpdHkpWyJTYWxlbSJdL25yb3coZHQpKjEwMCwgMilgJSwgdGnhur9wIHRoZW8gbMOgIFRhY29tYSAoYHIgcm91bmQodGFibGUoZHQkQ2l0eSlbIlRhY29tYSJdL25yb3coZHQpKjEwMCwgMilgJSksIExvcyBBbmdlbGVzIChgciByb3VuZCh0YWJsZShkdCRDaXR5KVsiTG9zIEFuZ2VsZXMiXS9ucm93KGR0KSoxMDAsIDIpYCUpIHbDoCBTZWF0dGxlIChgciByb3VuZCh0YWJsZShkdCRDaXR5KVsiU2VhdHRsZSJdL25yb3coZHQpKjEwMCwgMilgJSkuICANCg0KLSBDw6FjIHRow6BuaCBwaOG7kSBuaOG7jyBoxqFuIG5oxrAgSGlkYWxnbyAoYHIgcm91bmQodGFibGUoZHQkQ2l0eSlbIkhpZGFsZ28iXS9ucm93KGR0KSoxMDAsIDIpYCUpIGhv4bq3YyBHdWFkYWxhamFyYSAoYHIgcm91bmQodGFibGUoZHQkQ2l0eSlbIkd1YWRhbGFqYXJhIl0vbnJvdyhkdCkqMTAwLCAyKWAlKSBjw7MgdOG7tyBs4buHIHRo4bqlcCBoxqFuIG5oaeG7gXUuICANCg0KLSDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBnaWFvIGThu4tjaCBjaOG7pyB54bq/dSB04bqtcCB0cnVuZyDhu58gbeG7mXQgc+G7kSB0aMOgbmggcGjhu5EgbOG7m24gduG7m2kgZMOibiBz4buRIGhv4bq3YyBob+G6oXQgxJHhu5luZyBraW5oIHThur8gY2FvIGjGoW4uIEPDoWMgdGjDoG5oIHBo4buRIG5o4buPIGjGoW4gxJHDs25nIGfDs3Agw610IGjGoW4gdsOgbyB04buVbmcgc+G7kSBnaWFvIGThu4tjaCwgY8OzIHRo4buDIGRvIHF1eSBtw7QgdGjhu4sgdHLGsOG7nW5nIG5o4buPIGhv4bq3YyBt4bupYyDEkeG7mSBwaOG7lSBiaeG6v24gY+G7p2Egc+G6o24gcGjhuqltIHRo4bqlcC4gIA0KDQotIE5nb8OgaSByYSwgdmnhu4djIHBow6JuIGLhu5EgbsOgeSBjxaluZyBjw7MgdGjhu4MgcGjhuqNuIMOhbmggY2hp4bq/biBsxrDhu6NjIHRp4bq/cCB0aOG7iyBob+G6t2Mga8OqbmggcGjDom4gcGjhu5FpIG3DoCBzacOqdSB0aOG7iyDEkWFuZyB04bqtcCB0cnVuZyB2w6BvIGPDoWMga2h1IHbhu7FjIMSRw7QgdGjhu4sgbOG7m24uDQoNCiMjICoqMi42LiBCaeG6v24gU3RhdGVvclByb3ZpbmNlKioNCg0KKipC4bqjbmcgdOG6p24gc3XhuqV0KioNCmBgYHtyfQ0KI0zhuq1wIGLhuqNuZyB04bqnbiBzdeG6pXQgY+G7p2EgYmnhur9uIFN0YXRlb3JQcm92aW5jZQ0KdGFibGUoZHQkU3RhdGVvclByb3ZpbmNlKS9zdW0obnJvdyhkdCkpDQpgYGANCg0KKipC4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCiNM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBj4bunYSBiaeG6v24gU3RhdGVvclByb3ZpbmNlDQp0YWJsZShkdCRTdGF0ZW9yUHJvdmluY2UpDQpgYGANCg0KKipCaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCmdncGxvdChkdCwgYWVzKHggPSBTdGF0ZW9yUHJvdmluY2UpKSArDQogIGdlb21fYmFyKCkgKw0KICBjb29yZF9mbGlwKCkgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB4b2F5IHRy4bulYyBjaG8gZ+G7jW4NCiAgbGFicyh0aXRsZSA9ICJCaeG7gXUgxJHhu5MgNi4gVOG6p24gc+G7kSBnaWFvIGThu4tjaCB0aGVvIFN0YXRlIC8gUHJvdmluY2UiLA0KICAgICAgIHggPSAiU3RhdGUgLyBQcm92aW5jZSIsDQogICAgICAgeSA9ICJT4buRIGdpYW8gZOG7i2NoIikNCmBgYA0KDQoqKk5o4bqtbiB4w6l0OioqIFRyb25nIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSwgYmFuZyBob+G6t2MgdOG7iW5oIGPDsyB04bu3IGzhu4cgZ2lhbyBk4buLY2ggbOG7m24gbmjhuqV0IGzDoCBXQSB24bubaSBraG/huqNuZyBgciByb3VuZCh0YWJsZShkdCRTdGF0ZW9yUHJvdmluY2UpWyJXQSJdL25yb3coZHQpKjEwMCwgMilgJSwgdGnhur9wIHRoZW8gbMOgIENBIChgciByb3VuZCh0YWJsZShkdCRTdGF0ZW9yUHJvdmluY2UpWyJDQSJdL25yb3coZHQpKjEwMCwgMilgJSkgdsOgIE9SIChgciByb3VuZCh0YWJsZShkdCRTdGF0ZW9yUHJvdmluY2UpWyJPUiJdL25yb3coZHQpKjEwMCwgMilgJSkuIEPDoWMgYmFuZyBuaMawIEphbGlzY28gKGByIHJvdW5kKHRhYmxlKGR0JFN0YXRlb3JQcm92aW5jZSlbIkphbGlzY28iXS9ucm93KGR0KSoxMDAsIDIpYCUpIHbDoCBHdWVycmVybyAoYHIgcm91bmQodGFibGUoZHQkU3RhdGVvclByb3ZpbmNlKVsiR3VlcnJlcm8iXS9ucm93KGR0KSoxMDAsIDIpYCUpIGNoaeG6v20gdOG7tyBs4buHIHRo4bqlcCBoxqFuLiBOaMawIHbhuq15LCBk4buvIGxp4buHdSBjaG8gdGjhuqV5IHPhu7EgdOG6rXAgdHJ1bmcgZ2lhbyBk4buLY2ggY2FvIOG7nyBt4buZdCBz4buRIGJhbmcgY2jDrW5oLg0KDQojIyAqKjIuNy4gQmnhur9uIENvdW50cnkqKg0KDQoqKkLhuqNuZyB04bqnbiBzdeG6pXQqKg0KYGBge3J9DQojTOG6rXAgYuG6o25nIHThuqduIHN14bqldCBj4bunYSBiaeG6v24gQ291bnRyeQ0KdGFibGUoZHQkQ291bnRyeSkvc3VtKG5yb3coZHQpKQ0KYGBgDQoNCioqQuG6o25nIHThuqduIHPhu5EqKg0KYGBge3J9DQojTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY+G7p2EgYmnhur9uIENvdW50cnkNCnRhYmxlKGR0JENvdW50cnkpDQpgYGANCg0KKipCaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCiMgQsaw4bubYyAxOiBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IHbDoCBjaHV54buDbiBzYW5nIGRhdGEuZnJhbWUNCmNvdW50cnlfZnJlcSA8LSB0YWJsZShkdCRDb3VudHJ5KSAgICAgICAgICAgICAgICAgICAgICAjIMSQ4bq/bSBz4buRIGzGsOG7o25nIHThu6tuZyBxdeG7kWMgZ2lhIHRyb25nIGJp4bq/biBDb3VudHJ5DQpjb3VudHJ5X2RmICAgPC0gYXMuZGF0YS5mcmFtZShjb3VudHJ5X2ZyZXEpICAgICAgICAgICAgIyBDaHV54buDbiB04burIHRhYmxlIHNhbmcgZGF0YS5mcmFtZSDEkeG7gyB44butIGzDvSBi4bqxbmcgZ2dwbG90Mg0KY29sbmFtZXMoY291bnRyeV9kZikgPC0gYygiQ291bnRyeSIsICJDb3VudCIpICAgICAgICAgICMgxJDhurd0IGzhuqFpIHTDqm4gY+G7mXQ6ICJDb3VudHJ5IiBsw6AgdMOqbiBuaMOzbSwgIkNvdW50IiBsw6Agc+G7kSBsxrDhu6NuZw0KDQojIELGsOG7m2MgMjogVMOtbmggcGjhuqduIHRyxINtDQpjb3VudHJ5X2RmJFBlcmNlbnQgPC0gY291bnRyeV9kZiRDb3VudCAvIHN1bShjb3VudHJ5X2RmJENvdW50KSAqIDEwMCAgIyBUw61uaCBwaOG6p24gdHLEg20NCg0KIyBCxrDhu5tjIDM6IFThuqFvIG5ow6NuIHBo4bqnbiB0csSDbSBoaeG7g24gdGjhu4sgdHLDqm4gbMOhdCBj4bqvdA0KY291bnRyeV9kZiRMYWJlbCA8LSBwYXN0ZTAoY291bnRyeV9kZiRDb3VudHJ5LCAiICgiLCByb3VuZChjb3VudHJ5X2RmJFBlcmNlbnQsIDEpLCAiJSkiKSAgIyBWw60gZOG7pTogIlVTQSAoNDUuMyUpIg0KDQojIELGsOG7m2MgNDogVuG6vSBiaeG7g3UgxJHhu5MgdHLDsm4gYuG6sW5nIGdncGxvdDINCmdncGxvdChjb3VudHJ5X2RmLCBhZXMoeCA9ICIiLCB5ID0gQ291bnQsIGZpbGwgPSBDb3VudHJ5KSkgKyAgICMgS2jDtG5nIGNoaWEgdHLhu6VjIHgsIGNoaWEgbcOgdSB0aGVvIENvdW50cnkNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKyAgICAgICAgICAgICAgICAgICAgICMgVuG6vSBj4buZdCB0aGVvIHPhu5EgbMaw4bujbmcsIMSR4buZIHLhu5luZyAxIMSR4buDIGzDoG0gaMOsbmggdHLDsm4NCiAgY29vcmRfcG9sYXIoInkiKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQ2h1eeG7g24gc2FuZyBiaeG7g3UgxJHhu5MgdHLDsm4NCiAgdGhlbWVfdm9pZCgpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgWMOzYSB0cuG7pWMsIMSRxrDhu51uZyBsxrDhu5tpIHbDoCBu4buBbg0KICBsYWJzKHRpdGxlID0gIkJp4buDdSDEkeG7kyA3LiBQaMOibiBi4buRIGdpYW8gZOG7i2NoIHRoZW8gQ291bnRyeSIpICsgICAgICAgICAgICAgIyBUacOqdSDEkeG7gSBiaeG7g3UgxJHhu5MNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IExhYmVsKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgVGjDqm0gbmjDo24gcGjhuqduIHRyxINtIHbDoG8gZ2nhu69hIGzDoXQNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDQpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJHcmVlbnMiKSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBU4buxIMSR4buZbmcgdOG6oW8gbcOgdSBk4buFIHBow6JuIGJp4buHdCBnaeG7r2Egbmhp4buBdSBxdeG7kWMgZ2lhDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKg0KDQpgYGB7cn0NCiMgxJDhur9tIHPhu5EgYuG6o24gZ2hpIHRoZW8gcXXhu5FjIGdpYQ0KY3R5X2NvdW50cyA8LSB0YWJsZShkdCRDb3VudHJ5KQ0KDQojIENow6puaCBs4buHY2ggduG7gSBz4buRIGzGsOG7o25nIGdp4buvYSBxdeG7kWMgZ2lhIMSRw7RuZyBuaOG6pXQgdsOgIMOtdCBuaOG6pXQNCmN0eV9kaWZmIDwtIG1heChjdHlfY291bnRzKSAtIG1pbihjdHlfY291bnRzKQ0KYGBgDQoNCg0KLSBW4bqteSB0cm9uZyBi4buZIGThu68gbGnhu4d1IG7DoHkgY8OzIGByIHRhYmxlKGR0JENvdW50cnkpWzFdL3N1bShucm93KGR0KSkqMTAwYCBcJSDhu58gQ2FuYWRhLCBgciB0YWJsZShkdCRDb3VudHJ5KVsyXS9zdW0obnJvdyhkdCkpKjEwMGBcJSDhu58gTWV4aWNvIHbDoCBgciB0YWJsZShkdCRDb3VudHJ5KVszXS9zdW0obnJvdyhkdCkpKjEwMGBcJSDhu58gVVNBLg0KDQotIFF14buRYyBnaWEgxJHDtG5nIG5o4bqldCBjw7MgYHIgbWF4KGN0eV9jb3VudHMpYCwgcXXhu5FjIGdpYSDDrXQgbmjhuqV0IGPDsyByIGBtaW4oY3R5X2NvdW50cylgLg0KDQotIFPhu7EgY2jDqm5oIGzhu4djaCBnaeG7r2EgaGFpIHF14buRYyBnaWEgbsOgeSBsw6AgYHIgY3R5X2RpZmZgIG5nxrDhu51pLg0KDQojIyAqKjIuOC4gQmnhur9uIFByb2R1Y3RGYW1pbHkqKg0KDQoqKkLhuqNuZyB04bqnbiBzdeG6pXQqKg0KYGBge3J9DQojTOG6rXAgYuG6o25nIHThuqduIHN14bqldCBj4bunYSBiaeG6v24gUHJvZHVjdEZhbWlseQ0KdGFibGUoZHQkUHJvZHVjdEZhbWlseSkvc3VtKG5yb3coZHQpKQ0KYGBgDQoNCioqQuG6o25nIHThuqduIHPhu5EqKg0KYGBge3J9DQojTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY+G7p2EgYmnhur9uIFByb2R1Y3RGYW1pbHkNCnRhYmxlKGR0JFByb2R1Y3RGYW1pbHkpDQpgYGANCg0KKipCaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCiMgQsaw4bubYyAxOiBU4bqhbyBi4bqjbmcgdOG6p24gc3XhuqV0IHbDoCB0w61uaCB04bu3IGzhu4cgcGjhuqduIHRyxINtDQpwZnJlcSA8LSBzb3J0KHRhYmxlKGR0JFByb2R1Y3RGYW1pbHkpLCBkZWNyZWFzaW5nID0gVFJVRSkgICAjIMSQ4bq/bSBz4buRIGzGsOG7o25nIG3hu5dpIG5ow7NtIFByb2R1Y3RGYW1pbHkgdsOgIHPhuq9wIHjhur9wIGdp4bqjbSBk4bqnbg0KcHBjdCAgPC0gcGZyZXEgLyBucm93KGR0KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBUw61uaCB04bu3IGzhu4cgcGjhuqduIHRyxINtIGPhu6dhIG3hu5dpIG5ow7NtDQoNCiMgQsaw4bubYyAyOiBDaHV54buDbiBzYW5nIGRhdGEuZnJhbWUgxJHhu4MgZMO5bmcgZ2dwbG90Mg0KcHJvZHVjdF9kZiA8LSBhcy5kYXRhLmZyYW1lKHBmcmVxKSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBDaHV54buDbiBi4bqjbmcgdOG6p24gc3XhuqV0IHNhbmcgZGF0YS5mcmFtZQ0KY29sbmFtZXMocHJvZHVjdF9kZikgPC0gYygiUHJvZHVjdEZhbWlseSIsICJDb3VudCIpICAgICAgICAgIyDEkOG6t3QgdMOqbiBj4buZdDogdMOqbiBuaMOzbSB2w6Agc+G7kSBsxrDhu6NuZw0KcHJvZHVjdF9kZiRQZXJjZW50IDwtIHByb2R1Y3RfZGYkQ291bnQgLyBzdW0ocHJvZHVjdF9kZiRDb3VudCkgKiAxMDAgICAgIyBUw61uaCBwaOG6p24gdHLEg20gdOG7q25nIG5ow7NtDQpwcm9kdWN0X2RmJExhYmVsIDwtIHBhc3RlMChwcm9kdWN0X2RmJFByb2R1Y3RGYW1pbHksICAgICAgICAjIFThuqFvIG5ow6NuIGhp4buDbiB0aOG7iyB0w6puICsgcGjhuqduIHRyxINtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiICgiLCByb3VuZChwcm9kdWN0X2RmJFBlcmNlbnQsIDEpLCAiJSkiKQ0KDQojIELGsOG7m2MgMzogVuG6vSBiaeG7g3UgxJHhu5MgdHLDsm4gYuG6sW5nIGdncGxvdDINCmdncGxvdChwcm9kdWN0X2RmLCBhZXMoeCA9ICIiLCB5ID0gQ291bnQsIGZpbGwgPSBQcm9kdWN0RmFtaWx5KSkgKyAgIyBE4buvIGxp4buHdSBiaeG7g3UgxJHhu5M6IHkgbMOgIHPhu5EgbMaw4bujbmcsIGNoaWEgbcOgdSB0aGVvIG5ow7NtDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsgICAgICAgICAgICAgICAgICAgICAgICAgICMgVuG6vSBj4buZdCAoYmFyIGNoYXJ0KSBjw7MgY2hp4buBdSBy4buZbmcgYuG6sW5nIDEgxJHhu4MgdOG6oW8gaMOsbmggdHLDsm4NCiAgY29vcmRfcG9sYXIoInkiKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIENodXnhu4NuIGJhciBjaGFydCB0aMOgbmggYmnhu4N1IMSR4buTIHRyw7JuIHRoZW8gdHLhu6VjIHkNCiAgdGhlbWVfdm9pZCgpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIExv4bqhaSBi4buPIHRy4bulYyB2w6AgbuG7gW4gKGfhu41uIGfDoG5nIGjGoW4pDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIDguIFBow6JuIGLhu5EgZ2lhbyBk4buLY2ggdGhlbyBQcm9kdWN0IEZhbWlseSIpICsgICAgICAgICAgIyBUaMOqbSB0acOqdSDEkeG7gSBjaG8gYmnhu4N1IMSR4buTDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBMYWJlbCksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBUaMOqbSBuaMOjbiAobGFiZWwpIGhp4buDbiB0aOG7iyB0cm9uZyBsw6F0IGPhuq90DQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgICAgICAgICAgICAgICAgIyDEkOG6t3QgbmjDo24gdsOgbyBnaeG7r2EgbeG7l2kgbMOhdA0KICAgICAgICAgICAgc2l6ZSA9IDQpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgS8OtY2ggdGjGsOG7m2MgY2jhu68gY+G7p2EgbmjDo24NCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpgYGANCg0KKipOaOG6rW4geMOpdDoqKiANCg0KLSBUcm9uZyBi4buZIGThu68gbGnhu4d1IG7DoHksIG5ow7NtIMSR4buTIHXhu5FuZyBjaGnhur9tIGtob+G6o25nIGByIHJvdW5kKHRhYmxlKGR0JFByb2R1Y3RGYW1pbHkpWyJEcmluayJdIC8gbnJvdyhkdCkgKiAxMDAsIDIpYCUsICANCm5ow7NtIHRo4bupYyDEg24gY2hp4bq/bSBraG/huqNuZyBgciByb3VuZCh0YWJsZShkdCRQcm9kdWN0RmFtaWx5KVsiRm9vZCJdIC8gbnJvdyhkdCkgKiAxMDAsIDIpYCUsIHbDoCBuaMOzbSBow6BuZyBraMO0bmcgdGnDqnUgdGjhu6UgxJHGsOG7o2MgY2hp4bq/bSBraG/huqNuZyBgciByb3VuZCh0YWJsZShkdCRQcm9kdWN0RmFtaWx5KVsiTm9uLUNvbnN1bWFibGUiXSAvIG5yb3coZHQpICogMTAwLCAyKWAlLiAgDQoNCi0gVuG7gSBz4buRIGzGsOG7o25nLCBuaMOzbSB0aOG7qWMgxINuIGPDsyBgciB0YWJsZShkdCRQcm9kdWN0RmFtaWx5KVsiRm9vZCJdYCBnaWFvIGThu4tjaCwgIA0KbmjDs20gxJHhu5MgdeG7kW5nIGPDsyBgciB0YWJsZShkdCRQcm9kdWN0RmFtaWx5KVsiRHJpbmsiXWAgZ2lhbyBk4buLY2gsIHbDoCBuaMOzbSBow6BuZyBraMO0bmcgdGnDqnUgdGjhu6UgxJHGsOG7o2MgY8OzIGByIHRhYmxlKGR0JFByb2R1Y3RGYW1pbHkpWyJOb24tQ29uc3VtYWJsZSJdYCBnaWFvIGThu4tjaC4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbmjDs20gdGjhu6ljIMSDbiBsw6AgaOG6oW5nIG3hu6VjIGNoaeG6v20gxrB1IHRo4bq/IHLDtSBy4buHdCwgduG7m2kgc+G7sSBjaMOqbmggbOG7h2NoIHLhuqV0IGzhu5tuIHbhu4Egc+G7kSBsxrDhu6NuZyBzbyB24bubaSBoYWkgbmjDs20gY8OybiBs4bqhaS4gTmjGsCB24bqteSwgY8OzIHRo4buDIG5o4bqtbiB4w6l0IHLhurFuZyBwaOG6p24gbOG7m24gZ2lhbyBk4buLY2ggdHJvbmcgYuG7mSBk4buvIGxp4buHdSB04bqtcCB0cnVuZyB2w6BvIGPDoWMgc+G6o24gcGjhuqltIHRo4buxYyBwaOG6qW0g4oCTIMSRw6J5IGzDoCDEkeG6t2MgxJFp4buDbSBu4buVaSBi4bqtdCB0cm9uZyBjxqEgY+G6pXUgbeG6t3QgaMOgbmcgY+G7p2Egc2nDqnUgdGjhu4sgbsOgeS4NCg0KIyMgKioyLjkuIEJp4bq/biBQcm9kdWN0RGVwYXJ0bWVudCoqDQoNCioqQuG6o25nIHThuqduIHN14bqldCoqDQpgYGB7cn0NCiMgVOG6oW8gYuG6o25nIHThuqduIHN14bqldCAoaG/hurdjIHThu7cgbOG7hykgcuG7k2kgxJHhu5VpIHRow6BuaCBkYXRh4oCRZnJhbWUgMiBj4buZdA0KZGVwX3RhYiA8LSBwcm9wLnRhYmxlKHRhYmxlKGR0JFByb2R1Y3REZXBhcnRtZW50KSkgICAjIGhv4bq3YyB0YWJsZShkdCRQcm9kdWN0RGVwYXJ0bWVudCkNCmRlcF9kZiAgPC0gYXMuZGF0YS5mcmFtZShkZXBfdGFiKSAgICAgICAgICAgICAgICAgICAjIOKGkCBiaeG6v24gdGjDoG5oIDIgY+G7mXQNCg0KIyDEkOG6t3QgdMOqbiBj4buZdCBuZ+G6r24gZ+G7jW4NCm5hbWVzKGRlcF9kZikgPC0gYygiUHJvZHVjdERlcGFydG1lbnQiLCAiVHlfbGUiKSAgICAgICAgICAgICAgICAgICMgbuG6v3UgbMOgIHThu7cgbOG7hyAlDQpkZXBfZGYkVHlfbGUgIDwtIHJvdW5kKDEwMCAqIGRlcF9kZiRUeV9sZSwgMikgICAgICAgIyBuaMOibiAxMDAg4oaSICUNCg0KcHJpbnQoZGVwX2RmKQ0KYGBgDQoNCioqQuG6o25nIHThuqduIHPhu5EqKg0KYGBge3J9DQojIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRDQpkZXBfZnJlcSA8LSB0YWJsZShkdCRQcm9kdWN0RGVwYXJ0bWVudCkNCg0KIyBDaHV54buDbiB0aMOgbmggZGF0YeKAkWZyYW1lIDIgY+G7mXQNCmRlcF9mcmVxX2RmIDwtIGFzLmRhdGEuZnJhbWUoZGVwX2ZyZXEpDQpuYW1lcyhkZXBfZnJlcV9kZikgPC0gYygiUHJvZHVjdERlcGFydG1lbnQiLCAiU29fbHVvbmciKSAgICMgxJHhurd0IHTDqm4gY+G7mXQgcsO1IHLDoG5nDQoNCnByaW50KGRlcF9mcmVxX2RmKQ0KYGBgDQoNCg0KKipCaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCmdncGxvdChkdCwgYWVzKHggPSBQcm9kdWN0RGVwYXJ0bWVudCkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGNvb3JkX2ZsaXAoKSArICAjIHhvYXkgbmdhbmcgbmjDo24gY2hvIGThu4UgxJHhu41jDQogIGxhYnModGl0bGUgPSAiQmnhu4F1IMSR4buTIDkuIFThuqduIHPhu5EgZ2lhbyBk4buLY2ggdGhlbyBQcm9kdWN0IERlcGFydG1lbnQiLA0KICAgICAgIHggPSAiUHJvZHVjdCBEZXBhcnRtZW50IiwNCiAgICAgICB5ID0gIlPhu5EgZ2lhbyBk4buLY2giKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KioNCg0KLSBUcm9uZyBi4buZIGThu68gbGnhu4d1LCBuaMOzbSBz4bqjbiBwaOG6qW0gY8OzIHThu7cgbOG7hyBnaWFvIGThu4tjaCBjYW8gbmjhuqV0IGzDoCBQcm9kdWNlIHbhu5tpIGByIHJvdW5kKHRhYmxlKGR0JFByb2R1Y3REZXBhcnRtZW50KVsiUHJvZHVjZSJdL25yb3coZHQpKjEwMCwgMilgJSwgdGnhur9wIHRoZW8gbMOgIFNuYWNrIEZvb2RzIChgciByb3VuZCh0YWJsZShkdCRQcm9kdWN0RGVwYXJ0bWVudClbIlNuYWNrIEZvb2RzIl0vbnJvdyhkdCkqMTAwLCAyKWAlKSB2w6AgSG91c2Vob2xkIChgciByb3VuZCh0YWJsZShkdCRQcm9kdWN0RGVwYXJ0bWVudClbIkhvdXNlaG9sZCJdL25yb3coZHQpKjEwMCwgMilgJSkuIE5ow7NtIEZyb3plbiBGb29kcyBjxaluZyBjaGnhur9tIHThu7cgbOG7hyDEkcOhbmcga+G7gyBsw6AgYHIgcm91bmQodGFibGUoZHQkUHJvZHVjdERlcGFydG1lbnQpWyJGcm96ZW4gRm9vZHMiXS9ucm93KGR0KSoxMDAsIDIpYCUuIEPDoWMgbmjDs20gbmjGsCBDYXJvdXNlbCAoYHIgcm91bmQodGFibGUoZHQkUHJvZHVjdERlcGFydG1lbnQpWyJDYXJvdXNlbCJdL25yb3coZHQpKjEwMCwgMilgJSkgdsOgIENoZWNrb3V0IChgciByb3VuZCh0YWJsZShkdCRQcm9kdWN0RGVwYXJ0bWVudClbIkNoZWNrb3V0Il0vbnJvdyhkdCkqMTAwLCAyKWAlKSBjw7MgdOG7tyBs4buHIHRo4bqlcCBoxqFuIG5oaeG7gXUuDQoNCiMjICoqMi4xMC4gQmnhur9uIFByb2R1Y3RDYXRlZ29yeSoqDQpgYGB7cn0NCiMgLS0tLS0gdOG7tyBs4buHICUgY2hvIFByb2R1Y3RDYXRlZ29yeSAtLS0tLQ0KcGNfcHJvcF9kZiA8LSBwcm9wLnRhYmxlKHRhYmxlKGR0JFByb2R1Y3RDYXRlZ29yeSkpIHw+ICAjIGhv4bq3YyB0YWJsZSguLi4pL25yb3coZHQpDQogIGFzLmRhdGEuZnJhbWUoKSB8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGjDoG5oIDIgY+G7mXQNCiAgc2V0TmFtZXMoYygiQ2F0ZWdvcnkiLCAiVHlfbGUiKSkgfD4gICAgICAgICAgICAgICAgICAgIyDEkeG7lWkgdMOqbiBj4buZdA0KICB0cmFuc2Zvcm0oVHlfbGUgPSByb3VuZCgxMDAgKiBUeV9sZSwgMikpICAgICAgICAgICAgICAjIG5ow6JuIDEwMCDihpIgJQ0KDQpwcmludChwY19wcm9wX2RmKQ0KYGBgDQoNCg0KYGBge3J9DQpmcmVxX2RmIDwtIHRhYmxlKGR0JFByb2R1Y3RDYXRlZ29yeSkgfD4gICAgICAgICAgICMgVOG6oW8gYuG6o25nIHThuqduIHN14bqldCDEkeG6v20gc+G7kSBs4bqnbiB4deG6pXQgaGnhu4duIG3hu5dpIGNhdGVnb3J5IHRyb25nIGPhu5l0IFByb2R1Y3RDYXRlZ29yeSBj4bunYSBkYXRhZnJhbWUgZHQNCiAgYXMuZGF0YS5mcmFtZSgpIHw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQ2h1eeG7g24gYuG6o25nIHThuqduIHN14bqldCAoa2nhu4N1IHRhYmxlKSB0aMOgbmggZGF0YWZyYW1lIMSR4buDIGThu4UgeOG7rSBsw70gKDIgY+G7mXQ6IGNhdGVnb3J5IHbDoCBz4buRIGzGsOG7o25nKQ0KICBzZXROYW1lcyhjKCJDYXRlZ29yeSIsICJTb19sdW9uZyIpKSAgICAgICAgICAgICAgIyDEkOG7lWkgdMOqbiAyIGPhu5l0IGPhu6dhIGRhdGFmcmFtZSB0aMOgbmggIkNhdGVnb3J5IiAodMOqbiBjYXRlZ29yeSkgdsOgICJTb19sdW9uZyIgKHPhu5EgbOG6p24geHXhuqV0IGhp4buHbikNCnByaW50KGZyZXFfZGYpDQpgYGANCg0KKipCaeG7g3UgxJHhu5MqKg0KDQpgYGB7cn0NCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgdOG6p24gc3XhuqV0IFByb2R1Y3RDYXRlZ29yeQ0KZ2dwbG90KGR0LCBhZXMoeCA9IHJlb3JkZXIoUHJvZHVjdENhdGVnb3J5LCBQcm9kdWN0Q2F0ZWdvcnksIGZ1bmN0aW9uKHgpIC1sZW5ndGgoeCkpKSkgKw0KICBnZW9tX2JhcihmaWxsID0gInN0ZWVsYmx1ZSIpICsNCiAgY29vcmRfZmxpcCgpICsgICMgWG9heSB0cuG7pWMgxJHhu4MgbmjDo24gZOG7hSDEkeG7jWMgaMahbg0KICBsYWJzKHRpdGxlID0gIkJp4buDdSDEkeG7kyAxMC4gVOG6p24gc3XhuqV0IGdpYW8gZOG7i2NoIHRoZW8gUHJvZHVjdCBDYXRlZ29yeSIsDQogICAgICAgeCA9ICJQcm9kdWN0IENhdGVnb3J5IiwNCiAgICAgICB5ID0gIlPhu5EgZ2lhbyBk4buLY2giKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCioqTmjhuq1uIHjDqXQ6KiogVHJvbmcgYuG7mSBk4buvIGxp4buHdSwgbmjDs20gc+G6o24gcGjhuqltIGPDsyB04bu3IGzhu4cgZ2lhbyBk4buLY2ggY2FvIG5o4bqldCBsw6AgVmVnZXRhYmxlcyB24bubaSBgciByb3VuZCh0YWJsZShkdCRQcm9kdWN0Q2F0ZWdvcnkpWyJWZWdldGFibGVzIl0vbnJvdyhkdCkqMTAwLCAyKWAlLCB0aeG6v3AgdGhlbyBsw6AgU25hY2sgRm9vZHMgKGByIHJvdW5kKHRhYmxlKGR0JFByb2R1Y3RDYXRlZ29yeSlbIlNuYWNrIEZvb2RzIl0vbnJvdyhkdCkqMTAwLCAyKWAlKSB2w6AgRGFpcnkgKGByIHJvdW5kKHRhYmxlKGR0JFByb2R1Y3RDYXRlZ29yeSlbIkRhaXJ5Il0vbnJvdyhkdCkqMTAwLCAyKWAlKS4gQ8OhYyBuaMOzbSDEkcOzbmcgaOG7mXAgbmjGsCBDYW5uZWQgT3lzdGVycyAoYHIgcm91bmQodGFibGUoZHQkUHJvZHVjdENhdGVnb3J5KVsiQ2FubmVkIE95c3RlcnMiXS9ucm93KGR0KSoxMDAsIDIpYCUpIHbDoCBDYW5uZWQgQ2xhbXMgKGByIHJvdW5kKHRhYmxlKGR0JFByb2R1Y3RDYXRlZ29yeSlbIkNhbm5lZCBDbGFtcyJdL25yb3coZHQpKjEwMCwgMilgJSkgY2hp4bq/bSB04bu3IGzhu4cgcuG6pXQgbmjhu48sIGNobyB0aOG6pXkgc+G7sSDGsHUgdGnDqm4gbXVhIGjDoG5nIHTGsMahaSB2w6AgxJHhu5MgxINuIG5o4bq5Lg0KDQojICoqUGjhuqduIDMuIMav4buaQyBMxq/hu6JORyBLSE/huqJORyBWw4AgS0nhu4JNIMSQ4buKTkggR0nhuqIgVEhVWeG6vlQgQ0hPIFThu7YgTOG7hiAoTeG7mFQgQknhur5OKSoqDQoNClRyb25nIHRo4buRbmcga8OqLCBraGkgbMOgbSB2aeG7h2MgduG7m2kgZOG7ryBsaeG7h3UgZOG6oW5nIG5o4buLIHBow6JuICh2w60gZOG7pTogY8OzL2tow7RuZywgbmFtL27hu68sIMSR4bqhdC9raMO0bmcgxJHhuqF0Li4uKSwgbeG7mXQgxJHhuqFpIGzGsOG7o25nIHF1YW4gdHLhu41uZyB0aMaw4budbmcgxJHGsOG7o2MgcXVhbiB0w6JtIGzDoCAqKnThu7cgbOG7hyAocHJvcG9ydGlvbikqKiDigJMga8O9IGhp4buHdSBsw6AgJHAkLiBIYWkga+G7uSB0aHXhuq10IHBo4buVIGJp4bq/biDEkeG7gyBwaMOibiB0w61jaCB04bu3IGzhu4cgdHJvbmcgcXXhuqduIHRo4buDIGzDoCAqKsaw4bubYyBsxrDhu6NuZyBraG/huqNuZyB0aW4gY+G6rXkqKiB2w6AgKipraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCoqLg0KDQpHaeG6oyBz4butIGNow7puZyB0YSBjw7MgbeG7mXQgbeG6q3Ugbmfhuqt1IG5oacOqbiBn4buTbSAkbiQgcGjhuqduIHThu60sIHRyb25nIMSRw7MgY8OzICR4JCBwaOG6p24gdOG7rSBjw7MgxJHhurdjIMSRaeG7g20gcXVhbiB0w6JtLiBLaGkgxJHDsywgKip04bu3IGzhu4cgbeG6q3UqKiDEkcaw4bujYyB0w61uaCBsw6A6DQoNCiQkDQpcaGF0e3B9ID0gXGZyYWN7eH17bn0NCiQkDQoNCsSQ4buDIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgdOG7lW5nIHRo4buDICRwJCwgdGEgeMOieSBk4buxbmcgKipraG/huqNuZyB0aW4gY+G6rXkqKiB24bubaSBt4bupYyB0aW4gY+G6rXkgJCgxIC0gXGFscGhhKSBcdGltZXMgMTAwXCUkLiBLaGkga8OtY2ggdGjGsOG7m2MgbeG6q3UgxJHhu6cgbOG7m24sIGtob+G6o25nIHRpbiBj4bqteSDEkcaw4bujYyB0w61uaCBuaMawIHNhdToNCg0KJCQNClxoYXR7cH0gXHBtIHpfe1xhbHBoYS8yfSBcY2RvdCBcc3FydHsgXGZyYWN7XGhhdHtwfSgxIC0gXGhhdHtwfSl9e259IH0NCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gJFxoYXR7cH0kOiB04bu3IGzhu4cgbeG6q3UgIA0KLSAkel97XGFscGhhLzJ9JDogZ2nDoSB0cuG7iyB04bubaSBo4bqhbiB04burIHBow6JuIHBo4buRaSBjaHXhuqluICh2w60gZOG7pTogduG7m2kgbeG7qWMgdGluIGPhuq15IDk1JSwgJHpfezAuMDI1fSBcYXBwcm94IDEuOTYkKQ0KDQpN4bulYyB0acOqdSBsw6Aga2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3QgduG7gSB04bu3IGzhu4cgdOG7lW5nIHRo4buDICRwJC4gVsOtIGThu6U6DQoNCi0gJEhfMCQ6ICRwID0gcF8wJCAoZ2nhuqMgdGh1eeG6v3QgZ+G7kWMpICANCi0gJEhfMSQ6ICRwIFxuZSBwXzAkLCBob+G6t2MgJHAgPiBwXzAkLCBob+G6t2MgJHAgPCBwXzAkIChnaeG6oyB0aHV54bq/dCDEkeG7kWkpDQoNClRo4buRbmcga8OqIGtp4buDbSDEkeG7i25oIMSRxrDhu6NjIHPhu60gZOG7pW5nIGzDoDoNCg0KJCQNCnogPSBcZnJhY3sgXGhhdHtwfSAtIHBfMCB9eyBcc3FydHsgXGZyYWN7cF8wICgxIC0gcF8wKX17bn0gfSB9DQokJA0KDQpTbyBzw6FuaCBnacOhIHRy4buLICR6JCB24bubaSBnacOhIHRy4buLIHThu5tpIGjhuqFuIHThu6sgYuG6o25nIHBow6JuIHBo4buRaSBjaHXhuqluIMSR4buDIMSRxrBhIHJhIGvhur90IGx14bqtbjoNCg0KLSBO4bq/dSAkfHp8ID4gel97XGFscGhhLzJ9JCwgYsOhYyBi4buPICRIXzAkICh0csaw4budbmcgaOG7o3AgaGFpIHBow61hKSAgDQoNCi0gSG/hurdjIGTDuW5nICoqcC12YWx1ZSoqIMSR4buDIMSR4buRaSBjaGnhur91IHbhu5tpIG3hu6ljIMO9IG5naMSpYSAkXGFscGhhJA0KDQojIyAqKjMuMS4gR2VuZGVyIChO4buvKSoqDQoNCioqxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSoqDQoNCmBgYHtyfQ0KIyBT4buRIG5nxrDhu51pIG7hu68gKEdlbmRlciA9ICJGIikgdsOgIHThu5VuZyBz4buRIHF1YW4gc8OhdA0Kbl9mZW1hbGUgPC0gc3VtKGR0JEdlbmRlciA9PSAiRiIpDQpuX3RvdGFsICA8LSBucm93KGR0KQ0KDQojIFTDrW5oIGtob+G6o25nIHRpbiBj4bqteSA5NSUgdsOgIGtp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90IHbhu5tpIHThu7cgbOG7hyBr4buzIHbhu41uZyBwID0gMC41DQp0ZXN0X2ZlbWFsZSA8LSBwcm9wLnRlc3Qobl9mZW1hbGUsIG5fdG90YWwsIHAgPSAwLjUsIGNvcnJlY3QgPSBGQUxTRSkNCmBgYA0KDQotIFThu7cgbOG7hyBu4buvIHRyb25nIGThu68gbGnhu4d1IGzDoCBgciByb3VuZChuX2ZlbWFsZSAvIG5fdG90YWwsIDQpYC4NCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgbsOgeSBsw6AgdOG7qyBgciByb3VuZCh0ZXN0X2ZlbWFsZSRjb25mLmludFsxXSwgNClgIMSR4bq/biBgciByb3VuZCh0ZXN0X2ZlbWFsZSRjb25mLmludFsyXSwgNClgLg0KDQoqKktp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90KioNCg0KR2nhuqMgdGh1eeG6v3QgxJHhurd0IHJhIG5oxrAgc2F1Og0KDQotICoqSOKCgCoqOiBwID0gMC41IChU4bu3IGzhu4cgbuG7ryB0aHXhu5ljIGRhbmggbeG7pWMgZ2VuZGVyIGzDoCA1MCUpDQoNCi0gKipI4oKBKio6IHAg4omgIDAuNSAoVOG7tyBs4buHIG7hu68gdGh14buZYyBkYW5oIG3hu6VjIGdlbmRlciBraMOhYyA1MCUpDQoNCmBgYHtyfQ0KIyBLaeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCB24bubaSBwcm9wLnRlc3QNCnRlc3RfZmVtYWxlIDwtIHByb3AudGVzdChuX2ZlbWFsZSwgbl90b3RhbCwgcCA9IDAuNSwgY29ycmVjdCA9IEZBTFNFKQ0KdGVzdF9mZW1hbGUNCmBgYA0KYGBge3J9DQojR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiBDaGktYsOsbmggcGjGsMahbmc6IDUuNjE2NCB24bubaSBi4bqtYyB04buxIGRvIDEuDQoNCiNHacOhIHRy4buLIHAgPSAwLjAxNzc5Lg0KDQojS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7iSBs4buHIG7hu68gdHJvbmcgdOG7lW5nIHRo4buDIGzDoCB04burIDAuNTAxNyDEkeG6v24gMC41MTgzLg0KDQojxq/hu5tjIGzGsOG7o25nIHThu4kgbOG7hyBt4bqrdTogMC41MDk5OTM2ICh+NTAuOTk5JSkuDQpgYGANCg0KLSBW4bubaSBt4bupYyDDvSBuZ2jEqWEgJFxhbHBoYSA9IDAuMDUkLCBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBjaG8gdGjhuqV5IGdpw6EgdHLhu4sgcCBsw6AgYHIgcm91bmQodGVzdF9mZW1hbGUkcC52YWx1ZSwgNClgLg0KDQotIGByIGlmZWxzZSh0ZXN0X2ZlbWFsZSRwLnZhbHVlIDw9IDAuMDUsDQoiVsOsIHAtdmFsdWUgbmjhu48gaMahbiAwLjA1LCBjaMO6bmcgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuIFbhuq15IHThu7cgbOG7hyBu4buvIGtow6FjIDUwJSAuIiwNCiJWw6wgcC12YWx1ZSBs4bubbiBoxqFuIDAuMDUsIGNow7puZyB0YSAqKmtow7RuZyDEkeG7pyDEkWnhu4F1IGtp4buHbiBiw6FjIGLhu48qKiBnaeG6oyB0aHV54bq/dCBI4oKALiAgVuG6rXkgdOG7tyBs4buHIG7hu68gIGtow7RuZyBraMOhYyA1MCUgIilgDQoNCmBgYHtyfQ0KIyB0ZXN0X2ZlbWFsZSRwLnZhbHVlOiAgR2nDoSB0cuG7iyBwIChwLXZhbHVlKSB04burIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBu4buvDQojIGlmZWxzZSguLi4pOiAJSMOgbSDEkWnhu4F1IGtp4buHbiB0cm9uZyBSLiBO4bq/dSDEkWnhu4F1IGtp4buHbiDEkcO6bmcgdGjDrCBs4bqleSBwaOG6p24gMiwgc2FpIHRow6wgbOG6pXkgcGjhuqduIDMNCmBgYA0KDQojIyAqKjMuMi4gTWFyaXRhbFN0YXR1cyAoxJDDoyBr4bq/dCBow7RuX00pKioNCg0KKirGr+G7m2MgbMaw4bujbmcga2hv4bqjbmcgdGluIGPhuq15IGNobyB04bu3IGzhu4cgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuKioNCg0KYGBge3J9DQojIFPhu5EgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIChrw70gaGnhu4d1IE0pIHbDoCB04buVbmcgc+G7kSBxdWFuIHPDoXQNCm5fbWFycmllZCA8LSBzdW0oZHQkTWFyaXRhbFN0YXR1cyA9PSAiTSIpDQpuX3RvdGFsICAgPC0gbnJvdyhkdCkNCg0KIyBUw61uaCBraG/huqNuZyB0aW4gY+G6rXkgOTUlIHbDoCBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dA0KdGVzdF9tYXJyaWVkIDwtIHByb3AudGVzdChuX21hcnJpZWQsIG5fdG90YWwsIHAgPSAwLjUsIGNvcnJlY3QgPSBGQUxTRSkNCnRlc3RfbWFycmllZA0KYGBgDQpgYGB7cn0NCiNHacOhIHRy4buLIHRo4buRbmcga8OqIENoaS1iw6xuaCBwaMawxqFuZzogNy42MDU3IChkZj0xKS4NCg0KI0dpw6EgdHLhu4sgcCA9IDAuMDA1ODE4Lg0KDQojS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7iSBs4buHIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biB0cm9uZyB04buVbmcgdGjhu4M6IHThu6sgNDguMDElIMSR4bq/biA0OS42NiUuDQoNCiNU4buJIGzhu4cgbeG6q3UgxrDhu5tjIGzGsOG7o25nOiA0OC44NCUuDQpgYGANCg0KYGBge3J9DQojcCA9IDAuNToJVOG7tyBs4buHIGvhu7MgduG7jW5nIHRyb25nIGdp4bqjIHRodXnhur90IGtow7RuZyBI4oKAICjhu58gxJHDonk6IEjigoA6IHThu7cgbOG7hyDEkcOjIGvhur90IGjDtG4gPSAwLjUpDQoNCiNjb3JyZWN0ID0gRkFMU0U6CUtow7RuZyBkw7luZyBoaeG7h3UgY2jhu4luaCBsacOqbiB04bulYyAoY29udGludWl0eSBjb3JyZWN0aW9uKSwgY2hvIGvhur90IHF14bqjIGfhuqduIHbhu5tpIGzDvSB0aHV54bq/dCBoxqFuIGtoaSBt4bqrdSBs4bubbg0KYGBgDQoNCi0gVOG7tyBs4buHIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biB0cm9uZyBk4buvIGxp4buHdSBsw6AgYHIgcm91bmQobl9tYXJyaWVkIC8gbl90b3RhbCwgNClgLg0KDQotIEtob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIHThu7cgbOG7hyBuw6B5IGzDoCB04burIGByIHJvdW5kKHRlc3RfbWFycmllZCRjb25mLmludFsxXSwgNClgIMSR4bq/biBgciByb3VuZCh0ZXN0X21hcnJpZWQkY29uZi5pbnRbMl0sIDQpYC4NCg0KYGBge3J9DQojIHRlc3RfbWFycmllZCRjb25mLmludFsxXSDihpIgQ+G6rW4gZMaw4bubaQ0KDQojIHRlc3RfbWFycmllZCRjb25mLmludFsyXSDihpIgQ+G6rW4gdHLDqm4NCmBgYA0KDQoqKktp4buDbSDEkeG7i25oIGdp4bqjIHRodXnhur90KioNCg0KR2nhuqMgdGh1eeG6v3Q6DQoNCioqSOKCgDoqKiBwID0gMC41IChU4bu3IGzhu4cgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIGzDoCA1MCUpDQoNCioqSOKCgToqKiBwIOKJoCAwLjUgKFThu7cgbOG7hyBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4ga2jDoWMgNTAlKQ0KDQoNCkdpw6EgdHLhu4sgcCB04burIGtp4buDbSDEkeG7i25oIGzDoDogcF92YWx1ZSA9IGByIHJvdW5kKHRlc3RfbWFycmllZCRwLnZhbHVlLCA0KWANCg0KVuG7m2kgbeG7qWMgw70gbmdoxKlhICRcYWxwaGEgPSAwLjA1JCwNCmByIGlmZWxzZSh0ZXN0X21hcnJpZWQkcC52YWx1ZSA8PSAwLjA1LCAiVsOsIFBfdmFsdWUgPCAwLjA1LCB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgC4gRG8gxJHDsywgY8OzIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIGNobyB0aOG6pXkgKip04bu3IGzhu4cgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIGtow6FjIDUwJSoqIHRyb25nIHThu5VuZyB0aOG7gy4iLCAiVsOsIFBfdmFsdWUgPiAwLjA1LCB0YSBraMO0bmcgxJHhu6cgY8ahIHPhu58gYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuIERvIMSRw7MsIGPDsyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiBjaG8gdGjhuqV5ICoqdOG7tyBs4buHIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biBsw6AgNTAlKiogdHJvbmcgdOG7lW5nIHRo4buDLiIpYCANCg0KIyMgKiozLjMuIFByb2R1Y3RGYW1pbHkgKERyaW5rKSoqDQoNCmBgYHtyfQ0KIyDEkOG6v20gc+G7kSBz4bqjbiBwaOG6qW0gbMOgIEZvb2QNCm5fZHJpbmsgPC0gc3VtKGR0JFByb2R1Y3RGYW1pbHkgPT0gIkRyaW5rIiwgbmEucm0gPSBUUlVFKQ0KDQojIFThu5VuZyBz4buRIHF1YW4gc8OhdA0Kbl90b3RhbCA8LSBucm93KGR0KQ0KDQojIFThu7cgbOG7hyBz4bqjbiBwaOG6qW0gRm9vZA0KcHJvcF9kcmluayA8LSBuX2RyaW5rIC8gbl90b3RhbA0KcHJvcF9kcmluaw0KYGBgDQoNCi0gVOG7tyBs4buHIHPhuqNuIHBo4bqpbSBEcmluayB0cm9uZyBk4buvIGxp4buHdSBsw6AgYHIgcm91bmQocHJvcF9kcmluayAqIDEwMCwgMilgJS4NCioqxq/hu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSBjaG8gbmjDs20gc+G6o24gcGjhuqltIERyaW5rKioNCg0KKipLaeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dDoqKg0KDQoqKkdp4bqjIHRodXnhur90OioqDQoNCi0gSOKCgDogcCA8PSAwLjA5IChU4bu3IGzhu4cgc+G6o24gcGjhuqltIHRodeG7mWMgbmjDs20gRHJpbmsgbMOgIDklKQ0KDQotIEjigoE6IHAgPiAwLjA5IChU4bu3IGzhu4cgc+G6o24gcGjhuqltIHRodeG7mWMgbmjDs20gRHJpbmsgbOG7m24gaMahbiA5JSkNCg0KYGBge3J9DQp0ZXN0X2RyaW5rIDwtIHByb3AudGVzdChuX2RyaW5rLCBuX3RvdGFsLCBwID0gMC4wOSwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIsIGNvcnJlY3QgPSBGQUxTRSkNCiMgIyBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIjoga2nhu4NtIMSR4buLbmggMSBwaMOtYSwgSDE6IHThu7cgbOG7hyB0aOG7sWMgdOG6vyBs4bubbiBoxqFuIDAuMDkNCnRlc3RfZHJpbmsNCmBgYA0KYGBge3J9DQojR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiBDaGktYsOsbmggcGjGsMahbmc6IDAuMjAzNTcgKGRmPTEpLg0KDQojR2nDoSB0cuG7iyBwID0gMC42NzQxLg0KDQojS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gdOG7iSBs4buHIHPhuqNuIHBo4bqpbSBEcmluayB0cm9uZyB04buVbmcgdGjhu4MgbMOgIHThu6sgOC41JSDEkeG6v24gMTAwJSAoa2hv4bqjbmcgdHLDqm4ga2jDtG5nIGdp4bubaSBo4bqhbiB2w6wga2nhu4NtIMSR4buLbmggbeG7mXQgcGjDrWEpLg0KDQojVOG7iSBs4buHIG3huqt1IMaw4bubYyBsxrDhu6NuZzogOC44OSUuDQpgYGANCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyB04bu3IGzhu4cgdGjhu7FjIHThur8gcDogdOG7qyAwLjA4NTAgxJHhur9uIDEuMDAwMA0KDQotIEdpw6EgdHLhu4sgcCB04burIGtp4buDbSDEkeG7i25oOiBQX3ZhbHVlID0gYHIgcm91bmQodGVzdF9kcmluayRwLnZhbHVlLCA0KWAuDQoNCi0gVuG7m2kgbeG7qWMgw70gbmdoxKlhICRcYWxwaGEgPSAwLjA1JCwNCmByIHJvdW5kKHRlc3RfZHJpbmskcC52YWx1ZSwgNClgLCBgciBpZmVsc2UodGVzdF9kcmluayRwLnZhbHVlIDwgMC4wNSwgIlbDrCBQX3ZhbHVlIDwgMC4wNSwgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuIiwiIFbDrCBQX3ZhbHVlID4gMC4wNSwgdGEga2jDtG5nIMSR4bunIGPGoSBz4bufIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALiIpYA0KDQrihpIgS+G6v3QgbHXhuq1uOiBgciBpZmVsc2UodGVzdF9kcmluayRwLnZhbHVlIDwgMC4wNSwgIlThu7cgbOG7hyBz4bqjbiBwaOG6qW0gRHJpbmsgbOG7m24gaMahbiA5JS4iLCAiVOG7tyBs4buHIHPhuqNuIHBo4bqpbSBEcmluayBraMO0bmcgbOG7m24gaMahbiA5JS4iKWANCg0KIyMgKiozLjQuIENvdW50cnkqKg0KDQpLaeG7g20gxJHhu4tuaDoNCg0KSOKCgDogcOKCgSAtIHDigoIgPSAwICh04bu3IGzhu4cgTWV4aWNvIGLhurFuZyBDYW5hZGEpDQoNCkjigoE6IHDigoEgLSBw4oKCIDwgMCAodOG7tyBs4buHIE1leGljbyBuaOG7jyBoxqFuIENhbmFkYSkNCg0KYGBge3J9DQp0YmwgPC0gdGFibGUoZHQkQ291bnRyeSkNCnRibA0KYGBgDQoNCmBgYHtyfQ0KeCA8LSBjKHRibFsiTWV4aWNvIl0sIHRibFsiQ2FuYWRhIl0pICAjIFPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIG3hu5dpIG5ow7NtDQpuIDwtIGMoc3VtKHRibFtjKCJNZXhpY28iLCAiQ2FuYWRhIildKSwgc3VtKHRibFtjKCJNZXhpY28iLCAiQ2FuYWRhIildKSkNCg0KcHJvcC50ZXN0KHggPSB4LCBuID0gbiwgYWx0ZXJuYXRpdmUgPSAibGVzcyIsIGNvcnJlY3QgPSBGQUxTRSkNCg0KYGBgDQoNCi0gWC1zcXVhcmVkID0gMzY4Ni4zCUdpw6EgdHLhu4sgdGjhu5FuZyBrw6oga2nhu4NtIMSR4buLbmggY2hpIGLDrG5oIHBoxrDGoW5nIChDaGktc3F1YXJlZCkuIEdpw6EgdHLhu4sgbsOgeSBy4bqldCBs4bubbiwgY2hvIHRo4bqleSBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgbOG7m24gZ2nhu69hIGhhaSB04bu3IGzhu4cgcXVhbiBzw6F0IMSRxrDhu6NjLiBUdXkgbmhpw6puLCDEkWnhu4F1IHF1YW4gdHLhu41uZyBsw6AgcGjhuqNpIHhlbSB4w6l0IGjGsOG7m25nIGtp4buDbSDEkeG7i25oIG3hu5tpIGPDsyB0aOG7gyDEkcawYSByYSBr4bq/dCBsdeG6rW4gY2jDrW5oIHjDoWMuDQpkZiA9IDEJU+G7kSBi4bqtYyB04buxIGRvIGPhu6dhIGtp4buDbSDEkeG7i25oICh2w6wgc28gc8OhbmggMiBuaMOzbSBuw6puIGRmID0gMSkuDQoNCi0gcC12YWx1ZSA9IDEJxJDDonkgbMOgIHjDoWMgc3XhuqV0IMSR4buDIHF1YW4gc8OhdCDEkcaw4bujYyBz4buxIGNow6puaCBs4buHY2ggbmjGsCB24bqteSAoaG/hurdjIGzhu5tuIGjGoW4pIG7hur91IEjigoAgbMOgIMSRw7puZy4gVuG7m2kgcC12YWx1ZSA9IDEsIMSRaeG7gXUgxJHDsyBjw7MgbmdoxKlhIGzDoCBraMO0bmcgY8OzIGLhurFuZyBjaOG7qW5nIG7DoG8g4bunbmcgaOG7mSBI4oKBOiBw4oKBIDwgcOKCgi4gS+G6v3QgcXXhuqMgbsOgeSBsw6AgZG8gaMaw4bubbmcga2nhu4NtIMSR4buLbmgga2jDtG5nIHBow7kgaOG7o3AgduG7m2kgZOG7ryBsaeG7h3UgdGjhu7FjIHThur8uDQoNCi0gYWx0ZXJuYXRpdmUgaHlwb3RoZXNpczogbGVzcwlLaeG7g20gxJHhu4tuaCAxIHBow61hIHbhu5tpIGdp4bqjIHRodXnhur90IMSR4buRaTogcOKCgSA8IHDigoIgKE1leGljbyA8IENhbmFkYSkuIE5oxrBuZyBk4buvIGxp4buHdSBjaG8gdGjhuqV5IE1leGljbyBjaGnhur9tIDgyJSwgY8OybiBDYW5hZGEgY2jhu4kgMTglLCBuw6puIGdp4bqjIHRodXnhur90IG7DoHkgbmfGsOG7o2MgduG7m2kgdGjhu7FjIHThur8sIGThuqtuIMSR4bq/biBwLXZhbHVlID0gMS4NCg0KLSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbDogKC0xLjAwMDAwMDAsIDAuNjUzNTI4NCkJS2hv4bqjbmcgdGluIGPhuq15IGNobyBoaeG7h3UgcOKCgSAtIHDigoIuIEtob+G6o25nIG7DoHkgYmFvIGfhu5NtIGPhuqMgc+G7kSAwIHbDoCBwaOG6p24gZMawxqFuZyBs4bubbiwgY2hvIHRo4bqleSBjaMawYSDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBraOG6s25nIMSR4buLbmggcOKCgSA8IHDigoIuDQotIHNhbXBsZSBlc3RpbWF0ZXM6CQ0KICAtIHByb3AgMSA9IDAuODIwMQlU4bu3IGzhu4cga2jDoWNoIGjDoG5nIMSR4bq/biB04burIE1leGljby4NCiAgLSBwcm9wIDIgPSAwLjE3OTkJVOG7tyBs4buHIGtow6FjaCBow6BuZyDEkeG6v24gdOG7qyBDYW5hZGEuIFLDtSByw6BuZyBNZXhpY28gPiBDYW5hZGEsIG7Dqm4gdmnhu4djIGtp4buDbSDEkeG7i25oIE1leGljbyA8IENhbmFkYSBsw6Aga2jDtG5nIHBow7kgaOG7o3AuDQogIA0KVuG7m2kgbeG7qWMgw70gbmdoxKlhIM6xID0gMC4wNSwgdsOsIHAtdmFsdWUgPSAxID4gMC4wNSwgdGEga2jDtG5nIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALg0KS2jDtG5nIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgTWV4aWNvIHRo4bqlcCBoxqFuIENhbmFkYS4NCg0KIyAqKlBo4bqnbiA0LiBQSMOCTiBUw41DSCBN4buQSSBRVUFOIEjhu4YgR0nhu65BIEhBSSBCSeG6vk4gxJDhu4pOSCBUw41OSCoqDQoNCiMjICoqNC4xLiBHZW5kZXIgdsOgIEhvbWVvd25lcioqDQoNCiMjIyAqKjQuMS4xLiBC4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCiMgQuG6o25nIHThuqduIHPhu5EgY2jDqW8gKGNyb3NzLXRhYnVsYXRpb24pIGdp4buvYSBHZW5kZXIgdsOgIEhvbWVvd25lcg0KdGFibGVfZ2VuZGVyX2hvbWVvd25lciA8LSB0YWJsZShkdCRHZW5kZXIsIGR0JEhvbWVvd25lcikNCnRhYmxlX2dlbmRlcl9ob21lb3duZXINCmBgYA0KDQpgYGB7cn0NCmRpZmZfY291bnQgPC0gdGFibGVfZ2VuZGVyX2hvbWVvd25lclsiRiIsICJZIl0gLSB0YWJsZV9nZW5kZXJfaG9tZW93bmVyWyJNIiwgIlkiXQ0KZGlmZl9ub3Rfb3duZXJfY291bnQgPC10YWJsZV9nZW5kZXJfaG9tZW93bmVyWyJGIiwgIk4iXS0gdGFibGVfZ2VuZGVyX2hvbWVvd25lclsiTSIsICJOIl0NCg0KY2F0KCJO4buvIHPhu58gaOG7r3UgbmjDoCBuaGnhu4F1IGjGoW4gbmFtOiIsIGRpZmZfY291bnQsICJuZ8aw4budaSIpDQoNCmNhdCgiTuG7ryBraMO0bmcgc+G7nyBo4buvdSBuaMOgIG5oaeG7gXUgaMahbiBuYW06IiwgZGlmZl9ub3Rfb3duZXJfY291bnQsICJuZ8aw4budaVxuIikNCmBgYA0KDQoNCi0gTmjhuq1uIHjDqXQ6DQoNCiAgLSBUcm9uZyBi4buZIGThu68gbGnhu4d1LCBjw7MgYHIgdGFibGVfZ2VuZGVyX2hvbWVvd25lclsiRiIsICJOIl1gIG7hu68ga2jDtG5nIHPhu58gaOG7r3UgbmjDoCB2w6AgYHIgdGFibGVfZ2VuZGVyX2hvbWVvd25lclsiRiIsICJZIl1gIG7hu68gc+G7nyBo4buvdSBuaMOgLg0KTmdvw6BpIHJhLCBjw7MgYHIgdGFibGVfZ2VuZGVyX2hvbWVvd25lclsiTSIsICJOIl1gIG5hbSBraMO0bmcgc+G7nyBo4buvdSBuaMOgIHbDoCBgciB0YWJsZV9nZW5kZXJfaG9tZW93bmVyWyJNIiwgIlkiXWAgbmFtIHPhu58gaOG7r3UgbmjDoC4NCg0KICAtIFPhu5EgbmfGsOG7nWkgbuG7ryBz4bufIGjhu691IG5ow6Agbmhp4buBdSBoxqFuIHPhu5EgbmfGsOG7nWkgbmFtIHPhu58gaOG7r3UgbmjDoCBi4bqxbmcgYHIgZGlmZl9jb3VudGAgbmfGsOG7nWkuDQoNCiAgLSBT4buRIG5nxrDhu51pIG7hu68ga2jDtG5nIHPhu58gaOG7r3UgbmjDoCBuaGnhu4F1IGjGoW4gc+G7kSBuZ8aw4budaSBuYW0ga2jDtG5nIHPhu58gaOG7r3UgbmjDoCBi4bqxbmcgYHIgZGlmZl9ub3Rfb3duZXJfY291bnRgIG5nxrDhu51pLg0KICANCmBgYHtyfQ0KIyBDaHV54buDbiBzYW5nIGRhdGFmcmFtZQ0KZGZfZ2ggPC0gYXMuZGF0YS5mcmFtZSh0YWJsZV9nZW5kZXJfaG9tZW93bmVyKQ0KY29sbmFtZXMoZGZfZ2gpIDwtIGMoIkdlbmRlciIsICJIb21lb3duZXIiLCAiQ291bnQiKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTDQpsaWJyYXJ5KGdncGxvdDIpDQpnZ3Bsb3QoZGZfZ2gsIGFlcyhHZW5kZXIsIENvdW50LCBmaWxsID0gSG9tZW93bmVyKSkgKyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKyANCiAgbGFicyh0aXRsZSA9ICJCaWV1IGRvIDExLiBTbyBsdW9uZyBzbyBodXUgbmhhIHRoZW8gZ2lvaSB0aW5oIiwNCiAgICAgICB4ID0gIkdpb2kgdGluaCIsIHkgPSAiU28gbHVvbmciLCBmaWxsID0gIlNvIGh1dSBuaGEiKSArIA0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCiMjIyAqKjQuMS4yLiBC4bqjbmcgdOG6p24gc3XhuqV0KioNCg0KYGBge3J9DQoNCiMgVOG7lW5nIHPhu5EgbeG6q3UNCnRvdGFsX3NhbXBsZXMgPC0gbnJvdyhkdCkNCg0KIyBU4bu3IGzhu4cgdHV54buHdCDEkeG7kWkgdHLDqm4gdOG7lW5nIHPhu5EgbeG6q3UNCnByb3BfYWJzIDwtIHRhYmxlX2dlbmRlcl9ob21lb3duZXIgLyB0b3RhbF9zYW1wbGVzDQoNCiMgVOG7tyBs4buHIHTGsMahbmcgxJHhu5FpIHRyb25nIHThu6tuZyBnaeG7m2kgdMOtbmggKHRoZW8gaMOgbmcpDQpwcm9wX2J5X2dlbmRlciA8LSBwcm9wLnRhYmxlKHRhYmxlX2dlbmRlcl9ob21lb3duZXIsIG1hcmdpbiA9IDEpICN0w61uaCB04bu3IGzhu4cgY2hvIHThu6tuZyBow6BuZywgdOG7qWMgbMOgIGNoaWEgdOG7q25nIGdpw6EgdHLhu4sgdHJvbmcgaMOgbmcgxJHDsyBjaG8gdOG7lW5nIGPhu6dhIGjDoG5nIMSRw7MuDQoNCiMgSW4gdOG7tyBs4buHIHR1eeG7h3QgxJHhu5FpIHRyw6puIHThu5VuZyBz4buRIG3huqt1DQpwcmludCgiVOG7tyBs4buHIHR1eeG7h3QgxJHhu5FpICh0csOqbiB04buVbmcgc+G7kSBt4bqrdSk6IikNCnByaW50KHJvdW5kKHByb3BfYWJzLCA0KSkNCmBgYA0KDQotIE5o4bqtbiB4w6l0Og0KDQogIC0gVHJvbmcgdOG7lW5nIHPhu5EgbeG6q3UsIHThu7cgbOG7hyBu4buvIGtow7RuZyBz4bufIGjhu691IG5ow6AgbMOgIGByIHJvdW5kKHByb3BfYWJzWyJGIiwgIk4iXSAqIDEwMCwgMilgJSwgdsOgIHThu7cgbOG7hyBu4buvIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgcm91bmQocHJvcF9hYnNbIkYiLCAiWSJdICogMTAwLCAyKWAlLiAgDQpUxrDGoW5nIHThu7EsIHThu7cgbOG7hyBuYW0ga2jDtG5nIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgcm91bmQocHJvcF9hYnNbIk0iLCAiTiJdICogMTAwLCAyKWAlLCB2w6AgdOG7tyBs4buHIG5hbSBz4bufIGjhu691IG5ow6AgbMOgIGByIHJvdW5kKHByb3BfYWJzWyJNIiwgIlkiXSAqIDEwMCwgMilgJS4NCg0KDQpgYGB7cn0NCiMgSW4gdOG7tyBs4buHIHTGsMahbmcgxJHhu5FpIHRyb25nIHThu6tuZyBnaeG7m2kgdMOtbmgNCnByaW50KCJU4bu3IGzhu4cgdMawxqFuZyDEkeG7kWkgdHJvbmcgdOG7q25nIGdp4bubaSB0w61uaDoiKQ0KcHJpbnQocm91bmQocHJvcF9ieV9nZW5kZXIsIDQpKQ0KYGBgDQoNCi0gTmjhuq1uIHjDqXQ6DQoNCiAgLSBUcm9uZyBuaMOzbSBu4buvLCB04bu3IGzhu4cga2jDtG5nIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgcm91bmQocHJvcF9ieV9nZW5kZXJbIkYiLCAiTiJdICogMTAwLCAyKWAlIHbDoCB04bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIGzDoCBgciByb3VuZChwcm9wX2J5X2dlbmRlclsiRiIsICJZIl0gKiAxMDAsIDIpYCUuICANClRyb25nIG5ow7NtIG5hbSwgdOG7tyBs4buHIGtow7RuZyBz4bufIGjhu691IG5ow6AgbMOgIGByIHJvdW5kKHByb3BfYnlfZ2VuZGVyWyJNIiwgIk4iXSAqIDEwMCwgMilgJSB2w6AgdOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgcm91bmQocHJvcF9ieV9nZW5kZXJbIk0iLCAiWSJdICogMTAwLCAyKWAlLg0KDQojIyMgKio0LjEuMy4gS2nhu4NtIMSR4buLbmggVGjhu5FuZyBrw6ogKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQotICoqSOKCgCoqOiBHaeG7m2kgdMOtbmggdsOgIHZp4buHYyBz4bufIGjhu691IG5ow6AgbMOgIGhhaSBiaeG6v24gxJHhu5ljIGzhuq1wLg0KDQotICoqSOKCgSoqOiBHaeG7m2kgdMOtbmggdsOgIHZp4buHYyBz4bufIGjhu691IG5ow6AgY8OzIGxpw6puIHF1YW4uDQoNCioqVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBDaGktYsOsbmggcGjGsMahbmcqKg0KDQpgYGB7cn0NCmNoaV90ZXN0IDwtIGNoaXNxLnRlc3QodGFibGVfZ2VuZGVyX2hvbWVvd25lcikNCmNoaV90ZXN0DQpgYGANCg0KYGBge3J9DQpjaGlfc3FfdmFsdWUgPC0gcm91bmQoY2hpX3Rlc3Qkc3RhdGlzdGljLCA0KQ0KZGZfdmFsdWUgPC0gY2hpX3Rlc3QkcGFyYW1ldGVyDQpwX3ZhbHVlIDwtIHJvdW5kKGNoaV90ZXN0JHAudmFsdWUsIDQpDQpgYGANCg0KLSBHacOhIHRy4buLIHRo4buRbmcga8OqIENoaS1iw6xuaCBwaMawxqFuZzogYHIgY2hpX3NxX3ZhbHVlYA0KDQotIELhuq1jIHThu7EgZG8gKGRmKTogYHIgZGZfdmFsdWVgDQoNCi0gR2nDoSB0cuG7iyBwOiBwX3ZhbHVlID0gYHIgcF92YWx1ZWANCg0KDQotIFbhu5tpIG3hu6ljIMO9IG5naMSpYSAkXGFscGhhID0gMC4wNSQsIGByIGlmZWxzZShwX3ZhbHVlIDwgMC4wNSwgInbDrCBwX3ZhbHVlIDwgMC4wNSwgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAsIHThu6ljIGzDoCBjw7MgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBnaeG7m2kgdMOtbmggdsOgIHZp4buHYyBz4bufIGjhu691IG5ow6AuIiwgInbDrCBwX3ZhbHVlIOKJpSAwLjA1LCB0YSBraMO0bmcgxJHhu6cgY8ahIHPhu58gxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAsIHThu6ljIGzDoCBraMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyDEkcOhbmcga+G7gyBnaeG7r2EgZ2nhu5tpIHTDrW5oIHbDoCB2aeG7h2Mgc+G7nyBo4buvdSBuaMOgLiIpYA0KDQojIyAqKjQuMi4gTWFyaXRhbFN0YXR1cyB2w6AgSG9tZW93bmVyKioNCg0KIyMjICoqNC4yLjEuIELhuqNuZyB04bqnbiBz4buRKioNCg0KYGBge3J9DQojIFThuqFvIGLhuqNuZyB04bqnbiBz4buRIGNow6lvDQp0YWJsZV9tYXJpdGFsX2hvbWVvd25lciA8LSB0YWJsZShkdCRNYXJpdGFsU3RhdHVzLCBkdCRIb21lb3duZXIpDQoNCiMgSGnhu4NuIHRo4buLIGLhuqNuZw0KdGFibGVfbWFyaXRhbF9ob21lb3duZXINCmBgYA0KDQpgYGB7cn0NCiMgVMOtbmggY2jDqm5oIGzhu4djaCBz4buRIGzGsOG7o25nIG5nxrDhu51pIHPhu58gaOG7r3UgbmjDoCBnaeG7r2EgTWFycmllZCAoTSkgdsOgIFNpbmdsZSAoUykNCmRpZmZfb3duZXJfY291bnQgPC0gdGFibGVfbWFyaXRhbF9ob21lb3duZXJbIk0iLCAiWSJdIC0gdGFibGVfbWFyaXRhbF9ob21lb3duZXJbIlMiLCAiWSJdDQoNCiMgVMOtbmggY2jDqm5oIGzhu4djaCBz4buRIGzGsOG7o25nIG5nxrDhu51pIEtIw5RORyBz4bufIGjhu691IG5ow6AgZ2nhu69hIE1hcnJpZWQgKE0pIHbDoCBTaW5nbGUgKFMpDQpkaWZmX25vdF9vd25lcl9jb3VudCA8LSB0YWJsZV9tYXJpdGFsX2hvbWVvd25lclsiTSIsICJOIl0gLSB0YWJsZV9tYXJpdGFsX2hvbWVvd25lclsiUyIsICJOIl0NCg0KIyBJbiBr4bq/dCBxdeG6oyBz4bufIGjhu691IG5ow6ANCmlmIChkaWZmX293bmVyX2NvdW50ID4gMCkgew0KICBtZXNzYWdlKCJOZ8aw4budaSDEkcOjIGvhur90IGjDtG4gc+G7nyBo4buvdSBuaGnhu4F1IG5ow6AgaMahbiBuZ8aw4budaSDEkeG7mWMgdGjDom46ICIsIGRpZmZfb3duZXJfY291bnQsICIgbmfGsOG7nWkiKQ0KfSBlbHNlIHsNCiAgbWVzc2FnZSgiTmfGsOG7nWkgxJHhu5ljIHRow6JuIHPhu58gaOG7r3Ugbmhp4buBdSBuaMOgIGjGoW4gbmfGsOG7nWkga+G6v3QgaMO0bjogIiwgYWJzKGRpZmZfb3duZXJfY291bnQpLCAiIG5nxrDhu51pIikNCn0NCg0KIyBJbiBr4bq/dCBxdeG6oyBLSMOUTkcgc+G7nyBo4buvdSBuaMOgDQppZiAoZGlmZl9ub3Rfb3duZXJfY291bnQgPiAwKSB7DQogIG1lc3NhZ2UoIk5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biBLSMOUTkcgc+G7nyBo4buvdSBuaMOgIG5oaeG7gXUgaMahbiBuZ8aw4budaSDEkeG7mWMgdGjDom46ICIsIGRpZmZfbm90X293bmVyX2NvdW50LCAiIG5nxrDhu51pIikNCn0gZWxzZSB7DQogIG1lc3NhZ2UoIk5nxrDhu51pIMSR4buZYyB0aMOibiBLSMOUTkcgc+G7nyBo4buvdSBuaMOgIG5oaeG7gXUgaMahbiBuZ8aw4budaSBr4bq/dCBow7RuOiAiLCBhYnMoZGlmZl9ub3Rfb3duZXJfY291bnQpLCAiIG5nxrDhu51pIikNCn0NCg0KYGBgDQoNCi0gTmjhuq1uIHjDqXQ6DQoNCiAgLSBUcm9uZyBi4buZIGThu68gbGnhu4d1LCBjw7MgYHIgdGFibGVfbWFyaXRhbF9ob21lb3duZXJbIlMiLCAiTiJdYCBuZ8aw4budaSDEkeG7mWMgdGjDom4ga2jDtG5nIHPhu58gaOG7r3UgbmjDoCB2w6AgYHIgdGFibGVfbWFyaXRhbF9ob21lb3duZXJbIlMiLCAiWSJdYCBuZ8aw4budaSDEkeG7mWMgdGjDom4gc+G7nyBo4buvdSBuaMOgLg0KTmdvw6BpIHJhLCBjw7MgYHIgdGFibGVfbWFyaXRhbF9ob21lb3duZXJbIk0iLCAiTiJdYCBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4ga2jDtG5nIHPhu58gaOG7r3UgbmjDoCB2w6AgYHIgdGFibGVfbWFyaXRhbF9ob21lb3duZXJbIk0iLCAiWSJdYCBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gc+G7nyBo4buvdSBuaMOgLg0KDQogIC0gU+G7kSBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gc+G7nyBo4buvdSBuaMOgIG5oaeG7gXUgaMahbiBuZ8aw4budaSDEkeG7mWMgdGjDom4gbMOgICBgciBkaWZmX293bmVyX2NvdW50YCBuZ8aw4budaS4NCg0KICAtIE5nxrDhu51pIMSR4buZYyB0aMOibiBraMO0bmcgc+G7nyBo4buvdSBuaMOgIG5oaeG7gXUgaMahbiBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gbMOgIGByIGFicyhkaWZmX25vdF9vd25lcl9jb3VudClgIG5nxrDhu51pLg0KICANCmBgYHtyfQ0KIyBDaHV54buDbiBi4bqjbmcgdOG6p24gc+G7kSBzYW5nIGThuqFuZyBkYXRhLmZyYW1lIGTDoGkNCmRhdGFfbG9uZyA8LSBhcy5kYXRhLmZyYW1lLnRhYmxlKHRhYmxlX21hcml0YWxfaG9tZW93bmVyKQ0KY29sbmFtZXMoZGF0YV9sb25nKSA8LSBjKCJNYXJpdGFsU3RhdHVzIiwgIkhvbWVvd25lciIsICJDb3VudCIpDQoNCiMgTOG7jWMgbmjDs20gTSB2w6AgUyBsdcO0biB0cm9uZyBnZ3Bsb3QNCmdncGxvdChkYXRhX2xvbmdbZGF0YV9sb25nJE1hcml0YWxTdGF0dXMgJWluJSBjKCJNIiwgIlMiKSwgXSwNCiAgICAgICBhZXMoeCA9IE1hcml0YWxTdGF0dXMsIHkgPSBDb3VudCwgZmlsbCA9IEhvbWVvd25lcikpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk4iID0gIiNGRjk5OTkiLCAiWSIgPSAiIzY2Q0M5OSIpLA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJLaG9uZyBzbyBodXUgbmhhIiwgIlNvIGh1dSBuaGEiKSkgKw0KICBsYWJzKHRpdGxlID0gIkJpZXUgZG8gMTIuIFNvIHNhbmggc28gbHVvbmcgbmd1b2kgc28gaHV1IHZhIGtob25nIHNvIGh1dSBuaGEgdGhlbyB0aW5oIHRyYW5nIGhvbiBuaGFuIiwNCiAgICAgICB4ID0gIlRpbmggdHJhbmcgaG9uIG5oYW4iLA0KICAgICAgIHkgPSAiU28gbHVvbmcgbmd1b2kiLA0KICAgICAgIGZpbGwgPSAiU28gaHV1IG5oYSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQojIyMgKio0LjIuMi4gQuG6o25nIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KIyBC4bqjbmcgdOG6p24gc+G7kSBnaeG7r2EgTWFyaXRhbFN0YXR1cyB2w6AgSG9tZW93bmVyDQp0YWJsZV9tYXJpdGFsX2hvbWVvd25lciA8LSB0YWJsZShkdCRNYXJpdGFsU3RhdHVzLCBkdCRIb21lb3duZXIpDQoNCiMgVOG7tyBs4buHIHR1eeG7h3QgxJHhu5FpIHNvIHbhu5tpIHThu5VuZyBz4buRIG3huqt1ICh0b8OgbiBi4buZIGRhdGFzZXQpDQpwcm9wX2FicyA8LSB0YWJsZV9tYXJpdGFsX2hvbWVvd25lciAvIHRvdGFsX3NhbXBsZXMNCg0KIyBU4bu3IGzhu4cgdGhlbyB04burbmcgaMOgbmcgKHRyb25nIHThu6tuZyBNYXJpdGFsU3RhdHVzKQ0KcHJvcF9ieV9tYXJpdGFsIDwtIHByb3AudGFibGUodGFibGVfbWFyaXRhbF9ob21lb3duZXIsIG1hcmdpbiA9IDEpDQoNCiMgTMOgbSB0csOybiDEkeG7gyBk4buFIHhlbQ0KcHJvcF9hYnMgPC0gcm91bmQocHJvcF9hYnMsIDQpDQpwcm9wX2J5X21hcml0YWwgPC0gcm91bmQocHJvcF9ieV9tYXJpdGFsLCA0KQ0KYGBgDQoNCmBgYHtyfQ0KIyBJbiByYSBi4bqjbmcgdOG7tyBs4buHIHR1eeG7h3QgxJHhu5FpIHbhu5tpIHRpw6p1IMSR4buBDQpjYXQoIj09PSBU4bu3IGzhu4cgdHV54buHdCDEkeG7kWkgdGhlbyB04burbmcgbmjDs20gTWFyaXRhbFN0YXR1cyB2w6AgSG9tZW93bmVyIChzbyB24bubaSB04buVbmcgc+G7kSBt4bqrdSkgPT09XG4iKQ0KcHJpbnQocHJvcF9hYnMpDQoNCmNhdCgiXG49PT0gVOG7tyBs4buHIHTGsMahbmcgxJHhu5FpIHRyb25nIHThu6tuZyBuaMOzbSBNYXJpdGFsU3RhdHVzICh04bu3IGzhu4cgdGhlbyBow6BuZykgPT09XG4iKQ0KcHJpbnQocHJvcF9ieV9tYXJpdGFsKQ0KYGBgDQoNCi0gVHJvbmcgdOG7lW5nIHPhu5EgbeG6q3UsIHThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biAoTSkgc+G7nyBo4buvdSBuaMOgIChZKSBsw6Aga2hv4bqjbmcgYHIgcm91bmQocHJvcF9hYnNbIk0iLCAiWSJdICogMTAwLCAyKWAlLCB2w6Aga2jDtG5nIHPhu58gaOG7r3UgbmjDoCAoTikgbMOgIGByIHJvdW5kKHByb3BfYWJzWyJNIiwgIk4iXSAqIDEwMCwgMilgJS4gIA0KLSDhu54gbmjDs20gbmfGsOG7nWkgxJHhu5ljIHRow6JuIChTKSwgdOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgcm91bmQocHJvcF9hYnNbIlMiLCAiWSJdICogMTAwLCAyKWAlLCB2w6Aga2jDtG5nIHPhu58gaOG7r3UgbmjDoCBsw6AgYHIgcm91bmQocHJvcF9hYnNbIlMiLCAiTiJdICogMTAwLCAyKWAlLg0KDQotIFjDqXQgdOG7tyBs4buHIHTGsMahbmcgxJHhu5FpIHRyb25nIHThu6tuZyBuaMOzbSBNYXJpdGFsU3RhdHVzOg0KICAtIFRyb25nIG5ow7NtIE0sIGPDsyB04bubaSBgciByb3VuZChwcm9wX2J5X21hcml0YWxbIk0iLCAiWSJdICogMTAwLCAyKWAlIGzDoCBjaOG7pyBuaMOgLCBuZ2jEqWEgbMOgIHBo4bqnbiBs4bubbiBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gc+G7nyBo4buvdSBuaMOgLg0KICAtIFRyb25nIG5ow7NtIFMsIHThu7cgbOG7hyBjaOG7pyBuaMOgIGNo4buJIGNoaeG6v20gYHIgcm91bmQocHJvcF9ieV9tYXJpdGFsWyJTIiwgIlkiXSAqIDEwMCwgMilgJSwgdGjhuqVwIGjGoW4ga2jDoSBuaGnhu4F1IHNvIHbhu5tpIG5ow7NtIE0uDQoNCk5oxrAgduG6rXksIHRhIHRo4bqleSBy4bqxbmcgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIGPDsyB4dSBoxrDhu5tuZyBz4bufIGjhu691IG5ow6AgY2FvIGjGoW4gc28gduG7m2kgbmfGsOG7nWkgxJHhu5ljIHRow6JuLg0KDQojIyMgKio0LjIuMy4gS2nhu4NtIMSR4buLbmggVGjhu5FuZyBrw6ogKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQotICoqSOKCgCoqOiBUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdsOgIHZp4buHYyBz4bufIGjhu691IG5ow6AgbMOgIGhhaSBiaeG6v24gxJHhu5ljIGzhuq1wLg0KDQotICoqSOKCgSoqOiBUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdsOgIHZp4buHYyBz4bufIGjhu691IG5ow6AgY8OzIGxpw6puIHF1YW4uDQoNCmBgYHtyfQ0KIyBUaOG7sWMgaGnhu4duIGtp4buDbSDEkeG7i25oIENoaS1iw6xuaCBwaMawxqFuZw0KY2hpc3FfcmVzdWx0IDwtIGNoaXNxLnRlc3QodGFibGVfbWFyaXRhbF9ob21lb3duZXIpDQoNCiMgWGVtIGvhur90IHF14bqjDQpjaGlzcV9yZXN1bHQNCmBgYA0KYGBge3J9DQojIFRyw61jaCB4deG6pXQgdGjDtG5nIHRpbg0KIyBUcsOtY2ggeHXhuqV0IHRow7RuZyB0aW4NCmNoaV9zcV92YWx1ZTEgPC0gcm91bmQoY2hpc3FfcmVzdWx0JHN0YXRpc3RpYywgNCkNCmRmX3ZhbHVlMSA8LSBjaGlzcV9yZXN1bHQkcGFyYW1ldGVyDQpwX3ZhbHVlMSA8LSByb3VuZChjaGlzcV9yZXN1bHQkcC52YWx1ZSwgNCkNCmBgYA0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpLWLDrG5oIHBoxrDGoW5nOiBgciBjaGlfc3FfdmFsdWUxYA0KDQotIELhuq1jIHThu7EgZG8gKGRmKTogYHIgZGZfdmFsdWUxYA0KDQotIEdpw6EgdHLhu4sgcDogcF92YWx1ZSA9IGByIHBfdmFsdWUxYA0KDQotIFbhu5tpIG3hu6ljIMO9IG5naMSpYSAkXGFscGhhID0gMC4wNSQsIGByIGlmZWxzZShwX3ZhbHVlMSA8IDAuMDUsIA0KICAidsOsIHBfdmFsdWUgPCAwLjA1LCB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgCwgdOG7qWMgbMOgIGPDsyBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiB2w6Agdmnhu4djIHPhu58gaOG7r3UgbmjDoC4iLCANCiAgInbDrCBwX3ZhbHVlIOKJpSAwLjA1LCB0YSBraMO0bmcgxJHhu6cgY8ahIHPhu58gxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAsIHThu6ljIGzDoCBraMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyDEkcOhbmcga+G7gyBnaeG7r2EgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIHbDoCB2aeG7h2Mgc+G7nyBo4buvdSBuaMOgLiIpYA0KDQotIE5o4bqtbiB4w6l0Og0KDQogIC0gTmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIChNKSBjw7MgdOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCBjYW8gaMahbiDEkcOhbmcga+G7gyBzbyB24bubaSBuZ8aw4budaSDEkeG7mWMgdGjDom4gKFMpLg0KDQogIC0gTmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIChNYXJyaWVkIC0gTSkgY8OzIHThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgY2FvLCDEkeG6oXQgYHIgcm91bmQocHJvcF9ieV9tYXJpdGFsWyJNIiwgIlkiXSoxMDAsIDIpYCUsIHRyb25nIGtoaSDEkcOzIG5nxrDhu51pIMSR4buZYyB0aMOibiAoU2luZ2xlIC0gUykgY2jhu4kgY8OzIHThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgbMOgIGByIHJvdW5kKHByb3BfYnlfbWFyaXRhbFsiUyIsICJZIl0qMTAwLCAyKWAlLg0KDQogIC0gTmfGsOG7o2MgbOG6oWksIHThu7cgbOG7hyBraMO0bmcgc+G7nyBo4buvdSBuaMOgIOG7nyBuaMOzbSDEkeG7mWMgdGjDom4gKGByIHJvdW5kKHByb3BfYnlfbWFyaXRhbFsiUyIsICJOIl0qMTAwLCAyKWAlKSBjYW8gaMahbiBuaGnhu4F1IHNvIHbhu5tpIG5ow7NtIMSRw6Mga+G6v3QgaMO0biAoYHIgcm91bmQocHJvcF9ieV9tYXJpdGFsWyJNIiwgIk4iXSoxMDAsIDIpYCUpLg0KDQogIC0gxJBp4buBdSBuw6B5IHBo4bqjbiDDoW5oIG5o4buvbmcgxJFp4buDbSBxdWFuIHRy4buNbmcgc2F1Og0KDQogICAgLSAgICoqS2luaCB04bq/IHbDoCB0csOhY2ggbmhp4buHbSBnaWEgxJHDrG5oOioqIE5nxrDhu51pIMSRw6Mga+G6v3QgaMO0biB0aMaw4budbmcgY8OzIHRodSBuaOG6rXAg4buVbiDEkeG7i25oIGjGoW4gaG/hurdjIGPDsyBz4buxIGjhu5cgdHLhu6MgduG7gSB0w6BpIGNow61uaCB04burIGPhuqMgaGFpIHbhu6MgY2jhu5NuZywgdOG7qyDEkcOzIGto4bqjIG7Eg25nIHPhu58gaOG7r3UgbmjDoCBjxaluZyBjYW8gaMahbi4gSOG7jSB0aMaw4budbmcgY8OzIHh1IGjGsOG7m25nIHTDrG0ga2nhur9tIHPhu7Eg4buVbiDEkeG7i25oIGzDonUgZMOgaSwgZMOgbmggc+G7sSDGsHUgdGnDqm4gY2hvIHZp4buHYyBtdWEgbmjDoCDEkeG7gyB4w6J5IGThu7FuZyB04buVIOG6pW0gdsOgIGNoxINtIHPDs2MgY29uIGPDoWkuDQoNCiAgICAtICoqTOG7kWkgc+G7kW5nIHbDoCDGsHUgdGnDqm4gY+G7p2EgbmfGsOG7nWkgxJHhu5ljIHRow6JuOioqIE5nxrDhu51pIMSR4buZYyB0aMOibiBjw7MgdGjhu4MgbOG7sWEgY2jhu41uIHRodcOqIG5ow6AgaG/hurdjIGPDoWMgaMOsbmggdGjhu6ljIGzGsHUgdHLDuiBsaW5oIGhv4bqhdCBoxqFuLCBkbyBraMO0bmcgYuG7iyByw6BuZyBideG7mWMgYuG7n2kgdHLDoWNoIG5oaeG7h20gZ2lhIMSRw6xuaC4gSOG7jSBjw7MgdGjhu4MgxrB1IHRpw6puIGPDoWMgY8ahIGjhu5lpIG5naOG7gSBuZ2hp4buHcCBob+G6t2MgZGkgY2h1eeG7g24gxJHhu4thIGzDvSwgbsOqbiB2aeG7h2Mgc+G7nyBo4buvdSBuaMOgIGtow7RuZyBwaOG6o2kgbMOgIMawdSB0acOqbiBow6BuZyDEkeG6p3UuDQoNCiMjICoqNC4zLiBBbm51YWxJbmNvbWUgdsOgIFByb2R1Y3RDYXRlZ29yeSoqDQoNCiMjIyAqKjQuMy4xLiBC4bqjbmcgdOG6p24gc+G7kSoqDQoNCmBgYHtyfQ0KIyBU4bqhbyBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBnaeG7r2EgQW5udWFsSW5jb21lIHbDoCBQcm9kdWN0Q2F0ZWdvcnkNCnRhYmxlX2luY29tZV9wcm9kdWN0IDwtIHRhYmxlKGR0JEFubnVhbEluY29tZSwgZHQkUHJvZHVjdENhdGVnb3J5KQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcgdOG6p24gc+G7kQ0KdGFibGVfaW5jb21lX3Byb2R1Y3QNCmBgYA0KDQpgYGB7cn0NCiMgMS4gVOG6oW8gZGlwIHThu6sgYuG6o25nIHRhYmxlX2luY29tZV9wcm9kdWN0DQpkaXAgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZV9pbmNvbWVfcHJvZHVjdCkNCmNvbG5hbWVzKGRpcCkgPC0gYygiQW5udWFsSW5jb21lIiwgIlByb2R1Y3RDYXRlZ29yeSIsICJGcmVxdWVuY3kiKQ0KDQojIDIuIEzhu41jIFRvcCA1IHPhuqNuIHBo4bqpbSB0aGVvIHThu5VuZyBz4buRIGzGsOG7o25nIG11YQ0KbGlicmFyeShkcGx5cikNCnRvcF9wcm9kdWN0cyA8LSBkaXAgJT4lDQogIGdyb3VwX2J5KFByb2R1Y3RDYXRlZ29yeSkgJT4lDQogIHN1bW1hcmlzZShUb3RhbCA9IHN1bShGcmVxdWVuY3kpKSAlPiUNCiAgYXJyYW5nZShkZXNjKFRvdGFsKSkgJT4lDQogIHNsaWNlX2hlYWQobiA9IDUpICU+JQ0KICBwdWxsKFByb2R1Y3RDYXRlZ29yeSkNCg0KZGlwX3RvcCA8LSBkaXAgJT4lIGZpbHRlcihQcm9kdWN0Q2F0ZWdvcnkgJWluJSB0b3BfcHJvZHVjdHMpDQoNCiMgMy4gVuG6vSBiaeG7g3UgxJHhu5MgduG7m2kgZGlwX3RvcA0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQoNCmdncGxvdChkaXBfdG9wLCBhZXMoeCA9IEFubnVhbEluY29tZSwgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IFByb2R1Y3RDYXRlZ29yeSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArICAgIyBob+G6t2MgIkRhcmsyIiwgIlBhc3RlbDEiLCAiQWNjZW50IiwgLi4uDQogIGxhYnModGl0bGUgPSAiQmnhu4N1IMSR4buTIDEzLiBUb3AgNSBz4bqjbiBwaOG6qW0gdGhlbyBz4buRIGzGsOG7o25nIG11YSB0aGVvIG3hu6ljIHRodSBuaOG6rXAiLA0KICAgICAgIHggPSAiTeG7qWMgdGh1IG5o4bqtcCIsDQogICAgICAgeSA9ICJT4buRIGzGsOG7o25nIiwNCiAgICAgICBmaWxsID0gIlPhuqNuIHBo4bqpbSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpgYGB7cn0NCiMgdG9wX3Byb2R1Y3RzIDwtIGRpcCAlPiUNCiMgIGdyb3VwX2J5KFByb2R1Y3RDYXRlZ29yeSkgJT4lICAgICAgICAgICAgICAgICAgICMgR29tIG5ow7NtIHRoZW8gZGFuaCBt4bulYyBz4bqjbiBwaOG6qW0NCiMgIHN1bW1hcmlzZShUb3RhbCA9IHN1bShGcmVxdWVuY3kpKSAlPiUgICAgICAgICAgICMgVMOtbmggdOG7lW5nIHPhu5EgbMaw4bujbmcgbXVhIGPhu6dhIHThu6tuZyBz4bqjbiBwaOG6qW0NCiMgIGFycmFuZ2UoZGVzYyhUb3RhbCkpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAjIFPhuq9wIHjhur9wIGdp4bqjbSBk4bqnbiB0aGVvIHThu5VuZyBz4buRIGzGsOG7o25nDQojICBzbGljZV9oZWFkKG4gPSA1KSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBM4bqleSA1IHPhuqNuIHBo4bqpbSDEkeG7qW5nIMSR4bqndQ0KIyAgcHVsbChQcm9kdWN0Q2F0ZWdvcnkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgTOG6pXkgdMOqbiBjw6FjIHPhuqNuIHBo4bqpbSBuw6B5IHRow6BuaCB2ZWN0b3INCmBgYA0KDQpgYGB7cn0NCiNnZ3Bsb3QoZGlwX3RvcCwgYWVzKC4uLikpOiDEkeG7i25oIG5naMSpYSBk4buvIGxp4buHdSB2w6AgbWFwcGluZzoNCg0KI1Ry4bulYyBYIGzDoCBBbm51YWxJbmNvbWUgKG3hu6ljIHRodSBuaOG6rXApLA0KDQojVHLhu6VjIFkgbMOgIEZyZXF1ZW5jeSAoc+G7kSBsxrDhu6NuZyBtdWEpLA0KDQojTcOgdSBj4buZdCB0aGVvIFByb2R1Y3RDYXRlZ29yeS4NCg0KI2dlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpOg0KDQojc3RhdCA9ICJpZGVudGl0eSI6IGzhuqV5IGNow61uaCBnacOhIHRy4buLIEZyZXF1ZW5jeSDEkeG7gyB24bq9IGNoaeG7gXUgY2FvIGPhu5l0LA0KDQojcG9zaXRpb24gPSAiZG9kZ2UiOiBjw6FjIGPhu5l0IGPhu6dhIHThu6tuZyBsb+G6oWkgc+G6o24gcGjhuqltIHPhur0gxJHhu6luZyBj4bqhbmggbmhhdSAoa2jDtG5nIGNo4buTbmcgbMOqbikuDQoNCiNzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKTogY2jhu41uIGLhuqNuZyBtw6B1IMSR4bq5cCwgbmjhurkgbeG6r3QgdOG7qyB0aMawIHZp4buHbiBSQ29sb3JCcmV3ZXIuDQoNCiNsYWJzKC4uLik6IMSR4bq3dCB0acOqdSDEkeG7gSwgbmjDo24gdHLhu6VjIHbDoCBjaMO6IHRow61jaCBtw6B1Lg0KDQojdGhlbWVfbWluaW1hbCgpOiBnaWFvIGRp4buHbiBiaeG7g3UgxJHhu5MgxJHGoW4gZ2nhuqNuLCDDrXQgY2hpIHRp4bq/dCBy4buRaSBt4bqvdC4NCg0KI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpOiB4b2F5IG5ow6NuIHRy4bulYyBYIDQ1IMSR4buZIMSR4buDIGThu4UgxJHhu41jLCBjxINuIGNo4buJbmggaOG7o3AgbMO9Lg0KYGBgDQoNCkThu7FhIHRyw6puIGLhuqNuZyB04bqnbiBz4buRIGNow6lvIGdp4buvYSBiaeG6v24gQW5udWFsSW5jb21lIHbDoCBQcm9kdWN0Q2F0ZWdvcnksIGNow7puZyB0YSBuaOG6rW4gdGjhuqV5IG5o4buvbmcgeHUgaMaw4bubbmcgdGnDqnUgZMO5bmcga2jDoWMgbmhhdSB0aGVvIG3hu6ljIHRodSBuaOG6rXA6DQoNCi0gTmjDs20gdGh1IG5o4bqtcCB04burICQzMEsgLSAkNTBLIGPDsyBz4buRIGzGsOG7o25nIGdpYW8gZOG7i2NoIGNhbyBuaOG6pXQg4bufIGjhuqd1IGjhur90IGPDoWMgZGFuaCBt4bulYywgY2jhurNuZyBo4bqhbiBuaMawOg0KDQogICAgLSAqKlNuYWNrIEZvb2RzOioqIGByIHRhYmxlX2luY29tZV9wcm9kdWN0WyIkMzBLIC0gJDUwSyIsICJTbmFjayBGb29kcyJdYCBnaWFvIGThu4tjaC4NCg0KICAgIC0gKipWZWdldGFibGVzOioqIGByIHRhYmxlX2luY29tZV9wcm9kdWN0WyIkMzBLIC0gJDUwSyIsICJWZWdldGFibGVzIl1gIGdpYW8gZOG7i2NoLg0KDQogICAgLSAqKkRhaXJ5OioqIGByIHRhYmxlX2luY29tZV9wcm9kdWN0WyIkMzBLIC0gJDUwSyIsICJEYWlyeSJdYCBnaWFvIGThu4tjaC4NCg0KICAgIC0gxJDDonkgY8OzIHRo4buDIGzDoCBkbyBuaMOzbSBuw6B5IMSR4bqhaSBkaeG7h24gY2hvIHThuqduZyBs4bubcCB0cnVuZyBsxrB1LCBjw7Mga2jhuqMgbsSDbmcgY2hpIHRpw6p1IGNhbyBuaMawbmcgduG6q24gY2jDuiB0cuG7jW5nIGPDoWMgbeG6t3QgaMOgbmcgdGhp4bq/dCB54bq/dSwgcGjhu5UgYmnhur9uLg0KDQotIE5ow7NtIHRodSBuaOG6rXAgdGjhuqVwICgkMTBLIC0gJDMwSykgY8WpbmcgY8OzIGzGsOG7o25nIGdpYW8gZOG7i2NoIHTGsMahbmcgxJHhu5FpIGNhbywgxJHhurdjIGJp4buHdCB0cm9uZyBjw6FjIGRhbmggbeG7pWMgbmjGsDoNCg0KICAgIC0gKipWZWdldGFibGVzOioqIGByIHRhYmxlX2luY29tZV9wcm9kdWN0WyIkMTBLIC0gJDMwSyIsICJWZWdldGFibGVzIl1gIGdpYW8gZOG7i2NoLg0KDQogICAgLSAqKlNuYWNrIEZvb2RzOioqIGByIHRhYmxlX2luY29tZV9wcm9kdWN0WyIkMTBLIC0gJDMwSyIsICJTbmFjayBGb29kcyJdYCBnaWFvIGThu4tjaC4NCg0KICAgIC0gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbmh1IGPhuqd1IG11YSBjw6FjIHPhuqNuIHBo4bqpbSBjxqEgYuG6o24gdsOgIGdpw6EgY+G6oyBwaOG6o2kgY2jEg25nIHbhuqtuIHLhuqV0IGzhu5tuIHRyb25nIG5ow7NtIHRodSBuaOG6rXAgdGjhuqVwLg0KDQotIE5ow7NtIHRodSBuaOG6rXAgY2FvICgkMTUwSysgdsOgICQxMzBLIC0gJDE1MEspIGPDsyBz4buRIGzGsOG7o25nIGdpYW8gZOG7i2NoIHRo4bqlcCBoxqFuIHLDtSBy4buHdDoNCg0KICAgIC0gQ2jhu4kgY8OzIGByIHRhYmxlX2luY29tZV9wcm9kdWN0WyIkMTUwSyArIiwgIlNuYWNrIEZvb2RzIl1gIGdpYW8gZOG7i2NoIOG7nyBTbmFjayBGb29kcyB2w6AgYHIgdGFibGVfaW5jb21lX3Byb2R1Y3RbIiQxNTBLICsiLCAiVmVnZXRhYmxlcyJdYCDhu58gVmVnZXRhYmxlcy4NCg0KICAgIC0gQ8OzIHRo4buDIGRvIHPhu5EgbMaw4bujbmcga2jDoWNoIHRodeG7mWMgbmjDs20gbsOgeSDDrXQgaMahbiB0cm9uZyB04bqtcCBk4buvIGxp4buHdSBob+G6t2MgaMOgbmggdmkgdGnDqnUgZMO5bmcga2jDoWMgYmnhu4d0ICjDrXQgbXVhIGjDoG5nIHThuqFpIHNpw6p1IHRo4buLLCDGsHUgdGnDqm4gc+G6o24gcGjhuqltIGNhbyBj4bqlcCBob+G6t2MgbXVhIHPhuq9tIG9ubGluZSkuDQogICAgDQojIyMgKio0LjMuMi4gQuG6o25nIHThuqduIHN14bqldCoqDQoNCmBgYHtyfQ0KIyMgLS0tIDIuIFThu7YgTOG7hiBUVVnhu4ZUIMSQ4buQSSBzbyB24bubaSB0b8OgbiBi4buZIG3huqt1IC0tLS0tLS0tLS0tLS0tLS0tLS0tDQp0b3RhbF9zYW1wbGVzIDwtIG5yb3coZHQpDQpwcm9wX2Fic19pcCA8LSByb3VuZCh0YWJsZV9pbmNvbWVfcHJvZHVjdCAvIHRvdGFsX3NhbXBsZXMsIDQpDQoNCmNhdCgiXG4+Pj4gVOG7tyBs4buHIHR1eeG7h3QgxJHhu5FpICh0csOqbiB04buVbmcgc+G7kSBt4bqrdSk6XG4iKQ0KcHJpbnQocHJvcF9hYnNfaXApDQpgYGANCg0KLSBOaMOzbSB0aHUgbmjhuq1wICoqJDMwSyAtICQ1MEsqKiBsw6AgbmjDs20gY2hp4bq/bSB04bu3IGzhu4cgbXVhIG5oaeG7gXUgbmjhuqV0IOG7nyBo4bqndSBo4bq/dCBjw6FjIHPhuqNuIHBo4bqpbSwgY+G7pSB0aOG7gzoNCiAgLSAqKlZlZ2V0YWJsZXMqKiBjaGnhur9tIGtob+G6o25nIGByIHJvdW5kKHByb3BfYWJzX2lwWyIkMzBLIC0gJDUwSyIsICJWZWdldGFibGVzIl0sIDQpYCAoY2FvIG5o4bqldCB0cm9uZyBjw6FjIG5ow7NtKS4NCiAgLSAqKlNuYWNrIEZvb2RzKiogY2hp4bq/bSBraG/huqNuZyBgciByb3VuZChwcm9wX2Fic19pcFsiJDMwSyAtICQ1MEsiLCAiU25hY2sgRm9vZHMiXSwgNClgLCDEkeG7qW5nIMSR4bqndSB0b8OgbiBi4buZIGPDoWMgbmjDs20uDQogIC0gKipGcnVpdCoqIGNoaeG6v20ga2hv4bqjbmcgYHIgcm91bmQocHJvcF9hYnNfaXBbIiQzMEsgLSAkNTBLIiwgIkZydWl0Il0sIDQpYC4NCg0KLSBOZ8aw4bujYyBs4bqhaSwgbmjDs20gdGh1IG5o4bqtcCBjYW8gbmjhuqV0ICoqJDE1MEsgKyoqIGPDsyB04bu3IGzhu4cgbXVhIG5oaeG7gXUgc+G6o24gcGjhuqltIHRoxrDhu51uZyB0aOG6pXAgaMahbiBzbyB24bubaSBuaMOzbSB0cnVuZyBiw6xuaCB2w6AgdGjhuqVwLCB2w60gZOG7pToNCiAgLSAqKlZlZ2V0YWJsZXMqKiBjaOG7iSBjaGnhur9tIGtob+G6o25nIGByIHJvdW5kKHByb3BfYWJzX2lwWyIkMTUwSyArIiwgIlZlZ2V0YWJsZXMiXSwgNClgLg0KICAtICoqU25hY2sgRm9vZHMqKiBjaGnhur9tIGtob+G6o25nIGByIHJvdW5kKHByb3BfYWJzX2lwWyIkMTUwSyArIiwgIlNuYWNrIEZvb2RzIl0sIDQpYC4NCg0KLSBOaMOzbSB0aHUgbmjhuq1wIHRo4bqlcCBuaOG6pXQgKiokMTBLIC0gJDMwSyoqIGPFqW5nIGR1eSB0csOsIHThu7cgbOG7hyBtdWEga2jDoSBjYW8g4bufIG3hu5l0IHPhu5Egc+G6o24gcGjhuqltIHRoaeG6v3QgeeG6v3UsIG5oxrA6DQogIC0gKipGcnVpdCoqOiBraG/huqNuZyBgciByb3VuZChwcm9wX2Fic19pcFsiJDEwSyAtICQzMEsiLCAiRnJ1aXQiXSwgNClgLCBjaOG7iSB0aOG6pXAgaMahbiBuaMOzbSAkMzBLIC0gJDUwSy4NCiAgLSAqKlZlZ2V0YWJsZXMqKjoga2hv4bqjbmcgYHIgcm91bmQocHJvcF9hYnNfaXBbIiQxMEsgLSAkMzBLIiwgIlZlZ2V0YWJsZXMiXSw0KWAuDQoNCi0gTeG7mXQgc+G7kSBt4bq3dCBow6BuZyBuaMawICoqRnJvemVuIERlc3NlcnRzKiogY8OzIHThu7cgbOG7hyBtdWEgcGjDom4gYuG7kSBraMOhIMSR4buBdSBnaeG7r2EgY8OhYyBuaMOzbSB0aHUgbmjhuq1wLCB2w60gZOG7pToNCiAgLSBOaMOzbSAkMzBLIC0gJDUwSzogYHIgcm91bmQocHJvcF9hYnNfaXBbIiQzMEsgLSAkNTBLIiwgIkZyb3plbiBEZXNzZXJ0cyJdLCA0KWANCiAgLSBOaMOzbSAkMTBLIC0gJDMwSzogYHIgcm91bmQocHJvcF9hYnNfaXBbIiQxMEsgLSAkMzBLIiwgIkZyb3plbiBEZXNzZXJ0cyJdLCA0KWANCiAgLSBOaMOzbSAkMTUwSyArOiBgciByb3VuZChwcm9wX2Fic19pcFsiJDE1MEsgKyIsICJGcm96ZW4gRGVzc2VydHMiXSlgDQoNCi0gVOG7lW5nIHRo4buDLCBuaMOzbSB0aHUgbmjhuq1wIHRydW5nIGLDrG5oIHRo4bqlcCAoJDMwSyAtICQ1MEspIGzDoCBuaMOzbSBjw7MgaG/huqF0IMSR4buZbmcgbXVhIHPhuq9tIG3huqFuaCBt4bq9IG5o4bqldCwgduG7m2kgdOG7tyBs4buHIHR1eeG7h3QgxJHhu5FpIGNhbyBoxqFuIGjhurNuIGPDoWMgbmjDs20ga2jDoWMg4bufIMSRYSBz4buRIHPhuqNuIHBo4bqpbS4NCg0KYGBge3J9DQojIyAtLS0gMy4gVOG7tiBM4buGIFTGr8agTkcgxJDhu5BJIHRoZW8gdOG7q25nIGjDoG5nICh04burbmcgbeG7qWMgdGh1IG5o4bqtcCkgLS0tLQ0KcHJvcF9ieV9pbmNvbWUgPC0gcm91bmQocHJvcC50YWJsZSh0YWJsZV9pbmNvbWVfcHJvZHVjdCwgbWFyZ2luID0gMSksIDQpDQoNCmNhdCgiXG4+Pj4gVOG7tyBs4buHIHTGsMahbmcgxJHhu5FpIHRyb25nIHThu6tuZyBuaMOzbSB0aHUgbmjhuq1wOlxuIikNCnByaW50KHByb3BfYnlfaW5jb21lKQ0KYGBgDQoNCi0gKipOaMOzbSB0aHUgbmjhuq1wIHRo4bqlcCAoJDEwSyAtICQzMEspOioqDQogICAtIFThu7cgbOG7hyBtdWEgY2FvIOG7nyBjw6FjIG5ow7NtIHPhuqNuIHBo4bqpbSB0aGnhur90IHnhur91IG5oxrA6DQogICAgIC0gKipWZWdldGFibGVzKiogY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCB0cm9uZyBjw6FjIG5ow7NtIHRodSBuaOG6rXAuDQogICAgIC0gKipGcnVpdCoqIGPFqW5nIGPDsyB04bu3IGzhu4cgbXVhIGNhby4NCiAgICAgLSBDw6FjIG3hurd0IGjDoG5nIG5oxrAgKipCcmVha2Zhc3QgRm9vZHMqKiwgKipEYWlyeSoqLCB2w6AgKipTbmFjayBGb29kcyoqIGPDsyB04bu3IGzhu4cgbXVhIHTGsMahbmcgxJHhu5FpIGzhu5tuLCB0aOG7gyBoaeG7h24gbmh1IGPhuqd1IHThuq1wIHRydW5nIHbDoG8gdGjhu7FjIHBo4bqpbSBjxqEgYuG6o24gdsOgIHRp4buHbiBs4bujaS4NCg0KLSAqKk5ow7NtIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmggdGjhuqVwICgkMzBLIC0gJDUwSyk6KioNCiAgIC0gVOG7tyBs4buHIG11YSB0xrDGoW5nIMSR4buRaSDEkeG7k25nIMSR4buBdSB2w6AgY2FvIOG7nyBuaGnhu4F1IGxv4bqhaSBz4bqjbiBwaOG6qW0uDQogICAtIEPDoWMgc+G6o24gcGjhuqltIG5oxrAgKipWZWdldGFibGVzKiosICoqU25hY2sgRm9vZHMqKiwgKipGcnVpdCoqLCAqKkZyb3plbiBEZXNzZXJ0cyoqIMSRxrDhu6NjIG11YSBuaGnhu4F1Lg0KICAgLSBN4bq3dCBow6BuZyBraMO0bmcgdGhp4bq/dCB54bq/dSBuaMawICoqQ2FuZGxlcyoqIHbDoCAqKkphbXMgYW5kIEplbGxpZXMqKiBjxaluZyBjw7MgdOG7tyBs4buHIG11YSDhu5VuLCB0aOG7gyBoaeG7h24gY2hpIHRpw6p1IMSRYSBk4bqhbmcgaMahbi4NCg0KLSAqKk5ow7NtIHRodSBuaOG6rXAgdHJ1bmcgYsOsbmggY2FvICgkOTBLIC0gJDExMEssICQxMTBLIC0gJDEzMEssICQxMzBLIC0gJDE1MEspOioqDQogICAtIFThu7cgbOG7hyBtdWEgdGjhu7FjIHBo4bqpbSBjaMOtbmggbmjGsCAqKkRhaXJ5KiosICoqVmVnZXRhYmxlcyoqLCAqKkZydWl0Kiog4buVbiDEkeG7i25oIG5oxrBuZyBraMO0bmcgdsaw4bujdCB0cuG7mWkuDQogICAtIE5ow7NtICQxMzBLIC0gJDE1MEsgY8OzIHThu7cgbOG7hyBtdWEgKipGcnVpdCoqIGNhbyBuaOG6pXQuDQogICAtIEPDoWMgc+G6o24gcGjhuqltIMSR4bq3YyB0aMO5IG5oxrAgKipNYWdhemluZXMqKiB2w6AgKipNZWF0KiogY8OzIHThu7cgbOG7hyBtdWEgdMSDbmcsIHBo4bqjbiDDoW5oIGNoaSB0acOqdSBjaG8gbeG6t3QgaMOgbmcgY2FvIGPhuqVwIGhv4bq3YyDEkeG6t2MgdGjDuSBoxqFuLg0KDQotICoqTmjDs20gdGh1IG5o4bqtcCBjYW8gKCQxNTBLKyk6KioNCiAgIC0gVOG7tyBs4buHIG11YSBwaMOibiBi4buVIMSR4buBdSDhu58gbmhp4buBdSBt4bq3dCBow6BuZyB0aGnhur90IHnhur91Lg0KICAgLSAqKlNuYWNrIEZvb2RzKiogdsOgICoqVmVnZXRhYmxlcyoqIGR1eSB0csOsIHThu7cgbOG7hyBtdWEgY2FvLg0KICAgLSBN4buZdCBz4buRIHPhuqNuIHBo4bqpbSBuaMawICoqQnJlYWtmYXN0IEZvb2RzKiogY8OzIHThu7cgbOG7hyBtdWEgdGjhuqVwIGjGoW4sIGPDsyB0aOG7gyBkbyB0aGF5IMSR4buVaSB0aMOzaSBxdWVuIHRpw6p1IGTDuW5nLg0KICAgLSBN4bupYyBtdWEgKipDYW5uZWQgT3lzdGVycyoqLCAqKkZyb3plbiBEZXNzZXJ0cyoqIHTGsMahbmcgxJHhu5FpIOG7lW4gxJHhu4tuaCwgY2hvIHRo4bqleSDEkWEgZOG6oW5nIGzhu7FhIGNo4buNbi4NCg0KLSAqKk3hu5l0IHPhu5EgxJFp4buDbSDEkcOhbmcgY2jDuiDDvToqKg0KICAgLSBOaMOzbSB0aHUgbmjhuq1wIHRydW5nIGLDrG5oIHRo4bqlcCB2w6AgdHJ1bmcgYsOsbmggY2FvIGPDsyB04bu3IGzhu4cgbXVhIGjDoG5nIGtow6EgdMawxqFuZyDEkeG7k25nIG5oxrBuZyBuaMOzbSBjYW8gaMahbiBjaGkgbmhp4buBdSBjaG8gKipEYWlyeSoqIHbDoCAqKk1lYXQqKi4NCiAgIC0gQ8OhYyBz4bqjbiBwaOG6qW0gbmjGsCAqKkNhbmRsZXMqKiwgKipDYW5uZWQgQW5jaG92aWVzKiosICoqQ2FubmVkIENsYW1zKiogY8OzIHThu7cgbOG7hyBtdWEgdGjhuqVwIOG7nyB04bqldCBj4bqjIG5ow7NtLCB0aOG7gyBoaeG7h24gxJHDonkga2jDtG5nIHBo4bqjaSBsw6AgaMOgbmcgcGjhu5UgYmnhur9uLg0KICAgLSAqKlNuYWNrIEZvb2RzKiogbHXDtG4gZ2nhu68gdOG7tyBs4buHIG11YSBjYW8g4bufIHThuqV0IGPhuqMgbmjDs20sIMSR4bq3YyBiaeG7h3QgbmjDs20gdGh1IG5o4bqtcCBjYW8gdsOgIHRydW5nIGLDrG5oIHRo4bqlcCwgdGjhu4MgaGnhu4duIHh1IGjGsOG7m25nIHRpw6p1IGTDuW5nIHLhu5luZyByw6NpLg0KICAgDQojIyMgKio0LjMuMy4gS2nhu4NtIMSR4buLbmggVGjhu5FuZyBrw6ogKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQoqKkjigoAqKjogSGFpIGJp4bq/biBBbm51YWxJbmNvbWUgdsOgIFByb2R1Y3RDYXRlZ29yeSBsw6AgxJHhu5ljIGzhuq1wIChraMO0bmcgY8OzIG3hu5FpIGxpw6puIGjhu4cpDQoNCioqSOKCgSoqOiBIYWkgYmnhur9uIEFubnVhbEluY29tZSB2w6AgUHJvZHVjdENhdGVnb3J5IGPDsyBt4buRaSBsacOqbiBxdWFuIChraMO0bmcgxJHhu5ljIGzhuq1wKQ0KDQpgYGB7cn0NCiMgVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBDaGktc3F1YXJlZA0KY2hpX3Rlc3QxIDwtIGNoaXNxLnRlc3QodGFibGVfaW5jb21lX3Byb2R1Y3QpDQoNCiMgWGVtIGvhur90IHF14bqjDQpjaGlfdGVzdDENCmBgYA0KDQpgYGB7cn0NCmNoaV9zcV92YWx1ZTIgPC0gcm91bmQoY2hpX3Rlc3QxJHN0YXRpc3RpYywgNCkNCmRmX3ZhbHVlMiA8LSBjaGlfdGVzdDEkcGFyYW1ldGVyDQpwX3ZhbHVlMiA8LSByb3VuZChjaGlfdGVzdDEkcC52YWx1ZSwgNCkNCg0KYGBgDQoNCi0gR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiBDaGktYsOsbmggcGjGsMahbmc6IGByIGNoaV9zcV92YWx1ZTJgDQoNCi0gQuG6rWMgdOG7sSBkbyAoZGYpOiBgciBkZl92YWx1ZTJgDQoNCi0gR2nDoSB0cuG7iyBwOiBwX3ZhbHVlID0gYHIgcF92YWx1ZTJgDQoNCi0gVuG7m2kgbeG7qWMgw70gbmdoxKlhICRcYWxwaGEgPSAwLjA1JCwgDQpgciBpZmVsc2UocF92YWx1ZSA8IDAuMDUsIA0KICAidsOsIHBfdmFsdWUgPCAwLjA1LCB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgCwgdOG7qWMgbMOgIGPDsyBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIG3hu6ljIHRodSBuaOG6rXAgaMOgbmcgbsSDbSB2w6AgbG/huqFpIHPhuqNuIHBo4bqpbSDEkcaw4bujYyBtdWEuIiwNCiAgInbDrCBwX3ZhbHVlIOKJpSAwLjA1LCB0YSBraMO0bmcgxJHhu6cgY8ahIHPhu58gxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAsIHThu6ljIGzDoCBraMO0bmcgY8OzIG3hu5FpIHF1YW4gaOG7hyDEkcOhbmcga+G7gyBnaeG7r2EgbeG7qWMgdGh1IG5o4bqtcCBow6BuZyBuxINtIHbDoCBsb+G6oWkgc+G6o24gcGjhuqltIMSRxrDhu6NjIG11YS4iKWANCg0KIyAqKlBo4bqnbiA1LiBQSMOCTiBUw41DSCBC4bqiTkcgTkfhuqpVIE5IScOKTiAyeDIqKg0KDQojIyAqKjUuMS4gR2nhu5tpIHRoaeG7h3UqKg0KDQpUcm9uZyBwaMOibiB0w61jaCB0aOG7kW5nIGvDqiDEkeG7i25oIGzGsOG7o25nLCBi4bqjbmcgbmfhuqt1IG5oacOqbiAoY29udGluZ2VuY3kgdGFibGUpIGzDoCBt4buZdCBjw7RuZyBj4bulIGPGoSBi4bqjbiDEkeG7gyBraOG6o28gc8OhdCBt4buRaSBsacOqbiBo4buHIGdp4buvYSBoYWkgYmnhur9uIHBow6JuIGxv4bqhaS4gVHJvbmcgdHLGsOG7nW5nIGjhu6NwIMSRxqFuIGdp4bqjbiBuaOG6pXQsIGLhuqNuZyBuZ+G6q3Ugbmhpw6puIDJ4MiBiaeG7g3UgZGnhu4VuIHPhu7EgcGjDom4gYuG7kSBj4bunYSBoYWkgYmnhur9uIG5o4buLIHBow6JuLCBnacO6cCB4w6FjIMSR4buLbmggdsOgIMSRbyBsxrDhu51uZyBt4buRaSBsacOqbiBo4buHIGdp4buvYSBjaMO6bmcuIEPDoWMgY2jhu4kgc+G7kSBuaMawIGhp4buHdSB04bu3IGzhu4cgKHJpc2sgZGlmZmVyZW5jZSksIHThu7cgc+G7kSBuZ3V5IGPGoSAoUmVsYXRpdmUgUmlzayAtIFJSKSB2w6AgdOG7tyBz4buRIGNow6puaCAoT2RkcyBSYXRpbyAtIE9SKSDEkcOzbmcgdmFpIHRyw7IgcXVhbiB0cuG7jW5nIHRyb25nIHZp4buHYyBsxrDhu6NuZyBow7NhIG3hu5FpIHF1YW4gaOG7hyDEkcOzLiBCw6BpIHZp4bq/dCBuw6B5IHPhur0gdHLDrG5oIGLDoHkgY2hpIHRp4bq/dCBj4bqldSB0csO6YyB4w6FjIHN14bqldCBzaW5oIHJhIGLhuqNuZyBuZ+G6q3Ugbmhpw6puLCBwaMawxqFuZyBwaMOhcCBzbyBzw6FuaCBoYWkgdOG7tyBs4buHLCBjw6FjaCB4w6J5IGThu7FuZyBraG/huqNuZyB0aW4gY+G6rXkgY2hvIE9kZHMgUmF0aW8sIHbDoCBr4bq/dCB0aMO6YyBi4bqxbmcgbeG7mXQgdsOtIGThu6UgdGjhu7FjIHRp4buFbiB0cm9uZyBsxKluaCB24buxYyBraW5oIGRvYW5oLg0KDQojIyAqKjUuMi4gQ+G6pXUgdHLDumMgdsOgIHjDoWMgc3XhuqV0IGPhu6dhIGLhuqNuZyBuZ+G6q3Ugbmhpw6puKioNCg0KTeG7mXQgYuG6o25nIG5n4bqrdSBuaGnDqm4gMngyIGzDoCBi4bqjbmcgdOG6p24gc3XhuqV0IMSR4bq/bSBz4buRIHF1YW4gc8OhdCB0aHXhu5ljIHbDoG8gdOG7q25nIHThu5UgaOG7o3AgY+G7p2EgaGFpIGJp4bq/biBuaOG7iyBwaMOibjoNCg0KXFsNClxiZWdpbnthcnJheX17fGN8Y3xjfGN8fQ0KXGhsaW5lDQogJiBcdGV4dHtL4bq/dCBxdeG6oyAoKyl9ICYgXHRleHR7S+G6v3QgcXXhuqMgKOKAkyl9ICYgXHRleHR7VOG7lW5nfSBcXA0KXGhsaW5lDQpcdGV4dHtQaMahaSBuaGnhu4VtIChZZXMpfSAmIGEgJiBiICYgYSArIGIgXFwNClxobGluZQ0KXHRleHR7S2jDtG5nIHBoxqFpIG5oaeG7hW0gKE5vKX0gJiBjICYgZCAmIGMgKyBkIFxcDQpcaGxpbmUNClx0ZXh0e1Thu5VuZyBj4buZbmd9ICYgYSArIGMgJiBiICsgZCAmIG4gPSBhICsgYiArIGMgKyBkIFxcDQpcaGxpbmUNClxlbmR7YXJyYXl9DQpcXQ0KDQrEkOG7gyBoaeG7g3UgxJHGsOG7o2Mgc+G7sSBow6xuaCB0aMOgbmggY+G7p2EgYuG6o25nIG7DoHksIGPhuqduIHjDoWMgxJHhu4tuaCBtw7QgaMOsbmggeMOhYyBzdeG6pXQgc2luaCByYSBk4buvIGxp4buHdSDigJQgdHJvbmcgxJHDsyBwaOG7lSBiaeG6v24gbmjhuqV0IGzDoCBwaMOibiBwaOG7kWkgKipQb2lzc29uKiogdsOgICoqTXVsdGlub21pYWwqKi4NCg0KIyMjICoqNS4yLjEuIFBow6JuIHBo4buRaSBQb2lzc29uKioNCg0KUGjDom4gcGjhu5FpIFBvaXNzb24gdGjGsOG7nW5nIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIG3DtCBow6xuaCBow7NhIHPhu5EgbMaw4bujbmcgc+G7sSBraeG7h24geOG6o3kgcmEgdHJvbmcgbeG7mXQga2hv4bqjbmcgdGjhu51pIGdpYW4sIGtow7RuZyBnaWFuIGhv4bq3YyDEkcahbiB24buLIGPhu6UgdGjhu4MuIEdp4bqjIHPhu60gY8OhYyBz4buxIGtp4buHbiB44bqjeSByYSDEkeG7mWMgbOG6rXAgdsOgIHbhu5tpIG3hu5l0IHThu7cgbOG7hyB0cnVuZyBiw6xuaCBraMO0bmcgxJHhu5VpLCBt4buXaSDDtCB0cm9uZyBi4bqjbmcgY8OzIHRo4buDIHhlbSBsw6AgYmnhur9uIG5n4bqrdSBuaGnDqm4gUG9pc3NvbjoNCg0KXFsNClhfe2lqfSBcc2ltIFx0ZXh0e1BvaXNzb259KFxsYW1iZGFfe2lqfSkNClxdDQoNCioqxq91IMSRaeG7g206KioNCg0KLSBQaMO5IGjhu6NwIGtoaSB04buVbmcgc+G7kSBxdWFuIHPDoXQga2jDtG5nIGPhu5EgxJHhu4tuaC4NCg0KLSDDgXAgZOG7pW5nIHRyb25nIHBow6JuIHTDrWNoIHPhu5Egc+G7sSBraeG7h24gbmjGsDogc+G7kSBsxrDhu6N0IHRydXkgY+G6rXAsIHPhu5EgxJHGoW4gaMOgbmcgbOG7l2ksIHYudi4NCg0KKipI4bqhbiBjaOG6vzoqKg0KDQotIEtow7RuZyBraeG7g20gc2/DoXQgxJHGsOG7o2MgdOG7lW5nIHPhu5EgbeG6q3UgKG4pLg0KDQojIyMgKio1LjIuMi4gUGjDom4gcGjhu5FpIE11bHRpbm9taWFsKioNCg0KVHJvbmcgdHLGsOG7nW5nIGjhu6NwIHThu5VuZyBz4buRIHF1YW4gc8OhdCBcKCBuIFwpIGzDoCBj4buRIMSR4buLbmgsIHbDoCBt4buXaSBxdWFuIHPDoXQgcsahaSB2w6BvIG3hu5l0IHRyb25nIGLhu5FuIMO0IHbhu5tpIHjDoWMgc3XhuqV0IFwoIHBfMSwgcF8yLCBwXzMsIHBfNCBcKSwgdGjDrCBi4bqjbmcgbmfhuqt1IG5oacOqbiAyeDIgY8OzIHRo4buDIMSRxrDhu6NjIG3DtCBow6xuaCBow7NhIHRoZW8gcGjDom4gcGjhu5FpIMSRYSB0aOG7qWMgTXVsdGlub21pYWwgbmjGsCBzYXU6DQoNClxbDQooYSwgYiwgYywgZCkgXHNpbSBcdGV4dHtNdWx0aW5vbWlhbH0objsgcF8xLCBwXzIsIHBfMywgcF80KQ0KXF0NCg0KUGjDom4gcGjhu5FpIG7DoHkgdGjGsOG7nW5nIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIGPDoWMgdMOsbmggaHXhu5FuZyBtw6AgZOG7ryBsaeG7h3UgxJHGsOG7o2MgdGh1IHRo4bqtcCB04burIGto4bqjbyBzw6F0IGhv4bq3YyBuZ2hpw6puIGPhu6l1IHjDoyBo4buZaSBo4buNYyB24bubaSBrw61jaCB0aMaw4bubYyBt4bqrdSBj4buRIMSR4buLbmguIEtoaSDEkcOzLCBjw6FjIHjDoWMgc3XhuqV0IFwoIHBfMSwgcF8yLCBwXzMsIHBfNCBcKSBiaeG7g3UgZGnhu4VuIHjDoWMgc3XhuqV0IG3DoCBt4buZdCBjw6EgdGjhu4MgcsahaSB2w6BvIHThu6tuZyDDtCB0cm9uZyBi4bqjbmcgMngyLg0KDQoqKsavdSDEkWnhu4NtIGPhu6dhIG3DtCBow6xuaCBNdWx0aW5vbWlhbDoqKg0KDQotIEtp4buDbSBzb8OhdCDEkcaw4bujYyB04buVbmcgc+G7kSBt4bqrdS4NCg0KLSBQaMO5IGjhu6NwIGNobyBk4buvIGxp4buHdSBraOG6o28gc8OhdCwgdGjhu60gbmdoaeG7h20uDQoNCioqU28gc8OhbmggZ2nhu69hIHBow6JuIHBo4buRaSBQb2lzc29uIHbDoCBNdWx0aW5vbWlhbCoqDQoNCnwgVGnDqnUgY2jDrSAgICAgICAgIHwgUG9pc3NvbiAgICAgICAgICAgICAgICAgIHwgTXVsdGlub21pYWwgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwNCnwgVOG7lW5nIHPhu5EgbeG6q3UgICAgICB8IEtow7RuZyBj4buRIMSR4buLbmggICAgICAgICAgICAgfCBD4buRIMSR4buLbmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCDhu6huZyBk4bulbmcgY2jDrW5oICAgfCBT4buRIHPhu7Ega2nhu4duICAgICAgICAgICAgICAgIHwgVOG6p24gc3XhuqV0IGto4bqjbyBzw6F0ICAgICAgICAgICAgICAgICAgICAgfA0KfCBE4buvIGxp4buHdSBwaMO5IGjhu6NwICB8IEdpYW8gZOG7i2NoLCBs4buXaSwgdGFpIG7huqFuICAgfCBUcuG6oyBs4budaSBraOG6o28gc8OhdCwgcGjDom4gbmjDs20gICAgICAgICAgfA0KDQojIyAqKjUuMy4gQ8OhYyBjaOG7iSBz4buRIMSRbyBt4buRaSBsacOqbiBo4buHKioNCg0KIyMjICoqNS4zLjEuICBIaeG7h3UgdOG7tyBs4buHIChSaXNrIERpZmZlcmVuY2UgLSBSRCkqKg0KDQpcWw0KUkQgPSBcZnJhY3thfXthICsgYn0gLSBcZnJhY3tjfXtjICsgZH0NClxdDQoNCioqw50gbmdoxKlhKio6DQoNCi0gxJBvIGzGsOG7nW5nICoqY2jDqm5oIGzhu4djaCB0dXnhu4d0IMSR4buRaSoqIGdp4buvYSB4w6FjIHN14bqldCB44bqjeSByYSBr4bq/dCBxdeG6oyDhu58gbmjDs20gcGjGoWkgbmhp4buFbSB2w6AgbmjDs20ga2jDtG5nIHBoxqFpIG5oaeG7hW0uDQoNCi0gVGjGsOG7nW5nIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIMSRw6FuaCBnacOhICoqdMOhYyDEkeG7mW5nIGPhu6dhIGNow61uaCBzw6FjaCoqLCBjYW4gdGhp4buHcCBob+G6t2MgY2jGsMahbmcgdHLDrG5oIHRow60gxJFp4buDbSwga2hpIHPhu7Ega2jDoWMgYmnhu4d0IHbhu4EgeMOhYyBzdeG6pXQgbMOgIHF1YW4gdHLhu41uZyBoxqFuIHNvIHbhu5tpIHThu7cgc+G7kS4NCg0KS2hv4bqjbmcgdGluIGPhuq15IDk1JSAoQ0kpIGNobyBSRCBjw7MgdGjhu4MgxJHGsOG7o2MgxrDhu5tjIGzGsOG7o25nIGLhurFuZzoNCg0KXFsNCkNJX3tSRH0gPSBSRCBccG0gWl97MSAtIFxhbHBoYS8yfSBcY2RvdCBTRV97UkR9DQpcXQ0KDQpUcm9uZyDEkcOzOg0KLSBcKCBaX3sxIC0gXGFscGhhLzJ9IFwpIGzDoCBnacOhIHRy4buLIHThu5tpIGjhuqFuICh0aMaw4budbmcg4omIIDEuOTYgduG7m2kgOTUlIENJKSwNCg0KLSBcKCBTRV97UkR9ID0gXHNxcnR7XGZyYWN7YShhK2ItYSl9eyhhK2IpXjN9ICsgXGZyYWN7YyhjK2QtYyl9eyhjK2QpXjN9fSBcKQ0KDQojIyMgKio1LjMuMi4gIFThu7cgc+G7kSBuZ3V5IGPGoSAoUmVsYXRpdmUgUmlzayAtIFJSKSoqDQoNClxbDQpSUiA9IFxmcmFje2EgLyAoYSArIGIpfXtjIC8gKGMgKyBkKX0NClxdDQoNCioqw50gbmdoxKlhKio6DQoNCi0gXCggUlIgPiAxIFwpOiBuZ3V5IGPGoSB44bqjeSByYSBr4bq/dCBxdeG6oyBjYW8gaMahbiDhu58gbmjDs20gcGjGoWkgbmhp4buFbS4NCg0KLSBcKCBSUiA8IDEgXCk6IG5ndXkgY8ahIHjhuqN5IHJhIGvhur90IHF14bqjIHRo4bqlcCBoxqFuIOG7nyBuaMOzbSBwaMahaSBuaGnhu4VtLg0KDQotIFwoIFJSID0gMSBcKToga2jDtG5nIGPDsyBt4buRaSBsacOqbiBo4buHIGdp4buvYSBwaMahaSBuaGnhu4VtIHbDoCBr4bq/dCBxdeG6oy4NCg0KVGEgdGjGsOG7nW5nIGzhuqV5ICoqbG9nKiogY+G7p2EgUlIgxJHhu4MgdMOtbmgga2hv4bqjbmcgdGluIGPhuq15Og0KDQpcWw0KQ0lfe1JSfSA9IFxleHAgXGxlZnRbIFxsbihSUikgXHBtIFpfezEgLSBcYWxwaGEvMn0gXGNkb3QgU0Vfe1xsbihSUil9IFxyaWdodF0NClxdDQoNClRyb25nIMSRw7M6DQoNClxbDQpTRV97XGxuKFJSKX0gPSBcc3FydHsgXGZyYWN7MX17YX0gLSBcZnJhY3sxfXthICsgYn0gKyBcZnJhY3sxfXtjfSAtIFxmcmFjezF9e2MgKyBkfSB9DQpcXQ0KDQoqKlbDrSBk4bulIHRyb25nIGtpbmggZG9hbmgqKjoNCg0KLSBU4bu3IGzhu4cga2jDoWNoIG11YSBow6BuZyBraGkgY8OzIGtodXnhur9uIG3Do2k6IFwoIDgwLzEwMCA9IDAuOCBcKQ0KDQotIEtoaSBraMO0bmcgY8OzIGtodXnhur9uIG3Do2k6IFwoIDQwLzEwMCA9IDAuNCBcKQ0KDQotIFwoIFJSID0gMC44IC8gMC40ID0gMiBcKQ0KDQrih5IgS2h1eeG6v24gbcOjaSBsw6BtIHTEg25nIGfhuqVwICoqxJHDtGkqKiBraOG6oyBuxINuZyBraMOhY2ggbXVhIGjDoG5nLg0KDQpI4bqhbiBjaOG6vzoNCg0K4pqg77iPIEtow7RuZyBz4butIGThu6VuZyDEkcaw4bujYyB0cm9uZyBuZ2hpw6puIGPhu6l1IGLhu4duaCBjaOG7qW5nIChjYXNlLWNvbnRyb2wpIHbDrCB0YSBraMO0bmcgYmnhur90IG5ndXkgY8ahIHR1eeG7h3QgxJHhu5FpLg0KDQrimqDvuI8gROG7hSBnw6J5IGhp4buDdSBuaOG6p20gbuG6v3Uga2jDtG5nIMSRaSBrw6htIG5ndXkgY8ahIHR1eeG7h3QgxJHhu5FpLiBWw60gZOG7pTogUlIgPSAyIGPDsyB24bq7IGNhbywgbmjGsG5nIG7hur91IG5ndXkgY8ahIGJhbiDEkeG6p3UgbMOgIDElLCB0aMOsIHTEg25nIGzDqm4gMiUgduG6q24gbMOgIHLhuqV0IHRo4bqlcC4NCg0K4pqg77iPIEtow7RuZyDEkeG7kWkgeOG7qW5nOiBO4bq/dSDEkeG7lWkgbmjDs20gdGhhbSBjaGnhur91IHRow6wgZ2nDoSB0cuG7iyBSUiB0aGF5IMSR4buVaSwga2jDoWMgduG7m2kgT1IuDQoNCiMjIyAqKjUuMy4zLiAgVOG7tyBz4buRIGNow6puaCAoT2RkcyBSYXRpbyAtIE9SKSoqDQoNCiMjIyMgKio1LjMuMy4xLiBPZGRzKioNCg0KLSAqKk9kZHMgKHThu7cgc+G7kSBjxqEgaOG7mWkpKio6ICANCiAgXFsNCiAgXHRleHR7T2Rkc30gPSBcZnJhY3twfXsxIC0gcH0NCiAgXF0NCiAgVHJvbmcgxJHDsywgXChwXCkgbMOgIHjDoWMgc3XhuqV0IHjhuqN5IHJhIGPhu6dhIG3hu5l0IGJp4bq/biBuaOG7iyBwaMOibiAobmjGsCB2aeG7h2Mgc+G7nyBo4buvdSBuaMOgKS4NCiAgDQojIyMjICoqNS4zLjMuMS4gT2RkcyBSYXRpbyAtIE9SKioNCg0KXFsNCk9SID0gXGZyYWN7YSAvIGJ9e2MgLyBkfSA9IFxmcmFje2FkfXtiY30NClxdDQoNCkhheSAgDQoNClxbDQogIFx0ZXh0e09SfSA9IFxmcmFje1x0ZXh0e09kZHMg4bufIG5ow7NtIDF9fXtcdGV4dHtPZGRzIOG7nyBuaMOzbSAyfX0NClxdDQogIE9SIHRoxrDhu51uZyBkw7luZyDEkeG7gyDEkW8gbMaw4budbmcgbeG7kWkgbGnDqm4gaOG7hyBnaeG7r2EgbeG7mXQgeeG6v3UgdOG7kSB2w6AgbeG7mXQga+G6v3QgcXXhuqMgdHJvbmcgYuG6o25nIDJ4Mi4NCiAgDQotICoqT1IgPSAxKio6IEtow7RuZyBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgduG7gSBvZGRzIGdp4buvYSBoYWkgbmjDs20uICANCg0KLSAqKk9SID4gMSoqOiBOaMOzbSAxIGPDsyBvZGRzIHjhuqN5IHJhIGvhur90IHF14bqjIGNhbyBoxqFuIG5ow7NtIDIuICANCg0KLSAqKk9SIDwgMSoqOiBOaMOzbSAxIGPDsyBvZGRzIHjhuqN5IHJhIGvhur90IHF14bqjIHRo4bqlcCBoxqFuIG5ow7NtIDIuDQoNCj4gVsOtIGThu6U6IE9SID0gMiBuZ2jEqWEgbMOgICoqb2RkcyB44bqjeSByYSBr4bq/dCBxdeG6oyDhu58gbmjDs20gMSBjYW8gZ+G6pXAgMiBs4bqnbiBuaMOzbSAyKiouDQoNCi0gKipMxrB1IMO9Kio6IE9SIGtow6FjIHbhu5tpIFJSLCDEkeG6t2MgYmnhu4d0IGtoaSBiaeG6v24gcGjhu6UgdGh14buZYyBraMO0bmcgaGnhur9tIGfhurdwLiBLaGkga+G6v3QgcXXhuqMgbMOgIGhp4bq/bSAocCBuaOG7jyksIHRow6wgT1Ig4omIIFJSLg0KDQoqKsOdIG5naMSpYSoqOg0KDQotIE9SIGNobyBiaeG6v3QgdOG7tyBs4buHICoqb2RkcyoqICh04bupYyBsw6AgInjDoWMgc3XhuqV0IGNoaWEgY2hvIDEgdHLhu6sgeMOhYyBzdeG6pXQiKSBnaeG7r2EgaGFpIG5ow7NtLg0KDQotIFRoxrDhu51uZyDEkcaw4bujYyBz4butIGThu6VuZyBwaOG7lSBiaeG6v24gdHJvbmcgbcO0IGjDrG5oICoqbG9naXN0aWMgcmVncmVzc2lvbioqLg0KDQotIFRyb25nIGPDoWMgbmdoacOqbiBj4bupdSBi4buHbmggaGnhur9tIChyYXJlIGRpc2Vhc2UgYXNzdW1wdGlvbiksIE9SIHjhuqVwIHjhu4kgduG7m2kgUlIuDQoNCioqxq91IMSRaeG7g20gY+G7p2EgT2RkcyBSYXRpbyoqOg0KDQotIEThu4UgdMOtbmggdsOgIGThu4UgZGnhu4VuIGdp4bqjaS4NCg0KLSDhu5RuIMSR4buLbmggduG7gSBt4bq3dCB0b8OhbiBo4buNYyBraGkgc+G7rSBk4bulbmcgdHJvbmcgY8OhYyBtw7QgaMOsbmggaOG7k2kgcXV5Lg0KDQotIEtow7RuZyBwaOG7pSB0aHXhu5ljIHbDoG8gdOG7tyBs4buHIGhp4buHbiBkaeG7h24gdHJvbmcgbeG6q3UgKMSR4bq3YyBiaeG7h3QgdHJvbmcgY8OhYyB0aGnhur90IGvhur8gKipi4buHbmgg4oCTIGNo4bupbmcqKjogKmNhc2UtY29udHJvbCBzdHVkeSopLg0KDQojIyAqKjUuNC4gS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIHRpbiBj4bqteSBjaG8gT0REUyBSQVRJTyoqDQoNCsSQ4buDIHjDoWMgxJHhu4tuaCB4ZW0gT1IgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBoYXkga2jDtG5nLCBj4bqnbiB4w6J5IGThu7FuZyBraG/huqNuZyB0aW4gY+G6rXkuDQoNCioqTG9nYXJpdGhtIHThu7Egbmhpw6puIGPhu6dhIE9kZHMgUmF0aW86KioNCg0KXFsNClxsb2coT1IpID0gXGxvZ1xsZWZ0KCBcZnJhY3thIFxjZG90IGR9e2IgXGNkb3QgY30gXHJpZ2h0KQ0KXF0NCg0KKipTYWkgc+G7kSBjaHXhuqluIChTdGFuZGFyZCBFcnJvcik6KioNCg0KXFsNClNFID0gXHNxcnR7IFxmcmFjezF9e2F9ICsgXGZyYWN7MX17Yn0gKyBcZnJhY3sxfXtjfSArIFxmcmFjezF9e2R9IH0NClxdDQoNCioqS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gXChcbG9nKE9SKVwpOioqDQoNClxbDQpcbG9nKE9SKSBccG0gMS45NiBcY2RvdCBTRQ0KXF0NCg0KKipM4bqleSBtxakgxJHhu4MgY8OzIGtob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIE9SOioqDQoNClxbDQpDSV97OTVcJX0gPSBcbGVmdFsgZV57XGxvZyhPUikgLSAxLjk2IFxjZG90IFNFfSxccXVhZCBlXntcbG9nKE9SKSArIDEuOTYgXGNkb3QgU0V9IFxyaWdodF0NClxdDQoNCi0gTuG6v3Uga2hv4bqjbmcgdGluIGPhuq15ICoqa2jDtG5nIGNo4bupYSAxKiosIHRhIGPDsyB0aOG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nICoqbeG7kWkgbGnDqm4gaOG7hyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqKiog4bufIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KIyMgKio1LjUuIOG7qG5nIGThu6VuZyB0cm9uZyBraW5oIGRvYW5oOiBISeG7hlUgUVXhuqIgQ+G7pkEgS0hVWeG6vk4gTcODSSoqDQoNCk3hu5l0IGPDtG5nIHR5IHRoxrDGoW5nIG3huqFpIMSRaeG7h24gdOG7rSB0aOG7rSBuZ2hp4buHbSBjaGnhur9uIGThu4tjaCBraHV54bq/biBtw6NpIMSR4buDIGtp4buDbSB0cmEgeGVtIGxp4buHdSBjw7Mg4bqjbmggaMaw4bufbmcgxJHhur9uIGjDoG5oIHZpIG11YSBow6BuZyBraMO0bmcuIEjhu40gbOG6pXkgbeG6q3UgMjAwIGtow6FjaCBow6BuZyBuZ+G6q3Ugbmhpw6puIHbDoCB0aHUgxJHGsOG7o2MgYuG6o25nIHNhdToNCg0KfCAgICAgICAgICAgICAgICAgIHwgTXVhIGjDoG5nIHwgS2jDtG5nIG11YSB8IFThu5VuZyB8DQp8LS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS18LS0tLS0tLS0tLS0tfC0tLS0tLS18DQp8IEPDsyBraHV54bq/biBtw6NpICAgIHwgODAgICAgICAgfCAyMCAgICAgICAgIHwgMTAwICAgfA0KfCBLaMO0bmcga2h1eeG6v24gbcOjaSB8IDQwICAgICAgIHwgNjAgICAgICAgICB8IDEwMCAgIHwNCg0KLSBUw61uaCBPZGRzIFJhdGlvIChPUik6DQoNClxbDQpPUiA9IFxmcmFjezgwIFxjZG90IDYwfXsyMCBcY2RvdCA0MH0gPSBcZnJhY3s0ODAwfXs4MDB9ID0gNg0KXF0NCg0K4oaSIE9kZHMgbXVhIGjDoG5nIGtoaSBjw7Mga2h1eeG6v24gbcOjaSAqKmNhbyBn4bqlcCA2IGzhuqduKiogc28gduG7m2kga2hpIGtow7RuZyBjw7Mga2h1eeG6v24gbcOjaS4NCg0KLSBMb2dhcml0aG0gdOG7sSBuaGnDqm4gY+G7p2EgT1I6DQoNClxbDQpcbG9nKE9SKSA9IFxsb2coNikgXGFwcHJveCAxLjc5DQpcXQ0KDQotIFNhaSBz4buRIGNodeG6qW4gKFNFKToNCg0KXFsNClNFID0gXHNxcnR7IFxmcmFjezF9ezgwfSArIFxmcmFjezF9ezIwfSArIFxmcmFjezF9ezQwfSArIFxmcmFjezF9ezYwfSB9IFxhcHByb3ggMC4zNQ0KXF0NCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyBPUjoNCg0KXFsNCkNJID0gXGxlZnRbIGVeezEuNzkgLSAxLjk2IFxjZG90IDAuMzV9LFxxdWFkIGVeezEuNzkgKyAxLjk2IFxjZG90IDAuMzV9IFxyaWdodF0gDQpcYXBwcm94IFxsZWZ0WyBlXnsxLjExfSxccXVhZCBlXnsyLjQ3fSBccmlnaHRdIA0KPSBbMy4wMyxcIDExLjgxXQ0KXF0NCg0KLSBWw6wga2hv4bqjbmcgdGluIGPhuq15ICoqa2jDtG5nIGNo4bupYSAxKiosIGPDsyB0aOG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nICoqa2h1eeG6v24gbcOjaSBjw7Mg4bqjbmggaMaw4bufbmcgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqioqIMSR4bq/biBow6BuaCB2aSBtdWEgaMOgbmcuDQoNCi0gVuG7m2kgXCggT1IgPSA2IFwpIHbDoCBcKCBDSSA9ICgzLjAzLFwgMTEuODEpIFwpLCBkb2FuaCBuZ2hp4buHcCBjw7MgdGjhu4MgdOG7sSB0aW4gdHJp4buDbiBraGFpICoqY2hp4bq/biBsxrDhu6NjIGtodXnhur9uIG3Do2kgcXV5IG3DtCBs4bubbiBoxqFuKiouDQoNCiMgKipQaOG6p24gNi4gU08gU8OBTkggMiBU4bu2IEzhu4YgVsOAIFRIxq/hu5pDIMSQTyBN4buQSSBMScOKTiBI4buGOioqDQoNCiMjICoqNi4xLiBIaeG7h3UgaGFpIHThu7cgbOG7hyAoRGlmZmVyZW5jZSBpbiBQcm9wb3J0aW9ucyk6KioNCg0KIyMjICoqNi4xLjEuIELhuqNuZyBjaMOpbyAyeDIgZ2nhu69hIEdlbmRlciB2w6AgSG9tZW93bmVyOioqDQoNCmBgYHtyfQ0KIyBC4bqjbmcgY2jDqW8gZ2nhu69hIEdlbmRlciB2w6AgSG9tZW93bmVyDQpnaCA8LSB0YWJsZShkdCRHZW5kZXIsIGR0JEhvbWVvd25lcikNCmFkZG1hcmdpbnMoZ2gpDQoNCmBgYA0KDQpcWw0KcF8xID0gUChcdGV4dHtIb21lb3duZXJ9ID0gWSBcbWlkIFx0ZXh0e0dlbmRlcn0gPSBGKSBccXVhZCBcdGV4dHsodOG7tyBs4buHIG7hu68gc+G7nyBo4buvdSBuaMOgKX0NClxdDQoNClxbDQpwXzIgPSBQKFx0ZXh0e0hvbWVvd25lcn0gPSBZIFxtaWQgXHRleHR7R2VuZGVyfSA9IE0pIFxxdWFkIFx0ZXh0eyh04bu3IGzhu4cgbmFtIHPhu58gaOG7r3UgbmjDoCl9DQpcXQ0KDQpUw61uaCBoaeG7h3UgaGFpIHThu7cgbOG7hzoNCg0KXFsNCmQgPSBwXzEgLSBwXzINClxdDQoNCg0KS2nhu4NtIMSR4buLbmg6DQoNCkjigoA6IHDigoEgLSBw4oKCID0gMCAodOG7tyBs4buHIG7hu68gc+G7nyBo4buvdSBuaMOgIGLhurFuZyB04bu3IGzhu4cgbmFtIHPhu58gaOG7r3UgbmjDoCkNCg0KSOKCgTogcOKCgSAtIHDigoIgPCAwIChU4bu3IGzhu4cgbuG7ryBz4bufIGjhu691IG5ow6Agbmjhu48gaMahbiB04bu3IGzhu4cgbmFtIHPhu58gaOG7r3UgbmjDoCApDQoNCmBgYHtyfQ0KY291bnRzIDwtIGMoZ2hbIkYiLCAiWSJdLCBnaFsiTSIsICJZIl0pICAgIyBT4buRIG5nxrDhu51pIHPhu58gaOG7r3UgbmjDoCB0aGVvIHThu6tuZyBnaeG7m2kgdMOtbmgNCnRvdGFscyA8LSBjKHN1bShnaFsiRiIsIF0pLCBzdW0oZ2hbIk0iLCBdKSkgICMgVOG7lW5nIHPhu5EgbmfGsOG7nWkgdGhlbyB04burbmcgZ2nhu5tpIHTDrW5oDQoNCnRlc3QgPC0gcHJvcC50ZXN0KGNvdW50cywgdG90YWxzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIiwgY29ycmVjdCA9IEZBTFNFKQ0KdGVzdA0KYGBgDQoNCi0gcHJvcCAxIChwMSkgPSAwLjYwNTk6IHThu7cgbOG7hyBu4buvIHPhu58gaOG7r3UgbmjDoCBraG/huqNuZyA2MC41OSUNCg0KLSBwcm9wIDIgKHAyKSA9IDAuNTk1MjogdOG7tyBs4buHIG5hbSBz4bufIGjhu691IG5ow6Aga2hv4bqjbmcgNTkuNTIlDQoNCi0gUC12YWx1ZSA9IDAuOTAyNSANCg0KR2nDoSB0cuG7iyBwLXZhbHVlIHRodSDEkcaw4bujYyBsw6AgMC45MDI1LCBs4bubbiBoxqFuIG3hu6ljIMO9IG5naMSpYSAwLjA1LiBEbyDEkcOzLCBjaMO6bmcgdGEgKipraMO0bmcgxJHhu6cgYuG6sW5nIGNo4bupbmcgxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAgXChIXzA6IHBfMSAtIHBfMiA9IDBcKSoqLiANCg0KxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgLCB0aGVvIGThu68gbGnhu4d1IGhp4buHbiB04bqhaSwga2jDtG5nIGPDsyBz4buxIGtow6FjIGJp4buHdCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIGdp4buvYSB04bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIGPhu6dhIG7hu68gdsOgIG5hbSwgdsOgIGtow7RuZyBjw7MgYuG6sW5nIGNo4bupbmcgY2hvIHRo4bqleSB04bu3IGzhu4cgbuG7ryBz4bufIGjhu691IG5ow6AgdGjhuqVwIGjGoW4gdOG7tyBs4buHIG5hbS4NCg0KIyMjICoqNi4xLjIuIELhuqNuZyBjaMOpbyAyeDIgZ2nhu69hIE1hcml0YWxTdGF0dXMgdsOgIEhvbWVvd25lcjoqKg0KDQpgYGB7cn0NCm1oIDwtIHRhYmxlKGR0JE1hcml0YWxTdGF0dXMsIGR0JEhvbWVvd25lcikNCm1oMSA8LSBhZGRtYXJnaW5zKG1oKQ0KcHJpbnQobWgxKQ0KYGBgDQoNCkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oOg0KDQpcWw0KSF8wOiBwXzEgLSBwXzIgPSAwIFxxdWFkIFx0ZXh0eyh04bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIGPhu6dhIG5ow7NtIMSQw6Mga+G6v3QgaMO0biBi4bqxbmcgbmjDs20gxJDhu5ljIHRow6JuKX0NClxdDQoNClxbDQpIXzE6IHBfMSAtIHBfMiA+IDAgXHF1YWQgXHRleHR7KHThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgY+G7p2EgbmjDs20gxJDDoyBr4bq/dCBow7RuIGNhbyBoxqFuIG5ow7NtIMSQ4buZYyB0aMOibil9DQpcXQ0KDQpUcm9uZyDEkcOzOiAgDQotIFwocF8xID0gUChcdGV4dHtIb21lb3duZXJ9ID0gWSBcbWlkIFx0ZXh0e01hcml0YWxTdGF0dXN9ID0gTSlcKSBsw6AgdOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCBj4bunYSBuaMOzbSAqKsSQw6Mga+G6v3QgaMO0biAoTWFycmllZCwgTSkqKi4gIA0KLSBcKHBfMiA9IFAoXHRleHR7SG9tZW93bmVyfSA9IFkgXG1pZCBcdGV4dHtNYXJpdGFsU3RhdHVzfSA9IFMpXCkgbMOgIHThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgY+G7p2EgbmjDs20gKirEkOG7mWMgdGjDom4gKFNpbmdsZSwgUykqKi4NCg0KYGBge3J9DQpjb3VudHMxIDwtIGMobWhbIk0iLCAiWSJdLCBtaFsiUyIsICJZIl0pDQp0b3RhbHMxIDwtIGMoc3VtKG1oWyJNIiwgXSksIHN1bShtaFsiUyIsIF0pKQ0KDQp0ZXN0MSA8LSBwcm9wLnRlc3QoY291bnRzMSwgdG90YWxzMSwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIsIGNvcnJlY3QgPSBGQUxTRSkNCnRlc3QxDQpgYGANCg0KLSBwcm9wIDEgPSAwLjc0OTY6IHThu7cgbOG7hyBz4bufIGjhu691IG5ow6AgY+G7p2EgbmjDs20gxJDDoyBr4bq/dCBow7RuIChNKSBsw6Aga2hv4bqjbmcgNzQuOTYlDQoNCi0gcHJvcCAyID0gMC40NTg0OiB04bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIGPhu6dhIG5ow7NtIMSQ4buZYyB0aMOibiAoUykgbMOgIGtob+G6o25nIDQ1Ljg0JQ0KDQotIEdpw6EgdHLhu4sgcC12YWx1ZSBy4bqldCBuaOG7jyAoPCAyLjJlLTE2KSwgbmjhu48gaMahbiBt4bupYyDDvSBuZ2jEqWEgMC4wNSwgY2hvIHRo4bqleSBjw7MgYuG6sW5nIGNo4bupbmcgdGjhu5FuZyBrw6ogbeG6oW5oIG3hur0gxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLiBW4bqteSB04bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIGPhu6dhIG5ow7NtIMSRw6Mga+G6v3QgaMO0biBuaGnhu4F1IGjGoW4gY+G7p2EgbmjDs20gxJHhu5ljIHRow6JuLg0KDQojIyMgKio2LjEuMy4gQuG6o25nIGNow6lvIDJ4MiBnaeG7r2EgR2VuZGVyIHbDoCBNYXJpdGFsU3RhdHVzOioqDQoNCmBgYHtyfQ0KIyAxLiBM4bqtcCBi4bqjbmcgY2jDqW8gMngyIGdp4buvYSBHZW5kZXIgdsOgIE1hcml0YWxTdGF0dXMNCmdtIDwtIHRhYmxlKGR0JEdlbmRlciwgZHQkTWFyaXRhbFN0YXR1cykNCmFkZG1hcmdpbnMoZ20pICAjIFRow6ptIGjDoG5nIHbDoCBj4buZdCB04buVbmcNCmBgYA0KDQpHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaA0KDQpcWw0KSF8wOiBwXzEgLSBwXzIgPSAwIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgxJHDoyBr4bq/dCBow7RuIGPhu6dhIG7hu68gYuG6sW5nIG5hbSl9DQpcXQ0KDQpcWw0KSF8xOiBwXzEgLSBwXzIgPiAwIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgxJHDoyBr4bq/dCBow7RuIGPhu6dhIG7hu68gbOG7m24gaMahbiBuYW0pfQ0KXF0NCg0KVHJvbmcgxJHDszoNCi0gXChwXzEgPSBQKFx0ZXh0e01hcml0YWxTdGF0dXN9ID0gTSBcbWlkIFx0ZXh0e0dlbmRlcn0gPSBGKVwpOiB04bu3IGzhu4cgKipu4buvKiogxJHDoyBr4bq/dCBow7RuICANCg0KLSBcKHBfMiA9IFAoXHRleHR7TWFyaXRhbFN0YXR1c30gPSBNIFxtaWQgXHRleHR7R2VuZGVyfSA9IE0pXCk6IHThu7cgbOG7hyAqKm5hbSoqIMSRw6Mga+G6v3QgaMO0biAgDQoNCmBgYHtyfQ0KIyBUcsOtY2ggc+G7kSBsxrDhu6NuZyBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gdGhlbyBnaeG7m2kNCmNvdW50czMgPC0gYyhnbVsiRiIsICJNIl0sIGdtWyJNIiwgIk0iXSkNCnRvdGFsczMgPC0gYyhzdW0oZ21bIkYiLCBdKSwgc3VtKGdtWyJNIiwgXSkpDQoNCiMgVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBoaeG7h3UgaGFpIHThu7cgbOG7hw0KdGVzdDMgPC0gcHJvcC50ZXN0KGNvdW50czMsIHRvdGFsczMsIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiLCBjb3JyZWN0ID0gRkFMU0UpDQp0ZXN0Mw0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIGNobyB0aOG6pXk6DQoNCi0gVOG7tyBs4buHIG7hu68gxJHDoyBr4bq/dCBow7RuIChcKHBfMVwpKSDiiYggNTAuMjQlIA0KDQotIFThu7cgbOG7hyBuYW0gxJHDoyBr4bq/dCBow7RuIChcKHBfMlwpKSDiiYggNDcuMzglIA0KDQotIEhp4buHdSBoYWkgdOG7tyBs4buHOiBcKGQgPSBwXzEgLSBwXzIgXGFwcHJveCAwLjAyODZcKSANCg0KLSBHacOhIHRy4buLIHAtdmFsdWUgPSAwLjAwMDM1ICANCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyBoaeG7h3UgdOG7tyBs4buHOiBbMC4wMTQ3OyAxXQ0KDQpWw6wgKipwLXZhbHVlIDwgMC4wNSoqLCB0YSAqKmLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBcKEhfMFwpKiouIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGPDsyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nOiAqKlThu7cgbOG7hyBu4buvIMSRw6Mga+G6v3QgaMO0biBjYW8gaMahbiB04bu3IGzhu4cgbmFtIMSRw6Mga+G6v3QgaMO0bioqIHRyb25nIHThuq1wIGThu68gbGnhu4d1IGto4bqjbyBzw6F0Lg0KDQojIyAqKjYuMi4gVOG7tyBz4buRIE5ndXkgY8ahIChSZWxhdGl2ZSBSaXNrIC0gUlIpOioqDQoNCiMjIyAqKjYuMi4xLiBC4bqjbmcgY2jDqW8gMngyIGdp4buvYSBHZW5kZXIgdsOgIEhvbWVvd25lcjoqKg0KDQpgYGB7cn0NCmdoIDwtIHRhYmxlKGR0JEdlbmRlciwgZHQkSG9tZW93bmVyKQ0KI1Row6ptIHThu5VuZyBow6BuZyB2w6AgY+G7mXQNCmdoMSA8LSBhZGRtYXJnaW5zKGdoKQ0KZ2gxDQpgYGANCg0KYGBge3J9DQpyaXNrcmF0aW8oZ2gsIG1ldGhvZD0id2FsZCIpDQpgYGANCg0KLSBOaMOzbSBu4buvIChGKSDEkcaw4bujYyBjaOG7jW4gbMOgbSBuaMOzbSB0aGFtIGNoaeG6v3UsIG7Dqm4gUlIgPSAxLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBjaMO6bmcgdGEgc28gc8Ohbmggbmd1eSBjxqEgc+G7nyBo4buvdSBuaMOgIGPhu6dhIG5ow7NtIG5hbSAoTSkgduG7m2kgbmjDs20gbuG7ry4NCg0KLSBOaMOzbSBuYW0gKE0pIGPDsyBSUiA9IDAuOTgyMyBuZ2jEqWEgbMOgOg0KDQogIC0gVOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCDhu58gbmFtIGLhurFuZyBraG/huqNuZyA5OC4yMyUgc28gduG7m2kgbuG7ry4NCg0KYCAtIEhheSBuw7NpIGPDoWNoIGtow6FjLCBuZ3V5IGPGoSAoeMOhYyBzdeG6pXQpIHPhu58gaOG7r3UgbmjDoCBj4bunYSBuYW0gdGjhuqVwIGjGoW4gbuG7ryBraG/huqNuZyAxLjc3JS4NCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGPhu6dhIFJSIGzDoCAoMC45NTYyIOKAkyAxLjAwOTIpOg0KDQogIC0gS2hv4bqjbmcgbsOgeSBiYW8gZ+G7k20gc+G7kSAxLCBuZ2jEqWEgbMOgIGdpw6EgdHLhu4sgUlIgdGjhu7FjIHPhu7EgY8OzIHRo4buDIGzDoCAxIChraMO0bmcgY8OzIGtow6FjIGJp4buHdCkuDQoNCiAgLSBLaG/huqNuZyB0aW4gY+G6rXkgY2hvIHRhIGJp4bq/dCBt4bupYyDEkeG7mSBjaMOtbmggeMOhYyBj4bunYSDGsOG7m2MgbMaw4bujbmcgUlI7IGtob+G6o25nIHLhu5luZyB2w6AgYmFvIGfhu5NtIDEgY2hvIHRo4bqleSBz4buxIGtow7RuZyBjaOG6r2MgY2jhuq9uIHbDoCB0aGnhur91IGLhurFuZyBjaOG7qW5nIHbhu4Egc+G7sSBraMOhYyBiaeG7h3QgdGjhu7FjIHPhu7EuDQoNClRhIGPDsyBnaeG6oyB0aHV54bq/dDoNCg0KSOKCgDogVOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCDhu58gTmFtIHbDoCBO4buvIGtow7RuZyBraMOhYyBuaGF1LCB04bupYyBsw6AgUlIgPSAxLg0KDQpI4oKBOiBU4bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIOG7nyBOYW0gdsOgIE7hu68ga2jDoWMgbmhhdSwgUlIg4omgIDEuDQoNCg0KfCBLaeG7g20gxJHhu4tuaCAgICAgIHwgcC12YWx1ZSAoTmFtIHNvIHbhu5tpIE7hu68pIHwgw50gbmdoxKlhIGNow61uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwNCnwgbWlkcC5leGFjdCAgICAgfCAwLjE5NTIgICAgICAgICAgICAgICAgICB8IHAtdmFsdWUgY2jDrW5oIHjDoWMsIHPhu60gZOG7pW5nIHBoxrDGoW5nIHBow6FwIOKAnG1pZC1w4oCdICht4buZdCBiaeG6v24gdGjhu4MgY2jDrW5oIHjDoWMgaMahbiBGaXNoZXIpIHwNCnwgZmlzaGVyLmV4YWN0ICAgfCAwLjE5NjUgICAgICAgICAgICAgICAgICB8IHAtdmFsdWUgdOG7qyBraeG7g20gxJHhu4tuaCBGaXNoZXIgY2jDrW5oIHjDoWMgKHBow7kgaOG7o3AgduG7m2kgYuG6o25nIG5o4buPIGhv4bq3YyBz4buRIGxp4buHdSDDrXQpIHwNCnwgY2hpLnNxdWFyZSAgICAgfCAwLjE5NTEgICAgICAgICAgICAgICAgICB8IHAtdmFsdWUgdOG7qyBraeG7g20gxJHhu4tuaCBDaGktc3F1YXJlICh44bqlcCB44buJLCBk4buxYSB0csOqbiBwaMOibiBwaOG7kWkgY2hpIGLDrG5oIHBoxrDGoW5nKSB8DQoNClbDrCBwLXZhbHVlID4gMC4wNSwgdGEga2jDtG5nIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBuw7NpIHLhurFuZyBnaeG7m2kgdMOtbmgg4bqjbmggaMaw4bufbmcgxJHDoW5nIGvhu4MgxJHhur9uIGto4bqjIG7Eg25nIHPhu58gaOG7r3UgbmjDoC4NCg0KTsOzaSBjw6FjaCBraMOhYywgc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIG5ow7NtIE5hbSB2w6AgbmjDs20gTuG7ryB24buBIHThu7cgbOG7hyBz4bufIGjhu691IG5ow6Aga2jDtG5nIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCiMjIyAqKjYuMi4yLiBC4bqjbmcgY2jDqW8gMngyIGdp4buvYSBNYXJpdGFsU3RhdHVzIHbDoCBIb21lb3duZXI6KioNCg0KYGBge3J9DQptaCA8LSB0YWJsZShkdCRNYXJpdGFsU3RhdHVzLCBkdCRIb21lb3duZXIpDQptaDEgPC0gYWRkbWFyZ2lucyhtaCkNCnByaW50KG1oMSkNCmBgYA0KDQpgYGB7cn0NCnJpc2tyYXRpbyhtaCkNCmBgYA0KDQpOaMOzbSDEkcOjIGvhur90IGjDtG4gKE0pIMSRxrDhu6NjIGTDuW5nIGzDoG0gbmjDs20gdGhhbSBjaGnhur91IHbhu5tpIFJSID0gMS4NCg0KTmjDs20gxJHhu5ljIHRow6JuIChTKSBjw7M6DQoNCi0gUlIgPSAwLjYxMTQgKGtob+G6o25nIHRpbiBj4bqteSA5NSU6IDAuNTk0MiDigJMgMC42MjkyKS4NCg0KLSDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgbmfGsOG7nWkgxJHhu5ljIHRow6JuIGPDsyBuZ3V5IGPGoSBz4bufIGjhu691IG5ow6AgdGjhuqVwIGjGoW4ga2hv4bqjbmcgMzguODYlIHNvIHbhu5tpIG5nxrDhu51pIMSRw6Mga+G6v3QgaMO0bi4NCg0KLSBLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGtow6EgaOG6uXAgdsOgIGtow7RuZyBiYW8gZ+G7k20gZ2nDoSB0cuG7iyAxLCBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IG7DoHkgbMOgIHLDtSByw6BuZyB2w6AgxJHDoW5nIHRpbiBj4bqteS4NCg0KVGEgdGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCBuaMawIHNhdToNCg0KLSAqKkjigoA6KiogVOG7tyBs4buHIHPhu58gaOG7r3UgbmjDoCBj4bunYSBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gdsOgIMSR4buZYyB0aMOibiBsw6AgbmjGsCBuaGF1IChSUiA9IDEpLg0KDQotICoqSOKCgToqKiBU4bu3IGzhu4cgc+G7nyBo4buvdSBuaMOgIGPhu6dhIGhhaSBuaMOzbSBsw6Aga2jDoWMgbmhhdSAoUlIg4omgIDEpLg0KDQpL4bq/dCBxdeG6oyBwaMOibiB0w61jaCBjaOG7iSByYSBSUiA9IDAuNjExNCB24bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlICgwLjU5NDIg4oCTIDAuNjI5MiksIHbDoCBjw6FjIGtp4buDbSDEkeG7i25oIGNobyBwLXZhbHVlIOKJiCAwIDwgbeG7qWMgw70gbmdoxKlhIDAuMDUuIERvIMSRw7MsIHRhIGLDoWMgYuG7jyBI4oKAIHbDoCBr4bq/dCBsdeG6rW4gcuG6sW5nIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibiBjw7MgbeG7kWkgbGnDqm4gaOG7hyB0aOG7kW5nIGvDqiByw7UgcuG7h3QgduG7m2kga2jhuqMgbsSDbmcgc+G7nyBo4buvdSBuaMOgLiBOZ8aw4budaSDEkeG7mWMgdGjDom4gY8OzIGto4bqjIG7Eg25nIHPhu58gaOG7r3UgbmjDoCB0aOG6pXAgaMahbiDEkcOhbmcga+G7gyBzbyB24bubaSBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4uDQoNCiMjIyAqKjYuMi4zLiBC4bqjbmcgY2jDqW8gMngyIGdp4buvYSBHZW5kZXIgdsOgIE1hcml0YWxTdGF0dXM6KioNCg0KYGBge3J9DQojIDEuIEzhuq1wIGLhuqNuZyBjaMOpbyAyeDIgZ2nhu69hIEdlbmRlciB2w6AgTWFyaXRhbFN0YXR1cw0KZ20gPC0gdGFibGUoZHQkR2VuZGVyLCBkdCRNYXJpdGFsU3RhdHVzKQ0KYWRkbWFyZ2lucyhnbSkgICMgVGjDqm0gaMOgbmcgdsOgIGPhu5l0IHThu5VuZw0KYGBgDQpgYGB7cn0NCiMgMy4gVMOtbmggUlINCnJpc2tyYXRpbyhnbSkNCmBgYA0KDQpOYW0gZ2nhu5tpIGPDsyBuZ3V5IGPGoSDEkcOjIGvhur90IGjDtG4gY2FvIGjGoW4gbuG7ryBnaeG7m2kga2hv4bqjbmcgNS43JS4gVsOsIFJSID4gMSwgxJFp4buBdSBuw6B5IGNobyB0aOG6pXkgdOG7tyBs4buHIGvhur90IGjDtG4g4bufIG5hbSBjYW8gaMahbiBu4buvIHRyb25nIGThu68gbGnhu4d1IG7DoHkuDQoNClbhu5tpIHAtdmFsdWUgPCAwLjA1IHbDoCBraG/huqNuZyB0aW4gY+G6rXkga2jDtG5nIGNo4bupYSAxLCBjaMO6bmcgdGEgY8OzIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIMSR4buDICoqYsOhYyBi4buPIGdp4bqjIHRodXnhur90IGtow7RuZyoqLiAgDQpOaMawIHbhuq15LCAqKm5hbSBnaeG7m2kgY8OzIHThu7cgbOG7hyBr4bq/dCBow7RuIGNhbyBoxqFuIG7hu68gZ2nhu5tpKiogdHJvbmcgYuG7mSBk4buvIGxp4buHdSBuw6B5Lg0KDQojIyAqKjYuMy4gVOG7tyBz4buRIENow6puaCAoT2RkcyBSYXRpbyAtIE9SKTo6KioNCg0KIyMjICoqNi4zLjEuIEdlbmRlciB2w6AgSG9tZW93bmVyOioqDQoNCmBgYHtyfQ0KIyBUw61uaCBPUiB2w6Aga2hv4bqjbmcgdGluIGPhuq15DQpvcl9naCA8LSBPZGRzUmF0aW8oZ2gsIG1ldGhvZCA9ICJ3YWxkIiwgY29uZi5sZXZlbCA9IDAuOTUpDQpvcl9naA0KYGBgDQotIEvhur90IHF14bqjIHBow6JuIHTDrWNoIE9kZHMgUmF0aW8gZ2nhu69hIGdp4bubaSB0w61uaCB2w6Aga2jhuqMgbsSDbmcgc+G7nyBo4buvdSBuaMOgIG5oxrAgc2F1Og0KDQogIC0gT2RkcyBSYXRpbyAoT1IpID0gMC45NTYNCg0KICAtIEtob+G6o25nIHRpbiBj4bqteSA5NSU6IHThu6sgMC44OTQgxJHhur9uIDEuMDIzDQoNCi0gRGnhu4VuIGdp4bqjaToNCg0KICAtIEdpw6EgdHLhu4sgT1IgPSAwLjk1NiBjaG8gdGjhuqV5IG9kZHMgKGPGoSBo4buZaSkgc+G7nyBo4buvdSBuaMOgIGPhu6dhIG7hu68gdGjhuqVwIGjGoW4gbmFtIGtob+G6o25nIDQuNCUuIFR1eSBuaGnDqm4sIHPhu7Ega2jDoWMgYmnhu4d0IGzDoCBuaOG7jy4NCg0KICAtIERvIGtob+G6o25nIHRpbiBj4bqteSA5NSUgY2jhu6lhIGdpw6EgdHLhu4sgMSwgbsOqbjoNCg0KICAgIC0gS2jDtG5nIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nIGdp4bubaSB0w61uaCDhuqNuaCBoxrDhu59uZyDEkeG6v24gb2RkcyBz4bufIGjhu691IG5ow6AuDQoNCi0gKipL4bq/dCBsdeG6rW46KiogTeG6t2MgZMO5IG7hu68gY8OzIHbhursgY8OzIG9kZHMgc+G7nyBo4buvdSBuaMOgIHRo4bqlcCBoxqFuIG5hbSBt4buZdCBjaMO6dCwgbmjGsG5nIHPhu7Ega2jDoWMgYmnhu4d0IGtow7RuZyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLiBEbyDEkcOzLCBnaeG7m2kgdMOtbmgga2jDtG5nIHBo4bqjaSBsw6AgeeG6v3UgdOG7kSDhuqNuaCBoxrDhu59uZyByw7UgcuG7h3QgxJHhur9uIGto4bqjIG7Eg25nIHPhu58gaOG7r3UgbmjDoCB0cm9uZyBk4buvIGxp4buHdSBoaeG7h24gdOG6oWkuDQoNCiMjIyAqKjYuMy4yLiBNYXJpdGFsU3RhdHVzIHbDoCBIb21lb3duZXI6KioNCg0KYGBge3J9DQojIFTDrW5oIE9SIHbDoCBraG/huqNuZyB0aW4gY+G6rXkNCm9yX21oIDwtIE9kZHNSYXRpbyhtaCwgbWV0aG9kID0gIndhbGQiLCBjb25mLmxldmVsID0gMC45NSkNCm9yX21oDQpgYGANCg0KLSBPZGRzIFJhdGlvIChPUikgPSAwLjI4Mw0KDQotIEtob+G6o25nIHRpbiBj4bqteSA5NSU6IHThu6sgMC4yNjMgxJHhur9uIDAuMzA0DQoNCi0gRGnhu4VuIGdp4bqjaToNCg0KICAtIEdpw6EgdHLhu4sgT2RkcyBSYXRpbyAwLjI4MyBjw7MgbmdoxKlhIGzDoCBvZGRzIHPhu58gaOG7r3UgbmjDoCBj4bunYSBuaMOzbSBuZ8aw4budaSDEkeG7mWMgdGjDom4gY2jhu4kgYuG6sW5nIGtob+G6o25nIDI4LjMlIG9kZHMgY+G7p2EgbmjDs20gbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuLiBOw7NpIGPDoWNoIGtow6FjLCBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gY8OzIGto4bqjIG7Eg25nIHPhu58gaOG7r3UgbmjDoCBjYW8gaMahbiBn4bqnbiAzLjUgbOG6p24gc28gduG7m2kgbmfGsOG7nWkgxJHhu5ljIHRow6JuICh2w6wgMS8wLjI4M+KJiDMuNTMpLg0KDQogIC0gS2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gT2RkcyBSYXRpbyBu4bqxbSBob8OgbiB0b8OgbiBkxrDhu5tpIDEsIHThu6sgMC4yNjMgxJHhur9uIDAuMzA0LCDEkWnhu4F1IG7DoHkgY2hvIHRo4bqleSBz4buxIGtow6FjIGJp4buHdCB24buBIG9kZHMgc+G7nyBo4buvdSBuaMOgIGdp4buvYSBoYWkgbmjDs20gbMOgIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogdsOgIGtow7RuZyBwaOG6o2kgZG8gbmfhuqt1IG5oacOqbi4NCg0KLSBL4bq/dCBsdeG6rW46DQoNCkThu68gbGnhu4d1IGNobyB0aOG6pXkgdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIOG6o25oIGjGsOG7n25nIHLDtSByw6BuZyDEkeG6v24ga2jhuqMgbsSDbmcgc+G7nyBo4buvdSBuaMOgLiBOZ8aw4budaSDEkcOjIGvhur90IGjDtG4gY8OzIG9kZHMgc+G7nyBo4buvdSBuaMOgIGNhbyBoxqFuIMSRw6FuZyBr4buDIHNvIHbhu5tpIG5nxrDhu51pIMSR4buZYyB0aMOibiwgdsOgIGtow6FjIGJp4buHdCBuw6B5IGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIHbhu5tpIG3hu6ljIMSR4buZIHRpbiBj4bqteSA5NSUuIMSQw6J5IGzDoCBi4bqxbmcgY2jhu6luZyBjaG8gdGjhuqV5IHZp4buHYyDEkcOjIGvhur90IGjDtG4gY8OzIGxpw6puIHF1YW4gY2jhurd0IGNo4bq9IMSR4bq/biBraOG6oyBuxINuZyBz4bufIGjhu691IG5ow6AgdHJvbmcgbeG6q3Uga2jhuqNvIHPDoXQgbsOgeS4NCg0KIyMjICoqNi4zLjMuIEdlbmRlciB2w6AgTWFyaXRhbFN0YXR1czoqKg0KDQpgYGB7cn0NCiMgVMOtbmggT1IgdsOgIGtob+G6o25nIHRpbiBj4bqteQ0Kb3JfZ20gPC0gT2Rkc1JhdGlvKGdtLCBtZXRob2QgPSAid2FsZCIsIGNvbmYubGV2ZWwgPSAwLjk1KQ0Kb3JfZ20NCmBgYA0KDQotIE9kZHMgUmF0aW8gKE9SKSA9IDEuMTIxDQoNCi0gS2hv4bqjbmcgdGluIGPhuq15IDk1JTogdOG7qyAxLjA0OSDEkeG6v24gMS4xOTgNCg0KLSBEaeG7hW4gZ2nhuqNpOg0KDQogIC0gR2nDoSB0cuG7iyBPZGRzIFJhdGlvIDEuMTIxIGPDsyBuZ2jEqWEgbMOgIG9kZHMgKGPGoSBo4buZaSkgxJHDoyBr4bq/dCBow7RuIGPhu6dhIG7hu68gY2FvIGjGoW4gb2RkcyDEkcOjIGvhur90IGjDtG4gY+G7p2EgbmFtIGtob+G6o25nIDEyLjElLCBoYXkgbsOzaSBjw6FjaCBraMOhYywgbuG7ryBjw7Mga2jhuqMgbsSDbmcgxJHDoyBr4bq/dCBow7RuIGNhbyBoxqFuIG5hbSBraG/huqNuZyAxLjEyIGzhuqduLg0KDQogIC0gS2hv4bqjbmcgdGluIGPhuq15IDk1JSB04burIDEuMDQ5IMSR4bq/biAxLjE5OCwga2jDtG5nIGNo4bupYSBnacOhIHRy4buLIDEsIGNo4bupbmcgdOG7jyBz4buxIGtow6FjIGJp4buHdCBuw6B5IGzDoCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLiDEkGnhu4F1IG7DoHkgbmdoxKlhIGzDoCB24bubaSBt4bupYyB0aW4gY+G6rXkgOTUlLCBjaMO6bmcgdGEgY2jhuq9jIGNo4bqvbiBy4bqxbmcgdOG7tyBs4buHIMSRw6Mga+G6v3QgaMO0biBj4bunYSBu4buvIHbDoCBuYW0ga2jDtG5nIGLhurFuZyBuaGF1Lg0KDQotIEvhur90IGx14bqtbjoNCg0KROG7ryBsaeG7h3UgY2hvIHRo4bqleSBu4buvIGdp4bubaSBjw7Mgb2RkcyDEkcOjIGvhur90IGjDtG4gY2FvIGjGoW4gbmFtIGdp4bubaSBraG/huqNuZyAxMiUsIHTGsMahbmcgxJHGsMahbmcgduG7m2kgdmnhu4djIG7hu68gY8OzIGto4bqjIG7Eg25nIMSRw6Mga+G6v3QgaMO0biBn4bqlcCAxLjEyIGzhuqduIHNvIHbhu5tpIG5hbSBnaeG7m2kuIA0KDQojICoqUGjhuqduIDcuIFThu5RORyBL4bq+VCBWw4AgVEjhuqJPIExV4bqsTioqDQoNCiMjICoqNy4xLiBUw7NtIHThuq90IG5o4buvbmcgcGjDoXQgaGnhu4duIGNow61uaCoqDQoNCkThu7FhIHRyw6puIGPDoWMgcGjDom4gdMOtY2ggxJHhu4tuaCB0w61uaCB04burIGLhu5kgZOG7ryBsaeG7h3UgMTQsMDU5IGdpYW8gZOG7i2NoIHNpw6p1IHRo4buLLCBt4buZdCBz4buRIMSR4bq3YyDEkWnhu4NtIG7hu5VpIGLhuq10IGPhu6dhIGtow6FjaCBow6BuZyB2w6AgaMOgbmggdmkgbXVhIHPhuq9tIGPDsyB0aOG7gyByw7p0IHJhIG5oxrAgc2F1Og0KDQotIEPGoSBj4bqldSBnaeG7m2kgdMOtbmggdsOgIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibjoNCg0KICAtIEtow6FjaCBow6BuZyBu4buvIGNoaeG6v20gxrB1IHRo4bq/IG5o4bq5ICh+NTElKSwgduG7m2kgc+G7sSBjaMOqbmggbOG7h2NoIGtow7RuZyBs4bubbiBzbyB24bubaSBuYW0gKH40OSUpLg0KDQogIC0gTmfGsOG7nWkgxJHhu5ljIHRow6JuIChTKSB2w6AgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIChNKSBjw7MgdOG7tyBs4buHIGfhuqduIHTGsMahbmcgxJHGsMahbmcsIG5oxrBuZyBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgcsO1IHLhu4d0IHbhu4EgaMOgbmggdmkgc+G7nyBo4buvdSBuaMOgLg0KDQotIFTDrG5oIHRy4bqhbmcgc+G7nyBo4buvdSBuaMOgOg0KDQogIC0gS2hv4bqjbmcgNjAlIGtow6FjaCBow6BuZyBz4bufIGjhu691IG5ow6AsIGNobyB0aOG6pXkgcGjhuqduIGzhu5tuIGzDoCBuaMOzbSDhu5VuIMSR4buLbmggduG7gSBraW5oIHThur8gdsOgIGNo4buXIOG7ny4NCg0KICAtIEPDsyBt4buRaSBxdWFuIGjhu4cgxJHDoW5nIGvhu4MgZ2nhu69hIE1hcml0YWxTdGF0dXMgdsOgIEhvbWVvd25lcjogTmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIGPDsyB4dSBoxrDhu5tuZyBz4bufIGjhu691IG5ow6Agbmhp4buBdSBoxqFuIMSRw6FuZyBr4buDICg3NC45NiUpIHNvIHbhu5tpIG5nxrDhu51pIMSR4buZYyB0aMOibiAoNDUuODQlKS4NCg0KLSBQaMOibiBi4buRIHRodSBuaOG6rXA6DQoNCiAgLSBOaMOzbSAkMzBLIC0gJDUwSyBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0ICgzMi43MyUpLCBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyBjaOG7pyB54bq/dSB0aHXhu5ljIHThuqduZyBs4bubcCB0cnVuZyBsxrB1Lg0KDQogIC0gQ8OhYyBuaMOzbSB0aHUgbmjhuq1wIGNhbyAoJDE1MEsrKSBy4bqldCDDrXQgKH4yJSksIGPDsyB0aOG7gyBkbyB0aOG7iyBwaOG6p24gaG/hurdjIGjDoG5oIHZpIG11YSBz4bqvbSBraMOhYyBiaeG7h3QuDQoNCi0gxJDhu4thIGzDvToNCg0KICAtIEPDoWMgZ2lhbyBk4buLY2ggY2jhu6cgeeG6v3UgxJHhur9uIHThu6sgVVNBICg2OCUpLCDEkeG6t2MgYmnhu4d0IGzDoCBjw6FjIGJhbmcgV0EsIENBLCBPUi4NCg0KICAtIEPDoWMgdGjDoG5oIHBo4buRIG7hu5VpIGLhuq10IGfhu5NtIFNhbGVtLCBUYWNvbWEsIExvcyBBbmdlbGVzLCBjaGnhur9tIHThu7cgdHLhu41uZyBs4bubbiB0cm9uZyB04buVbmcgc+G7kSBnaWFvIGThu4tjaC4NCg0KLSBIw6BuaCB2aSBtdWEgc+G6r20gdGhlbyBz4bqjbiBwaOG6qW06DQoNCiAgLSBUaOG7sWMgcGjhuqltIChGb29kKSBsw6AgbmjDs20gc+G6o24gcGjhuqltIGNow61uaCAoNzIuMiUpLCDEkeG6t2MgYmnhu4d0IGzDoDoNCg0KICAgIC0gVmVnZXRhYmxlcyAoMTIuMjklKQ0KDQogICAgLSBTbmFjayBGb29kcyAoMTEuMzglKQ0KDQogICAgLSBEYWlyeSAoNi40MiUpDQoNCiAgLSBDw6FjIHPhuqNuIHBo4bqpbSBraMO0bmcgdGnDqnUgdGjhu6UgxJHGsOG7o2MgKE5vbi1jb25zdW1hYmxlKSBjaGnhur9tIH4xOSUsIHbDoCBEcmluayBjaGnhur9tIGtob+G6o25nIDklLg0KDQojIyAqKjcuMi4gSOG6oW4gY2jhur8gY+G7p2EgcGjDom4gdMOtY2gqKg0KDQpQaMOibiB0w61jaCB0cm9uZyBiw6FvIGPDoW8gbsOgeSBjaOG7pyB54bq/dSB04bqtcCB0cnVuZyB2w6BvIGPDoWMgYmnhur9uIMSR4buLbmggdMOtbmggdsOgIGRvIMSRw7MgY8OybiBt4buZdCBz4buRIGjhuqFuIGNo4bq/IG5oxrAgc2F1Og0KDQotIFRo4bupIG5o4bqldCwgcGjDom4gdMOtY2ggY2jhu6cgeeG6v3UgdOG6rXAgdHJ1bmcgdsOgbyBjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oIG5oxrAgR2VuZGVyLCBNYXJpdGFsU3RhdHVzLCBIb21lb3duZXIsIEFubnVhbEluY29tZSAoZMaw4bubaSBk4bqhbmcgcGjDom4gbmjDs20pLCBDaXR5LCBQcm9kdWN0RmFtaWx5IHbDoCBQcm9kdWN0Q2F0ZWdvcnkuIFZp4buHYyBraMO0bmcgxJHGsGEgdsOgbyBjw6FjIGJp4bq/biDEkeG7i25oIGzGsOG7o25nIG5oxrAgdHXhu5VpIHTDoWMsIHRodSBuaOG6rXAgY+G7pSB0aOG7gyAodGhlbyBz4buRKSwgdOG7lW5nIG3hu6ljIGNoaSB0acOqdSwgc+G7kSBsxrDhu6NuZyBnaWFvIGThu4tjaCBoYXkgdOG6p24gc3XhuqV0IG11YSBow6BuZyDEkcOjIGzDoG0gZ2nhuqNtIMSR4buZIHPDonUgdsOgIHTDrW5oIMSR4buLbmggbMaw4bujbmcgY+G7p2EgY8OhYyBr4bq/dCBsdeG6rW4uIE5o4buvbmcgeeG6v3UgdOG7kSBuw6B5IGPDsyB0aOG7gyBnacO6cCB4w6FjIMSR4buLbmggcsO1IGjGoW4gbeG7kWkgcXVhbiBo4buHIGdp4buvYSDEkeG6t2MgxJFp4buDbSBraMOhY2ggaMOgbmcgdsOgIGjDoG5oIHZpIHRpw6p1IGTDuW5nLg0KDQotIFRo4bupIGhhaSwgZOG7ryBsaeG7h3UgY8OzIHRo4buDIGtow7RuZyBjw6JuIGLhurFuZyBnaeG7r2EgY8OhYyBuaMOzbSwgZOG6q24gxJHhur9uIHNhaSBs4buHY2ggdHJvbmcga+G6v3QgbHXhuq1uLiBWw60gZOG7pSwgbmjDs20gdGh1IG5o4bqtcCBy4bqldCBjYW8gaG/hurdjIG3hu5l0IHPhu5EgdGjDoG5oIHBo4buRIGPDsyBz4buRIGzGsOG7o25nIHF1YW4gc8OhdCBy4bqldCBuaOG7jyBzbyB24bubaSB0b8OgbiBi4buZIHThuq1wIGThu68gbGnhu4d1LCBsw6BtIGdp4bqjbSB0w61uaCDEkeG6oWkgZGnhu4duIHbDoCBraOG6oyBuxINuZyBraMOhaSBxdcOhdCBow7NhLiBWaeG7h2Mgc28gc8OhbmggY8OhYyBuaMOzbSBjw7MgcXV5IG3DtCBraMOhYyBiaeG7h3QgbcOgIGtow7RuZyDEkWnhu4F1IGNo4buJbmggdHLhu41uZyBz4buRIGPDsyB0aOG7gyBnw6J5IGhp4buDdSBs4bqnbSB24buBIG3hu6ljIMSR4buZIOG6o25oIGjGsOG7n25nIGPhu6dhIHThu6tuZyDEkeG6t2MgxJFp4buDbSBuaMOibiBraOG6qXUgaOG7jWMgxJHhur9uIGjDoG5oIHZpIHRpw6p1IGTDuW5nLg0KDQotIFRo4bupIGJhLCBjw6FjIGJp4bq/biDEkcaw4bujYyBwaMOibiB0w61jaCBjw7Mga2jhuqMgbsSDbmcgdMawxqFuZyBxdWFuIGzhuqtuIG5oYXUg4oCTIHbDrSBk4bulIG5oxrAgdGh1IG5o4bqtcCB2w6AgdMOsbmggdHLhuqFuZyBz4bufIGjhu691IG5ow6AsIGhv4bq3YyB0aHUgbmjhuq1wIHbDoCBuxqFpIGPGsCB0csO6IOKAkyBuaMawbmcgYsOgaSBwaMOibiB0w61jaCBjaMawYSDEkcOhbmggZ2nDoSBjw6FjIG3hu5FpIHF1YW4gaOG7hyBjaMOpbyBuw6B5LiBWaeG7h2Mga2jDtG5nIGtp4buDbSBzb8OhdCDhuqNuaCBoxrDhu59uZyBjaMOpbyBnaeG7r2EgY8OhYyBiaeG6v24ga2hp4bq/biBjaG8ga+G6v3QgbHXhuq1uIHbhu4EgdMOhYyDEkeG7mW5nIHJpw6puZyBs4bq7IGPhu6dhIHThu6tuZyB54bq/dSB04buRIGPDsyB0aOG7gyBjaMawYSBob8OgbiB0b8OgbiBjaMOtbmggeMOhYy4NCg0KLSBUaOG7qSB0xrAsIHnhur91IHThu5EgZ2nhu5tpIHTDrW5oIChHZW5kZXIpIHR1eSDEkcaw4bujYyB0aOG7kW5nIGvDqiBuaMawbmcgY2jGsGEgxJHGsOG7o2MgcGjDom4gdMOtY2ggc8OidSBsacOqbiBxdWFuIMSR4bq/biBow6BuaCB2aSB0acOqdSBkw7luZyBuaMawIMawdSB0acOqbiBz4bqjbiBwaOG6qW0sIG3hu6ljIMSR4buZIGNoaSB0acOqdSBob+G6t2Mga2jDoWMgYmnhu4d0IHRyb25nIGzhu7FhIGNo4buNbiB0aGVvIGdp4bubaS4gVHJvbmcgdGjhu7FjIHThur8sIGdp4bubaSB0w61uaCB0aMaw4budbmcg4bqjbmggaMaw4bufbmcgxJHDoW5nIGvhu4MgxJHhur9uIGjDoG5oIHZpIG11YSBz4bqvbSB2w6Agc+G7nyB0aMOtY2ggdGnDqnUgZMO5bmcsIG7Dqm4gdmnhu4djIGtow7RuZyBraGFpIHRow6FjIGvhu7kga2jDrWEgY+G6oW5oIG7DoHkgbMOgIG3hu5l0IMSRaeG7g20gdGhp4bq/dSBzw7N0IMSRw6FuZyBr4buDLg0KICANCiMjICoqNy4zLiDEkOG7gSB4deG6pXQqKg0KDQpE4buxYSB0csOqbiBjw6FjIHBow6JuIHTDrWNoIMSRw6MgdGjhu7FjIGhp4buHbiwgbeG7mXQgc+G7kSDEkeG7gSB4deG6pXQgY2hp4bq/biBsxrDhu6NjIGTDoG5oIGNobyBkb2FuaCBuZ2hp4buHcCBuaMawIHNhdToNCg0KLSBU4bqtcCB0cnVuZyB2w6BvIHBow6JuIGtow7pjIGNo4bunIGzhu7FjOg0KDQogIC0gQ8OhYyBraMOhY2ggaMOgbmcgdGh1IG5o4bqtcCB04burICQzMEsgLSAkNzBLIGNoaeG6v20gdOG7tyB0cuG7jW5nIGzhu5tuIG5o4bqldCB2w6AgY8OzIHh1IGjGsOG7m25nIHRpw6p1IGTDuW5nIG3huqFuaCBjw6FjIHPhuqNuIHBo4bqpbSB0aGnhur90IHnhur91IG5oxrAgcmF1IGPhu6csIHPhu69hLCDEkeG7kyDEg24gbmjhurkg4oaSIGPhuqduIMawdSB0acOqbiB0aeG6v3AgY+G6rW4gbmjDs20gbsOgeSBxdWEgY8OhYyBjaGnhur9uIGThu4tjaCBraHV54bq/biBtw6NpLCBjb21ibyBz4bqjbiBwaOG6qW0gcGjDuSBo4bujcCB0w7ppIHRp4buBbi4NCg0KLSBUaGnhur90IGvhur8gY2jGsMahbmcgdHLDrG5oIGNoxINtIHPDs2MgcmnDqm5nIGNobyBuaMOzbSDEkcOjIGvhur90IGjDtG4gc+G7nyBo4buvdSBuaMOgOg0KDQogIC0gTmjDs20gbsOgeSBjw7MgdOG7tyBs4buHIHPhu58gaOG7r3UgY2FvIHbDoCB0aOG7gyBoaeG7h24gc+G7sSDhu5VuIMSR4buLbmgg4oaSIGPDsyB0aOG7gyDGsHUgdGnDqm4gY2hvIGPDoWMgc+G6o24gcGjhuqltIGdpYSDEkcOsbmgsIG5ow6AgYuG6v3AsIHbDoCBk4buLY2ggduG7pSBnaWFvIGjDoG5nIMSR4buLbmgga+G7sy4NCg0KLSBUw6FpIGPhuqV1IHRyw7pjIHRyxrBuZyBiw6B5IHPhuqNuIHBo4bqpbSB2w6AgcXXhuqNuIGzDvSB04buTbiBraG86DQoNCiAgLSBUxINuZyBkaeG7h24gdMOtY2ggY2hvIGPDoWMgbmjDs20gc+G6o24gcGjhuqltIGLDoW4gY2jhuqF5IG5oxrAgVmVnZXRhYmxlcywgU25hY2sgRm9vZHMsIERhaXJ5Lg0KDQogIC0gUsOgIHNvw6F0IGPDoWMgZGFuaCBt4bulYyBjw7MgdOG6p24gc3XhuqV0IHRo4bqlcCAobmjGsCBDYW5uZWQgT3lzdGVycywgQ2FuZGxlcykgxJHhu4MgdOG7kWkgxrB1IGtow7RuZyBnaWFuIHbDoCBkw7JuZyB0aeG7gW4uDQoNCi0gUGjDoXQgdHJp4buDbiB0aOG7iyB0csaw4budbmcgdGhlbyBraHUgduG7sWMgxJHhu4thIGzDvToNCg0KICAtIFTEg25nIGPGsOG7nW5nIHRp4bq/cCB0aOG7iyDhu58gY8OhYyB0aMOgbmggcGjhu5EgY8OzIGzGsOG7o25nIGdpYW8gZOG7i2NoIGzhu5tuIG5oxrAgU2FsZW0sIFRhY29tYSwgTG9zIEFuZ2VsZXMsIMSR4buTbmcgdGjhu51pIGto4bqjbyBzw6F0IGzhuqFpIGhp4buHdSBxdeG6oyBraW5oIGRvYW5oIOG7nyBuaOG7r25nIGtodSB24buxYyBjw7Mgw610IGhv4bqhdCDEkeG7mW5nLg0KDQotIEtodXnhur9uIGtow61jaCBt4bufIHLhu5luZyBk4buvIGxp4buHdSB0cm9uZyB0xrDGoW5nIGxhaToNCg0KICAtIERvYW5oIG5naGnhu4dwIG7Dqm4gYuG7lSBzdW5nIGPDoWMgYmnhur9uIMSR4buLbmggbMaw4bujbmcgKGdpw6EgdHLhu4sgxJHGoW4gaMOgbmcsIHPhu5EgbOG6p24gbXVhKSwgdGjhu51pIGdpYW4gZ2lhbyBk4buLY2ggdsOgIHRow7RuZyB0aW4gY8OhIG5ow6JuIGPGoSBi4bqjbiDEkeG7gyBo4buXIHRy4bujIHBow6JuIHTDrWNoIG7Dom5nIGNhbywgY8OhIG5ow6JuIGjDs2EgY2hp4bq/biBsxrDhu6NjIG1hcmtldGluZyB2w6AgY+G6o2kgdGhp4buHbiB0cuG6o2kgbmdoaeG7h20ga2jDoWNoIGjDoG5nLg0KICANCiMjICoqNy40LiDEkOG7gSB4deG6pXQgaMaw4bubbmcgbmdoaeG6v24gY+G7qXUgdGnhur9wIHRoZW8qKg0KDQotIExp4buHdSBuaMOzbSBraMOhY2ggaMOgbmcgxJHhu5ljIHRow6JuIG5oxrBuZyBjw7MgdGh1IG5o4bqtcCBjYW8gdsOgIHPhu58gaOG7r3UgbmjDoCBjw7MgaMOgbmggdmkgY2hpIHRpw6p1IGfhuqduIGdp4buRbmcgduG7m2kgbmjDs20gxJHDoyBr4bq/dCBow7RuIHbDoCB0aHUgbmjhuq1wIGNhbyBoYXkga2jDtG5nPw0KDQogIOKGkiBTbyBzw6FuaCBoYWkgbmjDs20gY8OzIMSRaeG7g20gY2h1bmcgduG7gSB0aHUgbmjhuq1wIHbDoCBz4bufIGjhu691IG5ow6AgbmjGsG5nIGtow6FjIHTDrG5oIHRy4bqhbmcgaMO0biBuaMOibi4NCg0KLSBT4buxIGvhur90IGjhu6NwIGdp4buvYSB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gdsOgIMSR4buZIHR14buVaSAobuG6v3UgY8OzKSDhuqNuaCBoxrDhu59uZyB0aOG6vyBuw6BvIMSR4bq/biB2aeG7h2MgbOG7sWEgY2jhu41uIG5ow7NtIHPhuqNuIHBo4bqpbT8NCg0KICDihpIgVsOtIGThu6U6IE5nxrDhu51pIHRy4bq7IMSRw6Mga+G6v3QgaMO0biBjw7MgdGnDqnUgZMO5bmcga2jDoWMgduG7m2kgbmfGsOG7nWkgbOG7m24gdHXhu5VpIMSRw6Mga+G6v3QgaMO0bj8NCg0KLSBLaMOhY2ggaMOgbmcgc+G7kW5nIHThuqFpIGPDoWMga2h1IHbhu7FjIMSRw7QgdGjhu4sgY8OzIHh1IGjGsOG7m25nIGNoaSB0acOqdSBuaGnhu4F1IGjGoW4gY2hvIHPhuqNuIHBo4bqpbSB0aeG7h24gbOG7o2kgc28gduG7m2kga2jDoWNoIGjDoG5nIG7DtG5nIHRow7RuIGtow7RuZz8NCg0KICDihpIgUGjDom4gdMOtY2ggdGhlbyBiaeG6v24gxJHhu4thIGzDvSBob+G6t2MgdGjDoG5oIHBo4buRLg0KDQotIE5o4buvbmcgbmjDs20gbmjDom4ga2jhuql1IGjhu41jIG7DoG8gY2hpIHRpw6p1IGNhbyBuaOG6pXQgY2hvIG5ow7NtIHPhuqNuIHBo4bqpbSBraMO0bmcgdGnDqnUgZMO5bmcgxJHGsOG7o2MgKE5vbi1jb25zdW1hYmxlKT8NCg0KICDihpIgVsOtIGThu6U6IEPDsyBwaOG6o2kgbmfGsOG7nWkgxJHhu5ljIHRow6JuLCBraMO0bmcgY8OzIG5ow6AsIHRodSBuaOG6rXAgY2FvIHF1YW4gdMOibSBuaGnhu4F1IGjGoW4gxJHhur9uIHPhuqNuIHBo4bqpbSBwaGkgdGjhu7FjIHBo4bqpbT8NCg0KLSBDw7Mgc+G7sSB0aGF5IMSR4buVaSBuw6BvIHRyb25nIHThu7cgdHLhu41uZyBjaGkgdGnDqnUgZ2nhu69hIGPDoWMgbmjDs20gdGh1IG5o4bqtcCDEkeG7kWkgduG7m2kgdOG7q25nIGRhbmggbeG7pWMgc+G6o24gcGjhuqltIGNow61uaCAoUHJvZHVjZSwgRGFpcnksIFNuYWNrIEZvb2RzLCB2LnYuKT8NCg0KICDihpIgUGjDom4gdMOtY2ggdOG7tyBs4buHIGNoaSB0acOqdSB04burbmcgbG/huqFpIHRoZW8gdOG7q25nIG3hu6ljIHRodSBuaOG6rXAuDQogIA0KDQoNCg==