# Set general settings for markdown file
knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
comment = "",
results = "hold")
# Clear environment
rm(list = ls())
# Enable/disable caching of time-consuming code chunks
knitr_cache_enabled = TRUE
# Load packages
library(dplyr) # for data wrangling
library(ggplot2) # for plotting
library(ggsignif) # for adding asterisks
library(cowplot) # for arranging plots
library(purrr) # for calculating within-participant CIs
library(eegUtils) # for plotting EEG topographies
library(tidyr) # for gather function
library(sjPlot) # for plot_model function
library(ggeffects) # for extracting certain effects from model
# Load functions
source("./functions/summarySEwithinO.R") # Function provided by R-cookbook: http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_(ggplot2)/
source("./functions/R_rainclouds.R") # Function to create raincloud plots
# Define function to create common legend (from http://www.sthda.com/english/wiki/wiki.php?id_contents=7930#add-a-common-legend-for-multiple-ggplot2-graphs)
get_legend <- function(myggplot) {
tmp <- ggplot_gtable(ggplot_build(myggplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}
# Set figure theme
my_figure_theme <- theme_classic(base_size = 11) +
theme(legend.position = "bottom",
axis.ticks.x = element_blank(),
plot.title = element_text(hjust = 0.5),
axis.title.x = element_text(vjust = -1),
strip.background = element_rect(color = "gray84", fill = "gray94", size = 0.3))
# Set figure colors
colors <- c("#2d5a7d", "tan1")
colors_erp <- c("royalblue1", "navy", "tan1", "sienna3")
Plot Behavioral Data (Observed)
This figure corresponds to Figure 2 in the manuscript.
# Load aggregated data per participant
load(file = "./saved_objects_for_plots/data_aggregated_rt.Rda")
load(file = "./saved_objects_for_plots/data_aggregated_acc.Rda")
# Define facet labels
group.labs <- c("Healthy Control Participants", "Patients With OCD")
names(group.labs) <- c("HC", "OCD")
#### Create RT plot ####
# Create raincloud plot
plot_rt <- ggplot() +
geom_flat_violin(data = data_aggregated_rt, aes(x = gng_response_type, y = word_rt, fill = word_valence),
position = position_nudge(x = .16, y = 0), adjust = 1.5, trim = FALSE, alpha = .7, color = NA) +
geom_point(data = data_aggregated_rt, aes(x = as.numeric(gng_response_type) - .23, y = word_rt, color = word_valence),
position = position_jitter(width = .05), size = 1, shape = 20, alpha = 0.8) +
geom_boxplot(data = data_aggregated_rt, aes(x = gng_response_type, y = word_rt, fill = word_valence),
outlier.shape = NA, alpha = 0.9, width = .3, color = "black") +
labs(x = "Response in the Go/No-Go Task", y = "Word Categorization RT (ms)") +
coord_cartesian(ylim = c(200, 1600)) +
scale_y_continuous(breaks = seq(200, 1600, 200), expand = c(0, 0)) +
scale_x_discrete(labels = c("SH" = "Slow Hit", "FH" = "Fast Hit", "FA" = "False Alarm", "IR" = "Inhibition")) +
scale_color_manual(name = "Word Valence:", labels = c("Negative", "Positive"), values = colors,
guide = guide_legend(override.aes = list(size = 6, shape = 15, alpha = 1), label.hjust = -2)) +
scale_fill_manual(name = "Word Valence:", labels = c("Negative", "Positive"), values = colors, guide = "none") +
facet_wrap(~group, labeller = labeller(group = group.labs)) +
my_figure_theme
# Save and remove legend
legend <- get_legend(plot_rt)
plot_rt <- plot_rt + theme(legend.position = "none")
# Add position of asterisks
asteriks_rt <- data.frame(
x1 = c(1.85, 2.85, 1.85, 2.85),
x2 = c(2.15, 3.15, 2.15, 3.15),
y1 = c(1320, 1320, 1320, 1320),
xstar = c(2, 3, 2, 3),
ystar = c(1330, 1330, 1330, 1330),
lab = c("*", "***", "**", "*"),
group = c("HC", "HC", "OCD", "OCD"))
# Add position of asterisks across groups
asteriks_rt2 <- data.frame(
x1 = .370,
x2 = .820,
y1 = .820,
xstar = .595,
ystar = .830,
lab = "**")
# Add a new layer on-top to add asterisks
plot_rt <- plot_rt +
geom_text(data = asteriks_rt, aes(x = xstar, y = ystar, label = lab, size = 2.5), color = "gray30") +
geom_segment(data = asteriks_rt, aes(x = x1, xend = x2, y = y1, yend = y1), size = 0.3, color = "gray30") +
facet_grid(. ~ group, labeller = labeller(group = group.labs))
# Add a new layer on-top to add asterisks across groups
plot_rt <- ggdraw(plot_rt) +
geom_text(data = asteriks_rt2, aes(x = xstar, y = ystar, label = lab, size = 2.5), color = "gray30") +
geom_segment(data = asteriks_rt2, aes(x = x1, xend = x2, y = y1, yend = y1), size = 0.3, color = "gray30")
#### Create accuracy plot ####
# Create raincloud plot
plot_acc <- ggplot() +
geom_flat_violin(data = data_aggregated_acc, aes(x = gng_response_type, y = accuracy, fill = word_valence),
position = position_nudge(x = .16, y = 0), adjust = 1.5, trim = FALSE, alpha = .7, color = NA) +
geom_point(data = data_aggregated_acc, aes(x = as.numeric(gng_response_type) - .23, y = accuracy, color = word_valence),
position = position_jitter(width = .05), size = 1, shape = 20, alpha = 0.8) +
geom_boxplot(data = data_aggregated_acc, aes(x = gng_response_type, y = accuracy, fill = word_valence),
outlier.shape = NA, alpha = 0.9, width = .3, color = "black") +
labs(x = "Response in the Go/No-Go Task", y = "Word Categorization Accuracy (%)") +
coord_cartesian(ylim = c(0, 105)) +
scale_y_continuous(breaks = seq(0, 100, 10), expand = c(0, 0)) +
scale_x_discrete(labels = c("SH" = "Slow Hit", "FH" = "Fast Hit", "FA" = "False Alarm", "IR" = "Inhibition")) +
scale_color_manual(name = "Word Valence:", labels = c("Negative", "Positive"), values = colors) +
scale_fill_manual(name = "Word Valence:", labels = c("Negative", "Positive"), values = colors) +
facet_wrap(~group, labeller = labeller(group = group.labs)) +
annotate("rect", xmin = 0.5, xmax = 4.5, ymin = 101, ymax = 105, fill = "white") + # Add whitespace below facet
my_figure_theme + theme(legend.position = "none")
# Add position of asterisks
asteriks_acc <- data.frame(
x1 = c(2.85, 2.85),
x2 = c(3.15, 3.15),
y1 = c(19, 19),
xstar = c(3, 3),
ystar = c(15, 15),
lab = c("***", "***"),
group = c("HC", "OCD"))
# Add a new layer on-top to add asterisks
plot_acc <- plot_acc +
geom_text(data = asteriks_acc, aes(x = xstar, y = ystar, label = lab, size = 2.5), color = "gray30") +
geom_segment(data = asteriks_acc, aes(x = x1, xend = x2, y = y1, yend = y1), size = 0.3, color = "gray30") +
facet_grid(. ~ group, labeller = labeller(group = group.labs))
# Arrange plots
figure_obs_val <- ggdraw() +
draw_plot(plot_rt, x = .00, y = .490, width = 1, height = .51) +
draw_plot(plot_acc, x = .00, y = .050, width = 1, height = .42) +
draw_plot(legend, x = .28, y = .015, width = .5, height = .00) +
draw_plot_label(c("A", "B"), c(0, 0), c(1, 0.47), size = 15)
figure_obs_val
# Save plot
ggsave(plot = figure_obs_val, "./figures/figure_2.tiff", width = 16, height = 27,
units = "cm", dpi = 600, compression = "lzw")
Plot Behavioral Data (Predicted)
This figure corresponds to Figure 3 in the manuscript.
# Load (G)LMM output
LMM_rt_final <- readRDS(file = "./saved_objects_for_plots/LMM_rt_final.rds")
GLMM_acc_final <- readRDS(file = "./saved_objects_for_plots/GLMM_acc_final.rds")
# Define facet labels
group.labs <- c("Healthy Control Participants", "Patients With OCD")
names(group.labs) <- c("HC", "OCD")
#### Create RT plot ####
# Extract only FA and FH from LMM
LMM_rt <- ggpredict(LMM_rt_final, terms = c("gng_response_type", "word_valence", "group"))
LMM_rt_plot <- LMM_rt[LMM_rt$x %in% c("FH", "FA"), ]
LMM_rt_plot$x <- droplevels(LMM_rt_plot$x)
# Plot predicted means
plot_LMM_rt <- ggplot() +
geom_point(data = LMM_rt_plot, aes(x = x, y = predicted, color = group),
position = position_dodge(width = .25), size = 2.5) +
geom_errorbar(data = LMM_rt_plot, aes(x = x, ymax = conf.low, ymin = conf.high, color = group),
position = position_dodge(width = .25), size = .7, width = .2) +
labs(x = "Response in the Go/No-Go Task", y = "Predicted Word Categorization RT (ms)") +
coord_cartesian(ylim = c(500, 950)) +
scale_y_continuous(breaks = seq(500, 950, 50), expand = c(0, 0)) +
scale_x_discrete(labels = c("FH" = "Fast Hit", "FA" = "False Alarm")) +
scale_color_manual(name = "Word Valence:", labels = c("Negative", "Positive"), values = colors) +
facet_wrap(~facet, labeller = labeller(facet = group.labs)) +
my_figure_theme
# Save and remove legend
legend <- get_legend(plot_LMM_rt)
plot_LMM_rt <- plot_LMM_rt + theme(legend.position = "none")
# Add position of asterisks
asteriks_rt <- data.frame(
x1 = c(.225, .415, .655, .845, .430),
x2 = c(.275, .465, .705, .895, .880),
y1 = c(.800, .800, .800, .800, .860),
xstar = c(.250, .440, .680, .870, .655),
ystar = c(.810, .810, .810, .810, .870),
lab = c("*", "***", "**", "*", "**"))
# Add a new layer on-top to add asterisks
plot_LMM_rt <- ggdraw(plot_LMM_rt) +
geom_text(data = asteriks_rt, aes(x = xstar, y = ystar, label = lab, size = 2.5), color = "gray30") +
geom_segment(data = asteriks_rt, aes(x = x1, xend = x2, y = y1, yend = y1), size = 0.3, color = "gray30")
#### Create accuracy plot ####
# Extract only FA and FH from GLMM
GLMM_acc <- ggpredict(GLMM_acc_final, terms = c("gng_response_type", "word_valence", "group"))
GLMM_acc_plot <- GLMM_acc[GLMM_acc$x %in% c("FH", "FA"), ]
GLMM_acc_plot$x <- droplevels(GLMM_acc_plot$x)
# Plot predicted means
plot_GLMM_acc <- ggplot() +
geom_point(data = GLMM_acc_plot, aes(x = x, y = predicted * 100, color = group),
position = position_dodge(width = .25), size = 2.5) +
geom_errorbar(data = GLMM_acc_plot, aes(x = x, ymax = conf.low * 100, ymin = conf.high * 100, color = group),
position = position_dodge(width = .25), size = .7, width = .2) +
labs(x = "Response in the Go/No-Go Task", y = "Predicted Word Categorization Accuracy (%)") +
coord_cartesian(ylim = c(50, 110)) +
scale_y_continuous(breaks = seq(50, 100, 5), expand = c(0, 0)) +
scale_x_discrete(labels = c("FH" = "Fast Hit", "FA" = "False Alarm")) +
scale_color_manual(name = "Word Valence:", labels = c("Negative", "Positive"), values = colors) +
facet_wrap(~facet, labeller = labeller(facet = group.labs)) +
my_figure_theme +
theme(legend.position = "none")
# Add position of asterisks
asteriks_acc <- data.frame(
x1 = c(.415, .845),
x2 = c(.465, .895),
y1 = c(.800, .800),
xstar = c(.440, .870),
ystar = c(.810, .810),
lab = c("***", "***"))
# Add a new layer on-top with ggdraw in order to add asterisks
plot_GLMM_acc <- ggdraw(plot_GLMM_acc) +
geom_text(data = asteriks_acc, aes(x = xstar, y = ystar, label = lab, size = 2.5), color = "gray30") +
geom_segment(data = asteriks_acc, aes(x = x1, xend = x2, y = y1, yend = y1), size = 0.3, color = "gray30")
#### Arrange plots
figure_pred_val <- ggdraw() +
draw_plot(plot_LMM_rt, x = .00, y = .070, width = .49, height = .93) +
draw_plot(plot_GLMM_acc, x = .52, y = .070, width = .49, height = .93) +
draw_plot(legend, x = .28, y = .015, width = .50, height = .00) +
draw_plot_label(c("A", "B"), c(0, 0.52), c(1, 1), size = 15)
figure_pred_val
# Save plot
ggsave(plot = figure_pred_val, "./figures/figure_3.tiff", width = 20, height = 12,
units = "cm", dpi = 600, compression = "lzw")
Plot ERP Data
This figure corresponds to Figure 4 in the manuscript.
# Load data
resp_locked_data <- read.csv(file = "./data/response_locked_data_for_plots.csv", header = TRUE)
# Create relevant variables and filter data
resp_locked_data <- resp_locked_data %>%
dplyr::mutate(
stimulation = factor(ifelse(
participant_id == "C_01_T1" | participant_id == "C_02_T1" | participant_id == "C_03_T2" |
participant_id == "C_04_T2" | participant_id == "C_05_T1" | participant_id == "C_06_T2" |
participant_id == "C_07_T1" | participant_id == "C_08_T1" | participant_id == "C_09_T2" |
participant_id == "C_10_T2" | participant_id == "C_11_T2" | participant_id == "C_12_T2" |
participant_id == "C_13_T1" | participant_id == "C_15_T2" | participant_id == "C_16_T1" |
participant_id == "C_17_T2" | participant_id == "C_18_T2" | participant_id == "C_19_T1" |
participant_id == "C_20_T1" | participant_id == "C_21_T2" | participant_id == "C_22_T2" |
participant_id == "C_23_T1" | participant_id == "C_24_T1" | participant_id == "C_25_T1" |
participant_id == "C_26_T1" | participant_id == "C_27_T2" | participant_id == "C_28_T2" |
participant_id == "C_29_T1" | participant_id == "C_30_T2" | participant_id == "P_01_T1" |
participant_id == "P_02_T2" | participant_id == "P_03_T2" | participant_id == "P_04_T1" |
participant_id == "P_05_T1" | participant_id == "P_06_T1" | participant_id == "P_07_T2" |
participant_id == "P_08_T2" | participant_id == "P_09_T2" | participant_id == "P_10_T1" |
participant_id == "P_11_T2" | participant_id == "P_12_T2" | participant_id == "P_13_T1" |
participant_id == "P_15_T1" | participant_id == "P_16_T1" | participant_id == "P_17_T2" |
participant_id == "P_18_T1" | participant_id == "P_19_T1" | participant_id == "P_20_T2" |
participant_id == "P_21_T2" | participant_id == "P_22_T1" | participant_id == "P_23_T1" |
participant_id == "P_24_T2" | participant_id == "P_25_T1" | participant_id == "P_26_T2" |
participant_id == "P_27_T1" | participant_id == "P_28_T2" | participant_id == "P_29_T2" |
participant_id == "P_30_T1", "sham", "verum")),
condition = factor(ifelse(condition == 1, "correct", "incorrect"), levels = c("incorrect", "correct")),
group = factor(ifelse(substr(participant_id, 1, 1) == "C", "HC", "OCD")),
session = factor(ifelse(substr(participant_id, 6, 7) == "T1", "T1", "T2")),
participant_id = factor(substr(participant_id, 1, 4))) %>% # to get correct no. of factor levels
# Only keep sham session and exclude P_02 and C_02
dplyr::filter(stimulation == "sham" & participant_id != "P_02" & participant_id != "C_02")
# Update factor levels
resp_locked_data$participant_id <- droplevels(resp_locked_data$participant_id)
# Calculate running within-participant CIs
running_ci_mfn <- resp_locked_data %>%
split(.$time) %>%
map(~ summarySEwithinO(
data = .,
measurevar = "FCz",
withinvars = "condition",
betweenvars = "group",
idvar = "participant_id"))
ci_mfn <- purrr::map_df(running_ci_mfn, magrittr::extract) %>%
dplyr::mutate(time = rep(unique(resp_locked_data$time), each = 4))
# Note. 4 refers to no. of conditions (group x response_type = 2 x 2 = 4)
# Convert to long format for electrodes
data_topo_mfn <- resp_locked_data %>%
# Remove channels of no interest
dplyr::select(-IO1, -M1, -F9, -F10) %>%
# Change from wide to long format for electrodes
tidyr::gather(., electrode, amplitude, Fp1:O2, factor_key = TRUE) %>%
# Select time windows
dplyr::filter(time >= 0 & time <= 100) %>%
# Add electrode information
electrode_locations(., electrode = "electrode", drop = FALSE, montage = NULL)
#### Create waveform plot ####
# Define electrode labels
label_fcz <- data.frame(time = -320, FCz = 17.5, lab = "Text")
# Create waveform plot
plot_waveform_mfn <- ggplot(resp_locked_data, aes(time, FCz)) +
stat_summary(fun = mean, geom = "line", size = 0.5, linetype = "solid", aes(color = condition:group)) +
geom_ribbon(data = ci_mfn, aes(ymin = FCz - ci, ymax = FCz + ci, fill = condition:group), alpha = 0.2) +
guides(fill = "none") +
geom_segment(aes(x = 0, xend = 0, y = -8, yend = 18), linetype = "dashed", color = "gray60", size = 0.2) +
geom_segment(aes(x = -400, xend = 800, y = 0, yend = 0), linetype = "dashed", color = "gray60", size = 0.2) +
geom_text(data = label_fcz, label = "FCz") +
annotate("rect", xmin = 0, xmax = 100, ymin = -8, ymax = 18, alpha = .2, fill = "gray50") + # Shaded time area
labs(x = "Time (ms)", y = expression(paste("Amplitude (", mu, "V)"))) +
coord_cartesian(ylim = c(-8, 18), xlim = c(-200, 400)) +
scale_y_continuous(breaks = seq(-8, 18, 2), expand = c(0, 0)) +
scale_x_continuous(breaks = seq(-200, 400, 100), expand = c(0, 0)) +
scale_color_manual(values = colors_erp, labels = c("HC: False Alarm", "OCD: False Alarm", "HC: Hit", "OCD: Hit"),
guide = guide_legend(override.aes = list(size = 1.3))) + # Thickness legend lines
scale_fill_manual(values = colors_erp) +
my_figure_theme +
theme(axis.ticks.x = NULL, legend.title = element_blank(), legend.text = element_text(size = 9))
#### Create topography plots ####
# Define facet labels
labs_incorr <- c("HC: False Alarm", "OCD: False Alarm")
names(labs_incorr) <- c("HC", "OCD")
labs_corr <- c("HC: Hit", "OCD: Hit")
names(labs_corr) <- c("HC", "OCD")
# ERN
plot_topo_ern <- ggplot(data_topo_mfn[data_topo_mfn$condition == "incorrect", ],
aes(x = x, y = y, fill = amplitude, z = amplitude, label = electrode)) +
geom_topo(grid_res = 300, interp_limit = "head", chan_markers = "point", chan_size = 0.1,
head_size = 0.2, colour = "gray40", size = 0.2) +
scale_fill_distiller(palette = "RdBu", limits = c(-4, 4), breaks = c(-4, 0, 4)) +
theme_void() +
coord_equal() +
labs(fill = expression(paste(mu, "V"))) +
theme(legend.position = "bottom", legend.text = element_text(size = 8, color = "gray30"),
legend.title = element_text(size = 8, color = "gray30", vjust = 0.9), legend.key.height = unit(0.25, 'cm'),
legend.key.width = unit(0.3, 'cm'), strip.text.x = element_text(size = 9)) +
facet_wrap(. ~group, ncol = 2, labeller = labeller(group = labs_incorr))
# Save and remove legend
legend_ern <- get_legend(plot_topo_ern)
plot_topo_ern <- plot_topo_ern + theme(legend.position = "none")
# CRN
plot_topo_crn <- ggplot(data_topo_mfn[data_topo_mfn$condition == "correct", ],
aes(x = x, y = y, fill = amplitude, z = amplitude, label = electrode)) +
geom_topo(grid_res = 300, interp_limit = "head", chan_markers = "point", chan_size = 0.1,
head_size = 0.2, colour = "gray40", size = 0.2) +
scale_fill_distiller(palette = "RdBu", limits = c(-4, 8.4), breaks = c(-4, 0, 4, 8)) +
theme_void() +
coord_equal() +
labs(fill = expression(paste(mu, "V"))) +
theme(legend.position = "bottom", legend.text = element_text(size = 8, color = "gray30"),
legend.title = element_text(size = 8, color = "gray30", vjust = 0.9), legend.key.height = unit(0.25, 'cm'),
legend.key.width = unit(0.3, 'cm'), strip.text.x = element_text(size = 9)) +
facet_wrap(. ~group, ncol = 2, labeller = labeller(group = labs_corr))
# Save and remove legend
legend_crn <- get_legend(plot_topo_crn)
plot_topo_crn <- plot_topo_crn + theme(legend.position = "none")
# Overlay waveform and topopgraphy plots
aligned_plots1_mfn <- align_plots(plot_waveform_mfn, plot_topo_ern, axis = "tr")
aligned_plots2_mfn <- align_plots(plot_waveform_mfn, plot_topo_crn, axis = "tr")
# Arrange plots
figure_ern_crn <- ggdraw() +
draw_plot(aligned_plots1_mfn[[1]], x = 0, y = .32, width = .99, height = .64) +
draw_plot(aligned_plots1_mfn[[2]], x = .09, y = .05, width = .42, height = .21) +
draw_plot(aligned_plots2_mfn[[2]], x = .55, y = .05, width = .42, height = .21) +
draw_plot(legend_ern, x = .07, y = 0, width = .42, height = .05) +
draw_plot(legend_crn, x = .53, y = 0, width = .42, height = .05) +
draw_plot_label(c("A", "B"), c(0, 0), c(1, 0.285), size = 15)
figure_ern_crn
# Save plot
ggsave(plot = figure_ern_crn, "./figures/figure_4.tiff", width = 13.5, height = 16,
units = "cm", dpi = 600, compression = "lzw")
Plot Effects of OCD Characteristics
OCD Symptom Severity (OCI-R)
This figure corresponds to Figure 5 in the manuscript.
# Load LMM output and correlation data
LMM_rt_oci_ocd <- readRDS(file = "./saved_objects_for_plots/LMM_rt_oci_ocd.rds")
load(file = "./saved_objects_for_plots/df_corr.Rda")
# Create plot of estimated interaction effects
plot_oci_1 <- plot_model(LMM_rt_oci_ocd,
type = "pred",
terms = c("oci_centered", "pos_neg", "FA_FH"),
ci.lvl = .95,
transform = "exp",
line.size = 1) +
labs(title = NULL, y = "Word Categorization RT (ms)", x = "OCI-R Score (Group-Mean-Centered)") +
coord_cartesian(ylim = c(500, 900), xlim = c(-13, 20)) +
scale_y_continuous(breaks = seq(500, 900, 50), expand = c(0, 0)) +
scale_x_continuous(breaks = seq(-10, 20, 5), expand = c(0, 0)) +
scale_color_manual(name = "Word Valence:", values = colors, labels = c("Negative", "Positive")) +
scale_fill_manual(name = "Word Valence:", values = colors, labels = c("Negative", "Positive")) +
my_figure_theme +
theme(strip.text.x = element_text(size = 11), axis.ticks.x = NULL) +
guides(fill = guide_legend(override.aes = list(color = colors, size = 0.65)))
# Change facet labels
plot_oci_1$data$facet <- ifelse(plot_oci_1$data$facet == "FA_FH = -0.5", "Fast Hits", "False Alarms")
# Create scatterplot
plot_oci_2 <- ggplot(data = df_corr[df_corr$group == "OCD", ], aes(x = oci, y = priming, fill = group)) +
geom_point(color = "#003192", size = 1) +
geom_smooth(method = 'lm', color = "#003192") +
labs(title = NULL, x = "OCI-R Score", y = "Overall Priming Effect (ms)") +
coord_cartesian(ylim = c(-150, 400), xlim = c(12.9, 45.5)) +
scale_y_continuous(breaks = seq(-150, 400, 50), expand = c(0, 0)) +
scale_x_continuous(breaks = seq(15, 45, 5), expand = c(0, 0)) +
scale_fill_manual(values = "#003192") +
my_figure_theme +
theme(legend.position = "none", axis.ticks.x = NULL) +
annotate("text", x = 45, y = -120, label = paste("list(italic(r)(26) ==", -.41, ", italic(p) == .029)"),
parse = TRUE, hjust = 1, size = 3, color = "gray20")
# Arrange plots
figure_oci <- ggdraw() +
draw_plot(plot_oci_1, x = .00, y = .000, width = .60, height = 1) +
draw_plot(plot_oci_2, x = .61, y = .115, width = .39, height = .83) +
draw_plot_label(c("A", "B"), c(0, .61), c(1, 1), size = 15)
figure_oci
# Save plot
ggsave(plot = figure_oci, "./figures/figure_5.tiff", width = 20, height = 12,
units = "cm", dpi = 600, compression = "lzw")
Trait Anxiety (STAI)
This figure corresponds to Figure S1 in the supplemental material.
# Load LMM output
LMM_rt_stai_ocd <- readRDS(file = "./saved_objects_for_plots/LMM_rt_stai_ocd.rds")
# Create plot of estimated interaction effects
plot_stai_1 <- plot_model(LMM_rt_stai_ocd,
type = "pred",
terms = c("stai_centered", "pos_neg", "FA_FH"),
ci.lvl = .95,
transform = "exp",
line.size = 1) +
labs(title = NULL, y = "Word Categorization RT (ms)", x = "STAI Trait Score (Group-Mean-Centered)") +
coord_cartesian(ylim = c(450, 900), xlim = c(-18, 25)) +
scale_y_continuous(breaks = seq(450, 900, 50), expand = c(0, 0)) +
scale_x_continuous(breaks = seq(-15, 25, 5), expand = c(0, 0)) +
scale_color_manual(name = "Word Valence:", values = colors, labels = c("Negative", "Positive")) +
scale_fill_manual(name = "Word Valence:", values = colors, labels = c("Negative", "Positive")) +
my_figure_theme +
theme(strip.text.x = element_text(size = 11), axis.ticks.x = NULL) +
guides(fill = guide_legend(override.aes = list(color = colors, size = 0.65)))
# Change facet labels
plot_stai_1$data$facet <- ifelse(plot_stai_1$data$facet == "FA_FH = -0.5", "Fast Hits", "False Alarms")
# Create scatterplot
plot_stai_2 <- ggplot(data = df_corr[df_corr$group == "OCD", ], aes(x = stai, y = priming, fill = group)) +
geom_point(color = "#003192", size = 1) +
geom_smooth(method = 'lm', color = "#003192") +
labs(title = NULL, x = "STAI Trait Score", y = "Overall Priming Effect (ms)") +
coord_cartesian(ylim = c(-150, 400), xlim = c(35.8, 80)) +
scale_y_continuous(breaks = seq(-150, 400, 50), expand = c(0, 0)) +
scale_x_continuous(breaks = seq(40, 80, 10), expand = c(0, 0)) +
scale_fill_manual(values = "#003192") +
my_figure_theme +
theme(legend.position = "none", axis.ticks.x = NULL) +
annotate("text", x = 80, y = -115, label = paste("list(italic(r)(26) ==", -.34, ", italic(p) == .078)"),
parse = TRUE, hjust = 1, size = 3, color = "gray20")
# Arrange plots
figure_stai <- ggdraw() +
draw_plot(plot_stai_1, x = .00, y = .000, width = .60, height = 1) +
draw_plot(plot_stai_2, x = .61, y = .115, width = .39, height = 0.83) +
draw_plot_label(c("A", "B"), c(0, .61), c(1, 1), size = 15)
figure_stai
# Save plot
ggsave(plot = figure_stai, "./figures/figure_S1.tiff", width = 20, height = 12,
units = "cm", dpi = 600, compression = "lzw")
Session Info
sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)
Matrix products: default
locale:
[1] LC_COLLATE=German_Germany.1252 LC_CTYPE=German_Germany.1252
[3] LC_MONETARY=German_Germany.1252 LC_NUMERIC=C
[5] LC_TIME=German_Germany.1252
attached base packages:
[1] stats graphics grDevices datasets utils methods base
other attached packages:
[1] lmerTest_3.1-3 lme4_1.1-25 Matrix_1.5-1 ggeffects_1.1.3
[5] sjPlot_2.8.11 tidyr_1.2.1 eegUtils_0.6.1 purrr_0.3.5
[9] cowplot_1.1.1 ggsignif_0.6.4 ggplot2_3.3.6 dplyr_1.0.10
loaded via a namespace (and not attached):
[1] nlme_3.1-140 matrixStats_0.58.0 RColorBrewer_1.1-3
[4] insight_0.18.4 httr_1.4.4 numDeriv_2016.8-1.1
[7] tools_3.6.1 backports_1.4.1 bslib_0.4.0
[10] utf8_1.2.2 R6_2.5.1 sjlabelled_1.2.0
[13] DBI_1.1.3 lazyeval_0.2.2 mgcv_1.8-28
[16] colorspace_2.0-3 withr_2.5.0 tidyselect_1.2.0
[19] emmeans_1.6.0 compiler_3.6.1 textshaping_0.3.6
[22] performance_0.10.0 cli_3.4.1 plotly_4.10.0
[25] labeling_0.4.2 bayestestR_0.13.0 sass_0.4.0
[28] scales_1.2.1 mvtnorm_1.1-3 systemfonts_1.0.4
[31] stringr_1.4.1 digest_0.6.30 minqa_1.2.4
[34] rmarkdown_2.16 pkgconfig_2.0.3 htmltools_0.5.3
[37] parallelly_1.32.1 highr_0.9 fastmap_1.1.0
[40] htmlwidgets_1.5.4 rlang_1.0.6 rstudioapi_0.14
[43] shiny_1.7.2 farver_2.1.1 jquerylib_0.1.4
[46] generics_0.1.3 jsonlite_1.8.3 magrittr_2.0.3
[49] parameters_0.19.0 Rcpp_1.0.9 munsell_0.5.0
[52] fansi_1.0.3 abind_1.4-5 lifecycle_1.0.3
[55] stringi_1.6.1 yaml_2.2.1 MASS_7.3-51.4
[58] plyr_1.8.7 grid_3.6.1 parallel_3.6.1
[61] listenv_0.8.0 promises_1.2.0.1 sjmisc_2.8.9
[64] miniUI_0.1.1.1 lattice_0.20-45 splines_3.6.1
[67] sjstats_0.18.1 knitr_1.40 pillar_1.8.1
[70] boot_1.3-22 estimability_1.4.1 effectsize_0.7.0.5
[73] future.apply_1.9.1 codetools_0.2-16 glue_1.6.2
[76] evaluate_0.16 modelr_0.1.9 data.table_1.14.4
[79] renv_0.12.0 nloptr_1.2.2.2 vctrs_0.5.0
[82] httpuv_1.6.1 gtable_0.3.1 future_1.28.0
[85] assertthat_0.2.1 datawizard_0.6.2 cachem_1.0.4
[88] xfun_0.33 mime_0.12 xtable_1.8-4
[91] broom_1.0.1 pracma_2.4.2 later_1.2.0
[94] ragg_1.2.4 viridisLite_0.4.1 signal_0.7-6
[97] tibble_3.1.8 statmod_1.4.37 globals_0.16.1
[100] ellipsis_0.3.2
LS0tDQp0aXRsZTogIlBsb3RzIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudA0KLS0tDQoNCjwhLS0gU2V0IGdlbmVyYWwgc2V0dGluZ3MgLS0+DQoNCmBgYHtyIHNldHVwLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCg0KIyBTZXQgZ2VuZXJhbCBzZXR0aW5ncyBmb3IgbWFya2Rvd24gZmlsZQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBtZXNzYWdlID0gRkFMU0UsDQogIHdhcm5pbmcgPSBGQUxTRSwNCiAgY29tbWVudCA9ICIiLA0KICByZXN1bHRzID0gImhvbGQiKQ0KDQoNCiMgQ2xlYXIgZW52aXJvbm1lbnQNCnJtKGxpc3QgPSBscygpKQ0KDQoNCiMgRW5hYmxlL2Rpc2FibGUgY2FjaGluZyBvZiB0aW1lLWNvbnN1bWluZyBjb2RlIGNodW5rcw0Ka25pdHJfY2FjaGVfZW5hYmxlZCA9IFRSVUUNCg0KDQojIExvYWQgcGFja2FnZXMNCmxpYnJhcnkoZHBseXIpICAgICAgIyBmb3IgZGF0YSB3cmFuZ2xpbmcNCmxpYnJhcnkoZ2dwbG90MikgICAgIyBmb3IgcGxvdHRpbmcNCmxpYnJhcnkoZ2dzaWduaWYpICAgIyBmb3IgYWRkaW5nIGFzdGVyaXNrcw0KbGlicmFyeShjb3dwbG90KSAgICAjIGZvciBhcnJhbmdpbmcgcGxvdHMNCmxpYnJhcnkocHVycnIpICAgICAgIyBmb3IgY2FsY3VsYXRpbmcgd2l0aGluLXBhcnRpY2lwYW50IENJcw0KbGlicmFyeShlZWdVdGlscykgICAjIGZvciBwbG90dGluZyBFRUcgdG9wb2dyYXBoaWVzDQpsaWJyYXJ5KHRpZHlyKSAgICAgICMgZm9yIGdhdGhlciBmdW5jdGlvbg0KbGlicmFyeShzalBsb3QpICAgICAjIGZvciBwbG90X21vZGVsIGZ1bmN0aW9uDQpsaWJyYXJ5KGdnZWZmZWN0cykgICMgZm9yIGV4dHJhY3RpbmcgY2VydGFpbiBlZmZlY3RzIGZyb20gbW9kZWwNCg0KDQojIExvYWQgZnVuY3Rpb25zDQpzb3VyY2UoIi4vZnVuY3Rpb25zL3N1bW1hcnlTRXdpdGhpbk8uUiIpICAjIEZ1bmN0aW9uIHByb3ZpZGVkIGJ5IFItY29va2Jvb2s6IGh0dHA6Ly93d3cuY29va2Jvb2stci5jb20vR3JhcGhzL1Bsb3R0aW5nX21lYW5zX2FuZF9lcnJvcl9iYXJzXyhnZ3Bsb3QyKS8NCnNvdXJjZSgiLi9mdW5jdGlvbnMvUl9yYWluY2xvdWRzLlIiKSAgICAgICMgRnVuY3Rpb24gdG8gY3JlYXRlIHJhaW5jbG91ZCBwbG90cw0KDQoNCiMgRGVmaW5lIGZ1bmN0aW9uIHRvIGNyZWF0ZSBjb21tb24gbGVnZW5kIChmcm9tIGh0dHA6Ly93d3cuc3RoZGEuY29tL2VuZ2xpc2gvd2lraS93aWtpLnBocD9pZF9jb250ZW50cz03OTMwI2FkZC1hLWNvbW1vbi1sZWdlbmQtZm9yLW11bHRpcGxlLWdncGxvdDItZ3JhcGhzKQ0KZ2V0X2xlZ2VuZCA8LSBmdW5jdGlvbihteWdncGxvdCkgew0KICB0bXAgICAgICA8LSBnZ3Bsb3RfZ3RhYmxlKGdncGxvdF9idWlsZChteWdncGxvdCkpDQogIGxlZyAgICAgIDwtIHdoaWNoKHNhcHBseSh0bXAkZ3JvYnMsIGZ1bmN0aW9uKHgpIHgkbmFtZSkgPT0gImd1aWRlLWJveCIpDQogIGxlZ2VuZCAgIDwtIHRtcCRncm9ic1tbbGVnXV0NCiAgcmV0dXJuKGxlZ2VuZCl9DQoNCg0KIyBTZXQgZmlndXJlIHRoZW1lDQpteV9maWd1cmVfdGhlbWUgPC0gdGhlbWVfY2xhc3NpYyhiYXNlX3NpemUgPSAxMSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gID0gImJvdHRvbSIsDQogICAgICAgIGF4aXMudGlja3MueCAgICAgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBsb3QudGl0bGUgICAgICAgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBheGlzLnRpdGxlLnggICAgID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gLTEpLA0KICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImdyYXk4NCIsIGZpbGwgPSAiZ3JheTk0Iiwgc2l6ZSA9IDAuMykpDQoNCg0KIyBTZXQgZmlndXJlIGNvbG9ycw0KY29sb3JzIDwtIGMoIiMyZDVhN2QiLCAidGFuMSIpDQpjb2xvcnNfZXJwIDwtIGMoInJveWFsYmx1ZTEiLCAibmF2eSIsICJ0YW4xIiwgInNpZW5uYTMiKQ0KYGBgDQo8YnI+DQoNCiMjIFBsb3QgQmVoYXZpb3JhbCBEYXRhIChPYnNlcnZlZCkNCioqKg0KDQpUaGlzIGZpZ3VyZSBjb3JyZXNwb25kcyB0byBGaWd1cmUgMiBpbiB0aGUgbWFudXNjcmlwdC4NCg0KYGBge3IgY3JlYXRlLW9icy12YWx1ZS1wbG90LCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gMTAsIGRwaSA9IDYwMCwgZmlnLmNhcCA9ICI8YnI+IE5vdGUuIChBKSBPYnNlcnZlZCB3b3JkIGNhdGVnb3JpemF0aW9uIFJUIHBlciBwcmVjZWRpbmcgcmVzcG9uc2UgdHlwZSBpbiB0aGUgZ28vbm8tZ28gdGFzaywgd29yZCB2YWxlbmNlLCBhbmQgZ3JvdXAuIChCKSBPYnNlcnZlZCB3b3JkIGNhdGVnb3JpemF0aW9uIGFjY3VyYWN5IHBlciBwcmVjZWRpbmcgcmVzcG9uc2UgdHlwZSBpbiB0aGUgZ28vbm8tZ28gdGFzaywgd29yZCB2YWxlbmNlLCBhbmQgZ3JvdXAuIChB4oCTQikgVGhlIHBsb3RzIHNob3cgaW5kaXZpZHVhbCBkYXRhIHBvaW50cywgYm94cGxvdHMsIGFuZCBwcm9iYWJpbGl0eSBkZW5zaXR5IHBsb3RzIGJhc2VkIG9uIHJhdyBkYXRhIHRoYXQgd2VyZSBhZ2dyZWdhdGVkIGJ5IHBhcnRpY2lwYW50LiBBc3Rlcmlza3MgaW5kaWNhdGUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgeWllbGRlZCBieSB0aGUgKGdlbmVyYWxpemVkKSBsaW5lYXIgbWl4ZWQgbW9kZWwgYW5hbHlzaXMuICogcCA8IC4wNSwgKiogcCA8IC4wMSwgKioqIHAgPCAuMDAxLiJ9DQoNCg0KIyBMb2FkIGFnZ3JlZ2F0ZWQgZGF0YSBwZXIgcGFydGljaXBhbnQNCmxvYWQoZmlsZSA9ICIuL3NhdmVkX29iamVjdHNfZm9yX3Bsb3RzL2RhdGFfYWdncmVnYXRlZF9ydC5SZGEiKQ0KbG9hZChmaWxlID0gIi4vc2F2ZWRfb2JqZWN0c19mb3JfcGxvdHMvZGF0YV9hZ2dyZWdhdGVkX2FjYy5SZGEiKQ0KDQoNCiMgRGVmaW5lIGZhY2V0IGxhYmVscw0KZ3JvdXAubGFicyA8LSBjKCJIZWFsdGh5IENvbnRyb2wgUGFydGljaXBhbnRzIiwgIlBhdGllbnRzIFdpdGggT0NEIikNCm5hbWVzKGdyb3VwLmxhYnMpIDwtIGMoIkhDIiwgIk9DRCIpDQoNCg0KIyMjIyBDcmVhdGUgUlQgcGxvdCAjIyMjDQoNCiMgQ3JlYXRlIHJhaW5jbG91ZCBwbG90DQpwbG90X3J0IDwtIGdncGxvdCgpICsNCiAgZ2VvbV9mbGF0X3Zpb2xpbihkYXRhID0gZGF0YV9hZ2dyZWdhdGVkX3J0LCBhZXMoeCA9IGduZ19yZXNwb25zZV90eXBlLCB5ID0gd29yZF9ydCwgZmlsbCA9IHdvcmRfdmFsZW5jZSksDQogICAgcG9zaXRpb24gPSBwb3NpdGlvbl9udWRnZSh4ID0gLjE2LCB5ID0gMCksIGFkanVzdCA9IDEuNSwgdHJpbSA9IEZBTFNFLCBhbHBoYSA9IC43LCBjb2xvciA9IE5BKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGRhdGFfYWdncmVnYXRlZF9ydCwgYWVzKHggPSBhcy5udW1lcmljKGduZ19yZXNwb25zZV90eXBlKSAtIC4yMywgeSA9IHdvcmRfcnQsIGNvbG9yID0gd29yZF92YWxlbmNlKSwNCiAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IC4wNSksIHNpemUgPSAxLCBzaGFwZSA9IDIwLCBhbHBoYSA9IDAuOCkgKw0KICBnZW9tX2JveHBsb3QoZGF0YSA9IGRhdGFfYWdncmVnYXRlZF9ydCwgYWVzKHggPSBnbmdfcmVzcG9uc2VfdHlwZSwgeSA9IHdvcmRfcnQsIGZpbGwgPSB3b3JkX3ZhbGVuY2UpLA0KICAgIG91dGxpZXIuc2hhcGUgPSBOQSwgYWxwaGEgPSAwLjksIHdpZHRoID0gLjMsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHggPSAiUmVzcG9uc2UgaW4gdGhlIEdvL05vLUdvIFRhc2siLCB5ID0gIldvcmQgQ2F0ZWdvcml6YXRpb24gUlQgKG1zKSIpICsNCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDIwMCwgMTYwMCkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgyMDAsIDE2MDAsIDIwMCksIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJTSCIgPSAiU2xvdyBIaXQiLCAiRkgiID0gIkZhc3QgSGl0IiwgIkZBIiA9ICJGYWxzZSBBbGFybSIsICJJUiIgPSAiSW5oaWJpdGlvbiIpKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gIldvcmQgVmFsZW5jZToiLCBsYWJlbHMgPSBjKCJOZWdhdGl2ZSIsICJQb3NpdGl2ZSIpLCB2YWx1ZXMgPSBjb2xvcnMsDQogICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gNiwgc2hhcGUgPSAxNSwgYWxwaGEgPSAxKSwgbGFiZWwuaGp1c3QgPSAtMikpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSAgPSAiV29yZCBWYWxlbmNlOiIsIGxhYmVscyA9IGMoIk5lZ2F0aXZlIiwgIlBvc2l0aXZlIiksIHZhbHVlcyA9IGNvbG9ycywgZ3VpZGUgPSAibm9uZSIpICsNCiAgZmFjZXRfd3JhcCh+Z3JvdXAsIGxhYmVsbGVyID0gbGFiZWxsZXIoZ3JvdXAgPSBncm91cC5sYWJzKSkgKw0KICBteV9maWd1cmVfdGhlbWUgDQoNCg0KIyBTYXZlIGFuZCByZW1vdmUgbGVnZW5kDQpsZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbG90X3J0KQ0KcGxvdF9ydCA8LSBwbG90X3J0ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQoNCiMgQWRkIHBvc2l0aW9uIG9mIGFzdGVyaXNrcw0KYXN0ZXJpa3NfcnQgPC0gZGF0YS5mcmFtZSgNCiAgeDEgICAgPSBjKDEuODUsIDIuODUsIDEuODUsIDIuODUpLA0KICB4MiAgICA9IGMoMi4xNSwgMy4xNSwgMi4xNSwgMy4xNSksDQogIHkxICAgID0gYygxMzIwLCAxMzIwLCAxMzIwLCAxMzIwKSwNCiAgeHN0YXIgPSBjKDIsICAgIDMsICAgIDIsICAgIDMpLA0KICB5c3RhciA9IGMoMTMzMCwgMTMzMCwgMTMzMCwgMTMzMCksDQogIGxhYiAgID0gYygiKiIsICIqKioiLCAiKioiLCAiKiIpLA0KICBncm91cCA9IGMoIkhDIiwgIkhDIiwgICJPQ0QiLCAiT0NEIikpDQoNCg0KIyBBZGQgcG9zaXRpb24gb2YgYXN0ZXJpc2tzIGFjcm9zcyBncm91cHMNCmFzdGVyaWtzX3J0MiA8LSBkYXRhLmZyYW1lKA0KICB4MSAgICA9IC4zNzAsDQogIHgyICAgID0gLjgyMCwNCiAgeTEgICAgPSAuODIwLA0KICB4c3RhciA9IC41OTUsDQogIHlzdGFyID0gLjgzMCwNCiAgbGFiICAgPSAiKioiKQ0KDQoNCiMgQWRkIGEgbmV3IGxheWVyIG9uLXRvcCB0byBhZGQgYXN0ZXJpc2tzDQpwbG90X3J0IDwtIHBsb3RfcnQgKw0KICBnZW9tX3RleHQoZGF0YSA9IGFzdGVyaWtzX3J0LCAgICBhZXMoeCA9IHhzdGFyLCB5ID0geXN0YXIsIGxhYmVsID0gbGFiLCBzaXplID0gMi41KSwgICAgY29sb3IgPSAiZ3JheTMwIikgKw0KICBnZW9tX3NlZ21lbnQoZGF0YSA9IGFzdGVyaWtzX3J0LCBhZXMoeCA9IHgxLCB4ZW5kID0geDIsIHkgPSB5MSwgeWVuZCA9IHkxKSwgc2l6ZSA9IDAuMywgY29sb3IgPSAiZ3JheTMwIikgKw0KICBmYWNldF9ncmlkKC4gfiBncm91cCwgbGFiZWxsZXIgPSBsYWJlbGxlcihncm91cCA9IGdyb3VwLmxhYnMpKQ0KDQoNCiMgQWRkIGEgbmV3IGxheWVyIG9uLXRvcCB0byBhZGQgYXN0ZXJpc2tzIGFjcm9zcyBncm91cHMNCnBsb3RfcnQgPC0gZ2dkcmF3KHBsb3RfcnQpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBhc3Rlcmlrc19ydDIsICAgIGFlcyh4ID0geHN0YXIsIHkgPSB5c3RhciwgbGFiZWwgPSBsYWIsIHNpemUgPSAyLjUpLCAgICBjb2xvciA9ICJncmF5MzAiKSArDQogIGdlb21fc2VnbWVudChkYXRhID0gYXN0ZXJpa3NfcnQyLCBhZXMoeCA9IHgxLCB4ZW5kID0geDIsIHkgPSB5MSwgeWVuZCA9IHkxKSwgc2l6ZSA9IDAuMywgY29sb3IgPSAiZ3JheTMwIikNCg0KDQojIyMjIENyZWF0ZSBhY2N1cmFjeSBwbG90ICMjIyMNCg0KIyBDcmVhdGUgcmFpbmNsb3VkIHBsb3QNCnBsb3RfYWNjIDwtIGdncGxvdCgpICsNCiAgZ2VvbV9mbGF0X3Zpb2xpbihkYXRhID0gZGF0YV9hZ2dyZWdhdGVkX2FjYywgYWVzKHggPSBnbmdfcmVzcG9uc2VfdHlwZSwgeSA9IGFjY3VyYWN5LCBmaWxsID0gd29yZF92YWxlbmNlKSwNCiAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX251ZGdlKHggPSAuMTYsIHkgPSAwKSwgYWRqdXN0ID0gMS41LCB0cmltID0gRkFMU0UsIGFscGhhID0gLjcsIGNvbG9yID0gTkEpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gZGF0YV9hZ2dyZWdhdGVkX2FjYywgYWVzKHggPSBhcy5udW1lcmljKGduZ19yZXNwb25zZV90eXBlKSAtIC4yMywgeSA9IGFjY3VyYWN5LCBjb2xvciA9IHdvcmRfdmFsZW5jZSksDQogICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAuMDUpLCBzaXplID0gMSwgc2hhcGUgPSAyMCwgYWxwaGEgPSAwLjgpICsNCiAgZ2VvbV9ib3hwbG90KGRhdGEgPSBkYXRhX2FnZ3JlZ2F0ZWRfYWNjLCBhZXMoeCA9IGduZ19yZXNwb25zZV90eXBlLCB5ID0gYWNjdXJhY3ksIGZpbGwgPSB3b3JkX3ZhbGVuY2UpLA0KICAgIG91dGxpZXIuc2hhcGUgPSBOQSwgYWxwaGEgPSAwLjksIHdpZHRoID0gLjMsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHggPSAiUmVzcG9uc2UgaW4gdGhlIEdvL05vLUdvIFRhc2siLCB5ID0gIldvcmQgQ2F0ZWdvcml6YXRpb24gQWNjdXJhY3kgKCUpIikgKw0KICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoMCwgMTA1KSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApLCBleHBhbmQgPSBjKDAsIDApKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiU0giID0gIlNsb3cgSGl0IiwgIkZIIiA9ICJGYXN0IEhpdCIsICJGQSIgPSAiRmFsc2UgQWxhcm0iLCAiSVIiID0gIkluaGliaXRpb24iKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJXb3JkIFZhbGVuY2U6IiwgbGFiZWxzID0gYygiTmVnYXRpdmUiLCAiUG9zaXRpdmUiKSwgdmFsdWVzID0gY29sb3JzKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgID0gIldvcmQgVmFsZW5jZToiLCBsYWJlbHMgPSBjKCJOZWdhdGl2ZSIsICJQb3NpdGl2ZSIpLCB2YWx1ZXMgPSBjb2xvcnMpICsNCiAgZmFjZXRfd3JhcCh+Z3JvdXAsIGxhYmVsbGVyID0gbGFiZWxsZXIoZ3JvdXAgPSBncm91cC5sYWJzKSkgKw0KICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAwLjUsIHhtYXggPSA0LjUsIHltaW4gPSAxMDEsIHltYXggPSAxMDUsIGZpbGwgPSAid2hpdGUiKSArICMgQWRkIHdoaXRlc3BhY2UgYmVsb3cgZmFjZXQNCiAgbXlfZmlndXJlX3RoZW1lICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSAgDQoNCg0KDQojIEFkZCBwb3NpdGlvbiBvZiBhc3Rlcmlza3MNCmFzdGVyaWtzX2FjYyA8LSBkYXRhLmZyYW1lKA0KICB4MSAgICA9IGMoMi44NSwgMi44NSksDQogIHgyICAgID0gYygzLjE1LCAzLjE1KSwNCiAgeTEgICAgPSBjKDE5LCAgIDE5KSwNCiAgeHN0YXIgPSBjKDMsICAgIDMpLA0KICB5c3RhciA9IGMoMTUsICAgMTUpLA0KICBsYWIgICA9IGMoIioqKiIsICIqKioiKSwNCiAgZ3JvdXAgPSBjKCJIQyIsICJPQ0QiKSkNCg0KDQojIEFkZCBhIG5ldyBsYXllciBvbi10b3AgdG8gYWRkIGFzdGVyaXNrcw0KcGxvdF9hY2MgPC0gcGxvdF9hY2MgKw0KICBnZW9tX3RleHQoZGF0YSA9IGFzdGVyaWtzX2FjYywgICAgYWVzKHggPSB4c3RhciwgeSA9IHlzdGFyLCBsYWJlbCA9IGxhYiwgc2l6ZSA9IDIuNSksICAgIGNvbG9yID0gImdyYXkzMCIpICsNCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBhc3Rlcmlrc19hY2MsIGFlcyh4ID0geDEsIHhlbmQgPSB4MiwgeSA9IHkxLCB5ZW5kID0geTEpLCBzaXplID0gMC4zLCBjb2xvciA9ICJncmF5MzAiKSArDQogIGZhY2V0X2dyaWQoLiB+IGdyb3VwLCBsYWJlbGxlciA9IGxhYmVsbGVyKGdyb3VwID0gZ3JvdXAubGFicykpDQoNCg0KIyBBcnJhbmdlIHBsb3RzDQpmaWd1cmVfb2JzX3ZhbCA8LSBnZ2RyYXcoKSArDQogIGRyYXdfcGxvdChwbG90X3J0LCAgeCA9IC4wMCwgeSA9IC40OTAsIHdpZHRoID0gMSwgIGhlaWdodCA9IC41MSkgKw0KICBkcmF3X3Bsb3QocGxvdF9hY2MsIHggPSAuMDAsIHkgPSAuMDUwLCB3aWR0aCA9IDEsICBoZWlnaHQgPSAuNDIpICsNCiAgZHJhd19wbG90KGxlZ2VuZCwgICB4ID0gLjI4LCB5ID0gLjAxNSwgd2lkdGggPSAuNSwgaGVpZ2h0ID0gLjAwKSArDQogIGRyYXdfcGxvdF9sYWJlbChjKCJBIiwgIkIiKSwgYygwLCAwKSwgYygxLCAwLjQ3KSwgc2l6ZSA9IDE1KQ0KZmlndXJlX29ic192YWwNCg0KDQojIFNhdmUgcGxvdA0KZ2dzYXZlKHBsb3QgPSBmaWd1cmVfb2JzX3ZhbCwgIi4vZmlndXJlcy9maWd1cmVfMi50aWZmIiwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMjcsDQogIHVuaXRzID0gImNtIiwgZHBpID0gNjAwLCBjb21wcmVzc2lvbiA9ICJsenciKQ0KYGBgDQo8YnI+PGJyPg0KDQojIyBQbG90IEJlaGF2aW9yYWwgRGF0YSAoUHJlZGljdGVkKQ0KKioqDQoNClRoaXMgZmlndXJlIGNvcnJlc3BvbmRzIHRvIEZpZ3VyZSAzIGluIHRoZSBtYW51c2NyaXB0Lg0KDQpgYGB7ciBjcmVhdGUtcHJlZC12YWx1ZS1wbG90LCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gNSwgZHBpID0gNjAwLCBmaWcuY2FwID0gIjxicj4gTm90ZS4gKEEpIE1vZGVsLXByZWRpY3RlZCBtZWFuIHdvcmQgY2F0ZWdvcml6YXRpb24gUlQgcGVyIHByZWNlZGluZyByZXNwb25zZSB0eXBlIChmYXN0IGhpdCwgZmFsc2UgYWxhcm0pIGluIHRoZSBnby9uby1nbyB0YXNrLCB3b3JkIHZhbGVuY2UsIGFuZCBncm91cCwgY29tcHV0ZWQgYXMgcGFydGlhbCBlZmZlY3RzIGZyb20gdGhlIGxpbmVhciBtaXhlZCBtb2RlbCAoTE1NKS4gUlQgZGF0YSB3ZXJlIGxvZy10cmFuc2Zvcm1lZCBmb3IgYW5hbHlzaXMgYnV0IGJhY2stdHJhbnNmb3JtZWQgdG8gbXMgZm9yIHZpc3VhbGl6YXRpb24uIChCKSBNb2RlbC1wcmVkaWN0ZWQgbWVhbiB3b3JkIGNhdGVnb3JpemF0aW9uIGFjY3VyYWN5IHBlciBwcmVjZWRpbmcgcmVzcG9uc2UgdHlwZSAoZmFzdCBoaXQsIGZhbHNlIGFsYXJtKSBpbiB0aGUgZ28vbm8tZ28gdGFzaywgd29yZCB2YWxlbmNlLCBhbmQgZ3JvdXAsIGNvbXB1dGVkIGFzIHBhcnRpYWwgZWZmZWN0cyBmcm9tIHRoZSBnZW5lcmFsaXplZCBsaW5lYXIgbWl4ZWQgbW9kZWwgKEdMTU0pLiAoQeKAk0IpIEVycm9yIGJhcnMgaW5kaWNhdGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiBBc3Rlcmlza3MgaW5kaWNhdGUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgeWllbGRlZCBieSB0aGUgKEcpTE1NIGFuYWx5c2lzLiAqIHAgPCAuMDUsICoqIHAgPCAuMDEsICoqKiBwIDwgLjAwMS4ifQ0KDQojIExvYWQgKEcpTE1NIG91dHB1dA0KTE1NX3J0X2ZpbmFsICAgPC0gcmVhZFJEUyhmaWxlID0gIi4vc2F2ZWRfb2JqZWN0c19mb3JfcGxvdHMvTE1NX3J0X2ZpbmFsLnJkcyIpDQpHTE1NX2FjY19maW5hbCA8LSByZWFkUkRTKGZpbGUgPSAiLi9zYXZlZF9vYmplY3RzX2Zvcl9wbG90cy9HTE1NX2FjY19maW5hbC5yZHMiKQ0KDQoNCiMgRGVmaW5lIGZhY2V0IGxhYmVscw0KZ3JvdXAubGFicyA8LSBjKCJIZWFsdGh5IENvbnRyb2wgUGFydGljaXBhbnRzIiwgIlBhdGllbnRzIFdpdGggT0NEIikNCm5hbWVzKGdyb3VwLmxhYnMpIDwtIGMoIkhDIiwgIk9DRCIpDQoNCg0KIyMjIyBDcmVhdGUgUlQgcGxvdCAjIyMjDQoNCiMgRXh0cmFjdCBvbmx5IEZBIGFuZCBGSCBmcm9tIExNTQ0KTE1NX3J0ICAgICAgICA8LSBnZ3ByZWRpY3QoTE1NX3J0X2ZpbmFsLCB0ZXJtcyA9IGMoImduZ19yZXNwb25zZV90eXBlIiwgIndvcmRfdmFsZW5jZSIsICJncm91cCIpKQ0KTE1NX3J0X3Bsb3QgICA8LSBMTU1fcnRbTE1NX3J0JHggJWluJSBjKCJGSCIsICJGQSIpLCBdDQpMTU1fcnRfcGxvdCR4IDwtIGRyb3BsZXZlbHMoTE1NX3J0X3Bsb3QkeCkNCg0KDQojIFBsb3QgcHJlZGljdGVkIG1lYW5zDQpwbG90X0xNTV9ydCA8LSBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IExNTV9ydF9wbG90LCBhZXMoeCA9IHgsIHkgPSBwcmVkaWN0ZWQsIGNvbG9yID0gZ3JvdXApLA0KICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuMjUpLCBzaXplID0gMi41KSArDQogIGdlb21fZXJyb3JiYXIoZGF0YSA9IExNTV9ydF9wbG90LCBhZXMoeCA9IHgsIHltYXggPSBjb25mLmxvdywgeW1pbiA9IGNvbmYuaGlnaCwgIGNvbG9yID0gZ3JvdXApLA0KICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuMjUpLCBzaXplID0gLjcsIHdpZHRoID0gLjIpICsNCiAgbGFicyh4ID0gIlJlc3BvbnNlIGluIHRoZSBHby9Oby1HbyBUYXNrIiwgeSA9ICJQcmVkaWN0ZWQgV29yZCBDYXRlZ29yaXphdGlvbiBSVCAobXMpIikgKw0KICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoNTAwLCA5NTApKSArDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoNTAwLCA5NTAsIDUwKSwgZXhwYW5kID0gYygwLCAwKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoIkZIIiA9ICJGYXN0IEhpdCIsICJGQSIgPSAiRmFsc2UgQWxhcm0iKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJXb3JkIFZhbGVuY2U6IiwgbGFiZWxzID0gYygiTmVnYXRpdmUiLCAiUG9zaXRpdmUiKSwgdmFsdWVzID0gY29sb3JzKSArDQogIGZhY2V0X3dyYXAofmZhY2V0LCBsYWJlbGxlciA9IGxhYmVsbGVyKGZhY2V0ID0gZ3JvdXAubGFicykpICsNCiAgbXlfZmlndXJlX3RoZW1lDQoNCg0KIyBTYXZlIGFuZCByZW1vdmUgbGVnZW5kDQpsZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbG90X0xNTV9ydCkNCnBsb3RfTE1NX3J0ICA8LSBwbG90X0xNTV9ydCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KDQojIEFkZCBwb3NpdGlvbiBvZiBhc3Rlcmlza3MNCmFzdGVyaWtzX3J0IDwtIGRhdGEuZnJhbWUoDQogIHgxICAgID0gYyguMjI1LCAuNDE1LCAuNjU1LCAuODQ1LCAuNDMwKSwNCiAgeDIgICAgPSBjKC4yNzUsIC40NjUsIC43MDUsIC44OTUsIC44ODApLA0KICB5MSAgICA9IGMoLjgwMCwgLjgwMCwgLjgwMCwgLjgwMCwgLjg2MCksDQogIHhzdGFyID0gYyguMjUwLCAuNDQwLCAuNjgwLCAuODcwLCAuNjU1KSwNCiAgeXN0YXIgPSBjKC44MTAsIC44MTAsIC44MTAsIC44MTAsIC44NzApLA0KICBsYWIgICA9IGMoIioiLCAgIioqKiIsICIqKiIsICIqIiwgICIqKiIpKQ0KDQoNCiMgQWRkIGEgbmV3IGxheWVyIG9uLXRvcCB0byBhZGQgYXN0ZXJpc2tzDQpwbG90X0xNTV9ydCA8LSBnZ2RyYXcocGxvdF9MTU1fcnQpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBhc3Rlcmlrc19ydCwgICAgYWVzKHggPSB4c3RhciwgeSA9IHlzdGFyLCBsYWJlbCA9IGxhYiwgc2l6ZSA9IDIuNSksICAgIGNvbG9yID0gImdyYXkzMCIpICsNCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBhc3Rlcmlrc19ydCwgYWVzKHggPSB4MSwgeGVuZCA9IHgyLCB5ID0geTEsIHllbmQgPSB5MSksIHNpemUgPSAwLjMsIGNvbG9yID0gImdyYXkzMCIpDQoNCg0KIyMjIyBDcmVhdGUgYWNjdXJhY3kgcGxvdCAjIyMjDQoNCiMgRXh0cmFjdCBvbmx5IEZBIGFuZCBGSCBmcm9tIEdMTU0NCkdMTU1fYWNjICAgICAgICA8LSBnZ3ByZWRpY3QoR0xNTV9hY2NfZmluYWwsIHRlcm1zID0gYygiZ25nX3Jlc3BvbnNlX3R5cGUiLCAid29yZF92YWxlbmNlIiwgImdyb3VwIikpDQpHTE1NX2FjY19wbG90ICAgPC0gR0xNTV9hY2NbR0xNTV9hY2MkeCAlaW4lIGMoIkZIIiwgIkZBIiksIF0NCkdMTU1fYWNjX3Bsb3QkeCA8LSBkcm9wbGV2ZWxzKEdMTU1fYWNjX3Bsb3QkeCkNCg0KDQojIFBsb3QgcHJlZGljdGVkIG1lYW5zDQpwbG90X0dMTU1fYWNjIDwtIGdncGxvdCgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gR0xNTV9hY2NfcGxvdCwgYWVzKHggPSB4LCB5ID0gcHJlZGljdGVkICogMTAwLCBjb2xvciA9IGdyb3VwKSwNCiAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLjI1KSwgc2l6ZSA9IDIuNSkgKw0KICBnZW9tX2Vycm9yYmFyKGRhdGEgPSBHTE1NX2FjY19wbG90LCBhZXMoeCA9IHgsIHltYXggPSBjb25mLmxvdyAqIDEwMCwgeW1pbiA9IGNvbmYuaGlnaCAqIDEwMCwgY29sb3IgPSBncm91cCksDQogICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC4yNSksIHNpemUgPSAuNywgd2lkdGggPSAuMikgKw0KICBsYWJzKHggPSAiUmVzcG9uc2UgaW4gdGhlIEdvL05vLUdvIFRhc2siLCB5ID0gIlByZWRpY3RlZCBXb3JkIENhdGVnb3JpemF0aW9uIEFjY3VyYWN5ICglKSIpICsNCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDUwLCAxMTApKSArDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoNTAsIDEwMCwgNSksIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJGSCIgPSAiRmFzdCBIaXQiLCAiRkEiID0gIkZhbHNlIEFsYXJtIikpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiV29yZCBWYWxlbmNlOiIsIGxhYmVscyA9IGMoIk5lZ2F0aXZlIiwgIlBvc2l0aXZlIiksIHZhbHVlcyA9IGNvbG9ycykgKw0KICBmYWNldF93cmFwKH5mYWNldCwgbGFiZWxsZXIgPSBsYWJlbGxlcihmYWNldCA9IGdyb3VwLmxhYnMpKSArDQogIG15X2ZpZ3VyZV90aGVtZSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KDQojIEFkZCBwb3NpdGlvbiBvZiBhc3Rlcmlza3MNCmFzdGVyaWtzX2FjYyA8LSBkYXRhLmZyYW1lKA0KICB4MSAgICA9IGMoLjQxNSwgLjg0NSksDQogIHgyICAgID0gYyguNDY1LCAuODk1KSwNCiAgeTEgICAgPSBjKC44MDAsIC44MDApLA0KICB4c3RhciA9IGMoLjQ0MCwgLjg3MCksDQogIHlzdGFyID0gYyguODEwLCAuODEwKSwNCiAgbGFiICAgPSBjKCIqKioiLCAiKioqIikpDQoNCg0KIyBBZGQgYSBuZXcgbGF5ZXIgb24tdG9wIHdpdGggZ2dkcmF3IGluIG9yZGVyIHRvIGFkZCBhc3Rlcmlza3MNCnBsb3RfR0xNTV9hY2MgPC0gZ2dkcmF3KHBsb3RfR0xNTV9hY2MpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBhc3Rlcmlrc19hY2MsICAgIGFlcyh4ID0geHN0YXIsICB5ID0geXN0YXIsIGxhYmVsID0gbGFiLCBzaXplID0gMi41KSwgICBjb2xvciA9ICJncmF5MzAiKSArDQogIGdlb21fc2VnbWVudChkYXRhID0gYXN0ZXJpa3NfYWNjLCBhZXMoeCA9IHgxLCB4ZW5kID0geDIsIHkgPSB5MSwgeWVuZCA9IHkxKSwgc2l6ZSA9IDAuMywgY29sb3IgPSAiZ3JheTMwIikNCg0KDQojIyMjIEFycmFuZ2UgcGxvdHMNCmZpZ3VyZV9wcmVkX3ZhbCA8LSBnZ2RyYXcoKSArDQogIGRyYXdfcGxvdChwbG90X0xNTV9ydCwgICB4ID0gLjAwLCB5ID0gLjA3MCwgd2lkdGggPSAuNDksIGhlaWdodCA9IC45MykgKw0KICBkcmF3X3Bsb3QocGxvdF9HTE1NX2FjYywgeCA9IC41MiwgeSA9IC4wNzAsIHdpZHRoID0gLjQ5LCBoZWlnaHQgPSAuOTMpICsNCiAgZHJhd19wbG90KGxlZ2VuZCwgICAgICAgIHggPSAuMjgsIHkgPSAuMDE1LCB3aWR0aCA9IC41MCwgaGVpZ2h0ID0gLjAwKSAgICsNCiAgZHJhd19wbG90X2xhYmVsKGMoIkEiLCAiQiIpLCBjKDAsIDAuNTIpLCBjKDEsIDEpLCBzaXplID0gMTUpDQpmaWd1cmVfcHJlZF92YWwNCg0KDQojIFNhdmUgcGxvdA0KZ2dzYXZlKHBsb3QgPSBmaWd1cmVfcHJlZF92YWwsICIuL2ZpZ3VyZXMvZmlndXJlXzMudGlmZiIsIHdpZHRoID0gMjAsIGhlaWdodCA9IDEyLA0KICB1bml0cyA9ICJjbSIsIGRwaSA9IDYwMCwgY29tcHJlc3Npb24gPSAibHp3IikNCmBgYA0KPGJyPjxicj4NCg0KIyMgUGxvdCBFUlAgRGF0YQ0KKioqDQoNClRoaXMgZmlndXJlIGNvcnJlc3BvbmRzIHRvIEZpZ3VyZSA0IGluIHRoZSBtYW51c2NyaXB0Lg0KDQo8IS0tIExvYWQgYW5kIGNsZWFuIGRhdGEgLS0+DQoNCmBgYHtyIGxvYWQtYW5kLWNsZWFuLWVycC1kYXRhLCBjYWNoZSA9IGtuaXRyX2NhY2hlX2VuYWJsZWR9DQoNCiMgTG9hZCBkYXRhDQpyZXNwX2xvY2tlZF9kYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSAiLi9kYXRhL3Jlc3BvbnNlX2xvY2tlZF9kYXRhX2Zvcl9wbG90cy5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KDQoNCiMgQ3JlYXRlIHJlbGV2YW50IHZhcmlhYmxlcyBhbmQgZmlsdGVyIGRhdGENCnJlc3BfbG9ja2VkX2RhdGEgPC0gcmVzcF9sb2NrZWRfZGF0YSAlPiUNCiAgZHBseXI6Om11dGF0ZSgNCiAgICBzdGltdWxhdGlvbiA9IGZhY3RvcihpZmVsc2UoDQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiQ18wMV9UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18wMl9UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18wM19UMiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIkNfMDRfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIkNfMDVfVDEiIHwgcGFydGljaXBhbnRfaWQgPT0gIkNfMDZfVDIiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJDXzA3X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJDXzA4X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJDXzA5X1QyIiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiQ18xMF9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18xMV9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18xMl9UMiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIkNfMTNfVDEiIHwgcGFydGljaXBhbnRfaWQgPT0gIkNfMTVfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIkNfMTZfVDEiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJDXzE3X1QyIiB8IHBhcnRpY2lwYW50X2lkID09ICJDXzE4X1QyIiB8IHBhcnRpY2lwYW50X2lkID09ICJDXzE5X1QxIiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiQ18yMF9UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18yMV9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18yMl9UMiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIkNfMjNfVDEiIHwgcGFydGljaXBhbnRfaWQgPT0gIkNfMjRfVDEiIHwgcGFydGljaXBhbnRfaWQgPT0gIkNfMjVfVDEiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJDXzI2X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJDXzI3X1QyIiB8IHBhcnRpY2lwYW50X2lkID09ICJDXzI4X1QyIiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiQ18yOV9UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiQ18zMF9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8wMV9UMSIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIlBfMDJfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMDNfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMDRfVDEiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJQXzA1X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzA2X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzA3X1QyIiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiUF8wOF9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8wOV9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8xMF9UMSIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIlBfMTFfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMTJfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMTNfVDEiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJQXzE1X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzE2X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzE3X1QyIiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiUF8xOF9UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8xOV9UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8yMF9UMiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIlBfMjFfVDIiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMjJfVDEiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMjNfVDEiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJQXzI0X1QyIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzI1X1QxIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzI2X1QyIiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiUF8yN19UMSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8yOF9UMiIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8yOV9UMiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIlBfMzBfVDEiLCAic2hhbSIsICJ2ZXJ1bSIpKSwNCiAgICBjb25kaXRpb24gICAgICA9IGZhY3RvcihpZmVsc2UoY29uZGl0aW9uID09IDEsICJjb3JyZWN0IiwgImluY29ycmVjdCIpLCBsZXZlbHMgPSBjKCJpbmNvcnJlY3QiLCAiY29ycmVjdCIpKSwNCiAgICBncm91cCAgICAgICAgICA9IGZhY3RvcihpZmVsc2Uoc3Vic3RyKHBhcnRpY2lwYW50X2lkLCAxLCAxKSA9PSAiQyIsICJIQyIsICJPQ0QiKSksDQogICAgc2Vzc2lvbiAgICAgICAgPSBmYWN0b3IoaWZlbHNlKHN1YnN0cihwYXJ0aWNpcGFudF9pZCwgNiwgNykgPT0gIlQxIiwgIlQxIiwgIlQyIikpLA0KICAgIHBhcnRpY2lwYW50X2lkID0gZmFjdG9yKHN1YnN0cihwYXJ0aWNpcGFudF9pZCwgMSwgNCkpKSAlPiUgIyB0byBnZXQgY29ycmVjdCBuby4gb2YgZmFjdG9yIGxldmVscw0KICAjIE9ubHkga2VlcCBzaGFtIHNlc3Npb24gYW5kIGV4Y2x1ZGUgUF8wMiBhbmQgQ18wMg0KICBkcGx5cjo6ZmlsdGVyKHN0aW11bGF0aW9uID09ICJzaGFtIiAmIHBhcnRpY2lwYW50X2lkICE9ICJQXzAyIiAmIHBhcnRpY2lwYW50X2lkICE9ICJDXzAyIikNCg0KDQojIFVwZGF0ZSBmYWN0b3IgbGV2ZWxzDQpyZXNwX2xvY2tlZF9kYXRhJHBhcnRpY2lwYW50X2lkIDwtIGRyb3BsZXZlbHMocmVzcF9sb2NrZWRfZGF0YSRwYXJ0aWNpcGFudF9pZCkNCg0KDQojIENhbGN1bGF0ZSBydW5uaW5nIHdpdGhpbi1wYXJ0aWNpcGFudCBDSXMNCnJ1bm5pbmdfY2lfbWZuIDwtIHJlc3BfbG9ja2VkX2RhdGEgJT4lDQogIHNwbGl0KC4kdGltZSkgJT4lDQogIG1hcCh+IHN1bW1hcnlTRXdpdGhpbk8oDQogICAgZGF0YSA9IC4sDQogICAgbWVhc3VyZXZhciAgPSAiRkN6IiwNCiAgICB3aXRoaW52YXJzICA9ICJjb25kaXRpb24iLA0KICAgIGJldHdlZW52YXJzID0gImdyb3VwIiwNCiAgICBpZHZhciAgICAgICA9ICJwYXJ0aWNpcGFudF9pZCIpKQ0KDQoNCmNpX21mbiA8LSBwdXJycjo6bWFwX2RmKHJ1bm5pbmdfY2lfbWZuLCBtYWdyaXR0cjo6ZXh0cmFjdCkgJT4lDQogIGRwbHlyOjptdXRhdGUodGltZSA9IHJlcCh1bmlxdWUocmVzcF9sb2NrZWRfZGF0YSR0aW1lKSwgZWFjaCA9IDQpKQ0KIyBOb3RlLiA0IHJlZmVycyB0byAgbm8uIG9mIGNvbmRpdGlvbnMgKGdyb3VwIHggcmVzcG9uc2VfdHlwZSA9IDIgeCAyID0gNCkNCg0KDQojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgZm9yIGVsZWN0cm9kZXMNCmRhdGFfdG9wb19tZm4gPC0gcmVzcF9sb2NrZWRfZGF0YSAlPiUNCiAgIyBSZW1vdmUgY2hhbm5lbHMgb2Ygbm8gaW50ZXJlc3QNCiAgZHBseXI6OnNlbGVjdCgtSU8xLCAtTTEsIC1GOSwgLUYxMCkgJT4lDQogICMgQ2hhbmdlIGZyb20gd2lkZSB0byBsb25nIGZvcm1hdCBmb3IgZWxlY3Ryb2Rlcw0KICB0aWR5cjo6Z2F0aGVyKC4sIGVsZWN0cm9kZSwgYW1wbGl0dWRlLCBGcDE6TzIsIGZhY3Rvcl9rZXkgPSBUUlVFKSAgJT4lDQogICMgU2VsZWN0IHRpbWUgd2luZG93cw0KICBkcGx5cjo6ZmlsdGVyKHRpbWUgPj0gMCAmIHRpbWUgPD0gMTAwKSAlPiUNCiAgIyBBZGQgZWxlY3Ryb2RlIGluZm9ybWF0aW9uDQogIGVsZWN0cm9kZV9sb2NhdGlvbnMoLiwgZWxlY3Ryb2RlID0gImVsZWN0cm9kZSIsIGRyb3AgPSBGQUxTRSwgbW9udGFnZSA9IE5VTEwpDQpgYGANCg0KPCEtLSBDcmVhdGUgcGxvdHMgLS0+DQoNCmBgYHtyIGNyZWF0ZS1lcnAtcGxvdCwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDEwLCBjYWNoZSA9IGtuaXRyX2NhY2hlX2VuYWJsZWQsIGRwaSA9IDYwMCwgZmlnLmNhcCA9ICJOb3RlLiAoQSkgR3JhbmQgYXZlcmFnZSByZXNwb25zZS1sb2NrZWQgd2F2ZWZvcm1zIGF0IGVsZWN0cm9kZSBzaXRlIEZDeiB3aXRoIDk1JSBjb25maWRlbmNlIGludGVydmFscyBpbiBwYXRpZW50cyB3aXRoIE9DRCBhbmQgSEMgcGFydGljaXBhbnRzIGZvciBjb3JyZWN0IChoaXQpIGFuZCBpbmNvcnJlY3QgKGZhbHNlIGFsYXJtKSByZXNwb25zZXMgaW4gdGhlIGdvL25vLWdvIHRhc2suIFRoZSBncmF5IHNoYWRlZCB0aW1lIGludGVydmFsIHdhcyB1c2VkIHRvIHF1YW50aWZ5IEVSTiBhbmQgQ1JOIGFtcGxpdHVkZS4gKEIpIFNjYWxwIHRvcG9ncmFwaGllcyBvZiBFUk4gYW5kIENSTiBpbiBib3RoIGdyb3VwcyBpbiB0aGUgdGltZSB3aW5kb3cgMOKAkzEwMCBtcyBhZnRlciBmYWxzZSBhbGFybXMgb3IgaGl0cywgcmVzcGVjdGl2ZWx5LiJ9DQoNCiMjIyMgQ3JlYXRlIHdhdmVmb3JtIHBsb3QgIyMjIw0KDQojIERlZmluZSBlbGVjdHJvZGUgbGFiZWxzDQpsYWJlbF9mY3ogPC0gZGF0YS5mcmFtZSh0aW1lID0gLTMyMCwgRkN6ID0gMTcuNSwgbGFiID0gIlRleHQiKSANCg0KDQojIENyZWF0ZSB3YXZlZm9ybSBwbG90DQpwbG90X3dhdmVmb3JtX21mbiA8LSBnZ3Bsb3QocmVzcF9sb2NrZWRfZGF0YSwgYWVzKHRpbWUsIEZDeikpICsNCiAgc3RhdF9zdW1tYXJ5KGZ1biA9IG1lYW4sIGdlb20gPSAibGluZSIsIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiwgYWVzKGNvbG9yID0gY29uZGl0aW9uOmdyb3VwKSkgKw0KICBnZW9tX3JpYmJvbihkYXRhID0gY2lfbWZuLCBhZXMoeW1pbiA9IEZDeiAtIGNpLCB5bWF4ID0gRkN6ICsgY2ksIGZpbGwgPSBjb25kaXRpb246Z3JvdXApLCBhbHBoYSA9IDAuMikgKw0KICBndWlkZXMoZmlsbCA9ICJub25lIikgKw0KICBnZW9tX3NlZ21lbnQoYWVzKHggPSAwLCAgICB4ZW5kID0gMCwgICB5ID0gLTgsIHllbmQgPSAxOCksIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImdyYXk2MCIsIHNpemUgPSAwLjIpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLTQwMCwgeGVuZCA9IDgwMCwgeSA9ICAwLCB5ZW5kID0gMCksICBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJncmF5NjAiLCBzaXplID0gMC4yKSArDQogIGdlb21fdGV4dChkYXRhID0gbGFiZWxfZmN6LCBsYWJlbCA9ICJGQ3oiKSArDQogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDAsIHhtYXggPSAxMDAsIHltaW4gPSAtOCwgeW1heCA9IDE4LCBhbHBoYSA9IC4yLCBmaWxsID0gImdyYXk1MCIpICsgIyBTaGFkZWQgdGltZSBhcmVhDQogIGxhYnMoeCA9ICJUaW1lIChtcykiLCB5ID0gZXhwcmVzc2lvbihwYXN0ZSgiQW1wbGl0dWRlICgiLCBtdSwgIlYpIikpKSArDQogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygtOCwgMTgpLCB4bGltID0gYygtMjAwLCA0MDApKSArDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTgsIDE4LCAyKSwgZXhwYW5kID0gYygwLCAwKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC0yMDAsIDQwMCwgMTAwKSwgZXhwYW5kID0gYygwLCAwKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzX2VycCwgbGFiZWxzID0gYygiSEM6IEZhbHNlIEFsYXJtIiwgIk9DRDogRmFsc2UgQWxhcm0iLCAiSEM6IEhpdCIsICJPQ0Q6IEhpdCIpLA0KICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDEuMykpKSArICMgVGhpY2tuZXNzIGxlZ2VuZCBsaW5lcw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnNfZXJwKSArDQogIG15X2ZpZ3VyZV90aGVtZSArIA0KICB0aGVtZShheGlzLnRpY2tzLnggPSBOVUxMLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSkNCg0KDQojIyMjIENyZWF0ZSB0b3BvZ3JhcGh5IHBsb3RzICMjIyMNCg0KIyBEZWZpbmUgZmFjZXQgbGFiZWxzDQpsYWJzX2luY29yciA8LSBjKCJIQzogRmFsc2UgQWxhcm0iLCAiT0NEOiBGYWxzZSBBbGFybSIpDQpuYW1lcyhsYWJzX2luY29ycikgPC0gYygiSEMiLCAiT0NEIikNCg0KbGFic19jb3JyIDwtIGMoIkhDOiBIaXQiLCAiT0NEOiBIaXQiKQ0KbmFtZXMobGFic19jb3JyKSA8LSBjKCJIQyIsICJPQ0QiKQ0KDQoNCiMgRVJODQpwbG90X3RvcG9fZXJuIDwtIGdncGxvdChkYXRhX3RvcG9fbWZuW2RhdGFfdG9wb19tZm4kY29uZGl0aW9uID09ICJpbmNvcnJlY3QiLCBdLA0KICBhZXMoeCA9IHgsIHkgPSB5LCBmaWxsID0gYW1wbGl0dWRlLCB6ID0gYW1wbGl0dWRlLCBsYWJlbCA9IGVsZWN0cm9kZSkpICsNCiAgZ2VvbV90b3BvKGdyaWRfcmVzID0gMzAwLCBpbnRlcnBfbGltaXQgPSAiaGVhZCIsIGNoYW5fbWFya2VycyA9ICJwb2ludCIsIGNoYW5fc2l6ZSA9IDAuMSwgDQogICAgICAgICAgICBoZWFkX3NpemUgPSAwLjIsIGNvbG91ciA9ICJncmF5NDAiLCBzaXplID0gMC4yKSArDQogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGUgPSAiUmRCdSIsIGxpbWl0cyA9IGMoLTQsIDQpLCBicmVha3MgPSBjKC00LCAwLCA0KSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICBjb29yZF9lcXVhbCgpICsNCiAgbGFicyhmaWxsID0gZXhwcmVzc2lvbihwYXN0ZShtdSwgIlYiKSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvciA9ICJncmF5MzAiKSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGNvbG9yID0gImdyYXkzMCIsIHZqdXN0ID0gMC45KSwgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuMjUsICdjbScpLA0KICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDAuMywgJ2NtJyksIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOSkpICsNCiAgZmFjZXRfd3JhcCguIH5ncm91cCwgbmNvbCA9IDIsIGxhYmVsbGVyID0gbGFiZWxsZXIoZ3JvdXAgPSBsYWJzX2luY29ycikpDQoNCg0KIyBTYXZlIGFuZCByZW1vdmUgbGVnZW5kDQpsZWdlbmRfZXJuIDwtIGdldF9sZWdlbmQocGxvdF90b3BvX2VybikNCnBsb3RfdG9wb19lcm4gPC0gcGxvdF90b3BvX2VybiArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KDQojIENSTg0KcGxvdF90b3BvX2NybiA8LSBnZ3Bsb3QoZGF0YV90b3BvX21mbltkYXRhX3RvcG9fbWZuJGNvbmRpdGlvbiA9PSAiY29ycmVjdCIsIF0sDQogIGFlcyh4ID0geCwgeSA9IHksIGZpbGwgPSBhbXBsaXR1ZGUsIHogPSBhbXBsaXR1ZGUsIGxhYmVsID0gZWxlY3Ryb2RlKSkgKw0KICBnZW9tX3RvcG8oZ3JpZF9yZXMgPSAzMDAsIGludGVycF9saW1pdCA9ICJoZWFkIiwgY2hhbl9tYXJrZXJzID0gInBvaW50IiwgY2hhbl9zaXplID0gMC4xLCANCiAgICAgICAgICAgIGhlYWRfc2l6ZSA9IDAuMiwgY29sb3VyID0gImdyYXk0MCIsIHNpemUgPSAwLjIpICsNCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIocGFsZXR0ZSA9ICJSZEJ1IiwgbGltaXRzID0gYygtNCwgOC40KSwgYnJlYWtzID0gYygtNCwgMCwgNCwgOCkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgY29vcmRfZXF1YWwoKSArDQogIGxhYnMoZmlsbCA9IGV4cHJlc3Npb24ocGFzdGUobXUsICJWIikpKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCwgY29sb3IgPSAiZ3JheTMwIiksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBjb2xvciA9ICJncmF5MzAiLCB2anVzdCA9IDAuOSksIGxlZ2VuZC5rZXkuaGVpZ2h0ID0gdW5pdCgwLjI1LCAnY20nKSwNCiAgICBsZWdlbmQua2V5LndpZHRoID0gdW5pdCgwLjMsICdjbScpLCBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkpKSArDQogIGZhY2V0X3dyYXAoLiB+Z3JvdXAsIG5jb2wgPSAyLCBsYWJlbGxlciA9IGxhYmVsbGVyKGdyb3VwID0gbGFic19jb3JyKSkNCg0KDQojIFNhdmUgYW5kIHJlbW92ZSBsZWdlbmQNCmxlZ2VuZF9jcm4gPC0gZ2V0X2xlZ2VuZChwbG90X3RvcG9fY3JuKQ0KcGxvdF90b3BvX2NybiA8LSBwbG90X3RvcG9fY3JuICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQoNCiMgT3ZlcmxheSB3YXZlZm9ybSBhbmQgdG9wb3BncmFwaHkgcGxvdHMNCmFsaWduZWRfcGxvdHMxX21mbiA8LSBhbGlnbl9wbG90cyhwbG90X3dhdmVmb3JtX21mbiwgcGxvdF90b3BvX2VybiwgYXhpcyA9ICJ0ciIpDQphbGlnbmVkX3Bsb3RzMl9tZm4gPC0gYWxpZ25fcGxvdHMocGxvdF93YXZlZm9ybV9tZm4sIHBsb3RfdG9wb19jcm4sIGF4aXMgPSAidHIiKQ0KDQoNCiMgQXJyYW5nZSBwbG90cw0KZmlndXJlX2Vybl9jcm4gPC0gZ2dkcmF3KCkgKw0KICBkcmF3X3Bsb3QoYWxpZ25lZF9wbG90czFfbWZuW1sxXV0sIHggPSAwLCAgIHkgPSAuMzIsIHdpZHRoID0gLjk5LCBoZWlnaHQgPSAuNjQpICsNCiAgZHJhd19wbG90KGFsaWduZWRfcGxvdHMxX21mbltbMl1dLCB4ID0gLjA5LCB5ID0gLjA1LCB3aWR0aCA9IC40MiwgaGVpZ2h0ID0gLjIxKSArDQogIGRyYXdfcGxvdChhbGlnbmVkX3Bsb3RzMl9tZm5bWzJdXSwgeCA9IC41NSwgeSA9IC4wNSwgd2lkdGggPSAuNDIsIGhlaWdodCA9IC4yMSkgKw0KICBkcmF3X3Bsb3QobGVnZW5kX2VybiwgICAgICAgICAgICAgIHggPSAuMDcsIHkgPSAwLCAgIHdpZHRoID0gLjQyLCBoZWlnaHQgPSAuMDUpICsNCiAgZHJhd19wbG90KGxlZ2VuZF9jcm4sICAgICAgICAgICAgICB4ID0gLjUzLCB5ID0gMCwgICB3aWR0aCA9IC40MiwgaGVpZ2h0ID0gLjA1KSArDQogIGRyYXdfcGxvdF9sYWJlbChjKCJBIiwgIkIiKSwgYygwLCAwKSwgYygxLCAwLjI4NSksIHNpemUgPSAxNSkNCmZpZ3VyZV9lcm5fY3JuDQoNCg0KIyBTYXZlIHBsb3QNCmdnc2F2ZShwbG90ID0gZmlndXJlX2Vybl9jcm4sICIuL2ZpZ3VyZXMvZmlndXJlXzQudGlmZiIsIHdpZHRoID0gMTMuNSwgaGVpZ2h0ID0gMTYsDQogIHVuaXRzID0gImNtIiwgZHBpID0gNjAwLCBjb21wcmVzc2lvbiA9ICJsenciKQ0KYGBgDQo8YnI+PGJyPg0KDQojIyBQbG90IEVmZmVjdHMgb2YgT0NEIENoYXJhY3RlcmlzdGljcw0KKioqDQoNCiMjIyBPQ0QgU3ltcHRvbSBTZXZlcml0eSAoT0NJLVIpDQo8YnI+DQpUaGlzIGZpZ3VyZSBjb3JyZXNwb25kcyB0byBGaWd1cmUgNSBpbiB0aGUgbWFudXNjcmlwdC4NCg0KYGBge3IgY3JlYXRlLXBsb3Qtb2NpLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gNSwgZHBpID0gNjAwLCBmaWcuY2FwID0gIjxicj4gTm90ZS4gKEEpIE1vZGVsLXByZWRpY3RlZCBpbnRlcmFjdGlvbiBlZmZlY3QgYmV0d2VlbiBPYnNlc3NpdmUtQ29tcHVsc2l2ZSBJbnZlbnRvcnktUmV2aXNlZCAoT0NJLVIpIHNjb3JlLCBwcmVjZWRpbmcgcmVzcG9uc2UgdHlwZSAoZmFzdCBoaXQsIGZhbHNlIGFsYXJtKSBpbiB0aGUgZ28vbm8tZ28gdGFzaywgYW5kIHdvcmQgdmFsZW5jZSBvbiB3b3JkIGNhdGVnb3JpemF0aW9uIHJlc3BvbnNlIHRpbWUgKFJUKSBpbiBwYXRpZW50cyB3aXRoIE9DRCwgY29tcHV0ZWQgYXMgcGFydGlhbCBlZmZlY3RzIGZyb20gdGhlIGxpbmVhciBtaXhlZCBtb2RlbC4gUlQgZGF0YSB3ZXJlIGxvZy10cmFuc2Zvcm1lZCBmb3IgYW5hbHlzaXMgYnV0IHdlcmUgYmFjay10cmFuc2Zvcm1lZCB0byBtcyBmb3IgZGF0YSB2aXN1YWxpemF0aW9uLiAoQikgTmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgT0NJLVIgc2NvcmUgYW5kIHRoZSBvdmVyYWxsIHByaW1pbmcgZWZmZWN0IGFjcm9zcyBwYXJ0aWNpcGFudHMuIFRoZSBvdmVyYWxsIHByaW1pbmcgZWZmZWN0IHJlZmVycyB0byB0aGUgcHJpbWluZyBlZmZlY3QgYWZ0ZXIgZmFsc2UgYWxhcm1zIGFuZCBmYXN0IGhpdHMgYW5kIHdhcyBjYWxjdWxhdGVkIGJ5IHN1YnRyYWN0aW5nIHRoZSBSVCBpbiBjb25ncnVlbnQgY29uZGl0aW9ucyAocG9zaXRpdmUgd29yZHMgYWZ0ZXIgZmFzdCBoaXRzIGFuZCBuZWdhdGl2ZSB3b3JkcyBhZnRlciBmYWxzZSBhbGFybXMpIGZyb20gdGhlIFJUIGluIGluY29uZ3J1ZW50IGNvbmRpdGlvbnMgKHBvc2l0aXZlIHdvcmRzIGFmdGVyIGZhbHNlIGFsYXJtcyBhbmQgbmVnYXRpdmUgd29yZHMgYWZ0ZXIgZmFzdCBoaXRzKSBmb3IgZWFjaCBwYXJ0aWNpcGFudCAoQWFydHMgZXQgYWwuLCAyMDEyKS4gKEHigJNCKSBTaGFkZWQgYmFuZHMgcmVwcmVzZW50IDk1JSBjb25maWRlbmNlIGludGVydmFscy4ifQ0KDQojIExvYWQgTE1NIG91dHB1dCBhbmQgY29ycmVsYXRpb24gZGF0YQ0KTE1NX3J0X29jaV9vY2QgIDwtIHJlYWRSRFMoZmlsZSA9ICIuL3NhdmVkX29iamVjdHNfZm9yX3Bsb3RzL0xNTV9ydF9vY2lfb2NkLnJkcyIpDQpsb2FkKGZpbGUgPSAiLi9zYXZlZF9vYmplY3RzX2Zvcl9wbG90cy9kZl9jb3JyLlJkYSIpDQoNCg0KIyBDcmVhdGUgcGxvdCBvZiBlc3RpbWF0ZWQgaW50ZXJhY3Rpb24gZWZmZWN0cw0KcGxvdF9vY2lfMSA8LSBwbG90X21vZGVsKExNTV9ydF9vY2lfb2NkLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgICA9ICJwcmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyAgPSBjKCJvY2lfY2VudGVyZWQiLCAicG9zX25lZyIsICJGQV9GSCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNpLmx2bCA9IC45NSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAiZXhwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lLnNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSBOVUxMLCB5ID0gIldvcmQgQ2F0ZWdvcml6YXRpb24gUlQgKG1zKSIsIHggPSAiT0NJLVIgU2NvcmUgKEdyb3VwLU1lYW4tQ2VudGVyZWQpIikgKw0KICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoNTAwLCA5MDApLCB4bGltID0gYygtMTMsIDIwKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDUwMCwgOTAwLCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDIwLCA1KSwgZXhwYW5kID0gYygwLCAwKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJXb3JkIFZhbGVuY2U6IiwgdmFsdWVzID0gY29sb3JzLCBsYWJlbHMgPSBjKCJOZWdhdGl2ZSIsICJQb3NpdGl2ZSIpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgID0gIldvcmQgVmFsZW5jZToiLCB2YWx1ZXMgPSBjb2xvcnMsIGxhYmVscyA9IGMoIk5lZ2F0aXZlIiwgIlBvc2l0aXZlIikpICsNCiAgbXlfZmlndXJlX3RoZW1lICsNCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksIGF4aXMudGlja3MueCA9IE5VTEwpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChjb2xvciA9IGNvbG9ycywgc2l6ZSA9IDAuNjUpKSkNCg0KDQojIENoYW5nZSBmYWNldCBsYWJlbHMNCnBsb3Rfb2NpXzEkZGF0YSRmYWNldCA8LSBpZmVsc2UocGxvdF9vY2lfMSRkYXRhJGZhY2V0ID09ICJGQV9GSCA9IC0wLjUiLCAiRmFzdCBIaXRzIiwgIkZhbHNlIEFsYXJtcyIpDQoNCg0KIyBDcmVhdGUgc2NhdHRlcnBsb3QNCnBsb3Rfb2NpXzIgPC0gZ2dwbG90KGRhdGEgPSBkZl9jb3JyW2RmX2NvcnIkZ3JvdXAgPT0gIk9DRCIsIF0sIGFlcyh4ID0gb2NpLCB5ID0gcHJpbWluZywgZmlsbCA9IGdyb3VwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gIiMwMDMxOTIiLCBzaXplID0gMSkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBjb2xvciA9ICIjMDAzMTkyIikgKw0KICBsYWJzKHRpdGxlID0gTlVMTCwgeCA9ICJPQ0ktUiBTY29yZSIsIHkgPSAiT3ZlcmFsbCBQcmltaW5nIEVmZmVjdCAobXMpIikgKw0KICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTE1MCwgNDAwKSwgeGxpbSA9IGMoMTIuOSwgNDUuNSkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTUwLCA0MDAsIDUwKSwgZXhwYW5kID0gYygwLCAwKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDE1LCA0NSwgNSksIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gIiMwMDMxOTIiKSArDQogIG15X2ZpZ3VyZV90aGVtZSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50aWNrcy54ID0gTlVMTCkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSA0NSwgeSA9IC0xMjAsIGxhYmVsID0gcGFzdGUoImxpc3QoaXRhbGljKHIpKDI2KSA9PSIsIC0uNDEsICIsIGl0YWxpYyhwKSA9PSAuMDI5KSIpLA0KICAgIHBhcnNlID0gVFJVRSwgaGp1c3QgPSAxLCBzaXplID0gMywgY29sb3IgPSAiZ3JheTIwIikNCg0KDQojIEFycmFuZ2UgcGxvdHMNCmZpZ3VyZV9vY2kgPC0gZ2dkcmF3KCkgKw0KICBkcmF3X3Bsb3QocGxvdF9vY2lfMSwgeCA9IC4wMCwgeSA9IC4wMDAsIHdpZHRoID0gLjYwLCBoZWlnaHQgPSAxKSArDQogIGRyYXdfcGxvdChwbG90X29jaV8yLCB4ID0gLjYxLCB5ID0gLjExNSwgd2lkdGggPSAuMzksIGhlaWdodCA9IC44MykgKw0KICBkcmF3X3Bsb3RfbGFiZWwoYygiQSIsICJCIiksIGMoMCwgLjYxKSwgYygxLCAxKSwgc2l6ZSA9IDE1KQ0KZmlndXJlX29jaQ0KDQoNCiMgU2F2ZSBwbG90DQpnZ3NhdmUocGxvdCA9IGZpZ3VyZV9vY2ksICIuL2ZpZ3VyZXMvZmlndXJlXzUudGlmZiIsIHdpZHRoID0gMjAsIGhlaWdodCA9IDEyLA0KICB1bml0cyA9ICJjbSIsIGRwaSA9IDYwMCwgY29tcHJlc3Npb24gPSAibHp3IikNCmBgYA0KPGJyPjxicj4NCg0KIyMjIFRyYWl0IEFueGlldHkgKFNUQUkpDQo8YnI+DQpUaGlzIGZpZ3VyZSBjb3JyZXNwb25kcyB0byBGaWd1cmUgUzEgaW4gdGhlIHN1cHBsZW1lbnRhbCBtYXRlcmlhbC4NCg0KYGBge3IgY3JlYXRlLXBsb3Qtc3RhaSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDUsIGRwaSA9IDYwMCwgZmlnLmNhcCA9ICI8YnI+IE5vdGUuIChBKSBNb2RlbC1wcmVkaWN0ZWQgaW50ZXJhY3Rpb24gZWZmZWN0IGJldHdlZW4gU3RhdGUtVHJhaXQgQW54aWV0eSBJbnZlbnRvcnkgKFNUQUkpIHRyYWl0IHNjb3JlLCBwcmVjZWRpbmcgcmVzcG9uc2UgdHlwZSAoZmFzdCBoaXQsIGZhbHNlIGFsYXJtKSBpbiB0aGUgZ28vbm8tZ28gdGFzaywgYW5kIHdvcmQgdmFsZW5jZSBvbiB3b3JkIGNhdGVnb3JpemF0aW9uIHJlc3BvbnNlIHRpbWUgKFJUKSBpbiBwYXRpZW50cyB3aXRoIE9DRCwgY29tcHV0ZWQgYXMgcGFydGlhbCBlZmZlY3RzIGZyb20gdGhlIGxpbmVhciBtaXhlZCBtb2RlbC4gUlQgZGF0YSB3ZXJlIGxvZy10cmFuc2Zvcm1lZCBmb3IgYW5hbHlzaXMgYnV0IHdlcmUgYmFjay10cmFuc2Zvcm1lZCB0byBtcyBmb3IgZGF0YSB2aXN1YWxpemF0aW9uLiAoQikgTmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgU1RBSSB0cmFpdCBzY29yZSBhbmQgdGhlIG92ZXJhbGwgcHJpbWluZyBlZmZlY3QgYWNyb3NzIHBhcnRpY2lwYW50cy4gVGhlIG92ZXJhbGwgcHJpbWluZyBlZmZlY3QgcmVmZXJzIHRvIHRoZSBwcmltaW5nIGVmZmVjdCBhZnRlciBmYWxzZSBhbGFybXMgYW5kIGZhc3QgaGl0cyBhbmQgd2FzIGNhbGN1bGF0ZWQgYnkgc3VidHJhY3RpbmcgdGhlIFJUIGluIGNvbmdydWVudCBjb25kaXRpb25zIChwb3NpdGl2ZSB3b3JkcyBhZnRlciBmYXN0IGhpdHMgYW5kIG5lZ2F0aXZlIHdvcmRzIGFmdGVyIGZhbHNlIGFsYXJtcykgZnJvbSB0aGUgUlQgaW4gaW5jb25ncnVlbnQgY29uZGl0aW9ucyAocG9zaXRpdmUgd29yZHMgYWZ0ZXIgZmFsc2UgYWxhcm1zIGFuZCBuZWdhdGl2ZSB3b3JkcyBhZnRlciBmYXN0IGhpdHMpIGZvciBlYWNoIHBhcnRpY2lwYW50IChBYXJ0cyBldCBhbC4sIDIwMTIpLiAoQeKAk0IpIFNoYWRlZCBiYW5kcyByZXByZXNlbnQgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiJ9DQoNCiMgTG9hZCBMTU0gb3V0cHV0DQpMTU1fcnRfc3RhaV9vY2QgPC0gcmVhZFJEUyhmaWxlID0gIi4vc2F2ZWRfb2JqZWN0c19mb3JfcGxvdHMvTE1NX3J0X3N0YWlfb2NkLnJkcyIpDQoNCg0KIyBDcmVhdGUgcGxvdCBvZiBlc3RpbWF0ZWQgaW50ZXJhY3Rpb24gZWZmZWN0cw0KcGxvdF9zdGFpXzEgPC0gcGxvdF9tb2RlbChMTU1fcnRfc3RhaV9vY2QsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgICA9ICJwcmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgID0gYygic3RhaV9jZW50ZXJlZCIsICJwb3NfbmVnIiwgIkZBX0ZIIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIGNpLmx2bCA9IC45NSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImV4cCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuc2l6ZSA9IDEpICsNCiAgbGFicyh0aXRsZSA9IE5VTEwsIHkgPSAiV29yZCBDYXRlZ29yaXphdGlvbiBSVCAobXMpIiwgeCA9ICJTVEFJIFRyYWl0IFNjb3JlIChHcm91cC1NZWFuLUNlbnRlcmVkKSIpICsNCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDQ1MCwgOTAwKSwgeGxpbSA9IGMoLTE4LCAyNSkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSg0NTAsIDkwMCwgNTApLCBleHBhbmQgPSBjKDAsIDApKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoLTE1LCAyNSwgNSksIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiV29yZCBWYWxlbmNlOiIsIHZhbHVlcyA9IGNvbG9ycywgbGFiZWxzID0gYygiTmVnYXRpdmUiLCAiUG9zaXRpdmUiKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbChuYW1lICA9ICJXb3JkIFZhbGVuY2U6IiwgdmFsdWVzID0gY29sb3JzLCBsYWJlbHMgPSBjKCJOZWdhdGl2ZSIsICJQb3NpdGl2ZSIpKSArDQogIG15X2ZpZ3VyZV90aGVtZSArDQogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLCBheGlzLnRpY2tzLnggPSBOVUxMKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoY29sb3IgPSBjb2xvcnMsIHNpemUgPSAwLjY1KSkpDQoNCg0KIyBDaGFuZ2UgZmFjZXQgbGFiZWxzDQpwbG90X3N0YWlfMSRkYXRhJGZhY2V0IDwtIGlmZWxzZShwbG90X3N0YWlfMSRkYXRhJGZhY2V0ID09ICJGQV9GSCA9IC0wLjUiLCAiRmFzdCBIaXRzIiwgIkZhbHNlIEFsYXJtcyIpDQoNCg0KIyBDcmVhdGUgc2NhdHRlcnBsb3QNCnBsb3Rfc3RhaV8yIDwtIGdncGxvdChkYXRhID0gZGZfY29ycltkZl9jb3JyJGdyb3VwID09ICJPQ0QiLCBdLCBhZXMoeCA9IHN0YWksIHkgPSBwcmltaW5nLCBmaWxsID0gZ3JvdXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAiIzAwMzE5MiIsIHNpemUgPSAxKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGNvbG9yID0gIiMwMDMxOTIiKSArDQogIGxhYnModGl0bGUgPSBOVUxMLCB4ID0gIlNUQUkgVHJhaXQgU2NvcmUiLCB5ID0gIk92ZXJhbGwgUHJpbWluZyBFZmZlY3QgKG1zKSIpICsNCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0xNTAsIDQwMCksIHhsaW0gPSBjKDM1LjgsIDgwKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC0xNTAsIDQwMCwgNTApLCBleHBhbmQgPSBjKDAsIDApKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoNDAsIDgwLCAxMCksIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gIiMwMDMxOTIiKSArDQogIG15X2ZpZ3VyZV90aGVtZSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50aWNrcy54ID0gTlVMTCkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSA4MCwgeSA9IC0xMTUsIGxhYmVsID0gcGFzdGUoImxpc3QoaXRhbGljKHIpKDI2KSA9PSIsIC0uMzQsICIsIGl0YWxpYyhwKSA9PSAuMDc4KSIpLA0KICAgIHBhcnNlID0gVFJVRSwgaGp1c3QgPSAxLCBzaXplID0gMywgY29sb3IgPSAiZ3JheTIwIikNCg0KDQojIEFycmFuZ2UgcGxvdHMNCmZpZ3VyZV9zdGFpIDwtIGdnZHJhdygpICsNCiAgZHJhd19wbG90KHBsb3Rfc3RhaV8xLCB4ID0gLjAwLCB5ID0gLjAwMCwgd2lkdGggPSAuNjAsIGhlaWdodCA9IDEpICsNCiAgZHJhd19wbG90KHBsb3Rfc3RhaV8yLCB4ID0gLjYxLCB5ID0gLjExNSwgd2lkdGggPSAuMzksIGhlaWdodCA9IDAuODMpICsNCiAgZHJhd19wbG90X2xhYmVsKGMoIkEiLCAiQiIpLCBjKDAsIC42MSksIGMoMSwgMSksIHNpemUgPSAxNSkNCmZpZ3VyZV9zdGFpDQoNCg0KIyBTYXZlIHBsb3QNCmdnc2F2ZShwbG90ID0gZmlndXJlX3N0YWksICIuL2ZpZ3VyZXMvZmlndXJlX1MxLnRpZmYiLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMiwNCiAgdW5pdHMgPSAiY20iLCBkcGkgPSA2MDAsIGNvbXByZXNzaW9uID0gImx6dyIpDQpgYGANCjxicj48YnI+DQoNCiMjIFJlZmVyZW5jZXMNCioqKg0KQWFydHMsIEsuLCBEZSBIb3V3ZXIsIEouLCAmIFBvdXJ0b2lzLCBHLiAoMjAxMikuIEV2aWRlbmNlIGZvciB0aGUgYXV0b21hdGljIGV2YWx1YXRpb24gb2Ygc2VsZi1nZW5lcmF0ZWQgYWN0aW9ucy4gKkNvZ25pdGlvbiwgMTI0KigyKSwgMTE34oCTMTI3LiBodHRwczovL2RvaS5vcmcvMTAuMTAxNi9qLmNvZ25pdGlvbi4yMDEyLjA1LjAwOQ0KPGJyPjxicj48YnI+DQoNCiMjIFNlc3Npb24gSW5mbw0KKioqDQpgYGB7ciBzZXNzaW9uLWluZm99DQoNCnNlc3Npb25JbmZvKCkNCmBgYA0K