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]+|&|<|>|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 |
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