# Set general settings for markdown file
knitr::opts_chunk$set(
  message = FALSE,
  warning = FALSE)


# Clear environment
rm(list = ls())


# Load packages
library(dplyr)      # for data wrangling
library(knitr)      # for integrating computing and reporting in markdown
library(kableExtra) # for customizing appearance of tables
library(foreign)    # for reading in SPSS file
library(psych)      # for describeBy function
library(tidyr)      # for gather and spread function


# Load functions
source("./functions/my_table_template.R")


# Turn off scientific notation
options(scipen = 999)


Sample Description


  • The final sample consisted of 28 patients with OCD and 28 healthy control (HC) participants.

  • Patients with OCD and healthy control participants were individually matched for age, gender, and educational level.

  • Patients were diagnosed using the Structured Clinical Interview for DSM-IV (SCID-I; Wittchen et al., 1997) and were recruited from the outpatient clinic for OCD at Humboldt-Universität zu Berlin.

  • All participants were native German speakers and had normal or corrected-to-normal vision.

  • Exclusion criteria were lifetime diagnosis of bipolar, psychotic, or substance-related disorders; neurological diseases; and use of neuroleptic medication in the last 3 months or benzodiazepines in the last week.

  • Additional exclusion criteria for control participants were any current or past psychiatric disorder or psychotherapeutic treatment.


Sample Characteristics


This table corresponds to Table 1 in the manuscript.

# Load data
participant_data <- read.spss("./data/Probandendaten.sav", to.data.frame = TRUE)
load(file = "./data/Trait_Data.rda")


# Prepare dataframe
demographics <- participant_data %>%
  # Prepare id variable for merging and add group variable
  dplyr::mutate(participant_id = as.factor(paste0(substr(Code, 13, 13), "_", substr(Code, 14, 15))),
                group = as.factor(ifelse(substr(participant_id, 1, 1) == "C", "HC", "OCD"))) %>%
  # Exclude P_02 and C_02 and row with NA
  dplyr::filter(participant_id != "P_02" & participant_id != "C_02" & !is.na(Alter)) %>%
  # Rename columns
  dplyr::rename(
    "Age (years)"                = Alter,
    "Gender"                     = Geschlecht,
    "Years of education"         = Schuljahre,
    "Y-BOCS total score"         = YBOCS_gesamt,
    "Y-BOCS obsessions"          = YBOCS_Gedanken,
    "Y-BOCS compulsions"         = YBOCS_Handlungen,
    "Verbal intelligence (WST)"  = WST,
    "Handedness"                 = "Händigkeit") %>%
  # Merge trait data
  dplyr::left_join(., traits, by = "participant_id") %>%
  # Select and reorder columns
  dplyr::select(c("group", "Age (years)", "Gender", "Years of education", "Verbal intelligence (WST)", "Handedness",
    "BDI-II",  "OCI-R", "PSWQ", "STAI trait", "Y-BOCS total score",  "Y-BOCS obsessions", "Y-BOCS compulsions"))


# Transform WST scores (range 24-37) to IQ scores (according to WST manual)
demographics[demographics$"Verbal intelligence (WST)" == 24, ]$"Verbal intelligence (WST)" <- 89
demographics[demographics$"Verbal intelligence (WST)" == 25, ]$"Verbal intelligence (WST)" <- 90
demographics[demographics$"Verbal intelligence (WST)" == 27, ]$"Verbal intelligence (WST)" <- 93
demographics[demographics$"Verbal intelligence (WST)" == 28, ]$"Verbal intelligence (WST)" <- 95
demographics[demographics$"Verbal intelligence (WST)" == 29, ]$"Verbal intelligence (WST)" <- 97
demographics[demographics$"Verbal intelligence (WST)" == 30, ]$"Verbal intelligence (WST)" <- 99
demographics[demographics$"Verbal intelligence (WST)" == 31, ]$"Verbal intelligence (WST)" <- 101
demographics[demographics$"Verbal intelligence (WST)" == 32, ]$"Verbal intelligence (WST)" <- 104
demographics[demographics$"Verbal intelligence (WST)" == 33, ]$"Verbal intelligence (WST)" <- 107
demographics[demographics$"Verbal intelligence (WST)" == 34, ]$"Verbal intelligence (WST)" <- 110
demographics[demographics$"Verbal intelligence (WST)" == 35, ]$"Verbal intelligence (WST)" <- 114
demographics[demographics$"Verbal intelligence (WST)" == 36, ]$"Verbal intelligence (WST)" <- 118
demographics[demographics$"Verbal intelligence (WST)" == 37, ]$"Verbal intelligence (WST)" <- 122


# Rescore one handedness score (according to EHI score that deviates from self report)
demographics[demographics$"Handedness" == "beidhändig" & 
             demographics$"Age (years)" == 29, ]$"Handedness" <- "rechts"



### Numeric variables

# Extract demographics per group
demographics_groups <- list()
demographics_groups <- describeBy(demographics %>% dplyr::select(-c("Gender", "Handedness", "group")), demographics$group)
ocd <- as.data.frame(demographics_groups$`OCD`)
hc  <- as.data.frame(demographics_groups$`HC`)


