Causal Impact

CAUSAL IMPACT BY GENDER

baseline_liwc_gender %>% 
  select(-text, -created_at, -id_tweet, -name) %>% 
  group_by(gender, id, days_tweet) %>% 
  summarise_all(mean) %>% 
  ungroup() %>% 
  select(-id) %>% 
  group_by(gender, days_tweet) %>% 
  summarise_all(mean) %>% 
  ungroup() %>% 
  pivot_longer(cols = fun:filler, names_to = "categ", values_to = "values_baseline") -> ci_baseline

neda_liwc_gender %>% 
  select(-id_tweet, -name, -name_proc) %>% 
  group_by(gender, id, days_tweet) %>% 
  summarise_all(mean) %>% 
  ungroup() %>% 
  select(-id) %>% 
  group_by(gender, days_tweet) %>% 
  summarise_all(mean) %>% 
  ungroup() %>% 
  pivot_longer(fun:filler, names_to = "categ", 
               values_to = "values_neda") -> ci_neda_liwc 

pre_period <- c(1, 16)
post_period <- c(17, 31)

ci_baseline %>% 
  full_join(ci_neda_liwc) -> d_second

d_second %>% 
  # count(gender, days_tweet) %>% 
  # view()
  # view()
  # select(categ, values_neda, values_baseline) %>% 
  # nest(data = - categ) %>% 
  select(gender, categ, values_neda, values_baseline) %>%
  # filter(gender == "m") %>% view()
  group_by(categ, gender) %>% 
  nest() %>% 
  ungroup() %>% 
  select(gender, categ, data) %>% 
  mutate(mod = map(data, ~CausalImpact::CausalImpact(., 
                                                     pre_period,
                                                     post_period))) -> ci
  
ci %>% 
  mutate(summary_mod = map(mod, "summary")) %>% 
  filter(!map_lgl(summary_mod, is.null)) -> ci_resul 

ci_resul %>% 
  mutate(p = map(summary_mod, "p")) %>% 
  mutate(p = map_dbl(p, 1)) %>% 
  filter(categ %in% c("female",
                      "family",
                      "anx",
                      "relig",
                      "money",
                      "they",
                      "achiev",
                      "negate",
                      "health",
                      "power",
                      "negemo",
                      "informal",
                      "ipron",
                      "you",
                      "discrep",
                      "differ",
                      "tentat",
                      "posemo",
                      "shehe",
                      "affiliation")) %>% 
  mutate(relative_effect = map(summary_mod, "RelEffect")) %>% 
  mutate(relative_effect = map_dbl(relative_effect, 2))-> sig_cat

# sig_cat %>% 
#   filter(categ %in% sel_cat) -> sig_cat

sig_cat %>% 
  arrange(gender, desc(relative_effect)) %>% 
  select(gender, categ, 
         second_relative_effect = relative_effect, p_second = p) -> second_ap

second_ap %>% 
  pivot_wider(id_cols = categ, 
              values_from = c(second_relative_effect, p_second),
              names_from = gender) %>% 
  mutate(categ = str_to_title(categ)) %>% 
  mutate_at(vars(starts_with("second")), ~.*100) %>% 
  mutate_if(is.numeric, ~round(., digits = 3)) %>% 
  mutate_at(vars(starts_with("second")), function(x){
    cell_spec(x, "html", color = spec_color(x), bold = T)
  }) %>% 
  kable("html", escape = F,
        align = "lrr",
        col.names = c("Word Category", "FEMALE Relative Eff.(%)",
                      "MALE Relative Eff.(%)",
                      "UNKNOWN Relative Eff.(%)",
                      "FEMALE P Value",
                      "MALE P Value",
                      "UNKNOWN P Value")) %>%  
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE)
Word Category FEMALE Relative Eff.(%) MALE Relative Eff.(%) UNKNOWN Relative Eff.(%) FEMALE P Value MALE P Value UNKNOWN P Value
Anx 13.196 1.808 10.928 0.001 0.313 0.005
Female 12.601 15.836 19.852 0.001 0.001 0.001
Family 7.904 1.151 14.691 0.012 0.350 0.001
Achiev 6.533 -1.29 0.71 0.004 0.289 0.384
Relig 5.685 -1.697 17.331 0.030 0.328 0.001
They 5.086 -1.85 3.6 0.005 0.291 0.057
Negemo 4.489 -4.545 -0.366 0.001 0.008 0.438
Money 4.037 16.973 5.994 0.035 0.001 0.021
Power 3.875 2.584 4.018 0.001 0.044 0.003
Negate 3.107 -2.063 3.02 0.015 0.158 0.104
Health 2.93 5.301 -4.463 0.070 0.060 0.009
Ipron 0.376 -1.107 -1.675 0.358 0.229 0.049
Informal 0.239 2.044 1.418 0.365 0.036 0.068
Tentat -0.532 -1.518 -6.818 0.380 0.176 0.001
Differ -1.323 -2.077 -0.054 0.137 0.070 0.485
Posemo -2.319 -5.974 -1.489 0.005 0.001 0.092
You -2.321 0.197 -3.912 0.021 0.451 0.002
Discrep -3.547 -5.811 0.608 0.006 0.023 0.334
Affiliation -5.274 -7.818 -7.205 0.004 0.001 0.011
Shehe -7.708 -3.775 -5.058 0.023 0.221 0.050

Words inside categ:

The tables below contain the changes for the 4 most changed words (positive and negative) within each of the categories. The first column is the specific word. Changes_total is the difference between the “before” and “after” frequency of all users. Changes_f same as Changes_total but for female users, Changes_m for male users and Changes_u for unknown users.

library(tidyverse)

read_delim(here::here("data", "liwc", "LIWC2015_English_Flat.dic"),
           delim = "\t", skip = 1, col_names = c("number", "name"), 
           n_max = 73) -> categories_name 

read_tsv(here::here("data", "liwc", "LIWC2015_English_Flat.dic"),
         skip = 75, col_names = paste0(c("x"), c("_"), 1:11),
         guess_max = 6000, col_types = "ccccccccccc") %>% 
  mutate(x_1 = str_remove(x_1, "\\*")) -> words_dic

categories_name %>% 
  filter(name %in% c("female", "family", "anx", "shehe", "affiliation", "friend")) %>% 
  pull(number) -> number_top_categ

words_dic %>% 
  filter_at(vars(-x_1), any_vars(. %in% number_top_categ)) %>%  
  pull(x_1) -> words_cat


# neda_timelapse ----------------------------------------------------------

library(lubridate)

neda_hist <- read_rds(here::here("data", "NEDA_historical.rds")) %>% 
  distinct() %>% 
  filter(created_at_tweet >= ymd("2018-03-01")) %>% 
  mutate(text = str_to_lower(text),
         neda_related = str_detect(text, 
                                   pattern = "#nedawareness|#comeasyouare|@nedastaff")) 

gender_output <- read_tsv(here::here("data", "gender_extractor", 
                                     "neda_liwc_gender_output.tsv"),
                          col_names = c("id", "name", "name_proc", "gender"))

first_tweet <- neda_hist %>% 
  select(created_at_tweet, text, id, id_tweet, neda_related) %>% 
  filter(neda_related) %>% 
  arrange(created_at_tweet) %>% 
  group_by(id) %>% 
  slice(1) %>% 
  ungroup() %>% 
  select(cero_date = created_at_tweet, id) %>% 
  filter(cero_date >= ymd("2019-01-01"))

neda_change <- neda_hist %>% 
  select(id_tweet, text, created_at_tweet, id) %>% 
  inner_join(first_tweet) %>% 
  mutate(days_tweet = interval(start = cero_date, end = created_at_tweet),
         days_tweet = round(time_length(days_tweet, unit = "days"))) %>% 
  select(-cero_date) %>% 
  filter(days_tweet >= -15, days_tweet <= 15)

neda_timelapse <- neda_change %>%
  count(id, before_after = sign(days_tweet), sort = T) %>% 
  mutate(before_after = case_when(before_after == -1 ~ "before",
                                  before_after == 1 ~ "after",
                                  TRUE ~ "cero")) %>% 
  pivot_wider(values_from = n, names_from = before_after) %>% 
  filter(before >= 15 & after >= 15) %>% 
  select(-cero) %>% 
  semi_join(x = neda_change, y = .)

neda_timelapse %>% 
  inner_join(gender_output) -> neda_timelapse

library(tidytext)

replace_reg1 <- "https://t.co/[A-Za-z]\\d]+|"
replace_reg2 <- "https://t.co/[A-Za-z]\\d]+|&amp;|&lt;|&gt;|RT|https"
replace_reg <- paste0(replace_reg1, replace_reg2)
unnest_reg <- "([^A-Za-z_\\d#@']|'(?![A-Za-z_\\d#@]))"

tidy_tweets <- neda_timelapse %>%
  mutate(text = str_to_lower(text)) %>% 
  mutate(text = str_replace_all(text, replace_reg, "")) %>% 
  unnest_tokens(word, text, token = "regex", pattern = unnest_reg)

tidy_tweets %>% 
  filter(word %in% words_cat) %>% 
  mutate(days_tweet = case_when(days_tweet < 0 ~ "before",
                                days_tweet > 0 ~ "after",
                                TRUE ~ "cero")) %>% 
  filter(days_tweet != "cero") -> tidy_words

neda_liwc <- read_rds(here::here("data", "neda_liwc.rds")) %>% 
  select(-created_at_tweet) %>% 
  filter(abs(days_tweet) <= 15)

FEMALE CATEGORY

# female ------------------------------------------------------------------
# female -> 43

words_dic %>% 
  filter_at(vars(-x_1), any_vars(. == 43)) %>% 
  pull(x_1) -> words_female

tidy_words %>% 
  filter(word %in% words_female) %>% 
  count(days_tweet, word) %>% 
  mutate(gender = "t") %>% 
  bind_rows(tidy_words %>% 
              filter(word %in% words_female) %>% 
              count(gender, days_tweet, word)) %>% 
  pivot_wider(names_from = c(days_tweet, gender), values_from = n) %>% 
  mutate_if(is.numeric, ~replace_na(., 0)) %>% 
  mutate(changes_total = after_t - before_t,
         changes_f = after_f - before_f,
         changes_m = after_m - before_m,
         changes_u = after_u - before_u) %>% 
  select(word, starts_with("changes")) %>% 
  arrange(desc(changes_total)) -> f 

f_top <- f %>% top_n(4, wt = changes_total)
f_bottom <- f %>% top_n(-4, wt = changes_total)

f_top %>% 
  bind_rows(f_bottom) %>% 
  gt::gt()
word changes_total changes_f changes_m changes_u
women 2117 896 404 817
her 320 265 -1 56
she 228 307 -27 -52
woman 207 82 34 91
gf -30 -19 -7 -4
wife -78 -37 -33 -8
queen -96 3 -32 -67
lady -158 -112 -21 -25

FAMILY

words_dic %>% 
  filter_at(vars(-x_1), any_vars(. == 41)) %>% 
  pull(x_1) -> words_family

tidy_words %>% 
  filter(word %in% words_family) %>% 
  count(days_tweet, word) %>% 
  mutate(gender = "t") %>% 
  bind_rows(tidy_words %>% 
              filter(word %in% words_family) %>% 
              count(gender, days_tweet, word)) %>% 
  pivot_wider(names_from = c(days_tweet, gender), values_from = n) %>% 
  mutate_if(is.numeric, ~replace_na(., 0)) %>% 
  mutate(changes_total = after_t - before_t,
         changes_f = after_f - before_f,
         changes_m = after_m - before_m,
         changes_u = after_u - before_u) %>% 
  select(word, starts_with("changes")) %>% 
  arrange(desc(changes_total))  -> f 

f_top <- f %>% top_n(4, wt = changes_total)
f_bottom <- f %>% top_n(-4, wt = changes_total)

f_top %>% 
  bind_rows(f_bottom) %>% 
  gt::gt()
word changes_total changes_f changes_m changes_u
ma 132 52 54 26
family 122 98 14 10
daughter 115 39 24 52
families 88 49 22 17
mama -19 -23 0 4
pa -19 -14 7 -12
daddy -23 -9 -6 -8
bro -63 7 31 -101
wife -78 -37 -33 -8

ANXIETY

# anxiety -----------------------------------------------------------------
# anxiety -> 33

words_dic %>% 
  filter_at(vars(-x_1), any_vars(. == 33)) %>% 
  pull(x_1) -> words_anxiety

tidy_words %>% 
  filter(word %in% words_anxiety) %>% 
  count(days_tweet, word) %>% 
  mutate(gender = "t") %>% 
  bind_rows(tidy_words %>% 
              filter(word %in% words_anxiety) %>% 
              count(gender, days_tweet, word)) %>% 
  pivot_wider(names_from = c(days_tweet, gender), values_from = n) %>% 
  mutate_if(is.numeric, ~replace_na(., 0)) %>% 
  mutate(changes_total = after_t - before_t,
         changes_f = after_f - before_f,
         changes_m = after_m - before_m,
         changes_u = after_u - before_u) %>% 
  select(word, starts_with("changes")) %>% 
  arrange(desc(changes_total))  -> f 

f_top <- f %>% top_n(4, wt = changes_total)
f_bottom <- f %>% top_n(-4, wt = changes_total)

f_top %>% 
  bind_rows(f_bottom) %>% 
  gt::gt()
word changes_total changes_f changes_m changes_u
risk 190 15 115 60
stress 78 38 13 27
upset 73 30 13 30
worried 70 31 15 24
confuse -10 -6 1 -5
horrible -11 -5 1 -7
doubt -21 -11 -1 -9
scared -31 16 -12 -35

COMMON WORDS IN TWEETS BY WORDS CATEGORY:

