1 Giới thiệu về thành phần tuyến tính

Đây là chặng thứ 5 trên hành trình khám phá packae gamlss. Để nhắc lại, mô hình gamlss có 2 đặc tính quan trọng : thứ nhất là chuyên biệt cho tham số của họ phân phối xác định, thứ hai là có cấu trúc nhiều thành phần, bao gồm 3 phần chính là : tham số, bù trừ và ngẫu nhiên. Phần tham số lại chia ra thành 2 loại bao gồm tuyến tính và phi tuyến tính.

Bài hôm nay Nhi sẽ giới thiệu sơ lược về thành phần tham số tuyến tính (các yếu tố tuyến tính này có thể gia giảm nên còn được gọi là phần cộng thêm : linear parametric additive term). Phần phi tuyến sẽ được giới thiệu trong 1 bài khác.

Bạn sẽ thấy trong hình sau đây 3 món ăn mà Nhi thích: Maki sushi, Kem hoa hồng của tiệm Armorino và Phở Việt Nam. Có thể các bạn không tin, nhưng chúng ta có thể tìm thấy những ý tưởng về thống kê và mô hình hồi quy từ những món ăn và trong lúc nấu ăn. Thí dụ có lần trong khi làm món sushi, Nhi liên tưởng tới data transformation và piecewise regression (có một số giáo trình thống kê có tựa đề là Cookbook).

Cả 3 món ăn trong hình đều có một đặc điểm chung, đó là công thức chế biến (công thức mô hình) đòi hỏi bạn kết hợp các thành phần khác nhau (các biến số trong dữ liệu đầu vào) bằng phép cộng (như món sushi) hoặc kết hợp giữa nguyên liệu và gia vị (tương tác) để tạo ra kết quả cuối cùng (response).

Đôi khi cùng 1 dữ liệu đầu vào nhưng có khả năng tạo ra rất nhiều mô hình khác nhau bằng cách gia giảm, thêm bớt các biến số bên trong mô hình. Tại cửa hàng Armorino, bạn đứng trước một tủ kính với hàng chục loại kem, và có thể chọn 2,3, thậm chí 5 mùi khác nhau. Chị bán kem sẽ dán từng lớp kem với nhau trên cornet để sau đó bạn có thể vui vẻ dạo phố với cành hoa hồng trên tay và chụp selfie với nó. Bằng cách thức tương tự, mọi mô hình hồi quy đã được tạo ra trong R, dù bạn sử dụng package gamlss hay glm.

Công thức thành phần tuyến tính và toán tử

Các thành phần tuyến tính được đưa vào mô hình thông qua công thức (formula) và liên kết với nhau bằng 2 toán tử : cộng thêm (+) và tương tác (*).

Hai toán tử này có nguồn gốc lâu đời (đề xuất bởi Wilkinson và Rogers năm 1973 và đưa vào ngôn ngữ lập trình thống kê S (là tiền thân của R) bởi Chambers và Hastie năm 1992). Do được quy ước sẵn trong R nên hầu hết (không phải tất cả) các package hồi quy sử dụng formula đều dùng + và * với ý nghĩa như nhau.

Các bạn từng làm ANOVA hay hồi quy với hàm glm() hoặc lm() đều quen thuộc với công thức và 2 toán tử +, *, nhưng ở đây Nhi sẽ nhắc lại về cú pháp của công thức hồi quy cho các bạn mới làm quen với R :

Toán tử +

Toán tử + có công dụng kết hợp 2 tham số hồi quy (predictors) với nhau bằng phép cộng : Thí dụ : Y ~ X1 + X2 + … Xn

Nếu X là 1 biến liên tục, toán tử + sẽ gán vector X vào matrix của mô hình hồi quy (cộng thêm 1 cột duy nhất). Với 2 predictors X1+X2, một mặt phẳng hồi quy sẽ được tạo ra.

Nếu ta đưa vào 1 yếu tố (factor) F với nhiều level, F sẽ bị cắt ra thành nhiều biến giả (dummy variable) được mã hóa bằng giá trị 0 và 1, mỗi cột dummy variable tương ứng với 1 level.

Khi mô hình có chứa intercept, và ta muốn khảo sát một yếu tố F có k levels thì chỉ có (k-1) level được mã hóa theo dạng dummy variable, level đầu tiên của F sẽ bị giản lược và không được trình bày trong mô hình sau cùng.

Ta có thể tổ chức lại nội dung của F bằng hàm contrasts( ).

library(tidyverse)

F1=gl(2,1,25)
levels(F1)=c("Group1", "Group2")

F2=gl(3,2,25)
levels(F2)=c("CondA", "CondB","CondC")

X1=rnorm(25,10,2)

X2=rnorm(25,5,1.5)
head(model.matrix(~X1),10)%>%knitr::kable()
(Intercept) X1
1 9.594486
1 8.797346
1 7.458943
1 12.099089
1 7.917185
1 9.890659
1 7.157442
1 9.588284
1 10.800068
1 9.328071
head(model.matrix(~X1+X2),10)%>%knitr::kable()
(Intercept) X1 X2
1 9.594486 4.366550
1 8.797346 4.403565
1 7.458943 6.300203
1 12.099089 6.416712
1 7.917185 6.041099
1 9.890659 4.058703
1 7.157442 7.891579
1 9.588284 5.119930
1 10.800068 7.052355
1 9.328071 2.636837
head(model.matrix(~F2),10)%>%knitr::kable()
(Intercept) F2CondB F2CondC
1 0 0
1 0 0
1 1 0
1 1 0
1 0 1
1 0 1
1 0 0
1 0 0
1 1 0
1 1 0
head(model.matrix(~F2-1),10)%>%knitr::kable()
F2CondA F2CondB F2CondC
1 0 0
1 0 0
0 1 0
0 1 0
0 0 1
0 0 1
1 0 0
1 0 0
0 1 0
0 1 0

Toán tử tương tác

Toán tử * có công dụng biểu diễn một sự tương tác giữa 2 hay nhiều predictors, chúng có thể là biến liên tục hay yếu tố , thí dụ :

Y ~ X1*X2

Y ~ X*F

Y ~ F1*F2

Lưu ý rằng khi viết X1*X2, thực ra ta muốn xét cả 3 hiệu ứng : 2 hiệu ứng riêng phần của X1 và X2, và hiệu ứng tương tác giữa chúng, do đó :

Y ~ X1*X2 tương đương : Y ~ X1 +X2 + X1:X2

Tương tác giữa 2 factors F1 (k1 level) và F2 (k2 level) sẽ tạo ra trong matrix (k1-1)*(k2-1)

và (k1-1) + (k2-1) hay (k1*k2)-1 cột dummy variable cho hiệu ứng chính và hiệu ứng tương tác.

Thí dụ F1 có 2 level (a,b), F2 có 3 level là (1,2,3) thì sẽ có 5 dummy variable gồm F1b, F22, F23, F1B :F22, F1B :F23

head(model.matrix(~X1*F2),10)%>%knitr::kable()
(Intercept) X1 F2CondB F2CondC X1:F2CondB X1:F2CondC
1 9.594486 0 0 0.000000 0.000000
1 8.797346 0 0 0.000000 0.000000
1 7.458943 1 0 7.458943 0.000000
1 12.099089 1 0 12.099089 0.000000
1 7.917185 0 1 0.000000 7.917185
1 9.890659 0 1 0.000000 9.890659
1 7.157442 0 0 0.000000 0.000000
1 9.588284 0 0 0.000000 0.000000
1 10.800068 1 0 10.800068 0.000000
1 9.328071 1 0 9.328071 0.000000
head(model.matrix(~F1+F2),10)%>%knitr::kable()
(Intercept) F1Group2 F2CondB F2CondC
1 0 0 0
1 1 0 0
1 0 1 0
1 1 1 0
1 0 0 1
1 1 0 1
1 0 0 0
1 1 0 0
1 0 1 0
1 1 1 0
head(model.matrix(~F1*F2),10)%>%knitr::kable()
(Intercept) F1Group2 F2CondB F2CondC F1Group2:F2CondB F1Group2:F2CondC
1 0 0 0 0 0
1 1 0 0 0 0
1 0 1 0 0 0
1 1 1 0 1 0
1 0 0 1 0 0
1 1 0 1 0 1
1 0 0 0 0 0
1 1 0 0 0 0
1 0 1 0 0 0
1 1 1 0 1 0
head(model.matrix(~X1*X2*F1*F2),10)%>%knitr::kable()
(Intercept) X1 X2 F1Group2 F2CondB F2CondC X1:X2 X1:F1Group2 X2:F1Group2 X1:F2CondB X1:F2CondC X2:F2CondB X2:F2CondC F1Group2:F2CondB F1Group2:F2CondC X1:X2:F1Group2 X1:X2:F2CondB X1:X2:F2CondC X1:F1Group2:F2CondB X1:F1Group2:F2CondC X2:F1Group2:F2CondB X2:F1Group2:F2CondC X1:X2:F1Group2:F2CondB X1:X2:F1Group2:F2CondC
1 9.594486 4.366550 0 0 0 41.89480 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0 0 0.00000 0.00000 0.00000 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 8.797346 4.403565 1 0 0 38.73968 8.797346 4.403565 0.000000 0.000000 0.000000 0.000000 0 0 38.73968 0.00000 0.00000 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 7.458943 6.300203 0 1 0 46.99286 0.000000 0.000000 7.458943 0.000000 6.300203 0.000000 0 0 0.00000 46.99286 0.00000 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 12.099089 6.416712 1 1 0 77.63637 12.099089 6.416712 12.099089 0.000000 6.416712 0.000000 1 0 77.63637 77.63637 0.00000 12.099089 0.000000 6.416712 0.000000 77.63637 0.00000
1 7.917185 6.041099 0 0 1 47.82849 0.000000 0.000000 0.000000 7.917185 0.000000 6.041099 0 0 0.00000 0.00000 47.82849 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 9.890659 4.058703 1 0 1 40.14325 9.890659 4.058703 0.000000 9.890659 0.000000 4.058703 0 1 40.14325 0.00000 40.14325 0.000000 9.890659 0.000000 4.058703 0.00000 40.14325
1 7.157442 7.891579 0 0 0 56.48353 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0 0 0.00000 0.00000 0.00000 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 9.588284 5.119930 1 0 0 49.09134 9.588284 5.119930 0.000000 0.000000 0.000000 0.000000 0 0 49.09134 0.00000 0.00000 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 10.800068 7.052355 0 1 0 76.16591 0.000000 0.000000 10.800068 0.000000 7.052355 0.000000 0 0 0.00000 76.16591 0.00000 0.000000 0.000000 0.000000 0.000000 0.00000 0.00000
1 9.328071 2.636837 1 1 0 24.59660 9.328071 2.636837 9.328071 0.000000 2.636837 0.000000 1 0 24.59660 24.59660 0.00000 9.328071 0.000000 2.636837 0.000000 24.59660 0.00000

Khi ta muốn xét tương tác giữa 2 biến liên tục X và 1 yếu tố F (k level), trong matrix sẽ gồm : 1 cột cho vector X, (k-1) cột cho các dummy hiệu ứng chính của (k-1) level trong F và (k-1) cột cho hiệu ứng tương tác giữa X và các dummy variable của (k-1) level trong F.

Liên hệ giữa mô hình tuyến tính và phân tích định lượng

