Turkish Natural Gas Market


        In this part we will do some exploratory data analysis using the data that we previously gathered, cleaned and processed. That procedure can be seen in this page.


        As usual we start by reading the rds file that was created before.

df <- readRDS("natural_gas_data.rds")


The Processed RDS Data


        This RDS data file contains all the data we need and previously gathered, cleaned and processed. The RDS data can be downloaded here.


Structure of the Data


        Let’s see the structure of the dataframe natural_gas_data.rds.

str(df)
'data.frame':   1188 obs. of  8 variables:
 $ Date               : Date, format: "2018-09-01" "2018-09-02" ...
 $ Total_Trade_Volume : num  378501 680025 1371846 1018608 1317451 ...
 $ week_num           : num  35 35 36 36 36 36 36 36 36 37 ...
 $ month_num          : num  9 9 9 9 9 9 9 9 9 9 ...
 $ day_of_week        : Ord.factor w/ 7 levels "Sun"<"Mon"<"Tue"<..: 7 1 2 3 4 5 6 7 1 2 ...
 $ year_num           : num  2018 2018 2018 2018 2018 ...
 $ season             : chr  "Fall" "Fall" "Fall" "Fall" ...
 $ Gas_Reference_Price: num  1650 1650 1656 1644 1656 ...

        As seen above there are 3 columns with 1188 row and all the values in appropriate format and ready to analysis.


        This summary function give us five-number summary of our whole dataset. The median identifies the centre of a data set; the upper and lower quartiles span the middle half of a data set; and the highest and lowest observations provide additional information about the actual dispersion of the data. That is why we use the five-number summary a lot to overview measure of the spread.

summary(df)
      Date            Total_Trade_Volume    week_num       month_num     
 Min.   :2018-09-01   Min.   :  176662   Min.   : 1.00   Min.   : 1.000  
 1st Qu.:2019-06-24   1st Qu.: 3641882   1st Qu.:15.00   1st Qu.: 4.000  
 Median :2020-04-16   Median : 5310350   Median :29.00   Median : 7.000  
 Mean   :2020-04-16   Mean   : 6653710   Mean   :27.79   Mean   : 6.793  
 3rd Qu.:2021-02-07   3rd Qu.: 8139018   3rd Qu.:41.00   3rd Qu.:10.000  
 Max.   :2021-12-01   Max.   :40030842   Max.   :53.00   Max.   :12.000  
                                                                         
 day_of_week    year_num       season          Gas_Reference_Price
 Sun:170     Min.   :2018   Length:1188        Min.   :1205       
 Mon:170     1st Qu.:2019   Class :character   1st Qu.:1409       
 Tue:170     Median :2020   Mode  :character   Median :1471       
 Wed:170     Mean   :2020                      Mean   :1645       
 Thu:169     3rd Qu.:2021                      3rd Qu.:1571       
 Fri:169     Max.   :2021                      Max.   :6903       
 Sat:170                                                          


Visualization of the Data


        The code chunk below includes the code that gives us General overview of Gas Reference Prices using ggplot2 package.

ggplot(df,
       aes(x=Date,
           y=Gas_Reference_Price)) +
  geom_bar(stat = "identity",
           aes(fill=Gas_Reference_Price)) +
  theme_light() +
  geom_hline(yintercept = mean(df$Gas_Reference_Price),
             size=1,
             color="red") +
  scale_fill_gradient(name="Gas Reference Price") +
  labs(title="Daily Gas Reference Prices",
       x="Date",
       y="Gas Reference Price")


        You can see the red line and wonder what that indicates. That line is the mean of our y-axis.


        With the same approach the code chunk below includes the code that gives us General overview of Total Trade Volume using ggplot2 package.

ggplot(df,
       aes(x=Date,
           y=Total_Trade_Volume)) +
  geom_bar(stat = "identity",
           aes(fill=Total_Trade_Volume)) +
  theme_light() +
  geom_hline(yintercept = mean(df$Total_Trade_Volume),
             size=1,
             color="red") +
  scale_fill_gradient(name="Total Trade Volume") +
  labs(title="Daily Total Trade Volume",
       x="Date",
       y="Total Trade Volume")

        As seen above, compared to reference prices, total trade volume is much more volatile and tend to vary abundantly.


        This surely can be observed when we take a look at the standard deviation values of both columns.

sd(df$Total_Trade_Volume)
[1] 4872730
sd(df$Gas_Reference_Price)
[1] 616.1736


        In this part, we will use the columns that we have created back in preprocessing procedure. These columns will allow us to overview our data in terms of different time periods.

        We start by visualizing our data frame in yearly basis.

tv_years_average <- df %>%
  group_by(year_num) %>%
  summarise(mean_yearly_tv = mean(Total_Trade_Volume)) %>%
  ggplot(aes(x=year_num, y=mean_yearly_tv, fill=mean_yearly_tv)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Total_Trade_Volume),
             size=1,
             color="red") +
  labs(
    x="Years",
    y="Average Yearly Total TV",
    title="Average TV over the Years",
    fill="Average Yearly Total TV"
  )
tv_years_total <- df %>%
  group_by(year_num) %>%
  summarise(total_yearly_tv = sum(Total_Trade_Volume)) %>%
  ggplot(aes(x=year_num, y=total_yearly_tv, fill=total_yearly_tv)) +
  geom_bar(stat="identity") +
  labs(
    x="Years",
    y="Total Yearly TV",
    title="Total TV over the Years",
    fill="Total Yearly TV"
  )
gp_years_average <- df %>%
  group_by(year_num) %>%
  summarise(mean_yearly_gp = mean(Gas_Reference_Price)) %>%
  ggplot(aes(x=year_num, y=mean_yearly_gp, fill=mean_yearly_gp)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Gas_Reference_Price),
             size=1,
             color="red") +
  labs(
    x="Years",
    y="Average Yearly GRP",
    title="Average GRP over the Years",
    fill="Average Yearly GRP"
  )
gp_years_total <- df %>%
  group_by(year_num) %>%
  summarise(total_yearly_gp = sum(Gas_Reference_Price)) %>%
  ggplot(aes(x=year_num, y=total_yearly_gp, fill=total_yearly_gp)) +
  geom_bar(stat="identity") +
  labs(
    x="Years",
    y="Total Yearly GRP",
    title="Total GRP over the Years",
    fill="Total Yearly GRP"
  )
grid.arrange(gp_years_average, gp_years_total, tv_years_average, tv_years_total, ncol=2)


        Then we continue with visualizing in monthly basis.

tv_months_average <- df %>%
  group_by(month_num) %>%
  summarise(mean_monthly_tv = mean(Total_Trade_Volume)) %>%
  ggplot(aes(x=month_num, y=mean_monthly_tv, fill=mean_monthly_tv)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Total_Trade_Volume),
           size=1,
           color="red") +
  labs(
    x="Months",
    y="Average Monthly Total TV",
    title="Average TV over the Months",
    fill="Average Monthly Total TV"
  )
tv_months_total <- df %>%
  group_by(month_num) %>%
  summarise(total_monthly_tv = sum(Total_Trade_Volume)) %>%
  ggplot(aes(x=month_num, y=total_monthly_tv, fill=total_monthly_tv)) +
  geom_bar(stat="identity") +
  labs(
    x="Months",
    y="Total Monthly TV",
    title="Total TV over the Months",
    fill="Total Monthly TV"
  )
gp_months_average <- df %>%
  group_by(month_num) %>%
  summarise(mean_monthly_gp = mean(Gas_Reference_Price)) %>%
  ggplot(aes(x=month_num, y=mean_monthly_gp, fill=mean_monthly_gp)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Gas_Reference_Price),
             size=1,
             color="red") +
  labs(
    x="Months",
    y="Average Monthly GRP",
    title="Average GRP over the Months",
    fill="Average Monthly GRP"
  )

gp_months_total <- df %>%
  group_by(month_num) %>%
  summarise(total_monthly_gp = sum(Gas_Reference_Price)) %>%
  ggplot(aes(x=month_num, y=total_monthly_gp, fill=total_monthly_gp)) +
  geom_bar(stat="identity") +
  labs(
    x="Months",
    y="Total Monthly GRP",
    title="Total GRP over the Months",
    fill="Total Monthly GRP"
  )
grid.arrange(gp_months_average, gp_months_total, tv_months_average, tv_months_total, ncol=2)


        We visualize the data in weekly basis as well.

tv_weeks_average <- df %>%
  group_by(week_num) %>%
  summarise(mean_weekly_tv = mean(Total_Trade_Volume)) %>%
  ggplot(aes(x=week_num, y=mean_weekly_tv, fill=mean_weekly_tv)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Total_Trade_Volume),
           size=1,
           color="red") +
  labs(
    x="Weeks",
    y="Average Weekly Total TV",
    title="Average TV over the Weeks",
    fill="Average Weekly Total TV"
  )
tv_weeks_total <- df %>%
  group_by(week_num) %>%
  summarise(total_weekly_tv = sum(Total_Trade_Volume)) %>%
  ggplot(aes(x=week_num, y=total_weekly_tv, fill=total_weekly_tv)) +
  geom_bar(stat="identity") +
  labs(
    x="Weeks",
    y="Total Weekly TV",
    title="Total TV over the Weeks",
    fill="Total Weekly TV"
  )
gp_weeks_average <- df %>%
  group_by(week_num) %>%
  summarise(mean_weekly_gp = mean(Gas_Reference_Price)) %>%
  ggplot(aes(x=week_num, y=mean_weekly_gp, fill=mean_weekly_gp)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Gas_Reference_Price),
             size=1,
             color="red") +
  labs(
    x="Weeks",
    y="Average Weekly GRP",
    title="Average GRP over the Weeks",
    fill="Average Weekly GRP"
  )
gp_weeks_total <- df %>%
  group_by(week_num) %>%
  summarise(total_weekly_gp = sum(Gas_Reference_Price)) %>%
  ggplot(aes(x=week_num, y=total_weekly_gp, fill=total_weekly_gp)) +
  geom_bar(stat="identity") +
  labs(
    x="Weeks",
    y="Total Weekly GRP",
    title="Total GRP over the Weeks",
    fill="Total Weekly GRP"
  )
grid.arrange(gp_weeks_average, gp_weeks_total, tv_weeks_average, tv_weeks_total, ncol=2)


        And then in days of the week basis. But since prices didn’t vary considering the day of the week we excluded that part in this visualization.

tv_days_average <- df %>%
  group_by(day_of_week) %>%
  summarise(mean_daily_tv = mean(Total_Trade_Volume)) %>%
  ggplot(aes(x=day_of_week, y=mean_daily_tv, fill=mean_daily_tv)) +
  geom_bar(stat="identity") +
  labs(
    x="Days of the Week",
    y="Average Daily Total TV",
    title="Average TV over the Weekdays",
    fill="Average Daily Total TV"
  )
tv_days_total <- df %>%
  group_by(day_of_week) %>%
  summarise(total_daily_tv = sum(Total_Trade_Volume)) %>%
  ggplot(aes(x=day_of_week, y=total_daily_tv, fill=total_daily_tv)) +
  geom_bar(stat="identity") +
  labs(
    x="Days of the Week",
    y="Daily Total TV",
    title="Total TV over the Weekdays",
    fill="Daily Total TV"
  )
grid.arrange(tv_days_average, tv_days_total)


        Lastly, we visualize our data based on the season of the year.

tv_seasons_average <- df %>%
  group_by(season) %>%
  summarise(mean_seasonal_tv = mean(Total_Trade_Volume)) %>%
  ggplot(aes(x=season, y=mean_seasonal_tv, fill=mean_seasonal_tv)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Total_Trade_Volume),
             size=1,
             color="red") +
  labs(
    x="Seasons",
    y="Average Seasonal TV",
    title="Average TV over the Seasons",
    fill="Average Seasonal TV"
  )
tv_seasons_total <- df %>%
  group_by(season) %>%
  summarise(total_seasonal_tv = sum(Total_Trade_Volume)) %>%
  ggplot(aes(x=season, y=total_seasonal_tv, fill=total_seasonal_tv)) +
  geom_bar(stat="identity") +
  labs(
    x="Seasons",
    y="Total Seasonal TV",
    title="Total TV over the Seasons",
    fill="Total Seasonal TV"
  )
gp_seasons_average <- df %>%
  group_by(season) %>%
  summarise(mean_seasonal_gp = mean(Gas_Reference_Price)) %>%
  ggplot(aes(x=season, y=mean_seasonal_gp, fill=mean_seasonal_gp)) +
  geom_bar(stat="identity") +
  geom_hline(yintercept = mean(df$Gas_Reference_Price),
             size=1,
             color="red") +
  labs(
    x="Seasons",
    y="Average Seasonal GRP",
    title="Average GRP over the Seasons",
    fill="Average Seasonal GRP"
  )
gp_seasons_total <- df %>%
  group_by(season) %>%
  summarise(total_seasonal_gp = sum(Gas_Reference_Price)) %>%
  ggplot(aes(x=season, y=total_seasonal_gp, fill=total_seasonal_gp)) +
  geom_bar(stat="identity") +
  labs(
    x="Seasons",
    y="Total Seasonal GRP",
    title="Total GRP over the Seasons",
    fill="Total Seasonal GRP"
  )
grid.arrange(gp_seasons_average, gp_seasons_total, tv_seasons_average, tv_seasons_total, ncol=2)




                                                                                                                                          Thanks for reading…

Division Bell

