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 numeric accuracy variable (1 = correct, 0 = incorrect)
single_trial_data_clean <- single_trial_data_clean %>%
  dplyr::mutate(accuracy_numeric = ifelse(response_type == "correct", 1, 0))


# Create column with single-trial PES (RT post-error - RT pre-error for all CCEC sequences)
single_trial_data_clean$pes <- NA
for (i in 3:(nrow(single_trial_data_clean) - 1)) {
  if (single_trial_data_clean[i,       ]$response_type == "incorrect" &
      single_trial_data_clean[(i + 1), ]$response_type == "correct" &
      single_trial_data_clean[(i - 1), ]$response_type == "correct" &
      single_trial_data_clean[(i - 2), ]$response_type == "correct" &
      # Exclude sequences in which a trial was excluded in between
      single_trial_data_clean[(i + 1), ]$trial - single_trial_data_clean[(i - 1), ]$trial == 2) {
    single_trial_data_clean[i, ]$pes <- (single_trial_data_clean[(i + 1), ]$rt) - (single_trial_data_clean[(i - 1), ]$rt)
  }
}


# For each last first and trial in a block, PES cannot be determined; set these values to NA
single_trial_data_clean[single_trial_data_clean$trial == 1   |
  single_trial_data_clean$trial == 80  | single_trial_data_clean$trial == 81 |
  single_trial_data_clean$trial == 160 | single_trial_data_clean$trial == 161 |
  single_trial_data_clean$trial == 240 | single_trial_data_clean$trial == 241 |
  single_trial_data_clean$trial == 320 | single_trial_data_clean$trial == 321 |
  single_trial_data_clean$trial == 400 | single_trial_data_clean$trial == 401 |
  single_trial_data_clean$trial == 480, "pes"] <- NA


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

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. Please see section “ERP Data” for the percentage of excluded trials.


Descriptive Statistics


This table corresponds to Table 2 in the manuscript.

# Calculate descriptive statistics for RT
descriptive_statistics_rt <- summarySEwithinO(
  data          = single_trial_data_clean,
  measurevar    = "rt",
  withinvars    = c("response_type", "stimulation"),
  betweenvars   = "group",
  idvar         = "participant_id",
  conf.interval = .95
) %>% dplyr::rename(M = rt, M_norm = rt_norm) %>%
  dplyr::arrange(response_type) %>%
  dplyr::select(-response_type)


# Calculate descriptive statistics for PES
descriptive_statistics_pes <- summarySEwithinO(
  data          = single_trial_data_clean[!is.na(single_trial_data_clean$pes), ],
  measurevar    = "pes",
  withinvars    = "stimulation",
  betweenvars   = "group",
  idvar         = "participant_id",
  conf.interval = .95
) %>% dplyr::rename(M = pes, M_norm = pes_norm)


# Calculate descriptive statistics for accuracy
descriptive_statistics_accuracy <- summarySEwithinO(
  data          = single_trial_data_clean,
  measurevar    = "accuracy_numeric",
  withinvars    = "stimulation",
  betweenvars   = "group",
  idvar         = "participant_id",
  conf.interval = .95
) %>% dplyr::rename(M = accuracy_numeric, M_norm = accuracy_numeric_norm) %>%
  # Multiply numeric values by 100 to obtain values in percent
  dplyr::mutate_if(is.numeric, list(~ . * 100))


# Combine measures
descriptive_statistics <- as.data.frame(rbind(descriptive_statistics_rt,
  descriptive_statistics_pes, descriptive_statistics_accuracy))


# Label measures
descriptive_statistics$Measure <- c(rep("RT correct (ms)", 4), rep("RT error (ms)", 4), 
                                    rep("PES (ms)", 4), rep("Accuracy (%)", 4))


# Create column with format "M [CI]" for RT and PES (round to 0 decimals)
descriptive_statistics$M_CI <- paste0(round(descriptive_statistics$M, 0), " [",
  round(descriptive_statistics$M - descriptive_statistics$ci, 0), ", ",
  round(descriptive_statistics$M + descriptive_statistics$ci, 0), "]")