# Create table with demographics formatted as "M (SD)"
demographics_groups <- as.data.frame(cbind(
  Characteristic = rownames(ocd),
  ocd = paste0(format(round(ocd$mean, 2), nsmall = 2), " (", format(round(ocd$sd, 2), nsmall = 2), ")"),
  hc  = paste0(format(round(hc$mean,  2), nsmall = 2), " (", format(round(hc$sd,  2), nsmall = 2), ")")))


# Calculate t tests
t_tests <- demographics %>%
  dplyr::select("Age (years)", "Years of education", "Verbal intelligence (WST)", "BDI-II", "OCI-R",
    "PSWQ", "STAI trait", "group") %>%
  tidyr::gather(key = Characteristic, value = value, -group) %>%
  dplyr::group_by(group, Characteristic) %>%
  dplyr::summarise(value = list(value)) %>%
  tidyr::spread(group, value) %>%
  dplyr::ungroup() %>%
  dplyr::group_by(Characteristic) %>%
  dplyr::mutate("Test statistic" = t.test(unlist(HC), unlist(OCD))$statistic,
                              df = t.test(unlist(HC), unlist(OCD))$parameter,
                              p  = t.test(unlist(HC), unlist(OCD))$p.value) %>%
  dplyr::select(-c(HC, OCD))  %>%
  dplyr::ungroup()


# Combine demographics and t test results
demographics_numeric <- left_join(demographics_groups, t_tests, by = "Characteristic")



### Count variables (gender, handedness)

# Gender: calculate chi-squared test and extract counts formatted as "female:male"
gender_test <- chisq.test(demographics$Gender, demographics$group)
gender      <- demographics %>% dplyr::group_by(group) %>% dplyr::count(Gender)
gender_ocd  <- paste0(gender[gender$group == "OCD" & gender$Gender == "weiblich", ]$n, ":",
                      gender[gender$group == "OCD" & gender$Gender == "männlich", ]$n)
gender_hc   <- paste0(gender[gender$group == "HC"  & gender$Gender == "weiblich", ]$n, ":",
                      gender[gender$group == "HC"  & gender$Gender == "männlich", ]$n)


# Handedness: calculate Fishers's exact test and extract counts formatted as "right:left:ambidextrous"
hand_test <- fisher.test(demographics$Handedness, demographics$group)
hand      <- demographics %>% dplyr::group_by(group) %>% dplyr::count(Handedness)
hand_ocd  <- paste0(hand[hand$group == "OCD" & hand$Handedness == "rechts", ]$n, ":",
                    hand[hand$group == "OCD" & hand$Handedness == "links", ]$n, ":",
                    hand[hand$group == "OCD" & hand$Handedness == "beidhändig", ]$n)
hand_hc   <- paste0(hand[hand$group == "HC"  & hand$Handedness == "rechts", ]$n, ":",
                    hand[hand$group == "HC"  & hand$Handedness == "links", ]$n, ":",
                    length(hand[hand$group == "HC" & hand$Handedness == "beidhändig", ]$n))


# Combine demographics and chi-squared test/Fisher's exact test
demographics_factorial <- as.data.frame(cbind(
  Characteristic = c("Gender (n female:male)", "Handedness (n right:left:ambidextrous)"),
  ocd = c(gender_ocd, hand_ocd),
  hc  = c(gender_hc,  hand_hc),
  "Test statistic" = c(gender_test$statistic, "-"),
  df = c(gender_test$parameter, "-"),
  p = c(gender_test$p.value, hand_test$p.value)))



### Create and display table

# Re-order rows and format p values
table <- rbind(demographics_numeric[c(1), ], demographics_factorial,
               demographics_numeric[c(2:nrow(demographics_numeric)), ])
table[, c("df", "Test statistic", "p")] <- as.numeric(unlist(table[, c("df", "Test statistic", "p")]))
table[, c("p")] <- format.pval(table[, c("p")], eps = 0.001, digits = 3)
table <- table %>% dplyr::rename("Patients with OCD" = ocd, "Healthy control participants" = hc)


