1 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")

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)
b2r_genes = c("RAF1", "PAMPK1", "PRKACA", "PIK3CA", "AKT1", "AKT2", "AKT3", "CREB1", "CREBBP", "BCL2", "BAD", "JUN", "FOS",  "MYC")
neuronal_pathways[["b2r_signature"]] = b2r_genes
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_TPM")
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)
}
FeaturePlot(acc_all,features = "Sympathetic_cholinergic_neuron_noRP_TPM")

df = acc_all$Sympathetic_cholinergic_neuron_noRP_TPM %>% as.data.frame()
names(df) = "epi"
ggplot(df, aes(x=epi)) +
    geom_density()

VlnPlot(object = acc_all,features = names(neuronal_signatures_no_RP))

3 Genes expression

count.data <- GetAssayData(object = acc_all[["RNA"]], slot = "data")
count.data <- as.matrix(x = (2**count.data) - 1)
acc_tpm <- SetAssayData(
    object = acc_all,
    slot = "counts",
    new.data = count.data,
    assay = "RNA"
)

for (neural_name in names(neuronal_signatures_no_RP)) {
  genes = neuronal_signatures_no_RP[[neural_name]]
  # 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 = 2)
}

Sympathetic_cholinergic_neuron_noRP_TPM

Sympathetic_noradrenergic_neuron_noRP_TPM

3.1 Peripheral_nervous_system_neuron__noRP_TPM {.unnumbered }

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_noRP_TPM

Peripheral_neuron_noRP_TPM

Sensory_neuron_noRP_TPM

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_noRP_TPM

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_noRP_TPM

Parasympathetic_neuron_noRP_TPM

NA

4 Violin plot

VlnPlot(object = wbc_cells,features = c("CD79A","PTPRC","CXCR4"))

high_cholinergic_neuron = list( high_cholinergic_neuron = colnames(acc_all)[acc_all$Sympathetic_cholinergic_neuron_noRP_TPM>1000])
DimPlot(object = acc_all, cells.highlight = high_cholinergic_neuron, cols.highlight = "red", cols = "gray", order = TRUE)
FeaturePlot(object = acc_all,features = names(neuronal_signatures_no_RP))& theme(plot.title = element_text(size=13))
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_logTPM")
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)
}
FeaturePlot(acc_all,features = "Sympathetic_cholinergic_neuron_noRP_logTPM")
df = acc_all$Sympathetic_cholinergic_neuron_noRP_logTPM %>% as.data.frame()
names(df) = "epi"
ggplot(df, aes(x=epi)) +
    geom_density()
for (genes in (neuronal_signatures)) {
  p = DoHeatmap(object = acc_all,
            features = genes,
            group.by = "cell.type")
  print(p)
}

5 Pathways

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)
}
FeaturePlot(object = acc_cancer_pri,features = names(neuronal_pathways)[c(2,9)],pt.size = 0.5,slot = "data") & labs(color='log TPM')&
  theme(plot.title = element_text(size=10.5))


FeaturePlot(object = acc_cancer_pri,features = names(neuronal_pathways)[c(1,2,9)],pt.size = 0.5,slot = "data") & labs(color='log TPM')&
  theme(plot.title = element_text(size=10.5))

library(ggrepel)
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)]
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'

library(ggplot2)
library(cdata)
library('WVPlots')

colnames(df) = c("patient.ident","epi_sec","epi_trans","noradrenergic_dev", "noradrenergic_dif","auto_nerv_dev","parasym_nerv","ADREN_sig","b2ADRENE","b2r_signature")
PairPlot(df, 
         colnames(df)[2:length(df)], 
         "Anderson's Iris Data -- 3 species", 
         group_var = "patient.ident") &  geom_smooth(method = lm) &stat_cor(method = "pearson",size=3)
LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCiMgRnVuY3Rpb25zCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHN0cmluZ2kpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiREVHX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjIuNDciKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gImNOTUZfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuNC4wIixzY3JpcHRfbmFtZSA9ICJjbm1mX2Z1bmN0aW9uc19WMy5SIikKc291cmNlX2Zyb21fZ2l0aHViKHJlcG9zaXRveSA9ICJzY19nZW5lcmFsX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjEuMjgiLHNjcmlwdF9uYW1lID0gImZ1bmN0aW9ucy5SIikKYGBgCgojIERhdGEKCmBgYHtyfQpsaWJyYXJ5KCJyZWFkeGwiKQphY2NfYWxsID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9hY2NfdHBtX25Db3VudF9taXRvX25vMTQ2XzE1a19hbGxkYXRhLnJkcyIpCmFjY19jYW5jZXJfcHJpID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9hY2NfY2FuY2VyX25vMTQ2X3ByaW1hcnlvbmx5MTVrX2NhbmNlcmNlbGxzLnJkcyIpCmFjY19jYW5jZXIgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX2NhbmNlcmNlbGxzLnJkcyIpCgoKbmV1cm9uYWxfc2lnbmF0dXJlcyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvTmV1cm9uYWwgU2lnbmF0dXJlcy54bHN4Iixjb2xfbmFtZXMgPUYpCm5ldXJvbmFsX3NpZ25hdHVyZXMgICU8PiUgIHQoKSAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBqYW5pdG9yOjpyb3dfdG9fbmFtZXMoMSkgJT4lICBmaWx0ZXIoIXJvd19udW1iZXIoKSA9PSAxKQpyb3duYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSA8LSBOVUxMCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICIiLCBwYXR0ZXJuID0gIl9cXGQuKiIpICNyZW1vdmUgYW55IF9udW1iZXJzCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICIiLCBwYXR0ZXJuID0gIlxcKC4qIikgI3JlbmFtZSAiKCIgdG8gdGhlIGVuZApjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSAgICU8PiUgIGdzdWIocmVwbGFjZW1lbnQgPSAiXyIsIHBhdHRlcm4gPSAiICIpICNyZW5hbWUgYWxsIHNwYWNlcwoKbmV1cm9uYWxfcGF0aHdheXMgPC0gcmVhZF9leGNlbCgiLi9EYXRhL1BhdGh3YXkgYW5hbHlzaXMgR2VuZSBzZXRzLnhsc3giLGNvbF9uYW1lcyA9RikKbmV1cm9uYWxfcGF0aHdheXMgICU8PiUgIHQoKSAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBqYW5pdG9yOjpyb3dfdG9fbmFtZXMoMSkgJT4lICBmaWx0ZXIoIXJvd19udW1iZXIoKSA9PSAxKSAgJT4lICBhcy5saXN0KCkgCm5ldXJvbmFsX3BhdGh3YXlzID0gbGFwcGx5KG5ldXJvbmFsX3BhdGh3YXlzLCBuYS5vbWl0KQpuZXVyb25hbF9wYXRod2F5cyA9IGxhcHBseShuZXVyb25hbF9wYXRod2F5cywgYXMuY2hhcmFjdGVyKQpiMnJfZ2VuZXMgPSBjKCJSQUYxIiwgIlBBTVBLMSIsICJQUktBQ0EiLCAiUElLM0NBIiwgIkFLVDEiLCAiQUtUMiIsICJBS1QzIiwgIkNSRUIxIiwgIkNSRUJCUCIsICJCQ0wyIiwgIkJBRCIsICJKVU4iLCAiRk9TIiwgICJNWUMiKQpuZXVyb25hbF9wYXRod2F5c1tbImIycl9zaWduYXR1cmUiXV0gPSBiMnJfZ2VuZXMKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTIsIHJlc3VsdHM9J2FzaXMnfQpuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQID0gbGFwcGx5KG5ldXJvbmFsX3NpZ25hdHVyZXMgJT4lIGFzLmxpc3QoKSwgIGZ1bmN0aW9uKHgpIHt4WyFzdGFydHNXaXRoKHggPSB4LHByZWZpeCA9ICJSUCIpXX0pCm5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApID0gIHBhc3RlMChuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSwiX25vUlBfVFBNIikKZm9yIChuZXVyYWxfbmFtZSBpbiBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkgewogIGdlbmVzID0gbmV1cm9uYWxfc2lnbmF0dXJlc19ub19SUFtbbmV1cmFsX25hbWVdXQogICMgQXNzdW1pbmcgZGYgaXMgeW91ciBkYXRhIGZyYW1lCgogIHBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfYWxsLHZhcnMgPSBnZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgICAgICAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCiAgYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IG5ldXJhbF9uYW1lKQp9CmBgYAoKYGBge3J9CkZlYXR1cmVQbG90KGFjY19hbGwsZmVhdHVyZXMgPSAiU3ltcGF0aGV0aWNfY2hvbGluZXJnaWNfbmV1cm9uX25vUlBfVFBNIikKZGYgPSBhY2NfYWxsJFN5bXBhdGhldGljX2Nob2xpbmVyZ2ljX25ldXJvbl9ub1JQX1RQTSAlPiUgYXMuZGF0YS5mcmFtZSgpCm5hbWVzKGRmKSA9ICJlcGkiCmdncGxvdChkZiwgYWVzKHg9ZXBpKSkgKwogICAgZ2VvbV9kZW5zaXR5KCkKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTIsIHJlc3VsdHM9J2FzaXMnfQpWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkKYGBgCgojIEdlbmVzIGV4cHJlc3Npb24gey50YWJzZXR9CgpgYGB7ciByZXN1bHRzPSdhc2lzJ30KY291bnQuZGF0YSA8LSBHZXRBc3NheURhdGEob2JqZWN0ID0gYWNjX2FsbFtbIlJOQSJdXSwgc2xvdCA9ICJkYXRhIikKY291bnQuZGF0YSA8LSBhcy5tYXRyaXgoeCA9ICgyKipjb3VudC5kYXRhKSAtIDEpCmFjY190cG0gPC0gU2V0QXNzYXlEYXRhKAogICAgb2JqZWN0ID0gYWNjX2FsbCwKICAgIHNsb3QgPSAiY291bnRzIiwKICAgIG5ldy5kYXRhID0gY291bnQuZGF0YSwKICAgIGFzc2F5ID0gIlJOQSIKKQoKZm9yIChuZXVyYWxfbmFtZSBpbiBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkgewogIGdlbmVzID0gbmV1cm9uYWxfc2lnbmF0dXJlc19ub19SUFtbbmV1cmFsX25hbWVdXQogICMgQXNzdW1pbmcgZGYgaXMgeW91ciBkYXRhIGZyYW1lCiAgcHJpbnRfdGFiKAogICAgRG9IZWF0bWFwKG9iamVjdCA9IGFjY190cG0sZmVhdHVyZXMgPSBnZW5lcyxzbG90ID0gImNvdW50cyIsY29tYmluZSA9IFQsZGlzcC5tYXggPSA1MDAwKSsgbGFicyhmaWxsID0gIlRQTSIpIAogICx0aXRsZSA9IG5ldXJhbF9uYW1lLHN1YnRpdGxlX251bSA9IDIpCn0KYGBgCgojIFZpb2xpbiBwbG90CgpgYGB7cn0KVmxuUGxvdChvYmplY3QgPSB3YmNfY2VsbHMsZmVhdHVyZXMgPSBjKCJDRDc5QSIsIlBUUFJDIiwiQ1hDUjQiKSkKYGBgCgpgYGB7ciByZXN1bHRzPSdhc2lzJ30KaGlnaF9jaG9saW5lcmdpY19uZXVyb24gPSBsaXN0KCBoaWdoX2Nob2xpbmVyZ2ljX25ldXJvbiA9IGNvbG5hbWVzKGFjY19hbGwpW2FjY19hbGwkU3ltcGF0aGV0aWNfY2hvbGluZXJnaWNfbmV1cm9uX25vUlBfVFBNPjEwMDBdKQpEaW1QbG90KG9iamVjdCA9IGFjY19hbGwsIGNlbGxzLmhpZ2hsaWdodCA9IGhpZ2hfY2hvbGluZXJnaWNfbmV1cm9uLCBjb2xzLmhpZ2hsaWdodCA9ICJyZWQiLCBjb2xzID0gImdyYXkiLCBvcmRlciA9IFRSVUUpCgpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMH0KRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApKSYgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEzKSkKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTIsIHJlc3VsdHM9J2FzaXMnfQpuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQID0gbGFwcGx5KG5ldXJvbmFsX3NpZ25hdHVyZXMgJT4lIGFzLmxpc3QoKSwgIGZ1bmN0aW9uKHgpIHt4WyFzdGFydHNXaXRoKHggPSB4LHByZWZpeCA9ICJSUCIpXX0pCm5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApID0gIHBhc3RlMChuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSwiX25vUlBfbG9nVFBNIikKZm9yIChuZXVyYWxfbmFtZSBpbiBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkgewogIGdlbmVzID0gbmV1cm9uYWxfc2lnbmF0dXJlc19ub19SUFtbbmV1cmFsX25hbWVdXQogICMgQXNzdW1pbmcgZGYgaXMgeW91ciBkYXRhIGZyYW1lCgogIHBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfYWxsLHZhcnMgPSBnZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgICAgICAgIyBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfYWxsICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gbmV1cmFsX25hbWUpCn0KYGBgCgpgYGB7cn0KRmVhdHVyZVBsb3QoYWNjX2FsbCxmZWF0dXJlcyA9ICJTeW1wYXRoZXRpY19jaG9saW5lcmdpY19uZXVyb25fbm9SUF9sb2dUUE0iKQpkZiA9IGFjY19hbGwkU3ltcGF0aGV0aWNfY2hvbGluZXJnaWNfbmV1cm9uX25vUlBfbG9nVFBNICU+JSBhcy5kYXRhLmZyYW1lKCkKbmFtZXMoZGYpID0gImVwaSIKZ2dwbG90KGRmLCBhZXMoeD1lcGkpKSArCiAgICBnZW9tX2RlbnNpdHkoKQpgYGAKCmBgYHtyfQpmb3IgKGdlbmVzIGluIChuZXVyb25hbF9zaWduYXR1cmVzKSkgewogIHAgPSBEb0hlYXRtYXAob2JqZWN0ID0gYWNjX2FsbCwKICAgICAgICAgICAgZmVhdHVyZXMgPSBnZW5lcywKICAgICAgICAgICAgZ3JvdXAuYnkgPSAiY2VsbC50eXBlIikKICBwcmludChwKQp9CgoKYGBgCgojIFBhdGh3YXlzCgpgYGB7cn0KZm9yIChwYXRod2F5X25hbWUgaW4gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9wYXRod2F5c1tbcGF0aHdheV9uYW1lXV0KICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyX3ByaSAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IHBhdGh3YXlfbmFtZSkKfQpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMH0KRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9wYXRod2F5cylbYygyLDkpXSxwdC5zaXplID0gMC41LHNsb3QgPSAiZGF0YSIpICYgbGFicyhjb2xvcj0nbG9nIFRQTScpJgogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMC41KSkKCkZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpW2MoMSwyLDkpXSxwdC5zaXplID0gMC41LHNsb3QgPSAiZGF0YSIpICYgbGFicyhjb2xvcj0nbG9nIFRQTScpJgogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMC41KSkKYGBgCgpgYGB7cn0KbGlicmFyeShnZ3JlcGVsKQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLHZhcnMgPSAgYygiYjJyX3NpZ25hdHVyZSIsIkdPQlBfTk9SRVBJTkVQSFJJTkVfVFJBTlNQT1JUIiwicGF0aWVudC5pZGVudCIpKQphdmVyYWdlX2RhdGExICA9IGRhdGEgJT4lIGdyb3VwX2J5KHBhdGllbnQuaWRlbnQpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShiMnJfbWVhbiA9IG1lYW4oYjJyX3NpZ25hdHVyZSwgbmEucm09VFJVRSkpCgphdmVyYWdlX2RhdGEyICA9IGRhdGEgJT4lIGdyb3VwX2J5KHBhdGllbnQuaWRlbnQpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShlcGlfdHJhbnNfbWVhbiA9IG1lYW4oR09CUF9OT1JFUElORVBIUklORV9UUkFOU1BPUlQsIG5hLnJtPVRSVUUpKQphdmVyYWdlX2FsbCA9IGNiaW5kKGF2ZXJhZ2VfZGF0YTEsYXZlcmFnZV9kYXRhMikKYXZlcmFnZV9hbGwgPSBhdmVyYWdlX2FsbFssYygtMSldCmdncGxvdChhdmVyYWdlX2FsbCwKICAgICAgICAgICBhZXMoeCA9IGIycl9tZWFuLCB5ID0gZXBpX3RyYW5zX21lYW4sIGxhYmVsPXBhdGllbnQuaWRlbnQpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKYGBgCgpgYGB7PWh0bWx9CjxzY3JpcHQgc3JjPSJodHRwczovL2h5cG90aGVzLmlzL2VtYmVkLmpzIiBhc3luYz48L3NjcmlwdD4KYGBgCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNkYXRhKQpsaWJyYXJ5KCdXVlBsb3RzJykKCmNvbG5hbWVzKGRmKSA9IGMoInBhdGllbnQuaWRlbnQiLCJlcGlfc2VjIiwiZXBpX3RyYW5zIiwibm9yYWRyZW5lcmdpY19kZXYiLCAibm9yYWRyZW5lcmdpY19kaWYiLCJhdXRvX25lcnZfZGV2IiwicGFyYXN5bV9uZXJ2IiwiQURSRU5fc2lnIiwiYjJBRFJFTkUiLCJiMnJfc2lnbmF0dXJlIikKUGFpclBsb3QoZGYsIAogICAgICAgICBjb2xuYW1lcyhkZilbMjpsZW5ndGgoZGYpXSwgCiAgICAgICAgICJBbmRlcnNvbidzIElyaXMgRGF0YSAtLSAzIHNwZWNpZXMiLCAKICAgICAgICAgZ3JvdXBfdmFyID0gInBhdGllbnQuaWRlbnQiKSAmICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgJnN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIixzaXplPTMpCmBgYAo=