Data Cleaning


# Load data
load(file = "./data/Single_Trial_Data.rda")


# Exclude missing responses, RT outliers, and trials with ERP artifacts
single_trial_data_clean <- single_trial_data %>%
  dplyr::filter(
      response_type != "miss" &
      rt_invalid    == FALSE &
      !is.na(MFN_0_100_FCz)
  ) # (53093 of 53760 trials left)


# Create medication variable (needed as covariate later)
single_trial_data_clean <- single_trial_data_clean %>%
  dplyr::mutate(
    medication = as.factor(ifelse(
      participant_id == "P_02" | participant_id == "P_04" |
      participant_id == "P_05" | participant_id == "P_06" |
      participant_id == "P_08" | participant_id == "P_10" |
      participant_id == "P_15" | participant_id == "P_16" |
      participant_id == "P_18" | participant_id == "P_22" |
      participant_id == "P_25" | participant_id == "P_26" |
      participant_id == "P_28" | participant_id == "P_30", "yes", "no")),
    group_medication = as.factor(ifelse((group == "HC"), "HC",
      ifelse((group == "OCD" & medication == "no"), "OCD_no_med", "OCD_med")))
    )


# Create within-participant standardized P300 variable (needed as covariate later)
single_trial_data_clean <- single_trial_data_clean %>%
  dplyr::group_by(participant_id, session) %>%
  dplyr::mutate(P3_300_500_CPz_standardized = scale(P3_300_500_CPz, center = TRUE, scale = TRUE))  %>%
  dplyr::ungroup()


# Make categorical variables factors
single_trial_data_clean$participant_id   <- factor(single_trial_data_clean$participant_id)
single_trial_data_clean$group            <- factor(single_trial_data_clean$group)
single_trial_data_clean$stimulation      <- factor(single_trial_data_clean$stimulation)
single_trial_data_clean$response_type    <- factor(single_trial_data_clean$response_type)
single_trial_data_clean$group_medication <- factor(single_trial_data_clean$group_medication, 
                                                   levels = c("HC", "OCD_no_med", "OCD_med"))

Trials with a response time below 100 ms or above 800 ms or with a missing response were excluded from all analyses. We further discarded trials containing artifacts in the EEG, that is, a voltage change exceeding 50 μV between sample points or 200 μV within an epoch.

# Calculate percentage of excluded trials per participant
excluded_trials_per_participant <- single_trial_data %>%
  dplyr::group_by(group, participant_id, session) %>%
  dplyr::summarize(
    invalid_rt   = sum(!is.na(rt_invalid) & rt_invalid != FALSE) / length(participant_id) * 100,
    misses       = sum(response_type == "miss") / length(participant_id) * 100,
    EEG_artifact = sum(is.nan(MFN_0_100_FCz))   / length(participant_id) * 100 
  ) %>%
  dplyr::ungroup()


# Summarize percentage of excluded trials per participant over groups
excluded_trials_per_participant_over_groups <- excluded_trials_per_participant %>%
  dplyr::summarize(across(-c(group, participant_id, session), list(mean, sd, min, max)))


# Summarize percentage of excluded trials per participant per group
excluded_trials_per_participant_per_group <- excluded_trials_per_participant %>%
  dplyr::group_by(group) %>%
  dplyr::summarize(across(-c(participant_id, session), list(mean, sd, min, max))) %>%
  dplyr::ungroup()


# Combine groups and total sample
excluded_trials <- rbind(excluded_trials_per_participant_per_group, 
                         cbind(group = "Overall", excluded_trials_per_participant_over_groups))


# Display percentage of excluded trials per participant
my_table_template(excluded_trials,
  caption = "Excluded Trials per Participant (in %)",
  col_names = c(" ", rep(c("M", "SD", "min", "max"), 3)),
  header_above_config = c(" " = 1, "RT < 100 / > 800 ms" = 4, "Misses" = 4, "EEG artifact" = 4)
)
Excluded Trials per Participant (in %)
RT < 100 / > 800 ms
Misses
EEG artifact
M SD min max M SD min max M SD min max
HC 0.03 0.10 0 0.42 0.66 1.09 0 5.00 0.30 0.51 0 2.08
OCD 0.04 0.11 0 0.62 0.61 0.76 0 2.71 0.84 1.20 0 5.42
Overall 0.04 0.10 0 0.62 0.64 0.93 0 5.00 0.57 0.96 0 5.42



Descriptive Statistics


This table corresponds to Table 2 in the manuscript.

# Calculate descriptive statistics for ERN/CRN
descriptive_statistics_MFN <- summarySEwithinO(
  data          = single_trial_data_clean,
  measurevar    = "MFN_0_100_FCz",
  withinvars    = c("response_type", "stimulation"),
  betweenvars   = "group",
  idvar         = "participant_id",
  conf.interval = .95
) %>% dplyr::rename(M = MFN_0_100_FCz, M_norm = MFN_0_100_FCz_norm) %>%
  dplyr::arrange(desc(response_type)) %>%
  dplyr::select(-response_type)


# Calculate descriptive statistics for Pe
descriptive_statistics_Pe <- summarySEwithinO(
  data          = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
  measurevar    = "Pe_200_400_Pz",
  withinvars    = "stimulation",
  betweenvars   = "group",
  idvar         = "participant_id",
  conf.interval = .95
) %>% dplyr::rename(M = Pe_200_400_Pz, M_norm = Pe_200_400_Pz_norm)



# Combine measures
descriptive_statistics <- as.data.frame(rbind(descriptive_statistics_MFN, descriptive_statistics_Pe))



# Label measures
descriptive_statistics$Measure <- c(rep("ERN (µV)", 4), rep("CRN (µV)", 4), rep("Pe (µV)", 4))


# Create column with format "M [CI]" (round to 2 decimals)
descriptive_statistics$M_CI <- paste0(
  format(round(descriptive_statistics$M,  2), nsmall = 2), " [",
  format(round(descriptive_statistics$M -
               descriptive_statistics$ci, 2), nsmall = 2), ", ",
  format(round(descriptive_statistics$M +
               descriptive_statistics$ci, 2), nsmall = 2), "]")



# Select relevant columns
descriptive_statistics <- descriptive_statistics[, c ("group", "stimulation", "Measure", "M_CI")]



# Split and re-merge table to display both groups next to each other
descriptive_statistics <- split(descriptive_statistics, list(descriptive_statistics$stimulation,
                                                             descriptive_statistics$group))
descriptive_statistics_display <- cbind(
  descriptive_statistics$sham.OCD[, c("Measure", "M_CI")],
  descriptive_statistics$sham.HC[, "M_CI"],
  descriptive_statistics$verum.OCD[, "M_CI"],
  descriptive_statistics$verum.HC[, "M_CI"]
)


# Display table
my_table_template(descriptive_statistics_display,
  caption = "ERP Measures in Patients With OCD and HC Participants",
  col_names = c(" ", rep("M [95% CI]", 4)),
  header_above_config = c(" ", rep(c("Patients with OCD", "HC participants"), 2)),
  footnote_config = c(general = "CIs are adjusted for within-participant designs (Morey, 2008).
  ERN = error-related negativity; CRN = correct-response negativity; Pe = error positivity.")) %>%
  add_header_above(c(" " = 1, "Sham tDCS" = 2, "Cathodal tDCS" = 2))
ERP Measures in Patients With OCD and HC Participants
Sham tDCS
Cathodal tDCS
Patients with OCD
HC participants
Patients with OCD
HC participants
M [95% CI] M [95% CI] M [95% CI] M [95% CI]
ERN (µV) -3.81 [-4.69, -2.93] -1.33 [-2.17, -0.49] -3.57 [-4.44, -2.70] -0.22 [-1.09, 0.65]
CRN (µV) 4.37 [ 4.18, 4.56] 7.03 [ 6.84, 7.23] 5.49 [ 5.30, 5.69] 7.17 [ 6.96, 7.37]
Pe (µV) 8.64 [ 7.76, 9.51] 8.02 [ 7.29, 8.75] 9.60 [ 8.81, 10.40] 8.92 [ 8.16, 9.67]
Note:
CIs are adjusted for within-participant designs (Morey, 2008).
ERN = error-related negativity; CRN = correct-response negativity; Pe = error positivity.



Split-Half Reliability


# Calculate permutation-based split-half internal consistency for ERN/CRN
invisible(capture.output(split_half_reliability_MFN <- splithalf(
  data = single_trial_data_clean,
  outcome = "RT",
  score = "average",
  permutations = 5000,
  halftype = "random",
  var.RT = "MFN_0_100_FCz",
  var.trialnum = "trial",
  var.participant = "participant_id",
  var.condition = "response_type",
  conditionlist = c("correct", "incorrect"),
  average = "mean")))


# Calculate permutation-based split-half internal consistency for Pe
invisible(capture.output(split_half_reliability_Pe <- splithalf(
  data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
  outcome = "RT",
  score = "average",
  permutations = 5000,
  halftype = "random",
  var.RT = "Pe_200_400_Pz",
  var.trialnum = "trial",
  var.participant = "participant_id",
  average = "mean")))


# Combine ERPs
split_half_reliability <- cbind(ERP = c("CRN", "ERN", "Pe"), 
                                rbind(split_half_reliability_MFN$final_estimates, 
                                      split_half_reliability_Pe$final_estimates)) %>%
  dplyr::select(ERP, spearmanbrown, SB_low, SB_high) %>%
  dplyr::rename(
    r      = spearmanbrown,
    CI_low = SB_low,
    CI_up  = SB_high
    )


# Display permutation-based split-half internal consistency
my_table_template(split_half_reliability[c(2,1,3), ], 
                  caption = "Permutation-based split-half reliability")
Permutation-based split-half reliability
ERP r CI_low CI_up
ERN 0.95 0.93 0.97
CRN 1.00 0.99 1.00
Pe 0.94 0.91 0.96

We examined the internal consistency of the ERPs using a permutation-based split-half approach with 5,000 random splits and Spearman–Brown correction. Results indicated excellent internal consistency for ERN (r = .95, 95% CI [.93, .97]), CRN (r = 1.00, 95% CI [.99, 1.00]), and Pe (r = .94, 95% CI [.91, .96]).


LMM Analyses


We analyzed ERP measures (ERN, CRN, Pe) using linear mixed models (LMMs) on single-trial data. We tested whether group differences and tDCS effects were present. Group (healthy controls, OCD) and tDCS condition (cathodal, sham) were included as fixed effects in all models. All categorical fixed effects were effect-coded (contrast coefficients −0.5 and 0.5).

We determined the random-effects structure for each model based on the procedure proposed by Bates et al. (2015), starting with the maximal random-effects structure justified by the design, with by-participant random intercepts and random slopes for all fixed factors and (where applicable) their interactions. If required for model convergence, correlation parameters of the random terms were set to zero. Random effects preventing model convergence or explaining zero variance as determined by principal component analysis were removed to avoid overparameterization.

In these analyses, model estimates directly reflect mean differences in microvolts. Note that for negative components, such as the ERN and CRN, negative estimates indicate an increase in amplitude, whereas positive estimates indicate a decrease.

# Define contrasts (sliding difference contrasts = effect coding for factors with 2 levels)
contrasts(single_trial_data_clean$stimulation)      <- contr.sdif(2)
contrasts(single_trial_data_clean$group)            <- contr.sdif(2)
contrasts(single_trial_data_clean$response_type)    <- contr.sdif(2)
contrasts(single_trial_data_clean$group_medication) <- contr.sdif(3)


# Prepare labels for LMM tables
labels <- c(
  "(Intercept)"                               = "Intercept",
  "stimulation2-1"                            = "Stimulation",
  "group2-1"                                  = "Group",
  "response_type2-1"                          = "Response type",
  "stimulation2-1:group2-1"                   = "Stimulation x Group",
  "stimulation2-1:response_type2-1"           = "Stimulation x Response type",
  "group2-1:response_type2-1"                 = "Group x Response type",
  "stimulation2-1:group2-1:response_type2-1"  = "Stimulation x Group x Response type",
  "group_medication2-1"                       = "OCDno med - HC",
  "group_medication3-2"                       = "OCDmed - OCDno med",
  "stimulation2-1:group_medication2-1"        = "Stimulation x OCDno med - HC",
  "stimulation2-1:group_medication3-2"        = "Stimulation x OCDmed - OCDno med",
  "P3_300_500_CPz_standardized"               = "P300",
  "stimulation2-1:P3_300_500_CPz_standardized"= "Stimulation x P300",
  "group2-1:P3_300_500_CPz_standardized"      = "Group x P300",
  "stimulation2-1:group2-1:P3_300_500_CPz_standardized" = "Stimulation x Group x P300"
)



ERN

Determine data transformation

No data transformation was required to meet the assumption of normally distributed residuals. This was determined using the Box–Cox procedure (Box & Cox, 1964).

# Arrange plots
par(mfrow = c(1, 3))


# Determine transformation by estimating optimal lambda using Box–Cox procedure
bc_ERN <- boxcox(MFN_0_100_FCz + 100 ~ 1, 
                 data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ])
optlambda_ERN <- bc_ERN$x[which.max(bc_ERN$y)]


# Density plot for ERN values
plot(density(single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ]$MFN_0_100_FCz), 
     main = "ERN: Density  Plot")


# Q-q plot for ERN values
qqnorm(single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ]$MFN_0_100_FCz, 
       main = "ERN: Q-Q Plot", pch = 1)

# Reset plot layout
par(mfrow = c(1, 1))

The optimal lambda is 1.23, suggesting that no transformation is needed.


LMM

Including only error trials in the analysis, we fitted a LMM with ERN amplitude as dependent variable. In accordance with the preregistratration, separate models for ERN and CRN were specified in addition to the overall model for the response-related negativity to allow comparison with previously reported results on these ERPs.

This table corresponds to Table 3 in the manuscript.

# Run model
LMM_ERN <- lmer(MFN_0_100_FCz ~ stimulation * group  +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


# Check model output and PCA of random-effects variance-covariance estimates
# summary(LMM_ERN)        # Model does converge
# isSingular(LMM_ERN)     # No singular fit
# summary(rePCA(LMM_ERN)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_ERN,
  dv.labels = "ERN", pred.labels = labels, show.stat = TRUE, show.icc = FALSE, show.r2 = FALSE,
  show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed effects", 
  string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMM Predicting ERN Amplitude as a Function of Stimulation Condition 
  (Cathodal - Sham) and Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(LMM_ERN), digits = 3, comp = "Std.Dev.")


# Save model output for plot
saveRDS(LMM_ERN, file = "./saved_objects_for_plots/LMM_ERN.rds")
Results of the LMM Predicting ERN Amplitude as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCD - Healthy Controls)
  ERN
Fixed effects b 95 % CI t p
Intercept -2.88 -4.60 – -1.16 -3.29 0.002
Stimulation 0.86 0.02 – 1.70 2.00 0.052
Group -3.14 -6.58 – 0.30 -1.79 0.079
Stimulation x Group -0.10 -1.78 – 1.59 -0.11 0.911
Observations 3244
[1] "Random effects:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    6.41          
                stimulation2-1 1.72     -0.10
 Residual                      9.93          



In the analysis of the ERN, the main effect of group did not reach statistical significance, but a trend for an enhanced ERN amplitude in patients with OCD relative to healthy control participants was observed. Moreover, there was a statistical trend toward a reduced ERN amplitude after cathodal tDCS relative to sham tDCS. No significant interaction between group and tDCS condition was found, indicating that there was no evidence that the effect of tDCS on ERN amplitude was larger in patients with OCD than in healthy participants.


Sham condition

# Run model
LMM_ERN_sham <- lmer(MFN_0_100_FCz ~ group  +  (1 | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect" & 
                                 single_trial_data_clean$stimulation == "sham", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


# Check model output and PCA of random-effects variance-covariance estimates
# summary(LMM_ERN_sham)        # Model does converge
# isSingular(LMM_ERN_sham)     # No singular fit
# summary(rePCA(LMM_ERN_sham)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_ERN_sham,
  dv.labels = "ERN sham", pred.labels = labels, show.stat = TRUE, show.icc = FALSE, show.r2 = FALSE,
  show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed effects", 
  string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMM Predicting ERN Amplitude in the Sham Condition as a Function of 
  Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(LMM_ERN_sham), digits = 3, comp = "Std.Dev.")
Results of the LMM Predicting ERN Amplitude in the Sham Condition as a Function of Group (OCD - Healthy Controls)
  ERN sham
Fixed effects b 95 % CI t p
Intercept -3.33 -5.13 – -1.53 -3.63 0.001
Group -3.22 -6.82 – 0.38 -1.76 0.085
Observations 1605
[1] "Random effects:"
 Groups         Name        Std.Dev.
 participant_id (Intercept) 6.59    
 Residual                   9.57    



The analysis evaluating group differences solely in the baseline ERN (i.e., in the sham condition) yielded the same pattern of results regarding the trend for an enhanced ERN amplitude in patients with OCD relative to healthy control participants.


Equivalence test: ERN

Since the tDCS-induced ERN reduction emerged only as a statistical trend in the main analysis, we further examined this effect using the two one-sided tests procedure for equivalence testing in a non-preregistered post hoc analysis. We defined the smallest effect size of interest (SESOI) as the effect size that the study by Reinhart and Woodman (2014) had 33% power to detect. On the basis of this approach, we set the SESOI for equivalence bounds to Cohen’s dz = 0.38, which corresponds to an ERN amplitude difference of 1.34 µV between cathodal and sham tDCS.

# Equivalence bounds (refers to difference in raw values of 1.34 microvolt)
bound_l <- -1.34 # lower equivalence bound
bound_u <-  1.34 # upper equivalence bound


# Use  contest1D function of the lmerTest package to perform tests centered on the lower and upper bound
lower <- contest1D(LMM_ERN, c(0, 1, 0, 0), confint = TRUE, rhs = bound_l) # test against lower bound
upper <- contest1D(LMM_ERN, c(0, 1, 0, 0), confint = TRUE, rhs = bound_u) # test against upper bound
# Note: c(0,1,0,0) refers to stimulation effect (= second fixed effect), as can be seen with fixef(LMM_ERN)


# Recalculate the required one-sided tests from the t-values (test provided by contest1D is two-sided)
p_lower <- pt(lower$`t value`, lower$df, lower.tail = FALSE) # test against lower bound
p_upper <- pt(upper$`t value`, upper$df, lower.tail = TRUE) # test against upper bound

Test against lower bound: t(44.18) = 5.12, p <0.001
Test against upper bound: t(44.18) = -1.12, p = 0.134

The equivalence test was not significant, t(44.18) = -1.12, p = 0.134, indicating that the ERN amplitude in the cathodal tDCS condition was not statistically equivalent to that in the sham condition. Thus, we cannot reject the presence of an effect as large or larger than 1.34 µV. Taken together, based on results from null hypothesis testing and equivalence testing, we can neither reliably conclude that the effect of cathodal tDCS on ERN amplitude is different from zero (no statistical significance, only a statistical trend), nor that an effect that can be considered meaningful is absent (no statistical equivalence).


CRN

Determine data transformation

No data transformation was required to meet the assumption of normally distributed residuals. This was determined using the Box–Cox procedure (Box & Cox, 1964).

# Arrange plots
par(mfrow = c(1, 3))


# Determine transformation by estimating optimal lambda using Box–Cox procedure
bc_CRN <- boxcox(MFN_0_100_FCz + 100 ~ 1, 
                 data = single_trial_data_clean[single_trial_data_clean$response_type == "correct", ])
optlambda_CRN <- bc_CRN$x[which.max(bc_CRN$y)]


# Density plot for CRN values
plot(density(single_trial_data_clean[single_trial_data_clean$response_type == "correct", ]$MFN_0_100_FCz), 
     main = "CRN: Density  Plot")


# Q-q plot for CRN values
qqnorm(single_trial_data_clean[single_trial_data_clean$response_type == "correct", ]$MFN_0_100_FCz, 
       main = "CRN: Q-Q Plot", pch = 1)

# Reset plot layout
par(mfrow = c(1, 1))

The optimal lambda is 0.95, suggesting that no transformation is needed.


LMM

Including only trials with correct response in the analysis, we fitted a LMM with CRN amplitude as dependent variable. In accordance with the preregistratration, separate models for ERN and CRN were specified in addition to the overall model for the response-related negativity to allow comparison with previously reported results on these ERPs.

This table corresponds to Table 3 in the manuscript.

# Run model
LMM_CRN <- lmer(MFN_0_100_FCz ~ stimulation * group  +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "correct", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


# Check model output and PCA of random-effects variance-covariance estimates
# summary(LMM_CRN)        # Model does converge
# isSingular(LMM_CRN)     # No singular fit
# summary(rePCA(LMM_CRN)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_CRN,
  dv.labels = "CRN", pred.labels = labels, show.stat = TRUE, show.icc = FALSE, show.r2 = FALSE,
  show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed effects", 
  string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMM Predicting CRN Amplitude as a Function of Stimulation Condition 
  (Cathodal - Sham) and Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(LMM_CRN), digits = 3, comp = "Std.Dev.")


# Save model output for plot
saveRDS(LMM_CRN, file = "./saved_objects_for_plots/LMM_CRN.rds")
Results of the LMM Predicting CRN Amplitude as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCD - Healthy Controls)
  CRN