LS0tDQp0aXRsZTogIioqQkRBLTUwMyBEaXZpc2lvbiBCZWxsIEdyb3VwIFByb2plY3QgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMqKiINCmF1dGhvcjogIiBfTXVyYXQgQ2FuIFRhxZ9hcl8sIF9OZWphdCBVxJ91ciBBa8Sxbl8sIF9ZdW51cyBFbXJlIERvxJ9hbl8sIF9FbWlyaGFuIMWeYWhpbl8iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgdG9jOiB0cnVlDQogICAgICAgIHRvY19kZXB0aDogMw0KICAgICAgICB0b2NfZmxvYXQ6DQogICAgICAgICAgICBjb2xsYXBzZWQ6IGZhbHNlDQotLS0NCjxicj4NCjxzdHlsZT4NCiNUT0Mgew0KICAgIGNvbG9yOiAjNDA0MDQwOw0KICAgIGZvbnQtc2l6ZTogMTNweDsNCiAgICBib3JkZXItY29sb3I6ICMwMDAwMDA7DQogICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIHN5c3RlbS11aSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAiU2Vnb2UgVUkiLCBSb2JvdG8sIFVidW50dTsNCn0NCmgxLnRpdGxlIHsNCiAgICBjb2xvcjogIzQwNDA0MDsNCiAgICBmb250LWZhbWlseTogLWFwcGxlLXN5c3RlbSwgc3lzdGVtLXVpLCBCbGlua01hY1N5c3RlbUZvbnQsICJTZWdvZSBVSSIsIFJvYm90bywgVWJ1bnR1Ow0KfQ0KaDQuYXV0aG9yIHsNCiAgICBjb2xvcjogIzQwNDA0MDsNCiAgICBmb250LXNpemU6IDEycHg7DQogICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIHN5c3RlbS11aSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAiU2Vnb2UgVUkiLCBSb2JvdG8sIFVidW50dTsNCn0NCmg0LmRhdGUgew0KICAgIGNvbG9yOiAjNDA0MDQwOw0KICAgIGZvbnQtc2l6ZTogMTJweDsNCiAgICBmb250LWZhbWlseTogLWFwcGxlLXN5c3RlbSwgc3lzdGVtLXVpLCBCbGlua01hY1N5c3RlbUZvbnQsICJTZWdvZSBVSSIsIFJvYm90bywgVWJ1bnR1Ow0KfQ0KYm9keSB7DQogICAgY29sb3I6ICM2OTY5Njk7DQogICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIHN5c3RlbS11aSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAiU2Vnb2UgVUkiLCBSb2JvdG8sIFVidW50dTsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjRjVGNUY1Ow0KICAgIGZvbnQtc2l6ZTogMTZweDsNCjwvc3R5bGU+DQoNCiMgJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IDxzcGFuIHN0eWxlPSJjb2xvcjojNDA0MDQwIj4qKlR1cmtpc2ggTmF0dXJhbCBHYXMgTWFya2V0Kio8L3NwYW4+DQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEluIHRoaXMgcGFydCB3ZSB3aWxsIGRvIHNvbWUgZXhwbG9yYXRvcnkgZGF0YSBhbmFseXNpcyB1c2luZyB0aGUgZGF0YSB0aGF0IHdlIHByZXZpb3VzbHkgZ2F0aGVyZWQsIGNsZWFuZWQgYW5kIHByb2Nlc3NlZC4gVGhhdCBwcm9jZWR1cmUgY2FuIGJlIHNlZW4gaW4gW3RoaXNdKGh0dHBzOi8vcGpvdXJuYWwuZ2l0aHViLmlvL21lZjA1Zy1kaXZpc2lvbi1iZWxsL3ByZV9wcm9jZXNzZWQubmIuaHRtbCkgcGFnZS4NCg0KYGBge3IsICBpbmNsdWRlID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHRpYmJsZSkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShncmlkRXh0cmEpDQpgYGANCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQXMgdXN1YWwgd2Ugc3RhcnQgYnkgcmVhZGluZyB0aGUgcmRzIGZpbGUgdGhhdCB3YXMgY3JlYXRlZCBiZWZvcmUuDQoNCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9DQpkZiA8LSByZWFkUkRTKCJuYXR1cmFsX2dhc19kYXRhLnJkcyIpDQpgYGANCg0KPGJyPg0KDQojIyAqKlRoZSBQcm9jZXNzZWQgUkRTIERhdGEqKg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBUaGlzIFJEUyBkYXRhIGZpbGUgY29udGFpbnMgYWxsIHRoZSBkYXRhIHdlIG5lZWQgYW5kIHByZXZpb3VzbHkgZ2F0aGVyZWQsIGNsZWFuZWQgYW5kIHByb2Nlc3NlZC4gVGhlIFJEUyBkYXRhIGNhbiBiZSBkb3dubG9hZGVkIFtoZXJlXShodHRwczovL3Bqb3VybmFsLmdpdGh1Yi5pby9tZWYwNWctZGl2aXNpb24tYmVsbC9uYXR1cmFsX2dhc19kYXRhLnJkcykuDQoNCjxicj4NCg0KIyMjICoqU3RydWN0dXJlIG9mIHRoZSBEYXRhKioNCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgTGV0J3Mgc2VlIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFmcmFtZSBgbmF0dXJhbF9nYXNfZGF0YS5yZHNgLg0KDQpgYGB7cn0NCnN0cihkZikNCmBgYA0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQXMgc2VlbiBhYm92ZSB0aGVyZSBhcmUgMyBjb2x1bW5zIHdpdGggMTE4OCByb3cgYW5kIGFsbCB0aGUgdmFsdWVzIGluIGFwcHJvcHJpYXRlIGZvcm1hdCBhbmQgcmVhZHkgdG8gYW5hbHlzaXMuDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFRoaXMgYHN1bW1hcnlgIGZ1bmN0aW9uIGdpdmUgdXMgZml2ZS1udW1iZXIgc3VtbWFyeSBvZiBvdXIgd2hvbGUgZGF0YXNldC4gVGhlIG1lZGlhbiBpZGVudGlmaWVzIHRoZSBjZW50cmUgb2YgYSBkYXRhIHNldDsgdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFydGlsZXMgc3BhbiB0aGUgbWlkZGxlIGhhbGYgb2YgYSBkYXRhIHNldDsgYW5kIHRoZSBoaWdoZXN0IGFuZCBsb3dlc3Qgb2JzZXJ2YXRpb25zIHByb3ZpZGUgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYWN0dWFsIGRpc3BlcnNpb24gb2YgdGhlIGRhdGEuIFRoYXQgaXMgd2h5IHdlIHVzZSB0aGUgZml2ZS1udW1iZXIgc3VtbWFyeSBhIGxvdCB0byBvdmVydmlldyBtZWFzdXJlIG9mIHRoZSBzcHJlYWQuDQoNCmBgYHtyfQ0Kc3VtbWFyeShkZikNCmBgYA0KDQo8YnI+DQoNCiMjIyAqKlZpc3VhbGl6YXRpb24gb2YgdGhlIERhdGEqKg0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBUaGUgY29kZSBjaHVuayBiZWxvdyBpbmNsdWRlcyB0aGUgY29kZSB0aGF0IGdpdmVzIHVzIGBHZW5lcmFsIG92ZXJ2aWV3IG9mIEdhcyBSZWZlcmVuY2UgUHJpY2VzYCB1c2luZyBnZ3Bsb3QyIHBhY2thZ2UuDQoNCmBgYHtyfQ0KZ2dwbG90KGRmLA0KICAgICAgIGFlcyh4PURhdGUsDQogICAgICAgICAgIHk9R2FzX1JlZmVyZW5jZV9QcmljZSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsDQogICAgICAgICAgIGFlcyhmaWxsPUdhc19SZWZlcmVuY2VfUHJpY2UpKSArDQogIHRoZW1lX2xpZ2h0KCkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGRmJEdhc19SZWZlcmVuY2VfUHJpY2UpLA0KICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICBjb2xvcj0icmVkIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KG5hbWU9IkdhcyBSZWZlcmVuY2UgUHJpY2UiKSArDQogIGxhYnModGl0bGU9IkRhaWx5IEdhcyBSZWZlcmVuY2UgUHJpY2VzIiwNCiAgICAgICB4PSJEYXRlIiwNCiAgICAgICB5PSJHYXMgUmVmZXJlbmNlIFByaWNlIikNCmBgYA0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBZb3UgY2FuIHNlZSB0aGUgcmVkIGxpbmUgYW5kIHdvbmRlciB3aGF0IHRoYXQgaW5kaWNhdGVzLiBUaGF0IGxpbmUgaXMgdGhlIG1lYW4gb2Ygb3VyIHktYXhpcy4NCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgV2l0aCB0aGUgc2FtZSBhcHByb2FjaCB0aGUgY29kZSBjaHVuayBiZWxvdyBpbmNsdWRlcyB0aGUgY29kZSB0aGF0IGdpdmVzIHVzIGBHZW5lcmFsIG92ZXJ2aWV3IG9mIFRvdGFsIFRyYWRlIFZvbHVtZWAgdXNpbmcgZ2dwbG90MiBwYWNrYWdlLg0KDQpgYGB7cn0NCmdncGxvdChkZiwNCiAgICAgICBhZXMoeD1EYXRlLA0KICAgICAgICAgICB5PVRvdGFsX1RyYWRlX1ZvbHVtZSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsDQogICAgICAgICAgIGFlcyhmaWxsPVRvdGFsX1RyYWRlX1ZvbHVtZSkpICsNCiAgdGhlbWVfbGlnaHQoKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IG1lYW4oZGYkVG90YWxfVHJhZGVfVm9sdW1lKSwNCiAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgY29sb3I9InJlZCIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChuYW1lPSJUb3RhbCBUcmFkZSBWb2x1bWUiKSArDQogIGxhYnModGl0bGU9IkRhaWx5IFRvdGFsIFRyYWRlIFZvbHVtZSIsDQogICAgICAgeD0iRGF0ZSIsDQogICAgICAgeT0iVG90YWwgVHJhZGUgVm9sdW1lIikNCmBgYA0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQXMgc2VlbiBhYm92ZSwgY29tcGFyZWQgdG8gcmVmZXJlbmNlIHByaWNlcywgdG90YWwgdHJhZGUgdm9sdW1lIGlzIG11Y2ggbW9yZSB2b2xhdGlsZSBhbmQgdGVuZCB0byB2YXJ5IGFidW5kYW50bHkuDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFRoaXMgc3VyZWx5IGNhbiBiZSBvYnNlcnZlZCB3aGVuIHdlIHRha2UgYSBsb29rIGF0IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gdmFsdWVzIG9mIGJvdGggY29sdW1ucy4NCg0KYGBge3J9DQpzZChkZiRUb3RhbF9UcmFkZV9Wb2x1bWUpDQpzZChkZiRHYXNfUmVmZXJlbmNlX1ByaWNlKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IEluIHRoaXMgcGFydCwgd2Ugd2lsbCB1c2UgdGhlIGNvbHVtbnMgdGhhdCB3ZSBoYXZlIGNyZWF0ZWQgYmFjayBpbiBwcmVwcm9jZXNzaW5nIHByb2NlZHVyZS4gVGhlc2UgY29sdW1ucyB3aWxsIGFsbG93IHVzIHRvIG92ZXJ2aWV3IG91ciBkYXRhIGluIHRlcm1zIG9mIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMuDQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBXZSBzdGFydCBieSB2aXN1YWxpemluZyBvdXIgZGF0YSBmcmFtZSBpbiB5ZWFybHkgYmFzaXMuDQoNCmBgYHtyfQ0KdHZfeWVhcnNfYXZlcmFnZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoeWVhcl9udW0pICU+JQ0KICBzdW1tYXJpc2UobWVhbl95ZWFybHlfdHYgPSBtZWFuKFRvdGFsX1RyYWRlX1ZvbHVtZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9eWVhcl9udW0sIHk9bWVhbl95ZWFybHlfdHYsIGZpbGw9bWVhbl95ZWFybHlfdHYpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGRmJFRvdGFsX1RyYWRlX1ZvbHVtZSksDQogICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgIGNvbG9yPSJyZWQiKSArDQogIGxhYnMoDQogICAgeD0iWWVhcnMiLA0KICAgIHk9IkF2ZXJhZ2UgWWVhcmx5IFRvdGFsIFRWIiwNCiAgICB0aXRsZT0iQXZlcmFnZSBUViBvdmVyIHRoZSBZZWFycyIsDQogICAgZmlsbD0iQXZlcmFnZSBZZWFybHkgVG90YWwgVFYiDQogICkNCnR2X3llYXJzX3RvdGFsIDwtIGRmICU+JQ0KICBncm91cF9ieSh5ZWFyX251bSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF95ZWFybHlfdHYgPSBzdW0oVG90YWxfVHJhZGVfVm9sdW1lKSkgJT4lDQogIGdncGxvdChhZXMoeD15ZWFyX251bSwgeT10b3RhbF95ZWFybHlfdHYsIGZpbGw9dG90YWxfeWVhcmx5X3R2KSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB4PSJZZWFycyIsDQogICAgeT0iVG90YWwgWWVhcmx5IFRWIiwNCiAgICB0aXRsZT0iVG90YWwgVFYgb3ZlciB0aGUgWWVhcnMiLA0KICAgIGZpbGw9IlRvdGFsIFllYXJseSBUViINCiAgKQ0KZ3BfeWVhcnNfYXZlcmFnZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoeWVhcl9udW0pICU+JQ0KICBzdW1tYXJpc2UobWVhbl95ZWFybHlfZ3AgPSBtZWFuKEdhc19SZWZlcmVuY2VfUHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXllYXJfbnVtLCB5PW1lYW5feWVhcmx5X2dwLCBmaWxsPW1lYW5feWVhcmx5X2dwKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbWVhbihkZiRHYXNfUmVmZXJlbmNlX1ByaWNlKSwNCiAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgY29sb3I9InJlZCIpICsNCiAgbGFicygNCiAgICB4PSJZZWFycyIsDQogICAgeT0iQXZlcmFnZSBZZWFybHkgR1JQIiwNCiAgICB0aXRsZT0iQXZlcmFnZSBHUlAgb3ZlciB0aGUgWWVhcnMiLA0KICAgIGZpbGw9IkF2ZXJhZ2UgWWVhcmx5IEdSUCINCiAgKQ0KZ3BfeWVhcnNfdG90YWwgPC0gZGYgJT4lDQogIGdyb3VwX2J5KHllYXJfbnVtKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX3llYXJseV9ncCA9IHN1bShHYXNfUmVmZXJlbmNlX1ByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeD15ZWFyX251bSwgeT10b3RhbF95ZWFybHlfZ3AsIGZpbGw9dG90YWxfeWVhcmx5X2dwKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB4PSJZZWFycyIsDQogICAgeT0iVG90YWwgWWVhcmx5IEdSUCIsDQogICAgdGl0bGU9IlRvdGFsIEdSUCBvdmVyIHRoZSBZZWFycyIsDQogICAgZmlsbD0iVG90YWwgWWVhcmx5IEdSUCINCiAgKQ0KZ3JpZC5hcnJhbmdlKGdwX3llYXJzX2F2ZXJhZ2UsIGdwX3llYXJzX3RvdGFsLCB0dl95ZWFyc19hdmVyYWdlLCB0dl95ZWFyc190b3RhbCwgbmNvbD0yKQ0KYGBgDQoNCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IFRoZW4gd2UgY29udGludWUgd2l0aCB2aXN1YWxpemluZyBpbiBtb250aGx5IGJhc2lzLg0KDQpgYGB7cn0NCnR2X21vbnRoc19hdmVyYWdlIDwtIGRmICU+JQ0KICBncm91cF9ieShtb250aF9udW0pICU+JQ0KICBzdW1tYXJpc2UobWVhbl9tb250aGx5X3R2ID0gbWVhbihUb3RhbF9UcmFkZV9Wb2x1bWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4PW1vbnRoX251bSwgeT1tZWFuX21vbnRobHlfdHYsIGZpbGw9bWVhbl9tb250aGx5X3R2KSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbWVhbihkZiRUb3RhbF9UcmFkZV9Wb2x1bWUpLA0KICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgIGNvbG9yPSJyZWQiKSArDQogIGxhYnMoDQogICAgeD0iTW9udGhzIiwNCiAgICB5PSJBdmVyYWdlIE1vbnRobHkgVG90YWwgVFYiLA0KICAgIHRpdGxlPSJBdmVyYWdlIFRWIG92ZXIgdGhlIE1vbnRocyIsDQogICAgZmlsbD0iQXZlcmFnZSBNb250aGx5IFRvdGFsIFRWIg0KICApDQp0dl9tb250aHNfdG90YWwgPC0gZGYgJT4lDQogIGdyb3VwX2J5KG1vbnRoX251bSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9tb250aGx5X3R2ID0gc3VtKFRvdGFsX1RyYWRlX1ZvbHVtZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9bW9udGhfbnVtLCB5PXRvdGFsX21vbnRobHlfdHYsIGZpbGw9dG90YWxfbW9udGhseV90dikpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgeD0iTW9udGhzIiwNCiAgICB5PSJUb3RhbCBNb250aGx5IFRWIiwNCiAgICB0aXRsZT0iVG90YWwgVFYgb3ZlciB0aGUgTW9udGhzIiwNCiAgICBmaWxsPSJUb3RhbCBNb250aGx5IFRWIg0KICApDQpncF9tb250aHNfYXZlcmFnZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkobW9udGhfbnVtKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbW9udGhseV9ncCA9IG1lYW4oR2FzX1JlZmVyZW5jZV9QcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9bW9udGhfbnVtLCB5PW1lYW5fbW9udGhseV9ncCwgZmlsbD1tZWFuX21vbnRobHlfZ3ApKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGRmJEdhc19SZWZlcmVuY2VfUHJpY2UpLA0KICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICBjb2xvcj0icmVkIikgKw0KICBsYWJzKA0KICAgIHg9Ik1vbnRocyIsDQogICAgeT0iQXZlcmFnZSBNb250aGx5IEdSUCIsDQogICAgdGl0bGU9IkF2ZXJhZ2UgR1JQIG92ZXIgdGhlIE1vbnRocyIsDQogICAgZmlsbD0iQXZlcmFnZSBNb250aGx5IEdSUCINCiAgKQ0KDQpncF9tb250aHNfdG90YWwgPC0gZGYgJT4lDQogIGdyb3VwX2J5KG1vbnRoX251bSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9tb250aGx5X2dwID0gc3VtKEdhc19SZWZlcmVuY2VfUHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4PW1vbnRoX251bSwgeT10b3RhbF9tb250aGx5X2dwLCBmaWxsPXRvdGFsX21vbnRobHlfZ3ApKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHg9Ik1vbnRocyIsDQogICAgeT0iVG90YWwgTW9udGhseSBHUlAiLA0KICAgIHRpdGxlPSJUb3RhbCBHUlAgb3ZlciB0aGUgTW9udGhzIiwNCiAgICBmaWxsPSJUb3RhbCBNb250aGx5IEdSUCINCiAgKQ0KZ3JpZC5hcnJhbmdlKGdwX21vbnRoc19hdmVyYWdlLCBncF9tb250aHNfdG90YWwsIHR2X21vbnRoc19hdmVyYWdlLCB0dl9tb250aHNfdG90YWwsIG5jb2w9MikNCmBgYA0KDQo8YnI+DQoNCiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBXZSB2aXN1YWxpemUgdGhlIGRhdGEgaW4gd2Vla2x5IGJhc2lzIGFzIHdlbGwuDQoNCmBgYHtyfQ0KdHZfd2Vla3NfYXZlcmFnZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkod2Vla19udW0pICU+JQ0KICBzdW1tYXJpc2UobWVhbl93ZWVrbHlfdHYgPSBtZWFuKFRvdGFsX1RyYWRlX1ZvbHVtZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9d2Vla19udW0sIHk9bWVhbl93ZWVrbHlfdHYsIGZpbGw9bWVhbl93ZWVrbHlfdHYpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGRmJFRvdGFsX1RyYWRlX1ZvbHVtZSksDQogICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgY29sb3I9InJlZCIpICsNCiAgbGFicygNCiAgICB4PSJXZWVrcyIsDQogICAgeT0iQXZlcmFnZSBXZWVrbHkgVG90YWwgVFYiLA0KICAgIHRpdGxlPSJBdmVyYWdlIFRWIG92ZXIgdGhlIFdlZWtzIiwNCiAgICBmaWxsPSJBdmVyYWdlIFdlZWtseSBUb3RhbCBUViINCiAgKQ0KdHZfd2Vla3NfdG90YWwgPC0gZGYgJT4lDQogIGdyb3VwX2J5KHdlZWtfbnVtKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX3dlZWtseV90diA9IHN1bShUb3RhbF9UcmFkZV9Wb2x1bWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXdlZWtfbnVtLCB5PXRvdGFsX3dlZWtseV90diwgZmlsbD10b3RhbF93ZWVrbHlfdHYpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHg9IldlZWtzIiwNCiAgICB5PSJUb3RhbCBXZWVrbHkgVFYiLA0KICAgIHRpdGxlPSJUb3RhbCBUViBvdmVyIHRoZSBXZWVrcyIsDQogICAgZmlsbD0iVG90YWwgV2Vla2x5IFRWIg0KICApDQpncF93ZWVrc19hdmVyYWdlIDwtIGRmICU+JQ0KICBncm91cF9ieSh3ZWVrX251bSkgJT4lDQogIHN1bW1hcmlzZShtZWFuX3dlZWtseV9ncCA9IG1lYW4oR2FzX1JlZmVyZW5jZV9QcmljZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9d2Vla19udW0sIHk9bWVhbl93ZWVrbHlfZ3AsIGZpbGw9bWVhbl93ZWVrbHlfZ3ApKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGRmJEdhc19SZWZlcmVuY2VfUHJpY2UpLA0KICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICBjb2xvcj0icmVkIikgKw0KICBsYWJzKA0KICAgIHg9IldlZWtzIiwNCiAgICB5PSJBdmVyYWdlIFdlZWtseSBHUlAiLA0KICAgIHRpdGxlPSJBdmVyYWdlIEdSUCBvdmVyIHRoZSBXZWVrcyIsDQogICAgZmlsbD0iQXZlcmFnZSBXZWVrbHkgR1JQIg0KICApDQpncF93ZWVrc190b3RhbCA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkod2Vla19udW0pICU+JQ0KICBzdW1tYXJpc2UodG90YWxfd2Vla2x5X2dwID0gc3VtKEdhc19SZWZlcmVuY2VfUHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXdlZWtfbnVtLCB5PXRvdGFsX3dlZWtseV9ncCwgZmlsbD10b3RhbF93ZWVrbHlfZ3ApKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHg9IldlZWtzIiwNCiAgICB5PSJUb3RhbCBXZWVrbHkgR1JQIiwNCiAgICB0aXRsZT0iVG90YWwgR1JQIG92ZXIgdGhlIFdlZWtzIiwNCiAgICBmaWxsPSJUb3RhbCBXZWVrbHkgR1JQIg0KICApDQpncmlkLmFycmFuZ2UoZ3Bfd2Vla3NfYXZlcmFnZSwgZ3Bfd2Vla3NfdG90YWwsIHR2X3dlZWtzX2F2ZXJhZ2UsIHR2X3dlZWtzX3RvdGFsLCBuY29sPTIpDQpgYGANCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQW5kIHRoZW4gaW4gZGF5cyBvZiB0aGUgd2VlayBiYXNpcy4gQnV0IHNpbmNlIHByaWNlcyBkaWRuJ3QgdmFyeSBjb25zaWRlcmluZyB0aGUgZGF5IG9mIHRoZSB3ZWVrIHdlIGV4Y2x1ZGVkIHRoYXQgcGFydCBpbiB0aGlzIHZpc3VhbGl6YXRpb24uDQoNCmBgYHtyfQ0KDQp0dl9kYXlzX2F2ZXJhZ2UgPC0gZGYgJT4lDQogIGdyb3VwX2J5KGRheV9vZl93ZWVrKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fZGFpbHlfdHYgPSBtZWFuKFRvdGFsX1RyYWRlX1ZvbHVtZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9ZGF5X29mX3dlZWssIHk9bWVhbl9kYWlseV90diwgZmlsbD1tZWFuX2RhaWx5X3R2KSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB4PSJEYXlzIG9mIHRoZSBXZWVrIiwNCiAgICB5PSJBdmVyYWdlIERhaWx5IFRvdGFsIFRWIiwNCiAgICB0aXRsZT0iQXZlcmFnZSBUViBvdmVyIHRoZSBXZWVrZGF5cyIsDQogICAgZmlsbD0iQXZlcmFnZSBEYWlseSBUb3RhbCBUViINCiAgKQ0KdHZfZGF5c190b3RhbCA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoZGF5X29mX3dlZWspICU+JQ0KICBzdW1tYXJpc2UodG90YWxfZGFpbHlfdHYgPSBzdW0oVG90YWxfVHJhZGVfVm9sdW1lKSkgJT4lDQogIGdncGxvdChhZXMoeD1kYXlfb2Zfd2VlaywgeT10b3RhbF9kYWlseV90diwgZmlsbD10b3RhbF9kYWlseV90dikpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgeD0iRGF5cyBvZiB0aGUgV2VlayIsDQogICAgeT0iRGFpbHkgVG90YWwgVFYiLA0KICAgIHRpdGxlPSJUb3RhbCBUViBvdmVyIHRoZSBXZWVrZGF5cyIsDQogICAgZmlsbD0iRGFpbHkgVG90YWwgVFYiDQogICkNCmdyaWQuYXJyYW5nZSh0dl9kYXlzX2F2ZXJhZ2UsIHR2X2RheXNfdG90YWwpDQpgYGANCg0KPGJyPg0KDQombmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgTGFzdGx5LCB3ZSB2aXN1YWxpemUgb3VyIGRhdGEgYmFzZWQgb24gdGhlIHNlYXNvbiBvZiB0aGUgeWVhci4NCg0KYGBge3J9DQoNCnR2X3NlYXNvbnNfYXZlcmFnZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2Vhc29uYWxfdHYgPSBtZWFuKFRvdGFsX1RyYWRlX1ZvbHVtZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHg9c2Vhc29uLCB5PW1lYW5fc2Vhc29uYWxfdHYsIGZpbGw9bWVhbl9zZWFzb25hbF90dikpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IG1lYW4oZGYkVG90YWxfVHJhZGVfVm9sdW1lKSwNCiAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgY29sb3I9InJlZCIpICsNCiAgbGFicygNCiAgICB4PSJTZWFzb25zIiwNCiAgICB5PSJBdmVyYWdlIFNlYXNvbmFsIFRWIiwNCiAgICB0aXRsZT0iQXZlcmFnZSBUViBvdmVyIHRoZSBTZWFzb25zIiwNCiAgICBmaWxsPSJBdmVyYWdlIFNlYXNvbmFsIFRWIg0KICApDQp0dl9zZWFzb25zX3RvdGFsIDwtIGRmICU+JQ0KICBncm91cF9ieShzZWFzb24pICU+JQ0KICBzdW1tYXJpc2UodG90YWxfc2Vhc29uYWxfdHYgPSBzdW0oVG90YWxfVHJhZGVfVm9sdW1lKSkgJT4lDQogIGdncGxvdChhZXMoeD1zZWFzb24sIHk9dG90YWxfc2Vhc29uYWxfdHYsIGZpbGw9dG90YWxfc2Vhc29uYWxfdHYpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHg9IlNlYXNvbnMiLA0KICAgIHk9IlRvdGFsIFNlYXNvbmFsIFRWIiwNCiAgICB0aXRsZT0iVG90YWwgVFYgb3ZlciB0aGUgU2Vhc29ucyIsDQogICAgZmlsbD0iVG90YWwgU2Vhc29uYWwgVFYiDQogICkNCmdwX3NlYXNvbnNfYXZlcmFnZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2Vhc29uYWxfZ3AgPSBtZWFuKEdhc19SZWZlcmVuY2VfUHJpY2UpKSAlPiUNCiAgZ2dwbG90KGFlcyh4PXNlYXNvbiwgeT1tZWFuX3NlYXNvbmFsX2dwLCBmaWxsPW1lYW5fc2Vhc29uYWxfZ3ApKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGRmJEdhc19SZWZlcmVuY2VfUHJpY2UpLA0KICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICBjb2xvcj0icmVkIikgKw0KICBsYWJzKA0KICAgIHg9IlNlYXNvbnMiLA0KICAgIHk9IkF2ZXJhZ2UgU2Vhc29uYWwgR1JQIiwNCiAgICB0aXRsZT0iQXZlcmFnZSBHUlAgb3ZlciB0aGUgU2Vhc29ucyIsDQogICAgZmlsbD0iQXZlcmFnZSBTZWFzb25hbCBHUlAiDQogICkNCmdwX3NlYXNvbnNfdG90YWwgPC0gZGYgJT4lDQogIGdyb3VwX2J5KHNlYXNvbikgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9zZWFzb25hbF9ncCA9IHN1bShHYXNfUmVmZXJlbmNlX1ByaWNlKSkgJT4lDQogIGdncGxvdChhZXMoeD1zZWFzb24sIHk9dG90YWxfc2Vhc29uYWxfZ3AsIGZpbGw9dG90YWxfc2Vhc29uYWxfZ3ApKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHg9IlNlYXNvbnMiLA0KICAgIHk9IlRvdGFsIFNlYXNvbmFsIEdSUCIsDQogICAgdGl0bGU9IlRvdGFsIEdSUCBvdmVyIHRoZSBTZWFzb25zIiwNCiAgICBmaWxsPSJUb3RhbCBTZWFzb25hbCBHUlAiDQogICkNCmdyaWQuYXJyYW5nZShncF9zZWFzb25zX2F2ZXJhZ2UsIGdwX3NlYXNvbnNfdG90YWwsIHR2X3NlYXNvbnNfYXZlcmFnZSwgdHZfc2Vhc29uc190b3RhbCwgbmNvbD0yKQ0KYGBgDQoNCjxicj4NCjxicj4NCjxicj4NCg0KJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDtfX19UaGFua3MgZm9yIHJlYWRpbmcuLi5fX18NCjxicj4NCjxicj4NCiFbRGl2aXNpb24gQmVsbF0oaHR0cHM6Ly9oZHdhbGxwYXBlcmltLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxNy8wOC8yNC8xMTA0NjAtUGlua19GbG95ZC10aGVfZGl2aXNpb25fYmVsbC1tdXNpYy5qcGcpXA==