Descriptive Statistics

Histograms of volumes and clusters

Boxplots sied by side of lobes

Boxplots side by side of vascular territories

library(ggplot2)
library(tidyverse)
library(viridis)
library(hrbrthemes)#for the violin plot
library(lme4)
library(reshape2)
library(splines)
library(modelr)
library(corrplot)
library(ggeffects)#ggpredict
#options(na.action = na.warn)
library(dplyr)

data <- read.csv("D:\\Dropbox/PhD/ukb/cross_merged_lobes.csv")

data$eid <- as.factor(data$eid)
data$sex <- as.factor(data$sex)


# descriptives
data$age_at_scan <-as.numeric(data$age_at_scan)
data$pvs_vol_mm3 <-as.numeric(data$pvs_vol_mm3)
data$overall_health_rating <-as.numeric(data$overall_health_rating)
data$overall_health_rating <- replace(data$overall_health_rating, which(data$overall_health_rating < 1), NA)
#data$overall_health_rating <- factor(data$overall_health_rating,levels=c(1,2,3,4),ordered=TRUE)
data$sex <- as.factor(data$sex)
data$diagnosed_diabetes <- factor(data$diagnosed_diabetes,c(0,1))
data$sex <- factor(data$sex,c(0,1))

summary(data$sex)
summary(data$age_at_scan)

data$typical_daily_alcohol <- replace(data$typical_daily_alcohol, which(data$typical_daily_alcohol < 0), NA)
data$typical_daily_alcohol <- factor(data$typical_daily_alcohol,c(1,2,3,4,5))
data$alcohol_frequency <- replace(data$alcohol_frequency, which(data$alcohol_frequency < 0), NA)
data$alcohol_frequency <- factor(data$alcohol_frequency)

summary(data$alcohol_frequency)
#hist(data$alcohol_frequency)


data$sleep_duration_sr <- replace(data$sleep_duration_sr, which(data$sleep_duration_sr < 0), NA)
summary(data$sleep_duration_sr)


data$freq_depressed_twoweeks <- replace(data$freq_depressed_twoweeks, which(data$freq_depressed_twoweeks < 0), NA)

summary(data$freq_depressed_twoweeks)
summary(data$height)
summary(data$weight)
summary(data$BMI)
summary(data$townsend_deprivation_index)

data$snoring_sr <- replace(data$snoring_sr, which(data$snoring_sr < 0), NA)
data$insomnia_sr <- replace(data$insomnia_sr, which(data$insomnia_sr < 0), NA)
data$difficulty_getting_up_morning <- replace(data$difficulty_getting_up_morning, which(data$difficulty_getting_up_morning < 0), NA)
data$avg_total_household_income <- replace(data$avg_total_household_income, which(data$avg_total_household_income < 0), NA)

summary(data$snoring_sr)
summary(data$insomnia_sr)
summary(data$difficulty_getting_up_morning)
summary(data$avg_total_household_income)
summary(data$ipaq_activity_group)

data$snoring_sr <- factor(data$snoring_sr)
data$insomnia_sr <- factor(data$insomnia_sr)
data$ipaq_activity_group <- factor(data$ipaq_activity_group)
data$avg_total_household_income <- factor(data$avg_total_household_income)

summary(data$age_at_scan)
summary(data$sex)
summary(data$pvs_vol_mm3)
summary(data$pvs_clusters)
summary(data$age_at_scan)

# create new vars

data$front_pvs_vol <- data$frontal_r + data$frontal_l
data$par_pvs_vol <- data$parietal_r + data$parietal_l
data$temp_pvs_vol <- data$temporal_r + data$temporal_l
data$occ_pvs_vol <- data$occipital_r + data$occipital_l
data$cerebel_pvs_vol <- data$cerebellum_r + data$cerebellum_l
#data$brainstem

data$anterior_pvs_vol <- data$ACAL + data$ACAR + data$MLSL + data$MLSR
data$middle_pvs_vol <- data$LLSL+data$LLSR+data$MCAFL+data$MCAFR+
                        data$MCAPL+data$MCAPR+data$MCATL+data$MCAOR+
                        data$MCAOL+data$MCAOR.1+data$MCAIL+data$MCAIR
data$post_pvs_vol <- data$PCATL+data$PCATR+data$PCAOL+data$PCAOR+
                      data$PCTPL+data$PCTPR+data$ACTPL+data$ACTPR
data$vb_pvs_vol <- data$BL+data$BR+data$SCL+data$SCR+data$ICL+data$ICR
data$vents_pvs_vol <- data$LVL+data$LVR

data$ACA_pvs_vol <- data$ACAL+data$ACAR
data$LLS_pvs_vol <- data$LLSL + data$LLSR
data$MCAF_pvs_vol <- data$MCAFL + data$MCAFR
data$MCAP_pvs_vol <- data$MCAPL + data$MCAPR

data$MCAT_pvs_vol <- data$MCATL+data$MCAOR
data$MCA0_pvs_vol <- data$MCAOL+data$MCAOR.1
# boxplots
# format and add in descriptive variables: median, mean, sd, min , max
boxplot(data$pvs_vol_mm3,
         main = "Boxplots",
         ylab = bquote("PVS Volume"~(mm^3)),
         xlab =c("PVS Volume"))

boxplot(data$pvs_clusters,
         main = "Boxplots",
         ylab = bquote("PVS Clusters"),
         xlab =c("PVS Clusters"))

# histograms
vol_density <- hist(data$pvs_vol_mm3,breaks=50,col="#87CEEB",xlab=bquote("PVS Volume"~(mm^3)),main="",cex.lab=1.3)
clu_density <- hist(data$pvs_clusters, breaks=50, col="#87CEEB",xlab="PVS Clusters",main="",cex.lab=1.3)

summary(data$pvs_vol_mm3)
summary(data$pvs_clusters)


boxplot(data$front_pvs_vol,data$par_pvs_vol,data$temp_pvs_vol,
        data$occ_pvs_vol,data$cerebel_pvs_vol,
         main = "Lobar Distributions",
         ylab = bquote("PVS Volume"~(mm^3)),
         names =c("Frontal", "Parietal", "Temporal", "Occipital Lobe","Cerebellar"))

# violin plot for wm lobes
subset_data_lobes <- data[c("front_pvs_vol","par_pvs_vol","temp_pvs_vol")]#,"occ_pvs_vol","cerebel_pvs_vol")]
meltData_lobes <- melt(subset_data_lobes)
boxplot(data=meltData_lobes, value~variable)

# Violin basic
meltData_lobes %>%
  ggplot( aes(factor(variable), value, fill=variable),) +
    geom_violin() +
    scale_fill_viridis(discrete = TRUE, alpha=0.6, option="A") +
    #theme_ipsum() +
    theme(
      legend.position="none",
      plot.title = element_text(size=15,hjust=0.5),
      text = element_text(size = 15)
      ) +
  ggtitle("Violin chart of Lobar Distributions") + 
  scale_x_discrete(breaks=c("front_pvs_vol","par_pvs_vol","temp_pvs_vol"),
                   labels=c("Frontal", "Parietal", "Temporal")) +
  ylab(bquote("PVS Volume"~(mm^3))) + xlab("")
  #geom_jitter(color="black", size=0.01, alpha=0.1) +
    


boxplot(data$anterior_pvs_vol,data$middle_pvs_vol,data$post_pvs_vol,
        data$vb_pvs_vol,data$vents_pvs_vol,
         main = "PVS Distribution by Vascular Territory",
         ylab = bquote("PVS Volume"~(mm^3)),
         names =c("ACA", "MCA", "PCA", "VB","LV"))
#VB=Vertebro-Basilar
#LV=Lateral Ventricular

# breakdown of ACA  territory
boxplot(data$ACAL+data$ACAR,data$MLSL+data$MLSR,
         main = "Subdivisions of the Anterior Territory",
         ylab = bquote("PVS Volume"~(mm^3)),
         names =c("ACA","Medial Lenticulostriate"))

# breakdown of MCA territory
boxplot(data$LLSL+data$LLSR,data$MCAFL+data$MCAFR,
        data$MCAPL+data$MCAPR,data$MCATL+data$MCAOR,
        data$MCAOL+data$MCAOR.1,data$MCAIL+data$MCAIR,
         main = "Subdivisions of the Middle Territory",
         ylab = bquote("PVS Volume"~(mm^3)),
         names =c("LLS","Frontal Pars","Parietal Pars","Temporal Pars","Occipital Pars","Insular Pars"),
        cex.axis=0.7)
       

#mca_df <- subset(data, select=c('LLS_pvs_vol','MCAF_pvs_vol','MCAP_pvs_vol'))
#mca_df <- melt(data)
# creating the modified dataframe
#data_mod < - melt(data_frame, id.vars='eid', 
#                  measure.vars=c('col2', 'col3', 'col4'))


subset_data <- data[c("ACA_pvs_vol","LLS_pvs_vol","MCAF_pvs_vol","MCAP_pvs_vol",'MCAT_pvs_vol','MCA0_pvs_vol')]
meltData <- melt(subset_data)
boxplot(data=meltData, value~variable)
#coudl i also use gather?
#https://www.statology.org/gather-function-in-r/

#p <- ggplot(meltData, aes(factor(variable), value)) 
#p + geom_boxplot() + facet_wrap(~variable, scale="free")

# Violin basic
meltData %>%
  ggplot( aes(factor(variable), value, fill=variable)) +
    geom_violin() +
    scale_fill_viridis(discrete = TRUE, alpha=0.6, option="A") +
    #theme_ipsum() +
    theme(
      legend.position="none",
      plot.title = element_text(size=14,hjust=0.5),
      text = element_text(size = 11)
    ) +
    ggtitle("PVS Volumes within Vascular Sub-Divisions") +
  scale_x_discrete(breaks=c("ACA_pvs_vol","LLS_pvs_vol","MCAF_pvs_vol",'MCAP_pvs_vol','MCAT_pvs_vol','MCA0_pvs_vol'),
                   labels=c("ACA", "LLS", "MCAF",'MCAP','MCAT','MCAO'))+
  #geom_jitter(color="black", size=0.01, alpha=0.1) ++
  ylab(bquote("PVS Volume"~(mm^3))) + xlab("")



# Focus on the ACA in anteiror territory
#data$ACAL+data$ACAR
# Focus on LL, Frontal pars and parietal pars in Middle territory
#data$LLSL+data$LLSR, data$MCAFL+data$MCAFR, data$MCAPL+data$MCAPR

Assocaitions with confounds

gamlj::gamljGlm( formula = LLSL ~ sex + age_at_scan + height + weight + I(age_at_scan^2) + height:age_at_scan + weight:age_at_scan, data = data, plotHAxis = age_at_scan, plotSepLines = weight, scaling=c(age_at_scan = “none”, height = “centered”, weight = “centered”))

modelling


# same with lm as glm
#model_break1 <- lm(pvs_vol_mm3 ~ age_at_scan + I(age_at_scan^2) + sex + sleep_duration_sr , data=data)

model <- lm(pvs_vol_mm3 ~ ns(age_at_scan,3) + sex + ns(pollution_score,3) +
              overall_health_rating + 
              overall_health_rating:age_at_scan +
              alcohol_frequency+ns(townsend_deprivation_index,1)+
              freq_depressed_twoweeks+ns(height,3)+ns(weight,1)+# ns(BMI,1)+
              diagnosed_diabetes+diagnosed_diabetes:age_at_scan+
              insomnia_sr+insomnia_sr:age_at_scan+snoring_sr+snoring_sr:age_at_scan+
              avg_total_household_income+ipaq_activity_group,data=data)
#INCLUDE GRAPH
age_vol <- ggpredict(model, terms=c('age_at_scan [all]','sex'))
age_vol$group <- str_replace(age_vol$group, "0", "Female")
age_vol$group <- str_replace(age_vol$group, "1", "Male")
age_plot <- plot(age_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

#INCLUDE GRAPH
height_vol <- ggpredict(model, terms=c('height [all]'))
height_plot <- plot(height_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Height (cm)")+ theme(text = element_text(size = 15))
#INCLUDE GRAPH
weight_vol <- ggpredict(model, terms=c('weight [all]'))
weight_plot <- plot(weight_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Weight (kg)")+ theme(text = element_text(size = 15))

#bmi_vol <- ggpredict(model, terms=c('BMI [all]'))
#bmi_plot <- plot(bmi_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
#  labs(y= bquote("PVS Volume"~(mm^3)), x =bquote("BMI"~(kg^2/m)))+ theme(text = element_text(size = 15))

#INCLUDE GRAPH
alco_vol <- ggpredict(model, terms=c('alcohol_frequency'))
#alco_vol$group <- str_replace_all(alco_vol$x, c(`0`="`Never`",`1`='`"0-1 per Month"`',`3`='`"2-3 per Week"`',`4`='`"4+ per Week"`',`2`='`"2-4 per Month"`'))

alco_vol$x <- recode_factor(alco_vol$x, `0` = "Never", 
                                `1` = "0-1 per Month", `2`='2-4 per Month',`3`='2-3 per Week',`4`='4+ per Week')

alco_plot <- plot(alco_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=FALSE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x ='Frequency of Alcohol Consumption')+ theme(text = element_text(size = 15))

#INCLUDE GRAPH
ipaq_vol <- ggpredict(model, terms=c('ipaq_activity_group'))
ipaq_plot <- plot(ipaq_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "IPAQ Activity Group")+ theme(text = element_text(size = 15))

insom_vol <- ggpredict(model, terms=c("age_at_scan [all]",'insomnia_sr'))
insom_plot <- plot(insom_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "age")+ theme(text = element_text(size = 15))

depres_vol <- ggpredict(model, terms=c("age_at_scan [all]",'freq_depressed_twoweeks'))
depres_plot <- plot(depres_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "age")+ theme(text = element_text(size = 15))

heath_vol <- ggpredict(model, terms=c("age_at_scan [all]",'overall_health_rating'))
health_plot <- plot(heath_vol, ci=FALSE,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "age")+ theme(text = element_text(size = 15))

diab_vol <- ggpredict(model, terms=c("age_at_scan [all]",'diagnosed_diabetes'))
diab_plot <- plot(diab_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "age")+ theme(text = element_text(size = 15))

income_vol <- ggpredict(model, terms=c('avg_total_household_income'))
income_plot <- plot(income_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "income group")+ theme(text = element_text(size = 15))

ipaq_vol <- ggpredict(model, terms=c("age_at_scan [all]",'ipaq_activity_group'))
ipaq_plot <- plot(ipaq_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))
income_vol <- ggpredict(model, terms=c("age_at_scan [all]",'avg_total_household_income'))
income_plot <- plot(income_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

#results:
#age2,sex,poll^2,daily alcohol^1,freq_depressed_twoweeks,height^3,weight^, diabetea,insomina^, age:diabetes
# not sig: health rating,twonsend,sleep duration, snoring, income, geeting up in mroonig, ipaq, 
# not sig interctions with age: mornnig get up, income, ipaq, insomnia, snoring, health rating

#####clu
##model_clu <- lm(pvs_clusters ~ ns(age_at_scan,3) + sex + ns(pollution_score,3) + 
##              overall_health_rating + 
##              overall_health_rating:age_at_scan +
##              ns(typical_daily_alcohol,3)+ns(townsend_deprivation_index,1)+
##              freq_depressed_twoweeks+ns(height,3)+ns(weight,1)+#ns(BMI,3)+
##              diagnosed_diabetes+diagnosed_diabetes:age_at_scan+
##              insomnia_sr+insomnia_sr:age_at_scan+snoring_sr+
##              avg_total_household_income+
##              ipaq_activity_group,data=data)
# not sig:sleep dur, health rating, alcohol (contradict), townsend, snoring, income
#sig: diabetes, age, insomnia (contradict), getting up^, 
# sig interaction with age: getting up^(cont vol), insomnia (contradict vol), diabetes



model_aca <- lm(ACA_pvs_vol ~ ns(age_at_scan,3) + sex + sex:age_at_scan + ns(pollution_score,3) + 
              ns(sleep_duration_sr,1) + overall_health_rating + 
              overall_health_rating:age_at_scan + ns(hrs, 1) + 
              ns(typical_daily_alcohol,1)+ns(townsend_deprivation_index,1)+
              freq_depressed_twoweeks+ns(height,3)+ns(weight,1)+#ns(BMI,3)+
              diagnosed_diabetes+diagnosed_diabetes:age_at_scan+
              insomnia_sr+insomnia_sr:age_at_scan+snoring_sr+snoring_sr:age_at_scan+
              avg_total_household_income+avg_total_household_income:age_at_scan+
              difficulty_getting_up_morning+difficulty_getting_up_morning:age_at_scan,data=data)

model_lls <- lm(LLS_pvs_vol ~ ns(age_at_scan,3) + sex + sex:age_at_scan + ns(pollution_score,3) + 
              ns(sleep_duration_sr,1) + overall_health_rating + 
              overall_health_rating:age_at_scan + ns(hrs, 1) + 
              ns(typical_daily_alcohol,1)+ns(townsend_deprivation_index,1)+
              freq_depressed_twoweeks+ns(height,3)+ns(weight,1)+#ns(BMI,3)+
              diagnosed_diabetes+diagnosed_diabetes:age_at_scan+
              insomnia_sr+insomnia_sr:age_at_scan+snoring_sr+snoring_sr:age_at_scan+
              avg_total_household_income+avg_total_household_income:age_at_scan+
              difficulty_getting_up_morning+difficulty_getting_up_morning:age_at_scan,data=data)

#without colineraities between time of day, age, insominia, difficulty getting up, typica daily alcohol, weight
model_hrs_vol<- lm(pvs_vol_mm3 ~ sex +
              ns(sleep_duration_sr,2) + ns(hrs, 2) +sex:sleep_duration_sr,data=data)
summary(model_hrs_vol)

Call:
lm(formula = pvs_vol_mm3 ~ sex + ns(sleep_duration_sr, 2) + ns(hrs, 
    2) + sex:sleep_duration_sr, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-2412.1  -893.4  -281.7   600.4  8223.4 

Coefficients: (1 not defined because of singularities)
                          Estimate Std. Error t value Pr(>|t|)    
(Intercept)                2085.72     123.93  16.829  < 2e-16 ***
sex1                        201.30     109.00   1.847  0.06478 .  
ns(sleep_duration_sr, 2)1   609.78     189.06   3.225  0.00126 ** 
ns(sleep_duration_sr, 2)2  -172.89     169.99  -1.017  0.30915    
ns(hrs, 2)1                 218.13      47.06   4.635 3.58e-06 ***
ns(hrs, 2)2                 -67.22      30.62  -2.195  0.02816 *  
sex0:sleep_duration_sr      -36.69      15.08  -2.434  0.01496 *  
sex1:sleep_duration_sr          NA         NA      NA       NA    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1267 on 31173 degrees of freedom
  (70 observations deleted due to missingness)
Multiple R-squared:  0.03305,   Adjusted R-squared:  0.03286 
F-statistic: 177.6 on 6 and 31173 DF,  p-value: < 2.2e-16
sleep_vol <- ggpredict(model_hrs_vol, terms=c("sleep_duration_sr [all]",'sex'))
Warning: prediction from a rank-deficient fit may be misleading
sleep_plot <- plot(sleep_vol, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Sleep Duration (Hours)")+ theme(text = element_text(size = 15))

model_alco_vol<- lm(pvs_vol_mm3 ~ sex + ns(age_at_scan,3)+ns(typical_daily_alcohol,1)+typical_daily_alcohol:age_at_scan,data=data)
summary(model_alco_vol)

Call:
lm(formula = pvs_vol_mm3 ~ sex + ns(age_at_scan, 3) + ns(typical_daily_alcohol, 
    1) + typical_daily_alcohol:age_at_scan, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-2515.1  -859.6  -270.8   574.1  8280.2 

Coefficients: (1 not defined because of singularities)
                                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)                         922.377    247.689   3.724 0.000197 ***
sex1                                413.066     18.712  22.075  < 2e-16 ***
ns(age_at_scan, 3)1                 832.775     83.234  10.005  < 2e-16 ***
ns(age_at_scan, 3)2                1495.096    212.267   7.043 1.94e-12 ***
ns(age_at_scan, 3)3                 481.330    131.136   3.670 0.000243 ***
ns(typical_daily_alcohol, 1)        806.890    366.054   2.204 0.027516 *  
typical_daily_alcohol1:age_at_scan    9.555      4.674   2.044 0.040944 *  
typical_daily_alcohol2:age_at_scan    7.609      3.602   2.112 0.034664 *  
typical_daily_alcohol3:age_at_scan    4.958      2.533   1.957 0.050309 .  
typical_daily_alcohol4:age_at_scan    3.143      1.559   2.016 0.043843 *  
typical_daily_alcohol5:age_at_scan       NA         NA      NA       NA    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1249 on 19340 degrees of freedom
  (11900 observations deleted due to missingness)
Multiple R-squared:  0.07539,   Adjusted R-squared:  0.07496 
F-statistic: 175.2 on 9 and 19340 DF,  p-value: < 2.2e-16
alco <- ggpredict(model_alco_vol, terms=c("age_at_scan [all]",'typical_daily_alcohol'))
Warning: prediction from a rank-deficient fit may be misleading
alco_plot <- plot(alco, ci=95,add.data=FALSE, show.title=FALSE,show.legend=TRUE)+
  labs(y= bquote("PVS Volume"~(mm^3)), x = "Age")+ theme(text = element_text(size = 15))


### plots
###vol <- ggpredict(model, terms=c("age_at_scan [all]"))
###vol_plot <- plot(vol,ci=95,add.data=FALSE,show.title=FALSE)+
###  labs(y= bquote("PVS Volume"~(mm^3)), x = "Age")+ theme(text = element_text(size = 15))

###time <- ggpredict(model, terms=c("hrs [all]"))
###time_plot <- plot(time,ci=95,add.data=FALSE,show.title=FALSE)+
###  labs(y= bquote("PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

# mean ci plots (dot plots with bar for each of the 4 health groups)
###dx_vol <- ggpredict(model, terms=c("overall_health_rating [all]"))
###dx_vol_plot <- plot(dx_vol,ci=95,add.data=FALSE,show.title=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453'))+
###  labs(y= bquote("PVS Volume"~(mm^3)), x = "Health Rating")+ theme(text = element_text(size = 15))+
###  geom_line(aes(group = "overall_health_rating"), linetype = "dashed")

# mean ci plots (dot plots with bar for each of the pollution)
###pollution_pred <- ggpredict(model, terms=c("pollution_score"))
###pollution_plot <- plot(pollution_pred,ci=95,add.data=FALSE,show.title=FALSE)+
###  labs(y= bquote("PVS Volume"~(mm^3)), x = "Pollution Level")+ theme(text = element_text(size = 15))+
###  geom_line(aes(group = "pollution_score"), linetype = "dashed")


model1 <- glm(ACA_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)
model2 <- glm(LLS_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)
model3 <- glm(MCAF_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)
model4 <- glm(MCAP_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)

summary(model1)

Call:
glm(formula = ACA_pvs_vol ~ age_at_scan + I(age_at_scan^2) + 
    sex, data = data)

Deviance Residuals: 
   Min      1Q  Median      3Q     Max  
-989.8  -362.4  -114.7   245.0  3297.9  

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)      -2.193e+03  1.972e+02 -11.125   <2e-16 ***
age_at_scan       7.626e+01  6.144e+00  12.413   <2e-16 ***
I(age_at_scan^2) -4.717e-01  4.742e-02  -9.948   <2e-16 ***
sex1              1.246e+02  5.841e+00  21.329   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 263121)

    Null deviance: 8830994910  on 31249  degrees of freedom
Residual deviance: 8221477571  on 31246  degrees of freedom
AIC: 478701

Number of Fisher Scoring iterations: 2
summary(model2)

Call:
glm(formula = LLS_pvs_vol ~ age_at_scan + I(age_at_scan^2) + 
    sex, data = data)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-489.72   -92.36   -10.46    80.39   919.65  

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)      669.84587   52.34623  12.796  < 2e-16 ***
age_at_scan       -4.62955    1.63122  -2.838  0.00454 ** 
I(age_at_scan^2)   0.03304    0.01259   2.625  0.00868 ** 
sex1              45.19143    1.55088  29.139  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 18547.86)

    Null deviance: 595572578  on 31249  degrees of freedom
Residual deviance: 579546427  on 31246  degrees of freedom
AIC: 395818

Number of Fisher Scoring iterations: 2
summary(model3)

Call:
glm(formula = MCAF_pvs_vol ~ age_at_scan + I(age_at_scan^2) + 
    sex, data = data)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-459.19  -181.68   -66.59   111.82  2049.99  

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)      -1148.3412   102.7209 -11.179   <2e-16 ***
age_at_scan         38.3972     3.2010  11.995   <2e-16 ***
I(age_at_scan^2)    -0.2405     0.0247  -9.737   <2e-16 ***
sex1                76.2932     3.0434  25.069   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 71423.46)

    Null deviance: 2391628056  on 31249  degrees of freedom