# Display table
my_table_template(table, 
  caption = "Demographic and Clinical Characteristics") %>%
  add_footnote(
  "\n Note. Means are reported with standard deviations in parentheses (except for gender and handedness). 
  Welch’s t test was used for continuous variables. Age range was 18 to 55 years  (control participants: 20 to 54 years; 
  patients with OCD: 18 to 55 years). Handedness was assessed with the Edinburgh Handedness Inventory (Oldfield, 1971). 
  For Fisher’s exact test, there is no test statistic to report. Years of education include primary and secondary education. 
  WST = Wortschatztest; BDI-II = Beck Depression Inventory-II; OCI-R = Obsessive-Compulsive Inventory-Revised; 
  PSWQ = Penn State Worry Questionnaire; STAI = State-Trait Anxiety Inventory; Y-BOCS = Yale-Brown Obsessive 
  Compulsive Scale.", notation = "none")
Demographic and Clinical Characteristics
Characteristic Patients with OCD Healthy control participants Test statistic df p
Age (years) 33.29 ( 8.57) 33.07 (8.20) -0.10 53.90 0.924
Gender (n female:male) 17:11 17:11 0.00 1.00 1.000
Handedness (n right:left:ambidextrous) 26:1:1 27:1:0 NA NA 1.000
Years of education 12.14 ( 1.46) 12.14 (1.08) 0.00 49.74 1.000
Verbal intelligence (WST) 104.93 ( 7.14) 105.71 (8.30) 0.38 52.81 0.706
BDI-II 14.14 (11.34) 1.86 (2.69) -5.58 30.03 <0.001
OCI-R 25.75 ( 9.95) 6.25 (5.65) -9.02 42.75 <0.001
PSWQ 61.21 (10.82) 37.07 (9.86) -8.73 53.54 <0.001
STAI trait 53.29 (10.08) 32.29 (7.22) -8.96 48.92 <0.001
Y-BOCS total score 23.36 ( 3.84) NaN ( NA) NA NA NA
Y-BOCS obsessions 11.43 ( 1.81) NaN ( NA) NA NA NA
Y-BOCS compulsions 11.86 ( 2.53) NaN ( NA) NA NA NA

Note. Means are reported with standard deviations in parentheses (except for gender and handedness).
Welch’s t test was used for continuous variables. Age range was 18 to 55 years (control participants: 20 to 54 years;
patients with OCD: 18 to 55 years). Handedness was assessed with the Edinburgh Handedness Inventory (Oldfield, 1971).
For Fisher’s exact test, there is no test statistic to report. Years of education include primary and secondary education.
WST = Wortschatztest; BDI-II = Beck Depression Inventory-II; OCI-R = Obsessive-Compulsive Inventory-Revised;
PSWQ = Penn State Worry Questionnaire; STAI = State-Trait Anxiety Inventory; Y-BOCS = Yale-Brown Obsessive
Compulsive Scale.



References


Wittchen, H., Zaudig, M., & Fydrich, T. (1997). Strukturiertes klinisches Interview für DSM-IV (SKID). Hogrefe.



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] tidyr_1.2.1      psych_2.2.9      foreign_0.8-71   kableExtra_1.3.4
## [5] knitr_1.40       dplyr_1.0.10    
## 
## loaded via a namespace (and not attached):
##  [1] tidyselect_1.2.0  xfun_0.33         bslib_0.4.0       purrr_0.3.5      
##  [5] lattice_0.20-45   colorspace_2.0-3  vctrs_0.5.0       generics_0.1.3   
##  [9] htmltools_0.5.3   viridisLite_0.4.1 yaml_2.2.1        utf8_1.2.2       
## [13] rlang_1.0.6       jquerylib_0.1.4   pillar_1.8.1      glue_1.6.2       
## [17] withr_2.5.0       DBI_1.1.3         lifecycle_1.0.3   stringr_1.4.1    
## [21] munsell_0.5.0     rvest_1.0.3       evaluate_0.16     fastmap_1.1.0    
## [25] parallel_3.6.1    fansi_1.0.3       highr_0.9         renv_0.12.0      
## [29] scales_1.2.1      cachem_1.0.4      webshot_0.5.4     jsonlite_1.8.3   
## [33] systemfonts_1.0.4 mnormt_2.1.1      digest_0.6.30     stringi_1.6.1    
## [37] grid_3.6.1        cli_3.4.1         tools_3.6.1       magrittr_2.0.3   
## [41] sass_0.4.0        tibble_3.1.8      pkgconfig_2.0.3   ellipsis_0.3.2   
## [45] xml2_1.3.3        assertthat_0.2.1  rmarkdown_2.16    svglite_2.1.0    
## [49] httr_1.4.4        rstudioapi_0.14   R6_2.5.1          nlme_3.1-140     
## [53] compiler_3.6.1
LS0tDQp0aXRsZTogIlBhcnRpY2lwYW50cyINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQNCi0tLQ0KDQo8IS0tIFNldCBnZW5lcmFsIHNldHRpbmdzIC0tPg0KDQpgYGB7ciBzZXR1cCwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9DQoNCiMgU2V0IGdlbmVyYWwgc2V0dGluZ3MgZm9yIG1hcmtkb3duIGZpbGUNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgbWVzc2FnZSA9IEZBTFNFLA0KICB3YXJuaW5nID0gRkFMU0UpDQoNCg0KIyBDbGVhciBlbnZpcm9ubWVudA0Kcm0obGlzdCA9IGxzKCkpDQoNCg0KIyBMb2FkIHBhY2thZ2VzDQpsaWJyYXJ5KGRwbHlyKSAgICAgICMgZm9yIGRhdGEgd3JhbmdsaW5nDQpsaWJyYXJ5KGtuaXRyKSAgICAgICMgZm9yIGludGVncmF0aW5nIGNvbXB1dGluZyBhbmQgcmVwb3J0aW5nIGluIG1hcmtkb3duDQpsaWJyYXJ5KGthYmxlRXh0cmEpICMgZm9yIGN1c3RvbWl6aW5nIGFwcGVhcmFuY2Ugb2YgdGFibGVzDQpsaWJyYXJ5KGZvcmVpZ24pICAgICMgZm9yIHJlYWRpbmcgaW4gU1BTUyBmaWxlDQpsaWJyYXJ5KHBzeWNoKSAgICAgICMgZm9yIGRlc2NyaWJlQnkgZnVuY3Rpb24NCmxpYnJhcnkodGlkeXIpICAgICAgIyBmb3IgZ2F0aGVyIGFuZCBzcHJlYWQgZnVuY3Rpb24NCg0KDQojIExvYWQgZnVuY3Rpb25zDQpzb3VyY2UoIi4vZnVuY3Rpb25zL215X3RhYmxlX3RlbXBsYXRlLlIiKQ0KDQoNCiMgVHVybiBvZmYgc2NpZW50aWZpYyBub3RhdGlvbg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpDQpgYGANCjxicj4NCg0KIyMgU2FtcGxlIERlc2NyaXB0aW9uDQoqKioNCg0KKiBUaGUgZmluYWwgc2FtcGxlIGNvbnNpc3RlZCBvZiAyOCBwYXRpZW50cyB3aXRoIE9DRCBhbmQgMjggaGVhbHRoeSBjb250cm9sIChIQykgcGFydGljaXBhbnRzLiANCg0KKiBQYXRpZW50cyB3aXRoIE9DRCBhbmQgaGVhbHRoeSBjb250cm9sIHBhcnRpY2lwYW50cyB3ZXJlIGluZGl2aWR1YWxseSBtYXRjaGVkIGZvciBhZ2UsIGdlbmRlciwgYW5kIGVkdWNhdGlvbmFsIGxldmVsLg0KDQoqIFBhdGllbnRzIHdlcmUgZGlhZ25vc2VkIHVzaW5nIHRoZSBTdHJ1Y3R1cmVkIENsaW5pY2FsIEludGVydmlldyBmb3IgRFNNLUlWIChTQ0lELUk7IFdpdHRjaGVuIGV0IGFsLiwgMTk5NykgYW5kIHdlcmUgcmVjcnVpdGVkIGZyb20gdGhlIG91dHBhdGllbnQgY2xpbmljIGZvciBPQ0QgYXQgSHVtYm9sZHQtVW5pdmVyc2l0w6R0IHp1IEJlcmxpbi4gDQoNCiogQWxsIHBhcnRpY2lwYW50cyB3ZXJlIG5hdGl2ZSBHZXJtYW4gc3BlYWtlcnMgYW5kIGhhZCBub3JtYWwgb3IgY29ycmVjdGVkLXRvLW5vcm1hbCB2aXNpb24uIA0KDQoqIEV4Y2x1c2lvbiBjcml0ZXJpYSB3ZXJlIGxpZmV0aW1lIGRpYWdub3NpcyBvZiBiaXBvbGFyLCBwc3ljaG90aWMsIG9yIHN1YnN0YW5jZS1yZWxhdGVkIGRpc29yZGVyczsgbmV1cm9sb2dpY2FsIGRpc2Vhc2VzOyBhbmQgdXNlIG9mIG5ldXJvbGVwdGljIG1lZGljYXRpb24gaW4gdGhlIGxhc3QgMyBtb250aHMgb3IgYmVuem9kaWF6ZXBpbmVzIGluIHRoZSBsYXN0IHdlZWsuIA0KDQoqIEFkZGl0aW9uYWwgZXhjbHVzaW9uIGNyaXRlcmlhIGZvciBjb250cm9sIHBhcnRpY2lwYW50cyB3ZXJlIGFueSBjdXJyZW50IG9yIHBhc3QgcHN5Y2hpYXRyaWMgZGlzb3JkZXIgb3IgcHN5Y2hvdGhlcmFwZXV0aWMgdHJlYXRtZW50LiAgDQo8YnI+PGJyPg0KDQojIyBTYW1wbGUgQ2hhcmFjdGVyaXN0aWNzDQoqKioNCg0KVGhpcyB0YWJsZSBjb3JyZXNwb25kcyB0byBUYWJsZSAxIGluIHRoZSBtYW51c2NyaXB0Lg0KDQpgYGB7ciBkZW1vZ3JhcGhpY3N9DQoNCiMgTG9hZCBkYXRhDQpwYXJ0aWNpcGFudF9kYXRhIDwtIHJlYWQuc3BzcygiLi9kYXRhL1Byb2JhbmRlbmRhdGVuLnNhdiIsIHRvLmRhdGEuZnJhbWUgPSBUUlVFKQ0KbG9hZChmaWxlID0gIi4vZGF0YS9UcmFpdF9EYXRhLnJkYSIpDQoNCg0KIyBQcmVwYXJlIGRhdGFmcmFtZQ0KZGVtb2dyYXBoaWNzIDwtIHBhcnRpY2lwYW50X2RhdGEgJT4lDQogICMgUHJlcGFyZSBpZCB2YXJpYWJsZSBmb3IgbWVyZ2luZyBhbmQgYWRkIGdyb3VwIHZhcmlhYmxlDQogIGRwbHlyOjptdXRhdGUocGFydGljaXBhbnRfaWQgPSBhcy5mYWN0b3IocGFzdGUwKHN1YnN0cihDb2RlLCAxMywgMTMpLCAiXyIsIHN1YnN0cihDb2RlLCAxNCwgMTUpKSksDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBhcy5mYWN0b3IoaWZlbHNlKHN1YnN0cihwYXJ0aWNpcGFudF9pZCwgMSwgMSkgPT0gIkMiLCAiSEMiLCAiT0NEIikpKSAlPiUNCiAgIyBFeGNsdWRlIFBfMDIgYW5kIENfMDIgYW5kIHJvdyB3aXRoIE5BDQogIGRwbHlyOjpmaWx0ZXIocGFydGljaXBhbnRfaWQgIT0gIlBfMDIiICYgcGFydGljaXBhbnRfaWQgIT0gIkNfMDIiICYgIWlzLm5hKEFsdGVyKSkgJT4lDQogICMgUmVuYW1lIGNvbHVtbnMNCiAgZHBseXI6OnJlbmFtZSgNCiAgICAiQWdlICh5ZWFycykiICAgICAgICAgICAgICAgID0gQWx0ZXIsDQogICAgIkdlbmRlciIgICAgICAgICAgICAgICAgICAgICA9IEdlc2NobGVjaHQsDQogICAgIlllYXJzIG9mIGVkdWNhdGlvbiIgICAgICAgICA9IFNjaHVsamFocmUsDQogICAgIlktQk9DUyB0b3RhbCBzY29yZSIgICAgICAgICA9IFlCT0NTX2dlc2FtdCwNCiAgICAiWS1CT0NTIG9ic2Vzc2lvbnMiICAgICAgICAgID0gWUJPQ1NfR2VkYW5rZW4sDQogICAgIlktQk9DUyBjb21wdWxzaW9ucyIgICAgICAgICA9IFlCT0NTX0hhbmRsdW5nZW4sDQogICAgIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiICA9IFdTVCwNCiAgICAiSGFuZGVkbmVzcyIgICAgICAgICAgICAgICAgID0gIkjDpG5kaWdrZWl0IikgJT4lDQogICMgTWVyZ2UgdHJhaXQgZGF0YQ0KICBkcGx5cjo6bGVmdF9qb2luKC4sIHRyYWl0cywgYnkgPSAicGFydGljaXBhbnRfaWQiKSAlPiUNCiAgIyBTZWxlY3QgYW5kIHJlb3JkZXIgY29sdW1ucw0KICBkcGx5cjo6c2VsZWN0KGMoImdyb3VwIiwgIkFnZSAoeWVhcnMpIiwgIkdlbmRlciIsICJZZWFycyBvZiBlZHVjYXRpb24iLCAiVmVyYmFsIGludGVsbGlnZW5jZSAoV1NUKSIsICJIYW5kZWRuZXNzIiwNCiAgICAiQkRJLUlJIiwgICJPQ0ktUiIsICJQU1dRIiwgIlNUQUkgdHJhaXQiLCAiWS1CT0NTIHRvdGFsIHNjb3JlIiwgICJZLUJPQ1Mgb2JzZXNzaW9ucyIsICJZLUJPQ1MgY29tcHVsc2lvbnMiKSkNCg0KDQojIFRyYW5zZm9ybSBXU1Qgc2NvcmVzIChyYW5nZSAyNC0zNykgdG8gSVEgc2NvcmVzIChhY2NvcmRpbmcgdG8gV1NUIG1hbnVhbCkNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDI0LCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSA4OQ0KZGVtb2dyYXBoaWNzW2RlbW9ncmFwaGljcyQiVmVyYmFsIGludGVsbGlnZW5jZSAoV1NUKSIgPT0gMjUsIF0kIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiIDwtIDkwDQpkZW1vZ3JhcGhpY3NbZGVtb2dyYXBoaWNzJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA9PSAyNywgXSQiVmVyYmFsIGludGVsbGlnZW5jZSAoV1NUKSIgPC0gOTMNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDI4LCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSA5NQ0KZGVtb2dyYXBoaWNzW2RlbW9ncmFwaGljcyQiVmVyYmFsIGludGVsbGlnZW5jZSAoV1NUKSIgPT0gMjksIF0kIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiIDwtIDk3DQpkZW1vZ3JhcGhpY3NbZGVtb2dyYXBoaWNzJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA9PSAzMCwgXSQiVmVyYmFsIGludGVsbGlnZW5jZSAoV1NUKSIgPC0gOTkNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDMxLCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMDENCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDMyLCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMDQNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDMzLCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMDcNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDM0LCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMTANCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDM1LCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMTQNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDM2LCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMTgNCmRlbW9ncmFwaGljc1tkZW1vZ3JhcGhpY3MkIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiID09IDM3LCBdJCJWZXJiYWwgaW50ZWxsaWdlbmNlIChXU1QpIiA8LSAxMjINCg0KDQojIFJlc2NvcmUgb25lIGhhbmRlZG5lc3Mgc2NvcmUgKGFjY29yZGluZyB0byBFSEkgc2NvcmUgdGhhdCBkZXZpYXRlcyBmcm9tIHNlbGYgcmVwb3J0KQ0KZGVtb2dyYXBoaWNzW2RlbW9ncmFwaGljcyQiSGFuZGVkbmVzcyIgPT0gImJlaWRow6RuZGlnIiAmIA0KICAgICAgICAgICAgIGRlbW9ncmFwaGljcyQiQWdlICh5ZWFycykiID09IDI5LCBdJCJIYW5kZWRuZXNzIiA8LSAicmVjaHRzIg0KDQoNCg0KIyMjIE51bWVyaWMgdmFyaWFibGVzDQoNCiMgRXh0cmFjdCBkZW1vZ3JhcGhpY3MgcGVyIGdyb3VwDQpkZW1vZ3JhcGhpY3NfZ3JvdXBzIDwtIGxpc3QoKQ0KZGVtb2dyYXBoaWNzX2dyb3VwcyA8LSBkZXNjcmliZUJ5KGRlbW9ncmFwaGljcyAlPiUgZHBseXI6OnNlbGVjdCgtYygiR2VuZGVyIiwgIkhhbmRlZG5lc3MiLCAiZ3JvdXAiKSksIGRlbW9ncmFwaGljcyRncm91cCkNCm9jZCA8LSBhcy5kYXRhLmZyYW1lKGRlbW9ncmFwaGljc19ncm91cHMkYE9DRGApDQpoYyAgPC0gYXMuZGF0YS5mcmFtZShkZW1vZ3JhcGhpY3NfZ3JvdXBzJGBIQ2ApDQoNCg0KIyBDcmVhdGUgdGFibGUgd2l0aCBkZW1vZ3JhcGhpY3MgZm9ybWF0dGVkIGFzICJNIChTRCkiDQpkZW1vZ3JhcGhpY3NfZ3JvdXBzIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoDQogIENoYXJhY3RlcmlzdGljID0gcm93bmFtZXMob2NkKSwNCiAgb2NkID0gcGFzdGUwKGZvcm1hdChyb3VuZChvY2QkbWVhbiwgMiksIG5zbWFsbCA9IDIpLCAiICgiLCBmb3JtYXQocm91bmQob2NkJHNkLCAyKSwgbnNtYWxsID0gMiksICIpIiksDQogIGhjICA9IHBhc3RlMChmb3JtYXQocm91bmQoaGMkbWVhbiwgIDIpLCBuc21hbGwgPSAyKSwgIiAoIiwgZm9ybWF0KHJvdW5kKGhjJHNkLCAgMiksIG5zbWFsbCA9IDIpLCAiKSIpKSkNCg0KDQojIENhbGN1bGF0ZSB0IHRlc3RzDQp0X3Rlc3RzIDwtIGRlbW9ncmFwaGljcyAlPiUNCiAgZHBseXI6OnNlbGVjdCgiQWdlICh5ZWFycykiLCAiWWVhcnMgb2YgZWR1Y2F0aW9uIiwgIlZlcmJhbCBpbnRlbGxpZ2VuY2UgKFdTVCkiLCAiQkRJLUlJIiwgIk9DSS1SIiwNCiAgICAiUFNXUSIsICJTVEFJIHRyYWl0IiwgImdyb3VwIikgJT4lDQogIHRpZHlyOjpnYXRoZXIoa2V5ID0gQ2hhcmFjdGVyaXN0aWMsIHZhbHVlID0gdmFsdWUsIC1ncm91cCkgJT4lDQogIGRwbHlyOjpncm91cF9ieShncm91cCwgQ2hhcmFjdGVyaXN0aWMpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXNlKHZhbHVlID0gbGlzdCh2YWx1ZSkpICU+JQ0KICB0aWR5cjo6c3ByZWFkKGdyb3VwLCB2YWx1ZSkgJT4lDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lDQogIGRwbHlyOjpncm91cF9ieShDaGFyYWN0ZXJpc3RpYykgJT4lDQogIGRwbHlyOjptdXRhdGUoIlRlc3Qgc3RhdGlzdGljIiA9IHQudGVzdCh1bmxpc3QoSEMpLCB1bmxpc3QoT0NEKSkkc3RhdGlzdGljLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYgPSB0LnRlc3QodW5saXN0KEhDKSwgdW5saXN0KE9DRCkpJHBhcmFtZXRlciwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAgID0gdC50ZXN0KHVubGlzdChIQyksIHVubGlzdChPQ0QpKSRwLnZhbHVlKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtYyhIQywgT0NEKSkgICU+JQ0KICBkcGx5cjo6dW5ncm91cCgpDQoNCg0KIyBDb21iaW5lIGRlbW9ncmFwaGljcyBhbmQgdCB0ZXN0IHJlc3VsdHMNCmRlbW9ncmFwaGljc19udW1lcmljIDwtIGxlZnRfam9pbihkZW1vZ3JhcGhpY3NfZ3JvdXBzLCB0X3Rlc3RzLCBieSA9ICJDaGFyYWN0ZXJpc3RpYyIpDQoNCg0KDQojIyMgQ291bnQgdmFyaWFibGVzIChnZW5kZXIsIGhhbmRlZG5lc3MpDQoNCiMgR2VuZGVyOiBjYWxjdWxhdGUgY2hpLXNxdWFyZWQgdGVzdCBhbmQgZXh0cmFjdCBjb3VudHMgZm9ybWF0dGVkIGFzICJmZW1hbGU6bWFsZSINCmdlbmRlcl90ZXN0IDwtIGNoaXNxLnRlc3QoZGVtb2dyYXBoaWNzJEdlbmRlciwgZGVtb2dyYXBoaWNzJGdyb3VwKQ0KZ2VuZGVyICAgICAgPC0gZGVtb2dyYXBoaWNzICU+JSBkcGx5cjo6Z3JvdXBfYnkoZ3JvdXApICU+JSBkcGx5cjo6Y291bnQoR2VuZGVyKQ0KZ2VuZGVyX29jZCAgPC0gcGFzdGUwKGdlbmRlcltnZW5kZXIkZ3JvdXAgPT0gIk9DRCIgJiBnZW5kZXIkR2VuZGVyID09ICJ3ZWlibGljaCIsIF0kbiwgIjoiLA0KICAgICAgICAgICAgICAgICAgICAgIGdlbmRlcltnZW5kZXIkZ3JvdXAgPT0gIk9DRCIgJiBnZW5kZXIkR2VuZGVyID09ICJtw6RubmxpY2giLCBdJG4pDQpnZW5kZXJfaGMgICA8LSBwYXN0ZTAoZ2VuZGVyW2dlbmRlciRncm91cCA9PSAiSEMiICAmIGdlbmRlciRHZW5kZXIgPT0gIndlaWJsaWNoIiwgXSRuLCAiOiIsDQogICAgICAgICAgICAgICAgICAgICAgZ2VuZGVyW2dlbmRlciRncm91cCA9PSAiSEMiICAmIGdlbmRlciRHZW5kZXIgPT0gIm3DpG5ubGljaCIsIF0kbikNCg0KDQojIEhhbmRlZG5lc3M6IGNhbGN1bGF0ZSBGaXNoZXJzJ3MgZXhhY3QgdGVzdCBhbmQgZXh0cmFjdCBjb3VudHMgZm9ybWF0dGVkIGFzICJyaWdodDpsZWZ0OmFtYmlkZXh0cm91cyINCmhhbmRfdGVzdCA8LSBmaXNoZXIudGVzdChkZW1vZ3JhcGhpY3MkSGFuZGVkbmVzcywgZGVtb2dyYXBoaWNzJGdyb3VwKQ0KaGFuZCAgICAgIDwtIGRlbW9ncmFwaGljcyAlPiUgZHBseXI6Omdyb3VwX2J5KGdyb3VwKSAlPiUgZHBseXI6OmNvdW50KEhhbmRlZG5lc3MpDQpoYW5kX29jZCAgPC0gcGFzdGUwKGhhbmRbaGFuZCRncm91cCA9PSAiT0NEIiAmIGhhbmQkSGFuZGVkbmVzcyA9PSAicmVjaHRzIiwgXSRuLCAiOiIsDQogICAgICAgICAgICAgICAgICAgIGhhbmRbaGFuZCRncm91cCA9PSAiT0NEIiAmIGhhbmQkSGFuZGVkbmVzcyA9PSAibGlua3MiLCBdJG4sICI6IiwNCiAgICAgICAgICAgICAgICAgICAgaGFuZFtoYW5kJGdyb3VwID09ICJPQ0QiICYgaGFuZCRIYW5kZWRuZXNzID09ICJiZWlkaMOkbmRpZyIsIF0kbikNCmhhbmRfaGMgICA8LSBwYXN0ZTAoaGFuZFtoYW5kJGdyb3VwID09ICJIQyIgICYgaGFuZCRIYW5kZWRuZXNzID09ICJyZWNodHMiLCBdJG4sICI6IiwNCiAgICAgICAgICAgICAgICAgICAgaGFuZFtoYW5kJGdyb3VwID09ICJIQyIgICYgaGFuZCRIYW5kZWRuZXNzID09ICJsaW5rcyIsIF0kbiwgIjoiLA0KICAgICAgICAgICAgICAgICAgICBsZW5ndGgoaGFuZFtoYW5kJGdyb3VwID09ICJIQyIgJiBoYW5kJEhhbmRlZG5lc3MgPT0gImJlaWRow6RuZGlnIiwgXSRuKSkNCg0KDQojIENvbWJpbmUgZGVtb2dyYXBoaWNzIGFuZCBjaGktc3F1YXJlZCB0ZXN0L0Zpc2hlcidzIGV4YWN0IHRlc3QNCmRlbW9ncmFwaGljc19mYWN0b3JpYWwgPC0gYXMuZGF0YS5mcmFtZShjYmluZCgNCiAgQ2hhcmFjdGVyaXN0aWMgPSBjKCJHZW5kZXIgKG4gZmVtYWxlOm1hbGUpIiwgIkhhbmRlZG5lc3MgKG4gcmlnaHQ6bGVmdDphbWJpZGV4dHJvdXMpIiksDQogIG9jZCA9IGMoZ2VuZGVyX29jZCwgaGFuZF9vY2QpLA0KICBoYyAgPSBjKGdlbmRlcl9oYywgIGhhbmRfaGMpLA0KICAiVGVzdCBzdGF0aXN0aWMiID0gYyhnZW5kZXJfdGVzdCRzdGF0aXN0aWMsICItIiksDQogIGRmID0gYyhnZW5kZXJfdGVzdCRwYXJhbWV0ZXIsICItIiksDQogIHAgPSBjKGdlbmRlcl90ZXN0JHAudmFsdWUsIGhhbmRfdGVzdCRwLnZhbHVlKSkpDQoNCg0KDQojIyMgQ3JlYXRlIGFuZCBkaXNwbGF5IHRhYmxlDQoNCiMgUmUtb3JkZXIgcm93cyBhbmQgZm9ybWF0IHAgdmFsdWVzDQp0YWJsZSA8LSByYmluZChkZW1vZ3JhcGhpY3NfbnVtZXJpY1tjKDEpLCBdLCBkZW1vZ3JhcGhpY3NfZmFjdG9yaWFsLA0KICAgICAgICAgICAgICAgZGVtb2dyYXBoaWNzX251bWVyaWNbYygyOm5yb3coZGVtb2dyYXBoaWNzX251bWVyaWMpKSwgXSkNCnRhYmxlWywgYygiZGYiLCAiVGVzdCBzdGF0aXN0aWMiLCAicCIpXSA8LSBhcy5udW1lcmljKHVubGlzdCh0YWJsZVssIGMoImRmIiwgIlRlc3Qgc3RhdGlzdGljIiwgInAiKV0pKQ0KdGFibGVbLCBjKCJwIildIDwtIGZvcm1hdC5wdmFsKHRhYmxlWywgYygicCIpXSwgZXBzID0gMC4wMDEsIGRpZ2l0cyA9IDMpDQp0YWJsZSA8LSB0YWJsZSAlPiUgZHBseXI6OnJlbmFtZSgiUGF0aWVudHMgd2l0aCBPQ0QiID0gb2NkLCAiSGVhbHRoeSBjb250cm9sIHBhcnRpY2lwYW50cyIgPSBoYykNCg0KDQojIERpc3BsYXkgdGFibGUNCm15X3RhYmxlX3RlbXBsYXRlKHRhYmxlLCANCiAgY2FwdGlvbiA9ICJEZW1vZ3JhcGhpYyBhbmQgQ2xpbmljYWwgQ2hhcmFjdGVyaXN0aWNzIikgJT4lDQogIGFkZF9mb290bm90ZSgNCiAgIlxuIE5vdGUuIE1lYW5zIGFyZSByZXBvcnRlZCB3aXRoIHN0YW5kYXJkIGRldmlhdGlvbnMgaW4gcGFyZW50aGVzZXMgKGV4Y2VwdCBmb3IgZ2VuZGVyIGFuZCBoYW5kZWRuZXNzKS4gDQogIFdlbGNo4oCZcyB0IHRlc3Qgd2FzIHVzZWQgZm9yIGNvbnRpbnVvdXMgdmFyaWFibGVzLiBBZ2UgcmFuZ2Ugd2FzIDE4IHRvIDU1IHllYXJzICAoY29udHJvbCBwYXJ0aWNpcGFudHM6IDIwIHRvIDU0IHllYXJzOyANCiAgcGF0aWVudHMgd2l0aCBPQ0Q6IDE4IHRvIDU1IHllYXJzKS4gSGFuZGVkbmVzcyB3YXMgYXNzZXNzZWQgd2l0aCB0aGUgRWRpbmJ1cmdoIEhhbmRlZG5lc3MgSW52ZW50b3J5IChPbGRmaWVsZCwgMTk3MSkuIA0KICBGb3IgRmlzaGVy4oCZcyBleGFjdCB0ZXN0LCB0aGVyZSBpcyBubyB0ZXN0IHN0YXRpc3RpYyB0byByZXBvcnQuIFllYXJzIG9mIGVkdWNhdGlvbiBpbmNsdWRlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBlZHVjYXRpb24uIA0KICBXU1QgPSBXb3J0c2NoYXR6dGVzdDsgQkRJLUlJID0gQmVjayBEZXByZXNzaW9uIEludmVudG9yeS1JSTsgT0NJLVIgPSBPYnNlc3NpdmUtQ29tcHVsc2l2ZSBJbnZlbnRvcnktUmV2aXNlZDsgDQogIFBTV1EgPSBQZW5uIFN0YXRlIFdvcnJ5IFF1ZXN0aW9ubmFpcmU7IFNUQUkgPSBTdGF0ZS1UcmFpdCBBbnhpZXR5IEludmVudG9yeTsgWS1CT0NTID0gWWFsZS1Ccm93biBPYnNlc3NpdmUgDQogIENvbXB1bHNpdmUgU2NhbGUuIiwgbm90YXRpb24gPSAibm9uZSIpDQpgYGANCjxicj48YnI+DQoNCiMjIFJlZmVyZW5jZXMNCioqKg0KV2l0dGNoZW4sIEguLCBaYXVkaWcsIE0uLCAmIEZ5ZHJpY2gsIFQuICgxOTk3KS4gKlN0cnVrdHVyaWVydGVzIGtsaW5pc2NoZXMgSW50ZXJ2aWV3IGbDvHIgRFNNLUlWIChTS0lEKS4qIEhvZ3JlZmUuIAkNCjxicj48YnI+PGJyPg0KDQojIyBTZXNzaW9uIEluZm8NCioqKg0KYGBge3Igc2Vzc2lvbi1pbmZvfQ0KDQpzZXNzaW9uSW5mbygpDQpgYGANCg==