1 Functions

library(stringi)
source_from_github(repositoy = "DEG_functions",version = "0.2.47")
ℹ SHA-1 hash of file is f5bb1cd741d13bded83fe3b6fd43169e29731216
Welcome to enrichR
Checking connection ... 
Enrichr ... Connection is Live!
FlyEnrichr ... Connection is available!
WormEnrichr ... Connection is available!
YeastEnrichr ... Connection is available!
FishEnrichr ... Connection is available!
source_from_github(repositoy = "cNMF_functions",version = "0.4.0",script_name = "cnmf_functions_V3.R")
ℹ SHA-1 hash of file is 7b39dfd215cf7e1d29ee976ecc6bfa0e3f1532f6
Loading required package: reticulate
source_from_github(repositoy = "sc_general_functions",version = "0.1.28",script_name = "functions.R")
ℹ SHA-1 hash of file is 737683e4e0a82ffa22769bbd4a0842a271fe63fc
Loading required package: RColorBrewer

2 Data

library("readxl")
acc_all = readRDS(file = "./Data/acc_tpm_nCount_mito_no146_15k_alldata.rds")
acc_cancer_pri = readRDS(file = "./Data/acc_cancer_no146_primaryonly15k_cancercells.rds")
acc_cancer = readRDS(file = "./Data/acc_tpm_nCount_mito_no146_15k_cancercells.rds")


neuronal_signatures <- read_excel("./Data/Neuronal Signatures.xlsx",col_names =F)
neuronal_signatures  %<>%  t() %>% as.data.frame() %>% janitor::row_to_names(1) %>%  filter(!row_number() == 1)
rownames(neuronal_signatures) <- NULL
colnames(neuronal_signatures)   %<>%  gsub(replacement = "", pattern = "_\\d.*") #remove any _numbers
colnames(neuronal_signatures)   %<>%  gsub(replacement = "", pattern = "\\(.*") #rename "(" to the end
colnames(neuronal_signatures)   %<>%  gsub(replacement = "_", pattern = " ") #rename all spaces

neuronal_pathways <- read_excel("./Data/Pathway analysis Gene sets.xlsx",col_names =F)
neuronal_pathways  %<>%  t() %>% as.data.frame() %>% janitor::row_to_names(1) %>%  filter(!row_number() == 1)  %>%  as.list() 
neuronal_pathways = lapply(neuronal_pathways, na.omit)
neuronal_pathways = lapply(neuronal_pathways, as.character)

3 Neuronal signatures

3.1 Violin plots

for (neural_name in colnames(neuronal_signatures)) {
  genes = neuronal_signatures[,neural_name,drop=T]
  # Assuming df is your data frame

  
  pathways_scores = FetchData(object = acc_all,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = neural_name)
}

Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = “data”) : The following requested variables were not found: SNHG29, NOP53 Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = “data”) : The following requested variables were not found: NOP53 Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = “data”) : The following requested variables were not found: NOP53

plt = VlnPlot(object = acc_all,features = colnames(neuronal_signatures))
plt[[1]] = plt[[1]]+ ylab("TPM")
plt[[4]] = plt[[4]]+ ylab("TPM")
plt[[7]] = plt[[7]]+ ylab("TPM")
print_tab(plt = plt,title = "expression with RP genes",subtitle_num = 3)

expression with RP genes

NA

rp_genes = lapply(neuronal_signatures %>% as.list(),  function(x) {x[startsWith(x = x,prefix = "RP")]}) %>% unlist() %>% unique() %>% as.data.frame()
print_tab(rp_genes,title = " RP genes names",subtitle_num = 3)

RP genes names

NA

neuronal_signatures_no_RP = lapply(neuronal_signatures %>% as.list(),  function(x) {x[!startsWith(x = x,prefix = "RP")]})
names(neuronal_signatures_no_RP) =  paste0(names(neuronal_signatures_no_RP),"_noRP")
for (neural_name in names(neuronal_signatures_no_RP)) {
  genes = neuronal_signatures_no_RP[[neural_name]]
  # Assuming df is your data frame

  pathways_scores = FetchData(object = acc_all,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = neural_name)
}

plt = VlnPlot(object = acc_all,features = names(neuronal_signatures_no_RP))
for (i in 1:(length(plt$patches$plots)+1)) {

  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=12))
  if (i %in% c(1,4,7)) {
    plt[[i]] = plt[[i]]+ylab("TPM")
  }
}
print_tab(plt = plt,title = "expression without RP genes",subtitle_num = 3)

expression without RP genes

NA

3.2 UMAPS

plt1 = FeaturePlot(object = acc_all,features = colnames(neuronal_signatures))& theme(plot.title = element_text(size=13))
plt2 = FeaturePlot(object = acc_all,features = names(neuronal_signatures_no_RP)) & theme(plot.title = element_text(size=12))
print_tab(plt = plt1,title = "UMAP with RP",subtitle_num = 3)

UMAP with RP

print_tab(plt = plt2,title = "UMAP without RP",subtitle_num = 3)

UMAP without RP

NA

3.3 High Sympathetic_cholinergic_neuron

high_cholinergic_neuron = list( high_cholinergic_neuron = colnames(acc_all)[acc_all$Sympathetic_cholinergic_neuron_noRP>1000])
DimPlot(object = acc_all, cells.highlight = high_cholinergic_neuron, cols.highlight = "red", cols = "gray", order = TRUE)

4 Pathway comparison

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_cancer,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = paste0(pathway_name,"_TPM"))
}
for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_cancer,vars = genes,slot = "data") %>% 
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}
library(reshape2) 
data = FetchData(object = acc_cancer,vars = names(neuronal_pathways)[c(1:2,7,8)])
my.labels <- c("GOBP_NOREPINEPHRINE\nSECRETION",
               "GOBP_NOREPINEPHRINE\nTRANSPORT", 
               "GOBP_ADRENERGIC_RECEPTOR\nSIGNALING_PATHWAY",
               "GOMF_BETA_2_ADRENERGIC\nRECEPTOR_BINDING") 

data =  reshape2::melt(data)
No id variables; using all as measure variables
names (data) = c("pathway","log(TPM)")
ggboxplot(data, x = "pathway", y ="log(TPM)",
              palette = "jco",
              add = "jitter")+ theme( axis.text.x  = element_text(size=10))+
    stat_summary(fun.data = function(x) data.frame(y=5, label = paste("Mean=",round(mean(x),digits = 
                                    2))), geom="text")  + scale_x_discrete(labels = my.labels)+ggtitle("ACC cells pathways")

4.1 pathways UMAP

plt = FeaturePlot(object = acc_cancer,features = paste0(names(neuronal_pathways),"_TPM"),pt.size = 0.5) & theme(plot.title = element_text(size=10.5)) & labs(color='TPM') & scale_color_gradientn(colours = rainbow(5)) 
print_tab(plt,title = "TPM",subtitle_num = 3)

TPM

NA



plt1 = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways),pt.size = 0.5)&
  theme(plot.title = element_text(size=10.5)) & labs(color='log (TPM+1)') & scale_color_gradientn(colours = rainbow(5))

Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

plt2 = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways),pt.size = 0.5)&
  theme(plot.title = element_text(size=10.5)) & labs(color='log (TPM+1)')
print_tab(plt2,title = "log(TPM+1) ",subtitle_num = 3)

log(TPM+1)

print_tab(plt1,title = "log(TPM+1) rainbow",subtitle_num = 3)

log(TPM+1) rainbow

NA

5 Beta-2 receptor

5.1 UMAP

b2r_genes = c("RAF1", "PAMPK1", "PRKACA", "PIK3CA", "AKT1", "AKT2", "AKT3", "CREB1", "CREBBP", "BCL2", "BAD", "JUN", "FOS",  "MYC")
tpm_1 = FeaturePlot(object = acc_tpm,features = b2r_genes[1:9],pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')
tpm_2 = FeaturePlot(object = acc_tpm,features = b2r_genes[10:length(b2r_genes)],pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')

logTPM1 = FeaturePlot(object = acc_all,features = b2r_genes[1:9],pt.size = 0.5) & labs(color='log(TPM+1)')
logTPM2 = FeaturePlot(object = acc_all,features = b2r_genes[10:length(b2r_genes)]) & labs(color='log(TPM+1)')
print_tab(plt = tpm_1,title = "TPM part 1",subtitle_num = 3)

TPM part 1

print_tab(plt = tpm_2,title = "TPM part 2",subtitle_num = 3)

TPM part 2

print_tab(plt = logTPM1,title = "log TPM part 1",subtitle_num = 3)

log TPM part 1

print_tab(plt = logTPM2,title = "log TPM part 2",subtitle_num = 3)

log TPM part 2

NA

5.2 Signature

pathways_scores = FetchData(object = acc_all,vars = b2r_genes,slot = "data") %>% 
  mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature_TPM")

tpm = FeaturePlot(object = acc_all,features ="b2r_signature_TPM",pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')

Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

pathways_scores = FetchData(object = acc_all,vars = b2r_genes,slot = "data") %>% 
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature")

logTPM = FeaturePlot(object = acc_all,features ="b2r_signature",pt.size = 0.5,slot = "counts")  & labs(color='log TPM')

print_tab(plt = tpm,title = "TPM",subtitle_num = 3)

TPM

print_tab(plt = logTPM,title = "log TPM",subtitle_num = 3)

log TPM

NA

5.3 b2r with pathways TPM

pathways_scores = FetchData(object = acc_cancer,vars = b2r_genes,slot = "data") %>% 
  mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature_TPM")

FeaturePlot(object = acc_cancer,features = c("b2r_signature_TPM",paste0(names(neuronal_pathways)[c(1:2,7,8)],"_TPM")),pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')&
  theme(plot.title = element_text(size=10.5))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

5.4 b2r with pathways log(TPM+1)

pathways_scores = FetchData(object = acc_cancer,vars = b2r_genes,slot = "data") %>% 
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature")

FeaturePlot(object = acc_cancer,features = c("b2r_signature",names(neuronal_pathways)[c(1:2,7,8)]),pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='log (TPM+1)')&
  theme(plot.title = element_text(size=10.5))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

5.5 Correlation TPM




pathways_scores = FetchData(object = acc_cancer,vars = b2r_genes,slot = "data") %>% 
  mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
Warning in FetchData.Seurat(object = acc_cancer, vars = b2r_genes, slot = "data") :
  The following requested variables were not found: PAMPK1
acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature_TPM")


data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM",paste0(names(neuronal_pathways)[c(1:2,7,8)],"_TPM")))
cor_res = cor(data)
breaks <- c(seq(-1,1,by=0.01))
colors_for_plot <- colorRampPalette(colors = c("blue", "white", "red"))(n = length(breaks))

pheatmap(cor_res,color = colors_for_plot,breaks = breaks,display_numbers = T,main = "Pearson correlation of pathways") 

5.6 Correlation llog TPM

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_cancer,vars = genes,slot = "data") %>% 
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}

pathways_scores = FetchData(object = acc_cancer,vars = b2r_genes,slot = "data") %>% 
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature")


data = FetchData(object = acc_cancer,vars =  c("b2r_signature",names(neuronal_pathways)[c(1:2,7,8)]))
cor_res = cor(data)
breaks <- c(seq(-1,1,by=0.01))
colors_for_plot <- colorRampPalette(colors = c("blue", "white", "red"))(n = length(breaks))
pheatmap(cor_res,color = colors_for_plot,breaks = breaks,display_numbers = T,main = "Pearson correlation of pathways") 

6 Correlation all cancer cells

library(ggpubr)
data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM"))
p1 = ggplot(data, aes(x=b2r_signature_TPM, y=GOBP_NOREPINEPHRINE_TRANSPORT_TPM)) +  geom_smooth(method = lm)+
  geom_point()+ stat_cor(method = "pearson")

data = FetchData(object = acc_cancer,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT"))
p2 = ggplot(data, aes(x=b2r_signature, y=GOBP_NOREPINEPHRINE_TRANSPORT)) +  geom_smooth(method = lm)+
  geom_point()+ stat_cor(method = "pearson")
print_tab(p1,title = "TPM")

TPM

geom_smooth() using formula ‘y ~ x’

print_tab(p2,title = "log TPM")

log TPM

geom_smooth() using formula ‘y ~ x’

NA

7 Intra-patient correlation

library(ggpubr)

data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM","patient.ident"))
p1 = ggplot(data,
           aes(x = b2r_signature_TPM, y = GOBP_NOREPINEPHRINE_TRANSPORT_TPM)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson") + facet_wrap(~patient.ident,nrow = 2)

data = FetchData(object = acc_cancer,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT","patient.ident"))
p2 = ggplot(data,
           aes(x = b2r_signature, y = GOBP_NOREPINEPHRINE_TRANSPORT)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson") + facet_wrap(~patient.ident,nrow = 2)
print_tab(p1,title = "TPM")

TPM

geom_smooth() using formula ‘y ~ x’

print_tab(p2,title = "log TPM")

log TPM

geom_smooth() using formula ‘y ~ x’

print_tab(DimPlot(acc_cancer,group.by = "patient.ident"),title = "UMAP")

UMAP

NA

8 Intra-cluster correlation

data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM","seurat_clusters"))

data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM","seurat_clusters"))
p1 = ggplot(data,
           aes(x = b2r_signature_TPM, y = GOBP_NOREPINEPHRINE_TRANSPORT_TPM)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson") + facet_wrap(~seurat_clusters,nrow = 2)

data = FetchData(object = acc_cancer,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT","seurat_clusters"))
p2 = ggplot(data,
           aes(x = b2r_signature, y = GOBP_NOREPINEPHRINE_TRANSPORT)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson") + facet_wrap(~seurat_clusters,nrow = 2)
print_tab(p1,title = "TPM")

TPM

geom_smooth() using formula ‘y ~ x’

print_tab(p2,title = "log TPM")

log TPM

geom_smooth() using formula ‘y ~ x’

print_tab(DimPlot(acc_cancer,group.by = "seurat_clusters"),title = "UMAP")

UMAP

NA

9 Classification

data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM"))
b2r_thresh1 = 500
b2r_thresh2 = 1000

data %<>% mutate(b2r_level = case_when(
  b2r_signature_TPM <b2r_thresh1 ~ "low",
  b2r_signature_TPM >=b2r_thresh1 & b2r_signature_TPM <=b2r_thresh2 ~ "medium",
  b2r_signature_TPM > b2r_thresh2 ~ "high",
)) 

epi_thresh1 = 250
epi_thresh2 = 500
data %<>% mutate(epi_trans_level = case_when(
  GOBP_NOREPINEPHRINE_TRANSPORT_TPM <epi_thresh1 ~ "low",
  GOBP_NOREPINEPHRINE_TRANSPORT_TPM >=epi_thresh1 & GOBP_NOREPINEPHRINE_TRANSPORT_TPM <=epi_thresh2 ~ "medium",
  GOBP_NOREPINEPHRINE_TRANSPORT_TPM > epi_thresh2 ~ "high",
))

b2r low = b2r < 500

b2r medium= b2r >= 500 & <= 1000

b2r high= b2r < 1000

GOBP_NOREPINEPHRINE_TRANSPORT low = GOBP_NOREPINEPHRINE_TRANSPORT< 250

GOBP_NOREPINEPHRINE_TRANSPORTmedium= GOBP_NOREPINEPHRINE_TRANSPORT>= 500 & <= 500

GOBP_NOREPINEPHRINE_TRANSPORT low = GOBP_NOREPINEPHRINE_TRANSPORT< 500

data_to_test = data %>% select(c("b2r_level","epi_trans_level")) %>% filter(b2r_level %in% c("low","high") & epi_trans_level %in%  c("low","high"))
test = fisher.test(table(data_to_test))

library(ggstatsplot)

plt = ggbarstats(
  data_to_test,
  b2r_level,
  epi_trans_level,
  results.subtitle = FALSE,
  subtitle = paste0("Fisher's exact test", ", p-value = ",
                    round(test$p.value, 13))
)
plt

data_for_plot = table(data %>% select(c("b2r_level","epi_trans_level"))) %>% as.data.frame.matrix()
data_for_plot = data_for_plot[c("low","medium","high"),c("low","medium","high")]
colnames(data_for_plot) = c("epi_trans_low","epi_trans_medium","epi_trans_high")
rownames(data_for_plot) = c("b2r_low","b2r_medium","b2r_high")

pheatmap(data_for_plot,cluster_rows = F,cluster_cols = F)

10 Between-clusters correlation


data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM","seurat_clusters"))
average_data1  = data %>% group_by(seurat_clusters) %>%
    dplyr::summarize(b2r_mean = mean(b2r_signature_TPM, na.rm=TRUE))

average_data2  = data %>% group_by(seurat_clusters) %>%
    dplyr::summarize(epi_trans_mean = mean(GOBP_NOREPINEPHRINE_TRANSPORT_TPM, na.rm=TRUE))
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
average_all$seurat_clusters = paste("cluster",average_all$seurat_clusters)
library(ggrepel)
p = ggplot(average_all,
           aes(x = b2r_mean, y = epi_trans_mean, label=seurat_clusters)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson")+geom_text_repel()
print_tab(plt = p,title = "TPM")

TPM

geom_smooth() using formula ‘y ~ x’

NA

data = FetchData(object = acc_cancer,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT","seurat_clusters"))
average_data1  = data %>% group_by(seurat_clusters) %>%
    dplyr::summarize(b2r_mean = mean(b2r_signature, na.rm=TRUE))

average_data2  = data %>% group_by(seurat_clusters) %>%
    dplyr::summarize(epi_trans_mean = mean(GOBP_NOREPINEPHRINE_TRANSPORT, na.rm=TRUE))
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
average_all$seurat_clusters = paste("cluster",average_all$seurat_clusters)
library(ggrepel)
p = ggplot(average_all,
           aes(x = b2r_mean, y = epi_trans_mean, label=seurat_clusters)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson")+geom_text_repel()
print_tab(plt = p,title = "log TPM")

log TPM

geom_smooth() using formula ‘y ~ x’

NA

11 Between-patients correlation

data = FetchData(object = acc_cancer,vars =  c("b2r_signature_TPM","GOBP_NOREPINEPHRINE_TRANSPORT_TPM","patient.ident"))
average_data1  = data %>% group_by(patient.ident) %>%
    dplyr::summarize(b2r_mean = mean(b2r_signature_TPM, na.rm=TRUE))

average_data2  = data %>% group_by(patient.ident) %>%
    dplyr::summarize(epi_trans_mean = mean(GOBP_NOREPINEPHRINE_TRANSPORT_TPM, na.rm=TRUE))
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
library(ggrepel)
p = ggplot(average_all,
           aes(x = b2r_mean, y = epi_trans_mean, label=patient.ident)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson")+geom_text_repel()
print_tab(plt = p,title = "TPM")

TPM

geom_smooth() using formula ‘y ~ x’

data = FetchData(object = acc_cancer,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT","patient.ident"))
average_data1  = data %>% group_by(patient.ident) %>%
    dplyr::summarize(b2r_mean = mean(b2r_signature, na.rm=TRUE))

average_data2  = data %>% group_by(patient.ident) %>%
    dplyr::summarize(epi_trans_mean = mean(GOBP_NOREPINEPHRINE_TRANSPORT, na.rm=TRUE))
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
library(ggrepel)
p = ggplot(average_all,
           aes(x = b2r_mean, y = epi_trans_mean, label=patient.ident)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson")+geom_text_repel()
print_tab(plt = p,title = "log TPM")

log TPM

geom_smooth() using formula ‘y ~ x’

NA

12 Primary cancer cells


# add scores
pathways_scores = FetchData(object = acc_cancer_pri,vars = b2r_genes,slot = "data") %>% 
  mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_cancer_pri  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature_TPM")


pathways_scores = FetchData(object = acc_cancer_pri,vars = b2r_genes,slot = "data") %>% 
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
acc_cancer_pri  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature")

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_cancer_pri,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_cancer_pri  %<>% AddMetaData(metadata = pathways_scores$score,col.name = paste0(pathway_name,"_TPM"))
}

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_cancer_pri,vars = genes,slot = "data") %>% 
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_cancer_pri  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}
data = FetchData(object = acc_cancer_pri,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT","patient.ident"))
average_data1  = data %>% group_by(patient.ident) %>%
    dplyr::summarize(b2r_mean = mean(b2r_signature, na.rm=TRUE))

average_data2  = data %>% group_by(patient.ident) %>%
    dplyr::summarize(epi_trans_mean = mean(GOBP_NOREPINEPHRINE_TRANSPORT, na.rm=TRUE))
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
# average_all$patient.ident = paste("cluster",average_all$patient.ident)
library(ggrepel)
ggplot(average_all,
           aes(x = b2r_mean, y = epi_trans_mean, label=patient.ident)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson")+geom_text_repel()
`geom_smooth()` using formula 'y ~ x'

acc_cancer_pri <- FindNeighbors(acc_cancer_pri, dims = 1:10,verbose = F) %>%  FindClusters(resolution = 0.7) 
library(ggrepel)
data = FetchData(object = acc_cancer_pri,vars =  c("b2r_signature","GOBP_NOREPINEPHRINE_TRANSPORT","seurat_clusters"))
average_data1  = data %>% group_by(seurat_clusters) %>%
    dplyr::summarize(b2r_mean = mean(b2r_signature, na.rm=TRUE))

average_data2  = data %>% group_by(seurat_clusters) %>%
    dplyr::summarize(epi_trans_mean = mean(GOBP_NOREPINEPHRINE_TRANSPORT, na.rm=TRUE))
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
average_all$seurat_clusters = paste("cluster",average_all$seurat_clusters)
ggplot(average_all,
           aes(x = b2r_mean, y = epi_trans_mean, label=seurat_clusters)) +  geom_smooth(method = lm) +
  geom_point() + stat_cor(method = "pearson")+geom_text_repel()
DimPlot(acc_cancer_pri,group.by = "patient.ident")
DimPlot(acc_cancer_pri)
LS0tCnRpdGxlOiAiQW5hbHlzaXNfbWVldGluZ18xMV8xOSIKYXV0aG9yOiAiQXZpc2hhaSBXaXplbCIKZGF0ZTogJ2ByIFN5cy50aW1lKClgJwpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwogICAgdG9jX2NvbGxhcHNlOiB5ZXMKICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogRkFMU0UKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jX2RlcHRoOiAxCi0tLQoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoc3RyaW5naSkKc291cmNlX2Zyb21fZ2l0aHViKHJlcG9zaXRveSA9ICJERUdfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMi40NyIpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiY05NRl9mdW5jdGlvbnMiLHZlcnNpb24gPSAiMC40LjAiLHNjcmlwdF9uYW1lID0gImNubWZfZnVuY3Rpb25zX1YzLlIiKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gInNjX2dlbmVyYWxfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMS4yOCIsc2NyaXB0X25hbWUgPSAiZnVuY3Rpb25zLlIiKQpgYGAKCiMgRGF0YQoKYGBge3J9CmxpYnJhcnkoInJlYWR4bCIpCmFjY19hbGwgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX2FsbGRhdGEucmRzIikKYWNjX2NhbmNlcl9wcmkgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY19jYW5jZXJfbm8xNDZfcHJpbWFyeW9ubHkxNWtfY2FuY2VyY2VsbHMucmRzIikKYWNjX2NhbmNlciA9IHJlYWRSRFMoZmlsZSA9ICIuL0RhdGEvYWNjX3RwbV9uQ291bnRfbWl0b19ubzE0Nl8xNWtfY2FuY2VyY2VsbHMucmRzIikKCgpuZXVyb25hbF9zaWduYXR1cmVzIDwtIHJlYWRfZXhjZWwoIi4vRGF0YS9OZXVyb25hbCBTaWduYXR1cmVzLnhsc3giLGNvbF9uYW1lcyA9RikKbmV1cm9uYWxfc2lnbmF0dXJlcyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpCnJvd25hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpIDwtIE5VTEwKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiX1xcZC4qIikgI3JlbW92ZSBhbnkgX251bWJlcnMKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiXFwoLioiKSAjcmVuYW1lICIoIiB0byB0aGUgZW5kCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICJfIiwgcGF0dGVybiA9ICIgIikgI3JlbmFtZSBhbGwgc3BhY2VzCgpuZXVyb25hbF9wYXRod2F5cyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvUGF0aHdheSBhbmFseXNpcyBHZW5lIHNldHMueGxzeCIsY29sX25hbWVzID1GKQpuZXVyb25hbF9wYXRod2F5cyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpICAlPiUgIGFzLmxpc3QoKSAKbmV1cm9uYWxfcGF0aHdheXMgPSBsYXBwbHkobmV1cm9uYWxfcGF0aHdheXMsIG5hLm9taXQpCm5ldXJvbmFsX3BhdGh3YXlzID0gbGFwcGx5KG5ldXJvbmFsX3BhdGh3YXlzLCBhcy5jaGFyYWN0ZXIpCgpgYGAKCiMgTmV1cm9uYWwgc2lnbmF0dXJlcwoKIyMgVmlvbGluIHBsb3RzIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNbLG5ldXJhbF9uYW1lLGRyb3A9VF0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQoKICAKICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCiAgYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IG5ldXJhbF9uYW1lKQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCByZXN1bHRzPSdhc2lzJ30KcGx0ID0gVmxuUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpCnBsdFtbMV1dID0gcGx0W1sxXV0rIHlsYWIoIlRQTSIpCnBsdFtbNF1dID0gcGx0W1s0XV0rIHlsYWIoIlRQTSIpCnBsdFtbN11dID0gcGx0W1s3XV0rIHlsYWIoIlRQTSIpCnByaW50X3RhYihwbHQgPSBwbHQsdGl0bGUgPSAiZXhwcmVzc2lvbiB3aXRoIFJQIGdlbmVzIixzdWJ0aXRsZV9udW0gPSAzKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgcmVzdWx0cz0nYXNpcyd9CnJwX2dlbmVzID0gbGFwcGx5KG5ldXJvbmFsX3NpZ25hdHVyZXMgJT4lIGFzLmxpc3QoKSwgIGZ1bmN0aW9uKHgpIHt4W3N0YXJ0c1dpdGgoeCA9IHgscHJlZml4ID0gIlJQIildfSkgJT4lIHVubGlzdCgpICU+JSB1bmlxdWUoKSAlPiUgYXMuZGF0YS5mcmFtZSgpCnByaW50X3RhYihycF9nZW5lcyx0aXRsZSA9ICIgUlAgZ2VuZXMgbmFtZXMiLHN1YnRpdGxlX251bSA9IDMpCgoKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTIsIHJlc3VsdHM9J2FzaXMnfQpuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQID0gbGFwcGx5KG5ldXJvbmFsX3NpZ25hdHVyZXMgJT4lIGFzLmxpc3QoKSwgIGZ1bmN0aW9uKHgpIHt4WyFzdGFydHNXaXRoKHggPSB4LHByZWZpeCA9ICJSUCIpXX0pCm5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApID0gIHBhc3RlMChuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSwiX25vUlAiKQpmb3IgKG5ldXJhbF9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQW1tuZXVyYWxfbmFtZV1dCiAgIyBBc3N1bWluZyBkZiBpcyB5b3VyIGRhdGEgZnJhbWUKCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19hbGwsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBuZXVyYWxfbmFtZSkKfQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgcmVzdWx0cz0nYXNpcyd9CgpwbHQgPSBWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKCiAgcGx0W1tpXV0gPSBwbHRbW2ldXSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCiAgaWYgKGkgJWluJSBjKDEsNCw3KSkgewogICAgcGx0W1tpXV0gPSBwbHRbW2ldXSt5bGFiKCJUUE0iKQogIH0KfQpwcmludF90YWIocGx0ID0gcGx0LHRpdGxlID0gImV4cHJlc3Npb24gd2l0aG91dCBSUCBnZW5lcyIsc3VidGl0bGVfbnVtID0gMykKYGBgCgojIyBVTUFQUyB7LnRhYnNldH0KCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgcmVzdWx0cz0nYXNpcyd9CnBsdDEgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpJiB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTMpKQpwbHQyID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApKSAmIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCnByaW50X3RhYihwbHQgPSBwbHQxLHRpdGxlID0gIlVNQVAgd2l0aCBSUCIsc3VidGl0bGVfbnVtID0gMykKcHJpbnRfdGFiKHBsdCA9IHBsdDIsdGl0bGUgPSAiVU1BUCB3aXRob3V0IFJQIixzdWJ0aXRsZV9udW0gPSAzKQoKYGBgCgojIyBIaWdoIFN5bXBhdGhldGljX2Nob2xpbmVyZ2ljX25ldXJvbgoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCByZXN1bHRzPSdhc2lzJ30KaGlnaF9jaG9saW5lcmdpY19uZXVyb24gPSBsaXN0KCBoaWdoX2Nob2xpbmVyZ2ljX25ldXJvbiA9IGNvbG5hbWVzKGFjY19hbGwpW2FjY19hbGwkU3ltcGF0aGV0aWNfY2hvbGluZXJnaWNfbmV1cm9uX25vUlA+MTAwMF0pCkRpbVBsb3Qob2JqZWN0ID0gYWNjX2FsbCwgY2VsbHMuaGlnaGxpZ2h0ID0gaGlnaF9jaG9saW5lcmdpY19uZXVyb24sIGNvbHMuaGlnaGxpZ2h0ID0gInJlZCIsIGNvbHMgPSAiZ3JheSIsIG9yZGVyID0gVFJVRSkKCmBgYAoKIyBQYXRod2F5IGNvbXBhcmlzb24KCmBgYHtyfQpmb3IgKHBhdGh3YXlfbmFtZSBpbiBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3BhdGh3YXlzW1twYXRod2F5X25hbWVdXQogIHBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSBnZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gcGFzdGUwKHBhdGh3YXlfbmFtZSwiX1RQTSIpKQp9CmBgYAoKYGBge3Igd2FybmluZz1GQUxTRX0KZm9yIChwYXRod2F5X25hbWUgaW4gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9wYXRod2F5c1tbcGF0aHdheV9uYW1lXV0KICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19jYW5jZXIgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBwYXRod2F5X25hbWUpCn0KYGBgCgpgYGB7ciBmaWcud2lkdGg9MTB9CmxpYnJhcnkocmVzaGFwZTIpIApkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKVtjKDE6Miw3LDgpXSkKbXkubGFiZWxzIDwtIGMoIkdPQlBfTk9SRVBJTkVQSFJJTkVcblNFQ1JFVElPTiIsCiAgICAgICAgICAgICAgICJHT0JQX05PUkVQSU5FUEhSSU5FXG5UUkFOU1BPUlQiLCAKICAgICAgICAgICAgICAgIkdPQlBfQURSRU5FUkdJQ19SRUNFUFRPUlxuU0lHTkFMSU5HX1BBVEhXQVkiLAogICAgICAgICAgICAgICAiR09NRl9CRVRBXzJfQURSRU5FUkdJQ1xuUkVDRVBUT1JfQklORElORyIpIAoKZGF0YSA9ICByZXNoYXBlMjo6bWVsdChkYXRhKQpuYW1lcyAoZGF0YSkgPSBjKCJwYXRod2F5IiwibG9nKFRQTSkiKQpnZ2JveHBsb3QoZGF0YSwgeCA9ICJwYXRod2F5IiwgeSA9ImxvZyhUUE0pIiwKICAgICAgICAgICAgICBwYWxldHRlID0gImpjbyIsCiAgICAgICAgICAgICAgYWRkID0gImppdHRlciIpKyB0aGVtZSggYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSsKICAgIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGZ1bmN0aW9uKHgpIGRhdGEuZnJhbWUoeT01LCBsYWJlbCA9IHBhc3RlKCJNZWFuPSIscm91bmQobWVhbih4KSxkaWdpdHMgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMikpKSwgZ2VvbT0idGV4dCIpICArIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gbXkubGFiZWxzKStnZ3RpdGxlKCJBQ0MgY2VsbHMgcGF0aHdheXMiKQoKYGBgCgojIyBwYXRod2F5cyBVTUFQIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTE1LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KcGx0ID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IHBhc3RlMChuYW1lcyhuZXVyb25hbF9wYXRod2F5cyksIl9UUE0iKSxwdC5zaXplID0gMC41KSAmIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMC41KSkgJiBsYWJzKGNvbG9yPSdUUE0nKSAmIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gcmFpbmJvdyg1KSkgCmBgYAoKYGBge3IgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTE1LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKHBsdCx0aXRsZSA9ICJUUE0iLHN1YnRpdGxlX251bSA9IDMpCmBgYAoKYGBge3IgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTE1LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KCgpwbHQxID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSxwdC5zaXplID0gMC41KSYKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpICYgbGFicyhjb2xvcj0nbG9nIChUUE0rMSknKSAmIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gcmFpbmJvdyg1KSkKCgpwbHQyID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSxwdC5zaXplID0gMC41KSYKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpICYgbGFicyhjb2xvcj0nbG9nIChUUE0rMSknKQoKCgpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTUsIGZpZy53aWR0aD0xNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CnByaW50X3RhYihwbHQyLHRpdGxlID0gImxvZyhUUE0rMSkgIixzdWJ0aXRsZV9udW0gPSAzKQpwcmludF90YWIocGx0MSx0aXRsZSA9ICJsb2coVFBNKzEpIHJhaW5ib3ciLHN1YnRpdGxlX251bSA9IDMpCgpgYGAKCiMgQmV0YS0yIHJlY2VwdG9yCgojIyBVTUFQIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTE1LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KYjJyX2dlbmVzID0gYygiUkFGMSIsICJQQU1QSzEiLCAiUFJLQUNBIiwgIlBJSzNDQSIsICJBS1QxIiwgIkFLVDIiLCAiQUtUMyIsICJDUkVCMSIsICJDUkVCQlAiLCAiQkNMMiIsICJCQUQiLCAiSlVOIiwgIkZPUyIsICAiTVlDIikKdHBtXzEgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfdHBtLGZlYXR1cmVzID0gYjJyX2dlbmVzWzE6OV0scHQuc2l6ZSA9IDAuNSxzbG90ID0gImNvdW50cyIpICYgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDUpKSAmIGxhYnMoY29sb3I9J1RQTScpCnRwbV8yID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX3RwbSxmZWF0dXJlcyA9IGIycl9nZW5lc1sxMDpsZW5ndGgoYjJyX2dlbmVzKV0scHQuc2l6ZSA9IDAuNSxzbG90ID0gImNvdW50cyIpICYgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDUpKSAmIGxhYnMoY29sb3I9J1RQTScpCgpsb2dUUE0xID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IGIycl9nZW5lc1sxOjldLHB0LnNpemUgPSAwLjUpICYgbGFicyhjb2xvcj0nbG9nKFRQTSsxKScpCmxvZ1RQTTIgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gYjJyX2dlbmVzWzEwOmxlbmd0aChiMnJfZ2VuZXMpXSkgJiBsYWJzKGNvbG9yPSdsb2coVFBNKzEpJykKCgpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTUsIGZpZy53aWR0aD0xNSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CnByaW50X3RhYihwbHQgPSB0cG1fMSx0aXRsZSA9ICJUUE0gcGFydCAxIixzdWJ0aXRsZV9udW0gPSAzKQpwcmludF90YWIocGx0ID0gdHBtXzIsdGl0bGUgPSAiVFBNIHBhcnQgMiIsc3VidGl0bGVfbnVtID0gMykKcHJpbnRfdGFiKHBsdCA9IGxvZ1RQTTEsdGl0bGUgPSAibG9nIFRQTSBwYXJ0IDEiLHN1YnRpdGxlX251bSA9IDMpCnByaW50X3RhYihwbHQgPSBsb2dUUE0yLHRpdGxlID0gImxvZyBUUE0gcGFydCAyIixzdWJ0aXRsZV9udW0gPSAzKQpgYGAKCiMjIFNpZ25hdHVyZSB7LnRhYnNldH0KCmBgYHtyIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQpwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gYjJyX2dlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCmFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSAiYjJyX3NpZ25hdHVyZV9UUE0iKQoKdHBtID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9ImIycl9zaWduYXR1cmVfVFBNIixwdC5zaXplID0gMC41LHNsb3QgPSAiY291bnRzIikgJiBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IHJhaW5ib3coNSkpICYgbGFicyhjb2xvcj0nVFBNJykKCnBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfYWxsLHZhcnMgPSBiMnJfZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9ICJiMnJfc2lnbmF0dXJlIikKCmxvZ1RQTSA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSJiMnJfc2lnbmF0dXJlIixwdC5zaXplID0gMC41LHNsb3QgPSAiY291bnRzIikgICYgbGFicyhjb2xvcj0nbG9nIFRQTScpCgpwcmludF90YWIocGx0ID0gdHBtLHRpdGxlID0gIlRQTSIsc3VidGl0bGVfbnVtID0gMykKcHJpbnRfdGFiKHBsdCA9IGxvZ1RQTSx0aXRsZSA9ICJsb2cgVFBNIixzdWJ0aXRsZV9udW0gPSAzKQpgYGAKCiMjIGIyciB3aXRoIHBhdGh3YXlzIFRQTQoKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTgsIHdhcm5pbmc9RkFMU0V9CnBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSBiMnJfZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KYWNjX2NhbmNlciAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9ICJiMnJfc2lnbmF0dXJlX1RQTSIpCgpGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gYygiYjJyX3NpZ25hdHVyZV9UUE0iLHBhc3RlMChuYW1lcyhuZXVyb25hbF9wYXRod2F5cylbYygxOjIsNyw4KV0sIl9UUE0iKSkscHQuc2l6ZSA9IDAuNSxzbG90ID0gImNvdW50cyIpICYgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDUpKSAmIGxhYnMoY29sb3I9J1RQTScpJgogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMC41KSkKYGBgCgojIyBiMnIgd2l0aCBwYXRod2F5cyBsb2coVFBNKzEpCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9OCwgd2FybmluZz1GQUxTRX0KcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9IGIycl9nZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgphY2NfY2FuY2VyICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gImIycl9zaWduYXR1cmUiKQoKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IGMoImIycl9zaWduYXR1cmUiLG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKVtjKDE6Miw3LDgpXSkscHQuc2l6ZSA9IDAuNSxzbG90ID0gImNvdW50cyIpICYgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDUpKSAmIGxhYnMoY29sb3I9J2xvZyAoVFBNKzEpJykmCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKQpgYGAKCiMjIENvcnJlbGF0aW9uIFRQTQoKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQoKCgpwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gYjJyX2dlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCmFjY19jYW5jZXIgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSAiYjJyX3NpZ25hdHVyZV9UUE0iKQoKCmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gIGMoImIycl9zaWduYXR1cmVfVFBNIixwYXN0ZTAobmFtZXMobmV1cm9uYWxfcGF0aHdheXMpW2MoMToyLDcsOCldLCJfVFBNIikpKQpjb3JfcmVzID0gY29yKGRhdGEpCmJyZWFrcyA8LSBjKHNlcSgtMSwxLGJ5PTAuMDEpKQpjb2xvcnNfZm9yX3Bsb3QgPC0gY29sb3JSYW1wUGFsZXR0ZShjb2xvcnMgPSBjKCJibHVlIiwgIndoaXRlIiwgInJlZCIpKShuID0gbGVuZ3RoKGJyZWFrcykpCgpwaGVhdG1hcChjb3JfcmVzLGNvbG9yID0gY29sb3JzX2Zvcl9wbG90LGJyZWFrcyA9IGJyZWFrcyxkaXNwbGF5X251bWJlcnMgPSBULG1haW4gPSAiUGVhcnNvbiBjb3JyZWxhdGlvbiBvZiBwYXRod2F5cyIpIApgYGAKCiMjIENvcnJlbGF0aW9uIGxsb2cgVFBNCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTB9CmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gcGF0aHdheV9uYW1lKQp9CgpwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gYjJyX2dlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCmFjY19jYW5jZXIgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSAiYjJyX3NpZ25hdHVyZSIpCgoKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZSIsbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpW2MoMToyLDcsOCldKSkKY29yX3JlcyA9IGNvcihkYXRhKQpicmVha3MgPC0gYyhzZXEoLTEsMSxieT0wLjAxKSkKY29sb3JzX2Zvcl9wbG90IDwtIGNvbG9yUmFtcFBhbGV0dGUoY29sb3JzID0gYygiYmx1ZSIsICJ3aGl0ZSIsICJyZWQiKSkobiA9IGxlbmd0aChicmVha3MpKQoKCmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQpwaGVhdG1hcChjb3JfcmVzLGNvbG9yID0gY29sb3JzX2Zvcl9wbG90LGJyZWFrcyA9IGJyZWFrcyxkaXNwbGF5X251bWJlcnMgPSBULG1haW4gPSAiUGVhcnNvbiBjb3JyZWxhdGlvbiBvZiBwYXRod2F5cyIpIApgYGAKCiMgQ29ycmVsYXRpb24gYWxsIGNhbmNlciBjZWxscyB7LnRhYnNldH0KCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZV9UUE0iLCJHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVF9UUE0iKSkKcDEgPSBnZ3Bsb3QoZGF0YSwgYWVzKHg9YjJyX3NpZ25hdHVyZV9UUE0sIHk9R09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlRfVFBNKSkgKyAgZ2VvbV9zbW9vdGgobWV0aG9kID0gbG0pKwogIGdlb21fcG9pbnQoKSsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKQoKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUIikpCnAyID0gZ2dwbG90KGRhdGEsIGFlcyh4PWIycl9zaWduYXR1cmUsIHk9R09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkrCiAgZ2VvbV9wb2ludCgpKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpCmBgYAoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CnByaW50X3RhYihwMSx0aXRsZSA9ICJUUE0iKQpwcmludF90YWIocDIsdGl0bGUgPSAibG9nIFRQTSIpCmBgYAoKIyBJbnRyYS1wYXRpZW50IGNvcnJlbGF0aW9uIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTIscmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoZ2dwdWJyKQoKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZV9UUE0iLCJHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVF9UUE0iLCJwYXRpZW50LmlkZW50IikpCnAxID0gZ2dwbG90KGRhdGEsCiAgICAgICAgICAgYWVzKHggPSBiMnJfc2lnbmF0dXJlX1RQTSwgeSA9IEdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUX1RQTSkpICsgIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtKSArCiAgZ2VvbV9wb2ludCgpICsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKSArIGZhY2V0X3dyYXAofnBhdGllbnQuaWRlbnQsbnJvdyA9IDIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9ICBjKCJiMnJfc2lnbmF0dXJlIiwiR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQiLCJwYXRpZW50LmlkZW50IikpCnAyID0gZ2dwbG90KGRhdGEsCiAgICAgICAgICAgYWVzKHggPSBiMnJfc2lnbmF0dXJlLCB5ID0gR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikgKyBmYWNldF93cmFwKH5wYXRpZW50LmlkZW50LG5yb3cgPSAyKQpwcmludF90YWIocDEsdGl0bGUgPSAiVFBNIikKcHJpbnRfdGFiKHAyLHRpdGxlID0gImxvZyBUUE0iKQpwcmludF90YWIoRGltUGxvdChhY2NfY2FuY2VyLGdyb3VwLmJ5ID0gInBhdGllbnQuaWRlbnQiKSx0aXRsZSA9ICJVTUFQIikKCmBgYAoKIyBJbnRyYS1jbHVzdGVyIGNvcnJlbGF0aW9uIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTIscmVzdWx0cz0nYXNpcyd9CmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gIGMoImIycl9zaWduYXR1cmVfVFBNIiwiR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlRfVFBNIiwic2V1cmF0X2NsdXN0ZXJzIikpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9ICBjKCJiMnJfc2lnbmF0dXJlX1RQTSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUX1RQTSIsInNldXJhdF9jbHVzdGVycyIpKQpwMSA9IGdncGxvdChkYXRhLAogICAgICAgICAgIGFlcyh4ID0gYjJyX3NpZ25hdHVyZV9UUE0sIHkgPSBHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVF9UUE0pKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikgKyBmYWNldF93cmFwKH5zZXVyYXRfY2x1c3RlcnMsbnJvdyA9IDIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9ICBjKCJiMnJfc2lnbmF0dXJlIiwiR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQiLCJzZXVyYXRfY2x1c3RlcnMiKSkKcDIgPSBnZ3Bsb3QoZGF0YSwKICAgICAgICAgICBhZXMoeCA9IGIycl9zaWduYXR1cmUsIHkgPSBHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVCkpICsgIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtKSArCiAgZ2VvbV9wb2ludCgpICsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKSArIGZhY2V0X3dyYXAofnNldXJhdF9jbHVzdGVycyxucm93ID0gMikKcHJpbnRfdGFiKHAxLHRpdGxlID0gIlRQTSIpCnByaW50X3RhYihwMix0aXRsZSA9ICJsb2cgVFBNIikKcHJpbnRfdGFiKERpbVBsb3QoYWNjX2NhbmNlcixncm91cC5ieSA9ICJzZXVyYXRfY2x1c3RlcnMiKSx0aXRsZSA9ICJVTUFQIikKCmBgYAoKIyBDbGFzc2lmaWNhdGlvbgoKYGBge3IgZWNobz1UUlVFLGNvbGxhcHNlPUZ9CmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gIGMoImIycl9zaWduYXR1cmVfVFBNIiwiR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlRfVFBNIikpCmIycl90aHJlc2gxID0gNTAwCmIycl90aHJlc2gyID0gMTAwMAoKZGF0YSAlPD4lIG11dGF0ZShiMnJfbGV2ZWwgPSBjYXNlX3doZW4oCiAgYjJyX3NpZ25hdHVyZV9UUE0gPGIycl90aHJlc2gxIH4gImxvdyIsCiAgYjJyX3NpZ25hdHVyZV9UUE0gPj1iMnJfdGhyZXNoMSAmIGIycl9zaWduYXR1cmVfVFBNIDw9YjJyX3RocmVzaDIgfiAibWVkaXVtIiwKICBiMnJfc2lnbmF0dXJlX1RQTSA+IGIycl90aHJlc2gyIH4gImhpZ2giLAopKSAKCmVwaV90aHJlc2gxID0gMjUwCmVwaV90aHJlc2gyID0gNTAwCmRhdGEgJTw+JSBtdXRhdGUoZXBpX3RyYW5zX2xldmVsID0gY2FzZV93aGVuKAogIEdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUX1RQTSA8ZXBpX3RocmVzaDEgfiAibG93IiwKICBHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVF9UUE0gPj1lcGlfdGhyZXNoMSAmIEdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUX1RQTSA8PWVwaV90aHJlc2gyIH4gIm1lZGl1bSIsCiAgR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlRfVFBNID4gZXBpX3RocmVzaDIgfiAiaGlnaCIsCikpCmBgYAoKYGAgYjJyIGxvdyA9IGIyciA8IGByIGIycl90aHJlc2gxYCBgYAoKYGAgYjJyIG1lZGl1bT0gYjJyID49IGByIGIycl90aHJlc2gxYCAmIDw9IGByIGIycl90aHJlc2gyYCBgYAoKYGAgYjJyIGhpZ2g9IGIyciA8IGByIGIycl90aHJlc2gyYCBgYAoKYGAgR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQgbG93ID0gR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQ8IGByIGVwaV90aHJlc2gxYCBgYAoKYGAgR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlRtZWRpdW09IEdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUPj0gYHIgYjJyX3RocmVzaDFgICYgPD0gYHIgZXBpX3RocmVzaDJgIGBgCgpgYCBHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVCBsb3cgPSBHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVDwgYHIgZXBpX3RocmVzaDJgIGBgCgpgYGB7ciBlY2hvPVRSVUUsY29sbGFwc2U9Rn0KZGF0YV90b190ZXN0ID0gZGF0YSAlPiUgc2VsZWN0KGMoImIycl9sZXZlbCIsImVwaV90cmFuc19sZXZlbCIpKSAlPiUgZmlsdGVyKGIycl9sZXZlbCAlaW4lIGMoImxvdyIsImhpZ2giKSAmIGVwaV90cmFuc19sZXZlbCAlaW4lICBjKCJsb3ciLCJoaWdoIikpCnRlc3QgPSBmaXNoZXIudGVzdCh0YWJsZShkYXRhX3RvX3Rlc3QpKQoKbGlicmFyeShnZ3N0YXRzcGxvdCkKCnBsdCA9IGdnYmFyc3RhdHMoCiAgZGF0YV90b190ZXN0LAogIGIycl9sZXZlbCwKICBlcGlfdHJhbnNfbGV2ZWwsCiAgcmVzdWx0cy5zdWJ0aXRsZSA9IEZBTFNFLAogIHN1YnRpdGxlID0gcGFzdGUwKCJGaXNoZXIncyBleGFjdCB0ZXN0IiwgIiwgcC12YWx1ZSA9ICIsCiAgICAgICAgICAgICAgICAgICAgcm91bmQodGVzdCRwLnZhbHVlLCAxMykpCikKcGx0CmBgYAoKYGBge3J9CmRhdGFfZm9yX3Bsb3QgPSB0YWJsZShkYXRhICU+JSBzZWxlY3QoYygiYjJyX2xldmVsIiwiZXBpX3RyYW5zX2xldmVsIikpKSAlPiUgYXMuZGF0YS5mcmFtZS5tYXRyaXgoKQpkYXRhX2Zvcl9wbG90ID0gZGF0YV9mb3JfcGxvdFtjKCJsb3ciLCJtZWRpdW0iLCJoaWdoIiksYygibG93IiwibWVkaXVtIiwiaGlnaCIpXQpjb2xuYW1lcyhkYXRhX2Zvcl9wbG90KSA9IGMoImVwaV90cmFuc19sb3ciLCJlcGlfdHJhbnNfbWVkaXVtIiwiZXBpX3RyYW5zX2hpZ2giKQpyb3duYW1lcyhkYXRhX2Zvcl9wbG90KSA9IGMoImIycl9sb3ciLCJiMnJfbWVkaXVtIiwiYjJyX2hpZ2giKQoKcGhlYXRtYXAoZGF0YV9mb3JfcGxvdCxjbHVzdGVyX3Jvd3MgPSBGLGNsdXN0ZXJfY29scyA9IEYpCmBgYAoKIyBCZXR3ZWVuLWNsdXN0ZXJzIGNvcnJlbGF0aW9uIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9ICBjKCJiMnJfc2lnbmF0dXJlX1RQTSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUX1RQTSIsInNldXJhdF9jbHVzdGVycyIpKQphdmVyYWdlX2RhdGExICA9IGRhdGEgJT4lIGdyb3VwX2J5KHNldXJhdF9jbHVzdGVycykgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGIycl9tZWFuID0gbWVhbihiMnJfc2lnbmF0dXJlX1RQTSwgbmEucm09VFJVRSkpCgphdmVyYWdlX2RhdGEyICA9IGRhdGEgJT4lIGdyb3VwX2J5KHNldXJhdF9jbHVzdGVycykgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGVwaV90cmFuc19tZWFuID0gbWVhbihHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVF9UUE0sIG5hLnJtPVRSVUUpKQphdmVyYWdlX2FsbCA9IGNiaW5kKGF2ZXJhZ2VfZGF0YTEsYXZlcmFnZV9kYXRhMikKYXZlcmFnZV9hbGwgPSBhdmVyYWdlX2FsbFssYygtMSldCmF2ZXJhZ2VfYWxsJHNldXJhdF9jbHVzdGVycyA9IHBhc3RlKCJjbHVzdGVyIixhdmVyYWdlX2FsbCRzZXVyYXRfY2x1c3RlcnMpCmxpYnJhcnkoZ2dyZXBlbCkKcCA9IGdncGxvdChhdmVyYWdlX2FsbCwKICAgICAgICAgICBhZXMoeCA9IGIycl9tZWFuLCB5ID0gZXBpX3RyYW5zX21lYW4sIGxhYmVsPXNldXJhdF9jbHVzdGVycykpICsgIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtKSArCiAgZ2VvbV9wb2ludCgpICsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKStnZW9tX3RleHRfcmVwZWwoKQpwcmludF90YWIocGx0ID0gcCx0aXRsZSA9ICJUUE0iKQpgYGAKCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9ICBjKCJiMnJfc2lnbmF0dXJlIiwiR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQiLCJzZXVyYXRfY2x1c3RlcnMiKSkKYXZlcmFnZV9kYXRhMSAgPSBkYXRhICU+JSBncm91cF9ieShzZXVyYXRfY2x1c3RlcnMpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShiMnJfbWVhbiA9IG1lYW4oYjJyX3NpZ25hdHVyZSwgbmEucm09VFJVRSkpCgphdmVyYWdlX2RhdGEyICA9IGRhdGEgJT4lIGdyb3VwX2J5KHNldXJhdF9jbHVzdGVycykgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGVwaV90cmFuc19tZWFuID0gbWVhbihHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVCwgbmEucm09VFJVRSkpCmF2ZXJhZ2VfYWxsID0gY2JpbmQoYXZlcmFnZV9kYXRhMSxhdmVyYWdlX2RhdGEyKQphdmVyYWdlX2FsbCA9IGF2ZXJhZ2VfYWxsWyxjKC0xKV0KYXZlcmFnZV9hbGwkc2V1cmF0X2NsdXN0ZXJzID0gcGFzdGUoImNsdXN0ZXIiLGF2ZXJhZ2VfYWxsJHNldXJhdF9jbHVzdGVycykKbGlicmFyeShnZ3JlcGVsKQpwID0gZ2dwbG90KGF2ZXJhZ2VfYWxsLAogICAgICAgICAgIGFlcyh4ID0gYjJyX21lYW4sIHkgPSBlcGlfdHJhbnNfbWVhbiwgbGFiZWw9c2V1cmF0X2NsdXN0ZXJzKSkgKyAgZ2VvbV9zbW9vdGgobWV0aG9kID0gbG0pICsKICBnZW9tX3BvaW50KCkgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpK2dlb21fdGV4dF9yZXBlbCgpCnByaW50X3RhYihwbHQgPSBwLHRpdGxlID0gImxvZyBUUE0iKQpgYGAKCiMgQmV0d2Vlbi1wYXRpZW50cyBjb3JyZWxhdGlvbiB7LnRhYnNldH0KCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9ICBjKCJiMnJfc2lnbmF0dXJlX1RQTSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUX1RQTSIsInBhdGllbnQuaWRlbnQiKSkKYXZlcmFnZV9kYXRhMSAgPSBkYXRhICU+JSBncm91cF9ieShwYXRpZW50LmlkZW50KSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUoYjJyX21lYW4gPSBtZWFuKGIycl9zaWduYXR1cmVfVFBNLCBuYS5ybT1UUlVFKSkKCmF2ZXJhZ2VfZGF0YTIgID0gZGF0YSAlPiUgZ3JvdXBfYnkocGF0aWVudC5pZGVudCkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGVwaV90cmFuc19tZWFuID0gbWVhbihHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVF9UUE0sIG5hLnJtPVRSVUUpKQphdmVyYWdlX2FsbCA9IGNiaW5kKGF2ZXJhZ2VfZGF0YTEsYXZlcmFnZV9kYXRhMikKYXZlcmFnZV9hbGwgPSBhdmVyYWdlX2FsbFssYygtMSldCmxpYnJhcnkoZ2dyZXBlbCkKcCA9IGdncGxvdChhdmVyYWdlX2FsbCwKICAgICAgICAgICBhZXMoeCA9IGIycl9tZWFuLCB5ID0gZXBpX3RyYW5zX21lYW4sIGxhYmVsPXBhdGllbnQuaWRlbnQpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKcHJpbnRfdGFiKHBsdCA9IHAsdGl0bGUgPSAiVFBNIikKCgoKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUIiwicGF0aWVudC5pZGVudCIpKQphdmVyYWdlX2RhdGExICA9IGRhdGEgJT4lIGdyb3VwX2J5KHBhdGllbnQuaWRlbnQpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShiMnJfbWVhbiA9IG1lYW4oYjJyX3NpZ25hdHVyZSwgbmEucm09VFJVRSkpCgphdmVyYWdlX2RhdGEyICA9IGRhdGEgJT4lIGdyb3VwX2J5KHBhdGllbnQuaWRlbnQpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShlcGlfdHJhbnNfbWVhbiA9IG1lYW4oR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQsIG5hLnJtPVRSVUUpKQphdmVyYWdlX2FsbCA9IGNiaW5kKGF2ZXJhZ2VfZGF0YTEsYXZlcmFnZV9kYXRhMikKYXZlcmFnZV9hbGwgPSBhdmVyYWdlX2FsbFssYygtMSldCmxpYnJhcnkoZ2dyZXBlbCkKcCA9IGdncGxvdChhdmVyYWdlX2FsbCwKICAgICAgICAgICBhZXMoeCA9IGIycl9tZWFuLCB5ID0gZXBpX3RyYW5zX21lYW4sIGxhYmVsPXBhdGllbnQuaWRlbnQpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKcHJpbnRfdGFiKHBsdCA9IHAsdGl0bGUgPSAibG9nIFRQTSIpCmBgYAoKIyAgUHJpbWFyeSBjYW5jZXIgY2VsbHMKCmBgYHtyfQoKIyBhZGQgc2NvcmVzCnBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSx2YXJzID0gYjJyX2dlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCmFjY19jYW5jZXJfcHJpICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gImIycl9zaWduYXR1cmVfVFBNIikKCgpwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFycyA9IGIycl9nZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgphY2NfY2FuY2VyX3ByaSAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9ICJiMnJfc2lnbmF0dXJlIikKCmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLHZhcnMgPSBnZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyX3ByaSAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IHBhc3RlMChwYXRod2F5X25hbWUsIl9UUE0iKSkKfQoKZm9yIChwYXRod2F5X25hbWUgaW4gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9wYXRod2F5c1tbcGF0aHdheV9uYW1lXV0KICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyX3ByaSAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IHBhdGh3YXlfbmFtZSkKfQpgYGAKCmBgYHtyfQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUIiwicGF0aWVudC5pZGVudCIpKQphdmVyYWdlX2RhdGExICA9IGRhdGEgJT4lIGdyb3VwX2J5KHBhdGllbnQuaWRlbnQpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShiMnJfbWVhbiA9IG1lYW4oYjJyX3NpZ25hdHVyZSwgbmEucm09VFJVRSkpCgphdmVyYWdlX2RhdGEyICA9IGRhdGEgJT4lIGdyb3VwX2J5KHBhdGllbnQuaWRlbnQpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShlcGlfdHJhbnNfbWVhbiA9IG1lYW4oR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQsIG5hLnJtPVRSVUUpKQphdmVyYWdlX2FsbCA9IGNiaW5kKGF2ZXJhZ2VfZGF0YTEsYXZlcmFnZV9kYXRhMikKYXZlcmFnZV9hbGwgPSBhdmVyYWdlX2FsbFssYygtMSldCiMgYXZlcmFnZV9hbGwkcGF0aWVudC5pZGVudCA9IHBhc3RlKCJjbHVzdGVyIixhdmVyYWdlX2FsbCRwYXRpZW50LmlkZW50KQpsaWJyYXJ5KGdncmVwZWwpCmdncGxvdChhdmVyYWdlX2FsbCwKICAgICAgICAgICBhZXMoeCA9IGIycl9tZWFuLCB5ID0gZXBpX3RyYW5zX21lYW4sIGxhYmVsPXBhdGllbnQuaWRlbnQpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKCmBgYAoKYGBge3J9CmFjY19jYW5jZXJfcHJpIDwtIEZpbmROZWlnaGJvcnMoYWNjX2NhbmNlcl9wcmksIGRpbXMgPSAxOjEwLHZlcmJvc2UgPSBGKSAlPiUgIEZpbmRDbHVzdGVycyhyZXNvbHV0aW9uID0gMC43KSAKCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2dyZXBlbCkKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSx2YXJzID0gIGMoImIycl9zaWduYXR1cmUiLCJHT0JQX05PUkVQSU5FUEhSSU5FX1RSQU5TUE9SVCIsInNldXJhdF9jbHVzdGVycyIpKQphdmVyYWdlX2RhdGExICA9IGRhdGEgJT4lIGdyb3VwX2J5KHNldXJhdF9jbHVzdGVycykgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGIycl9tZWFuID0gbWVhbihiMnJfc2lnbmF0dXJlLCBuYS5ybT1UUlVFKSkKCmF2ZXJhZ2VfZGF0YTIgID0gZGF0YSAlPiUgZ3JvdXBfYnkoc2V1cmF0X2NsdXN0ZXJzKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUoZXBpX3RyYW5zX21lYW4gPSBtZWFuKEdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JULCBuYS5ybT1UUlVFKSkKYXZlcmFnZV9hbGwgPSBjYmluZChhdmVyYWdlX2RhdGExLGF2ZXJhZ2VfZGF0YTIpCmF2ZXJhZ2VfYWxsID0gYXZlcmFnZV9hbGxbLGMoLTEpXQphdmVyYWdlX2FsbCRzZXVyYXRfY2x1c3RlcnMgPSBwYXN0ZSgiY2x1c3RlciIsYXZlcmFnZV9hbGwkc2V1cmF0X2NsdXN0ZXJzKQpnZ3Bsb3QoYXZlcmFnZV9hbGwsCiAgICAgICAgICAgYWVzKHggPSBiMnJfbWVhbiwgeSA9IGVwaV90cmFuc19tZWFuLCBsYWJlbD1zZXVyYXRfY2x1c3RlcnMpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKYGBgCgpgYGB7cn0KRGltUGxvdChhY2NfY2FuY2VyX3ByaSxncm91cC5ieSA9ICJwYXRpZW50LmlkZW50IikKRGltUGxvdChhY2NfY2FuY2VyX3ByaSkKYGBgCgpgYGB7PWh0bWx9CjxzY3JpcHQgc3JjPSJodHRwczovL2h5cG90aGVzLmlzL2VtYmVkLmpzIiBhc3luYz48L3NjcmlwdD4KYGBgCg==