1 Genome annotation input

There are a few methods of importing annotation data into R. The following are two attempts, the second is currently being used in these analyses.

1.1 AnnotationHub

AnnotationHub is a newer service and has promise to be an excellent top-level resource for gathering annotation data.

tt <- sm(library(AnnotationHub))
ah <- AnnotationHub()
orgdbs <- query(ah, "OrgDB")
annot_lb <- query(ah, c("OrgDB", "Leishmania"))
annot_lb
## It appears there are no braziliensis samples in AnnotationHub.

1.2 OrganismDb from the eupathdb

AnnotationHub is the new and fancier version of what OrganismDb does. Keith already made these for the parasites though, lets try and use one of those.

The OrganismDb packages are installable via Keith’s builder: https://github.com/elsayed-lab/eupathdb-organismdb

I did a git pull of it, changed a couple small things and ran ‘make lbraziliensis’. This pulls the annotations down from a mix of Najib’s directory on the cluster and the TriTrypdb. As a result, it currently gets the version 27 of the TriTrypDB data. It may be useful for me to download a newer revision (but I am reasonably certain not much (or anything) has changed for braziliensis in a while).

After 5 or so minutes a brand new package ‘Leishmania.braziliensis’ appeared in my R environment.

1.2.1 Eupathdb

Since the original writing of this document, I have improved my ability to import/use data from the eupathdb. With that in mind, relatively recent versions of the hpgltools provide functionality to create relatively complete orgdb/txdb/organismdbi/bsgenome packages from most (any?) species in the eupathdb heirarchy.

1.2.2 Creating orgdb

The creation of an orgdb instance for a given eupath species is below, but it takes a long time and I already did it for most of the Leishmania, so I am including the function here, but not running it.

testing_braziliensis <- make_eupath_organismdbi("2904")
braziliensis_names <- get_eupath_pkgnames("2904")
## Starting metadata download.
## Finished metadata download.
## Found the following hits: Leishmania braziliensis MHOM/BR/75/M2904, choosing the first.
braziliensis_names$orgdb
## [1] "org.Lbraziliensis.MHOMBR75M2904.v36.eg.db"
lb_org <- load_orgdb_annotations(braziliensis_names$orgdb, keytype="gid", fields=wanted_fields)$genes
## Unable to find GENENAME, setting it to GENE_NAME_OR_SYMBOL.
## Unable to find TYPE in the db, removing it.
## Unable to find CHR in the db, removing it.
## Unable to find TXSTRAND in the db, removing it.
## Unable to find TXSTART in the db, removing it.
## Unable to find TXEND in the db, removing it.
## Extracted all gene ids.
## 'select()' returned 1:many mapping between keys and columns

1.3 Read a gff file

In contrast, it is possible to load most annotations of interest directly from the gff files used in the alignments. More in-depth information for the human transcriptome may be extracted from biomart.

## The old way of getting genome/annotation data
lb_gff <- "reference/lbraziliensis.gff"
lb_fasta <- "reference/lbraziliensis.fasta.xz"

lb_annotations <- sm(load_gff_annotations(lb_gff, type="gene"))
rownames(lb_annotations) <- paste0("exon_", lb_annotations$web_id, ".1")

1.4 Getting ontology data

## While testing, I called this desc, that will need to change.
## lb_tooltips <- make_tooltips(lb_annotations)
lb_lengths <- lb_annotations[, c("ID", "width")]

lb_goids <- read.csv(file="reference/lbraz_go.txt.xz", sep="\t", header=FALSE)
colnames(lb_goids) <- c("ID","GO","ont","name","source","tag")

2 Putting the pieces together

The macrophage experiment has samples across 2 contexts, the host and parasite. The following block sets up one experiment for each. If you open the all_samples-species.xlsx files, you will note immediately that a few different attempts were made at ascertaining the most likely experimental factors that contributed to the readily apparent batch effects.

Question: Are there any human reads in this data? I assume no, but will happily map human if so.

2.1 The parasite transcriptome mappings

parasite_expt <- sm(create_expt("sample_sheet/all_samples.xlsx", gene_info=lb_annotations))
parasite_expt <- exclude_genes_expt(parasite_expt, column="web_id", patterns=c("rRNA", "tRNA"))
## Before removal, there were 8706 entries.
## Now there are 8633 entries.
## Percent kept: 99.537, 99.482, 98.554, 99.212, 99.368, 99.170, 99.522, 99.551, 99.650
## Percent removed: 0.463, 0.518, 1.446, 0.788, 0.632, 0.830, 0.478, 0.449, 0.350
chosen_colors <- list(
    "ama" = "#AA3939",
    "meta" = "#067300",
    "pro" = "#482AB1")
parasite_expt <- set_expt_colors(expt=parasite_expt, colors=chosen_colors)

At this point, we should have everything necessary to perform the various analyses of the 4 sub-experiments. So save the current data for reuse elsewhere.

3 The Experiment Design

3.1 Parasite

knitr::kable(parasite_expt$design)
sample sampleid strain condition stage batch altbatch file
axa1 axa1 axa1 MHOM_BR_74_M2903 ama amastigote a a preprocessing/AXA1/processed/outputs/bowtie2_lbraziliensis/axa1-trimmed.count.xz
axa2 axa2 axa2 MHOM_BR_74_M2903 ama amastigote b a preprocessing/AXA2/processed/outputs/bowtie2_lbraziliensis/axa2-trimmed.count.xz
axa3 axa3 axa3 MHOM_BR_74_M2903 ama amastigote c a preprocessing/AXA3/processed/outputs/bowtie2_lbraziliensis/axa3-trimmed.count.xz
meta1 meta1 meta1 MHOM_BR_74_M2903 meta metacyclic a a preprocessing/META1/processed/outputs/bowtie2_lbraziliensis/meta1-trimmed.count.xz
meta2 meta2 meta2 MHOM_BR_74_M2903 meta metacyclic b a preprocessing/META2/processed/outputs/bowtie2_lbraziliensis/meta2-trimmed.count.xz
meta3 meta3 meta3 MHOM_BR_74_M2903 meta metacyclic c a preprocessing/META3/processed/outputs/bowtie2_lbraziliensis/meta3-trimmed.count.xz
pro1 pro1 pro1 MHOM_BR_74_M2903 pro procyclic a a preprocessing/PRO1/processed/outputs/bowtie2_lbraziliensis/pro1-trimmed.count.xz
pro2 pro2 pro2 MHOM_BR_74_M2903 pro procyclic b a preprocessing/PRO2/processed/outputs/bowtie2_lbraziliensis/pro2-trimmed.count.xz
pro3 pro3 pro3 MHOM_BR_74_M2903 pro procyclic c a preprocessing/PRO3/processed/outputs/bowtie2_lbraziliensis/pro3-trimmed.count.xz

4 Changelog

  • 20170201

** Explicitly excluded rRNA genes/features, currently only those. The rest of the ncRNA may be removed by adding “snoRNA”, “ncRNA”, “snRNA” to ‘patterns’ above.

if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
  message(paste0("Saving to ", this_save))
  tmp <- sm(saveme(filename=this_save))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 2a0661d6e37f8a3d8831eb3bbd6347c0d9c4b3b7
