Sử dụng bộ dữ liệu có sẵn trong R

  • Bộ dữ liệu được dụng là bộ dữ liệu Diamonds có sẵn trong R

  • Bộ dữ liệu diamonds trong R là một tập dữ liệu phổ biến được sử dụng trong các ví dụ và hướng dẫn về phân tích dữ liệu. Nó bao gồm thông tin về 53.940 viên kim cương cắt tròn, với 10 biến mô tả các đặc điểm khác nhau của mỗi viên kim cương:

    • carat: Trọng lượng của viên kim cương (carat)
    • cut: Chất lượng đường cắt (Fair, Good, Very Good, Ideal, Premium)
    • color: Màu sắc của viên kim cương (từ D (tốt nhất) đến J (kém nhất))
    • price: Giá trị của viên kim cương (đơn vị USD)
    • clarity: Độ trong suốt của viên kim cương (từ IF (tốt nhất) đến I1 (kém nhất))
    • depth: Tỷ lệ phần trăm độ sâu (tính theo z / x)
    • table: Chiều rộng của mặt bàn (tính theo % của đường kính)
    • x: Chiều dài của viên kim cương (mm)
    • y: Chiều rộng của viên kim cương (mm)
    • z: Độ sâu của viên kim cương (mm)
library(DT)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
h<- diamonds
datatable(h)
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html

Phân tích dữ liệu với Bar-Chart

Giới thiệu

  • Biểu đồ thanh (Bar chart) là một dạng biểu đồ thống kê thị trường phổ biến, sử dụng các thanh dọc hoặc ngang để biểu diễn dữ liệu theo thời gian hoặc theo các nhóm khác nhau. Mỗi thanh đại diện cho một giá trị cụ thể, và độ dài của thanh thể hiện giá trị đó.

  • Ý nghĩa của biểu đồ thanh:

    • So sánh dữ liệu: Biểu đồ thanh giúp so sánh trực quan các giá trị khác nhau trong cùng một nhóm hoặc giữa các nhóm khác nhau.
    • Xác định xu hướng: Biểu đồ thanh có thể giúp xác định xu hướng tăng hoặc giảm của dữ liệu theo thời gian.
    • Phân bố dữ liệu: Biểu đồ thanh giúp so sánh sự phân bố của dữ liệu giữa các nhóm khác nhau.

Biểu đồ

library(dplyr)
install.packages('ggplot2')
## Warning: package 'ggplot2' is in use and will not be installed
library(ggplot2)

Giải thích chi tiết:

  • ggplot(aes(x = cut)): Khởi tạo một biểu đồ ggplot với cut là biến được ánh xạ đến trục x.
  • geom_bar(): Thêm một layer hình thanh vào biểu đồ. Mỗi thanh đại diện cho một mức độ cắt kim cương, và độ cao của thanh thể hiện số lượng kim cương có mức độ cắt đó.
  • labs(x = ‘Loại’, y = ‘Số lượng’): Thêm nhãn cho trục x và trục y.
library(tidyverse)
library(scales)
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
h %>% ggplot(aes(x=cut))+geom_bar()+
  labs(x='Loại',y='Số lượng',title = 'Hình 1.1: Số lượng của những loại kim cương theo biến cut')

Giải thích câu lệnh

  • library(tidyverse): Tải thư viện tidyverse, cung cấp nhiều hàm hữu ích cho việc thao tác và trực quan hóa dữ liệu.
  • library(scales): Tải thư viện scales, cung cấp các hàm để định dạng trục và nhãn trong biểu đồ.
  • h <- diamonds: Gán dữ liệu từ bộ dữ liệu diamonds vào biến h.
  • h %>% ggplot(aes(x = cut)): Tạo biểu đồ ggplot dựa trên dữ liệu h, với trục x thể hiện biến cut (chất lượng cắt kim cương).
  • geom_bar(): Thêm layer hình thanh vào biểu đồ.
  • labs(x = ‘Loại’, y = ‘Số lượng’): Thêm nhãn cho trục x (Loại) và trục y (Số lượng).

Nhận xét kết quả

Kết quả nhận được là một biểu đồ dạng Bar_Chart thể hiện gồm số lượng của những loại kim cương(Fair, Good, Very good, Premium, Ideal).Qua biểu đồ trên chúng ta sẽ thấy được số lượng của Ideal chiếm nhiều nhất cụ thể là lớn hơn 20000 kim cương trong 5 loại trên. Chiếm tỷ lệ thấp nhất là Fair là nhỏ hơn 5000 kim cương . Số lượng kim cương giảm dần từ Ideal đến Fair. Có sự chênh lệch lớn giữa loại lớn nhất và thấp nhất

table(diamonds$clarity)
## 
##    I1   SI2   SI1   VS2   VS1  VVS2  VVS1    IF 
##   741  9194 13065 12258  8171  5066  3655  1790
h %>% ggplot(aes(x= clarity)) + 
      geom_bar( )+
      labs(x = 'Clarity', y= ' Số lượng', title='Hình 1.2: Số lượng của những loại kim cương theo độ trong suốt')

Giải thích

Kết quả nhận được là một biểu đồ dạng Bar_Chart thể hiện gồm số lượng của những loại kim cương (I1,SI2,SI1,VS2,VS1,VVS2,VVS1,IF) .Trục x thể hiện độ trong suốt kim cương, từ thấp đến cao (từ “I1” đến “IF”). - Trục y thể hiện số lượng kim cương tương ứng với mỗi cấp độ độ trong suốt. Qua biểu đồ trên chúng ta sẽ thấy được số lượng của SI1 chiếm nhiều nhất cụ thể là lớn hơn 10000 kim cương trong 8 loại trên. Chiếm tỷ lệ thấp nhất là I1 là nhỏ hơn 2500 kim cương .Có sự chênh lệch lớn giữa loại lớn nhất và thấp nhất

h %>% group_by(cut) %>% summarise(n = n()) %>% ggplot(aes(cut,n))+ 
 geom_col(fill='black')+
   geom_text(aes(label = n), vjust = 1, color = 'pink') + 
   labs(x = 'Loại', y = 'Số lượng', title='Hình 1.3:Số lượng của những loại kim cương theo biến cut ')

Giải thích câu lệnh

Tạo nhóm và đếm số lượng:

  • h %>% group_by(cut): Nhóm dữ liệu theo biến cut (chất lượng cắt kim cương).
  • summarise(n = n()): Tính tổng số lượng kim cương trong mỗi nhóm. Tạo biểu đồ:
  • ggplot(aes(cut,n)): Khởi tạo một biểu đồ ggplot với cut là biến được ánh xạ đến trục x và n là biến được ánh xạ đến trục y.
  • geom_col(fill=‘black’): Thêm layer hình cột vào biểu đồ với màu đen.
  • geom_text(aes(label = n), vjust = 1, color = ‘pink’): Thêm layer văn bản vào biểu đồ, hiển thị số lượng kim cương trên mỗi cột với màu hồng.
  • labs(x = ‘Loại’, y = ‘Số lượng’): Thêm nhãn cho trục x (Loại) và trục y (Số lượng).

Nhận xét kết quả

  • Kết quả nhận được là một biểu đồ dạng Bar_Chart thể hiện gồm số lượng của những loại kim cương(Fair, Good, Very good, Premium, Ideal)
  • Nhìn biểu đồ chúng ta sẽ biết rõ được số lượng của mỗi loại:
    • Fair có 1610 kim cương
    • Good có 4906 kim cương
    • Very good 12082 kim cương
    • Premium 13791 kim cương
    • Ideal có 21551 kim cương
  • Qua đây chúng ta sẽ thấy được số lượng của Ideal chiếm nhiều nhất cụ thể là 21551 kim cương trong 5 loại trên
  • Chiếm tỷ lệ thấp nhất là Fair là 1610 kim cương
  • Số lượng kim cương giảm dần từ Ideal đến Fair
  • Số lượng loại lớn nhất và nhỏ chênh lệch với nhau hơn 13 lần
h %>% group_by(color) %>% summarise(n = n()) %>% ggplot(aes(color,n))+ 
 geom_col(fill='maroon')+
   geom_text(aes(label = n), vjust =0, color = 'black') + 
   labs(x = 'Color', y = 'Số lượng', title= 'Hình 1.4: Số lượng của những loại kim cương theo màu')

Nhận xét kết quả

  • Nhìn biểu đồ ta thấy, Kết quả nhận được là một biểu đồ dạng Bar_Chart thể hiện gồm số lượng của cột color (hay còn gọi là nước kim cương): D,E,F,G,H,I,J
  • Thang này được sử dụng để đánh giá mức độ không màu của kim cương, với D là cấp độ cao nhất (không màu) và J là cấp độ thấp nhất (màu trắng).
  • Nhìn biểu đồ chúng ta sẽ biết rõ được số lượng của mỗi loại:
    • D chiếm 6775 viên
    • E chiếm 9797 viến
    • F chiến 9542 viến
    • G chiếm 11292 viên
    • H chiếm 8304 viên
    • I chiếm 5422 viên
    • J chiếm 2808 viên
  • Qua đây chúng ta sẽ thấy được số lượng của G chiếm nhiều nhất cụ thể là 11292 kim cương trong 7 color trên
  • Chiếm tỷ lệ thấp nhất là J cũng là color thấp nhất trong các color là 2808 kim cương
  • Qua biều đồ trên ta thấy color D là color có màu sắc tốt nhất chiếm 12.56% trên tổng số viên kim cương
h %>% group_by(clarity) %>% summarise(n = n()) %>% ggplot(aes(clarity,n))+ 
 geom_col(fill='navyblue')+
   geom_text(aes(label = n), vjust = 1, color = 'pink') + 
   labs(x = 'Clarity', y = 'Số lượng',title='Hình1.5: Số lượng kim cương theo độ trong suốt')

Nhận xét kết quả

  • Nhìn biểu đồ ta thấy, Kết quả nhận được là một biểu đồ dạng Bar_Chart thể hiện gồm số lượng của cột Clarity(độ trong suốt của kim cương): I1, SI2, SI1, VS2, VS1, VVS1, IF
  • Là các cấp độ đánh giá độ tinh khiết (Clarity) của kim cương theo tiêu chuẩn GIA (Viện Đá Quý Hoa Kỳ). Thang đo này được sử dụng để phân loại mức độ tạp chất và bao thể bên trong kim cương, với IF là cấp độ cao nhất (hoàn toàn tinh khiết) và I1 là cấp độ thấp nhất (nhiều tạp chất và bao thề)
  • Nhìn biểu đồ chúng ta sẽ biết rõ được số lượng của mỗi loại:
    • I1 chiếm 741 kim cương đồng thời đây cũng là cấp độ thấp nhất trong 8 cấp đọ trong suốt và chiếm tỷ lệ 1.37% trong 53940 viên kim cương.
    • SI2 chiếm 9194 viên
    • SI1 chiếm 13065 viên đây cũng là mức độ chiếm nhiều viên kim cương nhất trong các loại, đây là loại Ít tạp chất (Slightly Included 1) - Có thể nhìn thấy một số tạp chất nhỏ dưới độ phóng đại 10x. Chiếm 24.22% trên tổng số.
    • VS2 chiếm 12258 viên , đây cũng là một loại chiếm tỷ lệ khá cao trên tổng thể cụ thể là 22.73%. Rất ít tạp chất (Very Slightly Included 2) - Có thể nhìn thấy một vài tạp chất nhỏ hơn so với VS1 dưới độ phóng đại 10x
    • VS1 chiếm 8171 viên
    • VVS2 chiếm 5066 viên kim cương
    • VVS1 chiếm 3655 viên kim
    • IF chiếm 1790 viên đây là hoàn toàn tinh khiết (Internally Flawless) - Không có bất kỳ tạp chất hoặc bao thể nào nhìn thấy được dưới độ phóng đại 10x. Do hoàn toàn tinh khiết nên giá thành của viên kim cương rất cao.
h%>% group_by(cut) %>% summarise(n=n())%>% ggplot(aes(cut,n))+ geom_col(fill='skyblue')+geom_text(aes(label=percent(n/length(h$carat))),vjust=1, color='black')+labs(x='Loại',y='Số lượng',title='Hình1.6: Số lượng kim cương theo chất lượng đường cắt ')

Giải thích câu lệnh

  • h %>% group_by(cut): Nhóm dữ liệu theo biến cut (chất lượng cắt kim cương).
  • summarise(n=n()): Tính tổng số lượng kim cương trong mỗi nhóm, gán kết quả vào biến n.
  • percent(…)): Tính tỷ lệ phần trăm của n (số lượng kim cương trong mỗi nhóm) so với tổng số lượng kim cương (length(h$carat)).
  • ggplot(aes(cut,n)): tạo một biểu đồ ggplot với cut là biến được ánh xạ đến trục x và n là biến được ánh xạ đến trục y (ban đầu).
  • geom_col(fill=‘skyblue’): Thêm layer hình cột vào biểu đồ với màu xanh da trời.
  • geom_text(aes(label= percent(n/length(h\(carat))),vjust = 1, color= 'black'): Thêm layer văn bản vào biểu đồ. - aes(label= percent(n/length(h\)carat))): Gán giá trị tỷ lệ phần trăm được tính toán ở bước 2 cho nhãn văn bản.
    • vjust = 1: Vị trí văn bản được điều chỉnh lên trên cùng của cột (vjust = 1).
    • color= ‘black’: Văn bản có màu đen.
  • labs(x = ‘Loại’, y= ’ Số lượng’): Thêm nhãn cho trục x (Loại) và trục y (Số lượng).

Biểu đồ này tương tự như biểu đồ trước, nhưng thay vì hiển thị số lượng kim cương tuyệt đối (n), nó hiển thị tỷ lệ phần trăm của mỗi nhóm so với tổng số kim cương. Tỷ lệ phần trăm được tính bằng cách chia số lượng kim cương trong mỗi nhóm (n) cho tổng số kim cương (length(h$carat)) và nhân với 100 để chuyển thành dạng phần trăm. Văn bản hiển thị trên mỗi cột thể hiện tỷ lệ phần trăm này.

Nhận xét kết quả

  • Kết quả nhận được là một biểu đồ dạng Bar_Chart thể hiện gồm số lượng của những loại kim cương(Fair, Good, Very good, Premium, Ideal)
  • Nhìn biểu đồ chúng ta sẽ biết rõ được tỷ lệ phân trăm của (tính bằng cách chia số lượng kim cương trong mỗi nhóm (n) cho tổng số kim cương (length(h$carat)) và nhân với 100 để chuyển thành dạng phần trăm) của mỗi loại kim cương:
    • Fair chiếm 3% kim cương
    • Good chiếm 9.1% kim cương
    • Very good chiếm 22.4% kim cương
    • Premium chiếm 25.6% kim cương
    • Ideal chiếm 40% kim cương
  • Qua đây chúng ta sẽ thấy được số lượng của Ideal chi55ua đây chúng ta sẽ thấy được số lượng của Ideal chi55ếm tỷ lên phân trăm số lượng kim cương nhiều nhất 40% trên 100%
  • Chiếm tỷ lệ thấp nhất là Fair là 3% kim cương
  • Số lượng kim cương giảm dần từ Ideal đến Fair
  • Số lượng loại lớn nhất và nhỏ chênh lệch với nhau hơn 13 lần
h%>% group_by(cut) %>% summarise(v= var(carat)) %>%
  ggplot(aes(x = cut,y = v)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(v,2)), vjust = 2, color = 'pink') +
    labs(x = 'cut', y = 'Var',title='Hình 1.7:Phương sai của carat theo biến chất lượng đường cắt ')

Giải thích câu lệnh

  • summarise(v = var(carat)): Trong mỗi nhóm được tạo ở bước 2, mã này tính toán phương sai của biến carat. Kết quả là một tập dữ liệu mới với các cột cut và v, trong đó v đại diện cho phương sai của mỗi nhóm cut.

Nhận xét kết quả

  • Phương sai (tiếng Anh: Variance) là phép đo mức chênh lệch giữa các số liệu trong một tập dữ liệu trong thống kê
  • Dây là là một biểu đò dang Bar_Chart thể hiện mức độ chenh lệch của biến cut(chất lượn đường cắt) theo biến cut
  • Biểu đồ cho thấy mức độ chênh lệch giữa các biến của “cut” dao động trong khoảng 0.19 đến 0.27
  • Nhóm “Fair” có mức độ chênh lệch cao nhất (khoảng 0.27 ).
  • Nhóm “Ideal” có mức đọ chênh lệch thấp nhất (khoảng 0.19 ).

Suy ra, kiểu cắt kim cương ảnh hưởng đến mức độ chênh lệch của biến “carat”.Kim cương có kiểu cắt “Fair và Premiuml” có mức đọ chênh lệch cao nhất về biến “carat” tức là có độ biến thiên cao nhất về kích thước carat. Điều này có nghĩa là kim cương trong nhóm “Fair và Premium” có thể có kích thước carat chênh lệch nhau đáng kể. Vd:Phương sai của Fair cao hơn Ideal. Điều này có nghĩa là trọng lượng của kim cương Fair phân tán rộng hơn quanh giá trị trung bình

h %>% group_by(cut,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_text(aes(label = n),vjust = 0, color = 'black') +
    labs(x = 'Loại', y = 'Số lượng',title='Hình1.8: Số lượng theo chất lượng đường cắt và màu')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích câu lệnh

  • Hàm group_by() từ thư viện dplyr được sử dụng để nhóm các hàng trong h theo các giá trị duy nhất của hai biến cut và color.Điều này giúp phân tích dữ liệu riêng biệt cho từng nhóm được tạo thành từ sự kết hợp của các giá trị cut và color.
  • Hàm summarise() từ thư viện dplyr được sử dụng để tính toán một tập hợp các thống kê tóm tắt cho mỗi nhóm được tạo ra ở bước 2.Biểu thức n = n() bên trong summarise() đếm số lượng các phần tử trong mỗi nhóm và đặt kết quả vào cột mới có tên n.
  • Hàm ggplot() từ thư viện ggplot2 được sử dụng để khởi tạo một đối tượng ggplot, nền tảng để xây dựng biểu đồ.
  • Biểu thức aes(x = cut, y = n) trong ggplot() xác định các biến được sử dụng để ánh xạ dữ liệu vào các trục x và y của biểu đồ.
  • Biến cut được sử dụng trên trục x, đại diện cho các nhóm (categories).
  • Biến n được sử dụng trên trục y, đại diện cho số lượng phần tử trong mỗi nhóm.
  • Hàm geom_col() tạo ra một biểu đồ cột.
  • Tham số position = ‘dodge’ đảm bảo các cột được xếp cạnh nhau một cách tách biệt, tránh chồng chéo lên nhau, giúp dễ dàng phân biệt các nhóm khác nhau.
  • Hàm facet_wrap() từ thư viện ggplot2 được sử dụng để tạo ra nhiều biểu đồ con, mỗi biểu đồ con thể hiện dữ liệu cho một giá trị duy nhất của biến color.Ký hiệu ~ trước color cho biết color sẽ được sử dụng để tạo ra các mặt (facet) của biểu đồ.
  • Hàm geom_text() từ thư viện ggplot2 được sử dụng để thêm các nhãn dữ liệu vào biểu đồ.Biểu thức aes(label = n) xác định rằng nội dung của nhãn sẽ lấy từ cột n, chứa số lượng các phần tử trong mỗi nhóm.Tham số vjust = 2 điều chỉnh vị trí của nhãn theo chiều dọc, di chuyển chúng lên 2 đơn vị so với vị trí mặc định.Tham số color = ‘green’ đặt màu của nhãn thành xanh lục.
  • Hàm labs() từ thư viện ggplot2 được sử dụng để đặt nhãn cho các trục x và y của biểu đồ.Thẻ x = ‘Loại’ đặt nhãn cho trục x thành “Loại” (nghĩa là “Hạng mục”).Thẻ y = ‘Số lượng’ đặt nhãn cho trục y thành “Số lượng” (nghĩa là “Số lượng phần tử”).

Nhận xét kết quả

  • Ta nhận được là một biểu đồ dạng Bar_Chart thể hiện số lượng của các loại kim cương trong biến cut theo từng nhóm gồm 7 biểu đồ nhỏ tương ứng với từng loại trong cột Color(tức là các loại nước kim cương )(D,E,F,G,H,I,J)
  • Nhìn hình 1.8 ta thấy loại Ideal luôn có số lượng lớn nhất trong 7 nhóm trong biến Color
  • Ngược lại là loại Fair luôn có số lương thấp nhất trong 7 nhóm
  • Các biểu đồ luôn có xu hướng tăng số lường từ Fair đến Ideal
  • Trong 7 biểu đồ thì biểu đồ về G chiếm số lượng trong các loại kim cương là lớn nhất cụ thể là chiếm 20.8% trên tổng. Ngược lại thấp nhất là nước J chiếm 5.21%. Suy ra ta thấy khi chia nhỏ ra từng nhóm như vầy chúng ta sẽ dễ dàng nhìn thấy sự phân bố số lượng của mỗi loại.
h %>% group_by(cut,clarity) %>% summarise(n=n()) %>%
  ggplot(aes(x = cut,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~clarity) +
    geom_text(aes(label = n),vjust = 0
            , color = 'red') +
    labs(x = 'Loại', y = 'Số lượng', title='Hình 1.9: Số lượng kím cương theo chất lượng đường cắt và độ trong suốt')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích câu lệnh*

  • group_by(cut, clarity): Nhóm dữ liệu theo các cột cut và clarity. Điều này tạo ra các nhóm riêng biệt cho mỗi giá trị kết hợp duy nhất của cut và clarity
  • Nhóm dữ liệu theo cut và clarity.

Tính số lượng quan sát trong mỗi nhóm.

Tạo biểu đồ thanh với một thanh cho mỗi kết hợp duy nhất của cut và clarity, được tô màu theo clarity.

Vị trí các thanh cạnh nhau để tránh chồng chéo.

Thêm nhãn văn bản để hiển thị số lượng trên các thanh.

Nhãn trục và thêm tiêu đề cho biểu đồ.

Nhận xét kết quả

  • Ta nhận được là một biểu đồ dạng Bar_Chart thể hiện số lượng của các loại kim cương trong biến cut theo từng nhóm gồm 7 biểu đồ nhỏ tương ứng với từng loại trong cột Clarity(tức là các loại nước kim cương )(I1,SI2,SI1,VS2,VS1,VVS2,VVS1,Ì)
  • Số lượng kim cương loại Ideal luôn chiếm số lượng nhiều trong các nhóm biẻu đò nhỏ
  • Trong đó ta thấy SI1( đây là loại Ít tạp chất (Slightly Included 1) - Có thể nhìn thấy một số tạp chất nhỏ dưới độ phóng đại 10x) chiếm số lượng nhiều nhất trong các nhóm cụ thể là 24.22%. Ngược lại thấp nhất là I1(cấp độ thấp nhất trong 8 cấp đọ trong suốt) chiếm 1.37% trên tổng thể.
h %>% group_by(clarity,color) %>% summarise(n=n()) %>%
  ggplot(aes(x = clarity,y = n)) +
    geom_col(position = 'dodge') +
    facet_wrap(~color) +
    geom_text(aes(label = n),vjust = 0, color = 'red') +
    labs(x = 'clarity', y = 'Số lượng',title='Hình 1.10: Số lượng kim cương theo độ trong suốt và màu')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Nhận xét biểu đồ

  • Ta nhận được là một biểu đồ dạng Bar_Chart thể hiện số lượng của các loại kim cương trong biến clarity theo từng nhóm gồm 7 biểu đồ nhỏ tương ứng với từng loại trong cột color(tức là các màu kim cương )(D,E,F,G,H,I,J)
  • Qua đây ta sẽ thấy rõ độ phân tán về số lượng của của cột clarity theo các nhóm colorcolor
  • Nhìn vào biểu đồ ta thấy số lượng của color G về độ trong suốt có lớn nhất cụ thể là 20.93%, ngược lại là color J thấp nhất với 5.21% Nó sẽ phân chia dữ liệu thành các nhóm riêng biệt, mỗi nhóm chứa các quan sát có cùng độ rõ ràng và màu sắc. Bên trong mỗi nhóm, hàm summarise được sử dụng để đếm số lượng quan sát và gán kết quả cho một biến mới được đặt tên là n. Biến n này sẽ chứa số lượng quan sát có cùng độ rõ ràng và màu sắc . Điều này cho phép bạn dễ dàng so sánh phân bố số lượng quan sát theo độ rõ ràng trên các màu sắc khác nhau.
h%>% group_by(cut, color)%>%summarise(m=mean(table))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'cut', y= 'Mean',title='Hình 1.11: Giá trị trung bình của table theo cut và color')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Biểu thức aes(label = round(m)) xác định rằng nội dung của nhãn sẽ lấy từ cột m, chứa trung bình của bảng tần suất, nhưng được làm tròn trước khi hiển thị.

Nhận xét biểu đồ

Ta có thể nhanh chóng nắm bắt và so sánh các giá trị trung bình của biến “table” trong các nhóm khác nhau được xác định bởi “cut” và “color”. Ý nghĩa của biểu đồ là hiển thị trung bình của cột “table” theo các mức độ “cut” và “color”, giúp hiểu rõ hơn về sự phân bố của dữ liệu. Dưới đây là ví dụ về cách sử dụng biểu đồ này: Biểu đồ này có thể được sử dụng trong ngành công nghiệp kim hoàn để so sánh trung bình của cột “table” (một chỉ số về chất lượng của viên kim cương) giữa các mức độ “cut” (cách xử lý viên kim cương) và “color” (màu sắc của viên kim cương). Điều này có thể giúp cho các nhà sản xuất kim cương hiểu được mối quan hệ giữa cách xử lý và chất lượng của sản phẩm.

h%>% group_by(cut, color)%>%summarise(m=var(table))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge',fill='grey')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=0, color='red')+ labs(x= 'cut', y= 'Var',title='Hình 1.12: Phương sai của table theo cut và color')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Nhận xét biểu đồ

Tác dụng của biểu đồ này là hiển thị phương sai của cột “table” theo các mức độ “cut” và “color”, cho ta cái nhìn về sự biến động của dữ liệu. Qua đây ta thấy được phương sai của mỗi nhóm color đều có xu hướng giảm dần từ Fair xuống Ideal

Suy ra, kiểu cắt kim cương ảnh hưởng đến mức độ chênh lệch của biến “carat”.Kim cương có kiểu cắt “Fair và Premiuml” có mức đọ chênh lệch cao nhất về biến “carat” tức là có độ biến thiên cao nhất về kích thước carat. Điều này có nghĩa là kim cương trong nhóm “Fair và Premium” có thể có kích thước carat chênh lệch nhau đáng kể.

Ví dụ:

Chất lượng cắt “Very Good”: Mặt cắt trên: Giả sử cột “Very Good” trên mặt cắt trên có chiều cao lớn hơn cột “Very Good” trên mặt cắt dưới. Điều này có nghĩa là số lượng kim cương màu sắc 1 (được xác định trong code) có phương sai cao hơn khi chất lượng cắt là “Very Good”. Nói cách khác, số lượng kim cương có thể khác biệt nhiều hơn giữa các chất lượng cắt “Very Good” cho màu sắc 1 so với màu sắc 2. So sánh: Bạn có thể so sánh trực quan phương sai của số lượng kim cương theo chất lượng cắt giữa hai màu sắc khác nhau bằng cách quan sát chiều cao tương đối của các cột trong cùng một nhóm chất lượng cắt trên hai mặt cắt riêng biệt.

h%>% group_by(cut, color)%>%summarise(m=mean(depth))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=1, color='orange')+ labs(x= 'cut', y= 'Mean',title='Hình 1.13: Giá trị trung bình của depth theo cut và color')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Nhận xét kết quả

