This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

Right BST and SCR analysis

effect: contrast of shock response between uncontrol and control participants

library(brms) # for the analysis
Loading required package: Rcpp
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Loading 'brms' package (version 2.12.0). Useful instructions
can be found by typing help('brms'). A more detailed introduction
to the package is available through vignette('brms_overview').

Attaching package: ‘brms’

The following object is masked from ‘package:stats’:

    ar
library(haven) # to load the SPSS .sav file
library(tidyverse) # needed for data manipulation.
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.0     ✓ purrr   0.3.3
✓ tibble  3.0.0     ✓ dplyr   0.8.5
✓ tidyr   1.0.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(RColorBrewer) # needed for some extra colours in one of the graphs
library(ggmcmc)
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2
library(ggthemes)
library(ggridges)

Model

\[Y = N(\mu, \sigma_{\epsilon}^{2})\] \[\mu = \beta_{0} + \beta_{scr}SCR + \beta_{Sm}Sm + \beta_{Sd}Sd + \beta_{Tm}Tm + \beta_{Td}Td + \epsilon\] Where SCR, Tm, Td, Sm, and Sd are covariates.

SCR: Skin conductance response
Sm: State mean
Sd: State difference (uncon - con)
Tm: Trait mean
Td: Triat difference (uncon - con)

Priors

\[N(0,100): \beta_{0}\] \[N(0,100): \beta_{SCR}\] \[N(0,100): \beta_{Sm}\] \[N(0,100): \beta_{Sd}\] \[N(0,100): \beta_{Tm}\] \[N(0,100): \beta_{Td}\] \[Cauchy(0,100): \sigma_{\epsilon}\]

setwd("~/Pessoa_Lab/eCON/uncon_v_con_rBNST_SCR_with_covariates")

df <- read.table('../data/uncon_v_con_rBNST_SCR_with_covariates.txt',header=TRUE)
prior1 <- c(prior(normal(0,100),class=Intercept),
            prior(normal(0,100),class=b, coef='SCR'),
            prior(normal(0,100),class=b, coef="TRAITmean"),
            prior(normal(0,100),class=b, coef="TRAITdiff"),
            prior(normal(0,100),class=b, coef="STATEmean"),
            prior(normal(0,100),class=b, coef="STATEdiff"),
            prior(cauchy(0,100),class=sigma)
           )

bmod1 <- brm(y ~ SCR + TRAITmean + TRAITdiff + STATEmean + STATEdiff, 
             data = df, 
             family = gaussian(),
             prior = prior1, 
             warmup = 2000, iter = 5000,
             chains = 4,
             cores  = 2)
Compiling the C++ model
Start sampling
starting worker pid=22934 on localhost:11459 at 16:29:41.415
starting worker pid=22947 on localhost:11459 at 16:29:41.807

SAMPLING FOR MODEL 'efac36ec2d54f72a5790404396195cd1' NOW (CHAIN 1).
Chain 1: 
Chain 1: Gradient evaluation took 0 seconds
Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0 seconds.
Chain 1: Adjust your expectations accordingly!
Chain 1: 
Chain 1: 
Chain 1: Iteration:    1 / 5000 [  0%]  (Warmup)

SAMPLING FOR MODEL 'efac36ec2d54f72a5790404396195cd1' NOW (CHAIN 2).
Chain 2: 
Chain 2: Gradient evaluation took 0 seconds
Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0 seconds.
Chain 2: Adjust your expectations accordingly!
Chain 2: 
Chain 2: 
Chain 2: Iteration:    1 / 5000 [  0%]  (Warmup)
Chain 1: Iteration:  500 / 5000 [ 10%]  (Warmup)
Chain 2: Iteration:  500 / 5000 [ 10%]  (Warmup)
Chain 1: Iteration: 1000 / 5000 [ 20%]  (Warmup)
Chain 2: Iteration: 1000 / 5000 [ 20%]  (Warmup)
Chain 1: Iteration: 1500 / 5000 [ 30%]  (Warmup)
Chain 2: Iteration: 1500 / 5000 [ 30%]  (Warmup)
Chain 1: Iteration: 2000 / 5000 [ 40%]  (Warmup)
Chain 1: Iteration: 2001 / 5000 [ 40%]  (Sampling)
Chain 1: Iteration: 2500 / 5000 [ 50%]  (Sampling)
Chain 2: Iteration: 2000 / 5000 [ 40%]  (Warmup)
Chain 2: Iteration: 2001 / 5000 [ 40%]  (Sampling)
Chain 1: Iteration: 3000 / 5000 [ 60%]  (Sampling)
Chain 2: Iteration: 2500 / 5000 [ 50%]  (Sampling)
Chain 1: Iteration: 3500 / 5000 [ 70%]  (Sampling)
Chain 2: Iteration: 3000 / 5000 [ 60%]  (Sampling)
Chain 1: Iteration: 4000 / 5000 [ 80%]  (Sampling)
Chain 2: Iteration: 3500 / 5000 [ 70%]  (Sampling)
Chain 1: Iteration: 4500 / 5000 [ 90%]  (Sampling)
Chain 2: Iteration: 4000 / 5000 [ 80%]  (Sampling)
Chain 1: Iteration: 5000 / 5000 [100%]  (Sampling)
Chain 1: 
Chain 1:  Elapsed Time: 0.1 seconds (Warm-up)
Chain 1:                0.14 seconds (Sampling)
Chain 1:                0.24 seconds (Total)
Chain 1: 
Chain 2: Iteration: 4500 / 5000 [ 90%]  (Sampling)
Chain 2: Iteration: 5000 / 5000 [100%]  (Sampling)
Chain 2: 
Chain 2:  Elapsed Time: 0.1 seconds (Warm-up)
Chain 2:                0.15 seconds (Sampling)
Chain 2:                0.25 seconds (Total)
Chain 2: 

SAMPLING FOR MODEL 'efac36ec2d54f72a5790404396195cd1' NOW (CHAIN 3).
Chain 3: 
Chain 3: Gradient evaluation took 0 seconds
Chain 3: 1000 transitions using 10 leapfrog steps per transition would take 0 seconds.
Chain 3: Adjust your expectations accordingly!
Chain 3: 
Chain 3: 
Chain 3: Iteration:    1 / 5000 [  0%]  (Warmup)
Chain 3: Iteration:  500 / 5000 [ 10%]  (Warmup)
Chain 3: Iteration: 1000 / 5000 [ 20%]  (Warmup)
Chain 3: Iteration: 1500 / 5000 [ 30%]  (Warmup)

SAMPLING FOR MODEL 'efac36ec2d54f72a5790404396195cd1' NOW (CHAIN 4).
Chain 4: 
Chain 4: Gradient evaluation took 0 seconds
Chain 4: 1000 transitions using 10 leapfrog steps per transition would take 0 seconds.
Chain 4: Adjust your expectations accordingly!
Chain 4: 
Chain 4: 
Chain 4: Iteration:    1 / 5000 [  0%]  (Warmup)
Chain 3: Iteration: 2000 / 5000 [ 40%]  (Warmup)
Chain 3: Iteration: 2001 / 5000 [ 40%]  (Sampling)
Chain 4: Iteration:  500 / 5000 [ 10%]  (Warmup)
Chain 3: Iteration: 2500 / 5000 [ 50%]  (Sampling)
Chain 4: Iteration: 1000 / 5000 [ 20%]  (Warmup)
Chain 3: Iteration: 3000 / 5000 [ 60%]  (Sampling)
Chain 4: Iteration: 1500 / 5000 [ 30%]  (Warmup)
Chain 3: Iteration: 3500 / 5000 [ 70%]  (Sampling)
Chain 4: Iteration: 2000 / 5000 [ 40%]  (Warmup)
Chain 4: Iteration: 2001 / 5000 [ 40%]  (Sampling)
Chain 3: Iteration: 4000 / 5000 [ 80%]  (Sampling)
Chain 4: Iteration: 2500 / 5000 [ 50%]  (Sampling)
Chain 4: Iteration: 3000 / 5000 [ 60%]  (Sampling)
Chain 3: Iteration: 4500 / 5000 [ 90%]  (Sampling)
Chain 4: Iteration: 3500 / 5000 [ 70%]  (Sampling)
Chain 3: Iteration: 5000 / 5000 [100%]  (Sampling)
Chain 3: 
Chain 3:  Elapsed Time: 0.11 seconds (Warm-up)
Chain 3:                0.17 seconds (Sampling)
Chain 3:                0.28 seconds (Total)
Chain 3: 
Chain 4: Iteration: 4000 / 5000 [ 80%]  (Sampling)
Chain 4: Iteration: 4500 / 5000 [ 90%]  (Sampling)
Chain 4: Iteration: 5000 / 5000 [100%]  (Sampling)
Chain 4: 
Chain 4:  Elapsed Time: 0.1 seconds (Warm-up)
Chain 4:                0.15 seconds (Sampling)
Chain 4:                0.25 seconds (Total)
Chain 4: 

Model Summary

summary(bmod1)
 Family: gaussian 
  Links: mu = identity; sigma = identity 
Formula: y ~ SCR + TRAITmean + TRAITdiff + STATEmean + STATEdiff 
   Data: df (Number of observations: 57) 
Samples: 4 chains, each with iter = 5000; warmup = 2000; thin = 1;
         total post-warmup samples = 12000

Population-Level Effects: 
          Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept     0.11      0.06    -0.01     0.23 1.00    16398     7737
