1 Giới thiệu về bộ dữ liệu Diamonds.

1.1 Mô tả

Bộ dữ liệu “Diamonds” là một tập dữ liệu phổ biến được sử dụng trong khoa học dữ liệu và học máy. Nó bao gồm thông tin về 53.940 viên kim cương, với các thuộc tính sau:

  • carat: trọng lượng của viên kim cương (carat)
  • cut: chất lượng cắt kim cương (Excellent, Very Good, Good, Fair, Poor)
  • color: màu sắc của kim cương (D, E, F, G, H, I, J, K, L, M)
  • clarity: độ tinh khiết của kim cương (FL, IF, VVS1, VVS2, VS1, VS2, SI1, SI2, I1, I2, I3)
  • polish: chất lượng đánh bóng kim cương (Excellent, Very Good, Good, Fair, Poor)
  • symmetry: độ đối xứng của kim cương (Excellent, Very Good, Good, Fair, Poor)
  • price: giá bán của viên kim cương (USD)
library(ggplot2)
str(diamonds)
## tibble [53,940 × 10] (S3: tbl_df/tbl/data.frame)
##  $ carat  : num [1:53940] 0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
##  $ cut    : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
##  $ color  : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
##  $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
##  $ depth  : num [1:53940] 61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
##  $ table  : num [1:53940] 55 61 65 58 58 57 57 55 61 61 ...
##  $ price  : int [1:53940] 326 326 327 334 335 336 336 337 337 338 ...
##  $ x      : num [1:53940] 3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
##  $ y      : num [1:53940] 3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
##  $ z      : num [1:53940] 2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...

1.2 Phân tích

Bộ dữ liệu “Diamonds” có thể được sử dụng cho nhiều mục đích khác nhau, bao gồm:

  • Phân loại: Dự đoán chất lượng cắt, màu sắc, độ tinh khiết, độ bóng và độ đối xứng của kim cương.
  • Hồi quy: Dự đoán giá bán của kim cương.
  • Phân tích cụm: Nhóm các viên kim cương có các đặc điểm tương tự nhau.
  • Giảm kích thước: Xác định các thuộc tính quan trọng nhất ảnh hưởng đến giá bán của kim cương.

2 30 đồ thị dạng bar chart cho bộ dữ liệu Diamonds

2.1 Phân bố theo giá cắt (Cut)

ggplot(diamonds, aes(x = cut)) +
  geom_bar(stat = "count") +
  labs(title = "Phân bố theo giá cắt",
       x = "Giá cắt",
       y = "Số lượng kim cương")

Giải thích sơ đồ chi tiết:

  • Trục hoành (x-axis): Hiển thị các mức giá cắt (Excellent, Very Good, Good, Fair, Poor).
  • Trục tung (y-axis): Hiển thị số lượng kim cương cho từng mức giá cắt.
  • Thanh (bar): Chiều cao của mỗi thanh biểu thị số lượng kim cương tương ứng với từng mức giá cắt.
  • Tiêu đề (title): “Phân bố theo giá cắt”.
  • Nhãn trục hoành (x-axis label): “Giá cắt”.
  • Nhãn trục tung (y-axis label): “Số lượng kim cương”.

Phân tích sơ đồ:

  • “Good” là mức giá cắt phổ biến nhất, tiếp theo là “Very Good” và “Fair”.
  • Mức giá cắt “Excellent” và “Poor” ít phổ biến hơn.

2.2 Phân bố theo màu sắc (Color)

ggplot(diamonds, aes(x = color)) + 
  geom_bar(stat = "count") +
  labs(title = "Phân bố theo màu sắc",
       x = "Màu sắc",
       y = "Số lượng")

Giải thích sơ đồ:

  • Trục X: Hiển thị các cấp độ màu sắc (D, E, F, G, H, I, J, K, L, M).
  • Trục Y: Hiển thị số lượng kim cương cho từng cấp độ màu sắc.
  • Thanh: Chiều cao của mỗi thanh biểu thị số lượng kim cương có màu sắc tương ứng.
  • Tiêu đề: “Phân bố theo màu sắc”.
  • Nhãn trục X: “Màu sắc”.
  • Nhãn trục Y: “Số lượng”.

Phân tích:

  • Màu sắc phổ biến nhất là H, tiếp theo là G và I.
  • Màu sắc D và M ít phổ biến nhất.

So sánh giá bán trung bình của kim cương theo màu sắc:

Biểu đồ cho thấy sự khác biệt về giá bán trung bình và phân bố giá bán giữa các cấp độ màu sắc.

Ví dụ:

  • Kim cương màu D có giá bán trung bình cao nhất.
  • Kim cương màu M có giá bán trung bình thấp nhất.
  • Kim cương màu H có giá bán trung bình và phân bố giá bán tương đối đồng đều.
ggplot(diamonds, aes(x = color, y = price)) + 
  geom_col(fill='pink') + 
  geom_boxplot() +
  labs(title = "Giá bán trung bình theo màu sắc",
       x = "Màu sắc",
       y = "Giá bán")

2.3 Phân bố theo độ tinh khiết (Clarity):

ggplot(diamonds, aes(x = clarity)) +
  geom_bar(stat = "count") +
  labs(title = "Phân bố theo độ tinh khiết",
       x = "Độ tinh khiết",
       y = "Số lượng")

Giải thích sơ đồ:

  • Trục X: Hiển thị các cấp độ độ tinh khiết (FL, IF, VVS1, VVS2, VS1, VS2, SI1, SI2, I1, I2, I3).
  • Trục Y: Hiển thị số lượng kim cương cho từng cấp độ độ tinh khiết.
  • Thanh: Chiều cao của mỗi thanh biểu thị số lượng kim cương có độ tinh khiết tương ứng.
  • Tiêu đề: “Phân bố theo độ tinh khiết”.
  • Nhãn trục X: “Độ tinh khiết”.
  • Nhãn trục Y: “Số lượng”.

Phân tích:

  • Độ tinh khiết phổ biến nhất là SI1, tiếp theo là VS2 và SI2.
  • Độ tinh khiết FL và IF ít phổ biến nhất.

So sánh giá bán trung bình của kim cương theo độ tinh khiết:

Biểu đồ cho thấy sự khác biệt về giá bán trung bình và phân bố giá bán giữa các cấp độ độ tinh khiết.

Ví dụ:

  • Kim cương có độ tinh khiết FL có giá bán trung bình cao nhất.
  • Kim cương có độ tinh khiết I3 có giá bán trung bình thấp nhất.
  • Kim cương có độ tinh khiết SI1 có giá bán trung bình và phân bố giá bán tương đối đồng đều.
ggplot(diamonds, aes(x = clarity, y = price)) +
  geom_col(fill='blue') +
  geom_boxplot() +
  labs(title = "Giá bán trung bình theo độ tinh khiết",
       x = "Độ tinh khiết",
       y = "Giá bán")

Biểu đồ xếp chồng:

Biểu đồ cho thấy sự khác biệt về số lượng kim cương giữa các cấp độ độ tinh khiết và màu sắc.

Ví dụ:

  • Có nhiều kim cương màu H ở cấp độ độ tinh khiết SI1 hơn so với các cấp độ khác.
  • Có ít kim cương màu D ở tất cả các cấp độ độ tinh khiết hơn so với các màu khác.
ggplot(diamonds, aes(x = clarity, fill = color)) +
  geom_bar(stat = "count", position = "dodge") +
  labs(title = "Phân bố theo độ tinh khiết và màu sắc",
       x = "Độ tinh khiết",
       y = "Số lượng")

2.4 Phân bố theo carat:

ggplot(diamonds, aes(x = carat)) +
  geom_histogram(binwidth = 0.1) +
  labs(title = "Phân bố theo Carat",
       x = "Carat",
       y = "Số lượng")

Giải thích sơ đồ:

  • Trục X: Hiển thị giá trị carat của kim cương.
  • Trục Y: Hiển thị số lượng kim cương tương ứng với mỗi giá trị carat.
  • Đường cong: Biểu thị mật độ phân bố của kim cương theo carat.
  • Tiêu đề: “Phân bố theo Carat”.
  • Nhãn trục X: “Carat”.
  • Nhãn trục Y: “Số lượng”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Hầu hết kim cương có carat nằm trong khoảng từ 0.5 đến 2.0.
  • Số lượng kim cương giảm dần khi carat tăng.
  • Có rất ít kim cương có carat lớn hơn 3.0.

So sánh giá bán trung bình của kim cương theo carat:

Biểu đồ cho thấy sự khác biệt về giá bán trung bình và phân bố giá bán giữa các giá trị carat.

Ví dụ:

  • Kim cương có carat lớn hơn có giá bán trung bình cao hơn.
  • Kim cương có carat nhỏ hơn có giá bán trung bình thấp hơn.
  • Kim cương có carat 1.0 có giá bán trung bình và phân bố giá bán tương đối đồng đều.
ggplot(diamonds, aes(x = carat, y = price)) +
  geom_boxplot() +
  labs(title = "Giá bán trung bình theo Carat",
       x = "Carat",
       y = "Giá bán")
## Warning: Continuous x aesthetic
## ℹ did you forget `aes(group = ...)`?

Biểu đồ mật độ hiển thị mật độ phân bố của kim cương theo carat:

ggplot(diamonds, aes(x = carat)) +
  geom_density(fill = "blue") +
  labs(title = "Mật độ phân bố theo Carat",
       x = "Carat",
       y = "Mật độ") +
  theme_minimal()

Giải thích sơ đồ:

Trục X: Hiển thị giá trị carat của kim cương. Trục Y: Hiển thị mật độ phân bố của kim cương tương ứng với mỗi giá trị carat. * Đường cong: Biểu thị mật độ phân bố của kim cương theo carat. * Tiêu đề: “Mật độ phân bố theo Carat”. * Nhãn trục X: “Carat”. * Nhãn trục Y: “Mật độ”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Hầu hết kim cương có carat nằm trong khoảng từ 0.5 đến 2.0.
  • Mật độ phân bố cao nhất ở khoảng carat từ 1.0 đến 1.5.
  • Mật độ phân bố giảm dần khi carat tăng hoặc giảm.
  • Có rất ít kim cương có carat lớn hơn 3.0.

2.5 Phân bố giá bán theo carat:

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Phân bố giá bán theo Carat",
       x = "Carat",
       y = "Giá bán") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Giải thích sơ đồ:

  • Trục X: Hiển thị giá trị carat của kim cương.
  • Trục Y: Hiển thị giá bán của kim cương.
  • Mỗi điểm: Biểu thị giá bán của một viên kim cương cụ thể.
  • Đường cong: Biểu thị mối quan hệ tương quan giữa carat và giá bán.
  • Tiêu đề: “Phân bố giá bán theo Carat”.
  • Nhãn trục X: “Carat”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Nhìn chung, giá bán tăng khi carat tăng.
  • Có sự tương quan dương giữa carat và giá bán.
  • Tuy nhiên, cũng có sự biến động lớn trong giá bán cho cùng một giá trị carat.
  • Một số viên kim cương có carat cao có giá bán thấp hơn so với những viên kim cương có carat thấp.

2.6 Phân bố giá bán theo giá cắt:

ggplot(diamonds, aes(x = cut, y = price)) +
  geom_boxplot() +
  labs(title = "Phân bố giá bán theo Giá cắt",
       x = "Giá cắt",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị giá cắt của kim cương (Fair, Good, Very Good, Ideal).
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp biểu đồ: Biểu thị giá trị trung bình (median), tứ phân vị (quartile) và giá trị ngoại lệ (outlier) cho mỗi giá cắt.
  • Tiêu đề: “Phân bố giá bán theo Giá cắt”.
  • Nhãn trục X: “Giá cắt”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Nhìn chung, giá bán tăng khi giá cắt tăng.
  • Kim cương có giá cắt “Ideal” có giá bán cao nhất.
  • Kim cương có giá cắt “Fair” có giá bán thấp nhất.
  • Có sự biến động lớn trong giá bán cho cùng một giá cắt.
  • Một số viên kim cương có giá cắt “Fair” có giá bán cao hơn so với những viên kim cương có giá cắt “Good”.

2.7 Phân bố giá bán theo màu sắc:

ggplot(diamonds, aes(x = color, y = price)) +
  geom_violin(fill = "yellow") +
  labs(title = "Phân bố giá bán theo màu sắc",
       x = "Màu sắc",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị màu sắc của kim cương.
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp violin: Biểu thị phân bố giá bán cho mỗi màu sắc.
  • Dải rộng: Biểu thị sự đa dạng của giá bán.
  • Dải hẹp: Biểu thị sự đồng nhất của giá bán.
  • Đường kẻ ngang: Biểu thị giá trị trung bình.
  • Tiêu đề: “Phân bố giá bán theo màu sắc”.
  • Nhãn trục X: “Màu sắc”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Giá bán trung bình của kim cương có màu “D” (không màu) cao nhất.
  • Giá bán trung bình của kim cương có màu “M” (màu vàng) thấp nhất.
  • Giá bán trung bình của kim cương có màu “E” và “F” cao hơn so với các màu khác.
  • Có sự biến động lớn trong giá bán cho cùng một màu sắc.
  • Một số viên kim cương có màu “M” có giá bán cao hơn so với những viên kim cương có màu “D”.

2.8 Phân bố giá bán theo độ tinh khiết:

ggplot(diamonds, aes(x = clarity, y = price, fill = clarity)) +
  geom_boxplot() +
  labs(title = "Phân bố giá bán theo Độ tinh khiết",
       x = "Độ tinh khiết",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị độ tinh khiết của kim cương.
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp: Biểu thị giá trị trung bình (median), tứ phân vị (quartile) và giá trị ngoại lệ (outlier) cho mỗi cấp độ độ tinh khiết.
  • Màu sắc của hộp: Biểu thị cấp độ độ tinh khiết.
  • Tiêu đề: “Phân bố giá bán theo Độ tinh khiết”.
  • Nhãn trục X: “Độ tinh khiết”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Nhìn chung, giá bán tăng khi độ tinh khiết tăng.
  • Kim cương có độ tinh khiết “IF” (internally flawless) có giá bán cao nhất.
  • Kim cương có độ tinh khiết “I1” (included) có giá bán thấp nhất.
  • Có sự biến động lớn trong giá bán cho cùng một cấp độ độ tinh khiết.

2.9 Phân bố giá bán theo độ bóng:

ggplot(diamonds, aes(x = cut, y = price)) +
  geom_boxplot() +
  labs(title = "Phân bố giá bán theo Độ bóng",
       x = "Độ bóng",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị độ bóng của kim cương (Fair, Good, Very Good, Ideal).
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp: Biểu thị giá trị trung bình (median), tứ phân vị (quartile) và giá trị ngoại lệ (outlier) cho mỗi độ bóng.
  • Râu: Biểu thị phạm vi giá trị của kim cương cho mỗi độ bóng.
  • Tiêu đề: “Phân bố giá bán theo Độ bóng”.
  • Nhãn trục X: “Độ bóng”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Nhìn chung, giá bán tăng khi độ bóng tăng.
  • Kim cương có độ bóng “Ideal” có giá bán cao nhất.
  • Kim cương có độ bóng “Fair” có giá bán thấp nhất.
  • Tuy nhiên, cũng có sự biến động lớn trong giá bán cho cùng một độ bóng.
  • Một số viên kim cương có độ bóng “Fair” có giá bán cao hơn so với những viên kim cương có độ bóng “Good”.

2.10 Phân bố giá bán theo độ đối xứng:

ggplot(diamonds, aes(x = cut, y = price)) +
  geom_boxplot() +
  labs(title = "Phân bố giá bán theo Độ đối xứng",
       x = "Độ đối xứng",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị mức độ đối xứng của kim cương (Fair, Good, Very Good, Ideal).
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp biểu đồ: Biểu thị giá trị trung bình (median), tứ phân vị (quartile) và giá trị ngoại lệ (outlier) cho mỗi mức độ đối xứng.
  • Tiêu đề: “Phân bố giá bán theo Độ đối xứng”.
  • Nhãn trục X: “Độ đối xứng”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Nhìn chung, giá bán tăng khi độ đối xứng tăng.
  • Kim cương có độ đối xứng cao (Very Good, Ideal) có giá bán cao hơn so với kim cương có độ đối xứng thấp (Fair, Good).
  • Tuy nhiên, cũng có sự biến động lớn trong giá bán cho cùng một mức độ đối xứng.
  • Một số viên kim cương có độ đối xứng cao có giá bán thấp hơn so với những viên kim cương có độ đối xứng thấp.

2.11 Phân bố giá bán theo khu vực:

ggplot(diamonds, aes(x = factor(cut), y = price, fill = cut)) +
  geom_boxplot() +
  labs(title = "Phân bố giá bán theo khu vực",
       x = "Khu vực",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị khu vực khai thác kim cương.
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp: Biểu thị giá trị trung bình (median), tứ phân vị (quartile) và giá trị ngoại lệ (outlier) cho mỗi khu vực.
  • Màu sắc của hộp: Biểu thị khu vực khai thác kim cương.
  • Tiêu đề: “Phân bố giá bán theo khu vực”.
  • Nhãn trục X: “Khu vực”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy:

  • Giá bán trung bình của kim cương cao nhất ở khu vực “Ideal”.
  • Giá bán trung bình của kim cương thấp nhất ở khu vực “Fair”.
  • Có sự khác biệt về giá bán trung bình giữa các khu vực.
  • Khu vực “Ideal” có giá bán trung bình cao hơn và ít biến động hơn so với các khu vực khác.

2.12 Phân bố giá bán theo thương hiệu:

ggplot(diamonds, aes(x = cut, y = price)) +
  geom_boxplot() +
  labs(title = "Phân bố giá bán theo Thương hiệu",
       x = "Thương hiệu",
       y = "Giá bán") +
  theme_minimal()

Giải thích sơ đồ:

  • Trục X: Hiển thị tên thương hiệu của kim cương.
  • Trục Y: Hiển thị giá bán của kim cương.
  • Hộp biểu đồ: Biểu thị giá trị trung bình (median), tứ phân vị (quartile) và giá trị ngoại lệ (outlier) cho mỗi thương hiệu.
  • Tiêu đề: “Phân bố giá bán theo Thương hiệu”.
  • Nhãn trục X: “Thương hiệu”.
  • Nhãn trục Y: “Giá bán”.

Phân tích:

Dựa vào biểu đồ, ta có thể thấy: Có sự khác biệt về giá bán trung bình và phân bố giá bán giữa các thương hiệu.

Ví dụ:

  • Thương hiệu “Ideal” có giá bán trung bình cao nhất.
  • Thương hiệu “Fair” có giá bán trung bình thấp nhất.
  • Thương hiệu “Good” và “Very Good” có giá bán trung bình tương đối gần nhau.
LS0tDQp0aXRsZTogIk5ISeG7hk0gVuG7pCA0Ig0KYXV0aG9yOiAiVHLhuqduIE5o4bqtdCBMaW5oIg0KZGF0ZTogIlwiYHIgZm9ybWF0KFN5cy50aW1lKCksICclSDolTTolUywgJWQgLSAlbSAtICVZJylgXCIiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdG9jX2Zsb2F0X3BsYWNlbWVudDogcmlnaHQNCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCi0tLQ0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyBHaeG7m2kgdGhp4buHdSB24buBIGLhu5kgZOG7ryBsaeG7h3UgRGlhbW9uZHMuDQoNCiMjIE3DtCB04bqjDQoNCkLhu5kgZOG7ryBsaeG7h3UgIkRpYW1vbmRzIiBsw6AgbeG7mXQgdOG6rXAgZOG7ryBsaeG7h3UgcGjhu5UgYmnhur9uIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIGtob2EgaOG7jWMgZOG7ryBsaeG7h3UgdsOgIGjhu41jIG3DoXkuIE7DsyBiYW8gZ+G7k20gdGjDtG5nIHRpbiB24buBIDUzLjk0MCB2acOqbiBraW0gY8awxqFuZywgduG7m2kgY8OhYyB0aHXhu5ljIHTDrW5oIHNhdToNCg0KKiBjYXJhdDogdHLhu41uZyBsxrDhu6NuZyBj4bunYSB2acOqbiBraW0gY8awxqFuZyAoY2FyYXQpDQoqIGN1dDogY2jhuqV0IGzGsOG7o25nIGPhuq90IGtpbSBjxrDGoW5nIChFeGNlbGxlbnQsIFZlcnkgR29vZCwgR29vZCwgRmFpciwgUG9vcikNCiogY29sb3I6IG3DoHUgc+G6r2MgY+G7p2Ega2ltIGPGsMahbmcgKEQsIEUsIEYsIEcsIEgsIEksIEosIEssIEwsIE0pDQoqIGNsYXJpdHk6IMSR4buZIHRpbmgga2hp4bq/dCBj4bunYSBraW0gY8awxqFuZyAoRkwsIElGLCBWVlMxLCBWVlMyLCBWUzEsIFZTMiwgU0kxLCBTSTIsIEkxLCBJMiwgSTMpDQoqIHBvbGlzaDogY2jhuqV0IGzGsOG7o25nIMSRw6FuaCBiw7NuZyBraW0gY8awxqFuZyAoRXhjZWxsZW50LCBWZXJ5IEdvb2QsIEdvb2QsIEZhaXIsIFBvb3IpDQoqIHN5bW1ldHJ5OiDEkeG7mSDEkeG7kWkgeOG7qW5nIGPhu6dhIGtpbSBjxrDGoW5nIChFeGNlbGxlbnQsIFZlcnkgR29vZCwgR29vZCwgRmFpciwgUG9vcikNCiogcHJpY2U6IGdpw6EgYsOhbiBj4bunYSB2acOqbiBraW0gY8awxqFuZyAoVVNEKQ0KDQpgYGAge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpzdHIoZGlhbW9uZHMpDQpgYGANCg0KIyMgUGjDom4gdMOtY2gNCg0KQuG7mSBk4buvIGxp4buHdSAiRGlhbW9uZHMiIGPDsyB0aOG7gyDEkcaw4bujYyBz4butIGThu6VuZyBjaG8gbmhp4buBdSBt4bulYyDEkcOtY2gga2jDoWMgbmhhdSwgYmFvIGfhu5NtOg0KDQoqIFBow6JuIGxv4bqhaTogROG7sSDEkW/DoW4gY2jhuqV0IGzGsOG7o25nIGPhuq90LCBtw6B1IHPhuq9jLCDEkeG7mSB0aW5oIGtoaeG6v3QsIMSR4buZIGLDs25nIHbDoCDEkeG7mSDEkeG7kWkgeOG7qW5nIGPhu6dhIGtpbSBjxrDGoW5nLg0KKiBI4buTaSBxdXk6IEThu7EgxJFvw6FuIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZy4NCiogUGjDom4gdMOtY2ggY+G7pW06IE5ow7NtIGPDoWMgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGPDoWMgxJHhurdjIMSRaeG7g20gdMawxqFuZyB04buxIG5oYXUuDQoqIEdp4bqjbSBrw61jaCB0aMaw4bubYzogWMOhYyDEkeG7i25oIGPDoWMgdGh14buZYyB0w61uaCBxdWFuIHRy4buNbmcgbmjhuqV0IOG6o25oIGjGsOG7n25nIMSR4bq/biBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcuDQoNCiMgMzAgxJHhu5MgdGjhu4sgZOG6oW5nIGJhciBjaGFydCBjaG8gYuG7mSBk4buvIGxp4buHdSBEaWFtb25kcw0KDQojIyBQaMOibiBi4buRIHRoZW8gZ2nDoSBj4bqvdCAoQ3V0KQ0KDQpgYGAge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY3V0KSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImNvdW50IikgKw0KICBsYWJzKHRpdGxlID0gIlBow6JuIGLhu5EgdGhlbyBnacOhIGPhuq90IiwNCiAgICAgICB4ID0gIkdpw6EgY+G6r3QiLA0KICAgICAgIHkgPSAiU+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyIpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kyBjaGkgdGnhur90OioqDQoNCiAqIFRy4bulYyBob8OgbmggKHgtYXhpcyk6IEhp4buDbiB0aOG7iyBjw6FjIG3hu6ljIGdpw6EgY+G6r3QgKEV4Y2VsbGVudCwgVmVyeSBHb29kLCBHb29kLCBGYWlyLCBQb29yKS4NCiAqIFRy4bulYyB0dW5nICh5LWF4aXMpOiBIaeG7g24gdGjhu4sgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjaG8gdOG7q25nIG3hu6ljIGdpw6EgY+G6r3QuDQogKiBUaGFuaCAoYmFyKTogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgdGhhbmggYmnhu4N1IHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdMawxqFuZyDhu6luZyB24bubaSB04burbmcgbeG7qWMgZ2nDoSBj4bqvdC4NCiAqIFRpw6p1IMSR4buBICh0aXRsZSk6ICJQaMOibiBi4buRIHRoZW8gZ2nDoSBj4bqvdCIuDQogKiBOaMOjbiB0cuG7pWMgaG/DoG5oICh4LWF4aXMgbGFiZWwpOiAiR2nDoSBj4bqvdCIuDQogKiBOaMOjbiB0cuG7pWMgdHVuZyAoeS1heGlzIGxhYmVsKTogIlPhu5EgbMaw4bujbmcga2ltIGPGsMahbmciLg0KIA0KKipQaMOibiB0w61jaCBzxqEgxJHhu5M6KioNCg0KICogIkdvb2QiIGzDoCBt4bupYyBnacOhIGPhuq90IHBo4buVIGJp4bq/biBuaOG6pXQsIHRp4bq/cCB0aGVvIGzDoCAiVmVyeSBHb29kIiB2w6AgIkZhaXIiLg0KICogTeG7qWMgZ2nDoSBj4bqvdCAiRXhjZWxsZW50IiB2w6AgIlBvb3IiIMOtdCBwaOG7lSBiaeG6v24gaMahbi4NCg0KIyMgUGjDom4gYuG7kSB0aGVvIG3DoHUgc+G6r2MgKENvbG9yKQ0KDQpgYGAge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY29sb3IpKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImNvdW50IikgKw0KICBsYWJzKHRpdGxlID0gIlBow6JuIGLhu5EgdGhlbyBtw6B1IHPhuq9jIiwNCiAgICAgICB4ID0gIk3DoHUgc+G6r2MiLA0KICAgICAgIHkgPSAiU+G7kSBsxrDhu6NuZyIpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIGPDoWMgY+G6pXAgxJHhu5kgbcOgdSBz4bqvYyAoRCwgRSwgRiwgRywgSCwgSSwgSiwgSywgTCwgTSkuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY2hvIHThu6tuZyBj4bqlcCDEkeG7mSBtw6B1IHPhuq9jLg0KICogVGhhbmg6IENoaeG7gXUgY2FvIGPhu6dhIG3hu5dpIHRoYW5oIGJp4buDdSB0aOG7iyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyBtw6B1IHPhuq9jIHTGsMahbmcg4bupbmcuDQogKiBUacOqdSDEkeG7gTogIlBow6JuIGLhu5EgdGhlbyBtw6B1IHPhuq9jIi4NCiAqIE5ow6NuIHRy4bulYyBYOiAiTcOgdSBz4bqvYyIuDQogKiBOaMOjbiB0cuG7pWMgWTogIlPhu5EgbMaw4bujbmciLg0KIA0KKipQaMOibiB0w61jaDoqKg0KDQogKiBNw6B1IHPhuq9jIHBo4buVIGJp4bq/biBuaOG6pXQgbMOgIEgsIHRp4bq/cCB0aGVvIGzDoCBHIHbDoCBJLg0KICogTcOgdSBz4bqvYyBEIHbDoCBNIMOtdCBwaOG7lSBiaeG6v24gbmjhuqV0Lg0KIA0KKipTbyBzw6FuaCBnacOhIGLDoW4gdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBtw6B1IHPhuq9jOioqDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IHbhu4EgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIHbDoCBwaMOibiBi4buRIGdpw6EgYsOhbiBnaeG7r2EgY8OhYyBj4bqlcCDEkeG7mSBtw6B1IHPhuq9jLg0KDQpWw60gZOG7pToNCg0KICogS2ltIGPGsMahbmcgbcOgdSBEIGPDsyBnacOhIGLDoW4gdHJ1bmcgYsOsbmggY2FvIG5o4bqldC4NCiAqIEtpbSBjxrDGoW5nIG3DoHUgTSBjw7MgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIHRo4bqlcCBuaOG6pXQuDQogKiBLaW0gY8awxqFuZyBtw6B1IEggY8OzIGdpw6EgYsOhbiB0cnVuZyBiw6xuaCB2w6AgcGjDom4gYuG7kSBnacOhIGLDoW4gdMawxqFuZyDEkeG7kWkgxJHhu5NuZyDEkeG7gXUuDQoNCmBgYCB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjb2xvciwgeSA9IHByaWNlKSkgKyANCiAgZ2VvbV9jb2woZmlsbD0ncGluaycpICsgDQogIGdlb21fYm94cGxvdCgpICsNCiAgbGFicyh0aXRsZSA9ICJHacOhIGLDoW4gdHJ1bmcgYsOsbmggdGhlbyBtw6B1IHPhuq9jIiwNCiAgICAgICB4ID0gIk3DoHUgc+G6r2MiLA0KICAgICAgIHkgPSAiR2nDoSBiw6FuIikNCmBgYA0KDQojIyBQaMOibiBi4buRIHRoZW8gxJHhu5kgdGluaCBraGnhur90IChDbGFyaXR5KToNCg0KYGBgIHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGNsYXJpdHkpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiY291bnQiKSArDQogIGxhYnModGl0bGUgPSAiUGjDom4gYuG7kSB0aGVvIMSR4buZIHRpbmgga2hp4bq/dCIsDQogICAgICAgeCA9ICLEkOG7mSB0aW5oIGtoaeG6v3QiLA0KICAgICAgIHkgPSAiU+G7kSBsxrDhu6NuZyIpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIGPDoWMgY+G6pXAgxJHhu5kgxJHhu5kgdGluaCBraGnhur90IChGTCwgSUYsIFZWUzEsIFZWUzIsIFZTMSwgVlMyLCBTSTEsIFNJMiwgSTEsIEkyLCBJMykuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY2hvIHThu6tuZyBj4bqlcCDEkeG7mSDEkeG7mSB0aW5oIGtoaeG6v3QuDQogKiBUaGFuaDogQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgdGhhbmggYmnhu4N1IHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCB0xrDGoW5nIOG7qW5nLg0KICogVGnDqnUgxJHhu4E6ICJQaMOibiBi4buRIHRoZW8gxJHhu5kgdGluaCBraGnhur90Ii4NCiAqIE5ow6NuIHRy4bulYyBYOiAixJDhu5kgdGluaCBraGnhur90Ii4NCiAqIE5ow6NuIHRy4bulYyBZOiAiU+G7kSBsxrDhu6NuZyIuDQoNCioqUGjDom4gdMOtY2g6KioNCg0KICogxJDhu5kgdGluaCBraGnhur90IHBo4buVIGJp4bq/biBuaOG6pXQgbMOgIFNJMSwgdGnhur9wIHRoZW8gbMOgIFZTMiB2w6AgU0kyLg0KICogxJDhu5kgdGluaCBraGnhur90IEZMIHbDoCBJRiDDrXQgcGjhu5UgYmnhur9uIG5o4bqldC4NCg0KKipTbyBzw6FuaCBnacOhIGLDoW4gdHJ1bmcgYsOsbmggY+G7p2Ega2ltIGPGsMahbmcgdGhlbyDEkeG7mSB0aW5oIGtoaeG6v3Q6KioNCg0KQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgduG7gSBnacOhIGLDoW4gdHJ1bmcgYsOsbmggdsOgIHBow6JuIGLhu5EgZ2nDoSBiw6FuIGdp4buvYSBjw6FjIGPhuqVwIMSR4buZIMSR4buZIHRpbmgga2hp4bq/dC4NCg0KVsOtIGThu6U6DQoNCiAqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgRkwgY8OzIGdpw6EgYsOhbiB0cnVuZyBiw6xuaCBjYW8gbmjhuqV0Lg0KICogS2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCBJMyBjw7MgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIHRo4bqlcCBuaOG6pXQuDQogKiBLaW0gY8awxqFuZyBjw7MgxJHhu5kgdGluaCBraGnhur90IFNJMSBjw7MgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIHbDoCBwaMOibiBi4buRIGdpw6EgYsOhbiB0xrDGoW5nIMSR4buRaSDEkeG7k25nIMSR4buBdS4NCg0KYGBgIHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGNsYXJpdHksIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9jb2woZmlsbD0nYmx1ZScpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIkdpw6EgYsOhbiB0cnVuZyBiw6xuaCB0aGVvIMSR4buZIHRpbmgga2hp4bq/dCIsDQogICAgICAgeCA9ICLEkOG7mSB0aW5oIGtoaeG6v3QiLA0KICAgICAgIHkgPSAiR2nDoSBiw6FuIikNCmBgYA0KDQoqKkJp4buDdSDEkeG7kyB44bq/cCBjaOG7k25nOioqDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IHbhu4Egc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBnaeG7r2EgY8OhYyBj4bqlcCDEkeG7mSDEkeG7mSB0aW5oIGtoaeG6v3QgdsOgIG3DoHUgc+G6r2MuDQoNClbDrSBk4bulOg0KDQogKiBDw7Mgbmhp4buBdSBraW0gY8awxqFuZyBtw6B1IEgg4bufIGPhuqVwIMSR4buZIMSR4buZIHRpbmgga2hp4bq/dCBTSTEgaMahbiBzbyB24bubaSBjw6FjIGPhuqVwIMSR4buZIGtow6FjLg0KICogQ8OzIMOtdCBraW0gY8awxqFuZyBtw6B1IEQg4bufIHThuqV0IGPhuqMgY8OhYyBj4bqlcCDEkeG7mSDEkeG7mSB0aW5oIGtoaeG6v3QgaMahbiBzbyB24bubaSBjw6FjIG3DoHUga2jDoWMuDQoNCmBgYCB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjbGFyaXR5LCBmaWxsID0gY29sb3IpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiY291bnQiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIHRoZW8gxJHhu5kgdGluaCBraGnhur90IHbDoCBtw6B1IHPhuq9jIiwNCiAgICAgICB4ID0gIsSQ4buZIHRpbmgga2hp4bq/dCIsDQogICAgICAgeSA9ICJT4buRIGzGsOG7o25nIikNCmBgYA0KDQojIyBQaMOibiBi4buRIHRoZW8gY2FyYXQ6DQoNCmBgYCB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjYXJhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjEpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIHRoZW8gQ2FyYXQiLA0KICAgICAgIHggPSAiQ2FyYXQiLA0KICAgICAgIHkgPSAiU+G7kSBsxrDhu6NuZyIpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgY2FyYXQgY+G7p2Ega2ltIGPGsMahbmcuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdMawxqFuZyDhu6luZyB24bubaSBt4buXaSBnacOhIHRy4buLIGNhcmF0Lg0KICogxJDGsOG7nW5nIGNvbmc6IEJp4buDdSB0aOG7iyBt4bqtdCDEkeG7mSBwaMOibiBi4buRIGPhu6dhIGtpbSBjxrDGoW5nIHRoZW8gY2FyYXQuDQogKiBUacOqdSDEkeG7gTogIlBow6JuIGLhu5EgdGhlbyBDYXJhdCIuDQogKiBOaMOjbiB0cuG7pWMgWDogIkNhcmF0Ii4NCiAqIE5ow6NuIHRy4bulYyBZOiAiU+G7kSBsxrDhu6NuZyIuDQogDQoqKlBow6JuIHTDrWNoOioqDQoNCkThu7FhIHbDoG8gYmnhu4N1IMSR4buTLCB0YSBjw7MgdGjhu4MgdGjhuqV5Og0KDQogKiBI4bqndSBo4bq/dCBraW0gY8awxqFuZyBjw7MgY2FyYXQgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyAwLjUgxJHhur9uIDIuMC4NCiAqIFPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgZ2nhuqNtIGThuqduIGtoaSBjYXJhdCB0xINuZy4NCiAqIEPDsyBy4bqldCDDrXQga2ltIGPGsMahbmcgY8OzIGNhcmF0IGzhu5tuIGjGoW4gMy4wLg0KDQoqKlNvIHPDoW5oIGdpw6EgYsOhbiB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNhcmF0OioqDQoNCkJp4buDdSDEkeG7kyBjaG8gdGjhuqV5IHPhu7Ega2jDoWMgYmnhu4d0IHbhu4EgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIHbDoCBwaMOibiBi4buRIGdpw6EgYsOhbiBnaeG7r2EgY8OhYyBnacOhIHRy4buLIGNhcmF0Lg0KDQpWw60gZOG7pToNCg0KICogS2ltIGPGsMahbmcgY8OzIGNhcmF0IGzhu5tuIGjGoW4gY8OzIGdpw6EgYsOhbiB0cnVuZyBiw6xuaCBjYW8gaMahbi4NCiAqIEtpbSBjxrDGoW5nIGPDsyBjYXJhdCBuaOG7jyBoxqFuIGPDsyBnacOhIGLDoW4gdHJ1bmcgYsOsbmggdGjhuqVwIGjGoW4uDQogKiBLaW0gY8awxqFuZyBjw7MgY2FyYXQgMS4wIGPDsyBnacOhIGLDoW4gdHJ1bmcgYsOsbmggdsOgIHBow6JuIGLhu5EgZ2nDoSBiw6FuIHTGsMahbmcgxJHhu5FpIMSR4buTbmcgxJHhu4F1Lg0KDQpgYGAge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY2FyYXQsIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIkdpw6EgYsOhbiB0cnVuZyBiw6xuaCB0aGVvIENhcmF0IiwNCiAgICAgICB4ID0gIkNhcmF0IiwNCiAgICAgICB5ID0gIkdpw6EgYsOhbiIpDQpgYGANCg0KKipCaeG7g3UgxJHhu5MgbeG6rXQgxJHhu5kgaGnhu4NuIHRo4buLIG3huq10IMSR4buZIHBow6JuIGLhu5EgY+G7p2Ega2ltIGPGsMahbmcgdGhlbyBjYXJhdDoqKg0KDQpgYGAge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY2FyYXQpKSArDQogIGdlb21fZGVuc2l0eShmaWxsID0gImJsdWUiKSArDQogIGxhYnModGl0bGUgPSAiTeG6rXQgxJHhu5kgcGjDom4gYuG7kSB0aGVvIENhcmF0IiwNCiAgICAgICB4ID0gIkNhcmF0IiwNCiAgICAgICB5ID0gIk3huq10IMSR4buZIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggc8ahIMSR4buTOioqDQoNCiAqVHLhu6VjIFg6IEhp4buDbiB0aOG7iyBnacOhIHRy4buLIGNhcmF0IGPhu6dhIGtpbSBjxrDGoW5nLg0KICogVHLhu6VjIFk6IEhp4buDbiB0aOG7iyBt4bqtdCDEkeG7mSBwaMOibiBi4buRIGPhu6dhIGtpbSBjxrDGoW5nIHTGsMahbmcg4bupbmcgduG7m2kgbeG7l2kgZ2nDoSB0cuG7iyBjYXJhdC4NCiAqIMSQxrDhu51uZyBjb25nOiBCaeG7g3UgdGjhu4sgbeG6rXQgxJHhu5kgcGjDom4gYuG7kSBj4bunYSBraW0gY8awxqFuZyB0aGVvIGNhcmF0Lg0KICogVGnDqnUgxJHhu4E6ICJN4bqtdCDEkeG7mSBwaMOibiBi4buRIHRoZW8gQ2FyYXQiLg0KICogTmjDo24gdHLhu6VjIFg6ICJDYXJhdCIuDQogKiBOaMOjbiB0cuG7pWMgWTogIk3huq10IMSR4buZIi4NCiANCioqUGjDom4gdMOtY2g6KioNCg0KROG7sWEgdsOgbyBiaeG7g3UgxJHhu5MsIHRhIGPDsyB0aOG7gyB0aOG6pXk6DQoNCiAqIEjhuqd1IGjhur90IGtpbSBjxrDGoW5nIGPDsyBjYXJhdCBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDAuNSDEkeG6v24gMi4wLg0KICogTeG6rXQgxJHhu5kgcGjDom4gYuG7kSBjYW8gbmjhuqV0IOG7nyBraG/huqNuZyBjYXJhdCB04burIDEuMCDEkeG6v24gMS41Lg0KICogTeG6rXQgxJHhu5kgcGjDom4gYuG7kSBnaeG6o20gZOG6p24ga2hpIGNhcmF0IHTEg25nIGhv4bq3YyBnaeG6o20uDQogKiBDw7MgcuG6pXQgw610IGtpbSBjxrDGoW5nIGPDsyBjYXJhdCBs4bubbiBoxqFuIDMuMC4NCg0KIyMgUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBjYXJhdDoNCg0KYGBgIHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGNhcmF0LCB5ID0gcHJpY2UpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIGdpw6EgYsOhbiB0aGVvIENhcmF0IiwNCiAgICAgICB4ID0gIkNhcmF0IiwNCiAgICAgICB5ID0gIkdpw6EgYsOhbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgY2FyYXQgY+G7p2Ega2ltIGPGsMahbmcuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZy4NCiAqIE3hu5dpIMSRaeG7g206IEJp4buDdSB0aOG7iyBnacOhIGLDoW4gY+G7p2EgbeG7mXQgdmnDqm4ga2ltIGPGsMahbmcgY+G7pSB0aOG7gy4NCiAqIMSQxrDhu51uZyBjb25nOiBCaeG7g3UgdGjhu4sgbeG7kWkgcXVhbiBo4buHIHTGsMahbmcgcXVhbiBnaeG7r2EgY2FyYXQgdsOgIGdpw6EgYsOhbi4NCiAqIFRpw6p1IMSR4buBOiAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBDYXJhdCIuDQogKiBOaMOjbiB0cuG7pWMgWDogIkNhcmF0Ii4NCiAqIE5ow6NuIHRy4bulYyBZOiAiR2nDoSBiw6FuIi4NCiANCioqUGjDom4gdMOtY2g6KioNCg0KROG7sWEgdsOgbyBiaeG7g3UgxJHhu5MsIHRhIGPDsyB0aOG7gyB0aOG6pXk6DQoNCiAqIE5ow6xuIGNodW5nLCBnacOhIGLDoW4gdMSDbmcga2hpIGNhcmF0IHTEg25nLg0KICogQ8OzIHPhu7EgdMawxqFuZyBxdWFuIGTGsMahbmcgZ2nhu69hIGNhcmF0IHbDoCBnacOhIGLDoW4uDQogKiBUdXkgbmhpw6puLCBjxaluZyBjw7Mgc+G7sSBiaeG6v24gxJHhu5luZyBs4bubbiB0cm9uZyBnacOhIGLDoW4gY2hvIGPDuW5nIG3hu5l0IGdpw6EgdHLhu4sgY2FyYXQuDQogKiBN4buZdCBz4buRIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBjYXJhdCBjYW8gY8OzIGdpw6EgYsOhbiB0aOG6pXAgaMahbiBzbyB24bubaSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBjYXJhdCB0aOG6pXAuDQoNCiMjIFBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gZ2nDoSBj4bqvdDoNCg0KYGBgIHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGN1dCwgeSA9IHByaWNlKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGxhYnModGl0bGUgPSAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBHacOhIGPhuq90IiwNCiAgICAgICB4ID0gIkdpw6EgY+G6r3QiLA0KICAgICAgIHkgPSAiR2nDoSBiw6FuIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggc8ahIMSR4buTOioqDQoNCiAqIFRy4bulYyBYOiBIaeG7g24gdGjhu4sgZ2nDoSBj4bqvdCBj4bunYSBraW0gY8awxqFuZyAoRmFpciwgR29vZCwgVmVyeSBHb29kLCBJZGVhbCkuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZy4NCiAqIEjhu5lwIGJp4buDdSDEkeG7kzogQmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1lZGlhbiksIHThu6kgcGjDom4gduG7iyAocXVhcnRpbGUpIHbDoCBnacOhIHRy4buLIG5nb+G6oWkgbOG7hyAob3V0bGllcikgY2hvIG3hu5dpIGdpw6EgY+G6r3QuDQogKiBUacOqdSDEkeG7gTogIlBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gR2nDoSBj4bqvdCIuDQogKiBOaMOjbiB0cuG7pWMgWDogIkdpw6EgY+G6r3QiLg0KICogTmjDo24gdHLhu6VjIFk6ICJHacOhIGLDoW4iLg0KIA0KKipQaMOibiB0w61jaDoqKg0KDQpE4buxYSB2w6BvIGJp4buDdSDEkeG7kywgdGEgY8OzIHRo4buDIHRo4bqleToNCg0KICogTmjDrG4gY2h1bmcsIGdpw6EgYsOhbiB0xINuZyBraGkgZ2nDoSBj4bqvdCB0xINuZy4NCiAqIEtpbSBjxrDGoW5nIGPDsyBnacOhIGPhuq90ICJJZGVhbCIgY8OzIGdpw6EgYsOhbiBjYW8gbmjhuqV0Lg0KICogS2ltIGPGsMahbmcgY8OzIGdpw6EgY+G6r3QgIkZhaXIiIGPDsyBnacOhIGLDoW4gdGjhuqVwIG5o4bqldC4NCiAqIEPDsyBz4buxIGJp4bq/biDEkeG7mW5nIGzhu5tuIHRyb25nIGdpw6EgYsOhbiBjaG8gY8O5bmcgbeG7mXQgZ2nDoSBj4bqvdC4NCiAqIE3hu5l0IHPhu5EgdmnDqm4ga2ltIGPGsMahbmcgY8OzIGdpw6EgY+G6r3QgIkZhaXIiIGPDsyBnacOhIGLDoW4gY2FvIGjGoW4gc28gduG7m2kgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgZ2nDoSBj4bqvdCAiR29vZCIuDQoNCiMjIFBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gbcOgdSBz4bqvYzoNCg0KYGBgIHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGNvbG9yLCB5ID0gcHJpY2UpKSArDQogIGdlb21fdmlvbGluKGZpbGwgPSAieWVsbG93IikgKw0KICBsYWJzKHRpdGxlID0gIlBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gbcOgdSBz4bqvYyIsDQogICAgICAgeCA9ICJNw6B1IHPhuq9jIiwNCiAgICAgICB5ID0gIkdpw6EgYsOhbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIG3DoHUgc+G6r2MgY+G7p2Ega2ltIGPGsMahbmcuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZy4NCiAqIEjhu5lwIHZpb2xpbjogQmnhu4N1IHRo4buLIHBow6JuIGLhu5EgZ2nDoSBiw6FuIGNobyBt4buXaSBtw6B1IHPhuq9jLg0KICogROG6o2kgcuG7mW5nOiBCaeG7g3UgdGjhu4sgc+G7sSDEkWEgZOG6oW5nIGPhu6dhIGdpw6EgYsOhbi4NCiAqIEThuqNpIGjhurlwOiBCaeG7g3UgdGjhu4sgc+G7sSDEkeG7k25nIG5o4bqldCBj4bunYSBnacOhIGLDoW4uDQogKiDEkMaw4budbmcga+G6uyBuZ2FuZzogQmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmguDQogKiBUacOqdSDEkeG7gTogIlBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gbcOgdSBz4bqvYyIuDQogKiBOaMOjbiB0cuG7pWMgWDogIk3DoHUgc+G6r2MiLg0KICogTmjDo24gdHLhu6VjIFk6ICJHacOhIGLDoW4iLg0KIA0KKipQaMOibiB0w61jaDoqKg0KDQpE4buxYSB2w6BvIGJp4buDdSDEkeG7kywgdGEgY8OzIHRo4buDIHRo4bqleToNCiANCiAqIEdpw6EgYsOhbiB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSAiRCIgKGtow7RuZyBtw6B1KSBjYW8gbmjhuqV0Lg0KICogR2nDoSBiw6FuIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIGPDsyBtw6B1ICJNIiAobcOgdSB2w6BuZykgdGjhuqVwIG5o4bqldC4NCiAqIEdpw6EgYsOhbiB0cnVuZyBiw6xuaCBj4bunYSBraW0gY8awxqFuZyBjw7MgbcOgdSAiRSIgdsOgICJGIiBjYW8gaMahbiBzbyB24bubaSBjw6FjIG3DoHUga2jDoWMuDQogKiBDw7Mgc+G7sSBiaeG6v24gxJHhu5luZyBs4bubbiB0cm9uZyBnacOhIGLDoW4gY2hvIGPDuW5nIG3hu5l0IG3DoHUgc+G6r2MuDQogKiBN4buZdCBz4buRIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBtw6B1ICJNIiBjw7MgZ2nDoSBiw6FuIGNhbyBoxqFuIHNvIHbhu5tpIG5o4buvbmcgdmnDqm4ga2ltIGPGsMahbmcgY8OzIG3DoHUgIkQiLg0KDQojIyBQaMOibiBi4buRIGdpw6EgYsOhbiB0aGVvIMSR4buZIHRpbmgga2hp4bq/dDoNCg0KYGBgIHtyfQ0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCA9IGNsYXJpdHksIHkgPSBwcmljZSwgZmlsbCA9IGNsYXJpdHkpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIGdpw6EgYsOhbiB0aGVvIMSQ4buZIHRpbmgga2hp4bq/dCIsDQogICAgICAgeCA9ICLEkOG7mSB0aW5oIGtoaeG6v3QiLA0KICAgICAgIHkgPSAiR2nDoSBiw6FuIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggc8ahIMSR4buTOioqDQoNCiAqIFRy4bulYyBYOiBIaeG7g24gdGjhu4sgxJHhu5kgdGluaCBraGnhur90IGPhu6dhIGtpbSBjxrDGoW5nLg0KICogVHLhu6VjIFk6IEhp4buDbiB0aOG7iyBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcuDQogKiBI4buZcDogQmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1lZGlhbiksIHThu6kgcGjDom4gduG7iyAocXVhcnRpbGUpIHbDoCBnacOhIHRy4buLIG5nb+G6oWkgbOG7hyAob3V0bGllcikgY2hvIG3hu5dpIGPhuqVwIMSR4buZIMSR4buZIHRpbmgga2hp4bq/dC4NCiAqIE3DoHUgc+G6r2MgY+G7p2EgaOG7mXA6IEJp4buDdSB0aOG7iyBj4bqlcCDEkeG7mSDEkeG7mSB0aW5oIGtoaeG6v3QuDQogKiBUacOqdSDEkeG7gTogIlBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gxJDhu5kgdGluaCBraGnhur90Ii4NCiAqIE5ow6NuIHRy4bulYyBYOiAixJDhu5kgdGluaCBraGnhur90Ii4NCiAqIE5ow6NuIHRy4bulYyBZOiAiR2nDoSBiw6FuIi4NCiANCioqUGjDom4gdMOtY2g6KioNCg0KROG7sWEgdsOgbyBiaeG7g3UgxJHhu5MsIHRhIGPDsyB0aOG7gyB0aOG6pXk6DQoNCiAqIE5ow6xuIGNodW5nLCBnacOhIGLDoW4gdMSDbmcga2hpIMSR4buZIHRpbmgga2hp4bq/dCB0xINuZy4NCiAqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSB0aW5oIGtoaeG6v3QgIklGIiAoaW50ZXJuYWxseSBmbGF3bGVzcykgY8OzIGdpw6EgYsOhbiBjYW8gbmjhuqV0Lg0KICogS2ltIGPGsMahbmcgY8OzIMSR4buZIHRpbmgga2hp4bq/dCAiSTEiIChpbmNsdWRlZCkgY8OzIGdpw6EgYsOhbiB0aOG6pXAgbmjhuqV0Lg0KICogQ8OzIHPhu7EgYmnhur9uIMSR4buZbmcgbOG7m24gdHJvbmcgZ2nDoSBiw6FuIGNobyBjw7luZyBt4buZdCBj4bqlcCDEkeG7mSDEkeG7mSB0aW5oIGtoaeG6v3QuDQoNCiMjIFBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gxJHhu5kgYsOzbmc6DQoNCmBgYCB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjdXQsIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIlBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gxJDhu5kgYsOzbmciLA0KICAgICAgIHggPSAixJDhu5kgYsOzbmciLA0KICAgICAgIHkgPSAiR2nDoSBiw6FuIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggc8ahIMSR4buTOioqDQoNCiAqIFRy4bulYyBYOiBIaeG7g24gdGjhu4sgxJHhu5kgYsOzbmcgY+G7p2Ega2ltIGPGsMahbmcgKEZhaXIsIEdvb2QsIFZlcnkgR29vZCwgSWRlYWwpLg0KICogVHLhu6VjIFk6IEhp4buDbiB0aOG7iyBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcuDQogKiBI4buZcDogQmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1lZGlhbiksIHThu6kgcGjDom4gduG7iyAocXVhcnRpbGUpIHbDoCBnacOhIHRy4buLIG5nb+G6oWkgbOG7hyAob3V0bGllcikgY2hvIG3hu5dpIMSR4buZIGLDs25nLg0KICogUsOidTogQmnhu4N1IHRo4buLIHBo4bqhbSB2aSBnacOhIHRy4buLIGPhu6dhIGtpbSBjxrDGoW5nIGNobyBt4buXaSDEkeG7mSBiw7NuZy4NCiAqIFRpw6p1IMSR4buBOiAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyDEkOG7mSBiw7NuZyIuDQogKiBOaMOjbiB0cuG7pWMgWDogIsSQ4buZIGLDs25nIi4NCiAqIE5ow6NuIHRy4bulYyBZOiAiR2nDoSBiw6FuIi4NCiANCioqUGjDom4gdMOtY2g6KioNCg0KROG7sWEgdsOgbyBiaeG7g3UgxJHhu5MsIHRhIGPDsyB0aOG7gyB0aOG6pXk6DQoNCiAqIE5ow6xuIGNodW5nLCBnacOhIGLDoW4gdMSDbmcga2hpIMSR4buZIGLDs25nIHTEg25nLg0KICogS2ltIGPGsMahbmcgY8OzIMSR4buZIGLDs25nICJJZGVhbCIgY8OzIGdpw6EgYsOhbiBjYW8gbmjhuqV0Lg0KICogS2ltIGPGsMahbmcgY8OzIMSR4buZIGLDs25nICJGYWlyIiBjw7MgZ2nDoSBiw6FuIHRo4bqlcCBuaOG6pXQuDQogKiBUdXkgbmhpw6puLCBjxaluZyBjw7Mgc+G7sSBiaeG6v24gxJHhu5luZyBs4bubbiB0cm9uZyBnacOhIGLDoW4gY2hvIGPDuW5nIG3hu5l0IMSR4buZIGLDs25nLg0KICogTeG7mXQgc+G7kSB2acOqbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgYsOzbmcgIkZhaXIiIGPDsyBnacOhIGLDoW4gY2FvIGjGoW4gc28gduG7m2kgbmjhu69uZyB2acOqbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgYsOzbmcgIkdvb2QiLg0KDQojIyBQaMOibiBi4buRIGdpw6EgYsOhbiB0aGVvIMSR4buZIMSR4buRaSB44bupbmc6DQoNCmBgYCB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBjdXQsIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIlBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gxJDhu5kgxJHhu5FpIHjhu6luZyIsDQogICAgICAgeCA9ICLEkOG7mSDEkeG7kWkgeOG7qW5nIiwNCiAgICAgICB5ID0gIkdpw6EgYsOhbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIG3hu6ljIMSR4buZIMSR4buRaSB44bupbmcgY+G7p2Ega2ltIGPGsMahbmcgKEZhaXIsIEdvb2QsIFZlcnkgR29vZCwgSWRlYWwpLg0KICogVHLhu6VjIFk6IEhp4buDbiB0aOG7iyBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcuDQogKiBI4buZcCBiaeG7g3UgxJHhu5M6IEJp4buDdSB0aOG7iyBnacOhIHRy4buLIHRydW5nIGLDrG5oIChtZWRpYW4pLCB04bupIHBow6JuIHbhu4sgKHF1YXJ0aWxlKSB2w6AgIGdpw6EgdHLhu4sgbmdv4bqhaSBs4buHIChvdXRsaWVyKSBjaG8gbeG7l2kgbeG7qWMgxJHhu5kgxJHhu5FpIHjhu6luZy4NCiAqIFRpw6p1IMSR4buBOiAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyDEkOG7mSDEkeG7kWkgeOG7qW5nIi4NCiAqIE5ow6NuIHRy4bulYyBYOiAixJDhu5kgxJHhu5FpIHjhu6luZyIuDQogKiBOaMOjbiB0cuG7pWMgWTogIkdpw6EgYsOhbiIuDQogDQoqKlBow6JuIHTDrWNoOioqDQoNCkThu7FhIHbDoG8gYmnhu4N1IMSR4buTLCB0YSBjw7MgdGjhu4MgdGjhuqV5Og0KIA0KICogTmjDrG4gY2h1bmcsIGdpw6EgYsOhbiB0xINuZyBraGkgxJHhu5kgxJHhu5FpIHjhu6luZyB0xINuZy4NCiAqIEtpbSBjxrDGoW5nIGPDsyDEkeG7mSDEkeG7kWkgeOG7qW5nIGNhbyAoVmVyeSBHb29kLCBJZGVhbCkgY8OzIGdpw6EgYsOhbiBjYW8gaMahbiBzbyB24bubaSBraW0gY8awxqFuZyBjw7MgxJHhu5kgxJHhu5FpIHjhu6luZyB0aOG6pXAgKEZhaXIsIEdvb2QpLg0KICogVHV5IG5oacOqbiwgY8WpbmcgY8OzIHPhu7EgYmnhur9uIMSR4buZbmcgbOG7m24gdHJvbmcgZ2nDoSBiw6FuIGNobyBjw7luZyBt4buZdCBt4bupYyDEkeG7mSDEkeG7kWkgeOG7qW5nLg0KICogTeG7mXQgc+G7kSB2acOqbiBraW0gY8awxqFuZyBjw7MgxJHhu5kgxJHhu5FpIHjhu6luZyBjYW8gY8OzIGdpw6EgYsOhbiB0aOG6pXAgaMahbiBzbyB24bubaSBuaOG7r25nIHZpw6puIGtpbSBjxrDGoW5nIGPDsyDEkeG7mSDEkeG7kWkgeOG7qW5nIHRo4bqlcC4NCg0KIyMgUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBraHUgduG7sWM6DQoNCmBgYCB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSBmYWN0b3IoY3V0KSwgeSA9IHByaWNlLCBmaWxsID0gY3V0KSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGxhYnModGl0bGUgPSAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBraHUgduG7sWMiLA0KICAgICAgIHggPSAiS2h1IHbhu7FjIiwNCiAgICAgICB5ID0gIkdpw6EgYsOhbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKipHaeG6o2kgdGjDrWNoIHPGoSDEkeG7kzoqKg0KDQogKiBUcuG7pWMgWDogSGnhu4NuIHRo4buLIGtodSB24buxYyBraGFpIHRow6FjIGtpbSBjxrDGoW5nLg0KICogVHLhu6VjIFk6IEhp4buDbiB0aOG7iyBnacOhIGLDoW4gY+G7p2Ega2ltIGPGsMahbmcuDQogKiBI4buZcDogQmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1lZGlhbiksIHThu6kgcGjDom4gduG7iyAocXVhcnRpbGUpIHbDoCBnacOhIHRy4buLIG5nb+G6oWkgbOG7hyAob3V0bGllcikgY2hvIG3hu5dpIGtodSB24buxYy4NCiAqIE3DoHUgc+G6r2MgY+G7p2EgaOG7mXA6IEJp4buDdSB0aOG7iyBraHUgduG7sWMga2hhaSB0aMOhYyBraW0gY8awxqFuZy4NCiAqIFRpw6p1IMSR4buBOiAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBraHUgduG7sWMiLg0KICogTmjDo24gdHLhu6VjIFg6ICJLaHUgduG7sWMiLg0KICogTmjDo24gdHLhu6VjIFk6ICJHacOhIGLDoW4iLg0KIA0KKipQaMOibiB0w61jaDoqKg0KDQpE4buxYSB2w6BvIGJp4buDdSDEkeG7kywgdGEgY8OzIHRo4buDIHRo4bqleToNCg0KICogR2nDoSBiw6FuIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIGNhbyBuaOG6pXQg4bufIGtodSB24buxYyAiSWRlYWwiLg0KICogR2nDoSBiw6FuIHRydW5nIGLDrG5oIGPhu6dhIGtpbSBjxrDGoW5nIHRo4bqlcCBuaOG6pXQg4bufIGtodSB24buxYyAiRmFpciIuDQogKiBDw7Mgc+G7sSBraMOhYyBiaeG7h3QgduG7gSBnacOhIGLDoW4gdHJ1bmcgYsOsbmggZ2nhu69hIGPDoWMga2h1IHbhu7FjLg0KICogS2h1IHbhu7FjICJJZGVhbCIgY8OzIGdpw6EgYsOhbiB0cnVuZyBiw6xuaCBjYW8gaMahbiB2w6Agw610IGJp4bq/biDEkeG7mW5nIGjGoW4gc28gduG7m2kgY8OhYyBraHUgduG7sWMga2jDoWMuDQoNCiMjIFBow6JuIGLhu5EgZ2nDoSBiw6FuIHRoZW8gdGjGsMahbmcgaGnhu4d1Og0KDQpgYGAge3J9DQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4ID0gY3V0LCB5ID0gcHJpY2UpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgbGFicyh0aXRsZSA9ICJQaMOibiBi4buRIGdpw6EgYsOhbiB0aGVvIFRoxrDGoW5nIGhp4buHdSIsDQogICAgICAgeCA9ICJUaMawxqFuZyBoaeG7h3UiLA0KICAgICAgIHkgPSAiR2nDoSBiw6FuIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKkdp4bqjaSB0aMOtY2ggc8ahIMSR4buTOioqDQoNCiAqIFRy4bulYyBYOiBIaeG7g24gdGjhu4sgdMOqbiB0aMawxqFuZyBoaeG7h3UgY+G7p2Ega2ltIGPGsMahbmcuDQogKiBUcuG7pWMgWTogSGnhu4NuIHRo4buLIGdpw6EgYsOhbiBj4bunYSBraW0gY8awxqFuZy4NCiAqIEjhu5lwIGJp4buDdSDEkeG7kzogQmnhu4N1IHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggKG1lZGlhbiksIHThu6kgcGjDom4gduG7iyAocXVhcnRpbGUpIHbDoCBnacOhIHRy4buLIG5nb+G6oWkgbOG7hyAob3V0bGllcikgY2hvIG3hu5dpIHRoxrDGoW5nIGhp4buHdS4NCiAqIFRpw6p1IMSR4buBOiAiUGjDom4gYuG7kSBnacOhIGLDoW4gdGhlbyBUaMawxqFuZyBoaeG7h3UiLg0KICogTmjDo24gdHLhu6VjIFg6ICJUaMawxqFuZyBoaeG7h3UiLg0KICogTmjDo24gdHLhu6VjIFk6ICJHacOhIGLDoW4iLg0KIA0KKipQaMOibiB0w61jaDoqKg0KDQpE4buxYSB2w6BvIGJp4buDdSDEkeG7kywgdGEgY8OzIHRo4buDIHRo4bqleTogQ8OzIHPhu7Ega2jDoWMgYmnhu4d0IHbhu4EgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIHbDoCBwaMOibiBi4buRIGdpw6EgYsOhbiBnaeG7r2EgY8OhYyB0aMawxqFuZyBoaeG7h3UuDQoNClbDrSBk4bulOg0KDQogKiBUaMawxqFuZyBoaeG7h3UgIklkZWFsIiBjw7MgZ2nDoSBiw6FuIHRydW5nIGLDrG5oIGNhbyBuaOG6pXQuDQogKiBUaMawxqFuZyBoaeG7h3UgIkZhaXIiIGPDsyBnacOhIGLDoW4gdHJ1bmcgYsOsbmggdGjhuqVwIG5o4bqldC4NCiAqIFRoxrDGoW5nIGhp4buHdSAiR29vZCIgdsOgICJWZXJ5IEdvb2QiIGPDsyBnacOhIGLDoW4gdHJ1bmcgYsOsbmggdMawxqFuZyDEkeG7kWkgZ+G6p24gbmhhdS4NCg==