Ta có thể nhanh chóng nắm bắt và so sánh các giá trị trung bình của biến “depth” trong các nhóm khác nhau được xác định bởi “cut” và “color”. Nhìn vào kết quả ta thấy được giá ttrịtrung bình của mỗi loại cut trong các nhóm color dao đồng trong khoảng 61 đến 64. Ý nghĩa của biểu đồ là hiển thị trung bình của cột “depth” theo các mức độ “cut” và “color”, giúp hiểu rõ hơn về sự phân bố của dữ liệu. Dưới đây là ví dụ về cách sử dụng biểu đồ này: Biểu đồ này có thể được sử dụng trong ngành công nghiệp kim hoàn để so sánh trung bình của cột “depth” (một chỉ số về chất lượng của viên kim cương) giữa các mức độ “cut” (cách xử lý viên kim cương) và “color” (màu sắc của viên kim cương). Điều này có thể giúp cho các nhà sản xuất kim cương hiểu được mối quan hệ giữa cách xử lý và chất lượng của sản phẩm. Giả sử bạn đang làm việc với một tập dữ liệu về các viên kim cương, trong đó mỗi viên kim cương có các thuộc tính như chất lượng cắt (“cut”), màu sắc (“color”) và độ sâu (“depth”). Bằng cách sử dụng mã này, bạn có thể tạo ra một biểu đồ cột hiển thị sự biến đổi của độ sâu trung bình của các viên kim cương dựa trên chất lượng cắt và màu sắc, giúp bạn hiểu rõ hơn về tương quan giữa các biến này và độ sâu của viên kim cương.

h%>% group_by(cut, color)%>%summarise(m=mean(price))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'cut', y= 'Số lượng',title='Hình 1.14: Giá trị trung bình của price theo cut và color')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Nhận xét kêt quả

Ta có thể nhanh chóng nắm bắt và so sánh các giá trị trung bình của biến “price” trong các nhóm khác nhau được xác định bởi “cut” và “color”.

Ý nghĩa của biểu đồ là hiển thị trung bình của cột “price” theo các mức độ “cut” và “color”, giúp hiểu rõ hơn về sự phân bố của dữ liệu. Dưới đây là ví dụ về cách sử dụng biểu đồ này: Biểu đồ này có thể được sử dụng trong ngành công nghiệp kim hoàn để so sánh trung bình của cột “price” (một chỉ số về chất lượng của viên kim cương) giữa các mức độ “cut” (cách xử lý viên kim cương) và “color” (màu sắc của viên kim cương). Điều này có thể giúp cho các nhà sản xuất kim cương hiểu được mối quan hệ giữa cách xử lý và chất lượng của sản phẩm.

h%>% group_by(cut, clarity)%>%summarise(m=mean(table))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~clarity)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'cut', y= 'Mean',title='Hình 1.15: Giá trị trung bình của table theo  chất lượng cắt và độ trong suốt')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích

Biểu đồ này có tác dụng hiển thị giá trị trung bình của cột “table” theo các nhóm được phân loại bởi cắt (cut) và rõ ràng (clarity) của kim cương. Các thanh cột được chia thành các nhóm theo “cut” và mỗi nhóm được phân tách dựa trên “clarity”. Mỗi thanh cột đại diện cho giá trị trung bình của cột “table” cho từng nhóm. Các nhóm được phân chia bởi “clarity” sẽ được hiển thị trên các panel khác nhau, giúp so sánh sự thay đổi của giá trị trung bình của “table” giữa các nhóm trong cùng một “clarity”. Các con số trung bình cụ thể được hiển thị trên các thanh cột để người đọc có thể dễ dàng nhận biết giá trị. Biểu đồ này giúp trực quan hóa sự phụ thuộc của giá trị trung bình của cột “table” đối với “cut” và “clarity” của kim cương, từ đó giúp phân tích mối quan hệ giữa các yếu tố này và phát hiện ra các mẫu hoặc xu hướng quan trọng. Qua đây ta thấy giá trị trung bình của mỗi lỗi thuộ các nhóm ổn định dao động trong khoảng 56 đến 60

Ví dụ:

Biểu đồ có thể cho thấy rằng các kim cương có mức độ rõ ràng “SI1” thường có giá trị trung bình của cột “table” cao hơn so với các kim cương khác khi cắt ở mức “Good”, nhưng lại thấp hơn đáng kể khi cắt ở mức “Very Good”. Điều này có thể gợi ý rằng có thể có sự tương tác phức tạp giữa cắt và mức độ rõ ràng đối với giá trị trung bình của cột “table”.

h%>% group_by(cut, clarity)%>%summarise(m=mean(depth))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~clarity)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'cut', y= 'Mean',title='Hình 1.16: Giá trị trung bình của depth theo cut và clarity ')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích

Biểu đồ này có tác dụng hiển thị giá trị trung bình của cột “depth” theo các nhóm được phân loại bởi cắt (cut) và rõ ràng (clarity) của kim cương. Các thanh cột được chia thành các nhóm theo “cut” và mỗi nhóm được phân tách dựa trên “clarity”. Mỗi thanh cột đại diện cho giá trị trung bình của cột “depth” cho từng nhóm.

Các nhóm được phân chia bởi “clarity” sẽ được hiển thị trên các panel khác nhau, giúp so sánh sự thay đổi của giá trị trung bình của “table” giữa các nhóm trong cùng một “clarity”. Các con số trung bình cụ thể được hiển thị trên các thanh cột để người đọc có thể dễ dàng nhận biết giá trị.

Biểu đồ này giúp trực quan hóa sự phụ thuộc của giá trị trung bình của cột “depth” đối với “cut” và “clarity” của kim cương, từ đó giúp phân tích mối quan hệ giữa các yếu tố này và phát hiện ra các mẫu hoặc xu hướng quan trọng. Qua đây ta thấy giá trị trung bình của mỗi lỗi thuộ các nhóm ổn định dao động trong khoảng 60 đến 64

Ý nghĩa của biểu đồ được tạo bởi mã này là để hiểu sự tương quan giữa cut, clarity và độ sâu của kim cương. Trong ngành công nghiệp kim cương, cut (cắt) và clarity (độ trong suốt) là hai yếu tố chính ảnh hưởng đến giá trị của một viên kim cương. Độ sâu (depth) cũng là một yếu tố quan trọng để đánh giá chất lượng của một viên kim cương. Biểu đồ sẽ giúp ta thấy liệu có sự tương quan giữa các yếu tố này không.

Ví dụ: nếu biểu đồ cho thấy rằng các cột biểu diễn độ sâu của kim cương (depth) thấp nhất đều nằm ở một nhóm cắt cụ thể và một độ trong suốt cụ thể, điều này có thể cho thấy rằng mối tương quan giữa cắt và clarity với độ sâu là đáng chú ý.

h%>% group_by(cut, clarity)%>%summarise(m=var(depth))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~clarity)+
  geom_text(aes(label= round(m)), vjust=0, color='red')+ labs(x= 'cut', y= 'Var',title='Hình 1.17: Phương sai của depth theo cut và clarity')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Nhận xét biểu đồ

Tác dụng của biểu đồ này là hiển thị phương sai của cột “depth” theo các mức độ “cut” và “clarity”, cho ta cái nhìn về sự biến động của dữ liệu. Qua đây ta thấy được phương sai của mỗi nhóm color đều có xu hướng giảm dần từ Fair xuống Ideal

Suy ra, kiểu cắt kim cương ảnh hưởng đến mức độ chênh lệch của biến “carat”.Kim cương có kiểu cắt “Fair và Ideal” có mức đọ chênh lệch cao nhất về biến “carat” tức là có độ biến thiên cao nhất về kích thước carat. Điều này có nghĩa là kim cương trong nhóm “Fair và Ideal” có thể có kích thước carat chênh lệch nhau đáng kể.

