1 Spyogenes TNSeq infections: 20170706

2 TODO list

  • 20170522: Get started.

3 Finished TODO

4 Installation and setup

These are rmarkdown documents which make heavy use of the hpgltools package. The following section demonstrates how to set that up in a clean R environment.

## Use R's install.packages to install devtools.
install.packages("devtools")
## Use devtools to install hpgltools.
devtools::install_github("abelew/hpgltools")
## Load hpgltools into the R environment.
library(hpgltools)
pander::pander(sessionInfo())

R version 3.5.1 (2018-07-02)

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: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: hpgltools(v.2018.03)

loaded via a namespace (and not attached): Rcpp(v.0.12.17), compiler(v.3.5.1), pillar(v.1.3.0), plyr(v.1.8.4), bindr(v.0.1.1), base64enc(v.0.1-3), iterators(v.1.0.10), tools(v.3.5.1), digest(v.0.6.15), memoise(v.1.1.0), evaluate(v.0.10.1), tibble(v.1.4.2), gtable(v.0.2.0), pkgconfig(v.2.0.1), rlang(v.0.2.1), foreach(v.1.4.4), commonmark(v.1.5), yaml(v.2.1.19), parallel(v.3.5.1), bindrcpp(v.0.2.2), xml2(v.1.2.0), roxygen2(v.6.0.1), withr(v.2.1.2), stringr(v.1.3.1), dplyr(v.0.7.6), knitr(v.1.20), devtools(v.1.13.6), rprojroot(v.1.3-2), grid(v.3.5.1), tidyselect(v.0.2.4), glue(v.1.2.0), data.table(v.1.11.4), Biobase(v.2.40.0), R6(v.2.2.2), rmarkdown(v.1.10), pander(v.0.6.2), ggplot2(v.3.0.0), purrr(v.0.2.5), magrittr(v.1.5), backports(v.1.1.2), scales(v.0.5.0), codetools(v.0.2-15), htmltools(v.0.3.6), BiocGenerics(v.0.26.0), assertthat(v.0.2.0), colorspace(v.1.3-2), stringi(v.1.2.3), lazyeval(v.0.2.1), munsell(v.0.5.0) and crayon(v.1.3.4)

this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
message(paste0("Saving to ", this_save))
## Saving to index-v20170706.rda.xz
tt <- sm(saveme(filename=this_save))

4.1 Can we produce a master library which is the sum of three others?

The three others are: hpgl0906, hpgl0907, hpgl0908

cd preprocessing
mkdir hpgl0906 hpgl0907 hpgl0908
cd hpgl0906 && rsync -av ~/scratch/tnseq/spyogenes_5448v2/preprocessing/tnseq/hpgl0906/ ./ && cd ..
cd hpgl0907 && rsync -av ~/scratch/tnseq/spyogenes_5448v2/preprocessing/tnseq/hpgl0907/ ./ && cd ..
cd hpgl0908 && rsync -av ~/scratch/tnseq/spyogenes_5448v2/preprocessing/tnseq/hpgl0908/ ./ && cd ..
bamfiles="../hpgl0906/outputs/bowtie_mgas_5005/hpgl0906-trimmed_ca_ta-v0M1.bam \
          ../hpgl0907/outputs/bowtie_mgas_5005/hpgl0907-trimmed_ca_ta-v0M1.bam \
          ../hpgl0908/outputs/bowtie_mgas_5005/hpgl0908-trimmed_ca_ta-v0M1.bam"
samtools merge combined.bam ${bamfiles}

Done.

4.2 For each library(separate and master) what are:

  1. Number of total reads
  2. Strictly aligned
  3. Randomly aligned
  4. The sum of 2,3
  5. Failed aligned reads
  6. Plasmid hits (this will take some time as I neglected to run these alignments)
  7. Unique insertion sites
  8. Saturation index
  9. Average distance

4.2.1 hpgl0906

## The following should answer 1-5 above.
cd preprocessing/
bamtools stats < hpgl0906.bam
## bash: line 2: hpgl0906.bam: No such file or directory

4.2.2 hpgl0907

cd preprocessing/
bamtools stats < hpgl0907.bam
## bash: line 1: hpgl0907.bam: No such file or directory

4.2.3 hpgl0908

cd preprocessing/
bamtools stats < hpgl0908.bam
## bash: line 1: hpgl0908.bam: No such file or directory

4.2.4 combined

cd preprocessing/
bamtools stats < combined.bam
## bash: line 1: combined.bam: No such file or directory

4.2.5 Saturation index

The answer for this is in the R function tnseq_saturation().

file <- "preprocessing/hpgl0906/outputs/essentiality/hpgl0906-v0M1.wig"
hpgl0906_saturation <- tnseq_saturation(data=file)
## Warning in max(data_list, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf
## Error in FUN(X[[i]], ...): only defined on a data frame with all numeric variables
file <- "preprocessing/hpgl0907/outputs/essentiality/hpgl0907-v0M1.wig"
hpgl0907_saturation <- tnseq_saturation(data=file)
## Warning in max(data_list, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf
## Error in FUN(X[[i]], ...): only defined on a data frame with all numeric variables
file <- "preprocessing/hpgl0908/outputs/essentiality/hpgl0908-v0M1.wig"
hpgl0908_saturation <- tnseq_saturation(data=file)
## Warning in max(data_list, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf
## Error in FUN(X[[i]], ...): only defined on a data frame with all numeric variables
file <- "preprocessing/hpgl0909/outputs/essentiality/hpgl0909-v0M1.wig"
hpgl0909_saturation <- tnseq_saturation(data=file)
## Warning in max(data_list, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf
## Error in FUN(X[[i]], ...): only defined on a data frame with all numeric variables
file <- "preprocessing/hpgl0910/outputs/essentiality/hpgl0910-v0M1.wig"
hpgl0910_saturation <- tnseq_saturation(data=file)
## Warning in max(data_list, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf
## Error in FUN(X[[i]], ...): only defined on a data frame with all numeric variables
file <- "preprocessing/hpgl0911/outputs/essentiality/hpgl0911-v0M1.wig"
hpgl0911_saturation <- tnseq_saturation(data=file)
## Warning in max(data_list, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf
## Error in FUN(X[[i]], ...): only defined on a data frame with all numeric variables
## Ok, now have stats for the individual libraries.
all_table <- merge(hpgl0906_saturation$hits_by_position,
                   hpgl0907_saturation$hits_by_position, by="Start")
## Error in merge(hpgl0906_saturation$hits_by_position, hpgl0907_saturation$hits_by_position, : object 'hpgl0906_saturation' not found
all_table <- merge(all_table,
                   hpgl0908_saturation$hits_by_position, by="Start")
## Error in merge(all_table, hpgl0908_saturation$hits_by_position, by = "Start"): object 'all_table' not found
all_table$sum <- 0
## Error in all_table$sum <- 0: object 'all_table' not found
for (r in 1:nrow(all_table)) {
  all_table[r, "sum"] <- all_table[r, "Reads.x"] + all_table[r, "Reads.y"] + all_table[r, "Reads"]
}
## Error in nrow(all_table): object 'all_table' not found
all_table <- all_table[, c("Start", "sum")]
## Error in eval(expr, envir, enclos): object 'all_table' not found
combined_saturation <- tnseq_saturation(data=all_table, column="sum")
## Error in tnseq_saturation(data = all_table, column = "sum"): object 'all_table' not found
all_table2 <- merge(hpgl0909_saturation$hits_by_position,
                    hpgl0910_saturation$hits_by_position, by="Start")
## Error in merge(hpgl0909_saturation$hits_by_position, hpgl0910_saturation$hits_by_position, : object 'hpgl0909_saturation' not found
all_table2 <- merge(all_table2,
                    hpgl0911_saturation$hits_by_position, by="Start")
