NHIỆM VỤ TUẦN 1

Nhiệm vụ 1. Tóm tắt cuốn sách: 2019_Generalized Linear Models With Examples in R

Nhiệm vụ 2. Thực hiện thống kê mô tả cho các biến trong file: Supermarket Transactions

1. Tóm tắt sách

Chương 1: Statistical Models

  • Giới thiệu mô hình thống kê bao gồm các khái niệm cơ bản như biến phản hồi response, biến giải thích explanatory, thành phần hệ thống systematic component và thành phần ngẫu nhiên random component.

  • Nhấn mạnh sự cần thiết của việc mô tả dữ liệu bằng biểu đồbiến đổi dữ liệu định tính thành định lượng để đưa vào mô hình.

  • Giới thiệu cách phân biệt mô hình vật lýmô hình thống kê, cũng như tiêu chí đánh giá một mô hình tốt là:

    • Tính chính xác (accuracy)

    • Tính đơn giản (parsimony)

  • Kết luận bằng việc nhấn mạnh rằng mọi mô hình đều có tính gần đúng, không hoàn hảo, nhưng một số mô hình vẫn hữu ích nếu sử dụng đúng cách.


Chương 2: Linear Regression Models

  • Trình bày mô hình hồi quy tuyến tính tổng quát:

\[ y_i = \beta_0 + \beta_1 x_{1i} + \cdots + \beta_p x_{pi} + \varepsilon_i \\ \text{với giả định: } \varepsilon_i \sim \mathcal{N}(0, \sigma^2) \]

  • Phân biệt:

    • Simple Linear Regression (một biến giải thích)

    • Multiple Regression (nhiều biến giải thích)

  • Giới thiệu cách ước lượng hệ số hồi quy bằng phương pháp bình phương tối thiểu OLS.

  • Phân tích phương sai và kiểm định ý nghĩa mô hình.

  • So sánh mô hình lồng ghép nestedkhông lồng ghép non-nested.

  • Cách sử dụng R để xây dựng mô hình hồi quy tuyến tính thông qua hàm lm().


Chương 3: Exponential Family and GLMs

  • Trình bày họ phân phối hàm mũ (exponential family):

\[ f(y; \theta, \phi) = \exp \left( \frac{y \theta - b(\theta)}{a(\phi)} + c(y, \phi) \right) \]

  • Giới thiệu khung lý thuyết tổng quát của GLMs (Generalized Linear Models) gồm 3 thành phần:

    1. Phân phối xác suất (Exponential Family)

    2. Hàm liên kết (Link Function): liên kết kỳ vọng 𝐸(𝑦) với thành phần hệ thống.

    3. Thành phần hệ thống (Systematic Component): biểu diễn mối quan hệ tuyến tính giữa biến độc lập và kỳ vọng của biến phản hồi.

  • Trình bày các ví dụ điển hình:

    • Hồi quy logistic (phân phối nhị phân)

    • Hồi quy Poisson (dữ liệu đếm)

    • Hồi quy Gamma (dữ liệu liên tục, dương)


Chương 4: Beyond Linear Regression – Maximum Likelihood

  • Giới thiệu hạn chế của OLS: không phù hợp khi dữ liệu không tuân theo giả định phân phối chuẩn, hoặc phương sai không đồng nhất.

  • Trình bày phương pháp ước lượng hợp lý tối đa (Maximum Likelihood Estimation – MLE):

    • Lập công thức hàm hợp lý

    • Tính đạo hàm và tìm cực trị

    • Áp dụng Fisher scoring hoặc Newton-Raphson

  • Phân tích chi tiết các trường hợp:

    • Dữ liệu tỉ lệ (0 ≤ y ≤ 1)

    • Dữ liệu đếm (y = 0, 1, 2, …)

    • Dữ liệu dương liên tục (y > 0)

  • Trình bày 3 phương pháp suy luận từ MLE:

    • Kiểm định Wald

    • Kiểm định tỉ số hợp lý (Likelihood Ratio)

    • Kiểm định điểm (Score Test)

  • Sử dụng chỉ số AIC và BIC để chọn mô hình tối ưu


Chương 5: Extended Generalized Linear Models

  • Giới thiệu các mô hình phân tán hàm mũ mở rộng Extended Exponential Dispersion Models – EDMs giúp linh hoạt hơn so với GLM cổ điển.

  • Bao gồm các phân phối: quasi-likelihood, negative binomial, Tweedie,…

  • Tập trung vào mô hình hóa phương sai: thay vì giả định phương sai cố định như GLM chuẩn, các mô hình mở rộng cho phép phương sai phụ thuộc vào giá trị trung bình.

  • Sử dụng quasi-likelihood để mô hình hóa mà không cần chỉ rõ đầy đủ phân phối.

  • Định nghĩa và minh họa các hàm power variance function, cho phép mô tả phương sai dưới dạng:

\[ \mathrm{Var}(Y) = \phi \cdot \mu^p \]

  • Cung cấp cách tiếp cận cho dữ liệu có phương sai lớn hoặc nhỏ bất thường (overdispersion hoặc underdispersion).

Chương 6: GLM – Estimation

  • Mở rộng phương pháp ước lượng MLE từ chương 4 để áp dụng vào GLM.

  • Trình bày thuật toán IRLS (Iteratively Reweighted Least Squares) để tìm ước lượng tối đa khả năng dựa vào score equations và Fisher scoring

  • Phân tích deviance như một phép đo thay thế cho RSS để đánh giá độ phù hợp mô hình.

  • Phát triển các công thức ma trận để tính hệ số và sai số chuẩn.

  • Đưa ra kỹ thuật ước lượng tham số phân tán φ trong các mô hình có phương sai thay đổi.

  • Cách sử dụng R để fitting GLM với hàm glm() và điều chỉnh thông số với glm.control()


Chương 7: GLM – Inference

  • Áp dụng các kiểm định từ chương 4 vào ngữ cảnh GLM:

    • Wald test

    • Likelihood Ratio Test (LRT)

    • Score test

  • Giới thiệu suy luận khi:

    • Biết trước φ

    • Không biết φ (phải ước lượng)

  • Xây dựng các kiểm định goodness-of-fit dựa trên deviance và thống kê Pearson.

  • Trình bày kết quả tiệm cận với số lượng mẫu lớn.

  • Thảo luận cách so sánh mô hình không lồng ghép (non-nested) và các phương pháp chọn mô hình tự động như AIC/BIC.

  • Minh họa bằng R cho từng loại kiểm định.


Chương 8: GLM – Diagnostics

  • Tập trung vào đánh giá giả định của mô hình sau khi đã fitting:

    • Residual analysis với 3 loại: Pearson residual - Deviance residual - Quantile residual

    • Leverage (tác động của từng quan sát lên mô hình)

    • Cook’s distance để phát hiện điểm ảnh hưởng lớn.

  • Trình bày cách xử lý:

    • Mô hình không hội tụ

    • Dữ liệu dị thường

    • Sai mô hình hóa liên kết (link function)

  • Hướng dẫn sử dụng các biểu đồ chẩn đoán trong R để phát hiện sai lệch.


Chương 9: Mô hình Binomial – Hồi quy Logistic

  • Tập trung vào binomial GLM, cụ thể là hồi quy logistic.

  • Dữ liệu phù hợp: biến phản hồi là tỉ lệ, nhị phân (success/failure).

  • Trình bày các hàm liên kết cho binomial:

    • Logit (thường dùng nhất)

    • Probit

    • Complementary log-log (cloglog)

  • Giải thích cách mô hình hóa xác suất thành hàm logit:

\[ \log\left(\frac{p}{1 - p}\right) = \beta_0 + \beta_1 x_1 + \cdots \]

  • Diễn giải hệ số dưới dạng tỷ số odds (odds ratio).

  • Giới thiệu ứng dụng thực tế như:

    • Ước lượng liều gây hiệu ứng 50% (ED50)

    • Phân tích hiệu ứng của biến độc lập lên khả năng thành công

  • Đề cập đến vấn đề overdispersion trong hồi quy nhị phân và cách xử lý.


Chương 10: Mô hình Dữ liệu Đếm – Poisson và Negative Binomial GLMs

  • Mô hình hóa các biến phản hồi là số đếm (count data), ví dụ: số ca bệnh, số sự kiện.

  • Phân phối Poisson là nền tảng:

\[ P(y; \mu) = \frac{e^{-\mu} \mu^y}{y!} \]

  • Poisson regression dùng hàm liên kết log:

\[ \log(\mu_i) = X_i^T \beta \]

  • Áp dụng cho các trường hợp:

    • Dữ liệu đếm thuần túy

    • Tỷ lệ (rates): dùng offset log(exposure)

    • Dữ liệu bảng chéo (contingency tables)

  • Overdispersion: khi phương sai > trung bình → dùng quasi-Poisson hoặc Negative Binomial GLM.

  • So sánh AIC, kiểm định dispersion để chọn mô hình phù hợp


Chương 11: Hồi quy Logistic Ordinal và Multinomial

  • Mô hình hóa dữ liệu phân loại có > 2 mức:

    • Multinomial Logistic Regression: với biến phản hồi phân loại không thứ tự.

    • Ordinal Logistic Regression: khi các mức có thứ tự (ví dụ: yếu – trung bình – tốt).

  • Logit đa thức (multinomial logit):

\[ \log\left(\frac{P(Y = j)}{P(Y = J)}\right) = X^T \beta_j \]

  • Proportional odds model cho dữ liệu ordinal:

\[ \log\left(\frac{P(Y \le j)}{P(Y > j)}\right) = X^T \beta \]

  • Thảo luận về giả định proportionality và cách kiểm định.

  • R code sử dụng hàm multinom() từ gói nnet và polr() từ MASS.


Chương 12: Generalized Additive Models (GAMs)

  • Mở rộng GLM để mô hình hóa quan hệ phi tuyến giữa biến phản hồi và biến giải thích.

  • Công thức GAM:

\[ g(\mu_i) = \beta_0 + f_1(x_{1i}) + f_2(x_{2i}) + \cdots \]

  • Dùng các công cụ như:

    • gam() trong gói mgcv

    • s() để chỉ định spline trong công thức mô hình

  • GAM cho phép linh hoạt nhưng cần đánh đổi với việc kiểm soát độ phức tạp (overfitting).


Chương 13: Extra Problems Bài tập mở rộng

  • Chương cuối cùng là phần luyện tập mở rộng

  • Các bài toán yêu cầu kết hợp mọi kiến thức từ trước để giải quyết tình huống thực tế.


2. Thống kê mô tả dữ liệu

2.1 Đọc file CSV

  • Supermarket Transactions là file csv, nên ta đọc từ file csv

  • Thao tác thực hiện : Ta gán bộ dữ liệu Supermarket Transactions với tên là data

library(csv)
data <- read.csv("D:/UFM/2025- Kì 2/Phân tích dữ liệu định tính - Trần Mạnh Tường/Supermarket Transactions.csv", header = T)

2.2 Tổng quan bộ dữ liệu

2.2.1 Nội dung bộ dữ liệu

  • Bộ dữ liệu Supermarket Transactions ghi lại các giao dịch mua hàng tại một hệ thống siêu thị, kèm theo thông tin khách hàng, địa lý, và chi tiết sản phẩm.

  • Nó có thể dùng để phân tích hành vi mua sắm, phân khúc khách hàng, hoặc hiệu suất kinh doanh theo sản phẩm, khu vực, nhân khẩu học.

2.2.2 Danh sách các biến và mô tả

Tên của các biến trong bộ dữ liệu sẽ bao gồm:

names(data)
##  [1] "X"                 "PurchaseDate"      "CustomerID"       
##  [4] "Gender"            "MaritalStatus"     "Homeowner"        
##  [7] "Children"          "AnnualIncome"      "City"             
## [10] "StateorProvince"   "Country"           "ProductFamily"    
## [13] "ProductDepartment" "ProductCategory"   "UnitsSold"        
## [16] "Revenue"

Cụ thể từng các biến và quan sát có ý nghĩa như sau:

library(knitr)

# Tạo bảng mô tả các biến
variable_description <- data.frame(
  Variable = c(
    "Unnamed: 0",
    "PurchaseDate",
    "CustomerID",
    "Gender",
    "MaritalStatus",
    "Homeowner",
    "Children",
    "AnnualIncome",
    "City",
    "StateorProvince",
    "Country",
    "ProductFamily",
    "ProductDepartment",
    "ProductCategory",
    "UnitsSold",
    "Revenue"
  ),
  Description = c(
    "Mã dòng (có thể bỏ qua)",
    "Ngày mua hàng",
    "ID khách hàng",
    "Giới tính (F: nữ, M: nam)",
    "Tình trạng hôn nhân (S: độc thân, M: đã kết hôn)",
    "Sở hữu nhà (Y: có, N: không)",
    "Số con trong gia đình",
    "Thu nhập hàng năm (theo nhóm)",
    "Thành phố sinh sống",
    "Bang / tỉnh",
    "Quốc gia",
    "Nhóm sản phẩm chính (Food, Drink, ...)",
    "Phòng ban sản phẩm (Snacks, Produce, ...)",
    "Danh mục sản phẩm cụ thể",
    "Số lượng sản phẩm đã bán",
    "Doanh thu từ giao dịch (USD)"
  )
)

# Hiển thị bảng
kable(variable_description, col.names = c("Biến", "Mô tả"))
Biến Mô tả
Unnamed: 0 Mã dòng (có thể bỏ qua)
PurchaseDate Ngày mua hàng
CustomerID ID khách hàng
Gender Giới tính (F: nữ, M: nam)
MaritalStatus Tình trạng hôn nhân (S: độc thân, M: đã kết hôn)
Homeowner Sở hữu nhà (Y: có, N: không)
Children Số con trong gia đình
AnnualIncome Thu nhập hàng năm (theo nhóm)
City Thành phố sinh sống
StateorProvince Bang / tỉnh
Country Quốc gia
ProductFamily Nhóm sản phẩm chính (Food, Drink, …)
ProductDepartment Phòng ban sản phẩm (Snacks, Produce, …)
ProductCategory Danh mục sản phẩm cụ thể
UnitsSold Số lượng sản phẩm đã bán
Revenue Doanh thu từ giao dịch (USD)

Ta có thể lấy ví dụ từ quan sát đầu tiên: Vào ngày 18/12/2007, khách hàng ID 7223 (nữ, độc thân, có nhà, 2 con, thu nhập $30K–$50K) ở Los Angeles, bang CA Hoa Kỳ mua 5 đơn vị sản phẩm “Snack Foods” thuộc nhóm “Food”, tạo ra doanh thu $27.38 cho siêu thị


2.3 Thống kê mô tả cho các biến

2.3.1 Số biến và số quan sát

  • Bộ dữ liệu data bao gồm 14059 quan sát và 16 biến

  • 14059 quan sát, tương ứng với 14.059 giao dịch mua hàng tại siêu thị. Mỗi quan sát đại diện cho một lần mua hàng, kèm theo 16 yếu tố mô tả đã nói trên

dim(data)
## [1] 14059    16

2.3.2 Kiểm tra cấu trúc tổng quát

Ta có thể kiểm tra cấu trúc tổng quát của dữ liệu như sau:

str(data)
## 'data.frame':    14059 obs. of  16 variables:
##  $ X                : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ PurchaseDate     : chr  "2007-12-18" "2007-12-20" "2007-12-21" "2007-12-21" ...
##  $ CustomerID       : int  7223 7841 8374 9619 1900 6696 9673 354 1293 7938 ...
##  $ Gender           : chr  "F" "M" "F" "M" ...
##  $ MaritalStatus    : chr  "S" "M" "M" "M" ...
##  $ Homeowner        : chr  "Y" "Y" "N" "Y" ...
##  $ Children         : int  2 5 2 3 3 3 2 2 3 1 ...
##  $ AnnualIncome     : chr  "$30K - $50K" "$70K - $90K" "$50K - $70K" "$30K - $50K" ...
##  $ City             : chr  "Los Angeles" "Los Angeles" "Bremerton" "Portland" ...
##  $ StateorProvince  : chr  "CA" "CA" "WA" "OR" ...
##  $ Country          : chr  "USA" "USA" "USA" "USA" ...
##  $ ProductFamily    : chr  "Food" "Food" "Food" "Food" ...
##  $ ProductDepartment: chr  "Snack Foods" "Produce" "Snack Foods" "Snacks" ...
##  $ ProductCategory  : chr  "Snack Foods" "Vegetables" "Snack Foods" "Candy" ...
##  $ UnitsSold        : int  5 5 3 4 4 3 4 6 1 2 ...
##  $ Revenue          : num  27.38 14.9 5.52 4.44 14 ...

2.3.3 Thống kê mô tả cho các biến phân loại

Vì bộ dữ liệu có cả dữ liệu định tính như dạng thông tin định danh hoặc phân loại khách hàng, các dữ liệu này không dùng để tính toán trực tiếp như biến định lượng (doanh thu, số lượng,…). Nên khi thống kê mô tả ta cần phân biệt rõ hai nhóm biến

  • Thống kê cho từng biến định tính - Gender

    • Gender đại diện cho giới tính của khách hàng, F - Female là nữ và M - Male là nam

    • Dựa theo kết quả, trong 14059 khách hàng thì có 7170 khách hàng là nữ và 6889 khách hàng là nam

table(data$Gender)
## 
##    F    M 
## 7170 6889
  • Thống kê cho từng biến định tính - MaritalStatus

    • MaritalStatus đại diện cho tình trạng hôn nhân

    • Kết quả cho thấy có 6866 khách hàng đã kết hôn (M - Married) và 7193 khách hàng là độc thân (S - Single)

    • Những kết quả này cũng có thể ảnh hưởng đến sức mua hàng, chẳng hạn như người đã kết hôn sẽ có nhu cầu mua hàng nhiều hơn người độc thân.

table(data$MaritalStatus)
## 
##    M    S 
## 6866 7193
  • Tổng hợp thống kê mô tả cho từng biến địng tính

    • 2 kết quả của 2 biến phân loại trên chỉ là để ví dụ nếu ta muốn nhìn thấy kết quả riêng của từng biến

    • Ta có thể tổng hợp kết quả như dưới đây:

# Danh sách các biến phân loại categorical
cat_vars <- c("Gender", "MaritalStatus", "Homeowner", "AnnualIncome",
              "City", "StateorProvince", "Country", 
              "ProductFamily", "ProductDepartment", "ProductCategory")

# Lặp qua từng biến để thống kê
for (var in cat_vars) {
  cat("\n----------------------------------------\n")
  cat("Biến:", var, "\n")
  cat("----------------------------------------\n")
  freq_table <- table(data[[var]])
  percent_table <- prop.table(freq_table) * 100
  print(data.frame(Tần_suất = freq_table, Tỷ_lệ_phần_trăm = round(percent_table, 2)))
}
## 
## ----------------------------------------
## Biến: Gender 
## ----------------------------------------
##   Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1             F          7170                    F                   51
## 2             M          6889                    M                   49
## 
## ----------------------------------------
## Biến: MaritalStatus 
## ----------------------------------------
##   Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1             M          6866                    M                48.84
## 2             S          7193                    S                51.16
## 
## ----------------------------------------
## Biến: Homeowner 
## ----------------------------------------
##   Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1             N          5615                    N                39.94
## 2             Y          8444                    Y                60.06
## 
## ----------------------------------------
## Biến: AnnualIncome 
## ----------------------------------------
##   Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1   $10K - $30K          3090          $10K - $30K                21.98
## 2 $110K - $130K           643        $110K - $130K                 4.57
## 3 $130K - $150K           760        $130K - $150K                 5.41
## 4       $150K +           273              $150K +                 1.94
## 5   $30K - $50K          4601          $30K - $50K                32.73
## 6   $50K - $70K          2370          $50K - $70K                16.86
## 7   $70K - $90K          1709          $70K - $90K                12.16
## 8  $90K - $110K           613         $90K - $110K                 4.36
## 
## ----------------------------------------
## Biến: City 
## ----------------------------------------
##    Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1       Acapulco           383             Acapulco                 2.72
## 2     Bellingham           143           Bellingham                 1.02
## 3  Beverly Hills           811        Beverly Hills                 5.77
## 4      Bremerton           834            Bremerton                 5.93
## 5        Camacho           452              Camacho                 3.22
## 6    Guadalajara            75          Guadalajara                 0.53
## 7        Hidalgo           845              Hidalgo                 6.01
## 8    Los Angeles           926          Los Angeles                 6.59
## 9         Merida           654               Merida                 4.65
## 10   Mexico City           194          Mexico City                 1.38
## 11       Orizaba           464              Orizaba                 3.30
## 12      Portland           876             Portland                 6.23
## 13         Salem          1386                Salem                 9.86
## 14    San Andres           621           San Andres                 4.42
## 15     San Diego           866            San Diego                 6.16
## 16 San Francisco           130        San Francisco                 0.92
## 17       Seattle           922              Seattle                 6.56
## 18       Spokane           875              Spokane                 6.22
## 19        Tacoma          1257               Tacoma                 8.94
## 20     Vancouver           633            Vancouver                 4.50
## 21      Victoria           176             Victoria                 1.25
## 22   Walla Walla           160          Walla Walla                 1.14
## 23        Yakima           376               Yakima                 2.67
## 
## ----------------------------------------
## Biến: StateorProvince 
## ----------------------------------------
##    Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1             BC           809                   BC                 5.75
## 2             CA          2733                   CA                19.44
## 3             DF           815                   DF                 5.80
## 4       Guerrero           383             Guerrero                 2.72
## 5        Jalisco            75              Jalisco                 0.53
## 6             OR          2262                   OR                16.09
## 7       Veracruz           464             Veracruz                 3.30
## 8             WA          4567                   WA                32.48
## 9        Yucatan           654              Yucatan                 4.65
## 10     Zacatecas          1297            Zacatecas                 9.23
## 
## ----------------------------------------
## Biến: Country 
## ----------------------------------------
##   Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1        Canada           809               Canada                 5.75
## 2        Mexico          3688               Mexico                26.23
## 3           USA          9562                  USA                68.01
## 
## ----------------------------------------
## Biến: ProductFamily 
## ----------------------------------------
##    Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1          Drink          1250                Drink                 8.89
## 2           Food         10153                 Food                72.22
## 3 Non-Consumable          2656       Non-Consumable                18.89
## 
## ----------------------------------------
## Biến: ProductDepartment 
## ----------------------------------------
##          Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1  Alcoholic Beverages           356  Alcoholic Beverages                 2.53
## 2          Baked Goods           425          Baked Goods                 3.02
## 3         Baking Goods          1072         Baking Goods                 7.63
## 4            Beverages           680            Beverages                 4.84
## 5      Breakfast Foods           188      Breakfast Foods                 1.34
## 6         Canned Foods           977         Canned Foods                 6.95
## 7      Canned Products           109      Canned Products                 0.78
## 8             Carousel            59             Carousel                 0.42
## 9             Checkout            82             Checkout                 0.58
## 10               Dairy           903                Dairy                 6.42
## 11                Deli           699                 Deli                 4.97
## 12                Eggs           198                 Eggs                 1.41
## 13        Frozen Foods          1382         Frozen Foods                 9.83
## 14  Health and Hygiene           893   Health and Hygiene                 6.35
## 15           Household          1420            Household                10.10
## 16                Meat            89                 Meat                 0.63
## 17         Periodicals           202          Periodicals                 1.44
## 18             Produce          1994              Produce                14.18
## 19             Seafood           102              Seafood                 0.73
## 20         Snack Foods          1600          Snack Foods                11.38
## 21              Snacks           352               Snacks                 2.50
## 22       Starchy Foods           277        Starchy Foods                 1.97
## 
## ----------------------------------------
## Biến: ProductCategory 
## ----------------------------------------
##           Tần_suất.Var1 Tần_suất.Freq Tỷ_lệ_phần_trăm.Var1 Tỷ_lệ_phần_trăm.Freq
## 1          Baking Goods           484         Baking Goods                 3.44
## 2     Bathroom Products           365    Bathroom Products                 2.60
## 3         Beer and Wine           356        Beer and Wine                 2.53
## 4                 Bread           425                Bread                 3.02
## 5       Breakfast Foods           417      Breakfast Foods                 2.97
## 6               Candles            45              Candles                 0.32
## 7                 Candy           352                Candy                 2.50
## 8      Canned Anchovies            44     Canned Anchovies                 0.31
## 9          Canned Clams            53         Canned Clams                 0.38
## 10       Canned Oysters            35       Canned Oysters                 0.25
## 11      Canned Sardines            40      Canned Sardines                 0.28
## 12        Canned Shrimp            38        Canned Shrimp                 0.27
## 13          Canned Soup           404          Canned Soup                 2.87
## 14          Canned Tuna            87          Canned Tuna                 0.62
## 15 Carbonated Beverages           154 Carbonated Beverages                 1.10
## 16    Cleaning Supplies           189    Cleaning Supplies                 1.34
## 17        Cold Remedies            93        Cold Remedies                 0.66
## 18                Dairy           903                Dairy                 6.42
## 19        Decongestants            85        Decongestants                 0.60
## 20               Drinks           135               Drinks                 0.96
## 21                 Eggs           198                 Eggs                 1.41
## 22           Electrical           355           Electrical                 2.53
## 23      Frozen Desserts           323      Frozen Desserts                 2.30
## 24       Frozen Entrees           118       Frozen Entrees                 0.84
## 25                Fruit           765                Fruit                 5.44
## 26             Hardware           129             Hardware                 0.92
## 27        Hot Beverages           226        Hot Beverages                 1.61
## 28              Hygiene           197              Hygiene                 1.40
## 29     Jams and Jellies           588     Jams and Jellies                 4.18
## 30     Kitchen Products           217     Kitchen Products                 1.54
## 31            Magazines           202            Magazines                 1.44
## 32                 Meat           761                 Meat                 5.41
## 33        Miscellaneous            42        Miscellaneous                 0.30
## 34  Packaged Vegetables            48  Packaged Vegetables                 0.34
## 35       Pain Relievers           192       Pain Relievers                 1.37
## 36       Paper Products           345       Paper Products                 2.45
## 37                Pizza           194                Pizza                 1.38
## 38     Plastic Products           141     Plastic Products                 1.00
## 39 Pure Juice Beverages           165 Pure Juice Beverages                 1.17
## 40              Seafood           102              Seafood                 0.73
## 41          Side Dishes           153          Side Dishes                 1.09
## 42          Snack Foods          1600          Snack Foods                11.38
## 43            Specialty           289            Specialty                 2.06
## 44        Starchy Foods           277        Starchy Foods                 1.97
## 45           Vegetables          1728           Vegetables                12.29

2.3.4 Thống kê mô tả cho các biến định lượng

Sau khi đã thống kê các biến phân loại, ta sẽ tiếp tục tiến hành với các biến định lượng. Thông tin của các biến này mới là những con số để có thể tính toán những giá trị như: trung bình, trung vị, giá trị lớn nhất nhỏ nhất,…

Trong bộ dữ liệu chỉ có biến UnitsSold (Số lượng sản phẩm đã bán)Revenue (Doanh thu) là có thể tính ra các thông số

Thống kê cho biến UnitsSold - Số lượng sản phẩm đã bán

library(psych)
## Warning: package 'psych' was built under R version 4.3.3
describe(data$UnitsSold)  
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 14059 4.080589 1.174421 4 4.076985 1.4826 1 8 7 0.0124645 -0.4381643 0.0099048
  • Giá trị trung bình mean: 4.08

  • Độ lệch chuẩn sd: 1.17

  • Giá trị trung vị median: 4

  • Giá trị trung bình đã cắt trimmed mean: 4.08

  • Độ lệch tuyệt đối trung bình MAD: 1.48

  • Giá trị nhỏ nhất min: 1

  • Giá trị lớn nhất max: 8

  • Độ nhọn Kurtosis: -0.44

  • Sai số chuẩn của độ nhọn SE: 0.01

  • Nhận xét: Giá trị trung bình và trung vị cho thấy phân phối dữ liệu khá cân đối và đối xứng, trung bình cắt cũng xác nhận thêm rằng không có nhiều ngoại lệ lớn ảnh hưởng đến trung bình. Độ lệch chuẩn đạt và độ lệch tuyệt đối trung vị phản ánh mức độ biến động thấp quanh giá trị trung tâm. Giá trị nhỏ nhất là 1 và lớn nhất là 8, cho thấy dữ liệu nằm trong một khoảng hẹp, dễ quản lý và phân tích.


Thống kê cho biến Revenue - Doanh thu

describe(data$Revenue)  
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 14059 13.00451 8.215543 11.25 12.04553 7.398174 0.53 56.7 56.17 1.134659 1.390813 0.0692882
  • Giá trị trung bình mean: 13

  • Độ lệch chuẩn sd: 8.22

  • Giá trị trung vị median: 11.25

  • Giá trị trung bình đã cắt trimmed mean: 12.05

  • Độ lệch tuyệt đối trung bình MAD: 7.4

  • Giá trị nhỏ nhất min: 0.53

  • Giá trị lớn nhất max: 56.7

  • Độ nhọn Kurtosis: 1.39

  • Sai số chuẩn của độ nhọn SE: 0.07

  • Nhận xét: Biến Revenue với giá trị trung bình là 13 và độ lệch chuẩn đạt 8.22, cho thấy dữ liệu có mức độ phân tán khá lớn quanh trung bình. Trung vị của biến thấp hơn trung bình, cho thấy phân phối dữ liệu có thể lệch phải. Giá trị trung bình đã cắt thấp hơn nhẹ so với trung bình, phản ánh sự hiện diện của một số giá trị ngoại lệ lớn làm tăng giá trị trung bình gốc. Giá trị nhỏ nhất và lớn nhất có khoảng biến thiên khá rộng. Về đặc điểm phân phối, độ nhọn thấp hơn phân phối chuẩn. Sai số chuẩn của độ nhọn là 0.07, giúp xác nhận rằng độ nhọn này khác biệt có ý nghĩa thống kê so với phân phối chuẩn.

LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSB0deG6p24gMSBQVERMRFQiDQphdXRob3I6ICJWxakgUXXhu7NuaCBUcsO6YyBWeSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvYzogdHJ1ZQ0KICAgIGRmX3ByaW50OiBrYWJsZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCg0KIyAqKk5ISeG7hk0gVuG7pCBUVeG6pk4gMSoqDQoNCiAgICoqTmhp4buHbSB24bulIDEuKiogVMOzbSB04bqvdCBjdeG7kW4gc8OhY2g6IDIwMTlfR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVscyBXaXRoIEV4YW1wbGVzIGluIFINCiAgIA0KICAgKipOaGnhu4dtIHbhu6UgMi4qKiBUaOG7sWMgaGnhu4duIHRo4buRbmcga8OqIG3DtCB04bqjIGNobyBjw6FjIGJp4bq/biB0cm9uZyBmaWxlOiBTdXBlcm1hcmtldCBUcmFuc2FjdGlvbnMNCiAgIA0KIyMgKioxLiBUw7NtIHThuq90IHPDoWNoKioNCg0KIyMjICoqQ2jGsMahbmcgMTogU3RhdGlzdGljYWwgTW9kZWxzKioNCg0KLSAqKkdp4bubaSB0aGnhu4d1IG3DtCBow6xuaCB0aOG7kW5nIGvDqioqIGJhbyBn4buTbSBjw6FjIGtow6FpIG5p4buHbSBjxqEgYuG6o24gbmjGsCBiaeG6v24gcGjhuqNuIGjhu5NpIHJlc3BvbnNlLCBiaeG6v24gZ2nhuqNpIHRow61jaCBleHBsYW5hdG9yeSwgdGjDoG5oIHBo4bqnbiBo4buHIHRo4buRbmcgc3lzdGVtYXRpYyBjb21wb25lbnQgdsOgIHRow6BuaCBwaOG6p24gbmfhuqt1IG5oacOqbiByYW5kb20gY29tcG9uZW50Lg0KDQotIE5o4bqlbiBt4bqhbmggc+G7sSBj4bqnbiB0aGnhur90IGPhu6dhIHZp4buHYyAqKm3DtCB04bqjIGThu68gbGnhu4d1IGLhurFuZyBiaeG7g3UgxJHhu5MqKiB2w6AgKipiaeG6v24gxJHhu5VpIGThu68gbGnhu4d1IMSR4buLbmggdMOtbmggdGjDoG5oIMSR4buLbmggbMaw4bujbmcqKiDEkeG7gyDEkcawYSB2w6BvIG3DtCBow6xuaC4NCg0KLSBHaeG7m2kgdGhp4buHdSBjw6FjaCBwaMOibiBiaeG7h3QgKiptw7QgaMOsbmggduG6rXQgbMO9KiogdsOgICoqbcO0IGjDrG5oIHRo4buRbmcga8OqKiosIGPFqW5nIG5oxrAgdGnDqnUgY2jDrSDEkcOhbmggZ2nDoSBt4buZdCBtw7QgaMOsbmggdOG7kXQgbMOgOg0KDQogICAtIFTDrW5oIGNow61uaCB4w6FjIChhY2N1cmFjeSkNCg0KICAgLSBUw61uaCDEkcahbiBnaeG6o24gKHBhcnNpbW9ueSkNCg0KLSBL4bq/dCBsdeG6rW4gYuG6sW5nIHZp4buHYyBuaOG6pW4gbeG6oW5oIHLhurFuZyBt4buNaSAqKm3DtCBow6xuaCDEkeG7gXUgY8OzIHTDrW5oIGfhuqduIMSRw7puZyoqLCBraMO0bmcgaG/DoG4gaOG6o28sIG5oxrBuZyBt4buZdCBz4buRIG3DtCBow6xuaCB24bqrbiBo4buvdSDDrWNoIG7hur91IHPhu60gZOG7pW5nIMSRw7puZyBjw6FjaC4NCg0KLS0tDQoNCiMjIyAqKkNoxrDGoW5nIDI6IExpbmVhciBSZWdyZXNzaW9uIE1vZGVscyoqDQoNCi0gVHLDrG5oIGLDoHkgbcO0IGjDrG5oICoqaOG7k2kgcXV5IHR1eeG6v24gdMOtbmggdOG7lW5nIHF1w6F0Kio6DQoNCiQkDQp5X2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X3sxaX0gKyBcY2RvdHMgKyBcYmV0YV9wIHhfe3BpfSArIFx2YXJlcHNpbG9uX2kgXFwNClx0ZXh0e3bhu5tpIGdp4bqjIMSR4buLbmg6IH0gXHZhcmVwc2lsb25faSBcc2ltIFxtYXRoY2Fse059KDAsIFxzaWdtYV4yKQ0KJCQNCg0KLSBQaMOibiBiaeG7h3Q6DQoNCiAgIC0gU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uICht4buZdCBiaeG6v24gZ2nhuqNpIHRow61jaCkNCg0KICAgLSBNdWx0aXBsZSBSZWdyZXNzaW9uIChuaGnhu4F1IGJp4bq/biBnaeG6o2kgdGjDrWNoKQ0KDQotIEdp4bubaSB0aGnhu4d1ICoqY8OhY2ggxrDhu5tjIGzGsOG7o25nIGjhu4cgc+G7kSBo4buTaSBxdXkgYuG6sW5nIHBoxrDGoW5nIHBow6FwIGLDrG5oIHBoxrDGoW5nIHThu5FpIHRoaeG7g3UgT0xTLioqDQoNCi0gUGjDom4gdMOtY2ggKipwaMawxqFuZyBzYWkqKiB2w6Aga2nhu4NtIMSR4buLbmggKirDvSBuZ2jEqWEgbcO0IGjDrG5oKiouDQoNCi0gU28gc8OhbmggKiptw7QgaMOsbmggbOG7k25nIGdow6lwIG5lc3RlZCoqIHbDoCAqKmtow7RuZyBs4buTbmcgZ2jDqXAgbm9uLW5lc3RlZCoqLg0KDQotIEPDoWNoIHPhu60gZOG7pW5nIFIgxJHhu4MgeMOieSBk4buxbmcgbcO0IGjDrG5oIGjhu5NpIHF1eSB0dXnhur9uIHTDrW5oIHRow7RuZyBxdWEgKipow6BtIGxtKCkuKioNCg0KLS0tDQoNCiMjIyAqKkNoxrDGoW5nIDM6IEV4cG9uZW50aWFsIEZhbWlseSBhbmQgR0xNcyoqDQoNCi0gVHLDrG5oIGLDoHkgaOG7jSAqKnBow6JuIHBo4buRaSBow6BtIG3FqSoqIChleHBvbmVudGlhbCBmYW1pbHkpOg0KDQokJA0KZih5OyBcdGhldGEsIFxwaGkpID0gXGV4cCBcbGVmdCggXGZyYWN7eSBcdGhldGEgLSBiKFx0aGV0YSl9e2EoXHBoaSl9ICsgYyh5LCBccGhpKSBccmlnaHQpDQokJA0KDQotIEdp4bubaSB0aGnhu4d1ICoqa2h1bmcgbMO9IHRodXnhur90IHThu5VuZyBxdcOhdCBj4bunYSBHTE1zIChHZW5lcmFsaXplZCBMaW5lYXIgTW9kZWxzKSoqIGfhu5NtIDMgdGjDoG5oIHBo4bqnbjoNCg0KICAgKDEpIFBow6JuIHBo4buRaSB4w6FjIHN14bqldCAoRXhwb25lbnRpYWwgRmFtaWx5KQ0KDQogICAoMikgSMOgbSBsacOqbiBr4bq/dCAoTGluayBGdW5jdGlvbik6IGxpw6puIGvhur90IGvhu7MgduG7jW5nIPCdkLgo8J2RpikgduG7m2kgdGjDoG5oIHBo4bqnbiBo4buHIHRo4buRbmcuDQoNCiAgICgzKSBUaMOgbmggcGjhuqduIGjhu4cgdGjhu5FuZyAoU3lzdGVtYXRpYyBDb21wb25lbnQpOiBiaeG7g3UgZGnhu4VuIG3hu5FpIHF1YW4gaOG7hyB0dXnhur9uIHTDrW5oIGdp4buvYSBiaeG6v24gxJHhu5ljIGzhuq1wIHbDoCBr4buzIHbhu41uZyBj4bunYSBiaeG6v24gcGjhuqNuIGjhu5NpLg0KDQotIFRyw6xuaCBiw6B5ICoqY8OhYyB2w60gZOG7pSDEkWnhu4NuIGjDrG5oOioqDQoNCiAgIC0gSOG7k2kgcXV5IGxvZ2lzdGljIChwaMOibiBwaOG7kWkgbmjhu4sgcGjDom4pDQoNCiAgIC0gSOG7k2kgcXV5IFBvaXNzb24gKGThu68gbGnhu4d1IMSR4bq/bSkNCg0KICAgLSBI4buTaSBxdXkgR2FtbWEgKGThu68gbGnhu4d1IGxpw6puIHThu6VjLCBkxrDGoW5nKQ0KDQotLS0NCg0KIyMjICoqQ2jGsMahbmcgNDogQmV5b25kIExpbmVhciBSZWdyZXNzaW9uIOKAkyBNYXhpbXVtIExpa2VsaWhvb2QqKg0KDQotIEdp4bubaSB0aGnhu4d1ICoqaOG6oW4gY2jhur8gY+G7p2EgT0xTOioqIGtow7RuZyBwaMO5IGjhu6NwIGtoaSBk4buvIGxp4buHdSBraMO0bmcgdHXDom4gdGhlbyBnaeG6oyDEkeG7i25oIHBow6JuIHBo4buRaSBjaHXhuqluLCBob+G6t2MgcGjGsMahbmcgc2FpIGtow7RuZyDEkeG7k25nIG5o4bqldC4NCg0KLSBUcsOsbmggYsOgeSAqKnBoxrDGoW5nIHBow6FwIMaw4bubYyBsxrDhu6NuZyBo4bujcCBsw70gdOG7kWkgxJFhIChNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbiDigJMgTUxFKToqKg0KDQogICAtIEzhuq1wIGPDtG5nIHRo4bupYyBow6BtIGjhu6NwIGzDvQ0KDQogICAtIFTDrW5oIMSR4bqhbyBow6BtIHbDoCB0w6xtIGPhu7FjIHRy4buLDQoNCiAgIC0gw4FwIGThu6VuZyBGaXNoZXIgc2NvcmluZyBob+G6t2MgTmV3dG9uLVJhcGhzb24NCg0KLSAqKlBow6JuIHTDrWNoIGNoaSB0aeG6v3QgY8OhYyB0csaw4budbmcgaOG7o3A6KioNCg0KICAgLSBE4buvIGxp4buHdSB04buJIGzhu4cgKDAg4omkIHkg4omkIDEpDQoNCiAgIC0gROG7ryBsaeG7h3UgxJHhur9tICh5ID0gMCwgMSwgMiwgLi4uKQ0KDQogICAtIEThu68gbGnhu4d1IGTGsMahbmcgbGnDqm4gdOG7pWMgKHkgPiAwKQ0KDQotIFRyw6xuaCBiw6B5ICoqMyBwaMawxqFuZyBwaMOhcCBzdXkgbHXhuq1uIHThu6sgTUxFOioqDQoNCiAgIC0gS2nhu4NtIMSR4buLbmggV2FsZA0KDQogICAtIEtp4buDbSDEkeG7i25oIHThu4kgc+G7kSBo4bujcCBsw70gKExpa2VsaWhvb2QgUmF0aW8pDQoNCiAgIC0gS2nhu4NtIMSR4buLbmggxJFp4buDbSAoU2NvcmUgVGVzdCkNCg0KLSBT4butIGThu6VuZyAqKmNo4buJIHPhu5EgQUlDIHbDoCBCSUMqKiDEkeG7gyBjaOG7jW4gbcO0IGjDrG5oIHThu5FpIMawdQ0KDQotLS0NCg0KIyMjICoqQ2jGsMahbmcgNTogRXh0ZW5kZWQgR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVscyoqDQoNCi0gR2nhu5tpIHRoaeG7h3UgY8OhYyAqKm3DtCBow6xuaCBwaMOibiB0w6FuIGjDoG0gbcWpIG3hu58gcuG7mW5nIEV4dGVuZGVkIEV4cG9uZW50aWFsIERpc3BlcnNpb24gTW9kZWxzIOKAkyBFRE1zKiogZ2nDunAgbGluaCBob+G6oXQgaMahbiBzbyB24bubaSBHTE0gY+G7lSDEkWnhu4NuLg0KDQotIEJhbyBn4buTbSBjw6FjIHBow6JuIHBo4buRaTogcXVhc2ktbGlrZWxpaG9vZCwgbmVnYXRpdmUgYmlub21pYWwsIFR3ZWVkaWUsLi4uDQoNCi0gVOG6rXAgdHJ1bmcgdsOgbyAqKm3DtCBow6xuaCBow7NhIHBoxrDGoW5nIHNhaToqKiB0aGF5IHbDrCBnaeG6oyDEkeG7i25oIHBoxrDGoW5nIHNhaSBj4buRIMSR4buLbmggbmjGsCBHTE0gY2h14bqpbiwgY8OhYyBtw7QgaMOsbmggbeG7nyBy4buZbmcgY2hvIHBow6lwIHBoxrDGoW5nIHNhaSBwaOG7pSB0aHXhu5ljIHbDoG8gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaC4NCg0KLSBT4butIGThu6VuZyAqKnF1YXNpLWxpa2VsaWhvb2QqKiDEkeG7gyBtw7QgaMOsbmggaMOzYSBtw6Aga2jDtG5nIGPhuqduIGNo4buJIHLDtSDEkeG6p3kgxJHhu6cgcGjDom4gcGjhu5FpLg0KDQotIMSQ4buLbmggbmdoxKlhIHbDoCBtaW5oIGjhu41hIGPDoWMgKipow6BtIHBvd2VyIHZhcmlhbmNlIGZ1bmN0aW9uKiosIGNobyBwaMOpcCBtw7QgdOG6oyBwaMawxqFuZyBzYWkgZMaw4bubaSBk4bqhbmc6DQoNCiQkDQpcbWF0aHJte1Zhcn0oWSkgPSBccGhpIFxjZG90IFxtdV5wDQokJA0KDQotIEN1bmcgY+G6pXAgY8OhY2ggdGnhur9wIGPhuq1uIGNobyAqKmThu68gbGnhu4d1IGPDsyBwaMawxqFuZyBzYWkgbOG7m24gaG/hurdjIG5o4buPIGLhuqV0IHRoxrDhu51uZyoqIChvdmVyZGlzcGVyc2lvbiBob+G6t2MgdW5kZXJkaXNwZXJzaW9uKS4NCg0KLS0tDQoNCiMjIyAqKkNoxrDGoW5nIDY6IEdMTSDigJMgRXN0aW1hdGlvbioqDQoNCi0gTeG7nyBy4buZbmcgKipwaMawxqFuZyBwaMOhcCDGsOG7m2MgbMaw4bujbmcgTUxFKiogdOG7qyBjaMawxqFuZyA0IMSR4buDIMOhcCBk4bulbmcgdsOgbyBHTE0uDQoNCi0gVHLDrG5oIGLDoHkgKip0aHXhuq10IHRvw6FuIElSTFMqKiAoSXRlcmF0aXZlbHkgUmV3ZWlnaHRlZCBMZWFzdCBTcXVhcmVzKSDEkeG7gyB0w6xtIMaw4bubYyBsxrDhu6NuZyB04buRaSDEkWEga2jhuqMgbsSDbmcgZOG7sWEgdsOgbyBzY29yZSBlcXVhdGlvbnMgdsOgIEZpc2hlciBzY29yaW5nDQoNCi0gUGjDom4gdMOtY2ggZGV2aWFuY2UgbmjGsCBt4buZdCBwaMOpcCDEkW8gdGhheSB0aOG6vyBjaG8gUlNTIMSR4buDIMSRw6FuaCBnacOhIMSR4buZIHBow7kgaOG7o3AgbcO0IGjDrG5oLg0KDQotIFBow6F0IHRyaeG7g24gY8OhYyBjw7RuZyB0aOG7qWMgbWEgdHLhuq1uIMSR4buDIHTDrW5oIGjhu4cgc+G7kSB2w6Agc2FpIHPhu5EgY2h14bqpbi4NCg0KLSDEkMawYSByYSAqKmvhu7kgdGh14bqtdCDGsOG7m2MgbMaw4bujbmcgdGhhbSBz4buRIHBow6JuIHTDoW4gz4YqKiB0cm9uZyBjw6FjIG3DtCBow6xuaCBjw7MgcGjGsMahbmcgc2FpIHRoYXkgxJHhu5VpLg0KDQotIEPDoWNoIHPhu60gZOG7pW5nIFIgxJHhu4MgZml0dGluZyBHTE0gduG7m2kgKipow6BtIGdsbSgpKiogdsOgIMSRaeG7gXUgY2jhu4luaCB0aMO0bmcgc+G7kSB24bubaSAqKmdsbS5jb250cm9sKCkqKg0KDQotLS0NCg0KIyMjICoqQ2jGsMahbmcgNzogR0xNIOKAkyBJbmZlcmVuY2UqKg0KDQotIMOBcCBk4bulbmcgY8OhYyAqKmtp4buDbSDEkeG7i25oIHThu6sgY2jGsMahbmcgNCB2w6BvIG5n4buvIGPhuqNuaCBHTE06KioNCg0KICAgLSBXYWxkIHRlc3QNCg0KICAgLSBMaWtlbGlob29kIFJhdGlvIFRlc3QgKExSVCkNCg0KICAgLSBTY29yZSB0ZXN0DQoNCi0gKipHaeG7m2kgdGhp4buHdSBzdXkgbHXhuq1uKioga2hpOg0KDQogICAtIEJp4bq/dCB0csaw4bubYyDPhg0KDQogICAtIEtow7RuZyBiaeG6v3Qgz4YgKHBo4bqjaSDGsOG7m2MgbMaw4bujbmcpDQoNCi0gWMOieSBk4buxbmcgY8OhYyAqKmtp4buDbSDEkeG7i25oIGdvb2RuZXNzLW9mLWZpdCoqIGThu7FhIHRyw6puIGRldmlhbmNlIHbDoCB0aOG7kW5nIGvDqiBQZWFyc29uLg0KDQotIFRyw6xuaCBiw6B5ICoqa+G6v3QgcXXhuqMgdGnhu4dtIGPhuq1uIHbhu5tpIHPhu5EgbMaw4bujbmcgbeG6q3UgbOG7m24qKi4NCg0KLSBUaOG6o28gbHXhuq1uIGPDoWNoICoqc28gc8OhbmggbcO0IGjDrG5oIGtow7RuZyBs4buTbmcgZ2jDqXAgKG5vbi1uZXN0ZWQpIHbDoCBjw6FjIHBoxrDGoW5nIHBow6FwIGNo4buNbiBtw7QgaMOsbmggdOG7sSDEkeG7mW5nIG5oxrAgQUlDL0JJQyoqLg0KDQotIE1pbmggaOG7jWEgYuG6sW5nIFIgY2hvIHThu6tuZyBsb+G6oWkga2nhu4NtIMSR4buLbmguDQoNCi0tLQ0KDQojIyMgKipDaMawxqFuZyA4OiBHTE0g4oCTIERpYWdub3N0aWNzKioNCg0KLSBU4bqtcCB0cnVuZyB2w6BvICoqxJHDoW5oIGdpw6EgZ2nhuqMgxJHhu4tuaCoqIGPhu6dhIG3DtCBow6xuaCBzYXUga2hpIMSRw6MgZml0dGluZzoNCg0KICAgLSBSZXNpZHVhbCBhbmFseXNpcyB24bubaSAzIGxv4bqhaTogUGVhcnNvbiByZXNpZHVhbCAtIERldmlhbmNlIHJlc2lkdWFsIC0gUXVhbnRpbGUgcmVzaWR1YWwNCg0KICAgLSBMZXZlcmFnZSAodMOhYyDEkeG7mW5nIGPhu6dhIHThu6tuZyBxdWFuIHPDoXQgbMOqbiBtw7QgaMOsbmgpDQoNCiAgIC0gQ29vaydzIGRpc3RhbmNlIMSR4buDIHBow6F0IGhp4buHbiDEkWnhu4NtIOG6o25oIGjGsOG7n25nIGzhu5tuLg0KDQotICoqVHLDrG5oIGLDoHkgY8OhY2ggeOG7rSBsw706KioNCg0KICAgLSBNw7QgaMOsbmgga2jDtG5nIGjhu5lpIHThu6UNCg0KICAgLSBE4buvIGxp4buHdSBk4buLIHRoxrDhu51uZw0KDQogICAtIFNhaSBtw7QgaMOsbmggaMOzYSBsacOqbiBr4bq/dCAobGluayBmdW5jdGlvbikNCg0KLSBIxrDhu5tuZyBk4bqrbiAqKnPhu60gZOG7pW5nIGPDoWMgYmnhu4N1IMSR4buTIGNo4bqpbiDEkW/DoW4gdHJvbmcgUioqIMSR4buDIHBow6F0IGhp4buHbiBzYWkgbOG7h2NoLg0KDQotLS0NCg0KIyMjICoqQ2jGsMahbmcgOTogTcO0IGjDrG5oIEJpbm9taWFsIOKAkyBI4buTaSBxdXkgTG9naXN0aWMqKg0KDQotIFThuq1wIHRydW5nIHbDoG8gKipiaW5vbWlhbCBHTE0qKiwgY+G7pSB0aOG7gyBsw6AgaOG7k2kgcXV5IGxvZ2lzdGljLg0KDQotIEThu68gbGnhu4d1IHBow7kgaOG7o3A6IGJp4bq/biBwaOG6o24gaOG7k2kgbMOgIHThu4kgbOG7hywgbmjhu4sgcGjDom4gKHN1Y2Nlc3MvZmFpbHVyZSkuDQoNCi0gVHLDrG5oIGLDoHkgY8OhYyAqKmjDoG0gbGnDqm4ga+G6v3QgY2hvIGJpbm9taWFsOioqDQoNCiAgIC0gTG9naXQgKHRoxrDhu51uZyBkw7luZyBuaOG6pXQpDQoNCiAgIC0gUHJvYml0DQoNCiAgIC0gQ29tcGxlbWVudGFyeSBsb2ctbG9nIChjbG9nbG9nKQ0KDQotIEdp4bqjaSB0aMOtY2ggY8OhY2ggKiptw7QgaMOsbmggaMOzYSB4w6FjIHN14bqldCB0aMOgbmggaMOgbSBsb2dpdDoqKg0KDQokJA0KXGxvZ1xsZWZ0KFxmcmFje3B9ezEgLSBwfVxyaWdodCkgPSBcYmV0YV8wICsgXGJldGFfMSB4XzEgKyBcY2RvdHMNCiQkDQoNCi0gRGnhu4VuIGdp4bqjaSAqKmjhu4cgc+G7kSBkxrDhu5tpIGThuqFuZyB04bu3IHPhu5Egb2RkcyAob2RkcyByYXRpbykuKioNCg0KLSBHaeG7m2kgdGhp4buHdSAqKuG7qW5nIGThu6VuZyB0aOG7sWMgdOG6vyBuaMawOioqDQoNCiAgIC0gxq/hu5tjIGzGsOG7o25nIGxp4buBdSBnw6J5IGhp4buHdSDhu6luZyA1MCUgKEVENTApDQoNCiAgIC0gUGjDom4gdMOtY2ggaGnhu4d1IOG7qW5nIGPhu6dhIGJp4bq/biDEkeG7mWMgbOG6rXAgbMOqbiBraOG6oyBuxINuZyB0aMOgbmggY8O0bmcNCg0KLSDEkOG7gSBj4bqtcCDEkeG6v24gduG6pW4gxJHhu4EgKipvdmVyZGlzcGVyc2lvbioqIHRyb25nIGjhu5NpIHF1eSBuaOG7iyBwaMOibiB2w6AgY8OhY2ggeOG7rSBsw70uDQoNCi0tLQ0KDQojIyMgKipDaMawxqFuZyAxMDogTcO0IGjDrG5oIEThu68gbGnhu4d1IMSQ4bq/bSDigJMgUG9pc3NvbiB2w6AgTmVnYXRpdmUgQmlub21pYWwgR0xNcyoqDQoNCi0gKipNw7QgaMOsbmggaMOzYSBjw6FjIGJp4bq/biBwaOG6o24gaOG7k2kgbMOgIHPhu5EgxJHhur9tKiogKGNvdW50IGRhdGEpLCB2w60gZOG7pTogc+G7kSBjYSBi4buHbmgsIHPhu5Egc+G7sSBraeG7h24uDQoNCi0gKipQaMOibiBwaOG7kWkgUG9pc3NvbioqIGzDoCBu4buBbiB04bqjbmc6DQoNCiQkDQpQKHk7IFxtdSkgPSBcZnJhY3tlXnstXG11fSBcbXVeeX17eSF9DQokJA0KDQotICoqUG9pc3NvbiByZWdyZXNzaW9uKiogZMO5bmcgaMOgbSBsacOqbiBr4bq/dCBsb2c6DQoNCiQkDQpcbG9nKFxtdV9pKSA9IFhfaV5UIFxiZXRhDQokJA0KDQotIMOBcCBk4bulbmcgY2hvIGPDoWMgdHLGsOG7nW5nIGjhu6NwOg0KDQogICAtIEThu68gbGnhu4d1IMSR4bq/bSB0aHXhuqduIHTDunkNCg0KICAgLSBU4bu3IGzhu4cgKHJhdGVzKTogZMO5bmcgb2Zmc2V0IGxvZyhleHBvc3VyZSkNCg0KICAgLSBE4buvIGxp4buHdSBi4bqjbmcgY2jDqW8gKGNvbnRpbmdlbmN5IHRhYmxlcykNCg0KLSBPdmVyZGlzcGVyc2lvbjoga2hpIHBoxrDGoW5nIHNhaSA+IHRydW5nIGLDrG5oIOKGkiBkw7luZyBxdWFzaS1Qb2lzc29uIGhv4bq3YyBOZWdhdGl2ZSBCaW5vbWlhbCBHTE0uDQoNCi0gU28gc8OhbmggQUlDLCBraeG7g20gxJHhu4tuaCBkaXNwZXJzaW9uIMSR4buDIGNo4buNbiBtw7QgaMOsbmggcGjDuSBo4bujcA0KDQotLS0NCg0KIyMjICoqQ2jGsMahbmcgMTE6IEjhu5NpIHF1eSBMb2dpc3RpYyBPcmRpbmFsIHbDoCBNdWx0aW5vbWlhbCoqDQoNCi0gKipNw7QgaMOsbmggaMOzYSBk4buvIGxp4buHdSBwaMOibiBsb+G6oWkgY8OzID4gMiBt4bupYzoqKg0KDQogICAtIE11bHRpbm9taWFsIExvZ2lzdGljIFJlZ3Jlc3Npb246IHbhu5tpIGJp4bq/biBwaOG6o24gaOG7k2kgcGjDom4gbG/huqFpIGtow7RuZyB0aOG7qSB04buxLg0KDQogICAtIE9yZGluYWwgTG9naXN0aWMgUmVncmVzc2lvbjoga2hpIGPDoWMgbeG7qWMgY8OzIHRo4bupIHThu7EgKHbDrSBk4bulOiB54bq/dSDigJMgdHJ1bmcgYsOsbmgg4oCTIHThu5F0KS4NCg0KLSAqKkxvZ2l0IMSRYSB0aOG7qWMgKG11bHRpbm9taWFsIGxvZ2l0KToqKg0KDQokJA0KXGxvZ1xsZWZ0KFxmcmFje1AoWSA9IGopfXtQKFkgPSBKKX1ccmlnaHQpID0gWF5UIFxiZXRhX2oNCiQkDQoNCi0gKipQcm9wb3J0aW9uYWwgb2RkcyBtb2RlbCBjaG8gZOG7ryBsaeG7h3Ugb3JkaW5hbDoqKg0KDQokJA0KXGxvZ1xsZWZ0KFxmcmFje1AoWSBcbGUgail9e1AoWSA+IGopfVxyaWdodCkgPSBYXlQgXGJldGENCiQkDQoNCi0gVGjhuqNvIGx14bqtbiB24buBIGdp4bqjIMSR4buLbmggcHJvcG9ydGlvbmFsaXR5IHbDoCBjw6FjaCBraeG7g20gxJHhu4tuaC4NCg0KLSBSIGNvZGUgc+G7rSBk4bulbmcgaMOgbSBtdWx0aW5vbSgpIHThu6sgZ8OzaSBubmV0IHbDoCBwb2xyKCkgdOG7qyBNQVNTLg0KDQotLS0NCg0KIyMjICoqQ2jGsMahbmcgMTI6IEdlbmVyYWxpemVkIEFkZGl0aXZlIE1vZGVscyAoR0FNcykqKg0KDQotICoqTeG7nyBy4buZbmcgR0xNKiogxJHhu4MgbcO0IGjDrG5oIGjDs2EgcXVhbiBo4buHIHBoaSB0dXnhur9uIGdp4buvYSBiaeG6v24gcGjhuqNuIGjhu5NpIHbDoCBiaeG6v24gZ2nhuqNpIHRow61jaC4NCg0KLSAqKkPDtG5nIHRo4bupYyBHQU06KioNCg0KJCQNCmcoXG11X2kpID0gXGJldGFfMCArIGZfMSh4X3sxaX0pICsgZl8yKHhfezJpfSkgKyBcY2RvdHMNCiQkDQoNCi0gRMO5bmcgY8OhYyBjw7RuZyBj4bulIG5oxrA6DQoNCiAgIC0gKipnYW0oKSoqIHRyb25nIGfDs2kgbWdjdg0KDQogICAtICoqcygpKiogxJHhu4MgY2jhu4kgxJHhu4tuaCBzcGxpbmUgdHJvbmcgY8O0bmcgdGjhu6ljIG3DtCBow6xuaA0KDQotIEdBTSBjaG8gcGjDqXAgbGluaCBob+G6oXQgbmjGsG5nIGPhuqduIMSRw6FuaCDEkeG7lWkgduG7m2kgdmnhu4djIGtp4buDbSBzb8OhdCDEkeG7mSBwaOG7qWMgdOG6oXAgKG92ZXJmaXR0aW5nKS4NCg0KLS0tDQoNCiMjIyAqKkNoxrDGoW5nIDEzOiBFeHRyYSBQcm9ibGVtcyBCw6BpIHThuq1wIG3hu58gcuG7mW5nKioNCg0KLSBDaMawxqFuZyBjdeG7kWkgY8O5bmcgbMOgIHBo4bqnbiBsdXnhu4duIHThuq1wIG3hu58gcuG7mW5nDQoNCi0gQ8OhYyBiw6BpIHRvw6FuIHnDqnUgY+G6p3Uga+G6v3QgaOG7o3AgbeG7jWkga2nhur9uIHRo4bupYyB04burIHRyxrDhu5tjIMSR4buDIGdp4bqjaSBxdXnhur90IHTDrG5oIGh14buRbmcgdGjhu7FjIHThur8uDQoNCi0tLQ0KDQojIyAqKjIuIFRo4buRbmcga8OqIG3DtCB04bqjIGThu68gbGnhu4d1KioNCg0KIyMjICoqMi4xIMSQ4buNYyBmaWxlIENTVioqDQoNCi0gKioqU3VwZXJtYXJrZXQgVHJhbnNhY3Rpb25zKioqIGzDoCBmaWxlICoqY3N2KiosIG7Dqm4gdGEgxJHhu41jIHThu6sgZmlsZSBjc3YNCg0KLSAqKlRoYW8gdMOhYyB0aOG7sWMgaGnhu4duIDoqKiBUYSBnw6FuIGLhu5kgZOG7ryBsaeG7h3UgKioqU3VwZXJtYXJrZXQgVHJhbnNhY3Rpb25zKioqIHbhu5tpIHTDqm4gbMOgICoqZGF0YSoqDQoNCmBgYHtyfQ0KbGlicmFyeShjc3YpDQpkYXRhIDwtIHJlYWQuY3N2KCJEOi9VRk0vMjAyNS0gS8OsIDIvUGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgxJHhu4tuaCB0w61uaCAtIFRy4bqnbiBN4bqhbmggVMaw4budbmcvU3VwZXJtYXJrZXQgVHJhbnNhY3Rpb25zLmNzdiIsIGhlYWRlciA9IFQpDQpgYGANCg0KLS0tDQoNCiMjIyAqKjIuMiBU4buVbmcgcXVhbiBi4buZIGThu68gbGnhu4d1KioNCg0KIyMjIyAqKjIuMi4xIE7hu5lpIGR1bmcgYuG7mSBk4buvIGxp4buHdSoqDQoNCi0gQuG7mSBk4buvIGxp4buHdSBTdXBlcm1hcmtldCBUcmFuc2FjdGlvbnMgZ2hpIGzhuqFpIGPDoWMgKipnaWFvIGThu4tjaCBtdWEgaMOgbmcqKiB04bqhaSBt4buZdCBo4buHIHRo4buRbmcgc2nDqnUgdGjhu4ssIGvDqG0gdGhlbyAqKnRow7RuZyB0aW4ga2jDoWNoIGjDoG5nLCDEkeG7i2EgbMO9LCB2w6AgY2hpIHRp4bq/dCBz4bqjbiBwaOG6qW0uKiogDQoNCi0gTsOzIGPDsyB0aOG7gyBkw7luZyDEkeG7gyBwaMOibiB0w61jaCBow6BuaCB2aSBtdWEgc+G6r20sIHBow6JuIGtow7pjIGtow6FjaCBow6BuZywgaG/hurdjIGhp4buHdSBzdeG6pXQga2luaCBkb2FuaCB0aGVvIHPhuqNuIHBo4bqpbSwga2h1IHbhu7FjLCBuaMOibiBraOG6qXUgaOG7jWMuDQoNCg0KDQojIyMjICoqMi4yLjIgRGFuaCBzw6FjaCBjw6FjIGJp4bq/biB2w6AgbcO0IHThuqMqKg0KDQpUw6puIGPhu6dhIGPDoWMgYmnhur9uIHRyb25nIGLhu5kgZOG7ryBsaeG7h3Ugc+G6vSBiYW8gZ+G7k206IA0KDQoNCmBgYHtyfQ0KbmFtZXMoZGF0YSkNCmBgYA0KDQpD4bulIHRo4buDIHThu6tuZyBjw6FjIGJp4bq/biB2w6AgcXVhbiBzw6F0IGPDsyDDvSBuZ2jEqWEgbmjGsCBzYXU6DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0KDQojIFThuqFvIGLhuqNuZyBtw7QgdOG6oyBjw6FjIGJp4bq/bg0KdmFyaWFibGVfZGVzY3JpcHRpb24gPC0gZGF0YS5mcmFtZSgNCiAgVmFyaWFibGUgPSBjKA0KICAgICJVbm5hbWVkOiAwIiwNCiAgICAiUHVyY2hhc2VEYXRlIiwNCiAgICAiQ3VzdG9tZXJJRCIsDQogICAgIkdlbmRlciIsDQogICAgIk1hcml0YWxTdGF0dXMiLA0KICAgICJIb21lb3duZXIiLA0KICAgICJDaGlsZHJlbiIsDQogICAgIkFubnVhbEluY29tZSIsDQogICAgIkNpdHkiLA0KICAgICJTdGF0ZW9yUHJvdmluY2UiLA0KICAgICJDb3VudHJ5IiwNCiAgICAiUHJvZHVjdEZhbWlseSIsDQogICAgIlByb2R1Y3REZXBhcnRtZW50IiwNCiAgICAiUHJvZHVjdENhdGVnb3J5IiwNCiAgICAiVW5pdHNTb2xkIiwNCiAgICAiUmV2ZW51ZSINCiAgKSwNCiAgRGVzY3JpcHRpb24gPSBjKA0KICAgICJNw6MgZMOybmcgKGPDsyB0aOG7gyBi4buPIHF1YSkiLA0KICAgICJOZ8OgeSBtdWEgaMOgbmciLA0KICAgICJJRCBraMOhY2ggaMOgbmciLA0KICAgICJHaeG7m2kgdMOtbmggKEY6IG7hu68sIE06IG5hbSkiLA0KICAgICJUw6xuaCB0cuG6oW5nIGjDtG4gbmjDom4gKFM6IMSR4buZYyB0aMOibiwgTTogxJHDoyBr4bq/dCBow7RuKSIsDQogICAgIlPhu58gaOG7r3UgbmjDoCAoWTogY8OzLCBOOiBraMO0bmcpIiwNCiAgICAiU+G7kSBjb24gdHJvbmcgZ2lhIMSRw6xuaCIsDQogICAgIlRodSBuaOG6rXAgaMOgbmcgbsSDbSAodGhlbyBuaMOzbSkiLA0KICAgICJUaMOgbmggcGjhu5Egc2luaCBz4buRbmciLA0KICAgICJCYW5nIC8gdOG7iW5oIiwNCiAgICAiUXXhu5FjIGdpYSIsDQogICAgIk5ow7NtIHPhuqNuIHBo4bqpbSBjaMOtbmggKEZvb2QsIERyaW5rLCAuLi4pIiwNCiAgICAiUGjDsm5nIGJhbiBz4bqjbiBwaOG6qW0gKFNuYWNrcywgUHJvZHVjZSwgLi4uKSIsDQogICAgIkRhbmggbeG7pWMgc+G6o24gcGjhuqltIGPhu6UgdGjhu4MiLA0KICAgICJT4buRIGzGsOG7o25nIHPhuqNuIHBo4bqpbSDEkcOjIGLDoW4iLA0KICAgICJEb2FuaCB0aHUgdOG7qyBnaWFvIGThu4tjaCAoVVNEKSINCiAgKQ0KKQ0KDQojIEhp4buDbiB0aOG7iyBi4bqjbmcNCmthYmxlKHZhcmlhYmxlX2Rlc2NyaXB0aW9uLCBjb2wubmFtZXMgPSBjKCJCaeG6v24iLCAiTcO0IHThuqMiKSkNCmBgYA0KDQpUYSBjw7MgdGjhu4MgbOG6pXkgdsOtIGThu6UgdOG7qyBxdWFuIHPDoXQgxJHhuqd1IHRpw6puOiBWw6BvIG5nw6B5IDE4LzEyLzIwMDcsIGtow6FjaCBow6BuZyBJRCA3MjIzIChu4buvLCDEkeG7mWMgdGjDom4sIGPDsyBuaMOgLCAyIGNvbiwgdGh1IG5o4bqtcCAkMzBL4oCTJDUwSykg4bufIExvcyBBbmdlbGVzLCBiYW5nIENBIEhvYSBL4buzIG11YSA1IMSRxqFuIHbhu4sgc+G6o24gcGjhuqltICJTbmFjayBGb29kcyIgdGh14buZYyBuaMOzbSAiRm9vZCIsIHThuqFvIHJhIGRvYW5oIHRodSAkMjcuMzggY2hvIHNpw6p1IHRo4buLDQoNCi0tLQ0KDQojIyMgKioyLjMgVGjhu5FuZyBrw6ogbcO0IHThuqMgY2hvIGPDoWMgYmnhur9uKioNCg0KIyMjIyAqKjIuMy4xIFPhu5EgYmnhur9uIHbDoCBz4buRIHF1YW4gc8OhdCoqDQoNCi0gQuG7mSBk4buvIGxp4buHdSAqKmRhdGEqKiBiYW8gZ+G7k20gKioxNDA1OSBxdWFuIHPDoXQgdsOgIDE2IGJp4bq/bioqDQoNCi0gMTQwNTkgcXVhbiBzw6F0LCB0xrDGoW5nIOG7qW5nIHbhu5tpIDE0LjA1OSBnaWFvIGThu4tjaCBtdWEgaMOgbmcgdOG6oWkgc2nDqnUgdGjhu4suIE3hu5dpIHF1YW4gc8OhdCDEkeG6oWkgZGnhu4duIGNobyBt4buZdCBs4bqnbiBtdWEgaMOgbmcsIGvDqG0gdGhlbyAxNiB54bq/dSB04buRIG3DtCB04bqjIMSRw6MgbsOzaSB0csOqbg0KDQpgYGB7cn0NCmRpbShkYXRhKQ0KYGBgDQoNCg0KDQojIyMjICoqMi4zLjIgS2nhu4NtIHRyYSBj4bqldSB0csO6YyB04buVbmcgcXXDoXQqKg0KDQpUYSBjw7MgdGjhu4Mga2nhu4NtIHRyYSBj4bqldSB0csO6YyB04buVbmcgcXXDoXQgY+G7p2EgZOG7ryBsaeG7h3UgbmjGsCBzYXU6DQoNCmBgYHtyfQ0Kc3RyKGRhdGEpDQpgYGANCg0KIyMjIyAqKjIuMy4zIFRo4buRbmcga8OqIG3DtCB04bqjIGNobyBjw6FjIGJp4bq/biBwaMOibiBsb+G6oWkqKg0KDQpWw6wgYuG7mSBk4buvIGxp4buHdSBjw7MgY+G6oyBk4buvIGxp4buHdSDEkeG7i25oIHTDrW5oIG5oxrAgZOG6oW5nIHRow7RuZyB0aW4gxJHhu4tuaCBkYW5oIGhv4bq3YyBwaMOibiBsb+G6oWkga2jDoWNoIGjDoG5nLCBjw6FjIGThu68gbGnhu4d1IG7DoHkga2jDtG5nIGTDuW5nIMSR4buDIHTDrW5oIHRvw6FuIHRy4buxYyB0aeG6v3AgbmjGsCBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZyAoZG9hbmggdGh1LCBz4buRIGzGsOG7o25nLOKApikuIE7Dqm4ga2hpIHRo4buRbmcga8OqIG3DtCB04bqjIHRhIGPhuqduIHBow6JuIGJp4buHdCByw7UgaGFpIG5ow7NtIGJp4bq/bg0KDQoNCi0gKipUaOG7kW5nIGvDqiBjaG8gdOG7q25nIGJp4bq/biDEkeG7i25oIHTDrW5oIC0gR2VuZGVyKioNCg0KICAgLSAqKkdlbmRlcioqIMSR4bqhaSBkaeG7h24gY2hvIGdp4bubaSB0w61uaCBj4bunYSBraMOhY2ggaMOgbmcsIEYgLSBGZW1hbGUgbMOgIG7hu68gdsOgIE0gLSBNYWxlIGzDoCBuYW0NCiAgIA0KICAgLSBE4buxYSB0aGVvIGvhur90IHF14bqjLCB0cm9uZyAxNDA1OSBraMOhY2ggaMOgbmcgdGjDrCBjw7MgNzE3MCBraMOhY2ggaMOgbmcgbMOgIG7hu68gdsOgIDY4ODkga2jDoWNoIGjDoG5nIGzDoCBuYW0NCg0KYGBge3J9DQp0YWJsZShkYXRhJEdlbmRlcikNCmBgYA0KDQogIA0KLSAqKlRo4buRbmcga8OqIGNobyB04burbmcgYmnhur9uIMSR4buLbmggdMOtbmggLSBNYXJpdGFsU3RhdHVzKiogDQogIA0KICAgLSAqKk1hcml0YWxTdGF0dXMqKiDEkeG6oWkgZGnhu4duIGNobyB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4NCiAgIA0KICAgLSBL4bq/dCBxdeG6oyBjaG8gdGjhuqV5IGPDsyA2ODY2IGtow6FjaCBow6BuZyDEkcOjIGvhur90IGjDtG4gKE0gLSBNYXJyaWVkKSB2w6AgNzE5MyBraMOhY2ggaMOgbmcgbMOgIMSR4buZYyB0aMOibiAoUyAtIFNpbmdsZSkNCiAgIA0KICAgLSBOaOG7r25nIGvhur90IHF14bqjIG7DoHkgY8WpbmcgY8OzIHRo4buDIOG6o25oIGjGsOG7n25nIMSR4bq/biBz4bupYyBtdWEgaMOgbmcsIGNo4bqzbmcgaOG6oW4gbmjGsCBuZ8aw4budaSDEkcOjIGvhur90IGjDtG4gc+G6vSBjw7Mgbmh1IGPhuqd1IG11YSBow6BuZyBuaGnhu4F1IGjGoW4gbmfGsOG7nWkgxJHhu5ljIHRow6JuLg0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkTWFyaXRhbFN0YXR1cykNCmBgYA0KDQoNCg0KLSAqKlThu5VuZyBo4bujcCB0aOG7kW5nIGvDqiBtw7QgdOG6oyBjaG8gdOG7q25nIGJp4bq/biDEkeG7i25nIHTDrW5oKioNCg0KICAgLSAyIGvhur90IHF14bqjIGPhu6dhIDIgYmnhur9uIHBow6JuIGxv4bqhaSB0csOqbiBjaOG7iSBsw6AgxJHhu4MgdsOtIGThu6UgbuG6v3UgdGEgbXXhu5FuIG5ow6xuIHRo4bqleSBr4bq/dCBxdeG6oyByacOqbmcgY+G7p2EgdOG7q25nIGJp4bq/bg0KICAgDQogICAtIFRhIGPDsyB0aOG7gyB04buVbmcgaOG7o3Aga+G6v3QgcXXhuqMgbmjGsCBkxrDhu5tpIMSRw6J5Og0KDQpgYGB7cn0NCiMgRGFuaCBzw6FjaCBjw6FjIGJp4bq/biBwaMOibiBsb+G6oWkgY2F0ZWdvcmljYWwNCmNhdF92YXJzIDwtIGMoIkdlbmRlciIsICJNYXJpdGFsU3RhdHVzIiwgIkhvbWVvd25lciIsICJBbm51YWxJbmNvbWUiLA0KICAgICAgICAgICAgICAiQ2l0eSIsICJTdGF0ZW9yUHJvdmluY2UiLCAiQ291bnRyeSIsIA0KICAgICAgICAgICAgICAiUHJvZHVjdEZhbWlseSIsICJQcm9kdWN0RGVwYXJ0bWVudCIsICJQcm9kdWN0Q2F0ZWdvcnkiKQ0KDQojIEzhurdwIHF1YSB04burbmcgYmnhur9uIMSR4buDIHRo4buRbmcga8OqDQpmb3IgKHZhciBpbiBjYXRfdmFycykgew0KICBjYXQoIlxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIikNCiAgY2F0KCJCaeG6v246IiwgdmFyLCAiXG4iKQ0KICBjYXQoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpDQogIGZyZXFfdGFibGUgPC0gdGFibGUoZGF0YVtbdmFyXV0pDQogIHBlcmNlbnRfdGFibGUgPC0gcHJvcC50YWJsZShmcmVxX3RhYmxlKSAqIDEwMA0KICBwcmludChkYXRhLmZyYW1lKFThuqduX3N14bqldCA9IGZyZXFfdGFibGUsIFThu7dfbOG7h19waOG6p25fdHLEg20gPSByb3VuZChwZXJjZW50X3RhYmxlLCAyKSkpDQp9DQpgYGANCg0KDQoNCg0KIyMjIyAqKjIuMy40IFRo4buRbmcga8OqIG3DtCB04bqjIGNobyBjw6FjIGJp4bq/biDEkeG7i25oIGzGsOG7o25nKioNCg0KU2F1IGtoaSDEkcOjIHRo4buRbmcga8OqIGPDoWMgYmnhur9uIHBow6JuIGxv4bqhaSwgdGEgc+G6vSB0aeG6v3AgdOG7pWMgdGnhur9uIGjDoG5oIHbhu5tpIGPDoWMgYmnhur9uIMSR4buLbmggbMaw4bujbmcuIFRow7RuZyB0aW4gY+G7p2EgY8OhYyBiaeG6v24gbsOgeSBt4bubaSBsw6Agbmjhu69uZyBjb24gc+G7kSDEkeG7gyBjw7MgdGjhu4MgdMOtbmggdG/DoW4gbmjhu69uZyBnacOhIHRy4buLIG5oxrA6IHRydW5nIGLDrG5oLCB0cnVuZyB24buLLCBnacOhIHRy4buLIGzhu5tuIG5o4bqldCBuaOG7jyBuaOG6pXQsLi4uDQoNClRyb25nIGLhu5kgZOG7ryBsaeG7h3UgY2jhu4kgY8OzIGJp4bq/biAqKlVuaXRzU29sZCAoU+G7kSBsxrDhu6NuZyBz4bqjbiBwaOG6qW0gxJHDoyBiw6FuKSoqIHbDoCAqKlJldmVudWUgKERvYW5oIHRodSkqKiBsw6AgY8OzIHRo4buDIHTDrW5oIHJhIGPDoWMgdGjDtG5nIHPhu5ENCg0KKipUaOG7kW5nIGvDqiBjaG8gYmnhur9uIFVuaXRzU29sZCAtIFPhu5EgbMaw4bujbmcgc+G6o24gcGjhuqltIMSRw6MgYsOhbioqIA0KDQpgYGB7cn0NCmxpYnJhcnkocHN5Y2gpDQpkZXNjcmliZShkYXRhJFVuaXRzU29sZCkgIA0KYGBgDQoNCiAgIC0gKipHacOhIHRy4buLIHRydW5nIGLDrG5oIG1lYW46KiogNC4wOA0KDQogICAtICoqxJDhu5kgbOG7h2NoIGNodeG6qW4gc2Q6KiogMS4xNw0KDQogICAtICoqR2nDoSB0cuG7iyB0cnVuZyB24buLIG1lZGlhbjoqKiA0DQogICANCiAgIC0gKipHacOhIHRy4buLIHRydW5nIGLDrG5oIMSRw6MgY+G6r3QgdHJpbW1lZCBtZWFuOioqIDQuMDgNCiAgIA0KICAgLSAqKsSQ4buZIGzhu4djaCB0dXnhu4d0IMSR4buRaSB0cnVuZyBiw6xuaCBNQUQ6KiogMS40OA0KICAgDQogICAtICoqR2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgbWluOioqIDENCg0KICAgLSAqKkdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IG1heDoqKiA4DQoNCiAgIC0gKirEkOG7mSBuaOG7jW4gS3VydG9zaXM6KiogLTAuNDQNCg0KICAgLSAqKlNhaSBz4buRIGNodeG6qW4gY+G7p2EgxJHhu5kgbmjhu41uIFNFOioqIDAuMDENCg0KICAgLSAqKk5o4bqtbiB4w6l0OioqIEdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggdsOgIHRydW5nIHbhu4sgY2hvIHRo4bqleSBwaMOibiBwaOG7kWkgZOG7ryBsaeG7h3Uga2jDoSBjw6JuIMSR4buRaSB2w6AgxJHhu5FpIHjhu6luZywgdHJ1bmcgYsOsbmggY+G6r3QgY8WpbmcgeMOhYyBuaOG6rW4gdGjDqm0gcuG6sW5nIGtow7RuZyBjw7Mgbmhp4buBdSBuZ2/huqFpIGzhu4cgbOG7m24g4bqjbmggaMaw4bufbmcgxJHhur9uIHRydW5nIGLDrG5oLiDEkOG7mSBs4buHY2ggY2h14bqpbiDEkeG6oXQgdsOgIMSR4buZIGzhu4djaCB0dXnhu4d0IMSR4buRaSB0cnVuZyB24buLIHBo4bqjbiDDoW5oIG3hu6ljIMSR4buZIGJp4bq/biDEkeG7mW5nIHRo4bqlcCBxdWFuaCBnacOhIHRy4buLIHRydW5nIHTDom0uIEdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGzDoCAxIHbDoCBs4bubbiBuaOG6pXQgbMOgIDgsIGNobyB0aOG6pXkgZOG7ryBsaeG7h3UgbuG6sW0gdHJvbmcgbeG7mXQga2hv4bqjbmcgaOG6uXAsIGThu4UgcXXhuqNuIGzDvSB2w6AgcGjDom4gdMOtY2guDQoNCg0KDQotLS0NCg0KICoqVGjhu5FuZyBrw6ogY2hvIGJp4bq/biBSZXZlbnVlIC0gRG9hbmggdGh1KiogDQoNCmBgYHtyfQ0KZGVzY3JpYmUoZGF0YSRSZXZlbnVlKSAgDQpgYGANCg0KICAgLSAqKkdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggbWVhbjoqKiAxMw0KDQogICAtICoqxJDhu5kgbOG7h2NoIGNodeG6qW4gc2Q6KiogOC4yMiANCg0KICAgLSAqKkdpw6EgdHLhu4sgdHJ1bmcgduG7iyBtZWRpYW46KiogMTEuMjUgDQoNCiAgIC0gKipHacOhIHRy4buLIHRydW5nIGLDrG5oIMSRw6MgY+G6r3QgdHJpbW1lZCBtZWFuOioqIDEyLjA1IA0KDQogICAtICoqxJDhu5kgbOG7h2NoIHR1eeG7h3QgxJHhu5FpIHRydW5nIGLDrG5oIE1BRDoqKiA3LjQgDQoNCiAgIC0gKipHacOhIHRy4buLIG5o4buPIG5o4bqldCBtaW46KiogMC41Mw0KDQogICAtICoqR2nDoSB0cuG7iyBs4bubbiBuaOG6pXQgbWF4OioqIDU2LjcNCg0KICAgLSAqKsSQ4buZIG5o4buNbiBLdXJ0b3NpczoqKiAxLjM5DQoNCiAgIC0gKipTYWkgc+G7kSBjaHXhuqluIGPhu6dhIMSR4buZIG5o4buNbiBTRToqKiAwLjA3DQoNCiAgIC0gKipOaOG6rW4geMOpdDoqKiBCaeG6v24gUmV2ZW51ZSB24bubaSBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCAxMyB2w6AgxJHhu5kgbOG7h2NoIGNodeG6qW4gxJHhuqF0IDguMjIsIGNobyB0aOG6pXkgZOG7ryBsaeG7h3UgY8OzIG3hu6ljIMSR4buZIHBow6JuIHTDoW4ga2jDoSBs4bubbiBxdWFuaCB0cnVuZyBiw6xuaC4gVHJ1bmcgduG7iyBj4bunYSBiaeG6v24gdGjhuqVwIGjGoW4gdHJ1bmcgYsOsbmgsIGNobyB0aOG6pXkgcGjDom4gcGjhu5FpIGThu68gbGnhu4d1IGPDsyB0aOG7gyBs4buHY2ggcGjhuqNpLiBHacOhIHRy4buLIHRydW5nIGLDrG5oIMSRw6MgY+G6r3QgdGjhuqVwIGjGoW4gbmjhurkgc28gduG7m2kgdHJ1bmcgYsOsbmgsIHBo4bqjbiDDoW5oIHPhu7EgaGnhu4duIGRp4buHbiBj4bunYSBt4buZdCBz4buRIGdpw6EgdHLhu4sgbmdv4bqhaSBs4buHIGzhu5tuIGzDoG0gdMSDbmcgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBn4buRYy4gR2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgdsOgIGzhu5tuIG5o4bqldCBjw7Mga2hv4bqjbmcgYmnhur9uIHRoacOqbiBraMOhIHLhu5luZy4gVuG7gSDEkeG6t2MgxJFp4buDbSBwaMOibiBwaOG7kWksIMSR4buZIG5o4buNbiB0aOG6pXAgaMahbiBwaMOibiBwaOG7kWkgY2h14bqpbi4gU2FpIHPhu5EgY2h14bqpbiBj4bunYSDEkeG7mSBuaOG7jW4gbMOgIDAuMDcsIGdpw7pwIHjDoWMgbmjhuq1uIHLhurFuZyDEkeG7mSBuaOG7jW4gbsOgeSBraMOhYyBiaeG7h3QgY8OzIMO9IG5naMSpYSB0aOG7kW5nIGvDqiBzbyB24bubaSBwaMOibiBwaOG7kWkgY2h14bqpbi4NCg0KDQoNCg0KDQoNCg0KDQoNCg0K