Author and date

Sources and descriptions of datasets

This R notebook explores the Ontario Works (social assistance for people without income) case numbers in the dataset Head of Household from Toronto Employment and Social Services. We compute mean monthly rates for a given year (2013, the latest year with data for all months), and plot this data as maps of Toronto divided into wards (44 wards) and neighbourhoods (140 neighbourhoods).

https://www.toronto.ca/city-government/data-research-maps/open-data/open-data-catalogue/community-services/#15580d71-31ca-010e-3895-6b77b49d966f

This dataset contains the Head of Household trending data from 2004 to present. It provides information on households by neighbourhood with reference to the Ontario Works social assistance program. The information in this dataset will inform the delivery of services by providing trending information on social assistance.

Currency: March 2015

http://opendata.toronto.ca/employment.social/head.household/opendata_tess_ow.zip

Children, Community and Social Services, Ontario, Social Assistance Caseloads

Total numbers of social assistance recipients and beneficiaries each month since January 1969.

https://files.ontario.ca/opendata/historical_sa_recipients_dataset_q2_2018_19.xlsx

Maytree, Social Assistance Summaries:

The Social Assistance Summaries series tracks the number of recipients of social assistance (welfare payments) in each province and territory.

https://maytree.com/wp-content/uploads/ON.xlsx

Income of individuals by age group, sex and income source, Canada, provinces and selected census metropolitan areas

Table: 11-10-0239-01 (formerly CANSIM 206-0052)

“1110023901-noSymbol.csv”

“Number of persons” = number of persons whose age is \(\geq 16\).

“Number with income” = number of persons with income from social assistance

Reading datasets and grouping observations

library(data.table)
library(plyr) #join
library(ggplot2) #fortify, ggplot
library(scales) #scale_fill_distiller
library(sp) #used by rgdal
library(rgdal) #readOGR
library(ggmap) #theme_nothing
library(rgeos) #gCentroids
library(forecast) #auto.arima, forecast

Read .csv containing monthly TESS Ontario works cases for January 2004 to November 2014. The size of the csv file is 2.68 GB.

CSVFILE <- "opendata_tess_ow.csv"
tess_dt <- fread(CSVFILE) #data.table
|--------------------------------------------------|
|==================================================|

Structure of datatable:

str(tess_dt)
Classes ‘data.table’ and 'data.frame':  9536341 obs. of  21 variables:
 $ YEAR_NUM              : int  2004 2004 2004 2004 2004 2004 2004 2004 2004 2004 ...
 $ MNTH                  : int  20040101 20040101 20040101 20040101 20040101 20040101 20040101 20040101 20040101 20040101 ...
 $ PROGRAM_NM            : chr  "Ontario Works" "Ontario Works" "Ontario Works" "Ontario Works" ...
 $ OFFICE                : chr  "Application Centre" "Application Centre" "Application Centre" "Application Centre" ...
 $ FAMILY_TYP_NM         : chr  "Families" "Families" "Families" "Families" ...
 $ FAMILY_SIZE           : chr  "2" "2" "2" "2" ...
 $ AGE                   : chr  "18 to 29 yrs old" "18 to 29 yrs old" "18 to 29 yrs old" "30 to 39 yrs old" ...
 $ EDUCATION_LEVEL       : chr  "High School Incomplete" "High School Incomplete" "Post Secondary" "High School Complete" ...
 $ EARNINGS              : chr  "" "" "" "Earnings from employment" ...
 $ IMMIGRATION_STATUS    : chr  "Permanent Resident" "Permanent Resident" "Canadian Citizen" "Canadian Citizen" ...
 $ TIMES_ON_ASSISTANCE   : chr  "1" "4+" "3" "1" ...
 $ MONTHS_ON_ASSISTANCE  : chr  "1 to 6 months" "1 to 6 months" "1 to 6 months" "1 to 6 months" ...
 $ MONTHS_OFF_ASSISTANCE : chr  "1 to 6 months" "1 to 6 months" "1 to 6 months" "7 to 24 months" ...
 $ GENDER                : chr  "F" "F" "F" "F" ...
 $ SHELTER_COSTS         : chr  "$600 to $999" "$400 to $599" "$200 to $399" "$400 to $599" ...
 $ YOUNGEST_DEP_AGE_RANGE: chr  "less than 5 yrs old" "less than 5 yrs old" "less than 5 yrs old" "5 to 10 yrs old" ...
 $ WARD_SCODE            : int  2 2 8 8 6 2 1 2 8 6 ...
 $ CENSUS_NEIGH_SCODE    : int  4 4 24 27 19 4 2 4 27 19 ...
 $ NEW_CASES             : int  0 0 0 0 0 0 0 0 0 0 ...
 $ EXITS                 : int  1 0 0 0 1 0 0 0 0 0 ...
 $ CASES                 : int  1 1 1 1 1 1 1 1 1 1 ...
 - attr(*, ".internal.selfref")=<externalptr> 

Select columns from tess_dt

ow_cases <- tess_dt[,.(YEAR_NUM, MNTH, WARD_SCODE, CENSUS_NEIGH_SCODE, CASES)]

Drop rows where at least one of CENSUS_NEIGH_SCODE and WARD_SCODE is missing

ow_cases_dropna <- na.omit(ow_cases, cols=c("CENSUS_NEIGH_SCODE", "WARD_SCODE"))

Calculate mean number of cases in 2010 by month and ward

ow_wards_2010 <- ow_cases_dropna[YEAR_NUM==2010,.(TOTAL_CASES=sum(CASES)),by=.(MNTH, WARD_SCODE)]

ow_wards_2010_months <- ow_wards_2010[,.(MONTHLY_CASES=sum(TOTAL_CASES)),by=.(MNTH, WARD_SCODE)]

ow_wards_2010_monthly <- ow_wards_2010_months[,.(MEAN_CASES_PER_MONTH=mean(MONTHLY_CASES)),by=.(WARD_SCODE)]

Add “id” column

ow_wards_2010_monthly$id <- ow_wards_2010_monthly$WARD_SCODE

Calculate mean number of cases in 2013 by month and ward

ow_wards_2013 <- ow_cases_dropna[YEAR_NUM==2013,.(TOTAL_CASES=sum(CASES)),by=.(MNTH, WARD_SCODE)]

ow_wards_2013_months <- ow_wards_2013[,.(MONTHLY_CASES=sum(TOTAL_CASES)),by=.(MNTH, WARD_SCODE)]

ow_wards_2013_monthly <- ow_wards_2013_months[,.(MEAN_CASES_PER_MONTH=mean(MONTHLY_CASES)),by=.(WARD_SCODE)]

Add “id” column

ow_wards_2013_monthly$id <- ow_wards_2013_monthly$WARD_SCODE

Plotting data by wards

City Wards

https://www.toronto.ca/city-government/data-research-maps/open-data/open-data-catalogue/#29b6fadf-0bd6-2af9-4a8c-8c41da285ad7

Owner: City Clerk’s Office

Currency: August 2018

44 Ward Model - May 2010 (WGS84 - Latitude / Longitude)

http://opendata.toronto.ca/gcc/wards_may2010_wgs84.zip

Shapefile: icitw_wgs84

readme.txt:

Wards: There are a total of 44 electoral wards in the City of Toronto
* GEO_ID = unique geographic identifier
* NAME = Name of the Ward with corresponding ward number
* SCODE_NAME = Ward Number
* LCODE_NAME = Ward Number and the community council area it is in (N,S, E or W)
* TYPE_DESC = Ward
* TYPE_CODE = City Ward

We shall input wards shapefile, create centroids of wards, and process shapefile as dataframe. First we input the shapefile

wards.sh <- readOGR("C:/Users/14165/Desktop/ArcGIS/SHAPEFILES/May2010_WGS84", "icitw_wgs84")
OGR data source with driver: ESRI Shapefile 
Source: "C:\Users\14165\Desktop\ArcGIS\SHAPEFILES\May2010_WGS84", layer: "icitw_wgs84"
with 44 features
It has 10 fields

Add “id” column

wards.sh@data$id <- as.integer(wards.sh@data$SCODE_NAME)

Make centroids of each ward, for placing labels when plotting

wards.sh.centroids  <- as.data.frame(gCentroid(wards.sh, byid = TRUE))

Add “id” column

wards.sh.centroids$id <- wards.sh@data$id

Shapefile processing

wards.sh.points = fortify(wards.sh, region="id")
wards.sh.df = join(wards.sh.points, wards.sh@data, by="id")

Merge ward shapefile and ow_wards_2010_monthly dataframe

wards.sh.ow_2010 <- merge(wards.sh.df, ow_wards_2010_monthly, by = "id")

Make graphics object for wards.sh.ow_2010

p.wards_2010 <- ggplot() + 
  geom_polygon(data = wards.sh.ow_2010, 
               aes(x = long, y = lat, group = group, fill = MEAN_CASES_PER_MONTH),
               color = "black", size = 0.25) +  
  coord_map() + 
  scale_fill_distiller(name="Cases", palette = "YlOrBr", trans = "reverse", breaks = pretty_breaks(n = 8)) + 
  theme_nothing(legend = TRUE) + 
  labs(title="Mean monthly number of Ontario Works cases by ward in Toronto in 2010") + 
  geom_text(aes(x=x, y=y, group=NULL, label=id), data = wards.sh.centroids, size = 2)

Plot graphics object

p.wards_2010 + guides(fill = guide_legend(reverse = TRUE)) #ggplot2

Calculate mean number of cases in 2013 by month and ward

ow_wards_2013 <- ow_cases_dropna[YEAR_NUM==2013,.(TOTAL_CASES=sum(CASES)),by=.(MNTH, WARD_SCODE)]

ow_wards_2013_months <- ow_wards_2013[,.(MONTHLY_CASES=sum(TOTAL_CASES)),by=.(MNTH, WARD_SCODE)]

ow_wards_2013_monthly <- ow_wards_2013_months[,.(MEAN_CASES_PER_MONTH=mean(MONTHLY_CASES)),by=.(WARD_SCODE)] 

Add “id” column

ow_wards_2013_monthly$id <- ow_wards_2013_monthly$WARD_SCODE

Merge ward shapefile and ow_wards_2013_monthly dataframe

wards.sh.ow_2013 <- merge(wards.sh.df, ow_wards_2013_monthly, by = "id")

Make graphics object

p.wards_2013 <- ggplot() + 
  geom_polygon(data = wards.sh.ow_2013, 
               aes(x = long, y = lat, group = group, fill = MEAN_CASES_PER_MONTH), 
               color = "black", size = 0.25) + 
  coord_map() + 
  scale_fill_distiller(name="Cases", palette = "YlOrBr", trans = "reverse", breaks = pretty_breaks(n = 8)) + 
  theme_nothing(legend = TRUE) + 
  labs(title="Mean monthly number of Ontario Works cases by ward in Toronto in 2013") + 
  geom_text(aes(x=x,y=y, group=NULL, label=id), data = wards.sh.centroids, size=2)

Plot graphics object

p.wards_2013 + guides(fill = guide_legend(reverse = TRUE)) #ggplot2

Calculate mean number of cases in 2013 by month and neighbourhood

ow_nbds_2013 <- ow_cases_dropna[YEAR_NUM==2013,.(TOTAL_CASES=sum(CASES)),by=.(MNTH, CENSUS_NEIGH_SCODE)]

ow_nbds_2013_months <- ow_nbds_2013[,.(MONTHLY_CASES=sum(TOTAL_CASES)),by=.(MNTH, CENSUS_NEIGH_SCODE)]

ow_nbds_2013_monthly <- ow_nbds_2013_months[,.(MEAN_CASES_PER_MONTH=mean(MONTHLY_CASES)),by=.(CENSUS_NEIGH_SCODE)]

Add “id” column

ow_nbds_2013_monthly$id <- ow_nbds_2013_monthly$CENSUS_NEIGH_SCODE

Doing finer aggregation: mean monthly cases who are single (without dependents)

ow_singles <- tess_dt[FAMILY_TYP_NM=="Singles",.(YEAR_NUM, MNTH, WARD_SCODE, CENSUS_NEIGH_SCODE, CASES)]

ow_singles_dropna <- na.omit(ow_singles, cols=c("CENSUS_NEIGH_SCODE", "WARD_SCODE"))

ow_singles_wards_2013 <- ow_singles_dropna[YEAR_NUM==2013,.(TOTAL_CASES=sum(CASES)),by=.(MNTH, WARD_SCODE)]

ow_singles_wards_2013_months <- ow_singles_wards_2013[,.(MONTHLY_CASES=sum(TOTAL_CASES)),by=.(MNTH, WARD_SCODE)]

ow_singles_wards_2013_monthly <- ow_singles_wards_2013_months[,.(MEAN_CASES_PER_MONTH=mean(MONTHLY_CASES)),by=.(WARD_SCODE)]

Add “id” column

ow_singles_wards_2013_monthly$id <- ow_singles_wards_2013_monthly$WARD_SCODE

Merge ward shapefile and Ontario Works dataframe

wards.sh.ow_singles_2013 <- merge(wards.sh.df, ow_singles_wards_2013_monthly, by = "id")

We shall plot wards.sh.ow_singles_2013. Make graphics object

p.wards_singles_2013 <- ggplot() +
  geom_polygon(data = wards.sh.ow_singles_2013, 
               aes(x = long, y = lat, group = group, fill = MEAN_CASES_PER_MONTH), 
               color = "black", size = 0.25) + 
  coord_map() + 
  scale_fill_distiller(name="Cases", palette = "PuRd", trans = "reverse", breaks = pretty_breaks(n = 8)) + 
  theme_nothing(legend = TRUE) + 
  labs(title="Mean monthly number of Ontario Works cases (singles) by ward in Toronto in 2013") + 
  geom_text(aes(x=x,y=y, group=NULL, label=id), data = wards.sh.centroids, size = 2)

Plot graphics object

p.wards_singles_2013 + guides(fill = guide_legend(reverse = TRUE))

Plotting data by neighbourhoods

Neighbourhoods shapefile

https://www.toronto.ca/city-government/data-research-maps/open-data/open-data-catalogue/#a45bd45a-ede8-730e-1abc-93105b2c439f

http://opendata.toronto.ca/gcc/neighbourhoods_planning_areas_wgs84.zip

Owner: Social Development, Finance & Administration

Currency: June 2014

Neighbourhoods (WGS84)

Shapefile: NEIGHBORHOODS_WGS84

NEIGHBORHOODS_WGS84_readme.txt:

NEIGHBORHOODS_WGS84_readme
* Column name (Description)
* AREA_S_CD = AREA_SHORT_CODE
* AREA_NAME = AREA_NAME

Input shapefile

nbds.sh <- readOGR("C:/Users/14165/Desktop/ArcGIS/SHAPEFILES/neighbourhoods_planning_areas_wgs84", "NEIGHBORHOODS_WGS84")
OGR data source with driver: ESRI Shapefile 
Source: "C:\Users\14165\Desktop\ArcGIS\SHAPEFILES\neighbourhoods_planning_areas_wgs84", layer: "NEIGHBORHOODS_WGS84"
with 140 features
It has 2 fields

Add “id” column

nbds.sh@data$id <- as.integer(nbds.sh@data$AREA_S_CD)

Make centroids of each neighbourhood, for placing labels when plotting

nbds.sh.centroids  <- as.data.frame(gCentroid(nbds.sh, byid = TRUE))

Add “id” column

nbds.sh.centroids$id <- nbds.sh@data$id

Shapefile processing

nbds.sh.points = fortify(nbds.sh, region = "id")
nbds.sh.df = join(nbds.sh.points, nbds.sh@data, by = "id")

Merge neighbourhood shapefile and Ontario Works dataframe

nbds.sh.ow_2013 <- merge(nbds.sh.df, ow_nbds_2013_monthly, by = "id")

Make graphics object

p.nbds_2013 <- ggplot() +
  geom_polygon(data = nbds.sh.ow_2013, 
               aes(x = long, y = lat, group = group, fill = MEAN_CASES_PER_MONTH), 
               color = "black", size = 0.2) + 
  coord_map() + 
  scale_fill_distiller(name="Cases", palette = "YlOrBr", trans = "reverse", breaks = pretty_breaks(n = 8)) + 
  theme_nothing(legend = TRUE) + 
  labs(title="Mean monthly number of Ontario Works cases by neighbourhood in Toronto in 2013") + 
  geom_text(aes(x=x,y=y, group=NULL, label=id), data = nbds.sh.centroids, size = 2)

Plot graphics object

p.nbds_2013+guides(fill = guide_legend(reverse = TRUE))

Time series

Avril Coghlan, Using R for Time Series Analysis

Vincent Zoonekynd, Time series

TESS Ontario Works data manipulation

Group by month and create time series:

ow_cases_months <- tess_dt[,.(MNTH, CASES, NEW_CASES, EXITS)]

ow_cases_monthly <- ow_cases_months[,.(CASES=sum(CASES), NEW_CASES=sum(NEW_CASES), EXITS=sum(EXITS)),by=.(MNTH)]

ow_cases_monthly$MNTH <- NULL

head(ow_cases_monthly)
ow_ts <- ts(ow_cases_monthly, start = c(2004,1), frequency = 12)

head(ow_ts)
         CASES NEW_CASES EXITS
Jan 2004 70169      3597  3788
Feb 2004 70327      3407  3977
Mar 2004 70929      5042  4430
Apr 2004 70040      5044  3917
May 2004 69999      4567  4146
Jun 2004 69976      4806  4318

TESS Ontario Works plots

Plot time series

options(scipen=999) #do not use scientific notation

plot(ow_ts)

Make time series of CASES

CASES <- ts(ow_cases_monthly$CASES, start = c(2004,1), frequency = 12)

plot(CASES)

Make time series of NEW_CASES

NEW_CASES <- ts(ow_cases_monthly$NEW_CASES, start = c(2004,1), frequency = 12)

plot(NEW_CASES)

Decomposing time series into trend, seasonal, and remainder terms

Now we use stats::decompose and stats::stl to separate time series as a sum of trend, seasonal, and remainder terms.

CASES_components <- decompose(CASES)
autoplot(CASES_components)

NEW_CASES_components <- decompose(NEW_CASES)
autoplot(NEW_CASES_components)

CASES.stl <- stl(CASES, s.window = "periodic")
autoplot(CASES.stl)

NEW_CASES.stl <- stl(NEW_CASES, s.window = "periodic")
autoplot(NEW_CASES.stl)

Holt-Winters exponential smoothing

CASES.HW <- HoltWinters(CASES)

CASES.HW
Holt-Winters exponential smoothing with trend and additive seasonal component.

Call:
HoltWinters(x = CASES)

Smoothing parameters:
 alpha: 0.9535295
 beta : 0.1484578
 gamma: 1

Coefficients:
           [,1]
a   84371.18862
b    -445.73297
s1  -1132.80119
s2  -1618.51347
s3   -369.32564
s4     -3.67365
s5    626.57812
s6    466.48438
s7    853.77241
s8    638.32040
s9    352.15093
s10   473.25854
s11   298.98513
s12  -793.18862
plot(CASES.HW)

CASES.HW.forecast <- forecast(CASES.HW, h = 24)

plot(CASES.HW.forecast)

ARIMA

CASES.arima <- auto.arima(CASES)
CASES.arima
Series: CASES 
ARIMA(0,2,1)(0,0,2)[12] 

Coefficients:
          ma1    sma1    sma2
      -0.8806  0.1925  0.2403
s.e.   0.0497  0.0852  0.0827

sigma^2 estimated as 825250:  log likelihood=-1053.56
AIC=2115.11   AICc=2115.44   BIC=2126.52
op <- par(mfrow=c(2,1), mar=c(2,4,1,2)+.1)
acf(CASES,  main="")
pacf(CASES, main="")
par(op)

CASES.forecast <- forecast(CASES, level = c(95), h = 22)

plot(CASES.forecast)

CASES.arima.forecast <- forecast(CASES.arima, level = c(95), h = 22)

plot(CASES.arima.forecast)

Ontario Monthly Social Assistance Caseloads 1969-2018

SA <- fread("historical_sa_recipients_dataset_q2_2018_19.csv")

SA$Beneficiaries <- NULL

Make time series

SA_ts <- ts(SA$Cases, start = c(1969,1), frequency = 12)
plot(SA_ts)

SA_ts_1997 <- window(SA_ts, c(1997,1))

plot(SA_ts_1997)

SA_ts_1997.components <- decompose(SA_ts_1997)

autoplot(SA_ts_1997.components)

SA_ts_1997.stl <- stl(SA_ts_1997, s.window = "periodic")

autoplot(SA_ts_1997.stl)

Maytree Social Assistance Summaries

Maytree_ON <- fread("ON.csv")
str(Maytree_ON)
Classes ‘data.table’ and 'data.frame':  25 obs. of  7 variables:
 $ Year                       : chr  "1997-98" "1998-99" "1999-00" "2000-01" ...
 $ Ontario Works Cases        : int  362334 310493 262439 215618 196596 195137 192096 191723 198377 199242 ...
 $ Ontario Works Beneficiaries: int  796109 690608 577620 469494 419493 404067 389754 380670 386801 383068 ...
 $ ODSP Cases                 : int  185479 189392 189536 191885 192048 194140 200087 205880 212058 221718 ...
 $ ODSP Beneficiaries         : int  261737 268159 268286 271144 270558 271740 278393 285231 292622 305202 ...
 $ Total Cases                : int  547813 499884 451975 407503 388644 389277 392183 397603 410435 420960 ...
 $ Total Beneficiaries        : int  1057846 958767 845907 740637 690051 675807 668148 665901 679423 688270 ...
 - attr(*, ".internal.selfref")=<externalptr> 
Maytree_OW.ts <- ts(Maytree_ON$`Ontario Works Cases`, start = 1997, frequency = 1)

Maytree_ODSP.ts <- ts(Maytree_ON$`ODSP Cases`, start = 1997, frequency = 1)
plot(Maytree_OW.ts)

plot(Maytree_ODSP.ts)

plot(Maytree_ODSP.ts+Maytree_OW.ts)

Statistics Canada Table 11-10-0239-01

T1110023901 <- fread("1110023901-noSymbol.csv")
str(T1110023901)
Classes ‘data.table’ and 'data.frame':  42 obs. of  3 variables:
 $ Reference period  : int  1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 ...
 $ Number of persons : int  1830 2182 2266 2281 2300 2500 2512 2760 2604 2636 ...
 $ Number with income: int  52 81 54 93 76 91 112 126 127 111 ...
 - attr(*, ".internal.selfref")=<externalptr> 
T1110023901.ts <- ts(T1110023901$`Number of persons`, start = 1976, frequency = 1)

plot(T1110023901.ts, ylab = "Number of persons", main = "Persons 16 years and older in Toronto with social assistance income" )

T1110023901.ts_1997 <- window(T1110023901.ts, c(1997,1))

plot(T1110023901.ts_1997)

op <- par(mfrow=c(2,1), mar=c(2,4,1,2)+.1)
acf(T1110023901.ts_1997,  main="")
pacf(T1110023901.ts_1997, main="")
par(op)

T1110023901.ts_1997.forecast <- forecast(T1110023901.ts_1997, level = c(95), h = 12)

plot(T1110023901.ts_1997.forecast)

T1110023901.ts_1997.arima <- auto.arima(T1110023901.ts_1997)

T1110023901.ts_1997.arima
Series: T1110023901.ts_1997 
ARIMA(0,1,1) with drift 

Coefficients:
          ma1    drift
      -0.6140  97.5973
s.e.   0.3226  10.4978

sigma^2 estimated as 11017:  log likelihood=-120.63
AIC=247.27   AICc=248.77   BIC=250.25
T1110023901.ts_1997.arima.forecast <- forecast(T1110023901.ts_1997.arima, level = c(95), h = 5)

plot(T1110023901.ts_1997.arima.forecast)

LS0tDQp0aXRsZTogIlRvcm9udG8gRW1wbG95bWVudCBhbmQgU29jaWFsIFNlcnZpY2VzIE9udGFyaW8gV29ya3MgRGF0YXNldCINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIHRvYzogeWVzDQotLS0NCg0KIyBBdXRob3IgYW5kIGRhdGUNCg0KKiBKb3JkYW4gQmVsbA0KKiBKdWx5IDEsIDIwMTkNCiogPGh0dHBzOi8vam9yZGFuYmVsbDIzNTcuZ2l0aHViLmlvL1RFU1NfT1cubmIuaHRtbD4NCg0KIyBTb3VyY2VzIGFuZCBkZXNjcmlwdGlvbnMgb2YgZGF0YXNldHMNCg0KVGhpcyBSIG5vdGVib29rIGV4cGxvcmVzIHRoZSBPbnRhcmlvIFdvcmtzIChzb2NpYWwgYXNzaXN0YW5jZSBmb3IgcGVvcGxlIHdpdGhvdXQgaW5jb21lKSBjYXNlIG51bWJlcnMgaW4gdGhlDQpkYXRhc2V0ICoqSGVhZCBvZiBIb3VzZWhvbGQqKiBmcm9tIFRvcm9udG8gRW1wbG95bWVudCBhbmQgU29jaWFsIFNlcnZpY2VzLg0KV2UgY29tcHV0ZSBtZWFuICBtb250aGx5IHJhdGVzIGZvciBhIGdpdmVuIHllYXIgKDIwMTMsIHRoZSBsYXRlc3QgeWVhciB3aXRoIGRhdGEgZm9yIGFsbCBtb250aHMpLA0KYW5kIHBsb3QgdGhpcyBkYXRhIGFzIG1hcHMgb2YgVG9yb250byBkaXZpZGVkIGludG8gd2FyZHMgKDQ0IHdhcmRzKSBhbmQgbmVpZ2hib3VyaG9vZHMgKDE0MCBuZWlnaGJvdXJob29kcykuDQoNCg0KPGh0dHBzOi8vd3d3LnRvcm9udG8uY2EvY2l0eS1nb3Zlcm5tZW50L2RhdGEtcmVzZWFyY2gtbWFwcy9vcGVuLWRhdGEvb3Blbi1kYXRhLWNhdGFsb2d1ZS9jb21tdW5pdHktc2VydmljZXMvIzE1NTgwZDcxLTMxY2EtMDEwZS0zODk1LTZiNzdiNDlkOTY2Zj4NCg0KDQo+VGhpcyBkYXRhc2V0IGNvbnRhaW5zIHRoZSBIZWFkIG9mIEhvdXNlaG9sZCB0cmVuZGluZyBkYXRhIGZyb20gMjAwNCB0byBwcmVzZW50LiBJdCBwcm92aWRlcyBpbmZvcm1hdGlvbiBvbiBob3VzZWhvbGRzIGJ5IG5laWdoYm91cmhvb2Qgd2l0aCByZWZlcmVuY2UgdG8gdGhlIE9udGFyaW8gV29ya3Mgc29jaWFsIGFzc2lzdGFuY2UgcHJvZ3JhbS4gVGhlIGluZm9ybWF0aW9uIGluIHRoaXMgZGF0YXNldCB3aWxsIGluZm9ybSB0aGUgZGVsaXZlcnkgb2Ygc2VydmljZXMgYnkgcHJvdmlkaW5nIHRyZW5kaW5nIGluZm9ybWF0aW9uIG9uIHNvY2lhbCBhc3Npc3RhbmNlLg0KPg0KPkN1cnJlbmN5OiBNYXJjaCAyMDE1DQoNCjxodHRwOi8vb3BlbmRhdGEudG9yb250by5jYS9lbXBsb3ltZW50LnNvY2lhbC9oZWFkLmhvdXNlaG9sZC9vcGVuZGF0YV90ZXNzX293LnppcD4NCg0KQ2hpbGRyZW4sIENvbW11bml0eSBhbmQgU29jaWFsIFNlcnZpY2VzLCBPbnRhcmlvLCBbU29jaWFsIEFzc2lzdGFuY2UgQ2FzZWxvYWRzXShodHRwczovL3d3dy5vbnRhcmlvLmNhL2RhdGEvc29jaWFsLWFzc2lzdGFuY2UtY2FzZWxvYWRzKQ0KDQo+IFRvdGFsIG51bWJlcnMgb2Ygc29jaWFsIGFzc2lzdGFuY2UgcmVjaXBpZW50cyBhbmQgYmVuZWZpY2lhcmllcyBlYWNoIG1vbnRoIHNpbmNlIEphbnVhcnkgMTk2OS4NCg0KPGh0dHBzOi8vZmlsZXMub250YXJpby5jYS9vcGVuZGF0YS9oaXN0b3JpY2FsX3NhX3JlY2lwaWVudHNfZGF0YXNldF9xMl8yMDE4XzE5Lnhsc3g+DQoNCk1heXRyZWUsIFtTb2NpYWwgQXNzaXN0YW5jZSBTdW1tYXJpZXNdKGh0dHBzOi8vbWF5dHJlZS5jb20vc29jaWFsLWFzc2lzdGFuY2Utc3VtbWFyaWVzL29udGFyaW8vKToNCg0KPiBUaGUgU29jaWFsIEFzc2lzdGFuY2UgU3VtbWFyaWVzIHNlcmllcyB0cmFja3MgdGhlIG51bWJlciBvZiByZWNpcGllbnRzIG9mIHNvY2lhbCBhc3Npc3RhbmNlICh3ZWxmYXJlIHBheW1lbnRzKSBpbiBlYWNoIHByb3ZpbmNlIGFuZCB0ZXJyaXRvcnkuDQoNCjxodHRwczovL21heXRyZWUuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy9PTi54bHN4Pg0KDQpbSW5jb21lIG9mIGluZGl2aWR1YWxzIGJ5IGFnZSBncm91cCwgc2V4IGFuZCBpbmNvbWUgc291cmNlLCBDYW5hZGEsIHByb3ZpbmNlcyBhbmQgc2VsZWN0ZWQgY2Vuc3VzIG1ldHJvcG9saXRhbiBhcmVhc10oaHR0cHM6Ly93d3cxNTAuc3RhdGNhbi5nYy5jYS90MS90YmwxL2VuL2N2IXJlY3JlYXRlLmFjdGlvbj9waWQ9MTExMDAyMzkwMSZzZWxlY3RlZE5vZGVJZHM9MUQxNyw0RDE0LDVEMSw1RDImY2hlY2tlZExldmVscz0xRDEsMkQxJnJlZlBlcmlvZHM9MTk3NjAxMDEsMjAxNzAxMDEmZGltZW5zaW9uTGF5b3V0cz1sYXlvdXQzLGxheW91dDMsbGF5b3V0MyxsYXlvdXQzLGxheW91dDIsbGF5b3V0MyZ2ZWN0b3JEaXNwbGF5PWZhbHNlKQ0KDQo+IFRhYmxlOiAxMS0xMC0wMjM5LTAxIChmb3JtZXJseSBDQU5TSU0gMjA2LTAwNTIpDQoNCiIxMTEwMDIzOTAxLW5vU3ltYm9sLmNzdiINCg0KIk51bWJlciBvZiBwZXJzb25zIiA9IG51bWJlciBvZiBwZXJzb25zIHdob3NlIGFnZSBpcyAkXGdlcSAxNiQuIA0KDQoiTnVtYmVyIHdpdGggaW5jb21lIiA9IG51bWJlciBvZiBwZXJzb25zIHdpdGggaW5jb21lIGZyb20gc29jaWFsIGFzc2lzdGFuY2UNCg0KDQojIFJlYWRpbmcgZGF0YXNldHMgYW5kIGdyb3VwaW5nIG9ic2VydmF0aW9ucw0KDQpgYGB7cn0NCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkocGx5cikgI2pvaW4NCmxpYnJhcnkoZ2dwbG90MikgI2ZvcnRpZnksIGdncGxvdA0KbGlicmFyeShzY2FsZXMpICNzY2FsZV9maWxsX2Rpc3RpbGxlcg0KbGlicmFyeShzcCkgI3VzZWQgYnkgcmdkYWwNCmxpYnJhcnkocmdkYWwpICNyZWFkT0dSDQpsaWJyYXJ5KGdnbWFwKSAjdGhlbWVfbm90aGluZw0KbGlicmFyeShyZ2VvcykgI2dDZW50cm9pZHMNCmxpYnJhcnkoZm9yZWNhc3QpICNhdXRvLmFyaW1hLCBmb3JlY2FzdA0KYGBgDQpSZWFkIC5jc3YgY29udGFpbmluZyBtb250aGx5IFRFU1MgT250YXJpbyB3b3JrcyBjYXNlcyBmb3IgSmFudWFyeSAyMDA0IHRvIE5vdmVtYmVyIDIwMTQuDQpUaGUgc2l6ZSBvZiB0aGUgY3N2IGZpbGUgaXMgMi42OCBHQi4NCg0KYGBge3J9DQpDU1ZGSUxFIDwtICJvcGVuZGF0YV90ZXNzX293LmNzdiINCnRlc3NfZHQgPC0gZnJlYWQoQ1NWRklMRSkgI2RhdGEudGFibGUNCmBgYA0KU3RydWN0dXJlIG9mIGRhdGF0YWJsZToNCmBgYHtyfQ0Kc3RyKHRlc3NfZHQpDQpgYGANCg0KU2VsZWN0IGNvbHVtbnMgZnJvbSB0ZXNzX2R0DQpgYGB7cn0NCm93X2Nhc2VzIDwtIHRlc3NfZHRbLC4oWUVBUl9OVU0sIE1OVEgsIFdBUkRfU0NPREUsIENFTlNVU19ORUlHSF9TQ09ERSwgQ0FTRVMpXQ0KYGBgDQoNCkRyb3Agcm93cyB3aGVyZSBhdCBsZWFzdCBvbmUgb2YgQ0VOU1VTX05FSUdIX1NDT0RFIGFuZCBXQVJEX1NDT0RFIGlzIG1pc3NpbmcNCmBgYHtyfQ0Kb3dfY2FzZXNfZHJvcG5hIDwtIG5hLm9taXQob3dfY2FzZXMsIGNvbHM9YygiQ0VOU1VTX05FSUdIX1NDT0RFIiwgIldBUkRfU0NPREUiKSkNCmBgYA0KQ2FsY3VsYXRlIG1lYW4gbnVtYmVyIG9mIGNhc2VzIGluIDIwMTAgYnkgbW9udGggYW5kIHdhcmQNCmBgYHtyfQ0Kb3dfd2FyZHNfMjAxMCA8LSBvd19jYXNlc19kcm9wbmFbWUVBUl9OVU09PTIwMTAsLihUT1RBTF9DQVNFUz1zdW0oQ0FTRVMpKSxieT0uKE1OVEgsIFdBUkRfU0NPREUpXQ0KDQpvd193YXJkc18yMDEwX21vbnRocyA8LSBvd193YXJkc18yMDEwWywuKE1PTlRITFlfQ0FTRVM9c3VtKFRPVEFMX0NBU0VTKSksYnk9LihNTlRILCBXQVJEX1NDT0RFKV0NCg0Kb3dfd2FyZHNfMjAxMF9tb250aGx5IDwtIG93X3dhcmRzXzIwMTBfbW9udGhzWywuKE1FQU5fQ0FTRVNfUEVSX01PTlRIPW1lYW4oTU9OVEhMWV9DQVNFUykpLGJ5PS4oV0FSRF9TQ09ERSldDQpgYGANCkFkZCAiaWQiIGNvbHVtbg0KYGBge3J9DQpvd193YXJkc18yMDEwX21vbnRobHkkaWQgPC0gb3dfd2FyZHNfMjAxMF9tb250aGx5JFdBUkRfU0NPREUNCmBgYA0KQ2FsY3VsYXRlIG1lYW4gbnVtYmVyIG9mIGNhc2VzIGluIDIwMTMgYnkgbW9udGggYW5kIHdhcmQNCmBgYHtyfQ0Kb3dfd2FyZHNfMjAxMyA8LSBvd19jYXNlc19kcm9wbmFbWUVBUl9OVU09PTIwMTMsLihUT1RBTF9DQVNFUz1zdW0oQ0FTRVMpKSxieT0uKE1OVEgsIFdBUkRfU0NPREUpXQ0KDQpvd193YXJkc18yMDEzX21vbnRocyA8LSBvd193YXJkc18yMDEzWywuKE1PTlRITFlfQ0FTRVM9c3VtKFRPVEFMX0NBU0VTKSksYnk9LihNTlRILCBXQVJEX1NDT0RFKV0NCg0Kb3dfd2FyZHNfMjAxM19tb250aGx5IDwtIG93X3dhcmRzXzIwMTNfbW9udGhzWywuKE1FQU5fQ0FTRVNfUEVSX01PTlRIPW1lYW4oTU9OVEhMWV9DQVNFUykpLGJ5PS4oV0FSRF9TQ09ERSldDQpgYGANCkFkZCAiaWQiIGNvbHVtbg0KYGBge3J9DQpvd193YXJkc18yMDEzX21vbnRobHkkaWQgPC0gb3dfd2FyZHNfMjAxM19tb250aGx5JFdBUkRfU0NPREUNCmBgYA0KDQojIFBsb3R0aW5nIGRhdGEgYnkgd2FyZHMNCg0KKipDaXR5IFdhcmRzKioNCg0KPGh0dHBzOi8vd3d3LnRvcm9udG8uY2EvY2l0eS1nb3Zlcm5tZW50L2RhdGEtcmVzZWFyY2gtbWFwcy9vcGVuLWRhdGEvb3Blbi1kYXRhLWNhdGFsb2d1ZS8jMjliNmZhZGYtMGJkNi0yYWY5LTRhOGMtOGM0MWRhMjg1YWQ3Pg0KDQo+IE93bmVyOiBDaXR5IENsZXJrJ3MgT2ZmaWNlDQo+DQo+IEN1cnJlbmN5OiBBdWd1c3QgMjAxOA0KDQoqKjQ0IFdhcmQgTW9kZWwgLSBNYXkgMjAxMCAoV0dTODQgLSBMYXRpdHVkZSAvIExvbmdpdHVkZSkqKg0KDQo8aHR0cDovL29wZW5kYXRhLnRvcm9udG8uY2EvZ2NjL3dhcmRzX21heTIwMTBfd2dzODQuemlwPg0KDQpTaGFwZWZpbGU6IGljaXR3X3dnczg0IA0KDQpyZWFkbWUudHh0Og0KDQo+IFdhcmRzOiBUaGVyZSBhcmUgYSB0b3RhbCBvZiA0NCBlbGVjdG9yYWwgd2FyZHMgaW4gdGhlIENpdHkgb2YgVG9yb250byAgDQo+ICogR0VPX0lEID0gdW5pcXVlIGdlb2dyYXBoaWMgaWRlbnRpZmllciAgICANCj4gKiBOQU1FID0gTmFtZSBvZiB0aGUgV2FyZCB3aXRoIGNvcnJlc3BvbmRpbmcgd2FyZCBudW1iZXIgICAgDQo+ICogU0NPREVfTkFNRSA9IFdhcmQgTnVtYmVyICAgIA0KPiAqIExDT0RFX05BTUUgPSBXYXJkIE51bWJlciBhbmQgdGhlIGNvbW11bml0eSBjb3VuY2lsIGFyZWEgaXQgaXMgaW4gKE4sUywgRSBvciBXKSAgICANCj4gKiBUWVBFX0RFU0MgPSBXYXJkICAgIA0KPiAqIFRZUEVfQ09ERSA9IENpdHkgV2FyZCAgICANCg0KV2Ugc2hhbGwgaW5wdXQgd2FyZHMgc2hhcGVmaWxlLCBjcmVhdGUgY2VudHJvaWRzIG9mIHdhcmRzLCBhbmQgcHJvY2VzcyBzaGFwZWZpbGUgYXMgZGF0YWZyYW1lLiBGaXJzdA0Kd2UgaW5wdXQgdGhlIHNoYXBlZmlsZQ0KYGBge3J9DQp3YXJkcy5zaCA8LSByZWFkT0dSKCJDOi9Vc2Vycy8xNDE2NS9EZXNrdG9wL0FyY0dJUy9TSEFQRUZJTEVTL01heTIwMTBfV0dTODQiLCAiaWNpdHdfd2dzODQiKQ0KYGBgDQpBZGQgImlkIiBjb2x1bW4NCmBgYHtyfQ0Kd2FyZHMuc2hAZGF0YSRpZCA8LSBhcy5pbnRlZ2VyKHdhcmRzLnNoQGRhdGEkU0NPREVfTkFNRSkNCmBgYA0KTWFrZSBjZW50cm9pZHMgb2YgZWFjaCB3YXJkLCBmb3IgcGxhY2luZyBsYWJlbHMgd2hlbiBwbG90dGluZw0KYGBge3J9DQp3YXJkcy5zaC5jZW50cm9pZHMgIDwtIGFzLmRhdGEuZnJhbWUoZ0NlbnRyb2lkKHdhcmRzLnNoLCBieWlkID0gVFJVRSkpDQpgYGANCkFkZCAiaWQiIGNvbHVtbg0KYGBge3J9DQp3YXJkcy5zaC5jZW50cm9pZHMkaWQgPC0gd2FyZHMuc2hAZGF0YSRpZA0KYGBgDQpTaGFwZWZpbGUgcHJvY2Vzc2luZw0KYGBge3J9DQp3YXJkcy5zaC5wb2ludHMgPSBmb3J0aWZ5KHdhcmRzLnNoLCByZWdpb249ImlkIikNCndhcmRzLnNoLmRmID0gam9pbih3YXJkcy5zaC5wb2ludHMsIHdhcmRzLnNoQGRhdGEsIGJ5PSJpZCIpDQpgYGANCk1lcmdlIHdhcmQgc2hhcGVmaWxlIGFuZCBvd193YXJkc18yMDEwX21vbnRobHkgZGF0YWZyYW1lDQpgYGB7cn0NCndhcmRzLnNoLm93XzIwMTAgPC0gbWVyZ2Uod2FyZHMuc2guZGYsIG93X3dhcmRzXzIwMTBfbW9udGhseSwgYnkgPSAiaWQiKQ0KYGBgDQpNYWtlIGdyYXBoaWNzIG9iamVjdCBmb3Igd2FyZHMuc2gub3dfMjAxMA0KYGBge3J9DQpwLndhcmRzXzIwMTAgPC0gZ2dwbG90KCkgKyANCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3YXJkcy5zaC5vd18yMDEwLCANCiAgICAgICAgICAgICAgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IE1FQU5fQ0FTRVNfUEVSX01PTlRIKSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuMjUpICsgIA0KICBjb29yZF9tYXAoKSArIA0KICBzY2FsZV9maWxsX2Rpc3RpbGxlcihuYW1lPSJDYXNlcyIsIHBhbGV0dGUgPSAiWWxPckJyIiwgdHJhbnMgPSAicmV2ZXJzZSIsIGJyZWFrcyA9IHByZXR0eV9icmVha3MobiA9IDgpKSArIA0KICB0aGVtZV9ub3RoaW5nKGxlZ2VuZCA9IFRSVUUpICsgDQogIGxhYnModGl0bGU9Ik1lYW4gbW9udGhseSBudW1iZXIgb2YgT250YXJpbyBXb3JrcyBjYXNlcyBieSB3YXJkIGluIFRvcm9udG8gaW4gMjAxMCIpICsgDQogIGdlb21fdGV4dChhZXMoeD14LCB5PXksIGdyb3VwPU5VTEwsIGxhYmVsPWlkKSwgZGF0YSA9IHdhcmRzLnNoLmNlbnRyb2lkcywgc2l6ZSA9IDIpDQpgYGANClBsb3QgZ3JhcGhpY3Mgb2JqZWN0DQpgYGB7cn0NCnAud2FyZHNfMjAxMCArIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgI2dncGxvdDINCmBgYA0KQ2FsY3VsYXRlIG1lYW4gbnVtYmVyIG9mIGNhc2VzIGluIDIwMTMgYnkgbW9udGggYW5kIHdhcmQNCmBgYHtyfQ0Kb3dfd2FyZHNfMjAxMyA8LSBvd19jYXNlc19kcm9wbmFbWUVBUl9OVU09PTIwMTMsLihUT1RBTF9DQVNFUz1zdW0oQ0FTRVMpKSxieT0uKE1OVEgsIFdBUkRfU0NPREUpXQ0KDQpvd193YXJkc18yMDEzX21vbnRocyA8LSBvd193YXJkc18yMDEzWywuKE1PTlRITFlfQ0FTRVM9c3VtKFRPVEFMX0NBU0VTKSksYnk9LihNTlRILCBXQVJEX1NDT0RFKV0NCg0Kb3dfd2FyZHNfMjAxM19tb250aGx5IDwtIG93X3dhcmRzXzIwMTNfbW9udGhzWywuKE1FQU5fQ0FTRVNfUEVSX01PTlRIPW1lYW4oTU9OVEhMWV9DQVNFUykpLGJ5PS4oV0FSRF9TQ09ERSldIA0KYGBgDQpBZGQgImlkIiBjb2x1bW4NCmBgYHtyfQ0Kb3dfd2FyZHNfMjAxM19tb250aGx5JGlkIDwtIG93X3dhcmRzXzIwMTNfbW9udGhseSRXQVJEX1NDT0RFDQpgYGANCk1lcmdlIHdhcmQgc2hhcGVmaWxlIGFuZCBvd193YXJkc18yMDEzX21vbnRobHkgZGF0YWZyYW1lDQpgYGB7cn0NCndhcmRzLnNoLm93XzIwMTMgPC0gbWVyZ2Uod2FyZHMuc2guZGYsIG93X3dhcmRzXzIwMTNfbW9udGhseSwgYnkgPSAiaWQiKQ0KYGBgDQpNYWtlIGdyYXBoaWNzIG9iamVjdA0KYGBge3J9DQpwLndhcmRzXzIwMTMgPC0gZ2dwbG90KCkgKyANCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3YXJkcy5zaC5vd18yMDEzLCANCiAgICAgICAgICAgICAgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IE1FQU5fQ0FTRVNfUEVSX01PTlRIKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjI1KSArIA0KICBjb29yZF9tYXAoKSArIA0KICBzY2FsZV9maWxsX2Rpc3RpbGxlcihuYW1lPSJDYXNlcyIsIHBhbGV0dGUgPSAiWWxPckJyIiwgdHJhbnMgPSAicmV2ZXJzZSIsIGJyZWFrcyA9IHByZXR0eV9icmVha3MobiA9IDgpKSArIA0KICB0aGVtZV9ub3RoaW5nKGxlZ2VuZCA9IFRSVUUpICsgDQogIGxhYnModGl0bGU9Ik1lYW4gbW9udGhseSBudW1iZXIgb2YgT250YXJpbyBXb3JrcyBjYXNlcyBieSB3YXJkIGluIFRvcm9udG8gaW4gMjAxMyIpICsgDQogIGdlb21fdGV4dChhZXMoeD14LHk9eSwgZ3JvdXA9TlVMTCwgbGFiZWw9aWQpLCBkYXRhID0gd2FyZHMuc2guY2VudHJvaWRzLCBzaXplPTIpDQpgYGANClBsb3QgZ3JhcGhpY3Mgb2JqZWN0DQpgYGB7cn0NCnAud2FyZHNfMjAxMyArIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgI2dncGxvdDINCmBgYA0KQ2FsY3VsYXRlIG1lYW4gbnVtYmVyIG9mIGNhc2VzIGluIDIwMTMgYnkgbW9udGggYW5kIG5laWdoYm91cmhvb2QNCmBgYHtyfQ0Kb3dfbmJkc18yMDEzIDwtIG93X2Nhc2VzX2Ryb3BuYVtZRUFSX05VTT09MjAxMywuKFRPVEFMX0NBU0VTPXN1bShDQVNFUykpLGJ5PS4oTU5USCwgQ0VOU1VTX05FSUdIX1NDT0RFKV0NCg0Kb3dfbmJkc18yMDEzX21vbnRocyA8LSBvd19uYmRzXzIwMTNbLC4oTU9OVEhMWV9DQVNFUz1zdW0oVE9UQUxfQ0FTRVMpKSxieT0uKE1OVEgsIENFTlNVU19ORUlHSF9TQ09ERSldDQoNCm93X25iZHNfMjAxM19tb250aGx5IDwtIG93X25iZHNfMjAxM19tb250aHNbLC4oTUVBTl9DQVNFU19QRVJfTU9OVEg9bWVhbihNT05USExZX0NBU0VTKSksYnk9LihDRU5TVVNfTkVJR0hfU0NPREUpXQ0KYGBgDQpBZGQgImlkIiBjb2x1bW4NCmBgYHtyfQ0Kb3dfbmJkc18yMDEzX21vbnRobHkkaWQgPC0gb3dfbmJkc18yMDEzX21vbnRobHkkQ0VOU1VTX05FSUdIX1NDT0RFDQpgYGANCkRvaW5nIGZpbmVyIGFnZ3JlZ2F0aW9uOiBtZWFuIG1vbnRobHkgY2FzZXMgd2hvIGFyZSBzaW5nbGUgKHdpdGhvdXQgZGVwZW5kZW50cykNCmBgYHtyfQ0Kb3dfc2luZ2xlcyA8LSB0ZXNzX2R0W0ZBTUlMWV9UWVBfTk09PSJTaW5nbGVzIiwuKFlFQVJfTlVNLCBNTlRILCBXQVJEX1NDT0RFLCBDRU5TVVNfTkVJR0hfU0NPREUsIENBU0VTKV0NCg0Kb3dfc2luZ2xlc19kcm9wbmEgPC0gbmEub21pdChvd19zaW5nbGVzLCBjb2xzPWMoIkNFTlNVU19ORUlHSF9TQ09ERSIsICJXQVJEX1NDT0RFIikpDQoNCm93X3NpbmdsZXNfd2FyZHNfMjAxMyA8LSBvd19zaW5nbGVzX2Ryb3BuYVtZRUFSX05VTT09MjAxMywuKFRPVEFMX0NBU0VTPXN1bShDQVNFUykpLGJ5PS4oTU5USCwgV0FSRF9TQ09ERSldDQoNCm93X3NpbmdsZXNfd2FyZHNfMjAxM19tb250aHMgPC0gb3dfc2luZ2xlc193YXJkc18yMDEzWywuKE1PTlRITFlfQ0FTRVM9c3VtKFRPVEFMX0NBU0VTKSksYnk9LihNTlRILCBXQVJEX1NDT0RFKV0NCg0Kb3dfc2luZ2xlc193YXJkc18yMDEzX21vbnRobHkgPC0gb3dfc2luZ2xlc193YXJkc18yMDEzX21vbnRoc1ssLihNRUFOX0NBU0VTX1BFUl9NT05USD1tZWFuKE1PTlRITFlfQ0FTRVMpKSxieT0uKFdBUkRfU0NPREUpXQ0KYGBgDQpBZGQgImlkIiBjb2x1bW4NCmBgYHtyfQ0Kb3dfc2luZ2xlc193YXJkc18yMDEzX21vbnRobHkkaWQgPC0gb3dfc2luZ2xlc193YXJkc18yMDEzX21vbnRobHkkV0FSRF9TQ09ERQ0KYGBgDQpNZXJnZSB3YXJkIHNoYXBlZmlsZSBhbmQgT250YXJpbyBXb3JrcyBkYXRhZnJhbWUNCmBgYHtyfQ0Kd2FyZHMuc2gub3dfc2luZ2xlc18yMDEzIDwtIG1lcmdlKHdhcmRzLnNoLmRmLCBvd19zaW5nbGVzX3dhcmRzXzIwMTNfbW9udGhseSwgYnkgPSAiaWQiKQ0KYGBgDQpXZSBzaGFsbCBwbG90IHdhcmRzLnNoLm93X3NpbmdsZXNfMjAxMy4gTWFrZSBncmFwaGljcyBvYmplY3QNCmBgYHtyfQ0KcC53YXJkc19zaW5nbGVzXzIwMTMgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3BvbHlnb24oZGF0YSA9IHdhcmRzLnNoLm93X3NpbmdsZXNfMjAxMywgDQogICAgICAgICAgICAgICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXAsIGZpbGwgPSBNRUFOX0NBU0VTX1BFUl9NT05USCksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC4yNSkgKyANCiAgY29vcmRfbWFwKCkgKyANCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIobmFtZT0iQ2FzZXMiLCBwYWxldHRlID0gIlB1UmQiLCB0cmFucyA9ICJyZXZlcnNlIiwgYnJlYWtzID0gcHJldHR5X2JyZWFrcyhuID0gOCkpICsgDQogIHRoZW1lX25vdGhpbmcobGVnZW5kID0gVFJVRSkgKyANCiAgbGFicyh0aXRsZT0iTWVhbiBtb250aGx5IG51bWJlciBvZiBPbnRhcmlvIFdvcmtzIGNhc2VzIChzaW5nbGVzKSBieSB3YXJkIGluIFRvcm9udG8gaW4gMjAxMyIpICsgDQogIGdlb21fdGV4dChhZXMoeD14LHk9eSwgZ3JvdXA9TlVMTCwgbGFiZWw9aWQpLCBkYXRhID0gd2FyZHMuc2guY2VudHJvaWRzLCBzaXplID0gMikNCmBgYA0KUGxvdCBncmFwaGljcyBvYmplY3QNCmBgYHtyfQ0KcC53YXJkc19zaW5nbGVzXzIwMTMgKyBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpDQpgYGANCg0KIyBQbG90dGluZyBkYXRhIGJ5IG5laWdoYm91cmhvb2RzDQoNCioqTmVpZ2hib3VyaG9vZHMgc2hhcGVmaWxlKioNCg0KPGh0dHBzOi8vd3d3LnRvcm9udG8uY2EvY2l0eS1nb3Zlcm5tZW50L2RhdGEtcmVzZWFyY2gtbWFwcy9vcGVuLWRhdGEvb3Blbi1kYXRhLWNhdGFsb2d1ZS8jYTQ1YmQ0NWEtZWRlOC03MzBlLTFhYmMtOTMxMDViMmM0MzlmPg0KDQo8aHR0cDovL29wZW5kYXRhLnRvcm9udG8uY2EvZ2NjL25laWdoYm91cmhvb2RzX3BsYW5uaW5nX2FyZWFzX3dnczg0LnppcD4NCg0KPiBPd25lcjogU29jaWFsIERldmVsb3BtZW50LCBGaW5hbmNlICYgQWRtaW5pc3RyYXRpb24NCj4NCj4gQ3VycmVuY3k6IEp1bmUgMjAxNA0KDQoqKk5laWdoYm91cmhvb2RzIChXR1M4NCkqKg0KDQpTaGFwZWZpbGU6IE5FSUdIQk9SSE9PRFNfV0dTODQNCg0KTkVJR0hCT1JIT09EU19XR1M4NF9yZWFkbWUudHh0Og0KDQo+IE5FSUdIQk9SSE9PRFNfV0dTODRfcmVhZG1lICANCj4gKiBDb2x1bW4gbmFtZSAgKERlc2NyaXB0aW9uKSAgICANCj4gKiBBUkVBX1NfQ0QgPSBBUkVBX1NIT1JUX0NPREUgICAgDQo+ICogQVJFQV9OQU1FID0gQVJFQV9OQU1FICAgIA0KDQpJbnB1dCBzaGFwZWZpbGUNCmBgYHtyfQ0KbmJkcy5zaCA8LSByZWFkT0dSKCJDOi9Vc2Vycy8xNDE2NS9EZXNrdG9wL0FyY0dJUy9TSEFQRUZJTEVTL25laWdoYm91cmhvb2RzX3BsYW5uaW5nX2FyZWFzX3dnczg0IiwgIk5FSUdIQk9SSE9PRFNfV0dTODQiKQ0KYGBgDQpBZGQgImlkIiBjb2x1bW4NCmBgYHtyfQ0KbmJkcy5zaEBkYXRhJGlkIDwtIGFzLmludGVnZXIobmJkcy5zaEBkYXRhJEFSRUFfU19DRCkNCmBgYA0KTWFrZSBjZW50cm9pZHMgb2YgZWFjaCBuZWlnaGJvdXJob29kLCBmb3IgcGxhY2luZyBsYWJlbHMgd2hlbiBwbG90dGluZw0KYGBge3J9DQpuYmRzLnNoLmNlbnRyb2lkcyAgPC0gYXMuZGF0YS5mcmFtZShnQ2VudHJvaWQobmJkcy5zaCwgYnlpZCA9IFRSVUUpKQ0KYGBgDQpBZGQgImlkIiBjb2x1bW4NCmBgYHtyfQ0KbmJkcy5zaC5jZW50cm9pZHMkaWQgPC0gbmJkcy5zaEBkYXRhJGlkDQpgYGANClNoYXBlZmlsZSBwcm9jZXNzaW5nDQpgYGB7cn0NCm5iZHMuc2gucG9pbnRzID0gZm9ydGlmeShuYmRzLnNoLCByZWdpb24gPSAiaWQiKQ0KbmJkcy5zaC5kZiA9IGpvaW4obmJkcy5zaC5wb2ludHMsIG5iZHMuc2hAZGF0YSwgYnkgPSAiaWQiKQ0KYGBgDQpNZXJnZSBuZWlnaGJvdXJob29kIHNoYXBlZmlsZSBhbmQgT250YXJpbyBXb3JrcyBkYXRhZnJhbWUNCmBgYHtyfQ0KbmJkcy5zaC5vd18yMDEzIDwtIG1lcmdlKG5iZHMuc2guZGYsIG93X25iZHNfMjAxM19tb250aGx5LCBieSA9ICJpZCIpDQpgYGANCk1ha2UgZ3JhcGhpY3Mgb2JqZWN0DQpgYGB7cn0NCnAubmJkc18yMDEzIDwtIGdncGxvdCgpICsNCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBuYmRzLnNoLm93XzIwMTMsIA0KICAgICAgICAgICAgICAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwLCBmaWxsID0gTUVBTl9DQVNFU19QRVJfTU9OVEgpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuMikgKyANCiAgY29vcmRfbWFwKCkgKyANCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIobmFtZT0iQ2FzZXMiLCBwYWxldHRlID0gIllsT3JCciIsIHRyYW5zID0gInJldmVyc2UiLCBicmVha3MgPSBwcmV0dHlfYnJlYWtzKG4gPSA4KSkgKyANCiAgdGhlbWVfbm90aGluZyhsZWdlbmQgPSBUUlVFKSArIA0KICBsYWJzKHRpdGxlPSJNZWFuIG1vbnRobHkgbnVtYmVyIG9mIE9udGFyaW8gV29ya3MgY2FzZXMgYnkgbmVpZ2hib3VyaG9vZCBpbiBUb3JvbnRvIGluIDIwMTMiKSArIA0KICBnZW9tX3RleHQoYWVzKHg9eCx5PXksIGdyb3VwPU5VTEwsIGxhYmVsPWlkKSwgZGF0YSA9IG5iZHMuc2guY2VudHJvaWRzLCBzaXplID0gMikNCmBgYA0KUGxvdCBncmFwaGljcyBvYmplY3QNCmBgYHtyfQ0KcC5uYmRzXzIwMTMrZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KYGBgDQoNCg0KDQojIFRpbWUgc2VyaWVzDQoNCkF2cmlsIENvZ2hsYW4sIFtVc2luZyBSIGZvciBUaW1lIFNlcmllcyBBbmFseXNpc10oaHR0cHM6Ly9hLWxpdHRsZS1ib29rLW9mLXItZm9yLXRpbWUtc2VyaWVzLnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC9zcmMvdGltZXNlcmllcy5odG1sKQ0KDQpWaW5jZW50IFpvb25la3luZCwgW1RpbWUgc2VyaWVzXShodHRwOi8vem9vbmVrMi5mcmVlLmZyL1VOSVgvNDhfUi8xNS5odG1sKQ0KDQoNCg0KIyMgVEVTUyBPbnRhcmlvIFdvcmtzIGRhdGEgbWFuaXB1bGF0aW9uDQoNCkdyb3VwIGJ5IG1vbnRoIGFuZCBjcmVhdGUgdGltZSBzZXJpZXM6DQpgYGB7cn0NCm93X2Nhc2VzX21vbnRocyA8LSB0ZXNzX2R0WywuKE1OVEgsIENBU0VTLCBORVdfQ0FTRVMsIEVYSVRTKV0NCg0Kb3dfY2FzZXNfbW9udGhseSA8LSBvd19jYXNlc19tb250aHNbLC4oQ0FTRVM9c3VtKENBU0VTKSwgTkVXX0NBU0VTPXN1bShORVdfQ0FTRVMpLCBFWElUUz1zdW0oRVhJVFMpKSxieT0uKE1OVEgpXQ0KDQpvd19jYXNlc19tb250aGx5JE1OVEggPC0gTlVMTA0KDQpoZWFkKG93X2Nhc2VzX21vbnRobHkpDQpgYGANCg0KYGBge3J9DQpvd190cyA8LSB0cyhvd19jYXNlc19tb250aGx5LCBzdGFydCA9IGMoMjAwNCwxKSwgZnJlcXVlbmN5ID0gMTIpDQoNCmhlYWQob3dfdHMpDQpgYGANCg0KIyMgVEVTUyBPbnRhcmlvIFdvcmtzIHBsb3RzDQoNClBsb3QgdGltZSBzZXJpZXMNCmBgYHtyfQ0Kb3B0aW9ucyhzY2lwZW49OTk5KSAjZG8gbm90IHVzZSBzY2llbnRpZmljIG5vdGF0aW9uDQoNCnBsb3Qob3dfdHMpDQpgYGANCg0KTWFrZSB0aW1lIHNlcmllcyBvZiBDQVNFUw0KDQpgYGB7cn0NCkNBU0VTIDwtIHRzKG93X2Nhc2VzX21vbnRobHkkQ0FTRVMsIHN0YXJ0ID0gYygyMDA0LDEpLCBmcmVxdWVuY3kgPSAxMikNCg0KcGxvdChDQVNFUykNCmBgYA0KDQpNYWtlIHRpbWUgc2VyaWVzIG9mIE5FV19DQVNFUw0KDQpgYGB7cn0NCk5FV19DQVNFUyA8LSB0cyhvd19jYXNlc19tb250aGx5JE5FV19DQVNFUywgc3RhcnQgPSBjKDIwMDQsMSksIGZyZXF1ZW5jeSA9IDEyKQ0KDQpwbG90KE5FV19DQVNFUykNCmBgYA0KDQoNCiMjIERlY29tcG9zaW5nIHRpbWUgc2VyaWVzIGludG8gdHJlbmQsIHNlYXNvbmFsLCBhbmQgcmVtYWluZGVyIHRlcm1zDQoNCk5vdyB3ZSB1c2Ugc3RhdHM6OmRlY29tcG9zZSBhbmQgc3RhdHM6OnN0bCB0byBzZXBhcmF0ZSB0aW1lIHNlcmllcyBhcyBhIHN1bSBvZiANCnRyZW5kLCBzZWFzb25hbCwgYW5kIHJlbWFpbmRlciB0ZXJtcy4NCg0KYGBge3J9DQpDQVNFU19jb21wb25lbnRzIDwtIGRlY29tcG9zZShDQVNFUykNCmBgYA0KDQpgYGB7cn0NCmF1dG9wbG90KENBU0VTX2NvbXBvbmVudHMpDQpgYGANCg0KYGBge3J9DQpORVdfQ0FTRVNfY29tcG9uZW50cyA8LSBkZWNvbXBvc2UoTkVXX0NBU0VTKQ0KYGBgDQoNCmBgYHtyfQ0KYXV0b3Bsb3QoTkVXX0NBU0VTX2NvbXBvbmVudHMpDQpgYGANCg0KYGBge3J9DQpDQVNFUy5zdGwgPC0gc3RsKENBU0VTLCBzLndpbmRvdyA9ICJwZXJpb2RpYyIpDQpgYGANCg0KYGBge3J9DQphdXRvcGxvdChDQVNFUy5zdGwpDQpgYGANCg0KYGBge3J9DQpORVdfQ0FTRVMuc3RsIDwtIHN0bChORVdfQ0FTRVMsIHMud2luZG93ID0gInBlcmlvZGljIikNCmBgYA0KDQpgYGB7cn0NCmF1dG9wbG90KE5FV19DQVNFUy5zdGwpDQpgYGANCg0KDQojIyBIb2x0LVdpbnRlcnMgZXhwb25lbnRpYWwgc21vb3RoaW5nDQoNCmBgYHtyfQ0KQ0FTRVMuSFcgPC0gSG9sdFdpbnRlcnMoQ0FTRVMpDQoNCkNBU0VTLkhXDQpgYGANCg0KYGBge3J9DQpwbG90KENBU0VTLkhXKQ0KYGBgDQoNCmBgYHtyfQ0KQ0FTRVMuSFcuZm9yZWNhc3QgPC0gZm9yZWNhc3QoQ0FTRVMuSFcsIGggPSAyNCkNCg0KcGxvdChDQVNFUy5IVy5mb3JlY2FzdCkNCmBgYA0KDQoNCiMjIEFSSU1BDQoNCmBgYHtyfQ0KQ0FTRVMuYXJpbWEgPC0gYXV0by5hcmltYShDQVNFUykNCmBgYA0KDQpgYGB7cn0NCkNBU0VTLmFyaW1hDQpgYGANCg0KDQpgYGB7cn0NCm9wIDwtIHBhcihtZnJvdz1jKDIsMSksIG1hcj1jKDIsNCwxLDIpKy4xKQ0KYWNmKENBU0VTLCAgbWFpbj0iIikNCnBhY2YoQ0FTRVMsIG1haW49IiIpDQpwYXIob3ApDQpgYGANCg0KDQpgYGB7cn0NCkNBU0VTLmZvcmVjYXN0IDwtIGZvcmVjYXN0KENBU0VTLCBsZXZlbCA9IGMoOTUpLCBoID0gMjIpDQoNCnBsb3QoQ0FTRVMuZm9yZWNhc3QpDQpgYGANCg0KYGBge3J9DQpDQVNFUy5hcmltYS5mb3JlY2FzdCA8LSBmb3JlY2FzdChDQVNFUy5hcmltYSwgbGV2ZWwgPSBjKDk1KSwgaCA9IDIyKQ0KDQpwbG90KENBU0VTLmFyaW1hLmZvcmVjYXN0KQ0KYGBgDQoNCg0KDQojIyBPbnRhcmlvIE1vbnRobHkgU29jaWFsIEFzc2lzdGFuY2UgQ2FzZWxvYWRzIDE5NjktMjAxOA0KDQpgYGB7cn0NClNBIDwtIGZyZWFkKCJoaXN0b3JpY2FsX3NhX3JlY2lwaWVudHNfZGF0YXNldF9xMl8yMDE4XzE5LmNzdiIpDQoNClNBJEJlbmVmaWNpYXJpZXMgPC0gTlVMTA0KYGBgDQoNCk1ha2UgdGltZSBzZXJpZXMNCg0KYGBge3J9DQpTQV90cyA8LSB0cyhTQSRDYXNlcywgc3RhcnQgPSBjKDE5NjksMSksIGZyZXF1ZW5jeSA9IDEyKQ0KYGBgDQoNCg0KYGBge3J9DQpwbG90KFNBX3RzKQ0KYGBgDQoNCg0KYGBge3J9DQpTQV90c18xOTk3IDwtIHdpbmRvdyhTQV90cywgYygxOTk3LDEpKQ0KDQpwbG90KFNBX3RzXzE5OTcpDQpgYGANCg0KYGBge3J9DQpTQV90c18xOTk3LmNvbXBvbmVudHMgPC0gZGVjb21wb3NlKFNBX3RzXzE5OTcpDQoNCmF1dG9wbG90KFNBX3RzXzE5OTcuY29tcG9uZW50cykNCmBgYA0KDQoNCmBgYHtyfQ0KU0FfdHNfMTk5Ny5zdGwgPC0gc3RsKFNBX3RzXzE5OTcsIHMud2luZG93ID0gInBlcmlvZGljIikNCg0KYXV0b3Bsb3QoU0FfdHNfMTk5Ny5zdGwpDQpgYGANCg0KDQojIyBNYXl0cmVlIFNvY2lhbCBBc3Npc3RhbmNlIFN1bW1hcmllcw0KDQpgYGB7cn0NCk1heXRyZWVfT04gPC0gZnJlYWQoIk9OLmNzdiIpDQpgYGANCg0KYGBge3J9DQpzdHIoTWF5dHJlZV9PTikNCmBgYA0KDQoNCmBgYHtyfQ0KTWF5dHJlZV9PVy50cyA8LSB0cyhNYXl0cmVlX09OJGBPbnRhcmlvIFdvcmtzIENhc2VzYCwgc3RhcnQgPSAxOTk3LCBmcmVxdWVuY3kgPSAxKQ0KDQpNYXl0cmVlX09EU1AudHMgPC0gdHMoTWF5dHJlZV9PTiRgT0RTUCBDYXNlc2AsIHN0YXJ0ID0gMTk5NywgZnJlcXVlbmN5ID0gMSkNCmBgYA0KDQpgYGB7cn0NCnBsb3QoTWF5dHJlZV9PVy50cykNCmBgYA0KDQpgYGB7cn0NCnBsb3QoTWF5dHJlZV9PRFNQLnRzKQ0KYGBgDQoNCmBgYHtyfQ0KcGxvdChNYXl0cmVlX09EU1AudHMrTWF5dHJlZV9PVy50cykNCmBgYA0KDQojIyBTdGF0aXN0aWNzIENhbmFkYSBUYWJsZSAxMS0xMC0wMjM5LTAxDQoNCmBgYHtyfQ0KVDExMTAwMjM5MDEgPC0gZnJlYWQoIjExMTAwMjM5MDEtbm9TeW1ib2wuY3N2IikNCmBgYA0KDQpgYGB7cn0NCnN0cihUMTExMDAyMzkwMSkNCmBgYA0KDQoNCmBgYHtyfQ0KVDExMTAwMjM5MDEudHMgPC0gdHMoVDExMTAwMjM5MDEkYE51bWJlciBvZiBwZXJzb25zYCwgc3RhcnQgPSAxOTc2LCBmcmVxdWVuY3kgPSAxKQ0KDQpwbG90KFQxMTEwMDIzOTAxLnRzLCB5bGFiID0gIk51bWJlciBvZiBwZXJzb25zIiwgbWFpbiA9ICJQZXJzb25zIDE2IHllYXJzIGFuZCBvbGRlciBpbiBUb3JvbnRvIHdpdGggc29jaWFsIGFzc2lzdGFuY2UgaW5jb21lIiApDQpgYGANCg0KYGBge3J9DQpUMTExMDAyMzkwMS50c18xOTk3IDwtIHdpbmRvdyhUMTExMDAyMzkwMS50cywgYygxOTk3LDEpKQ0KDQpwbG90KFQxMTEwMDIzOTAxLnRzXzE5OTcpDQpgYGANCg0KDQpgYGB7cn0NCm9wIDwtIHBhcihtZnJvdz1jKDIsMSksIG1hcj1jKDIsNCwxLDIpKy4xKQ0KYWNmKFQxMTEwMDIzOTAxLnRzXzE5OTcsICBtYWluPSIiKQ0KcGFjZihUMTExMDAyMzkwMS50c18xOTk3LCBtYWluPSIiKQ0KcGFyKG9wKQ0KYGBgDQoNCmBgYHtyfQ0KVDExMTAwMjM5MDEudHNfMTk5Ny5mb3JlY2FzdCA8LSBmb3JlY2FzdChUMTExMDAyMzkwMS50c18xOTk3LCBsZXZlbCA9IGMoOTUpLCBoID0gMTIpDQoNCnBsb3QoVDExMTAwMjM5MDEudHNfMTk5Ny5mb3JlY2FzdCkNCmBgYA0KDQoNCmBgYHtyfQ0KVDExMTAwMjM5MDEudHNfMTk5Ny5hcmltYSA8LSBhdXRvLmFyaW1hKFQxMTEwMDIzOTAxLnRzXzE5OTcpDQoNClQxMTEwMDIzOTAxLnRzXzE5OTcuYXJpbWENCmBgYA0KDQpgYGB7cn0NClQxMTEwMDIzOTAxLnRzXzE5OTcuYXJpbWEuZm9yZWNhc3QgPC0gZm9yZWNhc3QoVDExMTAwMjM5MDEudHNfMTk5Ny5hcmltYSwgbGV2ZWwgPSBjKDk1KSwgaCA9IDUpDQoNCnBsb3QoVDExMTAwMjM5MDEudHNfMTk5Ny5hcmltYS5mb3JlY2FzdCkNCmBgYA==