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

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

Bộ dữ liệu này mô phỏng hồ sơ bệnh nhân COVID-19 tại Đan Mạch, tập trung vào các yếu tố như lần nhiễm đầu tiên, tái nhiễm, tiêm vắc-xin, hội chứng hậu COVID (long COVID), cùng các thông tin nhân khẩu học và kết quả lâm sàng quan trọng. Dữ liệu bao gồm 3.000 hồ sơ tổng hợp với 26 đặc trưng liên quan, được thiết kế sát với thực tế nhằm phục vụ cho việc phân tích khám phá, mô hình dịch tễ học và mục đích giáo dục.

Toàn bộ dữ liệu đều là dữ liệu tổng hợp (synthetic), tái hiện các xu hướng thực tế từng ghi nhận trong giai đoạn đại dịch 2020–2024, đảm bảo an toàn khi sử dụng công khai. Bộ dữ liệu này phù hợp cho các ứng dụng như học máy, phân tích sống sót (survival analysis), khám phá yếu tố nguy cơ và nhiều nghiên cứu khác.

d <- read.csv("D:/PTDLDT/covid_related_disease_data.csv")
str(d)
## 'data.frame':    3000 obs. of  21 variables:
##  $ Patient_ID           : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Age                  : int  69 38 41 81 50 66 76 77 79 72 ...
##  $ Gender               : chr  "Male" "Male" "Female" "Female" ...
##  $ Region               : chr  "Hovedstaden" "Sjælland" "Syddanmark" "Hovedstaden" ...
##  $ Preexisting_Condition: chr  "Obesity" "Asthma" "Hypertension" "Asthma" ...
##  $ Date_of_Infection    : chr  "21/06/2022" "02/02/2024" "28/05/2023" "13/08/2023" ...
##  $ COVID_Strain         : chr  "Delta" "XBB.1.5" "Beta" "Delta" ...
##  $ Symptoms             : chr  "Mild" "Mild" "Mild" "Severe" ...
##  $ Severity             : chr  "Moderate" "Moderate" "High" "High" ...
##  $ Hospitalized         : chr  "Yes" "No" "Yes" "No" ...
##  $ ICU_Admission        : chr  "No" "No" "Yes" "No" ...
##  $ Ventilator_Support   : chr  "No" "No" "Yes" "No" ...
##  $ Recovered            : chr  "Yes" "No" "No" "Yes" ...
##  $ Reinfection          : chr  "No" "No" "No" "Yes" ...
##  $ Vaccination_Status   : chr  "Yes" "No" "Yes" "Yes" ...
##  $ Vaccine_Type         : chr  "None" "None" "Janssen" "AstraZeneca" ...
##  $ Doses_Received       : int  1 0 3 1 2 3 0 3 0 1 ...
##  $ Long_COVID_Symptoms  : chr  "None" "None" "None" "None" ...
##  $ Occupation           : chr  "Healthcare" "Healthcare" "Unemployed" "Office Worker" ...
##  $ Smoking_Status       : chr  "No" "No" "No" "No" ...
##  $ BMI                  : num  27.7 21.9 22.7 27.7 11.9 29.8 22.3 24.4 26.1 21.2 ...
  • Bộ dữ liệu covid_related_disease_data chứa tổng cộng 3.000 bản ghi với 21 biến đặc trưng mô tả thông tin liên quan đến bệnh nhân nhiễm COVID-19.
  • Các biến trong bộ dữ liệu bao gồm:
Tên biến Mô tả
Patient_ID Mã định danh duy nhất cho từng bệnh nhân
Age Tuổi của bệnh nhân
Gender Giới tính bệnh nhân (Male: nam, Female: nữ)
Region Khu vực địa lý sinh sống (ví dụ: Hovedstaden, Sjælland, …)
Preexisting_Condition Bệnh nền trước khi nhiễm (ví dụ: Obesity, Asthma, Hypertension, …)
Date_of_Infection Ngày nhiễm COVID-19 (định dạng “DD/MM/YYYY”)
COVID_Strain Biến thể virus SARS-CoV-2 mà bệnh nhân nhiễm (ví dụ: Delta, Beta, …)
Symptoms Mức độ triệu chứng ban đầu (ví dụ: Mild, Severe)
Severity Mức độ nghiêm trọng tổng thể của bệnh (ví dụ: Moderate, High)
Hospitalized Bệnh nhân có nhập viện hay không (Yes/No)
ICU_Admission Bệnh nhân có nhập ICU hay không (Yes/No)
Ventilator_Support Bệnh nhân có cần hỗ trợ thở máy không (Yes/No)
Recovered Bệnh nhân đã hồi phục hay chưa (Yes/No)
Reinfection Bệnh nhân có tái nhiễm COVID-19 không (Yes/No)
Vaccination_Status Bệnh nhân đã tiêm vắc-xin hay chưa (Yes/No)
Vaccine_Type Loại vắc-xin đã tiêm (nếu có), ví dụ: AstraZeneca, Janssen
Doses_Received Số liều vắc-xin mà bệnh nhân đã tiêm
Long_COVID_Symptoms Triệu chứng COVID kéo dài sau khi khỏi bệnh (nếu có)
Occupation Nghề nghiệp của bệnh nhân
Smoking_Status Tình trạng hút thuốc (Never, Former, Current, …)
BMI Chỉ số khối cơ thể của bệnh nhân (BMI - Body Mass Index)
  • Trong đó có 16 biến định tính
dldt <- c("Gender", "Region", "Preexisting_Condition", "COVID_Strain",
          "Symptoms", "Severity", "Hospitalized", "ICU_Admission", "Ventilator_Support",
          "Recovered", "Reinfection", "Vaccination_Status", "Vaccine_Type",
          "Long_COVID_Symptoms", "Occupation", "Smoking_Status")
dldt
##  [1] "Gender"                "Region"                "Preexisting_Condition"
##  [4] "COVID_Strain"          "Symptoms"              "Severity"             
##  [7] "Hospitalized"          "ICU_Admission"         "Ventilator_Support"   
## [10] "Recovered"             "Reinfection"           "Vaccination_Status"   
## [13] "Vaccine_Type"          "Long_COVID_Symptoms"   "Occupation"           
## [16] "Smoking_Status"
dt <- d[, dldt]
  • Chọn biến ReinfectionRecovered làm biến phụ thuộc để xem xét các yếu tố ảnh hưởng đến việc bệnh nhân có tái nhiệm Covid19 và việc phục hồi của bệnh nhận hay không.
dt <- data.frame(lapply(dt, as.factor))

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

2.1. Recovered và Vaccination_Status

2.1.1. Bảng tần số và tần suất

Bảng tần số

# Gán nhãn rõ ràng cho các biến
dt$Recovered <- factor(dt$Recovered,
                       levels = c("No", "Yes"),
                       labels = c("Không hồi phục", "Hồi phục"))

dt$Vaccination_Status <- factor(dt$Vaccination_Status,
                                levels = c("No", "Yes"),
                                labels = c("Chưa tiêm", "Đã tiêm"))

# Lập bảng tần số chéo giữa Recovered và Vaccination_Status
re_vac <- table(dt$Recovered, dt$Vaccination_Status)

# Thêm tổng hàng và tổng cột
re_vac1 <- addmargins(re_vac)

# Hiển thị bảng với nhãn rõ ràng
re_vac1
##                 
##                  Chưa tiêm Đã tiêm  Sum
##   Không hồi phục       743     749 1492
##   Hồi phục             785     723 1508
##   Sum                 1528    1472 3000

Bảng tần suất

# Lập bảng tần suất theo hàng (theo từng trạng thái hồi phục)
re_vac_prop <- prop.table(re_vac, margin = 1)

# Làm tròn để hiển thị đẹp hơn (ví dụ: 4 chữ số thập phân)
re_vac_prop_rounded <- round(re_vac_prop, 4)

# Hiển thị bảng tần suất
re_vac_prop_rounded
##                 
##                  Chưa tiêm Đã tiêm
##   Không hồi phục    0.4980  0.5020
##   Hồi phục          0.5206  0.4794

Biểu đồ

# Chuyển bảng sang dạng data frame
re_vac_df <- as.data.frame(re_vac)

# Đổi tên cột cho rõ ràng
colnames(re_vac_df) <- c("Recovered", "Vaccination_Status", "Count")

# Vẽ biểu đồ cột nhóm
ggplot(re_vac_df, aes(x = Vaccination_Status, y = Count, fill = Recovered)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Biểu đồ 1. Số lượng hồi phục theo tình trạng tiêm vắc xin",
    x = "Tình trạng tiêm vắc xin",
    y = "Số lượng bệnh nhân",
    fill = "Trạng thái hồi phục"
  ) +
  theme_minimal() +
  scale_fill_brewer(palette = "Pastel1")

Nhận xét

Dữ liệu cho thấy sự phân bố trạng thái hồi phục giữa hai nhóm bệnh nhân theo tình trạng tiêm vắc xin là tương đối đồng đều, tuy nhiên vẫn có một số khác biệt nhẹ. Trong nhóm chưa tiêm vắc xin, tỷ lệ hồi phục là khoảng 52.06%, trong khi 47.94% không hồi phục. Ngược lại, trong nhóm đã tiêm vắc xin, tỷ lệ không hồi phục lại nhỉnh hơn một chút, ở mức 50.20%, so với 49.80% hồi phục. Mặc dù sự chênh lệch là không lớn, điều này gợi ý rằng nhóm chưa tiêm có tỷ lệ hồi phục cao hơn một chút so với nhóm đã tiêm.

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

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

  • H₀: Tình trạng phục hồi và tình trạng tiêm vaccin là hai biến độc lập.

  • H₁: Tình trạng phục hồi và tình trạng tiêm vaccin có liên quan.

# Thực hiện kiểm định Chi bình phương
chi_re_vac <- chisq.test(re_vac)
print(chi_re_vac)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  re_vac
## X-squared = 1.4394, df = 1, p-value = 0.2302

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

  • Giá trị thống kê Chi bình phương: X² = 1.4394

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

  • p-value = 0.2302

Với p-value = 0.2302 lớn hơn mức ý nghĩa phổ biến α = 0.05, không đủ bằng chứng để bác bỏ giả thuyết H₀. Điều này có nghĩa là, trong mẫu dữ liệu hiện tại, không có sự khác biệt có ý nghĩa thống kê giữa tỷ lệ hồi phục của nhóm đã tiêm vắc xin và nhóm chưa tiêm.

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

# Lập bảng tần số chéo giữa Recovered và Vaccination_Status
re_vac <- table(dt$Recovered, dt$Vaccination_Status)

# Thêm tổng hàng và tổng cột
re_vac1 <- addmargins(re_vac)

# Hiển thị bảng với nhãn rõ ràng
re_vac1
##                 
##                  Chưa tiêm Đã tiêm  Sum
##   Không hồi phục       743     749 1492
##   Hồi phục             785     723 1508
##   Sum                 1528    1472 3000

\[ p_1 = P(\text{Recovered} = \text{Yes} \mid \text{Vaccination_Status} = \text{Chưa tiêm}) \quad \text{(Tỷ lệ hồi phục ở nhóm chưa tiêm)} \]

\[ p_2 = P(\text{Recovered} = \text{Yes} \mid \text{Vaccination_Status} = \text{Đã tiêm}) \quad \text{(Tỷ lệ hồi phục ở nhóm đã tiêm)} \]

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

\[ H_0: p_1 - p_2 = 0 \quad \text{(Tỷ lệ hồi phục ở nhóm chưa tiêm bằng tỷ lệ hồi phục ở nhóm đã tiêm)} \]

\[ H_1: p_1 - p_2 < 0 \quad \text{(Tỷ lệ hồi phục ở nhóm chưa tiêm nhỏ hơn tỷ lệ hồi phục ở nhóm đã tiêm)} \]

# Số người hồi phục trong từng nhóm tiêm chủng
counts <- c(re_vac["Hồi phục", "Chưa tiêm"], re_vac["Hồi phục", "Đã tiêm"])

# Tổng số người trong từng nhóm tiêm chủng
totals <- c(sum(re_vac[, "Chưa tiêm"]), sum(re_vac[, "Đã tiêm"]))

# Kiểm định tỉ lệ một phía: p1 < p2
test_recovery_less <- prop.test(counts, totals, alternative = "less", correct = FALSE)
test_recovery_less
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts out of totals
## X-squared = 1.5284, df = 1, p-value = 0.8918
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.00000000  0.05260304
## sample estimates:
##    prop 1    prop 2 
## 0.5137435 0.4911685
  • Kết quả kiểm định tỷ lệ hai mẫu cho thấy:

    • Tỷ lệ hồi phục ở nhóm chưa tiêm (prop 1) là khoảng 51.37%

    • Tỷ lệ hồi phục ở nhóm đã tiêm (prop 2) là khoảng 49.12%

  • Giá trị thống kê Chi bình phương là 1.5284 với bậc tự do 1 và p-value = 0.8918.

  • Vì p-value lớn hơn mức ý nghĩa 0.05, chúng ta không đủ bằng chứng để bác bỏ giả thuyết rằng tỷ lệ hồi phục ở nhóm chưa tiêm và nhóm đã tiêm là bằng nhau.

  • Ngoài ra, khoảng tin cậy 95% cho hiệu hai tỷ lệ bao gồm giá trị 0 (từ -1 đến 0.0526), cũng củng cố nhận định rằng sự khác biệt giữa hai tỷ lệ không có ý nghĩa thống kê.

  • Tóm lại, theo dữ liệu này, tỷ lệ hồi phục của nhóm chưa tiêm và nhóm đã tiêm không khác biệt đáng kể và không có bằng chứng cho thấy nhóm chưa tiêm có tỷ lệ hồi phục thấp hơn nhóm đã tiêm.

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

riskratio(re_vac, method="wald")
## $data
##                 
##                  Chưa tiêm Đã tiêm Total
##   Không hồi phục       743     749  1492
##   Hồi phục             785     723  1508
##   Total               1528    1472  3000
## 
## $measure
##                 risk ratio with 95% C.I.
##                   estimate     lower    upper
##   Không hồi phục 1.0000000        NA       NA
##   Hồi phục       0.9550453 0.8878662 1.027307
## 
## $p.value
##                 two-sided
##                  midp.exact fisher.exact chi.square
##   Không hồi phục         NA           NA         NA
##   Hồi phục        0.2166526    0.2281207  0.2163528
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Ta thấy RR = 0.955. Điều đó có nghĩa là tỷ lệ người đã tiêm trong nhóm hồi phục thấp hơn khoảng 4.5% so với tỷ lệ người đã tiêm trong nhóm không hồi phục. Có thể hiểu rằng việc tiêm vắc-xin không làm tăng khả năng hồi phục trong mẫu dữ liệu này.

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

or_result1 <- oddsratio(re_vac)
print(or_result1)
## $data
##                 
##                  Chưa tiêm Đã tiêm Total
##   Không hồi phục       743     749  1492
##   Hồi phục             785     723  1508
##   Total               1528    1472  3000
## 
## $measure
##                 odds ratio with 95% C.I.
##                   estimate    lower    upper
##   Không hồi phục 1.0000000       NA       NA
##   Hồi phục       0.9136808 0.791682 1.054367
## 
## $p.value
##                 two-sided
##                  midp.exact fisher.exact chi.square
##   Không hồi phục         NA           NA         NA
##   Hồi phục        0.2166526    0.2281207  0.2163528
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Giá trị odds ratio (OR) = 0.914 cho thấy rằng khả năng hồi phục ở nhóm đã tiêm vắc-xin thấp hơn khoảng 8,6% so với nhóm không hồi phục trong cùng điều kiện tiêm chủng. Nói cách khác, tỷ lệ người hồi phục nhờ đã tiêm vắc-xin thấp hơn khoảng 8.6% so với tỷ lệ người không hồi phục dù đã tiêm.

2.2. Recovered và Smoking_Status

2.2.1. Bảng tần số và tần suất

Bảng tần số

# Gán nhãn cho biến Smoking_Status (đã chuyển thành Yes/No trước đó)
dt$Smoking_Status <- factor(dt$Smoking_Status,
                            levels = c("No", "Yes"),
                            labels = c("Không hút thuốc", "Có hút thuốc"))
re_smoke <- table(dt$Recovered, dt$Smoking_Status)
re_smoke1 <- addmargins(re_smoke)
re_smoke1 
##                 
##                  Không hút thuốc Có hút thuốc  Sum
##   Không hồi phục             517          975 1492
##   Hồi phục                   502         1006 1508
##   Sum                       1019         1981 3000

Bảng tần suất

# Tính tỷ lệ theo hàng
re_smoke_prop <- prop.table(re_smoke, margin = 1)

# Làm tròn để hiển thị đẹp
re_smoke_prop_rounded <- round(re_smoke_prop, 4)

# Hiển thị bảng
re_smoke_prop_rounded
##                 
##                  Không hút thuốc Có hút thuốc
##   Không hồi phục          0.3465       0.6535
##   Hồi phục                0.3329       0.6671

Biểu đồ

# Chuyển bảng sang data frame
df <- as.data.frame(re_smoke)
colnames(df) <- c("Recovered", "Smoking_Status", "Count")

# Vẽ biểu đồ cột nhóm
ggplot(df, aes(x = Recovered, y = Count, fill = Smoking_Status)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Biều đồ 2. Phân bố trạng thái hút thuốc theo tình trạng hồi phục",
       x = "Tình trạng hồi phục",
       y = "Số lượng",
       fill = "Tình trạng hút thuốc") +
  theme_minimal()

Nhận xét

  • Trong tổng số 3.000 bệnh nhân, nhóm không hồi phục chiếm 1.492 người, trong đó có 517 người không hút thuốc (chiếm 34,65%) và 975 người có hút thuốc (chiếm 65,35%). Nhóm hồi phục chiếm 1.508 người, trong đó có 502 người không hút thuốc (33,29%) và 1.006 người có hút thuốc (66,71%).

  • Qua so sánh, tỷ lệ người có hút thuốc trong nhóm hồi phục (66,71%) cao hơn một chút so với nhóm không hồi phục (65,35%). Ngược lại, tỷ lệ người không hút thuốc ở nhóm không hồi phục (34,65%) cũng cao hơn nhẹ so với nhóm hồi phục (33,29%). Sự chênh lệch giữa hai nhóm là khá nhỏ, chỉ dao động khoảng 1–1,5%.

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

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

  • H₀: Tình trạng phục hồi và việc hút thuốc là hai biến độc lập.

  • H₁: Tình trạng phục hồi và việc hút thuốc có liên quan.

# Kiểm định Chi bình phương
chi_re_smoke <- chisq.test(re_smoke)
print(chi_re_smoke)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  re_smoke
## X-squared = 0.56134, df = 1, p-value = 0.4537

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

  • Giá trị thống kê Chi bình phương: X² = 0.56134

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

  • p-value = 0.4537

Với p-value = 0.4537 lớn hơn mức ý nghĩa phổ biến α = 0.05, không đủ bằng chứng để bác bỏ giả thuyết H₀. Điều này có nghĩa là Tình trạng phục hồi và việc hút thuốc là hai biến độc lập.

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

re_smoke <- table(dt$Recovered, dt$Smoking_Status)
re_smoke1 <- addmargins(re_smoke)
re_smoke1 
##                 
##                  Không hút thuốc Có hút thuốc  Sum
##   Không hồi phục             517          975 1492
##   Hồi phục                   502         1006 1508
##   Sum                       1019         1981 3000

\[ p_1 = P(\text{Recovered} = \text{Hồi phục} \mid \text{Smoking\_Status} = \text{Không hút thuốc}) \quad \text{(Tỷ lệ hồi phục ở nhóm không hút thuốc)} \] \[ p_2 = P(\text{Recovered} = \text{Hồi phục} \mid \text{Smoking\_Status} = \text{Có hút thuốc}) \quad \text{(Tỷ lệ hồi phục ở nhóm có hút thuốc)} \]

Giả thiết kiểm định

\[ H_0: p_1 - p_2 = 0 \quad \text{(Tỷ lệ hồi phục ở nhóm không hút thuốc bằng tỷ lệ hồi phục ở nhóm có hút thuốc)} \] \[ H_1: p_1 - p_2 < 0 \quad \text{(Tỷ lệ hồi phục ở nhóm không hút thuốc nhỏ hơn tỷ lệ hồi phục ở nhóm có hút thuốc)} \]

# Số người hồi phục trong từng nhóm hút thuốc
counts <- c(re_smoke["Hồi phục", "Không hút thuốc"],
            re_smoke["Hồi phục", "Có hút thuốc"])

# Tổng số người trong từng nhóm hút thuốc
totals <- c(sum(re_smoke[, "Không hút thuốc"]),
            sum(re_smoke[, "Có hút thuốc"]))

# Kiểm định một phía: Tỷ lệ hồi phục nhóm không hút thuốc < nhóm có hút thuốc
test_smoking_less <- prop.test(counts, totals, alternative = "less", correct = FALSE)

# Xem kết quả
print(test_smoking_less)
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts out of totals
## X-squared = 0.6206, df = 1, p-value = 0.2154
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.00000000  0.01651698
## sample estimates:
##    prop 1    prop 2 
## 0.4926398 0.5078243

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

  • Tỷ lệ hồi phục ở nhóm không hút thuốc (prop 1) là 49.26%

  • Tỷ lệ hồi phục ở nhóm có hút thuốc (prop 2) là 50.78%

  • Giá trị p-value = 0.2154, lớn hơn mức ý nghĩa thường dùng (α = 0.05)

Khoảng tin cậy 95% cho hiệu số tỷ lệ là từ –1.000 đến 0.0165, bao gồm giá trị 0

Với giá trị p-value = 0.2154 > 0.05, ta không đủ bằng chứng để bác bỏ giả thuyết \(H_0\). Nói cách khác, không có đủ cơ sở thống kê để kết luận rằng tỷ lệ hồi phục ở nhóm không hút thuốc thấp hơn so với nhóm có hút thuốc.

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

riskratio(re_smoke, method="wald")
## $data
##                 
##                  Không hút thuốc Có hút thuốc Total
##   Không hồi phục             517          975  1492
##   Hồi phục                   502         1006  1508
##   Total                     1019         1981  3000
## 
## $measure
##                 risk ratio with 95% C.I.
##                  estimate     lower    upper
##   Không hồi phục 1.000000        NA       NA
##   Hồi phục       1.020847 0.9697539 1.074633
## 
## $p.value
##                 two-sided
##                  midp.exact fisher.exact chi.square
##   Không hồi phục         NA           NA         NA
##   Hồi phục        0.4311699    0.4408087  0.4308253
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Ta thấy RR = 1.021. Điều này có nghĩa là tỷ lệ người hút thuốc trong nhóm hồi phục cao hơn khoảng 2.1% so với tỷ lệ người không hút thuốc trong nhóm hồi phục.

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

or_result2 <- oddsratio(re_smoke)
print(or_result2)
## $data
##                 
##                  Không hút thuốc Có hút thuốc Total
##   Không hồi phục             517          975  1492
##   Hồi phục                   502         1006  1508
##   Total                     1019         1981  3000
## 
## $measure
##                 odds ratio with 95% C.I.
##                  estimate     lower    upper
##   Không hồi phục 1.000000        NA       NA
##   Hồi phục       1.062596 0.9135028 1.236099
## 
## $p.value
##                 two-sided
##                  midp.exact fisher.exact chi.square
##   Không hồi phục         NA           NA         NA
##   Hồi phục        0.4311699    0.4408087  0.4308253
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Với OR = 1.0626, tỷ lệ người hồi phục trong nhóm hút thuốc cao hơn khoảng 6.26% so với tỷ lệ người không hồi phục trong nhóm hút thuốc.

2.3. Reinfection và Vaccination_Status

2.3.1. Bảng tần số và tần suất

Bảng tần số

dt$Reinfection <- factor(dt$Reinfection, 
                         levels = c("No", "Yes"),
                         labels = c("Không tái nhiễm", "Tái nhiễm"))

# Lập bảng tần số chéo
rein_vac <- table(dt$Reinfection, dt$Vaccination_Status)

# Thêm tổng hàng và cột
rein_vac1 <- addmargins(rein_vac)

# Hiển thị bảng
rein_vac1
##                  
##                   Chưa tiêm Đã tiêm  Sum
##   Không tái nhiễm      1398    1317 2715
##   Tái nhiễm             130     155  285
##   Sum                  1528    1472 3000

Bảng tần suất

# Lập bảng tần suất theo hàng (row percentages)
rein_vac_prop <- prop.table(rein_vac, margin = 1)

# Làm tròn 4 chữ số thập phân
rein_vac_prop <- round(rein_vac_prop, 4)

# Hiển thị bảng tần suất
rein_vac_prop
##                  
##                   Chưa tiêm Đã tiêm
##   Không tái nhiễm    0.5149  0.4851
##   Tái nhiễm          0.4561  0.5439

Biểu đồ

# Chuyển thành data frame
rein_vac_df <- as.data.frame(rein_vac)

# Đổi tên cột cho dễ hiểu
colnames(rein_vac_df) <- c("Reinfection", "Vaccination_Status", "Count")

# Vẽ biểu đồ
ggplot(rein_vac_df, aes(x = Vaccination_Status, y = Count, fill = Reinfection)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Biểu đồ 3. Tình trạng tái nhiễm theo tình trạng tiêm vắc xin",
    x = "Tình trạng tiêm vắc xin",
    y = "Số lượng bệnh nhân",
    fill = "Tình trạng tái nhiễm"
  ) +
  theme_minimal() +
  scale_fill_brewer(palette = "Set2")

Nhận xét

Dựa trên bảng tần suất, ta thấy rằng trong nhóm không tái nhiễm, tỷ lệ bệnh nhân chưa tiêm vắc xin chiếm khoảng 51.49%, cao hơn so với nhóm đã tiêm là 48.51%, với mức chênh lệch là 2.98%. Ngược lại, ở nhóm tái nhiễm, tỷ lệ bệnh nhân đã tiêm vắc xin lại cao hơn, đạt 54.39%, so với 45.61% ở nhóm chưa tiêm, tức là chênh lệch khoảng 8.78%.

Những con số này cho thấy rằng trong mẫu dữ liệu này, tỷ lệ tái nhiễm ở nhóm đã tiêm có xu hướng cao hơn so với nhóm chưa tiêm.

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

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

  • H₀: Tình trạng tái nhiễm và tình trạng tiêm vaccin là hai biến độc lập.

  • H₁: Tình trạng tái nhiễm và tình trạng tiêm vaccin có liên quan.

# Thực hiện kiểm định Chi bình phương
chi_rein_vac <- chisq.test(rein_vac)
print(chi_rein_vac)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  rein_vac
## X-squared = 3.3342, df = 1, p-value = 0.06786

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

  • Giá trị thống kê Chi bình phương: X² = 3.3342

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

  • p-value = 0.06786

Với mức ý nghĩa thường dùng là α = 0.05, ta thấy p-value = 0.06786 > 0.05, tức là không đủ bằng chứng thống kê để bác bỏ giả thuyết H₀. Nói cách khác, chưa thể kết luận rằng tình trạng tái nhiễm và tình trạng tiêm vắc xin có mối liên hệ rõ ràng trong mẫu dữ liệu này.

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

# Lập bảng tần số chéo
rein_vac <- table(dt$Reinfection, dt$Vaccination_Status)

# Thêm tổng hàng và cột
rein_vac1 <- addmargins(rein_vac)

# Hiển thị bảng
rein_vac1
##                  
##                   Chưa tiêm Đã tiêm  Sum
##   Không tái nhiễm      1398    1317 2715
##   Tái nhiễm             130     155  285
##   Sum                  1528    1472 3000

\[ p_1 = P(\text{Reinfection} = \text{Yes} \mid \text{Vaccination_Status} = \text{Chưa tiêm}) \quad \text{(Tỷ lệ tái nhiễm ở nhóm chưa tiêm)} \]

\[ p_2 = P(\text{Reinfection} = \text{Yes} \mid \text{Vaccination_Status} = \text{Đã tiêm}) \quad \text{(Tỷ lệ tái nhiễm ở nhóm đã tiêm)} \]

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

\[ H_0: p_1 - p_2 = 0 \quad \text{(Tỷ lệ tái nhiễm ở nhóm chưa tiêm bằng tỷ lệ tái nhiễm ở nhóm đã tiêm)} \]

\[ H_1: p_1 - p_2 < 0 \quad \text{(Tỷ lệ tái nhiễm ở nhóm chưa tiêm nhỏ hơn tỷ lệ tái nhiễm ở nhóm đã tiêm)} \]

# Số người tái nhiễm trong từng nhóm tiêm chủng
counts_reinfection <- c(rein_vac["Tái nhiễm", "Chưa tiêm"], rein_vac["Tái nhiễm", "Đã tiêm"])

# Tổng số người trong từng nhóm tiêm chủng
totals_reinfection <- c(sum(rein_vac[, "Chưa tiêm"]), sum(rein_vac[, "Đã tiêm"]))

# Kiểm định tỉ lệ một phía: p1 < p2 (tỷ lệ tái nhiễm ở nhóm chưa tiêm nhỏ hơn nhóm đã tiêm)
test_reinfection_less <- prop.test(counts_reinfection, totals_reinfection, alternative = "less", correct = FALSE)

# Hiển thị kết quả kiểm định
test_reinfection_less
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts_reinfection out of totals_reinfection
## X-squared = 3.5655, df = 1, p-value = 0.0295
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.000000000 -0.002585538
## sample estimates:
##     prop 1     prop 2 
## 0.08507853 0.10529891

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

  • Tỷ lệ tái nhiễm ở nhóm chưa tiêm (prop 1) là khoảng 8.51%.

  • Tỷ lệ tái nhiễm ở nhóm đã tiêm (prop 2) là khoảng 10.53%.

Với p-value = 0.0295, nhỏ hơn mức ý nghĩa 0.05, chúng ta có đủ bằng chứng để bác bỏ giả thuyết H₀. Điều này có nghĩa là Tỷ lệ tái nhiễm ở nhóm chưa tiêm nhỏ hơn tỷ lệ tái nhiễm ở nhóm đã tiêm.

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

riskratio(rein_vac, method="wald")
## $data
##                  
##                   Chưa tiêm Đã tiêm Total
##   Không tái nhiễm      1398    1317  2715
##   Tái nhiễm             130     155   285
##   Total                1528    1472  3000
## 
## $measure
##                  risk ratio with 95% C.I.
##                   estimate    lower    upper
##   Không tái nhiễm 1.000000       NA       NA
##   Tái nhiễm       1.121169 1.001205 1.255505
## 
## $p.value
##                  two-sided
##                   midp.exact fisher.exact chi.square
##   Không tái nhiễm         NA           NA         NA
##   Tái nhiễm       0.05943728   0.06179783 0.05899318
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Giá trị RR = 1.121 cho thấy rằng tỷ lệ người đã tiêm vắc xin trong nhóm bị tái nhiễm cao hơn khoảng 12.1% so với nhóm không bị tái nhiễm.

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

or_result3 <- oddsratio(rein_vac)
print(or_result3)
## $data
##                  
##                   Chưa tiêm Đã tiêm Total
##   Không tái nhiễm      1398    1317  2715
##   Tái nhiễm             130     155   285
##   Total                1528    1472  3000
## 
## $measure
##                  odds ratio with 95% C.I.
##                   estimate     lower    upper
##   Không tái nhiễm 1.000000        NA       NA
##   Tái nhiễm       1.265329 0.9906896 1.618385
## 
## $p.value
##                  two-sided
##                   midp.exact fisher.exact chi.square
##   Không tái nhiễm         NA           NA         NA
##   Tái nhiễm       0.05943728   0.06179783 0.05899318
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Giá trị OR = 1.265 cho thấy rằng khả năng đã tiêm vắc xin trong nhóm tái nhiễm cao hơn khoảng 26.5% so với nhóm không tái nhiễm. Nói cách khác, tỷ lệ đã tiêm so với chưa tiêm ở nhóm tái nhiễm lớn hơn so với nhóm không tái nhiễm.

Tỷ số odds (OR) là 1.265, nghĩa là odds đã tiêm so với chưa tiêm trong nhóm tái nhiễm cao hơn khoảng 26.5% so với nhóm không tái nhiễm.

2.4. Reinfection và Smoking_Status

2.4.1. Bảng tần số và tần suất

Bảng tần số

# Lập bảng tần số chéo
rein_smoke <- table(dt$Reinfection, dt$Smoking_Status)

# Thêm tổng hàng và cột
rein_smoke1 <- addmargins(rein_smoke)

# Hiển thị bảng
rein_smoke1
##                  
##                   Không hút thuốc Có hút thuốc  Sum
##   Không tái nhiễm             920         1795 2715
##   Tái nhiễm                    99          186  285
##   Sum                        1019         1981 3000

Bảng tần suất

# Lập bảng tần suất theo hàng (row percentages)
rein_smoke_prop <- prop.table(rein_smoke, margin = 1)

# Làm tròn 4 chữ số thập phân
rein_smoke_prop <- round(rein_smoke_prop, 4)

# Hiển thị bảng tần suất
rein_smoke_prop
##                  
##                   Không hút thuốc Có hút thuốc
##   Không tái nhiễm          0.3389       0.6611
##   Tái nhiễm                0.3474       0.6526

Biểu đồ

# Chuyển thành data frame
rein_smoke_df <- as.data.frame(rein_smoke)

# Đổi tên cột cho dễ hiểu
colnames(rein_smoke_df ) <- c("Reinfection", "Smoking_Status", "Count")

# Vẽ biểu đồ
ggplot(rein_smoke_df, aes(x = Smoking_Status, y = Count, fill = Reinfection)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(
    title = "Biểu đồ 4. Tình trạng tái nhiễm theo tình trạng hút thuốc",
    x = "Tình trạng hút thuốc",
    y = "Số lượng bệnh nhân",
    fill = "Tình trạng tái nhiễm"
  ) +
  theme_minimal() +
  scale_fill_brewer(palette = "Set2")

Dựa trên số liệu khảo sát từ 3.000 người, trong đó có 2.715 người không tái nhiễm và 285 người bị tái nhiễm, chúng ta có thể xem xét mối liên quan giữa tình trạng hút thuốc và nguy cơ tái nhiễm.

Ở nhóm không tái nhiễm, tỷ lệ người có hút thuốc là 66.11%, trong khi tỷ lệ không hút thuốc là 33.89%. Trong khi đó, ở nhóm tái nhiễm, tỷ lệ người có hút thuốc là 65.26%, và tỷ lệ không hút thuốc là 34.74%. Các tỷ lệ này cho thấy sự phân bố giữa người hút thuốc và không hút thuốc trong hai nhóm là khá tương đồng.

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

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

  • H₀: Tình trạng tái nhiễm và tình trạng hút thuốc là hai biến độc lập.

  • H₁: Tình trạng tái nhiễm và tình trạng hút thuốc có liên quan.

# Thực hiện kiểm định Chi bình phương
chi_rein_smoke<- chisq.test(rein_smoke)
print(chi_rein_smoke)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  rein_smoke
## X-squared = 0.049663, df = 1, p-value = 0.8237

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

  • Giá trị thống kê Chi bình phương: X² = 0.049663

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

  • p-value = 0.8237

Với mức ý nghĩa thường dùng là α = 0.05, ta thấy p-value = 0.8237 > 0.05, tức là không đủ bằng chứng thống kê để bác bỏ giả thuyết H₀. Nói cách khác, chưa thể kết luận rằng tình trạng tái nhiễm và tình trạng hút thuốc có mối liên hệ rõ ràng trong mẫu dữ liệu này.

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

# Lập bảng tần số chéo
rein_smoke <- table(dt$Reinfection, dt$Smoking_Status)

# Thêm tổng hàng và cột
rein_smoke1 <- addmargins(rein_smoke)

# Hiển thị bảng
rein_smoke1
##                  
##                   Không hút thuốc Có hút thuốc  Sum
##   Không tái nhiễm             920         1795 2715
##   Tái nhiễm                    99          186  285
##   Sum                        1019         1981 3000

\[ p_1 = P(\text{Reinfection} = \text{Yes} \mid \text{Smoking\_Status} = \text{Không hút thuốc}) \quad \text{(Tỷ lệ tái nhiễm ở nhóm không hút thuốc)} \]

\[ p_2 = P(\text{Reinfection} = \text{Yes} \mid \text{Smoking\_Status} = \text{Có hút thuốc}) \quad \text{(Tỷ lệ tái nhiễm ở nhóm có hút thuốc)} \]

Giả thuyết kiểm định

\[ H_0: p_1 - p_2 = 0 \quad \text{(Tỷ lệ tái nhiễm ở nhóm không hút thuốc bằng tỷ lệ tái nhiễm ở nhóm có hút thuốc)} \]

\[ H_1: p_1 - p_2 > 0 \quad \text{(Tỷ lệ tái nhiễm ở nhóm không hút thuốc lớn hơn tỷ lệ tái nhiễm ở nhóm có hút thuốc)} \]

# Số người tái nhiễm trong từng nhóm hút thuốc
counts_smoking <- c(rein_smoke["Tái nhiễm", "Không hút thuốc"],
                    rein_smoke["Tái nhiễm", "Có hút thuốc"])

# Tổng số người trong từng nhóm hút thuốc
totals_smoking <- c(sum(rein_smoke[, "Không hút thuốc"]),
                    sum(rein_smoke[, "Có hút thuốc"]))

# Kiểm định tỉ lệ một phía: p1 > p2 (tỷ lệ tái nhiễm ở nhóm không hút thuốc lớn hơn nhóm có hút thuốc)
test_smoking_greater <- prop.test(counts_smoking, totals_smoking, alternative = "greater", correct = FALSE)

# Hiển thị kết quả kiểm định
test_smoking_greater
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  counts_smoking out of totals_smoking
## X-squared = 0.083284, df = 1, p-value = 0.3864
## alternative hypothesis: greater
## 95 percent confidence interval:
##  -0.01542171  1.00000000
## sample estimates:
##     prop 1     prop 2 
## 0.09715407 0.09389197
  • Giá trị thống kê kiểm định (Chi-squared): 0.083
  • Giá trị p-value: 0.3864

Với mức ý nghĩa 5% (\(\alpha = 0.05\)), ta có:
\[ \text{p-value} = 0.3864 > 0.05 \]
Không có đủ bằng chứng để bác bỏ giả thuyết không.

Kết luận: Không có đủ bằng chứng thống kê để khẳng định rằng tỷ lệ tái nhiễm ở nhóm không hút thuốc lớn hơn nhóm có hút thuốc.

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

riskratio(rein_smoke, method="wald")
## $data
##                  
##                   Không hút thuốc Có hút thuốc Total
##   Không tái nhiễm             920         1795  2715
##   Tái nhiễm                    99          186   285
##   Total                      1019         1981  3000
## 
## $measure
##                  risk ratio with 95% C.I.
##                   estimate     lower    upper
##   Không tái nhiễm 1.000000        NA       NA
##   Tái nhiễm       0.987128 0.9031794 1.078879
## 
## $p.value
##                  two-sided
##                   midp.exact fisher.exact chi.square
##   Không tái nhiễm         NA           NA         NA
##   Tái nhiễm        0.7694533    0.7926716  0.7728959
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Với RR = 0.987, ta nhận thấy rằng tỷ lệ người hút thuốc ở nhóm tái nhiễm thấp hơn khoảng 1.3% so với nhóm không tái nhiễm.

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

or_result4 <- oddsratio(rein_smoke)
print(or_result4)
## $data
##                  
##                   Không hút thuốc Có hút thuốc Total
##   Không tái nhiễm             920         1795  2715
##   Tái nhiễm                    99          186   285
##   Total                      1019         1981  3000
## 
## $measure
##                  odds ratio with 95% C.I.
##                    estimate     lower    upper
##   Không tái nhiễm 1.0000000        NA       NA
##   Tái nhiễm       0.9622827 0.7462312 1.247627
## 
## $p.value
##                  two-sided
##                   midp.exact fisher.exact chi.square
##   Không tái nhiễm         NA           NA         NA
##   Tái nhiễm        0.7694533    0.7926716  0.7728959
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Kết quả phân tích cho thấy Odds Ratio (OR) = 0.962, nghĩa là tỷ lệ người tái nhiễm trong nhóm hút thuốc thấp hơn khoảng 3.8% so với tỷ lệ người không tái nhiễm.

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

Qua quá trình tìm hiểu, mô tả và kiểm định thống kê trên bộ dữ liệu mô phỏng bệnh nhân COVID-19, báo cáo này đã phác họa nên một bức tranh toàn cảnh về đặc điểm dịch tễ và lâm sàng, đồng thời khám phá những mối liên hệ ban đầu giữa các yếu tố nguy cơ và kết quả điều trị. Các kết quả không chỉ cung cấp những con số cụ thể mà còn mở ra nhiều hướng thảo luận quan trọng.

3.1. Tổng kết các kết quả nổi bật

  • Thứ nhất, không có bằng chứng thống kê cho thấy tiêm vắc xin có liên quan đến khả năng hồi phục sau nhiễm COVID-19. Dù tỷ lệ hồi phục ở nhóm chưa tiêm nhỉnh hơn một chút so với nhóm đã tiêm, các kiểm định thống kê đều không phát hiện sự khác biệt có ý nghĩa. Các chỉ số như Risk RatioOdds Ratio đều cho thấy mức độ tương đương giữa hai nhóm. Điều này cho thấy rằng việc tiêm vắc xin không thể hiện tác động rõ rệt đến kết quả hồi phục trong dữ liệu khảo sát.

  • Thứ hai, tương tự, hành vi hút thuốc không có mối liên hệ rõ ràng với khả năng hồi phục hay nguy cơ tái nhiễm. Tỷ lệ giữa các nhóm hút và không hút thuốc phân bố khá đồng đều, và không có kiểm định nào cho kết quả có ý nghĩa thống kê. Điều này hàm ý rằng tình trạng hút thuốc, trong phạm vi của bộ dữ liệu này, không phải là yếu tố phân biệt khả năng hồi phục hay tái nhiễm.

  • Thứ ba và quan trọng nhất, kết quả cho thấy nguy cơ tái nhiễm COVID-19 ở nhóm đã tiêm vắc xin cao hơn đáng kể so với nhóm chưa tiêm. Tỷ lệ tái nhiễm ở nhóm đã tiêm vượt trội so với nhóm chưa tiêm, và sự khác biệt này đạt mức ý nghĩa thống kê. Các chỉ số như RR = 1.121OR = 1.265 phản ánh nguy cơ tái nhiễm cao hơn ở nhóm đã tiêm. Đây là phát hiện bất ngờ, trái ngược với giả định phổ biến rằng tiêm chủng làm giảm nguy cơ tái nhiễm. Kết quả này có thể bị ảnh hưởng bởi nhiều yếu tố như thời điểm tiêm, số liều tiêm, hoặc chủng virus gây bệnh – những yếu tố chưa được kiểm soát trong phân tích hiện tại.

3.2. Thảo luận và Hạn chế

3.2.1. Thảo luận kết quả

Kết quả đáng chú ý nhất từ phân tích là tỷ lệ tái nhiễm cao hơn ở nhóm đã tiêm vắc-xin. Đây là một phát hiện mang tính phản trực giác và cần được diễn giải một cách thận trọng. Điều này không có nghĩa rằng vắc-xin gây ra tái nhiễm, mà có thể phản ánh ảnh hưởng của các yếu tố khác chưa được kiểm soát. Một số giả thuyết có thể được đưa ra để giải thích hiện tượng này:

  • Yếu tố thời gian và biến thể virus: Bộ dữ liệu mô phỏng kéo dài trong giai đoạn 2020–2024, trong đó các biến thể mới như Omicron, XBB.1.5 đã xuất hiện. Người được tiêm vắc-xin sớm có thể đã bị suy giảm miễn dịch theo thời gian, trong khi nhóm chưa tiêm có thể đã từng mắc bệnh và hình thành miễn dịch tự nhiên gần hơn với thời điểm khảo sát, giúp giảm nguy cơ tái nhiễm.

  • Hành vi và các yếu tố gây nhiễu: Người đã tiêm có thể có tâm lý an toàn chủ quan, dẫn đến việc ít tuân thủ các biện pháp phòng dịch, làm tăng nguy cơ phơi nhiễm. Ngoài ra, nghề nghiệp (như nhân viên y tế), tuổi, hoặc tình trạng bệnh nền có thể ảnh hưởng đến cả xác suất tiêm chủng lẫn nguy cơ tái nhiễm, nhưng chưa được kiểm soát trong phân tích song biến hiện tại.

  • Kết quả không rõ ràng với biến hút thuốc: Việc không tìm thấy mối liên hệ giữa hút thuốc và các kết quả lâm sàng như hồi phục hay tái nhiễm có thể do ảnh hưởng của các yếu tố mạnh hơn, hoặc do bộ dữ liệu chưa phản ánh đầy đủ tác động thực tế của hút thuốc đến tiến triển bệnh.

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

  • Dữ liệu tổng hợp (Synthetic Data): Bộ dữ liệu sử dụng là dữ liệu mô phỏng, không phản ánh hoàn toàn thực tế. Do đó, mọi kết luận chỉ có ý nghĩa trong phạm vi dữ liệu này và không thể khái quát cho dân số thật.

  • Phân tích song biến (Bivariate Analysis): Các kiểm định hiện tại chỉ xem xét từng cặp biến độc lập, chưa kiểm soát các yếu tố nhiễu như độ tuổi, giới tính, bệnh nền, hoặc thời gian tiêm chủng. Điều này có thể dẫn đến kết luận sai lệch hoặc đánh giá chưa đầy đủ.

  • Định nghĩa biến còn đơn giản: Biến Vaccination_Status chỉ được phân loại nhị phân (Đã tiêm/Chưa tiêm), không phân biệt số liều, loại vắc-xin hay thời gian tiêm, vốn là những yếu tố quan trọng. Biến Smoking_Status cũng chỉ đơn thuần chia thành “Có hút thuốc/Không hút thuốc”, không phản ánh rõ mức độ, thời gian hoặc thói quen hút.

  • Thiếu yếu tố thời gian: Một hạn chế đáng kể là chưa xem xét thời gian giữa các sự kiện, chẳng hạn như thời gian từ khi tiêm vắc-xin đến lúc bị tái nhiễm. Yếu tố thời gian là rất quan trọng trong nghiên cứu dịch tễ và có thể ảnh hưởng mạnh đến kết quả.

3.3. Hướng phát triển và Đề xuất

Dựa trên các kết quả thu được và những hạn chế đã được chỉ ra trong phần trước, một số hướng phát triển và đề xuất tiếp theo được đưa ra nhằm cải thiện độ sâu và độ tin cậy của phân tích:

3.3.1. Sử dụng Phân tích Đa biến (Multivariate Analysis)

Để kiểm soát các yếu tố gây nhiễu tiềm tàng (confounding factors), cần mở rộng từ phân tích song biến sang các mô hình hồi quy đa biến, chẳng hạn như hồi quy logistic. Phương pháp này sẽ giúp đánh giá tác động độc lập của từng biến đến nguy cơ tái nhiễm hoặc khả năng hồi phục, khi đã kiểm soát các yếu tố khác.

Ví dụ: Xây dựng mô hình dự báo tái nhiễm với các biến đầu vào như Vaccination_Status, Age, Preexisting_Condition, Doses_Received, và COVID_Strain.

3.3.2. Phân tích sâu hơn về yếu tố vắc-xin

Hiện tại, biến Vaccination_Status chỉ được mã hóa dưới dạng nhị phân (Yes/No), điều này chưa phản ánh đầy đủ thông tin. Nên mở rộng phân tích bằng cách đưa thêm:

  • Số liều đã tiêm (Doses_Received)
  • Loại vắc-xin (Vaccine_Type)

Điều này sẽ giúp làm rõ liệu các loại vắc-xin khác nhau hoặc số liều khác nhau có ảnh hưởng đến nguy cơ tái nhiễm hoặc khả năng hồi phục hay không.

3.3.3. Thực hiện Phân tích theo dòng thời gian (Longitudinal Analysis)

Sử dụng các biến thời gian như Date_of_Infection để tiến hành các phân tích theo thời gian — ví dụ như phân tích sống sót (survival analysis) nhằm đánh giá:

  • Thời gian đến khi tái nhiễm (time to reinfection)
  • Thời gian hồi phục (time to recovery)

Qua đó, có thể xác định các yếu tố ảnh hưởng đến diễn tiến bệnh theo thời gian.

3.3.4. Phân khúc dữ liệu theo nhóm

Thực hiện phân tích riêng biệt theo các nhóm cụ thể trong dữ liệu để tìm hiểu xem mối quan hệ giữa các biến có thay đổi trong từng phân nhóm hay không. Một số cách phân khúc hữu ích bao gồm:

  • Theo biến thể virus (COVID_Strain)
  • Theo khu vực địa lý (Region)
  • Theo nhóm tuổi hoặc nhóm nguy cơ

3.3.5. Truyền thông kết quả một cách cẩn trọng

Đặc biệt với kết quả liên quan đến mối liên hệ giữa tiêm vắc-xin và tái nhiễm, cần nhấn mạnh rằng:

Tương quan không đồng nghĩa với quan hệ nhân quả.

Kết quả này chỉ phản ánh xu hướng trong dữ liệu và cần được kiểm chứng bằng các phân tích chuyên sâu hơn, có kiểm soát các yếu tố nhiễu. Không nên đưa ra kết luận khẳng định về hiệu quả hay tác động tiêu cực của vắc-xin chỉ dựa trên các phân tích đơn giản hiện tại.

Phần 4. Phương pháp ước lượng Maximum likehood

4.1. Giới thiệu tổng quan

Maximum Likelihood Estimation (MLE) là một phương pháp thống kê suy luận được sử dụng để tìm ra các giá trị tham số sao cho xác suất (hay “độ hợp lý”) để quan sát được dữ liệu thực tế là lớn nhất.

Trong bối cảnh phân tích dữ liệu định tính (categorical data), các mô hình thống kê thường ước lượng xác suất của một hoặc nhiều sự kiện rời rạc. MLE là phương pháp chuẩn và mạnh mẽ để thực hiện việc này.


4.2. Nguyên tắc cốt lõi: Hàm Hợp lý (Likelihood Function)

4.2.1. Phân biệt giữa xác suất và độ hợp lý:

  • Xác suất: \(P(\text{dữ liệu} \mid \theta)\) – Tham số đã biết, tính xác suất để dữ liệu xảy ra.

  • Độ hợp lý: \(L(\theta \mid \text{dữ liệu})\) – Dữ liệu đã biết, tìm tham số phù hợp nhất với dữ liệu.

Nếu các quan sát là độc lập, hàm hợp lý được viết:

\[ L(\theta \mid y_1, y_2, ..., y_n) = \prod_{i=1}^{n} P(y_i \mid \theta) \]

Trong đó: - \(\theta\): tham số của mô hình (ví dụ: xác suất \(p\) trong phân phối Bernoulli), - \(y_i\): quan sát thứ \(i\).

Mục tiêu của MLE là tìm giá trị \(\hat{\theta}\) sao cho \(L(\theta)\) đạt cực đại.


4.3. Quy trình thực hiện MLE

4.3.1. Bước 1: Giả định mô hình phân phối

  • Phân phối Bernoulli: Biến nhị phân (Yes/No).
    \(P(Y = y) = p^y (1 - p)^{1 - y}, \quad y \in \{0, 1\}\)

  • Phân phối Binomial: Tổng số lần thành công sau \(n\) phép thử độc lập.

  • Phân phối Multinomial: Biến có nhiều danh mục.

4.3.2. Bước 2: Xây dựng hàm hợp lý

Từ mô hình xác suất đã chọn, viết hàm hợp lý bằng tích các xác suất cho từng quan sát.

4.3.3. Bước 3: Sử dụng hàm Log-Likelihood

Để đơn giản hóa tính toán, lấy logarit tự nhiên:

\[ LL(\theta) = \log L(\theta) = \sum_{i=1}^{n} \log P(y_i \mid \theta) \]

Bước 4: Tối đa hóa Log-Likelihood

  • Lấy đạo hàm riêng \(\frac{d}{d\theta} LL(\theta)\)
  • Giải phương trình \(\frac{d}{d\theta} LL(\theta) = 0\) để tìm \(\hat{\theta}\)

4.4. Ví dụ minh họa: Ước lượng tỷ lệ tái nhiễm

Bài toán: Ước lượng tỷ lệ tái nhiễm \(p\) trong nhóm đã tiêm vắc-xin.

Bước 1: Mô hình

Biến Reinfection là nhị phân ⇒ dùng Bernoulli với tham số \(p = P(\text{Reinfection = Yes} \mid \text{Vaccinated = Yes})\)

Bước 2: Dữ liệu

  • Số người đã tiêm: \(n = 1472\)
  • Số người tái nhiễm: \(k = 155\)

Hàm hợp lý:

\[ L(p) = p^{155} (1 - p)^{1317} \]

Bước 3: Hàm Log-Likelihood

\[ LL(p) = \log L(p) = 155 \cdot \log(p) + 1317 \cdot \log(1 - p) \]

Bước 4: Tối đa hóa

Lấy đạo hàm:

\[ \frac{dLL}{dp} = \frac{155}{p} - \frac{1317}{1 - p} \]

Cho đạo hàm bằng 0:

\[ \frac{155}{p} = \frac{1317}{1 - p} \quad \Rightarrow \quad 155(1 - p) = 1317p \quad \Rightarrow \quad p = \frac{155}{1472} \approx 0.1053 \]

Kết luận: Ước lượng hợp lý tối đa cho tỷ lệ tái nhiễm là 10.53%, đúng bằng tỷ lệ mẫu quan sát được.


4.5. Ứng dụng MLE trong Hồi quy Logistic

MLE là phương pháp cơ bản để ước lượng các hệ số trong hồi quy logistic, một mô hình phổ biến cho biến phụ thuộc nhị phân.

Mô hình:

\[ P(Y = 1 \mid X) = \frac{1}{1 + \exp(-(\beta_0 + \beta_1 X_1 + \cdots + \beta_k X_k))} \]

Hàm log-likelihood:

\[ LL(\beta) = \sum_{i=1}^{n} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right] \]

Do không thể giải đạo hàm bằng tay, ta dùng các thuật toán số như Newton-Raphson, Gradient Descent để tìm \(\hat{\beta}\).


4.6. Ưu điểm và Nhược điểm của MLE

Ưu điểm: - Hiệu quả: Phương sai nhỏ nếu cỡ mẫu lớn.

  • Vững: Hội tụ về tham số thật khi số mẫu tăng.

  • Tiệm cận chuẩn: Hỗ trợ kiểm định và khoảng tin cậy.

  • Linh hoạt: Áp dụng cho nhiều mô hình thống kê.

Nhược điểm: - Phụ thuộc mô hình: Nếu mô hình sai, MLE sẽ sai lệch.

  • Có thể chệch: Với cỡ mẫu nhỏ.

  • Tính toán phức tạp: Với mô hình nhiều tham số cần thuật toán lặp.


4.7. Tổng kết

Phương pháp Ước lượng Hợp lý Tối đa (MLE) là một công cụ nền tảng trong thống kê hiện đại, đặc biệt hiệu quả trong việc xử lý và phân tích dữ liệu định tính. Dù là với bài toán ước lượng tỷ lệ đơn giản hay các mô hình hồi quy logistic phức tạp, MLE vẫn cung cấp giải pháp mạnh mẽ và có tính tổng quát cao.

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSB0deG6p24gNSINCmF1dGhvcjogIkzDqiBUaOG7iyBOZ+G7jWMgw4FuaCINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvYzogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogJzQnDQogIHBkZl9kb2N1bWVudDoNCiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQo8c3R5bGU+DQpib2R5IHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBzYW5zLXNlcmlmOw0KICBmb250LXNpemU6IDE2cHg7DQogIHRleHQtYWxpZ246IGp1c3RpZnk7DQogIGxpbmUtaGVpZ2h0OiAxLjU7DQp9DQpoMiB7DQogIGNvbG9yOiByZWQ7DQp9DQpoMyB7DQogIGNvbG9yOiBkYXJrYmx1ZTsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHNraW1yKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoY3N2KQ0KbGlicmFyeShEVCkNCmxpYnJhcnkocGFuZGVyKQ0KbGlicmFyeShmb3JtYXR0YWJsZSkNCmxpYnJhcnkoaHRtbHRvb2xzKQ0KbGlicmFyeShEZXNjVG9vbHMpDQpsaWJyYXJ5KGVwaXRvb2xzKQ0KYGBgDQoNCiMgKipQaOG6p24gMS4gVMOMTSBISeG7glUgVsOAIENIVeG6qE4gQuG7iiBE4buuIExJ4buGVSoqDQoNCkLhu5kgZOG7ryBsaeG7h3UgbsOgeSBtw7QgcGjhu49uZyBo4buTIHPGoSBi4buHbmggbmjDom4gQ09WSUQtMTkgdOG6oWkgxJBhbiBN4bqhY2gsIHThuq1wIHRydW5nIHbDoG8gY8OhYyB54bq/dSB04buRIG5oxrAgbOG6p24gbmhp4buFbSDEkeG6p3UgdGnDqm4sIHTDoWkgbmhp4buFbSwgdGnDqm0gduG6r2MteGluLCBo4buZaSBjaOG7qW5nIGjhuq11IENPVklEIChsb25nIENPVklEKSwgY8O5bmcgY8OhYyB0aMO0bmcgdGluIG5ow6JuIGto4bqpdSBo4buNYyB2w6Aga+G6v3QgcXXhuqMgbMOibSBzw6BuZyBxdWFuIHRy4buNbmcuIEThu68gbGnhu4d1IGJhbyBn4buTbSAzLjAwMCBo4buTIHPGoSB04buVbmcgaOG7o3AgduG7m2kgMjYgxJHhurdjIHRyxrBuZyBsacOqbiBxdWFuLCDEkcaw4bujYyB0aGnhur90IGvhur8gc8OhdCB24bubaSB0aOG7sWMgdOG6vyBuaOG6sW0gcGjhu6VjIHbhu6UgY2hvIHZp4buHYyBwaMOibiB0w61jaCBraMOhbSBwaMOhLCBtw7QgaMOsbmggZOG7i2NoIHThu4UgaOG7jWMgdsOgIG3hu6VjIMSRw61jaCBnacOhbyBk4bulYy4NCg0KVG/DoG4gYuG7mSBk4buvIGxp4buHdSDEkeG7gXUgbMOgIGThu68gbGnhu4d1IHThu5VuZyBo4bujcCAoc3ludGhldGljKSwgdMOhaSBoaeG7h24gY8OhYyB4dSBoxrDhu5tuZyB0aOG7sWMgdOG6vyB04burbmcgZ2hpIG5o4bqtbiB0cm9uZyBnaWFpIMSRb+G6oW4gxJHhuqFpIGThu4tjaCAyMDIw4oCTMjAyNCwgxJHhuqNtIGLhuqNvIGFuIHRvw6BuIGtoaSBz4butIGThu6VuZyBjw7RuZyBraGFpLiBC4buZIGThu68gbGnhu4d1IG7DoHkgcGjDuSBo4bujcCBjaG8gY8OhYyDhu6luZyBk4bulbmcgbmjGsCBo4buNYyBtw6F5LCBwaMOibiB0w61jaCBz4buRbmcgc8OzdCAoc3Vydml2YWwgYW5hbHlzaXMpLCBraMOhbSBwaMOhIHnhur91IHThu5Egbmd1eSBjxqEgdsOgIG5oaeG7gXUgbmdoacOqbiBj4bupdSBraMOhYy4NCg0KYGBge3J9DQpkIDwtIHJlYWQuY3N2KCJEOi9QVERMRFQvY292aWRfcmVsYXRlZF9kaXNlYXNlX2RhdGEuY3N2IikNCmBgYA0KDQpgYGB7cn0NCnN0cihkKQ0KYGBgDQoNCi0gQuG7mSBk4buvIGxp4buHdSAqKmNvdmlkX3JlbGF0ZWRfZGlzZWFzZV9kYXRhKiogY2jhu6lhIHThu5VuZyBj4buZbmcgKiozLjAwMCBi4bqjbiBnaGkqKiB24bubaSAqKjIxIGJp4bq/biDEkeG6t2MgdHLGsG5nKiogbcO0IHThuqMgdGjDtG5nIHRpbiBsacOqbiBxdWFuIMSR4bq/biBi4buHbmggbmjDom4gbmhp4buFbSBDT1ZJRC0xOS4NCi0gQ8OhYyBiaeG6v24gdHJvbmcgYuG7mSBk4buvIGxp4buHdSBiYW8gZ+G7k206DQoNCnwgVMOqbiBiaeG6v24gICAgICAgICAgICAgIHwgTcO0IHThuqMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQp8IGBQYXRpZW50X0lEYCAgICAgICAgICB8IE3DoyDEkeG7i25oIGRhbmggZHV5IG5o4bqldCBjaG8gdOG7q25nIGLhu4duaCBuaMOibiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgYEFnZWAgICAgICAgICAgICAgICAgIHwgVHXhu5VpIGPhu6dhIGLhu4duaCBuaMOibiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IGBHZW5kZXJgICAgICAgICAgICAgICB8IEdp4bubaSB0w61uaCBi4buHbmggbmjDom4gKE1hbGU6IG5hbSwgRmVtYWxlOiBu4buvKSAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgYFJlZ2lvbmAgICAgICAgICAgICAgIHwgS2h1IHbhu7FjIMSR4buLYSBsw70gc2luaCBz4buRbmcgKHbDrSBk4bulOiBIb3ZlZHN0YWRlbiwgU2rDpmxsYW5kLCAuLi4pICAgICAgICAgIHwNCnwgYFByZWV4aXN0aW5nX0NvbmRpdGlvbmAgfCBC4buHbmggbuG7gW4gdHLGsOG7m2Mga2hpIG5oaeG7hW0gKHbDrSBk4bulOiBPYmVzaXR5LCBBc3RobWEsIEh5cGVydGVuc2lvbiwgLi4uKSB8DQp8IGBEYXRlX29mX0luZmVjdGlvbmAgICB8IE5nw6B5IG5oaeG7hW0gQ09WSUQtMTkgKMSR4buLbmggZOG6oW5nICJERC9NTS9ZWVlZIikgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgYENPVklEX1N0cmFpbmAgICAgICAgIHwgQmnhur9uIHRo4buDIHZpcnVzIFNBUlMtQ29WLTIgbcOgIGLhu4duaCBuaMOibiBuaGnhu4VtICh2w60gZOG7pTogRGVsdGEsIEJldGEsIC4uLil8DQp8IGBTeW1wdG9tc2AgICAgICAgICAgICB8IE3hu6ljIMSR4buZIHRyaeG7h3UgY2jhu6luZyBiYW4gxJHhuqd1ICh2w60gZOG7pTogTWlsZCwgU2V2ZXJlKSAgICAgICAgICAgICAgICAgICAgICB8DQp8IGBTZXZlcml0eWAgICAgICAgICAgICB8IE3hu6ljIMSR4buZIG5naGnDqm0gdHLhu41uZyB04buVbmcgdGjhu4MgY+G7p2EgYuG7h25oICh2w60gZOG7pTogTW9kZXJhdGUsIEhpZ2gpICAgICAgICAgfA0KfCBgSG9zcGl0YWxpemVkYCAgICAgICAgfCBC4buHbmggbmjDom4gY8OzIG5o4bqtcCB2aeG7h24gaGF5IGtow7RuZyAoWWVzL05vKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBgSUNVX0FkbWlzc2lvbmAgICAgICAgfCBC4buHbmggbmjDom4gY8OzIG5o4bqtcCBJQ1UgaGF5IGtow7RuZyAoWWVzL05vKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgYFZlbnRpbGF0b3JfU3VwcG9ydGAgIHwgQuG7h25oIG5ow6JuIGPDsyBj4bqnbiBo4buXIHRy4bujIHRo4bufIG3DoXkga2jDtG5nIChZZXMvTm8pICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBgUmVjb3ZlcmVkYCAgICAgICAgICAgfCBC4buHbmggbmjDom4gxJHDoyBo4buTaSBwaOG7pWMgaGF5IGNoxrBhIChZZXMvTm8pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgYFJlaW5mZWN0aW9uYCAgICAgICAgIHwgQuG7h25oIG5ow6JuIGPDsyB0w6FpIG5oaeG7hW0gQ09WSUQtMTkga2jDtG5nIChZZXMvTm8pICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBgVmFjY2luYXRpb25fU3RhdHVzYCAgfCBC4buHbmggbmjDom4gxJHDoyB0acOqbSB24bqvYy14aW4gaGF5IGNoxrBhIChZZXMvTm8pICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBgVmFjY2luZV9UeXBlYCAgICAgICAgfCBMb+G6oWkgduG6r2MteGluIMSRw6MgdGnDqm0gKG7hur91IGPDsyksIHbDrSBk4bulOiBBc3RyYVplbmVjYSwgSmFuc3NlbiAgICAgICAgICAgIHwNCnwgYERvc2VzX1JlY2VpdmVkYCAgICAgIHwgU+G7kSBsaeG7gXUgduG6r2MteGluIG3DoCBi4buHbmggbmjDom4gxJHDoyB0acOqbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IGBMb25nX0NPVklEX1N5bXB0b21zYCB8IFRyaeG7h3UgY2jhu6luZyBDT1ZJRCBrw6lvIGTDoGkgc2F1IGtoaSBraOG7j2kgYuG7h25oIChu4bq/dSBjw7MpICAgICAgICAgICAgICAgICAgfA0KfCBgT2NjdXBhdGlvbmAgICAgICAgICAgfCBOZ2jhu4EgbmdoaeG7h3AgY+G7p2EgYuG7h25oIG5ow6JuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgYFNtb2tpbmdfU3RhdHVzYCAgICAgIHwgVMOsbmggdHLhuqFuZyBow7p0IHRodeG7kWMgKE5ldmVyLCBGb3JtZXIsIEN1cnJlbnQsIC4uLikgICAgICAgICAgICAgICAgICAgICB8DQp8IGBCTUlgICAgICAgICAgICAgICAgICB8IENo4buJIHPhu5Ega2jhu5FpIGPGoSB0aOG7gyBj4bunYSBi4buHbmggbmjDom4gKEJNSSAtIEJvZHkgTWFzcyBJbmRleCkgICAgICAgICAgICAgIHwNCg0KDQotIFRyb25nIMSRw7MgY8OzICoqMTYgYmnhur9uIMSR4buLbmggdMOtbmgqKg0KDQpgYGB7cn0NCmRsZHQgPC0gYygiR2VuZGVyIiwgIlJlZ2lvbiIsICJQcmVleGlzdGluZ19Db25kaXRpb24iLCAiQ09WSURfU3RyYWluIiwNCiAgICAgICAgICAiU3ltcHRvbXMiLCAiU2V2ZXJpdHkiLCAiSG9zcGl0YWxpemVkIiwgIklDVV9BZG1pc3Npb24iLCAiVmVudGlsYXRvcl9TdXBwb3J0IiwNCiAgICAgICAgICAiUmVjb3ZlcmVkIiwgIlJlaW5mZWN0aW9uIiwgIlZhY2NpbmF0aW9uX1N0YXR1cyIsICJWYWNjaW5lX1R5cGUiLA0KICAgICAgICAgICJMb25nX0NPVklEX1N5bXB0b21zIiwgIk9jY3VwYXRpb24iLCAiU21va2luZ19TdGF0dXMiKQ0KZGxkdA0KYGBgDQpgYGB7cn0NCmR0IDwtIGRbLCBkbGR0XQ0KYGBgDQoNCi0gQ2jhu41uIGJp4bq/biAqKlJlaW5mZWN0aW9uKiogdsOgICoqUmVjb3ZlcmVkKiogbMOgbSBiaeG6v24gcGjhu6UgdGh14buZYyDEkeG7gyB4ZW0geMOpdCBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcgxJHhur9uIHZp4buHYyBi4buHbmggbmjDom4gY8OzIHTDoWkgbmhp4buHbSBDb3ZpZDE5IHbDoCB2aeG7h2MgcGjhu6VjIGjhu5NpIGPhu6dhIGLhu4duaCBuaOG6rW4gaGF5IGtow7RuZy4NCg0KYGBge3J9DQpkdCA8LSBkYXRhLmZyYW1lKGxhcHBseShkdCwgYXMuZmFjdG9yKSkNCmBgYA0KDQojICoqUGjhuqduIDIuIFBIw4JOIFTDjUNIIE3hu5BJIFFVQU4gSOG7hiBHSeG7rkEgSEFJIEJJ4bq+TiDEkOG7ik5IIFTDjU5IKioNCg0KIyMgKioyLjEuIFJlY292ZXJlZCB2w6AgVmFjY2luYXRpb25fU3RhdHVzKioNCg0KIyMjICoqMi4xLjEuIELhuqNuZyB04bqnbiBz4buRIHbDoCB04bqnbiBzdeG6pXQgKioNCg0KKipC4bqjbmcgdOG6p24gc+G7kSoqDQpgYGB7cn0NCiMgR8OhbiBuaMOjbiByw7UgcsOgbmcgY2hvIGPDoWMgYmnhur9uDQpkdCRSZWNvdmVyZWQgPC0gZmFjdG9yKGR0JFJlY292ZXJlZCwNCiAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTm8iLCAiWWVzIiksDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIktow7RuZyBo4buTaSBwaOG7pWMiLCAiSOG7k2kgcGjhu6VjIikpDQoNCmR0JFZhY2NpbmF0aW9uX1N0YXR1cyA8LSBmYWN0b3IoZHQkVmFjY2luYXRpb25fU3RhdHVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ2jGsGEgdGnDqm0iLCAixJDDoyB0acOqbSIpKQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRIGNow6lvIGdp4buvYSBSZWNvdmVyZWQgdsOgIFZhY2NpbmF0aW9uX1N0YXR1cw0KcmVfdmFjIDwtIHRhYmxlKGR0JFJlY292ZXJlZCwgZHQkVmFjY2luYXRpb25fU3RhdHVzKQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgdOG7lW5nIGPhu5l0DQpyZV92YWMxIDwtIGFkZG1hcmdpbnMocmVfdmFjKQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcgduG7m2kgbmjDo24gcsO1IHLDoG5nDQpyZV92YWMxDQpgYGANCg0KKipC4bqjbmcgdOG6p24gc3XhuqV0KioNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc3XhuqV0IHRoZW8gaMOgbmcgKHRoZW8gdOG7q25nIHRy4bqhbmcgdGjDoWkgaOG7k2kgcGjhu6VjKQ0KcmVfdmFjX3Byb3AgPC0gcHJvcC50YWJsZShyZV92YWMsIG1hcmdpbiA9IDEpDQoNCiMgTMOgbSB0csOybiDEkeG7gyBoaeG7g24gdGjhu4sgxJHhurlwIGjGoW4gKHbDrSBk4bulOiA0IGNo4buvIHPhu5EgdGjhuq1wIHBow6JuKQ0KcmVfdmFjX3Byb3Bfcm91bmRlZCA8LSByb3VuZChyZV92YWNfcHJvcCwgNCkNCg0KIyBIaeG7g24gdGjhu4sgYuG6o25nIHThuqduIHN14bqldA0KcmVfdmFjX3Byb3Bfcm91bmRlZA0KYGBgDQoNCioqQmnhu4N1IMSR4buTKioNCmBgYHtyfQ0KIyBDaHV54buDbiBi4bqjbmcgc2FuZyBk4bqhbmcgZGF0YSBmcmFtZQ0KcmVfdmFjX2RmIDwtIGFzLmRhdGEuZnJhbWUocmVfdmFjKQ0KDQojIMSQ4buVaSB0w6puIGPhu5l0IGNobyByw7UgcsOgbmcNCmNvbG5hbWVzKHJlX3ZhY19kZikgPC0gYygiUmVjb3ZlcmVkIiwgIlZhY2NpbmF0aW9uX1N0YXR1cyIsICJDb3VudCIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgbmjDs20NCmdncGxvdChyZV92YWNfZGYsIGFlcyh4ID0gVmFjY2luYXRpb25fU3RhdHVzLCB5ID0gQ291bnQsIGZpbGwgPSBSZWNvdmVyZWQpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgMS4gU+G7kSBsxrDhu6NuZyBo4buTaSBwaOG7pWMgdGhlbyB0w6xuaCB0cuG6oW5nIHRpw6ptIHbhuq9jIHhpbiIsDQogICAgeCA9ICJUw6xuaCB0cuG6oW5nIHRpw6ptIHbhuq9jIHhpbiIsDQogICAgeSA9ICJT4buRIGzGsOG7o25nIGLhu4duaCBuaMOibiIsDQogICAgZmlsbCA9ICJUcuG6oW5nIHRow6FpIGjhu5NpIHBo4bulYyINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFzdGVsMSIpDQpgYGANCg0KKipOaOG6rW4geMOpdCoqDQoNCkThu68gbGnhu4d1IGNobyB0aOG6pXkgc+G7sSBwaMOibiBi4buRIHRy4bqhbmcgdGjDoWkgaOG7k2kgcGjhu6VjIGdp4buvYSBoYWkgbmjDs20gYuG7h25oIG5ow6JuIHRoZW8gdMOsbmggdHLhuqFuZyB0acOqbSB24bqvYyB4aW4gbMOgIHTGsMahbmcgxJHhu5FpIMSR4buTbmcgxJHhu4F1LCB0dXkgbmhpw6puIHbhuqtuIGPDsyBt4buZdCBz4buRIGtow6FjIGJp4buHdCBuaOG6uS4gVHJvbmcgbmjDs20gY2jGsGEgdGnDqm0gduG6r2MgeGluLCB04bu3IGzhu4cgaOG7k2kgcGjhu6VjIGzDoCBraG/huqNuZyA1Mi4wNiUsIHRyb25nIGtoaSA0Ny45NCUga2jDtG5nIGjhu5NpIHBo4bulYy4gTmfGsOG7o2MgbOG6oWksIHRyb25nIG5ow7NtIMSRw6MgdGnDqm0gduG6r2MgeGluLCB04bu3IGzhu4cga2jDtG5nIGjhu5NpIHBo4bulYyBs4bqhaSBuaOG7iW5oIGjGoW4gbeG7mXQgY2jDunQsIOG7nyBt4bupYyA1MC4yMCUsIHNvIHbhu5tpIDQ5LjgwJSBo4buTaSBwaOG7pWMuIE3hurdjIGTDuSBz4buxIGNow6puaCBs4buHY2ggbMOgIGtow7RuZyBs4bubbiwgxJFp4buBdSBuw6B5IGfhu6NpIMO9IHLhurFuZyBuaMOzbSBjaMawYSB0acOqbSBjw7MgdOG7tyBs4buHIGjhu5NpIHBo4bulYyBjYW8gaMahbiBt4buZdCBjaMO6dCBzbyB24bubaSBuaMOzbSDEkcOjIHRpw6ptLiANCg0KIyMjICoqMi4xLjIuIEtp4buDbSDEkeG7i25oIFRo4buRbmcga8OqKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQotICoqSOKCgCoqOiBUw6xuaCB0cuG6oW5nIHBo4bulYyBo4buTaSB2w6AgdMOsbmggdHLhuqFuZyB0acOqbSB2YWNjaW4gbMOgIGhhaSBiaeG6v24gxJHhu5ljIGzhuq1wLg0KDQotICoqSOKCgSoqOiBUw6xuaCB0cuG6oW5nIHBo4bulYyBo4buTaSB2w6AgdMOsbmggdHLhuqFuZyB0acOqbSB2YWNjaW4gY8OzIGxpw6puIHF1YW4uDQpgYGB7cn0NCiMgVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBDaGkgYsOsbmggcGjGsMahbmcNCmNoaV9yZV92YWMgPC0gY2hpc3EudGVzdChyZV92YWMpDQpwcmludChjaGlfcmVfdmFjKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpIGLDrG5oIHBoxrDGoW5nOiBYwrIgPSAxLjQzOTQNCg0KLSBC4bqtYyB04buxIGRvIChkZikgPSAxDQoNCi0gcC12YWx1ZSA9ICAwLjIzMDINCg0KVuG7m2kgcC12YWx1ZSA9ICAwLjIzMDIgbOG7m24gaMahbiBt4bupYyDDvSBuZ2jEqWEgcGjhu5UgYmnhur9uIM6xID0gMC4wNSwga2jDtG5nIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AsIHRyb25nIG3huqt1IGThu68gbGnhu4d1IGhp4buHbiB04bqhaSwga2jDtG5nIGPDsyBz4buxIGtow6FjIGJp4buHdCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIGdp4buvYSB04bu3IGzhu4cgaOG7k2kgcGjhu6VjIGPhu6dhIG5ow7NtIMSRw6MgdGnDqm0gduG6r2MgeGluIHbDoCBuaMOzbSBjaMawYSB0acOqbS4gDQoNCiMjIyAqKjIuMS4zICBIaeG7h3UgdOG7tyBs4buHIChSaXNrIERpZmZlcmVuY2UgLSBSRCkqKg0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY2jDqW8gZ2nhu69hIFJlY292ZXJlZCB2w6AgVmFjY2luYXRpb25fU3RhdHVzDQpyZV92YWMgPC0gdGFibGUoZHQkUmVjb3ZlcmVkLCBkdCRWYWNjaW5hdGlvbl9TdGF0dXMpDQoNCiMgVGjDqm0gdOG7lW5nIGjDoG5nIHbDoCB04buVbmcgY+G7mXQNCnJlX3ZhYzEgPC0gYWRkbWFyZ2lucyhyZV92YWMpDQoNCiMgSGnhu4NuIHRo4buLIGLhuqNuZyB24bubaSBuaMOjbiByw7UgcsOgbmcNCnJlX3ZhYzENCmBgYA0KDQpcWw0KcF8xID0gUChcdGV4dHtSZWNvdmVyZWR9ID0gXHRleHR7WWVzfSBcbWlkIFx0ZXh0e1ZhY2NpbmF0aW9uX1N0YXR1c30gPSBcdGV4dHtDaMawYSB0acOqbX0pIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgaOG7k2kgcGjhu6VjIOG7nyBuaMOzbSBjaMawYSB0acOqbSl9DQpcXQ0KDQpcWw0KcF8yID0gUChcdGV4dHtSZWNvdmVyZWR9ID0gXHRleHR7WWVzfSBcbWlkIFx0ZXh0e1ZhY2NpbmF0aW9uX1N0YXR1c30gPSBcdGV4dHvEkMOjIHRpw6ptfSkgXHF1YWQgXHRleHR7KFThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIMSRw6MgdGnDqm0pfQ0KXF0NCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQpcWw0KSF8wOiBwXzEgLSBwXzIgPSAwIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgaOG7k2kgcGjhu6VjIOG7nyBuaMOzbSBjaMawYSB0acOqbSBi4bqxbmcgdOG7tyBs4buHIGjhu5NpIHBo4bulYyDhu58gbmjDs20gxJHDoyB0acOqbSl9DQpcXQ0KDQpcWw0KSF8xOiBwXzEgLSBwXzIgPCAwIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgaOG7k2kgcGjhu6VjIOG7nyBuaMOzbSBjaMawYSB0acOqbSBuaOG7jyBoxqFuIHThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIMSRw6MgdGnDqm0pfQ0KXF0NCg0KYGBge3J9DQojIFPhu5EgbmfGsOG7nWkgaOG7k2kgcGjhu6VjIHRyb25nIHThu6tuZyBuaMOzbSB0acOqbSBjaOG7p25nDQpjb3VudHMgPC0gYyhyZV92YWNbIkjhu5NpIHBo4bulYyIsICJDaMawYSB0acOqbSJdLCByZV92YWNbIkjhu5NpIHBo4bulYyIsICLEkMOjIHRpw6ptIl0pDQoNCiMgVOG7lW5nIHPhu5EgbmfGsOG7nWkgdHJvbmcgdOG7q25nIG5ow7NtIHRpw6ptIGNo4bunbmcNCnRvdGFscyA8LSBjKHN1bShyZV92YWNbLCAiQ2jGsGEgdGnDqm0iXSksIHN1bShyZV92YWNbLCAixJDDoyB0acOqbSJdKSkNCg0KIyBLaeG7g20gxJHhu4tuaCB04buJIGzhu4cgbeG7mXQgcGjDrWE6IHAxIDwgcDINCnRlc3RfcmVjb3ZlcnlfbGVzcyA8LSBwcm9wLnRlc3QoY291bnRzLCB0b3RhbHMsIGFsdGVybmF0aXZlID0gImxlc3MiLCBjb3JyZWN0ID0gRkFMU0UpDQp0ZXN0X3JlY292ZXJ5X2xlc3MNCmBgYA0KDQotIEvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIHThu7cgbOG7hyBoYWkgbeG6q3UgY2hvIHRo4bqleToNCg0KICAtIFThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIGNoxrBhIHRpw6ptIChwcm9wIDEpIGzDoCBraG/huqNuZyA1MS4zNyUNCg0KICAtIFThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIMSRw6MgdGnDqm0gKHByb3AgMikgbMOgIGtob+G6o25nIDQ5LjEyJQ0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpIGLDrG5oIHBoxrDGoW5nIGzDoCAxLjUyODQgduG7m2kgYuG6rWMgdOG7sSBkbyAxIHbDoCBwLXZhbHVlID0gMC44OTE4Lg0KDQotIFbDrCBwLXZhbHVlIGzhu5tuIGjGoW4gbeG7qWMgw70gbmdoxKlhIDAuMDUsIGNow7puZyB0YSBraMO0bmcgxJHhu6cgYuG6sW5nIGNo4bupbmcgxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IHLhurFuZyB04bu3IGzhu4cgaOG7k2kgcGjhu6VjIOG7nyBuaMOzbSBjaMawYSB0acOqbSB2w6AgbmjDs20gxJHDoyB0acOqbSBsw6AgYuG6sW5nIG5oYXUuDQoNCi0gTmdvw6BpIHJhLCBraG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyBoaeG7h3UgaGFpIHThu7cgbOG7hyBiYW8gZ+G7k20gZ2nDoSB0cuG7iyAwICh04burIC0xIMSR4bq/biAwLjA1MjYpLCBjxaluZyBj4bunbmcgY+G7kSBuaOG6rW4gxJHhu4tuaCBy4bqxbmcgc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIGhhaSB04bu3IGzhu4cga2jDtG5nIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCi0gVMOzbSBs4bqhaSwgdGhlbyBk4buvIGxp4buHdSBuw6B5LCB04bu3IGzhu4cgaOG7k2kgcGjhu6VjIGPhu6dhIG5ow7NtIGNoxrBhIHRpw6ptIHbDoCBuaMOzbSDEkcOjIHRpw6ptIGtow7RuZyBraMOhYyBiaeG7h3QgxJHDoW5nIGvhu4MgdsOgIGtow7RuZyBjw7MgYuG6sW5nIGNo4bupbmcgY2hvIHRo4bqleSBuaMOzbSBjaMawYSB0acOqbSBjw7MgdOG7tyBs4buHIGjhu5NpIHBo4bulYyB0aOG6pXAgaMahbiBuaMOzbSDEkcOjIHRpw6ptLg0KDQojIyMgKioyLjEuNC4gVOG7tyBz4buRIE5ndXkgY8ahIChSZWxhdGl2ZSBSaXNrIC0gUlIpOioqDQoNCmBgYHtyfQ0Kcmlza3JhdGlvKHJlX3ZhYywgbWV0aG9kPSJ3YWxkIikNCmBgYA0KDQotIFRhIHRo4bqleSBSUiA9IDAuOTU1LiDEkGnhu4F1IMSRw7MgY8OzIG5naMSpYSBsw6AgdOG7tyBs4buHIG5nxrDhu51pIMSRw6MgdGnDqm0gdHJvbmcgbmjDs20gaOG7k2kgcGjhu6VjIHRo4bqlcCBoxqFuIGtob+G6o25nIDQuNSUgc28gduG7m2kgdOG7tyBs4buHIG5nxrDhu51pIMSRw6MgdGnDqm0gdHJvbmcgbmjDs20ga2jDtG5nIGjhu5NpIHBo4bulYy4gQ8OzIHRo4buDIGhp4buDdSBy4bqxbmcgdmnhu4djIHRpw6ptIHbhuq9jLXhpbiBraMO0bmcgbMOgbSB0xINuZyBraOG6oyBuxINuZyBo4buTaSBwaOG7pWMgdHJvbmcgbeG6q3UgZOG7ryBsaeG7h3UgbsOgeS4NCg0KIyMjICoqMi4xLjUuIFThu7cgc+G7kSBDaMOqbmggKE9kZHMgUmF0aW8gLSBPUik6KioNCg0KYGBge3J9DQpvcl9yZXN1bHQxIDwtIG9kZHNyYXRpbyhyZV92YWMpDQpwcmludChvcl9yZXN1bHQxKQ0KYGBgDQoNCkdpw6EgdHLhu4sgb2RkcyByYXRpbyAoT1IpID0gMC45MTQgY2hvIHRo4bqleSBy4bqxbmcga2jhuqMgbsSDbmcgaOG7k2kgcGjhu6VjIOG7nyBuaMOzbSDEkcOjIHRpw6ptIHbhuq9jLXhpbiB0aOG6pXAgaMahbiBraG/huqNuZyA4LDYlIHNvIHbhu5tpIG5ow7NtIGtow7RuZyBo4buTaSBwaOG7pWMgdHJvbmcgY8O5bmcgxJFp4buBdSBraeG7h24gdGnDqm0gY2jhu6duZy4gTsOzaSBjw6FjaCBraMOhYywgdOG7tyBs4buHIG5nxrDhu51pIGjhu5NpIHBo4bulYyBuaOG7nSDEkcOjIHRpw6ptIHbhuq9jLXhpbiB0aOG6pXAgaMahbiBraG/huqNuZyA4LjYlIHNvIHbhu5tpIHThu7cgbOG7hyBuZ8aw4budaSBraMO0bmcgaOG7k2kgcGjhu6VjIGTDuSDEkcOjIHRpw6ptLg0KDQojIyAqKjIuMi4gUmVjb3ZlcmVkIHbDoCBTbW9raW5nX1N0YXR1cyoqDQoNCiMjIyAqKjIuMi4xLiBC4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0ICoqDQoNCioqQuG6o25nIHThuqduIHPhu5EqKg0KDQpgYGB7cn0NCg0KIyBHw6FuIG5ow6NuIGNobyBiaeG6v24gU21va2luZ19TdGF0dXMgKMSRw6MgY2h1eeG7g24gdGjDoG5oIFllcy9ObyB0csaw4bubYyDEkcOzKQ0KZHQkU21va2luZ19TdGF0dXMgPC0gZmFjdG9yKGR0JFNtb2tpbmdfU3RhdHVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk5vIiwgIlllcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIktow7RuZyBow7p0IHRodeG7kWMiLCAiQ8OzIGjDunQgdGh14buRYyIpKQ0KcmVfc21va2UgPC0gdGFibGUoZHQkUmVjb3ZlcmVkLCBkdCRTbW9raW5nX1N0YXR1cykNCnJlX3Ntb2tlMSA8LSBhZGRtYXJnaW5zKHJlX3Ntb2tlKQ0KcmVfc21va2UxIA0KYGBgDQoNCioqQuG6o25nIHThuqduIHN14bqldCoqDQpgYGB7cn0NCiMgVMOtbmggdOG7tyBs4buHIHRoZW8gaMOgbmcNCnJlX3Ntb2tlX3Byb3AgPC0gcHJvcC50YWJsZShyZV9zbW9rZSwgbWFyZ2luID0gMSkNCg0KIyBMw6BtIHRyw7JuIMSR4buDIGhp4buDbiB0aOG7iyDEkeG6uXANCnJlX3Ntb2tlX3Byb3Bfcm91bmRlZCA8LSByb3VuZChyZV9zbW9rZV9wcm9wLCA0KQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcNCnJlX3Ntb2tlX3Byb3Bfcm91bmRlZA0KYGBgDQoNCioqQmnhu4N1IMSR4buTKioNCmBgYHtyfQ0KIyBDaHV54buDbiBi4bqjbmcgc2FuZyBkYXRhIGZyYW1lDQpkZiA8LSBhcy5kYXRhLmZyYW1lKHJlX3Ntb2tlKQ0KY29sbmFtZXMoZGYpIDwtIGMoIlJlY292ZXJlZCIsICJTbW9raW5nX1N0YXR1cyIsICJDb3VudCIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgbmjDs20NCmdncGxvdChkZiwgYWVzKHggPSBSZWNvdmVyZWQsIHkgPSBDb3VudCwgZmlsbCA9IFNtb2tpbmdfU3RhdHVzKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiQmnhu4F1IMSR4buTIDIuIFBow6JuIGLhu5EgdHLhuqFuZyB0aMOhaSBow7p0IHRodeG7kWMgdGhlbyB0w6xuaCB0cuG6oW5nIGjhu5NpIHBo4bulYyIsDQogICAgICAgeCA9ICJUw6xuaCB0cuG6oW5nIGjhu5NpIHBo4bulYyIsDQogICAgICAgeSA9ICJT4buRIGzGsOG7o25nIiwNCiAgICAgICBmaWxsID0gIlTDrG5oIHRy4bqhbmcgaMO6dCB0aHXhu5FjIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKk5o4bqtbiB4w6l0KioNCg0KLSBUcm9uZyB04buVbmcgc+G7kSAzLjAwMCBi4buHbmggbmjDom4sIG5ow7NtIGtow7RuZyBo4buTaSBwaOG7pWMgY2hp4bq/bSAxLjQ5MiBuZ8aw4budaSwgdHJvbmcgxJHDsyBjw7MgNTE3IG5nxrDhu51pIGtow7RuZyBow7p0IHRodeG7kWMgKGNoaeG6v20gMzQsNjUlKSB2w6AgOTc1IG5nxrDhu51pIGPDsyBow7p0IHRodeG7kWMgKGNoaeG6v20gNjUsMzUlKS4gTmjDs20gaOG7k2kgcGjhu6VjIGNoaeG6v20gMS41MDggbmfGsOG7nWksIHRyb25nIMSRw7MgY8OzIDUwMiBuZ8aw4budaSBraMO0bmcgaMO6dCB0aHXhu5FjICgzMywyOSUpIHbDoCAxLjAwNiBuZ8aw4budaSBjw7MgaMO6dCB0aHXhu5FjICg2Niw3MSUpLg0KDQotIFF1YSBzbyBzw6FuaCwgdOG7tyBs4buHIG5nxrDhu51pIGPDsyBow7p0IHRodeG7kWMgdHJvbmcgbmjDs20gaOG7k2kgcGjhu6VjICg2Niw3MSUpIGNhbyBoxqFuIG3hu5l0IGNow7p0IHNvIHbhu5tpIG5ow7NtIGtow7RuZyBo4buTaSBwaOG7pWMgKDY1LDM1JSkuIE5nxrDhu6NjIGzhuqFpLCB04bu3IGzhu4cgbmfGsOG7nWkga2jDtG5nIGjDunQgdGh14buRYyDhu58gbmjDs20ga2jDtG5nIGjhu5NpIHBo4bulYyAoMzQsNjUlKSBjxaluZyBjYW8gaMahbiBuaOG6uSBzbyB24bubaSBuaMOzbSBo4buTaSBwaOG7pWMgKDMzLDI5JSkuIFPhu7EgY2jDqm5oIGzhu4djaCBnaeG7r2EgaGFpIG5ow7NtIGzDoCBraMOhIG5o4buPLCBjaOG7iSBkYW8gxJHhu5luZyBraG/huqNuZyAx4oCTMSw1JS4NCg0KIyMjICoqMi4yLjIuIEtp4buDbSDEkeG7i25oIFRo4buRbmcga8OqKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQotICoqSOKCgCoqOiBUw6xuaCB0cuG6oW5nIHBo4bulYyBo4buTaSB2w6Agdmnhu4djIGjDunQgdGh14buRYyBsw6AgaGFpIGJp4bq/biDEkeG7mWMgbOG6rXAuDQoNCi0gKipI4oKBKio6IFTDrG5oIHRy4bqhbmcgcGjhu6VjIGjhu5NpIHbDoCB2aeG7h2MgaMO6dCB0aHXhu5FjIGPDsyBsacOqbiBxdWFuLg0KDQpgYGB7cn0NCiMgS2nhu4NtIMSR4buLbmggQ2hpIGLDrG5oIHBoxrDGoW5nDQpjaGlfcmVfc21va2UgPC0gY2hpc3EudGVzdChyZV9zbW9rZSkNCnByaW50KGNoaV9yZV9zbW9rZSkNCmBgYA0KDQpL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaDoNCg0KLSBHacOhIHRy4buLIHRo4buRbmcga8OqIENoaSBiw6xuaCBwaMawxqFuZzogWMKyID0gMC41NjEzNA0KDQotIELhuq1jIHThu7EgZG8gKGRmKSA9IDENCg0KLSBwLXZhbHVlID0gIDAuNDUzNw0KDQpW4bubaSBwLXZhbHVlID0gIDAuNDUzNyBs4bubbiBoxqFuIG3hu6ljIMO9IG5naMSpYSBwaOG7lSBiaeG6v24gzrEgPSAwLjA1LCBraMO0bmcgxJHhu6cgYuG6sW5nIGNo4bupbmcgxJHhu4MgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEjigoAuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBUw6xuaCB0cuG6oW5nIHBo4bulYyBo4buTaSB2w6Agdmnhu4djIGjDunQgdGh14buRYyBsw6AgaGFpIGJp4bq/biDEkeG7mWMgbOG6rXAuDQoNCiMjIyAqKjIuMi4zICBIaeG7h3UgdOG7tyBs4buHIChSaXNrIERpZmZlcmVuY2UgLSBSRCkqKg0KDQpgYGB7cn0NCnJlX3Ntb2tlIDwtIHRhYmxlKGR0JFJlY292ZXJlZCwgZHQkU21va2luZ19TdGF0dXMpDQpyZV9zbW9rZTEgPC0gYWRkbWFyZ2lucyhyZV9zbW9rZSkNCnJlX3Ntb2tlMSANCmBgYA0KDQokJA0KcF8xID0gUChcdGV4dHtSZWNvdmVyZWR9ID0gXHRleHR7SOG7k2kgcGjhu6VjfSBcbWlkIFx0ZXh0e1Ntb2tpbmdcX1N0YXR1c30gPSBcdGV4dHtLaMO0bmcgaMO6dCB0aHXhu5FjfSkgDQpccXVhZCBcdGV4dHsoVOG7tyBs4buHIGjhu5NpIHBo4bulYyDhu58gbmjDs20ga2jDtG5nIGjDunQgdGh14buRYyl9DQokJA0KJCQNCnBfMiA9IFAoXHRleHR7UmVjb3ZlcmVkfSA9IFx0ZXh0e0jhu5NpIHBo4bulY30gXG1pZCBcdGV4dHtTbW9raW5nXF9TdGF0dXN9ID0gXHRleHR7Q8OzIGjDunQgdGh14buRY30pIA0KXHF1YWQgXHRleHR7KFThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIGPDsyBow7p0IHRodeG7kWMpfQ0KJCQNCg0KKipHaeG6oyB0aGnhur90IGtp4buDbSDEkeG7i25oKioNCg0KJCQNCkhfMDogcF8xIC0gcF8yID0gMCBccXVhZCBcdGV4dHsoVOG7tyBs4buHIGjhu5NpIHBo4bulYyDhu58gbmjDs20ga2jDtG5nIGjDunQgdGh14buRYyBi4bqxbmcgdOG7tyBs4buHIGjhu5NpIHBo4bulYyDhu58gbmjDs20gY8OzIGjDunQgdGh14buRYyl9DQokJA0KJCQNCkhfMTogcF8xIC0gcF8yIDwgMCBccXVhZCBcdGV4dHsoVOG7tyBs4buHIGjhu5NpIHBo4bulYyDhu58gbmjDs20ga2jDtG5nIGjDunQgdGh14buRYyBuaOG7jyBoxqFuIHThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIGPDsyBow7p0IHRodeG7kWMpfQ0KJCQNCg0KYGBge3J9DQojIFPhu5EgbmfGsOG7nWkgaOG7k2kgcGjhu6VjIHRyb25nIHThu6tuZyBuaMOzbSBow7p0IHRodeG7kWMNCmNvdW50cyA8LSBjKHJlX3Ntb2tlWyJI4buTaSBwaOG7pWMiLCAiS2jDtG5nIGjDunQgdGh14buRYyJdLA0KICAgICAgICAgICAgcmVfc21va2VbIkjhu5NpIHBo4bulYyIsICJDw7MgaMO6dCB0aHXhu5FjIl0pDQoNCiMgVOG7lW5nIHPhu5EgbmfGsOG7nWkgdHJvbmcgdOG7q25nIG5ow7NtIGjDunQgdGh14buRYw0KdG90YWxzIDwtIGMoc3VtKHJlX3Ntb2tlWywgIktow7RuZyBow7p0IHRodeG7kWMiXSksDQogICAgICAgICAgICBzdW0ocmVfc21va2VbLCAiQ8OzIGjDunQgdGh14buRYyJdKSkNCg0KIyBLaeG7g20gxJHhu4tuaCBt4buZdCBwaMOtYTogVOG7tyBs4buHIGjhu5NpIHBo4bulYyBuaMOzbSBraMO0bmcgaMO6dCB0aHXhu5FjIDwgbmjDs20gY8OzIGjDunQgdGh14buRYw0KdGVzdF9zbW9raW5nX2xlc3MgPC0gcHJvcC50ZXN0KGNvdW50cywgdG90YWxzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIiwgY29ycmVjdCA9IEZBTFNFKQ0KDQojIFhlbSBr4bq/dCBxdeG6ow0KcHJpbnQodGVzdF9zbW9raW5nX2xlc3MpDQpgYGANCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmggaGFpIHThu7cgbOG7hyBjaG8gdGjhuqV5Og0KDQotIFThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIGtow7RuZyBow7p0IHRodeG7kWMgKHByb3AgMSkgbMOgIDQ5LjI2JQ0KDQotIFThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIGPDsyBow7p0IHRodeG7kWMgKHByb3AgMikgbMOgIDUwLjc4JQ0KDQotIEdpw6EgdHLhu4sgcC12YWx1ZSA9IDAuMjE1NCwgbOG7m24gaMahbiBt4bupYyDDvSBuZ2jEqWEgdGjGsOG7nW5nIGTDuW5nICjOsSA9IDAuMDUpDQoNCktob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIGhp4buHdSBz4buRIHThu7cgbOG7hyBsw6AgdOG7qyDigJMxLjAwMCDEkeG6v24gMC4wMTY1LCBiYW8gZ+G7k20gZ2nDoSB0cuG7iyAwDQoNClbhu5tpIGdpw6EgdHLhu4sgcC12YWx1ZSA9IDAuMjE1NCA+IDAuMDUsIHRhICoqa2jDtG5nIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBcKCBIXzAgXCkqKi4gIE7Ds2kgY8OhY2gga2jDoWMsICoqa2jDtG5nIGPDsyDEkeG7pyBjxqEgc+G7nyB0aOG7kW5nIGvDqiDEkeG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nIHThu7cgbOG7hyBo4buTaSBwaOG7pWMg4bufIG5ow7NtIGtow7RuZyBow7p0IHRodeG7kWMgdGjhuqVwIGjGoW4gc28gduG7m2kgbmjDs20gY8OzIGjDunQgdGh14buRYyoqLiAgDQoNCiMjIyAqKjIuMi40LiBU4bu3IHPhu5EgTmd1eSBjxqEgKFJlbGF0aXZlIFJpc2sgLSBSUik6KioNCg0KYGBge3J9DQpyaXNrcmF0aW8ocmVfc21va2UsIG1ldGhvZD0id2FsZCIpDQpgYGANCg0KVGEgdGjhuqV5IFJSID0gMS4wMjEuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCB04bu3IGzhu4cgbmfGsOG7nWkgaMO6dCB0aHXhu5FjIHRyb25nIG5ow7NtIGjhu5NpIHBo4bulYyBjYW8gaMahbiBraG/huqNuZyAyLjElIHNvIHbhu5tpIHThu7cgbOG7hyBuZ8aw4budaSBraMO0bmcgaMO6dCB0aHXhu5FjIHRyb25nIG5ow7NtIGjhu5NpIHBo4bulYy4NCg0KIyMjICoqMi4yLjUuIFThu7cgc+G7kSBDaMOqbmggKE9kZHMgUmF0aW8gLSBPUik6KioNCg0KYGBge3J9DQpvcl9yZXN1bHQyIDwtIG9kZHNyYXRpbyhyZV9zbW9rZSkNCnByaW50KG9yX3Jlc3VsdDIpDQpgYGANCg0KVuG7m2kgT1IgPSAxLjA2MjYsIHThu7cgbOG7hyBuZ8aw4budaSBo4buTaSBwaOG7pWMgdHJvbmcgbmjDs20gaMO6dCB0aHXhu5FjIGNhbyBoxqFuIGtob+G6o25nIDYuMjYlIHNvIHbhu5tpIHThu7cgbOG7hyBuZ8aw4budaSBraMO0bmcgaOG7k2kgcGjhu6VjIHRyb25nIG5ow7NtIGjDunQgdGh14buRYy4NCg0KIyMgKioyLjMuIFJlaW5mZWN0aW9uIHbDoCBWYWNjaW5hdGlvbl9TdGF0dXMqKg0KDQojIyMgKioyLjMuMS4gQuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCAqKg0KDQoqKkLhuqNuZyB04bqnbiBz4buRKioNCmBgYHtyfQ0KZHQkUmVpbmZlY3Rpb24gPC0gZmFjdG9yKGR0JFJlaW5mZWN0aW9uLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJLaMO0bmcgdMOhaSBuaGnhu4VtIiwgIlTDoWkgbmhp4buFbSIpKQ0KDQojIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRIGNow6lvDQpyZWluX3ZhYyA8LSB0YWJsZShkdCRSZWluZmVjdGlvbiwgZHQkVmFjY2luYXRpb25fU3RhdHVzKQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgY+G7mXQNCnJlaW5fdmFjMSA8LSBhZGRtYXJnaW5zKHJlaW5fdmFjKQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcNCnJlaW5fdmFjMQ0KYGBgDQoNCioqQuG6o25nIHThuqduIHN14bqldCoqDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHN14bqldCB0aGVvIGjDoG5nIChyb3cgcGVyY2VudGFnZXMpDQpyZWluX3ZhY19wcm9wIDwtIHByb3AudGFibGUocmVpbl92YWMsIG1hcmdpbiA9IDEpDQoNCiMgTMOgbSB0csOybiA0IGNo4buvIHPhu5EgdGjhuq1wIHBow6JuDQpyZWluX3ZhY19wcm9wIDwtIHJvdW5kKHJlaW5fdmFjX3Byb3AsIDQpDQoNCiMgSGnhu4NuIHRo4buLIGLhuqNuZyB04bqnbiBzdeG6pXQNCnJlaW5fdmFjX3Byb3ANCmBgYA0KDQoqKkJp4buDdSDEkeG7kyoqDQpgYGB7cn0NCiMgQ2h1eeG7g24gdGjDoG5oIGRhdGEgZnJhbWUNCnJlaW5fdmFjX2RmIDwtIGFzLmRhdGEuZnJhbWUocmVpbl92YWMpDQoNCiMgxJDhu5VpIHTDqm4gY+G7mXQgY2hvIGThu4UgaGnhu4N1DQpjb2xuYW1lcyhyZWluX3ZhY19kZikgPC0gYygiUmVpbmZlY3Rpb24iLCAiVmFjY2luYXRpb25fU3RhdHVzIiwgIkNvdW50IikNCg0KIyBW4bq9IGJp4buDdSDEkeG7kw0KZ2dwbG90KHJlaW5fdmFjX2RmLCBhZXMoeCA9IFZhY2NpbmF0aW9uX1N0YXR1cywgeSA9IENvdW50LCBmaWxsID0gUmVpbmZlY3Rpb24pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgMy4gVMOsbmggdHLhuqFuZyB0w6FpIG5oaeG7hW0gdGhlbyB0w6xuaCB0cuG6oW5nIHRpw6ptIHbhuq9jIHhpbiIsDQogICAgeCA9ICJUw6xuaCB0cuG6oW5nIHRpw6ptIHbhuq9jIHhpbiIsDQogICAgeSA9ICJT4buRIGzGsOG7o25nIGLhu4duaCBuaMOibiIsDQogICAgZmlsbCA9ICJUw6xuaCB0cuG6oW5nIHTDoWkgbmhp4buFbSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpDQpgYGANCg0KKipOaOG6rW4geMOpdCoqDQoNCkThu7FhIHRyw6puIGLhuqNuZyB04bqnbiBzdeG6pXQsIHRhIHRo4bqleSBy4bqxbmcgdHJvbmcgbmjDs20ga2jDtG5nIHTDoWkgbmhp4buFbSwgdOG7tyBs4buHIGLhu4duaCBuaMOibiBjaMawYSB0acOqbSB24bqvYyB4aW4gY2hp4bq/bSBraG/huqNuZyA1MS40OSUsIGNhbyBoxqFuIHNvIHbhu5tpIG5ow7NtIMSRw6MgdGnDqm0gbMOgIDQ4LjUxJSwgduG7m2kgbeG7qWMgY2jDqm5oIGzhu4djaCBsw6AgMi45OCUuIE5nxrDhu6NjIGzhuqFpLCDhu58gbmjDs20gdMOhaSBuaGnhu4VtLCB04bu3IGzhu4cgYuG7h25oIG5ow6JuIMSRw6MgdGnDqm0gduG6r2MgeGluIGzhuqFpIGNhbyBoxqFuLCDEkeG6oXQgNTQuMzklLCBzbyB24bubaSA0NS42MSUg4bufIG5ow7NtIGNoxrBhIHRpw6ptLCB04bupYyBsw6AgY2jDqm5oIGzhu4djaCBraG/huqNuZyA4Ljc4JS4NCg0KTmjhu69uZyBjb24gc+G7kSBuw6B5IGNobyB0aOG6pXkgcuG6sW5nIHRyb25nIG3huqt1IGThu68gbGnhu4d1IG7DoHksIHThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIMSRw6MgdGnDqm0gY8OzIHh1IGjGsOG7m25nIGNhbyBoxqFuIHNvIHbhu5tpIG5ow7NtIGNoxrBhIHRpw6ptLiANCg0KIyMjICoqMi4zLjIuIEtp4buDbSDEkeG7i25oIFRo4buRbmcga8OqKioNCg0KKipHaeG6oyB0aHV54bq/dCBraeG7g20gxJHhu4tuaDoqKg0KDQotICoqSOKCgCoqOiBUw6xuaCB0cuG6oW5nIHTDoWkgbmhp4buFbSB2w6AgdMOsbmggdHLhuqFuZyB0acOqbSB2YWNjaW4gbMOgIGhhaSBiaeG6v24gxJHhu5ljIGzhuq1wLg0KDQotICoqSOKCgSoqOiBUw6xuaCB0cuG6oW5nIHTDoWkgbmhp4buFbSB2w6AgdMOsbmggdHLhuqFuZyB0acOqbSB2YWNjaW4gY8OzIGxpw6puIHF1YW4uDQoNCmBgYHtyfQ0KIyBUaOG7sWMgaGnhu4duIGtp4buDbSDEkeG7i25oIENoaSBiw6xuaCBwaMawxqFuZw0KY2hpX3JlaW5fdmFjIDwtIGNoaXNxLnRlc3QocmVpbl92YWMpDQpwcmludChjaGlfcmVpbl92YWMpDQpgYGANCg0KS+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmg6DQoNCi0gR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiBDaGkgYsOsbmggcGjGsMahbmc6IFjCsiA9IDMuMzM0Mg0KDQotIELhuq1jIHThu7EgZG8gKGRmKSA9IDENCg0KLSBwLXZhbHVlID0gIDAuMDY3ODYNCg0KVuG7m2kgbeG7qWMgw70gbmdoxKlhIHRoxrDhu51uZyBkw7luZyBsw6AgzrEgPSAwLjA1LCB0YSB0aOG6pXkgcC12YWx1ZSA9IDAuMDY3ODYgPiAwLjA1LCB04bupYyBsw6Aga2jDtG5nIMSR4bunIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALiBOw7NpIGPDoWNoIGtow6FjLCBjaMawYSB0aOG7gyBr4bq/dCBsdeG6rW4gcuG6sW5nIHTDrG5oIHRy4bqhbmcgdMOhaSBuaGnhu4VtIHbDoCB0w6xuaCB0cuG6oW5nIHRpw6ptIHbhuq9jIHhpbiBjw7MgbeG7kWkgbGnDqm4gaOG7hyByw7UgcsOgbmcgdHJvbmcgbeG6q3UgZOG7ryBsaeG7h3UgbsOgeS4NCg0KIyMjICoqMi4zLjMgIEhp4buHdSB04bu3IGzhu4cgKFJpc2sgRGlmZmVyZW5jZSAtIFJEKSoqDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY2jDqW8NCnJlaW5fdmFjIDwtIHRhYmxlKGR0JFJlaW5mZWN0aW9uLCBkdCRWYWNjaW5hdGlvbl9TdGF0dXMpDQoNCiMgVGjDqm0gdOG7lW5nIGjDoG5nIHbDoCBj4buZdA0KcmVpbl92YWMxIDwtIGFkZG1hcmdpbnMocmVpbl92YWMpDQoNCiMgSGnhu4NuIHRo4buLIGLhuqNuZw0KcmVpbl92YWMxDQpgYGANCg0KXFsNCnBfMSA9IFAoXHRleHR7UmVpbmZlY3Rpb259ID0gXHRleHR7WWVzfSBcbWlkIFx0ZXh0e1ZhY2NpbmF0aW9uX1N0YXR1c30gPSBcdGV4dHtDaMawYSB0acOqbX0pIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSBjaMawYSB0acOqbSl9DQpcXQ0KDQpcWw0KcF8yID0gUChcdGV4dHtSZWluZmVjdGlvbn0gPSBcdGV4dHtZZXN9IFxtaWQgXHRleHR7VmFjY2luYXRpb25fU3RhdHVzfSA9IFx0ZXh0e8SQw6MgdGnDqm19KSBccXVhZCBcdGV4dHsoVOG7tyBs4buHIHTDoWkgbmhp4buFbSDhu58gbmjDs20gxJHDoyB0acOqbSl9DQpcXQ0KDQoqKkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oOioqDQoNClxbDQpIXzA6IHBfMSAtIHBfMiA9IDAgXHF1YWQgXHRleHR7KFThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIGNoxrBhIHRpw6ptIGLhurFuZyB04bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSDEkcOjIHRpw6ptKX0NClxdDQoNClxbDQpIXzE6IHBfMSAtIHBfMiA8IDAgXHF1YWQgXHRleHR7KFThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIGNoxrBhIHRpw6ptIG5o4buPIGjGoW4gdOG7tyBs4buHIHTDoWkgbmhp4buFbSDhu58gbmjDs20gxJHDoyB0acOqbSl9DQpcXQ0KYGBge3J9DQojIFPhu5EgbmfGsOG7nWkgdMOhaSBuaGnhu4VtIHRyb25nIHThu6tuZyBuaMOzbSB0acOqbSBjaOG7p25nDQpjb3VudHNfcmVpbmZlY3Rpb24gPC0gYyhyZWluX3ZhY1siVMOhaSBuaGnhu4VtIiwgIkNoxrBhIHRpw6ptIl0sIHJlaW5fdmFjWyJUw6FpIG5oaeG7hW0iLCAixJDDoyB0acOqbSJdKQ0KDQojIFThu5VuZyBz4buRIG5nxrDhu51pIHRyb25nIHThu6tuZyBuaMOzbSB0acOqbSBjaOG7p25nDQp0b3RhbHNfcmVpbmZlY3Rpb24gPC0gYyhzdW0ocmVpbl92YWNbLCAiQ2jGsGEgdGnDqm0iXSksIHN1bShyZWluX3ZhY1ssICLEkMOjIHRpw6ptIl0pKQ0KDQojIEtp4buDbSDEkeG7i25oIHThu4kgbOG7hyBt4buZdCBwaMOtYTogcDEgPCBwMiAodOG7tyBs4buHIHTDoWkgbmhp4buFbSDhu58gbmjDs20gY2jGsGEgdGnDqm0gbmjhu48gaMahbiBuaMOzbSDEkcOjIHRpw6ptKQ0KdGVzdF9yZWluZmVjdGlvbl9sZXNzIDwtIHByb3AudGVzdChjb3VudHNfcmVpbmZlY3Rpb24sIHRvdGFsc19yZWluZmVjdGlvbiwgYWx0ZXJuYXRpdmUgPSAibGVzcyIsIGNvcnJlY3QgPSBGQUxTRSkNCg0KIyBIaeG7g24gdGjhu4sga+G6v3QgcXXhuqMga2nhu4NtIMSR4buLbmgNCnRlc3RfcmVpbmZlY3Rpb25fbGVzcw0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oIGNobyB0aOG6pXk6DQoNCi0gVOG7tyBs4buHIHTDoWkgbmhp4buFbSDhu58gbmjDs20gY2jGsGEgdGnDqm0gKHByb3AgMSkgbMOgIGtob+G6o25nIDguNTElLg0KDQotIFThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIMSRw6MgdGnDqm0gKHByb3AgMikgbMOgIGtob+G6o25nIDEwLjUzJS4NCg0KVuG7m2kgcC12YWx1ZSA9IDAuMDI5NSwgbmjhu48gaMahbiBt4bupYyDDvSBuZ2jEqWEgMC4wNSwgY2jDum5nIHRhIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIFThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIGNoxrBhIHRpw6ptIG5o4buPIGjGoW4gdOG7tyBs4buHIHTDoWkgbmhp4buFbSDhu58gbmjDs20gxJHDoyB0acOqbS4NCg0KIyMjICoqMi4zLjQuIFThu7cgc+G7kSBOZ3V5IGPGoSAoUmVsYXRpdmUgUmlzayAtIFJSKToqKg0KYGBge3J9DQpyaXNrcmF0aW8ocmVpbl92YWMsIG1ldGhvZD0id2FsZCIpDQpgYGANCg0KR2nDoSB0cuG7iyBSUiA9IDEuMTIxIGNobyB0aOG6pXkgcuG6sW5nIHThu7cgbOG7hyBuZ8aw4budaSDEkcOjIHRpw6ptIHbhuq9jIHhpbiB0cm9uZyBuaMOzbSBi4buLIHTDoWkgbmhp4buFbSBjYW8gaMahbiBraG/huqNuZyAxMi4xJSBzbyB24bubaSBuaMOzbSBraMO0bmcgYuG7iyB0w6FpIG5oaeG7hW0uDQoNCiMjIyAqKjIuMy41LiBU4bu3IHPhu5EgQ2jDqm5oIChPZGRzIFJhdGlvIC0gT1IpOioqDQoNCmBgYHtyfQ0Kb3JfcmVzdWx0MyA8LSBvZGRzcmF0aW8ocmVpbl92YWMpDQpwcmludChvcl9yZXN1bHQzKQ0KYGBgDQoNCkdpw6EgdHLhu4sgT1IgPSAxLjI2NSBjaG8gdGjhuqV5IHLhurFuZyBraOG6oyBuxINuZyDEkcOjIHRpw6ptIHbhuq9jIHhpbiB0cm9uZyBuaMOzbSB0w6FpIG5oaeG7hW0gY2FvIGjGoW4ga2hv4bqjbmcgMjYuNSUgc28gduG7m2kgbmjDs20ga2jDtG5nIHTDoWkgbmhp4buFbS4gTsOzaSBjw6FjaCBraMOhYywgdOG7tyBs4buHIMSRw6MgdGnDqm0gc28gduG7m2kgY2jGsGEgdGnDqm0g4bufIG5ow7NtIHTDoWkgbmhp4buFbSBs4bubbiBoxqFuIHNvIHbhu5tpIG5ow7NtIGtow7RuZyB0w6FpIG5oaeG7hW0uDQoNClThu7cgc+G7kSBvZGRzIChPUikgbMOgIDEuMjY1LCBuZ2jEqWEgbMOgIG9kZHMgxJHDoyB0acOqbSBzbyB24bubaSBjaMawYSB0acOqbSB0cm9uZyBuaMOzbSB0w6FpIG5oaeG7hW0gY2FvIGjGoW4ga2hv4bqjbmcgMjYuNSUgc28gduG7m2kgbmjDs20ga2jDtG5nIHTDoWkgbmhp4buFbS4NCg0KIyMgKioyLjQuIFJlaW5mZWN0aW9uIHbDoCBTbW9raW5nX1N0YXR1cyoqDQoNCiMjIyAqKjIuNC4xLiBC4bqjbmcgdOG6p24gc+G7kSB2w6AgdOG6p24gc3XhuqV0ICoqDQoNCioqQuG6o25nIHThuqduIHPhu5EqKg0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY2jDqW8NCnJlaW5fc21va2UgPC0gdGFibGUoZHQkUmVpbmZlY3Rpb24sIGR0JFNtb2tpbmdfU3RhdHVzKQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgY+G7mXQNCnJlaW5fc21va2UxIDwtIGFkZG1hcmdpbnMocmVpbl9zbW9rZSkNCg0KIyBIaeG7g24gdGjhu4sgYuG6o25nDQpyZWluX3Ntb2tlMQ0KYGBgDQoNCioqQuG6o25nIHThuqduIHN14bqldCoqDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHN14bqldCB0aGVvIGjDoG5nIChyb3cgcGVyY2VudGFnZXMpDQpyZWluX3Ntb2tlX3Byb3AgPC0gcHJvcC50YWJsZShyZWluX3Ntb2tlLCBtYXJnaW4gPSAxKQ0KDQojIEzDoG0gdHLDsm4gNCBjaOG7ryBz4buRIHRo4bqtcCBwaMOibg0KcmVpbl9zbW9rZV9wcm9wIDwtIHJvdW5kKHJlaW5fc21va2VfcHJvcCwgNCkNCg0KIyBIaeG7g24gdGjhu4sgYuG6o25nIHThuqduIHN14bqldA0KcmVpbl9zbW9rZV9wcm9wDQpgYGANCg0KKipCaeG7g3UgxJHhu5MqKg0KYGBge3J9DQojIENodXnhu4NuIHRow6BuaCBkYXRhIGZyYW1lDQpyZWluX3Ntb2tlX2RmIDwtIGFzLmRhdGEuZnJhbWUocmVpbl9zbW9rZSkNCg0KIyDEkOG7lWkgdMOqbiBj4buZdCBjaG8gZOG7hSBoaeG7g3UNCmNvbG5hbWVzKHJlaW5fc21va2VfZGYgKSA8LSBjKCJSZWluZmVjdGlvbiIsICJTbW9raW5nX1N0YXR1cyIsICJDb3VudCIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MNCmdncGxvdChyZWluX3Ntb2tlX2RmLCBhZXMoeCA9IFNtb2tpbmdfU3RhdHVzLCB5ID0gQ291bnQsIGZpbGwgPSBSZWluZmVjdGlvbikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkJp4buDdSDEkeG7kyA0LiBUw6xuaCB0cuG6oW5nIHTDoWkgbmhp4buFbSB0aGVvIHTDrG5oIHRy4bqhbmcgaMO6dCB0aHXhu5FjIiwNCiAgICB4ID0gIlTDrG5oIHRy4bqhbmcgaMO6dCB0aHXhu5FjIiwNCiAgICB5ID0gIlPhu5EgbMaw4bujbmcgYuG7h25oIG5ow6JuIiwNCiAgICBmaWxsID0gIlTDrG5oIHRy4bqhbmcgdMOhaSBuaGnhu4VtIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikNCmBgYA0KDQpE4buxYSB0csOqbiBz4buRIGxp4buHdSBraOG6o28gc8OhdCB04burIDMuMDAwIG5nxrDhu51pLCB0cm9uZyDEkcOzIGPDsyAyLjcxNSBuZ8aw4budaSBraMO0bmcgdMOhaSBuaGnhu4VtIHbDoCAyODUgbmfGsOG7nWkgYuG7iyB0w6FpIG5oaeG7hW0sIGNow7puZyB0YSBjw7MgdGjhu4MgeGVtIHjDqXQgbeG7kWkgbGnDqm4gcXVhbiBnaeG7r2EgdMOsbmggdHLhuqFuZyBow7p0IHRodeG7kWMgdsOgIG5ndXkgY8ahIHTDoWkgbmhp4buFbS4NCg0K4bueIG5ow7NtIGtow7RuZyB0w6FpIG5oaeG7hW0sIHThu7cgbOG7hyBuZ8aw4budaSBjw7MgaMO6dCB0aHXhu5FjIGzDoCA2Ni4xMSUsIHRyb25nIGtoaSB04bu3IGzhu4cga2jDtG5nIGjDunQgdGh14buRYyBsw6AgMzMuODklLiBUcm9uZyBraGkgxJHDsywg4bufIG5ow7NtIHTDoWkgbmhp4buFbSwgdOG7tyBs4buHIG5nxrDhu51pIGPDsyBow7p0IHRodeG7kWMgbMOgIDY1LjI2JSwgdsOgIHThu7cgbOG7hyBraMO0bmcgaMO6dCB0aHXhu5FjIGzDoCAzNC43NCUuIEPDoWMgdOG7tyBs4buHIG7DoHkgY2hvIHRo4bqleSBz4buxIHBow6JuIGLhu5EgZ2nhu69hIG5nxrDhu51pIGjDunQgdGh14buRYyB2w6Aga2jDtG5nIGjDunQgdGh14buRYyB0cm9uZyBoYWkgbmjDs20gbMOgIGtow6EgdMawxqFuZyDEkeG7k25nLg0KDQojIyMgKioyLjQuMi4gS2nhu4NtIMSR4buLbmggVGjhu5FuZyBrw6oqKg0KDQoqKkdp4bqjIHRodXnhur90IGtp4buDbSDEkeG7i25oOioqDQoNCi0gKipI4oKAKio6IFTDrG5oIHRy4bqhbmcgdMOhaSBuaGnhu4VtIHbDoCB0w6xuaCB0cuG6oW5nIGjDunQgdGh14buRYyBsw6AgaGFpIGJp4bq/biDEkeG7mWMgbOG6rXAuDQoNCi0gKipI4oKBKio6IFTDrG5oIHRy4bqhbmcgdMOhaSBuaGnhu4VtIHbDoCB0w6xuaCB0cuG6oW5nIGjDunQgdGh14buRYyBjw7MgbGnDqm4gcXVhbi4NCg0KYGBge3J9DQojIFRo4buxYyBoaeG7h24ga2nhu4NtIMSR4buLbmggQ2hpIGLDrG5oIHBoxrDGoW5nDQpjaGlfcmVpbl9zbW9rZTwtIGNoaXNxLnRlc3QocmVpbl9zbW9rZSkNCnByaW50KGNoaV9yZWluX3Ntb2tlKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpIGLDrG5oIHBoxrDGoW5nOiBYwrIgPSAwLjA0OTY2Mw0KDQotIELhuq1jIHThu7EgZG8gKGRmKSA9IDENCg0KLSBwLXZhbHVlID0gIDAuODIzNw0KDQpW4bubaSBt4bupYyDDvSBuZ2jEqWEgdGjGsOG7nW5nIGTDuW5nIGzDoCDOsSA9IDAuMDUsIHRhIHRo4bqleSBwLXZhbHVlID0gMC44MjM3ID4gMC4wNSwgdOG7qWMgbMOgIGtow7RuZyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgC4gTsOzaSBjw6FjaCBraMOhYywgY2jGsGEgdGjhu4Mga+G6v3QgbHXhuq1uIHLhurFuZyB0w6xuaCB0cuG6oW5nIHTDoWkgbmhp4buFbSB2w6AgdMOsbmggdHLhuqFuZyBow7p0IHRodeG7kWMgY8OzIG3hu5FpIGxpw6puIGjhu4cgcsO1IHLDoG5nIHRyb25nIG3huqt1IGThu68gbGnhu4d1IG7DoHkuDQoNCiMjIyAqKjIuNC4zICBIaeG7h3UgdOG7tyBs4buHIChSaXNrIERpZmZlcmVuY2UgLSBSRCkqKg0KDQpgYGB7cn0NCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY2jDqW8NCnJlaW5fc21va2UgPC0gdGFibGUoZHQkUmVpbmZlY3Rpb24sIGR0JFNtb2tpbmdfU3RhdHVzKQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgY+G7mXQNCnJlaW5fc21va2UxIDwtIGFkZG1hcmdpbnMocmVpbl9zbW9rZSkNCg0KIyBIaeG7g24gdGjhu4sgYuG6o25nDQpyZWluX3Ntb2tlMQ0KYGBgDQoNCiQkDQpwXzEgPSBQKFx0ZXh0e1JlaW5mZWN0aW9ufSA9IFx0ZXh0e1llc30gXG1pZCBcdGV4dHtTbW9raW5nXF9TdGF0dXN9ID0gXHRleHR7S2jDtG5nIGjDunQgdGh14buRY30pIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSBraMO0bmcgaMO6dCB0aHXhu5FjKX0NCiQkDQoNCiQkDQpwXzIgPSBQKFx0ZXh0e1JlaW5mZWN0aW9ufSA9IFx0ZXh0e1llc30gXG1pZCBcdGV4dHtTbW9raW5nXF9TdGF0dXN9ID0gXHRleHR7Q8OzIGjDunQgdGh14buRY30pIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSBjw7MgaMO6dCB0aHXhu5FjKX0NCiQkDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmgqKg0KDQokJA0KSF8wOiBwXzEgLSBwXzIgPSAwIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSBraMO0bmcgaMO6dCB0aHXhu5FjIGLhurFuZyB04bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSBjw7MgaMO6dCB0aHXhu5FjKX0NCiQkDQoNCiQkDQpIXzE6IHBfMSAtIHBfMiA+IDAgXHF1YWQgXHRleHR7KFThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIGtow7RuZyBow7p0IHRodeG7kWMgbOG7m24gaMahbiB04bu3IGzhu4cgdMOhaSBuaGnhu4VtIOG7nyBuaMOzbSBjw7MgaMO6dCB0aHXhu5FjKX0NCiQkDQoNCmBgYHtyfQ0KIyBT4buRIG5nxrDhu51pIHTDoWkgbmhp4buFbSB0cm9uZyB04burbmcgbmjDs20gaMO6dCB0aHXhu5FjDQpjb3VudHNfc21va2luZyA8LSBjKHJlaW5fc21va2VbIlTDoWkgbmhp4buFbSIsICJLaMO0bmcgaMO6dCB0aHXhu5FjIl0sDQogICAgICAgICAgICAgICAgICAgIHJlaW5fc21va2VbIlTDoWkgbmhp4buFbSIsICJDw7MgaMO6dCB0aHXhu5FjIl0pDQoNCiMgVOG7lW5nIHPhu5EgbmfGsOG7nWkgdHJvbmcgdOG7q25nIG5ow7NtIGjDunQgdGh14buRYw0KdG90YWxzX3Ntb2tpbmcgPC0gYyhzdW0ocmVpbl9zbW9rZVssICJLaMO0bmcgaMO6dCB0aHXhu5FjIl0pLA0KICAgICAgICAgICAgICAgICAgICBzdW0ocmVpbl9zbW9rZVssICJDw7MgaMO6dCB0aHXhu5FjIl0pKQ0KDQojIEtp4buDbSDEkeG7i25oIHThu4kgbOG7hyBt4buZdCBwaMOtYTogcDEgPiBwMiAodOG7tyBs4buHIHTDoWkgbmhp4buFbSDhu58gbmjDs20ga2jDtG5nIGjDunQgdGh14buRYyBs4bubbiBoxqFuIG5ow7NtIGPDsyBow7p0IHRodeG7kWMpDQp0ZXN0X3Ntb2tpbmdfZ3JlYXRlciA8LSBwcm9wLnRlc3QoY291bnRzX3Ntb2tpbmcsIHRvdGFsc19zbW9raW5nLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIiwgY29ycmVjdCA9IEZBTFNFKQ0KDQojIEhp4buDbiB0aOG7iyBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaA0KdGVzdF9zbW9raW5nX2dyZWF0ZXINCmBgYA0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6oga2nhu4NtIMSR4buLbmggKENoaS1zcXVhcmVkKTogMC4wODMgIA0KLSBHacOhIHRy4buLIHAtdmFsdWU6IDAuMzg2NCAgDQoNClbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JSAoJFxhbHBoYSA9IDAuMDUkKSwgdGEgY8OzOiAgDQokJA0KXHRleHR7cC12YWx1ZX0gPSAwLjM4NjQgPiAwLjA1DQokJCAgDQrih5IgKipLaMO0bmcgY8OzIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBraMO0bmcqKi4NCg0KKipL4bq/dCBsdeG6rW4qKjogS2jDtG5nIGPDsyDEkeG7pyBi4bqxbmcgY2jhu6luZyB0aOG7kW5nIGvDqiDEkeG7gyBraOG6s25nIMSR4buLbmggcuG6sW5nIHThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIGtow7RuZyBow7p0IHRodeG7kWMgbOG7m24gaMahbiBuaMOzbSBjw7MgaMO6dCB0aHXhu5FjLg0KDQojIyMgKioyLjQuNC4gVOG7tyBz4buRIE5ndXkgY8ahIChSZWxhdGl2ZSBSaXNrIC0gUlIpOioqDQoNCmBgYHtyfQ0Kcmlza3JhdGlvKHJlaW5fc21va2UsIG1ldGhvZD0id2FsZCIpDQpgYGANCg0KVuG7m2kgUlIgPSAwLjk4NywgdGEgbmjhuq1uIHRo4bqleSBy4bqxbmcgdOG7tyBs4buHIG5nxrDhu51pIGjDunQgdGh14buRYyDhu58gbmjDs20gdMOhaSBuaGnhu4VtIHRo4bqlcCBoxqFuIGtob+G6o25nIDEuMyUgc28gduG7m2kgbmjDs20ga2jDtG5nIHTDoWkgbmhp4buFbS4NCg0KIyMjICoqMi40LjUuIFThu7cgc+G7kSBDaMOqbmggKE9kZHMgUmF0aW8gLSBPUik6KioNCg0KYGBge3J9DQpvcl9yZXN1bHQ0IDwtIG9kZHNyYXRpbyhyZWluX3Ntb2tlKQ0KcHJpbnQob3JfcmVzdWx0NCkNCmBgYA0KDQpL4bq/dCBxdeG6oyBwaMOibiB0w61jaCBjaG8gdGjhuqV5IE9kZHMgUmF0aW8gKE9SKSA9IDAuOTYyLCBuZ2jEqWEgbMOgIHThu7cgbOG7hyBuZ8aw4budaSB0w6FpIG5oaeG7hW0gdHJvbmcgbmjDs20gaMO6dCB0aHXhu5FjIHRo4bqlcCBoxqFuIGtob+G6o25nIDMuOCUgc28gduG7m2kgdOG7tyBs4buHIG5nxrDhu51pIGtow7RuZyB0w6FpIG5oaeG7hW0uDQoNCiMgKipQaOG6p24gMy4gVOG7lE5HIEvhur5UIFbDgCBUSOG6ok8gTFXhuqxOKioNCg0KUXVhIHF1w6EgdHLDrG5oIHTDrG0gaGnhu4N1LCBtw7QgdOG6oyB2w6Aga2nhu4NtIMSR4buLbmggdGjhu5FuZyBrw6ogdHLDqm4gYuG7mSBk4buvIGxp4buHdSBtw7QgcGjhu49uZyBi4buHbmggbmjDom4gQ09WSUQtMTksIGLDoW8gY8OhbyBuw6B5IMSRw6MgcGjDoWMgaOG7jWEgbsOqbiBt4buZdCBi4bupYyB0cmFuaCB0b8OgbiBj4bqjbmggduG7gSDEkeG6t2MgxJFp4buDbSBk4buLY2ggdOG7hSB2w6AgbMOibSBzw6BuZywgxJHhu5NuZyB0aOG7nWkga2jDoW0gcGjDoSBuaOG7r25nIG3hu5FpIGxpw6puIGjhu4cgYmFuIMSR4bqndSBnaeG7r2EgY8OhYyB54bq/dSB04buRIG5ndXkgY8ahIHbDoCBr4bq/dCBxdeG6oyDEkWnhu4F1IHRy4buLLiBDw6FjIGvhur90IHF14bqjIGtow7RuZyBjaOG7iSBjdW5nIGPhuqVwIG5o4buvbmcgY29uIHPhu5EgY+G7pSB0aOG7gyBtw6AgY8OybiBt4bufIHJhIG5oaeG7gXUgaMaw4bubbmcgdGjhuqNvIGx14bqtbiBxdWFuIHRy4buNbmcuDQoNCiMjICoqMy4xLiBU4buVbmcga+G6v3QgY8OhYyBr4bq/dCBxdeG6oyBu4buVaSBi4bqtdCoqDQoNCi0gVGjhu6kgbmjhuqV0LCBraMO0bmcgY8OzIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIGNobyB0aOG6pXkgKip0acOqbSB24bqvYyB4aW4gY8OzIGxpw6puIHF1YW4gxJHhur9uIGto4bqjIG7Eg25nIGjhu5NpIHBo4bulYyBzYXUgbmhp4buFbSBDT1ZJRC0xOSoqLiBEw7kgdOG7tyBs4buHIGjhu5NpIHBo4bulYyDhu58gbmjDs20gY2jGsGEgdGnDqm0gbmjhu4luaCBoxqFuIG3hu5l0IGNow7p0IHNvIHbhu5tpIG5ow7NtIMSRw6MgdGnDqm0sIGPDoWMga2nhu4NtIMSR4buLbmggdGjhu5FuZyBrw6ogxJHhu4F1IGtow7RuZyBwaMOhdCBoaeG7h24gc+G7sSBraMOhYyBiaeG7h3QgY8OzIMO9IG5naMSpYS4gQ8OhYyBjaOG7iSBz4buRIG5oxrAgKlJpc2sgUmF0aW8qIHbDoCAqT2RkcyBSYXRpbyogxJHhu4F1IGNobyB0aOG6pXkgbeG7qWMgxJHhu5kgdMawxqFuZyDEkcawxqFuZyBnaeG7r2EgaGFpIG5ow7NtLiDEkGnhu4F1IG7DoHkgY2hvIHRo4bqleSBy4bqxbmcgdmnhu4djIHRpw6ptIHbhuq9jIHhpbiBraMO0bmcgdGjhu4MgaGnhu4duIHTDoWMgxJHhu5luZyByw7UgcuG7h3QgxJHhur9uIGvhur90IHF14bqjIGjhu5NpIHBo4bulYyB0cm9uZyBk4buvIGxp4buHdSBraOG6o28gc8OhdC4NCg0KLSBUaOG7qSBoYWksIHTGsMahbmcgdOG7sSwgKipow6BuaCB2aSBow7p0IHRodeG7kWMga2jDtG5nIGPDsyBt4buRaSBsacOqbiBo4buHIHLDtSByw6BuZyB24bubaSBraOG6oyBuxINuZyBo4buTaSBwaOG7pWMgaGF5IG5ndXkgY8ahIHTDoWkgbmhp4buFbSoqLiBU4bu3IGzhu4cgZ2nhu69hIGPDoWMgbmjDs20gaMO6dCB2w6Aga2jDtG5nIGjDunQgdGh14buRYyBwaMOibiBi4buRIGtow6EgxJHhu5NuZyDEkeG7gXUsIHbDoCBraMO0bmcgY8OzIGtp4buDbSDEkeG7i25oIG7DoG8gY2hvIGvhur90IHF14bqjIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouIMSQaeG7gXUgbsOgeSBow6BtIMO9IHLhurFuZyB0w6xuaCB0cuG6oW5nIGjDunQgdGh14buRYywgdHJvbmcgcGjhuqFtIHZpIGPhu6dhIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSwga2jDtG5nIHBo4bqjaSBsw6AgeeG6v3UgdOG7kSBwaMOibiBiaeG7h3Qga2jhuqMgbsSDbmcgaOG7k2kgcGjhu6VjIGhheSB0w6FpIG5oaeG7hW0uDQoNCi0gVGjhu6kgYmEgdsOgIHF1YW4gdHLhu41uZyBuaOG6pXQsIGvhur90IHF14bqjIGNobyB0aOG6pXkgKipuZ3V5IGPGoSB0w6FpIG5oaeG7hW0gQ09WSUQtMTkg4bufIG5ow7NtIMSRw6MgdGnDqm0gduG6r2MgeGluIGNhbyBoxqFuIMSRw6FuZyBr4buDIHNvIHbhu5tpIG5ow7NtIGNoxrBhIHRpw6ptKiouIFThu7cgbOG7hyB0w6FpIG5oaeG7hW0g4bufIG5ow7NtIMSRw6MgdGnDqm0gdsaw4bujdCB0cuG7mWkgc28gduG7m2kgbmjDs20gY2jGsGEgdGnDqm0sIHbDoCBz4buxIGtow6FjIGJp4buHdCBuw6B5IMSR4bqhdCBt4bupYyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouIEPDoWMgY2jhu4kgc+G7kSBuaMawICpSUiA9IDEuMTIxKiB2w6AgKk9SID0gMS4yNjUqIHBo4bqjbiDDoW5oIG5ndXkgY8ahIHTDoWkgbmhp4buFbSBjYW8gaMahbiDhu58gbmjDs20gxJHDoyB0acOqbS4gxJDDonkgbMOgIHBow6F0IGhp4buHbiBi4bqldCBuZ+G7nSwgdHLDoWkgbmfGsOG7o2MgduG7m2kgZ2nhuqMgxJHhu4tuaCBwaOG7lSBiaeG6v24gcuG6sW5nIHRpw6ptIGNo4bunbmcgbMOgbSBnaeG6o20gbmd1eSBjxqEgdMOhaSBuaGnhu4VtLiBL4bq/dCBxdeG6oyBuw6B5IGPDsyB0aOG7gyBi4buLIOG6o25oIGjGsOG7n25nIGLhu59pIG5oaeG7gXUgeeG6v3UgdOG7kSBuaMawICoqdGjhu51pIMSRaeG7g20gdGnDqm0sIHPhu5EgbGnhu4F1IHRpw6ptLCBob+G6t2MgY2jhu6duZyB2aXJ1cyBnw6J5IGLhu4duaCoqIOKAkyBuaOG7r25nIHnhur91IHThu5EgY2jGsGEgxJHGsOG7o2Mga2nhu4NtIHNvw6F0IHRyb25nIHBow6JuIHTDrWNoIGhp4buHbiB04bqhaS4NCg0KIyMgKiozLjIuIFRo4bqjbyBsdeG6rW4gdsOgIEjhuqFuIGNo4bq/KioNCg0KIyMjICoqMy4yLjEuIFRo4bqjbyBsdeG6rW4ga+G6v3QgcXXhuqMqKg0KDQpL4bq/dCBxdeG6oyDEkcOhbmcgY2jDuiDDvSBuaOG6pXQgdOG7qyBwaMOibiB0w61jaCBsw6AgKip04bu3IGzhu4cgdMOhaSBuaGnhu4VtIGNhbyBoxqFuIOG7nyBuaMOzbSDEkcOjIHRpw6ptIHbhuq9jLXhpbioqLiDEkMOieSBsw6AgbeG7mXQgcGjDoXQgaGnhu4duIG1hbmcgdMOtbmggcGjhuqNuIHRy4buxYyBnacOhYyB2w6AgY+G6p24gxJHGsOG7o2MgZGnhu4VuIGdp4bqjaSBt4buZdCBjw6FjaCB0aOG6rW4gdHLhu41uZy4gxJBp4buBdSBuw6B5ICoqa2jDtG5nIGPDsyBuZ2jEqWEgcuG6sW5nIHbhuq9jLXhpbiBnw6J5IHJhIHTDoWkgbmhp4buFbSoqLCBtw6AgY8OzIHRo4buDIHBo4bqjbiDDoW5oIOG6o25oIGjGsOG7n25nIGPhu6dhIGPDoWMgeeG6v3UgdOG7kSBraMOhYyBjaMawYSDEkcaw4bujYyBraeG7g20gc2/DoXQuIE3hu5l0IHPhu5EgZ2nhuqMgdGh1eeG6v3QgY8OzIHRo4buDIMSRxrDhu6NjIMSRxrBhIHJhIMSR4buDIGdp4bqjaSB0aMOtY2ggaGnhu4duIHTGsOG7o25nIG7DoHk6DQoNCi0gKipZ4bq/dSB04buRIHRo4budaSBnaWFuIHbDoCBiaeG6v24gdGjhu4MgdmlydXM6KiogQuG7mSBk4buvIGxp4buHdSBtw7QgcGjhu49uZyBrw6lvIGTDoGkgdHJvbmcgZ2lhaSDEkW/huqFuIDIwMjDigJMyMDI0LCB0cm9uZyDEkcOzIGPDoWMgYmnhur9uIHRo4buDIG3hu5tpIG5oxrAgKk9taWNyb24qLCAqWEJCLjEuNSogxJHDoyB4deG6pXQgaGnhu4duLiBOZ8aw4budaSDEkcaw4bujYyB0acOqbSB24bqvYy14aW4gc+G7m20gY8OzIHRo4buDIMSRw6MgYuG7iyBzdXkgZ2nhuqNtIG1p4buFbiBk4buLY2ggdGhlbyB0aOG7nWkgZ2lhbiwgdHJvbmcga2hpIG5ow7NtIGNoxrBhIHRpw6ptIGPDsyB0aOG7gyDEkcOjIHThu6tuZyBt4bqvYyBi4buHbmggdsOgIGjDrG5oIHRow6BuaCBtaeG7hW4gZOG7i2NoIHThu7Egbmhpw6puIGfhuqduIGjGoW4gduG7m2kgdGjhu51pIMSRaeG7g20ga2jhuqNvIHPDoXQsIGdpw7pwIGdp4bqjbSBuZ3V5IGPGoSB0w6FpIG5oaeG7hW0uDQoNCi0gKipIw6BuaCB2aSB2w6AgY8OhYyB54bq/dSB04buRIGfDonkgbmhp4buFdToqKiBOZ8aw4budaSDEkcOjIHRpw6ptIGPDsyB0aOG7gyBjw7MgdMOibSBsw70gYW4gdG/DoG4gY2jhu6cgcXVhbiwgZOG6q24gxJHhur9uIHZp4buHYyAqKsOtdCB0dcOibiB0aOG7pyBjw6FjIGJp4buHbiBwaMOhcCBwaMOybmcgZOG7i2NoKiosIGzDoG0gdMSDbmcgbmd1eSBjxqEgcGjGoWkgbmhp4buFbS4gTmdvw6BpIHJhLCAqKm5naOG7gSBuZ2hp4buHcCAobmjGsCBuaMOibiB2acOqbiB5IHThur8pKiosICoqdHXhu5VpKiosIGhv4bq3YyAqKnTDrG5oIHRy4bqhbmcgYuG7h25oIG7hu4FuKiogY8OzIHRo4buDIOG6o25oIGjGsOG7n25nIMSR4bq/biBj4bqjIHjDoWMgc3XhuqV0IHRpw6ptIGNo4bunbmcgbOG6q24gbmd1eSBjxqEgdMOhaSBuaGnhu4VtLCBuaMawbmcgY2jGsGEgxJHGsOG7o2Mga2nhu4NtIHNvw6F0IHRyb25nIHBow6JuIHTDrWNoIHNvbmcgYmnhur9uIGhp4buHbiB04bqhaS4NCg0KLSAqKkvhur90IHF14bqjIGtow7RuZyByw7UgcsOgbmcgduG7m2kgYmnhur9uIGjDunQgdGh14buRYzoqKiBWaeG7h2Mga2jDtG5nIHTDrG0gdGjhuqV5IG3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGjDunQgdGh14buRYyB2w6AgY8OhYyBr4bq/dCBxdeG6oyBsw6JtIHPDoG5nIG5oxrAgaOG7k2kgcGjhu6VjIGhheSB0w6FpIG5oaeG7hW0gY8OzIHRo4buDIGRvICoq4bqjbmggaMaw4bufbmcgY+G7p2EgY8OhYyB54bq/dSB04buRIG3huqFuaCBoxqFuKiosIGhv4bq3YyBkbyBi4buZIGThu68gbGnhu4d1IGNoxrBhIHBo4bqjbiDDoW5oIMSR4bqneSDEkeG7pyB0w6FjIMSR4buZbmcgdGjhu7FjIHThur8gY+G7p2EgaMO6dCB0aHXhu5FjIMSR4bq/biB0aeG6v24gdHJp4buDbiBi4buHbmguDQoNCiMjIyAqKjMuMi4yLiBI4bqhbiBjaOG6vyBj4bunYSBwaMOibiB0w61jaCoqDQoNCi0gKipE4buvIGxp4buHdSB04buVbmcgaOG7o3AgKFN5bnRoZXRpYyBEYXRhKToqKiBC4buZIGThu68gbGnhu4d1IHPhu60gZOG7pW5nIGzDoCBk4buvIGxp4buHdSBtw7QgcGjhu49uZywga2jDtG5nIHBo4bqjbiDDoW5oIGhvw6BuIHRvw6BuIHRo4buxYyB04bq/LiBEbyDEkcOzLCBt4buNaSBr4bq/dCBsdeG6rW4gY2jhu4kgY8OzIMO9IG5naMSpYSB0cm9uZyBwaOG6oW0gdmkgZOG7ryBsaeG7h3UgbsOgeSB2w6Aga2jDtG5nIHRo4buDIGtow6FpIHF1w6F0IGNobyBkw6JuIHPhu5EgdGjhuq10Lg0KDQotICoqUGjDom4gdMOtY2ggc29uZyBiaeG6v24gKEJpdmFyaWF0ZSBBbmFseXNpcyk6KiogQ8OhYyBraeG7g20gxJHhu4tuaCBoaeG7h24gdOG6oWkgY2jhu4kgeGVtIHjDqXQgdOG7q25nIGPhurdwIGJp4bq/biDEkeG7mWMgbOG6rXAsICoqY2jGsGEga2nhu4NtIHNvw6F0IGPDoWMgeeG6v3UgdOG7kSBuaGnhu4V1KiogbmjGsCDEkeG7mSB0deG7lWksIGdp4bubaSB0w61uaCwgYuG7h25oIG7hu4FuLCBob+G6t2MgdGjhu51pIGdpYW4gdGnDqm0gY2jhu6duZy4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBk4bqrbiDEkeG6v24ga+G6v3QgbHXhuq1uIHNhaSBs4buHY2ggaG/hurdjIMSRw6FuaCBnacOhIGNoxrBhIMSR4bqneSDEkeG7py4NCg0KLSAqKsSQ4buLbmggbmdoxKlhIGJp4bq/biBjw7JuIMSRxqFuIGdp4bqjbjoqKiBCaeG6v24gYFZhY2NpbmF0aW9uX1N0YXR1c2AgY2jhu4kgxJHGsOG7o2MgcGjDom4gbG/huqFpIG5o4buLIHBow6JuICjEkMOjIHRpw6ptL0NoxrBhIHRpw6ptKSwgKipraMO0bmcgcGjDom4gYmnhu4d0IHPhu5EgbGnhu4F1LCBsb+G6oWkgduG6r2MteGluIGhheSB0aOG7nWkgZ2lhbiB0acOqbSoqLCB24buRbiBsw6Agbmjhu69uZyB54bq/dSB04buRIHF1YW4gdHLhu41uZy4gQmnhur9uIGBTbW9raW5nX1N0YXR1c2AgY8WpbmcgY2jhu4kgxJHGoW4gdGh14bqnbiBjaGlhIHRow6BuaCAiQ8OzIGjDunQgdGh14buRYy9LaMO0bmcgaMO6dCB0aHXhu5FjIiwga2jDtG5nIHBo4bqjbiDDoW5oIHLDtSBt4bupYyDEkeG7mSwgdGjhu51pIGdpYW4gaG/hurdjIHRow7NpIHF1ZW4gaMO6dC4NCg0KLSAqKlRoaeG6v3UgeeG6v3UgdOG7kSB0aOG7nWkgZ2lhbjoqKiBN4buZdCBo4bqhbiBjaOG6vyDEkcOhbmcga+G7gyBsw6AgKipjaMawYSB4ZW0geMOpdCB0aOG7nWkgZ2lhbiBnaeG7r2EgY8OhYyBz4buxIGtp4buHbioqLCBjaOG6s25nIGjhuqFuIG5oxrAgdGjhu51pIGdpYW4gdOG7qyBraGkgdGnDqm0gduG6r2MteGluIMSR4bq/biBsw7pjIGLhu4sgdMOhaSBuaGnhu4VtLiBZ4bq/dSB04buRIHRo4budaSBnaWFuIGzDoCBy4bqldCBxdWFuIHRy4buNbmcgdHJvbmcgbmdoacOqbiBj4bupdSBk4buLY2ggdOG7hSB2w6AgY8OzIHRo4buDIOG6o25oIGjGsOG7n25nIG3huqFuaCDEkeG6v24ga+G6v3QgcXXhuqMuDQoNCiMjICoqMy4zLiBIxrDhu5tuZyBwaMOhdCB0cmnhu4NuIHbDoCDEkOG7gSB4deG6pXQqKg0KDQpE4buxYSB0csOqbiBjw6FjIGvhur90IHF14bqjIHRodSDEkcaw4bujYyB2w6Agbmjhu69uZyBo4bqhbiBjaOG6vyDEkcOjIMSRxrDhu6NjIGNo4buJIHJhIHRyb25nIHBo4bqnbiB0csaw4bubYywgbeG7mXQgc+G7kSBoxrDhu5tuZyBwaMOhdCB0cmnhu4NuIHbDoCDEkeG7gSB4deG6pXQgdGnhur9wIHRoZW8gxJHGsOG7o2MgxJHGsGEgcmEgbmjhurFtIGPhuqNpIHRoaeG7h24gxJHhu5kgc8OidSB2w6AgxJHhu5kgdGluIGPhuq15IGPhu6dhIHBow6JuIHTDrWNoOg0KDQojIyMgKiozLjMuMS4gU+G7rSBk4bulbmcgUGjDom4gdMOtY2ggxJBhIGJp4bq/biAoTXVsdGl2YXJpYXRlIEFuYWx5c2lzKSoqDQoNCsSQ4buDIGtp4buDbSBzb8OhdCBjw6FjIHnhur91IHThu5EgZ8OieSBuaGnhu4V1IHRp4buBbSB0w6BuZyAoY29uZm91bmRpbmcgZmFjdG9ycyksIGPhuqduIG3hu58gcuG7mW5nIHThu6sgcGjDom4gdMOtY2ggc29uZyBiaeG6v24gc2FuZyBjw6FjIG3DtCBow6xuaCBo4buTaSBxdXkgxJFhIGJp4bq/biwgY2jhurNuZyBo4bqhbiBuaMawIGjhu5NpIHF1eSBsb2dpc3RpYy4gUGjGsMahbmcgcGjDoXAgbsOgeSBz4bq9IGdpw7pwIMSRw6FuaCBnacOhICoqdMOhYyDEkeG7mW5nIMSR4buZYyBs4bqtcCoqIGPhu6dhIHThu6tuZyBiaeG6v24gxJHhur9uIG5ndXkgY8ahIHTDoWkgbmhp4buFbSBob+G6t2Mga2jhuqMgbsSDbmcgaOG7k2kgcGjhu6VjLCBraGkgxJHDoyBraeG7g20gc2/DoXQgY8OhYyB54bq/dSB04buRIGtow6FjLg0KDQpWw60gZOG7pTogWMOieSBk4buxbmcgbcO0IGjDrG5oIGThu7EgYsOhbyB0w6FpIG5oaeG7hW0gduG7m2kgY8OhYyBiaeG6v24gxJHhuqd1IHbDoG8gbmjGsCBgVmFjY2luYXRpb25fU3RhdHVzYCwgYEFnZWAsIGBQcmVleGlzdGluZ19Db25kaXRpb25gLCBgRG9zZXNfUmVjZWl2ZWRgLCB2w6AgYENPVklEX1N0cmFpbmAuDQoNCiMjIyAqKjMuMy4yLiBQaMOibiB0w61jaCBzw6J1IGjGoW4gduG7gSB54bq/dSB04buRIHbhuq9jLXhpbioqDQoNCkhp4buHbiB04bqhaSwgYmnhur9uIGBWYWNjaW5hdGlvbl9TdGF0dXNgIGNo4buJIMSRxrDhu6NjIG3DoyBow7NhIGTGsOG7m2kgZOG6oW5nIG5o4buLIHBow6JuIChZZXMvTm8pLCDEkWnhu4F1IG7DoHkgY2jGsGEgcGjhuqNuIMOhbmggxJHhuqd5IMSR4bunIHRow7RuZyB0aW4uIE7Dqm4gbeG7nyBy4buZbmcgcGjDom4gdMOtY2ggYuG6sW5nIGPDoWNoIMSRxrBhIHRow6ptOg0KDQotICoqU+G7kSBsaeG7gXUgxJHDoyB0acOqbSoqIChgRG9zZXNfUmVjZWl2ZWRgKSAgDQotICoqTG/huqFpIHbhuq9jLXhpbioqIChgVmFjY2luZV9UeXBlYCkNCg0KxJBp4buBdSBuw6B5IHPhur0gZ2nDunAgbMOgbSByw7UgbGnhu4d1IGPDoWMgbG/huqFpIHbhuq9jLXhpbiBraMOhYyBuaGF1IGhv4bq3YyBz4buRIGxp4buBdSBraMOhYyBuaGF1IGPDsyDhuqNuaCBoxrDhu59uZyDEkeG6v24gbmd1eSBjxqEgdMOhaSBuaGnhu4VtIGhv4bq3YyBraOG6oyBuxINuZyBo4buTaSBwaOG7pWMgaGF5IGtow7RuZy4NCg0KIyMjICoqMy4zLjMuIFRo4buxYyBoaeG7h24gUGjDom4gdMOtY2ggdGhlbyBkw7JuZyB0aOG7nWkgZ2lhbiAoTG9uZ2l0dWRpbmFsIEFuYWx5c2lzKSoqDQoNClPhu60gZOG7pW5nIGPDoWMgYmnhur9uIHRo4budaSBnaWFuIG5oxrAgYERhdGVfb2ZfSW5mZWN0aW9uYCDEkeG7gyB0aeG6v24gaMOgbmggY8OhYyBwaMOibiB0w61jaCB0aGVvIHRo4budaSBnaWFuIOKAlCB2w60gZOG7pSBuaMawICoqcGjDom4gdMOtY2ggc+G7kW5nIHPDs3QgKHN1cnZpdmFsIGFuYWx5c2lzKSoqIG5o4bqxbSDEkcOhbmggZ2nDoToNCg0KLSBUaOG7nWkgZ2lhbiDEkeG6v24ga2hpIHTDoWkgbmhp4buFbSAodGltZSB0byByZWluZmVjdGlvbikNCi0gVGjhu51pIGdpYW4gaOG7k2kgcGjhu6VjICh0aW1lIHRvIHJlY292ZXJ5KQ0KDQpRdWEgxJHDsywgY8OzIHRo4buDIHjDoWMgxJHhu4tuaCBjw6FjIHnhur91IHThu5Eg4bqjbmggaMaw4bufbmcgxJHhur9uIGRp4buFbiB0aeG6v24gYuG7h25oIHRoZW8gdGjhu51pIGdpYW4uDQoNCiMjIyAqKjMuMy40LiBQaMOibiBraMO6YyBk4buvIGxp4buHdSB0aGVvIG5ow7NtKioNCg0KVGjhu7FjIGhp4buHbiBwaMOibiB0w61jaCByacOqbmcgYmnhu4d0IHRoZW8gY8OhYyBuaMOzbSBj4bulIHRo4buDIHRyb25nIGThu68gbGnhu4d1IMSR4buDIHTDrG0gaGnhu4N1IHhlbSAqKm3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgY8OhYyBiaeG6v24gY8OzIHRoYXkgxJHhu5VpIHRyb25nIHThu6tuZyBwaMOibiBuaMOzbSBoYXkga2jDtG5nKiouIE3hu5l0IHPhu5EgY8OhY2ggcGjDom4ga2jDumMgaOG7r3Ugw61jaCBiYW8gZ+G7k206DQoNCi0gVGhlbyAqKmJp4bq/biB0aOG7gyB2aXJ1cyoqIChgQ09WSURfU3RyYWluYCkNCi0gVGhlbyAqKmtodSB24buxYyDEkeG7i2EgbMO9KiogKGBSZWdpb25gKQ0KLSBUaGVvICoqbmjDs20gdHXhu5VpIGhv4bq3YyBuaMOzbSBuZ3V5IGPGoSoqDQoNCiMjIyAqKjMuMy41LiBUcnV54buBbiB0aMO0bmcga+G6v3QgcXXhuqMgbeG7mXQgY8OhY2ggY+G6qW4gdHLhu41uZyoqDQoNCsSQ4bq3YyBiaeG7h3QgduG7m2kga+G6v3QgcXXhuqMgbGnDqm4gcXVhbiDEkeG6v24gKipt4buRaSBsacOqbiBo4buHIGdp4buvYSB0acOqbSB24bqvYy14aW4gdsOgIHTDoWkgbmhp4buFbSoqLCBj4bqnbiBuaOG6pW4gbeG6oW5oIHLhurFuZzoNCg0KPiAqKlTGsMahbmcgcXVhbiBraMO0bmcgxJHhu5NuZyBuZ2jEqWEgduG7m2kgcXVhbiBo4buHIG5ow6JuIHF14bqjLioqDQoNCkvhur90IHF14bqjIG7DoHkgY2jhu4kgcGjhuqNuIMOhbmggeHUgaMaw4bubbmcgdHJvbmcgZOG7ryBsaeG7h3UgdsOgIGPhuqduIMSRxrDhu6NjIGtp4buDbSBjaOG7qW5nIGLhurFuZyBjw6FjIHBow6JuIHTDrWNoIGNodXnDqm4gc8OidSBoxqFuLCBjw7Mga2nhu4NtIHNvw6F0IGPDoWMgeeG6v3UgdOG7kSBuaGnhu4V1LiBLaMO0bmcgbsOqbiDEkcawYSByYSBr4bq/dCBsdeG6rW4ga2jhurNuZyDEkeG7i25oIHbhu4EgaGnhu4d1IHF14bqjIGhheSB0w6FjIMSR4buZbmcgdGnDqnUgY+G7sWMgY+G7p2EgduG6r2MteGluIGNo4buJIGThu7FhIHRyw6puIGPDoWMgcGjDom4gdMOtY2ggxJHGoW4gZ2nhuqNuIGhp4buHbiB04bqhaS4NCg0KIyAqKlBo4bqnbiA0LiBQaMawxqFuZyBwaMOhcCDGsOG7m2MgbMaw4bujbmcgTWF4aW11bSBsaWtlaG9vZCoqDQoNCiMjICoqNC4xLiBHaeG7m2kgdGhp4buHdSB04buVbmcgcXVhbioqDQoNCk1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIChNTEUpIGzDoCBt4buZdCBwaMawxqFuZyBwaMOhcCB0aOG7kW5nIGvDqiBzdXkgbHXhuq1uIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHTDrG0gcmEgY8OhYyBnacOhIHRy4buLIHRoYW0gc+G7kSBzYW8gY2hvIHjDoWMgc3XhuqV0IChoYXkgIsSR4buZIGjhu6NwIGzDvSIpIMSR4buDIHF1YW4gc8OhdCDEkcaw4bujYyBk4buvIGxp4buHdSB0aOG7sWMgdOG6vyBsw6AgbOG7m24gbmjhuqV0LiAgDQoNClRyb25nIGLhu5FpIGPhuqNuaCBwaMOibiB0w61jaCBk4buvIGxp4buHdSDEkeG7i25oIHTDrW5oIChjYXRlZ29yaWNhbCBkYXRhKSwgY8OhYyBtw7QgaMOsbmggdGjhu5FuZyBrw6ogdGjGsOG7nW5nIMaw4bubYyBsxrDhu6NuZyB4w6FjIHN14bqldCBj4bunYSBt4buZdCBob+G6t2Mgbmhp4buBdSBz4buxIGtp4buHbiBy4budaSBy4bqhYy4gTUxFIGzDoCBwaMawxqFuZyBwaMOhcCBjaHXhuqluIHbDoCBt4bqhbmggbeG6vSDEkeG7gyB0aOG7sWMgaGnhu4duIHZp4buHYyBuw6B5Lg0KDQotLS0NCg0KIyMgKio0LjIuIE5ndXnDqm4gdOG6r2MgY+G7kXQgbMO1aTogSMOgbSBI4bujcCBsw70gKExpa2VsaWhvb2QgRnVuY3Rpb24pKioNCg0KIyMjICoqNC4yLjEuIFBow6JuIGJp4buHdCBnaeG7r2EgeMOhYyBzdeG6pXQgdsOgIMSR4buZIGjhu6NwIGzDvToqKg0KDQotICoqWMOhYyBzdeG6pXQqKjogXCggUChcdGV4dHtk4buvIGxp4buHdX0gXG1pZCBcdGhldGEpIFwpIOKAkyBUaGFtIHPhu5EgxJHDoyBiaeG6v3QsIHTDrW5oIHjDoWMgc3XhuqV0IMSR4buDIGThu68gbGnhu4d1IHjhuqN5IHJhLg0KDQotICoqxJDhu5kgaOG7o3AgbMO9Kio6IFwoIEwoXHRoZXRhIFxtaWQgXHRleHR7ZOG7ryBsaeG7h3V9KSBcKSDigJMgROG7ryBsaeG7h3UgxJHDoyBiaeG6v3QsIHTDrG0gdGhhbSBz4buRIHBow7kgaOG7o3AgbmjhuqV0IHbhu5tpIGThu68gbGnhu4d1Lg0KDQpO4bq/dSBjw6FjIHF1YW4gc8OhdCBsw6AgxJHhu5ljIGzhuq1wLCBow6BtIGjhu6NwIGzDvSDEkcaw4bujYyB2aeG6v3Q6DQoNCiQkDQpMKFx0aGV0YSBcbWlkIHlfMSwgeV8yLCAuLi4sIHlfbikgPSBccHJvZF97aT0xfV57bn0gUCh5X2kgXG1pZCBcdGhldGEpDQokJA0KDQpUcm9uZyDEkcOzOg0KLSBcKCBcdGhldGEgXCk6IHRoYW0gc+G7kSBj4bunYSBtw7QgaMOsbmggKHbDrSBk4bulOiB4w6FjIHN14bqldCBcKCBwIFwpIHRyb25nIHBow6JuIHBo4buRaSBCZXJub3VsbGkpLA0KLSBcKCB5X2kgXCk6IHF1YW4gc8OhdCB0aOG7qSBcKCBpIFwpLg0KDQpN4bulYyB0acOqdSBj4bunYSBNTEUgbMOgIHTDrG0gZ2nDoSB0cuG7iyBcKCBcaGF0e1x0aGV0YX0gXCkgc2FvIGNobyBcKCBMKFx0aGV0YSkgXCkgxJHhuqF0IGPhu7FjIMSR4bqhaS4NCg0KLS0tDQoNCiMjICoqNC4zLiBRdXkgdHLDrG5oIHRo4buxYyBoaeG7h24gTUxFKioNCg0KKio0LjMuMS4gQsaw4bubYyAxOiBHaeG6oyDEkeG7i25oIG3DtCBow6xuaCBwaMOibiBwaOG7kWkqKg0KDQotICoqUGjDom4gcGjhu5FpIEJlcm5vdWxsaSoqOiBCaeG6v24gbmjhu4sgcGjDom4gKFllcy9ObykuICANCiAgXCggUChZID0geSkgPSBwXnkgKDEgLSBwKV57MSAtIHl9LCBccXVhZCB5IFxpbiBcezAsIDFcfSBcKQ0KDQotICoqUGjDom4gcGjhu5FpIEJpbm9taWFsKio6IFThu5VuZyBz4buRIGzhuqduIHRow6BuaCBjw7RuZyBzYXUgXCggbiBcKSBwaMOpcCB0aOG7rSDEkeG7mWMgbOG6rXAuDQoNCi0gKipQaMOibiBwaOG7kWkgTXVsdGlub21pYWwqKjogQmnhur9uIGPDsyBuaGnhu4F1IGRhbmggbeG7pWMuDQoNCioqNC4zLjIuIELGsOG7m2MgMjogWMOieSBk4buxbmcgaMOgbSBo4bujcCBsw70qKg0KDQpU4burIG3DtCBow6xuaCB4w6FjIHN14bqldCDEkcOjIGNo4buNbiwgdmnhur90IGjDoG0gaOG7o3AgbMO9IGLhurFuZyB0w61jaCBjw6FjIHjDoWMgc3XhuqV0IGNobyB04burbmcgcXVhbiBzw6F0Lg0KDQoqKjQuMy4zLiBCxrDhu5tjIDM6IFPhu60gZOG7pW5nIGjDoG0gTG9nLUxpa2VsaWhvb2QqKg0KDQrEkOG7gyDEkcahbiBnaeG6o24gaMOzYSB0w61uaCB0b8OhbiwgbOG6pXkgbG9nYXJpdCB04buxIG5oacOqbjoNCg0KJCQNCkxMKFx0aGV0YSkgPSBcbG9nIEwoXHRoZXRhKSA9IFxzdW1fe2k9MX1ee259IFxsb2cgUCh5X2kgXG1pZCBcdGhldGEpDQokJA0KDQoqKkLGsOG7m2MgNDogVOG7kWkgxJFhIGjDs2EgTG9nLUxpa2VsaWhvb2QqKg0KDQotIEzhuqV5IMSR4bqhbyBow6BtIHJpw6puZyBcKCBcZnJhY3tkfXtkXHRoZXRhfSBMTChcdGhldGEpIFwpDQotIEdp4bqjaSBwaMawxqFuZyB0csOsbmggXCggXGZyYWN7ZH17ZFx0aGV0YX0gTEwoXHRoZXRhKSA9IDAgXCkgxJHhu4MgdMOsbSBcKCBcaGF0e1x0aGV0YX0gXCkNCg0KLS0tDQoNCiMjICoqNC40LiBWw60gZOG7pSBtaW5oIGjhu41hOiDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHTDoWkgbmhp4buFbSoqDQoNCioqQsOgaSB0b8OhbioqOiDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIHTDoWkgbmhp4buFbSBcKCBwIFwpIHRyb25nIG5ow7NtIMSRw6MgdGnDqm0gduG6r2MteGluLg0KDQoqKkLGsOG7m2MgMTogTcO0IGjDrG5oKioNCg0KQmnhur9uIFJlaW5mZWN0aW9uIGzDoCBuaOG7iyBwaMOibiDih5IgZMO5bmcgKipCZXJub3VsbGkqKiB24bubaSB0aGFtIHPhu5EgXCggcCA9IFAoXHRleHR7UmVpbmZlY3Rpb24gPSBZZXN9IFxtaWQgXHRleHR7VmFjY2luYXRlZCA9IFllc30pIFwpDQoNCioqQsaw4bubYyAyOiBE4buvIGxp4buHdSoqDQoNCi0gU+G7kSBuZ8aw4budaSDEkcOjIHRpw6ptOiBcKCBuID0gMTQ3MiBcKQ0KLSBT4buRIG5nxrDhu51pIHTDoWkgbmhp4buFbTogXCggayA9IDE1NSBcKQ0KDQpIw6BtIGjhu6NwIGzDvToNCg0KJCQNCkwocCkgPSBwXnsxNTV9ICgxIC0gcCleezEzMTd9DQokJA0KDQoqKkLGsOG7m2MgMzogSMOgbSBMb2ctTGlrZWxpaG9vZCoqDQoNCiQkDQpMTChwKSA9IFxsb2cgTChwKSA9IDE1NSBcY2RvdCBcbG9nKHApICsgMTMxNyBcY2RvdCBcbG9nKDEgLSBwKQ0KJCQNCg0KKipCxrDhu5tjIDQ6IFThu5FpIMSRYSBow7NhKioNCg0KTOG6pXkgxJHhuqFvIGjDoG06DQoNCiQkDQpcZnJhY3tkTEx9e2RwfSA9IFxmcmFjezE1NX17cH0gLSBcZnJhY3sxMzE3fXsxIC0gcH0NCiQkDQoNCkNobyDEkeG6oW8gaMOgbSBi4bqxbmcgMDoNCg0KJCQNClxmcmFjezE1NX17cH0gPSBcZnJhY3sxMzE3fXsxIC0gcH0NClxxdWFkIFxSaWdodGFycm93IFxxdWFkIDE1NSgxIC0gcCkgPSAxMzE3cCBccXVhZCBcUmlnaHRhcnJvdyBccXVhZCBwID0gXGZyYWN7MTU1fXsxNDcyfSBcYXBwcm94IDAuMTA1Mw0KJCQNCg0KKipL4bq/dCBsdeG6rW4qKjogxq/hu5tjIGzGsOG7o25nIGjhu6NwIGzDvSB04buRaSDEkWEgY2hvIHThu7cgbOG7hyB0w6FpIG5oaeG7hW0gbMOgICoqMTAuNTMlKiosIMSRw7puZyBi4bqxbmcgdOG7tyBs4buHIG3huqt1IHF1YW4gc8OhdCDEkcaw4bujYy4NCg0KLS0tDQoNCiMjICoqNC41LiDhu6huZyBk4bulbmcgTUxFIHRyb25nIEjhu5NpIHF1eSBMb2dpc3RpYyoqDQoNCk1MRSBsw6AgcGjGsMahbmcgcGjDoXAgY8ahIGLhuqNuIMSR4buDIMaw4bubYyBsxrDhu6NuZyBjw6FjIGjhu4cgc+G7kSB0cm9uZyAqKmjhu5NpIHF1eSBsb2dpc3RpYyoqLCBt4buZdCBtw7QgaMOsbmggcGjhu5UgYmnhur9uIGNobyBiaeG6v24gcGjhu6UgdGh14buZYyBuaOG7iyBwaMOibi4NCg0KTcO0IGjDrG5oOg0KDQokJA0KUChZID0gMSBcbWlkIFgpID0gXGZyYWN7MX17MSArIFxleHAoLShcYmV0YV8wICsgXGJldGFfMSBYXzEgKyBcY2RvdHMgKyBcYmV0YV9rIFhfaykpfQ0KJCQNCg0KSMOgbSBsb2ctbGlrZWxpaG9vZDoNCg0KJCQNCkxMKFxiZXRhKSA9IFxzdW1fe2k9MX1ee259IFxsZWZ0WyB5X2kgXGxvZyhwX2kpICsgKDEgLSB5X2kpIFxsb2coMSAtIHBfaSkgXHJpZ2h0XQ0KJCQNCg0KRG8ga2jDtG5nIHRo4buDIGdp4bqjaSDEkeG6oW8gaMOgbSBi4bqxbmcgdGF5LCB0YSBkw7luZyBjw6FjIHRodeG6rXQgdG/DoW4gc+G7kSBuaMawICoqTmV3dG9uLVJhcGhzb24qKiwgKipHcmFkaWVudCBEZXNjZW50KiogxJHhu4MgdMOsbSBcKCBcaGF0e1xiZXRhfSBcKS4NCg0KLS0tDQoNCiMjICoqNC42LiDGr3UgxJFp4buDbSB2w6AgTmjGsOG7o2MgxJFp4buDbSBj4bunYSBNTEUqKg0KDQoqKsavdSDEkWnhu4NtOioqDQotICoqSGnhu4d1IHF14bqjKio6IFBoxrDGoW5nIHNhaSBuaOG7jyBu4bq/dSBj4buhIG3huqt1IGzhu5tuLg0KDQotICoqVuG7r25nKio6IEjhu5lpIHThu6UgduG7gSB0aGFtIHPhu5EgdGjhuq10IGtoaSBz4buRIG3huqt1IHTEg25nLg0KDQotICoqVGnhu4dtIGPhuq1uIGNodeG6qW4qKjogSOG7lyB0cuG7oyBraeG7g20gxJHhu4tuaCB2w6Aga2hv4bqjbmcgdGluIGPhuq15Lg0KDQotICoqTGluaCBob+G6oXQqKjogw4FwIGThu6VuZyBjaG8gbmhp4buBdSBtw7QgaMOsbmggdGjhu5FuZyBrw6ouDQoNCioqTmjGsOG7o2MgxJFp4buDbToqKg0KLSAqKlBo4bulIHRodeG7mWMgbcO0IGjDrG5oKio6IE7hur91IG3DtCBow6xuaCBzYWksIE1MRSBz4bq9IHNhaSBs4buHY2guDQoNCi0gKipDw7MgdGjhu4MgY2jhu4djaCoqOiBW4bubaSBj4buhIG3huqt1IG5o4buPLg0KDQotICoqVMOtbmggdG/DoW4gcGjhu6ljIHThuqFwKio6IFbhu5tpIG3DtCBow6xuaCBuaGnhu4F1IHRoYW0gc+G7kSBj4bqnbiB0aHXhuq10IHRvw6FuIGzhurdwLg0KDQotLS0NCg0KIyMjICoqNC43LiBU4buVbmcga+G6v3QqKg0KDQpQaMawxqFuZyBwaMOhcCDGr+G7m2MgbMaw4bujbmcgSOG7o3AgbMO9IFThu5FpIMSRYSAoTUxFKSBsw6AgbeG7mXQgY8O0bmcgY+G7pSBu4buBbiB04bqjbmcgdHJvbmcgdGjhu5FuZyBrw6ogaGnhu4duIMSR4bqhaSwgxJHhurdjIGJp4buHdCBoaeG7h3UgcXXhuqMgdHJvbmcgdmnhu4djIHjhu60gbMO9IHbDoCBwaMOibiB0w61jaCBk4buvIGxp4buHdSDEkeG7i25oIHTDrW5oLiBEw7kgbMOgIHbhu5tpIGLDoGkgdG/DoW4gxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyDEkcahbiBnaeG6o24gaGF5IGPDoWMgbcO0IGjDrG5oIGjhu5NpIHF1eSBsb2dpc3RpYyBwaOG7qWMgdOG6oXAsIE1MRSB24bqrbiBjdW5nIGPhuqVwIGdp4bqjaSBwaMOhcCBt4bqhbmggbeG6vSB2w6AgY8OzIHTDrW5oIHThu5VuZyBxdcOhdCBjYW8uDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=