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

1. Đọc file dữ liệu

d <- read.csv("C:/Users/PC/OneDrive/Máy tính/TMT/NV5.csv")

Bộ dữ liệu gồm 1.000 quan sát, mỗi quan sát tương ứng với một sinh viên, ghi nhận toàn diện các khía cạnh trong thói quen sinh hoạt hàng ngày gắn liền với quá trình học tập. Các biến được thu thập bao gồm thời gian học mỗi ngày, thời lượng ngủ, mức độ sử dụng mạng xã hội, chất lượng chế độ ăn uống, tần suất vận động thể chất, mức độ căng thẳng, và đánh giá sức khỏe tinh thần. Ngoài ra, dữ liệu còn bao gồm thông tin cá nhân cơ bản như giới tính và năm học. Biến kết quả là điểm thi cuối kỳ, được sử dụng để phản ánh hiệu suất học tập của từng sinh viên. Dữ liệu có cấu trúc rõ ràng, đầy đủ, không chứa giá trị thiếu và phù hợp cho các phân tích định lượng chuyên sâu.

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

Bộ dữ liệu Thực hành chứa tổng cộng 1000 bản ghi với 16 biến đặc trưng.

str(d)
## 'data.frame':    1000 obs. of  16 variables:
##  $ student_id                   : chr  "S1000" "S1001" "S1002" "S1003" ...
##  $ age                          : int  23 20 21 23 19 24 21 21 23 18 ...
##  $ Gender                       : chr  "Female" "Male" "Female" "Female" ...
##  $ studyhours                   : chr  "Low" "High" "Low" "Low" ...
##  $ social_media_hours           : num  1.2 2.8 3.1 3.9 4.4 1.3 1.5 1 2.2 3.1 ...
##  $ netflix_hours                : num  1.1 2.3 1.3 1 0.5 0 1.4 2 1.7 1.3 ...
##  $ part_time_job                : chr  "No" "No" "No" "No" ...
##  $ attendance_percentage        : num  85 97.3 94.8 71 90.9 82.9 85.8 77.7 100 95.4 ...
##  $ sleep_hours                  : num  8 4.6 8 9.2 4.9 7.4 6.5 4.6 7.1 7.5 ...
##  $ diet_quality                 : chr  "Fair" "Good" "Good" "Fair" ...
##  $ exercise_frequency           : int  6 6 1 4 3 1 2 0 3 5 ...
##  $ parental_education_level     : chr  "Master" "High School" "High School" "Master" ...
##  $ internet_quality             : chr  "Average" "Average" "Poor" "Good" ...
##  $ mental_health_rating         : int  8 8 1 1 1 4 4 8 1 10 ...
##  $ extracurricular_participation: chr  "Yes" "No" "No" "Yes" ...
##  $ exam_score                   : chr  "High" "High" "Low" "Low" ...

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

  • student_id: mã sinh viên, dạng chuỗi ký tự (mỗi sinh viên có một mã duy nhất).

  • age: tuổi sinh viên, kiểu số nguyên.

  • Gender: giới tính, lưu dưới dạng ký tự (“Male”, “Female”).

  • studyhours: số giờ học mỗi ngày, kiểu số thực.

  • social_media_hours: thời gian sử dụng mạng xã hội trung bình mỗi ngày, kiểu số thực.

  • netflix_hours: số giờ xem Netflix hoặc các nền tảng tương tự mỗi ngày, kiểu số thực.

  • part_time_job: sinh viên có đi làm thêm không, kiểu ký tự (“Yes” hoặc “No”).

  • attendance_percentage: tỷ lệ chuyên cần đến lớp (tính theo %), kiểu số thực.

  • sleep_hours: số giờ ngủ trung bình mỗi ngày, kiểu số thực.

  • diet_quality: chất lượng chế độ ăn uống, kiểu ký tự (“Good”, “Fair”).

  • exercise_frequency: tần suất tập thể dục mỗi tuần, kiểu số nguyên.

  • parental_education_level: trình độ học vấn cao nhất của phụ huynh, kiểu ký tự (“None”, “High School”, “Bachelor”, “Master”).

  • internet_quality: chất lượng kết nối Internet tại nơi ở, kiểu ký tự (“Average”, “Good”).

  • mental_health_rating: đánh giá sức khỏe tâm thần theo thang điểm (ví dụ: từ 1 đến 10), kiểu số nguyên.

  • extracurricular_participation: sinh viên có tham gia hoạt động ngoại khóa không, kiểu ký tự (“Yes” hoặc “No”).

  • exam_score: điểm bài thi cuối kỳ, kiểu số thực.

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

dldt <- c("Gender","studyhours", "part_time_job", "diet_quality", "parental_education_level", "internet_quality","extracurricular_participation", "exam_score")
dt <- d[ , dldt]

6. Kiểm tra NA

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

Kết quả thu được sau khi kiểm tra “False” ta có thể nói không có giá trị Na trong dữ liệu.

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

# Kiểm tra kiểu dữ liệu của từng biến trong dldt
sapply(dt, class) 
##                        Gender                    studyhours 
##                   "character"                   "character" 
##                 part_time_job                  diet_quality 
##                   "character"                   "character" 
##      parental_education_level              internet_quality 
##                   "character"                   "character" 
## extracurricular_participation                    exam_score 
##                   "character"                   "character"

Kết quả kiểm tra kiểu dữ liệu ban đầu cho thấy các biến gender, part_time_job, diet_quality, parental_education_level, internet_qualityextracurricular_participation đều đang ở kiểu “character”, tức là chuỗi ký tự. Đây là dấu hiệu cho thấy dữ liệu chưa được xử lý đúng kiểu, đặc biệt khi các biến này đều mang tính phân loại.

Cụ thể, gender là biến định tính nên cần được chuyển sang kiểu factor để phục vụ cho phân tích thống kê theo nhóm giới tính. Các biến nhị phân như part_time_jobextracurricular_participation cũng nên chuyển thành factor với hai mức “Yes” và “No”. Đối với các biến có thứ tự như diet_quality, internet_qualityparental_education_level, việc chuyển sang kiểu ordered factor là cần thiết nhằm thể hiện đúng bản chất của dữ liệu và cho phép áp dụng các phương pháp phân tích thứ bậc.

Nếu các biến phân loại này vẫn giữ ở dạng chuỗi ký tự, quá trình phân tích sau này sẽ gặp nhiều hạn chế, đặc biệt trong việc trực quan hóa, tính toán tần suất, hoặc xây dựng mô hình học máy. Do đó, việc chuyển đổi đúng kiểu dữ liệu là một bước tiền xử lý quan trọng, góp phần đảm bảo tính chính xác và hiệu quả của toàn bộ quy trình phân tích.

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. Partime Job và Exam Score

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$PartimeJob <- factor(dt$part_time_job)

dt$ExamScore <- factor(dt$exam_score)
                                

# Lập bảng tần số chéo giữa Partime Job và Exam Score
job_score <- table(dt$part_time_job, dt$exam_score)

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

# Hiển thị bảng với nhãn rõ ràng
job_score1
##      
##       High  Low  Sum
##   No   682  103  785
##   Yes  187   28  215
##   Sum  869  131 1000

Bảng tần suất

# Lập bảng tần suất theo hàng (sv có việc làm)
job_score_prop <- prop.table(job_score, margin = 1)
# Hiển thị bảng tần suất
job_score_prop
##      
##            High       Low
##   No  0.8687898 0.1312102
##   Yes 0.8697674 0.1302326

Biểu đồ

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

# Đổi tên cột cho rõ ràng
colnames(job_score_df) <- c("Partime Job", "Exam Score", "Count")

library("ggplot2")
# Vẽ biểu đồ cột nhóm với nhãn số liệu
ggplot(job_score_df, aes(x = `Exam Score`, y = Count, fill = `Partime Job`)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
  geom_text(aes(label = Count), 
            position = position_dodge(width = 0.9), 
            vjust = -0.3, size = 3.5) +
  labs(
    title = "Biểu đồ 1. Số lượng sinh viên theo tình trạng làm thêm và điểm thi",
    x = "Điểm thi",
    y = "Số lượng sinh viên",
    fill = "Làm thêm"
  ) +
  theme_minimal() +
  scale_fill_brewer(palette = "Pastel1")

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

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

  • H₀: Việc làm thêm của sinh viên và điểm thi là hai biến độc lập.

  • H₁: Việc làm thêm của sinh viên và điểm thi có liên quan với nhau.

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

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

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

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

  • p-value = 1

Với p-value = 1 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 dữ liệu hiện tại, không có sự khác biệt có ý nghĩa thống kê nhóm sinh viên làm thêm với việc có điểm số cao hay thấp.

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

# Lập bảng tần số chéo giữa Partime Job và Exam Score
job_score <- table(dt$part_time_job, dt$exam_score)

# Thêm tổng hàng và tổng cột
job_score1 <- addmargins(job_score)
job_score1
##      
##       High  Low  Sum
##   No   682  103  785
##   Yes  187   28  215
##   Sum  869  131 1000

\[ p_1 = P(\text{part_time_job} = \text{Yes} \mid \text{exam_score} = \text{High}) \quad \text{(Tỷ lệ sinh viên có việc làm có điểm số cao)} \]

\[ p_2 = P(\text{part_time_job} = \text{Yes} \mid \text{exam_score} = \text{Low}) \quad \text{(Tỷ lệ sinh viên có việc làm có điểm số thấp)} \]

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

\[ H_0: p_1 - p_2 = 0 \quad \text{(Tỷ lệ sinh viên có việc làm ở nhóm có điểm số cao bằng tỷ lệ sinh viên có việc làm ở nhóm có điểm thấp)} \]

\[ H_1: p_1 - p_2 < 0 \quad \text{(Tỷ lệ sinh viên có việc làm có điểm số cao nhỏ hơn Tỷ lệ sinh viên có việc làm có điểm số thấp)} \]

# Số sinh viên có việc làm có điểm số cao hoặc thấp

counts <- c(job_score["Yes", "Low"], job_score["Yes", "High"])

# Tổng số sinh viên trong từng nhóm điểm 
totals <- c(sum(job_score[, "Low"]), sum(job_score[, "High"]))

# 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 = 0.001417, df = 1, p-value = 0.485
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.00000000  0.06176966
## sample estimates:
##    prop 1    prop 2 
## 0.2137405 0.2151899
  • Kết quả kiểm định tỷ lệ hai mẫu cho thấy:

    • Tỷ lệ có việc làm ở nhóm có điểm thấp (prop 1) là khoảng 21.37%

    • Tỷ lệ có việc làm ở nhóm có điểm cao (prop 2) là khoảng 21.52%

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

  • 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 sinh viên có việc làm ở nhóm có đểm cao và nhóm điểm thấp 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.061769), 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):

library(epitools)
riskratio(job_score, method="wald")
## $data
##        
##         High Low Total
##   No     682 103   785
##   Yes    187  28   215
##   Total  869 131  1000
## 
## $measure
##      risk ratio with 95% C.I.
##        estimate     lower   upper
##   No  1.0000000        NA      NA
##   Yes 0.9925491 0.6723314 1.46528
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   No          NA           NA         NA
##   Yes  0.9827568            1  0.9699723
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Ta thấy RR = 0.9925. Điều đó có nghĩa là tỷ lệ có việc làm ở nhóm điểm số cao thấp hơn khoảng 0.1125% so với nhóm sinh viên có việc làm ở nhóm điểm số thấp. Điều này có thể việc làm thêm vẫn có tác động đến điểm nhưng không quá lớn.

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

or_result1 <- oddsratio(job_score)
print(or_result1)
## $data
##        
##         High Low Total
##   No     682 103   785
##   Yes    187  28   215
##   Total  869 131  1000
## 
## $measure
##      odds ratio with 95% C.I.
##        estimate    lower    upper
##   No  1.0000000       NA       NA
##   Yes 0.9950642 0.624939 1.539313
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   No          NA           NA         NA
##   Yes  0.9827568            1  0.9699723
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Giá trị odds ratio (OR) = 0.995 cho thấy rằng việc sinh viên có việc làm có điểm cao, thấp hơn khoảng 0.5% so với nhóm sinh viên có việc làm ở nhóm điểm thấp.

2.2 Study Hours và Diet Quality

2.2.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$Studyhours <- factor(dt$studyhours)
dt$DietQuality <- factor(dt$diet_quality)
                                

# Lập bảng tần số chéo giữa Study Hours và Diet Quality
st_qa <- table(dt$studyhours, dt$diet_quality)

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

# Hiển thị bảng với nhãn rõ ràng
st_qa1
##       
##        Fair Good  Sum
##   High  169  196  365
##   Low   258  377  635
##   Sum   427  573 1000

Biểu đồ

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

# Đổi tên cột cho rõ ràng
colnames(st_qa_df) <- c("Study Hours", "Diet Quality", "Count")

# Vẽ biểu đồ cột nhóm với nhãn số liệu
ggplot(st_qa_df, aes(x = `Diet Quality`, y = Count, fill = `Study Hours`)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
  geom_text(aes(label = Count), 
            position = position_dodge(width = 0.9), 
            vjust = -0.3, size = 3.5) +
  labs(
    title = "Biểu đồ 1. Số lượng sinh viên theo chế độ ăn và số giờ tự học",
    x = "Chế độ ăn",
    y = "Số lượng sinh viên",
    fill = "Số giờ học"
  ) +
  theme_minimal() +
  scale_fill_brewer(palette = "Pastel1")

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

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

  • H₀: Số giờ tự học và chế độ ăn của sinh viên là hai biến độc lập.

  • H₁: Số giờ tự học và chế độ ăn của sinh viên có liên quan với nhau.

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

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

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

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

  • p-value = 0.09312

Với p-value = 0.09312 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 dữ liệu hiện tại, không có sự khác biệt có ý nghĩa thống kê của việc tự học của sinh viên với chế độ ăn.

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

# Lập bảng tần số chéo giữa Study Hours và Diet Quality
st_qa <- table(dt$studyhours, dt$diet_quality)

# Thêm tổng hàng và tổng cột
st_qa1 <- addmargins(st_qa)
st_qa1
##       
##        Fair Good  Sum
##   High  169  196  365
##   Low   258  377  635
##   Sum   427  573 1000

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

riskratio(st_qa, method="wald")
## $data
##        
##         Fair Good Total
##   High   169  196   365
##   Low    258  377   635
##   Total  427  573  1000
## 
## $measure
##       risk ratio with 95% C.I.
##        estimate     lower    upper
##   High 1.000000        NA       NA
##   Low  1.105616 0.9855529 1.240306
## 
## $p.value
##       two-sided
##        midp.exact fisher.exact chi.square
##   High         NA           NA         NA
##   Low  0.08179212   0.08456375 0.08088655
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Ta thấy RR = 1.105616. Điều đó có nghĩa là tỷ lệ sinh viên có chế độ ăn tốt ở nhóm sinh viên có giờ tự học thấp cao hơn nhóm sinh viên có giờ tự học cao có chế độ ăn tốt khoảng 10.5%. Điều này có thể việc chế độ ăn và số giờ học có tác động đến nha.

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

or_result2 <- oddsratio(st_qa)
print(or_result2)
## $data
##        
##         Fair Good Total
##   High   169  196   365
##   Low    258  377   635
##   Total  427  573  1000
## 
## $measure
##       odds ratio with 95% C.I.
##        estimate     lower    upper
##   High 1.000000        NA       NA
##   Low  1.259681 0.9712651 1.633527
## 
## $p.value
##       two-sided
##        midp.exact fisher.exact chi.square
##   High         NA           NA         NA
##   Low  0.08179212   0.08456375 0.08088655
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Giá trị odds ratio (OR) = 1.259681 cho thấy rằng việc sinh viên có giờ tự học cao ở nhóm có chế độ ăn không lành mạnh cao hơn khoảng 25.9% so với nhóm sinh viên có giờ tự học cao có chế độ ăn tốt.

PHẦN 3. KẾT LUẬN

Thông qua việc phân tích bộ dữ liệu “Nhiệm Vụ 5.csv”, báo cáo đã làm rõ một số mối quan hệ giữa đặc điểm hành vi học tập và kết quả học tập của sinh viên. Cụ thể, hai cặp biến chính được lựa chọn gồm: (1) tình trạng làm thêm và kết quả thi, và (2) số giờ tự học và chất lượng chế độ ăn uống. Những kết quả thu được không chỉ phản ánh thực trạng mà còn gợi mở những hướng nghiên cứu sâu hơn về ảnh hưởng của hành vi học tập đến thành tích học thuật và lối sống sinh viên.

3.1 Làm thêm và kết quả thi – mối quan hệ không rõ ràng

Việc phân tích mối liên hệ giữa tình trạng làm thêm và kết quả thi cho thấy không có bằng chứng thống kê đủ mạnh để khẳng định sinh viên đi làm thêm có ảnh hưởng tích cực hay tiêu cực đến kết quả thi.

Tỷ lệ sinh viên có việc làm đạt điểm cao gần tương đương với nhóm không làm thêm (21.37% so với 21.52%).

Kiểm định tỷ lệ hai mẫu cho kết quả p-value = 0.485, cao hơn ngưỡng ý nghĩa 0.05, cho thấy không có sự khác biệt đáng kể về mặt thống kê giữa hai nhóm.

Các chỉ số như Risk Ratio ≈ 0.99 và Odds Ratio ≈ 0.98, cùng khoảng tin cậy bao gồm giá trị trung tính (1), củng cố nhận định rằng việc làm thêm không tác động rõ rệt đến xác suất đạt điểm cao trong phạm vi mẫu nghiên cứu.

Việc sinh viên có tham gia làm thêm hay không không phải là yếu tố quyết định trực tiếp đến kết quả học tập, khi chưa xét đến các yếu tố trung gian khác như thời gian biểu cá nhân, năng lực tự quản lý thời gian, mức độ mệt mỏi,…

3.2 Số giờ tự học và chế độ ăn – sự phân tán không có ý nghĩa thống kê

Ở mối quan hệ giữa thời lượng học tập hàng ngày và chất lượng chế độ ăn uống, phân tích cũng không phát hiện ra mối liên hệ có ý nghĩa thống kê:

Bảng tần số chéo cho thấy sinh viên học nhiều và học ít có tỷ lệ phân bố tương đối đồng đều giữa nhóm có chế độ ăn tốt và không tốt.

Kiểm định Chi-squared test cho kết quả không có ý nghĩa (p > 0.05), cho thấy không có sự phụ thuộc rõ ràng giữa hai biến này.

Các chỉ số như RR và OR cho thấy xu hướng nhỏ, ví dụ sinh viên học ít có vẻ ăn uống tốt hơn, nhưng khoảng tin cậy rộng và bao gồm giá trị trung lập, không đủ cơ sở kết luận.

** Chế độ ăn uống của sinh viên có thể chịu ảnh hưởng bởi nhiều yếu tố khác như điều kiện tài chính, thói quen cá nhân hoặc ảnh hưởng từ môi trường sống – vượt ngoài phạm vi của số giờ học.**

PHẦN 4. PHƯƠNG PHÁP ƯỚC LƯỢNG MAXIMUM LIKEHOOD

4.1. Tổng quan khái niệm

Phương pháp ước lượng hợp lý tối đa (Maximum Likelihood Estimation - MLE) là một kỹ thuật thống kê phổ quát dùng để xác định giá trị của các tham số trong một mô hình sao cho xác suất xuất hiện của dữ liệu quan sát được là lớn nhất. Về bản chất, MLE là cầu nối giữa dữ liệu thực tế và mô hình lý thuyết, cho phép các nhà phân tích định lượng hóa hiện tượng ngẫu nhiên bằng cách tối đa hóa “độ phù hợp” giữa mô hình và dữ liệu.

Trong các bài toán phân tích dữ liệu định tính hoặc nhị phân, MLE được xem là phương pháp ước lượng chuẩn, thường được áp dụng trong các mô hình phân phối rời rạc như Bernoulli, Binomial hay Multinomial, cũng như trong mô hình hồi quy logistic.

4.2 Nguyên lý cốt lõi: Hàm Hợp lý và Tối đa hóa

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

Xác suất và Hàm hợp lý trong thống kê

  • Xác suất \(P(\text{Data} \mid \theta)\): đại diện cho khả năng xảy ra của dữ liệu quan sát được khi tham số \(\theta\) đã biết. Đây là khái niệm thường dùng trong mô hình suy diễn.

  • Độ hợp lý (Likelihood) \(L(\theta \mid \text{Data})\): đánh giá mức độ phù hợp của tham số \(\theta\) với dữ liệu đã quan sát. Đây là nền tảng của phương pháp ước lượng hợp lý tối đa (Maximum Likelihood Estimation - MLE).

Trường hợp các quan sát độc lập

Khi các quan sát \(y_1, y_2, ..., y_n\)độc lập, hàm hợp lý có thể được viết dưới dạng tích của xác suất có điều kiện:

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

Trong đó:

  • \(\theta\): tham số chưa biết của mô hình,
  • \(y_i\): giá trị quan sát được từ mẫu dữ liệu.

4.2.2 Tối đa hóa hàm hợp lý

Mục tiêu của Maximum Likelihood Estimation (MLE)

Mục tiêu của phương pháp ước lượng hợp lý tối đa là tìm giá trị ước lượng \(\hat{\theta}\) sao cho:

\[ \hat{\theta} = \arg\max_{\theta} L(\theta) \]

Tức là tìm giá trị tham số \(\theta\) làm tối đa hóa hàm hợp lý \(L(\theta)\), với dữ liệu đã cho.

Hàm log-likelihood

Để đơn giản hóa việc tính toán, người ta thường sử dụng hàm log-likelihood, vì logarit của hàm tích sẽ trở thành tổng, dễ xử lý hơn trong phân tích giải tích:

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

Việc tối đa hóa \(\log L(\theta)\) thường được ưa chuộng hơn vì:

  • Biến tích thành tổng, thuận tiện hơn khi lấy đạo hàm,
  • Tránh sai số làm tròn khi tính tích các xác suất rất nhỏ,
  • Giảm độ phức tạp tính toán trong các mô hình lớn.

Do đó, hầu hết các thuật toán MLE thực tế đều sử dụng log-likelihood thay vì trực tiếp làm việc với hàm hợp lý ban đầu.

4.3 Quy trình triển khai MLE

Các bước thực hiện phương pháp ước lượng hợp lý tối đa (MLE)

Bước 1: Xác định mô hình phân phối xác suất

Lựa chọn mô hình phân phối phù hợp với bản chất của biến phụ thuộc (biến đầu ra):

  • Bernoulli: Dùng cho biến nhị phân (0/1),
  • Binomial: Dùng khi mô hình hóa tổng số lần thành công trong nhiều lần thử,
  • Multinomial: Dùng cho biến định tính có nhiều mức (categorical nhiều hơn 2 nhóm).

Bước 2: Thiết lập hàm hợp lý (Likelihood Function)

Dựa vào mô hình xác suất đã chọn, biểu thức hàm hợp lý được thiết lập bằng cách nhân các xác suất có điều kiện ứng với từng quan sát:

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

Bước 3: Tính log-likelihood

Sử dụng logarit tự nhiên để biến đổi tích thành tổng, thuận tiện cho việc tối ưu:

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

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

  • Tính đạo hàm riêng theo tham số \(\theta\):

\[ \frac{d}{d\theta} \log L(\theta) \]

  • Giải phương trình đạo hàm bậc nhất:

\[ \frac{d}{d\theta} \log L(\theta) = 0 \]

  • Kiểm tra điều kiện cực đại:
    • Đạo hàm bậc hai phải âm: \(\frac{d^2}{d\theta^2} \log L(\theta) < 0\),
    • Hoặc sử dụng các phương pháp số (như Newton-Raphson) để tìm cực trị.

4.4 Ứng dụng MLE trong Hồi quy Logistic

Trong các mô hình hồi quy logistic – nơi biến phản hồi \(Y\)nhị phân (0/1) – phương pháp ước lượng hợp lý tối đa (MLE) được sử dụng để ước lượng các hệ số hồi quy \(\beta\) sao cho xác suất dự đoán:

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

phù hợp nhất với dữ liệu quan sát.

Hàm log-likelihood trong hồi quy logistic

Với \(p_i = P(Y_i = 1 \mid X_i)\), hàm log-likelihood có dạng:

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

Hàm log-likelihood này đánh giá độ phù hợp giữa mô hình logistic và dữ liệu quan sát.

Ước lượng \(\hat{\beta}\)

Các hệ số hồi quy \(\hat{\beta}\) được tìm bằng cách tối đa hóa hàm log-likelihood, thông qua các thuật toán tối ưu số như:

  • Newton-Raphson
  • Fisher Scoring
  • Gradient Descent, v.v.

4.55 Tổng kết

Phương pháp ước lượng hợp lý tối đa (MLE) là công cụ trung tâm trong thống kê hiện đại, đặc biệt quan trọng trong các bài toán phân tích dữ liệu định tính hoặc mô hình dự báo xác suất. Với khả năng áp dụng linh hoạt, khả năng hội tụ tốt và tính tối ưu trong điều kiện mẫu lớn, MLE không chỉ phù hợp với các bài toán đơn giản mà còn là xương sống cho các mô hình phức tạp như hồi quy logistic, mô hình phân loại rời rạc, hoặc mô hình ẩn Markov.

Sự thành công trong việc áp dụng MLE đòi hỏi sự hiểu biết sâu sắc về bản chất mô hình hóa xác suất, cũng như năng lực tính toán chính xác và hiệu quả – đặc biệt khi triển khai trong các môi trường dữ liệu lớn, đa chiều.

LS0tDQp0aXRsZTogIk5oaeG7h20gVuG7pSA0Ig0KYXV0aG9yOiAiTmfhu41jIFRyw6JtIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdG9jOiB0cnVlDQogIHdvcmRfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAnNCcNCiAgcGRmX2RvY3VtZW50Og0KICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KLS0tDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KPHN0eWxlPg0KYm9keSB7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgc2Fucy1zZXJpZjsNCiAgZm9udC1zaXplOiAxNnB4Ow0KICB0ZXh0LWFsaWduOiBqdXN0aWZ5Ow0KICBsaW5lLWhlaWdodDogMS41Ow0KfQ0KaDIgew0KICBjb2xvcjogb3JhbmdlOw0KfQ0KaDMgew0KICBjb2xvcjogcmVkOw0KfQ0KPC9zdHlsZT4NCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQoNCiMgKipQaOG6p24gMS4gVMOMTSBISeG7glUgVsOAIENIVeG6qE4gQuG7iiBE4buuIExJ4buGVSoqDQoNCiMjICoqMS4gxJDhu41jIGZpbGUgZOG7ryBsaeG7h3UqKg0KYGBge3IsIGVjaG89VFJVRX0NCmQgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL1BDL09uZURyaXZlL03DoXkgdMOtbmgvVE1UL05WNS5jc3YiKQ0KYGBgDQoNCkLhu5kgZOG7ryBsaeG7h3UgZ+G7k20gMS4wMDAgcXVhbiBzw6F0LCBt4buXaSBxdWFuIHPDoXQgdMawxqFuZyDhu6luZyB24bubaSBt4buZdCBzaW5oIHZpw6puLCBnaGkgbmjhuq1uIHRvw6BuIGRp4buHbiBjw6FjIGtow61hIGPhuqFuaCB0cm9uZyB0aMOzaSBxdWVuIHNpbmggaG/huqF0IGjDoG5nIG5nw6B5IGfhuq9uIGxp4buBbiB24bubaSBxdcOhIHRyw6xuaCBo4buNYyB04bqtcC4gQ8OhYyBiaeG6v24gxJHGsOG7o2MgdGh1IHRo4bqtcCBiYW8gZ+G7k20gdGjhu51pIGdpYW4gaOG7jWMgbeG7l2kgbmfDoHksIHRo4budaSBsxrDhu6NuZyBuZ+G7pywgbeG7qWMgxJHhu5kgc+G7rSBk4bulbmcgbeG6oW5nIHjDoyBo4buZaSwgY2jhuqV0IGzGsOG7o25nIGNo4bq/IMSR4buZIMSDbiB14buRbmcsIHThuqduIHN14bqldCB24bqtbiDEkeG7mW5nIHRo4buDIGNo4bqldCwgbeG7qWMgxJHhu5kgY8SDbmcgdGjhurNuZywgdsOgIMSRw6FuaCBnacOhIHPhu6ljIGto4buPZSB0aW5oIHRo4bqnbi4gTmdvw6BpIHJhLCBk4buvIGxp4buHdSBjw7JuIGJhbyBn4buTbSB0aMO0bmcgdGluIGPDoSBuaMOibiBjxqEgYuG6o24gbmjGsCBnaeG7m2kgdMOtbmggdsOgIG7Eg20gaOG7jWMuIEJp4bq/biBr4bq/dCBxdeG6oyBsw6AgxJFp4buDbSB0aGkgY3Xhu5FpIGvhu7MsIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIHBo4bqjbiDDoW5oIGhp4buHdSBzdeG6pXQgaOG7jWMgdOG6rXAgY+G7p2EgdOG7q25nIHNpbmggdmnDqm4uIEThu68gbGnhu4d1IGPDsyBj4bqldSB0csO6YyByw7UgcsOgbmcsIMSR4bqneSDEkeG7pywga2jDtG5nIGNo4bupYSBnacOhIHRy4buLIHRoaeG6v3UgdsOgIHBow7kgaOG7o3AgY2hvIGPDoWMgcGjDom4gdMOtY2ggxJHhu4tuaCBsxrDhu6NuZyBjaHV5w6puIHPDonUuDQoNCg0KIyMgKioyLiBD4bqldSB0csO6YyBi4buZIGThu68gbGnhu4d1KioNCg0KQuG7mSBk4buvIGxp4buHdSAqKlRo4buxYyBow6BuaCoqIGNo4bupYSB04buVbmcgY+G7mW5nICoqMTAwMCBi4bqjbiBnaGkqKiB24bubaSAqKjE2IGJp4bq/bioqIMSR4bq3YyB0csawbmcuDQoNCmBgYHtyfQ0Kc3RyKGQpDQpgYGANCg0KDQpDw6FjIGJp4bq/biB0cm9uZyBi4buZIGThu68gbGnhu4d1IGJhbyBn4buTbToNCg0KLSAqKipzdHVkZW50X2lkKioqOiBtw6Mgc2luaCB2acOqbiwgZOG6oW5nIGNodeG7l2kga8O9IHThu7EgKG3hu5dpIHNpbmggdmnDqm4gY8OzIG3hu5l0IG3DoyBkdXkgbmjhuqV0KS4NCg0KLSAqKiphZ2UqKio6IHR14buVaSBzaW5oIHZpw6puLCBraeG7g3Ugc+G7kSBuZ3V5w6puLg0KDQotICoqKkdlbmRlcioqKjogZ2nhu5tpIHTDrW5oLCBsxrB1IGTGsOG7m2kgZOG6oW5nIGvDvSB04buxICgiTWFsZSIsICJGZW1hbGUiKS4NCg0KLSAqKipzdHVkeWhvdXJzKioqOiBz4buRIGdp4budIGjhu41jIG3hu5dpIG5nw6B5LCBraeG7g3Ugc+G7kSB0aOG7sWMuDQoNCi0gKioqc29jaWFsX21lZGlhX2hvdXJzKioqOiB0aOG7nWkgZ2lhbiBz4butIGThu6VuZyBt4bqhbmcgeMOjIGjhu5lpIHRydW5nIGLDrG5oIG3hu5dpIG5nw6B5LCBraeG7g3Ugc+G7kSB0aOG7sWMuDQoNCi0gKioqbmV0ZmxpeF9ob3VycyoqKjogc+G7kSBnaeG7nSB4ZW0gTmV0ZmxpeCBob+G6t2MgY8OhYyBu4buBbiB04bqjbmcgdMawxqFuZyB04buxIG3hu5dpIG5nw6B5LCBraeG7g3Ugc+G7kSB0aOG7sWMuDQoNCi0gKioqcGFydF90aW1lX2pvYioqKjogc2luaCB2acOqbiBjw7MgxJFpIGzDoG0gdGjDqm0ga2jDtG5nLCBraeG7g3Uga8O9IHThu7EgKCJZZXMiIGhv4bq3YyAiTm8iKS4NCg0KLSAqKiphdHRlbmRhbmNlX3BlcmNlbnRhZ2UqKio6IHThu7cgbOG7hyBjaHV5w6puIGPhuqduIMSR4bq/biBs4bubcCAodMOtbmggdGhlbyAlKSwga2nhu4N1IHPhu5EgdGjhu7FjLg0KDQotICoqKnNsZWVwX2hvdXJzKioqOiBz4buRIGdp4budIG5n4bunIHRydW5nIGLDrG5oIG3hu5dpIG5nw6B5LCBraeG7g3Ugc+G7kSB0aOG7sWMuDQoNCi0gKioqZGlldF9xdWFsaXR5KioqOiBjaOG6pXQgbMaw4bujbmcgY2jhur8gxJHhu5kgxINuIHXhu5FuZywga2nhu4N1IGvDvSB04buxICgiR29vZCIsICJGYWlyIikuDQoNCi0gKioqZXhlcmNpc2VfZnJlcXVlbmN5KioqOiB04bqnbiBzdeG6pXQgdOG6rXAgdGjhu4MgZOG7pWMgbeG7l2kgdHXhuqduLCBraeG7g3Ugc+G7kSBuZ3V5w6puLg0KDQotICoqKnBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbCoqKjogdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIGNhbyBuaOG6pXQgY+G7p2EgcGjhu6UgaHV5bmgsIGtp4buDdSBrw70gdOG7sSAoIk5vbmUiLCAiSGlnaCBTY2hvb2wiLCAiQmFjaGVsb3IiLCAiTWFzdGVyIikuDQoNCi0gKioqaW50ZXJuZXRfcXVhbGl0eSoqKjogY2jhuqV0IGzGsOG7o25nIGvhur90IG7hu5FpIEludGVybmV0IHThuqFpIG7GoWkg4bufLCBraeG7g3Uga8O9IHThu7EgKCJBdmVyYWdlIiwgIkdvb2QiKS4NCg0KLSAqKiptZW50YWxfaGVhbHRoX3JhdGluZyoqKjogxJHDoW5oIGdpw6Egc+G7qWMga2jhu49lIHTDom0gdGjhuqduIHRoZW8gdGhhbmcgxJFp4buDbSAodsOtIGThu6U6IHThu6sgMSDEkeG6v24gMTApLCBraeG7g3Ugc+G7kSBuZ3V5w6puLg0KDQotICoqKmV4dHJhY3VycmljdWxhcl9wYXJ0aWNpcGF0aW9uKioqOiBzaW5oIHZpw6puIGPDsyB0aGFtIGdpYSBob+G6oXQgxJHhu5luZyBuZ2/huqFpIGtow7NhIGtow7RuZywga2nhu4N1IGvDvSB04buxICgiWWVzIiBob+G6t2MgIk5vIikuDQoNCi0gKioqZXhhbV9zY29yZSoqKjogxJFp4buDbSBiw6BpIHRoaSBjdeG7kWkga+G7sywga2nhu4N1IHPhu5EgdGjhu7FjLg0KDQojIyAqKjMuIENo4buNbiBjw6FjIGJp4bq/biDEkeG7i25oIHTDrW5oKioNCg0KYGBge3J9DQpkbGR0IDwtIGMoIkdlbmRlciIsInN0dWR5aG91cnMiLCAicGFydF90aW1lX2pvYiIsICJkaWV0X3F1YWxpdHkiLCAicGFyZW50YWxfZWR1Y2F0aW9uX2xldmVsIiwgImludGVybmV0X3F1YWxpdHkiLCJleHRyYWN1cnJpY3VsYXJfcGFydGljaXBhdGlvbiIsICJleGFtX3Njb3JlIikNCmR0IDwtIGRbICwgZGxkdF0NCmBgYA0KDQoNCg0KDQoNCiMjICoqNi4gS2nhu4NtIHRyYSBOQSoqDQoNCmBgYHtyfQ0KYW55KGlzLm5hKGR0KSkNCmBgYA0KDQpL4bq/dCBxdeG6oyB0aHUgxJHGsOG7o2Mgc2F1IGtoaSBraeG7g20gdHJhICJGYWxzZSIgdGEgY8OzIHRo4buDIG7Ds2kga2jDtG5nIGPDsyBnacOhIHRy4buLIE5hIHRyb25nIGThu68gbGnhu4d1Lg0KDQojIyAqKjcuIEtp4buDbSB0cmEga2nhu4N1IGThu68gbGnhu4d1IHbDoCDEkeG7lWkgduG7gSBmYWN0b3IqKg0KDQpgYGB7cn0NCiMgS2nhu4NtIHRyYSBraeG7g3UgZOG7ryBsaeG7h3UgY+G7p2EgdOG7q25nIGJp4bq/biB0cm9uZyBkbGR0DQpzYXBwbHkoZHQsIGNsYXNzKSANCmBgYA0KDQogIEvhur90IHF14bqjIGtp4buDbSB0cmEga2nhu4N1IGThu68gbGnhu4d1IGJhbiDEkeG6p3UgY2hvIHRo4bqleSBjw6FjIGJp4bq/biAqKipnZW5kZXIsIHBhcnRfdGltZV9qb2IsIGRpZXRfcXVhbGl0eSwgcGFyZW50YWxfZWR1Y2F0aW9uX2xldmVsLCBpbnRlcm5ldF9xdWFsaXR5KioqIHbDoCAqKipleHRyYWN1cnJpY3VsYXJfcGFydGljaXBhdGlvbiDEkeG7gXUqKiogxJFhbmcg4bufIGtp4buDdSAiY2hhcmFjdGVyIiwgdOG7qWMgbMOgIGNodeG7l2kga8O9IHThu7EuIMSQw6J5IGzDoCBk4bqldSBoaeG7h3UgY2hvIHRo4bqleSBk4buvIGxp4buHdSBjaMawYSDEkcaw4bujYyB44butIGzDvSDEkcO6bmcga2nhu4N1LCDEkeG6t2MgYmnhu4d0IGtoaSBjw6FjIGJp4bq/biBuw6B5IMSR4buBdSBtYW5nIHTDrW5oIHBow6JuIGxv4bqhaS4NCg0KICBD4bulIHRo4buDLCAqKipnZW5kZXIqKiogbMOgIGJp4bq/biDEkeG7i25oIHTDrW5oIG7Dqm4gY+G6p24gxJHGsOG7o2MgY2h1eeG7g24gc2FuZyBraeG7g3UgZmFjdG9yIMSR4buDIHBo4bulYyB24bulIGNobyBwaMOibiB0w61jaCB0aOG7kW5nIGvDqiB0aGVvIG5ow7NtIGdp4bubaSB0w61uaC4gQ8OhYyBiaeG6v24gbmjhu4sgcGjDom4gbmjGsCAqKipwYXJ0X3RpbWVfam9iKioqIHbDoCAqKipleHRyYWN1cnJpY3VsYXJfcGFydGljaXBhdGlvbioqKiBjxaluZyBuw6puIGNodXnhu4NuIHRow6BuaCBmYWN0b3IgduG7m2kgaGFpIG3hu6ljICJZZXMiIHbDoCAiTm8iLiDEkOG7kWkgduG7m2kgY8OhYyBiaeG6v24gY8OzIHRo4bupIHThu7EgbmjGsCAqKipkaWV0X3F1YWxpdHkqKiosICoqKmludGVybmV0X3F1YWxpdHkqKiogdsOgICoqKnBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbCoqKiwgdmnhu4djIGNodXnhu4NuIHNhbmcga2nhu4N1IG9yZGVyZWQgZmFjdG9yIGzDoCBj4bqnbiB0aGnhur90IG5o4bqxbSB0aOG7gyBoaeG7h24gxJHDum5nIGLhuqNuIGNo4bqldCBj4bunYSBk4buvIGxp4buHdSB2w6AgY2hvIHBow6lwIMOhcCBk4bulbmcgY8OhYyBwaMawxqFuZyBwaMOhcCBwaMOibiB0w61jaCB0aOG7qSBi4bqtYy4NCg0KICBO4bq/dSBjw6FjIGJp4bq/biBwaMOibiBsb+G6oWkgbsOgeSB24bqrbiBnaeG7ryDhu58gZOG6oW5nIGNodeG7l2kga8O9IHThu7EsIHF1w6EgdHLDrG5oIHBow6JuIHTDrWNoIHNhdSBuw6B5IHPhur0gZ+G6t3Agbmhp4buBdSBo4bqhbiBjaOG6vywgxJHhurdjIGJp4buHdCB0cm9uZyB2aeG7h2MgdHLhu7FjIHF1YW4gaMOzYSwgdMOtbmggdG/DoW4gdOG6p24gc3XhuqV0LCBob+G6t2MgeMOieSBk4buxbmcgbcO0IGjDrG5oIGjhu41jIG3DoXkuIERvIMSRw7MsIHZp4buHYyBjaHV54buDbiDEkeG7lWkgxJHDum5nIGtp4buDdSBk4buvIGxp4buHdSBsw6AgbeG7mXQgYsaw4bubYyB0aeG7gW4geOG7rSBsw70gcXVhbiB0cuG7jW5nLCBnw7NwIHBo4bqnbiDEkeG6o20gYuG6o28gdMOtbmggY2jDrW5oIHjDoWMgdsOgIGhp4buHdSBxdeG6oyBj4bunYSB0b8OgbiBi4buZIHF1eSB0csOsbmggcGjDom4gdMOtY2guDQoNCg0KYGBge3IsIGVjaG89VFJVRX0NCmR0IDwtIGRhdGEuZnJhbWUobGFwcGx5KGR0LCBhcy5mYWN0b3IpKQ0KYGBgDQoNCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQoNCiMgKipQaOG6p24gMi4gUEjDgk4gVMONQ0ggTeG7kEkgUVVBTiBI4buGIEdJ4buuQSBIQUkgQknhur5OIMSQ4buKTkggVMONTkgqKg0KDQojIyAqKjIuMS4gUGFydGltZSBKb2IgdsOgIEV4YW0gU2NvcmUqKg0KDQojIyMgKioyLjEuMS4gQuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCAqKg0KDQoqKkLhuqNuZyB04bqnbiBz4buRKioNCmBgYHtyfQ0KIyBHw6FuIG5ow6NuIHLDtSByw6BuZyBjaG8gY8OhYyBiaeG6v24NCmR0JFBhcnRpbWVKb2IgPC0gZmFjdG9yKGR0JHBhcnRfdGltZV9qb2IpDQoNCmR0JEV4YW1TY29yZSA8LSBmYWN0b3IoZHQkZXhhbV9zY29yZSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoNCiMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EgY2jDqW8gZ2nhu69hIFBhcnRpbWUgSm9iIHbDoCBFeGFtIFNjb3JlDQpqb2Jfc2NvcmUgPC0gdGFibGUoZHQkcGFydF90aW1lX2pvYiwgZHQkZXhhbV9zY29yZSkNCg0KIyBUaMOqbSB04buVbmcgaMOgbmcgdsOgIHThu5VuZyBj4buZdA0Kam9iX3Njb3JlMSA8LSBhZGRtYXJnaW5zKGpvYl9zY29yZSkNCg0KIyBIaeG7g24gdGjhu4sgYuG6o25nIHbhu5tpIG5ow6NuIHLDtSByw6BuZw0Kam9iX3Njb3JlMQ0KYGBgDQoNCg0KKipC4bqjbmcgdOG6p24gc3XhuqV0KioNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc3XhuqV0IHRoZW8gaMOgbmcgKHN2IGPDsyB2aeG7h2MgbMOgbSkNCmpvYl9zY29yZV9wcm9wIDwtIHByb3AudGFibGUoam9iX3Njb3JlLCBtYXJnaW4gPSAxKQ0KIyBIaeG7g24gdGjhu4sgYuG6o25nIHThuqduIHN14bqldA0Kam9iX3Njb3JlX3Byb3ANCmBgYA0KDQoqKkJp4buDdSDEkeG7kyoqDQpgYGB7cn0NCiMgQ2h1eeG7g24gYuG6o25nIHNhbmcgZOG6oW5nIGRhdGEgZnJhbWUNCmpvYl9zY29yZV9kZiA8LSBhcy5kYXRhLmZyYW1lKGpvYl9zY29yZSkNCg0KIyDEkOG7lWkgdMOqbiBj4buZdCBjaG8gcsO1IHLDoG5nDQpjb2xuYW1lcyhqb2Jfc2NvcmVfZGYpIDwtIGMoIlBhcnRpbWUgSm9iIiwgIkV4YW0gU2NvcmUiLCAiQ291bnQiKQ0KDQpsaWJyYXJ5KCJnZ3Bsb3QyIikNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgbmjDs20gduG7m2kgbmjDo24gc+G7kSBsaeG7h3UNCmdncGxvdChqb2Jfc2NvcmVfZGYsIGFlcyh4ID0gYEV4YW0gU2NvcmVgLCB5ID0gQ291bnQsIGZpbGwgPSBgUGFydGltZSBKb2JgKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IENvdW50KSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgDQogICAgICAgICAgICB2anVzdCA9IC0wLjMsIHNpemUgPSAzLjUpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJCaeG7g3UgxJHhu5MgMS4gU+G7kSBsxrDhu6NuZyBzaW5oIHZpw6puIHRoZW8gdMOsbmggdHLhuqFuZyBsw6BtIHRow6ptIHbDoCDEkWnhu4NtIHRoaSIsDQogICAgeCA9ICLEkGnhu4NtIHRoaSIsDQogICAgeSA9ICJT4buRIGzGsOG7o25nIHNpbmggdmnDqm4iLA0KICAgIGZpbGwgPSAiTMOgbSB0aMOqbSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFzdGVsMSIpDQpgYGANCg0KDQojIyMgKioyLjEuMiBLaeG7g20gxJHhu4tuaCBUaOG7kW5nIGvDqioqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6KioNCg0KLSAqKkjigoAqKjogVmnhu4djIGzDoG0gdGjDqm0gY+G7p2Egc2luaCB2acOqbiB2w6AgxJFp4buDbSB0aGkgIGzDoCBoYWkgYmnhur9uIMSR4buZYyBs4bqtcC4NCg0KLSAqKkjigoEqKjogVmnhu4djIGzDoG0gdGjDqm0gY+G7p2Egc2luaCB2acOqbiB2w6AgxJFp4buDbSB0aGkgY8OzIGxpw6puIHF1YW4gduG7m2kgbmhhdS4NCg0KDQpgYGB7cn0NCiMgVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBDaGkgYsOsbmggcGjGsMahbmcNCmNoaV9qb2Jfc2NvcmUgPC0gY2hpc3EudGVzdChqb2Jfc2NvcmUpDQpwcmludChjaGlfam9iX3Njb3JlKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpIGLDrG5oIHBoxrDGoW5nOiBYwrIgPSA2LjY4MTJlLTI5DQoNCi0gQuG6rWMgdOG7sSBkbyAoZGYpID0gMQ0KDQotIHAtdmFsdWUgPSAgMQ0KDQpW4bubaSBwLXZhbHVlID0gIDEgbOG7m24gaMahbiBt4bupYyDDvSBuZ2jEqWEgcGjhu5UgYmnhur9uIM6xID0gMC4wNSwga2jDtG5nIMSR4bunIGLhurFuZyBjaOG7qW5nIMSR4buDIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBI4oKALiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AsIHRyb25nIGThu68gbGnhu4d1IGhp4buHbiB04bqhaSwga2jDtG5nIGPDsyBz4buxIGtow6FjIGJp4buHdCBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqIG5ow7NtIHNpbmggdmnDqm4gbMOgbSB0aMOqbSB24bubaSB2aeG7h2MgY8OzIMSRaeG7g20gc+G7kSBjYW8gaGF5IHRo4bqlcC4NCg0KIyMjICoqMi4xLjMgIEhp4buHdSB04bu3IGzhu4cgKFJpc2sgRGlmZmVyZW5jZSAtIFJEKSoqDQoNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBnaeG7r2EgUGFydGltZSBKb2IgdsOgIEV4YW0gU2NvcmUNCmpvYl9zY29yZSA8LSB0YWJsZShkdCRwYXJ0X3RpbWVfam9iLCBkdCRleGFtX3Njb3JlKQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgdOG7lW5nIGPhu5l0DQpqb2Jfc2NvcmUxIDwtIGFkZG1hcmdpbnMoam9iX3Njb3JlKQ0Kam9iX3Njb3JlMQ0KYGBgDQoNClxbDQpwXzEgPSBQKFx0ZXh0e3BhcnRfdGltZV9qb2J9ID0gXHRleHR7WWVzfSBcbWlkIFx0ZXh0e2V4YW1fc2NvcmV9ID0gXHRleHR7SGlnaH0pIFxxdWFkIFx0ZXh0eyhU4bu3IGzhu4cgc2luaCB2acOqbiBjw7Mgdmnhu4djIGzDoG0gY8OzIMSRaeG7g20gc+G7kSBjYW8pfQ0KXF0NCg0KXFsNCnBfMiA9IFAoXHRleHR7cGFydF90aW1lX2pvYn0gPSBcdGV4dHtZZXN9IFxtaWQgXHRleHR7ZXhhbV9zY29yZX0gPSBcdGV4dHtMb3d9KSBccXVhZCBcdGV4dHsoVOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIGPDsyDEkWnhu4NtIHPhu5EgdGjhuqVwKX0NClxdDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6KioNCg0KXFsNCkhfMDogcF8xIC0gcF8yID0gMCBccXVhZCBcdGV4dHsoVOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIOG7nyBuaMOzbSBjw7MgxJFp4buDbSBz4buRIGNhbyBi4bqxbmcgdOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIOG7nyBuaMOzbSBjw7MgxJFp4buDbSB0aOG6pXApfQ0KXF0NCg0KXFsNCkhfMTogcF8xIC0gcF8yIDwgMCBccXVhZCBcdGV4dHsoVOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIGPDsyDEkWnhu4NtIHPhu5EgY2FvIG5o4buPIGjGoW4gVOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIGPDsyDEkWnhu4NtIHPhu5EgdGjhuqVwKX0NClxdDQoNCg0KDQpgYGB7cn0NCiMgU+G7kSBzaW5oIHZpw6puIGPDsyB2aeG7h2MgbMOgbSBjw7MgxJFp4buDbSBz4buRIGNhbyBob+G6t2MgdGjhuqVwDQoNCmNvdW50cyA8LSBjKGpvYl9zY29yZVsiWWVzIiwgIkxvdyJdLCBqb2Jfc2NvcmVbIlllcyIsICJIaWdoIl0pDQoNCiMgVOG7lW5nIHPhu5Egc2luaCB2acOqbiB0cm9uZyB04burbmcgbmjDs20gxJFp4buDbSANCnRvdGFscyA8LSBjKHN1bShqb2Jfc2NvcmVbLCAiTG93Il0pLCBzdW0oam9iX3Njb3JlWywgIkhpZ2giXSkpDQoNCiMgS2nhu4NtIMSR4buLbmggdOG7iSBs4buHIG3hu5l0IHBow61hOiBwMSA8IHAyDQp0ZXN0X3JlY292ZXJ5X2xlc3MgPC0gcHJvcC50ZXN0KGNvdW50cywgdG90YWxzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIiwgY29ycmVjdCA9IEZBTFNFKQ0KdGVzdF9yZWNvdmVyeV9sZXNzDQpgYGANCg0KLSBL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCB04bu3IGzhu4cgaGFpIG3huqt1IGNobyB0aOG6pXk6DQoNCiAgLSBU4bu3IGzhu4cgY8OzIHZp4buHYyBsw6BtIOG7nyBuaMOzbSBjw7MgxJFp4buDbSB0aOG6pXAgKHByb3AgMSkgbMOgIGtob+G6o25nIDIxLjM3JQ0KDQogIC0gVOG7tyBs4buHIGPDsyB2aeG7h2MgbMOgbSDhu58gbmjDs20gY8OzIMSRaeG7g20gY2FvIChwcm9wIDIpIGzDoCBraG/huqNuZyAyMS41MiUNCg0KLSBHacOhIHRy4buLIHRo4buRbmcga8OqIENoaSBiw6xuaCBwaMawxqFuZyBsw6AgMC4wMDE0MTcgduG7m2kgYuG6rWMgdOG7sSBkbyAxIHbDoCBwLXZhbHVlID0gMC40ODUuDQoNCi0gVsOsIHAtdmFsdWUgbOG7m24gaMahbiBt4bupYyDDvSBuZ2jEqWEgMC4wNSwgY2jDum5nIHRhIGtow7RuZyDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgcuG6sW5nIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIOG7nyBuaMOzbSBjw7MgxJHhu4NtIGNhbyB2w6AgbmjDs20gxJFp4buDbSB0aOG6pXAgbMOgIGLhurFuZyBuaGF1Lg0KDQotIE5nb8OgaSByYSwga2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gaGnhu4d1IGhhaSB04bu3IGzhu4cgYmFvIGfhu5NtIGdpw6EgdHLhu4sgMCAodOG7qyAtMSDEkeG6v24gMC4wNjE3NjkpLCBjxaluZyBj4bunbmcgY+G7kSBuaOG6rW4gxJHhu4tuaCBy4bqxbmcgc+G7sSBraMOhYyBiaeG7h3QgZ2nhu69hIGhhaSB04bu3IGzhu4cga2jDtG5nIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ouDQoNCi0gVMOzbSBs4bqhaSwgdGhlbyBk4buvIGxp4buHdSBuw6B5LCB04bu3IGzhu4cgaOG7k2kgcGjhu6VjIGPhu6dhIG5ow7NtIGNoxrBhIHRpw6ptIHbDoCBuaMOzbSDEkcOjIHRpw6ptIGtow7RuZyBraMOhYyBiaeG7h3QgxJHDoW5nIGvhu4MgdsOgIGtow7RuZyBjw7MgYuG6sW5nIGNo4bupbmcgY2hvIHRo4bqleSBuaMOzbSBjaMawYSB0acOqbSBjw7MgdOG7tyBs4buHIGjhu5NpIHBo4bulYyB0aOG6pXAgaMahbiBuaMOzbSDEkcOjIHRpw6ptLg0KDQoNCiMjIyAqKjIuMS40LiBU4bu3IHPhu5EgTmd1eSBjxqEgKFJlbGF0aXZlIFJpc2sgLSBSUik6KioNCg0KYGBge3J9DQpsaWJyYXJ5KGVwaXRvb2xzKQ0Kcmlza3JhdGlvKGpvYl9zY29yZSwgbWV0aG9kPSJ3YWxkIikNCmBgYA0KDQotIFRhIHRo4bqleSBSUiA9IDAuOTkyNS4gxJBp4buBdSDEkcOzIGPDsyBuZ2jEqWEgbMOgIHThu7cgbOG7hyBjw7Mgdmnhu4djIGzDoG0g4bufIG5ow7NtIMSRaeG7g20gc+G7kSBjYW8gdGjhuqVwIGjGoW4ga2hv4bqjbmcgMC4xMTI1JSBzbyB24bubaSBuaMOzbSBzaW5oIHZpw6puIGPDsyB2aeG7h2MgbMOgbSDhu58gbmjDs20gxJFp4buDbSBz4buRIHRo4bqlcC4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyB2aeG7h2MgbMOgbSB0aMOqbSB24bqrbiBjw7MgdMOhYyDEkeG7mW5nIMSR4bq/biDEkWnhu4NtIG5oxrBuZyBraMO0bmcgcXXDoSBs4bubbi4NCg0KIyMjICoqMi4xLjUuIFThu7cgc+G7kSBDaMOqbmggKE9kZHMgUmF0aW8gLSBPUik6KioNCg0KYGBge3J9DQpvcl9yZXN1bHQxIDwtIG9kZHNyYXRpbyhqb2Jfc2NvcmUpDQpwcmludChvcl9yZXN1bHQxKQ0KYGBgDQoNCkdpw6EgdHLhu4sgb2RkcyByYXRpbyAoT1IpID0gMC45OTUgY2hvIHRo4bqleSBy4bqxbmcgdmnhu4djIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtICBjw7MgxJFp4buDbSBjYW8sIHRo4bqlcCBoxqFuIGtob+G6o25nIDAuNSUgc28gduG7m2kgbmjDs20gc2luaCB2acOqbiBjw7Mgdmnhu4djIGzDoG0g4bufIG5ow7NtIMSRaeG7g20gdGjhuqVwLiANCg0KDQojIyAqKjIuMiBTdHVkeSBIb3VycyB2w6AgRGlldCBRdWFsaXR5KioNCg0KIyMjICoqMi4yLjEgQuG6o25nIHThuqduIHPhu5EgdsOgIHThuqduIHN14bqldCAqKg0KDQoqKkLhuqNuZyB04bqnbiBz4buRKioNCmBgYHtyfQ0KIyBHw6FuIG5ow6NuIHLDtSByw6BuZyBjaG8gY8OhYyBiaeG6v24NCmR0JFN0dWR5aG91cnMgPC0gZmFjdG9yKGR0JHN0dWR5aG91cnMpDQpkdCREaWV0UXVhbGl0eSA8LSBmYWN0b3IoZHQkZGlldF9xdWFsaXR5KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCg0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBnaeG7r2EgU3R1ZHkgSG91cnMgdsOgIERpZXQgUXVhbGl0eQ0Kc3RfcWEgPC0gdGFibGUoZHQkc3R1ZHlob3VycywgZHQkZGlldF9xdWFsaXR5KQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgdOG7lW5nIGPhu5l0DQpzdF9xYTEgPC0gYWRkbWFyZ2lucyhzdF9xYSkNCg0KIyBIaeG7g24gdGjhu4sgYuG6o25nIHbhu5tpIG5ow6NuIHLDtSByw6BuZw0Kc3RfcWExDQpgYGANCg0KDQoqKkJp4buDdSDEkeG7kyoqDQpgYGB7cn0NCiMgQ2h1eeG7g24gYuG6o25nIHNhbmcgZOG6oW5nIGRhdGEgZnJhbWUNCnN0X3FhX2RmIDwtIGFzLmRhdGEuZnJhbWUoc3RfcWEpDQoNCiMgxJDhu5VpIHTDqm4gY+G7mXQgY2hvIHLDtSByw6BuZw0KY29sbmFtZXMoc3RfcWFfZGYpIDwtIGMoIlN0dWR5IEhvdXJzIiwgIkRpZXQgUXVhbGl0eSIsICJDb3VudCIpDQoNCiMgVuG6vSBiaeG7g3UgxJHhu5MgY+G7mXQgbmjDs20gduG7m2kgbmjDo24gc+G7kSBsaeG7h3UNCmdncGxvdChzdF9xYV9kZiwgYWVzKHggPSBgRGlldCBRdWFsaXR5YCwgeSA9IENvdW50LCBmaWxsID0gYFN0dWR5IEhvdXJzYCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBDb3VudCksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIA0KICAgICAgICAgICAgdmp1c3QgPSAtMC4zLCBzaXplID0gMy41KSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQmnhu4N1IMSR4buTIDEuIFPhu5EgbMaw4bujbmcgc2luaCB2acOqbiB0aGVvIGNo4bq/IMSR4buZIMSDbiB2w6Agc+G7kSBnaeG7nSB04buxIGjhu41jIiwNCiAgICB4ID0gIkNo4bq/IMSR4buZIMSDbiIsDQogICAgeSA9ICJT4buRIGzGsOG7o25nIHNpbmggdmnDqm4iLA0KICAgIGZpbGwgPSAiU+G7kSBnaeG7nSBo4buNYyINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFzdGVsMSIpDQoNCmBgYA0KDQojIyMgKioyLjIuMiBLaeG7g20gxJHhu4tuaCBUaOG7kW5nIGvDqioqDQoNCioqR2nhuqMgdGh1eeG6v3Qga2nhu4NtIMSR4buLbmg6KioNCg0KLSAqKkjigoAqKjogU+G7kSBnaeG7nSB04buxIGjhu41jIHbDoCBjaOG6vyDEkeG7mSDEg24gY+G7p2Egc2luaCB2acOqbiBsw6AgaGFpIGJp4bq/biDEkeG7mWMgbOG6rXAuDQoNCi0gKipI4oKBKio6IFPhu5EgZ2nhu50gdOG7sSBo4buNYyB2w6AgY2jhur8gxJHhu5kgxINuIGPhu6dhIHNpbmggdmnDqm4gY8OzIGxpw6puIHF1YW4gduG7m2kgbmhhdS4NCg0KDQpgYGB7cn0NCiMgVGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBDaGkgYsOsbmggcGjGsMahbmcNCmNoaV9zdF9xYSA8LSBjaGlzcS50ZXN0KHN0X3FhKQ0KcHJpbnQoY2hpX3N0X3FhKQ0KYGBgDQoNCkvhur90IHF14bqjIGtp4buDbSDEkeG7i25oOg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogQ2hpIGLDrG5oIHBoxrDGoW5nOiBYwrIgPSAyLjgxOTYNCg0KLSBC4bqtYyB04buxIGRvIChkZikgPSAxDQoNCi0gcC12YWx1ZSA9ICAwLjA5MzEyDQoNClbhu5tpIHAtdmFsdWUgPSAwLjA5MzEyIGzhu5tuIGjGoW4gbeG7qWMgw70gbmdoxKlhIHBo4buVIGJp4bq/biDOsSA9IDAuMDUsIGtow7RuZyDEkeG7pyBi4bqxbmcgY2jhu6luZyDEkeG7gyBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSOKCgC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgLCB0cm9uZyBk4buvIGxp4buHdSBoaeG7h24gdOG6oWksIGtow7RuZyBjw7Mgc+G7sSBraMOhYyBiaeG7h3QgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBj4bunYSB2aeG7h2MgdOG7sSBo4buNYyBj4bunYSBzaW5oIHZpw6puIHbhu5tpIGNo4bq/IMSR4buZIMSDbi4NCg0KIyMjICoqMi4yLjMgIEhp4buHdSB04bu3IGzhu4cgKFJpc2sgRGlmZmVyZW5jZSAtIFJEKSoqDQoNCmBgYHtyfQ0KIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBnaeG7r2EgU3R1ZHkgSG91cnMgdsOgIERpZXQgUXVhbGl0eQ0Kc3RfcWEgPC0gdGFibGUoZHQkc3R1ZHlob3VycywgZHQkZGlldF9xdWFsaXR5KQ0KDQojIFRow6ptIHThu5VuZyBow6BuZyB2w6AgdOG7lW5nIGPhu5l0DQpzdF9xYTEgPC0gYWRkbWFyZ2lucyhzdF9xYSkNCnN0X3FhMQ0KYGBgDQoNCg0KIyMjICoqMi4yLjQuIFThu7cgc+G7kSBOZ3V5IGPGoSAoUmVsYXRpdmUgUmlzayAtIFJSKToqKg0KDQpgYGB7cn0NCnJpc2tyYXRpbyhzdF9xYSwgbWV0aG9kPSJ3YWxkIikNCmBgYA0KDQotIFRhIHRo4bqleSBSUiA9IDEuMTA1NjE2LiDEkGnhu4F1IMSRw7MgY8OzIG5naMSpYSBsw6AgdOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIGNo4bq/IMSR4buZIMSDbiB04buRdCDhu58gbmjDs20gc2luaCB2acOqbiBjw7MgZ2nhu50gdOG7sSBo4buNYyB0aOG6pXAgY2FvIGjGoW4gbmjDs20gc2luaCB2acOqbiBjw7MgZ2nhu50gdOG7sSBo4buNYyBjYW8gY8OzIGNo4bq/IMSR4buZIMSDbiB04buRdCBraG/huqNuZyAxMC41JS4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyB2aeG7h2MgY2jhur8gxJHhu5kgxINuIHbDoCBz4buRIGdp4budIGjhu41jIGPDsyB0w6FjIMSR4buZbmcgxJHhur9uIG5oYS4NCg0KIyMjICoqMi4xLjUuIFThu7cgc+G7kSBDaMOqbmggKE9kZHMgUmF0aW8gLSBPUik6KioNCg0KYGBge3J9DQpvcl9yZXN1bHQyIDwtIG9kZHNyYXRpbyhzdF9xYSkNCnByaW50KG9yX3Jlc3VsdDIpDQpgYGANCg0KR2nDoSB0cuG7iyBvZGRzIHJhdGlvIChPUikgPSAxLjI1OTY4MSBjaG8gdGjhuqV5IHLhurFuZyB2aeG7h2Mgc2luaCB2acOqbiBjw7MgZ2nhu50gdOG7sSBo4buNYyBjYW8g4bufIG5ow7NtIGPDsyBjaOG6vyDEkeG7mSDEg24ga2jDtG5nIGzDoG5oICBt4bqhbmggY2FvIGjGoW4ga2hv4bqjbmcgMjUuOSUgc28gduG7m2kgbmjDs20gc2luaCB2acOqbiBjw7MgZ2nhu50gdOG7sSBo4buNYyBjYW8gY8OzIGNo4bq/IMSR4buZIMSDbiB04buRdC4gDQoNCiMgKipQSOG6pk4gMy4gS+G6vlQgTFXhuqxOKioNCg0KVGjDtG5nIHF1YSB2aeG7h2MgcGjDom4gdMOtY2ggYuG7mSBk4buvIGxp4buHdSDigJxOaGnhu4dtIFbhu6UgNS5jc3bigJ0sIGLDoW8gY8OhbyDEkcOjIGzDoG0gcsO1IG3hu5l0IHPhu5EgbeG7kWkgcXVhbiBo4buHIGdp4buvYSDEkeG6t2MgxJFp4buDbSBow6BuaCB2aSBo4buNYyB04bqtcCB2w6Aga+G6v3QgcXXhuqMgaOG7jWMgdOG6rXAgY+G7p2Egc2luaCB2acOqbi4gQ+G7pSB0aOG7gywgaGFpIGPhurdwIGJp4bq/biBjaMOtbmggxJHGsOG7o2MgbOG7sWEgY2jhu41uIGfhu5NtOiAoMSkgdMOsbmggdHLhuqFuZyBsw6BtIHRow6ptIHbDoCBr4bq/dCBxdeG6oyB0aGksIHbDoCAoMikgc+G7kSBnaeG7nSB04buxIGjhu41jIHbDoCBjaOG6pXQgbMaw4bujbmcgY2jhur8gxJHhu5kgxINuIHXhu5FuZy4gTmjhu69uZyBr4bq/dCBxdeG6oyB0aHUgxJHGsOG7o2Mga2jDtG5nIGNo4buJIHBo4bqjbiDDoW5oIHRo4buxYyB0cuG6oW5nIG3DoCBjw7JuIGfhu6NpIG3hu58gbmjhu69uZyBoxrDhu5tuZyBuZ2hpw6puIGPhu6l1IHPDonUgaMahbiB24buBIOG6o25oIGjGsOG7n25nIGPhu6dhIGjDoG5oIHZpIGjhu41jIHThuq1wIMSR4bq/biB0aMOgbmggdMOtY2ggaOG7jWMgdGh14bqtdCB2w6AgbOG7kWkgc+G7kW5nIHNpbmggdmnDqm4uDQoNCg0KIyMgKiozLjEgTMOgbSB0aMOqbSB2w6Aga+G6v3QgcXXhuqMgdGhpIOKAkyBt4buRaSBxdWFuIGjhu4cga2jDtG5nIHLDtSByw6BuZyoqDQoNClZp4buHYyBwaMOibiB0w61jaCBt4buRaSBsacOqbiBo4buHIGdp4buvYSB0w6xuaCB0cuG6oW5nIGzDoG0gdGjDqm0gdsOgIGvhur90IHF14bqjIHRoaSBjaG8gdGjhuqV5IGtow7RuZyBjw7MgYuG6sW5nIGNo4bupbmcgdGjhu5FuZyBrw6ogxJHhu6cgbeG6oW5oIMSR4buDIGto4bqzbmcgxJHhu4tuaCBzaW5oIHZpw6puIMSRaSBsw6BtIHRow6ptIGPDsyDhuqNuaCBoxrDhu59uZyB0w61jaCBj4buxYyBoYXkgdGnDqnUgY+G7sWMgxJHhur9uIGvhur90IHF14bqjIHRoaS4NCg0KVOG7tyBs4buHIHNpbmggdmnDqm4gY8OzIHZp4buHYyBsw6BtIMSR4bqhdCDEkWnhu4NtIGNhbyBn4bqnbiB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIG5ow7NtIGtow7RuZyBsw6BtIHRow6ptICgyMS4zNyUgc28gduG7m2kgMjEuNTIlKS4NCg0KS2nhu4NtIMSR4buLbmggdOG7tyBs4buHIGhhaSBt4bqrdSBjaG8ga+G6v3QgcXXhuqMgcC12YWx1ZSA9IDAuNDg1LCBjYW8gaMahbiBuZ8aw4buhbmcgw70gbmdoxKlhIDAuMDUsIGNobyB0aOG6pXkga2jDtG5nIGPDsyBz4buxIGtow6FjIGJp4buHdCDEkcOhbmcga+G7gyB24buBIG3hurd0IHRo4buRbmcga8OqIGdp4buvYSBoYWkgbmjDs20uDQoNCkPDoWMgY2jhu4kgc+G7kSBuaMawIFJpc2sgUmF0aW8g4omIIDAuOTkgdsOgIE9kZHMgUmF0aW8g4omIIDAuOTgsIGPDuW5nIGtob+G6o25nIHRpbiBj4bqteSBiYW8gZ+G7k20gZ2nDoSB0cuG7iyB0cnVuZyB0w61uaCAoMSksIGPhu6duZyBj4buRIG5o4bqtbiDEkeG7i25oIHLhurFuZyB2aeG7h2MgbMOgbSB0aMOqbSBraMO0bmcgdMOhYyDEkeG7mW5nIHLDtSBy4buHdCDEkeG6v24geMOhYyBzdeG6pXQgxJHhuqF0IMSRaeG7g20gY2FvIHRyb25nIHBo4bqhbSB2aSBt4bqrdSBuZ2hpw6puIGPhu6l1Lg0KDQoqKlZp4buHYyBzaW5oIHZpw6puIGPDsyB0aGFtIGdpYSBsw6BtIHRow6ptIGhheSBraMO0bmcga2jDtG5nIHBo4bqjaSBsw6AgeeG6v3UgdOG7kSBxdXnhur90IMSR4buLbmggdHLhu7FjIHRp4bq/cCDEkeG6v24ga+G6v3QgcXXhuqMgaOG7jWMgdOG6rXAsIGtoaSBjaMawYSB4w6l0IMSR4bq/biBjw6FjIHnhur91IHThu5EgdHJ1bmcgZ2lhbiBraMOhYyBuaMawIHRo4budaSBnaWFuIGJp4buDdSBjw6EgbmjDom4sIG7Eg25nIGzhu7FjIHThu7EgcXXhuqNuIGzDvSB0aOG7nWkgZ2lhbiwgbeG7qWMgxJHhu5kgbeG7h3QgbeG7j2ksLi4uKioNCg0KIyMgKiozLjIgU+G7kSBnaeG7nSB04buxIGjhu41jIHbDoCBjaOG6vyDEkeG7mSDEg24g4oCTIHPhu7EgcGjDom4gdMOhbiBraMO0bmcgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqioqDQoNCuG7niBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIHRo4budaSBsxrDhu6NuZyBo4buNYyB04bqtcCBow6BuZyBuZ8OgeSB2w6AgY2jhuqV0IGzGsOG7o25nIGNo4bq/IMSR4buZIMSDbiB14buRbmcsIHBow6JuIHTDrWNoIGPFqW5nIGtow7RuZyBwaMOhdCBoaeG7h24gcmEgbeG7kWkgbGnDqm4gaOG7hyBjw7Mgw70gbmdoxKlhIHRo4buRbmcga8OqOg0KDQpC4bqjbmcgdOG6p24gc+G7kSBjaMOpbyBjaG8gdGjhuqV5IHNpbmggdmnDqm4gaOG7jWMgbmhp4buBdSB2w6AgaOG7jWMgw610IGPDsyB04bu3IGzhu4cgcGjDom4gYuG7kSB0xrDGoW5nIMSR4buRaSDEkeG7k25nIMSR4buBdSBnaeG7r2EgbmjDs20gY8OzIGNo4bq/IMSR4buZIMSDbiB04buRdCB2w6Aga2jDtG5nIHThu5F0Lg0KDQpLaeG7g20gxJHhu4tuaCBDaGktc3F1YXJlZCB0ZXN0IGNobyBr4bq/dCBxdeG6oyBraMO0bmcgY8OzIMO9IG5naMSpYSAocCA+IDAuMDUpLCBjaG8gdGjhuqV5IGtow7RuZyBjw7Mgc+G7sSBwaOG7pSB0aHXhu5ljIHLDtSByw6BuZyBnaeG7r2EgaGFpIGJp4bq/biBuw6B5Lg0KDQpDw6FjIGNo4buJIHPhu5EgbmjGsCBSUiB2w6AgT1IgY2hvIHRo4bqleSB4dSBoxrDhu5tuZyBuaOG7jywgdsOtIGThu6Ugc2luaCB2acOqbiBo4buNYyDDrXQgY8OzIHbhursgxINuIHXhu5FuZyB04buRdCBoxqFuLCBuaMawbmcga2hv4bqjbmcgdGluIGPhuq15IHLhu5luZyB2w6AgYmFvIGfhu5NtIGdpw6EgdHLhu4sgdHJ1bmcgbOG6rXAsIGtow7RuZyDEkeG7pyBjxqEgc+G7nyBr4bq/dCBsdeG6rW4uDQoNCioqIENo4bq/IMSR4buZIMSDbiB14buRbmcgY+G7p2Egc2luaCB2acOqbiBjw7MgdGjhu4MgY2jhu4t1IOG6o25oIGjGsOG7n25nIGLhu59pIG5oaeG7gXUgeeG6v3UgdOG7kSBraMOhYyBuaMawIMSRaeG7gXUga2nhu4duIHTDoGkgY2jDrW5oLCB0aMOzaSBxdWVuIGPDoSBuaMOibiBob+G6t2Mg4bqjbmggaMaw4bufbmcgdOG7qyBtw7RpIHRyxrDhu51uZyBz4buRbmcg4oCTIHbGsOG7o3Qgbmdvw6BpIHBo4bqhbSB2aSBj4bunYSBz4buRIGdp4budIGjhu41jLioqDQoNCg0KIyAqKlBI4bqmTiA0LiBQSMavxqBORyBQSMOBUCDGr+G7mkMgTMav4buiTkcgTUFYSU1VTSBMSUtFSE9PRCoqDQoNCiMjICoqNC4xLiBU4buVbmcgcXVhbiBraMOhaSBuaeG7h20qKg0KDQpQaMawxqFuZyBwaMOhcCDGsOG7m2MgbMaw4bujbmcgaOG7o3AgbMO9IHThu5FpIMSRYSAoTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24gLSBNTEUpIGzDoCBt4buZdCBr4bu5IHRodeG6rXQgdGjhu5FuZyBrw6ogcGjhu5UgcXXDoXQgZMO5bmcgxJHhu4MgeMOhYyDEkeG7i25oIGdpw6EgdHLhu4sgY+G7p2EgY8OhYyB0aGFtIHPhu5EgdHJvbmcgbeG7mXQgbcO0IGjDrG5oIHNhbyBjaG8geMOhYyBzdeG6pXQgeHXhuqV0IGhp4buHbiBj4bunYSBk4buvIGxp4buHdSBxdWFuIHPDoXQgxJHGsOG7o2MgbMOgIGzhu5tuIG5o4bqldC4gVuG7gSBi4bqjbiBjaOG6pXQsIE1MRSBsw6AgY+G6p3UgbuG7kWkgZ2nhu69hIGThu68gbGnhu4d1IHRo4buxYyB04bq/IHbDoCBtw7QgaMOsbmggbMO9IHRodXnhur90LCBjaG8gcGjDqXAgY8OhYyBuaMOgIHBow6JuIHTDrWNoIMSR4buLbmggbMaw4bujbmcgaMOzYSBoaeG7h24gdMaw4bujbmcgbmfhuqt1IG5oacOqbiBi4bqxbmcgY8OhY2ggdOG7kWkgxJFhIGjDs2EgIsSR4buZIHBow7kgaOG7o3AiIGdp4buvYSBtw7QgaMOsbmggdsOgIGThu68gbGnhu4d1Lg0KDQpUcm9uZyBjw6FjIGLDoGkgdG/DoW4gcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgxJHhu4tuaCB0w61uaCBob+G6t2Mgbmjhu4sgcGjDom4sIE1MRSDEkcaw4bujYyB4ZW0gbMOgIHBoxrDGoW5nIHBow6FwIMaw4bubYyBsxrDhu6NuZyBjaHXhuqluLCB0aMaw4budbmcgxJHGsOG7o2Mgw6FwIGThu6VuZyB0cm9uZyBjw6FjIG3DtCBow6xuaCBwaMOibiBwaOG7kWkgcuG7nWkgcuG6oWMgbmjGsCBCZXJub3VsbGksIEJpbm9taWFsIGhheSBNdWx0aW5vbWlhbCwgY8WpbmcgbmjGsCB0cm9uZyBtw7QgaMOsbmggaOG7k2kgcXV5IGxvZ2lzdGljLg0KDQoNCiMjICoqNC4yIE5ndXnDqm4gbMO9IGPhu5F0IGzDtWk6IEjDoG0gSOG7o3AgbMO9IHbDoCBU4buRaSDEkWEgaMOzYSoqDQoNCiMjIyAqKjQuMi4xIFBow6JuIGJp4buHdCB4w6FjIHN14bqldCB2w6AgxJHhu5kgaOG7o3AgbMO9KioNCg0KIFjDoWMgc3XhuqV0IHbDoCBIw6BtIGjhu6NwIGzDvSB0cm9uZyB0aOG7kW5nIGvDqg0KDQotICoqWMOhYyBzdeG6pXQqKiAkUChcdGV4dHtEYXRhfSBcbWlkIFx0aGV0YSkkOiDEkeG6oWkgZGnhu4duIGNobyBraOG6oyBuxINuZyB44bqjeSByYSBj4bunYSBk4buvIGxp4buHdSBxdWFuIHPDoXQgxJHGsOG7o2Mga2hpICoqdGhhbSBz4buRICRcdGhldGEkIMSRw6MgYmnhur90KiouIMSQw6J5IGzDoCBraMOhaSBuaeG7h20gdGjGsOG7nW5nIGTDuW5nIHRyb25nIG3DtCBow6xuaCBzdXkgZGnhu4VuLg0KDQotICoqxJDhu5kgaOG7o3AgbMO9IChMaWtlbGlob29kKSoqICRMKFx0aGV0YSBcbWlkIFx0ZXh0e0RhdGF9KSQ6IMSRw6FuaCBnacOhIG3hu6ljIMSR4buZICpwaMO5IGjhu6NwKiBj4bunYSB0aGFtIHPhu5EgJFx0aGV0YSQgduG7m2kgZOG7ryBsaeG7h3UgxJHDoyBxdWFuIHPDoXQuIMSQw6J5IGzDoCBu4buBbiB04bqjbmcgY+G7p2EgcGjGsMahbmcgcGjDoXAgxrDhu5tjIGzGsOG7o25nIGjhu6NwIGzDvSB04buRaSDEkWEgKE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIC0gTUxFKS4NCg0KIFRyxrDhu51uZyBo4bujcCBjw6FjIHF1YW4gc8OhdCDEkeG7mWMgbOG6rXANCg0KS2hpIGPDoWMgcXVhbiBzw6F0ICR5XzEsIHlfMiwgLi4uLCB5X24kIGzDoCAqKsSR4buZYyBs4bqtcCoqLCBow6BtIGjhu6NwIGzDvSBjw7MgdGjhu4MgxJHGsOG7o2Mgdmnhur90IGTGsOG7m2kgZOG6oW5nIHTDrWNoIGPhu6dhIHjDoWMgc3XhuqV0IGPDsyDEkWnhu4F1IGtp4buHbjoNCg0KJCQNCkwoXHRoZXRhIFxtaWQgeV8xLCB5XzIsIFxsZG90cywgeV9uKSA9IFxwcm9kX3tpPTF9XntufSBQKHlfaSBcbWlkIFx0aGV0YSkNCiQkDQoNClRyb25nIMSRw7M6DQoNCi0gJFx0aGV0YSQ6IHRoYW0gc+G7kSBjaMawYSBiaeG6v3QgY+G7p2EgbcO0IGjDrG5oLA0KLSAkeV9pJDogZ2nDoSB0cuG7iyBxdWFuIHPDoXQgxJHGsOG7o2MgdOG7qyBt4bqrdSBk4buvIGxp4buHdS4NCg0KDQojIyAqKjQuMi4yIFThu5FpIMSRYSBow7NhIGjDoG0gaOG7o3AgbMO9KioNCg0KTeG7pWMgdGnDqnUgY+G7p2EgTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24gKE1MRSkNCg0KTeG7pWMgdGnDqnUgY+G7p2EgcGjGsMahbmcgcGjDoXAgxrDhu5tjIGzGsOG7o25nIGjhu6NwIGzDvSB04buRaSDEkWEgbMOgIHTDrG0gZ2nDoSB0cuG7iyDGsOG7m2MgbMaw4bujbmcgJFxoYXR7XHRoZXRhfSQgc2FvIGNobzoNCg0KJCQNClxoYXR7XHRoZXRhfSA9IFxhcmdcbWF4X3tcdGhldGF9IEwoXHRoZXRhKQ0KJCQNCg0KVOG7qWMgbMOgIHTDrG0gZ2nDoSB0cuG7iyB0aGFtIHPhu5EgJFx0aGV0YSQgbMOgbSAqKnThu5FpIMSRYSBow7NhIGjDoG0gaOG7o3AgbMO9KiogJEwoXHRoZXRhKSQsIHbhu5tpIGThu68gbGnhu4d1IMSRw6MgY2hvLg0KDQpIw6BtIGxvZy1saWtlbGlob29kDQoNCsSQ4buDIMSRxqFuIGdp4bqjbiBow7NhIHZp4buHYyB0w61uaCB0b8OhbiwgbmfGsOG7nWkgdGEgdGjGsOG7nW5nIHPhu60gZOG7pW5nICoqaMOgbSBsb2ctbGlrZWxpaG9vZCoqLCB2w6wgbG9nYXJpdCBj4bunYSBow6BtIHTDrWNoIHPhur0gdHLhu58gdGjDoG5oIHThu5VuZywgZOG7hSB44butIGzDvSBoxqFuIHRyb25nIHBow6JuIHTDrWNoIGdp4bqjaSB0w61jaDoNCg0KJCQNClxsb2cgTChcdGhldGEpID0gXHN1bV97aT0xfV57bn0gXGxvZyBQKHlfaSBcbWlkIFx0aGV0YSkNCiQkDQoNClZp4buHYyB04buRaSDEkWEgaMOzYSAkXGxvZyBMKFx0aGV0YSkkIHRoxrDhu51uZyDEkcaw4bujYyDGsGEgY2h14buZbmcgaMahbiB2w6w6DQoNCi0gQmnhur9uIHTDrWNoIHRow6BuaCB04buVbmcsIHRodeG6rW4gdGnhu4duIGjGoW4ga2hpIGzhuqV5IMSR4bqhbyBow6BtLA0KLSBUcsOhbmggc2FpIHPhu5EgbMOgbSB0csOybiBraGkgdMOtbmggdMOtY2ggY8OhYyB4w6FjIHN14bqldCBy4bqldCBuaOG7jywNCi0gR2nhuqNtIMSR4buZIHBo4bupYyB04bqhcCB0w61uaCB0b8OhbiB0cm9uZyBjw6FjIG3DtCBow6xuaCBs4bubbi4NCg0KRG8gxJHDsywgaOG6p3UgaOG6v3QgY8OhYyB0aHXhuq10IHRvw6FuIE1MRSB0aOG7sWMgdOG6vyDEkeG7gXUgc+G7rSBk4bulbmcgKipsb2ctbGlrZWxpaG9vZCoqIHRoYXkgdsOsIHRy4buxYyB0aeG6v3AgbMOgbSB2aeG7h2MgduG7m2kgaMOgbSBo4bujcCBsw70gYmFuIMSR4bqndS4NCg0KIyMgKio0LjMgUXV5IHRyw6xuaCB0cmnhu4NuIGtoYWkgTUxFKioNCg0KDQogQ8OhYyBixrDhu5tjIHRo4buxYyBoaeG7h24gcGjGsMahbmcgcGjDoXAgxrDhu5tjIGzGsOG7o25nIGjhu6NwIGzDvSB04buRaSDEkWEgKE1MRSkNCg0KICoqQsaw4bubYyAxOiBYw6FjIMSR4buLbmggbcO0IGjDrG5oIHBow6JuIHBo4buRaSB4w6FjIHN14bqldCoqDQoNCkzhu7FhIGNo4buNbiBtw7QgaMOsbmggcGjDom4gcGjhu5FpIHBow7kgaOG7o3AgduG7m2kgYuG6o24gY2jhuqV0IGPhu6dhIGJp4bq/biBwaOG7pSB0aHXhu5ljIChiaeG6v24gxJHhuqd1IHJhKToNCg0KLSAqKkJlcm5vdWxsaSoqOiBEw7luZyBjaG8gYmnhur9uIG5o4buLIHBow6JuICgwLzEpLA0KLSAqKkJpbm9taWFsKio6IETDuW5nIGtoaSBtw7QgaMOsbmggaMOzYSB04buVbmcgc+G7kSBs4bqnbiB0aMOgbmggY8O0bmcgdHJvbmcgbmhp4buBdSBs4bqnbiB0aOG7rSwNCi0gKipNdWx0aW5vbWlhbCoqOiBEw7luZyBjaG8gYmnhur9uIMSR4buLbmggdMOtbmggY8OzIG5oaeG7gXUgbeG7qWMgKGNhdGVnb3JpY2FsIG5oaeG7gXUgaMahbiAyIG5ow7NtKS4NCg0KICoqQsaw4bubYyAyOiBUaGnhur90IGzhuq1wIGjDoG0gaOG7o3AgbMO9IChMaWtlbGlob29kIEZ1bmN0aW9uKSoqDQoNCkThu7FhIHbDoG8gbcO0IGjDrG5oIHjDoWMgc3XhuqV0IMSRw6MgY2jhu41uLCBiaeG7g3UgdGjhu6ljIGjDoG0gaOG7o3AgbMO9IMSRxrDhu6NjIHRoaeG6v3QgbOG6rXAgYuG6sW5nIGPDoWNoIG5ow6JuIGPDoWMgeMOhYyBzdeG6pXQgY8OzIMSRaeG7gXUga2nhu4duIOG7qW5nIHbhu5tpIHThu6tuZyBxdWFuIHPDoXQ6DQoNCiQkDQpMKFx0aGV0YSkgPSBccHJvZF97aT0xfV57bn0gUCh5X2kgXG1pZCBcdGhldGEpDQokJA0KDQogKipCxrDhu5tjIDM6IFTDrW5oIGxvZy1saWtlbGlob29kKioNCg0KU+G7rSBk4bulbmcgbG9nYXJpdCB04buxIG5oacOqbiDEkeG7gyBiaeG6v24gxJHhu5VpIHTDrWNoIHRow6BuaCB04buVbmcsIHRodeG6rW4gdGnhu4duIGNobyB2aeG7h2MgdOG7kWkgxrB1Og0KDQokJA0KXGxvZyBMKFx0aGV0YSkgPSBcc3VtX3tpPTF9XntufSBcbG9nIFAoeV9pIFxtaWQgXHRoZXRhKQ0KJCQNCg0KICoqQsaw4bubYyA0OiBU4buRaSDEkWEgaMOzYSBsb2ctbGlrZWxpaG9vZCoqDQoNCi0gVMOtbmggxJHhuqFvIGjDoG0gcmnDqm5nIHRoZW8gdGhhbSBz4buRICRcdGhldGEkOg0KDQokJA0KXGZyYWN7ZH17ZFx0aGV0YX0gXGxvZyBMKFx0aGV0YSkNCiQkDQoNCi0gR2nhuqNpIHBoxrDGoW5nIHRyw6xuaCDEkeG6oW8gaMOgbSBi4bqtYyBuaOG6pXQ6DQoNCiQkDQpcZnJhY3tkfXtkXHRoZXRhfSBcbG9nIEwoXHRoZXRhKSA9IDANCiQkDQoNCi0gS2nhu4NtIHRyYSDEkWnhu4F1IGtp4buHbiBj4buxYyDEkeG6oWk6DQogIC0gxJDhuqFvIGjDoG0gYuG6rWMgaGFpIHBo4bqjaSDDom06ICRcZnJhY3tkXjJ9e2RcdGhldGFeMn0gXGxvZyBMKFx0aGV0YSkgPCAwJCwgIA0KICAtIEhv4bq3YyBz4butIGThu6VuZyBjw6FjIHBoxrDGoW5nIHBow6FwIHPhu5EgKG5oxrAgTmV3dG9uLVJhcGhzb24pIMSR4buDIHTDrG0gY+G7sWMgdHLhu4suDQoNCiMjICoqNC40IOG7qG5nIGThu6VuZyBNTEUgdHJvbmcgSOG7k2kgcXV5IExvZ2lzdGljKioNCg0KVHJvbmcgY8OhYyBtw7QgaMOsbmggKipo4buTaSBxdXkgbG9naXN0aWMqKiDigJMgbsahaSBiaeG6v24gcGjhuqNuIGjhu5NpICRZJCBsw6AgKipuaOG7iyBwaMOibioqICgwLzEpIOKAkyAqKnBoxrDGoW5nIHBow6FwIMaw4bubYyBsxrDhu6NuZyBo4bujcCBsw70gdOG7kWkgxJFhIChNTEUpKiogxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgxrDhu5tjIGzGsOG7o25nIGPDoWMgaOG7hyBz4buRIGjhu5NpIHF1eSAkXGJldGEkIHNhbyBjaG8gKip4w6FjIHN14bqldCBk4buxIMSRb8OhbioqOg0KDQokJA0KUChZID0gMSBcbWlkIFgpID0gXGZyYWN7MX17MSArIFxleHBbLShcYmV0YV8wICsgXGJldGFfMSBYXzEgKyBcY2RvdHMgKyBcYmV0YV9rIFhfayldfQ0KJCQNCg0KcGjDuSBo4bujcCBuaOG6pXQgduG7m2kgZOG7ryBsaeG7h3UgcXVhbiBzw6F0Lg0KDQoNCioqSMOgbSBsb2ctbGlrZWxpaG9vZCB0cm9uZyBo4buTaSBxdXkgbG9naXN0aWMqKg0KDQpW4bubaSAkcF9pID0gUChZX2kgPSAxIFxtaWQgWF9pKSQsIGjDoG0gbG9nLWxpa2VsaWhvb2QgY8OzIGThuqFuZzoNCg0KJCQNCkxMKFxib2xkc3ltYm9se1xiZXRhfSkgPSBcc3VtX3tpPTF9XntufSBcbGVmdFsgeV9pIFxsb2cocF9pKSArICgxIC0geV9pKSBcbG9nKDEgLSBwX2kpIFxyaWdodF0NCiQkDQoNCkjDoG0gbG9nLWxpa2VsaWhvb2QgbsOgeSDEkcOhbmggZ2nDoSDEkeG7mSBwaMO5IGjhu6NwIGdp4buvYSBtw7QgaMOsbmggbG9naXN0aWMgdsOgIGThu68gbGnhu4d1IHF1YW4gc8OhdC4NCg0KDQoqKsav4bubYyBsxrDhu6NuZyAkXGhhdHtcYmV0YX0kKioNCg0KQ8OhYyBo4buHIHPhu5EgaOG7k2kgcXV5ICRcaGF0e1xiZXRhfSQgxJHGsOG7o2MgdMOsbSBi4bqxbmcgY8OhY2ggKip04buRaSDEkWEgaMOzYSBow6BtIGxvZy1saWtlbGlob29kKiosIHRow7RuZyBxdWEgY8OhYyB0aHXhuq10IHRvw6FuIHThu5FpIMawdSBz4buRIG5oxrA6DQoNCi0gKipOZXd0b24tUmFwaHNvbioqDQotICoqRmlzaGVyIFNjb3JpbmcqKg0KLSAqKkdyYWRpZW50IERlc2NlbnQqKiwgdi52Lg0KDQoNCiMjICAqKjQuNTUgVOG7lW5nIGvhur90KioNCg0KDQpQaMawxqFuZyBwaMOhcCDGsOG7m2MgbMaw4bujbmcgaOG7o3AgbMO9IHThu5FpIMSRYSAoTUxFKSBsw6AgY8O0bmcgY+G7pSB0cnVuZyB0w6JtIHRyb25nIHRo4buRbmcga8OqIGhp4buHbiDEkeG6oWksIMSR4bq3YyBiaeG7h3QgcXVhbiB0cuG7jW5nIHRyb25nIGPDoWMgYsOgaSB0b8OhbiBwaMOibiB0w61jaCBk4buvIGxp4buHdSDEkeG7i25oIHTDrW5oIGhv4bq3YyBtw7QgaMOsbmggZOG7sSBiw6FvIHjDoWMgc3XhuqV0LiBW4bubaSBraOG6oyBuxINuZyDDoXAgZOG7pW5nIGxpbmggaG/huqF0LCBraOG6oyBuxINuZyBo4buZaSB04bulIHThu5F0IHbDoCB0w61uaCB04buRaSDGsHUgdHJvbmcgxJFp4buBdSBraeG7h24gbeG6q3UgbOG7m24sIE1MRSBraMO0bmcgY2jhu4kgcGjDuSBo4bujcCB24bubaSBjw6FjIGLDoGkgdG/DoW4gxJHGoW4gZ2nhuqNuIG3DoCBjw7JuIGzDoCB4xrDGoW5nIHPhu5FuZyBjaG8gY8OhYyBtw7QgaMOsbmggcGjhu6ljIHThuqFwIG5oxrAgaOG7k2kgcXV5IGxvZ2lzdGljLCBtw7QgaMOsbmggcGjDom4gbG/huqFpIHLhu51pIHLhuqFjLCBob+G6t2MgbcO0IGjDrG5oIOG6qW4gTWFya292Lg0KDQpT4buxIHRow6BuaCBjw7RuZyB0cm9uZyB2aeG7h2Mgw6FwIGThu6VuZyBNTEUgxJHDsmkgaOG7j2kgc+G7sSBoaeG7g3UgYmnhur90IHPDonUgc+G6r2MgduG7gSBi4bqjbiBjaOG6pXQgbcO0IGjDrG5oIGjDs2EgeMOhYyBzdeG6pXQsIGPFqW5nIG5oxrAgbsSDbmcgbOG7sWMgdMOtbmggdG/DoW4gY2jDrW5oIHjDoWMgdsOgIGhp4buHdSBxdeG6oyDigJMgxJHhurdjIGJp4buHdCBraGkgdHJp4buDbiBraGFpIHRyb25nIGPDoWMgbcO0aSB0csaw4budbmcgZOG7ryBsaeG7h3UgbOG7m24sIMSRYSBjaGnhu4F1Lg0K