Define functions
## Define function that recodes to numeric, but watches out to coercion to not introduce NAs
colstonumeric <- function(df){
tryCatch({
df_num <- as.data.frame(
lapply(df,
function(x) { as.numeric(as.character(x))}))
},warning = function(stop_on_warning) {
message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
})
}
##
## Define function that reverse codes items
ReverseCode <- function(df, tonumeric = FALSE, min = NULL, max = NULL) {
if(tonumeric) df <- colstonumeric(df)
df <- (max + min) - df
}
##
## Define function that scores only rows with less than 10% NAs (returns NA if all or above threshold percentage of rows are NA); can reverse code if vector of column indexes and min, max are provided.
ScoreLikert <- function(df, napercent = .1, tonumeric = FALSE, reversecols = NULL, min = NULL, max = NULL) {
reverse_list <- list(reversecols = reversecols, min = min, max = max)
reverse_check <- !sapply(reverse_list, is.null)
# Recode to numeric, but watch out to coercion to not introduce NAs
colstonumeric <- function(df){
tryCatch({
df_num <- as.data.frame(
lapply(df,
function(x) { as.numeric(as.character(x))}))
},warning = function(stop_on_warning) {
message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
})
}
if(tonumeric) df <- colstonumeric(df)
if(all(reverse_check)){
df[ ,reversecols] <- (max + min) - df[ ,reversecols]
}else if(any(reverse_check)){
stop("Insuficient info for reversing. Please provide: ", paste(names(reverse_list)[!reverse_check], collapse = ", "))
}
ifelse(rowSums(is.na(df)) > ncol(df) * napercent,
NA,
rowSums(df, na.rm = TRUE) * NA ^ (rowSums(!is.na(df)) == 0)
)
}
##
## Func t test si boxplot simplu
func_t_box <- function(df, ind, pre_var, post_var){
vars <- c(ind, pre_var, post_var) # to avoid new tidyverse error of ambiguity due to external vectos
df_modif <-
df %>%
dplyr::select(tidyselect::all_of(vars)) %>%
tidyr::drop_na() %>%
gather(tidyselect::all_of(pre_var), tidyselect::all_of(post_var), key = "Cond", value = "value") %>%
mutate_at(vars(c(1, 2)), as.factor) %>%
mutate(Cond = factor(Cond, levels = c(pre_var, post_var)))
stat_comp <- ggpubr::compare_means(value ~ Cond, data = df_modif, method = "t.test", paired = TRUE)
stat_comp2 <-
df_modif %>%
do(tidy(t.test(.$value ~ .$Cond,
paired = TRUE,
data=.)))
plot <-
ggpubr::ggpaired(df_modif, x = "Cond", y = "value", id = ind,
color = "Cond", line.color = "gray", line.size = 0.4,
palette = c("#00AFBB", "#FC4E07"), legend = "none") +
stat_summary(fun.data = mean_se, colour = "darkred") +
ggpubr::stat_compare_means(method = "t.test", paired = TRUE, label.x = as.numeric(df_modif$Cond)-0.4, label.y = max(df_modif$value)+0.5) +
ggpubr::stat_compare_means(method = "t.test", paired = TRUE, label = "p.signif", comparisons = list(c(pre_var, post_var)))
cat(paste0("#### ", pre_var, " ", post_var, "\n", "\n"))
print(stat_comp)
print(stat_comp2)
print(plot)
}
samplesize_pairedttest <- function(df, pre_var, post_var){
vars <- c(pre_var, post_var) # to avoid new tidyverse error of ambiguity due to external vectors
df_modif <-
df %>%
dplyr::select(tidyselect::all_of(vars)) %>%
tidyr::drop_na() %>%
gather(tidyselect::all_of(pre_var), tidyselect::all_of(post_var), key = "Cond", value = "value") %>%
mutate(Cond = factor(Cond, levels = c(pre_var, post_var)))
cat("## Cohen's d \n")
eff_size_table <-
df_modif %>%
cohens_d(value ~ Cond, paired = TRUE) %>%
print()
eff_size <- as.numeric(eff_size_table$effsize)
cat("## Sample Size estimation \n")
sample_size_table <-
pwr::pwr.t.test(d = eff_size, sig.level = .05, power = .8, type = "paired", alternative = "two.sided")
sample_size_table %>% broom::tidy() %>% print()
plot(sample_size_table)
}
# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(broom)
# library(emmeans)
# library(rlang)
# Function ANCOVAPost
# Takes Long Data
ANCOVAPost_func <-
function(data, id_var,
time_var, pre_label, post_label,
value_var = scores, cond_var,
assum_check = TRUE, posthoc = TRUE,
p_adjust_method = "bonferroni"){
id_var_enq <- rlang::enquo(id_var)
id_var_name <- rlang::as_name(id_var_enq)
time_var_enq <- rlang::enquo(time_var)
time_var_name <- rlang::as_name(time_var_enq)
pre_var_enq <- rlang::enquo(pre_label)
pre_var_name <- rlang::as_name(pre_var_enq)
post_var_enq <- rlang::enquo(post_label)
post_var_name <- rlang::as_name(post_var_enq)
cond_var_enq <- rlang::enquo(cond_var)
cond_var_name <- rlang::as_name(cond_var_enq)
value_var_enq <- rlang::enquo(value_var)
value_var_name <- rlang::as_name(value_var_enq)
data_wider <-
data %>%
dplyr::select(!!id_var_enq, !!time_var_enq, !!cond_var_enq, !!value_var_enq) %>%
spread(key = time_var_name, value = value_var_name) # %>% # if need to compute change score statistics go from here
# mutate(difference = !!post_var_enq - !!pre_var_enq)
# Assumptions
if(assum_check){
cat("\n Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group) \n")
# Create a scatter plot between the covariate (i.e., pretest) and the outcome variable (i.e., posttest)
scatter_lin <-
ggscatter(data_wider, x = pre_var_name, y = post_var_name, color = cond_var_name,
add = "reg.line", title = "Linearity assumption") +
stat_regline_equation(aes(label = paste(..eq.label.., ..rr.label.., sep = "~~~~"), color = !!cond_var_enq))
cat("\n Homogeneity of regression slopes (interaction term is n.s.) \n")
data_wider %>%
anova_test(as.formula(paste0(post_var_name, " ~ ", cond_var_name, " * ", pre_var_name))) %>%
print()
cat("\n Normality of residuals (Model diagnostics & Shapiro Wilk) \n")
# Fit the model, the covariate goes first
model <-
lm(as.formula(paste0(post_var_name, " ~ ", cond_var_name, " + ", pre_var_name)),
data = data_wider)
cat("\n Inspect the model diagnostic metrics \n")
model.metrics <-
augment(model) %>%
dplyr::select(-.hat, -.sigma, -.fitted, -.se.fit) %>% # Remove details
print()
cat("\n Normality of residuals (Shapiro Wilk p>.05) \n")
shapiro_test(model.metrics$.resid) %>%
print()
cat("\n Homogeneity of variances (Levene’s test p>.05) \n")
model.metrics %>%
levene_test(as.formula(paste0(".resid", " ~ ", cond_var_name)) ) %>%
print()
cat("\n Outliers (needs to be 0) \n")
model.metrics %>%
filter(abs(.std.resid) > 3) %>%
as.data.frame() %>%
print()
}
cat("\n ANCOVAPost \n")
res_ancova <-
data_wider %>%
anova_test(as.formula(paste0(post_var_name, " ~ ", pre_var_name, " + ", cond_var_name))) # the covariate needs to be first term
get_anova_table(res_ancova) %>% print()
cat("\n Pairwise comparisons \n")
pwc <-
data_wider %>%
emmeans_test(as.formula(paste0(post_var_name, " ~ ", cond_var_name)),
covariate = !!pre_var_enq,
p.adjust.method = p_adjust_method)
pwc %>% print()
cat("\n Display the adjusted means of each group, also called as the estimated marginal means (emmeans) \n")
get_emmeans(pwc) %>% print()
# Visualization: line plots with p-values
pwc <-
pwc %>%
add_xy_position(x = cond_var_name, fun = "mean_se")
line_plot <-
ggline(get_emmeans(pwc), x = cond_var_name, y = "emmean") +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2) +
stat_pvalue_manual(pwc, hide.ns = TRUE, tip.length = FALSE) +
labs(subtitle = get_test_label(res_ancova, detailed = TRUE),
caption = get_pwc_label(pwc))
if(assum_check){
list(scatter_lin, line_plot)
}else{
line_plot
}
}
# ex.
# ANCOVAPost_func(new_anxiety, time_var = time, pre_label = pretest, post_label = posttest,
# value_var = scores, cond_var = group, assum_check = TRUE, p_adjust_method = "bonferroni")
# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(rlang)
# Define Function for Mixed Anova
tw_mixedANOVA_func <-
function(data, id_var, cond_var, time_var, value_var,
assum_check = TRUE, posthoc_sig_interac = FALSE, posthoc_ns_interac = FALSE,
p_adjust_method = "bonferroni"){
# input dataframe needs to have columns names diffrent from "variable" and "value" because it collides with rstatix::shapiro_test
id_var_enq <- rlang::enquo(id_var)
cond_var_enq <- rlang::enquo(cond_var)
cond_var_name <- rlang::as_name(cond_var_enq)
time_var_enq <- rlang::enquo(time_var)
time_var_name <- rlang::as_name(time_var_enq)
value_var_enq <- rlang::enquo(value_var)
value_var_name <- rlang::as_name(value_var_enq)
data <- # need to subset becuase of strange contrasts error in anova_test()
data %>%
dplyr::select(!!id_var_enq, !!time_var_enq, !!cond_var_enq, !!value_var_enq)
# Assumptions
if(assum_check){
cat("\n Outliers \n")
data %>%
dplyr::group_by(!!time_var_enq, !!cond_var_enq) %>%
rstatix::identify_outliers(!!value_var_enq) %>% # outliers (needs to be 0)
print()
cat("\n Normality assumption (p>.05) \n")
data %>%
dplyr::group_by(!!time_var_enq, !!cond_var_enq) %>%
rstatix::shapiro_test(!!value_var_enq) %>% # normality assumption (p>.05)
print()
qq_plot <-
ggpubr::ggqqplot(data = data, value_var_name, ggtheme = theme_bw(), title = "QQ Plot") +
ggplot2::facet_grid(vars(!!time_var_enq), vars(!!cond_var_enq), labeller = "label_both") # QQ plot
cat("\n Homogneity of variance assumption - Levene’s test (p>.05) \n")
data %>%
group_by(!!time_var_enq ) %>%
levene_test(as.formula(paste0(value_var_name, " ~ ", cond_var_name))) %>%
print()
cat("\n Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001) \n")
box_m(data = data[, value_var_name, drop = FALSE], group = data[, cond_var_name, drop = TRUE]) %>%
print
}
# Two-way rmANOVA - check for interaction (ex. F(2, 22) = 30.4, p < 0.0001)
cat("\n Two-way rmANOVA \n")
res_aov <-
anova_test(data = data, dv = !!value_var_enq, wid = !!id_var_enq, # automatically does sphericity Mauchly’s test
within = !!time_var_enq, between = !!cond_var_enq)
get_anova_table(res_aov) %>% # ges: Greenhouse-Geisser sphericity correction is automatically applied to factors violating the sphericity assumption
print()
# ------------------------------------------------------------------------
#- Procedure for a significant two-way interaction -
if(posthoc_sig_interac){
cat("\n Effect of group at each time point - One-way ANOVA\n")
one_way <-
data %>%
group_by(!!time_var_enq) %>%
anova_test(dv = !!value_var_enq, wid = !!id_var_enq, between = !!cond_var_enq) %>%
get_anova_table() %>%
adjust_pvalue(method = p_adjust_method)
one_way %>% print()
cat("\n Pairwise comparisons between group levels \n")
pwc <-
data %>%
group_by(!!time_var_enq) %>%
pairwise_t_test(as.formula(paste0(value_var_name, " ~ ", cond_var_name)),
p.adjust.method = p_adjust_method)
pwc %>% print()
cat("\n Effect of time at each level of exercises group - One-way ANOVA \n")
one_way2 <-
data %>%
group_by(!!cond_var_enq) %>%
anova_test(dv = !!value_var_enq, wid = !!id_var_enq, within = !!time_var_enq) %>%
get_anova_table() %>%
adjust_pvalue(method = p_adjust_method)
one_way2 %>% print()
cat("\n Pairwise comparisons between time points at each group levels (we have repeated measures by time) \n")
pwc2 <-
data %>%
group_by(!!cond_var_enq) %>%
pairwise_t_test(
as.formula(paste0(value_var_name, " ~ ", time_var_name)), # paste formula, not quosure
paired = TRUE,
p.adjust.method = p_adjust_method
)
pwc2 %>% print()
}
#- Procedure for non-significant two-way interaction-
# If the interaction is not significant, you need to interpret the main effects for each of the two variables: treatment and time.
if(posthoc_ns_interac){
cat("\n Comparisons for treatment variable \n")
pwc_cond <-
data %>%
pairwise_t_test(
as.formula(paste0(value_var_name, " ~ ", cond_var_name)), # paste formula, not quosure
paired = FALSE,
p.adjust.method = p_adjust_method
)
pwc_cond %>% print()
cat("\n Comparisons for time variable \n")
pwc_time <-
data %>%
pairwise_t_test(
as.formula(paste0(value_var_name, " ~ ", time_var_name)), # paste formula, not quosure
paired = TRUE,
p.adjust.method = p_adjust_method
)
pwc_time %>% print()
}
# Visualization
bx_plot <-
ggboxplot(data, x = time_var_name, y = value_var_name,
color = cond_var_name, palette = "jco")
pwc <-
pwc %>%
add_xy_position(x = time_var_name)
bx_plot <-
bx_plot +
stat_pvalue_manual(pwc, tip.length = 0, hide.ns = TRUE) +
labs(
subtitle = get_test_label(res_aov, detailed = TRUE),
caption = get_pwc_label(pwc)
)
if(assum_check){
list(qq_plot, bx_plot)
}else{
bx_plot
}
}
# ex. - run on long format
# tw_mixedANOVA_func(data = anxiety, id_var = id, cond_var = group, time_var = time, value_var = score,
# posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)
Read, Clean, Recode
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Read, Clean, Recode, Unite
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Read files
folder <- "C:/Users/Mihai/Desktop/R Notebooks/notebooks/PA4-report"
old_file <- "Date_pt_analiza_PA4online.xlsx"
file <- "Date_pt_analiza_PA4online - Final2.xlsx"
setwd(folder)
# ID df
id_df <- rio::import(file.path(folder, file),
skip = 1, which = "ID-uri atribuite")
id_df <-
id_df %>%
dplyr::mutate(ID = stringr::str_replace_all(ID, fixed(" "), "")) # remove white spaces
all(id_df$ID == toupper(id_df$ID)) # check if all are upper case
id_df[, "e-mail"] <- tolower(id_df[, "e-mail"])
id_df <- id_df[!duplicated(id_df),] # 36 duplicated, 115 unique
firstform_df <- rio::import(file.path(folder, file),
skip = 0, which = "Formular de înscriere și consim")
firstform_df <- firstform_df[, -length(firstform_df)] # a column "work" was added to the end
old_file_firstform_df <- rio::import(file.path(folder, old_file),
skip = 0, which = "Formular de înscriere și consim")
if(all.equal(colnames(firstform_df), colnames(old_file_firstform_df))) {rm(old_file_firstform_df)}
colnames(firstform_df)[7] <- "e-mail"
firstform_df[, "e-mail"] <- tolower(firstform_df[, "e-mail"])
baseline_df <- dplyr::left_join(id_df, firstform_df, by = "e-mail")
baseline_df <-
baseline_df %>%
dplyr::select(colnames(firstform_df), everything()) # move cols from id_df to back so we have matching cols index for baseline_df & firstform_df
all.equal(colnames(baseline_df)[1:172], colnames(firstform_df)[1:172]) # check if colnames match, except ID and name that where added
table(baseline_df$ID) # some IDs are doubled
## Settings
cutoffPCL <- 32 # literature: 31-33 or 38
algPCL <- data.frame(B = 1, C = 1, D = 2, E = 2)
algPCL_subclin <- data.frame(B = 1, C = 1, D = 1, E = 1)
cutoffMBI_Ex <- 2.20
cutoffMBI_Cy <- 2
##
## Data
Data <- baseline_df
##
# Define column index: index = col index; itemindex = index of item in questionnaire
indexSIG <- 60:67 - 10 # modified in new table by 10
indexMBI <- 68:83 - 10
indexPCL <- 159:178 - 10
itemindexMBI_Ex <- c(1, 3, 5, 11, 14)
itemindexMBI_Cy <- c(2, 7, 8, 13, 15)
itemindexMBI_Pe <- c(4, 6, 9, 10, 12, 16)
# Rename columns
# names(Data)[1:12] <- stringr::str_replace_all(names(Data)[1:12], "[[:blank:]]", "_")
# names(Data)[17] <- "Real_Email"
# names(Data)[18] <- "Real_Tel"
# names(Data)[19] <- "Real_Name"
# names(Data)[50] <- "Real_Age_categ"
names(Data)[9] <- "nume"
names(Data)[40] <- "Age_categ"
names(Data)[41] <- "Sex"
names(Data)[names(Data) %in% names(Data[, indexSIG])] <- c(sprintf("SIG_%01d", seq(1, 8)))
names(Data)[names(Data) %in% names(Data[, indexMBI])] <- c(sprintf("MBI_%01d", seq(1, 16)))
names(Data)[names(Data) %in% names(Data[, indexPCL])] <- c(sprintf("PCL_%01d", seq(1, 20)))
# Data <-
# Data %>%
# dplyr::filter(Response_Status == "completed") # select only complete cases
# Recode
## Define function that recodes to numeric, but watches out to coercion to not introduce NAs
colstonumeric <- function(df){
tryCatch({
df_num <- as.data.frame(
lapply(df,
function(x) { as.numeric(as.character(x))}))
},warning = function(stop_on_warning) {
message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
})
}
##
## Define function that reverse codes items
ReverseCode <- function(df, tonumeric = FALSE, min = NULL, max = NULL) {
if(tonumeric) df <- colstonumeric(df)
df <- (max + min) - df
}
##
# lapply(Data[,indexPCL], unique)
Data[ ,indexPCL][ Data[ ,indexPCL] == "deloc"] <- "0"
Data[ ,indexPCL][ Data[ ,indexPCL] == "puțin"] <- "1"
Data[ ,indexPCL][ Data[ ,indexPCL] == "moderat"] <- "2"
Data[ ,indexPCL][ Data[ ,indexPCL] == "mult"] <- "3"
Data[ ,indexPCL][ Data[ ,indexPCL] == "foarte mult"] <- "4"
Data[ ,indexPCL][ Data[ ,indexPCL] == "Not Answered"] <- NA
Data[ ,indexSIG][ Data[ ,indexSIG] == "NU"] <- "0"
Data[ ,indexSIG][ Data[ ,indexSIG] == "?"] <- "1.5"
Data[ ,indexSIG][ Data[ ,indexSIG] == "DA"] <- "3"
Data[ ,indexSIG][ Data[ ,indexSIG] == "Not Answered"] <- NA
Data[ ,indexMBI] <- data.frame(lapply(Data[ ,indexMBI],
function(x) {gsub(".*Niciodat.*", "0", x)}), stringsAsFactors = FALSE)
Data[ ,indexMBI] <- data.frame(lapply(Data[ ,indexMBI],
function(x) {gsub(".*Zilnic.*", "6", x)}), stringsAsFactors = FALSE)
Data[ ,indexMBI][ Data[ ,indexMBI] == "Not Answered"] <- NA
Data[, indexSIG] <- colstonumeric(Data[, indexSIG])
Data[, indexMBI] <- colstonumeric(Data[, indexMBI])
Data[, indexPCL] <- colstonumeric(Data[, indexPCL])
# Scores
## Define function that scores only rows with less than 10% NAs (returns NA if all or above threshold percentage of rows are NA); can reverse code if vector of column indexes and min, max are provided.
ScoreLikert <- function(df, stat = "sum", natozero = FALSE, napercent = .1, tonumeric = FALSE, reversecols = NULL, min = NULL, max = NULL) {
reverse_list <- list(reversecols = reversecols, min = min, max = max)
reverse_check <- !sapply(reverse_list, is.null)
# Recode to numeric, but watch out to coercion to not introduce NAs
colstonumeric <- function(df){
tryCatch({
df_num <- as.data.frame(
lapply(df,
function(x) { as.numeric(as.character(x))}))
},warning = function(stop_on_warning) {
message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
})
}
if(tonumeric) df <- colstonumeric(df)
if(all(reverse_check)){
df[ ,reversecols] <- (max + min) - df[ ,reversecols]
}else if(any(reverse_check)){
stop("Insuficient info for reversing. Please provide: ", paste(names(reverse_list)[!reverse_check], collapse = ", "))
}
if(tonumeric) df <- colstonumeric(df)
if(natozero) df[is.na(df)] <- 0 # NAs to 0 can help when stat = "mean" with na.rm = T because it keeps denominator constant
if(stat == "sum"){
df_res <- ifelse(rowSums(is.na(df)) > ncol(df) * napercent,
NA,
rowSums(df, na.rm = TRUE) * NA ^ (rowSums(!is.na(df)) == 0))
}
if(stat == "mean"){
df_res <- ifelse(rowSums(is.na(df)) > ncol(df) * napercent,
NA,
rowMeans(df, na.rm = TRUE) * NA ^ (rowSums(!is.na(df)) == 0))
}
return(df_res)
}
##
# Score PCL
Data$PCL_Total <- ScoreLikert(Data[, indexPCL], napercent = .3) # NA if NA threshold is exceeded
Data$PCL_B <- ScoreLikert(Data[, c(sprintf("PCL_%01d", 1:5))], napercent = 1) # do nothing if NA threshold is exceeded
Data$PCL_C <- ScoreLikert(Data[, c(sprintf("PCL_%01d", 6:7))], napercent = 1)
Data$PCL_D <- ScoreLikert(Data[, c(sprintf("PCL_%01d", 8:14))], napercent = 1)
Data$PCL_E <- ScoreLikert(Data[, c(sprintf("PCL_%01d", 15:20))], napercent = 1)
# Score SIG
Data$SIG_Total <- ScoreLikert(Data[, indexSIG], napercent = .3)
# Score MBI
Data$MBI_Total <- ScoreLikert(Data[, indexMBI], napercent = .3, stat = "mean", natozero = TRUE)
Data$MBI_Ex <- ScoreLikert(Data[, c(sprintf("MBI_%01d", itemindexMBI_Ex))], napercent = 1, stat = "mean", natozero = TRUE)
Data$MBI_Cy <- ScoreLikert(Data[, c(sprintf("MBI_%01d", itemindexMBI_Cy))], napercent = 1, stat = "mean", natozero = TRUE)
Data$MBI_Pe <- ScoreLikert(Data[, c(sprintf("MBI_%01d", itemindexMBI_Pe))], napercent = 1, stat = "mean", natozero = TRUE)
# PCL Diagnostic Algorithm
itemsPCL_B <- c(sprintf("PCL_%01d", 1:5))
itemsPCL_C <- c(sprintf("PCL_%01d", 6:7))
itemsPCL_D <- c(sprintf("PCL_%01d", 8:14))
itemsPCL_E <- c(sprintf("PCL_%01d", 15:20))
DataPCLAlg <-
Data %>%
dplyr::select(tidyselect::all_of(indexPCL)) %>%
dplyr::mutate_all(
funs(case_when(
. >=2 ~ 1,
# . <2 ~ 0,
is.na(.) ~ 0,
TRUE ~ 0))) %>%
mutate(PCL_CritB = case_when(rowSums(.[,itemsPCL_B], na.rm = TRUE) >= algPCL$B ~ 1, # algPCL <- data.frame(B = 1, C = 1, D = 2, E = 2)
# rowSums(.[,itemsPCL_B], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_CritC = case_when(rowSums(.[,itemsPCL_C], na.rm = TRUE) >= algPCL$C ~ 1,
# rowSums(.[,itemsPCL_C], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_CritD = case_when(rowSums(.[,itemsPCL_D], na.rm = TRUE) >= algPCL$D ~ 1,
# rowSums(.[,itemsPCL_D], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_CritE = case_when(rowSums(.[,itemsPCL_E], na.rm = TRUE) >= algPCL$E ~ 1,
# rowSums(.[,itemsPCL_E], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_Alg = case_when(PCL_CritB == 1 & PCL_CritC == 1 & PCL_CritD == 1 & PCL_CritE == 1 ~ 1,
TRUE ~ 0))
Data$PCLAlg <- DataPCLAlg$PCL_Alg
DataPCLAlg_subclin <-
Data %>%
dplyr::select(tidyselect::all_of(indexPCL)) %>%
dplyr::mutate_all(
funs(case_when(
. >=2 ~ 1,
# . <2 ~ 0,
is.na(.) ~ 0,
TRUE ~ 0))) %>%
mutate(PCL_CritB = case_when(rowSums(.[,itemsPCL_B], na.rm = TRUE) >= algPCL_subclin$B ~ 1,
# rowSums(.[,itemsPCL_B], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_CritC = case_when(rowSums(.[,itemsPCL_C], na.rm = TRUE) >= algPCL_subclin$C ~ 1,
# rowSums(.[,itemsPCL_C], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_CritD = case_when(rowSums(.[,itemsPCL_D], na.rm = TRUE) >= algPCL_subclin$D ~ 1,
# rowSums(.[,itemsPCL_D], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_CritE = case_when(rowSums(.[,itemsPCL_E], na.rm = TRUE) >= algPCL_subclin$E ~ 1,
# rowSums(.[,itemsPCL_E], na.rm = TRUE) <1 ~ 0,
TRUE ~ 0)) %>%
mutate(PCL_Alg_subclin = case_when(PCL_CritB == 1 & PCL_CritC == 1 & PCL_CritD == 1 & PCL_CritE == 1 ~ 1,
TRUE ~ 0))
Data$PCLAlg_subclin <- DataPCLAlg_subclin$PCL_Alg_subclin
Data$MBI_Ex_cut <- ifelse(Data$MBI_Ex >= cutoffMBI_Ex, 1, 0)
Data$MBI_Cy_cut <- ifelse(Data$MBI_Cy >= cutoffMBI_Cy, 1, 0)
# Global Screening & Groups
df_screening <- Data[,c("ID", "nume", "e-mail", "Age_categ", "Sex",
"SIG_Total", "MBI_Ex", "MBI_Cy", "MBI_Ex_cut", "MBI_Cy_cut",
"PCL_Total", "PCL_B", "PCL_C", "PCL_D", "PCL_E", "PCLAlg", "PCLAlg_subclin")]
# Check same result with screening done on Google Colab
# check_g <- rio::import(file.path(folder, "check_screening", "PA4_Screening 2021-01-18 18_03_40CHECK.xlsx"))
# check_l <- df_screening
#
# check_merge <- full_join(check_l, check_g, by = c("e-mail" = "Real_Email"))
#
# names_l <- paste0(c("SIG_Total", "MBI_Ex_cut", "MBI_Cy_cut", "PCL_Total", "PCL_B", "PCL_C", "PCL_D", "PCL_E", "PCLAlg", "PCLAlg_subclin"), ".x")
# names_g <- paste0(c("SIG_Total", "MBI_Ex_cut", "MBI_Cy_cut", "PCL_Total", "PCL_B", "PCL_C", "PCL_D", "PCL_E", "PCLAlg", "PCLAlg_subclin"), ".y")
#
# all.equal(check_merge[, names_l], check_merge[, names_l])
############
[1] "6A" "9C"
#####
ovelap_to_ptsd <- c("6X", "19X", "11R", "10C", "14C", "3D")
ovelap_to_burn <- c("9X", "12X", "8R", "12B", "13B", "5C", "17R")
ids_ptsd <-
df_screening %>%
dplyr::filter(PCLAlg == 1) %>%
dplyr::select(ID) %>%
dplyr::filter(!(ID %in% ovelap_to_burn)) %>%
dplyr::pull()
ids_burn <-
df_screening %>%
dplyr::filter(MBI_Ex_cut == 1, MBI_Cy_cut == 1) %>%
dplyr::select(ID) %>%
dplyr::filter(!(ID %in% ovelap_to_ptsd)) %>%
dplyr::pull()
ids_old <-
df_screening %>%
dplyr::filter(Age_categ == "peste 65 ani") %>%
dplyr::select(ID) %>%
dplyr::pull()
ids_normal <-
df_screening %>%
dplyr::filter(!(ID %in% c(ids_ptsd, ids_burn, ids_old))) %>%
dplyr::select(ID) %>%
dplyr::pull()
# CHECKS
length(unique(ids_ptsd)); length(unique(ids_ptsd)) == length(ids_ptsd) # no duplicate IDs
[1] 22
[1] TRUE
[1] 25
[1] TRUE
[1] 8
[1] TRUE
[1] 52
[1] TRUE
character(0)
[1] 47
[1] "5A" "6A" "2X" "6X" "13X" "17X" "19X" "9R" "11R" "2B" "6B" "3C" "10C" "13C" "14C" "15C" "16C" "3D" "8D" "10D" "6E" "18R"
[1] "3X" "5X" "8X" "9X" "12X" "15X" "25X" "28X" "8R" "12R" "1B" "8B" "9B" "10B" "12B" "13B" "14B" "2C" "5C" "6C" "7C" "8C" "4D" "5D" "17R"
character(0)
character(0)
[1] TRUE
Outcome Measures
Dictator Game
# DG df
dg_df_pre <- rio::import(file.path(folder, file),
skip = 0, which = "DictatorGame pre")
dg_df_pre <-
dg_df_pre %>%
janitor::remove_empty("rows")
colnames(dg_df_pre)[4] <- "ID"
dg_df_pre <-
dg_df_pre %>%
dplyr::mutate(ID = stringr::str_replace_all(ID, fixed(" "), "")) %>% # remove white spaces
dplyr::mutate(ID = toupper(ID)) # to upper
all(dg_df_pre$ID == toupper(dg_df_pre$ID))
dg_df_post <- rio::import(file.path(folder, file),
skip = 0, which = "DictatorGame post")
dg_df_post <-
dg_df_post %>%
janitor::remove_empty("rows")
colnames(dg_df_post)[4] <- "ID"
dg_df_post <-
dg_df_post %>%
dplyr::mutate(ID = stringr::str_replace_all(ID, fixed(" "), "")) %>% # remove white spaces
dplyr::mutate(ID = toupper(ID)) # to upper
all(dg_df_post$ID == toupper(dg_df_post$ID))
colnames(dg_df_pre)[5:8] <- sprintf("DG_%d", 1:4)
colnames(dg_df_pre)[2] <- "Response_Status"
colnames(dg_df_post)[5:8] <- sprintf("DG_%d", 1:4)
colnames(dg_df_post)[3] <- "Response_Status"
dg_df_pre <-
dg_df_pre %>%
dplyr::mutate(`Date Modified` = lubridate::ymd_hms(format(`Date Modified`, "%Y-%m-%d %H:%M:%S", tz = "UTC"))) %>%
mutate_if(is.character, ~na_if(., "Not Answered")) %>%
dplyr::filter(Response_Status == "completed") %>%
dplyr::filter(!stringr::str_detect(ID, "PA4OXT")) %>%
dplyr::filter(!stringr::str_detect(ID, "PA4RMN"))
dg_df_post <-
dg_df_post %>%
dplyr::mutate(`Date Modified` = lubridate::ymd_hms(format(`Date Modified`, "%Y-%m-%d %H:%M:%S", tz = "UTC"))) %>%
mutate_if(is.character, ~dplyr::na_if(., "Not Answered")) %>%
dplyr::filter(Response_Status == "completed") %>%
dplyr::filter(!stringr::str_detect(ID, "PA4OXT")) %>%
dplyr::filter(!stringr::str_detect(ID, "PA4RMN"))
dg_df_pre <-
dg_df_pre %>%
dplyr::mutate_at(vars(starts_with("DG_")), ~stringr::str_extract(., "[0-9]+")) %>% # extracts first number (all games start with Player A, so always first number)
dplyr::mutate_at(vars(starts_with("DG_")), as.numeric) %>%
dplyr::mutate(Time = rep("Pre", nrow(.))) %>%
dplyr::mutate(Cond = ifelse(stringr::str_detect(ID, "X"), "CTRL", "TR")) %>%
select(`Date Modified`, ID, starts_with("DG_"), Time, Cond)
dg_df_post <-
dg_df_post %>%
dplyr::mutate_at(vars(starts_with("DG_")), ~stringr::str_extract(., "[0-9]+")) %>% # extracts first number (all games start with Player A, so always first number)
dplyr::mutate_at(vars(starts_with("DG_")), as.numeric) %>%
dplyr::mutate(Time = rep("Post", nrow(.))) %>%
dplyr::mutate(Cond = ifelse(stringr::str_detect(ID, "X"), "CTRL", "TR")) %>%
select(`Date Modified`, ID, starts_with("DG_"), Time, Cond)
# Transform DG 0-900 egoism to 0-9 altruism
dg_trans_func <- function(x){trans <- 9 - x / 100}
dg_df_pre <-
dg_df_pre %>%
dplyr::mutate_at(vars(starts_with("DG_")), dg_trans_func)
dg_df_post <-
dg_df_post %>%
dplyr::mutate_at(vars(starts_with("DG_")), dg_trans_func)
# Unite DG data - Long Format
dg_united_long <- rbind(dg_df_pre, dg_df_post)
which(table(dg_united_long$ID)> 2 ) # IDs "3B" & "31X" have more than 2 trials
dg_united_long[dg_united_long$ID == "3B",] # two Pres -- keep the first
dg_united_long <- dg_united_long[-106, ]
dg_united_long$DG_Total <- rowSums(dg_united_long[, sprintf("DG_%d", 1:4)], na.rm = TRUE)
# Unite DG data - Wide Format
dg_united_wide <-
dg_united_long %>%
tidyr::pivot_wider(id_cols = c(ID, Cond), names_from = Time, values_from = c("Date Modified", sprintf("DG_%d", 1:4), "DG_Total"))
# dg_united_wide2 <- dplyr::left_join(dg_united_wide, ids_groups_df, by = "ID") # no need to merge, already have ids for groups stored
–>
T test Dicatator Game
## DG - PTSD TR
#### DG_Total_Pre DG_Total_Post
## DG - PTSD CTRL
#### DG_Total_Pre DG_Total_Post
## DG - Burnout TR
#### DG_Total_Pre DG_Total_Post
## DG - Burnout CTRL
#### DG_Total_Pre DG_Total_Post
## DG - Old TR
## DG - Old CTRL
## DG - General Population TR
#### DG_Total_Pre DG_Total_Post
## DG - General Population CTRL
#### DG_Total_Pre DG_Total_Post
–>
# Scales df
scale_df_pre <- rio::import(file.path(folder, file),
skip = 0, which = "Set teste zi 1 pre")
scale_df_pre <-
scale_df_pre %>%
janitor::remove_empty("rows")
scale_df_pre <- scale_df_pre[,-2]
colnames(scale_df_pre)[1] <- "Date"
colnames(scale_df_pre)[2] <- "ID"
scale_df_pre <-
scale_df_pre %>%
dplyr::mutate(ID = stringr::str_replace_all(ID, fixed(" "), "")) %>% # remove white spaces
dplyr::mutate(ID = toupper(ID)) # to upper
all(scale_df_pre$ID == toupper(scale_df_pre$ID))
scale_df_post <- rio::import(file.path(folder, file),
skip = 0, which = "Set teste zi 5 post")
scale_df_post <-
scale_df_post %>%
janitor::remove_empty("rows")
scale_df_post <- scale_df_post[,-2]
colnames(scale_df_post)[1] <- "Date"
colnames(scale_df_post)[2] <- "ID"
scale_df_post <-
scale_df_post %>%
dplyr::mutate(ID = stringr::str_replace_all(ID, fixed(" "), "")) %>% # remove white spaces
dplyr::mutate(ID = toupper(ID)) # to upper
all(scale_df_post$ID == toupper(scale_df_post$ID))
all.equal(colnames(scale_df_post), colnames(scale_df_pre)) # setdiff(colnames(scale_df_post), colnames(scale_df_pre))
# Deal with Not Answer
scale_df_pre <-
scale_df_pre %>%
mutate_if(is.character, ~dplyr::na_if(., "Not Answered"))
scale_df_post <-
scale_df_post %>%
mutate_if(is.character, ~dplyr::na_if(., "Not Answered"))
# Exclude subjects
scale_df_pre <-
scale_df_pre %>%
dplyr::filter(!stringr::str_detect(ID, "PA4OXT")) %>%
dplyr::filter(!stringr::str_detect(ID, "RMN"))
scale_df_post <-
scale_df_post %>%
dplyr::filter(!stringr::str_detect(ID, "PA4OXT")) %>%
dplyr::filter(!stringr::str_detect(ID, "RMN"))
# Add Condition
scale_df_pre <-
scale_df_pre %>%
dplyr::mutate(Time = rep("Pre", nrow(.))) %>%
dplyr::mutate(Cond = ifelse(stringr::str_detect(ID, "X"), "CTRL", "TR"))
scale_df_post <-
scale_df_post %>%
dplyr::mutate(Time = rep("Post", nrow(.))) %>%
dplyr::mutate(Cond = ifelse(stringr::str_detect(ID, "X"), "CTRL", "TR"))
## PANAS: Positive Affect Score = sum items 1, 3, 5, 9, 10, 12, 14, 16, 17, 19. Negative Affect Score = sum items 2, 4, 6, 7, 8, 11, 13, 15, 18, 20.
index_item_panas <- 3:22
colnames(scale_df_pre)[index_item_panas] <- sprintf("PANAS_%d", 1:20)
colnames(scale_df_post)[index_item_panas] <- sprintf("PANAS_%d", 1:20)
scale_df_pre[, index_item_panas] <- data.frame(lapply(scale_df_pre[, index_item_panas],
function(x) {gsub(".*în foarte mică măsură.*", "1", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_panas] <- data.frame(lapply(scale_df_pre[, index_item_panas],
function(x) {gsub(".*în mică măsură.*", "2", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_panas] <- data.frame(lapply(scale_df_pre[, index_item_panas],
function(x) {gsub(".*într-o oarecare măsură.*", "3", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_panas] <- data.frame(lapply(scale_df_pre[, index_item_panas],
function(x) {gsub(".*în mare măsură.*", "4", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_panas] <- data.frame(lapply(scale_df_pre[, index_item_panas],
function(x) {gsub(".*în foarte mare măsură.*", "5", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_panas] <- data.frame(lapply(scale_df_post[, index_item_panas],
function(x) {gsub(".*în foarte mică măsură.*", "1", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_panas] <- data.frame(lapply(scale_df_post[, index_item_panas],
function(x) {gsub(".*în mică măsură.*", "2", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_panas] <- data.frame(lapply(scale_df_post[, index_item_panas],
function(x) {gsub(".*într-o oarecare măsură.*", "3", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_panas] <- data.frame(lapply(scale_df_post[, index_item_panas],
function(x) {gsub(".*în mare măsură.*", "4", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_panas] <- data.frame(lapply(scale_df_post[, index_item_panas],
function(x) {gsub(".*în foarte mare măsură.*", "5", x)}), stringsAsFactors = FALSE)
# Scoring
scale_df_pre$PA_Total <- ScoreLikert(scale_df_pre[, index_item_panas][c(1, 3, 5, 9, 10, 12, 14, 16, 17, 19)],
tonumeric = TRUE, napercent = .11) # not more than 1 NAs for 10 items
scale_df_pre$NA_Total <- ScoreLikert(scale_df_pre[, index_item_panas][c(2, 4, 6, 7, 8, 11, 13, 15, 18, 20)],
tonumeric = TRUE, napercent = .11) # not more than 1 NAs for 10 items
scale_df_post$PA_Total <- ScoreLikert(scale_df_post[, index_item_panas][c(1, 3, 5, 9, 10, 12, 14, 16, 17, 19)],
tonumeric = TRUE, napercent = .11) # not more than 1 NAs for 10 items
scale_df_post$NA_Total <- ScoreLikert(scale_df_post[, index_item_panas][c(2, 4, 6, 7, 8, 11, 13, 15, 18, 20)],
tonumeric = TRUE, napercent = .11) # not more than 1 NAs for 10 items
## PSS-SF 14 (likert 0-4). Items 4, 5, 6, 7, 9, 10, and 13 are scored in reverse direction.
index_item_pss <- 23:36
index_item_revPSS <- c(4, 5, 6, 7, 9, 10, 13)
colnames(scale_df_pre)[index_item_pss] <- sprintf("PSS_%d", 1:14)
colnames(scale_df_post)[index_item_pss] <- sprintf("PSS_%d", 1:14)
scale_df_pre[, index_item_pss] <- data.frame(lapply(scale_df_pre[, index_item_pss],
function(x) {gsub(".*niciodată.*", "0", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_pss] <- data.frame(lapply(scale_df_pre[, index_item_pss],
function(x) {gsub(".*aproape niciodată.*", "1", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_pss] <- data.frame(lapply(scale_df_pre[, index_item_pss],
function(x) {gsub(".*uneori.*", "2", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_pss] <- data.frame(lapply(scale_df_pre[, index_item_pss],
function(x) {gsub(".*destul de des.*", "3", x)}), stringsAsFactors = FALSE)
scale_df_pre[, index_item_pss] <- data.frame(lapply(scale_df_pre[, index_item_pss],
function(x) {gsub(".*foarte des.*", "4", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_pss] <- data.frame(lapply(scale_df_post[, index_item_pss],
function(x) {gsub(".*niciodată.*", "0", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_pss] <- data.frame(lapply(scale_df_post[, index_item_pss],
function(x) {gsub(".*aproape niciodată.*", "1", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_pss] <- data.frame(lapply(scale_df_post[, index_item_pss],
function(x) {gsub(".*uneori.*", "2", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_pss] <- data.frame(lapply(scale_df_post[, index_item_pss],
function(x) {gsub(".*destul de des.*", "3", x)}), stringsAsFactors = FALSE)
scale_df_post[, index_item_pss] <- data.frame(lapply(scale_df_post[, index_item_pss],
function(x) {gsub(".*foarte des.*", "4", x)}), stringsAsFactors = FALSE)
# Score
scale_df_pre[, index_item_pss] <- colstonumeric(scale_df_pre[, index_item_pss])
scale_df_post[, index_item_pss] <- colstonumeric(scale_df_post[, index_item_pss])
scale_df_pre[, index_item_pss][index_item_revPSS] <- ReverseCode(scale_df_pre[, index_item_pss][index_item_revPSS], tonumeric = FALSE, min = 0, max = 4)
scale_df_post[, index_item_pss][index_item_revPSS] <- ReverseCode(scale_df_post[, index_item_pss][index_item_revPSS], tonumeric = FALSE, min = 0, max = 4)
scale_df_pre$PSS_Total <- ScoreLikert(scale_df_pre[, index_item_pss], napercent = .11)
scale_df_post$PSS_Total <- ScoreLikert(scale_df_post[, index_item_pss], napercent = .11)
# Unite scale df - Long Format
scale_united_long <- rbind(scale_df_pre, scale_df_post)
# scale_united_long %>%
# count(ID) %>%
# print(n = Inf) # ID "2B", "5E" have double record
# scale_united_long[scale_united_long$ID == "2B",]
scale_united_long <- scale_united_long[-26,]
# scale_united_long[scale_united_long$ID == "5E",]
scale_united_long <- scale_united_long[-109,]
# Exclude subj wiht only one observation, exclude ID NOTANSWERED
scale_united_long <-
scale_united_long %>%
group_by(ID) %>%
dplyr::filter(n() > 1) %>%
ungroup() %>%
dplyr::filter(ID != "NOTANSWERED")
# Unite DG data - Wide Format
scale_united_wide <-
scale_united_long %>%
dplyr::select(ID, Date, Time, Cond, PA_Total, NA_Total, PSS_Total) %>%
tidyr::pivot_wider(id_cols = c(ID, Cond), names_from = Time, values_from = c("Date", "PA_Total", "NA_Total", "PSS_Total"))
cat("Mixed ANOVA - PSS whole sample (not by groups)")
# Mixed ANOVA
scale_united_long %>%
group_by(ID) %>%
filter(n() > 1) %>% # keep only complete cases -- here are only complete
ungroup() %>%
tw_mixedANOVA_func(data = ., id_var = ID, cond_var = Cond, time_var = Time, value_var = PSS_Total,
posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)
cat("Mixed ANOVA - PA whole sample (not by groups)")
scale_united_long %>%
group_by(ID) %>%
filter(n() > 1) %>% # keep only complete cases -- here are only complete
ungroup() %>%
tw_mixedANOVA_func(data = ., id_var = ID, cond_var = Cond, time_var = Time, value_var = PA_Total,
posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)
cat("Mixed ANOVA - NA whole sample (not by groups)")
scale_united_long %>%
group_by(ID) %>%
filter(n() > 1) %>% # keep only complete cases -- here are only complete
ungroup() %>%
tw_mixedANOVA_func(data = ., id_var = ID, cond_var = Cond, time_var = Time, value_var = NA_Total,
posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)
–>
T test PSS
## PSS - PTSD TR
#### PSS_Total_Pre PSS_Total_Post
## PSS - PTSD CTRL
#### PSS_Total_Pre PSS_Total_Post
## PSS - Burnout TR
#### PSS_Total_Pre PSS_Total_Post
## PSS - Burnout CTRL
#### PSS_Total_Pre PSS_Total_Post
## PSS - General Population TR
#### PSS_Total_Pre PSS_Total_Post
## PSS - General Population CTRL
#### PSS_Total_Pre PSS_Total_Post
–>
T test PA
## PA - PTSD TR
#### PA_Total_Pre PA_Total_Post
## PA - PTSD CTRL
#### PA_Total_Pre PA_Total_Post
## PA - Burnout TR
#### PA_Total_Pre PA_Total_Post
## PA - Burnout CTRL
#### PA_Total_Pre PA_Total_Post
## PA - General Population TR
#### PA_Total_Pre PA_Total_Post
## PA - General Population CTRL
#### PA_Total_Pre PA_Total_Post
–>
T test NA
## NA - PTSD TR
#### NA_Total_Pre NA_Total_Post
## NA - PTSD CTRL
#### NA_Total_Pre NA_Total_Post
## NA - Burnout TR
#### NA_Total_Pre NA_Total_Post
## NA - Burnout CTRL
#### NA_Total_Pre NA_Total_Post
## NA - General Population TR
#### NA_Total_Pre NA_Total_Post
## NA - General Population CTRL
#### NA_Total_Pre NA_Total_Post
–>
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] pwr_1.2-2 rlang_0.4.6 emmeans_1.4.5 rio_0.5.16 scales_1.1.0 ggpubr_0.2.5
[7] magrittr_1.5 tadaatoolbox_0.16.1 summarytools_0.8.8 rstatix_0.5.0 broom_0.5.6 PerformanceAnalytics_1.5.2
[13] xts_0.11-2 zoo_1.8-4 psych_1.9.12.31 forcats_0.5.0 stringr_1.4.0 dplyr_0.8.5
[19] purrr_0.3.3 readr_1.3.1 tidyr_1.0.2 tibble_3.0.0 ggplot2_3.3.0 tidyverse_1.3.0
[25] papaja_0.1.0.9997 pacman_0.5.1
loaded via a namespace (and not attached):
[1] TH.data_1.0-9 colorspace_1.4-1 ggsignif_0.4.0 pryr_0.1.4 ellipsis_0.3.0 estimability_1.3 snakecase_0.9.2 fs_1.4.1
[9] rstudioapi_0.11 farver_2.0.3 fansi_0.4.1 mvtnorm_1.1-0 lubridate_1.7.4 xml2_1.3.1 codetools_0.2-16 splines_3.6.1
[17] mnormt_1.5-6 knitr_1.28 pixiedust_0.8.6 jsonlite_1.6.1 dbplyr_1.4.3 compiler_3.6.1 httr_1.4.1 backports_1.1.6
[25] assertthat_0.2.1 Matrix_1.2-17 cli_2.0.2 htmltools_0.4.0 tools_3.6.1 coda_0.19-2 gtable_0.3.0 glue_1.4.0
[33] Rcpp_1.0.4.6 carData_3.0-2 cellranger_1.1.0 vctrs_0.2.4 nlme_3.1-140 xfun_0.13 openxlsx_4.1.0 rvest_0.3.5
[41] lifecycle_0.2.0 MASS_7.3-51.4 hms_0.5.3 parallel_3.6.1 sandwich_2.5-0 expm_0.999-3 curl_4.3 gridExtra_2.3
[49] pander_0.6.3 stringi_1.4.6 nortest_1.0-4 boot_1.3-22 zip_1.0.0 pkgconfig_2.0.3 matrixStats_0.54.0 bitops_1.0-6
[57] lattice_0.20-38 rapportools_1.0 labeling_0.3 tidyselect_1.0.0 plyr_1.8.6 R6_2.4.1 DescTools_0.99.34 generics_0.0.2
[65] multcomp_1.4-8 DBI_1.0.0 pillar_1.4.3 haven_2.2.0 foreign_0.8-71 withr_2.1.2 survival_2.44-1.1 abind_1.4-5
[73] RCurl_1.95-4.11 janitor_2.0.1 modelr_0.1.6 crayon_1.3.4 car_3.0-7 viridis_0.5.1 grid_3.6.1 readxl_1.3.1
[81] data.table_1.12.8 reprex_0.3.0 digest_0.6.25 xtable_1.8-4 munsell_0.5.0 viridisLite_0.3.0 quadprog_1.5-5
Â
A work by Claudiu Papasteri
claudiu.papasteri@gmail.com
Â
LS0tDQp0aXRsZTogIjxicj4gUEE0IiANCnN1YnRpdGxlOiAiUmVwb3J0Ig0KYXV0aG9yOiAiPGJyPiBDbGF1ZGl1IFBhcGFzdGVyaSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVtICVZJylgIg0Kb3V0cHV0OiANCiAgICBodG1sX25vdGVib29rOg0KICAgICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgICAgICAgICB0b2M6IHRydWUNCiAgICAgICAgICAgIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICB0aGVtZTogc3BhY2VsYWINCiAgICAgICAgICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICAgICAgICAgIGZvbnQtZmFtaWx5OiBBcmlhbA0KICAgICAgICAgICAgZmlnX3dpZHRoOiAxMA0KICAgICAgICAgICAgZmlnX2hlaWdodDogOQ0KICAgICMgcGRmX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgIyBmb250c2l6ZTogMTFwdA0KICAgICAgICAgICAgIyBnZW9tZXRyeTogbWFyZ2luPTFpbg0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDcNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNg0KICAgICAgICAgICAgIyBmaWdfY2FwdGlvbjogdHJ1ZQ0KICAgICMgZ2l0aHViX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyBodG1sX3ByZXZpZXc6IGZhbHNlDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNQ0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA1DQogICAgICAgICAgICAjIGRldjoganBlZw0KLS0tDQoNCg0KPCEtLSBTZXR1cCAtLT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMga2ludHIgb3B0aW9ucw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjb21tZW50ID0gIiMiLA0KICBjb2xsYXBzZSA9IFRSVUUsDQogIGVycm9yID0gVFJVRSwNCiAgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBjYWNoZSA9IFRSVUUgICAgICAgIyBlY2hvID0gRmFsc2UgZm9yIGdpdGh1Yl9kb2N1bWVudCwgYnV0IHdpbGwgYmUgZm9sZGVkIGluIGh0bWxfbm90ZWJvb2sNCikNCg0KIyBHZW5lcmFsIFIgb3B0aW9ucyBhbmQgaW5mbw0Kc2V0LnNlZWQoMTExKSAgICAgICAgICAgICAgICMgaW4gY2FzZSB3ZSB1c2UgcmFuZG9taXplZCBwcm9jZWR1cmVzICAgICAgIA0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICAgICAgICMgcG9zaXRpdmUgdmFsdWVzIGJpYXMgdG93YXJkcyBmaXhlZCBhbmQgbmVnYXRpdmUgdG93YXJkcyBzY2llbnRpZmljIG5vdGF0aW9uDQoNCiMgTG9hZCBwYWNrYWdlcw0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY2thZ2VzIDwtIGMoDQogICJwYXBhamEiLA0KICAidGlkeXZlcnNlIiwgICAgICAgDQogICJwc3ljaCIsICJQZXJmb3JtYW5jZUFuYWx5dGljcyIsICAgICAgICAgIA0KICAiYnJvb20iLCAicnN0YXRpeCIsDQogICJzdW1tYXJ5dG9vbHMiLCAidGFkYWF0b29sYm94IiwgICAgICAgICAgIA0KICAiZ2dwbG90MiIsICJnZ3B1YnIiLCAic2NhbGVzIiwgICAgICAgIA0KICAicmlvIiwNCiAgImdncHViciIsICJyc3RhdGl4IiwgImJyb29tIiwgImVtbWVhbnMiLCAicmxhbmciLA0KICAicHdyIg0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCg0KDQoNCg0KPCEtLSBSZXBvcnQgLS0+DQoNCiMgRGVmaW5lIGZ1bmN0aW9ucw0KDQpgYGB7ciBkZWZfZnVuY30NCiMjIERlZmluZSBmdW5jdGlvbiB0aGF0IHJlY29kZXMgdG8gbnVtZXJpYywgYnV0IHdhdGNoZXMgb3V0IHRvIGNvZXJjaW9uIHRvIG5vdCBpbnRyb2R1Y2UgTkFzDQpjb2xzdG9udW1lcmljIDwtIGZ1bmN0aW9uKGRmKXsNCiAgdHJ5Q2F0Y2goew0KICAgIGRmX251bSA8LSBhcy5kYXRhLmZyYW1lKA0KICAgICAgbGFwcGx5KGRmLA0KICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHsgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeCkpfSkpIA0KICB9LHdhcm5pbmcgPSBmdW5jdGlvbihzdG9wX29uX3dhcm5pbmcpIHsNCiAgICBtZXNzYWdlKCJTdG9wZWQgdGhlIGV4ZWN1dGlvbiBvZiBudW1lcmljIGNvbnZlcnNpb246ICIsIGNvbmRpdGlvbk1lc3NhZ2Uoc3RvcF9vbl93YXJuaW5nKSkNCiAgfSkgDQp9DQojIw0KIyMgRGVmaW5lIGZ1bmN0aW9uIHRoYXQgcmV2ZXJzZSBjb2RlcyBpdGVtcw0KUmV2ZXJzZUNvZGUgPC0gZnVuY3Rpb24oZGYsIHRvbnVtZXJpYyA9IEZBTFNFLCBtaW4gPSBOVUxMLCBtYXggPSBOVUxMKSB7DQogIGlmKHRvbnVtZXJpYykgZGYgPC0gY29sc3RvbnVtZXJpYyhkZikNCiAgZGYgPC0gKG1heCArIG1pbikgLSBkZg0KfQ0KIyMNCiMjIERlZmluZSBmdW5jdGlvbiB0aGF0IHNjb3JlcyBvbmx5IHJvd3Mgd2l0aCBsZXNzIHRoYW4gMTAlIE5BcyAocmV0dXJucyBOQSBpZiBhbGwgb3IgYWJvdmUgdGhyZXNob2xkIHBlcmNlbnRhZ2Ugb2Ygcm93cyBhcmUgTkEpOyBjYW4gcmV2ZXJzZSBjb2RlIGlmIHZlY3RvciBvZiBjb2x1bW4gaW5kZXhlcyBhbmQgbWluLCBtYXggYXJlIHByb3ZpZGVkLg0KU2NvcmVMaWtlcnQgPC0gZnVuY3Rpb24oZGYsIG5hcGVyY2VudCA9IC4xLCB0b251bWVyaWMgPSBGQUxTRSwgcmV2ZXJzZWNvbHMgPSBOVUxMLCBtaW4gPSBOVUxMLCBtYXggPSBOVUxMKSB7DQogIHJldmVyc2VfbGlzdCA8LSBsaXN0KHJldmVyc2Vjb2xzID0gcmV2ZXJzZWNvbHMsIG1pbiA9IG1pbiwgbWF4ID0gbWF4KQ0KICByZXZlcnNlX2NoZWNrIDwtICFzYXBwbHkocmV2ZXJzZV9saXN0LCBpcy5udWxsKQ0KICANCiAgIyBSZWNvZGUgdG8gbnVtZXJpYywgYnV0IHdhdGNoIG91dCB0byBjb2VyY2lvbiB0byBub3QgaW50cm9kdWNlIE5Bcw0KICBjb2xzdG9udW1lcmljIDwtIGZ1bmN0aW9uKGRmKXsNCiAgICB0cnlDYXRjaCh7DQogICAgICBkZl9udW0gPC0gYXMuZGF0YS5mcmFtZSgNCiAgICAgICAgbGFwcGx5KGRmLA0KICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkgeyBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih4KSl9KSkgDQogICAgfSx3YXJuaW5nID0gZnVuY3Rpb24oc3RvcF9vbl93YXJuaW5nKSB7DQogICAgICBtZXNzYWdlKCJTdG9wZWQgdGhlIGV4ZWN1dGlvbiBvZiBudW1lcmljIGNvbnZlcnNpb246ICIsIGNvbmRpdGlvbk1lc3NhZ2Uoc3RvcF9vbl93YXJuaW5nKSkNCiAgICB9KSANCiAgfQ0KICANCiAgaWYodG9udW1lcmljKSBkZiA8LSBjb2xzdG9udW1lcmljKGRmKQ0KICANCiAgaWYoYWxsKHJldmVyc2VfY2hlY2spKXsNCiAgICBkZlsgLHJldmVyc2Vjb2xzXSA8LSAobWF4ICsgbWluKSAtIGRmWyAscmV2ZXJzZWNvbHNdDQogIH1lbHNlIGlmKGFueShyZXZlcnNlX2NoZWNrKSl7DQogICAgc3RvcCgiSW5zdWZpY2llbnQgaW5mbyBmb3IgcmV2ZXJzaW5nLiBQbGVhc2UgcHJvdmlkZTogIiwgcGFzdGUobmFtZXMocmV2ZXJzZV9saXN0KVshcmV2ZXJzZV9jaGVja10sIGNvbGxhcHNlID0gIiwgIikpDQogIH0NCiAgDQogIGlmZWxzZShyb3dTdW1zKGlzLm5hKGRmKSkgPiBuY29sKGRmKSAqIG5hcGVyY2VudCwNCiAgICAgICAgIE5BLA0KICAgICAgICAgcm93U3VtcyhkZiwgbmEucm0gPSBUUlVFKSAqIE5BIF4gKHJvd1N1bXMoIWlzLm5hKGRmKSkgPT0gMCkNCiAgKQ0KfQ0KIyMNCmBgYA0KDQoNCmBgYHtyIGRlZl9mdW5jX3R0ZXN0LCBoaWRlPVRSVUV9DQojIyBGdW5jIHQgdGVzdCBzaSBib3hwbG90IHNpbXBsdQ0KZnVuY190X2JveCA8LSBmdW5jdGlvbihkZiwgaW5kLCBwcmVfdmFyLCBwb3N0X3Zhcil7DQogIHZhcnMgPC0gYyhpbmQsIHByZV92YXIsIHBvc3RfdmFyKSAgICAgICAgICAgICAgICAjIHRvIGF2b2lkIG5ldyB0aWR5dmVyc2UgZXJyb3Igb2YgYW1iaWd1aXR5IGR1ZSB0byBleHRlcm5hbCB2ZWN0b3MNCiAgZGZfbW9kaWYgPC0NCiAgICBkZiAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KHRpZHlzZWxlY3Q6OmFsbF9vZih2YXJzKSkgJT4lIA0KICAgIHRpZHlyOjpkcm9wX25hKCkgJT4lDQogICAgZ2F0aGVyKHRpZHlzZWxlY3Q6OmFsbF9vZihwcmVfdmFyKSwgdGlkeXNlbGVjdDo6YWxsX29mKHBvc3RfdmFyKSwga2V5ID0gIkNvbmQiLCB2YWx1ZSA9ICJ2YWx1ZSIpICU+JSANCiAgICBtdXRhdGVfYXQodmFycyhjKDEsIDIpKSwgYXMuZmFjdG9yKSAlPiUgDQogICAgbXV0YXRlKENvbmQgPSBmYWN0b3IoQ29uZCwgbGV2ZWxzID0gYyhwcmVfdmFyLCBwb3N0X3ZhcikpKSANCiAgDQogIHN0YXRfY29tcCA8LSBnZ3B1YnI6OmNvbXBhcmVfbWVhbnModmFsdWUgfiBDb25kLCBkYXRhID0gZGZfbW9kaWYsIG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFKQ0KICANCiAgc3RhdF9jb21wMiA8LQ0KICAgIGRmX21vZGlmICU+JSANCiAgICBkbyh0aWR5KHQudGVzdCguJHZhbHVlIH4gLiRDb25kLA0KICAgICAgICAgICAgICAgICAgIHBhaXJlZCA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgZGF0YT0uKSkpDQogIA0KICBwbG90IDwtIA0KICAgIGdncHVicjo6Z2dwYWlyZWQoZGZfbW9kaWYsIHggPSAiQ29uZCIsIHkgPSAidmFsdWUiLCBpZCA9IGluZCwgDQogICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJDb25kIiwgbGluZS5jb2xvciA9ICJncmF5IiwgbGluZS5zaXplID0gMC40LA0KICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCAiI0ZDNEUwNyIpLCBsZWdlbmQgPSAibm9uZSIpICsNCiAgICAgIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsICBjb2xvdXIgPSAiZGFya3JlZCIpICsNCiAgICAgIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBsYWJlbC54ID0gYXMubnVtZXJpYyhkZl9tb2RpZiRDb25kKS0wLjQsIGxhYmVsLnkgPSBtYXgoZGZfbW9kaWYkdmFsdWUpKzAuNSkgKyANCiAgICAgIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBsYWJlbCA9ICJwLnNpZ25pZiIsIGNvbXBhcmlzb25zID0gbGlzdChjKHByZV92YXIsIHBvc3RfdmFyKSkpDQogIA0KICBjYXQocGFzdGUwKCIjIyMjICIsIHByZV92YXIsICIgIiwgcG9zdF92YXIsICJcbiIsICJcbiIpKQ0KICBwcmludChzdGF0X2NvbXApDQogIHByaW50KHN0YXRfY29tcDIpDQogIHByaW50KHBsb3QpDQp9DQpgYGANCg0KDQpgYGB7ciBzYW1wbGVzaXplX2lkZXB0dGVzdH0NCnNhbXBsZXNpemVfcGFpcmVkdHRlc3QgPC0gZnVuY3Rpb24oZGYsIHByZV92YXIsIHBvc3RfdmFyKXsNCiAgdmFycyA8LSBjKHByZV92YXIsIHBvc3RfdmFyKSAgICAgICAgICAgICAgICAjIHRvIGF2b2lkIG5ldyB0aWR5dmVyc2UgZXJyb3Igb2YgYW1iaWd1aXR5IGR1ZSB0byBleHRlcm5hbCB2ZWN0b3JzDQogIGRmX21vZGlmIDwtDQogICAgZGYgJT4lDQogICAgZHBseXI6OnNlbGVjdCh0aWR5c2VsZWN0OjphbGxfb2YodmFycykpICU+JSANCiAgICB0aWR5cjo6ZHJvcF9uYSgpICU+JQ0KICAgIGdhdGhlcih0aWR5c2VsZWN0OjphbGxfb2YocHJlX3ZhciksIHRpZHlzZWxlY3Q6OmFsbF9vZihwb3N0X3ZhciksIGtleSA9ICJDb25kIiwgdmFsdWUgPSAidmFsdWUiKSAlPiUgDQogICAgbXV0YXRlKENvbmQgPSBmYWN0b3IoQ29uZCwgbGV2ZWxzID0gYyhwcmVfdmFyLCBwb3N0X3ZhcikpKSANCiAgDQogIGNhdCgiIyMgQ29oZW4ncyBkIFxuIikNCiAgZWZmX3NpemVfdGFibGUgPC0NCiAgICBkZl9tb2RpZiAlPiUNCiAgICBjb2hlbnNfZCh2YWx1ZSB+IENvbmQsIHBhaXJlZCA9IFRSVUUpICU+JQ0KICAgIHByaW50KCkNCiAgZWZmX3NpemUgPC0gYXMubnVtZXJpYyhlZmZfc2l6ZV90YWJsZSRlZmZzaXplKQ0KDQogIGNhdCgiIyMgU2FtcGxlIFNpemUgZXN0aW1hdGlvbiBcbiIpDQogIHNhbXBsZV9zaXplX3RhYmxlIDwtDQogICAgcHdyOjpwd3IudC50ZXN0KGQgPSBlZmZfc2l6ZSwgc2lnLmxldmVsID0gLjA1LCBwb3dlciA9IC44LCB0eXBlID0gInBhaXJlZCIsIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpIA0KICBzYW1wbGVfc2l6ZV90YWJsZSAlPiUgYnJvb206OnRpZHkoKSAlPiUgcHJpbnQoKQ0KDQogIHBsb3Qoc2FtcGxlX3NpemVfdGFibGUpDQp9ICANCmBgYA0KDQoNCmBgYHtyIGRlZl9mdW5jX0FOQ09WQVBvc3R9DQojIGxpYnJhcnkodGlkeXZlcnNlKQ0KIyBsaWJyYXJ5KGdncHVicikNCiMgbGlicmFyeShyc3RhdGl4KQ0KIyBsaWJyYXJ5KGJyb29tKQ0KIyBsaWJyYXJ5KGVtbWVhbnMpDQojIGxpYnJhcnkocmxhbmcpDQoNCg0KIyBGdW5jdGlvbiBBTkNPVkFQb3N0DQojIFRha2VzIExvbmcgRGF0YQ0KQU5DT1ZBUG9zdF9mdW5jIDwtIA0KICBmdW5jdGlvbihkYXRhLCBpZF92YXIsIA0KICAgICAgICAgICB0aW1lX3ZhciwgcHJlX2xhYmVsLCBwb3N0X2xhYmVsLA0KICAgICAgICAgICB2YWx1ZV92YXIgPSBzY29yZXMsIGNvbmRfdmFyLCANCiAgICAgICAgICAgYXNzdW1fY2hlY2sgPSBUUlVFLCBwb3N0aG9jID0gVFJVRSwgDQogICAgICAgICAgIHBfYWRqdXN0X21ldGhvZCA9ICJib25mZXJyb25pIil7DQogIA0KICBpZF92YXJfZW5xIDwtIHJsYW5nOjplbnF1byhpZF92YXIpDQogIGlkX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKGlkX3Zhcl9lbnEpICAgIA0KICB0aW1lX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKHRpbWVfdmFyKQ0KICB0aW1lX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHRpbWVfdmFyX2VucSkNCiAgcHJlX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKHByZV9sYWJlbCkNCiAgcHJlX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHByZV92YXJfZW5xKSAgDQogIHBvc3RfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8ocG9zdF9sYWJlbCkNCiAgcG9zdF92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZShwb3N0X3Zhcl9lbnEpDQogIGNvbmRfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8oY29uZF92YXIpDQogIGNvbmRfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUoY29uZF92YXJfZW5xKQ0KICB2YWx1ZV92YXJfZW5xIDwtIHJsYW5nOjplbnF1byh2YWx1ZV92YXIpDQogIHZhbHVlX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHZhbHVlX3Zhcl9lbnEpIA0KICANCiAgZGF0YV93aWRlciA8LQ0KICAgIGRhdGEgJT4lDQogICAgZHBseXI6OnNlbGVjdCghIWlkX3Zhcl9lbnEsICEhdGltZV92YXJfZW5xLCAhIWNvbmRfdmFyX2VucSwgISF2YWx1ZV92YXJfZW5xKSAlPiUNCiAgICBzcHJlYWQoa2V5ID0gdGltZV92YXJfbmFtZSwgdmFsdWUgPSB2YWx1ZV92YXJfbmFtZSkgIyAlPiUgICAgICMgaWYgbmVlZCB0byBjb21wdXRlIGNoYW5nZSBzY29yZSBzdGF0aXN0aWNzIGdvIGZyb20gaGVyZQ0KICAgICMgbXV0YXRlKGRpZmZlcmVuY2UgPSAhIXBvc3RfdmFyX2VucSAtICEhcHJlX3Zhcl9lbnEpICANCiAgICANCiAgIyBBc3N1bXB0aW9ucw0KICBpZihhc3N1bV9jaGVjayl7DQogIGNhdCgiXG4gTGluZWFyaXR5IGFzc3VtcHRpb25MaW5lYXJpdHkgYXNzdW1wdGlvbiAobGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHByZS10ZXN0IGFuZCBwb3N0LXRlc3QgZm9yIGVhY2ggZ3JvdXApIFxuIikNCiAgIyBDcmVhdGUgYSBzY2F0dGVyIHBsb3QgYmV0d2VlbiB0aGUgY292YXJpYXRlIChpLmUuLCBwcmV0ZXN0KSBhbmQgdGhlIG91dGNvbWUgdmFyaWFibGUgKGkuZS4sIHBvc3R0ZXN0KQ0KICBzY2F0dGVyX2xpbiA8LSAgDQogICAgZ2dzY2F0dGVyKGRhdGFfd2lkZXIsIHggPSBwcmVfdmFyX25hbWUsIHkgPSBwb3N0X3Zhcl9uYW1lLCBjb2xvciA9IGNvbmRfdmFyX25hbWUsIA0KICAgICAgICAgICAgICBhZGQgPSAicmVnLmxpbmUiLCB0aXRsZSA9ICJMaW5lYXJpdHkgYXNzdW1wdGlvbiIpICsNCiAgICAgIHN0YXRfcmVnbGluZV9lcXVhdGlvbihhZXMobGFiZWwgPSAgcGFzdGUoLi5lcS5sYWJlbC4uLCAuLnJyLmxhYmVsLi4sIHNlcCA9ICJ+fn5+IiksIGNvbG9yID0gISFjb25kX3Zhcl9lbnEpKQ0KICANCiAgY2F0KCJcbiBIb21vZ2VuZWl0eSBvZiByZWdyZXNzaW9uIHNsb3BlcyAoaW50ZXJhY3Rpb24gdGVybSBpcyBuLnMuKSBcbiIpDQogIGRhdGFfd2lkZXIgJT4lIA0KICAgIGFub3ZhX3Rlc3QoYXMuZm9ybXVsYShwYXN0ZTAocG9zdF92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUsICIgKiAiLCBwcmVfdmFyX25hbWUpKSkgJT4lIA0KICAgIHByaW50KCkgICANCiAgDQogIGNhdCgiXG4gTm9ybWFsaXR5IG9mIHJlc2lkdWFscyAoTW9kZWwgZGlhZ25vc3RpY3MgJiBTaGFwaXJvIFdpbGspIFxuIikNCiAgIyBGaXQgdGhlIG1vZGVsLCB0aGUgY292YXJpYXRlIGdvZXMgZmlyc3QNCiAgbW9kZWwgPC0gDQogICAgbG0oYXMuZm9ybXVsYShwYXN0ZTAocG9zdF92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUsICIgKyAiLCBwcmVfdmFyX25hbWUpKSwNCiAgICAgICBkYXRhID0gZGF0YV93aWRlcikNCiAgY2F0KCJcbiBJbnNwZWN0IHRoZSBtb2RlbCBkaWFnbm9zdGljIG1ldHJpY3MgXG4iKQ0KICBtb2RlbC5tZXRyaWNzIDwtIA0KICAgIGF1Z21lbnQobW9kZWwpICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoLS5oYXQsIC0uc2lnbWEsIC0uZml0dGVkLCAtLnNlLmZpdCkgICU+JSAgICAjIFJlbW92ZSBkZXRhaWxzDQogICAgcHJpbnQoKQ0KICBjYXQoIlxuIE5vcm1hbGl0eSBvZiByZXNpZHVhbHMgKFNoYXBpcm8gV2lsayBwPi4wNSkgXG4iKQ0KICBzaGFwaXJvX3Rlc3QobW9kZWwubWV0cmljcyQucmVzaWQpICU+JSANCiAgICBwcmludCgpDQogIA0KICBjYXQoIlxuIEhvbW9nZW5laXR5IG9mIHZhcmlhbmNlcyAoTGV2ZW5l4oCZcyB0ZXN0IHA+LjA1KSBcbiIpDQogIG1vZGVsLm1ldHJpY3MgJT4lIA0KICAgIGxldmVuZV90ZXN0KGFzLmZvcm11bGEocGFzdGUwKCIucmVzaWQiLCAiIH4gIiwgY29uZF92YXJfbmFtZSkpICkgJT4lICAgICANCiAgICBwcmludCgpDQogIA0KICBjYXQoIlxuIE91dGxpZXJzIChuZWVkcyB0byBiZSAwKSBcbiIpDQogIG1vZGVsLm1ldHJpY3MgJT4lIA0KICAgIGZpbHRlcihhYnMoLnN0ZC5yZXNpZCkgPiAzKSAlPiUNCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lIA0KICAgIHByaW50KCkNCiAgDQogIH0NCiAgDQogIGNhdCgiXG4gQU5DT1ZBUG9zdCBcbiIpDQogIHJlc19hbmNvdmEgPC0gDQogICAgZGF0YV93aWRlciAlPiUgDQogICAgYW5vdmFfdGVzdChhcy5mb3JtdWxhKHBhc3RlMChwb3N0X3Zhcl9uYW1lLCAiIH4gIiwgIHByZV92YXJfbmFtZSwgIiArICIsIGNvbmRfdmFyX25hbWUpKSkgICAgICAgIyB0aGUgY292YXJpYXRlIG5lZWRzIHRvIGJlIGZpcnN0IHRlcm0gDQogIGdldF9hbm92YV90YWJsZShyZXNfYW5jb3ZhKSAlPiUgcHJpbnQoKQ0KICANCiAgY2F0KCJcbiBQYWlyd2lzZSBjb21wYXJpc29ucyBcbiIpDQogIHB3YyA8LSANCiAgICBkYXRhX3dpZGVyICU+JSANCiAgICBlbW1lYW5zX3Rlc3QoYXMuZm9ybXVsYShwYXN0ZTAocG9zdF92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUpKSwgICAgICAgDQogICAgICAgICAgICAgICAgIGNvdmFyaWF0ZSA9ICEhcHJlX3Zhcl9lbnEsDQogICAgICAgICAgICAgICAgIHAuYWRqdXN0Lm1ldGhvZCA9IHBfYWRqdXN0X21ldGhvZCkNCiAgcHdjICU+JSBwcmludCgpDQogIGNhdCgiXG4gRGlzcGxheSB0aGUgYWRqdXN0ZWQgbWVhbnMgb2YgZWFjaCBncm91cCwgYWxzbyBjYWxsZWQgYXMgdGhlIGVzdGltYXRlZCBtYXJnaW5hbCBtZWFucyAoZW1tZWFucykgXG4iKQ0KICBnZXRfZW1tZWFucyhwd2MpICU+JSBwcmludCgpDQogIA0KICAjIFZpc3VhbGl6YXRpb246IGxpbmUgcGxvdHMgd2l0aCBwLXZhbHVlcw0KICBwd2MgPC0gDQogICAgcHdjICU+JSANCiAgICBhZGRfeHlfcG9zaXRpb24oeCA9IGNvbmRfdmFyX25hbWUsIGZ1biA9ICJtZWFuX3NlIikNCiAgDQogIGxpbmVfcGxvdCA8LSANCiAgICBnZ2xpbmUoZ2V0X2VtbWVhbnMocHdjKSwgeCA9IGNvbmRfdmFyX25hbWUsIHkgPSAiZW1tZWFuIikgKw0KICAgICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGNvbmYubG93LCB5bWF4ID0gY29uZi5oaWdoKSwgd2lkdGggPSAwLjIpICsgDQogICAgICBzdGF0X3B2YWx1ZV9tYW51YWwocHdjLCBoaWRlLm5zID0gVFJVRSwgdGlwLmxlbmd0aCA9IEZBTFNFKSArDQogICAgICBsYWJzKHN1YnRpdGxlID0gZ2V0X3Rlc3RfbGFiZWwocmVzX2FuY292YSwgZGV0YWlsZWQgPSBUUlVFKSwNCiAgICAgICAgICAgY2FwdGlvbiA9IGdldF9wd2NfbGFiZWwocHdjKSkNCiAgDQogIGlmKGFzc3VtX2NoZWNrKXsNCiAgICBsaXN0KHNjYXR0ZXJfbGluLCBsaW5lX3Bsb3QpDQogIH1lbHNlew0KICAgIGxpbmVfcGxvdA0KICB9DQogIA0KfQ0KDQojIGV4Lg0KIyBBTkNPVkFQb3N0X2Z1bmMobmV3X2FueGlldHksIHRpbWVfdmFyID0gdGltZSwgcHJlX2xhYmVsID0gcHJldGVzdCwgcG9zdF9sYWJlbCA9IHBvc3R0ZXN0LA0KIyAgICAgICAgICAgdmFsdWVfdmFyID0gc2NvcmVzLCBjb25kX3ZhciA9IGdyb3VwLCBhc3N1bV9jaGVjayA9IFRSVUUsIHBfYWRqdXN0X21ldGhvZCA9ICJib25mZXJyb25pIikNCmBgYA0KDQoNCmBgYHtyIGRlZl9mdW5jX21peGVkQU5PVkF9DQojIGxpYnJhcnkodGlkeXZlcnNlKQ0KIyBsaWJyYXJ5KGdncHVicikNCiMgbGlicmFyeShyc3RhdGl4KQ0KIyBsaWJyYXJ5KHJsYW5nKQ0KDQojIERlZmluZSBGdW5jdGlvbiBmb3IgTWl4ZWQgQW5vdmENCnR3X21peGVkQU5PVkFfZnVuYyA8LSANCiAgZnVuY3Rpb24oZGF0YSwgaWRfdmFyLCBjb25kX3ZhciwgdGltZV92YXIsIHZhbHVlX3ZhciwgDQogICAgICAgICAgIGFzc3VtX2NoZWNrID0gVFJVRSwgcG9zdGhvY19zaWdfaW50ZXJhYyA9IEZBTFNFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBGQUxTRSwNCiAgICAgICAgICAgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKXsNCiAgICANCiAgICAjIGlucHV0IGRhdGFmcmFtZSBuZWVkcyB0byBoYXZlIGNvbHVtbnMgbmFtZXMgZGlmZnJlbnQgZnJvbSAidmFyaWFibGUiIGFuZCAidmFsdWUiIGJlY2F1c2UgaXQgY29sbGlkZXMgd2l0aCByc3RhdGl4OjpzaGFwaXJvX3Rlc3QNCiAgICANCiAgICBpZF92YXJfZW5xIDwtIHJsYW5nOjplbnF1byhpZF92YXIpICANCiAgICBjb25kX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKGNvbmRfdmFyKQ0KICAgIGNvbmRfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUoY29uZF92YXJfZW5xKQ0KICAgIHRpbWVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8odGltZV92YXIpDQogICAgdGltZV92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZSh0aW1lX3Zhcl9lbnEpDQogICAgdmFsdWVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8odmFsdWVfdmFyKQ0KICAgIHZhbHVlX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHZhbHVlX3Zhcl9lbnEpDQogICAgDQogICAgZGF0YSA8LSAgICAgICAgICAgICAgICAgICMgbmVlZCB0byBzdWJzZXQgYmVjdWFzZSBvZiBzdHJhbmdlIGNvbnRyYXN0cyBlcnJvciBpbiBhbm92YV90ZXN0KCkNCiAgICAgIGRhdGEgJT4lDQogICAgICBkcGx5cjo6c2VsZWN0KCEhaWRfdmFyX2VucSwgISF0aW1lX3Zhcl9lbnEsICEhY29uZF92YXJfZW5xLCAhIXZhbHVlX3Zhcl9lbnEpIA0KICAgIA0KICAgICMgQXNzdW1wdGlvbnMNCiAgICBpZihhc3N1bV9jaGVjayl7DQogICAgICBjYXQoIlxuIE91dGxpZXJzIFxuIikNCiAgICAgIGRhdGEgJT4lDQogICAgICAgIGRwbHlyOjpncm91cF9ieSghIXRpbWVfdmFyX2VucSwgISFjb25kX3Zhcl9lbnEpICU+JQ0KICAgICAgICByc3RhdGl4OjppZGVudGlmeV9vdXRsaWVycyghIXZhbHVlX3Zhcl9lbnEpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG91dGxpZXJzIChuZWVkcyB0byBiZSAwKQ0KICAgICAgICBwcmludCgpDQogICAgICANCiAgICAgIGNhdCgiXG4gTm9ybWFsaXR5IGFzc3VtcHRpb24gKHA+LjA1KSBcbiIpDQogICAgICBkYXRhICU+JQ0KICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoISF0aW1lX3Zhcl9lbnEsICEhY29uZF92YXJfZW5xKSAlPiUNCiAgICAgICAgcnN0YXRpeDo6c2hhcGlyb190ZXN0KCEhdmFsdWVfdmFyX2VucSkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm9ybWFsaXR5IGFzc3VtcHRpb24gKHA+LjA1KQ0KICAgICAgICBwcmludCgpDQogICAgICANCiAgICAgIHFxX3Bsb3QgPC0gDQogICAgICAgIGdncHVicjo6Z2dxcXBsb3QoZGF0YSA9IGRhdGEsIHZhbHVlX3Zhcl9uYW1lLCBnZ3RoZW1lID0gdGhlbWVfYncoKSwgdGl0bGUgPSAiUVEgUGxvdCIpICsNCiAgICAgICAgZ2dwbG90Mjo6ZmFjZXRfZ3JpZCh2YXJzKCEhdGltZV92YXJfZW5xKSwgdmFycyghIWNvbmRfdmFyX2VucSksIGxhYmVsbGVyID0gImxhYmVsX2JvdGgiKSAgICAjIFFRIHBsb3QNCiAgICAgIA0KICAgICAgY2F0KCJcbiBIb21vZ25laXR5IG9mIHZhcmlhbmNlIGFzc3VtcHRpb24gLSBMZXZlbmXigJlzIHRlc3QgKHA+LjA1KSBcbiIpDQogICAgICBkYXRhICU+JQ0KICAgICAgICBncm91cF9ieSghIXRpbWVfdmFyX2VucSApICU+JQ0KICAgICAgICBsZXZlbmVfdGVzdChhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUpKSkgJT4lDQogICAgICAgIHByaW50KCkNCiAgICAgIA0KICAgICAgY2F0KCJcbiBIb21vZ2VuZWl0eSBvZiBjb3ZhcmlhbmNlcyBhc3N1bXB0aW9uIC0gQm944oCZcyB0ZXN0IG9mIGVxdWFsaXR5IG9mIGNvdmFyaWFuY2UgbWF0cmljZXMgKHA+LjAwMSkgXG4iKQ0KICAgICAgYm94X20oZGF0YSA9IGRhdGFbLCB2YWx1ZV92YXJfbmFtZSwgZHJvcCA9IEZBTFNFXSwgZ3JvdXAgPSBkYXRhWywgY29uZF92YXJfbmFtZSwgZHJvcCA9IFRSVUVdKSAlPiUNCiAgICAgICAgcHJpbnQNCiAgICB9DQogICAgDQogICAgIyBUd28td2F5IHJtQU5PVkEgLSBjaGVjayBmb3IgaW50ZXJhY3Rpb24gKGV4LiBGKDIsIDIyKSA9IDMwLjQsIHAgPCAwLjAwMDEpDQogICAgY2F0KCJcbiBUd28td2F5IHJtQU5PVkEgXG4iKQ0KICAgIHJlc19hb3YgPC0gDQogICAgICBhbm92YV90ZXN0KGRhdGEgPSBkYXRhLCBkdiA9ICEhdmFsdWVfdmFyX2VucSwgd2lkID0gISFpZF92YXJfZW5xLCAgICAgICAgICAgICAgICMgYXV0b21hdGljYWxseSBkb2VzIHNwaGVyaWNpdHkgTWF1Y2hseeKAmXMgdGVzdA0KICAgICAgICAgICAgICAgICB3aXRoaW4gPSAhIXRpbWVfdmFyX2VucSwgYmV0d2VlbiA9ICEhY29uZF92YXJfZW5xKQ0KICAgIGdldF9hbm92YV90YWJsZShyZXNfYW92KSAlPiUgICMgZ2VzOiBHcmVlbmhvdXNlLUdlaXNzZXIgc3BoZXJpY2l0eSBjb3JyZWN0aW9uIGlzIGF1dG9tYXRpY2FsbHkgYXBwbGllZCB0byBmYWN0b3JzIHZpb2xhdGluZyB0aGUgc3BoZXJpY2l0eSBhc3N1bXB0aW9uICANCiAgICAgIHByaW50KCkNCiAgICANCiAgICANCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICAgIA0KICAgICMtIFByb2NlZHVyZSBmb3IgYSBzaWduaWZpY2FudCB0d28td2F5IGludGVyYWN0aW9uIC0NCiAgICBpZihwb3N0aG9jX3NpZ19pbnRlcmFjKXsNCiAgICAgIGNhdCgiXG4gRWZmZWN0IG9mIGdyb3VwIGF0IGVhY2ggdGltZSBwb2ludCAtIE9uZS13YXkgQU5PVkFcbiIpDQogICAgICBvbmVfd2F5IDwtIA0KICAgICAgICBkYXRhICU+JQ0KICAgICAgICBncm91cF9ieSghIXRpbWVfdmFyX2VucSkgJT4lDQogICAgICAgIGFub3ZhX3Rlc3QoZHYgPSAhIXZhbHVlX3Zhcl9lbnEsIHdpZCA9ICEhaWRfdmFyX2VucSwgYmV0d2VlbiA9ICEhY29uZF92YXJfZW5xKSAlPiUNCiAgICAgICAgZ2V0X2Fub3ZhX3RhYmxlKCkgJT4lDQogICAgICAgIGFkanVzdF9wdmFsdWUobWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kKQ0KICAgICAgb25lX3dheSAlPiUgcHJpbnQoKQ0KICAgICAgDQogICAgICBjYXQoIlxuIFBhaXJ3aXNlIGNvbXBhcmlzb25zIGJldHdlZW4gZ3JvdXAgbGV2ZWxzIFxuIikNCiAgICAgIHB3YyA8LSANCiAgICAgICAgZGF0YSAlPiUNCiAgICAgICAgZ3JvdXBfYnkoISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgICAgICBwYWlyd2lzZV90X3Rlc3QoYXMuZm9ybXVsYShwYXN0ZTAodmFsdWVfdmFyX25hbWUsICIgfiAiLCBjb25kX3Zhcl9uYW1lKSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kKQ0KICAgICAgcHdjICU+JSBwcmludCgpDQogICAgICBjYXQoIlxuIEVmZmVjdCBvZiB0aW1lIGF0IGVhY2ggbGV2ZWwgb2YgZXhlcmNpc2VzIGdyb3VwICAtIE9uZS13YXkgQU5PVkEgXG4iKQ0KICAgICAgb25lX3dheTIgPC0gDQogICAgICAgIGRhdGEgJT4lDQogICAgICAgIGdyb3VwX2J5KCEhY29uZF92YXJfZW5xKSAlPiUNCiAgICAgICAgYW5vdmFfdGVzdChkdiA9ICEhdmFsdWVfdmFyX2VucSwgd2lkID0gISFpZF92YXJfZW5xLCB3aXRoaW4gPSAhIXRpbWVfdmFyX2VucSkgJT4lDQogICAgICAgIGdldF9hbm92YV90YWJsZSgpICU+JQ0KICAgICAgICBhZGp1c3RfcHZhbHVlKG1ldGhvZCA9IHBfYWRqdXN0X21ldGhvZCkNCiAgICAgIG9uZV93YXkyICU+JSBwcmludCgpDQogICAgICANCiAgICAgIGNhdCgiXG4gUGFpcndpc2UgY29tcGFyaXNvbnMgYmV0d2VlbiB0aW1lIHBvaW50cyBhdCBlYWNoIGdyb3VwIGxldmVscyAod2UgaGF2ZSByZXBlYXRlZCBtZWFzdXJlcyBieSB0aW1lKSBcbiIpDQogICAgICBwd2MyIDwtDQogICAgICAgIGRhdGEgJT4lDQogICAgICAgIGdyb3VwX2J5KCEhY29uZF92YXJfZW5xKSAlPiUNCiAgICAgICAgcGFpcndpc2VfdF90ZXN0KA0KICAgICAgICAgIGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgdGltZV92YXJfbmFtZSkpLCAgICAgIyBwYXN0ZSBmb3JtdWxhLCBub3QgcXVvc3VyZQ0KICAgICAgICAgIHBhaXJlZCA9IFRSVUUsDQogICAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kDQogICAgICAgICkNCiAgICAgIHB3YzIgICU+JSBwcmludCgpDQogICAgfQ0KICAgIA0KICAgICMtIFByb2NlZHVyZSBmb3Igbm9uLXNpZ25pZmljYW50IHR3by13YXkgaW50ZXJhY3Rpb24tIA0KICAgICMgSWYgdGhlIGludGVyYWN0aW9uIGlzIG5vdCBzaWduaWZpY2FudCwgeW91IG5lZWQgdG8gaW50ZXJwcmV0IHRoZSBtYWluIGVmZmVjdHMgZm9yIGVhY2ggb2YgdGhlIHR3byB2YXJpYWJsZXM6IHRyZWF0bWVudCBhbmQgdGltZS4NCiAgICBpZihwb3N0aG9jX25zX2ludGVyYWMpew0KICAgICAgY2F0KCJcbiBDb21wYXJpc29ucyBmb3IgdHJlYXRtZW50IHZhcmlhYmxlIFxuIikNCiAgICAgIHB3Y19jb25kIDwtDQogICAgICAgIGRhdGEgJT4lDQogICAgICAgIHBhaXJ3aXNlX3RfdGVzdCgNCiAgICAgICAgICBhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUpKSwgICAgICMgcGFzdGUgZm9ybXVsYSwgbm90IHF1b3N1cmUgICAgICAgICAgICAgDQogICAgICAgICAgcGFpcmVkID0gRkFMU0UsDQogICAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kDQogICAgICAgICkNCiAgICAgIHB3Y19jb25kICU+JSBwcmludCgpDQogICAgICBjYXQoIlxuIENvbXBhcmlzb25zIGZvciB0aW1lIHZhcmlhYmxlIFxuIikNCiAgICAgIHB3Y190aW1lIDwtDQogICAgICAgIGRhdGEgJT4lIA0KICAgICAgICBwYWlyd2lzZV90X3Rlc3QoDQogICAgICAgICAgYXMuZm9ybXVsYShwYXN0ZTAodmFsdWVfdmFyX25hbWUsICIgfiAiLCB0aW1lX3Zhcl9uYW1lKSksICAgICAjIHBhc3RlIGZvcm11bGEsIG5vdCBxdW9zdXJlDQogICAgICAgICAgcGFpcmVkID0gVFJVRSwNCiAgICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QNCiAgICAgICAgKQ0KICAgICAgcHdjX3RpbWUgJT4lIHByaW50KCkNCiAgICB9DQogICAgDQogICAgIyBWaXN1YWxpemF0aW9uDQogICAgYnhfcGxvdCA8LSANCiAgICAgIGdnYm94cGxvdChkYXRhLCB4ID0gdGltZV92YXJfbmFtZSwgeSA9IHZhbHVlX3Zhcl9uYW1lLA0KICAgICAgICAgICAgICAgIGNvbG9yID0gY29uZF92YXJfbmFtZSwgcGFsZXR0ZSA9ICJqY28iKQ0KICAgIHB3YyA8LSANCiAgICAgIHB3YyAlPiUgDQogICAgICBhZGRfeHlfcG9zaXRpb24oeCA9IHRpbWVfdmFyX25hbWUpDQogICAgYnhfcGxvdCA8LSANCiAgICAgIGJ4X3Bsb3QgKyANCiAgICAgIHN0YXRfcHZhbHVlX21hbnVhbChwd2MsIHRpcC5sZW5ndGggPSAwLCBoaWRlLm5zID0gVFJVRSkgKw0KICAgICAgbGFicygNCiAgICAgICAgc3VidGl0bGUgPSBnZXRfdGVzdF9sYWJlbChyZXNfYW92LCBkZXRhaWxlZCA9IFRSVUUpLA0KICAgICAgICBjYXB0aW9uID0gZ2V0X3B3Y19sYWJlbChwd2MpDQogICAgICApDQogICAgDQogICAgaWYoYXNzdW1fY2hlY2speyANCiAgICAgIGxpc3QocXFfcGxvdCwgYnhfcGxvdCkNCiAgICB9ZWxzZXsNCiAgICAgIGJ4X3Bsb3QNCiAgICB9IA0KICAgIA0KICB9DQoNCiMgZXguIC0gcnVuIG9uIGxvbmcgZm9ybWF0DQojIHR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gYW54aWV0eSwgaWRfdmFyID0gaWQsIGNvbmRfdmFyID0gZ3JvdXAsIHRpbWVfdmFyID0gdGltZSwgdmFsdWVfdmFyID0gc2NvcmUsDQojICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KYGBgDQoNCg0KDQojIFJlYWQsIENsZWFuLCBSZWNvZGUNCg0KYGBge3IgcmVkX2NsZWFuX3JlY29kZV9tZXJnZSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0V9DQojfn5+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+fg0KIyBSZWFkLCBDbGVhbiwgUmVjb2RlLCBVbml0ZQ0KI35+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+fn4NCg0KIyMgUmVhZCBmaWxlcw0KZm9sZGVyIDwtICJDOi9Vc2Vycy9NaWhhaS9EZXNrdG9wL1IgTm90ZWJvb2tzL25vdGVib29rcy9QQTQtcmVwb3J0Ig0Kb2xkX2ZpbGUgPC0gIkRhdGVfcHRfYW5hbGl6YV9QQTRvbmxpbmUueGxzeCINCmZpbGUgPC0gIkRhdGVfcHRfYW5hbGl6YV9QQTRvbmxpbmUgLSBGaW5hbDIueGxzeCINCg0Kc2V0d2QoZm9sZGVyKQ0KDQojIElEIGRmDQppZF9kZiA8LSByaW86OmltcG9ydChmaWxlLnBhdGgoZm9sZGVyLCBmaWxlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMSwgd2hpY2ggPSAiSUQtdXJpIGF0cmlidWl0ZSIpICAgDQppZF9kZiA8LSANCiAgaWRfZGYgJT4lDQogIGRwbHlyOjptdXRhdGUoSUQgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoSUQsIGZpeGVkKCIgIiksICIiKSkgICAgICMgcmVtb3ZlIHdoaXRlIHNwYWNlcw0KYWxsKGlkX2RmJElEID09IHRvdXBwZXIoaWRfZGYkSUQpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNoZWNrIGlmIGFsbCBhcmUgdXBwZXIgY2FzZQ0KaWRfZGZbLCAiZS1tYWlsIl0gPC0gdG9sb3dlcihpZF9kZlssICJlLW1haWwiXSkNCmlkX2RmIDwtIGlkX2RmWyFkdXBsaWNhdGVkKGlkX2RmKSxdICAgICAgICAgICAgICAgICAgICMgMzYgZHVwbGljYXRlZCwgMTE1IHVuaXF1ZQ0KDQpmaXJzdGZvcm1fZGYgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IDAsIHdoaWNoID0gIkZvcm11bGFyIGRlIMOubnNjcmllcmUgyJlpIGNvbnNpbSIpDQpmaXJzdGZvcm1fZGYgPC0gZmlyc3Rmb3JtX2RmWywgLWxlbmd0aChmaXJzdGZvcm1fZGYpXSAgICAgICAgICAgICAgICAgICMgYSBjb2x1bW4gIndvcmsiIHdhcyBhZGRlZCB0byB0aGUgZW5kIA0Kb2xkX2ZpbGVfZmlyc3Rmb3JtX2RmIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIG9sZF9maWxlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMCwgd2hpY2ggPSAiRm9ybXVsYXIgZGUgw65uc2NyaWVyZSDImWkgY29uc2ltIikgDQppZihhbGwuZXF1YWwoY29sbmFtZXMoZmlyc3Rmb3JtX2RmKSwgY29sbmFtZXMob2xkX2ZpbGVfZmlyc3Rmb3JtX2RmKSkpIHtybShvbGRfZmlsZV9maXJzdGZvcm1fZGYpfQ0KDQoNCmNvbG5hbWVzKGZpcnN0Zm9ybV9kZilbN10gPC0gImUtbWFpbCINCmZpcnN0Zm9ybV9kZlssICJlLW1haWwiXSA8LSB0b2xvd2VyKGZpcnN0Zm9ybV9kZlssICJlLW1haWwiXSkNCg0KYmFzZWxpbmVfZGYgPC0gZHBseXI6OmxlZnRfam9pbihpZF9kZiwgZmlyc3Rmb3JtX2RmLCBieSA9ICJlLW1haWwiKQ0KYmFzZWxpbmVfZGYgPC0gDQogIGJhc2VsaW5lX2RmICU+JQ0KICBkcGx5cjo6c2VsZWN0KGNvbG5hbWVzKGZpcnN0Zm9ybV9kZiksIGV2ZXJ5dGhpbmcoKSkgICAgICMgbW92ZSBjb2xzIGZyb20gaWRfZGYgdG8gYmFjayBzbyB3ZSBoYXZlIG1hdGNoaW5nIGNvbHMgaW5kZXggZm9yIGJhc2VsaW5lX2RmICYgZmlyc3Rmb3JtX2RmDQphbGwuZXF1YWwoY29sbmFtZXMoYmFzZWxpbmVfZGYpWzE6MTcyXSwgY29sbmFtZXMoZmlyc3Rmb3JtX2RmKVsxOjE3Ml0pICAgICAgICAgICAgICMgY2hlY2sgaWYgY29sbmFtZXMgbWF0Y2gsIGV4Y2VwdCBJRCBhbmQgbmFtZSB0aGF0IHdoZXJlIGFkZGVkDQoNCnRhYmxlKGJhc2VsaW5lX2RmJElEKSAjIHNvbWUgSURzIGFyZSBkb3VibGVkDQpgYGANCg0KDQpgYGB7ciBkYXNkfQ0KIyMgU2V0dGluZ3MNCmN1dG9mZlBDTCA8LSAzMiAgICMgbGl0ZXJhdHVyZTogMzEtMzMgb3IgMzggDQphbGdQQ0wgPC0gZGF0YS5mcmFtZShCID0gMSwgQyA9IDEsIEQgPSAyLCBFID0gMikNCmFsZ1BDTF9zdWJjbGluIDwtIGRhdGEuZnJhbWUoQiA9IDEsIEMgPSAxLCBEID0gMSwgRSA9IDEpDQoNCmN1dG9mZk1CSV9FeCA8LSAyLjIwICANCmN1dG9mZk1CSV9DeSA8LSAyDQojIw0KDQojIyBEYXRhDQpEYXRhIDwtIGJhc2VsaW5lX2RmDQojIw0KDQojIERlZmluZSBjb2x1bW4gaW5kZXg6ICBpbmRleCA9IGNvbCBpbmRleDsgaXRlbWluZGV4ID0gaW5kZXggb2YgaXRlbSBpbiBxdWVzdGlvbm5haXJlDQppbmRleFNJRyA8LSA2MDo2NyAtIDEwICAgICMgbW9kaWZpZWQgaW4gbmV3IHRhYmxlIGJ5IDEwDQppbmRleE1CSSA8LSA2ODo4MyAtIDEwDQppbmRleFBDTCA8LSAxNTk6MTc4IC0gMTANCml0ZW1pbmRleE1CSV9FeCA8LSBjKDEsIDMsIDUsIDExLCAxNCkNCml0ZW1pbmRleE1CSV9DeSA8LSBjKDIsIDcsIDgsIDEzLCAxNSkNCml0ZW1pbmRleE1CSV9QZSA8LSBjKDQsIDYsIDksIDEwLCAxMiwgMTYpDQoNCiMgUmVuYW1lIGNvbHVtbnMNCiMgbmFtZXMoRGF0YSlbMToxMl0gPC0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKG5hbWVzKERhdGEpWzE6MTJdLCAiW1s6Ymxhbms6XV0iLCAiXyIpDQojIG5hbWVzKERhdGEpWzE3XSA8LSAiUmVhbF9FbWFpbCINCiMgbmFtZXMoRGF0YSlbMThdIDwtICJSZWFsX1RlbCINCiMgbmFtZXMoRGF0YSlbMTldIDwtICJSZWFsX05hbWUiDQojIG5hbWVzKERhdGEpWzUwXSA8LSAiUmVhbF9BZ2VfY2F0ZWciDQoNCm5hbWVzKERhdGEpWzldIDwtICJudW1lIg0KbmFtZXMoRGF0YSlbNDBdIDwtICJBZ2VfY2F0ZWciDQpuYW1lcyhEYXRhKVs0MV0gPC0gIlNleCINCg0KbmFtZXMoRGF0YSlbbmFtZXMoRGF0YSkgJWluJSBuYW1lcyhEYXRhWywgaW5kZXhTSUddKV0gIDwtIGMoc3ByaW50ZigiU0lHXyUwMWQiLCBzZXEoMSwgOCkpKQ0KbmFtZXMoRGF0YSlbbmFtZXMoRGF0YSkgJWluJSBuYW1lcyhEYXRhWywgaW5kZXhNQkldKV0gIDwtIGMoc3ByaW50ZigiTUJJXyUwMWQiLCBzZXEoMSwgMTYpKSkNCm5hbWVzKERhdGEpW25hbWVzKERhdGEpICVpbiUgbmFtZXMoRGF0YVssIGluZGV4UENMXSldICA8LSBjKHNwcmludGYoIlBDTF8lMDFkIiwgc2VxKDEsIDIwKSkpDQoNCg0KIyBEYXRhIDwtDQojICAgRGF0YSAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKFJlc3BvbnNlX1N0YXR1cyA9PSAiY29tcGxldGVkIikgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2VsZWN0IG9ubHkgY29tcGxldGUgY2FzZXMNCiANCg0KIyBSZWNvZGUgDQojIyBEZWZpbmUgZnVuY3Rpb24gdGhhdCByZWNvZGVzIHRvIG51bWVyaWMsIGJ1dCB3YXRjaGVzIG91dCB0byBjb2VyY2lvbiB0byBub3QgaW50cm9kdWNlIE5Bcw0KY29sc3RvbnVtZXJpYyA8LSBmdW5jdGlvbihkZil7DQogIHRyeUNhdGNoKHsNCiAgICBkZl9udW0gPC0gYXMuZGF0YS5mcmFtZSgNCiAgICAgIGxhcHBseShkZiwNCiAgICAgICAgICAgICBmdW5jdGlvbih4KSB7IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgpKX0pKSANCiAgfSx3YXJuaW5nID0gZnVuY3Rpb24oc3RvcF9vbl93YXJuaW5nKSB7DQogICAgbWVzc2FnZSgiU3RvcGVkIHRoZSBleGVjdXRpb24gb2YgbnVtZXJpYyBjb252ZXJzaW9uOiAiLCBjb25kaXRpb25NZXNzYWdlKHN0b3Bfb25fd2FybmluZykpDQogIH0pIA0KfQ0KIyMNCiMjIERlZmluZSBmdW5jdGlvbiB0aGF0IHJldmVyc2UgY29kZXMgaXRlbXMNClJldmVyc2VDb2RlIDwtIGZ1bmN0aW9uKGRmLCB0b251bWVyaWMgPSBGQUxTRSwgbWluID0gTlVMTCwgbWF4ID0gTlVMTCkgew0KICBpZih0b251bWVyaWMpIGRmIDwtIGNvbHN0b251bWVyaWMoZGYpDQogIGRmIDwtIChtYXggKyBtaW4pIC0gZGYNCn0NCiMjDQoNCiMgbGFwcGx5KERhdGFbLGluZGV4UENMXSwgdW5pcXVlKQ0KRGF0YVsgLGluZGV4UENMXVsgRGF0YVsgLGluZGV4UENMXSA9PSAiZGVsb2MiXSA8LSAiMCINCkRhdGFbICxpbmRleFBDTF1bIERhdGFbICxpbmRleFBDTF0gPT0gInB1yJtpbiJdIDwtICIxIg0KRGF0YVsgLGluZGV4UENMXVsgRGF0YVsgLGluZGV4UENMXSA9PSAibW9kZXJhdCJdIDwtICIyIg0KRGF0YVsgLGluZGV4UENMXVsgRGF0YVsgLGluZGV4UENMXSA9PSAibXVsdCJdIDwtICIzIg0KRGF0YVsgLGluZGV4UENMXVsgRGF0YVsgLGluZGV4UENMXSA9PSAiZm9hcnRlIG11bHQiXSA8LSAiNCINCkRhdGFbICxpbmRleFBDTF1bIERhdGFbICxpbmRleFBDTF0gPT0gIk5vdCBBbnN3ZXJlZCJdIDwtIE5BDQoNCkRhdGFbICxpbmRleFNJR11bIERhdGFbICxpbmRleFNJR10gPT0gIk5VIl0gPC0gIjAiDQpEYXRhWyAsaW5kZXhTSUddWyBEYXRhWyAsaW5kZXhTSUddID09ICI/Il0gPC0gIjEuNSINCkRhdGFbICxpbmRleFNJR11bIERhdGFbICxpbmRleFNJR10gPT0gIkRBIl0gPC0gIjMiDQpEYXRhWyAsaW5kZXhTSUddWyBEYXRhWyAsaW5kZXhTSUddID09ICJOb3QgQW5zd2VyZWQiXSA8LSBOQQ0KDQpEYXRhWyAsaW5kZXhNQkldIDwtIGRhdGEuZnJhbWUobGFwcGx5KERhdGFbICxpbmRleE1CSV0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLipOaWNpb2RhdC4qIiwgIjAiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpEYXRhWyAsaW5kZXhNQkldIDwtIGRhdGEuZnJhbWUobGFwcGx5KERhdGFbICxpbmRleE1CSV0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLipaaWxuaWMuKiIsICI2IiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KRGF0YVsgLGluZGV4TUJJXVsgRGF0YVsgLGluZGV4TUJJXSA9PSAiTm90IEFuc3dlcmVkIl0gPC0gTkENCg0KDQpEYXRhWywgaW5kZXhTSUddIDwtIGNvbHN0b251bWVyaWMoRGF0YVssIGluZGV4U0lHXSkNCkRhdGFbLCBpbmRleE1CSV0gPC0gY29sc3RvbnVtZXJpYyhEYXRhWywgaW5kZXhNQkldKQ0KRGF0YVssIGluZGV4UENMXSA8LSBjb2xzdG9udW1lcmljKERhdGFbLCBpbmRleFBDTF0pDQoNCg0KDQojIFNjb3Jlcw0KIyMgRGVmaW5lIGZ1bmN0aW9uIHRoYXQgc2NvcmVzIG9ubHkgcm93cyB3aXRoIGxlc3MgdGhhbiAxMCUgTkFzIChyZXR1cm5zIE5BIGlmIGFsbCBvciBhYm92ZSB0aHJlc2hvbGQgcGVyY2VudGFnZSBvZiByb3dzIGFyZSBOQSk7IGNhbiByZXZlcnNlIGNvZGUgaWYgdmVjdG9yIG9mIGNvbHVtbiBpbmRleGVzIGFuZCBtaW4sIG1heCBhcmUgcHJvdmlkZWQuDQpTY29yZUxpa2VydCA8LSBmdW5jdGlvbihkZiwgc3RhdCA9ICJzdW0iLCBuYXRvemVybyA9IEZBTFNFLCBuYXBlcmNlbnQgPSAuMSwgdG9udW1lcmljID0gRkFMU0UsIHJldmVyc2Vjb2xzID0gTlVMTCwgbWluID0gTlVMTCwgbWF4ID0gTlVMTCkgew0KICByZXZlcnNlX2xpc3QgPC0gbGlzdChyZXZlcnNlY29scyA9IHJldmVyc2Vjb2xzLCBtaW4gPSBtaW4sIG1heCA9IG1heCkNCiAgcmV2ZXJzZV9jaGVjayA8LSAhc2FwcGx5KHJldmVyc2VfbGlzdCwgaXMubnVsbCkNCiAgDQogICMgUmVjb2RlIHRvIG51bWVyaWMsIGJ1dCB3YXRjaCBvdXQgdG8gY29lcmNpb24gdG8gbm90IGludHJvZHVjZSBOQXMNCiAgY29sc3RvbnVtZXJpYyA8LSBmdW5jdGlvbihkZil7DQogICAgdHJ5Q2F0Y2goew0KICAgICAgZGZfbnVtIDwtIGFzLmRhdGEuZnJhbWUoDQogICAgICAgIGxhcHBseShkZiwNCiAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHsgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeCkpfSkpIA0KICAgIH0sd2FybmluZyA9IGZ1bmN0aW9uKHN0b3Bfb25fd2FybmluZykgew0KICAgICAgbWVzc2FnZSgiU3RvcGVkIHRoZSBleGVjdXRpb24gb2YgbnVtZXJpYyBjb252ZXJzaW9uOiAiLCBjb25kaXRpb25NZXNzYWdlKHN0b3Bfb25fd2FybmluZykpDQogICAgfSkgDQogIH0NCiAgDQogIGlmKHRvbnVtZXJpYykgZGYgPC0gY29sc3RvbnVtZXJpYyhkZikNCiAgDQogIGlmKGFsbChyZXZlcnNlX2NoZWNrKSl7DQogICAgZGZbICxyZXZlcnNlY29sc10gPC0gKG1heCArIG1pbikgLSBkZlsgLHJldmVyc2Vjb2xzXQ0KICB9ZWxzZSBpZihhbnkocmV2ZXJzZV9jaGVjaykpew0KICAgIHN0b3AoIkluc3VmaWNpZW50IGluZm8gZm9yIHJldmVyc2luZy4gUGxlYXNlIHByb3ZpZGU6ICIsIHBhc3RlKG5hbWVzKHJldmVyc2VfbGlzdClbIXJldmVyc2VfY2hlY2tdLCBjb2xsYXBzZSA9ICIsICIpKQ0KICB9DQogIA0KICBpZih0b251bWVyaWMpIGRmIDwtIGNvbHN0b251bWVyaWMoZGYpICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIA0KICBpZihuYXRvemVybykgZGZbaXMubmEoZGYpXSA8LSAwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBOQXMgdG8gMCBjYW4gaGVscCB3aGVuIHN0YXQgPSAibWVhbiIgd2l0aCBuYS5ybSA9IFQgYmVjYXVzZSBpdCBrZWVwcyBkZW5vbWluYXRvciBjb25zdGFudA0KICANCiAgaWYoc3RhdCA9PSAic3VtIil7DQogIGRmX3JlcyA8LSBpZmVsc2Uocm93U3Vtcyhpcy5uYShkZikpID4gbmNvbChkZikgKiBuYXBlcmNlbnQsDQogICAgICAgICAgICAgICAgICAgTkEsDQogICAgICAgICAgICAgICAgICAgcm93U3VtcyhkZiwgbmEucm0gPSBUUlVFKSAqIE5BIF4gKHJvd1N1bXMoIWlzLm5hKGRmKSkgPT0gMCkpDQogIH0NCiAgaWYoc3RhdCA9PSAibWVhbiIpew0KICAgIGRmX3JlcyA8LSBpZmVsc2Uocm93U3Vtcyhpcy5uYShkZikpID4gbmNvbChkZikgKiBuYXBlcmNlbnQsDQogICAgICAgICAgICAgICAgICAgICBOQSwNCiAgICAgICAgICAgICAgICAgICAgIHJvd01lYW5zKGRmLCBuYS5ybSA9IFRSVUUpICogTkEgXiAocm93U3VtcyghaXMubmEoZGYpKSA9PSAwKSkNCiAgfQ0KICByZXR1cm4oZGZfcmVzKQ0KfQ0KIyMNCg0KDQojIFNjb3JlIFBDTA0KRGF0YSRQQ0xfVG90YWwgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGluZGV4UENMXSwgbmFwZXJjZW50ID0gLjMpICAgICAgICAgICAgICAgIyBOQSBpZiBOQSB0aHJlc2hvbGQgaXMgZXhjZWVkZWQgDQpEYXRhJFBDTF9CIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKHNwcmludGYoIlBDTF8lMDFkIiwgMTo1KSldLCBuYXBlcmNlbnQgPSAxKSAgICAjIGRvIG5vdGhpbmcgaWYgTkEgdGhyZXNob2xkIGlzIGV4Y2VlZGVkDQpEYXRhJFBDTF9DIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKHNwcmludGYoIlBDTF8lMDFkIiwgNjo3KSldLCBuYXBlcmNlbnQgPSAxKSANCkRhdGEkUENMX0QgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoc3ByaW50ZigiUENMXyUwMWQiLCA4OjE0KSldLCBuYXBlcmNlbnQgPSAxKSAgDQpEYXRhJFBDTF9FIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKHNwcmludGYoIlBDTF8lMDFkIiwgMTU6MjApKV0sIG5hcGVyY2VudCA9IDEpDQoNCiMgU2NvcmUgU0lHDQpEYXRhJFNJR19Ub3RhbCA8LSBTY29yZUxpa2VydChEYXRhWywgaW5kZXhTSUddLCBuYXBlcmNlbnQgPSAuMykNCg0KIyBTY29yZSBNQkkNCkRhdGEkTUJJX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBpbmRleE1CSV0sIG5hcGVyY2VudCA9IC4zLCBzdGF0ID0gIm1lYW4iLCBuYXRvemVybyA9IFRSVUUpDQpEYXRhJE1CSV9FeCA8LSBTY29yZUxpa2VydChEYXRhWywgYyhzcHJpbnRmKCJNQklfJTAxZCIsIGl0ZW1pbmRleE1CSV9FeCkpXSwgbmFwZXJjZW50ID0gMSwgc3RhdCA9ICJtZWFuIiwgbmF0b3plcm8gPSBUUlVFKQ0KRGF0YSRNQklfQ3kgPC0gU2NvcmVMaWtlcnQoRGF0YVssIGMoc3ByaW50ZigiTUJJXyUwMWQiLCBpdGVtaW5kZXhNQklfQ3kpKV0sIG5hcGVyY2VudCA9IDEsIHN0YXQgPSAibWVhbiIsIG5hdG96ZXJvID0gVFJVRSkNCkRhdGEkTUJJX1BlIDwtIFNjb3JlTGlrZXJ0KERhdGFbLCBjKHNwcmludGYoIk1CSV8lMDFkIiwgaXRlbWluZGV4TUJJX1BlKSldLCBuYXBlcmNlbnQgPSAxLCBzdGF0ID0gIm1lYW4iLCBuYXRvemVybyA9IFRSVUUpDQoNCg0KIyBQQ0wgRGlhZ25vc3RpYyBBbGdvcml0aG0NCml0ZW1zUENMX0IgPC0gYyhzcHJpbnRmKCJQQ0xfJTAxZCIsIDE6NSkpDQppdGVtc1BDTF9DIDwtIGMoc3ByaW50ZigiUENMXyUwMWQiLCA2OjcpKQ0KaXRlbXNQQ0xfRCA8LSBjKHNwcmludGYoIlBDTF8lMDFkIiwgODoxNCkpDQppdGVtc1BDTF9FIDwtIGMoc3ByaW50ZigiUENMXyUwMWQiLCAxNToyMCkpDQoNCkRhdGFQQ0xBbGcgPC0gIA0KICBEYXRhICU+JSANCiAgZHBseXI6OnNlbGVjdCh0aWR5c2VsZWN0OjphbGxfb2YoaW5kZXhQQ0wpKSAlPiUgDQogIGRwbHlyOjptdXRhdGVfYWxsKA0KICAgIGZ1bnMoY2FzZV93aGVuKA0KICAgICAgLiA+PTIgfiAxLA0KICAgICAgIyAuIDwyIH4gMCwNCiAgICAgIGlzLm5hKC4pIH4gMCwNCiAgICAgIFRSVUUgIH4gIDApKSkgJT4lIA0KICANCiAgbXV0YXRlKFBDTF9Dcml0QiA9IGNhc2Vfd2hlbihyb3dTdW1zKC5bLGl0ZW1zUENMX0JdLCBuYS5ybSA9IFRSVUUpID49IGFsZ1BDTCRCIH4gMSwgICAgICAjIGFsZ1BDTCA8LSBkYXRhLmZyYW1lKEIgPSAxLCBDID0gMSwgRCA9IDIsIEUgPSAyKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgcm93U3VtcyguWyxpdGVtc1BDTF9CXSwgbmEucm0gPSBUUlVFKSA8MSB+IDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgfiAgMCkpICU+JSANCiAgbXV0YXRlKFBDTF9Dcml0QyA9IGNhc2Vfd2hlbihyb3dTdW1zKC5bLGl0ZW1zUENMX0NdLCBuYS5ybSA9IFRSVUUpID49IGFsZ1BDTCRDIH4gMSwgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyByb3dTdW1zKC5bLGl0ZW1zUENMX0NdLCBuYS5ybSA9IFRSVUUpIDwxIH4gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICB+ICAwKSkgJT4lIA0KICBtdXRhdGUoUENMX0NyaXREID0gY2FzZV93aGVuKHJvd1N1bXMoLlssaXRlbXNQQ0xfRF0sIG5hLnJtID0gVFJVRSkgPj0gYWxnUENMJEQgfiAxLCAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgcm93U3VtcyguWyxpdGVtc1BDTF9EXSwgbmEucm0gPSBUUlVFKSA8MSB+IDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgfiAgMCkpICU+JSANCiAgbXV0YXRlKFBDTF9Dcml0RSA9IGNhc2Vfd2hlbihyb3dTdW1zKC5bLGl0ZW1zUENMX0VdLCBuYS5ybSA9IFRSVUUpID49IGFsZ1BDTCRFIH4gMSwgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyByb3dTdW1zKC5bLGl0ZW1zUENMX0VdLCBuYS5ybSA9IFRSVUUpIDwxIH4gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICB+ICAwKSkgJT4lIA0KICBtdXRhdGUoUENMX0FsZyA9IGNhc2Vfd2hlbihQQ0xfQ3JpdEIgPT0gMSAmIFBDTF9Dcml0QyA9PSAxICYgUENMX0NyaXREID09IDEgJiBQQ0xfQ3JpdEUgPT0gMSB+IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgIH4gIDApKSANCg0KRGF0YSRQQ0xBbGcgPC0gRGF0YVBDTEFsZyRQQ0xfQWxnDQoNCkRhdGFQQ0xBbGdfc3ViY2xpbiA8LSAgDQogIERhdGEgJT4lIA0KICBkcGx5cjo6c2VsZWN0KHRpZHlzZWxlY3Q6OmFsbF9vZihpbmRleFBDTCkpICU+JSANCiAgZHBseXI6Om11dGF0ZV9hbGwoDQogICAgZnVucyhjYXNlX3doZW4oDQogICAgICAuID49MiB+IDEsDQogICAgICAjIC4gPDIgfiAwLA0KICAgICAgaXMubmEoLikgfiAwLA0KICAgICAgVFJVRSAgfiAgMCkpKSAlPiUgDQogIA0KICBtdXRhdGUoUENMX0NyaXRCID0gY2FzZV93aGVuKHJvd1N1bXMoLlssaXRlbXNQQ0xfQl0sIG5hLnJtID0gVFJVRSkgPj0gYWxnUENMX3N1YmNsaW4kQiB+IDEsICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHJvd1N1bXMoLlssaXRlbXNQQ0xfQl0sIG5hLnJtID0gVFJVRSkgPDEgfiAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgIH4gIDApKSAlPiUgDQogIG11dGF0ZShQQ0xfQ3JpdEMgPSBjYXNlX3doZW4ocm93U3VtcyguWyxpdGVtc1BDTF9DXSwgbmEucm0gPSBUUlVFKSA+PSBhbGdQQ0xfc3ViY2xpbiRDIH4gMSwgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyByb3dTdW1zKC5bLGl0ZW1zUENMX0NdLCBuYS5ybSA9IFRSVUUpIDwxIH4gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICB+ICAwKSkgJT4lIA0KICBtdXRhdGUoUENMX0NyaXREID0gY2FzZV93aGVuKHJvd1N1bXMoLlssaXRlbXNQQ0xfRF0sIG5hLnJtID0gVFJVRSkgPj0gYWxnUENMX3N1YmNsaW4kRCB+IDEsICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyByb3dTdW1zKC5bLGl0ZW1zUENMX0RdLCBuYS5ybSA9IFRSVUUpIDwxIH4gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICB+ICAwKSkgJT4lIA0KICBtdXRhdGUoUENMX0NyaXRFID0gY2FzZV93aGVuKHJvd1N1bXMoLlssaXRlbXNQQ0xfRV0sIG5hLnJtID0gVFJVRSkgPj0gYWxnUENMX3N1YmNsaW4kRSB+IDEsICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgcm93U3VtcyguWyxpdGVtc1BDTF9FXSwgbmEucm0gPSBUUlVFKSA8MSB+IDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgfiAgMCkpICU+JSANCiAgbXV0YXRlKFBDTF9BbGdfc3ViY2xpbiA9IGNhc2Vfd2hlbihQQ0xfQ3JpdEIgPT0gMSAmIFBDTF9Dcml0QyA9PSAxICYgUENMX0NyaXREID09IDEgJiBQQ0xfQ3JpdEUgPT0gMSB+IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgfiAgMCkpIA0KDQpEYXRhJFBDTEFsZ19zdWJjbGluIDwtIERhdGFQQ0xBbGdfc3ViY2xpbiRQQ0xfQWxnX3N1YmNsaW4NCg0KRGF0YSRNQklfRXhfY3V0IDwtIGlmZWxzZShEYXRhJE1CSV9FeCA+PSBjdXRvZmZNQklfRXgsIDEsIDApDQpEYXRhJE1CSV9DeV9jdXQgPC0gaWZlbHNlKERhdGEkTUJJX0N5ID49IGN1dG9mZk1CSV9DeSwgMSwgMCkNCg0KDQojIEdsb2JhbCBTY3JlZW5pbmcgJiBHcm91cHMNCmRmX3NjcmVlbmluZyA8LSBEYXRhWyxjKCJJRCIsICJudW1lIiwgImUtbWFpbCIsICJBZ2VfY2F0ZWciLCAiU2V4IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJTSUdfVG90YWwiLCAiTUJJX0V4IiwgIk1CSV9DeSIsICJNQklfRXhfY3V0IiwgIk1CSV9DeV9jdXQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIlBDTF9Ub3RhbCIsICJQQ0xfQiIsICJQQ0xfQyIsICJQQ0xfRCIsICJQQ0xfRSIsICJQQ0xBbGciLCAiUENMQWxnX3N1YmNsaW4iKV0NCg0KDQoNCiMgQ2hlY2sgc2FtZSByZXN1bHQgd2l0aCBzY3JlZW5pbmcgZG9uZSBvbiBHb29nbGUgQ29sYWIgDQojIGNoZWNrX2cgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgImNoZWNrX3NjcmVlbmluZyIsICJQQTRfU2NyZWVuaW5nIDIwMjEtMDEtMTggMThfMDNfNDBDSEVDSy54bHN4IikpIA0KIyBjaGVja19sIDwtIGRmX3NjcmVlbmluZw0KIyANCiMgY2hlY2tfbWVyZ2UgPC0gZnVsbF9qb2luKGNoZWNrX2wsIGNoZWNrX2csIGJ5ID0gYygiZS1tYWlsIiA9ICJSZWFsX0VtYWlsIikpDQojIA0KIyBuYW1lc19sIDwtIHBhc3RlMChjKCJTSUdfVG90YWwiLCAiTUJJX0V4X2N1dCIsICJNQklfQ3lfY3V0IiwgIlBDTF9Ub3RhbCIsICJQQ0xfQiIsICJQQ0xfQyIsICJQQ0xfRCIsICJQQ0xfRSIsICJQQ0xBbGciLCAiUENMQWxnX3N1YmNsaW4iKSwgIi54IikNCiMgbmFtZXNfZyA8LSBwYXN0ZTAoYygiU0lHX1RvdGFsIiwgIk1CSV9FeF9jdXQiLCAiTUJJX0N5X2N1dCIsICJQQ0xfVG90YWwiLCAiUENMX0IiLCAiUENMX0MiLCAiUENMX0QiLCAiUENMX0UiLCAiUENMQWxnIiwgIlBDTEFsZ19zdWJjbGluIiksICIueSIpDQojIA0KIyBhbGwuZXF1YWwoY2hlY2tfbWVyZ2VbLCBuYW1lc19sXSwgY2hlY2tfbWVyZ2VbLCBuYW1lc19sXSkNCiMjIyMjIyMjIyMjIw0KDQpgYGANCg0KDQpgYGB7ciBjbGVhbl9jb3JyZWN0aW5nX2lkc30NCmRmX3NjcmVlbmluZyA8LSANCiAgZGZfc2NyZWVuaW5nICU+JQ0KICBkcGx5cjo6bmFfaWYoIk5vdCBBbnN3ZXJlZCIpICAgICMgc29tZSBtb3JlIE5Bcw0KDQpkZl9zY3JlZW5pbmcgPC0gDQogIGRmX3NjcmVlbmluZyAlPiUNCiAgZHBseXI6OmZpbHRlcighc3RyaW5ncjo6c3RyX2RldGVjdChJRCwgIlBBNE9YVCIpKSAgICMgZXhjbHVkZSB0aGVzZQ0KDQojIElEICI4QSIgbmVlZHMgdG8gYmUgbmFtZSAiUyBBIiwgQWdlX2NhdGVnICJwZXN0ZSA2NSBhbmkiDQojIElEICIyNlgiIG5lZWRzIHRvIGJlIG5hbWUgImJvbGRhc3UgbGlsaWFuYSIsIEFnZV9jYXRlZyAiNDEtNjUgYW5pIiAgICANCmRmX3NjcmVlbmluZyA8LSANCiAgZGZfc2NyZWVuaW5nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCEoSUQgPT0gIjhBIiAmIEFnZV9jYXRlZyA9PSAiNDEtNjUgYW5pIikpICU+JSANCiAgZHBseXI6OmZpbHRlcighKElEID09ICIyNlgiICYgQWdlX2NhdGVnID09ICJwZXN0ZSA2NSBhbmkiKSkgDQoNCg0KIyBkdXBsaWNhdGVkDQpkZl9zY3JlZW5pbmckSURbZHVwbGljYXRlZChkZl9zY3JlZW5pbmckSUQpXSAgICAgICAgICAgICAjIGR1cGxpY2F0ZWQgSURzOiAiNkEiICI5QyINCmRmX3NjcmVlbmluZyA8LSANCiAgZGZfc2NyZWVuaW5nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCEoSUQgPT0gIjZBIiAmIGlzLm5hKEFnZV9jYXRlZykpKSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoIShJRCA9PSAiOUMiICYgaXMubmEoQWdlX2NhdGVnKSkpIA0KYGBgDQoNCg0KYGBge3IgZXh0cmFjdF9pZHN9DQoNCiMjIyMjDQpvdmVsYXBfdG9fcHRzZCA8LSBjKCI2WCIsICIxOVgiLCAiMTFSIiwgIjEwQyIsICIxNEMiLCAiM0QiKQ0Kb3ZlbGFwX3RvX2J1cm4gPC0gYygiOVgiLCAiMTJYIiwgIjhSIiwgIjEyQiIsICIxM0IiLCAiNUMiLCAiMTdSIikNCiANCiAgDQppZHNfcHRzZCA8LQ0KICBkZl9zY3JlZW5pbmcgJT4lDQogICAgZHBseXI6OmZpbHRlcihQQ0xBbGcgPT0gMSkgJT4lDQogICAgZHBseXI6OnNlbGVjdChJRCkgJT4lDQogICAgZHBseXI6OmZpbHRlcighKElEICVpbiUgb3ZlbGFwX3RvX2J1cm4pKSAlPiUNCiAgICBkcGx5cjo6cHVsbCgpDQoNCmlkc19idXJuIDwtDQogIGRmX3NjcmVlbmluZyAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKE1CSV9FeF9jdXQgPT0gMSwgTUJJX0N5X2N1dCA9PSAxKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KElEKSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKCEoSUQgJWluJSBvdmVsYXBfdG9fcHRzZCkpICU+JQ0KICAgIGRwbHlyOjpwdWxsKCkNCg0KaWRzX29sZCA8LQ0KICBkZl9zY3JlZW5pbmcgJT4lDQogICAgZHBseXI6OmZpbHRlcihBZ2VfY2F0ZWcgPT0gInBlc3RlIDY1IGFuaSIpICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoSUQpICU+JQ0KICAgIGRwbHlyOjpwdWxsKCkNCg0KaWRzX25vcm1hbCA8LQ0KICAgZGZfc2NyZWVuaW5nICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoIShJRCAlaW4lIGMoaWRzX3B0c2QsIGlkc19idXJuLCBpZHNfb2xkKSkpICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoSUQpICU+JQ0KICAgIGRwbHlyOjpwdWxsKCkNCg0KDQojIENIRUNLUw0KbGVuZ3RoKHVuaXF1ZShpZHNfcHRzZCkpOyBsZW5ndGgodW5pcXVlKGlkc19wdHNkKSkgPT0gbGVuZ3RoKGlkc19wdHNkKSAgICAgICAgICAgICAgIyBubyBkdXBsaWNhdGUgSURzDQpsZW5ndGgodW5pcXVlKGlkc19idXJuKSk7IGxlbmd0aCh1bmlxdWUoaWRzX2J1cm4pKSA9PSBsZW5ndGgoaWRzX2J1cm4pICAgICAgICAgICAgICAjIG5vIGR1cGxpY2F0ZSBJRHMNCmxlbmd0aCh1bmlxdWUoaWRzX29sZCkpOyBsZW5ndGgodW5pcXVlKGlkc19vbGQpKSA9PSBsZW5ndGgoaWRzX29sZCkgICAgICAgICAgICAgICAgICMgbm8gZHVwbGljYXRlIElEcw0KbGVuZ3RoKHVuaXF1ZShpZHNfbm9ybWFsKSk7IGxlbmd0aCh1bmlxdWUoaWRzX25vcm1hbCkpID09IGxlbmd0aChpZHNfbm9ybWFsKSAgICAgICAgIyBubyBkdXBsaWNhdGUgSURzDQoNCmludGVyc2VjdCh1bmlxdWUoaWRzX3B0c2QpLCB1bmlxdWUoaWRzX2J1cm4pKSAgICMgYmVmb3JlOiAxMyBjb21tb24gLS0gbm93OiAwIA0KbGVuZ3RoKHVuaXF1ZShjKGlkc19wdHNkLCBpZHNfYnVybikpKSAgICAgICMgNDcgdG90YWwNCnNldGRpZmYoaWRzX3B0c2QsIGlkc19idXJuKSAgICAgICAgICAjIGJlZm9yZTogb25seSBwdHNkICAgMTYgLS0gbm93OiAyMg0Kc2V0ZGlmZihpZHNfYnVybiwgaWRzX3B0c2QpICAgICAgICAgICMgYmVmb3JlOiBvbmx5IGJ1cm4gICAxOCAtLSBub3c6IDI1DQppbnRlcnNlY3QoaWRzX3B0c2QsIGlkc19vbGQpICAgICMgbm8gb2xkIHdpdGggUFRTRA0KaW50ZXJzZWN0KGlkc19wdHNkLCBpZHNfb2xkKSAgICAjIG5vIG9sZCB3aXRoIEJ1cm4gT3V0DQpsZW5ndGgodW5pcXVlKGMoaWRzX3B0c2QsIGlkc19idXJuLCBpZHNfb2xkLCBpZHNfbm9ybWFsKSkpID09IDEwNiAgIyBhbGwgZ29vZCANCg0KDQoNCiMjIyMNCnNjcmVlbmluZ19pZHNfZ3JvdXBzIDwtIGxpc3QoDQogIHB0c2QgPSBpZHNfcHRzZCwNCiAgYnVybiA9IGlkc19idXJuLA0KICBwdHNkX29yX2J1cm4gPSBpbnRlcnNlY3QodW5pcXVlKGlkc19wdHNkKSwgdW5pcXVlKGlkc19idXJuKSksDQogIG9sZCA9IGlkc19vbGQsDQogIG5vcm1hbCA9IGlkc19ub3JtYWwNCikNCg0KDQojIGlkc19ncm91cHNfZGY8LSANCiMgICBEYXRhICU+JQ0KIyAgIGRwbHlyOjpzZWxlY3QoMTczLCAxNzU6MTg4KQ0KYGBgDQoNCg0KYGBge3IgaXpvbGF0aX0NCiMgY29sbmFtZXMoRGF0YSlbMjZdIDwtICJTb2NfRGlzY29uZiINCiMgDQojIERhdGEgJT4lDQojICAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19ub3JtYWwpICU+JQ0KIyAgIGRwbHlyOjpzZWxlY3QoU29jX0Rpc2NvbmYpICU+JSANCiMgICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCB+ZHBseXI6Om5hX2lmKC4sICJOb3QgQW5zd2VyZWQiKSkgJT4lDQojICAgbXV0YXRlX2lmKGlzLmNoYXJhY3RlciwgYXMubG9naWNhbCkgJT4lDQojICAgZHBseXI6OnB1bGwoKSAlPiUgc3VtKC4sIG5hLnJtID0gVFJVRSkNCg0KIyBpem9sYXRpaSBhciBmaTogY2VpIDkgYmF0cmFuaSBzaSAxNiBub3JtYWxpDQogIA0KYGBgDQoNCiMgT3V0Y29tZSBNZWFzdXJlcw0KDQojIERpY3RhdG9yIEdhbWUNCg0KYGBge3IgZGdfc2NvcmluZywgcmVzdWx0cz0naGlkZSd9DQojIERHIGRmDQpkZ19kZl9wcmUgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNraXAgPSAwLCB3aGljaCA9ICJEaWN0YXRvckdhbWUgcHJlIikNCmRnX2RmX3ByZSA8LSANCiAgZGdfZGZfcHJlICU+JQ0KICBqYW5pdG9yOjpyZW1vdmVfZW1wdHkoInJvd3MiKSANCiAgDQpjb2xuYW1lcyhkZ19kZl9wcmUpWzRdIDwtICJJRCINCmRnX2RmX3ByZSA8LSANCiAgZGdfZGZfcHJlICU+JQ0KICBkcGx5cjo6bXV0YXRlKElEID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKElELCBmaXhlZCgiICIpLCAiIikpICU+JSAgICAjIHJlbW92ZSB3aGl0ZSBzcGFjZXMNCiAgZHBseXI6Om11dGF0ZShJRCA9IHRvdXBwZXIoSUQpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0byB1cHBlcg0KYWxsKGRnX2RmX3ByZSRJRCA9PSB0b3VwcGVyKGRnX2RmX3ByZSRJRCkpIA0KDQpkZ19kZl9wb3N0IDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMCwgd2hpY2ggPSAiRGljdGF0b3JHYW1lIHBvc3QiKQ0KZGdfZGZfcG9zdCA8LSANCiAgZGdfZGZfcG9zdCAlPiUNCiAgamFuaXRvcjo6cmVtb3ZlX2VtcHR5KCJyb3dzIikNCg0KY29sbmFtZXMoZGdfZGZfcG9zdClbNF0gPC0gIklEIg0KZGdfZGZfcG9zdCA8LSANCiAgZGdfZGZfcG9zdCAlPiUNCiAgZHBseXI6Om11dGF0ZShJRCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChJRCwgZml4ZWQoIiAiKSwgIiIpKSAlPiUgICAgIyByZW1vdmUgd2hpdGUgc3BhY2VzDQogIGRwbHlyOjptdXRhdGUoSUQgPSB0b3VwcGVyKElEKSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdG8gdXBwZXINCmFsbChkZ19kZl9wb3N0JElEID09IHRvdXBwZXIoZGdfZGZfcG9zdCRJRCkpIA0KDQpjb2xuYW1lcyhkZ19kZl9wcmUpWzU6OF0gPC0gc3ByaW50ZigiREdfJWQiLCAxOjQpDQpjb2xuYW1lcyhkZ19kZl9wcmUpWzJdIDwtICJSZXNwb25zZV9TdGF0dXMiDQpjb2xuYW1lcyhkZ19kZl9wb3N0KVs1OjhdIDwtIHNwcmludGYoIkRHXyVkIiwgMTo0KQ0KY29sbmFtZXMoZGdfZGZfcG9zdClbM10gPC0gIlJlc3BvbnNlX1N0YXR1cyINCg0KZGdfZGZfcHJlIDwtDQogIGRnX2RmX3ByZSAlPiUNCiAgZHBseXI6Om11dGF0ZShgRGF0ZSBNb2RpZmllZGAgPSBsdWJyaWRhdGU6OnltZF9obXMoZm9ybWF0KGBEYXRlIE1vZGlmaWVkYCwgIiVZLSVtLSVkICVIOiVNOiVTIiwgdHogPSAiVVRDIikpKSAlPiUNCiAgbXV0YXRlX2lmKGlzLmNoYXJhY3Rlciwgfm5hX2lmKC4sICJOb3QgQW5zd2VyZWQiKSkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoUmVzcG9uc2VfU3RhdHVzID09ICJjb21wbGV0ZWQiKSAlPiUNCiAgZHBseXI6OmZpbHRlcighc3RyaW5ncjo6c3RyX2RldGVjdChJRCwgIlBBNE9YVCIpKSAlPiUNCiAgZHBseXI6OmZpbHRlcighc3RyaW5ncjo6c3RyX2RldGVjdChJRCwgIlBBNFJNTiIpKQ0KDQpkZ19kZl9wb3N0IDwtDQogIGRnX2RmX3Bvc3QgJT4lDQogIGRwbHlyOjptdXRhdGUoYERhdGUgTW9kaWZpZWRgID0gbHVicmlkYXRlOjp5bWRfaG1zKGZvcm1hdChgRGF0ZSBNb2RpZmllZGAsICIlWS0lbS0lZCAlSDolTTolUyIsIHR6ID0gIlVUQyIpKSkgJT4lDQogIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIH5kcGx5cjo6bmFfaWYoLiwgIk5vdCBBbnN3ZXJlZCIpKSAlPiUNCiAgZHBseXI6OmZpbHRlcihSZXNwb25zZV9TdGF0dXMgPT0gImNvbXBsZXRlZCIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiUEE0T1hUIikpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiUEE0Uk1OIikpDQoNCmRnX2RmX3ByZSA8LQ0KICBkZ19kZl9wcmUgJT4lDQogIGRwbHlyOjptdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiREdfIikpLCB+c3RyaW5ncjo6c3RyX2V4dHJhY3QoLiwgIlswLTldKyIpKSAlPiUgICAjIGV4dHJhY3RzIGZpcnN0IG51bWJlciAoYWxsIGdhbWVzIHN0YXJ0IHdpdGggUGxheWVyIEEsIHNvIGFsd2F5cyBmaXJzdCBudW1iZXIpDQogIGRwbHlyOjptdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiREdfIikpLCBhcy5udW1lcmljKSAlPiUNCiAgZHBseXI6Om11dGF0ZShUaW1lID0gcmVwKCJQcmUiLCBucm93KC4pKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoQ29uZCA9IGlmZWxzZShzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiWCIpLCAiQ1RSTCIsICJUUiIpKSAlPiUNCiAgc2VsZWN0KGBEYXRlIE1vZGlmaWVkYCwgSUQsIHN0YXJ0c193aXRoKCJER18iKSwgVGltZSwgQ29uZCkNCg0KZGdfZGZfcG9zdCA8LQ0KICBkZ19kZl9wb3N0ICU+JQ0KICBkcGx5cjo6bXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoIkRHXyIpKSwgfnN0cmluZ3I6OnN0cl9leHRyYWN0KC4sICJbMC05XSsiKSkgJT4lICAgIyBleHRyYWN0cyBmaXJzdCBudW1iZXIgKGFsbCBnYW1lcyBzdGFydCB3aXRoIFBsYXllciBBLCBzbyBhbHdheXMgZmlyc3QgbnVtYmVyKQ0KICBkcGx5cjo6bXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoIkRHXyIpKSwgYXMubnVtZXJpYykgJT4lDQogIGRwbHlyOjptdXRhdGUoVGltZSA9IHJlcCgiUG9zdCIsIG5yb3coLikpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShDb25kID0gaWZlbHNlKHN0cmluZ3I6OnN0cl9kZXRlY3QoSUQsICJYIiksICJDVFJMIiwgIlRSIikpICU+JQ0KICBzZWxlY3QoYERhdGUgTW9kaWZpZWRgLCBJRCwgc3RhcnRzX3dpdGgoIkRHXyIpLCBUaW1lLCBDb25kKQ0KDQojIFRyYW5zZm9ybSBERyAwLTkwMCBlZ29pc20gdG8gMC05IGFsdHJ1aXNtDQpkZ190cmFuc19mdW5jIDwtIGZ1bmN0aW9uKHgpe3RyYW5zIDwtIDkgLSB4IC8gMTAwfQ0KDQpkZ19kZl9wcmUgPC0NCiAgZGdfZGZfcHJlICU+JQ0KICBkcGx5cjo6bXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoIkRHXyIpKSwgZGdfdHJhbnNfZnVuYykgDQoNCmRnX2RmX3Bvc3QgPC0NCiAgZGdfZGZfcG9zdCAlPiUNCiAgZHBseXI6Om11dGF0ZV9hdCh2YXJzKHN0YXJ0c193aXRoKCJER18iKSksIGRnX3RyYW5zX2Z1bmMpIA0KDQojIFVuaXRlIERHIGRhdGEgLSBMb25nIEZvcm1hdA0KZGdfdW5pdGVkX2xvbmcgPC0gcmJpbmQoZGdfZGZfcHJlLCBkZ19kZl9wb3N0KQ0Kd2hpY2godGFibGUoZGdfdW5pdGVkX2xvbmckSUQpPiAyICkgICAgICMgSURzICIzQiIgJiAiMzFYIiBoYXZlIG1vcmUgdGhhbiAyIHRyaWFscw0KZGdfdW5pdGVkX2xvbmdbZGdfdW5pdGVkX2xvbmckSUQgPT0gIjNCIixdICAjIHR3byBQcmVzIC0tIGtlZXAgdGhlIGZpcnN0DQpkZ191bml0ZWRfbG9uZyA8LSBkZ191bml0ZWRfbG9uZ1stNTUsIF0NCmRnX3VuaXRlZF9sb25nW2RnX3VuaXRlZF9sb25nJElEID09ICIzMVgiLF0gIyB0d28gUHJlcyAtLSBrZWVwIHRoZSBmaXJzdA0KZGdfdW5pdGVkX2xvbmcgPC0gZGdfdW5pdGVkX2xvbmdbLTczLCBdDQpkZ191bml0ZWRfbG9uZ1tkZ191bml0ZWRfbG9uZyRJRCA9PSAiNUUiLF0gIyB0d28gUHJlcyAtLSBrZWVwIHRoZSBmaXJzdA0KZGdfdW5pdGVkX2xvbmcgPC0gZGdfdW5pdGVkX2xvbmdbLTEwNiwgXQ0KDQpkZ191bml0ZWRfbG9uZyRER19Ub3RhbCA8LSByb3dTdW1zKGRnX3VuaXRlZF9sb25nWywgc3ByaW50ZigiREdfJWQiLCAxOjQpXSwgbmEucm0gPSBUUlVFKSANCg0KIyBVbml0ZSBERyBkYXRhIC0gV2lkZSBGb3JtYXQNCmRnX3VuaXRlZF93aWRlIDwtDQogIGRnX3VuaXRlZF9sb25nICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoSUQsIENvbmQpLCBuYW1lc19mcm9tID0gVGltZSwgdmFsdWVzX2Zyb20gPSBjKCJEYXRlIE1vZGlmaWVkIiwgc3ByaW50ZigiREdfJWQiLCAxOjQpLCAiREdfVG90YWwiKSkNCiMgZGdfdW5pdGVkX3dpZGUyIDwtIGRwbHlyOjpsZWZ0X2pvaW4oZGdfdW5pdGVkX3dpZGUsIGlkc19ncm91cHNfZGYsIGJ5ID0gIklEIikgICAgICMgbm8gbmVlZCB0byBtZXJnZSwgYWxyZWFkeSBoYXZlIGlkcyBmb3IgZ3JvdXBzIHN0b3JlZA0KDQpgYGANCg0KPCEtLQ0KYGBge3IgbWl4ZWRhbm92YV9kZ30NCmNhdCgiTWl4ZWQgQU5PVkEgLSBERyB3aG9sZSBzYW1wbGUgKG5vdCBieSBncm91cHMpIikNCiMgTWl4ZWQgQU5PVkENCmRnX3VuaXRlZF9sb25nICU+JQ0KICBncm91cF9ieShJRCkgJT4lDQogIGZpbHRlcihuKCkgPiAxKSAlPiUgICAgICMga2VlcCBvbmx5IGNvbXBsZXRlIGNhc2VzDQogIHVuZ3JvdXAoKSAlPiUgDQogIHR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gLiwgaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBUaW1lLCB2YWx1ZV92YXIgPSBER19Ub3RhbCwNCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KYGBgDQotLT4NCg0KIyBUIHRlc3QgRGljYXRhdG9yIEdhbWUNCg0KYGBge3IgdHRlc3RfYnlncm91cF9kZ30NCiMgZHBseXI6OmZpbHRlcihJRCAlaW4lIGMoaWRzX3B0c2QsIGlkc19idXJuLCBpZHNfb2xkLCBpZHNfbm9ybWFsKSkgJT4lDQoNCmNhdCgiIyMgREcgLSBQVFNEIFRSIikNCmRnX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX3B0c2QpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJER19Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJER19Ub3RhbF9Qb3N0IikNCmNhdCgiIyMgREcgLSBQVFNEIENUUkwiKQ0KZGdfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfcHRzZCkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiREdfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiREdfVG90YWxfUG9zdCIpDQoNCg0KY2F0KCIjIyBERyAtIEJ1cm5vdXQgVFIiKQ0KZGdfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfYnVybikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgZnVuY190X2JveCguLCBpbmQgPSAiSUQiLCBwcmVfdmFyID0gIkRHX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIkRHX1RvdGFsX1Bvc3QiKQ0KY2F0KCIjIyBERyAtIEJ1cm5vdXQgQ1RSTCIpDQpkZ191bml0ZWRfd2lkZSAlPiUNCiAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19idXJuKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJER19Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJER19Ub3RhbF9Qb3N0IikNCg0KDQpjYXQoIiMjIERHIC0gT2xkIFRSIikNCiMgZGdfdW5pdGVkX3dpZGUgJT4lDQojICAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19vbGQpICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiREdfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiREdfVG90YWxfUG9zdCIpDQpjYXQoIiMjIERHIC0gT2xkIENUUkwiKQ0KIyBkZ191bml0ZWRfd2lkZSAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX29sZCkgJT4lDQojICAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQojICAgZnVuY190X2JveCguLCBpbmQgPSAiSUQiLCBwcmVfdmFyID0gIkRHX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIkRHX1RvdGFsX1Bvc3QiKQ0KDQpjYXQoIiMjIERHIC0gR2VuZXJhbCBQb3B1bGF0aW9uIFRSIikNCmRnX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX25vcm1hbCkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgZnVuY190X2JveCguLCBpbmQgPSAiSUQiLCBwcmVfdmFyID0gIkRHX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIkRHX1RvdGFsX1Bvc3QiKQ0KY2F0KCIjIyBERyAtIEdlbmVyYWwgUG9wdWxhdGlvbiBDVFJMIikNCmRnX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX25vcm1hbCkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiREdfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiREdfVG90YWxfUG9zdCIpDQpgYGANCg0KPCEtLQ0KIyMgREcgTm9ybWFsIFNhbXBsZSBTaXplIGVzdGltYXRpb24NCg0KYGBge3IgZGdfc2FtcGxlc2l6ZX0NCmNhdCgiIyMgREcgLSBHZW5lcmFsIFBvcHVsYXRpb24gVFIiKQ0KZGdfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBzYW1wbGVzaXplX3BhaXJlZHR0ZXN0KC4sIHByZV92YXIgPSAiREdfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiREdfVG90YWxfUG9zdCIpDQpjYXQoIiMjIERHIC0gR2VuZXJhbCBQb3B1bGF0aW9uIENUUkwiKQ0KZGdfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIHNhbXBsZXNpemVfcGFpcmVkdHRlc3QoLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJER19Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJER19Ub3RhbF9Qb3N0IikNCmBgYA0KLS0+DQoNCg0KYGBge3Igc2NhbGVfc2NvcmluZywgcmVzdWx0cz0naGlkZSd9DQojIFNjYWxlcyBkZg0Kc2NhbGVfZGZfcHJlIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IDAsIHdoaWNoID0gIlNldCB0ZXN0ZSB6aSAxIHByZSIpDQpzY2FsZV9kZl9wcmUgPC0gDQogIHNjYWxlX2RmX3ByZSAlPiUNCiAgamFuaXRvcjo6cmVtb3ZlX2VtcHR5KCJyb3dzIikgDQoNCnNjYWxlX2RmX3ByZSA8LSBzY2FsZV9kZl9wcmVbLC0yXQ0KY29sbmFtZXMoc2NhbGVfZGZfcHJlKVsxXSA8LSAiRGF0ZSINCmNvbG5hbWVzKHNjYWxlX2RmX3ByZSlbMl0gPC0gIklEIg0Kc2NhbGVfZGZfcHJlIDwtIA0KICBzY2FsZV9kZl9wcmUgJT4lDQogIGRwbHlyOjptdXRhdGUoSUQgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoSUQsIGZpeGVkKCIgIiksICIiKSkgJT4lICAgICMgcmVtb3ZlIHdoaXRlIHNwYWNlcw0KICBkcGx5cjo6bXV0YXRlKElEID0gdG91cHBlcihJRCkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0byB1cHBlcg0KYWxsKHNjYWxlX2RmX3ByZSRJRCA9PSB0b3VwcGVyKHNjYWxlX2RmX3ByZSRJRCkpIA0KDQpzY2FsZV9kZl9wb3N0IDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNraXAgPSAwLCB3aGljaCA9ICJTZXQgdGVzdGUgemkgNSBwb3N0IikNCnNjYWxlX2RmX3Bvc3QgPC0gDQogIHNjYWxlX2RmX3Bvc3QgJT4lDQogIGphbml0b3I6OnJlbW92ZV9lbXB0eSgicm93cyIpIA0KDQpzY2FsZV9kZl9wb3N0IDwtIHNjYWxlX2RmX3Bvc3RbLC0yXQ0KY29sbmFtZXMoc2NhbGVfZGZfcG9zdClbMV0gPC0gIkRhdGUiDQpjb2xuYW1lcyhzY2FsZV9kZl9wb3N0KVsyXSA8LSAiSUQiDQpzY2FsZV9kZl9wb3N0IDwtIA0KICBzY2FsZV9kZl9wb3N0ICU+JQ0KICBkcGx5cjo6bXV0YXRlKElEID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKElELCBmaXhlZCgiICIpLCAiIikpICU+JSAgICAjIHJlbW92ZSB3aGl0ZSBzcGFjZXMNCiAgZHBseXI6Om11dGF0ZShJRCA9IHRvdXBwZXIoSUQpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRvIHVwcGVyDQphbGwoc2NhbGVfZGZfcG9zdCRJRCA9PSB0b3VwcGVyKHNjYWxlX2RmX3Bvc3QkSUQpKQ0KDQphbGwuZXF1YWwoY29sbmFtZXMoc2NhbGVfZGZfcG9zdCksIGNvbG5hbWVzKHNjYWxlX2RmX3ByZSkpICAgIyBzZXRkaWZmKGNvbG5hbWVzKHNjYWxlX2RmX3Bvc3QpLCBjb2xuYW1lcyhzY2FsZV9kZl9wcmUpKQ0KDQojIERlYWwgd2l0aCBOb3QgQW5zd2VyDQpzY2FsZV9kZl9wcmUgPC0NCiAgc2NhbGVfZGZfcHJlICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCB+ZHBseXI6Om5hX2lmKC4sICJOb3QgQW5zd2VyZWQiKSkNCg0Kc2NhbGVfZGZfcG9zdCA8LQ0KICBzY2FsZV9kZl9wb3N0ICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCB+ZHBseXI6Om5hX2lmKC4sICJOb3QgQW5zd2VyZWQiKSkNCg0KIyBFeGNsdWRlIHN1YmplY3RzDQpzY2FsZV9kZl9wcmUgPC0NCiAgc2NhbGVfZGZfcHJlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiUEE0T1hUIikpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiUk1OIikpIA0KDQpzY2FsZV9kZl9wb3N0IDwtDQogIHNjYWxlX2RmX3Bvc3QgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIXN0cmluZ3I6OnN0cl9kZXRlY3QoSUQsICJQQTRPWFQiKSkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIXN0cmluZ3I6OnN0cl9kZXRlY3QoSUQsICJSTU4iKSkgDQoNCiMgQWRkIENvbmRpdGlvbg0Kc2NhbGVfZGZfcHJlIDwtDQogIHNjYWxlX2RmX3ByZSAlPiUNCiAgZHBseXI6Om11dGF0ZShUaW1lID0gcmVwKCJQcmUiLCBucm93KC4pKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoQ29uZCA9IGlmZWxzZShzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiWCIpLCAiQ1RSTCIsICJUUiIpKQ0KDQpzY2FsZV9kZl9wb3N0IDwtDQogIHNjYWxlX2RmX3Bvc3QgJT4lDQogIGRwbHlyOjptdXRhdGUoVGltZSA9IHJlcCgiUG9zdCIsIG5yb3coLikpKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKENvbmQgPSBpZmVsc2Uoc3RyaW5ncjo6c3RyX2RldGVjdChJRCwgIlgiKSwgIkNUUkwiLCAiVFIiKSkNCg0KDQojIyBQQU5BUzogUG9zaXRpdmUgQWZmZWN0IFNjb3JlID0gc3VtIGl0ZW1zIDEsIDMsIDUsIDksIDEwLCAxMiwgMTQsIDE2LCAxNywgMTkuIE5lZ2F0aXZlIEFmZmVjdCBTY29yZSA9IHN1bSBpdGVtcyAyLCA0LCA2LCA3LCA4LCAxMSwgMTMsIDE1LCAxOCwgMjAuICANCmluZGV4X2l0ZW1fcGFuYXMgPC0gMzoyMg0KY29sbmFtZXMoc2NhbGVfZGZfcHJlKVtpbmRleF9pdGVtX3BhbmFzXSA8LSBzcHJpbnRmKCJQQU5BU18lZCIsIDE6MjApDQpjb2xuYW1lcyhzY2FsZV9kZl9wb3N0KVtpbmRleF9pdGVtX3BhbmFzXSA8LSBzcHJpbnRmKCJQQU5BU18lZCIsIDE6MjApDQoNCnNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcGFuYXNdIDwtIGRhdGEuZnJhbWUobGFwcGx5KHNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcGFuYXNdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qw65uIGZvYXJ0ZSBtaWPEgyBtxINzdXLEgy4qIiwgIjEiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubiBtaWPEgyBtxINzdXLEgy4qIiwgIjIiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubnRyLW8gb2FyZWNhcmUgbcSDc3VyxIMuKiIsICIzIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0Kc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm4gbWFyZSBtxINzdXLEgy4qIiwgIjQiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubiBmb2FydGUgbWFyZSBtxINzdXLEgy4qIiwgIjUiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQoNCnNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wYW5hc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qw65uIGZvYXJ0ZSBtaWPEgyBtxINzdXLEgy4qIiwgIjEiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubiBtaWPEgyBtxINzdXLEgy4qIiwgIjIiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubnRyLW8gb2FyZWNhcmUgbcSDc3VyxIMuKiIsICIzIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0Kc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdIDwtIGRhdGEuZnJhbWUobGFwcGx5KHNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm4gbWFyZSBtxINzdXLEgy4qIiwgIjQiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubiBmb2FydGUgbWFyZSBtxINzdXLEgy4qIiwgIjUiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQojIFNjb3JpbmcNCnNjYWxlX2RmX3ByZSRQQV9Ub3RhbCA8LSBTY29yZUxpa2VydChzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXVtjKDEsIDMsIDUsIDksIDEwLCAxMiwgMTQsIDE2LCAxNywgMTkpXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b251bWVyaWMgPSBUUlVFLCBuYXBlcmNlbnQgPSAuMTEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBub3QgbW9yZSB0aGFuIDEgTkFzIGZvciAxMCBpdGVtcw0Kc2NhbGVfZGZfcHJlJE5BX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KHNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcGFuYXNdW2MoMiwgNCwgNiwgNywgOCwgMTEsIDEzLCAxNSwgMTgsIDIwKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b251bWVyaWMgPSBUUlVFLCBuYXBlcmNlbnQgPSAuMTEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBub3QgbW9yZSB0aGFuIDEgTkFzIGZvciAxMCBpdGVtcw0KDQpzY2FsZV9kZl9wb3N0JFBBX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KHNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXVtjKDEsIDMsIDUsIDksIDEwLCAxMiwgMTQsIDE2LCAxNywgMTkpXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9udW1lcmljID0gVFJVRSwgbmFwZXJjZW50ID0gLjExKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm90IG1vcmUgdGhhbiAxIE5BcyBmb3IgMTAgaXRlbXMNCnNjYWxlX2RmX3Bvc3QkTkFfVG90YWwgPC0gU2NvcmVMaWtlcnQoc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdW2MoMiwgNCwgNiwgNywgOCwgMTEsIDEzLCAxNSwgMTgsIDIwKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9udW1lcmljID0gVFJVRSwgbmFwZXJjZW50ID0gLjExKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm90IG1vcmUgdGhhbiAxIE5BcyBmb3IgMTAgaXRlbXMNCg0KDQojIyBQU1MtU0YgMTQgKGxpa2VydCAwLTQpLiBJdGVtcyA0LCA1LCA2LCA3LCA5LCAxMCwgYW5kIDEzIGFyZSBzY29yZWQgaW4gcmV2ZXJzZSBkaXJlY3Rpb24uDQppbmRleF9pdGVtX3BzcyA8LSAyMzozNg0KaW5kZXhfaXRlbV9yZXZQU1MgPC0gYyg0LCA1LCA2LCA3LCA5LCAxMCwgMTMpDQpjb2xuYW1lcyhzY2FsZV9kZl9wcmUpW2luZGV4X2l0ZW1fcHNzXSA8LSBzcHJpbnRmKCJQU1NfJWQiLCAxOjE0KQ0KY29sbmFtZXMoc2NhbGVfZGZfcG9zdClbaW5kZXhfaXRlbV9wc3NdIDwtIHNwcmludGYoIlBTU18lZCIsIDE6MTQpDQoNCnNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLipuaWNpb2RhdMSDLioiLCAiMCIsIHgpfSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCnNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLiphcHJvYXBlIG5pY2lvZGF0xIMuKiIsICIxIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0Kc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KHNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcHNzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKnVuZW9yaS4qIiwgIjIiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3Bzc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qZGVzdHVsIGRlIGRlcy4qIiwgIjMiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wcmVbLCBpbmRleF9pdGVtX3Bzc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qZm9hcnRlIGRlcy4qIiwgIjQiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQoNCnNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qbmljaW9kYXTEgy4qIiwgIjAiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KHNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKmFwcm9hcGUgbmljaW9kYXTEgy4qIiwgIjEiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KHNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKnVuZW9yaS4qIiwgIjIiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KHNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKmRlc3R1bCBkZSBkZXMuKiIsICIzIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0Kc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLipmb2FydGUgZGVzLioiLCAiNCIsIHgpfSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCg0KIyBTY29yZQ0Kc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdIDwtIGNvbHN0b251bWVyaWMoc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdKQ0Kc2NhbGVfZGZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSA8LSBjb2xzdG9udW1lcmljKHNjYWxlX2RmX3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10pDQoNCnNjYWxlX2RmX3ByZVssIGluZGV4X2l0ZW1fcHNzXVtpbmRleF9pdGVtX3JldlBTU10gPC0gUmV2ZXJzZUNvZGUoc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdW2luZGV4X2l0ZW1fcmV2UFNTXSwgdG9udW1lcmljID0gRkFMU0UsIG1pbiA9IDAsIG1heCA9IDQpDQpzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdW2luZGV4X2l0ZW1fcmV2UFNTXSA8LSBSZXZlcnNlQ29kZShzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdW2luZGV4X2l0ZW1fcmV2UFNTXSwgdG9udW1lcmljID0gRkFMU0UsIG1pbiA9IDAsIG1heCA9IDQpDQoNCnNjYWxlX2RmX3ByZSRQU1NfVG90YWwgPC0gU2NvcmVMaWtlcnQoc2NhbGVfZGZfcHJlWywgaW5kZXhfaXRlbV9wc3NdLCBuYXBlcmNlbnQgPSAuMTEpDQpzY2FsZV9kZl9wb3N0JFBTU19Ub3RhbCA8LSBTY29yZUxpa2VydChzY2FsZV9kZl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdLCBuYXBlcmNlbnQgPSAuMTEpDQoNCg0KIyBVbml0ZSBzY2FsZSBkZiAtIExvbmcgRm9ybWF0DQpzY2FsZV91bml0ZWRfbG9uZyA8LSByYmluZChzY2FsZV9kZl9wcmUsIHNjYWxlX2RmX3Bvc3QpDQoNCiMgc2NhbGVfdW5pdGVkX2xvbmcgJT4lDQojICAgY291bnQoSUQpICU+JQ0KIyAgIHByaW50KG4gPSBJbmYpICAjIElEICIyQiIsICI1RSIgaGF2ZSBkb3VibGUgcmVjb3JkIA0KDQojIHNjYWxlX3VuaXRlZF9sb25nW3NjYWxlX3VuaXRlZF9sb25nJElEID09ICIyQiIsXQ0Kc2NhbGVfdW5pdGVkX2xvbmcgPC0gc2NhbGVfdW5pdGVkX2xvbmdbLTI2LF0NCiMgc2NhbGVfdW5pdGVkX2xvbmdbc2NhbGVfdW5pdGVkX2xvbmckSUQgPT0gIjVFIixdDQpzY2FsZV91bml0ZWRfbG9uZyA8LSBzY2FsZV91bml0ZWRfbG9uZ1stMTA5LF0NCg0KIyBFeGNsdWRlIHN1Ymogd2lodCBvbmx5IG9uZSBvYnNlcnZhdGlvbiwgZXhjbHVkZSBJRCBOT1RBTlNXRVJFRA0Kc2NhbGVfdW5pdGVkX2xvbmcgPC0NCiAgc2NhbGVfdW5pdGVkX2xvbmcgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgZHBseXI6OmZpbHRlcihuKCkgPiAxKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICE9ICJOT1RBTlNXRVJFRCIpDQoNCiMgVW5pdGUgREcgZGF0YSAtIFdpZGUgRm9ybWF0DQpzY2FsZV91bml0ZWRfd2lkZSA8LQ0KICBzY2FsZV91bml0ZWRfbG9uZyAlPiUNCiAgZHBseXI6OnNlbGVjdChJRCwgRGF0ZSwgVGltZSwgQ29uZCwgUEFfVG90YWwsIE5BX1RvdGFsLCBQU1NfVG90YWwpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoSUQsIENvbmQpLCBuYW1lc19mcm9tID0gVGltZSwgdmFsdWVzX2Zyb20gPSBjKCJEYXRlIiwgIlBBX1RvdGFsIiwgIk5BX1RvdGFsIiwgIlBTU19Ub3RhbCIpKQ0KDQpgYGANCg0KDQo8IS0tDQpgYGB7ciBtaXhlZGFub3ZhX3NjYWxlc30NCmNhdCgiTWl4ZWQgQU5PVkEgLSBQU1Mgd2hvbGUgc2FtcGxlIChub3QgYnkgZ3JvdXBzKSIpDQojIE1peGVkIEFOT1ZBDQpzY2FsZV91bml0ZWRfbG9uZyAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JQ0KICBmaWx0ZXIobigpID4gMSkgJT4lICAgICAjIGtlZXAgb25seSBjb21wbGV0ZSBjYXNlcyAtLSBoZXJlIGFyZSBvbmx5IGNvbXBsZXRlDQogIHVuZ3JvdXAoKSAlPiUgDQogIHR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gLiwgaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBUaW1lLCB2YWx1ZV92YXIgPSBQU1NfVG90YWwsDQogICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCJNaXhlZCBBTk9WQSAtIFBBIHdob2xlIHNhbXBsZSAobm90IGJ5IGdyb3VwcykiKQ0Kc2NhbGVfdW5pdGVkX2xvbmcgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgZmlsdGVyKG4oKSA+IDEpICU+JSAgICAgIyBrZWVwIG9ubHkgY29tcGxldGUgY2FzZXMgLS0gaGVyZSBhcmUgb25seSBjb21wbGV0ZQ0KICB1bmdyb3VwKCkgJT4lIA0KICB0d19taXhlZEFOT1ZBX2Z1bmMoZGF0YSA9IC4sIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gVGltZSwgdmFsdWVfdmFyID0gUEFfVG90YWwsDQogICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCJNaXhlZCBBTk9WQSAtIE5BIHdob2xlIHNhbXBsZSAobm90IGJ5IGdyb3VwcykiKQ0Kc2NhbGVfdW5pdGVkX2xvbmcgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgZmlsdGVyKG4oKSA+IDEpICU+JSAgICAgIyBrZWVwIG9ubHkgY29tcGxldGUgY2FzZXMgLS0gaGVyZSBhcmUgb25seSBjb21wbGV0ZQ0KICB1bmdyb3VwKCkgJT4lIA0KICB0d19taXhlZEFOT1ZBX2Z1bmMoZGF0YSA9IC4sIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gVGltZSwgdmFsdWVfdmFyID0gTkFfVG90YWwsDQogICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCmBgYA0KLS0+DQoNCiMgVCB0ZXN0IFBTUw0KDQpgYGB7ciB0dGVzdF9ieWdyb3VwX3Bzc30NCiMgZHBseXI6OmZpbHRlcihJRCAlaW4lIGMoaWRzX3B0c2QsIGlkc19idXJuLCBpZHNfb2xkLCBpZHNfbm9ybWFsKSkgJT4lDQoNCmNhdCgiIyMgUFNTIC0gUFRTRCBUUiIpDQpzY2FsZV91bml0ZWRfd2lkZSAlPiUNCiAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19wdHNkKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUFNTX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBTU19Ub3RhbF9Qb3N0IikNCmNhdCgiIyMgUFNTIC0gUFRTRCBDVFJMIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX3B0c2QpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgZnVuY190X2JveCguLCBpbmQgPSAiSUQiLCBwcmVfdmFyID0gIlBTU19Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJQU1NfVG90YWxfUG9zdCIpDQoNCg0KY2F0KCIjIyBQU1MgLSBCdXJub3V0IFRSIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX2J1cm4pICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJQU1NfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUFNTX1RvdGFsX1Bvc3QiKQ0KY2F0KCIjIyBQU1MgLSBCdXJub3V0IENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfYnVybikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUFNTX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBTU19Ub3RhbF9Qb3N0IikNCg0KDQojIGNhdCgiIyMgUFNTIC0gT2xkIFRSIikNCiMgc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQojICAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19vbGQpICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUFNTX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBTU19Ub3RhbF9Qb3N0IikNCiMgY2F0KCIjIyBQU1MgLSBPbGQgQ1RSTCIpDQojIHNjYWxlX3VuaXRlZF93aWRlICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfb2xkKSAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUFNTX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBTU19Ub3RhbF9Qb3N0IikNCg0KY2F0KCIjIyBQU1MgLSBHZW5lcmFsIFBvcHVsYXRpb24gVFIiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUFNTX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBTU19Ub3RhbF9Qb3N0IikNCmNhdCgiIyMgUFNTIC0gR2VuZXJhbCBQb3B1bGF0aW9uIENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJQU1NfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUFNTX1RvdGFsX1Bvc3QiKQ0KYGBgDQoNCjwhLS0NCiMjIFBTUyBOb3JtYWwgU2FtcGxlIFNpemUgZXN0aW1hdGlvbg0KDQpgYGB7ciBzYW1wbGVzaXplX3Bzc30NCmNhdCgiIyMgUFNTIC0gR2VuZXJhbCBQb3B1bGF0aW9uIFRSIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX25vcm1hbCkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgc2FtcGxlc2l6ZV9wYWlyZWR0dGVzdCguLCBwcmVfdmFyID0gIlBTU19Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJQU1NfVG90YWxfUG9zdCIpDQpjYXQoIiMjIFBTUyAtIEdlbmVyYWwgUG9wdWxhdGlvbiBDVFJMIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX25vcm1hbCkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBzYW1wbGVzaXplX3BhaXJlZHR0ZXN0KC4sIHByZV92YXIgPSAiUFNTX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBTU19Ub3RhbF9Qb3N0IikNCmBgYA0KLS0+DQoNCiMgVCB0ZXN0IFBBDQoNCmBgYHtyIHR0ZXN0X2J5Z3JvdXBfcGF9DQpjYXQoIiMjIFBBIC0gUFRTRCBUUiIpDQpzY2FsZV91bml0ZWRfd2lkZSAlPiUNCiAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19wdHNkKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUEFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUEFfVG90YWxfUG9zdCIpDQpjYXQoIiMjIFBBIC0gUFRTRCBDVFJMIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX3B0c2QpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgZnVuY190X2JveCguLCBpbmQgPSAiSUQiLCBwcmVfdmFyID0gIlBBX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIlBBX1RvdGFsX1Bvc3QiKQ0KDQoNCmNhdCgiIyMgUEEgLSBCdXJub3V0IFRSIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX2J1cm4pICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJQQV9Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJQQV9Ub3RhbF9Qb3N0IikNCmNhdCgiIyMgUEEgLSBCdXJub3V0IENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfYnVybikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUEFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUEFfVG90YWxfUG9zdCIpDQoNCg0KIyBjYXQoIiMjIFBBIC0gT2xkIFRSIikNCiMgc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQojICAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19vbGQpICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUEFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUEFfVG90YWxfUG9zdCIpDQojIGNhdCgiIyMgUEEgLSBPbGQgQ1RSTCIpDQojIHNjYWxlX3VuaXRlZF93aWRlICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfb2xkKSAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUEFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUEFfVG90YWxfUG9zdCIpDQoNCmNhdCgiIyMgUEEgLSBHZW5lcmFsIFBvcHVsYXRpb24gVFIiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiUEFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiUEFfVG90YWxfUG9zdCIpDQpjYXQoIiMjIFBBIC0gR2VuZXJhbCBQb3B1bGF0aW9uIENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJQQV9Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJQQV9Ub3RhbF9Qb3N0IikNCg0KYGBgDQoNCjwhLS0NCiMjIFBBIE5vcm1hbCBTYW1wbGUgU2l6ZSBlc3RpbWF0aW9uDQoNCmBgYHtyIHNhbXBsZXNpemVfcGF9DQpjYXQoIiMjIFBTUyAtIEdlbmVyYWwgUG9wdWxhdGlvbiBUUiIpDQpzY2FsZV91bml0ZWRfd2lkZSAlPiUNCiAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19ub3JtYWwpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIHNhbXBsZXNpemVfcGFpcmVkdHRlc3QoLiwgcHJlX3ZhciA9ICJQQV9Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJQQV9Ub3RhbF9Qb3N0IikNCmNhdCgiIyMgUFNTIC0gR2VuZXJhbCBQb3B1bGF0aW9uIENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIHNhbXBsZXNpemVfcGFpcmVkdHRlc3QoLiwgcHJlX3ZhciA9ICJQQV9Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJQQV9Ub3RhbF9Qb3N0IikNCmBgYA0KLS0+DQoNCiMgVCB0ZXN0IE5BDQoNCmBgYHtyIHR0ZXN0X2J5Z3JvdXBfbmF9DQpjYXQoIiMjIE5BIC0gUFRTRCBUUiIpDQpzY2FsZV91bml0ZWRfd2lkZSAlPiUNCiAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19wdHNkKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQpjYXQoIiMjIE5BIC0gUFRTRCBDVFJMIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX3B0c2QpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgZnVuY190X2JveCguLCBpbmQgPSAiSUQiLCBwcmVfdmFyID0gIk5BX1RvdGFsX1ByZSIsIHBvc3RfdmFyID0gIk5BX1RvdGFsX1Bvc3QiKQ0KDQoNCmNhdCgiIyMgTkEgLSBCdXJub3V0IFRSIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX2J1cm4pICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJOQV9Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJOQV9Ub3RhbF9Qb3N0IikNCmNhdCgiIyMgTkEgLSBCdXJub3V0IENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfYnVybikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQoNCg0KIyBjYXQoIiMjIE5BIC0gT2xkIFRSIikNCiMgc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQojICAgZHBseXI6OmZpbHRlcihJRCAlaW4lIGlkc19vbGQpICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQojIGNhdCgiIyMgTkEgLSBPbGQgQ1RSTCIpDQojIHNjYWxlX3VuaXRlZF93aWRlICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfb2xkKSAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiMgICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQoNCmNhdCgiIyMgTkEgLSBHZW5lcmFsIFBvcHVsYXRpb24gVFIiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBmdW5jX3RfYm94KC4sIGluZCA9ICJJRCIsIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQpjYXQoIiMjIE5BIC0gR2VuZXJhbCBQb3B1bGF0aW9uIENUUkwiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGZ1bmNfdF9ib3goLiwgaW5kID0gIklEIiwgcHJlX3ZhciA9ICJOQV9Ub3RhbF9QcmUiLCBwb3N0X3ZhciA9ICJOQV9Ub3RhbF9Qb3N0IikNCmBgYA0KDQo8IS0tDQojIyBOQSBOb3JtYWwgU2FtcGxlIFNpemUgZXN0aW1hdGlvbg0KDQpgYGB7ciBzYW1wbGVzaXplX25hfQ0KY2F0KCIjIyBQU1MgLSBHZW5lcmFsIFBvcHVsYXRpb24gVFIiKQ0Kc2NhbGVfdW5pdGVkX3dpZGUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoSUQgJWluJSBpZHNfbm9ybWFsKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBzYW1wbGVzaXplX3BhaXJlZHR0ZXN0KC4sIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQpjYXQoIiMjIFBTUyAtIEdlbmVyYWwgUG9wdWxhdGlvbiBDVFJMIikNCnNjYWxlX3VuaXRlZF93aWRlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKElEICVpbiUgaWRzX25vcm1hbCkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBzYW1wbGVzaXplX3BhaXJlZHR0ZXN0KC4sIHByZV92YXIgPSAiTkFfVG90YWxfUHJlIiwgcG9zdF92YXIgPSAiTkFfVG90YWxfUG9zdCIpDQpgYGANCi0tPg0KDQoNCg0KPCEtLSBTZXNzaW9uIEluZm8gYW5kIExpY2Vuc2UgLS0+DQoNCjxicj4NCg0KIyBTZXNzaW9uIEluZm8NCmBgYHtyIHNlc3Npb25faW5mbywgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9DQpzZXNzaW9uSW5mbygpICAgIA0KYGBgDQoNCjwhLS0gRm9vdGVyIC0tPg0KJm5ic3A7DQo8aHIgLz4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5BIHdvcmsgYnkgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL0NsYXVkaXVQYXBhc3RlcmkvIj5DbGF1ZGl1IFBhcGFzdGVyaTwvYT48L3A+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiAjODA4MDgwOyI+PGVtPmNsYXVkaXUucGFwYXN0ZXJpQGdtYWlsLmNvbTwvZW0+PC9zcGFuPjwvcD4NCiZuYnNwOw0K