## Error in merge(all_table2, hpgl0911_saturation$hits_by_position, by = "Start"): object 'all_table2' not found
all_table2$sum <- 0
## Error in all_table2$sum <- 0: object 'all_table2' not found
for (r in 1:nrow(all_table2)) {
  all_table2[r, "sum"] <- all_table2[r, "Reads.x"] + all_table2[r, "Reads.y"] + all_table2[r, "Reads"]
}
## Error in nrow(all_table2): object 'all_table2' not found
all_table2 <- all_table2[, c("Start", "sum")]
## Error in eval(expr, envir, enclos): object 'all_table2' not found
combined_saturation2 <- tnseq_saturation(data=all_table2, column="sum")
## Error in tnseq_saturation(data = all_table2, column = "sum"): object 'all_table2' not found

4.2.5.1 Unique insertion sites

I presume but am not certain that this is the number of > singleton hits.

hpgl0906_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'hpgl0906_saturation' not found
hpgl0906_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'hpgl0906_saturation' not found
hpgl0907_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'hpgl0907_saturation' not found
hpgl0907_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'hpgl0907_saturation' not found
hpgl0908_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'hpgl0908_saturation' not found
hpgl0908_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'hpgl0908_saturation' not found
combined_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'combined_saturation' not found
combined_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'combined_saturation' not found
hpgl0909_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'hpgl0909_saturation' not found
hpgl0909_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'hpgl0909_saturation' not found
hpgl0910_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'hpgl0910_saturation' not found
hpgl0910_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'hpgl0910_saturation' not found
hpgl0911_saturation$eq_0
## Error in eval(expr, envir, enclos): object 'hpgl0911_saturation' not found
hpgl0911_saturation$gt_1
## Error in eval(expr, envir, enclos): object 'hpgl0911_saturation' not found
combined_saturation2$eq_0
## Error in eval(expr, envir, enclos): object 'combined_saturation2' not found
combined_saturation2$gt_1
## Error in eval(expr, envir, enclos): object 'combined_saturation2' not found
hpgl0906_saturation$ratios[1]
## Error in eval(expr, envir, enclos): object 'hpgl0906_saturation' not found
hpgl0906_saturation$ratios[4]
## Error in eval(expr, envir, enclos): object 'hpgl0906_saturation' not found
hpgl0906_saturation$ratios[6]
## Error in eval(expr, envir, enclos): object 'hpgl0906_saturation' not found
hpgl0906_saturation$plot
## Error in eval(expr, envir, enclos): object 'hpgl0906_saturation' not found
hpgl0907_saturation$ratios[1]
## Error in eval(expr, envir, enclos): object 'hpgl0907_saturation' not found
hpgl0907_saturation$ratios[4]
## Error in eval(expr, envir, enclos): object 'hpgl0907_saturation' not found
hpgl0907_saturation$ratios[6]
## Error in eval(expr, envir, enclos): object 'hpgl0907_saturation' not found
hpgl0907_saturation$plot
## Error in eval(expr, envir, enclos): object 'hpgl0907_saturation' not found
hpgl0908_saturation$ratios[1]
## Error in eval(expr, envir, enclos): object 'hpgl0908_saturation' not found
hpgl0908_saturation$ratios[4]
## Error in eval(expr, envir, enclos): object 'hpgl0908_saturation' not found
hpgl0908_saturation$ratios[6]
## Error in eval(expr, envir, enclos): object 'hpgl0908_saturation' not found
hpgl0908_saturation$plot
## Error in eval(expr, envir, enclos): object 'hpgl0908_saturation' not found
combined_saturation$ratios[1]
## Error in eval(expr, envir, enclos): object 'combined_saturation' not found
combined_saturation$ratios[4]
## Error in eval(expr, envir, enclos): object 'combined_saturation' not found
combined_saturation$ratios[6]
## Error in eval(expr, envir, enclos): object 'combined_saturation' not found
combined_saturation$plot
## Error in eval(expr, envir, enclos): object 'combined_saturation' not found

4.3 How many TAs are in the MGAS5005 genome?

The answer to this question should be easily searchable in either the annotation data for the genome and/or the precursor files for essentiality (which collects hits on every TA).

The following counts the number of lines in the tas.txt file. The answer should be that -1, as the first line is a header.

cd preprocessing/hpgl0906/outputs/essentiality/
wc hpgl0906-trimmed_ca_ta-v0M1_tas.txt
## wc: hpgl0906-trimmed_ca_ta-v0M1_tas.txt: No such file or directory
LS0tCnRpdGxlOiAiUy5weW9nZW5lcyAyMDE3OiBUTlNlcSBpbmRleC4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogZGVmYXVsdAogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IHJlYWRhYmxlCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICAgY29sbGFwc2VkOiBmYWxzZQogICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoImhwZ2x0b29scyIpCnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnNldC5zZWVkKDEpCnZlciA8LSAiMjAxNzA3MDYiCnByZXZpb3VzX2ZpbGUgPC0gImluZGV4LlJtZCIKCnRtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpKQoKcm1kX2ZpbGUgPC0gImluZGV4LlJtZCIKYGBgCgojIFNweW9nZW5lcyBUTlNlcSBpbmZlY3Rpb25zOiBgciB2ZXJgCgojIFRPRE8gbGlzdAoKKiAyMDE3MDUyMjogR2V0IHN0YXJ0ZWQuCgojIEZpbmlzaGVkIFRPRE8KCiMgSW5zdGFsbGF0aW9uIGFuZCBzZXR1cAoKVGhlc2UgYXJlIHJtYXJrZG93biBkb2N1bWVudHMgd2hpY2ggbWFrZSBoZWF2eSB1c2Ugb2YgdGhlIGhwZ2x0b29scyBwYWNrYWdlLiAgVGhlIGZvbGxvd2luZyBzZWN0aW9uCmRlbW9uc3RyYXRlcyBob3cgdG8gc2V0IHRoYXQgdXAgaW4gYSBjbGVhbiBSIGVudmlyb25tZW50LgoKYGBge3Igc2V0dXAsIGV2YWw9RkFMU0V9CiMjIFVzZSBSJ3MgaW5zdGFsbC5wYWNrYWdlcyB0byBpbnN0YWxsIGRldnRvb2xzLgppbnN0YWxsLnBhY2thZ2VzKCJkZXZ0b29scyIpCiMjIFVzZSBkZXZ0b29scyB0byBpbnN0YWxsIGhwZ2x0b29scy4KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJhYmVsZXcvaHBnbHRvb2xzIikKIyMgTG9hZCBocGdsdG9vbHMgaW50byB0aGUgUiBlbnZpcm9ubWVudC4KbGlicmFyeShocGdsdG9vbHMpCmBgYAoKYGBge3Igc2F2ZW1lfQpwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQp0aGlzX3NhdmUgPC0gcGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1ybWRfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKQptZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCnR0IDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAKCiMjIENhbiB3ZSBwcm9kdWNlIGEgbWFzdGVyIGxpYnJhcnkgd2hpY2ggaXMgdGhlIHN1bSBvZiB0aHJlZSBvdGhlcnM/CgpUaGUgdGhyZWUgb3RoZXJzIGFyZTogaHBnbDA5MDYsIGhwZ2wwOTA3LCBocGdsMDkwOAoKYGBge3IgY29weV9jb21iaW5lLCBlbmdpbmU9J2Jhc2gnLCBldmFsPUZBTFNFfQpjZCBwcmVwcm9jZXNzaW5nCm1rZGlyIGhwZ2wwOTA2IGhwZ2wwOTA3IGhwZ2wwOTA4CmNkIGhwZ2wwOTA2ICYmIHJzeW5jIC1hdiB+L3NjcmF0Y2gvdG5zZXEvc3B5b2dlbmVzXzU0NDh2Mi9wcmVwcm9jZXNzaW5nL3Ruc2VxL2hwZ2wwOTA2LyAuLyAmJiBjZCAuLgpjZCBocGdsMDkwNyAmJiByc3luYyAtYXYgfi9zY3JhdGNoL3Ruc2VxL3NweW9nZW5lc181NDQ4djIvcHJlcHJvY2Vzc2luZy90bnNlcS9ocGdsMDkwNy8gLi8gJiYgY2QgLi4KY2QgaHBnbDA5MDggJiYgcnN5bmMgLWF2IH4vc2NyYXRjaC90bnNlcS9zcHlvZ2VuZXNfNTQ0OHYyL3ByZXByb2Nlc3NpbmcvdG5zZXEvaHBnbDA5MDgvIC4vICYmIGNkIC4uCmJhbWZpbGVzPSIuLi9ocGdsMDkwNi9vdXRwdXRzL2Jvd3RpZV9tZ2FzXzUwMDUvaHBnbDA5MDYtdHJpbW1lZF9jYV90YS12ME0xLmJhbSBcCiAgICAgICAgICAuLi9ocGdsMDkwNy9vdXRwdXRzL2Jvd3RpZV9tZ2FzXzUwMDUvaHBnbDA5MDctdHJpbW1lZF9jYV90YS12ME0xLmJhbSBcCiAgICAgICAgICAuLi9ocGdsMDkwOC9vdXRwdXRzL2Jvd3RpZV9tZ2FzXzUwMDUvaHBnbDA5MDgtdHJpbW1lZF9jYV90YS12ME0xLmJhbSIKc2FtdG9vbHMgbWVyZ2UgY29tYmluZWQuYmFtICR7YmFtZmlsZXN9CmBgYAoKRG9uZS4KCiMjIEZvciBlYWNoIGxpYnJhcnkoc2VwYXJhdGUgYW5kIG1hc3Rlcikgd2hhdCBhcmU6CgoxLiAgTnVtYmVyIG9mIHRvdGFsIHJlYWRzCjIuICBTdHJpY3RseSBhbGlnbmVkCjMuICBSYW5kb21seSBhbGlnbmVkCjQuICBUaGUgc3VtIG9mIDIsMwo1LiAgRmFpbGVkIGFsaWduZWQgcmVhZHMKNi4gIFBsYXNtaWQgaGl0cyAodGhpcyB3aWxsIHRha2Ugc29tZSB0aW1lIGFzIEkgbmVnbGVjdGVkIHRvIHJ1biB0aGVzZSBhbGlnbm1lbnRzKQo3LiAgVW5pcXVlIGluc2VydGlvbiBzaXRlcwo4LiAgU2F0dXJhdGlvbiBpbmRleAo5LiAgQXZlcmFnZSBkaXN0YW5jZQoKIyMjIGhwZ2wwOTA2CgpgYGB7ciBudW1iZXJfcmVhZHNfOTA2LCBlbmdpbmU9J2Jhc2gnfQojIyBUaGUgZm9sbG93aW5nIHNob3VsZCBhbnN3ZXIgMS01IGFib3ZlLgpjZCBwcmVwcm9jZXNzaW5nLwpiYW10b29scyBzdGF0cyA8IGhwZ2wwOTA2LmJhbQpgYGAKCiMjIyBocGdsMDkwNwoKYGBge3IgbnVtYmVyX3JlYWRzXzkwNywgZW5naW5lPSdiYXNoJ30KY2QgcHJlcHJvY2Vzc2luZy8KYmFtdG9vbHMgc3RhdHMgPCBocGdsMDkwNy5iYW0KYGBgCgojIyMgaHBnbDA5MDgKCmBgYHtyIG51bWJlcl9yZWFkc185MDgsIGVuZ2luZT0nYmFzaCd9CmNkIHByZXByb2Nlc3NpbmcvCmJhbXRvb2xzIHN0YXRzIDwgaHBnbDA5MDguYmFtCmBgYAoKIyMjIGNvbWJpbmVkCgpgYGB7ciBudW1iZXJfcmVhZHNfY29tYmluZWQsIGVuZ2luZT0nYmFzaCd9CmNkIHByZXByb2Nlc3NpbmcvCmJhbXRvb2xzIHN0YXRzIDwgY29tYmluZWQuYmFtCmBgYAoKIyMjIFNhdHVyYXRpb24gaW5kZXgKClRoZSBhbnN3ZXIgZm9yIHRoaXMgaXMgaW4gdGhlIFIgZnVuY3Rpb24gdG5zZXFfc2F0dXJhdGlvbigpLgoKYGBge3Igc2F0dXJhdGlvbn0KZmlsZSA8LSAicHJlcHJvY2Vzc2luZy9ocGdsMDkwNi9vdXRwdXRzL2Vzc2VudGlhbGl0eS9ocGdsMDkwNi12ME0xLndpZyIKaHBnbDA5MDZfc2F0dXJhdGlvbiA8LSB0bnNlcV9zYXR1cmF0aW9uKGRhdGE9ZmlsZSkKZmlsZSA8LSAicHJlcHJvY2Vzc2luZy9ocGdsMDkwNy9vdXRwdXRzL2Vzc2VudGlhbGl0eS9ocGdsMDkwNy12ME0xLndpZyIKaHBnbDA5MDdfc2F0dXJhdGlvbiA8LSB0bnNlcV9zYXR1cmF0aW9uKGRhdGE9ZmlsZSkKZmlsZSA8LSAicHJlcHJvY2Vzc2luZy9ocGdsMDkwOC9vdXRwdXRzL2Vzc2VudGlhbGl0eS9ocGdsMDkwOC12ME0xLndpZyIKaHBnbDA5MDhfc2F0dXJhdGlvbiA8LSB0bnNlcV9zYXR1cmF0aW9uKGRhdGE9ZmlsZSkKCmZpbGUgPC0gInByZXByb2Nlc3NpbmcvaHBnbDA5MDkvb3V0cHV0cy9lc3NlbnRpYWxpdHkvaHBnbDA5MDktdjBNMS53aWciCmhwZ2wwOTA5X3NhdHVyYXRpb24gPC0gdG5zZXFfc2F0dXJhdGlvbihkYXRhPWZpbGUpCmZpbGUgPC0gInByZXByb2Nlc3NpbmcvaHBnbDA5MTAvb3V0cHV0cy9lc3NlbnRpYWxpdHkvaHBnbDA5MTAtdjBNMS53aWciCmhwZ2wwOTEwX3NhdHVyYXRpb24gPC0gdG5zZXFfc2F0dXJhdGlvbihkYXRhPWZpbGUpCmZpbGUgPC0gInByZXByb2Nlc3NpbmcvaHBnbDA5MTEvb3V0cHV0cy9lc3NlbnRpYWxpdHkvaHBnbDA5MTEtdjBNMS53aWciCmhwZ2wwOTExX3NhdHVyYXRpb24gPC0gdG5zZXFfc2F0dXJhdGlvbihkYXRhPWZpbGUpCgojIyBPaywgbm93IGhhdmUgc3RhdHMgZm9yIHRoZSBpbmRpdmlkdWFsIGxpYnJhcmllcy4KYWxsX3RhYmxlIDwtIG1lcmdlKGhwZ2wwOTA2X3NhdHVyYXRpb24kaGl0c19ieV9wb3NpdGlvbiwKICAgICAgICAgICAgICAgICAgIGhwZ2wwOTA3X3NhdHVyYXRpb24kaGl0c19ieV9wb3NpdGlvbiwgYnk9IlN0YXJ0IikKYWxsX3RhYmxlIDwtIG1lcmdlKGFsbF90YWJsZSwKICAgICAgICAgICAgICAgICAgIGhwZ2wwOTA4X3NhdHVyYXRpb24kaGl0c19ieV9wb3NpdGlvbiwgYnk9IlN0YXJ0IikKYWxsX3RhYmxlJHN1bSA8LSAwCmZvciAociBpbiAxOm5yb3coYWxsX3RhYmxlKSkgewogIGFsbF90YWJsZVtyLCAic3VtIl0gPC0gYWxsX3RhYmxlW3IsICJSZWFkcy54Il0gKyBhbGxfdGFibGVbciwgIlJlYWRzLnkiXSArIGFsbF90YWJsZVtyLCAiUmVhZHMiXQp9CmFsbF90YWJsZSA8LSBhbGxfdGFibGVbLCBjKCJTdGFydCIsICJzdW0iKV0KY29tYmluZWRfc2F0dXJhdGlvbiA8LSB0bnNlcV9zYXR1cmF0aW9uKGRhdGE9YWxsX3RhYmxlLCBjb2x1bW49InN1bSIpCgphbGxfdGFibGUyIDwtIG1lcmdlKGhwZ2wwOTA5X3NhdHVyYXRpb24kaGl0c19ieV9wb3NpdGlvbiwKICAgICAgICAgICAgICAgICAgICBocGdsMDkxMF9zYXR1cmF0aW9uJGhpdHNfYnlfcG9zaXRpb24sIGJ5PSJTdGFydCIpCmFsbF90YWJsZTIgPC0gbWVyZ2UoYWxsX3RhYmxlMiwKICAgICAgICAgICAgICAgICAgICBocGdsMDkxMV9zYXR1cmF0aW9uJGhpdHNfYnlfcG9zaXRpb24sIGJ5PSJTdGFydCIpCmFsbF90YWJsZTIkc3VtIDwtIDAKZm9yIChyIGluIDE6bnJvdyhhbGxfdGFibGUyKSkgewogIGFsbF90YWJsZTJbciwgInN1bSJdIDwtIGFsbF90YWJsZTJbciwgIlJlYWRzLngiXSArIGFsbF90YWJsZTJbciwgIlJlYWRzLnkiXSArIGFsbF90YWJsZTJbciwgIlJlYWRzIl0KfQphbGxfdGFibGUyIDwtIGFsbF90YWJsZTJbLCBjKCJTdGFydCIsICJzdW0iKV0KY29tYmluZWRfc2F0dXJhdGlvbjIgPC0gdG5zZXFfc2F0dXJhdGlvbihkYXRhPWFsbF90YWJsZTIsIGNvbHVtbj0ic3VtIikKYGBgCgojIyMjIFVuaXF1ZSBpbnNlcnRpb24gc2l0ZXMKCkkgcHJlc3VtZSBidXQgYW0gbm90IGNlcnRhaW4gdGhhdCB0aGlzIGlzIHRoZSBudW1iZXIgb2YgPiBzaW5nbGV0b24gaGl0cy4KCmBgYHtyIHVuaXF1ZV9zaXRlc30KaHBnbDA5MDZfc2F0dXJhdGlvbiRlcV8wCmhwZ2wwOTA2X3NhdHVyYXRpb24kZ3RfMQoKaHBnbDA5MDdfc2F0dXJhdGlvbiRlcV8wCmhwZ2wwOTA3X3NhdHVyYXRpb24kZ3RfMQoKaHBnbDA5MDhfc2F0dXJhdGlvbiRlcV8wCmhwZ2wwOTA4X3NhdHVyYXRpb24kZ3RfMQoKY29tYmluZWRfc2F0dXJhdGlvbiRlcV8wCmNvbWJpbmVkX3NhdHVyYXRpb24kZ3RfMQoKaHBnbDA5MDlfc2F0dXJhdGlvbiRlcV8wCmhwZ2wwOTA5X3NhdHVyYXRpb24kZ3RfMQoKaHBnbDA5MTBfc2F0dXJhdGlvbiRlcV8wCmhwZ2wwOTEwX3NhdHVyYXRpb24kZ3RfMQoKaHBnbDA5MTFfc2F0dXJhdGlvbiRlcV8wCmhwZ2wwOTExX3NhdHVyYXRpb24kZ3RfMQoKY29tYmluZWRfc2F0dXJhdGlvbjIkZXFfMApjb21iaW5lZF9zYXR1cmF0aW9uMiRndF8xCmBgYAoKYGBge3Igc2F0dXJhdGlvbl9pbmRleGVzfQpocGdsMDkwNl9zYXR1cmF0aW9uJHJhdGlvc1sxXQpocGdsMDkwNl9zYXR1cmF0aW9uJHJhdGlvc1s0XQpocGdsMDkwNl9zYXR1cmF0aW9uJHJhdGlvc1s2XQpocGdsMDkwNl9zYXR1cmF0aW9uJHBsb3QKCmhwZ2wwOTA3X3NhdHVyYXRpb24kcmF0aW9zWzFdCmhwZ2wwOTA3X3NhdHVyYXRpb24kcmF0aW9zWzRdCmhwZ2wwOTA3X3NhdHVyYXRpb24kcmF0aW9zWzZdCmhwZ2wwOTA3X3NhdHVyYXRpb24kcGxvdAoKaHBnbDA5MDhfc2F0dXJhdGlvbiRyYXRpb3NbMV0KaHBnbDA5MDhfc2F0dXJhdGlvbiRyYXRpb3NbNF0KaHBnbDA5MDhfc2F0dXJhdGlvbiRyYXRpb3NbNl0KaHBnbDA5MDhfc2F0dXJhdGlvbiRwbG90Cgpjb21iaW5lZF9zYXR1cmF0aW9uJHJhdGlvc1sxXQpjb21iaW5lZF9zYXR1cmF0aW9uJHJhdGlvc1s0XQpjb21iaW5lZF9zYXR1cmF0aW9uJHJhdGlvc1s2XQpjb21iaW5lZF9zYXR1cmF0aW9uJHBsb3QKYGBgCgojIyBIb3cgbWFueSBUQXMgYXJlIGluIHRoZSBNR0FTNTAwNSBnZW5vbWU/CgpUaGUgYW5zd2VyIHRvIHRoaXMgcXVlc3Rpb24gc2hvdWxkIGJlIGVhc2lseSBzZWFyY2hhYmxlIGluIGVpdGhlciB0aGUgYW5ub3RhdGlvbiBkYXRhIGZvciB0aGUKZ2Vub21lIGFuZC9vciB0aGUgcHJlY3Vyc29yIGZpbGVzIGZvciBlc3NlbnRpYWxpdHkgKHdoaWNoIGNvbGxlY3RzIGhpdHMgb24gZXZlcnkgVEEpLgoKVGhlIGZvbGxvd2luZyBjb3VudHMgdGhlIG51bWJlciBvZiBsaW5lcyBpbiB0aGUgdGFzLnR4dCBmaWxlLgpUaGUgYW5zd2VyIHNob3VsZCBiZSB0aGF0IC0xLCBhcyB0aGUgZmlyc3QgbGluZSBpcyBhIGhlYWRlci4KCmBgYHtyIG51bWJlcl90YXMsIGVuZ2luZT0nYmFzaCd9CmNkIHByZXByb2Nlc3NpbmcvaHBnbDA5MDYvb3V0cHV0cy9lc3NlbnRpYWxpdHkvCndjIGhwZ2wwOTA2LXRyaW1tZWRfY2FfdGEtdjBNMV90YXMudHh0CmBgYAo=