Functions
library(stringi)
source_from_github(repositoy = "DEG_functions",version = "0.2.47")
source_from_github(repositoy = "cNMF_functions",version = "0.4.0",script_name = "cnmf_functions_V3.R")
source_from_github(repositoy = "sc_general_functions",version = "0.1.28",script_name = "functions.R")
Data
source_from_github(repositoy = "DEG_functions",version = "0.2.47")
ℹ SHA-1 hash of file is f5bb1cd741d13bded83fe3b6fd43169e29731216
ACC all cells UMAP
DimPlot(acc_all)

Neuronal
signatures
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")
plt
Warning in grSoftVersion() :
unable to load shared object '/usr/local/lib/R/modules//R_X11.so':
libXt.so.6: cannot open shared object file: No such file or directory

Neuronal signatures expression
for (neural_name in colnames(neuronal_signatures)) {
genes = neuronal_signatures[,neural_name,drop=T]
# Assuming df is your data frame
print_tab(
DoHeatmap(object = acc_tpm,features = genes,slot = "counts",combine = T,disp.max = 5000)+ labs(fill = "TPM")
,title = neural_name,subtitle_num = 3)
}
Sympathetic_cholinergic_neuron

Sympathetic_noradrenergic_neuron

Peripheral_nervous_system_neuron_
Warning in DoHeatmap(object = acc_tpm, features = genes, slot =
“counts”, : The following features were omitted as they were not found
in the counts slot for the RNA assay: NOP53, SNHG29

Autonomic_neuron

Peripheral_neuron

Sensory_neuron
Warning in DoHeatmap(object = acc_tpm, features = genes, slot =
“counts”, : The following features were omitted as they were not found
in the counts slot for the RNA assay: NOP53

Adrenergic_neuron_tabula_sapiens
Warning in DoHeatmap(object = acc_tpm, features = genes, slot =
“counts”, : The following features were omitted as they were not found
in the counts slot for the RNA assay: NOP53

Peripheral_sensory_neuron

Parasympathetic_neuron

NA
WBC
wbc_cells = subset(acc_all, subset = cell.type == "WBC")
wbc_cells <- FindNeighbors(wbc_cells, dims = 1:10,verbose = F) %>% FindClusters(resolution = 0.5) %>% RunUMAP(dims = 1:10,verbose = F)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 33
Number of edges: 528
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.5572
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(wbc_cells)

WBC devided into 2 clusters:
VlnPlot(object = wbc_cells,features = c("CD79A","PTPRC"))

WBC Neuronal
signatures

CD79A
neuronal_signatures correlation
library(ggpubr)
for (neural_name in colnames(neuronal_signatures)) {
wbc_cells = subset(acc_all, subset = cell.type == "WBC")
data = FetchData(object = wbc_cells,vars = c(neural_name,"CD79A"))
p = ggplot(data, aes_string(x=neural_name, y="CD79A")) +
geom_point()+
geom_smooth(method=lm) +
stat_cor()
print_tab(p,title = neural_name,subtitle_num = 3)
}
Sympathetic_cholinergic_neuron
geom_smooth() using formula ‘y ~ x’

Sympathetic_noradrenergic_neuron
geom_smooth() using formula ‘y ~ x’

Peripheral_nervous_system_neuron_
geom_smooth() using formula ‘y ~ x’

Autonomic_neuron
geom_smooth() using formula ‘y ~ x’

Peripheral_neuron
geom_smooth() using formula ‘y ~ x’

Sensory_neuron
geom_smooth() using formula ‘y ~ x’

Adrenergic_neuron_tabula_sapiens
geom_smooth() using formula ‘y ~ x’

Peripheral_sensory_neuron
geom_smooth() using formula ‘y ~ x’

Parasympathetic_neuron
geom_smooth() using formula ‘y ~ x’

NA
PTPRC
neuronal_signatures correlation
library(ggpubr)
for (neural_name in colnames(neuronal_signatures)) {
wbc_cells = subset(acc_all, subset = cell.type == "WBC")
data = FetchData(object = wbc_cells,vars = c(neural_name,"PTPRC"))
p = ggplot(data, aes_string(x=neural_name, y="PTPRC")) +
geom_point()+
geom_smooth(method=lm) +
stat_cor()
print_tab(p,title = neural_name,subtitle_num = 3)
}
Sympathetic_cholinergic_neuron
geom_smooth() using formula ‘y ~ x’

Sympathetic_noradrenergic_neuron
geom_smooth() using formula ‘y ~ x’

Peripheral_nervous_system_neuron_
geom_smooth() using formula ‘y ~ x’

Autonomic_neuron
geom_smooth() using formula ‘y ~ x’

Peripheral_neuron
geom_smooth() using formula ‘y ~ x’

Sensory_neuron
geom_smooth() using formula ‘y ~ x’

Adrenergic_neuron_tabula_sapiens
geom_smooth() using formula ‘y ~ x’

Peripheral_sensory_neuron
geom_smooth() using formula ‘y ~ x’

Parasympathetic_neuron
geom_smooth() using formula ‘y ~ x’

NA
Neuronal pathways in
ACC cancer cells
dim reduction
acc_cancer <- RunPCA(acc_cancer, features = VariableFeatures(object = acc_cancer),verbose = F)
ElbowPlot(acc_cancer)
acc_cancer <- FindNeighbors(acc_cancer, dims = 1:10,verbose = F) %>% FindClusters(resolution = 0.5) %>% RunUMAP(dims = 1:10,verbose = F)
DimPlot(acc_cancer,group.by = "patient.ident")
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 = pathway_name)
}
Scores
UMAP
plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways))
for (i in 1:(length(plt$patches$plots)+1)) {
plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print_tab(plt,title = "UMAP" ,subtitle_num = 3)
UMAP

plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways),max.cutoff = 50)
for (i in 1:(length(plt$patches$plots)+1)) {
plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print_tab(plt,title = "UMAP max=50" ,subtitle_num = 3)
UMAP max=50

plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways),max.cutoff = 250)
for (i in 1:(length(plt$patches$plots)+1)) {
plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print_tab(plt,title = "UMAP max=250" ,subtitle_num = 3)
UMAP max=250

plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways))
for (i in 1:(length(plt$patches$plots)+1)) {
plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM') + 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.
print_tab(plt,title = "UMAP rainbow" ,subtitle_num = 3)
UMAP rainbow

NA
Scores violin
plt = VlnPlot(object = acc_cancer,features = names(neuronal_pathways),group.by = "patient.ident")+theme(plot.title = element_text(size = 3))
for (i in 1:(length(plt$patches$plots)+1)) {
plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=9.5))
if (i %in% c(1,4,7)) {
plt[[i]] = plt[[i]]+ylab("TPM")
}
}
print(plt)