Fixed effects b 95 % CI t p
Intercept 6.05 4.84 – 7.25 9.84 <0.001
Stimulation 0.65 0.06 – 1.24 2.18 0.034
Group -2.20 -4.61 – 0.21 -1.79 0.079
Stimulation x Group 0.96 -0.21 – 2.13 1.60 0.114
Observations 49849
[1] "Random effects:"
 Groups         Name           Std.Dev. Corr
 participant_id (Intercept)    4.59         
                stimulation2-1 2.14     0.04
 Residual                      9.58         



The LMM on the CRN yielded a trend for a main effect of group, such that patients with OCD showed an enhanced CRN amplitude compared to control participants. In addition, a significant main effect of tDCS condition revealed that the CRN amplitude was significantly smaller after cathodal tDCS relative to sham tDCS. There was no significant interaction between group and tDCS condition.


Sham condition

# Run model
LMM_CRN_sham <- lmer(MFN_0_100_FCz ~ group  +  (1 | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "correct" & 
                                 single_trial_data_clean$stimulation == "sham", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


# Check model output and PCA of random-effects variance-covariance estimates
# summary(LMM_CRN_sham)        # Model does converge
# isSingular(LMM_CRN_sham)     # No singular fit
# summary(rePCA(LMM_CRN_sham)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_CRN_sham,
  dv.labels = "CRN sham", pred.labels = labels, show.stat = TRUE, show.icc = FALSE, show.r2 = FALSE,
  show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed effects", 
  string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMM Predicting CRN Amplitude in the Sham Condition as a Function of 
  Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(LMM_CRN_sham), digits = 3, comp = "Std.Dev.")
Results of the LMM Predicting CRN Amplitude in the Sham Condition as a Function of Group (OCD - Healthy Controls)
  CRN sham
Fixed effects b 95 % CI t p
Intercept 5.72 4.49 – 6.95 9.13 <0.001
Group -2.68 -5.14 – -0.23 -2.14 0.037
Observations 24955
[1] "Random effects:"
 Groups         Name        Std.Dev.
 participant_id (Intercept) 4.67    
 Residual                   9.46    



When evaluating group differences solely in the baseline CRN (i.e., in the sham condition), patients with OCD showed an enhanced CRN amplitude compared to control participants.


Pe

Determine data transformation

No data transformation was required to meet the assumption of normally distributed residuals. This was determined using the Box–Cox procedure (Box & Cox, 1964).

# Arrange plots
par(mfrow = c(1, 3))


# Determine transformation by estimating optimal lambda using Box–Cox procedure
bc_Pe <- boxcox(Pe_200_400_Pz + 120 ~ 1, 
                data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ])
optlambda_Pe <- bc_Pe$x[which.max(bc_Pe$y)]


# Density plot for Pe values
plot(density(single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ]$Pe_200_400_Pz), 
     main = "Pe: Density  Plot")


# Q-q plot for Pe values
qqnorm(single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ]$Pe_200_400_Pz, 
       main = "Pe: Q-Q Plot", pch = 1)

# Reset plot layout
par(mfrow = c(1, 1))

The optimal lambda is 0.75, suggesting that no transformation is needed.


LMM

Including only error trials in the analysis, we fitted a LMM with Pe amplitude as dependent variable.

This table corresponds to Table 3 in the manuscript.

# Run model
LMM_Pe <- lmer(Pe_200_400_Pz ~ stimulation * group  +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


# Check model output and PCA of random-effects variance-covariance estimates
# summary(LMM_Pe)        # Model does converge
# isSingular(LMM_Pe)     # No singular fit
# summary(rePCA(LMM_Pe)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_Pe,
  dv.labels = "Pe", pred.labels = labels, show.stat = TRUE, show.icc = FALSE, show.r2 = FALSE,
  show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed effects", 
  string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMM Predicting Pe Amplitude as a Function of Stimulation Condition 
  (Cathodal - Sham) and Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(LMM_Pe), digits = 3, comp = "Std.Dev.")


# Save model output for plot
saveRDS(LMM_Pe, file = "./saved_objects_for_plots/LMM_Pe.rds")
Results of the LMM Predicting Pe Amplitude as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCD - Healthy Controls)
  Pe
Fixed effects b 95 % CI t p
Intercept 9.28 8.03 – 10.53 14.56 <0.001
Stimulation 0.94 0.22 – 1.65 2.57 0.013
Group 0.42 -2.08 – 2.91 0.33 0.745
Stimulation x Group 0.55 -0.87 – 1.98 0.76 0.451
Observations 3244
[1] "Random effects:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    4.63          
                stimulation2-1 1.59     -0.16
 Residual                      8.07          



Analysis of the Pe amplitude indicated that this component was increased after cathodal tDCS relative to sham tDCS, as evidenced by a significant main effect of tDCS condition. No significant main effect of group and no interaction between group and tDCS condition were observed.


Control Analyses


Medication

We performed additional control analyses to examine whether tDCS effects on ERPs were affected by psychotropic medication. In these analyses, we accounted for possible confounding effects of psychotropic medication by respecifying the fixed effect group as a factor with three levels (control participants, medicated patients with OCD, unmedicated patients with OCD), which was coded using sliding difference contrasts.

This table corresponds to Table S4 in the supplemental material.

# Rum model ERN
LMM_ERN_medication <- lmer(MFN_0_100_FCz ~ stimulation * group_medication +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
) # Convergence, singularity, PCA checked, all ok


# Rum model CRN
LMM_CRN_medication <- lmer(MFN_0_100_FCz ~ stimulation * group_medication +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "correct", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
) # Convergence, singularity, PCA checked, all ok


# Rum model Pe
LMM_Pe_medication <- lmer(Pe_200_400_Pz ~ stimulation * group_medication +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
) # Convergence, singularity, PCA checked, all ok


# Display results (fixed effects) in one table
tab_model(LMM_ERN_medication, LMM_CRN_medication, LMM_Pe_medication,
  dv.labels = c("ERN", "CRN", "Pe"), pred.labels = labels, show.stat = TRUE, show.icc = FALSE, 
  show.r2 = FALSE, show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed 
  effects", string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMMs Predicting ERN, CRN, and Pe Amplitude as a Function of Stimulation 
  Condition (Cathodal - Sham) and Group (OCDno med – HC; OCDmed - OCDno med) to Examine 
  Effects of Psychotropic Medication"
)


# Display random effects
print("Random effects ERN:")
print(VarCorr(LMM_ERN_medication), digits = 3, comp = "Std.Dev.")

print("Random effects CRN:")
print(VarCorr(LMM_CRN_medication), digits = 3, comp = "Std.Dev.")

print("Random effects Pe:")
print(VarCorr(LMM_Pe_medication), digits = 3, comp = "Std.Dev.")
Results of the LMMs Predicting ERN, CRN, and Pe Amplitude as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCDno med – HC; OCDmed - OCDno med) to Examine Effects of Psychotropic Medication
  ERN CRN Pe
Fixed effects b 95 % CI t p b 95 % CI t p b 95 % CI t p
Intercept -3.50 -5.29 – -1.71 -3.84 <0.001 5.65 4.37 – 6.93 8.66 <0.001 9.32 8.00 – 10.65 13.80 <0.001
Stimulation 0.86 -0.05 – 1.77 1.85 0.070 0.83 0.21 – 1.45 2.62 0.011 0.96 0.23 – 1.68 2.59 0.012
OCDno med - HC -1.26 -5.32 – 2.79 -0.61 0.544 -1.67 -4.57 – 1.23 -1.13 0.264 1.18 -1.82 – 4.18 0.77 0.446
OCDmed - OCDno med -4.05 -8.85 – 0.76 -1.65 0.105 -1.15 -4.58 – 2.29 -0.65 0.516 -1.59 -5.14 – 1.97 -0.87 0.386
Stimulation x OCDno med -
HC
-0.51 -2.56 – 1.54 -0.49 0.629 0.60 -0.81 – 2.00 0.84 0.407 1.80 0.18 – 3.43 2.17 0.034
Stimulation x OCDmed -
OCDno med
0.90 -1.57 – 3.37 0.71 0.480 0.78 -0.89 – 2.44 0.91 0.365 -2.66 -4.62 – -0.70 -2.66 0.010
Observations 3244 49849 3244
[1] "Random effects ERN:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    6.31          
                stimulation2-1 1.76     -0.06
 Residual                      9.93          
[1] "Random effects CRN:"
 Groups         Name           Std.Dev. Corr
 participant_id (Intercept)    4.61         
                stimulation2-1 2.15     0.06
 Residual                      9.58         
[1] "Random effects Pe:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    4.64          
                stimulation2-1 1.32     -0.29
 Residual                      8.07          



Results remained unchanged, with a trend for a main effect of tDCS on ERN amplitude and a significant main effect of tDCS on CRN and Pe amplitude.


P300 Amplitude

P300 as dependent variable

In an exploratory analysis, we fitted a LMM with P300 amplitude as dependent variable to examine the presence of an tDCS effect on this stimulus-locked component. Both correct and incorrect trials were included in this analysis. We entered group, tDCS condition, and response type as predictors.

This table corresponds to Table S5 in the supplemental material.

# Run model
LMM_P3 <- lmer(P3_300_500_CPz ~ stimulation * group * response_type *
  (1 + stimulation * response_type | participant_id),
data = single_trial_data_clean,
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


# Check model output and PCA of random-effects variance-covariance estimates
# summary(LMM_P3)        # Model does converge
# isSingular(LMM_P3)     # No singular fit
# summary(rePCA(LMM_P3)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_P3,
  dv.labels = "P300", pred.labels = labels, show.stat = TRUE, show.icc = FALSE, show.r2 = FALSE,
  show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed effects", 
  string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", wrap.labels = 80,
  title = "Results of the LMM Predicting P300 Amplitude as a Function of Stimulation Condition 
  (Cathodal - Sham), Group (OCD - Healthy Controls), and Response Type (Incorrect - Correct)"
)


# Display random effects
print("Random effects")
print(VarCorr(LMM_P3), digits = 3, comp = "Std.Dev.")
Results of the LMM Predicting P300 Amplitude as a Function of Stimulation Condition (Cathodal - Sham), Group (OCD - Healthy Controls), and Response Type (Incorrect - Correct)
  P300
Fixed effects b 95 % CI t p
Intercept 7.17 5.88 – 8.45 10.90 <0.001
Stimulation 0.77 0.25 – 1.29 2.89 0.006
Group -1.78 -4.35 – 0.80 -1.35 0.182
Response type -3.52 -4.44 – -2.61 -7.52 <0.001
Stimulation x Group -0.01 -1.05 – 1.03 -0.02 0.980
Stimulation x Response type 0.28 -0.45 – 1.02 0.76 0.452
Group x Response type -0.56 -2.39 – 1.28 -0.59 0.555
Stimulation x Group x Response type -0.40 -1.87 – 1.08 -0.53 0.601
Observations 53002
[1] "Random effects"
 Groups         Name                            Std.Dev. Corr             
 participant_id (Intercept)                     4.88                      
                stimulation2-1                  1.63      0.26            
                response_type2-1                3.30      0.42  0.07      
                stimulation2-1:response_type2-1 1.63      0.30  0.03 -0.14
 Residual                                       8.16                      



Results of this exploratory analysis indicated that the P300 amplitude was modulated (increased) by tDCS.


P300 as covariate

In an additional (non-preregistered) analysis, we included the within-participant z-standardized single-trial P300 amplitude as a covariate into the analysis of the response-locked ERPs. Thereby, we aimed to control for variation in the P300 amplitude, since response-locked ERPs often overlap with this stimulus-locked positivity, which makes inferences about effects on response-locked components more difficult. Specifically, we aimed to control for tDCS-related P300 differences, since the exploratory analysis indicated that the P300 was modulated by tDCS (see tab “P300 as dependent variable”).

This table corresponds to Table S6 in the supplemental material.

# Run model ERN
LMM_ERN_P3 <- lmer(MFN_0_100_FCz ~ stimulation * group * P3_300_500_CPz_standardized  +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
) # Convergence, singularity, PCA checked, all ok


# Run model CRN
LMM_CRN_P3 <- lmer(MFN_0_100_FCz ~ stimulation * group * P3_300_500_CPz_standardized  +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "correct", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
) # Convergence, singularity, PCA checked, all ok


# Run model Pe
LMM_Pe_P3 <- lmer(Pe_200_400_Pz ~ stimulation * group * P3_300_500_CPz_standardized  +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[single_trial_data_clean$response_type == "incorrect", ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
) # Convergence, singularity, PCA checked, all ok


# Display results (fixed effects) in one table
tab_model(LMM_ERN_P3, LMM_CRN_P3, LMM_Pe_P3,
  dv.labels = c("ERN", "CRN", "Pe"), pred.labels = labels, show.stat = TRUE, show.icc = FALSE, 
  show.r2 = FALSE, show.re.var = FALSE, show.ngroups = FALSE, minus.sign = "−", string.pred = "Fixed 
  effects", string.est = "b", string.stat = "t", string.ci = "95 % CI", p.val = "satterthwaite", 
  title = "Results of the LMMs Predicting ERN, CRN, and Pe Amplitude as a Function of Stimulation 
  Condition (Cathodal - Sham) and Group (OCD - Healthy Controls) With Single-Trial P300 Amplitude 
  as a Covariate"
)


# Display random effects
print("Random effects ERN:")
print(VarCorr(LMM_ERN_P3), digits = 3, comp = "Std.Dev.")

print("Random effects CRN:")
print(VarCorr(LMM_CRN_P3), digits = 3, comp = "Std.Dev.")

print("Random effects Pe:")
print(VarCorr(LMM_Pe_P3), digits = 3, comp = "Std.Dev.")
Results of the LMMs Predicting ERN, CRN, and Pe Amplitude as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCD - Healthy Controls) With Single-Trial P300 Amplitude as a Covariate
  ERN CRN Pe
Fixed effects b 95 % CI t p b 95 % CI t p b 95 % CI t p
Intercept -0.33 -1.75 – 1.09 -0.46 0.651 5.90 4.70 – 7.10 9.62 <0.001 11.00 9.79 – 12.21 17.84 <0.001
Stimulation 0.91 0.18 – 1.64 2.45 0.017 0.67 0.09 – 1.26 2.25 0.028 0.83 0.07 – 1.60 2.13 0.038
Group -2.99 -5.83 – -0.14 -2.06 0.044 -2.17 -4.57 – 0.24 -1.77 0.083 0.65 -1.77 – 3.07 0.53 0.601
P300 6.14 5.85 – 6.42 42.08 <0.001 5.65 5.59 – 5.72 161.79 <0.001 4.09 3.84 – 4.35 31.74 <0.001
Stimulation x Group 0.08 -1.38 – 1.54 0.11 0.912 0.88 -0.30 – 2.05 1.47 0.148 0.68 -0.85 – 2.22 0.87 0.386
Stimulation x P300 0.75 0.20 – 1.30 2.66 0.008 0.09 -0.04 – 0.23 1.34 0.181 0.23 -0.26 – 0.73 0.93 0.354
Group x P300 -1.01 -1.58 – -0.44 -3.46 0.001 -0.59 -0.73 – -0.45 -8.47 <0.001 -0.34 -0.85 – 0.16 -1.34 0.181
Stimulation x Group x
P300
-0.91 -2.01 – 0.19 -1.62 0.104 0.09 -0.19 – 0.36 0.63 0.528 -0.53 -1.52 – 0.45 -1.06 0.290
Observations 3240 49762 3240
[1] "Random effects ERN:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    5.29          
                stimulation2-1 1.50     -0.16
 Residual                      7.94          
[1] "Random effects CRN:"
 Groups         Name           Std.Dev. Corr
 participant_id (Intercept)    4.58         
                stimulation2-1 2.18     0.04
 Residual                      7.72         
[1] "Random effects Pe:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    4.49          
                stimulation2-1 2.04     -0.39
 Residual                      7.02          



When including the P300 as a covariate in the LMMs on ERN, CRN, and Pe amplitude, a significant main effect of the P300 was observed in all models. The effect of tDCS on CRN and Pe remained significant. Importantly, the tDCS-induced reduction in ERN amplitude, previously present as a statistical trend, was now significant. The same applies to the group difference in ERN amplitude, which now also reached significance.


References


Bates, D., Kliegl, R., Vasishth, S., & Baayen, H. (2015). Parsimonious mixed models. arXiv. https://arxiv.org/abs/1506.04967v2

