index.html preprocessing.html

1 Annotation version: 20170703

1.1 Orgdb

The Orgdb packages provide a quick and dirty method for gathering annotation data, lets see what we get!

mouse_pkg <- "Mus.musculus"
if ("Mus.musculus" %in% .packages(all.available=TRUE)) {
    tt <- sm(library("Mus.musculus"))
} else {
    require.auto("Mus.musculus")
    tt <- sm(library("Mus.musculus"))
}
mm_tx_org <- sm(load_orgdb_annotations(Mus.musculus, keytype="ensembltrans",
                                       fields=c("definition", "genename")))

2 Extract useful biomart data

Now that we have the mouse data loaded into a big data frame, the goal is to pull out the most useful parts of it. We will also combine that information with the extant orgdb data.

mm_tx_genes <- mm_tx_org$genes
## The inclusion of the 'definition' columns means that we also end up with a bunch
## of redundant entries, like 200,000 of them; therefore I am going to whittle down
## the list.
tt <- sm(library(Mus.musculus))
##mm_go <- load_orgdb_go(orgdb=Mus.musculus)
mm_go <- load_biomart_go(species="mmusculus")
## The biomart annotations file already exists, loading from it.
mm_annot <- load_biomart_annotations(species="mmusculus")
## The biomart annotations file already exists, loading from it.
mm_annot <- mm_annot[["annotation"]]
mm_lengths <- mm_annot[, c("geneID", "length")]
rownames(mm_lengths) <- make.names(mm_lengths[["geneID"]], unique=TRUE)
colnames(mm_lengths) <- c("ID", "length")

mm_tx_unique <- !grepl(pattern="\\.", x=rownames(mm_tx_genes))
mm_tx_genes <- mm_tx_genes[mm_tx_unique, ]
##mmtx_annotations <- get_biomart_annotations(species="mmusculus")
mart <- biomaRt::useMart(biomart="ENSEMBL_MART_ENSEMBL", host="dec2015.archive.ensembl.org")
dataset <- paste0("mmusculus_gene_ensembl")
ensembl <- try(biomaRt::useDataset(dataset, mart=mart))
lots_of_rows <- biomaRt::listAttributes(ensembl)  ## List of possible attributes
## wanted_attributes <- c("ensembl_gene_id", "ensembl_transcript_id", "ensembl_peptide_id", "chromosome_name", "start_position","end_position","description", "entrezgene","hgnc_symbol","hgnc_id","uniprot_sptrembl","uniprot_swissprot","uniprot_genename")  ## attributes Lucia and I chose, but too many
wanted_attributes_global <- c("ensembl_gene_id", "ensembl_transcript_id", "chromosome_name",
                              "start_position", "end_position", "strand", "description")
wanted_attributes_names <- c("ensembl_gene_id", "ensembl_transcript_id", "entrezgene", "hgnc_symbol", "hgnc_id")
wanted_attributes_uniprot <- c("ensembl_gene_id", "ensembl_transcript_id", "uniprot_sptrembl", "uniprot_swissprot")

wanted_global_annotations <- biomaRt::getBM(attributes=wanted_attributes_global, mart=ensembl)
dim(wanted_global_annotations)
## [1] 114083      7
wanted_names_annotations <- biomaRt::getBM(attributes=wanted_attributes_names, mart=ensembl)
wanted_uniprot_annotations <- biomaRt::getBM(attributes=wanted_attributes_uniprot, mart=ensembl)
dim(wanted_uniprot_annotations)
## [1] 57040     4
wanted_global_annotations <- data.table::as.data.table(wanted_global_annotations)
wanted_names_annotations <- data.table::as.data.table(wanted_names_annotations)
wanted_uniprot_annotations <- data.table::as.data.table(wanted_uniprot_annotations)

2.1 Merge them together

Now let us bring together these data sources into a (hopefully) comprehesive table.

wanted_annotations <- merge(wanted_global_annotations,
                            wanted_names_annotations,
                            by.x="ensembl_transcript_id",
                            by.y="ensembl_transcript_id",
                            all.y=TRUE)
wanted_annotations <- merge(wanted_annotations,
                            wanted_uniprot_annotations,
                            by.x="ensembl_transcript_id",
                            by.y="ensembl_transcript_id",
                            all.x=TRUE)
