1 RNA sequencing of L. panamensis: Antimonial responses.

This document seeks to explore the differences in samples which did and did-not respond to drug treatment during infection.

3 Normalize antimonial host samples

Perform an initial sample normalization and see how they look.

## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(cbcb(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: cbcb
## Removing 6998 low-count genes (11849 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
## Graphing number of non-zero genes with respect to CPM by library.
## Graphing library sizes.
## Graphing a boxplot.
## Graphing a correlation heatmap.
## Graphing a standard median correlation.
## Performing correlation.
## Graphing a distance heatmap.
## Graphing a standard median distance.
## Performing distance.
## Graphing a PCA plot.
## Graphing a T-SNE plot.
## Plotting a density plot.
## Plotting a CV plot.
## Naively calculating coefficient of variation/dispersion with respect to condition.
## Finished calculating dispersion estimates.
## Plotting the representation of the top-n genes.
## Plotting the expression of the top-n PC loaded genes.
## Printing a color to condition legend.

Do these samples segregate in ways which make sense?

3.1 Batch normalize antimonial host samples

The batch effect is pretty severe, what happens if we try combat on it?

## This function will replace the expt$expressionset slot with:
## combat(quant(cbcb(data)))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data in its current base format, keep in mind that
##  some metrics are easier to see when the data is log2 transformed, but
##  EdgeR/DESeq do not accept transformed data.
## Leaving the data unconverted.  It is often advisable to cpm/rpkm
##  the data to normalize for sampling differences, keep in mind though that rpkm
##  has some annoying biases, and voom() by default does a cpm (though hpgl_voom()
##  will try to detect this).
## Step 1: performing count filter with option: cbcb
## Removing 6998 low-count genes (11849 remaining).
## Step 2: normalizing the data with quant.
## Step 3: not converting the data.
## Step 4: not transforming the data.
## Step 5: doing batch correction with combat.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 142037 entries are x>1: 99.9%.
## batch_counts: Before batch/surrogate estimation, 2 entries are x==0: 0.00141%.
## batch_counts: Before batch/surrogate estimation, 108 entries are 0<x<1: 0.0760%.
## The be method chose 2 surrogate variable(s).
## batch_counts: Using combat with a prior, no scaling, and a null model.
## There are 389 (0.274%) elements which are < 0 after batch correction.
## This function will replace the expt$expressionset slot with:
## combat_scale(quant(cbcb(data)))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data in its current base format, keep in mind that
##  some metrics are easier to see when the data is log2 transformed, but
##  EdgeR/DESeq do not accept transformed data.
## Leaving the data unconverted.  It is often advisable to cpm/rpkm
##  the data to normalize for sampling differences, keep in mind though that rpkm
##  has some annoying biases, and voom() by default does a cpm (though hpgl_voom()
##  will try to detect this).
## Step 1: performing count filter with option: cbcb
## Removing 6998 low-count genes (11849 remaining).
## Step 2: normalizing the data with quant.
## Step 3: not converting the data.
## Step 4: not transforming the data.
## Step 5: doing batch correction with combat_scale.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 142037 entries are x>1: 99.9%.
## batch_counts: Before batch/surrogate estimation, 2 entries are x==0: 0.00141%.
## batch_counts: Before batch/surrogate estimation, 108 entries are 0<x<1: 0.0760%.
## The be method chose 2 surrogate variable(s).
## batch_counts: Using combat with a prior and with scaling.
## There are 1929 (1.36%) elements which are < 0 after batch correction.

## Graphing number of non-zero genes with respect to CPM by library.
## Graphing library sizes.
## Graphing a boxplot.
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some data are negative.  We are on log scale, setting them to 0.
## Changed 1929 negative features.
## Some entries are 0.  We are on log scale, adding 1 to the data.
## Changed 1929 zero count features.
## Graphing a correlation heatmap.
## Graphing a standard median correlation.
## Performing correlation.
## Graphing a distance heatmap.
## Graphing a standard median distance.
## Performing distance.
## Graphing a PCA plot.
## Graphing a T-SNE plot.
## Plotting a density plot.
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some data are negative.  We are on log scale, setting them to 0.5.
## Changed 1929 negative features.
## Plotting a CV plot.
## Naively calculating coefficient of variation/dispersion with respect to condition.
## Finished calculating dispersion estimates.
## Plotting the representation of the top-n genes.
## Plotting the expression of the top-n PC loaded genes.
## Printing a color to condition legend.

The PCA plot of the combat adjusted data suggests that it might actually work out ok. Let us look at the other metrics.

4 Differential Expression of antimonial host samples

## Testing method: limma.
## Adding method: limma to the set.
## Testing method: deseq.
## Adding method: deseq to the set.
## Testing method: edger.
## Adding method: edger to the set.
## Testing method: ebseq.
## Adding method: ebseq to the set.
## Testing method: basic.
## Adding method: basic to the set.
## Warning in cor(x = fs[["x"]], y = fs[["y"]], method = cor_method): the
## standard deviation is zero

## Warning in cor(x = fs[["x"]], y = fs[["y"]], method = cor_method): the
## standard deviation is zero
## fail_respond_inf fail_respond_nil             fail          respond 
##           0.2371           0.1971           0.6620           0.6337

5 Repeat using the parasite data

## Using a subset expression.
## There were 33, now there are 6 samples.

## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(cbcb(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: cbcb
## Removing 0 low-count genes (8841 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 93 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.

## This function will replace the expt$expressionset slot with:
## log2(svaseq(simple(data)))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data unconverted.  It is often advisable to cpm/rpkm
##  the data to normalize for sampling differences, keep in mind though that rpkm
##  has some annoying biases, and voom() by default does a cpm (though hpgl_voom()
##  will try to detect this).
## Leaving the data unnormalized.  This is necessary for DESeq, but
##  EdgeR/limma might benefit from normalization.  Good choices include quantile,
##  size-factor, tmm, etc.
## Step 1: performing count filter with option: simple
## Removing 114 low-count genes (8727 remaining).
## Step 2: not normalizing the data.
## Step 3: not converting the data.
## Step 4: transforming the data with log2.
## transform_counts: Found 7670 values equal to 0, adding 1 to the matrix.
## Step 5: doing batch correction with svaseq.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 40937 entries are x>1: 78.2%.
## batch_counts: Before batch/surrogate estimation, 7670 entries are x==0: 14.6%.
## The be method chose 1 surrogate variable(s).
## Attempting svaseq estimation with 1 surrogates.
## There are 15939 (30.4%) elements which are < 0 after batch correction.

5.0.1 Also try antimonials

human_expt <- create_expt(file="all_samples-hsapiens.xlsx")
antimonial_expt <- expt_subset(human_expt, subset="condition=='respond_nil'|condition=='respond_inf'|condition=='fail_nil'|condition=='fail_inf'")
antimonial_expt$colors <- c("blue","blue","red","red","black","black","green","green","red","green","blue","black")
antimonial_metrics <- graph_metrics(antimonial_expt)
antimonial_metrics$libsize
antimonial_norm <- normalize_expt(antimonial_expt, transform="log2", convert="cpm", filter_low=TRUE, norm="quant")
antimonialnorm_metrics <- graph_metrics(antimonial_norm)
antimonialnorm_metrics$pcaplot
antimonialnorm_metrics$corheat
antimonialnorm_metrics$disheat
antimonial_nb <- normalize_expt(antimonial_expt, transform="log2", convert="cpm", filter_low=TRUE, norm="quant", batch="combat")
antimonialnb_metrics <- graph_metrics(antimonial_nb)
antimonialnb_metrics$pcaplot
pp("images/antimonial_batch_corheat.png")
antimonialnb_metrics$corheat
dev.off()

## Reread the parasite sample sheet to play with other covariants
## Wow, from the parasite perspective, it seems they cluster much more tightly by strain
parasite_expt <- create_expt(file="all_samples-lpanamensis_patientbatch.xlsx")
antipara_expt <-  expt_subset(parasite_expt, subset="condition=='ant_good'|condition=='ant_bad'")
antipara_metrics <- graph_metrics(antipara_expt)
antipara_metrics$pcaplot
antipara_norm <- normalize_expt(antipara_expt, transform="log2", convert="cpm", filter_low=TRUE, norm="quant", batch="combat")
antiparanorm_metrics <- graph_metrics(antipara_norm)
antiparanorm_metrics$pcaplot
antiparanorm_metrics$corheat

6 Save the results.

## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset c2881f6d97e1ec981fd1481cf46d6bc875fac423
## This is hpgltools commit: Tue Oct 22 10:22:30 2019 -0400: c2881f6d97e1ec981fd1481cf46d6bc875fac423
## Saving to 02_antimonial_estimation_20190914-v20190914.rda.xz

R version 3.6.1 (2019-07-05)

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

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

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

other attached packages: Heatplus(v.2.31.0), foreach(v.1.4.7), ruv(v.0.9.7.1), hpgltools(v.1.0), Biobase(v.2.45.1) and BiocGenerics(v.0.31.6)

loaded via a namespace (and not attached): Rtsne(v.0.15), colorspace(v.1.4-1), htmlTable(v.1.13.2), corpcor(v.1.6.9), XVector(v.0.25.0), GenomicRanges(v.1.37.17), base64enc(v.0.1-3), Vennerable(v.3.1.0.9000), rstudioapi(v.0.10), ggrepel(v.0.8.1), bit64(v.0.9-7), AnnotationDbi(v.1.47.1), codetools(v.0.2-16), splines(v.3.6.1), doParallel(v.1.0.15), robustbase(v.0.93-5), geneplotter(v.1.63.0), knitr(v.1.25), zeallot(v.0.1.0), Formula(v.1.2-3), Rsamtools(v.2.1.7), annotate(v.1.63.0), cluster(v.2.1.0), dbplyr(v.1.4.2), graph(v.1.63.0), BiocManager(v.1.30.8), compiler(v.3.6.1), httr(v.1.4.1), backports(v.1.1.5), assertthat(v.0.2.1), Matrix(v.1.2-17), lazyeval(v.0.2.2), limma(v.3.41.18), acepack(v.1.4.1), htmltools(v.0.4.0), prettyunits(v.1.0.2), tools(v.3.6.1), gtable(v.0.3.0), glue(v.1.3.1), GenomeInfoDbData(v.1.2.1), reshape2(v.1.4.3), dplyr(v.0.8.3), rappdirs(v.0.3.1), Rcpp(v.1.0.2), vctrs(v.0.2.0), Biostrings(v.2.53.2), gdata(v.2.18.0), preprocessCore(v.1.47.1), nlme(v.3.1-141), rtracklayer(v.1.45.6), iterators(v.1.0.12), xfun(v.0.10), fastcluster(v.1.1.25), stringr(v.1.4.0), openxlsx(v.4.1.0.1), gtools(v.3.8.1), XML(v.3.98-1.20), DEoptimR(v.1.0-8), edgeR(v.3.27.13), directlabels(v.2018.05.22), zlibbioc(v.1.31.0), scales(v.1.0.0), doSNOW(v.1.0.18), hms(v.0.5.1), SummarizedExperiment(v.1.15.9), RBGL(v.1.61.0), RColorBrewer(v.1.1-2), yaml(v.2.2.0), curl(v.4.2), memoise(v.1.1.0), gridExtra(v.2.3), pander(v.0.6.3), ggplot2(v.3.2.1), rpart(v.4.1-15), biomaRt(v.2.41.9), latticeExtra(v.0.6-28), stringi(v.1.4.3), RSQLite(v.2.1.2), genefilter(v.1.67.1), S4Vectors(v.0.23.25), checkmate(v.1.9.4), GenomicFeatures(v.1.37.4), caTools(v.1.17.1.2), zip(v.2.0.4), BiocParallel(v.1.19.4), GenomeInfoDb(v.1.21.2), rlang(v.0.4.0), pkgconfig(v.2.0.3), matrixStats(v.0.55.0), bitops(v.1.0-6), evaluate(v.0.14), lattice(v.0.20-38), purrr(v.0.3.3), htmlwidgets(v.1.5.1), GenomicAlignments(v.1.21.7), labeling(v.0.3), bit(v.1.1-14), tidyselect(v.0.2.5), plyr(v.1.8.4), magrittr(v.1.5), DESeq2(v.1.25.17), R6(v.2.4.0), snow(v.0.4-3), IRanges(v.2.19.17), gplots(v.3.0.1.1), Hmisc(v.4.2-0), DelayedArray(v.0.11.8), DBI(v.1.0.0), pillar(v.1.4.2), foreign(v.0.8-72), mgcv(v.1.8-29), survival(v.2.44-1.1), RCurl(v.1.95-4.12), nnet(v.7.3-12), tibble(v.2.1.3), crayon(v.1.3.4), KernSmooth(v.2.23-16), OrganismDbi(v.1.27.1), BiocFileCache(v.1.9.1), rmarkdown(v.1.16), progress(v.1.2.2), locfit(v.1.5-9.1), grid(v.3.6.1), sva(v.3.33.1), data.table(v.1.12.6), blob(v.1.2.0), digest(v.0.6.22), xtable(v.1.8-4), openssl(v.1.4.1), stats4(v.3.6.1), munsell(v.0.5.0), askpass(v.1.1) and quadprog(v.1.5-7)

LS0tCnRpdGxlOiAiTC5wYW5hbWVuc2lzIDIwMTkwOTogQW50aW1vbmlhbCBSZXNwb25zZSBTYW1wbGUgRXN0aW1hdGlvbi4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZl9wcmludDogcGFnZWQKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHdpZHRoOiAzMDAKICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5LCB0ZCB7CiAgZm9udC1zaXplOiAxNnB4Owp9CmNvZGUucnsKICBmb250LXNpemU6IDE2cHg7Cn0KcHJlIHsKIGZvbnQtc2l6ZTogMTZweAp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KCJocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LAogICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpzZXQuc2VlZCgxKQp2ZXIgPC0gIjIwMTkwOTE0IgpwcmV2aW91c19maWxlIDwtICIwMV9hbm5vdGF0aW9uXzIwMTkwOTE0LlJtZCIKCnRtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPXBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cHJldmlvdXNfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKSkpKQpybWRfZmlsZSA8LSAiMDJfYW50aW1vbmlhbF9lc3RpbWF0aW9uXzIwMTkwOTE0LlJtZCIKYGBgCgpSTkEgc2VxdWVuY2luZyBvZiBMLiBwYW5hbWVuc2lzOiBBbnRpbW9uaWFsIHJlc3BvbnNlcy4KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpUaGlzIGRvY3VtZW50IHNlZWtzIHRvIGV4cGxvcmUgdGhlIGRpZmZlcmVuY2VzIGluIHNhbXBsZXMgd2hpY2ggZGlkIGFuZCBkaWQtbm90IHJlc3BvbmQgdG8gZHJ1Zwp0cmVhdG1lbnQgZHVyaW5nIGluZmVjdGlvbi4KCiMgQW50aW1vbmlhbCBob3N0IHJlc3BvbnNlcwoKRXh0cmFjdCB0aGUgYW50aW1vbmlhbCBzYW1wbGVzIGZyb20gdGhlIGV4cGVyaW1lbnQuCgpgYGB7ciBleHBfc3Vic2V0fQphbnQgPC0gc3Vic2V0X2V4cHQoaHNfY2RzX2V4cHQsIHN1YnNldD0iY29uZGl0aW9uPT0ncmVzcG9uZF9uaWwnfGNvbmRpdGlvbj09J3Jlc3BvbmRfaW5mJ3xjb25kaXRpb249PSdmYWlsX25pbCd8Y29uZGl0aW9uPT0nZmFpbF9pbmYnIikKYW50JGNvbG9ycyA8LSBnc3ViKHBhdHRlcm49IkNEOTYwQyIsIHJlcGxhY2VtZW50PSIwMDU1MDAiLCB4PWFudCRjb2xvcnMpCmFudCRjb2xvcnMgPC0gZ3N1YihwYXR0ZXJuPSJBQTdBMUEiLCByZXBsYWNlbWVudD0iODgwMDAwIiwgeD1hbnQkY29sb3JzKQphbnQkY29sb3JzIDwtIGdzdWIocGF0dGVybj0iODg2RTNFIiwgcmVwbGFjZW1lbnQ9IjAwMDBFRSIsIHg9YW50JGNvbG9ycykKYW50JGNvbG9ycyA8LSBnc3ViKHBhdHRlcm49IjY2NjY2NiIsIHJlcGxhY2VtZW50PSI3Nzc3NzciLCB4PWFudCRjb2xvcnMpCmBgYAoKIyMgR3JhcGggYW50aW1vbmlhbCBob3N0IG1ldHJpY3MKCmBgYHtyIGFudGltb25pYWxfbWV0cmljcywgZmlnLnNob3c9ImhpZGUifQphbnRfbWV0IDwtIHN1cHByZXNzTWVzc2FnZXMoZ3JhcGhfbWV0cmljcyhhbnQpKQpgYGAKCkxldHMgdGFrZSBhIGxvb2sgYXQgdGhlIGRhdGEgYmVmb3JlIG5vcm1hbGl6YXRpb24uCgpgYGB7ciB2aXN1YWxpemVfcHJlfQphbnRfbWV0JGxpYnNpemUKYW50X21ldCRub256ZXJvCmBgYAoKIyBOb3JtYWxpemUgYW50aW1vbmlhbCBob3N0IHNhbXBsZXMKClBlcmZvcm0gYW4gaW5pdGlhbCBzYW1wbGUgbm9ybWFsaXphdGlvbiBhbmQgc2VlIGhvdyB0aGV5IGxvb2suCgpgYGB7ciBub3JtYWxpemV9CmFub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGFudCwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwgZmlsdGVyPVRSVUUsIG5vcm09InF1YW50IikKYGBgCgpgYGB7ciBncmFwaF9ub3JtYWxpemVkLCBmaWcuc2hvdz0iaGlkZSJ9CmFub3JtX21ldCA8LSBncmFwaF9tZXRyaWNzKGFub3JtKQpgYGAKCkRvIHRoZXNlIHNhbXBsZXMgc2VncmVnYXRlIGluIHdheXMgd2hpY2ggbWFrZSBzZW5zZT8KCmBgYHtyIHZpc3VhbGl6ZV9ub3JtYWxpemVkfQpwbG90X3BjYShhbm9ybSkkcGxvdAojIyBCbGFja3MgYXJlIG9rIC0tIHJlc3BvbmRzLCBpbmZlY3RlZAojIyBCbHVlIGFyZSBzdXBwb3NlZCB0byBiZSBmYWlsLCBpbmZlY3RlZAojIyBHcmVlbiBhcmUgc3VwcG9zZWQgdG8gYmUgcmVzcG9uZCwgdW5pbmZlY3RlZAojIyBUaGlzIGFwcGVhcnMgdG8gYmUgYSBmb3JtaWRhYmxlIGJhdGNoIGVmZmVjdC4KYW5vcm1fbWV0JGNvcmhlYXQKYGBgCgojIyBCYXRjaCBub3JtYWxpemUgYW50aW1vbmlhbCBob3N0IHNhbXBsZXMKClRoZSBiYXRjaCBlZmZlY3QgaXMgcHJldHR5IHNldmVyZSwgd2hhdCBoYXBwZW5zIGlmIHdlIHRyeSBjb21iYXQgb24gaXQ/CgpgYGB7ciBiYXRjaF9jb3JyZWN0fQphYmF0Y2hfY29tYmF0IDwtIG5vcm1hbGl6ZV9leHB0KGFudCwgZmlsdGVyPVRSVUUsIG5vcm09InF1YW50IiwgYmF0Y2g9ImNvbWJhdCIpCmFiYXRjaF9zY2FsZSA8LSBub3JtYWxpemVfZXhwdChhbnQsIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIsIGJhdGNoPSJjb21iYXRfc2NhbGUiKQphYmF0Y2hfcGNhIDwtIHBsb3RfcGNhKGFiYXRjaF9zY2FsZSkKYWJhdGNoX3BjYSRwbG90CiMjIFdvdywgdGhhdCBpcyBlbmNvdXJhZ2luZwp3cml0ZS5jc3YoZmlsZT0iZXhjZWwvYW50aW1vbmlhbF9wY2FfYmF0Y2hfdGFibGUuY3N2IiwgYWJhdGNoX3BjYSR0YWJsZSkKYGBgCgpgYGB7ciBncmFwaF9iYXRjaGVkLCBmaWcuc2hvdz0iaGlkZSJ9CmFiYXRjaF9tZXQgPC0gZ3JhcGhfbWV0cmljcyhhYmF0Y2hfc2NhbGUpCmBgYAoKVGhlIFBDQSBwbG90IG9mIHRoZSBjb21iYXQgYWRqdXN0ZWQgZGF0YSBzdWdnZXN0cyB0aGF0IGl0IG1pZ2h0IGFjdHVhbGx5IHdvcmsgb3V0IG9rLgpMZXQgdXMgbG9vayBhdCB0aGUgb3RoZXIgbWV0cmljcy4KCmBgYHtyIHZpc19iYXRjaH0KYWJhdGNoX21ldCRkZW5zaXR5CiMjIFRoZSBxdWFudGlsZSBub3JtYWxpemF0aW9uIHNtYXNoZWQgdGhlIGRpZmZlcmVuY2VzIGluIGRpc3RyaWJ1dGlvbgphYmF0Y2hfbWV0JGNvcmhlYXQKYWJhdGNoX21ldCRzbWMKYGBgCgojIERpZmZlcmVudGlhbCBFeHByZXNzaW9uIG9mIGFudGltb25pYWwgaG9zdCBzYW1wbGVzCgpgYGB7ciBhbnRpbW9uaWFsaG9zdF9kZX0KYW50aV9ob3N0X2NvbWJhdF9kZSA8LSBzbShhbGxfcGFpcndpc2UoYWJhdGNoX3NjYWxlLCBmb3JjZT1UUlVFLCBtb2RlbF9iYXRjaD1GQUxTRSkpCmFudGlfaG9zdF9jb21iYXRfZGUkY29tcGFyaXNvbiRoZWF0CmxpbW1hX3RhYmxlIDwtIGFudGlfaG9zdF9jb21iYXRfZGUkbGltbWEkYWxsX3RhYmxlcyRyZXNwb25kX2luZl92c19mYWlsX2luZgpkZV9wbG90cyA8LSBleHRyYWN0X2RlX3Bsb3RzKGFudGlfaG9zdF9jb21iYXRfZGUsIHRhYmxlPSJyZXNwb25kX2luZl92c19mYWlsX2luZiIpCmRlX3Bsb3RzJG1hJHBsb3QKYGBgCgpgYGB7ciBhbnRpbW9ueV9ob3N0c190YWJsZXMsIGZpZy5zaG93PSJoaWRlIn0KYW50aW1vbnlfY29udHJhc3RzIDwtIGxpc3QoCiAgICAiZmFpbF9yZXNwb25kX2luZiIgPSBjKCJmYWlsX2luZiIsICJyZXNwb25kX2luZiIpLAogICAgImZhaWxfcmVzcG9uZF9uaWwiID0gYygiZmFpbF9uaWwiLCAicmVzcG9uZF9uaWwiKSwKICAgICJmYWlsIiA9IGMoImZhaWxfaW5mIiwgImZhaWxfbmlsIiksCiAgICAicmVzcG9uZCIgPSBjKCJyZXNwb25kX2luZiIsICJyZXNwb25kX25pbCIpKQphbnRpbW9ueV90YWJsZXMgPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgYW50aV9ob3N0X2NvbWJhdF9kZSwKICBleGNlbD1nbHVlOjpnbHVlKCJleGNlbC9hbnRpbW9ueV9jb21iYXRfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAga2VlcGVycz1hbnRpbW9ueV9jb250cmFzdHMsIGFubm90X2RmPWhzX2Fubm90YXRpb25zKSkKIyNhbnRpbW9ueV90YWJsZXMkcGxvdHNbWyJmYWlsIl1dCmFudGltb255X3NpZ190YWJsZXMgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBhbnRpbW9ueV90YWJsZXMsCiAgZXhjZWw9Z2x1ZTo6Z2x1ZSgiZXhjZWwvYW50aW1vbnlfc2lnbmlmaWNhbnRfZ2VuZXMtdnt2ZXJ9Lnhsc3giKSwKICBhY2NvcmRpbmdfdG89ImFsbCIpKQoKYW50aV9ob3N0X3N2YSA8LSBzbShhbGxfcGFpcndpc2UoYW50LCBtb2RlbF9iYXRjaD0ic3Zhc2VxIiwgZmlsdGVyPVRSVUUpKQphbnRpX2hvc3RfdGFibGVzIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKAogIGFudGlfaG9zdF9zdmEsCiAgZXhjZWw9Z2x1ZTo6Z2x1ZSgiZXhjZWwvYW50aW1vbnlfc3ZhX3RhYmxlcy12e3Zlcn0ueGxzeCIpLAogIGtlZXBlcnM9YW50aW1vbnlfY29udHJhc3RzKSkKYW50aV9ob3N0X3Bsb3RzIDwtIGV4dHJhY3RfZGVfcGxvdHMoYW50aV9ob3N0X3RhYmxlcywgdGFibGU9ImZhaWwiLCB0eXBlPSJkZXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPTIwKQoKYW50aV9jb21wYXJpc29uIDwtIGNvbXBhcmVfZGVfcmVzdWx0cyhhbnRpbW9ueV90YWJsZXMsIGFudGlfaG9zdF90YWJsZXMpCmFudGlfY29tcGFyaXNvbiRsb2dmYwpgYGAKCiMgUmVwZWF0IHVzaW5nIHRoZSBwYXJhc2l0ZSBkYXRhCgpgYGB7ciBhbnRpbW9uaWFsX3BhcmFzaXRlfQojIyBSZXJlYWQgdGhlIHBhcmFzaXRlIHNhbXBsZSBzaGVldCB0byBwbGF5IHdpdGggb3RoZXIgY292YXJpYW50cwojIyBXb3csIGZyb20gdGhlIHBhcmFzaXRlIHBlcnNwZWN0aXZlLCBpdCBzZWVtcyB0aGV5IGNsdXN0ZXIgbXVjaCBtb3JlIHRpZ2h0bHkgYnkgc3RyYWluCnBhcmFzaXRlX2V4cHQgPC0gc20oY3JlYXRlX2V4cHQoCiAgInNhbXBsZV9zaGVldHMvb2xkL2FsbF9zYW1wbGVzLWxwYW5hbWVuc2lzLnhsc3giLAogIGdlbmVfaW5mbz1scF9hbm5vdGF0aW9ucykpCmFudGlwYXJhX2V4cHQgPC0gc3Vic2V0X2V4cHQocGFyYXNpdGVfZXhwdCwgc3Vic2V0PSJjb25kaXRpb249PSdhbnRfZ29vZCd8Y29uZGl0aW9uPT0nYW50X2JhZCciKQphbnRpcGFyYV9leHB0IDwtIHNldF9leHB0X2JhdGNoZXMoYW50aXBhcmFfZXhwdCwgZmFjdD0ic3RyYWluIikKYW50aXBhcmFfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKGFudGlwYXJhX2V4cHQpKQphbnRpcGFyYV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGFudGlwYXJhX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgZmlsdGVyPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybT0icXVhbnQiKQpwbG90X3BjYShhbnRpcGFyYV9ub3JtKSRwbG90CgphbnRpcGFyYV9zdmEgPC0gbm9ybWFsaXplX2V4cHQoYW50aXBhcmFfZXhwdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9InNpbXBsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0ic3Zhc2VxIikKcGxvdF9wY2EoYW50aXBhcmFfc3ZhKSRwbG90CmBgYAoKCiMjIyBBbHNvIHRyeSBhbnRpbW9uaWFscwoKCmBgYHtyIGFudGltb255X2lzX25hc3R5LCBldmFsPUZBTFNFfQpodW1hbl9leHB0IDwtIGNyZWF0ZV9leHB0KGZpbGU9ImFsbF9zYW1wbGVzLWhzYXBpZW5zLnhsc3giKQphbnRpbW9uaWFsX2V4cHQgPC0gZXhwdF9zdWJzZXQoaHVtYW5fZXhwdCwgc3Vic2V0PSJjb25kaXRpb249PSdyZXNwb25kX25pbCd8Y29uZGl0aW9uPT0ncmVzcG9uZF9pbmYnfGNvbmRpdGlvbj09J2ZhaWxfbmlsJ3xjb25kaXRpb249PSdmYWlsX2luZiciKQphbnRpbW9uaWFsX2V4cHQkY29sb3JzIDwtIGMoImJsdWUiLCJibHVlIiwicmVkIiwicmVkIiwiYmxhY2siLCJibGFjayIsImdyZWVuIiwiZ3JlZW4iLCJyZWQiLCJncmVlbiIsImJsdWUiLCJibGFjayIpCmFudGltb25pYWxfbWV0cmljcyA8LSBncmFwaF9tZXRyaWNzKGFudGltb25pYWxfZXhwdCkKYW50aW1vbmlhbF9tZXRyaWNzJGxpYnNpemUKYW50aW1vbmlhbF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGFudGltb25pYWxfZXhwdCwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwgZmlsdGVyX2xvdz1UUlVFLCBub3JtPSJxdWFudCIpCmFudGltb25pYWxub3JtX21ldHJpY3MgPC0gZ3JhcGhfbWV0cmljcyhhbnRpbW9uaWFsX25vcm0pCmFudGltb25pYWxub3JtX21ldHJpY3MkcGNhcGxvdAphbnRpbW9uaWFsbm9ybV9tZXRyaWNzJGNvcmhlYXQKYW50aW1vbmlhbG5vcm1fbWV0cmljcyRkaXNoZWF0CmFudGltb25pYWxfbmIgPC0gbm9ybWFsaXplX2V4cHQoYW50aW1vbmlhbF9leHB0LCB0cmFuc2Zvcm09ImxvZzIiLCBjb252ZXJ0PSJjcG0iLCBmaWx0ZXJfbG93PVRSVUUsIG5vcm09InF1YW50IiwgYmF0Y2g9ImNvbWJhdCIpCmFudGltb25pYWxuYl9tZXRyaWNzIDwtIGdyYXBoX21ldHJpY3MoYW50aW1vbmlhbF9uYikKYW50aW1vbmlhbG5iX21ldHJpY3MkcGNhcGxvdApwcCgiaW1hZ2VzL2FudGltb25pYWxfYmF0Y2hfY29yaGVhdC5wbmciKQphbnRpbW9uaWFsbmJfbWV0cmljcyRjb3JoZWF0CmRldi5vZmYoKQoKIyMgUmVyZWFkIHRoZSBwYXJhc2l0ZSBzYW1wbGUgc2hlZXQgdG8gcGxheSB3aXRoIG90aGVyIGNvdmFyaWFudHMKIyMgV293LCBmcm9tIHRoZSBwYXJhc2l0ZSBwZXJzcGVjdGl2ZSwgaXQgc2VlbXMgdGhleSBjbHVzdGVyIG11Y2ggbW9yZSB0aWdodGx5IGJ5IHN0cmFpbgpwYXJhc2l0ZV9leHB0IDwtIGNyZWF0ZV9leHB0KGZpbGU9ImFsbF9zYW1wbGVzLWxwYW5hbWVuc2lzX3BhdGllbnRiYXRjaC54bHN4IikKYW50aXBhcmFfZXhwdCA8LSAgZXhwdF9zdWJzZXQocGFyYXNpdGVfZXhwdCwgc3Vic2V0PSJjb25kaXRpb249PSdhbnRfZ29vZCd8Y29uZGl0aW9uPT0nYW50X2JhZCciKQphbnRpcGFyYV9tZXRyaWNzIDwtIGdyYXBoX21ldHJpY3MoYW50aXBhcmFfZXhwdCkKYW50aXBhcmFfbWV0cmljcyRwY2FwbG90CmFudGlwYXJhX25vcm0gPC0gbm9ybWFsaXplX2V4cHQoYW50aXBhcmFfZXhwdCwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwgZmlsdGVyX2xvdz1UUlVFLCBub3JtPSJxdWFudCIsIGJhdGNoPSJjb21iYXQiKQphbnRpcGFyYW5vcm1fbWV0cmljcyA8LSBncmFwaF9tZXRyaWNzKGFudGlwYXJhX25vcm0pCmFudGlwYXJhbm9ybV9tZXRyaWNzJHBjYXBsb3QKYW50aXBhcmFub3JtX21ldHJpY3MkY29yaGVhdApgYGAKCmBgYHtyIGJldHRlcl9oZWF0bWFwc30KbGlicmFyeShCaW9iYXNlKQpsaWJyYXJ5KEhlYXRwbHVzKQppbmZlY3Rpb25fbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChwYXJhc2l0ZV9leHB0LCB0cmFuc2Zvcm09InJhdyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIGZpbHRlcj0icG9mYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgYmF0Y2g9InN2YSIpKQppbmZlY3RfZGF0YSA8LSBleHBycyhpbmZlY3Rpb25fbm9ybSRleHByZXNzaW9uc2V0KQpjb3JyZWxhdGlvbnMgPC0gaHBnbF9jb3IoaW5mZWN0X2RhdGEpCmRpc3RhbmNlcyA8LSBhcy5tYXRyaXgoZGlzdCh0KGluZmVjdF9kYXRhKSwgbWV0aG9kPSJtaW5rIikpCgpkZXNpZ24gPC0gYXMuZGF0YS5mcmFtZShpbmZlY3Rpb25fbm9ybSRkZXNpZ24pCnJvd25hbWVzKGNvcnJlbGF0aW9ucykgPC0gcGFzdGUwKHJvd25hbWVzKGNvcnJlbGF0aW9ucyksICJfIiwgYXMuY2hhcmFjdGVyKGRlc2lnbiRjb25kaXRpb24pKQpjb2xuYW1lcyhjb3JyZWxhdGlvbnMpIDwtIHBhc3RlMChjb2xuYW1lcyhjb3JyZWxhdGlvbnMpLCAiXyIsIGFzLmNoYXJhY3RlcihkZXNpZ24kYmF0Y2gpKQoKY29sX2RhdGEgPC0gYXMuZGF0YS5mcmFtZShwRGF0YShpbmZlY3Rpb25fbm9ybSlbLCBjKCJzdHJhaW4iLCAiY29uZGl0aW9uIildKQpyb3dfZGF0YSA8LSBkZXNpZ25bLCBjKCJiYXRjaCIsImNvbmRpdGlvbiIpXQpjb2xuYW1lcyhjb2xfZGF0YSkgPC0gYygic3RyYWluIiwgInNlbGZoZWFsIikKY29sbmFtZXMocm93X2RhdGEpIDwtIGMoInZvbHVudGVlciIsInNlbGZoZWFsIikKcm93X2RhdGEkc2VsZmhlYWwgPC0gYXMubnVtZXJpYyhyb3dfZGF0YSRzZWxmaGVhbCkKcm93X2RhdGEkc2VsZmhlYWwgPC0gaWZlbHNlKHJvd19kYXRhJHNlbGZoZWFsID09IDIsIFRSVUUsIEZBTFNFKQpteWFubm90IDwtIGxpc3QoQ29sPWxpc3QoZGF0YT1jb2xfZGF0YSksIFJvdz1saXN0KGRhdGE9cm93X2RhdGEpKQpteWxhYmVscyA8LSBsaXN0KFJvdz1saXN0KG5yb3c9MTApLCBDb2w9bGlzdChucm93PTEwKSkKCm1hcDEgPC0gYW5uSGVhdG1hcDIoZGlzdGFuY2VzLAogICAgICAgICAgICAgICAgICAgIGNsdXN0ZXI9bGlzdChjdXRoPTcwMDApLAogICAgICAgICAgICAgICAgICAgIGFubj1teWFubm90LAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1teWxhYmVscykKIyMgMyBudW1iZXJzLCBkZW5kcm9ncmFtLCBwbG90LCBhbm5vdGF0aW9uIHdpZHRoL2hlaWdodApwbG90KG1hcDEpCmBgYAoKIyBTYXZlIHRoZSByZXN1bHRzLgoKYGBge3Igc2F2ZW1lfQptZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKbWVzc2FnZShwYXN0ZTAoIlNhdmluZyB0byAiLCB0aGlzX3NhdmUpKQojI3RtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWU9dGhpc19zYXZlKSkKcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKYGBgCgpgYGB7ciBsb2FkbWUsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CnRtcCA8LSBzbShsb2FkbWUoZmlsZW5hbWU9dGhpc19zYXZlKSkKIyMgbG9hZCgidmFyaWFudHNfdmVubi5yZGEiKQpgYGAK