Residual deviance: 2231697452  on 31246  degrees of freedom
AIC: 437952

Number of Fisher Scoring iterations: 2
summary(model4)

Call:
glm(formula = MCAP_pvs_vol ~ age_at_scan + I(age_at_scan^2) + 
    sex, data = data)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-596.38  -226.84   -67.02   157.12  2363.68  

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)      -1.762e+03  1.223e+02  -14.41   <2e-16 ***
age_at_scan       6.526e+01  3.812e+00   17.12   <2e-16 ***
I(age_at_scan^2) -4.696e-01  2.942e-02  -15.96   <2e-16 ***
sex1              9.652e+01  3.624e+00   26.63   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 101265.3)

    Null deviance: 3306020500  on 31249  degrees of freedom
Residual deviance: 3164136448  on 31246  degrees of freedom
AIC: 448862

Number of Fisher Scoring iterations: 2
mod_vol <- lm(pvs_vol_mm3 ~ ns(age_at_scan, 3), data = data)
mod_aca <- lm(ACA_pvs_vol ~ ns(age_at_scan, 3), data = data)
mod_lls <- lm(LLS_pvs_vol ~ ns(age_at_scan, 3), data = data)
mod_mcaf <- lm(MCAF_pvs_vol ~ ns(age_at_scan, 3), data = data)
mod_mcap <- lm(MCAP_pvs_vol ~ ns(age_at_scan, 3), data = data)


grid <- data %>% 
  data_grid(age_at_scan = seq_range(age_at_scan, n = 50, expand = 0.1)) %>% 
  gather_predictions(mod_vol,mod_aca,mod_lls,mod_mcaf,mod_mcap)#, .pred = "pvs_vol_mm3")
Error in data_grid(., age_at_scan = seq_range(age_at_scan, n = 50, expand = 0.1)) : 
  unused argument (age_at_scan = seq_range(age_at_scan, n = 50, expand = 0.1))

# i hate r
# the errors dont fking make sense
model1 <- glm(ACA_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)
model2 <- glm(LLS_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)
model3 <- glm(MCAF_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)
model4 <- glm(MCAP_pvs_vol ~ age_at_scan + I(age_at_scan^2) + sex, data=data)

summary(model1)
summary(model2)
summary(model3)
summary(model4)

mod_vol <- lm(pvs_vol_mm3 ~ ns(age_at_scan, 3), data = data)
mod_aca <- lm(ACA_pvs_vol ~ ns(age_at_scan, 3), data = data)
mod_lls <- lm(LLS_pvs_vol ~ ns(age_at_scan, 3), data = data)
mod_mcaf <- lm(MCAF_pvs_vol ~ ns(age_at_scan, 3), data = data)
mod_mcap <- lm(MCAP_pvs_vol ~ ns(age_at_scan, 3), data = data)

grid <- data %>% 
  data_grid(age_at_scan = seq_range(age_at_scan, n = 50, expand = 0.1)) %>% 
  gather_predictions(mod_vol,mod_aca,mod_lls,mod_mcaf,mod_mcap, .pred = "pvs_vol_mm3")

ggplot(data, aes(age_at_scan, pred)) + 
  #geom_point() +
  #geom_line(data = subset(grid,model=="mod_vol"),colour = "red") +
  geom_line(data = subset(grid,model=="mod_aca"),colour = "blue")+
  #geom_line(data = subset(grid,model=="mod_lls"),colour = "purple")+
  geom_line(data = subset(grid,model=="mod_mcaf"),colour = "green")+
  geom_line(data = subset(grid,model=="mod_mcap"),colour = "orange")# +
  #facet_wrap(~ model)
ggplot(data, aes(age_at_scan, pred)) + 
  geom_line(data = subset(grid,model=="mod_lls"),colour = "purple")

LLS Model and Plots Below


lls_model <- lm(LLS_pvs_vol ~ ns(age_at_scan,2) + sex + ns(pollution_score,3) + 
              ns(sleep_duration_sr,1) + overall_health_rating + 
              overall_health_rating:age_at_scan + ns(hrs, 1) + overall_health_rating:hrs + 
                sleep_duration_sr:hrs + diagnosed_diabetes + diagnosed_diabetes:age_at_scan, data=data)

lls_vol <- ggpredict(lls_model, terms=c("age_at_scan [all]"))
lls_vol_plot <- plot(lls_vol,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Age")+ theme(text = element_text(size = 15))

lls_time <- ggpredict(lls_model, terms=c("hrs [all]"))
lls_time_plot <- plot(lls_time,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

# mean ci plots (dot plots with bar for each of the 4 health groups)
lls_dx_vol <- ggpredict(lls_model, terms=c("overall_health_rating [all]"))
lls_dx_vol_plot <- plot(lls_dx_vol,ci=95,add.data=FALSE,show.title=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453'))+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Health Rating")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "overall_health_rating"), linetype = "dashed")

# mean ci plots (dot plots with bar for each of the pollution)
lls_pollution_pred <- ggpredict(lls_model, terms=c("pollution_score"))
lls_pollution_plot <- plot(lls_pollution_pred,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Pollution Level")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "pollution_score"), linetype = "dashed")


# over time plots
lls_prediction_a_vol <- ggpredict(lls_model, terms=c("age_at_scan [all]","overall_health_rating"))
lls_prediction_a_vol_plot<-plot(lls_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))


lls_prediction_time_vol <- ggpredict(lls_model, terms=c("hrs [all]","overall_health_rating"))
lls_prediction_time_vol_plot<-plot(lls_prediction_time_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=FALSE,show.title=FALSE)+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

lls_sleep <- ggpredict(lls_model, terms=c("hrs [all]","sleep_duration_sr"))
lls_prediction_sleep_vol_plot<-plot(lls_sleep,ci=TRUE,add.data=FALSE,line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Time")+ theme(text = element_text(size = 15))


# same as before.... lls plot against health rating
# no inflection point as i saw in jamovi
simple_lls_model <- lm(LLS_pvs_vol ~ ns(age_at_scan,2) + overall_health_rating + overall_health_rating:age_at_scan, data=data)

simp_lls_prediction_a_vol <- ggpredict(simple_lls_model, terms=c("age_at_scan [all]","overall_health_rating"))
simp_lls_prediction_a_vol_plot <-plot(simp_lls_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453','pink'),
                                       line.size=1.2,show.legend=FALSE,show.title=FALSE)+
                                    labs(y= bquote("LLS PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

# look at left only
left_lls_model <- lm(LLSL ~ ns(age_at_scan,2) + overall_health_rating + 
                       overall_health_rating:age_at_scan +sex+ 
                       diagnosed_diabetes + diagnosed_diabetes:age_at_scan, data=data)

left_lls_prediction_a_vol <- ggpredict(left_lls_model, terms=c("age_at_scan [all]","overall_health_rating"))
left_lls_prediction_a_vol_plot <-plot(left_lls_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453','pink'),
                                       line.size=1.2,show.legend=FALSE,show.title=FALSE)+
                                    labs(y= bquote("Left LLS PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

# look at right only
right_lls_model <- lm(LLSR ~ ns(age_at_scan,2) + overall_health_rating + 
                        overall_health_rating:age_at_scan +sex+ 
                        diagnosed_diabetes + diagnosed_diabetes:age_at_scan, data=data)

right_lls_prediction_a_vol <- ggpredict(right_lls_model, terms=c("age_at_scan [all]","overall_health_rating"))
right_lls_prediction_a_vol_plot <-plot(right_lls_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453','pink'),
                                       line.size=1.2,show.legend=FALSE,show.title=FALSE)+
                                    labs(y= bquote("Right LLS PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))


# LLS and diabetes

llls_pred_agediab <- ggpredict(left_lls_model, terms=c("age_at_scan [all]","diagnosed_diabetes"))
left_lls_pred_a_diab_vol_plot <-plot(llls_pred_agediab,ci=TRUE,add.data=FALSE,
                                       line.size=1.2,show.legend=TRUE,show.title=FALSE,colors=c('blue','red'))+
                                    labs(y= bquote("Left LLS PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

rlls_pred_agediab <- ggpredict(right_lls_model, terms=c("age_at_scan [all]","diagnosed_diabetes"))
right_lls_pred_a_diab_vol_plot <-plot(rlls_pred_agediab,ci=TRUE,add.data=FALSE,
                                       line.size=1.2,show.legend=TRUE,show.title=FALSE,colors=c('blue','red'))+
                                    labs(y= bquote("Right LLS PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

Do the same shit but for the ACA

#data$ACA_pvs_vol <- data$ACAL+data$ACAR
aca_model <- lm(ACA_pvs_vol ~ ns(age_at_scan,2) + sex + ns(pollution_score,3) + 
              ns(sleep_duration_sr,3) + overall_health_rating + 
              overall_health_rating:age_at_scan + ns(hrs, 3) + overall_health_rating:hrs + 
                sleep_duration_sr:hrs + diagnosed_diabetes + diagnosed_diabetes:age_at_scan, data=data)

aca_vol <- ggpredict(aca_model, terms=c("age_at_scan [all]"))
aca_vol_plot <- plot(aca_vol,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Age")+ theme(text = element_text(size = 15))

aca_time <- ggpredict(aca_model, terms=c("hrs [all]"))
aca_time_plot <- plot(aca_time,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

# mean ci plots (dot plots with bar for each of the 4 health groups)
# only when it is converted to factors, when as continous numerilca, it's a line plot
aca_dx_vol <- ggpredict(aca_model, terms=c("overall_health_rating [all]"))
aca_dx_vol_plot <- plot(aca_dx_vol,ci=95,add.data=FALSE,show.title=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453'))+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Health Rating")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "overall_health_rating"), linetype = "dashed")

# mean ci plots (dot plots with bar for each of the pollution)
aca_pollution_pred <- ggpredict(aca_model, terms=c("pollution_score"))
aca_pollution_plot <- plot(aca_pollution_pred,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Pollution Level")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "pollution_score"), linetype = "dashed")


# over time plots
aca_prediction_a_vol <- ggpredict(aca_model, terms=c("age_at_scan [all]","overall_health_rating"))
aca_prediction_a_vol_plot<-plot(aca_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))


aca_prediction_time_vol <- ggpredict(aca_model, terms=c("hrs [all]","overall_health_rating"))
aca_prediction_time_vol_plot<-plot(aca_prediction_time_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=FALSE,show.title=FALSE)+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

aca_sleep <- ggpredict(aca_model, terms=c("hrs [all]","sleep_duration_sr"))
aca_prediction_sleep_vol_plot<-plot(aca_sleep,ci=TRUE,add.data=FALSE,line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Time")+ theme(text = element_text(size = 15))

aca_pred_agediab <- ggpredict(aca_model, terms=c("age_at_scan [all]","diagnosed_diabetes"))
aca_pred_a_diab_vol_plot <-plot(aca_pred_agediab,ci=TRUE,add.data=FALSE,
                                       line.size=1.2,show.legend=TRUE,show.title=FALSE,colors=c('blue','red'))+
                                    labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

# now left and right

laca_model <- lm(ACAL ~ ns(age_at_scan,2) + sex + ns(pollution_score,3) + 
              ns(sleep_duration_sr,3) + overall_health_rating + 
              overall_health_rating:age_at_scan + ns(hrs, 3) + overall_health_rating:hrs + 
                sleep_duration_sr:hrs + diagnosed_diabetes + diagnosed_diabetes:age_at_scan, data=data)

laca_vol <- ggpredict(laca_model, terms=c("age_at_scan [all]"))
laca_vol_plot <- plot(laca_vol,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Age")+ theme(text = element_text(size = 15))

laca_time <- ggpredict(laca_model, terms=c("hrs [all]"))
laca_time_plot <- plot(aca_time,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

# mean ci plots (dot plots with bar for each of the 4 health groups)
# only when it is converted to factors, when as continous numerilca, it's a line plot
laca_dx_vol <- ggpredict(laca_model, terms=c("overall_health_rating [all]"))
laca_dx_vol_plot <- plot(laca_dx_vol,ci=95,add.data=FALSE,show.title=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453'))+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Health Rating")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "overall_health_rating"), linetype = "dashed")

# mean ci plots (dot plots with bar for each of the pollution)
laca_pollution_pred <- ggpredict(laca_model, terms=c("pollution_score"))
laca_pollution_plot <- plot(laca_pollution_pred,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Pollution Level")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "pollution_score"), linetype = "dashed")


# over time plots
laca_prediction_a_vol <- ggpredict(laca_model, terms=c("age_at_scan [all]","overall_health_rating"))
laca_prediction_a_vol_plot<-plot(laca_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))


laca_prediction_time_vol <- ggpredict(laca_model, terms=c("hrs [all]","overall_health_rating"))
laca_prediction_time_vol_plot<-plot(laca_prediction_time_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=FALSE,show.title=FALSE)+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

laca_sleep <- ggpredict(laca_model, terms=c("hrs [all]","sleep_duration_sr"))
laca_prediction_sleep_vol_plot<-plot(laca_sleep,ci=TRUE,add.data=FALSE,line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("LACA PVS Volume"~(mm^3)), x = "Time")+ theme(text = element_text(size = 15))

laca_pred_agediab <- ggpredict(laca_model, terms=c("age_at_scan [all]","diagnosed_diabetes"))
laca_pred_a_diab_vol_plot <-plot(laca_pred_agediab,ci=TRUE,add.data=FALSE,
                                       line.size=1.2,show.legend=TRUE,show.title=FALSE,colors=c('blue','red'))+
                                    labs(y= bquote("ACA PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))


raca_model <- lm(ACAR ~ ns(age_at_scan,2) + sex + ns(pollution_score,3) + 
              ns(sleep_duration_sr,3) + overall_health_rating + 
              overall_health_rating:age_at_scan + ns(hrs, 3) + overall_health_rating:hrs + 
                sleep_duration_sr:hrs + diagnosed_diabetes + diagnosed_diabetes:age_at_scan, data=data)

raca_vol <- ggpredict(raca_model, terms=c("age_at_scan [all]"))
raca_vol_plot <- plot(raca_vol,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Age")+ theme(text = element_text(size = 15))

raca_time <- ggpredict(raca_model, terms=c("hrs [all]"))
raca_time_plot <- plot(raca_time,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

# mean ci plots (dot plots with bar for each of the 4 health groups)
# only when it is converted to factors, when as continous numerilca, it's a line plot
raca_dx_vol <- ggpredict(raca_model, terms=c("overall_health_rating [all]"))
raca_dx_vol_plot <- plot(raca_dx_vol,ci=95,add.data=FALSE,show.title=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453'))+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Health Rating")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "overall_health_rating"), linetype = "dashed")

# mean ci plots (dot plots with bar for each of the pollution)
raca_pollution_pred <- ggpredict(raca_model, terms=c("pollution_score"))
raca_pollution_plot <- plot(raca_pollution_pred,ci=95,add.data=FALSE,show.title=FALSE)+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Pollution Level")+ theme(text = element_text(size = 15))+
  geom_line(aes(group = "pollution_score"), linetype = "dashed")


# over time plots
raca_prediction_a_vol <- ggpredict(raca_model, terms=c("age_at_scan [all]","overall_health_rating"))
raca_prediction_a_vol_plot<-plot(raca_prediction_a_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))


raca_prediction_time_vol <- ggpredict(raca_model, terms=c("hrs [all]","overall_health_rating"))
raca_prediction_time_vol_plot<-plot(raca_prediction_time_vol,ci=TRUE,add.data=FALSE,colors=c("#79A6EA",'#A8A8A8','#E8B453', 'pink'),line.size =1.2,show.legend=FALSE,show.title=FALSE)+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Time of Scan")+ theme(text = element_text(size = 15))

raca_sleep <- ggpredict(raca_model, terms=c("hrs [all]","sleep_duration_sr"))
raca_prediction_sleep_vol_plot<-plot(raca_sleep,ci=TRUE,add.data=FALSE,line.size =1.2,show.legend=TRUE,show.title=FALSE)+
  labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Time")+ theme(text = element_text(size = 15))

raca_pred_agediab <- ggpredict(raca_model, terms=c("age_at_scan [all]","diagnosed_diabetes"))
raca_pred_a_diab_vol_plot <-plot(raca_pred_agediab,ci=TRUE,add.data=FALSE,
                                       line.size=1.2,show.legend=TRUE,show.title=FALSE,colors=c('blue','red'))+
                                    labs(y= bquote("RACA PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))
# plots the old way (honours project)
#pred_age_vol <- ggpredict(vol_lmm15, terms=c("Age [all]"))
#pred_age_vol_plot<-plot(pred_age_vol,ci=TRUE,add.data=TRUE, color ='blue',line.size =1,show.legend=FALSE,show.title=FALSE)+
#  labs(y= bquote("PVS Volume"~(mm^3)), x = "Age (years)")+ theme(text = element_text(size = 15))

# correlation plots

subset_data <- data[c("pvs_vol_mm3","pvs_clusters",'age_at_scan','sex',
                      "hip_circ","waist_circ","height","weight","BMI",
                      "pollution_score","townsend_deprivation_index","reason_ltfu",
                      "ipaq_activity_group","num_treatments_medications",
                      "overall_health_rating",
                      "avg_total_household_income",
                      "sleep_duration_sr","difficulty_getting_up_morning","chronotype","nap_during_day",
                      "insomnia_sr","snoring_sr", "narcolepsy_sr",
                      "seen_gp_anx_dep","freq_tiredness_twoweeks",
                      "freq_tension_twoweeks","freq_unenthusiam_twoweeks",
                      "freq_depressed_twoweeks","mood_swings",
                      
                      "miserable","irritable","fed_up",
                      "nervous","worrier_anxious","tension_highlystrung",
                      
                      "neuroticism_score",
                      "typical_daily_alcohol","alcohol_frequency",'hrs')]

subset_data <- sapply(subset_data, as.numeric)

my_cor <- cor(subset_data, use="complete.obs")
#subset_data <- lapply(subset_data,as.numeric)
corr_plot <- corrplot(my_cor, type = "upper", order = "hclust", 
         tl.col = "black", tl.srt = 45,
         tl.cex = 0.8)#number.cex = 0.5
#is.corr = FALSE, method = "square"

Didn’t work in the correlation plot “long_term_illness”,“weight_change_last_year”,“job_night_shift”,“job_shift_work”, “age_at_death”,###### ,“trouble_falling_asleep”,“oversleeping”, “diagnosed_diabetes”,“diagnosed_cancer”, “other_serious_condition”,“number_live_births” “contraceptive_pill_use”,“age_stroke”, “number_depression_episodes”,“seen_psych_anx_dep”,“sensitive_hurtfeelings”, “worry_after_embarressment”,“nerves”,“able_walk_cycle_tenmins”, “age_first_depression”,“age_last_depression”

“pollution_score”, “waist_circ”,“hip_circ”,“height”,“weight”,“BMI”,

“suburb”,“ethnicity”,

“ipaq_activity_group”,“num_treatments_medications”,“townsend_deprivation_index”, “reason_ltfu”,“date_ltfu”,

“overall_health_rating”,“long_term_illness”,“weight_change_last_year”, “avg_total_household_income”,“job_night_shift”,“job_shift_work”,

“age_at_death”,“age_stroke”,“number_depression_episodes”,

“sleep_duration_sr”,“difficulty_getting_up_morning”,“chronotype”,“nap_during_day” “insomnia_sr”,“snoring_sr”, “narcolepsy_sr”, “diagnosed_diabetes”,“diagnosed_cancer”, “other_serious_condition”,“number_live_births”. “contraceptive_pill_use”, “seen_psych_anx_dep”, “seen_gp_anx_dep”,“freq_tiredness_twoweeks”, “freq_tension_twoweeks”,“freq_unenthusiam_twoweeks”, “freq_depressed_twoweeks”,“mood_swings”, “miserable”,“irritable”, “sensitive_hurtfeelings”,“fed_up”, “nervous”,“worrier_anxious”, “tension_highlystrung”,“worry_after_embarressment”, “nerves”,“able_walk_cycle_tenmins”, “neuroticism_score”,“typical_daily_alcohol”, “alcohol_frequency”,“age_first_depression”, “age_last_depression”,“trouble_falling_asleep”, “oversleeping”,

“time”,“year”,“month”, “day”,“hrs”, “mnths”,“pollution_score”,“season”

time_of_scan
age_at_death
age_stroke

sleep_duration_sr
insomnia_sr
nap_during_day
snoring_sr
narcolepsy_sr

overall_health_rating
long_term_illness
diagnosed_diabetes

BMI
height
weight
waist_circ
hip_circ

Associations with disease

gamlj::gamljGlm( formula = LLSL ~ sex + age_at_scan + overall_health_rating + I(age_at_scan^2) + overall_health_rating:age_at_scan, data = data, plotHAxis = age_at_scan, plotSepLines = overall_health_rating, scaling=c(age_at_scan = “none”, sleep_duration_sr = “none”, overall_health_rating = “centered”, typical_daily_alcohol = “centered”, diagnosed_diabetes = “centered”))

ukb startup code by Lachy

Create Core Dataset

# packages

library(dplyr)
library(readr)
library(purrr)
library(tidyr)

# read UKB data

d <- readRDS("/home/lcri0006/bc41_scratch/UKB_data/ukb51956.rds")

# read data dictionary
# dict has "Field_id", "New_name", 'coding_units', 'Detail'
datadict <- read_csv("/home/lcri0006/bc41/core_ukb/core_data_dictionary.csv")


# select core variables

core <- d %>% 
  select(all_of(datadict$Field_id))

# rename variables 

names(core) <- datadict$New_name

# count missing 

map_df(core, ~sum(is.na(.))) %>% 
  pivot_longer(everything()) %>% 
  arrange(desc(value)) %>% 
  print(n = 150)

# save core dataset
write_csv(core, "/fs02/bc41/core_ukb/core_ukb.csv")

ukb Lachy code

cut ukb data

library(tidyverse)

# r formatted data storage
# tab delimited file
d <- readRDS("/home/lcri0006/bc41/UKB_data/ukb51956.rds")

# get bulk data ids
# mri ID's 

mri_id <- d %>% 
  select(eid, `20252-2.0`) %>% 
  filter(!is.na(`20252-2.0`))

write.table(mri_id, "/home/lcri0006/bc41/UKB_data/mri_id.txt",
            quote = F, col.names = F, row.names = F)

# Actigraphy ID's

acc_id <- d %>% 
  select(eid, `90001-0.0`) %>% 
  filter(!is.na(`90001-0.0`))

write.table(acc_id, "/home/lcri0006/bc41/UKB_data/accel_id.txt",
            quote = F, col.names = F, row.names = F)

# first 100 rows of actigraphy data (test)

test_acc <- acc_id %>% 
  slice(1:100)

write.table(test_acc, "/home/lcri0006/bc41/UKB_data/accel_test.txt",
            quote = F, col.names = F, row.names = F)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCg0KIyB1a2IgY29kZQ0KDQotLS0NCg0KRGVzY3JpcHRpdmUgU3RhdGlzdGljcw0KDQpIaXN0b2dyYW1zIG9mIHZvbHVtZXMgYW5kIGNsdXN0ZXJzDQoNCkJveHBsb3RzIHNpZWQgYnkgc2lkZSBvZiBsb2Jlcw0KDQpCb3hwbG90cyBzaWRlIGJ5IHNpZGUgb2YgdmFzY3VsYXIgdGVycml0b3JpZXMNCg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeShocmJydGhlbWVzKSNmb3IgdGhlIHZpb2xpbiBwbG90DQpsaWJyYXJ5KGxtZTQpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShzcGxpbmVzKQ0KbGlicmFyeShtb2RlbHIpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShnZ2VmZmVjdHMpI2dncHJlZGljdA0KI29wdGlvbnMobmEuYWN0aW9uID0gbmEud2FybikNCmxpYnJhcnkoZHBseXIpDQoNCmRhdGEgPC0gcmVhZC5jc3YoIkQ6XFxEcm9wYm94L1BoRC91a2IvY3Jvc3NfbWVyZ2VkX2xvYmVzLmNzdiIpDQoNCmRhdGEkZWlkIDwtIGFzLmZhY3RvcihkYXRhJGVpZCkNCmRhdGEkc2V4IDwtIGFzLmZhY3RvcihkYXRhJHNleCkNCg0KDQojIGRlc2NyaXB0aXZlcw0KZGF0YSRhZ2VfYXRfc2NhbiA8LWFzLm51bWVyaWMoZGF0YSRhZ2VfYXRfc2NhbikNCmRhdGEkcHZzX3ZvbF9tbTMgPC1hcy5udW1lcmljKGRhdGEkcHZzX3ZvbF9tbTMpDQpkYXRhJG92ZXJhbGxfaGVhbHRoX3JhdGluZyA8LWFzLm51bWVyaWMoZGF0YSRvdmVyYWxsX2hlYWx0aF9yYXRpbmcpDQpkYXRhJG92ZXJhbGxfaGVhbHRoX3JhdGluZyA8LSByZXBsYWNlKGRhdGEkb3ZlcmFsbF9oZWFsdGhfcmF0aW5nLCB3aGljaChkYXRhJG92ZXJhbGxfaGVhbHRoX3JhdGluZyA8IDEpLCBOQSkNCiNkYXRhJG92ZXJhbGxfaGVhbHRoX3JhdGluZyA8LSBmYWN0b3IoZGF0YSRvdmVyYWxsX2hlYWx0aF9yYXRpbmcsbGV2ZWxzPWMoMSwyLDMsNCksb3JkZXJlZD1UUlVFKQ0KZGF0YSRzZXggPC0gYXMuZmFjdG9yKGRhdGEkc2V4KQ0KZGF0YSRkaWFnbm9zZWRfZGlhYmV0ZXMgPC0gZmFjdG9yKGRhdGEkZGlhZ25vc2VkX2RpYWJldGVzLGMoMCwxKSkNCmRhdGEkc2V4IDwtIGZhY3RvcihkYXRhJHNleCxjKDAsMSkpDQoNCnN1bW1hcnkoZGF0YSRzZXgpDQpzdW1tYXJ5KGRhdGEkYWdlX2F0X3NjYW4pDQoNCmRhdGEkdHlwaWNhbF9kYWlseV9hbGNvaG9sIDwtIHJlcGxhY2UoZGF0YSR0eXBpY2FsX2RhaWx5X2FsY29ob2wsIHdoaWNoKGRhdGEkdHlwaWNhbF9kYWlseV9hbGNvaG9sIDwgMCksIE5BKQ0KZGF0YSR0eXBpY2FsX2RhaWx5X2FsY29ob2wgPC0gZmFjdG9yKGRhdGEkdHlwaWNhbF9kYWlseV9hbGNvaG9sLGMoMSwyLDMsNCw1KSkNCmRhdGEkYWxjb2hvbF9mcmVxdWVuY3kgPC0gcmVwbGFjZShkYXRhJGFsY29ob2xfZnJlcXVlbmN5LCB3aGljaChkYXRhJGFsY29ob2xfZnJlcXVlbmN5IDwgMCksIE5BKQ0KZGF0YSRhbGNvaG9sX2ZyZXF1ZW5jeSA8LSBmYWN0b3IoZGF0YSRhbGNvaG9sX2ZyZXF1ZW5jeSkNCg0Kc3VtbWFyeShkYXRhJGFsY29ob2xfZnJlcXVlbmN5KQ0KI2hpc3QoZGF0YSRhbGNvaG9sX2ZyZXF1ZW5jeSkNCg0KDQpkYXRhJHNsZWVwX2R1cmF0aW9uX3NyIDwtIHJlcGxhY2UoZGF0YSRzbGVlcF9kdXJhdGlvbl9zciwgd2hpY2goZGF0YSRzbGVlcF9kdXJhdGlvbl9zciA8IDApLCBOQSkNCnN1bW1hcnkoZGF0YSRzbGVlcF9kdXJhdGlvbl9zcikNCg0KDQpkYXRhJGZyZXFfZGVwcmVzc2VkX3R3b3dlZWtzIDwtIHJlcGxhY2UoZGF0YSRmcmVxX2RlcHJlc3NlZF90d293ZWVrcywgd2hpY2goZGF0YSRmcmVxX2RlcHJlc3NlZF90d293ZWVrcyA8IDApLCBOQSkNCg0Kc3VtbWFyeShkYXRhJGZyZXFfZGVwcmVzc2VkX3R3b3dlZWtzKQ0Kc3VtbWFyeShkYXRhJGhlaWdodCkNCnN1bW1hcnkoZGF0YSR3ZWlnaHQpDQpzdW1tYXJ5KGRhdGEkQk1JKQ0Kc3VtbWFyeShkYXRhJHRvd25zZW5kX2RlcHJpdmF0aW9uX2luZGV4KQ0KDQpkYXRhJHNub3Jpbmdfc3IgPC0gcmVwbGFjZShkYXRhJHNub3Jpbmdfc3IsIHdoaWNoKGRhdGEkc25vcmluZ19zciA8IDApLCBOQSkNCmRhdGEkaW5zb21uaWFfc3IgPC0gcmVwbGFjZShkYXRhJGluc29tbmlhX3NyLCB3aGljaChkYXRhJGluc29tbmlhX3NyIDwgMCksIE5BKQ0KZGF0YSRkaWZmaWN1bHR5X2dldHRpbmdfdXBfbW9ybmluZyA8LSByZXBsYWNlKGRhdGEkZGlmZmljdWx0eV9nZXR0aW5nX3VwX21vcm5pbmcsIHdoaWNoKGRhdGEkZGlmZmljdWx0eV9nZXR0aW5nX3VwX21vcm5pbmcgPCAwKSwgTkEpDQpkYXRhJGF2Z190b3RhbF9ob3VzZWhvbGRfaW5jb21lIDwtIHJlcGxhY2UoZGF0YSRhdmdfdG90YWxfaG91c2Vob2xkX2luY29tZSwgd2hpY2goZGF0YSRhdmdfdG90YWxfaG91c2Vob2xkX2luY29tZSA8IDApLCBOQSkNCg0Kc3VtbWFyeShkYXRhJHNub3Jpbmdfc3IpDQpzdW1tYXJ5KGRhdGEkaW5zb21uaWFfc3IpDQpzdW1tYXJ5KGRhdGEkZGlmZmljdWx0eV9nZXR0aW5nX3VwX21vcm5pbmcpDQpzdW1tYXJ5KGRhdGEkYXZnX3RvdGFsX2hvdXNlaG9sZF9pbmNvbWUpDQpzdW1tYXJ5KGRhdGEkaXBhcV9hY3Rpdml0eV9ncm91cCkNCg0KZGF0YSRzbm9yaW5nX3NyIDwtIGZhY3RvcihkYXRhJHNub3Jpbmdfc3IpDQpkYXRhJGluc29tbmlhX3NyIDwtIGZhY3RvcihkYXRhJGluc29tbmlhX3NyKQ0KZGF0YSRpcGFxX2FjdGl2aXR5X2dyb3VwIDwtIGZhY3RvcihkYXRhJGlwYXFfYWN0aXZpdHlfZ3JvdXApDQpkYXRhJGF2Z190b3RhbF9ob3VzZWhvbGRfaW5jb21lIDwtIGZhY3RvcihkYXRhJGF2Z190b3RhbF9ob3VzZWhvbGRfaW5jb21lKQ0KDQpzdW1tYXJ5KGRhdGEkYWdlX2F0X3NjYW4pDQpzdW1tYXJ5KGRhdGEkc2V4KQ0Kc3VtbWFyeShkYXRhJHB2c192b2xfbW0zKQ0Kc3VtbWFyeShkYXRhJHB2c19jbHVzdGVycykNCnN1bW1hcnkoZGF0YSRhZ2VfYXRfc2NhbikNCg0KIyBjcmVhdGUgbmV3IHZhcnMNCg0KZGF0YSRmcm9udF9wdnNfdm9sIDwtIGRhdGEkZnJvbnRhbF9yICsgZGF0YSRmcm9udGFsX2wNCmRhdGEkcGFyX3B2c192b2wgPC0gZGF0YSRwYXJpZXRhbF9yICsgZGF0YSRwYXJpZXRhbF9sDQpkYXRhJHRlbXBfcHZzX3ZvbCA8LSBkYXRhJHRlbXBvcmFsX3IgKyBkYXRhJHRlbXBvcmFsX2wNCmRhdGEkb2NjX3B2c192b2wgPC0gZGF0YSRvY2NpcGl0YWxfciArIGRhdGEkb2NjaXBpdGFsX2wNCmRhdGEkY2VyZWJlbF9wdnNfdm9sIDwtIGRhdGEkY2VyZWJlbGx1bV9yICsgZGF0YSRjZXJlYmVsbHVtX2wNCiNkYXRhJGJyYWluc3RlbQ0KDQpkYXRhJGFudGVyaW9yX3B2c192b2wgPC0gZGF0YSRBQ0FMICsgZGF0YSRBQ0FSICsgZGF0YSRNTFNMICsgZGF0YSRNTFNSDQpkYXRhJG1pZGRsZV9wdnNfdm9sIDwtIGRhdGEkTExTTCtkYXRhJExMU1IrZGF0YSRNQ0FGTCtkYXRhJE1DQUZSKw0KICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSRNQ0FQTCtkYXRhJE1DQVBSK2RhdGEkTUNBVEwrZGF0YSRNQ0FPUisNCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEkTUNBT0wrZGF0YSRNQ0FPUi4xK2RhdGEkTUNBSUwrZGF0YSRNQ0FJUg0KZGF0YSRwb3N0X3B2c192b2wgPC0gZGF0YSRQQ0FUTCtkYXRhJFBDQVRSK2RhdGEkUENBT0wrZGF0YSRQQ0FPUisNCiAgICAgICAgICAgICAgICAgICAgICBkYXRhJFBDVFBMK2RhdGEkUENUUFIrZGF0YSRBQ1RQTCtkYXRhJEFDVFBSDQpkYXRhJHZiX3B2c192b2wgPC0gZGF0YSRCTCtkYXRhJEJSK2RhdGEkU0NMK2RhdGEkU0NSK2RhdGEkSUNMK2RhdGEkSUNSDQpkYXRhJHZlbnRzX3B2c192b2wgPC0gZGF0YSRMVkwrZGF0YSRMVlINCg0KZGF0YSRBQ0FfcHZzX3ZvbCA8LSBkYXRhJEFDQUwrZGF0YSRBQ0FSDQpkYXRhJExMU19wdnNfdm9sIDwtIGRhdGEkTExTTCArIGRhdGEkTExTUg0KZGF0YSRNQ0FGX3B2c192b2wgPC0gZGF0YSRNQ0FGTCArIGRhdGEkTUNBRlINCmRhdGEkTUNBUF9wdnNfdm9sIDwtIGRhdGEkTUNBUEwgKyBkYXRhJE1DQVBSDQoNCmRhdGEkTUNBVF9wdnNfdm9sIDwtIGRhdGEkTUNBVEwrZGF0YSRNQ0FPUg0KZGF0YSRNQ0EwX3B2c192b2wgPC0gZGF0YSRNQ0FPTCtkYXRhJE1DQU9SLjENCg0KYGBgDQoNCg0KDQoNCg0KYGBge3J9DQojIGJveHBsb3RzDQojIGZvcm1hdCBhbmQgYWRkIGluIGRlc2NyaXB0aXZlIHZhcmlhYmxlczogbWVkaWFuLCBtZWFuLCBzZCwgbWluICwgbWF4DQpib3hwbG90KGRhdGEkcHZzX3ZvbF9tbTMsDQogICAgICAgICBtYWluID0gIkJveHBsb3RzIiwNCiAgICAgICAgIHlsYWIgPSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksDQogICAgICAgICB4bGFiID1jKCJQVlMgVm9sdW1lIikpDQoNCmJveHBsb3QoZGF0YSRwdnNfY2x1c3RlcnMsDQogICAgICAgICBtYWluID0gIkJveHBsb3RzIiwNCiAgICAgICAgIHlsYWIgPSBicXVvdGUoIlBWUyBDbHVzdGVycyIpLA0KICAgICAgICAgeGxhYiA9YygiUFZTIENsdXN0ZXJzIikpDQoNCiMgaGlzdG9ncmFtcw0Kdm9sX2RlbnNpdHkgPC0gaGlzdChkYXRhJHB2c192b2xfbW0zLGJyZWFrcz01MCxjb2w9IiM4N0NFRUIiLHhsYWI9YnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLG1haW49IiIsY2V4LmxhYj0xLjMpDQpjbHVfZGVuc2l0eSA8LSBoaXN0KGRhdGEkcHZzX2NsdXN0ZXJzLCBicmVha3M9NTAsIGNvbD0iIzg3Q0VFQiIseGxhYj0iUFZTIENsdXN0ZXJzIixtYWluPSIiLGNleC5sYWI9MS4zKQ0KDQpzdW1tYXJ5KGRhdGEkcHZzX3ZvbF9tbTMpDQpzdW1tYXJ5KGRhdGEkcHZzX2NsdXN0ZXJzKQ0KDQpgYGANCg0KYGBge3J9DQoNCg0KYm94cGxvdChkYXRhJGZyb250X3B2c192b2wsZGF0YSRwYXJfcHZzX3ZvbCxkYXRhJHRlbXBfcHZzX3ZvbCwNCiAgICAgICAgZGF0YSRvY2NfcHZzX3ZvbCxkYXRhJGNlcmViZWxfcHZzX3ZvbCwNCiAgICAgICAgIG1haW4gPSAiTG9iYXIgRGlzdHJpYnV0aW9ucyIsDQogICAgICAgICB5bGFiID0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLA0KICAgICAgICAgbmFtZXMgPWMoIkZyb250YWwiLCAiUGFyaWV0YWwiLCAiVGVtcG9yYWwiLCAiT2NjaXBpdGFsIExvYmUiLCJDZXJlYmVsbGFyIikpDQoNCiMgdmlvbGluIHBsb3QgZm9yIHdtIGxvYmVzDQpzdWJzZXRfZGF0YV9sb2JlcyA8LSBkYXRhW2MoImZyb250X3B2c192b2wiLCJwYXJfcHZzX3ZvbCIsInRlbXBfcHZzX3ZvbCIpXSMsIm9jY19wdnNfdm9sIiwiY2VyZWJlbF9wdnNfdm9sIildDQptZWx0RGF0YV9sb2JlcyA8LSBtZWx0KHN1YnNldF9kYXRhX2xvYmVzKQ0KYm94cGxvdChkYXRhPW1lbHREYXRhX2xvYmVzLCB2YWx1ZX52YXJpYWJsZSkNCg0KIyBWaW9saW4gYmFzaWMNCm1lbHREYXRhX2xvYmVzICU+JQ0KICBnZ3Bsb3QoIGFlcyhmYWN0b3IodmFyaWFibGUpLCB2YWx1ZSwgZmlsbD12YXJpYWJsZSksKSArDQogICAgZ2VvbV92aW9saW4oKSArDQogICAgc2NhbGVfZmlsbF92aXJpZGlzKGRpc2NyZXRlID0gVFJVRSwgYWxwaGE9MC42LCBvcHRpb249IkEiKSArDQogICAgI3RoZW1lX2lwc3VtKCkgKw0KICAgIHRoZW1lKA0KICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwNCiAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSxoanVzdD0wLjUpLA0KICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpDQogICAgICApICsNCiAgZ2d0aXRsZSgiVmlvbGluIGNoYXJ0IG9mIExvYmFyIERpc3RyaWJ1dGlvbnMiKSArIA0KICBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcz1jKCJmcm9udF9wdnNfdm9sIiwicGFyX3B2c192b2wiLCJ0ZW1wX3B2c192b2wiKSwNCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiRnJvbnRhbCIsICJQYXJpZXRhbCIsICJUZW1wb3JhbCIpKSArDQogIHlsYWIoYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpKSArIHhsYWIoIiIpDQogICNnZW9tX2ppdHRlcihjb2xvcj0iYmxhY2siLCBzaXplPTAuMDEsIGFscGhhPTAuMSkgKw0KICAgIA0KDQoNCmJveHBsb3QoZGF0YSRhbnRlcmlvcl9wdnNfdm9sLGRhdGEkbWlkZGxlX3B2c192b2wsZGF0YSRwb3N0X3B2c192b2wsDQogICAgICAgIGRhdGEkdmJfcHZzX3ZvbCxkYXRhJHZlbnRzX3B2c192b2wsDQogICAgICAgICBtYWluID0gIlBWUyBEaXN0cmlidXRpb24gYnkgVmFzY3VsYXIgVGVycml0b3J5IiwNCiAgICAgICAgIHlsYWIgPSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksDQogICAgICAgICBuYW1lcyA9YygiQUNBIiwgIk1DQSIsICJQQ0EiLCAiVkIiLCJMViIpKQ0KI1ZCPVZlcnRlYnJvLUJhc2lsYXINCiNMVj1MYXRlcmFsIFZlbnRyaWN1bGFyDQoNCiMgYnJlYWtkb3duIG9mIEFDQSAgdGVycml0b3J5DQpib3hwbG90KGRhdGEkQUNBTCtkYXRhJEFDQVIsZGF0YSRNTFNMK2RhdGEkTUxTUiwNCiAgICAgICAgIG1haW4gPSAiU3ViZGl2aXNpb25zIG9mIHRoZSBBbnRlcmlvciBUZXJyaXRvcnkiLA0KICAgICAgICAgeWxhYiA9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwNCiAgICAgICAgIG5hbWVzID1jKCJBQ0EiLCJNZWRpYWwgTGVudGljdWxvc3RyaWF0ZSIpKQ0KDQojIGJyZWFrZG93biBvZiBNQ0EgdGVycml0b3J5DQpib3hwbG90KGRhdGEkTExTTCtkYXRhJExMU1IsZGF0YSRNQ0FGTCtkYXRhJE1DQUZSLA0KICAgICAgICBkYXRhJE1DQVBMK2RhdGEkTUNBUFIsZGF0YSRNQ0FUTCtkYXRhJE1DQU9SLA0KICAgICAgICBkYXRhJE1DQU9MK2RhdGEkTUNBT1IuMSxkYXRhJE1DQUlMK2RhdGEkTUNBSVIsDQogICAgICAgICBtYWluID0gIlN1YmRpdmlzaW9ucyBvZiB0aGUgTWlkZGxlIFRlcnJpdG9yeSIsDQogICAgICAgICB5bGFiID0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLA0KICAgICAgICAgbmFtZXMgPWMoIkxMUyIsIkZyb250YWwgUGFycyIsIlBhcmlldGFsIFBhcnMiLCJUZW1wb3JhbCBQYXJzIiwiT2NjaXBpdGFsIFBhcnMiLCJJbnN1bGFyIFBhcnMiKSwNCiAgICAgICAgY2V4LmF4aXM9MC43KQ0KICAgICAgIA0KDQojbWNhX2RmIDwtIHN1YnNldChkYXRhLCBzZWxlY3Q9YygnTExTX3B2c192b2wnLCdNQ0FGX3B2c192b2wnLCdNQ0FQX3B2c192b2wnKSkNCiNtY2FfZGYgPC0gbWVsdChkYXRhKQ0KIyBjcmVhdGluZyB0aGUgbW9kaWZpZWQgZGF0YWZyYW1lDQojZGF0YV9tb2QgPCAtIG1lbHQoZGF0YV9mcmFtZSwgaWQudmFycz0nZWlkJywgDQojICAgICAgICAgICAgICAgICAgbWVhc3VyZS52YXJzPWMoJ2NvbDInLCAnY29sMycsICdjb2w0JykpDQoNCg0Kc3Vic2V0X2RhdGEgPC0gZGF0YVtjKCJBQ0FfcHZzX3ZvbCIsIkxMU19wdnNfdm9sIiwiTUNBRl9wdnNfdm9sIiwiTUNBUF9wdnNfdm9sIiwnTUNBVF9wdnNfdm9sJywnTUNBMF9wdnNfdm9sJyldDQptZWx0RGF0YSA8LSBtZWx0KHN1YnNldF9kYXRhKQ0KYm94cGxvdChkYXRhPW1lbHREYXRhLCB2YWx1ZX52YXJpYWJsZSkNCiNjb3VkbCBpIGFsc28gdXNlIGdhdGhlcj8NCiNodHRwczovL3d3dy5zdGF0b2xvZ3kub3JnL2dhdGhlci1mdW5jdGlvbi1pbi1yLw0KDQojcCA8LSBnZ3Bsb3QobWVsdERhdGEsIGFlcyhmYWN0b3IodmFyaWFibGUpLCB2YWx1ZSkpIA0KI3AgKyBnZW9tX2JveHBsb3QoKSArIGZhY2V0X3dyYXAofnZhcmlhYmxlLCBzY2FsZT0iZnJlZSIpDQoNCiMgVmlvbGluIGJhc2ljDQptZWx0RGF0YSAlPiUNCiAgZ2dwbG90KCBhZXMoZmFjdG9yKHZhcmlhYmxlKSwgdmFsdWUsIGZpbGw9dmFyaWFibGUpKSArDQogICAgZ2VvbV92aW9saW4oKSArDQogICAgc2NhbGVfZmlsbF92aXJpZGlzKGRpc2NyZXRlID0gVFJVRSwgYWxwaGE9MC42LCBvcHRpb249IkEiKSArDQogICAgI3RoZW1lX2lwc3VtKCkgKw0KICAgIHRoZW1lKA0KICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwNCiAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCxoanVzdD0wLjUpLA0KICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpDQogICAgKSArDQogICAgZ2d0aXRsZSgiUFZTIFZvbHVtZXMgd2l0aGluIFZhc2N1bGFyIFN1Yi1EaXZpc2lvbnMiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzPWMoIkFDQV9wdnNfdm9sIiwiTExTX3B2c192b2wiLCJNQ0FGX3B2c192b2wiLCdNQ0FQX3B2c192b2wnLCdNQ0FUX3B2c192b2wnLCdNQ0EwX3B2c192b2wnKSwNCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQUNBIiwgIkxMUyIsICJNQ0FGIiwnTUNBUCcsJ01DQVQnLCdNQ0FPJykpKw0KICAjZ2VvbV9qaXR0ZXIoY29sb3I9ImJsYWNrIiwgc2l6ZT0wLjAxLCBhbHBoYT0wLjEpICsrDQogIHlsYWIoYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpKSArIHhsYWIoIiIpDQoNCg0KDQojIEZvY3VzIG9uIHRoZSBBQ0EgaW4gYW50ZWlyb3IgdGVycml0b3J5DQojZGF0YSRBQ0FMK2RhdGEkQUNBUg0KIyBGb2N1cyBvbiBMTCwgRnJvbnRhbCBwYXJzIGFuZCBwYXJpZXRhbCBwYXJzIGluIE1pZGRsZSB0ZXJyaXRvcnkNCiNkYXRhJExMU0wrZGF0YSRMTFNSLCBkYXRhJE1DQUZMK2RhdGEkTUNBRlIsIGRhdGEkTUNBUEwrZGF0YSRNQ0FQUg0KDQoNCmBgYA0KDQoNCkFzc29jYWl0aW9ucyB3aXRoIGNvbmZvdW5kcw0KDQpnYW1sajo6Z2FtbGpHbG0oDQogICAgZm9ybXVsYSA9IExMU0wgfiBzZXggKyBhZ2VfYXRfc2NhbiArIGhlaWdodCArIHdlaWdodCArIEkoYWdlX2F0X3NjYW5eMikgKyBoZWlnaHQ6YWdlX2F0X3NjYW4gKyB3ZWlnaHQ6YWdlX2F0X3NjYW4sDQogICAgZGF0YSA9IGRhdGEsDQogICAgcGxvdEhBeGlzID0gYWdlX2F0X3NjYW4sDQogICAgcGxvdFNlcExpbmVzID0gd2VpZ2h0LA0KICAgIHNjYWxpbmc9YyhhZ2VfYXRfc2NhbiA9ICJub25lIiwgaGVpZ2h0ID0gImNlbnRlcmVkIiwgd2VpZ2h0ID0gImNlbnRlcmVkIikpDQoNCg0KbW9kZWxsaW5nDQpgYGB7cn0NCg0KIyBzYW1lIHdpdGggbG0gYXMgZ2xtDQojbW9kZWxfYnJlYWsxIDwtIGxtKHB2c192b2xfbW0zIH4gYWdlX2F0X3NjYW4gKyBJKGFnZV9hdF9zY2FuXjIpICsgc2V4ICsgc2xlZXBfZHVyYXRpb25fc3IgLCBkYXRhPWRhdGEpDQoNCm1vZGVsIDwtIGxtKHB2c192b2xfbW0zIH4gbnMoYWdlX2F0X3NjYW4sMykgKyBzZXggKyBucyhwb2xsdXRpb25fc2NvcmUsMykgKw0KICAgICAgICAgICAgICBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiAgICAgICAgICAgICAgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nOmFnZV9hdF9zY2FuICsNCiAgICAgICAgICAgICAgYWxjb2hvbF9mcmVxdWVuY3krbnModG93bnNlbmRfZGVwcml2YXRpb25faW5kZXgsMSkrDQogICAgICAgICAgICAgIGZyZXFfZGVwcmVzc2VkX3R3b3dlZWtzK25zKGhlaWdodCwzKStucyh3ZWlnaHQsMSkrIyBucyhCTUksMSkrDQogICAgICAgICAgICAgIGRpYWdub3NlZF9kaWFiZXRlcytkaWFnbm9zZWRfZGlhYmV0ZXM6YWdlX2F0X3NjYW4rDQogICAgICAgICAgICAgIGluc29tbmlhX3NyK2luc29tbmlhX3NyOmFnZV9hdF9zY2FuK3Nub3Jpbmdfc3Irc25vcmluZ19zcjphZ2VfYXRfc2NhbisNCiAgICAgICAgICAgICAgYXZnX3RvdGFsX2hvdXNlaG9sZF9pbmNvbWUraXBhcV9hY3Rpdml0eV9ncm91cCxkYXRhPWRhdGEpDQojSU5DTFVERSBHUkFQSA0KYWdlX3ZvbCA8LSBnZ3ByZWRpY3QobW9kZWwsIHRlcm1zPWMoJ2FnZV9hdF9zY2FuIFthbGxdJywnc2V4JykpDQphZ2Vfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGFnZV92b2wkZ3JvdXAsICIwIiwgIkZlbWFsZSIpDQphZ2Vfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGFnZV92b2wkZ3JvdXAsICIxIiwgIk1hbGUiKQ0KYWdlX3Bsb3QgPC0gcGxvdChhZ2Vfdm9sLCBjaT05NSxhZGQuZGF0YT1GQUxTRSwgc2hvdy50aXRsZT1GQUxTRSxzaG93LmxlZ2VuZD1UUlVFKSsNCiAgbGFicyh5PSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiQWdlICh5ZWFycykiLCBjb2xvcj0iU2V4IikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KI0lOQ0xVREUgR1JBUEgNCmhlaWdodF92b2wgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCdoZWlnaHQgW2FsbF0nKSkNCmhlaWdodF9wbG90IDwtIHBsb3QoaGVpZ2h0X3ZvbCwgY2k9OTUsYWRkLmRhdGE9RkFMU0UsIHNob3cudGl0bGU9RkFMU0Usc2hvdy5sZWdlbmQ9VFJVRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkhlaWdodCAoY20pIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCiNJTkNMVURFIEdSQVBIDQp3ZWlnaHRfdm9sIDwtIGdncHJlZGljdChtb2RlbCwgdGVybXM9Yygnd2VpZ2h0IFthbGxdJykpDQp3ZWlnaHRfcGxvdCA8LSBwbG90KHdlaWdodF92b2wsIGNpPTk1LGFkZC5kYXRhPUZBTFNFLCBzaG93LnRpdGxlPUZBTFNFLHNob3cubGVnZW5kPVRSVUUpKw0KICBsYWJzKHk9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJXZWlnaHQgKGtnKSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCiNibWlfdm9sIDwtIGdncHJlZGljdChtb2RlbCwgdGVybXM9YygnQk1JIFthbGxdJykpDQojYm1pX3Bsb3QgPC0gcGxvdChibWlfdm9sLCBjaT05NSxhZGQuZGF0YT1GQUxTRSwgc2hvdy50aXRsZT1GQUxTRSxzaG93LmxlZ2VuZD1UUlVFKSsNCiMgIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID1icXVvdGUoIkJNSSJ+KGtnXjIvbSkpKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQojSU5DTFVERSBHUkFQSA0KI2FsY29fdm9sIDwtIGdncHJlZGljdChtb2RlbCwgdGVybXM9YygnYWxjb2hvbF9mcmVxdWVuY3knKSkNCiNhbGNvX3ZvbCRncm91cCA8LSBzdHJfcmVwbGFjZV9hbGwoYWxjb192b2wkeCwgYyhgMGA9ImBOZXZlcmAiLGAxYD0nYCIwLTEgcGVyIE1vbnRoImAnLGAzYD0nYCIyLTMgcGVyIFdlZWsiYCcsYDRgPSdgIjQrIHBlciBXZWVrImAnLGAyYD0nYCIyLTQgcGVyIE1vbnRoImAnKSkNCg0KI2FsY29fdm9sJHggPC0gcmVjb2RlX2ZhY3RvcihhbGNvX3ZvbCR4LCBgMGAgPSAiTmV2ZXIiLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAxYCA9ICIwLTEgcGVyIE1vbnRoIiwgYDJgPScyLTQgcGVyIE1vbnRoJyxgM2A9JzItMyBwZXIgV2VlaycsYDRgPSc0KyBwZXIgV2VlaycpDQojIDwtIHBsb3QoYWxjb192b2wsIGNpPTk1LGFkZC5kYXRhPUZBTFNFLCBzaG93LnRpdGxlPUZBTFNFLHNob3cubGVnZW5kPUZBTFNFKSsNCiMgIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0nRnJlcXVlbmN5IG9mIEFsY29ob2wgQ29uc3VtcHRpb24nKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCmlwYXFfdm9sIDwtIGdncHJlZGljdChtb2RlbCwgdGVybXM9YygnaXBhcV9hY3Rpdml0eV9ncm91cCcpKQ0KaXBhcV92b2wkeCA8LSBzdHJfcmVwbGFjZV9hbGwoaXBhcV92b2wkeCwgYyhgMGA9Ikxvd2AiLGAxYD0nTW9kZXJhdGUnLGAyYD0nSGlnaCcpKQ0KDQppcGFxX3Bsb3QgPC0gcGxvdChpcGFxX3ZvbCwgY2k9OTUsYWRkLmRhdGE9RkFMU0UsIHNob3cudGl0bGU9RkFMU0Usc2hvdy5sZWdlbmQ9VFJVRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIklQQVEgQWN0aXZpdHkgR3JvdXAiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCmluc29tX3ZvbCA8LSBnZ3ByZWRpY3QobW9kZWwsIHRlcm1zPWMoImFnZV9hdF9zY2FuIFthbGxdIiwnaW5zb21uaWFfc3InKSkNCmluc29tX3Bsb3QgPC0gcGxvdChpbnNvbV92b2wsIGNpPTk1LGFkZC5kYXRhPUZBTFNFLCBzaG93LnRpdGxlPUZBTFNFLHNob3cubGVnZW5kPVRSVUUpKw0KICBsYWJzKHk9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJhZ2UiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KI0lOQ0xVREUgR1JBUEgNCmRlcHJlc192b2wgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsJ2ZyZXFfZGVwcmVzc2VkX3R3b3dlZWtzJykpDQpkZXByZXNfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlX2FsbChkZXByZXNfdm9sJGdyb3VwLCBjKGAxYD0iTm90IGF0IGFsbGAiLGAyYD0nU2V2ZXJhbCBEYXlzJyxgM2A9J01vcmUgdGhhbiBoYWxmIHRoZSBkYXlzJyxgNGA9J05lYXJseSBldmVyeSBkYXknKSkNCmRlcHJlc19wbG90IDwtIHBsb3QoZGVwcmVzX3ZvbCwgY2k9RkFMU0UsYWRkLmRhdGE9RkFMU0UsIHNob3cudGl0bGU9RkFMU0Usc2hvdy5sZWdlbmQ9VFJVRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gImFnZSIsY29sb3I9IkZyZXF1ZW5jeSBvZiBkZXByZXNzaW9uIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyMjWUVTDQoNCmhlYXRoX3ZvbCA8LSBnZ3ByZWRpY3QobW9kZWwsIHRlcm1zPWMoImFnZV9hdF9zY2FuIFthbGxdIiwnb3ZlcmFsbF9oZWFsdGhfcmF0aW5nJykpDQpoZWF0aF92b2wkZ3JvdXAgPC0gc3RyX3JlcGxhY2VfYWxsKGhlYXRoX3ZvbCRncm91cCwgYyhgMWA9IkV4Y2VsbGVudGAiLGAyYD0nR29vZCcsYDNgPSdGYWlyJyxgNGA9IlBvb3JgIikpDQpoZWFsdGhfcGxvdCA8LSBwbG90KGhlYXRoX3ZvbCwgY2k9RkFMU0UsYWRkLmRhdGE9RkFMU0UsIHNob3cudGl0bGU9RkFMU0Usc2hvdy5sZWdlbmQ9VFJVRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gImFnZSIsY29sb3I9Ik92ZXJhbGwgSGVhbHRoIFJhdGluZyIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmRpYWJfdm9sIDwtIGdncHJlZGljdChtb2RlbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iLCdkaWFnbm9zZWRfZGlhYmV0ZXMnKSkNCmRpYWJfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGRpYWJfdm9sJGdyb3VwLCAiMCIsICJObyIpDQpkaWFiX3ZvbCRncm91cCA8LSBzdHJfcmVwbGFjZShkaWFiX3ZvbCRncm91cCwgIjEiLCAiWWVzIikNCmRpYWJfcGxvdCA8LSBwbG90KGRpYWJfdm9sLCBjaT05NSxhZGQuZGF0YT1GQUxTRSwgc2hvdy50aXRsZT1GQUxTRSxzaG93LmxlZ2VuZD1UUlVFKSsNCiAgbGFicyh5PSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiYWdlIiwgY29sb3I9IkRpYWJldGVzIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQojIyMgZG9udCBib3RoZXINCmluY29tZV92b2wgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCdhdmdfdG90YWxfaG91c2Vob2xkX2luY29tZScpKQ0KaW5jb21lX3Bsb3QgPC0gcGxvdChpbmNvbWVfdm9sLCBjaT05NSxhZGQuZGF0YT1GQUxTRSwgc2hvdy50aXRsZT1GQUxTRSxzaG93LmxlZ2VuZD1UUlVFKSsNCiAgbGFicyh5PSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiQXZlcmFnZSBUb3RhbCBIb3VzZWhvbGQgSW5jb21lIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KaXBhcV92b2wgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsJ2lwYXFfYWN0aXZpdHlfZ3JvdXAnKSkNCmlwYXFfcGxvdCA8LSBwbG90KGlwYXFfdm9sLCBjaT05NSxhZGQuZGF0YT1GQUxTRSwgc2hvdy50aXRsZT1GQUxTRSxzaG93LmxlZ2VuZD1UUlVFKSsNCiAgbGFicyh5PSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiQWdlICh5ZWFycykiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCmluY29tZV92b2wgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsJ2F2Z190b3RhbF9ob3VzZWhvbGRfaW5jb21lJykpDQppbmNvbWVfcGxvdCA8LSBwbG90KGluY29tZV92b2wsIGNpPTk1LGFkZC5kYXRhPUZBTFNFLCBzaG93LnRpdGxlPUZBTFNFLHNob3cubGVnZW5kPVRSVUUpKw0KICBsYWJzKHk9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UgKHllYXJzKSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCiNyZXN1bHRzOg0KI2FnZTIsc2V4LHBvbGxeMixkYWlseSBhbGNvaG9sXjEsZnJlcV9kZXByZXNzZWRfdHdvd2Vla3MsaGVpZ2h0XjMsd2VpZ2h0XiwgZGlhYmV0ZWEsaW5zb21pbmFeLCBhZ2U6ZGlhYmV0ZXMNCiMgbm90IHNpZzogaGVhbHRoIHJhdGluZyx0d29uc2VuZCxzbGVlcCBkdXJhdGlvbiwgc25vcmluZywgaW5jb21lLCBnZWV0aW5nIHVwIGluIG1yb29uaWcsIGlwYXEsIA0KIyBub3Qgc2lnIGludGVyY3Rpb25zIHdpdGggYWdlOiBtb3JubmlnIGdldCB1cCwgaW5jb21lLCBpcGFxLCBpbnNvbW5pYSwgc25vcmluZywgaGVhbHRoIHJhdGluZw0KDQojIyMjI2NsdQ0KIyNtb2RlbF9jbHUgPC0gbG0ocHZzX2NsdXN0ZXJzIH4gbnMoYWdlX2F0X3NjYW4sMykgKyBzZXggKyBucyhwb2xsdXRpb25fc2NvcmUsMykgKyANCiMjICAgICAgICAgICAgICBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiMjICAgICAgICAgICAgICBvdmVyYWxsX2hlYWx0aF9yYXRpbmc6YWdlX2F0X3NjYW4gKw0KIyMgICAgICAgICAgICAgIG5zKHR5cGljYWxfZGFpbHlfYWxjb2hvbCwzKStucyh0b3duc2VuZF9kZXByaXZhdGlvbl9pbmRleCwxKSsNCiMjICAgICAgICAgICAgICBmcmVxX2RlcHJlc3NlZF90d293ZWVrcytucyhoZWlnaHQsMykrbnMod2VpZ2h0LDEpKyNucyhCTUksMykrDQojIyAgICAgICAgICAgICAgZGlhZ25vc2VkX2RpYWJldGVzK2RpYWdub3NlZF9kaWFiZXRlczphZ2VfYXRfc2NhbisNCiMjICAgICAgICAgICAgICBpbnNvbW5pYV9zcitpbnNvbW5pYV9zcjphZ2VfYXRfc2Nhbitzbm9yaW5nX3NyKw0KIyMgICAgICAgICAgICAgIGF2Z190b3RhbF9ob3VzZWhvbGRfaW5jb21lKw0KIyMgICAgICAgICAgICAgIGlwYXFfYWN0aXZpdHlfZ3JvdXAsZGF0YT1kYXRhKQ0KIyBub3Qgc2lnOnNsZWVwIGR1ciwgaGVhbHRoIHJhdGluZywgYWxjb2hvbCAoY29udHJhZGljdCksIHRvd25zZW5kLCBzbm9yaW5nLCBpbmNvbWUNCiNzaWc6IGRpYWJldGVzLCBhZ2UsIGluc29tbmlhIChjb250cmFkaWN0KSwgZ2V0dGluZyB1cF4sIA0KIyBzaWcgaW50ZXJhY3Rpb24gd2l0aCBhZ2U6IGdldHRpbmcgdXBeKGNvbnQgdm9sKSwgaW5zb21uaWEgKGNvbnRyYWRpY3Qgdm9sKSwgZGlhYmV0ZXMNCg0KDQoNCm1vZGVsX2FjYSA8LSBsbShBQ0FfcHZzX3ZvbCB+IG5zKGFnZV9hdF9zY2FuLDMpICsgc2V4ICsgc2V4OmFnZV9hdF9zY2FuICsgbnMocG9sbHV0aW9uX3Njb3JlLDMpICsgDQogICAgICAgICAgICAgIG5zKHNsZWVwX2R1cmF0aW9uX3NyLDEpICsgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nICsgDQogICAgICAgICAgICAgIG92ZXJhbGxfaGVhbHRoX3JhdGluZzphZ2VfYXRfc2NhbiArIG5zKGhycywgMSkgKyANCiAgICAgICAgICAgICAgbnModHlwaWNhbF9kYWlseV9hbGNvaG9sLDEpK25zKHRvd25zZW5kX2RlcHJpdmF0aW9uX2luZGV4LDEpKw0KICAgICAgICAgICAgICBmcmVxX2RlcHJlc3NlZF90d293ZWVrcytucyhoZWlnaHQsMykrbnMod2VpZ2h0LDEpKyNucyhCTUksMykrDQogICAgICAgICAgICAgIGRpYWdub3NlZF9kaWFiZXRlcytkaWFnbm9zZWRfZGlhYmV0ZXM6YWdlX2F0X3NjYW4rDQogICAgICAgICAgICAgIGluc29tbmlhX3NyK2luc29tbmlhX3NyOmFnZV9hdF9zY2FuK3Nub3Jpbmdfc3Irc25vcmluZ19zcjphZ2VfYXRfc2NhbisNCiAgICAgICAgICAgICAgYXZnX3RvdGFsX2hvdXNlaG9sZF9pbmNvbWUrYXZnX3RvdGFsX2hvdXNlaG9sZF9pbmNvbWU6YWdlX2F0X3NjYW4rDQogICAgICAgICAgICAgIGRpZmZpY3VsdHlfZ2V0dGluZ191cF9tb3JuaW5nK2RpZmZpY3VsdHlfZ2V0dGluZ191cF9tb3JuaW5nOmFnZV9hdF9zY2FuLGRhdGE9ZGF0YSkNCg0KbW9kZWxfbGxzIDwtIGxtKExMU19wdnNfdm9sIH4gbnMoYWdlX2F0X3NjYW4sMykgKyBzZXggKyBzZXg6YWdlX2F0X3NjYW4gKyBucyhwb2xsdXRpb25fc2NvcmUsMykgKyANCiAgICAgICAgICAgICAgbnMoc2xlZXBfZHVyYXRpb25fc3IsMSkgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiAgICAgICAgICAgICAgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nOmFnZV9hdF9zY2FuICsgbnMoaHJzLCAxKSArIA0KICAgICAgICAgICAgICBucyh0eXBpY2FsX2RhaWx5X2FsY29ob2wsMSkrbnModG93bnNlbmRfZGVwcml2YXRpb25faW5kZXgsMSkrDQogICAgICAgICAgICAgIGZyZXFfZGVwcmVzc2VkX3R3b3dlZWtzK25zKGhlaWdodCwzKStucyh3ZWlnaHQsMSkrI25zKEJNSSwzKSsNCiAgICAgICAgICAgICAgZGlhZ25vc2VkX2RpYWJldGVzK2RpYWdub3NlZF9kaWFiZXRlczphZ2VfYXRfc2NhbisNCiAgICAgICAgICAgICAgaW5zb21uaWFfc3IraW5zb21uaWFfc3I6YWdlX2F0X3NjYW4rc25vcmluZ19zcitzbm9yaW5nX3NyOmFnZV9hdF9zY2FuKw0KICAgICAgICAgICAgICBhdmdfdG90YWxfaG91c2Vob2xkX2luY29tZSthdmdfdG90YWxfaG91c2Vob2xkX2luY29tZTphZ2VfYXRfc2NhbisNCiAgICAgICAgICAgICAgZGlmZmljdWx0eV9nZXR0aW5nX3VwX21vcm5pbmcrZGlmZmljdWx0eV9nZXR0aW5nX3VwX21vcm5pbmc6YWdlX2F0X3NjYW4sZGF0YT1kYXRhKQ0KDQojd2l0aG91dCBjb2xpbmVyYWl0aWVzIGJldHdlZW4gdGltZSBvZiBkYXksIGFnZSwgaW5zb21pbmlhLCBkaWZmaWN1bHR5IGdldHRpbmcgdXAsIHR5cGljYSBkYWlseSBhbGNvaG9sLCB3ZWlnaHQNCm1vZGVsX2hyc192b2w8LSBsbShwdnNfdm9sX21tMyB+IHNleCArDQogICAgICAgICAgICAgIG5zKHNsZWVwX2R1cmF0aW9uX3NyLDIpICsgbnMoaHJzLCAyKSArc2V4OnNsZWVwX2R1cmF0aW9uX3NyLGRhdGE9ZGF0YSkNCnN1bW1hcnkobW9kZWxfaHJzX3ZvbCkNCg0Kc2xlZXBfdm9sIDwtIGdncHJlZGljdChtb2RlbF9ocnNfdm9sLCB0ZXJtcz1jKCJzbGVlcF9kdXJhdGlvbl9zciBbYWxsXSIsJ3NleCcpKQ0Kc2xlZXBfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlX2FsbChzbGVlcF92b2wkZ3JvdXAsIGMoYDBgPSJGZW1hbGUiLGAxYD0nTWFsZScpKQ0KDQpzbGVlcF9wbG90IDwtIHBsb3Qoc2xlZXBfdm9sLCBjaT05NSxhZGQuZGF0YT1GQUxTRSwgc2hvdy50aXRsZT1GQUxTRSxzaG93LmxlZ2VuZD1UUlVFKSsNCiAgbGFicyh5PSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiU2xlZXAgRHVyYXRpb24gKEhvdXJzKSIsIGNvbG9yPSJTZXgiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQptb2RlbF9hbGNvX3ZvbDwtIGxtKHB2c192b2xfbW0zIH4gc2V4ICsgbnMoYWdlX2F0X3NjYW4sMykrbnModHlwaWNhbF9kYWlseV9hbGNvaG9sLDEpK3R5cGljYWxfZGFpbHlfYWxjb2hvbDphZ2VfYXRfc2NhbixkYXRhPWRhdGEpDQpzdW1tYXJ5KG1vZGVsX2FsY29fdm9sKQ0KDQphbGNvIDwtIGdncHJlZGljdChtb2RlbF9hbGNvX3ZvbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iLCd0eXBpY2FsX2RhaWx5X2FsY29ob2wnKSkNCiNhbGNvJGdyb3VwIDwtIHN0cl9yZXBsYWNlX2FsbChhbGNvJGdyb3VwLCBjKCcxJz0iMSBvciAyIiwnMic9JzNvcjQnLCczJz0nNW9yNicsJzQnPSc3b3I5JywnNSc9JzEwKycpKQ0KIyByIGlzIGZ1a2NpbmcgYnVnZ3kNCmFsY29fcGxvdCA8LSBwbG90KGFsY28sIGNpPUZBTFNFLGFkZC5kYXRhPUZBTFNFLCBzaG93LnRpdGxlPUZBTFNFLHNob3cubGVnZW5kPVRSVUUpKw0KICBsYWJzKHk9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UiLCBjb2xvcj0iRGFpbHkgQWxjb2hvbCAoZHJpbmtzL2RheSkiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCiMjIyBwbG90cw0KIyMjdm9sIDwtIGdncHJlZGljdChtb2RlbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iKSkNCiMjI3ZvbF9wbG90IDwtIHBsb3Qodm9sLGNpPTk1LGFkZC5kYXRhPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KIyMjICBsYWJzKHk9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQp0aW1lIDwtIGdncHJlZGljdChtb2RlbF9ocnNfdm9sLCB0ZXJtcz1jKCJocnMgW2FsbF0iKSkNCnRpbWVfcGxvdCA8LSBwbG90KHRpbWUsY2k9OTUsYWRkLmRhdGE9RkFMU0Usc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlRpbWUgb2YgU2NhbiIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCiMgbWVhbiBjaSBwbG90cyAoZG90IHBsb3RzIHdpdGggYmFyIGZvciBlYWNoIG9mIHRoZSA0IGhlYWx0aCBncm91cHMpDQojIyNkeF92b2wgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCJvdmVyYWxsX2hlYWx0aF9yYXRpbmcgW2FsbF0iKSkNCiMjI2R4X3ZvbF9wbG90IDwtIHBsb3QoZHhfdm9sLGNpPTk1LGFkZC5kYXRhPUZBTFNFLHNob3cudGl0bGU9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycpKSsNCiMjIyAgbGFicyh5PSBicXVvdGUoIlBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiSGVhbHRoIFJhdGluZyIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KIyMjICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQ0KDQojIG1lYW4gY2kgcGxvdHMgKGRvdCBwbG90cyB3aXRoIGJhciBmb3IgZWFjaCBvZiB0aGUgcG9sbHV0aW9uKQ0KcG9sbHV0aW9uX3ByZWQgPC0gZ2dwcmVkaWN0KG1vZGVsLCB0ZXJtcz1jKCJwb2xsdXRpb25fc2NvcmUiKSkNCnBvbGx1dGlvbl9wbG90IDwtIHBsb3QocG9sbHV0aW9uX3ByZWQsY2k9OTUsYWRkLmRhdGE9RkFMU0Usc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlBvbGx1dGlvbiBMZXZlbCIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gInBvbGx1dGlvbl9zY29yZSIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQ0KDQoNCg0KYGBgDQoNCg0KYGBge3J9DQoNCiMgaSBoYXRlIHINCiMgdGhlIGVycm9ycyBkb250IGZraW5nIG1ha2Ugc2Vuc2UNCm1vZGVsMSA8LSBnbG0oQUNBX3B2c192b2wgfiBhZ2VfYXRfc2NhbiArIEkoYWdlX2F0X3NjYW5eMikgKyBzZXgsIGRhdGE9ZGF0YSkNCm1vZGVsMiA8LSBnbG0oTExTX3B2c192b2wgfiBhZ2VfYXRfc2NhbiArIEkoYWdlX2F0X3NjYW5eMikgKyBzZXgsIGRhdGE9ZGF0YSkNCm1vZGVsMyA8LSBnbG0oTUNBRl9wdnNfdm9sIH4gYWdlX2F0X3NjYW4gKyBJKGFnZV9hdF9zY2FuXjIpICsgc2V4LCBkYXRhPWRhdGEpDQptb2RlbDQgPC0gZ2xtKE1DQVBfcHZzX3ZvbCB+IGFnZV9hdF9zY2FuICsgSShhZ2VfYXRfc2Nhbl4yKSArIHNleCwgZGF0YT1kYXRhKQ0KDQpzdW1tYXJ5KG1vZGVsMSkNCnN1bW1hcnkobW9kZWwyKQ0Kc3VtbWFyeShtb2RlbDMpDQpzdW1tYXJ5KG1vZGVsNCkNCg0KbW9kX3ZvbCA8LSBsbShwdnNfdm9sX21tMyB+IG5zKGFnZV9hdF9zY2FuLCAzKSwgZGF0YSA9IGRhdGEpDQptb2RfYWNhIDwtIGxtKEFDQV9wdnNfdm9sIH4gbnMoYWdlX2F0X3NjYW4sIDMpLCBkYXRhID0gZGF0YSkNCm1vZF9sbHMgPC0gbG0oTExTX3B2c192b2wgfiBucyhhZ2VfYXRfc2NhbiwgMyksIGRhdGEgPSBkYXRhKQ0KbW9kX21jYWYgPC0gbG0oTUNBRl9wdnNfdm9sIH4gbnMoYWdlX2F0X3NjYW4sIDMpLCBkYXRhID0gZGF0YSkNCm1vZF9tY2FwIDwtIGxtKE1DQVBfcHZzX3ZvbCB+IG5zKGFnZV9hdF9zY2FuLCAzKSwgZGF0YSA9IGRhdGEpDQoNCmdyaWQgPC0gZGF0YSAlPiUgDQogIGRhdGFfZ3JpZChhZ2VfYXRfc2NhbiA9IHNlcV9yYW5nZShhZ2VfYXRfc2NhbiwgbiA9IDUwLCBleHBhbmQgPSAwLjEpKSAlPiUgDQogIGdhdGhlcl9wcmVkaWN0aW9ucyhtb2Rfdm9sLG1vZF9hY2EsbW9kX2xscyxtb2RfbWNhZixtb2RfbWNhcCwgLnByZWQgPSAicHZzX3ZvbF9tbTMiKQ0KDQpnZ3Bsb3QoZGF0YSwgYWVzKGFnZV9hdF9zY2FuLCBwcmVkKSkgKyANCiAgI2dlb21fcG9pbnQoKSArDQogICNnZW9tX2xpbmUoZGF0YSA9IHN1YnNldChncmlkLG1vZGVsPT0ibW9kX3ZvbCIpLGNvbG91ciA9ICJyZWQiKSArDQogIGdlb21fbGluZShkYXRhID0gc3Vic2V0KGdyaWQsbW9kZWw9PSJtb2RfYWNhIiksY29sb3VyID0gImJsdWUiKSsNCiAgI2dlb21fbGluZShkYXRhID0gc3Vic2V0KGdyaWQsbW9kZWw9PSJtb2RfbGxzIiksY29sb3VyID0gInB1cnBsZSIpKw0KICBnZW9tX2xpbmUoZGF0YSA9IHN1YnNldChncmlkLG1vZGVsPT0ibW9kX21jYWYiKSxjb2xvdXIgPSAiZ3JlZW4iKSsNCiAgZ2VvbV9saW5lKGRhdGEgPSBzdWJzZXQoZ3JpZCxtb2RlbD09Im1vZF9tY2FwIiksY29sb3VyID0gIm9yYW5nZSIpIyArDQogICNmYWNldF93cmFwKH4gbW9kZWwpDQpnZ3Bsb3QoZGF0YSwgYWVzKGFnZV9hdF9zY2FuLCBwcmVkKSkgKyANCiAgZ2VvbV9saW5lKGRhdGEgPSBzdWJzZXQoZ3JpZCxtb2RlbD09Im1vZF9sbHMiKSxjb2xvdXIgPSAicHVycGxlIikNCg0KDQpgYGANCg0KTExTIE1vZGVsIGFuZCBQbG90cyBCZWxvdw0KDQpgYGB7cn0NCg0KbGxzX21vZGVsIDwtIGxtKExMU19wdnNfdm9sIH4gbnMoYWdlX2F0X3NjYW4sMikgKyBzZXggKyBucyhwb2xsdXRpb25fc2NvcmUsMykgKyANCiAgICAgICAgICAgICAgbnMoc2xlZXBfZHVyYXRpb25fc3IsMikgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiAgICAgICAgICAgICAgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nOmFnZV9hdF9zY2FuICsgbnMoaHJzLCAxKSArIG92ZXJhbGxfaGVhbHRoX3JhdGluZzpocnMgKyANCiAgICAgICAgICAgICAgICBzbGVlcF9kdXJhdGlvbl9zcjpocnMgKyBkaWFnbm9zZWRfZGlhYmV0ZXMgKyBkaWFnbm9zZWRfZGlhYmV0ZXM6YWdlX2F0X3NjYW4sIGRhdGE9ZGF0YSkNCg0KbGxzX3ZvbCA8LSBnZ3ByZWRpY3QobGxzX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIpKQ0KbGxzX3ZvbF9wbG90IDwtIHBsb3QobGxzX3ZvbCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkxMUyBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmxsc190aW1lIDwtIGdncHJlZGljdChsbHNfbW9kZWwsIHRlcm1zPWMoImhycyBbYWxsXSIpKQ0KbGxzX3RpbWVfcGxvdCA8LSBwbG90KGxsc190aW1lLGNpPTk1LGFkZC5kYXRhPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiTExTIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSBvZiBTY2FuIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBtZWFuIGNpIHBsb3RzIChkb3QgcGxvdHMgd2l0aCBiYXIgZm9yIGVhY2ggb2YgdGhlIDQgaGVhbHRoIGdyb3VwcykNCmxsc19keF92b2wgPC0gZ2dwcmVkaWN0KGxsc19tb2RlbCwgdGVybXM9Yygib3ZlcmFsbF9oZWFsdGhfcmF0aW5nIFthbGxdIikpDQpsbHNfZHhfdm9sX3Bsb3QgPC0gcGxvdChsbHNfZHhfdm9sLGNpPTk1LGFkZC5kYXRhPUZBTFNFLHNob3cudGl0bGU9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycpKSsNCiAgbGFicyh5PSBicXVvdGUoIkxMUyBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkhlYWx0aCBSYXRpbmciKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9ICJvdmVyYWxsX2hlYWx0aF9yYXRpbmciKSwgbGluZXR5cGUgPSAiZGFzaGVkIikNCg0KIyBtZWFuIGNpIHBsb3RzIChkb3QgcGxvdHMgd2l0aCBiYXIgZm9yIGVhY2ggb2YgdGhlIHBvbGx1dGlvbikNCmxsc19wb2xsdXRpb25fcHJlZCA8LSBnZ3ByZWRpY3QobGxzX21vZGVsLCB0ZXJtcz1jKCJwb2xsdXRpb25fc2NvcmUiKSkNCmxsc19wb2xsdXRpb25fcGxvdCA8LSBwbG90KGxsc19wb2xsdXRpb25fcHJlZCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkxMUyBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlBvbGx1dGlvbiBMZXZlbCIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gInBvbGx1dGlvbl9zY29yZSIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQ0KDQoNCiMgb3ZlciB0aW1lIHBsb3RzDQpsbHNfcHJlZGljdGlvbl9hX3ZvbCA8LSBnZ3ByZWRpY3QobGxzX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KbGxzX3ByZWRpY3Rpb25fYV92b2wkZ3JvdXAgPC0gc3RyX3JlcGxhY2VfYWxsKGxsc19wcmVkaWN0aW9uX2Ffdm9sJGdyb3VwLCBjKGAxYD0iRXhjZWxsZW50IixgMmA9J0dvb2QnLGAzYD0nRmFpcicsYDRgPSJQb29yIikpDQoNCmxsc19wcmVkaWN0aW9uX2Ffdm9sX3Bsb3Q8LXBsb3QobGxzX3ByZWRpY3Rpb25fYV92b2wsY2k9VFJVRSxhZGQuZGF0YT1GQUxTRSxjb2xvcnM9YygiIzc5QTZFQSIsJyNBOEE4QTgnLCcjRThCNDUzJywgJ3BpbmsnKSxsaW5lLnNpemUgPTEuMixzaG93LmxlZ2VuZD1UUlVFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiTExTIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiQWdlICh5ZWFycykiLGNvbG9yPSJPdmVyYWxsIEhlYWx0aCBSYXRpbmciKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQojZXhjbGRldWQNCmxsc19wcmVkaWN0aW9uX3RpbWVfdm9sIDwtIGdncHJlZGljdChsbHNfbW9kZWwsIHRlcm1zPWMoImhycyBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KbGxzX3ByZWRpY3Rpb25fdGltZV92b2xfcGxvdDwtcGxvdChsbHNfcHJlZGljdGlvbl90aW1lX3ZvbCxjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLGNvbG9ycz1jKCIjNzlBNkVBIiwnI0E4QThBOCcsJyNFOEI0NTMnLCAncGluaycpLGxpbmUuc2l6ZSA9MS4yLHNob3cubGVnZW5kPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiTExTIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSBvZiBTY2FuIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KbGxzX3NsZWVwIDwtIGdncHJlZGljdChsbHNfbW9kZWwsIHRlcm1zPWMoInNsZWVwX2R1cmF0aW9uX3NyIikpDQpsbHNfcHJlZGljdGlvbl9zbGVlcF92b2xfcGxvdDwtcGxvdChsbHNfc2xlZXAsY2k9VFJVRSxhZGQuZGF0YT1GQUxTRSxsaW5lLnNpemUgPTEuMixzaG93LmxlZ2VuZD1UUlVFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiTExTIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiU2xlZXAgRHVyYXRpb24gKGhvdXJzKSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmxsc19kaWFiX3ZvbCA8LSBnZ3ByZWRpY3QobGxzX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsJ2RpYWdub3NlZF9kaWFiZXRlcycpKQ0KbGxzX2RpYWJfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGxsc19kaWFiX3ZvbCRncm91cCwgIjAiLCAiTm8iKQ0KbGxzX2RpYWJfdm9sJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGxsc19kaWFiX3ZvbCRncm91cCwgIjEiLCAiWWVzIikNCmxsc19kaWFiX3Bsb3QgPC0gcGxvdChsbHNfZGlhYl92b2wsIGNpPTk1LGFkZC5kYXRhPUZBTFNFLCBzaG93LnRpdGxlPUZBTFNFLHNob3cubGVnZW5kPVRSVUUpKw0KICBsYWJzKHk9IGJxdW90ZSgiUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJhZ2UiLCBjb2xvcj0iRGlhYmV0ZXMiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCg0KIyBzYW1lIGFzIGJlZm9yZS4uLi4gbGxzIHBsb3QgYWdhaW5zdCBoZWFsdGggcmF0aW5nDQojIG5vIGluZmxlY3Rpb24gcG9pbnQgYXMgaSBzYXcgaW4gamFtb3ZpDQpzaW1wbGVfbGxzX21vZGVsIDwtIGxtKExMU19wdnNfdm9sIH4gbnMoYWdlX2F0X3NjYW4sMikgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmc6YWdlX2F0X3NjYW4sIGRhdGE9ZGF0YSkNCg0Kc2ltcF9sbHNfcHJlZGljdGlvbl9hX3ZvbCA8LSBnZ3ByZWRpY3Qoc2ltcGxlX2xsc19tb2RlbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iLCJvdmVyYWxsX2hlYWx0aF9yYXRpbmciKSkNCnNpbXBfbGxzX3ByZWRpY3Rpb25fYV92b2xfcGxvdCA8LXBsb3Qoc2ltcF9sbHNfcHJlZGljdGlvbl9hX3ZvbCxjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLGNvbG9ycz1jKCIjNzlBNkVBIiwnI0E4QThBOCcsJyNFOEI0NTMnLCdwaW5rJyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lLnNpemU9MS4yLHNob3cubGVnZW5kPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh5PSBicXVvdGUoIkxMUyBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBsb29rIGF0IGxlZnQgb25seQ0KbGVmdF9sbHNfbW9kZWwgPC0gbG0oTExTTCB+IG5zKGFnZV9hdF9zY2FuLDIpICsgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nICsgDQogICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxfaGVhbHRoX3JhdGluZzphZ2VfYXRfc2NhbiArc2V4KyANCiAgICAgICAgICAgICAgICAgICAgICAgZGlhZ25vc2VkX2RpYWJldGVzICsgZGlhZ25vc2VkX2RpYWJldGVzOmFnZV9hdF9zY2FuLCBkYXRhPWRhdGEpDQoNCmxlZnRfbGxzX3ByZWRpY3Rpb25fYV92b2wgPC0gZ2dwcmVkaWN0KGxlZnRfbGxzX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KbGVmdF9sbHNfcHJlZGljdGlvbl9hX3ZvbCRncm91cCA8LSBzdHJfcmVwbGFjZV9hbGwobGVmdF9sbHNfcHJlZGljdGlvbl9hX3ZvbCRncm91cCwgYyhgMWA9IkV4Y2VsbGVudCIsYDJgPSdHb29kJyxgM2A9J0ZhaXInLGA0YD0iUG9vciIpKQ0KbGVmdF9sbHNfcHJlZGljdGlvbl9hX3ZvbF9wbG90IDwtcGxvdChsZWZ0X2xsc19wcmVkaWN0aW9uX2Ffdm9sLGNpPVRSVUUsYWRkLmRhdGE9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycsJ3BpbmsnKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuc2l6ZT0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYnMoeT0gYnF1b3RlKCJMZWZ0IExMUyBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIixjb2xvcj0iT3ZlcmFsbCBIZWFsdGggUmF0aW5nIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBsb29rIGF0IHJpZ2h0IG9ubHkNCnJpZ2h0X2xsc19tb2RlbCA8LSBsbShMTFNSIH4gbnMoYWdlX2F0X3NjYW4sMikgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJhbGxfaGVhbHRoX3JhdGluZzphZ2VfYXRfc2NhbiArc2V4KyANCiAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdub3NlZF9kaWFiZXRlcyArIGRpYWdub3NlZF9kaWFiZXRlczphZ2VfYXRfc2NhbiwgZGF0YT1kYXRhKQ0KDQpyaWdodF9sbHNfcHJlZGljdGlvbl9hX3ZvbCA8LSBnZ3ByZWRpY3QocmlnaHRfbGxzX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KcmlnaHRfbGxzX3ByZWRpY3Rpb25fYV92b2wkZ3JvdXAgPC0gc3RyX3JlcGxhY2VfYWxsKHJpZ2h0X2xsc19wcmVkaWN0aW9uX2Ffdm9sJGdyb3VwLCBjKGAxYD0iRXhjZWxsZW50IixgMmA9J0dvb2QnLGAzYD0nRmFpcicsYDRgPSJQb29yIikpDQoNCnJpZ2h0X2xsc19wcmVkaWN0aW9uX2Ffdm9sX3Bsb3QgPC1wbG90KHJpZ2h0X2xsc19wcmVkaWN0aW9uX2Ffdm9sLGNpPVRSVUUsYWRkLmRhdGE9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycsJ3BpbmsnKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuc2l6ZT0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYnMoeT0gYnF1b3RlKCJSaWdodCBMTFMgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UgKHllYXJzKSIsY29sb3I9Ik92ZXJhbGwgSGVhbHRoIFJhdGluZyIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KIyBMTFMgYW5kIGRpYWJldGVzDQoNCmxsbHNfcHJlZF9hZ2VkaWFiIDwtIGdncHJlZGljdChsZWZ0X2xsc19tb2RlbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iLCJkaWFnbm9zZWRfZGlhYmV0ZXMiKSkNCmxsbHNfcHJlZF9hZ2VkaWFiJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGxsbHNfcHJlZF9hZ2VkaWFiJGdyb3VwLCAiMCIsICJObyIpDQpsbGxzX3ByZWRfYWdlZGlhYiRncm91cCA8LSBzdHJfcmVwbGFjZShsbGxzX3ByZWRfYWdlZGlhYiRncm91cCwgIjEiLCAiWWVzIikNCmxlZnRfbGxzX3ByZWRfYV9kaWFiX3ZvbF9wbG90IDwtcGxvdChsbGxzX3ByZWRfYWdlZGlhYixjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZS5zaXplPTEuMixzaG93LmxlZ2VuZD1UUlVFLHNob3cudGl0bGU9RkFMU0UsY29sb3JzPWMoJ2JsdWUnLCdyZWQnKSkrDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHk9IGJxdW90ZSgiTGVmdCBMTFMgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UgKHllYXJzKSIsY29sb3I9IkRpYWJldGVzIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0Kcmxsc19wcmVkX2FnZWRpYWIgPC0gZ2dwcmVkaWN0KHJpZ2h0X2xsc19tb2RlbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iLCJkaWFnbm9zZWRfZGlhYmV0ZXMiKSkNCnJsbHNfcHJlZF9hZ2VkaWFiJGdyb3VwIDwtIHN0cl9yZXBsYWNlKHJsbHNfcHJlZF9hZ2VkaWFiJGdyb3VwLCAiMCIsICJObyIpDQpybGxzX3ByZWRfYWdlZGlhYiRncm91cCA8LSBzdHJfcmVwbGFjZShybGxzX3ByZWRfYWdlZGlhYiRncm91cCwgIjEiLCAiWWVzIikNCnJpZ2h0X2xsc19wcmVkX2FfZGlhYl92b2xfcGxvdCA8LXBsb3Qocmxsc19wcmVkX2FnZWRpYWIsY2k9VFJVRSxhZGQuZGF0YT1GQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuc2l6ZT0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFLGNvbG9ycz1jKCdibHVlJywncmVkJykpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh5PSBicXVvdGUoIlJpZ2h0IExMUyBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIixjb2xvcj0iRGlhYmV0ZXMiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCg0KDQoNCg0KDQoNCmBgYA0KDQpEbyB0aGUgc2FtZSBzaGl0IGJ1dCBmb3IgdGhlIEFDQQ0KDQoNCmBgYHtyfQ0KI2RhdGEkQUNBX3B2c192b2wgPC0gZGF0YSRBQ0FMK2RhdGEkQUNBUg0KYWNhX21vZGVsIDwtIGxtKEFDQV9wdnNfdm9sIH4gbnMoYWdlX2F0X3NjYW4sMykgKyBzZXggKyBucyhwb2xsdXRpb25fc2NvcmUsMykgKyANCiAgICAgICAgICAgICAgbnMoc2xlZXBfZHVyYXRpb25fc3IsMykgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiAgICAgICAgICAgICAgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nOmFnZV9hdF9zY2FuICsgbnMoaHJzLCAzKSArIG92ZXJhbGxfaGVhbHRoX3JhdGluZzpocnMgKyANCiAgICAgICAgICAgICAgICBzbGVlcF9kdXJhdGlvbl9zcjpocnMgKyBkaWFnbm9zZWRfZGlhYmV0ZXMgKyBkaWFnbm9zZWRfZGlhYmV0ZXM6YWdlX2F0X3NjYW4sIGRhdGE9ZGF0YSkNCg0KYWNhX3ZvbCA8LSBnZ3ByZWRpY3QoYWNhX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIpKQ0KYWNhX3ZvbF9wbG90IDwtIHBsb3QoYWNhX3ZvbCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmFjYV90aW1lIDwtIGdncHJlZGljdChhY2FfbW9kZWwsIHRlcm1zPWMoImhycyBbYWxsXSIpKQ0KYWNhX3RpbWVfcGxvdCA8LSBwbG90KGFjYV90aW1lLGNpPTk1LGFkZC5kYXRhPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSBvZiBTY2FuIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBtZWFuIGNpIHBsb3RzIChkb3QgcGxvdHMgd2l0aCBiYXIgZm9yIGVhY2ggb2YgdGhlIDQgaGVhbHRoIGdyb3VwcykNCiMgb25seSB3aGVuIGl0IGlzIGNvbnZlcnRlZCB0byBmYWN0b3JzLCB3aGVuIGFzIGNvbnRpbm91cyBudW1lcmlsY2EsIGl0J3MgYSBsaW5lIHBsb3QNCmFjYV9keF92b2wgPC0gZ2dwcmVkaWN0KGFjYV9tb2RlbCwgdGVybXM9Yygib3ZlcmFsbF9oZWFsdGhfcmF0aW5nIFthbGxdIikpDQphY2FfZHhfdm9sX3Bsb3QgPC0gcGxvdChhY2FfZHhfdm9sLGNpPTk1LGFkZC5kYXRhPUZBTFNFLHNob3cudGl0bGU9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycpKSsNCiAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkhlYWx0aCBSYXRpbmciKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9ICJvdmVyYWxsX2hlYWx0aF9yYXRpbmciKSwgbGluZXR5cGUgPSAiZGFzaGVkIikNCg0KIyBtZWFuIGNpIHBsb3RzIChkb3QgcGxvdHMgd2l0aCBiYXIgZm9yIGVhY2ggb2YgdGhlIHBvbGx1dGlvbikNCmFjYV9wb2xsdXRpb25fcHJlZCA8LSBnZ3ByZWRpY3QoYWNhX21vZGVsLCB0ZXJtcz1jKCJwb2xsdXRpb25fc2NvcmUiKSkNCmFjYV9wb2xsdXRpb25fcGxvdCA8LSBwbG90KGFjYV9wb2xsdXRpb25fcHJlZCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlBvbGx1dGlvbiBMZXZlbCIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gInBvbGx1dGlvbl9zY29yZSIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQ0KDQoNCiMgb3ZlciB0aW1lIHBsb3RzDQphY2FfcHJlZGljdGlvbl9hX3ZvbCA8LSBnZ3ByZWRpY3QoYWNhX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KYWNhX3ByZWRpY3Rpb25fYV92b2wkZ3JvdXAgPC0gc3RyX3JlcGxhY2VfYWxsKGFjYV9wcmVkaWN0aW9uX2Ffdm9sJGdyb3VwLCBjKGAxYD0iRXhjZWxsZW50IixgMmA9J0dvb2QnLGAzYD0nRmFpcicsYDRgPSJQb29yIikpDQphY2FfcHJlZGljdGlvbl9hX3ZvbF9wbG90PC1wbG90KGFjYV9wcmVkaWN0aW9uX2Ffdm9sLGNpPVRSVUUsYWRkLmRhdGE9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycsICdwaW5rJyksbGluZS5zaXplID0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIixjb2xvcj0iT3ZlcmFsbCBIZWFsdGggUmF0aW5nIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQphY2FfcHJlZGljdGlvbl90aW1lX3ZvbCA8LSBnZ3ByZWRpY3QoYWNhX21vZGVsLCB0ZXJtcz1jKCJocnMgW2FsbF0iLCJvdmVyYWxsX2hlYWx0aF9yYXRpbmciKSkNCmFjYV9wcmVkaWN0aW9uX3RpbWVfdm9sX3Bsb3Q8LXBsb3QoYWNhX3ByZWRpY3Rpb25fdGltZV92b2wsY2k9VFJVRSxhZGQuZGF0YT1GQUxTRSxjb2xvcnM9YygiIzc5QTZFQSIsJyNBOEE4QTgnLCcjRThCNDUzJywgJ3BpbmsnKSxsaW5lLnNpemUgPTEuMixzaG93LmxlZ2VuZD1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlRpbWUgb2YgU2NhbiIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmFjYV9zbGVlcCA8LSBnZ3ByZWRpY3QoYWNhX21vZGVsLCB0ZXJtcz1jKCJocnMgW2FsbF0iLCJzbGVlcF9kdXJhdGlvbl9zciIpKQ0KYWNhX3ByZWRpY3Rpb25fc2xlZXBfdm9sX3Bsb3Q8LXBsb3QoYWNhX3NsZWVwLGNpPVRSVUUsYWRkLmRhdGE9RkFMU0UsbGluZS5zaXplID0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlRpbWUiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQphY2FfcHJlZF9hZ2VkaWFiIDwtIGdncHJlZGljdChhY2FfbW9kZWwsIHRlcm1zPWMoImFnZV9hdF9zY2FuIFthbGxdIiwiZGlhZ25vc2VkX2RpYWJldGVzIikpDQphY2FfcHJlZF9hZ2VkaWFiJGdyb3VwIDwtIHN0cl9yZXBsYWNlKGFjYV9wcmVkX2FnZWRpYWIkZ3JvdXAsICIwIiwgIk5vIikNCmFjYV9wcmVkX2FnZWRpYWIkZ3JvdXAgPC0gc3RyX3JlcGxhY2UoYWNhX3ByZWRfYWdlZGlhYiRncm91cCwgIjEiLCAiWWVzIikNCmFjYV9wcmVkX2FfZGlhYl92b2xfcGxvdCA8LXBsb3QoYWNhX3ByZWRfYWdlZGlhYixjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZS5zaXplPTEuMixzaG93LmxlZ2VuZD1UUlVFLHNob3cudGl0bGU9RkFMU0UsY29sb3JzPWMoJ2JsdWUnLCdyZWQnKSkrDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHk9IGJxdW90ZSgiQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiQWdlICh5ZWFycykiLGNvbG9yPSJEaWFiZXRlcyIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KDQoNCg0KDQojIGZvcmdldCBsZWZ0IGFuZCByaWdodA0KIyBub3cgbGVmdCBhbmQgcmlnaHQNCg0KbGFjYV9tb2RlbCA8LSBsbShBQ0FMIH4gbnMoYWdlX2F0X3NjYW4sMikgKyBzZXggKyBucyhwb2xsdXRpb25fc2NvcmUsMykgKyANCiAgICAgICAgICAgICAgbnMoc2xlZXBfZHVyYXRpb25fc3IsMykgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmcgKyANCiAgICAgICAgICAgICAgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nOmFnZV9hdF9zY2FuICsgbnMoaHJzLCAzKSArIG92ZXJhbGxfaGVhbHRoX3JhdGluZzpocnMgKyANCiAgICAgICAgICAgICAgICBzbGVlcF9kdXJhdGlvbl9zcjpocnMgKyBkaWFnbm9zZWRfZGlhYmV0ZXMgKyBkaWFnbm9zZWRfZGlhYmV0ZXM6YWdlX2F0X3NjYW4sIGRhdGE9ZGF0YSkNCg0KbGFjYV92b2wgPC0gZ2dwcmVkaWN0KGxhY2FfbW9kZWwsIHRlcm1zPWMoImFnZV9hdF9zY2FuIFthbGxdIikpDQpsYWNhX3ZvbF9wbG90IDwtIHBsb3QobGFjYV92b2wsY2k9OTUsYWRkLmRhdGE9RkFMU0Usc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJMQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiQWdlIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KbGFjYV90aW1lIDwtIGdncHJlZGljdChsYWNhX21vZGVsLCB0ZXJtcz1jKCJocnMgW2FsbF0iKSkNCmxhY2FfdGltZV9wbG90IDwtIHBsb3QoYWNhX3RpbWUsY2k9OTUsYWRkLmRhdGE9RkFMU0Usc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJMQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSBvZiBTY2FuIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBtZWFuIGNpIHBsb3RzIChkb3QgcGxvdHMgd2l0aCBiYXIgZm9yIGVhY2ggb2YgdGhlIDQgaGVhbHRoIGdyb3VwcykNCiMgb25seSB3aGVuIGl0IGlzIGNvbnZlcnRlZCB0byBmYWN0b3JzLCB3aGVuIGFzIGNvbnRpbm91cyBudW1lcmlsY2EsIGl0J3MgYSBsaW5lIHBsb3QNCmxhY2FfZHhfdm9sIDwtIGdncHJlZGljdChsYWNhX21vZGVsLCB0ZXJtcz1jKCJvdmVyYWxsX2hlYWx0aF9yYXRpbmcgW2FsbF0iKSkNCmxhY2FfZHhfdm9sX3Bsb3QgPC0gcGxvdChsYWNhX2R4X3ZvbCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFLGNvbG9ycz1jKCIjNzlBNkVBIiwnI0E4QThBOCcsJyNFOEI0NTMnKSkrDQogIGxhYnMoeT0gYnF1b3RlKCJMQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiSGVhbHRoIFJhdGluZyIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQ0KDQojIG1lYW4gY2kgcGxvdHMgKGRvdCBwbG90cyB3aXRoIGJhciBmb3IgZWFjaCBvZiB0aGUgcG9sbHV0aW9uKQ0KbGFjYV9wb2xsdXRpb25fcHJlZCA8LSBnZ3ByZWRpY3QobGFjYV9tb2RlbCwgdGVybXM9YygicG9sbHV0aW9uX3Njb3JlIikpDQpsYWNhX3BvbGx1dGlvbl9wbG90IDwtIHBsb3QobGFjYV9wb2xsdXRpb25fcHJlZCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkxBQ0EgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJQb2xsdXRpb24gTGV2ZWwiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9ICJwb2xsdXRpb25fc2NvcmUiKSwgbGluZXR5cGUgPSAiZGFzaGVkIikNCg0KDQojIG92ZXIgdGltZSBwbG90cw0KbGFjYV9wcmVkaWN0aW9uX2Ffdm9sIDwtIGdncHJlZGljdChsYWNhX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KbGFjYV9wcmVkaWN0aW9uX2Ffdm9sX3Bsb3Q8LXBsb3QobGFjYV9wcmVkaWN0aW9uX2Ffdm9sLGNpPVRSVUUsYWRkLmRhdGE9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycsICdwaW5rJyksbGluZS5zaXplID0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIkxBQ0EgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UgKHllYXJzKSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KbGFjYV9wcmVkaWN0aW9uX3RpbWVfdm9sIDwtIGdncHJlZGljdChsYWNhX21vZGVsLCB0ZXJtcz1jKCJocnMgW2FsbF0iLCJvdmVyYWxsX2hlYWx0aF9yYXRpbmciKSkNCmxhY2FfcHJlZGljdGlvbl90aW1lX3ZvbF9wbG90PC1wbG90KGxhY2FfcHJlZGljdGlvbl90aW1lX3ZvbCxjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLGNvbG9ycz1jKCIjNzlBNkVBIiwnI0E4QThBOCcsJyNFOEI0NTMnLCAncGluaycpLGxpbmUuc2l6ZSA9MS4yLHNob3cubGVnZW5kPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiTEFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlRpbWUgb2YgU2NhbiIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmxhY2Ffc2xlZXAgPC0gZ2dwcmVkaWN0KGxhY2FfbW9kZWwsIHRlcm1zPWMoImhycyBbYWxsXSIsInNsZWVwX2R1cmF0aW9uX3NyIikpDQpsYWNhX3ByZWRpY3Rpb25fc2xlZXBfdm9sX3Bsb3Q8LXBsb3QobGFjYV9zbGVlcCxjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLGxpbmUuc2l6ZSA9MS4yLHNob3cubGVnZW5kPVRSVUUsc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJMQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmxhY2FfcHJlZF9hZ2VkaWFiIDwtIGdncHJlZGljdChsYWNhX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsImRpYWdub3NlZF9kaWFiZXRlcyIpKQ0KbGFjYV9wcmVkX2FfZGlhYl92b2xfcGxvdCA8LXBsb3QobGFjYV9wcmVkX2FnZWRpYWIsY2k9VFJVRSxhZGQuZGF0YT1GQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuc2l6ZT0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFLGNvbG9ycz1jKCdibHVlJywncmVkJykpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh5PSBicXVvdGUoIkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQpyYWNhX21vZGVsIDwtIGxtKEFDQVIgfiBucyhhZ2VfYXRfc2NhbiwyKSArIHNleCArIG5zKHBvbGx1dGlvbl9zY29yZSwzKSArIA0KICAgICAgICAgICAgICBucyhzbGVlcF9kdXJhdGlvbl9zciwzKSArIG92ZXJhbGxfaGVhbHRoX3JhdGluZyArIA0KICAgICAgICAgICAgICBvdmVyYWxsX2hlYWx0aF9yYXRpbmc6YWdlX2F0X3NjYW4gKyBucyhocnMsIDMpICsgb3ZlcmFsbF9oZWFsdGhfcmF0aW5nOmhycyArIA0KICAgICAgICAgICAgICAgIHNsZWVwX2R1cmF0aW9uX3NyOmhycyArIGRpYWdub3NlZF9kaWFiZXRlcyArIGRpYWdub3NlZF9kaWFiZXRlczphZ2VfYXRfc2NhbiwgZGF0YT1kYXRhKQ0KDQpyYWNhX3ZvbCA8LSBnZ3ByZWRpY3QocmFjYV9tb2RlbCwgdGVybXM9YygiYWdlX2F0X3NjYW4gW2FsbF0iKSkNCnJhY2Ffdm9sX3Bsb3QgPC0gcGxvdChyYWNhX3ZvbCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIlJBQ0EgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQpyYWNhX3RpbWUgPC0gZ2dwcmVkaWN0KHJhY2FfbW9kZWwsIHRlcm1zPWMoImhycyBbYWxsXSIpKQ0KcmFjYV90aW1lX3Bsb3QgPC0gcGxvdChyYWNhX3RpbWUsY2k9OTUsYWRkLmRhdGE9RkFMU0Usc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJSQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSBvZiBTY2FuIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBtZWFuIGNpIHBsb3RzIChkb3QgcGxvdHMgd2l0aCBiYXIgZm9yIGVhY2ggb2YgdGhlIDQgaGVhbHRoIGdyb3VwcykNCiMgb25seSB3aGVuIGl0IGlzIGNvbnZlcnRlZCB0byBmYWN0b3JzLCB3aGVuIGFzIGNvbnRpbm91cyBudW1lcmlsY2EsIGl0J3MgYSBsaW5lIHBsb3QNCnJhY2FfZHhfdm9sIDwtIGdncHJlZGljdChyYWNhX21vZGVsLCB0ZXJtcz1jKCJvdmVyYWxsX2hlYWx0aF9yYXRpbmcgW2FsbF0iKSkNCnJhY2FfZHhfdm9sX3Bsb3QgPC0gcGxvdChyYWNhX2R4X3ZvbCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFLGNvbG9ycz1jKCIjNzlBNkVBIiwnI0E4QThBOCcsJyNFOEI0NTMnKSkrDQogIGxhYnMoeT0gYnF1b3RlKCJSQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiSGVhbHRoIFJhdGluZyIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQ0KDQojIG1lYW4gY2kgcGxvdHMgKGRvdCBwbG90cyB3aXRoIGJhciBmb3IgZWFjaCBvZiB0aGUgcG9sbHV0aW9uKQ0KcmFjYV9wb2xsdXRpb25fcHJlZCA8LSBnZ3ByZWRpY3QocmFjYV9tb2RlbCwgdGVybXM9YygicG9sbHV0aW9uX3Njb3JlIikpDQpyYWNhX3BvbGx1dGlvbl9wbG90IDwtIHBsb3QocmFjYV9wb2xsdXRpb25fcHJlZCxjaT05NSxhZGQuZGF0YT1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIlJBQ0EgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJQb2xsdXRpb24gTGV2ZWwiKSsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9ICJwb2xsdXRpb25fc2NvcmUiKSwgbGluZXR5cGUgPSAiZGFzaGVkIikNCg0KDQojIG92ZXIgdGltZSBwbG90cw0KcmFjYV9wcmVkaWN0aW9uX2Ffdm9sIDwtIGdncHJlZGljdChyYWNhX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsIm92ZXJhbGxfaGVhbHRoX3JhdGluZyIpKQ0KcmFjYV9wcmVkaWN0aW9uX2Ffdm9sX3Bsb3Q8LXBsb3QocmFjYV9wcmVkaWN0aW9uX2Ffdm9sLGNpPVRSVUUsYWRkLmRhdGE9RkFMU0UsY29sb3JzPWMoIiM3OUE2RUEiLCcjQThBOEE4JywnI0U4QjQ1MycsICdwaW5rJyksbGluZS5zaXplID0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFKSsNCiAgbGFicyh5PSBicXVvdGUoIlJBQ0EgUFZTIFZvbHVtZSJ+KG1tXjMpKSwgeCA9ICJBZ2UgKHllYXJzKSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KcmFjYV9wcmVkaWN0aW9uX3RpbWVfdm9sIDwtIGdncHJlZGljdChyYWNhX21vZGVsLCB0ZXJtcz1jKCJocnMgW2FsbF0iLCJvdmVyYWxsX2hlYWx0aF9yYXRpbmciKSkNCnJhY2FfcHJlZGljdGlvbl90aW1lX3ZvbF9wbG90PC1wbG90KHJhY2FfcHJlZGljdGlvbl90aW1lX3ZvbCxjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLGNvbG9ycz1jKCIjNzlBNkVBIiwnI0E4QThBOCcsJyNFOEI0NTMnLCAncGluaycpLGxpbmUuc2l6ZSA9MS4yLHNob3cubGVnZW5kPUZBTFNFLHNob3cudGl0bGU9RkFMU0UpKw0KICBsYWJzKHk9IGJxdW90ZSgiUkFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIlRpbWUgb2YgU2NhbiIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCnJhY2Ffc2xlZXAgPC0gZ2dwcmVkaWN0KHJhY2FfbW9kZWwsIHRlcm1zPWMoImhycyBbYWxsXSIsInNsZWVwX2R1cmF0aW9uX3NyIikpDQpyYWNhX3ByZWRpY3Rpb25fc2xlZXBfdm9sX3Bsb3Q8LXBsb3QocmFjYV9zbGVlcCxjaT1UUlVFLGFkZC5kYXRhPUZBTFNFLGxpbmUuc2l6ZSA9MS4yLHNob3cubGVnZW5kPVRSVUUsc2hvdy50aXRsZT1GQUxTRSkrDQogIGxhYnMoeT0gYnF1b3RlKCJSQUNBIFBWUyBWb2x1bWUifihtbV4zKSksIHggPSAiVGltZSIpKyB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCnJhY2FfcHJlZF9hZ2VkaWFiIDwtIGdncHJlZGljdChyYWNhX21vZGVsLCB0ZXJtcz1jKCJhZ2VfYXRfc2NhbiBbYWxsXSIsImRpYWdub3NlZF9kaWFiZXRlcyIpKQ0KcmFjYV9wcmVkX2FfZGlhYl92b2xfcGxvdCA8LXBsb3QocmFjYV9wcmVkX2FnZWRpYWIsY2k9VFJVRSxhZGQuZGF0YT1GQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUuc2l6ZT0xLjIsc2hvdy5sZWdlbmQ9VFJVRSxzaG93LnRpdGxlPUZBTFNFLGNvbG9ycz1jKCdibHVlJywncmVkJykpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh5PSBicXVvdGUoIlJpZ2h0IEFDQSBQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KIyBwbG90cyB0aGUgb2xkIHdheSAoaG9ub3VycyBwcm9qZWN0KQ0KI3ByZWRfYWdlX3ZvbCA8LSBnZ3ByZWRpY3Qodm9sX2xtbTE1LCB0ZXJtcz1jKCJBZ2UgW2FsbF0iKSkNCiNwcmVkX2FnZV92b2xfcGxvdDwtcGxvdChwcmVkX2FnZV92b2wsY2k9VFJVRSxhZGQuZGF0YT1UUlVFLCBjb2xvciA9J2JsdWUnLGxpbmUuc2l6ZSA9MSxzaG93LmxlZ2VuZD1GQUxTRSxzaG93LnRpdGxlPUZBTFNFKSsNCiMgIGxhYnMoeT0gYnF1b3RlKCJQVlMgVm9sdW1lIn4obW1eMykpLCB4ID0gIkFnZSAoeWVhcnMpIikrIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KIyBjb3JyZWxhdGlvbiBwbG90cw0KDQpzdWJzZXRfZGF0YSA8LSBkYXRhW2MoInB2c192b2xfbW0zIiwicHZzX2NsdXN0ZXJzIiwnYWdlX2F0X3NjYW4nLCdzZXgnLA0KICAgICAgICAgICAgICAgICAgICAgICJoaXBfY2lyYyIsIndhaXN0X2NpcmMiLCJoZWlnaHQiLCJ3ZWlnaHQiLCJCTUkiLA0KICAgICAgICAgICAgICAgICAgICAgICJwb2xsdXRpb25fc2NvcmUiLCJ0b3duc2VuZF9kZXByaXZhdGlvbl9pbmRleCIsInJlYXNvbl9sdGZ1IiwNCiAgICAgICAgICAgICAgICAgICAgICAiaXBhcV9hY3Rpdml0eV9ncm91cCIsIm51bV90cmVhdG1lbnRzX21lZGljYXRpb25zIiwNCiAgICAgICAgICAgICAgICAgICAgICAib3ZlcmFsbF9oZWFsdGhfcmF0aW5nIiwNCiAgICAgICAgICAgICAgICAgICAgICAiYXZnX3RvdGFsX2hvdXNlaG9sZF9pbmNvbWUiLA0KICAgICAgICAgICAgICAgICAgICAgICJzbGVlcF9kdXJhdGlvbl9zciIsImRpZmZpY3VsdHlfZ2V0dGluZ191cF9tb3JuaW5nIiwiY2hyb25vdHlwZSIsIm5hcF9kdXJpbmdfZGF5IiwNCiAgICAgICAgICAgICAgICAgICAgICAiaW5zb21uaWFfc3IiLCJzbm9yaW5nX3NyIiwgIm5hcmNvbGVwc3lfc3IiLA0KICAgICAgICAgICAgICAgICAgICAgICJzZWVuX2dwX2FueF9kZXAiLCJmcmVxX3RpcmVkbmVzc190d293ZWVrcyIsDQogICAgICAgICAgICAgICAgICAgICAgImZyZXFfdGVuc2lvbl90d293ZWVrcyIsImZyZXFfdW5lbnRodXNpYW1fdHdvd2Vla3MiLA0KICAgICAgICAgICAgICAgICAgICAgICJmcmVxX2RlcHJlc3NlZF90d293ZWVrcyIsIm1vb2Rfc3dpbmdzIiwNCiAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAibWlzZXJhYmxlIiwiaXJyaXRhYmxlIiwiZmVkX3VwIiwNCiAgICAgICAgICAgICAgICAgICAgICAibmVydm91cyIsIndvcnJpZXJfYW54aW91cyIsInRlbnNpb25faGlnaGx5c3RydW5nIiwNCiAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAibmV1cm90aWNpc21fc2NvcmUiLA0KICAgICAgICAgICAgICAgICAgICAgICJ0eXBpY2FsX2RhaWx5X2FsY29ob2wiLCJhbGNvaG9sX2ZyZXF1ZW5jeSIsJ2hycycpXQ0KDQpzdWJzZXRfZGF0YSA8LSBzYXBwbHkoc3Vic2V0X2RhdGEsIGFzLm51bWVyaWMpDQoNCm15X2NvciA8LSBjb3Ioc3Vic2V0X2RhdGEsIHVzZT0iY29tcGxldGUub2JzIikNCiNzdWJzZXRfZGF0YSA8LSBsYXBwbHkoc3Vic2V0X2RhdGEsYXMubnVtZXJpYykNCmNvcnJfcGxvdCA8LSBjb3JycGxvdChteV9jb3IsIHR5cGUgPSAidXBwZXIiLCBvcmRlciA9ICJoY2x1c3QiLCANCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1LA0KICAgICAgICAgdGwuY2V4ID0gMC44KSNudW1iZXIuY2V4ID0gMC41DQojaXMuY29yciA9IEZBTFNFLCBtZXRob2QgPSAic3F1YXJlIg0KYGBgDQpEaWRuJ3Qgd29yayBpbiB0aGUgY29ycmVsYXRpb24gcGxvdA0KICAgICAgICAgICAgICAgICAgICAgICJsb25nX3Rlcm1faWxsbmVzcyIsIndlaWdodF9jaGFuZ2VfbGFzdF95ZWFyIiwiam9iX25pZ2h0X3NoaWZ0Iiwiam9iX3NoaWZ0X3dvcmsiLCANCiAgICAgICAgICAgICAgICAgICAgICAiYWdlX2F0X2RlYXRoIiwjIyMjIyMNCiAgICAgICAgICAgICAgICAgICAgICAsInRyb3VibGVfZmFsbGluZ19hc2xlZXAiLCJvdmVyc2xlZXBpbmciLA0KICAgICAgICAgICAgICAgICAgICAgICJkaWFnbm9zZWRfZGlhYmV0ZXMiLCJkaWFnbm9zZWRfY2FuY2VyIiwNCiAgICAgICAgICAgICAgICAgICAgICAib3RoZXJfc2VyaW91c19jb25kaXRpb24iLCJudW1iZXJfbGl2ZV9iaXJ0aHMiDQogICAgICAgICAgICAgICAgICAgICAgImNvbnRyYWNlcHRpdmVfcGlsbF91c2UiLCJhZ2Vfc3Ryb2tlIiwNCiAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyX2RlcHJlc3Npb25fZXBpc29kZXMiLCJzZWVuX3BzeWNoX2FueF9kZXAiLCJzZW5zaXRpdmVfaHVydGZlZWxpbmdzIiwNCiAgICAgICAgICAgICAgICAgICAgICJ3b3JyeV9hZnRlcl9lbWJhcnJlc3NtZW50IiwibmVydmVzIiwiYWJsZV93YWxrX2N5Y2xlX3Rlbm1pbnMiLA0KICAgICAgICAgICAgICAgICAgICAgICJhZ2VfZmlyc3RfZGVwcmVzc2lvbiIsImFnZV9sYXN0X2RlcHJlc3Npb24iDQoNCiAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICANCiJwb2xsdXRpb25fc2NvcmUiLA0KIndhaXN0X2NpcmMiLCJoaXBfY2lyYyIsImhlaWdodCIsIndlaWdodCIsIkJNSSIsDQoNCg0KInN1YnVyYiIsImV0aG5pY2l0eSIsDQoNCiJpcGFxX2FjdGl2aXR5X2dyb3VwIiwibnVtX3RyZWF0bWVudHNfbWVkaWNhdGlvbnMiLCJ0b3duc2VuZF9kZXByaXZhdGlvbl9pbmRleCIsDQoicmVhc29uX2x0ZnUiLCJkYXRlX2x0ZnUiLA0KDQoib3ZlcmFsbF9oZWFsdGhfcmF0aW5nIiwibG9uZ190ZXJtX2lsbG5lc3MiLCJ3ZWlnaHRfY2hhbmdlX2xhc3RfeWVhciIsDQoiYXZnX3RvdGFsX2hvdXNlaG9sZF9pbmNvbWUiLCJqb2JfbmlnaHRfc2hpZnQiLCJqb2Jfc2hpZnRfd29yayIsIA0KDQoiYWdlX2F0X2RlYXRoIiwiYWdlX3N0cm9rZSIsIm51bWJlcl9kZXByZXNzaW9uX2VwaXNvZGVzIiwNCg0KInNsZWVwX2R1cmF0aW9uX3NyIiwiZGlmZmljdWx0eV9nZXR0aW5nX3VwX21vcm5pbmciLCJjaHJvbm90eXBlIiwibmFwX2R1cmluZ19kYXkiDQoiaW5zb21uaWFfc3IiLCJzbm9yaW5nX3NyIiwgIm5hcmNvbGVwc3lfc3IiLA0KImRpYWdub3NlZF9kaWFiZXRlcyIsImRpYWdub3NlZF9jYW5jZXIiLA0KIm90aGVyX3NlcmlvdXNfY29uZGl0aW9uIiwibnVtYmVyX2xpdmVfYmlydGhzIi4NCiJjb250cmFjZXB0aXZlX3BpbGxfdXNlIiwNCiJzZWVuX3BzeWNoX2FueF9kZXAiLA0KInNlZW5fZ3BfYW54X2RlcCIsImZyZXFfdGlyZWRuZXNzX3R3b3dlZWtzIiwNCiJmcmVxX3RlbnNpb25fdHdvd2Vla3MiLCJmcmVxX3VuZW50aHVzaWFtX3R3b3dlZWtzIiwNCiJmcmVxX2RlcHJlc3NlZF90d293ZWVrcyIsIm1vb2Rfc3dpbmdzIiwNCiJtaXNlcmFibGUiLCJpcnJpdGFibGUiLA0KInNlbnNpdGl2ZV9odXJ0ZmVlbGluZ3MiLCJmZWRfdXAiLA0KIm5lcnZvdXMiLCJ3b3JyaWVyX2FueGlvdXMiLA0KInRlbnNpb25faGlnaGx5c3RydW5nIiwid29ycnlfYWZ0ZXJfZW1iYXJyZXNzbWVudCIsDQoibmVydmVzIiwiYWJsZV93YWxrX2N5Y2xlX3Rlbm1pbnMiLA0KIm5ldXJvdGljaXNtX3Njb3JlIiwidHlwaWNhbF9kYWlseV9hbGNvaG9sIiwNCiAiYWxjb2hvbF9mcmVxdWVuY3kiLCJhZ2VfZmlyc3RfZGVwcmVzc2lvbiIsDQogImFnZV9sYXN0X2RlcHJlc3Npb24iLCJ0cm91YmxlX2ZhbGxpbmdfYXNsZWVwIiwNCiAib3ZlcnNsZWVwaW5nIiwNCiANCg0KInRpbWUiLCJ5ZWFyIiwibW9udGgiLCAiZGF5IiwiaHJzIiwgIm1udGhzIiwicG9sbHV0aW9uX3Njb3JlIiwic2Vhc29uIiAgDQoNCg0KYGBge3J9DQp0aW1lX29mX3NjYW4NCmFnZV9hdF9kZWF0aA0KYWdlX3N0cm9rZQ0KDQpzbGVlcF9kdXJhdGlvbl9zcg0KaW5zb21uaWFfc3INCm5hcF9kdXJpbmdfZGF5DQpzbm9yaW5nX3NyDQpuYXJjb2xlcHN5X3NyDQoNCm92ZXJhbGxfaGVhbHRoX3JhdGluZw0KbG9uZ190ZXJtX2lsbG5lc3MNCmRpYWdub3NlZF9kaWFiZXRlcw0KDQpCTUkNCmhlaWdodA0Kd2VpZ2h0DQp3YWlzdF9jaXJjDQpoaXBfY2lyYw0KDQpgYGANCg0KQXNzb2NpYXRpb25zIHdpdGggZGlzZWFzZQ0KDQpnYW1sajo6Z2FtbGpHbG0oDQogICAgZm9ybXVsYSA9IExMU0wgfiBzZXggKyBhZ2VfYXRfc2NhbiArIG92ZXJhbGxfaGVhbHRoX3JhdGluZyArIEkoYWdlX2F0X3NjYW5eMikgKyBvdmVyYWxsX2hlYWx0aF9yYXRpbmc6YWdlX2F0X3NjYW4sDQogICAgZGF0YSA9IGRhdGEsDQogICAgcGxvdEhBeGlzID0gYWdlX2F0X3NjYW4sDQogICAgcGxvdFNlcExpbmVzID0gb3ZlcmFsbF9oZWFsdGhfcmF0aW5nLA0KICAgIHNjYWxpbmc9YyhhZ2VfYXRfc2NhbiA9ICJub25lIiwgc2xlZXBfZHVyYXRpb25fc3IgPSAibm9uZSIsIG92ZXJhbGxfaGVhbHRoX3JhdGluZyA9ICJjZW50ZXJlZCIsIHR5cGljYWxfZGFpbHlfYWxjb2hvbCA9ICJjZW50ZXJlZCIsIGRpYWdub3NlZF9kaWFiZXRlcyA9ICJjZW50ZXJlZCIpKQ0KDQoNCg0KYGBge3J9DQoNCg0KDQpgYGANCg0KdWtiIHN0YXJ0dXAgY29kZSANCmJ5IExhY2h5DQoNCkNyZWF0ZSBDb3JlIERhdGFzZXQNCg0KYGBge3J9DQojIHBhY2thZ2VzDQoNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShwdXJycikNCmxpYnJhcnkodGlkeXIpDQoNCiMgcmVhZCBVS0IgZGF0YQ0KDQpkIDwtIHJlYWRSRFMoIi9ob21lL2xjcmkwMDA2L2JjNDFfc2NyYXRjaC9VS0JfZGF0YS91a2I1MTk1Ni5yZHMiKQ0KDQojIHJlYWQgZGF0YSBkaWN0aW9uYXJ5DQojIGRpY3QgaGFzICJGaWVsZF9pZCIsICJOZXdfbmFtZSIsICdjb2RpbmdfdW5pdHMnLCAnRGV0YWlsJw0KZGF0YWRpY3QgPC0gcmVhZF9jc3YoIi9ob21lL2xjcmkwMDA2L2JjNDEvY29yZV91a2IvY29yZV9kYXRhX2RpY3Rpb25hcnkuY3N2IikNCg0KDQojIHNlbGVjdCBjb3JlIHZhcmlhYmxlcw0KDQpjb3JlIDwtIGQgJT4lIA0KICBzZWxlY3QoYWxsX29mKGRhdGFkaWN0JEZpZWxkX2lkKSkNCg0KIyByZW5hbWUgdmFyaWFibGVzIA0KDQpuYW1lcyhjb3JlKSA8LSBkYXRhZGljdCROZXdfbmFtZQ0KDQojIGNvdW50IG1pc3NpbmcgDQoNCm1hcF9kZihjb3JlLCB+c3VtKGlzLm5hKC4pKSkgJT4lIA0KICBwaXZvdF9sb25nZXIoZXZlcnl0aGluZygpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh2YWx1ZSkpICU+JSANCiAgcHJpbnQobiA9IDE1MCkNCg0KIyBzYXZlIGNvcmUgZGF0YXNldA0Kd3JpdGVfY3N2KGNvcmUsICIvZnMwMi9iYzQxL2NvcmVfdWtiL2NvcmVfdWtiLmNzdiIpDQpgYGANCg0KDQp1a2IgTGFjaHkgY29kZQ0KDQpjdXQgdWtiIGRhdGENCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCiMgciBmb3JtYXR0ZWQgZGF0YSBzdG9yYWdlDQojIHRhYiBkZWxpbWl0ZWQgZmlsZQ0KZCA8LSByZWFkUkRTKCIvaG9tZS9sY3JpMDAwNi9iYzQxL1VLQl9kYXRhL3VrYjUxOTU2LnJkcyIpDQoNCiMgZ2V0IGJ1bGsgZGF0YSBpZHMNCiMgbXJpIElEJ3MgDQoNCm1yaV9pZCA8LSBkICU+JSANCiAgc2VsZWN0KGVpZCwgYDIwMjUyLTIuMGApICU+JSANCiAgZmlsdGVyKCFpcy5uYShgMjAyNTItMi4wYCkpDQoNCndyaXRlLnRhYmxlKG1yaV9pZCwgIi9ob21lL2xjcmkwMDA2L2JjNDEvVUtCX2RhdGEvbXJpX2lkLnR4dCIsDQogICAgICAgICAgICBxdW90ZSA9IEYsIGNvbC5uYW1lcyA9IEYsIHJvdy5uYW1lcyA9IEYpDQoNCiMgQWN0aWdyYXBoeSBJRCdzDQoNCmFjY19pZCA8LSBkICU+JSANCiAgc2VsZWN0KGVpZCwgYDkwMDAxLTAuMGApICU+JSANCiAgZmlsdGVyKCFpcy5uYShgOTAwMDEtMC4wYCkpDQoNCndyaXRlLnRhYmxlKGFjY19pZCwgIi9ob21lL2xjcmkwMDA2L2JjNDEvVUtCX2RhdGEvYWNjZWxfaWQudHh0IiwNCiAgICAgICAgICAgIHF1b3RlID0gRiwgY29sLm5hbWVzID0gRiwgcm93Lm5hbWVzID0gRikNCg0KIyBmaXJzdCAxMDAgcm93cyBvZiBhY3RpZ3JhcGh5IGRhdGEgKHRlc3QpDQoNCnRlc3RfYWNjIDwtIGFjY19pZCAlPiUgDQogIHNsaWNlKDE6MTAwKQ0KDQp3cml0ZS50YWJsZSh0ZXN0X2FjYywgIi9ob21lL2xjcmkwMDA2L2JjNDEvVUtCX2RhdGEvYWNjZWxfdGVzdC50eHQiLA0KICAgICAgICAgICAgcXVvdGUgPSBGLCBjb2wubmFtZXMgPSBGLCByb3cubmFtZXMgPSBGKQ0KDQpgYGANCg0KDQoNCg0K