SCR          -0.08      0.05    -0.18     0.01 1.00    16915     9573
TRAITmean    -0.05      0.08    -0.20     0.11 1.00    12442     9990
TRAITdiff     0.10      0.07    -0.03     0.23 1.00    14623     9098
STATEmean     0.22      0.08     0.06     0.38 1.00    12104    10050
STATEdiff     0.08      0.06    -0.05     0.20 1.00    15980     9426

Family Specific Parameters: 
      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma     0.47      0.05     0.39     0.58 1.00    14859     9243

Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

Posteriors

data <- fixef(bmod1,summary = FALSE)
#write.csv(data,file = 'posteriors.csv')
# IMPORT LIBRARIES:
library(data.table)
library(ggplot2)
library(ggridges)
library(dplyr)
library(tidyr)
library(scales)
library(viridis)
Loading required package: viridisLite

Attaching package: ‘viridis’

The following object is masked from ‘package:scales’:

    viridis_pal
rois <- colnames(data)
#data$X <- NULL
nobj=dim(data)[1]

# rename columns with ROI list


data_stats = data.frame(1:length(rois))

# create ROI column instead of numerics to match threat table above

data_stats$ROI <- rois
data_stats$mean <- colMeans(data)
data_stats$P <- colSums(data > 0)/nobj
data_stats$Pn <- data_stats$P


for (i in 1:length(rois)) {
  if (data_stats$P[i]<.5){data_stats$Pn[i]=1-data_stats$P[i]}
}


# this will order the distributions correctly
data_stats <- data_stats[order(data_stats$mean),]



data_trans <- as.data.frame(t(as.matrix(data)))
data_trans <- tibble::rownames_to_column(data_trans, "ROI")
data_trans$X <- 1:nrow(data_trans)




# merge values & stats into one table by ROI

data_merge <- merge(data_stats, data_trans, by = "ROI")
data_merge <- data_merge[order(data_merge$X),]

# Transform data into long form


# Melt dataframe by ROI
library(data.table)

data_long <- melt(data_trans, id=c("ROI","X"))
The melt generic in data.table has been passed a data.frame and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is deprecated, and this redirection is now deprecated as well. To continue using melt methods from reshape2 while both libraries are attached, e.g. melt.list, you can prepend the namespace like reshape2::melt(data_trans). In the next version, this warning will become an error.
#threat_long <- melt(threat_trans, id=c("ROI","X.x"))


data_long <- data_long[order(data_long$X),]


# This is incredibly clunky, but for the sake of time adding stats by ensuring orders are all the same and repeating each value 2000 times... Tried a few different methods with no success for some reason. 

data_long$mean <- rep(data_merge$mean, each = nobj)
data_long$P <- rep(data_merge$P, each =nobj)
data_long$Pn <- rep(data_merge$Pn, each =nobj)

# set your labels here so you don't have to change within the plot below: 
format(round(1, 2), nsmall = 2)
[1] "1.00"
y.axis.labs <- format(round(data_stats$P,2), nsmall = 2)                        # y axis labels
sec.y.axis.labs <- data_stats$ROI                             # second y axis labels (probabilities)


 # X AXIS LABELS NEED TO CHANGE TO CORRESPOND TO DATA SET! UNCOMMENT WHICHEVER MATCHES

# Uncomment for THREAT
x.axis.labs <- c( "control > uncontrol", "0", "uncontrol > control")                 # x axis labels  THREAT
x.labs.pos <- c(-0.2, 0, 0.2)                                             # x axis position THREAT


# Uncomment for VALENCE
#x.axis.labs <- c("Neutral > Positive", "0", "Positive > Neutral")         # x axis labels  VALENCE
#x.labs.pos  <- c(-0.1,0,0.2)                                              # x axis position VALENCE

# Uncomment for INTERACTION
#x.axis.labs <- NULL                                                       # x axis labels  INTERACTION, not sure what to put.
#x.labs.pos <- NULL                                                        # a axis position INTERACTION, change when labels decided

#graph.title <- data.name                                   # graph title 
legend.title <- "Probability"                              # legend title
y.axis.title <- NULL                                       # for now ...
x.axis.title <- NULL                                       # for now...

# GRAPH DATA 
dataset <- data_long
x.values <- data_long$value                               # x values
y.values <- data_long$ROI                                 # y values
y.values.RO <- data_long$value                            # values to reorder Y by
distrib.fill <- data_long$Pn                              # fill graph with probabilities
group <- data_long$ROI

# Other aspects
gradient.colors <- c("yellow","#C9182B","#41245C")        # change gradient colors here (currently, yellow - purple)
label.size <- 12                                         # adjust ROI and probability y-axis font size
title.size <- 28                                          # adjust graph title size 
x.axis.size <- 12                                        # adjust x-axis label sizes

# here is where you can change information about the graph and add other characteristics using ggplot and ggridges


ggplot(dataset, aes(x = x.values, y = as.numeric(reorder(y.values, y.values.RO)), 
                    fill = distrib.fill, group = group)) +                        # scale = spacing, alpha = transparency
  coord_cartesian(xlim = c(-0.5, 0.5)) +
  stat_density_ridges(quantile_lines = TRUE, 
                      quantiles = 2, 
                      alpha = .95, 
                      scale = 2.55,
                      color = "black",
                      size = .35
                     ) +            # divide into two quantiles (show mean)
  geom_vline(xintercept = 0, linetype="solid",color = "black",alpha = .95, size = .45) +    #create line at X = 0
  scale_fill_gradientn(colors = viridis_pal(direction = 1, option = "inferno")(20),                         # set gradient
                       limits = c(.85,1),                                # which probabilites matter?
                       na.value = "#909497",                                # if not in limits, gray out
                       name = legend.title) +                            # name legend
  scale_y_continuous(breaks = 1:length(rois),                            # A VERY HACK-Y WAY TO HAVE TWO Y AXES W DISCRETE DATA
                     expand = c(0,0),
                     labels = y.axis.labs,                               # Trick ggplot into thinking data is continuous...
                     sec.axis = sec_axis(~.,                             # Second axis to show probabilities
                                         breaks = 1:length(rois),
                                         labels = sec.y.axis.labs)) +
  #theme_ridges(font_size = label.size, grid = TRUE, center_axis_labels = TRUE) +  # theme info
  #ggtitle(graph.title)+ 
  #theme_bw() +# graph title
 #theme_ridges(grid = FALSE) + 
  theme(   
    panel.background = element_blank(),
    legend.position = "none",
    #panel.grid.major.y = element_line(color = "grey"), 
    plot.title = element_text(hjust = 0.5, size = title.size),            # plot title size and position
    axis.text.y = element_text(size=label.size),                               # y-axis text size
    axis.line.x = element_line(color = "gray"),
    axis.text.y.right = element_text(size = label.size),                  # y-axis info for right axis
    axis.text.x = element_text(size = x.axis.size),
    #plot.margin = unit(c(0,0,0,0), "cm"),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    legend.title.align = 5)+
  guides(shape = guide_legend(label.position = "bottom",
                              title.positon = "bottom",
                              title.vjust = 0.4)) +          
  labs(
    x = NULL,                                                         # Add or not add X and Y labels
    y = NULL) +
  scale_x_continuous(breaks = x.labs.pos, labels = c(x.axis.labs))


#ggsave(file = paste0(strsplit(type,'.RData'),".jpg", sep=""), width=4.5, height=3, units = "in", dpi = 900)

# preview will look smooshed, be sure to look at the saved .jpg before making any changes to text size, etc!
#graph
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiAKClRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gCgojICoqUmlnaHQgQlNUIGFuZCBTQ1IgYW5hbHlzaXMqKgoKIyMjIGVmZmVjdDogY29udHJhc3Qgb2Ygc2hvY2sgcmVzcG9uc2UgYmV0d2VlbiB1bmNvbnRyb2wgYW5kIGNvbnRyb2wgcGFydGljaXBhbnRzCgpgYGB7cn0KbGlicmFyeShicm1zKSAjIGZvciB0aGUgYW5hbHlzaXMKbGlicmFyeShoYXZlbikgIyB0byBsb2FkIHRoZSBTUFNTIC5zYXYgZmlsZQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyBuZWVkZWQgZm9yIGRhdGEgbWFuaXB1bGF0aW9uLgpsaWJyYXJ5KFJDb2xvckJyZXdlcikgIyBuZWVkZWQgZm9yIHNvbWUgZXh0cmEgY29sb3VycyBpbiBvbmUgb2YgdGhlIGdyYXBocwpsaWJyYXJ5KGdnbWNtYykKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShnZ3JpZGdlcykKYGBgCiMjICoqTW9kZWwqKgokJFkgPSBOKFxtdSwgXHNpZ21hX3tcZXBzaWxvbn1eezJ9KSQkCiQkXG11ID0gXGJldGFfezB9ICsgXGJldGFfe3Njcn1TQ1IgKyBcYmV0YV97U219U20gKyBcYmV0YV97U2R9U2QgKyBcYmV0YV97VG19VG0gKyBcYmV0YV97VGR9VGQgKyBcZXBzaWxvbiQkCldoZXJlIFNDUiwgVG0sIFRkLCBTbSwgYW5kIFNkIGFyZSBjb3ZhcmlhdGVzLiAgCgpTQ1I6IFNraW4gY29uZHVjdGFuY2UgcmVzcG9uc2UgIApTbTogU3RhdGUgbWVhbiAgClNkOiBTdGF0ZSBkaWZmZXJlbmNlICh1bmNvbiAtIGNvbikgIApUbTogVHJhaXQgbWVhbiAgClRkOiBUcmlhdCBkaWZmZXJlbmNlICh1bmNvbiAtIGNvbikgIAoKCiMjICoqUHJpb3JzKioKCiQkTigwLDEwMCk6IFxiZXRhX3swfSQkCiQkTigwLDEwMCk6IFxiZXRhX3tTQ1J9JCQKJCROKDAsMTAwKTogXGJldGFfe1NtfSQkCiQkTigwLDEwMCk6IFxiZXRhX3tTZH0kJAokJE4oMCwxMDApOiBcYmV0YV97VG19JCQKJCROKDAsMTAwKTogXGJldGFfe1RkfSQkCiQkQ2F1Y2h5KDAsMTAwKTogXHNpZ21hX3tcZXBzaWxvbn0kJAoKYGBge3J9CnNldHdkKCJ+L1Blc3NvYV9MYWIvZUNPTi91bmNvbl92X2Nvbl9yQk5TVF9TQ1Jfd2l0aF9jb3ZhcmlhdGVzIikKCmRmIDwtIHJlYWQudGFibGUoJy4uL2RhdGEvdW5jb25fdl9jb25fckJOU1RfU0NSX3dpdGhfY292YXJpYXRlcy50eHQnLGhlYWRlcj1UUlVFKQpwcmlvcjEgPC0gYyhwcmlvcihub3JtYWwoMCwxMDApLGNsYXNzPUludGVyY2VwdCksCiAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLDEwMCksY2xhc3M9YiwgY29lZj0nU0NSJyksCiAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLDEwMCksY2xhc3M9YiwgY29lZj0iVFJBSVRtZWFuIiksCiAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLDEwMCksY2xhc3M9YiwgY29lZj0iVFJBSVRkaWZmIiksCiAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLDEwMCksY2xhc3M9YiwgY29lZj0iU1RBVEVtZWFuIiksCiAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLDEwMCksY2xhc3M9YiwgY29lZj0iU1RBVEVkaWZmIiksCiAgICAgICAgICAgIHByaW9yKGNhdWNoeSgwLDEwMCksY2xhc3M9c2lnbWEpCiAgICAgICAgICAgKQoKYm1vZDEgPC0gYnJtKHkgfiBTQ1IgKyBUUkFJVG1lYW4gKyBUUkFJVGRpZmYgKyBTVEFURW1lYW4gKyBTVEFURWRpZmYsIAogICAgICAgICAgICAgZGF0YSA9IGRmLCAKICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCksCiAgICAgICAgICAgICBwcmlvciA9IHByaW9yMSwgCiAgICAgICAgICAgICB3YXJtdXAgPSAyMDAwLCBpdGVyID0gNTAwMCwKICAgICAgICAgICAgIGNoYWlucyA9IDQsCiAgICAgICAgICAgICBjb3JlcyAgPSAyKQoKYGBgCiMjICoqTW9kZWwgU3VtbWFyeSoqCmBgYHtyfQpzdW1tYXJ5KGJtb2QxKQpgYGAKIyMgKipQb3N0ZXJpb3JzKioKYGBge3J9CmRhdGEgPC0gZml4ZWYoYm1vZDEsc3VtbWFyeSA9IEZBTFNFKQojd3JpdGUuY3N2KGRhdGEsZmlsZSA9ICdwb3N0ZXJpb3JzLmNzdicpCmBgYAoKCmBgYHtyfQojIElNUE9SVCBMSUJSQVJJRVM6CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncmlkZ2VzKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeSh2aXJpZGlzKQpgYGAKCgpgYGB7cn0Kcm9pcyA8LSBjb2xuYW1lcyhkYXRhKQojZGF0YSRYIDwtIE5VTEwKYGBgCgoKYGBge3J9Cm5vYmo9ZGltKGRhdGEpWzFdCgojIHJlbmFtZSBjb2x1bW5zIHdpdGggUk9JIGxpc3QKCgpkYXRhX3N0YXRzID0gZGF0YS5mcmFtZSgxOmxlbmd0aChyb2lzKSkKCiMgY3JlYXRlIFJPSSBjb2x1bW4gaW5zdGVhZCBvZiBudW1lcmljcyB0byBtYXRjaCB0aHJlYXQgdGFibGUgYWJvdmUKCmRhdGFfc3RhdHMkUk9JIDwtIHJvaXMKZGF0YV9zdGF0cyRtZWFuIDwtIGNvbE1lYW5zKGRhdGEpCmRhdGFfc3RhdHMkUCA8LSBjb2xTdW1zKGRhdGEgPiAwKS9ub2JqCmRhdGFfc3RhdHMkUG4gPC0gZGF0YV9zdGF0cyRQCgoKZm9yIChpIGluIDE6bGVuZ3RoKHJvaXMpKSB7CiAgaWYgKGRhdGFfc3RhdHMkUFtpXTwuNSl7ZGF0YV9zdGF0cyRQbltpXT0xLWRhdGFfc3RhdHMkUFtpXX0KfQoKCiMgdGhpcyB3aWxsIG9yZGVyIHRoZSBkaXN0cmlidXRpb25zIGNvcnJlY3RseQpkYXRhX3N0YXRzIDwtIGRhdGFfc3RhdHNbb3JkZXIoZGF0YV9zdGF0cyRtZWFuKSxdCgoKCmRhdGFfdHJhbnMgPC0gYXMuZGF0YS5mcmFtZSh0KGFzLm1hdHJpeChkYXRhKSkpCmRhdGFfdHJhbnMgPC0gdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oZGF0YV90cmFucywgIlJPSSIpCmRhdGFfdHJhbnMkWCA8LSAxOm5yb3coZGF0YV90cmFucykKCgoKCiMgbWVyZ2UgdmFsdWVzICYgc3RhdHMgaW50byBvbmUgdGFibGUgYnkgUk9JCgpkYXRhX21lcmdlIDwtIG1lcmdlKGRhdGFfc3RhdHMsIGRhdGFfdHJhbnMsIGJ5ID0gIlJPSSIpCmRhdGFfbWVyZ2UgPC0gZGF0YV9tZXJnZVtvcmRlcihkYXRhX21lcmdlJFgpLF0KCiMgVHJhbnNmb3JtIGRhdGEgaW50byBsb25nIGZvcm0KCgojIE1lbHQgZGF0YWZyYW1lIGJ5IFJPSQpsaWJyYXJ5KGRhdGEudGFibGUpCgpkYXRhX2xvbmcgPC0gbWVsdChkYXRhX3RyYW5zLCBpZD1jKCJST0kiLCJYIikpCiN0aHJlYXRfbG9uZyA8LSBtZWx0KHRocmVhdF90cmFucywgaWQ9YygiUk9JIiwiWC54IikpCgoKZGF0YV9sb25nIDwtIGRhdGFfbG9uZ1tvcmRlcihkYXRhX2xvbmckWCksXQoKCiMgVGhpcyBpcyBpbmNyZWRpYmx5IGNsdW5reSwgYnV0IGZvciB0aGUgc2FrZSBvZiB0aW1lIGFkZGluZyBzdGF0cyBieSBlbnN1cmluZyBvcmRlcnMgYXJlIGFsbCB0aGUgc2FtZSBhbmQgcmVwZWF0aW5nIGVhY2ggdmFsdWUgMjAwMCB0aW1lcy4uLiBUcmllZCBhIGZldyBkaWZmZXJlbnQgbWV0aG9kcyB3aXRoIG5vIHN1Y2Nlc3MgZm9yIHNvbWUgcmVhc29uLiAKCmRhdGFfbG9uZyRtZWFuIDwtIHJlcChkYXRhX21lcmdlJG1lYW4sIGVhY2ggPSBub2JqKQpkYXRhX2xvbmckUCA8LSByZXAoZGF0YV9tZXJnZSRQLCBlYWNoID1ub2JqKQpkYXRhX2xvbmckUG4gPC0gcmVwKGRhdGFfbWVyZ2UkUG4sIGVhY2ggPW5vYmopCgpgYGAKCmBgYHtyfQoKIyBzZXQgeW91ciBsYWJlbHMgaGVyZSBzbyB5b3UgZG9uJ3QgaGF2ZSB0byBjaGFuZ2Ugd2l0aGluIHRoZSBwbG90IGJlbG93OiAKZm9ybWF0KHJvdW5kKDEsIDIpLCBuc21hbGwgPSAyKQp5LmF4aXMubGFicyA8LSBmb3JtYXQocm91bmQoZGF0YV9zdGF0cyRQLDIpLCBuc21hbGwgPSAyKSAgICAgICAgICAgICAgICAgICAgICAgICMgeSBheGlzIGxhYmVscwpzZWMueS5heGlzLmxhYnMgPC0gZGF0YV9zdGF0cyRST0kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2Vjb25kIHkgYXhpcyBsYWJlbHMgKHByb2JhYmlsaXRpZXMpCgoKICMgWCBBWElTIExBQkVMUyBORUVEIFRPIENIQU5HRSBUTyBDT1JSRVNQT05EIFRPIERBVEEgU0VUISBVTkNPTU1FTlQgV0hJQ0hFVkVSIE1BVENIRVMKCiMgVW5jb21tZW50IGZvciBUSFJFQVQKeC5heGlzLmxhYnMgPC0gYyggImNvbnRyb2wgPiB1bmNvbnRyb2wiLCAiMCIsICJ1bmNvbnRyb2wgPiBjb250cm9sIikgICAgICAgICAgICAgICAgICMgeCBheGlzIGxhYmVscyAgVEhSRUFUCngubGFicy5wb3MgPC0gYygtMC4yLCAwLCAwLjIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB4IGF4aXMgcG9zaXRpb24gVEhSRUFUCgoKIyBVbmNvbW1lbnQgZm9yIFZBTEVOQ0UKI3guYXhpcy5sYWJzIDwtIGMoIk5ldXRyYWwgPiBQb3NpdGl2ZSIsICIwIiwgIlBvc2l0aXZlID4gTmV1dHJhbCIpICAgICAgICAgIyB4IGF4aXMgbGFiZWxzICBWQUxFTkNFCiN4LmxhYnMucG9zICA8LSBjKC0wLjEsMCwwLjIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeCBheGlzIHBvc2l0aW9uIFZBTEVOQ0UKCiMgVW5jb21tZW50IGZvciBJTlRFUkFDVElPTgojeC5heGlzLmxhYnMgPC0gTlVMTCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHggYXhpcyBsYWJlbHMgIElOVEVSQUNUSU9OLCBub3Qgc3VyZSB3aGF0IHRvIHB1dC4KI3gubGFicy5wb3MgPC0gTlVMTCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhIGF4aXMgcG9zaXRpb24gSU5URVJBQ1RJT04sIGNoYW5nZSB3aGVuIGxhYmVscyBkZWNpZGVkCgojZ3JhcGgudGl0bGUgPC0gZGF0YS5uYW1lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGdyYXBoIHRpdGxlIApsZWdlbmQudGl0bGUgPC0gIlByb2JhYmlsaXR5IiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbGVnZW5kIHRpdGxlCnkuYXhpcy50aXRsZSA8LSBOVUxMICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmb3Igbm93IC4uLgp4LmF4aXMudGl0bGUgPC0gTlVMTCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgZm9yIG5vdy4uLgoKIyBHUkFQSCBEQVRBIApkYXRhc2V0IDwtIGRhdGFfbG9uZwp4LnZhbHVlcyA8LSBkYXRhX2xvbmckdmFsdWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB4IHZhbHVlcwp5LnZhbHVlcyA8LSBkYXRhX2xvbmckUk9JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5IHZhbHVlcwp5LnZhbHVlcy5STyA8LSBkYXRhX2xvbmckdmFsdWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB2YWx1ZXMgdG8gcmVvcmRlciBZIGJ5CmRpc3RyaWIuZmlsbCA8LSBkYXRhX2xvbmckUG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZpbGwgZ3JhcGggd2l0aCBwcm9iYWJpbGl0aWVzCmdyb3VwIDwtIGRhdGFfbG9uZyRST0kKCiMgT3RoZXIgYXNwZWN0cwpncmFkaWVudC5jb2xvcnMgPC0gYygieWVsbG93IiwiI0M5MTgyQiIsIiM0MTI0NUMiKSAgICAgICAgIyBjaGFuZ2UgZ3JhZGllbnQgY29sb3JzIGhlcmUgKGN1cnJlbnRseSwgeWVsbG93IC0gcHVycGxlKQpsYWJlbC5zaXplIDwtIDEyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFkanVzdCBST0kgYW5kIHByb2JhYmlsaXR5IHktYXhpcyBmb250IHNpemUKdGl0bGUuc2l6ZSA8LSAyOCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWRqdXN0IGdyYXBoIHRpdGxlIHNpemUgCnguYXhpcy5zaXplIDwtIDEyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWRqdXN0IHgtYXhpcyBsYWJlbCBzaXplcwoKIyBoZXJlIGlzIHdoZXJlIHlvdSBjYW4gY2hhbmdlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBncmFwaCBhbmQgYWRkIG90aGVyIGNoYXJhY3RlcmlzdGljcyB1c2luZyBnZ3Bsb3QgYW5kIGdncmlkZ2VzCgoKZ2dwbG90KGRhdGFzZXQsIGFlcyh4ID0geC52YWx1ZXMsIHkgPSBhcy5udW1lcmljKHJlb3JkZXIoeS52YWx1ZXMsIHkudmFsdWVzLlJPKSksIAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSBkaXN0cmliLmZpbGwsIGdyb3VwID0gZ3JvdXApKSArICAgICAgICAgICAgICAgICAgICAgICAgIyBzY2FsZSA9IHNwYWNpbmcsIGFscGhhID0gdHJhbnNwYXJlbmN5CiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjUsIDAuNSkpICsKICBzdGF0X2RlbnNpdHlfcmlkZ2VzKHF1YW50aWxlX2xpbmVzID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICBxdWFudGlsZXMgPSAyLCAKICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gLjk1LCAKICAgICAgICAgICAgICAgICAgICAgIHNjYWxlID0gMi41NSwKICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAuMzUKICAgICAgICAgICAgICAgICAgICAgKSArICAgICAgICAgICAgIyBkaXZpZGUgaW50byB0d28gcXVhbnRpbGVzIChzaG93IG1lYW4pCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGU9InNvbGlkIixjb2xvciA9ICJibGFjayIsYWxwaGEgPSAuOTUsIHNpemUgPSAuNDUpICsgICAgI2NyZWF0ZSBsaW5lIGF0IFggPSAwCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gdmlyaWRpc19wYWwoZGlyZWN0aW9uID0gMSwgb3B0aW9uID0gImluZmVybm8iKSgyMCksICAgICAgICAgICAgICAgICAgICAgICAgICMgc2V0IGdyYWRpZW50CiAgICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYyguODUsMSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHdoaWNoIHByb2JhYmlsaXRlcyBtYXR0ZXI/CiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAiIzkwOTQ5NyIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGlmIG5vdCBpbiBsaW1pdHMsIGdyYXkgb3V0CiAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGxlZ2VuZC50aXRsZSkgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG5hbWUgbGVnZW5kCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IDE6bGVuZ3RoKHJvaXMpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEEgVkVSWSBIQUNLLVkgV0FZIFRPIEhBVkUgVFdPIFkgQVhFUyBXIERJU0NSRVRFIERBVEEKICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYygwLDApLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSB5LmF4aXMubGFicywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBUcmljayBnZ3Bsb3QgaW50byB0aGlua2luZyBkYXRhIGlzIGNvbnRpbnVvdXMuLi4KICAgICAgICAgICAgICAgICAgICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+LiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgU2Vjb25kIGF4aXMgdG8gc2hvdyBwcm9iYWJpbGl0aWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gMTpsZW5ndGgocm9pcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gc2VjLnkuYXhpcy5sYWJzKSkgKwogICN0aGVtZV9yaWRnZXMoZm9udF9zaXplID0gbGFiZWwuc2l6ZSwgZ3JpZCA9IFRSVUUsIGNlbnRlcl9heGlzX2xhYmVscyA9IFRSVUUpICsgICMgdGhlbWUgaW5mbwogICNnZ3RpdGxlKGdyYXBoLnRpdGxlKSsgCiAgI3RoZW1lX2J3KCkgKyMgZ3JhcGggdGl0bGUKICN0aGVtZV9yaWRnZXMoZ3JpZCA9IEZBTFNFKSArIAogIHRoZW1lKCAgIAogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICNwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleSIpLCAKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSB0aXRsZS5zaXplKSwgICAgICAgICAgICAjIHBsb3QgdGl0bGUgc2l6ZSBhbmQgcG9zaXRpb24KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9bGFiZWwuc2l6ZSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeS1heGlzIHRleHQgc2l6ZQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIpLAogICAgYXhpcy50ZXh0LnkucmlnaHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGxhYmVsLnNpemUpLCAgICAgICAgICAgICAgICAgICMgeS1heGlzIGluZm8gZm9yIHJpZ2h0IGF4aXMKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSB4LmF4aXMuc2l6ZSksCiAgICAjcGxvdC5tYXJnaW4gPSB1bml0KGMoMCwwLDAsMCksICJjbSIpLAogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnRpdGxlLmFsaWduID0gNSkrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKGxhYmVsLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlLnBvc2l0b24gPSAiYm90dG9tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUudmp1c3QgPSAwLjQpKSArICAgICAgICAgIAogIGxhYnMoCiAgICB4ID0gTlVMTCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEFkZCBvciBub3QgYWRkIFggYW5kIFkgbGFiZWxzCiAgICB5ID0gTlVMTCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSB4LmxhYnMucG9zLCBsYWJlbHMgPSBjKHguYXhpcy5sYWJzKSkKCiNnZ3NhdmUoZmlsZSA9IHBhc3RlMChzdHJzcGxpdCh0eXBlLCcuUkRhdGEnKSwiLmpwZyIsIHNlcD0iIiksIHdpZHRoPTQuNSwgaGVpZ2h0PTMsIHVuaXRzID0gImluIiwgZHBpID0gOTAwKQoKIyBwcmV2aWV3IHdpbGwgbG9vayBzbW9vc2hlZCwgYmUgc3VyZSB0byBsb29rIGF0IHRoZSBzYXZlZCAuanBnIGJlZm9yZSBtYWtpbmcgYW55IGNoYW5nZXMgdG8gdGV4dCBzaXplLCBldGMhCiNncmFwaApgYGAK