Tidy Tuesday week 34 Star Trek Voice Commands, data from SpeechInteraction.org.

# Load libraries
library(tidyverse)
library(colorspace)
library(patchwork)
library(ggmosaic)
library(ggpubr)
library(ggparallel)
library(ggdist)
library(glue)
library(ggsci)
library(ggparallel)
library(scales)

options(dplyr.summarise.inform = FALSE)
# Import data
computer <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-08-17/computer.csv')

── Column specification ───────────────────────────────────────────────────────────────────────────────
cols(
  name = col_double(),
  char = col_character(),
  line = col_character(),
  direction = col_character(),
  type = col_character(),
  pri_type = col_character(),
  domain = col_character(),
  sub_domain = col_character(),
  nv_resp = col_logical(),
  interaction = col_character(),
  char_type = col_character(),
  is_fed = col_logical(),
  error = col_logical(),
  value_id = col_double()
)
# Missing data
colSums(is.na(computer))
       name        char        line   direction        type    pri_type      domain  sub_domain 
          0           0           0        1167           0           0         252         754 
    nv_resp interaction   char_type      is_fed       error    value_id 
          0           0           0           0           0           0 
# variable unique value count 
computer %>% summarise_all(n_distinct)

Character type, interaction type, domain

# combine plot
ggarrange(p4,p5, ncol=1)

ALT text: Bar plot showing the count of interaction type by character type (human and computer) where the highest interaction type for computer is response and person is command. Mosaic plot showing the domain of interaction by computer and person, where human have higher proportions than computer across domains, with the exception of the emergency domain.

Word count

theme_set(theme_minimal(base_size = 10))
theme_update(plot.margin=unit(c(.5,.5,.5,.5),"cm"),
             plot.title.position="plot",
             panel.grid=element_line(size=.2))
# top 4 domains 
d = computer %>% filter(!is.na(domain)) %>% count(domain, sort=T) %>% slice(1:4)

c1 = computer %>% mutate(word_count = str_count(computer$interaction, "\\w+")) %>%
  filter(domain %in% d$domain) %>%
  filter(!is.na(domain)) 

# stat df
stat = c1 %>%
  group_by(domain,char_type) %>%
  summarise(median = median(word_count),
            max=max(word_count),
            n=n())

# plot
computer %>% mutate(word_count = str_count(computer$interaction, "\\w+")) %>%
  filter(domain %in% d$domain) %>%
  filter(!is.na(domain)) %>%
  ggplot(aes(x=char_type, y=word_count, fill=char_type)) + 
  #stat_interval(show.legend=F)+
  stat_halfeye(alpha=0.8) + 
  geom_text(data=stat, aes(y=median, x=char_type, label=median), color="white",
                           fontface="bold", size=3, nudge_x=.2) +
  geom_text(data=stat, aes(y=max, x=char_type, label = glue::glue("n = {n}"), color=char_type), 
                          size=2.5, nudge_x=.2)+
  coord_flip() + 
  scale_fill_aaas() + 
  scale_color_aaas() +
  facet_wrap(~domain, ncol=2, labeller = label_both) + 
  scale_y_continuous(breaks=seq(0,50,10)) +
  theme(legend.position = "none",
        panel.grid.major.y=element_blank(),
        panel.grid.minor.x=element_blank(),
        axis.title=element_blank(),
        axis.text.x=element_text(size=7)) + 
  labs(title="Word count by interaction domain and character type")

Character type and domain parallel plot

# parallel plot
dfc=as.data.frame(computer %>%
                    drop_na(domain) %>% 
                    mutate(domain= str_to_title(domain),
                           domain=fct_lump(domain,4)))
ggparallel(list('domain','char_type'), data=dfc, label=T, text.angle=0, label.size=3.2) + 
  #geom_text(aes(label=dfc$domain)) +
  scale_fill_aaas()+ 
  scale_color_aaas() + 
  scale_x_discrete(label=c("Domain","Character Type"), expand=c(0,0)) +
  theme(axis.text=element_blank(),
        axis.text.y=element_text(size=9, margin=margin(r=-10)),
        axis.title=element_blank(),
        panel.grid.major.x=element_blank(),
        panel.grid.minor.x=element_blank(),
        legend.position = "none") + 
  coord_flip() + 
  labs(title="Character type and interaction domain\n")

Proportion of character type by sub domain

# y axis labels
lab1 = computer %>% 
  drop_na(sub_domain) %>% 
  mutate(sub_domain= ifelse(sub_domain=="Holodeck?","Holodeck",sub_domain)) %>%
  count(sub_domain, sort=T) %>%
  mutate(sub_domain=fct_rev(fct_inorder(sub_domain)),
         label=paste0("<b>",sub_domain,"</b>"," ","(n=",n,")"))

# plot
computer %>% 
  drop_na(sub_domain) %>%
  mutate(sub_domain= ifelse(sub_domain=="Holodeck?","Holodeck",sub_domain)) %>%
  group_by(sub_domain, char_type) %>%
  tally() %>%
  mutate(prop=n/sum(n),
         col=ifelse(lead(n)>n,"Person > Computer","Computer > Person"),
         col=ifelse(is.na(col),"Computer > Person","Person > Computer")) %>%
  ggplot(aes(y=reorder(sub_domain,n), x=prop)) + 
  geom_line(aes(group=sub_domain, color=col)) +
  geom_point(aes(shape=char_type), size=2.2)+ 
  scale_y_discrete(labels=rev(lab1$label)) + 
  scale_shape_manual(values=c(1,19)) + 
  scale_color_manual(values=c("#3366CC","#AD722C")) + 
  scale_x_continuous(limits=c(0,1.05), label=scales::percent_format(), expand=c(0,0)) +
  theme(legend.position = "top",
        legend.justification = "left",
        panel.grid.minor=element_blank(),
        axis.title=element_text(size=8.5),
        axis.text.y=element_markdown(),
        plot.margin=unit(c(.5,1.5,.5,.5),"cm")
        ) + 
  guides(col = guide_legend(order = 2),shape = guide_legend(order = 1)) + 
  labs(color="", shape="",
       x="Proportion",y="Sub Domain",
       title= "Proportion of character type by interaction sub domain") 

