1 Một số khái niệm cơ bản

1.1 Biến ngẫu nhiên wiki

1.1.1 Khái niệm

  • Biến ngẫu nhiên là một thuật ngữ được dùng trong toán học và thống kê.

  • Trong một phép thử ngẫu nhiên (Randomness tests), đầu ra (outcome) của nó có thể là giá trị số hoặc không phải.

  • Ví dụ:

    • Ví dụ phép thử ngẫu nhiên là tung một đồng xu lên và xét mặt nào của đồng xu ở phía trên, thì kết quả đầu ra có thể là {sấp, ngửa} (đầu ra không phải là số).

    • Ví dụ phép thử ngẫu nhiên là tung con súc sắc và xem mặt nằm phía trên là có mấy chấm, thì kết quả đầu ra có thể là {1,2,3,4,5,6} (đầu ra là số).

  • Tuy nhiên, trong các ứng dụng của thống kê, người ta muốn mỗi đầu ra đều gắn với một đại lượng đo đạc được, hay còn gọi là thuộc tính có giá trị là số. Để thực hiện điều này, người ta định ra biến ngẫu nhiên để ánh xạ mỗi đầu ra của một phép thử ngẫu nhiên với một giá trị số.

-> Biến ngẫu nhiên là một hàm số ánh xạ các biến cố tới các số

1.1.2 Phân loại biến ngẫu nhiên

  • Biến ngẫu nhiên rời rạc: là một biến ngẫu nhiên nhận giá trị trong một tập con rời rạc của tập số thực

  • Biến ngẫu nhiên liên tục: Biến ngẫu nhiên X là liên tục nếu giá trị có thể có của nó lấp đầy một khoảng trên trục số (Biến ngẫu nhiên X được gọi là liên tục nếu hàm phân bố xác suất của nó có đạo hàm)

1.2 Hàm mật độ xác suất

Hàm mật độ xác suất của biến ngẫu nhiên liên tục X, ký hiệu là f(x), là hàm số không âm trong khoảng giá trị của X và diện tích tạo bởi hàm số đó và trục hoành bằng 1, thể hiện sự phân phối xác suất của X

1.3 Hàm phân phối xác suất (đọc thêm trên internet)

1.4 Mẫu ngẫu nhiên

Khi nghiên cứu các đối tượng tự nhiên, kinh tế – xã hội người ta luôn hướng đến việc nắm bắt nội dung, bản chất và sự vận động của chúng. Tuy nhiên, do có quá nhiều tác động đo được và không đo được, hầu hết các đối tượng chỉ thể hiện sự tồn tại và vận động qua các đặc trưng. Mỗi đặc trưng như vậy có thể mô tả bởi 1 biến hay một quá trình ngẫu nhiên.

1.4.1 Định nghĩa:

Cho biến ngẫu nhiên X, mẫu ngẫu nhiên kích thước n lập từ X là tập hợp Wn(X) = (X1, X2¬, …, Xn) trong đó Xi (i = 1:n) là các biến ngẫu nhiên i.i.d (độc lập và có cùng quy luật phân phối xác suất với X).

1.4.2 Phân loại theo số chiều

  • Mẫu ngẫu nhiên 1 chiều

  • Mẫu ngẫu nhiên đa chiều

2 Chỉ số thống kê cơ bản

2.1 Đặc trưng trung tâm

2.1.1 Trung bình (Mean)

Trung bình của một biến ngẫu nhiên (X), thường được tính theo công thức:

  • Trung bình số học: Thường áp dụng khi tính với số dạng tuyệt đối

\[ \bar{X} = \frac{1}{n} \sum_{i=1}^{n} X_{i}\]

  • Trung bình nhân: Thường áp dụng khi tính trung bình của tỷ lệ, tốc độ tăng …

\[\bar{X} = (\prod_i r_{i})^\frac{1}{n} \]

  • So sánh trung bình cộng với trung bình nhân wiki

  • Ví dụ

Giả sử một danh mục đầu tư B có tỷ suất lợi nhuận hàng năm r lần lượt là (90%, 20%, 10%, 30%, -90%)

\[r_{t} = (\frac{x_{t} - x_{t-1}}{x_{t-1})}) \]

? Tính lợi suất trung bình năm của danh mục B

  • Tính trung bình cộng (trung bình số học) lợi suất hàng năm của danh mục
r <-  c(90, 20, 10, 30, -90)/100

(.9 + .2 + .1 + .3 -.9)/5 
## [1] 0.12
# sum(r)/length(r)
# mean(r) 
  • Tính trung bình nhân lợi suất hàng năm của danh mục
# Năm đầu, danh mục tăng 1.9 lần, năm 2 danh mục tăng 1.2 lần ...
gr <-  r + 1

(1.9 * 1.2 * 1.1 * 1.3 * 0.1)^(1/5) - 1
## [1] -0.2008024
# exp(sum(log(gr)) / length(gr)) - 1

# psych::geometric.mean(gr) - 1

2.1.2 Trung vị (Median)

Trung vị là giá trị nằm giữa các giá trị của biến ngẫu nhiên, đặc trưng này thường chỉ có ý nghĩa khi các giá trị có thể có rời rạc, hữu hạn

  • Nếu dãy quan sát có 2n+1 quan sát xếp theo thứ tự tăng dần thì giá trị thứ n+1 là trung vị, nếu có 2n quan sát thì trung vị là trung bình của giá trị thứ (2n-1)/2 và (2n+1)/2

  • Ví dụ:

    • Ví dụ với dãy có 2n+1 quan sát 1:11
x1 <- 1:11
x1
##  [1]  1  2  3  4  5  6  7  8  9 10 11
median(x1)
## [1] 6
  • Ví dụ 1 dãy số khác: (2, 4, 7, 8, 3, 1, 2)
x2 <- c(2, 4, 7, 8, 3, 1, 2)

# Sắp xếp rồi lấy số ở vị trí thứ n+1
x2 %>% sort() %>% .[ceiling(length(.)/2)] 
## [1] 3
# median(x2)
  • Ví dụ với dãy có 2n quan sát
x3 <- x1[-11] # Bỏ số cuối cùng đi

median(x3)
## [1] 5.5

2.1.3 Mốt (Mode)

Mốt của biến ngẫu nhiên X là giá trị tương ứng với xác suất lớn nhất. Một biến có thể có nhiều mốt và như vậy số giá trị mốt càng ít thì ý nghĩa của mốt càng lớn

  • Ví dụ:
m <- sample(c('a', 'b', 'c', 'd'), size = 20, replace = T)
m
##  [1] "b" "a" "a" "a" "d" "b" "a" "a" "b" "c" "b" "a" "a" "b" "d" "a" "a"
## [18] "a" "c" "b"
m %>% table() %>% sort()
## .
##  c  d  b  a 
##  2  2  6 10

2.2 Đặc trưng về độ phân tán

2.2.1 Phương sai (Variance)

Là trung bình của bình phương khoảng cách của mỗi điểm dữ liệu tới trung bình. Hay trung bình bình phương các độ lệch

Phương sai tổng thể: \[\sigma^2 = \frac{1}{n} \sum_{i=1}^{n} (X_{i} - \bar{X})^2\]

Do mất đi 1 bậc tự do nên Phương sai mẫu: \[ S^2 = \frac{1}{n-1} \sum_{i=1}^{n} (X_{i} - \bar{X})^2\]

2.2.2 Độ lệch chuẩn (Standard diviation): sd

Đo lường sự biến động của mẫu với giá trị trung bình mẫu

Độ lệch chuẩn tổng thể: \[\sigma =\sqrt{\frac{1}{n} \sum_{i=1}^{n} (X_{i} - \bar{X})^2}\]

Độ lệch chuẩn mẫu: \[S = \sqrt{\frac{1}{n-1} \sum_{i=1}^{n} (X_{i} - \bar{X})^2} \]

Sai số chuẩn (standard error) \[se = sd / \sqrt{n}\] (se và sd là 2 khái niệm rất dễ bị nhầm lẫn. Sd đo lượng sự biến động của tập mẫu so với giá trị trung bình được ước lượng từ tập mẫu. Nhưng giá trị trung bình ước lượng được không phải là giá trị trung bình thực sự của tổng thể, giá trị này phụ thuộc vào mẫu lựa chọn, khi thay đổi cỡ mẫu hoặc thời gian lấy mẫu … thì giá trị này sẽ thay đổi. SE đo lường sự chính xác của giá trị trung bình đã ước lượng được từ mẫu. Mẫu càng lớn thì giá trị trung bình ước lượng càng tốt hơn hay SE càng nhỏ hơn ) so sánh ### Sai số trung bình tuyệt đối

\[ ASD = \frac{1}{n} \sum_{i=1}^{n} |X_{i} - \bar{X}|\]

2.2.3 Tứ phân vị

  • Sắp xếp số liệu quan sát theo chiều tăng dần, các giá trị tương ứng với các tần suất tích luỹ 25%, 50%, 75% gọi là tứ phân vị thứ nhất, thứ hai và thứ 3; ký hiệu Q1, Q2, và Q3. Khoảng từ giá trị nhỏ nhất đến Q1 gọi là khoảng tứ phân vị thứ nhất (SQ1); khoảng từ Q1 đến Q2 gọi là khoảng tứ phân vị thứ 2 (SQ2) …

  • Thông thường các giá trị quan sát tập trung trong khoảng (Q1, Q3) khoảng này gọi là khoảng giá trị chuẩn

  • Q1 là giá trị quan sát thứ i(1) xác định theo công thức i(1)=(n+1)/4. Nếu n+1 không chia hết cho 4, chẳng hạn n=22, (n+1)/4=5 người ta chọn Q1 là giá trị nằm ở vị trí 3/4 của khoảng X5 và X6. Tứ phân vị thứ 3 cũng tính tương tự như vậy. Chẳng hạn vẫn với n=22 thì i(3)=3(n+1)/4=17 .

x4 <- 1:21
x5 <- seq(6, 16, by = 0.5)

x4
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
x5
##  [1]  6.0  6.5  7.0  7.5  8.0  8.5  9.0  9.5 10.0 10.5 11.0 11.5 12.0 12.5
## [15] 13.0 13.5 14.0 14.5 15.0 15.5 16.0
quantile(x4, c(.25, 0.5, 0.75))
## 25% 50% 75% 
##   6  11  16
quantile(x5, c(.25, 0.5, 0.75))
##  25%  50%  75% 
##  8.5 11.0 13.5
data.frame(x4, x5) %>% 
  gather() %>% ggplot() +
  geom_boxplot(aes(x = key, y = value))

–> các quan sát của x4 phân tán hơn so với x5

2.2.4 Khoảng biến thiên (range)

Được tính bảng độ lớn của hiệu hai giá trị quan sát lớn nhất và nhỏ nhất

set.seed(158)
x6 <- c(sample(1:21, size = 19, replace = TRUE), 1, 21)
x6
##  [1] 17 21 13 10  8 10  3 16 15 13  4 21 11 13 10 10  2  9  2  1 21
max(x6) - min(x6)
## [1] 20
max(x4) - min(x4)
## [1] 20

2.2.5 Hạng của dãy quan sát (rank)

  • Hạng của dãy quan sát là số quan sát khác nhau của dãy số

  • Nếu hay dãy quan sát có khoảng biến thiên như nhau thì có thể so sánh hạng của chúng để so sánh độ phân tán.

min_rank(x4) %>% table() %>% names() %>% length()
## [1] 21
min_rank(x6) %>% table() %>% names() %>% length()
## [1] 13
  • Lưu ý: Đây là hạng của dãy số chứ không phải là hạng của từng quan sát trong dãy số

Hạng của dãy số x4 là 21, hạng của dãy số x6 là 14 –> x6 có các quan sát phân tán hơn x4

data.frame(x6, count = min_rank(x6)) %>% 
  ggplot() +
  geom_point(aes(y = count, x = 6), color = "blue", size = 2) +
  geom_point(aes(x = 5, y = x4), alpha = 0.3) +
  scale_x_discrete(limits = c(5,6))

2.2.6 Hệ số biến thiên

Hệ số biến thiên là tỷ số giữa độ lệch tiêu chuẩn và giá trị trung bình

Hệ số này càng lớn thì quan sát của dãy số càng phân tán hơn

sd(x4) / mean(x4)
## [1] 0.5640761
sd(x6) / mean(x6)
## [1] 0.5705435

2.3 Các đặc trưng dạng phân phối

Hai đặc trưng cơ bản về dạng phân phối là độ bất đối xứng và độ nhọn

2.3.1 Độ bất đối xứng (độ xiên) (skewness)

  • Công thức tính: wiki

\[Skew = \frac{\frac{1}{n} \sum_{i=1}^{n} (X_{i} - \bar{X})^3}{\sqrt{\frac{1}{n-1} \sum_{i=1}^{n} (X_{i} - \bar{X})^2}^3} \]

  • Negative skew: đuôi bên trái dài hơn ~ phân phối lệch trái

  • mean < median < mode

negative_skew <- data.frame(negative_skew = rbeta(1000,50,2))

negative_skew %>% 
  ggplot() +
  geom_density(aes(x = negative_skew), fill = 'red', alpha= 0.2) +
  geom_vline(aes(xintercept = mean(negative_skew)), color = 'green', size = 2) +
  geom_vline(aes(xintercept = median(negative_skew)), color = 'blue', size = 2) +
  geom_text(aes(x = mean(negative_skew), y = 0, label = "mean"), angle = 90, hjust = -1, vjust = -0.5) +
  geom_text(aes(x = median(negative_skew), y = 0, label = "median"), angle = 90, hjust = -1.5, vjust = 2) +
  labs(title = "Negative skew",
       x = 'X',
       caption = "Source: BI - SeAbank") +
  theme(plot.title = element_text(hjust = 0.5))

describe(negative_skew)
##    vars    n mean   sd median trimmed  mad  min max range  skew kurtosis
## X1    1 1000 0.96 0.03   0.97    0.96 0.02 0.84   1  0.16 -1.08      1.3
##    se
## X1  0
  • Positive skew: đuôi bên phải dài hơn ~ phân phối lệch phải

  • Trong trường hợp này mode < median < mean

positive_skew <- data.frame(positive_skew = rbeta(1000, 2, 50))

positive_skew %>% 
  ggplot() +
  geom_density(aes(x = positive_skew), fill = 'red', alpha= 0.2) +
  geom_vline(aes(xintercept = mean(positive_skew)), color = 'green', size = 1.5) +
  geom_vline(aes(xintercept = median(positive_skew)), color = 'blue', size = 1.5) +
  geom_text(aes(x = mean(positive_skew), y = 0, label = "mean"), angle=90, hjust = -1, vjust = 1) +
  geom_text(aes(x = median(positive_skew), y = 0, label = "median"), angle=90, hjust = -1.5, vjust = -0.5)+
  labs(title = "Positive skew",
       x = 'X',
       caption = "Source: BI - SeAbank") +
  theme(plot.title = element_text(hjust = 0.5))

describe(positive_skew)
##    vars    n mean   sd median trimmed  mad min  max range skew kurtosis se
## X1    1 1000 0.04 0.03   0.03    0.03 0.02   0 0.15  0.15 1.27     1.81  0

2.3.2 Độ nhọn (Kurtosis)

  • Công thức tính: wiki

\[ Kurt = \frac{\frac{1}{n} \sum_{i=1}^{n} (X_{i} - \bar{X})^4}{(\frac{1}{n} \sum_{i=1}^{n} (X_{i} - \bar{X})^2)^2} \]

  • So sánh độ nhọn của 2 phân phối
set.seed(158)

df <- data.frame(x1 = rnorm(10000, mean = 0, sd = 3),
                 x2 = rnorm(10000, mean = 0, sd = 1),
                 x3 = rnorm(10000, mean = 5, sd = 1)) 
                 
df %>% 
ggplot() +
  geom_density(aes(x = x1), fill = 'red', alpha = 0.2) +
  geom_density(aes(x = x2), fill = 'blue', alpha = 0.2)+
  geom_text(aes(x = mean(x1), y = 0.1), 
            label = paste('Kurtosis', round(kurtosi(df$x1), 2)), 
            color = 'red') +
  geom_text(aes(x = mean(x1), y = 0.4), 
            label = paste('Kurtosis',round(kurtosi(df$x2), 2)), 
            color = 'blue') +
  labs(title = "Compare kurtosis of two distribution",
       x = 'X',
       caption = "Source: BI - SeAbank ") +
  theme(plot.title = element_text(hjust = 0.5))

2.4 Phân phối xác suất

Phân phối xác suất là quy luật cho biết cách gán mỗi xác suất cho mỗi khoảng giá trị của tập số thực, sao cho các tiên đề xác suất được thỏa mãn

2.4.1 Phân phối chuẩn: wiki

2.4.1.1 Khái niệm

  • Phân phối chuẩn (còn gọi là phân phối Gauss): là một phân phối xác suất cực kì quan trọng trong nhiều lĩnh vực. Nó là họ phân phối có dạng tổng quát giống nhau, chỉ khác tham số trung bình μ và phương sai σ2.

  • Phân phối chuẩn tắc (standard normal distribution): là phân phối chuẩn với giá trị trung bình bằng 0 và phương sai bằng 1. Phân phối chuẩn còn được gọi là đường cong chuông (bell curve) vì đồ thị của mật độ xác suất có dạng chuông.

density_label <- expression(f(x) == paste(frac(1, sqrt(2 * pi * sigma^2)), " ", 
                                          e^{frac(-(x - mu)^2, 2 * sigma^2)}))

df %>%
  ggplot() +
  geom_density(aes(x = x2), fill = "pink") +
  geom_text(aes(x = 0, y = 0.2,
                label = paste('Mean = 0'))) +
  geom_text(aes(x = 0, y = 0.17,
                label = paste('Sd = 1'))) +
  labs(title = "Density of standard normal distribution",
       x = "X",
       caption = "Source: BI - SeAbank") +
  annotate("text", label = density_label, x = -2, y = 0.3 ) +
  theme(plot.title = element_text(hjust = 0.5)) 
## Warning in is.na(x): is.na() applied to non-(list or vector) of type
## 'expression'

2.4.1.2 Đặc tính của phân phối chuẩn

Có nhiều cách để thể hiện các đặc tính của một phân phối xác suất:

  • Cách dễ thấy nhất là thông qua hàm mật độ xác suất, nó cho biết khả năng xảy ra của mỗi giá trị của biến ngẫu nhiên.

  • Hàm phân phối tích lũy cũng cho cùng thông tin, nhưng hình ảnh của nó thì thông tin chứa đựng không dễ nhận thấy cho.
  • Một cách khác tương đương khi chỉ định một phân phối chuẩn là thông qua: mômen, ước lượng, hàm đặc trưng, …

cdf_label <- expression(phi(x) == paste(frac(1, sqrt(2 * pi)),
                                          " ", integral(e^(-t^2/2) * dt, -infinity, x)))

set.seed(158)

1:5 %>% 
  map_dfc(rnorm, n = 1000, sd = 1) ->> df2


df2  %>% 
  gather() %>% 
  ggplot(aes(value)) +
  stat_ecdf(aes(colour = key)) + 
  labs(title = "Cummulative distribution function",
       x = "X",
       y = "Probability",
       caption = "Source: BI - SeAbank") +
  annotate("text", label = cdf_label, x = 0, y = 0.85 ) +
  scale_color_manual(name="Parameter",
                     labels=c(expression(paste(mu, " = 1, ",  sigma, " = 1")),
                              expression(paste(mu, " = 2, ",  sigma, " = 1")),
                              expression(paste(mu, " = 3, ",  sigma, " = 1")),
                              expression(paste(mu, " = 4, ",  sigma, " = 1")),
                              expression(paste(mu, " = 5, ",  sigma, " = 1"))),
                       values=c("red", "orange", "yellow", "green", "blue")) +
  theme(plot.title = element_text(hjust = 0.5))
## Warning in is.na(x): is.na() applied to non-(list or vector) of type
## 'expression'

df2 %>% describe()
##    vars    n mean   sd median trimmed  mad   min  max range  skew kurtosis
## V1    1 1000 0.94 1.00   0.96    0.92 1.03 -1.83 4.10  5.93  0.14    -0.04
## V2    2 1000 2.03 0.99   2.02    2.03 0.99 -0.83 5.44  6.27  0.06     0.18
## V3    3 1000 3.03 0.99   3.03    3.04 0.95  0.21 5.91  5.70 -0.07    -0.12
## V4    4 1000 4.03 1.02   4.02    4.03 1.00  0.81 6.89  6.07 -0.02    -0.03
## V5    5 1000 5.04 1.02   5.02    5.03 1.02  1.89 8.73  6.84  0.14     0.00
##      se
## V1 0.03
## V2 0.03
## V3 0.03
## V4 0.03
## V5 0.03

2.4.2 Phân phối T-student wiki

  • Là phân phối đơn giản nhất, hàm phân phối chỉ có tham số duy nhất là số bậc tự do

  • Ứng dụng trong ước lượng khoảng tin cậy, kiểm định tham số

  • Khi số bậc tự do lớn phân phối T-student tiệm cận phân phối chuẩn

set.seed(158)

df3 <- data.frame(k1 = rt(1000, 1),
                  k2 = rt(1000, 2),
                  k3 = rt(1000, 3),
                  k5 = rt(1000, 5),
                  k10 = rt(1000, 10),
                  k30 = rt(1000, 10))

df3 %>% gather() %>% 
  mutate(key = fct_relevel(key, "k1", "k2", "k3", "k5", "k10", "k30"))  %>% 
  ggplot() +
  geom_density(aes(x = value, color = key), alpha = 0, size = 1) +
  scale_x_continuous(limits = c(-6, 6)) +
  facet_wrap( ~key)
## Warning: Removed 128 rows containing non-finite values (stat_density).

df3 %>% gather() %>% 
  mutate(key = fct_relevel(key, "k1", "k2", "k3", "k5", "k10", "k30"))  %>% 
  ggplot() +
  geom_density(aes(x = value, color = key), alpha = 0) +
  scale_x_continuous(limits = c(-4, 4)) 
## Warning: Removed 253 rows containing non-finite values (stat_density).

  • So sánh phân phối chuẩn và T-student k = 30
df4 <- data.frame(x = rnorm(1000, 0, 1),
                  y = rnorm(1000, 5, 1),
                  z = rt(1000, 30))


p1 <- df4 %>% ggplot() +
  geom_density(aes(x), alpha = 0.3, fill = '#C42E26')+
  geom_density(aes(z), alpha = 0.2, fill = 'blue') +
  geom_text(aes(x = 0, y = 0.1), label = paste('Normal, mean = 0, sd = 1')) +
  geom_text(aes(x = 0, y = 0.2), label = paste('T-student, k = 30')) +
  labs(x = 'x-z')



p2 <-df4 %>% ggplot() +
  geom_density(aes(y), alpha = 0.3, fill = '#C42E26')+
  geom_density(aes(z), alpha = 0.2, fill = 'blue') +
  geom_text(aes(x = 5, y = 0.1), label = paste('Normal, mean = 5, sd = 1')) +
  geom_text(aes(x = 0, y = 0.2), label = paste('T-student, k = 30')) +
  labs(x = 'y-z')

stable<- df4 %>% 
  describe() %>% 
  mutate_if(is.numeric, function(x){round(x, digits = 2)}) %>% 
  mutate(vars = c("x", "y", "z"))

stable.p <- ggtexttable(stable, rows = NULL,
                        theme = ttheme("mRed"))

ggarrange(
  ggarrange(p1, p2, ncol = 2),
  stable.p,
  nrow = 2)

2.4.3 Phân phối khác

See more

See more

R Functions for Probability Distributions Every distribution that R handles has four functions. There is a root name, for example, the root name for the normal distribution is norm. This root is prefixed by one of the letters

p for “probability”, the cumulative distribution function (c. d. f.)

q for “quantile”, the inverse c. d. f.

d for “density”, the density function (p. f. or p. d. f.)

r for “random”, a random variable having the specified distribution

For the normal distribution, these functions are pnorm, qnorm, dnorm, and rnorm. For the binomial distribution, these functions are pbinom, qbinom, dbinom, and rbinom. And so forth.

2.4.4 Chuẩn hóa 1 vector hay 1 biến số

  • Mục đích: chuyển các biến về cùng 1 độ đo. Ví dụ: Khi phân tích dòng tiền gửi của khách hàng theo tháng, có 2 biến số lượng người gửi (đv: người), số tiền gửi (đv: đồng). Nếu vẽ 2 biến này trên cùng 1 đồ thị thì cần phải có 2 trục Y có 2 đơn vị khác nhau. Thay vì làm việc đó, ta quy các biến về cùng 1 độ đo (ở đây là chuẩn hóa vector)

  • Sau khi chuẩn hóa đặc điểm của biến không bị thay đổi (vì tất cả các quan sát đều áp dụng chung 1 rule)

  • Chuẩn hóa không có nghĩa là chuyển 1 biến có phân phối khác về phân phối chuẩn

x4 <- sample(1:20, size = 100, replace = TRUE)
normalized_x4  <- (x4 - mean(x4)) / sd(x4) # scale(x4)

ggplot()+
  geom_density(aes(x4), fill = "tomato") 

ggplot()+  
  geom_density(aes(normalized_x4), fill = "green", alpha = 0.3)

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

Cho X là một biến ngẫu nhiên có phân bố gốc F(x, \(\theta\) ) đã biết dạng, nhưng tham số \(\theta\) chưa biết. Nếu X rời rạc thì phân bố gốc có thể thể hiện qua hàm xác suất p(x, \(\theta\) ); với X là biến ngẫu nhiên liên tục phân phối gốc có thể biểu thị qua hàm mật độ f(x, \(\theta\)).

Việc tìm được giá trị đúng của tham số \(\theta\) thường rất khó khăn vì điều này đòi hỏi phải biết toàn bộ thông tin về X nên người ta thường ước lượng tham số căn cứ theo kết quả của mẫu.

Lý thuyết ước lượng thiết lập các qui tắc, tiêu chuẩn và cách đánh giá khi dùng thông tin từ mẫu ước lượng cho các tham số chưa biết của các phân phối.

  • Phương pháp thứ nhất là sử dụng một thống kê lập từ mẫu ngẫu nhiên để ước lượng và lấy giá trị quan sát mẫu của thống kê này làm giá trị xấp xỉ cho tham số \(\theta\)

  • Phương pháp thứ hai là sử dụng những khoảng ngẫu nhiên (1 hay nhiều khoảng) thành lập bởi các thống kê lập từ mẫu ngẫu nhiên sao cho xác suất các khoảng này chứa tham số \(\theta\) xác định bằng một mức cho trước (đủ lớn). Các ước lượng này gọi là ước lượng bằng khoảng tin cậy (hay gọi tắt là ước lượng khoảng tin cậy).

2.5.1 Khoảng tin cậy của trung bình

2.5.1.1 Khoảng tin cậy của tham số \(\mu\) trong quy luật \(N(\mu, \sigma^2)\)

Để ước lượng giá trị trung bình \(\mu\) trong quy luật \(N(\mu, \sigma^2)\), ta sẽ dùng trung bình mẫu {X} để ước lượng

Vì quy luật chuẩn phụ thuộc vào hai tham số \(\mu\)\(\sigma^2\) nên để xây dựng các khoảng tin cậy của \(\mu\) ta xét hai trường hợp:

    1. Khi đã biết \(\sigma^2\):
    \[h(\bar{X}, \mu) = \frac{(\bar{X} - \mu) \sqrt{n}} {\sigma}\]

hàm này tuân theo quy luật N(0,1)

Gọi \(h_{\alpha1}\) là điểm tới hạn dưới \(U_{\alpha}\), \(h_{\alpha2}\) là điểm tới hạn trên \(U_{1-\alpha}\). Khi đó ta có:

\[P(U_{\alpha} < \frac{(\bar{X} - \mu) \sqrt{n}} {\sigma} < U_{1-\alpha}) = 1 - \alpha\]

\[P(\bar{X} - U_{1-\alpha}\frac{\sigma} {\sqrt{n}} < \mu < \bar{X} - U_{\alpha}\frac{\sigma} {\sqrt{n}}) = 1 - \alpha\]