Như chúng ta đã biết, có liên hệ chặt chẽ giữa mô hình tuyến tính và các phương pháp thống kê cổ điển, và những thiết kế nghiên cứu có thể được biểu diễn thông qua mô hình, thí dụ :

Y ~ 1 là một mô hình chỉ chứa intercept, nó tương đương với việc khảo sát giá trị trung bình của Y, hoặc với hàm ý chuẩn bị 1 mô hình cơ bản (baseline model) dùng vào việc đánh giá phẩm chất của những mô hình khác ; thí dụ trong hồi quy logistic, một model chỉ bắt đầu đáng tin nếu nó có thể đánh bại quy luật binnomial ngẫu nhiên.

Y ~ X với X là 1 biến liên tục : tương đương với hồi quy đơn biến hay khảo sát tương quan tuyến tính giữa Y và X

Y ~ F với F là 1 factor từ 2 level trở lên : tương đương với One way ANOVA (phân tích phương sai 1 yếu tố).

Y ~ X1 + X2 : tương đương với khảo sát quan hệ riêng phần giữa Y,X1 và X2

Y ~ X*F : tương đương với ANCOVA

Y ~ F1*F2…Fn : tương đương với n ways ANOVA

Thí dụ minh họa

Nhi lấy thí dụ dataset cigarette, đây là 1 bài toán hồi quy với câu hỏi là liệu việc đánh thuế lên thuốc lá có làm giảm doanh số của sản phẩm này hay không ? Tác giả đã ghi nhận giá thuốc lá trong vòng 30 năm từ 1963 tại 51 bang của Hoa kỳ, đồng thời ghi nhận các biến như dân số, dân số >16 tuổi, thu nhập bình quân đầu người, giá thuốc lá. Biến kết quả là mức tiêu thụ thuốc lá.

Trong khi thăm dò quan hệ giữa biến kết quả (mức tiêu thụ thuốc lá tính bằng gói trên đầu người) và những biến số khác trong dữ liệu, trên một không gian 2 chiều, chúng ta thực ra có thể cảm nhận được về những mô hình hồi quy đơn biến, ANOVA, mô hình có hiệu ứng tương tác…

cigarette=read.csv("https://raw.github.com/vincentarelbundock/Rdatasets/master/csv/plm/Cigar.csv")

cigarette$state=factor(cigarette$state)
cigarette$year=factor(cigarette$year-62)

library(viridis)

cigarette%>%ggplot()+
  geom_boxplot(aes(x=as.integer(year),y=sales,fill=year,color=year),show.legend = F,alpha=0.2)+
  theme_bw(10)+
  scale_fill_viridis(discrete=T,option="C",direction = -1)+
  scale_color_viridis(discrete=T,option="C",direction = -1)+
  geom_smooth(aes(x=as.integer(year),y=sales),show.legend = F,color="darkviolet",fill="gold")+
  scale_x_continuous("30 years period")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  ggtitle("Model: Sale~ Year (as dummy variables)")

cigarette%>%ggplot()+
  geom_path(aes(x=as.integer(year),y=sales,color=reorder(state,sales)),show.legend = F)+
  theme_bw(10)+
  scale_colour_viridis(discrete=T,option="C",direction = -1)+
  scale_x_continuous("30 years period")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  ggtitle("Model: Sale~ Year*State (both as factors)")

cigarette%>%ggplot()+
  geom_jitter(aes(x=as.integer(year),y=sales,color=sales),size=1,alpha=0.5)+
  geom_smooth(aes(x=as.integer(year),y=sales),show.legend = F,color="purple",fill="gold")+
  theme_bw(10)+
  scale_x_continuous("30 years period")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=F,option="B",direction = -1)+
  ggtitle("Model: Sale~ Year (as discrete number)")