ACC2 DEG
acc_cancer_pri = SetIdent(object = acc_cancer_pri,value = "patient.ident")
markers = FindMarkers(object = acc_cancer_pri,ident.1 = "ACC2",features = VariableFeatures(acc_cancer_pri),densify = T)
volcano_plot(de_genes = markers,max_names = 10,title = "",ident1 = "ACC2",ident2 = "PNI patients",show_graph = F,log2fc_cutoff = 1)
GSEA- canonical
pathways
up = up in ACC2
library(hypeR)
genesets <- msigdb_download("Homo sapiens",category="H") %>% append( msigdb_download("Homo sapiens",category="C2",subcategory = "CP"))
all_genes = markers %>% arrange(desc(avg_log2FC)) %>% select("avg_log2FC")
ranked_list <- setNames(all_genes$avg_log2FC, rownames(all_genes))
hyp_obj <- hypeR_fgsea(signature = ranked_list,genesets = genesets,up_only = F)
hyp_dots(hyp_obj)
GSEA- GO BP
genesets <- msigdb_download("Homo sapiens",category="H") %>% append( msigdb_download("Homo sapiens",category="C5",subcategory = "GO:BP"))
all_genes = markers %>% arrange(desc(avg_log2FC)) %>% select("avg_log2FC")
ranked_list <- setNames(all_genes$avg_log2FC, rownames(all_genes))
hyp_obj <- hypeR_fgsea(signature = ranked_list,genesets = genesets,up_only = F)
hyp_dots(hyp_obj)
Neuronal pathways in
ACC primary cancer cells
lum_score = FetchData(acc_cancer_pri,"luminal_over_myo")
lum_score %<>% mutate (lum_or_myo = case_when(
luminal_over_myo > 1 ~ "luminal",
luminal_over_myo < (-1) ~ "myo",
TRUE ~ "unknown"))
acc_cancer_pri %<>% AddMetaData(metadata = lum_score$lum_or_myo,col.name = "lum_or_myo")
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 = pathway_name)
}
plt = FeaturePlot(object = acc_cancer_pri,features = names(neuronal_pathways))
for (i in 1:(length(plt$patches$plots)+1)) {
plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print(plt)

Lum vs
Myo
library(ggpubr)
for (pathway in names(neuronal_pathways)) {
data = FetchData(object = acc_cancer_pri,vars = c("lum_or_myo",pathway)) %>% filter(lum_or_myo != "unknown")
p = ggboxplot(data, x = "lum_or_myo", y =pathway,
palette = "jco",
add = "jitter")+
stat_compare_means(method = "wilcox.test",comparisons = list(c("luminal","myo")))+ stat_summary(fun.data = function(x) data.frame(y=max(x)*1.2, label = paste("Mean=",round(mean(x),digits = 2))), geom="text") +ylab("TPM")+ggtitle(pathway)
print_tab(p,title = pathway)
}
GOBP_NOREPINEPHRINE_SECRETION

GOBP_NOREPINEPHRINE_TRANSPORT

GOBP_NORADRENERGIC_NEURON_DEVELOPMENT

GOBP_NORADRENERGIC_NEURON_DIFFERENTIATION

GOBP_AUTONOMIC_NERVOUS_SYSTEM_DEVELOPMENT

GOBP_PARASYMPATHETIC_NERVOUS_SYSTEM_DEVELOPMENT

GOBP_ADRENERGIC_RECEPTOR_SIGNALING_PATHWAY

GOMF_BETA_2_ADRENERGIC_RECEPTOR_BINDING

NA
LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jX2RlcHRoOiA0Ci0tLQoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoc3RyaW5naSkKc291cmNlX2Zyb21fZ2l0aHViKHJlcG9zaXRveSA9ICJERUdfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMi40NyIpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiY05NRl9mdW5jdGlvbnMiLHZlcnNpb24gPSAiMC40LjAiLHNjcmlwdF9uYW1lID0gImNubWZfZnVuY3Rpb25zX1YzLlIiKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gInNjX2dlbmVyYWxfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMS4yOCIsc2NyaXB0X25hbWUgPSAiZnVuY3Rpb25zLlIiKQpgYGAKCiMgRGF0YQoKYGBge3J9CmxpYnJhcnkoInJlYWR4bCIpCmFjY19hbGwgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX2FsbGRhdGEucmRzIikKYWNjX2NhbmNlcl9wcmkgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY19jYW5jZXJfbm8xNDZfcHJpbWFyeW9ubHkxNWtfY2FuY2VyY2VsbHMucmRzIikKYWNjX2NhbmNlciA9IHJlYWRSRFMoZmlsZSA9ICIuL0RhdGEvYWNjX3RwbV9uQ291bnRfbWl0b19ubzE0Nl8xNWtfY2FuY2VyY2VsbHMucmRzIikKCgpuZXVyb25hbF9zaWduYXR1cmVzIDwtIHJlYWRfZXhjZWwoIi4vRGF0YS9OZXVyb25hbCBTaWduYXR1cmVzLnhsc3giLGNvbF9uYW1lcyA9RikKbmV1cm9uYWxfc2lnbmF0dXJlcyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpCnJvd25hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpIDwtIE5VTEwKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiX1xcZC4qIikgI3JlbW92ZSBhbnkgX251bWJlcnMKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiXFwoLioiKSAjcmVuYW1lICIoIiB0byB0aGUgZW5kCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICJfIiwgcGF0dGVybiA9ICIgIikgI3JlbmFtZSBhbGwgc3BhY2VzCgpuZXVyb25hbF9wYXRod2F5cyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvUGF0aHdheSBhbmFseXNpcyBHZW5lIHNldHMueGxzeCIsY29sX25hbWVzID1GKQpuZXVyb25hbF9wYXRod2F5cyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpICAlPiUgIGFzLmxpc3QoKSAKbmV1cm9uYWxfcGF0aHdheXMgPSBsYXBwbHkobmV1cm9uYWxfcGF0aHdheXMsIG5hLm9taXQpCm5ldXJvbmFsX3BhdGh3YXlzID0gbGFwcGx5KG5ldXJvbmFsX3BhdGh3YXlzLCBhcy5jaGFyYWN0ZXIpCgpgYGAKCiMgQUNDIGFsbCBjZWxscyBVTUFQCgpgYGB7cn0KRGltUGxvdChhY2NfYWxsKQpgYGAKCiMgTmV1cm9uYWwgc2lnbmF0dXJlcwoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNbLG5ldXJhbF9uYW1lLGRyb3A9VF0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQoKICAKICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCiAgYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IG5ldXJhbF9uYW1lKQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpwbHQgPSBWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSkKcGx0W1sxXV0gPSBwbHRbWzFdXSsgeWxhYigiVFBNIikKcGx0W1s0XV0gPSBwbHRbWzRdXSsgeWxhYigiVFBNIikKcGx0W1s3XV0gPSBwbHRbWzddXSsgeWxhYigiVFBNIikKcGx0CmBgYAoKIyMgTmV1cm9uYWwgc2lnbmF0dXJlcyBleHByZXNzaW9uIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgcmVzdWx0cz0nYXNpcyd9CmNvdW50LmRhdGEgPC0gR2V0QXNzYXlEYXRhKG9iamVjdCA9IGFjY19hbGxbWyJSTkEiXV0sIHNsb3QgPSAiZGF0YSIpCmNvdW50LmRhdGEgPC0gYXMubWF0cml4KHggPSAoMioqY291bnQuZGF0YSkgLSAxKQphY2NfdHBtIDwtIFNldEFzc2F5RGF0YSgKICAgIG9iamVjdCA9IGFjY19hbGwsCiAgICBzbG90ID0gImNvdW50cyIsCiAgICBuZXcuZGF0YSA9IGNvdW50LmRhdGEsCiAgICBhc3NheSA9ICJSTkEiCikKCmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNbLG5ldXJhbF9uYW1lLGRyb3A9VF0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQogIHByaW50X3RhYigKICAgIERvSGVhdG1hcChvYmplY3QgPSBhY2NfdHBtLGZlYXR1cmVzID0gZ2VuZXMsc2xvdCA9ICJjb3VudHMiLGNvbWJpbmUgPSBULGRpc3AubWF4ID0gNTAwMCkrIGxhYnMoZmlsbCA9ICJUUE0iKSAKICAsdGl0bGUgPSBuZXVyYWxfbmFtZSxzdWJ0aXRsZV9udW0gPSAzKQp9CmBgYAoKIyMgV0JDIAoKYGBge3J9CndiY19jZWxscyA9IHN1YnNldChhY2NfYWxsLCBzdWJzZXQgPSBjZWxsLnR5cGUgPT0gIldCQyIpCndiY19jZWxscyA8LSBGaW5kTmVpZ2hib3JzKHdiY19jZWxscywgZGltcyA9IDE6MTAsdmVyYm9zZSA9IEYpICU+JSAgRmluZENsdXN0ZXJzKHJlc29sdXRpb24gPSAwLjUpICU+JSAgUnVuVU1BUChkaW1zID0gMToxMCx2ZXJib3NlID0gRikKCkRpbVBsb3Qod2JjX2NlbGxzKQpgYGAKCldCQyBkZXZpZGVkIGludG8gMiBjbHVzdGVyczoKCmBgYHtyfQpWbG5QbG90KG9iamVjdCA9IHdiY19jZWxscyxmZWF0dXJlcyA9IGMoIkNENzlBIiwiUFRQUkMiKSkKYGBgCgojIyBXQkMgTmV1cm9uYWwgc2lnbmF0dXJlcwoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEzfQphY2NfYWxsJGNsdXN0ZXJfaWRlbnRzID0gYWNjX2FsbEBhY3RpdmUuaWRlbnQKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfYWxsLHZhcnMgPSBjKCJjbHVzdGVyX2lkZW50cyIpKSAlPiUgbXV0YXRlKGNsdXN0ZXJfaWRlbnRzID0gYXMuY2hhcmFjdGVyKGNsdXN0ZXJfaWRlbnRzKSkKY2x1c3Rlcl8wX2NlbGxzID0gc3Vic2V0KHdiY19jZWxscywgc3Vic2V0ID0gc2V1cmF0X2NsdXN0ZXJzID09IDApICU+JSBjb2xuYW1lcygpCmNsdXN0ZXJfMV9jZWxscyA9IHN1YnNldCh3YmNfY2VsbHMsIHN1YnNldCA9IHNldXJhdF9jbHVzdGVycyA9PSAxKSAlPiUgY29sbmFtZXMoKQoKZGF0YVtyb3duYW1lcyhkYXRhKSAlaW4lIGNsdXN0ZXJfMF9jZWxscyxdID0iV0JDX2NsdXN0ZXJfMCIKZGF0YVtyb3duYW1lcyhkYXRhKSAlaW4lIGNsdXN0ZXJfMV9jZWxscyxdID0iV0JDX2NsdXN0ZXJfMSIKYWNjX2FsbCRjbHVzdGVyX2lkZW50cyA9IGRhdGEKCnBsdCA9IFZsblBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IGNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpLGdyb3VwLmJ5ID0gImNsdXN0ZXJfaWRlbnRzIikKcGx0W1sxXV0gPSBwbHRbWzFdXSsgeWxhYigiVFBNIikKcGx0W1s0XV0gPSBwbHRbWzRdXSsgeWxhYigiVFBNIikKcGx0W1s3XV0gPSBwbHRbWzddXSsgeWxhYigiVFBNIikKcGx0CmBgYAoKIyMgQ0Q3OUEgbmV1cm9uYWxfc2lnbmF0dXJlcyBjb3JyZWxhdGlvbiB7LnRhYnNldH0KCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpsaWJyYXJ5KGdncHVicikKZm9yIChuZXVyYWxfbmFtZSBpbiBjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSkgewogIHdiY19jZWxscyA9IHN1YnNldChhY2NfYWxsLCBzdWJzZXQgPSBjZWxsLnR5cGUgPT0gIldCQyIpCiAgZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSB3YmNfY2VsbHMsdmFycyA9IGMobmV1cmFsX25hbWUsIkNENzlBIikpCiAgcCA9IGdncGxvdChkYXRhLCBhZXNfc3RyaW5nKHg9bmV1cmFsX25hbWUsIHk9IkNENzlBIikpICsgCiAgICAgICAgICAgZ2VvbV9wb2ludCgpKwogICAgICAgICAgIGdlb21fc21vb3RoKG1ldGhvZD1sbSkgKwogICAgICAgICAgIHN0YXRfY29yKCkKICBwcmludF90YWIocCx0aXRsZSAgPSBuZXVyYWxfbmFtZSxzdWJ0aXRsZV9udW0gPSAzKQp9CgpgYGAKCiMjIFBUUFJDIG5ldXJvbmFsX3NpZ25hdHVyZXMgY29ycmVsYXRpb24gey50YWJzZXR9CgpgYGB7ciByZXN1bHRzPSdhc2lzJ30KbGlicmFyeShnZ3B1YnIpCmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICB3YmNfY2VsbHMgPSBzdWJzZXQoYWNjX2FsbCwgc3Vic2V0ID0gY2VsbC50eXBlID09ICJXQkMiKQogIGRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gd2JjX2NlbGxzLHZhcnMgPSBjKG5ldXJhbF9uYW1lLCJQVFBSQyIpKQogIHAgPSBnZ3Bsb3QoZGF0YSwgYWVzX3N0cmluZyh4PW5ldXJhbF9uYW1lLCB5PSJQVFBSQyIpKSArIAogICAgICAgICAgIGdlb21fcG9pbnQoKSsKICAgICAgICAgICBnZW9tX3Ntb290aChtZXRob2Q9bG0pICsKICAgICAgICAgICBzdGF0X2NvcigpCiAgcHJpbnRfdGFiKHAsdGl0bGUgID0gbmV1cmFsX25hbWUsc3VidGl0bGVfbnVtID0gMykKfQpgYGAKCiMgQ1NGMwoKW1NpbmdsZS1jZWxsIFJOQSBzZXF1ZW5jaW5nIHJldmVhbHMgaW50cmF0dW1vcmFsIGhldGVyb2dlbmVpdHkgYW5kIHBvdGVudGlhbCBtZWNoYW5pc21zIG9mIG1hbGlnbmFudCBwcm9ncmVzc2lvbiBpbiBwcm9zdGF0ZSBjYW5jZXIgd2l0aCBwZXJpbmV1cmFsIGludmFzaW9uXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3BtYy9hcnRpY2xlcy9QTUM5ODc1Nzk5LykKCmBgYHtyfQpWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSAiQ1NGMyIsZ3JvdXAuYnkgPSAicGF0aWVudC5pZGVudCIpKyB5bGFiKCJsb2cyIChUUE0rMSkiKQpgYGAKCiMgTmV1cm9uYWwgcGF0aHdheXMgaW4gQUNDIGNhbmNlciBjZWxscwoKIyMgZGltIHJlZHVjdGlvbgoKYGBge3J9CmFjY19jYW5jZXIgPC0gUnVuUENBKGFjY19jYW5jZXIsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBhY2NfY2FuY2VyKSx2ZXJib3NlID0gRikKRWxib3dQbG90KGFjY19jYW5jZXIpCmFjY19jYW5jZXIgPC0gRmluZE5laWdoYm9ycyhhY2NfY2FuY2VyLCBkaW1zID0gMToxMCx2ZXJib3NlID0gRikgJT4lICBGaW5kQ2x1c3RlcnMocmVzb2x1dGlvbiA9IDAuNSkgJT4lICBSdW5VTUFQKGRpbXMgPSAxOjEwLHZlcmJvc2UgPSBGKQpgYGAKCmBgYHtyfQpEaW1QbG90KGFjY19jYW5jZXIsZ3JvdXAuYnkgPSAicGF0aWVudC5pZGVudCIpCmBgYAoKYGBge3J9CmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19jYW5jZXIgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBwYXRod2F5X25hbWUpCn0KYGBgCgojIyBTY29yZXMgVU1BUCB7LnRhYnNldH0KCmBgYHtyIGZpZy5oZWlnaHQ9MTMsIGZpZy53aWR0aD0xMywgcmVzdWx0cz0nYXNpcyd9CgpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKQpmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpKyBsYWJzKGNvbG9yPSdUUE0nKQp9CnByaW50X3RhYihwbHQsdGl0bGUgPSAiVU1BUCIgLHN1YnRpdGxlX251bSA9IDMpCgpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpLG1heC5jdXRvZmYgPSA1MCkKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKICBwbHRbW2ldXSA9IHBsdFtbaV1dICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSsgbGFicyhjb2xvcj0nVFBNJykKfQpwcmludF90YWIocGx0LHRpdGxlID0gIlVNQVAgbWF4PTUwIiAsc3VidGl0bGVfbnVtID0gMykKCnBsdCA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19jYW5jZXIsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9wYXRod2F5cyksbWF4LmN1dG9mZiA9IDI1MCkKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKICBwbHRbW2ldXSA9IHBsdFtbaV1dICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSsgbGFicyhjb2xvcj0nVFBNJykKfQpwcmludF90YWIocGx0LHRpdGxlID0gIlVNQVAgbWF4PTI1MCIgLHN1YnRpdGxlX251bSA9IDMpCgpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKQpmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpKyBsYWJzKGNvbG9yPSdUUE0nKSArIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gcmFpbmJvdyg1KSkKfQpwcmludF90YWIocGx0LHRpdGxlID0gIlVNQVAgcmFpbmJvdyIgLHN1YnRpdGxlX251bSA9IDMpCgpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTMsIGZpZy53aWR0aD0xMywgcmVzdWx0cz0nYXNpcyd9CgpgYGAKCiMjIFNjb3JlcyB2aW9saW4KCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KIHBsdCA9IFZsblBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSxncm91cC5ieSA9ICJwYXRpZW50LmlkZW50IikrdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMykpCiAKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKICBwbHRbW2ldXSA9IHBsdFtbaV1dICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTkuNSkpCiAgaWYgKGkgJWluJSBjKDEsNCw3KSkgewogICAgcGx0W1tpXV0gPSBwbHRbW2ldXSt5bGFiKCJUUE0iKQogIH0KfQpwcmludChwbHQpCmBgYAoKIyBBQ0MyIERFRwoKYGBge3J9CmFjY19jYW5jZXJfcHJpID0gU2V0SWRlbnQob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFsdWUgPSAicGF0aWVudC5pZGVudCIpCm1hcmtlcnMgPSBGaW5kTWFya2VycyhvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSxpZGVudC4xID0gIkFDQzIiLGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhhY2NfY2FuY2VyX3ByaSksZGVuc2lmeSA9IFQpCnZvbGNhbm9fcGxvdChkZV9nZW5lcyA9IG1hcmtlcnMsbWF4X25hbWVzID0gMTAsdGl0bGUgPSAiIixpZGVudDEgPSAiQUNDMiIsaWRlbnQyID0gIlBOSSBwYXRpZW50cyIsc2hvd19ncmFwaCA9IEYsbG9nMmZjX2N1dG9mZiA9IDEpCmBgYAoKIyMgR1NFQS0gY2Fub25pY2FsIHBhdGh3YXlzCgp1cCA9IHVwIGluIEFDQzIKCmBgYHtyfQpsaWJyYXJ5KGh5cGVSKQpnZW5lc2V0cyA8LSBtc2lnZGJfZG93bmxvYWQoIkhvbW8gc2FwaWVucyIsY2F0ZWdvcnk9IkgiKSAlPiUgYXBwZW5kKCBtc2lnZGJfZG93bmxvYWQoIkhvbW8gc2FwaWVucyIsY2F0ZWdvcnk9IkMyIixzdWJjYXRlZ29yeSA9ICJDUCIpKQphbGxfZ2VuZXMgPSBtYXJrZXJzICAlPiUgIGFycmFuZ2UoZGVzYyhhdmdfbG9nMkZDKSkgJT4lIHNlbGVjdCgiYXZnX2xvZzJGQyIpIApyYW5rZWRfbGlzdCAgIDwtIHNldE5hbWVzKGFsbF9nZW5lcyRhdmdfbG9nMkZDLCByb3duYW1lcyhhbGxfZ2VuZXMpKQpoeXBfb2JqIDwtIGh5cGVSX2Znc2VhKHNpZ25hdHVyZSA9IHJhbmtlZF9saXN0LGdlbmVzZXRzID0gIGdlbmVzZXRzLHVwX29ubHkgPSBGKQpoeXBfZG90cyhoeXBfb2JqKQpgYGAKCiMjIEdTRUEtIEdPIEJQCgpgYGB7cn0KZ2VuZXNldHMgPC0gbXNpZ2RiX2Rvd25sb2FkKCJIb21vIHNhcGllbnMiLGNhdGVnb3J5PSJIIikgJT4lIGFwcGVuZCggbXNpZ2RiX2Rvd25sb2FkKCJIb21vIHNhcGllbnMiLGNhdGVnb3J5PSJDNSIsc3ViY2F0ZWdvcnkgPSAiR086QlAiKSkKYWxsX2dlbmVzID0gbWFya2VycyAgJT4lICBhcnJhbmdlKGRlc2MoYXZnX2xvZzJGQykpICU+JSBzZWxlY3QoImF2Z19sb2cyRkMiKSAKcmFua2VkX2xpc3QgICA8LSBzZXROYW1lcyhhbGxfZ2VuZXMkYXZnX2xvZzJGQywgcm93bmFtZXMoYWxsX2dlbmVzKSkKaHlwX29iaiA8LSBoeXBlUl9mZ3NlYShzaWduYXR1cmUgPSByYW5rZWRfbGlzdCxnZW5lc2V0cyA9ICBnZW5lc2V0cyx1cF9vbmx5ID0gRikKaHlwX2RvdHMoaHlwX29iaikKYGBgCgpgYGB7PWh0bWx9CjxzY3JpcHQgc3JjPSJodHRwczovL2h5cG90aGVzLmlzL2VtYmVkLmpzIiBhc3luYz48L3NjcmlwdD4KYGBgCiMgTmV1cm9uYWwgcGF0aHdheXMgaW4gQUNDIHByaW1hcnkgY2FuY2VyIGNlbGxzCgpgYGB7cn0KbHVtX3Njb3JlID0gRmV0Y2hEYXRhKGFjY19jYW5jZXJfcHJpLCJsdW1pbmFsX292ZXJfbXlvIikKbHVtX3Njb3JlICAlPD4lIG11dGF0ZSAobHVtX29yX215byA9IGNhc2Vfd2hlbigKICAgICAgICAgbHVtaW5hbF9vdmVyX215byA+IDEgfiAibHVtaW5hbCIsCiAgICAgICAgIGx1bWluYWxfb3Zlcl9teW8gPCAoLTEpIH4gIm15byIsCiAgICAgICAgIFRSVUUgfiAidW5rbm93biIpKQphY2NfY2FuY2VyX3ByaSAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IGx1bV9zY29yZSRsdW1fb3JfbXlvLGNvbC5uYW1lID0gImx1bV9vcl9teW8iKQpgYGAKCmBgYHtyfQpmb3IgKHBhdGh3YXlfbmFtZSBpbiBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3BhdGh3YXlzW1twYXRod2F5X25hbWVdXQogcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLHZhcnMgPSBnZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyX3ByaSAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IHBhdGh3YXlfbmFtZSkKfQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTMsIGZpZy53aWR0aD0xM30KcGx0ID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksZmVhdHVyZXMgPSAgbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKQoKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKICBwbHRbW2ldXSA9IHBsdFtbaV1dICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSsgbGFicyhjb2xvcj0nVFBNJykgCn0KcHJpbnQocGx0KQpgYGAKCiMgTHVtIHZzIE15byB7LnRhYnNldH0KCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpsaWJyYXJ5KGdncHVicikKZm9yIChwYXRod2F5IGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFycyA9IGMoImx1bV9vcl9teW8iLHBhdGh3YXkpKSAlPiUgZmlsdGVyKGx1bV9vcl9teW8gIT0gInVua25vd24iKQogIHAgPSBnZ2JveHBsb3QoZGF0YSwgeCA9ICJsdW1fb3JfbXlvIiwgeSA9cGF0aHdheSwKICAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiamNvIiwKICAgICAgICAgICAgICAgIGFkZCA9ICJqaXR0ZXIiKSsgCiAgICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0Iixjb21wYXJpc29ucyA9IGxpc3QoYygibHVtaW5hbCIsIm15byIpKSkrIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGZ1bmN0aW9uKHgpIGRhdGEuZnJhbWUoeT1tYXgoeCkqMS4yLCBsYWJlbCA9IHBhc3RlKCJNZWFuPSIscm91bmQobWVhbih4KSxkaWdpdHMgPSAyKSkpLCBnZW9tPSJ0ZXh0IikgK3lsYWIoIlRQTSIpK2dndGl0bGUocGF0aHdheSkKICBwcmludF90YWIocCx0aXRsZSA9IHBhdGh3YXkpCn0KCmBgYAo=