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

source_from_github(repositoy = "DEG_functions",version = "0.2.47")
ℹ SHA-1 hash of file is f5bb1cd741d13bded83fe3b6fd43169e29731216

3 ACC all cells UMAP

DimPlot(acc_all)

4 Neuronal signatures

DimPlot(acc_all)

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

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

6 Neuronal pathways in ACC cancer cells

6.1 dim reduction

VlnPlot(object = acc_all,features = "CSF3",group.by = "patient.ident")+ ylab("log2 (TPM+1)")

DimPlot(acc_cancer,group.by = "patient.ident")
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)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 951
Number of edges: 28888

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8456
Number of communities: 7
Elapsed time: 0 seconds

6.2 Scores UMAP

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)
}
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ARX, HOXB1, ASCL1, PRLH, PHOX2B, ISX
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: HOXB1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: DRD3, MIR1-1, MIR133A1

6.3 Scores violin

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(plt)

7 ACC2 DEG

 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)

7.1 GSEA- canonical pathways

up = up in ACC2

7.2 GSEA- GO BP

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)
$up

$dn

8 Neuronal pathways in ACC primary cancer cells

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)
Warning in fgsea::fgseaMultilevel(stats = signature, pathways = gsets.obj$genesets,  :
  For some of the pathways the P-values were likely overestimated. For such pathways log2err is set to NA.
hyp_dots(hyp_obj)
$up

$dn

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)
}
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ARX, HOXB1, ASCL1, PRLH, PHOX2B, ISX
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: HOXB1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: DRD3, MIR1-1, MIR133A1

9 Lum vs Myo

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)

LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCiMgRnVuY3Rpb25zCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHN0cmluZ2kpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiREVHX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjIuNDciKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gImNOTUZfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuNC4wIixzY3JpcHRfbmFtZSA9ICJjbm1mX2Z1bmN0aW9uc19WMy5SIikKc291cmNlX2Zyb21fZ2l0aHViKHJlcG9zaXRveSA9ICJzY19nZW5lcmFsX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjEuMjgiLHNjcmlwdF9uYW1lID0gImZ1bmN0aW9ucy5SIikKYGBgCgojIERhdGEKCmBgYHtyfQpsaWJyYXJ5KCJyZWFkeGwiKQphY2NfYWxsID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9hY2NfdHBtX25Db3VudF9taXRvX25vMTQ2XzE1a19hbGxkYXRhLnJkcyIpCmFjY19jYW5jZXJfcHJpID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9hY2NfY2FuY2VyX25vMTQ2X3ByaW1hcnlvbmx5MTVrX2NhbmNlcmNlbGxzLnJkcyIpCmFjY19jYW5jZXIgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX2NhbmNlcmNlbGxzLnJkcyIpCgoKbmV1cm9uYWxfc2lnbmF0dXJlcyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvTmV1cm9uYWwgU2lnbmF0dXJlcy54bHN4Iixjb2xfbmFtZXMgPUYpCm5ldXJvbmFsX3NpZ25hdHVyZXMgICU8PiUgIHQoKSAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBqYW5pdG9yOjpyb3dfdG9fbmFtZXMoMSkgJT4lICBmaWx0ZXIoIXJvd19udW1iZXIoKSA9PSAxKQpyb3duYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSA8LSBOVUxMCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICIiLCBwYXR0ZXJuID0gIl9cXGQuKiIpICNyZW1vdmUgYW55IF9udW1iZXJzCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICIiLCBwYXR0ZXJuID0gIlxcKC4qIikgI3JlbmFtZSAiKCIgdG8gdGhlIGVuZApjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSAgICU8PiUgIGdzdWIocmVwbGFjZW1lbnQgPSAiXyIsIHBhdHRlcm4gPSAiICIpICNyZW5hbWUgYWxsIHNwYWNlcwoKbmV1cm9uYWxfcGF0aHdheXMgPC0gcmVhZF9leGNlbCgiLi9EYXRhL1BhdGh3YXkgYW5hbHlzaXMgR2VuZSBzZXRzLnhsc3giLGNvbF9uYW1lcyA9RikKbmV1cm9uYWxfcGF0aHdheXMgICU8PiUgIHQoKSAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBqYW5pdG9yOjpyb3dfdG9fbmFtZXMoMSkgJT4lICBmaWx0ZXIoIXJvd19udW1iZXIoKSA9PSAxKSAgJT4lICBhcy5saXN0KCkgCm5ldXJvbmFsX3BhdGh3YXlzID0gbGFwcGx5KG5ldXJvbmFsX3BhdGh3YXlzLCBuYS5vbWl0KQpuZXVyb25hbF9wYXRod2F5cyA9IGxhcHBseShuZXVyb25hbF9wYXRod2F5cywgYXMuY2hhcmFjdGVyKQoKYGBgCgojIEFDQyBhbGwgY2VsbHMgVU1BUAoKYGBge3J9CkRpbVBsb3QoYWNjX2FsbCkKYGBgCgojIE5ldXJvbmFsIHNpZ25hdHVyZXMKCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpmb3IgKG5ldXJhbF9uYW1lIGluIGNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9zaWduYXR1cmVzWyxuZXVyYWxfbmFtZSxkcm9wPVRdCiAgIyBBc3N1bWluZyBkZiBpcyB5b3VyIGRhdGEgZnJhbWUKCiAgCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19hbGwsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBuZXVyYWxfbmFtZSkKfQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KcGx0ID0gVmxuUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpCnBsdFtbMV1dID0gcGx0W1sxXV0rIHlsYWIoIlRQTSIpCnBsdFtbNF1dID0gcGx0W1s0XV0rIHlsYWIoIlRQTSIpCnBsdFtbN11dID0gcGx0W1s3XV0rIHlsYWIoIlRQTSIpCnBsdApgYGAKCiMgQ1NGMwoKW1NpbmdsZS1jZWxsIFJOQSBzZXF1ZW5jaW5nIHJldmVhbHMgaW50cmF0dW1vcmFsIGhldGVyb2dlbmVpdHkgYW5kIHBvdGVudGlhbCBtZWNoYW5pc21zIG9mIG1hbGlnbmFudCBwcm9ncmVzc2lvbiBpbiBwcm9zdGF0ZSBjYW5jZXIgd2l0aCBwZXJpbmV1cmFsIGludmFzaW9uXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3BtYy9hcnRpY2xlcy9QTUM5ODc1Nzk5LykKCmBgYHtyfQpWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSAiQ1NGMyIsZ3JvdXAuYnkgPSAicGF0aWVudC5pZGVudCIpKyB5bGFiKCJsb2cyIChUUE0rMSkiKQpgYGAKCiMgTmV1cm9uYWwgcGF0aHdheXMgaW4gQUNDIGNhbmNlciBjZWxscwoKIyMgZGltIHJlZHVjdGlvbgoKYGBge3J9CmFjY19jYW5jZXIgPC0gUnVuUENBKGFjY19jYW5jZXIsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBhY2NfY2FuY2VyKSx2ZXJib3NlID0gRikKRWxib3dQbG90KGFjY19jYW5jZXIpCmFjY19jYW5jZXIgPC0gRmluZE5laWdoYm9ycyhhY2NfY2FuY2VyLCBkaW1zID0gMToxMCx2ZXJib3NlID0gRikgJT4lICBGaW5kQ2x1c3RlcnMocmVzb2x1dGlvbiA9IDAuNSkgJT4lICBSdW5VTUFQKGRpbXMgPSAxOjEwLHZlcmJvc2UgPSBGKQpgYGAKCmBgYHtyfQpEaW1QbG90KGFjY19jYW5jZXIsZ3JvdXAuYnkgPSAicGF0aWVudC5pZGVudCIpCmBgYAoKYGBge3J9CmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXIsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19jYW5jZXIgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBwYXRod2F5X25hbWUpCn0KYGBgCgojIyBTY29yZXMgVU1BUAoKYGBge3IgZmlnLmhlaWdodD0xMywgZmlnLndpZHRoPTEzfQpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKQpmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpKyBsYWJzKGNvbG9yPSdUUE0nKSAKfQpwcmludChwbHQpCmBgYAoKIyMgU2NvcmVzIHZpb2xpbgoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQogcGx0ID0gVmxuUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpLGdyb3VwLmJ5ID0gInBhdGllbnQuaWRlbnQiKSt0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzKSkKIApmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9OS41KSkKICBpZiAoaSAlaW4lIGMoMSw0LDcpKSB7CiAgICBwbHRbW2ldXSA9IHBsdFtbaV1dK3lsYWIoIlRQTSIpCiAgfQp9CnByaW50KHBsdCkKYGBgCgojIEFDQzIgREVHCgpgYGB7cn0KYWNjX2NhbmNlcl9wcmkgPSBTZXRJZGVudChvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSx2YWx1ZSA9ICJwYXRpZW50LmlkZW50IikKbWFya2VycyA9IEZpbmRNYXJrZXJzKG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLGlkZW50LjEgPSAiQUNDMiIsZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKGFjY19jYW5jZXJfcHJpKSxkZW5zaWZ5ID0gVCkKdm9sY2Fub19wbG90KGRlX2dlbmVzID0gbWFya2VycyxtYXhfbmFtZXMgPSAxMCx0aXRsZSA9ICIiLGlkZW50MSA9ICJBQ0MyIixpZGVudDIgPSAiUE5JIHBhdGllbnRzIixzaG93X2dyYXBoID0gRixsb2cyZmNfY3V0b2ZmID0gMSkKYGBgCgojIyBHU0VBLSBjYW5vbmljYWwgcGF0aHdheXMKCnVwID0gdXAgaW4gQUNDMgoKYGBge3J9CmxpYnJhcnkoaHlwZVIpCmdlbmVzZXRzIDwtIG1zaWdkYl9kb3dubG9hZCgiSG9tbyBzYXBpZW5zIixjYXRlZ29yeT0iSCIpICU+JSBhcHBlbmQoIG1zaWdkYl9kb3dubG9hZCgiSG9tbyBzYXBpZW5zIixjYXRlZ29yeT0iQzIiLHN1YmNhdGVnb3J5ID0gIkNQIikpCmFsbF9nZW5lcyA9IG1hcmtlcnMgICU+JSAgYXJyYW5nZShkZXNjKGF2Z19sb2cyRkMpKSAlPiUgc2VsZWN0KCJhdmdfbG9nMkZDIikgCnJhbmtlZF9saXN0ICAgPC0gc2V0TmFtZXMoYWxsX2dlbmVzJGF2Z19sb2cyRkMsIHJvd25hbWVzKGFsbF9nZW5lcykpCmh5cF9vYmogPC0gaHlwZVJfZmdzZWEoc2lnbmF0dXJlID0gcmFua2VkX2xpc3QsZ2VuZXNldHMgPSAgZ2VuZXNldHMsdXBfb25seSA9IEYpCmh5cF9kb3RzKGh5cF9vYmopCmBgYAoKIyMgR1NFQS0gR08gQlAKCmBgYHtyfQpnZW5lc2V0cyA8LSBtc2lnZGJfZG93bmxvYWQoIkhvbW8gc2FwaWVucyIsY2F0ZWdvcnk9IkgiKSAlPiUgYXBwZW5kKCBtc2lnZGJfZG93bmxvYWQoIkhvbW8gc2FwaWVucyIsY2F0ZWdvcnk9IkM1IixzdWJjYXRlZ29yeSA9ICJHTzpCUCIpKQphbGxfZ2VuZXMgPSBtYXJrZXJzICAlPiUgIGFycmFuZ2UoZGVzYyhhdmdfbG9nMkZDKSkgJT4lIHNlbGVjdCgiYXZnX2xvZzJGQyIpIApyYW5rZWRfbGlzdCAgIDwtIHNldE5hbWVzKGFsbF9nZW5lcyRhdmdfbG9nMkZDLCByb3duYW1lcyhhbGxfZ2VuZXMpKQpoeXBfb2JqIDwtIGh5cGVSX2Znc2VhKHNpZ25hdHVyZSA9IHJhbmtlZF9saXN0LGdlbmVzZXRzID0gIGdlbmVzZXRzLHVwX29ubHkgPSBGKQpoeXBfZG90cyhoeXBfb2JqKQpgYGAKCmBgYHs9aHRtbH0KPHNjcmlwdCBzcmM9Imh0dHBzOi8vaHlwb3RoZXMuaXMvZW1iZWQuanMiIGFzeW5jPjwvc2NyaXB0PgpgYGAKIyBOZXVyb25hbCBwYXRod2F5cyBpbiBBQ0MgcHJpbWFyeSBjYW5jZXIgY2VsbHMKCmBgYHtyfQpsdW1fc2NvcmUgPSBGZXRjaERhdGEoYWNjX2NhbmNlcl9wcmksImx1bWluYWxfb3Zlcl9teW8iKQpsdW1fc2NvcmUgICU8PiUgbXV0YXRlIChsdW1fb3JfbXlvID0gY2FzZV93aGVuKAogICAgICAgICBsdW1pbmFsX292ZXJfbXlvID4gMSB+ICJsdW1pbmFsIiwKICAgICAgICAgbHVtaW5hbF9vdmVyX215byA8ICgtMSkgfiAibXlvIiwKICAgICAgICAgVFJVRSB+ICJ1bmtub3duIikpCmFjY19jYW5jZXJfcHJpICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gbHVtX3Njb3JlJGx1bV9vcl9teW8sY29sLm5hbWUgPSAibHVtX29yX215byIpCmBgYAoKYGBge3J9CmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19jYW5jZXJfcHJpICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gcGF0aHdheV9uYW1lKQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMywgZmlnLndpZHRoPTEzfQpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSxmZWF0dXJlcyA9ICBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykpCgpmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpKyBsYWJzKGNvbG9yPSdUUE0nKSAKfQpwcmludChwbHQpCmBgYAoKIyBMdW0gdnMgTXlvIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoZ2dwdWJyKQpmb3IgKHBhdGh3YXkgaW4gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKSB7CiAgZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSx2YXJzID0gYygibHVtX29yX215byIscGF0aHdheSkpICU+JSBmaWx0ZXIobHVtX29yX215byAhPSAidW5rbm93biIpCiAgcCA9IGdnYm94cGxvdChkYXRhLCB4ID0gImx1bV9vcl9teW8iLCB5ID1wYXRod2F5LAogICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJqY28iLAogICAgICAgICAgICAgICAgYWRkID0gImppdHRlciIpKyAKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLGNvbXBhcmlzb25zID0gbGlzdChjKCJsdW1pbmFsIiwibXlvIikpKSsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gZnVuY3Rpb24oeCkgZGF0YS5mcmFtZSh5PW1heCh4KSoxLjIsIGxhYmVsID0gcGFzdGUoIk1lYW49Iixyb3VuZChtZWFuKHgpLGRpZ2l0cyA9IDIpKSksIGdlb209InRleHQiKSAreWxhYigiVFBNIikrZ2d0aXRsZShwYXRod2F5KQogIHByaW50X3RhYihwLHRpdGxlID0gcGF0aHdheSkKfQoKYGBgCg==