cigarette%>%ggplot()+
  geom_jitter(aes(x=price,y=sales,color=sales),size=1,alpha=0.5)+
  geom_smooth(aes(x=price,y=sales),show.legend = F,color="purple",fill="gold")+
  theme_bw(10)+
  scale_x_continuous("Price per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=F,option="B",direction = -1)+
  ggtitle("Model: Sale~ Price per pack")

cigarette%>%ggplot()+
  geom_point(aes(x=pimin,y=sales,color=sales),size=1,alpha=0.2)+
  geom_smooth(aes(x=pimin,y=sales),color="purple",fill="gold")+
  theme_bw(10)+
  scale_x_continuous("minimum price in adjoining states per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=F,option="B",direction = -1)+
  ggtitle("Model: Sale~ minimum price")

cigarette%>%ggplot()+
  geom_jitter(aes(x=price,y=sales),size=1,alpha=0.2,show.legend = F,color="grey")+
  geom_smooth(aes(x=price,y=sales,color=year),show.legend = F,se=F,method="lm")+
  theme_bw(10)+
  scale_x_continuous("Price per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=T,option="C",direction = -1)+
  ggtitle("Model: Sale~ Price:Year")

cigarette%>%ggplot()+
  geom_jitter(aes(x=price,y=sales),size=1,alpha=0.2,show.legend = F,color="grey")+
  geom_smooth(aes(x=price,y=sales,color=state),show.legend = F,se=F)+
  theme_bw(10)+
  scale_x_continuous("Price per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=T,option="C",direction = -1)+
  ggtitle("Model: Sale~ Price*State")

cigarette%>%ggplot()+
  geom_jitter(aes(x=log(pop16),y=sales,color=sales),size=1,alpha=0.5)+
  geom_smooth(aes(x=log(pop16),y=sales),show.legend = F,color="purple",fill="gold")+
  theme_bw(10)+
  scale_x_continuous("Population above 16 yrs old in Log scale")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=F,option="B",direction = -1)+
  ggtitle("Model: Sale~ log(Population>16 yrs)")

cigarette%>%ggplot()+
  geom_jitter(aes(x=ndi,y=sales,color=sales),size=1,alpha=0.5)+
  geom_smooth(aes(x=ndi,y=sales),show.legend = F,color="purple",fill="gold")+
  theme_bw(10)+
  scale_x_continuous("Per capita disposable income")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=F,option="B",direction = -1)+
  ggtitle("Model: Sale~ Per capita disposable income")

cigarette%>%ggplot()+
  geom_jitter(aes(x=price,y=sales,color= factor(round(log(cigarette$ndi),0))),size=1,alpha=0.2,show.legend = F)+
  geom_smooth(aes(x=price,y=sales,color= factor(round(log(cigarette$ndi),0))),show.legend = F,se=F,method="lm")+
  theme_bw(10)+
  scale_x_continuous("Price per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=T,option="C",direction = -1)+
  ggtitle("Model: Sale~ Price * Per capita disposable income")

cigarette%>%ggplot()+
  geom_boxplot(aes(x=reorder(state,sales),y=sales,fill=reorder(state,sales),color=reorder(state,sales)),show.legend = F,alpha=0.5)+
  theme_bw(10)+
  scale_fill_viridis(discrete=T,option="B",direction = -1)+
  scale_color_viridis(discrete=T,option="B",direction = -1)+
  scale_x_discrete("51 States")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  ggtitle("One_way ANOVA: Sale~ State (as dummy variables)")

cigarette%>%ggplot()+
  geom_jitter(aes(x=price,y=sales,color=year),size=1,alpha=0.2,show.legend = F)+
  geom_smooth(aes(x=price,y=sales,color=year),show.legend = F,se=F)+
  theme_bw(10)+
  scale_x_continuous("Price per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=T,option="C",direction = -1)+
  facet_wrap(~year,scales="free")+
  ggtitle("Model: Sale~ Price + random(1|Year)")+
  theme_bw(3)

cigarette%>%ggplot()+
  geom_jitter(aes(x=price,y=sales,color=state),size=1,alpha=0.2,show.legend = F)+
  geom_smooth(aes(x=price,y=sales,color=state),show.legend = F,se=F)+
  theme_bw(10)+
  scale_x_continuous("Price per pack")+
  scale_y_continuous("Cigarette sales (packs per capita)")+
  scale_color_viridis(discrete=T,option="C",direction = -1)+
  facet_wrap(~state,scales="free")+
  ggtitle("Model: Sale~ Price + Year + random(1|State)")+
  theme_bw(3)

p2=cigarette%>%ggplot(aes(x=sales))+
  geom_histogram(aes(y=..density..,fill=..density..,color=..density..),binwidth = 1, alpha=0.7,show.legend = F)+
  geom_density(alpha=.1,color="black",fill="gold",linetype=2)+
  theme_bw()+
  scale_fill_viridis(discrete=F,option="C",direction = -1)+
  scale_color_viridis(discrete=F,option="C",direction = -1)+
  ggtitle("True observations")

2 Thăm dò phân phối

Như trong bài 2, bước đầu tiên khi dựng mô hình trong gamlss là thăm dò về đặc tính phân phối của biến kết quả. Bằng hàm fitdist, Nhi nhanh chóng xác định được phân phối phù hợp nhất cho biến sales là họ phân phối Skewed T type 4. Họ phân phối này được mô tả bởi 4 tham số là Mu, Sigma, Nu và Tau (có thể hình dung là Mean, Sd, skewness và kurtosis). Sử dụng hàm rST4, Nhi mô phỏng một mẫu ngẫu nhiên với Mu, Sigma, Tau và Nu của mô hình chỉ chứa Intercept), kết quả mô phỏng khá phù hợp với quans át trên thực tế :

library(gamlss)

scan=fitDist(sales,data=cigarette,type="realAll",k=log(nrow(cigarette)),parallel="multicore",ncpus = 4)

scan$fits
##      ST4    BCPEo     BCTo      ST1      ST5      JSU      ST2      ST3 
## 12800.57 12801.47 12812.24 12813.80 12819.56 12829.01 12829.37 12840.16 
##     SEP4   SHASHo       TF       GT     SEP3     SEP1       PE     SEP2 
## 12848.93 12849.70 12851.47 12857.84 12881.36 12888.94 12901.18 12909.46 
##   exGAUS   IGAMMA       RG    BCCGo       GG      GIG    LOGNO       LO 
## 12915.38 13009.24 13011.65 13012.41 13016.37 13016.47 13037.61 13043.48 
##       IG       GA      SN2      SN1     WEI3       GU      EXP  PARETO2 
## 13051.96 13118.36 13175.23 13413.97 13634.60 14491.46 16070.11 16077.34
gamlss.family(ST4)
## 
## GAMLSS Family: ST4 skew t type 4 
## Link function for mu   : identity 
## Link function for sigma: log 
## Link function for nu   : log 
## Link function for tau  : log
set.seed(123456)
p1=rST4(1000, mu = 119, sigma =exp(2.833), nu=exp(1.892), tau=exp(0.6194))%>%
  as_tibble()%>%
  ggplot(aes(x=value))+
  geom_histogram(aes(y=..density..,fill=..density..,color=..density..),binwidth = 1, alpha=0.7,show.legend = F)+
  geom_density(alpha=.1,color="black",fill="gold",linetype=2)+
  theme_bw()+
  scale_fill_viridis(discrete=F,option="C",direction = -1)+
  scale_color_viridis(discrete=F,option="C",direction = -1)+
  ggtitle("Simulated ST4 (mu=119,s=exp(2.83),nu=exp(1.89),tau=exp(0.62))")

gridExtra::grid.arrange(p1,p2,ncol=1)

3 Mô hình gamlss với các thành phần tuyến tính

Nhi sẽ lần lượt dựng 5 mô hình, các bạn có thể xem xét formula và nội dung của mô hình xuất ra để có thể hình dung về hoạt động của toán tử + và *, đồng thời diễn dịch các thành phần tuyến tính, tương tác trong mô hình.

Mô hình chỉ chứa hằng số

nC<-detectCores()

m0=gamlss(data=cigarette,
          formula=sales~1,
          family=ST4,
          trace=F,
          parallel="multicore",
          ncpus = detectCores()
          )

summary(m0)
## ******************************************************************
## Family:  c("ST4", "skew t type 4") 
## 
## Call:  gamlss(formula = sales ~ 1, family = ST4, data = cigarette,  
##     trace = F, parallel = "multicore", ncpus = detectCores()) 
## 
## Fitting method: RS() 
## 
## ------------------------------------------------------------------
## Mu link function:  identity
## Mu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 119.0192     0.5679   209.6   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Sigma link function:  log
## Sigma Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.83347    0.03661    77.4   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Nu link function:  log 
## Nu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.8924     0.2484   7.619 4.72e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Tau link function:  log 
## Tau Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.61952    0.07959   7.784 1.37e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## No. of observations in the fit:  1380 
## Degrees of Freedom for the fit:  4
##       Residual Deg. of Freedom:  1376 
##                       at cycle:  10 
##  
## Global Deviance:     12771.65 
##             AIC:     12779.65 
##             SBC:     12800.57 
## ******************************************************************

Mô hình đơn biến

m1=gamlss(data=cigarette,
          formula=sales~price,
          family=ST4,
          trace=F,
          parallel="multicore",
          ncpus = detectCores()
)

summary(m1)
## ******************************************************************
## Family:  c("ST4", "skew t type 4") 
## 
## Call:  gamlss(formula = sales ~ price, family = ST4, data = cigarette,  
##     trace = F, parallel = "multicore", ncpus = detectCores()) 
## 
## Fitting method: RS() 
## 
## ------------------------------------------------------------------
## Mu link function:  identity
## Mu Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 130.61543    1.01783  128.33   <2e-16 ***
## price        -0.16791    0.01213  -13.85   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Sigma link function:  log
## Sigma Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.74743    0.03589   76.56   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Nu link function:  log 
## Nu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.7963     0.2181   8.238 4.04e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Tau link function:  log 
## Tau Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.57867    0.07716   7.499 1.15e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## No. of observations in the fit:  1380 
## Degrees of Freedom for the fit:  5
##       Residual Deg. of Freedom:  1375 
##                       at cycle:  9 
##  
## Global Deviance:     12595.12 
##             AIC:     12605.12 
##             SBC:     12631.27 
## ******************************************************************

Mô hình 2 biến tương tác

m2=gamlss(data=cigarette,
          formula=sales~price*ndi,
          family=ST4,
          trace=F,
          parallel="multicore",
          ncpus = detectCores()
)

summary(m2)
## ******************************************************************
## Family:  c("ST4", "skew t type 4") 
## 
## Call:  gamlss(formula = sales ~ price * ndi, family = ST4,  
##     data = cigarette, trace = F, parallel = "multicore",  
##     ncpus = detectCores()) 
## 
## Fitting method: RS() 
## 
## ------------------------------------------------------------------
## Mu link function:  identity
## Mu Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.172e+02  1.792e+00  65.424  < 2e-16 ***
## price       -3.751e-01  4.989e-02  -7.518 9.97e-14 ***
## ndi          5.528e-03  3.274e-04  16.884  < 2e-16 ***
## price:ndi   -2.051e-05  2.444e-06  -8.395  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Sigma link function:  log
## Sigma Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.61914    0.03565   73.47   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Nu link function:  log 
## Nu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.8638     0.2096   8.891   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Tau link function:  log 
## Tau Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.50719    0.07556   6.712 2.79e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## No. of observations in the fit:  1380 
## Degrees of Freedom for the fit:  7
##       Residual Deg. of Freedom:  1373 
##                       at cycle:  9 
##  
## Global Deviance:     12309.88 
##             AIC:     12323.88 
##             SBC:     12360.48 
## ******************************************************************

ANOVA với Year là fixed factor

m3=gamlss(data=cigarette,
          formula=sales~year,
          family=ST4,
          trace=F,
          parallel="multicore",
          ncpus = detectCores()
)

summary(m3)
## ******************************************************************
## Family:  c("ST4", "skew t type 4") 
## 
## Call:  gamlss(formula = sales ~ year, family = ST4, data = cigarette,  
##     trace = F, parallel = "multicore", ncpus = detectCores()) 
## 
## Fitting method: RS() 
## 
## ------------------------------------------------------------------
## Mu link function:  identity
## Mu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 119.6801     2.9393  40.717  < 2e-16 ***
## year2        -3.7095     4.1785  -0.888 0.374833    
## year3        -1.0348     4.1252  -0.251 0.801979    
## year4        -3.2866     4.2544  -0.773 0.439944    
## year5        -1.1830     4.1496  -0.285 0.775627    
## year6        -2.2424     4.0820  -0.549 0.582861    
## year7        -3.8627     3.9638  -0.975 0.329980    
## year8        -5.5466     3.8691  -1.434 0.151927    
## year9        -3.4533     3.8295  -0.902 0.367348    
## year10       -0.2822     3.9038  -0.072 0.942380    
## year11        0.4806     3.8979   0.123 0.901881    
## year12        4.1379     3.9596   1.045 0.296196    
## year13        5.1056     3.9123   1.305 0.192113    
## year14        7.7548     3.8941   1.991 0.046640 *  
## year15        8.9079     3.8886   2.291 0.022131 *  
## year16       10.1401     3.8375   2.642 0.008327 ** 
## year17        8.4816     3.8384   2.210 0.027295 *  
## year18       10.1201     3.8488   2.629 0.008651 ** 
## year19       10.1538     3.8050   2.669 0.007710 ** 
## year20        8.8099     3.8237   2.304 0.021375 *  
## year21        4.9056     3.7674   1.302 0.193091    
## year22        0.5878     3.7874   0.155 0.876692    
## year23       -0.8223     3.8064  -0.216 0.828998    
## year24       -3.1214     3.8586  -0.809 0.418676    
## year25       -6.9478     3.9006  -1.781 0.075105 .  
## year26      -10.3361     4.0035  -2.582 0.009934 ** 
## year27      -14.6591     3.9756  -3.687 0.000236 ***
## year28      -20.0512     3.9548  -5.070 4.53e-07 ***
## year29      -21.3457     4.0198  -5.310 1.28e-07 ***
## year30      -23.3993     4.0704  -5.749 1.11e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Sigma link function:  log
## Sigma Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.65762    0.03569   74.46   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Nu link function:  log 
## Nu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.8054     0.1968   9.173   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Tau link function:  log 
## Tau Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.48745    0.07488    6.51 1.06e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## No. of observations in the fit:  1380 
## Degrees of Freedom for the fit:  33
##       Residual Deg. of Freedom:  1347 
##                       at cycle:  9 
##  
## Global Deviance:     12453.97 
##             AIC:     12519.97 
##             SBC:     12692.55 
## ******************************************************************

Mô hình tương tác 3 biến

m4=gamlss(data=cigarette,
          formula=sales~price*ndi*pop16,
          family=ST4,
          trace=F,
          parallel="multicore",
          ncpus = detectCores()
)

summary(m4)
## Warning in summary.gamlss(m4): summary: vcov has failed, option qr is used instead
## ******************************************************************
## Family:  c("ST4", "skew t type 4") 
## 
## Call:  
## gamlss(formula = sales ~ price * ndi * pop16, family = ST4, data = cigarette,  
##     trace = F, parallel = "multicore", ncpus = detectCores()) 
## 
## Fitting method: RS() 
## 
## ------------------------------------------------------------------
## Mu link function:  identity
## Mu Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      1.129e+02  2.203e+00  51.257  < 2e-16 ***
## price           -5.889e-01  5.821e-02 -10.117  < 2e-16 ***
## ndi              7.827e-03  3.939e-04  19.868  < 2e-16 ***
## pop16            1.326e-03  5.991e-04   2.214  0.02702 *  
## price:ndi       -1.957e-05  3.207e-06  -6.102 1.36e-09 ***
## price:pop16      5.100e-05  1.845e-05   2.764  0.00578 ** 
## ndi:pop16       -5.575e-07  1.004e-07  -5.552 3.39e-08 ***
## price:ndi:pop16 -1.606e-10  7.742e-10  -0.207  0.83569    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Sigma link function:  log
## Sigma Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.58474    0.02693   95.97   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Nu link function:  log 
## Nu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.9334     0.1861   10.39   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Tau link function:  log 
## Tau Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   0.4833     0.0734   6.585 6.44e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## No. of observations in the fit:  1380 
## Degrees of Freedom for the fit:  11
##       Residual Deg. of Freedom:  1369 
##                       at cycle:  9 
##  
## Global Deviance:     12225.52 
##             AIC:     12247.52 
##             SBC:     12305.05 
## ******************************************************************

Mô hình có cả biến liên tục và yếu tố = ANCOVA

m5=gamlss(data=cigarette,
          formula=sales~price+year,
          family=ST4,
          trace=F,
          parallel="multicore",
          ncpus = detectCores()
)

summary(m5)
## ******************************************************************
## Family:  c("ST4", "skew t type 4") 
## 
## Call:  gamlss(formula = sales ~ price + year, family = ST4,  
##     data = cigarette, trace = F, parallel = "multicore",  
##     ncpus = detectCores()) 
## 
## Fitting method: RS() 
## 
## ------------------------------------------------------------------
## Mu link function:  identity
## Mu Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 143.73434    3.30681  43.466  < 2e-16 ***
## price        -0.88847    0.06856 -12.959  < 2e-16 ***
## year2        -3.04465    3.90047  -0.781 0.435183    
## year3         0.20743    3.81303   0.054 0.956624    
## year4        -0.97454    4.03306  -0.242 0.809098    
## year5         2.16177    3.95856   0.546 0.585087    
## year6         2.75561    3.85874   0.714 0.475275    
## year7         2.37619    3.80034   0.625 0.531908    
## year8         3.03405    3.74560   0.810 0.418065    
## year9         7.20534    3.67231   1.962 0.049960 *  
## year10       11.90394    3.66587   3.247 0.001194 ** 
## year11       13.34395    3.70133   3.605 0.000323 ***
## year12       18.14435    3.76781   4.816 1.63e-06 ***
## year13       21.79917    3.82046   5.706 1.42e-08 ***
## year14       27.05878    3.85073   7.027 3.34e-12 ***
## year15       29.40588    3.87276   7.593 5.82e-14 ***
## year16       35.41725    3.99930   8.856  < 2e-16 ***
## year17       35.78210    4.06322   8.806  < 2e-16 ***
## year18       40.03731    4.17714   9.585  < 2e-16 ***
## year19       43.25537    4.30948  10.037  < 2e-16 ***
## year20       47.58785    4.57468  10.402  < 2e-16 ***
## year21       54.18075    5.11089  10.601  < 2e-16 ***
## year22       59.10690    5.61826  10.520  < 2e-16 ***
## year23       62.65829    5.92569  10.574  < 2e-16 ***
## year24       67.16567    6.38709  10.516  < 2e-16 ***
## year25       69.60638    6.82172  10.204  < 2e-16 ***
## year26       73.33025    7.29444  10.053  < 2e-16 ***
## year27       78.53767    7.94158   9.889  < 2e-16 ***
## year28       85.35976    8.73088   9.777  < 2e-16 ***
## year29       91.03478    9.24477   9.847  < 2e-16 ***
## year30      109.03117   10.85850  10.041  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Sigma link function:  log
## Sigma Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.53185    0.03788   66.85   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Nu link function:  log 
## Nu Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.4000     0.1501    9.33   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## Tau link function:  log 
## Tau Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.43097    0.07401   5.823 7.21e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## ------------------------------------------------------------------
## No. of observations in the fit:  1380 
## Degrees of Freedom for the fit:  34
##       Residual Deg. of Freedom:  1346 
##                       at cycle:  9 
##  
## Global Deviance:     12272.55 
##             AIC:     12340.55 
##             SBC:     12518.36 
## ******************************************************************

4 Kết luận

Đây là 1 bài rất ngắn và nội dung của nó không có gì mới lạ đối với các bạn đã quen sử dụng R. Chúng ta sẽ dừng lại ở đây. Thực ra công dụng chính của Gamlss là cho mô hình tiên lượng chứ rất hiếm khi nó được sử dụng với mục đích diễn dịch, và output gamlss không tương thích với tất cả hàm phân tích ANOVA mà ta từng biết nên để làm được suy diễn thống kê, hoặc là ta phải tự viết hàm để tính F statistics và làm ANOVA, post-hoc test một cách thủ công, hoặc là ta phải suy diễn thống kê dựa vào marginal effect với bootstrap (cũng thủ công luôn). Thông điệp chính của bài đó là cú pháp cho phần tuyến tính trong gamlss hoàn toàn giống như của hàm glm() hoặc lm() và nhiều package hồi quy khác. Bài này chỉ là khởi động cho những thành phần phức tạp hơn mà Nhi sẽ đề cập trong lần tới, bao gồm đa thức bậc cao và smoothing splines.

Xin cảm ơn và hẹn gặp lại.

LS0tDQp0aXRsZTogIlPhu60gZOG7pW5nIHBhY2thZ2UgR2FtbHNzIg0Kc3VidGl0bGU6ICJCw6BpIDU6IFRow6BuaCBwaOG6p24gdHV54bq/biB0w61uaCAiDQphdXRob3I6ICJMw6ogTmfhu41jIEto4bqjIE5oaSINCmRhdGU6ICIwNCBUaMOhbmcgOCAyMDE3Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogImRlZmF1bHQiDQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQoNCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQpsaWJyYXJ5KGdhbWxzcykNCg0KbkM8LWRldGVjdENvcmVzKCkNCmBgYA0KDQohW10oZ2FtbHNzNS5wbmcpDQoNCiMgR2nhu5tpIHRoaeG7h3UgduG7gSB0aMOgbmggcGjhuqduIHR1eeG6v24gdMOtbmgNCg0KxJDDonkgbMOgIGNo4bq3bmcgdGjhu6kgNSB0csOqbiBow6BuaCB0csOsbmgga2jDoW0gcGjDoSBwYWNrYWUgZ2FtbHNzLiDEkOG7gyBuaOG6r2MgbOG6oWksIG3DtCBow6xuaCBnYW1sc3MgY8OzIDIgxJHhurdjIHTDrW5oIHF1YW4gdHLhu41uZyA6IHRo4bupIG5o4bqldCBsw6AgY2h1ecOqbiBiaeG7h3QgY2hvIHRoYW0gc+G7kSBj4bunYSBo4buNIHBow6JuIHBo4buRaSB4w6FjIMSR4buLbmgsIHRo4bupIGhhaSBsw6AgY8OzIGPhuqV1IHRyw7pjIG5oaeG7gXUgdGjDoG5oIHBo4bqnbiwgYmFvIGfhu5NtIDMgcGjhuqduIGNow61uaCBsw6AgOiB0aGFtIHPhu5EsIGLDuSB0cuG7qyB2w6Agbmfhuqt1IG5oacOqbi4gUGjhuqduIHRoYW0gc+G7kSBs4bqhaSBjaGlhIHJhIHRow6BuaCAyIGxv4bqhaSBiYW8gZ+G7k20gdHV54bq/biB0w61uaCB2w6AgcGhpIHR1eeG6v24gdMOtbmguIA0KDQpCw6BpIGjDtG0gbmF5IE5oaSBz4bq9IGdp4bubaSB0aGnhu4d1IHPGoSBsxrDhu6NjIHbhu4EgdGjDoG5oIHBo4bqnbiB0aGFtIHPhu5EgdHV54bq/biB0w61uaCAoY8OhYyB54bq/dSB04buRIHR1eeG6v24gdMOtbmggbsOgeSBjw7MgdGjhu4MgZ2lhIGdp4bqjbSBuw6puIGPDsm4gxJHGsOG7o2MgZ+G7jWkgbMOgIHBo4bqnbiBj4buZbmcgdGjDqm0gOiBsaW5lYXIgcGFyYW1ldHJpYyBhZGRpdGl2ZSB0ZXJtKS4gUGjhuqduIHBoaSB0dXnhur9uIHPhur0gxJHGsOG7o2MgZ2nhu5tpIHRoaeG7h3UgdHJvbmcgMSBiw6BpIGtow6FjLg0KDQpC4bqhbiBz4bq9IHRo4bqleSB0cm9uZyBow6xuaCBzYXUgxJHDonkgMyBtw7NuIMSDbiBtw6AgTmhpIHRow61jaDogTWFraSBzdXNoaSwgS2VtIGhvYSBo4buTbmcgY+G7p2EgdGnhu4dtIEFybW9yaW5vIHbDoCBQaOG7nyBWaeG7h3QgTmFtLiBDw7MgdGjhu4MgY8OhYyBi4bqhbiBraMO0bmcgdGluLCBuaMawbmcgY2jDum5nIHRhIGPDsyB0aOG7gyB0w6xtIHRo4bqleSBuaOG7r25nIMO9IHTGsOG7n25nIHbhu4EgdGjhu5FuZyBrw6ogdsOgIG3DtCBow6xuaCBo4buTaSBxdXkgdOG7qyBuaOG7r25nIG3Ds24gxINuIHbDoCB0cm9uZyBsw7pjIG7huqV1IMSDbi4gVGjDrSBk4bulIGPDsyBs4bqnbiB0cm9uZyBraGkgbMOgbSBtw7NuIHN1c2hpLCBOaGkgbGnDqm4gdMaw4bufbmcgdOG7m2kgZGF0YSB0cmFuc2Zvcm1hdGlvbiB2w6AgcGllY2V3aXNlIHJlZ3Jlc3Npb24gKGPDsyBt4buZdCBz4buRIGdpw6FvIHRyw6xuaCB0aOG7kW5nIGvDqiBjw7MgdOG7sWEgxJHhu4EgbMOgIENvb2tib29rKS4NCg0KIVtdKGFkZGl0aXZlLnBuZykNCg0KQ+G6oyAzIG3Ds24gxINuIHRyb25nIGjDrG5oIMSR4buBdSBjw7MgbeG7mXQgxJHhurdjIMSRaeG7g20gY2h1bmcsIMSRw7MgbMOgIGPDtG5nIHRo4bupYyBjaOG6vyBiaeG6v24gKGPDtG5nIHRo4bupYyBtw7QgaMOsbmgpIMSRw7JpIGjhu49pIGLhuqFuIGvhur90IGjhu6NwIGPDoWMgdGjDoG5oIHBo4bqnbiBraMOhYyBuaGF1IChjw6FjIGJp4bq/biBz4buRIHRyb25nIGThu68gbGnhu4d1IMSR4bqndSB2w6BvKSBi4bqxbmcgcGjDqXAgY+G7mW5nIChuaMawIG3Ds24gc3VzaGkpIGhv4bq3YyBr4bq/dCBo4bujcCBnaeG7r2Egbmd1ecOqbiBsaeG7h3UgdsOgIGdpYSB24buLICh0xrDGoW5nIHTDoWMpIMSR4buDIHThuqFvIHJhIGvhur90IHF14bqjIGN14buRaSBjw7luZyAocmVzcG9uc2UpLg0KDQrEkMO0aSBraGkgY8O5bmcgMSBk4buvIGxp4buHdSDEkeG6p3UgdsOgbyBuaMawbmcgY8OzIGto4bqjIG7Eg25nIHThuqFvIHJhIHLhuqV0IG5oaeG7gXUgbcO0IGjDrG5oIGtow6FjIG5oYXUgYuG6sW5nIGPDoWNoIGdpYSBnaeG6o20sIHRow6ptIGLhu5t0IGPDoWMgYmnhur9uIHPhu5EgYsOqbiB0cm9uZyBtw7QgaMOsbmguIFThuqFpIGPhu61hIGjDoG5nIEFybW9yaW5vLCBi4bqhbiDEkeG7qW5nIHRyxrDhu5tjIG3hu5l0IHThu6cga8OtbmggduG7m2kgaMOgbmcgY2jhu6VjIGxv4bqhaSBrZW0sIHbDoCBjw7MgdGjhu4MgY2jhu41uIDIsMywgdGjhuq1tIGNow60gNSBtw7lpIGtow6FjIG5oYXUuIENo4buLIGLDoW4ga2VtIHPhur0gZMOhbiB04burbmcgbOG7m3Aga2VtIHbhu5tpIG5oYXUgdHLDqm4gY29ybmV0IMSR4buDIHNhdSDEkcOzIGLhuqFuIGPDsyB0aOG7gyB2dWkgduG6uyBk4bqhbyBwaOG7kSB24bubaSBjw6BuaCBob2EgaOG7k25nIHRyw6puIHRheSB2w6AgY2jhu6VwIHNlbGZpZSB24bubaSBuw7MuIELhurFuZyBjw6FjaCB0aOG7qWMgdMawxqFuZyB04buxLCBt4buNaSBtw7QgaMOsbmggaOG7k2kgcXV5IMSRw6MgxJHGsOG7o2MgdOG6oW8gcmEgdHJvbmcgUiwgZMO5IGLhuqFuIHPhu60gZOG7pW5nIHBhY2thZ2UgZ2FtbHNzIGhheSBnbG0uDQoNCioqQ8O0bmcgdGjhu6ljIHRow6BuaCBwaOG6p24gdHV54bq/biB0w61uaCB2w6AgdG/DoW4gdOG7rSoqDQoNCkPDoWMgdGjDoG5oIHBo4bqnbiB0dXnhur9uIHTDrW5oIMSRxrDhu6NjIMSRxrBhIHbDoG8gbcO0IGjDrG5oIHRow7RuZyBxdWEgY8O0bmcgdGjhu6ljIChmb3JtdWxhKSB2w6AgbGnDqm4ga+G6v3QgduG7m2kgbmhhdSBi4bqxbmcgMiB0b8OhbiB04butIDogY+G7mW5nIHRow6ptICgrKSB2w6AgdMawxqFuZyB0w6FjICgqKS4NCg0KSGFpIHRvw6FuIHThu60gbsOgeSBjw7Mgbmd14buTbiBn4buRYyBsw6J1IMSR4budaSAoxJHhu4EgeHXhuqV0IGLhu59pIFdpbGtpbnNvbiB2w6AgUm9nZXJzIG7Eg20gMTk3MyB2w6AgxJHGsGEgdsOgbyBuZ8O0biBuZ+G7ryBs4bqtcCB0csOsbmggdGjhu5FuZyBrw6ogUyAobMOgIHRp4buBbiB0aMOibiBj4bunYSBSKSBi4bufaSBDaGFtYmVycyB2w6AgSGFzdGllIG7Eg20gMTk5MikuIERvIMSRxrDhu6NjIHF1eSDGsOG7m2Mgc+G6tW4gdHJvbmcgUiBuw6puIGjhuqd1IGjhur90IChraMO0bmcgcGjhuqNpIHThuqV0IGPhuqMpIGPDoWMgcGFja2FnZSBo4buTaSBxdXkgc+G7rSBk4bulbmcgZm9ybXVsYSDEkeG7gXUgZMO5bmcgKyB2w6AgKiB24bubaSDDvSBuZ2jEqWEgbmjGsCBuaGF1LiANCg0KQ8OhYyBi4bqhbiB04burbmcgbMOgbSBBTk9WQSBoYXkgaOG7k2kgcXV5IHbhu5tpIGjDoG0gZ2xtKCkgaG/hurdjIGxtKCkgxJHhu4F1IHF1ZW4gdGh14buZYyB24bubaSBjw7RuZyB0aOG7qWMgdsOgIDIgdG/DoW4gdOG7rSArLCAqLCBuaMawbmcg4bufIMSRw6J5IE5oaSBz4bq9IG5o4bqvYyBs4bqhaSB24buBIGPDuiBwaMOhcCBj4bunYSBjw7RuZyB0aOG7qWMgaOG7k2kgcXV5IGNobyBjw6FjIGLhuqFuIG3hu5tpIGzDoG0gcXVlbiB24bubaSBSIDoNCg0KKlRvw6FuIHThu60gKyoNCg0KVG/DoW4gdOG7rSArIGPDsyBjw7RuZyBk4bulbmcga+G6v3QgaOG7o3AgMiB0aGFtIHPhu5EgaOG7k2kgcXV5IChwcmVkaWN0b3JzKSB24bubaSBuaGF1IGLhurFuZyBwaMOpcCBj4buZbmcgOg0KVGjDrSBk4bulIDogWSB+IFgxICsgWDIgKyDigKYgWG4NCg0KTuG6v3UgWCBsw6AgMSBiaeG6v24gbGnDqm4gdOG7pWMsIHRvw6FuIHThu60gKyBz4bq9IGfDoW4gdmVjdG9yIFggdsOgbyBtYXRyaXggY+G7p2EgbcO0IGjDrG5oIGjhu5NpIHF1eSAoY+G7mW5nIHRow6ptIDEgY+G7mXQgZHV5IG5o4bqldCkuIFbhu5tpIDIgcHJlZGljdG9ycyBYMStYMiwgbeG7mXQgbeG6t3QgcGjhurNuZyBo4buTaSBxdXkgc+G6vSDEkcaw4bujYyB04bqhbyByYS4NCg0KTuG6v3UgdGEgxJHGsGEgdsOgbyAxIHnhur91IHThu5EgKGZhY3RvcikgRiB24bubaSBuaGnhu4F1IGxldmVsLCBGIHPhur0gYuG7iyBj4bqvdCByYSB0aMOgbmggbmhp4buBdSBiaeG6v24gZ2nhuqMgKGR1bW15IHZhcmlhYmxlKSDEkcaw4bujYyBtw6MgaMOzYSBi4bqxbmcgZ2nDoSB0cuG7iyAwIHbDoCAxLCBt4buXaSBj4buZdCBkdW1teSB2YXJpYWJsZSB0xrDGoW5nIOG7qW5nIHbhu5tpIDEgbGV2ZWwuIA0KDQpLaGkgbcO0IGjDrG5oIGPDsyBjaOG7qWEgaW50ZXJjZXB0LCB2w6AgdGEgbXXhu5FuIGto4bqjbyBzw6F0IG3hu5l0IHnhur91IHThu5EgRiBjw7MgayBsZXZlbHMgdGjDrCBjaOG7iSBjw7MgKGstMSkgbGV2ZWwgxJHGsOG7o2MgbcOjIGjDs2EgdGhlbyBk4bqhbmcgZHVtbXkgdmFyaWFibGUsIGxldmVsIMSR4bqndSB0acOqbiBj4bunYSBGIHPhur0gYuG7iyBnaeG6o24gbMaw4bujYyB2w6Aga2jDtG5nIMSRxrDhu6NjIHRyw6xuaCBiw6B5IHRyb25nIG3DtCBow6xuaCBzYXUgY8O5bmcuIA0KDQpUYSBjw7MgdGjhu4MgdOG7lSBjaOG7qWMgbOG6oWkgbuG7mWkgZHVuZyBj4bunYSBGIGLhurFuZyBow6BtIGNvbnRyYXN0cyggKS4gDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCg0KRjE9Z2woMiwxLDI1KQ0KbGV2ZWxzKEYxKT1jKCJHcm91cDEiLCAiR3JvdXAyIikNCg0KRjI9Z2woMywyLDI1KQ0KbGV2ZWxzKEYyKT1jKCJDb25kQSIsICJDb25kQiIsIkNvbmRDIikNCg0KWDE9cm5vcm0oMjUsMTAsMikNCg0KWDI9cm5vcm0oMjUsNSwxLjUpDQoNCmBgYA0KDQpgYGB7cn0NCmhlYWQobW9kZWwubWF0cml4KH5YMSksMTApJT4la25pdHI6OmthYmxlKCkNCg0KaGVhZChtb2RlbC5tYXRyaXgoflgxK1gyKSwxMCklPiVrbml0cjo6a2FibGUoKQ0KDQoNCmhlYWQobW9kZWwubWF0cml4KH5GMiksMTApJT4la25pdHI6OmthYmxlKCkNCg0KaGVhZChtb2RlbC5tYXRyaXgofkYyLTEpLDEwKSU+JWtuaXRyOjprYWJsZSgpDQoNCmBgYA0KDQoqVG/DoW4gdOG7rSB0xrDGoW5nIHTDoWMqDQoNClRvw6FuIHThu60gKiBjw7MgY8O0bmcgZOG7pW5nIGJp4buDdSBkaeG7hW4gbeG7mXQgc+G7sSB0xrDGoW5nIHTDoWMgZ2nhu69hIDIgaGF5IG5oaeG7gXUgcHJlZGljdG9ycywNCmNow7puZyBjw7MgdGjhu4MgbMOgIGJp4bq/biBsacOqbiB04bulYyBoYXkgeeG6v3UgdOG7kSAsIHRow60gZOG7pSA6DQoNClkgfiBYMSpYMg0KDQpZIH4gWCpGIA0KDQpZIH4gRjEqRjINCg0KTMawdSDDvSBy4bqxbmcga2hpIHZp4bq/dCBYMSpYMiwgdGjhu7FjIHJhIHRhIG114buRbiB4w6l0IGPhuqMgMyBoaeG7h3Ug4bupbmcgOiAyIGhp4buHdSDhu6luZyByacOqbmcgcGjhuqduIGPhu6dhIFgxIHbDoCBYMiwgdsOgIGhp4buHdSDhu6luZyB0xrDGoW5nIHTDoWMgZ2nhu69hIGNow7puZywgZG8gxJHDsyA6IA0KDQpZIH4gWDEqWDIgdMawxqFuZyDEkcawxqFuZyA6IFkgfiBYMSArWDIgKyBYMTpYMg0KDQpUxrDGoW5nIHTDoWMgZ2nhu69hIDIgZmFjdG9ycyBGMSAoazEgbGV2ZWwpIHbDoCBGMiAoazIgbGV2ZWwpIHPhur0gdOG6oW8gcmEgdHJvbmcgbWF0cml4IChrMS0xKSooazItMSkgDQoNCnbDoCAoazEtMSkgKyAoazItMSkgaGF5IChrMSprMiktMSBj4buZdCBkdW1teSB2YXJpYWJsZSBjaG8gaGnhu4d1IOG7qW5nIGNow61uaCB2w6AgaGnhu4d1IOG7qW5nIHTGsMahbmcgdMOhYy4gDQoNClRow60gZOG7pSBGMSBjw7MgMiBsZXZlbCAoYSxiKSwgRjIgY8OzIDMgbGV2ZWwgbMOgICgxLDIsMykgdGjDrCBz4bq9IGPDsyA1IGR1bW15IHZhcmlhYmxlIGfhu5NtIA0KRjFiLCBGMjIsIEYyMywgRjFCIDpGMjIsIEYxQiA6RjIzDQoNCmBgYHtyfQ0KaGVhZChtb2RlbC5tYXRyaXgoflgxKkYyKSwxMCklPiVrbml0cjo6a2FibGUoKQ0KDQpoZWFkKG1vZGVsLm1hdHJpeCh+RjErRjIpLDEwKSU+JWtuaXRyOjprYWJsZSgpDQoNCmhlYWQobW9kZWwubWF0cml4KH5GMSpGMiksMTApJT4la25pdHI6OmthYmxlKCkNCg0KaGVhZChtb2RlbC5tYXRyaXgoflgxKlgyKkYxKkYyKSwxMCklPiVrbml0cjo6a2FibGUoKQ0KDQpgYGANCg0KS2hpIHRhIG114buRbiB4w6l0IHTGsMahbmcgdMOhYyBnaeG7r2EgMiBiaeG6v24gbGnDqm4gdOG7pWMgWCB2w6AgMSB54bq/dSB04buRIEYgKGsgbGV2ZWwpLCB0cm9uZyBtYXRyaXggc+G6vSBn4buTbSA6IDEgY+G7mXQgY2hvIHZlY3RvciBYLCAoay0xKSBj4buZdCBjaG8gY8OhYyBkdW1teSBoaeG7h3Ug4bupbmcgY2jDrW5oIGPhu6dhIChrLTEpIGxldmVsIHRyb25nIEYgdsOgIChrLTEpIGPhu5l0IGNobyBoaeG7h3Ug4bupbmcgdMawxqFuZyB0w6FjIGdp4buvYSBYIHbDoCBjw6FjIGR1bW15IHZhcmlhYmxlIGPhu6dhIChrLTEpIGxldmVsIHRyb25nIEYuDQoNCioqTGnDqm4gaOG7hyBnaeG7r2EgbcO0IGjDrG5oIHR1eeG6v24gdMOtbmggdsOgIHBow6JuIHTDrWNoIMSR4buLbmggbMaw4bujbmcqKg0KDQpOaMawIGNow7puZyB0YSDEkcOjIGJp4bq/dCwgY8OzIGxpw6puIGjhu4cgY2jhurd0IGNo4bq9IGdp4buvYSBtw7QgaMOsbmggdHV54bq/biB0w61uaCB2w6AgY8OhYyBwaMawxqFuZyBwaMOhcCB0aOG7kW5nIGvDqiBj4buVIMSRaeG7g24sIHbDoCBuaOG7r25nIHRoaeG6v3Qga+G6vyBuZ2hpw6puIGPhu6l1IGPDsyB0aOG7gyDEkcaw4bujYyBiaeG7g3UgZGnhu4VuIHRow7RuZyBxdWEgbcO0IGjDrG5oLCB0aMOtIGThu6UgOg0KDQpZIH4gMSBsw6AgbeG7mXQgbcO0IGjDrG5oIGNo4buJIGNo4bupYSBpbnRlcmNlcHQsIG7DsyB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIHZp4buHYyBraOG6o28gc8OhdCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIFksIGhv4bq3YyB24bubaSBow6BtIMO9IGNodeG6qW4gYuG7iyAxIG3DtCBow6xuaCBjxqEgYuG6o24gKGJhc2VsaW5lIG1vZGVsKSBkw7luZyB2w6BvIHZp4buHYyDEkcOhbmggZ2nDoSBwaOG6qW0gY2jhuqV0IGPhu6dhIG5o4buvbmcgbcO0IGjDrG5oIGtow6FjIDsgdGjDrSBk4bulIHRyb25nIGjhu5NpIHF1eSBsb2dpc3RpYywgbeG7mXQgbW9kZWwgY2jhu4kgYuG6r3QgxJHhuqd1IMSRw6FuZyB0aW4gbuG6v3UgbsOzIGPDsyB0aOG7gyDEkcOhbmggYuG6oWkgcXV5IGx14bqtdCBiaW5ub21pYWwgbmfhuqt1IG5oacOqbi4NCg0KWSB+IFggduG7m2kgWCBsw6AgMSBiaeG6v24gbGnDqm4gdOG7pWMgOiB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIGjhu5NpIHF1eSDEkcahbiBiaeG6v24gaGF5IGto4bqjbyBzw6F0IHTGsMahbmcgcXVhbiB0dXnhur9uIHTDrW5oIGdp4buvYSBZIHbDoCBYDQoNClkgfiBGIHbhu5tpIEYgbMOgIDEgZmFjdG9yIHThu6sgMiBsZXZlbCB0cuG7nyBsw6puIDogdMawxqFuZyDEkcawxqFuZyB24bubaSBPbmUgd2F5IEFOT1ZBIChwaMOibiB0w61jaCBwaMawxqFuZyBzYWkgMSB54bq/dSB04buRKS4NCg0KWSB+IFgxICsgWDIgOiB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIGto4bqjbyBzw6F0IHF1YW4gaOG7hyByacOqbmcgcGjhuqduIGdp4buvYSBZLFgxIHbDoCBYMg0KDQpZIH4gWCpGIDogdMawxqFuZyDEkcawxqFuZyB24bubaSBBTkNPVkENCg0KWSB+IEYxKkYy4oCmRm4gOiB0xrDGoW5nIMSRxrDGoW5nIHbhu5tpIG4gd2F5cyBBTk9WQQ0KDQoqKlRow60gZOG7pSBtaW5oIGjhu41hKioNCg0KTmhpIGzhuqV5IHRow60gZOG7pSBkYXRhc2V0IGNpZ2FyZXR0ZSwgxJHDonkgbMOgIDEgYsOgaSB0b8OhbiBo4buTaSBxdXkgduG7m2kgY8OidSBo4buPaSBsw6AgbGnhu4d1IHZp4buHYyDEkcOhbmggdGh14bq/IGzDqm4gdGh14buRYyBsw6EgY8OzIGzDoG0gZ2nhuqNtIGRvYW5oIHPhu5EgY+G7p2Egc+G6o24gcGjhuqltIG7DoHkgaGF5IGtow7RuZyA/IFTDoWMgZ2nhuqMgxJHDoyBnaGkgbmjhuq1uIGdpw6EgdGh14buRYyBsw6EgdHJvbmcgdsOybmcgMzAgbsSDbSB04burIDE5NjMgdOG6oWkgNTEgYmFuZyBj4bunYSBIb2Ega+G7sywgxJHhu5NuZyB0aOG7nWkgZ2hpIG5o4bqtbiBjw6FjIGJp4bq/biBuaMawIGTDom4gc+G7kSwgZMOibiBz4buRID4xNiB0deG7lWksIHRodSBuaOG6rXAgYsOsbmggcXXDom4gxJHhuqd1IG5nxrDhu51pLCBnacOhIHRodeG7kWMgbMOhLiBCaeG6v24ga+G6v3QgcXXhuqMgbMOgIG3hu6ljIHRpw6p1IHRo4bulIHRodeG7kWMgbMOhLg0KDQpUcm9uZyBraGkgdGjEg20gZMOyIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGvhur90IHF14bqjICht4bupYyB0acOqdSB0aOG7pSB0aHXhu5FjIGzDoSB0w61uaCBi4bqxbmcgZ8OzaSB0csOqbiDEkeG6p3UgbmfGsOG7nWkpIHbDoCBuaOG7r25nIGJp4bq/biBz4buRIGtow6FjIHRyb25nIGThu68gbGnhu4d1LCB0csOqbiBt4buZdCBraMO0bmcgZ2lhbiAyIGNoaeG7gXUsIGNow7puZyB0YSB0aOG7sWMgcmEgY8OzIHRo4buDIGPhuqNtIG5o4bqtbiDEkcaw4bujYyB24buBIG5o4buvbmcgbcO0IGjDrG5oIGjhu5NpIHF1eSDEkcahbiBiaeG6v24sIEFOT1ZBLCBtw7QgaMOsbmggY8OzIGhp4buHdSDhu6luZyB0xrDGoW5nIHTDoWMuLi4NCg0KYGBge3IsbWVzc2FnZSA9IEZBTFNFLHdhcm5pbmc9RkFMU0V9DQpjaWdhcmV0dGU9cmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vdmluY2VudGFyZWxidW5kb2NrL1JkYXRhc2V0cy9tYXN0ZXIvY3N2L3BsbS9DaWdhci5jc3YiKQ0KDQpjaWdhcmV0dGUkc3RhdGU9ZmFjdG9yKGNpZ2FyZXR0ZSRzdGF0ZSkNCmNpZ2FyZXR0ZSR5ZWFyPWZhY3RvcihjaWdhcmV0dGUkeWVhci02MikNCg0KbGlicmFyeSh2aXJpZGlzKQ0KDQpjaWdhcmV0dGUlPiVnZ3Bsb3QoKSsNCiAgZ2VvbV9ib3hwbG90KGFlcyh4PWFzLmludGVnZXIoeWVhcikseT1zYWxlcyxmaWxsPXllYXIsY29sb3I9eWVhciksc2hvdy5sZWdlbmQgPSBGLGFscGhhPTAuMikrDQogIHRoZW1lX2J3KDEwKSsNCiAgc2NhbGVfZmlsbF92aXJpZGlzKGRpc2NyZXRlPVQsb3B0aW9uPSJDIixkaXJlY3Rpb24gPSAtMSkrDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGU9VCxvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHg9YXMuaW50ZWdlcih5ZWFyKSx5PXNhbGVzKSxzaG93LmxlZ2VuZCA9IEYsY29sb3I9ImRhcmt2aW9sZXQiLGZpbGw9ImdvbGQiKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKCIzMCB5ZWFycyBwZXJpb2QiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIGdndGl0bGUoIk1vZGVsOiBTYWxlfiBZZWFyIChhcyBkdW1teSB2YXJpYWJsZXMpIikNCg0KY2lnYXJldHRlJT4lZ2dwbG90KCkrDQogIGdlb21fcGF0aChhZXMoeD1hcy5pbnRlZ2VyKHllYXIpLHk9c2FsZXMsY29sb3I9cmVvcmRlcihzdGF0ZSxzYWxlcykpLHNob3cubGVnZW5kID0gRikrDQogIHRoZW1lX2J3KDEwKSsNCiAgc2NhbGVfY29sb3VyX3ZpcmlkaXMoZGlzY3JldGU9VCxvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKCIzMCB5ZWFycyBwZXJpb2QiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIGdndGl0bGUoIk1vZGVsOiBTYWxlfiBZZWFyKlN0YXRlIChib3RoIGFzIGZhY3RvcnMpIikNCg0KY2lnYXJldHRlJT4lZ2dwbG90KCkrDQogIGdlb21faml0dGVyKGFlcyh4PWFzLmludGVnZXIoeWVhcikseT1zYWxlcyxjb2xvcj1zYWxlcyksc2l6ZT0xLGFscGhhPTAuNSkrDQogIGdlb21fc21vb3RoKGFlcyh4PWFzLmludGVnZXIoeWVhcikseT1zYWxlcyksc2hvdy5sZWdlbmQgPSBGLGNvbG9yPSJwdXJwbGUiLGZpbGw9ImdvbGQiKSsNCiAgdGhlbWVfYncoMTApKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoIjMwIHllYXJzIHBlcmlvZCIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkNpZ2FyZXR0ZSBzYWxlcyAocGFja3MgcGVyIGNhcGl0YSkiKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1GLG9wdGlvbj0iQiIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJNb2RlbDogU2FsZX4gWWVhciAoYXMgZGlzY3JldGUgbnVtYmVyKSIpDQoNCmNpZ2FyZXR0ZSU+JWdncGxvdCgpKw0KICBnZW9tX2ppdHRlcihhZXMoeD1wcmljZSx5PXNhbGVzLGNvbG9yPXNhbGVzKSxzaXplPTEsYWxwaGE9MC41KSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpY2UseT1zYWxlcyksc2hvdy5sZWdlbmQgPSBGLGNvbG9yPSJwdXJwbGUiLGZpbGw9ImdvbGQiKSsNCiAgdGhlbWVfYncoMTApKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoIlByaWNlIHBlciBwYWNrIikrDQogIHNjYWxlX3lfY29udGludW91cygiQ2lnYXJldHRlIHNhbGVzIChwYWNrcyBwZXIgY2FwaXRhKSIpKw0KICBzY2FsZV9jb2xvcl92aXJpZGlzKGRpc2NyZXRlPUYsb3B0aW9uPSJCIixkaXJlY3Rpb24gPSAtMSkrDQogIGdndGl0bGUoIk1vZGVsOiBTYWxlfiBQcmljZSBwZXIgcGFjayIpDQoNCmNpZ2FyZXR0ZSU+JWdncGxvdCgpKw0KICBnZW9tX3BvaW50KGFlcyh4PXBpbWluLHk9c2FsZXMsY29sb3I9c2FsZXMpLHNpemU9MSxhbHBoYT0wLjIpKw0KICBnZW9tX3Ntb290aChhZXMoeD1waW1pbix5PXNhbGVzKSxjb2xvcj0icHVycGxlIixmaWxsPSJnb2xkIikrDQogIHRoZW1lX2J3KDEwKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKCJtaW5pbXVtIHByaWNlIGluIGFkam9pbmluZyBzdGF0ZXMgcGVyIHBhY2siKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGU9RixvcHRpb249IkIiLGRpcmVjdGlvbiA9IC0xKSsNCiAgZ2d0aXRsZSgiTW9kZWw6IFNhbGV+IG1pbmltdW0gcHJpY2UiKQ0KDQpjaWdhcmV0dGUlPiVnZ3Bsb3QoKSsNCiAgZ2VvbV9qaXR0ZXIoYWVzKHg9cHJpY2UseT1zYWxlcyksc2l6ZT0xLGFscGhhPTAuMixzaG93LmxlZ2VuZCA9IEYsY29sb3I9ImdyZXkiKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpY2UseT1zYWxlcyxjb2xvcj15ZWFyKSxzaG93LmxlZ2VuZCA9IEYsc2U9RixtZXRob2Q9ImxtIikrDQogIHRoZW1lX2J3KDEwKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKCJQcmljZSBwZXIgcGFjayIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkNpZ2FyZXR0ZSBzYWxlcyAocGFja3MgcGVyIGNhcGl0YSkiKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1ULG9wdGlvbj0iQyIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJNb2RlbDogU2FsZX4gUHJpY2U6WWVhciIpDQoNCmNpZ2FyZXR0ZSU+JWdncGxvdCgpKw0KICBnZW9tX2ppdHRlcihhZXMoeD1wcmljZSx5PXNhbGVzKSxzaXplPTEsYWxwaGE9MC4yLHNob3cubGVnZW5kID0gRixjb2xvcj0iZ3JleSIpKw0KICBnZW9tX3Ntb290aChhZXMoeD1wcmljZSx5PXNhbGVzLGNvbG9yPXN0YXRlKSxzaG93LmxlZ2VuZCA9IEYsc2U9RikrDQogIHRoZW1lX2J3KDEwKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKCJQcmljZSBwZXIgcGFjayIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkNpZ2FyZXR0ZSBzYWxlcyAocGFja3MgcGVyIGNhcGl0YSkiKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1ULG9wdGlvbj0iQyIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJNb2RlbDogU2FsZX4gUHJpY2UqU3RhdGUiKQ0KDQpjaWdhcmV0dGUlPiVnZ3Bsb3QoKSsNCiAgZ2VvbV9qaXR0ZXIoYWVzKHg9bG9nKHBvcDE2KSx5PXNhbGVzLGNvbG9yPXNhbGVzKSxzaXplPTEsYWxwaGE9MC41KSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHg9bG9nKHBvcDE2KSx5PXNhbGVzKSxzaG93LmxlZ2VuZCA9IEYsY29sb3I9InB1cnBsZSIsZmlsbD0iZ29sZCIpKw0KICB0aGVtZV9idygxMCkrDQogIHNjYWxlX3hfY29udGludW91cygiUG9wdWxhdGlvbiBhYm92ZSAxNiB5cnMgb2xkIGluIExvZyBzY2FsZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkNpZ2FyZXR0ZSBzYWxlcyAocGFja3MgcGVyIGNhcGl0YSkiKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1GLG9wdGlvbj0iQiIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJNb2RlbDogU2FsZX4gbG9nKFBvcHVsYXRpb24+MTYgeXJzKSIpDQoNCmNpZ2FyZXR0ZSU+JWdncGxvdCgpKw0KICBnZW9tX2ppdHRlcihhZXMoeD1uZGkseT1zYWxlcyxjb2xvcj1zYWxlcyksc2l6ZT0xLGFscGhhPTAuNSkrDQogIGdlb21fc21vb3RoKGFlcyh4PW5kaSx5PXNhbGVzKSxzaG93LmxlZ2VuZCA9IEYsY29sb3I9InB1cnBsZSIsZmlsbD0iZ29sZCIpKw0KICB0aGVtZV9idygxMCkrDQogIHNjYWxlX3hfY29udGludW91cygiUGVyIGNhcGl0YSBkaXNwb3NhYmxlIGluY29tZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkNpZ2FyZXR0ZSBzYWxlcyAocGFja3MgcGVyIGNhcGl0YSkiKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1GLG9wdGlvbj0iQiIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJNb2RlbDogU2FsZX4gUGVyIGNhcGl0YSBkaXNwb3NhYmxlIGluY29tZSIpDQoNCmNpZ2FyZXR0ZSU+JWdncGxvdCgpKw0KICBnZW9tX2ppdHRlcihhZXMoeD1wcmljZSx5PXNhbGVzLGNvbG9yPSBmYWN0b3Iocm91bmQobG9nKGNpZ2FyZXR0ZSRuZGkpLDApKSksc2l6ZT0xLGFscGhhPTAuMixzaG93LmxlZ2VuZCA9IEYpKw0KICBnZW9tX3Ntb290aChhZXMoeD1wcmljZSx5PXNhbGVzLGNvbG9yPSBmYWN0b3Iocm91bmQobG9nKGNpZ2FyZXR0ZSRuZGkpLDApKSksc2hvdy5sZWdlbmQgPSBGLHNlPUYsbWV0aG9kPSJsbSIpKw0KICB0aGVtZV9idygxMCkrDQogIHNjYWxlX3hfY29udGludW91cygiUHJpY2UgcGVyIHBhY2siKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGU9VCxvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgZ2d0aXRsZSgiTW9kZWw6IFNhbGV+IFByaWNlICogUGVyIGNhcGl0YSBkaXNwb3NhYmxlIGluY29tZSIpDQoNCmNpZ2FyZXR0ZSU+JWdncGxvdCgpKw0KICBnZW9tX2JveHBsb3QoYWVzKHg9cmVvcmRlcihzdGF0ZSxzYWxlcykseT1zYWxlcyxmaWxsPXJlb3JkZXIoc3RhdGUsc2FsZXMpLGNvbG9yPXJlb3JkZXIoc3RhdGUsc2FsZXMpKSxzaG93LmxlZ2VuZCA9IEYsYWxwaGE9MC41KSsNCiAgdGhlbWVfYncoMTApKw0KICBzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGU9VCxvcHRpb249IkIiLGRpcmVjdGlvbiA9IC0xKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1ULG9wdGlvbj0iQiIsZGlyZWN0aW9uID0gLTEpKw0KICBzY2FsZV94X2Rpc2NyZXRlKCI1MSBTdGF0ZXMiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIGdndGl0bGUoIk9uZV93YXkgQU5PVkE6IFNhbGV+IFN0YXRlIChhcyBkdW1teSB2YXJpYWJsZXMpIikNCg0KDQpjaWdhcmV0dGUlPiVnZ3Bsb3QoKSsNCiAgZ2VvbV9qaXR0ZXIoYWVzKHg9cHJpY2UseT1zYWxlcyxjb2xvcj15ZWFyKSxzaXplPTEsYWxwaGE9MC4yLHNob3cubGVnZW5kID0gRikrDQogIGdlb21fc21vb3RoKGFlcyh4PXByaWNlLHk9c2FsZXMsY29sb3I9eWVhciksc2hvdy5sZWdlbmQgPSBGLHNlPUYpKw0KICB0aGVtZV9idygxMCkrDQogIHNjYWxlX3hfY29udGludW91cygiUHJpY2UgcGVyIHBhY2siKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGU9VCxvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgZmFjZXRfd3JhcCh+eWVhcixzY2FsZXM9ImZyZWUiKSsNCiAgZ2d0aXRsZSgiTW9kZWw6IFNhbGV+IFByaWNlICsgcmFuZG9tKDF8WWVhcikiKSsNCiAgdGhlbWVfYncoMykNCg0KY2lnYXJldHRlJT4lZ2dwbG90KCkrDQogIGdlb21faml0dGVyKGFlcyh4PXByaWNlLHk9c2FsZXMsY29sb3I9c3RhdGUpLHNpemU9MSxhbHBoYT0wLjIsc2hvdy5sZWdlbmQgPSBGKSsNCiAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpY2UseT1zYWxlcyxjb2xvcj1zdGF0ZSksc2hvdy5sZWdlbmQgPSBGLHNlPUYpKw0KICB0aGVtZV9idygxMCkrDQogIHNjYWxlX3hfY29udGludW91cygiUHJpY2UgcGVyIHBhY2siKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDaWdhcmV0dGUgc2FsZXMgKHBhY2tzIHBlciBjYXBpdGEpIikrDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGU9VCxvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgZmFjZXRfd3JhcCh+c3RhdGUsc2NhbGVzPSJmcmVlIikrDQogIGdndGl0bGUoIk1vZGVsOiBTYWxlfiBQcmljZSArIFllYXIgKyByYW5kb20oMXxTdGF0ZSkiKSsNCiAgdGhlbWVfYncoMykNCg0KcDI9Y2lnYXJldHRlJT4lZ2dwbG90KGFlcyh4PXNhbGVzKSkrDQogIGdlb21faGlzdG9ncmFtKGFlcyh5PS4uZGVuc2l0eS4uLGZpbGw9Li5kZW5zaXR5Li4sY29sb3I9Li5kZW5zaXR5Li4pLGJpbndpZHRoID0gMSwgYWxwaGE9MC43LHNob3cubGVnZW5kID0gRikrDQogIGdlb21fZGVuc2l0eShhbHBoYT0uMSxjb2xvcj0iYmxhY2siLGZpbGw9ImdvbGQiLGxpbmV0eXBlPTIpKw0KICB0aGVtZV9idygpKw0KICBzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGU9RixvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1GLG9wdGlvbj0iQyIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJUcnVlIG9ic2VydmF0aW9ucyIpDQpgYGANCg0KIyBUaMSDbSBkw7IgcGjDom4gcGjhu5FpIA0KDQoNCk5oxrAgdHJvbmcgYsOgaSAyLCBixrDhu5tjIMSR4bqndSB0acOqbiBraGkgZOG7sW5nIG3DtCBow6xuaCB0cm9uZyBnYW1sc3MgbMOgIHRoxINtIGTDsiB24buBIMSR4bq3YyB0w61uaCBwaMOibiBwaOG7kWkgY+G7p2EgYmnhur9uIGvhur90IHF14bqjLiBC4bqxbmcgaMOgbSBmaXRkaXN0LCBOaGkgbmhhbmggY2jDs25nIHjDoWMgxJHhu4tuaCDEkcaw4bujYyBwaMOibiBwaOG7kWkgcGjDuSBo4bujcCBuaOG6pXQgY2hvIGJp4bq/biBzYWxlcyBsw6AgaOG7jSBwaMOibiBwaOG7kWkgU2tld2VkIFQgdHlwZSA0LiBI4buNIHBow6JuIHBo4buRaSBuw6B5IMSRxrDhu6NjIG3DtCB04bqjIGLhu59pIDQgdGhhbSBz4buRIGzDoCBNdSwgU2lnbWEsIE51IHbDoCBUYXUgKGPDsyB0aOG7gyBow6xuaCBkdW5nIGzDoCBNZWFuLCBTZCwgc2tld25lc3MgdsOgIGt1cnRvc2lzKS4gU+G7rSBk4bulbmcgaMOgbSByU1Q0LCBOaGkgbcO0IHBo4buPbmcgbeG7mXQgbeG6q3Ugbmfhuqt1IG5oacOqbiB24bubaSBNdSwgU2lnbWEsIFRhdSB2w6AgTnUgY+G7p2EgbcO0IGjDrG5oIGNo4buJIGNo4bupYSBJbnRlcmNlcHQpLCBr4bq/dCBxdeG6oyBtw7QgcGjhu49uZyBraMOhIHBow7kgaOG7o3AgduG7m2kgcXVhbnMgw6F0IHRyw6puIHRo4buxYyB04bq/IDoNCg0KDQpgYGB7cixtZXNzYWdlID0gRkFMU0Usd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZ2FtbHNzKQ0KDQpzY2FuPWZpdERpc3Qoc2FsZXMsZGF0YT1jaWdhcmV0dGUsdHlwZT0icmVhbEFsbCIsaz1sb2cobnJvdyhjaWdhcmV0dGUpKSxwYXJhbGxlbD0ibXVsdGljb3JlIixuY3B1cyA9IDQpDQoNCnNjYW4kZml0cw0KDQpnYW1sc3MuZmFtaWx5KFNUNCkNCg0Kc2V0LnNlZWQoMTIzNDU2KQ0KcDE9clNUNCgxMDAwLCBtdSA9IDExOSwgc2lnbWEgPWV4cCgyLjgzMyksIG51PWV4cCgxLjg5MiksIHRhdT1leHAoMC42MTk0KSklPiUNCiAgYXNfdGliYmxlKCklPiUNCiAgZ2dwbG90KGFlcyh4PXZhbHVlKSkrDQogIGdlb21faGlzdG9ncmFtKGFlcyh5PS4uZGVuc2l0eS4uLGZpbGw9Li5kZW5zaXR5Li4sY29sb3I9Li5kZW5zaXR5Li4pLGJpbndpZHRoID0gMSwgYWxwaGE9MC43LHNob3cubGVnZW5kID0gRikrDQogIGdlb21fZGVuc2l0eShhbHBoYT0uMSxjb2xvcj0iYmxhY2siLGZpbGw9ImdvbGQiLGxpbmV0eXBlPTIpKw0KICB0aGVtZV9idygpKw0KICBzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGU9RixvcHRpb249IkMiLGRpcmVjdGlvbiA9IC0xKSsNCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1GLG9wdGlvbj0iQyIsZGlyZWN0aW9uID0gLTEpKw0KICBnZ3RpdGxlKCJTaW11bGF0ZWQgU1Q0IChtdT0xMTkscz1leHAoMi44MyksbnU9ZXhwKDEuODkpLHRhdT1leHAoMC42MikpIikNCg0KZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UocDEscDIsbmNvbD0xKQ0KDQpgYGANCg0KIyBNw7QgaMOsbmggZ2FtbHNzIHbhu5tpIGPDoWMgdGjDoG5oIHBo4bqnbiB0dXnhur9uIHTDrW5oDQoNCk5oaSBz4bq9IGzhuqduIGzGsOG7o3QgZOG7sW5nIDUgbcO0IGjDrG5oLCBjw6FjIGLhuqFuIGPDsyB0aOG7gyB4ZW0geMOpdCBmb3JtdWxhIHbDoCBu4buZaSBkdW5nIGPhu6dhIG3DtCBow6xuaCB4deG6pXQgcmEgxJHhu4MgY8OzIHRo4buDIGjDrG5oIGR1bmcgduG7gSBob+G6oXQgxJHhu5luZyBj4bunYSB0b8OhbiB04butICsgdsOgICosIMSR4buTbmcgdGjhu51pIGRp4buFbiBk4buLY2ggY8OhYyB0aMOgbmggcGjhuqduIHR1eeG6v24gdMOtbmgsIHTGsMahbmcgdMOhYyB0cm9uZyBtw7QgaMOsbmguDQoNCg0KKipNw7QgaMOsbmggY2jhu4kgY2jhu6lhIGjhurFuZyBz4buRKioNCg0KYGBge3IsbWVzc2FnZSA9IEZBTFNFLHdhcm5pbmc9RkFMU0V9DQoNCm5DPC1kZXRlY3RDb3JlcygpDQoNCm0wPWdhbWxzcyhkYXRhPWNpZ2FyZXR0ZSwNCiAgICAgICAgICBmb3JtdWxhPXNhbGVzfjEsDQogICAgICAgICAgZmFtaWx5PVNUNCwNCiAgICAgICAgICB0cmFjZT1GLA0KICAgICAgICAgIHBhcmFsbGVsPSJtdWx0aWNvcmUiLA0KICAgICAgICAgIG5jcHVzID0gZGV0ZWN0Q29yZXMoKQ0KICAgICAgICAgICkNCg0Kc3VtbWFyeShtMCkNCg0KDQoNCmBgYA0KDQoqKk3DtCBow6xuaCDEkcahbiBiaeG6v24qKg0KDQpgYGB7cn0NCm0xPWdhbWxzcyhkYXRhPWNpZ2FyZXR0ZSwNCiAgICAgICAgICBmb3JtdWxhPXNhbGVzfnByaWNlLA0KICAgICAgICAgIGZhbWlseT1TVDQsDQogICAgICAgICAgdHJhY2U9RiwNCiAgICAgICAgICBwYXJhbGxlbD0ibXVsdGljb3JlIiwNCiAgICAgICAgICBuY3B1cyA9IGRldGVjdENvcmVzKCkNCikNCg0Kc3VtbWFyeShtMSkNCg0KYGBgDQoNCioqTcO0IGjDrG5oIDIgYmnhur9uIHTGsMahbmcgdMOhYyoqDQoNCmBgYHtyfQ0KbTI9Z2FtbHNzKGRhdGE9Y2lnYXJldHRlLA0KICAgICAgICAgIGZvcm11bGE9c2FsZXN+cHJpY2UqbmRpLA0KICAgICAgICAgIGZhbWlseT1TVDQsDQogICAgICAgICAgdHJhY2U9RiwNCiAgICAgICAgICBwYXJhbGxlbD0ibXVsdGljb3JlIiwNCiAgICAgICAgICBuY3B1cyA9IGRldGVjdENvcmVzKCkNCikNCg0Kc3VtbWFyeShtMikNCg0KDQpgYGANCg0KKipBTk9WQSB24bubaSBZZWFyIGzDoCBmaXhlZCBmYWN0b3IqKg0KDQpgYGB7cn0NCm0zPWdhbWxzcyhkYXRhPWNpZ2FyZXR0ZSwNCiAgICAgICAgICBmb3JtdWxhPXNhbGVzfnllYXIsDQogICAgICAgICAgZmFtaWx5PVNUNCwNCiAgICAgICAgICB0cmFjZT1GLA0KICAgICAgICAgIHBhcmFsbGVsPSJtdWx0aWNvcmUiLA0KICAgICAgICAgIG5jcHVzID0gZGV0ZWN0Q29yZXMoKQ0KKQ0KDQpzdW1tYXJ5KG0zKQ0KYGBgDQoNCioqTcO0IGjDrG5oIHTGsMahbmcgdMOhYyAzIGJp4bq/bioqDQoNCmBgYHtyfQ0KbTQ9Z2FtbHNzKGRhdGE9Y2lnYXJldHRlLA0KICAgICAgICAgIGZvcm11bGE9c2FsZXN+cHJpY2UqbmRpKnBvcDE2LA0KICAgICAgICAgIGZhbWlseT1TVDQsDQogICAgICAgICAgdHJhY2U9RiwNCiAgICAgICAgICBwYXJhbGxlbD0ibXVsdGljb3JlIiwNCiAgICAgICAgICBuY3B1cyA9IGRldGVjdENvcmVzKCkNCikNCg0Kc3VtbWFyeShtNCkNCg0KYGBgDQoNCioqTcO0IGjDrG5oIGPDsyBj4bqjIGJp4bq/biBsacOqbiB04bulYyB2w6AgeeG6v3UgdOG7kSA9IEFOQ09WQSoqDQoNCmBgYHtyfQ0KbTU9Z2FtbHNzKGRhdGE9Y2lnYXJldHRlLA0KICAgICAgICAgIGZvcm11bGE9c2FsZXN+cHJpY2UreWVhciwNCiAgICAgICAgICBmYW1pbHk9U1Q0LA0KICAgICAgICAgIHRyYWNlPUYsDQogICAgICAgICAgcGFyYWxsZWw9Im11bHRpY29yZSIsDQogICAgICAgICAgbmNwdXMgPSBkZXRlY3RDb3JlcygpDQopDQoNCnN1bW1hcnkobTUpDQoNCmBgYA0KDQoNCg0KIyBL4bq/dCBsdeG6rW4NCg0KxJDDonkgbMOgIDEgYsOgaSBy4bqldCBuZ+G6r24gdsOgIG7hu5lpIGR1bmcgY+G7p2EgbsOzIGtow7RuZyBjw7MgZ8OsIG3hu5tpIGzhuqEgxJHhu5FpIHbhu5tpIGPDoWMgYuG6oW4gxJHDoyBxdWVuIHPhu60gZOG7pW5nIFIuIENow7puZyB0YSBz4bq9IGThu6tuZyBs4bqhaSDhu58gxJHDonkuIFRo4buxYyByYSBjw7RuZyBk4bulbmcgY2jDrW5oIGPhu6dhIEdhbWxzcyBsw6AgY2hvIG3DtCBow6xuaCB0acOqbiBsxrDhu6NuZyBjaOG7qSBy4bqldCBoaeG6v20ga2hpIG7DsyDEkcaw4bujYyBz4butIGThu6VuZyB24bubaSBt4bulYyDEkcOtY2ggZGnhu4VuIGThu4tjaCwgdsOgIG91dHB1dCBnYW1sc3Mga2jDtG5nIHTGsMahbmcgdGjDrWNoIHbhu5tpIHThuqV0IGPhuqMgaMOgbSBwaMOibiB0w61jaCBBTk9WQSBtw6AgdGEgdOG7q25nIGJp4bq/dCBuw6puIMSR4buDIGzDoG0gxJHGsOG7o2Mgc3V5IGRp4buFbiB0aOG7kW5nIGvDqiwgaG/hurdjIGzDoCB0YSBwaOG6o2kgdOG7sSB2aeG6v3QgaMOgbSDEkeG7gyB0w61uaCBGIHN0YXRpc3RpY3MgdsOgIGzDoG0gQU5PVkEsIHBvc3QtaG9jIHRlc3QgbeG7mXQgY8OhY2ggdGjhu6cgY8O0bmcsIGhv4bq3YyBsw6AgdGEgcGjhuqNpIHN1eSBkaeG7hW4gdGjhu5FuZyBrw6ogZOG7sWEgdsOgbyBtYXJnaW5hbCBlZmZlY3QgduG7m2kgYm9vdHN0cmFwIChjxaluZyB0aOG7pyBjw7RuZyBsdcO0bikuIFRow7RuZyDEkWnhu4dwIGNow61uaCBj4bunYSBiw6BpIMSRw7MgbMOgIGPDuiBwaMOhcCBjaG8gcGjhuqduIHR1eeG6v24gdMOtbmggdHJvbmcgZ2FtbHNzIGhvw6BuIHRvw6BuIGdp4buRbmcgbmjGsCBj4bunYSBow6BtIGdsbSgpIGhv4bq3YyBsbSgpIHbDoCBuaGnhu4F1IHBhY2thZ2UgaOG7k2kgcXV5IGtow6FjLiBCw6BpIG7DoHkgY2jhu4kgbMOgIGto4bufaSDEkeG7mW5nIGNobyBuaOG7r25nIHRow6BuaCBwaOG6p24gcGjhu6ljIHThuqFwIGjGoW4gbcOgIE5oaSBz4bq9IMSR4buBIGPhuq1wIHRyb25nIGzhuqduIHThu5tpLCBiYW8gZ+G7k20gxJFhIHRo4bupYyBi4bqtYyBjYW8gdsOgIHNtb290aGluZyBzcGxpbmVzLg0KDQoqKlhpbiBj4bqjbSDGoW4gdsOgIGjhurluIGfhurdwIGzhuqFpLioqDQo=