h%>% group_by(cut, clarity)%>%summarise(m=mean(price))%>%ggplot(aes(x=cut, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~clarity)+
  geom_text(aes(label= round(m)), vjust=1, color='pink')+ labs(x= 'cut', y= 'Mean',title='Hình 1.18: Giá trị trung bình của price theo cut và clarity')
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.

Giải thích

Biểu đồ có dạng cột, với các cột thể hiện giá trị trung bình của giá (price) cho từng nhóm cut và clarity. Biểu đồ được chia thành các mặt con theo các giá trị khác nhau của biến clarity. Mỗi mặt con hiển thị biểu đồ cột riêng cho một mức độ trong cụ thể, giúp so sánh giá trị trung bình của giá giữa các kiểu cắt trong cùng mức độ trong. Các cột được tô màu khác nhau để dễ dàng phân biệt các nhóm clarity. Giá trị trung bình của giá được hiển thị trên mỗi cột để giúp người đọc dễ dàng so sánh giá trị giữa các nhóm.

h%>% group_by(clarity,color)%>%summarise(m=mean(table))%>%ggplot(aes(x=clarity, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'cut', y= 'Mean',title='Hình 1.19: Giá trị trung bình của table theo clarity và color')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Giải thích

Biểu đồ này có tác dụng hiển thị giá trị trung bình của cột “table” theo các nhóm được phân loại bởi (color) và rõ ràng (clarity) của kim cương. Các thanh cột được chia thành các nhóm theo “color” và mỗi nhóm được phân tách dựa trên “clarity”. Mỗi thanh cột đại diện cho giá trị trung bình của cột “table” cho từng nhóm.

Các nhóm được phân chia bởi “clarity” sẽ được hiển thị trên các panel khác nhau, giúp so sánh sự thay đổi của giá trị trung bình của “table” giữa các nhóm trong cùng một “clarity”. Các con số trung bình cụ thể được hiển thị trên các thanh cột để người đọc có thể dễ dàng nhận biết giá trị.

Biểu đồ này giúp trực quan hóa sự phụ thuộc của giá trị trung bình của cột “table” đối với “color” và “clarity” của kim cương, từ đó giúp phân tích mối quan hệ giữa các yếu tố này và phát hiện ra các mẫu hoặc xu hướng quan trọng.

Qua đây ta thấy giá trị trung bình của mỗi loại trong Cột Clarity thuộc các nhóm ổn định dao động trong khoảng 56 đến 5959

Ý nghĩa của biểu đồ được tạo bởi mã này là để hiểu sự tương quan giữa color, clarity và table của kim cương. Trong ngành công nghiệp kim cương, color và clarity (độ trong suốt) là hai yếu tố chính ảnh hưởng đến giá trị của một viên kim cương. Biểu đồ sẽ giúp ta thấy liệu có sự tương quan giữa các yếu tố này không.

h%>% group_by(clarity,color)%>%summarise(m=var(table))%>%ggplot(aes(x=clarity, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'clarity', y= 'Var',title='Hình 1.20: Phương sai của table theo clarity và color ')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Giải thích

Đoạn mã trên sẽ giúp bạn trực quan hóa dữ liệu một cách dễ dàng và cung cấp thông tin . Nó sẽ tạo ra một biểu đồ cột, mỗi cột biểu diễn cho một cặp “clarity” và “color”, với chiều cao của cột tương ứng với phương sai của biến “table”. Bạn cũng có thể thấy các giá trị phương sai được hiển thị trên biểu đồ, giúp bạn so sánh dễ dàng hơn giữa các nhóm. Phương sai của biểu đồ trên không có dộ chenh lệch lớn giữa các loại.

Nếu kết quả từ biểu đồ cho thấy các cặp clarity và color có phương sai của biến “table” khác biệt lớn, bạn có thể kết luận rằng có mối quan hệ giữa độ trong suốt và màu sắc của kim cương đối với đặc điểm “table”. Điều này có thể cung cấp thông tin hữu ích cho việc lựa chọn kim cương trong các ứng dụng khác nhau, như trong ngành công nghiệp trang sức.

h%>% group_by(clarity,color)%>%summarise(m=var(depth))%>%ggplot(aes(x=clarity, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=0, color='red')+ labs(x= 'clarity', y= 'Var',title='Hình 1.21: Phương sai của depth theo clarity và color')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Nhận xét biểu đồ

Tác dụng của biểu đồ này là hiển thị phương sai của cột “depth” theo các mức độ “clarity” và “color”, cho ta cái nhìn về sự biến động của dữ liệu. Qua đây ta thấy được phương sai của mỗi nhóm color đều có xu hướng giảm dần từ I1 xuống IF

Suy ra, kiểu cắt kim cương ảnh hưởng đến mức độ chênh lệch của biến “carat”.Kim cương có kiểu cắt “Fair và Premiuml” có mức đọ chênh lệch cao nhất về biến “carat” tức là có độ biến thiên cao nhất về kích thước carat. Điều này có nghĩa là kim cương trong nhóm “Fair và Premium” có thể có kích thước carat chênh lệch nhau đáng kể.

h%>% group_by(clarity,color)%>%summarise(m=mean(depth))%>%ggplot(aes(x=clarity, y= m))+
  geom_col(position='dodge')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=2, color='pink')+ labs(x= 'clarity', y= 'Meann',title='Hình 1.22: Giá trị trung bình của depth theo clarity và color')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Nhận xét biểu đồ

Biểu đồ thể hiện mối quan hệ giữa độ trong suốt (Clarity) và độ sâu trung bình (Mean Depth) của đá quý, phân theo màu sắc (Color). Mỗi thanh màu đại diện cho độ sâu trung bình của đá quý có cùng độ trong suốt và màu sắc. Có thể quan sát thấy sự khác biệt về độ sâu trung bình giữa các độ trong suốt khác nhau trong cùng một màu sắc. Có thể có sự tương quan hoặc không tương quan giữa độ trong suốt và độ sâu trung bình tùy thuộc vào loại đá quý cụ thể. Chú thích trên mỗi thanh hiển thị giá trị trung bình được làm tròn đến hai chữ số thập phân. Qua biểu đồ trên ta thầy được giá trị trung bình của độ sâu (depth) khá là ổn định dao động trong khoảng 61-64

h%>% group_by(clarity,color)%>%summarise(m=mean(price))%>%ggplot(aes(x=clarity, y= m))+
  geom_col(position='dodge',fill='black')+
  facet_wrap(~color)+
  geom_text(aes(label= round(m)), vjust=0, color='red')+ labs(x= 'clarity', y= 'Mean',title='Hình 1.23: Giá trị trung bình của price theo clarity và color')
## `summarise()` has grouped output by 'clarity'. You can override using the
## `.groups` argument.

Nhận xét biểu đồ

h %>%: Sử dụng toán tử pipe (%>%) trong gói dplyr để áp dụng các lệnh tiếp theo cho một khung dữ liệu (thường được biểu thị bằng h).

group_by(clarity, color): Chia khung dữ liệu thành các nhóm dựa trên hai yếu tố: clarity (độ tinh khiết) và color (màu sắc). Cho phép tính toán thống kê tóm tắt trong từng nhóm.

summarise(m = mean(price)): Tính toán giá trị trung bình của biến price trong mỗi nhóm, gán kết quả cho biến mới m.

ggplot(aes(x = clarity, y = m)): Tạo một đối tượng ggplot để xây dựng các dạng trực quan hóa. Hàm aes() ánh xạ biến clarity sang trục x và giá trị m (giá trị trung bình) được tính toán sang trục y.

geom_col(position = ‘dodge’, fill = ‘black’): Thêm lớp biểu đồ thanh (geom_col) vào ggplot. position = ‘dodge’ đảm bảo các thanh cho các nhóm color khác nhau được đặt cạnh nhau mà không chồng lấn. fill = ‘black’ đặt màu của các thanh thành đen.

facet_wrap(~ color): Chia nhỏ biểu đồ thành các phần dựa trên các nhóm color. Mỗi phần hiển thị biểu đồ thanh cho một nhóm color cụ thể.

geom_text(aes(label = round(m)), vjust = 2, color = ‘red’): Thêm chú thích văn bản vào các thanh. aes() chỉ định văn bản label là giá trị được làm tròn của m (giá trị trung bình). vjust = 2 điều chỉnh vị trí dọc của văn bản cao hơn các thanh một chút để hiển thị rõ ràng hơn. color = ‘red’ đặt màu văn bản thành đỏ.

labs(x = ‘clarity’, y = ‘Mean’, title = ‘Hình 1.23’): Thêm nhãn cho trục x (‘clarity’), trục y (‘Mean’) và tiêu đề chung cho biểu đồ (‘Hình 1.23’)

Nhằm mục đích tạo ra một biểu đồ cột đa biến để so sánh giá trị trung bình của cột price dựa trên các nhóm clarity và color, với việc thêm chú thích văn bản cho từng cột và phân chia biểu đồ thành các phần nhỏ dựa trên màu sắc

k<- h %>% group_by(cut, color) %>% summarise(n = n())
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
k %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = k %>% filter(color == 'D'), fill = 'pink') +
  geom_col(data = k %>% filter(color == 'J'), fill = 'brown')+labs(title='Hình 1.24')

Giải thích

  • Tạo một khung dữ liệu mới k bằng cách nhóm dữ liệu trong h theo các giá trị trong các cột cut và color.
  • Trong mỗi nhóm, tính toán số lượng quan sát (n) bằng hàm n() và lưu trữ kết quả trong cột n mới.
  • Khởi tạo một đối tượng ggplot từ khung dữ liệu k.
  • Xác định các thuộc tính thẩm mỹ (ánh xạ trực quan) cho biểu đồ:
  • Trục hoành (x) được ánh xạ với biến cut.
  • Trục tung (y) được ánh xạ với biến n (số lượng quan sát).
  • Thêm một lớp các cột màu vào biểu đồ.
  • Lọc dữ liệu trong k để chỉ giữ lại các hàng có giá trị color bằng ‘D’ (giả sử đại diện cho một loại cụ thể).
  • Sử dụng hàm geom_col để tạo các cột cho dữ liệu đã lọc, tô màu hồng (‘pink’).
  • Tương tự, thêm một lớp cột màu khác cho các hàng có color bằng ‘J’, tô màu nâu (‘brown’). Qua biểu đồ trên ta nhìn thấy tổng số lượng của color ‘D’ chiếm ưu thế hơn so với color ‘J’ trong tất các loại. Qua đó ta có cái nhìn tổng quan hơn về phân phối của chúng trong các loại của cột Cut. Giúp cho chúng ta trong việc phân tích và hiểu rõ hơn về màu sắc của các loại kim cương. vd: cột Ideal là màu hồng nhiều hơn màu dỏ tức là ở loại Ideal có tỷ lệ màu D lớn hơn so với màu J
g<- h %>% group_by(cut, clarity) %>% summarise(n = n())
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
g %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = g %>% filter(clarity == 'SI2'), fill = 'black') +
  geom_col(data = g %>% filter(clarity == 'VS1'), fill = 'brown') +labs(title='Hình 1.25')

Nhận xét kết quả

Nhóm dữ liệu: Dữ liệu được nhóm theo hai biến: “cut” và “clarity”. Điều này có nghĩa là dữ liệu được phân chia thành các nhóm dựa trên giá trị của hai biến này. Tổng hợp số lượng mẫu: Sau khi dữ liệu được nhóm, tổng số lượng mẫu trong mỗi nhóm được tính toán bằng hàm summarise() và lưu vào một biến mới được đặt tên là n. Tạo biểu đồ cột: Sử dụng gói ggplot2, một biểu đồ cột được tạo ra. Trục x của biểu đồ là các loại “cut”, và trục y là số lượng mẫu. Hai cột được vẽ, mỗi cột đại diện cho một màu sắc: “H” và “E”. Cột màu brown đại diện cho màu “E”, trong khi cột màu đen đại diện cho màu “H”.

Qua biểu đồ trên ta nhìn thấy tổng số lượng của color ‘E’ chiếm ưu thế hơn so với color ‘H’ trong tất các loại qua đó ta có cái nhìn tổng quan hơn về phân phối của chúng trong các loại của cột Cut. Giúp cho chúng ta trong việc phân tích và hiểu rõ hơn về độ trong suốt của các loại kim cương.

p<- h %>% group_by(color, clarity) %>% summarise(n = n())
## `summarise()` has grouped output by 'color'. You can override using the
## `.groups` argument.
p %>% ggplot(aes(x = color, y = n)) +
  geom_col(data = p %>% filter(clarity == 'SI2'), fill = 'pink') +
  geom_col(data = p %>% filter(clarity == 'VS1'), fill = 'brown') +labs(title='Hình 1.26')

Nhận xét biểu đồ

Bước này tính toán số lượng quan sát (số lần xuất hiện) của mỗi tổ hợp “color” và “clarity” trong tập dữ liệu.

Biểu đồ hình cột được tạo ra, với trục hoành thể hiện “màu sắc” và trục tung thể hiện số lượng quan sát (số lần xuất hiện) của mỗi tổ hợp ” color ” và “clarity”.

Hai nhóm thanh riêng biệt được thêm vào biểu đồ: Nhóm thanh màu hồng: Hiển thị số lượng quan sát (số lần xuất hiện) của các đối tượng có “clarity” là “SI2” cho từng “color”. Nhóm thanh màu nâu: Hiển thị số lượng quan sát (số lần xuất hiện) của các đối tượng có “clarity” là “VS1” cho từng “color”.

Qua biểu đồ trên chẳng hạn như ở cột E ta thấy có 2 màu thì màu brown chiếm ưu thế hơn so với màu hồng tức là độ trong suốt clarity SI2 chiếm tỷ lên ít hơn so với VS1

o <- h %>% mutate(caratC = cut(carat,5, label = c('rất nhỏ', 'nhỏ','vừa','lớn','rất lớn')))
o %>% ggplot(aes(x = caratC)) +
  geom_bar(fill = 'yellow')+labs(title='Hình 1.2727')

Giải thích câu lệnh

  • o<-: Gán giá trị cho biến o.
  • h%>%: Sử dụng pipe (%>%) để chuyển kết quả của biểu thức bên trái sang biểu thức bên phải.
  • mutate(caratC =cut(carat,5,label=c(‘rất nhỏ’,‘nhỏ’,‘vừa’,‘lớn’,‘rất lớn’))): Thêm một cột mới tên là caratC vào dataframe o. Cột caratC được tạo ra bằng cách phân chia cột carat thành 5 nhóm bằng nhau (cut) và gán nhãn cho mỗi nhóm (label).
  • o %>%: Sử dụng pipe (%>%) để chuyển kết quả của biểu thức bên trái sang biểu thức bên phải.
  • ggplot(aes(x=caratC)): Tạo một ggplot object với trục x là biến caratC.
  • geom_bar(fill=‘yellow’): Thêm một layer geom_bar vào ggplot object. Layer này hiển thị biểu đồ thanh với trục x là caratC, trục y là số lượng quan sát trong mỗi nhóm, và màu sắc của thanh được tô màu vàng (fill=‘yellow’).

Nhận xét Kết quả

Đây là một dạng biểu đồ dạng Bar_Chart nói số lượng của cột CaratC vừa mới tạo trong được gán vào biến o. Biểu đồ thanh này cho thấy sự phân bố của các viên kim cương dựa trên kích thước carat của chúng, được chia thành 5 nhóm: “rất nhỏ”, “nhỏ”, “vừa”, “lớn” và “rất lớn”. Chiều cao của mỗi thanh biểu thị số lượng viên kim cương trong nhóm kích thước carat tương ứng.

Nhóm “vừa” là nhóm phổ biến nhất.Nhóm “rất nhỏ” và “rất lớn” là nhóm ít phổ biến nhất.Có sự phân bố tương đối đồng đều giữa các nhóm “nhỏ”, “vừa” và “lớn”.Số lượng kim cương có xu hướng giảm dần theo kích thước.Kim cương có kích thước “rất nhỏ” chiếm số lượng lớn nhất cụ thể là , tiếp theo là “nhỏ”, “vừa” và “lớn”.Kim cương “rất lớn” có số lượng ít nhất.

Ví dụ:Giả sử biểu đồ thanh cho thấy nhóm “vừa” có chiều cao cao nhất. Điều này có nghĩa là có nhiều viên kim cương thuộc nhóm kích thước carat này hơn so với các nhóm khác. Ngược lại, nhóm “rất nhỏ” có chiều cao thấp nhất, cho thấy số lượng viên kim cương trong nhóm này ít hơn so với các nhóm khác.

h%>% group_by(cut) %>% summarise(m= mean(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'cut', y = 'Mean',title='Hình 1.28: Giá trị trung bình của carat theo biến cut')

Giải thích câu lệnh

  • summarise(m = mean(carat)): Tính toán giá trị trung bình (mean) của cột carat (trọng lượng kim cương) cho mỗi nhóm được tạo bởi lệnh group_by. Kết quả được lưu trong một cột mới có tên m.
  • position = ‘dodge’: Xếp các cột cạnh nhau theo thứ tự của các nhóm (màu) trên trục hoành, tránh chồng chéo lên nhau.
  • geom_text(): Thêm một lớp văn bản (text) vào biểu đồ.
  • aes(label = round(m, 2)): Gán nhãn cho các cột là giá trị trung bình của trọng lượng kim cương (m), được làm tròn đến 2 chữ số thập phân (round(m, 2)).
  • labs(): Thêm nhãn cho trục hoành (x) và trục tung (y).
  • x = ‘Màu’: Gán nhãn “Màu” cho trục hoành, biểu thị các nhóm theo màu sắc kim cương.
  • y = ‘Mean’: Gán nhãn “Mean” (Trung bình) cho trục tung, biểu thị giá trị trung bình của trọng lượng kim cương.

Tóm tắt:

Đây là đoạn mã sử dụng thư viện ggplot2 trong R để tạo biểu đồ cột thể hiện mối quan hệ giữa màu sắc (cut) và giá trị trung bình của trọng lượng (carat) kim cương. Biểu đồ được tùy chỉnh với các cột xếp cạnh nhau, nhãn văn bản màu hồng làm tròn đến 2 chữ số thập phân, và nhãn trục được đặt tên theo ý nghĩa.

Nhận xét kết quả

  • Dây là là một biểu đò dang Bar_Chart thể hiện giá trị trung bình của carat(kích thước kim cương) theo biến cut
  • Biểu đồ cho thấy giá trị trung bình của biến “carat” dao động trong khoảng 0.7 đến 1.05 carat.
  • Nhóm “Fair” có giá trị trung bình thấp nhất (khoảng 0.7 carat).
  • Nhóm “Ideal” có giá trị trung bình cao nhất (khoảng 1.05 carat).
  • Nhìn chung, giá trị trung bình của biến “carat” tăng dần từ nhóm “Fair” đến nhóm “Ideal”. Suy ra, kiểu cắt kim cương ảnh hưởng đến giá trị trung bình của biến “carat”.Kim cương có kiểu cắt “Ideal” có giá trị trung bình cao nhất về biến “carat”.
h%>% group_by(cut) %>% summarise(m= median(carat)) %>%
  ggplot(aes(x = cut,y = m)) +
    geom_col(position = 'dodge') +
    geom_text(aes(label = round(m,2)), vjust = 2, color = 'pink') +
    labs(x = 'cut', y = 'Median',title='Hình 1.29: Trung vị của carat theo biến cut')

Nhận xét kết quả

Chất lượng cắt “Ideal” (hoàn hảo): cột “Ideal” thấp nhất trong biểu đồ. Điều này có nghĩa là kim cương có chất lượng cắt hoàn hảo có trung vị trọng lượng carat thấp nhất. Ví dụ, chú thích trên cột “Ideal” có thể hiển thị giá trị 0.54 carat, cho biết nửa số kim cương có chất lượng cắt hoàn hảo có trọng lượng carat thấp hơn 0.54 carat, và nửa còn lại có trọng lượng carat cao hơn 0.54 carat.

Chất lượng cắt “Fair” (kém): cột “Fair” cao nhất trong biểu đồ. Điều này có nghĩa là kim cương có chất lượng cắt kém có trung vị trọng lượng carat cao nhất. Ví dụ, chú thích trên cột “Fair” có thể hiển thị giá trị 1 carat, cho biết nửa số kim cương có chất lượng cắt kém có trọng lượng carat thấp hơn 1 carat, và nửa còn lại có trọng lượng carat cao hơn 1 carat.

b <- h%>% group_by(cut, color) %>% summarise(n = n())
## `summarise()` has grouped output by 'cut'. You can override using the `.groups`
## argument.
 b %>% ggplot(aes(x = cut, y = n)) +
  geom_col(data = b %>% filter(color == 'E'), fill = 'pink') +
  geom_col(data = b %>% filter(color == 'H'), fill = 'black')+labs(title='Hình 1.30: Tổng số lượng kim cương theo biến cut mà color')

Nhận xét biểu đồ

Nhóm dữ liệu: Dữ liệu được nhóm theo hai biến: “cut” và “color”. Điều này có nghĩa là dữ liệu được phân chia thành các nhóm dựa trên giá trị của hai biến này. Tổng hợp số lượng mẫu: Sau khi dữ liệu được nhóm, tổng số lượng mẫu trong mỗi nhóm được tính toán bằng hàm summarise() và lưu vào một biến mới được đặt tên là n. Tạo biểu đồ cột: Sử dụng gói ggplot2, một biểu đồ cột được tạo ra. Trục x của biểu đồ là các loại “cut”, và trục y là số lượng mẫu. Hai cột được vẽ, mỗi cột đại diện cho một màu sắc: “E” và “H”. Cột màu hồng đại diện cho màu “E”, trong khi cột màu đen đại diện cho màu “H”. Tiêu đề của biểu đồ: Tiêu đề của biểu đồ được đặt là “Hình 1.30”.

Qua biểu đồ trên ta nhìn thấy tổng số lượng của color ‘H’ chiếm ưu thế hơn so với color ’E trong tất các loại. Qua đó ta có cái nhìn tổng quan hơn về phân phối của chúng trong các loại của cột Cut. Giúp cho chúng ta trong việc phân tích và hiểu rõ hơn về màu sắc của các loại kim cương.

LS0tDQp0aXRsZTogIlBow6JuIHTDrWNoIGLhu5kgZOG7ryBsaeG7h3UgRGlhbW9uZHMiDQphdXRob3I6ICJRdeG7s25oIEjGsMahbmciDQpkYXRlOiAiMjAyNC0wMy0wMiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICBudW1iZXIgc2VjdGlvbjogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgDQogICANCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojICoqKlPhu60gZOG7pW5nIGLhu5kgZOG7ryBsaeG7h3UgY8OzIHPhurVuIHRyb25nIFIqKioNCg0KICAtIELhu5kgZOG7ryBsaeG7h3UgxJHGsOG7o2MgZOG7pW5nIGzDoCBi4buZIGThu68gbGnhu4d1IERpYW1vbmRzIGPDsyBz4bq1biB0cm9uZyBSIA0KICAtIELhu5kgZOG7ryBsaeG7h3UgZGlhbW9uZHMgdHJvbmcgUiBsw6AgbeG7mXQgdOG6rXAgZOG7ryBsaeG7h3UgcGjhu5UgYmnhur9uIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIGPDoWMgdsOtIGThu6UgdsOgIGjGsOG7m25nIGThuqtuIHbhu4EgcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UuIE7DsyBiYW8gZ+G7k20gdGjDtG5nIHRpbiB24buBIDUzLjk0MCB2acOqbiBraW0gY8awxqFuZyBj4bqvdCB0csOybiwgduG7m2kgMTAgYmnhur9uIG3DtCB04bqjIGPDoWMgxJHhurdjIMSRaeG7g20ga2jDoWMgbmhhdSBj4bunYSBt4buXaSB2acOqbiBraW0gY8awxqFuZzoNCg0KICAgICAtIGNhcmF0OiBUcuG7jW5nIGzGsOG7o25nIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIChjYXJhdCkNCiAgICAgLSBjdXQ6IENo4bqldCBsxrDhu6NuZyDEkcaw4budbmcgY+G6r3QgKEZhaXIsIEdvb2QsIFZlcnkgR29vZCwgSWRlYWwsIFByZW1pdW0pDQogICAgIC0gY29sb3I6IE3DoHUgc+G6r2MgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgKHThu6sgRCAodOG7kXQgbmjhuqV0KSDEkeG6v24gSiAoa8OpbSBuaOG6pXQpKQ0KICAgICAtIHByaWNlOiBHacOhIHRy4buLIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nICjEkcahbiB24buLIFVTRCkNCiAgICAgLSBjbGFyaXR5OiDEkOG7mSB0cm9uZyBzdeG7kXQgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgKHThu6sgSUYgKHThu5F0IG5o4bqldCkgxJHhur9uIEkxIChrw6ltIG5o4bqldCkpDQogICAgIC0gZGVwdGg6IFThu7cgbOG7hyBwaOG6p24gdHLEg20gxJHhu5kgc8OidSAodMOtbmggdGhlbyB6IC8geCkNCiAgICAgLSB0YWJsZTogQ2hp4buBdSBy4buZbmcgY+G7p2EgbeG6t3QgYsOgbiAodMOtbmggdGhlbyAlIGPhu6dhIMSRxrDhu51uZyBrw61uaCkNCiAgICAgLSB4OiBDaGnhu4F1IGTDoGkgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgKG1tKQ0KICAgICAtIHk6IENoaeG7gXUgcuG7mW5nIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIChtbSkNCiAgICAgLSB6OiDEkOG7mSBzw6J1IGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nIChtbSkNCg0KICANCiANCg0KYGBge3J9DQpsaWJyYXJ5KERUKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpoPC0gZGlhbW9uZHMNCmRhdGF0YWJsZShoKQ0KYGBgDQoNCiMgKioqUGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgduG7m2kgQmFyLUNoYXJ0KioqDQoNCiMjICoqR2nhu5tpIHRoaeG7h3UqKg0KICAtIEJp4buDdSDEkeG7kyB0aGFuaCAoQmFyIGNoYXJ0KSBsw6AgbeG7mXQgZOG6oW5nIGJp4buDdSDEkeG7kyB0aOG7kW5nIGvDqiB0aOG7iyB0csaw4budbmcgcGjhu5UgYmnhur9uLCBz4butIGThu6VuZyBjw6FjIHRoYW5oIGThu41jIGhv4bq3YyBuZ2FuZyDEkeG7gyBiaeG7g3UgZGnhu4VuIGThu68gbGnhu4d1IHRoZW8gdGjhu51pIGdpYW4gaG/hurdjIHRoZW8gY8OhYyBuaMOzbSBraMOhYyBuaGF1LiBN4buXaSB0aGFuaCDEkeG6oWkgZGnhu4duIGNobyBt4buZdCBnacOhIHRy4buLIGPhu6UgdGjhu4MsIHbDoCDEkeG7mSBkw6BpIGPhu6dhIHRoYW5oIHRo4buDIGhp4buHbiBnacOhIHRy4buLIMSRw7MuDQoNCiAgLSDDnSBuZ2jEqWEgY+G7p2EgYmnhu4N1IMSR4buTIHRoYW5oOg0KICAgIC0gU28gc8OhbmggZOG7ryBsaeG7h3U6IEJp4buDdSDEkeG7kyB0aGFuaCBnacO6cCBzbyBzw6FuaCB0cuG7sWMgcXVhbiBjw6FjIGdpw6EgdHLhu4sga2jDoWMgbmhhdSB0cm9uZyBjw7luZyBt4buZdCBuaMOzbSBob+G6t2MgZ2nhu69hIGPDoWMgbmjDs20ga2jDoWMgbmhhdS4NCiAgICAtIFjDoWMgxJHhu4tuaCB4dSBoxrDhu5tuZzogQmnhu4N1IMSR4buTIHRoYW5oIGPDsyB0aOG7gyBnacO6cCB4w6FjIMSR4buLbmggeHUgaMaw4bubbmcgdMSDbmcgaG/hurdjIGdp4bqjbSBj4bunYSBk4buvIGxp4buHdSB0aGVvIHRo4budaSBnaWFuLg0KICAgIC0gUGjDom4gYuG7kSBk4buvIGxp4buHdTogQmnhu4N1IMSR4buTIHRoYW5oIGdpw7pwIHNvIHPDoW5oIHPhu7EgcGjDom4gYuG7kSBj4bunYSBk4buvIGxp4buHdSBnaeG7r2EgY8OhYyBuaMOzbSBraMOhYyBuaGF1Lg0KDQojIyAqKkJp4buDdSDEkeG7kyoqDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KaW5zdGFsbC5wYWNrYWdlcygnZ2dwbG90MicpDQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KDQogIA0KICoqKkdp4bqjaSB0aMOtY2ggY2hpIHRp4bq/dDoqKioNCiANCiAgLSBnZ3Bsb3QoYWVzKHggPSBjdXQpKTogS2jhu59pIHThuqFvIG3hu5l0IGJp4buDdSDEkeG7kyBnZ3Bsb3QgduG7m2kgY3V0IGzDoCBiaeG6v24gxJHGsOG7o2Mgw6FuaCB44bqhIMSR4bq/biB0cuG7pWMgeC4NCiAgLSBnZW9tX2JhcigpOiBUaMOqbSBt4buZdCBsYXllciBow6xuaCB0aGFuaCB2w6BvIGJp4buDdSDEkeG7ky4gTeG7l2kgdGhhbmggxJHhuqFpIGRp4buHbiBjaG8gbeG7mXQgbeG7qWMgxJHhu5kgY+G6r3Qga2ltIGPGsMahbmcsIHbDoCDEkeG7mSBjYW8gY+G7p2EgdGhhbmggdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgY8OzIG3hu6ljIMSR4buZIGPhuq90IMSRw7MuDQogIC0gbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpOiBUaMOqbSBuaMOjbiBjaG8gdHLhu6VjIHggdsOgIHRy4bulYyB5Lg0KICANCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHNjYWxlcykNCmggJT4lIGdncGxvdChhZXMoeD1jdXQpKStnZW9tX2JhcigpKw0KICBsYWJzKHg9J0xv4bqhaScseT0nU+G7kSBsxrDhu6NuZycsdGl0bGUgPSAnSMOsbmggMS4xOiBT4buRIGzGsOG7o25nIGPhu6dhIG5o4buvbmcgbG/huqFpIGtpbSBjxrDGoW5nIHRoZW8gYmnhur9uIGN1dCcpDQoNCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oKioqDQoNCiAtIGxpYnJhcnkodGlkeXZlcnNlKTogVOG6o2kgdGjGsCB2aeG7h24gdGlkeXZlcnNlLCBjdW5nIGPhuqVwIG5oaeG7gXUgaMOgbSBo4buvdSDDrWNoIGNobyB2aeG7h2MgdGhhbyB0w6FjIHbDoCB0cuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1Lg0KICAtIGxpYnJhcnkoc2NhbGVzKTogVOG6o2kgdGjGsCB2aeG7h24gc2NhbGVzLCBjdW5nIGPhuqVwIGPDoWMgaMOgbSDEkeG7gyDEkeG7i25oIGThuqFuZyB0cuG7pWMgdsOgIG5ow6NuIHRyb25nIGJp4buDdSDEkeG7ky4NCiAgLSBoIDwtIGRpYW1vbmRzOiBHw6FuIGThu68gbGnhu4d1IHThu6sgYuG7mSBk4buvIGxp4buHdSBkaWFtb25kcyB2w6BvIGJp4bq/biBoLg0KICAtIGggJT4lIGdncGxvdChhZXMoeCA9IGN1dCkpOiBU4bqhbyBiaeG7g3UgxJHhu5MgZ2dwbG90IGThu7FhIHRyw6puIGThu68gbGnhu4d1IGgsIHbhu5tpIHRy4bulYyB4IHRo4buDIGhp4buHbiBiaeG6v24gY3V0IChjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2ltIGPGsMahbmcpLg0KICAtIGdlb21fYmFyKCk6IFRow6ptIGxheWVyIGjDrG5oIHRoYW5oIHbDoG8gYmnhu4N1IMSR4buTLg0KICAtIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnKTogVGjDqm0gbmjDo24gY2hvIHRy4bulYyB4IChMb+G6oWkpIHbDoCB0cuG7pWMgeSAoU+G7kSBsxrDhu6NuZykuDQogICANCg0KDQoqKipOaOG6rW4geMOpdCBr4bq/dCBxdeG6oyoqKg0KDQogICBL4bq/dCBxdeG6oyBuaOG6rW4gxJHGsOG7o2MgbMOgIG3hu5l0IGJp4buDdSDEkeG7kyBk4bqhbmcgQmFyX0NoYXJ0IHRo4buDIGhp4buHbiBn4buTbSBz4buRIGzGsOG7o25nIGPhu6dhIG5o4buvbmcgbG/huqFpIGtpbSBjxrDGoW5nKEZhaXIsIEdvb2QsIFZlcnkgZ29vZCwgUHJlbWl1bSwgSWRlYWwpLlF1YSBiaeG7g3UgxJHhu5MgdHLDqm4gY2jDum5nIHRhIHPhur0gdGjhuqV5IMSRxrDhu6NjIHPhu5EgbMaw4bujbmcgY+G7p2EgKipJZGVhbCoqIGNoaeG6v20gbmhp4buBdSBuaOG6pXQgY+G7pSB0aOG7gyBsw6AgbOG7m24gaMahbiAyMDAwMCBraW0gY8awxqFuZyB0cm9uZyA1IGxv4bqhaSB0csOqbi4gQ2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCBsw6AgKipGYWlyKiogbMOgIG5o4buPIGjGoW4gNTAwMCBraW0gY8awxqFuZyAuIFPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgZ2nhuqNtIGThuqduIHThu6sgSWRlYWwgxJHhur9uIEZhaXIuIEPDsyBz4buxIGNow6puaCBs4buHY2ggbOG7m24gZ2nhu69hIGxv4bqhaSBs4bubbiBuaOG6pXQgdsOgIHRo4bqlcCBuaOG6pXQNCiAgIA0KICANCmBgYHtyfQ0KdGFibGUoZGlhbW9uZHMkY2xhcml0eSkNCmggJT4lIGdncGxvdChhZXMoeD0gY2xhcml0eSkpICsgDQogICAgICBnZW9tX2JhciggKSsNCiAgICAgIGxhYnMoeCA9ICdDbGFyaXR5JywgeT0gJyBT4buRIGzGsOG7o25nJywgdGl0bGU9J0jDrG5oIDEuMjogU+G7kSBsxrDhu6NuZyBj4bunYSBuaOG7r25nIGxv4bqhaSBraW0gY8awxqFuZyB0aGVvIMSR4buZIHRyb25nIHN14buRdCcpDQoNCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoKioqDQoNCkvhur90IHF14bqjIG5o4bqtbiDEkcaw4bujYyBsw6AgbeG7mXQgYmnhu4N1IMSR4buTIGThuqFuZyBCYXJfQ2hhcnQgdGjhu4MgaGnhu4duIGfhu5NtIHPhu5EgbMaw4bujbmcgY+G7p2Egbmjhu69uZyBsb+G6oWkga2ltIGPGsMahbmcgKEkxLFNJMixTSTEsVlMyLFZTMSxWVlMyLFZWUzEsSUYpIC5UcuG7pWMgeCB0aOG7gyBoaeG7h24gxJHhu5kgdHJvbmcgc3Xhu5F0IGtpbSBjxrDGoW5nLCB04burIHRo4bqlcCDEkeG6v24gY2FvICh04burIOKAnEkx4oCdIMSR4bq/biDigJxJRuKAnSkuIC0gVHLhu6VjIHkgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdMawxqFuZyDhu6luZyB24bubaSBt4buXaSBj4bqlcCDEkeG7mSDEkeG7mSB0cm9uZyBzdeG7kXQuIA0KUXVhIGJp4buDdSDEkeG7kyB0csOqbiBjaMO6bmcgdGEgc+G6vSB0aOG6pXkgxJHGsOG7o2Mgc+G7kSBsxrDhu6NuZyBj4bunYSAqKlNJMSoqIGNoaeG6v20gbmhp4buBdSBuaOG6pXQgY+G7pSB0aOG7gyBsw6AgbOG7m24gaMahbiAxMDAwMCBraW0gY8awxqFuZyB0cm9uZyA4IGxv4bqhaSB0csOqbi4gQ2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCBsw6AgKipJMSoqIGzDoCBuaOG7jyBoxqFuIDI1MDAga2ltIGPGsMahbmcgLkPDsyBz4buxIGNow6puaCBs4buHY2ggbOG7m24gZ2nhu69hIGxv4bqhaSBs4bubbiBuaOG6pXQgdsOgIHRo4bqlcCBuaOG6pXQgDQogIA0KDQpgYGB7cn0NCg0KaCAlPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSBnZ3Bsb3QoYWVzKGN1dCxuKSkrIA0KIGdlb21fY29sKGZpbGw9J2JsYWNrJykrDQogICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gMSwgY29sb3IgPSAncGluaycpICsgDQogICBsYWJzKHggPSAnTG/huqFpJywgeSA9ICdT4buRIGzGsOG7o25nJywgdGl0bGU9J0jDrG5oIDEuMzpT4buRIGzGsOG7o25nIGPhu6dhIG5o4buvbmcgbG/huqFpIGtpbSBjxrDGoW5nIHRoZW8gYmnhur9uIGN1dCAnKQ0KYGBgDQogDQogKioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCoqKg0KIA0KVOG6oW8gbmjDs20gdsOgIMSR4bq/bSBz4buRIGzGsOG7o25nOg0KDQogIC0gaCAlPiUgZ3JvdXBfYnkoY3V0KTogTmjDs20gZOG7ryBsaeG7h3UgdGhlbyBiaeG6v24gY3V0IChjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2ltIGPGsMahbmcpLg0KICAtIHN1bW1hcmlzZShuID0gbigpKTogVMOtbmggdOG7lW5nIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdHJvbmcgbeG7l2kgbmjDs20uDQpU4bqhbyBiaeG7g3UgxJHhu5M6DQogIC0gZ2dwbG90KGFlcyhjdXQsbikpOiBLaOG7n2kgdOG6oW8gbeG7mXQgYmnhu4N1IMSR4buTIGdncGxvdCB24bubaSBjdXQgbMOgIGJp4bq/biDEkcaw4bujYyDDoW5oIHjhuqEgxJHhur9uIHRy4bulYyB4IHbDoCBuIGzDoCBiaeG6v24gxJHGsOG7o2Mgw6FuaCB44bqhIMSR4bq/biB0cuG7pWMgeS4NCiAgLSBnZW9tX2NvbChmaWxsPSdibGFjaycpOiBUaMOqbSBsYXllciBow6xuaCBj4buZdCB2w6BvIGJp4buDdSDEkeG7kyB24bubaSBtw6B1IMSRZW4uDQogIC0gZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdCA9IDEsIGNvbG9yID0gJ3BpbmsnKTogVGjDqm0gbGF5ZXIgdsSDbiBi4bqjbiB2w6BvIGJp4buDdSDEkeG7kywgaGnhu4NuIHRo4buLIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdHLDqm4gbeG7l2kgY+G7mXQgduG7m2kgbcOgdSBo4buTbmcuDQogIC0gbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycpOiBUaMOqbSBuaMOjbiBjaG8gdHLhu6VjIHggKExv4bqhaSkgdsOgIHRy4bulYyB5IChT4buRIGzGsOG7o25nKS4NCiAgDQoqKipOaOG6rW4geMOpdCBr4bq/dCBxdeG6oyoqKg0KDQogIC0gS+G6v3QgcXXhuqMgbmjhuq1uIMSRxrDhu6NjIGzDoCBt4buZdCBiaeG7g3UgxJHhu5MgZOG6oW5nIEJhcl9DaGFydCB0aOG7gyBoaeG7h24gZ+G7k20gc+G7kSBsxrDhu6NuZyBj4bunYSBuaOG7r25nIGxv4bqhaSBraW0gY8awxqFuZyhGYWlyLCBHb29kLCBWZXJ5IGdvb2QsIFByZW1pdW0sIElkZWFsKQ0KICAtIE5ow6xuIGJp4buDdSDEkeG7kyBjaMO6bmcgdGEgc+G6vSBiaeG6v3QgcsO1IMSRxrDhu6NjIHPhu5EgbMaw4bujbmcgY+G7p2EgbeG7l2kgbG/huqFpOg0KICAgICAtIEZhaXIgY8OzIDE2MTAga2ltIGPGsMahbmcNCiAgICAgLSBHb29kIGPDsyA0OTA2IGtpbSBjxrDGoW5nDQogICAgIC0gVmVyeSBnb29kIDEyMDgyIGtpbSBjxrDGoW5nIA0KICAgICAtIFByZW1pdW0gMTM3OTEga2ltIGPGsMahbmcNCiAgICAgLSBJZGVhbCBjw7MgMjE1NTEga2ltIGPGsMahbmcgDQogIC0gUXVhIMSRw6J5IGNow7puZyB0YSBz4bq9IHRo4bqleSDEkcaw4bujYyBz4buRIGzGsOG7o25nIGPhu6dhICoqSWRlYWwqKiBjaGnhur9tIG5oaeG7gXUgbmjhuqV0IGPhu6UgdGjhu4MgbMOgIDIxNTUxIGtpbSBjxrDGoW5nIHRyb25nIDUgbG/huqFpIHRyw6puDQogIC0gQ2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCBsw6AgKipGYWlyKiogbMOgIDE2MTAga2ltIGPGsMahbmcgDQogIC0gU+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBnaeG6o20gZOG6p24gdOG7qyBJZGVhbCDEkeG6v24gRmFpcg0KICAtIFPhu5EgbMaw4bujbmcgbG/huqFpIGzhu5tuIG5o4bqldCB2w6Agbmjhu48gY2jDqm5oIGzhu4djaCB24bubaSBuaGF1IGjGoW4gMTMgbOG6p24NCiAgDQogIA0KICANCmBgYHtyfQ0KaCAlPiUgZ3JvdXBfYnkoY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIGdncGxvdChhZXMoY29sb3IsbikpKyANCiBnZW9tX2NvbChmaWxsPSdtYXJvb24nKSsNCiAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgdmp1c3QgPTAsIGNvbG9yID0gJ2JsYWNrJykgKyANCiAgIGxhYnMoeCA9ICdDb2xvcicsIHkgPSAnU+G7kSBsxrDhu6NuZycsIHRpdGxlPSAnSMOsbmggMS40OiBT4buRIGzGsOG7o25nIGPhu6dhIG5o4buvbmcgbG/huqFpIGtpbSBjxrDGoW5nIHRoZW8gbcOgdScpDQpgYGANCg0KKioqTmjhuq1uIHjDqXQga+G6v3QgcXXhuqMqKioNCg0KICAtIE5ow6xuIGJp4buDdSDEkeG7kyB0YSB0aOG6pXksIEvhur90IHF14bqjIG5o4bqtbiDEkcaw4bujYyBsw6AgbeG7mXQgYmnhu4N1IMSR4buTIGThuqFuZyBCYXJfQ2hhcnQgdGjhu4MgaGnhu4duIGfhu5NtIHPhu5EgbMaw4bujbmcgY+G7p2EgY+G7mXQgY29sb3IgKGhheSBjw7JuIGfhu41pIGzDoCBuxrDhu5tjIGtpbSBjxrDGoW5nKTogRCxFLEYsRyxILEksSg0KICAtICBUaGFuZyBuw6B5IMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIMSRw6FuaCBnacOhIG3hu6ljIMSR4buZIGtow7RuZyBtw6B1IGPhu6dhIGtpbSBjxrDGoW5nLCB24bubaSBEIGzDoCBj4bqlcCDEkeG7mSBjYW8gbmjhuqV0IChraMO0bmcgbcOgdSkgdsOgIEogbMOgIGPhuqVwIMSR4buZIHRo4bqlcCBuaOG6pXQgKG3DoHUgdHLhuq9uZykuDQogIC0gTmjDrG4gYmnhu4N1IMSR4buTIGNow7puZyB0YSBz4bq9IGJp4bq/dCByw7UgxJHGsOG7o2Mgc+G7kSBsxrDhu6NuZyBj4bunYSBt4buXaSBsb+G6oWk6DQogICAgIC0gRCBjaGnhur9tIDY3NzUgdmnDqm4NCiAgICAgLSBFIGNoaeG6v20gOTc5NyB2aeG6v24NCiAgICAgLSBGIGNoaeG6v24gOTU0MiB2aeG6v24NCiAgICAgLSBHIGNoaeG6v20gMTEyOTIgdmnDqm4NCiAgICAgLSBIIGNoaeG6v20gODMwNCB2acOqbg0KICAgICAtIEkgY2hp4bq/bSA1NDIyIHZpw6puDQogICAgIC0gSiBjaGnhur9tIDI4MDggdmnDqm4gDQogIC0gUXVhIMSRw6J5IGNow7puZyB0YSBz4bq9IHRo4bqleSDEkcaw4bujYyBz4buRIGzGsOG7o25nIGPhu6dhICoqRyoqIGNoaeG6v20gbmhp4buBdSBuaOG6pXQgY+G7pSB0aOG7gyBsw6AgMTEyOTIga2ltIGPGsMahbmcgdHJvbmcgNyBjb2xvciB0csOqbg0KICAtIENoaeG6v20gdOG7tyBs4buHIHRo4bqlcCBuaOG6pXQgbMOgICoqSioqIGPFqW5nIGzDoCBjb2xvciB0aOG6pXAgbmjhuqV0IHRyb25nIGPDoWMgY29sb3IgbMOgIDI4MDgga2ltIGPGsMahbmcgDQogIC0gUXVhIGJp4buBdSDEkeG7kyB0csOqbiB0YSB0aOG6pXkgY29sb3IgKipEKiogbMOgIGNvbG9yIGPDsyBtw6B1IHPhuq9jIHThu5F0IG5o4bqldCBjaGnhur9tIDEyLjU2JSB0csOqbiB04buVbmcgc+G7kSB2acOqbiBraW0gY8awxqFuZyANCg0KDQpgYGB7cn0NCmggJT4lIGdyb3VwX2J5KGNsYXJpdHkpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIGdncGxvdChhZXMoY2xhcml0eSxuKSkrIA0KIGdlb21fY29sKGZpbGw9J25hdnlibHVlJykrDQogICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gMSwgY29sb3IgPSAncGluaycpICsgDQogICBsYWJzKHggPSAnQ2xhcml0eScsIHkgPSAnU+G7kSBsxrDhu6NuZycsdGl0bGU9J0jDrG5oMS41OiBT4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gxJHhu5kgdHJvbmcgc3Xhu5F0JykNCmBgYA0KDQoqKipOaOG6rW4geMOpdCBr4bq/dCBxdeG6oyoqKg0KDQogIC0gTmjDrG4gYmnhu4N1IMSR4buTIHRhIHRo4bqleSwgS+G6v3QgcXXhuqMgbmjhuq1uIMSRxrDhu6NjIGzDoCBt4buZdCBiaeG7g3UgxJHhu5MgZOG6oW5nIEJhcl9DaGFydCB0aOG7gyBoaeG7h24gZ+G7k20gc+G7kSBsxrDhu6NuZyBj4bunYSBj4buZdCBDbGFyaXR5KMSR4buZIHRyb25nIHN14buRdCBj4bunYSBraW0gY8awxqFuZyk6IEkxLCBTSTIsIFNJMSwgVlMyLCBWUzEsIFZWUzEsIElGDQogIC0gTMOgIGPDoWMgY+G6pXAgxJHhu5kgxJHDoW5oIGdpw6EgxJHhu5kgdGluaCBraGnhur90IChDbGFyaXR5KSBj4bunYSBraW0gY8awxqFuZyB0aGVvIHRpw6p1IGNodeG6qW4gR0lBIChWaeG7h24gxJDDoSBRdcO9IEhvYSBL4buzKS4gVGhhbmcgxJFvIG7DoHkgxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgcGjDom4gbG/huqFpIG3hu6ljIMSR4buZIHThuqFwIGNo4bqldCB2w6AgYmFvIHRo4buDIGLDqm4gdHJvbmcga2ltIGPGsMahbmcsIHbhu5tpIElGIGzDoCBj4bqlcCDEkeG7mSBjYW8gbmjhuqV0IChob8OgbiB0b8OgbiB0aW5oIGtoaeG6v3QpIHbDoCBJMSBsw6AgY+G6pXAgxJHhu5kgdGjhuqVwIG5o4bqldCAobmhp4buBdSB04bqhcCBjaOG6pXQgdsOgIGJhbyB0aOG7gSkNCiAgLSBOaMOsbiBiaeG7g3UgxJHhu5MgY2jDum5nIHRhIHPhur0gYmnhur90IHLDtSDEkcaw4bujYyBz4buRIGzGsOG7o25nIGPhu6dhIG3hu5dpIGxv4bqhaToNCiAgICAgLSBJMSBjaGnhur9tIDc0MSBraW0gY8awxqFuZyDEkeG7k25nIHRo4budaSDEkcOieSBjxaluZyBsw6AgY+G6pXAgxJHhu5kgdGjhuqVwIG5o4bqldCB0cm9uZyA4IGPhuqVwIMSR4buNIHRyb25nIHN14buRdCB2w6AgY2hp4bq/bSB04bu3IGzhu4cgMS4zNyUgdHJvbmcgNTM5NDAgdmnDqm4ga2ltIGPGsMahbmcuDQogICAgIC0gU0kyIGNoaeG6v20gOTE5NCB2acOqbiANCiAgICAgLSBTSTEgY2hp4bq/bSAxMzA2NSB2acOqbiDEkcOieSBjxaluZyBsw6AgbeG7qWMgxJHhu5kgY2hp4bq/bSBuaGnhu4F1IHZpw6puIGtpbSBjxrDGoW5nIG5o4bqldCB0cm9uZyBjw6FjIGxv4bqhaSwgxJHDonkgbMOgIGxv4bqhaSDDjXQgdOG6oXAgY2jhuqV0IChTbGlnaHRseSBJbmNsdWRlZCAxKSAtIEPDsyB0aOG7gyBuaMOsbiB0aOG6pXkgbeG7mXQgc+G7kSB04bqhcCBjaOG6pXQgbmjhu48gZMaw4bubaSDEkeG7mSBwaMOzbmcgxJHhuqFpIDEweC4gQ2hp4bq/bSAyNC4yMiUgdHLDqm4gdOG7lW5nIHPhu5EuDQogICAgIC0gVlMyIGNoaeG6v20gMTIyNTggdmnDqm4gLCDEkcOieSBjxaluZyBsw6AgbeG7mXQgbG/huqFpIGNoaeG6v20gdOG7tyBs4buHIGtow6EgY2FvIHRyw6puIHThu5VuZyB0aOG7gyBj4bulIHRo4buDIGzDoCAyMi43MyUuIFLhuqV0IMOtdCB04bqhcCBjaOG6pXQgKFZlcnkgU2xpZ2h0bHkgSW5jbHVkZWQgMikgLSBDw7MgdGjhu4MgbmjDrG4gdGjhuqV5IG3hu5l0IHbDoGkgdOG6oXAgY2jhuqV0IG5o4buPIGjGoW4gc28gduG7m2kgVlMxIGTGsOG7m2kgxJHhu5kgcGjDs25nIMSR4bqhaSAxMHggDQogICAgIC0gVlMxIGNoaeG6v20gODE3MSB2acOqbiANCiAgICAgLSBWVlMyIGNoaeG6v20gNTA2NiB2acOqbiBraW0gY8awxqFuZw0KICAgICAtIFZWUzEgY2hp4bq/bSAzNjU1IHZpw6puIGtpbSANCiAgICAgLSBJRiBjaGnhur9tIDE3OTAgdmnDqm4gxJHDonkgbMOgIGhvw6BuIHRvw6BuIHRpbmgga2hp4bq/dCAoSW50ZXJuYWxseSBGbGF3bGVzcykgLSBLaMO0bmcgY8OzIGLhuqV0IGvhu7MgdOG6oXAgY2jhuqV0IGhv4bq3YyBiYW8gdGjhu4MgbsOgbyBuaMOsbiB0aOG6pXkgxJHGsOG7o2MgZMaw4bubaSDEkeG7mSBwaMOzbmcgxJHhuqFpIDEweC4gRG8gaG/DoG4gdG/DoG4gdGluaCBraGnhur90IG7Dqm4gZ2nDoSB0aMOgbmggY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcgcuG6pXQgY2FvLg0KDQoNCmBgYHtyfQ0KaCU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2Uobj1uKCkpJT4lIGdncGxvdChhZXMoY3V0LG4pKSsgZ2VvbV9jb2woZmlsbD0nc2t5Ymx1ZScpK2dlb21fdGV4dChhZXMobGFiZWw9cGVyY2VudChuL2xlbmd0aChoJGNhcmF0KSkpLHZqdXN0PTEsIGNvbG9yPSdibGFjaycpK2xhYnMoeD0nTG/huqFpJyx5PSdT4buRIGzGsOG7o25nJyx0aXRsZT0nSMOsbmgxLjY6IFPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBjaOG6pXQgbMaw4bujbmcgxJHGsOG7nW5nIGPhuq90ICcpDQpgYGANCg0KKioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCoqKg0KDQogIC0gaCAlPiUgZ3JvdXBfYnkoY3V0KTogTmjDs20gZOG7ryBsaeG7h3UgdGhlbyBiaeG6v24gY3V0IChjaOG6pXQgbMaw4bujbmcgY+G6r3Qga2ltIGPGsMahbmcpLg0KICAtIHN1bW1hcmlzZShuPW4oKSk6IFTDrW5oIHThu5VuZyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRyb25nIG3hu5dpIG5ow7NtLCBnw6FuIGvhur90IHF14bqjIHbDoG8gYmnhur9uIG4uDQogIC0gcGVyY2VudCguLi4pKTogVMOtbmggdOG7tyBs4buHIHBo4bqnbiB0csSDbSBj4bunYSBuIChz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRyb25nIG3hu5dpIG5ow7NtKSBzbyB24bubaSB04buVbmcgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyAobGVuZ3RoKGgkY2FyYXQpKS4NCiAgLSBnZ3Bsb3QoYWVzKGN1dCxuKSk6IHThuqFvIG3hu5l0IGJp4buDdSDEkeG7kyBnZ3Bsb3QgduG7m2kgY3V0IGzDoCBiaeG6v24gxJHGsOG7o2Mgw6FuaCB44bqhIMSR4bq/biB0cuG7pWMgeCB2w6AgbiBsw6AgYmnhur9uIMSRxrDhu6NjIMOhbmggeOG6oSDEkeG6v24gdHLhu6VjIHkgKGJhbiDEkeG6p3UpLg0KICAtIGdlb21fY29sKGZpbGw9J3NreWJsdWUnKTogVGjDqm0gbGF5ZXIgaMOsbmggY+G7mXQgdsOgbyBiaeG7g3UgxJHhu5MgduG7m2kgbcOgdSB4YW5oIGRhIHRy4budaS4NCiAgLSBnZW9tX3RleHQoYWVzKGxhYmVsPSBwZXJjZW50KG4vbGVuZ3RoKGgkY2FyYXQpKSksdmp1c3QgPSAxLCBjb2xvcj0gJ2JsYWNrJyk6IFRow6ptIGxheWVyIHbEg24gYuG6o24gdsOgbyBiaeG7g3UgxJHhu5MuDQogICAgIC0gYWVzKGxhYmVsPSBwZXJjZW50KG4vbGVuZ3RoKGgkY2FyYXQpKSk6IEfDoW4gZ2nDoSB0cuG7iyB04bu3IGzhu4cgcGjhuqduIHRyxINtIMSRxrDhu6NjIHTDrW5oIHRvw6FuIOG7nyBixrDhu5tjIDIgY2hvIG5ow6NuIHbEg24gYuG6o24uDQogICAgIC0gdmp1c3QgPSAxOiBW4buLIHRyw60gdsSDbiBi4bqjbiDEkcaw4bujYyDEkWnhu4F1IGNo4buJbmggbMOqbiB0csOqbiBjw7luZyBj4bunYSBj4buZdCAodmp1c3QgPSAxKS4NCiAgICAgLSBjb2xvcj0gJ2JsYWNrJzogVsSDbiBi4bqjbiBjw7MgbcOgdSDEkWVuLg0KICAtIGxhYnMoeCA9ICdMb+G6oWknLCB5PSAnIFPhu5EgbMaw4bujbmcnKTogVGjDqm0gbmjDo24gY2hvIHRy4bulYyB4IChMb+G6oWkpIHbDoCB0cuG7pWMgeSAoU+G7kSBsxrDhu6NuZykuDQoNCkJp4buDdSDEkeG7kyBuw6B5IHTGsMahbmcgdOG7sSBuaMawIGJp4buDdSDEkeG7kyB0csaw4bubYywgbmjGsG5nIHRoYXkgdsOsIGhp4buDbiB0aOG7iyBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHR1eeG7h3QgxJHhu5FpIChuKSwgbsOzIGhp4buDbiB0aOG7iyB04bu3IGzhu4cgcGjhuqduIHRyxINtIGPhu6dhIG3hu5dpIG5ow7NtIHNvIHbhu5tpIHThu5VuZyBz4buRIGtpbSBjxrDGoW5nLg0KVOG7tyBs4buHIHBo4bqnbiB0csSDbSDEkcaw4bujYyB0w61uaCBi4bqxbmcgY8OhY2ggY2hpYSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRyb25nIG3hu5dpIG5ow7NtIChuKSBjaG8gdOG7lW5nIHPhu5Ega2ltIGPGsMahbmcgKGxlbmd0aChoJGNhcmF0KSkgdsOgIG5ow6JuIHbhu5tpIDEwMCDEkeG7gyBjaHV54buDbiB0aMOgbmggZOG6oW5nIHBo4bqnbiB0csSDbS4NClbEg24gYuG6o24gaGnhu4NuIHRo4buLIHRyw6puIG3hu5dpIGPhu5l0IHRo4buDIGhp4buHbiB04bu3IGzhu4cgcGjhuqduIHRyxINtIG7DoHkuDQoNCioqKk5o4bqtbiB4w6l0IGvhur90IHF14bqjKioqDQoNCiAgLSBL4bq/dCBxdeG6oyBuaOG6rW4gxJHGsOG7o2MgbMOgIG3hu5l0IGJp4buDdSDEkeG7kyBk4bqhbmcgQmFyX0NoYXJ0IHRo4buDIGhp4buHbiBn4buTbSBz4buRIGzGsOG7o25nIGPhu6dhIG5o4buvbmcgbG/huqFpIGtpbSBjxrDGoW5nKEZhaXIsIEdvb2QsIFZlcnkgZ29vZCwgUHJlbWl1bSwgSWRlYWwpDQogIC0gTmjDrG4gYmnhu4N1IMSR4buTIGNow7puZyB0YSBz4bq9IGJp4bq/dCByw7UgxJHGsOG7o2MgdOG7tyBs4buHIHBow6JuIHRyxINtIGPhu6dhICh0w61uaCBi4bqxbmcgY8OhY2ggY2hpYSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRyb25nIG3hu5dpIG5ow7NtIChuKSBjaG8gdOG7lW5nIHPhu5Ega2ltIGPGsMahbmcgKGxlbmd0aChoJGNhcmF0KSkgdsOgIG5ow6JuIHbhu5tpIDEwMCDEkeG7gyBjaHV54buDbiB0aMOgbmggZOG6oW5nIHBo4bqnbiB0csSDbSkgY+G7p2EgbeG7l2kgbG/huqFpIGtpbSBjxrDGoW5nOg0KICAgICAtIEZhaXIgY2hp4bq/bSAzJSBraW0gY8awxqFuZw0KICAgICAtIEdvb2QgY2hp4bq/bSA5LjElIGtpbSBjxrDGoW5nDQogICAgIC0gVmVyeSBnb29kIGNoaeG6v20gMjIuNCUga2ltIGPGsMahbmcgDQogICAgIC0gUHJlbWl1bSBjaGnhur9tIDI1LjYlIGtpbSBjxrDGoW5nDQogICAgIC0gSWRlYWwgY2hp4bq/bSA0MCUga2ltIGPGsMahbmcgDQogIC0gUXVhIMSRw6J5IGNow7puZyB0YSBz4bq9IHRo4bqleSDEkcaw4bujYyBz4buRIGzGsOG7o25nIGPhu6dhICoqSWRlYWwqKiBjaGk1NXVhIMSRw6J5IGNow7puZyB0YSBz4bq9IHRo4bqleSDEkcaw4bujYyBz4buRIGzGsOG7o25nIGPhu6dhICoqSWRlYWwqKiBjaGk1NeG6v20gdOG7tyBsw6puIHBow6JuIHRyxINtIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgbmhp4buBdSBuaOG6pXQgNDAlIHRyw6puIDEwMCUgDQogIC0gQ2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCBsw6AgKipGYWlyKiogbMOgIDMlIGtpbSBjxrDGoW5nIA0KICAtIFPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgZ2nhuqNtIGThuqduIHThu6sgSWRlYWwgxJHhur9uIEZhaXINCiAgLSBT4buRIGzGsOG7o25nIGxv4bqhaSBs4bubbiBuaOG6pXQgdsOgIG5o4buPIGNow6puaCBs4buHY2ggduG7m2kgbmhhdSBoxqFuICoqMTMgbOG6p24qKg0KDQoNCmBgYHtyfQ0KaCU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2Uodj0gdmFyKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gdikpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQodiwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAncGluaycpICsNCiAgICBsYWJzKHggPSAnY3V0JywgeSA9ICdWYXInLHRpdGxlPSdIw6xuaCAxLjc6UGjGsMahbmcgc2FpIGPhu6dhIGNhcmF0IHRoZW8gYmnhur9uIGNo4bqldCBsxrDhu6NuZyDEkcaw4budbmcgY+G6r3QgJykNCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oKioqDQoNCiAgLSBzdW1tYXJpc2UodiA9IHZhcihjYXJhdCkpOiBUcm9uZyBt4buXaSBuaMOzbSDEkcaw4bujYyB04bqhbyDhu58gYsaw4bubYyAyLCBtw6MgbsOgeSB0w61uaCB0b8OhbiBwaMawxqFuZyBzYWkgY+G7p2EgYmnhur9uIGNhcmF0LiBL4bq/dCBxdeG6oyBsw6AgbeG7mXQgdOG6rXAgZOG7ryBsaeG7h3UgbeG7m2kgduG7m2kgY8OhYyBj4buZdCBjdXQgdsOgIHYsIHRyb25nIMSRw7MgdiDEkeG6oWkgZGnhu4duIGNobyBwaMawxqFuZyBzYWkgY+G7p2EgbeG7l2kgbmjDs20gY3V0Lg0KIA0KKioqTmjhuq1uIHjDqXQga+G6v3QgcXXhuqMqKioNCg0KIC0gUGjGsMahbmcgc2FpICh0aeG6v25nIEFuaDogVmFyaWFuY2UpIGzDoCBwaMOpcCDEkW8gbeG7qWMgY2jDqm5oIGzhu4djaCBnaeG7r2EgY8OhYyBz4buRIGxp4buHdSB0cm9uZyBt4buZdCB04bqtcCBk4buvIGxp4buHdSB0cm9uZyB0aOG7kW5nIGvDqiANCiAgLSBEw6J5IGzDoCBsw6AgbeG7mXQgYmnhu4N1IMSRw7IgZGFuZyBCYXJfQ2hhcnQgdGjhu4MgaGnhu4duIG3hu6ljIMSR4buZIGNoZW5oIGzhu4djaCBj4bunYSBiaeG6v24gY3V0KGNo4bqldCBsxrDhu6NuIMSRxrDhu51uZyBj4bqvdCkgdGhlbyBiaeG6v24gY3V0DQogIC0gQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgbeG7qWMgxJHhu5kgY2jDqm5oIGzhu4djaCBnaeG7r2EgY8OhYyBiaeG6v24gY+G7p2EgImN1dCIgZGFvIMSR4buZbmcgdHJvbmcga2hv4bqjbmcgMC4xOSDEkeG6v24gMC4yNyANCiAgLSBOaMOzbSAiRmFpciIgY8OzIG3hu6ljIMSR4buZIGNow6puaCBs4buHY2ggY2FvIG5o4bqldCAoa2hv4bqjbmcgMC4yNyApLg0KICAtIE5ow7NtICJJZGVhbCIgY8OzIG3hu6ljIMSR4buNIGNow6puaCBs4buHY2ggdGjhuqVwIG5o4bqldCAoa2hv4bqjbmcgMC4xOSApLg0KDQpTdXkgcmEsIGtp4buDdSBj4bqvdCBraW0gY8awxqFuZyDhuqNuaCBoxrDhu59uZyDEkeG6v24gbeG7qWMgxJHhu5kgY2jDqm5oIGzhu4djaCBj4bunYSBiaeG6v24gImNhcmF0Ii5LaW0gY8awxqFuZyBjw7Mga2nhu4N1IGPhuq90ICJGYWlyIHbDoCBQcmVtaXVtbCIgY8OzIG3hu6ljIMSR4buNIGNow6puaCBs4buHY2ggY2FvIG5o4bqldCB24buBIGJp4bq/biAiY2FyYXQiIHThu6ljIGzDoCBjw7MgxJHhu5kgYmnhur9uIHRoacOqbiBjYW8gbmjhuqV0IHbhu4Ega8OtY2ggdGjGsOG7m2MgY2FyYXQuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBraW0gY8awxqFuZyB0cm9uZyBuaMOzbSAiRmFpciB2w6AgUHJlbWl1bSIgY8OzIHRo4buDIGPDsyBrw61jaCB0aMaw4bubYyBjYXJhdCBjaMOqbmggbOG7h2NoIG5oYXUgxJHDoW5nIGvhu4MuDQpWZDpQaMawxqFuZyBzYWkgY+G7p2EgRmFpciBjYW8gaMahbiBJZGVhbC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIHRy4buNbmcgbMaw4bujbmcgY+G7p2Ega2ltIGPGsMahbmcgRmFpciAgcGjDom4gdMOhbiBy4buZbmcgaMahbiBxdWFuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oIA0KDQpgYGB7cn0NCmggJT4lIGdyb3VwX2J5KGN1dCxjb2xvcikgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbikpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jb2xvcikgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDAsIGNvbG9yID0gJ2JsYWNrJykgKw0KICAgIGxhYnMoeCA9ICdMb+G6oWknLCB5ID0gJ1Phu5EgbMaw4bujbmcnLHRpdGxlPSdIw6xuaDEuODogU+G7kSBsxrDhu6NuZyB0aGVvIGNo4bqldCBsxrDhu6NuZyDEkcaw4budbmcgY+G6r3QgdsOgIG3DoHUnKQ0KYGBgDQoNCg0KKioqR2nhuqNpIHRow61jaCBjw6J1IGzhu4duaCoqKg0KDQogICAtIEjDoG0gZ3JvdXBfYnkoKSB04burIHRoxrAgdmnhu4duIGRwbHlyIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIG5ow7NtIGPDoWMgaMOgbmcgdHJvbmcgaCB0aGVvIGPDoWMgZ2nDoSB0cuG7iyBkdXkgbmjhuqV0IGPhu6dhIGhhaSBiaeG6v24gY3V0IHbDoCBjb2xvci7EkGnhu4F1IG7DoHkgZ2nDunAgcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgcmnDqm5nIGJp4buHdCBjaG8gdOG7q25nIG5ow7NtIMSRxrDhu6NjIHThuqFvIHRow6BuaCB04burIHPhu7Ega+G6v3QgaOG7o3AgY+G7p2EgY8OhYyBnacOhIHRy4buLIGN1dCB2w6AgY29sb3IuDQogICAtIEjDoG0gc3VtbWFyaXNlKCkgdOG7qyB0aMawIHZp4buHbiBkcGx5ciDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyB0w61uaCB0b8OhbiBt4buZdCB04bqtcCBo4bujcCBjw6FjIHRo4buRbmcga8OqIHTDs20gdOG6r3QgY2hvIG3hu5dpIG5ow7NtIMSRxrDhu6NjIHThuqFvIHJhIOG7nyBixrDhu5tjIDIuQmnhu4N1IHRo4bupYyBuID0gbigpIGLDqm4gdHJvbmcgc3VtbWFyaXNlKCkgxJHhur9tIHPhu5EgbMaw4bujbmcgY8OhYyBwaOG6p24gdOG7rSB0cm9uZyBt4buXaSBuaMOzbSB2w6AgxJHhurd0IGvhur90IHF14bqjIHbDoG8gY+G7mXQgbeG7m2kgY8OzIHTDqm4gbi4NCiAgLSBIw6BtIGdncGxvdCgpIHThu6sgdGjGsCB2aeG7h24gZ2dwbG90MiDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyBraOG7n2kgdOG6oW8gbeG7mXQgxJHhu5FpIHTGsOG7o25nIGdncGxvdCwgbuG7gW4gdOG6o25nIMSR4buDIHjDonkgZOG7sW5nIGJp4buDdSDEkeG7ky4NCiAgLSBCaeG7g3UgdGjhu6ljIGFlcyh4ID0gY3V0LCB5ID0gbikgdHJvbmcgZ2dwbG90KCkgeMOhYyDEkeG7i25oIGPDoWMgYmnhur9uIMSRxrDhu6NjIHPhu60gZOG7pW5nIMSR4buDIMOhbmggeOG6oSBk4buvIGxp4buHdSB2w6BvIGPDoWMgdHLhu6VjIHggdsOgIHkgY+G7p2EgYmnhu4N1IMSR4buTLg0KICAtIEJp4bq/biBjdXQgxJHGsOG7o2Mgc+G7rSBk4bulbmcgdHLDqm4gdHLhu6VjIHgsIMSR4bqhaSBkaeG7h24gY2hvIGPDoWMgbmjDs20gKGNhdGVnb3JpZXMpLg0KICAtIEJp4bq/biBuIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyw6puIHRy4bulYyB5LCDEkeG6oWkgZGnhu4duIGNobyBz4buRIGzGsOG7o25nIHBo4bqnbiB04butIHRyb25nIG3hu5dpIG5ow7NtLg0KICAtIEjDoG0gZ2VvbV9jb2woKSB04bqhbyByYSBt4buZdCBiaeG7g3UgxJHhu5MgY+G7mXQuDQogIC0gVGhhbSBz4buRIHBvc2l0aW9uID0gJ2RvZGdlJyDEkeG6o20gYuG6o28gY8OhYyBj4buZdCDEkcaw4bujYyB44bq/cCBj4bqhbmggbmhhdSBt4buZdCBjw6FjaCB0w6FjaCBiaeG7h3QsIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gbmhhdSwgZ2nDunAgZOG7hSBkw6BuZyBwaMOibiBiaeG7h3QgY8OhYyBuaMOzbSBraMOhYyBuaGF1Lg0KICAtIEjDoG0gZmFjZXRfd3JhcCgpIHThu6sgdGjGsCB2aeG7h24gZ2dwbG90MiDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyB04bqhbyByYSBuaGnhu4F1IGJp4buDdSDEkeG7kyBjb24sIG3hu5dpIGJp4buDdSDEkeG7kyBjb24gdGjhu4MgaGnhu4duIGThu68gbGnhu4d1IGNobyBt4buZdCBnacOhIHRy4buLIGR1eSBuaOG6pXQgY+G7p2EgYmnhur9uIGNvbG9yLkvDvSBoaeG7h3UgfiB0csaw4bubYyBjb2xvciBjaG8gYmnhur90IGNvbG9yIHPhur0gxJHGsOG7o2Mgc+G7rSBk4bulbmcgxJHhu4MgdOG6oW8gcmEgY8OhYyBt4bq3dCAoZmFjZXQpIGPhu6dhIGJp4buDdSDEkeG7ky4NCiAgLSBIw6BtIGdlb21fdGV4dCgpIHThu6sgdGjGsCB2aeG7h24gZ2dwbG90MiDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyB0aMOqbSBjw6FjIG5ow6NuIGThu68gbGnhu4d1IHbDoG8gYmnhu4N1IMSR4buTLkJp4buDdSB0aOG7qWMgYWVzKGxhYmVsID0gbikgeMOhYyDEkeG7i25oIHLhurFuZyBu4buZaSBkdW5nIGPhu6dhIG5ow6NuIHPhur0gbOG6pXkgdOG7qyBj4buZdCBuLCBjaOG7qWEgc+G7kSBsxrDhu6NuZyBjw6FjIHBo4bqnbiB04butIHRyb25nIG3hu5dpIG5ow7NtLlRoYW0gc+G7kSB2anVzdCA9IDIgxJFp4buBdSBjaOG7iW5oIHbhu4sgdHLDrSBj4bunYSBuaMOjbiB0aGVvIGNoaeG7gXUgZOG7jWMsIGRpIGNodXnhu4NuIGNow7puZyBsw6puIDIgxJHGoW4gduG7iyBzbyB24bubaSB24buLIHRyw60gbeG6t2MgxJHhu4tuaC5UaGFtIHPhu5EgY29sb3IgPSAnZ3JlZW4nIMSR4bq3dCBtw6B1IGPhu6dhIG5ow6NuIHRow6BuaCB4YW5oIGzhu6VjLg0KICAtIEjDoG0gbGFicygpIHThu6sgdGjGsCB2aeG7h24gZ2dwbG90MiDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyDEkeG6t3QgbmjDo24gY2hvIGPDoWMgdHLhu6VjIHggdsOgIHkgY+G7p2EgYmnhu4N1IMSR4buTLlRo4bq7IHggPSAnTG/huqFpJyDEkeG6t3QgbmjDo24gY2hvIHRy4bulYyB4IHRow6BuaCAiTG/huqFpIiAobmdoxKlhIGzDoCAiSOG6oW5nIG3hu6VjIikuVGjhursgeSA9ICdT4buRIGzGsOG7o25nJyDEkeG6t3QgbmjDo24gY2hvIHRy4bulYyB5IHRow6BuaCAiU+G7kSBsxrDhu6NuZyIgKG5naMSpYSBsw6AgIlPhu5EgbMaw4bujbmcgcGjhuqduIHThu60iKS4gDQogIA0KKioqTmjhuq1uIHjDqXQga+G6v3QgcXXhuqMqKioNCg0KICAtIFRhIG5o4bqtbiDEkcaw4bujYyBsw6AgbeG7mXQgYmnhu4N1IMSR4buTIGThuqFuZyBCYXJfQ2hhcnQgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgY+G7p2EgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcgdHJvbmcgYmnhur9uICoqY3V0KiogdGhlbyB04burbmcgbmjDs20gZ+G7k20gNyBiaeG7g3UgxJHhu5Mgbmjhu48gdMawxqFuZyDhu6luZyB24bubaSB04burbmcgbG/huqFpIHRyb25nIGPhu5l0ICoqQ29sb3IqKih04bupYyBsw6AgY8OhYyBsb+G6oWkgbsaw4bubYyBraW0gY8awxqFuZyApKEQsRSxGLEcsSCxJLEopDQogIC0gTmjDrG4gaMOsbmggMS44IHRhIHRo4bqleSBsb+G6oWkgKipJZGVhbCoqIGx1w7RuIGPDsyBz4buRIGzGsOG7o25nIGzhu5tuIG5o4bqldCB0cm9uZyA3IG5ow7NtIHRyb25nIGJp4bq/biBDb2xvcg0KICAtIE5nxrDhu6NjIGzhuqFpIGzDoCBsb+G6oWkgRmFpciBsdcO0biBjw7Mgc+G7kSBsxrDGoW5nIHRo4bqlcCBuaOG6pXQgdHJvbmcgNyBuaMOzbSANCiAgLSBDw6FjIGJp4buDdSDEkeG7kyBsdcO0biBjw7MgeHUgaMaw4bubbmcgdMSDbmcgc+G7kSBsxrDhu51uZyB04burIEZhaXIgxJHhur9uIElkZWFsDQogIC0gVHJvbmcgNyBiaeG7g3UgxJHhu5MgdGjDrCBiaeG7g3UgxJHhu5MgduG7gSAqKkcqKiBjaGnhur9tIHPhu5EgbMaw4bujbmcgdHJvbmcgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcgbMOgIGzhu5tuIG5o4bqldCBj4bulIHRo4buDIGzDoCBjaGnhur9tIDIwLjglIHRyw6puIHThu5VuZy4gTmfGsOG7o2MgbOG6oWkgdGjhuqVwIG5o4bqldCBsw6Agbsaw4bubYyAqKkoqKiBjaGnhur9tIDUuMjElLiANClN1eSByYSB0YSB0aOG6pXkga2hpIGNoaWEgbmjhu48gcmEgdOG7q25nIG5ow7NtIG5oxrAgduG6p3kgY2jDum5nIHRhIHPhur0gZOG7hSBkw6BuZyBuaMOsbiB0aOG6pXkgc+G7sSBwaMOibiBi4buRIHPhu5EgbMaw4bujbmcgY+G7p2EgbeG7l2kgbG/huqFpLiANCg0KYGBge3J9DQpoICU+JSBncm91cF9ieShjdXQsY2xhcml0eSkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbikpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jbGFyaXR5KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLHZqdXN0ID0gMA0KICAgICAgICAgICAgLCBjb2xvciA9ICdyZWQnKSArDQogICAgbGFicyh4ID0gJ0xv4bqhaScsIHkgPSAnU+G7kSBsxrDhu6NuZycsIHRpdGxlPSdIw6xuaCAxLjk6IFPhu5EgbMaw4bujbmcga8OtbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIMSRxrDhu51uZyBj4bqvdCB2w6AgxJHhu5kgdHJvbmcgc3Xhu5F0JykNCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oKioqKg0KDQogIC0gZ3JvdXBfYnkoY3V0LCBjbGFyaXR5KTogTmjDs20gZOG7ryBsaeG7h3UgdGhlbyBjw6FjIGPhu5l0IGN1dCB2w6AgY2xhcml0eS4gxJBp4buBdSBuw6B5IHThuqFvIHJhIGPDoWMgbmjDs20gcmnDqm5nIGJp4buHdCBjaG8gbeG7l2kgZ2nDoSB0cuG7iyBr4bq/dCBo4bujcCBkdXkgbmjhuqV0IGPhu6dhIGN1dCB2w6AgY2xhcml0eQ0KICAtIE5ow7NtIGThu68gbGnhu4d1IHRoZW8gY3V0IHbDoCBjbGFyaXR5Lg0KDQpUw61uaCBz4buRIGzGsOG7o25nIHF1YW4gc8OhdCB0cm9uZyBt4buXaSBuaMOzbS4NCg0KVOG6oW8gYmnhu4N1IMSR4buTIHRoYW5oIHbhu5tpIG3hu5l0IHRoYW5oIGNobyBt4buXaSBr4bq/dCBo4bujcCBkdXkgbmjhuqV0IGPhu6dhIGN1dCB2w6AgY2xhcml0eSwgxJHGsOG7o2MgdMO0IG3DoHUgdGhlbyBjbGFyaXR5Lg0KDQpW4buLIHRyw60gY8OhYyB0aGFuaCBj4bqhbmggbmhhdSDEkeG7gyB0csOhbmggY2jhu5NuZyBjaMOpby4NCg0KVGjDqm0gbmjDo24gdsSDbiBi4bqjbiDEkeG7gyBoaeG7g24gdGjhu4sgc+G7kSBsxrDhu6NuZyB0csOqbiBjw6FjIHRoYW5oLg0KDQpOaMOjbiB0cuG7pWMgdsOgIHRow6ptIHRpw6p1IMSR4buBIGNobyBiaeG7g3UgxJHhu5MuDQoNCioqKk5o4bqtbiB4w6l0IGvhur90IHF14bqjKioqDQoNCiAgLSBUYSBuaOG6rW4gxJHGsOG7o2MgbMOgIG3hu5l0IGJp4buDdSDEkeG7kyBk4bqhbmcgQmFyX0NoYXJ0IHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGPhu6dhIGPDoWMgbG/huqFpIGtpbSBjxrDGoW5nIHRyb25nIGJp4bq/biAqKmN1dCoqIHRoZW8gdOG7q25nIG5ow7NtIGfhu5NtIDcgYmnhu4N1IMSR4buTIG5o4buPIHTGsMahbmcg4bupbmcgduG7m2kgdOG7q25nIGxv4bqhaSB0cm9uZyBj4buZdCAqKkNsYXJpdHkqKih04bupYyBsw6AgY8OhYyBsb+G6oWkgbsaw4bubYyBraW0gY8awxqFuZyApKEkxLFNJMixTSTEsVlMyLFZTMSxWVlMyLFZWUzEsw4wpDQogIC0gU+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBsb+G6oWkgSWRlYWwgbHXDtG4gY2hp4bq/bSBz4buRIGzGsOG7o25nIG5oaeG7gXUgdHJvbmcgY8OhYyBuaMOzbSBiaeG6u3UgxJHDsiBuaOG7jw0KICAtIFRyb25nIMSRw7MgdGEgdGjhuqV5IFNJMSggxJHDonkgbMOgIGxv4bqhaSDDjXQgdOG6oXAgY2jhuqV0IChTbGlnaHRseSBJbmNsdWRlZCAxKSAtIEPDsyB0aOG7gyBuaMOsbiB0aOG6pXkgbeG7mXQgc+G7kSB04bqhcCBjaOG6pXQgbmjhu48gZMaw4bubaSDEkeG7mSBwaMOzbmcgxJHhuqFpIDEweCkgY2hp4bq/bSBz4buRIGzGsOG7o25nIG5oaeG7gXUgbmjhuqV0IHRyb25nIGPDoWMgbmjDs20gY+G7pSB0aOG7gyBsw6AgMjQuMjIlLiBOZ8aw4bujYyBs4bqhaSB0aOG6pXAgbmjhuqV0IGzDoCBJMShj4bqlcCDEkeG7mSB0aOG6pXAgbmjhuqV0IHRyb25nIDggY+G6pXAgxJHhu40gdHJvbmcgc3Xhu5F0KSBjaGnhur9tIDEuMzclIHRyw6puIHThu5VuZyB0aOG7gy4NCiANCiAgDQoNCg0KYGBge3J9DQpoICU+JSBncm91cF9ieShjbGFyaXR5LGNvbG9yKSAlPiUgc3VtbWFyaXNlKG49bigpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY2xhcml0eSx5ID0gbikpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBmYWNldF93cmFwKH5jb2xvcikgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSx2anVzdCA9IDAsIGNvbG9yID0gJ3JlZCcpICsNCiAgICBsYWJzKHggPSAnY2xhcml0eScsIHkgPSAnU+G7kSBsxrDhu6NuZycsdGl0bGU9J0jDrG5oIDEuMTA6IFPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyDEkeG7mSB0cm9uZyBzdeG7kXQgdsOgIG3DoHUnKQ0KYGBgDQogDQoqKipOaOG6rW4geMOpdCBiaeG7g3UgxJHhu5MqKioNCg0KICAtICBUYSBuaOG6rW4gxJHGsOG7o2MgbMOgIG3hu5l0IGJp4buDdSDEkeG7kyBk4bqhbmcgQmFyX0NoYXJ0IHRo4buDIGhp4buHbiBz4buRIGzGsOG7o25nIGPhu6dhIGPDoWMgbG/huqFpIGtpbSBjxrDGoW5nIHRyb25nIGJp4bq/biAqKmNsYXJpdHkqKiB0aGVvIHThu6tuZyBuaMOzbSBn4buTbSA3IGJp4buDdSDEkeG7kyBuaOG7jyB0xrDGoW5nIOG7qW5nIHbhu5tpIHThu6tuZyBsb+G6oWkgdHJvbmcgY+G7mXQgKipjb2xvcioqKHThu6ljIGzDoCBjw6FjIG3DoHUga2ltIGPGsMahbmcgKShELEUsRixHLEgsSSxKKQ0KIC0gUXVhIMSRw6J5IHRhIHPhur0gdGjhuqV5IHLDtSDEkeG7mSBwaMOibiB0w6FuIHbhu4Egc+G7kSBsxrDhu6NuZyBj4bunYSBj4bunYSBj4buZdCBjbGFyaXR5IHRoZW8gY8OhYyBuaMOzbSBjb2xvcmNvbG9yDQogLSBOaMOsbiB2w6BvIGJp4buDdSDEkeG7kyB0YSB0aOG6pXkgc+G7kSBsxrDhu6NuZyBj4bunYSBjb2xvciBHIHbhu4EgxJHhu5kgdHJvbmcgc3Xhu5F0IGPDsyBs4bubbiBuaOG6pXQgY+G7pSB0aOG7gyBsw6AgMjAuOTMlLCBuZ8aw4bujYyBs4bqhaSBsw6AgY29sb3IgSiB0aOG6pXAgbmjhuqV0IHbhu5tpIDUuMjElDQpOw7Mgc+G6vSBwaMOibiBjaGlhIGThu68gbGnhu4d1IHRow6BuaCBjw6FjIG5ow7NtIHJpw6puZyBiaeG7h3QsIG3hu5dpIG5ow7NtIGNo4bupYSBjw6FjIHF1YW4gc8OhdCBjw7MgY8O5bmcgxJHhu5kgcsO1IHLDoG5nIHbDoCBtw6B1IHPhuq9jLiBCw6puIHRyb25nIG3hu5dpIG5ow7NtLCBow6BtIHN1bW1hcmlzZSDEkcaw4bujYyBz4butIGThu6VuZyDEkeG7gyDEkeG6v20gc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgdsOgIGfDoW4ga+G6v3QgcXXhuqMgY2hvIG3hu5l0IGJp4bq/biBt4bubaSDEkcaw4bujYyDEkeG6t3QgdMOqbiBsw6Agbi4gQmnhur9uIG4gbsOgeSBz4bq9IGNo4bupYSBz4buRIGzGsOG7o25nIHF1YW4gc8OhdCBjw7MgY8O5bmcgxJHhu5kgcsO1IHLDoG5nIHbDoCBtw6B1IHPhuq9jIC4gxJBp4buBdSBuw6B5IGNobyBwaMOpcCBi4bqhbiBk4buFIGTDoG5nIHNvIHPDoW5oIHBow6JuIGLhu5Egc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgdGhlbyDEkeG7mSByw7UgcsOgbmcgdHLDqm4gY8OhYyBtw6B1IHPhuq9jIGtow6FjIG5oYXUuDQoNCg0KDQoNCg0KYGBge3J9DQpoJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpJT4lc3VtbWFyaXNlKG09bWVhbih0YWJsZSkpJT4lZ2dwbG90KGFlcyh4PWN1dCwgeT0gbSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbj0nZG9kZ2UnKSsNCiAgZmFjZXRfd3JhcCh+Y29sb3IpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPSByb3VuZChtKSksIHZqdXN0PTIsIGNvbG9yPSdwaW5rJykrIGxhYnMoeD0gJ2N1dCcsIHk9ICdNZWFuJyx0aXRsZT0nSMOsbmggMS4xMTogR2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSB0YWJsZSB0aGVvIGN1dCB2w6AgY29sb3InKQ0KYGBgDQoNCkJp4buDdSB0aOG7qWMgYWVzKGxhYmVsID0gcm91bmQobSkpIHjDoWMgxJHhu4tuaCBy4bqxbmcgbuG7mWkgZHVuZyBj4bunYSBuaMOjbiBz4bq9IGzhuqV5IHThu6sgY+G7mXQgbSwgY2jhu6lhIHRydW5nIGLDrG5oIGPhu6dhIGLhuqNuZyB04bqnbiBzdeG6pXQsIG5oxrBuZyDEkcaw4bujYyBsw6BtIHRyw7JuIHRyxrDhu5tjIGtoaSBoaeG7g24gdGjhu4suDQoNCioqKk5o4bqtbiB4w6l0IGJp4buDdSDEkeG7kyoqKg0KDQpUYSBjw7MgdGjhu4MgbmhhbmggY2jDs25nIG7huq9tIGLhuq90IHbDoCBzbyBzw6FuaCBjw6FjIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgYmnhur9uICJ0YWJsZSIgdHJvbmcgY8OhYyBuaMOzbSBraMOhYyBuaGF1IMSRxrDhu6NjIHjDoWMgxJHhu4tuaCBi4bufaSAiY3V0IiB2w6AgImNvbG9yIi4NCsOdIG5naMSpYSBj4bunYSBiaeG7g3UgxJHhu5MgbMOgIGhp4buDbiB0aOG7iyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAidGFibGUiIHRoZW8gY8OhYyBt4bupYyDEkeG7mSAiY3V0IiB2w6AgImNvbG9yIiwgZ2nDunAgaGnhu4N1IHLDtSBoxqFuIHbhu4Egc+G7sSBwaMOibiBi4buRIGPhu6dhIGThu68gbGnhu4d1LiBExrDhu5tpIMSRw6J5IGzDoCB2w60gZOG7pSB24buBIGPDoWNoIHPhu60gZOG7pW5nIGJp4buDdSDEkeG7kyBuw6B5Og0KQmnhu4N1IMSR4buTIG7DoHkgY8OzIHRo4buDIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIG5nw6BuaCBjw7RuZyBuZ2hp4buHcCBraW0gaG/DoG4gxJHhu4Mgc28gc8OhbmggdHJ1bmcgYsOsbmggY+G7p2EgY+G7mXQgInRhYmxlIiAobeG7mXQgY2jhu4kgc+G7kSB24buBIGNo4bqldCBsxrDhu6NuZyBj4bunYSB2acOqbiBraW0gY8awxqFuZykgZ2nhu69hIGPDoWMgbeG7qWMgxJHhu5kgImN1dCIgKGPDoWNoIHjhu60gbMO9IHZpw6puIGtpbSBjxrDGoW5nKSB2w6AgImNvbG9yIiAobcOgdSBz4bqvYyBj4bunYSB2acOqbiBraW0gY8awxqFuZykuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgZ2nDunAgY2hvIGPDoWMgbmjDoCBz4bqjbiB4deG6pXQga2ltIGPGsMahbmcgaGnhu4N1IMSRxrDhu6NjIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgY8OhY2ggeOG7rSBsw70gdsOgIGNo4bqldCBsxrDhu6NuZyBj4bunYSBz4bqjbiBwaOG6qW0uDQoNCg0KDQpgYGB7cn0NCmglPiUgZ3JvdXBfYnkoY3V0LCBjb2xvciklPiVzdW1tYXJpc2UobT12YXIodGFibGUpKSU+JWdncGxvdChhZXMoeD1jdXQsIHk9IG0pKSsNCiAgZ2VvbV9jb2wocG9zaXRpb249J2RvZGdlJyxmaWxsPSdncmV5JykrDQogIGZhY2V0X3dyYXAofmNvbG9yKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gcm91bmQobSkpLCB2anVzdD0wLCBjb2xvcj0ncmVkJykrIGxhYnMoeD0gJ2N1dCcsIHk9ICdWYXInLHRpdGxlPSdIw6xuaCAxLjEyOiBQaMawxqFuZyBzYWkgY+G7p2EgdGFibGUgdGhlbyBjdXQgdsOgIGNvbG9yJykNCmBgYA0KDQogDQoqKipOaOG6rW4geMOpdCBiaeG7g3UgxJHhu5MqKioNCg0KIFTDoWMgZOG7pW5nIGPhu6dhIGJp4buDdSDEkeG7kyBuw6B5IGzDoCBoaeG7g24gdGjhu4sgcGjGsMahbmcgc2FpIGPhu6dhIGPhu5l0ICJ0YWJsZSIgdGhlbyBjw6FjIG3hu6ljIMSR4buZICJjdXQiIHbDoCAiY29sb3IiLCBjaG8gdGEgY8OhaSBuaMOsbiB24buBIHPhu7EgYmnhur9uIMSR4buZbmcgY+G7p2EgZOG7ryBsaeG7h3UuDQpRdWEgxJHDonkgdGEgdGjhuqV5IMSRxrDhu6NjIHBoxrDGoW5nIHNhaSBj4bunYSBt4buXaSBuaMOzbSBjb2xvciDEkeG7gXUgY8OzIHh1IGjGsOG7m25nIGdp4bqjbSBk4bqnbiB04burIEZhaXIgeHXhu5FuZyBJZGVhbA0KDQpTdXkgcmEsIGtp4buDdSBj4bqvdCBraW0gY8awxqFuZyDhuqNuaCBoxrDhu59uZyDEkeG6v24gbeG7qWMgxJHhu5kgY2jDqm5oIGzhu4djaCBj4bunYSBiaeG6v24gImNhcmF0Ii5LaW0gY8awxqFuZyBjw7Mga2nhu4N1IGPhuq90ICJGYWlyIHbDoCBQcmVtaXVtbCIgY8OzIG3hu6ljIMSR4buNIGNow6puaCBs4buHY2ggY2FvIG5o4bqldCB24buBIGJp4bq/biAiY2FyYXQiIHThu6ljIGzDoCBjw7MgxJHhu5kgYmnhur9uIHRoacOqbiBjYW8gbmjhuqV0IHbhu4Ega8OtY2ggdGjGsOG7m2MgY2FyYXQuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBraW0gY8awxqFuZyB0cm9uZyBuaMOzbSAiRmFpciB2w6AgUHJlbWl1bSIgY8OzIHRo4buDIGPDsyBrw61jaCB0aMaw4bubYyBjYXJhdCBjaMOqbmggbOG7h2NoIG5oYXUgxJHDoW5nIGvhu4MuDQoNCioqVsOtIGThu6U6KioNCg0KQ2jhuqV0IGzGsOG7o25nIGPhuq90ICJWZXJ5IEdvb2QiOg0KTeG6t3QgY+G6r3QgdHLDqm46IEdp4bqjIHPhu60gY+G7mXQgIlZlcnkgR29vZCIgdHLDqm4gbeG6t3QgY+G6r3QgdHLDqm4gY8OzIGNoaeG7gXUgY2FvIGzhu5tuIGjGoW4gY+G7mXQgIlZlcnkgR29vZCIgdHLDqm4gbeG6t3QgY+G6r3QgZMaw4bubaS4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgbcOgdSBz4bqvYyAxICjEkcaw4bujYyB4w6FjIMSR4buLbmggdHJvbmcgY29kZSkgY8OzIHBoxrDGoW5nIHNhaSBjYW8gaMahbiBraGkgY2jhuqV0IGzGsOG7o25nIGPhuq90IGzDoCAiVmVyeSBHb29kIi4gTsOzaSBjw6FjaCBraMOhYywgc+G7kSBsxrDhu6NuZyBraW0gY8awxqFuZyBjw7MgdGjhu4Mga2jDoWMgYmnhu4d0IG5oaeG7gXUgaMahbiBnaeG7r2EgY8OhYyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgIlZlcnkgR29vZCIgY2hvIG3DoHUgc+G6r2MgMSBzbyB24bubaSBtw6B1IHPhuq9jIDIuDQpTbyBzw6FuaDogQuG6oW4gY8OzIHRo4buDIHNvIHPDoW5oIHRy4buxYyBxdWFuIHBoxrDGoW5nIHNhaSBj4bunYSBz4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIHRoZW8gY2jhuqV0IGzGsOG7o25nIGPhuq90IGdp4buvYSBoYWkgbcOgdSBz4bqvYyBraMOhYyBuaGF1IGLhurFuZyBjw6FjaCBxdWFuIHPDoXQgY2hp4buBdSBjYW8gdMawxqFuZyDEkeG7kWkgY+G7p2EgY8OhYyBj4buZdCB0cm9uZyBjw7luZyBt4buZdCBuaMOzbSBjaOG6pXQgbMaw4bujbmcgY+G6r3QgdHLDqm4gaGFpIG3hurd0IGPhuq90IHJpw6puZyBiaeG7h3QuDQoNCg0KDQoNCmBgYHtyfQ0KaCU+JSBncm91cF9ieShjdXQsIGNvbG9yKSU+JXN1bW1hcmlzZShtPW1lYW4oZGVwdGgpKSU+JWdncGxvdChhZXMoeD1jdXQsIHk9IG0pKSsNCiAgZ2VvbV9jb2wocG9zaXRpb249J2RvZGdlJykrDQogIGZhY2V0X3dyYXAofmNvbG9yKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gcm91bmQobSkpLCB2anVzdD0xLCBjb2xvcj0nb3JhbmdlJykrIGxhYnMoeD0gJ2N1dCcsIHk9ICdNZWFuJyx0aXRsZT0nSMOsbmggMS4xMzogR2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBkZXB0aCB0aGVvIGN1dCB2w6AgY29sb3InKQ0KYGBgDQoNCg0KKioqTmjhuq1uIHjDqXQga+G6v3QgcXXhuqMqKioNCg0KVGEgY8OzIHRo4buDIG5oYW5oIGNow7NuZyBu4bqvbSBi4bqvdCB2w6Agc28gc8OhbmggY8OhYyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biAiZGVwdGgiIHRyb25nIGPDoWMgbmjDs20ga2jDoWMgbmhhdSDEkcaw4bujYyB4w6FjIMSR4buLbmggYuG7n2kgImN1dCIgdsOgICJjb2xvciIuDQpOaMOsbiB2w6BvIGvhur90IHF14bqjIHRhIHRo4bqleSDEkcaw4bujYyBnacOhIHR0cuG7i3RydW5nIGLDrG5oIGPhu6dhIG3hu5dpIGxv4bqhaSBjdXQgdHJvbmcgY8OhYyBuaMOzbSBjb2xvciBkYW8gxJHhu5NuZyB0cm9uZyBraG/huqNuZyA2MSDEkeG6v24gNjQuIA0Kw50gbmdoxKlhIGPhu6dhIGJp4buDdSDEkeG7kyBsw6AgaGnhu4NuIHRo4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0ICJkZXB0aCIgdGhlbyBjw6FjIG3hu6ljIMSR4buZICJjdXQiIHbDoCAiY29sb3IiLCBnacO6cCBoaeG7g3UgcsO1IGjGoW4gduG7gSBz4buxIHBow6JuIGLhu5EgY+G7p2EgZOG7ryBsaeG7h3UuIETGsOG7m2kgxJHDonkgbMOgIHbDrSBk4bulIHbhu4EgY8OhY2ggc+G7rSBk4bulbmcgYmnhu4N1IMSR4buTIG7DoHk6DQpCaeG7g3UgxJHhu5MgbsOgeSBjw7MgdGjhu4MgxJHGsOG7o2Mgc+G7rSBk4bulbmcgdHJvbmcgbmfDoG5oIGPDtG5nIG5naGnhu4dwIGtpbSBob8OgbiDEkeG7gyBzbyBzw6FuaCB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAiZGVwdGgiICht4buZdCBjaOG7iSBz4buRIHbhu4EgY2jhuqV0IGzGsOG7o25nIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nKSBnaeG7r2EgY8OhYyBt4bupYyDEkeG7mSAiY3V0IiAoY8OhY2ggeOG7rSBsw70gdmnDqm4ga2ltIGPGsMahbmcpIHbDoCAiY29sb3IiIChtw6B1IHPhuq9jIGPhu6dhIHZpw6puIGtpbSBjxrDGoW5nKS4gxJBp4buBdSBuw6B5IGPDsyB0aOG7gyBnacO6cCBjaG8gY8OhYyBuaMOgIHPhuqNuIHh14bqldCBraW0gY8awxqFuZyBoaeG7g3UgxJHGsOG7o2MgbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjaCB44butIGzDvSB2w6AgY2jhuqV0IGzGsOG7o25nIGPhu6dhIHPhuqNuIHBo4bqpbS4NCkdp4bqjIHPhu60gYuG6oW4gxJFhbmcgbMOgbSB2aeG7h2MgduG7m2kgbeG7mXQgdOG6rXAgZOG7ryBsaeG7h3UgduG7gSBjw6FjIHZpw6puIGtpbSBjxrDGoW5nLCB0cm9uZyDEkcOzIG3hu5dpIHZpw6puIGtpbSBjxrDGoW5nIGPDsyBjw6FjIHRodeG7mWMgdMOtbmggbmjGsCBjaOG6pXQgbMaw4bujbmcgY+G6r3QgKCJjdXQiKSwgbcOgdSBz4bqvYyAoImNvbG9yIikgdsOgIMSR4buZIHPDonUgKCJkZXB0aCIpLiBC4bqxbmcgY8OhY2ggc+G7rSBk4bulbmcgbcOjIG7DoHksIGLhuqFuIGPDsyB0aOG7gyB04bqhbyByYSBt4buZdCBiaeG7g3UgxJHhu5MgY+G7mXQgaGnhu4NuIHRo4buLIHPhu7EgYmnhur9uIMSR4buVaSBj4bunYSDEkeG7mSBzw6J1IHRydW5nIGLDrG5oIGPhu6dhIGPDoWMgdmnDqm4ga2ltIGPGsMahbmcgZOG7sWEgdHLDqm4gY2jhuqV0IGzGsOG7o25nIGPhuq90IHbDoCBtw6B1IHPhuq9jLCBnacO6cCBi4bqhbiBoaeG7g3UgcsO1IGjGoW4gduG7gSB0xrDGoW5nIHF1YW4gZ2nhu69hIGPDoWMgYmnhur9uIG7DoHkgdsOgIMSR4buZIHPDonUgY+G7p2EgdmnDqm4ga2ltIGPGsMahbmcuDQoNCg0KYGBge3J9DQpoJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpJT4lc3VtbWFyaXNlKG09bWVhbihwcmljZSkpJT4lZ2dwbG90KGFlcyh4PWN1dCwgeT0gbSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbj0nZG9kZ2UnKSsNCiAgZmFjZXRfd3JhcCh+Y29sb3IpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPSByb3VuZChtKSksIHZqdXN0PTIsIGNvbG9yPSdwaW5rJykrIGxhYnMoeD0gJ2N1dCcsIHk9ICdT4buRIGzGsOG7o25nJyx0aXRsZT0nSMOsbmggMS4xNDogR2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBwcmljZSB0aGVvIGN1dCB2w6AgY29sb3InKQ0KYGBgDQoNCioqKk5o4bqtbiB4w6l0IGvDqnQgcXXhuqMqKioNCg0KVGEgY8OzIHRo4buDIG5oYW5oIGNow7NuZyBu4bqvbSBi4bqvdCB2w6Agc28gc8OhbmggY8OhYyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biAicHJpY2UiIHRyb25nIGPDoWMgbmjDs20ga2jDoWMgbmhhdSDEkcaw4bujYyB4w6FjIMSR4buLbmggYuG7n2kgImN1dCIgdsOgICJjb2xvciIuDQoNCsOdIG5naMSpYSBj4bunYSBiaeG7g3UgxJHhu5MgbMOgIGhp4buDbiB0aOG7iyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAicHJpY2UiIHRoZW8gY8OhYyBt4bupYyDEkeG7mSAiY3V0IiB2w6AgImNvbG9yIiwgZ2nDunAgaGnhu4N1IHLDtSBoxqFuIHbhu4Egc+G7sSBwaMOibiBi4buRIGPhu6dhIGThu68gbGnhu4d1LiBExrDhu5tpIMSRw6J5IGzDoCB2w60gZOG7pSB24buBIGPDoWNoIHPhu60gZOG7pW5nIGJp4buDdSDEkeG7kyBuw6B5Og0KQmnhu4N1IMSR4buTIG7DoHkgY8OzIHRo4buDIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIG5nw6BuaCBjw7RuZyBuZ2hp4buHcCBraW0gaG/DoG4gxJHhu4Mgc28gc8OhbmggdHJ1bmcgYsOsbmggY+G7p2EgY+G7mXQgInByaWNlIiAobeG7mXQgY2jhu4kgc+G7kSB24buBIGNo4bqldCBsxrDhu6NuZyBj4bunYSB2acOqbiBraW0gY8awxqFuZykgZ2nhu69hIGPDoWMgbeG7qWMgxJHhu5kgImN1dCIgKGPDoWNoIHjhu60gbMO9IHZpw6puIGtpbSBjxrDGoW5nKSB2w6AgImNvbG9yIiAobcOgdSBz4bqvYyBj4bunYSB2acOqbiBraW0gY8awxqFuZykuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgZ2nDunAgY2hvIGPDoWMgbmjDoCBz4bqjbiB4deG6pXQga2ltIGPGsMahbmcgaGnhu4N1IMSRxrDhu6NjIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgY8OhY2ggeOG7rSBsw70gdsOgIGNo4bqldCBsxrDhu6NuZyBj4bunYSBz4bqjbiBwaOG6qW0uDQoNCg0KYGBge3J9DQpoJT4lIGdyb3VwX2J5KGN1dCwgY2xhcml0eSklPiVzdW1tYXJpc2UobT1tZWFuKHRhYmxlKSklPiVnZ3Bsb3QoYWVzKHg9Y3V0LCB5PSBtKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpKw0KICBmYWNldF93cmFwKH5jbGFyaXR5KSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gcm91bmQobSkpLCB2anVzdD0yLCBjb2xvcj0ncGluaycpKyBsYWJzKHg9ICdjdXQnLCB5PSAnTWVhbicsdGl0bGU9J0jDrG5oIDEuMTU6IEdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgdGFibGUgdGhlbyAgY2jhuqV0IGzGsOG7o25nIGPhuq90IHbDoCDEkeG7mSB0cm9uZyBzdeG7kXQnKQ0KYGBgDQoNCg0KKioqR2nhuqNpIHRow61jaCoqKg0KDQpCaeG7g3UgxJHhu5MgbsOgeSBjw7MgdMOhYyBk4bulbmcgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgY+G7mXQgInRhYmxlIiB0aGVvIGPDoWMgbmjDs20gxJHGsOG7o2MgcGjDom4gbG/huqFpIGLhu59pIGPhuq90IChjdXQpIHbDoCByw7UgcsOgbmcgKGNsYXJpdHkpIGPhu6dhIGtpbSBjxrDGoW5nLiBDw6FjIHRoYW5oIGPhu5l0IMSRxrDhu6NjIGNoaWEgdGjDoG5oIGPDoWMgbmjDs20gdGhlbyAiY3V0IiB2w6AgbeG7l2kgbmjDs20gxJHGsOG7o2MgcGjDom4gdMOhY2ggZOG7sWEgdHLDqm4gImNsYXJpdHkiLiBN4buXaSB0aGFuaCBj4buZdCDEkeG6oWkgZGnhu4duIGNobyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0ICJ0YWJsZSIgY2hvIHThu6tuZyBuaMOzbS4NCkPDoWMgbmjDs20gxJHGsOG7o2MgcGjDom4gY2hpYSBi4bufaSAiY2xhcml0eSIgc+G6vSDEkcaw4bujYyBoaeG7g24gdGjhu4sgdHLDqm4gY8OhYyBwYW5lbCBraMOhYyBuaGF1LCBnacO6cCBzbyBzw6FuaCBz4buxIHRoYXkgxJHhu5VpIGPhu6dhIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgInRhYmxlIiBnaeG7r2EgY8OhYyBuaMOzbSB0cm9uZyBjw7luZyBt4buZdCAiY2xhcml0eSIuIEPDoWMgY29uIHPhu5EgdHJ1bmcgYsOsbmggY+G7pSB0aOG7gyDEkcaw4bujYyBoaeG7g24gdGjhu4sgdHLDqm4gY8OhYyB0aGFuaCBj4buZdCDEkeG7gyBuZ8aw4budaSDEkeG7jWMgY8OzIHRo4buDIGThu4UgZMOgbmcgbmjhuq1uIGJp4bq/dCBnacOhIHRy4buLLg0KQmnhu4N1IMSR4buTIG7DoHkgZ2nDunAgdHLhu7FjIHF1YW4gaMOzYSBz4buxIHBo4bulIHRodeG7mWMgY+G7p2EgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAidGFibGUiIMSR4buRaSB24bubaSAiY3V0IiB2w6AgImNsYXJpdHkiIGPhu6dhIGtpbSBjxrDGoW5nLCB04burIMSRw7MgZ2nDunAgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIHnhur91IHThu5EgbsOgeSB2w6AgcGjDoXQgaGnhu4duIHJhIGPDoWMgbeG6q3UgaG/hurdjIHh1IGjGsOG7m25nIHF1YW4gdHLhu41uZy4NClF1YSDEkcOieSB0YSB0aOG6pXkgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBt4buXaSBs4buXaSB0aHXhu5kgY8OhYyBuaMOzbSDhu5VuIMSR4buLbmggZGFvIMSR4buZbmcgdHJvbmcga2hv4bqjbmcgNTYgxJHhur9uIDYwDQoNCioqVsOtIGThu6U6KioNCg0KQmnhu4N1IMSR4buTIGPDsyB0aOG7gyBjaG8gdGjhuqV5IHLhurFuZyBjw6FjIGtpbSBjxrDGoW5nIGPDsyBt4bupYyDEkeG7mSByw7UgcsOgbmcgIlNJMSIgdGjGsOG7nW5nIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0ICJ0YWJsZSIgY2FvIGjGoW4gc28gduG7m2kgY8OhYyBraW0gY8awxqFuZyBraMOhYyBraGkgY+G6r3Qg4bufIG3hu6ljICJHb29kIiwgbmjGsG5nIGzhuqFpIHRo4bqlcCBoxqFuIMSRw6FuZyBr4buDIGtoaSBj4bqvdCDhu58gbeG7qWMgIlZlcnkgR29vZCIuIMSQaeG7gXUgbsOgeSBjw7MgdGjhu4MgZ+G7o2kgw70gcuG6sW5nIGPDsyB0aOG7gyBjw7Mgc+G7sSB0xrDGoW5nIHTDoWMgcGjhu6ljIHThuqFwIGdp4buvYSBj4bqvdCB2w6AgbeG7qWMgxJHhu5kgcsO1IHLDoG5nIMSR4buRaSB24bubaSBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0ICJ0YWJsZSIuDQoNCg0KYGBge3J9DQpoJT4lIGdyb3VwX2J5KGN1dCwgY2xhcml0eSklPiVzdW1tYXJpc2UobT1tZWFuKGRlcHRoKSklPiVnZ3Bsb3QoYWVzKHg9Y3V0LCB5PSBtKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpKw0KICBmYWNldF93cmFwKH5jbGFyaXR5KSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gcm91bmQobSkpLCB2anVzdD0yLCBjb2xvcj0ncGluaycpKyBsYWJzKHg9ICdjdXQnLCB5PSAnTWVhbicsdGl0bGU9J0jDrG5oIDEuMTY6IEdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgZGVwdGggdGhlbyBjdXQgdsOgIGNsYXJpdHkgJykNCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoKioqDQoNCkJp4buDdSDEkeG7kyBuw6B5IGPDsyB0w6FjIGThu6VuZyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAiZGVwdGgiIHRoZW8gY8OhYyBuaMOzbSDEkcaw4bujYyBwaMOibiBsb+G6oWkgYuG7n2kgY+G6r3QgKGN1dCkgdsOgIHLDtSByw6BuZyAoY2xhcml0eSkgY+G7p2Ega2ltIGPGsMahbmcuIEPDoWMgdGhhbmggY+G7mXQgxJHGsOG7o2MgY2hpYSB0aMOgbmggY8OhYyBuaMOzbSB0aGVvICJjdXQiIHbDoCBt4buXaSBuaMOzbSDEkcaw4bujYyBwaMOibiB0w6FjaCBk4buxYSB0csOqbiAiY2xhcml0eSIuIE3hu5dpIHRoYW5oIGPhu5l0IMSR4bqhaSBkaeG7h24gY2hvIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgY+G7mXQgImRlcHRoIiBjaG8gdOG7q25nIG5ow7NtLg0KDQpDw6FjIG5ow7NtIMSRxrDhu6NjIHBow6JuIGNoaWEgYuG7n2kgImNsYXJpdHkiIHPhur0gxJHGsOG7o2MgaGnhu4NuIHRo4buLIHRyw6puIGPDoWMgcGFuZWwga2jDoWMgbmhhdSwgZ2nDunAgc28gc8Ohbmggc+G7sSB0aGF5IMSR4buVaSBj4bunYSBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhICJ0YWJsZSIgZ2nhu69hIGPDoWMgbmjDs20gdHJvbmcgY8O5bmcgbeG7mXQgImNsYXJpdHkiLiBDw6FjIGNvbiBz4buRIHRydW5nIGLDrG5oIGPhu6UgdGjhu4MgxJHGsOG7o2MgaGnhu4NuIHRo4buLIHRyw6puIGPDoWMgdGhhbmggY+G7mXQgxJHhu4MgbmfGsOG7nWkgxJHhu41jIGPDsyB0aOG7gyBk4buFIGTDoG5nIG5o4bqtbiBiaeG6v3QgZ2nDoSB0cuG7iy4NCg0KQmnhu4N1IMSR4buTIG7DoHkgZ2nDunAgdHLhu7FjIHF1YW4gaMOzYSBz4buxIHBo4bulIHRodeG7mWMgY+G7p2EgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAiZGVwdGgiIMSR4buRaSB24bubaSAiY3V0IiB2w6AgImNsYXJpdHkiIGPhu6dhIGtpbSBjxrDGoW5nLCB04burIMSRw7MgZ2nDunAgcGjDom4gdMOtY2ggbeG7kWkgcXVhbiBo4buHIGdp4buvYSBjw6FjIHnhur91IHThu5EgbsOgeSB2w6AgcGjDoXQgaGnhu4duIHJhIGPDoWMgbeG6q3UgaG/hurdjIHh1IGjGsOG7m25nIHF1YW4gdHLhu41uZy4NClF1YSDEkcOieSB0YSB0aOG6pXkgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBt4buXaSBs4buXaSB0aHXhu5kgY8OhYyBuaMOzbSDhu5VuIMSR4buLbmggZGFvIMSR4buZbmcgdHJvbmcga2hv4bqjbmcgNjAgxJHhur9uIDY0DQoNCsOdIG5naMSpYSBj4bunYSBiaeG7g3UgxJHhu5MgxJHGsOG7o2MgdOG6oW8gYuG7n2kgbcOjIG7DoHkgbMOgIMSR4buDIGhp4buDdSBz4buxIHTGsMahbmcgcXVhbiBnaeG7r2EgY3V0LCBjbGFyaXR5IHbDoCDEkeG7mSBzw6J1IGPhu6dhIGtpbSBjxrDGoW5nLiBUcm9uZyBuZ8OgbmggY8O0bmcgbmdoaeG7h3Aga2ltIGPGsMahbmcsIGN1dCAoY+G6r3QpIHbDoCBjbGFyaXR5ICjEkeG7mSB0cm9uZyBzdeG7kXQpIGzDoCBoYWkgeeG6v3UgdOG7kSBjaMOtbmgg4bqjbmggaMaw4bufbmcgxJHhur9uIGdpw6EgdHLhu4sgY+G7p2EgbeG7mXQgdmnDqm4ga2ltIGPGsMahbmcuIMSQ4buZIHPDonUgKGRlcHRoKSBjxaluZyBsw6AgbeG7mXQgeeG6v3UgdOG7kSBxdWFuIHRy4buNbmcgxJHhu4MgxJHDoW5oIGdpw6EgY2jhuqV0IGzGsOG7o25nIGPhu6dhIG3hu5l0IHZpw6puIGtpbSBjxrDGoW5nLiBCaeG7g3UgxJHhu5Mgc+G6vSBnacO6cCB0YSB0aOG6pXkgbGnhu4d1IGPDsyBz4buxIHTGsMahbmcgcXVhbiBnaeG7r2EgY8OhYyB54bq/dSB04buRIG7DoHkga2jDtG5nLg0KDQpWw60gZOG7pTogbuG6v3UgYmnhu4N1IMSR4buTIGNobyB0aOG6pXkgcuG6sW5nIGPDoWMgY+G7mXQgYmnhu4N1IGRp4buFbiDEkeG7mSBzw6J1IGPhu6dhIGtpbSBjxrDGoW5nIChkZXB0aCkgdGjhuqVwIG5o4bqldCDEkeG7gXUgbuG6sW0g4bufIG3hu5l0IG5ow7NtIGPhuq90IGPhu6UgdGjhu4MgdsOgIG3hu5l0IMSR4buZIHRyb25nIHN14buRdCBj4bulIHRo4buDLCDEkWnhu4F1IG7DoHkgY8OzIHRo4buDIGNobyB0aOG6pXkgcuG6sW5nIG3hu5FpIHTGsMahbmcgcXVhbiBnaeG7r2EgY+G6r3QgdsOgIGNsYXJpdHkgduG7m2kgxJHhu5kgc8OidSBsw6AgxJHDoW5nIGNow7ogw70uDQoNCmBgYHtyfQ0KaCU+JSBncm91cF9ieShjdXQsIGNsYXJpdHkpJT4lc3VtbWFyaXNlKG09dmFyKGRlcHRoKSklPiVnZ3Bsb3QoYWVzKHg9Y3V0LCB5PSBtKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpKw0KICBmYWNldF93cmFwKH5jbGFyaXR5KSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gcm91bmQobSkpLCB2anVzdD0wLCBjb2xvcj0ncmVkJykrIGxhYnMoeD0gJ2N1dCcsIHk9ICdWYXInLHRpdGxlPSdIw6xuaCAxLjE3OiBQaMawxqFuZyBzYWkgY+G7p2EgZGVwdGggdGhlbyBjdXQgdsOgIGNsYXJpdHknKQ0KYGBgDQoNCioqKk5o4bqtbiB4w6l0IGJp4buDdSDEkeG7kyoqKg0KDQogVMOhYyBk4bulbmcgY+G7p2EgYmnhu4N1IMSR4buTIG7DoHkgbMOgIGhp4buDbiB0aOG7iyBwaMawxqFuZyBzYWkgY+G7p2EgY+G7mXQgImRlcHRoIiB0aGVvIGPDoWMgbeG7qWMgxJHhu5kgImN1dCIgdsOgICJjbGFyaXR5IiwgY2hvIHRhIGPDoWkgbmjDrG4gduG7gSBz4buxIGJp4bq/biDEkeG7mW5nIGPhu6dhIGThu68gbGnhu4d1Lg0KUXVhIMSRw6J5IHRhIHRo4bqleSDEkcaw4bujYyBwaMawxqFuZyBzYWkgY+G7p2EgbeG7l2kgbmjDs20gY29sb3IgxJHhu4F1IGPDsyB4dSBoxrDhu5tuZyBnaeG6o20gZOG6p24gdOG7qyBGYWlyIHh14buRbmcgSWRlYWwNCg0KU3V5IHJhLCBraeG7g3UgY+G6r3Qga2ltIGPGsMahbmcg4bqjbmggaMaw4bufbmcgxJHhur9uIG3hu6ljIMSR4buZIGNow6puaCBs4buHY2ggY+G7p2EgYmnhur9uICJjYXJhdCIuS2ltIGPGsMahbmcgY8OzIGtp4buDdSBj4bqvdCAiRmFpciB2w6AgSWRlYWwiIGPDsyBt4bupYyDEkeG7jSBjaMOqbmggbOG7h2NoIGNhbyBuaOG6pXQgduG7gSBiaeG6v24gImNhcmF0IiB04bupYyBsw6AgY8OzIMSR4buZIGJp4bq/biB0aGnDqm4gY2FvIG5o4bqldCB24buBIGvDrWNoIHRoxrDhu5tjIGNhcmF0LiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6Aga2ltIGPGsMahbmcgdHJvbmcgbmjDs20gIkZhaXIgdsOgIElkZWFsIiBjw7MgdGjhu4MgY8OzIGvDrWNoIHRoxrDhu5tjIGNhcmF0IGNow6puaCBs4buHY2ggbmhhdSDEkcOhbmcga+G7gy4NCg0KDQpgYGB7cn0NCmglPiUgZ3JvdXBfYnkoY3V0LCBjbGFyaXR5KSU+JXN1bW1hcmlzZShtPW1lYW4ocHJpY2UpKSU+JWdncGxvdChhZXMoeD1jdXQsIHk9IG0pKSsNCiAgZ2VvbV9jb2wocG9zaXRpb249J2RvZGdlJykrDQogIGZhY2V0X3dyYXAofmNsYXJpdHkpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPSByb3VuZChtKSksIHZqdXN0PTEsIGNvbG9yPSdwaW5rJykrIGxhYnMoeD0gJ2N1dCcsIHk9ICdNZWFuJyx0aXRsZT0nSMOsbmggMS4xODogR2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBwcmljZSB0aGVvIGN1dCB2w6AgY2xhcml0eScpDQpgYGANCg0KDQoqKipHaeG6o2kgdGjDrWNoKioqDQoNCkJp4buDdSDEkeG7kyBjw7MgZOG6oW5nIGPhu5l0LCB24bubaSBjw6FjIGPhu5l0IHRo4buDIGhp4buHbiBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6EgKHByaWNlKSBjaG8gdOG7q25nIG5ow7NtIGN1dCB2w6AgY2xhcml0eS4NCkJp4buDdSDEkeG7kyDEkcaw4bujYyBjaGlhIHRow6BuaCBjw6FjIG3hurd0IGNvbiB0aGVvIGPDoWMgZ2nDoSB0cuG7iyBraMOhYyBuaGF1IGPhu6dhIGJp4bq/biBjbGFyaXR5Lg0KTeG7l2kgbeG6t3QgY29uIGhp4buDbiB0aOG7iyBiaeG7g3UgxJHhu5MgY+G7mXQgcmnDqm5nIGNobyBt4buZdCBt4bupYyDEkeG7mSB0cm9uZyBj4bulIHRo4buDLCBnacO6cCBzbyBzw6FuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGdpw6EgZ2nhu69hIGPDoWMga2nhu4N1IGPhuq90IHRyb25nIGPDuW5nIG3hu6ljIMSR4buZIHRyb25nLg0KQ8OhYyBj4buZdCDEkcaw4bujYyB0w7QgbcOgdSBraMOhYyBuaGF1IMSR4buDIGThu4UgZMOgbmcgcGjDom4gYmnhu4d0IGPDoWMgbmjDs20gY2xhcml0eS4NCkdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgZ2nDoSDEkcaw4bujYyBoaeG7g24gdGjhu4sgdHLDqm4gbeG7l2kgY+G7mXQgxJHhu4MgZ2nDunAgbmfGsOG7nWkgxJHhu41jIGThu4UgZMOgbmcgc28gc8OhbmggZ2nDoSB0cuG7iyBnaeG7r2EgY8OhYyBuaMOzbS4NCg0KDQoNCmBgYHtyfQ0KaCU+JSBncm91cF9ieShjbGFyaXR5LGNvbG9yKSU+JXN1bW1hcmlzZShtPW1lYW4odGFibGUpKSU+JWdncGxvdChhZXMoeD1jbGFyaXR5LCB5PSBtKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpKw0KICBmYWNldF93cmFwKH5jb2xvcikrDQogIGdlb21fdGV4dChhZXMobGFiZWw9IHJvdW5kKG0pKSwgdmp1c3Q9MiwgY29sb3I9J3BpbmsnKSsgbGFicyh4PSAnY3V0JywgeT0gJ01lYW4nLHRpdGxlPSdIw6xuaCAxLjE5OiBHacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIHRhYmxlIHRoZW8gY2xhcml0eSB2w6AgY29sb3InKQ0KYGBgDQoNCioqKkdp4bqjaSB0aMOtY2gqKioNCg0KQmnhu4N1IMSR4buTIG7DoHkgY8OzIHTDoWMgZOG7pW5nIGhp4buDbiB0aOG7iyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0ICJ0YWJsZSIgdGhlbyBjw6FjIG5ow7NtIMSRxrDhu6NjIHBow6JuIGxv4bqhaSBi4bufaSAoY29sb3IpIHbDoCByw7UgcsOgbmcgKGNsYXJpdHkpIGPhu6dhIGtpbSBjxrDGoW5nLiBDw6FjIHRoYW5oIGPhu5l0IMSRxrDhu6NjIGNoaWEgdGjDoG5oIGPDoWMgbmjDs20gdGhlbyAiY29sb3IiIHbDoCBt4buXaSBuaMOzbSDEkcaw4bujYyBwaMOibiB0w6FjaCBk4buxYSB0csOqbiAiY2xhcml0eSIuIE3hu5dpIHRoYW5oIGPhu5l0IMSR4bqhaSBkaeG7h24gY2hvIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgY+G7mXQgInRhYmxlIiBjaG8gdOG7q25nIG5ow7NtLg0KDQpDw6FjIG5ow7NtIMSRxrDhu6NjIHBow6JuIGNoaWEgYuG7n2kgImNsYXJpdHkiIHPhur0gxJHGsOG7o2MgaGnhu4NuIHRo4buLIHRyw6puIGPDoWMgcGFuZWwga2jDoWMgbmhhdSwgZ2nDunAgc28gc8Ohbmggc+G7sSB0aGF5IMSR4buVaSBj4bunYSBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhICJ0YWJsZSIgZ2nhu69hIGPDoWMgbmjDs20gdHJvbmcgY8O5bmcgbeG7mXQgImNsYXJpdHkiLiBDw6FjIGNvbiBz4buRIHRydW5nIGLDrG5oIGPhu6UgdGjhu4MgxJHGsOG7o2MgaGnhu4NuIHRo4buLIHRyw6puIGPDoWMgdGhhbmggY+G7mXQgxJHhu4MgbmfGsOG7nWkgxJHhu41jIGPDsyB0aOG7gyBk4buFIGTDoG5nIG5o4bqtbiBiaeG6v3QgZ2nDoSB0cuG7iy4NCg0KQmnhu4N1IMSR4buTIG7DoHkgZ2nDunAgdHLhu7FjIHF1YW4gaMOzYSBz4buxIHBo4bulIHRodeG7mWMgY+G7p2EgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBj4buZdCAidGFibGUiIMSR4buRaSB24bubaSAiY29sb3IiIHbDoCAiY2xhcml0eSIgY+G7p2Ega2ltIGPGsMahbmcsIHThu6sgxJHDsyBnacO6cCBwaMOibiB0w61jaCBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGPDoWMgeeG6v3UgdOG7kSBuw6B5IHbDoCBwaMOhdCBoaeG7h24gcmEgY8OhYyBt4bqrdSBob+G6t2MgeHUgaMaw4bubbmcgcXVhbiB0cuG7jW5nLg0KDQpRdWEgxJHDonkgdGEgdGjhuqV5IGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgbeG7l2kgbG/huqFpIHRyb25nIEPhu5l0IENsYXJpdHkgdGh14buZYyBjw6FjIG5ow7NtIOG7lW4gxJHhu4tuaCBkYW8gxJHhu5luZyB0cm9uZyBraG/huqNuZyA1NiDEkeG6v24gNTk1OQ0KDQrDnSBuZ2jEqWEgY+G7p2EgYmnhu4N1IMSR4buTIMSRxrDhu6NjIHThuqFvIGLhu59pIG3DoyBuw6B5IGzDoCDEkeG7gyBoaeG7g3Ugc+G7sSB0xrDGoW5nIHF1YW4gZ2nhu69hIGNvbG9yLCBjbGFyaXR5IHbDoCB0YWJsZSBj4bunYSBraW0gY8awxqFuZy4gVHJvbmcgbmfDoG5oIGPDtG5nIG5naGnhu4dwIGtpbSBjxrDGoW5nLCBjb2xvciB2w6AgY2xhcml0eSAoxJHhu5kgdHJvbmcgc3Xhu5F0KSBsw6AgaGFpIHnhur91IHThu5EgY2jDrW5oIOG6o25oIGjGsOG7n25nIMSR4bq/biBnacOhIHRy4buLIGPhu6dhIG3hu5l0IHZpw6puIGtpbSBjxrDGoW5nLiAgQmnhu4N1IMSR4buTIHPhur0gZ2nDunAgdGEgdGjhuqV5IGxp4buHdSBjw7Mgc+G7sSB0xrDGoW5nIHF1YW4gZ2nhu69hIGPDoWMgeeG6v3UgdOG7kSBuw6B5IGtow7RuZy4NCg0KDQpgYGB7cn0NCmglPiUgZ3JvdXBfYnkoY2xhcml0eSxjb2xvciklPiVzdW1tYXJpc2UobT12YXIodGFibGUpKSU+JWdncGxvdChhZXMoeD1jbGFyaXR5LCB5PSBtKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpKw0KICBmYWNldF93cmFwKH5jb2xvcikrDQogIGdlb21fdGV4dChhZXMobGFiZWw9IHJvdW5kKG0pKSwgdmp1c3Q9MiwgY29sb3I9J3BpbmsnKSsgbGFicyh4PSAnY2xhcml0eScsIHk9ICdWYXInLHRpdGxlPSdIw6xuaCAxLjIwOiBQaMawxqFuZyBzYWkgY+G7p2EgdGFibGUgdGhlbyBjbGFyaXR5IHbDoCBjb2xvciAnKQ0KYGBgDQoNCioqKkdp4bqjaSB0aMOtY2gqKioNCg0KxJBv4bqhbiBtw6MgdHLDqm4gc+G6vSBnacO6cCBi4bqhbiB0cuG7sWMgcXVhbiBow7NhIGThu68gbGnhu4d1IG3hu5l0IGPDoWNoIGThu4UgZMOgbmcgdsOgIGN1bmcgY+G6pXAgdGjDtG5nIHRpbiAuIE7DsyBz4bq9IHThuqFvIHJhIG3hu5l0IGJp4buDdSDEkeG7kyBj4buZdCwgbeG7l2kgY+G7mXQgYmnhu4N1IGRp4buFbiBjaG8gbeG7mXQgY+G6t3AgImNsYXJpdHkiIHbDoCAiY29sb3IiLCB24bubaSBjaGnhu4F1IGNhbyBj4bunYSBj4buZdCB0xrDGoW5nIOG7qW5nIHbhu5tpIHBoxrDGoW5nIHNhaSBj4bunYSBiaeG6v24gInRhYmxlIi4gQuG6oW4gY8WpbmcgY8OzIHRo4buDIHRo4bqleSBjw6FjIGdpw6EgdHLhu4sgcGjGsMahbmcgc2FpIMSRxrDhu6NjIGhp4buDbiB0aOG7iyB0csOqbiBiaeG7g3UgxJHhu5MsIGdpw7pwIGLhuqFuIHNvIHPDoW5oIGThu4UgZMOgbmcgaMahbiBnaeG7r2EgY8OhYyBuaMOzbS4NClBoxrDGoW5nIHNhaSBj4bunYSBiaeG7g3UgxJHhu5MgdHLDqm4ga2jDtG5nIGPDsyBk4buZIGNoZW5oIGzhu4djaCBs4bubbiBnaeG7r2EgY8OhYyBsb+G6oWkuDQoNCk7hur91IGvhur90IHF14bqjIHThu6sgYmnhu4N1IMSR4buTIGNobyB0aOG6pXkgY8OhYyBj4bq3cCBjbGFyaXR5IHbDoCBjb2xvciBjw7MgcGjGsMahbmcgc2FpIGPhu6dhIGJp4bq/biAidGFibGUiIGtow6FjIGJp4buHdCBs4bubbiwgYuG6oW4gY8OzIHRo4buDIGvhur90IGx14bqtbiBy4bqxbmcgY8OzIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgxJHhu5kgdHJvbmcgc3Xhu5F0IHbDoCBtw6B1IHPhuq9jIGPhu6dhIGtpbSBjxrDGoW5nIMSR4buRaSB24bubaSDEkeG6t2MgxJFp4buDbSAidGFibGUiLiDEkGnhu4F1IG7DoHkgY8OzIHRo4buDIGN1bmcgY+G6pXAgdGjDtG5nIHRpbiBo4buvdSDDrWNoIGNobyB2aeG7h2MgbOG7sWEgY2jhu41uIGtpbSBjxrDGoW5nIHRyb25nIGPDoWMg4bupbmcgZOG7pW5nIGtow6FjIG5oYXUsIG5oxrAgdHJvbmcgbmfDoG5oIGPDtG5nIG5naGnhu4dwIHRyYW5nIHPhu6ljLg0KDQoNCg0KYGBge3J9DQpoJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpJT4lc3VtbWFyaXNlKG09dmFyKGRlcHRoKSklPiVnZ3Bsb3QoYWVzKHg9Y2xhcml0eSwgeT0gbSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbj0nZG9kZ2UnKSsNCiAgZmFjZXRfd3JhcCh+Y29sb3IpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPSByb3VuZChtKSksIHZqdXN0PTAsIGNvbG9yPSdyZWQnKSsgbGFicyh4PSAnY2xhcml0eScsIHk9ICdWYXInLHRpdGxlPSdIw6xuaCAxLjIxOiBQaMawxqFuZyBzYWkgY+G7p2EgZGVwdGggdGhlbyBjbGFyaXR5IHbDoCBjb2xvcicpDQpgYGANCg0KKioqTmjhuq1uIHjDqXQgYmnhu4N1IMSR4buTKioqDQoNClTDoWMgZOG7pW5nIGPhu6dhIGJp4buDdSDEkeG7kyBuw6B5IGzDoCBoaeG7g24gdGjhu4sgcGjGsMahbmcgc2FpIGPhu6dhIGPhu5l0ICJkZXB0aCIgdGhlbyBjw6FjIG3hu6ljIMSR4buZICJjbGFyaXR5IiB2w6AgImNvbG9yIiwgY2hvIHRhIGPDoWkgbmjDrG4gduG7gSBz4buxIGJp4bq/biDEkeG7mW5nIGPhu6dhIGThu68gbGnhu4d1Lg0KUXVhIMSRw6J5IHRhIHRo4bqleSDEkcaw4bujYyBwaMawxqFuZyBzYWkgY+G7p2EgbeG7l2kgbmjDs20gY29sb3IgxJHhu4F1IGPDsyB4dSBoxrDhu5tuZyBnaeG6o20gZOG6p24gdOG7qyBJMSB4deG7kW5nIElGDQoNClN1eSByYSwga2nhu4N1IGPhuq90IGtpbSBjxrDGoW5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBt4bupYyDEkeG7mSBjaMOqbmggbOG7h2NoIGPhu6dhIGJp4bq/biAiY2FyYXQiLktpbSBjxrDGoW5nIGPDsyBraeG7g3UgY+G6r3QgIkZhaXIgdsOgIFByZW1pdW1sIiBjw7MgbeG7qWMgxJHhu40gY2jDqm5oIGzhu4djaCBjYW8gbmjhuqV0IHbhu4EgYmnhur9uICJjYXJhdCIgdOG7qWMgbMOgIGPDsyDEkeG7mSBiaeG6v24gdGhpw6puIGNhbyBuaOG6pXQgduG7gSBrw61jaCB0aMaw4bubYyBjYXJhdC4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGtpbSBjxrDGoW5nIHRyb25nIG5ow7NtICJGYWlyIHbDoCBQcmVtaXVtIiBjw7MgdGjhu4MgY8OzIGvDrWNoIHRoxrDhu5tjIGNhcmF0IGNow6puaCBs4buHY2ggbmhhdSDEkcOhbmcga+G7gy4NCg0KDQoNCmBgYHtyfQ0KaCU+JSBncm91cF9ieShjbGFyaXR5LGNvbG9yKSU+JXN1bW1hcmlzZShtPW1lYW4oZGVwdGgpKSU+JWdncGxvdChhZXMoeD1jbGFyaXR5LCB5PSBtKSkrDQogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpKw0KICBmYWNldF93cmFwKH5jb2xvcikrDQogIGdlb21fdGV4dChhZXMobGFiZWw9IHJvdW5kKG0pKSwgdmp1c3Q9MiwgY29sb3I9J3BpbmsnKSsgbGFicyh4PSAnY2xhcml0eScsIHk9ICdNZWFubicsdGl0bGU9J0jDrG5oIDEuMjI6IEdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgZGVwdGggdGhlbyBjbGFyaXR5IHbDoCBjb2xvcicpDQpgYGANCg0KKioqTmjhuq1uIHjDqXQgYmnhu4N1IMSR4buTKioqDQoNCkJp4buDdSDEkeG7kyB0aOG7gyBoaeG7h24gbeG7kWkgcXVhbiBo4buHIGdp4buvYSDEkeG7mSB0cm9uZyBzdeG7kXQgKENsYXJpdHkpIHbDoCDEkeG7mSBzw6J1IHRydW5nIGLDrG5oIChNZWFuIERlcHRoKSBj4bunYSDEkcOhIHF1w70sIHBow6JuIHRoZW8gbcOgdSBz4bqvYyAoQ29sb3IpLg0KTeG7l2kgdGhhbmggbcOgdSDEkeG6oWkgZGnhu4duIGNobyDEkeG7mSBzw6J1IHRydW5nIGLDrG5oIGPhu6dhIMSRw6EgcXXDvSBjw7MgY8O5bmcgxJHhu5kgdHJvbmcgc3Xhu5F0IHbDoCBtw6B1IHPhuq9jLg0KQ8OzIHRo4buDIHF1YW4gc8OhdCB0aOG6pXkgc+G7sSBraMOhYyBiaeG7h3QgduG7gSDEkeG7mSBzw6J1IHRydW5nIGLDrG5oIGdp4buvYSBjw6FjIMSR4buZIHRyb25nIHN14buRdCBraMOhYyBuaGF1IHRyb25nIGPDuW5nIG3hu5l0IG3DoHUgc+G6r2MuDQpDw7MgdGjhu4MgY8OzIHPhu7EgdMawxqFuZyBxdWFuIGhv4bq3YyBraMO0bmcgdMawxqFuZyBxdWFuIGdp4buvYSDEkeG7mSB0cm9uZyBzdeG7kXQgdsOgIMSR4buZIHPDonUgdHJ1bmcgYsOsbmggdMO5eSB0aHXhu5ljIHbDoG8gbG/huqFpIMSRw6EgcXXDvSBj4bulIHRo4buDLg0KQ2jDuiB0aMOtY2ggdHLDqm4gbeG7l2kgdGhhbmggaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggxJHGsOG7o2MgbMOgbSB0csOybiDEkeG6v24gaGFpIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuLg0KUXVhIGJp4buDdSDEkeG7kyB0csOqbiB0YSB0aOG6p3kgxJHGsOG7o2MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSDEkeG7mSBzw6J1IChkZXB0aCkga2jDoSBsw6Ag4buVbiDEkeG7i25oIGRhbyDEkeG7mW5nIHRyb25nIGtob+G6o25nIDYxLTY0DQoNCg0KYGBge3J9DQpoJT4lIGdyb3VwX2J5KGNsYXJpdHksY29sb3IpJT4lc3VtbWFyaXNlKG09bWVhbihwcmljZSkpJT4lZ2dwbG90KGFlcyh4PWNsYXJpdHksIHk9IG0pKSsNCiAgZ2VvbV9jb2wocG9zaXRpb249J2RvZGdlJyxmaWxsPSdibGFjaycpKw0KICBmYWNldF93cmFwKH5jb2xvcikrDQogIGdlb21fdGV4dChhZXMobGFiZWw9IHJvdW5kKG0pKSwgdmp1c3Q9MCwgY29sb3I9J3JlZCcpKyBsYWJzKHg9ICdjbGFyaXR5JywgeT0gJ01lYW4nLHRpdGxlPSdIw6xuaCAxLjIzOiBHacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIHByaWNlIHRoZW8gY2xhcml0eSB2w6AgY29sb3InKQ0KYGBgDQoNCioqKk5o4bqtbiB4w6l0IGJp4buDdSDEkeG7kyoqKg0KIA0KaCAlPiU6IFPhu60gZOG7pW5nIHRvw6FuIHThu60gcGlwZSAoJT4lKSB0cm9uZyBnw7NpIGRwbHlyIMSR4buDIMOhcCBk4bulbmcgY8OhYyBs4buHbmggdGnhur9wIHRoZW8gY2hvIG3hu5l0IGtodW5nIGThu68gbGnhu4d1ICh0aMaw4budbmcgxJHGsOG7o2MgYmnhu4N1IHRo4buLIGLhurFuZyBoKS4NCg0KZ3JvdXBfYnkoY2xhcml0eSwgY29sb3IpOiBDaGlhIGtodW5nIGThu68gbGnhu4d1IHRow6BuaCBjw6FjIG5ow7NtIGThu7FhIHRyw6puIGhhaSB54bq/dSB04buROiBjbGFyaXR5ICjEkeG7mSB0aW5oIGtoaeG6v3QpIHbDoCBjb2xvciAobcOgdSBz4bqvYykuIENobyBwaMOpcCB0w61uaCB0b8OhbiB0aOG7kW5nIGvDqiB0w7NtIHThuq90IHRyb25nIHThu6tuZyBuaMOzbS4NCg0Kc3VtbWFyaXNlKG0gPSBtZWFuKHByaWNlKSk6IFTDrW5oIHRvw6FuIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgYmnhur9uIHByaWNlIHRyb25nIG3hu5dpIG5ow7NtLCBnw6FuIGvhur90IHF14bqjIGNobyBiaeG6v24gbeG7m2kgbS4NCg0KZ2dwbG90KGFlcyh4ID0gY2xhcml0eSwgeSA9IG0pKTogVOG6oW8gbeG7mXQgxJHhu5FpIHTGsOG7o25nIGdncGxvdCDEkeG7gyB4w6J5IGThu7FuZyBjw6FjIGThuqFuZyB0cuG7sWMgcXVhbiBow7NhLiBIw6BtIGFlcygpIMOhbmggeOG6oSBiaeG6v24gY2xhcml0eSBzYW5nIHRy4bulYyB4IHbDoCBnacOhIHRy4buLIG0gKGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmgpIMSRxrDhu6NjIHTDrW5oIHRvw6FuIHNhbmcgdHLhu6VjIHkuDQoNCmdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJywgZmlsbCA9ICdibGFjaycpOiBUaMOqbSBs4bubcCBiaeG7g3UgxJHhu5MgdGhhbmggKGdlb21fY29sKSB2w6BvIGdncGxvdC4gcG9zaXRpb24gPSAnZG9kZ2UnIMSR4bqjbSBi4bqjbyBjw6FjIHRoYW5oIGNobyBjw6FjIG5ow7NtIGNvbG9yIGtow6FjIG5oYXUgxJHGsOG7o2MgxJHhurd0IGPhuqFuaCBuaGF1IG3DoCBraMO0bmcgY2jhu5NuZyBs4bqlbi4gZmlsbCA9ICdibGFjaycgxJHhurd0IG3DoHUgY+G7p2EgY8OhYyB0aGFuaCB0aMOgbmggxJFlbi4NCg0KZmFjZXRfd3JhcCh+IGNvbG9yKTogQ2hpYSBuaOG7jyBiaeG7g3UgxJHhu5MgdGjDoG5oIGPDoWMgcGjhuqduIGThu7FhIHRyw6puIGPDoWMgbmjDs20gY29sb3IuIE3hu5dpIHBo4bqnbiBoaeG7g24gdGjhu4sgYmnhu4N1IMSR4buTIHRoYW5oIGNobyBt4buZdCBuaMOzbSBjb2xvciBj4bulIHRo4buDLg0KDQpnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSkpLCB2anVzdCA9IDIsIGNvbG9yID0gJ3JlZCcpOiBUaMOqbSBjaMO6IHRow61jaCB2xINuIGLhuqNuIHbDoG8gY8OhYyB0aGFuaC4gYWVzKCkgY2jhu4kgxJHhu4tuaCB2xINuIGLhuqNuIGxhYmVsIGzDoCBnacOhIHRy4buLIMSRxrDhu6NjIGzDoG0gdHLDsm4gY+G7p2EgbSAoZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCkuIHZqdXN0ID0gMiDEkWnhu4F1IGNo4buJbmggduG7iyB0csOtIGThu41jIGPhu6dhIHbEg24gYuG6o24gY2FvIGjGoW4gY8OhYyB0aGFuaCBt4buZdCBjaMO6dCDEkeG7gyBoaeG7g24gdGjhu4sgcsO1IHLDoG5nIGjGoW4uIGNvbG9yID0gJ3JlZCcgxJHhurd0IG3DoHUgdsSDbiBi4bqjbiB0aMOgbmggxJHhu48uDQoNCmxhYnMoeCA9ICdjbGFyaXR5JywgeSA9ICdNZWFuJywgdGl0bGUgPSAnSMOsbmggMS4yMycpOiBUaMOqbSBuaMOjbiBjaG8gdHLhu6VjIHggKCdjbGFyaXR5JyksIHRy4bulYyB5ICgnTWVhbicpIHbDoCB0acOqdSDEkeG7gSBjaHVuZyBjaG8gYmnhu4N1IMSR4buTICgnSMOsbmggMS4yMycpIA0KIA0KTmjhurFtIG3hu6VjIMSRw61jaCB04bqhbyByYSBt4buZdCBiaeG7g3UgxJHhu5MgY+G7mXQgxJFhIGJp4bq/biDEkeG7gyBzbyBzw6FuaCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0IHByaWNlIGThu7FhIHRyw6puIGPDoWMgbmjDs20gY2xhcml0eSB2w6AgY29sb3IsIHbhu5tpIHZp4buHYyB0aMOqbSBjaMO6IHRow61jaCB2xINuIGLhuqNuIGNobyB04burbmcgY+G7mXQgdsOgIHBow6JuIGNoaWEgYmnhu4N1IMSR4buTIHRow6BuaCBjw6FjIHBo4bqnbiBuaOG7jyBk4buxYSB0csOqbiBtw6B1IHPhuq9jDQoNCg0KYGBge3J9DQprPC0gaCAlPiUgZ3JvdXBfYnkoY3V0LCBjb2xvcikgJT4lIHN1bW1hcmlzZShuID0gbigpKQ0KayAlPiUgZ2dwbG90KGFlcyh4ID0gY3V0LCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZGF0YSA9IGsgJT4lIGZpbHRlcihjb2xvciA9PSAnRCcpLCBmaWxsID0gJ3BpbmsnKSArDQogIGdlb21fY29sKGRhdGEgPSBrICU+JSBmaWx0ZXIoY29sb3IgPT0gJ0onKSwgZmlsbCA9ICdicm93bicpK2xhYnModGl0bGU9J0jDrG5oIDEuMjQnKQ0KICANCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoKioqDQoNCiAgLSBU4bqhbyBt4buZdCBraHVuZyBk4buvIGxp4buHdSBt4bubaSBrIGLhurFuZyBjw6FjaCBuaMOzbSBk4buvIGxp4buHdSB0cm9uZyBoIHRoZW8gY8OhYyBnacOhIHRy4buLIHRyb25nIGPDoWMgY+G7mXQgY3V0IHbDoCBjb2xvci4NCiAgLSBUcm9uZyBt4buXaSBuaMOzbSwgdMOtbmggdG/DoW4gc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgKG4pIGLhurFuZyBow6BtIG4oKSB2w6AgbMawdSB0cuG7ryBr4bq/dCBxdeG6oyB0cm9uZyBj4buZdCBuIG3hu5tpLg0KICAtIEto4bufaSB04bqhbyBt4buZdCDEkeG7kWkgdMaw4bujbmcgZ2dwbG90IHThu6sga2h1bmcgZOG7ryBsaeG7h3Ugay4NCiAgLSBYw6FjIMSR4buLbmggY8OhYyB0aHXhu5ljIHTDrW5oIHRo4bqpbSBt4bu5ICjDoW5oIHjhuqEgdHLhu7FjIHF1YW4pIGNobyBiaeG7g3UgxJHhu5M6DQogIC0gVHLhu6VjIGhvw6BuaCAoeCkgxJHGsOG7o2Mgw6FuaCB44bqhIHbhu5tpIGJp4bq/biBjdXQuDQogIC0gVHLhu6VjIHR1bmcgKHkpIMSRxrDhu6NjIMOhbmggeOG6oSB24bubaSBiaeG6v24gbiAoc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQpLg0KICAtIFRow6ptIG3hu5l0IGzhu5twIGPDoWMgY+G7mXQgbcOgdSB2w6BvIGJp4buDdSDEkeG7ky4NCiAgLSBM4buNYyBk4buvIGxp4buHdSB0cm9uZyBrIMSR4buDIGNo4buJIGdp4buvIGzhuqFpIGPDoWMgaMOgbmcgY8OzIGdpw6EgdHLhu4sgY29sb3IgYuG6sW5nICdEJyAoZ2nhuqMgc+G7rSDEkeG6oWkgZGnhu4duIGNobyBt4buZdCBsb+G6oWkgY+G7pSB0aOG7gykuDQogIC0gU+G7rSBk4bulbmcgaMOgbSBnZW9tX2NvbCDEkeG7gyB04bqhbyBjw6FjIGPhu5l0IGNobyBk4buvIGxp4buHdSDEkcOjIGzhu41jLCB0w7QgbcOgdSBo4buTbmcgKCdwaW5rJykuDQogIC0gVMawxqFuZyB04buxLCB0aMOqbSBt4buZdCBs4bubcCBj4buZdCBtw6B1IGtow6FjIGNobyBjw6FjIGjDoG5nIGPDsyBjb2xvciBi4bqxbmcgJ0onLCB0w7QgbcOgdSBuw6J1ICgnYnJvd24nKS4NClF1YSBiaeG7g3UgxJHhu5MgdHLDqm4gdGEgbmjDrG4gdGjhuqV5IHThu5VuZyBz4buRIGzGsOG7o25nIGPhu6dhIGNvbG9yICdEJyBjaGnhur9tIMawdSB0aOG6vyBoxqFuIHNvIHbhu5tpIGNvbG9yICdKJyB0cm9uZyB04bqldCBjw6FjIGxv4bqhaS4gUXVhIMSRw7MgdGEgY8OzIGPDoWkgbmjDrG4gdOG7lW5nIHF1YW4gaMahbiB24buBIHBow6JuIHBo4buRaSBj4bunYSBjaMO6bmcgdHJvbmcgY8OhYyBsb+G6oWkgY+G7p2EgY+G7mXQgQ3V0LiBHacO6cCBjaG8gY2jDum5nIHRhIHRyb25nIHZp4buHYyBwaMOibiB0w61jaCB2w6AgaGnhu4N1IHLDtSBoxqFuIHbhu4EgbcOgdSBz4bqvYyBj4bunYSBjw6FjIGxv4bqhaSBraW0gY8awxqFuZy4NCnZkOiBj4buZdCBJZGVhbCBsw6AgbcOgdSBo4buTbmcgbmhp4buBdSBoxqFuIG3DoHUgZOG7jyB04bupYyBsw6Ag4bufIGxv4bqhaSBJZGVhbCBjw7MgdOG7tyBs4buHIG3DoHUgRCBs4bubbiBoxqFuIHNvIHbhu5tpIG3DoHUgSg0KDQoNCg0KYGBge3J9DQpnPC0gaCAlPiUgZ3JvdXBfYnkoY3V0LCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpDQpnICU+JSBnZ3Bsb3QoYWVzKHggPSBjdXQsIHkgPSBuKSkgKw0KICBnZW9tX2NvbChkYXRhID0gZyAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1NJMicpLCBmaWxsID0gJ2JsYWNrJykgKw0KICBnZW9tX2NvbChkYXRhID0gZyAlPiUgZmlsdGVyKGNsYXJpdHkgPT0gJ1ZTMScpLCBmaWxsID0gJ2Jyb3duJykgK2xhYnModGl0bGU9J0jDrG5oIDEuMjUnKQ0KYGBgDQoNCioqKk5o4bqtbiB4w6l0IGvhur90IHF14bqjKioqDQoNCk5ow7NtIGThu68gbGnhu4d1OiBE4buvIGxp4buHdSDEkcaw4bujYyBuaMOzbSB0aGVvIGhhaSBiaeG6v246ICJjdXQiIHbDoCAiY2xhcml0eSIuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBk4buvIGxp4buHdSDEkcaw4bujYyBwaMOibiBjaGlhIHRow6BuaCBjw6FjIG5ow7NtIGThu7FhIHRyw6puIGdpw6EgdHLhu4sgY+G7p2EgaGFpIGJp4bq/biBuw6B5Lg0KVOG7lW5nIGjhu6NwIHPhu5EgbMaw4bujbmcgbeG6q3U6IFNhdSBraGkgZOG7ryBsaeG7h3UgxJHGsOG7o2MgbmjDs20sIHThu5VuZyBz4buRIGzGsOG7o25nIG3huqt1IHRyb25nIG3hu5dpIG5ow7NtIMSRxrDhu6NjIHTDrW5oIHRvw6FuIGLhurFuZyBow6BtIHN1bW1hcmlzZSgpIHbDoCBsxrB1IHbDoG8gbeG7mXQgYmnhur9uIG3hu5tpIMSRxrDhu6NjIMSR4bq3dCB0w6puIGzDoCBuLg0KVOG6oW8gYmnhu4N1IMSR4buTIGPhu5l0OiBT4butIGThu6VuZyBnw7NpIGdncGxvdDIsIG3hu5l0IGJp4buDdSDEkeG7kyBj4buZdCDEkcaw4bujYyB04bqhbyByYS4gVHLhu6VjIHggY+G7p2EgYmnhu4N1IMSR4buTIGzDoCBjw6FjIGxv4bqhaSAiY3V0IiwgdsOgIHRy4bulYyB5IGzDoCBz4buRIGzGsOG7o25nIG3huqt1LiBIYWkgY+G7mXQgxJHGsOG7o2MgduG6vSwgbeG7l2kgY+G7mXQgxJHhuqFpIGRp4buHbiBjaG8gbeG7mXQgbcOgdSBz4bqvYzogIkgiIHbDoCAiRSIuIEPhu5l0IG3DoHUgYnJvd24gxJHhuqFpIGRp4buHbiBjaG8gbcOgdSAiRSIsIHRyb25nIGtoaSBj4buZdCBtw6B1IMSRZW4gxJHhuqFpIGRp4buHbiBjaG8gbcOgdSAiSCIuDQoNClF1YSBiaeG7g3UgxJHhu5MgdHLDqm4gdGEgbmjDrG4gdGjhuqV5IHThu5VuZyBz4buRIGzGsOG7o25nIGPhu6dhIGNvbG9yICdFJyBjaGnhur9tIMawdSB0aOG6vyBoxqFuIHNvIHbhu5tpIGNvbG9yICdIJyB0cm9uZyB04bqldCBjw6FjIGxv4bqhaSBxdWEgxJHDsyB0YSBjw7MgY8OhaSBuaMOsbiB04buVbmcgcXVhbiBoxqFuIHbhu4EgcGjDom4gcGjhu5FpIGPhu6dhIGNow7puZyB0cm9uZyBjw6FjIGxv4bqhaSBj4bunYSBj4buZdCBDdXQuIEdpw7pwIGNobyBjaMO6bmcgdGEgdHJvbmcgdmnhu4djIHBow6JuIHTDrWNoIHbDoCBoaeG7g3UgcsO1IGjGoW4gduG7gSDEkeG7mSB0cm9uZyBzdeG7kXQgY+G7p2EgY8OhYyBsb+G6oWkga2ltIGPGsMahbmcuIA0KDQoNCg0KDQoNCmBgYHtyfQ0KcDwtIGggJT4lIGdyb3VwX2J5KGNvbG9yLCBjbGFyaXR5KSAlPiUgc3VtbWFyaXNlKG4gPSBuKCkpDQpwICU+JSBnZ3Bsb3QoYWVzKHggPSBjb2xvciwgeSA9IG4pKSArDQogIGdlb21fY29sKGRhdGEgPSBwICU+JSBmaWx0ZXIoY2xhcml0eSA9PSAnU0kyJyksIGZpbGwgPSAncGluaycpICsNCiAgZ2VvbV9jb2woZGF0YSA9IHAgJT4lIGZpbHRlcihjbGFyaXR5ID09ICdWUzEnKSwgZmlsbCA9ICdicm93bicpICtsYWJzKHRpdGxlPSdIw6xuaCAxLjI2JykNCmBgYA0KDQoqKipOaOG6rW4geMOpdCBiaeG7g3UgxJHhu5MqKioNCg0KQsaw4bubYyBuw6B5IHTDrW5oIHRvw6FuIHPhu5EgbMaw4bujbmcgcXVhbiBzw6F0IChz4buRIGzhuqduIHh14bqldCBoaeG7h24pIGPhu6dhIG3hu5dpIHThu5UgaOG7o3AgImNvbG9yIiB2w6AgImNsYXJpdHkiIHRyb25nIHThuq1wIGThu68gbGnhu4d1Lg0KDQpCaeG7g3UgxJHhu5MgaMOsbmggY+G7mXQgxJHGsOG7o2MgdOG6oW8gcmEsIHbhu5tpIHRy4bulYyBob8OgbmggdGjhu4MgaGnhu4duICJtw6B1IHPhuq9jIiB2w6AgdHLhu6VjIHR1bmcgdGjhu4MgaGnhu4duIHPhu5EgbMaw4bujbmcgcXVhbiBzw6F0IChz4buRIGzhuqduIHh14bqldCBoaeG7h24pIGPhu6dhIG3hu5dpIHThu5UgaOG7o3AgIiBjb2xvciAiIHbDoCAiY2xhcml0eSIuDQoNCkhhaSBuaMOzbSB0aGFuaCByacOqbmcgYmnhu4d0IMSRxrDhu6NjIHRow6ptIHbDoG8gYmnhu4N1IMSR4buTOg0KICBOaMOzbSB0aGFuaCBtw6B1IGjhu5NuZzogSGnhu4NuIHRo4buLIHPhu5EgbMaw4bujbmcgcXVhbiBzw6F0IChz4buRIGzhuqduIHh14bqldCBoaeG7h24pIGPhu6dhIGPDoWMgxJHhu5FpIHTGsOG7o25nIGPDsyAiY2xhcml0eSIgbMOgICJTSTIiIGNobyB04burbmcgImNvbG9yIi4NCiAgTmjDs20gdGhhbmggbcOgdSBuw6J1OiBIaeG7g24gdGjhu4sgc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgKHPhu5EgbOG6p24geHXhuqV0IGhp4buHbikgY+G7p2EgY8OhYyDEkeG7kWkgdMaw4bujbmcgY8OzICJjbGFyaXR5IiBsw6AgIlZTMSIgY2hvIHThu6tuZyAiY29sb3IiLg0KICANClF1YSBiaeG7g3UgxJHhu5MgdHLDqm4gY2jhurNuZyBo4bqhbiBuaMawIOG7nyBj4buZdCBFIHRhIHRo4bqleSBjw7MgMiBtw6B1IHRow6wgbcOgdSBicm93biBjaGnhur9tIMawdSB0aOG6vyBoxqFuIHNvIHbhu5tpIG3DoHUgaOG7k25nIHThu6ljIGzDoCDEkeG7mSB0cm9uZyBzdeG7kXQgY2xhcml0eSBTSTIgY2hp4bq/bSB04bu3IGzDqm4gw610IGjGoW4gc28gduG7m2kgVlMxDQoNCg0KYGBge3J9DQpvIDwtIGggJT4lIG11dGF0ZShjYXJhdEMgPSBjdXQoY2FyYXQsNSwgbGFiZWwgPSBjKCdy4bqldCBuaOG7jycsICduaOG7jycsJ3bhu6thJywnbOG7m24nLCdy4bqldCBs4bubbicpKSkNCm8gJT4lIGdncGxvdChhZXMoeCA9IGNhcmF0QykpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICd5ZWxsb3cnKStsYWJzKHRpdGxlPSdIw6xuaCAxLjI3MjcnKQ0KYGBgDQoNCioqKkdp4bqjaSB0aMOtY2ggY8OidSBs4buHbmgqKioNCg0KICAtIG88LTogR8OhbiBnacOhIHRy4buLIGNobyBiaeG6v24gby4NCiAgLSBoJT4lOiBT4butIGThu6VuZyBwaXBlICglPiUpIMSR4buDIGNodXnhu4NuIGvhur90IHF14bqjIGPhu6dhIGJp4buDdSB0aOG7qWMgYsOqbiB0csOhaSBzYW5nIGJp4buDdSB0aOG7qWMgYsOqbiBwaOG6o2kuDQogIC0gbXV0YXRlKGNhcmF0QyA9Y3V0KGNhcmF0LDUsbGFiZWw9YygncuG6pXQgbmjhu48nLCduaOG7jycsJ3bhu6thJywnbOG7m24nLCdy4bqldCBs4bubbicpKSk6IFRow6ptIG3hu5l0IGPhu5l0IG3hu5tpIHTDqm4gbMOgIGNhcmF0QyB2w6BvIGRhdGFmcmFtZSBvLiBD4buZdCBjYXJhdEMgxJHGsOG7o2MgdOG6oW8gcmEgYuG6sW5nIGPDoWNoIHBow6JuIGNoaWEgY+G7mXQgY2FyYXQgdGjDoG5oIDUgbmjDs20gYuG6sW5nIG5oYXUgKGN1dCkgdsOgIGfDoW4gbmjDo24gY2hvIG3hu5dpIG5ow7NtIChsYWJlbCkuDQogIC0gbyAlPiU6IFPhu60gZOG7pW5nIHBpcGUgKCU+JSkgxJHhu4MgY2h1eeG7g24ga+G6v3QgcXXhuqMgY+G7p2EgYmnhu4N1IHRo4bupYyBiw6puIHRyw6FpIHNhbmcgYmnhu4N1IHRo4bupYyBiw6puIHBo4bqjaS4NCiAgLSBnZ3Bsb3QoYWVzKHg9Y2FyYXRDKSk6IFThuqFvIG3hu5l0IGdncGxvdCBvYmplY3QgduG7m2kgdHLhu6VjIHggbMOgIGJp4bq/biBjYXJhdEMuDQogIC0gZ2VvbV9iYXIoZmlsbD0neWVsbG93Jyk6IFRow6ptIG3hu5l0IGxheWVyIGdlb21fYmFyIHbDoG8gZ2dwbG90IG9iamVjdC4gTGF5ZXIgbsOgeSBoaeG7g24gdGjhu4sgYmnhu4N1IMSR4buTIHRoYW5oIHbhu5tpIHRy4bulYyB4IGzDoCBjYXJhdEMsIHRy4bulYyB5IGzDoCBz4buRIGzGsOG7o25nIHF1YW4gc8OhdCB0cm9uZyBt4buXaSBuaMOzbSwgdsOgIG3DoHUgc+G6r2MgY+G7p2EgdGhhbmggxJHGsOG7o2MgdMO0IG3DoHUgdsOgbmcgKGZpbGw9J3llbGxvdycpLg0KDQoqKipOaOG6rW4geMOpdCBL4bq/dCBxdeG6oyoqKg0KDQogIMSQw6J5IGzDoCBt4buZdCBk4bqhbmcgYmnhu4N1IMSR4buTIGThuqFuZyBCYXJfQ2hhcnQgbsOzaSBz4buRIGzGsOG7o25nIGPhu6dhIGPhu5l0ICoqQ2FyYXRDKiogduG7q2EgbeG7m2kgdOG6oW8gdHJvbmcgxJHGsOG7o2MgZ8OhbiB2w6BvIGJp4bq/biBvLiBCaeG7g3UgxJHhu5MgdGhhbmggbsOgeSBjaG8gdGjhuqV5IHPhu7EgcGjDom4gYuG7kSBj4bunYSBjw6FjIHZpw6puIGtpbSBjxrDGoW5nIGThu7FhIHRyw6puIGvDrWNoIHRoxrDhu5tjIGNhcmF0IGPhu6dhIGNow7puZywgxJHGsOG7o2MgY2hpYSB0aMOgbmggNSBuaMOzbTogInLhuqV0IG5o4buPIiwgIm5o4buPIiwgInbhu6thIiwgImzhu5tuIiB2w6AgInLhuqV0IGzhu5tuIi4gQ2hp4buBdSBjYW8gY+G7p2EgbeG7l2kgdGhhbmggYmnhu4N1IHRo4buLIHPhu5EgbMaw4bujbmcgdmnDqm4ga2ltIGPGsMahbmcgdHJvbmcgbmjDs20ga8OtY2ggdGjGsOG7m2MgY2FyYXQgdMawxqFuZyDhu6luZy4NCg0KICBOaMOzbSAiduG7q2EiIGzDoCBuaMOzbSBwaOG7lSBiaeG6v24gbmjhuqV0Lk5ow7NtICJy4bqldCBuaOG7jyIgdsOgICJy4bqldCBs4bubbiIgbMOgIG5ow7NtIMOtdCBwaOG7lSBiaeG6v24gbmjhuqV0LkPDsyBz4buxIHBow6JuIGLhu5EgdMawxqFuZyDEkeG7kWkgxJHhu5NuZyDEkeG7gXUgZ2nhu69hIGPDoWMgbmjDs20gIm5o4buPIiwgInbhu6thIiB2w6AgImzhu5tuIi5T4buRIGzGsOG7o25nIGtpbSBjxrDGoW5nIGPDsyB4dSBoxrDhu5tuZyBnaeG6o20gZOG6p24gdGhlbyBrw61jaCB0aMaw4bubYy5LaW0gY8awxqFuZyBjw7Mga8OtY2ggdGjGsOG7m2MgInLhuqV0IG5o4buPIiBjaGnhur9tIHPhu5EgbMaw4bujbmcgbOG7m24gbmjhuqV0IGPhu6UgdGjhu4MgbMOgICwgdGnhur9wIHRoZW8gbMOgICJuaOG7jyIsICJ24burYSIgdsOgICJs4bubbiIuS2ltIGPGsMahbmcgInLhuqV0IGzhu5tuIiBjw7Mgc+G7kSBsxrDhu6NuZyDDrXQgbmjhuqV0Lg0KDQpWw60gZOG7pTpHaeG6oyBz4butIGJp4buDdSDEkeG7kyB0aGFuaCBjaG8gdGjhuqV5IG5ow7NtICJ24burYSIgY8OzIGNoaeG7gXUgY2FvIGNhbyBuaOG6pXQuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBjw7Mgbmhp4buBdSB2acOqbiBraW0gY8awxqFuZyB0aHXhu5ljIG5ow7NtIGvDrWNoIHRoxrDhu5tjIGNhcmF0IG7DoHkgaMahbiBzbyB24bubaSBjw6FjIG5ow7NtIGtow6FjLiBOZ8aw4bujYyBs4bqhaSwgbmjDs20gInLhuqV0IG5o4buPIiBjw7MgY2hp4buBdSBjYW8gdGjhuqVwIG5o4bqldCwgY2hvIHRo4bqleSBz4buRIGzGsOG7o25nIHZpw6puIGtpbSBjxrDGoW5nIHRyb25nIG5ow7NtIG7DoHkgw610IGjGoW4gc28gduG7m2kgY8OhYyBuaMOzbSBraMOhYy4NCg0KDQpgYGB7cn0NCmglPiUgZ3JvdXBfYnkoY3V0KSAlPiUgc3VtbWFyaXNlKG09IG1lYW4oY2FyYXQpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gY3V0LHkgPSBtKSkgKw0KICAgIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChtLDIpKSwgdmp1c3QgPSAyLCBjb2xvciA9ICdwaW5rJykgKw0KICAgIGxhYnMoeCA9ICdjdXQnLCB5ID0gJ01lYW4nLHRpdGxlPSdIw6xuaCAxLjI4OiBHacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGNhcmF0IHRoZW8gYmnhur9uIGN1dCcpDQoNCmBgYA0KDQoqKipHaeG6o2kgdGjDrWNoIGPDonUgbOG7h25oKioqDQoNCiAgLSBzdW1tYXJpc2UobSA9IG1lYW4oY2FyYXQpKTogVMOtbmggdG/DoW4gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCAobWVhbikgY+G7p2EgY+G7mXQgY2FyYXQgKHRy4buNbmcgbMaw4bujbmcga2ltIGPGsMahbmcpIGNobyBt4buXaSBuaMOzbSDEkcaw4bujYyB04bqhbyBi4bufaSBs4buHbmggZ3JvdXBfYnkuIEvhur90IHF14bqjIMSRxrDhu6NjIGzGsHUgdHJvbmcgbeG7mXQgY+G7mXQgbeG7m2kgY8OzIHTDqm4gbS4NCiAgLSBwb3NpdGlvbiA9ICdkb2RnZSc6IFjhur9wIGPDoWMgY+G7mXQgY+G6oW5oIG5oYXUgdGhlbyB0aOG7qSB04buxIGPhu6dhIGPDoWMgbmjDs20gKG3DoHUpIHRyw6puIHRy4bulYyBob8OgbmgsIHRyw6FuaCBjaOG7k25nIGNow6lvIGzDqm4gbmhhdS4NCiAgLSBnZW9tX3RleHQoKTogVGjDqm0gbeG7mXQgbOG7m3AgdsSDbiBi4bqjbiAodGV4dCkgdsOgbyBiaeG7g3UgxJHhu5MuDQogIC0gYWVzKGxhYmVsID0gcm91bmQobSwgMikpOiBHw6FuIG5ow6NuIGNobyBjw6FjIGPhu5l0IGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIHRy4buNbmcgbMaw4bujbmcga2ltIGPGsMahbmcgKG0pLCDEkcaw4bujYyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuIChyb3VuZChtLCAyKSkuDQogIC0gbGFicygpOiBUaMOqbSBuaMOjbiBjaG8gdHLhu6VjIGhvw6BuaCAoeCkgdsOgIHRy4bulYyB0dW5nICh5KS4NCiAgLSB4ID0gJ03DoHUnOiBHw6FuIG5ow6NuICJNw6B1IiBjaG8gdHLhu6VjIGhvw6BuaCwgYmnhu4N1IHRo4buLIGPDoWMgbmjDs20gdGhlbyBtw6B1IHPhuq9jIGtpbSBjxrDGoW5nLg0KICAtIHkgPSAnTWVhbic6IEfDoW4gbmjDo24gIk1lYW4iIChUcnVuZyBiw6xuaCkgY2hvIHRy4bulYyB0dW5nLCBiaeG7g3UgdGjhu4sgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIGtpbSBjxrDGoW5nLg0KDQoqKlTDs20gdOG6r3Q6KioNCg0KxJDDonkgbMOgIMSRb+G6oW4gbcOjIHPhu60gZOG7pW5nIHRoxrAgdmnhu4duIGdncGxvdDIgdHJvbmcgUiDEkeG7gyB04bqhbyBiaeG7g3UgxJHhu5MgY+G7mXQgdGjhu4MgaGnhu4duIG3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgbcOgdSBz4bqvYyAoY3V0KSB2w6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSB0cuG7jW5nIGzGsOG7o25nIChjYXJhdCkga2ltIGPGsMahbmcuIEJp4buDdSDEkeG7kyDEkcaw4bujYyB0w7l5IGNo4buJbmggduG7m2kgY8OhYyBj4buZdCB44bq/cCBj4bqhbmggbmhhdSwgbmjDo24gdsSDbiBi4bqjbiBtw6B1IGjhu5NuZyBsw6BtIHRyw7JuIMSR4bq/biAyIGNo4buvIHPhu5EgdGjhuq1wIHBow6JuLCB2w6AgbmjDo24gdHLhu6VjIMSRxrDhu6NjIMSR4bq3dCB0w6puIHRoZW8gw70gbmdoxKlhLg0KIA0KKioqTmjhuq1uIHjDqXQga+G6v3QgcXXhuqMqKioNCg0KICAtIETDonkgbMOgIGzDoCBt4buZdCBiaeG7g3UgxJHDsiBkYW5nIEJhcl9DaGFydCB0aOG7gyBoaeG7h24gZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBjYXJhdChrw61jaCB0aMaw4bubYyBraW0gY8awxqFuZykgdGhlbyBiaeG6v24gY3V0DQogIC0gQmnhu4N1IMSR4buTIGNobyB0aOG6pXkgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24gImNhcmF0IiBkYW8gxJHhu5luZyB0cm9uZyBraG/huqNuZyAwLjcgxJHhur9uIDEuMDUgY2FyYXQuDQogIC0gTmjDs20gIkZhaXIiIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIHRo4bqlcCBuaOG6pXQgKGtob+G6o25nIDAuNyBjYXJhdCkuDQogIC0gTmjDs20gIklkZWFsIiBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBjYW8gbmjhuqV0IChraG/huqNuZyAxLjA1IGNhcmF0KS4NCiAgLSBOaMOsbiBjaHVuZywgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBiaeG6v24gImNhcmF0IiB0xINuZyBk4bqnbiB04burIG5ow7NtICJGYWlyIiDEkeG6v24gbmjDs20gIklkZWFsIi4NClN1eSByYSwga2nhu4N1IGPhuq90IGtpbSBjxrDGoW5nIOG6o25oIGjGsOG7n25nIMSR4bq/biBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGJp4bq/biAiY2FyYXQiLktpbSBjxrDGoW5nIGPDsyBraeG7g3UgY+G6r3QgIklkZWFsIiBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBjYW8gbmjhuqV0IHbhu4EgYmnhur9uICJjYXJhdCIuDQoNCg0KDQpgYGB7cn0NCg0KaCU+JSBncm91cF9ieShjdXQpICU+JSBzdW1tYXJpc2UobT0gbWVkaWFuKGNhcmF0KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGN1dCx5ID0gbSkpICsNCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZScpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobSwyKSksIHZqdXN0ID0gMiwgY29sb3IgPSAncGluaycpICsNCiAgICBsYWJzKHggPSAnY3V0JywgeSA9ICdNZWRpYW4nLHRpdGxlPSdIw6xuaCAxLjI5OiBUcnVuZyB24buLIGPhu6dhIGNhcmF0IHRoZW8gYmnhur9uIGN1dCcpDQoNCmBgYA0KDQoqKipOaOG6rW4geMOpdCBr4bq/dCBxdeG6oyoqKg0KIA0KQ2jhuqV0IGzGsOG7o25nIGPhuq90ICJJZGVhbCIgKGhvw6BuIGjhuqNvKTogY+G7mXQgIklkZWFsIiB0aOG6pXAgbmjhuqV0IHRyb25nIGJp4buDdSDEkeG7ky4gxJBp4buBdSBuw6B5IGPDsyBuZ2jEqWEgbMOgIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgaG/DoG4gaOG6o28gY8OzIHRydW5nIHbhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCB0aOG6pXAgbmjhuqV0LiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIklkZWFsIiBjw7MgdGjhu4MgaGnhu4NuIHRo4buLIGdpw6EgdHLhu4sgMC41NCBjYXJhdCwgY2hvIGJp4bq/dCBu4butYSBz4buRIGtpbSBjxrDGoW5nIGPDsyBjaOG6pXQgbMaw4bujbmcgY+G6r3QgaG/DoG4gaOG6o28gY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgdGjhuqVwIGjGoW4gMC41NCBjYXJhdCwgdsOgIG7hu61hIGPDsm4gbOG6oWkgY8OzIHRy4buNbmcgbMaw4bujbmcgY2FyYXQgY2FvIGjGoW4gMC41NCBjYXJhdC4NCg0KQ2jhuqV0IGzGsOG7o25nIGPhuq90ICJGYWlyIiAoa8OpbSk6ICBj4buZdCAiRmFpciIgY2FvIG5o4bqldCB0cm9uZyBiaeG7g3UgxJHhu5MuIMSQaeG7gXUgbsOgeSBjw7MgbmdoxKlhIGzDoCBraW0gY8awxqFuZyBjw7MgY2jhuqV0IGzGsOG7o25nIGPhuq90IGvDqW0gY8OzIHRydW5nIHbhu4sgdHLhu41uZyBsxrDhu6NuZyBjYXJhdCBjYW8gbmjhuqV0LiBWw60gZOG7pSwgY2jDuiB0aMOtY2ggdHLDqm4gY+G7mXQgIkZhaXIiIGPDsyB0aOG7gyBoaeG7g24gdGjhu4sgZ2nDoSB0cuG7iyAxIGNhcmF0LCBjaG8gYmnhur90IG7hu61hIHPhu5Ega2ltIGPGsMahbmcgY8OzIGNo4bqldCBsxrDhu6NuZyBj4bqvdCBrw6ltIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IHRo4bqlcCBoxqFuIDEgY2FyYXQsIHbDoCBu4butYSBjw7JuIGzhuqFpIGPDsyB0cuG7jW5nIGzGsOG7o25nIGNhcmF0IGNhbyBoxqFuIDEgY2FyYXQuDQoNCmBgYHtyfQ0KYiA8LSBoJT4lIGdyb3VwX2J5KGN1dCwgY29sb3IpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkNCiBiICU+JSBnZ3Bsb3QoYWVzKHggPSBjdXQsIHkgPSBuKSkgKw0KICBnZW9tX2NvbChkYXRhID0gYiAlPiUgZmlsdGVyKGNvbG9yID09ICdFJyksIGZpbGwgPSAncGluaycpICsNCiAgZ2VvbV9jb2woZGF0YSA9IGIgJT4lIGZpbHRlcihjb2xvciA9PSAnSCcpLCBmaWxsID0gJ2JsYWNrJykrbGFicyh0aXRsZT0nSMOsbmggMS4zMDogVOG7lW5nIHPhu5EgbMaw4bujbmcga2ltIGPGsMahbmcgdGhlbyBiaeG6v24gY3V0IG3DoCBjb2xvcicpDQpgYGANCg0KKioqTmjhuq1uIHjDqXQgYmnhu4N1IMSR4buTKioqDQoNCk5ow7NtIGThu68gbGnhu4d1OiBE4buvIGxp4buHdSDEkcaw4bujYyBuaMOzbSB0aGVvIGhhaSBiaeG6v246ICJjdXQiIHbDoCAiY29sb3IiLiDEkGnhu4F1IG7DoHkgY8OzIG5naMSpYSBsw6AgZOG7ryBsaeG7h3UgxJHGsOG7o2MgcGjDom4gY2hpYSB0aMOgbmggY8OhYyBuaMOzbSBk4buxYSB0csOqbiBnacOhIHRy4buLIGPhu6dhIGhhaSBiaeG6v24gbsOgeS4NClThu5VuZyBo4bujcCBz4buRIGzGsOG7o25nIG3huqt1OiBTYXUga2hpIGThu68gbGnhu4d1IMSRxrDhu6NjIG5ow7NtLCB04buVbmcgc+G7kSBsxrDhu6NuZyBt4bqrdSB0cm9uZyBt4buXaSBuaMOzbSDEkcaw4bujYyB0w61uaCB0b8OhbiBi4bqxbmcgaMOgbSBzdW1tYXJpc2UoKSB2w6AgbMawdSB2w6BvIG3hu5l0IGJp4bq/biBt4bubaSDEkcaw4bujYyDEkeG6t3QgdMOqbiBsw6Agbi4NClThuqFvIGJp4buDdSDEkeG7kyBj4buZdDogU+G7rSBk4bulbmcgZ8OzaSBnZ3Bsb3QyLCBt4buZdCBiaeG7g3UgxJHhu5MgY+G7mXQgxJHGsOG7o2MgdOG6oW8gcmEuIFRy4bulYyB4IGPhu6dhIGJp4buDdSDEkeG7kyBsw6AgY8OhYyBsb+G6oWkgImN1dCIsIHbDoCB0cuG7pWMgeSBsw6Agc+G7kSBsxrDhu6NuZyBt4bqrdS4gSGFpIGPhu5l0IMSRxrDhu6NjIHbhur0sIG3hu5dpIGPhu5l0IMSR4bqhaSBkaeG7h24gY2hvIG3hu5l0IG3DoHUgc+G6r2M6ICJFIiB2w6AgIkgiLiBD4buZdCBtw6B1IGjhu5NuZyDEkeG6oWkgZGnhu4duIGNobyBtw6B1ICJFIiwgdHJvbmcga2hpIGPhu5l0IG3DoHUgxJFlbiDEkeG6oWkgZGnhu4duIGNobyBtw6B1ICJIIi4NClRpw6p1IMSR4buBIGPhu6dhIGJp4buDdSDEkeG7kzogVGnDqnUgxJHhu4EgY+G7p2EgYmnhu4N1IMSR4buTIMSRxrDhu6NjIMSR4bq3dCBsw6AgIkjDrG5oIDEuMzAiLg0KDQpRdWEgYmnhu4N1IMSR4buTIHRyw6puIHRhIG5ow6xuIHRo4bqleSB04buVbmcgc+G7kSBsxrDhu6NuZyBj4bunYSBjb2xvciAnSCcgY2hp4bq/bSDGsHUgdGjhur8gaMahbiBzbyB24bubaSBjb2xvciAnRSB0cm9uZyB04bqldCBjw6FjIGxv4bqhaS4gUXVhIMSRw7MgdGEgY8OzIGPDoWkgbmjDrG4gdOG7lW5nIHF1YW4gaMahbiB24buBIHBow6JuIHBo4buRaSBj4bunYSBjaMO6bmcgdHJvbmcgY8OhYyBsb+G6oWkgY+G7p2EgY+G7mXQgQ3V0LiBHacO6cCBjaG8gY2jDum5nIHRhIHRyb25nIHZp4buHYyBwaMOibiB0w61jaCB2w6AgaGnhu4N1IHLDtSBoxqFuIHbhu4EgbcOgdSBz4bqvYyBj4bunYSBjw6FjIGxv4bqhaSBraW0gY8awxqFuZy4NCg0KDQoNCiAgDQoNCg0KDQoNCg==