## R> packrat::restore()
## This is hpgltools commit: Thu Mar 29 16:59:07 2018 -0400: 2a0661d6e37f8a3d8831eb3bbd6347c0d9c4b3b7
## Saving to 01_annotation-v20170201.rda.xz
LS0tCnRpdGxlOiAiTC5icmF6aWxpZW5zaXMgMjAxNzogQW5ub3RhdGlvbiBkYXRhLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBsaWJyYXJ5KGhwZ2x0b29scykKICB0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikKICBrbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD05MCwKICAgICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCiAga25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKICBvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQogIGdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQogIHZlciA8LSAiMjAxNzAyMDEiCiAgcHJldmlvdXNfZmlsZSA8LSAiaW5kZXguUm1kIgoKICB0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKSkKICBybWRfZmlsZSA8LSAiMDFfYW5ub3RhdGlvbi5SbWQiCn0KYGBgCgojIEdlbm9tZSBhbm5vdGF0aW9uIGlucHV0CgpUaGVyZSBhcmUgYSBmZXcgbWV0aG9kcyBvZiBpbXBvcnRpbmcgYW5ub3RhdGlvbiBkYXRhIGludG8gUi4gIFRoZSBmb2xsb3dpbmcgYXJlIHR3byBhdHRlbXB0cywgdGhlCnNlY29uZCBpcyBjdXJyZW50bHkgYmVpbmcgdXNlZCBpbiB0aGVzZSBhbmFseXNlcy4KCiMjIEFubm90YXRpb25IdWIKCkFubm90YXRpb25IdWIgaXMgYSBuZXdlciBzZXJ2aWNlIGFuZCBoYXMgcHJvbWlzZSB0byBiZSBhbiBleGNlbGxlbnQgdG9wLWxldmVsIHJlc291cmNlIGZvciBnYXRoZXJpbmcKYW5ub3RhdGlvbiBkYXRhLgoKYGBge3IgZGF0YV9pbnB1dF9nZW5vbWUsIGV2YWw9RkFMU0V9CnR0IDwtIHNtKGxpYnJhcnkoQW5ub3RhdGlvbkh1YikpCmFoIDwtIEFubm90YXRpb25IdWIoKQpvcmdkYnMgPC0gcXVlcnkoYWgsICJPcmdEQiIpCmFubm90X2xiIDwtIHF1ZXJ5KGFoLCBjKCJPcmdEQiIsICJMZWlzaG1hbmlhIikpCmFubm90X2xiCiMjIEl0IGFwcGVhcnMgdGhlcmUgYXJlIG5vIGJyYXppbGllbnNpcyBzYW1wbGVzIGluIEFubm90YXRpb25IdWIuCmBgYAoKIyMgT3JnYW5pc21EYiBmcm9tIHRoZSBldXBhdGhkYgoKQW5ub3RhdGlvbkh1YiBpcyB0aGUgbmV3IGFuZCBmYW5jaWVyIHZlcnNpb24gb2Ygd2hhdCBPcmdhbmlzbURiIGRvZXMuICBLZWl0aCBhbHJlYWR5IG1hZGUgdGhlc2UgZm9yIHRoZQpwYXJhc2l0ZXMgdGhvdWdoLCBsZXRzIHRyeSBhbmQgdXNlIG9uZSBvZiB0aG9zZS4KClRoZSBPcmdhbmlzbURiIHBhY2thZ2VzIGFyZSBpbnN0YWxsYWJsZSB2aWEgS2VpdGgncyBidWlsZGVyOgpodHRwczovL2dpdGh1Yi5jb20vZWxzYXllZC1sYWIvZXVwYXRoZGItb3JnYW5pc21kYgoKSSBkaWQgYSBnaXQgcHVsbCBvZiBpdCwgY2hhbmdlZCBhIGNvdXBsZSBzbWFsbCB0aGluZ3MgYW5kIHJhbiAnbWFrZSBsYnJhemlsaWVuc2lzJy4KVGhpcyBwdWxscyB0aGUgYW5ub3RhdGlvbnMgZG93biBmcm9tIGEgbWl4IG9mIE5hamliJ3MgZGlyZWN0b3J5IG9uIHRoZSBjbHVzdGVyIGFuZCB0aGUgVHJpVHJ5cGRiLgpBcyBhIHJlc3VsdCwgaXQgY3VycmVudGx5IGdldHMgdGhlIHZlcnNpb24gMjcgb2YgdGhlIFRyaVRyeXBEQiBkYXRhLiAgSXQgbWF5IGJlIHVzZWZ1bCBmb3IgbWUKdG8gZG93bmxvYWQgYSBuZXdlciByZXZpc2lvbiAoYnV0IEkgYW0gcmVhc29uYWJseSBjZXJ0YWluIG5vdCBtdWNoIChvciBhbnl0aGluZykgaGFzIGNoYW5nZWQKZm9yIGJyYXppbGllbnNpcyBpbiBhIHdoaWxlKS4KCkFmdGVyIDUgb3Igc28gbWludXRlcyBhIGJyYW5kIG5ldyBwYWNrYWdlICdMZWlzaG1hbmlhLmJyYXppbGllbnNpcycgYXBwZWFyZWQgaW4gbXkgUiBlbnZpcm9ubWVudC4KCiMjIyBFdXBhdGhkYgoKU2luY2UgdGhlIG9yaWdpbmFsIHdyaXRpbmcgb2YgdGhpcyBkb2N1bWVudCwgSSBoYXZlIGltcHJvdmVkIG15IGFiaWxpdHkgdG8KaW1wb3J0L3VzZSBkYXRhIGZyb20gdGhlIGV1cGF0aGRiLiAgV2l0aCB0aGF0IGluIG1pbmQsIHJlbGF0aXZlbHkgcmVjZW50CnZlcnNpb25zIG9mIHRoZSBocGdsdG9vbHMgcHJvdmlkZSBmdW5jdGlvbmFsaXR5IHRvIGNyZWF0ZSByZWxhdGl2ZWx5IGNvbXBsZXRlCm9yZ2RiL3R4ZGIvb3JnYW5pc21kYmkvYnNnZW5vbWUgcGFja2FnZXMgZnJvbSBtb3N0IChhbnk/KSBzcGVjaWVzIGluIHRoZQpldXBhdGhkYiBoZWlyYXJjaHkuCgojIyMgQ3JlYXRpbmcgb3JnZGIKClRoZSBjcmVhdGlvbiBvZiBhbiBvcmdkYiBpbnN0YW5jZSBmb3IgYSBnaXZlbiBldXBhdGggc3BlY2llcyBpcyBiZWxvdywgYnV0IGl0CnRha2VzIGEgbG9uZyB0aW1lIGFuZCBJIGFscmVhZHkgZGlkIGl0IGZvciBtb3N0IG9mIHRoZSBMZWlzaG1hbmlhLCBzbyBJIGFtCmluY2x1ZGluZyB0aGUgZnVuY3Rpb24gaGVyZSwgYnV0IG5vdCBydW5uaW5nIGl0LgoKYGBge3Igb3JnZGJfaW5zdGFsbCwgZXZhbD1GQUxTRX0KdGVzdGluZ19icmF6aWxpZW5zaXMgPC0gbWFrZV9ldXBhdGhfb3JnYW5pc21kYmkoIjI5MDQiKQpgYGAKCmBgYHtyIGxicmF6aWxpZW5zaXNfb3JnZGJ9CmJyYXppbGllbnNpc19uYW1lcyA8LSBnZXRfZXVwYXRoX3BrZ25hbWVzKCIyOTA0IikKYnJhemlsaWVuc2lzX25hbWVzJG9yZ2RiCmxiX29yZyA8LSBsb2FkX29yZ2RiX2Fubm90YXRpb25zKGJyYXppbGllbnNpc19uYW1lcyRvcmdkYiwga2V5dHlwZT0iZ2lkIiwgZmllbGRzPXdhbnRlZF9maWVsZHMpJGdlbmVzCmBgYAoKIyMgUmVhZCBhIGdmZiBmaWxlCgpJbiBjb250cmFzdCwgaXQgaXMgcG9zc2libGUgdG8gbG9hZCBtb3N0IGFubm90YXRpb25zIG9mIGludGVyZXN0IGRpcmVjdGx5IGZyb20gdGhlIGdmZiBmaWxlcyB1c2VkIGluCnRoZSBhbGlnbm1lbnRzLiAgTW9yZSBpbi1kZXB0aCBpbmZvcm1hdGlvbiBmb3IgdGhlIGh1bWFuIHRyYW5zY3JpcHRvbWUgbWF5IGJlIGV4dHJhY3RlZCBmcm9tIGJpb21hcnQuCgpgYGB7ciBnZW5vbWVfaW5wdXQsIGNhY2hlPVRSVUV9CiMjIFRoZSBvbGQgd2F5IG9mIGdldHRpbmcgZ2Vub21lL2Fubm90YXRpb24gZGF0YQpsYl9nZmYgPC0gInJlZmVyZW5jZS9sYnJhemlsaWVuc2lzLmdmZiIKbGJfZmFzdGEgPC0gInJlZmVyZW5jZS9sYnJhemlsaWVuc2lzLmZhc3RhLnh6IgoKbGJfYW5ub3RhdGlvbnMgPC0gc20obG9hZF9nZmZfYW5ub3RhdGlvbnMobGJfZ2ZmLCB0eXBlPSJnZW5lIikpCnJvd25hbWVzKGxiX2Fubm90YXRpb25zKSA8LSBwYXN0ZTAoImV4b25fIiwgbGJfYW5ub3RhdGlvbnMkd2ViX2lkLCAiLjEiKQpgYGAKCiMjIEdldHRpbmcgb250b2xvZ3kgZGF0YQoKYGBge3Igb250b2xvZ3l9CiMjIFdoaWxlIHRlc3RpbmcsIEkgY2FsbGVkIHRoaXMgZGVzYywgdGhhdCB3aWxsIG5lZWQgdG8gY2hhbmdlLgojIyBsYl90b29sdGlwcyA8LSBtYWtlX3Rvb2x0aXBzKGxiX2Fubm90YXRpb25zKQpsYl9sZW5ndGhzIDwtIGxiX2Fubm90YXRpb25zWywgYygiSUQiLCAid2lkdGgiKV0KCmxiX2dvaWRzIDwtIHJlYWQuY3N2KGZpbGU9InJlZmVyZW5jZS9sYnJhel9nby50eHQueHoiLCBzZXA9Ilx0IiwgaGVhZGVyPUZBTFNFKQpjb2xuYW1lcyhsYl9nb2lkcykgPC0gYygiSUQiLCJHTyIsIm9udCIsIm5hbWUiLCJzb3VyY2UiLCJ0YWciKQpgYGAKCiMgUHV0dGluZyB0aGUgcGllY2VzIHRvZ2V0aGVyCgpUaGUgbWFjcm9waGFnZSBleHBlcmltZW50IGhhcyBzYW1wbGVzIGFjcm9zcyAyIGNvbnRleHRzLCB0aGUgaG9zdCBhbmQgcGFyYXNpdGUuICBUaGUgZm9sbG93aW5nIGJsb2NrCnNldHMgdXAgb25lIGV4cGVyaW1lbnQgZm9yIGVhY2guICBJZiB5b3Ugb3BlbiB0aGUgYWxsX3NhbXBsZXMtc3BlY2llcy54bHN4IGZpbGVzLCB5b3Ugd2lsbCBub3RlCmltbWVkaWF0ZWx5IHRoYXQgYSBmZXcgZGlmZmVyZW50IGF0dGVtcHRzIHdlcmUgbWFkZSBhdCBhc2NlcnRhaW5pbmcgdGhlIG1vc3QgbGlrZWx5IGV4cGVyaW1lbnRhbApmYWN0b3JzIHRoYXQgY29udHJpYnV0ZWQgdG8gdGhlIHJlYWRpbHkgYXBwYXJlbnQgYmF0Y2ggZWZmZWN0cy4KClF1ZXN0aW9uOiAgQXJlIHRoZXJlIGFueSBodW1hbiByZWFkcyBpbiB0aGlzIGRhdGE/ICBJIGFzc3VtZSBubywgYnV0IHdpbGwgaGFwcGlseSBtYXAgaHVtYW4gaWYgc28uCgojIyBUaGUgcGFyYXNpdGUgdHJhbnNjcmlwdG9tZSBtYXBwaW5ncwoKYGBge3IgcGFyYXNpdGVfZXhwdH0KcGFyYXNpdGVfZXhwdCA8LSBzbShjcmVhdGVfZXhwdCgic2FtcGxlX3NoZWV0L2FsbF9zYW1wbGVzLnhsc3giLCBnZW5lX2luZm89bGJfYW5ub3RhdGlvbnMpKQpwYXJhc2l0ZV9leHB0IDwtIGV4Y2x1ZGVfZ2VuZXNfZXhwdChwYXJhc2l0ZV9leHB0LCBjb2x1bW49IndlYl9pZCIsIHBhdHRlcm5zPWMoInJSTkEiLCAidFJOQSIpKQpjaG9zZW5fY29sb3JzIDwtIGxpc3QoCiAgICAiYW1hIiA9ICIjQUEzOTM5IiwKICAgICJtZXRhIiA9ICIjMDY3MzAwIiwKICAgICJwcm8iID0gIiM0ODJBQjEiKQpwYXJhc2l0ZV9leHB0IDwtIHNldF9leHB0X2NvbG9ycyhleHB0PXBhcmFzaXRlX2V4cHQsIGNvbG9ycz1jaG9zZW5fY29sb3JzKQpgYGAKCkF0IHRoaXMgcG9pbnQsIHdlIHNob3VsZCBoYXZlIGV2ZXJ5dGhpbmcgbmVjZXNzYXJ5IHRvIHBlcmZvcm0gdGhlIHZhcmlvdXMKYW5hbHlzZXMgb2YgdGhlIDQgc3ViLWV4cGVyaW1lbnRzLiAgU28gc2F2ZSB0aGUgY3VycmVudCBkYXRhIGZvciByZXVzZQplbHNld2hlcmUuCgojIFRoZSBFeHBlcmltZW50IERlc2lnbgoKIyMgUGFyYXNpdGUKCmBgYHtyIGthYmxlX3BhcmFzaXRlfQprbml0cjo6a2FibGUocGFyYXNpdGVfZXhwdCRkZXNpZ24pCmBgYAoKIyBDaGFuZ2Vsb2cKCiogMjAxNzAyMDEKCioqICAgRXhwbGljaXRseSBleGNsdWRlZCByUk5BIGdlbmVzL2ZlYXR1cmVzLCBjdXJyZW50bHkgX29ubHlfIHRob3NlLiAgVGhlIHJlc3Qgb2YgdGhlIG5jUk5BIG1heSBiZQogICAgIHJlbW92ZWQgYnkgYWRkaW5nICJzbm9STkEiLCAibmNSTkEiLCAic25STkEiIHRvICdwYXR0ZXJucycgYWJvdmUuCgpgYGB7ciBzYXZlbWV9CmlmICghaXNUUlVFKGdldDAoInNraXBfbG9hZCIpKSkgewogIHBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCiAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiAgdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCiAgdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQp9CmBgYAo=