Data Preparation

In this pre-registered study, we collected data from 176 participants. Two of 176 IP addresses were identical, which prompted their removal from the dataset. Additionally, six participants failed the attention checks, leading to an analyzable sample of 168 participants.

Loading Packages

Before running this chunk, please load “Study 1b.csv” into the R environment.

# packages should be loaded in the following order to avoid function conflicts
options(scipen = 99) # turns off scientific notation
library(psych) # for describing data
library(effsize) # for mean difference effect sizes
library(sjstats) # for eta-squared effect sizes
library(correlation) # for cleaner correlation test output
library(rmcorr) # for repeated-measures correlation tests
library(cocor) # for comparing dependent correlation coefficients
library(tidyverse) # for data manipulation and plotting

Attention Check

Participants were instructed to select zero (i.e., the middle option in the 9-point scale) as their response for three measures that followed a modified scenario. If a participant failed to select “0” as their response for any of the three measures, they would be excluded from the analyses.

# Experimental task attention check variable
Study_1b$AttChecks <- rowSums(Study_1b[, c("AttnCheck1_S2", "AttnCheck2_S2", "AttnCheck3_S2")], na.rm = T)

# The exclusion of any sum (within the variable "AttChecks") that did not result in a zero
Study_1b <- Study_1b %>% 
  filter(Study_1b$AttChecks == 0)

Variable Creation

The original design provided by Berman & Small required virtuosity, honorability, and respectability measures to be averaged across for all participants. Moreover, since the study had a between-subjects design, it included an overall “Virtuosity Average”. For this replication, the within-subjects design does not allow to have an overall average, so there will be a moral and a non-moral average for each participant. Additionally, there will be a virtuosity average for each vignette.


# Create a variable for virtuosity average in the moral condition
Study_1b$MoralAverage <- rowMeans(Study_1b[, c("AdulteryVirtuous1_S2", "AdulteryHonorable2_S2", "AdulteryRespectable3_S2", "OfficeVirtuous1_S2", "OfficeHonorable2_S2", "OfficeRespectable3_S2", "KidneyVirtuous1_S2", "KidneyHonorable2_S2", "KidneyRespectable3_S2", "AdulteryVirtuous2_S2", "AdulteryHonrable3_S2", "AdulteryRespectable1_S2", "OfficeVirtuous2_S2", "OfficeHonorable3_S2", "OfficeRespectable1_S2", "KidneyVirtuous2_S2", "KidneyHonorable3_S2", "KidneyRespectable1_S2", "AdulteryVirtuous3_S2", "AdulteryHonrable1_S2", "AdulteryRespectable2_S2", "OfficeVirtuous3_S2", "OfficeHonorable1_S2", "OfficeRespectable2_S2", "KidneyVirtuous3_S2", "KidneyHonorable1_S2", "KidneyRespectable2_S2")], na.rm = T)

# Create a variable for virtuosity average in the non-moral condition
Study_1b$NonmoralAverage <- rowMeans(Study_1b[, c("DessertVirtuous1_S2", "DessertHonorable2_S2", "DessertRespectable3_S2", "GymVirtuous1_S2", "GymHonorable2_S2", "GymRespectable3_S2", "SchoolworkVirtuous1_S2", "SchoolworkHonorable2_S2", "SchoolworkRespectable3_S2", "DessertVirtuous2_S2", "DessertHonorable3_S2", "DessertRespectable1_S2", "GymVirtuous2_S2", "GymHonorable3_S2", "GymRespectable1_S2", "SchoolworkVirtuous2_S2", "SchoolworkHonorable3_S2", "SchoolworkRespectable1_S2", "DessertVirtuous3_S2", "DessertHonorable1_S2", "DessertRespectable2_S2", "GymVirtuous3_S2", "GymHonorable1_S2", "GymRespectable2_S2", "SchoolworkVirtuous3_S2", "SchoolworkHonorable1_S2", "SchoolworkRespectable2_S2")], na.rm = T)

# Create a variable for virtuosity average in the Office Supplies scenario
Study_1b$OfficeAverage <- rowMeans(Study_1b[, c("OfficeVirtuous1_S2", "OfficeHonorable2_S2", "OfficeRespectable3_S2", "OfficeVirtuous2_S2", "OfficeHonorable3_S2", "OfficeRespectable1_S2", "OfficeVirtuous3_S2", "OfficeHonorable1_S2", "OfficeRespectable2_S2" )], na.rm = T)

# Create a variable for virtuosity average in the Adultery scenario
Study_1b$AdulteryAverage <- rowMeans(Study_1b[, c("AdulteryVirtuous1_S2", "AdulteryHonorable2_S2", "AdulteryRespectable3_S2", "AdulteryVirtuous2_S2", "AdulteryHonrable3_S2", "AdulteryRespectable1_S2", "AdulteryVirtuous3_S2", "AdulteryHonrable1_S2", "AdulteryRespectable2_S2" )], na.rm = T)

# Create a variable for virtuosity average in the Kidney scenario
Study_1b$KidneyAverage <- rowMeans(Study_1b[, c("KidneyVirtuous1_S2", "KidneyHonorable2_S2", "KidneyRespectable3_S2", "KidneyVirtuous2_S2", "KidneyHonorable3_S2", "KidneyRespectable1_S2", "KidneyVirtuous3_S2", "KidneyHonorable1_S2", "KidneyRespectable2_S2")], na.rm = T)

# Create a variable for virtuosity average in the Dessert scenario
Study_1b$DessertAverage <- rowMeans(Study_1b[, c("DessertVirtuous1_S2", "DessertHonorable2_S2", "DessertRespectable3_S2", "DessertVirtuous2_S2", "DessertHonorable3_S2", "DessertRespectable1_S2", "DessertVirtuous3_S2", "DessertHonorable1_S2", "DessertRespectable2_S2")], na.rm = T)

# Create a variable for virtuosity average in the Gym scenario
Study_1b$GymAverage <- rowMeans(Study_1b[, c("GymVirtuous1_S2", "GymHonorable2_S2", "GymRespectable3_S2", "GymVirtuous2_S2", "GymHonorable3_S2", "GymRespectable1_S2", "GymVirtuous3_S2", "GymHonorable1_S2", "GymRespectable2_S2")], na.rm = T)

# Create a variable for virtuosity average in the Schoolwork scenario
Study_1b$SchoolworkAverage <- rowMeans(Study_1b[, c("SchoolworkVirtuous1_S2", "SchoolworkHonorable2_S2", "SchoolworkRespectable3_S2", "SchoolworkVirtuous2_S2", "SchoolworkHonorable3_S2", "SchoolworkRespectable1_S2","SchoolworkVirtuous3_S2", "SchoolworkHonorable1_S2", "SchoolworkRespectable2_S2")], na.rm = T)


B&S (2018)’s Group-Lvl Analyses

Simple Effects

For all t-tests, we conduct both one-tailed and two-tailed tests. Our pre-registration specified directional hypotheses which therefore ought to be analyzed with one-tailed tests. However, in order for readers to know any estimate’s uncertainty in both directions, we also conduct two-tailed tests to get relevant CIs.

Non-Moral Vignettes

Overall

# Non-Moral t-test using person-level averages across Non-Moral vignettes
Study_1b_nonmoral_t <- t.test(Study_1b$NonmoralAverage, mu = 0, alternative = "less") 
## 'greater' is for one-tailed p-value because of the tempted > non-tempted hypothesis (negative numbers mean tempted > non-tempted)
print(Study_1b_nonmoral_t)

    One Sample t-test

data:  Study_1b$NonmoralAverage
t = -2.0956, df = 167, p-value = 0.01881
alternative hypothesis: true mean is less than 0
95 percent confidence interval:
       -Inf -0.0303816
sample estimates:
 mean of x 
-0.1441799 
Study_1b_nonmoral_t_2side <- t.test(Study_1b$NonmoralAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_nonmoral_t_2side)

    One Sample t-test

data:  Study_1b$NonmoralAverage
t = -2.0956, df = 167, p-value = 0.03762
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 -0.28001104 -0.00834875
sample estimates:
 mean of x 
-0.1441799 
# returns cohen's d
effsize::cohen.d(Study_1b$NonmoralAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: -0.1616804 (negligible)
Reference mu: 0
95 percent confidence interval:
     lower      upper 
-0.4668144  0.1434535 

Dessert Vignette

# Dessert vignette t-test
Study_1b_dessert_t <- t.test(Study_1b$DessertAverage, mu = 0, alternative = "less") 
## 'greater' is for one-tailed p-value because of the tempted > non-tempted hypothesis (negative numbers mean tempted > non-tempted)
print(Study_1b_dessert_t)

    One Sample t-test

data:  Study_1b$DessertAverage
t = -2.6352, df = 167, p-value = 0.004601
alternative hypothesis: true mean is less than 0
95 percent confidence interval:
       -Inf -0.0679641
sample estimates:
 mean of x 
-0.1825397 
Study_1b_dessert_t_2side <- t.test(Study_1b$DessertAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_dessert_t_2side)

    One Sample t-test

data:  Study_1b$DessertAverage
t = -2.6352, df = 167, p-value = 0.009201
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 -0.31929861 -0.04578076
sample estimates:
 mean of x 
-0.1825397 
# returns cohen's d
effsize::cohen.d(Study_1b$DessertAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: -0.2033077 (small)
Reference mu: 0
95 percent confidence interval:
     lower      upper 
-0.5087303  0.1021149 

Gym Vignette

# Gym vignette t-test
Study_1b_gym_t <- t.test(Study_1b$GymAverage, mu = 0, alternative = "less") 
## 'greater' is for one-tailed p-value because of the tempted > non-tempted hypothesis (negative numbers mean tempted > non-tempted)
print(Study_1b_gym_t)

    One Sample t-test

data:  Study_1b$GymAverage
t = -1.9341, df = 167, p-value = 0.0274
alternative hypothesis: true mean is less than 0
95 percent confidence interval:
        -Inf -0.02441968
sample estimates:
 mean of x 
-0.1686508 
Study_1b_gym_t_2side <- t.test(Study_1b$GymAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_gym_t_2side)

    One Sample t-test

data:  Study_1b$GymAverage
t = -1.9341, df = 167, p-value = 0.05479
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 -0.340806954  0.003505366
sample estimates:
 mean of x 
-0.1686508 
# returns cohen's d
effsize::cohen.d(Study_1b$GymAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: -0.1492169 (negligible)
Reference mu: 0
95 percent confidence interval:
     lower      upper 
-0.4542771  0.1558434 

Schoolwork Vignette

# Schoolwork vignette t-test
Study_1b_schoolwork_t <- t.test(Study_1b$SchoolworkAverage, mu = 0, alternative = "less") 
## 'greater' is for one-tailed p-value because of the tempted > non-tempted hypothesis (negative numbers mean tempted > non-tempted)
print(Study_1b_schoolwork_t)

    One Sample t-test

data:  Study_1b$SchoolworkAverage
t = -0.94962, df = 167, p-value = 0.1718
alternative hypothesis: true mean is less than 0
95 percent confidence interval:
       -Inf 0.06034302
sample estimates:
  mean of x 
-0.08134921 
Study_1b_schoolwork_t_2side <- t.test(Study_1b$SchoolworkAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_schoolwork_t_2side)

    One Sample t-test

data:  Study_1b$SchoolworkAverage
t = -0.94962, df = 167, p-value = 0.3437
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 -0.25047492  0.08777651
sample estimates:
  mean of x 
-0.08134921 
# returns cohen's d
effsize::cohen.d(Study_1b$SchoolworkAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: -0.07326487 (negligible)
Reference mu: 0
95 percent confidence interval:
     lower      upper 
-0.3780037  0.2314739 

Moral Vignettes

Overall

# Moral t-test using person-level averages across Moral vignettes
Study_1b_moral_t <- t.test(Study_1b$MoralAverage, mu = 0, alternative = "greater") 
## 'less' is for one-tailed p-value because of the non-tempted > tempted hypothesis (positive numbers mean non-tempted > tempted)
print(Study_1b_moral_t)

    One Sample t-test

data:  Study_1b$MoralAverage
t = 10.334, df = 167, p-value < 0.00000000000000022
alternative hypothesis: true mean is greater than 0
95 percent confidence interval:
 0.8049388       Inf
sample estimates:
mean of x 
0.9583333 
Study_1b_moral_t_2side <- t.test(Study_1b$MoralAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_moral_t_2side)

    One Sample t-test

data:  Study_1b$MoralAverage
t = 10.334, df = 167, p-value < 0.00000000000000022
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 0.7752396 1.1414270
sample estimates:
mean of x 
0.9583333 
# returns cohen's d
effsize::cohen.d(Study_1b$MoralAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: 0.7972515 (medium)
Reference mu: 0
95 percent confidence interval:
    lower     upper 
0.4807443 1.1137587 

Office Vignette

# Office vignette t-test
Study_1b_office_t <- t.test(Study_1b$OfficeAverage, mu = 0, alternative = "greater") 
## 'less' is for one-tailed p-value because of the non-tempted > tempted hypothesis (positive numbers mean non-tempted > tempted)
print(Study_1b_office_t)

    One Sample t-test

data:  Study_1b$OfficeAverage
t = 7.0028, df = 167, p-value = 0.00000000002924
alternative hypothesis: true mean is greater than 0
95 percent confidence interval:
 0.592554      Inf
sample estimates:
mean of x 
0.7757937 
Study_1b_office_t_2side <- t.test(Study_1b$OfficeAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_office_t_2side)

    One Sample t-test

data:  Study_1b$OfficeAverage
t = 7.0028, df = 167, p-value = 0.00000000005848
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 0.5570764 0.9945109
sample estimates:
mean of x 
0.7757937 
# returns cohen's d
effsize::cohen.d(Study_1b$OfficeAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: 0.5402756 (medium)
Reference mu: 0
95 percent confidence interval:
    lower     upper 
0.2301311 0.8504201 

Adultery Vignette

# Adultery vignette t-test
Study_1b_adultery_t <- t.test(Study_1b$AdulteryAverage, mu = 0, alternative = "greater") 
## 'less' is for one-tailed p-value because of the non-tempted > tempted hypothesis (positive numbers mean non-tempted > tempted)
print(Study_1b_adultery_t)

    One Sample t-test

data:  Study_1b$AdulteryAverage
t = 10.843, df = 167, p-value < 0.00000000000000022
alternative hypothesis: true mean is greater than 0
95 percent confidence interval:
 1.229141      Inf
sample estimates:
mean of x 
 1.450397 
Study_1b_adultery_t_2side <- t.test(Study_1b$AdulteryAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_adultery_t_2side)

    One Sample t-test

data:  Study_1b$AdulteryAverage
t = 10.843, df = 167, p-value < 0.00000000000000022
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 1.186302 1.714491
sample estimates:
mean of x 
 1.450397 
# returns cohen's d
effsize::cohen.d(Study_1b$AdulteryAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: 0.8365266 (large)
Reference mu: 0
95 percent confidence interval:
    lower     upper 
0.5188457 1.1542076 

Kidney Vignette

# Kidney vignette t-test
Study_1b_kidney_t <- t.test(Study_1b$KidneyAverage, mu = 0, alternative = "greater") 
## 'less' is for one-tailed p-value because of the non-tempted > tempted hypothesis (positive numbers mean non-tempted > tempted)
print(Study_1b_kidney_t)

    One Sample t-test

data:  Study_1b$KidneyAverage
t = 6.5382, df = 167, p-value = 0.000000000363
alternative hypothesis: true mean is greater than 0
95 percent confidence interval:
 0.4846732       Inf
sample estimates:
mean of x 
0.6488095 
Study_1b_kidney_t_2side <- t.test(Study_1b$KidneyAverage, mu = 0, alternative = "two.sided") 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_kidney_t_2side)

    One Sample t-test

data:  Study_1b$KidneyAverage
t = 6.5382, df = 167, p-value = 0.000000000726
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 0.4528942 0.8447249
sample estimates:
mean of x 
0.6488095 
# returns cohen's d
effsize::cohen.d(Study_1b$KidneyAverage,
                 f = NA,
                 mu = 0,
                 data = data)

Cohen's d (single sample)

d estimate: 0.50443 (medium)
Reference mu: 0
95 percent confidence interval:
    lower     upper 
0.1949866 0.8138734 

Interaction

Repeated-Measures ANOVA

The purpose of this test is to determine whether there is a difference in mean virtuosity depending on condition (i.e., non-moral vs moral).

# Prepare data by using pivot_longer on a new dataset
Study_1b_anova <- Study_1b %>%
  dplyr::select(c(ResponseId, MoralAverage, NonmoralAverage))%>% 
  group_by(ResponseId) %>%
  pivot_longer(cols = (c(MoralAverage,NonmoralAverage)),
               names_to = "Condition",
               values_to = "VirtuosityAverage")

# Repeated-Meausures ANOVA
Study_1b_interaction_aov <- aov(VirtuosityAverage~Condition + Error(as.factor(ResponseId)), data = Study_1b_anova)
summary(Study_1b_interaction_aov)

Error: as.factor(ResponseId)
           Df Sum Sq Mean Sq F value Pr(>F)
Residuals 167  228.8    1.37               

Error: Within
           Df Sum Sq Mean Sq F value              Pr(>F)    
Condition   1  102.1  102.10   117.3 <0.0000000000000002 ***
Residuals 167  145.3    0.87                                
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Paired-Samples t-Test

Replicates results of the repeated-measures ANOVA (Berman & Small used ANOVAs rather than paired-samples t-tests for the interaction test). These tests are statistically identical, but we conduct both in case researchers have preferences for one over the other.

Study_1b_interaction_t <- t.test(VirtuosityAverage ~ Condition, data = Study_1b_anova, alternative = "greater", paired = TRUE)
## 'less' is for one-tailed p-value because of the non-moral > moral hypothesis (positive numbers mean non-moral > moral)
Study_1b_interaction_t

    Paired t-test

data:  VirtuosityAverage by Condition
t = 10.833, df = 167, p-value < 0.00000000000000022
alternative hypothesis: true mean difference is greater than 0
95 percent confidence interval:
 0.9341718       Inf
sample estimates:
mean difference 
       1.102513 
Study_1b_interaction_t_2side <- t.test(VirtuosityAverage ~ Condition, data = Study_1b_anova, alternative = "two.sided", paired = TRUE) 
## 'two.sided' is to get uncertainty estimates in both directions
print(Study_1b_interaction_t_2side)

    Paired t-test

data:  VirtuosityAverage by Condition
t = 10.833, df = 167, p-value < 0.00000000000000022
alternative hypothesis: true mean difference is not equal to 0
95 percent confidence interval:
 0.9015787 1.3034477
sample estimates:
mean difference 
       1.102513 
# returns dz effect size and 95% CIs
effsize::cohen.d(VirtuosityAverage ~ Condition | Subject(ResponseId),
                 data = Study_1b_anova %>% droplevels(), 
                 paired = T,
                 within = F)

Cohen's d

d estimate: 0.8357596 (large)
95 percent confidence interval:
    lower     upper 
0.6594744 1.0120448 
# returns d-av effect size and 95% CIs
effsize::cohen.d(VirtuosityAverage ~ Condition | Subject(ResponseId),
                 data = Study_1b_anova %>% droplevels(), 
                 paired = T,
                 within = T)

Cohen's d

d estimate: 1.035001 (large)
95 percent confidence interval:
    lower     upper 
0.8021003 1.2679011 

Person-Lvl Analyses

It is first necessary to rearrange data in a way that facilitates conducting various person-level analyses.

# Create person-level variables
Study_1b_plvl <- Study_1b %>% 
  mutate(fits_hypothesis_n = if_else(NonmoralAverage < 0, 1, 0)) %>% 
  mutate(fits_hypothesis_dessert = if_else(DessertAverage < 0, 1, 0)) %>% 
  mutate(fits_hypothesis_gym = if_else(GymAverage < 0, 1, 0)) %>% 
  mutate(fits_hypothesis_schoolwork = if_else(SchoolworkAverage < 0, 1, 0)) %>% 
  mutate(fits_hypothesis_m = if_else(MoralAverage > 0, 1, 0)) %>%
  mutate(fits_hypothesis_office = if_else(OfficeAverage > 0, 1, 0)) %>% 
  mutate(fits_hypothesis_adultery = if_else(AdulteryAverage > 0, 1, 0)) %>% 
  mutate(fits_hypothesis_kidney = if_else(KidneyAverage > 0, 1, 0))

# Create variable that indicates whether participants fit the full complex hypothesis or not 
Study_1b_plvl$number_of_hyp_fit <- rowSums(Study_1b_plvl[, c("fits_hypothesis_m", "fits_hypothesis_n")], na.rm = T)
Study_1b_plvl <- Study_1b_plvl %>% 
   mutate(fits_complex = if_else(number_of_hyp_fit == 2, "Yes", "No"))

Descriptive Pervasiveness

Non-Moral Vignettes

# How many participants fit hypothesis for Non-Moral vignettes
table(Study_1b_plvl$fits_hypothesis_n) # (0 = "no"; 1 = "yes")

  0   1 
108  60 

Moral Vignettes

# How many participants fit hypothesis for Moral vignettes
table(Study_1b_plvl$fits_hypothesis_m) # (0 = "no"; 1 = "yes")

  0   1 
 43 125 

Interaction

# How many participants fit complex interaction hypothesis (i.e., in Non-Moral vignettes: tempted > non-tempted; in Moral vignettes: non-tempted > tempted)
table(Study_1b_plvl$fits_complex) # (0 = "no"; 1 = "yes")

 No Yes 
124  44 

Randomization Test

This test is only possible for the complex interaction hypothesis, as randomly shuffling within-condition data would yield the same result across shufflings.

library(mosaic) # for randomly shuffling data
Registered S3 method overwritten by 'mosaic':
  method                           from   
  fortify.SpatialPolygonsDataFrame ggplot2

The 'mosaic' package masks several functions from core packages in order to add 
additional features.  The original behavior of these functions should not be affected by this.

Attaching package: ‘mosaic’

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

    mean

The following objects are masked from ‘package:dplyr’:

    count, do, tally

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

    cross

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

    stat

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

    cor_test

The following objects are masked from ‘package:sjstats’:

    prop, props

The following objects are masked from ‘package:psych’:

    logit, rescale

The following objects are masked from ‘package:stats’:

    binom.test, cor, cor.test, cov, fivenum, IQR, median, prop.test, quantile, sd, t.test, var

The following objects are masked from ‘package:base’:

    max, mean, min, prod, range, sample, sum
Study_1b_random <- Study_1b_plvl %>% 
  dplyr::select(c(ResponseId, MoralAverage, NonmoralAverage))

Study_1b_random <- Study_1b_random %>% 
  mutate("Interaction" = case_when(
    (MoralAverage == 0 & NonmoralAverage == 0) ~ "Zero, Zero, Zero",
    (MoralAverage == 0 & NonmoralAverage < 0) ~ "Zero, Neg, Pos",
    (MoralAverage == 0 & NonmoralAverage > 0) ~ "Zero, Pos, Neg",
    (MoralAverage < 0 & NonmoralAverage == 0) ~ "Neg, Zero, Neg",
    (MoralAverage < 0 & NonmoralAverage < 0 & MoralAverage == NonmoralAverage) ~ "Neg, Neg, Zero",
    (MoralAverage < 0 & NonmoralAverage > 0) ~ "Neg, Pos, Neg",
    (MoralAverage < 0 & NonmoralAverage < 0 & MoralAverage > NonmoralAverage) ~ "Neg, Neg, Pos",
    (MoralAverage < 0 & NonmoralAverage < 0 & MoralAverage < NonmoralAverage) ~ "Neg, Neg, Neg",
    (MoralAverage > 0 & NonmoralAverage == 0) ~ "Pos, Zero, Pos",
    (MoralAverage > 0 & NonmoralAverage < 0) ~ "Pos, Neg, Pos", # this is the predicted pattern
    (MoralAverage > 0 & NonmoralAverage > 0 & MoralAverage == NonmoralAverage) ~ "Pos, Pos, Zero",
    (MoralAverage > 0 & NonmoralAverage > 0 & MoralAverage < NonmoralAverage) ~ "Pos, Pos, Neg",
    (MoralAverage > 0 & NonmoralAverage > 0 & MoralAverage > NonmoralAverage) ~ "Pos, Pos, Pos"))

prop_Study_1b <- prop( ~ Interaction == "Pos, Neg, Pos", data = Study_1b_random) # create descriptive proportion of claimed pattern from Berman & Small
prop_Study_1b_dp <- unname(prop_Study_1b[1]) # get descriptive proportion proportion for interaction

nsim <- 1000 # number of random datasets to generate
nullprop_Study_1b <- rep(NA, nsim) # creating empty bin

for (i in 1:nsim) { # for loop to do random shuffling across nsim datasets and calculate proportions in those randomly shuffled datasets
  #permutation, size equal to number of observations for each condition
  Study_1b_random$NonmoralAverageR <- shuffle(Study_1b_random$NonmoralAverage) # shuffling 'Non-Moral' values  
  Study_1b_random$MoralAverageR <- shuffle(Study_1b_random$MoralAverage) # shuffling 'Moral' values
  
  ## Creating variable that distinguishes Ps who showed predicted (claimed) pattern from Ps who did not
  Study_1b_R <- Study_1b_random %>%
  mutate("InteractionR" = case_when(
    (MoralAverageR == 0 & NonmoralAverageR == 0) ~ "Zero, Zero, Zero",
    (MoralAverageR == 0 & NonmoralAverageR < 0) ~ "Zero, Neg, Pos",
    (MoralAverageR == 0 & NonmoralAverageR > 0) ~ "Zero, Pos, Neg",
    (MoralAverageR < 0 & NonmoralAverageR == 0) ~ "Neg, Zero, Neg",
    (MoralAverageR < 0 & NonmoralAverageR < 0 & MoralAverageR == NonmoralAverageR) ~ "Neg, Neg, Zero",
    (MoralAverageR < 0 & NonmoralAverageR > 0) ~ "Neg, Pos, Neg",
    (MoralAverageR < 0 & NonmoralAverageR < 0 & MoralAverageR > NonmoralAverageR) ~ "Neg, Neg, Pos",
    (MoralAverageR < 0 & NonmoralAverageR < 0 & MoralAverageR < NonmoralAverageR) ~ "Neg, Neg, Neg",
    (MoralAverageR > 0 & NonmoralAverageR == 0) ~ "Pos, Zero, Pos",
    (MoralAverageR > 0 & NonmoralAverageR < 0) ~ "Pos, Neg, Pos", # this is the predicted pattern
    (MoralAverageR > 0 & NonmoralAverageR > 0 & MoralAverageR == NonmoralAverageR) ~ "Pos, Pos, Zero",
    (MoralAverageR > 0 & NonmoralAverageR > 0 & MoralAverageR < NonmoralAverageR) ~ "Pos, Pos, Neg",
    (MoralAverageR > 0 & NonmoralAverageR > 0 & MoralAverageR > NonmoralAverageR) ~ "Pos, Pos, Pos"))

  
  nullprop_TF_Study_1b <-prop( ~ InteractionR == "Pos, Neg, Pos", data = Study_1b_R) # create proportion value of claimed direction 
  nullprop_Study_1b[i]<- unname(nullprop_TF_Study_1b[1]) # get claimed pattern proportion for randomly shuffled data and repeat for each nsim dataset
}

gf_histogram( ~ nullprop_Study_1b, fill = ~ (nullprop_Study_1b >= prop_Study_1b_dp)) # create histogram of how many randomly shuffled datasets lead to a prop value similar to or greater than empirical prop


#c(chance)-value for empirical proportion (similar to Grice's c-values computed in his OOM software)
prop( ~ nullprop_Study_1b >= prop_Study_1b_dp) # suggests that empirical interaction proportion is very likely to have occurred by chance
prop_TRUE 
    0.672 

Frequentist Prevalence

# CREATE NECESSARY FREQUENTIST FUNCTION (code adapted from Donhauser et al.'s (2018) MATLAB code)

prevalence_test <- function(observed, alpha_ind=0.05, beta_ind=1, alpha_group=0.05, gamma_0=0.5) {
  
  # Inputs:
  # observed    = vector of p-values OR vector with two values, e.g., 'c(positive cases, total cases)'
  # alpha_ind   = alpha threshold for person-level tests, if 'observed' = vector of p-values (typically set to .05)
  # beta_ind    = sensitivity of person-level tests (probably set to 1.00)
  # alpha_group = see "outputs"
  # gamma_0     = null gamma value for empirical prevalence to be tested against (defaults to majority null)
  
  # Outputs:
  # p_null      = p-value for majority null or whatever null you specify in the gamma_0 argument (e.g., to specify a global null set "gamma_0 = 0") 
  # gamma_0     = highest gamma_0 value that can be rejected at threshold of 'alpha_group' given positive cases. Note this output is not the same as the input argument
  if(sum(observed > 1) == 0) {
    pvals <- observed
  } else {
    pvals <- c(rep(0, observed[1]), rep(1, observed[2]-observed[1]))
  }
  
  n <- length(pvals)
  k_obs <- sum(pvals < alpha_ind)
  kvals <- 0:n
  dgamma <- 0.001
  gammavals <- seq(0, 1, dgamma)
  
  p_k_gamma <- matrix(0, nrow=length(gammavals), ncol=length(kvals))
  p_kk_gamma <- matrix(0, nrow=length(gammavals), ncol=length(kvals))
  
  for(iGam in 1:length(gammavals)) {
    p_pos <- gammavals[iGam] * beta_ind + (1 - gammavals[iGam]) * alpha_ind
    p_neg <- gammavals[iGam] * (1 - beta_ind) + (1 - gammavals[iGam]) * (1 - alpha_ind)
    for(iK in 1:length(kvals)) {
      k <- kvals[iK]
      tmp <- choose(n, k) * p_pos^k * p_neg^(n - k)
      p_k_gamma[iGam, iK] <- tmp
      p_kk_gamma[iGam, iK] <- 1 - sum(p_k_gamma[iGam, 1:iK]) + tmp
    }
  }
  
  iK <- which(kvals == k_obs)
  p_null <- p_kk_gamma[which(gammavals == gamma_0), iK]
  
  index <- sum(p_kk_gamma[, iK] < alpha_group)
  if(index != 0) {
    gamma_0 <- gammavals[index]
  } else {
    gamma_0 <- 0
  }
  
  return(list(p_null=p_null, gamma_0=gamma_0, p_kk_gamma=p_kk_gamma, gammavals=gammavals, p_k_gamma=p_k_gamma))
}

Non-Moral Vignettes


k <- 60  # number of persons matching hypothesized / group-level pattern
n <- 60+108 # total N
nonmoral_freqPrevalence <- prevalence_test(c(k, n)) # specify positive cases out of total cases for prev test function
nonmoral_freqPrevalence$p_null # print p-value testing against majority null
[1] 0.9999957

Moral Vignettes


k <- 125  # number of persons matching hypothesized / group-level pattern
n <- 125+43 # total N
moral_freqPrevalence <- prevalence_test(c(k, n)) # specify positive cases out of total cases for prev test function
moral_freqPrevalence$p_null # print p-value testing against majority null
[1] 0.000000004627076

Interaction


k <- 44  # number of persons matching hypothesized / group-level pattern
n <- 44+124 # total N
primary_freqPrevalence <- prevalence_test(c(k, n)) # specify positive cases out of total cases for prev test function
primary_freqPrevalence$p_null # print p-value testing against majority null
[1] 1

Bayesian Prevalence

# CREATE NECESSARY BAYES FUNCTIONS (code from Ince et al., 2021)
library(nleqslv)

bayesprev_map <- function(k, n, a=0.05, b=1) {
  # Bayesian maximum a posteriori estimate of population prevalence gamma
  # under a uniform prior
  # 
  # Args:
  #  k: number of participants/tests significant out of 
  #  n: total number of participants/tests
  #  a: alpha value of within-participant test (default=0.05)
  #  b: sensitivity/beta of within-participant test (default=1)
  
  gm <- (k/n -a)/(b-a)
  if(gm <0) gm <- 0
  if(gm>1) gm <- 1
  return(gm)
} 

bayesprev_posterior <- function(x, k, n, a=0.05, b=1) {
  # Bayesian posterior of population prevalence gamma under a uniform prior
  #
  # Args:
  # x : values of gamma at which to evaluate the posterior density
  # k : number of participants significant out of 
  # n : total number of participants
  # a : alpha value of within-participant test (default=0.05)
  # b : sensitivity/beta of within-participant test (default=1)
  
  m1 <-  k + 1
  m2 <- n - k + 1
  theta <- a + (b-a)*x
  post <- (b -a)*dbeta(theta,m1, m2)
  post <- post/(pbeta(b, m1, m2) - pbeta(a, m1, m2))
  return(post)
}


bayesprev_bound <- function(p, k, n, a=0.05, b=1) {
  # Bayesian lower bound of population prevalence gamma under a uniform prior
  #
  # Args:
  #  p : density the lower bound should bound (e.g. 0.95)
  #  k : number of participants significant out of 
  #  n : total number of participants
  #  a : alpha value of within-participant test (default=0.05)
  #  b : sensitivity/beta of within-participant test (default=1)
  
  m1 <-  k + 1
  m2 <- n - k + 1
  th_c <- qbeta( p*pbeta(a, m1, m2) + (1-p)*pbeta(b, m1, m2), m1, m2 )
  g_c <- (th_c -a)/(b-a)
  return(g_c)
}


bayesprev_hpdi <- function(p, k, n, a=0.05, b=1) {
  # Bayesian highest posterior density interval of population prevalence gamma
  # under a uniform prior
  #
  # Args:
  #  p : HPDI to return (e.g. 0.95 for 95%)
  #  k : number of participants significant out of 
  #  n : total number of participants
  #  a : alpha value of within-participant test (default=0.05)
  #  b : sensitivity/beta of within-participant test (default=1)
  
  m1 <- k+1
  m2 <- n-k+1
  
  if(m1 ==1) {
    endpts <- c(a, qbeta( (1 -p)*pbeta(a, m1, m2) + p*pbeta(b, m1, m2), m1, m2 ) ) 
    return((endpts -a)/(b-a))
  }
  
  if(m2 ==1) {
    endpts <- c( qbeta( p*pbeta(a, m1, m2) + (1- p)* pbeta(b, m1, m2), m1, m2 ) , b) 
    return( (endpts-a)/(b-a))
  }
  
  if(k<= n*a) {
    endpts <- c(a, qbeta( (1 -p)*pbeta(a, m1, m2) + p*pbeta(b, m1, m2), m1, m2 ) ) 
    return((endpts -a)/(b-a))
  }
  
  if(k>= n*b) {
    endpts <- c( qbeta( p*pbeta(a, m1, m2) + (1- p)* pbeta(b, m1, m2), m1, m2 ) , b) 
    return( (endpts-a)/(b-a))
  }
  
  
  g <- function(x, m1, m2, a, b, p ) {
    y <- numeric(2)
    y[1] <-  pbeta(x[2], m1, m2) - pbeta(x[1], m1, m2) - p*(pbeta(b, m1, m2) - pbeta(a, m1, m2))
    y[2] <- log(dbeta(x[2], m1, m2)) - log(dbeta(x[1], m1, m2))
    return(y)
  }
  
  x_init <- numeric(2)
  
  p1 <- (1-p)/2 
  p2 <- (1 +p)/2
  
  x_init[1] <- qbeta( (1 -p1)*pbeta(a, m1, m2) + p1* pbeta(b, m1, m2), m1, m2 )
  x_init[2] <- qbeta( (1 -p2)*pbeta(a, m1, m2) + p2* pbeta(b, m1, m2), m1, m2 )
  
  opt <- nleqslv(x_init, g, method ="Newton", control=list(maxit=1000), m1=m1, m2=m2, a=a, b=b, p=p)
  
  if (opt$termcd ==1)  print("convergence achieved") 
  if (opt$termcd != 1)  print("failed to converge") 
  
  temp <- opt$x
  if (temp[1] <a) {
    temp[1] <- a
    temp[2] <- qbeta( (1 -p)*pbeta(a, m1, m2) + p* pbeta(b, m1, m2), m1, m2 )
  }
  if (temp[2] > b) {
    temp[1] <- qbeta( p*pbeta(a, m1, m2) + (1-p)* pbeta(b, m1, m2), m1, m2 )
    temp[2] <- b
  }
  endpts <- (temp -a)/(b-a)
  return(endpts) 
}


bayesprev_posteriorprob <- function(x, k, n, a=0.05, b=1) {
  # Bayesian posterior probability in favour of the population prevalence gamma being greater than x
  #
  # Args:
  # x : values of gamma at which to evaluate the posterior probability
  # k : number of participants significant out of 
  # n : total number of participants
  # a : alpha value of within-participant test (default=0.05)
  # b : sensitivity/beta of within-participant test (default=1)
  
  theta <- a + (b-a)*x
  m1 <-  k + 1
  m2 <- n - k + 1
  p <- (pbeta(b,m1,m2)-pbeta(theta,m1,m2)) / (pbeta(b,m1,m2)-pbeta(a,m1,m2))
  return(p)
  
}

bayesprev_posteriorlogodds <- function(x, k, n, a=0.05, b=1) {
  # Bayesian posterior log-odds in favour of the population prevalence gamma being greater than x
  #
  # Args:
  # x : log-odds threshold
  # k : number of participants significant out of 
  # n : total number of participants
  # a : alpha value of within-participant test (default=0.05)
  # b : sensitivity/beta of within-participant test (default=1)
  
  theta <- a + (b-a)*x
  m1 <-  k + 1
  m2 <- n - k + 1
  p <- (pbeta(b,m1,m2)-pbeta(theta,m1,m2)) / (pbeta(b,m1,m2)-pbeta(a,m1,m2))
  lo<- log(p / (1 - p))
  return(lo)
  
}

Non-Moral Vignettes


k <- 60  # number of persons matching hypothesized / group-level pattern
n <- 60+108 # total N
x <- 0.50 # minority cut-off of population prevalence gamma for Bayesian posterior probability
x_0 <- 0.00 # global null of population prevalence gamma for Bayesian posterior probability
map = bayesprev_map(k, n) # get maximum a posteriori (MAP) estimate (i.e., the likeliest person-level prevalence population value)
int = bayesprev_hpdi(0.96, k, n) # get 96% HPDIs
[1] "convergence achieved"
i1 = int[1] # get lower 96% HPDI
i2 = int[2] # get upper 96% HPDI
print(c(i1, map ,i2)) # print lower 96 HPDI, map estimate, and upper 96 HPDI
[1] 0.2466803 0.3233083 0.4048897
bayesprev_posteriorprob(x, k, n) # Bayesian posterior probability in favor of population prevalence being greater than x
[1] 0.000006394378
bayesprev_posteriorprob(x_0, k, n) # Bayesian posterior probability in favor of population prevalence being greater than x_0
[1] 1

Moral Vignettes


k <- 125  # number of persons matching hypothesized / group-level pattern
n <- 125+43 # total N
x <- 0.50 # minority cut-off of population prevalence gamma for Bayesian posterior probability
x_0 <- 0.00 # global null of population prevalence gamma for Bayesian posterior probability
map = bayesprev_map(k, n) # get maximum a posteriori (MAP) estimate (i.e., the likeliest person-level prevalence population value)
int = bayesprev_hpdi(0.96, k, n) # get 96% HPDIs
[1] "convergence achieved"
i1 = int[1] # get lower 96% HPDI
i2 = int[2] # get upper 96% HPDI
print(c(i1, map ,i2)) # print lower 96 HPDI, map estimate, and upper 96 HPDI
[1] 0.6542208 0.7305764 0.7984644
bayesprev_posteriorprob(x, k, n) # Bayesian posterior probability in favor of population prevalence being greater than x
[1] 1
bayesprev_posteriorprob(x_0, k, n) # Bayesian posterior probability in favor of population prevalence being greater than x_0
[1] 1

Interaction


k <- 44  # number of persons matching hypothesized / group-level pattern
n <- 44+124 # total N
x <- 0.50 # minority cut-off of population prevalence gamma for Bayesian posterior probability
x_0 <- 0.00 # global null of population prevalence gamma for Bayesian posterior probability
map = bayesprev_map(k, n) # get maximum a posteriori (MAP) estimate (i.e., the likeliest person-level prevalence population value)
int = bayesprev_hpdi(0.96, k, n) # get 96% HPDIs
[1] "convergence achieved"
i1 = int[1] # get lower 96% HPDI
i2 = int[2] # get upper 96% HPDI
print(c(i1, map ,i2)) # print lower 96 HPDI, map estimate, and upper 96 HPDI
[1] 0.1545315 0.2230576 0.2998444
bayesprev_posteriorprob(x, k, n) # Bayesian posterior probability in favor of population prevalence being greater than x
[1] 0.000000000002327472
bayesprev_posteriorprob(x_0, k, n) # Bayesian posterior probability in favor of population prevalence being greater than x_0
[1] 1

Primary Plots

# set breaks for histograms / groups for histogram values
breaks_seezero <- c(-4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5, -0.01, 0.01, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4)

Non-Moral Vignettes

print(S1b_nonmoral <- ggplot(Study_1b_plvl, aes(x = NonmoralAverage)) +
  geom_histogram(breaks = breaks_seezero,
                 color = "grey30", fill = c("#8b1616", "#8b1616", "#8b1616", "#8b1616",
                                           "#8b1616", "#8b1616", "#8b1616", "#8b1616",
                                           "black",
                                           "#8b1616", "#8b1616", "#8b1616", "#8b1616",
                                           "#8b1616", "#8b1616", "#8b1616", "#8b1616")) +
  scale_x_continuous(limits = c(-4.1,4.1), breaks = c(-4,-3,-2,-1,0,1,2,3,4)) +
  scale_y_continuous(limits = c(-0.1,75.1), breaks = c(0, 15, 30, 45, 60, 75)) +
  xlab("\nGlobal Virtuosity Judgment") +
  ylab("Number of Participants\n") +
  theme_classic() +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 16),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))


ggsave("S1b_nonmoral_plot.png")
Saving 14.1 x 9.04 in image

Moral Vignettes

print(S1b_moral <- ggplot(Study_1b_plvl, aes(x = MoralAverage)) +
  geom_histogram(breaks = breaks_seezero,
                 color = "grey30", fill = c("#8b1616", "#8b1616", "#8b1616", "#8b1616",
                                           "#8b1616", "#8b1616", "#8b1616", "#8b1616",
                                           "black",
                                           "#8b1616", "#8b1616", "#8b1616", "#8b1616",
                                           "#8b1616", "#8b1616", "#8b1616", "#8b1616")) +
  scale_x_continuous(limits = c(-4.1,4.1), breaks = c(-4,-3,-2,-1,0,1,2,3,4)) +
  scale_y_continuous(limits = c(-0.1,50.1), breaks = c(0, 10, 20, 30, 40, 50)) +
  xlab("\nGlobal Virtuosity Judgment") +
  ylab("Number of Participants\n") +
  theme_classic() +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 16),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))


ggsave("S1b_moral_plot.png")
Saving 14.1 x 9.04 in image

Interaction

Berman & Small predicted an interaction such that tempted agents would be judged as more virtuous in non-moral contexts, but less virtuous in moral contexts. Therefore, this interaction plot shows how many participants’ responses mirrored that nuanced prediction.

print(S1b_int <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  scale_y_continuous(limits = c(-0.1,151.1), breaks = c(0, 25, 50, 75, 100, 125, 150)) +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 16),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

    
ggsave("S1b_int_plot.png")
Saving 14.1 x 9.04 in image

Robustness Plots

Here, we investigate the number of participants matching predicted effects by demographics in order to catalog the generality (or lack thereof) of these effects across levels of various the demographics that we collected.

# create yes/no variable for simple hypotheses
Study_1b_plvl <- Study_1b_plvl %>%
  mutate(fits_nonmoral = if_else(fits_hypothesis_n == 1, "Yes", "No"))

# create yes/no variable for simple hypotheses
Study_1b_plvl <- Study_1b_plvl %>%
  mutate(fits_moral = if_else(fits_hypothesis_m == 1, "Yes", "No"))

Education

Non-Moral Vignettes

print(S1b_nonmoral_educ <- ggplot(Study_1b_plvl, aes(x = fits_nonmoral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Non-Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Education_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Moral Vignettes

print(S1b_moral_educ <- ggplot(Study_1b_plvl, aes(x = fits_moral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Education_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Interaction

print(S1b_int_educ <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Education_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Political Party

Non-Moral Vignettes

print(S1b_nonmoral_pol <- ggplot(Study_1b_plvl, aes(x = fits_nonmoral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Non-Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Political_Party_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Moral Vignettes

print(S1b_moral_pol <- ggplot(Study_1b_plvl, aes(x = fits_moral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Political_Party_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Interaction

print(S1b_int_pol <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Political_Party_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Religiosity

Non-Moral Vignettes

print(S1b_nonmoral_relig <- ggplot(Study_1b_plvl, aes(x = fits_nonmoral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Non-Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Religiosity_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Moral Vignettes

print(S1b_moral_relig <- ggplot(Study_1b_plvl, aes(x = fits_moral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Religiosity_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Interaction

print(S1b_int_relig <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Religiosity_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Urban vs Rural

Non-Moral Vignettes

print(S1b_nonmoral_urb <- ggplot(Study_1b_plvl, aes(x = fits_nonmoral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Non-Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~UrbanRural_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Moral Vignettes

print(S1b_moral_urb <- ggplot(Study_1b_plvl, aes(x = fits_moral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~UrbanRural_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Interaction

print(S1b_int_urb <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~UrbanRural_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Gender

Non-Moral Vignettes

print(S1b_nonmoral_gender <- ggplot(Study_1b_plvl, aes(x = fits_nonmoral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Non-Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Gender_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Moral Vignettes

print(S1b_moral_gender <- ggplot(Study_1b_plvl, aes(x = fits_moral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Gender_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Interaction

print(S1b_int_gender <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Gender_S2) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Race

# make race one variable
Study_1b_plvl <- Study_1b_plvl %>%
  mutate(Race = coalesce(Race_S2_1, Race_S2_2, Race_S2_3, Race_S2_4, Race_S2_5, Race_S2_6, Race_S2_7, Race_S2_8))

Non-Moral Vignettes

print(S1b_nonmoral_race <- ggplot(Study_1b_plvl, aes(x = fits_nonmoral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Non-Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Race) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Moral Vignettes

print(S1b_moral_race <- ggplot(Study_1b_plvl, aes(x = fits_moral)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Moral Vignette Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Race) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

Interaction

print(S1b_int_race <- ggplot(Study_1b_plvl, aes(x = fits_complex)) +
  geom_bar(fill = "#8b1616") +
  xlab("\nMatched Predicted Interaction Pattern") +
  ylab("Number of Participants\n") +
  theme_classic() +
  facet_wrap(~Race) +
  theme(axis.title.x = element_text(size = 18), 
              axis.title.y = element_text(size = 18),
              axis.text.x = element_text(color = "black", size = 16), 
              axis.text.y = element_text(color = "black", size = 16),
              strip.text.x = element_text(color = "black", size = 12),
              legend.position = "right",
              legend.title = element_text(color = "black", size = 18),
              legend.text = element_text(color = "black", size = 16)))

LS0tDQp0aXRsZTogIlN0dWR5IDFiOiAybmQgVy1TcyBSZXBsaWNhdGlvbiBvZiBCZXJtYW4gJiBTbWFsbCAoMjAxOCkncyBTdHVkeSAyIg0KYXV0aG9yOiAiSGVsZW4gUGFkaWxsYSBGb25nICYgUnlhbiBNLiBNY01hbnVzIg0KZGF0ZTogJ2ByIGZvcm1hdChTeXMudGltZSgpLCAiJUIgJWQsICVZIilgJw0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgdGhlbWU6IGRhcmtseQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB5ZXMNCi0tLQ0KDQoNCiMgRGF0YSBQcmVwYXJhdGlvbiB7LnRhYnNldH0NCg0KSW4gdGhpcyBwcmUtcmVnaXN0ZXJlZCBzdHVkeSwgd2UgY29sbGVjdGVkIGRhdGEgZnJvbSAxNzYgcGFydGljaXBhbnRzLiBUd28gb2YgMTc2IElQIGFkZHJlc3NlcyB3ZXJlIGlkZW50aWNhbCwgd2hpY2ggcHJvbXB0ZWQgdGhlaXIgcmVtb3ZhbCBmcm9tIHRoZSBkYXRhc2V0LiBBZGRpdGlvbmFsbHksIHNpeCBwYXJ0aWNpcGFudHMgZmFpbGVkIHRoZSBhdHRlbnRpb24gY2hlY2tzLCBsZWFkaW5nIHRvIGFuIGFuYWx5emFibGUgc2FtcGxlIG9mIDE2OCBwYXJ0aWNpcGFudHMuDQoNCiMjIExvYWRpbmcgUGFja2FnZXMNCg0KQmVmb3JlIHJ1bm5pbmcgdGhpcyBjaHVuaywgcGxlYXNlIGxvYWQgIlN0dWR5IDFiLmNzdiIgaW50byB0aGUgUiBlbnZpcm9ubWVudC4NCg0KYGBge3J9DQojIHBhY2thZ2VzIHNob3VsZCBiZSBsb2FkZWQgaW4gdGhlIGZvbGxvd2luZyBvcmRlciB0byBhdm9pZCBmdW5jdGlvbiBjb25mbGljdHMNCm9wdGlvbnMoc2NpcGVuID0gOTkpICMgdHVybnMgb2ZmIHNjaWVudGlmaWMgbm90YXRpb24NCmxpYnJhcnkocHN5Y2gpICMgZm9yIGRlc2NyaWJpbmcgZGF0YQ0KbGlicmFyeShlZmZzaXplKSAjIGZvciBtZWFuIGRpZmZlcmVuY2UgZWZmZWN0IHNpemVzDQpsaWJyYXJ5KHNqc3RhdHMpICMgZm9yIGV0YS1zcXVhcmVkIGVmZmVjdCBzaXplcw0KbGlicmFyeShjb3JyZWxhdGlvbikgIyBmb3IgY2xlYW5lciBjb3JyZWxhdGlvbiB0ZXN0IG91dHB1dA0KbGlicmFyeShybWNvcnIpICMgZm9yIHJlcGVhdGVkLW1lYXN1cmVzIGNvcnJlbGF0aW9uIHRlc3RzDQpsaWJyYXJ5KGNvY29yKSAjIGZvciBjb21wYXJpbmcgZGVwZW5kZW50IGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cw0KbGlicmFyeSh0aWR5dmVyc2UpICMgZm9yIGRhdGEgbWFuaXB1bGF0aW9uIGFuZCBwbG90dGluZw0KYGBgDQoNCiMjIEF0dGVudGlvbiBDaGVjaw0KDQpQYXJ0aWNpcGFudHMgd2VyZSBpbnN0cnVjdGVkIHRvIHNlbGVjdCB6ZXJvIChpLmUuLCB0aGUgbWlkZGxlIG9wdGlvbiBpbiB0aGUgOS1wb2ludCBzY2FsZSkgYXMgdGhlaXIgcmVzcG9uc2UgZm9yIHRocmVlIG1lYXN1cmVzIHRoYXQgZm9sbG93ZWQgYSBtb2RpZmllZCBzY2VuYXJpby4gSWYgYSBwYXJ0aWNpcGFudCBmYWlsZWQgdG8gc2VsZWN0ICIwIiBhcyB0aGVpciByZXNwb25zZSBmb3IgYW55IG9mIHRoZSB0aHJlZSBtZWFzdXJlcywgdGhleSB3b3VsZCBiZSBleGNsdWRlZCBmcm9tIHRoZSBhbmFseXNlcy4NCg0KYGBge3J9DQojIEV4cGVyaW1lbnRhbCB0YXNrIGF0dGVudGlvbiBjaGVjayB2YXJpYWJsZQ0KU3R1ZHlfMWIkQXR0Q2hlY2tzIDwtIHJvd1N1bXMoU3R1ZHlfMWJbLCBjKCJBdHRuQ2hlY2sxX1MyIiwgIkF0dG5DaGVjazJfUzIiLCAiQXR0bkNoZWNrM19TMiIpXSwgbmEucm0gPSBUKQ0KDQojIFRoZSBleGNsdXNpb24gb2YgYW55IHN1bSAod2l0aGluIHRoZSB2YXJpYWJsZSAiQXR0Q2hlY2tzIikgdGhhdCBkaWQgbm90IHJlc3VsdCBpbiBhIHplcm8NClN0dWR5XzFiIDwtIFN0dWR5XzFiICU+JSANCiAgZmlsdGVyKFN0dWR5XzFiJEF0dENoZWNrcyA9PSAwKQ0KYGBgDQoNCiMjIFZhcmlhYmxlIENyZWF0aW9uDQoNClRoZSBvcmlnaW5hbCBkZXNpZ24gcHJvdmlkZWQgYnkgQmVybWFuICYgU21hbGwgcmVxdWlyZWQgdmlydHVvc2l0eSwgaG9ub3JhYmlsaXR5LCBhbmQgcmVzcGVjdGFiaWxpdHkgbWVhc3VyZXMgdG8gYmUgYXZlcmFnZWQgYWNyb3NzIGZvciBhbGwgcGFydGljaXBhbnRzLiBNb3Jlb3Zlciwgc2luY2UgdGhlIHN0dWR5IGhhZCBhIGJldHdlZW4tc3ViamVjdHMgZGVzaWduLCBpdCBpbmNsdWRlZCBhbiBvdmVyYWxsICJWaXJ0dW9zaXR5IEF2ZXJhZ2UiLiBGb3IgdGhpcyByZXBsaWNhdGlvbiwgdGhlIHdpdGhpbi1zdWJqZWN0cyBkZXNpZ24gZG9lcyBub3QgYWxsb3cgdG8gaGF2ZSBhbiBvdmVyYWxsIGF2ZXJhZ2UsIHNvIHRoZXJlIHdpbGwgYmUgYSBtb3JhbCBhbmQgYSBub24tbW9yYWwgYXZlcmFnZSBmb3IgZWFjaCBwYXJ0aWNpcGFudC4gQWRkaXRpb25hbGx5LCB0aGVyZSB3aWxsIGJlIGEgdmlydHVvc2l0eSBhdmVyYWdlIGZvciBlYWNoIHZpZ25ldHRlLg0KDQpgYGB7cn0NCg0KIyBDcmVhdGUgYSB2YXJpYWJsZSBmb3IgdmlydHVvc2l0eSBhdmVyYWdlIGluIHRoZSBtb3JhbCBjb25kaXRpb24NClN0dWR5XzFiJE1vcmFsQXZlcmFnZSA8LSByb3dNZWFucyhTdHVkeV8xYlssIGMoIkFkdWx0ZXJ5VmlydHVvdXMxX1MyIiwgIkFkdWx0ZXJ5SG9ub3JhYmxlMl9TMiIsICJBZHVsdGVyeVJlc3BlY3RhYmxlM19TMiIsICJPZmZpY2VWaXJ0dW91czFfUzIiLCAiT2ZmaWNlSG9ub3JhYmxlMl9TMiIsICJPZmZpY2VSZXNwZWN0YWJsZTNfUzIiLCAiS2lkbmV5VmlydHVvdXMxX1MyIiwgIktpZG5leUhvbm9yYWJsZTJfUzIiLCAiS2lkbmV5UmVzcGVjdGFibGUzX1MyIiwgIkFkdWx0ZXJ5VmlydHVvdXMyX1MyIiwgIkFkdWx0ZXJ5SG9ucmFibGUzX1MyIiwgIkFkdWx0ZXJ5UmVzcGVjdGFibGUxX1MyIiwgIk9mZmljZVZpcnR1b3VzMl9TMiIsICJPZmZpY2VIb25vcmFibGUzX1MyIiwgIk9mZmljZVJlc3BlY3RhYmxlMV9TMiIsICJLaWRuZXlWaXJ0dW91czJfUzIiLCAiS2lkbmV5SG9ub3JhYmxlM19TMiIsICJLaWRuZXlSZXNwZWN0YWJsZTFfUzIiLCAiQWR1bHRlcnlWaXJ0dW91czNfUzIiLCAiQWR1bHRlcnlIb25yYWJsZTFfUzIiLCAiQWR1bHRlcnlSZXNwZWN0YWJsZTJfUzIiLCAiT2ZmaWNlVmlydHVvdXMzX1MyIiwgIk9mZmljZUhvbm9yYWJsZTFfUzIiLCAiT2ZmaWNlUmVzcGVjdGFibGUyX1MyIiwgIktpZG5leVZpcnR1b3VzM19TMiIsICJLaWRuZXlIb25vcmFibGUxX1MyIiwgIktpZG5leVJlc3BlY3RhYmxlMl9TMiIpXSwgbmEucm0gPSBUKQ0KDQojIENyZWF0ZSBhIHZhcmlhYmxlIGZvciB2aXJ0dW9zaXR5IGF2ZXJhZ2UgaW4gdGhlIG5vbi1tb3JhbCBjb25kaXRpb24NClN0dWR5XzFiJE5vbm1vcmFsQXZlcmFnZSA8LSByb3dNZWFucyhTdHVkeV8xYlssIGMoIkRlc3NlcnRWaXJ0dW91czFfUzIiLCAiRGVzc2VydEhvbm9yYWJsZTJfUzIiLCAiRGVzc2VydFJlc3BlY3RhYmxlM19TMiIsICJHeW1WaXJ0dW91czFfUzIiLCAiR3ltSG9ub3JhYmxlMl9TMiIsICJHeW1SZXNwZWN0YWJsZTNfUzIiLCAiU2Nob29sd29ya1ZpcnR1b3VzMV9TMiIsICJTY2hvb2x3b3JrSG9ub3JhYmxlMl9TMiIsICJTY2hvb2x3b3JrUmVzcGVjdGFibGUzX1MyIiwgIkRlc3NlcnRWaXJ0dW91czJfUzIiLCAiRGVzc2VydEhvbm9yYWJsZTNfUzIiLCAiRGVzc2VydFJlc3BlY3RhYmxlMV9TMiIsICJHeW1WaXJ0dW91czJfUzIiLCAiR3ltSG9ub3JhYmxlM19TMiIsICJHeW1SZXNwZWN0YWJsZTFfUzIiLCAiU2Nob29sd29ya1ZpcnR1b3VzMl9TMiIsICJTY2hvb2x3b3JrSG9ub3JhYmxlM19TMiIsICJTY2hvb2x3b3JrUmVzcGVjdGFibGUxX1MyIiwgIkRlc3NlcnRWaXJ0dW91czNfUzIiLCAiRGVzc2VydEhvbm9yYWJsZTFfUzIiLCAiRGVzc2VydFJlc3BlY3RhYmxlMl9TMiIsICJHeW1WaXJ0dW91czNfUzIiLCAiR3ltSG9ub3JhYmxlMV9TMiIsICJHeW1SZXNwZWN0YWJsZTJfUzIiLCAiU2Nob29sd29ya1ZpcnR1b3VzM19TMiIsICJTY2hvb2x3b3JrSG9ub3JhYmxlMV9TMiIsICJTY2hvb2x3b3JrUmVzcGVjdGFibGUyX1MyIildLCBuYS5ybSA9IFQpDQoNCiMgQ3JlYXRlIGEgdmFyaWFibGUgZm9yIHZpcnR1b3NpdHkgYXZlcmFnZSBpbiB0aGUgT2ZmaWNlIFN1cHBsaWVzIHNjZW5hcmlvDQpTdHVkeV8xYiRPZmZpY2VBdmVyYWdlIDwtIHJvd01lYW5zKFN0dWR5XzFiWywgYygiT2ZmaWNlVmlydHVvdXMxX1MyIiwgIk9mZmljZUhvbm9yYWJsZTJfUzIiLCAiT2ZmaWNlUmVzcGVjdGFibGUzX1MyIiwgIk9mZmljZVZpcnR1b3VzMl9TMiIsICJPZmZpY2VIb25vcmFibGUzX1MyIiwgIk9mZmljZVJlc3BlY3RhYmxlMV9TMiIsICJPZmZpY2VWaXJ0dW91czNfUzIiLCAiT2ZmaWNlSG9ub3JhYmxlMV9TMiIsICJPZmZpY2VSZXNwZWN0YWJsZTJfUzIiICldLCBuYS5ybSA9IFQpDQoNCiMgQ3JlYXRlIGEgdmFyaWFibGUgZm9yIHZpcnR1b3NpdHkgYXZlcmFnZSBpbiB0aGUgQWR1bHRlcnkgc2NlbmFyaW8NClN0dWR5XzFiJEFkdWx0ZXJ5QXZlcmFnZSA8LSByb3dNZWFucyhTdHVkeV8xYlssIGMoIkFkdWx0ZXJ5VmlydHVvdXMxX1MyIiwgIkFkdWx0ZXJ5SG9ub3JhYmxlMl9TMiIsICJBZHVsdGVyeVJlc3BlY3RhYmxlM19TMiIsICJBZHVsdGVyeVZpcnR1b3VzMl9TMiIsICJBZHVsdGVyeUhvbnJhYmxlM19TMiIsICJBZHVsdGVyeVJlc3BlY3RhYmxlMV9TMiIsICJBZHVsdGVyeVZpcnR1b3VzM19TMiIsICJBZHVsdGVyeUhvbnJhYmxlMV9TMiIsICJBZHVsdGVyeVJlc3BlY3RhYmxlMl9TMiIgKV0sIG5hLnJtID0gVCkNCg0KIyBDcmVhdGUgYSB2YXJpYWJsZSBmb3IgdmlydHVvc2l0eSBhdmVyYWdlIGluIHRoZSBLaWRuZXkgc2NlbmFyaW8NClN0dWR5XzFiJEtpZG5leUF2ZXJhZ2UgPC0gcm93TWVhbnMoU3R1ZHlfMWJbLCBjKCJLaWRuZXlWaXJ0dW91czFfUzIiLCAiS2lkbmV5SG9ub3JhYmxlMl9TMiIsICJLaWRuZXlSZXNwZWN0YWJsZTNfUzIiLCAiS2lkbmV5VmlydHVvdXMyX1MyIiwgIktpZG5leUhvbm9yYWJsZTNfUzIiLCAiS2lkbmV5UmVzcGVjdGFibGUxX1MyIiwgIktpZG5leVZpcnR1b3VzM19TMiIsICJLaWRuZXlIb25vcmFibGUxX1MyIiwgIktpZG5leVJlc3BlY3RhYmxlMl9TMiIpXSwgbmEucm0gPSBUKQ0KDQojIENyZWF0ZSBhIHZhcmlhYmxlIGZvciB2aXJ0dW9zaXR5IGF2ZXJhZ2UgaW4gdGhlIERlc3NlcnQgc2NlbmFyaW8NClN0dWR5XzFiJERlc3NlcnRBdmVyYWdlIDwtIHJvd01lYW5zKFN0dWR5XzFiWywgYygiRGVzc2VydFZpcnR1b3VzMV9TMiIsICJEZXNzZXJ0SG9ub3JhYmxlMl9TMiIsICJEZXNzZXJ0UmVzcGVjdGFibGUzX1MyIiwgIkRlc3NlcnRWaXJ0dW91czJfUzIiLCAiRGVzc2VydEhvbm9yYWJsZTNfUzIiLCAiRGVzc2VydFJlc3BlY3RhYmxlMV9TMiIsICJEZXNzZXJ0VmlydHVvdXMzX1MyIiwgIkRlc3NlcnRIb25vcmFibGUxX1MyIiwgIkRlc3NlcnRSZXNwZWN0YWJsZTJfUzIiKV0sIG5hLnJtID0gVCkNCg0KIyBDcmVhdGUgYSB2YXJpYWJsZSBmb3IgdmlydHVvc2l0eSBhdmVyYWdlIGluIHRoZSBHeW0gc2NlbmFyaW8NClN0dWR5XzFiJEd5bUF2ZXJhZ2UgPC0gcm93TWVhbnMoU3R1ZHlfMWJbLCBjKCJHeW1WaXJ0dW91czFfUzIiLCAiR3ltSG9ub3JhYmxlMl9TMiIsICJHeW1SZXNwZWN0YWJsZTNfUzIiLCAiR3ltVmlydHVvdXMyX1MyIiwgIkd5bUhvbm9yYWJsZTNfUzIiLCAiR3ltUmVzcGVjdGFibGUxX1MyIiwgIkd5bVZpcnR1b3VzM19TMiIsICJHeW1Ib25vcmFibGUxX1MyIiwgIkd5bVJlc3BlY3RhYmxlMl9TMiIpXSwgbmEucm0gPSBUKQ0KDQojIENyZWF0ZSBhIHZhcmlhYmxlIGZvciB2aXJ0dW9zaXR5IGF2ZXJhZ2UgaW4gdGhlIFNjaG9vbHdvcmsgc2NlbmFyaW8NClN0dWR5XzFiJFNjaG9vbHdvcmtBdmVyYWdlIDwtIHJvd01lYW5zKFN0dWR5XzFiWywgYygiU2Nob29sd29ya1ZpcnR1b3VzMV9TMiIsICJTY2hvb2x3b3JrSG9ub3JhYmxlMl9TMiIsICJTY2hvb2x3b3JrUmVzcGVjdGFibGUzX1MyIiwgIlNjaG9vbHdvcmtWaXJ0dW91czJfUzIiLCAiU2Nob29sd29ya0hvbm9yYWJsZTNfUzIiLCAiU2Nob29sd29ya1Jlc3BlY3RhYmxlMV9TMiIsIlNjaG9vbHdvcmtWaXJ0dW91czNfUzIiLCAiU2Nob29sd29ya0hvbm9yYWJsZTFfUzIiLCAiU2Nob29sd29ya1Jlc3BlY3RhYmxlMl9TMiIpXSwgbmEucm0gPSBUKQ0KDQpgYGANCg0KPGJyPg0KDQojIEImUyAoMjAxOCkncyBHcm91cC1MdmwgQW5hbHlzZXMgey50YWJzZXR9DQoNCiMjIFNpbXBsZSBFZmZlY3RzIHsudGFic2V0fQ0KDQpGb3IgYWxsIHQtdGVzdHMsIHdlIGNvbmR1Y3QgYm90aCBvbmUtdGFpbGVkIGFuZCB0d28tdGFpbGVkIHRlc3RzLiBPdXIgcHJlLXJlZ2lzdHJhdGlvbiBzcGVjaWZpZWQgZGlyZWN0aW9uYWwgaHlwb3RoZXNlcyB3aGljaCB0aGVyZWZvcmUgb3VnaHQgdG8gYmUgYW5hbHl6ZWQgd2l0aCBvbmUtdGFpbGVkIHRlc3RzLiBIb3dldmVyLCBpbiBvcmRlciBmb3IgcmVhZGVycyB0byBrbm93IGFueSBlc3RpbWF0ZSdzIHVuY2VydGFpbnR5IGluIGJvdGggZGlyZWN0aW9ucywgd2UgYWxzbyBjb25kdWN0IHR3by10YWlsZWQgdGVzdHMgdG8gZ2V0IHJlbGV2YW50IENJcy4NCg0KIyMjIE5vbi1Nb3JhbCBWaWduZXR0ZXMgey50YWJzZXR9DQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojIE5vbi1Nb3JhbCB0LXRlc3QgdXNpbmcgcGVyc29uLWxldmVsIGF2ZXJhZ2VzIGFjcm9zcyBOb24tTW9yYWwgdmlnbmV0dGVzDQpTdHVkeV8xYl9ub25tb3JhbF90IDwtIHQudGVzdChTdHVkeV8xYiROb25tb3JhbEF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAibGVzcyIpIA0KIyMgJ2dyZWF0ZXInIGlzIGZvciBvbmUtdGFpbGVkIHAtdmFsdWUgYmVjYXVzZSBvZiB0aGUgdGVtcHRlZCA+IG5vbi10ZW1wdGVkIGh5cG90aGVzaXMgKG5lZ2F0aXZlIG51bWJlcnMgbWVhbiB0ZW1wdGVkID4gbm9uLXRlbXB0ZWQpDQpwcmludChTdHVkeV8xYl9ub25tb3JhbF90KQ0KDQpTdHVkeV8xYl9ub25tb3JhbF90XzJzaWRlIDwtIHQudGVzdChTdHVkeV8xYiROb25tb3JhbEF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikgDQojIyAndHdvLnNpZGVkJyBpcyB0byBnZXQgdW5jZXJ0YWludHkgZXN0aW1hdGVzIGluIGJvdGggZGlyZWN0aW9ucw0KcHJpbnQoU3R1ZHlfMWJfbm9ubW9yYWxfdF8yc2lkZSkNCg0KIyByZXR1cm5zIGNvaGVuJ3MgZA0KZWZmc2l6ZTo6Y29oZW4uZChTdHVkeV8xYiROb25tb3JhbEF2ZXJhZ2UsDQogICAgICAgICAgICAgICAgIGYgPSBOQSwNCiAgICAgICAgICAgICAgICAgbXUgPSAwLA0KICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSkNCmBgYA0KIyMjIyBEZXNzZXJ0IFZpZ25ldHRlDQpgYGB7cn0NCiMgRGVzc2VydCB2aWduZXR0ZSB0LXRlc3QNClN0dWR5XzFiX2Rlc3NlcnRfdCA8LSB0LnRlc3QoU3R1ZHlfMWIkRGVzc2VydEF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAibGVzcyIpIA0KIyMgJ2dyZWF0ZXInIGlzIGZvciBvbmUtdGFpbGVkIHAtdmFsdWUgYmVjYXVzZSBvZiB0aGUgdGVtcHRlZCA+IG5vbi10ZW1wdGVkIGh5cG90aGVzaXMgKG5lZ2F0aXZlIG51bWJlcnMgbWVhbiB0ZW1wdGVkID4gbm9uLXRlbXB0ZWQpDQpwcmludChTdHVkeV8xYl9kZXNzZXJ0X3QpDQoNClN0dWR5XzFiX2Rlc3NlcnRfdF8yc2lkZSA8LSB0LnRlc3QoU3R1ZHlfMWIkRGVzc2VydEF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikgDQojIyAndHdvLnNpZGVkJyBpcyB0byBnZXQgdW5jZXJ0YWludHkgZXN0aW1hdGVzIGluIGJvdGggZGlyZWN0aW9ucw0KcHJpbnQoU3R1ZHlfMWJfZGVzc2VydF90XzJzaWRlKQ0KDQojIHJldHVybnMgY29oZW4ncyBkDQplZmZzaXplOjpjb2hlbi5kKFN0dWR5XzFiJERlc3NlcnRBdmVyYWdlLA0KICAgICAgICAgICAgICAgICBmID0gTkEsDQogICAgICAgICAgICAgICAgIG11ID0gMCwNCiAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEpDQpgYGANCiMjIyMgR3ltIFZpZ25ldHRlDQpgYGB7cn0NCiMgR3ltIHZpZ25ldHRlIHQtdGVzdA0KU3R1ZHlfMWJfZ3ltX3QgPC0gdC50ZXN0KFN0dWR5XzFiJEd5bUF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAibGVzcyIpIA0KIyMgJ2dyZWF0ZXInIGlzIGZvciBvbmUtdGFpbGVkIHAtdmFsdWUgYmVjYXVzZSBvZiB0aGUgdGVtcHRlZCA+IG5vbi10ZW1wdGVkIGh5cG90aGVzaXMgKG5lZ2F0aXZlIG51bWJlcnMgbWVhbiB0ZW1wdGVkID4gbm9uLXRlbXB0ZWQpDQpwcmludChTdHVkeV8xYl9neW1fdCkNCg0KU3R1ZHlfMWJfZ3ltX3RfMnNpZGUgPC0gdC50ZXN0KFN0dWR5XzFiJEd5bUF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikgDQojIyAndHdvLnNpZGVkJyBpcyB0byBnZXQgdW5jZXJ0YWludHkgZXN0aW1hdGVzIGluIGJvdGggZGlyZWN0aW9ucw0KcHJpbnQoU3R1ZHlfMWJfZ3ltX3RfMnNpZGUpDQoNCiMgcmV0dXJucyBjb2hlbidzIGQNCmVmZnNpemU6OmNvaGVuLmQoU3R1ZHlfMWIkR3ltQXZlcmFnZSwNCiAgICAgICAgICAgICAgICAgZiA9IE5BLA0KICAgICAgICAgICAgICAgICBtdSA9IDAsDQogICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQ0KYGBgDQojIyMjIFNjaG9vbHdvcmsgVmlnbmV0dGUNCmBgYHtyfQ0KIyBTY2hvb2x3b3JrIHZpZ25ldHRlIHQtdGVzdA0KU3R1ZHlfMWJfc2Nob29sd29ya190IDwtIHQudGVzdChTdHVkeV8xYiRTY2hvb2x3b3JrQXZlcmFnZSwgbXUgPSAwLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIikgDQojIyAnZ3JlYXRlcicgaXMgZm9yIG9uZS10YWlsZWQgcC12YWx1ZSBiZWNhdXNlIG9mIHRoZSB0ZW1wdGVkID4gbm9uLXRlbXB0ZWQgaHlwb3RoZXNpcyAobmVnYXRpdmUgbnVtYmVycyBtZWFuIHRlbXB0ZWQgPiBub24tdGVtcHRlZCkNCnByaW50KFN0dWR5XzFiX3NjaG9vbHdvcmtfdCkNCg0KU3R1ZHlfMWJfc2Nob29sd29ya190XzJzaWRlIDwtIHQudGVzdChTdHVkeV8xYiRTY2hvb2x3b3JrQXZlcmFnZSwgbXUgPSAwLCBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiKSANCiMjICd0d28uc2lkZWQnIGlzIHRvIGdldCB1bmNlcnRhaW50eSBlc3RpbWF0ZXMgaW4gYm90aCBkaXJlY3Rpb25zDQpwcmludChTdHVkeV8xYl9zY2hvb2x3b3JrX3RfMnNpZGUpDQoNCiMgcmV0dXJucyBjb2hlbidzIGQNCmVmZnNpemU6OmNvaGVuLmQoU3R1ZHlfMWIkU2Nob29sd29ya0F2ZXJhZ2UsDQogICAgICAgICAgICAgICAgIGYgPSBOQSwNCiAgICAgICAgICAgICAgICAgbXUgPSAwLA0KICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSkNCmBgYA0KDQojIyMgTW9yYWwgVmlnbmV0dGVzIHsudGFic2V0fQ0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KIyBNb3JhbCB0LXRlc3QgdXNpbmcgcGVyc29uLWxldmVsIGF2ZXJhZ2VzIGFjcm9zcyBNb3JhbCB2aWduZXR0ZXMNClN0dWR5XzFiX21vcmFsX3QgPC0gdC50ZXN0KFN0dWR5XzFiJE1vcmFsQXZlcmFnZSwgbXUgPSAwLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikgDQojIyAnbGVzcycgaXMgZm9yIG9uZS10YWlsZWQgcC12YWx1ZSBiZWNhdXNlIG9mIHRoZSBub24tdGVtcHRlZCA+IHRlbXB0ZWQgaHlwb3RoZXNpcyAocG9zaXRpdmUgbnVtYmVycyBtZWFuIG5vbi10ZW1wdGVkID4gdGVtcHRlZCkNCnByaW50KFN0dWR5XzFiX21vcmFsX3QpDQoNClN0dWR5XzFiX21vcmFsX3RfMnNpZGUgPC0gdC50ZXN0KFN0dWR5XzFiJE1vcmFsQXZlcmFnZSwgbXUgPSAwLCBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiKSANCiMjICd0d28uc2lkZWQnIGlzIHRvIGdldCB1bmNlcnRhaW50eSBlc3RpbWF0ZXMgaW4gYm90aCBkaXJlY3Rpb25zDQpwcmludChTdHVkeV8xYl9tb3JhbF90XzJzaWRlKQ0KDQojIHJldHVybnMgY29oZW4ncyBkDQplZmZzaXplOjpjb2hlbi5kKFN0dWR5XzFiJE1vcmFsQXZlcmFnZSwNCiAgICAgICAgICAgICAgICAgZiA9IE5BLA0KICAgICAgICAgICAgICAgICBtdSA9IDAsDQogICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQ0KYGBgDQojIyMjIE9mZmljZSBWaWduZXR0ZQ0KYGBge3J9DQojIE9mZmljZSB2aWduZXR0ZSB0LXRlc3QNClN0dWR5XzFiX29mZmljZV90IDwtIHQudGVzdChTdHVkeV8xYiRPZmZpY2VBdmVyYWdlLCBtdSA9IDAsIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKSANCiMjICdsZXNzJyBpcyBmb3Igb25lLXRhaWxlZCBwLXZhbHVlIGJlY2F1c2Ugb2YgdGhlIG5vbi10ZW1wdGVkID4gdGVtcHRlZCBoeXBvdGhlc2lzIChwb3NpdGl2ZSBudW1iZXJzIG1lYW4gbm9uLXRlbXB0ZWQgPiB0ZW1wdGVkKQ0KcHJpbnQoU3R1ZHlfMWJfb2ZmaWNlX3QpDQoNClN0dWR5XzFiX29mZmljZV90XzJzaWRlIDwtIHQudGVzdChTdHVkeV8xYiRPZmZpY2VBdmVyYWdlLCBtdSA9IDAsIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpIA0KIyMgJ3R3by5zaWRlZCcgaXMgdG8gZ2V0IHVuY2VydGFpbnR5IGVzdGltYXRlcyBpbiBib3RoIGRpcmVjdGlvbnMNCnByaW50KFN0dWR5XzFiX29mZmljZV90XzJzaWRlKQ0KDQojIHJldHVybnMgY29oZW4ncyBkDQplZmZzaXplOjpjb2hlbi5kKFN0dWR5XzFiJE9mZmljZUF2ZXJhZ2UsDQogICAgICAgICAgICAgICAgIGYgPSBOQSwNCiAgICAgICAgICAgICAgICAgbXUgPSAwLA0KICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSkNCmBgYA0KIyMjIyBBZHVsdGVyeSBWaWduZXR0ZQ0KYGBge3J9DQojIEFkdWx0ZXJ5IHZpZ25ldHRlIHQtdGVzdA0KU3R1ZHlfMWJfYWR1bHRlcnlfdCA8LSB0LnRlc3QoU3R1ZHlfMWIkQWR1bHRlcnlBdmVyYWdlLCBtdSA9IDAsIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKSANCiMjICdsZXNzJyBpcyBmb3Igb25lLXRhaWxlZCBwLXZhbHVlIGJlY2F1c2Ugb2YgdGhlIG5vbi10ZW1wdGVkID4gdGVtcHRlZCBoeXBvdGhlc2lzIChwb3NpdGl2ZSBudW1iZXJzIG1lYW4gbm9uLXRlbXB0ZWQgPiB0ZW1wdGVkKQ0KcHJpbnQoU3R1ZHlfMWJfYWR1bHRlcnlfdCkNCg0KU3R1ZHlfMWJfYWR1bHRlcnlfdF8yc2lkZSA8LSB0LnRlc3QoU3R1ZHlfMWIkQWR1bHRlcnlBdmVyYWdlLCBtdSA9IDAsIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpIA0KIyMgJ3R3by5zaWRlZCcgaXMgdG8gZ2V0IHVuY2VydGFpbnR5IGVzdGltYXRlcyBpbiBib3RoIGRpcmVjdGlvbnMNCnByaW50KFN0dWR5XzFiX2FkdWx0ZXJ5X3RfMnNpZGUpDQoNCiMgcmV0dXJucyBjb2hlbidzIGQNCmVmZnNpemU6OmNvaGVuLmQoU3R1ZHlfMWIkQWR1bHRlcnlBdmVyYWdlLA0KICAgICAgICAgICAgICAgICBmID0gTkEsDQogICAgICAgICAgICAgICAgIG11ID0gMCwNCiAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEpDQpgYGANCiMjIyMgS2lkbmV5IFZpZ25ldHRlDQpgYGB7cn0NCiMgS2lkbmV5IHZpZ25ldHRlIHQtdGVzdA0KU3R1ZHlfMWJfa2lkbmV5X3QgPC0gdC50ZXN0KFN0dWR5XzFiJEtpZG5leUF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIpIA0KIyMgJ2xlc3MnIGlzIGZvciBvbmUtdGFpbGVkIHAtdmFsdWUgYmVjYXVzZSBvZiB0aGUgbm9uLXRlbXB0ZWQgPiB0ZW1wdGVkIGh5cG90aGVzaXMgKHBvc2l0aXZlIG51bWJlcnMgbWVhbiBub24tdGVtcHRlZCA+IHRlbXB0ZWQpDQpwcmludChTdHVkeV8xYl9raWRuZXlfdCkNCg0KU3R1ZHlfMWJfa2lkbmV5X3RfMnNpZGUgPC0gdC50ZXN0KFN0dWR5XzFiJEtpZG5leUF2ZXJhZ2UsIG11ID0gMCwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikgDQojIyAndHdvLnNpZGVkJyBpcyB0byBnZXQgdW5jZXJ0YWludHkgZXN0aW1hdGVzIGluIGJvdGggZGlyZWN0aW9ucw0KcHJpbnQoU3R1ZHlfMWJfa2lkbmV5X3RfMnNpZGUpDQoNCiMgcmV0dXJucyBjb2hlbidzIGQNCmVmZnNpemU6OmNvaGVuLmQoU3R1ZHlfMWIkS2lkbmV5QXZlcmFnZSwNCiAgICAgICAgICAgICAgICAgZiA9IE5BLA0KICAgICAgICAgICAgICAgICBtdSA9IDAsDQogICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQ0KYGBgDQoNCiMjIEludGVyYWN0aW9uIHsudGFic2V0fQ0KDQojIyMgUmVwZWF0ZWQtTWVhc3VyZXMgQU5PVkENCg0KVGhlIHB1cnBvc2Ugb2YgdGhpcyB0ZXN0IGlzIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbiBtZWFuIHZpcnR1b3NpdHkgZGVwZW5kaW5nIG9uIGNvbmRpdGlvbiAoaS5lLiwgbm9uLW1vcmFsIHZzIG1vcmFsKS4NCmBgYHtyfQ0KIyBQcmVwYXJlIGRhdGEgYnkgdXNpbmcgcGl2b3RfbG9uZ2VyIG9uIGEgbmV3IGRhdGFzZXQNClN0dWR5XzFiX2Fub3ZhIDwtIFN0dWR5XzFiICU+JQ0KICBkcGx5cjo6c2VsZWN0KGMoUmVzcG9uc2VJZCwgTW9yYWxBdmVyYWdlLCBOb25tb3JhbEF2ZXJhZ2UpKSU+JSANCiAgZ3JvdXBfYnkoUmVzcG9uc2VJZCkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gKGMoTW9yYWxBdmVyYWdlLE5vbm1vcmFsQXZlcmFnZSkpLA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiQ29uZGl0aW9uIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJWaXJ0dW9zaXR5QXZlcmFnZSIpDQoNCiMgUmVwZWF0ZWQtTWVhdXN1cmVzIEFOT1ZBDQpTdHVkeV8xYl9pbnRlcmFjdGlvbl9hb3YgPC0gYW92KFZpcnR1b3NpdHlBdmVyYWdlfkNvbmRpdGlvbiArIEVycm9yKGFzLmZhY3RvcihSZXNwb25zZUlkKSksIGRhdGEgPSBTdHVkeV8xYl9hbm92YSkNCnN1bW1hcnkoU3R1ZHlfMWJfaW50ZXJhY3Rpb25fYW92KQ0KYGBgDQojIyMgUGFpcmVkLVNhbXBsZXMgdC1UZXN0DQoNClJlcGxpY2F0ZXMgcmVzdWx0cyBvZiB0aGUgcmVwZWF0ZWQtbWVhc3VyZXMgQU5PVkEgKEJlcm1hbiAmIFNtYWxsIHVzZWQgQU5PVkFzIHJhdGhlciB0aGFuIHBhaXJlZC1zYW1wbGVzIHQtdGVzdHMgZm9yIHRoZSBpbnRlcmFjdGlvbiB0ZXN0KS4gVGhlc2UgdGVzdHMgYXJlIHN0YXRpc3RpY2FsbHkgaWRlbnRpY2FsLCBidXQgd2UgY29uZHVjdCBib3RoIGluIGNhc2UgcmVzZWFyY2hlcnMgaGF2ZSBwcmVmZXJlbmNlcyBmb3Igb25lIG92ZXIgdGhlIG90aGVyLg0KYGBge3J9DQpTdHVkeV8xYl9pbnRlcmFjdGlvbl90IDwtIHQudGVzdChWaXJ0dW9zaXR5QXZlcmFnZSB+IENvbmRpdGlvbiwgZGF0YSA9IFN0dWR5XzFiX2Fub3ZhLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIiwgcGFpcmVkID0gVFJVRSkNCiMjICdsZXNzJyBpcyBmb3Igb25lLXRhaWxlZCBwLXZhbHVlIGJlY2F1c2Ugb2YgdGhlIG5vbi1tb3JhbCA+IG1vcmFsIGh5cG90aGVzaXMgKHBvc2l0aXZlIG51bWJlcnMgbWVhbiBub24tbW9yYWwgPiBtb3JhbCkNClN0dWR5XzFiX2ludGVyYWN0aW9uX3QNCg0KU3R1ZHlfMWJfaW50ZXJhY3Rpb25fdF8yc2lkZSA8LSB0LnRlc3QoVmlydHVvc2l0eUF2ZXJhZ2UgfiBDb25kaXRpb24sIGRhdGEgPSBTdHVkeV8xYl9hbm92YSwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIiwgcGFpcmVkID0gVFJVRSkgDQojIyAndHdvLnNpZGVkJyBpcyB0byBnZXQgdW5jZXJ0YWludHkgZXN0aW1hdGVzIGluIGJvdGggZGlyZWN0aW9ucw0KcHJpbnQoU3R1ZHlfMWJfaW50ZXJhY3Rpb25fdF8yc2lkZSkNCg0KIyByZXR1cm5zIGR6IGVmZmVjdCBzaXplIGFuZCA5NSUgQ0lzDQplZmZzaXplOjpjb2hlbi5kKFZpcnR1b3NpdHlBdmVyYWdlIH4gQ29uZGl0aW9uIHwgU3ViamVjdChSZXNwb25zZUlkKSwNCiAgICAgICAgICAgICAgICAgZGF0YSA9IFN0dWR5XzFiX2Fub3ZhICU+JSBkcm9wbGV2ZWxzKCksIA0KICAgICAgICAgICAgICAgICBwYWlyZWQgPSBULA0KICAgICAgICAgICAgICAgICB3aXRoaW4gPSBGKQ0KDQojIHJldHVybnMgZC1hdiBlZmZlY3Qgc2l6ZSBhbmQgOTUlIENJcw0KZWZmc2l6ZTo6Y29oZW4uZChWaXJ0dW9zaXR5QXZlcmFnZSB+IENvbmRpdGlvbiB8IFN1YmplY3QoUmVzcG9uc2VJZCksDQogICAgICAgICAgICAgICAgIGRhdGEgPSBTdHVkeV8xYl9hbm92YSAlPiUgZHJvcGxldmVscygpLCANCiAgICAgICAgICAgICAgICAgcGFpcmVkID0gVCwNCiAgICAgICAgICAgICAgICAgd2l0aGluID0gVCkNCmBgYA0KDQoNCiMgUGVyc29uLUx2bCBBbmFseXNlcyB7LnRhYnNldH0NCg0KSXQgaXMgZmlyc3QgbmVjZXNzYXJ5IHRvIHJlYXJyYW5nZSBkYXRhIGluIGEgd2F5IHRoYXQgZmFjaWxpdGF0ZXMgY29uZHVjdGluZyB2YXJpb3VzIHBlcnNvbi1sZXZlbCBhbmFseXNlcy4NCmBgYHtyfQ0KIyBDcmVhdGUgcGVyc29uLWxldmVsIHZhcmlhYmxlcw0KU3R1ZHlfMWJfcGx2bCA8LSBTdHVkeV8xYiAlPiUgDQogIG11dGF0ZShmaXRzX2h5cG90aGVzaXNfbiA9IGlmX2Vsc2UoTm9ubW9yYWxBdmVyYWdlIDwgMCwgMSwgMCkpICU+JSANCiAgbXV0YXRlKGZpdHNfaHlwb3RoZXNpc19kZXNzZXJ0ID0gaWZfZWxzZShEZXNzZXJ0QXZlcmFnZSA8IDAsIDEsIDApKSAlPiUgDQogIG11dGF0ZShmaXRzX2h5cG90aGVzaXNfZ3ltID0gaWZfZWxzZShHeW1BdmVyYWdlIDwgMCwgMSwgMCkpICU+JSANCiAgbXV0YXRlKGZpdHNfaHlwb3RoZXNpc19zY2hvb2x3b3JrID0gaWZfZWxzZShTY2hvb2x3b3JrQXZlcmFnZSA8IDAsIDEsIDApKSAlPiUgDQogIG11dGF0ZShmaXRzX2h5cG90aGVzaXNfbSA9IGlmX2Vsc2UoTW9yYWxBdmVyYWdlID4gMCwgMSwgMCkpICU+JQ0KICBtdXRhdGUoZml0c19oeXBvdGhlc2lzX29mZmljZSA9IGlmX2Vsc2UoT2ZmaWNlQXZlcmFnZSA+IDAsIDEsIDApKSAlPiUgDQogIG11dGF0ZShmaXRzX2h5cG90aGVzaXNfYWR1bHRlcnkgPSBpZl9lbHNlKEFkdWx0ZXJ5QXZlcmFnZSA+IDAsIDEsIDApKSAlPiUgDQogIG11dGF0ZShmaXRzX2h5cG90aGVzaXNfa2lkbmV5ID0gaWZfZWxzZShLaWRuZXlBdmVyYWdlID4gMCwgMSwgMCkpDQoNCiMgQ3JlYXRlIHZhcmlhYmxlIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgcGFydGljaXBhbnRzIGZpdCB0aGUgZnVsbCBjb21wbGV4IGh5cG90aGVzaXMgb3Igbm90IA0KU3R1ZHlfMWJfcGx2bCRudW1iZXJfb2ZfaHlwX2ZpdCA8LSByb3dTdW1zKFN0dWR5XzFiX3BsdmxbLCBjKCJmaXRzX2h5cG90aGVzaXNfbSIsICJmaXRzX2h5cG90aGVzaXNfbiIpXSwgbmEucm0gPSBUKQ0KU3R1ZHlfMWJfcGx2bCA8LSBTdHVkeV8xYl9wbHZsICU+JSANCiAgIG11dGF0ZShmaXRzX2NvbXBsZXggPSBpZl9lbHNlKG51bWJlcl9vZl9oeXBfZml0ID09IDIsICJZZXMiLCAiTm8iKSkNCmBgYA0KDQojIyBEZXNjcmlwdGl2ZSBQZXJ2YXNpdmVuZXNzIHsudGFic2V0fQ0KDQojIyMgTm9uLU1vcmFsIFZpZ25ldHRlcw0KYGBge3J9DQojIEhvdyBtYW55IHBhcnRpY2lwYW50cyBmaXQgaHlwb3RoZXNpcyBmb3IgTm9uLU1vcmFsIHZpZ25ldHRlcw0KdGFibGUoU3R1ZHlfMWJfcGx2bCRmaXRzX2h5cG90aGVzaXNfbikgIyAoMCA9ICJubyI7IDEgPSAieWVzIikNCmBgYA0KIyMjIE1vcmFsIFZpZ25ldHRlcw0KYGBge3J9DQojIEhvdyBtYW55IHBhcnRpY2lwYW50cyBmaXQgaHlwb3RoZXNpcyBmb3IgTW9yYWwgdmlnbmV0dGVzDQp0YWJsZShTdHVkeV8xYl9wbHZsJGZpdHNfaHlwb3RoZXNpc19tKSAjICgwID0gIm5vIjsgMSA9ICJ5ZXMiKQ0KYGBgDQojIyMgSW50ZXJhY3Rpb24NCmBgYHtyfQ0KIyBIb3cgbWFueSBwYXJ0aWNpcGFudHMgZml0IGNvbXBsZXggaW50ZXJhY3Rpb24gaHlwb3RoZXNpcyAoaS5lLiwgaW4gTm9uLU1vcmFsIHZpZ25ldHRlczogdGVtcHRlZCA+IG5vbi10ZW1wdGVkOyBpbiBNb3JhbCB2aWduZXR0ZXM6IG5vbi10ZW1wdGVkID4gdGVtcHRlZCkNCnRhYmxlKFN0dWR5XzFiX3BsdmwkZml0c19jb21wbGV4KSAjICgwID0gIm5vIjsgMSA9ICJ5ZXMiKQ0KYGBgDQoNCiMjIFJhbmRvbWl6YXRpb24gVGVzdA0KVGhpcyB0ZXN0IGlzIG9ubHkgcG9zc2libGUgZm9yIHRoZSBjb21wbGV4IGludGVyYWN0aW9uIGh5cG90aGVzaXMsIGFzIHJhbmRvbWx5IHNodWZmbGluZyB3aXRoaW4tY29uZGl0aW9uIGRhdGEgd291bGQgeWllbGQgdGhlIHNhbWUgcmVzdWx0IGFjcm9zcyBzaHVmZmxpbmdzLg0KYGBge3J9DQpsaWJyYXJ5KG1vc2FpYykgIyBmb3IgcmFuZG9tbHkgc2h1ZmZsaW5nIGRhdGENCg0KU3R1ZHlfMWJfcmFuZG9tIDwtIFN0dWR5XzFiX3BsdmwgJT4lIA0KICBkcGx5cjo6c2VsZWN0KGMoUmVzcG9uc2VJZCwgTW9yYWxBdmVyYWdlLCBOb25tb3JhbEF2ZXJhZ2UpKQ0KDQpTdHVkeV8xYl9yYW5kb20gPC0gU3R1ZHlfMWJfcmFuZG9tICU+JSANCiAgbXV0YXRlKCJJbnRlcmFjdGlvbiIgPSBjYXNlX3doZW4oDQogICAgKE1vcmFsQXZlcmFnZSA9PSAwICYgTm9ubW9yYWxBdmVyYWdlID09IDApIH4gIlplcm8sIFplcm8sIFplcm8iLA0KICAgIChNb3JhbEF2ZXJhZ2UgPT0gMCAmIE5vbm1vcmFsQXZlcmFnZSA8IDApIH4gIlplcm8sIE5lZywgUG9zIiwNCiAgICAoTW9yYWxBdmVyYWdlID09IDAgJiBOb25tb3JhbEF2ZXJhZ2UgPiAwKSB+ICJaZXJvLCBQb3MsIE5lZyIsDQogICAgKE1vcmFsQXZlcmFnZSA8IDAgJiBOb25tb3JhbEF2ZXJhZ2UgPT0gMCkgfiAiTmVnLCBaZXJvLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2UgPCAwICYgTm9ubW9yYWxBdmVyYWdlIDwgMCAmIE1vcmFsQXZlcmFnZSA9PSBOb25tb3JhbEF2ZXJhZ2UpIH4gIk5lZywgTmVnLCBaZXJvIiwNCiAgICAoTW9yYWxBdmVyYWdlIDwgMCAmIE5vbm1vcmFsQXZlcmFnZSA+IDApIH4gIk5lZywgUG9zLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2UgPCAwICYgTm9ubW9yYWxBdmVyYWdlIDwgMCAmIE1vcmFsQXZlcmFnZSA+IE5vbm1vcmFsQXZlcmFnZSkgfiAiTmVnLCBOZWcsIFBvcyIsDQogICAgKE1vcmFsQXZlcmFnZSA8IDAgJiBOb25tb3JhbEF2ZXJhZ2UgPCAwICYgTW9yYWxBdmVyYWdlIDwgTm9ubW9yYWxBdmVyYWdlKSB+ICJOZWcsIE5lZywgTmVnIiwNCiAgICAoTW9yYWxBdmVyYWdlID4gMCAmIE5vbm1vcmFsQXZlcmFnZSA9PSAwKSB+ICJQb3MsIFplcm8sIFBvcyIsDQogICAgKE1vcmFsQXZlcmFnZSA+IDAgJiBOb25tb3JhbEF2ZXJhZ2UgPCAwKSB+ICJQb3MsIE5lZywgUG9zIiwgIyB0aGlzIGlzIHRoZSBwcmVkaWN0ZWQgcGF0dGVybg0KICAgIChNb3JhbEF2ZXJhZ2UgPiAwICYgTm9ubW9yYWxBdmVyYWdlID4gMCAmIE1vcmFsQXZlcmFnZSA9PSBOb25tb3JhbEF2ZXJhZ2UpIH4gIlBvcywgUG9zLCBaZXJvIiwNCiAgICAoTW9yYWxBdmVyYWdlID4gMCAmIE5vbm1vcmFsQXZlcmFnZSA+IDAgJiBNb3JhbEF2ZXJhZ2UgPCBOb25tb3JhbEF2ZXJhZ2UpIH4gIlBvcywgUG9zLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2UgPiAwICYgTm9ubW9yYWxBdmVyYWdlID4gMCAmIE1vcmFsQXZlcmFnZSA+IE5vbm1vcmFsQXZlcmFnZSkgfiAiUG9zLCBQb3MsIFBvcyIpKQ0KDQpwcm9wX1N0dWR5XzFiIDwtIHByb3AoIH4gSW50ZXJhY3Rpb24gPT0gIlBvcywgTmVnLCBQb3MiLCBkYXRhID0gU3R1ZHlfMWJfcmFuZG9tKSAjIGNyZWF0ZSBkZXNjcmlwdGl2ZSBwcm9wb3J0aW9uIG9mIGNsYWltZWQgcGF0dGVybiBmcm9tIEJlcm1hbiAmIFNtYWxsDQpwcm9wX1N0dWR5XzFiX2RwIDwtIHVubmFtZShwcm9wX1N0dWR5XzFiWzFdKSAjIGdldCBkZXNjcmlwdGl2ZSBwcm9wb3J0aW9uIHByb3BvcnRpb24gZm9yIGludGVyYWN0aW9uDQoNCm5zaW0gPC0gMTAwMCAjIG51bWJlciBvZiByYW5kb20gZGF0YXNldHMgdG8gZ2VuZXJhdGUNCm51bGxwcm9wX1N0dWR5XzFiIDwtIHJlcChOQSwgbnNpbSkgIyBjcmVhdGluZyBlbXB0eSBiaW4NCg0KZm9yIChpIGluIDE6bnNpbSkgeyAjIGZvciBsb29wIHRvIGRvIHJhbmRvbSBzaHVmZmxpbmcgYWNyb3NzIG5zaW0gZGF0YXNldHMgYW5kIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyBpbiB0aG9zZSByYW5kb21seSBzaHVmZmxlZCBkYXRhc2V0cw0KICAjcGVybXV0YXRpb24sIHNpemUgZXF1YWwgdG8gbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBmb3IgZWFjaCBjb25kaXRpb24NCiAgU3R1ZHlfMWJfcmFuZG9tJE5vbm1vcmFsQXZlcmFnZVIgPC0gc2h1ZmZsZShTdHVkeV8xYl9yYW5kb20kTm9ubW9yYWxBdmVyYWdlKSAjIHNodWZmbGluZyAnTm9uLU1vcmFsJyB2YWx1ZXMgIA0KICBTdHVkeV8xYl9yYW5kb20kTW9yYWxBdmVyYWdlUiA8LSBzaHVmZmxlKFN0dWR5XzFiX3JhbmRvbSRNb3JhbEF2ZXJhZ2UpICMgc2h1ZmZsaW5nICdNb3JhbCcgdmFsdWVzDQogIA0KICAjIyBDcmVhdGluZyB2YXJpYWJsZSB0aGF0IGRpc3Rpbmd1aXNoZXMgUHMgd2hvIHNob3dlZCBwcmVkaWN0ZWQgKGNsYWltZWQpIHBhdHRlcm4gZnJvbSBQcyB3aG8gZGlkIG5vdA0KICBTdHVkeV8xYl9SIDwtIFN0dWR5XzFiX3JhbmRvbSAlPiUNCiAgbXV0YXRlKCJJbnRlcmFjdGlvblIiID0gY2FzZV93aGVuKA0KICAgIChNb3JhbEF2ZXJhZ2VSID09IDAgJiBOb25tb3JhbEF2ZXJhZ2VSID09IDApIH4gIlplcm8sIFplcm8sIFplcm8iLA0KICAgIChNb3JhbEF2ZXJhZ2VSID09IDAgJiBOb25tb3JhbEF2ZXJhZ2VSIDwgMCkgfiAiWmVybywgTmVnLCBQb3MiLA0KICAgIChNb3JhbEF2ZXJhZ2VSID09IDAgJiBOb25tb3JhbEF2ZXJhZ2VSID4gMCkgfiAiWmVybywgUG9zLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2VSIDwgMCAmIE5vbm1vcmFsQXZlcmFnZVIgPT0gMCkgfiAiTmVnLCBaZXJvLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2VSIDwgMCAmIE5vbm1vcmFsQXZlcmFnZVIgPCAwICYgTW9yYWxBdmVyYWdlUiA9PSBOb25tb3JhbEF2ZXJhZ2VSKSB+ICJOZWcsIE5lZywgWmVybyIsDQogICAgKE1vcmFsQXZlcmFnZVIgPCAwICYgTm9ubW9yYWxBdmVyYWdlUiA+IDApIH4gIk5lZywgUG9zLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2VSIDwgMCAmIE5vbm1vcmFsQXZlcmFnZVIgPCAwICYgTW9yYWxBdmVyYWdlUiA+IE5vbm1vcmFsQXZlcmFnZVIpIH4gIk5lZywgTmVnLCBQb3MiLA0KICAgIChNb3JhbEF2ZXJhZ2VSIDwgMCAmIE5vbm1vcmFsQXZlcmFnZVIgPCAwICYgTW9yYWxBdmVyYWdlUiA8IE5vbm1vcmFsQXZlcmFnZVIpIH4gIk5lZywgTmVnLCBOZWciLA0KICAgIChNb3JhbEF2ZXJhZ2VSID4gMCAmIE5vbm1vcmFsQXZlcmFnZVIgPT0gMCkgfiAiUG9zLCBaZXJvLCBQb3MiLA0KICAgIChNb3JhbEF2ZXJhZ2VSID4gMCAmIE5vbm1vcmFsQXZlcmFnZVIgPCAwKSB+ICJQb3MsIE5lZywgUG9zIiwgIyB0aGlzIGlzIHRoZSBwcmVkaWN0ZWQgcGF0dGVybg0KICAgIChNb3JhbEF2ZXJhZ2VSID4gMCAmIE5vbm1vcmFsQXZlcmFnZVIgPiAwICYgTW9yYWxBdmVyYWdlUiA9PSBOb25tb3JhbEF2ZXJhZ2VSKSB+ICJQb3MsIFBvcywgWmVybyIsDQogICAgKE1vcmFsQXZlcmFnZVIgPiAwICYgTm9ubW9yYWxBdmVyYWdlUiA+IDAgJiBNb3JhbEF2ZXJhZ2VSIDwgTm9ubW9yYWxBdmVyYWdlUikgfiAiUG9zLCBQb3MsIE5lZyIsDQogICAgKE1vcmFsQXZlcmFnZVIgPiAwICYgTm9ubW9yYWxBdmVyYWdlUiA+IDAgJiBNb3JhbEF2ZXJhZ2VSID4gTm9ubW9yYWxBdmVyYWdlUikgfiAiUG9zLCBQb3MsIFBvcyIpKQ0KDQogIA0KICBudWxscHJvcF9URl9TdHVkeV8xYiA8LXByb3AoIH4gSW50ZXJhY3Rpb25SID09ICJQb3MsIE5lZywgUG9zIiwgZGF0YSA9IFN0dWR5XzFiX1IpICMgY3JlYXRlIHByb3BvcnRpb24gdmFsdWUgb2YgY2xhaW1lZCBkaXJlY3Rpb24gDQogIG51bGxwcm9wX1N0dWR5XzFiW2ldPC0gdW5uYW1lKG51bGxwcm9wX1RGX1N0dWR5XzFiWzFdKSAjIGdldCBjbGFpbWVkIHBhdHRlcm4gcHJvcG9ydGlvbiBmb3IgcmFuZG9tbHkgc2h1ZmZsZWQgZGF0YSBhbmQgcmVwZWF0IGZvciBlYWNoIG5zaW0gZGF0YXNldA0KfQ0KDQpnZl9oaXN0b2dyYW0oIH4gbnVsbHByb3BfU3R1ZHlfMWIsIGZpbGwgPSB+IChudWxscHJvcF9TdHVkeV8xYiA+PSBwcm9wX1N0dWR5XzFiX2RwKSkgIyBjcmVhdGUgaGlzdG9ncmFtIG9mIGhvdyBtYW55IHJhbmRvbWx5IHNodWZmbGVkIGRhdGFzZXRzIGxlYWQgdG8gYSBwcm9wIHZhbHVlIHNpbWlsYXIgdG8gb3IgZ3JlYXRlciB0aGFuIGVtcGlyaWNhbCBwcm9wDQoNCiNjKGNoYW5jZSktdmFsdWUgZm9yIGVtcGlyaWNhbCBwcm9wb3J0aW9uIChzaW1pbGFyIHRvIEdyaWNlJ3MgYy12YWx1ZXMgY29tcHV0ZWQgaW4gaGlzIE9PTSBzb2Z0d2FyZSkNCnByb3AoIH4gbnVsbHByb3BfU3R1ZHlfMWIgPj0gcHJvcF9TdHVkeV8xYl9kcCkgIyBzdWdnZXN0cyB0aGF0IGVtcGlyaWNhbCBpbnRlcmFjdGlvbiBwcm9wb3J0aW9uIGlzIHZlcnkgbGlrZWx5IHRvIGhhdmUgb2NjdXJyZWQgYnkgY2hhbmNlDQpgYGANCg0KDQojIyBGcmVxdWVudGlzdCBQcmV2YWxlbmNlIHsudGFic2V0fQ0KYGBge3J9DQojIENSRUFURSBORUNFU1NBUlkgRlJFUVVFTlRJU1QgRlVOQ1RJT04gKGNvZGUgYWRhcHRlZCBmcm9tIERvbmhhdXNlciBldCBhbC4ncyAoMjAxOCkgTUFUTEFCIGNvZGUpDQoNCnByZXZhbGVuY2VfdGVzdCA8LSBmdW5jdGlvbihvYnNlcnZlZCwgYWxwaGFfaW5kPTAuMDUsIGJldGFfaW5kPTEsIGFscGhhX2dyb3VwPTAuMDUsIGdhbW1hXzA9MC41KSB7DQogIA0KICAjIElucHV0czoNCiAgIyBvYnNlcnZlZCAgICA9IHZlY3RvciBvZiBwLXZhbHVlcyBPUiB2ZWN0b3Igd2l0aCB0d28gdmFsdWVzLCBlLmcuLCAnYyhwb3NpdGl2ZSBjYXNlcywgdG90YWwgY2FzZXMpJw0KICAjIGFscGhhX2luZCAgID0gYWxwaGEgdGhyZXNob2xkIGZvciBwZXJzb24tbGV2ZWwgdGVzdHMsIGlmICdvYnNlcnZlZCcgPSB2ZWN0b3Igb2YgcC12YWx1ZXMgKHR5cGljYWxseSBzZXQgdG8gLjA1KQ0KICAjIGJldGFfaW5kICAgID0gc2Vuc2l0aXZpdHkgb2YgcGVyc29uLWxldmVsIHRlc3RzIChwcm9iYWJseSBzZXQgdG8gMS4wMCkNCiAgIyBhbHBoYV9ncm91cCA9IHNlZSAib3V0cHV0cyINCiAgIyBnYW1tYV8wICAgICA9IG51bGwgZ2FtbWEgdmFsdWUgZm9yIGVtcGlyaWNhbCBwcmV2YWxlbmNlIHRvIGJlIHRlc3RlZCBhZ2FpbnN0IChkZWZhdWx0cyB0byBtYWpvcml0eSBudWxsKQ0KICANCiAgIyBPdXRwdXRzOg0KICAjIHBfbnVsbCAgICAgID0gcC12YWx1ZSBmb3IgbWFqb3JpdHkgbnVsbCBvciB3aGF0ZXZlciBudWxsIHlvdSBzcGVjaWZ5IGluIHRoZSBnYW1tYV8wIGFyZ3VtZW50IChlLmcuLCB0byBzcGVjaWZ5IGEgZ2xvYmFsIG51bGwgc2V0ICJnYW1tYV8wID0gMCIpIA0KICAjIGdhbW1hXzAgICAgID0gaGlnaGVzdCBnYW1tYV8wIHZhbHVlIHRoYXQgY2FuIGJlIHJlamVjdGVkIGF0IHRocmVzaG9sZCBvZiAnYWxwaGFfZ3JvdXAnIGdpdmVuIHBvc2l0aXZlIGNhc2VzLiBOb3RlIHRoaXMgb3V0cHV0IGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUgaW5wdXQgYXJndW1lbnQNCiAgaWYoc3VtKG9ic2VydmVkID4gMSkgPT0gMCkgew0KICAgIHB2YWxzIDwtIG9ic2VydmVkDQogIH0gZWxzZSB7DQogICAgcHZhbHMgPC0gYyhyZXAoMCwgb2JzZXJ2ZWRbMV0pLCByZXAoMSwgb2JzZXJ2ZWRbMl0tb2JzZXJ2ZWRbMV0pKQ0KICB9DQogIA0KICBuIDwtIGxlbmd0aChwdmFscykNCiAga19vYnMgPC0gc3VtKHB2YWxzIDwgYWxwaGFfaW5kKQ0KICBrdmFscyA8LSAwOm4NCiAgZGdhbW1hIDwtIDAuMDAxDQogIGdhbW1hdmFscyA8LSBzZXEoMCwgMSwgZGdhbW1hKQ0KICANCiAgcF9rX2dhbW1hIDwtIG1hdHJpeCgwLCBucm93PWxlbmd0aChnYW1tYXZhbHMpLCBuY29sPWxlbmd0aChrdmFscykpDQogIHBfa2tfZ2FtbWEgPC0gbWF0cml4KDAsIG5yb3c9bGVuZ3RoKGdhbW1hdmFscyksIG5jb2w9bGVuZ3RoKGt2YWxzKSkNCiAgDQogIGZvcihpR2FtIGluIDE6bGVuZ3RoKGdhbW1hdmFscykpIHsNCiAgICBwX3BvcyA8LSBnYW1tYXZhbHNbaUdhbV0gKiBiZXRhX2luZCArICgxIC0gZ2FtbWF2YWxzW2lHYW1dKSAqIGFscGhhX2luZA0KICAgIHBfbmVnIDwtIGdhbW1hdmFsc1tpR2FtXSAqICgxIC0gYmV0YV9pbmQpICsgKDEgLSBnYW1tYXZhbHNbaUdhbV0pICogKDEgLSBhbHBoYV9pbmQpDQogICAgZm9yKGlLIGluIDE6bGVuZ3RoKGt2YWxzKSkgew0KICAgICAgayA8LSBrdmFsc1tpS10NCiAgICAgIHRtcCA8LSBjaG9vc2UobiwgaykgKiBwX3Bvc15rICogcF9uZWdeKG4gLSBrKQ0KICAgICAgcF9rX2dhbW1hW2lHYW0sIGlLXSA8LSB0bXANCiAgICAgIHBfa2tfZ2FtbWFbaUdhbSwgaUtdIDwtIDEgLSBzdW0ocF9rX2dhbW1hW2lHYW0sIDE6aUtdKSArIHRtcA0KICAgIH0NCiAgfQ0KICANCiAgaUsgPC0gd2hpY2goa3ZhbHMgPT0ga19vYnMpDQogIHBfbnVsbCA8LSBwX2trX2dhbW1hW3doaWNoKGdhbW1hdmFscyA9PSBnYW1tYV8wKSwgaUtdDQogIA0KICBpbmRleCA8LSBzdW0ocF9ra19nYW1tYVssIGlLXSA8IGFscGhhX2dyb3VwKQ0KICBpZihpbmRleCAhPSAwKSB7DQogICAgZ2FtbWFfMCA8LSBnYW1tYXZhbHNbaW5kZXhdDQogIH0gZWxzZSB7DQogICAgZ2FtbWFfMCA8LSAwDQogIH0NCiAgDQogIHJldHVybihsaXN0KHBfbnVsbD1wX251bGwsIGdhbW1hXzA9Z2FtbWFfMCwgcF9ra19nYW1tYT1wX2trX2dhbW1hLCBnYW1tYXZhbHM9Z2FtbWF2YWxzLCBwX2tfZ2FtbWE9cF9rX2dhbW1hKSkNCn0NCg0KYGBgDQoNCiMjIyBOb24tTW9yYWwgVmlnbmV0dGVzDQpgYGB7cn0NCg0KayA8LSA2MCAgIyBudW1iZXIgb2YgcGVyc29ucyBtYXRjaGluZyBoeXBvdGhlc2l6ZWQgLyBncm91cC1sZXZlbCBwYXR0ZXJuDQpuIDwtIDYwKzEwOCAjIHRvdGFsIE4NCm5vbm1vcmFsX2ZyZXFQcmV2YWxlbmNlIDwtIHByZXZhbGVuY2VfdGVzdChjKGssIG4pKSAjIHNwZWNpZnkgcG9zaXRpdmUgY2FzZXMgb3V0IG9mIHRvdGFsIGNhc2VzIGZvciBwcmV2IHRlc3QgZnVuY3Rpb24NCm5vbm1vcmFsX2ZyZXFQcmV2YWxlbmNlJHBfbnVsbCAjIHByaW50IHAtdmFsdWUgdGVzdGluZyBhZ2FpbnN0IG1ham9yaXR5IG51bGwNCmBgYA0KIyMjIE1vcmFsIFZpZ25ldHRlcw0KYGBge3J9DQoNCmsgPC0gMTI1ICAjIG51bWJlciBvZiBwZXJzb25zIG1hdGNoaW5nIGh5cG90aGVzaXplZCAvIGdyb3VwLWxldmVsIHBhdHRlcm4NCm4gPC0gMTI1KzQzICMgdG90YWwgTg0KbW9yYWxfZnJlcVByZXZhbGVuY2UgPC0gcHJldmFsZW5jZV90ZXN0KGMoaywgbikpICMgc3BlY2lmeSBwb3NpdGl2ZSBjYXNlcyBvdXQgb2YgdG90YWwgY2FzZXMgZm9yIHByZXYgdGVzdCBmdW5jdGlvbg0KbW9yYWxfZnJlcVByZXZhbGVuY2UkcF9udWxsICMgcHJpbnQgcC12YWx1ZSB0ZXN0aW5nIGFnYWluc3QgbWFqb3JpdHkgbnVsbA0KYGBgDQojIyMgSW50ZXJhY3Rpb24NCmBgYHtyfQ0KDQprIDwtIDQ0ICAjIG51bWJlciBvZiBwZXJzb25zIG1hdGNoaW5nIGh5cG90aGVzaXplZCAvIGdyb3VwLWxldmVsIHBhdHRlcm4NCm4gPC0gNDQrMTI0ICMgdG90YWwgTg0KcHJpbWFyeV9mcmVxUHJldmFsZW5jZSA8LSBwcmV2YWxlbmNlX3Rlc3QoYyhrLCBuKSkgIyBzcGVjaWZ5IHBvc2l0aXZlIGNhc2VzIG91dCBvZiB0b3RhbCBjYXNlcyBmb3IgcHJldiB0ZXN0IGZ1bmN0aW9uDQpwcmltYXJ5X2ZyZXFQcmV2YWxlbmNlJHBfbnVsbCAjIHByaW50IHAtdmFsdWUgdGVzdGluZyBhZ2FpbnN0IG1ham9yaXR5IG51bGwNCmBgYA0KDQojIyBCYXllc2lhbiBQcmV2YWxlbmNlIHsudGFic2V0fQ0KYGBge3J9DQojIENSRUFURSBORUNFU1NBUlkgQkFZRVMgRlVOQ1RJT05TIChjb2RlIGZyb20gSW5jZSBldCBhbC4sIDIwMjEpDQpsaWJyYXJ5KG5sZXFzbHYpDQoNCmJheWVzcHJldl9tYXAgPC0gZnVuY3Rpb24oaywgbiwgYT0wLjA1LCBiPTEpIHsNCiAgIyBCYXllc2lhbiBtYXhpbXVtIGEgcG9zdGVyaW9yaSBlc3RpbWF0ZSBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgZ2FtbWENCiAgIyB1bmRlciBhIHVuaWZvcm0gcHJpb3INCiAgIyANCiAgIyBBcmdzOg0KICAjICBrOiBudW1iZXIgb2YgcGFydGljaXBhbnRzL3Rlc3RzIHNpZ25pZmljYW50IG91dCBvZiANCiAgIyAgbjogdG90YWwgbnVtYmVyIG9mIHBhcnRpY2lwYW50cy90ZXN0cw0KICAjICBhOiBhbHBoYSB2YWx1ZSBvZiB3aXRoaW4tcGFydGljaXBhbnQgdGVzdCAoZGVmYXVsdD0wLjA1KQ0KICAjICBiOiBzZW5zaXRpdml0eS9iZXRhIG9mIHdpdGhpbi1wYXJ0aWNpcGFudCB0ZXN0IChkZWZhdWx0PTEpDQogIA0KICBnbSA8LSAoay9uIC1hKS8oYi1hKQ0KICBpZihnbSA8MCkgZ20gPC0gMA0KICBpZihnbT4xKSBnbSA8LSAxDQogIHJldHVybihnbSkNCn0gDQoNCmJheWVzcHJldl9wb3N0ZXJpb3IgPC0gZnVuY3Rpb24oeCwgaywgbiwgYT0wLjA1LCBiPTEpIHsNCiAgIyBCYXllc2lhbiBwb3N0ZXJpb3Igb2YgcG9wdWxhdGlvbiBwcmV2YWxlbmNlIGdhbW1hIHVuZGVyIGEgdW5pZm9ybSBwcmlvcg0KICAjDQogICMgQXJnczoNCiAgIyB4IDogdmFsdWVzIG9mIGdhbW1hIGF0IHdoaWNoIHRvIGV2YWx1YXRlIHRoZSBwb3N0ZXJpb3IgZGVuc2l0eQ0KICAjIGsgOiBudW1iZXIgb2YgcGFydGljaXBhbnRzIHNpZ25pZmljYW50IG91dCBvZiANCiAgIyBuIDogdG90YWwgbnVtYmVyIG9mIHBhcnRpY2lwYW50cw0KICAjIGEgOiBhbHBoYSB2YWx1ZSBvZiB3aXRoaW4tcGFydGljaXBhbnQgdGVzdCAoZGVmYXVsdD0wLjA1KQ0KICAjIGIgOiBzZW5zaXRpdml0eS9iZXRhIG9mIHdpdGhpbi1wYXJ0aWNpcGFudCB0ZXN0IChkZWZhdWx0PTEpDQogIA0KICBtMSA8LSAgayArIDENCiAgbTIgPC0gbiAtIGsgKyAxDQogIHRoZXRhIDwtIGEgKyAoYi1hKSp4DQogIHBvc3QgPC0gKGIgLWEpKmRiZXRhKHRoZXRhLG0xLCBtMikNCiAgcG9zdCA8LSBwb3N0LyhwYmV0YShiLCBtMSwgbTIpIC0gcGJldGEoYSwgbTEsIG0yKSkNCiAgcmV0dXJuKHBvc3QpDQp9DQoNCg0KYmF5ZXNwcmV2X2JvdW5kIDwtIGZ1bmN0aW9uKHAsIGssIG4sIGE9MC4wNSwgYj0xKSB7DQogICMgQmF5ZXNpYW4gbG93ZXIgYm91bmQgb2YgcG9wdWxhdGlvbiBwcmV2YWxlbmNlIGdhbW1hIHVuZGVyIGEgdW5pZm9ybSBwcmlvcg0KICAjDQogICMgQXJnczoNCiAgIyAgcCA6IGRlbnNpdHkgdGhlIGxvd2VyIGJvdW5kIHNob3VsZCBib3VuZCAoZS5nLiAwLjk1KQ0KICAjICBrIDogbnVtYmVyIG9mIHBhcnRpY2lwYW50cyBzaWduaWZpY2FudCBvdXQgb2YgDQogICMgIG4gOiB0b3RhbCBudW1iZXIgb2YgcGFydGljaXBhbnRzDQogICMgIGEgOiBhbHBoYSB2YWx1ZSBvZiB3aXRoaW4tcGFydGljaXBhbnQgdGVzdCAoZGVmYXVsdD0wLjA1KQ0KICAjICBiIDogc2Vuc2l0aXZpdHkvYmV0YSBvZiB3aXRoaW4tcGFydGljaXBhbnQgdGVzdCAoZGVmYXVsdD0xKQ0KICANCiAgbTEgPC0gIGsgKyAxDQogIG0yIDwtIG4gLSBrICsgMQ0KICB0aF9jIDwtIHFiZXRhKCBwKnBiZXRhKGEsIG0xLCBtMikgKyAoMS1wKSpwYmV0YShiLCBtMSwgbTIpLCBtMSwgbTIgKQ0KICBnX2MgPC0gKHRoX2MgLWEpLyhiLWEpDQogIHJldHVybihnX2MpDQp9DQoNCg0KYmF5ZXNwcmV2X2hwZGkgPC0gZnVuY3Rpb24ocCwgaywgbiwgYT0wLjA1LCBiPTEpIHsNCiAgIyBCYXllc2lhbiBoaWdoZXN0IHBvc3RlcmlvciBkZW5zaXR5IGludGVydmFsIG9mIHBvcHVsYXRpb24gcHJldmFsZW5jZSBnYW1tYQ0KICAjIHVuZGVyIGEgdW5pZm9ybSBwcmlvcg0KICAjDQogICMgQXJnczoNCiAgIyAgcCA6IEhQREkgdG8gcmV0dXJuIChlLmcuIDAuOTUgZm9yIDk1JSkNCiAgIyAgayA6IG51bWJlciBvZiBwYXJ0aWNpcGFudHMgc2lnbmlmaWNhbnQgb3V0IG9mIA0KICAjICBuIDogdG90YWwgbnVtYmVyIG9mIHBhcnRpY2lwYW50cw0KICAjICBhIDogYWxwaGEgdmFsdWUgb2Ygd2l0aGluLXBhcnRpY2lwYW50IHRlc3QgKGRlZmF1bHQ9MC4wNSkNCiAgIyAgYiA6IHNlbnNpdGl2aXR5L2JldGEgb2Ygd2l0aGluLXBhcnRpY2lwYW50IHRlc3QgKGRlZmF1bHQ9MSkNCiAgDQogIG0xIDwtIGsrMQ0KICBtMiA8LSBuLWsrMQ0KICANCiAgaWYobTEgPT0xKSB7DQogICAgZW5kcHRzIDwtIGMoYSwgcWJldGEoICgxIC1wKSpwYmV0YShhLCBtMSwgbTIpICsgcCpwYmV0YShiLCBtMSwgbTIpLCBtMSwgbTIgKSApIA0KICAgIHJldHVybigoZW5kcHRzIC1hKS8oYi1hKSkNCiAgfQ0KICANCiAgaWYobTIgPT0xKSB7DQogICAgZW5kcHRzIDwtIGMoIHFiZXRhKCBwKnBiZXRhKGEsIG0xLCBtMikgKyAoMS0gcCkqIHBiZXRhKGIsIG0xLCBtMiksIG0xLCBtMiApICwgYikgDQogICAgcmV0dXJuKCAoZW5kcHRzLWEpLyhiLWEpKQ0KICB9DQogIA0KICBpZihrPD0gbiphKSB7DQogICAgZW5kcHRzIDwtIGMoYSwgcWJldGEoICgxIC1wKSpwYmV0YShhLCBtMSwgbTIpICsgcCpwYmV0YShiLCBtMSwgbTIpLCBtMSwgbTIgKSApIA0KICAgIHJldHVybigoZW5kcHRzIC1hKS8oYi1hKSkNCiAgfQ0KICANCiAgaWYoaz49IG4qYikgew0KICAgIGVuZHB0cyA8LSBjKCBxYmV0YSggcCpwYmV0YShhLCBtMSwgbTIpICsgKDEtIHApKiBwYmV0YShiLCBtMSwgbTIpLCBtMSwgbTIgKSAsIGIpIA0KICAgIHJldHVybiggKGVuZHB0cy1hKS8oYi1hKSkNCiAgfQ0KICANCiAgDQogIGcgPC0gZnVuY3Rpb24oeCwgbTEsIG0yLCBhLCBiLCBwICkgew0KICAgIHkgPC0gbnVtZXJpYygyKQ0KICAgIHlbMV0gPC0gIHBiZXRhKHhbMl0sIG0xLCBtMikgLSBwYmV0YSh4WzFdLCBtMSwgbTIpIC0gcCoocGJldGEoYiwgbTEsIG0yKSAtIHBiZXRhKGEsIG0xLCBtMikpDQogICAgeVsyXSA8LSBsb2coZGJldGEoeFsyXSwgbTEsIG0yKSkgLSBsb2coZGJldGEoeFsxXSwgbTEsIG0yKSkNCiAgICByZXR1cm4oeSkNCiAgfQ0KICANCiAgeF9pbml0IDwtIG51bWVyaWMoMikNCiAgDQogIHAxIDwtICgxLXApLzIgDQogIHAyIDwtICgxICtwKS8yDQogIA0KICB4X2luaXRbMV0gPC0gcWJldGEoICgxIC1wMSkqcGJldGEoYSwgbTEsIG0yKSArIHAxKiBwYmV0YShiLCBtMSwgbTIpLCBtMSwgbTIgKQ0KICB4X2luaXRbMl0gPC0gcWJldGEoICgxIC1wMikqcGJldGEoYSwgbTEsIG0yKSArIHAyKiBwYmV0YShiLCBtMSwgbTIpLCBtMSwgbTIgKQ0KICANCiAgb3B0IDwtIG5sZXFzbHYoeF9pbml0LCBnLCBtZXRob2QgPSJOZXd0b24iLCBjb250cm9sPWxpc3QobWF4aXQ9MTAwMCksIG0xPW0xLCBtMj1tMiwgYT1hLCBiPWIsIHA9cCkNCiAgDQogIGlmIChvcHQkdGVybWNkID09MSkgIHByaW50KCJjb252ZXJnZW5jZSBhY2hpZXZlZCIpIA0KICBpZiAob3B0JHRlcm1jZCAhPSAxKSAgcHJpbnQoImZhaWxlZCB0byBjb252ZXJnZSIpIA0KICANCiAgdGVtcCA8LSBvcHQkeA0KICBpZiAodGVtcFsxXSA8YSkgew0KICAgIHRlbXBbMV0gPC0gYQ0KICAgIHRlbXBbMl0gPC0gcWJldGEoICgxIC1wKSpwYmV0YShhLCBtMSwgbTIpICsgcCogcGJldGEoYiwgbTEsIG0yKSwgbTEsIG0yICkNCiAgfQ0KICBpZiAodGVtcFsyXSA+IGIpIHsNCiAgICB0ZW1wWzFdIDwtIHFiZXRhKCBwKnBiZXRhKGEsIG0xLCBtMikgKyAoMS1wKSogcGJldGEoYiwgbTEsIG0yKSwgbTEsIG0yICkNCiAgICB0ZW1wWzJdIDwtIGINCiAgfQ0KICBlbmRwdHMgPC0gKHRlbXAgLWEpLyhiLWEpDQogIHJldHVybihlbmRwdHMpIA0KfQ0KDQoNCmJheWVzcHJldl9wb3N0ZXJpb3Jwcm9iIDwtIGZ1bmN0aW9uKHgsIGssIG4sIGE9MC4wNSwgYj0xKSB7DQogICMgQmF5ZXNpYW4gcG9zdGVyaW9yIHByb2JhYmlsaXR5IGluIGZhdm91ciBvZiB0aGUgcG9wdWxhdGlvbiBwcmV2YWxlbmNlIGdhbW1hIGJlaW5nIGdyZWF0ZXIgdGhhbiB4DQogICMNCiAgIyBBcmdzOg0KICAjIHggOiB2YWx1ZXMgb2YgZ2FtbWEgYXQgd2hpY2ggdG8gZXZhbHVhdGUgdGhlIHBvc3RlcmlvciBwcm9iYWJpbGl0eQ0KICAjIGsgOiBudW1iZXIgb2YgcGFydGljaXBhbnRzIHNpZ25pZmljYW50IG91dCBvZiANCiAgIyBuIDogdG90YWwgbnVtYmVyIG9mIHBhcnRpY2lwYW50cw0KICAjIGEgOiBhbHBoYSB2YWx1ZSBvZiB3aXRoaW4tcGFydGljaXBhbnQgdGVzdCAoZGVmYXVsdD0wLjA1KQ0KICAjIGIgOiBzZW5zaXRpdml0eS9iZXRhIG9mIHdpdGhpbi1wYXJ0aWNpcGFudCB0ZXN0IChkZWZhdWx0PTEpDQogIA0KICB0aGV0YSA8LSBhICsgKGItYSkqeA0KICBtMSA8LSAgayArIDENCiAgbTIgPC0gbiAtIGsgKyAxDQogIHAgPC0gKHBiZXRhKGIsbTEsbTIpLXBiZXRhKHRoZXRhLG0xLG0yKSkgLyAocGJldGEoYixtMSxtMiktcGJldGEoYSxtMSxtMikpDQogIHJldHVybihwKQ0KICANCn0NCg0KYmF5ZXNwcmV2X3Bvc3RlcmlvcmxvZ29kZHMgPC0gZnVuY3Rpb24oeCwgaywgbiwgYT0wLjA1LCBiPTEpIHsNCiAgIyBCYXllc2lhbiBwb3N0ZXJpb3IgbG9nLW9kZHMgaW4gZmF2b3VyIG9mIHRoZSBwb3B1bGF0aW9uIHByZXZhbGVuY2UgZ2FtbWEgYmVpbmcgZ3JlYXRlciB0aGFuIHgNCiAgIw0KICAjIEFyZ3M6DQogICMgeCA6IGxvZy1vZGRzIHRocmVzaG9sZA0KICAjIGsgOiBudW1iZXIgb2YgcGFydGljaXBhbnRzIHNpZ25pZmljYW50IG91dCBvZiANCiAgIyBuIDogdG90YWwgbnVtYmVyIG9mIHBhcnRpY2lwYW50cw0KICAjIGEgOiBhbHBoYSB2YWx1ZSBvZiB3aXRoaW4tcGFydGljaXBhbnQgdGVzdCAoZGVmYXVsdD0wLjA1KQ0KICAjIGIgOiBzZW5zaXRpdml0eS9iZXRhIG9mIHdpdGhpbi1wYXJ0aWNpcGFudCB0ZXN0IChkZWZhdWx0PTEpDQogIA0KICB0aGV0YSA8LSBhICsgKGItYSkqeA0KICBtMSA8LSAgayArIDENCiAgbTIgPC0gbiAtIGsgKyAxDQogIHAgPC0gKHBiZXRhKGIsbTEsbTIpLXBiZXRhKHRoZXRhLG0xLG0yKSkgLyAocGJldGEoYixtMSxtMiktcGJldGEoYSxtMSxtMikpDQogIGxvPC0gbG9nKHAgLyAoMSAtIHApKQ0KICByZXR1cm4obG8pDQogIA0KfQ0KYGBgDQoNCiMjIyBOb24tTW9yYWwgVmlnbmV0dGVzDQpgYGB7cn0NCg0KayA8LSA2MCAgIyBudW1iZXIgb2YgcGVyc29ucyBtYXRjaGluZyBoeXBvdGhlc2l6ZWQgLyBncm91cC1sZXZlbCBwYXR0ZXJuDQpuIDwtIDYwKzEwOCAjIHRvdGFsIE4NCnggPC0gMC41MCAjIG1pbm9yaXR5IGN1dC1vZmYgb2YgcG9wdWxhdGlvbiBwcmV2YWxlbmNlIGdhbW1hIGZvciBCYXllc2lhbiBwb3N0ZXJpb3IgcHJvYmFiaWxpdHkNCnhfMCA8LSAwLjAwICMgZ2xvYmFsIG51bGwgb2YgcG9wdWxhdGlvbiBwcmV2YWxlbmNlIGdhbW1hIGZvciBCYXllc2lhbiBwb3N0ZXJpb3IgcHJvYmFiaWxpdHkNCm1hcCA9IGJheWVzcHJldl9tYXAoaywgbikgIyBnZXQgbWF4aW11bSBhIHBvc3RlcmlvcmkgKE1BUCkgZXN0aW1hdGUgKGkuZS4sIHRoZSBsaWtlbGllc3QgcGVyc29uLWxldmVsIHByZXZhbGVuY2UgcG9wdWxhdGlvbiB2YWx1ZSkNCmludCA9IGJheWVzcHJldl9ocGRpKDAuOTYsIGssIG4pICMgZ2V0IDk2JSBIUERJcw0KaTEgPSBpbnRbMV0gIyBnZXQgbG93ZXIgOTYlIEhQREkNCmkyID0gaW50WzJdICMgZ2V0IHVwcGVyIDk2JSBIUERJDQpwcmludChjKGkxLCBtYXAgLGkyKSkgIyBwcmludCBsb3dlciA5NiBIUERJLCBtYXAgZXN0aW1hdGUsIGFuZCB1cHBlciA5NiBIUERJDQpiYXllc3ByZXZfcG9zdGVyaW9ycHJvYih4LCBrLCBuKSAjIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eSBpbiBmYXZvciBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgYmVpbmcgZ3JlYXRlciB0aGFuIHgNCmJheWVzcHJldl9wb3N0ZXJpb3Jwcm9iKHhfMCwgaywgbikgIyBCYXllc2lhbiBwb3N0ZXJpb3IgcHJvYmFiaWxpdHkgaW4gZmF2b3Igb2YgcG9wdWxhdGlvbiBwcmV2YWxlbmNlIGJlaW5nIGdyZWF0ZXIgdGhhbiB4XzANCmBgYA0KIyMjIE1vcmFsIFZpZ25ldHRlcw0KYGBge3J9DQoNCmsgPC0gMTI1ICAjIG51bWJlciBvZiBwZXJzb25zIG1hdGNoaW5nIGh5cG90aGVzaXplZCAvIGdyb3VwLWxldmVsIHBhdHRlcm4NCm4gPC0gMTI1KzQzICMgdG90YWwgTg0KeCA8LSAwLjUwICMgbWlub3JpdHkgY3V0LW9mZiBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgZ2FtbWEgZm9yIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eQ0KeF8wIDwtIDAuMDAgIyBnbG9iYWwgbnVsbCBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgZ2FtbWEgZm9yIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eQ0KbWFwID0gYmF5ZXNwcmV2X21hcChrLCBuKSAjIGdldCBtYXhpbXVtIGEgcG9zdGVyaW9yaSAoTUFQKSBlc3RpbWF0ZSAoaS5lLiwgdGhlIGxpa2VsaWVzdCBwZXJzb24tbGV2ZWwgcHJldmFsZW5jZSBwb3B1bGF0aW9uIHZhbHVlKQ0KaW50ID0gYmF5ZXNwcmV2X2hwZGkoMC45NiwgaywgbikgIyBnZXQgOTYlIEhQRElzDQppMSA9IGludFsxXSAjIGdldCBsb3dlciA5NiUgSFBESQ0KaTIgPSBpbnRbMl0gIyBnZXQgdXBwZXIgOTYlIEhQREkNCnByaW50KGMoaTEsIG1hcCAsaTIpKSAjIHByaW50IGxvd2VyIDk2IEhQREksIG1hcCBlc3RpbWF0ZSwgYW5kIHVwcGVyIDk2IEhQREkNCmJheWVzcHJldl9wb3N0ZXJpb3Jwcm9iKHgsIGssIG4pICMgQmF5ZXNpYW4gcG9zdGVyaW9yIHByb2JhYmlsaXR5IGluIGZhdm9yIG9mIHBvcHVsYXRpb24gcHJldmFsZW5jZSBiZWluZyBncmVhdGVyIHRoYW4geA0KYmF5ZXNwcmV2X3Bvc3RlcmlvcnByb2IoeF8wLCBrLCBuKSAjIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eSBpbiBmYXZvciBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgYmVpbmcgZ3JlYXRlciB0aGFuIHhfMA0KYGBgDQojIyMgSW50ZXJhY3Rpb24NCmBgYHtyfQ0KDQprIDwtIDQ0ICAjIG51bWJlciBvZiBwZXJzb25zIG1hdGNoaW5nIGh5cG90aGVzaXplZCAvIGdyb3VwLWxldmVsIHBhdHRlcm4NCm4gPC0gNDQrMTI0ICMgdG90YWwgTg0KeCA8LSAwLjUwICMgbWlub3JpdHkgY3V0LW9mZiBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgZ2FtbWEgZm9yIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eQ0KeF8wIDwtIDAuMDAgIyBnbG9iYWwgbnVsbCBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgZ2FtbWEgZm9yIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eQ0KbWFwID0gYmF5ZXNwcmV2X21hcChrLCBuKSAjIGdldCBtYXhpbXVtIGEgcG9zdGVyaW9yaSAoTUFQKSBlc3RpbWF0ZSAoaS5lLiwgdGhlIGxpa2VsaWVzdCBwZXJzb24tbGV2ZWwgcHJldmFsZW5jZSBwb3B1bGF0aW9uIHZhbHVlKQ0KaW50ID0gYmF5ZXNwcmV2X2hwZGkoMC45NiwgaywgbikgIyBnZXQgOTYlIEhQRElzDQppMSA9IGludFsxXSAjIGdldCBsb3dlciA5NiUgSFBESQ0KaTIgPSBpbnRbMl0gIyBnZXQgdXBwZXIgOTYlIEhQREkNCnByaW50KGMoaTEsIG1hcCAsaTIpKSAjIHByaW50IGxvd2VyIDk2IEhQREksIG1hcCBlc3RpbWF0ZSwgYW5kIHVwcGVyIDk2IEhQREkNCmJheWVzcHJldl9wb3N0ZXJpb3Jwcm9iKHgsIGssIG4pICMgQmF5ZXNpYW4gcG9zdGVyaW9yIHByb2JhYmlsaXR5IGluIGZhdm9yIG9mIHBvcHVsYXRpb24gcHJldmFsZW5jZSBiZWluZyBncmVhdGVyIHRoYW4geA0KYmF5ZXNwcmV2X3Bvc3RlcmlvcnByb2IoeF8wLCBrLCBuKSAjIEJheWVzaWFuIHBvc3RlcmlvciBwcm9iYWJpbGl0eSBpbiBmYXZvciBvZiBwb3B1bGF0aW9uIHByZXZhbGVuY2UgYmVpbmcgZ3JlYXRlciB0aGFuIHhfMA0KYGBgDQoNCiMgUHJpbWFyeSBQbG90cyB7LnRhYnNldH0NCmBgYHtyfQ0KIyBzZXQgYnJlYWtzIGZvciBoaXN0b2dyYW1zIC8gZ3JvdXBzIGZvciBoaXN0b2dyYW0gdmFsdWVzDQpicmVha3Nfc2VlemVybyA8LSBjKC00LCAtMy41LCAtMywgLTIuNSwgLTIsIC0xLjUsIC0xLCAtMC41LCAtMC4wMSwgMC4wMSwgMC41LCAxLCAxLjUsIDIsIDIuNSwgMywgMy41LCA0KQ0KYGBgDQojIyBOb24tTW9yYWwgVmlnbmV0dGVzIHsudGFic2V0fQ0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9ub25tb3JhbCA8LSBnZ3Bsb3QoU3R1ZHlfMWJfcGx2bCwgYWVzKHggPSBOb25tb3JhbEF2ZXJhZ2UpKSArDQogIGdlb21faGlzdG9ncmFtKGJyZWFrcyA9IGJyZWFrc19zZWV6ZXJvLA0KICAgICAgICAgICAgICAgICBjb2xvciA9ICJncmV5MzAiLCBmaWxsID0gYygiIzhiMTYxNiIsICIjOGIxNjE2IiwgIiM4YjE2MTYiLCAiIzhiMTYxNiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiM4YjE2MTYiLCAiIzhiMTYxNiIsICIjOGIxNjE2IiwgIiM4YjE2MTYiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJibGFjayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiM4YjE2MTYiLCAiIzhiMTYxNiIsICIjOGIxNjE2IiwgIiM4YjE2MTYiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjOGIxNjE2IiwgIiM4YjE2MTYiLCAiIzhiMTYxNiIsICIjOGIxNjE2IikpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTQuMSw0LjEpLCBicmVha3MgPSBjKC00LC0zLC0yLC0xLDAsMSwyLDMsNCkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuMSw3NS4xKSwgYnJlYWtzID0gYygwLCAxNSwgMzAsIDQ1LCA2MCwgNzUpKSArDQogIHhsYWIoIlxuR2xvYmFsIFZpcnR1b3NpdHkgSnVkZ21lbnQiKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksIA0KICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLCANCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLA0KICAgICAgICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTgpLA0KICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNikpKQ0KDQpnZ3NhdmUoIlMxYl9ub25tb3JhbF9wbG90LnBuZyIpDQpgYGANCiMjIE1vcmFsIFZpZ25ldHRlcyB7LnRhYnNldH0NCmBgYHtyLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICI3NSUiLCBvdXQuaGVpZ2h0ID0gIjc1JSJ9DQpwcmludChTMWJfbW9yYWwgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gTW9yYWxBdmVyYWdlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShicmVha3MgPSBicmVha3Nfc2VlemVybywNCiAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JleTMwIiwgZmlsbCA9IGMoIiM4YjE2MTYiLCAiIzhiMTYxNiIsICIjOGIxNjE2IiwgIiM4YjE2MTYiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjOGIxNjE2IiwgIiM4YjE2MTYiLCAiIzhiMTYxNiIsICIjOGIxNjE2IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjOGIxNjE2IiwgIiM4YjE2MTYiLCAiIzhiMTYxNiIsICIjOGIxNjE2IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIzhiMTYxNiIsICIjOGIxNjE2IiwgIiM4YjE2MTYiLCAiIzhiMTYxNiIpKSArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC00LjEsNC4xKSwgYnJlYWtzID0gYygtNCwtMywtMiwtMSwwLDEsMiwzLDQpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0wLjEsNTAuMSksIGJyZWFrcyA9IGMoMCwgMTAsIDIwLCAzMCwgNDAsIDUwKSkgKw0KICB4bGFiKCJcbkdsb2JhbCBWaXJ0dW9zaXR5IEp1ZGdtZW50IikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCg0KZ2dzYXZlKCJTMWJfbW9yYWxfcGxvdC5wbmciKQ0KYGBgDQojIyBJbnRlcmFjdGlvbiB7LnRhYnNldH0NCkJlcm1hbiAmIFNtYWxsIHByZWRpY3RlZCBhbiBpbnRlcmFjdGlvbiBzdWNoIHRoYXQgdGVtcHRlZCBhZ2VudHMgd291bGQgYmUganVkZ2VkIGFzIG1vcmUgdmlydHVvdXMgaW4gbm9uLW1vcmFsIGNvbnRleHRzLCBidXQgbGVzcyB2aXJ0dW91cyBpbiBtb3JhbCBjb250ZXh0cy4gVGhlcmVmb3JlLCB0aGlzIGludGVyYWN0aW9uIHBsb3Qgc2hvd3MgaG93IG1hbnkgcGFydGljaXBhbnRzJyByZXNwb25zZXMgbWlycm9yZWQgdGhhdCBudWFuY2VkIHByZWRpY3Rpb24uDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX2ludCA8LSBnZ3Bsb3QoU3R1ZHlfMWJfcGx2bCwgYWVzKHggPSBmaXRzX2NvbXBsZXgpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuMSwxNTEuMSksIGJyZWFrcyA9IGMoMCwgMjUsIDUwLCA3NSwgMTAwLCAxMjUsIDE1MCkpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBJbnRlcmFjdGlvbiBQYXR0ZXJuIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCiAgICANCmdnc2F2ZSgiUzFiX2ludF9wbG90LnBuZyIpDQpgYGANCg0KIyBSb2J1c3RuZXNzIFBsb3RzIHsudGFic2V0fQ0KSGVyZSwgd2UgaW52ZXN0aWdhdGUgdGhlIG51bWJlciBvZiBwYXJ0aWNpcGFudHMgbWF0Y2hpbmcgcHJlZGljdGVkIGVmZmVjdHMgYnkgZGVtb2dyYXBoaWNzIGluIG9yZGVyIHRvIGNhdGFsb2cgdGhlIGdlbmVyYWxpdHkgKG9yIGxhY2sgdGhlcmVvZikgb2YgdGhlc2UgZWZmZWN0cyBhY3Jvc3MgbGV2ZWxzIG9mIHZhcmlvdXMgdGhlIGRlbW9ncmFwaGljcyB0aGF0IHdlIGNvbGxlY3RlZC4NCmBgYHtyfQ0KIyBjcmVhdGUgeWVzL25vIHZhcmlhYmxlIGZvciBzaW1wbGUgaHlwb3RoZXNlcw0KU3R1ZHlfMWJfcGx2bCA8LSBTdHVkeV8xYl9wbHZsICU+JQ0KICBtdXRhdGUoZml0c19ub25tb3JhbCA9IGlmX2Vsc2UoZml0c19oeXBvdGhlc2lzX24gPT0gMSwgIlllcyIsICJObyIpKQ0KDQojIGNyZWF0ZSB5ZXMvbm8gdmFyaWFibGUgZm9yIHNpbXBsZSBoeXBvdGhlc2VzDQpTdHVkeV8xYl9wbHZsIDwtIFN0dWR5XzFiX3BsdmwgJT4lDQogIG11dGF0ZShmaXRzX21vcmFsID0gaWZfZWxzZShmaXRzX2h5cG90aGVzaXNfbSA9PSAxLCAiWWVzIiwgIk5vIikpDQpgYGANCg0KIyMgRWR1Y2F0aW9uIHsudGFic2V0fQ0KDQojIyMgTm9uLU1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9ub25tb3JhbF9lZHVjIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfbm9ubW9yYWwpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBOb24tTW9yYWwgVmlnbmV0dGUgUGF0dGVybiIpICsNCiAgeWxhYigiTnVtYmVyIG9mIFBhcnRpY2lwYW50c1xuIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBmYWNldF93cmFwKH5FZHVjYXRpb25fUzIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksIA0KICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLCANCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLA0KICAgICAgICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTIpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTgpLA0KICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNikpKQ0KYGBgDQojIyMgTW9yYWwgVmlnbmV0dGVzDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX21vcmFsX2VkdWMgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gZml0c19tb3JhbCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIE1vcmFsIFZpZ25ldHRlIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+RWR1Y2F0aW9uX1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KIyMjIEludGVyYWN0aW9uDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX2ludF9lZHVjIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfY29tcGxleCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIEludGVyYWN0aW9uIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+RWR1Y2F0aW9uX1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KDQojIyBQb2xpdGljYWwgUGFydHkgey50YWJzZXR9DQoNCiMjIyBOb24tTW9yYWwgVmlnbmV0dGVzDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX25vbm1vcmFsX3BvbCA8LSBnZ3Bsb3QoU3R1ZHlfMWJfcGx2bCwgYWVzKHggPSBmaXRzX25vbm1vcmFsKSkgKw0KICBnZW9tX2JhcihmaWxsID0gIiM4YjE2MTYiKSArDQogIHhsYWIoIlxuTWF0Y2hlZCBQcmVkaWN0ZWQgTm9uLU1vcmFsIFZpZ25ldHRlIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+UG9saXRpY2FsX1BhcnR5X1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KIyMjIE1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9tb3JhbF9wb2wgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gZml0c19tb3JhbCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIE1vcmFsIFZpZ25ldHRlIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+UG9saXRpY2FsX1BhcnR5X1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KIyMjIEludGVyYWN0aW9uDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX2ludF9wb2wgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gZml0c19jb21wbGV4KSkgKw0KICBnZW9tX2JhcihmaWxsID0gIiM4YjE2MTYiKSArDQogIHhsYWIoIlxuTWF0Y2hlZCBQcmVkaWN0ZWQgSW50ZXJhY3Rpb24gUGF0dGVybiIpICsNCiAgeWxhYigiTnVtYmVyIG9mIFBhcnRpY2lwYW50c1xuIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBmYWNldF93cmFwKH5Qb2xpdGljYWxfUGFydHlfUzIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksIA0KICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLCANCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLA0KICAgICAgICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTIpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTgpLA0KICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNikpKQ0KYGBgDQoNCiMjIFJlbGlnaW9zaXR5IHsudGFic2V0fQ0KDQojIyMgTm9uLU1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9ub25tb3JhbF9yZWxpZyA8LSBnZ3Bsb3QoU3R1ZHlfMWJfcGx2bCwgYWVzKHggPSBmaXRzX25vbm1vcmFsKSkgKw0KICBnZW9tX2JhcihmaWxsID0gIiM4YjE2MTYiKSArDQogIHhsYWIoIlxuTWF0Y2hlZCBQcmVkaWN0ZWQgTm9uLU1vcmFsIFZpZ25ldHRlIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+UmVsaWdpb3NpdHlfUzIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksIA0KICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLCANCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLA0KICAgICAgICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTIpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTgpLA0KICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNikpKQ0KYGBgDQojIyMgTW9yYWwgVmlnbmV0dGVzDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX21vcmFsX3JlbGlnIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfbW9yYWwpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBNb3JhbCBWaWduZXR0ZSBQYXR0ZXJuIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGZhY2V0X3dyYXAoflJlbGlnaW9zaXR5X1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KIyMjIEludGVyYWN0aW9uDQpgYGB7ciwgZmlnLndpZHRoID0gMTQsIGZpZy5oZWlnaHQgPSA5LCBvdXQud2lkdGggPSAiNzUlIiwgb3V0LmhlaWdodCA9ICI3NSUifQ0KcHJpbnQoUzFiX2ludF9yZWxpZyA8LSBnZ3Bsb3QoU3R1ZHlfMWJfcGx2bCwgYWVzKHggPSBmaXRzX2NvbXBsZXgpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBJbnRlcmFjdGlvbiBQYXR0ZXJuIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGZhY2V0X3dyYXAoflJlbGlnaW9zaXR5X1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KDQojIyBVcmJhbiB2cyBSdXJhbCB7LnRhYnNldH0NCg0KIyMjIE5vbi1Nb3JhbCBWaWduZXR0ZXMNCmBgYHtyLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICI3NSUiLCBvdXQuaGVpZ2h0ID0gIjc1JSJ9DQpwcmludChTMWJfbm9ubW9yYWxfdXJiIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfbm9ubW9yYWwpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBOb24tTW9yYWwgVmlnbmV0dGUgUGF0dGVybiIpICsNCiAgeWxhYigiTnVtYmVyIG9mIFBhcnRpY2lwYW50c1xuIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBmYWNldF93cmFwKH5VcmJhblJ1cmFsX1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KIyMjIE1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9tb3JhbF91cmIgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gZml0c19tb3JhbCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIE1vcmFsIFZpZ25ldHRlIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+VXJiYW5SdXJhbF9TMikgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwgDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLA0KICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksIA0KICAgICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksDQogICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxMiksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSkpDQpgYGANCiMjIyBJbnRlcmFjdGlvbg0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9pbnRfdXJiIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfY29tcGxleCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIEludGVyYWN0aW9uIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+VXJiYW5SdXJhbF9TMikgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwgDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLA0KICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksIA0KICAgICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksDQogICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxMiksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSkpDQpgYGANCg0KIyMgR2VuZGVyIHsudGFic2V0fQ0KDQojIyMgTm9uLU1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9ub25tb3JhbF9nZW5kZXIgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gZml0c19ub25tb3JhbCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIE5vbi1Nb3JhbCBWaWduZXR0ZSBQYXR0ZXJuIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGZhY2V0X3dyYXAofkdlbmRlcl9TMikgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwgDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLA0KICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksIA0KICAgICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksDQogICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxMiksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSkpDQpgYGANCiMjIyBNb3JhbCBWaWduZXR0ZXMNCmBgYHtyLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICI3NSUiLCBvdXQuaGVpZ2h0ID0gIjc1JSJ9DQpwcmludChTMWJfbW9yYWxfZ2VuZGVyIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfbW9yYWwpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBNb3JhbCBWaWduZXR0ZSBQYXR0ZXJuIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGZhY2V0X3dyYXAofkdlbmRlcl9TMikgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwgDQogICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLA0KICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksIA0KICAgICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiksDQogICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxMiksDQogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSkpDQpgYGANCiMjIyBJbnRlcmFjdGlvbg0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9pbnRfZ2VuZGVyIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfY29tcGxleCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOGIxNjE2IikgKw0KICB4bGFiKCJcbk1hdGNoZWQgUHJlZGljdGVkIEludGVyYWN0aW9uIFBhdHRlcm4iKSArDQogIHlsYWIoIk51bWJlciBvZiBQYXJ0aWNpcGFudHNcbiIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgZmFjZXRfd3JhcCh+R2VuZGVyX1MyKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KDQojIyBSYWNlIHsudGFic2V0fQ0KDQpgYGB7cn0NCiMgbWFrZSByYWNlIG9uZSB2YXJpYWJsZQ0KU3R1ZHlfMWJfcGx2bCA8LSBTdHVkeV8xYl9wbHZsICU+JQ0KICBtdXRhdGUoUmFjZSA9IGNvYWxlc2NlKFJhY2VfUzJfMSwgUmFjZV9TMl8yLCBSYWNlX1MyXzMsIFJhY2VfUzJfNCwgUmFjZV9TMl81LCBSYWNlX1MyXzYsIFJhY2VfUzJfNywgUmFjZV9TMl84KSkNCmBgYA0KDQojIyMgTm9uLU1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9ub25tb3JhbF9yYWNlIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfbm9ubW9yYWwpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBOb24tTW9yYWwgVmlnbmV0dGUgUGF0dGVybiIpICsNCiAgeWxhYigiTnVtYmVyIG9mIFBhcnRpY2lwYW50c1xuIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBmYWNldF93cmFwKH5SYWNlKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KIyMjIE1vcmFsIFZpZ25ldHRlcw0KYGBge3IsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOSwgb3V0LndpZHRoID0gIjc1JSIsIG91dC5oZWlnaHQgPSAiNzUlIn0NCnByaW50KFMxYl9tb3JhbF9yYWNlIDwtIGdncGxvdChTdHVkeV8xYl9wbHZsLCBhZXMoeCA9IGZpdHNfbW9yYWwpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzhiMTYxNiIpICsNCiAgeGxhYigiXG5NYXRjaGVkIFByZWRpY3RlZCBNb3JhbCBWaWduZXR0ZSBQYXR0ZXJuIikgKw0KICB5bGFiKCJOdW1iZXIgb2YgUGFydGljaXBhbnRzXG4iKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIGZhY2V0X3dyYXAoflJhY2UpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksIA0KICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLCANCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpLA0KICAgICAgICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTIpLA0KICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTgpLA0KICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNikpKQ0KYGBgDQojIyMgSW50ZXJhY3Rpb24NCmBgYHtyLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICI3NSUiLCBvdXQuaGVpZ2h0ID0gIjc1JSJ9DQpwcmludChTMWJfaW50X3JhY2UgPC0gZ2dwbG90KFN0dWR5XzFiX3BsdmwsIGFlcyh4ID0gZml0c19jb21wbGV4KSkgKw0KICBnZW9tX2JhcihmaWxsID0gIiM4YjE2MTYiKSArDQogIHhsYWIoIlxuTWF0Y2hlZCBQcmVkaWN0ZWQgSW50ZXJhY3Rpb24gUGF0dGVybiIpICsNCiAgeWxhYigiTnVtYmVyIG9mIFBhcnRpY2lwYW50c1xuIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBmYWNldF93cmFwKH5SYWNlKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLCANCiAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksDQogICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwgDQogICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyKSwNCiAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE4KSwNCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMTYpKSkNCmBgYA0KDQoNCg0KDQoNCg==