These documents are a series of Leishmania panamensis RNASeq analyses.

This data is in fact in 4 sub-experiments. Lets address them one at a time.

1 TODO

1.1 2017-08-24

  1. Define analyses.
  2. Set up supplementals.
    1. Same panels as per Santuza’s paper:
    • Coverage
    • Boxplot
    • correlation
    • PCA
    • distance
    • SMC

1.2 2017-07-27

  1. Find overlaps between the three patients and the groups of ch/un + sh/un

1.3 2016-11-29

  • Do the following:
    1. Limma with batch in model, report # genes fc>0, p<=0.05; fc<0, p<=0.05; fc>1.5, p<=0.05; fc<-1.5, p<=0.05
    2. Limma with combat, report # genes fc>0, p<=0.05; fc<0, p<=0.05, etc.
    3. Limma without b, report same
    4. Limma without b+sva, report same
  • Take the 4 results and compare them:
    1. Correlate various fold changes
    2. Find # genes of 1 in 2, 1 in 3, 1 in 4, 2 in 3, 2 in 4, 3 in 4.

1.4 2016-11-03

Do in lexical order, send the first 4 by email asap.

  • For macrophage, remove batch b and re-perform metrics.
  • For macrophage, look at pca information after adjustment with combat.
  • Compare de lists with and without batch b (using combat for batch b containing work)
  • PBMC: variance partition human, “Are there any genes with variance we can ascribe to condition?” That set of genes is the most interesting. – use the variance parition table and pull the top 200. Report back the % variance by condition for all of these genes.

  • Simplify snp plot for keith.
  • Make separate snp plot of only macrophage and only infection.

1.5 2016-09-23

  1. Add to existing vcfutils pipeline a check that all samples have sufficient coverage. Rsamtools, calculate coverage on all positions stored as gRanges[]. Cross reference these against each snp position and percentage.
    1. For each existing snp position, make a data structure including the coverage and percentage for all samples
    2. Given this data structure, keep only those rows with sufficient coverage across all samples. (If any sample has < n reads at position x && at no one sample has it > 0.95 then remove the row)
    3. The remaining positions should all have 0<=x<=1 percentage. Use them for the following analyses.
  2. Subset the full data set into a separate plot for each experiment. Plot these heatmaps accordingly.
    1. If there are interesting clades within these subsets, reuse them for variancePartition/models.
  3. Assuming the same result applies, use PCA or something to query self/chronic for all samples and see if the funny blue clade is split or not.

1.6 2016-09-15

  1. (2)Re-perform vcfutils pipeline and have it include in its summary a number of coverage, then when merging keep only those positions which have coverage > x for all samples. (done except I didn’t do coverage > x for all samples properly, but the results I think make it a moot point)
  2. Perform with a set of monocladous samples
  3. (4)Perform an explicit set of mappings of only the non-human reads and collect mapping stats for keith ;p
  4. (1)Make 100+% certain that all violin plots are on human data (I think this is true now, done by performing plots of both for all).
  5. (3)Conversely/simultaneously, query the snp profiles (focus on hpgl0635) to seek snps which define: (Goal is to find positions driving the clustering observed)
  6. Make a heatmap of snps in the columns and strains in rows and use the % to score. How to choose n out of 92k snps
  1. For each snp, use snp3 clade as outcome and perform an f-test for each snp and extract the highest n f-statistic snps, then plot the heatmap at i.
  2. Compare clustering of gene expression vs. SNP genotype.
  3. Measure variance explained by SNP vs. variance explained by strain by doing varPartition of:
  4. donor + strain
  5. donor + snp(3/4/5) and snpclade
  6. Assuming this works out, fit a model without strain, but instead snp.

1.7 Misc

  1. VCF tools in bioconductor (I am inclined to suggest that these tools sort of suck)
  2. Exclude <0.9 percentages from: (done – there is no significant difference between the two, the correlations/distances are nearly identical.) DO ME FIRST: newb.
  3. Step1: Perform varpart and see that variance by snp > variance by strain
  4. Perform this on the human data and not parasite
  1. Perform this for both snp3 and snp5 clades
  2. Make sure to plot donor+strain+healing and donor+snp+healing for snp3/snp5
  3. Assuming snp3 is appropriate, fit a model of y=donor+snp3+healing
  1. Assuming it functions properly, we have a set of genes with differential expression taking into account both donor and clustering.
  1. Bioconductor package ‘variancePartition’
  1. (1|factor) are random effects ergo; model <- as.formula(“~ (1|donor) + (1|strain) + (1|batch)”)
  2. Make violin plot of this result, plot residuals vs. healing,
  3. Repeat above with introduced + (1|healing)
  1. Copy chr/sh pca plot down to the relabel one sample section to make it easier to follow
  2. Figure out a way to automatically compare every sample against the SNP profiles generated for all strains.
  1. Record a set of canonical snps for each strain
  2. For each sample, use something like bam_whateveritwas to extract those regions
  3. For each snp profile, count the identities/differences for every snp position and heatmap them?
  4. Then if they match it should come up the terminal color I think
  1. Try the same PCA plots with just dropping hpgl0635
  2. Print full set of plots for the parasite samples before getting into the PCA.

1.8 Macrophage tasks

  1. Re-perform DE analyses with no-sva/ruv but condition+batch (done)
  2. Collect IGV images for strains ch/sh (done)
  3. For SVs, plot SV vs. technical variables: %rna, snps (done)
  4. Take the % of reads mapped to parasite and add it as an experimental parameter (done)
  5. Extend SV analysis to include condition + batch (not done)
  6. For the SV methods, plot log2 genes vs. log2fc (?)
  7. Run RUV/SVA condition + nobatch (done)
  1. Take SVs and add to the model
  2. Perform DE
  3. Plot MA, correlate log2FCs across analyses
  1. Provide a PCA plot of our final decision for this data and provide a table of coordinates
  2. Provide DE lists with condition+batch in the model vs. combat adjusted and do comparison
  3. Provide some ontology/KEGG results

