cat("\014")     # clean terminal

rm(list = ls()) # clean workspace
try(dev.off(), silent = TRUE) # close all plots
library(readxl)
library(afex)
library(emmeans)
library(ggplot2)
theme_set(
  theme_minimal()
)
a_posteriori <- function(afex_aov, sig_level = .05) {
  factors  <- as.list(rownames(afex_aov$anova_table))
  for (j in 1:length(factors)) {
    if (grepl(":", factors[[j]])) {
      factors[[j]] <- unlist(strsplit(factors[[j]], ":"))
    }
  }
  p_values <- afex_aov$anova_table$`Pr(>F)`
  for (i in 1:length(p_values)) {
    if (p_values[i] <= sig_level) {
      cat(rep("_", 100), '\n', sep = "")
      print(emmeans(afex_aov, factors[[i]], contr = "pairwise"))
    }
  }
}
painEmpathy_p2_name <- file.path('average_voltage_180_to_230_painEmpathy.txt')
painEmpathy_p2_data <- read.table(painEmpathy_p2_name, header = TRUE, strip.white = TRUE, sep = "\t")
painEmpathy_p3_name <- file.path('average_voltage_300_to_500_painEmpathy.txt')
painEmpathy_p3_data <- read.table(painEmpathy_p3_name, header = TRUE, strip.white = TRUE, sep = "\t")
painEmpathy_data <- rbind(painEmpathy_p2_data, painEmpathy_p3_data)
painEmpathy_data$worklat <- gsub(".0", "", painEmpathy_data$worklat, fixed = TRUE)
names(painEmpathy_data)[names(painEmpathy_data) == "mlabel"]   <- "component"
names(painEmpathy_data)[names(painEmpathy_data) == "value"]    <- "amplitude"
names(painEmpathy_data)[names(painEmpathy_data) == "binlabel"] <- "stimulus"
names(painEmpathy_data)[names(painEmpathy_data) == "chlabel"]  <- "electrode"
painEmpathy_data$num_id <- readr::parse_number(painEmpathy_data$ERPset)
painEmpathy_data$sex[ grepl("female", painEmpathy_data$ERPset)] <- "Female"
painEmpathy_data$sex[!grepl("female", painEmpathy_data$ERPset)] <- "Male"
painEmpathy_data$num_id  <- factor(painEmpathy_data$num_id)
painEmpathy_data$chindex <- factor(painEmpathy_data$chindex)
painEmpathy_data$bini    <- factor(painEmpathy_data$bini)
painEmpathy_data[sapply(painEmpathy_data, is.character)] <- lapply(painEmpathy_data[sapply(painEmpathy_data, is.character)], as.factor)
painEmpathy_data$stimulus <- relevel(painEmpathy_data$stimulus, "Pain")
sass_data <- read_xlsx(file.path('..',  'bad channels empathy huepe.xlsx'))
names(sass_data)[names(sass_data) == "SASS_TOTAL"]   <- "sass"
sass_data$num_id <- readr::parse_number(sass_data$ID_gsheet)
painEmpathy_data <- merge(painEmpathy_data, sass_data[c('sass', 'num_id')], by = 'num_id')
painEmpathy_data$sass_centered <- painEmpathy_data$sass - mean(painEmpathy_data$sass, na.rm=TRUE)
write.csv(painEmpathy_data,  file.path('painEmpathy_data_clean.csv'),  row.names = FALSE)

1 Participants

options(width = 100)
xtabs(~ sex, data = painEmpathy_data) / length(unique(painEmpathy_data$chindex)) / length(unique(painEmpathy_data$stimulus))  / length(unique(painEmpathy_data$component))
sex
Female   Male 
    34     25 

2 ERP plots

Dong, L., Li, F., Liu, Q., Wen, X., Lai, Y., Xu, P., & Yao, D. (2017). MATLAB Toolboxes for Reference Electrode Standardization Technique (REST) of Scalp EEG. Frontiers in Neuroscience, 11(OCT), 601. https://doi.org/10.3389/fnins.2017.00601

2.1 Pain & no-Pain ERPs:

2.2 Topographic layout:

3 General description

options(width = 100)
ggplot(
  painEmpathy_data, aes(x = amplitude, fill = component, color = component)) +
  geom_histogram(alpha = .4, position = "identity")

