Load and clean data

library(tidyverse)
library(crackdownsphilanthropy)
library(csvy)
library(here)

# Load data
# results_file <- file.path(here(), "data", "test_data.csv")
results_file <- here("data", "raw_data", "crackdowns_philanthropy_raw.csv")

# Possible answers
favorability <- c("Very unfavorable", "Unfavorable", "Neutral", 
                  "Favorable", "Very favorable")

likelihood <- c("Extremely unlikely", "Somewhat unlikely", 
                "Neither likely nor unlikely", 
                "Somewhat likely", "Extremely likely")

frequency_charity <- c("Once a week", "Once a month", "Once every three months", 
                       "Once every six months", "Once a year", "Once every few years", 
                       "Never")

frequency_public_affairs <- c("Most of the time", "Some of the time", 
                              "Only now and then", "Hardly at all")

levels_ideology <- c("Strong liberal", "Liberal", "Independent, leaning liberal", 
                     "Independent", "Independent, leaning conservative", 
                     "Conservative", "Very conservative")

levels_education <- c("Less than high school", "High school graduate", 
                      "Some college", "2 year degree", "4 year degree", 
                      "Graduate or professional degree", "Doctorate")

frequency_religion <- c("More than once a week", "Once a week", "Once or twice a month", 
                        "A few times a year", "Seldom", "Never", "Don't know")

levels_gender <- c("Female", "Male", "Transgender", "Other", "Prefer not to say")

levels_income <- c("Less than $10,000", "$10,000 – $19,999", "$20,000 – $29,999", 
                   "$30,000 – $39,999", "$40,000 – $49,999", "$50,000 – $59,999", 
                   "$60,000 – $69,999", "$70,000 – $79,999", "$80,000 – $89,999", 
                   "$90,000 – $99,999", "$100,000 – $149,999", "More than $150,000", 
                   "Prefer not to say")

levels_age <- c("Under 18", "18 – 24", "25 – 34", "35 – 44", "45 – 54", 
                "55 – 64", "65 – 74", "75 – 84", "85 or older")

attention1_answer <- c("Green", "Yellow")
attention2_answer <- "Blue"
levels_attention <- c("Correct", "Incorrect")

# Qualtrics stores question information in the first 3 rows. All we care about
# are the column names in the first row.
results_meta <- read_csv(results_file, n_max = 2)

# The first 10 rows need to be skipped because the consent question has a bunch
# of line breaks and it messes with CSV line counting. The actual responses
# start on row 11. This doesn't entirely make sense, since read_csv can read the
# line break-filled row in just fine. Skipping said lines makes it choke. <shrug>
results_raw <- read_csv(results_file, skip = 16,
                        col_names = colnames(results_meta))

# Confirmation codes to exclude. These are people who failed the attention
# checks or who took the survey outside of MTurk.
#
# The code for determining these is in a script that is excluded from the main
# repository because of privacy issues (it deals directly with MTurk worker
# IDs), called "data/private_data/approve_mturkers.R". It outputs this text list
# of codes.
codes_to_exclude <- read_csv(here("data", "derived_data", "codes_to_exclude.csv"))

# Clean everything
results_check_attention <- results_raw %>%
  # Only select necessary columns
  select(id = ResponseId, confirmation_code = mTurkCode, duration = `Duration (in seconds)`,
         start_date = StartDate, end_date = EndDate,
         crackdown, issue, funding, starts_with("Q")) %>%
  rename(favor_humanitarian = Q2.1_1, favor_human_rights = Q2.1_2, 
         favor_development = Q2.1_3, donate_likely = Q2.3, 
         amount_donate = Q2.4_1, amount_keep = Q2.4_2, amount_why = Q2.5,
         give_charity = Q3.2, volunteer = Q3.3, political_knowledge = Q3.4,
         ideology = Q3.5, education = Q3.6, religiosity = Q3.7,
         gender = Q3.9, gender_other = Q3.9_4_TEXT, income = Q3.10, age = Q3.11) %>%
  # Clean up experimental condition columns
  mutate(issue = recode(issue, `human rights for refugees` = "Human rights",
                        `humanitarian assistance for refugees` = "Humanitarian assistance"),
         funding = recode(funding, `government donors` = "Government",
                          `individual, private donors` = "Private")) %>%
  mutate(crackdown = ifelse(str_detect(crackdown, "harshly restrict"), 
                            "Crackdown", "No crackdown")) %>% 
  mutate(crackdown = factor(crackdown, levels = c("No crackdown", "Crackdown"), 
                            ordered = TRUE),
         issue = factor(issue, levels = c("Human rights", "Humanitarian assistance"), 
                        ordered = TRUE),
         funding = factor(funding, levels = c("Government", "Private"), 
                          ordered = TRUE)) %>% 
  # Attention checks
  mutate(attention1_correct = str_split(Q1.3, ",") %>% 
           map_lgl(~ all(attention1_answer %in% .) & length(.) == length(attention1_answer)),
         attention2_correct = Q3.8 == attention2_answer) %>% 
  # This person contacted me separately to say that they accidentally did the first
  # attention check wrong, but that they did pay attention: 6518634
  mutate(attention1_correct = ifelse(confirmation_code == 6518634,
                                     TRUE, attention1_correct)) 

results <- results_check_attention %>% 
  filter(!(confirmation_code %in% codes_to_exclude$confirmation_code)) %>% 
  filter(attention2_correct) %>%
  # Factorize variables
  mutate(donate_likely = factor(donate_likely, levels = likelihood, ordered = TRUE)) %>% 
  mutate_at(vars(favor_humanitarian, favor_human_rights, favor_development),
            funs(factor(., levels = favorability, ordered = TRUE))) %>% 
  mutate(give_charity = factor(give_charity, 
                               levels = frequency_charity, ordered = TRUE),
         volunteer = factor(volunteer, levels = c("No", "Yes"), ordered = TRUE),
         political_knowledge = factor(political_knowledge, 
                                      levels = frequency_public_affairs, ordered = TRUE),
         ideology = factor(ideology, levels = levels_ideology, ordered = TRUE),
         education = factor(education, levels = levels_education, ordered = TRUE),
         religiosity = factor(religiosity, levels = frequency_religion, ordered = TRUE),
         gender = recode(gender, `Other:` = "Other"),
         gender = factor(gender, levels = levels_gender, ordered = TRUE),
         income = factor(income, levels = levels_income, ordered = TRUE),
         age = factor(age, levels = levels_age, ordered = TRUE),
         check1 = factor(attention1_correct, levels = c(TRUE, FALSE),
                         labels = levels_attention, ordered = TRUE),
         check2 = factor(attention2_correct, levels = c(TRUE, FALSE),
                         labels = levels_attention, ordered = TRUE)) %>% 
  # Dichotomize variables
  mutate(donate_likely_bin = fct_recode(donate_likely,
                                        `Not likely` = "Extremely unlikely",
                                        `Not likely` = "Somewhat unlikely",
                                        `Not likely` = "Neither likely nor unlikely",
                                        Likely = "Somewhat likely",
                                        Likely = "Extremely likely")) %>% 
  mutate_at(vars(favor_humanitarian, favor_human_rights, favor_development),
            funs(bin = fct_recode(., 
                                  `Not favorable` = "Very unfavorable",
                                  `Not favorable` = "Unfavorable",
                                  `Not favorable` = "Neutral",
                                  Favorable = "Favorable",
                                  Favorable = "Very favorable"))) %>% 
  mutate(give_charity_3 = fct_recode(give_charity,
                                     `At least once a month` = "Once a week",
                                     `At least once a month` = "Once a month",
                                     `Once a month-once a year` = "Once every three months",
                                     `Once a month-once a year` = "Once every six months",
                                     `Once a month-once a year` = "Once a year",
                                     Rarely = "Once every few years",
                                     Rarely = "Never") %>% fct_rev(),
         give_charity_2 = fct_recode(give_charity,
                                     `At least once a year` = "Once a week",
                                     `At least once a year` = "Once a month",
                                     `At least once a year` = "Once every three months",
                                     `At least once a year` = "Once every six months",
                                     `At least once a year` = "Once a year",
                                     Rarely = "Once every few years",
                                     Rarely = "Never")) %>% 
  mutate(political_knowledge_bin = fct_recode(political_knowledge,
                                              `Often` = "Most of the time",
                                              `Often` = "Some of the time",
                                              `Not often` = "Only now and then",
                                              `Not often` = "Hardly at all") %>% fct_rev()) %>% 
  mutate(ideology_3 = fct_recode(ideology,
                                 `Liberal` = "Strong liberal",
                                 `Liberal` = "Liberal",
                                 `Liberal` = "Independent, leaning liberal",
                                 `Independent` = "Independent",
                                 `Conservative` = "Independent, leaning conservative",
                                 `Conservative` = "Conservative",
                                 `Conservative` = "Very conservative") %>% fct_rev()) %>% 
  mutate(ideology_bin = fct_recode(ideology_3,
                                   `Not liberal` = "Independent",
                                   `Not liberal` = "Conservative")) %>% 
  mutate(education_bin = fct_recode(education,
                                    `No BA` = "Less than high school",
                                    `No BA` = "High school graduate",
                                    `No BA` = "Some college",
                                    `No BA` = "2 year degree",
                                    `BA and above` = "4 year degree",
                                    `BA and above` = "Graduate or professional degree",
                                    `BA and above` = "Doctorate")) %>% 
  mutate(religiosity_bin = fct_recode(religiosity,
                                      `At least once a month` = "More than once a week",
                                      `At least once a month` = "Once a week",
                                      `At least once a month` = "Once or twice a month",
                                      `Rarely` = "A few times a year",
                                      `Rarely` = "Seldom",
                                      `Rarely` = "Never",
                                      NULL = "Don't know") %>% fct_rev()) %>% 
  mutate(income_clean = fct_recode(income, NULL = "Prefer not to say"),
         income_bin = factor(income_clean >= median(.$income), levels = c(FALSE, TRUE),
                             labels = paste(c("Less than", "At least"), median(.$income)))) %>% 
  mutate(age_bin = factor(age >= median(.$age), levels = c(FALSE, TRUE),
                          labels = paste(c("Less than", "At least"), median(.$age))),
         gender_bin = fct_collapse(gender,
                                   Female = "Female",
                                   `Not Female` = c("Male", "Transgender", 
                                                    "Other", "Prefer not to say")))

# Save final clean data
saveRDS(results, here("data", "derived_data", "results_clean.rds"))
write_csvy(results, file = here("data", "derived_data", "results_clean.csv"),
           metadata = here("data", "derived_data", "results_clean.yaml"), na = "NA")

Original computing environment