Box, G. E., & Cox, D. R. (1964). An analysis of transformations. Journal of the Royal Statistical Society: Series B (Methodological), 26(2), 211-243. https://doi.org/10.1111/j.2517-6161.1964.tb00553.x

Morey, R. (2008). Confidence intervals from normalized data: A correction to Cousineau (2005). Tutorials in Quantitative Methods for Psychology, 4(2), 61-64. https://doi.org/10.20982/tqmp.04.2.p061

Reinhart, R. M., & Woodman, G. F. (2014). Causal control of medial–frontal cortex governs electrophysiological and behavioral indices of performance monitoring and learning. Journal of Neuroscience, 34(12), 4214-4227. https://doi.org/10.1523/JNEUROSCI.5421-13.2014



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 19044)

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] plyr_1.8.6       ggplot2_3.3.2    splithalf_0.7.1  sjPlot_2.8.6    
 [5] lmerTest_3.1-3   lme4_1.1-25      Matrix_1.2-17    MASS_7.3-53     
 [9] kableExtra_1.3.1 knitr_1.30       dplyr_1.0.6     

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.5          mvtnorm_1.1-1       lattice_0.20-38    
 [4] tidyr_1.1.2         digest_0.6.27       utf8_1.1.4         
 [7] R6_2.5.0            backports_1.2.0     evaluate_0.14      
[10] highr_0.8           httr_1.4.2          pillar_1.6.0       
[13] rlang_0.4.11        rstudioapi_0.11     minqa_1.2.4        
[16] performance_0.7.1.1 nloptr_1.2.2.2      effectsize_0.4.0   
[19] rmarkdown_2.5       ggeffects_0.16.0    splines_3.6.1      
[22] webshot_0.5.2       statmod_1.4.35      stringr_1.4.0      
[25] munsell_0.5.0       broom_0.7.2         modelr_0.1.8       
[28] compiler_3.6.1      numDeriv_2016.8-1.1 xfun_0.19          
[31] pkgconfig_2.0.3     parameters_0.13.0   htmltools_0.5.0    
[34] insight_0.14.0      tidyselect_1.1.0    tibble_3.0.4       
[37] codetools_0.2-16    fansi_0.4.1         viridisLite_0.3.0  
[40] withr_2.3.0         crayon_1.3.4        sjmisc_2.8.5       
[43] grid_3.6.1          nlme_3.1-140        xtable_1.8-4       
[46] gtable_0.3.0        lifecycle_1.0.0     magrittr_2.0.1     
[49] bayestestR_0.9.0    scales_1.1.1        estimability_1.3   
[52] stringi_1.5.3       renv_0.12.0         robustbase_0.93-6  
[55] xml2_1.3.2          ellipsis_0.3.2      generics_0.1.0     
[58] vctrs_0.3.8         boot_1.3-22         sjlabelled_1.1.7   
[61] tools_3.6.1         glue_1.4.2          DEoptimR_1.0-8     
[64] purrr_0.3.4         sjstats_0.18.0      emmeans_1.5.2-1    
[67] yaml_2.2.1          colorspace_1.4-1    rvest_1.0.2        
[70] patchwork_1.1.0    
LS0tDQp0aXRsZTogIkVSUCBEYXRhIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudA0KLS0tDQoNCjwhLS0gU2V0IGdlbmVyYWwgc2V0dGluZ3MgLS0+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQoNCiMgU2V0IGdlbmVyYWwgc2V0dGluZ3MgZm9yIG1hcmtkb3duIGZpbGUNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgbWVzc2FnZSA9IEZBTFNFLA0KICB3YXJuaW5nID0gRkFMU0UsDQogIGNvbW1lbnQgPSAiIiwNCiAgcmVzdWx0cyA9ICJob2xkIg0KKQ0KDQoNCiMgQ2xlYXIgZW52aXJvbm1lbnQNCnJtKGxpc3QgPSBscygpKQ0KDQoNCiMgRW5hYmxlL2Rpc2FibGUgY2FjaGluZyBvZiB0aW1lLWNvbnN1bWluZyBjb2RlIGNodW5rcw0Ka25pdHJfY2FjaGVfZW5hYmxlZCA9IFRSVUUNCg0KDQojIExvYWQgcGFja2FnZXMNCmxpYnJhcnkoZHBseXIpICAgICAgIyBmb3IgZGF0YSB3cmFuZ2xpbmcNCmxpYnJhcnkoa25pdHIpICAgICAgIyBmb3IgaW50ZWdyYXRpbmcgY29tcHV0aW5nIGFuZCByZXBvcnRpbmcgaW4gbWFya2Rvd24NCmxpYnJhcnkoa2FibGVFeHRyYSkgIyBmb3IgY3VzdG9taXppbmcgYXBwZWFyYW5jZSBvZiB0YWJsZXMNCmxpYnJhcnkoTUFTUykgICAgICAgIyBmb3IgYm94Y294IGZ1bmN0aW9uIGFuZCBjb250cmFzdCBkZWZpbml0aW9uDQpsaWJyYXJ5KGxtZTQpICAgICAgICMgZm9yIChHKUxNTXMNCmxpYnJhcnkobG1lclRlc3QpICAgIyBmb3IgTE1NIHAgdmFsdWVzIChTYXR0ZXJ0aHdhaXRlJ3MgbWV0aG9kIGZvciBhcHByb3hpbWF0aW5nIGRmcyBmb3IgdCBhbmQgRiB0ZXN0cykNCmxpYnJhcnkoc2pQbG90KSAgICAgIyBmb3IgdGFiX21vZGVsIGZ1bmN0aW9uIHRvIGRpc3BsYXkgKEcpTE1NIHJlc3VsdHMNCmxpYnJhcnkoc3BsaXRoYWxmKSAgIyBmb3IgcGVybXV0YXRpb24tYmFzZWQgc3BsaXQtaGFsZiByZWxpYWJpbGl0eQ0KDQoNCiMgTG9hZCBmdW5jdGlvbnMNCnNvdXJjZSgiLi9mdW5jdGlvbnMvc3VtbWFyeVNFd2l0aGluTy5SIikgICMgRnVuY3Rpb24gcHJvdmlkZWQgYnkgUi1jb29rYm9vazogaHR0cDovL3d3dy5jb29rYm9vay1yLmNvbS9HcmFwaHMvUGxvdHRpbmdfbWVhbnNfYW5kX2Vycm9yX2JhcnNfKGdncGxvdDIpLw0Kc291cmNlKCIuL2Z1bmN0aW9ucy9teV90YWJsZV90ZW1wbGF0ZS5SIikgIyBGdW5jdGlvbiB0byBjcmVhdGUgdGFibGUgdGVtcGxhdGUNCnNvdXJjZSgiLi9mdW5jdGlvbnMvUl9yYWluY2xvdWRzLlIiKSAgICAgICMgRnVuY3Rpb24gdG8gY3JlYXRlIHJhaW5jbG91ZCBwbG90cw0KDQoNCiMgVHVybiBvZmYgc2NpZW50aWZpYyBub3RhdGlvbg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpDQpgYGANCjxicj48YnI+IA0KDQojIyBEYXRhIENsZWFuaW5nDQoqKioNCg0KYGBge3IgbG9hZC1hbmQtY2xlYW4tZGF0YX0NCg0KIyBMb2FkIGRhdGENCmxvYWQoZmlsZSA9ICIuL2RhdGEvU2luZ2xlX1RyaWFsX0RhdGEucmRhIikNCg0KDQojIEV4Y2x1ZGUgbWlzc2luZyByZXNwb25zZXMsIFJUIG91dGxpZXJzLCBhbmQgdHJpYWxzIHdpdGggRVJQIGFydGlmYWN0cw0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4gPC0gc2luZ2xlX3RyaWFsX2RhdGEgJT4lDQogIGRwbHlyOjpmaWx0ZXIoDQogICAgICByZXNwb25zZV90eXBlICE9ICJtaXNzIiAmDQogICAgICBydF9pbnZhbGlkICAgID09IEZBTFNFICYNCiAgICAgICFpcy5uYShNRk5fMF8xMDBfRkN6KQ0KICApICMgKDUzMDkzIG9mIDUzNzYwIHRyaWFscyBsZWZ0KQ0KDQoNCiMgQ3JlYXRlIG1lZGljYXRpb24gdmFyaWFibGUgKG5lZWRlZCBhcyBjb3ZhcmlhdGUgbGF0ZXIpDQpzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiA8LSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiAlPiUNCiAgZHBseXI6Om11dGF0ZSgNCiAgICBtZWRpY2F0aW9uID0gYXMuZmFjdG9yKGlmZWxzZSgNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJQXzAyIiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzA0IiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiUF8wNSIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8wNiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIlBfMDgiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMTAiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJQXzE1IiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzE2IiB8DQogICAgICBwYXJ0aWNpcGFudF9pZCA9PSAiUF8xOCIgfCBwYXJ0aWNpcGFudF9pZCA9PSAiUF8yMiIgfA0KICAgICAgcGFydGljaXBhbnRfaWQgPT0gIlBfMjUiIHwgcGFydGljaXBhbnRfaWQgPT0gIlBfMjYiIHwNCiAgICAgIHBhcnRpY2lwYW50X2lkID09ICJQXzI4IiB8IHBhcnRpY2lwYW50X2lkID09ICJQXzMwIiwgInllcyIsICJubyIpKSwNCiAgICBncm91cF9tZWRpY2F0aW9uID0gYXMuZmFjdG9yKGlmZWxzZSgoZ3JvdXAgPT0gIkhDIiksICJIQyIsDQogICAgICBpZmVsc2UoKGdyb3VwID09ICJPQ0QiICYgbWVkaWNhdGlvbiA9PSAibm8iKSwgIk9DRF9ub19tZWQiLCAiT0NEX21lZCIpKSkNCiAgICApDQoNCg0KIyBDcmVhdGUgd2l0aGluLXBhcnRpY2lwYW50IHN0YW5kYXJkaXplZCBQMzAwIHZhcmlhYmxlIChuZWVkZWQgYXMgY292YXJpYXRlIGxhdGVyKQ0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4gPC0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4gJT4lDQogIGRwbHlyOjpncm91cF9ieShwYXJ0aWNpcGFudF9pZCwgc2Vzc2lvbikgJT4lDQogIGRwbHlyOjptdXRhdGUoUDNfMzAwXzUwMF9DUHpfc3RhbmRhcmRpemVkID0gc2NhbGUoUDNfMzAwXzUwMF9DUHosIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkpICAlPiUNCiAgZHBseXI6OnVuZ3JvdXAoKQ0KDQoNCiMgTWFrZSBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgZmFjdG9ycw0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcGFydGljaXBhbnRfaWQgICA8LSBmYWN0b3Ioc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcGFydGljaXBhbnRfaWQpDQpzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRncm91cCAgICAgICAgICAgIDwtIGZhY3RvcihzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRncm91cCkNCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHN0aW11bGF0aW9uICAgICAgPC0gZmFjdG9yKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHN0aW11bGF0aW9uKQ0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSAgICA8LSBmYWN0b3Ioc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSkNCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJGdyb3VwX21lZGljYXRpb24gPC0gZmFjdG9yKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJGdyb3VwX21lZGljYXRpb24sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiSEMiLCAiT0NEX25vX21lZCIsICJPQ0RfbWVkIikpDQpgYGANCg0KVHJpYWxzIHdpdGggYSByZXNwb25zZSB0aW1lIGJlbG93IDEwMCBtcyBvciBhYm92ZSA4MDAgbXMgb3Igd2l0aCBhIG1pc3NpbmcgcmVzcG9uc2Ugd2VyZSBleGNsdWRlZCBmcm9tIGFsbCBhbmFseXNlcy4gV2UgZnVydGhlciBkaXNjYXJkZWQgdHJpYWxzIGNvbnRhaW5pbmcgYXJ0aWZhY3RzIGluIHRoZSBFRUcsIHRoYXQgaXMsIGEgdm9sdGFnZSBjaGFuZ2UgZXhjZWVkaW5nIDUwIM68ViBiZXR3ZWVuIHNhbXBsZSBwb2ludHMgb3IgMjAwIM68ViB3aXRoaW4gYW4gZXBvY2guIDxicj48YnI+DQoNCmBgYHtyIGV4Y2x1ZGVkLXRyaWFsc30NCg0KIyBDYWxjdWxhdGUgcGVyY2VudGFnZSBvZiBleGNsdWRlZCB0cmlhbHMgcGVyIHBhcnRpY2lwYW50DQpleGNsdWRlZF90cmlhbHNfcGVyX3BhcnRpY2lwYW50IDwtIHNpbmdsZV90cmlhbF9kYXRhICU+JQ0KICBkcGx5cjo6Z3JvdXBfYnkoZ3JvdXAsIHBhcnRpY2lwYW50X2lkLCBzZXNzaW9uKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZSgNCiAgICBpbnZhbGlkX3J0ICAgPSBzdW0oIWlzLm5hKHJ0X2ludmFsaWQpICYgcnRfaW52YWxpZCAhPSBGQUxTRSkgLyBsZW5ndGgocGFydGljaXBhbnRfaWQpICogMTAwLA0KICAgIG1pc3NlcyAgICAgICA9IHN1bShyZXNwb25zZV90eXBlID09ICJtaXNzIikgLyBsZW5ndGgocGFydGljaXBhbnRfaWQpICogMTAwLA0KICAgIEVFR19hcnRpZmFjdCA9IHN1bShpcy5uYW4oTUZOXzBfMTAwX0ZDeikpICAgLyBsZW5ndGgocGFydGljaXBhbnRfaWQpICogMTAwIA0KICApICU+JQ0KICBkcGx5cjo6dW5ncm91cCgpDQoNCg0KIyBTdW1tYXJpemUgcGVyY2VudGFnZSBvZiBleGNsdWRlZCB0cmlhbHMgcGVyIHBhcnRpY2lwYW50IG92ZXIgZ3JvdXBzDQpleGNsdWRlZF90cmlhbHNfcGVyX3BhcnRpY2lwYW50X292ZXJfZ3JvdXBzIDwtIGV4Y2x1ZGVkX3RyaWFsc19wZXJfcGFydGljaXBhbnQgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoYWNyb3NzKC1jKGdyb3VwLCBwYXJ0aWNpcGFudF9pZCwgc2Vzc2lvbiksIGxpc3QobWVhbiwgc2QsIG1pbiwgbWF4KSkpDQoNCg0KIyBTdW1tYXJpemUgcGVyY2VudGFnZSBvZiBleGNsdWRlZCB0cmlhbHMgcGVyIHBhcnRpY2lwYW50IHBlciBncm91cA0KZXhjbHVkZWRfdHJpYWxzX3Blcl9wYXJ0aWNpcGFudF9wZXJfZ3JvdXAgPC0gZXhjbHVkZWRfdHJpYWxzX3Blcl9wYXJ0aWNpcGFudCAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGdyb3VwKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShhY3Jvc3MoLWMocGFydGljaXBhbnRfaWQsIHNlc3Npb24pLCBsaXN0KG1lYW4sIHNkLCBtaW4sIG1heCkpKSAlPiUNCiAgZHBseXI6OnVuZ3JvdXAoKQ0KDQoNCiMgQ29tYmluZSBncm91cHMgYW5kIHRvdGFsIHNhbXBsZQ0KZXhjbHVkZWRfdHJpYWxzIDwtIHJiaW5kKGV4Y2x1ZGVkX3RyaWFsc19wZXJfcGFydGljaXBhbnRfcGVyX2dyb3VwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjYmluZChncm91cCA9ICJPdmVyYWxsIiwgZXhjbHVkZWRfdHJpYWxzX3Blcl9wYXJ0aWNpcGFudF9vdmVyX2dyb3VwcykpDQoNCg0KIyBEaXNwbGF5IHBlcmNlbnRhZ2Ugb2YgZXhjbHVkZWQgdHJpYWxzIHBlciBwYXJ0aWNpcGFudA0KbXlfdGFibGVfdGVtcGxhdGUoZXhjbHVkZWRfdHJpYWxzLA0KICBjYXB0aW9uID0gIkV4Y2x1ZGVkIFRyaWFscyBwZXIgUGFydGljaXBhbnQgKGluICUpIiwNCiAgY29sX25hbWVzID0gYygiICIsIHJlcChjKCJNIiwgIlNEIiwgIm1pbiIsICJtYXgiKSwgMykpLA0KICBoZWFkZXJfYWJvdmVfY29uZmlnID0gYygiICIgPSAxLCAiUlQgPCAxMDAgLyA+IDgwMCBtcyIgPSA0LCAiTWlzc2VzIiA9IDQsICJFRUcgYXJ0aWZhY3QiID0gNCkNCikNCmBgYA0KPGJyPjxicj4NCg0KDQojIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzIA0KKioqDQoNClRoaXMgdGFibGUgY29ycmVzcG9uZHMgdG8gVGFibGUgMiBpbiB0aGUgbWFudXNjcmlwdC4NCg0KYGBge3IgZGVzY3JpcHRpdmUtc3RhdGlzdGljcy10YWJsZX0NCg0KIyBDYWxjdWxhdGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBmb3IgRVJOL0NSTg0KZGVzY3JpcHRpdmVfc3RhdGlzdGljc19NRk4gPC0gc3VtbWFyeVNFd2l0aGluTygNCiAgZGF0YSAgICAgICAgICA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuLA0KICBtZWFzdXJldmFyICAgID0gIk1GTl8wXzEwMF9GQ3oiLA0KICB3aXRoaW52YXJzICAgID0gYygicmVzcG9uc2VfdHlwZSIsICJzdGltdWxhdGlvbiIpLA0KICBiZXR3ZWVudmFycyAgID0gImdyb3VwIiwNCiAgaWR2YXIgICAgICAgICA9ICJwYXJ0aWNpcGFudF9pZCIsDQogIGNvbmYuaW50ZXJ2YWwgPSAuOTUNCikgJT4lIGRwbHlyOjpyZW5hbWUoTSA9IE1GTl8wXzEwMF9GQ3osIE1fbm9ybSA9IE1GTl8wXzEwMF9GQ3pfbm9ybSkgJT4lDQogIGRwbHlyOjphcnJhbmdlKGRlc2MocmVzcG9uc2VfdHlwZSkpICU+JQ0KICBkcGx5cjo6c2VsZWN0KC1yZXNwb25zZV90eXBlKQ0KDQoNCiMgQ2FsY3VsYXRlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIFBlDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX1BlIDwtIHN1bW1hcnlTRXdpdGhpbk8oDQogIGRhdGEgICAgICAgICAgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbltzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlID09ICJpbmNvcnJlY3QiLCBdLA0KICBtZWFzdXJldmFyICAgID0gIlBlXzIwMF80MDBfUHoiLA0KICB3aXRoaW52YXJzICAgID0gInN0aW11bGF0aW9uIiwNCiAgYmV0d2VlbnZhcnMgICA9ICJncm91cCIsDQogIGlkdmFyICAgICAgICAgPSAicGFydGljaXBhbnRfaWQiLA0KICBjb25mLmludGVydmFsID0gLjk1DQopICU+JSBkcGx5cjo6cmVuYW1lKE0gPSBQZV8yMDBfNDAwX1B6LCBNX25vcm0gPSBQZV8yMDBfNDAwX1B6X25vcm0pDQoNCg0KDQojIENvbWJpbmUgbWVhc3VyZXMNCmRlc2NyaXB0aXZlX3N0YXRpc3RpY3MgPC0gYXMuZGF0YS5mcmFtZShyYmluZChkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX01GTiwgZGVzY3JpcHRpdmVfc3RhdGlzdGljc19QZSkpDQoNCg0KDQojIExhYmVsIG1lYXN1cmVzDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzJE1lYXN1cmUgPC0gYyhyZXAoIkVSTiAowrVWKSIsIDQpLCByZXAoIkNSTiAowrVWKSIsIDQpLCByZXAoIlBlICjCtVYpIiwgNCkpDQoNCg0KIyBDcmVhdGUgY29sdW1uIHdpdGggZm9ybWF0ICJNIFtDSV0iIChyb3VuZCB0byAyIGRlY2ltYWxzKQ0KZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRNX0NJIDwtIHBhc3RlMCgNCiAgZm9ybWF0KHJvdW5kKGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkTSwgIDIpLCBuc21hbGwgPSAyKSwgIiBbIiwNCiAgZm9ybWF0KHJvdW5kKGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkTSAtDQogICAgICAgICAgICAgICBkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzJGNpLCAyKSwgbnNtYWxsID0gMiksICIsICIsDQogIGZvcm1hdChyb3VuZChkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzJE0gKw0KICAgICAgICAgICAgICAgZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRjaSwgMiksIG5zbWFsbCA9IDIpLCAiXSIpDQoNCg0KDQojIFNlbGVjdCByZWxldmFudCBjb2x1bW5zDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzIDwtIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3NbLCBjICgiZ3JvdXAiLCAic3RpbXVsYXRpb24iLCAiTWVhc3VyZSIsICJNX0NJIildDQoNCg0KDQojIFNwbGl0IGFuZCByZS1tZXJnZSB0YWJsZSB0byBkaXNwbGF5IGJvdGggZ3JvdXBzIG5leHQgdG8gZWFjaCBvdGhlcg0KZGVzY3JpcHRpdmVfc3RhdGlzdGljcyA8LSBzcGxpdChkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzLCBsaXN0KGRlc2NyaXB0aXZlX3N0YXRpc3RpY3Mkc3RpbXVsYXRpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRncm91cCkpDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX2Rpc3BsYXkgPC0gY2JpbmQoDQogIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3Mkc2hhbS5PQ0RbLCBjKCJNZWFzdXJlIiwgIk1fQ0kiKV0sDQogIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3Mkc2hhbS5IQ1ssICJNX0NJIl0sDQogIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkdmVydW0uT0NEWywgIk1fQ0kiXSwNCiAgZGVzY3JpcHRpdmVfc3RhdGlzdGljcyR2ZXJ1bS5IQ1ssICJNX0NJIl0NCikNCg0KDQojIERpc3BsYXkgdGFibGUNCm15X3RhYmxlX3RlbXBsYXRlKGRlc2NyaXB0aXZlX3N0YXRpc3RpY3NfZGlzcGxheSwNCiAgY2FwdGlvbiA9ICJFUlAgTWVhc3VyZXMgaW4gUGF0aWVudHMgV2l0aCBPQ0QgYW5kIEhDIFBhcnRpY2lwYW50cyIsDQogIGNvbF9uYW1lcyA9IGMoIiAiLCByZXAoIk0gWzk1JSBDSV0iLCA0KSksDQogIGhlYWRlcl9hYm92ZV9jb25maWcgPSBjKCIgIiwgcmVwKGMoIlBhdGllbnRzIHdpdGggT0NEIiwgIkhDIHBhcnRpY2lwYW50cyIpLCAyKSksDQogIGZvb3Rub3RlX2NvbmZpZyA9IGMoZ2VuZXJhbCA9ICJDSXMgYXJlIGFkanVzdGVkIGZvciB3aXRoaW4tcGFydGljaXBhbnQgZGVzaWducyAoTW9yZXksIDIwMDgpLg0KICBFUk4gPSBlcnJvci1yZWxhdGVkIG5lZ2F0aXZpdHk7IENSTiA9IGNvcnJlY3QtcmVzcG9uc2UgbmVnYXRpdml0eTsgUGUgPSBlcnJvciBwb3NpdGl2aXR5LiIpKSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiA9IDEsICJTaGFtIHREQ1MiID0gMiwgIkNhdGhvZGFsIHREQ1MiID0gMikpDQpgYGANCjxicj48YnI+DQoNCiMjIFNwbGl0LUhhbGYgUmVsaWFiaWxpdHkNCioqKg0KDQpgYGB7ciBwZXJtdXRhdGlvbi1zcGxpdC1oYWxmLXJlbGlhYmlsaXR5LCBjYWNoZSA9IGtuaXRyX2NhY2hlX2VuYWJsZWR9DQoNCiMgQ2FsY3VsYXRlIHBlcm11dGF0aW9uLWJhc2VkIHNwbGl0LWhhbGYgaW50ZXJuYWwgY29uc2lzdGVuY3kgZm9yIEVSTi9DUk4NCmludmlzaWJsZShjYXB0dXJlLm91dHB1dChzcGxpdF9oYWxmX3JlbGlhYmlsaXR5X01GTiA8LSBzcGxpdGhhbGYoDQogIGRhdGEgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiwNCiAgb3V0Y29tZSA9ICJSVCIsDQogIHNjb3JlID0gImF2ZXJhZ2UiLA0KICBwZXJtdXRhdGlvbnMgPSA1MDAwLA0KICBoYWxmdHlwZSA9ICJyYW5kb20iLA0KICB2YXIuUlQgPSAiTUZOXzBfMTAwX0ZDeiIsDQogIHZhci50cmlhbG51bSA9ICJ0cmlhbCIsDQogIHZhci5wYXJ0aWNpcGFudCA9ICJwYXJ0aWNpcGFudF9pZCIsDQogIHZhci5jb25kaXRpb24gPSAicmVzcG9uc2VfdHlwZSIsDQogIGNvbmRpdGlvbmxpc3QgPSBjKCJjb3JyZWN0IiwgImluY29ycmVjdCIpLA0KICBhdmVyYWdlID0gIm1lYW4iKSkpDQoNCg0KIyBDYWxjdWxhdGUgcGVybXV0YXRpb24tYmFzZWQgc3BsaXQtaGFsZiBpbnRlcm5hbCBjb25zaXN0ZW5jeSBmb3IgUGUNCmludmlzaWJsZShjYXB0dXJlLm91dHB1dChzcGxpdF9oYWxmX3JlbGlhYmlsaXR5X1BlIDwtIHNwbGl0aGFsZigNCiAgZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImluY29ycmVjdCIsIF0sDQogIG91dGNvbWUgPSAiUlQiLA0KICBzY29yZSA9ICJhdmVyYWdlIiwNCiAgcGVybXV0YXRpb25zID0gNTAwMCwNCiAgaGFsZnR5cGUgPSAicmFuZG9tIiwNCiAgdmFyLlJUID0gIlBlXzIwMF80MDBfUHoiLA0KICB2YXIudHJpYWxudW0gPSAidHJpYWwiLA0KICB2YXIucGFydGljaXBhbnQgPSAicGFydGljaXBhbnRfaWQiLA0KICBhdmVyYWdlID0gIm1lYW4iKSkpDQoNCg0KIyBDb21iaW5lIEVSUHMNCnNwbGl0X2hhbGZfcmVsaWFiaWxpdHkgPC0gY2JpbmQoRVJQID0gYygiQ1JOIiwgIkVSTiIsICJQZSIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmJpbmQoc3BsaXRfaGFsZl9yZWxpYWJpbGl0eV9NRk4kZmluYWxfZXN0aW1hdGVzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXRfaGFsZl9yZWxpYWJpbGl0eV9QZSRmaW5hbF9lc3RpbWF0ZXMpKSAlPiUNCiAgZHBseXI6OnNlbGVjdChFUlAsIHNwZWFybWFuYnJvd24sIFNCX2xvdywgU0JfaGlnaCkgJT4lDQogIGRwbHlyOjpyZW5hbWUoDQogICAgciAgICAgID0gc3BlYXJtYW5icm93biwNCiAgICBDSV9sb3cgPSBTQl9sb3csDQogICAgQ0lfdXAgID0gU0JfaGlnaA0KICAgICkNCg0KDQojIERpc3BsYXkgcGVybXV0YXRpb24tYmFzZWQgc3BsaXQtaGFsZiBpbnRlcm5hbCBjb25zaXN0ZW5jeQ0KbXlfdGFibGVfdGVtcGxhdGUoc3BsaXRfaGFsZl9yZWxpYWJpbGl0eVtjKDIsMSwzKSwgXSwgDQogICAgICAgICAgICAgICAgICBjYXB0aW9uID0gIlBlcm11dGF0aW9uLWJhc2VkIHNwbGl0LWhhbGYgcmVsaWFiaWxpdHkiKQ0KYGBgDQpXZSBleGFtaW5lZCB0aGUgaW50ZXJuYWwgY29uc2lzdGVuY3kgb2YgdGhlIEVSUHMgdXNpbmcgYSBwZXJtdXRhdGlvbi1iYXNlZCBzcGxpdC1oYWxmIGFwcHJvYWNoIHdpdGggNSwwMDAgcmFuZG9tIHNwbGl0cyBhbmQgU3BlYXJtYW7igJNCcm93biBjb3JyZWN0aW9uLiBSZXN1bHRzIGluZGljYXRlZCBleGNlbGxlbnQgaW50ZXJuYWwgY29uc2lzdGVuY3kgZm9yIEVSTiAociA9IC45NSwgOTUlIENJIFsuOTMsIC45N10pLCBDUk4gKHIgPSAxLjAwLCA5NSUgQ0kgWy45OSwgMS4wMF0pLCBhbmQgUGUgKHIgPSAuOTQsIDk1JSBDSSBbLjkxLCAuOTZdKS4NCjxicj48YnI+PGJyPg0KDQojIyBMTU0gQW5hbHlzZXMNCioqKg0KDQpXZSBhbmFseXplZCBFUlAgbWVhc3VyZXMgKEVSTiwgQ1JOLCBQZSkgdXNpbmcgbGluZWFyIG1peGVkIG1vZGVscyAoTE1Ncykgb24gc2luZ2xlLXRyaWFsIGRhdGEuIFdlIHRlc3RlZCB3aGV0aGVyIGdyb3VwIGRpZmZlcmVuY2VzIGFuZCB0RENTIGVmZmVjdHMgd2VyZSBwcmVzZW50LiBHcm91cCAoaGVhbHRoeSBjb250cm9scywgT0NEKSBhbmQgdERDUyBjb25kaXRpb24gKGNhdGhvZGFsLCBzaGFtKSB3ZXJlIGluY2x1ZGVkIGFzIGZpeGVkIGVmZmVjdHMgaW4gYWxsIG1vZGVscy4gQWxsIGNhdGVnb3JpY2FsIGZpeGVkIGVmZmVjdHMgd2VyZSBlZmZlY3QtY29kZWQgKGNvbnRyYXN0IGNvZWZmaWNpZW50cyDiiJIwLjUgYW5kIDAuNSkuIA0KDQpXZSBkZXRlcm1pbmVkIHRoZSByYW5kb20tZWZmZWN0cyBzdHJ1Y3R1cmUgZm9yIGVhY2ggbW9kZWwgYmFzZWQgb24gdGhlIHByb2NlZHVyZSBwcm9wb3NlZCBieSBCYXRlcyBldCBhbC4gKDIwMTUpLCBzdGFydGluZyB3aXRoIHRoZSBtYXhpbWFsIHJhbmRvbS1lZmZlY3RzIHN0cnVjdHVyZSBqdXN0aWZpZWQgYnkgdGhlIGRlc2lnbiwgd2l0aCBieS1wYXJ0aWNpcGFudCByYW5kb20gaW50ZXJjZXB0cyBhbmQgcmFuZG9tIHNsb3BlcyBmb3IgYWxsIGZpeGVkIGZhY3RvcnMgYW5kICh3aGVyZSBhcHBsaWNhYmxlKSB0aGVpciBpbnRlcmFjdGlvbnMuIElmIHJlcXVpcmVkIGZvciBtb2RlbCBjb252ZXJnZW5jZSwgY29ycmVsYXRpb24gcGFyYW1ldGVycyBvZiB0aGUgcmFuZG9tIHRlcm1zIHdlcmUgc2V0IHRvIHplcm8uIFJhbmRvbSBlZmZlY3RzIHByZXZlbnRpbmcgbW9kZWwgY29udmVyZ2VuY2Ugb3IgZXhwbGFpbmluZyB6ZXJvIHZhcmlhbmNlIGFzIGRldGVybWluZWQgYnkgcHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcyB3ZXJlIHJlbW92ZWQgdG8gYXZvaWQgb3ZlcnBhcmFtZXRlcml6YXRpb24uDQoNCkluIHRoZXNlIGFuYWx5c2VzLCBtb2RlbCBlc3RpbWF0ZXMgZGlyZWN0bHkgcmVmbGVjdCBtZWFuIGRpZmZlcmVuY2VzIGluIG1pY3Jvdm9sdHMuIE5vdGUgdGhhdCBmb3IgbmVnYXRpdmUgY29tcG9uZW50cywgc3VjaCBhcyB0aGUgRVJOIGFuZCBDUk4sIG5lZ2F0aXZlIGVzdGltYXRlcyBpbmRpY2F0ZSBhbiBpbmNyZWFzZSBpbiBhbXBsaXR1ZGUsIHdoZXJlYXMgcG9zaXRpdmUgZXN0aW1hdGVzIGluZGljYXRlIGEgZGVjcmVhc2UuDQoNCmBgYHtyIExNTS1jb250cmFzdC1jb2Rpbmd9DQoNCiMgRGVmaW5lIGNvbnRyYXN0cyAoc2xpZGluZyBkaWZmZXJlbmNlIGNvbnRyYXN0cyA9IGVmZmVjdCBjb2RpbmcgZm9yIGZhY3RvcnMgd2l0aCAyIGxldmVscykNCmNvbnRyYXN0cyhzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRzdGltdWxhdGlvbikgICAgICA8LSBjb250ci5zZGlmKDIpDQpjb250cmFzdHMoc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kZ3JvdXApICAgICAgICAgICAgPC0gY29udHIuc2RpZigyKQ0KY29udHJhc3RzKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUpICAgIDwtIGNvbnRyLnNkaWYoMikNCmNvbnRyYXN0cyhzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRncm91cF9tZWRpY2F0aW9uKSA8LSBjb250ci5zZGlmKDMpDQoNCg0KIyBQcmVwYXJlIGxhYmVscyBmb3IgTE1NIHRhYmxlcw0KbGFiZWxzIDwtIGMoDQogICIoSW50ZXJjZXB0KSIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiSW50ZXJjZXB0IiwNCiAgInN0aW11bGF0aW9uMi0xIiAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICJTdGltdWxhdGlvbiIsDQogICJncm91cDItMSIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiR3JvdXAiLA0KICAicmVzcG9uc2VfdHlwZTItMSIgICAgICAgICAgICAgICAgICAgICAgICAgID0gIlJlc3BvbnNlIHR5cGUiLA0KICAic3RpbXVsYXRpb24yLTE6Z3JvdXAyLTEiICAgICAgICAgICAgICAgICAgID0gIlN0aW11bGF0aW9uIHggR3JvdXAiLA0KICAic3RpbXVsYXRpb24yLTE6cmVzcG9uc2VfdHlwZTItMSIgICAgICAgICAgID0gIlN0aW11bGF0aW9uIHggUmVzcG9uc2UgdHlwZSIsDQogICJncm91cDItMTpyZXNwb25zZV90eXBlMi0xIiAgICAgICAgICAgICAgICAgPSAiR3JvdXAgeCBSZXNwb25zZSB0eXBlIiwNCiAgInN0aW11bGF0aW9uMi0xOmdyb3VwMi0xOnJlc3BvbnNlX3R5cGUyLTEiICA9ICJTdGltdWxhdGlvbiB4IEdyb3VwIHggUmVzcG9uc2UgdHlwZSIsDQogICJncm91cF9tZWRpY2F0aW9uMi0xIiAgICAgICAgICAgICAgICAgICAgICAgPSAiT0NEbm8gbWVkIC0gSEMiLA0KICAiZ3JvdXBfbWVkaWNhdGlvbjMtMiIgICAgICAgICAgICAgICAgICAgICAgID0gIk9DRG1lZCAtIE9DRG5vIG1lZCIsDQogICJzdGltdWxhdGlvbjItMTpncm91cF9tZWRpY2F0aW9uMi0xIiAgICAgICAgPSAiU3RpbXVsYXRpb24geCBPQ0RubyBtZWQgLSBIQyIsDQogICJzdGltdWxhdGlvbjItMTpncm91cF9tZWRpY2F0aW9uMy0yIiAgICAgICAgPSAiU3RpbXVsYXRpb24geCBPQ0RtZWQgLSBPQ0RubyBtZWQiLA0KICAiUDNfMzAwXzUwMF9DUHpfc3RhbmRhcmRpemVkIiAgICAgICAgICAgICAgID0gIlAzMDAiLA0KICAic3RpbXVsYXRpb24yLTE6UDNfMzAwXzUwMF9DUHpfc3RhbmRhcmRpemVkIj0gIlN0aW11bGF0aW9uIHggUDMwMCIsDQogICJncm91cDItMTpQM18zMDBfNTAwX0NQel9zdGFuZGFyZGl6ZWQiICAgICAgPSAiR3JvdXAgeCBQMzAwIiwNCiAgInN0aW11bGF0aW9uMi0xOmdyb3VwMi0xOlAzXzMwMF81MDBfQ1B6X3N0YW5kYXJkaXplZCIgPSAiU3RpbXVsYXRpb24geCBHcm91cCB4IFAzMDAiDQopDQpgYGANCjxicj48YnI+DQoNCiMjIyBSZXNwb25zZS1SZWxhdGVkIE5lZ2F0aXZpdHkgey50YWJzZXR9DQoNCiMjIyMgRGV0ZXJtaW5lIGRhdGEgdHJhbnNmb3JtYXRpb24NCg0KTm8gZGF0YSB0cmFuc2Zvcm1hdGlvbiB3YXMgcmVxdWlyZWQgdG8gbWVldCB0aGUgYXNzdW1wdGlvbiBvZiBub3JtYWxseSBkaXN0cmlidXRlZCByZXNpZHVhbHMuIFRoaXMgd2FzIGRldGVybWluZWQgdXNpbmcgdGhlIEJveOKAk0NveCBwcm9jZWR1cmUgKEJveCAmIENveCwgMTk2NCkuDQoNCmBgYHtyIE1GTi1kZXRlcm1pbmUtdHJhbnNmb3JtYXRpb24sIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSAzfQ0KDQojIEFycmFuZ2UgcGxvdHMNCnBhcihtZnJvdyA9IGMoMSwgMykpDQoNCg0KIyBEZXRlcm1pbmUgdHJhbnNmb3JtYXRpb24gYnkgZXN0aW1hdGluZyBvcHRpbWFsIGxhbWJkYSB1c2luZyBCb3jigJNDb3ggcHJvY2VkdXJlDQpiY19NRk4gPC0gYm94Y294KE1GTl8wXzEwMF9GQ3ogKyAxMDAgfiAxLCBkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4pDQpvcHRsYW1iZGFfTUZOIDwtIGJjX01GTiR4W3doaWNoLm1heChiY19NRk4keSldDQoNCg0KIyBEZW5zaXR5IHBsb3QgZm9yIE1GTiB2YWx1ZXMNCnBsb3QoZGVuc2l0eShzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRNRk5fMF8xMDBfRkN6KSwgbWFpbiA9ICJEZW5zaXR5ICBQbG90IikNCg0KDQojIFEtcSBwbG90IGZvciBNRk4gdmFsdWVzDQpxcW5vcm0oc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kTUZOXzBfMTAwX0ZDeiwgbWFpbiA9ICJRLVEgUGxvdCIsIHBjaCA9IDEpDQoNCg0KIyBSZXNldCBwbG90IGxheW91dA0KcGFyKG1mcm93ID0gYygxLCAxKSkNCmBgYA0KVGhlIG9wdGltYWwgbGFtYmRhIGlzIGByIHJvdW5kKG9wdGxhbWJkYV9NRk4sIGRpZ2l0cyA9IDIpYCwgc3VnZ2VzdGluZyB0aGF0IG5vIHRyYW5zZm9ybWF0aW9uIGlzIG5lZWRlZC4NCjxicj48YnI+PGJyPg0KDQojIyMjIExNTSB7LmFjdGl2ZX0NCg0KV2UgZml0dGVkIGEgTE1NIHdpdGggcmVzcG9uc2UtcmVsYXRlZCBuZWdhdGl2aXR5IChjb3JyZXNwb25kcyB0byBFUk4gZm9yIGVycm9yIHRyaWFscyBhbmQgQ1JOIGZvciBjb3JyZWN0IHRyaWFscykgYXMgZGVwZW5kZW50IHZhcmlhYmxlIHRvIGV4YW1pbmUgdGhlIHByZXNlbmNlIG9mIGFuIG92ZXJhbGwgdERDUyBlZmZlY3Qgb24gZWxlY3Ryb3BoeXNpb2xvZ2ljYWwgY29ycmVsYXRlcyBvZiBwZXJmb3JtYW5jZSBtb25pdG9yaW5nLiBCb3RoIGNvcnJlY3QgYW5kIGluY29ycmVjdCB0cmlhbHMgd2VyZSBpbmNsdWRlZCBpbiB0aGlzIGFuYWx5c2lzLiBXZSBlbnRlcmVkIGdyb3VwLCB0RENTIGNvbmRpdGlvbiwgYW5kIHJlc3BvbnNlIHR5cGUgYXMgcHJlZGljdG9ycy4gPGJyPjxicj4NClRoaXMgdGFibGUgY29ycmVzcG9uZHMgdG8gVGFibGUgUzMgaW4gdGhlIHN1cHBsZW1lbnRhbCBtYXRlcmlhbC4NCg0KYGBge3IgTE1NLU1GTiwgY2FjaGUgPSBrbml0cl9jYWNoZV9lbmFibGVkfQ0KDQojIFJ1biBtb2RlbA0KTE1NX01GTiA8LSBsbWVyKE1GTl8wXzEwMF9GQ3ogfiBzdGltdWxhdGlvbiAqIGdyb3VwICogcmVzcG9uc2VfdHlwZSArDQogICgxICsgc3RpbXVsYXRpb24gKiByZXNwb25zZV90eXBlIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuLA0KUkVNTCA9IFRSVUUsDQpjb250cm9sID0gbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopDQoNCg0KIyBDaGVjayBtb2RlbCBvdXRwdXQgYW5kIFBDQSBvZiByYW5kb20tZWZmZWN0cyB2YXJpYW5jZS1jb3ZhcmlhbmNlIGVzdGltYXRlcw0KIyBzdW1tYXJ5KExNTV9NRk4pICAgICAgICAjIE1vZGVsIGRvZXMgY29udmVyZ2UNCiMgaXNTaW5ndWxhcihMTU1fTUZOKSAgICAgIyBObyBzaW5ndWxhciBmaXQNCiMgc3VtbWFyeShyZVBDQShMTU1fTUZOKSkgIyBBbGwgdGVybXMgZXhwbGFpbiB2YXJpYW5jZQ0KDQoNCiMgRGlzcGxheSByZXN1bHRzIChmaXhlZCBlZmZlY3RzKQ0KdGFiX21vZGVsKExNTV9NRk4sDQogIGR2LmxhYmVscyA9ICJSZXNwb25zZS1yZWxhdGVkIG5lZ2F0aXZpdHkiLCBwcmVkLmxhYmVscyA9IGxhYmVscywgc2hvdy5zdGF0ID0gVFJVRSwgc2hvdy5pY2MgPSBGQUxTRSwgDQogIHNob3cucjIgPSBGQUxTRSwgc2hvdy5yZS52YXIgPSBGQUxTRSwgc2hvdy5uZ3JvdXBzID0gRkFMU0UsIG1pbnVzLnNpZ24gPSAi4oiSIiwgc3RyaW5nLnByZWQgPSAiRml4ZWQgDQogIGVmZmVjdHMiLCBzdHJpbmcuZXN0ID0gImIiLCBzdHJpbmcuc3RhdCA9ICJ0Iiwgc3RyaW5nLmNpID0gIjk1ICUgQ0kiLCBwLnZhbCA9ICJzYXR0ZXJ0aHdhaXRlIiwgDQogIHdyYXAubGFiZWxzID0gODAsIHRpdGxlID0gIlJlc3VsdHMgb2YgdGhlIExNTSBQcmVkaWN0aW5nIHRoZSBSZXNwb25zZS1SZWxhdGVkIE5lZ2F0aXZpdHkgQW1wbGl0dWRlIA0KICBhcyBhIEZ1bmN0aW9uIG9mIFN0aW11bGF0aW9uIENvbmRpdGlvbiAoQ2F0aG9kYWwgLSBTaGFtKSwgR3JvdXAgKE9DRCAtIEhlYWx0aHkgQ29udHJvbHMpLCBhbmQgDQogIFJlc3BvbnNlIFR5cGUgKEluY29ycmVjdCAtIENvcnJlY3QpIg0KKQ0KDQoNCiMgRGlzcGxheSByYW5kb20gZWZmZWN0cw0KcHJpbnQoIlJhbmRvbSBlZmZlY3RzOiIpDQpwcmludChWYXJDb3JyKExNTV9NRk4pLCBkaWdpdHMgPSAzLCBjb21wID0gIlN0ZC5EZXYuIikNCmBgYA0KPGJyPjxicj4NClRoZSBMTU0gb24gdGhlIHJlc3BvbnNlLXJlbGF0ZWQgbmVnYXRpdml0eSBhY3Jvc3MgY29ycmVjdCBhbmQgaW5jb3JyZWN0IHJlc3BvbnNlcyByZXZlYWxlZCBhIG1haW4gZWZmZWN0IG9mIHJlc3BvbnNlIHR5cGUsIHdpdGggbW9yZSBuZWdhdGl2ZSBhbXBsaXR1ZGVzIGZvciBlcnJvcnMgKEVSTikgdGhhbiBmb3IgY29ycmVjdCByZXNwb25zZXMgKENSTikuIEEgdHJlbmQgZm9yIGFuIGVuaGFuY2VkIHJlc3BvbnNlLXJlbGF0ZWQgbmVnYXRpdml0eSBpbiBwYXRpZW50cyB3aXRoIE9DRCBjb21wYXJlZCB0byBjb250cm9sIHBhcnRpY2lwYW50cyB3YXMgb2JzZXJ2ZWQuIENydWNpYWxseSwgd2UgZm91bmQgdGhhdCB0aGUgcmVzcG9uc2UtcmVsYXRlZCBuZWdhdGl2aXR5IHdhcyByZWR1Y2VkIChpLmUuLCBsZXNzIG5lZ2F0aXZlKSBhZnRlciBjYXRob2RhbCB0RENTIHJlbGF0aXZlIHRvIHNoYW0gdERDUywgYXMgZXZpZGVuY2VkIGJ5IGEgbWFpbiBlZmZlY3Qgb2YgdERDUyBjb25kaXRpb24uIFRoZXJlIHdhcyBubyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBiZXR3ZWVuIGFueSBvZiB0aGUgZmFjdG9ycy4gDQo8YnI+PGJyPjxicj4NCg0KIyMjIEVSTiB7LnRhYnNldH0NCg0KIyMjIyBEZXRlcm1pbmUgZGF0YSB0cmFuc2Zvcm1hdGlvbg0KDQpObyBkYXRhIHRyYW5zZm9ybWF0aW9uIHdhcyByZXF1aXJlZCB0byBtZWV0IHRoZSBhc3N1bXB0aW9uIG9mIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJlc2lkdWFscy4gVGhpcyB3YXMgZGV0ZXJtaW5lZCB1c2luZyB0aGUgQm944oCTQ294IHByb2NlZHVyZSAoQm94ICYgQ294LCAxOTY0KS4NCg0KYGBge3IgRVJOLWRldGVybWluZS10cmFuc2Zvcm1hdGlvbiwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDN9DQoNCiMgQXJyYW5nZSBwbG90cw0KcGFyKG1mcm93ID0gYygxLCAzKSkNCg0KDQojIERldGVybWluZSB0cmFuc2Zvcm1hdGlvbiBieSBlc3RpbWF0aW5nIG9wdGltYWwgbGFtYmRhIHVzaW5nIEJveOKAk0NveCBwcm9jZWR1cmUNCmJjX0VSTiA8LSBib3hjb3goTUZOXzBfMTAwX0ZDeiArIDEwMCB+IDEsIA0KICAgICAgICAgICAgICAgICBkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiaW5jb3JyZWN0IiwgXSkNCm9wdGxhbWJkYV9FUk4gPC0gYmNfRVJOJHhbd2hpY2gubWF4KGJjX0VSTiR5KV0NCg0KDQojIERlbnNpdHkgcGxvdCBmb3IgRVJOIHZhbHVlcw0KcGxvdChkZW5zaXR5KHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImluY29ycmVjdCIsIF0kTUZOXzBfMTAwX0ZDeiksIA0KICAgICBtYWluID0gIkVSTjogRGVuc2l0eSAgUGxvdCIpDQoNCg0KIyBRLXEgcGxvdCBmb3IgRVJOIHZhbHVlcw0KcXFub3JtKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImluY29ycmVjdCIsIF0kTUZOXzBfMTAwX0ZDeiwgDQogICAgICAgbWFpbiA9ICJFUk46IFEtUSBQbG90IiwgcGNoID0gMSkNCg0KDQojIFJlc2V0IHBsb3QgbGF5b3V0DQpwYXIobWZyb3cgPSBjKDEsIDEpKQ0KYGBgDQpUaGUgb3B0aW1hbCBsYW1iZGEgaXMgYHIgcm91bmQob3B0bGFtYmRhX0VSTiwgZGlnaXRzID0gMilgLCBzdWdnZXN0aW5nIHRoYXQgbm8gdHJhbnNmb3JtYXRpb24gaXMgbmVlZGVkLg0KPGJyPjxicj48YnI+DQoNCiMjIyMgTE1NIHsuYWN0aXZlfQ0KDQpJbmNsdWRpbmcgb25seSBlcnJvciB0cmlhbHMgaW4gdGhlIGFuYWx5c2lzLCB3ZSBmaXR0ZWQgYSBMTU0gd2l0aCBFUk4gYW1wbGl0dWRlIGFzIGRlcGVuZGVudCB2YXJpYWJsZS4gSW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBwcmVyZWdpc3RyYXRyYXRpb24sIHNlcGFyYXRlIG1vZGVscyBmb3IgRVJOIGFuZCBDUk4gd2VyZSBzcGVjaWZpZWQgaW4gYWRkaXRpb24gdG8gdGhlIG92ZXJhbGwgbW9kZWwgZm9yIHRoZSByZXNwb25zZS1yZWxhdGVkIG5lZ2F0aXZpdHkgdG8gYWxsb3cgY29tcGFyaXNvbiB3aXRoIHByZXZpb3VzbHkgcmVwb3J0ZWQgcmVzdWx0cyBvbiB0aGVzZSBFUlBzLiA8YnI+PGJyPg0KVGhpcyB0YWJsZSBjb3JyZXNwb25kcyB0byBUYWJsZSAzIGluIHRoZSBtYW51c2NyaXB0Lg0KDQpgYGB7ciBMTU0tRVJOfQ0KDQojIFJ1biBtb2RlbA0KTE1NX0VSTiA8LSBsbWVyKE1GTl8wXzEwMF9GQ3ogfiBzdGltdWxhdGlvbiAqIGdyb3VwICArDQogICgxICsgc3RpbXVsYXRpb24gfCBwYXJ0aWNpcGFudF9pZCksDQpkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiaW5jb3JyZWN0IiwgXSwNClJFTUwgPSBUUlVFLA0KY29udHJvbCA9IGxtZXJDb250cm9sKG9wdGltaXplciA9ICJib2J5cWEiKQ0KKQ0KDQoNCiMgQ2hlY2sgbW9kZWwgb3V0cHV0IGFuZCBQQ0Egb2YgcmFuZG9tLWVmZmVjdHMgdmFyaWFuY2UtY292YXJpYW5jZSBlc3RpbWF0ZXMNCiMgc3VtbWFyeShMTU1fRVJOKSAgICAgICAgIyBNb2RlbCBkb2VzIGNvbnZlcmdlDQojIGlzU2luZ3VsYXIoTE1NX0VSTikgICAgICMgTm8gc2luZ3VsYXIgZml0DQojIHN1bW1hcnkocmVQQ0EoTE1NX0VSTikpICMgQWxsIHRlcm1zIGV4cGxhaW4gdmFyaWFuY2UNCg0KDQojIERpc3BsYXkgcmVzdWx0cyAoZml4ZWQgZWZmZWN0cykNCnRhYl9tb2RlbChMTU1fRVJOLA0KICBkdi5sYWJlbHMgPSAiRVJOIiwgcHJlZC5sYWJlbHMgPSBsYWJlbHMsIHNob3cuc3RhdCA9IFRSVUUsIHNob3cuaWNjID0gRkFMU0UsIHNob3cucjIgPSBGQUxTRSwNCiAgc2hvdy5yZS52YXIgPSBGQUxTRSwgc2hvdy5uZ3JvdXBzID0gRkFMU0UsIG1pbnVzLnNpZ24gPSAi4oiSIiwgc3RyaW5nLnByZWQgPSAiRml4ZWQgZWZmZWN0cyIsIA0KICBzdHJpbmcuZXN0ID0gImIiLCBzdHJpbmcuc3RhdCA9ICJ0Iiwgc3RyaW5nLmNpID0gIjk1ICUgQ0kiLCBwLnZhbCA9ICJzYXR0ZXJ0aHdhaXRlIiwgDQogIHRpdGxlID0gIlJlc3VsdHMgb2YgdGhlIExNTSBQcmVkaWN0aW5nIEVSTiBBbXBsaXR1ZGUgYXMgYSBGdW5jdGlvbiBvZiBTdGltdWxhdGlvbiBDb25kaXRpb24gDQogIChDYXRob2RhbCAtIFNoYW0pIGFuZCBHcm91cCAoT0NEIC0gSGVhbHRoeSBDb250cm9scykiDQopDQoNCg0KIyBEaXNwbGF5IHJhbmRvbSBlZmZlY3RzDQpwcmludCgiUmFuZG9tIGVmZmVjdHM6IikNCnByaW50KFZhckNvcnIoTE1NX0VSTiksIGRpZ2l0cyA9IDMsIGNvbXAgPSAiU3RkLkRldi4iKQ0KDQoNCiMgU2F2ZSBtb2RlbCBvdXRwdXQgZm9yIHBsb3QNCnNhdmVSRFMoTE1NX0VSTiwgZmlsZSA9ICIuL3NhdmVkX29iamVjdHNfZm9yX3Bsb3RzL0xNTV9FUk4ucmRzIikNCmBgYA0KPGJyPjxicj4NCkluIHRoZSBhbmFseXNpcyBvZiB0aGUgRVJOLCB0aGUgbWFpbiBlZmZlY3Qgb2YgZ3JvdXAgZGlkIG5vdCByZWFjaCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UsIGJ1dCBhIHRyZW5kIGZvciBhbiBlbmhhbmNlZCBFUk4gYW1wbGl0dWRlIGluIHBhdGllbnRzIHdpdGggT0NEIHJlbGF0aXZlIHRvIGhlYWx0aHkgY29udHJvbCBwYXJ0aWNpcGFudHMgd2FzIG9ic2VydmVkLiBNb3Jlb3ZlciwgdGhlcmUgd2FzIGEgc3RhdGlzdGljYWwgdHJlbmQgdG93YXJkIGEgcmVkdWNlZCBFUk4gYW1wbGl0dWRlIGFmdGVyIGNhdGhvZGFsIHREQ1MgcmVsYXRpdmUgdG8gc2hhbSB0RENTLiBObyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBiZXR3ZWVuIGdyb3VwIGFuZCB0RENTIGNvbmRpdGlvbiB3YXMgZm91bmQsIGluZGljYXRpbmcgdGhhdCB0aGVyZSB3YXMgbm8gZXZpZGVuY2UgdGhhdCB0aGUgZWZmZWN0IG9mIHREQ1Mgb24gRVJOIGFtcGxpdHVkZSB3YXMgbGFyZ2VyIGluIHBhdGllbnRzIHdpdGggT0NEIHRoYW4gaW4gaGVhbHRoeSBwYXJ0aWNpcGFudHMuIA0KPGJyPjxicj48YnI+DQoNCiMjIyMgU2hhbSBjb25kaXRpb24NCg0KYGBge3IgTE1NLUVSTi1zaGFtfQ0KDQojIFJ1biBtb2RlbA0KTE1NX0VSTl9zaGFtIDwtIGxtZXIoTUZOXzBfMTAwX0ZDeiB+IGdyb3VwICArICAoMSB8IHBhcnRpY2lwYW50X2lkKSwNCmRhdGEgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbltzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlID09ICJpbmNvcnJlY3QiICYgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRzdGltdWxhdGlvbiA9PSAic2hhbSIsIF0sDQpSRU1MID0gVFJVRSwNCmNvbnRyb2wgPSBsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIikNCikNCg0KDQojIENoZWNrIG1vZGVsIG91dHB1dCBhbmQgUENBIG9mIHJhbmRvbS1lZmZlY3RzIHZhcmlhbmNlLWNvdmFyaWFuY2UgZXN0aW1hdGVzDQojIHN1bW1hcnkoTE1NX0VSTl9zaGFtKSAgICAgICAgIyBNb2RlbCBkb2VzIGNvbnZlcmdlDQojIGlzU2luZ3VsYXIoTE1NX0VSTl9zaGFtKSAgICAgIyBObyBzaW5ndWxhciBmaXQNCiMgc3VtbWFyeShyZVBDQShMTU1fRVJOX3NoYW0pKSAjIEFsbCB0ZXJtcyBleHBsYWluIHZhcmlhbmNlDQoNCg0KIyBEaXNwbGF5IHJlc3VsdHMgKGZpeGVkIGVmZmVjdHMpDQp0YWJfbW9kZWwoTE1NX0VSTl9zaGFtLA0KICBkdi5sYWJlbHMgPSAiRVJOIHNoYW0iLCBwcmVkLmxhYmVscyA9IGxhYmVscywgc2hvdy5zdGF0ID0gVFJVRSwgc2hvdy5pY2MgPSBGQUxTRSwgc2hvdy5yMiA9IEZBTFNFLA0KICBzaG93LnJlLnZhciA9IEZBTFNFLCBzaG93Lm5ncm91cHMgPSBGQUxTRSwgbWludXMuc2lnbiA9ICLiiJIiLCBzdHJpbmcucHJlZCA9ICJGaXhlZCBlZmZlY3RzIiwgDQogIHN0cmluZy5lc3QgPSAiYiIsIHN0cmluZy5zdGF0ID0gInQiLCBzdHJpbmcuY2kgPSAiOTUgJSBDSSIsIHAudmFsID0gInNhdHRlcnRod2FpdGUiLCANCiAgdGl0bGUgPSAiUmVzdWx0cyBvZiB0aGUgTE1NIFByZWRpY3RpbmcgRVJOIEFtcGxpdHVkZSBpbiB0aGUgU2hhbSBDb25kaXRpb24gYXMgYSBGdW5jdGlvbiBvZiANCiAgR3JvdXAgKE9DRCAtIEhlYWx0aHkgQ29udHJvbHMpIg0KKQ0KDQoNCiMgRGlzcGxheSByYW5kb20gZWZmZWN0cw0KcHJpbnQoIlJhbmRvbSBlZmZlY3RzOiIpDQpwcmludChWYXJDb3JyKExNTV9FUk5fc2hhbSksIGRpZ2l0cyA9IDMsIGNvbXAgPSAiU3RkLkRldi4iKQ0KYGBgDQo8YnI+PGJyPg0KVGhlIGFuYWx5c2lzIGV2YWx1YXRpbmcgZ3JvdXAgZGlmZmVyZW5jZXMgc29sZWx5IGluIHRoZSBiYXNlbGluZSBFUk4gKGkuZS4sIGluIHRoZSBzaGFtIGNvbmRpdGlvbikgeWllbGRlZCB0aGUgc2FtZSBwYXR0ZXJuIG9mIHJlc3VsdHMgcmVnYXJkaW5nIHRoZSB0cmVuZCBmb3IgYW4gZW5oYW5jZWQgRVJOIGFtcGxpdHVkZSBpbiBwYXRpZW50cyB3aXRoIE9DRCByZWxhdGl2ZSB0byBoZWFsdGh5IGNvbnRyb2wgcGFydGljaXBhbnRzLg0KPGJyPjxicj48YnI+DQoNCiMjIyMgRXF1aXZhbGVuY2UgdGVzdDogRVJODQoNClNpbmNlIHRoZSB0RENTLWluZHVjZWQgRVJOIHJlZHVjdGlvbiBlbWVyZ2VkIG9ubHkgYXMgYSBzdGF0aXN0aWNhbCB0cmVuZCBpbiB0aGUgbWFpbiBhbmFseXNpcywgd2UgZnVydGhlciBleGFtaW5lZCB0aGlzIGVmZmVjdCB1c2luZyB0aGUgdHdvIG9uZS1zaWRlZCB0ZXN0cyBwcm9jZWR1cmUgZm9yIGVxdWl2YWxlbmNlIHRlc3RpbmcgaW4gYSBub24tcHJlcmVnaXN0ZXJlZCBwb3N0IGhvYyBhbmFseXNpcy4gV2UgZGVmaW5lZCB0aGUgc21hbGxlc3QgZWZmZWN0IHNpemUgb2YgaW50ZXJlc3QgKFNFU09JKSBhcyB0aGUgZWZmZWN0IHNpemUgdGhhdCB0aGUgc3R1ZHkgYnkgUmVpbmhhcnQgYW5kIFdvb2RtYW4gKDIwMTQpIGhhZCAzMyUgcG93ZXIgdG8gZGV0ZWN0LiBPbiB0aGUgYmFzaXMgb2YgdGhpcyBhcHByb2FjaCwgd2Ugc2V0IHRoZSBTRVNPSSBmb3IgZXF1aXZhbGVuY2UgYm91bmRzIHRvIENvaGVu4oCZcyAqZHoqID0gMC4zOCwgd2hpY2ggY29ycmVzcG9uZHMgdG8gYW4gRVJOIGFtcGxpdHVkZSBkaWZmZXJlbmNlIG9mIDEuMzQgwrVWIGJldHdlZW4gY2F0aG9kYWwgYW5kIHNoYW0gdERDUy4gDQoNCmBgYHtyIEVSTi1lcXVpdmFsZW5jZS10ZXN0fQ0KDQojIEVxdWl2YWxlbmNlIGJvdW5kcyAocmVmZXJzIHRvIGRpZmZlcmVuY2UgaW4gcmF3IHZhbHVlcyBvZiAxLjM0IG1pY3Jvdm9sdCkNCmJvdW5kX2wgPC0gLTEuMzQgIyBsb3dlciBlcXVpdmFsZW5jZSBib3VuZA0KYm91bmRfdSA8LSAgMS4zNCAjIHVwcGVyIGVxdWl2YWxlbmNlIGJvdW5kDQoNCg0KIyBVc2UgIGNvbnRlc3QxRCBmdW5jdGlvbiBvZiB0aGUgbG1lclRlc3QgcGFja2FnZSB0byBwZXJmb3JtIHRlc3RzIGNlbnRlcmVkIG9uIHRoZSBsb3dlciBhbmQgdXBwZXIgYm91bmQNCmxvd2VyIDwtIGNvbnRlc3QxRChMTU1fRVJOLCBjKDAsIDEsIDAsIDApLCBjb25maW50ID0gVFJVRSwgcmhzID0gYm91bmRfbCkgIyB0ZXN0IGFnYWluc3QgbG93ZXIgYm91bmQNCnVwcGVyIDwtIGNvbnRlc3QxRChMTU1fRVJOLCBjKDAsIDEsIDAsIDApLCBjb25maW50ID0gVFJVRSwgcmhzID0gYm91bmRfdSkgIyB0ZXN0IGFnYWluc3QgdXBwZXIgYm91bmQNCiMgTm90ZTogYygwLDEsMCwwKSByZWZlcnMgdG8gc3RpbXVsYXRpb24gZWZmZWN0ICg9IHNlY29uZCBmaXhlZCBlZmZlY3QpLCBhcyBjYW4gYmUgc2VlbiB3aXRoIGZpeGVmKExNTV9FUk4pDQoNCg0KIyBSZWNhbGN1bGF0ZSB0aGUgcmVxdWlyZWQgb25lLXNpZGVkIHRlc3RzIGZyb20gdGhlIHQtdmFsdWVzICh0ZXN0IHByb3ZpZGVkIGJ5IGNvbnRlc3QxRCBpcyB0d28tc2lkZWQpDQpwX2xvd2VyIDwtIHB0KGxvd2VyJGB0IHZhbHVlYCwgbG93ZXIkZGYsIGxvd2VyLnRhaWwgPSBGQUxTRSkgIyB0ZXN0IGFnYWluc3QgbG93ZXIgYm91bmQNCnBfdXBwZXIgPC0gcHQodXBwZXIkYHQgdmFsdWVgLCB1cHBlciRkZiwgbG93ZXIudGFpbCA9IFRSVUUpICMgdGVzdCBhZ2FpbnN0IHVwcGVyIGJvdW5kDQpgYGANCg0KVGVzdCBhZ2FpbnN0IGxvd2VyIGJvdW5kOiAqdCooYHIgcm91bmQobG93ZXIkZGYsIDIpYCkgPSBgciByb3VuZChsb3dlciQidCB2YWx1ZSIsIDIpYCwgKnAqIGByIGZvcm1hdC5wdmFsKHBfbG93ZXIsIGRpZ2l0cyA9IDMsIGVwcyA9IDAuMDAxKWAgIDxicj4NClRlc3QgYWdhaW5zdCB1cHBlciBib3VuZDogKnQqKGByIHJvdW5kKHVwcGVyJGRmLCAyKWApID0gYHIgcm91bmQodXBwZXIkInQgdmFsdWUiLCAyKWAsICpwKiA9IGByIHJvdW5kKHBfdXBwZXIsIDMpYCAgPGJyPg0KDQpUaGUgZXF1aXZhbGVuY2UgdGVzdCB3YXMgbm90IHNpZ25pZmljYW50LCB0KGByIHJvdW5kKHVwcGVyJGRmLCAyKWApID0gYHIgcm91bmQodXBwZXIkInQgdmFsdWUiLCAyKWAsICpwKiA9IGByIHJvdW5kKHBfdXBwZXIsIDMpYCwgaW5kaWNhdGluZyB0aGF0IHRoZSBFUk4gYW1wbGl0dWRlIGluIHRoZSBjYXRob2RhbCB0RENTIGNvbmRpdGlvbiB3YXMgbm90IHN0YXRpc3RpY2FsbHkgZXF1aXZhbGVudCB0byB0aGF0IGluIHRoZSBzaGFtIGNvbmRpdGlvbi4gVGh1cywgd2UgY2Fubm90IHJlamVjdCB0aGUgcHJlc2VuY2Ugb2YgYW4gZWZmZWN0IGFzIGxhcmdlIG9yIGxhcmdlciB0aGFuIDEuMzQgwrVWLiBUYWtlbiB0b2dldGhlciwgYmFzZWQgb24gcmVzdWx0cyBmcm9tIG51bGwgaHlwb3RoZXNpcyB0ZXN0aW5nIGFuZCBlcXVpdmFsZW5jZSB0ZXN0aW5nLCB3ZSBjYW4gbmVpdGhlciByZWxpYWJseSBjb25jbHVkZSB0aGF0IHRoZSBlZmZlY3Qgb2YgY2F0aG9kYWwgdERDUyBvbiBFUk4gYW1wbGl0dWRlIGlzIGRpZmZlcmVudCBmcm9tIHplcm8gKG5vIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSwgb25seSBhIHN0YXRpc3RpY2FsIHRyZW5kKSwgbm9yIHRoYXQgYW4gZWZmZWN0IHRoYXQgY2FuIGJlIGNvbnNpZGVyZWQgbWVhbmluZ2Z1bCBpcyBhYnNlbnQgKG5vIHN0YXRpc3RpY2FsIGVxdWl2YWxlbmNlKS4gDQo8YnI+PGJyPjxicj4NCg0KIyMjIENSTiB7LnRhYnNldH0NCg0KIyMjIyBEZXRlcm1pbmUgZGF0YSB0cmFuc2Zvcm1hdGlvbg0KDQpObyBkYXRhIHRyYW5zZm9ybWF0aW9uIHdhcyByZXF1aXJlZCB0byBtZWV0IHRoZSBhc3N1bXB0aW9uIG9mIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJlc2lkdWFscy4gVGhpcyB3YXMgZGV0ZXJtaW5lZCB1c2luZyB0aGUgQm944oCTQ294IHByb2NlZHVyZSAoQm94ICYgQ294LCAxOTY0KS4NCg0KYGBge3IgQ1JOLWRldGVybWluZS10cmFuc2Zvcm1hdGlvbiwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDN9DQoNCiMgQXJyYW5nZSBwbG90cw0KcGFyKG1mcm93ID0gYygxLCAzKSkNCg0KDQojIERldGVybWluZSB0cmFuc2Zvcm1hdGlvbiBieSBlc3RpbWF0aW5nIG9wdGltYWwgbGFtYmRhIHVzaW5nIEJveOKAk0NveCBwcm9jZWR1cmUNCmJjX0NSTiA8LSBib3hjb3goTUZOXzBfMTAwX0ZDeiArIDEwMCB+IDEsIA0KICAgICAgICAgICAgICAgICBkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiY29ycmVjdCIsIF0pDQpvcHRsYW1iZGFfQ1JOIDwtIGJjX0NSTiR4W3doaWNoLm1heChiY19DUk4keSldDQoNCg0KIyBEZW5zaXR5IHBsb3QgZm9yIENSTiB2YWx1ZXMNCnBsb3QoZGVuc2l0eShzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbltzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlID09ICJjb3JyZWN0IiwgXSRNRk5fMF8xMDBfRkN6KSwgDQogICAgIG1haW4gPSAiQ1JOOiBEZW5zaXR5ICBQbG90IikNCg0KDQojIFEtcSBwbG90IGZvciBDUk4gdmFsdWVzDQpxcW5vcm0oc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiY29ycmVjdCIsIF0kTUZOXzBfMTAwX0ZDeiwgDQogICAgICAgbWFpbiA9ICJDUk46IFEtUSBQbG90IiwgcGNoID0gMSkNCg0KDQojIFJlc2V0IHBsb3QgbGF5b3V0DQpwYXIobWZyb3cgPSBjKDEsIDEpKQ0KYGBgDQpUaGUgb3B0aW1hbCBsYW1iZGEgaXMgYHIgcm91bmQob3B0bGFtYmRhX0NSTiwgZGlnaXRzID0gMilgLCBzdWdnZXN0aW5nIHRoYXQgbm8gdHJhbnNmb3JtYXRpb24gaXMgbmVlZGVkLg0KPGJyPjxicj48YnI+DQoNCiMjIyMgTE1NIHsuYWN0aXZlfQ0KDQpJbmNsdWRpbmcgb25seSB0cmlhbHMgd2l0aCBjb3JyZWN0IHJlc3BvbnNlIGluIHRoZSBhbmFseXNpcywgd2UgZml0dGVkIGEgTE1NIHdpdGggQ1JOIGFtcGxpdHVkZSBhcyBkZXBlbmRlbnQgdmFyaWFibGUuIEluIGFjY29yZGFuY2Ugd2l0aCB0aGUgcHJlcmVnaXN0cmF0cmF0aW9uLCBzZXBhcmF0ZSBtb2RlbHMgZm9yIEVSTiBhbmQgQ1JOIHdlcmUgc3BlY2lmaWVkIGluIGFkZGl0aW9uIHRvIHRoZSBvdmVyYWxsIG1vZGVsIGZvciB0aGUgcmVzcG9uc2UtcmVsYXRlZCBuZWdhdGl2aXR5IHRvIGFsbG93IGNvbXBhcmlzb24gd2l0aCBwcmV2aW91c2x5IHJlcG9ydGVkIHJlc3VsdHMgb24gdGhlc2UgRVJQcy4gPGJyPjxicj4NClRoaXMgdGFibGUgY29ycmVzcG9uZHMgdG8gVGFibGUgMyBpbiB0aGUgbWFudXNjcmlwdC4NCg0KYGBge3IgTE1NLUNSTn0NCg0KIyBSdW4gbW9kZWwNCkxNTV9DUk4gPC0gbG1lcihNRk5fMF8xMDBfRkN6IH4gc3RpbXVsYXRpb24gKiBncm91cCAgKw0KICAoMSArIHN0aW11bGF0aW9uIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImNvcnJlY3QiLCBdLA0KUkVNTCA9IFRSVUUsDQpjb250cm9sID0gbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopDQoNCg0KIyBDaGVjayBtb2RlbCBvdXRwdXQgYW5kIFBDQSBvZiByYW5kb20tZWZmZWN0cyB2YXJpYW5jZS1jb3ZhcmlhbmNlIGVzdGltYXRlcw0KIyBzdW1tYXJ5KExNTV9DUk4pICAgICAgICAjIE1vZGVsIGRvZXMgY29udmVyZ2UNCiMgaXNTaW5ndWxhcihMTU1fQ1JOKSAgICAgIyBObyBzaW5ndWxhciBmaXQNCiMgc3VtbWFyeShyZVBDQShMTU1fQ1JOKSkgIyBBbGwgdGVybXMgZXhwbGFpbiB2YXJpYW5jZQ0KDQoNCiMgRGlzcGxheSByZXN1bHRzIChmaXhlZCBlZmZlY3RzKQ0KdGFiX21vZGVsKExNTV9DUk4sDQogIGR2LmxhYmVscyA9ICJDUk4iLCBwcmVkLmxhYmVscyA9IGxhYmVscywgc2hvdy5zdGF0ID0gVFJVRSwgc2hvdy5pY2MgPSBGQUxTRSwgc2hvdy5yMiA9IEZBTFNFLA0KICBzaG93LnJlLnZhciA9IEZBTFNFLCBzaG93Lm5ncm91cHMgPSBGQUxTRSwgbWludXMuc2lnbiA9ICLiiJIiLCBzdHJpbmcucHJlZCA9ICJGaXhlZCBlZmZlY3RzIiwgDQogIHN0cmluZy5lc3QgPSAiYiIsIHN0cmluZy5zdGF0ID0gInQiLCBzdHJpbmcuY2kgPSAiOTUgJSBDSSIsIHAudmFsID0gInNhdHRlcnRod2FpdGUiLCANCiAgdGl0bGUgPSAiUmVzdWx0cyBvZiB0aGUgTE1NIFByZWRpY3RpbmcgQ1JOIEFtcGxpdHVkZSBhcyBhIEZ1bmN0aW9uIG9mIFN0aW11bGF0aW9uIENvbmRpdGlvbiANCiAgKENhdGhvZGFsIC0gU2hhbSkgYW5kIEdyb3VwIChPQ0QgLSBIZWFsdGh5IENvbnRyb2xzKSINCikNCg0KDQojIERpc3BsYXkgcmFuZG9tIGVmZmVjdHMNCnByaW50KCJSYW5kb20gZWZmZWN0czoiKQ0KcHJpbnQoVmFyQ29ycihMTU1fQ1JOKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQoNCg0KIyBTYXZlIG1vZGVsIG91dHB1dCBmb3IgcGxvdA0Kc2F2ZVJEUyhMTU1fQ1JOLCBmaWxlID0gIi4vc2F2ZWRfb2JqZWN0c19mb3JfcGxvdHMvTE1NX0NSTi5yZHMiKQ0KYGBgDQo8YnI+PGJyPg0KVGhlIExNTSBvbiB0aGUgQ1JOIHlpZWxkZWQgYSB0cmVuZCBmb3IgYSBtYWluIGVmZmVjdCBvZiBncm91cCwgc3VjaCB0aGF0IHBhdGllbnRzIHdpdGggT0NEIHNob3dlZCBhbiBlbmhhbmNlZCBDUk4gYW1wbGl0dWRlIGNvbXBhcmVkIHRvIGNvbnRyb2wgcGFydGljaXBhbnRzLiBJbiBhZGRpdGlvbiwgYSBzaWduaWZpY2FudCBtYWluIGVmZmVjdCBvZiB0RENTIGNvbmRpdGlvbiByZXZlYWxlZCB0aGF0IHRoZSBDUk4gYW1wbGl0dWRlIHdhcyBzaWduaWZpY2FudGx5IHNtYWxsZXIgYWZ0ZXIgY2F0aG9kYWwgdERDUyByZWxhdGl2ZSB0byBzaGFtIHREQ1MuIFRoZXJlIHdhcyBubyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBiZXR3ZWVuIGdyb3VwIGFuZCB0RENTIGNvbmRpdGlvbi4NCjxicj48YnI+PGJyPg0KDQojIyMjIFNoYW0gY29uZGl0aW9uDQoNCmBgYHtyIExNTS1DUk4tc2hhbX0NCg0KIyBSdW4gbW9kZWwNCkxNTV9DUk5fc2hhbSA8LSBsbWVyKE1GTl8wXzEwMF9GQ3ogfiBncm91cCAgKyAgKDEgfCBwYXJ0aWNpcGFudF9pZCksDQpkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiY29ycmVjdCIgJiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHN0aW11bGF0aW9uID09ICJzaGFtIiwgXSwNClJFTUwgPSBUUlVFLA0KY29udHJvbCA9IGxtZXJDb250cm9sKG9wdGltaXplciA9ICJib2J5cWEiKQ0KKQ0KDQoNCiMgQ2hlY2sgbW9kZWwgb3V0cHV0IGFuZCBQQ0Egb2YgcmFuZG9tLWVmZmVjdHMgdmFyaWFuY2UtY292YXJpYW5jZSBlc3RpbWF0ZXMNCiMgc3VtbWFyeShMTU1fQ1JOX3NoYW0pICAgICAgICAjIE1vZGVsIGRvZXMgY29udmVyZ2UNCiMgaXNTaW5ndWxhcihMTU1fQ1JOX3NoYW0pICAgICAjIE5vIHNpbmd1bGFyIGZpdA0KIyBzdW1tYXJ5KHJlUENBKExNTV9DUk5fc2hhbSkpICMgQWxsIHRlcm1zIGV4cGxhaW4gdmFyaWFuY2UNCg0KDQojIERpc3BsYXkgcmVzdWx0cyAoZml4ZWQgZWZmZWN0cykNCnRhYl9tb2RlbChMTU1fQ1JOX3NoYW0sDQogIGR2LmxhYmVscyA9ICJDUk4gc2hhbSIsIHByZWQubGFiZWxzID0gbGFiZWxzLCBzaG93LnN0YXQgPSBUUlVFLCBzaG93LmljYyA9IEZBTFNFLCBzaG93LnIyID0gRkFMU0UsDQogIHNob3cucmUudmFyID0gRkFMU0UsIHNob3cubmdyb3VwcyA9IEZBTFNFLCBtaW51cy5zaWduID0gIuKIkiIsIHN0cmluZy5wcmVkID0gIkZpeGVkIGVmZmVjdHMiLCANCiAgc3RyaW5nLmVzdCA9ICJiIiwgc3RyaW5nLnN0YXQgPSAidCIsIHN0cmluZy5jaSA9ICI5NSAlIENJIiwgcC52YWwgPSAic2F0dGVydGh3YWl0ZSIsIA0KICB0aXRsZSA9ICJSZXN1bHRzIG9mIHRoZSBMTU0gUHJlZGljdGluZyBDUk4gQW1wbGl0dWRlIGluIHRoZSBTaGFtIENvbmRpdGlvbiBhcyBhIEZ1bmN0aW9uIG9mIA0KICBHcm91cCAoT0NEIC0gSGVhbHRoeSBDb250cm9scykiDQopDQoNCg0KIyBEaXNwbGF5IHJhbmRvbSBlZmZlY3RzDQpwcmludCgiUmFuZG9tIGVmZmVjdHM6IikNCnByaW50KFZhckNvcnIoTE1NX0NSTl9zaGFtKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQpgYGANCjxicj48YnI+DQpXaGVuIGV2YWx1YXRpbmcgZ3JvdXAgZGlmZmVyZW5jZXMgc29sZWx5IGluIHRoZSBiYXNlbGluZSBDUk4gKGkuZS4sIGluIHRoZSBzaGFtIGNvbmRpdGlvbiksIHBhdGllbnRzIHdpdGggT0NEIHNob3dlZCBhbiBlbmhhbmNlZCBDUk4gYW1wbGl0dWRlIGNvbXBhcmVkIHRvIGNvbnRyb2wgcGFydGljaXBhbnRzLg0KPGJyPjxicj48YnI+DQoNCiMjIyBQZSB7LnRhYnNldH0NCg0KIyMjIyBEZXRlcm1pbmUgZGF0YSB0cmFuc2Zvcm1hdGlvbg0KDQpObyBkYXRhIHRyYW5zZm9ybWF0aW9uIHdhcyByZXF1aXJlZCB0byBtZWV0IHRoZSBhc3N1bXB0aW9uIG9mIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJlc2lkdWFscy4gVGhpcyB3YXMgZGV0ZXJtaW5lZCB1c2luZyB0aGUgQm944oCTQ294IHByb2NlZHVyZSAoQm94ICYgQ294LCAxOTY0KS4NCg0KYGBge3IgUGUtZGV0ZXJtaW5lLXRyYW5zZm9ybWF0aW9uLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gM30NCg0KIyBBcnJhbmdlIHBsb3RzDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KDQoNCiMgRGV0ZXJtaW5lIHRyYW5zZm9ybWF0aW9uIGJ5IGVzdGltYXRpbmcgb3B0aW1hbCBsYW1iZGEgdXNpbmcgQm944oCTQ294IHByb2NlZHVyZQ0KYmNfUGUgPC0gYm94Y294KFBlXzIwMF80MDBfUHogKyAxMjAgfiAxLCANCiAgICAgICAgICAgICAgICBkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiaW5jb3JyZWN0IiwgXSkNCm9wdGxhbWJkYV9QZSA8LSBiY19QZSR4W3doaWNoLm1heChiY19QZSR5KV0NCg0KDQojIERlbnNpdHkgcGxvdCBmb3IgUGUgdmFsdWVzDQpwbG90KGRlbnNpdHkoc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiaW5jb3JyZWN0IiwgXSRQZV8yMDBfNDAwX1B6KSwgDQogICAgIG1haW4gPSAiUGU6IERlbnNpdHkgIFBsb3QiKQ0KDQoNCiMgUS1xIHBsb3QgZm9yIFBlIHZhbHVlcw0KcXFub3JtKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImluY29ycmVjdCIsIF0kUGVfMjAwXzQwMF9QeiwgDQogICAgICAgbWFpbiA9ICJQZTogUS1RIFBsb3QiLCBwY2ggPSAxKQ0KDQoNCiMgUmVzZXQgcGxvdCBsYXlvdXQNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANClRoZSBvcHRpbWFsIGxhbWJkYSBpcyBgciByb3VuZChvcHRsYW1iZGFfUGUsIGRpZ2l0cyA9IDIpYCwgc3VnZ2VzdGluZyB0aGF0IG5vIHRyYW5zZm9ybWF0aW9uIGlzIG5lZWRlZC4NCjxicj48YnI+PGJyPg0KDQoNCiMjIyMgTE1NIHsuYWN0aXZlfQ0KDQpJbmNsdWRpbmcgb25seSBlcnJvciB0cmlhbHMgaW4gdGhlIGFuYWx5c2lzLCB3ZSBmaXR0ZWQgYSBMTU0gd2l0aCBQZSBhbXBsaXR1ZGUgYXMgZGVwZW5kZW50IHZhcmlhYmxlLjxicj48YnI+DQpUaGlzIHRhYmxlIGNvcnJlc3BvbmRzIHRvIFRhYmxlIDMgaW4gdGhlIG1hbnVzY3JpcHQuDQoNCmBgYHtyIExNTS1QZX0NCg0KIyBSdW4gbW9kZWwNCkxNTV9QZSA8LSBsbWVyKFBlXzIwMF80MDBfUHogfiBzdGltdWxhdGlvbiAqIGdyb3VwICArDQogICgxICsgc3RpbXVsYXRpb24gfCBwYXJ0aWNpcGFudF9pZCksDQpkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiaW5jb3JyZWN0IiwgXSwNClJFTUwgPSBUUlVFLA0KY29udHJvbCA9IGxtZXJDb250cm9sKG9wdGltaXplciA9ICJib2J5cWEiKQ0KKQ0KDQoNCiMgQ2hlY2sgbW9kZWwgb3V0cHV0IGFuZCBQQ0Egb2YgcmFuZG9tLWVmZmVjdHMgdmFyaWFuY2UtY292YXJpYW5jZSBlc3RpbWF0ZXMNCiMgc3VtbWFyeShMTU1fUGUpICAgICAgICAjIE1vZGVsIGRvZXMgY29udmVyZ2UNCiMgaXNTaW5ndWxhcihMTU1fUGUpICAgICAjIE5vIHNpbmd1bGFyIGZpdA0KIyBzdW1tYXJ5KHJlUENBKExNTV9QZSkpICMgQWxsIHRlcm1zIGV4cGxhaW4gdmFyaWFuY2UNCg0KDQojIERpc3BsYXkgcmVzdWx0cyAoZml4ZWQgZWZmZWN0cykNCnRhYl9tb2RlbChMTU1fUGUsDQogIGR2LmxhYmVscyA9ICJQZSIsIHByZWQubGFiZWxzID0gbGFiZWxzLCBzaG93LnN0YXQgPSBUUlVFLCBzaG93LmljYyA9IEZBTFNFLCBzaG93LnIyID0gRkFMU0UsDQogIHNob3cucmUudmFyID0gRkFMU0UsIHNob3cubmdyb3VwcyA9IEZBTFNFLCBtaW51cy5zaWduID0gIuKIkiIsIHN0cmluZy5wcmVkID0gIkZpeGVkIGVmZmVjdHMiLCANCiAgc3RyaW5nLmVzdCA9ICJiIiwgc3RyaW5nLnN0YXQgPSAidCIsIHN0cmluZy5jaSA9ICI5NSAlIENJIiwgcC52YWwgPSAic2F0dGVydGh3YWl0ZSIsIA0KICB0aXRsZSA9ICJSZXN1bHRzIG9mIHRoZSBMTU0gUHJlZGljdGluZyBQZSBBbXBsaXR1ZGUgYXMgYSBGdW5jdGlvbiBvZiBTdGltdWxhdGlvbiBDb25kaXRpb24gDQogIChDYXRob2RhbCAtIFNoYW0pIGFuZCBHcm91cCAoT0NEIC0gSGVhbHRoeSBDb250cm9scykiDQopDQoNCg0KIyBEaXNwbGF5IHJhbmRvbSBlZmZlY3RzDQpwcmludCgiUmFuZG9tIGVmZmVjdHM6IikNCnByaW50KFZhckNvcnIoTE1NX1BlKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQoNCg0KIyBTYXZlIG1vZGVsIG91dHB1dCBmb3IgcGxvdA0Kc2F2ZVJEUyhMTU1fUGUsIGZpbGUgPSAiLi9zYXZlZF9vYmplY3RzX2Zvcl9wbG90cy9MTU1fUGUucmRzIikNCmBgYA0KPGJyPjxicj4NCkFuYWx5c2lzIG9mIHRoZSBQZSBhbXBsaXR1ZGUgaW5kaWNhdGVkIHRoYXQgdGhpcyBjb21wb25lbnQgd2FzIGluY3JlYXNlZCBhZnRlciBjYXRob2RhbCB0RENTIHJlbGF0aXZlIHRvIHNoYW0gdERDUywgYXMgZXZpZGVuY2VkIGJ5IGEgc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2YgdERDUyBjb25kaXRpb24uIE5vIHNpZ25pZmljYW50IG1haW4gZWZmZWN0IG9mIGdyb3VwIGFuZCBubyBpbnRlcmFjdGlvbiBiZXR3ZWVuIGdyb3VwIGFuZCB0RENTIGNvbmRpdGlvbiB3ZXJlIG9ic2VydmVkLiANCjxicj48YnI+PGJyPg0KDQojIyBDb250cm9sIEFuYWx5c2VzDQoqKioNCg0KIyMjIE1lZGljYXRpb24gDQoNCldlIHBlcmZvcm1lZCBhZGRpdGlvbmFsIGNvbnRyb2wgYW5hbHlzZXMgdG8gZXhhbWluZSB3aGV0aGVyIHREQ1MgZWZmZWN0cyBvbiBFUlBzIHdlcmUgYWZmZWN0ZWQgYnkgcHN5Y2hvdHJvcGljIG1lZGljYXRpb24uIEluIHRoZXNlIGFuYWx5c2VzLCB3ZSBhY2NvdW50ZWQgZm9yIHBvc3NpYmxlIGNvbmZvdW5kaW5nIGVmZmVjdHMgb2YgcHN5Y2hvdHJvcGljIG1lZGljYXRpb24gYnkgcmVzcGVjaWZ5aW5nIHRoZSBmaXhlZCBlZmZlY3QgZ3JvdXAgYXMgYSBmYWN0b3Igd2l0aCB0aHJlZSBsZXZlbHMgKGNvbnRyb2wgcGFydGljaXBhbnRzLCBtZWRpY2F0ZWQgcGF0aWVudHMgd2l0aCBPQ0QsIHVubWVkaWNhdGVkIHBhdGllbnRzIHdpdGggT0NEKSwgd2hpY2ggd2FzIGNvZGVkIHVzaW5nIHNsaWRpbmcgZGlmZmVyZW5jZSBjb250cmFzdHMuIDxicj48YnI+DQpUaGlzIHRhYmxlIGNvcnJlc3BvbmRzIHRvIFRhYmxlIFM0IGluIHRoZSBzdXBwbGVtZW50YWwgbWF0ZXJpYWwuIA0KDQpgYGB7ciBMTU0tbWVkaWNhdGlvbiwgY2FjaGUgPSBrbml0cl9jYWNoZV9lbmFibGVkLCBmaWcud2lkdGggPSA1LCBmaWcuaGVpZ2h0ID0gNH0NCg0KIyBSdW0gbW9kZWwgRVJODQpMTU1fRVJOX21lZGljYXRpb24gPC0gbG1lcihNRk5fMF8xMDBfRkN6IH4gc3RpbXVsYXRpb24gKiBncm91cF9tZWRpY2F0aW9uICsNCiAgKDEgKyBzdGltdWxhdGlvbiB8IHBhcnRpY2lwYW50X2lkKSwNCmRhdGEgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbltzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlID09ICJpbmNvcnJlY3QiLCBdLA0KUkVNTCA9IFRSVUUsDQpjb250cm9sID0gbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopICMgQ29udmVyZ2VuY2UsIHNpbmd1bGFyaXR5LCBQQ0EgY2hlY2tlZCwgYWxsIG9rDQoNCg0KIyBSdW0gbW9kZWwgQ1JODQpMTU1fQ1JOX21lZGljYXRpb24gPC0gbG1lcihNRk5fMF8xMDBfRkN6IH4gc3RpbXVsYXRpb24gKiBncm91cF9tZWRpY2F0aW9uICsNCiAgKDEgKyBzdGltdWxhdGlvbiB8IHBhcnRpY2lwYW50X2lkKSwNCmRhdGEgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbltzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlID09ICJjb3JyZWN0IiwgXSwNClJFTUwgPSBUUlVFLA0KY29udHJvbCA9IGxtZXJDb250cm9sKG9wdGltaXplciA9ICJib2J5cWEiKQ0KKSAjIENvbnZlcmdlbmNlLCBzaW5ndWxhcml0eSwgUENBIGNoZWNrZWQsIGFsbCBvaw0KDQoNCiMgUnVtIG1vZGVsIFBlDQpMTU1fUGVfbWVkaWNhdGlvbiA8LSBsbWVyKFBlXzIwMF80MDBfUHogfiBzdGltdWxhdGlvbiAqIGdyb3VwX21lZGljYXRpb24gKw0KICAoMSArIHN0aW11bGF0aW9uIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImluY29ycmVjdCIsIF0sDQpSRU1MID0gVFJVRSwNCmNvbnRyb2wgPSBsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIikNCikgIyBDb252ZXJnZW5jZSwgc2luZ3VsYXJpdHksIFBDQSBjaGVja2VkLCBhbGwgb2sNCg0KDQojIERpc3BsYXkgcmVzdWx0cyAoZml4ZWQgZWZmZWN0cykgaW4gb25lIHRhYmxlDQp0YWJfbW9kZWwoTE1NX0VSTl9tZWRpY2F0aW9uLCBMTU1fQ1JOX21lZGljYXRpb24sIExNTV9QZV9tZWRpY2F0aW9uLA0KICBkdi5sYWJlbHMgPSBjKCJFUk4iLCAiQ1JOIiwgIlBlIiksIHByZWQubGFiZWxzID0gbGFiZWxzLCBzaG93LnN0YXQgPSBUUlVFLCBzaG93LmljYyA9IEZBTFNFLCANCiAgc2hvdy5yMiA9IEZBTFNFLCBzaG93LnJlLnZhciA9IEZBTFNFLCBzaG93Lm5ncm91cHMgPSBGQUxTRSwgbWludXMuc2lnbiA9ICLiiJIiLCBzdHJpbmcucHJlZCA9ICJGaXhlZCANCiAgZWZmZWN0cyIsIHN0cmluZy5lc3QgPSAiYiIsIHN0cmluZy5zdGF0ID0gInQiLCBzdHJpbmcuY2kgPSAiOTUgJSBDSSIsIHAudmFsID0gInNhdHRlcnRod2FpdGUiLCANCiAgdGl0bGUgPSAiUmVzdWx0cyBvZiB0aGUgTE1NcyBQcmVkaWN0aW5nIEVSTiwgQ1JOLCBhbmQgUGUgQW1wbGl0dWRlIGFzIGEgRnVuY3Rpb24gb2YgU3RpbXVsYXRpb24gDQogIENvbmRpdGlvbiAoQ2F0aG9kYWwgLSBTaGFtKSBhbmQgR3JvdXAgKE9DRG5vIG1lZCDigJMgSEM7IE9DRG1lZCAtIE9DRG5vIG1lZCkgdG8gRXhhbWluZSANCiAgRWZmZWN0cyBvZiBQc3ljaG90cm9waWMgTWVkaWNhdGlvbiINCikNCg0KDQojIERpc3BsYXkgcmFuZG9tIGVmZmVjdHMNCnByaW50KCJSYW5kb20gZWZmZWN0cyBFUk46IikNCnByaW50KFZhckNvcnIoTE1NX0VSTl9tZWRpY2F0aW9uKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQoNCnByaW50KCJSYW5kb20gZWZmZWN0cyBDUk46IikNCnByaW50KFZhckNvcnIoTE1NX0NSTl9tZWRpY2F0aW9uKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQoNCnByaW50KCJSYW5kb20gZWZmZWN0cyBQZToiKQ0KcHJpbnQoVmFyQ29ycihMTU1fUGVfbWVkaWNhdGlvbiksIGRpZ2l0cyA9IDMsIGNvbXAgPSAiU3RkLkRldi4iKQ0KYGBgDQo8YnI+PGJyPg0KUmVzdWx0cyByZW1haW5lZCB1bmNoYW5nZWQsIHdpdGggYSB0cmVuZCBmb3IgYSBtYWluIGVmZmVjdCBvZiB0RENTIG9uIEVSTiBhbXBsaXR1ZGUgYW5kIGEgc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2YgdERDUyBvbiBDUk4gYW5kIFBlIGFtcGxpdHVkZS4gDQo8YnI+PGJyPjxicj4NCg0KIyMjIFAzMDAgQW1wbGl0dWRlIHsudGFic2V0fQ0KDQojIyMjIFAzMDAgYXMgZGVwZW5kZW50IHZhcmlhYmxlIA0KDQpJbiBhbiBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgZml0dGVkIGEgTE1NIHdpdGggUDMwMCBhbXBsaXR1ZGUgYXMgZGVwZW5kZW50IHZhcmlhYmxlIHRvIGV4YW1pbmUgdGhlIHByZXNlbmNlIG9mIGFuIHREQ1MgZWZmZWN0IG9uIHRoaXMgc3RpbXVsdXMtbG9ja2VkIGNvbXBvbmVudC4gQm90aCBjb3JyZWN0IGFuZCBpbmNvcnJlY3QgdHJpYWxzIHdlcmUgaW5jbHVkZWQgaW4gdGhpcyBhbmFseXNpcy4gV2UgZW50ZXJlZCBncm91cCwgdERDUyBjb25kaXRpb24sIGFuZCByZXNwb25zZSB0eXBlIGFzIHByZWRpY3RvcnMuIDxicj48YnI+DQpUaGlzIHRhYmxlIGNvcnJlc3BvbmRzIHRvIFRhYmxlIFM1IGluIHRoZSBzdXBwbGVtZW50YWwgbWF0ZXJpYWwuIA0KDQpgYGB7ciBMTU0tUDMwMC1kdiwgY2FjaGUgPSBrbml0cl9jYWNoZV9lbmFibGVkfQ0KDQojIFJ1biBtb2RlbA0KTE1NX1AzIDwtIGxtZXIoUDNfMzAwXzUwMF9DUHogfiBzdGltdWxhdGlvbiAqIGdyb3VwICogcmVzcG9uc2VfdHlwZSAqDQogICgxICsgc3RpbXVsYXRpb24gKiByZXNwb25zZV90eXBlIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuLA0KUkVNTCA9IFRSVUUsDQpjb250cm9sID0gbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopDQoNCg0KIyBDaGVjayBtb2RlbCBvdXRwdXQgYW5kIFBDQSBvZiByYW5kb20tZWZmZWN0cyB2YXJpYW5jZS1jb3ZhcmlhbmNlIGVzdGltYXRlcw0KIyBzdW1tYXJ5KExNTV9QMykgICAgICAgICMgTW9kZWwgZG9lcyBjb252ZXJnZQ0KIyBpc1Npbmd1bGFyKExNTV9QMykgICAgICMgTm8gc2luZ3VsYXIgZml0DQojIHN1bW1hcnkocmVQQ0EoTE1NX1AzKSkgIyBBbGwgdGVybXMgZXhwbGFpbiB2YXJpYW5jZQ0KDQoNCiMgRGlzcGxheSByZXN1bHRzIChmaXhlZCBlZmZlY3RzKQ0KdGFiX21vZGVsKExNTV9QMywNCiAgZHYubGFiZWxzID0gIlAzMDAiLCBwcmVkLmxhYmVscyA9IGxhYmVscywgc2hvdy5zdGF0ID0gVFJVRSwgc2hvdy5pY2MgPSBGQUxTRSwgc2hvdy5yMiA9IEZBTFNFLA0KICBzaG93LnJlLnZhciA9IEZBTFNFLCBzaG93Lm5ncm91cHMgPSBGQUxTRSwgbWludXMuc2lnbiA9ICLiiJIiLCBzdHJpbmcucHJlZCA9ICJGaXhlZCBlZmZlY3RzIiwgDQogIHN0cmluZy5lc3QgPSAiYiIsIHN0cmluZy5zdGF0ID0gInQiLCBzdHJpbmcuY2kgPSAiOTUgJSBDSSIsIHAudmFsID0gInNhdHRlcnRod2FpdGUiLCB3cmFwLmxhYmVscyA9IDgwLA0KICB0aXRsZSA9ICJSZXN1bHRzIG9mIHRoZSBMTU0gUHJlZGljdGluZyBQMzAwIEFtcGxpdHVkZSBhcyBhIEZ1bmN0aW9uIG9mIFN0aW11bGF0aW9uIENvbmRpdGlvbiANCiAgKENhdGhvZGFsIC0gU2hhbSksIEdyb3VwIChPQ0QgLSBIZWFsdGh5IENvbnRyb2xzKSwgYW5kIFJlc3BvbnNlIFR5cGUgKEluY29ycmVjdCAtIENvcnJlY3QpIg0KKQ0KDQoNCiMgRGlzcGxheSByYW5kb20gZWZmZWN0cw0KcHJpbnQoIlJhbmRvbSBlZmZlY3RzIikNCnByaW50KFZhckNvcnIoTE1NX1AzKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQpgYGANCjxicj48YnI+DQpSZXN1bHRzIG9mIHRoaXMgZXhwbG9yYXRvcnkgYW5hbHlzaXMgaW5kaWNhdGVkIHRoYXQgdGhlIFAzMDAgYW1wbGl0dWRlIHdhcyBtb2R1bGF0ZWQgKGluY3JlYXNlZCkgYnkgdERDUy4gDQo8YnI+PGJyPjxicj4NCg0KIyMjIyBQMzAwIGFzIGNvdmFyaWF0ZSB7LmFjdGl2ZX0NCg0KSW4gYW4gYWRkaXRpb25hbCAobm9uLXByZXJlZ2lzdGVyZWQpIGFuYWx5c2lzLCB3ZSBpbmNsdWRlZCB0aGUgd2l0aGluLXBhcnRpY2lwYW50ICp6Ki1zdGFuZGFyZGl6ZWQgc2luZ2xlLXRyaWFsIFAzMDAgYW1wbGl0dWRlIGFzIGEgY292YXJpYXRlIGludG8gdGhlIGFuYWx5c2lzIG9mIHRoZSByZXNwb25zZS1sb2NrZWQgRVJQcy4gVGhlcmVieSwgd2UgYWltZWQgdG8gY29udHJvbCBmb3IgdmFyaWF0aW9uIGluIHRoZSBQMzAwIGFtcGxpdHVkZSwgc2luY2UgcmVzcG9uc2UtbG9ja2VkIEVSUHMgb2Z0ZW4gb3ZlcmxhcCB3aXRoIHRoaXMgc3RpbXVsdXMtbG9ja2VkIHBvc2l0aXZpdHksIHdoaWNoIG1ha2VzIGluZmVyZW5jZXMgYWJvdXQgZWZmZWN0cyBvbiByZXNwb25zZS1sb2NrZWQgY29tcG9uZW50cyBtb3JlIGRpZmZpY3VsdC4gU3BlY2lmaWNhbGx5LCB3ZSBhaW1lZCB0byBjb250cm9sIGZvciB0RENTLXJlbGF0ZWQgUDMwMCBkaWZmZXJlbmNlcywgc2luY2UgdGhlIGV4cGxvcmF0b3J5IGFuYWx5c2lzIGluZGljYXRlZCB0aGF0IHRoZSBQMzAwIHdhcyBtb2R1bGF0ZWQgYnkgdERDUyAoc2VlIHRhYiAiUDMwMCBhcyBkZXBlbmRlbnQgdmFyaWFibGUiKS4gPGJyPjxicj4NClRoaXMgdGFibGUgY29ycmVzcG9uZHMgdG8gVGFibGUgUzYgaW4gdGhlIHN1cHBsZW1lbnRhbCBtYXRlcmlhbC4gDQoNCmBgYHtyIExNTS1QMzAwLWNvdiwgY2FjaGUgPSBrbml0cl9jYWNoZV9lbmFibGVkfQ0KDQojIFJ1biBtb2RlbCBFUk4NCkxNTV9FUk5fUDMgPC0gbG1lcihNRk5fMF8xMDBfRkN6IH4gc3RpbXVsYXRpb24gKiBncm91cCAqIFAzXzMwMF81MDBfQ1B6X3N0YW5kYXJkaXplZCAgKw0KICAoMSArIHN0aW11bGF0aW9uIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImluY29ycmVjdCIsIF0sDQpSRU1MID0gVFJVRSwNCmNvbnRyb2wgPSBsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIikNCikgIyBDb252ZXJnZW5jZSwgc2luZ3VsYXJpdHksIFBDQSBjaGVja2VkLCBhbGwgb2sNCg0KDQojIFJ1biBtb2RlbCBDUk4NCkxNTV9DUk5fUDMgPC0gbG1lcihNRk5fMF8xMDBfRkN6IH4gc3RpbXVsYXRpb24gKiBncm91cCAqIFAzXzMwMF81MDBfQ1B6X3N0YW5kYXJkaXplZCAgKw0KICAoMSArIHN0aW11bGF0aW9uIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgPT0gImNvcnJlY3QiLCBdLA0KUkVNTCA9IFRSVUUsDQpjb250cm9sID0gbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopICMgQ29udmVyZ2VuY2UsIHNpbmd1bGFyaXR5LCBQQ0EgY2hlY2tlZCwgYWxsIG9rDQoNCg0KIyBSdW4gbW9kZWwgUGUNCkxNTV9QZV9QMyA8LSBsbWVyKFBlXzIwMF80MDBfUHogfiBzdGltdWxhdGlvbiAqIGdyb3VwICogUDNfMzAwXzUwMF9DUHpfc3RhbmRhcmRpemVkICArDQogICgxICsgc3RpbXVsYXRpb24gfCBwYXJ0aWNpcGFudF9pZCksDQpkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcmVzcG9uc2VfdHlwZSA9PSAiaW5jb3JyZWN0IiwgXSwNClJFTUwgPSBUUlVFLA0KY29udHJvbCA9IGxtZXJDb250cm9sKG9wdGltaXplciA9ICJib2J5cWEiKQ0KKSAjIENvbnZlcmdlbmNlLCBzaW5ndWxhcml0eSwgUENBIGNoZWNrZWQsIGFsbCBvaw0KDQoNCiMgRGlzcGxheSByZXN1bHRzIChmaXhlZCBlZmZlY3RzKSBpbiBvbmUgdGFibGUNCnRhYl9tb2RlbChMTU1fRVJOX1AzLCBMTU1fQ1JOX1AzLCBMTU1fUGVfUDMsDQogIGR2LmxhYmVscyA9IGMoIkVSTiIsICJDUk4iLCAiUGUiKSwgcHJlZC5sYWJlbHMgPSBsYWJlbHMsIHNob3cuc3RhdCA9IFRSVUUsIHNob3cuaWNjID0gRkFMU0UsIA0KICBzaG93LnIyID0gRkFMU0UsIHNob3cucmUudmFyID0gRkFMU0UsIHNob3cubmdyb3VwcyA9IEZBTFNFLCBtaW51cy5zaWduID0gIuKIkiIsIHN0cmluZy5wcmVkID0gIkZpeGVkIA0KICBlZmZlY3RzIiwgc3RyaW5nLmVzdCA9ICJiIiwgc3RyaW5nLnN0YXQgPSAidCIsIHN0cmluZy5jaSA9ICI5NSAlIENJIiwgcC52YWwgPSAic2F0dGVydGh3YWl0ZSIsIA0KICB0aXRsZSA9ICJSZXN1bHRzIG9mIHRoZSBMTU1zIFByZWRpY3RpbmcgRVJOLCBDUk4sIGFuZCBQZSBBbXBsaXR1ZGUgYXMgYSBGdW5jdGlvbiBvZiBTdGltdWxhdGlvbiANCiAgQ29uZGl0aW9uIChDYXRob2RhbCAtIFNoYW0pIGFuZCBHcm91cCAoT0NEIC0gSGVhbHRoeSBDb250cm9scykgV2l0aCBTaW5nbGUtVHJpYWwgUDMwMCBBbXBsaXR1ZGUgDQogIGFzIGEgQ292YXJpYXRlIg0KKQ0KDQoNCiMgRGlzcGxheSByYW5kb20gZWZmZWN0cw0KcHJpbnQoIlJhbmRvbSBlZmZlY3RzIEVSTjoiKQ0KcHJpbnQoVmFyQ29ycihMTU1fRVJOX1AzKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQoNCnByaW50KCJSYW5kb20gZWZmZWN0cyBDUk46IikNCnByaW50KFZhckNvcnIoTE1NX0NSTl9QMyksIGRpZ2l0cyA9IDMsIGNvbXAgPSAiU3RkLkRldi4iKQ0KDQpwcmludCgiUmFuZG9tIGVmZmVjdHMgUGU6IikNCnByaW50KFZhckNvcnIoTE1NX1BlX1AzKSwgZGlnaXRzID0gMywgY29tcCA9ICJTdGQuRGV2LiIpDQpgYGANCjxicj48YnI+DQpXaGVuIGluY2x1ZGluZyB0aGUgUDMwMCBhcyBhIGNvdmFyaWF0ZSBpbiB0aGUgTE1NcyBvbiBFUk4sIENSTiwgYW5kIFBlIGFtcGxpdHVkZSwgYSBzaWduaWZpY2FudCBtYWluIGVmZmVjdCBvZiB0aGUgUDMwMCB3YXMgb2JzZXJ2ZWQgaW4gYWxsIG1vZGVscy4gVGhlIGVmZmVjdCBvZiB0RENTIG9uIENSTiBhbmQgUGUgcmVtYWluZWQgc2lnbmlmaWNhbnQuIEltcG9ydGFudGx5LCB0aGUgdERDUy1pbmR1Y2VkIHJlZHVjdGlvbiBpbiBFUk4gYW1wbGl0dWRlLCBwcmV2aW91c2x5IHByZXNlbnQgYXMgYSBzdGF0aXN0aWNhbCB0cmVuZCwgd2FzIG5vdyBzaWduaWZpY2FudC4gVGhlIHNhbWUgYXBwbGllcyB0byB0aGUgZ3JvdXAgZGlmZmVyZW5jZSBpbiBFUk4gYW1wbGl0dWRlLCB3aGljaCBub3cgYWxzbyByZWFjaGVkIHNpZ25pZmljYW5jZS4gDQo8YnI+PGJyPjxicj4NCg0KIyMgUmVmZXJlbmNlcw0KKioqDQpCYXRlcywgRC4sIEtsaWVnbCwgUi4sIFZhc2lzaHRoLCBTLiwgJiBCYWF5ZW4sIEguICgyMDE1KS4gKlBhcnNpbW9uaW91cyBtaXhlZCBtb2RlbHMuKiBhclhpdi4gaHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzE1MDYuMDQ5Njd2MiA8YnI+PGJyPg0KQm94LCBHLiBFLiwgJiBDb3gsIEQuIFIuICgxOTY0KS4gQW4gYW5hbHlzaXMgb2YgdHJhbnNmb3JtYXRpb25zLiAqSm91cm5hbCBvZiB0aGUgUm95YWwgU3RhdGlzdGljYWwgU29jaWV0eTogU2VyaWVzIEIgKE1ldGhvZG9sb2dpY2FsKSwgMjYqKDIpLCAyMTEtMjQzLiBodHRwczovL2RvaS5vcmcvMTAuMTExMS9qLjI1MTctNjE2MS4xOTY0LnRiMDA1NTMueCA8YnI+PGJyPg0KTW9yZXksIFIuICgyMDA4KS4gQ29uZmlkZW5jZSBpbnRlcnZhbHMgZnJvbSBub3JtYWxpemVkIGRhdGE6IEEgY29ycmVjdGlvbiB0byBDb3VzaW5lYXUgKDIwMDUpLiAqVHV0b3JpYWxzIGluIFF1YW50aXRhdGl2ZSBNZXRob2RzIGZvciBQc3ljaG9sb2d5LCA0KigyKSwgNjEtNjQuIGh0dHBzOi8vZG9pLm9yZy8xMC4yMDk4Mi90cW1wLjA0LjIucDA2MSA8YnI+PGJyPg0KUmVpbmhhcnQsIFIuIE0uLCAmIFdvb2RtYW4sIEcuIEYuICgyMDE0KS4gQ2F1c2FsIGNvbnRyb2wgb2YgbWVkaWFs4oCTZnJvbnRhbCBjb3J0ZXggZ292ZXJucyBlbGVjdHJvcGh5c2lvbG9naWNhbCBhbmQgYmVoYXZpb3JhbCBpbmRpY2VzIG9mIHBlcmZvcm1hbmNlIG1vbml0b3JpbmcgYW5kIGxlYXJuaW5nLiAqSm91cm5hbCBvZiBOZXVyb3NjaWVuY2UsIDM0KigxMiksIDQyMTQtNDIyNy4gaHR0cHM6Ly9kb2kub3JnLzEwLjE1MjMvSk5FVVJPU0NJLjU0MjEtMTMuMjAxNCA8YnI+PGJyPg0KPGJyPjxicj4NCg0KIyMgU2Vzc2lvbiBJbmZvDQoqKioNCg0KYGBge3Igc2Vzc2lvbi1pbmZvfQ0KDQpzZXNzaW9uSW5mbygpDQpgYGANCg==