CHƯƠNG 1: TỔNG QUAN NGHIÊN CỨU

1.1 Đặt vấn đề

Trong bối cảnh cạnh tranh ngày càng khốc liệt của ngành hàng không, chất lượng dịch vụ trở thành yếu tố then chốt quyết định sự hài lòng và lòng trung thành của khách hàng. Các hãng hàng không không chỉ cạnh tranh về giá cả và tuyến bay mà còn phải không ngừng nâng cao chất lượng dịch vụ để thu hút và giữ chân khách hàng. Việc phân tích từ dữ liệu trong cuộc khảo sát về trải nghiệm dịch vụ hàng không như loại hình du lịch, sự sạch sẽ, xử lý hành lý và trải nghiệm trên chuyến bay không chỉ giúp hãng hàng không hiểu rõ hơn nhu cầu và mong muốn của khách hàng mà còn định hướng cho các cải tiến dịch vụ trong tương lai.Chình vì thế, ở bài nghiên cứu này nhằm phân tích các yếu tố ảnh hưởng đến sự hài lòng của hành khách, từ đó đề xuất các biện pháp nâng cao chất lượng dịch vụ của hãng hàng không.

1.2 Mục tiêu bài nghiên cứu

Mục tiêu của của bài nghiên cứu lần này chúng tôi sẽ đánh giá mức độ hài lòng của hành khách của hãng hàng không dựa trên bộ dữ liệu về sự hài lòng của hành khách. Nghiên cứu tập trung vào các yếu tố như giới tính, độ tuổi, loại khách hàng, loại hình du lịch, độ trễ xuất phát và đến, khoảng cách bay, và các tiện ích liên quan đến thời gian. Mục đích là phân tích mối quan hệ giữa các yếu tố này và mức độ hài lòng của hành khách, từ đó đưa ra những nhận định và đề xuất cải thiện để nâng cao trải nghiệm của hành khách trong quá trình sử dụng dịch vụ hàng không.

1.3 Phương pháp nghiên cứu

Thu thập dữ liệu, Phân tích khảo sát trải nghiệm dịch vụ hàng không của khách hàng tham gia khảo sát bằng cách sử dụng phương pháp mô hình hồi quy, các thống kê mổ tả để đo lường biến định tính, định lười dưới dạng đếm số lần xuất hiện các biến. và nghiên cứu mối tương quan giữa chúng.

1.4 Ý nghĩa nghiên cứu

Kết quả này giúp các công ty hàng không tập trung cải thiện các dịch vụ quan trọng để nâng cao trải nghiệm khách hàng, duy trì sự trung thành và thu hút thêm khách hàng mới. Điều này không chỉ có ý nghĩa thực tiễn trong quản lý và tiếp thị mà còn đóng góp vào cơ sở dữ liệu khoa học về sự hài lòng và trung thành của khách hàng, ngoài ra có thể phát triển thêm trong lĩnh vực ngành nghề hàng không.

CHƯƠNG 2: TỔNG QUAN BỘ DỮ LIỆU AIRLINE PASSENGER SATISFACTION

2.1 Giới thiệu bộ dữ liệu Airline Passenger Satisfaction

Chúng tôi sẽ giới thiệu bộ dữ liệu “Airline Passenger Satisfaction”, được thu thập từ trang Kaggle.

Bộ dữ liệu Airline Passenger Satisfaction cung cấp Khảo sát về dịch vụ hàng không của khách hàng từ hơn 25.000 tham gia khảo sát đối với hãng hãng không, bao gồm thông tin bổ sung về từng hành khách, chuyến bay và loại hình di chuyển của họ, cũng như đánh giá các yếu tố khác nhau như mức độ sạch sẽ trong máy bay, sự thoải mái, dịch vụ và trải nghiệm tổng thể. Dựa vào những thông tin này chúng tôi có thể phân tích các mức độ về sự trải nghiệm của hành khách hàng không khi đi máy bay.

2.2 Mô tả đặc trưng dữ liệu

Bộ dữ liệu Airline Passenger Satisfaction là một tập dữ liệu cung cấp thông tin chi tiết về sử hài lòng của hàng khách hàng không chứa trên 12 biến và 25.976 quan sát

• Gender (gender): Giới tính của hành khách, “Male” (Nam) hoặc “Female” (Nữ).

• Age (age): Độ tuổi của hành khách khi họ sử dụng dịch vụ hàng không.

• Customer Type (type of customer): Phân loại khách hàng trung thành và không trung thành

• Type of Travel (type of travel): Mục đích của việc di chuyển là công việc kinh doanh ( Business) và Personal ( Các công việc khác).

• Class (class): Mô tả hạng ghế trên máy bay mà hành khách sử dụng,

• Departure Delay (delay): Thời gian cất cánh muộn của chuyến bay

• Arrival Delay (arrival delay): Thời gian hạ cánh trễ của chuyến bay

• Departure and Arrival Time Convenience (dep and arr):Sự thuận tiện về thời gian cất cánh và hạ cánh.

• Baggage handling : Mức độ hài lòng với dịch vụ xử lý hành lý của hãng hàng không từ 1 (rất tệ) đến 5 (rất hài lòng) - 0 điểm.

• Satisfaction: Trải nghiệm của khách hàng đối với hãng bay, bao gồm: Satisfied: Hài lòng; Neutral or Unsatisfied: Trung lập hoặc không hài lòng.

• Inflight wifi service: Mức độ hài lòng với dịch vụ Wifi trên máy bay từ 1 (rất tệ) đến 5 (rất hài lòng) - 0 nghĩa là “không đánh giá”

• In-flight Service: Mức độ hài lòng với dịch vụ trên chuyến bay từ 1 (rất tệ) đến 5 (rất hài lòng) - 0 có nghĩa là “không đánh giá”

• Cleanliness: Mức độ hài lòng với độ sạch sẽ của máy bay từ 1 (rất tệ) đến 5 (rất hài lòng) - 0 có nghĩa là “không đánh giá”

Link: https://docs.google.com/spreadsheets/d/1XnCc9U2Ou23aRKs0BjJbngczC6RvTmcq/edit?gid=866704878#gid=866704878

library(scales)
## Warning: package 'scales' was built under R version 4.2.3
library(DT)
## Warning: package 'DT' was built under R version 4.2.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.2.3
## 
## 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(magrittr)
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.3
## Warning: package 'ggplot2' was built under R version 4.2.3
## Warning: package 'tibble' was built under R version 4.2.3
## Warning: package 'tidyr' was built under R version 4.2.3
## Warning: package 'readr' was built under R version 4.2.3
## Warning: package 'purrr' was built under R version 4.2.3
## Warning: package 'stringr' was built under R version 4.2.3
## Warning: package 'forcats' was built under R version 4.2.3
## Warning: package 'lubridate' was built under R version 4.2.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.4
## ✔ ggplot2   3.4.2     ✔ stringr   1.5.0
## ✔ lubridate 1.9.2     ✔ tibble    3.2.1
## ✔ purrr     1.0.1     ✔ tidyr     1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ readr::col_factor() masks scales::col_factor()
## ✖ purrr::discard()    masks scales::discard()
## ✖ tidyr::extract()    masks magrittr::extract()
## ✖ dplyr::filter()     masks stats::filter()
## ✖ dplyr::lag()        masks stats::lag()
## ✖ purrr::set_names()  masks magrittr::set_names()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggplot2)
library(DescTools)
## Warning: package 'DescTools' was built under R version 4.2.3
library(epitools)
library(readxl)
## Warning: package 'readxl' was built under R version 4.2.3
data <- read_excel("Zalo Received Files/test airline passenger.xlsx")
View(data)
str(data)
## tibble [25,976 × 25] (S3: tbl_df/tbl/data.frame)
##  $ x                                : num [1:25976] 25673 12805 17032 17232 11783 ...
##  $ id                               : num [1:25976] 63665 62219 79679 62549 92304 ...
##  $ Gender                           : chr [1:25976] "Male" "Male" "Female" "Male" ...
##  $ Customer Type                    : chr [1:25976] "Loyal Customer" "Loyal Customer" "Loyal Customer" "disloyal Customer" ...
##  $ Age                              : num [1:25976] 65 59 20 25 10 36 36 25 56 46 ...
##  $ Type of Travel                   : chr [1:25976] "Business travel" "Personal Travel" "Personal Travel" "Business travel" ...
##  $ Class                            : chr [1:25976] "Business" "Eco" "Eco" "Business" ...
##  $ Flight Distance                  : num [1:25976] 3086 2425 762 1037 2615 ...
##  $ Inflight wifi service            : num [1:25976] 5 4 1 5 3 3 2 3 4 4 ...
##  $ Departure/Arrival time convenient: num [1:25976] 5 2 4 2 1 3 2 4 4 4 ...
##  $ Ease of Online booking           : num [1:25976] 2 4 1 5 3 3 2 3 4 3 ...
##  $ Gate location                    : num [1:25976] 5 3 3 3 3 3 2 4 4 4 ...
##  $ Food and drink                   : num [1:25976] 4 3 5 2 2 5 2 3 4 3 ...
##  $ Online boarding                  : num [1:25976] 3 4 1 5 3 2 5 3 3 5 ...
##  $ Seat comfort                     : num [1:25976] 5 3 5 2 2 5 4 3 4 5 ...
##  $ Inflight entertainment           : num [1:25976] 4 3 5 2 2 5 5 3 5 5 ...
##  $ On-board service                 : num [1:25976] 4 3 4 4 2 5 5 4 5 5 ...
##  $ Leg room service                 : num [1:25976] 4 5 4 5 5 5 5 1 5 4 ...
##  $ Baggage handling                 : num [1:25976] 4 3 3 3 2 4 5 3 5 5 ...
##  $ Checkin service                  : num [1:25976] 3 4 4 5 1 4 5 4 3 3 ...
##  $ Inflight service                 : num [1:25976] 4 3 4 5 4 5 5 2 5 5 ...
##  $ Cleanliness                      : num [1:25976] 4 3 5 2 2 5 5 3 3 4 ...
##  $ Departure Delay in Minutes       : num [1:25976] 40 39 31 31 30 28 28 27 26 26 ...
##  $ Arrival Delay in Minutes         : num [1:25976] 0 0 0 0 0 0 0 0 0 0 ...
##  $ satisfaction                     : chr [1:25976] "satisfied" "neutral or dissatisfied" "neutral or dissatisfied" "satisfied" ...

CHƯƠNG 3: KẾT QUẢ NGHIÊN CỨU

Thống kê mô tả 1 biến

Biến satisfaction