wanted_annotations <- as.data.frame(wanted_annotations)
wanted_annotations <- wanted_annotations[, c(
  "ensembl_transcript_id", "ensembl_gene_id", "chromosome_name", "start_position", "end_position",
  "strand", "description", "entrezgene", "hgnc_symbol", "hgnc_id", "uniprot_sptrembl",
  "uniprot_swissprot")]

length(unique(wanted_annotations$ensembl_gene_id))
## [1] 22684
rownames(wanted_annotations) <- make.names(wanted_annotations[["ensembl_gene_id"]], unique=TRUE)
pander::pander(sessionInfo())

R version 3.4.4 (2018-03-15)

**Platform:** x86_64-pc-linux-gnu (64-bit)

locale: LC_CTYPE=en_US.utf8, LC_NUMERIC=C, LC_TIME=en_US.utf8, LC_COLLATE=en_US.utf8, LC_MONETARY=en_US.utf8, LC_MESSAGES=en_US.utf8, LC_PAPER=en_US.utf8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.utf8 and LC_IDENTIFICATION=C

attached base packages: parallel, stats4, stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: hpgltools(v.2018.03), Mus.musculus(v.1.3.1), TxDb.Mmusculus.UCSC.mm10.knownGene(v.3.4.0), org.Mm.eg.db(v.3.5.0), GO.db(v.3.5.0), OrganismDbi(v.1.20.0), GenomicFeatures(v.1.30.3), GenomicRanges(v.1.30.3), GenomeInfoDb(v.1.14.0), AnnotationDbi(v.1.40.0), IRanges(v.2.12.0), S4Vectors(v.0.16.0), Biobase(v.2.38.0) and BiocGenerics(v.0.24.0)

loaded via a namespace (and not attached): httr(v.1.3.1), RMySQL(v.0.10.14), bit64(v.0.9-7), foreach(v.1.4.4), assertthat(v.0.2.0), pander(v.0.6.1), RBGL(v.1.54.0), blob(v.1.1.0), GenomeInfoDbData(v.1.0.0), Rsamtools(v.1.30.0), yaml(v.2.1.18), progress(v.1.1.2), pillar(v.1.2.1), RSQLite(v.2.0), backports(v.1.1.2), lattice(v.0.20-35), digest(v.0.6.15), XVector(v.0.18.0), colorspace(v.1.3-2), htmltools(v.0.3.6), Matrix(v.1.2-12), plyr(v.1.8.4), XML(v.3.98-1.10), pkgconfig(v.2.0.1), devtools(v.1.13.5), biomaRt(v.2.34.2), zlibbioc(v.1.24.0), scales(v.0.5.0), BiocParallel(v.1.12.0), tibble(v.1.4.2), ggplot2(v.2.2.1), withr(v.2.1.2), SummarizedExperiment(v.1.8.1), lazyeval(v.0.2.1), magrittr(v.1.5), memoise(v.1.1.0), evaluate(v.0.10.1), xml2(v.1.2.0), graph(v.1.56.0), BiocInstaller(v.1.28.0), tools(v.3.4.4), data.table(v.1.10.4-3), prettyunits(v.1.0.2), matrixStats(v.0.53.1), stringr(v.1.3.0), munsell(v.0.4.3), DelayedArray(v.0.4.1), Biostrings(v.2.46.0), compiler(v.3.4.4), rlang(v.0.2.0), grid(v.3.4.4), RCurl(v.1.95-4.10), iterators(v.1.0.9), bitops(v.1.0-6), base64enc(v.0.1-3), rmarkdown(v.1.9), gtable(v.0.2.0), codetools(v.0.2-15), curl(v.3.1), DBI(v.0.8), roxygen2(v.6.0.1), R6(v.2.2.2), GenomicAlignments(v.1.14.1), knitr(v.1.20), rtracklayer(v.1.38.3), bit(v.1.1-12), commonmark(v.1.4), rprojroot(v.1.3-2), stringi(v.1.1.7) and Rcpp(v.0.12.16)