# Create column with format "M [CI]" for accuracy (round to 2 decimals)
descriptive_statistics[c(13:16), ]$M_CI <- paste0(
  format(round(descriptive_statistics[c(13:16), ]$M,  2), nsmall = 2), " [",
  format(round(descriptive_statistics[c(13:16), ]$M -
               descriptive_statistics[c(13:16), ]$ci, 2), nsmall = 2), ", ",
  format(round(descriptive_statistics[c(13:16), ]$M +
               descriptive_statistics[c(13:16), ]$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 = "Behavioral 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). 
  RT = response time; PES = post-error slowing.")) %>%
  add_header_above(c(" " = 1, "Sham tDCS" = 2, "Cathodal tDCS" = 2))
Behavioral 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]
RT correct (ms) 416 [415, 418] 401 [400, 403] 411 [410, 412] 403 [401, 404]
RT error (ms) 346 [341, 352] 341 [335, 346] 345 [340, 350] 335 [330, 340]
PES (ms) 40 [28, 51] 29 [20, 39] 39 [29, 50] 32 [21, 42]
Accuracy (%) 94.68 [94.14, 95.21] 93.24 [92.64, 93.84] 94.14 [93.57, 94.70] 93.51 [92.92, 94.10]
Note:
CIs are adjusted for within-participant designs (Morey, 2008).
RT = response time; PES = post-error slowing.



(G)LMM Analyses


We analyzed behavioral performance (response time, post-error slowing, and response accuracy) using (generalized) linear mixed models ([G]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.

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


# Prepare labels for (G)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"
)



Response Time

Determine data transformation

Response time was log-transformed prior to analysis to meet the assumption of normally distributed residuals. The appropriate transformation 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_rt <- boxcox(rt ~ 1, data = single_trial_data_clean)
optlambda_rt <- bc_rt$x[which.max(bc_rt$y)]


# Density plot for log-transformed RT values
plot(density(single_trial_data_clean$rt_log), main = "Log RT: Density  Plot")


# Q-q plot for log-transformed RT values
qqnorm(single_trial_data_clean$rt_log, main = "Log RT: Q-Q Plot", pch = 1)

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

The optimal lambda is -0.38, suggesting that log transformation is appropriate.


LMM

We analyzed response time data using a LMM with response type (correct, error), group, and tDCS condition as predictors.

This table corresponds to Table S1 in the supplemental material.

# Run model
LMM_rt <- lmer(rt_log ~ 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_rt)        # Model does converge
# isSingular(LMM_rt)     # No singular fit
# summary(rePCA(LMM_rt)) # All terms explain variance


# Display results (fixed effects)
tab_model(LMM_rt,
  dv.labels = "log(RT)", 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 RT 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_rt), digits = 1, comp = "Std.Dev.")
Results of the LMM Predicting RT as a Function of Stimulation Condition (Cathodal - Sham), Group (OCD - Healthy Controls), and Response Type (Incorrect - Correct)
  log(RT)
Fixed effects b 95 % CI t p
Intercept 5.91 5.89 – 5.93 568.05 <0.001
Stimulation -0.00 -0.02 – 0.01 -0.53 0.599
Group 0.02 -0.02 – 0.06 0.99 0.328
Response type -0.17 -0.19 – -0.15 -16.46 <0.001
Stimulation x Group 0.00 -0.03 – 0.03 0.00 1.000
Stimulation x Response type 0.00 -0.02 – 0.02 0.14 0.890
Group x Response type -0.02 -0.06 – 0.02 -0.80 0.426
Stimulation x Group x Response type 0.03 -0.01 – 0.07 1.68 0.099
Observations 53093
[1] "Random effects:"
 Groups         Name                            Std.Dev. Corr             
 participant_id (Intercept)                     0.08                      
                stimulation2-1                  0.05      0.04            
                response_type2-1                0.07      0.03  0.17      
                stimulation2-1:response_type2-1 0.06     -0.12  0.04 -0.18
 Residual                                       0.17                      



Response time analysis revealed a significant main effect of response type, indicating that responses were faster for errors than for correct responses. Response time did not differ significantly between groups or tDCS conditions and there was no significant interaction between any of the factors.


Post-Error Slowing

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_pes <- boxcox(pes + 1000 ~ 1, data = single_trial_data_clean[!is.na(single_trial_data_clean$pes), ])
optlambda_pes <- bc_pes$x[which.max(bc_pes$y)]


# Density plot for PES values
plot(density(single_trial_data_clean[!is.na(single_trial_data_clean$pes), ]$pes), main = "PES: Density  Plot")


# Q-q plot for PES values
qqnorm(single_trial_data_clean[!is.na(single_trial_data_clean$pes), ]$pes, main = "PES: 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

For the analysis of PES, we fitted a LMM on single-trial values that were calculated as the response time difference between correct responses that directly preceded and followed an error. This PES quantification results in a measure that is not confounded by fluctuations in motivation or response caution over time (Dutilh et al., 2012). In this analysis, we considered only error trials that were preceded by at least two correct trials and followed by at least one correct trial. Model estimates of the LMM on PES directly reflect mean differences in milliseconds.

This table corresponds to Table S2 in the supplemental material.

# Run model
LMM_pes <- lmer(pes ~ stimulation * group +
  (1 + stimulation | participant_id),
data = single_trial_data_clean[!is.na(single_trial_data_clean$pes), ],
REML = TRUE,
control = lmerControl(optimizer = "bobyqa")
)


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


# Display results (fixed effects)
tab_model(LMM_pes,
  dv.labels = "PES", 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 PES as a Function of Stimulation Condition 
  (Cathodal - Sham) and Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(LMM_pes), digits = 4, comp = "Std.Dev.")
Results of the LMM Predicting PES as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCD - Healthy Controls)
  PES
Fixed effects b 95 % CI t p
Intercept 35.71 29.40 – 42.02 11.09 <0.001
Stimulation 1.08 -8.73 – 10.89 0.22 0.830
Group 9.59 -3.03 – 22.21 1.49 0.142
Stimulation x Group -3.08 -22.70 – 16.54 -0.31 0.760
Observations 2622
[1] "Random effects:"
 Groups         Name           Std.Dev. Corr 
 participant_id (Intercept)    19.17         
                stimulation2-1 23.80    -0.02
 Residual                      95.82         



The LMM on PES yielded a significant intercept, reflecting that participants slowed down after error commission. The groups did not differ significantly in PES. There was no significant main effect of tDCS condition and no interaction between group and tDCS condition.


Response Accuracy

Response accuracy was analyzed using a binomial generalized linear mixed model (GLMM). For the GLMM on accuracy, estimates reflect odds ratios for a correct response.

This table corresponds to Table S2 in the supplemental material.

# Run model
GLMM_accuracy <- glmer(accuracy_numeric ~ stimulation * group +
  (1 + stimulation | participant_id),
data = single_trial_data_clean,
family = binomial,
control = glmerControl(optimizer = "bobyqa")
)


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


# Display results (fixed effects)
tab_model(GLMM_accuracy,
  dv.labels = "Accuracy", 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 = "Odds ratio", string.stat = "z", string.ci = "95 % CI", title = "Results of the Binomial GLMM 
  Predicting Response Accuracy as a Function of Stimulation Condition (Cathodal - Sham) and 
  Group (OCD - Healthy Controls)"
)


# Display random effects
print("Random effects:")
print(VarCorr(GLMM_accuracy), digits = 2, comp = "Std.Dev.")
Results of the Binomial GLMM Predicting Response Accuracy as a Function of Stimulation Condition (Cathodal - Sham) and Group (OCD - Healthy Controls)
  Accuracy
Fixed effects Odds ratio 95 % CI z p
Intercept 16.45 14.84 – 18.24 53.10 <0.001
Stimulation 0.97 0.88 – 1.07 -0.56 0.573
Group 1.18 0.96 – 1.44 1.54 0.123
Stimulation x Group 0.84 0.70 – 1.02 -1.71 0.087
Observations 53093
[1] "Random effects:"
 Groups         Name           Std.Dev. Corr
 participant_id (Intercept)    0.37         
                stimulation2-1 0.24     0.01



Results of the GLMM indicated that there was no significant difference in response accuracy between groups or tDCS conditions and no significant interaction between group and tDCS condition.


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

Dutilh, G., van Ravenzwaaij, D., Nieuwenhuis, S., van der Maas, H. L. J., Forstmann, B. U., & Wagenmakers, E.-J. (2012). How to measure post-error slowing: A confound and a simple solution. Journal of Mathematical Psychology, 56(3), 208-216. https://doi.org/10.1016/j.jmp.2012.04.001

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



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       sjPlot_2.8.6     lmerTest_3.1-3   lme4_1.1-25     
[5] Matrix_1.2-17    MASS_7.3-53      kableExtra_1.3.1 knitr_1.30      
[9] 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          ggplot2_3.3.2      
[13] pillar_1.6.0        rlang_0.4.11        rstudioapi_0.11    
[16] minqa_1.2.4         performance_0.7.1.1 nloptr_1.2.2.2     
[19] effectsize_0.4.0    rmarkdown_2.5       ggeffects_0.16.0   
[22] splines_3.6.1       webshot_0.5.2       statmod_1.4.35     
[25] stringr_1.4.0       munsell_0.5.0       broom_0.7.2        
[28] modelr_0.1.8        compiler_3.6.1      numDeriv_2016.8-1.1
[31] xfun_0.19           pkgconfig_2.0.3     parameters_0.13.0  
[34] htmltools_0.5.0     insight_0.14.0      tidyselect_1.1.0   
[37] tibble_3.0.4        codetools_0.2-16    fansi_0.4.1        
[40] viridisLite_0.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         xml2_1.3.2         
[55] ellipsis_0.3.2      generics_0.1.0      vctrs_0.3.8        
[58] boot_1.3-22         sjlabelled_1.1.7    tools_3.6.1        
[61] glue_1.4.2          purrr_0.3.4         sjstats_0.18.0     
[64] emmeans_1.5.2-1     yaml_2.2.1          colorspace_1.4-1   
[67] rvest_1.0.2        
LS0tDQp0aXRsZTogIkJlaGF2aW9yYWwgRGF0YSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQNCi0tLQ0KDQo8IS0tIFNldCBnZW5lcmFsIHNldHRpbmdzIC0tPg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KDQojIFNldCBnZW5lcmFsIHNldHRpbmdzIGZvciBtYXJrZG93biBmaWxlDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICBjb21tZW50ID0gIiIsDQogIHJlc3VsdHMgPSAiaG9sZCINCikNCg0KDQojIENsZWFyIGVudmlyb25tZW50DQpybShsaXN0ID0gbHMoKSkNCg0KDQojIEVuYWJsZS9kaXNhYmxlIGNhY2hpbmcgb2YgdGltZS1jb25zdW1pbmcgY29kZSBjaHVua3MNCmtuaXRyX2NhY2hlX2VuYWJsZWQgPSBUUlVFDQoNCg0KIyBMb2FkIHBhY2thZ2VzDQpsaWJyYXJ5KGRwbHlyKSAgICAgICMgZm9yIGRhdGEgd3JhbmdsaW5nDQpsaWJyYXJ5KGtuaXRyKSAgICAgICMgZm9yIGludGVncmF0aW5nIGNvbXB1dGluZyBhbmQgcmVwb3J0aW5nIGluIG1hcmtkb3duDQpsaWJyYXJ5KGthYmxlRXh0cmEpICMgZm9yIGN1c3RvbWl6aW5nIGFwcGVhcmFuY2Ugb2YgdGFibGVzDQpsaWJyYXJ5KE1BU1MpICAgICAgICMgZm9yIGJveGNveCBmdW5jdGlvbiBhbmQgY29udHJhc3QgZGVmaW5pdGlvbg0KbGlicmFyeShsbWU0KSAgICAgICAjIGZvciAoRylMTU1zDQpsaWJyYXJ5KGxtZXJUZXN0KSAgICMgZm9yIExNTSBwIHZhbHVlcyAoU2F0dGVydGh3YWl0ZSdzIG1ldGhvZCBmb3IgYXBwcm94aW1hdGluZyBkZnMgZm9yIHQgYW5kIEYgdGVzdHMpDQpsaWJyYXJ5KHNqUGxvdCkgICAgICMgZm9yIHRhYl9tb2RlbCBmdW5jdGlvbiB0byBkaXNwbGF5IChHKUxNTSByZXN1bHRzDQoNCg0KIyBMb2FkIGZ1bmN0aW9ucw0Kc291cmNlKCIuL2Z1bmN0aW9ucy9zdW1tYXJ5U0V3aXRoaW5PLlIiKSAgIyBGdW5jdGlvbiBwcm92aWRlZCBieSBSLWNvb2tib29rOiBodHRwOi8vd3d3LmNvb2tib29rLXIuY29tL0dyYXBocy9QbG90dGluZ19tZWFuc19hbmRfZXJyb3JfYmFyc18oZ2dwbG90MikvDQpzb3VyY2UoIi4vZnVuY3Rpb25zL215X3RhYmxlX3RlbXBsYXRlLlIiKSAjIEZ1bmN0aW9uIHRvIGNyZWF0ZSB0YWJsZSB0ZW1wbGF0ZQ0KDQoNCiMgVHVybiBvZmYgc2NpZW50aWZpYyBub3RhdGlvbg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpDQpgYGANCjxicj48YnI+IA0KDQojIyBEYXRhIENsZWFuaW5nDQoqKioNCg0KYGBge3IgbG9hZC1hbmQtY2xlYW4tZGF0YX0NCg0KIyBMb2FkIGRhdGENCmxvYWQoZmlsZSA9ICIuL2RhdGEvU2luZ2xlX1RyaWFsX0RhdGEucmRhIikNCg0KDQojIEV4Y2x1ZGUgbWlzc2luZyByZXNwb25zZXMsIFJUIG91dGxpZXJzLCBhbmQgdHJpYWxzIHdpdGggRVJQIGFydGlmYWN0cw0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4gPC0gc2luZ2xlX3RyaWFsX2RhdGEgJT4lDQogIGRwbHlyOjpmaWx0ZXIoDQogICAgICByZXNwb25zZV90eXBlICE9ICJtaXNzIiAmDQogICAgICBydF9pbnZhbGlkICAgID09IEZBTFNFICYNCiAgICAgICFpcy5uYShNRk5fMF8xMDBfRkN6KQ0KICApICMgKDUzMDkzIG9mIDUzNzYwIHRyaWFscyBsZWZ0KQ0KDQoNCiMgQ3JlYXRlIG51bWVyaWMgYWNjdXJhY3kgdmFyaWFibGUgKDEgPSBjb3JyZWN0LCAwID0gaW5jb3JyZWN0KQ0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4gPC0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4gJT4lDQogIGRwbHlyOjptdXRhdGUoYWNjdXJhY3lfbnVtZXJpYyA9IGlmZWxzZShyZXNwb25zZV90eXBlID09ICJjb3JyZWN0IiwgMSwgMCkpDQoNCg0KIyBDcmVhdGUgY29sdW1uIHdpdGggc2luZ2xlLXRyaWFsIFBFUyAoUlQgcG9zdC1lcnJvciAtIFJUIHByZS1lcnJvciBmb3IgYWxsIENDRUMgc2VxdWVuY2VzKQ0Kc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcGVzIDwtIE5BDQpmb3IgKGkgaW4gMzoobnJvdyhzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbikgLSAxKSkgew0KICBpZiAoc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5baSwgICAgICAgXSRyZXNwb25zZV90eXBlID09ICJpbmNvcnJlY3QiICYNCiAgICAgIHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuWyhpICsgMSksIF0kcmVzcG9uc2VfdHlwZSA9PSAiY29ycmVjdCIgJg0KICAgICAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bKGkgLSAxKSwgXSRyZXNwb25zZV90eXBlID09ICJjb3JyZWN0IiAmDQogICAgICBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhblsoaSAtIDIpLCBdJHJlc3BvbnNlX3R5cGUgPT0gImNvcnJlY3QiICYNCiAgICAgICMgRXhjbHVkZSBzZXF1ZW5jZXMgaW4gd2hpY2ggYSB0cmlhbCB3YXMgZXhjbHVkZWQgaW4gYmV0d2Vlbg0KICAgICAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bKGkgKyAxKSwgXSR0cmlhbCAtIHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuWyhpIC0gMSksIF0kdHJpYWwgPT0gMikgew0KICAgIHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW2ksIF0kcGVzIDwtIChzaW5nbGVfdHJpYWxfZGF0YV9jbGVhblsoaSArIDEpLCBdJHJ0KSAtIChzaW5nbGVfdHJpYWxfZGF0YV9jbGVhblsoaSAtIDEpLCBdJHJ0KQ0KICB9DQp9DQoNCg0KIyBGb3IgZWFjaCBsYXN0IGZpcnN0IGFuZCB0cmlhbCBpbiBhIGJsb2NrLCBQRVMgY2Fubm90IGJlIGRldGVybWluZWQ7IHNldCB0aGVzZSB2YWx1ZXMgdG8gTkENCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuW3NpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHRyaWFsID09IDEgICB8DQogIHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHRyaWFsID09IDgwICB8IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHRyaWFsID09IDgxIHwNCiAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gMTYwIHwgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gMTYxIHwNCiAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gMjQwIHwgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gMjQxIHwNCiAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gMzIwIHwgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gMzIxIHwNCiAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gNDAwIHwgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gNDAxIHwNCiAgc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kdHJpYWwgPT0gNDgwLCAicGVzIl0gPC0gTkENCg0KDQojIE1ha2UgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGZhY3RvcnMNCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHBhcnRpY2lwYW50X2lkIDwtIGZhY3RvcihzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRwYXJ0aWNpcGFudF9pZCkNCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJGdyb3VwICAgICAgICAgIDwtIGZhY3RvcihzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRncm91cCkNCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHN0aW11bGF0aW9uICAgIDwtIGZhY3RvcihzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRzdGltdWxhdGlvbikNCnNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJlc3BvbnNlX3R5cGUgIDwtIGZhY3RvcihzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlKQ0KYGBgDQoNClRyaWFscyB3aXRoIGEgcmVzcG9uc2UgdGltZSBiZWxvdyAxMDAgbXMgb3IgYWJvdmUgODAwIG1zIG9yIHdpdGggYSBtaXNzaW5nIHJlc3BvbnNlIHdlcmUgZXhjbHVkZWQgZnJvbSBhbGwgYW5hbHlzZXMuIFdlIGZ1cnRoZXIgZGlzY2FyZGVkIHRyaWFscyBjb250YWluaW5nIGFydGlmYWN0cyBpbiB0aGUgRUVHLCB0aGF0IGlzLCBhIHZvbHRhZ2UgY2hhbmdlIGV4Y2VlZGluZyA1MCDOvFYgYmV0d2VlbiBzYW1wbGUgcG9pbnRzIG9yIDIwMCDOvFYgd2l0aGluIGFuIGVwb2NoLiBQbGVhc2Ugc2VlIHNlY3Rpb24gIkVSUCBEYXRhIiBmb3IgdGhlIHBlcmNlbnRhZ2Ugb2YgZXhjbHVkZWQgdHJpYWxzLg0KPGJyPjxicj48YnI+DQoNCiMjIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MgDQoqKioNCg0KVGhpcyB0YWJsZSBjb3JyZXNwb25kcyB0byBUYWJsZSAyIGluIHRoZSBtYW51c2NyaXB0Lg0KDQpgYGB7ciBkZXNjcmlwdGl2ZS1zdGF0aXN0aWNzLXRhYmxlfQ0KDQojIENhbGN1bGF0ZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGZvciBSVA0KZGVzY3JpcHRpdmVfc3RhdGlzdGljc19ydCA8LSBzdW1tYXJ5U0V3aXRoaW5PKA0KICBkYXRhICAgICAgICAgID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4sDQogIG1lYXN1cmV2YXIgICAgPSAicnQiLA0KICB3aXRoaW52YXJzICAgID0gYygicmVzcG9uc2VfdHlwZSIsICJzdGltdWxhdGlvbiIpLA0KICBiZXR3ZWVudmFycyAgID0gImdyb3VwIiwNCiAgaWR2YXIgICAgICAgICA9ICJwYXJ0aWNpcGFudF9pZCIsDQogIGNvbmYuaW50ZXJ2YWwgPSAuOTUNCikgJT4lIGRwbHlyOjpyZW5hbWUoTSA9IHJ0LCBNX25vcm0gPSBydF9ub3JtKSAlPiUNCiAgZHBseXI6OmFycmFuZ2UocmVzcG9uc2VfdHlwZSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoLXJlc3BvbnNlX3R5cGUpDQoNCg0KIyBDYWxjdWxhdGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBmb3IgUEVTDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX3BlcyA8LSBzdW1tYXJ5U0V3aXRoaW5PKA0KICBkYXRhICAgICAgICAgID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bIWlzLm5hKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHBlcyksIF0sDQogIG1lYXN1cmV2YXIgICAgPSAicGVzIiwNCiAgd2l0aGludmFycyAgICA9ICJzdGltdWxhdGlvbiIsDQogIGJldHdlZW52YXJzICAgPSAiZ3JvdXAiLA0KICBpZHZhciAgICAgICAgID0gInBhcnRpY2lwYW50X2lkIiwNCiAgY29uZi5pbnRlcnZhbCA9IC45NQ0KKSAlPiUgZHBseXI6OnJlbmFtZShNID0gcGVzLCBNX25vcm0gPSBwZXNfbm9ybSkNCg0KDQojIENhbGN1bGF0ZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGZvciBhY2N1cmFjeQ0KZGVzY3JpcHRpdmVfc3RhdGlzdGljc19hY2N1cmFjeSA8LSBzdW1tYXJ5U0V3aXRoaW5PKA0KICBkYXRhICAgICAgICAgID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4sDQogIG1lYXN1cmV2YXIgICAgPSAiYWNjdXJhY3lfbnVtZXJpYyIsDQogIHdpdGhpbnZhcnMgICAgPSAic3RpbXVsYXRpb24iLA0KICBiZXR3ZWVudmFycyAgID0gImdyb3VwIiwNCiAgaWR2YXIgICAgICAgICA9ICJwYXJ0aWNpcGFudF9pZCIsDQogIGNvbmYuaW50ZXJ2YWwgPSAuOTUNCikgJT4lIGRwbHlyOjpyZW5hbWUoTSA9IGFjY3VyYWN5X251bWVyaWMsIE1fbm9ybSA9IGFjY3VyYWN5X251bWVyaWNfbm9ybSkgJT4lDQogICMgTXVsdGlwbHkgbnVtZXJpYyB2YWx1ZXMgYnkgMTAwIHRvIG9idGFpbiB2YWx1ZXMgaW4gcGVyY2VudA0KICBkcGx5cjo6bXV0YXRlX2lmKGlzLm51bWVyaWMsIGxpc3QofiAuICogMTAwKSkNCg0KDQojIENvbWJpbmUgbWVhc3VyZXMNCmRlc2NyaXB0aXZlX3N0YXRpc3RpY3MgPC0gYXMuZGF0YS5mcmFtZShyYmluZChkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX3J0LA0KICBkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX3BlcywgZGVzY3JpcHRpdmVfc3RhdGlzdGljc19hY2N1cmFjeSkpDQoNCg0KIyBMYWJlbCBtZWFzdXJlcw0KZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRNZWFzdXJlIDwtIGMocmVwKCJSVCBjb3JyZWN0IChtcykiLCA0KSwgcmVwKCJSVCBlcnJvciAobXMpIiwgNCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJQRVMgKG1zKSIsIDQpLCByZXAoIkFjY3VyYWN5ICglKSIsIDQpKQ0KDQoNCiMgQ3JlYXRlIGNvbHVtbiB3aXRoIGZvcm1hdCAiTSBbQ0ldIiBmb3IgUlQgYW5kIFBFUyAocm91bmQgdG8gMCBkZWNpbWFscykNCmRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkTV9DSSA8LSBwYXN0ZTAocm91bmQoZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRNLCAwKSwgIiBbIiwNCiAgcm91bmQoZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRNIC0gZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRjaSwgMCksICIsICIsDQogIHJvdW5kKGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkTSArIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkY2ksIDApLCAiXSIpDQoNCg0KIyBDcmVhdGUgY29sdW1uIHdpdGggZm9ybWF0ICJNIFtDSV0iIGZvciBhY2N1cmFjeSAocm91bmQgdG8gMiBkZWNpbWFscykNCmRlc2NyaXB0aXZlX3N0YXRpc3RpY3NbYygxMzoxNiksIF0kTV9DSSA8LSBwYXN0ZTAoDQogIGZvcm1hdChyb3VuZChkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzW2MoMTM6MTYpLCBdJE0sICAyKSwgbnNtYWxsID0gMiksICIgWyIsDQogIGZvcm1hdChyb3VuZChkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzW2MoMTM6MTYpLCBdJE0gLQ0KICAgICAgICAgICAgICAgZGVzY3JpcHRpdmVfc3RhdGlzdGljc1tjKDEzOjE2KSwgXSRjaSwgMiksIG5zbWFsbCA9IDIpLCAiLCAiLA0KICBmb3JtYXQocm91bmQoZGVzY3JpcHRpdmVfc3RhdGlzdGljc1tjKDEzOjE2KSwgXSRNICsNCiAgICAgICAgICAgICAgIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3NbYygxMzoxNiksIF0kY2ksIDIpLCBuc21hbGwgPSAyKSwgIl0iKQ0KDQoNCiMgU2VsZWN0IHJlbGV2YW50IGNvbHVtbnMNCmRlc2NyaXB0aXZlX3N0YXRpc3RpY3MgPC0gZGVzY3JpcHRpdmVfc3RhdGlzdGljc1ssIGMgKCJncm91cCIsICJzdGltdWxhdGlvbiIsICJNZWFzdXJlIiwgIk1fQ0kiKV0NCg0KDQoNCiMgU3BsaXQgYW5kIHJlLW1lcmdlIHRhYmxlIHRvIGRpc3BsYXkgYm90aCBncm91cHMgbmV4dCB0byBlYWNoIG90aGVyDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzIDwtIHNwbGl0KGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MsIGxpc3QoZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRzdGltdWxhdGlvbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpdmVfc3RhdGlzdGljcyRncm91cCkpDQpkZXNjcmlwdGl2ZV9zdGF0aXN0aWNzX2Rpc3BsYXkgPC0gY2JpbmQoDQogIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3Mkc2hhbS5PQ0RbLCBjKCJNZWFzdXJlIiwgIk1fQ0kiKV0sDQogIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3Mkc2hhbS5IQ1ssICJNX0NJIl0sDQogIGRlc2NyaXB0aXZlX3N0YXRpc3RpY3MkdmVydW0uT0NEWywgIk1fQ0kiXSwNCiAgZGVzY3JpcHRpdmVfc3RhdGlzdGljcyR2ZXJ1bS5IQ1ssICJNX0NJIl0NCikNCg0KDQojIERpc3BsYXkgdGFibGUNCm15X3RhYmxlX3RlbXBsYXRlKGRlc2NyaXB0aXZlX3N0YXRpc3RpY3NfZGlzcGxheSwNCiAgY2FwdGlvbiA9ICJCZWhhdmlvcmFsIE1lYXN1cmVzIGluIFBhdGllbnRzIFdpdGggT0NEIGFuZCBIQyBQYXJ0aWNpcGFudHMiLA0KICBjb2xfbmFtZXMgPSBjKCIgIiwgcmVwKCJNIFs5NSUgQ0ldIiwgNCkpLA0KICBoZWFkZXJfYWJvdmVfY29uZmlnID0gYygiICIsIHJlcChjKCJQYXRpZW50cyB3aXRoIE9DRCIsICJIQyBwYXJ0aWNpcGFudHMiKSwgMikpLA0KICBmb290bm90ZV9jb25maWcgPSBjKGdlbmVyYWwgPSAiQ0lzIGFyZSBhZGp1c3RlZCBmb3Igd2l0aGluLXBhcnRpY2lwYW50IGRlc2lnbnMgKE1vcmV5LCAyMDA4KS4gDQogIFJUID0gcmVzcG9uc2UgdGltZTsgUEVTID0gcG9zdC1lcnJvciBzbG93aW5nLiIpKSAlPiUNCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiA9IDEsICJTaGFtIHREQ1MiID0gMiwgIkNhdGhvZGFsIHREQ1MiID0gMikpDQpgYGANCjxicj48YnI+DQoNCiMjIChHKUxNTSBBbmFseXNlcw0KKioqDQoNCldlIGFuYWx5emVkIGJlaGF2aW9yYWwgcGVyZm9ybWFuY2UgKHJlc3BvbnNlIHRpbWUsIHBvc3QtZXJyb3Igc2xvd2luZywgYW5kIHJlc3BvbnNlIGFjY3VyYWN5KSB1c2luZyAoZ2VuZXJhbGl6ZWQpIGxpbmVhciBtaXhlZCBtb2RlbHMgKFtHXUxNTXMpIG9uIHNpbmdsZS10cmlhbCBkYXRhLiBXZSB0ZXN0ZWQgd2hldGhlciBncm91cCBkaWZmZXJlbmNlcyBhbmQgdERDUyBlZmZlY3RzIHdlcmUgcHJlc2VudC4gR3JvdXAgKGhlYWx0aHkgY29udHJvbHMsIE9DRCkgYW5kIHREQ1MgY29uZGl0aW9uIChjYXRob2RhbCwgc2hhbSkgd2VyZSBpbmNsdWRlZCBhcyBmaXhlZCBlZmZlY3RzIGluIGFsbCBtb2RlbHMuIEFsbCBjYXRlZ29yaWNhbCBmaXhlZCBlZmZlY3RzIHdlcmUgZWZmZWN0LWNvZGVkIChjb250cmFzdCBjb2VmZmljaWVudHMg4oiSMC41IGFuZCAwLjUpLiANCg0KV2UgZGV0ZXJtaW5lZCB0aGUgcmFuZG9tLWVmZmVjdHMgc3RydWN0dXJlIGZvciBlYWNoIG1vZGVsIGJhc2VkIG9uIHRoZSBwcm9jZWR1cmUgcHJvcG9zZWQgYnkgQmF0ZXMgZXQgYWwuICgyMDE1KSwgc3RhcnRpbmcgd2l0aCB0aGUgbWF4aW1hbCByYW5kb20tZWZmZWN0cyBzdHJ1Y3R1cmUganVzdGlmaWVkIGJ5IHRoZSBkZXNpZ24sIHdpdGggYnktcGFydGljaXBhbnQgcmFuZG9tIGludGVyY2VwdHMgYW5kIHJhbmRvbSBzbG9wZXMgZm9yIGFsbCBmaXhlZCBmYWN0b3JzIGFuZCAod2hlcmUgYXBwbGljYWJsZSkgdGhlaXIgaW50ZXJhY3Rpb25zLiBJZiByZXF1aXJlZCBmb3IgbW9kZWwgY29udmVyZ2VuY2UsIGNvcnJlbGF0aW9uIHBhcmFtZXRlcnMgb2YgdGhlIHJhbmRvbSB0ZXJtcyB3ZXJlIHNldCB0byB6ZXJvLiBSYW5kb20gZWZmZWN0cyBwcmV2ZW50aW5nIG1vZGVsIGNvbnZlcmdlbmNlIG9yIGV4cGxhaW5pbmcgemVybyB2YXJpYW5jZSBhcyBkZXRlcm1pbmVkIGJ5IHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgd2VyZSByZW1vdmVkIHRvIGF2b2lkIG92ZXJwYXJhbWV0ZXJpemF0aW9uLg0KDQpgYGB7ciAoRylMTU0tY29udHJhc3QtY29kaW5nfQ0KDQojIERlZmluZSBjb250cmFzdHMgKHNsaWRpbmcgZGlmZmVyZW5jZSBjb250cmFzdHMgPSBlZmZlY3QgY29kaW5nIGZvciBmYWN0b3JzIHdpdGggMiBsZXZlbHMpDQpjb250cmFzdHMoc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kc3RpbXVsYXRpb24pICAgPC0gY29udHIuc2RpZigyKQ0KY29udHJhc3RzKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJGdyb3VwKSAgICAgICAgIDwtIGNvbnRyLnNkaWYoMikNCmNvbnRyYXN0cyhzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRyZXNwb25zZV90eXBlKSA8LSBjb250ci5zZGlmKDIpDQoNCg0KIyBQcmVwYXJlIGxhYmVscyBmb3IgKEcpTE1NIHRhYmxlcw0KbGFiZWxzIDwtIGMoDQogICIoSW50ZXJjZXB0KSIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiSW50ZXJjZXB0IiwNCiAgInN0aW11bGF0aW9uMi0xIiAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICJTdGltdWxhdGlvbiIsDQogICJncm91cDItMSIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAiR3JvdXAiLA0KICAicmVzcG9uc2VfdHlwZTItMSIgICAgICAgICAgICAgICAgICAgICAgICAgID0gIlJlc3BvbnNlIHR5cGUiLA0KICAic3RpbXVsYXRpb24yLTE6Z3JvdXAyLTEiICAgICAgICAgICAgICAgICAgID0gIlN0aW11bGF0aW9uIHggR3JvdXAiLA0KICAic3RpbXVsYXRpb24yLTE6cmVzcG9uc2VfdHlwZTItMSIgICAgICAgICAgID0gIlN0aW11bGF0aW9uIHggUmVzcG9uc2UgdHlwZSIsDQogICJncm91cDItMTpyZXNwb25zZV90eXBlMi0xIiAgICAgICAgICAgICAgICAgPSAiR3JvdXAgeCBSZXNwb25zZSB0eXBlIiwNCiAgInN0aW11bGF0aW9uMi0xOmdyb3VwMi0xOnJlc3BvbnNlX3R5cGUyLTEiICA9ICJTdGltdWxhdGlvbiB4IEdyb3VwIHggUmVzcG9uc2UgdHlwZSINCikNCmBgYA0KPGJyPjxicj4NCg0KIyMjIFJlc3BvbnNlIFRpbWUgey50YWJzZXR9DQoNCiMjIyMgRGV0ZXJtaW5lIGRhdGEgdHJhbnNmb3JtYXRpb24NCg0KUmVzcG9uc2UgdGltZSB3YXMgbG9nLXRyYW5zZm9ybWVkIHByaW9yIHRvIGFuYWx5c2lzIHRvIG1lZXQgdGhlIGFzc3VtcHRpb24gb2Ygbm9ybWFsbHkgZGlzdHJpYnV0ZWQgcmVzaWR1YWxzLiBUaGUgYXBwcm9wcmlhdGUgdHJhbnNmb3JtYXRpb24gd2FzIGRldGVybWluZWQgdXNpbmcgdGhlIEJveOKAk0NveCBwcm9jZWR1cmUgKEJveCAmIENveCwgMTk2NCkuDQoNCmBgYHtyIFJULWRldGVybWluZS10cmFuc2Zvcm1hdGlvbiwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDN9DQoNCiMgQXJyYW5nZSBwbG90cw0KcGFyKG1mcm93ID0gYygxLCAzKSkNCg0KDQojIERldGVybWluZSB0cmFuc2Zvcm1hdGlvbiBieSBlc3RpbWF0aW5nIG9wdGltYWwgbGFtYmRhIHVzaW5nIEJveOKAk0NveCBwcm9jZWR1cmUNCmJjX3J0IDwtIGJveGNveChydCB+IDEsIGRhdGEgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbikNCm9wdGxhbWJkYV9ydCA8LSBiY19ydCR4W3doaWNoLm1heChiY19ydCR5KV0NCg0KDQojIERlbnNpdHkgcGxvdCBmb3IgbG9nLXRyYW5zZm9ybWVkIFJUIHZhbHVlcw0KcGxvdChkZW5zaXR5KHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHJ0X2xvZyksIG1haW4gPSAiTG9nIFJUOiBEZW5zaXR5ICBQbG90IikNCg0KDQojIFEtcSBwbG90IGZvciBsb2ctdHJhbnNmb3JtZWQgUlQgdmFsdWVzDQpxcW5vcm0oc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcnRfbG9nLCBtYWluID0gIkxvZyBSVDogUS1RIFBsb3QiLCBwY2ggPSAxKQ0KDQoNCiMgUmVzZXQgcGxvdCBsYXlvdXQNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANClRoZSBvcHRpbWFsIGxhbWJkYSBpcyBgciByb3VuZChvcHRsYW1iZGFfcnQsIGRpZ2l0cyA9IDIpYCwgc3VnZ2VzdGluZyB0aGF0IGxvZyB0cmFuc2Zvcm1hdGlvbiBpcyBhcHByb3ByaWF0ZS4gDQo8YnI+PGJyPjxicj4NCg0KIyMjIyBMTU0gey5hY3RpdmV9DQoNCldlIGFuYWx5emVkIHJlc3BvbnNlIHRpbWUgZGF0YSB1c2luZyBhIExNTSB3aXRoIHJlc3BvbnNlIHR5cGUgKGNvcnJlY3QsIGVycm9yKSwgZ3JvdXAsIGFuZCB0RENTIGNvbmRpdGlvbiBhcyBwcmVkaWN0b3JzLiA8YnI+PGJyPg0KVGhpcyB0YWJsZSBjb3JyZXNwb25kcyB0byBUYWJsZSBTMSBpbiB0aGUgc3VwcGxlbWVudGFsIG1hdGVyaWFsLiANCg0KYGBge3IgTE1NLVJULCBjYWNoZSA9IGtuaXRyX2NhY2hlX2VuYWJsZWR9DQoNCiMgUnVuIG1vZGVsDQpMTU1fcnQgPC0gbG1lcihydF9sb2cgfiBzdGltdWxhdGlvbiAqIGdyb3VwICogcmVzcG9uc2VfdHlwZSArDQogICgxICsgc3RpbXVsYXRpb24gKiByZXNwb25zZV90eXBlIHwgcGFydGljaXBhbnRfaWQpLA0KZGF0YSA9IHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuLA0KUkVNTCA9IFRSVUUsDQpjb250cm9sID0gbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopDQoNCg0KIyBDaGVjayBtb2RlbCBvdXRwdXQgYW5kIFBDQSBvZiByYW5kb20tZWZmZWN0cyB2YXJpYW5jZS1jb3ZhcmlhbmNlIGVzdGltYXRlcw0KIyBzdW1tYXJ5KExNTV9ydCkgICAgICAgICMgTW9kZWwgZG9lcyBjb252ZXJnZQ0KIyBpc1Npbmd1bGFyKExNTV9ydCkgICAgICMgTm8gc2luZ3VsYXIgZml0DQojIHN1bW1hcnkocmVQQ0EoTE1NX3J0KSkgIyBBbGwgdGVybXMgZXhwbGFpbiB2YXJpYW5jZQ0KDQoNCiMgRGlzcGxheSByZXN1bHRzIChmaXhlZCBlZmZlY3RzKQ0KdGFiX21vZGVsKExNTV9ydCwNCiAgZHYubGFiZWxzID0gImxvZyhSVCkiLCBwcmVkLmxhYmVscyA9IGxhYmVscywgc2hvdy5zdGF0ID0gVFJVRSwgc2hvdy5pY2MgPSBGQUxTRSwgc2hvdy5yMiA9IEZBTFNFLCANCiAgc2hvdy5yZS52YXIgPSBGQUxTRSwgc2hvdy5uZ3JvdXBzID0gRkFMU0UsIG1pbnVzLnNpZ24gPSAi4oiSIiwgc3RyaW5nLnByZWQgPSAiRml4ZWQgZWZmZWN0cyIsIA0KICBzdHJpbmcuZXN0ID0gImIiLCBzdHJpbmcuc3RhdCA9ICJ0Iiwgc3RyaW5nLmNpID0gIjk1ICUgQ0kiLCBwLnZhbCA9ICJzYXR0ZXJ0aHdhaXRlIiwgDQogIHdyYXAubGFiZWxzID0gODAsIHRpdGxlID0gIlJlc3VsdHMgb2YgdGhlIExNTSBQcmVkaWN0aW5nIFJUIGFzIGEgRnVuY3Rpb24gb2YgU3RpbXVsYXRpb24gQ29uZGl0aW9uIA0KICAoQ2F0aG9kYWwgLSBTaGFtKSwgR3JvdXAgKE9DRCAtIEhlYWx0aHkgQ29udHJvbHMpLCBhbmQgUmVzcG9uc2UgVHlwZSAoSW5jb3JyZWN0IC0gQ29ycmVjdCkiDQopDQoNCg0KIyBEaXNwbGF5IHJhbmRvbSBlZmZlY3RzDQpwcmludCgiUmFuZG9tIGVmZmVjdHM6IikNCnByaW50KFZhckNvcnIoTE1NX3J0KSwgZGlnaXRzID0gMSwgY29tcCA9ICJTdGQuRGV2LiIpDQpgYGANCjxicj48YnI+DQpSZXNwb25zZSB0aW1lIGFuYWx5c2lzIHJldmVhbGVkIGEgc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2YgcmVzcG9uc2UgdHlwZSwgaW5kaWNhdGluZyB0aGF0IHJlc3BvbnNlcyB3ZXJlIGZhc3RlciBmb3IgZXJyb3JzIHRoYW4gZm9yIGNvcnJlY3QgcmVzcG9uc2VzLiBSZXNwb25zZSB0aW1lIGRpZCBub3QgZGlmZmVyIHNpZ25pZmljYW50bHkgYmV0d2VlbiBncm91cHMgb3IgdERDUyBjb25kaXRpb25zIGFuZCB0aGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBhbnkgb2YgdGhlIGZhY3RvcnMuDQo8YnI+PGJyPjxicj4NCg0KIyMjIFBvc3QtRXJyb3IgU2xvd2luZyB7LnRhYnNldH0NCg0KIyMjIyBEZXRlcm1pbmUgZGF0YSB0cmFuc2Zvcm1hdGlvbg0KDQpObyBkYXRhIHRyYW5zZm9ybWF0aW9uIHdhcyByZXF1aXJlZCB0byBtZWV0IHRoZSBhc3N1bXB0aW9uIG9mIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJlc2lkdWFscy4gVGhpcyB3YXMgZGV0ZXJtaW5lZCB1c2luZyB0aGUgQm944oCTQ294IHByb2NlZHVyZSAoQm94ICYgQ294LCAxOTY0KS4NCg0KYGBge3IgUEVTLWRldGVybWluZS10cmFuc2Zvcm1hdGlvbiwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDN9DQoNCiMgQXJyYW5nZSBwbG90cw0KcGFyKG1mcm93ID0gYygxLCAzKSkNCg0KDQojIERldGVybWluZSB0cmFuc2Zvcm1hdGlvbiBieSBlc3RpbWF0aW5nIG9wdGltYWwgbGFtYmRhIHVzaW5nIEJveOKAk0NveCBwcm9jZWR1cmUNCmJjX3BlcyA8LSBib3hjb3gocGVzICsgMTAwMCB+IDEsIGRhdGEgPSBzaW5nbGVfdHJpYWxfZGF0YV9jbGVhblshaXMubmEoc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4kcGVzKSwgXSkNCm9wdGxhbWJkYV9wZXMgPC0gYmNfcGVzJHhbd2hpY2gubWF4KGJjX3BlcyR5KV0NCg0KDQojIERlbnNpdHkgcGxvdCBmb3IgUEVTIHZhbHVlcw0KcGxvdChkZW5zaXR5KHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuWyFpcy5uYShzaW5nbGVfdHJpYWxfZGF0YV9jbGVhbiRwZXMpLCBdJHBlcyksIG1haW4gPSAiUEVTOiBEZW5zaXR5ICBQbG90IikNCg0KDQojIFEtcSBwbG90IGZvciBQRVMgdmFsdWVzDQpxcW5vcm0oc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bIWlzLm5hKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHBlcyksIF0kcGVzLCBtYWluID0gIlBFUzogUS1RIFBsb3QiLCBwY2ggPSAxKQ0KDQoNCiMgUmVzZXQgcGxvdCBsYXlvdXQNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANClRoZSBvcHRpbWFsIGxhbWJkYSBpcyBgciByb3VuZChvcHRsYW1iZGFfcGVzLCBkaWdpdHMgPSAyKWAsIHN1Z2dlc3RpbmcgdGhhdCBubyB0cmFuc2Zvcm1hdGlvbiBpcyBuZWVkZWQuDQo8YnI+PGJyPjxicj4NCg0KIyMjIyBMTU0gey5hY3RpdmV9DQoNCkZvciB0aGUgYW5hbHlzaXMgb2YgUEVTLCB3ZSBmaXR0ZWQgYSBMTU0gb24gc2luZ2xlLXRyaWFsIHZhbHVlcyB0aGF0IHdlcmUgY2FsY3VsYXRlZCBhcyB0aGUgcmVzcG9uc2UgdGltZSBkaWZmZXJlbmNlIGJldHdlZW4gY29ycmVjdCByZXNwb25zZXMgdGhhdCBkaXJlY3RseSBwcmVjZWRlZCBhbmQgZm9sbG93ZWQgYW4gZXJyb3IuIFRoaXMgUEVTIHF1YW50aWZpY2F0aW9uIHJlc3VsdHMgaW4gYSBtZWFzdXJlIHRoYXQgaXMgbm90IGNvbmZvdW5kZWQgYnkgZmx1Y3R1YXRpb25zIGluIG1vdGl2YXRpb24gb3IgcmVzcG9uc2UgY2F1dGlvbiBvdmVyIHRpbWUgKER1dGlsaCBldCBhbC4sIDIwMTIpLiBJbiB0aGlzIGFuYWx5c2lzLCB3ZSBjb25zaWRlcmVkIG9ubHkgZXJyb3IgdHJpYWxzIHRoYXQgd2VyZSBwcmVjZWRlZCBieSBhdCBsZWFzdCB0d28gY29ycmVjdCB0cmlhbHMgYW5kIGZvbGxvd2VkIGJ5IGF0IGxlYXN0IG9uZSBjb3JyZWN0IHRyaWFsLiBNb2RlbCBlc3RpbWF0ZXMgb2YgdGhlIExNTSBvbiBQRVMgZGlyZWN0bHkgcmVmbGVjdCBtZWFuIGRpZmZlcmVuY2VzIGluIG1pbGxpc2Vjb25kcy4gPGJyPjxicj4NClRoaXMgdGFibGUgY29ycmVzcG9uZHMgdG8gVGFibGUgUzIgaW4gdGhlIHN1cHBsZW1lbnRhbCBtYXRlcmlhbC4gDQoNCmBgYHtyIExNTS1QRVN9DQoNCiMgUnVuIG1vZGVsDQpMTU1fcGVzIDwtIGxtZXIocGVzIH4gc3RpbXVsYXRpb24gKiBncm91cCArDQogICgxICsgc3RpbXVsYXRpb24gfCBwYXJ0aWNpcGFudF9pZCksDQpkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW5bIWlzLm5hKHNpbmdsZV90cmlhbF9kYXRhX2NsZWFuJHBlcyksIF0sDQpSRU1MID0gVFJVRSwNCmNvbnRyb2wgPSBsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIikNCikNCg0KDQojIENoZWNrIG1vZGVsIG91dHB1dCBhbmQgUENBIG9mIHJhbmRvbS1lZmZlY3RzIHZhcmlhbmNlLWNvdmFyaWFuY2UgZXN0aW1hdGVzDQojIHN1bW1hcnkoTE1NX3BlcykgICAgICAgICMgTW9kZWwgZG9lcyBjb252ZXJnZQ0KIyBpc1Npbmd1bGFyKExNTV9wZXMpICAgICAjIE5vIHNpbmd1bGFyIGZpdA0KIyBzdW1tYXJ5KHJlUENBKExNTV9wZXMpKSAjIEFsbCB0ZXJtcyBleHBsYWluIHZhcmlhbmNlDQoNCg0KIyBEaXNwbGF5IHJlc3VsdHMgKGZpeGVkIGVmZmVjdHMpDQp0YWJfbW9kZWwoTE1NX3BlcywNCiAgZHYubGFiZWxzID0gIlBFUyIsIHByZWQubGFiZWxzID0gbGFiZWxzLCBzaG93LnN0YXQgPSBUUlVFLCBzaG93LmljYyA9IEZBTFNFLCBzaG93LnIyID0gRkFMU0UsDQogIHNob3cucmUudmFyID0gRkFMU0UsIHNob3cubmdyb3VwcyA9IEZBTFNFLCBtaW51cy5zaWduID0gIuKIkiIsIHN0cmluZy5wcmVkID0gIkZpeGVkIGVmZmVjdHMiLCANCiAgc3RyaW5nLmVzdCA9ICJiIiwgc3RyaW5nLnN0YXQgPSAidCIsIHN0cmluZy5jaSA9ICI5NSAlIENJIiwgcC52YWwgPSAic2F0dGVydGh3YWl0ZSIsIA0KICB0aXRsZSA9ICJSZXN1bHRzIG9mIHRoZSBMTU0gUHJlZGljdGluZyBQRVMgYXMgYSBGdW5jdGlvbiBvZiBTdGltdWxhdGlvbiBDb25kaXRpb24gDQogIChDYXRob2RhbCAtIFNoYW0pIGFuZCBHcm91cCAoT0NEIC0gSGVhbHRoeSBDb250cm9scykiDQopDQoNCg0KIyBEaXNwbGF5IHJhbmRvbSBlZmZlY3RzDQpwcmludCgiUmFuZG9tIGVmZmVjdHM6IikNCnByaW50KFZhckNvcnIoTE1NX3BlcyksIGRpZ2l0cyA9IDQsIGNvbXAgPSAiU3RkLkRldi4iKQ0KYGBgDQo8YnI+PGJyPg0KVGhlIExNTSBvbiBQRVMgeWllbGRlZCBhIHNpZ25pZmljYW50IGludGVyY2VwdCwgcmVmbGVjdGluZyB0aGF0IHBhcnRpY2lwYW50cyBzbG93ZWQgZG93biBhZnRlciBlcnJvciBjb21taXNzaW9uLiBUaGUgZ3JvdXBzIGRpZCBub3QgZGlmZmVyIHNpZ25pZmljYW50bHkgaW4gUEVTLiBUaGVyZSB3YXMgbm8gc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3Qgb2YgdERDUyBjb25kaXRpb24gYW5kIG5vIGludGVyYWN0aW9uIGJldHdlZW4gZ3JvdXAgYW5kIHREQ1MgY29uZGl0aW9uLg0KPGJyPjxicj48YnI+DQoNCiMjIyBSZXNwb25zZSBBY2N1cmFjeSANCg0KUmVzcG9uc2UgYWNjdXJhY3kgd2FzIGFuYWx5emVkIHVzaW5nIGEgYmlub21pYWwgZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIG1vZGVsIChHTE1NKS4gRm9yIHRoZSBHTE1NIG9uIGFjY3VyYWN5LCBlc3RpbWF0ZXMgcmVmbGVjdCBvZGRzIHJhdGlvcyBmb3IgYSBjb3JyZWN0IHJlc3BvbnNlLiA8YnI+PGJyPg0KVGhpcyB0YWJsZSBjb3JyZXNwb25kcyB0byBUYWJsZSBTMiBpbiB0aGUgc3VwcGxlbWVudGFsIG1hdGVyaWFsLiANCg0KYGBge3IgR0xNTS1hY2N1cmFjeSwgY2FjaGUgPSBrbml0cl9jYWNoZV9lbmFibGVkfQ0KDQojIFJ1biBtb2RlbA0KR0xNTV9hY2N1cmFjeSA8LSBnbG1lcihhY2N1cmFjeV9udW1lcmljIH4gc3RpbXVsYXRpb24gKiBncm91cCArDQogICgxICsgc3RpbXVsYXRpb24gfCBwYXJ0aWNpcGFudF9pZCksDQpkYXRhID0gc2luZ2xlX3RyaWFsX2RhdGFfY2xlYW4sDQpmYW1pbHkgPSBiaW5vbWlhbCwNCmNvbnRyb2wgPSBnbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIpDQopDQoNCg0KIyBDaGVjayBtb2RlbCBvdXRwdXQgYW5kIFBDQSBvZiByYW5kb20tZWZmZWN0cyB2YXJpYW5jZS1jb3ZhcmlhbmNlIGVzdGltYXRlcw0KIyBzdW1tYXJ5KEdMTU1fYWNjdXJhY3kpICAgICAgICAjIE1vZGVsIGRvZXMgY29udmVyZ2UNCiMgaXNTaW5ndWxhcihHTE1NX2FjY3VyYWN5KSAgICAgIyBObyBzaW5ndWxhciBmaXQNCiMgc3VtbWFyeShyZVBDQShHTE1NX2FjY3VyYWN5KSkgIyBBbGwgdGVybXMgZXhwbGFpbiB2YXJpYW5jZQ0KDQoNCiMgRGlzcGxheSByZXN1bHRzIChmaXhlZCBlZmZlY3RzKQ0KdGFiX21vZGVsKEdMTU1fYWNjdXJhY3ksDQogIGR2LmxhYmVscyA9ICJBY2N1cmFjeSIsIHByZWQubGFiZWxzID0gbGFiZWxzLCBzaG93LnN0YXQgPSBUUlVFLCBzaG93LmljYyA9IEZBTFNFLCBzaG93LnIyID0gRkFMU0UsDQogIHNob3cucmUudmFyID0gRkFMU0UsIHNob3cubmdyb3VwcyA9IEZBTFNFLCBtaW51cy5zaWduID0gIuKIkiIsIHN0cmluZy5wcmVkID0gIkZpeGVkIGVmZmVjdHMiLCANCiAgc3RyaW5nLmVzdCA9ICJPZGRzIHJhdGlvIiwgc3RyaW5nLnN0YXQgPSAieiIsIHN0cmluZy5jaSA9ICI5NSAlIENJIiwgdGl0bGUgPSAiUmVzdWx0cyBvZiB0aGUgQmlub21pYWwgR0xNTSANCiAgUHJlZGljdGluZyBSZXNwb25zZSBBY2N1cmFjeSBhcyBhIEZ1bmN0aW9uIG9mIFN0aW11bGF0aW9uIENvbmRpdGlvbiAoQ2F0aG9kYWwgLSBTaGFtKSBhbmQgDQogIEdyb3VwIChPQ0QgLSBIZWFsdGh5IENvbnRyb2xzKSINCikNCg0KDQojIERpc3BsYXkgcmFuZG9tIGVmZmVjdHMNCnByaW50KCJSYW5kb20gZWZmZWN0czoiKQ0KcHJpbnQoVmFyQ29ycihHTE1NX2FjY3VyYWN5KSwgZGlnaXRzID0gMiwgY29tcCA9ICJTdGQuRGV2LiIpDQpgYGANCjxicj48YnI+DQpSZXN1bHRzIG9mIHRoZSBHTE1NIGluZGljYXRlZCB0aGF0IHRoZXJlIHdhcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHJlc3BvbnNlIGFjY3VyYWN5IGJldHdlZW4gZ3JvdXBzIG9yIHREQ1MgY29uZGl0aW9ucyBhbmQgbm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBncm91cCBhbmQgdERDUyBjb25kaXRpb24uDQo8YnI+PGJyPjxicj4NCg0KIyMgUmVmZXJlbmNlcw0KKioqDQpCYXRlcywgRC4sIEtsaWVnbCwgUi4sIFZhc2lzaHRoLCBTLiwgJiBCYWF5ZW4sIEguICgyMDE1KS4gKlBhcnNpbW9uaW91cyBtaXhlZCBtb2RlbHMuKiBhclhpdi4gaHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzE1MDYuMDQ5Njd2MiA8YnI+PGJyPg0KQm94LCBHLiBFLiwgJiBDb3gsIEQuIFIuICgxOTY0KS4gQW4gYW5hbHlzaXMgb2YgdHJhbnNmb3JtYXRpb25zLiAqSm91cm5hbCBvZiB0aGUgUm95YWwgU3RhdGlzdGljYWwgU29jaWV0eTogU2VyaWVzIEIgKE1ldGhvZG9sb2dpY2FsKSwgMjYqKDIpLCAyMTEtMjQzLiBodHRwczovL2RvaS5vcmcvMTAuMTExMS9qLjI1MTctNjE2MS4xOTY0LnRiMDA1NTMueCA8YnI+PGJyPg0KRHV0aWxoLCBHLiwgdmFuIFJhdmVuendhYWlqLCBELiwgTmlldXdlbmh1aXMsIFMuLCB2YW4gZGVyIE1hYXMsIEguIEwuIEouLCBGb3JzdG1hbm4sIEIuIFUuLCAmIFdhZ2VubWFrZXJzLCBFLi1KLiAoMjAxMikuIEhvdyB0byBtZWFzdXJlIHBvc3QtZXJyb3Igc2xvd2luZzogQSBjb25mb3VuZCBhbmQgYSBzaW1wbGUgc29sdXRpb24uICpKb3VybmFsIG9mIE1hdGhlbWF0aWNhbCBQc3ljaG9sb2d5LCA1NiooMyksIDIwOC0yMTYuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L2ouam1wLjIwMTIuMDQuMDAxIDxicj48YnI+DQpNb3JleSwgUi4gKDIwMDgpLiBDb25maWRlbmNlIGludGVydmFscyBmcm9tIG5vcm1hbGl6ZWQgZGF0YTogQSBjb3JyZWN0aW9uIHRvIENvdXNpbmVhdSAoMjAwNSkuICpUdXRvcmlhbHMgaW4gUXVhbnRpdGF0aXZlIE1ldGhvZHMgZm9yIFBzeWNob2xvZ3ksIDQqKDIpLCA2MS02NC4gaHR0cHM6Ly9kb2kub3JnLzEwLjIwOTgyL3RxbXAuMDQuMi5wMDYxIDxicj48YnI+DQo8YnI+PGJyPg0KDQojIyBTZXNzaW9uIEluZm8NCioqKg0KYGBge3Igc2Vzc2lvbi1pbmZvfQ0KDQpzZXNzaW9uSW5mbygpDQpgYGANCg==