table(data$satisfaction)
## 
## neutral or dissatisfied               satisfied 
##                   14573                   11403
table(data$satisfaction)/sum(table(data$satisfaction))
## 
## neutral or dissatisfied               satisfied 
##               0.5610179               0.4389821
p <- as.data.frame(table(data$satisfaction)) 
colnames(p) <- c("satisfaction", "Count")
ggplot(p, aes(x = satisfaction, y = Count, fill = satisfaction)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "Số khách hàng đánh giá",
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

library(ggplot2)
p$Percentage <- (p$Count / sum(p$Count)) * 100

ggplot(p, aes(x = "", y = Percentage, fill = satisfaction)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Biến gender

Đầu tiên, chúng tôi sẽ lập bảng tần số cho biến Gender nhằm mục đích để nắm bắt được số lượng giới thích của hàng khách khi sự dụng dịch vụ hàng không.

table(data$Gender)
## 
## Female   Male 
##  13172  12804
table(data$Gender)/sum(table(data$Gender))
## 
##    Female      Male 
## 0.5070835 0.4929165
s <- as.data.frame(table(data$Gender)) 
colnames(s) <- c("Gender", "Count")
ggplot(s, aes(x = Gender, y = Count, fill = Gender)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "GIỚI TÍNH",
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

library(ggplot2)
s$Percentage <- (s$Count / sum(s$Count)) * 100

ggplot(s, aes(x = "", y = Percentage, fill = Gender)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Dựa vào kết quả bảng tần số và biểu đồ trên ta có thể thấy: Phân bố giới tính trong bộ dữ liệu “Airline Passenger Satisfaction” Sự chênh lệch về giới tính giữa số lượng hành khách nữ 13,172 (50.71%) và nam 12,804 (49.29%). Sự chênh lệch nhỏ này (nữ chỉ hơn nam khoảng 1.42%) cho thấy rằng cả hai giới tính đều được đại diện gần như đồng đều trong bộ dữ liệu, tạo điều kiện thuận lợi cho việc phân tích trải nghiệm khách hàng.

Biến Age

Trước khi phân tích biến Age, nhóm chúng tôi sẽ phân nhóm thành 6 nhóm độ tuổi: trẻ em(7-12), thiếu niên(12-18), thanh niên(18-25), trung niên(25-60), người cao tuổi(60-75), người già( 75 tuổi trở lên).

Biến Age thể hiện độ tuổi của hàng khách tham gia máy bay.

data$age <- cut(data$Age, 
                   breaks = c(6, 12, 18, 25, 60, 75, Inf), 
                   labels = c("trẻ nhỏ","thiếu niên", "thanh niên","trung niên","người cao tuổi","người già"))

Bây giờ chúng tôi sẽ lập bảng tần số để thể hiện rõ số tuổi cho khách hàng.

table(data$age)
## 
##        trẻ nhỏ     thiếu niên     thanh niên     trung niên người cao tuổi 
##            904           1257           3399          18338           1983 
##      người già 
##             95
library(ggplot2)
z <- as.data.frame(table(data$'age')) 
colnames(z) <- c("age", "Count")
ggplot(z, aes(x = `age`, y = Count, fill = `age`)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "Phân bố các nhóm tuổi"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

Biểu đồ trên cho thấy sự phân bố các nhóm tuổi trong tập dữ liệu với sự không đồng đều rõ rệt. Nhóm trung niên chiếm ưu thế vượt trội với 18,338 người, trong khi các nhóm khác như trẻ nhỏ (904 người), thiếu niên (1,257 người), thanh niên (3,399 người), người cao tuổi (1,983 người) và người già (95 người) có số lượng ít hơn đáng kể.

o <- prop.table(table(data$age)) * 100
o
## 
##        trẻ nhỏ     thiếu niên     thanh niên     trung niên người cao tuổi 
##      3.4801355      4.8390822     13.0851555     70.5959347      7.6339698 
##      người già 
##      0.3657222
z$Percentage <- (z$Count / sum(z$Count)) * 100

ggplot(z, aes(x = "", y = Percentage, fill = age)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Có sự đa dạng về các độ tuổi tham gia khảo sát mức độ hài lòng , với phần lớn hành khách tập trung trong độ tuổi từ 20 đến 40, đặc biệt đỉnh cao nhất ở tuổi 25. Tỷ lệ hành khách giảm dần từ khoảng 45 tuổi trở đi, với nhóm tuổi trên 60 và dưới 16 có tỷ lệ thấp hơn đáng kể. Nhóm trẻ (dưới 20) chiếm khoảng 7-10% tổng số hành khách. Phân bố này giúp điều chỉnh dịch vụ và chiến lược kinh doanh phù hợp hơn với từng nhóm tuổi.

Biến Type of travel

Việc mô tả mục đích khi di chuyển bằng máy bay mà hành khách thực hiện chủ yếu rất quan trọng, giúp cho chúng ta có thể hiểu rõ về hàng khách hơn. Như việc khách dùng dịch vụ dịch chuyển nhầm mục đích gì?

Nên bây giờ chúng tôi sẽ vẽ biểu đồ thống kê xem khách hàng tham gia dịch vụ nhắm mục đích làm việc gì

table(data$'Type of Travel')
## 
## Business travel Personal Travel 
##           18038            7938
table(data$'Type of Travel')/sum(table(data$'Type of Travel'))
## 
## Business travel Personal Travel 
##       0.6944102       0.3055898
b <- as.data.frame(table(data$'Type of Travel')) 
colnames(b) <- c("Type of Travel", "Count")
ggplot(b, aes(x = `Type of Travel`, y = Count, fill = `Type of Travel`)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  theme_minimal()

b$Percentage <- (b$Count / sum(b$Count)) * 100

ggplot(b, aes(x = "", y = Percentage, fill = `Type of Travel`)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Qua biểu đồ, ta thấy:

Số lượng khách hàng đi công tác là 18038 người (khoảng 69,44%)

Số lượng khách hàng đi vì công việc riêng là 7938 người ( khoảng 30,56%)

Như vậy số lượng khách hàng đi công tác nhiều hơn kh khách hàng đi vì công việc riêng là 10100 người (khoảng 38,88%)

Điều này cho thấy rằng hành khách sử dụng dịch vụ của hãng hàng không chủ yếu vì mục đích công việc hơn là hình thức di chuyển khác.Thông tin có thể cung cấp cho doanh nghiệp hàng không về việc phát triển và tối ưu hóa dịch vụ, tiếp thị và chiến lược phân phối. Các chính sách khuyến mãi, dịch vụ chăm sóc khách hàng và lựa chọn các tuyến bay có thể được điều chỉnh để phù hợp với nhu cầu chủ yếu của khách hàng là đi công tác.

Chẳng hạn, cung cấp các dịch vụ và tiện ích phù hợp với loại hình di chuyển của hành khách đi công tác như wifi, dịch vụ chăm sóc khách hàng trong khi họ đang bận công việc.

Biến Class

table(data$'Class')
## 
## Business      Eco Eco Plus 
##    12495    11564     1917
table(data$'Class')/sum(table(data$'Class'))
## 
##   Business        Eco   Eco Plus 
## 0.48102094 0.44518017 0.07379889
c <- as.data.frame(table(data$'Class')) 
colnames(c) <- c("Class", "Count")
c$Percentage <- ( c$Count / sum( c$Count)) * 100

ggplot(c, aes(x = "", y = Percentage, fill = `Class`)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.75), size = 3)

c <- as.data.frame(table(data$'Class')) 
colnames(c) <- c("Class", "Count")
ggplot(c, aes(x = Class, y = Count, fill = Class)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "Phân bố các hạng vé khách hàng dùng"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

Qua biểu đồ, ta thấy:

Số lượng khách hàng đăng ký hạng ghế thương gia chiếm số lượng lớn khoảng 12495 người (khoảng 48,1%)

Số lượng khách hàng đăng ký hạng ghế phổ thống là 11564 người ( khoảng 44,52%)

Số lượng khách hàng đăng ký hạng ghế cao cấp có ít người sử dụng nhất khoảng 1917 người (khoảng 7,38%)

Biến Customer Type

table(data$'Customer Type')
## 
## disloyal Customer    Loyal Customer 
##              4799             21177
table(data$'Customer Type')/sum(table(data$'Customer Type'))
## 
## disloyal Customer    Loyal Customer 
##         0.1847475         0.8152525
a <- as.data.frame(table(data$'Customer Type')) 
colnames(a) <- c("Customer Type", "Count")
ggplot(a, aes(x = `Customer Type`, y = Count, fill = `Customer Type`)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "Phân bố tệp khách hàng"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

a$Percentage <- (a$Count / sum(a$Count)) * 100

ggplot(a, aes(x = "", y = Percentage, fill = `Customer Type`)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Qua biểu đồ, ta thấy:

Số lượng khách hàng trung thành chiếm số lượng lớn khoảng 21177 người (khoảng 81,53%)

Số lượng khách hàng không trung thành là 4799 người ( khoảng 18,47%)

Như vậy số lượng khách trung thành nhiều hơn khách hàng không trung thành là 16348 người (khoảng 63,05%)

Biến Inflight wifi service

table(data$`Inflight wifi service`)/sum(table(data$`Inflight wifi service`))
## 
##          0          1          2          3          4          5 
## 0.03129812 0.17277487 0.24984601 0.24318602 0.19175393 0.11114105
# Dữ liệu
labels <- c("Không đánh giá","Rất tệ", "Tệ", "Bình thường", "Hài lòng", "Rất hài lòng")
values <- c(0.0313, 0.1728, 0.2498, 0.2432, 0.1918, 0.1111)
variable_name <- "Inflight.wifi.service"

# Tính tổng giá trị
total <- sum(values)

# Tính phần trăm cho mỗi mức độ
percentages <- values / total * 100

# Tạo dataframe
df <- data.frame(labels, values, percentages)

# Vẽ biểu đồ cột
library(ggplot2)
ggplot(df, aes(x = labels, y = percentages)) +
  geom_col(fill = '#4c72b0') +
  geom_text(aes(label = sprintf("%.2f%%", percentages)), vjust = -0.5, size = 4) +
  labs(x = "Mức độ đánh giá", y = "Phần trăm", title = paste0("Phân bố các mức độ đánh giá cho biến ", variable_name)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Nhận xét:

Khách hàng đánh giá ở mức bình thường về dịch vụ wifi chiếm tỷ trọng khá cao (24.32%). Điều này cho thấy rằng phần lớn hành khách có trải nghiệm ở mức tương đối. Họ có thể gặp một số vấn đề nhưng chúng không đủ nghiêm trọng để đánh giá tệ hơn.

Khách hàng đánh giá tệ về dịch vụ wifi chiếm tỷ trọng cao nhất (24.98%): cho thấy có một lượng lớn hành khách không hài lòng với dịch vụ wifi. Điều này có thể phản ánh các vấn đề nghiêm trọng về chất lượng kết nối, tốc độ hoặc độ ổn định của wifi.

Khách hàng đánh giá hài lòng về dịch vụ wifi chiếm tỷ trọng thấp hơn đánh giá bình thường và tệ nhưng vẫn có tỷ trọng khá cao (19.18%). Điều đó cho thấy dịch vụ có thể được đánh giá tốt về tốc độ và ổn định, nhưng vẫn có những yếu tố khác chưa đạt đến mức xuất sắc.

Khách hàng đánh giá rất hài lòng về dịch vụ wifi chiếm tỷ trọng không cao (11.11%). Điều này cho thấy rằng chỉ một phần nhỏ hành khách có trải nghiệm rất tốt với dịch vụ wifi. Dịch vụ này có thể rất tốt ở một số khía cạnh như tốc độ cao, ổn định, và dễ truy cập.

Khách hàng đánh giá rất tệ về dịch vụ wifi chiếm tỷ trọng khá cao (17.28%), cho thấy có nhiều hành khách gặp phải trải nghiệm rất không hài lòng với dịch vụ wifi. Những vấn đề như kết nối không ổn định, tốc độ chậm, hoặc không thể truy cập có thể là nguyên nhân chính.

Khách hàng không đánh giá về dịch vụ wifi chiếm tỷ trọng thấp nhất (3.13%). Nguyên nhân dẫn đến việc khách hàng không đánh giá tỷ trọng thấp có thể do họ không sử dụng dịch vụ hoặc không có ý kiến về chất lượng dịch vụ.

Biến baggage handling

table(data$`Baggage handling`)/sum(table(data$`Baggage handling`))
## 
##          1          2          3          4          5 
## 0.06894826 0.10937019 0.20091623 0.36102556 0.25973976
# Dữ liệu
labels <- c("Không đánh giá","Rất tệ", "Tệ", "Bình thường", "Hài lòng", "Rất hài lòng")
values <- c( 0,0.06895, 0.10937, 0.20092, 0.36103, 0.25974  )
variable_name <- "Baggage.handling"

# Tính toán tổng giá trị
total <- sum(values)

# Tính phần trăm cho mỗi mức độ
percentages <- values / total * 100

# Tạo dataframe
df <- data.frame(labels, values, percentages)

# Vẽ biểu đồ cột
library(ggplot2)
ggplot(df, aes(x = labels, y = percentages)) +
  geom_col(fill = '#4c72b0') +
  geom_text(aes(label = sprintf("%.2f%%", percentages)), vjust = -0.5, size = 4) +
  labs(x = "Mức độ đánh giá", y = "Phần trăm", title = paste0("Phân bố các mức độ đánh giá cho ", variable_name)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Khách hàng đánh giá bình thường về dịch vụ vận chuyển hành lý chiếm tỷ lệ khoảng 20.09%. Điều này cho thấy có một số khách hàng cảm thấy dịch vụ này chỉ ở mức trung bình, không nổi bật nhưng cũng không quá tệ.

Khách hàng đánh giá hài lòng về dịch vụ vận chuyển hành lý chiếm tỷ lệ cao nhất khoảng 36.10%. Điều này cho thấy rằng dịch vụ xử lý hành lý đang thực hiện tốt các chức năng cơ bản và đáp ứng kỳ vọng của phần lớn khách hàng.

Khách hàng không đánh giá về dịch vụ vận chuyển hành lý chiểm tỷ lệ 0% cho chúng ta biết rằng không có khách hàng nào bỏ qua việc đánh giá dịch vụ này.

Khách hàng đánh giá rất hài lòng về dịch vụ vận chuyển hành lý chiếm tỷ lệ khá cao khoảng 25.97%. Điều này cho thấy một số lượng đáng kể khách hàng rất hài lòng với dịch vụ. Khách hàng có thể rất hài lòng do dịch vụ nhanh chóng, nhân viên thân thiện và chuyên nghiệp, hoặc do việc xử lý các vấn đề phát sinh một cách hiệu quả.

Khách hàng đánh giá rất tệ về dịch vụ vận chuyển hành lý chiếm tỷ lệ khoảng 6.89% cho thấy có một nhóm nhỏ khách hàng rất không hài lòng với dịch vụ, có thể do các vấn đề nghiêm trọng như hành lý bị mất, hư hỏng nặng, hoặc thái độ phục vụ không tốt.

Khách hàng đánh giá tệ về dịch vụ vận chuyển hành lý chiếm tỷ lệ khoảng 10.94%, có thể do các vấn đề như thời gian chờ đợi lâu, hành lý bị hư hỏng nhẹ, hoặc dịch vụ không đáp ứng kỳ vọng.

Biến Inflight service

table(data$`Inflight service`)/sum(table(data$`Inflight service`))
## 
##            0            1            2            3            4            5 
## 7.699415e-05 6.844780e-02 1.097552e-01 1.931398e-01 3.610256e-01 2.675547e-01
# Dữ liệu
labels <- c("Không đánh giá","Rất tệ", "Tệ", "Bình thường", "Hài lòng", "Rất hài lòng")
values <- c( 7.699e-05, 6.845e-02, 1.098e-01, 1.931e-01, 3.610e-01, 2.676e-01   )
variable_name <- "Inflight.service"

# Tính toán tổng giá trị
total <- sum(values)

# Tính phần trăm cho mỗi mức độ
percentages <- values / total * 100

# Tạo dataframe
df <- data.frame(labels, values, percentages)

# Vẽ biểu đồ cột
library(ggplot2)
ggplot(df, aes(x = labels, y = percentages)) +
  geom_col(fill = '#4c72b0') +
  geom_text(aes(label = sprintf("%.2f%%", percentages)), vjust = -0.5, size = 4) +
  labs(x = "Mức độ đánh giá", y = "Phần trăm", title = paste0("Phân bố các mức độ đánh giá cho ", variable_name)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))# Dữ liệu

labels <- c("Không đánh giá","Rất tệ", "Tệ", "Bình thường", "Hài lòng", "Rất hài lòng")
values <- c( 7.699e-05, 6.845e-02, 1.098e-01, 1.931e-01, 3.610e-01, 2.676e-01   )
variable_name <- "Inflight.service"

Nhận xét: Biểu đồ phân bố các mức độ đánh giá cho dịch vụ trên chuyến bay cho thấy kết quả khá tích cực với hơn một nửa số hành khách đánh giá dịch vụ ở mức “Hài lòng” hoặc “Rất hài lòng”. Cụ thể, “Hài lòng” chiếm tỷ lệ cao nhất với 36.10%, tiếp theo là “Rất hài lòng” với 26.76%. Mức độ “Bình thường” cũng chiếm một tỷ lệ đáng kể là 19.31%, cho thấy có một phần hành khách có trải nghiệm trung bình. Tuy nhiên, có khoảng 17.82% hành khách đánh giá dịch vụ là “Tệ” hoặc “Rất tệ”, điều này cho thấy cần có những cải thiện để nâng cao trải nghiệm của những hành khách này. Tỷ lệ “Không đánh giá” là rất nhỏ (0.01%), cho thấy hầu hết hành khách đều có đánh giá về dịch vụ. Nhìn chung, dịch vụ trên chuyến bay nhận được nhiều phản hồi tích cực nhưng vẫn cần cải tiến để giảm tỷ lệ khách hàng không hài lòng.

Biến Cleanliness

table(data$Cleanliness)/sum(table(data$Cleanliness))
## 
##            0            1            2            3            4            5 
## 7.699415e-05 1.313135e-01 1.532569e-01 2.334848e-01 2.613951e-01 2.204727e-01
# Dữ liệu
labels <- c("Không đánh giá","Rất tệ", "Tệ", "Bình thường", "Hài lòng", "Rất hài lòng")
values <- c(  7.699e-05, 1.313e-01, 1.533e-01, 2.335e-01 ,2.614e-01, 2.205e-01   )
variable_name <- "Cleaneliness"

# Tính toán tổng giá trị
total <- sum(values)

# Tính phần trăm cho mỗi mức độ
percentages <- values / total * 100

# Tạo dataframe
df <- data.frame(labels, values, percentages)

# Vẽ biểu đồ cột
library(ggplot2)
ggplot(df, aes(x = labels, y = percentages)) +
  geom_col(fill = '#4c72b0') +
  geom_text(aes(label = sprintf("%.2f%%", percentages)), vjust = -0.5, size = 4) +
  labs(x = "Mức độ đánh giá", y = "Phần trăm", title = paste0("Phân bố các mức độ đánh giá cho ", variable_name)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Kết quả biểu đồ cho thấy phần lớn hành khách đánh giá mức độ vệ sinh của hãng hàng không là tích cực, với tỷ lệ “Hài lòng” và “Rất hài lòng” chiếm tổng cộng gần 50% (48.19%). Tuy nhiên, vẫn còn một tỷ lệ đáng kể hành khách cảm thấy không hài lòng, với mức độ “Tệ” và “Rất tệ” chiếm khoảng 28.46%. Điều này cho thấy có sự phân hóa rõ rệt trong mức độ hài lòng về mức độ vệ sinh. Dù phần lớn hành khách có cảm nhận tích cực về mức độ vệ sinh, vẫn còn một tỷ lệ không nhỏ cảm thấy không hài lòng. Điều này chỉ ra rằng, bên cạnh những phản hồi tích cực, hãng hàng không cần chú trọng cải thiện chất lượng vệ sinh để nâng cao trải nghiệm của hành khách, đặc biệt là những người có cảm nhận tiêu cực.

Biến Departure Delay in Mintutes

Trước khi phân tích biến Departure Delay in Mintutes, nhóm chúng tôi sẽ phân nhóm thành 3 nhóm thời gian khởi hành: trễ ngắn hạn (0-60 phút), trễ trung hạn (60-240 phút), trễ dài hạn (240 phút trở lên).

Biến Departure Delay in Mintutes thể hiện thời gian khởi hành trễ của chuyến bay.

data$dd <- cut(data$`Departure Delay in Minutes`, 
                   breaks = c(-2,0, 60, 240, Inf), 
                   labels = c("đúng giờ","ngắn hạn","trung hạn", "dài hạn"))

Bây giờ chúng tôi sẽ lập bảng tần số để thể hiện rõ nhóm thời gian khởi hành

table(data$dd)
## 
##  đúng giờ  ngắn hạn trung hạn   dài hạn 
##     14688      9552      1623       113
l <- prop.table(table(data$dd)) * 100
l
## 
##   đúng giờ   ngắn hạn  trung hạn    dài hạn 
## 56.5445026 36.7724053  6.2480751  0.4350169
library(ggplot2)
l <- as.data.frame(table(data$dd)) 
colnames(l) <- c("dd", "Count")
ggplot(l, aes(x = dd, y = Count, fill = dd)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "Phân bố các nhóm thời gian khởi hành"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

l$Percentage <- (l$Count / sum(l$Count)) * 100

ggplot(l, aes(x = "", y = Percentage, fill = dd)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Biểu đồ từ cuộc khảo sát cho thấy phân bố nhóm thời gian chuyến bay cất cánh muộn cho thấy rằng phần lớn các chuyến bay (56.54%) đến đúng giờ, với cất cánh muộn ngắn hạn là phổ biến thứ hai (36.77%). Các nhóm thời gian chuyến bay muộn trung hạn (6.25%) và dài hạn (0.44%) ít phổ biến hơn nhiều. Điều này cho thấy rằng, mặc dù chuyến bay cất cánh muộn trong thời gian ngắn hạn là khá phổ biến, chuyến bay cất cánh muộn trong thời gian dài hạn là tương đối hiếm.

Biến Arrival Delay in Mintutes

Trước khi phân tích biến Arrival Delay in Mintutes, nhóm chúng tôi sẽ phân nhóm thành 3 nhóm thời gian hạ cánh: trễ ngắn hạn (0-60 phút), trễ trung hạn (60-240 phút), trễ dài hạn (240 phút trở lên).

Biến Arrival Delay in Mintutes thể hiện thời gian hạ cánh trễ của chuyến bay.

data$ad <- cut(data$`Arrival Delay in Minutes`, 
                   breaks = c(-2, 0, 60, 240, Inf), 
                   labels = c("đúng giờ","ngắn hạn","trung hạn", "dài hạn"))

Bây giờ chúng tôi sẽ lập bảng tần số để thể hiện rõ nhóm thời gian hạ cánh

table(data$ad)
## 
##  đúng giờ  ngắn hạn trung hạn   dài hạn 
##     14677      9538      1651       110
k <- prop.table(table(data$dd)) * 100
k
## 
##   đúng giờ   ngắn hạn  trung hạn    dài hạn 
## 56.5445026 36.7724053  6.2480751  0.4350169
library(ggplot2)
k <- as.data.frame(table(data$ad)) 
colnames(k) <- c("ad", "Count")
ggplot(k, aes(x = ad, y = Count, fill = ad)) + 
  geom_bar(stat = "identity", position = "dodge") + geom_text(aes(label = Count), vjust = -0.3, size = 3.5) +
  labs(
    x = "", y = "Số lượng",
    title = "Phân bố nhóm thời gian hạ cánh"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "grey50"),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top"
  )

k$Percentage <- (k$Count / sum(k$Count)) * 100

ggplot(k, aes(x = "", y = Percentage, fill = ad)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y") +
  labs(title = "Tỷ lệ phần trăm", x = "", y = "") +
  theme_void() + 
  theme(legend.title = element_blank()) + 
  geom_text(aes(label = paste(round(Percentage, 2), "%")), 
            position = position_stack(vjust = 0.5), size = 4)

Biểu đồ phân bố nhóm thời gian hạ cánh cho thấy phần lớn các chuyến bay hạ cánh đúng giờ gồm 14677 người chiếm 56.5% hoặc trong thời gian ngắn hạn gồm 9538 người chiếm 36.72%. Số lượng chuyến bay có thời gian hạ cánh trung hạn gồm 1651 chiếm 6.36% và dài hạn gồm 110 người chiếm 0.42% là rất ít. Kết quả này phản ánh đa số chuyến bay đáp xuống đúng giờ hoặc sớm.

Thống kê mô tả 2 biến

Biến satisfaction và biến customer type

addmargins(table(data$satisfaction, data$`Customer Type`))
##                          
##                           disloyal Customer Loyal Customer   Sum
##   neutral or dissatisfied              3591          10982 14573
##   satisfied                            1208          10195 11403
##   Sum                                  4799          21177 25976
prop.table(table(data$satisfaction, data$`Customer Type`))
##                          
##                           disloyal Customer Loyal Customer
##   neutral or dissatisfied        0.13824299     0.42277487
##   satisfied                      0.04650447     0.39247767
library(ggplot2)
library(dplyr)
data %>% ggplot(aes(x = `satisfaction`, fill = `Customer Type`)) +
  geom_bar(position = "dodge") +
  geom_text(aes(label = scales::percent(after_stat(count / sum(count)), accuracy = 0.01)), 
            stat = "count", 
            position = position_dodge(width = 0.9), 
            vjust = -0.5, 
            color = 'red') +
  scale_fill_manual(values = c("Loyal Customer" = "blue", "disloyal Customer" = "green")) + labs( fill = 'Loại khách hàng',title = "Sự hài lòng về hãng hàng không ở từng loại khách hàng") + theme_minimal()

Từ kết quả trên, có thể thấy rằng khách hàng trung thành có mức độ hài lòng chiếm 39.35% cao hơn so với khách hàng không trung thành chiếm 4.65%. Cụ thể, tỷ lệ khách hàng hài lòng trong nhóm khách hàng trung thành cao hơn đáng kể so với nhóm khách hàng không trung thành. Điều này cho thấy rằng mức độ hài lòng có mối liên hệ chặt chẽ với sự trung thành của khách hàng, và việc nâng cao mức độ hài lòng của khách hàng có thể giúp tăng cường sự trung thành của họ đối với dịch vụ.

Biến satisfaction và biến class

addmargins(table(data$satisfaction, data$`Class`))
##                          
##                           Business   Eco Eco Plus   Sum
##   neutral or dissatisfied     3809  9322     1442 14573
##   satisfied                   8686  2242      475 11403
##   Sum                        12495 11564     1917 25976
prop.table(table(data$satisfaction, data$`Class`))
##                          
##                             Business        Eco   Eco Plus
##   neutral or dissatisfied 0.14663536 0.35886973 0.05551278
##   satisfied               0.33438559 0.08631044 0.01828611
library(ggplot2)
library(dplyr)
data %>% ggplot(aes(x = `satisfaction`, fill = `Class`)) +
  geom_bar(position = "dodge") +
  geom_text(aes(label = scales::percent(after_stat(count / sum(count)), accuracy = 0.01)), 
            stat = "count", 
            position = position_dodge(width = 0.9), 
            vjust = -0.5, 
            color = 'red') +
  scale_fill_manual(values = c("Business" = "blue", "Eco Plus" = "green", "Eco" = "brown")) + labs( fill = 'Hạng ghế',title = "Sự hài lòng về hãng hàng không ở từng loại hạng ghế") + theme_minimal()

Nhận xét: Từ kết quả biểu đồ trên có thể thấy phần lớn khách hàng không hài lòng ngồi ở hạng ghể thường (Eco) chiếm tỷ tệ cao nhất 35,89% so với hạng ghế thương gia (Business) chiếm 14,66% và hạng ghế cao cấp Eco Plus chiếm 5,55%. Mặc khác khách hàng hài lòng nhiều nhất khi ngồi ở hạng ghế thương gia chiếm 33,44% so với 2 hạng ghế còn lại là hạng ghế thường chiếm 8,63% và hạng ghế cao cấp 1,83%. Nhìn chung có thể thấy sự đánh giá của khách hàng hạng thương gia đối với hạng thương gia là tương đối cao. Còn số người đăng ký hạng ghế thường thì đánh giá trải nghiệm rất tốt.

Biến satisfaction và biến Inflight service

data$`Inflight service` = factor(data$`Inflight service`,
               levels = c(0, 1, 2, 3, 4, 5),
               labels = c("Không đánh giá","Rất tệ", "Tệ", "Bình thường", "Hài lòng", "Rất hài lòng"))
addmargins(table(data$`satisfaction`, data$`Inflight service`))
##                          
##                           Không đánh giá Rất tệ    Tệ Bình thường Hài lòng
##   neutral or dissatisfied              2   1244  1997        3785     4875
##   satisfied                            0    534   854        1232     4503
##   Sum                                  2   1778  2851        5017     9378
##                          
##                           Rất hài lòng   Sum
##   neutral or dissatisfied         2670 14573
##   satisfied                       4280 11403
##   Sum                             6950 25976
prop.table(table(data$satisfaction, data$`Inflight service`))
##                          
##                           Không đánh giá       Rất tệ           Tệ  Bình thường
##   neutral or dissatisfied   7.699415e-05 4.789036e-02 7.687866e-02 1.457114e-01
##   satisfied                 0.000000e+00 2.055744e-02 3.287650e-02 4.742840e-02
##                          
##                               Hài lòng Rất hài lòng
##   neutral or dissatisfied 1.876732e-01 1.027872e-01
##   satisfied               1.733523e-01 1.647675e-01
library(ggplot2)
library(dplyr)
data %>% ggplot(aes(x = `satisfaction`, fill = data$`Inflight service`)) +
  geom_bar(position = "dodge") +
  geom_text(aes(label = scales::percent(after_stat(count / sum(count)), accuracy = 0.01)), 
            stat = "count", 
            position = position_dodge(width = 0.9), 
            vjust = -0.5, 
            color = 'black') +
  scale_fill_manual(values = c("Không đánh giá" = "blue", "Rất tệ" = "green", "Tệ" = "brown","Bình thường"="purple", "Hài lòng"="pink", "Rất hài lòng"="grey" )) + labs( fill = 'Đánh giá',title = "Sự hài lòng về hãng hàng không về dịch vụ trên chuyến bay ") + theme_minimal()
## Warning: Use of `` data$`Inflight service` `` is discouraged.
## ℹ Use `Inflight service` instead.
## Use of `` data$`Inflight service` `` is discouraged.
## ℹ Use `Inflight service` instead.

Tỷ lệ khách hàng hài lòng khi tham gia dịch vụ hàng không về dịch vụ trên chuyến bay cảm thấy hài lòng chiếm tỉ lệ cao nhất là 17.34%, và rất hài lòng 16,48% cho thấy dịch vụ trên chuyến bay của hãng hàng không dành cho khách hàng cực kì tốt. Còn những khách hàng không hài lòng về dịch vụ trên chuyến bay chiếm tỉ lệ cao nhất là hài lòng 18,7%, và thấp nhất là rất tệ chiếm 4,79%. Chính vì thế việc về dịch vụ trên chuyến bay không ảnh hưởng gì nhiều đến sự hài lòng của khách hàng.

Biến satisfaction và biến Departure Delay in Mintutes

addmargins(table(data$`satisfaction`, data$dd))
##                          
##                           đúng giờ ngắn hạn trung hạn dài hạn   Sum
##   neutral or dissatisfied     7831     5637      1033      72 14573
##   satisfied                   6857     3915       590      41 11403
##   Sum                        14688     9552      1623     113 25976
prop.table(table(data$satisfaction, data$dd))
##                          
##                              đúng giờ    ngắn hạn   trung hạn     dài hạn
##   neutral or dissatisfied 0.301470588 0.217008007 0.039767478 0.002771789
##   satisfied               0.263974438 0.150716046 0.022713274 0.001578380
library(ggplot2)
library(dplyr)
data %>% ggplot(aes(x = `satisfaction`, fill = data$`dd`)) +
  geom_bar(position = "dodge") +
  geom_text(aes(label = scales::percent(after_stat(count / sum(count)), accuracy = 0.01)), 
            stat = "count", 
            position = position_dodge(width = 0.9), 
            vjust = -0.5, 
            color = 'black') +
  scale_fill_manual(values = c("đúng giờ" = "red","ngắn hạn" = "blue", "trung hạn" = "green", "dài hạn" = "brown")) + labs( fill = 'Thời gian cất cánh trễ',title = "Sự hài lòng về hãng hàng không đối với thời gian cất cánh ") + theme_minimal()
## Warning: Use of `data$dd` is discouraged.
## ℹ Use `dd` instead.
## Use of `data$dd` is discouraged.
## ℹ Use `dd` instead.

Biểu đồ cho thấy hành khách hài lòng thường có xu hướng gặp ít sự chậm trễ hơn, với tỷ lệ cao hơn trong nhóm “Đúng giờ” (26.40%) so với nhóm trung lập hoặc không hài lòng (30.15%). Ngược lại, hành khách trung lập hoặc không hài lòng có tỷ lệ cao hơn trong các nhóm thời gian chậm trễ, đặc biệt là nhóm “Ngắn hạn” (21.70% so với 15.07%). Điều này cho thấy sự chậm trễ, đặc biệt là trong khoảng thời gian ngắn hạn, ảnh hưởng tiêu cực đến sự hài lòng của hành khách.

Biến satisfaction và biến Arrival Delay in Mintutes

addmargins(table(data$`satisfaction`, data$ad))
##                          
##                           đúng giờ ngắn hạn trung hạn dài hạn   Sum
##   neutral or dissatisfied     7646     5782      1077      68 14573
##   satisfied                   7031     3756       574      42 11403
##   Sum                        14677     9538      1651     110 25976
prop.table(table(data$satisfaction, data$ad))
##                          
##                              đúng giờ    ngắn hạn   trung hạn     dài hạn
##   neutral or dissatisfied 0.294348630 0.222590083 0.041461349 0.002617801
##   satisfied               0.270672929 0.144595011 0.022097321 0.001616877
library(ggplot2)
library(dplyr)
data %>% ggplot(aes(x = `satisfaction`, fill = data$ad)) +
  geom_bar(position = "dodge") +
  geom_text(aes(label = scales::percent(after_stat(count / sum(count)), accuracy = 0.01)), 
            stat = "count", 
            position = position_dodge(width = 0.9), 
            vjust = -0.5, 
            color = 'black') +
  scale_fill_manual(values = c("đúng giờ" = "red","ngắn hạn" = "blue", "trung hạn" = "green", "dài hạn" = "brown")) + labs( fill = 'Thời gian cất cánh trễ',title = "Sự hài lòng về hãng hàng không đối với thời gian cất cánh ") + theme_minimal()
## Warning: Use of `data$ad` is discouraged.
## ℹ Use `ad` instead.
## Use of `data$ad` is discouraged.
## ℹ Use `ad` instead.

Biểu đồ phân tích mối quan hệ giữa mức độ hài lòng và thời gian đến trễ của chuyến bay cho thấy rằng hành khách hài lòng có xu hướng gặp ít sự chậm trễ hơn. Cụ thể, tỷ lệ hành khách hài lòng cao nhất là trong nhóm “Đúng giờ” (27.07%), giảm dần trong các nhóm thời gian đến trễ, với tỷ lệ thấp nhất trong nhóm “Dài hạn” (0.16%). Ngược lại, hành khách trung lập hoặc không hài lòng có tỷ lệ cao hơn trong các nhóm thời gian đến trễ, đặc biệt là nhóm “Ngắn hạn” (22.26%). Điều này phản ánh rằng sự chậm trễ, đặc biệt là trong khoảng thời gian ngắn hạn, ảnh hưởng tiêu cực đến sự hài lòng của hành khách.

Thống kê suy diễn

Kiểm tra tính độc lập của 2 biến

Biến satisfaction và biến customer type

chisq.test(table(data$satisfaction, data$`Customer Type`))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(data$satisfaction, data$`Customer Type`)
## X-squared = 837.25, df = 1, p-value < 2.2e-16

Giả thuyết:

H0: biến satisfaction và biến customer type độc lập

H1: biến satisfaction và biến customer type không độc lập

Mức ý nghĩa: α= 0.05

Ta có p_value < α, vậy bác bỏ giả thuyết H0.

Với mức ý nghĩa 5%, sự hài lòng của khách hàng có chịu sự ảnh hưởng của loại khách hàng.

Biến satisfaction và biến class

chisq.test(table(data$satisfaction, data$Class))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$satisfaction, data$Class)
## X-squared = 6435, df = 2, p-value < 2.2e-16

Giả thuyết:

H0: biến satisfaction và biến class độc lập

H1: biến satisfaction và biến class không độc lập

Mức ý nghĩa: α= 0.05

Ta có p_value < α, vậy bác bỏ giả thuyết H0.

Với mức ý nghĩa 5%, sự hài lòng của khách hàng có chịu sự ảnh hưởng của hạng ghế.

Biến satisfaction và biến Inflight service

chisq.test(table(data$satisfaction, data$`Inflight service`))
## Warning in chisq.test(table(data$satisfaction, data$`Inflight service`)):
## Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$satisfaction, data$`Inflight service`)
## X-squared = 2074.7, df = 5, p-value < 2.2e-16

Giả thuyết:

H0: biến satisfaction và biến Inflight service độc lập

H1: biến satisfaction và biến Inflight service không độc lập

Mức ý nghĩa: α= 0.05

Ta có p_value < α, vậy bác bỏ giả thuyết H0.

Với mức ý nghĩa 5%, sự hài lòng của khách hàng có chịu sự ảnh hưởng của dịch vụ cung cấp trên chuyến bay.

Biến satisfaction và biến Departure Delay in Mintutes

chisq.test(table(data$satisfaction, data$dd))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$satisfaction, data$dd)
## X-squared = 119.37, df = 3, p-value < 2.2e-16

Giả thuyết:

H0: biến satisfaction và biến Departure Delay in Mintutes độc lập

H1: biến satisfaction và biến Departure Delay in Mintutes không độc lập

Mức ý nghĩa: α= 0.05

Ta có p_value < α, vậy bác bỏ giả thuyết H0.

Với mức ý nghĩa 5%, sự hài lòng của khách hàng có chịu sự ảnh hưởng của thời gian cất cánh trễ của chuyến bay

Biến satisfaction và biến Arrival Delay in Mintutes

chisq.test(table(data$satisfaction, data$ad))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$satisfaction, data$ad)
## X-squared = 232.11, df = 3, p-value < 2.2e-16

Giả thuyết:

H0: biến satisfaction và biến Arrival Delay in Mintutes độc lập

H1: biến satisfaction và biến Arrival Delay in Mintutes không độc lập

Mức ý nghĩa: α= 0.05

Ta có p_value < α, vậy bác bỏ giả thuyết H0.

Với mức ý nghĩa 5%, sự hài lòng của khách hàng có chịu sự ảnh hưởng của thời gian hạ cánh trễ của chuyến bay

Relative risk và Odd ratio

Biến satisfaction và biến customer type

Relative risk

rr1 <- table(data$`Customer Type`,data$satisfaction)
addmargins(rr1)
##                    
##                     neutral or dissatisfied satisfied   Sum
##   disloyal Customer                    3591      1208  4799
##   Loyal Customer                      10982     10195 21177
##   Sum                                 14573     11403 25976
RelRisk(rr1)
## [1] 1.442938

Với kết quả RR = 1.442938, có thể thấy rằng trong nhóm khách không hài lòng, xác suất khách hàng không trung thành cao gấp 1.44 lần so với khách hàng trung thành.

Odd Ratio

addmargins(rr1)
##                    
##                     neutral or dissatisfied satisfied   Sum
##   disloyal Customer                    3591      1208  4799
##   Loyal Customer                      10982     10195 21177
##   Sum                                 14573     11403 25976
OddsRatio(rr1)
## [1] 2.759652

Với kết quả OR = 2.759652, Odd khách hàng trung thành không hài lòng gấp 2.76 lần Odd khách hàng trung thành hài lòng. Điều này có thể phản ánh rằng khách hàng có thể không hài lòng bởi chất lượng dịch vụ, cách phục vụ khách hàng,…

Biến satisfaction và biến class

Relative risk

rr2 <- matrix(c(3809, 10764,
               8686, 2717
               ),
             nrow = 2,
             byrow = TRUE,
             dimnames = list(c("Neutral or dissatisfied", "Satisfied"),
                             c("Business", "Eco")))
addmargins(rr2)
##                         Business   Eco   Sum
## Neutral or dissatisfied     3809 10764 14573
## Satisfied                   8686  2717 11403
## Sum                        12495 13481 25976
RelRisk(rr2)
## [1] 0.3431321

Với RR = 0.3431321, có thể thấy rằng trong nhóm khách ghế hạng thương gia, xác suất khách hàng không hài lòng cao gấp 0.34 lầnso với tỷ lệ hành khách hài lòng.

Odd Ratio

addmargins(rr2)
##                         Business   Eco   Sum
## Neutral or dissatisfied     3809 10764 14573
## Satisfied                   8686  2717 11403
## Sum                        12495 13481 25976
OddsRatio(rr2)
## [1] 0.1106897

Với kết quả OR = 0.1106897, odd khách hàng ghế hạng thương gia cảm cảm thấy hài lòng gấp 0.11 lần khách hàng ghế hạng thường cảm thấy hài lòng.

Biến satisfaction và biến Inflight service

Relative risk

rr3 <- matrix(c(3243, 11330,
               1388, 10015
               ),
             nrow = 2,
             byrow = TRUE,
             dimnames = list(c("Neutral or dissatisfied", "Satisfied"),
                             c("Tệ", "Tốt")))
addmargins(rr3)
##                           Tệ   Tốt   Sum
## Neutral or dissatisfied 3243 11330 14573
## Satisfied               1388 10015 11403
## Sum                     4631 21345 25976
RelRisk(rr3)
## [1] 1.828217

Với RR = 1.828217 có thể thấy rằng trong nhóm khách cảm thấy dịch vụ trên chuyến bay tệ, xác suất khách hàng không hài lòng cao gấp 1.82 lần khách hàng hài lòng.

Odd Ratio

addmargins(rr3)
##                           Tệ   Tốt   Sum
## Neutral or dissatisfied 3243 11330 14573
## Satisfied               1388 10015 11403
## Sum                     4631 21345 25976
OddsRatio(rr3)
## [1] 2.065278

Với kết quả OR = 2.065278, odd khách hàng hài lòng cảm thấy dịch vụ trên chuyến bay tệ gấp 2.07 lần hơn so với khách hàng hài lòng cảm thấy dịch vụ trên chuyến bay tốt.

Biến satisfaction và biến Departure Delay in Mintutes

Relative risk

rr4 <- matrix(c(7831, 6742,
               6857, 4546
               ),
             nrow = 2,
             byrow = TRUE,
             dimnames = list(c("Neutral or dissatisfied", "Satisfied"),
                             c("Đúng giờ", "Trễ giờ")))
addmargins(rr4)
##                         Đúng giờ Trễ giờ   Sum
## Neutral or dissatisfied     7831    6742 14573
## Satisfied                   6857    4546 11403
## Sum                        14688   11288 25976
RelRisk(rr4)
## [1] 0.8936207

Với kết quả RR = 0.8936207, có thể thấy rằng trong nhóm khách có chuyến bay cất cánh đúng giờ, xác suất khách hàng không hài lòng cao gấp 0.89 lần so với tỷ lệ hành khách hài lòng.

Odd Ratio

addmargins(rr4)
##                         Đúng giờ Trễ giờ   Sum
## Neutral or dissatisfied     7831    6742 14573
## Satisfied                   6857    4546 11403
## Sum                        14688   11288 25976
OddsRatio(rr4)
## [1] 0.7700586

Với kết quả OR = 0.7700586, odd khách hàng có chuyến bay cất cánh đúng giờ cảm thấy hài lòng gấp 0.77 lần hơn so với khách hàng có chuyến bay cất cánh trễ giờ cảm thấy hài lòng.

Biến satisfaction và biến Arrival Delay in Mintutes

Relative risk

rr5 <- matrix(c(7646, 6927,
               7031, 4372
               ),
             nrow = 2,
             byrow = TRUE,
             dimnames = list(c("Neutral or dissatisfied", "Satisfied"),
                             c("Đúng giờ", "Trễ giờ")))
addmargins(rr5)
##                         Đúng giờ Trễ giờ   Sum
## Neutral or dissatisfied     7646    6927 14573
## Satisfied                   7031    4372 11403
## Sum                        14677   11299 25976
RelRisk(rr5)
## [1] 0.8509173

Với kết quả RR = 0.8509173, có thể thấy rằng trong nhóm khách có chuyến bay hạ cánh đúng giờ, xác suất khách hàng không hài lòng cao gấp 0.85 lần so với hành khách hài lòng.

Odd Ratio

addmargins(rr5)
##                         Đúng giờ Trễ giờ   Sum
## Neutral or dissatisfied     7646    6927 14573
## Satisfied                   7031    4372 11403
## Sum                        14677   11299 25976
OddsRatio(rr5)
## [1] 0.6863603

Với kết quả OR = 0.6863603, odd khách hàng có chuyến bay hạ cánh đúng giờ cảm thấy hài lòng gấp 0.69 lần hơn so với khách hàng có chuyến bay hạ cánh trể giờ cảm thấy hài lòng.

Khoảng ước lượng Relative Risk

Biến satisfaction và biến customer type

epitab(rr1, method = 'riskratio', rev = 'c')
## $tab
##                    
##                     satisfied        p0 neutral or dissatisfied        p1
##   disloyal Customer      1208 0.2517191                    3591 0.7482809
##   Loyal Customer        10195 0.4814185                   10982 0.5185815
##                    
##                     riskratio     lower     upper     p.value
##   disloyal Customer 1.0000000        NA        NA          NA
##   Loyal Customer    0.6930305 0.6786825 0.7076819 5.4258e-193
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Kết quả trên cho thấy những khách hàng không trung thành cảm thấy hài lòng là 25.17% còn những khách hàng trung thành cảm thấy hài lòng là 48.14%. Tỷ lệ relative risk là khoảng 0.69, điều này có thể hiểu là nhóm khách hàng trung thành cảm thấy hài lòng chỉ bằng 0.69 lần so với nhóm khách hàng không trung thành. Khoảng ước lượng của relative risk là 0.6786825 đến 0.7076819 với mức độ tin cậy 95% và p-value là 5.4258e-193 cho thấy sự chênh lệch về sự hài lòng giữa 2 nhóm khách hàng là có sự chênh lệch đáng kể.

Biến satisfaction và biến class

epitab(rr2, method = 'riskratio', rev = 'c')
## $tab
##                           Eco        p0 Business        p1 riskratio    lower
## Neutral or dissatisfied 10764 0.7386262     3809 0.2613738   1.00000       NA
## Satisfied                2717 0.2382706     8686 0.7617294   2.91433 2.830575
##                            upper p.value
## Neutral or dissatisfied       NA      NA
## Satisfied               3.000562       0
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Kết quả trên cho thấy những khách hàng hạng ghế phổ thông cảm thấy hài lòng là 23.82% còn những khách hàng hạng ghế phổ thông cảm thấy không hài lòng là 73.86%. Tỷ lệ relative risk là khoảng 2.91, điều này có thể hiểu là nhóm khách hàng hạng ghế phổ thông cảm thấy hài lòng bằng 2.91 lần so với nhóm khách hàng hạng ghế phổ thông cảm thấy không hài lòng. Khoảng ước lượng của relative risk là 2.830575 đến 3.000562 với mức độ tin cậy 95% và p-value là 0 cho thấy sự chênh lệch về sự hài lòng giữa 2 nhóm khách hàng là có sự chênh lệch đáng kể.

Biến satisfaction và biến Inflight service

epitab(rr3, method = 'riskratio', rev = 'c')
## $tab
##                           Tốt        p0   Tệ        p1 riskratio     lower
## Neutral or dissatisfied 11330 0.7774652 3243 0.2225348 1.0000000        NA
## Satisfied               10015 0.8782776 1388 0.1217224 0.5469811 0.5162136
##                             upper       p.value
## Neutral or dissatisfied        NA            NA
## Satisfied               0.5795825 2.389286e-101
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Kết quả trên cho thấy những khách hàng cảm thấy dịch vụ trên chuyến bay tốt và cảm thấy hài lòng là 87.82% còn những khách hàng cảm thấy dịch vụ trên chuyến bay tốt và cảm thấy không hài lòng là 77.75%. Tỷ lệ relative risk là khoảng 0.54, điều này có thể hiểu là nhóm khách hàng cảm thấy dịch vụ trên chuyến bay tốt và cảm thấy hài lòng bằng 0.54 lần so với những khách hàng cảm thấy dịch vụ trên chuyến bay tốt và cảm thấy không hài lòng. Khoảng ước lượng của relative risk là 0.5162136 đến 0.5795825 với mức độ tin cậy 95% và p-value là 2.389286e-101 cho thấy sự chênh lệch về sự hài lòng giữa 2 nhóm khách hàng là có sự chênh lệch đáng kể.

Biến satisfaction và biến Departure Delay in Mintutes

epitab(rr4, method = 'riskratio', rev = 'c')
## $tab
##                         Trễ giờ        p0 Đúng giờ        p1 riskratio    lower
## Neutral or dissatisfied    6742 0.4626364     7831 0.5373636  1.000000       NA
## Satisfied                  4546 0.3986670     6857 0.6013330  1.119043 1.095547
##                            upper      p.value
## Neutral or dissatisfied       NA           NA
## Satisfied               1.143043 5.065551e-25
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Kết quả trên cho thấy những khách hàng có chuyến bay trễ giờ cảm thấy hài lòng là 39.86% còn những khách hàng có chuyến bay trễ giờ cảm thấy không hài lòng là 46.26%. Tỷ lệ relative risk là khoảng 1.11, điều này có thể hiểu là nhóm khách hàng ccó chuyến bay trễ giờ cảm thấy hài lòng bằng 1.11 lần so với những khách hàng có chuyến bay trễ giờ cảm thấy không hài lòng. Khoảng ước lượng của relative risk là 1.095547 đến 1.143043 với mức độ tin cậy 95% và p-value là 5.065551e-25 cho thấy sự chênh lệch đáng kể về sự hài lòng giữa 2 nhóm khách hàng.

Biến satisfaction và biến Arrival Delay in Mintutes

epitab(rr5, method = 'riskratio', rev = 'c')
## $tab
##                         Trễ giờ        p0 Đúng giờ        p1 riskratio    lower
## Neutral or dissatisfied    6927 0.4753311     7646 0.5246689  1.000000       NA
## Satisfied                  4372 0.3834079     7031 0.6165921  1.175202 1.150581
##                           upper      p.value
## Neutral or dissatisfied      NA           NA
## Satisfied               1.20035 6.664911e-50
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Kết quả trên cho thấy những khách hàng có chuyến bay hạ cánh trễ giờ cảm thấy hài lòng là 38.34% còn những khách hàng có chuyến bay hạ cánh trễ giờ cảm thấy không hài lòng là 47.53%. Tỷ lệ relative risk là khoảng 1.17, điều này có thể hiểu là nhóm khách hàng ccó chuyến bay hạ cánh trễ giờ cảm thấy hài lòng bằng 1.17 lần so với những khách hàng có chuyến bay hạ cánh trễ giờ cảm thấy không hài lòng. Khoảng ước lượng của relative risk là 1.150581 đến 1.20035 với mức độ tin cậy 95% và p-value là 6.664911e-50 cho thấy sự chênh lệch đáng kể về sự hài lòng giữa 2 nhóm khách hàng.

Khoảng ước lượng Odd ratio

Biến satisfaction và biến customer type

epitab(rr1, method = 'oddsratio',rev = 'c')
## $tab
##                    
##                     satisfied       p0 neutral or dissatisfied        p1
##   disloyal Customer      1208 0.105937                    3591 0.2464146
##   Loyal Customer        10195 0.894063                   10982 0.7535854
##                    
##                     oddsratio    lower     upper     p.value
##   disloyal Customer 1.0000000       NA        NA          NA
##   Loyal Customer    0.3623646 0.337683 0.3888502 5.4258e-193
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Odds ratio: 0.3623646 cho thấy khách hàng trung thành có khả năng hài lòng thấp hơn 64% so với khách hàng không trung thành. Điều này được xác nhận bởi p-value cực nhỏ (5.4258e-193) cho thấy kết quả này rất đáng tin cậy.

Phân tích chi tiết:

  • Khách hàng không trung thành có 10,6% hài lòng và 24,6% không hài lòng hoặc trung tính.

  • Khách hàng trung thành có 89,4% hài lòng và 75,4% không hài lòng hoặc trung tính.

Kết luận: Khách hàng trung thành có khả năng hài lòng thấp hơn đáng kể so với khách hàng không trung thành. Điều này cho thấy có vấn đề về sự hài lòng của khách hàng trung thành cần được giải quyết.

Biến satisfaction và biến class

epitab(rr2, method = 'oddsratio', rev = 'c')
## $tab
##                           Eco        p0 Business        p1 oddsratio    lower
## Neutral or dissatisfied 10764 0.7984571     3809 0.3048419  1.000000       NA
## Satisfied                2717 0.2015429     8686 0.6951581  9.034267 8.535776
##                            upper p.value
## Neutral or dissatisfied       NA      NA
## Satisfied               9.561869       0
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Odds ratio: 9.034267 cho thấy khách hàng thuộc nhóm “Business” có khả năng hài lòng cao hơn 9 lần so với khách hàng thuộc nhóm “Eco”. Điều này được xác nhận bởi p-value cực nhỏ (0) cho thấy kết quả này rất đáng tin cậy.

Phân tích chi tiết:

  • Khách hàng thuộc nhóm “Eco” có 79,8% không hài lòng hoặc trung tính và 20,2% hài lòng.

  • Khách hàng thuộc nhóm “Business” có 30,5% không hài lòng hoặc trung tính và 69,5% hài lòng.

Kết luận: Khách hàng thuộc nhóm “Business” có khả năng hài lòng cao hơn đáng kể so với khách hàng thuộc nhóm “Eco”. Điều này có thể cho thấy nhóm “Eco” có thể cần được chú ý nhiều hơn về mặt cải thiện sự hài lòng khách hàng

Biến satisfaction và biến Inflight service

epitab(rr3, method = 'oddsratio', rev = 'c')
## $tab
##                           Tốt        p0   Tệ        p1 oddsratio     lower
## Neutral or dissatisfied 11330 0.5308035 3243 0.7002807 1.0000000        NA
## Satisfied               10015 0.4691965 1388 0.2997193 0.4841963 0.4521971
##                           upper       p.value
## Neutral or dissatisfied      NA            NA
## Satisfied               0.51846 2.389286e-101
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Odds ratio: 0.4841963 cho thấy khách hàng đánh giá dịch vụ trên chuyến bay là “Tệ” có khả năng hài lòng thấp hơn 52% so với khách hàng đánh giá dịch vụ là “Tốt”. Điều này được xác nhận bởi p-value cực nhỏ (2.389286e-101) cho thấy kết quả này rất đáng tin cậy.

Phân tích chi tiết:

  • Khách hàng đánh giá dịch vụ là “Tốt” có 53,1% không hài lòng hoặc trung tính và 46,9% hài lòng.

  • Khách hàng đánh giá dịch vụ là “Tệ” có 70,0% không hài lòng hoặc trung tính và 30,0% hài lòng.

Kết luận: Khách hàng đánh giá dịch vụ trên chuyến bay là “Tệ” có khả năng hài lòng thấp hơn đáng kể so với khách hàng đánh giá dịch vụ là “Tốt”. Điều này cho thấy dịch vụ trên chuyến bay có ảnh hưởng rõ rệt đến mức độ hài lòng của khách hàng.

Biến satisfaction và biến Departure Delay in Mintutes

epitab(rr4, method = 'oddsratio', rev = 'c')
## $tab
##                         Trễ giờ        p0 Đúng giờ        p1 oddsratio    lower
## Neutral or dissatisfied    6742 0.5972714     7831 0.5331563  1.000000       NA
## Satisfied                  4546 0.4027286     6857 0.4668437  1.298603 1.235696
##                            upper      p.value
## Neutral or dissatisfied       NA           NA
## Satisfied               1.364712 5.065551e-25
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Odds ratio: 1.298603 cho thấy khách hàng đi chuyến bay đúng giờ có khả năng hài lòng cao hơn 30% so với khách hàng đi chuyến bay bị trễ giờ. Điều này được xác nhận bởi p-value cực nhỏ (5.065551e-25) cho thấy kết quả này rất đáng tin cậy.

Phân tích chi tiết:

  • Khách hàng đi chuyến bay bị trễ giờ có 59,7% không hài lòng hoặc trung tính và 40,3% hài lòng.

  • Khách hàng đi chuyến bay đúng giờ có 53,3% không hài lòng hoặc trung tính và 46,7% hài lòng.

Kết luận: Khách hàng đi chuyến bay đúng giờ có khả năng hài lòng cao hơn đáng kể so với khách hàng đi chuyến bay bị trễ giờ. Điều này cho thấy độ trễ giờ bay là một yếu tố quan trọng ảnh hưởng đến sự hài lòng của khách hàng.

Biến satisfaction và biến Arrival Delay in Mintutes

epitab(rr5, method = 'oddsratio', rev = 'c')
## $tab
##                         Trễ giờ        p0 Đúng giờ        p1 oddsratio    lower
## Neutral or dissatisfied    6927 0.6130631     7646 0.5209511  1.000000       NA
## Satisfied                  4372 0.3869369     7031 0.4790489  1.456961 1.386154
##                            upper      p.value
## Neutral or dissatisfied       NA           NA
## Satisfied               1.531384 6.664911e-50
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Odds ratio: 1.456961 cho thấy khách hàng đi chuyến bay đúng giờ có khả năng hài lòng cao hơn 46% so với khách hàng đi chuyến bay bị trễ giờ đến. Điều này được xác nhận bởi p-value cực nhỏ (6.664911e-50) cho thấy kết quả này rất đáng tin cậy.

Phân tích chi tiết:

  • Khách hàng đi chuyến bay bị trễ giờ đến có 61,3% không hài lòng hoặc trung tính và 38,7% hài lòng.

  • Khách hàng đi chuyến bay đúng giờ có 52,1% không hài lòng hoặc trung tính và 47,9% hài lòng.

Kết luận: Khách hàng đi chuyến bay đúng giờ có khả năng hài lòng cao hơn đáng kể so với khách hàng đi chuyến bay bị trễ giờ đến. Điều này cho thấy độ trễ giờ đến là một yếu tố quan trọng ảnh hưởng đến sự hài lòng của khách hàng.

Khoảng ước lượng tỷ lệ

Ước lượng tỷ lệ người có và không có hài lòng về hãng hàng không

p <- data[data$satisfaction == 'satisfied',]
prop.test(length(p$satisfaction), length(data$satisfaction))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$satisfaction) out of length(data$satisfaction), null probability 0.5
## X-squared = 386.61, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4329374 0.4450449
## sample estimates:
##         p 
## 0.4389821
p <- data[data$satisfaction == 'neutral or dissatisfied',]
prop.test(length(p$satisfaction), length(data$satisfaction))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$satisfaction) out of length(data$satisfaction), null probability 0.5
## X-squared = 386.61, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5549551 0.5670626
## sample estimates:
##         p 
## 0.5610179

Với độ tin cậy 95%, ta có tỷ lệ khách hàng hài lòng về hãng hàng không so với tổng thể nằm trong khoảng từ 43.3% đến 44.5%. Hay nói cách khác, tỷ lệ người không hài lòng về hãng hàng không sẽ chiếm khoảng từ 55.5% đến 56.7%.

Ước lượng tỷ lệ khách hàng ngồi ở các hạng ghế

p <- data[data$Class== 'Business',]
prop.test(length(p$Class), length(data$Class))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$Class) out of length(data$Class), null probability 0.5
## X-squared = 37.351, df = 1, p-value = 9.868e-10
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4749289 0.4871186
## sample estimates:
##         p 
## 0.4810209

Với độ tin cậy 95%, ta có tỷ lệ khách hàng ngồi ở hạng ghế thương gia so với tổng thể nằm trong khoảng từ 47.5% đến 48.7%.

p <- data[data$Class== 'Eco Plus',]
prop.test(length(p$Class), length(data$Class))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$Class) out of length(data$Class), null probability 0.5
## X-squared = 18872, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.07066330 0.07706129
## sample estimates:
##          p 
## 0.07379889

Với độ tin cậy 95%, ta có tỷ lệ khách hàng ngồi ở hạng ghế cao cấp so với tổng thể nằm trong khoảng từ 7.07% đến 7.71%.

p <- data[data$Class== 'Eco',]
prop.test(length(p$Class), length(data$Class))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$Class) out of length(data$Class), null probability 0.5
## X-squared = 312.03, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4391258 0.4512508
## sample estimates:
##         p 
## 0.4451802

Với độ tin cậy 95%, ta có tỷ lệ khách hàng ngồi ở hạng ghế thường so với tổng thể nằm trong khoảng từ 43.91% đến 45.13%.

Ước lượng tỷ lệ khách hàng trung thành hay không trung thành

p <- data[data$`Customer Type`== 'Loyal Customer',]
prop.test(length(p$`Customer Type`), length(data$`Customer Type`))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$`Customer Type`) out of length(data$`Customer Type`), null probability 0.5
## X-squared = 10325, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.8104671 0.8199444
## sample estimates:
##         p 
## 0.8152525
p <- data[data$`Customer Type`== 'disloyal Customer',]
prop.test(length(p$`Customer Type`), length(data$`Customer Type`))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$`Customer Type`) out of length(data$`Customer Type`), null probability 0.5
## X-squared = 10325, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1800556 0.1895329
## sample estimates:
##         p 
## 0.1847475

Với độ tin cậy 95%, ta có tỷ lệ khách hàng trung thành so với tổng thể nằm trong khoảng từ 81.05% đến 82%. Hay nói cách khác, tỷ lệ người không hài lòng về hãng hàng không sẽ chiếm khoảng từ 18% đến 18.95%.

Ước lượng tỷ lệ KH hài lòng dịch vụ trên chuyến bay

p <- data[data$`Inflight service`== 'Hài lòng',]
prop.test(length(p$`Inflight service`), length(data$`Inflight service`))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$`Inflight service`) out of length(data$`Inflight service`), null probability 0.5
## X-squared = 2006.2, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3551865 0.3669058
## sample estimates:
##         p 
## 0.3610256

Với độ tin cậy 95%, ta có tỷ lệ khách hàng hài lòng về dịch vụ trên chuyến bay so với tổng thể nằm trong khoảng từ 35.52% đến 36.69%.

Ước lượng tỷ lệ chuyến bay cất cánh đúng giờ

p <- data[data$dd== 'đúng giờ',]
prop.test(length(p$dd), length(data$dd))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$dd) out of length(data$dd), null probability 0.5
## X-squared = 444.76, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5593884 0.5714822
## sample estimates:
##        p 
## 0.565445

Với độ tin cậy 95%, ta có tỷ lệ chuyến bay cất cánh đúng giờ so với tổng thể nằm trong khoảng từ 55.93% đến 57.14%.

Ước lượng tỷ lệ chuyến bay hạ cánh đúng giờ

p <- data[data$ad== 'đúng giờ',]
prop.test(length(p$ad), length(data$ad))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(p$ad) out of length(data$ad), null probability 0.5
## X-squared = 439.03, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.5589643 0.5710595
## sample estimates:
##         p 
## 0.5650216

Với độ tin cậy 95%, ta có tỷ lệ chuyến bay hạ cánh đúng giờ so với tổng thể nằm trong khoảng từ 55.9% đến 57.11%.

Phân tích đa biến các yếu tố tác động đến sự hài lòng của khách hàng

Mô hình xác suất tuyến tính

# Chạy mô hình xác suất tuyến tính
data$satisfaction <- ifelse(data$satisfaction == "satisfied", 1, 0)
# Chạy mô hình xác suất tuyến tính
model1 <- glm(satisfaction ~ `Customer Type` + Class + `Inflight service`+ `Departure Delay in Minutes`+`Arrival Delay in Minutes`, data = data )

# Hiển thị kết quả mô hình
summary(model1)
## 
## Call:
## glm(formula = satisfaction ~ `Customer Type` + Class + `Inflight service` + 
##     `Departure Delay in Minutes` + `Arrival Delay in Minutes`, 
##     data = data)
## 
## Deviance Residuals: 
##      Min        1Q    Median        3Q       Max  
## -0.84501  -0.28743  -0.08723   0.26106   1.19585  
## 
## Coefficients:
##                                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                    -0.1808279  0.2919948  -0.619  0.53573    
## `Customer Type`Loyal Customer   0.1801179  0.0066611  27.040  < 2e-16 ***
## ClassEco                       -0.4515135  0.0054387 -83.018  < 2e-16 ***
## ClassEco Plus                  -0.4093591  0.0102043 -40.116  < 2e-16 ***
## `Inflight service`Rất tệ        0.6380948  0.2921079   2.184  0.02894 *  
## `Inflight service`Tệ            0.5955417  0.2920402   2.039  0.04144 *  
## `Inflight service`Bình thường   0.5773312  0.2920005   1.977  0.04803 *  
## `Inflight service`Hài lòng      0.7396498  0.2919643   2.533  0.01130 *  
## `Inflight service`Rất hài lòng  0.8390910  0.2919714   2.874  0.00406 ** 
## `Departure Delay in Minutes`    0.0004734  0.0002328   2.033  0.04204 *  
## `Arrival Delay in Minutes`     -0.0009983  0.0002327  -4.290 1.79e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for gaussian family taken to be 0.170433)
## 
##     Null deviance: 6397.3  on 25975  degrees of freedom
## Residual deviance: 4425.3  on 25965  degrees of freedom
## AIC: 27767
## 
## Number of Fisher Scoring iterations: 2

Phương Trình Hồi Quy:

π ̂= -0.1808+0.1801.Customer Type -0.4515.Class -0.4094.Class +0.6381.Inflight Service +0.5955×Inflight Service +0.5773×Inflight Service +0.7396×Inflight Service +0.8391×Inflight Service + 0.0005×Departure Delay in Minutes-0.0010×Arrival Delay in Minutes

Phương trình này cho phép bạn dự đoán sự hài lòng của khách hàng dựa trên các yếu tố như loại khách hàng, hạng ghế, chất lượng dịch vụ trên máy bay, và thời gian chậm trễ của chuyến bay.

Giải Thích:

Hệ số chặn: -0.1808 Đây là giá trị dự đoán của sự hài lòng khi tất cả các biến độc lập đều bằng 0.

Hệ số của Customer Type: 0.1801 cho thấy khách hàng trung thành có mức độ hài lòng cao hơn so với khách hàng không trung thành. Cụ thể, nếu khách hàng là trung thành, mức độ hài lòng dự đoán tăng thêm 0.1801 đơn vị so với khách hàng không trung thành.

Hệ số của Class (Eco): -0.4515 cho thấy hành khách chọn hạng ghế Economy (Eco) có mức độ hài lòng thấp hơn so với hạng ghế khác (ví dụ: Business hoặc First Class). Cụ thể, nếu khách hàng chọn hạng ghế Economy, mức độ hài lòng dự đoán giảm 0.4515 đơn vị so với hạng ghế khác.

Hệ số của Class (Eco Plus): -0.4094 cho thấy hành khách chọn hạng ghế Economy Plus (Eco Plus) có mức độ hài lòng thấp hơn so với hạng ghế khác. Cụ thể, nếu khách hàng chọn hạng ghế Economy Plus, mức độ hài lòng dự đoán giảm 0.4094 đơn vị so với hạng ghế khác.

Hệ số của Inflight Service (Very Poor): 0.6381 cho thấy mức độ hài lòng tăng thêm 0.6381 đơn vị nếu hành khách đánh giá dịch vụ trên máy bay là “Very Poor” so với dịch vụ cơ bản.

Hệ số của Inflight Service (Poor): 0.5955 cho thấy mức độ hài lòng tăng thêm 0.5955 đơn vị nếu hành khách đánh giá dịch vụ trên máy bay là “Poor” so với dịch vụ cơ bản.

Hệ số của Inflight Service (Average): 0.5773 cho thấy mức độ hài lòng tăng thêm 0.5773 đơn vị nếu hành khách đánh giá dịch vụ trên máy bay là “Average” so với dịch vụ cơ bản.

Hệ số của Inflight Service (Good): 0.7396 cho thấy mức độ hài lòng tăng thêm 0.7396 đơn vị nếu hành khách đánh giá dịch vụ trên máy bay là “Good” so với dịch vụ cơ bản.

Hệ số của Inflight Service (Very Good): 0.8391 cho thấy mức độ hài lòng tăng thêm 0.8391 đơn vị nếu hành khách đánh giá dịch vụ trên máy bay là “Very Good” so với dịch vụ cơ bản.

Hệ số của Departure Delay in Minutes: 0.0005 cho thấy mỗi phút chậm trễ khi khởi hành làm tăng mức độ hài lòng dự đoán lên 0.0005 đơn vị. Tuy nhiên, ảnh hưởng này là rất nhỏ và có thể không đáng kể trong thực tế.

Hệ số của Arrival Delay in Minutes: -0.0010 cho thấy mỗi phút hạ cánh chậm trễ khi đến làm giảm mức độ hài lòng dự đoán đi 0.0010 đơn vị. Mặc dù giá trị này nhỏ, nhưng nó cho thấy rằng sự chậm trễ khi đến có ảnh hưởng tiêu cực đến sự hài lòng của hành khách.

Mô hình logit

# Fit the logistic regression model
model2 <- glm(satisfaction ~ `Customer Type` + Class + `Inflight service`+ `Departure Delay in Minutes`+`Arrival Delay in Minutes`, family = binomial(link = "logit"), data = data)
# View the model summary
summary(model2)
## 
## Call:
## glm(formula = satisfaction ~ `Customer Type` + Class + `Inflight service` + 
##     `Departure Delay in Minutes` + `Arrival Delay in Minutes`, 
##     family = binomial(link = "logit"), data = data)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.9695  -0.7899  -0.4381   0.7226   2.8596  
## 
## Coefficients:
##                                  Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    -11.765320  84.476497  -0.139   0.8892    
## `Customer Type`Loyal Customer    1.195130   0.043273  27.618  < 2e-16 ***
## ClassEco                        -2.214556   0.032260 -68.648  < 2e-16 ***
## ClassEco Plus                   -1.927334   0.059139 -32.590  < 2e-16 ***
## `Inflight service`Rất tệ        11.179080  84.476509   0.132   0.8947    
## `Inflight service`Tệ            10.921410  84.476500   0.129   0.8971    
## `Inflight service`Bình thường   10.771445  84.476496   0.128   0.8985    
## `Inflight service`Hài lòng      11.779817  84.476491   0.139   0.8891    
## `Inflight service`Rất hài lòng  12.315701  84.476493   0.146   0.8841    
## `Departure Delay in Minutes`     0.002772   0.001435   1.932   0.0534 .  
## `Arrival Delay in Minutes`      -0.006018   0.001432  -4.203 2.63e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 35623  on 25975  degrees of freedom
## Residual deviance: 26635  on 25965  degrees of freedom
## AIC: 26657
## 
## Number of Fisher Scoring iterations: 9

Mô hình probit

# Fit the logistic regression model
model3 <- glm(satisfaction ~ `Customer Type` + Class + `Inflight service`+ `Departure Delay in Minutes`+`Arrival Delay in Minutes`, family = binomial(link = "probit"), data = data)
# View the model summary
summary(model3)
## 
## Call:
## glm(formula = satisfaction ~ `Customer Type` + Class + `Inflight service` + 
##     `Departure Delay in Minutes` + `Arrival Delay in Minutes`, 
##     family = binomial(link = "probit"), data = data)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.9791  -0.8016  -0.4460   0.7349   3.0302  
## 
## Coefficients:
##                                  Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    -4.8247549 25.8612297  -0.187   0.8520    
## `Customer Type`Loyal Customer   0.6562462  0.0245971  26.680  < 2e-16 ***
## ClassEco                       -1.3155285  0.0184706 -71.223  < 2e-16 ***
## ClassEco Plus                  -1.1630282  0.0345099 -33.701  < 2e-16 ***
## `Inflight service`Rất tệ        4.5753655 25.8612433   0.177   0.8596    
## `Inflight service`Tệ            4.4252886 25.8612340   0.171   0.8641    
## `Inflight service`Bình thường   4.3227983 25.8612288   0.167   0.8672    
## `Inflight service`Hài lòng      4.8855463 25.8612239   0.189   0.8502    
## `Inflight service`Rất hài lòng  5.2205784 25.8612255   0.202   0.8400    
## `Departure Delay in Minutes`    0.0016727  0.0008311   2.013   0.0441 *  
## `Arrival Delay in Minutes`     -0.0035541  0.0008294  -4.285 1.83e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 35623  on 25975  degrees of freedom
## Residual deviance: 26725  on 25965  degrees of freedom
## AIC: 26747
## 
## Number of Fisher Scoring iterations: 9

probit(P(satisfaction = 1)) = -4.8247549 + 0.6562462 * Customer TypeLoyal Customer - 1.3155285 * ClassEco - 1.1630282 * ClassEco Plus + 4.5753655 * Inflight serviceRất tệ + 4.4252886 * Inflight serviceTệ + 4.3227983 * Inflight serviceBình thường + 4.8855463 * Inflight serviceHài lòng + 5.2205784 * Inflight serviceRất hài lòng + 0.0016727 * Departure Delay in Minutes - 0.0035541 * Arrival Delay in Minutes

Hệ số của Customer Type (1.1951 cho thấy Khách hàng trung thành có chỉ số probit 1.1951 so với khách hàng không trung thành. Điều này có nghĩa là khách hàng trung thành có khả năng hài lòng cao hơn đáng kể và trong điều kiện các yếu tố khác không đổi

Hệ số của Class (Eco): -2.2146 cho thấy Hành khách chọn hạng ghế Economy (Eco) có chỉ số probit của sự hài lòng giảm đi 2.2146 so với hạng ghế khác. Điều này chỉ ra rằng hành khách chọn hạng ghế Economy có khả năng không hài lòng cao hơn và trong điều kiện các yếu tố khác không đổi

Hệ số của Class (Eco Plus): -1.9273 cho thấy: Hành khách chọn hạng ghế Economy Plus (Eco Plus) có log odds của sự hài lòng giảm đi 1.9273 so với hạng ghế khác. Điều này chỉ ra rằng hành khách chọn hạng ghế Economy Plus có khả năng không hài lòng cao hơn và trong điều kiện các yếu tố khác không đổi

Hệ số của Inflight Service (Very Poor): 11.1791 cho thấy chỉ số probit của sự hài lòng tăng thêm 11.1791 khi dịch vụ trên máy bay được đánh giá là “Very Poor” và trong điều kiện các yếu tố khác không đổi . và trong điều kiện các yếu tố khác không đổi .Mặc dù hệ số này cao, nó có thể không có ý nghĩa thực tế do giá trị p cao (0.8947).

Hệ số của Inflight Service (Poor): 10.9214 cho thấy chỉ số probit của sự hài lòng tăng thêm 10.9214 khi dịch vụ trên máy bay được đánh giá là “Poor”. và trong điều kiện các yếu tố khác không đổi Tương tự như trên, giá trị p cao (0.8971) cho thấy hệ số này không có ý nghĩa thống kê.

Hệ số của Inflight Service (Average): 10.7714 cho thấy chỉ số probit của sự hài lòng tăng thêm 10.7714 khi dịch vụ trên máy bay được đánh giá là “Average”. và trong điều kiện các yếu tố khác không đổi Giá trị p cao (0.8985) cho thấy hệ số này không có ý nghĩa thống kê.

Hệ số của Inflight Service (Good): 11.7798 cho thấy chỉ số probit của sự hài lòng tăng thêm 11.7798 khi dịch vụ trên máy bay được đánh giá là “Good”. Và trong điều kiện các yếu tố khác không đổi Giá trị p cao (0.8891) cho thấy hệ số này không có ý nghĩa thống kê.

Hệ số của Inflight Service (Very Good): 12.3157 cho thấy chỉ số probit của sự hài lòng tăng thêm 12.3157 khi dịch vụ trên máy bay được đánh giá là “Very Good”. và trong điều kiện các yếu tố khác không đổi Giá trị p cao (0.8841) cho thấy hệ số này không có ý nghĩa thống kê.

Các tiêu chí đánh giá mô hình

Chỉ số AIC

Chỉ số AIC mô hình xác suất tuyến tính

AIC(model1)
## [1] 27767.42

Chỉ số AIC mô hình logit

AIC(model2)
## [1] 26656.64

Chỉ số AIC mô hình probit

AIC(model3)
## [1] 26746.69

Kết quả trên cho chúng ta thấy rằng mô hình logit sẽ hiệu quả hơn các mô hình probit và xác suất tuyến tính. Bởi vì chỉ số AIC của logit đạt thấp nhất là 26656.64, trong khi đó của mô hình probit là 26746.69 và kém hiệu quả nhất của mô hình xác suất tuyến tính với AIC là 27767.42.

Brier Score

Brier Score mô hình xác suất tuyến tính

BrierScore(model1)
## [1] 0.1703608

Brier Score mô hình logit

BrierScore(model2)
## [1] 0.1665815

Brier Score mô hình probit

BrierScore(model3)
## [1] 0.1676092

Dựa vào kết quả của hệ số Brier Score chúng tôi cho rằng mô hình logit vẫn sẽ là lựa chọn tốt nhất vì giá trị BrierScore thấp hơn đạt 0.1665815, kết quả này tương đồng với phương pháp AIC. Trong khi đó hệ số Brier Score của mô hình probit là 0.1676092. Brier Score của hai mô hình khá thấp, mô hình xác suất tuyến tính kém hiệu quả nhất với hệ số Brier Score là 0.1703608.

Ma trận nhầm lẫn

Ma trận nhầm lẫn mô hình xác suất tuyến tính

Conf(table(predict(model1, type="response") >=0.5,model1$data$satisfaction == '1'))
## 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction FALSE  TRUE
##      FALSE 11005  2795
##      TRUE   3568  8608
## 
##                 Total n : 25'976
##                Accuracy : 0.7550
##                  95% CI : (0.7498, 0.7602)
##     No Information Rate : 0.5610
##     P-Value [Acc > NIR] : < 2.2e-16
## 
##                   Kappa : 0.5063
##  Mcnemar's Test P-Value : < 2.2e-16
## 
##             Sensitivity : 0.7552
##             Specificity : 0.7549
##          Pos Pred Value : 0.7975
##          Neg Pred Value : 0.7070
##              Prevalence : 0.5610
##          Detection Rate : 0.5313
##    Detection Prevalence : 0.4237
##       Balanced Accuracy : 0.7550
##          F-val Accuracy : 0.7757
##      Matthews Cor.-Coef : 0.5072
## 
##        'Positive' Class : FALSE

Từ kết quả ma trận nhầm lẫn của mô hình xác suất tuyến tính cho rằng có 11005 số lần mô hình dự đoán đúng là số khách hàng không hài lòng. Tuy nhiên có 2795 lần mô hình dự đoán sai đối với số khách hàng không hài lòng và khoảng 3568 lần mô hình dự đoán sai số khách hàng hài lòng. Số lần mô hình dự đoán đúng số khách hàng hài lòng là 8608 lần . Kết quả cũng chỉ ra tỷ lệ mô hình dự đoán đúng là 75.50%

Ma trận nhầm lẫn mô hình logit

Conf(table(predict(model2, type="response") >=0.5,model2$data$satisfaction == '1'))
## 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction FALSE  TRUE
##      FALSE 11263  2954
##      TRUE   3310  8449
## 
##                 Total n : 25'976
##                Accuracy : 0.7589
##                  95% CI : (0.7536, 0.7640)
##     No Information Rate : 0.5610
##     P-Value [Acc > NIR] : < 2.2e-16
## 
##                   Kappa : 0.5121
##  Mcnemar's Test P-Value : 7.28e-06
## 
##             Sensitivity : 0.7729
##             Specificity : 0.7409
##          Pos Pred Value : 0.7922
##          Neg Pred Value : 0.7185
##              Prevalence : 0.5610
##          Detection Rate : 0.5473
##    Detection Prevalence : 0.4336
##       Balanced Accuracy : 0.7569
##          F-val Accuracy : 0.7824
##      Matthews Cor.-Coef : 0.5123
## 
##        'Positive' Class : FALSE

Từ kết quả ma trận nhầm lẫn của mô hình logit cho rằng có 11263 số lần mô hình dự đoán đúng là số khách hàng không hài lòng. Tuy nhiên có 2954 lần mô hình dự đoán sai đối với số khách hàng không hài lòng và khoảng 3310 lần mô hình dự đoán sai số khách hàng hài lòng. Số lần mô hình dự đoán đúng số khách hàng hài lòng là 8449 lần . Kết quả cũng chỉ ra tỷ lệ mô hình dự đoán đúng là 75.89%.

Ma trận nhầm lẫn mô hình probit

Conf(table(predict(model3, type="response") >=0.5,model3$data$satisfaction == '1'))
## 
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction FALSE  TRUE
##      FALSE 11121  2876
##      TRUE   3452  8527
## 
##                 Total n : 25'976
##                Accuracy : 0.7564
##                  95% CI : (0.7511, 0.7616)
##     No Information Rate : 0.5610
##     P-Value [Acc > NIR] : < 2.2e-16
## 
##                   Kappa : 0.5081
##  Mcnemar's Test P-Value : 4.89e-13
## 
##             Sensitivity : 0.7631
##             Specificity : 0.7478
##          Pos Pred Value : 0.7945
##          Neg Pred Value : 0.7118
##              Prevalence : 0.5610
##          Detection Rate : 0.5388
##    Detection Prevalence : 0.4281
##       Balanced Accuracy : 0.7555
##          F-val Accuracy : 0.7785
##      Matthews Cor.-Coef : 0.5086
## 
##        'Positive' Class : FALSE

Từ kết quả ma trận nhầm lẫn của mô hình probit cho rằng có 11121 số lần mô hình dự đoán đúng là số khách hàng không hài lòng. Tuy nhiên có 2876 lần mô hình dự đoán sai đối với số khách hàng không hài lòng và khoảng 3452 lần mô hình dự đoán sai số khách hàng hài lòng. Số lần mô hình dự đoán đúng số khách hàng hài lòng là 8527 lần . Kết quả cũng chỉ ra tỷ lệ mô hình dự đoán đúng là 75.89%.

LS0tDQp0aXRsZTogIlRp4buDdSBsdeG6rW4gUFRETMSQVCINCmF1dGhvcjogIlBoYcyjbSBUcsOizIBuIFBodcyBYyDDgm4sIFBoYW4gxJDhuq9jIEtow6FuaCBUb8OgbiwgTmd1eeG7hW4gS2jDoW5oIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJUg6JU06JVMsICVkIC0gJW0gLSAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogIHBkZl9kb2N1bWVudDoNCiAgICBleHRyYV9kZXBlbmRlbmNpZXM6DQogICAgICB2aWV0bmFtOiB1dGY4DQogICAgdG9jOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCmdlb21ldHJ5Og0KICAgICAgLSBpbm5lcj0zY20NCiAgICAgIC0gb3V0ZXI9NGNtDQogICAgICAtIHRvcD0zY20NCiAgICAgIC0gYm90dG9tPTRjbQ0KICAgICAgLSBoZWFkc2VwPTIycHQNCiAgICAgIC0gaGVhZGhlaWdodD0xMXB0DQogICAgICAtIGZvb3Rza2lwPTMzcHQNCiAgICAgIC0gaWdub3JlaGVhZA0KICAgICAgLSBpZ25vcmVmb290DQogICAgICAtIGhlaWdodHJvdW5kZWQNCi0tLQ0KYGBge2NzcyxlY2hvID0gRkFMU0V9DQpoMSB7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBmb250LXNpemU6IDMycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkDQogIH0NCg0KaDIgew0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC1zaXplOiAyOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiANCn0NCg0KaDMgew0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zdHlsZTogaXRhbGljOw0KfQ0KDQpoNCB7Zm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC1zdHlsZTogaXRhbGljfQ0KDQpib2R5IHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGZvbnQtc2l6ZTogMThweDsNCiAgDQp9DQpwOm5vdChoMSk6bm90KGgyKTpub3QoaDMpOm5vdChoNCk6bm90KGg1KSB7DQogIHRleHQtaW5kZW50OiAyZW07fQ0KcCB7DQogIHRleHQtYWxpZ246IGp1c3RpZnk7DQogIH0NCi50b2NpZnktaGVhZGVyIHsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQoNCmBgYA0KIyBDSMavxqBORyAxOiBU4buUTkcgUVVBTiBOR0hJw4pOIEPhu6hVDQoNCiMjIDEuMSDEkOG6t3QgduG6pW4gxJHhu4EgDQoNClRyb25nIGLhu5FpIGPhuqNuaCBj4bqhbmggdHJhbmggbmfDoHkgY8Ogbmcga2jhu5FjIGxp4buHdCBj4bunYSBuZ8OgbmggaMOgbmcga2jDtG5nLCBjaOG6pXQgbMaw4bujbmcgZOG7i2NoIHbhu6UgdHLhu58gdGjDoG5oIHnhur91IHThu5EgdGhlbiBjaOG7kXQgcXV54bq/dCDEkeG7i25oIHPhu7EgaMOgaSBsw7JuZyB2w6AgbMOybmcgdHJ1bmcgdGjDoG5oIGPhu6dhIGtow6FjaCBow6BuZy4gQ8OhYyBow6NuZyBow6BuZyBraMO0bmcga2jDtG5nIGNo4buJIGPhuqFuaCB0cmFuaCB24buBIGdpw6EgY+G6oyB2w6AgdHV54bq/biBiYXkgbcOgIGPDsm4gcGjhuqNpIGtow7RuZyBuZ+G7q25nIG7Dom5nIGNhbyBjaOG6pXQgbMaw4bujbmcgZOG7i2NoIHbhu6UgxJHhu4MgdGh1IGjDunQgdsOgIGdp4buvIGNow6JuIGtow6FjaCBow6BuZy4gVmnhu4djIHBow6JuIHTDrWNoIHThu6sgZOG7ryBsaeG7h3UgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IHbhu4EgdHLhuqNpIG5naGnhu4dtIGThu4tjaCB24bulIGjDoG5nIGtow7RuZyBuaMawIGxv4bqhaSBow6xuaCBkdSBs4buLY2gsIHPhu7Egc+G6oWNoIHPhur0sIHjhu60gbMO9IGjDoG5oIGzDvSB2w6AgdHLhuqNpIG5naGnhu4dtIHRyw6puIGNodXnhur9uIGJheSBraMO0bmcgY2jhu4kgZ2nDunAgaMOjbmcgaMOgbmcga2jDtG5nIGhp4buDdSByw7UgaMahbiBuaHUgY+G6p3UgdsOgIG1vbmcgbXXhu5FuIGPhu6dhIGtow6FjaCBow6BuZyBtw6AgY8OybiDEkeG7i25oIGjGsOG7m25nIGNobyBjw6FjIGPhuqNpIHRp4bq/biBk4buLY2ggduG7pSB0cm9uZyB0xrDGoW5nIGxhaS5DaMOsbmggdsOsIHRo4bq/LCDhu58gYsOgaSBuZ2hpw6puIGPhu6l1IG7DoHkgbmjhurFtIHBow6JuIHTDrWNoIGPDoWMgeeG6v3UgdOG7kSDhuqNuaCBoxrDhu59uZyDEkeG6v24gc+G7sSBow6BpIGzDsm5nIGPhu6dhIGjDoG5oIGtow6FjaCwgdOG7qyDEkcOzIMSR4buBIHh14bqldCBjw6FjIGJp4buHbiBwaMOhcCBuw6JuZyBjYW8gY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulIGPhu6dhIGjDo25nIGjDoG5nIGtow7RuZy4NCg0KIyMgMS4yIE3hu6VjIHRpw6p1IGLDoGkgbmdoacOqbiBj4bupdQ0KDQpN4bulYyB0acOqdSBj4bunYSBj4bunYSBiw6BpIG5naGnDqm4gY+G7qXUgbOG6p24gbsOgeSBjaMO6bmcgdMO0aSBz4bq9IMSRw6FuaCBnacOhIG3hu6ljIMSR4buZIGjDoGkgbMOybmcgY+G7p2EgaMOgbmgga2jDoWNoIGPhu6dhIGjDo25nIGjDoG5nIGtow7RuZyBk4buxYSB0csOqbiBi4buZIGThu68gbGnhu4d1IHbhu4Egc+G7sSBow6BpIGzDsm5nIGPhu6dhIGjDoG5oIGtow6FjaC4gTmdoacOqbiBj4bupdSB04bqtcCB0cnVuZyB2w6BvIGPDoWMgeeG6v3UgdOG7kSBuaMawIGdp4bubaSB0w61uaCwgxJHhu5kgdHXhu5VpLCBsb+G6oWkga2jDoWNoIGjDoG5nLCBsb+G6oWkgaMOsbmggZHUgbOG7i2NoLCDEkeG7mSB0cuG7hSB4deG6pXQgcGjDoXQgdsOgIMSR4bq/biwga2hv4bqjbmcgY8OhY2ggYmF5LCB2w6AgY8OhYyB0aeG7h24gw61jaCBsacOqbiBxdWFuIMSR4bq/biB0aOG7nWkgZ2lhbi4gTeG7pWMgxJHDrWNoIGzDoCBwaMOibiB0w61jaCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGPDoWMgeeG6v3UgdOG7kSBuw6B5IHbDoCBt4bupYyDEkeG7mSBow6BpIGzDsm5nIGPhu6dhIGjDoG5oIGtow6FjaCwgdOG7qyDEkcOzIMSRxrBhIHJhIG5o4buvbmcgbmjhuq1uIMSR4buLbmggdsOgIMSR4buBIHh14bqldCBj4bqjaSB0aGnhu4duIMSR4buDIG7Dom5nIGNhbyB0cuG6o2kgbmdoaeG7h20gY+G7p2EgaMOgbmgga2jDoWNoIHRyb25nIHF1w6EgdHLDrG5oIHPhu60gZOG7pW5nIGThu4tjaCB24bulIGjDoG5nIGtow7RuZy4NCg0KIyMgMS4zIFBoxrDGoW5nIHBow6FwIG5naGnDqm4gY+G7qXUgDQoNClRodSB0aOG6rXAgZOG7ryBsaeG7h3UsIFBow6JuIHTDrWNoIGto4bqjbyBzw6F0IHRy4bqjaSBuZ2hp4buHbSBk4buLY2ggduG7pSBow6BuZyBraMO0bmcgY+G7p2Ega2jDoWNoIGjDoG5nIHRoYW0gZ2lhIGto4bqjbyBzw6F0IGLhurFuZyBjw6FjaCBz4butIGThu6VuZyBwaMawxqFuZyBwaMOhcCBtw7QgaMOsbmggaOG7k2kgcXV5LCBjw6FjIHRo4buRbmcga8OqIG3hu5UgdOG6oyDEkeG7gyDEkW8gbMaw4budbmcgYmnhur9uIMSR4buLbmggdMOtbmgsIMSR4buLbmggbMaw4budaSBkxrDhu5tpIGThuqFuZyDEkeG6v20gc+G7kSBs4bqnbiB4deG6pXQgaGnhu4duIGPDoWMgYmnhur9uLiB2w6AgbmdoacOqbiBj4bupdSBt4buRaSB0xrDGoW5nIHF1YW4gZ2nhu69hIGNow7puZy4NCg0KIyMgMS40IMOdIG5naMSpYSBuZ2hpw6puIGPhu6l1DQoNCkvhur90IHF14bqjIG7DoHkgZ2nDunAgY8OhYyBjw7RuZyB0eSBow6BuZyBraMO0bmcgdOG6rXAgdHJ1bmcgY+G6o2kgdGhp4buHbiBjw6FjIGThu4tjaCB24bulIHF1YW4gdHLhu41uZyDEkeG7gyBuw6JuZyBjYW8gdHLhuqNpIG5naGnhu4dtIGtow6FjaCBow6BuZywgZHV5IHRyw6wgc+G7sSB0cnVuZyB0aMOgbmggdsOgIHRodSBow7p0IHRow6ptIGtow6FjaCBow6BuZyBt4bubaS4gxJBp4buBdSBuw6B5IGtow7RuZyBjaOG7iSBjw7Mgw70gbmdoxKlhIHRo4buxYyB0aeG7hW4gdHJvbmcgcXXhuqNuIGzDvSB2w6AgdGnhur9wIHRo4buLIG3DoCBjw7JuIMSRw7NuZyBnw7NwIHbDoG8gY8ahIHPhu58gZOG7ryBsaeG7h3Uga2hvYSBo4buNYyB24buBIHPhu7EgaMOgaSBsw7JuZyB2w6AgdHJ1bmcgdGjDoG5oIGPhu6dhIGtow6FjaCBow6BuZywgbmdvw6BpIHJhIGPDsyB0aOG7gyBwaMOhdCB0cmnhu4NuIHRow6ptIHRyb25nIGzEqW5oIHbhu7FjIG5nw6BuaCBuZ2jhu4EgaMOgbmcga2jDtG5nLg0KDQojIENIxq/GoE5HIDI6IFThu5RORyBRVUFOIELhu5ggROG7riBMSeG7hlUgQUlSTElORSBQQVNTRU5HRVIgU0FUSVNGQUNUSU9ODQoNCiMjIDIuMSBHaeG7m2kgdGhp4buHdSBi4buZIGThu68gbGnhu4d1IEFpcmxpbmUgUGFzc2VuZ2VyIFNhdGlzZmFjdGlvbg0KDQpDaMO6bmcgdMO0aSBz4bq9IGdp4bubaSB0aGnhu4d1IGLhu5kgZOG7ryBsaeG7h3Ug4oCcQWlybGluZSBQYXNzZW5nZXIgU2F0aXNmYWN0aW9u4oCdLCDEkcaw4bujYyB0aHUgdGjhuq1wIHThu6sgdHJhbmcgS2FnZ2xlLg0KDQpC4buZIGThu68gbGnhu4d1IEFpcmxpbmUgUGFzc2VuZ2VyIFNhdGlzZmFjdGlvbiBjdW5nIGPhuqVwIEto4bqjbyBzw6F0IHbhu4EgZOG7i2NoIHbhu6UgaMOgbmcga2jDtG5nIGPhu6dhIGtow6FjaCBow6BuZyB04burIGjGoW4gMjUuMDAwIHRoYW0gZ2lhIGto4bqjbyBzw6F0IMSR4buRaSB24bubaSBow6NuZyBow6NuZyBraMO0bmcsIGJhbyBn4buTbSB0aMO0bmcgdGluIGLhu5Ugc3VuZyB24buBIHThu6tuZyBow6BuaCBraMOhY2gsIGNodXnhur9uIGJheSB2w6AgbG/huqFpIGjDrG5oIGRpIGNodXnhu4NuIGPhu6dhIGjhu40sIGPFqW5nIG5oxrAgxJHDoW5oIGdpw6EgY8OhYyB54bq/dSB04buRIGtow6FjIG5oYXUgbmjGsCBt4bupYyDEkeG7mSBz4bqhY2ggc+G6vSB0cm9uZyBtw6F5IGJheSwgc+G7sSB0aG/huqNpIG3DoWksIGThu4tjaCB24bulIHbDoCB0cuG6o2kgbmdoaeG7h20gdOG7lW5nIHRo4buDLiBE4buxYSB2w6BvIG5o4buvbmcgdGjDtG5nIHRpbiBuw6B5IGNow7puZyB0w7RpIGPDsyB0aOG7gyBwaMOibiB0w61jaCBjw6FjIG3hu6ljIMSR4buZIHbhu4Egc+G7sSB0cuG6o2kgbmdoaeG7h20gY+G7p2EgaMOgbmgga2jDoWNoIGjDoG5nIGtow7RuZyBraGkgxJFpIG3DoXkgYmF5Lg0KDQojIyAyLjIgTcO0IHThuqMgxJHhurdjIHRyxrBuZyBk4buvIGxp4buHdQ0KDQpC4buZIGThu68gbGnhu4d1IEFpcmxpbmUgUGFzc2VuZ2VyIFNhdGlzZmFjdGlvbiBsw6AgbeG7mXQgdOG6rXAgZOG7ryBsaeG7h3UgY3VuZyBj4bqlcCB0aMO0bmcgdGluIGNoaSB0aeG6v3QgduG7gSBz4butIGjDoGkgbMOybmcgY+G7p2EgaMOgbmcga2jDoWNoIGjDoG5nIGtow7RuZyBjaOG7qWEgdHLDqm4gMTIgYmnhur9uIHbDoCAyNS45NzYgcXVhbiBzw6F0IA0KDQrigKIgR2VuZGVyIChnZW5kZXIpOiBHaeG7m2kgdMOtbmggY+G7p2EgaMOgbmgga2jDoWNoLCDigJxNYWxl4oCdIChOYW0pIGhv4bq3YyDigJxGZW1hbGXigJ0gKE7hu68pLg0KDQrigKIgQWdlIChhZ2UpOiDEkOG7mSB0deG7lWkgY+G7p2EgaMOgbmgga2jDoWNoIGtoaSBo4buNIHPhu60gZOG7pW5nIGThu4tjaCB24bulIGjDoG5nIGtow7RuZy4NCg0K4oCiIEN1c3RvbWVyIFR5cGUgKHR5cGUgb2YgY3VzdG9tZXIpOiBQaMOibiBsb+G6oWkga2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCB2w6Aga2jDtG5nIHRydW5nIHRow6BuaCANCg0K4oCiIFR5cGUgb2YgVHJhdmVsICh0eXBlIG9mIHRyYXZlbCk6IE3hu6VjIMSRw61jaCBj4bunYSB2aeG7h2MgZGkgY2h1eeG7g24gbMOgIGPDtG5nIHZp4buHYyBraW5oIGRvYW5oICggQnVzaW5lc3MpIHbDoCBQZXJzb25hbCAoIEPDoWMgY8O0bmcgdmnhu4djIGtow6FjKS4NCg0K4oCiIENsYXNzIChjbGFzcyk6IE3DtCB04bqjIGjhuqFuZyBnaOG6vyB0csOqbiBtw6F5IGJheSBtw6AgaMOgbmgga2jDoWNoIHPhu60gZOG7pW5nLA0KDQrigKIgRGVwYXJ0dXJlIERlbGF5IChkZWxheSk6IFRo4budaSBnaWFuIGPhuqV0IGPDoW5oIG114buZbiBj4bunYSBjaHV54bq/biBiYXkgIA0KDQrigKIgQXJyaXZhbCBEZWxheSAoYXJyaXZhbCBkZWxheSk6IFRo4budaSBnaWFuIGjhuqEgY8OhbmggdHLhu4UgY+G7p2EgY2h1eeG6v24gYmF5DQoNCuKAoiBEZXBhcnR1cmUgYW5kIEFycml2YWwgVGltZSBDb252ZW5pZW5jZSAoZGVwIGFuZCBhcnIpOlPhu7EgdGh14bqtbiB0aeG7h24gduG7gSB0aOG7nWkgZ2lhbiBj4bqldCBjw6FuaCB2w6AgaOG6oSBjw6FuaC4NCg0K4oCiIEJhZ2dhZ2UgaGFuZGxpbmcgOiBN4bupYyDEkeG7mSBow6BpIGzDsm5nIHbhu5tpIGThu4tjaCB24bulIHjhu60gbMO9IGjDoG5oIGzDvSBj4bunYSBow6NuZyBow6BuZyBraMO0bmcgdOG7qyAxIChy4bqldCB04buHKSDEkeG6v24gNSAocuG6pXQgaMOgaSBsw7JuZykgLSAwIMSRaeG7g20uDQoNCuKAoiBTYXRpc2ZhY3Rpb246IFRy4bqjaSBuZ2hp4buHbSBj4bunYSBraMOhY2ggaMOgbmcgxJHhu5FpIHbhu5tpIGjDo25nIGJheSwgYmFvIGfhu5NtOiBTYXRpc2ZpZWQ6IEjDoGkgbMOybmc7IE5ldXRyYWwgb3IgVW5zYXRpc2ZpZWQ6IFRydW5nIGzhuq1wIGhv4bq3YyBraMO0bmcgaMOgaSBsw7JuZy4NCg0K4oCiIEluZmxpZ2h0IHdpZmkgc2VydmljZTogTeG7qWMgxJHhu5kgaMOgaSBsw7JuZyB24bubaSBk4buLY2ggduG7pSBXaWZpIHRyw6puIG3DoXkgYmF5IHThu6sgMSAocuG6pXQgdOG7hykgxJHhur9uIDUgKHLhuqV0IGjDoGkgbMOybmcpIC0gMCBuZ2jEqWEgbMOgICJraMO0bmcgxJHDoW5oIGdpw6HigJ0NCg0K4oCiIEluLWZsaWdodCBTZXJ2aWNlOiBN4bupYyDEkeG7mSBow6BpIGzDsm5nIHbhu5tpIGThu4tjaCB24bulIHRyw6puIGNodXnhur9uIGJheSB04burIDEgKHLhuqV0IHThu4cpIMSR4bq/biA1IChy4bqldCBow6BpIGzDsm5nKSAtIDAgY8OzIG5naMSpYSBsw6AgImtow7RuZyDEkcOhbmggZ2nDoeKAnQ0KDQrigKIgQ2xlYW5saW5lc3M6IE3hu6ljIMSR4buZIGjDoGkgbMOybmcgduG7m2kgxJHhu5kgc+G6oWNoIHPhur0gY+G7p2EgbcOheSBiYXkgdOG7qyAxIChy4bqldCB04buHKSDEkeG6v24gNSAocuG6pXQgaMOgaSBsw7JuZykgLSAwIGPDsyBuZ2jEqWEgbMOgICJraMO0bmcgxJHDoW5oIGdpw6HigJ0NCg0KTGluazogaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMVhuQ2M5VTJPdTIzYVJLczBCakpibmdjekM2UnZUbWNxL2VkaXQ/Z2lkPTg2NjcwNDg3OCNnaWQ9ODY2NzA0ODc4DQoNCmBgYHtyfQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkobWFncml0dHIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoRGVzY1Rvb2xzKQ0KbGlicmFyeShlcGl0b29scykNCmxpYnJhcnkocmVhZHhsKQ0KZGF0YSA8LSByZWFkX2V4Y2VsKCJaYWxvIFJlY2VpdmVkIEZpbGVzL3Rlc3QgYWlybGluZSBwYXNzZW5nZXIueGxzeCIpDQpWaWV3KGRhdGEpDQpgYGANCg0KDQpgYGB7cn0NCnN0cihkYXRhKQ0KYGBgDQoNCiMgQ0jGr8agTkcgMzogS+G6vlQgUVXhuqIgTkdIScOKTiBD4buoVQ0KDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyAxIGJp4bq/bg0KDQojIyMgQmnhur9uIHNhdGlzZmFjdGlvbg0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uKQ0KYGBgDQoNCmBgYHtyfQ0KdGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24pL3N1bSh0YWJsZShkYXRhJHNhdGlzZmFjdGlvbikpDQpgYGANCg0KYGBge3J9DQpwIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24pKSANCmNvbG5hbWVzKHApIDwtIGMoInNhdGlzZmFjdGlvbiIsICJDb3VudCIpDQpnZ3Bsb3QocCwgYWVzKHggPSBzYXRpc2ZhY3Rpb24sIHkgPSBDb3VudCwgZmlsbCA9IHNhdGlzZmFjdGlvbikpICsgDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC4zLCBzaXplID0gMy41KSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIlPhu5EgbMaw4bujbmciLA0KICAgIHRpdGxlID0gIlPhu5Ega2jDoWNoIGjDoG5nIMSRw6FuaCBnacOhIiwNCiAgKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgZmFjZSA9ICJib2xkIiksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGNvbG9yID0gImdyZXk1MCIpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCINCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KcCRQZXJjZW50YWdlIDwtIChwJENvdW50IC8gc3VtKHAkQ291bnQpKSAqIDEwMA0KDQpnZ3Bsb3QocCwgYWVzKHggPSAiIiwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBzYXRpc2ZhY3Rpb24pKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHBo4bqnbiB0csSDbSIsIHggPSAiIiwgeSA9ICIiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChQZXJjZW50YWdlLCAyKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KQ0KYGBgDQoNCiMjIyBCaeG6v24gZ2VuZGVyDQoNCsSQ4bqndSB0acOqbiwgY2jDum5nIHTDtGkgc+G6vSBs4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBjaG8gYmnhur9uIEdlbmRlciBuaOG6sW0gbeG7pWMgxJHDrWNoIMSR4buDIG7huq9tIGLhuq90IMSRxrDhu6NjIHPhu5EgbMaw4bujbmcgZ2nhu5tpIHRow61jaCBj4bunYSBow6BuZyBraMOhY2gga2hpIHPhu7EgZOG7pW5nIGThu4tjaCB24bulIGjDoG5nIGtow7RuZy4NCg0KYGBge3J9DQp0YWJsZShkYXRhJEdlbmRlcikNCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkR2VuZGVyKS9zdW0odGFibGUoZGF0YSRHZW5kZXIpKQ0KYGBgDQoNCmBgYHtyfQ0KcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGEkR2VuZGVyKSkgDQpjb2xuYW1lcyhzKSA8LSBjKCJHZW5kZXIiLCAiQ291bnQiKQ0KZ2dwbG90KHMsIGFlcyh4ID0gR2VuZGVyLCB5ID0gQ291bnQsIGZpbGwgPSBHZW5kZXIpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDMuNSkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICJT4buRIGzGsOG7o25nIiwNCiAgICB0aXRsZSA9ICJHSeG7mkkgVMONTkgiLA0KICApICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiZ3JleTUwIiksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIg0KICApDQpgYGANCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KcyRQZXJjZW50YWdlIDwtIChzJENvdW50IC8gc3VtKHMkQ291bnQpKSAqIDEwMA0KDQpnZ3Bsb3QocywgYWVzKHggPSAiIiwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBHZW5kZXIpKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHBo4bqnbiB0csSDbSIsIHggPSAiIiwgeSA9ICIiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChQZXJjZW50YWdlLCAyKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KQ0KYGBgDQoNCkThu7FhIHbDoG8ga+G6v3QgcXXhuqMgYuG6o25nIHThuqduIHPhu5EgdsOgIGJp4buDdSDEkeG7kyB0csOqbiB0YSBjw7MgdGjhu4MgdGjhuqV5OiBQaMOibiBi4buRIGdp4bubaSB0w61uaCB0cm9uZyBi4buZIGThu68gbGnhu4d1IOKAnEFpcmxpbmUgUGFzc2VuZ2VyIFNhdGlzZmFjdGlvbuKAnSBT4buxIGNow6puaCBs4buHY2ggduG7gSBnaeG7m2kgdMOtbmggZ2nhu69hIHPhu5EgbMaw4bujbmcgaMOgbmgga2jDoWNoIG7hu68gMTMsMTcyICg1MC43MSUpIHbDoCBuYW0gMTIsODA0ICg0OS4yOSUpLiBT4buxIGNow6puaCBs4buHY2ggbmjhu48gbsOgeSAobuG7ryBjaOG7iSBoxqFuIG5hbSBraG/huqNuZyAxLjQyJSkgY2hvIHRo4bqleSBy4bqxbmcgY+G6oyBoYWkgZ2nhu5tpIHTDrW5oIMSR4buBdSDEkcaw4bujYyDEkeG6oWkgZGnhu4duIGfhuqduIG5oxrAgxJHhu5NuZyDEkeG7gXUgdHJvbmcgYuG7mSBk4buvIGxp4buHdSwgdOG6oW8gxJFp4buBdSBraeG7h24gdGh14bqtbiBs4bujaSBjaG8gdmnhu4djIHBow6JuIHTDrWNoIHRy4bqjaSBuZ2hp4buHbSBraMOhY2ggaMOgbmcuDQoNCiMjIyBCaeG6v24gQWdlDQoNClRyxrDhu5tjIGtoaSBwaMOibiB0w61jaCBiaeG6v24gQWdlLCBuaMOzbSBjaMO6bmcgdMO0aSBz4bq9IHBow6JuIG5ow7NtIHRow6BuaCA2IG5ow7NtIMSR4buZIHR14buVaTogdHLhursgZW0oNy0xMiksIHRoaeG6v3UgbmnDqm4oMTItMTgpLCB0aGFuaCBuacOqbigxOC0yNSksIHRydW5nIG5pw6puKDI1LTYwKSwgbmfGsOG7nWkgY2FvIHR14buVaSg2MC03NSksIG5nxrDhu51pIGdpw6AoIDc1IHR14buVaSB0cuG7nyBsw6puKS4NCg0KQmnhur9uIEFnZSB0aOG7gyBoaeG7h24gxJHhu5kgdHXhu5VpIGPhu6dhIGjDoG5nIGtow6FjaCB0aGFtIGdpYSBtw6F5IGJheS4NCg0KYGBge3J9DQpkYXRhJGFnZSA8LSBjdXQoZGF0YSRBZ2UsIA0KICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoNiwgMTIsIDE4LCAyNSwgNjAsIDc1LCBJbmYpLCANCiAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJ0cuG6uyBuaOG7jyIsInRoaeG6v3UgbmnDqm4iLCAidGhhbmggbmnDqm4iLCJ0cnVuZyBuacOqbiIsIm5nxrDhu51pIGNhbyB0deG7lWkiLCJuZ8aw4budaSBnacOgIikpDQpgYGANCg0KQsOieSBnaeG7nSBjaMO6bmcgdMO0aSBz4bq9IGzhuq1wIGLhuqNuZyB04bqnbiBz4buRIMSR4buDIHRo4buDIGhp4buHbiByw7Ugc+G7kSB0deG7lWkgY2hvIGtow6FjaCBow6BuZy4NCg0KYGBge3J9DQp0YWJsZShkYXRhJGFnZSkNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KeiA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGEkJ2FnZScpKSANCmNvbG5hbWVzKHopIDwtIGMoImFnZSIsICJDb3VudCIpDQpnZ3Bsb3QoeiwgYWVzKHggPSBgYWdlYCwgeSA9IENvdW50LCBmaWxsID0gYGFnZWApKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDMuNSkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICJT4buRIGzGsOG7o25nIiwNCiAgICB0aXRsZSA9ICJQaMOibiBi4buRIGPDoWMgbmjDs20gdHXhu5VpIg0KICApICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiZ3JleTUwIiksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIg0KICApDQpgYGANCg0KQmnhu4N1IMSR4buTIHRyw6puIGNobyB0aOG6pXkgc+G7sSBwaMOibiBi4buRIGPDoWMgbmjDs20gdHXhu5VpIHRyb25nIHThuq1wIGThu68gbGnhu4d1IHbhu5tpIHPhu7Ega2jDtG5nIMSR4buTbmcgxJHhu4F1IHLDtSBy4buHdC4gTmjDs20gdHJ1bmcgbmnDqm4gY2hp4bq/bSDGsHUgdGjhur8gdsaw4bujdCB0cuG7mWkgduG7m2kgMTgsMzM4IG5nxrDhu51pLCB0cm9uZyBraGkgY8OhYyBuaMOzbSBraMOhYyBuaMawIHRy4bq7IG5o4buPICg5MDQgbmfGsOG7nWkpLCB0aGnhur91IG5pw6puICgxLDI1NyBuZ8aw4budaSksIHRoYW5oIG5pw6puICgzLDM5OSBuZ8aw4budaSksIG5nxrDhu51pIGNhbyB0deG7lWkgKDEsOTgzIG5nxrDhu51pKSB2w6AgbmfGsOG7nWkgZ2nDoCAoOTUgbmfGsOG7nWkpIGPDsyBz4buRIGzGsOG7o25nIMOtdCBoxqFuIMSRw6FuZyBr4buDLg0KDQpgYGB7cn0NCm8gPC0gcHJvcC50YWJsZSh0YWJsZShkYXRhJGFnZSkpICogMTAwDQpvDQpgYGANCg0KYGBge3J9DQp6JFBlcmNlbnRhZ2UgPC0gKHokQ291bnQgLyBzdW0oeiRDb3VudCkpICogMTAwDQoNCmdncGxvdCh6LCBhZXMoeCA9ICIiLCB5ID0gUGVyY2VudGFnZSwgZmlsbCA9IGFnZSkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgbGFicyh0aXRsZSA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIiwgeCA9ICIiLCB5ID0gIiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKHJvdW5kKFBlcmNlbnRhZ2UsIDIpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDQpDQpgYGANCg0KQ8OzIHPhu7EgxJFhIGThuqFuZyB24buBIGPDoWMgxJHhu5kgdHXhu5VpIHRoYW0gZ2lhIGto4bqjbyBzw6F0IG3hu6ljIMSR4buZIGjDoGkgbMOybmcgLCB24bubaSBwaOG6p24gbOG7m24gaMOgbmgga2jDoWNoIHThuq1wIHRydW5nIHRyb25nIMSR4buZIHR14buVaSB04burIDIwIMSR4bq/biA0MCwgxJHhurdjIGJp4buHdCDEkeG7iW5oIGNhbyBuaOG6pXQg4bufIHR14buVaSAyNS4gVOG7tyBs4buHIGjDoG5oIGtow6FjaCBnaeG6o20gZOG6p24gdOG7qyBraG/huqNuZyA0NSB0deG7lWkgdHLhu58gxJFpLCB24bubaSBuaMOzbSB0deG7lWkgdHLDqm4gNjAgdsOgIGTGsOG7m2kgMTYgY8OzIHThu7cgbOG7hyB0aOG6pXAgaMahbiDEkcOhbmcga+G7gy4gTmjDs20gdHLhursgKGTGsOG7m2kgMjApIGNoaeG6v20ga2hv4bqjbmcgNy0xMCUgdOG7lW5nIHPhu5EgaMOgbmgga2jDoWNoLiBQaMOibiBi4buRIG7DoHkgZ2nDunAgxJFp4buBdSBjaOG7iW5oIGThu4tjaCB24bulIHbDoCBjaGnhur9uIGzGsOG7o2Mga2luaCBkb2FuaCBwaMO5IGjhu6NwIGjGoW4gduG7m2kgdOG7q25nIG5ow7NtIHR14buVaS4NCg0KIyMjIEJp4bq/biBUeXBlIG9mIHRyYXZlbA0KDQpWaeG7h2MgbcO0IHThuqMgbeG7pWMgxJHDrWNoIGtoaSBkaSBjaHV54buDbiBi4bqxbmcgbcOheSBiYXkgIG3DoCBow6BuaCBraMOhY2ggdGjhu7FjIGhp4buHbiBjaOG7pyB54bq/dSBy4bqldCBxdWFuIHRy4buNbmcsIGdpw7pwIGNobyBjaMO6bmcgdGEgY8OzIHRo4buDIGhp4buDdSByw7UgduG7gSBow6BuZyBraMOhY2ggaMahbi4gTmjGsCB2aeG7h2Mga2jDoWNoIGTDuW5nIGThu4tjaCB24bulIGThu4tjaCBjaHV54buDbiBuaOG6p20gbeG7pWMgxJHDrWNoIGfDrD8NCg0KTsOqbiBiw6J5IGdp4budIGNow7puZyB0w7RpIHPhur0gduG6vSBiaeG7g3UgxJHhu5MgdGjhu5FuZyBrw6ogeGVtIGtow6FjaCBow6BuZyB0aGFtIGdpYSBk4buLY2ggduG7pSBuaOG6r20gbeG7pWMgxJHDrWNoIGzDoG0gdmnhu4djIGfDrA0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkJ1R5cGUgb2YgVHJhdmVsJykNCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkJ1R5cGUgb2YgVHJhdmVsJykvc3VtKHRhYmxlKGRhdGEkJ1R5cGUgb2YgVHJhdmVsJykpDQpgYGANCg0KYGBge3J9DQpiIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YSQnVHlwZSBvZiBUcmF2ZWwnKSkgDQpjb2xuYW1lcyhiKSA8LSBjKCJUeXBlIG9mIFRyYXZlbCIsICJDb3VudCIpDQpnZ3Bsb3QoYiwgYWVzKHggPSBgVHlwZSBvZiBUcmF2ZWxgLCB5ID0gQ291bnQsIGZpbGwgPSBgVHlwZSBvZiBUcmF2ZWxgKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjMsIHNpemUgPSAzLjUpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KYGBge3J9DQpiJFBlcmNlbnRhZ2UgPC0gKGIkQ291bnQgLyBzdW0oYiRDb3VudCkpICogMTAwDQoNCmdncGxvdChiLCBhZXMoeCA9ICIiLCB5ID0gUGVyY2VudGFnZSwgZmlsbCA9IGBUeXBlIG9mIFRyYXZlbGApKSArDQogIGdlb21fYmFyKHdpZHRoID0gMSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVOG7tyBs4buHIHBo4bqnbiB0csSDbSIsIHggPSAiIiwgeSA9ICIiKSArDQogIHRoZW1lX3ZvaWQoKSArIA0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChQZXJjZW50YWdlLCAyKSwgIiUiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KQ0KYGBgDQoNClF1YSBiaeG7g3UgxJHhu5MsIHRhIHRo4bqleToNCg0KU+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgxJFpIGPDtG5nIHTDoWMgbMOgIDE4MDM4IG5nxrDhu51pIChraG/huqNuZyA2OSw0NCUpDQoNClPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIMSRaSB2w6wgY8O0bmcgdmnhu4djIHJpw6puZyBsw6AgNzkzOCBuZ8aw4budaSAoIGtob+G6o25nIDMwLDU2JSkNCg0KTmjGsCB24bqteSBz4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyDEkWkgY8O0bmcgdMOhYyBuaGnhu4F1IGjGoW4ga2gga2jDoWNoIGjDoG5nIMSRaSB2w6wgY8O0bmcgdmnhu4djIHJpw6puZyBsw6AgMTAxMDAgbmfGsOG7nWkgKGtob+G6o25nIDM4LDg4JSkNCg0KxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgcuG6sW5nIGjDoG5oIGtow6FjaCBz4butIGThu6VuZyBk4buLY2ggduG7pSBj4bunYSBow6NuZyBow6BuZyBraMO0bmcgY2jhu6cgeeG6v3UgdsOsIG3hu6VjIMSRw61jaCBjw7RuZyB2aeG7h2MgaMahbiBsw6AgaMOsbmggdGjhu6ljIGRpIGNodXnhu4NuIGtow6FjLlRow7RuZyB0aW4gY8OzIHRo4buDIGN1bmcgY+G6pXAgY2hvIGRvYW5oIG5naGnhu4dwIGjDoG5nIGtow7RuZyB24buBIHZp4buHYyBwaMOhdCB0cmnhu4NuIHbDoCB04buRaSDGsHUgaMOzYSBk4buLY2ggduG7pSwgdGnhur9wIHRo4buLIHbDoCBjaGnhur9uIGzGsOG7o2MgcGjDom4gcGjhu5FpLiBDw6FjIGNow61uaCBzw6FjaCBraHV54bq/biBtw6NpLCBk4buLY2ggduG7pSBjaMSDbSBzw7NjIGtow6FjaCBow6BuZyB2w6AgbOG7sWEgY2jhu41uIGPDoWMgdHV54bq/biBiYXkgY8OzIHRo4buDIMSRxrDhu6NjIMSRaeG7gXUgY2jhu4luaCDEkeG7gyBwaMO5IGjhu6NwIHbhu5tpIG5odSBj4bqndSBjaOG7pyB54bq/dSBj4bunYSBraMOhY2ggaMOgbmcgbMOgIMSRaSBjw7RuZyB0w6FjLg0KDQpDaOG6s25nIGjhuqFuLCBjdW5nIGPhuqVwIGPDoWMgZOG7i2NoIHbhu6UgdsOgIHRp4buHbiDDrWNoIHBow7kgaOG7o3AgduG7m2kgbG/huqFpIGjDrG5oIGRpIGNodXnhu4NuIGPhu6dhIGjDoG5oIGtow6FjaCDEkWkgY8O0bmcgdMOhYyBuaMawIHdpZmksIGThu4tjaCB24bulIGNoxINtIHPDs2Mga2jDoWNoIGjDoG5nIHRyb25nIGtoaSBo4buNIMSRYW5nIGLhuq1uIGPDtG5nIHZp4buHYy4NCg0KIyMjIEJp4bq/biBDbGFzcw0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkJ0NsYXNzJykNCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkJ0NsYXNzJykvc3VtKHRhYmxlKGRhdGEkJ0NsYXNzJykpDQpgYGANCg0KYGBge3J9DQpjIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YSQnQ2xhc3MnKSkgDQpjb2xuYW1lcyhjKSA8LSBjKCJDbGFzcyIsICJDb3VudCIpDQpjJFBlcmNlbnRhZ2UgPC0gKCBjJENvdW50IC8gc3VtKCBjJENvdW50KSkgKiAxMDANCg0KZ2dwbG90KGMsIGFlcyh4ID0gIiIsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gYENsYXNzYCkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgbGFicyh0aXRsZSA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIiwgeCA9ICIiLCB5ID0gIiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKHJvdW5kKFBlcmNlbnRhZ2UsIDIpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC43NSksIHNpemUgPSAzKQ0KYGBgDQoNCmBgYHtyfQ0KYyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGEkJ0NsYXNzJykpIA0KY29sbmFtZXMoYykgPC0gYygiQ2xhc3MiLCAiQ291bnQiKQ0KZ2dwbG90KGMsIGFlcyh4ID0gQ2xhc3MsIHkgPSBDb3VudCwgZmlsbCA9IENsYXNzKSkgKyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjMsIHNpemUgPSAzLjUpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiU+G7kSBsxrDhu6NuZyIsDQogICAgdGl0bGUgPSAiUGjDom4gYuG7kSBjw6FjIGjhuqFuZyB2w6kga2jDoWNoIGjDoG5nIGTDuW5nIg0KICApICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiZ3JleTUwIiksDQogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIg0KICApDQpgYGANCg0KUXVhIGJp4buDdSDEkeG7kywgdGEgdGjhuqV5Og0KDQpT4buRIGzGsOG7o25nIGtow6FjaCBow6BuZyDEkcSDbmcga8O9IGjhuqFuZyBnaOG6vyB0aMawxqFuZyBnaWEgY2hp4bq/bSBz4buRIGzGsOG7o25nIGzhu5tuIGtob+G6o25nIDEyNDk1IG5nxrDhu51pIChraG/huqNuZyA0OCwxJSkNCg0KU+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcgxJHEg25nIGvDvSBo4bqhbmcgZ2jhur8gcGjhu5UgdGjhu5FuZyBsw6AgMTE1NjQgbmfGsOG7nWkgKCBraG/huqNuZyA0NCw1MiUpDQoNClPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIMSRxINuZyBrw70gaOG6oW5nIGdo4bq/IGNhbyBj4bqlcCBjw7Mgw610IG5nxrDhu51pIHPhu60gZOG7pW5nIG5o4bqldCBraG/huqNuZyAxOTE3IG5nxrDhu51pIChraG/huqNuZyA3LDM4JSkNCg0KIyMjIEJp4bq/biBDdXN0b21lciBUeXBlDQoNCmBgYHtyfQ0KdGFibGUoZGF0YSQnQ3VzdG9tZXIgVHlwZScpDQpgYGANCg0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkJ0N1c3RvbWVyIFR5cGUnKS9zdW0odGFibGUoZGF0YSQnQ3VzdG9tZXIgVHlwZScpKQ0KYGBgDQoNCmBgYHtyfQ0KYSA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGEkJ0N1c3RvbWVyIFR5cGUnKSkgDQpjb2xuYW1lcyhhKSA8LSBjKCJDdXN0b21lciBUeXBlIiwgIkNvdW50IikNCmdncGxvdChhLCBhZXMoeCA9IGBDdXN0b21lciBUeXBlYCwgeSA9IENvdW50LCBmaWxsID0gYEN1c3RvbWVyIFR5cGVgKSkgKyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjMsIHNpemUgPSAzLjUpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiU+G7kSBsxrDhu6NuZyIsDQogICAgdGl0bGUgPSAiUGjDom4gYuG7kSB04buHcCBraMOhY2ggaMOgbmciDQogICkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gY29tbWEpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIpLA0KICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBjb2xvciA9ICJncmV5NTAiKSwNCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiDQogICkNCmBgYA0KDQpgYGB7cn0NCmEkUGVyY2VudGFnZSA8LSAoYSRDb3VudCAvIHN1bShhJENvdW50KSkgKiAxMDANCg0KZ2dwbG90KGEsIGFlcyh4ID0gIiIsIHkgPSBQZXJjZW50YWdlLCBmaWxsID0gYEN1c3RvbWVyIFR5cGVgKSkgKw0KICBnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGNvb3JkX3BvbGFyKCJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlThu7cgbOG7hyBwaOG6p24gdHLEg20iLCB4ID0gIiIsIHkgPSAiIikgKw0KICB0aGVtZV92b2lkKCkgKyANCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUocm91bmQoUGVyY2VudGFnZSwgMiksICIlIikpLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gNCkNCmBgYA0KDQpRdWEgYmnhu4N1IMSR4buTLCB0YSB0aOG6pXk6DQoNClPhu5EgbMaw4bujbmcga2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCBjaGnhur9tIHPhu5EgbMaw4bujbmcgbOG7m24ga2hv4bqjbmcgMjExNzcgbmfGsOG7nWkgKGtob+G6o25nIDgxLDUzJSkNCg0KU+G7kSBsxrDhu6NuZyBraMOhY2ggaMOgbmcga2jDtG5nIHRydW5nIHRow6BuaCBsw6AgNDc5OSBuZ8aw4budaSAoIGtob+G6o25nIDE4LDQ3JSkNCg0KTmjGsCB24bqteSBz4buRIGzGsOG7o25nIGtow6FjaCB0cnVuZyB0aMOgbmggbmhp4buBdSBoxqFuIGtow6FjaCBow6BuZyBraMO0bmcgdHJ1bmcgdGjDoG5oIGzDoCAxNjM0OCBuZ8aw4budaSAoa2hv4bqjbmcgNjMsMDUlKQ0KDQoNCiMjIyBCaeG6v24gSW5mbGlnaHQgd2lmaSBzZXJ2aWNlDQpgYGB7cn0NCnRhYmxlKGRhdGEkYEluZmxpZ2h0IHdpZmkgc2VydmljZWApL3N1bSh0YWJsZShkYXRhJGBJbmZsaWdodCB3aWZpIHNlcnZpY2VgKSkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBE4buvIGxp4buHdQ0KbGFiZWxzIDwtIGMoIktow7RuZyDEkcOhbmggZ2nDoSIsIlLhuqV0IHThu4ciLCAiVOG7hyIsICJCw6xuaCB0aMaw4budbmciLCAiSMOgaSBsw7JuZyIsICJS4bqldCBow6BpIGzDsm5nIikNCnZhbHVlcyA8LSBjKDAuMDMxMywgMC4xNzI4LCAwLjI0OTgsIDAuMjQzMiwgMC4xOTE4LCAwLjExMTEpDQp2YXJpYWJsZV9uYW1lIDwtICJJbmZsaWdodC53aWZpLnNlcnZpY2UiDQoNCiMgVMOtbmggdOG7lW5nIGdpw6EgdHLhu4sNCnRvdGFsIDwtIHN1bSh2YWx1ZXMpDQoNCiMgVMOtbmggcGjhuqduIHRyxINtIGNobyBt4buXaSBt4bupYyDEkeG7mQ0KcGVyY2VudGFnZXMgPC0gdmFsdWVzIC8gdG90YWwgKiAxMDANCg0KIyBU4bqhbyBkYXRhZnJhbWUNCmRmIDwtIGRhdGEuZnJhbWUobGFiZWxzLCB2YWx1ZXMsIHBlcmNlbnRhZ2VzKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0DQpsaWJyYXJ5KGdncGxvdDIpDQpnZ3Bsb3QoZGYsIGFlcyh4ID0gbGFiZWxzLCB5ID0gcGVyY2VudGFnZXMpKSArDQogIGdlb21fY29sKGZpbGwgPSAnIzRjNzJiMCcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNwcmludGYoIiUuMmYlJSIsIHBlcmNlbnRhZ2VzKSksIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDQpICsNCiAgbGFicyh4ID0gIk3hu6ljIMSR4buZIMSRw6FuaCBnacOhIiwgeSA9ICJQaOG6p24gdHLEg20iLCB0aXRsZSA9IHBhc3RlMCgiUGjDom4gYuG7kSBjw6FjIG3hu6ljIMSR4buZIMSRw6FuaCBnacOhIGNobyBiaeG6v24gIiwgdmFyaWFibGVfbmFtZSkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCk5o4bqtbiB4w6l0OiANCg0KS2jDoWNoIGjDoG5nIMSRw6FuaCBnacOhIOG7nyBt4bupYyBiw6xuaCB0aMaw4budbmcgduG7gSBk4buLY2ggduG7pSB3aWZpIGNoaeG6v20gdOG7tyB0cuG7jW5nIGtow6EgY2FvICgyNC4zMiUpLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBy4bqxbmcgcGjhuqduIGzhu5tuIGjDoG5oIGtow6FjaCBjw7MgdHLhuqNpIG5naGnhu4dtIOG7nyBt4bupYyB0xrDGoW5nIMSR4buRaS4gSOG7jSBjw7MgdGjhu4MgZ+G6t3AgbeG7mXQgc+G7kSB24bqlbiDEkeG7gSBuaMawbmcgY2jDum5nIGtow7RuZyDEkeG7pyBuZ2hpw6ptIHRy4buNbmcgxJHhu4MgxJHDoW5oIGdpw6EgdOG7hyBoxqFuLg0KDQpLaMOhY2ggaMOgbmcgxJHDoW5oIGdpw6EgdOG7hyB24buBIGThu4tjaCB24bulIHdpZmkgY2hp4bq/bSB04bu3IHRy4buNbmcgY2FvIG5o4bqldCAoMjQuOTglKTogY2hvIHRo4bqleSBjw7MgbeG7mXQgbMaw4bujbmcgbOG7m24gaMOgbmgga2jDoWNoIGtow7RuZyBow6BpIGzDsm5nIHbhu5tpIGThu4tjaCB24bulIHdpZmkuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgcGjhuqNuIMOhbmggY8OhYyB24bqlbiDEkeG7gSBuZ2hpw6ptIHRy4buNbmcgduG7gSBjaOG6pXQgbMaw4bujbmcga+G6v3QgbuG7kWksIHThu5FjIMSR4buZIGhv4bq3YyDEkeG7mSDhu5VuIMSR4buLbmggY+G7p2Egd2lmaS4NCg0KS2jDoWNoIGjDoG5nIMSRw6FuaCBnacOhIGjDoGkgbMOybmcgduG7gSBk4buLY2ggduG7pSB3aWZpIGNoaeG6v20gdOG7tyB0cuG7jW5nIHRo4bqlcCBoxqFuIMSRw6FuaCBnacOhIGLDrG5oIHRoxrDhu51uZyB2w6AgdOG7hyBuaMawbmcgduG6q24gY8OzIHThu7cgdHLhu41uZyBraMOhIGNhbyAoMTkuMTglKS4gxJBp4buBdSDEkcOzIGNobyB0aOG6pXkgZOG7i2NoIHbhu6UgY8OzIHRo4buDIMSRxrDhu6NjIMSRw6FuaCBnacOhIHThu5F0IHbhu4EgdOG7kWMgxJHhu5kgdsOgIOG7lW4gxJHhu4tuaCwgbmjGsG5nIHbhuqtuIGPDsyBuaOG7r25nIHnhur91IHThu5Ega2jDoWMgY2jGsGEgxJHhuqF0IMSR4bq/biBt4bupYyB4deG6pXQgc+G6r2MuDQoNCktow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBy4bqldCBow6BpIGzDsm5nIHbhu4EgZOG7i2NoIHbhu6Ugd2lmaSBjaGnhur9tIHThu7cgdHLhu41uZyBraMO0bmcgY2FvICgxMS4xMSUpLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBy4bqxbmcgY2jhu4kgbeG7mXQgcGjhuqduIG5o4buPIGjDoG5oIGtow6FjaCBjw7MgdHLhuqNpIG5naGnhu4dtIHLhuqV0IHThu5F0IHbhu5tpIGThu4tjaCB24bulIHdpZmkuIEThu4tjaCB24bulIG7DoHkgY8OzIHRo4buDIHLhuqV0IHThu5F0IOG7nyBt4buZdCBz4buRIGtow61hIGPhuqFuaCBuaMawIHThu5FjIMSR4buZIGNhbywg4buVbiDEkeG7i25oLCB2w6AgZOG7hSB0cnV5IGPhuq1wLg0KDQpLaMOhY2ggaMOgbmcgxJHDoW5oIGdpw6EgcuG6pXQgdOG7hyB24buBIGThu4tjaCB24bulIHdpZmkgY2hp4bq/bSB04bu3IHRy4buNbmcga2jDoSBjYW8gICgxNy4yOCUpLCBjaG8gdGjhuqV5IGPDsyBuaGnhu4F1IGjDoG5oIGtow6FjaCBn4bq3cCBwaOG6o2kgdHLhuqNpIG5naGnhu4dtIHLhuqV0IGtow7RuZyBow6BpIGzDsm5nIHbhu5tpIGThu4tjaCB24bulIHdpZmkuIE5o4buvbmcgduG6pW4gxJHhu4EgbmjGsCBr4bq/dCBu4buRaSBraMO0bmcg4buVbiDEkeG7i25oLCB04buRYyDEkeG7mSBjaOG6rW0sIGhv4bq3YyBraMO0bmcgdGjhu4MgdHJ1eSBj4bqtcCBjw7MgdGjhu4MgbMOgIG5ndXnDqm4gbmjDom4gY2jDrW5oLg0KDQpLaMOhY2ggaMOgbmcga2jDtG5nIMSRw6FuaCBnacOhIHbhu4EgZOG7i2NoIHbhu6Ugd2lmaSBjaGnhur9tIHThu7cgdHLhu41uZyB0aOG6pXAgbmjhuqV0ICgzLjEzJSkuIE5ndXnDqm4gbmjDom4gZOG6q24gxJHhur9uIHZp4buHYyBraMOhY2ggaMOgbmcga2jDtG5nIMSRw6FuaCBnacOhIHThu7cgdHLhu41uZyB0aOG6pXAgY8OzIHRo4buDIGRvIGjhu40ga2jDtG5nIHPhu60gZOG7pW5nIGThu4tjaCB24bulIGhv4bq3YyBraMO0bmcgY8OzIMO9IGtp4bq/biB24buBIGNo4bqldCBsxrDhu6NuZyBk4buLY2ggduG7pS4NCg0KIyMjIEJp4bq/biBiYWdnYWdlIGhhbmRsaW5nDQoNCmBgYHtyfQ0KdGFibGUoZGF0YSRgQmFnZ2FnZSBoYW5kbGluZ2ApL3N1bSh0YWJsZShkYXRhJGBCYWdnYWdlIGhhbmRsaW5nYCkpDQpgYGANCg0KYGBge3J9DQojIEThu68gbGnhu4d1DQpsYWJlbHMgPC0gYygiS2jDtG5nIMSRw6FuaCBnacOhIiwiUuG6pXQgdOG7hyIsICJU4buHIiwgIkLDrG5oIHRoxrDhu51uZyIsICJIw6BpIGzDsm5nIiwgIlLhuqV0IGjDoGkgbMOybmciKQ0KdmFsdWVzIDwtIGMoIDAsMC4wNjg5NSwgMC4xMDkzNywgMC4yMDA5MiwgMC4zNjEwMywgMC4yNTk3NCAgKQ0KdmFyaWFibGVfbmFtZSA8LSAiQmFnZ2FnZS5oYW5kbGluZyINCg0KIyBUw61uaCB0b8OhbiB04buVbmcgZ2nDoSB0cuG7iw0KdG90YWwgPC0gc3VtKHZhbHVlcykNCg0KIyBUw61uaCBwaOG6p24gdHLEg20gY2hvIG3hu5dpIG3hu6ljIMSR4buZDQpwZXJjZW50YWdlcyA8LSB2YWx1ZXMgLyB0b3RhbCAqIDEwMA0KDQojIFThuqFvIGRhdGFmcmFtZQ0KZGYgPC0gZGF0YS5mcmFtZShsYWJlbHMsIHZhbHVlcywgcGVyY2VudGFnZXMpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkZiwgYWVzKHggPSBsYWJlbHMsIHkgPSBwZXJjZW50YWdlcykpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICcjNGM3MmIwJykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3ByaW50ZigiJS4yZiUlIiwgcGVyY2VudGFnZXMpKSwgdmp1c3QgPSAtMC41LCBzaXplID0gNCkgKw0KICBsYWJzKHggPSAiTeG7qWMgxJHhu5kgxJHDoW5oIGdpw6EiLCB5ID0gIlBo4bqnbiB0csSDbSIsIHRpdGxlID0gcGFzdGUwKCJQaMOibiBi4buRIGPDoWMgbeG7qWMgxJHhu5kgxJHDoW5oIGdpw6EgY2hvICIsIHZhcmlhYmxlX25hbWUpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KS2jDoWNoIGjDoG5nIMSRw6FuaCBnacOhIGLDrG5oIHRoxrDhu51uZyB24buBIGThu4tjaCB24bulIHbhuq1uIGNodXnhu4NuIGjDoG5oIGzDvSBjaGnhur9tIHThu7cgbOG7hyBraG/huqNuZyAyMC4wOSUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGPDsyBt4buZdCBz4buRIGtow6FjaCBow6BuZyBj4bqjbSB0aOG6pXkgZOG7i2NoIHbhu6UgbsOgeSBjaOG7iSDhu58gbeG7qWMgdHJ1bmcgYsOsbmgsIGtow7RuZyBu4buVaSBi4bqtdCBuaMawbmcgY8Wpbmcga2jDtG5nIHF1w6EgdOG7hy4gDQoNCktow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBow6BpIGzDsm5nIHbhu4EgZOG7i2NoIHbhu6UgduG6rW4gY2h1eeG7g24gaMOgbmggbMO9IGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQgIGtob+G6o25nIDM2LjEwJS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgcuG6sW5nIGThu4tjaCB24bulIHjhu60gbMO9IGjDoG5oIGzDvSDEkWFuZyB0aOG7sWMgaGnhu4duIHThu5F0IGPDoWMgY2jhu6ljIG7Eg25nIGPGoSBi4bqjbiB2w6AgxJHDoXAg4bupbmcga+G7syB24buNbmcgY+G7p2EgcGjhuqduIGzhu5tuIGtow6FjaCBow6BuZy4NCg0KS2jDoWNoIGjDoG5nIGtow7RuZyDEkcOhbmggZ2nDoSB24buBIGThu4tjaCB24bulIHbhuq1uIGNodXnhu4NuIGjDoG5oIGzDvSBjaGnhu4NtIHThu7cgbOG7hyAwJSBjaG8gY2jDum5nIHRhIGJp4bq/dCBy4bqxbmcga2jDtG5nIGPDsyBraMOhY2ggaMOgbmcgbsOgbyBi4buPIHF1YSB2aeG7h2MgxJHDoW5oIGdpw6EgZOG7i2NoIHbhu6UgbsOgeS4NCg0KDQoNCktow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBy4bqldCBow6BpIGzDsm5nIHbhu4EgZOG7i2NoIHbhu6UgduG6rW4gY2h1eeG7g24gaMOgbmggbMO9IGNoaeG6v20gdOG7tyBs4buHIGtow6EgY2FvIGtob+G6o25nIDI1Ljk3JS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgbeG7mXQgc+G7kSBsxrDhu6NuZyDEkcOhbmcga+G7gyBraMOhY2ggaMOgbmcgcuG6pXQgaMOgaSBsw7JuZyB24bubaSBk4buLY2ggduG7pS4gS2jDoWNoIGjDoG5nIGPDsyB0aOG7gyBy4bqldCBow6BpIGzDsm5nIGRvIGThu4tjaCB24bulIG5oYW5oIGNow7NuZywgbmjDom4gdmnDqm4gdGjDom4gdGhp4buHbiB2w6AgY2h1ecOqbiBuZ2hp4buHcCwgaG/hurdjIGRvIHZp4buHYyB44butIGzDvSBjw6FjIHbhuqVuIMSR4buBIHBow6F0IHNpbmggbeG7mXQgY8OhY2ggaGnhu4d1IHF14bqjLg0KDQpLaMOhY2ggaMOgbmcgxJHDoW5oIGdpw6EgcuG6pXQgdOG7hyB24buBIGThu4tjaCB24bulIHbhuq1uIGNodXnhu4NuIGjDoG5oIGzDvSBjaGnhur9tIHThu7cgbOG7hyBraG/huqNuZyA2Ljg5JSBjaG8gdGjhuqV5IGPDsyBt4buZdCBuaMOzbSBuaOG7jyBraMOhY2ggaMOgbmcgcuG6pXQga2jDtG5nIGjDoGkgbMOybmcgduG7m2kgZOG7i2NoIHbhu6UsIGPDsyB0aOG7gyBkbyBjw6FjIHbhuqVuIMSR4buBIG5naGnDqm0gdHLhu41uZyBuaMawIGjDoG5oIGzDvSBi4buLIG3huqV0LCBoxrAgaOG7j25nIG7hurduZywgaG/hurdjIHRow6FpIMSR4buZIHBo4bulYyB24bulIGtow7RuZyB04buRdC4NCg0KS2jDoWNoIGjDoG5nIMSRw6FuaCBnacOhIHThu4cgduG7gSBk4buLY2ggduG7pSB24bqtbiBjaHV54buDbiBow6BuaCBsw70gY2hp4bq/bSB04bu3IGzhu4cga2hv4bqjbmcgMTAuOTQlLCBjw7MgdGjhu4MgZG8gY8OhYyB24bqlbiDEkeG7gSBuaMawIHRo4budaSBnaWFuIGNo4budIMSR4bujaSBsw6J1LCBow6BuaCBsw70gYuG7iyBoxrAgaOG7j25nIG5o4bq5LCBob+G6t2MgZOG7i2NoIHbhu6Uga2jDtG5nIMSRw6FwIOG7qW5nIGvhu7MgduG7jW5nLg0KDQojIyMgQmnhur9uIEluZmxpZ2h0IHNlcnZpY2UNCg0KYGBge3J9DQp0YWJsZShkYXRhJGBJbmZsaWdodCBzZXJ2aWNlYCkvc3VtKHRhYmxlKGRhdGEkYEluZmxpZ2h0IHNlcnZpY2VgKSkNCmBgYA0KDQpgYGB7cn0NCiMgROG7ryBsaeG7h3UNCmxhYmVscyA8LSBjKCJLaMO0bmcgxJHDoW5oIGdpw6EiLCJS4bqldCB04buHIiwgIlThu4ciLCAiQsOsbmggdGjGsOG7nW5nIiwgIkjDoGkgbMOybmciLCAiUuG6pXQgaMOgaSBsw7JuZyIpDQp2YWx1ZXMgPC0gYyggNy42OTllLTA1LCA2Ljg0NWUtMDIsIDEuMDk4ZS0wMSwgMS45MzFlLTAxLCAzLjYxMGUtMDEsIDIuNjc2ZS0wMSAgICkNCnZhcmlhYmxlX25hbWUgPC0gIkluZmxpZ2h0LnNlcnZpY2UiDQoNCiMgVMOtbmggdG/DoW4gdOG7lW5nIGdpw6EgdHLhu4sNCnRvdGFsIDwtIHN1bSh2YWx1ZXMpDQoNCiMgVMOtbmggcGjhuqduIHRyxINtIGNobyBt4buXaSBt4bupYyDEkeG7mQ0KcGVyY2VudGFnZXMgPC0gdmFsdWVzIC8gdG90YWwgKiAxMDANCg0KIyBU4bqhbyBkYXRhZnJhbWUNCmRmIDwtIGRhdGEuZnJhbWUobGFiZWxzLCB2YWx1ZXMsIHBlcmNlbnRhZ2VzKQ0KDQojIFbhur0gYmnhu4N1IMSR4buTIGPhu5l0DQpsaWJyYXJ5KGdncGxvdDIpDQpnZ3Bsb3QoZGYsIGFlcyh4ID0gbGFiZWxzLCB5ID0gcGVyY2VudGFnZXMpKSArDQogIGdlb21fY29sKGZpbGwgPSAnIzRjNzJiMCcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNwcmludGYoIiUuMmYlJSIsIHBlcmNlbnRhZ2VzKSksIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDQpICsNCiAgbGFicyh4ID0gIk3hu6ljIMSR4buZIMSRw6FuaCBnacOhIiwgeSA9ICJQaOG6p24gdHLEg20iLCB0aXRsZSA9IHBhc3RlMCgiUGjDom4gYuG7kSBjw6FjIG3hu6ljIMSR4buZIMSRw6FuaCBnacOhIGNobyAiLCB2YXJpYWJsZV9uYW1lKSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSMgROG7ryBsaeG7h3UNCmxhYmVscyA8LSBjKCJLaMO0bmcgxJHDoW5oIGdpw6EiLCJS4bqldCB04buHIiwgIlThu4ciLCAiQsOsbmggdGjGsOG7nW5nIiwgIkjDoGkgbMOybmciLCAiUuG6pXQgaMOgaSBsw7JuZyIpDQp2YWx1ZXMgPC0gYyggNy42OTllLTA1LCA2Ljg0NWUtMDIsIDEuMDk4ZS0wMSwgMS45MzFlLTAxLCAzLjYxMGUtMDEsIDIuNjc2ZS0wMSAgICkNCnZhcmlhYmxlX25hbWUgPC0gIkluZmxpZ2h0LnNlcnZpY2UiDQoNCmBgYA0KDQpOaOG6rW4geMOpdDogQmnhu4N1IMSR4buTIHBow6JuIGLhu5EgY8OhYyBt4bupYyDEkeG7mSDEkcOhbmggZ2nDoSBjaG8gZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5ICBjaG8gdGjhuqV5IGvhur90IHF14bqjIGtow6EgdMOtY2ggY+G7sWMgduG7m2kgaMahbiBt4buZdCBu4butYSBz4buRIGjDoG5oIGtow6FjaCDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSDhu58gbeG7qWMgIkjDoGkgbMOybmciIGhv4bq3YyAiUuG6pXQgaMOgaSBsw7JuZyIuIEPhu6UgdGjhu4MsICJIw6BpIGzDsm5nIiBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0IHbhu5tpIDM2LjEwJSwgdGnhur9wIHRoZW8gbMOgICJS4bqldCBow6BpIGzDsm5nIiB24bubaSAyNi43NiUuIE3hu6ljIMSR4buZICJCw6xuaCB0aMaw4budbmciIGPFqW5nIGNoaeG6v20gbeG7mXQgdOG7tyBs4buHIMSRw6FuZyBr4buDIGzDoCAxOS4zMSUsIGNobyB0aOG6pXkgY8OzIG3hu5l0IHBo4bqnbiBow6BuaCBraMOhY2ggY8OzIHRy4bqjaSBuZ2hp4buHbSB0cnVuZyBiw6xuaC4gVHV5IG5oacOqbiwgY8OzIGtob+G6o25nIDE3LjgyJSBow6BuaCBraMOhY2ggxJHDoW5oIGdpw6EgZOG7i2NoIHbhu6UgbMOgICJU4buHIiBob+G6t2MgIlLhuqV0IHThu4ciLCDEkWnhu4F1IG7DoHkgY2hvIHRo4bqleSBj4bqnbiBjw7Mgbmjhu69uZyBj4bqjaSB0aGnhu4duIMSR4buDIG7Dom5nIGNhbyB0cuG6o2kgbmdoaeG7h20gY+G7p2Egbmjhu69uZyBow6BuaCBraMOhY2ggbsOgeS4gVOG7tyBs4buHICJLaMO0bmcgxJHDoW5oIGdpw6EiIGzDoCBy4bqldCBuaOG7jyAoMC4wMSUpLCBjaG8gdGjhuqV5IGjhuqd1IGjhur90IGjDoG5oIGtow6FjaCDEkeG7gXUgY8OzIMSRw6FuaCBnacOhIHbhu4EgZOG7i2NoIHbhu6UuIE5ow6xuIGNodW5nLCBk4buLY2ggduG7pSB0csOqbiBjaHV54bq/biBiYXkgbmjhuq1uIMSRxrDhu6NjIG5oaeG7gXUgcGjhuqNuIGjhu5NpIHTDrWNoIGPhu7FjIG5oxrBuZyB24bqrbiBj4bqnbiBj4bqjaSB0aeG6v24gxJHhu4MgZ2nhuqNtIHThu7cgbOG7hyBraMOhY2ggaMOgbmcga2jDtG5nIGjDoGkgbMOybmcuDQoNCiMjIyBCaeG6v24gQ2xlYW5saW5lc3MNCg0KYGBge3J9DQp0YWJsZShkYXRhJENsZWFubGluZXNzKS9zdW0odGFibGUoZGF0YSRDbGVhbmxpbmVzcykpDQpgYGANCg0KYGBge3J9DQojIEThu68gbGnhu4d1DQpsYWJlbHMgPC0gYygiS2jDtG5nIMSRw6FuaCBnacOhIiwiUuG6pXQgdOG7hyIsICJU4buHIiwgIkLDrG5oIHRoxrDhu51uZyIsICJIw6BpIGzDsm5nIiwgIlLhuqV0IGjDoGkgbMOybmciKQ0KdmFsdWVzIDwtIGMoICA3LjY5OWUtMDUsIDEuMzEzZS0wMSwgMS41MzNlLTAxLCAyLjMzNWUtMDEgLDIuNjE0ZS0wMSwgMi4yMDVlLTAxICAgKQ0KdmFyaWFibGVfbmFtZSA8LSAiQ2xlYW5lbGluZXNzIg0KDQojIFTDrW5oIHRvw6FuIHThu5VuZyBnacOhIHRy4buLDQp0b3RhbCA8LSBzdW0odmFsdWVzKQ0KDQojIFTDrW5oIHBo4bqnbiB0csSDbSBjaG8gbeG7l2kgbeG7qWMgxJHhu5kNCnBlcmNlbnRhZ2VzIDwtIHZhbHVlcyAvIHRvdGFsICogMTAwDQoNCiMgVOG6oW8gZGF0YWZyYW1lDQpkZiA8LSBkYXRhLmZyYW1lKGxhYmVscywgdmFsdWVzLCBwZXJjZW50YWdlcykNCg0KIyBW4bq9IGJp4buDdSDEkeG7kyBj4buZdA0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRmLCBhZXMoeCA9IGxhYmVscywgeSA9IHBlcmNlbnRhZ2VzKSkgKw0KICBnZW9tX2NvbChmaWxsID0gJyM0YzcyYjAnKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzcHJpbnRmKCIlLjJmJSUiLCBwZXJjZW50YWdlcykpLCB2anVzdCA9IC0wLjUsIHNpemUgPSA0KSArDQogIGxhYnMoeCA9ICJN4bupYyDEkeG7mSDEkcOhbmggZ2nDoSIsIHkgPSAiUGjhuqduIHRyxINtIiwgdGl0bGUgPSBwYXN0ZTAoIlBow6JuIGLhu5EgY8OhYyBt4bupYyDEkeG7mSDEkcOhbmggZ2nDoSBjaG8gIiwgdmFyaWFibGVfbmFtZSkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpL4bq/dCBxdeG6oyBiaeG7g3UgxJHhu5MgY2hvIHRo4bqleSBwaOG6p24gbOG7m24gaMOgbmgga2jDoWNoIMSRw6FuaCBnacOhIG3hu6ljIMSR4buZIHbhu4cgc2luaCBj4bunYSBow6NuZyBow6BuZyBraMO0bmcgbMOgIHTDrWNoIGPhu7FjLCB24bubaSB04bu3IGzhu4cgIkjDoGkgbMOybmciIHbDoCAiUuG6pXQgaMOgaSBsw7JuZyIgY2hp4bq/bSB04buVbmcgY+G7mW5nIGfhuqduIDUwJSAoNDguMTklKS4gVHV5IG5oacOqbiwgduG6q24gY8OybiBt4buZdCB04bu3IGzhu4cgxJHDoW5nIGvhu4MgaMOgbmgga2jDoWNoIGPhuqNtIHRo4bqleSBraMO0bmcgaMOgaSBsw7JuZywgduG7m2kgbeG7qWMgxJHhu5kgIlThu4ciIHbDoCAiUuG6pXQgdOG7hyIgY2hp4bq/bSBraG/huqNuZyAyOC40NiUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGPDsyBz4buxIHBow6JuIGjDs2EgcsO1IHLhu4d0IHRyb25nIG3hu6ljIMSR4buZIGjDoGkgbMOybmcgduG7gSBt4bupYyDEkeG7mSB24buHIHNpbmguIA0KRMO5IHBo4bqnbiBs4bubbiBow6BuaCBraMOhY2ggY8OzIGPhuqNtIG5o4bqtbiB0w61jaCBj4buxYyB24buBIG3hu6ljIMSR4buZIHbhu4cgc2luaCwgduG6q24gY8OybiBt4buZdCB04bu3IGzhu4cga2jDtG5nIG5o4buPIGPhuqNtIHRo4bqleSBraMO0bmcgaMOgaSBsw7JuZy4gxJBp4buBdSBuw6B5IGNo4buJIHJhIHLhurFuZywgYsOqbiBj4bqhbmggbmjhu69uZyBwaOG6o24gaOG7k2kgdMOtY2ggY+G7sWMsIGjDo25nIGjDoG5nIGtow7RuZyBj4bqnbiBjaMO6IHRy4buNbmcgY+G6o2kgdGhp4buHbiBjaOG6pXQgbMaw4bujbmcgduG7hyBzaW5oIMSR4buDIG7Dom5nIGNhbyB0cuG6o2kgbmdoaeG7h20gY+G7p2EgaMOgbmgga2jDoWNoLCDEkeG6t2MgYmnhu4d0IGzDoCBuaOG7r25nIG5nxrDhu51pIGPDsyBj4bqjbSBuaOG6rW4gdGnDqnUgY+G7sWMuDQoNCiMjIyBCaeG6v24gRGVwYXJ0dXJlIERlbGF5IGluIE1pbnR1dGVzDQoNClRyxrDhu5tjIGtoaSBwaMOibiB0w61jaCBiaeG6v24gRGVwYXJ0dXJlIERlbGF5IGluIE1pbnR1dGVzLCBuaMOzbSBjaMO6bmcgdMO0aSBz4bq9IHBow6JuIG5ow7NtIHRow6BuaCAzIG5ow7NtIHRo4budaSBnaWFuIGto4bufaSBow6BuaDogdHLhu4Ugbmfhuq9uIGjhuqFuICgwLTYwIHBow7p0KSwgdHLhu4UgdHJ1bmcgaOG6oW4gKDYwLTI0MCBwaMO6dCksIHRy4buFIGTDoGkgaOG6oW4gKDI0MCBwaMO6dCB0cuG7nyBsw6puKS4NCg0KQmnhur9uIERlcGFydHVyZSBEZWxheSBpbiBNaW50dXRlcyB0aOG7gyBoaeG7h24gdGjhu51pIGdpYW4ga2jhu59pIGjDoG5oIHRy4buFIGPhu6dhIGNodXnhur9uIGJheS4NCg0KYGBge3J9DQpkYXRhJGRkIDwtIGN1dChkYXRhJGBEZXBhcnR1cmUgRGVsYXkgaW4gTWludXRlc2AsIA0KICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoLTIsMCwgNjAsIDI0MCwgSW5mKSwgDQogICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygixJHDum5nIGdp4budIiwibmfhuq9uIGjhuqFuIiwidHJ1bmcgaOG6oW4iLCAiZMOgaSBo4bqhbiIpKQ0KYGBgDQoNCkLDonkgZ2nhu50gY2jDum5nIHTDtGkgc+G6vSBs4bqtcCBi4bqjbmcgdOG6p24gc+G7kSDEkeG7gyB0aOG7gyBoaeG7h24gcsO1IG5ow7NtIHRo4budaSBnaWFuIGto4bufaSBow6BuaA0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkZGQpDQpgYGANCg0KYGBge3J9DQpsIDwtIHByb3AudGFibGUodGFibGUoZGF0YSRkZCkpICogMTAwDQpsDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZGF0YSRkZCkpIA0KY29sbmFtZXMobCkgPC0gYygiZGQiLCAiQ291bnQiKQ0KZ2dwbG90KGwsIGFlcyh4ID0gZGQsIHkgPSBDb3VudCwgZmlsbCA9IGRkKSkgKyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjMsIHNpemUgPSAzLjUpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiU+G7kSBsxrDhu6NuZyIsDQogICAgdGl0bGUgPSAiUGjDom4gYuG7kSBjw6FjIG5ow7NtIHRo4budaSBnaWFuIGto4bufaSBow6BuaCINCiAgKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgZmFjZSA9ICJib2xkIiksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGNvbG9yID0gImdyZXk1MCIpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCINCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KbCRQZXJjZW50YWdlIDwtIChsJENvdW50IC8gc3VtKGwkQ291bnQpKSAqIDEwMA0KDQpnZ3Bsb3QobCwgYWVzKHggPSAiIiwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBkZCkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgbGFicyh0aXRsZSA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIiwgeCA9ICIiLCB5ID0gIiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKHJvdW5kKFBlcmNlbnRhZ2UsIDIpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDQpDQpgYGANCg0KDQpCaeG7g3UgxJHhu5MgdOG7qyBjdeG7mWMga2jhuqNvIHPDoXQgY2hvIHRo4bqleSBwaMOibiBi4buRIG5ow7NtIHRo4budaSBnaWFuIGNodXnhur9uIGJheSBj4bqldCBjw6FuaCBtdeG7mW4gY2hvIHRo4bqleSBy4bqxbmcgcGjhuqduIGzhu5tuIGPDoWMgY2h1eeG6v24gYmF5ICg1Ni41NCUpIMSR4bq/biDEkcO6bmcgZ2nhu50sIHbhu5tpIGPhuqV0IGPDoW5oIG114buZbiBuZ+G6r24gaOG6oW4gbMOgIHBo4buVIGJp4bq/biB0aOG7qSBoYWkgKDM2Ljc3JSkuIEPDoWMgbmjDs20gdGjhu51pIGdpYW4gY2h1eeG6v24gYmF5IG114buZbiB0cnVuZyBo4bqhbiAoNi4yNSUpIHbDoCBkw6BpIGjhuqFuICgwLjQ0JSkgw610IHBo4buVIGJp4bq/biBoxqFuIG5oaeG7gXUuIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHLhurFuZywgbeG6t2MgZMO5IGNodXnhur9uIGJheSBj4bqldCBjw6FuaCBtdeG7mW4gdHJvbmcgdGjhu51pIGdpYW4gbmfhuq9uIGjhuqFuIGzDoCBraMOhIHBo4buVIGJp4bq/biwgY2h1eeG6v24gYmF5IGPhuqV0IGPDoW5oIG114buZbiB0cm9uZyB0aOG7nWkgZ2lhbiBkw6BpIGjhuqFuIGzDoCB0xrDGoW5nIMSR4buRaSBoaeG6v20uDQoNCiMjIyBCaeG6v24gQXJyaXZhbCBEZWxheSBpbiBNaW50dXRlcw0KDQpUcsaw4bubYyBraGkgcGjDom4gdMOtY2ggYmnhur9uIEFycml2YWwgRGVsYXkgaW4gTWludHV0ZXMsIG5ow7NtIGNow7puZyB0w7RpIHPhur0gcGjDom4gbmjDs20gdGjDoG5oIDMgbmjDs20gdGjhu51pIGdpYW4gaOG6oSBjw6FuaDogdHLhu4Ugbmfhuq9uIGjhuqFuICgwLTYwIHBow7p0KSwgdHLhu4UgdHJ1bmcgaOG6oW4gKDYwLTI0MCBwaMO6dCksIHRy4buFIGTDoGkgaOG6oW4gKDI0MCBwaMO6dCB0cuG7nyBsw6puKS4NCg0KQmnhur9uIEFycml2YWwgRGVsYXkgaW4gTWludHV0ZXMgdGjhu4MgaGnhu4duIHRo4budaSBnaWFuIGjhuqEgY8OhbmggdHLhu4UgY+G7p2EgY2h1eeG6v24gYmF5Lg0KDQpgYGB7cn0NCmRhdGEkYWQgPC0gY3V0KGRhdGEkYEFycml2YWwgRGVsYXkgaW4gTWludXRlc2AsIA0KICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoLTIsIDAsIDYwLCAyNDAsIEluZiksIA0KICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIsSRw7puZyBnaeG7nSIsIm5n4bqvbiBo4bqhbiIsInRydW5nIGjhuqFuIiwgImTDoGkgaOG6oW4iKSkNCmBgYA0KDQpCw6J5IGdp4budIGNow7puZyB0w7RpIHPhur0gbOG6rXAgYuG6o25nIHThuqduIHPhu5EgxJHhu4MgdGjhu4MgaGnhu4duIHLDtSBuaMOzbSB0aOG7nWkgZ2lhbiBo4bqhIGPDoW5oDQoNCmBgYHtyfQ0KdGFibGUoZGF0YSRhZCkNCmBgYA0KDQpgYGB7cn0NCmsgPC0gcHJvcC50YWJsZSh0YWJsZShkYXRhJGRkKSkgKiAxMDANCmsNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KayA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGRhdGEkYWQpKSANCmNvbG5hbWVzKGspIDwtIGMoImFkIiwgIkNvdW50IikNCmdncGxvdChrLCBhZXMoeCA9IGFkLCB5ID0gQ291bnQsIGZpbGwgPSBhZCkpICsgDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgdmp1c3QgPSAtMC4zLCBzaXplID0gMy41KSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIlPhu5EgbMaw4bujbmciLA0KICAgIHRpdGxlID0gIlBow6JuIGLhu5EgbmjDs20gdGjhu51pIGdpYW4gaOG6oSBjw6FuaCINCiAgKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgZmFjZSA9ICJib2xkIiksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGNvbG9yID0gImdyZXk1MCIpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCINCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KayRQZXJjZW50YWdlIDwtIChrJENvdW50IC8gc3VtKGskQ291bnQpKSAqIDEwMA0KDQpnZ3Bsb3QoaywgYWVzKHggPSAiIiwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBhZCkpICsNCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgbGFicyh0aXRsZSA9ICJU4bu3IGzhu4cgcGjhuqduIHRyxINtIiwgeCA9ICIiLCB5ID0gIiIpICsNCiAgdGhlbWVfdm9pZCgpICsgDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKHJvdW5kKFBlcmNlbnRhZ2UsIDIpLCAiJSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDQpDQpgYGANCg0KQmnhu4N1IMSR4buTIHBow6JuIGLhu5EgbmjDs20gdGjhu51pIGdpYW4gaOG6oSBjw6FuaCBjaG8gdGjhuqV5IHBo4bqnbiBs4bubbiBjw6FjIGNodXnhur9uIGJheSBo4bqhIGPDoW5oIMSRw7puZyBnaeG7nSBn4buTbSAxNDY3NyBuZ8aw4budaSBjaGnhur9tIDU2LjUlIGhv4bq3YyB0cm9uZyB0aOG7nWkgZ2lhbiBuZ+G6r24gaOG6oW4gZ+G7k20gOTUzOCBuZ8aw4budaSBjaGnhur9tIDM2LjcyJS4gU+G7kSBsxrDhu6NuZyBjaHV54bq/biBiYXkgY8OzIHRo4budaSBnaWFuIGjhuqEgY8OhbmggdHJ1bmcgaOG6oW4gZ+G7k20gMTY1MSBjaGnhur9tIDYuMzYlICB2w6AgZMOgaSBo4bqhbiBn4buTbSAxMTAgbmfGsOG7nWkgY2hp4bq/bSAwLjQyJSBsw6AgcuG6pXQgw610LiBL4bq/dCBxdeG6oyBuw6B5IHBo4bqjbiDDoW5oICDEkWEgc+G7kSBjaHV54bq/biBiYXkgxJHDoXAgeHXhu5FuZyDEkcO6bmcgZ2nhu50gaG/hurdjIHPhu5ttLg0KDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyAyIGJp4bq/biANCg0KIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjdXN0b21lciB0eXBlIA0KDQpgYGB7cn0NCmFkZG1hcmdpbnModGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24sIGRhdGEkYEN1c3RvbWVyIFR5cGVgKSkNCmBgYA0KDQpgYGB7cn0NCnByb3AudGFibGUodGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24sIGRhdGEkYEN1c3RvbWVyIFR5cGVgKSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpkYXRhICU+JSBnZ3Bsb3QoYWVzKHggPSBgc2F0aXNmYWN0aW9uYCwgZmlsbCA9IGBDdXN0b21lciBUeXBlYCkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudCAvIHN1bShjb3VudCkpLCBhY2N1cmFjeSA9IDAuMDEpKSwgDQogICAgICAgICAgICBzdGF0ID0gImNvdW50IiwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgDQogICAgICAgICAgICB2anVzdCA9IC0wLjUsIA0KICAgICAgICAgICAgY29sb3IgPSAncmVkJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJMb3lhbCBDdXN0b21lciIgPSAiYmx1ZSIsICJkaXNsb3lhbCBDdXN0b21lciIgPSAiZ3JlZW4iKSkgKyBsYWJzKCBmaWxsID0gJ0xv4bqhaSBraMOhY2ggaMOgbmcnLHRpdGxlID0gIlPhu7EgaMOgaSBsw7JuZyB24buBIGjDo25nIGjDoG5nIGtow7RuZyDhu58gdOG7q25nIGxv4bqhaSBraMOhY2ggaMOgbmciKSArIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClThu6sga+G6v3QgcXXhuqMgdHLDqm4sIGPDsyB0aOG7gyB0aOG6pXkgcuG6sW5nIGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY8OzIG3hu6ljIMSR4buZIGjDoGkgbMOybmcgY2hp4bq/bSAzOS4zNSUgY2FvIGjGoW4gc28gduG7m2kga2jDoWNoIGjDoG5nIGtow7RuZyB0cnVuZyB0aMOgbmggY2hp4bq/bSA0LjY1JS4gQ+G7pSB0aOG7gywgdOG7tyBs4buHIGtow6FjaCBow6BuZyBow6BpIGzDsm5nIHRyb25nIG5ow7NtIGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY2FvIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyB0cnVuZyB0aMOgbmguIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IHLhurFuZyBt4bupYyDEkeG7mSBow6BpIGzDsm5nIGPDsyBt4buRaSBsacOqbiBo4buHIGNo4bq3dCBjaOG6vSB24bubaSBz4buxIHRydW5nIHRow6BuaCBj4bunYSBraMOhY2ggaMOgbmcsIHbDoCB2aeG7h2MgbsOibmcgY2FvIG3hu6ljIMSR4buZIGjDoGkgbMOybmcgY+G7p2Ega2jDoWNoIGjDoG5nIGPDsyB0aOG7gyBnacO6cCB0xINuZyBjxrDhu51uZyBz4buxIHRydW5nIHRow6BuaCBj4bunYSBo4buNIMSR4buRaSB24bubaSBk4buLY2ggduG7pS4NCg0KIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjbGFzcw0KDQpgYGB7cn0NCmFkZG1hcmdpbnModGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24sIGRhdGEkYENsYXNzYCkpDQpgYGANCg0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJGBDbGFzc2ApKQ0KYGBgDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KZGF0YSAlPiUgZ2dwbG90KGFlcyh4ID0gYHNhdGlzZmFjdGlvbmAsIGZpbGwgPSBgQ2xhc3NgKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChhZnRlcl9zdGF0KGNvdW50IC8gc3VtKGNvdW50KSksIGFjY3VyYWN5ID0gMC4wMSkpLCANCiAgICAgICAgICAgIHN0YXQgPSAiY291bnQiLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCANCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwgDQogICAgICAgICAgICBjb2xvciA9ICdyZWQnKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIkJ1c2luZXNzIiA9ICJibHVlIiwgIkVjbyBQbHVzIiA9ICJncmVlbiIsICJFY28iID0gImJyb3duIikpICsgbGFicyggZmlsbCA9ICdI4bqhbmcgZ2jhur8nLHRpdGxlID0gIlPhu7EgaMOgaSBsw7JuZyB24buBIGjDo25nIGjDoG5nIGtow7RuZyDhu58gdOG7q25nIGxv4bqhaSBo4bqhbmcgZ2jhur8iKSArIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCk5o4bqtbiB4w6l0Og0KVOG7qyBr4bq/dCBxdeG6oyBiaeG7g3UgxJHhu5MgdHLDqm4gY8OzIHRo4buDIHRo4bqleSBwaOG6p24gbOG7m24ga2jDoWNoIGjDoG5nIGtow7RuZyBow6BpIGzDsm5nIG5n4buTaSDhu58gaOG6oW5nIGdo4buDIHRoxrDhu51uZyAoRWNvKSBjaGnhur9tIHThu7cgdOG7hyBjYW8gbmjhuqV0IDM1LDg5JSBzbyB24bubaSBo4bqhbmcgZ2jhur8gdGjGsMahbmcgZ2lhIChCdXNpbmVzcykgY2hp4bq/bSAxNCw2NiUgdsOgIGjhuqFuZyBnaOG6vyBjYW8gY+G6pXAgRWNvIFBsdXMgY2hp4bq/bSA1LDU1JS4gTeG6t2Mga2jDoWMga2jDoWNoIGjDoG5nIGjDoGkgbMOybmcgbmhp4buBdSBuaOG6pXQga2hpIG5n4buTaSDhu58gaOG6oW5nIGdo4bq/IHRoxrDGoW5nIGdpYSBjaGnhur9tIDMzLDQ0JSBzbyB24bubaSAyIGjhuqFuZyBnaOG6vyBjw7JuIGzhuqFpIGzDoCBo4bqhbmcgZ2jhur8gdGjGsOG7nW5nIGNoaeG6v20gOCw2MyUgdsOgIGjhuqFuZyBnaOG6vyBjYW8gY+G6pXAgMSw4MyUuIE5ow6xuIGNodW5nIGPDsyB0aOG7gyB0aOG6pXkgc+G7sSDEkcOhbmggZ2nDoSBj4bunYSBraMOhY2ggaMOgbmcgaOG6oW5nIHRoxrDGoW5nIGdpYSDEkeG7kWkgduG7m2kgaOG6oW5nIHRoxrDGoW5nIGdpYSBsw6AgdMawxqFuZyDEkeG7kWkgY2FvLiBDw7JuIHPhu5EgbmfGsOG7nWkgxJHEg25nIGvDvSBo4bqhbmcgZ2jhur8gdGjGsOG7nW5nIHRow6wgxJHDoW5oIGdpw6EgdHLhuqNpIG5naGnhu4dtIHLhuqV0IHThu5F0Lg0KDQojIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIEluZmxpZ2h0IHNlcnZpY2UNCg0KYGBge3J9DQpkYXRhJGBJbmZsaWdodCBzZXJ2aWNlYCA9IGZhY3RvcihkYXRhJGBJbmZsaWdodCBzZXJ2aWNlYCwNCiAgICAgICAgICAgICAgIGxldmVscyA9IGMoMCwgMSwgMiwgMywgNCwgNSksDQogICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJLaMO0bmcgxJHDoW5oIGdpw6EiLCJS4bqldCB04buHIiwgIlThu4ciLCAiQsOsbmggdGjGsOG7nW5nIiwgIkjDoGkgbMOybmciLCAiUuG6pXQgaMOgaSBsw7JuZyIpKQ0KYGBgDQoNCmBgYHtyfQ0KYWRkbWFyZ2lucyh0YWJsZShkYXRhJGBzYXRpc2ZhY3Rpb25gLCBkYXRhJGBJbmZsaWdodCBzZXJ2aWNlYCkpDQpgYGANCg0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJGBJbmZsaWdodCBzZXJ2aWNlYCkpDQpgYGANCg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpkYXRhICU+JSBnZ3Bsb3QoYWVzKHggPSBgc2F0aXNmYWN0aW9uYCwgZmlsbCA9IGRhdGEkYEluZmxpZ2h0IHNlcnZpY2VgKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChhZnRlcl9zdGF0KGNvdW50IC8gc3VtKGNvdW50KSksIGFjY3VyYWN5ID0gMC4wMSkpLCANCiAgICAgICAgICAgIHN0YXQgPSAiY291bnQiLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCANCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwgDQogICAgICAgICAgICBjb2xvciA9ICdibGFjaycpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiS2jDtG5nIMSRw6FuaCBnacOhIiA9ICJibHVlIiwgIlLhuqV0IHThu4ciID0gImdyZWVuIiwgIlThu4ciID0gImJyb3duIiwiQsOsbmggdGjGsOG7nW5nIj0icHVycGxlIiwgIkjDoGkgbMOybmciPSJwaW5rIiwgIlLhuqV0IGjDoGkgbMOybmciPSJncmV5IiApKSArIGxhYnMoIGZpbGwgPSAnxJDDoW5oIGdpw6EnLHRpdGxlID0gIlPhu7EgaMOgaSBsw7JuZyB24buBIGjDo25nIGjDoG5nIGtow7RuZyB24buBIGThu4tjaCB24bulIHRyw6puIGNodXnhur9uIGJheSAiKSArIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClThu7cgbOG7hyBraMOhY2ggaMOgbmcgaMOgaSBsw7JuZyBraGkgdGhhbSBnaWEgZOG7i2NoIHbhu6UgaMOgbmcga2jDtG5nIHbhu4EgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IGPhuqNtIHRo4bqleSBow6BpIGzDsm5nIGNoaeG6v20gdOG7iSBs4buHIGNhbyBuaOG6pXQgbMOgIDE3LjM0JSwgdsOgIHLhuqV0IGjDoGkgbMOybmcgMTYsNDglIGNobyB0aOG6pXkgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IGPhu6dhIGjDo25nIGjDoG5nIGtow7RuZyBkw6BuaCBjaG8ga2jDoWNoIGjDoG5nIGPhu7FjIGvDrCB04buRdC4gIEPDsm4gbmjhu69uZyBraMOhY2ggaMOgbmcga2jDtG5nIGjDoGkgbMOybmcgduG7gSBk4buLY2ggduG7pSB0csOqbiBjaHV54bq/biBiYXkgY2hp4bq/bSB04buJIGzhu4cgY2FvIG5o4bqldCBsw6AgaMOgaSBsw7JuZyAxOCw3JSwgdsOgIHRo4bqlcCBuaOG6pXQgbMOgIHLhuqV0IHThu4cgY2hp4bq/bSA0LDc5JS4gQ2jDrW5oIHbDrCB0aOG6vyB2aeG7h2MgduG7gSBk4buLY2ggduG7pSB0csOqbiBjaHV54bq/biBiYXkga2jDtG5nIOG6o25oIGjGsOG7n25nIGfDrCBuaGnhu4F1IMSR4bq/biBz4buxIGjDoGkgbMOybmcgY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQojIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIERlcGFydHVyZSBEZWxheSBpbiBNaW50dXRlcw0KDQpgYGB7cn0NCmFkZG1hcmdpbnModGFibGUoZGF0YSRgc2F0aXNmYWN0aW9uYCwgZGF0YSRkZCkpDQpgYGANCg0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJGRkKSkNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmRhdGEgJT4lIGdncGxvdChhZXMoeCA9IGBzYXRpc2ZhY3Rpb25gLCBmaWxsID0gZGF0YSRgZGRgKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChhZnRlcl9zdGF0KGNvdW50IC8gc3VtKGNvdW50KSksIGFjY3VyYWN5ID0gMC4wMSkpLCANCiAgICAgICAgICAgIHN0YXQgPSAiY291bnQiLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCANCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwgDQogICAgICAgICAgICBjb2xvciA9ICdibGFjaycpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygixJHDum5nIGdp4budIiA9ICJyZWQiLCJuZ+G6r24gaOG6oW4iID0gImJsdWUiLCAidHJ1bmcgaOG6oW4iID0gImdyZWVuIiwgImTDoGkgaOG6oW4iID0gImJyb3duIikpICsgbGFicyggZmlsbCA9ICdUaOG7nWkgZ2lhbiBj4bqldCBjw6FuaCB0cuG7hScsdGl0bGUgPSAiU+G7sSBow6BpIGzDsm5nIHbhu4EgaMOjbmcgaMOgbmcga2jDtG5nIMSR4buRaSB24bubaSB0aOG7nWkgZ2lhbiBj4bqldCBjw6FuaCAiKSArIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IGjDoG5oIGtow6FjaCBow6BpIGzDsm5nIHRoxrDhu51uZyBjw7MgeHUgaMaw4bubbmcgZ+G6t3Agw610IHPhu7EgY2jhuq1tIHRy4buFIGjGoW4sIHbhu5tpIHThu7cgbOG7hyBjYW8gaMahbiB0cm9uZyBuaMOzbSAixJDDum5nIGdp4budIiAoMjYuNDAlKSBzbyB24bubaSBuaMOzbSB0cnVuZyBs4bqtcCBob+G6t2Mga2jDtG5nIGjDoGkgbMOybmcgKDMwLjE1JSkuIE5nxrDhu6NjIGzhuqFpLCBow6BuaCBraMOhY2ggdHJ1bmcgbOG6rXAgaG/hurdjIGtow7RuZyBow6BpIGzDsm5nIGPDsyB04bu3IGzhu4cgY2FvIGjGoW4gdHJvbmcgY8OhYyBuaMOzbSB0aOG7nWkgZ2lhbiBjaOG6rW0gdHLhu4UsIMSR4bq3YyBiaeG7h3QgbMOgIG5ow7NtICJOZ+G6r24gaOG6oW4iICgyMS43MCUgc28gduG7m2kgMTUuMDclKS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgc+G7sSBjaOG6rW0gdHLhu4UsIMSR4bq3YyBiaeG7h3QgbMOgIHRyb25nIGtob+G6o25nIHRo4budaSBnaWFuIG5n4bqvbiBo4bqhbiwg4bqjbmggaMaw4bufbmcgdGnDqnUgY+G7sWMgxJHhur9uIHPhu7EgaMOgaSBsw7JuZyBj4bunYSBow6BuaCBraMOhY2guDQoNCiMjIyBCaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gQXJyaXZhbCBEZWxheSBpbiBNaW50dXRlcw0KDQpgYGB7cn0NCmFkZG1hcmdpbnModGFibGUoZGF0YSRgc2F0aXNmYWN0aW9uYCwgZGF0YSRhZCkpDQpgYGANCg0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJGFkKSkNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmRhdGEgJT4lIGdncGxvdChhZXMoeCA9IGBzYXRpc2ZhY3Rpb25gLCBmaWxsID0gZGF0YSRhZCkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudCAvIHN1bShjb3VudCkpLCBhY2N1cmFjeSA9IDAuMDEpKSwgDQogICAgICAgICAgICBzdGF0ID0gImNvdW50IiwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgDQogICAgICAgICAgICB2anVzdCA9IC0wLjUsIA0KICAgICAgICAgICAgY29sb3IgPSAnYmxhY2snKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIsSRw7puZyBnaeG7nSIgPSAicmVkIiwibmfhuq9uIGjhuqFuIiA9ICJibHVlIiwgInRydW5nIGjhuqFuIiA9ICJncmVlbiIsICJkw6BpIGjhuqFuIiA9ICJicm93biIpKSArIGxhYnMoIGZpbGwgPSAnVGjhu51pIGdpYW4gY+G6pXQgY8OhbmggdHLhu4UnLHRpdGxlID0gIlPhu7EgaMOgaSBsw7JuZyB24buBIGjDo25nIGjDoG5nIGtow7RuZyDEkeG7kWkgduG7m2kgdGjhu51pIGdpYW4gY+G6pXQgY8OhbmggIikgKyB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpCaeG7g3UgxJHhu5MgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBt4bupYyDEkeG7mSBow6BpIGzDsm5nIHbDoCB0aOG7nWkgZ2lhbiDEkeG6v24gdHLhu4UgY+G7p2EgY2h1eeG6v24gYmF5IGNobyB0aOG6pXkgcuG6sW5nIGjDoG5oIGtow6FjaCBow6BpIGzDsm5nIGPDsyB4dSBoxrDhu5tuZyBn4bq3cCDDrXQgc+G7sSBjaOG6rW0gdHLhu4UgaMahbi4gQ+G7pSB0aOG7gywgdOG7tyBs4buHIGjDoG5oIGtow6FjaCBow6BpIGzDsm5nIGNhbyBuaOG6pXQgbMOgIHRyb25nIG5ow7NtICLEkMO6bmcgZ2nhu50iICgyNy4wNyUpLCBnaeG6o20gZOG6p24gdHJvbmcgY8OhYyBuaMOzbSB0aOG7nWkgZ2lhbiDEkeG6v24gdHLhu4UsIHbhu5tpIHThu7cgbOG7hyB0aOG6pXAgbmjhuqV0IHRyb25nIG5ow7NtICJEw6BpIGjhuqFuIiAoMC4xNiUpLiBOZ8aw4bujYyBs4bqhaSwgaMOgbmgga2jDoWNoIHRydW5nIGzhuq1wIGhv4bq3YyBraMO0bmcgaMOgaSBsw7JuZyBjw7MgdOG7tyBs4buHIGNhbyBoxqFuIHRyb25nIGPDoWMgbmjDs20gdGjhu51pIGdpYW4gxJHhur9uIHRy4buFLCDEkeG6t2MgYmnhu4d0IGzDoCBuaMOzbSAiTmfhuq9uIGjhuqFuIiAoMjIuMjYlKS4gxJBp4buBdSBuw6B5IHBo4bqjbiDDoW5oIHLhurFuZyBz4buxIGNo4bqtbSB0cuG7hSwgxJHhurdjIGJp4buHdCBsw6AgdHJvbmcga2hv4bqjbmcgdGjhu51pIGdpYW4gbmfhuq9uIGjhuqFuLCDhuqNuaCBoxrDhu59uZyB0acOqdSBj4buxYyDEkeG6v24gc+G7sSBow6BpIGzDsm5nIGPhu6dhIGjDoG5oIGtow6FjaC4NCg0KIyMgVGjhu5FuZyBrw6ogc3V5IGRp4buFbg0KDQojIyMgS2nhu4NtIHRyYSB0w61uaCDEkeG7mWMgbOG6rXAgY+G7p2EgMiBiaeG6v24NCg0KIyMjIyBCaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gY3VzdG9tZXIgdHlwZSANCg0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJGBDdXN0b21lciBUeXBlYCkpDQpgYGANCg0KR2nhuqMgdGh1eeG6v3Q6DQoNCkgwOiBiaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gY3VzdG9tZXIgdHlwZSDEkeG7mWMgbOG6rXANCg0KSDE6IGJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjdXN0b21lciB0eXBlIGtow7RuZyDEkeG7mWMgbOG6rXANCg0KTeG7qWMgw70gbmdoxKlhOiDOsT0gMC4wNQ0KDQpUYSBjw7MgcF92YWx1ZSA8IM6xLCB24bqteSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuDQoNClbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JSwgc+G7sSBow6BpIGzDsm5nIGPhu6dhIGtow6FjaCBow6BuZyBjw7MgY2jhu4t1IHPhu7Eg4bqjbmggaMaw4bufbmcgY+G7p2EgbG/huqFpIGtow6FjaCBow6BuZy4NCg0KIyMjIyBCaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gY2xhc3MNCg0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJENsYXNzKSkNCmBgYA0KDQpHaeG6oyB0aHV54bq/dDoNCg0KSDA6IGJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjbGFzcyDEkeG7mWMgbOG6rXANCg0KSDE6IGJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjbGFzcyBraMO0bmcgxJHhu5ljIGzhuq1wDQoNCk3hu6ljIMO9IG5naMSpYTogzrE9IDAuMDUNCg0KVGEgY8OzIHBfdmFsdWUgPCDOsSwgduG6rXkgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLg0KDQpW4bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIHPhu7EgaMOgaSBsw7JuZyBj4bunYSBraMOhY2ggaMOgbmcgY8OzIGNo4buLdSBz4buxIOG6o25oIGjGsOG7n25nIGPhu6dhIGjhuqFuZyBnaOG6vy4NCg0KDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIEluZmxpZ2h0IHNlcnZpY2UNCg0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxlKGRhdGEkc2F0aXNmYWN0aW9uLCBkYXRhJGBJbmZsaWdodCBzZXJ2aWNlYCkpDQpgYGANCg0KR2nhuqMgdGh1eeG6v3Q6DQoNCkgwOiBiaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gSW5mbGlnaHQgc2VydmljZSDEkeG7mWMgbOG6rXANCg0KSDE6IGJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBJbmZsaWdodCBzZXJ2aWNlIGtow7RuZyDEkeG7mWMgbOG6rXANCg0KTeG7qWMgw70gbmdoxKlhOiDOsT0gMC4wNQ0KDQpUYSBjw7MgcF92YWx1ZSA8IM6xLCB24bqteSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuDQoNClbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JSwgc+G7sSBow6BpIGzDsm5nIGPhu6dhIGtow6FjaCBow6BuZyBjw7MgY2jhu4t1IHPhu7Eg4bqjbmggaMaw4bufbmcgY+G7p2EgZOG7i2NoIHbhu6UgY3VuZyBj4bqlcCB0csOqbiBjaHV54bq/biBiYXkuDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIERlcGFydHVyZSBEZWxheSBpbiBNaW50dXRlcw0KDQpgYGB7cn0NCmNoaXNxLnRlc3QodGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24sIGRhdGEkZGQpKQ0KYGBgDQoNCkdp4bqjIHRodXnhur90Og0KDQpIMDogYmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIERlcGFydHVyZSBEZWxheSBpbiBNaW50dXRlcyDEkeG7mWMgbOG6rXANCg0KSDE6IGJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBEZXBhcnR1cmUgRGVsYXkgaW4gTWludHV0ZXMga2jDtG5nIMSR4buZYyBs4bqtcA0KDQpN4bupYyDDvSBuZ2jEqWE6IM6xPSAwLjA1DQoNClRhIGPDsyBwX3ZhbHVlIDwgzrEsIHbhuq15IGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMC4NCg0KVuG7m2kgbeG7qWMgw70gbmdoxKlhIDUlLCBz4buxIGjDoGkgbMOybmcgY+G7p2Ega2jDoWNoIGjDoG5nIGPDsyBjaOG7i3Ugc+G7sSDhuqNuaCBoxrDhu59uZyBj4bunYSB0aOG7nWkgZ2lhbiBj4bqldCBjw6FuaCB0cuG7hSBj4bunYSBjaHV54bq/biBiYXkNCg0KIyMjIyBCaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gQXJyaXZhbCBEZWxheSBpbiBNaW50dXRlcw0KDQpgYGB7cn0NCmNoaXNxLnRlc3QodGFibGUoZGF0YSRzYXRpc2ZhY3Rpb24sIGRhdGEkYWQpKQ0KYGBgDQoNCkdp4bqjIHRodXnhur90Og0KDQpIMDogYmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIEFycml2YWwgRGVsYXkgaW4gTWludHV0ZXMgxJHhu5ljIGzhuq1wDQoNCkgxOiBiaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gQXJyaXZhbCBEZWxheSBpbiBNaW50dXRlcyBraMO0bmcgxJHhu5ljIGzhuq1wDQoNCk3hu6ljIMO9IG5naMSpYTogzrE9IDAuMDUNCg0KVGEgY8OzIHBfdmFsdWUgPCDOsSwgduG6rXkgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLg0KDQpW4bubaSBt4bupYyDDvSBuZ2jEqWEgNSUsIHPhu7EgaMOgaSBsw7JuZyBj4bunYSBraMOhY2ggaMOgbmcgY8OzIGNo4buLdSBz4buxIOG6o25oIGjGsOG7n25nIGPhu6dhIHRo4budaSBnaWFuIGjhuqEgY8OhbmggdHLhu4UgY+G7p2EgY2h1eeG6v24gYmF5DQoNCiMjIyBSZWxhdGl2ZSByaXNrIHbDoCBPZGQgcmF0aW8NCg0KIyMjIyBCaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gY3VzdG9tZXIgdHlwZQ0KDQpSZWxhdGl2ZSByaXNrDQoNCmBgYHtyfQ0KcnIxIDwtIHRhYmxlKGRhdGEkYEN1c3RvbWVyIFR5cGVgLGRhdGEkc2F0aXNmYWN0aW9uKQ0KYWRkbWFyZ2lucyhycjEpDQpSZWxSaXNrKHJyMSkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyBSUiA9IDEuNDQyOTM4LCBjw7MgdGjhu4MgdGjhuqV5IHLhurFuZyB0cm9uZyBuaMOzbSBraMOhY2gga2jDtG5nIGjDoGkgbMOybmcsIHjDoWMgc3XhuqV0IGtow6FjaCBow6BuZyBraMO0bmcgdHJ1bmcgdGjDoG5oIGNhbyBn4bqlcCAxLjQ0IGzhuqduIHNvIHbhu5tpIGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmguDQoNCk9kZCBSYXRpbw0KDQpgYGB7cn0NCmFkZG1hcmdpbnMocnIxKQ0KT2Rkc1JhdGlvKHJyMSkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyBPUiA9IDIuNzU5NjUyLCBPZGQga2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCBraMO0bmcgaMOgaSBsw7JuZyBn4bqlcCAyLjc2IGzhuqduIE9kZCBraMOhY2ggaMOgbmcgdHJ1bmcgdGjDoG5oIGjDoGkgbMOybmcuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgcGjhuqNuIMOhbmggcuG6sW5nIGtow6FjaCBow6BuZyBjw7MgdGjhu4Mga2jDtG5nIGjDoGkgbMOybmcgYuG7n2kgY2jhuqV0IGzGsOG7o25nIGThu4tjaCB24bulLCBjw6FjaCBwaOG7pWMgduG7pSBraMOhY2ggaMOgbmcsLi4uDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIGNsYXNzDQoNClJlbGF0aXZlIHJpc2sNCg0KYGBge3J9DQpycjIgPC0gbWF0cml4KGMoMzgwOSwgMTA3NjQsDQogICAgICAgICAgICAgICA4Njg2LCAyNzE3DQogICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgIG5yb3cgPSAyLA0KICAgICAgICAgICAgIGJ5cm93ID0gVFJVRSwNCiAgICAgICAgICAgICBkaW1uYW1lcyA9IGxpc3QoYygiTmV1dHJhbCBvciBkaXNzYXRpc2ZpZWQiLCAiU2F0aXNmaWVkIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIkJ1c2luZXNzIiwgIkVjbyIpKSkNCmFkZG1hcmdpbnMocnIyKQ0KUmVsUmlzayhycjIpDQpgYGANCg0KVuG7m2kgUlIgPSAwLjM0MzEzMjEsIGPDsyB0aOG7gyB0aOG6pXkgcuG6sW5nIHRyb25nIG5ow7NtIGtow6FjaCBnaOG6vyBo4bqhbmcgdGjGsMahbmcgZ2lhLCB4w6FjIHN14bqldCBraMOhY2ggaMOgbmcga2jDtG5nIGjDoGkgbMOybmcgY2FvIGfhuqVwIDAuMzQgbOG6p25zbyB24bubaSB04bu3IGzhu4cgaMOgbmgga2jDoWNoIGjDoGkgbMOybmcuIA0KDQpPZGQgUmF0aW8NCg0KYGBge3J9DQphZGRtYXJnaW5zKHJyMikNCk9kZHNSYXRpbyhycjIpDQpgYGANCg0KVuG7m2kga+G6v3QgcXXhuqMgT1IgPSAwLjExMDY4OTcsIG9kZCBraMOhY2ggaMOgbmcgZ2jhur8gaOG6oW5nIHRoxrDGoW5nIGdpYSBj4bqjbSBj4bqjbSB0aOG6pXkgaMOgaSBsw7JuZyBn4bqlcCAwLjExIGzhuqduIGtow6FjaCBow6BuZyBnaOG6vyBo4bqhbmcgdGjGsOG7nW5nIGPhuqNtIHRo4bqleSBow6BpIGzDsm5nLg0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBJbmZsaWdodCBzZXJ2aWNlDQoNClJlbGF0aXZlIHJpc2sNCg0KYGBge3J9DQpycjMgPC0gbWF0cml4KGMoMzI0MywgMTEzMzAsDQogICAgICAgICAgICAgICAxMzg4LCAxMDAxNQ0KICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICBucm93ID0gMiwNCiAgICAgICAgICAgICBieXJvdyA9IFRSVUUsDQogICAgICAgICAgICAgZGltbmFtZXMgPSBsaXN0KGMoIk5ldXRyYWwgb3IgZGlzc2F0aXNmaWVkIiwgIlNhdGlzZmllZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJU4buHIiwgIlThu5F0IikpKQ0KYGBgDQoNCmBgYHtyfQ0KYWRkbWFyZ2lucyhycjMpDQpSZWxSaXNrKHJyMykNCmBgYA0KDQpW4bubaSBSUiA9IDEuODI4MjE3IGPDsyB0aOG7gyB0aOG6pXkgcuG6sW5nIHRyb25nIG5ow7NtIGtow6FjaCBj4bqjbSB0aOG6pXkgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IHThu4csIHjDoWMgc3XhuqV0IGtow6FjaCBow6BuZyBraMO0bmcgaMOgaSBsw7JuZyBjYW8gZ+G6pXAgMS44MiBs4bqnbiBraMOhY2ggaMOgbmcgaMOgaSBsw7JuZy4gDQoNCk9kZCBSYXRpbw0KDQpgYGB7cn0NCmFkZG1hcmdpbnMocnIzKQ0KT2Rkc1JhdGlvKHJyMykNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyBPUiA9IDIuMDY1Mjc4LCBvZGQga2jDoWNoIGjDoG5nIGjDoGkgbMOybmcgY+G6o20gdGjhuqV5IGThu4tjaCB24bulIHRyw6puIGNodXnhur9uIGJheSB04buHIGfhuqVwIDIuMDcgbOG6p24gaMahbiBzbyB24bubaSBraMOhY2ggaMOgbmcgaMOgaSBsw7JuZyBj4bqjbSB0aOG6pXkgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IHThu5F0LiANCg0KIyMjIyBCaeG6v24gc2F0aXNmYWN0aW9uIHbDoCBiaeG6v24gRGVwYXJ0dXJlIERlbGF5IGluIE1pbnR1dGVzDQoNClJlbGF0aXZlIHJpc2sNCg0KYGBge3J9DQpycjQgPC0gbWF0cml4KGMoNzgzMSwgNjc0MiwNCiAgICAgICAgICAgICAgIDY4NTcsIDQ1NDYNCiAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgbnJvdyA9IDIsDQogICAgICAgICAgICAgYnlyb3cgPSBUUlVFLA0KICAgICAgICAgICAgIGRpbW5hbWVzID0gbGlzdChjKCJOZXV0cmFsIG9yIGRpc3NhdGlzZmllZCIsICJTYXRpc2ZpZWQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygixJDDum5nIGdp4budIiwgIlRy4buFIGdp4budIikpKQ0KYGBgDQoNCmBgYHtyfQ0KYWRkbWFyZ2lucyhycjQpDQpSZWxSaXNrKHJyNCkNCmBgYA0KDQpW4bubaSBr4bq/dCBxdeG6oyBSUiA9IDAuODkzNjIwNywgY8OzIHRo4buDIHRo4bqleSBy4bqxbmcgdHJvbmcgbmjDs20ga2jDoWNoIGPDsyBjaHV54bq/biBiYXkgY+G6pXQgY8OhbmggxJHDum5nIGdp4budLCB4w6FjIHN14bqldCBraMOhY2ggaMOgbmcga2jDtG5nIGjDoGkgbMOybmcgY2FvIGfhuqVwIDAuODkgbOG6p24gc28gduG7m2kgdOG7tyBs4buHIGjDoG5oIGtow6FjaCBow6BpIGzDsm5nLiANCg0KT2RkIFJhdGlvDQoNCmBgYHtyfQ0KYWRkbWFyZ2lucyhycjQpDQpPZGRzUmF0aW8ocnI0KQ0KYGBgDQpW4bubaSBr4bq/dCBxdeG6oyBPUiA9IDAuNzcwMDU4Niwgb2RkIGtow6FjaCBow6BuZyBjw7MgY2h1eeG6v24gYmF5IGPhuqV0IGPDoW5oIMSRw7puZyBnaeG7nSBj4bqjbSB0aOG6pXkgaMOgaSBsw7JuZyBn4bqlcCAwLjc3IGzhuqduIGjGoW4gc28gduG7m2kga2jDoWNoIGjDoG5nIGPDsyBjaHV54bq/biBiYXkgY+G6pXQgY8OhbmggdHLhu4UgZ2nhu50gY+G6o20gdGjhuqV5IGjDoGkgbMOybmcuDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIEFycml2YWwgRGVsYXkgaW4gTWludHV0ZXMNCg0KUmVsYXRpdmUgcmlzaw0KDQpgYGB7cn0NCnJyNSA8LSBtYXRyaXgoYyg3NjQ2LCA2OTI3LA0KICAgICAgICAgICAgICAgNzAzMSwgNDM3Mg0KICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICBucm93ID0gMiwNCiAgICAgICAgICAgICBieXJvdyA9IFRSVUUsDQogICAgICAgICAgICAgZGltbmFtZXMgPSBsaXN0KGMoIk5ldXRyYWwgb3IgZGlzc2F0aXNmaWVkIiwgIlNhdGlzZmllZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCLEkMO6bmcgZ2nhu50iLCAiVHLhu4UgZ2nhu50iKSkpDQpgYGANCg0KYGBge3J9DQphZGRtYXJnaW5zKHJyNSkNClJlbFJpc2socnI1KQ0KYGBgDQoNClbhu5tpIGvhur90IHF14bqjIFJSID0gMC44NTA5MTczLCBjw7MgdGjhu4MgdGjhuqV5IHLhurFuZyB0cm9uZyBuaMOzbSBraMOhY2ggY8OzIGNodXnhur9uIGJheSBo4bqhIGPDoW5oIMSRw7puZyBnaeG7nSwgeMOhYyBzdeG6pXQga2jDoWNoIGjDoG5nIGtow7RuZyBow6BpIGzDsm5nIGNhbyBn4bqlcCAwLjg1IGzhuqduIHNvIHbhu5tpIGjDoG5oIGtow6FjaCBow6BpIGzDsm5nLiANCg0KT2RkIFJhdGlvDQoNCmBgYHtyfQ0KYWRkbWFyZ2lucyhycjUpDQpPZGRzUmF0aW8ocnI1KQ0KYGBgDQoNClbhu5tpIGvhur90IHF14bqjIE9SID0gMC42ODYzNjAzLCBvZGQga2jDoWNoIGjDoG5nIGPDsyBjaHV54bq/biBiYXkgaOG6oSBjw6FuaCDEkcO6bmcgZ2nhu50gY+G6o20gdGjhuqV5IGjDoGkgbMOybmcgZ+G6pXAgMC42OSBs4bqnbiBoxqFuIHNvIHbhu5tpIGtow6FjaCBow6BuZyBjw7MgY2h1eeG6v24gYmF5IGjhuqEgY8OhbmggdHLhu4MgZ2nhu50gY+G6o20gdGjhuqV5IGjDoGkgbMOybmcuDQoNCiMjIyBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgUmVsYXRpdmUgUmlzaw0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjdXN0b21lciB0eXBlDQoNCmBgYHtyfQ0KZXBpdGFiKHJyMSwgbWV0aG9kID0gJ3Jpc2tyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpL4bq/dCBxdeG6oyB0csOqbiBjaG8gdGjhuqV5IG5o4buvbmcga2jDoWNoIGjDoG5nIGtow7RuZyB0cnVuZyB0aMOgbmggY+G6o20gdGjhuqV5IGjDoGkgbMOybmcgbMOgIDI1LjE3JSBjw7JuIG5o4buvbmcga2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCBj4bqjbSB0aOG6pXkgaMOgaSBsw7JuZyBsw6AgNDguMTQlLiBU4bu3IGzhu4cgcmVsYXRpdmUgcmlzayBsw6Aga2hv4bqjbmcgMC42OSwgxJFp4buBdSBuw6B5IGPDsyB0aOG7gyBoaeG7g3UgbMOgIG5ow7NtIGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY+G6o20gdGjhuqV5IGjDoGkgbMOybmcgY2jhu4kgYuG6sW5nIDAuNjkgbOG6p24gc28gduG7m2kgbmjDs20ga2jDoWNoIGjDoG5nIGtow7RuZyB0cnVuZyB0aMOgbmguIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBj4bunYSByZWxhdGl2ZSByaXNrIGzDoCAwLjY3ODY4MjUgxJHhur9uIDAuNzA3NjgxOSB24bubaSBt4bupYyDEkeG7mSB0aW4gY+G6rXkgOTUlIHbDoCBwLXZhbHVlIGzDoCA1LjQyNThlLTE5MyBjaG8gdGjhuqV5IHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHPhu7EgaMOgaSBsw7JuZyBnaeG7r2EgMiBuaMOzbSBraMOhY2ggaMOgbmcgbMOgIGPDsyBz4buxIGNow6puaCBs4buHY2ggxJHDoW5nIGvhu4MuDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIGNsYXNzDQoNCmBgYHtyfQ0KZXBpdGFiKHJyMiwgbWV0aG9kID0gJ3Jpc2tyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpL4bq/dCBxdeG6oyB0csOqbiBjaG8gdGjhuqV5IG5o4buvbmcga2jDoWNoIGjDoG5nIGjhuqFuZyBnaOG6vyBwaOG7lSB0aMO0bmcgY+G6o20gdGjhuqV5IGjDoGkgbMOybmcgbMOgIDIzLjgyJSBjw7JuIG5o4buvbmcga2jDoWNoIGjDoG5nIGjhuqFuZyBnaOG6vyBwaOG7lSB0aMO0bmcgY+G6o20gdGjhuqV5IGtow7RuZyBow6BpIGzDsm5nIGzDoCA3My44NiUuIFThu7cgbOG7hyByZWxhdGl2ZSByaXNrIGzDoCBraG/huqNuZyAyLjkxLCDEkWnhu4F1IG7DoHkgY8OzIHRo4buDIGhp4buDdSBsw6AgbmjDs20ga2jDoWNoIGjDoG5nIGjhuqFuZyBnaOG6vyBwaOG7lSB0aMO0bmcgY+G6o20gdGjhuqV5IGjDoGkgbMOybmcgYuG6sW5nIDIuOTEgbOG6p24gc28gduG7m2kgbmjDs20ga2jDoWNoIGjDoG5nIGjhuqFuZyBnaOG6vyBwaOG7lSB0aMO0bmcgY+G6o20gdGjhuqV5IGtow7RuZyBow6BpIGzDsm5nLiBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgY+G7p2EgcmVsYXRpdmUgcmlzayBsw6AgMi44MzA1NzUgxJHhur9uIDMuMDAwNTYyIHbhu5tpIG3hu6ljIMSR4buZIHRpbiBj4bqteSA5NSUgdsOgIHAtdmFsdWUgbMOgIDAgY2hvIHRo4bqleSBz4buxIGNow6puaCBs4buHY2ggduG7gSBz4buxIGjDoGkgbMOybmcgZ2nhu69hIDIgbmjDs20ga2jDoWNoIGjDoG5nIGzDoCBjw7Mgc+G7sSBjaMOqbmggbOG7h2NoIMSRw6FuZyBr4buDLg0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBJbmZsaWdodCBzZXJ2aWNlDQoNCmBgYHtyfQ0KZXBpdGFiKHJyMywgbWV0aG9kID0gJ3Jpc2tyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpL4bq/dCBxdeG6oyB0csOqbiBjaG8gdGjhuqV5IG5o4buvbmcga2jDoWNoIGjDoG5nIGPhuqNtIHRo4bqleSBk4buLY2ggduG7pSB0csOqbiBjaHV54bq/biBiYXkgdOG7kXQgdsOgIGPhuqNtIHRo4bqleSBow6BpIGzDsm5nIGzDoCA4Ny44MiUgY8OybiBuaOG7r25nIGtow6FjaCBow6BuZyBj4bqjbSB0aOG6pXkgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IHThu5F0IHbDoCBj4bqjbSB0aOG6pXkga2jDtG5nIGjDoGkgbMOybmcgbMOgIDc3Ljc1JS4gVOG7tyBs4buHIHJlbGF0aXZlIHJpc2sgbMOgIGtob+G6o25nIDAuNTQsIMSRaeG7gXUgbsOgeSBjw7MgdGjhu4MgaGnhu4N1IGzDoCBuaMOzbSBraMOhY2ggaMOgbmcgY+G6o20gdGjhuqV5IGThu4tjaCB24bulIHRyw6puIGNodXnhur9uIGJheSB04buRdCB2w6AgY+G6o20gdGjhuqV5IGjDoGkgbMOybmcgYuG6sW5nIDAuNTQgbOG6p24gc28gduG7m2kgbmjhu69uZyBraMOhY2ggaMOgbmcgY+G6o20gdGjhuqV5IGThu4tjaCB24bulIHRyw6puIGNodXnhur9uIGJheSB04buRdCB2w6AgY+G6o20gdGjhuqV5IGtow7RuZyBow6BpIGzDsm5nLiBLaG/huqNuZyDGsOG7m2MgbMaw4bujbmcgY+G7p2EgcmVsYXRpdmUgcmlzayBsw6AgMC41MTYyMTM2IMSR4bq/biAwLjU3OTU4MjUgduG7m2kgbeG7qWMgxJHhu5kgdGluIGPhuq15IDk1JSB2w6AgcC12YWx1ZSBsw6AgMi4zODkyODZlLTEwMSBjaG8gdGjhuqV5IHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHPhu7EgaMOgaSBsw7JuZyBnaeG7r2EgMiBuaMOzbSBraMOhY2ggaMOgbmcgbMOgIGPDsyBz4buxIGNow6puaCBs4buHY2ggxJHDoW5nIGvhu4MuDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIERlcGFydHVyZSBEZWxheSBpbiBNaW50dXRlcw0KDQpgYGB7cn0NCmVwaXRhYihycjQsIG1ldGhvZCA9ICdyaXNrcmF0aW8nLCByZXYgPSAnYycpDQpgYGANCg0KS+G6v3QgcXXhuqMgdHLDqm4gY2hvIHRo4bqleSBuaOG7r25nIGtow6FjaCBow6BuZyBjw7MgY2h1eeG6v24gYmF5IHRy4buFIGdp4budIGPhuqNtIHRo4bqleSBow6BpIGzDsm5nIGzDoCAzOS44NiUgY8OybiBuaOG7r25nIGtow6FjaCBow6BuZyBjw7MgY2h1eeG6v24gYmF5IHRy4buFIGdp4budIGPhuqNtIHRo4bqleSBraMO0bmcgaMOgaSBsw7JuZyBsw6AgNDYuMjYlLiBU4bu3IGzhu4cgcmVsYXRpdmUgcmlzayBsw6Aga2hv4bqjbmcgMS4xMSwgxJFp4buBdSBuw6B5IGPDsyB0aOG7gyBoaeG7g3UgbMOgIG5ow7NtIGtow6FjaCBow6BuZyBjY8OzIGNodXnhur9uIGJheSB0cuG7hSBnaeG7nSBj4bqjbSB0aOG6pXkgaMOgaSBsw7JuZyBi4bqxbmcgMS4xMSBs4bqnbiBzbyB24bubaSBuaOG7r25nIGtow6FjaCBow6BuZyBjw7MgY2h1eeG6v24gYmF5IHRy4buFIGdp4budIGPhuqNtIHRo4bqleSBraMO0bmcgaMOgaSBsw7JuZy4gS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIGPhu6dhIHJlbGF0aXZlIHJpc2sgbMOgIDEuMDk1NTQ3IMSR4bq/biAxLjE0MzA0MyB24bubaSBt4bupYyDEkeG7mSB0aW4gY+G6rXkgOTUlIHbDoCBwLXZhbHVlIGzDoCA1LjA2NTU1MWUtMjUgY2hvIHRo4bqleSBz4buxIGNow6puaCBs4buHY2ggxJHDoW5nIGvhu4MgduG7gSBz4buxIGjDoGkgbMOybmcgZ2nhu69hIDIgbmjDs20ga2jDoWNoIGjDoG5nLg0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBBcnJpdmFsIERlbGF5IGluIE1pbnR1dGVzDQoNCmBgYHtyfQ0KZXBpdGFiKHJyNSwgbWV0aG9kID0gJ3Jpc2tyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpL4bq/dCBxdeG6oyB0csOqbiBjaG8gdGjhuqV5IG5o4buvbmcga2jDoWNoIGjDoG5nIGPDsyBjaHV54bq/biBiYXkgaOG6oSBjw6FuaCB0cuG7hSBnaeG7nSBj4bqjbSB0aOG6pXkgaMOgaSBsw7JuZyBsw6AgMzguMzQlIGPDsm4gbmjhu69uZyBraMOhY2ggaMOgbmcgY8OzIGNodXnhur9uIGJheSBo4bqhIGPDoW5oIHRy4buFIGdp4budIGPhuqNtIHRo4bqleSBraMO0bmcgaMOgaSBsw7JuZyBsw6AgNDcuNTMlLiBU4bu3IGzhu4cgcmVsYXRpdmUgcmlzayBsw6Aga2hv4bqjbmcgMS4xNywgxJFp4buBdSBuw6B5IGPDsyB0aOG7gyBoaeG7g3UgbMOgIG5ow7NtIGtow6FjaCBow6BuZyBjY8OzIGNodXnhur9uIGJheSBo4bqhIGPDoW5oIHRy4buFIGdp4budIGPhuqNtIHRo4bqleSBow6BpIGzDsm5nIGLhurFuZyAxLjE3IGzhuqduIHNvIHbhu5tpIG5o4buvbmcga2jDoWNoIGjDoG5nIGPDsyBjaHV54bq/biBiYXkgaOG6oSBjw6FuaCB0cuG7hSBnaeG7nSBj4bqjbSB0aOG6pXkga2jDtG5nIGjDoGkgbMOybmcuIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBj4bunYSByZWxhdGl2ZSByaXNrIGzDoCAxLjE1MDU4MSDEkeG6v24gMS4yMDAzNSB24bubaSBt4bupYyDEkeG7mSB0aW4gY+G6rXkgOTUlIHbDoCBwLXZhbHVlIGzDoCA2LjY2NDkxMWUtNTAgY2hvIHRo4bqleSBz4buxIGNow6puaCBs4buHY2ggxJHDoW5nIGvhu4MgduG7gSBz4buxIGjDoGkgbMOybmcgZ2nhu69hIDIgbmjDs20ga2jDoWNoIGjDoG5nLg0KDQojIyMgS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIE9kZCByYXRpbw0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBjdXN0b21lciB0eXBlDQoNCmBgYHtyfQ0KZXBpdGFiKHJyMSwgbWV0aG9kID0gJ29kZHNyYXRpbycscmV2ID0gJ2MnKQ0KYGBgDQoNCk9kZHMgcmF0aW86IDAuMzYyMzY0NiBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgdGjhuqVwIGjGoW4gNjQlIHNvIHbhu5tpIGtow6FjaCBow6BuZyBraMO0bmcgdHJ1bmcgdGjDoG5oLiDEkGnhu4F1IG7DoHkgxJHGsOG7o2MgeMOhYyBuaOG6rW4gYuG7n2kgcC12YWx1ZSBj4buxYyBuaOG7jyAoNS40MjU4ZS0xOTMpIGNobyB0aOG6pXkga+G6v3QgcXXhuqMgbsOgeSBy4bqldCDEkcOhbmcgdGluIGPhuq15Lg0KDQpQaMOibiB0w61jaCBjaGkgdGnhur90Og0KDQotCUtow6FjaCBow6BuZyBraMO0bmcgdHJ1bmcgdGjDoG5oIGPDsyAxMCw2JSBow6BpIGzDsm5nIHbDoCAyNCw2JSBraMO0bmcgaMOgaSBsw7JuZyBob+G6t2MgdHJ1bmcgdMOtbmguDQoNCi0JS2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCBjw7MgODksNCUgaMOgaSBsw7JuZyB2w6AgNzUsNCUga2jDtG5nIGjDoGkgbMOybmcgaG/hurdjIHRydW5nIHTDrW5oLg0KDQpL4bq/dCBsdeG6rW46IEtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgdGjhuqVwIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kga2jDoWNoIGjDoG5nIGtow7RuZyB0cnVuZyB0aMOgbmguIMSQaeG7gXUgbsOgeSBjaG8gdGjhuqV5IGPDsyB24bqlbiDEkeG7gSB24buBIHPhu7EgaMOgaSBsw7JuZyBj4bunYSBraMOhY2ggaMOgbmcgdHJ1bmcgdGjDoG5oIGPhuqduIMSRxrDhu6NjIGdp4bqjaSBxdXnhur90Lg0KDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIGNsYXNzDQoNCmBgYHtyfQ0KZXBpdGFiKHJyMiwgbWV0aG9kID0gJ29kZHNyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpPZGRzIHJhdGlvOiA5LjAzNDI2NyBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyB0aHXhu5ljIG5ow7NtICJCdXNpbmVzcyIgY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgY2FvIGjGoW4gOSBs4bqnbiBzbyB24bubaSBraMOhY2ggaMOgbmcgdGh14buZYyBuaMOzbSAiRWNvIi4gxJBp4buBdSBuw6B5IMSRxrDhu6NjIHjDoWMgbmjhuq1uIGLhu59pIHAtdmFsdWUgY+G7sWMgbmjhu48gKDApIGNobyB0aOG6pXkga+G6v3QgcXXhuqMgbsOgeSBy4bqldCDEkcOhbmcgdGluIGPhuq15Lg0KDQpQaMOibiB0w61jaCBjaGkgdGnhur90Og0KDQotCUtow6FjaCBow6BuZyB0aHXhu5ljIG5ow7NtICJFY28iIGPDsyA3OSw4JSBraMO0bmcgaMOgaSBsw7JuZyBob+G6t2MgdHJ1bmcgdMOtbmggdsOgIDIwLDIlIGjDoGkgbMOybmcuDQoNCi0JS2jDoWNoIGjDoG5nIHRodeG7mWMgbmjDs20gIkJ1c2luZXNzIiBjw7MgMzAsNSUga2jDtG5nIGjDoGkgbMOybmcgaG/hurdjIHRydW5nIHTDrW5oIHbDoCA2OSw1JSBow6BpIGzDsm5nLg0KDQpL4bq/dCBsdeG6rW46IEtow6FjaCBow6BuZyB0aHXhu5ljIG5ow7NtICJCdXNpbmVzcyIgY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgY2FvIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kga2jDoWNoIGjDoG5nIHRodeG7mWMgbmjDs20gIkVjbyIuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgY2hvIHRo4bqleSBuaMOzbSAiRWNvIiBjw7MgdGjhu4MgY+G6p24gxJHGsOG7o2MgY2jDuiDDvSBuaGnhu4F1IGjGoW4gduG7gSBt4bq3dCBj4bqjaSB0aGnhu4duIHPhu7EgaMOgaSBsw7JuZyBraMOhY2ggaMOgbmcNCg0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBJbmZsaWdodCBzZXJ2aWNlDQoNCmBgYHtyfQ0KZXBpdGFiKHJyMywgbWV0aG9kID0gJ29kZHNyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpPZGRzIHJhdGlvOiAwLjQ4NDE5NjMgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgxJHDoW5oIGdpw6EgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IGzDoCAiVOG7hyIgY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgdGjhuqVwIGjGoW4gNTIlIHNvIHbhu5tpIGtow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSBsw6AgIlThu5F0Ii4gxJBp4buBdSBuw6B5IMSRxrDhu6NjIHjDoWMgbmjhuq1uIGLhu59pIHAtdmFsdWUgY+G7sWMgbmjhu48gKDIuMzg5Mjg2ZS0xMDEpIGNobyB0aOG6pXkga+G6v3QgcXXhuqMgbsOgeSBy4bqldCDEkcOhbmcgdGluIGPhuq15Lg0KDQpQaMOibiB0w61jaCBjaGkgdGnhur90Og0KDQotCUtow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSBsw6AgIlThu5F0IiBjw7MgNTMsMSUga2jDtG5nIGjDoGkgbMOybmcgaG/hurdjIHRydW5nIHTDrW5oIHbDoCA0Niw5JSBow6BpIGzDsm5nLg0KDQotCUtow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSBsw6AgIlThu4ciIGPDsyA3MCwwJSBraMO0bmcgaMOgaSBsw7JuZyBob+G6t2MgdHJ1bmcgdMOtbmggdsOgIDMwLDAlIGjDoGkgbMOybmcuDQoNCkvhur90IGx14bqtbjogS2jDoWNoIGjDoG5nIMSRw6FuaCBnacOhIGThu4tjaCB24bulIHRyw6puIGNodXnhur9uIGJheSBsw6AgIlThu4ciIGPDsyBraOG6oyBuxINuZyBow6BpIGzDsm5nIHRo4bqlcCBoxqFuIMSRw6FuZyBr4buDIHNvIHbhu5tpIGtow6FjaCBow6BuZyDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSBsw6AgIlThu5F0Ii4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IGPDsyDhuqNuaCBoxrDhu59uZyByw7UgcuG7h3QgxJHhur9uIG3hu6ljIMSR4buZIGjDoGkgbMOybmcgY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQoNCiMjIyMgQmnhur9uIHNhdGlzZmFjdGlvbiB2w6AgYmnhur9uIERlcGFydHVyZSBEZWxheSBpbiBNaW50dXRlcw0KDQpgYGB7cn0NCmVwaXRhYihycjQsIG1ldGhvZCA9ICdvZGRzcmF0aW8nLCByZXYgPSAnYycpDQpgYGANCg0KT2RkcyByYXRpbzogMS4yOTg2MDMgY2hvIHRo4bqleSBraMOhY2ggaMOgbmcgxJFpIGNodXnhur9uIGJheSDEkcO6bmcgZ2nhu50gY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgY2FvIGjGoW4gMzAlIHNvIHbhu5tpIGtow6FjaCBow6BuZyDEkWkgY2h1eeG6v24gYmF5IGLhu4sgdHLhu4UgZ2nhu50uIMSQaeG7gXUgbsOgeSDEkcaw4bujYyB4w6FjIG5o4bqtbiBi4bufaSBwLXZhbHVlIGPhu7FjIG5o4buPICg1LjA2NTU1MWUtMjUpIGNobyB0aOG6pXkga+G6v3QgcXXhuqMgbsOgeSBy4bqldCDEkcOhbmcgdGluIGPhuq15Lg0KDQpQaMOibiB0w61jaCBjaGkgdGnhur90Og0KDQotCUtow6FjaCBow6BuZyDEkWkgY2h1eeG6v24gYmF5IGLhu4sgdHLhu4UgZ2nhu50gY8OzIDU5LDclIGtow7RuZyBow6BpIGzDsm5nIGhv4bq3YyB0cnVuZyB0w61uaCB2w6AgNDAsMyUgaMOgaSBsw7JuZy4NCg0KLQlLaMOhY2ggaMOgbmcgxJFpIGNodXnhur9uIGJheSDEkcO6bmcgZ2nhu50gY8OzIDUzLDMlIGtow7RuZyBow6BpIGzDsm5nIGhv4bq3YyB0cnVuZyB0w61uaCB2w6AgNDYsNyUgaMOgaSBsw7JuZy4NCg0KS+G6v3QgbHXhuq1uOiBLaMOhY2ggaMOgbmcgxJFpIGNodXnhur9uIGJheSDEkcO6bmcgZ2nhu50gY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgY2FvIGjGoW4gxJHDoW5nIGvhu4Mgc28gduG7m2kga2jDoWNoIGjDoG5nIMSRaSBjaHV54bq/biBiYXkgYuG7iyB0cuG7hSBnaeG7nS4gxJBp4buBdSBuw6B5IGNobyB0aOG6pXkgxJHhu5kgdHLhu4UgZ2nhu50gYmF5IGzDoCBt4buZdCB54bq/dSB04buRIHF1YW4gdHLhu41uZyDhuqNuaCBoxrDhu59uZyDEkeG6v24gc+G7sSBow6BpIGzDsm5nIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KDQojIyMjIEJp4bq/biBzYXRpc2ZhY3Rpb24gdsOgIGJp4bq/biBBcnJpdmFsIERlbGF5IGluIE1pbnR1dGVzDQoNCmBgYHtyfQ0KZXBpdGFiKHJyNSwgbWV0aG9kID0gJ29kZHNyYXRpbycsIHJldiA9ICdjJykNCmBgYA0KDQpPZGRzIHJhdGlvOiAxLjQ1Njk2MSBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyDEkWkgY2h1eeG6v24gYmF5IMSRw7puZyBnaeG7nSBjw7Mga2jhuqMgbsSDbmcgaMOgaSBsw7JuZyBjYW8gaMahbiA0NiUgc28gduG7m2kga2jDoWNoIGjDoG5nIMSRaSBjaHV54bq/biBiYXkgYuG7iyB0cuG7hSBnaeG7nSDEkeG6v24uIMSQaeG7gXUgbsOgeSDEkcaw4bujYyB4w6FjIG5o4bqtbiBi4bufaSBwLXZhbHVlIGPhu7FjIG5o4buPICg2LjY2NDkxMWUtNTApIGNobyB0aOG6pXkga+G6v3QgcXXhuqMgbsOgeSBy4bqldCDEkcOhbmcgdGluIGPhuq15Lg0KDQpQaMOibiB0w61jaCBjaGkgdGnhur90Og0KDQotCUtow6FjaCBow6BuZyDEkWkgY2h1eeG6v24gYmF5IGLhu4sgdHLhu4UgZ2nhu50gxJHhur9uIGPDsyA2MSwzJSBraMO0bmcgaMOgaSBsw7JuZyBob+G6t2MgdHJ1bmcgdMOtbmggdsOgIDM4LDclIGjDoGkgbMOybmcuDQoNCi0JS2jDoWNoIGjDoG5nIMSRaSBjaHV54bq/biBiYXkgxJHDum5nIGdp4budIGPDsyA1MiwxJSBraMO0bmcgaMOgaSBsw7JuZyBob+G6t2MgdHJ1bmcgdMOtbmggdsOgIDQ3LDklIGjDoGkgbMOybmcuDQoNCkvhur90IGx14bqtbjogS2jDoWNoIGjDoG5nIMSRaSBjaHV54bq/biBiYXkgxJHDum5nIGdp4budIGPDsyBraOG6oyBuxINuZyBow6BpIGzDsm5nIGNhbyBoxqFuIMSRw6FuZyBr4buDIHNvIHbhu5tpIGtow6FjaCBow6BuZyDEkWkgY2h1eeG6v24gYmF5IGLhu4sgdHLhu4UgZ2nhu50gxJHhur9uLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSDEkeG7mSB0cuG7hSBnaeG7nSDEkeG6v24gbMOgIG3hu5l0IHnhur91IHThu5EgcXVhbiB0cuG7jW5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBz4buxIGjDoGkgbMOybmcgY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQojIyMgS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hw0KDQojIyMjIMav4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIHbDoCBraMO0bmcgY8OzIGjDoGkgbMOybmcgduG7gSBow6NuZyBow6BuZyBraMO0bmcNCg0KYGBge3J9DQpwIDwtIGRhdGFbZGF0YSRzYXRpc2ZhY3Rpb24gPT0gJ3NhdGlzZmllZCcsXQ0KcHJvcC50ZXN0KGxlbmd0aChwJHNhdGlzZmFjdGlvbiksIGxlbmd0aChkYXRhJHNhdGlzZmFjdGlvbikpDQpgYGANCg0KYGBge3J9DQpwIDwtIGRhdGFbZGF0YSRzYXRpc2ZhY3Rpb24gPT0gJ25ldXRyYWwgb3IgZGlzc2F0aXNmaWVkJyxdDQpwcm9wLnRlc3QobGVuZ3RoKHAkc2F0aXNmYWN0aW9uKSwgbGVuZ3RoKGRhdGEkc2F0aXNmYWN0aW9uKSkNCmBgYA0KDQpW4bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlLCB0YSBjw7MgdOG7tyBs4buHIGtow6FjaCBow6BuZyBow6BpIGzDsm5nIHbhu4EgaMOjbmcgaMOgbmcga2jDtG5nIHNvIHbhu5tpIHThu5VuZyB0aOG7gyBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDQzLjMlIMSR4bq/biA0NC41JS4gSGF5IG7Ds2kgY8OhY2gga2jDoWMsIHThu7cgbOG7hyBuZ8aw4budaSBraMO0bmcgaMOgaSBsw7JuZyB24buBIGjDo25nIGjDoG5nIGtow7RuZyBz4bq9IGNoaeG6v20ga2hv4bqjbmcgdOG7qyA1NS41JSDEkeG6v24gNTYuNyUuDQoNCiMjIyMgxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbmfhu5NpIOG7nyBjw6FjIGjhuqFuZyBnaOG6vw0KDQpgYGB7cn0NCnAgPC0gZGF0YVtkYXRhJENsYXNzPT0gJ0J1c2luZXNzJyxdDQpwcm9wLnRlc3QobGVuZ3RoKHAkQ2xhc3MpLCBsZW5ndGgoZGF0YSRDbGFzcykpDQpgYGANCg0KVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSwgdGEgY8OzIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbmfhu5NpIOG7nyBo4bqhbmcgZ2jhur8gdGjGsMahbmcgZ2lhIHNvIHbhu5tpIHThu5VuZyB0aOG7gyBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDQ3LjUlIMSR4bq/biA0OC43JS4NCg0KYGBge3J9DQpwIDwtIGRhdGFbZGF0YSRDbGFzcz09ICdFY28gUGx1cycsXQ0KcHJvcC50ZXN0KGxlbmd0aChwJENsYXNzKSwgbGVuZ3RoKGRhdGEkQ2xhc3MpKQ0KYGBgDQoNClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUsIHRhIGPDsyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG5n4buTaSDhu58gaOG6oW5nIGdo4bq/IGNhbyBj4bqlcCBzbyB24bubaSB04buVbmcgdGjhu4MgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyA3LjA3JSDEkeG6v24gNy43MSUuDQoNCmBgYHtyfQ0KcCA8LSBkYXRhW2RhdGEkQ2xhc3M9PSAnRWNvJyxdDQpwcm9wLnRlc3QobGVuZ3RoKHAkQ2xhc3MpLCBsZW5ndGgoZGF0YSRDbGFzcykpDQpgYGANCg0KVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSwgdGEgY8OzIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbmfhu5NpIOG7nyBo4bqhbmcgZ2jhur8gdGjGsOG7nW5nIHNvIHbhu5tpIHThu5VuZyB0aOG7gyBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDQzLjkxJSDEkeG6v24gNDUuMTMlLg0KDQojIyMjIMav4bubYyBsxrDhu6NuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCBoYXkga2jDtG5nIHRydW5nIHRow6BuaA0KDQpgYGB7cn0NCnAgPC0gZGF0YVtkYXRhJGBDdXN0b21lciBUeXBlYD09ICdMb3lhbCBDdXN0b21lcicsXQ0KcHJvcC50ZXN0KGxlbmd0aChwJGBDdXN0b21lciBUeXBlYCksIGxlbmd0aChkYXRhJGBDdXN0b21lciBUeXBlYCkpDQpgYGANCg0KYGBge3J9DQpwIDwtIGRhdGFbZGF0YSRgQ3VzdG9tZXIgVHlwZWA9PSAnZGlzbG95YWwgQ3VzdG9tZXInLF0NCnByb3AudGVzdChsZW5ndGgocCRgQ3VzdG9tZXIgVHlwZWApLCBsZW5ndGgoZGF0YSRgQ3VzdG9tZXIgVHlwZWApKQ0KYGBgDQoNClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUsIHRhIGPDsyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIHRydW5nIHRow6BuaCBzbyB24bubaSB04buVbmcgdGjhu4MgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyA4MS4wNSUgxJHhur9uIDgyJS4gSGF5IG7Ds2kgY8OhY2gga2jDoWMsIHThu7cgbOG7hyBuZ8aw4budaSBraMO0bmcgaMOgaSBsw7JuZyB24buBIGjDo25nIGjDoG5nIGtow7RuZyBz4bq9IGNoaeG6v20ga2hv4bqjbmcgdOG7qyAxOCUgxJHhur9uIDE4Ljk1JS4NCg0KIyMjIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIEtIIGjDoGkgbMOybmcgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5DQoNCmBgYHtyfQ0KcCA8LSBkYXRhW2RhdGEkYEluZmxpZ2h0IHNlcnZpY2VgPT0gJ0jDoGkgbMOybmcnLF0NCnByb3AudGVzdChsZW5ndGgocCRgSW5mbGlnaHQgc2VydmljZWApLCBsZW5ndGgoZGF0YSRgSW5mbGlnaHQgc2VydmljZWApKQ0KYGBgDQpW4bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlLCB0YSBjw7MgdOG7tyBs4buHIGtow6FjaCBow6BuZyBow6BpIGzDsm5nIHbhu4EgZOG7i2NoIHbhu6UgdHLDqm4gY2h1eeG6v24gYmF5IHNvIHbhu5tpIHThu5VuZyB0aOG7gyBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDM1LjUyJSDEkeG6v24gMzYuNjklLg0KDQojIyMjIMav4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgY2h1eeG6v24gYmF5IGPhuqV0IGPDoW5oIMSRw7puZyBnaeG7nQ0KDQpgYGB7cn0NCnAgPC0gZGF0YVtkYXRhJGRkPT0gJ8SRw7puZyBnaeG7nScsXQ0KcHJvcC50ZXN0KGxlbmd0aChwJGRkKSwgbGVuZ3RoKGRhdGEkZGQpKQ0KYGBgDQoNClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUsIHRhIGPDsyB04bu3IGzhu4cgY2h1eeG6v24gYmF5IGPhuqV0IGPDoW5oIMSRw7puZyBnaeG7nSBzbyB24bubaSB04buVbmcgdGjhu4MgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyA1NS45MyUgxJHhur9uIDU3LjE0JS4NCg0KIyMjIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGNodXnhur9uIGJheSBo4bqhIGPDoW5oIMSRw7puZyBnaeG7nQ0KDQpgYGB7cn0NCnAgPC0gZGF0YVtkYXRhJGFkPT0gJ8SRw7puZyBnaeG7nScsXQ0KcHJvcC50ZXN0KGxlbmd0aChwJGFkKSwgbGVuZ3RoKGRhdGEkYWQpKQ0KYGBgDQoNClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUsIHRhIGPDsyB04bu3IGzhu4cgY2h1eeG6v24gYmF5IGjhuqEgY8OhbmggxJHDum5nIGdp4budIHNvIHbhu5tpIHThu5VuZyB0aOG7gyBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDU1LjklIMSR4bq/biA1Ny4xMSUuDQoNCiMjIFBow6JuIHTDrWNoIMSRYSBiaeG6v24gY8OhYyB54bq/dSB04buRIHTDoWMgxJHhu5luZyDEkeG6v24gc+G7sSBow6BpIGzDsm5nIGPhu6dhIGtow6FjaCBow6BuZw0KDQojIyMgTcO0IGjDrG5oIHjDoWMgc3XhuqV0IHR1eeG6v24gdMOtbmgNCg0KYGBge3J9DQojIENo4bqheSBtw7QgaMOsbmggeMOhYyBzdeG6pXQgdHV54bq/biB0w61uaA0KZGF0YSRzYXRpc2ZhY3Rpb24gPC0gaWZlbHNlKGRhdGEkc2F0aXNmYWN0aW9uID09ICJzYXRpc2ZpZWQiLCAxLCAwKQ0KIyBDaOG6oXkgbcO0IGjDrG5oIHjDoWMgc3XhuqV0IHR1eeG6v24gdMOtbmgNCm1vZGVsMSA8LSBnbG0oc2F0aXNmYWN0aW9uIH4gYEN1c3RvbWVyIFR5cGVgICsgQ2xhc3MgKyBgSW5mbGlnaHQgc2VydmljZWArIGBEZXBhcnR1cmUgRGVsYXkgaW4gTWludXRlc2ArYEFycml2YWwgRGVsYXkgaW4gTWludXRlc2AsIGRhdGEgPSBkYXRhICkNCg0KIyBIaeG7g24gdGjhu4sga+G6v3QgcXXhuqMgbcO0IGjDrG5oDQpzdW1tYXJ5KG1vZGVsMSkNCmBgYA0KDQpQaMawxqFuZyBUcsOsbmggSOG7k2kgUXV5Og0KDQrPgCDMgj0gLTAuMTgwOCswLjE4MDEuQ3VzdG9tZXIgVHlwZSAtMC40NTE1LkNsYXNzIC0wLjQwOTQuQ2xhc3MgICswLjYzODEuSW5mbGlnaHQgU2VydmljZSArMC41OTU1w5dJbmZsaWdodCBTZXJ2aWNlICswLjU3NzPDl0luZmxpZ2h0IFNlcnZpY2UgICAgKzAuNzM5NsOXSW5mbGlnaHQgU2VydmljZSArMC44Mzkxw5dJbmZsaWdodCBTZXJ2aWNlICsgMC4wMDA1w5dEZXBhcnR1cmUgRGVsYXkgaW4gTWludXRlcy0wLjAwMTDDl0Fycml2YWwgRGVsYXkgaW4gTWludXRlcw0KDQpQaMawxqFuZyB0csOsbmggbsOgeSBjaG8gcGjDqXAgYuG6oW4gZOG7sSDEkW/DoW4gc+G7sSBow6BpIGzDsm5nIGPhu6dhIGtow6FjaCBow6BuZyBk4buxYSB0csOqbiBjw6FjIHnhur91IHThu5EgbmjGsCBsb+G6oWkga2jDoWNoIGjDoG5nLCBo4bqhbmcgZ2jhur8sIGNo4bqldCBsxrDhu6NuZyBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSwgdsOgIHRo4budaSBnaWFuIGNo4bqtbSB0cuG7hSBj4bunYSBjaHV54bq/biBiYXkuDQoNCkdp4bqjaSBUaMOtY2g6DQoNCkjhu4cgc+G7kSBjaOG6t246IC0wLjE4MDggxJDDonkgbMOgIGdpw6EgdHLhu4sgZOG7sSDEkW/DoW4gY+G7p2Egc+G7sSBow6BpIGzDsm5nIGtoaSB04bqldCBj4bqjIGPDoWMgYmnhur9uIMSR4buZYyBs4bqtcCDEkeG7gXUgYuG6sW5nIDAuIA0KCQ0KSOG7hyBz4buRIGPhu6dhIEN1c3RvbWVyIFR5cGU6IDAuMTgwMSBjaG8gdGjhuqV5IGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY8OzIG3hu6ljIMSR4buZIGjDoGkgbMOybmcgY2FvIGjGoW4gc28gduG7m2kga2jDoWNoIGjDoG5nIGtow7RuZyB0cnVuZyB0aMOgbmguIEPhu6UgdGjhu4MsIG7hur91IGtow6FjaCBow6BuZyBsw6AgdHJ1bmcgdGjDoG5oLCBt4bupYyDEkeG7mSBow6BpIGzDsm5nIGThu7EgxJFvw6FuIHTEg25nIHRow6ptIDAuMTgwMSDEkcahbiB24buLIHNvIHbhu5tpIGtow6FjaCBow6BuZyBraMO0bmcgdHJ1bmcgdGjDoG5oLg0KCQ0KSOG7hyBz4buRIGPhu6dhIENsYXNzIChFY28pOiAtMC40NTE1IGNobyB0aOG6pXkgaMOgbmgga2jDoWNoIGNo4buNbiBo4bqhbmcgZ2jhur8gRWNvbm9teSAoRWNvKSBjw7MgbeG7qWMgxJHhu5kgaMOgaSBsw7JuZyB0aOG6pXAgaMahbiBzbyB24bubaSBo4bqhbmcgZ2jhur8ga2jDoWMgKHbDrSBk4bulOiBCdXNpbmVzcyBob+G6t2MgRmlyc3QgQ2xhc3MpLiBD4bulIHRo4buDLCBu4bq/dSBraMOhY2ggaMOgbmcgY2jhu41uIGjhuqFuZyBnaOG6vyBFY29ub215LCBt4bupYyDEkeG7mSBow6BpIGzDsm5nIGThu7EgxJFvw6FuIGdp4bqjbSAwLjQ1MTUgxJHGoW4gduG7iyBzbyB24bubaSBo4bqhbmcgZ2jhur8ga2jDoWMuDQoJDQpI4buHIHPhu5EgY+G7p2EgQ2xhc3MgKEVjbyBQbHVzKTogLTAuNDA5NCBjaG8gdGjhuqV5ICBow6BuaCBraMOhY2ggY2jhu41uIGjhuqFuZyBnaOG6vyBFY29ub215IFBsdXMgKEVjbyBQbHVzKSBjw7MgbeG7qWMgxJHhu5kgaMOgaSBsw7JuZyB0aOG6pXAgaMahbiBzbyB24bubaSBo4bqhbmcgZ2jhur8ga2jDoWMuIEPhu6UgdGjhu4MsIG7hur91IGtow6FjaCBow6BuZyBjaOG7jW4gaOG6oW5nIGdo4bq/IEVjb25vbXkgUGx1cywgbeG7qWMgxJHhu5kgaMOgaSBsw7JuZyBk4buxIMSRb8OhbiBnaeG6o20gMC40MDk0IMSRxqFuIHbhu4sgc28gduG7m2kgaOG6oW5nIGdo4bq/IGtow6FjLg0KDQpI4buHIHPhu5EgY+G7p2EgSW5mbGlnaHQgU2VydmljZSAoVmVyeSBQb29yKTogMC42MzgxIGNobyB0aOG6pXkgbeG7qWMgxJHhu5kgaMOgaSBsw7JuZyB0xINuZyB0aMOqbSAwLjYzODEgxJHGoW4gduG7iyBu4bq/dSBow6BuaCBraMOhY2ggxJHDoW5oIGdpw6EgZOG7i2NoIHbhu6UgdHLDqm4gbcOheSBiYXkgbMOgICJWZXJ5IFBvb3IiIHNvIHbhu5tpIGThu4tjaCB24bulIGPGoSBi4bqjbi4NCg0KSOG7hyBz4buRIGPhu6dhIEluZmxpZ2h0IFNlcnZpY2UgKFBvb3IpOiAwLjU5NTUgY2hvIHRo4bqleSBt4bupYyDEkeG7mSBow6BpIGzDsm5nIHTEg25nIHRow6ptIDAuNTk1NSDEkcahbiB24buLIG7hur91IGjDoG5oIGtow6FjaCDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSBsw6AgIlBvb3IiIHNvIHbhu5tpIGThu4tjaCB24bulIGPGoSBi4bqjbi4NCg0KSOG7hyBz4buRIGPhu6dhIEluZmxpZ2h0IFNlcnZpY2UgKEF2ZXJhZ2UpOiAwLjU3NzMgY2hvIHRo4bqleSBt4bupYyDEkeG7mSBow6BpIGzDsm5nIHTEg25nIHRow6ptIDAuNTc3MyDEkcahbiB24buLIG7hur91IGjDoG5oIGtow6FjaCDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSBsw6AgIkF2ZXJhZ2UiIHNvIHbhu5tpIGThu4tjaCB24bulIGPGoSBi4bqjbi4NCg0KSOG7hyBz4buRIGPhu6dhIEluZmxpZ2h0IFNlcnZpY2UgKEdvb2QpOiAwLjczOTYgY2hvIHRo4bqleSBt4bupYyDEkeG7mSBow6BpIGzDsm5nIHTEg25nIHRow6ptIDAuNzM5NiDEkcahbiB24buLIG7hur91IGjDoG5oIGtow6FjaCDEkcOhbmggZ2nDoSBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSBsw6AgIkdvb2QiIHNvIHbhu5tpIGThu4tjaCB24bulIGPGoSBi4bqjbi4NCg0KSOG7hyBz4buRIGPhu6dhIEluZmxpZ2h0IFNlcnZpY2UgKFZlcnkgR29vZCk6IDAuODM5MSBjaG8gdGjhuqV5IG3hu6ljIMSR4buZIGjDoGkgbMOybmcgdMSDbmcgdGjDqm0gMC44MzkxIMSRxqFuIHbhu4sgbuG6v3UgaMOgbmgga2jDoWNoIMSRw6FuaCBnacOhIGThu4tjaCB24bulIHRyw6puIG3DoXkgYmF5IGzDoCAiVmVyeSBHb29kIiBzbyB24bubaSBk4buLY2ggduG7pSBjxqEgYuG6o24uDQoNCkjhu4cgc+G7kSBj4bunYSBEZXBhcnR1cmUgRGVsYXkgaW4gTWludXRlczogMC4wMDA1IGNobyB0aOG6pXkgbeG7l2kgcGjDunQgY2jhuq1tIHRy4buFIGtoaSBraOG7n2kgaMOgbmggbMOgbSB0xINuZyBt4bupYyDEkeG7mSBow6BpIGzDsm5nIGThu7EgxJFvw6FuIGzDqm4gMC4wMDA1IMSRxqFuIHbhu4suIFR1eSBuaGnDqm4sIOG6o25oIGjGsOG7n25nIG7DoHkgbMOgIHLhuqV0IG5o4buPIHbDoCBjw7MgdGjhu4Mga2jDtG5nIMSRw6FuZyBr4buDIHRyb25nIHRo4buxYyB04bq/Lg0KDQpI4buHIHPhu5EgY+G7p2EgQXJyaXZhbCBEZWxheSBpbiBNaW51dGVzOiAtMC4wMDEwIGNobyB0aOG6pXkgbeG7l2kgcGjDunQgaOG6oSBjw6FuaCBjaOG6rW0gdHLhu4Uga2hpIMSR4bq/biBsw6BtIGdp4bqjbSBt4bupYyDEkeG7mSBow6BpIGzDsm5nIGThu7EgxJFvw6FuIMSRaSAwLjAwMTAgxJHGoW4gduG7iy4gTeG6t2MgZMO5IGdpw6EgdHLhu4sgbsOgeSBuaOG7jywgbmjGsG5nIG7DsyBjaG8gdGjhuqV5IHLhurFuZyBz4buxIGNo4bqtbSB0cuG7hSBraGkgxJHhur9uIGPDsyDhuqNuaCBoxrDhu59uZyB0acOqdSBj4buxYyDEkeG6v24gc+G7sSBow6BpIGzDsm5nIGPhu6dhIGjDoG5oIGtow6FjaC4NCg0KIyMjIE3DtCBow6xuaCBsb2dpdA0KDQpgYGB7cn0NCiMgRml0IHRoZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsDQptb2RlbDIgPC0gZ2xtKHNhdGlzZmFjdGlvbiB+IGBDdXN0b21lciBUeXBlYCArIENsYXNzICsgYEluZmxpZ2h0IHNlcnZpY2VgKyBgRGVwYXJ0dXJlIERlbGF5IGluIE1pbnV0ZXNgK2BBcnJpdmFsIERlbGF5IGluIE1pbnV0ZXNgLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IiksIGRhdGEgPSBkYXRhKQ0KIyBWaWV3IHRoZSBtb2RlbCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZGVsMikNCmBgYA0KIVtdKEM6XFVzZXJzXGRlbGxcUGljdHVyZXNcU2NyZWVuc2hvdHNcU2NyZWVuc2hvdCAyMDI0LTA4LTAzIDEyMzczOS5wbmcpDQohW10oQzpcVXNlcnNcZGVsbFxQaWN0dXJlc1xTY3JlZW5zaG90c1xTY3JlZW5zaG90IDIwMjQtMDgtMDMgMTIzOTE1LnBuZykNCg0KIVtdKEM6XFVzZXJzXGRlbGxcUGljdHVyZXNcU2NyZWVuc2hvdHNcU2NyZWVuc2hvdCAyMDI0LTA4LTAzIDEyMzQ1Ni5wbmcpDQoNCiMjIyBNw7QgaMOsbmggcHJvYml0DQoNCmBgYHtyfQ0KIyBGaXQgdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwNCm1vZGVsMyA8LSBnbG0oc2F0aXNmYWN0aW9uIH4gYEN1c3RvbWVyIFR5cGVgICsgQ2xhc3MgKyBgSW5mbGlnaHQgc2VydmljZWArIGBEZXBhcnR1cmUgRGVsYXkgaW4gTWludXRlc2ArYEFycml2YWwgRGVsYXkgaW4gTWludXRlc2AsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAicHJvYml0IiksIGRhdGEgPSBkYXRhKQ0KIyBWaWV3IHRoZSBtb2RlbCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZGVsMykNCmBgYA0KDQpwcm9iaXQoUChzYXRpc2ZhY3Rpb24gPSAxKSkgPSAtNC44MjQ3NTQ5ICsgMC42NTYyNDYyICogQ3VzdG9tZXIgVHlwZUxveWFsIEN1c3RvbWVyIC0gMS4zMTU1Mjg1ICogQ2xhc3NFY28gLSAxLjE2MzAyODIgKiBDbGFzc0VjbyBQbHVzICsgNC41NzUzNjU1ICogSW5mbGlnaHQgc2VydmljZVLhuqV0IHThu4cgKyA0LjQyNTI4ODYgKiBJbmZsaWdodCBzZXJ2aWNlVOG7hyArIDQuMzIyNzk4MyAqIEluZmxpZ2h0IHNlcnZpY2VCw6xuaCB0aMaw4budbmcgKyA0Ljg4NTU0NjMgKiBJbmZsaWdodCBzZXJ2aWNlSMOgaSBsw7JuZyArIDUuMjIwNTc4NCAqIEluZmxpZ2h0IHNlcnZpY2VS4bqldCBow6BpIGzDsm5nICsgMC4wMDE2NzI3ICogRGVwYXJ0dXJlIERlbGF5IGluIE1pbnV0ZXMgLSAwLjAwMzU1NDEgKiBBcnJpdmFsIERlbGF5IGluIE1pbnV0ZXMNCg0KSOG7hyBz4buRIGPhu6dhIEN1c3RvbWVyIFR5cGUgKDEuMTk1MSBjaG8gdGjhuqV5IEtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY8OzIGNo4buJIHPhu5EgcHJvYml0IDEuMTk1MSBzbyB24bubaSBraMOhY2ggaMOgbmcga2jDtG5nIHRydW5nIHRow6BuaC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGtow6FjaCBow6BuZyB0cnVuZyB0aMOgbmggY8OzIGto4bqjIG7Eg25nIGjDoGkgbMOybmcgY2FvIGjGoW4gxJHDoW5nIGvhu4MgdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpDQoNCkjhu4cgc+G7kSBj4bunYSBDbGFzcyAoRWNvKTogLTIuMjE0NiBjaG8gdGjhuqV5IEjDoG5oIGtow6FjaCBjaOG7jW4gaOG6oW5nIGdo4bq/IEVjb25vbXkgKEVjbykgY8OzIGNo4buJIHPhu5EgcHJvYml0IGPhu6dhIHPhu7EgaMOgaSBsw7JuZyBnaeG6o20gxJFpIDIuMjE0NiBzbyB24bubaSBo4bqhbmcgZ2jhur8ga2jDoWMuIMSQaeG7gXUgbsOgeSBjaOG7iSByYSBy4bqxbmcgaMOgbmgga2jDoWNoIGNo4buNbiBo4bqhbmcgZ2jhur8gRWNvbm9teSBjw7Mga2jhuqMgbsSDbmcga2jDtG5nIGjDoGkgbMOybmcgY2FvIGjGoW4gdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpDQoNCkjhu4cgc+G7kSBj4bunYSBDbGFzcyAoRWNvIFBsdXMpOiAtMS45MjczIGNobyB0aOG6pXk6IEjDoG5oIGtow6FjaCBjaOG7jW4gaOG6oW5nIGdo4bq/IEVjb25vbXkgUGx1cyAoRWNvIFBsdXMpIGPDsyBsb2cgb2RkcyBj4bunYSBz4buxIGjDoGkgbMOybmcgZ2nhuqNtIMSRaSAxLjkyNzMgc28gduG7m2kgaOG6oW5nIGdo4bq/IGtow6FjLiDEkGnhu4F1IG7DoHkgY2jhu4kgcmEgcuG6sW5nIGjDoG5oIGtow6FjaCBjaOG7jW4gaOG6oW5nIGdo4bq/IEVjb25vbXkgUGx1cyBjw7Mga2jhuqMgbsSDbmcga2jDtG5nIGjDoGkgbMOybmcgY2FvIGjGoW4gdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpDQoNCkjhu4cgc+G7kSBj4bunYSBJbmZsaWdodCBTZXJ2aWNlIChWZXJ5IFBvb3IpOiAxMS4xNzkxIGNobyB0aOG6pXkgY2jhu4kgc+G7kSBwcm9iaXQgY+G7p2Egc+G7sSBow6BpIGzDsm5nIHTEg25nIHRow6ptIDExLjE3OTEga2hpIGThu4tjaCB24bulIHRyw6puIG3DoXkgYmF5IMSRxrDhu6NjIMSRw6FuaCBnacOhIGzDoCDigJxWZXJ5IFBvb3LigJ0gdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpIC4gdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpIC5N4bq3YyBkw7kgaOG7hyBz4buRIG7DoHkgY2FvLCBuw7MgY8OzIHRo4buDIGtow7RuZyBjw7Mgw70gbmdoxKlhIHRo4buxYyB04bq/IGRvIGdpw6EgdHLhu4sgcCBjYW8gKDAuODk0NykuDQoNCkjhu4cgc+G7kSBj4bunYSBJbmZsaWdodCBTZXJ2aWNlIChQb29yKTogMTAuOTIxNCBjaG8gdGjhuqV5IGNo4buJIHPhu5EgcHJvYml0IGPhu6dhIHPhu7EgaMOgaSBsw7JuZyB0xINuZyB0aMOqbSAxMC45MjE0IGtoaSBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSDEkcaw4bujYyDEkcOhbmggZ2nDoSBsw6Ag4oCcUG9vcuKAnS4gdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpIFTGsMahbmcgdOG7sSBuaMawIHRyw6puLCBnacOhIHRy4buLIHAgY2FvICgwLjg5NzEpIGNobyB0aOG6pXkgaOG7hyBz4buRIG7DoHkga2jDtG5nIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCkjhu4cgc+G7kSBj4bunYSBJbmZsaWdodCBTZXJ2aWNlIChBdmVyYWdlKTogMTAuNzcxNCBjaG8gdGjhuqV5IGNo4buJIHPhu5EgcHJvYml0IGPhu6dhIHPhu7EgaMOgaSBsw7JuZyB0xINuZyB0aMOqbSAxMC43NzE0IGtoaSBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSDEkcaw4bujYyDEkcOhbmggZ2nDoSBsw6Ag4oCcQXZlcmFnZeKAnS4gdsOgIHRyb25nIMSRaeG7gXUga2nhu4duIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpIEdpw6EgdHLhu4sgcCBjYW8gKDAuODk4NSkgY2hvIHRo4bqleSBo4buHIHPhu5EgbsOgeSBraMO0bmcgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqi4NCg0KSOG7hyBz4buRIGPhu6dhIEluZmxpZ2h0IFNlcnZpY2UgKEdvb2QpOiAxMS43Nzk4IGNobyB0aOG6pXkgY2jhu4kgc+G7kSBwcm9iaXQgY+G7p2Egc+G7sSBow6BpIGzDsm5nIHTEg25nIHRow6ptIDExLjc3OTgga2hpIGThu4tjaCB24bulIHRyw6puIG3DoXkgYmF5IMSRxrDhu6NjIMSRw6FuaCBnacOhIGzDoCDigJxHb29k4oCdLiBWw6AgdHJvbmcgxJFp4buBdSBraeG7h24gY8OhYyB54bq/dSB04buRIGtow6FjIGtow7RuZyDEkeG7lWkgR2nDoSB0cuG7iyBwIGNhbyAoMC44ODkxKSBjaG8gdGjhuqV5IGjhu4cgc+G7kSBuw6B5IGtow7RuZyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLg0KDQpI4buHIHPhu5EgY+G7p2EgSW5mbGlnaHQgU2VydmljZSAoVmVyeSBHb29kKTogMTIuMzE1NyBjaG8gdGjhuqV5IGNo4buJIHPhu5EgcHJvYml0IGPhu6dhIHPhu7EgaMOgaSBsw7JuZyB0xINuZyB0aMOqbSAxMi4zMTU3IGtoaSBk4buLY2ggduG7pSB0csOqbiBtw6F5IGJheSDEkcaw4bujYyDEkcOhbmggZ2nDoSBsw6Ag4oCcVmVyeSBHb29k4oCdLiB2w6AgdHJvbmcgxJFp4buBdSBraeG7h24gY8OhYyB54bq/dSB04buRIGtow6FjIGtow7RuZyDEkeG7lWkgR2nDoSB0cuG7iyBwIGNhbyAoMC44ODQxKSBjaG8gdGjhuqV5IGjhu4cgc+G7kSBuw6B5IGtow7RuZyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqLg0KDQoNCiMjIEPDoWMgdGnDqnUgY2jDrSDEkcOhbmggZ2nDoSBtw7QgaMOsbmgNCg0KIyMjIENo4buJIHPhu5EgQUlDDQoNCiMjIyMgQ2jhu4kgc+G7kSBBSUMgbcO0IGjDrG5oIHjDoWMgc3XhuqV0IHR1eeG6v24gdMOtbmgNCg0KYGBge3J9DQpBSUMobW9kZWwxKQ0KYGBgDQoNCiMjIyMgQ2jhu4kgc+G7kSBBSUMgbcO0IGjDrG5oIGxvZ2l0DQoNCmBgYHtyfQ0KQUlDKG1vZGVsMikNCmBgYA0KDQojIyMjIENo4buJIHPhu5EgQUlDIG3DtCBow6xuaCBwcm9iaXQNCg0KYGBge3J9DQpBSUMobW9kZWwzKQ0KYGBgDQoNCkvhur90IHF14bqjIHRyw6puIGNobyBjaMO6bmcgdGEgdGjhuqV5IHLhurFuZyBtw7QgaMOsbmggbG9naXQgc+G6vSBoaeG7h3UgcXXhuqMgaMahbiBjw6FjIG3DtCBow6xuaCBwcm9iaXQgdsOgIHjDoWMgc3XhuqV0IHR1eeG6v24gdMOtbmguIELhu59pIHbDrCBjaOG7iSBz4buRIEFJQyBj4bunYSBsb2dpdCDEkeG6oXQgdGjhuqVwIG5o4bqldCBsw6AgMjY2NTYuNjQsIHRyb25nIGtoaSDEkcOzIGPhu6dhIG3DtCBow6xuaCBwcm9iaXQgbMOgIDI2NzQ2LjY5IHbDoCBrw6ltIGhp4buHdSBxdeG6oyBuaOG6pXQgY+G7p2EgbcO0IGjDrG5oIHjDoWMgc3XhuqV0IHR1eeG6v24gdMOtbmggduG7m2kgQUlDIGzDoCAyNzc2Ny40Mi4NCg0KIyMjIEJyaWVyIFNjb3JlDQoNCiMjIyMgQnJpZXIgU2NvcmUgbcO0IGjDrG5oIHjDoWMgc3XhuqV0IHR1eeG6v24gdMOtbmgNCg0KYGBge3J9DQpCcmllclNjb3JlKG1vZGVsMSkNCmBgYA0KDQojIyMjIEJyaWVyIFNjb3JlIG3DtCBow6xuaCBsb2dpdA0KDQpgYGB7cn0NCkJyaWVyU2NvcmUobW9kZWwyKQ0KYGBgDQoNCiMjIyMgQnJpZXIgU2NvcmUgbcO0IGjDrG5oIHByb2JpdA0KDQpgYGB7cn0NCkJyaWVyU2NvcmUobW9kZWwzKQ0KYGBgDQoNCkThu7FhIHbDoG8ga+G6v3QgcXXhuqMgY+G7p2EgaOG7hyBz4buRIEJyaWVyIFNjb3JlIGNow7puZyB0w7RpIGNobyBy4bqxbmcgbcO0IGjDrG5oIGxvZ2l0IHbhuqtuIHPhur0gbMOgIGzhu7FhIGNo4buNbiB04buRdCBuaOG6pXQgdsOsIGdpw6EgdHLhu4sgQnJpZXJTY29yZSB0aOG6pXAgaMahbiDEkeG6oXQgMC4xNjY1ODE1LCBr4bq/dCBxdeG6oyBuw6B5IHTGsMahbmcgxJHhu5NuZyB24bubaSBwaMawxqFuZyBwaMOhcCBBSUMuIFRyb25nIGtoaSDEkcOzIGjhu4cgc+G7kSBCcmllciBTY29yZSBj4bunYSBtw7QgaMOsbmggcHJvYml0IGzDoCAwLjE2NzYwOTIuIEJyaWVyIFNjb3JlIGPhu6dhIGhhaSBtw7QgaMOsbmgga2jDoSB0aOG6pXAsIG3DtCBow6xuaCB4w6FjIHN14bqldCB0dXnhur9uIHTDrW5oIGvDqW0gaGnhu4d1IHF14bqjIG5o4bqldCB24bubaSAgaOG7hyBz4buRIEJyaWVyIFNjb3JlIGzDoCAwLjE3MDM2MDguDQoNCiMjIyBNYSB0cuG6rW4gbmjhuqdtIGzhuqtuDQoNCiMjIyMgTWEgdHLhuq1uIG5o4bqnbSBs4bqrbiBtw7QgaMOsbmggeMOhYyBzdeG6pXQgdHV54bq/biB0w61uaA0KDQpgYGB7cn0NCkNvbmYodGFibGUocHJlZGljdChtb2RlbDEsIHR5cGU9InJlc3BvbnNlIikgPj0wLjUsbW9kZWwxJGRhdGEkc2F0aXNmYWN0aW9uID09ICcxJykpDQpgYGANCg0KVOG7qyBr4bq/dCBxdeG6oyBtYSB0cuG6rW4gbmjhuqdtIGzhuqtuIGPhu6dhIG3DtCBow6xuaCB4w6FjIHN14bqldCB0dXnhur9uIHTDrW5oIGNobyBy4bqxbmcgY8OzIDExMDA1IHPhu5EgbOG6p24gbcO0IGjDrG5oIGThu7EgxJFvw6FuIMSRw7puZyBsw6Agc+G7kSBraMOhY2ggaMOgbmcga2jDtG5nIGjDoGkgbMOybmcuIFR1eSBuaGnDqm4gY8OzIDI3OTUgbOG6p24gbcO0IGjDrG5oIGThu7EgxJFvw6FuIHNhaSDEkeG7kWkgduG7m2kgc+G7kSBraMOhY2ggaMOgbmcga2jDtG5nIGjDoGkgbMOybmcgdsOgIGtob+G6o25nIDM1NjggbOG6p24gbcO0IGjDrG5oIGThu7EgxJFvw6FuIHNhaSBz4buRIGtow6FjaCBow6BuZyBow6BpIGzDsm5nLiBT4buRIGzhuqduIG3DtCBow6xuaCBk4buxIMSRb8OhbiDEkcO6bmcgc+G7kSBraMOhY2ggaMOgbmcgaMOgaSBsw7JuZyBsw6AgODYwOCBs4bqnbiAuIEvhur90IHF14bqjIGPFqW5nIGNo4buJIHJhIHThu7cgbOG7hyBtw7QgaMOsbmggZOG7sSDEkW/DoW4gxJHDum5nIGzDoCA3NS41MCUNCg0KIyMjIyBNYSB0cuG6rW4gbmjhuqdtIGzhuqtuIG3DtCBow6xuaCBsb2dpdA0KDQpgYGB7cn0NCkNvbmYodGFibGUocHJlZGljdChtb2RlbDIsIHR5cGU9InJlc3BvbnNlIikgPj0wLjUsbW9kZWwyJGRhdGEkc2F0aXNmYWN0aW9uID09ICcxJykpDQpgYGANCg0KVOG7qyBr4bq/dCBxdeG6oyBtYSB0cuG6rW4gbmjhuqdtIGzhuqtuIGPhu6dhIG3DtCBow6xuaCBsb2dpdCBjaG8gcuG6sW5nIGPDsyAxMTI2MyBz4buRIGzhuqduIG3DtCBow6xuaCBk4buxIMSRb8OhbiDEkcO6bmcgbMOgIHPhu5Ega2jDoWNoIGjDoG5nIGtow7RuZyBow6BpIGzDsm5nLiBUdXkgbmhpw6puIGPDsyAyOTU0IGzhuqduIG3DtCBow6xuaCBk4buxIMSRb8OhbiBzYWkgxJHhu5FpIHbhu5tpIHPhu5Ega2jDoWNoIGjDoG5nIGtow7RuZyBow6BpIGzDsm5nIHbDoCBraG/huqNuZyAzMzEwIGzhuqduIG3DtCBow6xuaCBk4buxIMSRb8OhbiBzYWkgc+G7kSBraMOhY2ggaMOgbmcgaMOgaSBsw7JuZy4gU+G7kSBs4bqnbiBtw7QgaMOsbmggZOG7sSDEkW/DoW4gxJHDum5nIHPhu5Ega2jDoWNoIGjDoG5nIGjDoGkgbMOybmcgbMOgIDg0NDkgbOG6p24gLiBL4bq/dCBxdeG6oyBjxaluZyBjaOG7iSByYSB04bu3IGzhu4cgbcO0IGjDrG5oIGThu7EgxJFvw6FuIMSRw7puZyBsw6AgNzUuODklLg0KDQojIyMjIE1hIHRy4bqtbiBuaOG6p20gbOG6q24gbcO0IGjDrG5oIHByb2JpdA0KDQpgYGB7cn0NCkNvbmYodGFibGUocHJlZGljdChtb2RlbDMsIHR5cGU9InJlc3BvbnNlIikgPj0wLjUsbW9kZWwzJGRhdGEkc2F0aXNmYWN0aW9uID09ICcxJykpDQpgYGANCg0KVOG7qyBr4bq/dCBxdeG6oyBtYSB0cuG6rW4gbmjhuqdtIGzhuqtuIGPhu6dhIG3DtCBow6xuaCBwcm9iaXQgY2hvIHLhurFuZyBjw7MgMTExMjEgc+G7kSBs4bqnbiBtw7QgaMOsbmggZOG7sSDEkW/DoW4gxJHDum5nIGzDoCBz4buRIGtow6FjaCBow6BuZyBraMO0bmcgaMOgaSBsw7JuZy4gVHV5IG5oacOqbiBjw7MgMjg3NiBs4bqnbiBtw7QgaMOsbmggZOG7sSDEkW/DoW4gc2FpIMSR4buRaSB24bubaSBz4buRIGtow6FjaCBow6BuZyBraMO0bmcgaMOgaSBsw7JuZyB2w6Aga2hv4bqjbmcgMzQ1MiBs4bqnbiBtw7QgaMOsbmggZOG7sSDEkW/DoW4gc2FpIHPhu5Ega2jDoWNoIGjDoG5nIGjDoGkgbMOybmcuIFPhu5EgbOG6p24gbcO0IGjDrG5oIGThu7EgxJFvw6FuIMSRw7puZyBz4buRIGtow6FjaCBow6BuZyBow6BpIGzDsm5nIGzDoCA4NTI3IGzhuqduIC4gS+G6v3QgcXXhuqMgY8WpbmcgY2jhu4kgcmEgdOG7tyBs4buHIG3DtCBow6xuaCBk4buxIMSRb8OhbiDEkcO6bmcgbMOgIDc1Ljg5JS4NCg0KDQo=