# 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
<br> Note. (A) Observed word categorization RT per preceding response type in the go/no-go task, word valence, and group. (B) Observed word categorization accuracy per preceding response type in the go/no-go task, word valence, and group. (A–B) The plots show individual data points, boxplots, and probability density plots based on raw data that were aggregated by participant. Asterisks indicate significant differences yielded by the (generalized) linear mixed model analysis. * p < .05, ** p < .01, *** p < .001.


Note. (A) Observed word categorization RT per preceding response type in the go/no-go task, word valence, and group. (B) Observed word categorization accuracy per preceding response type in the go/no-go task, word valence, and group. (A–B) The plots show individual data points, boxplots, and probability density plots based on raw data that were aggregated by participant. Asterisks indicate significant differences yielded by the (generalized) linear mixed model analysis. * p < .05, ** p < .01, *** p < .001.

# 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
<br> Note. (A) Model-predicted mean word categorization RT per preceding response type (fast hit, false alarm) in the go/no-go task, word valence, and group, computed as partial effects from the linear mixed model (LMM). RT data were log-transformed for analysis but back-transformed to ms for visualization. (B) Model-predicted mean word categorization accuracy per preceding response type (fast hit, false alarm) in the go/no-go task, word valence, and group, computed as partial effects from the generalized linear mixed model (GLMM). (A–B) Error bars indicate 95% confidence intervals. Asterisks indicate significant differences yielded by the (G)LMM analysis. * p < .05, ** p < .01, *** p < .001.


Note. (A) Model-predicted mean word categorization RT per preceding response type (fast hit, false alarm) in the go/no-go task, word valence, and group, computed as partial effects from the linear mixed model (LMM). RT data were log-transformed for analysis but back-transformed to ms for visualization. (B) Model-predicted mean word categorization accuracy per preceding response type (fast hit, false alarm) in the go/no-go task, word valence, and group, computed as partial effects from the generalized linear mixed model (GLMM). (A–B) Error bars indicate 95% confidence intervals. Asterisks indicate significant differences yielded by the (G)LMM analysis. * p < .05, ** p < .01, *** p < .001.

# 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
Note. (A) Grand average response-locked waveforms at electrode site FCz with 95% confidence intervals in patients with OCD and HC participants for correct (hit) and incorrect (false alarm) responses in the go/no-go task. The gray shaded time interval was used to quantify ERN and CRN amplitude. (B) Scalp topographies of ERN and CRN in both groups in the time window 0–100 ms after false alarms or hits, respectively.

Note. (A) Grand average response-locked waveforms at electrode site FCz with 95% confidence intervals in patients with OCD and HC participants for correct (hit) and incorrect (false alarm) responses in the go/no-go task. The gray shaded time interval was used to quantify ERN and CRN amplitude. (B) Scalp topographies of ERN and CRN in both groups in the time window 0–100 ms after false alarms or hits, respectively.

# 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
<br> Note. (A) Model-predicted interaction effect between Obsessive-Compulsive Inventory-Revised (OCI-R) score, preceding response type (fast hit, false alarm) in the go/no-go task, and word valence on word categorization response time (RT) in patients with OCD, computed as partial effects from the linear mixed model. RT data were log-transformed for analysis but were back-transformed to ms for data visualization. (B) Negative correlation between the OCI-R score and the overall priming effect across participants. The overall priming effect refers to the priming effect after false alarms and fast hits and was calculated by subtracting the RT in congruent conditions (positive words after fast hits and negative words after false alarms) from the RT in incongruent conditions (positive words after false alarms and negative words after fast hits) for each participant (Aarts et al., 2012). (A–B) Shaded bands represent 95% confidence intervals.


Note. (A) Model-predicted interaction effect between Obsessive-Compulsive Inventory-Revised (OCI-R) score, preceding response type (fast hit, false alarm) in the go/no-go task, and word valence on word categorization response time (RT) in patients with OCD, computed as partial effects from the linear mixed model. RT data were log-transformed for analysis but were back-transformed to ms for data visualization. (B) Negative correlation between the OCI-R score and the overall priming effect across participants. The overall priming effect refers to the priming effect after false alarms and fast hits and was calculated by subtracting the RT in congruent conditions (positive words after fast hits and negative words after false alarms) from the RT in incongruent conditions (positive words after false alarms and negative words after fast hits) for each participant (Aarts et al., 2012). (A–B) Shaded bands represent 95% confidence intervals.

# 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
<br> Note. (A) Model-predicted interaction effect between State-Trait Anxiety Inventory (STAI) trait score, preceding response type (fast hit, false alarm) in the go/no-go task, and word valence on word categorization response time (RT) in patients with OCD, computed as partial effects from the linear mixed model. RT data were log-transformed for analysis but were back-transformed to ms for data visualization. (B) Negative correlation between the STAI trait score and the overall priming effect across participants. The overall priming effect refers to the priming effect after false alarms and fast hits and was calculated by subtracting the RT in congruent conditions (positive words after fast hits and negative words after false alarms) from the RT in incongruent conditions (positive words after false alarms and negative words after fast hits) for each participant (Aarts et al., 2012). (A–B) Shaded bands represent 95% confidence intervals.


Note. (A) Model-predicted interaction effect between State-Trait Anxiety Inventory (STAI) trait score, preceding response type (fast hit, false alarm) in the go/no-go task, and word valence on word categorization response time (RT) in patients with OCD, computed as partial effects from the linear mixed model. RT data were log-transformed for analysis but were back-transformed to ms for data visualization. (B) Negative correlation between the STAI trait score and the overall priming effect across participants. The overall priming effect refers to the priming effect after false alarms and fast hits and was calculated by subtracting the RT in congruent conditions (positive words after fast hits and negative words after false alarms) from the RT in incongruent conditions (positive words after false alarms and negative words after fast hits) for each participant (Aarts et al., 2012). (A–B) Shaded bands represent 95% confidence intervals.

# Save plot
ggsave(plot = figure_stai, "./figures/figure_S1.tiff", width = 20, height = 12,
  units = "cm", dpi = 600, compression = "lzw")



References


Aarts, K., De Houwer, J., & Pourtois, G. (2012). Evidence for the automatic evaluation of self-generated actions. Cognition, 124(2), 117–127. https://doi.org/10.1016/j.cognition.2012.05.009


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