1.9 Infection tasks

  1. Add ‘coordinates’ for all the PCA plots for Maria Adelaida to pick up. done by adding them to all PCA plots
  2. Send along some PCA coordinates (from the email:) done
  1. The coordinates of the PCA of PBMCs without batch correction – showing the strong batch effect by patient Ibid #0
  2. The coordinates of the PCAs of PBMCs after batch correction Ibid #0
  1. Amend PCA coordinates: first without uninfected, then with
  1. without batch, patient, strain Ibid #0 – actually did I do them all, I think so
  1. Will we call the 6 isolates be called ‘strains’, ‘isolates’, ‘cultures’?
  1. The reason for this question is that they do not necessarily follow well defined rules vis a vis the similarity to the characterized genome.
  1. Make sure the actual experimental batch comparison is maintained I believe this is correct
  2. Make sure that it is clear the difference between ‘experimental batch effect’ and ‘donor effect’ I think this is clear, I have a specific call before each comparison now, is there a best way to ensure this?
  3. Report correlation between factors and components. Done for the case of samples without uninfected
  4. Fit linear model after removing each factor and observe variance remaining to directly assess %var in each factor. ‘Most elegant method is the mixed effect model’
  5. Terms agreed to:
    1. “donor”: (patient) bob jane alice
    2. “isolate”: (strain) 2171 2172 etc
    3. “status”: (self healing, chronic, uninfected)
    4. “batch”: (a b) The two library/RNA isolation dates
    5. “snp”: (x y z) Clade top (few), clade middle (some), clade bottom (many)
  6. Make a model of ~ 0 + isolate + donor + batch (maybe not batch) Fit to the data, take residuals, make PCA of the residuals, color by sh/ch
  7. Compare parasite data clustering to see if some other surrogate factor to make some sense of this a) Goal: attempt to identify the cluster of strains which has peculiar human expression.
  8. See what happens if I relabel 635 as strain ch2504 Done for some values of ‘done’ I am not certain of the result
  9. Learn best method

2 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("elsayedlab/hpgltools")
## Load hpgltools into the R environment.
library(hpgltools)
## Use hpgltools' autoloads_all() function to install the many packages used by hpgltools.
autoloads_all()

This document is rather short. In some others I did the preprocessing, shared, etc steps as ‘child’ documents of this and they would be appended here. In this case I did not.

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 index-v20171110.rda.xz
LS0tCnRpdGxlOiAiTC5wYW5hbWVuc2lzIDIwMTY6IFJOQXNlcSBvZiBMLnBhbmFtZW5zaXMgaW4gaHVtYW4gbWFjcm9waGFnZXMsIGR1cmluZyBpbmZlY3Rpb24sIGluIGJpb3BzaWVzLCBhbmQgd2l0aCBhbnRpbW9uaWFsIHRyZWF0bWVudC4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogZGVmYXVsdAogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IHJlYWRhYmxlCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICAgY29sbGFwc2VkOiBmYWxzZQogICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7CiAgfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgbGlicmFyeShocGdsdG9vbHMpCiAgdHQgPC0gZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpCiAga25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9OTAsCiAgICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQogIGtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGg9OCwKICAgICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LAogICAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCiAgb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHM9NCwKICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKICBnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKICB2ZXIgPC0gIjIwMTcxMTEwIgogIHByZXZpb3VzX2ZpbGUgPC0gImluZGV4LlJtZCIKCiAgdG1wIDwtIHRyeShzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkpCiAgcm1kX2ZpbGUgPC0gImluZGV4LlJtZCIKfQpgYGAKClRoZXNlIGRvY3VtZW50cyBhcmUgYSBzZXJpZXMgb2YgTGVpc2htYW5pYSBwYW5hbWVuc2lzIFJOQVNlcSBhbmFseXNlcy4KClRoaXMgZGF0YSBpcyBpbiBmYWN0IGluIDQgc3ViLWV4cGVyaW1lbnRzLiAgTGV0cyBhZGRyZXNzIHRoZW0gb25lIGF0IGEgdGltZS4KCiogW1ByZXByb2Nlc3NpbmddKHByZXByb2Nlc3NpbmcuaHRtbCkgIFRoZSBzdGVwcyBwZXJmb3JtZWQgdG8gcHJlcHJvY2VzcyB0aGUgZGF0YS4KKiBbQW5ub3RhdGlvbl0oYW5ub3RhdGlvbi5odG1sKSAgRGF0YSBzaGFyZWQgYnkgYWxsIGV4cGVyaW1lbnRzIChhbm5vdGF0aW9ucywgZ2Vub21lcywgZXRjKS4KKiBbU25wIGNsdXN0ZXJpbmddKHNucF9jbHVzdGVyLmh0bWwpICBDbHVzdGVyIHNhbXBsZXMgYnkgc25wIHBlcmNlbnRhZ2VzLgoqIE1hY3JvcGhhZ2UgQW5hbHlzZXM6ICBSZXNwb25zZXMgb2YgbWFjcm9waGFnZXMgZnJvbSAxIGRvbm9yIGFuZCAzIHN0cmFpbnMuCiAgICAqIFtNYWNyb3BoYWdlIFNhbXBsZSBFc3RpbWF0aW9uOiBIdW1hbl0obWFjcm9waGFnZV9lc3RpbWF0aW9uX2h1bWFuLmh0bWwpICBNYWNyb3BoYWdlIHJlc3BvbnNlczogaHBnbDAyNDEtMDI0OAogICAgICBhbmQgaHBnbDA2MzYtMDYzOS4KICAgICogW01hY3JvcGhhZ2UgU2FtcGxlIEVzdGltYXRpb246IFBhcmFzaXRlXShtYWNyb3BoYWdlX2VzdGltYXRpb25fcGFyYXNpdGUuaHRtbCkgIEliaWQgZXhjZXB0IHRoZSBwYXJhc2l0ZSBtYXBwaW5ncy4KICAgICogW01hY3JvcGhhZ2UgRGlmZmVyZW50aWFsIEV4cHJlc3Npb246IEh1bWFuXShtYWNyb3BoYWdlX2V4cHJlc3Npb25faHVtYW4uaHRtbCkgIE1hY3JvcGhhZ2UgcmVzcG9uc2VzOiBodW1hbgogICAgKiBbTWFjcm9waGFnZSBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbjogUGFyYXNpdGVdKG1hY3JvcGhhZ2VfZXhwcmVzc2lvbl9wYXJhc2l0ZS5odG1sKSAgTWFjcm9waGFnZSByZXNwb25zZXM6IHBhcmFzaXRlCiAgICAqIFtNYWNyb3BoYWdlIEdlbmUgT250b2xvZ3k6IEh1bWFuXShtYWNyb3BoYWdlX29udG9sb2d5X2h1bWFuLmh0bWwpICBHZW5lIG9udG9sb2d5IHNlYXJjaGVzOiBodW1hbgogICAgKiBbTWFjcm9waGFnZSBHZW5lIE9udG9sb2d5OiBQYXJhc2l0ZV0obWFjcm9waGFnZV9vbnRvbG9neV9wYXJhc2l0ZS5odG1sKSAgR2VuZSBvbnRvbG9neSBzZWFyY2hlczogcGFyYXNpdGUKKiBJbmZlY3Rpb24gQW5hbHlzZXM6ICBSZXNwb25zZXMgb2YgUEJNQyBjZWxscyB0byBzdHJhaW5zIGlkZW50aWZpZWQgYXMgJ3NlbGYtaGVhbGluZycgYW5kICdjaHJvbmljJy4KICAgICogW0luZmVjdGlvbiBTYW1wbGUgRXN0aW1hdGlvbjogSHVtYW5dKGluZmVjdGlvbl9lc3RpbWF0aW9uX2h1bWFuLmh0bWwpICBJbmZlY3Rpb24gcmVzcG9uc2VzOiBocGdsMDI0MS0wMjQ4CiAgICAgIGFuZCBocGdsMDYzNi0wNjM5LgogICAgKiBbSW5mZWN0aW9uIFNhbXBsZSBFc3RpbWF0aW9uOiBQYXJhc2l0ZV0oaW5mZWN0aW9uX2VzdGltYXRpb25fcGFyYXNpdGUuaHRtbCkgIEliaWQgZXhjZXB0IHRoZSBwYXJhc2l0ZSBtYXBwaW5ncy4KICAgICogW0luZmVjdGlvbiBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbjogSHVtYW5dKGluZmVjdGlvbl9leHByZXNzaW9uX2h1bWFuLmh0bWwpICBJbmZlY3Rpb24gcmVzcG9uc2VzOiBodW1hbgogICAgKiBbSW5mZWN0aW9uIERpZmZlcmVudGlhbCBFeHByZXNzaW9uOiBQYXJhc2l0ZV0oaW5mZWN0aW9uX2V4cHJlc3Npb25fcGFyYXNpdGUuaHRtbCkgIEluZmVjdGlvbiByZXNwb25zZXM6IHBhcmFzaXRlCiAgICAqIFtJbmZlY3Rpb24gR2VuZSBPbnRvbG9neTogSHVtYW5dKGluZmVjdGlvbl9vbnRvbG9neV9odW1hbi5odG1sKSAgR2VuZSBvbnRvbG9neSBzZWFyY2hlczogaHVtYW4KICAgICogW0luZmVjdGlvbiBHZW5lIE9udG9sb2d5OiBQYXJhc2l0ZV0oaW5mZWN0aW9uX29udG9sb2d5X3BhcmFzaXRlLmh0bWwpICBHZW5lIG9udG9sb2d5IHNlYXJjaGVzOiBwYXJhc2l0ZQoqICBCaW9wc3kgQW5hbHlzZXM6ICBQQk1DIHNhbXBsZXMgcHJlIGFuZCBwb3N0LWJpb3BzeS4KICAgICogW0Jpb3BzeSBTYW1wbGUgRXN0aW1hdGlvbjogSHVtYW5dKGJpb3BzeV9lc3RpbWF0aW9uX2h1bWFuLmh0bWwpICBCaW9wc3kgcmVzcG9uc2VzOiBocGdsMDI0MS0wMjQ4CiAgICBhbmQgaHBnbDA2MzYtMDYzOS4KICAgICogW0Jpb3BzeSBTYW1wbGUgRXN0aW1hdGlvbjogUGFyYXNpdGVdKGJpb3BzeV9lc3RpbWF0aW9uX3BhcmFzaXRlLmh0bWwpICBJYmlkIGV4Y2VwdCB0aGUgcGFyYXNpdGUgbWFwcGluZ3MuCiAgICAqIFtCaW9wc3kgRGlmZmVyZW50aWFsIEV4cHJlc3Npb246IEh1bWFuXShiaW9wc3lfZXhwcmVzc2lvbl9odW1hbi5odG1sKSAgQmlvcHN5IHJlc3BvbnNlczogaHVtYW4KICAgICogW0Jpb3BzeSBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbjogUGFyYXNpdGVdKGJpb3BzeV9leHByZXNzaW9uX3BhcmFzaXRlLmh0bWwpICBCaW9wc3kgcmVzcG9uc2VzOiBwYXJhc2l0ZQogICAgKiBbQmlvcHN5IEdlbmUgT250b2xvZ3k6IEh1bWFuXShiaW9wc3lfb250b2xvZ3lfaHVtYW4uaHRtbCkgIEdlbmUgb250b2xvZ3kgc2VhcmNoZXM6IGh1bWFuCiAgICAqIFtCaW9wc3kgR2VuZSBPbnRvbG9neTogUGFyYXNpdGVdKGJpb3BzeV9vbnRvbG9neV9wYXJhc2l0ZS5odG1sKSAgR2VuZSBvbnRvbG9neSBzZWFyY2hlczogcGFyYXNpdGUKKiAgQW50aW1vbmlhbCBUcmVhdG1lbnRzOiAgQSBzZWFyY2ggZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gcmVzcG9uc2l2ZSBhbmQgdW5yZXNwb25zaXZlIHNhbXBsZXMKICAgICogW0FudGltb25pYWwgU2FtcGxlIEVzdGltYXRpb246IEh1bWFuXShhbnRpbW9uaWFsX2VzdGltYXRpb25faHVtYW4uaHRtbCkgIEFudGltb25pYWwgcmVzcG9uc2VzOiBocGdsMDI0MS0wMjQ4CiAgICBhbmQgaHBnbDA2MzYtMDYzOS4KICAgICogW0FudGltb25pYWwgU2FtcGxlIEVzdGltYXRpb246IFBhcmFzaXRlXShhbnRpbW9uaWFsX2VzdGltYXRpb25fcGFyYXNpdGUuaHRtbCkgIEliaWQgZXhjZXB0IHRoZSBwYXJhc2l0ZSBtYXBwaW5ncy4KICAgICogW0FudGltb25pYWwgRGlmZmVyZW50aWFsIEV4cHJlc3Npb246IEh1bWFuXShhbnRpbW9uaWFsX2V4cHJlc3Npb25faHVtYW4uaHRtbCkgIEFudGltb25pYWwgcmVzcG9uc2VzOiBodW1hbgogICAgKiBbQW50aW1vbmlhbCBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbjogUGFyYXNpdGVdKGFudGltb25pYWxfZXhwcmVzc2lvbl9wYXJhc2l0ZS5odG1sKSAgQW50aW1vbmlhbCByZXNwb25zZXM6IHBhcmFzaXRlCiAgICAqIFtBbnRpbW9uaWFsIEdlbmUgT250b2xvZ3k6IEh1bWFuXShhbnRpbW9uaWFsX29udG9sb2d5X2h1bWFuLmh0bWwpICBHZW5lIG9udG9sb2d5IHNlYXJjaGVzOiBodW1hbgogICAgKiBbQW50aW1vbmlhbCBHZW5lIE9udG9sb2d5OiBQYXJhc2l0ZV0oYW50aW1vbmlhbF9vbnRvbG9neV9wYXJhc2l0ZS5odG1sKSAgR2VuZSBvbnRvbG9neSBzZWFyY2hlczogcGFyYXNpdGUKCiMgVE9ETwoKIyMgMjAxNy0wOC0yNAoKMS4gIERlZmluZSBhbmFseXNlcy4KMi4gIFNldCB1cCBzdXBwbGVtZW50YWxzLgogICAgYS4gIFNhbWUgcGFuZWxzIGFzIHBlciBTYW50dXphJ3MgcGFwZXI6CiAgICAgICogIENvdmVyYWdlCiAgICAgICogIEJveHBsb3QKICAgICAgKiAgY29ycmVsYXRpb24KICAgICAgKiAgUENBCiAgICAgICogIGRpc3RhbmNlCiAgICAgICogIFNNQwoKCgojIyAyMDE3LTA3LTI3CgoxLiAgRmluZCBvdmVybGFwcyBiZXR3ZWVuIHRoZSB0aHJlZSBwYXRpZW50cyBhbmQgdGhlIGdyb3VwcyBvZiBjaC91biArIHNoL3VuCgojIyAyMDE2LTExLTI5CgoqICBEbyB0aGUgZm9sbG93aW5nOgogICAgMS4gIExpbW1hIHdpdGggYmF0Y2ggaW4gbW9kZWwsIHJlcG9ydCAjIGdlbmVzIGZjPjAsIHA8PTAuMDU7ICBmYzwwLCBwPD0wLjA1OyBmYz4xLjUsIHA8PTAuMDU7IGZjPC0xLjUsIHA8PTAuMDUKICAgIDIuICBMaW1tYSB3aXRoIGNvbWJhdCwgcmVwb3J0ICMgZ2VuZXMgZmM+MCwgcDw9MC4wNTsgZmM8MCwgcDw9MC4wNSwgZXRjLgogICAgMy4gIExpbW1hIHdpdGhvdXQgYiwgcmVwb3J0IHNhbWUKICAgIDQuICBMaW1tYSB3aXRob3V0IGIrc3ZhLCByZXBvcnQgc2FtZQoqICBUYWtlIHRoZSA0IHJlc3VsdHMgYW5kIGNvbXBhcmUgdGhlbToKICAgIDEuICBDb3JyZWxhdGUgdmFyaW91cyBmb2xkIGNoYW5nZXMKICAgIDIuICBGaW5kICMgZ2VuZXMgb2YgMSBpbiAyLCAxIGluIDMsIDEgaW4gNCwgMiBpbiAzLCAyIGluIDQsIDMgaW4gNC4KCiMjIDIwMTYtMTEtMDMKCkRvIGluIGxleGljYWwgb3JkZXIsIHNlbmQgdGhlIGZpcnN0IDQgYnkgZW1haWwgYXNhcC4KCiogICAgRm9yIG1hY3JvcGhhZ2UsIHJlbW92ZSBiYXRjaCBiIGFuZCByZS1wZXJmb3JtIG1ldHJpY3MuCiogICAgRm9yIG1hY3JvcGhhZ2UsIGxvb2sgYXQgcGNhIGluZm9ybWF0aW9uIGFmdGVyIGFkanVzdG1lbnQgd2l0aCBjb21iYXQuCiogICAgQ29tcGFyZSBkZSBsaXN0cyB3aXRoIGFuZCB3aXRob3V0IGJhdGNoIGIgKHVzaW5nIGNvbWJhdCBmb3IgYmF0Y2ggYiBjb250YWluaW5nIHdvcmspCiogICAgUEJNQzogdmFyaWFuY2UgcGFydGl0aW9uIGh1bWFuLCAiQXJlIHRoZXJlIGFueSBnZW5lcyB3aXRoIHZhcmlhbmNlIHdlIGNhbiBhc2NyaWJlIHRvIGNvbmRpdGlvbj8iCiAgICBUaGF0IHNldCBvZiBnZW5lcyBpcyB0aGUgbW9zdCBpbnRlcmVzdGluZy4gLS0gdXNlIHRoZSB2YXJpYW5jZSBwYXJpdGlvbiB0YWJsZSBhbmQgcHVsbCB0aGUgdG9wIDIwMC4KICAgIFJlcG9ydCBiYWNrIHRoZSAlIHZhcmlhbmNlIGJ5IGNvbmRpdGlvbiBmb3IgYWxsIG9mIHRoZXNlIGdlbmVzLgoKCiogICAgU2ltcGxpZnkgc25wIHBsb3QgZm9yIGtlaXRoLgoqICAgIE1ha2Ugc2VwYXJhdGUgc25wIHBsb3Qgb2Ygb25seSBtYWNyb3BoYWdlIGFuZCBvbmx5IGluZmVjdGlvbi4KCiMjIDIwMTYtMDktMjMKCjEuICBBZGQgdG8gZXhpc3RpbmcgdmNmdXRpbHMgcGlwZWxpbmUgYSBjaGVjayB0aGF0IF9hbGxfIHNhbXBsZXMgaGF2ZSBzdWZmaWNpZW50IGNvdmVyYWdlLgpSc2FtdG9vbHMsIGNhbGN1bGF0ZSBjb3ZlcmFnZSBvbiBhbGwgcG9zaXRpb25zIHN0b3JlZCBhcyBnUmFuZ2VzW10uICBDcm9zcyByZWZlcmVuY2UgdGhlc2UgYWdhaW5zdAplYWNoIHNucCBwb3NpdGlvbiBhbmQgcGVyY2VudGFnZS4KICAgIGEuICBGb3IgZWFjaCBleGlzdGluZyBzbnAgcG9zaXRpb24sIG1ha2UgYSBkYXRhIHN0cnVjdHVyZSBpbmNsdWRpbmcgdGhlIGNvdmVyYWdlIGFuZCBwZXJjZW50YWdlIGZvciBhbGwgc2FtcGxlcwogICAgYi4gIEdpdmVuIHRoaXMgZGF0YSBzdHJ1Y3R1cmUsIGtlZXAgb25seSB0aG9zZSByb3dzIHdpdGggc3VmZmljaWVudCBjb3ZlcmFnZSBhY3Jvc3MgX2FsbF8KICAgIHNhbXBsZXMuICAoSWYgYW55IHNhbXBsZSBoYXMgPCBuIHJlYWRzIGF0IHBvc2l0aW9uIHggJiYgYXQgbm8gb25lIHNhbXBsZSBoYXMgaXQgPiAwLjk1IHRoZW4KICAgIHJlbW92ZSB0aGUgcm93KQogICAgYy4gIFRoZSByZW1haW5pbmcgcG9zaXRpb25zIHNob3VsZCBhbGwgaGF2ZSAwPD14PD0xIHBlcmNlbnRhZ2UuICBVc2UgdGhlbSBmb3IgdGhlIGZvbGxvd2luZwogICAgYW5hbHlzZXMuCjIuICBTdWJzZXQgdGhlIGZ1bGwgZGF0YSBzZXQgaW50byBhIHNlcGFyYXRlIHBsb3QgZm9yIGVhY2ggZXhwZXJpbWVudC4gIFBsb3QgdGhlc2UgaGVhdG1hcHMKICAgIGFjY29yZGluZ2x5LgogICAgYS4gIElmIHRoZXJlIGFyZSBpbnRlcmVzdGluZyBjbGFkZXMgd2l0aGluIHRoZXNlIHN1YnNldHMsIHJldXNlIHRoZW0gZm9yIHZhcmlhbmNlUGFydGl0aW9uL21vZGVscy4KMy4gIEFzc3VtaW5nIHRoZSBzYW1lIHJlc3VsdCBhcHBsaWVzLCB1c2UgUENBIG9yIHNvbWV0aGluZyB0byBxdWVyeSBzZWxmL2Nocm9uaWMgZm9yIGFsbCBzYW1wbGVzIGFuZAogICAgc2VlIGlmIHRoZSBmdW5ueSBibHVlIGNsYWRlIGlzIHNwbGl0IG9yIG5vdC4KCiMjIDIwMTYtMDktMTUKCmEuICAoMilSZS1wZXJmb3JtIHZjZnV0aWxzIHBpcGVsaW5lIGFuZCBoYXZlIGl0IGluY2x1ZGUgaW4gaXRzIHN1bW1hcnkgYSBudW1iZXIgb2YgY292ZXJhZ2UsICB0aGVuIHdoZW4gbWVyZ2luZyBrZWVwIG9ubHkgdGhvc2UgcG9zaXRpb25zIHdoaWNoIGhhdmUgY292ZXJhZ2UgPiB4IGZvciBfYWxsXyBzYW1wbGVzLiAgKGRvbmUgZXhjZXB0IEkgZGlkbid0IGRvIGNvdmVyYWdlID4geCBmb3IgYWxsIHNhbXBsZXMgcHJvcGVybHksIGJ1dCB0aGUgcmVzdWx0cyBJIHRoaW5rIG1ha2UgaXQgYSBtb290IHBvaW50KQogaS4gUGVyZm9ybSB3aXRoIGEgc2V0IG9mIG1vbm9jbGFkb3VzIHNhbXBsZXMKYi4gICg0KVBlcmZvcm0gYW4gZXhwbGljaXQgc2V0IG9mIG1hcHBpbmdzIG9mIG9ubHkgdGhlIG5vbi1odW1hbiByZWFkcyBhbmQgY29sbGVjdCBtYXBwaW5nIHN0YXRzIGZvciBrZWl0aCA7cAphLiAgKDEpTWFrZSAxMDArJSBjZXJ0YWluIHRoYXQgYWxsIHZpb2xpbiBwbG90cyBhcmUgb24gaHVtYW4gZGF0YSAoSSB0aGluayB0aGlzIGlzIHRydWUgbm93LCBkb25lIGJ5IHBlcmZvcm1pbmcgcGxvdHMgb2YgYm90aCBmb3IgYWxsKS4KYi4gICgzKUNvbnZlcnNlbHkvc2ltdWx0YW5lb3VzbHksIHF1ZXJ5IHRoZSBzbnAgcHJvZmlsZXMgKGZvY3VzIG9uIGhwZ2wwNjM1KSB0bwogICAgc2VlayBzbnBzIHdoaWNoIGRlZmluZTogICAoR29hbCBpcyB0byBmaW5kIHBvc2l0aW9ucyBkcml2aW5nIHRoZSBjbHVzdGVyaW5nIG9ic2VydmVkKQogIGkuICBNYWtlIGEgaGVhdG1hcCBvZiBzbnBzIGluIHRoZSBjb2x1bW5zIGFuZCBzdHJhaW5zIGluIHJvd3MgYW5kIHVzZSB0aGUKICAgICUgdG8gc2NvcmUuICBIb3cgdG8gY2hvb3NlIG4gb3V0IG9mIDkyayBzbnBzCiAgaWkuICBGb3IgZWFjaCBzbnAsIHVzZSBzbnAzIGNsYWRlIGFzIG91dGNvbWUgYW5kIHBlcmZvcm0gYW4gZi10ZXN0IGZvciBlYWNoIHNucCBhbmQgZXh0cmFjdCB0aGUKICAgIGhpZ2hlc3QgbiBmLXN0YXRpc3RpYyBzbnBzLCB0aGVuIHBsb3QgdGhlIGhlYXRtYXAgYXQgaS4KYy4gIENvbXBhcmUgY2x1c3RlcmluZyBvZiBnZW5lIGV4cHJlc3Npb24gdnMuIFNOUCBnZW5vdHlwZS4KZC4gIE1lYXN1cmUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IFNOUCB2cy4gdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IHN0cmFpbiBieSBkb2luZyB2YXJQYXJ0aXRpb24gb2Y6CiAgaS4gICBkb25vciArIHN0cmFpbgogIGlpLiAgZG9ub3IgKyBzbnAoMy80LzUpIGFuZCBzbnBjbGFkZQogIGlpaS4gQXNzdW1pbmcgdGhpcyB3b3JrcyBvdXQsIGZpdCBhIG1vZGVsIHdpdGhvdXQgc3RyYWluLCBidXQgaW5zdGVhZCBzbnAuCgojIyBNaXNjCgphLiAgVkNGIHRvb2xzIGluIGJpb2NvbmR1Y3RvciAoSSBhbSBpbmNsaW5lZCB0byBzdWdnZXN0IHRoYXQgdGhlc2UgdG9vbHMgc29ydCBvZiBzdWNrKQpiLiAgRXhjbHVkZSA8MC45IHBlcmNlbnRhZ2VzIGZyb206ICAoZG9uZSAtLSB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3bywgdGhlIGNvcnJlbGF0aW9ucy9kaXN0YW5jZXMgYXJlIG5lYXJseSBpZGVudGljYWwuKQpETyBNRSBGSVJTVDogbmV3Yi4KYy4gIFN0ZXAxOiAgUGVyZm9ybSB2YXJwYXJ0IGFuZCBzZWUgdGhhdCB2YXJpYW5jZSBieSBzbnAgPiB2YXJpYW5jZSBieSBzdHJhaW4KICAgaS4gIFBlcmZvcm0gdGhpcyBvbiB0aGUgaHVtYW4gZGF0YSBhbmQgbm90IHBhcmFzaXRlCiAgIGlpLiAgUGVyZm9ybSB0aGlzIGZvciBib3RoIHNucDMgYW5kIHNucDUgY2xhZGVzCiAgIGlpaS4gTWFrZSBzdXJlIHRvIHBsb3QgZG9ub3Irc3RyYWluK2hlYWxpbmcgYW5kIGRvbm9yK3NucCtoZWFsaW5nIGZvciBzbnAzL3NucDUKZC4gIEFzc3VtaW5nIHNucDMgaXMgYXBwcm9wcmlhdGUsIGZpdCBhIG1vZGVsIG9mIHk9ZG9ub3Irc25wMytoZWFsaW5nCmUuICBBc3N1bWluZyBpdCBmdW5jdGlvbnMgcHJvcGVybHksIHdlIGhhdmUgYSBzZXQgb2YgZ2VuZXMgd2l0aAogICAgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gdGFraW5nIGludG8gYWNjb3VudCBib3RoIGRvbm9yIGFuZCBjbHVzdGVyaW5nLgoKCjEuICBCaW9jb25kdWN0b3IgcGFja2FnZSAndmFyaWFuY2VQYXJ0aXRpb24nCiAgYS4gICgxfGZhY3RvcikgYXJlIHJhbmRvbSBlZmZlY3RzICBlcmdvOyBtb2RlbCA8LSBhcy5mb3JtdWxhKCJ+ICgxfGRvbm9yKSArICgxfHN0cmFpbikgKyAoMXxiYXRjaCkiKQogIGIuICBNYWtlIHZpb2xpbiBwbG90IG9mIHRoaXMgcmVzdWx0LCBwbG90IHJlc2lkdWFscyB2cy4gaGVhbGluZywKICBjLiAgUmVwZWF0IGFib3ZlIHdpdGggaW50cm9kdWNlZCArICgxfGhlYWxpbmcpCjIuICBDb3B5IGNoci9zaCBwY2EgcGxvdCBkb3duIHRvIHRoZSByZWxhYmVsIG9uZSBzYW1wbGUgc2VjdGlvbiB0byBtYWtlIGl0IGVhc2llciB0byBmb2xsb3cKMy4gIEZpZ3VyZSBvdXQgYSB3YXkgdG8gYXV0b21hdGljYWxseSBjb21wYXJlIGV2ZXJ5IHNhbXBsZSBhZ2FpbnN0IHRoZSBTTlAgcHJvZmlsZXMgZ2VuZXJhdGVkIGZvciBhbGwgc3RyYWlucy4KICBhLiAgUmVjb3JkIGEgc2V0IG9mIGNhbm9uaWNhbCBzbnBzIGZvciBlYWNoIHN0cmFpbgogIGIuICBGb3IgZWFjaCBzYW1wbGUsIHVzZSBzb21ldGhpbmcgbGlrZSBiYW1fd2hhdGV2ZXJpdHdhcyB0byBleHRyYWN0IHRob3NlIHJlZ2lvbnMKICBjLiAgRm9yIGVhY2ggc25wIHByb2ZpbGUsIGNvdW50IHRoZSBpZGVudGl0aWVzL2RpZmZlcmVuY2VzIGZvciBldmVyeSBzbnAgcG9zaXRpb24gYW5kIGhlYXRtYXAgdGhlbT8KICBkLiAgVGhlbiBpZiB0aGV5IG1hdGNoIGl0IHNob3VsZCBjb21lIHVwIHRoZSB0ZXJtaW5hbCBjb2xvciBJIHRoaW5rCjQuICBUcnkgdGhlIHNhbWUgUENBIHBsb3RzIHdpdGgganVzdCBkcm9wcGluZyBocGdsMDYzNQo1LiAgUHJpbnQgZnVsbCBzZXQgb2YgcGxvdHMgZm9yIHRoZSBwYXJhc2l0ZSBzYW1wbGVzIGJlZm9yZSBnZXR0aW5nIGludG8gdGhlIFBDQS4KCiMjIE1hY3JvcGhhZ2UgdGFza3MKCjEuICBSZS1wZXJmb3JtIERFIGFuYWx5c2VzIHdpdGggbm8tc3ZhL3J1diBidXQgY29uZGl0aW9uK2JhdGNoIChkb25lKQoyLiAgQ29sbGVjdCBJR1YgaW1hZ2VzIGZvciBzdHJhaW5zIGNoL3NoIChkb25lKQozLiAgRm9yIFNWcywgcGxvdCBTViB2cy4gdGVjaG5pY2FsIHZhcmlhYmxlczogJXJuYSwgc25wcyAoZG9uZSkKNC4gIFRha2UgdGhlICUgb2YgcmVhZHMgbWFwcGVkIHRvIHBhcmFzaXRlIGFuZCBhZGQgaXQgYXMgYW4gZXhwZXJpbWVudGFsIHBhcmFtZXRlciAoZG9uZSkKNS4gIEV4dGVuZCBTViBhbmFseXNpcyB0byBpbmNsdWRlIGNvbmRpdGlvbiArIGJhdGNoIChub3QgZG9uZSkKNi4gIEZvciB0aGUgU1YgbWV0aG9kcywgcGxvdCBsb2cyIGdlbmVzIHZzLiBsb2cyZmMgKD8pCjcuICBSdW4gUlVWL1NWQSBjb25kaXRpb24gKyBub2JhdGNoIChkb25lKQogIGEuICBUYWtlIFNWcyBhbmQgYWRkIHRvIHRoZSBtb2RlbAogIGIuICBQZXJmb3JtIERFCiAgYy4gIFBsb3QgTUEsIGNvcnJlbGF0ZSBsb2cyRkNzIGFjcm9zcyBhbmFseXNlcwo4LiAgUHJvdmlkZSBhIFBDQSBwbG90IG9mIG91ciBmaW5hbCBkZWNpc2lvbiBmb3IgdGhpcyBkYXRhIGFuZCBwcm92aWRlIGEgdGFibGUgb2YgY29vcmRpbmF0ZXMKOS4gIFByb3ZpZGUgREUgbGlzdHMgd2l0aCBjb25kaXRpb24rYmF0Y2ggaW4gdGhlIG1vZGVsIHZzLiBjb21iYXQgYWRqdXN0ZWQgYW5kIGRvIGNvbXBhcmlzb24KMTAuIFByb3ZpZGUgc29tZSBvbnRvbG9neS9LRUdHIHJlc3VsdHMKCiMjIEluZmVjdGlvbiB0YXNrcwoKMC4gQWRkICdjb29yZGluYXRlcycgZm9yIGFsbCB0aGUgUENBIHBsb3RzIGZvciBNYXJpYSBBZGVsYWlkYSB0byBwaWNrIHVwLgogICAgICAqZG9uZSBieSBhZGRpbmcgdGhlbSB0byBhbGwgUENBIHBsb3RzKgoxLiBTZW5kIGFsb25nIHNvbWUgUENBIGNvb3JkaW5hdGVzIChmcm9tIHRoZSBlbWFpbDopCiAgICAgICpkb25lKgogIGEpIFRoZSBjb29yZGluYXRlcyBvZiB0aGUgUENBIG9mIFBCTUNzIHdpdGhvdXQgYmF0Y2ggY29ycmVjdGlvbiDigJMKICAgICAgc2hvd2luZyB0aGUgc3Ryb25nIGJhdGNoIGVmZmVjdCBieSBwYXRpZW50CiAgICAgICpJYmlkICMwKgogIGIpIFRoZSBjb29yZGluYXRlcyBvZiB0aGUgUENBcyBvZiBQQk1DcyBhZnRlciBiYXRjaCBjb3JyZWN0aW9uCiAgICAgICpJYmlkICMwKgoyLiAgQW1lbmQgUENBIGNvb3JkaW5hdGVzOiAgZmlyc3Qgd2l0aG91dCB1bmluZmVjdGVkLCB0aGVuIHdpdGgKICBhKSAgd2l0aG91dCBiYXRjaCwgcGF0aWVudCwgc3RyYWluCiAgICAgICpJYmlkICMwIC0tIGFjdHVhbGx5IGRpZCBJIGRvIHRoZW0gYWxsLCBJIHRoaW5rIHNvKgozLiAgV2lsbCB3ZSBjYWxsIHRoZSA2IGlzb2xhdGVzIGJlIGNhbGxlZCAnc3RyYWlucycsICdpc29sYXRlcycsICdjdWx0dXJlcyc/CiAgYSkgIFRoZSByZWFzb24gZm9yIHRoaXMgcXVlc3Rpb24gaXMgdGhhdCB0aGV5IGRvIG5vdCBuZWNlc3NhcmlseSBmb2xsb3cgd2VsbCBkZWZpbmVkIHJ1bGVzIHZpcyBhCiAgICAgIHZpcyB0aGUgc2ltaWxhcml0eSB0byB0aGUgY2hhcmFjdGVyaXplZCBnZW5vbWUuCgo0LiAgTWFrZSBzdXJlIHRoZSBhY3R1YWwgZXhwZXJpbWVudGFsIGJhdGNoIGNvbXBhcmlzb24gaXMgbWFpbnRhaW5lZAogICAgICAqSSBiZWxpZXZlIHRoaXMgaXMgY29ycmVjdCoKNS4gIE1ha2Ugc3VyZSB0aGF0IGl0IGlzIGNsZWFyIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJ2V4cGVyaW1lbnRhbCBiYXRjaCBlZmZlY3QnIGFuZCAnZG9ub3IgZWZmZWN0JwogICAgICAqSSB0aGluayB0aGlzIGlzIGNsZWFyLCBJIGhhdmUgYSBzcGVjaWZpYyBjYWxsIGJlZm9yZSBlYWNoIGNvbXBhcmlzb24gbm93LCBpcyB0aGVyZSBhIGJlc3Qgd2F5IHRvIGVuc3VyZSB0aGlzPyoKNi4gIFJlcG9ydCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGZhY3RvcnMgYW5kIGNvbXBvbmVudHMuCiAgICAgICpEb25lIGZvciB0aGUgY2FzZSBvZiBzYW1wbGVzIHdpdGhvdXQgdW5pbmZlY3RlZCoKNy4gIEZpdCBsaW5lYXIgbW9kZWwgYWZ0ZXIgcmVtb3ZpbmcgZWFjaCBmYWN0b3IgYW5kIG9ic2VydmUgdmFyaWFuY2UgcmVtYWluaW5nIHRvIGRpcmVjdGx5IGFzc2VzcwogICAgJXZhciBpbiBlYWNoIGZhY3Rvci4gICdNb3N0IGVsZWdhbnQgbWV0aG9kIGlzIHRoZSBtaXhlZCBlZmZlY3QgbW9kZWwnCjguICBUZXJtcyBhZ3JlZWQgdG86CiAgICBhKSAgImRvbm9yIjogIChwYXRpZW50KSBib2IgamFuZSBhbGljZQogICAgYikgICJpc29sYXRlIjogIChzdHJhaW4pIDIxNzEgMjE3MiBldGMKICAgIGMpICAic3RhdHVzIjogICAoc2VsZiBoZWFsaW5nLCBjaHJvbmljLCB1bmluZmVjdGVkKQogICAgZCkgICJiYXRjaCI6ICAgIChhIGIpIFRoZSB0d28gbGlicmFyeS9STkEgaXNvbGF0aW9uIGRhdGVzCiAgICBlKSAgInNucCI6ICAgICAgKHggeSB6KSBDbGFkZSB0b3AgKGZldyksIGNsYWRlIG1pZGRsZSAoc29tZSksIGNsYWRlIGJvdHRvbSAobWFueSkKOS4gIE1ha2UgYSBtb2RlbCBvZiB+IDAgKyBpc29sYXRlICsgZG9ub3IgKyBiYXRjaCAobWF5YmUgbm90IGJhdGNoKQogICAgRml0IHRvIHRoZSBkYXRhLCB0YWtlIHJlc2lkdWFscywgbWFrZSBQQ0Egb2YgdGhlIHJlc2lkdWFscywgY29sb3IgYnkgc2gvY2gKMTAuIENvbXBhcmUgcGFyYXNpdGUgZGF0YSBjbHVzdGVyaW5nIHRvIHNlZSBpZiBzb21lIG90aGVyIHN1cnJvZ2F0ZSBmYWN0b3IgdG8gbWFrZSBzb21lIHNlbnNlIG9mCiAgICB0aGlzICAgIGEpICBHb2FsOiBhdHRlbXB0IHRvIGlkZW50aWZ5IHRoZSBjbHVzdGVyIG9mIHN0cmFpbnMgd2hpY2ggaGFzIHBlY3VsaWFyIGh1bWFuIGV4cHJlc3Npb24uCjExLiBTZWUgd2hhdCBoYXBwZW5zIGlmIEkgcmVsYWJlbCA2MzUgYXMgc3RyYWluIGNoMjUwNAogICAgICAqRG9uZSBmb3Igc29tZSB2YWx1ZXMgb2YgJ2RvbmUnIEkgYW0gbm90IGNlcnRhaW4gb2YgdGhlIHJlc3VsdCoKMTIuIExlYXJuIGJlc3QgbWV0aG9kCgojIEluc3RhbGxhdGlvbiBhbmQgc2V0dXAKClRoZXNlIGFyZSBybWFya2Rvd24gZG9jdW1lbnRzIHdoaWNoIG1ha2UgaGVhdnkgdXNlIG9mIHRoZSBocGdsdG9vbHMgcGFja2FnZS4gIFRoZSBmb2xsb3dpbmcgc2VjdGlvbgpkZW1vbnN0cmF0ZXMgaG93IHRvIHNldCB0aGF0IHVwIGluIGEgY2xlYW4gUiBlbnZpcm9ubWVudC4KCmBgYHtyIHNldHVwLCBldmFsPUZBTFNFfQojIyBVc2UgUidzIGluc3RhbGwucGFja2FnZXMgdG8gaW5zdGFsbCBkZXZ0b29scy4KaW5zdGFsbC5wYWNrYWdlcygiZGV2dG9vbHMiKQojIyBVc2UgZGV2dG9vbHMgdG8gaW5zdGFsbCBocGdsdG9vbHMuCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiZWxzYXllZGxhYi9ocGdsdG9vbHMiKQojIyBMb2FkIGhwZ2x0b29scyBpbnRvIHRoZSBSIGVudmlyb25tZW50LgpsaWJyYXJ5KGhwZ2x0b29scykKIyMgVXNlIGhwZ2x0b29scycgYXV0b2xvYWRzX2FsbCgpIGZ1bmN0aW9uIHRvIGluc3RhbGwgdGhlIG1hbnkgcGFja2FnZXMgdXNlZCBieSBocGdsdG9vbHMuCmF1dG9sb2Fkc19hbGwoKQpgYGAKClRoaXMgZG9jdW1lbnQgaXMgcmF0aGVyIHNob3J0LiAgSW4gc29tZSBvdGhlcnMgSSBkaWQgdGhlIHByZXByb2Nlc3NpbmcsIHNoYXJlZCwgZXRjIHN0ZXBzIGFzICdjaGlsZCcKZG9jdW1lbnRzIG9mIHRoaXMgYW5kIHRoZXkgd291bGQgYmUgYXBwZW5kZWQgaGVyZS4gIEluIHRoaXMgY2FzZSBJIGRpZCBub3QuCgpgYGB7ciBzYXZlbWV9CmlmICghaXNUUlVFKGdldDAoInNraXBfbG9hZCIpKSkgewogIHBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCiAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiAgdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCiAgdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQp9CmBgYAo=