summary(painEmpathy_data)
     num_id          worklat    component   amplitude       chindex  electrode bini      stimulus  
 1      :  8   [180  230]:236   P2:236    Min.   :-13.376   25:236   PO7:236   1:236   Pain  :236  
 3      :  8   [300  500]:236   P3:236    1st Qu.:  2.342   62:236   PO8:236   2:236   NoPain:236  
 4      :  8                              Median :  5.104                                          
 6      :  8                              Mean   :  5.533                                          
 7      :  8                              3rd Qu.:  8.408                                          
 11     :  8                              Max.   : 22.731                                          
 (Other):424                                                                                       
                    ERPset        sex           sass       sass_centered     
 S01_female_painEmpathy:  8   Female:272   Min.   :27.00   Min.   :-15.5172  
 S03_female_painEmpathy:  8   Male  :200   1st Qu.:36.00   1st Qu.: -6.5172  
 S04_male_painEmpathy  :  8                Median :42.00   Median : -0.5172  
 S06_male_painEmpathy  :  8                Mean   :42.52   Mean   :  0.0000  
 S07_male_painEmpathy  :  8                3rd Qu.:49.00   3rd Qu.:  6.4828  
 S11_female_painEmpathy:  8                Max.   :55.00   Max.   : 12.4828  
 (Other)               :424                NA's   :8       NA's   :8         
painEmpathy_vars <- c('sass_centered', 'amplitude')

4 Pain & No-pain P2, average from 180 to 230 ms

4.1 Scalp voltage distribution:

4.2 P2 by sex & stimulus:

options(width = 100)
painEmpathy_p2_rep_anova = aov_ez(
  "num_id", "amplitude", subset(painEmpathy_data, component == "P2",),
  within = c("stimulus", "electrode"), between = "sex", covariate = "sass_centered", factorize = FALSE
  )
Warning: Numerical variables NOT centered on 0 (matters if variable in interaction):
   NA
Warning: Missing values for 1 ID(s), which were removed before analysis:
99
Below the first few rows (in wide format) of the removed cases with missing data.
  Contrasts set to contr.sum for the following variables: sex
painEmpathy_p2_afex_plot <-
  afex_plot(
    painEmpathy_p2_rep_anova,
    x     = "electrode",
    trace = "stimulus",
    panel = "sex",
    error = "within",
    error_arg = list(width = .25),
    dodge     = -.5,
    mapping   = c("color"),
    point_arg = list(size = 4)
  )
nice(painEmpathy_p2_rep_anova)
Anova Table (Type 3 tests)

Response: amplitude
                             Effect    df   MSE        F   ges p.value
1                               sex 1, 55 46.68     1.17  .018    .284
2                     sass_centered 1, 55 46.68     0.49  .008    .486
3                          stimulus 1, 55  1.65     0.16 <.001    .688
4                      sex:stimulus 1, 55  1.65     0.01 <.001    .910
5            sass_centered:stimulus 1, 55  1.65     2.44  .001    .124
6                         electrode 1, 55  5.47 10.16 **  .018    .002
7                     sex:electrode 1, 55  5.47     1.23  .002    .272
8           sass_centered:electrode 1, 55  5.47     2.03  .004    .160
9                stimulus:electrode 1, 55  0.47     0.13 <.001    .725
10           sex:stimulus:electrode 1, 55  0.47   3.17 + <.001    .080
11 sass_centered:stimulus:electrode 1, 55  0.47     1.15 <.001    .288
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
suppressWarnings(print(painEmpathy_p2_afex_plot))

a_posteriori(painEmpathy_p2_rep_anova)
____________________________________________________________________________________________________
$emmeans
 electrode emmean    SE df lower.CL upper.CL
 PO7         3.65 0.445 55     2.76     4.54
 PO8         4.64 0.511 55     3.61     5.66

Results are averaged over the levels of: sex, stimulus 
Confidence level used: 0.95 

$contrasts
 contrast  estimate   SE df t.ratio p.value
 PO7 - PO8   -0.989 0.31 55  -3.188  0.0024

Results are averaged over the levels of: sex, stimulus 

5 Pain & No-pain P3, average from 300 to 500 ms

5.1 Scalp voltage distribution:

5.2 P3 by sex & stimulus:

options(width = 100)
painEmpathy_p3_rep_anova = aov_ez(
  "num_id", "amplitude", subset(painEmpathy_data, component == "P3"),
  within = c("stimulus", "electrode"), between = "sex", covariate = "sass_centered", factorize = FALSE
  )
Warning: Numerical variables NOT centered on 0 (matters if variable in interaction):
   NA
Warning: Missing values for 1 ID(s), which were removed before analysis:
99
Below the first few rows (in wide format) of the removed cases with missing data.
  Contrasts set to contr.sum for the following variables: sex
painEmpathy_p3_afex_plot <-
  afex_plot(
    painEmpathy_p3_rep_anova,
    x     = "electrode",
    trace = "stimulus",
    panel = "sex",
    error = "within",
    error_arg = list(width = .25),
    dodge     = -.5,
    mapping   = c("color"),
    point_arg = list(size = 4)
  )
nice(painEmpathy_p3_rep_anova)
Anova Table (Type 3 tests)

Response: amplitude
                             Effect    df    MSE         F   ges p.value
1                               sex 1, 55 107.93      0.59  .010    .445
2                     sass_centered 1, 55 107.93      0.74  .012    .393
3                          stimulus 1, 55   1.80  10.01 **  .003    .003
4                      sex:stimulus 1, 55   1.80      0.43 <.001    .514
5            sass_centered:stimulus 1, 55   1.80      0.74 <.001    .392
6                         electrode 1, 55   7.98 16.43 ***  .020   <.001
7                     sex:electrode 1, 55   7.98      0.00 <.001    .989
8           sass_centered:electrode 1, 55   7.98      0.06 <.001    .803
9                stimulus:electrode 1, 55   0.53      1.38 <.001    .245
10           sex:stimulus:electrode 1, 55   0.53      1.52 <.001    .223
11 sass_centered:stimulus:electrode 1, 55   0.53      0.30 <.001    .589
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
suppressWarnings(print(painEmpathy_p3_afex_plot))

a_posteriori(painEmpathy_p3_rep_anova)
____________________________________________________________________________________________________
$emmeans
 stimulus emmean    SE df lower.CL upper.CL
 Pain       6.61 0.704 55      5.2     8.02
 NoPain     7.17 0.685 55      5.8     8.54

Results are averaged over the levels of: sex, electrode 
Confidence level used: 0.95 

$contrasts
 contrast      estimate    SE df t.ratio p.value
 Pain - NoPain   -0.563 0.178 55  -3.164  0.0025

Results are averaged over the levels of: sex, electrode 

____________________________________________________________________________________________________
$emmeans
 electrode emmean    SE df lower.CL upper.CL
 PO7         6.13 0.675 55     4.78     7.48
 PO8         7.65 0.750 55     6.14     9.15

Results are averaged over the levels of: sex, stimulus 
Confidence level used: 0.95 

$contrasts
 contrast  estimate    SE df t.ratio p.value
 PO7 - PO8    -1.52 0.374 55  -4.054  0.0002

Results are averaged over the levels of: sex, stimulus 

6 Mass univariate analysis (cluster-mass)

Groppe, D. M., Urbach, T. P., & Kutas, M. (2011). Mass univariate analysis of event-related brain potentials/fields I: A critical tutorial review. Psychophysiology, 48(12), 1711–1725. https://doi.org/10.1111/J.1469-8986.2011.01273.X

6.1 Early time window

6.2 Late time window

7 Multivariate pattern analysis (decoding)

Occipital channels:
PO7, PO3, POz, PO4, PO8
O1, Oz, O2
Iz

Fahrenfort, J. J., van Driel, J., van Gaal, S., & Olivers, C. N. L. (2018). From ERPs to MVPA using the Amsterdam Decoding and Modeling toolbox (ADAM). Frontiers in Neuroscience, 12(JUL), 351586. https://doi.org/10.3389/FNINS.2018.00368/BIBTEX

7.1 Exemplar ERP on PO8

7.2 Decoding over time

7.3 Individual results, pretty shitty

7.4 Temporal generalization plot

