General Setup

Analysis table creation. Don’t run if already created. Instead skip to “Analysis table loads”

dbExecute(con,"DROP TABLE IF EXISTS articles_cdp")
articles_cdp <- articles %>% filter(case_when(
  media == "HS" ~ section %in% c("Kotimaa", "Politiikka", "Talous"),
  media == "IL" ~ subsection %in% c("kotimaa","politiikka","talous","uutiset"),
  media == "STT" ~ section %in% c("Kotimaa","Politiikka","Talous"),
  media == "YLE" ~ section == "Yle Uutiset" & str_detect(subject,"Kotimaan uutiset|politiikka|talous") & (!str_detect(subject,"Ulkomaat") | str_detect(subject,"Kotimaan uutiset")),
  T ~ F
)) %>% 
  distinct(a_id) %>% 
  compute(name="articles_cdp",temporary=F,unique_indexes=c("a_id"))
dbExecute(con,"DROP TABLE IF EXISTS articles_opinionated")
articles_opinionated <- articles %>% mutate(opinionated=case_when(
  media == "HS" ~ case_when(
    str_to_lower(section) == "pääkirjoitus" & str_detect(str_to_lower(story_logo),"ieras") ~ "external editorial",
    str_to_lower(section) == "pääkirjoitus" & is.na(story_logo) ~ "editorial",
    str_to_lower(section) == "pääkirjoitus" & str_to_lower(story_logo) == "pääkirjoitus" ~ "editorial",
    str_to_lower(section) == "mielipide" | str_to_lower(story_logo) == "mielipide" ~ "external opinion",
    str_detect(str_to_lower(title),"analyysi:") | str_detect(str_to_lower(story_logo),"analyysi")  ~ "analysis",
    str_detect(str_to_lower(title),"näkökulma:") | str_detect(str_to_lower(story_logo),"näkökulma") ~ "perspective",
    str_detect(str_to_lower(title),"kolumni:") | str_detect(str_to_lower(story_logo),"kolumni") ~ "column",
    str_detect(str_to_lower(title),"blogi:") | str_detect(str_to_lower(story_logo),"blog") ~ "blog"    
  ),
  media == "IL" ~ case_when(
    subsection == "paakirjoitus" ~ "editorial",
    str_detect(str_to_lower(title),"kommentti:") ~ "commentary",
    str_detect(str_to_lower(title),"analyysi:") ~ "analysis",
    str_detect(str_to_lower(title),"kolumni:") ~ "column",
    str_detect(str_to_lower(title),"näkökulma:") ~ "perspective"
  ),
  media == "YLE" ~ case_when(
    str_detect(str_to_lower(title),"kommentti:") ~ "commentary",
    str_detect(str_to_lower(title),"analyysi:") | str_detect(subject,"Analyysit \\(Yle Uutiset\\)") ~ "analysis",
    str_detect(str_to_lower(title),"kolumni:") | str_detect(str_to_lower(subject),"kolumn") ~ "column",
    str_detect(str_to_lower(title),"näkökulma:")  | str_detect(str_to_lower(subject),"näkökulm") ~ "perspective",
    str_detect(str_to_lower(title),"blogi:")  | str_detect(str_to_lower(subject),"blog") ~ "blog"
  )
)) %>%
  filter(!is.na(opinionated)) %>%
  distinct(a_id, opinionated) %>%
  compute(name="articles_opinionated",temporary=F,unique_indexes=c("a_id"))
labels <- read_tsv(here("data/person_labels.tsv")) %>%
  filter(!category %in% c('adjektiivi', 'ei'))

lemmas_of_interest <- labels %>%
  rename("lemma" = "name") %>%
  copy_to(con,.,name="labels",overwrite=T) %>%
  union_all(words %>%
    filter(str_detect(lemma, "yhden#ve")) %>% 
      distinct(lemma) %>% 
      mutate(category="yhdenvertaisuus")) %>%
  union_all(words %>%
      filter(str_detect(lemma, "tasa#arv")) %>% 
      distinct(lemma) %>% 
      mutate(category="tasa-arvo")) %>%
  distinct()
dbExecute(con,"DROP TABLE IF EXISTS words_of_interest")
words_of_interest <- words %>% 
  inner_join(lemmas_of_interest) %>% 
  distinct(w_id,lemma,category,genus) %>% 
  compute(name="words_of_interest",temporary=F,indexes=c("w_id","category","genus"))