neda_liwc_gender %>% 
  filter(days_tweet >= 0) %>% 
  select(id_tweet, id, gender, family, female, anx) %>% 
  pivot_longer(cols = family:anx) %>% 
  filter(value > 0) %>% 
  left_join(neda_liwc %>% 
              select(id, id_tweet, text)) %>%  
  rename("category" = name) %>% 
  mutate(text = str_remove_all(text, pattern = "[:graph:]+(…)")) %>% 
  unnest_tokens(word, text, token = "tweets") %>% 
  filter(!word %in% stop_words$word,
         word != "rt",
         !word %in% str_remove_all(stop_words$word, "'")) %>% 
  mutate(word = case_when(category == "female" & word %in% c(words_female,
                                                             "womens") ~ NA_character_,
                          category == "family" & word %in% c(words_family,
                                                             "parents",
                                                             "brothers")~ NA_character_,
                          category == "anx" & word %in% words_anxiety ~ NA_character_,
                          TRUE ~ word)) %>% 
  filter(!is.na(word),
         word != "amp") %>% 
  count(category, gender, word, sort = T) %>%
  group_by(gender, category) %>% 
  top_n(10, wt = n) %>% 
  ungroup() %>% 
  pivot_wider(id_cols = c(category, word), names_from = gender, values_from = n) %>% 
  mutate(category = str_to_title(category)) %>% 
  gt::gt(groupname_col = "category",
         rowname_col = "word")   
f u m
Female
day 491 432 222
love 390 274 130
happy 314 326 138
time 305 214 114
international 261 229 122
people 261 209 NA
black 234 204 97
notre NA 227 NA
de NA 201 113
life 182 NA 91
#internationalwomensday 158 179 NA
white 173 NA NA
amazing NA NA 103
world NA NA 93
Anx
love 136 362 151
people 340 287 98
struggling 225 204 NA
feel 163 117 NA
@swampmusicinfo NA 157 70
time 155 NA NA
struggle 148 NA NA
@laurarjacobs NA 148 NA
mental 147 108 NA
laura NA 145 NA
jacobs NA 135 NA
depression 118 NA NA
life 118 NA NA
ft NA 117 NA
eating 112 NA NA
3 NA NA 94
sixty NA NA 87
$safe NA NA 85
cse NA NA 85
solutions NA NA 85
news NA NA 83
@financialbuzz NA NA 80
Family
love 248 161 76
day 209 143 88
people 194 169 52
kids 191 151 NA
time 190 NA 72
de NA 176 171
ur NA 173 NA
apologize NA 170 NA
4 NA 164 NA
children 149 163 NA
da NA 157 NA
friends 135 NA 60
women 135 NA NA
child 127 NA NA
pregnant 118 NA NA
la NA NA 98
life NA NA 79
en NA NA 56
fathersrightshq NA NA 52
LS0tCnRpdGxlOiAiQ2F1c2FsIEltcGFjdCIgCmNsZWFuOiB0cnVlCm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogZmFsc2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKCnhmdW46OnBrZ19hdHRhY2goInRpZHl2ZXJzZSIsICJsdWJyaWRhdGUiLCAia2FibGVFeHRyYSIpCgp0aGVtZV9zZXQodGhlbWVfbGluZWRyYXcoKSkKYGBgCgojIyBDYXVzYWwgSW1wYWN0IAoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KYmFzZWxpbmVfbGl3YyA8LSByZWFkX3JkcyhoZXJlOjpoZXJlKCJkYXRhIiwgImJhc2VsaW5lX2xpd2MucmRzIikpCm5lZGFfbGl3YyA8LSByZWFkX3JkcyhoZXJlOjpoZXJlKCJkYXRhIiwgIm5lZGFfbGl3Yy5yZHMiKSkgJT4lIAogIHNlbGVjdCgtdGV4dCwgLWNyZWF0ZWRfYXRfdHdlZXQpICU+JSAKICBmaWx0ZXIoYWJzKGRheXNfdHdlZXQpIDw9IDE1KSAlPiUgCiAgCgpzZWxfY2F0IDwtIGMoCiAgImkiLCJ3ZSIsInlvdSIsInNoZWhlIiwidGhleSIsImlwcm9uIiwibmVnYXRlIiwiY29tcGFyZSIsInBvc2VtbyIsIm5lZ2VtbyIsImFueCIsImFuZ2VyIiwic2FkIiwic29jaWFsIiwiZmFtaWx5IiwiZnJpZW5kIiwiZmVtYWxlIiwibWFsZSIsImluc2lnaHQiLCJjYXVzZSIsImRpc2NyZXAiLCJ0ZW50YXQiLCJjZXJ0YWluIiwiZGlmZmVyIiwic2VlIiwiaGVhciIsImZlZWwiLCJib2R5IiwiaGVhbHRoIiwic2V4dWFsIiwiaW5nZXN0IiwiYWZmaWxpYXRpb24iLCJhY2hpZXYiLCJwb3dlciIsInJld2FyZCIsInJpc2siLCJmb2N1c3Bhc3QiLCJmb2N1c3ByZXNlbnQiLCJmb2N1c2Z1dHVyZSIsInJlbGF0aXYiLCJ3b3JrIiwibGVpc3VyZSIsImhvbWUiLCJtb25leSIsInJlbGlnIiwiZGVhdGgiLCJpbmZvcm1hbCIsInN3ZWFyIiwiYXNzZW50Iiwibm9uZmx1IiwiZmlsbGVyIgopCmBgYAoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KYmFzZWxpbmVfbGl3YyAlPiUgCiAgc2VsZWN0KC10ZXh0LCAtY3JlYXRlZF9hdCwgLWlkX3R3ZWV0KSAlPiUgCiAgZ3JvdXBfYnkoZGF5c190d2VldCwgaWQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdCgtaWQpICU+JSAKICBncm91cF9ieShkYXlzX3R3ZWV0KSAlPiUgCiAgc3VtbWFyaXNlX2FsbChtZWFuKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGZ1bjpmaWxsZXIsIG5hbWVzX3RvID0gImNhdGVnIiwgdmFsdWVzX3RvID0gInZhbHVlc19iYXNlbGluZSIpIC0+IGNpX2Jhc2VsaW5lCgpuZWRhX2xpd2MgJT4lIAogIHNlbGVjdCgtaWRfdHdlZXQpICU+JSAKICBncm91cF9ieShkYXlzX3R3ZWV0LCBpZCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KC1pZCkgJT4lIAogIGdyb3VwX2J5KGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHBpdm90X2xvbmdlcigtZGF5c190d2VldCwgbmFtZXNfdG8gPSAiY2F0ZWciLCB2YWx1ZXNfdG8gPSAidmFsdWVzX25lZGEiKSAtPiBjaV9uZWRhX2xpd2MgCiAgCnByZV9wZXJpb2QgPC0gYygxLCAxNikKcG9zdF9wZXJpb2QgPC0gYygxNywgMzEpCgpjaV9iYXNlbGluZSAlPiUgCiAgaW5uZXJfam9pbihjaV9uZWRhX2xpd2MpIC0+IGRfc2Vjb25kCgpkX3NlY29uZCAlPiUgCiAgc2VsZWN0KGNhdGVnLCB2YWx1ZXNfbmVkYSwgdmFsdWVzX2Jhc2VsaW5lKSAlPiUgCiAgbmVzdChkYXRhID0gLSBjYXRlZykgJT4lIAogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfkNhdXNhbEltcGFjdDo6Q2F1c2FsSW1wYWN0KC4sIHByZV9wZXJpb2QsIHBvc3RfcGVyaW9kKSkpIC0+IGNpCiAgCmNpICU+JSAKICBtdXRhdGUoc3VtbWFyeV9tb2QgPSBtYXAobW9kLCAic3VtbWFyeSIpKSAlPiUgCiAgZmlsdGVyKCFtYXBfbGdsKHN1bW1hcnlfbW9kLCBpcy5udWxsKSkgLT4gY2lfcmVzdWwgCgpjaV9yZXN1bCAlPiUgCiAgbXV0YXRlKHAgPSBtYXAoc3VtbWFyeV9tb2QsICJwIikpICU+JSAKICBtdXRhdGUocCA9IG1hcF9kYmwocCwgMSkpICU+JSAKICBmaWx0ZXIocCA8IDAuMDUpICU+JSAKICBtdXRhdGUocmVsYXRpdmVfZWZmZWN0ID0gbWFwKHN1bW1hcnlfbW9kLCAiUmVsRWZmZWN0IikpICU+JSAKICBtdXRhdGUocmVsYXRpdmVfZWZmZWN0ID0gbWFwX2RibChyZWxhdGl2ZV9lZmZlY3QsIDIpKS0+IHNpZ19jYXQKCnNpZ19jYXQgJT4lIAogIGZpbHRlcihjYXRlZyAlaW4lIHNlbF9jYXQpIC0+IHNpZ19jYXQKCnNpZ19jYXQgJT4lIAogIGFycmFuZ2UoZGVzYyhyZWxhdGl2ZV9lZmZlY3QpKSAlPiUgCiAgc2VsZWN0KGNhdGVnLCBzZWNvbmRfcmVsYXRpdmVfZWZmZWN0ID0gcmVsYXRpdmVfZWZmZWN0LCBwX3NlY29uZCA9IHApIC0+IHNlY29uZF9hcAoKc2Vjb25kX2FwICU+JSAKICBtdXRhdGUoY2F0ZWcgPSBzdHJfdG9fdGl0bGUoY2F0ZWcpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCksIH4uKjEwMCkgJT4lIAogIG11dGF0ZV9pZihpcy5udW1lcmljLCB+cm91bmQoLiwgZGlnaXRzID0gMykpICU+JSAKICBtdXRhdGVfYXQodmFycyhzZWNvbmRfcmVsYXRpdmVfZWZmZWN0KSwgZnVuY3Rpb24oeCl7CiAgICBjZWxsX3NwZWMoeCwgImh0bWwiLCBjb2xvciA9IHNwZWNfY29sb3IoeCksIGJvbGQgPSBUKQogIH0pICU+JSAKICBrYWJsZSgiaHRtbCIsIGVzY2FwZSA9IEYsCiAgICAgICAgYWxpZ24gPSAibHJyIiwKICAgICAgICBjb2wubmFtZXMgPSBjKCJXb3JkIENhdGVnb3J5IiwgIlJlbGF0aXZlIEVmZi4oJSkiLAogICAgICAgICAgICAgICAgICAgICAgIlAgVmFsdWUiKSkgJT4lIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLAogICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAKCiMjIENBVVNBTCBJTVBBQ1QgQlkgR0VOREVSCgpgYGB7ciBlY2hvPUZBTFNFfQpiYXNlbGluZV9saXdjX2dlbmRlciA8LSByZWFkX3JkcyhoZXJlOjpoZXJlKCJkYXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmFzZWxpbmVfbGl3Y19nZW5kZXIucmRzIikpCgpuZWRhX2xpd2NfZ2VuZGVyIDwtIHJlYWRfcmRzKGhlcmU6OmhlcmUoImRhdGEiLCAibmVkYV9saXdjX2dlbmRlci5yZHMiKSkgJT4lIAogICMgc2VsZWN0KC10ZXh0LCAtY3JlYXRlZF9hdF90d2VldCkgJT4lIAogIGZpbHRlcihhYnMoZGF5c190d2VldCkgPD0gMTUpCgpzZWxfY2F0IDwtIGMoCiAgImkiLCJ3ZSIsInlvdSIsInNoZWhlIiwidGhleSIsImlwcm9uIiwibmVnYXRlIiwiY29tcGFyZSIsInBvc2VtbyIsIm5lZ2VtbyIsImFueCIsImFuZ2VyIiwic2FkIiwic29jaWFsIiwiZmFtaWx5IiwiZnJpZW5kIiwiZmVtYWxlIiwibWFsZSIsImluc2lnaHQiLCJjYXVzZSIsImRpc2NyZXAiLCJ0ZW50YXQiLCJjZXJ0YWluIiwiZGlmZmVyIiwic2VlIiwiaGVhciIsImZlZWwiLCJib2R5IiwiaGVhbHRoIiwic2V4dWFsIiwiaW5nZXN0IiwiYWZmaWxpYXRpb24iLCJhY2hpZXYiLCJwb3dlciIsInJld2FyZCIsInJpc2siLCJmb2N1c3Bhc3QiLCJmb2N1c3ByZXNlbnQiLCJmb2N1c2Z1dHVyZSIsInJlbGF0aXYiLCJ3b3JrIiwibGVpc3VyZSIsImhvbWUiLCJtb25leSIsInJlbGlnIiwiZGVhdGgiLCJpbmZvcm1hbCIsInN3ZWFyIiwiYXNzZW50Iiwibm9uZmx1IiwiZmlsbGVyIgopCmBgYAoKYGBge3IgfQpiYXNlbGluZV9saXdjX2dlbmRlciAlPiUgCiAgc2VsZWN0KC10ZXh0LCAtY3JlYXRlZF9hdCwgLWlkX3R3ZWV0LCAtbmFtZSkgJT4lIAogIGdyb3VwX2J5KGdlbmRlciwgaWQsIGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdCgtaWQpICU+JSAKICBncm91cF9ieShnZW5kZXIsIGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gZnVuOmZpbGxlciwgbmFtZXNfdG8gPSAiY2F0ZWciLCB2YWx1ZXNfdG8gPSAidmFsdWVzX2Jhc2VsaW5lIikgLT4gY2lfYmFzZWxpbmUKCm5lZGFfbGl3Y19nZW5kZXIgJT4lIAogIHNlbGVjdCgtaWRfdHdlZXQsIC1uYW1lLCAtbmFtZV9wcm9jKSAlPiUgCiAgZ3JvdXBfYnkoZ2VuZGVyLCBpZCwgZGF5c190d2VldCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KC1pZCkgJT4lIAogIGdyb3VwX2J5KGdlbmRlciwgZGF5c190d2VldCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGZ1bjpmaWxsZXIsIG5hbWVzX3RvID0gImNhdGVnIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZXNfbmVkYSIpIC0+IGNpX25lZGFfbGl3YyAKCnByZV9wZXJpb2QgPC0gYygxLCAxNikKcG9zdF9wZXJpb2QgPC0gYygxNywgMzEpCgpjaV9iYXNlbGluZSAlPiUgCiAgZnVsbF9qb2luKGNpX25lZGFfbGl3YykgLT4gZF9zZWNvbmQKCmRfc2Vjb25kICU+JSAKICAjIGNvdW50KGdlbmRlciwgZGF5c190d2VldCkgJT4lIAogICMgdmlldygpCiAgIyB2aWV3KCkKICAjIHNlbGVjdChjYXRlZywgdmFsdWVzX25lZGEsIHZhbHVlc19iYXNlbGluZSkgJT4lIAogICMgbmVzdChkYXRhID0gLSBjYXRlZykgJT4lIAogIHNlbGVjdChnZW5kZXIsIGNhdGVnLCB2YWx1ZXNfbmVkYSwgdmFsdWVzX2Jhc2VsaW5lKSAlPiUKICAjIGZpbHRlcihnZW5kZXIgPT0gIm0iKSAlPiUgdmlldygpCiAgZ3JvdXBfYnkoY2F0ZWcsIGdlbmRlcikgJT4lIAogIG5lc3QoKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoZ2VuZGVyLCBjYXRlZywgZGF0YSkgJT4lIAogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfkNhdXNhbEltcGFjdDo6Q2F1c2FsSW1wYWN0KC4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZV9wZXJpb2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zdF9wZXJpb2QpKSkgLT4gY2kKICAKY2kgJT4lIAogIG11dGF0ZShzdW1tYXJ5X21vZCA9IG1hcChtb2QsICJzdW1tYXJ5IikpICU+JSAKICBmaWx0ZXIoIW1hcF9sZ2woc3VtbWFyeV9tb2QsIGlzLm51bGwpKSAtPiBjaV9yZXN1bCAKCmNpX3Jlc3VsICU+JSAKICBtdXRhdGUocCA9IG1hcChzdW1tYXJ5X21vZCwgInAiKSkgJT4lIAogIG11dGF0ZShwID0gbWFwX2RibChwLCAxKSkgJT4lIAogIGZpbHRlcihjYXRlZyAlaW4lIGMoImZlbWFsZSIsCiAgICAgICAgICAgICAgICAgICAgICAiZmFtaWx5IiwKICAgICAgICAgICAgICAgICAgICAgICJhbngiLAogICAgICAgICAgICAgICAgICAgICAgInJlbGlnIiwKICAgICAgICAgICAgICAgICAgICAgICJtb25leSIsCiAgICAgICAgICAgICAgICAgICAgICAidGhleSIsCiAgICAgICAgICAgICAgICAgICAgICAiYWNoaWV2IiwKICAgICAgICAgICAgICAgICAgICAgICJuZWdhdGUiLAogICAgICAgICAgICAgICAgICAgICAgImhlYWx0aCIsCiAgICAgICAgICAgICAgICAgICAgICAicG93ZXIiLAogICAgICAgICAgICAgICAgICAgICAgIm5lZ2VtbyIsCiAgICAgICAgICAgICAgICAgICAgICAiaW5mb3JtYWwiLAogICAgICAgICAgICAgICAgICAgICAgImlwcm9uIiwKICAgICAgICAgICAgICAgICAgICAgICJ5b3UiLAogICAgICAgICAgICAgICAgICAgICAgImRpc2NyZXAiLAogICAgICAgICAgICAgICAgICAgICAgImRpZmZlciIsCiAgICAgICAgICAgICAgICAgICAgICAidGVudGF0IiwKICAgICAgICAgICAgICAgICAgICAgICJwb3NlbW8iLAogICAgICAgICAgICAgICAgICAgICAgInNoZWhlIiwKICAgICAgICAgICAgICAgICAgICAgICJhZmZpbGlhdGlvbiIpKSAlPiUgCiAgbXV0YXRlKHJlbGF0aXZlX2VmZmVjdCA9IG1hcChzdW1tYXJ5X21vZCwgIlJlbEVmZmVjdCIpKSAlPiUgCiAgbXV0YXRlKHJlbGF0aXZlX2VmZmVjdCA9IG1hcF9kYmwocmVsYXRpdmVfZWZmZWN0LCAyKSktPiBzaWdfY2F0CgojIHNpZ19jYXQgJT4lIAojICAgZmlsdGVyKGNhdGVnICVpbiUgc2VsX2NhdCkgLT4gc2lnX2NhdAoKc2lnX2NhdCAlPiUgCiAgYXJyYW5nZShnZW5kZXIsIGRlc2MocmVsYXRpdmVfZWZmZWN0KSkgJT4lIAogIHNlbGVjdChnZW5kZXIsIGNhdGVnLCAKICAgICAgICAgc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCA9IHJlbGF0aXZlX2VmZmVjdCwgcF9zZWNvbmQgPSBwKSAtPiBzZWNvbmRfYXAKCnNlY29uZF9hcCAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGNhdGVnLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGMoc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCwgcF9zZWNvbmQpLAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBnZW5kZXIpICU+JSAKICBtdXRhdGUoY2F0ZWcgPSBzdHJfdG9fdGl0bGUoY2F0ZWcpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoInNlY29uZCIpKSwgfi4qMTAwKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yb3VuZCguLCBkaWdpdHMgPSAzKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKHN0YXJ0c193aXRoKCJzZWNvbmQiKSksIGZ1bmN0aW9uKHgpewogICAgY2VsbF9zcGVjKHgsICJodG1sIiwgY29sb3IgPSBzcGVjX2NvbG9yKHgpLCBib2xkID0gVCkKICB9KSAlPiUgCiAga2FibGUoImh0bWwiLCBlc2NhcGUgPSBGLAogICAgICAgIGFsaWduID0gImxyciIsCiAgICAgICAgY29sLm5hbWVzID0gYygiV29yZCBDYXRlZ29yeSIsICJGRU1BTEUgUmVsYXRpdmUgRWZmLiglKSIsCiAgICAgICAgICAgICAgICAgICAgICAiTUFMRSBSZWxhdGl2ZSBFZmYuKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICJVTktOT1dOIFJlbGF0aXZlIEVmZi4oJSkiLAogICAgICAgICAgICAgICAgICAgICAgIkZFTUFMRSBQIFZhbHVlIiwKICAgICAgICAgICAgICAgICAgICAgICJNQUxFIFAgVmFsdWUiLAogICAgICAgICAgICAgICAgICAgICAgIlVOS05PV04gUCBWYWx1ZSIpKSAlPiUgIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLAogICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAKCiMjIFdvcmRzIGluc2lkZSBjYXRlZzoKClRoZSB0YWJsZXMgYmVsb3cgY29udGFpbiB0aGUgY2hhbmdlcyBmb3IgdGhlIDQgbW9zdCBjaGFuZ2VkIHdvcmRzIChwb3NpdGl2ZSBhbmQgbmVnYXRpdmUpIHdpdGhpbiBlYWNoIG9mIHRoZSBjYXRlZ29yaWVzLiBUaGUgZmlyc3QgY29sdW1uIGlzIHRoZSBzcGVjaWZpYyB3b3JkLiBDaGFuZ2VzX3RvdGFsIGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlICJiZWZvcmUiIGFuZCAiYWZ0ZXIiIGZyZXF1ZW5jeSBvZiBhbGwgdXNlcnMuIENoYW5nZXNfZiBzYW1lIGFzIENoYW5nZXNfdG90YWwgYnV0IGZvciBmZW1hbGUgdXNlcnMsIENoYW5nZXNfbSBmb3IgbWFsZSB1c2VycyBhbmQgQ2hhbmdlc191IGZvciB1bmtub3duIHVzZXJzLgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQoKcmVhZF9kZWxpbShoZXJlOjpoZXJlKCJkYXRhIiwgImxpd2MiLCAiTElXQzIwMTVfRW5nbGlzaF9GbGF0LmRpYyIpLAogICAgICAgICAgIGRlbGltID0gIlx0Iiwgc2tpcCA9IDEsIGNvbF9uYW1lcyA9IGMoIm51bWJlciIsICJuYW1lIiksIAogICAgICAgICAgIG5fbWF4ID0gNzMpIC0+IGNhdGVnb3JpZXNfbmFtZSAKCnJlYWRfdHN2KGhlcmU6OmhlcmUoImRhdGEiLCAibGl3YyIsICJMSVdDMjAxNV9FbmdsaXNoX0ZsYXQuZGljIiksCiAgICAgICAgIHNraXAgPSA3NSwgY29sX25hbWVzID0gcGFzdGUwKGMoIngiKSwgYygiXyIpLCAxOjExKSwKICAgICAgICAgZ3Vlc3NfbWF4ID0gNjAwMCwgY29sX3R5cGVzID0gImNjY2NjY2NjY2NjIikgJT4lIAogIG11dGF0ZSh4XzEgPSBzdHJfcmVtb3ZlKHhfMSwgIlxcKiIpKSAtPiB3b3Jkc19kaWMKCmNhdGVnb3JpZXNfbmFtZSAlPiUgCiAgZmlsdGVyKG5hbWUgJWluJSBjKCJmZW1hbGUiLCAiZmFtaWx5IiwgImFueCIsICJzaGVoZSIsICJhZmZpbGlhdGlvbiIsICJmcmllbmQiKSkgJT4lIAogIHB1bGwobnVtYmVyKSAtPiBudW1iZXJfdG9wX2NhdGVnCgp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguICVpbiUgbnVtYmVyX3RvcF9jYXRlZykpICU+JSAgCiAgcHVsbCh4XzEpIC0+IHdvcmRzX2NhdAoKCiMgbmVkYV90aW1lbGFwc2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbGlicmFyeShsdWJyaWRhdGUpCgpuZWRhX2hpc3QgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsICJORURBX2hpc3RvcmljYWwucmRzIikpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBmaWx0ZXIoY3JlYXRlZF9hdF90d2VldCA+PSB5bWQoIjIwMTgtMDMtMDEiKSkgJT4lIAogIG11dGF0ZSh0ZXh0ID0gc3RyX3RvX2xvd2VyKHRleHQpLAogICAgICAgICBuZWRhX3JlbGF0ZWQgPSBzdHJfZGV0ZWN0KHRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiI25lZGF3YXJlbmVzc3wjY29tZWFzeW91YXJlfEBuZWRhc3RhZmYiKSkgCgpnZW5kZXJfb3V0cHV0IDwtIHJlYWRfdHN2KGhlcmU6OmhlcmUoImRhdGEiLCAiZ2VuZGVyX2V4dHJhY3RvciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZGFfbGl3Y19nZW5kZXJfb3V0cHV0LnRzdiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9uYW1lcyA9IGMoImlkIiwgIm5hbWUiLCAibmFtZV9wcm9jIiwgImdlbmRlciIpKQoKZmlyc3RfdHdlZXQgPC0gbmVkYV9oaXN0ICU+JSAKICBzZWxlY3QoY3JlYXRlZF9hdF90d2VldCwgdGV4dCwgaWQsIGlkX3R3ZWV0LCBuZWRhX3JlbGF0ZWQpICU+JSAKICBmaWx0ZXIobmVkYV9yZWxhdGVkKSAlPiUgCiAgYXJyYW5nZShjcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiAgZ3JvdXBfYnkoaWQpICU+JSAKICBzbGljZSgxKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoY2Vyb19kYXRlID0gY3JlYXRlZF9hdF90d2VldCwgaWQpICU+JSAKICBmaWx0ZXIoY2Vyb19kYXRlID49IHltZCgiMjAxOS0wMS0wMSIpKQoKbmVkYV9jaGFuZ2UgPC0gbmVkYV9oaXN0ICU+JSAKICBzZWxlY3QoaWRfdHdlZXQsIHRleHQsIGNyZWF0ZWRfYXRfdHdlZXQsIGlkKSAlPiUgCiAgaW5uZXJfam9pbihmaXJzdF90d2VldCkgJT4lIAogIG11dGF0ZShkYXlzX3R3ZWV0ID0gaW50ZXJ2YWwoc3RhcnQgPSBjZXJvX2RhdGUsIGVuZCA9IGNyZWF0ZWRfYXRfdHdlZXQpLAogICAgICAgICBkYXlzX3R3ZWV0ID0gcm91bmQodGltZV9sZW5ndGgoZGF5c190d2VldCwgdW5pdCA9ICJkYXlzIikpKSAlPiUgCiAgc2VsZWN0KC1jZXJvX2RhdGUpICU+JSAKICBmaWx0ZXIoZGF5c190d2VldCA+PSAtMTUsIGRheXNfdHdlZXQgPD0gMTUpCgpuZWRhX3RpbWVsYXBzZSA8LSBuZWRhX2NoYW5nZSAlPiUKICBjb3VudChpZCwgYmVmb3JlX2FmdGVyID0gc2lnbihkYXlzX3R3ZWV0KSwgc29ydCA9IFQpICU+JSAKICBtdXRhdGUoYmVmb3JlX2FmdGVyID0gY2FzZV93aGVuKGJlZm9yZV9hZnRlciA9PSAtMSB+ICJiZWZvcmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlX2FmdGVyID09IDEgfiAiYWZ0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJjZXJvIikpICU+JSAKICBwaXZvdF93aWRlcih2YWx1ZXNfZnJvbSA9IG4sIG5hbWVzX2Zyb20gPSBiZWZvcmVfYWZ0ZXIpICU+JSAKICBmaWx0ZXIoYmVmb3JlID49IDE1ICYgYWZ0ZXIgPj0gMTUpICU+JSAKICBzZWxlY3QoLWNlcm8pICU+JSAKICBzZW1pX2pvaW4oeCA9IG5lZGFfY2hhbmdlLCB5ID0gLikKCm5lZGFfdGltZWxhcHNlICU+JSAKICBpbm5lcl9qb2luKGdlbmRlcl9vdXRwdXQpIC0+IG5lZGFfdGltZWxhcHNlCgpsaWJyYXJ5KHRpZHl0ZXh0KQoKcmVwbGFjZV9yZWcxIDwtICJodHRwczovL3QuY28vW0EtWmEtel1cXGRdK3wiCnJlcGxhY2VfcmVnMiA8LSAiaHR0cHM6Ly90LmNvL1tBLVphLXpdXFxkXSt8JmFtcDt8Jmx0O3wmZ3Q7fFJUfGh0dHBzIgpyZXBsYWNlX3JlZyA8LSBwYXN0ZTAocmVwbGFjZV9yZWcxLCByZXBsYWNlX3JlZzIpCnVubmVzdF9yZWcgPC0gIihbXkEtWmEtel9cXGQjQCddfCcoPyFbQS1aYS16X1xcZCNAXSkpIgoKdGlkeV90d2VldHMgPC0gbmVkYV90aW1lbGFwc2UgJT4lCiAgbXV0YXRlKHRleHQgPSBzdHJfdG9fbG93ZXIodGV4dCkpICU+JSAKICBtdXRhdGUodGV4dCA9IHN0cl9yZXBsYWNlX2FsbCh0ZXh0LCByZXBsYWNlX3JlZywgIiIpKSAlPiUgCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0LCB0b2tlbiA9ICJyZWdleCIsIHBhdHRlcm4gPSB1bm5lc3RfcmVnKQoKdGlkeV90d2VldHMgJT4lIAogIGZpbHRlcih3b3JkICVpbiUgd29yZHNfY2F0KSAlPiUgCiAgbXV0YXRlKGRheXNfdHdlZXQgPSBjYXNlX3doZW4oZGF5c190d2VldCA8IDAgfiAiYmVmb3JlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlzX3R3ZWV0ID4gMCB+ICJhZnRlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJjZXJvIikpICU+JSAKICBmaWx0ZXIoZGF5c190d2VldCAhPSAiY2VybyIpIC0+IHRpZHlfd29yZHMKCm5lZGFfbGl3YyA8LSByZWFkX3JkcyhoZXJlOjpoZXJlKCJkYXRhIiwgIm5lZGFfbGl3Yy5yZHMiKSkgJT4lIAogIHNlbGVjdCgtY3JlYXRlZF9hdF90d2VldCkgJT4lIAogIGZpbHRlcihhYnMoZGF5c190d2VldCkgPD0gMTUpCgpgYGAKCiMjIyBGRU1BTEUgQ0FURUdPUlkKCmBgYHtyfQojIGZlbWFsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBmZW1hbGUgLT4gNDMKCndvcmRzX2RpYyAlPiUgCiAgZmlsdGVyX2F0KHZhcnMoLXhfMSksIGFueV92YXJzKC4gPT0gNDMpKSAlPiUgCiAgcHVsbCh4XzEpIC0+IHdvcmRzX2ZlbWFsZQoKdGlkeV93b3JkcyAlPiUgCiAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19mZW1hbGUpICU+JSAKICBjb3VudChkYXlzX3R3ZWV0LCB3b3JkKSAlPiUgCiAgbXV0YXRlKGdlbmRlciA9ICJ0IikgJT4lIAogIGJpbmRfcm93cyh0aWR5X3dvcmRzICU+JSAKICAgICAgICAgICAgICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX2ZlbWFsZSkgJT4lIAogICAgICAgICAgICAgIGNvdW50KGdlbmRlciwgZGF5c190d2VldCwgd29yZCkpICU+JSAKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gYyhkYXlzX3R3ZWV0LCBnZW5kZXIpLCB2YWx1ZXNfZnJvbSA9IG4pICU+JSAKICBtdXRhdGVfaWYoaXMubnVtZXJpYywgfnJlcGxhY2VfbmEoLiwgMCkpICU+JSAKICBtdXRhdGUoY2hhbmdlc190b3RhbCA9IGFmdGVyX3QgLSBiZWZvcmVfdCwKICAgICAgICAgY2hhbmdlc19mID0gYWZ0ZXJfZiAtIGJlZm9yZV9mLAogICAgICAgICBjaGFuZ2VzX20gPSBhZnRlcl9tIC0gYmVmb3JlX20sCiAgICAgICAgIGNoYW5nZXNfdSA9IGFmdGVyX3UgLSBiZWZvcmVfdSkgJT4lIAogIHNlbGVjdCh3b3JkLCBzdGFydHNfd2l0aCgiY2hhbmdlcyIpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGNoYW5nZXNfdG90YWwpKSAtPiBmIAoKZl90b3AgPC0gZiAlPiUgdG9wX24oNCwgd3QgPSBjaGFuZ2VzX3RvdGFsKQpmX2JvdHRvbSA8LSBmICU+JSB0b3BfbigtNCwgd3QgPSBjaGFuZ2VzX3RvdGFsKQoKZl90b3AgJT4lIAogIGJpbmRfcm93cyhmX2JvdHRvbSkgJT4lIAogIGd0OjpndCgpCmBgYAoKIyMjIEZBTUlMWQoKYGBge3J9CndvcmRzX2RpYyAlPiUgCiAgZmlsdGVyX2F0KHZhcnMoLXhfMSksIGFueV92YXJzKC4gPT0gNDEpKSAlPiUgCiAgcHVsbCh4XzEpIC0+IHdvcmRzX2ZhbWlseQoKdGlkeV93b3JkcyAlPiUgCiAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19mYW1pbHkpICU+JSAKICBjb3VudChkYXlzX3R3ZWV0LCB3b3JkKSAlPiUgCiAgbXV0YXRlKGdlbmRlciA9ICJ0IikgJT4lIAogIGJpbmRfcm93cyh0aWR5X3dvcmRzICU+JSAKICAgICAgICAgICAgICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX2ZhbWlseSkgJT4lIAogICAgICAgICAgICAgIGNvdW50KGdlbmRlciwgZGF5c190d2VldCwgd29yZCkpICU+JSAKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gYyhkYXlzX3R3ZWV0LCBnZW5kZXIpLCB2YWx1ZXNfZnJvbSA9IG4pICU+JSAKICBtdXRhdGVfaWYoaXMubnVtZXJpYywgfnJlcGxhY2VfbmEoLiwgMCkpICU+JSAKICBtdXRhdGUoY2hhbmdlc190b3RhbCA9IGFmdGVyX3QgLSBiZWZvcmVfdCwKICAgICAgICAgY2hhbmdlc19mID0gYWZ0ZXJfZiAtIGJlZm9yZV9mLAogICAgICAgICBjaGFuZ2VzX20gPSBhZnRlcl9tIC0gYmVmb3JlX20sCiAgICAgICAgIGNoYW5nZXNfdSA9IGFmdGVyX3UgLSBiZWZvcmVfdSkgJT4lIAogIHNlbGVjdCh3b3JkLCBzdGFydHNfd2l0aCgiY2hhbmdlcyIpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGNoYW5nZXNfdG90YWwpKSAgLT4gZiAKCmZfdG9wIDwtIGYgJT4lIHRvcF9uKDQsIHd0ID0gY2hhbmdlc190b3RhbCkKZl9ib3R0b20gPC0gZiAlPiUgdG9wX24oLTQsIHd0ID0gY2hhbmdlc190b3RhbCkKCmZfdG9wICU+JSAKICBiaW5kX3Jvd3MoZl9ib3R0b20pICU+JSAKICBndDo6Z3QoKQpgYGAKCiMjIyBBTlhJRVRZCgpgYGB7cn0KIyBhbnhpZXR5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgYW54aWV0eSAtPiAzMwoKd29yZHNfZGljICU+JSAKICBmaWx0ZXJfYXQodmFycygteF8xKSwgYW55X3ZhcnMoLiA9PSAzMykpICU+JSAKICBwdWxsKHhfMSkgLT4gd29yZHNfYW54aWV0eQoKdGlkeV93b3JkcyAlPiUgCiAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19hbnhpZXR5KSAlPiUgCiAgY291bnQoZGF5c190d2VldCwgd29yZCkgJT4lIAogIG11dGF0ZShnZW5kZXIgPSAidCIpICU+JSAKICBiaW5kX3Jvd3ModGlkeV93b3JkcyAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19hbnhpZXR5KSAlPiUgCiAgICAgICAgICAgICAgY291bnQoZ2VuZGVyLCBkYXlzX3R3ZWV0LCB3b3JkKSkgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjKGRheXNfdHdlZXQsIGdlbmRlciksIHZhbHVlc19mcm9tID0gbikgJT4lIAogIG11dGF0ZV9pZihpcy5udW1lcmljLCB+cmVwbGFjZV9uYSguLCAwKSkgJT4lIAogIG11dGF0ZShjaGFuZ2VzX3RvdGFsID0gYWZ0ZXJfdCAtIGJlZm9yZV90LAogICAgICAgICBjaGFuZ2VzX2YgPSBhZnRlcl9mIC0gYmVmb3JlX2YsCiAgICAgICAgIGNoYW5nZXNfbSA9IGFmdGVyX20gLSBiZWZvcmVfbSwKICAgICAgICAgY2hhbmdlc191ID0gYWZ0ZXJfdSAtIGJlZm9yZV91KSAlPiUgCiAgc2VsZWN0KHdvcmQsIHN0YXJ0c193aXRoKCJjaGFuZ2VzIikpICU+JSAKICBhcnJhbmdlKGRlc2MoY2hhbmdlc190b3RhbCkpICAtPiBmIAoKZl90b3AgPC0gZiAlPiUgdG9wX24oNCwgd3QgPSBjaGFuZ2VzX3RvdGFsKQpmX2JvdHRvbSA8LSBmICU+JSB0b3BfbigtNCwgd3QgPSBjaGFuZ2VzX3RvdGFsKQoKZl90b3AgJT4lIAogIGJpbmRfcm93cyhmX2JvdHRvbSkgJT4lIAogIGd0OjpndCgpCmBgYAoKIyMgQ09NTU9OIFdPUkRTIElOIFRXRUVUUyBCWSBXT1JEUyBDQVRFR09SWToKCmBgYHtyfQpuZWRhX2xpd2NfZ2VuZGVyICU+JSAKICBmaWx0ZXIoZGF5c190d2VldCA+PSAwKSAlPiUgCiAgc2VsZWN0KGlkX3R3ZWV0LCBpZCwgZ2VuZGVyLCBmYW1pbHksIGZlbWFsZSwgYW54KSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBmYW1pbHk6YW54KSAlPiUgCiAgZmlsdGVyKHZhbHVlID4gMCkgJT4lIAogIGxlZnRfam9pbihuZWRhX2xpd2MgJT4lIAogICAgICAgICAgICAgIHNlbGVjdChpZCwgaWRfdHdlZXQsIHRleHQpKSAlPiUgIAogIHJlbmFtZSgiY2F0ZWdvcnkiID0gbmFtZSkgJT4lIAogIG11dGF0ZSh0ZXh0ID0gc3RyX3JlbW92ZV9hbGwodGV4dCwgcGF0dGVybiA9ICJbOmdyYXBoOl0rKOKApikiKSkgJT4lIAogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCwgdG9rZW4gPSAidHdlZXRzIikgJT4lIAogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCwKICAgICAgICAgd29yZCAhPSAicnQiLAogICAgICAgICAhd29yZCAlaW4lIHN0cl9yZW1vdmVfYWxsKHN0b3Bfd29yZHMkd29yZCwgIiciKSkgJT4lIAogIG11dGF0ZSh3b3JkID0gY2FzZV93aGVuKGNhdGVnb3J5ID09ICJmZW1hbGUiICYgd29yZCAlaW4lIGMod29yZHNfZmVtYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndvbWVucyIpIH4gTkFfY2hhcmFjdGVyXywKICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeSA9PSAiZmFtaWx5IiAmIHdvcmQgJWluJSBjKHdvcmRzX2ZhbWlseSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYXJlbnRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJicm90aGVycyIpfiBOQV9jaGFyYWN0ZXJfLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5ID09ICJhbngiICYgd29yZCAlaW4lIHdvcmRzX2FueGlldHkgfiBOQV9jaGFyYWN0ZXJfLAogICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiB3b3JkKSkgJT4lIAogIGZpbHRlcighaXMubmEod29yZCksCiAgICAgICAgIHdvcmQgIT0gImFtcCIpICU+JSAKICBjb3VudChjYXRlZ29yeSwgZ2VuZGVyLCB3b3JkLCBzb3J0ID0gVCkgJT4lCiAgZ3JvdXBfYnkoZ2VuZGVyLCBjYXRlZ29yeSkgJT4lIAogIHRvcF9uKDEwLCB3dCA9IG4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKGNhdGVnb3J5LCB3b3JkKSwgbmFtZXNfZnJvbSA9IGdlbmRlciwgdmFsdWVzX2Zyb20gPSBuKSAlPiUgCiAgbXV0YXRlKGNhdGVnb3J5ID0gc3RyX3RvX3RpdGxlKGNhdGVnb3J5KSkgJT4lIAogIGd0OjpndChncm91cG5hbWVfY29sID0gImNhdGVnb3J5IiwKICAgICAgICAgcm93bmFtZV9jb2wgPSAid29yZCIpICAgCiAgCmBgYAoK