LS0tCnRpdGxlOiAiUGFpbiBFbXBhdGh5IEVSUHMgMjAxNSIKYXV0aG9yOiAiQWx2YXJvIFJpdmVyYS1SZWkiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0aGVtZTogY2VydWxlYW4KICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogbm8KICAgICAgc21vb3RoX3Njcm9sbDogbm8KICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwpzdWJ0aXRsZTogUmVmZXJlbmNlIGF0IGluZmluaXR5LCBSRVNUIChSZWZlcmVuY2UgRWxlY3Ryb2RlIFN0YW5kYXJkaXphdGlvbiBUZWNobmlxdWUpLgotLS0KCmBgYHtyIENsZWFuIGFuZCBMb2FkIExpYnJhcmllc30KY2F0KCJcMDE0IikgICAgICMgY2xlYW4gdGVybWluYWwKcm0obGlzdCA9IGxzKCkpICMgY2xlYW4gd29ya3NwYWNlCnRyeShkZXYub2ZmKCksIHNpbGVudCA9IFRSVUUpICMgY2xvc2UgYWxsIHBsb3RzCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGFmZXgpCmxpYnJhcnkoZW1tZWFucykKbGlicmFyeShnZ3Bsb3QyKQpgYGAKCmBgYHtyIFNldCBEZWZhdWx0c30KdGhlbWVfc2V0KAogIHRoZW1lX21pbmltYWwoKQopCmFfcG9zdGVyaW9yaSA8LSBmdW5jdGlvbihhZmV4X2Fvdiwgc2lnX2xldmVsID0gLjA1KSB7CiAgZmFjdG9ycyAgPC0gYXMubGlzdChyb3duYW1lcyhhZmV4X2FvdiRhbm92YV90YWJsZSkpCiAgZm9yIChqIGluIDE6bGVuZ3RoKGZhY3RvcnMpKSB7CiAgICBpZiAoZ3JlcGwoIjoiLCBmYWN0b3JzW1tqXV0pKSB7CiAgICAgIGZhY3RvcnNbW2pdXSA8LSB1bmxpc3Qoc3Ryc3BsaXQoZmFjdG9yc1tbal1dLCAiOiIpKQogICAgfQogIH0KICBwX3ZhbHVlcyA8LSBhZmV4X2FvdiRhbm92YV90YWJsZSRgUHIoPkYpYAogIGZvciAoaSBpbiAxOmxlbmd0aChwX3ZhbHVlcykpIHsKICAgIGlmIChwX3ZhbHVlc1tpXSA8PSBzaWdfbGV2ZWwpIHsKICAgICAgY2F0KHJlcCgiXyIsIDEwMCksICdcbicsIHNlcCA9ICIiKQogICAgICBwcmludChlbW1lYW5zKGFmZXhfYW92LCBmYWN0b3JzW1tpXV0sIGNvbnRyID0gInBhaXJ3aXNlIikpCiAgICB9CiAgfQp9CmBgYAoKYGBge3IgTG9hZCBwYWluIGRhdGF9CnBhaW5FbXBhdGh5X3AyX25hbWUgPC0gZmlsZS5wYXRoKCdhdmVyYWdlX3ZvbHRhZ2VfMTgwX3RvXzIzMF9wYWluRW1wYXRoeS50eHQnKQpwYWluRW1wYXRoeV9wMl9kYXRhIDwtIHJlYWQudGFibGUocGFpbkVtcGF0aHlfcDJfbmFtZSwgaGVhZGVyID0gVFJVRSwgc3RyaXAud2hpdGUgPSBUUlVFLCBzZXAgPSAiXHQiKQpwYWluRW1wYXRoeV9wM19uYW1lIDwtIGZpbGUucGF0aCgnYXZlcmFnZV92b2x0YWdlXzMwMF90b181MDBfcGFpbkVtcGF0aHkudHh0JykKcGFpbkVtcGF0aHlfcDNfZGF0YSA8LSByZWFkLnRhYmxlKHBhaW5FbXBhdGh5X3AzX25hbWUsIGhlYWRlciA9IFRSVUUsIHN0cmlwLndoaXRlID0gVFJVRSwgc2VwID0gIlx0IikKcGFpbkVtcGF0aHlfZGF0YSA8LSByYmluZChwYWluRW1wYXRoeV9wMl9kYXRhLCBwYWluRW1wYXRoeV9wM19kYXRhKQpwYWluRW1wYXRoeV9kYXRhJHdvcmtsYXQgPC0gZ3N1YigiLjAiLCAiIiwgcGFpbkVtcGF0aHlfZGF0YSR3b3JrbGF0LCBmaXhlZCA9IFRSVUUpCm5hbWVzKHBhaW5FbXBhdGh5X2RhdGEpW25hbWVzKHBhaW5FbXBhdGh5X2RhdGEpID09ICJtbGFiZWwiXSAgIDwtICJjb21wb25lbnQiCm5hbWVzKHBhaW5FbXBhdGh5X2RhdGEpW25hbWVzKHBhaW5FbXBhdGh5X2RhdGEpID09ICJ2YWx1ZSJdICAgIDwtICJhbXBsaXR1ZGUiCm5hbWVzKHBhaW5FbXBhdGh5X2RhdGEpW25hbWVzKHBhaW5FbXBhdGh5X2RhdGEpID09ICJiaW5sYWJlbCJdIDwtICJzdGltdWx1cyIKbmFtZXMocGFpbkVtcGF0aHlfZGF0YSlbbmFtZXMocGFpbkVtcGF0aHlfZGF0YSkgPT0gImNobGFiZWwiXSAgPC0gImVsZWN0cm9kZSIKcGFpbkVtcGF0aHlfZGF0YSRudW1faWQgPC0gcmVhZHI6OnBhcnNlX251bWJlcihwYWluRW1wYXRoeV9kYXRhJEVSUHNldCkKcGFpbkVtcGF0aHlfZGF0YSRzZXhbIGdyZXBsKCJmZW1hbGUiLCBwYWluRW1wYXRoeV9kYXRhJEVSUHNldCldIDwtICJGZW1hbGUiCnBhaW5FbXBhdGh5X2RhdGEkc2V4WyFncmVwbCgiZmVtYWxlIiwgcGFpbkVtcGF0aHlfZGF0YSRFUlBzZXQpXSA8LSAiTWFsZSIKcGFpbkVtcGF0aHlfZGF0YSRudW1faWQgIDwtIGZhY3RvcihwYWluRW1wYXRoeV9kYXRhJG51bV9pZCkKcGFpbkVtcGF0aHlfZGF0YSRjaGluZGV4IDwtIGZhY3RvcihwYWluRW1wYXRoeV9kYXRhJGNoaW5kZXgpCnBhaW5FbXBhdGh5X2RhdGEkYmluaSAgICA8LSBmYWN0b3IocGFpbkVtcGF0aHlfZGF0YSRiaW5pKQpwYWluRW1wYXRoeV9kYXRhW3NhcHBseShwYWluRW1wYXRoeV9kYXRhLCBpcy5jaGFyYWN0ZXIpXSA8LSBsYXBwbHkocGFpbkVtcGF0aHlfZGF0YVtzYXBwbHkocGFpbkVtcGF0aHlfZGF0YSwgaXMuY2hhcmFjdGVyKV0sIGFzLmZhY3RvcikKcGFpbkVtcGF0aHlfZGF0YSRzdGltdWx1cyA8LSByZWxldmVsKHBhaW5FbXBhdGh5X2RhdGEkc3RpbXVsdXMsICJQYWluIikKc2Fzc19kYXRhIDwtIHJlYWRfeGxzeChmaWxlLnBhdGgoJy4uJywgICdiYWQgY2hhbm5lbHMgZW1wYXRoeSBodWVwZS54bHN4JykpCm5hbWVzKHNhc3NfZGF0YSlbbmFtZXMoc2Fzc19kYXRhKSA9PSAiU0FTU19UT1RBTCJdICAgPC0gInNhc3MiCnNhc3NfZGF0YSRudW1faWQgPC0gcmVhZHI6OnBhcnNlX251bWJlcihzYXNzX2RhdGEkSURfZ3NoZWV0KQpwYWluRW1wYXRoeV9kYXRhIDwtIG1lcmdlKHBhaW5FbXBhdGh5X2RhdGEsIHNhc3NfZGF0YVtjKCdzYXNzJywgJ251bV9pZCcpXSwgYnkgPSAnbnVtX2lkJykKcGFpbkVtcGF0aHlfZGF0YSRzYXNzX2NlbnRlcmVkIDwtIHBhaW5FbXBhdGh5X2RhdGEkc2FzcyAtIG1lYW4ocGFpbkVtcGF0aHlfZGF0YSRzYXNzLCBuYS5ybT1UUlVFKQp3cml0ZS5jc3YocGFpbkVtcGF0aHlfZGF0YSwgIGZpbGUucGF0aCgncGFpbkVtcGF0aHlfZGF0YV9jbGVhbi5jc3YnKSwgIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMgUGFydGljaXBhbnRzCmBgYHtyIHBhcnRpY2lwYW50cywgZmlnLndpZHRoID0gMTJ9Cm9wdGlvbnMod2lkdGggPSAxMDApCnh0YWJzKH4gc2V4LCBkYXRhID0gcGFpbkVtcGF0aHlfZGF0YSkgLyBsZW5ndGgodW5pcXVlKHBhaW5FbXBhdGh5X2RhdGEkY2hpbmRleCkpIC8gbGVuZ3RoKHVuaXF1ZShwYWluRW1wYXRoeV9kYXRhJHN0aW11bHVzKSkgIC8gbGVuZ3RoKHVuaXF1ZShwYWluRW1wYXRoeV9kYXRhJGNvbXBvbmVudCkpCmBgYAoKIyBFUlAgcGxvdHMKPGRpdiBjbGFzcz0iY3NsLWVudHJ5Ij5Eb25nLCBMLiwgTGksIEYuLCBMaXUsIFEuLCBXZW4sIFguLCBMYWksIFkuLCBYdSwgUC4sICYjMzg7IFlhbywgRC4gKDIwMTcpLiBNQVRMQUIgVG9vbGJveGVzIGZvciBSZWZlcmVuY2UgRWxlY3Ryb2RlIFN0YW5kYXJkaXphdGlvbiBUZWNobmlxdWUgKFJFU1QpIG9mIFNjYWxwIEVFRy4gPGk+RnJvbnRpZXJzIGluIE5ldXJvc2NpZW5jZTwvaT4sIDxpPjExPC9pPihPQ1QpLCA2MDEuIGh0dHBzOi8vZG9pLm9yZy8xMC4zMzg5L2ZuaW5zLjIwMTcuMDA2MDE8L2Rpdj4KIyMgUGFpbiAmIG5vLVBhaW4gRVJQczoKIVtdKHBhaW5FbXBhdGh5LnBuZykKCiMjIFRvcG9ncmFwaGljIGxheW91dDoKIVtdKHBhaW5FbXBhdGh5X3RvcG9ncmFwaHkucG5nKQoKIyBHZW5lcmFsIGRlc2NyaXB0aW9uCmBgYHtyIGdlbmVyYWwsIGZpZy53aWR0aCA9IDEyfQpvcHRpb25zKHdpZHRoID0gMTAwKQpnZ3Bsb3QoCiAgcGFpbkVtcGF0aHlfZGF0YSwgYWVzKHggPSBhbXBsaXR1ZGUsIGZpbGwgPSBjb21wb25lbnQsIGNvbG9yID0gY29tcG9uZW50KSkgKwogIGdlb21faGlzdG9ncmFtKGFscGhhID0gLjQsIHBvc2l0aW9uID0gImlkZW50aXR5IikKc3VtbWFyeShwYWluRW1wYXRoeV9kYXRhKQpwYWluRW1wYXRoeV92YXJzIDwtIGMoJ3Nhc3NfY2VudGVyZWQnLCAnYW1wbGl0dWRlJykKYGBgCgojIFBhaW4gJiBOby1wYWluICoqYHIgdW5pcXVlKHBhaW5FbXBhdGh5X3AyX2RhdGEkbWxhYmVsKWAqKiwgYXZlcmFnZSBmcm9tIGByIHBhc3RlKHN0cnNwbGl0KHBhaW5FbXBhdGh5X3AyX25hbWUsIHNwbGl0ID0gIl8iKVtbMV1dWzM6NV0sIGNvbGxhcHNlID0gJyAnKWAgbXMKIyMgU2NhbHAgdm9sdGFnZSBkaXN0cmlidXRpb246CiFbXShwYWluRW1wYXRoeV9zY2FscF9QMi5wbmcpCgojIyBgciB1bmlxdWUocGFpbkVtcGF0aHlfcDJfZGF0YSRtbGFiZWwpYCBieSBzZXggJiBzdGltdWx1czoKYGBge3IgcDIsIGZpZy53aWR0aCA9IDEyfQpvcHRpb25zKHdpZHRoID0gMTAwKQpwYWluRW1wYXRoeV9wMl9yZXBfYW5vdmEgPSBhb3ZfZXooCiAgIm51bV9pZCIsICJhbXBsaXR1ZGUiLCBzdWJzZXQocGFpbkVtcGF0aHlfZGF0YSwgY29tcG9uZW50ID09ICJQMiIsKSwKICB3aXRoaW4gPSBjKCJzdGltdWx1cyIsICJlbGVjdHJvZGUiKSwgYmV0d2VlbiA9ICJzZXgiLCBjb3ZhcmlhdGUgPSAic2Fzc19jZW50ZXJlZCIsIGZhY3Rvcml6ZSA9IEZBTFNFCiAgKQpwYWluRW1wYXRoeV9wMl9hZmV4X3Bsb3QgPC0KICBhZmV4X3Bsb3QoCiAgICBwYWluRW1wYXRoeV9wMl9yZXBfYW5vdmEsCiAgICB4ICAgICA9ICJlbGVjdHJvZGUiLAogICAgdHJhY2UgPSAic3RpbXVsdXMiLAogICAgcGFuZWwgPSAic2V4IiwKICAgIGVycm9yID0gIndpdGhpbiIsCiAgICBlcnJvcl9hcmcgPSBsaXN0KHdpZHRoID0gLjI1KSwKICAgIGRvZGdlICAgICA9IC0uNSwKICAgIG1hcHBpbmcgICA9IGMoImNvbG9yIiksCiAgICBwb2ludF9hcmcgPSBsaXN0KHNpemUgPSA0KQogICkKbmljZShwYWluRW1wYXRoeV9wMl9yZXBfYW5vdmEpCnN1cHByZXNzV2FybmluZ3MocHJpbnQocGFpbkVtcGF0aHlfcDJfYWZleF9wbG90KSkKYV9wb3N0ZXJpb3JpKHBhaW5FbXBhdGh5X3AyX3JlcF9hbm92YSkKYGBgCgojIFBhaW4gJiBOby1wYWluICoqYHIgdW5pcXVlKHBhaW5FbXBhdGh5X3AzX2RhdGEkbWxhYmVsKWAqKiwgYXZlcmFnZSBmcm9tIGByIHBhc3RlKHN0cnNwbGl0KHBhaW5FbXBhdGh5X3AzX25hbWUsIHNwbGl0ID0gIl8iKVtbMV1dWzM6NV0sIGNvbGxhcHNlID0gJyAnKWAgbXMKIyMgU2NhbHAgdm9sdGFnZSBkaXN0cmlidXRpb246CiFbXShwYWluRW1wYXRoeV9zY2FscF9QMy5wbmcpCgojIyBgciB1bmlxdWUocGFpbkVtcGF0aHlfcDNfZGF0YSRtbGFiZWwpYCBieSBzZXggJiBzdGltdWx1czoKYGBge3IgcDMsIGZpZy53aWR0aCA9IDEyfQpvcHRpb25zKHdpZHRoID0gMTAwKQpwYWluRW1wYXRoeV9wM19yZXBfYW5vdmEgPSBhb3ZfZXooCiAgIm51bV9pZCIsICJhbXBsaXR1ZGUiLCBzdWJzZXQocGFpbkVtcGF0aHlfZGF0YSwgY29tcG9uZW50ID09ICJQMyIpLAogIHdpdGhpbiA9IGMoInN0aW11bHVzIiwgImVsZWN0cm9kZSIpLCBiZXR3ZWVuID0gInNleCIsIGNvdmFyaWF0ZSA9ICJzYXNzX2NlbnRlcmVkIiwgZmFjdG9yaXplID0gRkFMU0UKICApCnBhaW5FbXBhdGh5X3AzX2FmZXhfcGxvdCA8LQogIGFmZXhfcGxvdCgKICAgIHBhaW5FbXBhdGh5X3AzX3JlcF9hbm92YSwKICAgIHggICAgID0gImVsZWN0cm9kZSIsCiAgICB0cmFjZSA9ICJzdGltdWx1cyIsCiAgICBwYW5lbCA9ICJzZXgiLAogICAgZXJyb3IgPSAid2l0aGluIiwKICAgIGVycm9yX2FyZyA9IGxpc3Qod2lkdGggPSAuMjUpLAogICAgZG9kZ2UgICAgID0gLS41LAogICAgbWFwcGluZyAgID0gYygiY29sb3IiKSwKICAgIHBvaW50X2FyZyA9IGxpc3Qoc2l6ZSA9IDQpCiAgKQpuaWNlKHBhaW5FbXBhdGh5X3AzX3JlcF9hbm92YSkKc3VwcHJlc3NXYXJuaW5ncyhwcmludChwYWluRW1wYXRoeV9wM19hZmV4X3Bsb3QpKQphX3Bvc3RlcmlvcmkocGFpbkVtcGF0aHlfcDNfcmVwX2Fub3ZhKQpgYGAKCiMgTWFzcyB1bml2YXJpYXRlIGFuYWx5c2lzIChjbHVzdGVyLW1hc3MpCjxkaXYgY2xhc3M9ImNzbC1lbnRyeSI+R3JvcHBlLCBELiBNLiwgVXJiYWNoLCBULiBQLiwgJiMzODsgS3V0YXMsIE0uICgyMDExKS4gTWFzcyB1bml2YXJpYXRlIGFuYWx5c2lzIG9mIGV2ZW50LXJlbGF0ZWQgYnJhaW4gcG90ZW50aWFscy9maWVsZHMgSTogQSBjcml0aWNhbCB0dXRvcmlhbCByZXZpZXcuIDxpPlBzeWNob3BoeXNpb2xvZ3k8L2k+LCA8aT40ODwvaT4oMTIpLCAxNzEx4oCTMTcyNS4gaHR0cHM6Ly9kb2kub3JnLzEwLjExMTEvSi4xNDY5LTg5ODYuMjAxMS4wMTI3My5YPC9kaXY+CiMjIEVhcmx5IHRpbWUgd2luZG93CiFbXShtYXNzL2Vhcmx5IHBhaW5FbXBhdGh5IHJhc3RlciBtYXNzIGNsdXN0LnBuZykKCiMjIExhdGUgdGltZSB3aW5kb3cKIVtdKG1hc3MvbGF0ZSBwYWluRW1wYXRoeSByYXN0ZXIgbWFzcyBjbHVzdC5wbmcpCgojIE11bHRpdmFyaWF0ZSBwYXR0ZXJuIGFuYWx5c2lzIChkZWNvZGluZykKKipPY2NpcGl0YWwgY2hhbm5lbHM6KipcClBPNywgUE8zLCBQT3osIFBPNCwgUE84XApPMSwgT3osIE8yXApJegoKRmFocmVuZm9ydCwgSi4gSi4sIHZhbiBEcmllbCwgSi4sIHZhbiBHYWFsLCBTLiwgJiBPbGl2ZXJzLCBDLiBOLiBMLiAoMjAxOCkuIEZyb20gRVJQcyB0byBNVlBBIHVzaW5nIHRoZSBBbXN0ZXJkYW0gRGVjb2RpbmcgYW5kIE1vZGVsaW5nIHRvb2xib3ggKEFEQU0pLiBGcm9udGllcnMgaW4gTmV1cm9zY2llbmNlLCAxMihKVUwpLCAzNTE1ODYuIGh0dHBzOi8vZG9pLm9yZy8xMC4zMzg5L0ZOSU5TLjIwMTguMDAzNjgvQklCVEVYCgojIyBFeGVtcGxhciBFUlAgb24gUE84CiFbXSguLi8uLi9BREFNL1BMT1RTLzAxX2V4ZW1wbGFyX0VSUC5wbmcpCgojIyBEZWNvZGluZyBvdmVyIHRpbWUKIVtdKC4uLy4uL0FEQU0vUExPVFMvMDJfZGVjb2Rpbmdfb3Zlcl90aW1lLnBuZykKCiMjIEluZGl2aWR1YWwgcmVzdWx0cywgcHJldHR5IHNoaXR0eQohW10oLi4vLi4vQURBTS9QTE9UUy8wM19kZWNvZGluZ19ieV9zdWJqZWN0LnBuZykKCiMjIFRlbXBvcmFsIGdlbmVyYWxpemF0aW9uIHBsb3QKIVtdKC4uLy4uL0FEQU0vUExPVFMvMDVfdGVtcG9yYWxfZ2VuZXJhbGl6YXRpb24ucG5nKQ==