dbExecute(con,"DROP TABLE IF EXISTS corpus_of_interest")
corpus_of_interest <- corpus %>%
  inner_join(words_of_interest) %>%
  compute(name="corpus_of_interest",temporary=F,indexes=list(c("a_id","par_id","s_id","pos"),c("w_id"),c("genus"),c("category"))
dbExecute(con,"DROP TABLE IF EXISTS article_types")
article_types <- articles %>% 
  left_join(articles_cdp %>% mutate(cdp=T)) %>%
  left_join(articles_opinionated) %>%
  mutate(type=case_when(
    media == "STT" & version != "Loppuversio" ~ "Other",
    !is.na(opinionated) & !str_detect(opinionated,"^external ") ~ "Journalistic opinion",
    !is.na(opinionated) ~ "External opinion",
    cdp ~ "Domestic general/political/economic news",
    media == "HS" & section == "Kulttuuri" ~ "Culture/entertainment",
    media == "IL" & section == "viihde" ~ "Culture/entertainment",
    media == "STT" & section == "Kulttuuri" ~ "Culture/entertainment",
    media == "YLE" & section == "Yle Uutiset" & str_detect(subject,"kulttuuri|musiikki|viihde") & !str_detect(subject, "Ulkomaat") ~ "Culture/entertainment",
    media == "HS" & section == "Kaupunki" ~ "Local news",
    media == "YLE" & section == "Yle Uutiset" & coverage=="local" ~ "Local news",
    media == "STT" & section == "Urheilu" ~ "Sports",
    media == "HS" & section == "Urheilu" ~ "Sports",
    media == "YLE" & section == "YLE Urheilu" ~ "Sports",
    media == "IL" & section == "urheilu" ~ "Sports",
    media == "STT" & section == "Ulkomaat" ~ "Foreign news",
    media == "HS" & section == "Ulkomaat" ~ "Foreign news",
    media == "YLE" & section == "Yle Uutiset" & str_detect(subject,"Ulkomaat") & !str_detect(subject,"Kotimaan uutiset") ~ "Foreign news",
    media == "IL" & subsection == "ulkomaat" ~ "Foreign news",
    T ~ "Other"
  )) %>%
  distinct(a_id,type) %>%
  compute(temporary=F,name="article_types",unique_indexes=list(c("a_id"),c("a_id","type"),c("type","a_id")))
dbExecute(con,"DROP TABLE IF EXISTS articles_by_type_by_year")
articles_by_type_by_year <- articles %>% 
  inner_join(article_types) %>%
  mutate(year_created=year(date_created)) %>%
  count(media,year_created,type,name="total_articles") %>%
  compute(unique_indexes=list(c("media","year_created","type")),temporary=F,name="articles_by_type_by_year")
dbExecute(con,"DROP TABLE IF EXISTS articles_to_ref_categories")
articles_to_ref_categories <- words_of_interest %>%
    filter(category %in% c("tasa-arvo","yhdenvertaisuus")) %>%
    inner_join(corpus) %>%
    group_by(a_id) %>%
    summarize(yv=max(category=="yhdenvertaisuus"),ta=max(category=="tasa-arvo"),.groups="drop") %>%
    mutate(ref_category=case_when(yv==1 & ta==1 ~ "both",yv==1 ~ "yhdenvertaisuus", ta==1 ~ "tasa-arvo")) %>% 
  select(a_id,ref_category) %>% 
  compute()
articles_to_ref_categories <- articles_to_ref_categories %>% union_all(
    articles_to_ref_categories %>%
    filter(ref_category=="both") %>% 
    mutate(ref_category="yhdenvertaisuus")
  ) %>%
  union_all(
    articles_to_ref_categories %>%
    filter(ref_category=="both") %>% 
    mutate(ref_category="tasa-arvo")
  ) %>%
  compute(temporary=F,name="articles_to_ref_categories",indexes=c("a_id"),unique_indexes=list(c("a_id","ref_category"),c("ref_category","a_id")))
yv_ta_corpus <- words_of_interest %>%
  filter(category %in% c("tasa-arvo","yhdenvertaisuus")) %>%
  inner_join(corpus) 

dbExecute(con,"DROP TABLE IF EXISTS yv_ta_paragraphs")
yv_ta_paragraphs <- yv_ta_corpus %>%
  distinct(a_id,par_id) %>%
  compute(temporary=F,name="yv_ta_paragraphs", unique_indexes=list(c("a_id","par_id")))

Analysis table loads

articles_cdp <- tbl(con,"articles_cdp")
articles_opinionated <- tbl(con,"articles_opinionated")
article_types <- tbl(con,"article_types")
articles_by_type_by_year <- tbl(con,"articles_by_type_by_year")
words_of_interest <- tbl(con,"words_of_interest")
corpus_of_interest <- tbl(con,"corpus_of_interest")
articles_to_ref_categories <- tbl(con,"articles_to_ref_categories")
yv_ta_paragraphs <- tbl(con,"yv_ta_paragraphs")

Named query definitions

quotation_corpus <- quotes %>% 
  inner_join(corpus,sql_on="LHS.a_id=RHS.a_id AND (s_id > start_s_id OR (s_id=start_s_id AND pos >= start_pos)) AND (s_id < end_s_id OR (s_id=end_s_id AND pos <= end_pos))") %>%
  select(a_id=a_id.x,par_id,s_id,pos, q_id)

quotation_sentence_corpus <- quotes %>% 
  inner_join(corpus,sql_on="LHS.a_id=RHS.a_id AND s_id >= start_s_id AND s_id <= end_s_id") %>%
  select(a_id=a_id.x,par_id,s_id,pos, q_id)

yv_corpus <- corpus_of_interest %>% 
  filter(category=="yhdenvertaisuus")

yv_paragraphs <- yv_corpus %>% 
  distinct(a_id,par_id)

ta_corpus <- corpus_of_interest %>% 
  filter(category=="tasa-arvo")

ta_paragraphs <- ta_corpus %>% 
  distinct(a_id,par_id)

quote_orgs <- read_tsv(here("data/q_id_to_orgs.tsv")) %>%
  select(c(author_head, a_id, org_cat))
New names:
• `` -> `...1`
Rows: 19362 Columns: 5
── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (2): org_cat, author_head
dbl (3): ...1, q_id, a_id

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
d <- corpus_of_interest %>%
  inner_join(articles %>% select(a_id,date_created,media)) %>%
  inner_join(article_types) %>%
  left_join(articles_to_ref_categories) %>%
  left_join(quotation_corpus %>% mutate(in_quote=T)) %>%
  left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
  left_join(quote_orgs, copy = TRUE, auto_index = TRUE) %>%
  mutate(in_quote_head=in_quote_sentence & !in_quote) %>%
  mutate(year_created=year(date_created)) %>%
  mutate(week_created=week(date_created)) %>%
  mutate(type2=case_when(
    str_detect(type,"opinion$") ~ type,
    in_quote_sentence ~ str_c("Quotes in ",type),
    TRUE ~ str_c("Journalistic text in ",type)
  ))
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
Joining, by = c("a_id", "par_id", "s_id", "pos", "q_id")
Joining, by = "a_id"
  
d2 <- corpus_of_interest %>%
  inner_join(yv_ta_paragraphs) %>%
  inner_join(articles %>% select(a_id,date_created,media)) %>%
  inner_join(article_types) %>%
  inner_join(articles_to_ref_categories) %>%
  left_join(quotation_corpus %>% mutate(in_quote=T)) %>%
  left_join(quote_orgs, copy = TRUE, auto_index = TRUE) %>%
  left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
  mutate(in_quote_head=in_quote_sentence & !in_quote) %>%
  mutate(year_created=year(date_created)) %>%
  mutate(week_created=week(date_created)) %>%
  mutate(type2=case_when(
    str_detect(type,"opinion$") ~ type,
    in_quote_sentence ~ str_c("Quotes in ",type),
    TRUE ~ str_c("Journalistic text in ",type)
  ))
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos", "q_id")
key_cats <- c('potilas', 'maahanmuutto', 'etnos', 'seksuaalisuus', 'työsuhde')
main_types <- c('core', 'opinionated', 'external opinion')

Analysis 1: development of yhdenvertaisuus/tasa-arvo in different text genres

Master chart

my_d <- d %>% 
  filter(category %in% c("yhdenvertaisuus","tasa-arvo")) %>%
  mutate(year_created=year(date_created),week_created=week(date_created)) %>%
  group_by(media,category,type,type2,year_created) %>%
  summarize(articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
  inner_join(articles_by_type_by_year,by=c("media","type","year_created")) %>%
  collect()

my_d2 <- d %>% 
  filter(category %in% c("yhdenvertaisuus","tasa-arvo")) %>%
  mutate(year_created=year(date_created),week_created=week(date_created)) %>%
  group_by(a_id,media,type,type2,year_created) %>%
  filter(any(category=="yhdenvertaisuus"),any(category=="tasa-arvo")) %>%
  group_by(media,type,type2,year_created) %>%
  summarize(articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
  inner_join(articles_by_type_by_year,by=c("media","type","year_created")) %>%
  collect()
Warning: Missing values are always removed in SQL aggregation functions.
Use `na.rm = TRUE` to silence this warning
This warning is displayed once every 8 hours.
my_d <- my_d %>% 
  mutate(word="Word") %>%
  union_all(my_d2 %>% 
              mutate(category="tasa-arvo") %>%
              mutate(word="Both")) %>%
  union_all(my_d2 %>% 
              mutate(category="yhdenvertaisuus") %>%
              mutate(word="Both")) %>%
  mutate(
    word=fct_relevel(word,"Word"),
    category=fct_relevel(category,"tasa-arvo","yhdenvertaisuus"),
    type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))  
my_d %>%
  filter(type=="Other") %>%
  ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
  geom_step() +
  geom_vline(xintercept = 2009,color="red") + 
  theme_hsci_discrete(base_family="Arial") +
  scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
  scale_x_continuous(breaks=seq(2000,2020,by=4)) +
  facet_grid(category~type2,scales="free") +
  labs(color="Media",linetype="Signal") +
  xlab("Year") +
  ylab("Percentage of articles of type containing the word")
1:3 %>% map(~
  my_d %>%
    filter(type!="Other") %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
    geom_step() +
    geom_vline(xintercept = 2009,color="red") + 
    theme_hsci_discrete(base_family="Arial") +
    scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_grid_paginate(category~type2,scales="free", nrow=2, ncol=4, page=.x) +
    labs(color="Media",linetype="Signal") +
    xlab("Year") +
    ylab("Percentage of articles of type containing the word")
)
[[1]]

[[2]]

[[3]]

Conclusions:

  • IL is behind other media in change, but same trajectory
  • For foreign news, STT (and therefore IL) do not increase tasa-arvo terminology usage
  • For local news, terminology usage increases only for HS (Helsinki) as opposed to YLE (regional news)
  • For culture/entertainment, other sources differ from IL. This is probably due to category heterogeneity: for IL, this category contains entertainment news, for others, these are more culture reviews etc.

Does change in media composition affect results?

1:3 %>% map(~
  my_d %>%
    filter(type!="Other") %>%
    mutate(
      l_total_articles=if_else(media %in% c("HS","STT"),total_articles,0L),
      l_articles=if_else(media %in% c("HS","STT"),articles,0L)
      ) %>%
    group_by(year_created,category,type2,word) %>%
    summarize(`HS/STT`=sum(l_articles)/sum(l_total_articles),`All medias`=sum(articles)/sum(total_articles),.groups="drop") %>%
    pivot_longer(`HS/STT`:`All medias`) %>%
    ggplot(aes(x=year_created,y=value,color=name,linetype=word)) +
    geom_step() +
    geom_vline(xintercept = 2009,color="red") + 
    theme_hsci_discrete(base_family="Arial") +
    scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_grid_paginate(category~type2,scales="free",nrow=2,ncol=4,page=.x) +
    labs(color="Media") +
    xlab("Year") +
    ylab("Percentage of articles of type containing the word")
)
[[1]]

[[2]]

[[3]]

Conclusions:

  • If we mention the IL/STT behavior from above in text, we can then drop the medias from graphs as they do not otherwise affect results for main categories of interest.

Final graph to include in article

d %>% 
  filter(category %in% c("yhdenvertaisuus","tasa-arvo")) %>% 
  filter(type %in% c("Domestic general/political/economic news", "Journalistic opinion", "External opinion")) %>%
  left_join(articles_by_type_by_year %>% group_by(type,year_created) %>%
               summarize(total_articles=sum(total_articles),.groups="drop"),by=c("type","year_created")) %>%
  group_by(category,type2,year_created) %>%
  summarize(total_articles=min(total_articles),articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
  collect() %>%
  mutate(type2=fct_relevel(type2,"External opinion","Journalistic opinion")) %>%
  mutate(category=fct_relevel(category,"yhdenvertaisuus")) %>%
  ggplot(aes(x=year_created,y=articles/total_articles,color=type2)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
  scale_x_continuous(breaks=seq(2000,2020,by=5)) +
  facet_wrap(~category, scales="free_y") +
  labs(color="Text type") +
  xlab("Year") +
  ylab("Percentage of articles of type containing the word") +
  theme(legend.justification = c(0, 1), legend.position = c(0.02, 0.98), legend.background = element_blank(), legend.box.just = "bottom", legend.key = element_blank(), legend.box = "horizontal")

Analysis 2: distribution of language by speaker and subject category


d %>%
  filter(org_cat %in% c("politiikka", "oikeus"), category %in% c("yhdenvertaisuus", "tasa-arvo"), in_quote == T) %>%
  group_by(org_cat,year_created, category) %>%
  summarize(n=n(),.groups="drop") %>%
  ggplot(aes(x=year_created,y=n,color=category)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  facet_grid(~org_cat, scales="free")


d %>%
  filter(org_cat %in% c("politiikka", "oikeus"), category %in% key_cats, in_quote == T) %>%
  group_by(org_cat,year_created, category) %>%
  summarize(n=n(),.groups="drop") %>%
  ggplot(aes(x=year_created,y=n,color=category)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  facet_grid(~org_cat, scales="free")

Analysis 3: subject associations

sp <- yv_ta_paragraphs %>%
  inner_join(
    words %>% 
      filter(lemma=="suku#puoli") %>%
      inner_join(corpus)
    ) %>% inner_join(articles %>% select(a_id,date_created,media)) %>%
  inner_join(article_types) %>%
  inner_join(articles_to_ref_categories) %>%
  left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
  mutate(year_created=year(date_created)) %>%
  mutate(week_created=week(date_created)) %>%
  mutate(type2=case_when(
    str_detect(type,"opinion$") ~ type,
    in_quote_sentence ~ str_c("Quotes in ",type),
    TRUE ~ str_c("Journalistic text in ",type)
  )) %>%
  group_by(media,ref_category,type,type2,year_created) %>%
  summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>% 
  collect() %>%
  mutate(
    ref_category=fct_relevel(ref_category,"tasa-arvo","yhdenvertaisuus"),
    type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))
Joining, by = "w_id"
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
  
my_cd <- corpus_of_interest %>%
  filter(lemma!="suomalainen") %>%
  inner_join(yv_ta_paragraphs) %>%
  inner_join(articles %>% select(a_id,date_created,media)) %>%
  inner_join(article_types) %>%
  inner_join(articles_to_ref_categories) %>%
  mutate(year_created=year(date_created)) %>%
  mutate(week_created=week(date_created)) %>%
  left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
  mutate(type2=case_when(
    str_detect(type,"opinion$") ~ type,
    in_quote_sentence ~ str_c("Quotes in ",type),
    TRUE ~ str_c("Journalistic text in ",type)
  ))
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
cd2 <- my_cd %>%
  group_by(ref_category,genus,type,type2,year_created) %>%
  summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>% 
  collect() %>%
  mutate(
    ref_category=fct_relevel(ref_category,"tasa-arvo","yhdenvertaisuus"),
    type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))

cd <- my_cd %>%
  group_by(ref_category,category,type,type2,year_created) %>%
  summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>% 
  collect() %>%
  mutate(
    ref_category=fct_relevel(ref_category,"tasa-arvo","yhdenvertaisuus"),
    type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))

Gender

my_d <- sp %>%
  filter(type!="Other") %>%
  inner_join(articles_by_type_by_year %>% 
               group_by(year_created,type) %>%
               summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>% 
  collect()
Joining, by = c("type", "year_created")
1:3 %>% map(~
  my_d %>% 
    filter(ref_category!="both") %>%
    mutate(fct=ref_category,word="Word") %>%
    union_all(
      my_d %>%
        filter(ref_category=="both") %>%
        mutate(fct="tasa-arvo",word="Both")
    ) %>%
    union_all(
      my_d %>%
        filter(ref_category=="both") %>%
        mutate(fct="yhdenvertaisuus",word="Both")
    ) %>%
    mutate(word=fct_relevel(word,"Word")) %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
    geom_step() +
    geom_vline(xintercept = 2009,color="red") + 
    theme_hsci_discrete(base_family="Arial") +
    scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_grid_paginate(fct~type2,scales="free",ncol=4,nrow=2,page=.x) +
    labs(color="Media",linetype="Signal") +
    xlab("Year") +
    ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

1:3 %>% map(~  
  my_d %>% 
    filter(ref_category!="both") %>%
    mutate(fct=ref_category,word="Word") %>%
    union_all(
      my_d %>%
        filter(ref_category=="both") %>%
        mutate(fct="tasa-arvo",word="Both")
    ) %>%
    union_all(
      my_d %>%
        filter(ref_category=="both") %>%
        mutate(fct="yhdenvertaisuus",word="Both")
    ) %>%
    mutate(word=fct_relevel(word,"Word")) %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
    geom_step() +
    geom_vline(xintercept = 2009,color="red") + 
    theme_hsci_discrete(base_family="Arial") +
    scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_wrap_paginate(fct~type2,scales="free",ncol=4,nrow=2,page=.x) +
    labs(color="Media",linetype="Signal") +
    xlab("Year") +
    ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

Conclusions:

  • Decline in “sukupuolten tasa-arvo” in STT for domestic news is interesting. What could cause this?
  • Otherwise, all sources seem to be following similar patterns.
sp %>% 
  filter(type=="Domestic general/political/economic news") %>%
  group_by(ref_category,type,type2,year_created) %>%
  summarize(articles=sum(articles),.groups="drop") %>%
  inner_join(articles_by_type_by_year %>% 
               group_by(year_created,type) %>%
               summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
  ggplot(aes(x=year_created,y=articles/total_articles,color=ref_category,linetype=type2)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  scale_x_continuous(breaks=seq(2000,2020,by=2))
Joining, by = c("type", "year_created")

Conclusions:

  • Gender equality discussion also gets a boost after 2014
  • When “yhdenvertaisuus” is used in relation to gender, “tasa-arvo” is almost always also mentioned!
my_d <- cd2 %>%
  filter(type!="Other") %>%
  inner_join(articles_by_type_by_year %>% 
               group_by(year_created,type) %>%
               summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>% 
  collect()
Joining, by = c("type", "year_created")
1:3 %>% map(~
  my_d %>% 
    ggplot(aes(x=year_created,y=articles/total_articles,color=ref_category)) +
    geom_step() +
    geom_vline(xintercept = 2009,color="red") + 
    theme_hsci_discrete(base_family="Arial") +
    scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_grid_paginate(genus~type2,scales="free",ncol=4,nrow=2,page=.x) +
    labs(color="ref-category",linetype="Signal") +
    xlab("Year") +
    ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

1:3 %>% map(~  
  my_d %>% 
    ggplot(aes(x=year_created,y=articles/total_articles,color=ref_category)) +
    geom_step() +
    geom_vline(xintercept = 2009,color="red") + 
    theme_hsci_discrete(base_family="Arial") +
    scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_wrap_paginate(genus~type2,scales="free",ncol=4,nrow=2,page=.x) +
    labs(color="ref-category",linetype="Signal") +
    xlab("Year") +
    ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

Conclusions:

  • Same behavior seen for “sukupuolten tasa-arvo/yhdenvertaisuus” is also evident when looking at explicitly gendered words (mies/nainen)

Subject topic

1:3 %>% map(~
  cd %>% 
    filter(type!="Other") %>%
    filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
    inner_join(articles_by_type_by_year %>% 
                 group_by(year_created,type) %>%
                 summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
    geom_step() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_grid_paginate(ref_category~type2,scales="free",nrow=2,ncol=4,page=.x)
)
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

1:3 %>% map(~ 
  cd %>% 
    filter(type!="Other") %>%
    filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
    inner_join(articles_by_type_by_year %>% 
                 group_by(year_created,type) %>%
                 summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
    geom_step() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=4)) +
    facet_wrap_paginate(ref_category~type2,scales="free",nrow=2,ncol=4,page=.x)
)
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

Conclusions:

  • There don’t seem to be major discernible patterns between different subjects for equality

Supporting auxiliary analyses

Subject topic graphs using different measures

cd %>% 
  filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
  group_by(ref_category) %>%
  group_map(~.x %>%
    ggplot(aes(x=year_created,y=days,color=category)) +
    geom_line() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=2)) +
    facet_wrap(~type2,scales="free") +
    ggtitle(.y[1]$ref_category))
[[1]]

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]

cd %>% 
  filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
  group_by(ref_category) %>%
  group_map(~.x %>%
    ggplot(aes(x=year_created,y=weeks,color=category)) +
    geom_line() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=2)) +
    facet_wrap(~type2,scales="free") +
    ggtitle(.y[1]$ref_category))
[[1]]

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]

cd %>% 
  filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
  inner_join(articles_by_type_by_year %>% 
               group_by(year_created,type) %>%
               summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
  group_by(ref_category) %>%
  group_map(~.x %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
    geom_line() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=2)) +
    facet_wrap(~type2,scales="free") +
    ggtitle(.y[1]$ref_category))
Joining, by = c("type", "year_created")
[[1]]

[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

[[3]]

Do the subject topics combined capture the phenomenon?

cd3 <- yv_ta_paragraphs %>%
  inner_join(corpus_of_interest) %>%
  filter(lemma!="suomalainen") %>%
  inner_join(articles %>% select(a_id,date_created,media)) %>%
  inner_join(article_types) %>%
  inner_join(articles_to_ref_categories) %>%
  mutate(year_created=year(date_created)) %>%
  mutate(week_created=week(date_created)) %>%
  mutate(category="potilas") %>%
  group_by(ref_category,category,type,year_created) %>%
  summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>% 
  collect()
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
cd3 %>% 
  filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
  mutate(type=fct_relevel(type,"foreign","sports","other",after=Inf)) %>%
  group_by(ref_category) %>%
  group_map(~.x %>%
    ggplot(aes(x=year_created,y=days,color=category)) +
    geom_line() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=2)) +
    facet_wrap(~type,scales="free") +
    ggtitle(.y[1]$ref_category))
Warning: Problem while computing `type = fct_relevel(type, "foreign", "sports", "other", after = Inf)`.
ℹ Unknown levels in `f`: foreign, sports, other
[[1]]

[[2]]

[[3]]

cd3 %>% 
  filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
  mutate(type=fct_relevel(type,"foreign","sports","other",after=Inf)) %>%
  group_by(ref_category) %>%
  group_map(~.x %>%
    ggplot(aes(x=year_created,y=weeks,color=category)) +
    geom_line() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=2)) +
    facet_wrap(~type,scales="free") +
    ggtitle(.y[1]$ref_category))
Warning: Problem while computing `type = fct_relevel(type, "foreign", "sports", "other", after = Inf)`.
ℹ Unknown levels in `f`: foreign, sports, other
[[1]]

[[2]]

[[3]]

cd3 %>% 
  filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
  inner_join(articles_by_type_by_year %>% 
               group_by(year_created,type) %>%
               summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
  mutate(type=fct_relevel(type,"foreign","sports","other",after=Inf)) %>%
  group_by(ref_category) %>%
  group_map(~.x %>%
    ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
    geom_line() +
    theme_hsci_discrete(base_family="Arial") +
    scale_x_continuous(breaks=seq(2000,2020,by=2)) +
    facet_wrap(~type,scales="free") +
    ggtitle(.y[1]$ref_category))
Joining, by = c("type", "year_created")
Warning: Problem while computing `type = fct_relevel(type, "foreign", "sports", "other", after = Inf)`.
ℹ Unknown levels in `f`: foreign, sports, other
[[1]]

[[2]]

[[3]]

Conclusions:

  • While we saw no discernible patterns between subjects, we do seem to be capturing the “whole” of equality discussion by targeting them -> can conclude that everyone benefits.

Background Analyses

articles %>% 
  inner_join(articles_to_ref_categories) %>%
  inner_join(article_types) %>%
  mutate(year_created=year(date_created),week_created=week(date_created)) %>%
  group_by(media,ref_category,type,year_created) %>%
  summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
  ggplot(aes(x=year_created,y=days,color=media)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  scale_x_continuous(breaks=seq(2000,2020,by=2)) +
  facet_grid(ref_category~type,scales="free")
Joining, by = "a_id"
Joining, by = "a_id"

articles %>% 
  inner_join(articles_to_ref_categories) %>%
  inner_join(article_types) %>%
  mutate(year_created=year(date_created),week_created=week(date_created)) %>%
  group_by(media,ref_category,type,year_created) %>%
  summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
  ggplot(aes(x=year_created,y=weeks,color=media)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  scale_x_continuous(breaks=seq(2000,2020,by=2)) +
  facet_grid(ref_category~type,scales="free")
Joining, by = "a_id"
Joining, by = "a_id"

articles %>% 
  inner_join(articles_to_ref_categories) %>%
  inner_join(article_types) %>%
  mutate(year_created=year(date_created),week_created=week(date_created)) %>%
  group_by(media,ref_category,type,year_created) %>%
  summarize(articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
  inner_join(articles_by_type_by_year) %>%
  ggplot(aes(x=year_created,y=articles/total_articles,color=media)) +
  geom_step() +
  theme_hsci_discrete(base_family="Arial") +
  scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
  scale_x_continuous(breaks=seq(2000,2020,by=2)) +
  facet_grid(ref_category~type,scales="free")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("media", "type", "year_created")

Auxiliary background analyses

articles %>%
  mutate(year_created=year(date_created),month_created=month(date_created)) %>%
  count(media,year_created,month_created) %>%
  ggplot(aes(x=as.Date(str_c(year_created,'-',month_created,'-01')),y=n,color=media)) +
  geom_step() +
  theme_hsci_discrete()

articles %>% 
  inner_join(article_types) %>%
  mutate(year_created=year(date_created)) %>%
  count(media,year_created,type) %>%
  ggplot(aes(x=year_created,y=n,color=type)) +
  geom_step() +
  facet_wrap(~media,scales="free") +
  theme_hsci_discrete()
Joining, by = "a_id"

articles %>% 
  inner_join(article_types) %>%
  mutate(year_created=year(date_created)) %>%
  mutate(from_stt=author=="STT") %>%
  filter(media=="IL") %>%
  count(media,year_created,type,from_stt) %>%
  collect() %>%
  group_by(media) %>%
  mutate(type=fct_lump_n(type,11,w=n)) %>%
  count(media,year_created,type,from_stt,wt=n) %>%
  ggplot(aes(x=year_created,y=n,color=from_stt==1)) +
  geom_step() +
  facet_wrap(type~media,scales="free") +
  theme_hsci_discrete()
Joining, by = "a_id"

LS0tCnRpdGxlOiAiRkxPUE8gWVYvVEEgYW5hbHlzaXMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwotLS0KCiMgR2VuZXJhbCBTZXR1cAoKYGBge3Igc2V0dXAsaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBoZXJlOjpoZXJlKCkpCmxpYnJhcnkoaGVyZSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoREJJKQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGhtcykKbGlicmFyeShnZ2JlZXN3YXJtKQpsaWJyYXJ5KGdnZm9yY2UpCmxpYnJhcnkocGFrKQpwa2dfaW5zdGFsbCgiaHNjaS1yL2dnaHNjaSIpCmxpYnJhcnkoZ2doc2NpKQpsaWJyYXJ5KFJNYXJpYURCKQoKY29uIDwtIERCSTo6ZGJDb25uZWN0KAogIFJNYXJpYURCOjpNYXJpYURCKCksIAogIGhvc3QgPSAiMTI4LjIxNC4yNTMuMjExIiwgCiAgZGJuYW1lID0gImZsb3BvIiwgCiAgdXNlciA9ICJyb290IiwgCiAgcGFzc3dvcmQgPSAiZGhoMTciLAogIGJpZ2ludCA9ICJpbnRlZ2VyIiwKICBsb2FkX2RhdGFfbG9jYWxfaW5maWxlID0gVFJVRSwKICBhdXRvY29tbWl0ID0gVFJVRSwKICByZWNvbm5lY3QgPSBUUlVFKQpkYkV4ZWN1dGUoY29uLCAiU0VUIFNFU1NJT04gc3RvcmFnZV9lbmdpbmU9YXJpYSIpCgp0YmwoY29uLCAiYV9zaW0iKQphY3Rvcl9tZW50aW9ucyA8LSB0YmwoY29uLCAiYWN0b3JfbWVudGlvbnMiKQphY3Rvcl9vcmcgPC0gdGJsKGNvbiwgImFjdG9yX29yZyIpCmFjdG9yX3JvbGVzIDwtIHRibChjb24sICJhY3Rvcl9yb2xlcyIpCmFjdG9ycyA8LSB0YmwoY29uLCAiYWN0b3JzIikKYXJ0aWNsZXMgPC0gdGJsKGNvbiwgImFydGljbGVzIikKY29ycHVzIDwtIHRibChjb24sICJjb3JwdXMiKQptaXNjIDwtIHRibChjb24sICJtaXNjIikKcV9xYSA8LSB0YmwoY29uLCAicV9xYSIpCnF1b3RlX2F1dGhvcnMgPC0gdGJsKGNvbiwgInF1b3RlX2F1dGhvcnMiKQpxdW90ZXMgPC0gdGJsKGNvbiwgInF1b3RlcyIpCndvcmRzIDwtIHRibChjb24sICJ3b3JkcyIpCnF1b3RlX2F1dGhvcl9uYW1lc190b19jYW5vbmljYWxfbmFtZXMgPC0gdGJsKGNvbiwgInF1b3RlX2F1dGhvcl9uYW1lc190b19jYW5vbmljYWxfbmFtZXMiKQphY3Rvcl9uYW1lc190b19jYW5vbmljYWxfbmFtZXMgPC0gdGJsKGNvbiwgImFjdG9yX25hbWVzX3RvX2Nhbm9uaWNhbF9uYW1lcyIpCmFjdG9yX3JvbGVzX3RvX2Nhbm9uaWNhbF9yb2xlcyA8LSB0YmwoY29uLCAiYWN0b3Jfcm9sZXNfdG9fY2Fub25pY2FsX3JvbGVzIikKYWN0b3Jfb3Jnc190b19jYW5vbmljYWxfb3JncyA8LSB0YmwoY29uLCAiYWN0b3Jfb3Jnc190b19jYW5vbmljYWxfb3JncyIpCmFfY2FuX25hbWVzX3RvX2Nhbl9vcmdzX3JvbGVzX2J5X3RfY3JlYXRlZCA8LSB0YmwoY29uLCAiYV9jYW5fbmFtZXNfdG9fY2FuX29yZ3Nfcm9sZXNfYnlfdF9jcmVhdGVkIikKYGBgCgojIEFuYWx5c2lzIHRhYmxlIGNyZWF0aW9uLiBEb24ndCBydW4gaWYgYWxyZWFkeSBjcmVhdGVkLiBJbnN0ZWFkIHNraXAgdG8gIkFuYWx5c2lzIHRhYmxlIGxvYWRzIgoKYGBge3IsZXZhbD1GQUxTRX0KZGJFeGVjdXRlKGNvbiwiRFJPUCBUQUJMRSBJRiBFWElTVFMgYXJ0aWNsZXNfY2RwIikKYXJ0aWNsZXNfY2RwIDwtIGFydGljbGVzICU+JSBmaWx0ZXIoY2FzZV93aGVuKAogIG1lZGlhID09ICJIUyIgfiBzZWN0aW9uICVpbiUgYygiS290aW1hYSIsICJQb2xpdGlpa2thIiwgIlRhbG91cyIpLAogIG1lZGlhID09ICJJTCIgfiBzdWJzZWN0aW9uICVpbiUgYygia290aW1hYSIsInBvbGl0aWlra2EiLCJ0YWxvdXMiLCJ1dXRpc2V0IiksCiAgbWVkaWEgPT0gIlNUVCIgfiBzZWN0aW9uICVpbiUgYygiS290aW1hYSIsIlBvbGl0aWlra2EiLCJUYWxvdXMiKSwKICBtZWRpYSA9PSAiWUxFIiB+IHNlY3Rpb24gPT0gIllsZSBVdXRpc2V0IiAmIHN0cl9kZXRlY3Qoc3ViamVjdCwiS290aW1hYW4gdXV0aXNldHxwb2xpdGlpa2thfHRhbG91cyIpICYgKCFzdHJfZGV0ZWN0KHN1YmplY3QsIlVsa29tYWF0IikgfCBzdHJfZGV0ZWN0KHN1YmplY3QsIktvdGltYWFuIHV1dGlzZXQiKSksCiAgVCB+IEYKKSkgJT4lIAogIGRpc3RpbmN0KGFfaWQpICU+JSAKICBjb21wdXRlKG5hbWU9ImFydGljbGVzX2NkcCIsdGVtcG9yYXJ5PUYsdW5pcXVlX2luZGV4ZXM9YygiYV9pZCIpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIGFydGljbGVzX29waW5pb25hdGVkIikKYXJ0aWNsZXNfb3BpbmlvbmF0ZWQgPC0gYXJ0aWNsZXMgJT4lIG11dGF0ZShvcGluaW9uYXRlZD1jYXNlX3doZW4oCiAgbWVkaWEgPT0gIkhTIiB+IGNhc2Vfd2hlbigKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAicMOkw6RraXJqb2l0dXMiICYgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIoc3RvcnlfbG9nbyksImllcmFzIikgfiAiZXh0ZXJuYWwgZWRpdG9yaWFsIiwKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAicMOkw6RraXJqb2l0dXMiICYgaXMubmEoc3RvcnlfbG9nbykgfiAiZWRpdG9yaWFsIiwKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAicMOkw6RraXJqb2l0dXMiICYgc3RyX3RvX2xvd2VyKHN0b3J5X2xvZ28pID09ICJww6TDpGtpcmpvaXR1cyIgfiAiZWRpdG9yaWFsIiwKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAibWllbGlwaWRlIiB8IHN0cl90b19sb3dlcihzdG9yeV9sb2dvKSA9PSAibWllbGlwaWRlIiB+ICJleHRlcm5hbCBvcGluaW9uIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwiYW5hbHl5c2k6IikgfCBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcihzdG9yeV9sb2dvKSwiYW5hbHl5c2kiKSAgfiAiYW5hbHlzaXMiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJuw6Rrw7ZrdWxtYToiKSB8IHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHN0b3J5X2xvZ28pLCJuw6Rrw7ZrdWxtYSIpIH4gInBlcnNwZWN0aXZlIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwia29sdW1uaToiKSB8IHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHN0b3J5X2xvZ28pLCJrb2x1bW5pIikgfiAiY29sdW1uIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwiYmxvZ2k6IikgfCBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcihzdG9yeV9sb2dvKSwiYmxvZyIpIH4gImJsb2ciICAgIAogICksCiAgbWVkaWEgPT0gIklMIiB+IGNhc2Vfd2hlbigKICAgIHN1YnNlY3Rpb24gPT0gInBhYWtpcmpvaXR1cyIgfiAiZWRpdG9yaWFsIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwia29tbWVudHRpOiIpIH4gImNvbW1lbnRhcnkiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJhbmFseXlzaToiKSB+ICJhbmFseXNpcyIsCiAgICBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcih0aXRsZSksImtvbHVtbmk6IikgfiAiY29sdW1uIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwibsOka8O2a3VsbWE6IikgfiAicGVyc3BlY3RpdmUiCiAgKSwKICBtZWRpYSA9PSAiWUxFIiB+IGNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwia29tbWVudHRpOiIpIH4gImNvbW1lbnRhcnkiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJhbmFseXlzaToiKSB8IHN0cl9kZXRlY3Qoc3ViamVjdCwiQW5hbHl5c2l0IFxcKFlsZSBVdXRpc2V0XFwpIikgfiAiYW5hbHlzaXMiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJrb2x1bW5pOiIpIHwgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIoc3ViamVjdCksImtvbHVtbiIpIH4gImNvbHVtbiIsCiAgICBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcih0aXRsZSksIm7DpGvDtmt1bG1hOiIpICB8IHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHN1YmplY3QpLCJuw6Rrw7ZrdWxtIikgfiAicGVyc3BlY3RpdmUiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJibG9naToiKSAgfCBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcihzdWJqZWN0KSwiYmxvZyIpIH4gImJsb2ciCiAgKQopKSAlPiUKICBmaWx0ZXIoIWlzLm5hKG9waW5pb25hdGVkKSkgJT4lCiAgZGlzdGluY3QoYV9pZCwgb3BpbmlvbmF0ZWQpICU+JQogIGNvbXB1dGUobmFtZT0iYXJ0aWNsZXNfb3BpbmlvbmF0ZWQiLHRlbXBvcmFyeT1GLHVuaXF1ZV9pbmRleGVzPWMoImFfaWQiKSkKYGBgCgpgYGB7cixldmFsPUZBTFNFfQpsYWJlbHMgPC0gcmVhZF90c3YoaGVyZSgiZGF0YS9wZXJzb25fbGFiZWxzLnRzdiIpKSAlPiUKICBmaWx0ZXIoIWNhdGVnb3J5ICVpbiUgYygnYWRqZWt0aWl2aScsICdlaScpKQoKbGVtbWFzX29mX2ludGVyZXN0IDwtIGxhYmVscyAlPiUKICByZW5hbWUoImxlbW1hIiA9ICJuYW1lIikgJT4lCiAgY29weV90byhjb24sLixuYW1lPSJsYWJlbHMiLG92ZXJ3cml0ZT1UKSAlPiUKICB1bmlvbl9hbGwod29yZHMgJT4lCiAgICBmaWx0ZXIoc3RyX2RldGVjdChsZW1tYSwgInloZGVuI3ZlIikpICU+JSAKICAgICAgZGlzdGluY3QobGVtbWEpICU+JSAKICAgICAgbXV0YXRlKGNhdGVnb3J5PSJ5aGRlbnZlcnRhaXN1dXMiKSkgJT4lCiAgdW5pb25fYWxsKHdvcmRzICU+JQogICAgICBmaWx0ZXIoc3RyX2RldGVjdChsZW1tYSwgInRhc2EjYXJ2IikpICU+JSAKICAgICAgZGlzdGluY3QobGVtbWEpICU+JSAKICAgICAgbXV0YXRlKGNhdGVnb3J5PSJ0YXNhLWFydm8iKSkgJT4lCiAgZGlzdGluY3QoKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIHdvcmRzX29mX2ludGVyZXN0IikKd29yZHNfb2ZfaW50ZXJlc3QgPC0gd29yZHMgJT4lIAogIGlubmVyX2pvaW4obGVtbWFzX29mX2ludGVyZXN0KSAlPiUgCiAgZGlzdGluY3Qod19pZCxsZW1tYSxjYXRlZ29yeSxnZW51cykgJT4lIAogIGNvbXB1dGUobmFtZT0id29yZHNfb2ZfaW50ZXJlc3QiLHRlbXBvcmFyeT1GLGluZGV4ZXM9Yygid19pZCIsImNhdGVnb3J5IiwiZ2VudXMiKSkKYGBgCgpgYGB7cixldmFsPUZBTFNFfQpkYkV4ZWN1dGUoY29uLCJEUk9QIFRBQkxFIElGIEVYSVNUUyBjb3JwdXNfb2ZfaW50ZXJlc3QiKQpjb3JwdXNfb2ZfaW50ZXJlc3QgPC0gY29ycHVzICU+JQogIGlubmVyX2pvaW4od29yZHNfb2ZfaW50ZXJlc3QpICU+JQogIGNvbXB1dGUobmFtZT0iY29ycHVzX29mX2ludGVyZXN0Iix0ZW1wb3Jhcnk9RixpbmRleGVzPWxpc3QoYygiYV9pZCIsInBhcl9pZCIsInNfaWQiLCJwb3MiKSxjKCJ3X2lkIiksYygiZ2VudXMiKSxjKCJjYXRlZ29yeSIpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIGFydGljbGVfdHlwZXMiKQphcnRpY2xlX3R5cGVzIDwtIGFydGljbGVzICU+JSAKICBsZWZ0X2pvaW4oYXJ0aWNsZXNfY2RwICU+JSBtdXRhdGUoY2RwPVQpKSAlPiUKICBsZWZ0X2pvaW4oYXJ0aWNsZXNfb3BpbmlvbmF0ZWQpICU+JQogIG11dGF0ZSh0eXBlPWNhc2Vfd2hlbigKICAgIG1lZGlhID09ICJTVFQiICYgdmVyc2lvbiAhPSAiTG9wcHV2ZXJzaW8iIH4gIk90aGVyIiwKICAgICFpcy5uYShvcGluaW9uYXRlZCkgJiAhc3RyX2RldGVjdChvcGluaW9uYXRlZCwiXmV4dGVybmFsICIpIH4gIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwKICAgICFpcy5uYShvcGluaW9uYXRlZCkgfiAiRXh0ZXJuYWwgb3BpbmlvbiIsCiAgICBjZHAgfiAiRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsCiAgICBtZWRpYSA9PSAiSFMiICYgc2VjdGlvbiA9PSAiS3VsdHR1dXJpIiB+ICJDdWx0dXJlL2VudGVydGFpbm1lbnQiLAogICAgbWVkaWEgPT0gIklMIiAmIHNlY3Rpb24gPT0gInZpaWhkZSIgfiAiQ3VsdHVyZS9lbnRlcnRhaW5tZW50IiwKICAgIG1lZGlhID09ICJTVFQiICYgc2VjdGlvbiA9PSAiS3VsdHR1dXJpIiB+ICJDdWx0dXJlL2VudGVydGFpbm1lbnQiLAogICAgbWVkaWEgPT0gIllMRSIgJiBzZWN0aW9uID09ICJZbGUgVXV0aXNldCIgJiBzdHJfZGV0ZWN0KHN1YmplY3QsImt1bHR0dXVyaXxtdXNpaWtraXx2aWloZGUiKSAmICFzdHJfZGV0ZWN0KHN1YmplY3QsICJVbGtvbWFhdCIpIH4gIkN1bHR1cmUvZW50ZXJ0YWlubWVudCIsCiAgICBtZWRpYSA9PSAiSFMiICYgc2VjdGlvbiA9PSAiS2F1cHVua2kiIH4gIkxvY2FsIG5ld3MiLAogICAgbWVkaWEgPT0gIllMRSIgJiBzZWN0aW9uID09ICJZbGUgVXV0aXNldCIgJiBjb3ZlcmFnZT09ImxvY2FsIiB+ICJMb2NhbCBuZXdzIiwKICAgIG1lZGlhID09ICJTVFQiICYgc2VjdGlvbiA9PSAiVXJoZWlsdSIgfiAiU3BvcnRzIiwKICAgIG1lZGlhID09ICJIUyIgJiBzZWN0aW9uID09ICJVcmhlaWx1IiB+ICJTcG9ydHMiLAogICAgbWVkaWEgPT0gIllMRSIgJiBzZWN0aW9uID09ICJZTEUgVXJoZWlsdSIgfiAiU3BvcnRzIiwKICAgIG1lZGlhID09ICJJTCIgJiBzZWN0aW9uID09ICJ1cmhlaWx1IiB+ICJTcG9ydHMiLAogICAgbWVkaWEgPT0gIlNUVCIgJiBzZWN0aW9uID09ICJVbGtvbWFhdCIgfiAiRm9yZWlnbiBuZXdzIiwKICAgIG1lZGlhID09ICJIUyIgJiBzZWN0aW9uID09ICJVbGtvbWFhdCIgfiAiRm9yZWlnbiBuZXdzIiwKICAgIG1lZGlhID09ICJZTEUiICYgc2VjdGlvbiA9PSAiWWxlIFV1dGlzZXQiICYgc3RyX2RldGVjdChzdWJqZWN0LCJVbGtvbWFhdCIpICYgIXN0cl9kZXRlY3Qoc3ViamVjdCwiS290aW1hYW4gdXV0aXNldCIpIH4gIkZvcmVpZ24gbmV3cyIsCiAgICBtZWRpYSA9PSAiSUwiICYgc3Vic2VjdGlvbiA9PSAidWxrb21hYXQiIH4gIkZvcmVpZ24gbmV3cyIsCiAgICBUIH4gIk90aGVyIgogICkpICU+JQogIGRpc3RpbmN0KGFfaWQsdHlwZSkgJT4lCiAgY29tcHV0ZSh0ZW1wb3Jhcnk9RixuYW1lPSJhcnRpY2xlX3R5cGVzIix1bmlxdWVfaW5kZXhlcz1saXN0KGMoImFfaWQiKSxjKCJhX2lkIiwidHlwZSIpLGMoInR5cGUiLCJhX2lkIikpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciIpCmFydGljbGVzX2J5X3R5cGVfYnlfeWVhciA8LSBhcnRpY2xlcyAlPiUgCiAgaW5uZXJfam9pbihhcnRpY2xlX3R5cGVzKSAlPiUKICBtdXRhdGUoeWVhcl9jcmVhdGVkPXllYXIoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgY291bnQobWVkaWEseWVhcl9jcmVhdGVkLHR5cGUsbmFtZT0idG90YWxfYXJ0aWNsZXMiKSAlPiUKICBjb21wdXRlKHVuaXF1ZV9pbmRleGVzPWxpc3QoYygibWVkaWEiLCJ5ZWFyX2NyZWF0ZWQiLCJ0eXBlIikpLHRlbXBvcmFyeT1GLG5hbWU9ImFydGljbGVzX2J5X3R5cGVfYnlfeWVhciIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KZGJFeGVjdXRlKGNvbiwiRFJPUCBUQUJMRSBJRiBFWElTVFMgYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMiKQphcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcyA8LSB3b3Jkc19vZl9pbnRlcmVzdCAlPiUKICAgIGZpbHRlcihjYXRlZ29yeSAlaW4lIGMoInRhc2EtYXJ2byIsInloZGVudmVydGFpc3V1cyIpKSAlPiUKICAgIGlubmVyX2pvaW4oY29ycHVzKSAlPiUKICAgIGdyb3VwX2J5KGFfaWQpICU+JQogICAgc3VtbWFyaXplKHl2PW1heChjYXRlZ29yeT09InloZGVudmVydGFpc3V1cyIpLHRhPW1heChjYXRlZ29yeT09InRhc2EtYXJ2byIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICAgIG11dGF0ZShyZWZfY2F0ZWdvcnk9Y2FzZV93aGVuKHl2PT0xICYgdGE9PTEgfiAiYm90aCIseXY9PTEgfiAieWhkZW52ZXJ0YWlzdXVzIiwgdGE9PTEgfiAidGFzYS1hcnZvIikpICU+JSAKICBzZWxlY3QoYV9pZCxyZWZfY2F0ZWdvcnkpICU+JSAKICBjb21wdXRlKCkKYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMgPC0gYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMgJT4lIHVuaW9uX2FsbCgKICAgIGFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzICU+JQogICAgZmlsdGVyKHJlZl9jYXRlZ29yeT09ImJvdGgiKSAlPiUgCiAgICBtdXRhdGUocmVmX2NhdGVnb3J5PSJ5aGRlbnZlcnRhaXN1dXMiKQogICkgJT4lCiAgdW5pb25fYWxsKAogICAgYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMgJT4lCiAgICBmaWx0ZXIocmVmX2NhdGVnb3J5PT0iYm90aCIpICU+JSAKICAgIG11dGF0ZShyZWZfY2F0ZWdvcnk9InRhc2EtYXJ2byIpCiAgKSAlPiUKICBjb21wdXRlKHRlbXBvcmFyeT1GLG5hbWU9ImFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzIixpbmRleGVzPWMoImFfaWQiKSx1bmlxdWVfaW5kZXhlcz1saXN0KGMoImFfaWQiLCJyZWZfY2F0ZWdvcnkiKSxjKCJyZWZfY2F0ZWdvcnkiLCJhX2lkIikpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9Cnl2X3RhX2NvcnB1cyA8LSB3b3Jkc19vZl9pbnRlcmVzdCAlPiUKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJ0YXNhLWFydm8iLCJ5aGRlbnZlcnRhaXN1dXMiKSkgJT4lCiAgaW5uZXJfam9pbihjb3JwdXMpIAoKZGJFeGVjdXRlKGNvbiwiRFJPUCBUQUJMRSBJRiBFWElTVFMgeXZfdGFfcGFyYWdyYXBocyIpCnl2X3RhX3BhcmFncmFwaHMgPC0geXZfdGFfY29ycHVzICU+JQogIGRpc3RpbmN0KGFfaWQscGFyX2lkKSAlPiUKICBjb21wdXRlKHRlbXBvcmFyeT1GLG5hbWU9Inl2X3RhX3BhcmFncmFwaHMiLCB1bmlxdWVfaW5kZXhlcz1saXN0KGMoImFfaWQiLCJwYXJfaWQiKSkpCmBgYAoKIyBBbmFseXNpcyB0YWJsZSBsb2FkcwoKYGBge3J9CmFydGljbGVzX2NkcCA8LSB0YmwoY29uLCJhcnRpY2xlc19jZHAiKQphcnRpY2xlc19vcGluaW9uYXRlZCA8LSB0YmwoY29uLCJhcnRpY2xlc19vcGluaW9uYXRlZCIpCmFydGljbGVfdHlwZXMgPC0gdGJsKGNvbiwiYXJ0aWNsZV90eXBlcyIpCmFydGljbGVzX2J5X3R5cGVfYnlfeWVhciA8LSB0YmwoY29uLCJhcnRpY2xlc19ieV90eXBlX2J5X3llYXIiKQp3b3Jkc19vZl9pbnRlcmVzdCA8LSB0YmwoY29uLCJ3b3Jkc19vZl9pbnRlcmVzdCIpCmNvcnB1c19vZl9pbnRlcmVzdCA8LSB0YmwoY29uLCJjb3JwdXNfb2ZfaW50ZXJlc3QiKQphcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcyA8LSB0YmwoY29uLCJhcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcyIpCnl2X3RhX3BhcmFncmFwaHMgPC0gdGJsKGNvbiwieXZfdGFfcGFyYWdyYXBocyIpCmBgYAoKIyBOYW1lZCBxdWVyeSBkZWZpbml0aW9ucwoKYGBge3J9CnF1b3RhdGlvbl9jb3JwdXMgPC0gcXVvdGVzICU+JSAKICBpbm5lcl9qb2luKGNvcnB1cyxzcWxfb249IkxIUy5hX2lkPVJIUy5hX2lkIEFORCAoc19pZCA+IHN0YXJ0X3NfaWQgT1IgKHNfaWQ9c3RhcnRfc19pZCBBTkQgcG9zID49IHN0YXJ0X3BvcykpIEFORCAoc19pZCA8IGVuZF9zX2lkIE9SIChzX2lkPWVuZF9zX2lkIEFORCBwb3MgPD0gZW5kX3BvcykpIikgJT4lCiAgc2VsZWN0KGFfaWQ9YV9pZC54LHBhcl9pZCxzX2lkLHBvcywgcV9pZCkKCnF1b3RhdGlvbl9zZW50ZW5jZV9jb3JwdXMgPC0gcXVvdGVzICU+JSAKICBpbm5lcl9qb2luKGNvcnB1cyxzcWxfb249IkxIUy5hX2lkPVJIUy5hX2lkIEFORCBzX2lkID49IHN0YXJ0X3NfaWQgQU5EIHNfaWQgPD0gZW5kX3NfaWQiKSAlPiUKICBzZWxlY3QoYV9pZD1hX2lkLngscGFyX2lkLHNfaWQscG9zLCBxX2lkKQoKeXZfY29ycHVzIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5PT0ieWhkZW52ZXJ0YWlzdXVzIikKCnl2X3BhcmFncmFwaHMgPC0geXZfY29ycHVzICU+JSAKICBkaXN0aW5jdChhX2lkLHBhcl9pZCkKCnRhX2NvcnB1cyA8LSBjb3JwdXNfb2ZfaW50ZXJlc3QgJT4lIAogIGZpbHRlcihjYXRlZ29yeT09InRhc2EtYXJ2byIpCgp0YV9wYXJhZ3JhcGhzIDwtIHRhX2NvcnB1cyAlPiUgCiAgZGlzdGluY3QoYV9pZCxwYXJfaWQpCgpxdW90ZV9vcmdzIDwtIHJlYWRfdHN2KGhlcmUoImRhdGEvcV9pZF90b19vcmdzLnRzdiIpKSAlPiUKICBzZWxlY3QoYyhhdXRob3JfaGVhZCwgYV9pZCwgb3JnX2NhdCkpCgpkIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzICU+JSBzZWxlY3QoYV9pZCxkYXRlX2NyZWF0ZWQsbWVkaWEpKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIGxlZnRfam9pbihhcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcykgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZT1UKSkgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9zZW50ZW5jZV9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZV9zZW50ZW5jZT1UKSkgJT4lCiAgbGVmdF9qb2luKHF1b3RlX29yZ3MsIGNvcHkgPSBUUlVFLCBhdXRvX2luZGV4ID0gVFJVRSkgJT4lCiAgbXV0YXRlKGluX3F1b3RlX2hlYWQ9aW5fcXVvdGVfc2VudGVuY2UgJiAhaW5fcXVvdGUpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHR5cGUyPWNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QodHlwZSwib3BpbmlvbiQiKSB+IHR5cGUsCiAgICBpbl9xdW90ZV9zZW50ZW5jZSB+IHN0cl9jKCJRdW90ZXMgaW4gIix0eXBlKSwKICAgIFRSVUUgfiBzdHJfYygiSm91cm5hbGlzdGljIHRleHQgaW4gIix0eXBlKQogICkpCiAgCmQyIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUKICBpbm5lcl9qb2luKHl2X3RhX3BhcmFncmFwaHMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXMgJT4lIHNlbGVjdChhX2lkLGRhdGVfY3JlYXRlZCxtZWRpYSkpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZV90eXBlcykgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcykgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZT1UKSkgJT4lCiAgbGVmdF9qb2luKHF1b3RlX29yZ3MsIGNvcHkgPSBUUlVFLCBhdXRvX2luZGV4ID0gVFJVRSkgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9zZW50ZW5jZV9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZV9zZW50ZW5jZT1UKSkgJT4lCiAgbXV0YXRlKGluX3F1b3RlX2hlYWQ9aW5fcXVvdGVfc2VudGVuY2UgJiAhaW5fcXVvdGUpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHR5cGUyPWNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QodHlwZSwib3BpbmlvbiQiKSB+IHR5cGUsCiAgICBpbl9xdW90ZV9zZW50ZW5jZSB+IHN0cl9jKCJRdW90ZXMgaW4gIix0eXBlKSwKICAgIFRSVUUgfiBzdHJfYygiSm91cm5hbGlzdGljIHRleHQgaW4gIix0eXBlKQogICkpCmBgYAoKYGBge3J9CmtleV9jYXRzIDwtIGMoJ3BvdGlsYXMnLCAnbWFhaGFubXV1dHRvJywgJ2V0bm9zJywgJ3Nla3N1YWFsaXN1dXMnLCAndHnDtnN1aGRlJykKbWFpbl90eXBlcyA8LSBjKCdjb3JlJywgJ29waW5pb25hdGVkJywgJ2V4dGVybmFsIG9waW5pb24nKQpgYGAKCiMgQW5hbHlzaXMgMTogZGV2ZWxvcG1lbnQgb2YgeWhkZW52ZXJ0YWlzdXVzL3Rhc2EtYXJ2byBpbiBkaWZmZXJlbnQgdGV4dCBnZW5yZXMKCiMjIE1hc3RlciBjaGFydAoKYGBge3J9Cm15X2QgPC0gZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygieWhkZW52ZXJ0YWlzdXVzIiwidGFzYS1hcnZvIikpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGdyb3VwX2J5KG1lZGlhLGNhdGVnb3J5LHR5cGUsdHlwZTIseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSxkYXlzPW5fZGlzdGluY3QoZGF0ZV9jcmVhdGVkKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIsYnk9YygibWVkaWEiLCJ0eXBlIiwieWVhcl9jcmVhdGVkIikpICU+JQogIGNvbGxlY3QoKQoKbXlfZDIgPC0gZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygieWhkZW52ZXJ0YWlzdXVzIiwidGFzYS1hcnZvIikpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGdyb3VwX2J5KGFfaWQsbWVkaWEsdHlwZSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIGZpbHRlcihhbnkoY2F0ZWdvcnk9PSJ5aGRlbnZlcnRhaXN1dXMiKSxhbnkoY2F0ZWdvcnk9PSJ0YXNhLWFydm8iKSkgJT4lCiAgZ3JvdXBfYnkobWVkaWEsdHlwZSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIHN1bW1hcml6ZShhcnRpY2xlcz1uX2Rpc3RpbmN0KGFfaWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhcixieT1jKCJtZWRpYSIsInR5cGUiLCJ5ZWFyX2NyZWF0ZWQiKSkgJT4lCiAgY29sbGVjdCgpCgpteV9kIDwtIG15X2QgJT4lIAogIG11dGF0ZSh3b3JkPSJXb3JkIikgJT4lCiAgdW5pb25fYWxsKG15X2QyICU+JSAKICAgICAgICAgICAgICBtdXRhdGUoY2F0ZWdvcnk9InRhc2EtYXJ2byIpICU+JQogICAgICAgICAgICAgIG11dGF0ZSh3b3JkPSJCb3RoIikpICU+JQogIHVuaW9uX2FsbChteV9kMiAlPiUgCiAgICAgICAgICAgICAgbXV0YXRlKGNhdGVnb3J5PSJ5aGRlbnZlcnRhaXN1dXMiKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUod29yZD0iQm90aCIpKSAlPiUKICBtdXRhdGUoCiAgICB3b3JkPWZjdF9yZWxldmVsKHdvcmQsIldvcmQiKSwKICAgIGNhdGVnb3J5PWZjdF9yZWxldmVsKGNhdGVnb3J5LCJ0YXNhLWFydm8iLCJ5aGRlbnZlcnRhaXN1dXMiKSwKICAgIHR5cGUyPWZjdF9yZWxldmVsKHR5cGUyLCJFeHRlcm5hbCBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiUXVvdGVzIGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiSm91cm5hbGlzdGljIHRleHQgaW4gTG9jYWwgbmV3cyIsICJRdW90ZXMgaW4gTG9jYWwgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBGb3JlaWduIG5ld3MiLCAiUXVvdGVzIGluIEZvcmVpZ24gbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBDdWx0dXJlL2VudGVydGFpbm1lbnQiLCAiUXVvdGVzIGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBTcG9ydHMiLCAiUXVvdGVzIGluIFNwb3J0cyIpKSAgCmBgYAoKYGBge3IsZmlnLndpZHRoPTI4LGZpZy5oZWlnaHQ9OCxldmFsPUZBTFNFfQpteV9kICU+JQogIGZpbHRlcih0eXBlPT0iT3RoZXIiKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9bWVkaWEsbGluZXR5cGU9d29yZCkpICsKICBnZW9tX3N0ZXAoKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMjAwOSxjb2xvcj0icmVkIikgKyAKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT00KSkgKwogIGZhY2V0X2dyaWQoY2F0ZWdvcnl+dHlwZTIsc2NhbGVzPSJmcmVlIikgKwogIGxhYnMoY29sb3I9Ik1lZGlhIixsaW5ldHlwZT0iU2lnbmFsIikgKwogIHhsYWIoIlllYXIiKSArCiAgeWxhYigiUGVyY2VudGFnZSBvZiBhcnRpY2xlcyBvZiB0eXBlIGNvbnRhaW5pbmcgdGhlIHdvcmQiKQpgYGAKCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KMTozICU+JSBtYXAofgogIG15X2QgJT4lCiAgICBmaWx0ZXIodHlwZSE9Ik90aGVyIikgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9bWVkaWEsbGluZXR5cGU9d29yZCkpICsKICAgIGdlb21fc3RlcCgpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDIwMDksY29sb3I9InJlZCIpICsgCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0wLjEpKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9NCkpICsKICAgIGZhY2V0X2dyaWRfcGFnaW5hdGUoY2F0ZWdvcnl+dHlwZTIsc2NhbGVzPSJmcmVlIiwgbnJvdz0yLCBuY29sPTQsIHBhZ2U9LngpICsKICAgIGxhYnMoY29sb3I9Ik1lZGlhIixsaW5ldHlwZT0iU2lnbmFsIikgKwogICAgeGxhYigiWWVhciIpICsKICAgIHlsYWIoIlBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgb2YgdHlwZSBjb250YWluaW5nIHRoZSB3b3JkIikKKQpgYGAKCkNvbmNsdXNpb25zOgoKLSBJTCBpcyBiZWhpbmQgb3RoZXIgbWVkaWEgaW4gY2hhbmdlLCBidXQgc2FtZSB0cmFqZWN0b3J5Ci0gRm9yIGZvcmVpZ24gbmV3cywgU1RUIChhbmQgdGhlcmVmb3JlIElMKSBkbyBub3QgaW5jcmVhc2UgdGFzYS1hcnZvIHRlcm1pbm9sb2d5IHVzYWdlCi0gRm9yIGxvY2FsIG5ld3MsIHRlcm1pbm9sb2d5IHVzYWdlIGluY3JlYXNlcyBvbmx5IGZvciBIUyAoSGVsc2lua2kpIGFzIG9wcG9zZWQgdG8gWUxFIChyZWdpb25hbCBuZXdzKQotIEZvciBjdWx0dXJlL2VudGVydGFpbm1lbnQsIG90aGVyIHNvdXJjZXMgZGlmZmVyIGZyb20gSUwuIFRoaXMgaXMgcHJvYmFibHkgZHVlIHRvIGNhdGVnb3J5IGhldGVyb2dlbmVpdHk6IGZvciBJTCwgdGhpcyBjYXRlZ29yeSBjb250YWlucyBlbnRlcnRhaW5tZW50IG5ld3MsIGZvciBvdGhlcnMsIHRoZXNlIGFyZSBtb3JlIGN1bHR1cmUgcmV2aWV3cyBldGMuCgojIyBEb2VzIGNoYW5nZSBpbiBtZWRpYSBjb21wb3NpdGlvbiBhZmZlY3QgcmVzdWx0cz8KCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KMTozICU+JSBtYXAofgogIG15X2QgJT4lCiAgICBmaWx0ZXIodHlwZSE9Ik90aGVyIikgJT4lCiAgICBtdXRhdGUoCiAgICAgIGxfdG90YWxfYXJ0aWNsZXM9aWZfZWxzZShtZWRpYSAlaW4lIGMoIkhTIiwiU1RUIiksdG90YWxfYXJ0aWNsZXMsMEwpLAogICAgICBsX2FydGljbGVzPWlmX2Vsc2UobWVkaWEgJWluJSBjKCJIUyIsIlNUVCIpLGFydGljbGVzLDBMKQogICAgICApICU+JQogICAgZ3JvdXBfYnkoeWVhcl9jcmVhdGVkLGNhdGVnb3J5LHR5cGUyLHdvcmQpICU+JQogICAgc3VtbWFyaXplKGBIUy9TVFRgPXN1bShsX2FydGljbGVzKS9zdW0obF90b3RhbF9hcnRpY2xlcyksYEFsbCBtZWRpYXNgPXN1bShhcnRpY2xlcykvc3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgICBwaXZvdF9sb25nZXIoYEhTL1NUVGA6YEFsbCBtZWRpYXNgKSAlPiUKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT12YWx1ZSxjb2xvcj1uYW1lLGxpbmV0eXBlPXdvcmQpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5LGNvbG9yPSJyZWQiKSArIAogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTQpKSArCiAgICBmYWNldF9ncmlkX3BhZ2luYXRlKGNhdGVnb3J5fnR5cGUyLHNjYWxlcz0iZnJlZSIsbnJvdz0yLG5jb2w9NCxwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJNZWRpYSIpICsKICAgIHhsYWIoIlllYXIiKSArCiAgICB5bGFiKCJQZXJjZW50YWdlIG9mIGFydGljbGVzIG9mIHR5cGUgY29udGFpbmluZyB0aGUgd29yZCIpCikKYGBgCgpDb25jbHVzaW9uczoKCiAtIElmIHdlIG1lbnRpb24gdGhlIElML1NUVCBiZWhhdmlvciBmcm9tIGFib3ZlIGluIHRleHQsIHdlIGNhbiB0aGVuIGRyb3AgdGhlIG1lZGlhcyBmcm9tIGdyYXBocyBhcyB0aGV5IGRvIG5vdCBvdGhlcndpc2UgYWZmZWN0IHJlc3VsdHMgZm9yIG1haW4gY2F0ZWdvcmllcyBvZiBpbnRlcmVzdC4KCiMjIEZpbmFsIGdyYXBoIHRvIGluY2x1ZGUgaW4gYXJ0aWNsZQoKYGBge3J9CmQgJT4lIAogIGZpbHRlcihjYXRlZ29yeSAlaW4lIGMoInloZGVudmVydGFpc3V1cyIsInRhc2EtYXJ2byIpKSAlPiUgCiAgZmlsdGVyKHR5cGUgJWluJSBjKCJEb21lc3RpYyBnZW5lcmFsL3BvbGl0aWNhbC9lY29ub21pYyBuZXdzIiwgIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwgIkV4dGVybmFsIG9waW5pb24iKSkgJT4lCiAgbGVmdF9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciAlPiUgZ3JvdXBfYnkodHlwZSx5ZWFyX2NyZWF0ZWQpICU+JQogICAgICAgICAgICAgICBzdW1tYXJpemUodG90YWxfYXJ0aWNsZXM9c3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIiksYnk9YygidHlwZSIsInllYXJfY3JlYXRlZCIpKSAlPiUKICBncm91cF9ieShjYXRlZ29yeSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIHN1bW1hcml6ZSh0b3RhbF9hcnRpY2xlcz1taW4odG90YWxfYXJ0aWNsZXMpLGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksZGF5cz1uX2Rpc3RpbmN0KGRhdGVfY3JlYXRlZCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGNvbGxlY3QoKSAlPiUKICBtdXRhdGUodHlwZTI9ZmN0X3JlbGV2ZWwodHlwZTIsIkV4dGVybmFsIG9waW5pb24iLCJKb3VybmFsaXN0aWMgb3BpbmlvbiIpKSAlPiUKICBtdXRhdGUoY2F0ZWdvcnk9ZmN0X3JlbGV2ZWwoY2F0ZWdvcnksInloZGVudmVydGFpc3V1cyIpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9dHlwZTIpKSArCiAgZ2VvbV9zdGVwKCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0wLjEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTUpKSArCiAgZmFjZXRfd3JhcCh+Y2F0ZWdvcnksIHNjYWxlcz0iZnJlZV95IikgKwogIGxhYnMoY29sb3I9IlRleHQgdHlwZSIpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIlBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgb2YgdHlwZSBjb250YWluaW5nIHRoZSB3b3JkIikgKwogIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAxKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjAyLCAwLjk4KSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKQpgYGAKCiMgQW5hbHlzaXMgMjogZGlzdHJpYnV0aW9uIG9mIGxhbmd1YWdlIGJ5IHNwZWFrZXIgYW5kIHN1YmplY3QgY2F0ZWdvcnkKCmBgYHtyfQoKZCAlPiUKICBmaWx0ZXIob3JnX2NhdCAlaW4lIGMoInBvbGl0aWlra2EiLCAib2lrZXVzIiksIGNhdGVnb3J5ICVpbiUgYygieWhkZW52ZXJ0YWlzdXVzIiwgInRhc2EtYXJ2byIpLCBpbl9xdW90ZSA9PSBUKSAlPiUKICBncm91cF9ieShvcmdfY2F0LHllYXJfY3JlYXRlZCwgY2F0ZWdvcnkpICU+JQogIHN1bW1hcml6ZShuPW4oKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PW4sY29sb3I9Y2F0ZWdvcnkpKSArCiAgZ2VvbV9zdGVwKCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogIGZhY2V0X2dyaWQofm9yZ19jYXQsIHNjYWxlcz0iZnJlZSIpCgpkICU+JQogIGZpbHRlcihvcmdfY2F0ICVpbiUgYygicG9saXRpaWtrYSIsICJvaWtldXMiKSwgY2F0ZWdvcnkgJWluJSBrZXlfY2F0cywgaW5fcXVvdGUgPT0gVCkgJT4lCiAgZ3JvdXBfYnkob3JnX2NhdCx5ZWFyX2NyZWF0ZWQsIGNhdGVnb3J5KSAlPiUKICBzdW1tYXJpemUobj1uKCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1uLGNvbG9yPWNhdGVnb3J5KSkgKwogIGdlb21fc3RlcCgpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICBmYWNldF9ncmlkKH5vcmdfY2F0LCBzY2FsZXM9ImZyZWUiKQpgYGAKCiMgQW5hbHlzaXMgMzogc3ViamVjdCBhc3NvY2lhdGlvbnMKCmBgYHtyfQpzcCA8LSB5dl90YV9wYXJhZ3JhcGhzICU+JQogIGlubmVyX2pvaW4oCiAgICB3b3JkcyAlPiUgCiAgICAgIGZpbHRlcihsZW1tYT09InN1a3UjcHVvbGkiKSAlPiUKICAgICAgaW5uZXJfam9pbihjb3JwdXMpCiAgICApICU+JSBpbm5lcl9qb2luKGFydGljbGVzICU+JSBzZWxlY3QoYV9pZCxkYXRlX2NyZWF0ZWQsbWVkaWEpKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIGxlZnRfam9pbihxdW90YXRpb25fc2VudGVuY2VfY29ycHVzICU+JSBtdXRhdGUoaW5fcXVvdGVfc2VudGVuY2U9VCkpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHR5cGUyPWNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QodHlwZSwib3BpbmlvbiQiKSB+IHR5cGUsCiAgICBpbl9xdW90ZV9zZW50ZW5jZSB+IHN0cl9jKCJRdW90ZXMgaW4gIix0eXBlKSwKICAgIFRSVUUgfiBzdHJfYygiSm91cm5hbGlzdGljIHRleHQgaW4gIix0eXBlKQogICkpICU+JQogIGdyb3VwX2J5KG1lZGlhLHJlZl9jYXRlZ29yeSx0eXBlLHR5cGUyLHllYXJfY3JlYXRlZCkgJT4lCiAgc3VtbWFyaXplKGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksd2Vla3M9bl9kaXN0aW5jdCh3ZWVrX2NyZWF0ZWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUgCiAgY29sbGVjdCgpICU+JQogIG11dGF0ZSgKICAgIHJlZl9jYXRlZ29yeT1mY3RfcmVsZXZlbChyZWZfY2F0ZWdvcnksInRhc2EtYXJ2byIsInloZGVudmVydGFpc3V1cyIpLAogICAgdHlwZTI9ZmN0X3JlbGV2ZWwodHlwZTIsIkV4dGVybmFsIG9waW5pb24iLCAiSm91cm5hbGlzdGljIG9waW5pb24iLCAiSm91cm5hbGlzdGljIHRleHQgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJRdW90ZXMgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBMb2NhbCBuZXdzIiwgIlF1b3RlcyBpbiBMb2NhbCBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEZvcmVpZ24gbmV3cyIsICJRdW90ZXMgaW4gRm9yZWlnbiBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJRdW90ZXMgaW4gQ3VsdHVyZS9lbnRlcnRhaW5tZW50IiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIFNwb3J0cyIsICJRdW90ZXMgaW4gU3BvcnRzIikpCiAgCm15X2NkIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUKICBmaWx0ZXIobGVtbWEhPSJzdW9tYWxhaW5lbiIpICU+JQogIGlubmVyX2pvaW4oeXZfdGFfcGFyYWdyYXBocykgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlcyAlPiUgc2VsZWN0KGFfaWQsZGF0ZV9jcmVhdGVkLG1lZGlhKSkgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlX3R5cGVzKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzKSAlPiUKICBtdXRhdGUoeWVhcl9jcmVhdGVkPXllYXIoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGxlZnRfam9pbihxdW90YXRpb25fc2VudGVuY2VfY29ycHVzICU+JSBtdXRhdGUoaW5fcXVvdGVfc2VudGVuY2U9VCkpICU+JQogIG11dGF0ZSh0eXBlMj1jYXNlX3doZW4oCiAgICBzdHJfZGV0ZWN0KHR5cGUsIm9waW5pb24kIikgfiB0eXBlLAogICAgaW5fcXVvdGVfc2VudGVuY2UgfiBzdHJfYygiUXVvdGVzIGluICIsdHlwZSksCiAgICBUUlVFIH4gc3RyX2MoIkpvdXJuYWxpc3RpYyB0ZXh0IGluICIsdHlwZSkKICApKQoKY2QyIDwtIG15X2NkICU+JQogIGdyb3VwX2J5KHJlZl9jYXRlZ29yeSxnZW51cyx0eXBlLHR5cGUyLHllYXJfY3JlYXRlZCkgJT4lCiAgc3VtbWFyaXplKGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksd2Vla3M9bl9kaXN0aW5jdCh3ZWVrX2NyZWF0ZWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUgCiAgY29sbGVjdCgpICU+JQogIG11dGF0ZSgKICAgIHJlZl9jYXRlZ29yeT1mY3RfcmVsZXZlbChyZWZfY2F0ZWdvcnksInRhc2EtYXJ2byIsInloZGVudmVydGFpc3V1cyIpLAogICAgdHlwZTI9ZmN0X3JlbGV2ZWwodHlwZTIsIkV4dGVybmFsIG9waW5pb24iLCAiSm91cm5hbGlzdGljIG9waW5pb24iLCAiSm91cm5hbGlzdGljIHRleHQgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJRdW90ZXMgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBMb2NhbCBuZXdzIiwgIlF1b3RlcyBpbiBMb2NhbCBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEZvcmVpZ24gbmV3cyIsICJRdW90ZXMgaW4gRm9yZWlnbiBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJRdW90ZXMgaW4gQ3VsdHVyZS9lbnRlcnRhaW5tZW50IiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIFNwb3J0cyIsICJRdW90ZXMgaW4gU3BvcnRzIikpCgpjZCA8LSBteV9jZCAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnksY2F0ZWdvcnksdHlwZSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIHN1bW1hcml6ZShhcnRpY2xlcz1uX2Rpc3RpbmN0KGFfaWQpLHdlZWtzPW5fZGlzdGluY3Qod2Vla19jcmVhdGVkKSxkYXlzPW5fZGlzdGluY3QoZGF0ZV9jcmVhdGVkKSwuZ3JvdXBzPSJkcm9wIikgJT4lIAogIGNvbGxlY3QoKSAlPiUKICBtdXRhdGUoCiAgICByZWZfY2F0ZWdvcnk9ZmN0X3JlbGV2ZWwocmVmX2NhdGVnb3J5LCJ0YXNhLWFydm8iLCJ5aGRlbnZlcnRhaXN1dXMiKSwKICAgIHR5cGUyPWZjdF9yZWxldmVsKHR5cGUyLCJFeHRlcm5hbCBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiUXVvdGVzIGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiSm91cm5hbGlzdGljIHRleHQgaW4gTG9jYWwgbmV3cyIsICJRdW90ZXMgaW4gTG9jYWwgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBGb3JlaWduIG5ld3MiLCAiUXVvdGVzIGluIEZvcmVpZ24gbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBDdWx0dXJlL2VudGVydGFpbm1lbnQiLCAiUXVvdGVzIGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBTcG9ydHMiLCAiUXVvdGVzIGluIFNwb3J0cyIpKQpgYGAKCiMjIEdlbmRlcgoKYGBge3IsZmlnLndpZHRoPTgsZmlnLmhlaWdodD02fQpteV9kIDwtIHNwICU+JQogIGZpbHRlcih0eXBlIT0iT3RoZXIiKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciAlPiUgCiAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXJfY3JlYXRlZCx0eXBlKSAlPiUKICAgICAgICAgICAgICAgc3VtbWFyaXplKHRvdGFsX2FydGljbGVzPXN1bSh0b3RhbF9hcnRpY2xlcyksLmdyb3Vwcz0iZHJvcCIpICU+JSBjb2xsZWN0KCkpICU+JSAKICBjb2xsZWN0KCkKCjE6MyAlPiUgbWFwKH4KICBteV9kICU+JSAKICAgIGZpbHRlcihyZWZfY2F0ZWdvcnkhPSJib3RoIikgJT4lCiAgICBtdXRhdGUoZmN0PXJlZl9jYXRlZ29yeSx3b3JkPSJXb3JkIikgJT4lCiAgICB1bmlvbl9hbGwoCiAgICAgIG15X2QgJT4lCiAgICAgICAgZmlsdGVyKHJlZl9jYXRlZ29yeT09ImJvdGgiKSAlPiUKICAgICAgICBtdXRhdGUoZmN0PSJ0YXNhLWFydm8iLHdvcmQ9IkJvdGgiKQogICAgKSAlPiUKICAgIHVuaW9uX2FsbCgKICAgICAgbXlfZCAlPiUKICAgICAgICBmaWx0ZXIocmVmX2NhdGVnb3J5PT0iYm90aCIpICU+JQogICAgICAgIG11dGF0ZShmY3Q9InloZGVudmVydGFpc3V1cyIsd29yZD0iQm90aCIpCiAgICApICU+JQogICAgbXV0YXRlKHdvcmQ9ZmN0X3JlbGV2ZWwod29yZCwiV29yZCIpKSAlPiUKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1tZWRpYSxsaW5ldHlwZT13b3JkKSkgKwogICAgZ2VvbV9zdGVwKCkgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMjAwOSxjb2xvcj0icmVkIikgKyAKICAgIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTAuMSkpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT00KSkgKwogICAgZmFjZXRfZ3JpZF9wYWdpbmF0ZShmY3R+dHlwZTIsc2NhbGVzPSJmcmVlIixuY29sPTQsbnJvdz0yLHBhZ2U9LngpICsKICAgIGxhYnMoY29sb3I9Ik1lZGlhIixsaW5ldHlwZT0iU2lnbmFsIikgKwogICAgeGxhYigiWWVhciIpICsKICAgIHlsYWIoIlBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgb2YgdHlwZSBjb250YWluaW5nIHRoZSB3b3JkIikKKQoKMTozICU+JSBtYXAofiAgCiAgbXlfZCAlPiUgCiAgICBmaWx0ZXIocmVmX2NhdGVnb3J5IT0iYm90aCIpICU+JQogICAgbXV0YXRlKGZjdD1yZWZfY2F0ZWdvcnksd29yZD0iV29yZCIpICU+JQogICAgdW5pb25fYWxsKAogICAgICBteV9kICU+JQogICAgICAgIGZpbHRlcihyZWZfY2F0ZWdvcnk9PSJib3RoIikgJT4lCiAgICAgICAgbXV0YXRlKGZjdD0idGFzYS1hcnZvIix3b3JkPSJCb3RoIikKICAgICkgJT4lCiAgICB1bmlvbl9hbGwoCiAgICAgIG15X2QgJT4lCiAgICAgICAgZmlsdGVyKHJlZl9jYXRlZ29yeT09ImJvdGgiKSAlPiUKICAgICAgICBtdXRhdGUoZmN0PSJ5aGRlbnZlcnRhaXN1dXMiLHdvcmQ9IkJvdGgiKQogICAgKSAlPiUKICAgIG11dGF0ZSh3b3JkPWZjdF9yZWxldmVsKHdvcmQsIldvcmQiKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9bWVkaWEsbGluZXR5cGU9d29yZCkpICsKICAgIGdlb21fc3RlcCgpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDIwMDksY29sb3I9InJlZCIpICsgCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0wLjEpKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9NCkpICsKICAgIGZhY2V0X3dyYXBfcGFnaW5hdGUoZmN0fnR5cGUyLHNjYWxlcz0iZnJlZSIsbmNvbD00LG5yb3c9MixwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJNZWRpYSIsbGluZXR5cGU9IlNpZ25hbCIpICsKICAgIHhsYWIoIlllYXIiKSArCiAgICB5bGFiKCJQZXJjZW50YWdlIG9mIGFydGljbGVzIG9mIHR5cGUgY29udGFpbmluZyB0aGUgd29yZCIpCikKYGBgCgpDb25jbHVzaW9uczoKCiAtIERlY2xpbmUgaW4gInN1a3VwdW9sdGVuIHRhc2EtYXJ2byIgaW4gU1RUIGZvciBkb21lc3RpYyBuZXdzIGlzIGludGVyZXN0aW5nLiBXaGF0IGNvdWxkIGNhdXNlIHRoaXM/CiAtIE90aGVyd2lzZSwgYWxsIHNvdXJjZXMgc2VlbSB0byBiZSBmb2xsb3dpbmcgc2ltaWxhciBwYXR0ZXJucy4KCmBgYHtyfQpzcCAlPiUgCiAgZmlsdGVyKHR5cGU9PSJEb21lc3RpYyBnZW5lcmFsL3BvbGl0aWNhbC9lY29ub21pYyBuZXdzIikgJT4lCiAgZ3JvdXBfYnkocmVmX2NhdGVnb3J5LHR5cGUsdHlwZTIseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9c3VtKGFydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIgJT4lIAogICAgICAgICAgICAgICBncm91cF9ieSh5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgICAgICAgICAgICAgIHN1bW1hcml6ZSh0b3RhbF9hcnRpY2xlcz1zdW0odG90YWxfYXJ0aWNsZXMpLC5ncm91cHM9ImRyb3AiKSAlPiUgY29sbGVjdCgpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9cmVmX2NhdGVnb3J5LGxpbmV0eXBlPXR5cGUyKSkgKwogIGdlb21fc3RlcCgpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpCmBgYAoKQ29uY2x1c2lvbnM6CgogLSBHZW5kZXIgZXF1YWxpdHkgZGlzY3Vzc2lvbiBhbHNvIGdldHMgYSBib29zdCBhZnRlciAyMDE0CiAtIFdoZW4gInloZGVudmVydGFpc3V1cyIgaXMgdXNlZCBpbiByZWxhdGlvbiB0byBnZW5kZXIsICJ0YXNhLWFydm8iIGlzIGFsbW9zdCBhbHdheXMgYWxzbyBtZW50aW9uZWQhCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9Cm15X2QgPC0gY2QyICU+JQogIGZpbHRlcih0eXBlIT0iT3RoZXIiKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciAlPiUgCiAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXJfY3JlYXRlZCx0eXBlKSAlPiUKICAgICAgICAgICAgICAgc3VtbWFyaXplKHRvdGFsX2FydGljbGVzPXN1bSh0b3RhbF9hcnRpY2xlcyksLmdyb3Vwcz0iZHJvcCIpICU+JSBjb2xsZWN0KCkpICU+JSAKICBjb2xsZWN0KCkKCjE6MyAlPiUgbWFwKH4KICBteV9kICU+JSAKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1yZWZfY2F0ZWdvcnkpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5LGNvbG9yPSJyZWQiKSArIAogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTQpKSArCiAgICBmYWNldF9ncmlkX3BhZ2luYXRlKGdlbnVzfnR5cGUyLHNjYWxlcz0iZnJlZSIsbmNvbD00LG5yb3c9MixwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJyZWYtY2F0ZWdvcnkiLGxpbmV0eXBlPSJTaWduYWwiKSArCiAgICB4bGFiKCJZZWFyIikgKwogICAgeWxhYigiUGVyY2VudGFnZSBvZiBhcnRpY2xlcyBvZiB0eXBlIGNvbnRhaW5pbmcgdGhlIHdvcmQiKQopCgoxOjMgJT4lIG1hcCh+ICAKICBteV9kICU+JSAKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1yZWZfY2F0ZWdvcnkpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5LGNvbG9yPSJyZWQiKSArIAogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTQpKSArCiAgICBmYWNldF93cmFwX3BhZ2luYXRlKGdlbnVzfnR5cGUyLHNjYWxlcz0iZnJlZSIsbmNvbD00LG5yb3c9MixwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJyZWYtY2F0ZWdvcnkiLGxpbmV0eXBlPSJTaWduYWwiKSArCiAgICB4bGFiKCJZZWFyIikgKwogICAgeWxhYigiUGVyY2VudGFnZSBvZiBhcnRpY2xlcyBvZiB0eXBlIGNvbnRhaW5pbmcgdGhlIHdvcmQiKQopCmBgYAoKQ29uY2x1c2lvbnM6CgotIFNhbWUgYmVoYXZpb3Igc2VlbiBmb3IgInN1a3VwdW9sdGVuIHRhc2EtYXJ2by95aGRlbnZlcnRhaXN1dXMiIGlzIGFsc28gZXZpZGVudCB3aGVuIGxvb2tpbmcgYXQgZXhwbGljaXRseSBnZW5kZXJlZCB3b3JkcyAobWllcy9uYWluZW4pCgojIyBTdWJqZWN0IHRvcGljCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CjE6MyAlPiUgbWFwKH4KICBjZCAlPiUgCiAgICBmaWx0ZXIodHlwZSE9Ik90aGVyIikgJT4lCiAgICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJldG5vcyIsInBvdGlsYXMiLCJzZWtzdWFhbGlzdXVzIiwidHnDtnN1aGRlIiwibWFhaGFubXV1dHRvIikpICU+JQogICAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIgJT4lIAogICAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXJfY3JlYXRlZCx0eXBlKSAlPiUKICAgICAgICAgICAgICAgICBzdW1tYXJpemUodG90YWxfYXJ0aWNsZXM9c3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lIGNvbGxlY3QoKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT00KSkgKwogICAgZmFjZXRfZ3JpZF9wYWdpbmF0ZShyZWZfY2F0ZWdvcnl+dHlwZTIsc2NhbGVzPSJmcmVlIixucm93PTIsbmNvbD00LHBhZ2U9LngpCikKCjE6MyAlPiUgbWFwKH4gCiAgY2QgJT4lIAogICAgZmlsdGVyKHR5cGUhPSJPdGhlciIpICU+JQogICAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICAgIGlubmVyX2pvaW4oYXJ0aWNsZXNfYnlfdHlwZV9ieV95ZWFyICU+JSAKICAgICAgICAgICAgICAgICBncm91cF9ieSh5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgICAgICAgICAgICAgICAgc3VtbWFyaXplKHRvdGFsX2FydGljbGVzPXN1bSh0b3RhbF9hcnRpY2xlcyksLmdyb3Vwcz0iZHJvcCIpICU+JSBjb2xsZWN0KCkpICU+JQogICAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PWFydGljbGVzL3RvdGFsX2FydGljbGVzLGNvbG9yPWNhdGVnb3J5KSkgKwogICAgZ2VvbV9zdGVwKCkgKwogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9NCkpICsKICAgIGZhY2V0X3dyYXBfcGFnaW5hdGUocmVmX2NhdGVnb3J5fnR5cGUyLHNjYWxlcz0iZnJlZSIsbnJvdz0yLG5jb2w9NCxwYWdlPS54KQopCmBgYAoKQ29uY2x1c2lvbnM6CgogLSBUaGVyZSBkb24ndCBzZWVtIHRvIGJlIG1ham9yIGRpc2Nlcm5pYmxlIHBhdHRlcm5zIGJldHdlZW4gZGlmZmVyZW50IHN1YmplY3RzIGZvciBlcXVhbGl0eQoKIyMgU3VwcG9ydGluZyBhdXhpbGlhcnkgYW5hbHlzZXMKCiMjIyBTdWJqZWN0IHRvcGljIGdyYXBocyB1c2luZyBkaWZmZXJlbnQgbWVhc3VyZXMKCmBgYHtyfQpjZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9ZGF5cyxjb2xvcj1jYXRlZ29yeSkpICsKICAgIGdlb21fbGluZSgpICsKICAgIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTIpKSArCiAgICBmYWNldF93cmFwKH50eXBlMixzY2FsZXM9ImZyZWUiKSArCiAgICBnZ3RpdGxlKC55WzFdJHJlZl9jYXRlZ29yeSkpCgpjZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9d2Vla3MsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT0yKSkgKwogICAgZmFjZXRfd3JhcCh+dHlwZTIsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQoKY2QgJT4lIAogIGZpbHRlcihjYXRlZ29yeSAlaW4lIGMoImV0bm9zIiwicG90aWxhcyIsInNla3N1YWFsaXN1dXMiLCJ0ecO2c3VoZGUiLCJtYWFoYW5tdXV0dG8iKSkgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIgJT4lIAogICAgICAgICAgICAgICBncm91cF9ieSh5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgICAgICAgICAgICAgIHN1bW1hcml6ZSh0b3RhbF9hcnRpY2xlcz1zdW0odG90YWxfYXJ0aWNsZXMpLC5ncm91cHM9ImRyb3AiKSAlPiUgY29sbGVjdCgpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT0yKSkgKwogICAgZmFjZXRfd3JhcCh+dHlwZTIsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQpgYGAKCiMjIyBEbyB0aGUgc3ViamVjdCB0b3BpY3MgY29tYmluZWQgY2FwdHVyZSB0aGUgcGhlbm9tZW5vbj8KCmBgYHtyfQpjZDMgPC0geXZfdGFfcGFyYWdyYXBocyAlPiUKICBpbm5lcl9qb2luKGNvcnB1c19vZl9pbnRlcmVzdCkgJT4lCiAgZmlsdGVyKGxlbW1hIT0ic3VvbWFsYWluZW4iKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzICU+JSBzZWxlY3QoYV9pZCxkYXRlX2NyZWF0ZWQsbWVkaWEpKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKGNhdGVnb3J5PSJwb3RpbGFzIikgJT4lCiAgZ3JvdXBfYnkocmVmX2NhdGVnb3J5LGNhdGVnb3J5LHR5cGUseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSx3ZWVrcz1uX2Rpc3RpbmN0KHdlZWtfY3JlYXRlZCksZGF5cz1uX2Rpc3RpbmN0KGRhdGVfY3JlYXRlZCksLmdyb3Vwcz0iZHJvcCIpICU+JSAKICBjb2xsZWN0KCkKCmNkMyAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICBtdXRhdGUodHlwZT1mY3RfcmVsZXZlbCh0eXBlLCJmb3JlaWduIiwic3BvcnRzIiwib3RoZXIiLGFmdGVyPUluZikpICU+JQogIGdyb3VwX2J5KHJlZl9jYXRlZ29yeSkgJT4lCiAgZ3JvdXBfbWFwKH4ueCAlPiUKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1kYXlzLGNvbG9yPWNhdGVnb3J5KSkgKwogICAgZ2VvbV9saW5lKCkgKwogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpICsKICAgIGZhY2V0X3dyYXAofnR5cGUsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQoKY2QzICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJldG5vcyIsInBvdGlsYXMiLCJzZWtzdWFhbGlzdXVzIiwidHnDtnN1aGRlIiwibWFhaGFubXV1dHRvIikpICU+JQogIG11dGF0ZSh0eXBlPWZjdF9yZWxldmVsKHR5cGUsImZvcmVpZ24iLCJzcG9ydHMiLCJvdGhlciIsYWZ0ZXI9SW5mKSkgJT4lCiAgZ3JvdXBfYnkocmVmX2NhdGVnb3J5KSAlPiUKICBncm91cF9tYXAofi54ICU+JQogICAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PXdlZWtzLGNvbG9yPWNhdGVnb3J5KSkgKwogICAgZ2VvbV9saW5lKCkgKwogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpICsKICAgIGZhY2V0X3dyYXAofnR5cGUsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQoKY2QzICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJldG5vcyIsInBvdGlsYXMiLCJzZWtzdWFhbGlzdXVzIiwidHnDtnN1aGRlIiwibWFhaGFubXV1dHRvIikpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXNfYnlfdHlwZV9ieV95ZWFyICU+JSAKICAgICAgICAgICAgICAgZ3JvdXBfYnkoeWVhcl9jcmVhdGVkLHR5cGUpICU+JQogICAgICAgICAgICAgICBzdW1tYXJpemUodG90YWxfYXJ0aWNsZXM9c3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lIGNvbGxlY3QoKSkgJT4lCiAgbXV0YXRlKHR5cGU9ZmN0X3JlbGV2ZWwodHlwZSwiZm9yZWlnbiIsInNwb3J0cyIsIm90aGVyIixhZnRlcj1JbmYpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT0yKSkgKwogICAgZmFjZXRfd3JhcCh+dHlwZSxzY2FsZXM9ImZyZWUiKSArCiAgICBnZ3RpdGxlKC55WzFdJHJlZl9jYXRlZ29yeSkpCmBgYAoKQ29uY2x1c2lvbnM6CgogLSBXaGlsZSB3ZSBzYXcgbm8gZGlzY2VybmlibGUgcGF0dGVybnMgYmV0d2VlbiBzdWJqZWN0cywgd2UgZG8gc2VlbSB0byBiZSBjYXB0dXJpbmcgdGhlICJ3aG9sZSIgb2YgZXF1YWxpdHkgZGlzY3Vzc2lvbiBieSB0YXJnZXRpbmcgdGhlbSAtPiBjYW4gY29uY2x1ZGUgdGhhdCBldmVyeW9uZSBiZW5lZml0cy4KCiMgQmFja2dyb3VuZCBBbmFseXNlcwoKYGBge3J9CmFydGljbGVzICU+JSAKICBpbm5lcl9qb2luKGFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGdyb3VwX2J5KG1lZGlhLHJlZl9jYXRlZ29yeSx0eXBlLHllYXJfY3JlYXRlZCkgJT4lCiAgc3VtbWFyaXplKGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksd2Vla3M9bl9kaXN0aW5jdCh3ZWVrX2NyZWF0ZWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9ZGF5cyxjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTIpKSArCiAgZmFjZXRfZ3JpZChyZWZfY2F0ZWdvcnl+dHlwZSxzY2FsZXM9ImZyZWUiKQoKYXJ0aWNsZXMgJT4lIAogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZV90eXBlcykgJT4lCiAgbXV0YXRlKHllYXJfY3JlYXRlZD15ZWFyKGRhdGVfY3JlYXRlZCksd2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgZ3JvdXBfYnkobWVkaWEscmVmX2NhdGVnb3J5LHR5cGUseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSx3ZWVrcz1uX2Rpc3RpbmN0KHdlZWtfY3JlYXRlZCksZGF5cz1uX2Rpc3RpbmN0KGRhdGVfY3JlYXRlZCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT13ZWVrcyxjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTIpKSArCiAgZmFjZXRfZ3JpZChyZWZfY2F0ZWdvcnl+dHlwZSxzY2FsZXM9ImZyZWUiKQoKYXJ0aWNsZXMgJT4lIAogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZV90eXBlcykgJT4lCiAgbXV0YXRlKHllYXJfY3JlYXRlZD15ZWFyKGRhdGVfY3JlYXRlZCksd2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgZ3JvdXBfYnkobWVkaWEscmVmX2NhdGVnb3J5LHR5cGUseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSxkYXlzPW5fZGlzdGluY3QoZGF0ZV9jcmVhdGVkKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIpICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTAuMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpICsKICBmYWNldF9ncmlkKHJlZl9jYXRlZ29yeX50eXBlLHNjYWxlcz0iZnJlZSIpCmBgYAoKIyBBdXhpbGlhcnkgYmFja2dyb3VuZCBhbmFseXNlcwoKYGBge3J9CmFydGljbGVzICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLG1vbnRoX2NyZWF0ZWQ9bW9udGgoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgY291bnQobWVkaWEseWVhcl9jcmVhdGVkLG1vbnRoX2NyZWF0ZWQpICU+JQogIGdncGxvdChhZXMoeD1hcy5EYXRlKHN0cl9jKHllYXJfY3JlYXRlZCwnLScsbW9udGhfY3JlYXRlZCwnLTAxJykpLHk9bixjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpCmBgYAoKYGBge3J9CmFydGljbGVzICU+JSAKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBjb3VudChtZWRpYSx5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PW4sY29sb3I9dHlwZSkpICsKICBnZW9tX3N0ZXAoKSArCiAgZmFjZXRfd3JhcCh+bWVkaWEsc2NhbGVzPSJmcmVlIikgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKQpgYGAKCmBgYHtyfQphcnRpY2xlcyAlPiUgCiAgaW5uZXJfam9pbihhcnRpY2xlX3R5cGVzKSAlPiUKICBtdXRhdGUoeWVhcl9jcmVhdGVkPXllYXIoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKGZyb21fc3R0PWF1dGhvcj09IlNUVCIpICU+JQogIGZpbHRlcihtZWRpYT09IklMIikgJT4lCiAgY291bnQobWVkaWEseWVhcl9jcmVhdGVkLHR5cGUsZnJvbV9zdHQpICU+JQogIGNvbGxlY3QoKSAlPiUKICBncm91cF9ieShtZWRpYSkgJT4lCiAgbXV0YXRlKHR5cGU9ZmN0X2x1bXBfbih0eXBlLDExLHc9bikpICU+JQogIGNvdW50KG1lZGlhLHllYXJfY3JlYXRlZCx0eXBlLGZyb21fc3R0LHd0PW4pICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1uLGNvbG9yPWZyb21fc3R0PT0xKSkgKwogIGdlb21fc3RlcCgpICsKICBmYWNldF93cmFwKHR5cGV+bWVkaWEsc2NhbGVzPSJmcmVlIikgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKQpgYGAK