Make data frame
Exclude Protocol 8 (mother)
Define Functions
## Func t test si boxplot simplu
func_t_box <- function(df, ind, pre_var, post_var, facet = FALSE, xlab = ""){
if(facet){
facet <- "Protocol"
}else{
facet <- NULL
}
df_modif <-
df %>%
select(ind, P, pre_var, post_var) %>%
tidyr::drop_na() %>%
gather(pre_var, post_var, key = "PrePost", value = "value") %>%
mutate_at(vars(c(1, 2)), funs(as.factor)) %>%
mutate(PrePost = factor(PrePost, levels = c(pre_var, post_var)))
if(!is.null(facet)){
df_modif <-
df_modif %>%
group_by(P) %>%
mutate(Protocol = paste0("Protocol = ", P, ", n = ", n()))
}
stat_comp <-
df_modif %>%
do(tidy(t.test(.$value ~ .$PrePost,
paired = TRUE,
data=.)))
plot <-
ggpubr::ggpaired(df_modif, x = "PrePost", y = "value", id = ind,
color = "PrePost", line.color = "gray", line.size = 0.4,
palette = c("#00AFBB", "#FC4E07"), legend = "none",
facet.by = facet, ncol = 3,
xlab = xlab) +
stat_summary(fun.data = mean_se, colour = "darkred") +
ggpubr::stat_compare_means(method = "t.test", paired = TRUE, label.x = as.numeric(df_modif$PrePost)-0.4, label.y = max(df_modif$value)+1) +
ggpubr::stat_compare_means(method = "t.test", paired = TRUE, label = "p.signif", comparisons = list(c(pre_var, post_var)))
print(stat_comp)
cat("\n")
print(plot)
cat("\n")
plot.new() # Need this workaround for interleaving tables and plots in R Markdown, within loop
dev.off()
}
heat_cor_plotly <- function(df, x_vars = NULL, y_vars = NULL, low_color = "cyan", high_color = "red", ...){
# inherit type = c("pearson","spearman") from Hmisc::rcorr()
library(ggplot2)
library(plotly)
library(reshape2)
library(Hmisc)
# use all numeric columns only, print message if non-numeric are found
numeric_cols <- unlist(lapply(df, is.numeric))
if(!all(numeric_cols)) message("Warning: Non-numeric columns were excluded!")
df <- df[, numeric_cols]
df_mat <- as.matrix(df)
rt <- Hmisc::rcorr(df_mat, ...)
# extract correlations, p-values and merge into another dataframe
mtlr <- reshape2::melt(rt$r, value.name = "Correlation")
mtlp <- reshape2::melt(rt$P, value.name = "P-Value")
mtl <- merge(mtlr, mtlp)
# give possibility to prune the correlation matrix
if(!is.null(x_vars)){
mtl <- mtl[(mtl$Var1 %in% x_vars), ]
}
if(!is.null(x_vars)){
mtl <- mtl[(mtl$Var2 %in% y_vars), ]
}
# want to avoid scientific notetion, but this doesnt work as numeric
# mtl$Correlation <- as.numeric(format(mtl$Correlation, digits = 4, scientific = FALSE)) # doesnt work
# mtl$`P-Value` <- as.numeric(format(mtl$`P-Value`, digits = 4, scientific = FALSE))
options(scipen = 999)
mtl$Correlation <- round(mtl$Correlation, 3)
mtl$`P-Value` <- round(mtl$`P-Value`, 3)
gx <-
ggplot2::ggplot(mtl,
aes(Var1, Var2,
fill = Correlation,
text = paste("P-val = ", `P-Value`))) +
ggplot2::geom_tile() +
ggplot2::scale_fill_gradient(low = low_color, high = high_color, limits = c(-1, 1), breaks = c(-1, -.5, 0, .5, 1)) +
ggplot2::theme_minimal() +
{if(any(nchar(names(df)) > 6)) ggplot2::theme(axis.text.x = element_text(angle = 90, hjust = 1))} # vertical x axis labels if lenghty
plotly::ggplotly(gx)
}
Plot Age
## Dodged Bar plot of Age and Gender
Data %>%
mutate(Varta_categ = cut(Varsta,
breaks=c(-Inf, 25, 30, 35, 40, 45, 50, 55, 60, Inf),
labels=c("<25","25-29","30-34", "35-39", "40-44", "45-49", "50-54", "55-59", "60>"),
right = FALSE)) %>%
mutate(Varsta = as.factor(Varsta),
Gen = as.factor(as.character(Gen))) %>%
mutate(Gen = forcats::fct_recode(Gen, "femin" = "1", "masculin" = "2")) %>%
dplyr::count(Varta_categ, Gen, .drop = FALSE) %>% # Group by, then count number in each group (dont drop 0 counts)
mutate(pct = prop.table(n)) %>% # Calculate percent within each var
ggplot(aes(x = Varta_categ, y = pct, fill = Gen, label = scales::percent(pct))) +
geom_col(position = position_dodge(preserve = "single"), stat = "identity",) + # Don't drop zero count
geom_text(position = position_dodge(width = .9), # move to center of bars
vjust = -0.5, # nudge above top of bar
size = 3) +
scale_y_continuous(labels = scales::percent) +
ggtitle("") +
xlab("Varsta") + ylab("Percentage %") +
guides(fill = guide_legend(title = "Gen", ncol = 1)) +
scale_fill_grey(start = 0.8, end = 0.2, na.value = "red", aesthetics = "fill") +
theme(legend.position = "right", legend.direction = "vertical",
legend.justification = c(0, 1), panel.border = element_rect(fill = NA, colour = "black"))
By Protocol
## Dodged Bar plot of Age and Gender by Protocol
Data %>%
mutate(Varta_categ = cut(Varsta,
breaks=c(-Inf, 25, 30, 35, 40, 45, 50, 55, 60, Inf),
labels=c("<25","25-29","30-34", "35-39", "40-44", "45-49", "50-54", "55-59", "60>"),
right = FALSE)) %>%
mutate(Varsta = as.factor(Varsta),
Gen = as.factor(as.character(Gen))) %>%
mutate(Gen = forcats::fct_recode(Gen, "femin" = "1", "masculin" = "2")) %>%
group_by(P) %>%
dplyr::count(Varta_categ, Gen, .drop = FALSE) %>% # Group by, then count number in each group (dont drop 0 counts)
mutate(pct = prop.table(n)) %>% # Calculate percent within each var
ggplot(aes(x = Varta_categ, y = pct, fill = Gen, label = scales::percent(pct))) +
facet_wrap(~P, scales = "free", ncol = 1) +
geom_col(position = position_dodge(preserve = "single"), stat = "identity",) + # Don't drop zero count
geom_text(position = position_dodge(width = .9), # move to center of bars
vjust = -0.5, # nudge above top of bar
size = 3) +
scale_y_continuous(labels = scales::percent) +
ggtitle("") +
xlab("Varsta") + ylab("Percentage %") +
guides(fill = guide_legend(title = "Gen", ncol = 1)) +
scale_fill_grey(start = 0.8, end = 0.2, na.value = "red", aesthetics = "fill") +
theme(legend.position = "right", legend.direction = "vertical",
legend.justification = c(0, 1), panel.border = element_rect(fill = NA, colour = "black"))
## Pie chart
Data %>%
mutate(Gen = as.factor(as.character(Gen))) %>%
mutate(Gen = forcats::fct_recode(Gen, "femin" = "1", "masculin" = "2")) %>%
group_by(Gen) %>%
dplyr::summarise(counts = n()) %>%
mutate(prop = round(counts*100/sum(counts), 1),
lab.ypos = cumsum(prop) - .5*prop,
Percent = paste0(prop, " %")) %>%
ggpubr::ggpie(x = "prop", label = "Percent",
fill = "Gen", color = "white",
lab.pos = "in", lab.font = list(color = "white"),
palette = "grey")
Analyses
Simple before-after analyses with t test
VAS Stress
NANA
null device 1
VAS Stress
NANA
null device 1
Correlations: Anotimpuri - Calitate Amintiri (without P6, P7)
dateplot1 <- Data[, c("P", "Primavara", "Vara", "Toamna", "Iarna", "Media_s1", "Media_s2", "Media_s3", "SocDih_Part", "SocDih_FamN", "SocDih_FamInd", "SocDih_Priet", "SocDih_Amici", "SocDih_Necun", "SocDih_Antag", "SocDih_TotAprop", "SocDih_TotNeaprop", "STAI_T")]
names(dateplot1) <- c("P", "Primavara", "Vara", "Toamna", "Iarna", "S1- Valenta", "S2 - Vividness", "S3 - Relevanta", "Partener", "Familie nucleu", "Familie extinsa", "Prieteni", "Amici", "Necunoscuti", "Antagonisti", "Toti Apropiatii", "Toti Neapropiatii", "STAI_T")
dateplot1 <- subset(dateplot1, P!=6 & P!=7)
COR <- Hmisc::rcorr(as.matrix(dateplot1[,-1]))
M <- COR$r
P_MAT <- COR$P
corrplot::corrplot(M, method = "number", type = "upper", p.mat = P_MAT, sig.level = 0.05, insig = "blank", tl.col = "black", tl.cex = .9, tl.srt = 45)
Correlations: Personality - Qualities of Memories (without P6, P7)
dateplot2 <- Data[, c(24, 40, 56, 87:121, 126)]
names(dateplot2)[1:3] <- c("S1- Valenta", "S2 - Vividness", "S3 - Relevanta")
COR <- Hmisc::rcorr(as.matrix(dateplot2))
M <- COR$r
P_MAT <- COR$P
corrplot::corrplot(M, type = "upper", p.mat = P_MAT, sig.level = 0.05, insig = "blank", tl.col = "black", tl.cex = .7, cl.pos = "b", tl.srt = 45)
Correlations: Social - Personality
dateplot3 <- Data[, c(131:139, 87:121)]
names(dateplot3)[1:9] <- c("Partener", "Familie nucleu", "Familie extinsa", "Prieteni", "Amici", "Necunoscuti", "Antagonisti", "Toti Apropiatii", "Toti Neapropiatii")
COR <- Hmisc::rcorr(as.matrix(dateplot3))
M <- COR$r
P_MAT <- COR$P
corrplot::corrplot(M, type = "upper", p.mat = P_MAT, sig.level = 0.05, insig = "blank", tl.col = "black", tl.cex = .7, cl.pos = "b", tl.srt = 45)
Social
# names(Data[str_detect(colnames(Data), fixed("SocDih", ignore_case=TRUE))])
Data_soc <-
Data %>%
dplyr::select("ID", "P", starts_with("SocDih")) %>%
haven::zap_formats(.) %>% # to not get warning
haven::zap_labels(.) %>% # "attributes are not identical across measure variables"
haven::zap_widths(.) %>% # on gather() because of SPSS
dplyr::rename_all(list(~stringr::str_replace(., "SocDih_", ""))) %>%
gather(key = "Variable", value = "Value", -ID, -P)
# Create a custom color scale for all ASCQ graphs
library(RColorBrewer)
myColors <- brewer.pal(10,"Set1")
names(myColors) <- levels(Data_soc$Variable)
colScale <- scale_colour_manual(name = "Variable", values = myColors)
# Plot
ggpubr::ggviolin(data = Data_soc, x = "Variable", y = "Value", fill = "Variable",
add = "boxplot", add.params = list(fill = "white"),
xlab = "", legend = "none") +
colScale + # color scale here keep consistency of color with factor level
stat_summary(fun.data = mean_se, colour = "darkred") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
# Plot faceted by Protocol
p <-
ggpubr::ggviolin(data = Data_soc, x = "Variable", y = "Value", fill = "Variable",
add = "boxplot", add.params = list(fill = "white"),
xlab = "", legend = "none") +
colScale + # color scale here keep consistency of color with factor level
stat_summary(fun.data = mean_se, colour = "darkred") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
ggpubr::facet(p, facet.by = "P", ncol = 1, scales = "free_x")
Social - this doesnt make sense
# PerformanceAnalytics::chart.Correlation(Data[, c(8, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140)])
# Example of Simpsons Paradox
coplot(DifStres ~ SocDih_Amici | Media_s1,
data = Data,
rows = 1,
panel = function(x, y, ...) {
panel.smooth(x, y, span = .8, iter = 5,...)
abline(lm(y ~ x), col = "blue")})
Varsta Amint - P1,P2,P3
coplot(DifStres ~ Dif_Med_amintvarsta | Media_s1,
data = Data_P1P2P3,
rows = 1,
panel = function(x, y, ...) {
panel.smooth(x, y, span = .8, iter = 5,...)
abline(lm(y ~ x), col = "blue")})
Protocol 3 - Social
Data_P3 <-
Data %>%
filter(P == "3")
PerformanceAnalytics::chart.Correlation(Data_P3[, c(8, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140)])
# coplot(SocDih_Amici ~ DifStres | Media_s1,
# data = Data,
# columns = 3,
# panel = function(x, y, ...) {
# panel.smooth(x, y, span = .8, iter = 5,...)
# abline(lm(y ~ x), col = "blue") } )
Protocol 3 - Varsta Amint
Session Info
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)
Matrix products: default
locale:
[1] LC_COLLATE=Romanian_Romania.1250 LC_CTYPE=Romanian_Romania.1250 LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C
[5] LC_TIME=Romanian_Romania.1250
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] RColorBrewer_1.1-2 Hmisc_4.1-1 Formula_1.2-3 survival_2.44-1.1 lattice_0.20-38
[6] reshape2_1.4.3 plotly_4.9.0 rio_0.5.16 scales_1.0.0 ggpubr_0.2
[11] magrittr_1.5 tadaatoolbox_0.16.1 summarytools_0.8.8 rstatix_0.2.0 broom_0.5.2
[16] PerformanceAnalytics_1.5.2 xts_0.11-2 zoo_1.8-4 psych_1.8.12 plyr_1.8.4
[21] forcats_0.4.0 stringr_1.4.0 dplyr_0.8.3 purrr_0.3.2 readr_1.3.1
[26] tidyr_1.0.0 tibble_2.1.3 ggplot2_3.2.1 tidyverse_1.2.1 papaja_0.1.0.9842
[31] pacman_0.5.1
loaded via a namespace (and not attached):
[1] colorspace_1.4-1 ggsignif_0.4.0 pryr_0.1.4 ellipsis_0.3.0 htmlTable_1.12 base64enc_0.1-3 rstudioapi_0.8
[8] DT_0.5 mvtnorm_1.0-11 lubridate_1.7.4 xml2_1.2.0 codetools_0.2-16 splines_3.6.1 mnormt_1.5-5
[15] knitr_1.25 zeallot_0.1.0 pixiedust_0.8.6 jsonlite_1.6 cluster_2.1.0 shiny_1.2.0 compiler_3.6.1
[22] httr_1.4.0 backports_1.1.4 assertthat_0.2.1 Matrix_1.2-17 lazyeval_0.2.2 cli_1.1.0 later_0.7.5
[29] acepack_1.4.1 htmltools_0.3.6 tools_3.6.1 gtable_0.3.0 glue_1.3.1 Rcpp_1.0.2 carData_3.0-2
[36] cellranger_1.1.0 vctrs_0.2.0 nlme_3.1-140 crosstalk_1.0.0 xfun_0.9 openxlsx_4.1.0 rvest_0.3.2
[43] mime_0.7 lifecycle_0.1.0 MASS_7.3-51.4 hms_0.5.1 promises_1.0.1 parallel_3.6.1 expm_0.999-3
[50] pwr_1.2-2 yaml_2.2.0 curl_3.2 gridExtra_2.3 pander_0.6.3 rpart_4.1-15 latticeExtra_0.6-28
[57] stringi_1.4.3 corrplot_0.84 nortest_1.0-4 checkmate_1.8.5 boot_1.3-22 zip_1.0.0 rlang_0.4.0
[64] pkgconfig_2.0.3 matrixStats_0.54.0 bitops_1.0-6 rapportools_1.0 htmlwidgets_1.3 labeling_0.3 tidyselect_0.2.5
[71] R6_2.4.0 DescTools_0.99.29 generics_0.0.2 pillar_1.4.2 haven_2.1.1 foreign_0.8-71 withr_2.1.2
[78] nnet_7.3-12 abind_1.4-5 RCurl_1.95-4.11 modelr_0.1.5 crayon_1.3.4 car_3.0-2 viridis_0.5.1
[85] grid_3.6.1 readxl_1.1.0 data.table_1.11.8 digest_0.6.21 xtable_1.8-4 httpuv_1.4.5 munsell_0.5.0
[92] viridisLite_0.3.0 quadprog_1.5-5
A work by Claudiu Papasteri
claudiu.papasteri@gmail.com
LS0tDQp0aXRsZTogIjxicj4gR2VuZXJhbCBQbG90cyBmb3IgTS4xLiAoQXV0b2Jpb2dyYXBoaWNhbCBNZW1vcmllcykiIA0Kc3VidGl0bGU6ICJJbml0aWFsIERhdGFzZXQiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICAgICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgICAgICAgICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgICAgICAgICAgZm9udC1mYW1pbHk6IEFyaWFsDQogICAgICAgICAgICBmaWdfd2lkdGg6IDEwDQogICAgICAgICAgICBmaWdfaGVpZ2h0OiA5DQogICAgIyB3b3JkX2RvY3VtZW50ICAgICAgICANCiAgICAjIHBkZl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICAjIGZvbnRzaXplOiAxMXB0DQogICAgICAgICAgICAjIGdlb21ldHJ5OiBtYXJnaW49MWluDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNw0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA2DQogICAgICAgICAgICAjIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgIyBnaXRodWJfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIGh0bWxfcHJldmlldzogZmFsc2UNCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA1DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDUNCiAgICAgICAgICAgICMgZGV2OiBqcGVnDQotLS0NCg0KDQo8IS0tIFNldHVwIC0tPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZWNobyA9IFRSVUUsIA0KICB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgZXJyb3IgPSBGQUxTRSwNCiAgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAicGFwYWphIiwNCiAgInRpZHl2ZXJzZSIsICJwbHlyIiwgICAgICANCiAgInBzeWNoIiwgIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgICAgICAgICAgDQogICJicm9vbSIsICJyc3RhdGl4IiwNCiAgInN1bW1hcnl0b29scyIsICJ0YWRhYXRvb2xib3giLCAgICAgICAgICAgDQogICJnZ3Bsb3QyIiwgImdncHViciIsICJzY2FsZXMiLCAgICAgICAgDQogICJyaW8iDQogICMgLCAuLi4NCikNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNtYW46OnBfbG9hZChjaGFyID0gcGFja2FnZXMpDQoNCiMgVGhlbWVzIGZvciBnZ3Bsb3QyIHBsb3RpbmcgKGhlcmUgdXNlZCBBUEEgc3R5bGUpDQp0aGVtZV9zZXQodGhlbWVfYXBhKCkpDQoNCiMgVGFibGVzIGtuaXR0aW5nIHRvIFdvcmQNCmRvYy50eXBlIDwtIGtuaXRyOjpvcHRzX2tuaXQkZ2V0KCdybWFya2Rvd24ucGFuZG9jLnRvJykgICMgdGhlbiBmb3JtYXQgdGFibGVzIHVzaW5nIGFuIGlmIHN0YXRlbWVudCBsaWtlOg0KIyBpZiAoZG9jLnR5cGUgPT0gImRvY3giKSB7IHBhbmRlcjo6cGFuZGVyKGRmKSB9IGVsc2UgeyBrbml0cjo6a2FibGUoZGYpIH0NCg0KIyBTZXQgd2QgZm9yIE5vdGVib29rDQpmb2xkZXIgPC0gIkM6L1VzZXJzL01paGFpL0Rlc2t0b3AvUiBOb3RlYm9va3Mvbm90ZWJvb2tzL00uMS4gR2VuZXJhbCINCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBub3JtYWxpemVQYXRoKGZvbGRlcikpDQpgYGANCg0KDQoNCg0KDQo8IS0tIFJlcG9ydCAtLT4NCg0KDQojIFJlYWQNCg0KYGBge3IgcmVkX2NsZWFuX3JlY29kZV9tZXJnZSwgcmVzdWx0cz0naGlkZSd9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBSZWFkDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KDQojIyBSZWFkIGZpbGVzDQpmaWxlIDwtICJEYXRlIENvbXBsZXRlIE0xIHYuMTMgc2lQUEdHU1JhbWlsYXphLnNhdiINCg0KIyBzZXR3ZChmb2xkZXIpDQpEYXRhIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGUpKQ0KYGBgDQoNCg0KIyBNYWtlIGRhdGEgZnJhbWUNCg0KYGBge3IgZGZfZXhjZWx9DQpEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KC1OdW1lKSAlPiUNCiAgICBEVDo6ZGF0YXRhYmxlKA0KICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywNCiAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywNCiAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLA0KICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCmBgYA0KDQoNCiMjIEV4Y2x1ZGUgUHJvdG9jb2wgOCAobW90aGVyKQ0KDQpgYGB7ciBkZl9maWx0ZXJlZH0NCkRhdGEgPC0gDQogIERhdGEgJT4lDQogIGZpbHRlcihQICE9IDgpDQpgYGANCg0KDQojIERlZmluZSBGdW5jdGlvbnMgDQoNCmBgYHtyIGRlZl9mdW5jX3R0ZXN0LCBoaWRlPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQ0KIyMgRnVuYyB0IHRlc3Qgc2kgYm94cGxvdCBzaW1wbHUNCmZ1bmNfdF9ib3ggPC0gZnVuY3Rpb24oZGYsIGluZCwgcHJlX3ZhciwgcG9zdF92YXIsIGZhY2V0ID0gRkFMU0UsIHhsYWIgPSAiIil7ICANCiAgaWYoZmFjZXQpew0KICAgIGZhY2V0IDwtICJQcm90b2NvbCINCiAgfWVsc2V7DQogICAgZmFjZXQgPC0gTlVMTA0KICB9DQogIA0KICBkZl9tb2RpZiA8LQ0KICAgIGRmICU+JQ0KICAgIHNlbGVjdChpbmQsIFAsIHByZV92YXIsIHBvc3RfdmFyKSAlPiUgDQogICAgdGlkeXI6OmRyb3BfbmEoKSAlPiUNCiAgICBnYXRoZXIocHJlX3ZhciwgcG9zdF92YXIsIGtleSA9ICJQcmVQb3N0IiwgdmFsdWUgPSAidmFsdWUiKSAlPiUgDQogICAgbXV0YXRlX2F0KHZhcnMoYygxLCAyKSksIGZ1bnMoYXMuZmFjdG9yKSkgJT4lIA0KICAgIG11dGF0ZShQcmVQb3N0ID0gZmFjdG9yKFByZVBvc3QsIGxldmVscyA9IGMocHJlX3ZhciwgcG9zdF92YXIpKSkgDQogIA0KICBpZighaXMubnVsbChmYWNldCkpew0KICAgIGRmX21vZGlmIDwtDQogICAgICBkZl9tb2RpZiAlPiUNCiAgICAgIGdyb3VwX2J5KFApICU+JQ0KICAgICAgbXV0YXRlKFByb3RvY29sID0gcGFzdGUwKCJQcm90b2NvbCA9ICIsIFAsICIsIG4gPSAiLCBuKCkpKQ0KICB9DQogIA0KICBzdGF0X2NvbXAgPC0NCiAgICBkZl9tb2RpZiAlPiUgDQogICAgZG8odGlkeSh0LnRlc3QoLiR2YWx1ZSB+IC4kUHJlUG9zdCwNCiAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9LikpKQ0KICANCiAgcGxvdCA8LSANCiAgICBnZ3B1YnI6OmdncGFpcmVkKGRmX21vZGlmLCB4ID0gIlByZVBvc3QiLCB5ID0gInZhbHVlIiwgaWQgPSBpbmQsIA0KICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiUHJlUG9zdCIsIGxpbmUuY29sb3IgPSAiZ3JheSIsIGxpbmUuc2l6ZSA9IDAuNCwNCiAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNGQzRFMDciKSwgbGVnZW5kID0gIm5vbmUiLA0KICAgICAgICAgICAgICAgICAgICAgZmFjZXQuYnkgPSBmYWNldCwgbmNvbCA9IDMsIA0KICAgICAgICAgICAgICAgICAgICAgeGxhYiA9IHhsYWIpICsNCiAgICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCAgY29sb3VyID0gImRhcmtyZWQiKSArDQogICAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGxhYmVsLnggPSBhcy5udW1lcmljKGRmX21vZGlmJFByZVBvc3QpLTAuNCwgbGFiZWwueSA9IG1heChkZl9tb2RpZiR2YWx1ZSkrMSkgKyANCiAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgbGFiZWwgPSAicC5zaWduaWYiLCBjb21wYXJpc29ucyA9IGxpc3QoYyhwcmVfdmFyLCBwb3N0X3ZhcikpKQ0KICANCiAgcHJpbnQoc3RhdF9jb21wKQ0KICBjYXQoIlxuIikgICAgICAgICAgICAgICAgICAgICAgDQogIHByaW50KHBsb3QpDQogIGNhdCgiXG4iKQ0KICBwbG90Lm5ldygpICAgICAgICAgICAgICAgICAgICAgIyBOZWVkIHRoaXMgd29ya2Fyb3VuZCBmb3IgaW50ZXJsZWF2aW5nIHRhYmxlcyBhbmQgcGxvdHMgaW4gUiBNYXJrZG93biwgd2l0aGluIGxvb3ANCiAgZGV2Lm9mZigpDQp9DQpgYGANCg0KDQpgYGB7ciBkZWZfZnVuY19oZWF0Y29ycGxvdGx5LCBoaWRlPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQ0KaGVhdF9jb3JfcGxvdGx5IDwtIGZ1bmN0aW9uKGRmLCB4X3ZhcnMgPSBOVUxMLCB5X3ZhcnMgPSBOVUxMLCBsb3dfY29sb3IgPSAiY3lhbiIsICBoaWdoX2NvbG9yID0gInJlZCIsICAuLi4peyAgIA0KICAjIGluaGVyaXQgdHlwZSA9IGMoInBlYXJzb24iLCJzcGVhcm1hbiIpIGZyb20gSG1pc2M6OnJjb3JyKCkgDQogIGxpYnJhcnkoZ2dwbG90MikNCiAgbGlicmFyeShwbG90bHkpDQogIGxpYnJhcnkocmVzaGFwZTIpDQogIGxpYnJhcnkoSG1pc2MpDQogIA0KICAjIHVzZSBhbGwgbnVtZXJpYyBjb2x1bW5zIG9ubHksIHByaW50IG1lc3NhZ2UgaWYgbm9uLW51bWVyaWMgYXJlIGZvdW5kDQogIG51bWVyaWNfY29scyA8LSB1bmxpc3QobGFwcGx5KGRmLCBpcy5udW1lcmljKSkNCiAgaWYoIWFsbChudW1lcmljX2NvbHMpKSBtZXNzYWdlKCJXYXJuaW5nOiBOb24tbnVtZXJpYyBjb2x1bW5zIHdlcmUgZXhjbHVkZWQhIikNCiAgZGYgPC0gZGZbLCBudW1lcmljX2NvbHNdDQogIA0KICBkZl9tYXQgPC0gYXMubWF0cml4KGRmKQ0KICBydCA8LSBIbWlzYzo6cmNvcnIoZGZfbWF0LCAuLi4pDQogIA0KICAjIGV4dHJhY3QgY29ycmVsYXRpb25zLCBwLXZhbHVlcyBhbmQgbWVyZ2UgaW50byBhbm90aGVyIGRhdGFmcmFtZQ0KICBtdGxyIDwtIHJlc2hhcGUyOjptZWx0KHJ0JHIsIHZhbHVlLm5hbWUgPSAiQ29ycmVsYXRpb24iKQ0KICBtdGxwIDwtIHJlc2hhcGUyOjptZWx0KHJ0JFAsIHZhbHVlLm5hbWUgPSAiUC1WYWx1ZSIpDQogIA0KICBtdGwgPC0gbWVyZ2UobXRsciwgbXRscCkNCiAgDQogICMgZ2l2ZSBwb3NzaWJpbGl0eSB0byBwcnVuZSB0aGUgY29ycmVsYXRpb24gbWF0cml4DQogIGlmKCFpcy5udWxsKHhfdmFycykpew0KICAgIG10bCA8LSBtdGxbKG10bCRWYXIxICVpbiUgeF92YXJzKSwgXQ0KICB9DQogIGlmKCFpcy5udWxsKHhfdmFycykpew0KICAgIG10bCA8LSBtdGxbKG10bCRWYXIyICVpbiUgeV92YXJzKSwgXQ0KICB9DQogIA0KICAjIHdhbnQgdG8gYXZvaWQgc2NpZW50aWZpYyBub3RldGlvbiwgYnV0IHRoaXMgZG9lc250IHdvcmsgYXMgbnVtZXJpYw0KICAjIG10bCRDb3JyZWxhdGlvbiA8LSBhcy5udW1lcmljKGZvcm1hdChtdGwkQ29ycmVsYXRpb24sIGRpZ2l0cyA9IDQsIHNjaWVudGlmaWMgPSBGQUxTRSkpICAjIGRvZXNudCB3b3JrDQogICMgbXRsJGBQLVZhbHVlYCA8LSBhcy5udW1lcmljKGZvcm1hdChtdGwkYFAtVmFsdWVgLCBkaWdpdHMgPSA0LCBzY2llbnRpZmljID0gRkFMU0UpKSANCiAgb3B0aW9ucyhzY2lwZW4gPSA5OTkpDQogIG10bCRDb3JyZWxhdGlvbiA8LSByb3VuZChtdGwkQ29ycmVsYXRpb24sIDMpDQogIG10bCRgUC1WYWx1ZWAgPC0gcm91bmQobXRsJGBQLVZhbHVlYCwgMykNCg0KICBneCA8LQ0KICAgIGdncGxvdDI6OmdncGxvdChtdGwsIA0KICAgICAgICAgICBhZXMoVmFyMSwgVmFyMiwgDQogICAgICAgICAgICAgICBmaWxsID0gQ29ycmVsYXRpb24sICANCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiUC12YWwgPSAiLCBgUC1WYWx1ZWApKSkgKw0KICAgIGdncGxvdDI6Omdlb21fdGlsZSgpICsgDQogICAgZ2dwbG90Mjo6c2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBsb3dfY29sb3IsICBoaWdoID0gaGlnaF9jb2xvciwgbGltaXRzID0gYygtMSwgMSksIGJyZWFrcyA9IGMoLTEsIC0uNSwgMCwgLjUsIDEpKSArDQogICAgZ2dwbG90Mjo6dGhlbWVfbWluaW1hbCgpICsNCiAgICB7aWYoYW55KG5jaGFyKG5hbWVzKGRmKSkgPiA2KSkgZ2dwbG90Mjo6dGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSl9ICAjIHZlcnRpY2FsIHggYXhpcyBsYWJlbHMgaWYgbGVuZ2h0eQ0KICBwbG90bHk6OmdncGxvdGx5KGd4KSAgDQp9DQpgYGANCg0KDQojIFBsb3QgQWdlDQoNCmBgYHtyIHBsb3QxLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LCByZXN1bHRzPSdhc2lzJ30NCiMjIERvZGdlZCBCYXIgcGxvdCBvZiBBZ2UgYW5kIEdlbmRlcg0KRGF0YSAgJT4lDQogIG11dGF0ZShWYXJ0YV9jYXRlZyA9IGN1dChWYXJzdGEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoLUluZiwgMjUsIDMwLCAzNSwgNDAsIDQ1LCA1MCwgNTUsIDYwLCBJbmYpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCI8MjUiLCIyNS0yOSIsIjMwLTM0IiwgIjM1LTM5IiwgIjQwLTQ0IiwgIjQ1LTQ5IiwgIjUwLTU0IiwgIjU1LTU5IiwgIjYwPiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gRkFMU0UpKSAlPiUgIA0KICBtdXRhdGUoVmFyc3RhID0gYXMuZmFjdG9yKFZhcnN0YSksDQogICAgICAgICBHZW4gPSBhcy5mYWN0b3IoYXMuY2hhcmFjdGVyKEdlbikpKSAlPiUNCiAgbXV0YXRlKEdlbiA9IGZvcmNhdHM6OmZjdF9yZWNvZGUoR2VuLCAiZmVtaW4iID0gIjEiLCAibWFzY3VsaW4iID0gIjIiKSkgJT4lDQogIGRwbHlyOjpjb3VudChWYXJ0YV9jYXRlZywgR2VuLCAuZHJvcCA9IEZBTFNFKSAlPiUgICAgICAgICAjIEdyb3VwIGJ5LCB0aGVuIGNvdW50IG51bWJlciBpbiBlYWNoIGdyb3VwIChkb250IGRyb3AgMCBjb3VudHMpDQogIG11dGF0ZShwY3QgPSBwcm9wLnRhYmxlKG4pKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAjIENhbGN1bGF0ZSBwZXJjZW50IHdpdGhpbiBlYWNoIHZhcg0KICAgIGdncGxvdChhZXMoeCA9IFZhcnRhX2NhdGVnLCB5ID0gcGN0LCBmaWxsID0gR2VuLCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwY3QpKSkgKyANCiAgICAgIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UocHJlc2VydmUgPSAic2luZ2xlIiksIHN0YXQgPSAiaWRlbnRpdHkiLCkgKyAgICAjIERvbid0IGRyb3AgemVybyBjb3VudA0KICAgICAgZ2VvbV90ZXh0KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuOSksICAgICAgIyBtb3ZlIHRvIGNlbnRlciBvZiBiYXJzDQogICAgICAgICAgICAgICAgdmp1c3QgPSAtMC41LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG51ZGdlIGFib3ZlIHRvcCBvZiBiYXINCiAgICAgICAgICAgICAgICBzaXplID0gMykgKyANCiAgICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgICAgIGdndGl0bGUoIiIpICsNCiAgICAgIHhsYWIoIlZhcnN0YSIpICsgeWxhYigiUGVyY2VudGFnZSAlIikgKyANCiAgICAgIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkdlbiIsIG5jb2wgPSAxKSkgKyANCiAgICAgIHNjYWxlX2ZpbGxfZ3JleShzdGFydCA9IDAuOCwgZW5kID0gMC4yLCBuYS52YWx1ZSA9ICJyZWQiLCBhZXN0aGV0aWNzID0gImZpbGwiKSArDQogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwgDQogICAgICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMSksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG91ciA9ICJibGFjayIpKQ0KYGBgDQoNCg0KIyMgQnkgUHJvdG9jb2wNCg0KYGBge3IgcGxvdDFfMiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MjgsIHJlc3VsdHM9J2FzaXMnfQ0KIyMgRG9kZ2VkIEJhciBwbG90IG9mIEFnZSBhbmQgR2VuZGVyIGJ5IFByb3RvY29sDQpEYXRhICAlPiUNCiAgbXV0YXRlKFZhcnRhX2NhdGVnID0gY3V0KFZhcnN0YSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9YygtSW5mLCAyNSwgMzAsIDM1LCA0MCwgNDUsIDUwLCA1NSwgNjAsIEluZiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIjwyNSIsIjI1LTI5IiwiMzAtMzQiLCAiMzUtMzkiLCAiNDAtNDQiLCAiNDUtNDkiLCAiNTAtNTQiLCAiNTUtNTkiLCAiNjA+IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSBGQUxTRSkpICU+JSAgDQogIG11dGF0ZShWYXJzdGEgPSBhcy5mYWN0b3IoVmFyc3RhKSwNCiAgICAgICAgIEdlbiA9IGFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoR2VuKSkpICU+JQ0KICBtdXRhdGUoR2VuID0gZm9yY2F0czo6ZmN0X3JlY29kZShHZW4sICJmZW1pbiIgPSAiMSIsICJtYXNjdWxpbiIgPSAiMiIpKSAlPiUNCiAgZ3JvdXBfYnkoUCkgJT4lDQogIGRwbHlyOjpjb3VudChWYXJ0YV9jYXRlZywgR2VuLCAuZHJvcCA9IEZBTFNFKSAlPiUgICAgICAgICAjIEdyb3VwIGJ5LCB0aGVuIGNvdW50IG51bWJlciBpbiBlYWNoIGdyb3VwIChkb250IGRyb3AgMCBjb3VudHMpDQogIG11dGF0ZShwY3QgPSBwcm9wLnRhYmxlKG4pKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAjIENhbGN1bGF0ZSBwZXJjZW50IHdpdGhpbiBlYWNoIHZhcg0KICAgIGdncGxvdChhZXMoeCA9IFZhcnRhX2NhdGVnLCB5ID0gcGN0LCBmaWxsID0gR2VuLCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwY3QpKSkgKw0KICAgICAgZmFjZXRfd3JhcCh+UCwgc2NhbGVzID0gImZyZWUiLCBuY29sID0gMSkgKw0KICAgICAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZShwcmVzZXJ2ZSA9ICJzaW5nbGUiKSwgc3RhdCA9ICJpZGVudGl0eSIsKSArICAgICMgRG9uJ3QgZHJvcCB6ZXJvIGNvdW50DQogICAgICBnZW9tX3RleHQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC45KSwgICAgICAjIG1vdmUgdG8gY2VudGVyIG9mIGJhcnMNCiAgICAgICAgICAgICAgICB2anVzdCA9IC0wLjUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbnVkZ2UgYWJvdmUgdG9wIG9mIGJhcg0KICAgICAgICAgICAgICAgIHNpemUgPSAzKSArIA0KICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICAgICAgZ2d0aXRsZSgiIikgKw0KICAgICAgeGxhYigiVmFyc3RhIikgKyB5bGFiKCJQZXJjZW50YWdlICUiKSArIA0KICAgICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiR2VuIiwgbmNvbCA9IDEpKSArIA0KICAgICAgc2NhbGVfZmlsbF9ncmV5KHN0YXJ0ID0gMC44LCBlbmQgPSAwLjIsIG5hLnZhbHVlID0gInJlZCIsIGFlc3RoZXRpY3MgPSAiZmlsbCIpICsNCiAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiLCANCiAgICAgICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAxKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3VyID0gImJsYWNrIikpDQpgYGANCg0KDQpgYGB7ciBwbG90MiwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgcmVzdWx0cz0nYXNpcyd9DQojIyBQaWUgY2hhcnQNCkRhdGEgICU+JQ0KICBtdXRhdGUoR2VuID0gYXMuZmFjdG9yKGFzLmNoYXJhY3RlcihHZW4pKSkgJT4lDQogIG11dGF0ZShHZW4gPSBmb3JjYXRzOjpmY3RfcmVjb2RlKEdlbiwgImZlbWluIiA9ICIxIiwgIm1hc2N1bGluIiA9ICIyIikpICU+JQ0KICBncm91cF9ieShHZW4pICU+JQ0KICBkcGx5cjo6c3VtbWFyaXNlKGNvdW50cyA9IG4oKSkgJT4lDQogIG11dGF0ZShwcm9wID0gcm91bmQoY291bnRzKjEwMC9zdW0oY291bnRzKSwgMSksDQogICAgICAgICBsYWIueXBvcyA9IGN1bXN1bShwcm9wKSAtIC41KnByb3AsDQogICAgICAgICBQZXJjZW50ID0gcGFzdGUwKHByb3AsICIgJSIpKSAlPiUgDQogIGdncHVicjo6Z2dwaWUoeCA9ICJwcm9wIiwgbGFiZWwgPSAiUGVyY2VudCIsDQogICAgICAgICAgICAgICAgZmlsbCA9ICJHZW4iLCBjb2xvciA9ICJ3aGl0ZSIsIA0KICAgICAgICAgICAgICAgIGxhYi5wb3MgPSAiaW4iLCBsYWIuZm9udCA9IGxpc3QoY29sb3IgPSAid2hpdGUiKSwNCiAgICAgICAgICAgICAgICBwYWxldHRlID0gImdyZXkiKQ0KYGBgDQoNCg0KDQojIEFuYWx5c2VzDQoNCiMjIFNpbXBsZSBiZWZvcmUtYWZ0ZXIgYW5hbHlzZXMgd2l0aCB0IHRlc3QNCg0KYGBge3IgdF90ZXN0MSwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NiwgcmVzdWx0cz0nYXNpcyd9DQojIyBTaW1wbGUgYmVmb3JlLWFmdGVyIGFuYWx5c2VzIHdpdGggdCB0ZXN0DQpjYXQoIiMjIyMgVkFTIFN0cmVzcyIpDQpmdW5jX3RfYm94KERhdGEsIGluZCA9ICJJRCIsICJTdHJlc19wcmUiLCAiU3RyZXNfcG9zdCIsIGZhY2V0ID0gRkFMU0UpIA0KYGBgDQoNCg0KYGBge3IgdF90ZXN0MiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTIsIHJlc3VsdHM9J2FzaXMnfQ0KIyMgU2ltcGxlIGJlZm9yZS1hZnRlciBhbmFseXNlcyB3aXRoIHQgdGVzdA0KY2F0KCIjIyMjIFZBUyBTdHJlc3MiKQ0KZnVuY190X2JveChEYXRhLCBpbmQgPSAiSUQiLCAiU3RyZXNfcHJlIiwgIlN0cmVzX3Bvc3QiLCBmYWNldCA9IFRSVUUpIA0KYGBgDQoNCg0KIyMgQ29ycmVsYXRpb25zOiBBbm90aW1wdXJpIC0gQ2FsaXRhdGUgQW1pbnRpcmkgKHdpdGhvdXQgUDYsIFA3KQ0KDQpgYGB7ciBjb3IxLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD05LCByZXN1bHRzPSdhc2lzJ30NCmRhdGVwbG90MSA8LSBEYXRhWywgYygiUCIsICJQcmltYXZhcmEiLCAiVmFyYSIsICJUb2FtbmEiLCAiSWFybmEiLCAiTWVkaWFfczEiLCAiTWVkaWFfczIiLCAiTWVkaWFfczMiLCAgIlNvY0RpaF9QYXJ0IiwgICJTb2NEaWhfRmFtTiIsICAiU29jRGloX0ZhbUluZCIsICAiU29jRGloX1ByaWV0IiwgICJTb2NEaWhfQW1pY2kiLCAgIlNvY0RpaF9OZWN1biIsICAiU29jRGloX0FudGFnIiwgICJTb2NEaWhfVG90QXByb3AiLCAgIlNvY0RpaF9Ub3ROZWFwcm9wIiwgIlNUQUlfVCIpXSANCm5hbWVzKGRhdGVwbG90MSkgPC0gYygiUCIsICJQcmltYXZhcmEiLCAiVmFyYSIsICJUb2FtbmEiLCAiSWFybmEiLCAiUzEtIFZhbGVudGEiLCAiUzIgLSBWaXZpZG5lc3MiLCAiUzMgLSBSZWxldmFudGEiLCAgIlBhcnRlbmVyIiwgICJGYW1pbGllIG51Y2xldSIsICAiRmFtaWxpZSBleHRpbnNhIiwgICJQcmlldGVuaSIsICAiQW1pY2kiLCAgIk5lY3Vub3NjdXRpIiwgICJBbnRhZ29uaXN0aSIsICAiVG90aSBBcHJvcGlhdGlpIiwgICJUb3RpIE5lYXByb3BpYXRpaSIsICJTVEFJX1QiKQ0KZGF0ZXBsb3QxIDwtIHN1YnNldChkYXRlcGxvdDEsIFAhPTYgJiBQIT03KQ0KDQpDT1IgPC0gSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChkYXRlcGxvdDFbLC0xXSkpICAgDQpNIDwtIENPUiRyDQpQX01BVCA8LSBDT1IkUA0KY29ycnBsb3Q6OmNvcnJwbG90KE0sIG1ldGhvZCA9ICJudW1iZXIiLCB0eXBlID0gInVwcGVyIiwgcC5tYXQgPSBQX01BVCwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiLCB0bC5jb2wgPSAiYmxhY2siLCB0bC5jZXggPSAuOSwgdGwuc3J0ID0gNDUpICANCmBgYA0KDQoNCmBgYHtyIGhlYXRfY29yMSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9OSwgcmVzdWx0cz0nYXNpcyd9DQpoZWF0X2Nvcl9wbG90bHkoZGF0ZXBsb3QxWywtMV0pDQpgYGANCg0KDQojIyBDb3JyZWxhdGlvbnM6IFBlcnNvbmFsaXR5IC0gUXVhbGl0aWVzIG9mIE1lbW9yaWVzICh3aXRob3V0IFA2LCBQNykNCg0KYGBge3IgY29yMiwgZmlnLndpZHRoPTExLCBmaWcuaGVpZ2h0PTExLCByZXN1bHRzPSdhc2lzJ30NCmRhdGVwbG90MiA8LSBEYXRhWywgYygyNCwgNDAsIDU2LCA4NzoxMjEsIDEyNildIA0KbmFtZXMoZGF0ZXBsb3QyKVsxOjNdIDwtIGMoIlMxLSBWYWxlbnRhIiwgIlMyIC0gVml2aWRuZXNzIiwgIlMzIC0gUmVsZXZhbnRhIikNCg0KQ09SIDwtIEhtaXNjOjpyY29ycihhcy5tYXRyaXgoZGF0ZXBsb3QyKSkgICANCk0gPC0gQ09SJHINClBfTUFUIDwtIENPUiRQDQpjb3JycGxvdDo6Y29ycnBsb3QoTSwgdHlwZSA9ICJ1cHBlciIsIHAubWF0ID0gUF9NQVQsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIiwgdGwuY29sID0gImJsYWNrIiwgdGwuY2V4ID0gLjcsIGNsLnBvcyA9ICJiIiwgdGwuc3J0ID0gNDUpDQpgYGANCg0KDQpgYGB7ciBoZWF0X2NvcjIsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTEyLCByZXN1bHRzPSdhc2lzJ30NCmhlYXRfY29yX3Bsb3RseShkYXRlcGxvdDIsIHhfdmFycyA9IG5hbWVzKGRhdGVwbG90MilbMTozXSwgeV92YXJzID0gbmFtZXMoZGF0ZXBsb3QyKVstKDE6MyldKQ0KYGBgDQoNCg0KIyMgQ29ycmVsYXRpb25zOiBTb2NpYWwgLSBQZXJzb25hbGl0eQ0KDQpgYGB7ciBjb3IzLCBmaWcud2lkdGg9MTEsIGZpZy5oZWlnaHQ9MTEsIHJlc3VsdHM9J2FzaXMnfQ0KZGF0ZXBsb3QzIDwtIERhdGFbLCBjKDEzMToxMzksIDg3OjEyMSldDQpuYW1lcyhkYXRlcGxvdDMpWzE6OV0gPC0gYygiUGFydGVuZXIiLCAgIkZhbWlsaWUgbnVjbGV1IiwgICJGYW1pbGllIGV4dGluc2EiLCAgIlByaWV0ZW5pIiwgICJBbWljaSIsICAiTmVjdW5vc2N1dGkiLCAgIkFudGFnb25pc3RpIiwgICJUb3RpIEFwcm9waWF0aWkiLCAgIlRvdGkgTmVhcHJvcGlhdGlpIikNCg0KQ09SIDwtIEhtaXNjOjpyY29ycihhcy5tYXRyaXgoZGF0ZXBsb3QzKSkgICANCk0gPC0gQ09SJHINClBfTUFUIDwtIENPUiRQDQpjb3JycGxvdDo6Y29ycnBsb3QoTSwgdHlwZSA9ICJ1cHBlciIsIHAubWF0ID0gUF9NQVQsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIiwgdGwuY29sID0gImJsYWNrIiwgdGwuY2V4ID0gLjcsIGNsLnBvcyA9ICJiIiwgdGwuc3J0ID0gNDUpDQpgYGANCg0KDQpgYGB7ciBoZWF0X2NvcjMsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTEyLCByZXN1bHRzPSdhc2lzJ30NCmhlYXRfY29yX3Bsb3RseShkYXRlcGxvdDMsIHhfdmFycyA9IG5hbWVzKGRhdGVwbG90MylbMTo5XSwgeV92YXJzID0gbmFtZXMoZGF0ZXBsb3QzKVstKDE6OSldKQ0KYGBgDQoNCg0KIyBTb2NpYWwNCg0KYGBge3Igc29jXzEsIHJlc3VsdHM9J2FzaXMnLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LCBmaWcuYWxpZ249J2NlbnRlcid9DQojIG5hbWVzKERhdGFbc3RyX2RldGVjdChjb2xuYW1lcyhEYXRhKSwgZml4ZWQoIlNvY0RpaCIsIGlnbm9yZV9jYXNlPVRSVUUpKV0pDQpEYXRhX3NvYyA8LQ0KICBEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KCJJRCIsICJQIiwgc3RhcnRzX3dpdGgoIlNvY0RpaCIpKSAlPiUNCiAgaGF2ZW46OnphcF9mb3JtYXRzKC4pICU+JSAgICAgICAgICAgICAgICAjIHRvIG5vdCBnZXQgd2FybmluZyAgDQogIGhhdmVuOjp6YXBfbGFiZWxzKC4pICU+JSAgICAgICAgICAgICAgICAgIyAiYXR0cmlidXRlcyBhcmUgbm90IGlkZW50aWNhbCBhY3Jvc3MgbWVhc3VyZSB2YXJpYWJsZXMiDQogIGhhdmVuOjp6YXBfd2lkdGhzKC4pICU+JSAgICAgICAgICAgICAgICAgIyBvbiBnYXRoZXIoKSBiZWNhdXNlIG9mIFNQU1MNCiAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2UoLiwgIlNvY0RpaF8iLCAiIikpKSAlPiUgDQogIGdhdGhlcihrZXkgPSAiVmFyaWFibGUiLCB2YWx1ZSA9ICJWYWx1ZSIsIC1JRCwgLVApIA0KICANCiMgQ3JlYXRlIGEgY3VzdG9tIGNvbG9yIHNjYWxlIGZvciBhbGwgQVNDUSBncmFwaHMNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbXlDb2xvcnMgPC0gYnJld2VyLnBhbCgxMCwiU2V0MSIpDQpuYW1lcyhteUNvbG9ycykgPC0gbGV2ZWxzKERhdGFfc29jJFZhcmlhYmxlKQ0KY29sU2NhbGUgPC0gc2NhbGVfY29sb3VyX21hbnVhbChuYW1lID0gIlZhcmlhYmxlIiwgdmFsdWVzID0gbXlDb2xvcnMpDQoNCiMgUGxvdA0KZ2dwdWJyOjpnZ3Zpb2xpbihkYXRhID0gRGF0YV9zb2MsIHggPSAiVmFyaWFibGUiLCB5ID0gIlZhbHVlIiwgZmlsbCA9ICJWYXJpYWJsZSIsDQogICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSwNCiAgICAgIHhsYWIgPSAiIiwgbGVnZW5kID0gIm5vbmUiKSArDQogIGNvbFNjYWxlICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNvbG9yIHNjYWxlIGhlcmUga2VlcCBjb25zaXN0ZW5jeSBvZiBjb2xvciB3aXRoIGZhY3RvciBsZXZlbA0KICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCAgY29sb3VyID0gImRhcmtyZWQiKSArICAgICAgICAgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQpgYGB7ciBzb2NfMiwgcmVzdWx0cz0nYXNpcycsIGZpZy5oZWlnaHQ9MjgsIGZpZy53aWR0aD05LCBmaWcuYWxpZ249J2NlbnRlcid9DQojIFBsb3QgZmFjZXRlZCBieSBQcm90b2NvbA0KcCA8LSANCiAgZ2dwdWJyOjpnZ3Zpb2xpbihkYXRhID0gRGF0YV9zb2MsIHggPSAiVmFyaWFibGUiLCB5ID0gIlZhbHVlIiwgZmlsbCA9ICJWYXJpYWJsZSIsDQogICAgICAgIGFkZCA9ICJib3hwbG90IiwgYWRkLnBhcmFtcyA9IGxpc3QoZmlsbCA9ICJ3aGl0ZSIpLA0KICAgICAgICB4bGFiID0gIiIsIGxlZ2VuZCA9ICJub25lIikgKw0KICAgICAgICAgDQogICAgY29sU2NhbGUgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29sb3Igc2NhbGUgaGVyZSBrZWVwIGNvbnNpc3RlbmN5IG9mIGNvbG9yIHdpdGggZmFjdG9yIGxldmVsDQogICAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgIGNvbG91ciA9ICJkYXJrcmVkIikgKyAgICAgICAgIA0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQoNCmdncHVicjo6ZmFjZXQocCwgZmFjZXQuYnkgPSAiUCIsIG5jb2wgPSAxLCBzY2FsZXMgPSAiZnJlZV94IikNCmBgYA0KDQoNCiMjIFNvY2lhbCAtIHRoaXMgZG9lc250IG1ha2Ugc2Vuc2UgDQoNCmBgYHtyIHNvY18zLCByZXN1bHRzPSdhc2lzJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KIyBQZXJmb3JtYW5jZUFuYWx5dGljczo6Y2hhcnQuQ29ycmVsYXRpb24oRGF0YVssIGMoOCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwKV0pDQoNCiMgRXhhbXBsZSBvZiBTaW1wc29ucyBQYXJhZG94DQpjb3Bsb3QoRGlmU3RyZXMgfiBTb2NEaWhfQW1pY2kgfCBNZWRpYV9zMSwNCiAgICAgICBkYXRhID0gRGF0YSwNCiAgICAgICByb3dzID0gMSwNCiAgICAgcGFuZWwgPSBmdW5jdGlvbih4LCB5LCAuLi4pIHsNCiAgICAgICAgICBwYW5lbC5zbW9vdGgoeCwgeSwgc3BhbiA9IC44LCBpdGVyID0gNSwuLi4pDQogICAgICAgICAgYWJsaW5lKGxtKHkgfiB4KSwgY29sID0gImJsdWUiKX0pDQpgYGANCg0KDQojIFZhcnN0YSBBbWludCAtIFAxLFAyLFAzDQoNCmBgYHtyIGRpZnN0cmVzX3ZhcnN0YWFtaW50LCByZXN1bHRzPSdhc2lzJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KRGF0YV9QMVAyUDMgPC0gDQogIERhdGEgJT4lDQogIGZpbHRlcihQICVpbiUgYygiMSIsICIyIiwgIjMiKSkgJT4lDQogIG11dGF0ZShNZWRfYW1pbnR2YXJzdGEgPSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihNZWRfYW1pbnR2YXJzdGEpKSwNCiAgICAgICAgIERpZl9NZWRfYW1pbnR2YXJzdGEgPSBWYXJzdGEgLSBNZWRfYW1pbnR2YXJzdGEpDQoNClBlcmZvcm1hbmNlQW5hbHl0aWNzOjpjaGFydC5Db3JyZWxhdGlvbihEYXRhX1AxUDJQM1ssIGMoOCwgODUsIDEyMiwgMTQ4KV0pDQoNCmNvcGxvdChEaWZTdHJlcyB+IERpZl9NZWRfYW1pbnR2YXJzdGEgfCBNZWRpYV9zMSwNCiAgICAgICBkYXRhID0gRGF0YV9QMVAyUDMsDQogICAgICAgcm93cyA9IDEsDQogICAgIHBhbmVsID0gZnVuY3Rpb24oeCwgeSwgLi4uKSB7DQogICAgICAgICAgcGFuZWwuc21vb3RoKHgsIHksIHNwYW4gPSAuOCwgaXRlciA9IDUsLi4uKQ0KICAgICAgICAgIGFibGluZShsbSh5IH4geCksIGNvbCA9ICJibHVlIil9KQ0KYGBgDQoNCg0KIyBQcm90b2NvbCAzIC0gU29jaWFsDQoNCmBgYHtyIHAzX3NvYywgcmVzdWx0cz0nYXNpcycsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIGZpZy5hbGlnbj0nY2VudGVyJ30NCkRhdGFfUDMgPC0gDQogIERhdGEgJT4lDQogIGZpbHRlcihQID09ICIzIikNCg0KUGVyZm9ybWFuY2VBbmFseXRpY3M6OmNoYXJ0LkNvcnJlbGF0aW9uKERhdGFfUDNbLCBjKDgsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCldKQ0KDQojIGNvcGxvdChTb2NEaWhfQW1pY2kgfiBEaWZTdHJlcyB8IE1lZGlhX3MxLCANCiMgICAgICAgIGRhdGEgPSBEYXRhLA0KIyAgICAgICAgY29sdW1ucyA9IDMsDQojICAgICAgcGFuZWwgPSBmdW5jdGlvbih4LCB5LCAuLi4pIHsNCiMgICAgICAgICAgIHBhbmVsLnNtb290aCh4LCB5LCBzcGFuID0gLjgsIGl0ZXIgPSA1LC4uLikNCiMgICAgICAgICAgIGFibGluZShsbSh5IH4geCksIGNvbCA9ICJibHVlIikgfSApDQpgYGANCg0KDQojIFByb3RvY29sIDMgLSBWYXJzdGEgQW1pbnQNCg0KYGBge3IgcDNfZGlmc3RyZXNfdmFyc3RhYW1pbnQsIHJlc3VsdHM9J2FzaXMnLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBmaWcuYWxpZ249J2NlbnRlcid9DQpEYXRhX1AzIDwtIA0KICBEYXRhICU+JQ0KICBmaWx0ZXIoUCA9PSAiMyIpICU+JQ0KICBtdXRhdGUoTWVkX2FtaW50dmFyc3RhID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoTWVkX2FtaW50dmFyc3RhKSksDQogICAgICAgICBEaWZfTWVkX2FtaW50dmFyc3RhID0gVmFyc3RhIC0gTWVkX2FtaW50dmFyc3RhKQ0KDQpQZXJmb3JtYW5jZUFuYWx5dGljczo6Y2hhcnQuQ29ycmVsYXRpb24oRGF0YV9QM1ssIGMoOCwgODUsIDEyMiwgMTQ4KV0pDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCjxicj4NCg0KDQoNCg0KDQo8IS0tIFNlc3Npb24gSW5mbyBhbmQgTGljZW5zZSAtLT4NCg0KPGJyPg0KDQojIFNlc3Npb24gSW5mbw0KYGBge3Igc2Vzc2lvbl9pbmZvLCBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30NCnNlc3Npb25JbmZvKCkgICAgDQpgYGANCg0KPCEtLSBGb290ZXIgLS0+DQombmJzcDsNCjxociAvPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPkEgd29yayBieSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vQ2xhdWRpdVBhcGFzdGVyaS8iPkNsYXVkaXUgUGFwYXN0ZXJpPC9hPjwvcD4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48c3BhbiBzdHlsZT0iY29sb3I6ICM4MDgwODA7Ij48ZW0+Y2xhdWRpdS5wYXBhc3RlcmlAZ21haWwuY29tPC9lbT48L3NwYW4+PC9wPg0KJm5ic3A7DQo=
6 Social
6.1 Social - this doesnt make sense