message(paste0("This is hpgltools commit: ", get_git_commit()))
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 5d8c266e48bb9f73cdac8300e5c7c9f5baf003dc
## R> packrat::restore()
## This is hpgltools commit: Wed Mar 21 15:55:32 2018 -0400: 5d8c266e48bb9f73cdac8300e5c7c9f5baf003dc
this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
message(paste0("Saving to ", this_save))
## Saving to 01_annotation_mmusculus-v20170703.rda.xz
tmp <- sm(saveme(filename=this_save))
LS0tCnRpdGxlOiAiSS5zY2FwdWxhcmlzIDIwMTc6IEluZmVjdGVkIG1pY2UgYW5ub3RhdGlvbiBpbmZvcm1hdGlvbi4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogZGVmYXVsdAogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IHJlYWRhYmxlCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICAgY29sbGFwc2VkOiBmYWxzZQogICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnNldC5zZWVkKDEpCnZlciA8LSAiMjAxNzA3MDMiCnByZXZpb3VzX2ZpbGUgPC0gImluZGV4LlJtZCIKCnRtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpKQoKcm1kX2ZpbGUgPC0gIjAxX2Fubm90YXRpb25fbW11c2N1bHVzLlJtZCIKYGBgCgpbaW5kZXguaHRtbF0oaW5kZXguaHRtbCkgW3ByZXByb2Nlc3NpbmcuaHRtbF0ocHJlcHJvY2Vzc2luZy5odG1sKQoKIyBBbm5vdGF0aW9uIHZlcnNpb246IGByIHZlcmAKCiMjIE9yZ2RiCgpUaGUgT3JnZGIgcGFja2FnZXMgcHJvdmlkZSBhIHF1aWNrIGFuZCBkaXJ0eSBtZXRob2QgZm9yIGdhdGhlcmluZyBhbm5vdGF0aW9uCmRhdGEsIGxldHMgc2VlIHdoYXQgd2UgZ2V0IQoKYGBge3IgbW91c2VfYW5ub3RhdGlvbnN9Cm1vdXNlX3BrZyA8LSAiTXVzLm11c2N1bHVzIgppZiAoIk11cy5tdXNjdWx1cyIgJWluJSAucGFja2FnZXMoYWxsLmF2YWlsYWJsZT1UUlVFKSkgewogICAgdHQgPC0gc20obGlicmFyeSgiTXVzLm11c2N1bHVzIikpCn0gZWxzZSB7CiAgICByZXF1aXJlLmF1dG8oIk11cy5tdXNjdWx1cyIpCiAgICB0dCA8LSBzbShsaWJyYXJ5KCJNdXMubXVzY3VsdXMiKSkKfQptbV90eF9vcmcgPC0gc20obG9hZF9vcmdkYl9hbm5vdGF0aW9ucyhNdXMubXVzY3VsdXMsIGtleXR5cGU9ImVuc2VtYmx0cmFucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkcz1jKCJkZWZpbml0aW9uIiwgImdlbmVuYW1lIikpKQpgYGAKCiMgRXh0cmFjdCB1c2VmdWwgYmlvbWFydCBkYXRhCgpOb3cgdGhhdCB3ZSBoYXZlIHRoZSBtb3VzZSBkYXRhIGxvYWRlZCBpbnRvIGEgYmlnIGRhdGEgZnJhbWUsIHRoZSBnb2FsIGlzIHRvCnB1bGwgb3V0IHRoZSBtb3N0IHVzZWZ1bCBwYXJ0cyBvZiBpdC4gIFdlIHdpbGwgYWxzbyBjb21iaW5lIHRoYXQgaW5mb3JtYXRpb24Kd2l0aCB0aGUgZXh0YW50IG9yZ2RiIGRhdGEuCgpgYGB7ciBleHRyYWN0X2Jpb21hcnR9Cm1tX3R4X2dlbmVzIDwtIG1tX3R4X29yZyRnZW5lcwojIyBUaGUgaW5jbHVzaW9uIG9mIHRoZSAnZGVmaW5pdGlvbicgY29sdW1ucyBtZWFucyB0aGF0IHdlIGFsc28gZW5kIHVwIHdpdGggYSBidW5jaAojIyBvZiByZWR1bmRhbnQgZW50cmllcywgbGlrZSAyMDAsMDAwIG9mIHRoZW07IHRoZXJlZm9yZSBJIGFtIGdvaW5nIHRvIHdoaXR0bGUgZG93bgojIyB0aGUgbGlzdC4KdHQgPC0gc20obGlicmFyeShNdXMubXVzY3VsdXMpKQojI21tX2dvIDwtIGxvYWRfb3JnZGJfZ28ob3JnZGI9TXVzLm11c2N1bHVzKQptbV9nbyA8LSBsb2FkX2Jpb21hcnRfZ28oc3BlY2llcz0ibW11c2N1bHVzIikKCm1tX2Fubm90IDwtIGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucyhzcGVjaWVzPSJtbXVzY3VsdXMiKQptbV9hbm5vdCA8LSBtbV9hbm5vdFtbImFubm90YXRpb24iXV0KbW1fbGVuZ3RocyA8LSBtbV9hbm5vdFssIGMoImdlbmVJRCIsICJsZW5ndGgiKV0Kcm93bmFtZXMobW1fbGVuZ3RocykgPC0gbWFrZS5uYW1lcyhtbV9sZW5ndGhzW1siZ2VuZUlEIl1dLCB1bmlxdWU9VFJVRSkKY29sbmFtZXMobW1fbGVuZ3RocykgPC0gYygiSUQiLCAibGVuZ3RoIikKCm1tX3R4X3VuaXF1ZSA8LSAhZ3JlcGwocGF0dGVybj0iXFwuIiwgeD1yb3duYW1lcyhtbV90eF9nZW5lcykpCm1tX3R4X2dlbmVzIDwtIG1tX3R4X2dlbmVzW21tX3R4X3VuaXF1ZSwgXQojI21tdHhfYW5ub3RhdGlvbnMgPC0gZ2V0X2Jpb21hcnRfYW5ub3RhdGlvbnMoc3BlY2llcz0ibW11c2N1bHVzIikKbWFydCA8LSBiaW9tYVJ0Ojp1c2VNYXJ0KGJpb21hcnQ9IkVOU0VNQkxfTUFSVF9FTlNFTUJMIiwgaG9zdD0iZGVjMjAxNS5hcmNoaXZlLmVuc2VtYmwub3JnIikKZGF0YXNldCA8LSBwYXN0ZTAoIm1tdXNjdWx1c19nZW5lX2Vuc2VtYmwiKQplbnNlbWJsIDwtIHRyeShiaW9tYVJ0Ojp1c2VEYXRhc2V0KGRhdGFzZXQsIG1hcnQ9bWFydCkpCmxvdHNfb2Zfcm93cyA8LSBiaW9tYVJ0OjpsaXN0QXR0cmlidXRlcyhlbnNlbWJsKSAgIyMgTGlzdCBvZiBwb3NzaWJsZSBhdHRyaWJ1dGVzCiMjIHdhbnRlZF9hdHRyaWJ1dGVzIDwtIGMoImVuc2VtYmxfZ2VuZV9pZCIsICJlbnNlbWJsX3RyYW5zY3JpcHRfaWQiLCAiZW5zZW1ibF9wZXB0aWRlX2lkIiwgImNocm9tb3NvbWVfbmFtZSIsICJzdGFydF9wb3NpdGlvbiIsImVuZF9wb3NpdGlvbiIsImRlc2NyaXB0aW9uIiwgImVudHJlemdlbmUiLCJoZ25jX3N5bWJvbCIsImhnbmNfaWQiLCJ1bmlwcm90X3NwdHJlbWJsIiwidW5pcHJvdF9zd2lzc3Byb3QiLCJ1bmlwcm90X2dlbmVuYW1lIikgICMjIGF0dHJpYnV0ZXMgTHVjaWEgYW5kIEkgY2hvc2UsIGJ1dCB0b28gbWFueQp3YW50ZWRfYXR0cmlidXRlc19nbG9iYWwgPC0gYygiZW5zZW1ibF9nZW5lX2lkIiwgImVuc2VtYmxfdHJhbnNjcmlwdF9pZCIsICJjaHJvbW9zb21lX25hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RhcnRfcG9zaXRpb24iLCAiZW5kX3Bvc2l0aW9uIiwgInN0cmFuZCIsICJkZXNjcmlwdGlvbiIpCndhbnRlZF9hdHRyaWJ1dGVzX25hbWVzIDwtIGMoImVuc2VtYmxfZ2VuZV9pZCIsICJlbnNlbWJsX3RyYW5zY3JpcHRfaWQiLCAiZW50cmV6Z2VuZSIsICJoZ25jX3N5bWJvbCIsICJoZ25jX2lkIikKd2FudGVkX2F0dHJpYnV0ZXNfdW5pcHJvdCA8LSBjKCJlbnNlbWJsX2dlbmVfaWQiLCAiZW5zZW1ibF90cmFuc2NyaXB0X2lkIiwgInVuaXByb3Rfc3B0cmVtYmwiLCAidW5pcHJvdF9zd2lzc3Byb3QiKQoKd2FudGVkX2dsb2JhbF9hbm5vdGF0aW9ucyA8LSBiaW9tYVJ0OjpnZXRCTShhdHRyaWJ1dGVzPXdhbnRlZF9hdHRyaWJ1dGVzX2dsb2JhbCwgbWFydD1lbnNlbWJsKQpkaW0od2FudGVkX2dsb2JhbF9hbm5vdGF0aW9ucykKd2FudGVkX25hbWVzX2Fubm90YXRpb25zIDwtIGJpb21hUnQ6OmdldEJNKGF0dHJpYnV0ZXM9d2FudGVkX2F0dHJpYnV0ZXNfbmFtZXMsIG1hcnQ9ZW5zZW1ibCkKd2FudGVkX3VuaXByb3RfYW5ub3RhdGlvbnMgPC0gYmlvbWFSdDo6Z2V0Qk0oYXR0cmlidXRlcz13YW50ZWRfYXR0cmlidXRlc191bmlwcm90LCBtYXJ0PWVuc2VtYmwpCmRpbSh3YW50ZWRfdW5pcHJvdF9hbm5vdGF0aW9ucykKCndhbnRlZF9nbG9iYWxfYW5ub3RhdGlvbnMgPC0gZGF0YS50YWJsZTo6YXMuZGF0YS50YWJsZSh3YW50ZWRfZ2xvYmFsX2Fubm90YXRpb25zKQp3YW50ZWRfbmFtZXNfYW5ub3RhdGlvbnMgPC0gZGF0YS50YWJsZTo6YXMuZGF0YS50YWJsZSh3YW50ZWRfbmFtZXNfYW5ub3RhdGlvbnMpCndhbnRlZF91bmlwcm90X2Fubm90YXRpb25zIDwtIGRhdGEudGFibGU6OmFzLmRhdGEudGFibGUod2FudGVkX3VuaXByb3RfYW5ub3RhdGlvbnMpCmBgYAoKIyMgTWVyZ2UgdGhlbSB0b2dldGhlcgoKTm93IGxldCB1cyBicmluZyB0b2dldGhlciB0aGVzZSBkYXRhIHNvdXJjZXMgaW50byBhIChob3BlZnVsbHkpIGNvbXByZWhlc2l2ZQp0YWJsZS4KCmBgYHtyIG1lcmdlc30Kd2FudGVkX2Fubm90YXRpb25zIDwtIG1lcmdlKHdhbnRlZF9nbG9iYWxfYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YW50ZWRfbmFtZXNfYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieS54PSJlbnNlbWJsX3RyYW5zY3JpcHRfaWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkueT0iZW5zZW1ibF90cmFuc2NyaXB0X2lkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbC55PVRSVUUpCndhbnRlZF9hbm5vdGF0aW9ucyA8LSBtZXJnZSh3YW50ZWRfYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YW50ZWRfdW5pcHJvdF9hbm5vdGF0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5Lng9ImVuc2VtYmxfdHJhbnNjcmlwdF9pZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieS55PSJlbnNlbWJsX3RyYW5zY3JpcHRfaWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsLng9VFJVRSkKd2FudGVkX2Fubm90YXRpb25zIDwtIGFzLmRhdGEuZnJhbWUod2FudGVkX2Fubm90YXRpb25zKQp3YW50ZWRfYW5ub3RhdGlvbnMgPC0gd2FudGVkX2Fubm90YXRpb25zWywgYygKICAiZW5zZW1ibF90cmFuc2NyaXB0X2lkIiwgImVuc2VtYmxfZ2VuZV9pZCIsICJjaHJvbW9zb21lX25hbWUiLCAic3RhcnRfcG9zaXRpb24iLCAiZW5kX3Bvc2l0aW9uIiwKICAic3RyYW5kIiwgImRlc2NyaXB0aW9uIiwgImVudHJlemdlbmUiLCAiaGduY19zeW1ib2wiLCAiaGduY19pZCIsICJ1bmlwcm90X3NwdHJlbWJsIiwKICAidW5pcHJvdF9zd2lzc3Byb3QiKV0KCmxlbmd0aCh1bmlxdWUod2FudGVkX2Fubm90YXRpb25zJGVuc2VtYmxfZ2VuZV9pZCkpCnJvd25hbWVzKHdhbnRlZF9hbm5vdGF0aW9ucykgPC0gbWFrZS5uYW1lcyh3YW50ZWRfYW5ub3RhdGlvbnNbWyJlbnNlbWJsX2dlbmVfaWQiXV0sIHVuaXF1ZT1UUlVFKQpgYGAKCmBgYHtyIHNhdmVtZX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAK