Hide all the warnings messages

knitr::opts_chunk$set(message = FALSE, warning = FALSE)

Packages

pacman::p_load(tidyverse, # for data science
               janitor,  # to clean names
               visdat) # for NAs visualization
# uploaded the dataset to a google drive and published as csv file
happiness <- read_csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vQQlW28r9deAndL9Jq0tBy93o3273SWFSR1Rrgtn2jS37rjfJALF5dlwATtqm7SPZYctV4hJxb34azG/pub?gid=684260656&single=true&output=csv")
head(happiness) # for data exploration
## # A tibble: 6 × 11
##   `Country name`  year `Life Ladder` `Log GDP per capita` `Social support`
##   <chr>          <dbl>         <dbl>                <dbl>            <dbl>
## 1 Afghanistan     2008          3.72                 7.37            0.451
## 2 Afghanistan     2009          4.40                 7.54            0.552
## 3 Afghanistan     2010          4.76                 7.65            0.539
## 4 Afghanistan     2011          3.83                 7.62            0.521
## 5 Afghanistan     2012          3.78                 7.70            0.521
## 6 Afghanistan     2013          3.57                 7.72            0.484
## # … with 6 more variables: Healthy life expectancy at birth <dbl>,
## #   Freedom to make life choices <dbl>, Generosity <dbl>,
## #   Perceptions of corruption <dbl>, Positive affect <dbl>,
## #   Negative affect <dbl>

clean the names, removing the white spaces, etc. The manipulation of clean names is easier

happiness <- happiness %>% 
  janitor::clean_names()

check the variables

glimpse(happiness)
## Rows: 1,949
## Columns: 11
## $ country_name                     <chr> "Afghanistan", "Afghanistan", "Afghan…
## $ year                             <dbl> 2008, 2009, 2010, 2011, 2012, 2013, 2…
## $ life_ladder                      <dbl> 3.724, 4.402, 4.758, 3.832, 3.783, 3.…
## $ log_gdp_per_capita               <dbl> 7.370, 7.540, 7.647, 7.620, 7.705, 7.…
## $ social_support                   <dbl> 0.451, 0.552, 0.539, 0.521, 0.521, 0.…
## $ healthy_life_expectancy_at_birth <dbl> 50.80, 51.20, 51.60, 51.92, 52.24, 52…
## $ freedom_to_make_life_choices     <dbl> 0.718, 0.679, 0.600, 0.496, 0.531, 0.…
## $ generosity                       <dbl> 0.168, 0.190, 0.121, 0.162, 0.236, 0.…
## $ perceptions_of_corruption        <dbl> 0.882, 0.850, 0.707, 0.731, 0.776, 0.…
## $ positive_affect                  <dbl> 0.518, 0.584, 0.618, 0.611, 0.710, 0.…
## $ negative_affect                  <dbl> 0.258, 0.237, 0.275, 0.267, 0.268, 0.…

check the completeness of the dataset

Check the completeness of the dataset. The grey spots are NAs values

visdat::vis_dat(happiness)

Data exploration

Baltics countries

happiness %>% 
  filter(country_name %in% c("Latvia", "Estonia", "Lithuania")) %>%  # filter some countries
  ggplot(aes(x = year, 
             y = life_ladder, 
             color = country_name)) + 
  geom_line() +
  labs(title = "Happiness in Baltic by year", 
       y = "Happiness (0= worst, 10 = best)", 
       x = "Year", 
       color = "Country") 

Group all the variables to make many plots at once

There are some absolute value variables and some related to a survey

  • log_gdp_per_capita

  • healthy_life_expectancy_at_birth

  • life_ladder: Happiness score or subjective well-being. 0 worst, 10 best

The ones from the survey can be collapsed into one column

  • social_support

  • freedom_to_make_life_choices

  • perceptions_of_corruption

  • positive_affect

  • negative_affect

happiness %>% 
  filter(country_name %in% c("Latvia", "Estonia", "Lithuania")) %>%  # filter some countries
  # relocate one column to make it easier the pivoting later
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # now reshape the dataset
  pivot_longer(social_support:negative_affect, 
               names_to = "name_variable", 
               values_to = "name_value") %>% 
# change the name of the levels of name_variable
  mutate(name_variable = recode(name_variable, # change the variable, recoding the levels
                                freedom_to_make_life_choices = "Freedom",  # old name = new name
                                generosity = "Generosity", 
                                negative_affect = "Negative", 
                                perceptions_of_corruption = "Corruption", 
                                positive_affect = "Positive", 
                                social_support = "Support")) %>% 
  # make the plot
  ggplot(aes(x = year, 
             y = name_value, 
             color = country_name)) + 
  geom_line() +
  facet_grid(. ~ name_variable ) + 
  labs(title = "Survey results in the Baltic countries", 
       y = "Survey results", 
       color = "Country", 
       x = "Year")

Join with another dataset

It would be interesting to group by continent. I could add by hand the continent for each country, but it is much simpler if I take another database where each country has the continent information.

Take this as an example in case you want to cross some happiness variable with another one, for example, from the world bank. The key is that both databases must have a column to fit. You can also match by two columns, for example, country and year.

Googling, I found this dataset with the required information of the countries and continents https://github.com/lukes/ISO-3166-Countries-with-Regional-Codes/blob/master/all/all.csv

countries <- read_csv("https://raw.githubusercontent.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/all/all.csv")
head(countries)
## # A tibble: 6 × 11
##   name      `alpha-2` `alpha-3` `country-code` `iso_3166-2` region `sub-region` 
##   <chr>     <chr>     <chr>     <chr>          <chr>        <chr>  <chr>        
## 1 Afghanis… AF        AFG       004            ISO 3166-2:… Asia   Southern Asia
## 2 Åland Is… AX        ALA       248            ISO 3166-2:… Europe Northern Eur…
## 3 Albania   AL        ALB       008            ISO 3166-2:… Europe Southern Eur…
## 4 Algeria   DZ        DZA       012            ISO 3166-2:… Africa Northern Afr…
## 5 American… AS        ASM       016            ISO 3166-2:… Ocean… Polynesia    
## 6 Andorra   AD        AND       020            ISO 3166-2:… Europe Southern Eur…
## # … with 4 more variables: intermediate-region <chr>, region-code <chr>,
## #   sub-region-code <chr>, intermediate-region-code <chr>

For how to join different datasets, see https://www.youtube.com/watch?v=Yg-pNqzDuN4 and this https://craig.rbind.io/post/2020-03-29-asgr-2-2-joining-data/

# overwrite the old dataset
happiness <- 
  # with a new one, where we will add the name dataset, matching by the columns "country_name" from the happiness data set and "name" from the countries data set
  left_join(happiness, countries, by = c("country_name" = "name")) %>% 
  select(country_name:negative_affect, "alpha-3", "region", "sub-region")

Now I have the happiness dataset with the information of the continents (region)

summarize the life_ladder accross continents

happiness %>% 
  filter(region != "NA") %>% # remove the antartica, etc
  # calculate the mean happines by continent and year
  group_by(region, year) %>% 
  summarise(mean_happiness = mean(life_ladder)) %>% 
  # make the plot
  ggplot(aes(x = year, 
             y = mean_happiness, 
             color = region)) + 
  geom_line() +
  labs(title = "Happiness by continent and year", 
       y = "Happiness (0= worst, 10 = best)", 
       x = "Year", 
       color = "Continent") 

## summary all continents at once And I can check all the variable sby continents at once

happiness %>% 
  # first relocate one column to make it easier
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now reshape the dataset
  pivot_longer(social_support:negative_affect, 
               names_to = "happiness_variable", 
               values_to = "happiness_value") %>% 
  
  # calculate the mean value per continent
  group_by(happiness_variable, region, year) %>% 
  summarise(mean = mean(happiness_value, na.rm = T)) %>% 
  
  # change the name of the levels of name_variable
  mutate(happiness_variable = recode(happiness_variable, # change the variable, recoding the levels
                                freedom_to_make_life_choices = "Freedom",  # old name = new name
                                generosity = "Generosity", 
                                negative_affect = "Negative", 
                                perceptions_of_corruption = "Corruption", 
                                positive_affect = "Positive", 
                                social_support = "Support")) %>% 
  
  # and now plot
  ggplot(aes(x = year, 
             y = mean, 
             color = region, 
             group = region)) + 
  geom_line() +
  facet_grid(. ~ happiness_variable) + 
  labs(title = "Several variables in one plot", 
       y = "Mean value", 
       x = "Year", 
       color = "Continent")

All the variables for just for the Baltic countries

happiness %>% 
  # first relocate one column to make it easier to manipulate the variables during the pivoting
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now filter only european countries
  filter(region == "Europe") %>%  # comnent this line to check for all the world
  # now reshape the dataset
  pivot_longer(social_support:negative_affect, 
               names_to = "happiness_variable", 
               values_to = "happiness_value") %>% 
  
  # calculate the mean value per continent
  group_by(happiness_variable, country_name, year) %>% 
  summarise(mean = mean(happiness_value, na.rm = T)) %>% 
  
  # change the name of the levels of name_variable
  mutate(happiness_variable = recode(happiness_variable, # change the variable, recoding the levels
                                freedom_to_make_life_choices = "Freedom",  # old name = new name
                                generosity = "Generosity", 
                                negative_affect = "Negative", 
                                perceptions_of_corruption = "Corruption", 
                                positive_affect = "Positive", 
                                social_support = "Support")) %>% 
  
  # and now plot
  ggplot(aes(x = year, 
             y = mean, 
             color = (country_name == "Latvia"), 
             group = country_name)) + 
  geom_line(alpha = .5) +
  # change the name of levels in the legend
  scale_color_manual(values=c("Grey", "red"), 
                     labels=c("Other", "Latvia")) +
  # now generate several plots, each for one variable
  facet_grid(. ~ happiness_variable) +  # this means rows and columns, in this case, no variable ~ happiness
  labs(title = "Several variables in one plot", 
       y = "Mean value", 
       x = "Year", 
       color = "Country") 

# gghightlight

Check Latvia for all the countries. I will use the gghighlight package

see https://cran.r-project.org/web/packages/gghighlight/vignettes/gghighlight.html

pacman::p_load(gghighlight)
# copy and paste all the code
happiness %>% 
  # first relocate one column to make it easier
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now filter only european countries
  # filter(region == "Europe") %>%
  
  ggplot(aes(x = year, 
             y = life_ladder, 
             color = region, 
             group = country_name)) +
  geom_line() +
  gghighlight(country_name == "Latvia") +
  labs(title = "Life ladder, all the world", 
       y = "Life ladder", 
       x = "Year")

for the baltic countries

# copy and paste all the code
happiness %>% 
  # first relocate one column to make it easier
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now filter only european countries
  # uncomment next line to filter european countries only
  # filter(region == "Europe") %>%
  
  ggplot(aes(x = year, 
             y = life_ladder, 
             color = country_name, 
             group = country_name)) +
  geom_line() +
  gghighlight(country_name %in% c("Latvia", "Estonia", "Lithuania")) +
  labs(title = "Life ladder, all the world", 
       y = "Life ladder", 
       x = "Year")

## check the happiest

# copy and paste all the code
happiness %>% 
  # first relocate one column to make it easier
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now filter only european countries
  # uncomment next line to filter european countries only
  # filter(region == "Europe") %>%
  
  ggplot(aes(x = year, 
             y = life_ladder, 
             color = country_name, 
             group = country_name)) +
  geom_line() +
  gghighlight(life_ladder > 7.6) + # select some arbitraty threshold
  labs(title = "Life ladder, all the world", 
       y = "Life ladder", 
       x = "Year")

## and the lowest happiness score

# copy and paste all the code
happiness %>% 
  # first relocate one column to make it easier
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now filter only european countries
  # uncomment next line to filter european countries only
  # filter(region == "Europe") %>%
  
  ggplot(aes(x = year, 
             y = life_ladder, 
             color = country_name, 
             group = country_name)) +
  geom_line() +
  gghighlight(life_ladder < 3) +
  labs(title = "Life ladder, all the world", 
       y = "Life ladder", 
       x = "Year")

## top three from Europe

# copy and paste all the code
happiness %>% 
  # first relocate one column to make it easier
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region == "Europe") %>% 
  # now filter only european countries
  # uncomment next line to filter european countries only
  # filter(region == "Europe") %>%
  
  ggplot(aes(x = year, 
             y = life_ladder, 
             color = country_name, 
             group = country_name)) +
  geom_line() +
  gghighlight(max(life_ladder), max_highlight = 3L) # select the top 3

  labs(title = "Life ladder, all the world", 
       y = "Life ladder", 
       x = "Year")
## $y
## [1] "Life ladder"
## 
## $x
## [1] "Year"
## 
## $title
## [1] "Life ladder, all the world"
## 
## attr(,"class")
## [1] "labels"

no gghighlight needed

Now with all variables and no gghighligth needed

happiness %>% 
  # first relocate one column to make it easier to manipulate the variables during the pivoting
  relocate(social_support, .after = healthy_life_expectancy_at_birth) %>% 
  # filter to exclude the NA continents
  filter(region != "NA") %>% 
  # now filter only european countries
  filter(region == "Europe") %>%  # comnent this line to check for all the world
  # now reshape the dataset
  pivot_longer(social_support:negative_affect, 
               names_to = "happiness_variable", 
               values_to = "happiness_value") %>% 
  
  # calculate the mean value per continent
  group_by(happiness_variable, country_name, year) %>% 
  summarise(mean = mean(happiness_value, na.rm = T)) %>% 
  
  # change the name of the levels of name_variable
  mutate(happiness_variable = recode(happiness_variable, # change the variable, recoding the levels
                                freedom_to_make_life_choices = "Freedom",  # old name = new name
                                generosity = "Generosity", 
                                negative_affect = "Negative", 
                                perceptions_of_corruption = "Corruption", 
                                positive_affect = "Positive", 
                                social_support = "Support")) %>% 
  
  # and now plot
  ggplot(aes(x = year, 
             y = mean, 
             color = (country_name == "Latvia"), # good trick! :D
             group = country_name)) + 
  geom_line(alpha = .5) +
  # change the name of levels in the legend
  scale_color_manual(values=c("Grey", "red"), 
                     labels=c("Other", "Latvia")) +
  # now generate several plots, each for one variable
  facet_grid(. ~ happiness_variable) +  # this means rows and columns, in this case, no variable ~ happiness
  labs(title = "Several variables in one plot", 
       y = "Mean value", 
       x = "Year", 
       color = "Country") 

LS0tCnRpdGxlOiAiV29ybGQgSGFwcGluZXNzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDogCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IG5vCiAgICAgIHNtb290aF9zY3JvbGw6IG5vCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwotLS0KCkhpZGUgYWxsIHRoZSB3YXJuaW5ncyBtZXNzYWdlcwoKYGBge3J9CmtuaXRyOjpvcHRzX2NodW5rJHNldChtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkKYGBgCgojIFBhY2thZ2VzCgpgYGB7cn0KcGFjbWFuOjpwX2xvYWQodGlkeXZlcnNlLCAjIGZvciBkYXRhIHNjaWVuY2UKICAgICAgICAgICAgICAgamFuaXRvciwgICMgdG8gY2xlYW4gbmFtZXMKICAgICAgICAgICAgICAgdmlzZGF0KSAjIGZvciBOQXMgdmlzdWFsaXphdGlvbgpgYGAKCmBgYHtyfQojIHVwbG9hZGVkIHRoZSBkYXRhc2V0IHRvIGEgZ29vZ2xlIGRyaXZlIGFuZCBwdWJsaXNoZWQgYXMgY3N2IGZpbGUKaGFwcGluZXNzIDwtIHJlYWRfY3N2KCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC9lLzJQQUNYLTF2UVFsVzI4cjlkZUFuZEw5SnEwdEJ5OTNvMzI3M1NXRlNSMVJyZ3RuMmpTMzdyamZKQUxGNWRsd0FUdHFtN1NQWlljdFY0aEp4YjM0YXpHL3B1Yj9naWQ9Njg0MjYwNjU2JnNpbmdsZT10cnVlJm91dHB1dD1jc3YiKQpgYGAKCmBgYHtyfQpoZWFkKGhhcHBpbmVzcykgIyBmb3IgZGF0YSBleHBsb3JhdGlvbgpgYGAKCmNsZWFuIHRoZSBuYW1lcywgcmVtb3ZpbmcgdGhlIHdoaXRlIHNwYWNlcywgZXRjLiBUaGUgbWFuaXB1bGF0aW9uIG9mIGNsZWFuIG5hbWVzIGlzIGVhc2llcgoKYGBge3J9CmhhcHBpbmVzcyA8LSBoYXBwaW5lc3MgJT4lIAogIGphbml0b3I6OmNsZWFuX25hbWVzKCkKYGBgCgoKY2hlY2sgdGhlIHZhcmlhYmxlcwpgYGB7cn0KZ2xpbXBzZShoYXBwaW5lc3MpCmBgYAojIGNoZWNrIHRoZSBjb21wbGV0ZW5lc3Mgb2YgdGhlIGRhdGFzZXQKQ2hlY2sgdGhlIGNvbXBsZXRlbmVzcyBvZiB0aGUgZGF0YXNldC4gVGhlIGdyZXkgc3BvdHMgYXJlIE5BcyB2YWx1ZXMKCmBgYHtyfQp2aXNkYXQ6OnZpc19kYXQoaGFwcGluZXNzKQpgYGAKCgojIERhdGEgZXhwbG9yYXRpb24KCiMjIEJhbHRpY3MgY291bnRyaWVzCgpgYGB7cn0KaGFwcGluZXNzICU+JSAKICBmaWx0ZXIoY291bnRyeV9uYW1lICVpbiUgYygiTGF0dmlhIiwgIkVzdG9uaWEiLCAiTGl0aHVhbmlhIikpICU+JSAgIyBmaWx0ZXIgc29tZSBjb3VudHJpZXMKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCAKICAgICAgICAgICAgIHkgPSBsaWZlX2xhZGRlciwgCiAgICAgICAgICAgICBjb2xvciA9IGNvdW50cnlfbmFtZSkpICsgCiAgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAiSGFwcGluZXNzIGluIEJhbHRpYyBieSB5ZWFyIiwgCiAgICAgICB5ID0gIkhhcHBpbmVzcyAoMD0gd29yc3QsIDEwID0gYmVzdCkiLCAKICAgICAgIHggPSAiWWVhciIsIAogICAgICAgY29sb3IgPSAiQ291bnRyeSIpIApgYGAKCgojIyBHcm91cCBhbGwgdGhlIHZhcmlhYmxlcyB0byBtYWtlIG1hbnkgcGxvdHMgYXQgb25jZQoKVGhlcmUgYXJlIHNvbWUgYWJzb2x1dGUgdmFsdWUgdmFyaWFibGVzIGFuZCBzb21lIHJlbGF0ZWQgdG8gYSBzdXJ2ZXkKCi0gICBsb2dfZ2RwX3Blcl9jYXBpdGEKCi0gICBoZWFsdGh5X2xpZmVfZXhwZWN0YW5jeV9hdF9iaXJ0aAoKLSAgIGxpZmVfbGFkZGVyOiBIYXBwaW5lc3Mgc2NvcmUgb3Igc3ViamVjdGl2ZSB3ZWxsLWJlaW5nLiAwIHdvcnN0LCAxMCBiZXN0CgpUaGUgb25lcyBmcm9tIHRoZSBzdXJ2ZXkgY2FuIGJlIGNvbGxhcHNlZCBpbnRvIG9uZSBjb2x1bW4KCi0gICBzb2NpYWxfc3VwcG9ydAoKLSAgIGZyZWVkb21fdG9fbWFrZV9saWZlX2Nob2ljZXMKCi0gICBwZXJjZXB0aW9uc19vZl9jb3JydXB0aW9uCgotICAgcG9zaXRpdmVfYWZmZWN0CgotICAgbmVnYXRpdmVfYWZmZWN0CgoKYGBge3J9CmhhcHBpbmVzcyAlPiUgCiAgZmlsdGVyKGNvdW50cnlfbmFtZSAlaW4lIGMoIkxhdHZpYSIsICJFc3RvbmlhIiwgIkxpdGh1YW5pYSIpKSAlPiUgICMgZmlsdGVyIHNvbWUgY291bnRyaWVzCiAgIyByZWxvY2F0ZSBvbmUgY29sdW1uIHRvIG1ha2UgaXQgZWFzaWVyIHRoZSBwaXZvdGluZyBsYXRlcgogIHJlbG9jYXRlKHNvY2lhbF9zdXBwb3J0LCAuYWZ0ZXIgPSBoZWFsdGh5X2xpZmVfZXhwZWN0YW5jeV9hdF9iaXJ0aCkgJT4lIAogICMgbm93IHJlc2hhcGUgdGhlIGRhdGFzZXQKICBwaXZvdF9sb25nZXIoc29jaWFsX3N1cHBvcnQ6bmVnYXRpdmVfYWZmZWN0LCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAibmFtZV92YXJpYWJsZSIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAibmFtZV92YWx1ZSIpICU+JSAKIyBjaGFuZ2UgdGhlIG5hbWUgb2YgdGhlIGxldmVscyBvZiBuYW1lX3ZhcmlhYmxlCiAgbXV0YXRlKG5hbWVfdmFyaWFibGUgPSByZWNvZGUobmFtZV92YXJpYWJsZSwgIyBjaGFuZ2UgdGhlIHZhcmlhYmxlLCByZWNvZGluZyB0aGUgbGV2ZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZWRvbV90b19tYWtlX2xpZmVfY2hvaWNlcyA9ICJGcmVlZG9tIiwgICMgb2xkIG5hbWUgPSBuZXcgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyb3NpdHkgPSAiR2VuZXJvc2l0eSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlX2FmZmVjdCA9ICJOZWdhdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlcHRpb25zX29mX2NvcnJ1cHRpb24gPSAiQ29ycnVwdGlvbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2FmZmVjdCA9ICJQb3NpdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvY2lhbF9zdXBwb3J0ID0gIlN1cHBvcnQiKSkgJT4lIAogICMgbWFrZSB0aGUgcGxvdAogIGdncGxvdChhZXMoeCA9IHllYXIsIAogICAgICAgICAgICAgeSA9IG5hbWVfdmFsdWUsIAogICAgICAgICAgICAgY29sb3IgPSBjb3VudHJ5X25hbWUpKSArIAogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKC4gfiBuYW1lX3ZhcmlhYmxlICkgKyAKICBsYWJzKHRpdGxlID0gIlN1cnZleSByZXN1bHRzIGluIHRoZSBCYWx0aWMgY291bnRyaWVzIiwgCiAgICAgICB5ID0gIlN1cnZleSByZXN1bHRzIiwgCiAgICAgICBjb2xvciA9ICJDb3VudHJ5IiwgCiAgICAgICB4ID0gIlllYXIiKQpgYGAKCgoKCgojIEpvaW4gd2l0aCBhbm90aGVyIGRhdGFzZXQKCkl0IHdvdWxkIGJlIGludGVyZXN0aW5nIHRvIGdyb3VwIGJ5IGNvbnRpbmVudC4gCkkgY291bGQgYWRkIGJ5IGhhbmQgdGhlIGNvbnRpbmVudCBmb3IgZWFjaCBjb3VudHJ5LCBidXQgaXQgaXMgbXVjaCBzaW1wbGVyIGlmIEkgdGFrZSBhbm90aGVyIGRhdGFiYXNlIHdoZXJlIGVhY2ggY291bnRyeSBoYXMgdGhlIGNvbnRpbmVudCBpbmZvcm1hdGlvbi4gCgpUYWtlIHRoaXMgYXMgYW4gZXhhbXBsZSBpbiBjYXNlIHlvdSB3YW50IHRvIGNyb3NzIHNvbWUgaGFwcGluZXNzIHZhcmlhYmxlIHdpdGggYW5vdGhlciBvbmUsIGZvciBleGFtcGxlLCBmcm9tIHRoZSB3b3JsZCBiYW5rLiBUaGUga2V5IGlzIHRoYXQgYm90aCBkYXRhYmFzZXMgbXVzdCBoYXZlIGEgY29sdW1uIHRvIGZpdC4gWW91IGNhbiBhbHNvIG1hdGNoIGJ5IHR3byBjb2x1bW5zLCBmb3IgZXhhbXBsZSwgY291bnRyeSBhbmQgeWVhci4KCgpHb29nbGluZywgSSBmb3VuZCB0aGlzIGRhdGFzZXQgd2l0aCB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb24gb2YgdGhlIGNvdW50cmllcyBhbmQgY29udGluZW50cyBodHRwczovL2dpdGh1Yi5jb20vbHVrZXMvSVNPLTMxNjYtQ291bnRyaWVzLXdpdGgtUmVnaW9uYWwtQ29kZXMvYmxvYi9tYXN0ZXIvYWxsL2FsbC5jc3YKCmBgYHtyfQpjb3VudHJpZXMgPC0gcmVhZF9jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9sdWtlcy9JU08tMzE2Ni1Db3VudHJpZXMtd2l0aC1SZWdpb25hbC1Db2Rlcy9tYXN0ZXIvYWxsL2FsbC5jc3YiKQpgYGAKCmBgYHtyfQpoZWFkKGNvdW50cmllcykKYGBgCgoKRm9yIGhvdyB0byBqb2luIGRpZmZlcmVudCBkYXRhc2V0cywgc2VlIGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WWctcE5xekR1TjQgYW5kIHRoaXMgaHR0cHM6Ly9jcmFpZy5yYmluZC5pby9wb3N0LzIwMjAtMDMtMjktYXNnci0yLTItam9pbmluZy1kYXRhLyAKYGBge3J9CiMgb3ZlcndyaXRlIHRoZSBvbGQgZGF0YXNldApoYXBwaW5lc3MgPC0gCiAgIyB3aXRoIGEgbmV3IG9uZSwgd2hlcmUgd2Ugd2lsbCBhZGQgdGhlIG5hbWUgZGF0YXNldCwgbWF0Y2hpbmcgYnkgdGhlIGNvbHVtbnMgImNvdW50cnlfbmFtZSIgZnJvbSB0aGUgaGFwcGluZXNzIGRhdGEgc2V0IGFuZCAibmFtZSIgZnJvbSB0aGUgY291bnRyaWVzIGRhdGEgc2V0CiAgbGVmdF9qb2luKGhhcHBpbmVzcywgY291bnRyaWVzLCBieSA9IGMoImNvdW50cnlfbmFtZSIgPSAibmFtZSIpKSAlPiUgCiAgc2VsZWN0KGNvdW50cnlfbmFtZTpuZWdhdGl2ZV9hZmZlY3QsICJhbHBoYS0zIiwgInJlZ2lvbiIsICJzdWItcmVnaW9uIikKYGBgCgpOb3cgSSBoYXZlIHRoZSBoYXBwaW5lc3MgZGF0YXNldCB3aXRoIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgY29udGluZW50cyAocmVnaW9uKQoKIyBzdW1tYXJpemUgdGhlIGxpZmVfbGFkZGVyIGFjY3Jvc3MgY29udGluZW50cwoKYGBge3J9CmhhcHBpbmVzcyAlPiUgCiAgZmlsdGVyKHJlZ2lvbiAhPSAiTkEiKSAlPiUgIyByZW1vdmUgdGhlIGFudGFydGljYSwgZXRjCiAgIyBjYWxjdWxhdGUgdGhlIG1lYW4gaGFwcGluZXMgYnkgY29udGluZW50IGFuZCB5ZWFyCiAgZ3JvdXBfYnkocmVnaW9uLCB5ZWFyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5faGFwcGluZXNzID0gbWVhbihsaWZlX2xhZGRlcikpICU+JSAKICAjIG1ha2UgdGhlIHBsb3QKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCAKICAgICAgICAgICAgIHkgPSBtZWFuX2hhcHBpbmVzcywgCiAgICAgICAgICAgICBjb2xvciA9IHJlZ2lvbikpICsgCiAgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAiSGFwcGluZXNzIGJ5IGNvbnRpbmVudCBhbmQgeWVhciIsIAogICAgICAgeSA9ICJIYXBwaW5lc3MgKDA9IHdvcnN0LCAxMCA9IGJlc3QpIiwgCiAgICAgICB4ID0gIlllYXIiLCAKICAgICAgIGNvbG9yID0gIkNvbnRpbmVudCIpIApgYGAKIyMgc3VtbWFyeSBhbGwgY29udGluZW50cyBhdCBvbmNlCkFuZCBJIGNhbiBjaGVjayBhbGwgdGhlIHZhcmlhYmxlIHNieSBjb250aW5lbnRzIGF0IG9uY2UKCmBgYHtyfQpoYXBwaW5lc3MgJT4lIAogICMgZmlyc3QgcmVsb2NhdGUgb25lIGNvbHVtbiB0byBtYWtlIGl0IGVhc2llcgogIHJlbG9jYXRlKHNvY2lhbF9zdXBwb3J0LCAuYWZ0ZXIgPSBoZWFsdGh5X2xpZmVfZXhwZWN0YW5jeV9hdF9iaXJ0aCkgJT4lIAogICMgZmlsdGVyIHRvIGV4Y2x1ZGUgdGhlIE5BIGNvbnRpbmVudHMKICBmaWx0ZXIocmVnaW9uICE9ICJOQSIpICU+JSAKICAjIG5vdyByZXNoYXBlIHRoZSBkYXRhc2V0CiAgcGl2b3RfbG9uZ2VyKHNvY2lhbF9zdXBwb3J0Om5lZ2F0aXZlX2FmZmVjdCwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImhhcHBpbmVzc192YXJpYWJsZSIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiaGFwcGluZXNzX3ZhbHVlIikgJT4lIAogIAogICMgY2FsY3VsYXRlIHRoZSBtZWFuIHZhbHVlIHBlciBjb250aW5lbnQKICBncm91cF9ieShoYXBwaW5lc3NfdmFyaWFibGUsIHJlZ2lvbiwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gbWVhbihoYXBwaW5lc3NfdmFsdWUsIG5hLnJtID0gVCkpICU+JSAKICAKICAjIGNoYW5nZSB0aGUgbmFtZSBvZiB0aGUgbGV2ZWxzIG9mIG5hbWVfdmFyaWFibGUKICBtdXRhdGUoaGFwcGluZXNzX3ZhcmlhYmxlID0gcmVjb2RlKGhhcHBpbmVzc192YXJpYWJsZSwgIyBjaGFuZ2UgdGhlIHZhcmlhYmxlLCByZWNvZGluZyB0aGUgbGV2ZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZWRvbV90b19tYWtlX2xpZmVfY2hvaWNlcyA9ICJGcmVlZG9tIiwgICMgb2xkIG5hbWUgPSBuZXcgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyb3NpdHkgPSAiR2VuZXJvc2l0eSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlX2FmZmVjdCA9ICJOZWdhdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlcHRpb25zX29mX2NvcnJ1cHRpb24gPSAiQ29ycnVwdGlvbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2FmZmVjdCA9ICJQb3NpdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvY2lhbF9zdXBwb3J0ID0gIlN1cHBvcnQiKSkgJT4lIAogIAogICMgYW5kIG5vdyBwbG90CiAgZ2dwbG90KGFlcyh4ID0geWVhciwgCiAgICAgICAgICAgICB5ID0gbWVhbiwgCiAgICAgICAgICAgICBjb2xvciA9IHJlZ2lvbiwgCiAgICAgICAgICAgICBncm91cCA9IHJlZ2lvbikpICsgCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoLiB+IGhhcHBpbmVzc192YXJpYWJsZSkgKyAKICBsYWJzKHRpdGxlID0gIlNldmVyYWwgdmFyaWFibGVzIGluIG9uZSBwbG90IiwgCiAgICAgICB5ID0gIk1lYW4gdmFsdWUiLCAKICAgICAgIHggPSAiWWVhciIsIAogICAgICAgY29sb3IgPSAiQ29udGluZW50IikKYGBgCgoKIyMgQWxsIHRoZSB2YXJpYWJsZXMgZm9yIGp1c3QgZm9yIHRoZSBCYWx0aWMgY291bnRyaWVzCgpgYGB7cn0KaGFwcGluZXNzICU+JSAKICAjIGZpcnN0IHJlbG9jYXRlIG9uZSBjb2x1bW4gdG8gbWFrZSBpdCBlYXNpZXIgdG8gbWFuaXB1bGF0ZSB0aGUgdmFyaWFibGVzIGR1cmluZyB0aGUgcGl2b3RpbmcKICByZWxvY2F0ZShzb2NpYWxfc3VwcG9ydCwgLmFmdGVyID0gaGVhbHRoeV9saWZlX2V4cGVjdGFuY3lfYXRfYmlydGgpICU+JSAKICAjIGZpbHRlciB0byBleGNsdWRlIHRoZSBOQSBjb250aW5lbnRzCiAgZmlsdGVyKHJlZ2lvbiAhPSAiTkEiKSAlPiUgCiAgIyBub3cgZmlsdGVyIG9ubHkgZXVyb3BlYW4gY291bnRyaWVzCiAgZmlsdGVyKHJlZ2lvbiA9PSAiRXVyb3BlIikgJT4lICAjIGNvbW5lbnQgdGhpcyBsaW5lIHRvIGNoZWNrIGZvciBhbGwgdGhlIHdvcmxkCiAgIyBub3cgcmVzaGFwZSB0aGUgZGF0YXNldAogIHBpdm90X2xvbmdlcihzb2NpYWxfc3VwcG9ydDpuZWdhdGl2ZV9hZmZlY3QsIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJoYXBwaW5lc3NfdmFyaWFibGUiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImhhcHBpbmVzc192YWx1ZSIpICU+JSAKICAKICAjIGNhbGN1bGF0ZSB0aGUgbWVhbiB2YWx1ZSBwZXIgY29udGluZW50CiAgZ3JvdXBfYnkoaGFwcGluZXNzX3ZhcmlhYmxlLCBjb3VudHJ5X25hbWUsIHllYXIpICU+JSAKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oaGFwcGluZXNzX3ZhbHVlLCBuYS5ybSA9IFQpKSAlPiUgCiAgCiAgIyBjaGFuZ2UgdGhlIG5hbWUgb2YgdGhlIGxldmVscyBvZiBuYW1lX3ZhcmlhYmxlCiAgbXV0YXRlKGhhcHBpbmVzc192YXJpYWJsZSA9IHJlY29kZShoYXBwaW5lc3NfdmFyaWFibGUsICMgY2hhbmdlIHRoZSB2YXJpYWJsZSwgcmVjb2RpbmcgdGhlIGxldmVscwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVkb21fdG9fbWFrZV9saWZlX2Nob2ljZXMgPSAiRnJlZWRvbSIsICAjIG9sZCBuYW1lID0gbmV3IG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcm9zaXR5ID0gIkdlbmVyb3NpdHkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZV9hZmZlY3QgPSAiTmVnYXRpdmUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJjZXB0aW9uc19vZl9jb3JydXB0aW9uID0gIkNvcnJ1cHRpb24iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9hZmZlY3QgPSAiUG9zaXRpdmUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb2NpYWxfc3VwcG9ydCA9ICJTdXBwb3J0IikpICU+JSAKICAKICAjIGFuZCBub3cgcGxvdAogIGdncGxvdChhZXMoeCA9IHllYXIsIAogICAgICAgICAgICAgeSA9IG1lYW4sIAogICAgICAgICAgICAgY29sb3IgPSAoY291bnRyeV9uYW1lID09ICJMYXR2aWEiKSwgCiAgICAgICAgICAgICBncm91cCA9IGNvdW50cnlfbmFtZSkpICsgCiAgZ2VvbV9saW5lKGFscGhhID0gLjUpICsKICAjIGNoYW5nZSB0aGUgbmFtZSBvZiBsZXZlbHMgaW4gdGhlIGxlZ2VuZAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiR3JleSIsICJyZWQiKSwgCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJPdGhlciIsICJMYXR2aWEiKSkgKwogICMgbm93IGdlbmVyYXRlIHNldmVyYWwgcGxvdHMsIGVhY2ggZm9yIG9uZSB2YXJpYWJsZQogIGZhY2V0X2dyaWQoLiB+IGhhcHBpbmVzc192YXJpYWJsZSkgKyAgIyB0aGlzIG1lYW5zIHJvd3MgYW5kIGNvbHVtbnMsIGluIHRoaXMgY2FzZSwgbm8gdmFyaWFibGUgfiBoYXBwaW5lc3MKICBsYWJzKHRpdGxlID0gIlNldmVyYWwgdmFyaWFibGVzIGluIG9uZSBwbG90IiwgCiAgICAgICB5ID0gIk1lYW4gdmFsdWUiLCAKICAgICAgIHggPSAiWWVhciIsIAogICAgICAgY29sb3IgPSAiQ291bnRyeSIpIApgYGAKIyBnZ2hpZ2h0bGlnaHQKCkNoZWNrIExhdHZpYSBmb3IgYWxsIHRoZSBjb3VudHJpZXMuICBJIHdpbGwgdXNlIHRoZSBnZ2hpZ2hsaWdodCBwYWNrYWdlCgpzZWUgaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2dnaGlnaGxpZ2h0L3ZpZ25ldHRlcy9nZ2hpZ2hsaWdodC5odG1sCgpgYGB7cn0KcGFjbWFuOjpwX2xvYWQoZ2doaWdobGlnaHQpCmBgYAoKYGBge3J9CiMgY29weSBhbmQgcGFzdGUgYWxsIHRoZSBjb2RlCmhhcHBpbmVzcyAlPiUgCiAgIyBmaXJzdCByZWxvY2F0ZSBvbmUgY29sdW1uIHRvIG1ha2UgaXQgZWFzaWVyCiAgcmVsb2NhdGUoc29jaWFsX3N1cHBvcnQsIC5hZnRlciA9IGhlYWx0aHlfbGlmZV9leHBlY3RhbmN5X2F0X2JpcnRoKSAlPiUgCiAgIyBmaWx0ZXIgdG8gZXhjbHVkZSB0aGUgTkEgY29udGluZW50cwogIGZpbHRlcihyZWdpb24gIT0gIk5BIikgJT4lIAogICMgbm93IGZpbHRlciBvbmx5IGV1cm9wZWFuIGNvdW50cmllcwogICMgZmlsdGVyKHJlZ2lvbiA9PSAiRXVyb3BlIikgJT4lCiAgCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgCiAgICAgICAgICAgICB5ID0gbGlmZV9sYWRkZXIsIAogICAgICAgICAgICAgY29sb3IgPSByZWdpb24sIAogICAgICAgICAgICAgZ3JvdXAgPSBjb3VudHJ5X25hbWUpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdnaGlnaGxpZ2h0KGNvdW50cnlfbmFtZSA9PSAiTGF0dmlhIikgKwogIGxhYnModGl0bGUgPSAiTGlmZSBsYWRkZXIsIGFsbCB0aGUgd29ybGQiLCAKICAgICAgIHkgPSAiTGlmZSBsYWRkZXIiLCAKICAgICAgIHggPSAiWWVhciIpCmBgYAoKIyMgZm9yIHRoZSBiYWx0aWMgY291bnRyaWVzCgpgYGB7cn0KIyBjb3B5IGFuZCBwYXN0ZSBhbGwgdGhlIGNvZGUKaGFwcGluZXNzICU+JSAKICAjIGZpcnN0IHJlbG9jYXRlIG9uZSBjb2x1bW4gdG8gbWFrZSBpdCBlYXNpZXIKICByZWxvY2F0ZShzb2NpYWxfc3VwcG9ydCwgLmFmdGVyID0gaGVhbHRoeV9saWZlX2V4cGVjdGFuY3lfYXRfYmlydGgpICU+JSAKICAjIGZpbHRlciB0byBleGNsdWRlIHRoZSBOQSBjb250aW5lbnRzCiAgZmlsdGVyKHJlZ2lvbiAhPSAiTkEiKSAlPiUgCiAgIyBub3cgZmlsdGVyIG9ubHkgZXVyb3BlYW4gY291bnRyaWVzCiAgIyB1bmNvbW1lbnQgbmV4dCBsaW5lIHRvIGZpbHRlciBldXJvcGVhbiBjb3VudHJpZXMgb25seQogICMgZmlsdGVyKHJlZ2lvbiA9PSAiRXVyb3BlIikgJT4lCiAgCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgCiAgICAgICAgICAgICB5ID0gbGlmZV9sYWRkZXIsIAogICAgICAgICAgICAgY29sb3IgPSBjb3VudHJ5X25hbWUsIAogICAgICAgICAgICAgZ3JvdXAgPSBjb3VudHJ5X25hbWUpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdnaGlnaGxpZ2h0KGNvdW50cnlfbmFtZSAlaW4lIGMoIkxhdHZpYSIsICJFc3RvbmlhIiwgIkxpdGh1YW5pYSIpKSArCiAgbGFicyh0aXRsZSA9ICJMaWZlIGxhZGRlciwgYWxsIHRoZSB3b3JsZCIsIAogICAgICAgeSA9ICJMaWZlIGxhZGRlciIsIAogICAgICAgeCA9ICJZZWFyIikKYGBgCiMjIGNoZWNrIHRoZSBoYXBwaWVzdCAKCgpgYGB7cn0KIyBjb3B5IGFuZCBwYXN0ZSBhbGwgdGhlIGNvZGUKaGFwcGluZXNzICU+JSAKICAjIGZpcnN0IHJlbG9jYXRlIG9uZSBjb2x1bW4gdG8gbWFrZSBpdCBlYXNpZXIKICByZWxvY2F0ZShzb2NpYWxfc3VwcG9ydCwgLmFmdGVyID0gaGVhbHRoeV9saWZlX2V4cGVjdGFuY3lfYXRfYmlydGgpICU+JSAKICAjIGZpbHRlciB0byBleGNsdWRlIHRoZSBOQSBjb250aW5lbnRzCiAgZmlsdGVyKHJlZ2lvbiAhPSAiTkEiKSAlPiUgCiAgIyBub3cgZmlsdGVyIG9ubHkgZXVyb3BlYW4gY291bnRyaWVzCiAgIyB1bmNvbW1lbnQgbmV4dCBsaW5lIHRvIGZpbHRlciBldXJvcGVhbiBjb3VudHJpZXMgb25seQogICMgZmlsdGVyKHJlZ2lvbiA9PSAiRXVyb3BlIikgJT4lCiAgCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgCiAgICAgICAgICAgICB5ID0gbGlmZV9sYWRkZXIsIAogICAgICAgICAgICAgY29sb3IgPSBjb3VudHJ5X25hbWUsIAogICAgICAgICAgICAgZ3JvdXAgPSBjb3VudHJ5X25hbWUpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdnaGlnaGxpZ2h0KGxpZmVfbGFkZGVyID4gNy42KSArICMgc2VsZWN0IHNvbWUgYXJiaXRyYXR5IHRocmVzaG9sZAogIGxhYnModGl0bGUgPSAiTGlmZSBsYWRkZXIsIGFsbCB0aGUgd29ybGQiLCAKICAgICAgIHkgPSAiTGlmZSBsYWRkZXIiLCAKICAgICAgIHggPSAiWWVhciIpCmBgYAojIyBhbmQgdGhlIGxvd2VzdCBoYXBwaW5lc3Mgc2NvcmUKCmBgYHtyfQojIGNvcHkgYW5kIHBhc3RlIGFsbCB0aGUgY29kZQpoYXBwaW5lc3MgJT4lIAogICMgZmlyc3QgcmVsb2NhdGUgb25lIGNvbHVtbiB0byBtYWtlIGl0IGVhc2llcgogIHJlbG9jYXRlKHNvY2lhbF9zdXBwb3J0LCAuYWZ0ZXIgPSBoZWFsdGh5X2xpZmVfZXhwZWN0YW5jeV9hdF9iaXJ0aCkgJT4lIAogICMgZmlsdGVyIHRvIGV4Y2x1ZGUgdGhlIE5BIGNvbnRpbmVudHMKICBmaWx0ZXIocmVnaW9uICE9ICJOQSIpICU+JSAKICAjIG5vdyBmaWx0ZXIgb25seSBldXJvcGVhbiBjb3VudHJpZXMKICAjIHVuY29tbWVudCBuZXh0IGxpbmUgdG8gZmlsdGVyIGV1cm9wZWFuIGNvdW50cmllcyBvbmx5CiAgIyBmaWx0ZXIocmVnaW9uID09ICJFdXJvcGUiKSAlPiUKICAKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCAKICAgICAgICAgICAgIHkgPSBsaWZlX2xhZGRlciwgCiAgICAgICAgICAgICBjb2xvciA9IGNvdW50cnlfbmFtZSwgCiAgICAgICAgICAgICBncm91cCA9IGNvdW50cnlfbmFtZSkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2doaWdobGlnaHQobGlmZV9sYWRkZXIgPCAzKSArCiAgbGFicyh0aXRsZSA9ICJMaWZlIGxhZGRlciwgYWxsIHRoZSB3b3JsZCIsIAogICAgICAgeSA9ICJMaWZlIGxhZGRlciIsIAogICAgICAgeCA9ICJZZWFyIikKYGBgCiMjIHRvcCB0aHJlZSBmcm9tIEV1cm9wZQpgYGB7cn0KIyBjb3B5IGFuZCBwYXN0ZSBhbGwgdGhlIGNvZGUKaGFwcGluZXNzICU+JSAKICAjIGZpcnN0IHJlbG9jYXRlIG9uZSBjb2x1bW4gdG8gbWFrZSBpdCBlYXNpZXIKICByZWxvY2F0ZShzb2NpYWxfc3VwcG9ydCwgLmFmdGVyID0gaGVhbHRoeV9saWZlX2V4cGVjdGFuY3lfYXRfYmlydGgpICU+JSAKICAjIGZpbHRlciB0byBleGNsdWRlIHRoZSBOQSBjb250aW5lbnRzCiAgZmlsdGVyKHJlZ2lvbiA9PSAiRXVyb3BlIikgJT4lIAogICMgbm93IGZpbHRlciBvbmx5IGV1cm9wZWFuIGNvdW50cmllcwogICMgdW5jb21tZW50IG5leHQgbGluZSB0byBmaWx0ZXIgZXVyb3BlYW4gY291bnRyaWVzIG9ubHkKICAjIGZpbHRlcihyZWdpb24gPT0gIkV1cm9wZSIpICU+JQogIAogIGdncGxvdChhZXMoeCA9IHllYXIsIAogICAgICAgICAgICAgeSA9IGxpZmVfbGFkZGVyLCAKICAgICAgICAgICAgIGNvbG9yID0gY291bnRyeV9uYW1lLCAKICAgICAgICAgICAgIGdyb3VwID0gY291bnRyeV9uYW1lKSkgKwogIGdlb21fbGluZSgpICsKICBnZ2hpZ2hsaWdodChtYXgobGlmZV9sYWRkZXIpLCBtYXhfaGlnaGxpZ2h0ID0gM0wpICMgc2VsZWN0IHRoZSB0b3AgMwogIGxhYnModGl0bGUgPSAiTGlmZSBsYWRkZXIsIGFsbCB0aGUgd29ybGQiLCAKICAgICAgIHkgPSAiTGlmZSBsYWRkZXIiLCAKICAgICAgIHggPSAiWWVhciIpCmBgYAoKIyBubyBnZ2hpZ2hsaWdodCBuZWVkZWQKCk5vdyB3aXRoIGFsbCB2YXJpYWJsZXMgYW5kIG5vIGdnaGlnaGxpZ3RoIG5lZWRlZAoKCmBgYHtyfQpoYXBwaW5lc3MgJT4lIAogICMgZmlyc3QgcmVsb2NhdGUgb25lIGNvbHVtbiB0byBtYWtlIGl0IGVhc2llciB0byBtYW5pcHVsYXRlIHRoZSB2YXJpYWJsZXMgZHVyaW5nIHRoZSBwaXZvdGluZwogIHJlbG9jYXRlKHNvY2lhbF9zdXBwb3J0LCAuYWZ0ZXIgPSBoZWFsdGh5X2xpZmVfZXhwZWN0YW5jeV9hdF9iaXJ0aCkgJT4lIAogICMgZmlsdGVyIHRvIGV4Y2x1ZGUgdGhlIE5BIGNvbnRpbmVudHMKICBmaWx0ZXIocmVnaW9uICE9ICJOQSIpICU+JSAKICAjIG5vdyBmaWx0ZXIgb25seSBldXJvcGVhbiBjb3VudHJpZXMKICBmaWx0ZXIocmVnaW9uID09ICJFdXJvcGUiKSAlPiUgICMgY29tbmVudCB0aGlzIGxpbmUgdG8gY2hlY2sgZm9yIGFsbCB0aGUgd29ybGQKICAjIG5vdyByZXNoYXBlIHRoZSBkYXRhc2V0CiAgcGl2b3RfbG9uZ2VyKHNvY2lhbF9zdXBwb3J0Om5lZ2F0aXZlX2FmZmVjdCwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImhhcHBpbmVzc192YXJpYWJsZSIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiaGFwcGluZXNzX3ZhbHVlIikgJT4lIAogIAogICMgY2FsY3VsYXRlIHRoZSBtZWFuIHZhbHVlIHBlciBjb250aW5lbnQKICBncm91cF9ieShoYXBwaW5lc3NfdmFyaWFibGUsIGNvdW50cnlfbmFtZSwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gbWVhbihoYXBwaW5lc3NfdmFsdWUsIG5hLnJtID0gVCkpICU+JSAKICAKICAjIGNoYW5nZSB0aGUgbmFtZSBvZiB0aGUgbGV2ZWxzIG9mIG5hbWVfdmFyaWFibGUKICBtdXRhdGUoaGFwcGluZXNzX3ZhcmlhYmxlID0gcmVjb2RlKGhhcHBpbmVzc192YXJpYWJsZSwgIyBjaGFuZ2UgdGhlIHZhcmlhYmxlLCByZWNvZGluZyB0aGUgbGV2ZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZWRvbV90b19tYWtlX2xpZmVfY2hvaWNlcyA9ICJGcmVlZG9tIiwgICMgb2xkIG5hbWUgPSBuZXcgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyb3NpdHkgPSAiR2VuZXJvc2l0eSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlX2FmZmVjdCA9ICJOZWdhdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlcHRpb25zX29mX2NvcnJ1cHRpb24gPSAiQ29ycnVwdGlvbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2FmZmVjdCA9ICJQb3NpdGl2ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvY2lhbF9zdXBwb3J0ID0gIlN1cHBvcnQiKSkgJT4lIAogIAogICMgYW5kIG5vdyBwbG90CiAgZ2dwbG90KGFlcyh4ID0geWVhciwgCiAgICAgICAgICAgICB5ID0gbWVhbiwgCiAgICAgICAgICAgICBjb2xvciA9IChjb3VudHJ5X25hbWUgPT0gIkxhdHZpYSIpLCAjIGdvb2QgdHJpY2shIDpECiAgICAgICAgICAgICBncm91cCA9IGNvdW50cnlfbmFtZSkpICsgCiAgZ2VvbV9saW5lKGFscGhhID0gLjUpICsKICAjIGNoYW5nZSB0aGUgbmFtZSBvZiBsZXZlbHMgaW4gdGhlIGxlZ2VuZAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiR3JleSIsICJyZWQiKSwgCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJPdGhlciIsICJMYXR2aWEiKSkgKwogICMgbm93IGdlbmVyYXRlIHNldmVyYWwgcGxvdHMsIGVhY2ggZm9yIG9uZSB2YXJpYWJsZQogIGZhY2V0X2dyaWQoLiB+IGhhcHBpbmVzc192YXJpYWJsZSkgKyAgIyB0aGlzIG1lYW5zIHJvd3MgYW5kIGNvbHVtbnMsIGluIHRoaXMgY2FzZSwgbm8gdmFyaWFibGUgfiBoYXBwaW5lc3MKICBsYWJzKHRpdGxlID0gIlNldmVyYWwgdmFyaWFibGVzIGluIG9uZSBwbG90IiwgCiAgICAgICB5ID0gIk1lYW4gdmFsdWUiLCAKICAgICAgIHggPSAiWWVhciIsIAogICAgICAgY29sb3IgPSAiQ291bnRyeSIpIApgYGAKCgo=