1 Nhiệm vụ 3.1:

1.1 Mục tiêu nghiên cứu:

  • Nắm bắt sự thay đổi về dân số của China, Japan, Spain, Thailand, Vietnam trong 72 năm

  • Nắm bắt sự thay đổi về dân số Vietnam thông qua các đặc trưng đo lường

  • Biết được trung bình về dân số trong 72 năm của 5 quốc gia

  • Biết được các giá trị trung bình dân số độ tuổi từ 70 đến 79 của 5 quốc gia trong năm 2020

  • Biết được các giá trị trung bình về dân số trẻ em dưới 15 tuổi của 5 quốc gia ở năm 1970 và năm 1990

1.2 Phương pháp nghiên cứu

  • Sử dụng các phương pháp:

    • Mã hóa dữ liệu

    • Tạo bảng tần số

    • Tính toán các đặc trưng đo lường

1.3 Giải thích bộ dữ liệu:

Dữ liệu trong file population-and-demography.csv nói về Dân số và Nhân khẩu học của 254 quốc gia được phân tích trong 72 năm từ năm 1950 đến năm 2021

Có 18288 hàng tương ứng với 18288 quan sát

Có 24 cột tương ứng với 24 biến

  • Country name: Tên Quốc Gia

  • Year: Năm lấy số liệu

  • Population: Dân số

  • Population of children under the age of 1: Dân số trẻ em dưới 1 tuổi

  • Population of children under the age of 5: Dân số trẻ em dưới 5 tuổi

  • Population of children under the age of 15: Dân số trẻ em dưới 15 tuổi

  • Population under the age of 25: Dân số dưới 25 tuổi

  • Population aged 15 to 64 years: Dân số từ 15 đến 64 tuổi

  • Population older than 15 years: Dân số lớn hơn 15 tuổi

  • Population older than 18 years: Dân số lớn hơn 18 tuổi

  • Population at age 1: Dân số 1 tuổi

  • Population aged 1 to 4 years: Dân số từ 1 đến 4 tuổi

  • Population aged 5 to 9 years: Dân số từ 5 đến 9 tuổi

  • Population aged 10 to 14 years: Dân số từ 10 đến 14 tuổi

  • Population aged 15 to 19 years: Dân số từ 15 đến 19 tuổi

  • Population aged 20 to 29 years: Dân số từ 20 đến 29 tuổi

  • Population aged 30 to 39 years: Dân số từ 30 đến 39 tuổi

  • Population aged 40 to 49 years: Dân số từ 40 đến 49 tuổi

  • Population aged 50 to 59 years: Dân số từ 50 đến 59 tuổi

  • Population aged 60 to 69 years: Dân số từ 60 đến 69 tuổi

  • Population aged 70 to 79 years: Dân số từ 70 đến 79 tuổi

  • Population aged 80 to 89 years: Dân số từ 80 đến 89 tuổi

  • Population aged 90 to 99 years: Dân số từ 90 đến 99 tuổi

  • Population older than 100 years: Dân số lớn hơn 100 tuổi

1.4 Phân tích dữ liệu về dân số của China, Japan, Spain, Thailand, Vietnam trong 72 năm:

  • Tạo một bản sao của file dữ liệu population-and-demography.csv và gán nó vào một biến mới có tên p. Điều này giúp bạn giữ nguyên dữ liệu gốc trong khi thực hiện các thao tác trên bản sao.
p <- read.csv(file.choose(), header = T)

datatable(p)
  • Thực hiện đổi tên các biến của dữ liệu để dễ dàng gọi tên trong các thao tác phân tích
names(p) <- c('cn','y','p','pcu1','pcu5','pcu15','pu25','p15to64','po15','po18','p1','p1to4','p5to9','p10to14','p15to19','p20to29','p30to39','p40to49','p50to59','p60to69','p70to79','p80to89','p90t90to99','po100')
datatable(p)
  • Trong R, đối tượng dữ liệu là một tập hợp các biến. Mỗi biến có một tên duy nhất. Câu lệnh này sẽ thay đổi tên của các biến trong đối tượng dữ liệu p thành các tên được liệt kê trong vector c(‘cn’,‘y’,‘p’,‘pcu1’,‘pcu5’,‘pcu15’,‘pu25’,‘p15to64’,‘po15’,‘po18’,‘p1’,‘p1to4’,‘p5to9’,‘p10to14’,‘p15to19’,‘p20to29’,‘p30to39’,‘p40to49’,‘p50to59’,‘p60to69’,‘p70to79’,‘p80to89’,‘p90t90to99’,‘po100’).

  • Chẳng hạn, tên dữ liệu được rút gọn như sau:

    • Country name được đổi tên thành cn: Tên Quốc Gia

    • Year được đổi tên thành y: Năm lấy số liệu

    • Population được đổi tên thành p: Dân số

    • Population of children under the age of 1 được đổi tên thành pcu1: Dân số trẻ em dưới 1 tuổi

    • Population of children under the age of 5 được đổi tên thành pcu5: Dân số trẻ em dưới 5 tuổi

    • Population of children under the age of 15 được đổi tên thành pcu15: Dân số trẻ em dưới 15 tuổi

    • Population under the age of 25 được đổi tên thành pu25: Dân số dưới 25 tuổi

    • Population aged 15 to 64 years được đổi tên thành p15to64: Dân số từ 15 đến 64 tuổi

    • Population older than 15 years được đổi tên thành po15: Dân số lớn hơn 15 tuổi

    • Population older than 18 years được đổi tên thành po18: Dân số lớn hơn 18 tuổi

    • Population at age 1 được đổi tên thành p1: Dân số 1 tuổi

    • Population aged 1 to 4 years được đổi tên thành p1to4: Dân số từ 1 đến 4 tuổi

    • Population aged 5 to 9 years được đổi tên thành p5to9: Dân số từ 5 đến 9 tuổi

    • Population aged 10 to 14 years được đổi tên thành p10to14: Dân số từ 10 đến 14 tuổi

    • Population aged 15 to 19 years được đổi tên thành p15to19: Dân số từ 15 đến 19 tuổi

    • Population aged 20 to 29 years được đổi tên thành p20to29: Dân số từ 20 đến 29 tuổi

    • Population aged 30 to 39 years được đổi tên thành p30to39: Dân số từ 30 đến 39 tuổi

    • Population aged 40 to 49 years được đổi tên thành p40to49: Dân số từ 40 đến 49 tuổi

    • Population aged 50 to 59 years được đổi tên thành p50to59: Dân số từ 50 đến 59 tuổi

    • Population aged 60 to 69 years được đổi tên thành p60to69: Dân số từ 60 đến 69 tuổi

    • Population aged 70 to 79 years được đổi tên thành p70to79: Dân số từ 70 đến 79 tuổi

    • Population aged 80 to 89 years được đổi tên thành p80to89: Dân số từ 80 đến 89 tuổi

    • Population aged 90 to 99 years được đổi tên thành p90to99: Dân số từ 90 đến 99 tuổi

    • Population older than 100 years được đổi tên thành po100: Dân số lớn hơn 100 tuổi

  • Thực hiện lọc 5 quốc gia cần phân tích, ở đây phân tích “China, Japan, Spain, Thailand, Vietnam”

  • Chọn 5 cột số liệu về các độ tuổi của dân số trong các năm, ở đây phân tích tổng dân số của 5 quốc gia (p), dân số trẻ em dưới 15 tuổi (pcu15), dân số dưới 25 tuổi (pu25), dân số từ 30 đến 39 tuổi (p30to39), dân số từ 70 đến 79 tuổi (p70to79)

  • Xóa bỏ các cột thừa chỉ giữ lại 7 cột cần lấy dữ liệu để phân tích và gán cho dữ liệu mới một object p1

p1 <- filter(p, cn == 'China' | cn == 'Japan' | cn == 'Spain' | cn == 'Thailand' | cn == 'Vietnam') %>% select(-c('pcu1','pcu5','p15to64','po15','po18','p1','p1to4','p5to9','p10to14','p15to19','p20to29','p40to49','p50to59','p60to69','p80to89','p90t90to99','po100'))

datatable(p1)
  • Qua bảng trên ta có thể thấy được, dân số của 5 nước trên hầu như tăng dần qua từng năm

  • Tiến hành in ra một bảng tần suất dựa trên các giá trị của biến cn trong đối tượng dữ liệu p1.

  • Bảng tần suất là một cách để hiển thị dữ liệu theo cách cho thấy số lần mỗi giá trị xuất hiện. Trong trường hợp này, bảng tần suất sẽ cho biết có bao nhiêu quan sát cho mỗi giá trị duy nhất có trong biến cn của p1. Điều này sẽ cung cấp cho bạn tổng quan về số lượng quan sát thuộc mỗi danh mục quốc gia.

table(p1$cn)
## 
##    China    Japan    Spain Thailand  Vietnam 
##       72       72       72       72       72
  • Kết quả trả về cho biết rằng có 72 quan sát từ China, 72 từ Japan, 72 từ Spain, 72 từ Thailand và 72 từ Vietnam trong đối tượng dữ liệu p1.

1.5 Mã hóa dữ liệu về dân số của Vietnam:

  • Tiến hành phân tích về dân số của Vietnam

  • Tạo một biến mới trong đối tượng dữ liệu p1 gọi là cn.Coded. Để biết được giá trị dữ liệu nào là của Vietnam. Giá trị của biến này sẽ được xác định bởi câu lệnh điều kiện sau:

p1$cn.Coded <- ifelse(p1$cn == 'Vietnam','Vietnam','other country')

datatable(p1)
  • Trước hết là phân tích về dân số ở độ tuổi từ 30 đến 39 của Vietnam
p2 <- filter(p1, cn == 'Vietnam') %>% select (cn, p30to39)

datatable(p2)
  • Tiến hành phân tích mật độ dân số của Vietnam qua các năm và cho nó ra một cột mới có tên là p30to39.Coded2
p2$p30to39.Coded2 <- case_when(p2$p30to39 < 4000000 ~ 'mật độ dân số thấp', p2$p30to39 >= 4000000 & p2$p30to39 <= 10000000 ~ 'mật độ dân số trung bình', p2$p30to39 > 10000000 ~ 'mật độ dân số đông')

datatable(p2)
  • Qua bảng trên ta có thể thấy được: Tốc độ gia tăng dân số ở độ tuổi từ 30 đến 39 của Vietnam, tăng đều theo từng năm

1.6 Phân tích dữ liệu theo quốc gia và theo thời gian:

1.6.1 Các đặc trưng đo lường theo quốc gia (ở đây phân tích Vietnam):

  • Tiến hành tạo một bảng thống kê tóm tắt về dân số ở độ tuổi từ 30 đến 39 của Vietnam.
filter(p1, cn == 'Vietnam') %>%
  select(cn, p30to39) %>% 
  summary(p1$p30to39)
