Causal Impact
Number of total users:
neda_liwc %>%
select(id) %>%
distinct() %>%
nrow()
## [1] 431
|
Word Category
|
Relative Eff.(%)
|
P Value
|
|
Female
|
33.031
|
0.001
|
|
Risk
|
20.29
|
0.001
|
|
Relig
|
17.409
|
0.015
|
|
Anx
|
15.936
|
0.046
|
|
We
|
15.857
|
0.004
|
|
Money
|
10.6
|
0.002
|
|
Hear
|
9.708
|
0.002
|
|
Body
|
8.89
|
0.003
|
|
Nonflu
|
7.344
|
0.019
|
|
Power
|
6.675
|
0.001
|
|
Focusfuture
|
6.63
|
0.006
|
|
Relativ
|
6.452
|
0.001
|
|
Tentat
|
4.874
|
0.012
|
|
Focuspresent
|
4.403
|
0.001
|
|
Negemo
|
4.233
|
0.004
|
|
Work
|
3.925
|
0.022
|
|
Social
|
3.632
|
0.001
|
|
Informal
|
3.155
|
0.002
|
|
Focuspast
|
2.694
|
0.040
|
|
Posemo
|
-2.59
|
0.007
|
|
Negate
|
-3.469
|
0.048
|
|
See
|
-15.408
|
0.001
|
|
Ingest
|
-26.529
|
0.025
|
|
Friend
|
-27.165
|
0.001
|
|
Filler
|
-42.13
|
0.001
|
CAUSAL IMPACT BY GENDER
Number of users by gender (400~):
neda_liwc_gender %>%
select(id, gender) %>%
distinct() %>%
count(gender)
## # A tibble: 3 x 2
## gender n
## <chr> <int>
## 1 f 173
## 2 m 65
## 3 u 193
Number of users in the baseline ():
baseline_liwc_gender %>%
select(id, gender) %>%
distinct() %>%
count(gender)
## # A tibble: 3 x 2
## gender n
## <chr> <int>
## 1 f 1699
## 2 m 2066
## 3 u 2978
baseline_liwc_gender %>%
select(-text, -created_at_tweet, -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, -created_at_tweet) %>%
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% categories_in_gender) %>%
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
|
|
Risk
|
27.713
|
7.938
|
10.948
|
0.001
|
0.174
|
0.074
|
|
Female
|
26.164
|
22.59
|
34.262
|
0.001
|
0.005
|
0.001
|
|
Relig
|
25.409
|
-2.293
|
15.585
|
0.014
|
0.393
|
0.102
|
|
We
|
17.588
|
-0.364
|
18.167
|
0.028
|
0.471
|
0.002
|
|
Hear
|
10.457
|
-3.575
|
10.76
|
0.003
|
0.255
|
0.003
|
|
Power
|
9.825
|
0.762
|
5.091
|
0.001
|
0.417
|
0.012
|
|
Anx
|
8.477
|
6.309
|
29.838
|
0.174
|
0.270
|
0.031
|
|
Money
|
8.209
|
31.643
|
-0.583
|
0.029
|
0.001
|
0.464
|
|
Tentat
|
7.838
|
2.283
|
3.036
|
0.011
|
0.262
|
0.141
|
|
Relativ
|
7.719
|
1.424
|
2.714
|
0.001
|
0.256
|
0.070
|
|
Informal
|
6.653
|
4.143
|
0.35
|
0.001
|
0.001
|
0.391
|
|
Work
|
6.207
|
0.102
|
2.455
|
0.016
|
0.477
|
0.190
|
|
Focuspast
|
5.91
|
9.87
|
-4.13
|
0.010
|
0.007
|
0.024
|
|
Social
|
4.541
|
4.411
|
3.713
|
0.001
|
0.002
|
0.003
|
|
Focuspresent
|
3.932
|
10.171
|
3.492
|
0.007
|
0.001
|
0.001
|
|
Focusfuture
|
2.705
|
9.076
|
13.746
|
0.267
|
0.002
|
0.001
|
|
Nonflu
|
2.614
|
15.021
|
8.292
|
0.326
|
0.042
|
0.079
|
|
Negemo
|
1.98
|
13.916
|
2.728
|
0.253
|
0.001
|
0.156
|
|
Body
|
-0.127
|
31.309
|
15.016
|
0.494
|
0.001
|
0.001
|
|
Negate
|
-6.244
|
1.931
|
-0.057
|
0.080
|
0.346
|
0.483
|
|
Posemo
|
-7.802
|
-0.554
|
-0.266
|
0.001
|
0.434
|
0.423
|
|
Ingest
|
-17.991
|
-27.943
|
-12.164
|
0.188
|
0.012
|
0.207
|
|
See
|
-20.432
|
1.343
|
-17.405
|
0.001
|
0.419
|
0.001
|
|
Friend
|
-34.369
|
-16.925
|
-24.181
|
0.001
|
0.092
|
0.008
|
|
Filler
|
-40.55
|
-34.464
|
-52.18
|
0.002
|
0.007
|
0.001
|
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_twenty.rds")) %>%
# distinct() %>%
# filter(created_at_tweet >= ymd("2019-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"))
gender_output <- read_rds(here::here("data", "neda_liwc_gender_twenty.rds")) %>%
select(gender, id_tweet, id)
# 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 = .)
read_rds(here::here("data", "neda_timelapse_twenty.rds")) %>%
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_twenty.rds")) %>%
select(-created_at_tweet) %>%
filter(abs(days_tweet) <= 15)
FEMALE
# 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 |
816 |
323 |
110 |
383 |
| she |
489 |
181 |
67 |
241 |
| her |
431 |
234 |
51 |
146 |
| madam |
233 |
39 |
2 |
192 |
| girly |
-9 |
-4 |
-3 |
-2 |
| witch |
-9 |
-10 |
-2 |
3 |
| gal |
-10 |
-7 |
-2 |
-1 |
| gals |
-14 |
-5 |
0 |
-9 |
| lesbian |
-56 |
-24 |
-6 |
-26 |
RISK
# risk -> 85
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 85)) %>%
pull(x_1) -> words_risk
tidy_words %>%
filter(word %in% words_risk) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_risk) %>%
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 |
| avoid |
92 |
39 |
19 |
34 |
| risk |
89 |
50 |
28 |
11 |
| threat |
51 |
32 |
7 |
12 |
| alarm |
11 |
4 |
2 |
5 |
| dread |
3 |
0 |
2 |
1 |
| doubt |
2 |
2 |
3 |
-3 |
| inhibit |
1 |
1 |
0 |
0 |
| unsure |
-3 |
0 |
-2 |
-1 |
RELIGION
# relig -> 114
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 114)) %>%
pull(x_1) -> words_relig
tidy_words %>%
filter(word %in% words_relig) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_relig) %>%
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 |
| church |
31 |
20 |
9 |
2 |
| goddess |
4 |
2 |
0 |
2 |
| church |
31 |
20 |
9 |
2 |
| goddess |
4 |
2 |
0 |
2 |
MONEY
# money -> 113
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 113)) %>%
pull(x_1) -> words_money
tidy_words %>%
filter(word %in% words_money) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_money) %>%
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 |
| donate |
10 |
6 |
1 |
3 |
| donation |
10 |
0 |
6 |
4 |
| donate |
10 |
6 |
1 |
3 |
| donation |
10 |
0 |
6 |
4 |
BODY
# body -> 71
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 114)) %>%
pull(x_1) -> words_body
tidy_words %>%
filter(word %in% words_body) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_body) %>%
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 |
| church |
31 |
20 |
9 |
2 |
| goddess |
4 |
2 |
0 |
2 |
| church |
31 |
20 |
9 |
2 |
| goddess |
4 |
2 |
0 |
2 |
LS0tCnRpdGxlOiAiQ2F1c2FsIEltcGFjdCIgCmNsZWFuOiB0cnVlCm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogZmFsc2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKCnhmdW46OnBrZ19hdHRhY2goInRpZHl2ZXJzZSIsICJsdWJyaWRhdGUiLCAia2FibGVFeHRyYSIpCgp0aGVtZV9zZXQodGhlbWVfbGluZWRyYXcoKSkKYGBgCgojIyBDYXVzYWwgSW1wYWN0IAoKYGBge3IgZWNobz1GQUxTRX0KYmFzZWxpbmVfbGl3YyA8LSByZWFkX3JkcyhoZXJlOjpoZXJlKCJkYXRhIiwgImJhc2VsaW5lX2xpd2NfdHdlbnR5LnJkcyIpKQoKbmVkYV9saXdjIDwtIHJlYWRfcmRzKGhlcmU6OmhlcmUoImRhdGEiLCAibmVkYV9saXdjX3R3ZW50eS5yZHMiKSkgJT4lIAogIHNlbGVjdCgtdGV4dCwgLWNyZWF0ZWRfYXRfdHdlZXQpICU+JSAKICBmaWx0ZXIoYWJzKGRheXNfdHdlZXQpIDw9IDE1KQoKc2VsX2NhdCA8LSBjKAogICJpIiwid2UiLCJ5b3UiLCJzaGVoZSIsInRoZXkiLCJpcHJvbiIsIm5lZ2F0ZSIsImNvbXBhcmUiLCJwb3NlbW8iLCJuZWdlbW8iLCJhbngiLCJhbmdlciIsInNhZCIsInNvY2lhbCIsImZhbWlseSIsImZyaWVuZCIsImZlbWFsZSIsIm1hbGUiLCJpbnNpZ2h0IiwiY2F1c2UiLCJkaXNjcmVwIiwidGVudGF0IiwiY2VydGFpbiIsImRpZmZlciIsInNlZSIsImhlYXIiLCJmZWVsIiwiYm9keSIsImhlYWx0aCIsInNleHVhbCIsImluZ2VzdCIsImFmZmlsaWF0aW9uIiwiYWNoaWV2IiwicG93ZXIiLCJyZXdhcmQiLCJyaXNrIiwiZm9jdXNwYXN0IiwiZm9jdXNwcmVzZW50IiwiZm9jdXNmdXR1cmUiLCJyZWxhdGl2Iiwid29yayIsImxlaXN1cmUiLCJob21lIiwibW9uZXkiLCJyZWxpZyIsImRlYXRoIiwiaW5mb3JtYWwiLCJzd2VhciIsImFzc2VudCIsIm5vbmZsdSIsImZpbGxlciIKKQpgYGAKCk51bWJlciBvZiB0b3RhbCB1c2VyczoKYGBge3J9Cm5lZGFfbGl3YyAlPiUgCiAgc2VsZWN0KGlkKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgbnJvdygpCmBgYAoKYGBge3IgZWNobz1GQUxTRX0KYmFzZWxpbmVfbGl3YyAlPiUgCiAgc2VsZWN0KC10ZXh0LCAtY3JlYXRlZF9hdF90d2VldCwgLWlkX3R3ZWV0KSAlPiUgCiAgZ3JvdXBfYnkoZGF5c190d2VldCwgaWQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdCgtaWQpICU+JSAKICBncm91cF9ieShkYXlzX3R3ZWV0KSAlPiUgCiAgc3VtbWFyaXNlX2FsbChtZWFuKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGZ1bjpmaWxsZXIsIG5hbWVzX3RvID0gImNhdGVnIiwgdmFsdWVzX3RvID0gInZhbHVlc19iYXNlbGluZSIpIC0+IGNpX2Jhc2VsaW5lCgpuZWRhX2xpd2MgJT4lIAogIHNlbGVjdCgtaWRfdHdlZXQpICU+JSAKICBncm91cF9ieShkYXlzX3R3ZWV0LCBpZCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KC1pZCkgJT4lIAogIGdyb3VwX2J5KGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHBpdm90X2xvbmdlcigtZGF5c190d2VldCwgbmFtZXNfdG8gPSAiY2F0ZWciLCB2YWx1ZXNfdG8gPSAidmFsdWVzX25lZGEiKSAtPiBjaV9uZWRhX2xpd2MgCiAgCnByZV9wZXJpb2QgPC0gYygxLCAxNikKcG9zdF9wZXJpb2QgPC0gYygxNywgMzEpCgpjaV9iYXNlbGluZSAlPiUgCiAgaW5uZXJfam9pbihjaV9uZWRhX2xpd2MpIC0+IGRfc2Vjb25kCgpkX3NlY29uZCAlPiUgCiAgc2VsZWN0KGNhdGVnLCB2YWx1ZXNfbmVkYSwgdmFsdWVzX2Jhc2VsaW5lKSAlPiUgCiAgbmVzdChkYXRhID0gLSBjYXRlZykgJT4lIAogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfkNhdXNhbEltcGFjdDo6Q2F1c2FsSW1wYWN0KC4sIHByZV9wZXJpb2QsIHBvc3RfcGVyaW9kKSkpIC0+IGNpCiAgCmNpICU+JSAKICBtdXRhdGUoc3VtbWFyeV9tb2QgPSBtYXAobW9kLCAic3VtbWFyeSIpKSAlPiUgCiAgZmlsdGVyKCFtYXBfbGdsKHN1bW1hcnlfbW9kLCBpcy5udWxsKSkgLT4gY2lfcmVzdWwgCgpjaV9yZXN1bCAlPiUgCiAgbXV0YXRlKHAgPSBtYXAoc3VtbWFyeV9tb2QsICJwIikpICU+JSAKICBtdXRhdGUocCA9IG1hcF9kYmwocCwgMSkpICU+JSAKICBmaWx0ZXIocCA8IDAuMDUpICU+JSAKICBtdXRhdGUocmVsYXRpdmVfZWZmZWN0ID0gbWFwKHN1bW1hcnlfbW9kLCAiUmVsRWZmZWN0IikpICU+JSAKICBtdXRhdGUocmVsYXRpdmVfZWZmZWN0ID0gbWFwX2RibChyZWxhdGl2ZV9lZmZlY3QsIDIpKS0+IHNpZ19jYXQKCnNpZ19jYXQgJT4lIAogIGZpbHRlcihjYXRlZyAlaW4lIHNlbF9jYXQpIC0+IHNpZ19jYXQKCmNhdGVnb3JpZXNfaW5fZ2VuZGVyIDwtIHNpZ19jYXQgJT4lIHB1bGwoY2F0ZWcpCgpzaWdfY2F0ICU+JSAKICBhcnJhbmdlKGRlc2MocmVsYXRpdmVfZWZmZWN0KSkgJT4lIAogIHNlbGVjdChjYXRlZywgc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCA9IHJlbGF0aXZlX2VmZmVjdCwgcF9zZWNvbmQgPSBwKSAtPiBzZWNvbmRfYXAKCnNlY29uZF9hcCAlPiUgCiAgbXV0YXRlKGNhdGVnID0gc3RyX3RvX3RpdGxlKGNhdGVnKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKHNlY29uZF9yZWxhdGl2ZV9lZmZlY3QpLCB+LioxMDApICU+JSAKICBtdXRhdGVfaWYoaXMubnVtZXJpYywgfnJvdW5kKC4sIGRpZ2l0cyA9IDMpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCksIGZ1bmN0aW9uKHgpewogICAgY2VsbF9zcGVjKHgsICJodG1sIiwgY29sb3IgPSBzcGVjX2NvbG9yKHgpLCBib2xkID0gVCkKICB9KSAlPiUgCiAga2FibGUoImh0bWwiLCBlc2NhcGUgPSBGLAogICAgICAgIGFsaWduID0gImxyciIsCiAgICAgICAgY29sLm5hbWVzID0gYygiV29yZCBDYXRlZ29yeSIsICJSZWxhdGl2ZSBFZmYuKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICJQIFZhbHVlIikpICU+JSAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSwKICAgICAgICAgICAgICAgIGZ1bGxfd2lkdGggPSBGQUxTRSkKYGBgCgojIyBDQVVTQUwgSU1QQUNUIEJZIEdFTkRFUgoKYGBge3IgZWNobz1GQUxTRX0KYmFzZWxpbmVfbGl3Y19nZW5kZXIgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJhc2VsaW5lX2xpd2NfZ2VuZGVyX3R3ZW50eS5yZHMiKSkKCm5lZGFfbGl3Y19nZW5kZXIgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZGFfbGl3Y19nZW5kZXJfdHdlbnR5LnJkcyIpKSAlPiUgCiAgIyBzZWxlY3QoLXRleHQsIC1jcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiAgZmlsdGVyKGFicyhkYXlzX3R3ZWV0KSA8PSAxNSkKCnNlbF9jYXQgPC0gYygKICAiaSIsIndlIiwieW91Iiwic2hlaGUiLCJ0aGV5IiwiaXByb24iLCJuZWdhdGUiLCJjb21wYXJlIiwicG9zZW1vIiwibmVnZW1vIiwiYW54IiwiYW5nZXIiLCJzYWQiLCJzb2NpYWwiLCJmYW1pbHkiLCJmcmllbmQiLCJmZW1hbGUiLCJtYWxlIiwiaW5zaWdodCIsImNhdXNlIiwiZGlzY3JlcCIsInRlbnRhdCIsImNlcnRhaW4iLCJkaWZmZXIiLCJzZWUiLCJoZWFyIiwiZmVlbCIsImJvZHkiLCJoZWFsdGgiLCJzZXh1YWwiLCJpbmdlc3QiLCJhZmZpbGlhdGlvbiIsImFjaGlldiIsInBvd2VyIiwicmV3YXJkIiwicmlzayIsImZvY3VzcGFzdCIsImZvY3VzcHJlc2VudCIsImZvY3VzZnV0dXJlIiwicmVsYXRpdiIsIndvcmsiLCJsZWlzdXJlIiwiaG9tZSIsIm1vbmV5IiwicmVsaWciLCJkZWF0aCIsImluZm9ybWFsIiwic3dlYXIiLCJhc3NlbnQiLCJub25mbHUiLCJmaWxsZXIiCikKYGBgCgpOdW1iZXIgb2YgdXNlcnMgYnkgZ2VuZGVyICg0MDB+KToKYGBge3J9Cm5lZGFfbGl3Y19nZW5kZXIgJT4lIAogIHNlbGVjdChpZCwgZ2VuZGVyKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgY291bnQoZ2VuZGVyKQpgYGAKCk51bWJlciBvZiB1c2VycyBpbiB0aGUgYmFzZWxpbmUgKCk6CmBgYHtyfQpiYXNlbGluZV9saXdjX2dlbmRlciAlPiUgCiAgc2VsZWN0KGlkLCBnZW5kZXIpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBjb3VudChnZW5kZXIpCmBgYAoKYGBge3IgfQpiYXNlbGluZV9saXdjX2dlbmRlciAlPiUgCiAgc2VsZWN0KC10ZXh0LCAtY3JlYXRlZF9hdF90d2VldCwgLWlkX3R3ZWV0LCAtbmFtZSkgJT4lIAogIGdyb3VwX2J5KGdlbmRlciwgaWQsIGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdCgtaWQpICU+JSAKICBncm91cF9ieShnZW5kZXIsIGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gZnVuOmZpbGxlciwgbmFtZXNfdG8gPSAiY2F0ZWciLCB2YWx1ZXNfdG8gPSAidmFsdWVzX2Jhc2VsaW5lIikgLT4gY2lfYmFzZWxpbmUKCm5lZGFfbGl3Y19nZW5kZXIgJT4lIAogIHNlbGVjdCgtaWRfdHdlZXQsIC1jcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiAgZ3JvdXBfYnkoZ2VuZGVyLCBpZCwgZGF5c190d2VldCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KC1pZCkgJT4lIAogIGdyb3VwX2J5KGdlbmRlciwgZGF5c190d2VldCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGZ1bjpmaWxsZXIsIG5hbWVzX3RvID0gImNhdGVnIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZXNfbmVkYSIpIC0+IGNpX25lZGFfbGl3YyAKCnByZV9wZXJpb2QgPC0gYygxLCAxNikKcG9zdF9wZXJpb2QgPC0gYygxNywgMzEpCgpjaV9iYXNlbGluZSAlPiUgCiAgZnVsbF9qb2luKGNpX25lZGFfbGl3YykgLT4gZF9zZWNvbmQKCmRfc2Vjb25kICU+JSAKICAjIGNvdW50KGdlbmRlciwgZGF5c190d2VldCkgJT4lIAogICMgdmlldygpCiAgIyB2aWV3KCkKICAjIHNlbGVjdChjYXRlZywgdmFsdWVzX25lZGEsIHZhbHVlc19iYXNlbGluZSkgJT4lIAogICMgbmVzdChkYXRhID0gLSBjYXRlZykgJT4lIAogIHNlbGVjdChnZW5kZXIsIGNhdGVnLCB2YWx1ZXNfbmVkYSwgdmFsdWVzX2Jhc2VsaW5lKSAlPiUKICAjIGZpbHRlcihnZW5kZXIgPT0gIm0iKSAlPiUgdmlldygpCiAgZ3JvdXBfYnkoY2F0ZWcsIGdlbmRlcikgJT4lIAogIG5lc3QoKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoZ2VuZGVyLCBjYXRlZywgZGF0YSkgJT4lIAogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfkNhdXNhbEltcGFjdDo6Q2F1c2FsSW1wYWN0KC4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZV9wZXJpb2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zdF9wZXJpb2QpKSkgLT4gY2kKICAKY2kgJT4lIAogIG11dGF0ZShzdW1tYXJ5X21vZCA9IG1hcChtb2QsICJzdW1tYXJ5IikpICU+JSAKICBmaWx0ZXIoIW1hcF9sZ2woc3VtbWFyeV9tb2QsIGlzLm51bGwpKSAtPiBjaV9yZXN1bCAKCmNpX3Jlc3VsICU+JSAKICBtdXRhdGUocCA9IG1hcChzdW1tYXJ5X21vZCwgInAiKSkgJT4lIAogIG11dGF0ZShwID0gbWFwX2RibChwLCAxKSkgJT4lIAogIGZpbHRlcihjYXRlZyAlaW4lIGNhdGVnb3JpZXNfaW5fZ2VuZGVyKSAlPiUgCiAgbXV0YXRlKHJlbGF0aXZlX2VmZmVjdCA9IG1hcChzdW1tYXJ5X21vZCwgIlJlbEVmZmVjdCIpKSAlPiUgCiAgbXV0YXRlKHJlbGF0aXZlX2VmZmVjdCA9IG1hcF9kYmwocmVsYXRpdmVfZWZmZWN0LCAyKSktPiBzaWdfY2F0CgojIHNpZ19jYXQgJT4lIAojICAgZmlsdGVyKGNhdGVnICVpbiUgc2VsX2NhdCkgLT4gc2lnX2NhdAoKc2lnX2NhdCAlPiUgCiAgYXJyYW5nZShnZW5kZXIsIGRlc2MocmVsYXRpdmVfZWZmZWN0KSkgJT4lIAogIHNlbGVjdChnZW5kZXIsIGNhdGVnLCAKICAgICAgICAgc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCA9IHJlbGF0aXZlX2VmZmVjdCwgcF9zZWNvbmQgPSBwKSAtPiBzZWNvbmRfYXAKCnNlY29uZF9hcCAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGNhdGVnLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGMoc2Vjb25kX3JlbGF0aXZlX2VmZmVjdCwgcF9zZWNvbmQpLAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBnZW5kZXIpICU+JSAKICBtdXRhdGUoY2F0ZWcgPSBzdHJfdG9fdGl0bGUoY2F0ZWcpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoInNlY29uZCIpKSwgfi4qMTAwKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yb3VuZCguLCBkaWdpdHMgPSAzKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKHN0YXJ0c193aXRoKCJzZWNvbmQiKSksIGZ1bmN0aW9uKHgpewogICAgY2VsbF9zcGVjKHgsICJodG1sIiwgY29sb3IgPSBzcGVjX2NvbG9yKHgpLCBib2xkID0gVCkKICB9KSAlPiUgCiAga2FibGUoImh0bWwiLCBlc2NhcGUgPSBGLAogICAgICAgIGFsaWduID0gImxyciIsCiAgICAgICAgY29sLm5hbWVzID0gYygiV29yZCBDYXRlZ29yeSIsICJGRU1BTEUgUmVsYXRpdmUgRWZmLiglKSIsCiAgICAgICAgICAgICAgICAgICAgICAiTUFMRSBSZWxhdGl2ZSBFZmYuKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICJVTktOT1dOIFJlbGF0aXZlIEVmZi4oJSkiLAogICAgICAgICAgICAgICAgICAgICAgIkZFTUFMRSBQIFZhbHVlIiwKICAgICAgICAgICAgICAgICAgICAgICJNQUxFIFAgVmFsdWUiLAogICAgICAgICAgICAgICAgICAgICAgIlVOS05PV04gUCBWYWx1ZSIpKSAlPiUgIAogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLAogICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAKCiMjIFdvcmRzIGluc2lkZSBjYXRlZzoKClRoZSB0YWJsZXMgYmVsb3cgY29udGFpbiB0aGUgY2hhbmdlcyBmb3IgdGhlIDQgbW9zdCBjaGFuZ2VkIHdvcmRzIChwb3NpdGl2ZSBhbmQgbmVnYXRpdmUpIHdpdGhpbiBlYWNoIG9mIHRoZSBjYXRlZ29yaWVzLiBUaGUgZmlyc3QgY29sdW1uIGlzIHRoZSBzcGVjaWZpYyB3b3JkLiBDaGFuZ2VzX3RvdGFsIGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlICJiZWZvcmUiIGFuZCAiYWZ0ZXIiIGZyZXF1ZW5jeSBvZiBhbGwgdXNlcnMuIENoYW5nZXNfZiBzYW1lIGFzIENoYW5nZXNfdG90YWwgYnV0IGZvciBmZW1hbGUgdXNlcnMsIENoYW5nZXNfbSBmb3IgbWFsZSB1c2VycyBhbmQgQ2hhbmdlc191IGZvciB1bmtub3duIHVzZXJzLgoKYGBge3IgfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKCnJlYWRfZGVsaW0oaGVyZTo6aGVyZSgiZGF0YSIsICJsaXdjIiwgIkxJV0MyMDE1X0VuZ2xpc2hfRmxhdC5kaWMiKSwKICAgICAgICAgICBkZWxpbSA9ICJcdCIsIHNraXAgPSAxLCBjb2xfbmFtZXMgPSBjKCJudW1iZXIiLCAibmFtZSIpLCAKICAgICAgICAgICBuX21heCA9IDczKSAtPiBjYXRlZ29yaWVzX25hbWUgCgpyZWFkX3RzdihoZXJlOjpoZXJlKCJkYXRhIiwgImxpd2MiLCAiTElXQzIwMTVfRW5nbGlzaF9GbGF0LmRpYyIpLAogICAgICAgICBza2lwID0gNzUsIGNvbF9uYW1lcyA9IHBhc3RlMChjKCJ4IiksIGMoIl8iKSwgMToxMSksCiAgICAgICAgIGd1ZXNzX21heCA9IDYwMDAsIGNvbF90eXBlcyA9ICJjY2NjY2NjY2NjYyIpICU+JSAKICBtdXRhdGUoeF8xID0gc3RyX3JlbW92ZSh4XzEsICJcXCoiKSkgLT4gd29yZHNfZGljCgpjYXRlZ29yaWVzX25hbWUgJT4lIAogIGZpbHRlcihuYW1lICVpbiUgYygiZmVtYWxlIiwgImZhbWlseSIsICJhbngiLCAic2hlaGUiLCAiYWZmaWxpYXRpb24iLCAiZnJpZW5kIikpICU+JSAKICBwdWxsKG51bWJlcikgLT4gbnVtYmVyX3RvcF9jYXRlZwoKd29yZHNfZGljICU+JSAKICBmaWx0ZXJfYXQodmFycygteF8xKSwgYW55X3ZhcnMoLiAlaW4lIG51bWJlcl90b3BfY2F0ZWcpKSAlPiUgIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19jYXQKCgojIG5lZGFfdGltZWxhcHNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmxpYnJhcnkobHVicmlkYXRlKQoKIyBuZWRhX2hpc3QgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsICJORURBX2hpc3RvcmljYWxfdHdlbnR5LnJkcyIpKSAlPiUgCiMgICBkaXN0aW5jdCgpICU+JSAKIyAgIGZpbHRlcihjcmVhdGVkX2F0X3R3ZWV0ID49IHltZCgiMjAxOS0wMy0wMSIpKSAlPiUgCiMgICBtdXRhdGUodGV4dCA9IHN0cl90b19sb3dlcih0ZXh0KSwKIyAgICAgICAgICBuZWRhX3JlbGF0ZWQgPSBzdHJfZGV0ZWN0KHRleHQsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9ICIjbmVkYXdhcmVuZXNzfCNjb21lYXN5b3VhcmV8QG5lZGFzdGFmZiIpKSAKCiMgZ2VuZGVyX291dHB1dCA8LSByZWFkX3RzdihoZXJlOjpoZXJlKCJkYXRhIiwgImdlbmRlcl9leHRyYWN0b3IiLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZGFfbGl3Y19nZW5kZXJfb3V0cHV0LnRzdiIpLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gYygiaWQiLCAibmFtZSIsICJuYW1lX3Byb2MiLCAiZ2VuZGVyIikpCgpnZW5kZXJfb3V0cHV0IDwtIHJlYWRfcmRzKGhlcmU6OmhlcmUoImRhdGEiLCAibmVkYV9saXdjX2dlbmRlcl90d2VudHkucmRzIikpICU+JSAKICBzZWxlY3QoZ2VuZGVyLCBpZF90d2VldCwgaWQpCiMgZmlyc3RfdHdlZXQgPC0gbmVkYV9oaXN0ICU+JSAKIyAgIHNlbGVjdChjcmVhdGVkX2F0X3R3ZWV0LCB0ZXh0LCBpZCwgaWRfdHdlZXQsIG5lZGFfcmVsYXRlZCkgJT4lIAojICAgZmlsdGVyKG5lZGFfcmVsYXRlZCkgJT4lIAojICAgYXJyYW5nZShjcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiMgICBncm91cF9ieShpZCkgJT4lIAojICAgc2xpY2UoMSkgJT4lIAojICAgdW5ncm91cCgpICU+JSAKIyAgIHNlbGVjdChjZXJvX2RhdGUgPSBjcmVhdGVkX2F0X3R3ZWV0LCBpZCkgJT4lIAojICAgZmlsdGVyKGNlcm9fZGF0ZSA+PSB5bWQoIjIwMTktMDEtMDEiKSkKIyAKIyBuZWRhX2NoYW5nZSA8LSBuZWRhX2hpc3QgJT4lIAojICAgc2VsZWN0KGlkX3R3ZWV0LCB0ZXh0LCBjcmVhdGVkX2F0X3R3ZWV0LCBpZCkgJT4lIAojICAgaW5uZXJfam9pbihmaXJzdF90d2VldCkgJT4lIAojICAgbXV0YXRlKGRheXNfdHdlZXQgPSBpbnRlcnZhbChzdGFydCA9IGNlcm9fZGF0ZSwgZW5kID0gY3JlYXRlZF9hdF90d2VldCksCiMgICAgICAgICAgZGF5c190d2VldCA9IHJvdW5kKHRpbWVfbGVuZ3RoKGRheXNfdHdlZXQsIHVuaXQgPSAiZGF5cyIpKSkgJT4lIAojICAgc2VsZWN0KC1jZXJvX2RhdGUpICU+JSAKIyAgIGZpbHRlcihkYXlzX3R3ZWV0ID49IC0xNSwgZGF5c190d2VldCA8PSAxNSkKIyAKIyBuZWRhX3RpbWVsYXBzZSA8LSBuZWRhX2NoYW5nZSAlPiUKIyAgIGNvdW50KGlkLCBiZWZvcmVfYWZ0ZXIgPSBzaWduKGRheXNfdHdlZXQpLCBzb3J0ID0gVCkgJT4lIAojICAgbXV0YXRlKGJlZm9yZV9hZnRlciA9IGNhc2Vfd2hlbihiZWZvcmVfYWZ0ZXIgPT0gLTEgfiAiYmVmb3JlIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlX2FmdGVyID09IDEgfiAiYWZ0ZXIiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gImNlcm8iKSkgJT4lIAojICAgcGl2b3Rfd2lkZXIodmFsdWVzX2Zyb20gPSBuLCBuYW1lc19mcm9tID0gYmVmb3JlX2FmdGVyKSAlPiUgCiMgICBmaWx0ZXIoYmVmb3JlID49IDE1ICYgYWZ0ZXIgPj0gMTUpICU+JSAKIyAgIHNlbGVjdCgtY2VybykgJT4lIAojICAgc2VtaV9qb2luKHggPSBuZWRhX2NoYW5nZSwgeSA9IC4pCgoKCnJlYWRfcmRzKGhlcmU6OmhlcmUoImRhdGEiLCAibmVkYV90aW1lbGFwc2VfdHdlbnR5LnJkcyIpKSAlPiUgCiAgaW5uZXJfam9pbihnZW5kZXJfb3V0cHV0KSAtPiBuZWRhX3RpbWVsYXBzZQoKbGlicmFyeSh0aWR5dGV4dCkKCnJlcGxhY2VfcmVnMSA8LSAiaHR0cHM6Ly90LmNvL1tBLVphLXpdXFxkXSt8IgpyZXBsYWNlX3JlZzIgPC0gImh0dHBzOi8vdC5jby9bQS1aYS16XVxcZF0rfCZhbXA7fCZsdDt8Jmd0O3xSVHxodHRwcyIKcmVwbGFjZV9yZWcgPC0gcGFzdGUwKHJlcGxhY2VfcmVnMSwgcmVwbGFjZV9yZWcyKQp1bm5lc3RfcmVnIDwtICIoW15BLVphLXpfXFxkI0AnXXwnKD8hW0EtWmEtel9cXGQjQF0pKSIKCnRpZHlfdHdlZXRzIDwtIG5lZGFfdGltZWxhcHNlICU+JQogIG11dGF0ZSh0ZXh0ID0gc3RyX3RvX2xvd2VyKHRleHQpKSAlPiUgCiAgbXV0YXRlKHRleHQgPSBzdHJfcmVwbGFjZV9hbGwodGV4dCwgcmVwbGFjZV9yZWcsICIiKSkgJT4lIAogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCwgdG9rZW4gPSAicmVnZXgiLCBwYXR0ZXJuID0gdW5uZXN0X3JlZykKCnRpZHlfdHdlZXRzICU+JSAKICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX2NhdCkgJT4lIAogIG11dGF0ZShkYXlzX3R3ZWV0ID0gY2FzZV93aGVuKGRheXNfdHdlZXQgPCAwIH4gImJlZm9yZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5c190d2VldCA+IDAgfiAiYWZ0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiY2VybyIpKSAlPiUgCiAgZmlsdGVyKGRheXNfdHdlZXQgIT0gImNlcm8iKSAtPiB0aWR5X3dvcmRzCgpuZWRhX2xpd2MgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsICJuZWRhX2xpd2NfdHdlbnR5LnJkcyIpKSAlPiUgCiAgc2VsZWN0KC1jcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiAgZmlsdGVyKGFicyhkYXlzX3R3ZWV0KSA8PSAxNSkKCmBgYAoKIyMjIEZFTUFMRSAKCmBgYHtyIH0KIyBmZW1hbGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZmVtYWxlIC0+IDQzCgp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguID09IDQzKSkgJT4lIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19mZW1hbGUKCnRpZHlfd29yZHMgJT4lIAogIGZpbHRlcih3b3JkICVpbiUgd29yZHNfZmVtYWxlKSAlPiUgCiAgY291bnQoZGF5c190d2VldCwgd29yZCkgJT4lIAogIG11dGF0ZShnZW5kZXIgPSAidCIpICU+JSAKICBiaW5kX3Jvd3ModGlkeV93b3JkcyAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19mZW1hbGUpICU+JSAKICAgICAgICAgICAgICBjb3VudChnZW5kZXIsIGRheXNfdHdlZXQsIHdvcmQpKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoZGF5c190d2VldCwgZ2VuZGVyKSwgdmFsdWVzX2Zyb20gPSBuKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yZXBsYWNlX25hKC4sIDApKSAlPiUgCiAgbXV0YXRlKGNoYW5nZXNfdG90YWwgPSBhZnRlcl90IC0gYmVmb3JlX3QsCiAgICAgICAgIGNoYW5nZXNfZiA9IGFmdGVyX2YgLSBiZWZvcmVfZiwKICAgICAgICAgY2hhbmdlc19tID0gYWZ0ZXJfbSAtIGJlZm9yZV9tLAogICAgICAgICBjaGFuZ2VzX3UgPSBhZnRlcl91IC0gYmVmb3JlX3UpICU+JSAKICBzZWxlY3Qod29yZCwgc3RhcnRzX3dpdGgoImNoYW5nZXMiKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhjaGFuZ2VzX3RvdGFsKSkgLT4gZiAKCmZfdG9wIDwtIGYgJT4lIHRvcF9uKDQsIHd0ID0gY2hhbmdlc190b3RhbCkKZl9ib3R0b20gPC0gZiAlPiUgdG9wX24oLTQsIHd0ID0gY2hhbmdlc190b3RhbCkKCmZfdG9wICU+JSAKICBiaW5kX3Jvd3MoZl9ib3R0b20pICU+JSAKICBndDo6Z3QoKQpgYGAKCiMjIyBSSVNLCgpgYGB7cn0KIyByaXNrIC0+IDg1Cgp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguID09IDg1KSkgJT4lIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19yaXNrCgp0aWR5X3dvcmRzICU+JSAKICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX3Jpc2spICU+JSAKICBjb3VudChkYXlzX3R3ZWV0LCB3b3JkKSAlPiUgCiAgbXV0YXRlKGdlbmRlciA9ICJ0IikgJT4lIAogIGJpbmRfcm93cyh0aWR5X3dvcmRzICU+JSAKICAgICAgICAgICAgICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX3Jpc2spICU+JSAKICAgICAgICAgICAgICBjb3VudChnZW5kZXIsIGRheXNfdHdlZXQsIHdvcmQpKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoZGF5c190d2VldCwgZ2VuZGVyKSwgdmFsdWVzX2Zyb20gPSBuKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yZXBsYWNlX25hKC4sIDApKSAlPiUgCiAgbXV0YXRlKGNoYW5nZXNfdG90YWwgPSBhZnRlcl90IC0gYmVmb3JlX3QsCiAgICAgICAgIGNoYW5nZXNfZiA9IGFmdGVyX2YgLSBiZWZvcmVfZiwKICAgICAgICAgY2hhbmdlc19tID0gYWZ0ZXJfbSAtIGJlZm9yZV9tLAogICAgICAgICBjaGFuZ2VzX3UgPSBhZnRlcl91IC0gYmVmb3JlX3UpICU+JSAKICBzZWxlY3Qod29yZCwgc3RhcnRzX3dpdGgoImNoYW5nZXMiKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhjaGFuZ2VzX3RvdGFsKSkgLT4gZiAKCmZfdG9wIDwtIGYgJT4lIHRvcF9uKDQsIHd0ID0gY2hhbmdlc190b3RhbCkKZl9ib3R0b20gPC0gZiAlPiUgdG9wX24oLTQsIHd0ID0gY2hhbmdlc190b3RhbCkKCmZfdG9wICU+JSAKICBiaW5kX3Jvd3MoZl9ib3R0b20pICU+JSAKICBndDo6Z3QoKQpgYGAKCiMjIyBSRUxJR0lPTgpgYGB7cn0KIyByZWxpZyAtPiAxMTQKCndvcmRzX2RpYyAlPiUgCiAgZmlsdGVyX2F0KHZhcnMoLXhfMSksIGFueV92YXJzKC4gPT0gMTE0KSkgJT4lIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19yZWxpZwoKdGlkeV93b3JkcyAlPiUgCiAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19yZWxpZykgJT4lIAogIGNvdW50KGRheXNfdHdlZXQsIHdvcmQpICU+JSAKICBtdXRhdGUoZ2VuZGVyID0gInQiKSAlPiUgCiAgYmluZF9yb3dzKHRpZHlfd29yZHMgJT4lIAogICAgICAgICAgICAgIGZpbHRlcih3b3JkICVpbiUgd29yZHNfcmVsaWcpICU+JSAKICAgICAgICAgICAgICBjb3VudChnZW5kZXIsIGRheXNfdHdlZXQsIHdvcmQpKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoZGF5c190d2VldCwgZ2VuZGVyKSwgdmFsdWVzX2Zyb20gPSBuKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yZXBsYWNlX25hKC4sIDApKSAlPiUgCiAgbXV0YXRlKGNoYW5nZXNfdG90YWwgPSBhZnRlcl90IC0gYmVmb3JlX3QsCiAgICAgICAgIGNoYW5nZXNfZiA9IGFmdGVyX2YgLSBiZWZvcmVfZiwKICAgICAgICAgY2hhbmdlc19tID0gYWZ0ZXJfbSAtIGJlZm9yZV9tLAogICAgICAgICBjaGFuZ2VzX3UgPSBhZnRlcl91IC0gYmVmb3JlX3UpICU+JSAKICBzZWxlY3Qod29yZCwgc3RhcnRzX3dpdGgoImNoYW5nZXMiKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhjaGFuZ2VzX3RvdGFsKSkgLT4gZiAKCmZfdG9wIDwtIGYgJT4lIHRvcF9uKDQsIHd0ID0gY2hhbmdlc190b3RhbCkKZl9ib3R0b20gPC0gZiAlPiUgdG9wX24oLTQsIHd0ID0gY2hhbmdlc190b3RhbCkKCmZfdG9wICU+JSAKICBiaW5kX3Jvd3MoZl9ib3R0b20pICU+JSAKICBndDo6Z3QoKQoKYGBgCgojIyBNT05FWQoKYGBge3J9CiMgbW9uZXkgLT4gMTEzCgp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguID09IDExMykpICU+JSAKICBwdWxsKHhfMSkgLT4gd29yZHNfbW9uZXkKCnRpZHlfd29yZHMgJT4lIAogIGZpbHRlcih3b3JkICVpbiUgd29yZHNfbW9uZXkpICU+JSAKICBjb3VudChkYXlzX3R3ZWV0LCB3b3JkKSAlPiUgCiAgbXV0YXRlKGdlbmRlciA9ICJ0IikgJT4lIAogIGJpbmRfcm93cyh0aWR5X3dvcmRzICU+JSAKICAgICAgICAgICAgICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX21vbmV5KSAlPiUgCiAgICAgICAgICAgICAgY291bnQoZ2VuZGVyLCBkYXlzX3R3ZWV0LCB3b3JkKSkgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjKGRheXNfdHdlZXQsIGdlbmRlciksIHZhbHVlc19mcm9tID0gbikgJT4lIAogIG11dGF0ZV9pZihpcy5udW1lcmljLCB+cmVwbGFjZV9uYSguLCAwKSkgJT4lIAogIG11dGF0ZShjaGFuZ2VzX3RvdGFsID0gYWZ0ZXJfdCAtIGJlZm9yZV90LAogICAgICAgICBjaGFuZ2VzX2YgPSBhZnRlcl9mIC0gYmVmb3JlX2YsCiAgICAgICAgIGNoYW5nZXNfbSA9IGFmdGVyX20gLSBiZWZvcmVfbSwKICAgICAgICAgY2hhbmdlc191ID0gYWZ0ZXJfdSAtIGJlZm9yZV91KSAlPiUgCiAgc2VsZWN0KHdvcmQsIHN0YXJ0c193aXRoKCJjaGFuZ2VzIikpICU+JSAKICBhcnJhbmdlKGRlc2MoY2hhbmdlc190b3RhbCkpIC0+IGYgCgpmX3RvcCA8LSBmICU+JSB0b3Bfbig0LCB3dCA9IGNoYW5nZXNfdG90YWwpCmZfYm90dG9tIDwtIGYgJT4lIHRvcF9uKC00LCB3dCA9IGNoYW5nZXNfdG90YWwpCgpmX3RvcCAlPiUgCiAgYmluZF9yb3dzKGZfYm90dG9tKSAlPiUgCiAgZ3Q6Omd0KCkKCmBgYAoKIyMgQk9EWQpgYGB7cn0KIyBib2R5IC0+IDcxCgp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguID09IDExNCkpICU+JSAKICBwdWxsKHhfMSkgLT4gd29yZHNfYm9keQoKdGlkeV93b3JkcyAlPiUgCiAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19ib2R5KSAlPiUgCiAgY291bnQoZGF5c190d2VldCwgd29yZCkgJT4lIAogIG11dGF0ZShnZW5kZXIgPSAidCIpICU+JSAKICBiaW5kX3Jvd3ModGlkeV93b3JkcyAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19ib2R5KSAlPiUgCiAgICAgICAgICAgICAgY291bnQoZ2VuZGVyLCBkYXlzX3R3ZWV0LCB3b3JkKSkgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjKGRheXNfdHdlZXQsIGdlbmRlciksIHZhbHVlc19mcm9tID0gbikgJT4lIAogIG11dGF0ZV9pZihpcy5udW1lcmljLCB+cmVwbGFjZV9uYSguLCAwKSkgJT4lIAogIG11dGF0ZShjaGFuZ2VzX3RvdGFsID0gYWZ0ZXJfdCAtIGJlZm9yZV90LAogICAgICAgICBjaGFuZ2VzX2YgPSBhZnRlcl9mIC0gYmVmb3JlX2YsCiAgICAgICAgIGNoYW5nZXNfbSA9IGFmdGVyX20gLSBiZWZvcmVfbSwKICAgICAgICAgY2hhbmdlc191ID0gYWZ0ZXJfdSAtIGJlZm9yZV91KSAlPiUgCiAgc2VsZWN0KHdvcmQsIHN0YXJ0c193aXRoKCJjaGFuZ2VzIikpICU+JSAKICBhcnJhbmdlKGRlc2MoY2hhbmdlc190b3RhbCkpIC0+IGYgCgpmX3RvcCA8LSBmICU+JSB0b3Bfbig0LCB3dCA9IGNoYW5nZXNfdG90YWwpCmZfYm90dG9tIDwtIGYgJT4lIHRvcF9uKC00LCB3dCA9IGNoYW5nZXNfdG90YWwpCgpmX3RvcCAlPiUgCiAgYmluZF9yb3dzKGZfYm90dG9tKSAlPiUgCiAgZ3Q6Omd0KCkKCmBgYAoKCiMjIENPTU1PTiBXT1JEUyBJTiBUV0VFVFMgQlkgV09SRFMgQ0FURUdPUlk6CgpgYGB7ciB9Cm5lZGFfbGl3Y19nZW5kZXIgJT4lIAogIGZpbHRlcihkYXlzX3R3ZWV0ID49IDApICU+JSAKICBzZWxlY3QoaWRfdHdlZXQsIGlkLCBnZW5kZXIsIGZlbWFsZSwgcmlzaywgcmVsaWcsIGJvZHksIG1vbmV5KSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBmZW1hbGU6bW9uZXkpICU+JSAKICBmaWx0ZXIodmFsdWUgPiAwKSAlPiUgCiAgbGVmdF9qb2luKG5lZGFfbGl3YyAlPiUgCiAgICAgICAgICAgICAgc2VsZWN0KGlkLCBpZF90d2VldCwgdGV4dCkpICU+JSAgCiAgcmVuYW1lKCJjYXRlZ29yeSIgPSBuYW1lKSAlPiUgCiAgbXV0YXRlKHRleHQgPSBzdHJfcmVtb3ZlX2FsbCh0ZXh0LCBwYXR0ZXJuID0gIls6Z3JhcGg6XSso4oCmKSIpKSAlPiUgCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0LCB0b2tlbiA9ICJ0d2VldHMiKSAlPiUgIAogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCwKICAgICAgICAgIXdvcmQgJWluJSBjKCJkZSIsIDQsICJkYSIsICJsYSIsICJlbiIsICJsZSIsICJsb3MiLCAzKSwKICAgICAgICAgd29yZCAhPSAicnQiLAogICAgICAgICAhd29yZCAlaW4lIHN0cl9yZW1vdmVfYWxsKHN0b3Bfd29yZHMkd29yZCwgIiciKSkgJT4lIAogICMgbXV0YXRlKHdvcmQgPSBjYXNlX3doZW4oY2F0ZWdvcnkgPT0gImZlbWFsZSIgJiB3b3JkICVpbiUgYyh3b3Jkc19mZW1hbGUsCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3b21lbnMiKSB+IE5BX2NoYXJhY3Rlcl8sCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeSA9PSAiZmFtaWx5IiAmIHdvcmQgJWluJSBjKHdvcmRzX2ZhbWlseSwKICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhcmVudHMiLAogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYnJvdGhlcnMiKX4gTkFfY2hhcmFjdGVyXywKICAjICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5ID09ICJhbngiICYgd29yZCAlaW4lIHdvcmRzX2FueGlldHkgfiBOQV9jaGFyYWN0ZXJfLAogICMgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IHdvcmQpKSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh3b3JkKSwKICAgICAgICAgd29yZCAhPSAiYW1wIikgJT4lIAogIGNvdW50KGNhdGVnb3J5LCBnZW5kZXIsIHdvcmQsIHNvcnQgPSBUKSAlPiUKICBncm91cF9ieShnZW5kZXIsIGNhdGVnb3J5KSAlPiUgCiAgdG9wX24oMTAsIHd0ID0gbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoY2F0ZWdvcnksIHdvcmQpLCBuYW1lc19mcm9tID0gZ2VuZGVyLCB2YWx1ZXNfZnJvbSA9IG4pICU+JSAKICBtdXRhdGUoY2F0ZWdvcnkgPSBzdHJfdG9fdGl0bGUoY2F0ZWdvcnkpKSAlPiUgCiAgZ3Q6Omd0KGdyb3VwbmFtZV9jb2wgPSAiY2F0ZWdvcnkiLAogICAgICAgICByb3duYW1lX2NvbCA9ICJ3b3JkIikgICAKICAKYGBgCgo=