Với độ tin cậy 1 - \(\alpha\) thì khoảng tin cậy của giá trị trung bình nằm trong khoảng

\[\bar{X} - U_{1-\alpha}\frac{\sigma} {\sqrt{n}} < \mu < \bar{X} - U_{\alpha}\frac{\sigma} {\sqrt{n}}\]

    1. Khi chưa biết \(\sigma^2\):

\[ h(\bar{X}, \mu) = \frac{(\bar{X} - \mu) \sqrt{n}} {s}\]

hàm này tuân theo quy luật T-student với (n-1) bậc tự do

2.5.1.2 Khoảng tin cậy của tham số p của quy luật a(p)

  • Hàm mật độ có dạng: \[ Pr(k) = \frac{n!}{k!(n-k)!}p^k(1-p)^{N-k} = \binom{N}{k} p^kq^{N-k}\]

  • Tần suất mẫu f là hàm ước lượng p (xem thêm sách thống kê về kết quả chứng minh).

  • Phương sai: \(\frac{p(1-p)}{n} \)

Cách ước lượng tương tự như trên

2.5.2 Khoảng tin cậy của phương sai

2.6 Kiểm định

  • Giả thiết kiểm định thường gọi là H0

Ví dụ: H0: Biến ngẫu nhiên x có phân phối chuẩn

  • Giá trị thống kê: Tùy thuộc vào loại kiểm định giá trị này được tính theo các cách khác nhau. Giá trị này đã được chứng minh tuân theo 1 quy luật phân phối nào đó

Ví dụ: giá trị thống kê ( JB = n( + ) ) được chứng minh tuân theo quy luật phân phối Khi bình phương 2 bậc tự do

  • Xác suất: Khi đã biết được giá trị thống kê và loại phân phối, ta sẽ tính được xác suất xảy ra sự kiện H0 Thông thường người ta thường lấy ngưỡng là 0.01, 0.05, 0.1 để chấp nhận hoặc bác bỏ H0. Trong các phần mềm thông thường các giá trị này đã được tính toán. Người sử dụng chỉ cần nhìn vào mức xác suất để đưa ra kết luận.

Ví dụ: Xác suất xảy ra sự kiện H0 đã được tính toán = 0.04. Ta có thể kết luận bác bỏ H0 (tức là biến ngẫu nhiên x không phân phối chuẩn) với mức ý nghĩa 5% hoặc chấp nhận H0 với mức ý nghĩa < 4%

2.6.1 Kiểm định phân phối chuẩn

2.6.1.1 Tiêu chuẩn Jacque- Bera

x <- rnorm(100)
tseries::jarque.bera.test(x)
## 
##  Jarque Bera Test
## 
## data:  x
## X-squared = 1.6317, df = 2, p-value = 0.4423

2.6.1.2 Tiêu chuẩn Kolmogorov-Smirnov

ks.test(x, "pnorm", mean = 0, sd = 1)
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  x
## D = 0.090843, p-value = 0.3812
## alternative hypothesis: two-sided

2.6.1.3 Tiêu chuẩn Shapiro-Wilks

shapiro.test(x)
## 
##  Shapiro-Wilk normality test
## 
## data:  x
## W = 0.9857, p-value = 0.3561

2.6.1.4 Tiêu chuẩn Anderson - Darling

nortest::ad.test(x)
## 
##  Anderson-Darling normality test
## 
## data:  x
## A = 0.23628, p-value = 0.7826

2.6.2 Kiểm định giả thuyết về giá trị trung bình

2.6.2.1 Kiểm định giả thuyết về tham số của quy luật \(N(\mu_{0}, \sigma_{0}^2)\)

  • Khi đã biết \(\sigma_{0}\)

H0: \(\mu=\mu_{0}\)

H1: \(\mu<>\mu_{0}\)

  • Lập thống kê \(U = \frac{(\bar{X} - \mu_{0}) \sqrt{n}} {\sigma}\), thống kê này tuân theo quy luật phân phối N(0, 1)

  • Khi chưa biết \(\sigma_{0}\)

  • Lập thống kê \(T = \frac{(\bar{X} - \mu_{0}) \sqrt{n}} {s}\), thống kê này tuân theo quy luật phân phối T-student (n-1) bậc tự do

x <- rpois(100, 12) # tạo biến ngẫu nhiêu phân phối poisson

head(x)
## [1]  9 13 15 13 10  8
  • Trung bình và độ lệch chuẩn lần lượt
mean(x)
## [1] 12.28
sd(x)
## [1] 3.997676
  • Kiểm định:

H0: mu = 10

t.test(x, mu = 10) # H0: Giả sử biến này có giá trị trung bình = 10
## 
##  One Sample t-test
## 
## data:  x
## t = 5.7033, df = 99, p-value = 1.221e-07
## alternative hypothesis: true mean is not equal to 10
## 95 percent confidence interval:
##  11.48677 13.07323
## sample estimates:
## mean of x 
##     12.28
t.test(x, mu = 11) # H0: Giả sử biến này có giá trị trung bình = 11
## 
##  One Sample t-test
## 
## data:  x
## t = 3.2019, df = 99, p-value = 0.001836
## alternative hypothesis: true mean is not equal to 11
## 95 percent confidence interval:
##  11.48677 13.07323
## sample estimates:
## mean of x 
##     12.28
  • So sánh trung bình của 2 mẫu
  • 2 mẫu có phương sai bằng nhau
y <- rnorm(100, 12, sd(x))

t.test(x, y, var.equal = TRUE)
## 
##  Two Sample t-test
## 
## data:  x and y
## t = 1.3943, df = 198, p-value = 0.1648
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.342367  1.994960
## sample estimates:
## mean of x mean of y 
##   12.2800   11.4537
  • 2 mẫu có phương sai khác nhau
z <- rnorm(100, 12, 6)
t.test(x, z, var.equal = FALSE)
## 
##  Welch Two Sample t-test
## 
## data:  x and z
## t = -0.2376, df = 167.12, p-value = 0.8125
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -1.656097  1.300292
## sample estimates:
## mean of x mean of y 
##   12.2800   12.4579

2.6.3 Kiểm định giả thuyết về giá trị phương sai

H0: \(\sigma_{x} = \sigma_{y}\)

var.test(x, y)
## 
##  F test to compare two variances
## 
## data:  x and y
## F = 0.83503, num df = 99, denom df = 99, p-value = 0.3713
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
##  0.5618404 1.2410440
## sample estimates:
## ratio of variances 
##          0.8350261
var.test(x, z)
## 
##  F test to compare two variances
## 
## data:  x and z
## F = 0.39875, num df = 99, denom df = 99, p-value = 7.258e-06
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
##  0.2682959 0.5926364
## sample estimates:
## ratio of variances 
##          0.3987504
LS0tDQp0aXRsZTogIk3hu5l0IHPhu5EgY2jhu4kgc+G7kSB0aOG7kW5nIGvDqiBjxqEgYuG6o24gc2VhYmFuayINCmF1dGhvcjogIlNlQUJhbmsgRGl2aXNpb24gb2YgQnVzaW5lc3MgSW50ZWxsaWdlbmNlIGFuZCBBbmFseXRpY3MiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIHRoZW1lOiBmbGF0bHkNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogbm8NCiAgICAgIHNtb290aF9zY3JvbGw6IG5vDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogIGZpZ193aWR0aDogOSANCiAgZmlnX2hlaWdodDogNiANCiAgZmlnLmNhcCA6ICJTb3VyY2U6IEJJIC0gU2VBYmFuayAiDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCiMgImRlZmF1bHQiLCAiY2VydWxlYW4iLCAiam91cm5hbCIsICJmbGF0bHkiLCAicmVhZGFibGUiLCAic3BhY2VsYWIiLCAidW5pdGVkIiwgImNvc21vIiwgImx1bWVuIiwgInBhcGVyIiwgInNhbmRzdG9uZSIsICJzaW1wbGV4IiwgInlldGkiDQpgYGANCg0KIyBN4buZdCBz4buRIGtow6FpIG5p4buHbSBjxqEgYuG6o24NCg0KIyMgQmnhur9uIG5n4bqrdSBuaGnDqm4gW3dpa2ldKGh0dHBzOi8vdmkud2lraXBlZGlhLm9yZy93aWtpL0JpJUUxJUJBJUJGbl9uZyVFMSVCQSVBQnVfbmhpJUMzJUFBbikNCg0KIyMjIEtow6FpIG5p4buHbQ0KDQoqIEJp4bq/biBuZ+G6q3Ugbmhpw6puIGzDoCBt4buZdCB0aHXhuq10IG5n4buvIMSRxrDhu6NjIGTDuW5nIHRyb25nIHRvw6FuIGjhu41jIHbDoCB0aOG7kW5nIGvDqi4gDQoNCiogVHJvbmcgbeG7mXQgcGjDqXAgdGjhu60gbmfhuqt1IG5oacOqbiAoUmFuZG9tbmVzcyB0ZXN0cyksIMSR4bqndSByYSAob3V0Y29tZSkgY+G7p2EgbsOzIGPDsyB0aOG7gyBsw6AgZ2nDoSB0cuG7iyBz4buRIGhv4bq3YyBraMO0bmcgcGjhuqNpLiANCg0KKiBWw60gZOG7pTogDQoNCiAgICAtIFbDrSBk4bulIHBow6lwIHRo4butIG5n4bqrdSBuaGnDqm4gbMOgIHR1bmcgbeG7mXQgxJHhu5NuZyB4dSBsw6puIHbDoCB4w6l0IG3hurd0IG7DoG8gY+G7p2EgxJHhu5NuZyB4dSDhu58gcGjDrWEgdHLDqm4sIHRow6wga+G6v3QgcXXhuqMgxJHhuqd1IHJhIGPDsyB0aOG7gyBsw6Age3PhuqVwLCBuZ+G7rWF9ICjEkeG6p3UgcmEga2jDtG5nIHBo4bqjaSBsw6Agc+G7kSkuIA0KDQogICAgLSBWw60gZOG7pSBwaMOpcCB0aOG7rSBuZ+G6q3Ugbmhpw6puIGzDoCB0dW5nIGNvbiBzw7pjIHPhuq9jIHbDoCB4ZW0gbeG6t3QgbuG6sW0gcGjDrWEgdHLDqm4gbMOgIGPDsyBt4bqleSBjaOG6pW0sIHRow6wga+G6v3QgcXXhuqMgxJHhuqd1IHJhIGPDsyB0aOG7gyBsw6AgezEsMiwzLDQsNSw2fSAoxJHhuqd1IHJhIGzDoCBz4buRKS4gDQoNCiogVHV5IG5oacOqbiwgdHJvbmcgY8OhYyDhu6luZyBk4bulbmcgY+G7p2EgdGjhu5FuZyBrw6osIG5nxrDhu51pIHRhIG114buRbiBt4buXaSDEkeG6p3UgcmEgxJHhu4F1IGfhuq9uIHbhu5tpIG3hu5l0IMSR4bqhaSBsxrDhu6NuZyDEkW8gxJHhuqFjIMSRxrDhu6NjLCBoYXkgY8OybiBn4buNaSBsw6AgdGh14buZYyB0w61uaCBjw7MgZ2nDoSB0cuG7iyBsw6Agc+G7kS4gxJDhu4MgdGjhu7FjIGhp4buHbiDEkWnhu4F1IG7DoHksIG5nxrDhu51pIHRhIMSR4buLbmggcmEgYmnhur9uIG5n4bqrdSBuaGnDqm4gxJHhu4Mgw6FuaCB44bqhIG3hu5dpIMSR4bqndSByYSBj4bunYSBt4buZdCBwaMOpcCB0aOG7rSBuZ+G6q3Ugbmhpw6puIHbhu5tpIG3hu5l0IGdpw6EgdHLhu4sgc+G7kS4NCg0KPHNwYW4gc3R5bGU9ImNvbG9yOnRvbWF0byI+IC0+IEJp4bq/biBuZ+G6q3Ugbmhpw6puIGzDoCBt4buZdCBow6BtIHPhu5Egw6FuaCB44bqhIGPDoWMgYmnhur9uIGPhu5EgdOG7m2kgY8OhYyBz4buRDQoNCiMjIyBQaMOibiBsb+G6oWkgYmnhur9uIG5n4bqrdSBuaGnDqm4NCg0KKiBCaeG6v24gbmfhuqt1IG5oacOqbiBy4budaSBy4bqhYzogbMOgIG3hu5l0IGJp4bq/biBuZ+G6q3Ugbmhpw6puIG5o4bqtbiBnacOhIHRy4buLIHRyb25nIG3hu5l0IHThuq1wIGNvbiBy4budaSBy4bqhYyBj4bunYSB04bqtcCBz4buRIHRo4buxYw0KDQoqIEJp4bq/biBuZ+G6q3Ugbmhpw6puIGxpw6puIHThu6VjOiBCaeG6v24gbmfhuqt1IG5oacOqbiBYIGzDoCBsacOqbiB04bulYyBu4bq/dSBnacOhIHRy4buLIGPDsyB0aOG7gyBjw7MgY+G7p2EgbsOzIGzhuqVwIMSR4bqneSBt4buZdCBraG/huqNuZyB0csOqbiB0cuG7pWMgc+G7kSANCihCaeG6v24gbmfhuqt1IG5oacOqbiBYIMSRxrDhu6NjIGfhu41pIGzDoCBsacOqbiB04bulYyBu4bq/dSBow6BtIHBow6JuIGLhu5EgeMOhYyBzdeG6pXQgY+G7p2EgbsOzIGPDsyDEkeG6oW8gaMOgbSkNCg0KIyMgSMOgbSBt4bqtdCDEkeG7mSB4w6FjIHN14bqldA0KDQpIw6BtIG3huq10IMSR4buZIHjDoWMgc3XhuqV0IGPhu6dhIGJp4bq/biBuZ+G6q3Ugbmhpw6puIGxpw6puIHThu6VjIFgsIGvDvSBoaeG7h3UgbMOgIGYoeCksIGzDoCBow6BtIHPhu5Ega2jDtG5nIMOibSB0cm9uZyBraG/huqNuZyBnacOhIHRy4buLIGPhu6dhIFggdsOgIGRp4buHbiB0w61jaCB04bqhbyBi4bufaSBow6BtIHPhu5EgxJHDsyB2w6AgdHLhu6VjIGhvw6BuaCBi4bqxbmcgMSwgdGjhu4MgaGnhu4duIHPhu7EgcGjDom4gcGjhu5FpIHjDoWMgc3XhuqV0IGPhu6dhIFgNCg0KIyMgSMOgbSBwaMOibiBwaOG7kWkgeMOhYyBzdeG6pXQgKMSR4buNYyB0aMOqbSB0csOqbiBpbnRlcm5ldCkNCg0KIyMgTeG6q3Ugbmfhuqt1IG5oacOqbg0KDQpLaGkgbmdoacOqbiBj4bupdSBjw6FjIMSR4buRaSB0xrDhu6NuZyB04buxIG5oacOqbiwga2luaCB04bq/IOKAkyB4w6MgaOG7mWkgbmfGsOG7nWkgdGEgbHXDtG4gaMaw4bubbmcgxJHhur9uIHZp4buHYyBu4bqvbSBi4bqvdCBu4buZaSBkdW5nLCBi4bqjbiBjaOG6pXQgdsOgIHPhu7EgduG6rW4gxJHhu5luZyBj4bunYSBjaMO6bmcuIFR1eSBuaGnDqm4sIGRvIGPDsyBxdcOhIG5oaeG7gXUgdMOhYyDEkeG7mW5nIMSRbyDEkcaw4bujYyB2w6Aga2jDtG5nIMSRbyDEkcaw4bujYywgaOG6p3UgaOG6v3QgY8OhYyDEkeG7kWkgdMaw4bujbmcgY2jhu4kgdGjhu4MgaGnhu4duIHPhu7EgdOG7k24gdOG6oWkgdsOgIHbhuq1uIMSR4buZbmcgcXVhIGPDoWMgxJHhurdjIHRyxrBuZy4gTeG7l2kgxJHhurdjIHRyxrBuZyBuaMawIHbhuq15IGPDsyB0aOG7gyBtw7QgdOG6oyBi4bufaSAxIGJp4bq/biBoYXkgbeG7mXQgcXXDoSB0csOsbmggbmfhuqt1IG5oacOqbi4gDQoNCiMjIyDEkOG7i25oIG5naMSpYTogDQoNCkNobyBiaeG6v24gbmfhuqt1IG5oacOqbiBYLCBt4bqrdSBuZ+G6q3Ugbmhpw6puIGvDrWNoIHRoxrDhu5tjIG4gbOG6rXAgdOG7qyBYIGzDoCB04bqtcCBo4bujcCBXbihYKSA9IChYMSwgWDLCrCwgLi4uLCBYbikgdHJvbmcgxJHDsyBYaSAoaSA9ICAxOm4pIGzDoCBjw6FjIGJp4bq/biBuZ+G6q3Ugbmhpw6puIGkuaS5kICjEkeG7mWMgbOG6rXAgdsOgIGPDsyBjw7luZyBxdXkgbHXhuq10IHBow6JuIHBo4buRaSB4w6FjIHN14bqldCB24bubaSBYKS4NCg0KIyMjIFBow6JuIGxv4bqhaSB0aGVvIHPhu5EgY2hp4buBdQ0KDQoqIE3huqt1IG5n4bqrdSBuaGnDqm4gMSBjaGnhu4F1DQoNCiogTeG6q3Ugbmfhuqt1IG5oacOqbiDEkWEgY2hp4buBdSANCg0KIyBDaOG7iSBz4buRIHRo4buRbmcga8OqIGPGoSBi4bqjbg0KDQojIyDEkOG6t2MgdHLGsG5nIHRydW5nIHTDom0gey50YWJzZXR9DQoNCiMjIyBUcnVuZyBiw6xuaCAoTWVhbikgDQoNClRydW5nIGLDrG5oIGPhu6dhIG3hu5l0IGJp4bq/biBuZ+G6q3Ugbmhpw6puIChYKSwgdGjGsOG7nW5nIMSRxrDhu6NjIHTDrW5oIHRoZW8gY8O0bmcgdGjhu6ljOg0KDQotIFRydW5nIGLDrG5oIHPhu5EgaOG7jWM6IFRoxrDhu51uZyDDoXAgZOG7pW5nIGtoaSB0w61uaCB24bubaSBz4buRIGThuqFuZyB0dXnhu4d0IMSR4buRaQ0KDQpcWyBcYmFye1h9ID0gXGZyYWN7MX17bn0gXHN1bV97aT0xfV57bn0gWF97aX1cXQ0KDQotIFRydW5nIGLDrG5oIG5ow6JuOiBUaMaw4budbmcgw6FwIGThu6VuZyBraGkgdMOtbmggdHJ1bmcgYsOsbmggY+G7p2EgdOG7tyBs4buHLCB04buRYyDEkeG7mSB0xINuZyAuLi4NCg0KDQpcW1xiYXJ7WH0gPSAoXHByb2RfaSByX3tpfSleXGZyYWN7MX17bn0gXF0NCg0KDQotIFNvIHPDoW5oIHRydW5nIGLDrG5oIGPhu5luZyB24bubaSB0cnVuZyBiw6xuaCBuaMOibiBbd2lraV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW5lcXVhbGl0eV9vZl9hcml0aG1ldGljX2FuZF9nZW9tZXRyaWNfbWVhbnMpDQoNCiogVsOtIGThu6UNCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoZ2dwdWJyKQ0KYGBgDQoNCkdp4bqjIHPhu60gbeG7mXQgZGFuaCBt4bulYyDEkeG6p3UgdMawIEIgY8OzIHThu7cgc3XhuqV0IGzhu6NpIG5odeG6rW4gaMOgbmcgbsSDbSByIGzhuqduIGzGsOG7o3QgbMOgICg5MCUsIDIwJSwgMTAlLCAzMCUsIC05MCUpDQoNClxbcl97dH0gPSAoXGZyYWN7eF97dH0gLSB4X3t0LTF9fXt4X3t0LTF9KX0pIFxdDQoNCj8gVMOtbmggbOG7o2kgc3XhuqV0IHRydW5nIGLDrG5oIG7Eg20gY+G7p2EgZGFuaCBt4bulYyBCDQoNCiogVMOtbmggdHJ1bmcgYsOsbmggY+G7mW5nICh0cnVuZyBiw6xuaCBz4buRIGjhu41jKSBs4bujaSBzdeG6pXQgaMOgbmcgbsSDbSBj4bunYSBkYW5oIG3hu6VjDQoNCmBgYHtyfQ0KciA8LSAgYyg5MCwgMjAsIDEwLCAzMCwgLTkwKS8xMDANCg0KKC45ICsgLjIgKyAuMSArIC4zIC0uOSkvNSANCg0KIyBzdW0ocikvbGVuZ3RoKHIpDQojIG1lYW4ocikgDQpgYGANCg0KKiBUw61uaCB0cnVuZyBiw6xuaCBuaMOibiBs4bujaSBzdeG6pXQgaMOgbmcgbsSDbSBj4bunYSBkYW5oIG3hu6VjDQoNCmBgYHtyfQ0KIyBOxINtIMSR4bqndSwgZGFuaCBt4bulYyB0xINuZyAxLjkgbOG6p24sIG7Eg20gMiBkYW5oIG3hu6VjIHTEg25nIDEuMiBs4bqnbiAuLi4NCmdyIDwtICByICsgMQ0KDQooMS45ICogMS4yICogMS4xICogMS4zICogMC4xKV4oMS81KSAtIDENCg0KIyBleHAoc3VtKGxvZyhncikpIC8gbGVuZ3RoKGdyKSkgLSAxDQoNCiMgcHN5Y2g6Omdlb21ldHJpYy5tZWFuKGdyKSAtIDENCg0KYGBgDQoNCg0KIyMjIFRydW5nIHbhu4sgKE1lZGlhbikNCg0KVHJ1bmcgduG7iyBsw6AgZ2nDoSB0cuG7iyBu4bqxbSBnaeG7r2EgY8OhYyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBuZ+G6q3Ugbmhpw6puLCDEkeG6t2MgdHLGsG5nIG7DoHkgdGjGsOG7nW5nIGNo4buJIGPDsyDDvSBuZ2jEqWEga2hpIGPDoWMgZ2nDoSB0cuG7iyBjw7MgdGjhu4MgY8OzIHLhu51pIHLhuqFjLCBo4buvdSBo4bqhbg0KDQotIE7hur91IGTDo3kgcXVhbiBzw6F0IGPDsyAybisxIHF1YW4gc8OhdCB44bq/cCB0aGVvIHRo4bupIHThu7EgdMSDbmcgZOG6p24gdGjDrCBnacOhIHRy4buLIHRo4bupIG4rMSBsw6AgdHJ1bmcgduG7iywgbuG6v3UgY8OzIDJuIHF1YW4gc8OhdCB0aMOsIHRydW5nIHbhu4sgbMOgIHRydW5nIGLDrG5oIGPhu6dhIGdpw6EgdHLhu4sgdGjhu6kgKDJuLTEpLzIgdsOgICgybisxKS8yDQoNCiogVsOtIGThu6U6DQoNCiAgICAtIFbDrSBk4bulIHbhu5tpIGTDo3kgY8OzIDJuKzEgcXVhbiBzw6F0IDE6MTENCiAgICANCmBgYHtyfQ0KeDEgPC0gMToxMQ0KeDENCm1lZGlhbih4MSkNCg0KYGBgDQoNCiAgLSBWw60gZOG7pSAxIGTDo3kgc+G7kSBraMOhYzogKDIsIDQsIDcsIDgsIDMsIDEsIDIpDQoNCmBgYHtyfQ0KeDIgPC0gYygyLCA0LCA3LCA4LCAzLCAxLCAyKQ0KDQojIFPhuq9wIHjhur9wIHLhu5NpIGzhuqV5IHPhu5Eg4bufIHbhu4sgdHLDrSB0aOG7qSBuKzENCngyICU+JSBzb3J0KCkgJT4lIC5bY2VpbGluZyhsZW5ndGgoLikvMildIA0KIyBtZWRpYW4oeDIpDQpgYGANCg0KICAtIFbDrSBk4bulIHbhu5tpIGTDo3kgY8OzIDJuIHF1YW4gc8OhdA0KICAgIA0KYGBge3J9DQoNCngzIDwtIHgxWy0xMV0gIyBC4buPIHPhu5EgY3Xhu5FpIGPDuW5nIMSRaQ0KDQptZWRpYW4oeDMpDQpgYGANCg0KDQojIyMgTeG7kXQgKE1vZGUpDQoNCk3hu5F0IGPhu6dhIGJp4bq/biBuZ+G6q3Ugbmhpw6puIFggbMOgIGdpw6EgdHLhu4sgdMawxqFuZyDhu6luZyB24bubaSB4w6FjIHN14bqldCBs4bubbiBuaOG6pXQuIE3hu5l0IGJp4bq/biBjw7MgdGjhu4MgY8OzIG5oaeG7gXUgbeG7kXQgdsOgIG5oxrAgduG6rXkgc+G7kSBnacOhIHRy4buLIG3hu5F0IGPDoG5nIMOtdCB0aMOsIMO9IG5naMSpYSBj4bunYSBt4buRdCBjw6BuZyBs4bubbg0KDQoqIFbDrSBk4bulOg0KYGBge3J9DQptIDwtIHNhbXBsZShjKCdhJywgJ2InLCAnYycsICdkJyksIHNpemUgPSAyMCwgcmVwbGFjZSA9IFQpDQptDQoNCm0gJT4lIHRhYmxlKCkgJT4lIHNvcnQoKQ0KDQpgYGANCg0KDQojIyDEkOG6t2MgdHLGsG5nIHbhu4EgxJHhu5kgcGjDom4gdMOhbiB7LnRhYnNldH0NCg0KIyMjIFBoxrDGoW5nIHNhaSAoVmFyaWFuY2UpDQoNCkzDoCB0cnVuZyBiw6xuaCBj4bunYSBiw6xuaCBwaMawxqFuZyBraG/huqNuZyBjw6FjaCBj4bunYSBt4buXaSDEkWnhu4NtIGThu68gbGnhu4d1IHThu5tpIHRydW5nIGLDrG5oLiBIYXkgdHJ1bmcgYsOsbmggYsOsbmggcGjGsMahbmcgY8OhYyDEkeG7mSBs4buHY2gNCg0KUGjGsMahbmcgc2FpIHThu5VuZyB0aOG7gzogXFtcc2lnbWFeMiA9IFxmcmFjezF9e259IFxzdW1fe2k9MX1ee259IChYX3tpfSAtIFxiYXJ7WH0pXjJcXQ0KDQpEbyBt4bqldCDEkWkgMSBi4bqtYyB04buxIGRvIG7Dqm4gDQpQaMawxqFuZyBzYWkgbeG6q3U6IFxbIFNeMiA9IFxmcmFjezF9e24tMX0gXHN1bV97aT0xfV57bn0gKFhfe2l9IC0gXGJhcntYfSleMlxdDQoNCiMjIyDEkOG7mSBs4buHY2ggY2h14bqpbiAoU3RhbmRhcmQgZGl2aWF0aW9uKTogc2QNCsSQbyBsxrDhu51uZyBz4buxIGJp4bq/biDEkeG7mW5nIGPhu6dhIG3huqt1IHbhu5tpIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggbeG6q3UNCg0KxJDhu5kgbOG7h2NoIGNodeG6qW4gdOG7lW5nIHRo4buDOiBcW1xzaWdtYSA9XHNxcnR7XGZyYWN7MX17bn0gXHN1bV97aT0xfV57bn0gKFhfe2l9IC0gXGJhcntYfSleMn1cXQ0KDQrEkOG7mSBs4buHY2ggY2h14bqpbiBt4bqrdTogXFtTID0gXHNxcnR7XGZyYWN7MX17bi0xfSBcc3VtX3tpPTF9XntufSAoWF97aX0gLSBcYmFye1h9KV4yfSBcXQ0KDQpTYWkgc+G7kSBjaHXhuqluIChzdGFuZGFyZCBlcnJvcikgXFtzZSA9IHNkIC8gXHNxcnR7bn1cXQ0KKHNlIHbDoCBzZCBsw6AgMiBraMOhaSBuaeG7h20gcuG6pXQgZOG7hSBi4buLIG5o4bqnbSBs4bqrbi4gU2QgxJFvIGzGsOG7o25nIHPhu7EgYmnhur9uIMSR4buZbmcgY+G7p2EgdOG6rXAgbeG6q3Ugc28gduG7m2kgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCDEkcaw4bujYyDGsOG7m2MgbMaw4bujbmcgdOG7qyB04bqtcCBt4bqrdS4NCk5oxrBuZyBnacOhIHRy4buLIHRydW5nIGLDrG5oIMaw4bubYyBsxrDhu6NuZyDEkcaw4bujYyBraMO0bmcgcGjhuqNpIGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRo4buxYyBz4buxIGPhu6dhIHThu5VuZyB0aOG7gywgZ2nDoSB0cuG7iyBuw6B5IHBo4bulIHRodeG7mWMgdsOgbyBt4bqrdSBs4buxYSBjaOG7jW4sIGtoaSB0aGF5IMSR4buVaSBj4buhIG3huqt1IGhv4bq3YyB0aOG7nWkgZ2lhbiBs4bqleSBt4bqrdSAuLi4gdGjDrCBnacOhIHRy4buLIG7DoHkgc+G6vSB0aGF5IMSR4buVaS4gDQpTRSDEkW8gbMaw4budbmcgc+G7sSBjaMOtbmggeMOhYyBj4bunYSBnacOhIHRy4buLIHRydW5nIGLDrG5oIMSRw6MgxrDhu5tjIGzGsOG7o25nIMSRxrDhu6NjIHThu6sgbeG6q3UuIE3huqt1IGPDoG5nIGzhu5tuIHRow6wgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCDGsOG7m2MgbMaw4bujbmcgY8OgbmcgdOG7kXQgaMahbiBoYXkgU0UgY8Ogbmcgbmjhu48gaMahbiANCikNCiBbc28gc8OhbmhdKGh0dHA6Ly93d3ctaXN0Lm1hc3NleS5hYy5uei9kc3Rpcmxpbi9DQVNUL0NBU1QvSHNlTWVhbi9zZU1lYW43Lmh0bWwpDQojIyMgU2FpIHPhu5EgdHJ1bmcgYsOsbmggdHV54buHdCDEkeG7kWkNCg0KXFsgQVNEID0gXGZyYWN7MX17bn0gXHN1bV97aT0xfV57bn0gfFhfe2l9IC0gXGJhcntYfXxcXQ0KDQoNCiMjIyBU4bupIHBow6JuIHbhu4sNCg0KKiBT4bqvcCB44bq/cCBz4buRIGxp4buHdSBxdWFuIHPDoXQgdGhlbyBjaGnhu4F1IHTEg25nIGThuqduLCBjw6FjIGdpw6EgdHLhu4sgdMawxqFuZyDhu6luZyB24bubaSBjw6FjIHThuqduIHN14bqldCB0w61jaCBsdeG7uSAyNSUsIDUwJSwgNzUlIGfhu41pIGzDoCB04bupIHBow6JuIHbhu4sgdGjhu6kgbmjhuqV0LCB0aOG7qSBoYWkgdsOgIHRo4bupIDM7IGvDvSBoaeG7h3UgUTEsIFEyLCB2w6AgUTMuIEtob+G6o25nIHThu6sgZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgxJHhur9uIFExIGfhu41pIGzDoCBraG/huqNuZyB04bupIHBow6JuIHbhu4sgdGjhu6kgbmjhuqV0IChTUTEpOyBraG/huqNuZyB04burIFExIMSR4bq/biBRMiBn4buNaSBsw6Aga2hv4bqjbmcgdOG7qSBwaMOibiB24buLIHRo4bupIDIgKFNRMikgLi4uDQoNCiogVGjDtG5nIHRoxrDhu51uZyBjw6FjIGdpw6EgdHLhu4sgcXVhbiBzw6F0IHThuq1wIHRydW5nIHRyb25nIGtob+G6o25nIChRMSwgUTMpIGtob+G6o25nIG7DoHkgZ+G7jWkgbMOgIGtob+G6o25nIGdpw6EgdHLhu4sgY2h14bqpbiANCg0KKiBRMSBsw6AgZ2nDoSB0cuG7iyBxdWFuIHPDoXQgdGjhu6kgaSgxKSB4w6FjIMSR4buLbmggdGhlbyBjw7RuZyB0aOG7qWMgaSgxKT0obisxKS80LiBO4bq/dSBuKzEga2jDtG5nIGNoaWEgaOG6v3QgY2hvIDQsIGNo4bqzbmcgaOG6oW4gbj0yMiwgKG4rMSkvND01ICBuZ8aw4budaSB0YSBjaOG7jW4gUTEgbMOgIGdpw6EgdHLhu4sgbuG6sW0g4bufIHbhu4sgdHLDrSAzLzQgY+G7p2Ega2hv4bqjbmcgWDUgdsOgIFg2LiBU4bupIHBow6JuIHbhu4sgdGjhu6kgMyBjxaluZyB0w61uaCB0xrDGoW5nIHThu7EgbmjGsCB24bqteS4gQ2jhurNuZyBo4bqhbiB24bqrbiB24bubaSBuPTIyIHRow6wgaSgzKT0zKG4rMSkvND0xNyAuDQoNCmBgYHtyfQ0KeDQgPC0gMToyMQ0KeDUgPC0gc2VxKDYsIDE2LCBieSA9IDAuNSkNCg0KeDQNCg0KeDUNCg0KcXVhbnRpbGUoeDQsIGMoLjI1LCAwLjUsIDAuNzUpKQ0KDQpxdWFudGlsZSh4NSwgYyguMjUsIDAuNSwgMC43NSkpDQoNCg0KZGF0YS5mcmFtZSh4NCwgeDUpICU+JSANCiAgZ2F0aGVyKCkgJT4lIGdncGxvdCgpICsNCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0ga2V5LCB5ID0gdmFsdWUpKQ0KDQpgYGANCg0KLS0+IGPDoWMgcXVhbiBzw6F0IGPhu6dhIHg0IHBow6JuIHTDoW4gaMahbiBzbyB24bubaSB4NQ0KDQojIyMgS2hv4bqjbmcgYmnhur9uIHRoacOqbiAocmFuZ2UpDQoNCsSQxrDhu6NjIHTDrW5oIGLhuqNuZyDEkeG7mSBs4bubbiBj4bunYSBoaeG7h3UgaGFpIGdpw6EgdHLhu4sgcXVhbiBzw6F0IGzhu5tuIG5o4bqldCB2w6Agbmjhu48gbmjhuqV0DQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTU4KQ0KeDYgPC0gYyhzYW1wbGUoMToyMSwgc2l6ZSA9IDE5LCByZXBsYWNlID0gVFJVRSksIDEsIDIxKQ0KeDYNCg0KbWF4KHg2KSAtIG1pbih4NikNCg0KbWF4KHg0KSAtIG1pbih4NCkNCg0KYGBgDQoNCiMjIyBI4bqhbmcgY+G7p2EgZMOjeSBxdWFuIHPDoXQgKHJhbmspDQoNCiogSOG6oW5nIGPhu6dhIGTDo3kgcXVhbiBzw6F0IGzDoCAqKnPhu5EgcXVhbiBzw6F0IGtow6FjIG5oYXUqKiBj4bunYSBkw6N5IHPhu5EgDQoNCiogTuG6v3UgaGF5IGTDo3kgcXVhbiBzw6F0IGPDsyBraG/huqNuZyBiaeG6v24gdGhpw6puIG5oxrAgbmhhdSB0aMOsIGPDsyB0aOG7gyBzbyBzw6FuaCBo4bqhbmcgY+G7p2EgY2jDum5nIMSR4buDIHNvIHPDoW5oIMSR4buZIHBow6JuIHTDoW4uDQoNCmBgYHtyfQ0KbWluX3JhbmsoeDQpICU+JSB0YWJsZSgpICU+JSBuYW1lcygpICU+JSBsZW5ndGgoKQ0KDQptaW5fcmFuayh4NikgJT4lIHRhYmxlKCkgJT4lIG5hbWVzKCkgJT4lIGxlbmd0aCgpDQoNCmBgYA0KDQoqIEzGsHUgw706IMSQw6J5IGzDoCBo4bqhbmcgY+G7p2EgZMOjeSBz4buRIGNo4bupIGtow7RuZyBwaOG6o2kgbMOgIGjhuqFuZyBj4bunYSB04burbmcgcXVhbiBzw6F0IHRyb25nIGTDo3kgc+G7kQ0KDQpI4bqhbmcgY+G7p2EgZMOjeSBz4buRIHg0IGzDoCAyMSwgaOG6oW5nIGPhu6dhIGTDo3kgc+G7kSB4NiBsw6AgMTQNCi0tPiB4NiBjw7MgY8OhYyBxdWFuIHPDoXQgcGjDom4gdMOhbiBoxqFuIHg0DQoNCmBgYHtyfQ0KZGF0YS5mcmFtZSh4NiwgY291bnQgPSBtaW5fcmFuayh4NikpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh5ID0gY291bnQsIHggPSA2KSwgY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAyKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSA1LCB5ID0geDQpLCBhbHBoYSA9IDAuMykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoNSw2KSkNCg0KYGBgDQoNCiMjIyBI4buHIHPhu5EgYmnhur9uIHRoacOqbg0KDQpI4buHIHPhu5EgYmnhur9uIHRoacOqbiBsw6AgdOG7tyBz4buRIGdp4buvYSDEkeG7mSBs4buHY2ggdGnDqnUgY2h14bqpbiB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaA0KDQpI4buHIHPhu5EgbsOgeSBjw6BuZyBs4bubbiB0aMOsIHF1YW4gc8OhdCBj4bunYSBkw6N5IHPhu5EgY8OgbmcgcGjDom4gdMOhbiBoxqFuDQoNCmBgYHtyfQ0Kc2QoeDQpIC8gbWVhbih4NCkNCg0Kc2QoeDYpIC8gbWVhbih4NikNCmBgYA0KDQoNCiMjIEPDoWMgxJHhurdjIHRyxrBuZyBk4bqhbmcgcGjDom4gcGjhu5FpIHsudGFic2V0fQ0KDQpIYWkgxJHhurdjIHRyxrBuZyBjxqEgYuG6o24gduG7gSBk4bqhbmcgcGjDom4gcGjhu5FpIGzDoCDEkeG7mSBi4bqldCDEkeG7kWkgeOG7qW5nIHbDoCDEkeG7mSBuaOG7jW4NCg0KDQojIyMgxJDhu5kgYuG6pXQgxJHhu5FpIHjhu6luZyAoxJHhu5kgeGnDqm4pIChza2V3bmVzcykNCg0KKiBDw7RuZyB0aOG7qWMgdMOtbmg6IFt3aWtpXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Ta2V3bmVzcykNCg0KXFtTa2V3ID0gXGZyYWN7XGZyYWN7MX17bn0gXHN1bV97aT0xfV57bn0gKFhfe2l9IC0gXGJhcntYfSleM317XHNxcnR7XGZyYWN7MX17bi0xfSBcc3VtX3tpPTF9XntufSAoWF97aX0gLSBcYmFye1h9KV4yfV4zfSBcXQ0KDQoqIE5lZ2F0aXZlIHNrZXc6IMSRdcO0aSBiw6puIHRyw6FpIGTDoGkgaMahbiB+IHBow6JuIHBo4buRaSBs4buHY2ggdHLDoWkNCg0KKiBtZWFuIDwgbWVkaWFuIDwgbW9kZQ0KDQpgYGB7cn0NCm5lZ2F0aXZlX3NrZXcgPC0gZGF0YS5mcmFtZShuZWdhdGl2ZV9za2V3ID0gcmJldGEoMTAwMCw1MCwyKSkNCg0KbmVnYXRpdmVfc2tldyAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gbmVnYXRpdmVfc2tldyksIGZpbGwgPSAncmVkJywgYWxwaGE9IDAuMikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbihuZWdhdGl2ZV9za2V3KSksIGNvbG9yID0gJ2dyZWVuJywgc2l6ZSA9IDIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lZGlhbihuZWdhdGl2ZV9za2V3KSksIGNvbG9yID0gJ2JsdWUnLCBzaXplID0gMikgKw0KICBnZW9tX3RleHQoYWVzKHggPSBtZWFuKG5lZ2F0aXZlX3NrZXcpLCB5ID0gMCwgbGFiZWwgPSAibWVhbiIpLCBhbmdsZSA9IDkwLCBoanVzdCA9IC0xLCB2anVzdCA9IC0wLjUpICsNCiAgZ2VvbV90ZXh0KGFlcyh4ID0gbWVkaWFuKG5lZ2F0aXZlX3NrZXcpLCB5ID0gMCwgbGFiZWwgPSAibWVkaWFuIiksIGFuZ2xlID0gOTAsIGhqdXN0ID0gLTEuNSwgdmp1c3QgPSAyKSArDQogIGxhYnModGl0bGUgPSAiTmVnYXRpdmUgc2tldyIsDQogICAgICAgeCA9ICdYJywNCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogQkkgLSBTZUFiYW5rIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCiAgDQpkZXNjcmliZShuZWdhdGl2ZV9za2V3KQ0KYGBgDQoNCiogUG9zaXRpdmUgc2tldzogxJF1w7RpIGLDqm4gcGjhuqNpIGTDoGkgaMahbiB+IHBow6JuIHBo4buRaSBs4buHY2ggcGjhuqNpDQoNCiogVHJvbmcgdHLGsOG7nW5nIGjhu6NwIG7DoHkgbW9kZSA8IG1lZGlhbiA8IG1lYW4NCg0KYGBge3J9DQpwb3NpdGl2ZV9za2V3IDwtIGRhdGEuZnJhbWUocG9zaXRpdmVfc2tldyA9IHJiZXRhKDEwMDAsIDIsIDUwKSkNCg0KcG9zaXRpdmVfc2tldyAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gcG9zaXRpdmVfc2tldyksIGZpbGwgPSAncmVkJywgYWxwaGE9IDAuMikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbihwb3NpdGl2ZV9za2V3KSksIGNvbG9yID0gJ2dyZWVuJywgc2l6ZSA9IDEuNSkgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVkaWFuKHBvc2l0aXZlX3NrZXcpKSwgY29sb3IgPSAnYmx1ZScsIHNpemUgPSAxLjUpICsNCiAgZ2VvbV90ZXh0KGFlcyh4ID0gbWVhbihwb3NpdGl2ZV9za2V3KSwgeSA9IDAsIGxhYmVsID0gIm1lYW4iKSwgYW5nbGU9OTAsIGhqdXN0ID0gLTEsIHZqdXN0ID0gMSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSBtZWRpYW4ocG9zaXRpdmVfc2tldyksIHkgPSAwLCBsYWJlbCA9ICJtZWRpYW4iKSwgYW5nbGU9OTAsIGhqdXN0ID0gLTEuNSwgdmp1c3QgPSAtMC41KSsNCiAgbGFicyh0aXRsZSA9ICJQb3NpdGl2ZSBza2V3IiwNCiAgICAgICB4ID0gJ1gnLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBCSSAtIFNlQWJhbmsiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KICANCg0KZGVzY3JpYmUocG9zaXRpdmVfc2tldykNCmBgYA0KDQojIyMgxJDhu5kgbmjhu41uIChLdXJ0b3NpcykNCg0KKiBDw7RuZyB0aOG7qWMgdMOtbmg6IFt3aWtpXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9LdXJ0b3NpcykNCg0KIFxbIEt1cnQgPSBcZnJhY3tcZnJhY3sxfXtufSBcc3VtX3tpPTF9XntufSAoWF97aX0gLSBcYmFye1h9KV40fXsoXGZyYWN7MX17bn0gXHN1bV97aT0xfV57bn0gKFhfe2l9IC0gXGJhcntYfSleMileMn0gXF0NCg0KKiBTbyBzw6FuaCDEkeG7mSBuaOG7jW4gY+G7p2EgMiBwaMOibiBwaOG7kWkgDQoNCmBgYHtyfQ0KDQpzZXQuc2VlZCgxNTgpDQoNCmRmIDwtIGRhdGEuZnJhbWUoeDEgPSBybm9ybSgxMDAwMCwgbWVhbiA9IDAsIHNkID0gMyksDQogICAgICAgICAgICAgICAgIHgyID0gcm5vcm0oMTAwMDAsIG1lYW4gPSAwLCBzZCA9IDEpLA0KICAgICAgICAgICAgICAgICB4MyA9IHJub3JtKDEwMDAwLCBtZWFuID0gNSwgc2QgPSAxKSkgDQogICAgICAgICAgICAgICAgIA0KZGYgJT4lIA0KZ2dwbG90KCkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSB4MSksIGZpbGwgPSAncmVkJywgYWxwaGEgPSAwLjIpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0geDIpLCBmaWxsID0gJ2JsdWUnLCBhbHBoYSA9IDAuMikrDQogIGdlb21fdGV4dChhZXMoeCA9IG1lYW4oeDEpLCB5ID0gMC4xKSwgDQogICAgICAgICAgICBsYWJlbCA9IHBhc3RlKCdLdXJ0b3NpcycsIHJvdW5kKGt1cnRvc2koZGYkeDEpLCAyKSksIA0KICAgICAgICAgICAgY29sb3IgPSAncmVkJykgKw0KICBnZW9tX3RleHQoYWVzKHggPSBtZWFuKHgxKSwgeSA9IDAuNCksIA0KICAgICAgICAgICAgbGFiZWwgPSBwYXN0ZSgnS3VydG9zaXMnLHJvdW5kKGt1cnRvc2koZGYkeDIpLCAyKSksIA0KICAgICAgICAgICAgY29sb3IgPSAnYmx1ZScpICsNCiAgbGFicyh0aXRsZSA9ICJDb21wYXJlIGt1cnRvc2lzIG9mIHR3byBkaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAnWCcsDQogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEJJIC0gU2VBYmFuayAiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KDQpgYGANCg0KDQojIyBQaMOibiBwaOG7kWkgeMOhYyBzdeG6pXQgey50YWJzZXR9DQoNClBow6JuIHBo4buRaSB4w6FjIHN14bqldCBsw6AgcXV5IGx14bqtdCBjaG8gYmnhur90IGPDoWNoIGfDoW4gbeG7l2kgeMOhYyBzdeG6pXQgY2hvIG3hu5dpIGtob+G6o25nIGdpw6EgdHLhu4sgY+G7p2EgdOG6rXAgc+G7kSB0aOG7sWMsIHNhbyBjaG8gY8OhYyB0acOqbiDEkeG7gSB4w6FjIHN14bqldCDEkcaw4bujYyB0aOG7j2EgbcOjbg0KDQojIyMgUGjDom4gcGjhu5FpIGNodeG6qW46IFt3aWtpXShodHRwczovL3ZpLndpa2lwZWRpYS5vcmcvd2lraS9QaCVDMyVBMm5fcGglRTElQkIlOTFpX2NodSVFMSVCQSVBOW4pDQoNCiMjIyMgS2jDoWkgbmnhu4dtDQoNCiogUGjDom4gcGjhu5FpIGNodeG6qW4gKGPDsm4gZ+G7jWkgbMOgIHBow6JuIHBo4buRaSBHYXVzcyk6IGzDoCBt4buZdCBwaMOibiBwaOG7kWkgeMOhYyBzdeG6pXQgY+G7sWMga8OsIHF1YW4gdHLhu41uZyB0cm9uZyBuaGnhu4F1IGzEqW5oIHbhu7FjLiBOw7MgbMOgIGjhu40gcGjDom4gcGjhu5FpIGPDsyBk4bqhbmcgdOG7lW5nIHF1w6F0IGdp4buRbmcgbmhhdSwgY2jhu4kga2jDoWMgdGhhbSBz4buRIHRydW5nIGLDrG5oIM68IHbDoCBwaMawxqFuZyBzYWkgz4MyLg0KDQoqIFBow6JuIHBo4buRaSBjaHXhuqluIHThuq9jIChzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uKTogbMOgIHBow6JuIHBo4buRaSBjaHXhuqluIHbhu5tpIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggYuG6sW5nIDAgdsOgIHBoxrDGoW5nIHNhaSBi4bqxbmcgMS4gUGjDom4gcGjhu5FpIGNodeG6qW4gY8OybiDEkcaw4bujYyBn4buNaSBsw6AgxJHGsOG7nW5nIGNvbmcgY2h1w7RuZyAoYmVsbCBjdXJ2ZSkgdsOsIMSR4buTIHRo4buLIGPhu6dhIG3huq10IMSR4buZIHjDoWMgc3XhuqV0IGPDsyBk4bqhbmcgY2h1w7RuZy4NCg0KYGBge3J9DQpkZW5zaXR5X2xhYmVsIDwtIGV4cHJlc3Npb24oZih4KSA9PSBwYXN0ZShmcmFjKDEsIHNxcnQoMiAqIHBpICogc2lnbWFeMikpLCAiICIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZV57ZnJhYygtKHggLSBtdSleMiwgMiAqIHNpZ21hXjIpfSkpDQoNCmRmICU+JQ0KICBnZ3Bsb3QoKSArDQogIGdlb21fZGVuc2l0eShhZXMoeCA9IHgyKSwgZmlsbCA9ICJwaW5rIikgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMC4yLA0KICAgICAgICAgICAgICAgIGxhYmVsID0gcGFzdGUoJ01lYW4gPSAwJykpKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDAsIHkgPSAwLjE3LA0KICAgICAgICAgICAgICAgIGxhYmVsID0gcGFzdGUoJ1NkID0gMScpKSkgKw0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgb2Ygc3RhbmRhcmQgbm9ybWFsIGRpc3RyaWJ1dGlvbiIsDQogICAgICAgeCA9ICJYIiwNCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogQkkgLSBTZUFiYW5rIikgKw0KICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gZGVuc2l0eV9sYWJlbCwgeCA9IC0yLCB5ID0gMC4zICkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgDQoNCg0KYGBgDQoNCg0KIyMjIyDEkOG6t2MgdMOtbmggY+G7p2EgcGjDom4gcGjhu5FpIGNodeG6qW4NCg0KQ8OzIG5oaeG7gXUgY8OhY2ggxJHhu4MgdGjhu4MgaGnhu4duIGPDoWMgxJHhurdjIHTDrW5oIGPhu6dhIG3hu5l0IHBow6JuIHBo4buRaSB4w6FjIHN14bqldDoNCg0KKiBDw6FjaCBk4buFIHRo4bqleSBuaOG6pXQgbMOgIHRow7RuZyBxdWEgaMOgbSBt4bqtdCDEkeG7mSB4w6FjIHN14bqldCwgbsOzIGNobyBiaeG6v3Qga2jhuqMgbsSDbmcgeOG6o3kgcmEgY+G7p2EgbeG7l2kgZ2nDoSB0cuG7iyBj4bunYSBiaeG6v24gbmfhuqt1IG5oacOqbi4gDQoNCiogSMOgbSBwaMOibiBwaOG7kWkgdMOtY2ggbMWpeSBjxaluZyBjaG8gY8O5bmcgdGjDtG5nIHRpbiwgbmjGsG5nIGjDrG5oIOG6o25oIGPhu6dhIG7DsyB0aMOsIHRow7RuZyB0aW4gY2jhu6lhIMSR4buxbmcga2jDtG5nIGThu4Ugbmjhuq1uIHRo4bqleSBjaG8uIA0KKiBN4buZdCBjw6FjaCBraMOhYyB0xrDGoW5nIMSRxrDGoW5nIGtoaSBjaOG7iSDEkeG7i25oIG3hu5l0IHBow6JuIHBo4buRaSBjaHXhuqluIGzDoCB0aMO0bmcgcXVhOiBtw7RtZW4sIMaw4bubYyBsxrDhu6NuZywgaMOgbSDEkeG6t2MgdHLGsG5nLCAuLi4gDQoNCmBgYHtyfQ0KDQpjZGZfbGFiZWwgPC0gZXhwcmVzc2lvbihwaGkoeCkgPT0gcGFzdGUoZnJhYygxLCBzcXJ0KDIgKiBwaSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAiLCBpbnRlZ3JhbChlXigtdF4yLzIpICogZHQsIC1pbmZpbml0eSwgeCkpKQ0KDQpzZXQuc2VlZCgxNTgpDQoNCjE6NSAlPiUgDQogIG1hcF9kZmMocm5vcm0sIG4gPSAxMDAwLCBzZCA9IDEpIC0+PiBkZjINCg0KDQpkZjIgICU+JSANCiAgZ2F0aGVyKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHZhbHVlKSkgKw0KICBzdGF0X2VjZGYoYWVzKGNvbG91ciA9IGtleSkpICsgDQogIGxhYnModGl0bGUgPSAiQ3VtbXVsYXRpdmUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIiwNCiAgICAgICB4ID0gIlgiLA0KICAgICAgIHkgPSAiUHJvYmFiaWxpdHkiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBCSSAtIFNlQWJhbmsiKSArDQogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSBjZGZfbGFiZWwsIHggPSAwLCB5ID0gMC44NSApICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IlBhcmFtZXRlciIsDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YyhleHByZXNzaW9uKHBhc3RlKG11LCAiID0gMSwgIiwgIHNpZ21hLCAiID0gMSIpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24ocGFzdGUobXUsICIgPSAyLCAiLCAgc2lnbWEsICIgPSAxIikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbihwYXN0ZShtdSwgIiA9IDMsICIsICBzaWdtYSwgIiA9IDEiKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKHBhc3RlKG11LCAiID0gNCwgIiwgIHNpZ21hLCAiID0gMSIpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24ocGFzdGUobXUsICIgPSA1LCAiLCAgc2lnbWEsICIgPSAxIikpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPWMoInJlZCIsICJvcmFuZ2UiLCAieWVsbG93IiwgImdyZWVuIiwgImJsdWUiKSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCg0KZGYyICU+JSBkZXNjcmliZSgpDQogIA0KDQpgYGANCg0KIyMjIFBow6JuIHBo4buRaSBULXN0dWRlbnQgW3dpa2ldKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N0dWRlbnQlMjdzX3QtZGlzdHJpYnV0aW9uKQ0KDQoqIEzDoCBwaMOibiBwaOG7kWkgxJHGoW4gZ2nhuqNuIG5o4bqldCwgaMOgbSBwaMOibiBwaOG7kWkgY2jhu4kgY8OzIHRoYW0gc+G7kSBkdXkgbmjhuqV0IGzDoCBz4buRIGLhuq1jIHThu7EgZG8NCg0KKiDhu6huZyBk4bulbmcgdHJvbmcgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSwga2nhu4NtIMSR4buLbmggdGhhbSBz4buRDQoNCiogS2hpIHPhu5EgYuG6rWMgdOG7sSBkbyBs4bubbiBwaMOibiBwaOG7kWkgVC1zdHVkZW50IHRp4buHbSBj4bqtbiBwaMOibiBwaOG7kWkgY2h14bqpbg0KDQpgYGB7cn0NCnNldC5zZWVkKDE1OCkNCg0KZGYzIDwtIGRhdGEuZnJhbWUoazEgPSBydCgxMDAwLCAxKSwNCiAgICAgICAgICAgICAgICAgIGsyID0gcnQoMTAwMCwgMiksDQogICAgICAgICAgICAgICAgICBrMyA9IHJ0KDEwMDAsIDMpLA0KICAgICAgICAgICAgICAgICAgazUgPSBydCgxMDAwLCA1KSwNCiAgICAgICAgICAgICAgICAgIGsxMCA9IHJ0KDEwMDAsIDEwKSwNCiAgICAgICAgICAgICAgICAgIGszMCA9IHJ0KDEwMDAsIDEwKSkNCg0KZGYzICU+JSBnYXRoZXIoKSAlPiUgDQogIG11dGF0ZShrZXkgPSBmY3RfcmVsZXZlbChrZXksICJrMSIsICJrMiIsICJrMyIsICJrNSIsICJrMTAiLCAiazMwIikpICAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gdmFsdWUsIGNvbG9yID0ga2V5KSwgYWxwaGEgPSAwLCBzaXplID0gMSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtNiwgNikpICsNCiAgZmFjZXRfd3JhcCggfmtleSkNCg0KZGYzICU+JSBnYXRoZXIoKSAlPiUgDQogIG11dGF0ZShrZXkgPSBmY3RfcmVsZXZlbChrZXksICJrMSIsICJrMiIsICJrMyIsICJrNSIsICJrMTAiLCAiazMwIikpICAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gdmFsdWUsIGNvbG9yID0ga2V5KSwgYWxwaGEgPSAwKSArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC00LCA0KSkgDQoNCmBgYA0KDQoqIFNvIHPDoW5oIHBow6JuIHBo4buRaSBjaHXhuqluIHbDoCBULXN0dWRlbnQgayA9IDMwDQoNCmBgYHtyfQ0KZGY0IDwtIGRhdGEuZnJhbWUoeCA9IHJub3JtKDEwMDAsIDAsIDEpLA0KICAgICAgICAgICAgICAgICAgeSA9IHJub3JtKDEwMDAsIDUsIDEpLA0KICAgICAgICAgICAgICAgICAgeiA9IHJ0KDEwMDAsIDMwKSkNCg0KDQpwMSA8LSBkZjQgJT4lIGdncGxvdCgpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4KSwgYWxwaGEgPSAwLjMsIGZpbGwgPSAnI0M0MkUyNicpKw0KICBnZW9tX2RlbnNpdHkoYWVzKHopLCBhbHBoYSA9IDAuMiwgZmlsbCA9ICdibHVlJykgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMC4xKSwgbGFiZWwgPSBwYXN0ZSgnTm9ybWFsLCBtZWFuID0gMCwgc2QgPSAxJykpICsNCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMCwgeSA9IDAuMiksIGxhYmVsID0gcGFzdGUoJ1Qtc3R1ZGVudCwgayA9IDMwJykpICsNCiAgbGFicyh4ID0gJ3gteicpDQoNCg0KDQpwMiA8LWRmNCAlPiUgZ2dwbG90KCkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHkpLCBhbHBoYSA9IDAuMywgZmlsbCA9ICcjQzQyRTI2JykrDQogIGdlb21fZGVuc2l0eShhZXMoeiksIGFscGhhID0gMC4yLCBmaWxsID0gJ2JsdWUnKSArDQogIGdlb21fdGV4dChhZXMoeCA9IDUsIHkgPSAwLjEpLCBsYWJlbCA9IHBhc3RlKCdOb3JtYWwsIG1lYW4gPSA1LCBzZCA9IDEnKSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMC4yKSwgbGFiZWwgPSBwYXN0ZSgnVC1zdHVkZW50LCBrID0gMzAnKSkgKw0KICBsYWJzKHggPSAneS16JykNCg0Kc3RhYmxlPC0gZGY0ICU+JSANCiAgZGVzY3JpYmUoKSAlPiUgDQogIG11dGF0ZV9pZihpcy5udW1lcmljLCBmdW5jdGlvbih4KXtyb3VuZCh4LCBkaWdpdHMgPSAyKX0pICU+JSANCiAgbXV0YXRlKHZhcnMgPSBjKCJ4IiwgInkiLCAieiIpKQ0KDQpzdGFibGUucCA8LSBnZ3RleHR0YWJsZShzdGFibGUsIHJvd3MgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0dGhlbWUoIm1SZWQiKSkNCg0KZ2dhcnJhbmdlKA0KICBnZ2FycmFuZ2UocDEsIHAyLCBuY29sID0gMiksDQogIHN0YWJsZS5wLA0KICBucm93ID0gMikNCg0KYGBgDQoNCiMjIyBQaMOibiBwaOG7kWkga2jDoWMNCg0KW1NlZSBtb3JlXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvdmlld3MvRGlzdHJpYnV0aW9ucy5odG1sKQ0KDQpbU2VlIG1vcmVdKGh0dHA6Ly93d3cuc3RhdC51bW4uZWR1L2dleWVyL29sZC81MTAxL3Jsb29rLmh0bWwpDQoNClIgRnVuY3Rpb25zIGZvciBQcm9iYWJpbGl0eSBEaXN0cmlidXRpb25zDQpFdmVyeSBkaXN0cmlidXRpb24gdGhhdCBSIGhhbmRsZXMgaGFzIGZvdXIgZnVuY3Rpb25zLiBUaGVyZSBpcyBhIHJvb3QgbmFtZSwgZm9yIGV4YW1wbGUsIHRoZSByb290IG5hbWUgZm9yIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGlzIG5vcm0uIFRoaXMgcm9vdCBpcyBwcmVmaXhlZCBieSBvbmUgb2YgdGhlIGxldHRlcnMNCg0KcCBmb3IgInByb2JhYmlsaXR5IiwgdGhlIGN1bXVsYXRpdmUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIChjLiBkLiBmLikNCg0KcSBmb3IgInF1YW50aWxlIiwgdGhlIGludmVyc2UgYy4gZC4gZi4NCg0KZCBmb3IgImRlbnNpdHkiLCB0aGUgZGVuc2l0eSBmdW5jdGlvbiAocC4gZi4gb3IgcC4gZC4gZi4pDQoNCnIgZm9yICJyYW5kb20iLCBhIHJhbmRvbSB2YXJpYWJsZSBoYXZpbmcgdGhlIHNwZWNpZmllZCBkaXN0cmlidXRpb24NCg0KRm9yIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uLCB0aGVzZSBmdW5jdGlvbnMgYXJlIHBub3JtLCBxbm9ybSwgZG5vcm0sIGFuZCBybm9ybS4gRm9yIHRoZSBiaW5vbWlhbCBkaXN0cmlidXRpb24sIHRoZXNlIGZ1bmN0aW9ucyBhcmUgcGJpbm9tLCBxYmlub20sIGRiaW5vbSwgYW5kIHJiaW5vbS4gQW5kIHNvIGZvcnRoLg0KDQojIyMgQ2h14bqpbiBow7NhIDEgdmVjdG9yIGhheSAxIGJp4bq/biBz4buRIA0KDQotIE3hu6VjIMSRw61jaDogY2h1eeG7g24gY8OhYyBiaeG6v24gduG7gSBjw7luZyAxIMSR4buZIMSRby4gDQpWw60gZOG7pTogS2hpIHBow6JuIHTDrWNoIGTDsm5nIHRp4buBbiBn4butaSBj4bunYSBraMOhY2ggaMOgbmcgdGhlbyB0aMOhbmcsIGPDsyAyIGJp4bq/biBz4buRIGzGsOG7o25nIG5nxrDhu51pIGfhu61pICjEkXY6IG5nxrDhu51pKSwgc+G7kSB0aeG7gW4gZ+G7rWkgKMSRdjogxJHhu5NuZykuIE7hur91IHbhur0gMiBiaeG6v24gbsOgeSB0csOqbiBjw7luZyAxIMSR4buTIHRo4buLIHRow6wgY+G6p24gcGjhuqNpIGPDsyAyIHRy4bulYyBZIGPDsyAyIMSRxqFuIHbhu4sga2jDoWMgbmhhdS4gVGhheSB2w6wgbMOgbSB2aeG7h2MgxJHDsywgdGEgcXV5IGPDoWMgYmnhur9uIHbhu4EgY8O5bmcgMSDEkeG7mSDEkW8gKOG7nyDEkcOieSBsw6AgY2h14bqpbiBow7NhIHZlY3RvcikNCg0KLSBTYXUga2hpIGNodeG6qW4gaMOzYSDEkeG6t2MgxJFp4buDbSBj4bunYSBiaeG6v24ga2jDtG5nIGLhu4sgdGhheSDEkeG7lWkgKHbDrCB04bqldCBj4bqjIGPDoWMgcXVhbiBzw6F0IMSR4buBdSDDoXAgZOG7pW5nIGNodW5nIDEgcnVsZSkNCg0KLSBDaHXhuqluIGjDs2Ega2jDtG5nIGPDsyBuZ2jEqWEgbMOgIGNodXnhu4NuIDEgYmnhur9uIGPDsyBwaMOibiBwaOG7kWkga2jDoWMgduG7gSBwaMOibiBwaOG7kWkgY2h14bqpbg0KDQpgYGB7cn0NCng0IDwtIHNhbXBsZSgxOjIwLCBzaXplID0gMTAwLCByZXBsYWNlID0gVFJVRSkNCm5vcm1hbGl6ZWRfeDQgIDwtICh4NCAtIG1lYW4oeDQpKSAvIHNkKHg0KSAjIHNjYWxlKHg0KQ0KDQpnZ3Bsb3QoKSsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4NCksIGZpbGwgPSAidG9tYXRvIikgDQoNCmdncGxvdCgpKyAgDQogIGdlb21fZGVuc2l0eShhZXMobm9ybWFsaXplZF94NCksIGZpbGwgPSAiZ3JlZW4iLCBhbHBoYSA9IDAuMykNCg0KYGBgDQoNCiMjIMav4bubYyBsxrDhu6NuZyBraG/huqNuZyB0aW4gY+G6rXkgey50YWJzZXR9DQoNCkNobyBYIGzDoCBt4buZdCBiaeG6v24gbmfhuqt1IG5oacOqbiBjw7MgcGjDom4gYuG7kSBn4buRYyBGKHgsIFwoXHRoZXRhXCkgKSDEkcOjIGJp4bq/dCBk4bqhbmcsIG5oxrBuZyB0aGFtIHPhu5EgXChcdGhldGFcKSBjaMawYSBiaeG6v3QuIE7hur91IFggcuG7nWkgcuG6oWMgdGjDrCBwaMOibiBi4buRIGfhu5FjIGPDsyB0aOG7gyB0aOG7gyBoaeG7h24gcXVhIGjDoG0geMOhYyBzdeG6pXQgcCh4LCBcKFx0aGV0YVwpICk7IHbhu5tpIFggbMOgIGJp4bq/biBuZ+G6q3Ugbmhpw6puIGxpw6puIHThu6VjIHBow6JuIHBo4buRaSBn4buRYyBjw7MgdGjhu4MgYmnhu4N1IHRo4buLIHF1YSBow6BtIG3huq10IMSR4buZIGYoeCwgXChcdGhldGFcKSkuDQoJDQpWaeG7h2MgdMOsbSDEkcaw4bujYyBnacOhIHRy4buLIMSRw7puZyBj4bunYSB0aGFtIHPhu5EgXChcdGhldGFcKSB0aMaw4budbmcgcuG6pXQga2jDsyBraMSDbiB2w6wgxJFp4buBdSBuw6B5IMSRw7JpIGjhu49pIHBo4bqjaSBiaeG6v3QgdG/DoG4gYuG7mSB0aMO0bmcgdGluIHbhu4EgWCBuw6puIG5nxrDhu51pIHRhIHRoxrDhu51uZyDGsOG7m2MgbMaw4bujbmcgdGhhbSBz4buRIGPEg24gY+G7qSB0aGVvIGvhur90IHF14bqjIGPhu6dhIG3huqt1Lg0KDQpMw70gdGh1eeG6v3QgxrDhu5tjIGzGsOG7o25nIHRoaeG6v3QgbOG6rXAgY8OhYyBxdWkgdOG6r2MsIHRpw6p1IGNodeG6qW4gdsOgIGPDoWNoIMSRw6FuaCBnacOhIGtoaSBkw7luZyB0aMO0bmcgdGluIHThu6sgbeG6q3UgxrDhu5tjIGzGsOG7o25nIGNobyBjw6FjIHRoYW0gc+G7kSBjaMawYSBiaeG6v3QgY+G7p2EgY8OhYyBwaMOibiBwaOG7kWkuDQoJDQogIC0JUGjGsMahbmcgcGjDoXAgdGjhu6kgbmjhuqV0IGzDoCBz4butIGThu6VuZyBt4buZdCB0aOG7kW5nIGvDqiBs4bqtcCB04burIG3huqt1IG5n4bqrdSBuaGnDqm4gxJHhu4MgxrDhu5tjIGzGsOG7o25nIHbDoCBs4bqleSBnacOhIHRy4buLIHF1YW4gc8OhdCBt4bqrdSBj4bunYSB0aOG7kW5nIGvDqiBuw6B5IGzDoG0gZ2nDoSB0cuG7iyB44bqlcCB44buJIGNobyB0aGFtIHPhu5EgXChcdGhldGFcKQ0KDQogIC0JUGjGsMahbmcgcGjDoXAgdGjhu6kgaGFpIGzDoCBz4butIGThu6VuZyBuaOG7r25nIGtob+G6o25nIG5n4bqrdSBuaGnDqm4gKDEgaGF5IG5oaeG7gXUga2hv4bqjbmcpIHRow6BuaCBs4bqtcCBi4bufaSBjw6FjIHRo4buRbmcga8OqIGzhuq1wIHThu6sgbeG6q3Ugbmfhuqt1IG5oacOqbiBzYW8gY2hvIHjDoWMgc3XhuqV0IGPDoWMga2hv4bqjbmcgbsOgeSBjaOG7qWEgdGhhbSBz4buRIFwoXHRoZXRhXCkgeMOhYyDEkeG7i25oIGLhurFuZyBt4buZdCBt4bupYyBjaG8gdHLGsOG7m2MgKMSR4bunIGzhu5tuKS4gQ8OhYyDGsOG7m2MgbMaw4bujbmcgbsOgeSBn4buNaSBsw6AgxrDhu5tjIGzGsOG7o25nIGLhurFuZyBraG/huqNuZyB0aW4gY+G6rXkgKGhheSBn4buNaSB04bqvdCBsw6AgxrDhu5tjIGzGsOG7o25nIGtob+G6o25nIHRpbiBj4bqteSkuIA0KDQojIyMgS2hv4bqjbmcgdGluIGPhuq15IGPhu6dhIHRydW5nIGLDrG5oDQoNCiMjIyMgS2hv4bqjbmcgdGluIGPhuq15IGPhu6dhIHRoYW0gc+G7kSBcKFxtdVwpIHRyb25nIHF1eSBsdeG6rXQgXChOKFxtdSwgXHNpZ21hXjIpXCkNCg0KxJDhu4MgxrDhu5tjIGzGsOG7o25nIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggXChcbXVcKSB0cm9uZyBxdXkgbHXhuq10IFwoTihcbXUsIFxzaWdtYV4yKVwpLCB0YSBz4bq9IGTDuW5nIHRydW5nIGLDrG5oIG3huqt1IFxiYXJ7WH0gxJHhu4MgxrDhu5tjIGzGsOG7o25nDQoNClbDrCBxdXkgbHXhuq10IGNodeG6qW4gcGjhu6UgdGh14buZYyB2w6BvIGhhaSB0aGFtIHPhu5EgXChcbXVcKSB2w6AgXChcc2lnbWFeMlwpIG7Dqm4gxJHhu4MgeMOieSBk4buxbmcgY8OhYyBraG/huqNuZyB0aW4gY+G6rXkgY+G7p2EgXChcbXVcKSB0YSB4w6l0IGhhaSB0csaw4budbmcgaOG7o3A6DQoNCi0gYS4gS2hpIMSRw6MgYmnhur90IFwoXHNpZ21hXjJcKToNCgkNCglcW2goXGJhcntYfSwgXG11KSA9IFxmcmFjeyhcYmFye1h9IC0gXG11KSBcc3FydHtufX0ge1xzaWdtYX1cXQ0KDQpow6BtIG7DoHkgdHXDom4gdGhlbyBxdXkgbHXhuq10IE4oMCwxKQ0KDQpH4buNaSBcKGhfe1xhbHBoYTF9XCkgbMOgIMSRaeG7g20gdOG7m2kgaOG6oW4gZMaw4bubaSBcKFVfe1xhbHBoYX1cKSwgIFwoaF97XGFscGhhMn1cKSBsw6AgxJFp4buDbSB04bubaSBo4bqhbiB0csOqbiBcKFVfezEtXGFscGhhfVwpLiBLaGkgxJHDsyB0YSBjw7M6DQoNClxbUChVX3tcYWxwaGF9IDwgXGZyYWN7KFxiYXJ7WH0gLSBcbXUpIFxzcXJ0e259fSB7XHNpZ21hfSA8IFVfezEtXGFscGhhfSkgPSAxIC0gXGFscGhhXF0NCg0KXFtQKFxiYXJ7WH0gIC0gVV97MS1cYWxwaGF9XGZyYWN7XHNpZ21hfSB7XHNxcnR7bn19IDwgXG11IDwgXGJhcntYfSAgLSBVX3tcYWxwaGF9XGZyYWN7XHNpZ21hfSB7XHNxcnR7bn19KSA9IDEgLSBcYWxwaGFcXQ0KDQpW4bubaSDEkeG7mSB0aW4gY+G6rXkgMSAtIFwoXGFscGhhXCkgdGjDrCBraG/huqNuZyB0aW4gY+G6rXkgY+G7p2EgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBu4bqxbSB0cm9uZyBraG/huqNuZw0KDQpcW1xiYXJ7WH0gIC0gVV97MS1cYWxwaGF9XGZyYWN7XHNpZ21hfSB7XHNxcnR7bn19IDwgXG11IDwgXGJhcntYfSAgLSBVX3tcYWxwaGF9XGZyYWN7XHNpZ21hfSB7XHNxcnR7bn19XF0NCgkNCi0gYi4gS2hpIGNoxrBhIGJp4bq/dCBcKFxzaWdtYV4yXCk6DQoJDQpcWyBoKFxiYXJ7WH0sIFxtdSkgPSBcZnJhY3soXGJhcntYfSAtIFxtdSkgXHNxcnR7bn19IHtzfVxdDQoNCmjDoG0gbsOgeSB0dcOibiB0aGVvIHF1eSBsdeG6rXQgVC1zdHVkZW50IHbhu5tpIChuLTEpIGLhuq1jIHThu7EgZG8NCg0KIyMjIyBLaG/huqNuZyB0aW4gY+G6rXkgY+G7p2EgdGhhbSBz4buRIHAgY+G7p2EgcXV5IGx14bqtdCBhKHApDQoNCi0gSMOgbSBt4bqtdCDEkeG7mSBjw7MgZOG6oW5nOiBcWyBQcihrKSA9IFxmcmFje24hfXtrIShuLWspIX1wXmsoMS1wKV57Ti1rfSAgPSBcYmlub217Tn17a30gcF5rcV57Ti1rfVxdDQoNCi0gVOG6p24gc3XhuqV0IG3huqt1IGYgbMOgIGjDoG0gxrDhu5tjIGzGsOG7o25nIHAgKHhlbSB0aMOqbSBzw6FjaCB0aOG7kW5nIGvDqiB24buBIGvhur90IHF14bqjIGNo4bupbmcgbWluaCkuDQoNCi0gUGjGsMahbmcgc2FpOiBcKFxmcmFje3AoMS1wKX17bn0gXCkNCg0KQ8OhY2ggxrDhu5tjIGzGsOG7o25nIHTGsMahbmcgdOG7sSBuaMawIHRyw6puDQoNCiMjIyBLaG/huqNuZyB0aW4gY+G6rXkgY+G7p2EgcGjGsMahbmcgc2FpDQoNCg0KDQojIyBLaeG7g20gxJHhu4tuaCB7LnRhYnNldH0NCg0KLSBHaeG6oyB0aGnhur90IGtp4buDbSDEkeG7i25oIHRoxrDhu51uZyBn4buNaSBsw6AgSDANCg0KVsOtIGThu6U6IEgwOiBCaeG6v24gbmfhuqt1IG5oacOqbiB4IGPDsyBwaMOibiBwaOG7kWkgY2h14bqpbg0KDQotIEdpw6EgdHLhu4sgdGjhu5FuZyBrw6o6IFTDuXkgdGh14buZYyB2w6BvIGxv4bqhaSBraeG7g20gxJHhu4tuaCBnacOhIHRy4buLIG7DoHkgxJHGsOG7o2MgdMOtbmggdGhlbyBjw6FjIGPDoWNoIGtow6FjIG5oYXUuIEdpw6EgdHLhu4sgbsOgeSDEkcOjIMSRxrDhu6NjIGNo4bupbmcgbWluaCB0dcOibiB0aGVvIDEgcXV5IGx14bqtdCBwaMOibiBwaOG7kWkgbsOgbyDEkcOzDQoNClbDrSBk4bulOiBnacOhIHRy4buLIHRo4buRbmcga8OqIFwoIEpCID0gbihcZnJhY3tTa2V3XnsyfX0gezZ9ICsgXGZyYWN7S3VydF57Mn19IHsyNH0pIFwpIMSRxrDhu6NjIGNo4bupbmcgbWluaCB0dcOibiB0aGVvIHF1eSBsdeG6rXQgcGjDom4gcGjhu5FpIEtoaSBiw6xuaCBwaMawxqFuZyAyIGLhuq1jIHThu7EgZG8NCg0KLSBYw6FjIHN14bqldDogS2hpIMSRw6MgYmnhur90IMSRxrDhu6NjIGdpw6EgdHLhu4sgdGjhu5FuZyBrw6ogdsOgIGxv4bqhaSBwaMOibiBwaOG7kWksIHRhIHPhur0gdMOtbmggxJHGsOG7o2MgeMOhYyBzdeG6pXQgeOG6o3kgcmEgc+G7sSBraeG7h24gSDANClRow7RuZyB0aMaw4budbmcgbmfGsOG7nWkgdGEgdGjGsOG7nW5nIGzhuqV5IG5nxrDhu6FuZyBsw6AgMC4wMSwgMC4wNSwgMC4xIMSR4buDIGNo4bqlcCBuaOG6rW4gaG/hurdjIGLDoWMgYuG7jyBIMC4NClRyb25nIGPDoWMgcGjhuqduIG3hu4FtIHRow7RuZyB0aMaw4budbmcgY8OhYyBnacOhIHRy4buLIG7DoHkgxJHDoyDEkcaw4bujYyB0w61uaCB0b8Ohbi4gTmfGsOG7nWkgc+G7rSBk4bulbmcgY2jhu4kgY+G6p24gbmjDrG4gdsOgbyBt4bupYyB4w6FjIHN14bqldCDEkeG7gyDEkcawYSByYSBr4bq/dCBsdeG6rW4uDQoNClbDrSBk4bulOiBYw6FjIHN14bqldCB44bqjeSByYSBz4buxIGtp4buHbiBIMCDEkcOjIMSRxrDhu6NjIHTDrW5oIHRvw6FuID0gMC4wNC4gVGEgY8OzIHRo4buDIGvhur90IGx14bqtbiBiw6FjIGLhu48gSDAgKHThu6ljIGzDoCBiaeG6v24gbmfhuqt1IG5oacOqbiB4IGtow7RuZyBwaMOibiBwaOG7kWkgY2h14bqpbikgduG7m2kgbeG7qWMgw70gbmdoxKlhIDUlIGhv4bq3YyBjaOG6pXAgbmjhuq1uIEgwIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA8IDQlDQoNCiMjIyBLaeG7g20gxJHhu4tuaCBwaMOibiBwaOG7kWkgY2h14bqpbg0KDQojIyMjIFRpw6p1IGNodeG6qW4gSmFjcXVlLSBCZXJhDQpgYGB7cn0NCnggPC0gcm5vcm0oMTAwKQ0KdHNlcmllczo6amFycXVlLmJlcmEudGVzdCh4KQ0KYGBgDQoNCiMjIyMgVGnDqnUgY2h14bqpbiBLb2xtb2dvcm92LVNtaXJub3YNCg0KYGBge3J9DQprcy50ZXN0KHgsICJwbm9ybSIsIG1lYW4gPSAwLCBzZCA9IDEpDQpgYGANCg0KIyMjIyBUacOqdSBjaHXhuqluIFNoYXBpcm8tV2lsa3MNCg0KYGBge3J9DQpzaGFwaXJvLnRlc3QoeCkNCmBgYA0KDQojIyMjIFRpw6p1IGNodeG6qW4gQW5kZXJzb24gLSBEYXJsaW5nDQoNCmBgYHtyfQ0Kbm9ydGVzdDo6YWQudGVzdCh4KQ0KYGBgDQoNCiMjIyBLaeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCB24buBIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmgNCg0KIyMjIyBLaeG7g20gxJHhu4tuaCBnaeG6oyB0aHV54bq/dCB24buBIHRoYW0gc+G7kSBj4bunYSBxdXkgbHXhuq10IFwoTihcbXVfezB9LCBcc2lnbWFfezB9XjIpXCkNCg0KKiBLaGkgxJHDoyBiaeG6v3QgXChcc2lnbWFfezB9XCkNCg0KSDA6IFwoXG11PVxtdV97MH1cKQ0KDQpIMTogXChcbXU8PlxtdV97MH1cKQ0KDQogIC0gTOG6rXAgdGjhu5FuZyBrw6ogXChVID0gXGZyYWN7KFxiYXJ7WH0gLSBcbXVfezB9KSBcc3FydHtufX0ge1xzaWdtYX1cKSwgdGjhu5FuZyBrw6ogbsOgeSB0dcOibiB0aGVvIHF1eSBsdeG6rXQgcGjDom4gcGjhu5FpIE4oMCwgMSkNCg0KKiBLaGkgY2jGsGEgYmnhur90ICBcKFxzaWdtYV97MH1cKQ0KDQogIC0gTOG6rXAgdGjhu5FuZyBrw6ogXChUID0gXGZyYWN7KFxiYXJ7WH0gLSBcbXVfezB9KSBcc3FydHtufX0ge3N9XCksIHRo4buRbmcga8OqIG7DoHkgdHXDom4gdGhlbyBxdXkgbHXhuq10IHBow6JuIHBo4buRaSBULXN0dWRlbnQgKG4tMSkgYuG6rWMgdOG7sSBkbw0KICANCg0KYGBge3J9DQp4IDwtIHJwb2lzKDEwMCwgMTIpICMgdOG6oW8gYmnhur9uIG5n4bqrdSBuaGnDqnUgcGjDom4gcGjhu5FpIHBvaXNzb24NCg0KaGVhZCh4KQ0KDQpgYGANCi0gVHJ1bmcgYsOsbmggdsOgIMSR4buZIGzhu4djaCBjaHXhuqluIGzhuqduIGzGsOG7o3QNCmBgYHtyfQ0KbWVhbih4KQ0KDQpzZCh4KQ0KDQpgYGANCg0KLSBLaeG7g20gxJHhu4tuaDoNCg0KSDA6IG11ID0gMTANCmBgYHtyfQ0KDQp0LnRlc3QoeCwgbXUgPSAxMCkgIyBIMDogR2nhuqMgc+G7rSBiaeG6v24gbsOgeSBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCA9IDEwDQoNCnQudGVzdCh4LCBtdSA9IDExKSAjIEgwOiBHaeG6oyBz4butIGJp4bq/biBuw6B5IGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oID0gMTENCmBgYA0KDQoqIFNvIHPDoW5oIHRydW5nIGLDrG5oIGPhu6dhIDIgbeG6q3UNCiAgLSAyIG3huqt1IGPDsyBwaMawxqFuZyBzYWkgYuG6sW5nIG5oYXUgDQoNCmBgYHtyfQ0KeSA8LSBybm9ybSgxMDAsIDEyLCBzZCh4KSkNCg0KdC50ZXN0KHgsIHksIHZhci5lcXVhbCA9IFRSVUUpDQoNCmBgYA0KICAtIDIgbeG6q3UgY8OzIHBoxrDGoW5nIHNhaSBraMOhYyBuaGF1IA0KDQpgYGB7cn0NCnogPC0gcm5vcm0oMTAwLCAxMiwgNikNCnQudGVzdCh4LCB6LCB2YXIuZXF1YWwgPSBGQUxTRSkNCmBgYA0KDQojIyMgS2nhu4NtIMSR4buLbmggZ2nhuqMgdGh1eeG6v3QgduG7gSBnacOhIHRy4buLIHBoxrDGoW5nIHNhaQ0KSDA6IFwoXHNpZ21hX3t4fSA9IFxzaWdtYV97eX1cKQ0KDQoNCmBgYHtyfQ0KdmFyLnRlc3QoeCwgeSkNCg0KdmFyLnRlc3QoeCwgeikNCmBgYA0KDQoNCg0K