LS0tCnRpdGxlOiAiVGlkeSBUdWVzZGF5IFdlZWsgMzQvMjAyMSIKZGF0ZTogIjIwMjEvMDgvMTciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCltUaWR5IFR1ZXNkYXldKGh0dHBzOi8vZ2l0aHViLmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkpIHdlZWsgMzQKW1N0YXIgVHJlayBWb2ljZSBDb21tYW5kc10oaHR0cHM6Ly9naXRodWIuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9ibG9iL21hc3Rlci9kYXRhLzIwMjEvMjAyMS0wOC0xNy9yZWFkbWUubWQpLCBkYXRhIGZyb20gW1NwZWVjaEludGVyYWN0aW9uLm9yZ10oaHR0cDovL3d3dy5zcGVlY2hpbnRlcmFjdGlvbi5vcmcvVE5HLykuCgoKYGBge3J9CiMgTG9hZCBsaWJyYXJpZXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY29sb3JzcGFjZSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZ2dtb3NhaWMpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGdncGFyYWxsZWwpCmxpYnJhcnkoZ2dkaXN0KQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoZ2dzY2kpCmxpYnJhcnkoZ2dwYXJhbGxlbCkKbGlicmFyeShzY2FsZXMpCgpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSkKYGBgCgpgYGB7cn0KIyBJbXBvcnQgZGF0YQpjb21wdXRlciA8LSByZWFkcjo6cmVhZF9jc3YoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvbWFzdGVyL2RhdGEvMjAyMS8yMDIxLTA4LTE3L2NvbXB1dGVyLmNzdicpCmBgYAoKYGBge3J9CiMgTWlzc2luZyBkYXRhCmNvbFN1bXMoaXMubmEoY29tcHV0ZXIpKQpgYGAKCmBgYHtyfQojIHZhcmlhYmxlIHVuaXF1ZSB2YWx1ZSBjb3VudCAKY29tcHV0ZXIgJT4lIHN1bW1hcmlzZV9hbGwobl9kaXN0aW5jdCkKYGBgCgojIyMgQ2hhcmFjdGVyIHR5cGUsIGludGVyYWN0aW9uIHR5cGUsIGRvbWFpbgoqIHNoYXJlZCBvbiBbVHdpdHRlcl0oaHR0cHM6Ly90d2l0dGVyLmNvbS9sZWVvbG5leTMvc3RhdHVzLzE0Mjc1NDE5NzE2NzgyMTIxMTIpCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTApKQp0aGVtZV91cGRhdGUocGFuZWwuZ3JpZD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICB0ZXh0PWVsZW1lbnRfdGV4dChmYW1pbHk9Im1vbm8iKSwKICAgICAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTksIG1hcmdpbj1tYXJnaW4ocj01KSwgZmFtaWx5PSJtb25vIiksCiAgICAgICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF9tYXJrZG93bihzaXplPTE2KSwKICAgICAgICAgICAgIHBsb3Quc3VidGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTAsIG1hcmdpbj1tYXJnaW4odD0tMywgYj0tMykpKQoKIyBiYXIgcGxvdApwMSA9IGNvbXB1dGVyICU+JSAKICBtdXRhdGUodHlwZT1zdHJfdG9fdGl0bGUodHlwZSkpICU+JQogIGZpbHRlcihjaGFyX3R5cGU9PSJDb21wdXRlciIpICU+JQogIGNvdW50KGNoYXJfdHlwZSwgdHlwZSwgc29ydD1UKSAlPiUKICBtdXRhdGUodHlwZT1mY3RfcmV2KGZjdF9pbm9yZGVyKHR5cGUpKSkgJT4lCiAgZ2dwbG90KGFlcyh4PW4sIHk9dHlwZSwgZmlsbD1uKSkgKyAKICBnZW9tX2NvbCh3aWR0aD0uNSwgc2hvdy5sZWdlbmQgPSBGKSArIAogIGdlb21fdGV4dChhZXMobGFiZWw9biksIGhqdXN0PS0wLjMsIHNpemU9Mi43LCBmYW1pbHk9Im1vbm8iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1jKDAsNTgwKSwgZXhwYW5kPWMoMCwwKSkgKyAKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlPSJIYXdhaWkiKSArIAogIGxhYnMoc3VidGl0bGU9IkNvbXB1dGVyIikKCnAyID0gY29tcHV0ZXIgJT4lIAogIG11dGF0ZSh0eXBlPXN0cl90b190aXRsZSh0eXBlKSkgJT4lCiAgZmlsdGVyKGNoYXJfdHlwZT09IlBlcnNvbiIpICU+JQogIGNvdW50KGNoYXJfdHlwZSwgdHlwZSwgc29ydD1UKSAlPiUKICBtdXRhdGUodHlwZT1mY3RfcmV2KGZjdF9pbm9yZGVyKHR5cGUpKSkgJT4lCiAgZ2dwbG90KGFlcyh4PW4sIHk9dHlwZSwgZmlsbD1uKSkgKyAKICBnZW9tX2NvbCh3aWR0aD0uNSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1uKSwgaGp1c3Q9LTAuMywgc2l6ZT0yLjcsIGZhbWlseT0ibW9ubyIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzPWMoMCw1ODApLCBleHBhbmQ9YygwLDApKSArIAogIHNjYWxlX2ZpbGxfY29udGludW91c19zZXF1ZW50aWFsKHBhbGV0dGU9IkJhdGxvdyIpICsgCiAgbGFicyhzdWJ0aXRsZT0iUGVyc29uIikKCnAzID0gcDF8cDIgCnA0ID0gcDMgKyBwbG90X2Fubm90YXRpb24oCiAgdGl0bGUgPSAiPGI+U3RhciBUcmVrIENvbW1hbmRzPGI+PGJyPjxicj48c3BhbiBzdHlsZSA9ICdjb2xvcjojNDk1MDU3OyBmb250LXNpemU6MTFwdCc+SW50ZXJhY3Rpb24gdHlwZSBjb3VudCBieSBDb21wdXRlciBhbmQgUGVyc29uPC9zcGFuPiIsCiAgKSAmIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF9tYXJrZG93bihoanVzdD0wLjUpLHBsb3QubWFyZ2luPXVuaXQoYygwLjgsMC41LDAuNSwwLjUpLCJjbSIpKQoKIyBtb3NpYWMgcGxvdApwNSA9IGNvbXB1dGVyICU+JSAKICBtdXRhdGUoZG9tYWluPSBzdHJfdG9fdGl0bGUoZG9tYWluKSkgJT4lCiAgZmlsdGVyKCFpcy5uYShkb21haW4pKSAlPiUKICNjb3VudChjaGFyX3R5cGUsIGRvbWFpbikgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX21vc2FpYyhhZXMoeD1wcm9kdWN0KGNoYXJfdHlwZSxkb21haW4pLCBmaWxsPWNoYXJfdHlwZSksc2l6ZT0wLjcpICsgCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMmI1M2E3IiwiI2MxYzczMCIpKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICB0ZXh0PWVsZW1lbnRfdGV4dChmYW1pbHk9Im1vbm8iKSwKICAgICAgICBwYW5lbC5ncmlkPWVsZW1lbnRfbGluZShzaXplPS4zKSwKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiLAogICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSwgZmFjZT0iYm9sZCIpLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X21hcmtkb3duKGhqdXN0PTAuNSksCiAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAsMC41LDAuNSwwLjUpLCJjbSIpLAogICAgICAgIHBsb3QuY2FwdGlvbj1lbGVtZW50X3RleHQoc2l6ZT03LjUpLAogICAgICAgICkgKwogIGxhYnMoc3VidGl0bGU9IkRvbWFpbiBvZiBpbnRlcmFjdGlvbiBieSA8c3BhbiBzdHlsZSA9ICdjb2xvcjojMmI1M2E3Jz48Yj5Db21wdXRlcjwvYj48L3NwYW4+IGFuZCA8c3BhbiBzdHlsZSA9ICdjb2xvcjojYzFjNzMwJz48Yj5QZXJzb248L2I+PC9zcGFuPiIsCiAgICAgICBjYXB0aW9uID0gIlxuI1RpZHlUdWVzZGF5IFdlZWsgMzQgfCBEYXRhIGZyb20gU3BlZWNoSW50ZXJhY3Rpb24ub3JnIikKYGBgCgoKYGBge3IsZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NH0KIyBjb21iaW5lIHBsb3QKZ2dhcnJhbmdlKHA0LHA1LCBuY29sPTEpCmBgYAoKQUxUIHRleHQ6IEJhciBwbG90IHNob3dpbmcgdGhlIGNvdW50IG9mIGludGVyYWN0aW9uIHR5cGUgYnkgY2hhcmFjdGVyIHR5cGUgKGh1bWFuIGFuZCBjb21wdXRlcikgd2hlcmUgdGhlIGhpZ2hlc3QgaW50ZXJhY3Rpb24gdHlwZSBmb3IgY29tcHV0ZXIgaXMgcmVzcG9uc2UgYW5kIHBlcnNvbiBpcyBjb21tYW5kLiBNb3NhaWMgcGxvdCBzaG93aW5nIHRoZSBkb21haW4gb2YgaW50ZXJhY3Rpb24gYnkgY29tcHV0ZXIgYW5kIHBlcnNvbiwgd2hlcmUgaHVtYW4gaGF2ZSBoaWdoZXIgcHJvcG9ydGlvbnMgdGhhbiBjb21wdXRlciBhY3Jvc3MgZG9tYWlucywgd2l0aCB0aGUgZXhjZXB0aW9uIG9mIHRoZSBlbWVyZ2VuY3kgZG9tYWluLiAKCiMjIyBXb3JkIGNvdW50CgpgYGB7cn0KdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTApKQp0aGVtZV91cGRhdGUocGxvdC5tYXJnaW49dW5pdChjKC41LC41LC41LC41KSwiY20iKSwKICAgICAgICAgICAgIHBsb3QudGl0bGUucG9zaXRpb249InBsb3QiLAogICAgICAgICAgICAgcGFuZWwuZ3JpZD1lbGVtZW50X2xpbmUoc2l6ZT0uMikpCmBgYAoKYGBge3J9CiMgdG9wIDQgZG9tYWlucyAKZCA9IGNvbXB1dGVyICU+JSBmaWx0ZXIoIWlzLm5hKGRvbWFpbikpICU+JSBjb3VudChkb21haW4sIHNvcnQ9VCkgJT4lIHNsaWNlKDE6NCkKCmMxID0gY29tcHV0ZXIgJT4lIG11dGF0ZSh3b3JkX2NvdW50ID0gc3RyX2NvdW50KGNvbXB1dGVyJGludGVyYWN0aW9uLCAiXFx3KyIpKSAlPiUKICBmaWx0ZXIoZG9tYWluICVpbiUgZCRkb21haW4pICU+JQogIGZpbHRlcighaXMubmEoZG9tYWluKSkgCgojIHN0YXQgZGYKc3RhdCA9IGMxICU+JQogIGdyb3VwX2J5KGRvbWFpbixjaGFyX3R5cGUpICU+JQogIHN1bW1hcmlzZShtZWRpYW4gPSBtZWRpYW4od29yZF9jb3VudCksCiAgICAgICAgICAgIG1heD1tYXgod29yZF9jb3VudCksCiAgICAgICAgICAgIG49bigpKQoKIyBwbG90CmNvbXB1dGVyICU+JSBtdXRhdGUod29yZF9jb3VudCA9IHN0cl9jb3VudChjb21wdXRlciRpbnRlcmFjdGlvbiwgIlxcdysiKSkgJT4lCiAgZmlsdGVyKGRvbWFpbiAlaW4lIGQkZG9tYWluKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGRvbWFpbikpICU+JQogIGdncGxvdChhZXMoeD1jaGFyX3R5cGUsIHk9d29yZF9jb3VudCwgZmlsbD1jaGFyX3R5cGUpKSArIAogICNzdGF0X2ludGVydmFsKHNob3cubGVnZW5kPUYpKwogIHN0YXRfaGFsZmV5ZShhbHBoYT0wLjgpICsgCiAgZ2VvbV90ZXh0KGRhdGE9c3RhdCwgYWVzKHk9bWVkaWFuLCB4PWNoYXJfdHlwZSwgbGFiZWw9bWVkaWFuKSwgY29sb3I9IndoaXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udGZhY2U9ImJvbGQiLCBzaXplPTMsIG51ZGdlX3g9LjIpICsKICBnZW9tX3RleHQoZGF0YT1zdGF0LCBhZXMoeT1tYXgsIHg9Y2hhcl90eXBlLCBsYWJlbCA9IGdsdWU6OmdsdWUoIm4gPSB7bn0iKSwgY29sb3I9Y2hhcl90eXBlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT0yLjUsIG51ZGdlX3g9LjIpKwogIGNvb3JkX2ZsaXAoKSArIAogIHNjYWxlX2ZpbGxfYWFhcygpICsgCiAgc2NhbGVfY29sb3JfYWFhcygpICsKICBmYWNldF93cmFwKH5kb21haW4sIG5jb2w9MiwgbGFiZWxsZXIgPSBsYWJlbF9ib3RoKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsNTAsMTApKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT03KSkgKyAKICBsYWJzKHRpdGxlPSJXb3JkIGNvdW50IGJ5IGludGVyYWN0aW9uIGRvbWFpbiBhbmQgY2hhcmFjdGVyIHR5cGUiKQoKYGBgCgojIyMgQ2hhcmFjdGVyIHR5cGUgYW5kIGRvbWFpbiBwYXJhbGxlbCBwbG90CgpgYGB7ciwgbWVzc2FnZT1GfQojIHBhcmFsbGVsIHBsb3QKZGZjPWFzLmRhdGEuZnJhbWUoY29tcHV0ZXIgJT4lCiAgICAgICAgICAgICAgICAgICAgZHJvcF9uYShkb21haW4pICU+JSAKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZG9tYWluPSBzdHJfdG9fdGl0bGUoZG9tYWluKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluPWZjdF9sdW1wKGRvbWFpbiw0KSkpCmdncGFyYWxsZWwobGlzdCgnZG9tYWluJywnY2hhcl90eXBlJyksIGRhdGE9ZGZjLCBsYWJlbD1ULCB0ZXh0LmFuZ2xlPTAsIGxhYmVsLnNpemU9My4yKSArIAogICNnZW9tX3RleHQoYWVzKGxhYmVsPWRmYyRkb21haW4pKSArCiAgc2NhbGVfZmlsbF9hYWFzKCkrIAogIHNjYWxlX2NvbG9yX2FhYXMoKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWw9YygiRG9tYWluIiwiQ2hhcmFjdGVyIFR5cGUiKSwgZXhwYW5kPWMoMCwwKSkgKwogIHRoZW1lKGF4aXMudGV4dD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9OSwgbWFyZ2luPW1hcmdpbihyPS0xMCkpLAogICAgICAgIGF4aXMudGl0bGU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgCiAgY29vcmRfZmxpcCgpICsgCiAgbGFicyh0aXRsZT0iQ2hhcmFjdGVyIHR5cGUgYW5kIGludGVyYWN0aW9uIGRvbWFpblxuIikKYGBgCgoKCiMjIyBQcm9wb3J0aW9uIG9mIGNoYXJhY3RlciB0eXBlIGJ5IHN1YiBkb21haW4KCmBgYHtyfQojIHkgYXhpcyBsYWJlbHMKbGFiMSA9IGNvbXB1dGVyICU+JSAKICBkcm9wX25hKHN1Yl9kb21haW4pICU+JSAKICBtdXRhdGUoc3ViX2RvbWFpbj0gaWZlbHNlKHN1Yl9kb21haW49PSJIb2xvZGVjaz8iLCJIb2xvZGVjayIsc3ViX2RvbWFpbikpICU+JQogIGNvdW50KHN1Yl9kb21haW4sIHNvcnQ9VCkgJT4lCiAgbXV0YXRlKHN1Yl9kb21haW49ZmN0X3JldihmY3RfaW5vcmRlcihzdWJfZG9tYWluKSksCiAgICAgICAgIGxhYmVsPXBhc3RlMCgiPGI+IixzdWJfZG9tYWluLCI8L2I+IiwiICIsIihuPSIsbiwiKSIpKQoKIyBwbG90CmNvbXB1dGVyICU+JSAKICBkcm9wX25hKHN1Yl9kb21haW4pICU+JQogIG11dGF0ZShzdWJfZG9tYWluPSBpZmVsc2Uoc3ViX2RvbWFpbj09IkhvbG9kZWNrPyIsIkhvbG9kZWNrIixzdWJfZG9tYWluKSkgJT4lCiAgZ3JvdXBfYnkoc3ViX2RvbWFpbiwgY2hhcl90eXBlKSAlPiUKICB0YWxseSgpICU+JQogIG11dGF0ZShwcm9wPW4vc3VtKG4pLAogICAgICAgICBjb2w9aWZlbHNlKGxlYWQobik+biwiUGVyc29uID4gQ29tcHV0ZXIiLCJDb21wdXRlciA+IFBlcnNvbiIpLAogICAgICAgICBjb2w9aWZlbHNlKGlzLm5hKGNvbCksIkNvbXB1dGVyID4gUGVyc29uIiwiUGVyc29uID4gQ29tcHV0ZXIiKSkgJT4lCiAgZ2dwbG90KGFlcyh5PXJlb3JkZXIoc3ViX2RvbWFpbixuKSwgeD1wcm9wKSkgKyAKICBnZW9tX2xpbmUoYWVzKGdyb3VwPXN1Yl9kb21haW4sIGNvbG9yPWNvbCkpICsKICBnZW9tX3BvaW50KGFlcyhzaGFwZT1jaGFyX3R5cGUpLCBzaXplPTIuMikrIAogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPXJldihsYWIxJGxhYmVsKSkgKyAKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPWMoMSwxOSkpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjMzM2NkNDIiwiI0FENzIyQyIpKSArIAogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHM9YygwLDEuMDUpLCBsYWJlbD1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksIGV4cGFuZD1jKDAsMCkpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9ICJsZWZ0IiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTguNSksCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9tYXJrZG93bigpLAogICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYyguNSwxLjUsLjUsLjUpLCJjbSIpCiAgICAgICAgKSArIAogIGd1aWRlcyhjb2wgPSBndWlkZV9sZWdlbmQob3JkZXIgPSAyKSxzaGFwZSA9IGd1aWRlX2xlZ2VuZChvcmRlciA9IDEpKSArIAogIGxhYnMoY29sb3I9IiIsIHNoYXBlPSIiLAogICAgICAgeD0iUHJvcG9ydGlvbiIseT0iU3ViIERvbWFpbiIsCiAgICAgICB0aXRsZT0gIlByb3BvcnRpb24gb2YgY2hhcmFjdGVyIHR5cGUgYnkgaW50ZXJhY3Rpb24gc3ViIGRvbWFpbiIpIApgYGAKCgoKCgoKCgo=