##       cn               p30to39        
##  Length:72          Min.   : 3480061  
##  Class :character   1st Qu.: 4313676  
##  Mode  :character   Median : 7073500  
##                     Mean   : 8300103  
##                     3rd Qu.:11843949  
##                     Max.   :15962702
  • Kết quả trả về cho thấy:

    • Min: cho thấy giá trị thấp nhất trong cột p30to39 của Việt Nam, là 3480061

    • 1st Qu. (tứ phân vị thứ nhất): Giá trị này đại diện cho giá trị mà 25% các điểm dữ liệu trong cột p30to39 nằm dưới, cho thấy 25% dân số Việt Nam thuộc nhóm tuổi 30-39 có giá trị thấp hơn 4313676

    • Median: Đây là giá trị trung bình của cột p30to39, cho thấy một nửa dân số Việt Nam thuộc nhóm tuổi 30-39 có giá trị thấp hơn và một nửa có giá trị cao hơn 7073500

    • Mean: Đây là giá trị trung bình của cột p30to39, trong trường hợp này là 8300103

    • 3rd Qu. (tứ phân vị thứ ba): Giá trị này đại diện cho giá trị mà 75% các điểm dữ liệu trong cột p30to39 nằm dưới, cho thấy 75% dân số Việt Nam thuộc nhóm tuổi 30-39 có giá trị thấp hơn 11843949

    • Max (tối đa): Giá trị này cho thấy giá trị cao nhất trong cột p30to39 cho Việt Nam, là 15962702

  • Tạo một bản sao của dữ liệu p1 và gán nó vào một biến mới có tên p3. Ở dữ liệu p3 này, chỉ có số liệu dân số ở độ tuổi dưới 25 của Vietnam.

p3 <- filter(p1, cn == 'Vietnam') %>% select (cn, pu25)

datatable(p3)
  • Tổng dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:
sum(p3$pu25) 
## [1] 2235306052
  • Trung bình dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:
mean(p3$pu25, rm.na = T)
## [1] 31045917
  • Xử lý giá trị thiếu bằng câu lệnh: rm.na = T: Tùy chọn này được truyền cho hàm mean để chỉ định rằng bất kỳ giá trị thiếu nào (được biểu thị là NA) nên được loại bỏ trước khi tính trung bình. Điều này đảm bảo rằng chỉ các điểm dữ liệu hợp lệ được sử dụng trong tính toán.

  • Độ dài của cột số liệu dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:

length(p3$pu25)
## [1] 72
  • Kết quả trả về là 72 tương ứng với 72 năm phân tích về dân số của Vietnam.

  • Phương sai về dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:

var(p3$pu25)
## [1] 8.330077e+13
  • Độ lệch chuẩn về dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:
sd(p3$pu25) 
## [1] 9126926
  • Trung vị về dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:
median(p3$pu25)
## [1] 35466660
  • Kết quả trả về cho thấy một nửa dân số Việt Nam thuộc nhóm tuổi dưới 25 có giá trị thấp hơn và một nửa có giá trị cao hơn 35466660

  • Tứ phân vị về dân số của Vietnam ở độ tuổi dưới 25 trong 72 năm:

quantile(p3$pu25, probs = c(.25,.5,.75))
##      25%      50%      75% 
## 23610692 35466660 38246840
  • Kết quả trả về cho thấy:

    • 1st Qu. (tứ phân vị thứ nhất): Giá trị này đại diện cho giá trị mà 25% các điểm dữ liệu trong cột pu25 nằm dưới, cho thấy 25% dân số Việt Nam thuộc nhóm tuổi dưới 25 có giá trị thấp hơn 23610692

    • Median: Đây là giá trị trung bình của cột pu25, cho thấy một nửa dân số Việt Nam thuộc nhóm tuổi dưới 25 có giá trị thấp hơn và một nửa có giá trị cao hơn 35466660

    • 3rd Qu. (tứ phân vị thứ ba): Giá trị này đại diện cho giá trị mà 75% các điểm dữ liệu trong cột pu25 nằm dưới, cho thấy 75% dân số Việt Nam thuộc nhóm tuổi dưới 25 có giá trị thấp hơn 38246840

1.6.2 Đặc trưng đo lường theo nhóm quốc gia (5 quốc gia đang phân tích):

  • Tiếp theo ta tiến hành phân tích dữ liệu về tổng dân số của 5 quốc gia sau đó tính giá trị trung bình về tổng dân số của 5 quốc gia đó.
VNTL <- p1 %>% 
  filter(cn == 'China' | cn == 'Japan' | cn == 'Spain' | cn == 'Thailand' | cn == 'Vietnam') %>%
  group_by(cn, p) %>%
  summarise(mean_of_p = mean(p), .groups = 'drop')

datatable(VNTL)
mean(VNTL$mean_of_p)
## [1] 259598624

1.6.3 Đặc trưng đo lường theo năm:

  • Trung bình dân số độ tuổi từ 70 đến 79 của 5 quốc gia trong năm 2020
t1 <- p1 %>% 
  filter(y == '2020') %>%
  group_by(cn, y, p70to79) %>% 
  summarise(mean_of_p70to79 = mean(p70to79), .groups = 'drop')

datatable(t1)
mean(t1$mean_of_p70to79)
## [1] 20633026

1.6.4 Đặc trưng đo lường theo khoảng thời gian:

  • Trung bình dân số trẻ em dưới 15 tuổi của 5 quốc gia ở năm 1970 và năm 1990:
nam <- p1 %>% 
  filter(y == '1970' | y == '1990') %>%
  group_by(cn, y, pcu15) %>%
  summarise(mean_of_pcu15 = mean(pcu15), .groups = 'drop')

datatable(nam)
mean(nam$mean_of_pcu15)
## [1] 80977349

2 Nhiệm vụ 3.2:

2.1 Mục tiêu nghiên cứu:

  • Nắm bắt sự thay đổi về GDP của China, France, Italy, Mexico trong 57 năm từ năm 1960 đến năm 2016

  • Nắm bắt sự thay đổi về GDP của China thông qua các đặc trưng đo lường

  • Biết được trung bình về GDP trong 57 năm của 4 quốc gia

  • Biết được các giá trị trung bình về GDP của 4 quốc gia trong năm 1980

  • Biết được các giá trị trung bình về GDP của 4 quốc gia ở năm 2010 và năm 2012

2.2 Phương pháp nghiên cứu

  • Sử dụng các phương pháp:

    • Mã hóa dữ liệu

    • Tạo bảng tần số

    • Tính toán các đặc trưng đo lường

2.3 Giải thích bộ dữ liệu:

Dữ liệu trong file gdp4country.xlsx nói về GDP của 4 quốc gia được phân tích trong 57 năm từ năm 1960 đến năm 2016

Có 228 hàng tương ứng với 228 quan sát

Có 4 cột tương ứng với 4 biến

  • Country name: Tên Quốc Gia

  • Country Code: Mã quốc gia

  • Year: Năm lấy số liệu

  • Value: Giá trị GDP

2.4 Phân tích dữ liệu về GDP của China, France, Italy, Mexico trong 57 năm:

  • Tạo một bản sao của file dữ liệu gdp4country.xlsx và gán nó vào một biến mới có tên gdp. Điều này giúp bạn giữ nguyên dữ liệu gốc trong khi thực hiện các thao tác trên bản sao.
library(xlsx)
gdp <- read.xlsx(file.choose(), sheetIndex = 1, header = T) 

datatable(gdp) 
  • Qua bảng trên ta có thể thấy được, GDP của 4 nước trên hầu như tăng dần qua từng năm (nhưng cũng có 1 vài năm GDP giảm)

  • Tiến hành in ra một bảng tần suất dựa trên các giá trị của biến Country.Name trong đối tượng dữ liệu gdp.

table(gdp$Country.Name)
## 
##  China France  Italy Mexico 
##     57     57     57     57
  • Kết quả trả về cho biết rằng có 57 quan sát từ China, 57 từ France, 57 từ Italy và 57 từ Mexico tương ứng với 57 năm phân tích về gdp.

2.5 Mã hóa dữ liệu về dân số của China:

  • Tiến hành phân tích về GDP của China

  • Tạo một biến mới trong đối tượng dữ liệu gdp gọi là China.Coded. Để biết được giá trị dữ liệu nào là của China. Giá trị của biến này sẽ được xác định bởi câu lệnh điều kiện sau:

gdp$China.Coded <- ifelse(gdp$Country.Name == 'China','China','other country')

datatable(gdp)
  • Trước hết là phân tích về GDP của China
library(dplyr)

gdp.China <- filter(gdp, Country.Name == 'China') %>% select (Country.Name, Value)

datatable(gdp.China)
  • Tiến hành phân tích GDP của China qua các năm và cho nó ra một cột mới có tên là Value.China
gdp.China$Value.China <- case_when(gdp.China$Value < 200000000000 ~ 'chỉ số gdp ở mức thấp', gdp.China$Value >= 200000000000 & gdp.China$Value <= 1000000000000 ~ 'chỉ số gdp ở mức trung bình', gdp.China$Value > 1000000000000 ~ 'chỉ số gdp ở mức cao')

datatable(gdp.China)
  • Qua bảng trên ta có thể thấy được: Tốc độ gia GDP của China, tăng đều theo từng năm (nhưng cũng có 1 vài năm GDP giảm)

2.6 Phân tích dữ liệu theo quốc gia và theo thời gian:

2.6.1 Các đặc trưng đo lường theo quốc gia (ở đây phân tích China):

  • Tiến hành tạo một bảng thống kê tóm tắt về GDP của China
filter(gdp, Country.Name == 'China') %>%
  select(Country.Name, Value) %>% 
  summary(gdp$Value)
##  Country.Name           Value          
##  Length:57          Min.   :4.721e+10  
##  Class :character   1st Qu.:1.442e+11  
##  Mode  :character   Median :3.124e+11  
##                     Mean   :1.791e+12  
##                     3rd Qu.:1.471e+12  
##                     Max.   :1.120e+13
  • Kết quả trả về cho thấy:

    • Min: cho thấy giá trị thấp nhất về GDP của China, là 4.721e+10

    • 1st Qu. (tứ phân vị thứ nhất): cho thấy 25% GDP của China có giá trị thấp hơn 1.442e+11

    • Median: cho thấy một nửa GDP của China có giá trị thấp hơn và một nửa có giá trị cao hơn 3.124e+11

    • Mean: Đây là giá trị trung bình về GDP của China là 1.791e+12

    • 3rd Qu. (tứ phân vị thứ ba): cho thấy 75% GDP của China có giá trị thấp hơn 1.471e+12

    • Max (tối đa): Giá trị này cho thấy giá trị cao nhất về GDP của China, là 1.120e+13

  • Từ dữ liệu gdp.China đã được tạo ở trên, ta tiến hành tính các đặc trưng đo lường về GDP của China

  • Tổng GDP của China từ năm 1960 đến năm 2016:

sum(gdp.China$Value) 
## [1] 1.020587e+14
  • Độ dài GDP của China từ năm 1960 đến năm 2016:
length(gdp.China$Value)
## [1] 57
  • Kết quả trả về là 57 tương ứng với 57 năm phân tích về GDP của China.

  • Phương sai về GDP của China từ năm 1960 đến năm 2016:

var(gdp.China$Value)
## [1] 9.396759e+24
  • Độ lệch chuẩn về GDP của China từ năm 1960 đến năm 2016:
sd(gdp.China$Value) 
## [1] 3.065413e+12

2.6.2 Đặc trưng đo lường theo nhóm quốc gia (4 quốc gia đang phân tích):

  • Giá trị trung bình về GDP của 4 quốc gia từ năm 1960 đến năm 2016:
tb.gdp <- gdp %>% 
  group_by(Country.Name, Value) %>% 
  summarise(mean_of_Value = mean(Value), .groups = 'drop')

datatable(tb.gdp)
mean(tb.gdp$mean_of_Value)
## [1] 1.072052e+12

2.6.3 Đặc trưng đo lường theo năm:

  • Trung bình GDP của 4 quốc gia ở năm 1980
tb.y <- gdp %>% 
  filter(Year == '1980') %>%
  group_by(Country.Name, Year, Value) %>% 
  summarise(mean_of_Value = mean(Value), .groups = 'drop')

datatable(tb.y)
mean(tb.y$mean_of_Value)
## [1] 391178461702

2.6.4 Đặc trưng đo lường theo khoảng thời gian:

  • Trung bình GDP của 4 quốc gia ở năm 2010 và năm 2012
tb.2y <- gdp %>% 
  filter(Year == '2010' | Year == '2012') %>%
  group_by(Country.Name, Year, Value) %>%
  summarise(mean_of_Value = mean(Value), .groups = 'drop')

datatable(tb.2y)
mean(tb.2y$mean_of_Value)
## [1] 3.303129e+12
LS0tDQp0aXRsZTogIk5oaeG7h20gduG7pSAzIg0KYXV0aG9yOiAiVsawxqFuZyBOaMawIFRo4buneSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6ICJkZWZhdWx0Ig0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvYzogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogJzInDQogIHBkZl9kb2N1bWVudDogDQogICAgbGF0ZXhfZW5naW5lOiB4ZWxhdGV4DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpsaWJyYXJ5KGZsZXh0YWJsZSkNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KGRwbHlyKQ0KYGBgDQoNCiMgTmhp4buHbSB24bulIDMuMTogDQoNCiMjIE3hu6VjIHRpw6p1IG5naGnDqm4gY+G7qXU6DQoNCi0gTuG6r20gYuG6r3Qgc+G7sSB0aGF5IMSR4buVaSB24buBIGTDom4gc+G7kSBj4bunYSBDaGluYSwgSmFwYW4sIFNwYWluLCBUaGFpbGFuZCwgVmlldG5hbSB0cm9uZyA3MiBuxINtDQoNCi0gTuG6r20gYuG6r3Qgc+G7sSB0aGF5IMSR4buVaSB24buBIGTDom4gc+G7kSBWaWV0bmFtIHRow7RuZyBxdWEgY8OhYyDEkeG6t2MgdHLGsG5nIMSRbyBsxrDhu51uZyANCiAgDQotIEJp4bq/dCDEkcaw4bujYyB0cnVuZyBiw6xuaCB24buBIGTDom4gc+G7kSB0cm9uZyA3MiBuxINtIGPhu6dhIDUgcXXhu5FjIGdpYSANCg0KLSBCaeG6v3QgxJHGsOG7o2MgY8OhYyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGTDom4gc+G7kSDEkeG7mSB0deG7lWkgdOG7qyA3MCDEkeG6v24gNzkgY+G7p2EgNSBxdeG7kWMgZ2lhIHRyb25nIG7Eg20gMjAyMA0KDQotIEJp4bq/dCDEkcaw4bujYyBjw6FjIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggduG7gSBkw6JuIHPhu5EgdHLhursgZW0gZMaw4bubaSAxNSB0deG7lWkgY+G7p2EgNSBxdeG7kWMgZ2lhIOG7nyBuxINtIDE5NzAgdsOgIG7Eg20gMTk5MA0KDQojIyBQaMawxqFuZyBwaMOhcCBuZ2hpw6puIGPhu6l1DQoNCi0gU+G7rSBk4bulbmcgY8OhYyBwaMawxqFuZyBwaMOhcDoNCg0KICAtIE3DoyBow7NhIGThu68gbGnhu4d1DQogIA0KICAtIFThuqFvIGLhuqNuZyB04bqnbiBz4buRDQogIA0KICAtIFTDrW5oIHRvw6FuIGPDoWMgxJHhurdjIHRyxrBuZyDEkW8gbMaw4budbmcgDQoNCiMjIEdp4bqjaSB0aMOtY2ggYuG7mSBk4buvIGxp4buHdTogDQoNCkThu68gbGnhu4d1IHRyb25nIGZpbGUgKipwb3B1bGF0aW9uLWFuZC1kZW1vZ3JhcGh5LmNzdioqIG7Ds2kgduG7gSAqKkTDom4gc+G7kSB2w6AgTmjDom4ga2jhuql1IGjhu41jKiogY+G7p2EgMjU0IHF14buRYyBnaWEgxJHGsOG7o2MgcGjDom4gdMOtY2ggdHJvbmcgNzIgbsSDbSB04burIG7Eg20gMTk1MCDEkeG6v24gbsSDbSAyMDIxIA0KDQpDw7MgMTgyODggaMOgbmcgdMawxqFuZyDhu6luZyB24bubaSAxODI4OCBxdWFuIHPDoXQgDQoNCkPDsyAyNCBj4buZdCB0xrDGoW5nIOG7qW5nICB24bubaSAyNCBiaeG6v24NCg0KLSBDb3VudHJ5IG5hbWU6IFTDqm4gUXXhu5FjIEdpYQ0KDQotIFllYXI6IE7Eg20gbOG6pXkgc+G7kSBsaeG7h3UgDQoNCi0gUG9wdWxhdGlvbjogRMOibiBz4buRDQoNCi0gUG9wdWxhdGlvbiBvZiBjaGlsZHJlbiB1bmRlciB0aGUgYWdlIG9mIDE6IETDom4gc+G7kSB0cuG6uyBlbSBkxrDhu5tpIDEgdHXhu5VpDQoNCi0gUG9wdWxhdGlvbiBvZiBjaGlsZHJlbiB1bmRlciB0aGUgYWdlIG9mIDU6IETDom4gc+G7kSB0cuG6uyBlbSBkxrDhu5tpIDUgdHXhu5VpDQoNCi0gUG9wdWxhdGlvbiBvZiBjaGlsZHJlbiB1bmRlciB0aGUgYWdlIG9mIDE1OiBEw6JuIHPhu5EgdHLhursgZW0gZMaw4bubaSAxNSB0deG7lWkgDQoNCi0gUG9wdWxhdGlvbiB1bmRlciB0aGUgYWdlIG9mIDI1OiBEw6JuIHPhu5EgZMaw4bubaSAyNSB0deG7lWkJDQoNCi0gUG9wdWxhdGlvbiBhZ2VkIDE1IHRvIDY0IHllYXJzOiBEw6JuIHPhu5EgdOG7qyAxNSDEkeG6v24gNjQgdHXhu5VpDQoNCi0gUG9wdWxhdGlvbiBvbGRlciB0aGFuIDE1IHllYXJzOiBEw6JuIHPhu5EgbOG7m24gaMahbiAxNSB0deG7lWkgCQ0KDQotIFBvcHVsYXRpb24gb2xkZXIgdGhhbiAxOCB5ZWFyczogRMOibiBz4buRIGzhu5tuIGjGoW4gMTggdHXhu5VpIA0KDQotIFBvcHVsYXRpb24gYXQgYWdlIDE6IETDom4gc+G7kSAxIHR14buVaSANCg0KLSBQb3B1bGF0aW9uIGFnZWQgMSB0byA0IHllYXJzOiBEw6JuIHPhu5EgdOG7qyAxIMSR4bq/biA0IHR14buVaSAJDQoNCi0gUG9wdWxhdGlvbiBhZ2VkIDUgdG8gOSB5ZWFyczogRMOibiBz4buRIHThu6sgNSDEkeG6v24gOSB0deG7lWkNCg0KLSBQb3B1bGF0aW9uIGFnZWQgMTAgdG8gMTQgeWVhcnM6IETDom4gc+G7kSB04burIDEwIMSR4bq/biAxNCB0deG7lWkNCg0KLSBQb3B1bGF0aW9uIGFnZWQgMTUgdG8gMTkgeWVhcnM6IETDom4gc+G7kSB04burIDE1IMSR4bq/biAxOSB0deG7lWkgCQ0KDQotIFBvcHVsYXRpb24gYWdlZCAyMCB0byAyOSB5ZWFyczogRMOibiBz4buRIHThu6sgMjAgxJHhur9uIDI5IHR14buVaQ0KDQotIFBvcHVsYXRpb24gYWdlZCAzMCB0byAzOSB5ZWFyczogRMOibiBz4buRIHThu6sgMzAgxJHhur9uIDM5IHR14buVaQkNCg0KLSBQb3B1bGF0aW9uIGFnZWQgNDAgdG8gNDkgeWVhcnM6IETDom4gc+G7kSB04burIDQwIMSR4bq/biA0OSB0deG7lWkJDQoNCi0gUG9wdWxhdGlvbiBhZ2VkIDUwIHRvIDU5IHllYXJzOiBEw6JuIHPhu5EgdOG7qyA1MCDEkeG6v24gNTkgdHXhu5VpDQoNCi0gUG9wdWxhdGlvbiBhZ2VkIDYwIHRvIDY5IHllYXJzOiBEw6JuIHPhu5EgdOG7qyA2MCDEkeG6v24gNjkgdHXhu5VpDQoNCi0gUG9wdWxhdGlvbiBhZ2VkIDcwIHRvIDc5IHllYXJzOiBEw6JuIHPhu5EgdOG7qyA3MCDEkeG6v24gNzkgdHXhu5VpDQoNCi0gUG9wdWxhdGlvbiBhZ2VkIDgwIHRvIDg5IHllYXJzOiBEw6JuIHPhu5EgdOG7qyA4MCDEkeG6v24gODkgdHXhu5VpCQ0KDQotIFBvcHVsYXRpb24gYWdlZCA5MCB0byA5OSB5ZWFyczogRMOibiBz4buRIHThu6sgOTAgxJHhur9uIDk5IHR14buVaQ0KDQotIFBvcHVsYXRpb24gb2xkZXIgdGhhbiAxMDAgeWVhcnM6IETDom4gc+G7kSBs4bubbiBoxqFuIDEwMCB0deG7lWkgDQoNCiMjIFBow6JuIHTDrWNoIGThu68gbGnhu4d1IHbhu4EgZMOibiBz4buRIGPhu6dhIENoaW5hLCBKYXBhbiwgU3BhaW4sIFRoYWlsYW5kLCBWaWV0bmFtIHRyb25nIDcyIG7Eg206DQoNCi0gVOG6oW8gbeG7mXQgYuG6o24gc2FvIGPhu6dhIGZpbGUgZOG7ryBsaeG7h3UgKioqcG9wdWxhdGlvbi1hbmQtZGVtb2dyYXBoeS5jc3YqKiogdsOgIGfDoW4gbsOzIHbDoG8gbeG7mXQgYmnhur9uIG3hu5tpIGPDsyB0w6puIHAuIMSQaeG7gXUgbsOgeSBnacO6cCBi4bqhbiBnaeG7ryBuZ3V5w6puIGThu68gbGnhu4d1IGfhu5FjIHRyb25nIGtoaSB0aOG7sWMgaGnhu4duIGPDoWMgdGhhbyB0w6FjIHRyw6puIGLhuqNuIHNhby4NCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnAgPC0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSwgaGVhZGVyID0gVCkNCg0KZGF0YXRhYmxlKHApDQpgYGAgDQoNCi0gVGjhu7FjIGhp4buHbiDEkeG7lWkgdMOqbiBjw6FjIGJp4bq/biBj4bunYSBk4buvIGxp4buHdSDEkeG7gyBk4buFIGTDoG5nIGfhu41pIHTDqm4gdHJvbmcgY8OhYyB0aGFvIHTDoWMgcGjDom4gdMOtY2ggDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQpuYW1lcyhwKSA8LSBjKCdjbicsJ3knLCdwJywncGN1MScsJ3BjdTUnLCdwY3UxNScsJ3B1MjUnLCdwMTV0bzY0JywncG8xNScsJ3BvMTgnLCdwMScsJ3AxdG80JywncDV0bzknLCdwMTB0bzE0JywncDE1dG8xOScsJ3AyMHRvMjknLCdwMzB0bzM5JywncDQwdG80OScsJ3A1MHRvNTknLCdwNjB0bzY5JywncDcwdG83OScsJ3A4MHRvODknLCdwOTB0OTB0bzk5JywncG8xMDAnKQ0KZGF0YXRhYmxlKHApDQpgYGANCg0KLSBUcm9uZyBSLCDEkeG7kWkgdMaw4bujbmcgZOG7ryBsaeG7h3UgbMOgIG3hu5l0IHThuq1wIGjhu6NwIGPDoWMgYmnhur9uLiBN4buXaSBiaeG6v24gY8OzIG3hu5l0IHTDqm4gZHV5IG5o4bqldC4gQ8OidSBs4buHbmggbsOgeSBz4bq9IHRoYXkgxJHhu5VpIHTDqm4gY+G7p2EgY8OhYyBiaeG6v24gdHJvbmcgxJHhu5FpIHTGsOG7o25nIGThu68gbGnhu4d1IHAgdGjDoG5oIGPDoWMgdMOqbiDEkcaw4bujYyBsaeG7h3Qga8OqIHRyb25nIHZlY3RvciBjKCdjbicsJ3knLCdwJywncGN1MScsJ3BjdTUnLCdwY3UxNScsJ3B1MjUnLCdwMTV0bzY0JywncG8xNScsJ3BvMTgnLCdwMScsJ3AxdG80JywncDV0bzknLCdwMTB0bzE0JywncDE1dG8xOScsJ3AyMHRvMjknLCdwMzB0bzM5JywncDQwdG80OScsJ3A1MHRvNTknLCdwNjB0bzY5JywncDcwdG83OScsJ3A4MHRvODknLCdwOTB0OTB0bzk5JywncG8xMDAnKS4NCg0KLSBDaOG6s25nIGjhuqFuLCB0w6puIGThu68gbGnhu4d1IMSRxrDhu6NjIHLDunQgZ+G7jW4gbmjGsCBzYXU6DQogIA0KICAtICoqKkNvdW50cnkgbmFtZSoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqY24qKio6IFTDqm4gUXXhu5FjIEdpYQ0KDQogIC0gKioqWWVhcioqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqeSoqKjogTsSDbSBs4bqleSBz4buRIGxp4buHdSANCg0KICAtICoqKlBvcHVsYXRpb24qKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnAqKio6IETDom4gc+G7kQ0KDQogIC0gKioqUG9wdWxhdGlvbiBvZiBjaGlsZHJlbiB1bmRlciB0aGUgYWdlIG9mIDEqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnBjdTEqKio6IETDom4gc+G7kSB0cuG6uyBlbSBkxrDhu5tpIDEgdHXhu5VpDQoNCiAgLSAqKipQb3B1bGF0aW9uIG9mIGNoaWxkcmVuIHVuZGVyIHRoZSBhZ2Ugb2YgNSoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcGN1NSoqKjogRMOibiBz4buRIHRy4bq7IGVtIGTGsOG7m2kgNSB0deG7lWkNCg0KICAtICoqKlBvcHVsYXRpb24gb2YgY2hpbGRyZW4gdW5kZXIgdGhlIGFnZSBvZiAxNSoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcGN1MTUqKio6IETDom4gc+G7kSB0cuG6uyBlbSBkxrDhu5tpIDE1IHR14buVaSANCg0KICAtICoqKlBvcHVsYXRpb24gdW5kZXIgdGhlIGFnZSBvZiAyNSoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcHUyNSoqKjogRMOibiBz4buRIGTGsOG7m2kgMjUgdHXhu5VpCQ0KDQogIC0gKioqUG9wdWxhdGlvbiBhZ2VkIDE1IHRvIDY0IHllYXJzKioqIMSRxrDhu6NjIMSR4buVaSB0w6puIHRow6BuaCAqKipwMTV0bzY0KioqOiBEw6JuIHPhu5EgdOG7qyAxNSDEkeG6v24gNjQgdHXhu5VpDQoNCiAgLSAqKipQb3B1bGF0aW9uIG9sZGVyIHRoYW4gMTUgeWVhcnMqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnBvMTUqKio6IETDom4gc+G7kSBs4bubbiBoxqFuIDE1IHR14buVaSAJDQoNCiAgLSAqKipQb3B1bGF0aW9uIG9sZGVyIHRoYW4gMTggeWVhcnMqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnBvMTgqKio6IETDom4gc+G7kSBs4bubbiBoxqFuIDE4IHR14buVaSANCg0KICAtICoqKlBvcHVsYXRpb24gYXQgYWdlIDEqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnAxKioqOiBEw6JuIHPhu5EgMSB0deG7lWkgDQoNCiAgLSAqKipQb3B1bGF0aW9uIGFnZWQgMSB0byA0IHllYXJzKioqIMSRxrDhu6NjIMSR4buVaSB0w6puIHRow6BuaCAqKipwMXRvNCoqKjogRMOibiBz4buRIHThu6sgMSDEkeG6v24gNCB0deG7lWkgCQ0KDQogIC0gKioqUG9wdWxhdGlvbiBhZ2VkIDUgdG8gOSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDV0bzkqKio6IETDom4gc+G7kSB04burIDUgxJHhur9uIDkgdHXhu5VpDQoNCiAgLSAqKipQb3B1bGF0aW9uIGFnZWQgMTAgdG8gMTQgeWVhcnMqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnAxMHRvMTQqKio6IETDom4gc+G7kSB04burIDEwIMSR4bq/biAxNCB0deG7lWkNCg0KICAtICoqKlBvcHVsYXRpb24gYWdlZCAxNSB0byAxOSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDE1dG8xOSoqKjogRMOibiBz4buRIHThu6sgMTUgxJHhur9uIDE5IHR14buVaSAJDQoNCiAgLSAqKipQb3B1bGF0aW9uIGFnZWQgMjAgdG8gMjkgeWVhcnMqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnAyMHRvMjkqKio6IETDom4gc+G7kSB04burIDIwIMSR4bq/biAyOSB0deG7lWkNCg0KICAtICoqKlBvcHVsYXRpb24gYWdlZCAzMCB0byAzOSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDMwdG8zOSoqKjogRMOibiBz4buRIHThu6sgMzAgxJHhur9uIDM5IHR14buVaQkNCg0KICAtICoqKlBvcHVsYXRpb24gYWdlZCA0MCB0byA0OSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDQwdG80OSoqKjogRMOibiBz4buRIHThu6sgNDAgxJHhur9uIDQ5IHR14buVaQkNCg0KICAtICoqKlBvcHVsYXRpb24gYWdlZCA1MCB0byA1OSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDUwdG81OSoqKjogRMOibiBz4buRIHThu6sgNTAgxJHhur9uIDU5IHR14buVaQ0KDQogIC0gKioqUG9wdWxhdGlvbiBhZ2VkIDYwIHRvIDY5IHllYXJzKioqIMSRxrDhu6NjIMSR4buVaSB0w6puIHRow6BuaCAqKipwNjB0bzY5KioqOiBEw6JuIHPhu5EgdOG7qyA2MCDEkeG6v24gNjkgdHXhu5VpDQoNCiAgLSAqKipQb3B1bGF0aW9uIGFnZWQgNzAgdG8gNzkgeWVhcnMqKiogxJHGsOG7o2MgxJHhu5VpIHTDqm4gdGjDoG5oICoqKnA3MHRvNzkqKio6IETDom4gc+G7kSB04burIDcwIMSR4bq/biA3OSB0deG7lWkNCg0KICAtICoqKlBvcHVsYXRpb24gYWdlZCA4MCB0byA4OSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDgwdG84OSoqKjogRMOibiBz4buRIHThu6sgODAgxJHhur9uIDg5IHR14buVaQkNCg0KICAtICoqKlBvcHVsYXRpb24gYWdlZCA5MCB0byA5OSB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcDkwdG85OSoqKjogRMOibiBz4buRIHThu6sgOTAgxJHhur9uIDk5IHR14buVaQ0KDQogIC0gKioqUG9wdWxhdGlvbiBvbGRlciB0aGFuIDEwMCB5ZWFycyoqKiDEkcaw4bujYyDEkeG7lWkgdMOqbiB0aMOgbmggKioqcG8xMDAqKio6IETDom4gc+G7kSBs4bubbiBoxqFuIDEwMCB0deG7lWkgDQoNCi0gVGjhu7FjIGhp4buHbiBs4buNYyA1IHF14buRYyBnaWEgY+G6p24gcGjDom4gdMOtY2gsIOG7nyDEkcOieSBwaMOibiB0w61jaCAiQ2hpbmEsIEphcGFuLCBTcGFpbiwgVGhhaWxhbmQsIFZpZXRuYW0iDQoNCi0gQ2jhu41uIDUgY+G7mXQgc+G7kSBsaeG7h3UgduG7gSBjw6FjIMSR4buZIHR14buVaSBj4bunYSBkw6JuIHPhu5EgdHJvbmcgY8OhYyBuxINtLCDhu58gxJHDonkgcGjDom4gdMOtY2ggdOG7lW5nIGTDom4gc+G7kSBj4bunYSA1IHF14buRYyBnaWEgKHApLCBkw6JuIHPhu5EgdHLhursgZW0gZMaw4bubaSAxNSB0deG7lWkgKHBjdTE1KSwgZMOibiBz4buRIGTGsOG7m2kgMjUgdHXhu5VpIChwdTI1KSwgZMOibiBz4buRIHThu6sgMzAgxJHhur9uIDM5IHR14buVaSAocDMwdG8zOSksIGTDom4gc+G7kSB04burIDcwIMSR4bq/biA3OSB0deG7lWkgKHA3MHRvNzkpDQoNCi0gWMOzYSBi4buPIGPDoWMgY+G7mXQgdGjhu6thIGNo4buJIGdp4buvIGzhuqFpIDcgY+G7mXQgY+G6p24gbOG6pXkgZOG7ryBsaeG7h3UgxJHhu4MgcGjDom4gdMOtY2ggdsOgIGfDoW4gY2hvIGThu68gbGnhu4d1IG3hu5tpIG3hu5l0IG9iamVjdCBwMQ0KDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQpwMSA8LSBmaWx0ZXIocCwgY24gPT0gJ0NoaW5hJyB8IGNuID09ICdKYXBhbicgfCBjbiA9PSAnU3BhaW4nIHwgY24gPT0gJ1RoYWlsYW5kJyB8IGNuID09ICdWaWV0bmFtJykgJT4lIHNlbGVjdCgtYygncGN1MScsJ3BjdTUnLCdwMTV0bzY0JywncG8xNScsJ3BvMTgnLCdwMScsJ3AxdG80JywncDV0bzknLCdwMTB0bzE0JywncDE1dG8xOScsJ3AyMHRvMjknLCdwNDB0bzQ5JywncDUwdG81OScsJ3A2MHRvNjknLCdwODB0bzg5JywncDkwdDkwdG85OScsJ3BvMTAwJykpDQoNCmRhdGF0YWJsZShwMSkNCmBgYA0KLSBRdWEgYuG6o25nIHRyw6puIHRhIGPDsyB0aOG7gyB0aOG6pXkgxJHGsOG7o2MsIGTDom4gc+G7kSBj4bunYSA1IG7GsOG7m2MgdHLDqm4gaOG6p3UgbmjGsCB0xINuZyBk4bqnbiBxdWEgdOG7q25nIG7Eg20gDQoNCi0gVGnhur9uIGjDoG5oIGluIHJhIG3hu5l0IGLhuqNuZyB04bqnbiBzdeG6pXQgZOG7sWEgdHLDqm4gY8OhYyBnacOhIHRy4buLIGPhu6dhIGJp4bq/biBjbiB0cm9uZyDEkeG7kWkgdMaw4bujbmcgZOG7ryBsaeG7h3UgcDEuDQoNCi0gQuG6o25nIHThuqduIHN14bqldCBsw6AgbeG7mXQgY8OhY2ggxJHhu4MgaGnhu4NuIHRo4buLIGThu68gbGnhu4d1IHRoZW8gY8OhY2ggY2hvIHRo4bqleSBz4buRIGzhuqduIG3hu5dpIGdpw6EgdHLhu4sgeHXhuqV0IGhp4buHbi4gVHJvbmcgdHLGsOG7nW5nIGjhu6NwIG7DoHksIGLhuqNuZyB04bqnbiBzdeG6pXQgc+G6vSBjaG8gYmnhur90IGPDsyBiYW8gbmhpw6p1IHF1YW4gc8OhdCBjaG8gbeG7l2kgZ2nDoSB0cuG7iyBkdXkgbmjhuqV0IGPDsyB0cm9uZyBiaeG6v24gY24gY+G7p2EgcDEuIMSQaeG7gXUgbsOgeSBz4bq9IGN1bmcgY+G6pXAgY2hvIGLhuqFuIHThu5VuZyBxdWFuIHbhu4Egc+G7kSBsxrDhu6NuZyBxdWFuIHPDoXQgdGh14buZYyBt4buXaSBkYW5oIG3hu6VjIHF14buRYyBnaWEuDQoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnRhYmxlKHAxJGNuKQ0KYGBgDQoNCi0gS+G6v3QgcXXhuqMgdHLhuqMgduG7gSBjaG8gYmnhur90IHLhurFuZyBjw7MgNzIgcXVhbiBzw6F0IHThu6sgQ2hpbmEsIDcyIHThu6sgSmFwYW4sIDcyIHThu6sgU3BhaW4sIDcyIHThu6sgVGhhaWxhbmQgdsOgIDcyIHThu6sgVmlldG5hbSB0cm9uZyDEkeG7kWkgdMaw4bujbmcgZOG7ryBsaeG7h3UgcDEuDQoNCiMjIE3DoyBow7NhIGThu68gbGnhu4d1IHbhu4EgZMOibiBz4buRIGPhu6dhIFZpZXRuYW06IA0KDQotIFRp4bq/biBow6BuaCBwaMOibiB0w61jaCB24buBIGTDom4gc+G7kSBj4bunYSBWaWV0bmFtIA0KDQotIFThuqFvIG3hu5l0IGJp4bq/biBt4bubaSB0cm9uZyDEkeG7kWkgdMaw4bujbmcgZOG7ryBsaeG7h3UgcDEgZ+G7jWkgbMOgIGNuLkNvZGVkLiDEkOG7gyBiaeG6v3QgxJHGsOG7o2MgZ2nDoSB0cuG7iyBk4buvIGxp4buHdSBuw6BvIGzDoCBj4bunYSBWaWV0bmFtLiAgR2nDoSB0cuG7iyBj4bunYSBiaeG6v24gbsOgeSBz4bq9IMSRxrDhu6NjIHjDoWMgxJHhu4tuaCBi4bufaSBjw6J1IGzhu4duaCDEkWnhu4F1IGtp4buHbiBzYXU6DQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQpwMSRjbi5Db2RlZCA8LSBpZmVsc2UocDEkY24gPT0gJ1ZpZXRuYW0nLCdWaWV0bmFtJywnb3RoZXIgY291bnRyeScpDQoNCmRhdGF0YWJsZShwMSkNCmBgYA0KDQotIFRyxrDhu5tjIGjhur90IGzDoCBwaMOibiB0w61jaCB24buBIGTDom4gc+G7kSDhu58gxJHhu5kgdHXhu5VpIHThu6sgMzAgxJHhur9uIDM5IGPhu6dhIFZpZXRuYW0gDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQpwMiA8LSBmaWx0ZXIocDEsIGNuID09ICdWaWV0bmFtJykgJT4lIHNlbGVjdCAoY24sIHAzMHRvMzkpDQoNCmRhdGF0YWJsZShwMikNCmBgYA0KDQotIFRp4bq/biBow6BuaCBwaMOibiB0w61jaCBt4bqtdCDEkeG7mSBkw6JuIHPhu5EgY+G7p2EgVmlldG5hbSBxdWEgY8OhYyBuxINtIHbDoCBjaG8gbsOzIHJhIG3hu5l0IGPhu5l0IG3hu5tpIGPDsyB0w6puIGzDoCBwMzB0bzM5LkNvZGVkMg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KcDIkcDMwdG8zOS5Db2RlZDIgPC0gY2FzZV93aGVuKHAyJHAzMHRvMzkgPCA0MDAwMDAwIH4gJ23huq10IMSR4buZIGTDom4gc+G7kSB0aOG6pXAnLCBwMiRwMzB0bzM5ID49IDQwMDAwMDAgJiBwMiRwMzB0bzM5IDw9IDEwMDAwMDAwIH4gJ23huq10IMSR4buZIGTDom4gc+G7kSB0cnVuZyBiw6xuaCcsIHAyJHAzMHRvMzkgPiAxMDAwMDAwMCB+ICdt4bqtdCDEkeG7mSBkw6JuIHPhu5EgxJHDtG5nJykNCg0KZGF0YXRhYmxlKHAyKQ0KYGBgDQotIFF1YSBi4bqjbmcgdHLDqm4gdGEgY8OzIHRo4buDIHRo4bqleSDEkcaw4bujYzogVOG7kWMgxJHhu5kgZ2lhIHTEg25nIGTDom4gc+G7kSDhu58gxJHhu5kgdHXhu5VpIHThu6sgMzAgxJHhur9uIDM5IGPhu6dhIFZpZXRuYW0sIHTEg25nIMSR4buBdSB0aGVvIHThu6tuZyBuxINtIA0KICANCiMjIFBow6JuIHTDrWNoIGThu68gbGnhu4d1IHRoZW8gcXXhu5FjIGdpYSB2w6AgdGhlbyB0aOG7nWkgZ2lhbjogDQoNCiMjIyBDw6FjIMSR4bq3YyB0csawbmcgxJFvIGzGsOG7nW5nIHRoZW8gcXXhu5FjIGdpYSAo4bufIMSRw6J5IHBow6JuIHTDrWNoIFZpZXRuYW0pOiANCg0KLSBUaeG6v24gaMOgbmggdOG6oW8gbeG7mXQgYuG6o25nIHRo4buRbmcga8OqIHTDs20gdOG6r3QgduG7gSBkw6JuIHPhu5Eg4bufIMSR4buZIHR14buVaSB04burIDMwIMSR4bq/biAzOSBj4bunYSBWaWV0bmFtLg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KZmlsdGVyKHAxLCBjbiA9PSAnVmlldG5hbScpICU+JQ0KICBzZWxlY3QoY24sIHAzMHRvMzkpICU+JSANCiAgc3VtbWFyeShwMSRwMzB0bzM5KQ0KYGBgDQotIEvhur90IHF14bqjIHRy4bqjIHbhu4EgY2hvIHRo4bqleTogDQogICAgDQogIC0gTWluOiBjaG8gdGjhuqV5IGdpw6EgdHLhu4sgdGjhuqVwIG5o4bqldCB0cm9uZyBj4buZdCBwMzB0bzM5IGPhu6dhIFZp4buHdCBOYW0sIGzDoCAzNDgwMDYxDQogICAgICANCiAgLSAxc3QgUXUuICh04bupIHBow6JuIHbhu4sgdGjhu6kgbmjhuqV0KTogR2nDoSB0cuG7iyBuw6B5IMSR4bqhaSBkaeG7h24gY2hvIGdpw6EgdHLhu4sgbcOgIDI1JSBjw6FjIMSRaeG7g20gZOG7ryBsaeG7h3UgdHJvbmcgY+G7mXQgcDMwdG8zOSBu4bqxbSBkxrDhu5tpLCBjaG8gdGjhuqV5IDI1JSBkw6JuIHPhu5EgVmnhu4d0IE5hbSB0aHXhu5ljIG5ow7NtIHR14buVaSAzMC0zOSBjw7MgZ2nDoSB0cuG7iyB0aOG6pXAgaMahbiA0MzEzNjc2DQogICAgICANCiAgLSBNZWRpYW46IMSQw6J5IGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0IHAzMHRvMzksIGNobyB0aOG6pXkgbeG7mXQgbuG7rWEgZMOibiBz4buRIFZp4buHdCBOYW0gdGh14buZYyBuaMOzbSB0deG7lWkgMzAtMzkgY8OzIGdpw6EgdHLhu4sgdGjhuqVwIGjGoW4gdsOgIG3hu5l0IG7hu61hIGPDsyBnacOhIHRy4buLIGNhbyBoxqFuIDcwNzM1MDANCiAgICAgIA0KICAtIE1lYW46IMSQw6J5IGzDoCBnacOhIHRy4buLIHRydW5nIGLDrG5oIGPhu6dhIGPhu5l0IHAzMHRvMzksIHRyb25nIHRyxrDhu51uZyBo4bujcCBuw6B5IGzDoCA4MzAwMTAzDQogICAgICANCiAgLSAzcmQgUXUuICh04bupIHBow6JuIHbhu4sgdGjhu6kgYmEpOiBHacOhIHRy4buLIG7DoHkgxJHhuqFpIGRp4buHbiBjaG8gZ2nDoSB0cuG7iyBtw6AgNzUlIGPDoWMgxJFp4buDbSBk4buvIGxp4buHdSB0cm9uZyBj4buZdCBwMzB0bzM5IG7hurFtIGTGsOG7m2ksIGNobyB0aOG6pXkgNzUlIGTDom4gc+G7kSBWaeG7h3QgTmFtIHRodeG7mWMgbmjDs20gdHXhu5VpIDMwLTM5IGPDsyBnacOhIHRy4buLIHRo4bqlcCBoxqFuIDExODQzOTQ5DQogICAgICANCiAgLSBNYXggKHThu5FpIMSRYSk6IEdpw6EgdHLhu4sgbsOgeSBjaG8gdGjhuqV5IGdpw6EgdHLhu4sgY2FvIG5o4bqldCB0cm9uZyBj4buZdCBwMzB0bzM5IGNobyBWaeG7h3QgTmFtLCBsw6AgMTU5NjI3MDINCg0KLSBU4bqhbyBt4buZdCBi4bqjbiBzYW8gY+G7p2EgZOG7ryBsaeG7h3UgcDEgdsOgIGfDoW4gbsOzIHbDoG8gbeG7mXQgYmnhur9uIG3hu5tpIGPDsyB0w6puIHAzLiDhu54gZOG7ryBsaeG7h3UgcDMgbsOgeSwgY2jhu4kgY8OzIHPhu5EgbGnhu4d1IGTDom4gc+G7kSDhu58gxJHhu5kgdHXhu5VpIGTGsOG7m2kgMjUgY+G7p2EgVmlldG5hbS4NCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnAzIDwtIGZpbHRlcihwMSwgY24gPT0gJ1ZpZXRuYW0nKSAlPiUgc2VsZWN0IChjbiwgcHUyNSkNCg0KZGF0YXRhYmxlKHAzKQ0KYGBgDQoNCi0gVOG7lW5nIGTDom4gc+G7kSBj4bunYSBWaWV0bmFtIOG7nyDEkeG7mSB0deG7lWkgZMaw4bubaSAyNSB0cm9uZyA3MiBuxINtOg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0Kc3VtKHAzJHB1MjUpIA0KYGBgDQoNCi0gVHJ1bmcgYsOsbmggZMOibiBz4buRIGPhu6dhIFZpZXRuYW0g4bufIMSR4buZIHR14buVaSBkxrDhu5tpIDI1IHRyb25nIDcyIG7Eg206IA0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbWVhbihwMyRwdTI1LCBybS5uYSA9IFQpDQpgYGANCi0gWOG7rSBsw70gZ2nDoSB0cuG7iyB0aGnhur91IGLhurFuZyBjw6J1IGzhu4duaDogcm0ubmEgPSBUOiBUw7l5IGNo4buNbiBuw6B5IMSRxrDhu6NjIHRydXnhu4FuIGNobyBow6BtIG1lYW4gxJHhu4MgY2jhu4kgxJHhu4tuaCBy4bqxbmcgYuG6pXQga+G7syBnacOhIHRy4buLIHRoaeG6v3UgbsOgbyAoxJHGsOG7o2MgYmnhu4N1IHRo4buLIGzDoCBOQSkgbsOqbiDEkcaw4bujYyBsb+G6oWkgYuG7jyB0csaw4bubYyBraGkgdMOtbmggdHJ1bmcgYsOsbmguIMSQaeG7gXUgbsOgeSDEkeG6o20gYuG6o28gcuG6sW5nIGNo4buJIGPDoWMgxJFp4buDbSBk4buvIGxp4buHdSBo4bujcCBs4buHIMSRxrDhu6NjIHPhu60gZOG7pW5nIHRyb25nIHTDrW5oIHRvw6FuLg0KDQotIMSQ4buZIGTDoGkgY+G7p2EgY+G7mXQgc+G7kSBsaeG7h3UgZMOibiBz4buRIGPhu6dhIFZpZXRuYW0g4bufIMSR4buZIHR14buVaSBkxrDhu5tpIDI1IHRyb25nIDcyIG7Eg206DQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQpsZW5ndGgocDMkcHUyNSkNCmBgYCANCi0gS+G6v3QgcXXhuqMgdHLhuqMgduG7gSBsw6AgNzIgdMawxqFuZyDhu6luZyB24bubaSA3MiBuxINtIHBow6JuIHTDrWNoIHbhu4EgZMOibiBz4buRIGPhu6dhIFZpZXRuYW0uIA0KDQotIFBoxrDGoW5nIHNhaSB24buBIGTDom4gc+G7kSBj4bunYSBWaWV0bmFtIOG7nyDEkeG7mSB0deG7lWkgZMaw4bubaSAyNSB0cm9uZyA3MiBuxINtOg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KdmFyKHAzJHB1MjUpDQpgYGANCg0KLSDEkOG7mSBs4buHY2ggY2h14bqpbiB24buBIGTDom4gc+G7kSBj4bunYSBWaWV0bmFtIOG7nyDEkeG7mSB0deG7lWkgZMaw4bubaSAyNSB0cm9uZyA3MiBuxINtOg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0Kc2QocDMkcHUyNSkgDQpgYGANCg0KLSBUcnVuZyB24buLIHbhu4EgZMOibiBz4buRIGPhu6dhIFZpZXRuYW0g4bufIMSR4buZIHR14buVaSBkxrDhu5tpIDI1IHRyb25nIDcyIG7Eg206DQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQptZWRpYW4ocDMkcHUyNSkNCmBgYA0KLSBL4bq/dCBxdeG6oyB0cuG6oyB24buBIGNobyB0aOG6pXkgbeG7mXQgbuG7rWEgZMOibiBz4buRIFZp4buHdCBOYW0gdGh14buZYyBuaMOzbSB0deG7lWkgZMaw4bubaSAyNSBjw7MgZ2nDoSB0cuG7iyB0aOG6pXAgaMahbiB2w6AgbeG7mXQgbuG7rWEgY8OzIGdpw6EgdHLhu4sgY2FvIGjGoW4gMzU0NjY2NjANCg0KDQotIFThu6kgcGjDom4gduG7iyB24buBIGTDom4gc+G7kSBj4bunYSBWaWV0bmFtIOG7nyDEkeG7mSB0deG7lWkgZMaw4bubaSAyNSB0cm9uZyA3MiBuxINtOg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KcXVhbnRpbGUocDMkcHUyNSwgcHJvYnMgPSBjKC4yNSwuNSwuNzUpKQ0KYGBgDQotIEvhur90IHF14bqjIHRy4bqjIHbhu4EgY2hvIHRo4bqleToNCg0KICAtIDFzdCBRdS4gKHThu6kgcGjDom4gduG7iyB0aOG7qSBuaOG6pXQpOiBHacOhIHRy4buLIG7DoHkgxJHhuqFpIGRp4buHbiBjaG8gZ2nDoSB0cuG7iyBtw6AgMjUlIGPDoWMgxJFp4buDbSBk4buvIGxp4buHdSB0cm9uZyBj4buZdCBwdTI1IG7hurFtIGTGsOG7m2ksIGNobyB0aOG6pXkgMjUlIGTDom4gc+G7kSBWaeG7h3QgTmFtIHRodeG7mWMgbmjDs20gdHXhu5VpIGTGsOG7m2kgMjUgY8OzIGdpw6EgdHLhu4sgdGjhuqVwIGjGoW4gMjM2MTA2OTINCiAgICAgIA0KICAtIE1lZGlhbjogxJDDonkgbMOgIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggY+G7p2EgY+G7mXQgcHUyNSwgY2hvIHRo4bqleSBt4buZdCBu4butYSBkw6JuIHPhu5EgVmnhu4d0IE5hbSB0aHXhu5ljIG5ow7NtIHR14buVaSBkxrDhu5tpIDI1IGPDsyBnacOhIHRy4buLIHRo4bqlcCBoxqFuIHbDoCBt4buZdCBu4butYSBjw7MgZ2nDoSB0cuG7iyBjYW8gaMahbiAzNTQ2NjY2MA0KICAgICAgDQogIC0gM3JkIFF1LiAodOG7qSBwaMOibiB24buLIHRo4bupIGJhKTogR2nDoSB0cuG7iyBuw6B5IMSR4bqhaSBkaeG7h24gY2hvIGdpw6EgdHLhu4sgbcOgIDc1JSBjw6FjIMSRaeG7g20gZOG7ryBsaeG7h3UgdHJvbmcgY+G7mXQgcHUyNSBu4bqxbSBkxrDhu5tpLCBjaG8gdGjhuqV5IDc1JSBkw6JuIHPhu5EgVmnhu4d0IE5hbSB0aHXhu5ljIG5ow7NtIHR14buVaSBkxrDhu5tpIDI1IGPDsyBnacOhIHRy4buLIHRo4bqlcCBoxqFuIDM4MjQ2ODQwIA0KICANCg0KIyMjIMSQ4bq3YyB0csawbmcgxJFvIGzGsOG7nW5nIHRoZW8gbmjDs20gcXXhu5FjIGdpYSAoNSBxdeG7kWMgZ2lhIMSRYW5nIHBow6JuIHTDrWNoKToNCg0KLSBUaeG6v3AgdGhlbyB0YSB0aeG6v24gaMOgbmggcGjDom4gdMOtY2ggZOG7ryBsaeG7h3UgduG7gSB04buVbmcgZMOibiBz4buRIGPhu6dhIDUgcXXhu5FjIGdpYSBzYXUgxJHDsyB0w61uaCBnacOhIHRy4buLIHRydW5nIGLDrG5oIHbhu4EgdOG7lW5nIGTDom4gc+G7kSBj4bunYSA1IHF14buRYyBnaWEgxJHDsy4gDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQpWTlRMIDwtIHAxICU+JSANCiAgZmlsdGVyKGNuID09ICdDaGluYScgfCBjbiA9PSAnSmFwYW4nIHwgY24gPT0gJ1NwYWluJyB8IGNuID09ICdUaGFpbGFuZCcgfCBjbiA9PSAnVmlldG5hbScpICU+JQ0KICBncm91cF9ieShjbiwgcCkgJT4lDQogIHN1bW1hcmlzZShtZWFuX29mX3AgPSBtZWFuKHApLCAuZ3JvdXBzID0gJ2Ryb3AnKQ0KDQpkYXRhdGFibGUoVk5UTCkNCg0KbWVhbihWTlRMJG1lYW5fb2ZfcCkNCmBgYA0KDQojIyMgxJDhurdjIHRyxrBuZyDEkW8gbMaw4budbmcgdGhlbyBuxINtOg0KLSBUcnVuZyBiw6xuaCBkw6JuIHPhu5EgxJHhu5kgdHXhu5VpIHThu6sgNzAgxJHhur9uIDc5IGPhu6dhIDUgcXXhu5FjIGdpYSB0cm9uZyBuxINtIDIwMjAgDQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQp0MSA8LSBwMSAlPiUgDQogIGZpbHRlcih5ID09ICcyMDIwJykgJT4lDQogIGdyb3VwX2J5KGNuLCB5LCBwNzB0bzc5KSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX29mX3A3MHRvNzkgPSBtZWFuKHA3MHRvNzkpLCAuZ3JvdXBzID0gJ2Ryb3AnKQ0KDQpkYXRhdGFibGUodDEpDQoNCm1lYW4odDEkbWVhbl9vZl9wNzB0bzc5KQ0KYGBgIA0KDQoNCiMjIyDEkOG6t2MgdHLGsG5nIMSRbyBsxrDhu51uZyB0aGVvIGtob+G6o25nIHRo4budaSBnaWFuOiANCi0gVHJ1bmcgYsOsbmggZMOibiBz4buRIHRy4bq7IGVtIGTGsOG7m2kgMTUgdHXhu5VpIGPhu6dhIDUgcXXhu5FjIGdpYSDhu58gbsSDbSAxOTcwIHbDoCBuxINtIDE5OTA6IA0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbmFtIDwtIHAxICU+JSANCiAgZmlsdGVyKHkgPT0gJzE5NzAnIHwgeSA9PSAnMTk5MCcpICU+JQ0KICBncm91cF9ieShjbiwgeSwgcGN1MTUpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9vZl9wY3UxNSA9IG1lYW4ocGN1MTUpLCAuZ3JvdXBzID0gJ2Ryb3AnKQ0KDQpkYXRhdGFibGUobmFtKQ0KDQptZWFuKG5hbSRtZWFuX29mX3BjdTE1KQ0KYGBgDQoNCiMgTmhp4buHbSB24bulIDMuMjogDQoNCiMjIE3hu6VjIHRpw6p1IG5naGnDqm4gY+G7qXU6DQoNCi0gTuG6r20gYuG6r3Qgc+G7sSB0aGF5IMSR4buVaSB24buBIEdEUCBj4bunYSBDaGluYSwgRnJhbmNlLCBJdGFseSwgTWV4aWNvIHRyb25nIDU3IG7Eg20gdOG7qyBuxINtIDE5NjAgxJHhur9uIG7Eg20gMjAxNiANCg0KLSBO4bqvbSBi4bqvdCBz4buxIHRoYXkgxJHhu5VpIHbhu4EgR0RQIGPhu6dhIENoaW5hIHRow7RuZyBxdWEgY8OhYyDEkeG6t2MgdHLGsG5nIMSRbyBsxrDhu51uZyANCiAgDQotIEJp4bq/dCDEkcaw4bujYyB0cnVuZyBiw6xuaCB24buBIEdEUCB0cm9uZyA1NyBuxINtIGPhu6dhIDQgcXXhu5FjIGdpYSANCg0KLSBCaeG6v3QgxJHGsOG7o2MgY8OhYyBnacOhIHRy4buLIHRydW5nIGLDrG5oIHbhu4EgR0RQIGPhu6dhIDQgcXXhu5FjIGdpYSB0cm9uZyBuxINtIDE5ODANCg0KLSBCaeG6v3QgxJHGsOG7o2MgY8OhYyBnacOhIHRy4buLIHRydW5nIGLDrG5oIHbhu4EgR0RQIGPhu6dhIDQgcXXhu5FjIGdpYSDhu58gbsSDbSAyMDEwIHbDoCBuxINtIDIwMTINCg0KIyMgUGjGsMahbmcgcGjDoXAgbmdoacOqbiBj4bupdQ0KDQotIFPhu60gZOG7pW5nIGPDoWMgcGjGsMahbmcgcGjDoXA6DQoNCiAgLSBNw6MgaMOzYSBk4buvIGxp4buHdQ0KICANCiAgLSBU4bqhbyBi4bqjbmcgdOG6p24gc+G7kQ0KICANCiAgLSBUw61uaCB0b8OhbiBjw6FjIMSR4bq3YyB0csawbmcgxJFvIGzGsOG7nW5nIA0KDQojIyBHaeG6o2kgdGjDrWNoIGLhu5kgZOG7ryBsaeG7h3U6IA0KDQpE4buvIGxp4buHdSB0cm9uZyBmaWxlICoqZ2RwNGNvdW50cnkueGxzeCoqIG7Ds2kgduG7gSAqKkdEUCoqIGPhu6dhIDQgcXXhu5FjIGdpYSDEkcaw4bujYyBwaMOibiB0w61jaCB0cm9uZyA1NyBuxINtIHThu6sgbsSDbSAxOTYwIMSR4bq/biBuxINtIDIwMTYNCg0KQ8OzIDIyOCBow6BuZyB0xrDGoW5nIOG7qW5nIHbhu5tpIDIyOCBxdWFuIHPDoXQgDQoNCkPDsyA0IGPhu5l0IHTGsMahbmcg4bupbmcgIHbhu5tpIDQgYmnhur9uDQoNCi0gQ291bnRyeSBuYW1lOiBUw6puIFF14buRYyBHaWENCg0KLSBDb3VudHJ5IENvZGU6IE3DoyBxdeG7kWMgZ2lhIA0KDQotIFllYXI6IE7Eg20gbOG6pXkgc+G7kSBsaeG7h3UgDQoNCi0gVmFsdWU6IEdpw6EgdHLhu4sgR0RQIA0KDQojIyBQaMOibiB0w61jaCBk4buvIGxp4buHdSB24buBIEdEUCBj4bunYSBDaGluYSwgRnJhbmNlLCBJdGFseSwgTWV4aWNvIHRyb25nIDU3IG7Eg206IA0KDQotIFThuqFvIG3hu5l0IGLhuqNuIHNhbyBj4bunYSBmaWxlIGThu68gbGnhu4d1ICoqKmdkcDRjb3VudHJ5Lnhsc3gqKiogdsOgIGfDoW4gbsOzIHbDoG8gbeG7mXQgYmnhur9uIG3hu5tpIGPDsyB0w6puIGdkcC4gxJBp4buBdSBuw6B5IGdpw7pwIGLhuqFuIGdp4buvIG5ndXnDqm4gZOG7ryBsaeG7h3UgZ+G7kWMgdHJvbmcga2hpIHRo4buxYyBoaeG7h24gY8OhYyB0aGFvIHTDoWMgdHLDqm4gYuG6o24gc2FvLg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh4bHN4KQ0KZ2RwIDwtIHJlYWQueGxzeChmaWxlLmNob29zZSgpLCBzaGVldEluZGV4ID0gMSwgaGVhZGVyID0gVCkgDQoNCmRhdGF0YWJsZShnZHApIA0KYGBgIA0KLSBRdWEgYuG6o25nIHRyw6puIHRhIGPDsyB0aOG7gyB0aOG6pXkgxJHGsOG7o2MsIEdEUCBj4bunYSA0IG7GsOG7m2MgdHLDqm4gaOG6p3UgbmjGsCB0xINuZyBk4bqnbiBxdWEgdOG7q25nIG7Eg20gKG5oxrBuZyBjxaluZyBjw7MgMSB2w6BpIG7Eg20gR0RQIGdp4bqjbSkNCg0KLSBUaeG6v24gaMOgbmggaW4gcmEgbeG7mXQgYuG6o25nIHThuqduIHN14bqldCBk4buxYSB0csOqbiBjw6FjIGdpw6EgdHLhu4sgY+G7p2EgYmnhur9uIENvdW50cnkuTmFtZSB0cm9uZyDEkeG7kWkgdMaw4bujbmcgZOG7ryBsaeG7h3UgZ2RwLg0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KdGFibGUoZ2RwJENvdW50cnkuTmFtZSkNCmBgYA0KLSBL4bq/dCBxdeG6oyB0cuG6oyB24buBIGNobyBiaeG6v3QgcuG6sW5nIGPDsyA1NyBxdWFuIHPDoXQgdOG7qyBDaGluYSwgNTcgdOG7qyBGcmFuY2UsIDU3IHThu6sgSXRhbHkgdsOgIDU3IHThu6sgTWV4aWNvIHTGsMahbmcg4bupbmcgduG7m2kgNTcgbsSDbSBwaMOibiB0w61jaCB24buBIGdkcC4NCg0KIyMgTcOjIGjDs2EgZOG7ryBsaeG7h3UgduG7gSBkw6JuIHPhu5EgY+G7p2EgQ2hpbmE6ICANCg0KLSBUaeG6v24gaMOgbmggcGjDom4gdMOtY2ggduG7gSBHRFAgY+G7p2EgQ2hpbmENCg0KLSBU4bqhbyBt4buZdCBiaeG6v24gbeG7m2kgdHJvbmcgxJHhu5FpIHTGsOG7o25nIGThu68gbGnhu4d1IGdkcCBn4buNaSBsw6AgQ2hpbmEuQ29kZWQuIMSQ4buDIGJp4bq/dCDEkcaw4bujYyBnacOhIHRy4buLIGThu68gbGnhu4d1IG7DoG8gbMOgIGPhu6dhIENoaW5hLiBHacOhIHRy4buLIGPhu6dhIGJp4bq/biBuw6B5IHPhur0gxJHGsOG7o2MgeMOhYyDEkeG7i25oIGLhu59pIGPDonUgbOG7h25oIMSRaeG7gXUga2nhu4duIHNhdToNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCmdkcCRDaGluYS5Db2RlZCA8LSBpZmVsc2UoZ2RwJENvdW50cnkuTmFtZSA9PSAnQ2hpbmEnLCdDaGluYScsJ290aGVyIGNvdW50cnknKQ0KDQpkYXRhdGFibGUoZ2RwKQ0KYGBgDQoNCi0gVHLGsOG7m2MgaOG6v3QgbMOgIHBow6JuIHTDrWNoIHbhu4EgR0RQIGPhu6dhIENoaW5hIA0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCg0KZ2RwLkNoaW5hIDwtIGZpbHRlcihnZHAsIENvdW50cnkuTmFtZSA9PSAnQ2hpbmEnKSAlPiUgc2VsZWN0IChDb3VudHJ5Lk5hbWUsIFZhbHVlKQ0KDQpkYXRhdGFibGUoZ2RwLkNoaW5hKQ0KYGBgDQoNCi0gVGnhur9uIGjDoG5oIHBow6JuIHTDrWNoIEdEUCBj4bunYSBDaGluYSBxdWEgY8OhYyBuxINtIHbDoCBjaG8gbsOzIHJhIG3hu5l0IGPhu5l0IG3hu5tpIGPDsyB0w6puIGzDoCBWYWx1ZS5DaGluYQ0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KZ2RwLkNoaW5hJFZhbHVlLkNoaW5hIDwtIGNhc2Vfd2hlbihnZHAuQ2hpbmEkVmFsdWUgPCAyMDAwMDAwMDAwMDAgfiAnY2jhu4kgc+G7kSBnZHAg4bufIG3hu6ljIHRo4bqlcCcsIGdkcC5DaGluYSRWYWx1ZSA+PSAyMDAwMDAwMDAwMDAgJiBnZHAuQ2hpbmEkVmFsdWUgPD0gMTAwMDAwMDAwMDAwMCB+ICdjaOG7iSBz4buRIGdkcCDhu58gbeG7qWMgdHJ1bmcgYsOsbmgnLCBnZHAuQ2hpbmEkVmFsdWUgPiAxMDAwMDAwMDAwMDAwIH4gJ2No4buJIHPhu5EgZ2RwIOG7nyBt4bupYyBjYW8nKQ0KDQpkYXRhdGFibGUoZ2RwLkNoaW5hKQ0KYGBgDQotIFF1YSBi4bqjbmcgdHLDqm4gdGEgY8OzIHRo4buDIHRo4bqleSDEkcaw4bujYzogVOG7kWMgxJHhu5kgZ2lhIEdEUCBj4bunYSBDaGluYSwgdMSDbmcgxJHhu4F1IHRoZW8gdOG7q25nIG7Eg20gKG5oxrBuZyBjxaluZyBjw7MgMSB2w6BpIG7Eg20gR0RQIGdp4bqjbSkNCiAgDQojIyBQaMOibiB0w61jaCBk4buvIGxp4buHdSB0aGVvIHF14buRYyBnaWEgdsOgIHRoZW8gdGjhu51pIGdpYW46IA0KDQojIyMgQ8OhYyDEkeG6t2MgdHLGsG5nIMSRbyBsxrDhu51uZyB0aGVvIHF14buRYyBnaWEgKOG7nyDEkcOieSBwaMOibiB0w61jaCBDaGluYSk6IA0KDQotIFRp4bq/biBow6BuaCB04bqhbyBt4buZdCBi4bqjbmcgdGjhu5FuZyBrw6ogdMOzbSB04bqvdCB24buBIEdEUCBj4bunYSBDaGluYQ0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KZmlsdGVyKGdkcCwgQ291bnRyeS5OYW1lID09ICdDaGluYScpICU+JQ0KICBzZWxlY3QoQ291bnRyeS5OYW1lLCBWYWx1ZSkgJT4lIA0KICBzdW1tYXJ5KGdkcCRWYWx1ZSkNCmBgYA0KLSBL4bq/dCBxdeG6oyB0cuG6oyB24buBIGNobyB0aOG6pXk6IA0KICAgIA0KICAtIE1pbjogY2hvIHRo4bqleSBnacOhIHRy4buLIHRo4bqlcCBuaOG6pXQgduG7gSBHRFAgY+G7p2EgQ2hpbmEsIGzDoCA0LjcyMWUrMTANCiAgICAgIA0KICAtIDFzdCBRdS4gKHThu6kgcGjDom4gduG7iyB0aOG7qSBuaOG6pXQpOiBjaG8gdGjhuqV5IDI1JSBHRFAgY+G7p2EgQ2hpbmEgY8OzIGdpw6EgdHLhu4sgdGjhuqVwIGjGoW4gMS40NDJlKzExIA0KICAgICAgDQogIC0gTWVkaWFuOiBjaG8gdGjhuqV5IG3hu5l0IG7hu61hIEdEUCBj4bunYSBDaGluYSBjw7MgZ2nDoSB0cuG7iyB0aOG6pXAgaMahbiB2w6AgbeG7mXQgbuG7rWEgY8OzIGdpw6EgdHLhu4sgY2FvIGjGoW4gMy4xMjRlKzExDQogICAgICANCiAgLSBNZWFuOiDEkMOieSBsw6AgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCB24buBIEdEUCBj4bunYSBDaGluYSBsw6AgMS43OTFlKzEyICANCiAgICAgIA0KICAtIDNyZCBRdS4gKHThu6kgcGjDom4gduG7iyB0aOG7qSBiYSk6IGNobyB0aOG6pXkgNzUlIEdEUCBj4bunYSBDaGluYSBjw7MgZ2nDoSB0cuG7iyB0aOG6pXAgaMahbiAxLjQ3MWUrMTIgDQogICAgICANCiAgLSBNYXggKHThu5FpIMSRYSk6IEdpw6EgdHLhu4sgbsOgeSBjaG8gdGjhuqV5IGdpw6EgdHLhu4sgY2FvIG5o4bqldCB24buBIEdEUCBj4bunYSBDaGluYSwgbMOgIDEuMTIwZSsxMyAgDQoNCi0gVOG7qyBk4buvIGxp4buHdSBnZHAuQ2hpbmEgxJHDoyDEkcaw4bujYyB04bqhbyDhu58gdHLDqm4sIHRhIHRp4bq/biBow6BuaCB0w61uaCBjw6FjIMSR4bq3YyB0csawbmcgxJFvIGzGsOG7nW5nIHbhu4EgR0RQIGPhu6dhIENoaW5hIA0KDQotIFThu5VuZyBHRFAgY+G7p2EgQ2hpbmEgdOG7qyBuxINtIDE5NjAgxJHhur9uIG7Eg20gMjAxNjoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnN1bShnZHAuQ2hpbmEkVmFsdWUpIA0KYGBgDQoNCi0gxJDhu5kgZMOgaSBHRFAgY+G7p2EgQ2hpbmEgdOG7qyBuxINtIDE5NjAgxJHhur9uIG7Eg20gMjAxNjoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCmxlbmd0aChnZHAuQ2hpbmEkVmFsdWUpDQpgYGAgDQotIEvhur90IHF14bqjIHRy4bqjIHbhu4EgbMOgIDU3IHTGsMahbmcg4bupbmcgduG7m2kgNTcgbsSDbSBwaMOibiB0w61jaCB24buBIEdEUCBj4bunYSBDaGluYS4gDQoNCi0gUGjGsMahbmcgc2FpIHbhu4EgR0RQIGPhu6dhIENoaW5hIHThu6sgbsSDbSAxOTYwIMSR4bq/biBuxINtIDIwMTY6DQpgYGB7ciBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0V9DQp2YXIoZ2RwLkNoaW5hJFZhbHVlKQ0KYGBgDQoNCi0gxJDhu5kgbOG7h2NoIGNodeG6qW4gduG7gSBHRFAgY+G7p2EgQ2hpbmEgdOG7qyBuxINtIDE5NjAgxJHhur9uIG7Eg20gMjAxNjoNCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnNkKGdkcC5DaGluYSRWYWx1ZSkgDQpgYGANCg0KIyMjIMSQ4bq3YyB0csawbmcgxJFvIGzGsOG7nW5nIHRoZW8gbmjDs20gcXXhu5FjIGdpYSAoNCBxdeG7kWMgZ2lhIMSRYW5nIHBow6JuIHTDrWNoKToNCg0KLSBHacOhIHRy4buLIHRydW5nIGLDrG5oIHbhu4EgR0RQIGPhu6dhIDQgcXXhu5FjIGdpYSB04burIG7Eg20gMTk2MCDEkeG6v24gbsSDbSAyMDE2Og0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KdGIuZ2RwIDwtIGdkcCAlPiUgDQogIGdyb3VwX2J5KENvdW50cnkuTmFtZSwgVmFsdWUpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fb2ZfVmFsdWUgPSBtZWFuKFZhbHVlKSwgLmdyb3VwcyA9ICdkcm9wJykNCg0KZGF0YXRhYmxlKHRiLmdkcCkNCg0KbWVhbih0Yi5nZHAkbWVhbl9vZl9WYWx1ZSkNCmBgYA0KDQojIyMgxJDhurdjIHRyxrBuZyDEkW8gbMaw4budbmcgdGhlbyBuxINtOg0KDQotIFRydW5nIGLDrG5oIEdEUCBj4bunYSA0IHF14buRYyBnaWEg4bufIG7Eg20gMTk4MA0KYGBge3IgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KdGIueSA8LSBnZHAgJT4lIA0KICBmaWx0ZXIoWWVhciA9PSAnMTk4MCcpICU+JQ0KICBncm91cF9ieShDb3VudHJ5Lk5hbWUsIFllYXIsIFZhbHVlKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX29mX1ZhbHVlID0gbWVhbihWYWx1ZSksIC5ncm91cHMgPSAnZHJvcCcpDQoNCmRhdGF0YWJsZSh0Yi55KQ0KDQptZWFuKHRiLnkkbWVhbl9vZl9WYWx1ZSkNCmBgYCANCg0KDQojIyMgxJDhurdjIHRyxrBuZyDEkW8gbMaw4budbmcgdGhlbyBraG/huqNuZyB0aOG7nWkgZ2lhbjogDQoNCi0gVHJ1bmcgYsOsbmggR0RQIGPhu6dhIDQgcXXhu5FjIGdpYSDhu58gbsSDbSAyMDEwIHbDoCBuxINtIDIwMTINCmBgYHtyIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRX0NCnRiLjJ5IDwtIGdkcCAlPiUgDQogIGZpbHRlcihZZWFyID09ICcyMDEwJyB8IFllYXIgPT0gJzIwMTInKSAlPiUNCiAgZ3JvdXBfYnkoQ291bnRyeS5OYW1lLCBZZWFyLCBWYWx1ZSkgJT4lDQogIHN1bW1hcmlzZShtZWFuX29mX1ZhbHVlID0gbWVhbihWYWx1ZSksIC5ncm91cHMgPSAnZHJvcCcpDQoNCmRhdGF0YWJsZSh0Yi4yeSkNCg0KbWVhbih0Yi4yeSRtZWFuX29mX1ZhbHVlKQ0KYGBg