PWF for DOWN regulated genes
go_title.down <- 'GO enrichment for U343 T24_vs_T21_DOWN'
pwf.down = nullp(u343_t25_down.genes, "hg38", "ensGene", bias.data = lengthData.down)
PWF for UP regulated genes
pwf.up = nullp(u343_t25_up.genes, "hg38", "ensGene", bias.data = lengthData.up)
GO.wall.up <- goseq(pwf.up,"hg38","ensGene",test.cats=c("GO:BP"))
GO.wall.up$padj <- p.adjust(GO.wall.up$over_represented_pvalue, method="BH")
GO.wall.up
GO.wall.up <- subset(GO.wall.up, GO.wall.up$padj<.05)
GO.wall.up[["ratio"]] <- GO.wall.up[["numDEInCat"]] / GO.wall.up[["numInCat"]]
GO.wall.down <- goseq(pwf.down, "hg38","ensGene",test.cats=c("GO:BP"))
GO.wall.down$padj <- p.adjust(GO.wall.down$over_represented_pvalue, method="BH")
GO.wall.down <- subset(GO.wall.down, GO.wall.down$padj<.05)
GO.wall.down[["ratio"]] <- GO.wall.down[["numDEInCat"]] / GO.wall.down[["numInCat"]]
Go enrichment DOWN regulated
No enricment for DOWN in KEGG or UP in KEGG/GO.
barplot(GO.wall.down, showCategory = 15)
dotplot(GO.wall.down)
KEGG.up <- goseq(pwf.up, 'hg38', 'ensGene', test.cats="KEGG")
KEGG.up$padj <- p.adjust(KEGG.up$over_represented_pvalue, method="BH")
KEGG.up.sig <- subset(KEGG.up, KEGG.up$padj<.05)
KEGG.up.sig[["ratio"]] <- KEGG.up.sig[["numDEInCat"]] / KEGG.up[["numInCat"]]
KEGG.down <- goseq(pwf.down, 'hg38', 'ensGene', test.cats="KEGG")
KEGG.down$padj <- p.adjust(KEGG.down$over_represented_pvalue, method="BH")
KEGG.down.sig <- subset(KEGG.down, KEGG.down$padj<.05)
KEGG.down.sig[["ratio"]] <- KEGG.down.sig[["numDEInCat"]] / KEGG.down.sig[["numInCat"]]
human <- useMart('ensembl', dataset = 'hsapiens_gene_ensembl')
attributes <- c('ensembl_gene_id',
'entrezgene')
ensembl.entrez <- getBM(attributes,
values="*",
mart = human,
bmHeader=FALSE)
ensembl2entrez <- as.character(ensembl.entrez$entrezgene)
names(ensembl2entrez) <- ensembl.entrez$ensembl_gene_id
ensembl2entrez <- as.list(ensembl2entrez)
get_kegg <- function(l)
{
return( keggLink("pathway", l))
}
entrez.kegg <- paste('hsa', unique(ensembl2entrez), sep=":")
entrez.kegg.splitted <- split( entrez.kegg, ceiling(seq_along( entrez.kegg)/20))
entrez.kegg.pathways <- lapply(entrez.kegg.splitted, get_kegg)
entrez.kegg.pathways.red <- Reduce(c, entrez.kegg.pathways)
grepKEGG <- function(geneid, pathway_map){
if (!is.na(geneid))
{
return (unique(unlist(pathway_map[names(pathway_map) == paste('hsa', geneid, sep=':')])))
}
}
gene2cat <- lapply(ensembl2entrez,grepKEGG, entrez.kegg.pathways.red)
getPathwayName <- function(x){
y <- keggGet(x)
return (as.character(unlist(strsplit(y[[1]]$NAME, '-'))[1]))
}
pwf.down <- nullp(u343_t25_down.genes, "hg38", "ensGene", bias.data = lengthData.down)
KEGG.down.custom <- goseq(pwf.down, gene2cat = gene2cat)
KEGG.down.custom$term <- unlist(lapply(KEGG.down.custom$category, getPathwayName))
KEGG.down.custom[["ratio"]] <- KEGG.down.custom[["numDEInCat"]] / KEGG.down.custom[["numInCat"]]
KEGG.down.custom$padj <- p.adjust(KEGG.down.custom$over_represented_pvalue, method="BH")
KEGG.down.custom.sig <- subset(KEGG.down.custom, KEGG.down.custom$padj<.05)
dotplot(KEGG.down.custom)
KEGG.up.custom <- goseq(pwf.up, gene2cat=gene2cat)
KEGG.up.custom$term <- unlist(lapply(KEGG.up.custom$category, getPathwayName))
KEGG.up.custom[["ratio"]] <- KEGG.up.custom[["numDEInCat"]] / KEGG.up.custom[["numInCat"]]
KEGG.up.custom$padj <- p.adjust(KEGG.up.custom$over_represented_pvalue, method="BH")
KEGG.up.custom.sig <- subset(KEGG.up.custom, KEGG.up.custom$padj<.05)
dotplot(KEGG.up.custom)
LS0tCnRpdGxlOiAiVTM0MyBUMjQgUmFkaWF0aW9uIEdPU2VxIGFuYWx5c2lzIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICBmaWdfaGVpZ2h0OiAzMAogICAgZmlnX3dpZHRoOiAzMApkYXRlOiAiMDMvMjYvMjAxNyIKCi0tLQoKYGBge3IsIGVjaG89VFJVRSwgcmVzdWx0cz0naGlkZScsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFfQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkob3JnLkhzLmVnLmRiKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGdvc2VxKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KEdlbm9taWNGZWF0dXJlcykpCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShnZ3Bsb3QyKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KEtFR0dSRVNUKSkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGJpb21hUnQpKQoKYmFycGxvdCA8LSBmdW5jdGlvbihkZiwgc2hvd0NhdGVnb3J5PTE1KXsKICBkZiA8LSBkZlt3aXRoKGRmLCBvcmRlcihwYWRqLCByYXRpbywgZGVjcmVhc2luZyA9IGMoRkFMU0UsIFRSVUUpKSksXQogIGRmIDwtIGhlYWQoZGYsIG49c2hvd0NhdGVnb3J5KQogIGJyZWFrcyA8LSByb3VuZCggYygwLCAxLzQsIDIvNCwgMy80LCAxKSAqIG1heChkZltbJ3JhdGlvJ11dKSAsIDIpCiAgcHZhbHVlX3Bsb3QgPC0gZ2dwbG90KGRmLCBhZXNfc3RyaW5nKHg9InRlcm0iLCB5PSJyYXRpbyIsIGZpbGw9InBhZGoiKSkgKwogICAgICAgICAgICAgICAgICBnZW9tX2NvbCgpICsKICAgICAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsIDApLCBicmVha3M9YnJlYWtzLCBsaW1pdHM9YygwLCBtYXgoZGZbWyJyYXRpbyJdXSswLjA1KSkpICsKICAgICAgICAgICAgICAgICAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lPSdHTyB0ZXJtJykgKwogICAgICAgICAgICAgICAgICBzY2FsZV9maWxsX2NvbnRpbnVvdXMobG93PSIjMDBkYmRlIiwgaGlnaD0iI0ZGRjk0QyIpICsgCiAgICAgICAgICAgICAgICAgIHRoZW1lKHRleHQ9Z2dwbG90Mjo6ZWxlbWVudF90ZXh0KHNpemU9OSkpICsKICAgICAgICAgICAgICAgICAgY29vcmRfZmxpcCgpICsKICAgICAgICAgICAgICAgICAgdGhlbWVfYncoYmFzZV9zaXplPTkpCiAgcmV0dXJuKHB2YWx1ZV9wbG90KQp9Cgpkb3RwbG90IDwtIGZ1bmN0aW9uKGRmLCBzaG93Q2F0ZWdvcnk9MTUpewogIGRmIDwtIGRmW3dpdGgoZGYsIG9yZGVyKHBhZGosIHJhdGlvLCBkZWNyZWFzaW5nID0gYyhGQUxTRSwgVFJVRSkpKSxdCiAgZGYgPC0gaGVhZChkZiwgbj1zaG93Q2F0ZWdvcnkpCiAgZF9wbG90IDwtIGdncGxvdChkZiwgYWVzX3N0cmluZyh4PSJ0ZXJtIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5PSJyYXRpbyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyPSJwYWRqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9Im51bURFSW5DYXQiKSkgKyAKICAgICAgICAgIGdlb21fcG9pbnQoKSArCiAgICAgICAgICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3c9IiMwMGRiZGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlnaD0iI0ZGRjk0QyIpICsKICAgICAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgICAgICB0aGVtZV9idyhiYXNlX3NpemU9OSkKICByZXR1cm4oZF9wbG90KQp9CmBgYAoKCmBgYHtyLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2hpZGUnLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KZ3RmICA8LSAnL21lZGlhL2RuYS9nZW5vbWVzL2hnMzgvYW5ub3RhdGlvbi9nZW5jb2RlLnYyNS5hbm5vdGF0aW9uLmd0ZicKdHhkYiA8LSBtYWtlVHhEYkZyb21HRkYoZ3RmKQp0eHNCeUdlbmUgPC0gdHJhbnNjcmlwdHNCeSh0eGRiLCAiZ2VuZSIpCmxlbmd0aERhdGEgPC0gbWVkaWFuKHdpZHRoKHR4c0J5R2VuZSkpCm5hbWVzKGxlbmd0aERhdGEpIDwtIGdzdWIoJ1xcLlswLTldKycsICcnLCBuYW1lcyhsZW5ndGhEYXRhKSkKCmdvLm91dGRpciA8LSAnL21lZGlhL2RuYS9naXRodWIvcmFkaWF0aW9uX3Byb2plY3QvZGF0YS9ob2RhX2FuYWx5c2lzL1UzNDMvR09fYW5hbHlzaXMnCmtlZ2cub3V0ZGlyIDwtICcvbWVkaWEvZG5hL2dpdGh1Yi9yYWRpYXRpb25fcHJvamVjdC9kYXRhL2hvZGFfYW5hbHlzaXMvVTM0My9LRUdHX2FuYWx5c2lzJwpkYXZpZC5vdXRkaXIgPC0gJy9tZWRpYS9kbmEvZ2l0aHViL3JhZGlhdGlvbl9wcm9qZWN0L2RhdGEvaG9kYV9hbmFseXNpcy9VMzQzL0RBVklEX2FuYWx5c2lzJwpwcmVmaXgudXAgPC0gJ1QyNF92c19UMF9VUC50c3YnCnByZWZpeC5kb3duIDwtICdUMjRfdnNfVDBfRE9XTi50c3YnCmBgYAoKYGBge3IsIGVjaG89VFJVRSwgcmVzdWx0cz0naGlkZScsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFfQp1MzQzX3QyNC5yaWJvLmRlc2VxMiA8LSByZWFkLnRhYmxlKCcvaG9tZS9zYWtldC9Ecm9wYm94L1BoRF9Qcm9qZWN0cy9SYWRpYXRpb24tTmV3LUFuYWx5c2lzL1UzNDMgY2VsbCBsaW5lL0RFX2FuYWx5c2lzL1UzNDNfUmlib1NlcV9UMjRfVlNfVDAuYWxsLnRzdicsIGhlYWRlcj1ULCBzZXA9JyAnKQp1MzQzX3QyNC5yaWJvLmRlc2VxMiRjaGFuZ2UgPC0gTkEKdTM0M190MjQucmliby5kZXNlcTIkY2hhbmdlW3UzNDNfdDI0LnJpYm8uZGVzZXEyJGxvZzJGb2xkQ2hhbmdlPDBdIDwtICdET1dOJwp1MzQzX3QyNC5yaWJvLmRlc2VxMiRjaGFuZ2VbdTM0M190MjQucmliby5kZXNlcTIkbG9nMkZvbGRDaGFuZ2U+MF0gPC0gJ1VQJwoKCnUzNDNfdDI0LnJuYS5kZXNlcTIgPC0gcmVhZC50YWJsZSgnL2hvbWUvc2FrZXQvRHJvcGJveC9QaERfUHJvamVjdHMvUmFkaWF0aW9uLU5ldy1BbmFseXNpcy9VMzQzIGNlbGwgbGluZS9ERV9hbmFseXNpcy9VMzQzX1JOQXNlcV9UMjRfVlNfVDAuYWxsLnRzdicsIGhlYWRlcj1ULCBzZXA9JyAnKQp1MzQzX3QyNC5ybmEuZGVzZXEyJGNoYW5nZSA8LSBOQQp1MzQzX3QyNC5ybmEuZGVzZXEyJGNoYW5nZVt1MzQzX3QyNC5ybmEuZGVzZXEyJGxvZzJGb2xkQ2hhbmdlPDBdIDwtICdET1dOJwp1MzQzX3QyNC5ybmEuZGVzZXEyJGNoYW5nZVt1MzQzX3QyNC5ybmEuZGVzZXEyJGxvZzJGb2xkQ2hhbmdlPjBdIDwtICdVUCcKCnUzNDNfdDI0LnJpYm8uZGVzZXEyIDwtIHN1YnNldCh1MzQzX3QyNC5yaWJvLmRlc2VxMiwgaXMuZmluaXRlKHUzNDNfdDI0LnJpYm8uZGVzZXEyJHBhZGopKQp1MzQzX3QyNC5ybmEuZGVzZXEyIDwtIHN1YnNldCh1MzQzX3QyNC5ybmEuZGVzZXEyLCBpcy5maW5pdGUodTM0M190MjQucm5hLmRlc2VxMiRwYWRqKSkKCm1lcmdlZC5kZXNlcTIgPC0gbWVyZ2UodTM0M190MjQucm5hLmRlc2VxMiwgdTM0M190MjQucmliby5kZXNlcTIsIHN1ZmZpeGVzPWMoJ19ybmEnLCAnX3JpYm8nKSwgYnk9InJvdy5uYW1lcyIpCmRpbShtZXJnZWQuZGVzZXEyKQpgYGAKCmBgYHtyLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2hpZGUnLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KbWVyZ2VkLmRlc2VxMi5jb25jb3JkYW50IDwtIG1lcmdlZC5kZXNlcTJbbWVyZ2VkLmRlc2VxMiRjaGFuZ2Vfcmlibz09bWVyZ2VkLmRlc2VxMiRjaGFuZ2Vfcm5hLF0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCnUzNDNfdDI0X2Rvd24uZGVzZXEyIDwtIHN1YnNldChtZXJnZWQuZGVzZXEyLmNvbmNvcmRhbnQsIG1lcmdlZC5kZXNlcTIuY29uY29yZGFudCRjaGFuZ2Vfcmlibz09J0RPV04nKQp1MzQzX3QyNF9kb3duLmRlc2VxMiA8LSBzdWJzZXQodTM0M190MjRfZG93bi5kZXNlcTIsIGlzLmZpbml0ZSh1MzQzX3QyNF9kb3duLmRlc2VxMiRwYWRqX3JuYSkgJiBpcy5maW5pdGUodTM0M190MjRfZG93bi5kZXNlcTIkcGFkal9yaWJvKSApCnUzNDNfdDI1X2Rvd24uZ2VuZXMgPC0gYXMuaW50ZWdlcih1MzQzX3QyNF9kb3duLmRlc2VxMiRwYWRqX3JuYTwuMDUgJiB1MzQzX3QyNF9kb3duLmRlc2VxMiRwYWRqX3JpYm88LjA1KQpuYW1lcyh1MzQzX3QyNV9kb3duLmdlbmVzKSA8LSB1MzQzX3QyNF9kb3duLmRlc2VxMiRSb3cubmFtZXMKCnUzNDNfdDI0X3VwLmRlc2VxMiA8LSBzdWJzZXQobWVyZ2VkLmRlc2VxMi5jb25jb3JkYW50LCBtZXJnZWQuZGVzZXEyLmNvbmNvcmRhbnQkY2hhbmdlX3JpYm89PSdVUCcpCnUzNDNfdDI0X3VwLmRlc2VxMiA8LSBzdWJzZXQodTM0M190MjRfdXAuZGVzZXEyLCBpcy5maW5pdGUodTM0M190MjRfdXAuZGVzZXEyJHBhZGpfcm5hKSAmIGlzLmZpbml0ZSh1MzQzX3QyNF91cC5kZXNlcTIkcGFkal9yaWJvKSkKdTM0M190MjVfdXAuZ2VuZXMgPC0gYXMuaW50ZWdlcih1MzQzX3QyNF91cC5kZXNlcTIkcGFkal9yaWJvPC4wNSAmIHUzNDNfdDI0X3VwLmRlc2VxMiRwYWRqX3JuYTwuMDUpCm5hbWVzKHUzNDNfdDI1X3VwLmdlbmVzKSA8LSB1MzQzX3QyNF91cC5kZXNlcTIkUm93Lm5hbWVzCgpsZW5ndGhEYXRhLnVwIDwtIGxlbmd0aERhdGFbbmFtZXModTM0M190MjVfdXAuZ2VuZXMpXQpsZW5ndGhEYXRhLmRvd24gPC0gbGVuZ3RoRGF0YVtuYW1lcyh1MzQzX3QyNV9kb3duLmdlbmVzKV0KYGBgCgoKIyMgUFdGIGZvciBET1dOIHJlZ3VsYXRlZCBnZW5lcwpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KZ29fdGl0bGUuZG93biA8LSAnR08gZW5yaWNobWVudCBmb3IgVTM0MyBUMjRfdnNfVDIxX0RPV04nCnB3Zi5kb3duICA9IG51bGxwKHUzNDNfdDI1X2Rvd24uZ2VuZXMsICJoZzM4IiwgImVuc0dlbmUiLCBiaWFzLmRhdGEgPSBsZW5ndGhEYXRhLmRvd24pCmBgYAoKIyMgUFdGIGZvciBVUCByZWd1bGF0ZWQgZ2VuZXMKYGBge3IsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9CnB3Zi51cCAgPSBudWxscCh1MzQzX3QyNV91cC5nZW5lcywgImhnMzgiLCAiZW5zR2VuZSIsIGJpYXMuZGF0YSA9IGxlbmd0aERhdGEudXApCmBgYAoKYGBge3IsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9CkdPLndhbGwudXAgPC0gZ29zZXEocHdmLnVwLCJoZzM4IiwiZW5zR2VuZSIsdGVzdC5jYXRzPWMoIkdPOkJQIikpCkdPLndhbGwudXAkcGFkaiA8LSBwLmFkanVzdChHTy53YWxsLnVwJG92ZXJfcmVwcmVzZW50ZWRfcHZhbHVlLCBtZXRob2Q9IkJIIikKR08ud2FsbC51cApgYGAKCmBgYHtyLCBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFfQpHTy53YWxsLnVwIDwtIHN1YnNldChHTy53YWxsLnVwLCBHTy53YWxsLnVwJHBhZGo8LjA1KQpHTy53YWxsLnVwW1sicmF0aW8iXV0gPC0gR08ud2FsbC51cFtbIm51bURFSW5DYXQiXV0gLyBHTy53YWxsLnVwW1sibnVtSW5DYXQiXV0KCkdPLndhbGwuZG93biA8LSBnb3NlcShwd2YuZG93biwgImhnMzgiLCJlbnNHZW5lIix0ZXN0LmNhdHM9YygiR086QlAiKSkKR08ud2FsbC5kb3duJHBhZGogPC0gcC5hZGp1c3QoR08ud2FsbC5kb3duJG92ZXJfcmVwcmVzZW50ZWRfcHZhbHVlLCBtZXRob2Q9IkJIIikKR08ud2FsbC5kb3duIDwtIHN1YnNldChHTy53YWxsLmRvd24sIEdPLndhbGwuZG93biRwYWRqPC4wNSkKR08ud2FsbC5kb3duW1sicmF0aW8iXV0gPC0gR08ud2FsbC5kb3duW1sibnVtREVJbkNhdCJdXSAvIEdPLndhbGwuZG93bltbIm51bUluQ2F0Il1dCgpgYGAKIyMgR28gZW5yaWNobWVudCBET1dOIHJlZ3VsYXRlZAoKTm8gZW5yaWNtZW50IGZvciBET1dOIGluIEtFR0cgb3IgVVAgaW4gS0VHRy9HTy4KYGBge3IsIGVjaG89VFJVRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9CmJhcnBsb3QoR08ud2FsbC5kb3duLCBzaG93Q2F0ZWdvcnkgPSAxNSkKYGBgCgpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KZG90cGxvdChHTy53YWxsLmRvd24pCmBgYAoKCmBgYHtyLCBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFLCBldmFsPUZBTFNFfQpLRUdHLnVwIDwtIGdvc2VxKHB3Zi51cCwgJ2hnMzgnLCAnZW5zR2VuZScsIHRlc3QuY2F0cz0iS0VHRyIpCktFR0cudXAkcGFkaiA8LSBwLmFkanVzdChLRUdHLnVwJG92ZXJfcmVwcmVzZW50ZWRfcHZhbHVlLCBtZXRob2Q9IkJIIikKS0VHRy51cC5zaWcgPC0gc3Vic2V0KEtFR0cudXAsIEtFR0cudXAkcGFkajwuMDUpCktFR0cudXAuc2lnW1sicmF0aW8iXV0gPC0gS0VHRy51cC5zaWdbWyJudW1ERUluQ2F0Il1dIC8gS0VHRy51cFtbIm51bUluQ2F0Il1dCgpgYGAKCgpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgZXZhbD1GQUxTRX0KS0VHRy5kb3duIDwtIGdvc2VxKHB3Zi5kb3duLCAnaGczOCcsICdlbnNHZW5lJywgdGVzdC5jYXRzPSJLRUdHIikKS0VHRy5kb3duJHBhZGogPC0gcC5hZGp1c3QoS0VHRy5kb3duJG92ZXJfcmVwcmVzZW50ZWRfcHZhbHVlLCBtZXRob2Q9IkJIIikKS0VHRy5kb3duLnNpZyA8LSBzdWJzZXQoS0VHRy5kb3duLCBLRUdHLmRvd24kcGFkajwuMDUpCktFR0cuZG93bi5zaWdbWyJyYXRpbyJdXSA8LSBLRUdHLmRvd24uc2lnW1sibnVtREVJbkNhdCJdXSAvIEtFR0cuZG93bi5zaWdbWyJudW1JbkNhdCJdXQpgYGAKCgpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KaHVtYW4gPC0gdXNlTWFydCgnZW5zZW1ibCcsIGRhdGFzZXQgPSAnaHNhcGllbnNfZ2VuZV9lbnNlbWJsJykKYXR0cmlidXRlcyA8LSBjKCdlbnNlbWJsX2dlbmVfaWQnLAogICAgICAgICAgICAgICAgJ2VudHJlemdlbmUnKQoKZW5zZW1ibC5lbnRyZXogPC0gZ2V0Qk0oYXR0cmlidXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz0iKiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFydCA9IGh1bWFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm1IZWFkZXI9RkFMU0UpCmVuc2VtYmwyZW50cmV6IDwtIGFzLmNoYXJhY3RlcihlbnNlbWJsLmVudHJleiRlbnRyZXpnZW5lKQpuYW1lcyhlbnNlbWJsMmVudHJleikgPC0gZW5zZW1ibC5lbnRyZXokZW5zZW1ibF9nZW5lX2lkCmVuc2VtYmwyZW50cmV6IDwtIGFzLmxpc3QoZW5zZW1ibDJlbnRyZXopCgpnZXRfa2VnZyA8LSBmdW5jdGlvbihsKQp7CiAgcmV0dXJuKCBrZWdnTGluaygicGF0aHdheSIsIGwpKQp9CgplbnRyZXoua2VnZyA8LSBwYXN0ZSgnaHNhJywgdW5pcXVlKGVuc2VtYmwyZW50cmV6KSwgc2VwPSI6IikKZW50cmV6LmtlZ2cuc3BsaXR0ZWQgPC0gc3BsaXQoIGVudHJlei5rZWdnLCBjZWlsaW5nKHNlcV9hbG9uZyggZW50cmV6LmtlZ2cpLzIwKSkKZW50cmV6LmtlZ2cucGF0aHdheXMgPC0gbGFwcGx5KGVudHJlei5rZWdnLnNwbGl0dGVkLCBnZXRfa2VnZykgCmVudHJlei5rZWdnLnBhdGh3YXlzLnJlZCA8LSBSZWR1Y2UoYywgZW50cmV6LmtlZ2cucGF0aHdheXMpCmdyZXBLRUdHIDwtIGZ1bmN0aW9uKGdlbmVpZCwgcGF0aHdheV9tYXApewogIGlmICghaXMubmEoZ2VuZWlkKSkKICB7CiAgICByZXR1cm4gKHVuaXF1ZSh1bmxpc3QocGF0aHdheV9tYXBbbmFtZXMocGF0aHdheV9tYXApID09IHBhc3RlKCdoc2EnLCBnZW5laWQsIHNlcD0nOicpXSkpKQogIH0KfQpnZW5lMmNhdCA8LSBsYXBwbHkoZW5zZW1ibDJlbnRyZXosZ3JlcEtFR0csIGVudHJlei5rZWdnLnBhdGh3YXlzLnJlZCkKYGBgCgpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KZ2V0UGF0aHdheU5hbWUgPC0gZnVuY3Rpb24oeCl7CiAgeSA8LSBrZWdnR2V0KHgpCiAgcmV0dXJuIChhcy5jaGFyYWN0ZXIodW5saXN0KHN0cnNwbGl0KHlbWzFdXSROQU1FLCAnLScpKVsxXSkpCn0KYGBgCgpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0KcHdmLmRvd24gIDwtIG51bGxwKHUzNDNfdDI1X2Rvd24uZ2VuZXMsICJoZzM4IiwgImVuc0dlbmUiLCBiaWFzLmRhdGEgPSBsZW5ndGhEYXRhLmRvd24pCktFR0cuZG93bi5jdXN0b20gPC0gZ29zZXEocHdmLmRvd24sIGdlbmUyY2F0ID0gZ2VuZTJjYXQpCktFR0cuZG93bi5jdXN0b20kdGVybSA8LSB1bmxpc3QobGFwcGx5KEtFR0cuZG93bi5jdXN0b20kY2F0ZWdvcnksIGdldFBhdGh3YXlOYW1lKSkKS0VHRy5kb3duLmN1c3RvbVtbInJhdGlvIl1dIDwtIEtFR0cuZG93bi5jdXN0b21bWyJudW1ERUluQ2F0Il1dIC8gS0VHRy5kb3duLmN1c3RvbVtbIm51bUluQ2F0Il1dCgpLRUdHLmRvd24uY3VzdG9tJHBhZGogPC0gcC5hZGp1c3QoS0VHRy5kb3duLmN1c3RvbSRvdmVyX3JlcHJlc2VudGVkX3B2YWx1ZSwgbWV0aG9kPSJCSCIpCktFR0cuZG93bi5jdXN0b20uc2lnIDwtIHN1YnNldChLRUdHLmRvd24uY3VzdG9tLCBLRUdHLmRvd24uY3VzdG9tJHBhZGo8LjA1KQoKYGBgCgpgYGB7cn0KZG90cGxvdChLRUdHLmRvd24uY3VzdG9tKQpgYGAKCmBgYHtyLCBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFfQpLRUdHLnVwLmN1c3RvbSA8LSBnb3NlcShwd2YudXAsIGdlbmUyY2F0PWdlbmUyY2F0KQpLRUdHLnVwLmN1c3RvbSR0ZXJtIDwtIHVubGlzdChsYXBwbHkoS0VHRy51cC5jdXN0b20kY2F0ZWdvcnksIGdldFBhdGh3YXlOYW1lKSkKS0VHRy51cC5jdXN0b21bWyJyYXRpbyJdXSA8LSBLRUdHLnVwLmN1c3RvbVtbIm51bURFSW5DYXQiXV0gLyBLRUdHLnVwLmN1c3RvbVtbIm51bUluQ2F0Il1dCgpLRUdHLnVwLmN1c3RvbSRwYWRqIDwtIHAuYWRqdXN0KEtFR0cudXAuY3VzdG9tJG92ZXJfcmVwcmVzZW50ZWRfcHZhbHVlLCBtZXRob2Q9IkJIIikKS0VHRy51cC5jdXN0b20uc2lnIDwtIHN1YnNldChLRUdHLnVwLmN1c3RvbSwgS0VHRy51cC5jdXN0b20kcGFkajwuMDUpCmBgYAoKYGBge3J9CmRvdHBsb3QoS0VHRy51cC5jdXN0b20pCmBgYA==