## # http://dirk.eddelbuettel.com/blog/2017/11/27/#011_faster_package_installation_one
## VER=
## CCACHE=ccache
## CC=$(CCACHE) gcc$(VER)
## CXX=$(CCACHE) g++$(VER)
## CXXFLAGS=-O3 -Wno-unused-variable -Wno-unused-function -Wno-unused-local-typedefs
## CXX11=$(CCACHE) g++$(VER)
## CXX14=$(CCACHE) g++$(VER)
## FLIBS = -L`gfortran -print-file-name=libgfortran.dylib | xargs dirname`
## FC=$(CCACHE) gfortran$(VER)
## F77=$(CCACHE) gfortran$(VER)
## ─ Session info ──────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 3.5.2 (2018-12-20)
##  os       macOS Mojave 10.14.3        
##  system   x86_64, darwin15.6.0        
##  ui       X11                         
##  language (EN)                        
##  collate  en_US.UTF-8                 
##  ctype    en_US.UTF-8                 
##  tz       America/Denver              
##  date     2019-03-13                  
## 
## ─ Packages ──────────────────────────────────────────────────────────────
##  package                * version    date       lib
##  assertthat               0.2.0      2017-04-11 [1]
##  backports                1.1.3      2018-12-14 [1]
##  base64enc                0.1-3      2015-07-28 [1]
##  bindr                    0.1.1      2018-03-13 [1]
##  bindrcpp               * 0.2.2      2018-03-29 [1]
##  broom                    0.5.1      2018-12-05 [1]
##  callr                    3.1.1      2018-12-21 [1]
##  cellranger               1.1.0      2016-07-27 [1]
##  cli                      1.0.1      2018-09-25 [1]
##  codetools                0.2-15     2016-10-05 [1]
##  colorspace               1.4-0      2019-01-13 [1]
##  crackdownsphilanthropy * 0.0.0.9000 2019-03-13 [1]
##  crayon                   1.3.4      2017-09-16 [1]
##  csvy                   * 0.3.0      2018-08-01 [1]
##  data.table               1.12.0     2019-01-13 [1]
##  desc                     1.2.0      2018-05-01 [1]
##  devtools                 2.0.1      2018-10-26 [1]
##  digest                   0.6.18     2018-10-10 [1]
##  dplyr                  * 0.7.8      2018-11-10 [1]
##  evaluate                 0.13       2019-02-12 [1]
##  forcats                * 0.3.0      2018-02-19 [1]
##  fs                       1.2.6      2018-08-23 [1]
##  generics                 0.0.2      2018-11-29 [1]
##  ggplot2                * 3.1.0      2018-10-25 [1]
##  glue                     1.3.0.9000 2019-02-09 [1]
##  gridExtra                2.3        2017-09-09 [1]
##  gtable                   0.2.0      2016-02-26 [1]
##  haven                    2.0.0      2018-11-22 [1]
##  here                   * 0.1        2017-05-28 [1]
##  hms                      0.4.2      2018-03-10 [1]
##  htmltools                0.3.6      2017-04-28 [1]
##  httr                     1.4.0      2018-12-11 [1]
##  inline                   0.3.15     2018-05-18 [1]
##  jsonlite                 1.6        2018-12-07 [1]
##  knitr                    1.21       2018-12-10 [1]
##  lattice                  0.20-38    2018-11-04 [1]
##  lazyeval                 0.2.1      2017-10-29 [1]
##  loo                      2.0.0      2018-04-11 [1]
##  lubridate                1.7.4      2018-04-11 [1]
##  magrittr                 1.5        2014-11-22 [1]
##  matrixStats              0.54.0     2018-07-23 [1]
##  memoise                  1.1.0      2017-04-21 [1]
##  modelr                   0.1.2      2018-05-11 [1]
##  munsell                  0.5.0      2018-06-12 [1]
##  nlme                     3.1-137    2018-04-07 [1]
##  pillar                   1.3.1      2018-12-15 [1]
##  pkgbuild                 1.0.2      2018-10-16 [1]
##  pkgconfig                2.0.2      2018-08-16 [1]
##  pkgload                  1.0.2      2018-10-29 [1]
##  plyr                     1.8.4      2016-06-08 [1]
##  prettyunits              1.0.2      2015-07-13 [1]
##  processx                 3.2.1.9000 2019-03-07 [1]
##  ps                       1.3.0      2018-12-21 [1]
##  purrr                  * 0.3.1      2019-03-03 [1]
##  R6                       2.4.0      2019-02-14 [1]
##  Rcpp                   * 1.0.0      2018-11-07 [1]
##  readr                  * 1.3.1      2018-12-21 [1]
##  readxl                   1.2.0      2018-12-19 [1]
##  remotes                  2.0.2      2018-10-30 [1]
##  rlang                    0.3.1      2019-01-08 [1]
##  rmarkdown                1.11       2018-12-08 [1]
##  rprojroot                1.3-2      2018-01-03 [1]
##  rstan                    2.18.2     2018-11-07 [1]
##  rstantools               1.5.1      2018-08-22 [1]
##  rstudioapi               0.9.0      2019-01-09 [1]
##  rvest                    0.3.2      2016-06-17 [1]
##  scales                   1.0.0      2018-08-09 [1]
##  sessioninfo              1.1.1      2018-11-05 [1]
##  StanHeaders              2.18.1     2019-01-28 [1]
##  stringi                  1.3.1      2019-02-13 [1]
##  stringr                * 1.4.0      2019-02-10 [1]
##  testthat                 2.0.1      2018-10-13 [1]
##  tibble                 * 2.0.1      2019-01-12 [1]
##  tidyr                  * 0.8.2      2018-10-28 [1]
##  tidyselect               0.2.5      2018-10-11 [1]
##  tidyverse              * 1.2.1      2017-11-14 [1]
##  usethis                  1.4.0      2018-08-14 [1]
##  withr                    2.1.2      2018-03-15 [1]
##  xfun                     0.5        2019-02-20 [1]
##  xml2                     1.2.0      2018-01-24 [1]
##  yaml                     2.2.0      2018-07-25 [1]
##  source                          
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.2)                  
##  local                           
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  Github (tidyverse/glue@8188cea) 
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  Github (r-pkgs/processx@823819d)
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.2)                  
##  CRAN (R 3.5.0)                  
##  CRAN (R 3.5.0)                  
## 
## [1] /Library/Frameworks/R.framework/Versions/3.5/Resources/library
LS0tCnRpdGxlOiAiQ2xlYW4gZGF0YSIKYXV0aG9yOiAiQW5kcmV3IEhlaXNzIGFuZCBTdXBhcm5hIENoYXVkaHJ5IgpkYXRlOiAiTGFzdCBydW46IGByIGZvcm1hdChTeXMudGltZSgpLCAnJUIgJWUsICVZJylgIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKIyBMb2FkIGFuZCBjbGVhbiBkYXRhCgpgYGB7ciBjbGVhbi1kYXRhLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjcmFja2Rvd25zcGhpbGFudGhyb3B5KQpsaWJyYXJ5KGNzdnkpCmxpYnJhcnkoaGVyZSkKCiMgTG9hZCBkYXRhCiMgcmVzdWx0c19maWxlIDwtIGZpbGUucGF0aChoZXJlKCksICJkYXRhIiwgInRlc3RfZGF0YS5jc3YiKQpyZXN1bHRzX2ZpbGUgPC0gaGVyZSgiZGF0YSIsICJyYXdfZGF0YSIsICJjcmFja2Rvd25zX3BoaWxhbnRocm9weV9yYXcuY3N2IikKCiMgUG9zc2libGUgYW5zd2VycwpmYXZvcmFiaWxpdHkgPC0gYygiVmVyeSB1bmZhdm9yYWJsZSIsICJVbmZhdm9yYWJsZSIsICJOZXV0cmFsIiwgCiAgICAgICAgICAgICAgICAgICJGYXZvcmFibGUiLCAiVmVyeSBmYXZvcmFibGUiKQoKbGlrZWxpaG9vZCA8LSBjKCJFeHRyZW1lbHkgdW5saWtlbHkiLCAiU29tZXdoYXQgdW5saWtlbHkiLCAKICAgICAgICAgICAgICAgICJOZWl0aGVyIGxpa2VseSBub3IgdW5saWtlbHkiLCAKICAgICAgICAgICAgICAgICJTb21ld2hhdCBsaWtlbHkiLCAiRXh0cmVtZWx5IGxpa2VseSIpCgpmcmVxdWVuY3lfY2hhcml0eSA8LSBjKCJPbmNlIGEgd2VlayIsICJPbmNlIGEgbW9udGgiLCAiT25jZSBldmVyeSB0aHJlZSBtb250aHMiLCAKICAgICAgICAgICAgICAgICAgICAgICAiT25jZSBldmVyeSBzaXggbW9udGhzIiwgIk9uY2UgYSB5ZWFyIiwgIk9uY2UgZXZlcnkgZmV3IHllYXJzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIk5ldmVyIikKCmZyZXF1ZW5jeV9wdWJsaWNfYWZmYWlycyA8LSBjKCJNb3N0IG9mIHRoZSB0aW1lIiwgIlNvbWUgb2YgdGhlIHRpbWUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk9ubHkgbm93IGFuZCB0aGVuIiwgIkhhcmRseSBhdCBhbGwiKQoKbGV2ZWxzX2lkZW9sb2d5IDwtIGMoIlN0cm9uZyBsaWJlcmFsIiwgIkxpYmVyYWwiLCAiSW5kZXBlbmRlbnQsIGxlYW5pbmcgbGliZXJhbCIsIAogICAgICAgICAgICAgICAgICAgICAiSW5kZXBlbmRlbnQiLCAiSW5kZXBlbmRlbnQsIGxlYW5pbmcgY29uc2VydmF0aXZlIiwgCiAgICAgICAgICAgICAgICAgICAgICJDb25zZXJ2YXRpdmUiLCAiVmVyeSBjb25zZXJ2YXRpdmUiKQoKbGV2ZWxzX2VkdWNhdGlvbiA8LSBjKCJMZXNzIHRoYW4gaGlnaCBzY2hvb2wiLCAiSGlnaCBzY2hvb2wgZ3JhZHVhdGUiLCAKICAgICAgICAgICAgICAgICAgICAgICJTb21lIGNvbGxlZ2UiLCAiMiB5ZWFyIGRlZ3JlZSIsICI0IHllYXIgZGVncmVlIiwgCiAgICAgICAgICAgICAgICAgICAgICAiR3JhZHVhdGUgb3IgcHJvZmVzc2lvbmFsIGRlZ3JlZSIsICJEb2N0b3JhdGUiKQoKZnJlcXVlbmN5X3JlbGlnaW9uIDwtIGMoIk1vcmUgdGhhbiBvbmNlIGEgd2VlayIsICJPbmNlIGEgd2VlayIsICJPbmNlIG9yIHR3aWNlIGEgbW9udGgiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIkEgZmV3IHRpbWVzIGEgeWVhciIsICJTZWxkb20iLCAiTmV2ZXIiLCAiRG9uJ3Qga25vdyIpCgpsZXZlbHNfZ2VuZGVyIDwtIGMoIkZlbWFsZSIsICJNYWxlIiwgIlRyYW5zZ2VuZGVyIiwgIk90aGVyIiwgIlByZWZlciBub3QgdG8gc2F5IikKCmxldmVsc19pbmNvbWUgPC0gYygiTGVzcyB0aGFuICQxMCwwMDAiLCAiJDEwLDAwMCDigJMgJDE5LDk5OSIsICIkMjAsMDAwIOKAkyAkMjksOTk5IiwgCiAgICAgICAgICAgICAgICAgICAiJDMwLDAwMCDigJMgJDM5LDk5OSIsICIkNDAsMDAwIOKAkyAkNDksOTk5IiwgIiQ1MCwwMDAg4oCTICQ1OSw5OTkiLCAKICAgICAgICAgICAgICAgICAgICIkNjAsMDAwIOKAkyAkNjksOTk5IiwgIiQ3MCwwMDAg4oCTICQ3OSw5OTkiLCAiJDgwLDAwMCDigJMgJDg5LDk5OSIsIAogICAgICAgICAgICAgICAgICAgIiQ5MCwwMDAg4oCTICQ5OSw5OTkiLCAiJDEwMCwwMDAg4oCTICQxNDksOTk5IiwgIk1vcmUgdGhhbiAkMTUwLDAwMCIsIAogICAgICAgICAgICAgICAgICAgIlByZWZlciBub3QgdG8gc2F5IikKCmxldmVsc19hZ2UgPC0gYygiVW5kZXIgMTgiLCAiMTgg4oCTIDI0IiwgIjI1IOKAkyAzNCIsICIzNSDigJMgNDQiLCAiNDUg4oCTIDU0IiwgCiAgICAgICAgICAgICAgICAiNTUg4oCTIDY0IiwgIjY1IOKAkyA3NCIsICI3NSDigJMgODQiLCAiODUgb3Igb2xkZXIiKQoKYXR0ZW50aW9uMV9hbnN3ZXIgPC0gYygiR3JlZW4iLCAiWWVsbG93IikKYXR0ZW50aW9uMl9hbnN3ZXIgPC0gIkJsdWUiCmxldmVsc19hdHRlbnRpb24gPC0gYygiQ29ycmVjdCIsICJJbmNvcnJlY3QiKQoKIyBRdWFsdHJpY3Mgc3RvcmVzIHF1ZXN0aW9uIGluZm9ybWF0aW9uIGluIHRoZSBmaXJzdCAzIHJvd3MuIEFsbCB3ZSBjYXJlIGFib3V0CiMgYXJlIHRoZSBjb2x1bW4gbmFtZXMgaW4gdGhlIGZpcnN0IHJvdy4KcmVzdWx0c19tZXRhIDwtIHJlYWRfY3N2KHJlc3VsdHNfZmlsZSwgbl9tYXggPSAyKQoKIyBUaGUgZmlyc3QgMTAgcm93cyBuZWVkIHRvIGJlIHNraXBwZWQgYmVjYXVzZSB0aGUgY29uc2VudCBxdWVzdGlvbiBoYXMgYSBidW5jaAojIG9mIGxpbmUgYnJlYWtzIGFuZCBpdCBtZXNzZXMgd2l0aCBDU1YgbGluZSBjb3VudGluZy4gVGhlIGFjdHVhbCByZXNwb25zZXMKIyBzdGFydCBvbiByb3cgMTEuIFRoaXMgZG9lc24ndCBlbnRpcmVseSBtYWtlIHNlbnNlLCBzaW5jZSByZWFkX2NzdiBjYW4gcmVhZCB0aGUKIyBsaW5lIGJyZWFrLWZpbGxlZCByb3cgaW4ganVzdCBmaW5lLiBTa2lwcGluZyBzYWlkIGxpbmVzIG1ha2VzIGl0IGNob2tlLiA8c2hydWc+CnJlc3VsdHNfcmF3IDwtIHJlYWRfY3N2KHJlc3VsdHNfZmlsZSwgc2tpcCA9IDE2LAogICAgICAgICAgICAgICAgICAgICAgICBjb2xfbmFtZXMgPSBjb2xuYW1lcyhyZXN1bHRzX21ldGEpKQoKIyBDb25maXJtYXRpb24gY29kZXMgdG8gZXhjbHVkZS4gVGhlc2UgYXJlIHBlb3BsZSB3aG8gZmFpbGVkIHRoZSBhdHRlbnRpb24KIyBjaGVja3Mgb3Igd2hvIHRvb2sgdGhlIHN1cnZleSBvdXRzaWRlIG9mIE1UdXJrLgojCiMgVGhlIGNvZGUgZm9yIGRldGVybWluaW5nIHRoZXNlIGlzIGluIGEgc2NyaXB0IHRoYXQgaXMgZXhjbHVkZWQgZnJvbSB0aGUgbWFpbgojIHJlcG9zaXRvcnkgYmVjYXVzZSBvZiBwcml2YWN5IGlzc3VlcyAoaXQgZGVhbHMgZGlyZWN0bHkgd2l0aCBNVHVyayB3b3JrZXIKIyBJRHMpLCBjYWxsZWQgImRhdGEvcHJpdmF0ZV9kYXRhL2FwcHJvdmVfbXR1cmtlcnMuUiIuIEl0IG91dHB1dHMgdGhpcyB0ZXh0IGxpc3QKIyBvZiBjb2Rlcy4KY29kZXNfdG9fZXhjbHVkZSA8LSByZWFkX2NzdihoZXJlKCJkYXRhIiwgImRlcml2ZWRfZGF0YSIsICJjb2Rlc190b19leGNsdWRlLmNzdiIpKQoKIyBDbGVhbiBldmVyeXRoaW5nCnJlc3VsdHNfY2hlY2tfYXR0ZW50aW9uIDwtIHJlc3VsdHNfcmF3ICU+JQogICMgT25seSBzZWxlY3QgbmVjZXNzYXJ5IGNvbHVtbnMKICBzZWxlY3QoaWQgPSBSZXNwb25zZUlkLCBjb25maXJtYXRpb25fY29kZSA9IG1UdXJrQ29kZSwgZHVyYXRpb24gPSBgRHVyYXRpb24gKGluIHNlY29uZHMpYCwKICAgICAgICAgc3RhcnRfZGF0ZSA9IFN0YXJ0RGF0ZSwgZW5kX2RhdGUgPSBFbmREYXRlLAogICAgICAgICBjcmFja2Rvd24sIGlzc3VlLCBmdW5kaW5nLCBzdGFydHNfd2l0aCgiUSIpKSAlPiUKICByZW5hbWUoZmF2b3JfaHVtYW5pdGFyaWFuID0gUTIuMV8xLCBmYXZvcl9odW1hbl9yaWdodHMgPSBRMi4xXzIsIAogICAgICAgICBmYXZvcl9kZXZlbG9wbWVudCA9IFEyLjFfMywgZG9uYXRlX2xpa2VseSA9IFEyLjMsIAogICAgICAgICBhbW91bnRfZG9uYXRlID0gUTIuNF8xLCBhbW91bnRfa2VlcCA9IFEyLjRfMiwgYW1vdW50X3doeSA9IFEyLjUsCiAgICAgICAgIGdpdmVfY2hhcml0eSA9IFEzLjIsIHZvbHVudGVlciA9IFEzLjMsIHBvbGl0aWNhbF9rbm93bGVkZ2UgPSBRMy40LAogICAgICAgICBpZGVvbG9neSA9IFEzLjUsIGVkdWNhdGlvbiA9IFEzLjYsIHJlbGlnaW9zaXR5ID0gUTMuNywKICAgICAgICAgZ2VuZGVyID0gUTMuOSwgZ2VuZGVyX290aGVyID0gUTMuOV80X1RFWFQsIGluY29tZSA9IFEzLjEwLCBhZ2UgPSBRMy4xMSkgJT4lCiAgIyBDbGVhbiB1cCBleHBlcmltZW50YWwgY29uZGl0aW9uIGNvbHVtbnMKICBtdXRhdGUoaXNzdWUgPSByZWNvZGUoaXNzdWUsIGBodW1hbiByaWdodHMgZm9yIHJlZnVnZWVzYCA9ICJIdW1hbiByaWdodHMiLAogICAgICAgICAgICAgICAgICAgICAgICBgaHVtYW5pdGFyaWFuIGFzc2lzdGFuY2UgZm9yIHJlZnVnZWVzYCA9ICJIdW1hbml0YXJpYW4gYXNzaXN0YW5jZSIpLAogICAgICAgICBmdW5kaW5nID0gcmVjb2RlKGZ1bmRpbmcsIGBnb3Zlcm5tZW50IGRvbm9yc2AgPSAiR292ZXJubWVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYGluZGl2aWR1YWwsIHByaXZhdGUgZG9ub3JzYCA9ICJQcml2YXRlIikpICU+JQogIG11dGF0ZShjcmFja2Rvd24gPSBpZmVsc2Uoc3RyX2RldGVjdChjcmFja2Rvd24sICJoYXJzaGx5IHJlc3RyaWN0IiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNyYWNrZG93biIsICJObyBjcmFja2Rvd24iKSkgJT4lIAogIG11dGF0ZShjcmFja2Rvd24gPSBmYWN0b3IoY3JhY2tkb3duLCBsZXZlbHMgPSBjKCJObyBjcmFja2Rvd24iLCAiQ3JhY2tkb3duIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBpc3N1ZSA9IGZhY3Rvcihpc3N1ZSwgbGV2ZWxzID0gYygiSHVtYW4gcmlnaHRzIiwgIkh1bWFuaXRhcmlhbiBhc3Npc3RhbmNlIiksIAogICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSksCiAgICAgICAgIGZ1bmRpbmcgPSBmYWN0b3IoZnVuZGluZywgbGV2ZWxzID0gYygiR292ZXJubWVudCIsICJQcml2YXRlIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lIAogICMgQXR0ZW50aW9uIGNoZWNrcwogIG11dGF0ZShhdHRlbnRpb24xX2NvcnJlY3QgPSBzdHJfc3BsaXQoUTEuMywgIiwiKSAlPiUgCiAgICAgICAgICAgbWFwX2xnbCh+IGFsbChhdHRlbnRpb24xX2Fuc3dlciAlaW4lIC4pICYgbGVuZ3RoKC4pID09IGxlbmd0aChhdHRlbnRpb24xX2Fuc3dlcikpLAogICAgICAgICBhdHRlbnRpb24yX2NvcnJlY3QgPSBRMy44ID09IGF0dGVudGlvbjJfYW5zd2VyKSAlPiUgCiAgIyBUaGlzIHBlcnNvbiBjb250YWN0ZWQgbWUgc2VwYXJhdGVseSB0byBzYXkgdGhhdCB0aGV5IGFjY2lkZW50YWxseSBkaWQgdGhlIGZpcnN0CiAgIyBhdHRlbnRpb24gY2hlY2sgd3JvbmcsIGJ1dCB0aGF0IHRoZXkgZGlkIHBheSBhdHRlbnRpb246IDY1MTg2MzQKICBtdXRhdGUoYXR0ZW50aW9uMV9jb3JyZWN0ID0gaWZlbHNlKGNvbmZpcm1hdGlvbl9jb2RlID09IDY1MTg2MzQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFLCBhdHRlbnRpb24xX2NvcnJlY3QpKSAKCnJlc3VsdHMgPC0gcmVzdWx0c19jaGVja19hdHRlbnRpb24gJT4lIAogIGZpbHRlcighKGNvbmZpcm1hdGlvbl9jb2RlICVpbiUgY29kZXNfdG9fZXhjbHVkZSRjb25maXJtYXRpb25fY29kZSkpICU+JSAKICBmaWx0ZXIoYXR0ZW50aW9uMl9jb3JyZWN0KSAlPiUKICAjIEZhY3Rvcml6ZSB2YXJpYWJsZXMKICBtdXRhdGUoZG9uYXRlX2xpa2VseSA9IGZhY3Rvcihkb25hdGVfbGlrZWx5LCBsZXZlbHMgPSBsaWtlbGlob29kLCBvcmRlcmVkID0gVFJVRSkpICU+JSAKICBtdXRhdGVfYXQodmFycyhmYXZvcl9odW1hbml0YXJpYW4sIGZhdm9yX2h1bWFuX3JpZ2h0cywgZmF2b3JfZGV2ZWxvcG1lbnQpLAogICAgICAgICAgICBmdW5zKGZhY3RvciguLCBsZXZlbHMgPSBmYXZvcmFiaWxpdHksIG9yZGVyZWQgPSBUUlVFKSkpICU+JSAKICBtdXRhdGUoZ2l2ZV9jaGFyaXR5ID0gZmFjdG9yKGdpdmVfY2hhcml0eSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBmcmVxdWVuY3lfY2hhcml0eSwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICB2b2x1bnRlZXIgPSBmYWN0b3Iodm9sdW50ZWVyLCBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBwb2xpdGljYWxfa25vd2xlZGdlID0gZmFjdG9yKHBvbGl0aWNhbF9rbm93bGVkZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGZyZXF1ZW5jeV9wdWJsaWNfYWZmYWlycywgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBpZGVvbG9neSA9IGZhY3RvcihpZGVvbG9neSwgbGV2ZWxzID0gbGV2ZWxzX2lkZW9sb2d5LCBvcmRlcmVkID0gVFJVRSksCiAgICAgICAgIGVkdWNhdGlvbiA9IGZhY3RvcihlZHVjYXRpb24sIGxldmVscyA9IGxldmVsc19lZHVjYXRpb24sIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgcmVsaWdpb3NpdHkgPSBmYWN0b3IocmVsaWdpb3NpdHksIGxldmVscyA9IGZyZXF1ZW5jeV9yZWxpZ2lvbiwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBnZW5kZXIgPSByZWNvZGUoZ2VuZGVyLCBgT3RoZXI6YCA9ICJPdGhlciIpLAogICAgICAgICBnZW5kZXIgPSBmYWN0b3IoZ2VuZGVyLCBsZXZlbHMgPSBsZXZlbHNfZ2VuZGVyLCBvcmRlcmVkID0gVFJVRSksCiAgICAgICAgIGluY29tZSA9IGZhY3RvcihpbmNvbWUsIGxldmVscyA9IGxldmVsc19pbmNvbWUsIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgYWdlID0gZmFjdG9yKGFnZSwgbGV2ZWxzID0gbGV2ZWxzX2FnZSwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBjaGVjazEgPSBmYWN0b3IoYXR0ZW50aW9uMV9jb3JyZWN0LCBsZXZlbHMgPSBjKFRSVUUsIEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxldmVsc19hdHRlbnRpb24sIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgY2hlY2syID0gZmFjdG9yKGF0dGVudGlvbjJfY29ycmVjdCwgbGV2ZWxzID0gYyhUUlVFLCBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBsZXZlbHNfYXR0ZW50aW9uLCBvcmRlcmVkID0gVFJVRSkpICU+JSAKICAjIERpY2hvdG9taXplIHZhcmlhYmxlcwogIG11dGF0ZShkb25hdGVfbGlrZWx5X2JpbiA9IGZjdF9yZWNvZGUoZG9uYXRlX2xpa2VseSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGlrZWx5YCA9ICJFeHRyZW1lbHkgdW5saWtlbHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE5vdCBsaWtlbHlgID0gIlNvbWV3aGF0IHVubGlrZWx5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGlrZWx5YCA9ICJOZWl0aGVyIGxpa2VseSBub3IgdW5saWtlbHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlrZWx5ID0gIlNvbWV3aGF0IGxpa2VseSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaWtlbHkgPSAiRXh0cmVtZWx5IGxpa2VseSIpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoZmF2b3JfaHVtYW5pdGFyaWFuLCBmYXZvcl9odW1hbl9yaWdodHMsIGZhdm9yX2RldmVsb3BtZW50KSwKICAgICAgICAgICAgZnVucyhiaW4gPSBmY3RfcmVjb2RlKC4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE5vdCBmYXZvcmFibGVgID0gIlZlcnkgdW5mYXZvcmFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE5vdCBmYXZvcmFibGVgID0gIlVuZmF2b3JhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgZmF2b3JhYmxlYCA9ICJOZXV0cmFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhdm9yYWJsZSA9ICJGYXZvcmFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmF2b3JhYmxlID0gIlZlcnkgZmF2b3JhYmxlIikpKSAlPiUgCiAgbXV0YXRlKGdpdmVfY2hhcml0eV8zID0gZmN0X3JlY29kZShnaXZlX2NoYXJpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJPbmNlIGEgd2VlayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJPbmNlIGEgbW9udGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9uY2UgYSBtb250aC1vbmNlIGEgeWVhcmAgPSAiT25jZSBldmVyeSB0aHJlZSBtb250aHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9uY2UgYSBtb250aC1vbmNlIGEgeWVhcmAgPSAiT25jZSBldmVyeSBzaXggbW9udGhzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBPbmNlIGEgbW9udGgtb25jZSBhIHllYXJgID0gIk9uY2UgYSB5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJhcmVseSA9ICJPbmNlIGV2ZXJ5IGZldyB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSYXJlbHkgPSAiTmV2ZXIiKSAlPiUgZmN0X3JldigpLAogICAgICAgICBnaXZlX2NoYXJpdHlfMiA9IGZjdF9yZWNvZGUoZ2l2ZV9jaGFyaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYEF0IGxlYXN0IG9uY2UgYSB5ZWFyYCA9ICJPbmNlIGEgd2VlayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIHllYXJgID0gIk9uY2UgYSBtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIHllYXJgID0gIk9uY2UgZXZlcnkgdGhyZWUgbW9udGhzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmNlIGEgeWVhcmAgPSAiT25jZSBldmVyeSBzaXggbW9udGhzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmNlIGEgeWVhcmAgPSAiT25jZSBhIHllYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmFyZWx5ID0gIk9uY2UgZXZlcnkgZmV3IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJhcmVseSA9ICJOZXZlciIpKSAlPiUgCiAgbXV0YXRlKHBvbGl0aWNhbF9rbm93bGVkZ2VfYmluID0gZmN0X3JlY29kZShwb2xpdGljYWxfa25vd2xlZGdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9mdGVuYCA9ICJNb3N0IG9mIHRoZSB0aW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBPZnRlbmAgPSAiU29tZSBvZiB0aGUgdGltZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm90IG9mdGVuYCA9ICJPbmx5IG5vdyBhbmQgdGhlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm90IG9mdGVuYCA9ICJIYXJkbHkgYXQgYWxsIikgJT4lIGZjdF9yZXYoKSkgJT4lIAogIG11dGF0ZShpZGVvbG9neV8zID0gZmN0X3JlY29kZShpZGVvbG9neSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYExpYmVyYWxgID0gIlN0cm9uZyBsaWJlcmFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYExpYmVyYWxgID0gIkxpYmVyYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTGliZXJhbGAgPSAiSW5kZXBlbmRlbnQsIGxlYW5pbmcgbGliZXJhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBJbmRlcGVuZGVudGAgPSAiSW5kZXBlbmRlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29uc2VydmF0aXZlYCA9ICJJbmRlcGVuZGVudCwgbGVhbmluZyBjb25zZXJ2YXRpdmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29uc2VydmF0aXZlYCA9ICJDb25zZXJ2YXRpdmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29uc2VydmF0aXZlYCA9ICJWZXJ5IGNvbnNlcnZhdGl2ZSIpICU+JSBmY3RfcmV2KCkpICU+JSAKICBtdXRhdGUoaWRlb2xvZ3lfYmluID0gZmN0X3JlY29kZShpZGVvbG9neV8zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGliZXJhbGAgPSAiSW5kZXBlbmRlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGliZXJhbGAgPSAiQ29uc2VydmF0aXZlIikpICU+JSAKICBtdXRhdGUoZWR1Y2F0aW9uX2JpbiA9IGZjdF9yZWNvZGUoZWR1Y2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm8gQkFgID0gIkxlc3MgdGhhbiBoaWdoIHNjaG9vbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBObyBCQWAgPSAiSGlnaCBzY2hvb2wgZ3JhZHVhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm8gQkFgID0gIlNvbWUgY29sbGVnZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBObyBCQWAgPSAiMiB5ZWFyIGRlZ3JlZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBCQSBhbmQgYWJvdmVgID0gIjQgeWVhciBkZWdyZWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQkEgYW5kIGFib3ZlYCA9ICJHcmFkdWF0ZSBvciBwcm9mZXNzaW9uYWwgZGVncmVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYEJBIGFuZCBhYm92ZWAgPSAiRG9jdG9yYXRlIikpICU+JSAKICBtdXRhdGUocmVsaWdpb3NpdHlfYmluID0gZmN0X3JlY29kZShyZWxpZ2lvc2l0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJNb3JlIHRoYW4gb25jZSBhIHdlZWsiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmNlIGEgbW9udGhgID0gIk9uY2UgYSB3ZWVrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJPbmNlIG9yIHR3aWNlIGEgbW9udGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBSYXJlbHlgID0gIkEgZmV3IHRpbWVzIGEgeWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFJhcmVseWAgPSAiU2VsZG9tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgUmFyZWx5YCA9ICJOZXZlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCA9ICJEb24ndCBrbm93IikgJT4lIGZjdF9yZXYoKSkgJT4lIAogIG11dGF0ZShpbmNvbWVfY2xlYW4gPSBmY3RfcmVjb2RlKGluY29tZSwgTlVMTCA9ICJQcmVmZXIgbm90IHRvIHNheSIpLAogICAgICAgICBpbmNvbWVfYmluID0gZmFjdG9yKGluY29tZV9jbGVhbiA+PSBtZWRpYW4oLiRpbmNvbWUpLCBsZXZlbHMgPSBjKEZBTFNFLCBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBwYXN0ZShjKCJMZXNzIHRoYW4iLCAiQXQgbGVhc3QiKSwgbWVkaWFuKC4kaW5jb21lKSkpKSAlPiUgCiAgbXV0YXRlKGFnZV9iaW4gPSBmYWN0b3IoYWdlID49IG1lZGlhbiguJGFnZSksIGxldmVscyA9IGMoRkFMU0UsIFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHBhc3RlKGMoIkxlc3MgdGhhbiIsICJBdCBsZWFzdCIpLCBtZWRpYW4oLiRhZ2UpKSksCiAgICAgICAgIGdlbmRlcl9iaW4gPSBmY3RfY29sbGFwc2UoZ2VuZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZlbWFsZSA9ICJGZW1hbGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgRmVtYWxlYCA9IGMoIk1hbGUiLCAiVHJhbnNnZW5kZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciIsICJQcmVmZXIgbm90IHRvIHNheSIpKSkKCiMgU2F2ZSBmaW5hbCBjbGVhbiBkYXRhCnNhdmVSRFMocmVzdWx0cywgaGVyZSgiZGF0YSIsICJkZXJpdmVkX2RhdGEiLCAicmVzdWx0c19jbGVhbi5yZHMiKSkKd3JpdGVfY3N2eShyZXN1bHRzLCBmaWxlID0gaGVyZSgiZGF0YSIsICJkZXJpdmVkX2RhdGEiLCAicmVzdWx0c19jbGVhbi5jc3YiKSwKICAgICAgICAgICBtZXRhZGF0YSA9IGhlcmUoImRhdGEiLCAiZGVyaXZlZF9kYXRhIiwgInJlc3VsdHNfY2xlYW4ueWFtbCIpLCBuYSA9ICJOQSIpCmBgYAoKYGBge3IgY29tcGxldGVkLXN1bW1hcnl9CiMgU2F2ZSBpbmZvcm1hdGlvbiBhYm91dCBjb21wbGV0aW9uIHJhdGVzCmNvbXBsZXRlZF9za2VsZXRvbiA8LSByZXN1bHRzX2NoZWNrX2F0dGVudGlvbiAlPiUgCiAgbGVmdF9qb2luKGNvZGVzX3RvX2V4Y2x1ZGUsIGJ5ID0gImNvbmZpcm1hdGlvbl9jb2RlIikgJT4lIAogIHJlcGxhY2VfbmEobGlzdChyZWFzb24gPSAiQXBwcm92ZWQiKSkgJT4lIAogIGV4cGFuZChyZWFzb24sIGNyYWNrZG93biwgaXNzdWUsIGZ1bmRpbmcpCgpjb21wbGV0ZWRfc3VtbWFyeSA8LSByZXN1bHRzX2NoZWNrX2F0dGVudGlvbiAlPiUgCiAgbGVmdF9qb2luKGNvZGVzX3RvX2V4Y2x1ZGUsIGJ5ID0gImNvbmZpcm1hdGlvbl9jb2RlIikgJT4lIAogIHJlcGxhY2VfbmEobGlzdChyZWFzb24gPSAiQXBwcm92ZWQiKSkgJT4lIAogIGNvdW50KHJlYXNvbiwgY3JhY2tkb3duLCBpc3N1ZSwgZnVuZGluZykgJT4lIAogIHJpZ2h0X2pvaW4oY29tcGxldGVkX3NrZWxldG9uLCBieSA9IGMoInJlYXNvbiIsICJjcmFja2Rvd24iLCAiaXNzdWUiLCAiZnVuZGluZyIpKSAlPiUgCiAgcmVwbGFjZV9uYShsaXN0KG4gPSAwKSkKCnNhdmVSRFMoY29tcGxldGVkX3N1bW1hcnksIGhlcmUoImRhdGEiLCAiZGVyaXZlZF9kYXRhIiwgImNvbXBsZXRpb25fc3VtbWFyeS5yZHMiKSkKd3JpdGVfY3N2KGNvbXBsZXRlZF9zdW1tYXJ5LCBoZXJlKCJkYXRhIiwgImRlcml2ZWRfZGF0YSIsICJjb21wbGV0aW9uX3N1bW1hcnkuY3N2IikpCmBgYAoKCiMgT3JpZ2luYWwgY29tcHV0aW5nIGVudmlyb25tZW50Cgo8YnV0dG9uIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNzZXNzaW9uaW5mbyIgY2xhc3M9ImJ0biBidG4tcHJpbWFyeSBidG4tbWQgYnRuLWluZm8iPkhlcmUncyB3aGF0IHdlIHVzZWQgdGhlIGxhc3QgdGltZSB3ZSBidWlsdCB0aGlzIHBhZ2U8L2J1dHRvbj4KCjxkaXYgaWQ9InNlc3Npb25pbmZvIiBjbGFzcz0iY29sbGFwc2UiPgoKYGBge3Igc2hvdy1zZXNzaW9uLWluZm8sIGVjaG89VFJVRSwgd2lkdGg9OTB9CndyaXRlTGluZXMocmVhZExpbmVzKGZpbGUucGF0aChTeXMuZ2V0ZW52KCJIT01FIiksICIuUi9NYWtldmFycyIpKSkKCmRldnRvb2xzOjpzZXNzaW9uX2luZm8oKQpgYGAKCjwvZGl2PiAgCg==