Read in relevant files & merge

mcdi <- read.csv("hypernym_analysis-master/wordbank/wordbank-aoa-data.csv") %>% 
  filter(language=="English (American)") %>% 
  select(uni_lemma, words, aoa) %>% 
  rename(aoa_months=aoa, Word=uni_lemma) %>% 
  select(Word)
hypernyms <- read.csv("seedWords_aoa_hypernyms_concreteness_CDI_z.csv") %>% 
  select(-Conc.M, conc_z_pos) %>% 
  rename(num_hypernyms=hypernyms)
concreteness <- read.csv("Concreteness_ratings_Brysbaert_et_al_BRM.txt", sep="") %>% 
  filter(Dom_Pos != 0) %>% 
  select(Word, Conc.M)
hyponyms <- read.csv("AOA/aoa_to_wordnet_with_hyponyms1.csv") %>% 
  rename(Word=wordnet_lemma, pos=wordnet_PoS) %>% 
  select(Word, num_hyponyms, pos)
peers <- read.csv("AOA/aoa_to_wordnet_with_peers.csv") %>% 
  rename(Word=wordnet_lemma, pos=wordnet_PoS) %>% 
  select(Word, num_peers, pos)
subtlex <- read.csv("subtlex_full.txt", sep="")
candidate_words <- left_join(hypernyms, concreteness, by="Word") %>% 
  filter(!(Word %in% mcdi)) %>% 
  left_join(hyponyms, by=c("Word", "pos")) %>% 
  left_join(peers, by=c("Word","pos")) %>%
  group_by(pos) %>% 
  mutate(conc_z_pos = scale(Conc.M)) %>% 
  ungroup() %>% 
  arrange(Word)
head(candidate_words)

Look up childes frequency

candidate_word_list <- candidate_words$Word
#stop doing this every time you need to run this code, it takes forever
#candidate_word_tokens_raw <- get_tokens(collection = "Eng-NA",
                                    #role_exclude = "Target_Child",
                                    #token=candidate_word_list) 
#read csv instead
candidate_word_tokens_raw <- read.csv("candidate_word_tokens_CHILDES.csv")
candidate_word_tokens <- candidate_word_tokens_raw %>% 
  select(gloss, speaker_id, token_order)
  
candidate_word_token_summary <- candidate_word_tokens %>% 
  mutate(gloss = tolower(gloss)) %>%
  filter(gloss %in% candidate_word_list) %>% 
  group_by(gloss) %>%
  summarise(raw_freq_childes=n()) %>% 
  mutate(logFreq_childes=log(raw_freq_childes+1))
weird_words <- filter(candidate_word_token_summary, !(gloss %in% candidate_word_list))
not_in_childes <- filter(candidate_words, !(Word %in% candidate_word_token_summary$gloss))
#df to merge
childes_frequency <- candidate_word_token_summary %>% 
  rename(Word=gloss)
candidate_words_childes <- left_join(candidate_words, childes_frequency, by="Word")

Add subtlex frequency

subtlex_merge <- select(subtlex, Word, FREQcount)
candidate_words_all_freqs <- left_join(candidate_words_childes, subtlex_merge, by="Word") %>% 
  rename(raw_freq_subtlex=FREQcount) %>% 
  mutate(logFreq_subtlex=log(raw_freq_subtlex+1))
#fix num_hyponyms
candidate_words_all_freqs$num_hyponyms <- as.integer(candidate_words_all_freqs$num_hyponyms)

Play around with graphing stuff and correlations

Correlation matrix

candidate_words_corrmatrix <- select(candidate_words_all_freqs, -Word, -pos, -CatName, -MCDI_Cat)
candidate_words_cor <- cor(candidate_words_corrmatrix, use="pairwise.complete.obs", method="pearson")
p.mat_item <- cor.mtest(candidate_words_cor)
pMatrix_item <- p.mat_item$p
corrplot(candidate_words_cor, method = 'color', type='lower', diag = TRUE, addCoef.col = "black",
         tl.col = "black", number.font=2, number.cex=10/ncol(candidate_words_cor), p.mat=pMatrix_item, sig.level = 0.05, insig = "blank")

Look at relations between density & category hierarchy

Hyponyms & Hypernyms

ggplot(candidate_words_all_freqs, aes(num_hypernyms, num_hyponyms, label=as.character(Word)))+
  geom_point()+
  geom_label()+
  theme_classic()

Hypernyms & Peers

ggplot(candidate_words_all_freqs, aes(num_hypernyms, num_peers, label=as.character(Word)))+
  geom_point()+
  #geom_smooth(method="lm")
  geom_label()+
  theme_classic()

#What are those low-hypernym, highly dense words? (they are all verbs - this makes sense)
lowHyper_highPeer <- filter(candidate_words_all_freqs, (num_peers > 300) & (num_hypernyms < 2)) %>% 
  select(Word, pos, aoa, num_peers, num_hyponyms, num_hypernyms, Conc.M,logFreq_childes)
DT::datatable(lowHyper_highPeer)

Hyponyms & Peers

ggplot(candidate_words_all_freqs, aes(num_hyponyms, num_peers, label=as.character(Word)))+
  geom_point()+
  #geom_smooth(method="lm")
  geom_label()+
  scale_x_continuous(breaks=seq(0,120,15))+
  theme_classic()

Compare childes and subtlex frequencies (r = .76)

Points

ggplot(candidate_words_all_freqs, aes(logFreq_childes, logFreq_subtlex))+
  geom_point()+
  geom_smooth(method="lm")+
  theme_classic()

Words

ggplot(candidate_words_all_freqs, aes(logFreq_childes, logFreq_subtlex, label=as.character(Word)))+
  geom_point()+
  geom_label()+
  theme_classic()

Childes frequency vs. concreteness (r = -.2, ns)

Points

ggplot(candidate_words_all_freqs, aes(logFreq_childes, Conc.M))+
  geom_point()+
  geom_smooth(method="lm")+
  theme_classic()

Words

ggplot(candidate_words_all_freqs, aes(logFreq_childes, Conc.M, label=as.character(Word)))+
  geom_point()+
  geom_label()+
  theme_classic()

Childes frequency vs. AOA (r = -.45)

Points

ggplot(candidate_words_all_freqs, aes(logFreq_childes, aoa))+
  geom_point()+
  geom_smooth(method="lm")+
  theme_classic()

Words

ggplot(candidate_words_all_freqs, aes(logFreq_childes, aoa, label=as.character(Word)))+
  geom_point()+
  geom_label()+
  theme_classic()

Childes frequency vs. AOA for lower-than-mean concreteness

Points

ggplot(filter(candidate_words_all_freqs, Conc.M<3.90), aes(logFreq_childes, aoa))+
  geom_point()+
  geom_smooth(method="lm")+
  theme_classic()

Words

ggplot(filter(candidate_words_all_freqs, Conc.M<3.90), aes(logFreq_childes, aoa, label=as.character(Word)))+
  geom_point()+
  geom_label()+
  theme_classic()

What are the low-concreteness (lower than mean), high-frequency (higher than mean), late-aoa (older than 5) words?

hFreq_hAOA_lConc <- filter(candidate_words_all_freqs, (Conc.M < 3.90) & (aoa>5) & (logFreq_childes > 5.41)) %>% 
  select(Word, pos, aoa, num_hypernyms, num_hyponyms, num_peers, Conc.M, logFreq_childes, logFreq_subtlex)
DT::datatable(hFreq_hAOA_lConc)

Some stats

Does concreteness predict AOA, controlling for frequency? (yes)

predAOA <- lm(aoa ~ logFreq_childes + Conc.M, candidate_words_all_freqs)
summary(predAOA)

Call:
lm(formula = aoa ~ logFreq_childes + Conc.M, data = candidate_words_all_freqs)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.53400 -0.40355  0.05828  0.46345  1.36855 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)      6.76833    0.22543  30.025  < 2e-16 ***
logFreq_childes -0.19723    0.02027  -9.728  < 2e-16 ***
Conc.M          -0.19149    0.04408  -4.344  1.9e-05 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.6303 on 307 degrees of freedom
  (9 observations deleted due to missingness)
Multiple R-squared:  0.2465,    Adjusted R-squared:  0.2416 
F-statistic: 50.22 on 2 and 307 DF,  p-value: < 2.2e-16
LS0tDQp0aXRsZTogIkNyZWF0ZSBkZiBvZiBjYW5kaWRhdGUgc2VlZCB3b3JkcyAmIHBva2UgYXQgaXQiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGNoaWxkZXNyKQ0KbGlicmFyeShsbWU0KQ0KbGlicmFyeShjb3JycGxvdCkNCmxpYnJhcnkoZ2dyZXBlbCkNCmxpYnJhcnkocHN5Y2gpDQpgYGANCg0KIyMjIFJlYWQgaW4gcmVsZXZhbnQgZmlsZXMgJiBtZXJnZQ0KYGBge3J9DQptY2RpIDwtIHJlYWQuY3N2KCJoeXBlcm55bV9hbmFseXNpcy1tYXN0ZXIvd29yZGJhbmsvd29yZGJhbmstYW9hLWRhdGEuY3N2IikgJT4lIA0KICBmaWx0ZXIobGFuZ3VhZ2U9PSJFbmdsaXNoIChBbWVyaWNhbikiKSAlPiUgDQogIHNlbGVjdCh1bmlfbGVtbWEsIHdvcmRzLCBhb2EpICU+JSANCiAgcmVuYW1lKGFvYV9tb250aHM9YW9hLCBXb3JkPXVuaV9sZW1tYSkgJT4lIA0KICBzZWxlY3QoV29yZCkNCmh5cGVybnltcyA8LSByZWFkLmNzdigic2VlZFdvcmRzX2FvYV9oeXBlcm55bXNfY29uY3JldGVuZXNzX0NESV96LmNzdiIpICU+JSANCiAgc2VsZWN0KC1Db25jLk0sIGNvbmNfel9wb3MpICU+JSANCiAgcmVuYW1lKG51bV9oeXBlcm55bXM9aHlwZXJueW1zKQ0KY29uY3JldGVuZXNzIDwtIHJlYWQuY3N2KCJDb25jcmV0ZW5lc3NfcmF0aW5nc19CcnlzYmFlcnRfZXRfYWxfQlJNLnR4dCIsIHNlcD0iIikgJT4lIA0KICBmaWx0ZXIoRG9tX1BvcyAhPSAwKSAlPiUgDQogIHNlbGVjdChXb3JkLCBDb25jLk0pDQpoeXBvbnltcyA8LSByZWFkLmNzdigiQU9BL2FvYV90b193b3JkbmV0X3dpdGhfaHlwb255bXMxLmNzdiIpICU+JSANCiAgcmVuYW1lKFdvcmQ9d29yZG5ldF9sZW1tYSwgcG9zPXdvcmRuZXRfUG9TKSAlPiUgDQogIHNlbGVjdChXb3JkLCBudW1faHlwb255bXMsIHBvcykNCnBlZXJzIDwtIHJlYWQuY3N2KCJBT0EvYW9hX3RvX3dvcmRuZXRfd2l0aF9wZWVycy5jc3YiKSAlPiUgDQogIHJlbmFtZShXb3JkPXdvcmRuZXRfbGVtbWEsIHBvcz13b3JkbmV0X1BvUykgJT4lIA0KICBzZWxlY3QoV29yZCwgbnVtX3BlZXJzLCBwb3MpDQpzdWJ0bGV4IDwtIHJlYWQuY3N2KCJzdWJ0bGV4X2Z1bGwudHh0Iiwgc2VwPSIiKQ0KDQpjYW5kaWRhdGVfd29yZHMgPC0gbGVmdF9qb2luKGh5cGVybnltcywgY29uY3JldGVuZXNzLCBieT0iV29yZCIpICU+JSANCiAgZmlsdGVyKCEoV29yZCAlaW4lIG1jZGkpKSAlPiUgDQogIGxlZnRfam9pbihoeXBvbnltcywgYnk9YygiV29yZCIsICJwb3MiKSkgJT4lIA0KICBsZWZ0X2pvaW4ocGVlcnMsIGJ5PWMoIldvcmQiLCJwb3MiKSkgJT4lDQogIGdyb3VwX2J5KHBvcykgJT4lIA0KICBtdXRhdGUoY29uY196X3BvcyA9IHNjYWxlKENvbmMuTSkpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgYXJyYW5nZShXb3JkKQ0KDQpoZWFkKGNhbmRpZGF0ZV93b3JkcykNCmBgYA0KDQojIyMjIExvb2sgdXAgY2hpbGRlcyBmcmVxdWVuY3kNCmBgYHtyfQ0KY2FuZGlkYXRlX3dvcmRfbGlzdCA8LSBjYW5kaWRhdGVfd29yZHMkV29yZA0KDQojc3RvcCBkb2luZyB0aGlzIGV2ZXJ5IHRpbWUgeW91IG5lZWQgdG8gcnVuIHRoaXMgY29kZSwgaXQgdGFrZXMgZm9yZXZlcg0KI2NhbmRpZGF0ZV93b3JkX3Rva2Vuc19yYXcgPC0gZ2V0X3Rva2Vucyhjb2xsZWN0aW9uID0gIkVuZy1OQSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjcm9sZV9leGNsdWRlID0gIlRhcmdldF9DaGlsZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjdG9rZW49Y2FuZGlkYXRlX3dvcmRfbGlzdCkgDQojcmVhZCBjc3YgaW5zdGVhZA0KY2FuZGlkYXRlX3dvcmRfdG9rZW5zX3JhdyA8LSByZWFkLmNzdigiY2FuZGlkYXRlX3dvcmRfdG9rZW5zX0NISUxERVMuY3N2IikNCmNhbmRpZGF0ZV93b3JkX3Rva2VucyA8LSBjYW5kaWRhdGVfd29yZF90b2tlbnNfcmF3ICU+JSANCiAgc2VsZWN0KGdsb3NzLCBzcGVha2VyX2lkLCB0b2tlbl9vcmRlcikNCiAgDQpjYW5kaWRhdGVfd29yZF90b2tlbl9zdW1tYXJ5IDwtIGNhbmRpZGF0ZV93b3JkX3Rva2VucyAlPiUgDQogIG11dGF0ZShnbG9zcyA9IHRvbG93ZXIoZ2xvc3MpKSAlPiUNCiAgZmlsdGVyKGdsb3NzICVpbiUgY2FuZGlkYXRlX3dvcmRfbGlzdCkgJT4lIA0KICBncm91cF9ieShnbG9zcykgJT4lDQogIHN1bW1hcmlzZShyYXdfZnJlcV9jaGlsZGVzPW4oKSkgJT4lIA0KICBtdXRhdGUobG9nRnJlcV9jaGlsZGVzPWxvZyhyYXdfZnJlcV9jaGlsZGVzKzEpKQ0KDQp3ZWlyZF93b3JkcyA8LSBmaWx0ZXIoY2FuZGlkYXRlX3dvcmRfdG9rZW5fc3VtbWFyeSwgIShnbG9zcyAlaW4lIGNhbmRpZGF0ZV93b3JkX2xpc3QpKQ0Kbm90X2luX2NoaWxkZXMgPC0gZmlsdGVyKGNhbmRpZGF0ZV93b3JkcywgIShXb3JkICVpbiUgY2FuZGlkYXRlX3dvcmRfdG9rZW5fc3VtbWFyeSRnbG9zcykpDQoNCiNkZiB0byBtZXJnZQ0KY2hpbGRlc19mcmVxdWVuY3kgPC0gY2FuZGlkYXRlX3dvcmRfdG9rZW5fc3VtbWFyeSAlPiUgDQogIHJlbmFtZShXb3JkPWdsb3NzKQ0KDQpjYW5kaWRhdGVfd29yZHNfY2hpbGRlcyA8LSBsZWZ0X2pvaW4oY2FuZGlkYXRlX3dvcmRzLCBjaGlsZGVzX2ZyZXF1ZW5jeSwgYnk9IldvcmQiKQ0KYGBgDQoNCiMjIyMgQWRkIHN1YnRsZXggZnJlcXVlbmN5DQpgYGB7cn0NCnN1YnRsZXhfbWVyZ2UgPC0gc2VsZWN0KHN1YnRsZXgsIFdvcmQsIEZSRVFjb3VudCkNCmNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMgPC0gbGVmdF9qb2luKGNhbmRpZGF0ZV93b3Jkc19jaGlsZGVzLCBzdWJ0bGV4X21lcmdlLCBieT0iV29yZCIpICU+JSANCiAgcmVuYW1lKHJhd19mcmVxX3N1YnRsZXg9RlJFUWNvdW50KSAlPiUgDQogIG11dGF0ZShsb2dGcmVxX3N1YnRsZXg9bG9nKHJhd19mcmVxX3N1YnRsZXgrMSkpDQoNCiNmaXggbnVtX2h5cG9ueW1zDQpjYW5kaWRhdGVfd29yZHNfYWxsX2ZyZXFzJG51bV9oeXBvbnltcyA8LSBhcy5pbnRlZ2VyKGNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMkbnVtX2h5cG9ueW1zKQ0KYGBgDQoNCiMjIFBsYXkgYXJvdW5kIHdpdGggZ3JhcGhpbmcgc3R1ZmYgYW5kIGNvcnJlbGF0aW9ucw0KIyMjIENvcnJlbGF0aW9uIG1hdHJpeA0KYGBge3J9DQpjYW5kaWRhdGVfd29yZHNfY29ycm1hdHJpeCA8LSBzZWxlY3QoY2FuZGlkYXRlX3dvcmRzX2FsbF9mcmVxcywgLVdvcmQsIC1wb3MsIC1DYXROYW1lLCAtTUNESV9DYXQpDQoNCmNhbmRpZGF0ZV93b3Jkc19jb3IgPC0gY29yKGNhbmRpZGF0ZV93b3Jkc19jb3JybWF0cml4LCB1c2U9InBhaXJ3aXNlLmNvbXBsZXRlLm9icyIsIG1ldGhvZD0icGVhcnNvbiIpDQoNCnAubWF0X2l0ZW0gPC0gY29yLm10ZXN0KGNhbmRpZGF0ZV93b3Jkc19jb3IpDQpwTWF0cml4X2l0ZW0gPC0gcC5tYXRfaXRlbSRwDQpjb3JycGxvdChjYW5kaWRhdGVfd29yZHNfY29yLCBtZXRob2QgPSAnY29sb3InLCB0eXBlPSdsb3dlcicsIGRpYWcgPSBUUlVFLCBhZGRDb2VmLmNvbCA9ICJibGFjayIsDQogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLCBudW1iZXIuZm9udD0yLCBudW1iZXIuY2V4PTEwL25jb2woY2FuZGlkYXRlX3dvcmRzX2NvciksIHAubWF0PXBNYXRyaXhfaXRlbSwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiKQ0KYGBgDQojIyMgTG9vayBhdCByZWxhdGlvbnMgYmV0d2VlbiBkZW5zaXR5ICYgY2F0ZWdvcnkgaGllcmFyY2h5IHsudGFic2V0fQ0KIyMjIyBIeXBvbnltcyAmIEh5cGVybnltcw0KYGBge3J9DQpnZ3Bsb3QoY2FuZGlkYXRlX3dvcmRzX2FsbF9mcmVxcywgYWVzKG51bV9oeXBlcm55bXMsIG51bV9oeXBvbnltcywgbGFiZWw9YXMuY2hhcmFjdGVyKFdvcmQpKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9sYWJlbCgpKw0KICB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KDQojIyMjIEh5cGVybnltcyAmIFBlZXJzDQpgYGB7cn0NCmdncGxvdChjYW5kaWRhdGVfd29yZHNfYWxsX2ZyZXFzLCBhZXMobnVtX2h5cGVybnltcywgbnVtX3BlZXJzLCBsYWJlbD1hcy5jaGFyYWN0ZXIoV29yZCkpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICAjZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIpDQogIGdlb21fbGFiZWwoKSsNCiAgdGhlbWVfY2xhc3NpYygpDQoNCiNXaGF0IGFyZSB0aG9zZSBsb3ctaHlwZXJueW0sIGhpZ2hseSBkZW5zZSB3b3Jkcz8gKHRoZXkgYXJlIGFsbCB2ZXJicyAtIHRoaXMgbWFrZXMgc2Vuc2UpDQpsb3dIeXBlcl9oaWdoUGVlciA8LSBmaWx0ZXIoY2FuZGlkYXRlX3dvcmRzX2FsbF9mcmVxcywgKG51bV9wZWVycyA+IDMwMCkgJiAobnVtX2h5cGVybnltcyA8IDIpKSAlPiUgDQogIHNlbGVjdChXb3JkLCBwb3MsIGFvYSwgbnVtX3BlZXJzLCBudW1faHlwb255bXMsIG51bV9oeXBlcm55bXMsIENvbmMuTSxsb2dGcmVxX2NoaWxkZXMpDQpEVDo6ZGF0YXRhYmxlKGxvd0h5cGVyX2hpZ2hQZWVyKQ0KDQpgYGANCiMjIyMgSHlwb255bXMgJiBQZWVycw0KYGBge3J9DQpnZ3Bsb3QoY2FuZGlkYXRlX3dvcmRzX2FsbF9mcmVxcywgYWVzKG51bV9oeXBvbnltcywgbnVtX3BlZXJzLCBsYWJlbD1hcy5jaGFyYWN0ZXIoV29yZCkpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICAjZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIpDQogIGdlb21fbGFiZWwoKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwxMjAsMTUpKSsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCg0KDQojIyMgQ29tcGFyZSBjaGlsZGVzIGFuZCBzdWJ0bGV4IGZyZXF1ZW5jaWVzICgqciogPSAuNzYpIHsudGFic2V0fQ0KIyMjIyBQb2ludHMNCmBgYHtyfQ0KZ2dwbG90KGNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMsIGFlcyhsb2dGcmVxX2NoaWxkZXMsIGxvZ0ZyZXFfc3VidGxleCkpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iKSsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCiMjIyMgV29yZHMNCmBgYHtyfQ0KZ2dwbG90KGNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMsIGFlcyhsb2dGcmVxX2NoaWxkZXMsIGxvZ0ZyZXFfc3VidGxleCwgbGFiZWw9YXMuY2hhcmFjdGVyKFdvcmQpKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9sYWJlbCgpKw0KICB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KDQojIyMgQ2hpbGRlcyBmcmVxdWVuY3kgdnMuIGNvbmNyZXRlbmVzcyAoKnIqID0gLS4yLCBucykgey50YWJzZXR9DQojIyMjIFBvaW50cw0KYGBge3J9DQpnZ3Bsb3QoY2FuZGlkYXRlX3dvcmRzX2FsbF9mcmVxcywgYWVzKGxvZ0ZyZXFfY2hpbGRlcywgQ29uYy5NKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIpKw0KICB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KIyMjIyBXb3Jkcw0KYGBge3J9DQpnZ3Bsb3QoY2FuZGlkYXRlX3dvcmRzX2FsbF9mcmVxcywgYWVzKGxvZ0ZyZXFfY2hpbGRlcywgQ29uYy5NLCBsYWJlbD1hcy5jaGFyYWN0ZXIoV29yZCkpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2xhYmVsKCkrDQogIHRoZW1lX2NsYXNzaWMoKQ0KYGBgDQoNCiMjIyBDaGlsZGVzIGZyZXF1ZW5jeSB2cy4gQU9BICgqciogPSAtLjQ1KSB7LnRhYnNldH0NCiMjIyMgUG9pbnRzDQpgYGB7cn0NCmdncGxvdChjYW5kaWRhdGVfd29yZHNfYWxsX2ZyZXFzLCBhZXMobG9nRnJlcV9jaGlsZGVzLCBhb2EpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIikrDQogIHRoZW1lX2NsYXNzaWMoKQ0KYGBgDQojIyMjIFdvcmRzDQpgYGB7cn0NCmdncGxvdChjYW5kaWRhdGVfd29yZHNfYWxsX2ZyZXFzLCBhZXMobG9nRnJlcV9jaGlsZGVzLCBhb2EsIGxhYmVsPWFzLmNoYXJhY3RlcihXb3JkKSkpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21fbGFiZWwoKSsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCg0KIyMjIENoaWxkZXMgZnJlcXVlbmN5IHZzLiBBT0EgZm9yIGxvd2VyLXRoYW4tbWVhbiBjb25jcmV0ZW5lc3Mgey50YWJzZXR9DQojIyMjIFBvaW50cw0KYGBge3J9DQpnZ3Bsb3QoZmlsdGVyKGNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMsIENvbmMuTTwzLjkwKSwgYWVzKGxvZ0ZyZXFfY2hpbGRlcywgYW9hKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIpKw0KICB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KIyMjIyBXb3Jkcw0KYGBge3J9DQpnZ3Bsb3QoZmlsdGVyKGNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMsIENvbmMuTTwzLjkwKSwgYWVzKGxvZ0ZyZXFfY2hpbGRlcywgYW9hLCBsYWJlbD1hcy5jaGFyYWN0ZXIoV29yZCkpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2xhYmVsKCkrDQogIHRoZW1lX2NsYXNzaWMoKQ0KDQpgYGANCg0KIyMjIFdoYXQgYXJlIHRoZSBsb3ctY29uY3JldGVuZXNzIChsb3dlciB0aGFuIG1lYW4pLCBoaWdoLWZyZXF1ZW5jeSAoaGlnaGVyIHRoYW4gbWVhbiksIGxhdGUtYW9hIChvbGRlciB0aGFuIDUpIHdvcmRzPw0KYGBge3J9DQpoRnJlcV9oQU9BX2xDb25jIDwtIGZpbHRlcihjYW5kaWRhdGVfd29yZHNfYWxsX2ZyZXFzLCAoQ29uYy5NIDwgMy45MCkgJiAoYW9hPjUpICYgKGxvZ0ZyZXFfY2hpbGRlcyA+IDUuNDEpKSAlPiUgDQogIHNlbGVjdChXb3JkLCBwb3MsIGFvYSwgbnVtX2h5cGVybnltcywgbnVtX2h5cG9ueW1zLCBudW1fcGVlcnMsIENvbmMuTSwgbG9nRnJlcV9jaGlsZGVzLCBsb2dGcmVxX3N1YnRsZXgpDQoNCkRUOjpkYXRhdGFibGUoaEZyZXFfaEFPQV9sQ29uYykNCmBgYA0KDQojIyBTb21lIHN0YXRzDQojIyMgRG9lcyBjb25jcmV0ZW5lc3MgcHJlZGljdCBBT0EsIGNvbnRyb2xsaW5nIGZvciBmcmVxdWVuY3k/ICh5ZXMpDQpgYGB7cn0NCg0KcHJlZEFPQSA8LSBsbShhb2EgfiBsb2dGcmVxX2NoaWxkZXMgKyBDb25jLk0sIGNhbmRpZGF0ZV93b3Jkc19hbGxfZnJlcXMpDQpzdW1tYXJ5KHByZWRBT0EpDQoNCmBgYA==