Giới thiệu các biến định tính sẽ sử dụng

Bộ dữ liệu bao gồm 4165, 14 biến, trong đó sử dụng 2 biến định tính là:

  • Biến married: Biến phân loại. Cá nhân có kết hôn không?

  • Biến gender: phân loại giới tính của cá nhân đó là nam hay nữ.

Khai báo các package cần thiết

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(epitools)
library(DescTools)
library(DT)
library(energy)
library(ggplot2)
library(AER)
## Loading required package: car
## Loading required package: carData
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:DescTools':
## 
##     Recode
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
## 
## The following object is masked from 'package:purrr':
## 
##     some
## 
## Loading required package: lmtest
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## 
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## Loading required package: sandwich
## Loading required package: survival
## 
## Attaching package: 'survival'
## 
## The following object is masked from 'package:epitools':
## 
##     ratetable

Bảng dữ liệu

options(digits = 4)
data("PSID7682")
th <- PSID7682
datatable(th)

1. Bảng tần số

Lập bảng tần số cho biến married

table(th$married)
## 
##   no  yes 
##  773 3392
  • Tỷ lệ kết hôn chiếm số lượng lớn, có 3392 người đã kết hôn (chiếm 81.4%), 773 người chưa kết hôn (18.6%), cho thấy là có sự chênh lệch rất lớn giữa người đã kết hôn và người chưa kết hôn (62.8%)

Lập bảng tần biến cho biến gender

table(th$gender)
## 
##   male female 
##   3696    469
  • Nhận xét, nam là 3696 người (chiếm khoảng 88.7%), nữ là 469 người (chiếm 11.3%), giới tính tương đối đồng đều, với nam và nữ không chênh lệch quá nhiều (chênh lệch khoảng 77.4%).
tp <- th
tp <- table(th$married, th$gender)

addmargins(tp)
##      
##       male female  Sum
##   no   316    457  773
##   yes 3380     12 3392
##   Sum 3696    469 4165
tp <- prop.table(tp)
tp
##      
##           male   female
##   no  0.075870 0.109724
##   yes 0.811525 0.002881
  • Nhận xét: Trong số nam, có khoảng 81.15% đã kết hôn, trong khi đó, chỉ có khoảng 7.58% không kết hôn. Trong số nữ, tỷ lệ kết hôn khoảng 0.29% thấp hơn rất nhiều so với nam giới, và tỷ lệ không kết hôn 10.97%.

2. Đồ thị

2.1. Đồ thị cột cho biến married

th |> ggplot(aes(married))+geom_bar(color = "blue", fill = "red")

th |> ggplot(aes(x = th$married, y = after_stat(count))) + geom_bar(fill = 'red') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'green', vjust = - .5) + theme_classic() + labs(x = 'Giới tính', y = 'Số người')
## Warning: Use of `th$married` is discouraged.
## ℹ Use `married` instead.
## Use of `th$married` is discouraged.
## ℹ Use `married` instead.

th |> ggplot(aes(married)) +
  geom_bar(aes(y = (..count..)/sum(..count..)),color = "blue", fill = "red") +
  ylab('Tỷ lệ %') + xlab('Tình trạng hôn nhân')
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

2.2. Dồ thị cột cho biến gender

th |> ggplot(aes(gender))+geom_bar(color = "green", fill = "blue")

th |> ggplot(aes(x = th$gender, y = after_stat(count))) + geom_bar(fill = 'blue') + geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'green', vjust = - .5) + theme_classic() + labs(x = 'Giới tính', y = 'Số người')
## Warning: Use of `th$gender` is discouraged.
## ℹ Use `gender` instead.
## Use of `th$gender` is discouraged.
## ℹ Use `gender` instead.

th |> ggplot(aes(gender)) +
  geom_bar(aes(y = (..count..)/sum(..count..)),color = "green", fill = "blue") +
  ylab('Tỷ lệ %') + xlab('Giới tính')

2.3. Đồ thị bánh cho biến married

tp <- th
tp <- table(th$married)
tp <- th |> group_by(married) |> summarise(freq = n()) |> mutate(tp, per = freq/sum(freq))
tp |> ggplot(aes(x = '', y = per, fill = married)) +
  geom_bar(stat = 'identity') + 
  coord_polar('y')

2.4. Đồ thị bánh cho biến gender

tp <- th
tp <- table(th$gender)
tp <- th |> group_by(gender) |> summarise(freq = n()) |> mutate(tp, per = freq/sum(freq))
tp |> ggplot(aes(x = '', y = per, fill = )) +
  geom_bar(stat = 'identity') + 
  coord_polar('y')

h <- data.frame(th$gender,th$married)
ggplot(th, aes(x = th$gender, fill = th$married)) +
  geom_bar(position = "dodge") +
  labs(title = "Gender vs Marital Status",
       x = "Gender",
       y = "Count",
       fill = "Marital Status") +
  theme_minimal()
## Warning: Use of `th$gender` is discouraged.
## ℹ Use `gender` instead.
## Warning: Use of `th$married` is discouraged.
## ℹ Use `married` instead.

3. Ước lượng tỉ lệ

3.1. Ước lượng tỉ lệ cho cá nhân đã kết hôn

mar_mal <- table(th[th$married == "yes", ]$gender)
mar_mal
## 
##   male female 
##   3380     12
prop.test(mar_mal["male"], sum(mar_mal), p = 0.4)
## 
##  1-sample proportions test with continuity correction
## 
## data:  mar_mal["male"] out of sum(mar_mal), null probability 0.4
## X-squared = 5026, df = 1, p-value <2e-16
## alternative hypothesis: true p is not equal to 0.4
## 95 percent confidence interval:
##  0.9936 0.9981
## sample estimates:
##      p 
## 0.9965
prop.test(mar_mal["female"], sum(mar_mal), p = 0.6)
## 
##  1-sample proportions test with continuity correction
## 
## data:  mar_mal["female"] out of sum(mar_mal), null probability 0.6
## X-squared = 5026, df = 1, p-value <2e-16
## alternative hypothesis: true p is not equal to 0.6
## 95 percent confidence interval:
##  0.001918 0.006360
## sample estimates:
##        p 
## 0.003538

3.2. Ước lượng tỉ lệ cho cá nhân chưa kết hôn

mar_fe <- table(th[th$married == "no", ]$gender)
mar_fe
## 
##   male female 
##    316    457
prop.test(mar_fe["male"], sum(mar_fe), p = 0.4)
## 
##  1-sample proportions test with continuity correction
## 
## data:  mar_fe["male"] out of sum(mar_fe), null probability 0.4
## X-squared = 0.21, df = 1, p-value = 0.6
## alternative hypothesis: true p is not equal to 0.4
## 95 percent confidence interval:
##  0.3740 0.4445
## sample estimates:
##      p 
## 0.4088
prop.test(mar_fe["female"], sum(mar_fe), p = 0.6)
## 
##  1-sample proportions test with continuity correction
## 
## data:  mar_fe["female"] out of sum(mar_fe), null probability 0.6
## X-squared = 0.21, df = 1, p-value = 0.6
## alternative hypothesis: true p is not equal to 0.6
## 95 percent confidence interval:
##  0.5555 0.6260
## sample estimates:
##      p 
## 0.5912

4. Ước lượng chênh lệch tỷ lệ

th_yes <- th[th$married == "đakethon",]
th_no <- th[th$married == "chuakethon",]

dakethon_nam <- th_yes[th_yes$gender == 'nam',]
chuakethon_nu <- th_no[th_no$gender == 'nu' ,]

a <- c(nrow(th_yes), nrow(th_no))
a
## [1] 0 0
b <- c(nrow(dakethon_nam), nrow(chuakethon_nu))
b
## [1] 0 0

5. Ước lượng Relative risk

d <- table(th$gender,th$married)
addmargins(d)
##         
##            no  yes  Sum
##   male    316 3380 3696
##   female  457   12  469
##   Sum     773 3392 4165
RelRisk(d)
## [1] 0.08774

Nhận xét : RelRisk được tính toán cho việc kết hôn giữa nam và nữ. Nếu RelRisk = 0.08774 như trong trường hợp này, điều này có thể được hiểu là nam có một mức độ rủi ro tương đối cao hơn một chút so với nữ khi liên quan đến việc kết hôn, nhưng sự khác biệt không lớn.

Khoảng ước lượng cho Relative risk

m <- matrix(c(316 ,457 ,3380 ,12),nrow = 2)
RelRisk(m, conf.level = .95)
## rel. risk    lwr.ci    upr.ci 
##   0.08774   0.07885   0.09755

Ước lượng cho Tỷ lệ Rủi ro Tương đối giữa nhóm đã kết hôn và nhóm chưa kết hôn là khoảng 0.09.

Khoảng tin cậy 95% cho ước lượng này là từ khoảng 0.079 đến 0.1. Điều này ngụ ý rằng có 95% khả năng rằng giá trị thực sự của Tỷ lệ Rủi ro Tương đối nằm trong khoảng từ 0.079 đến 0.1.

6. Odd ratio

OddsRatio(d, conf.level = .95)
## odds ratio     lwr.ci     upr.ci 
##   0.002455   0.001368   0.004405

Odds Ratio (Tỷ lệ cơ hội): ước lượng cho tỷ lệ giữa xác suất chênh lệch giữa người nam và nữ (giữa đã kết hôn và chưa kết hôn) là 0.002455

Lwr.ci và Upr.ci: Đây là khoảng tin cậy 95% cho ước lượng của tỷ lệ cơ hội. Nó cho biết phạm vi mà ước lượng tỷ lệ cơ hội có thể nằm trong đó với mức độ tin cậy 95%. Trong trường hợp này, khoảng tin cậy này từ 0.001368 đến 0.004405.

oddsratio(d)
## $data
##         
##           no  yes Total
##   male   316 3380  3696
##   female 457   12   469
##   Total  773 3392  4165
## 
## $measure
##         odds ratio with 95% C.I.
##          estimate    lower    upper
##   male   1.000000       NA       NA
##   female 0.002496 0.001315 0.004279
## 
## $p.value
##         two-sided
##          midp.exact fisher.exact chi.square
##   male           NA           NA         NA
##   female          0            0          0
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
epitab(d,method = "oddsratio")
## $tab
##         
##           no     p0  yes       p1 oddsratio    lower    upper p.value
##   male   316 0.4088 3380 0.996462  1.000000       NA       NA      NA
##   female 457 0.5912   12 0.003538  0.002455 0.001368 0.004405       0
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

từ bảng ước lượng trên, cho thấy: - giá trị p

7. Hồi quy

Trước tiên, tôi tiến hành kiểm định tính độc lập cho hai biến như sau:

\(H_0\) = Giữa hai biến là độc lập

\(H_1\) = Giữa hai biến có liên quan với nhau

chisq.test(table(PSID7682$gender, PSID7682$married))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(PSID7682$gender, PSID7682$married)
## X-squared = 2170, df = 1, p-value <2e-16

Kết quả:

  • Giá trị p-value = 0 < 5% cho thấy giới tính có ảnh hưởng đến kết hôn

Sau đó, để làm rõ sự ảnh hưởng của giới tính đến khả năng kết hôn, tôi tiến hành phân tích nhị phân Logit như sau:

p <- glm(factor(married) ~ gender, family = binomial(link = "logit"), data = th)
p
## 
## Call:  glm(formula = factor(married) ~ gender, family = binomial(link = "logit"), 
##     data = th)
## 
## Coefficients:
##  (Intercept)  genderfemale  
##         2.37         -6.01  
## 
## Degrees of Freedom: 4164 Total (i.e. Null);  4163 Residual
## Null Deviance:       4000 
## Residual Deviance: 2270  AIC: 2270

Ta có hàm hồi quy sau: y = 2.37 - 6.01*x (Với x là Gender (giới tính))

Nhận xét:

  • Sự thay đổi giới tính nam và nữ có khác biệt lớn về khả năng kết hôn với hệ số hồi quy là - 6,01

=> Kết quả cho thấy, nếu là nam thì khả năng sống sót là cao hơn trung bình khoảng 6,01 lần so với giới tính nữ.

LS0tDQp0aXRsZTogIkLDgEkgVOG6rFAiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgcGRmX2RvY3VtZW50Og0KICAgIGV4dHJhX2RlcGVuZGVuY2llczoNCiAgICAgIHZpZXRuYW06IHV0ZjgNCiAgICB0b2M6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogIHdvcmRfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KZ2VvbWV0cnk6DQogICAgICAtIGlubmVyPTNjbQ0KICAgICAgLSBvdXRlcj00Y20NCiAgICAgIC0gdG9wPTNjbQ0KICAgICAgLSBib3R0b209NGNtDQogICAgICAtIGhlYWRzZXA9MjJwdA0KICAgICAgLSBoZWFkaGVpZ2h0PTExcHQNCiAgICAgIC0gZm9vdHNraXA9MzNwdA0KICAgICAgLSBpZ25vcmVoZWFkDQogICAgICAtIGlnbm9yZWZvb3QNCiAgICAgIC0gaGVpZ2h0cm91bmRlZA0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogNzINCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgb3B0aW9ucyhkaWdpdHMgPSA0KSwgIGF0dHIuc291cmNlPScubnVtYmVyTGluZXMnKQ0KYGBgDQoNCiMgR2nhu5tpIHRoaeG7h3UgY8OhYyBiaeG6v24gxJHhu4tuaCB0w61uaCBz4bq9IHPhu60gZOG7pW5nDQoNCkLhu5kgZOG7ryBsaeG7h3UgYmFvIGfhu5NtIDQxNjUsIDE0IGJp4bq/biwgdHJvbmcgxJHDsyBz4butIGThu6VuZyAyIGJp4bq/biDEkeG7i25oIHTDrW5oIGzDoDoNCg0KLSBCaeG6v24gbWFycmllZDogQmnhur9uIHBow6JuIGxv4bqhaS4gQ8OhIG5ow6JuIGPDsyBr4bq/dCBow7RuIGtow7RuZz8NCg0KLSBCaeG6v24gZ2VuZGVyOiBwaMOibiBsb+G6oWkgZ2nhu5tpIHTDrW5oIGPhu6dhIGPDoSBuaMOibiDEkcOzIGzDoCBuYW0gaGF5IG7hu68uDQoNCktoYWkgYsOhbyBjw6FjIHBhY2thZ2UgY+G6p24gdGhp4bq/dA0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZXBpdG9vbHMpDQpsaWJyYXJ5KERlc2NUb29scykNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KGVuZXJneSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoQUVSKQ0KYGBgDQpC4bqjbmcgZOG7ryBsaeG7h3UNCmBgYHtyfQ0Kb3B0aW9ucyhkaWdpdHMgPSA0KQ0KZGF0YSgiUFNJRDc2ODIiKQ0KdGggPC0gUFNJRDc2ODINCmRhdGF0YWJsZSh0aCkNCmBgYA0KIyAxLiBC4bqjbmcgdOG6p24gc+G7kQ0KDQpM4bqtcCBi4bqjbmcgdOG6p24gc+G7kSBjaG8gYmnhur9uIG1hcnJpZWQNCg0KYGBge3J9DQp0YWJsZSh0aCRtYXJyaWVkKQ0KYGBgDQotIFThu7cgbOG7hyBr4bq/dCBow7RuIGNoaeG6v20gc+G7kSBsxrDhu6NuZyBs4bubbiwgY8OzIDMzOTIgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIChjaGnhur9tIDgxLjQlKSwgNzczIG5nxrDhu51pIGNoxrBhIGvhur90IGjDtG4gKDE4LjYlKSwgY2hvIHRo4bqleSBsw6AgY8OzIHPhu7EgY2jDqm5oIGzhu4djaCBy4bqldCBs4bubbiBnaeG7r2EgbmfGsOG7nWkgxJHDoyBr4bq/dCBow7RuIHbDoCBuZ8aw4budaSBjaMawYSBr4bq/dCBow7RuICg2Mi44JSkNCg0KTOG6rXAgYuG6o25nIHThuqduIGJp4bq/biBjaG8gYmnhur9uIGdlbmRlcg0KDQpgYGB7cn0NCnRhYmxlKHRoJGdlbmRlcikNCmBgYA0KDQotIE5o4bqtbiB4w6l0LCBuYW0gbMOgIDM2OTYgbmfGsOG7nWkgKGNoaeG6v20ga2hv4bqjbmcgODguNyUpLCBu4buvIGzDoCA0NjkgbmfGsOG7nWkgKGNoaeG6v20gMTEuMyUpLCBnaeG7m2kgdMOtbmggdMawxqFuZyDEkeG7kWkgxJHhu5NuZyDEkeG7gXUsIHbhu5tpIG5hbSB2w6AgbuG7ryBraMO0bmcgY2jDqm5oIGzhu4djaCBxdcOhIG5oaeG7gXUgKGNow6puaCBs4buHY2gga2hv4bqjbmcgNzcuNCUpLg0KDQpgYGB7cn0NCnRwIDwtIHRoDQp0cCA8LSB0YWJsZSh0aCRtYXJyaWVkLCB0aCRnZW5kZXIpDQoNCmFkZG1hcmdpbnModHApDQpgYGANCmBgYHtyfQ0KdHAgPC0gcHJvcC50YWJsZSh0cCkNCnRwDQpgYGANCg0KLSBOaOG6rW4geMOpdDogVHJvbmcgc+G7kSBuYW0sIGPDsyBraG/huqNuZyA4MS4xNSUgxJHDoyBr4bq/dCBow7RuLCB0cm9uZyBraGkgxJHDsywgY2jhu4kgY8OzIGtob+G6o25nIDcuNTglIGtow7RuZyBr4bq/dCBow7RuLiBUcm9uZyBz4buRIG7hu68sIHThu7cgbOG7hyBr4bq/dCBow7RuIGtob+G6o25nIDAuMjklIHRo4bqlcCBoxqFuIHLhuqV0IG5oaeG7gXUgc28gduG7m2kgbmFtIGdp4bubaSwgdsOgIHThu7cgbOG7hyBraMO0bmcga+G6v3QgaMO0biAxMC45NyUuDQoNCiMgMi4gxJDhu5MgdGjhu4sNCg0KIyMgMi4xLiDEkOG7kyB0aOG7iyBj4buZdCBjaG8gYmnhur9uIG1hcnJpZWQNCg0KYGBge3J9DQp0aCB8PiBnZ3Bsb3QoYWVzKG1hcnJpZWQpKStnZW9tX2Jhcihjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJyZWQiKQ0KYGBgDQoNCmBgYHtyfQ0KdGggfD4gZ2dwbG90KGFlcyh4ID0gdGgkbWFycmllZCwgeSA9IGFmdGVyX3N0YXQoY291bnQpKSkgKyBnZW9tX2JhcihmaWxsID0gJ3JlZCcpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdncmVlbicsIHZqdXN0ID0gLSAuNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHggPSAnR2nhu5tpIHTDrW5oJywgeSA9ICdT4buRIG5nxrDhu51pJykNCmBgYA0KDQoNCmBgYHtyfQ0KdGggfD4gZ2dwbG90KGFlcyhtYXJyaWVkKSkgKw0KICBnZW9tX2JhcihhZXMoeSA9ICguLmNvdW50Li4pL3N1bSguLmNvdW50Li4pKSxjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJyZWQiKSArDQogIHlsYWIoJ1Thu7cgbOG7hyAlJykgKyB4bGFiKCdUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4nKQ0KYGBgDQoNCiMjIDIuMi4gROG7kyB0aOG7iyBj4buZdCBjaG8gYmnhur9uIGdlbmRlcg0KDQpgYGB7cn0NCnRoIHw+IGdncGxvdChhZXMoZ2VuZGVyKSkrZ2VvbV9iYXIoY29sb3IgPSAiZ3JlZW4iLCBmaWxsID0gImJsdWUiKQ0KYGBgDQoNCmBgYHtyfQ0KdGggfD4gZ2dwbG90KGFlcyh4ID0gdGgkZ2VuZGVyLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArIGdlb21fYmFyKGZpbGwgPSAnYmx1ZScpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdncmVlbicsIHZqdXN0ID0gLSAuNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHggPSAnR2nhu5tpIHTDrW5oJywgeSA9ICdT4buRIG5nxrDhu51pJykNCmBgYA0KDQpgYGB7cn0NCnRoIHw+IGdncGxvdChhZXMoZ2VuZGVyKSkgKw0KICBnZW9tX2JhcihhZXMoeSA9ICguLmNvdW50Li4pL3N1bSguLmNvdW50Li4pKSxjb2xvciA9ICJncmVlbiIsIGZpbGwgPSAiYmx1ZSIpICsNCiAgeWxhYignVOG7tyBs4buHICUnKSArIHhsYWIoJ0dp4bubaSB0w61uaCcpDQpgYGANCg0KIyMgMi4zLiDEkOG7kyB0aOG7iyBiw6FuaCBjaG8gYmnhur9uIG1hcnJpZWQNCg0KYGBge3J9DQp0cCA8LSB0aA0KdHAgPC0gdGFibGUodGgkbWFycmllZCkNCnRwIDwtIHRoIHw+IGdyb3VwX2J5KG1hcnJpZWQpIHw+IHN1bW1hcmlzZShmcmVxID0gbigpKSB8PiBtdXRhdGUodHAsIHBlciA9IGZyZXEvc3VtKGZyZXEpKQ0KdHAgfD4gZ2dwbG90KGFlcyh4ID0gJycsIHkgPSBwZXIsIGZpbGwgPSBtYXJyaWVkKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyANCiAgY29vcmRfcG9sYXIoJ3knKQ0KYGBgDQoNCiMjIDIuNC4gxJDhu5MgdGjhu4sgYsOhbmggY2hvIGJp4bq/biBnZW5kZXINCg0KYGBge3J9DQp0cCA8LSB0aA0KdHAgPC0gdGFibGUodGgkZ2VuZGVyKQ0KdHAgPC0gdGggfD4gZ3JvdXBfYnkoZ2VuZGVyKSB8PiBzdW1tYXJpc2UoZnJlcSA9IG4oKSkgfD4gbXV0YXRlKHRwLCBwZXIgPSBmcmVxL3N1bShmcmVxKSkNCnRwIHw+IGdncGxvdChhZXMoeCA9ICcnLCB5ID0gcGVyLCBmaWxsID0gKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyANCiAgY29vcmRfcG9sYXIoJ3knKQ0KYGBgDQoNCmBgYHtyfQ0KaCA8LSBkYXRhLmZyYW1lKHRoJGdlbmRlcix0aCRtYXJyaWVkKQ0KZ2dwbG90KHRoLCBhZXMoeCA9IHRoJGdlbmRlciwgZmlsbCA9IHRoJG1hcnJpZWQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHRpdGxlID0gIkdlbmRlciB2cyBNYXJpdGFsIFN0YXR1cyIsDQogICAgICAgeCA9ICJHZW5kZXIiLA0KICAgICAgIHkgPSAiQ291bnQiLA0KICAgICAgIGZpbGwgPSAiTWFyaXRhbCBTdGF0dXMiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMgMy4gxq/hu5tjIGzGsOG7o25nIHThu4kgbOG7hw0KIA0KIyMgMy4xLiDGr+G7m2MgbMaw4bujbmcgdOG7iSBs4buHIGNobyBjw6EgbmjDom4gxJHDoyBr4bq/dCBow7RuDQoNCmBgYHtyfQ0KbWFyX21hbCA8LSB0YWJsZSh0aFt0aCRtYXJyaWVkID09ICJ5ZXMiLCBdJGdlbmRlcikNCm1hcl9tYWwNCmBgYA0KDQpgYGB7cn0NCnByb3AudGVzdChtYXJfbWFsWyJtYWxlIl0sIHN1bShtYXJfbWFsKSwgcCA9IDAuNCkNCmBgYA0KDQpgYGB7cn0NCnByb3AudGVzdChtYXJfbWFsWyJmZW1hbGUiXSwgc3VtKG1hcl9tYWwpLCBwID0gMC42KQ0KYGBgDQoNCiMjIDMuMi4gxq/hu5tjIGzGsOG7o25nIHThu4kgbOG7hyBjaG8gY8OhIG5ow6JuIGNoxrBhIGvhur90IGjDtG4NCg0KYGBge3J9DQptYXJfZmUgPC0gdGFibGUodGhbdGgkbWFycmllZCA9PSAibm8iLCBdJGdlbmRlcikNCm1hcl9mZQ0KYGBgDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KG1hcl9mZVsibWFsZSJdLCBzdW0obWFyX2ZlKSwgcCA9IDAuNCkNCmBgYA0KDQpgYGB7cn0NCnByb3AudGVzdChtYXJfZmVbImZlbWFsZSJdLCBzdW0obWFyX2ZlKSwgcCA9IDAuNikNCmBgYA0KDQojIDQuIMav4bubYyBsxrDhu6NuZyBjaMOqbmggbOG7h2NoIHThu7cgbOG7hw0KDQpgYGB7cn0NCnRoX3llcyA8LSB0aFt0aCRtYXJyaWVkID09ICLEkWFrZXRob24iLF0NCnRoX25vIDwtIHRoW3RoJG1hcnJpZWQgPT0gImNodWFrZXRob24iLF0NCg0KZGFrZXRob25fbmFtIDwtIHRoX3llc1t0aF95ZXMkZ2VuZGVyID09ICduYW0nLF0NCmNodWFrZXRob25fbnUgPC0gdGhfbm9bdGhfbm8kZ2VuZGVyID09ICdudScgLF0NCg0KYSA8LSBjKG5yb3codGhfeWVzKSwgbnJvdyh0aF9ubykpDQphDQpgYGANCg0KYGBge3J9DQpiIDwtIGMobnJvdyhkYWtldGhvbl9uYW0pLCBucm93KGNodWFrZXRob25fbnUpKQ0KYg0KYGBgDQoNCiMgNS4gxq/hu5tjIGzGsOG7o25nIFJlbGF0aXZlIHJpc2sNCg0KYGBge3J9DQpkIDwtIHRhYmxlKHRoJGdlbmRlcix0aCRtYXJyaWVkKQ0KYWRkbWFyZ2lucyhkKQ0KYGBgDQoNCmBgYHtyfQ0KUmVsUmlzayhkKQ0KYGBgDQoNCk5o4bqtbiB4w6l0IDogUmVsUmlzayDEkcaw4bujYyB0w61uaCB0b8OhbiBjaG8gdmnhu4djIGvhur90IGjDtG4gZ2nhu69hIG5hbSB2w6AgbuG7ry4gTuG6v3UgUmVsUmlzayA9IDAuMDg3NzQgbmjGsCB0cm9uZyB0csaw4budbmcgaOG7o3AgbsOgeSwgxJFp4buBdSBuw6B5IGPDsyB0aOG7gyDEkcaw4bujYyBoaeG7g3UgbMOgIG5hbSBjw7MgbeG7mXQgbeG7qWMgxJHhu5kgcuG7p2kgcm8gdMawxqFuZyDEkeG7kWkgY2FvIGjGoW4gbeG7mXQgY2jDunQgc28gduG7m2kgbuG7ryBraGkgbGnDqm4gcXVhbiDEkeG6v24gdmnhu4djIGvhur90IGjDtG4sIG5oxrBuZyBz4buxIGtow6FjIGJp4buHdCBraMO0bmcgbOG7m24uDQoNCktob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gUmVsYXRpdmUgcmlzaw0KDQpgYGB7cn0NCm0gPC0gbWF0cml4KGMoMzE2ICw0NTcgLDMzODAgLDEyKSxucm93ID0gMikNClJlbFJpc2sobSwgY29uZi5sZXZlbCA9IC45NSkNCmBgYA0KDQrGr+G7m2MgbMaw4bujbmcgY2hvIFThu7cgbOG7hyBS4bunaSBybyBUxrDGoW5nIMSR4buRaSBnaeG7r2EgbmjDs20gxJHDoyBr4bq/dCBow7RuIHbDoCBuaMOzbSBjaMawYSBr4bq/dCBow7RuIGzDoCBraG/huqNuZyAwLjA5Lg0KDQpLaG/huqNuZyB0aW4gY+G6rXkgOTUlIGNobyDGsOG7m2MgbMaw4bujbmcgbsOgeSBsw6AgdOG7qyBraG/huqNuZyAwLjA3OSDEkeG6v24gMC4xLiDEkGnhu4F1IG7DoHkgbmfhu6Ugw70gcuG6sW5nIGPDsyA5NSUga2jhuqMgbsSDbmcgcuG6sW5nIGdpw6EgdHLhu4sgdGjhu7FjIHPhu7EgY+G7p2EgVOG7tyBs4buHIFLhu6dpIHJvIFTGsMahbmcgxJHhu5FpIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMC4wNzkgxJHhur9uIDAuMS4NCg0KDQojIDYuIE9kZCByYXRpbw0KDQpgYGB7cn0NCk9kZHNSYXRpbyhkLCBjb25mLmxldmVsID0gLjk1KQ0KYGBgDQpPZGRzIFJhdGlvIChU4bu3IGzhu4cgY8ahIGjhu5lpKTogxrDhu5tjIGzGsOG7o25nIGNobyB04bu3IGzhu4cgZ2nhu69hIHjDoWMgc3XhuqV0IGNow6puaCBs4buHY2ggZ2nhu69hIG5nxrDhu51pIG5hbSB2w6AgbuG7ryAoZ2nhu69hIMSRw6Mga+G6v3QgaMO0biB2w6AgY2jGsGEga+G6v3QgaMO0bikgbMOgIDAuMDAyNDU1DQoNCkx3ci5jaSB2w6AgVXByLmNpOiDEkMOieSBsw6Aga2hv4bqjbmcgdGluIGPhuq15IDk1JSBjaG8gxrDhu5tjIGzGsOG7o25nIGPhu6dhIHThu7cgbOG7hyBjxqEgaOG7mWkuIE7DsyBjaG8gYmnhur90IHBo4bqhbSB2aSBtw6AgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBjxqEgaOG7mWkgY8OzIHRo4buDIG7hurFtIHRyb25nIMSRw7MgduG7m2kgbeG7qWMgxJHhu5kgdGluIGPhuq15IDk1JS4gVHJvbmcgdHLGsOG7nW5nIGjhu6NwIG7DoHksIGtob+G6o25nIHRpbiBj4bqteSBuw6B5IHThu6sgMC4wMDEzNjggxJHhur9uIDAuMDA0NDA1Lg0KDQpgYGB7cn0NCm9kZHNyYXRpbyhkKQ0KYGBgDQoNCmBgYHtyfQ0KZXBpdGFiKGQsbWV0aG9kID0gIm9kZHNyYXRpbyIpDQpgYGANCg0KdOG7qyBi4bqjbmcgxrDhu5tjIGzGsOG7o25nIHRyw6puLCBjaG8gdGjhuqV5Og0KLSBnacOhIHRy4buLIHANCg0KIyA3LiBI4buTaSBxdXkNCg0KVHLGsOG7m2MgdGnDqm4sIHTDtGkgdGnhur9uIGjDoG5oIGtp4buDbSDEkeG7i25oIHTDrW5oIMSR4buZYyBs4bqtcCBjaG8gaGFpIGJp4bq/biBuaMawIHNhdToNCg0KICRIXzAkID0gR2nhu69hIGhhaSBiaeG6v24gbMOgIMSR4buZYyBs4bqtcA0KDQogJEhfMSQgPSBHaeG7r2EgaGFpIGJp4bq/biBjw7MgbGnDqm4gcXVhbiB24bubaSBuaGF1DQogDQpgYGB7cn0NCmNoaXNxLnRlc3QodGFibGUoUFNJRDc2ODIkZ2VuZGVyLCBQU0lENzY4MiRtYXJyaWVkKSkNCmBgYA0KDQpL4bq/dCBxdeG6ozoNCg0KLSBHacOhIHRy4buLIHAtdmFsdWUgPSAwIDwgNSUgY2hvIHRo4bqleSBnaeG7m2kgdMOtbmggY8OzIOG6o25oIGjGsOG7n25nIMSR4bq/biBr4bq/dCBow7RuDQoNClNhdSDEkcOzLCDEkeG7gyBsw6BtIHLDtSBz4buxIOG6o25oIGjGsOG7n25nIGPhu6dhIGdp4bubaSB0w61uaCDEkeG6v24ga2jhuqMgbsSDbmcga+G6v3QgaMO0biwgdMO0aSB0aeG6v24gaMOgbmggcGjDom4gdMOtY2ggbmjhu4sgcGjDom4gTG9naXQgbmjGsCBzYXU6DQoNCmBgYHtyfQ0KcCA8LSBnbG0oZmFjdG9yKG1hcnJpZWQpIH4gZ2VuZGVyLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IiksIGRhdGEgPSB0aCkNCnANCmBgYA0KDQpUYSBjw7MgaMOgbSBo4buTaSBxdXkgc2F1Og0KeSA9IDIuMzcgLSA2LjAxKnggKFbhu5tpIHggbMOgIEdlbmRlciAoZ2nhu5tpIHTDrW5oKSkNCg0KTmjhuq1uIHjDqXQ6DQoNCi0gU+G7sSB0aGF5IMSR4buVaSBnaeG7m2kgdMOtbmggbmFtIHbDoCBu4buvIGPDsyBraMOhYyBiaeG7h3QgbOG7m24gduG7gSBraOG6oyBuxINuZyBr4bq/dCBow7RuIHbhu5tpIGjhu4cgc+G7kSBo4buTaSBxdXkgbMOgIC0gNiwwMQ0KDQo9PiBL4bq/dCBxdeG6oyBjaG8gdGjhuqV5LCBu4bq/dSBsw6AgbmFtIHRow6wga2jhuqMgbsSDbmcgc+G7kW5nIHPDs3QgbMOgIGNhbyBoxqFuIHRydW5nIGLDrG5oIGtob+G6o25nIDYsMDEgbOG6p24gc28gduG7m2kgZ2nhu5tpIHTDrW5oIG7hu68uDQo=