1 20190115 Sample Estimation, Spyogenes: 20190115

This document is concerned with analyzing TNSeq from S.pyogenes, primarily from the perspective of changing Zn concentration in the media. This was done with samples where Cu concentrations were changed; those are not included in the final analyses, but are important for the variance calculations and so are kept here.

1.1 Extract the relevant samples

There were some other samples in this series of runs which were not relevant; so lets subset the data to include only the relevant samples.

## There were 48, now there are 42 samples.

1.4 Now some plots from after normalization

After log2 and such, PCA becomes informative. Let us therefore look first at the clustering before any surrogate estimation.

So I think once again, the primary surrogate variable is not batch per se, but stems from how the libraries diverge after their selection but before collection/library prepration.

1.5 Try a couple of surrogate variables

Given the wretched clustering observed, I figure I should try a couple tools from ruv/sva and see if they help. It looks like I prefered fsva in my earlier iteration of this visualization. I have since come to the feeling that fsva is a bit weird; and so I think I will use svaseq instead.

## Warning in varpart(expt = rpmi_filt, predictor = NULL, factors =
## c("coverage", : Renaming this soon to 'simple_varpart().'
## varpart sees only 1 batch, adjusting the model accordingly.
## Attempting mixed linear model with: ~  (1|coverage) + (1|replicate) + (1|time) + (1|cuzn) + (1|medium)
## Fitting the expressionset to the model, this is slow.
## Projected run time: ~ 0.2 min
## Placing factor: coverage at the beginning of the model.

## There is 1 batch in the data, fitting condition+batch will fail.
## batch_counts: Before batch/surrogate estimation, 274 entries are x<=0.
## The be method chose 4 surrogate variable(s).
## Attempting pca surrogate estimation with 4 surrogates.
## batch_counts: Before batch/surrogate estimation, 274 entries are x<=0.
## The be method chose 4 surrogate variable(s).
## Attempting sva supervised surrogate estimation with 4 surrogates.
## batch_counts: Before batch/surrogate estimation, 274 entries are x<=0.
## The be method chose 4 surrogate variable(s).
## Attempting sva unsupervised surrogate estimation with 4 surrogates.
## batch_counts: Before batch/surrogate estimation, 274 entries are x<=0.
## The be method chose 4 surrogate variable(s).
## Attempting ruvseq supervised surrogate estimation with 4 surrogates.
## batch_counts: Before batch/surrogate estimation, 274 entries are x<=0.
## The be method chose 4 surrogate variable(s).
## Attempting ruvseq residual surrogate estimation with 4 surrogates.
## batch_counts: Before batch/surrogate estimation, 274 entries are x<=0.
## The be method chose 4 surrogate variable(s).
## Attempting ruvseq empirical surrogate estimation with 4 surrogates.
## Warning in cor(first_svs): the standard deviation is zero

## A friendly reminder that there is only 1 batch in the data.
## 2/7: Performing lmFit(data) etc. with pca in the model.
## 3/7: Performing lmFit(data) etc. with sva_sup in the model.
## 4/7: Performing lmFit(data) etc. with sva_unsup in the model.
## 5/7: Performing lmFit(data) etc. with ruv_sup in the model.
## 6/7: Performing lmFit(data) etc. with ruv_resid in the model.
## 7/7: Performing lmFit(data) etc. with ruv_emp in the model.

## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset c89fbb1a6badaccdac9bfbc109bd1fe2d673b639
## This is hpgltools commit: Sun Jan 13 20:46:37 2019 -0500: c89fbb1a6badaccdac9bfbc109bd1fe2d673b639

R version 3.5.2 (2018-12-20)

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

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

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

other attached packages: variancePartition(v.1.12.1), ruv(v.0.9.7), bindrcpp(v.0.2.2), hpgltools(v.2018.11), Biobase(v.2.42.0) and BiocGenerics(v.0.28.0)

loaded via a namespace (and not attached): R.utils(v.2.7.0), tidyselect(v.0.2.5), lme4(v.1.1-19), RSQLite(v.2.1.1), AnnotationDbi(v.1.44.0), grid(v.3.5.2), BiocParallel(v.1.16.5), Rtsne(v.0.15), devtools(v.2.0.1), DESeq(v.1.34.1), munsell(v.0.5.0), codetools(v.0.2-16), preprocessCore(v.1.45.0), units(v.0.6-2), statmod(v.1.4.30), withr(v.2.1.2), colorspace(v.1.3-2), GOSemSim(v.2.8.0), knitr(v.1.21), rstudioapi(v.0.9.0), stats4(v.3.5.2), DOSE(v.3.8.0), labeling(v.0.3), urltools(v.1.7.1), GenomeInfoDbData(v.1.2.0), hwriter(v.1.3.2), bit64(v.0.9-7), farver(v.1.1.0), rprojroot(v.1.3-2), xfun(v.0.4), EDASeq(v.2.16.3), R6(v.2.3.0), doParallel(v.1.0.14), GenomeInfoDb(v.1.18.1), locfit(v.1.5-9.1), bitops(v.1.0-6), fgsea(v.1.8.0), gridGraphics(v.0.3-0), DelayedArray(v.0.8.0), assertthat(v.0.2.0), scales(v.1.0.0), ggraph(v.1.0.2), enrichplot(v.1.2.0), gtable(v.0.2.0), RUVSeq(v.1.16.1), sva(v.3.30.1), processx(v.3.2.1), rlang(v.0.3.1), genefilter(v.1.64.0), splines(v.3.5.2), rtracklayer(v.1.42.1), lazyeval(v.0.2.1), europepmc(v.0.3), yaml(v.2.2.0), reshape2(v.1.4.3), GenomicFeatures(v.1.34.1), backports(v.1.1.3), qvalue(v.2.14.1), clusterProfiler(v.3.10.1), tools(v.3.5.2), usethis(v.1.4.0), ggplotify(v.0.0.3), ggplot2(v.3.1.0), gplots(v.3.0.1), RColorBrewer(v.1.1-2), sessioninfo(v.1.1.1), ggridges(v.0.5.1), Rcpp(v.1.0.0), plyr(v.1.8.4), base64enc(v.0.1-3), progress(v.1.2.0), zlibbioc(v.1.28.0), purrr(v.0.2.5), RCurl(v.1.95-4.11), ps(v.1.3.0), prettyunits(v.1.0.2), viridis(v.0.5.1), cowplot(v.0.9.4), S4Vectors(v.0.20.1), SummarizedExperiment(v.1.12.0), ggrepel(v.0.8.0), colorRamps(v.2.3), fs(v.1.2.6), magrittr(v.1.5), data.table(v.1.11.8), DO.db(v.2.9), openxlsx(v.4.1.0), triebeard(v.0.3.0), packrat(v.0.5.0), matrixStats(v.0.54.0), pkgload(v.1.0.2), aroma.light(v.3.12.0), hms(v.0.4.2), evaluate(v.0.12), xtable(v.1.8-3), pbkrtest(v.0.4-7), XML(v.3.98-1.16), IRanges(v.2.16.0), gridExtra(v.2.3), testthat(v.2.0.1), compiler(v.3.5.2), biomaRt(v.2.38.0), tibble(v.2.0.0), KernSmooth(v.2.23-15), crayon(v.1.3.4), minqa(v.1.2.4), R.oo(v.1.22.0), htmltools(v.0.3.6), mgcv(v.1.8-26), corpcor(v.1.6.9), tidyr(v.0.8.2), geneplotter(v.1.60.0), DBI(v.1.0.0), corrplot(v.0.84), tweenr(v.1.0.1), MASS(v.7.3-51.1), ShortRead(v.1.40.0), Matrix(v.1.2-15), cli(v.1.0.1), quadprog(v.1.5-5), R.methodsS3(v.1.7.1), gdata(v.2.18.0), bindr(v.0.1.1), igraph(v.1.2.2), GenomicRanges(v.1.34.0), pkgconfig(v.2.0.2), rvcheck(v.0.1.3), GenomicAlignments(v.1.18.1), xml2(v.1.2.0), foreach(v.1.4.4), annotate(v.1.60.0), XVector(v.0.22.0), stringr(v.1.3.1), callr(v.3.1.1), digest(v.0.6.18), Biostrings(v.2.50.2), rmarkdown(v.1.11), fastmatch(v.1.1-0), edgeR(v.3.24.3), directlabels(v.2018.05.22), Rsamtools(v.1.34.0), gtools(v.3.8.1), nloptr(v.1.2.1), nlme(v.3.1-137), jsonlite(v.1.6), desc(v.1.2.0), viridisLite(v.0.3.0), limma(v.3.38.3), pillar(v.1.3.1), lattice(v.0.20-38), httr(v.1.4.0), pkgbuild(v.1.0.2), survival(v.2.43-3), GO.db(v.3.7.0), glue(v.1.3.0), remotes(v.2.0.2), zip(v.1.0.0), UpSetR(v.1.3.3), iterators(v.1.0.10), pander(v.0.6.3), bit(v.1.1-14), ggforce(v.0.1.3), stringi(v.1.2.4), blob(v.1.1.1), latticeExtra(v.0.6-28), caTools(v.1.17.1.1), memoise(v.1.1.0) and dplyr(v.0.7.8)

## Saving to 20190115_02_sample_estimation-v20190115.rda.xz
LS0tCnRpdGxlOiAiMjAxOTAxMTY6IFNhbXBsZSBlc3RpbWF0aW9uIGZvciBUTlNlcSBvZiBTcHlvZ2VuZXMgKDIwMTcgaW5jbHVkaW5nIEFuZHJldykuIgphdXRob3I6ICJhdGIiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgd2lkdGg6IDMwMAogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIHRvY19mbG9hdDogdHJ1ZQogIEJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogZm9udC1zaXplOiAxNnB4Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoImhwZ2x0b29scyIpCnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldCh3aWR0aD0xMjAsCiAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHM9NCwKICAgICAgICAgICAgICAgICAgICAgICBtYXgucHJpbnQ9MTIwLAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQ9IiVZJW0lZCIpCnByZXZpb3VzX2ZpbGUgPC0gIjIwMTkwMTE1XzAxX2Fubm90YXRpb24uUm1kIgp2ZXIgPC0gIjIwMTkwMTE1IgoKdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKQoKcm1kX2ZpbGUgPC0gIjIwMTkwMTE1XzAyX3NhbXBsZV9lc3RpbWF0aW9uLlJtZCIKYGBgCgojIGByIHJ1bmRhdGVgIFNhbXBsZSBFc3RpbWF0aW9uLCBTcHlvZ2VuZXM6IGByIHZlcmAKClRoaXMgZG9jdW1lbnQgaXMgY29uY2VybmVkIHdpdGggYW5hbHl6aW5nIFROU2VxIGZyb20gUy5weW9nZW5lcywgcHJpbWFyaWx5IGZyb20KdGhlIHBlcnNwZWN0aXZlIG9mIGNoYW5naW5nIFpuIGNvbmNlbnRyYXRpb24gaW4gdGhlIG1lZGlhLiAgVGhpcyB3YXMgZG9uZSB3aXRoCnNhbXBsZXMgd2hlcmUgQ3UgY29uY2VudHJhdGlvbnMgd2VyZSBjaGFuZ2VkOyB0aG9zZSBhcmUgbm90IGluY2x1ZGVkIGluIHRoZQpmaW5hbCBhbmFseXNlcywgYnV0IGFyZSBpbXBvcnRhbnQgZm9yIHRoZSB2YXJpYW5jZSBjYWxjdWxhdGlvbnMgYW5kIHNvIGFyZSBrZXB0CmhlcmUuCgojIyBFeHRyYWN0IHRoZSByZWxldmFudCBzYW1wbGVzCgpUaGVyZSB3ZXJlIHNvbWUgb3RoZXIgc2FtcGxlcyBpbiB0aGlzIHNlcmllcyBvZiBydW5zIHdoaWNoIHdlcmUgbm90IHJlbGV2YW50OyBzbwpsZXRzIHN1YnNldCB0aGUgZGF0YSB0byBpbmNsdWRlIG9ubHkgdGhlIHJlbGV2YW50IHNhbXBsZXMuCgpgYGB7ciBleHRyYWN0X3NhbXBsZXN9CnJwbWlfZXhwdCA8LSBzdWJzZXRfZXhwdChleHB0PXNwX2V4cHQsIHN1YnNldD0iZXhwZXJpbWVudD09J21ldGFsIGhvbWVvc3Rhc2lzJyIpCmBgYAoKIyMgUGxvdCBzYW1wbGVzIG9mIHRoZSByYXcgZGF0YQoKYGBge3IgaW5pdGlhbF9lc3RpbWF0aW9uLCBmaWcuc2hvdz0iaGlkZSJ9CnJwbWlfbWV0cmljcyA8LSBzbShncmFwaF9tZXRyaWNzKGV4cHQ9cnBtaV9leHB0KSkKYGBgCgpJIGFtIGRvaW5nIHRoaXMgZnJlc2ggYWZ0ZXIgYSBsb25nIHRpbWU7IEkgZG9uJ3QgcmVhbGx5IHJlbWVtYmVyIHdoYXQgdGhlc2UKcGxvdHMgbG9vayBsaWtlLCBidXQgSSBhbSBiZXR0aW5nIHRoZXJlIGlzIGEgaHVnZSBiYXRjaC1saWtlIGVmZmVjdCB3aGljaApkZXBlbmRzIG9uIHRoZSBsaWJyYXJ5IHByZWN1cnNvci4gIEJ1dCBiZWZvcmUgdGhhdCwgbGV0IHVzIGxvb2sgYXQgdGhlaXIKc2F0dXJhdGlvbnMgYW5kIG90aGVyIG1ldHJpY3MuCgpgYGB7ciBwbG90X2luaXRpYWxfZXN0aW1hdGVzfQpycG1pX21ldHJpY3MkbGVnZW5kCiMjIERvbid0IGZvcmdldCB0byBwcmludCB0aGUgbGVnZW5kIQpycG1pX21ldHJpY3MkbGlic2l6ZQojIyBTbyB0aGUgc2FkZGVzdCBsaWJyYXJ5IGhhcyAzLDkyMiwwNDcgcmVhZHMsIHRoYXQgaXMgbm90IHRlcnJpYmxlIEkgdGhpbmsuCiMjIEEgZmV3IHNhbXBsZXMgbWlnaHQgYmUgYSBwcm9ibGVtOiBocGdsMDg5OCwgaHBnbDA4Nzk7IGJ1dCBJIGFtIGd1ZXNzaW5nIGEgZmFjdG9yCiMjIG9mIDw0IGJldHdlZW4gdGhlIGhpZ2hlc3QgYW5kIGxvd2VzdCBzYW1wbGVzIHNob3VsZCBub3QgYmUgdG9vIGJpZyBvZiBhIHByb2JsZW0uCnJwbWlfbWV0cmljcyRub256ZXJvCiMjIExvd2VyIHktYXhpcyBzYW1wbGVzIGFyZSBtb3JlIGxpa2VseSB0byBiZSB0cm91Ymxlc29tZSAobG9va2luZyBhdCB5b3UgaHBnbDA4NjYsIDg5OCwgODc4LCA4NjkpLgpycG1pX21ldHJpY3MkY29yaGVhdAojIyBUaGVyZSBpcyBhIHByZXR0eSBoYXJzaCBiYXRjaC1saWtlIGVmZmVjdApycG1pX21ldHJpY3MkY3ZwbG90CiMjIEJ1dCBhdCBsZWFzdCB0aGUgY29lZmZpY2llbnRzIG9mIHZhcmlhbmNlIGFyZSBzaW1pbGFyLiAgd2FpdCwgd2Ugb25seSBoYXZlIDIgdGh5IHNhbXBsZXM/CnJwbWlfbWV0cmljcyRkZW5zaXR5CiMjIE5pY2UsIGNvbnNpc3RlbnQgc2FtcGxlIGRlbnNpdGllcwpgYGAKCiMjIE5vcm1hbGl6ZSBhbmQgcmVwbG90CgpJIGp1c3QgY29waWVkL3Bhc3RlZCB0aGUgZm9sbG93aW5nIGZyb20gdGhlIHByZXZpb3VzIHdvcmtzaGVldCwgYnV0IEkgYW0gc2VlaW5nCnRoYXQgSSBkaWQgbm90IGFjdHVhbGx5IHVzZSB0aGVzZSBwbG90cy4gIEkgdGhpbmsgSSB3aWxsIGxlYXZlIHRoZW0gaGVyZSBmb3IKbm93LgoKYGBge3Igbm9ybV9yZXBsb3QsIGZpZy5zaG93PSJoaWRlIn0KcnBtaV9maWx0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJwbWlfZXhwdCwgZmlsdGVyPVRSVUUpKQojIyBUaGlzIHdpbGwgbGlrZWx5IGJlIG91ciBkYXRhIGZvciBERSBhbmFseXNlcy4KcnBtaV9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJwbWlfZXhwdCwgZmlsdGVyPVRSVUUsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIpKQojIyBUaGlzLCBhbmQgYSBzdmEgdmVyc2lvbiBvZiBpdCwgd2lsbCBiZSB1c2VkIGZvciB2aXN1YWxpemluZy4KcnBtaV9iYXRjaCA8LSBzbShub3JtYWxpemVfZXhwdChycG1pX2ZpbHQsIGZpbHRlcj1UUlVFLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJzdmFzZXEiLCB0cmFuc2Zvcm09ImxvZzIiKSkKCnJwbWlfbm9ybV9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MocnBtaV9ub3JtKSkKcnBtaV9iYXRjaF9tZXRyaWNzIDwtIHNtKGdyYXBoX21ldHJpY3MocnBtaV9iYXRjaCkpCmBgYAoKIyMgTm93IHNvbWUgcGxvdHMgZnJvbSBhZnRlciBub3JtYWxpemF0aW9uCgpBZnRlciBsb2cyIGFuZCBzdWNoLCBQQ0EgYmVjb21lcyBpbmZvcm1hdGl2ZS4gIExldCB1cyB0aGVyZWZvcmUgbG9vayBmaXJzdCBhdAp0aGUgY2x1c3RlcmluZyBiZWZvcmUgYW55IHN1cnJvZ2F0ZSBlc3RpbWF0aW9uLgoKYGBge3IgbW91c2Vfc2hvd19pbWFnZXNfcG9zdH0Kbm9ybV9wY2EgPC0gcGxvdF9wY2EocnBtaV9ub3JtLCBjaXM9RkFMU0UpCm5vcm1fcGNhJHBsb3QKIyMgVGhpcyBjbHVzdGVyaW5nIGlzIGtpbmQgb2YgdGVycmlibGUuCnJwbWlfbm9ybV9tZXRyaWNzJGRpc2hlYXQKIyMgVGhpcyBpcyBnb2luZyB0byBiZSBhIHByb2JsZW0uCmBgYAoKU28gSSB0aGluayBvbmNlIGFnYWluLCB0aGUgcHJpbWFyeSBzdXJyb2dhdGUgdmFyaWFibGUgaXMgbm90IGJhdGNoIHBlciBzZSwgYnV0CnN0ZW1zIGZyb20gaG93IHRoZSBsaWJyYXJpZXMgZGl2ZXJnZSBhZnRlciB0aGVpciBzZWxlY3Rpb24gYnV0IGJlZm9yZQpjb2xsZWN0aW9uL2xpYnJhcnkgcHJlcHJhdGlvbi4KCiMjIFRyeSBhIGNvdXBsZSBvZiBzdXJyb2dhdGUgdmFyaWFibGVzCgpHaXZlbiB0aGUgd3JldGNoZWQgY2x1c3RlcmluZyBvYnNlcnZlZCwgSSBmaWd1cmUgSSBzaG91bGQgdHJ5IGEgY291cGxlIHRvb2xzCmZyb20gcnV2L3N2YSBhbmQgc2VlIGlmIHRoZXkgaGVscC4gIEl0IGxvb2tzIGxpa2UgSSBwcmVmZXJlZCBmc3ZhIGluIG15IGVhcmxpZXIKaXRlcmF0aW9uIG9mIHRoaXMgdmlzdWFsaXphdGlvbi4gIEkgaGF2ZSBzaW5jZSBjb21lIHRvIHRoZSBmZWVsaW5nIHRoYXQgZnN2YSBpcwphIGJpdCB3ZWlyZDsgYW5kIHNvIEkgdGhpbmsgSSB3aWxsIHVzZSBzdmFzZXEgaW5zdGVhZC4KCmBgYHtyIGJhdGNoX3Rlc3Rpbmd9CnJwbWlfYmF0Y2gxIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJwbWlfZXhwdCwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJmc3ZhIikpCnBsb3RfcGNhKHJwbWlfYmF0Y2gxKSRwbG90CnBsb3RfY29yaGVhdChycG1pX2JhdGNoMSkkcGxvdAojIyBUaGlzIGxvb2tzIGEgYml0IG1vcmUgZW5jb3VyYWdpbmcuCgpycG1pX2JhdGNoMiA8LSBzbShub3JtYWxpemVfZXhwdChycG1pX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBiYXRjaD0ic3Zhc2VxIikpCnBsb3RfcGNhKHJwbWlfYmF0Y2gyKSRwbG90CiMjIGFzIGRvZXMgdGhpcy4KCnJwbWlfYmF0Y2hfd3JpdHRlbiA8LSBzbSgKICB3cml0ZV9leHB0KGV4cHQ9cnBtaV9leHB0LCB0cmFuc2Zvcm09ImxvZzIiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgZmlsdGVyPVRSVUUsIGJhdGNoPSJzdmFzZXEiLCB2aW9saW49VFJVRSwKICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvIiwgcnVuZGF0ZSwgIl9ycG1pX3N2YXNlcS12IiwgdmVyLCAiLnhsc3giKSkpCmBgYAoKYGBge3Igc3Vycm9nYXRlX3Rlc3Rpbmd9CnZhcnBhcnRfdGVzdCA8LSB2YXJwYXJ0KGV4cHQ9cnBtaV9maWx0LCBwcmVkaWN0b3I9TlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9ycz1jKCJjb3ZlcmFnZSIsICJyZXBsaWNhdGUiLCAidGltZSIsICJjdXpuIiwgIm1lZGl1bSIpKQp2YXJwYXJ0X3Rlc3QkcGFydGl0aW9uX3Bsb3QKdmFycGFydF90ZXN0JHBlcmNlbnRfcGxvdAoKc3Vycm9nYXRlX3Rlc3QgPC0gY29tcGFyZV9zdXJyb2dhdGVfZXN0aW1hdGVzKHJwbWlfZmlsdCkKCnN1cnJvZ2F0ZV90ZXN0JHN2YV91bnN1cGVydmlzZWRfYWRqdXN0JHN2c19zYW1wbGUKcnBtaV9tZXRyaWNzJGxpYnNpemUKIyMgR2l2ZW4gdGhlIGNvbnRyaWJ1dGlvbiBvZiBjb3ZlcmFnZSBpbiB0aGUgdmFyaWFuY2VQYXJ0aXRpb24gcmVzdWx0cyBhYm92ZSwgb25lIG1pZ2h0CiMjIGFzc3VtZSB0aGF0IHRoZSBsaWJyYXJ5IHNpemVzIHdpbGwgY29ycmVzcG9uZCB0byB0aGUgc3Vycm9nYXRlcyBkZXRlY3RlZCBieSBzdmEgYW5kIGZyaWVuZHMuCiMjIFRoaXMgYXBwZWFycyB0byBub3QgYmUgdGhlIGNhc2UuCnN1cnJvZ2F0ZV90ZXN0JHBsb3QKIyMgaXQgbG9va3MgbGlrZSB0aGUgdmFyaW91cyBzdXJyb2dhdGUgZXN0aW1hdG9ycyBtb3N0bHkgYWdyZWUgb24gdGhpcyBkYXRhIC0tCiMjIGVzcGVjaWFsbHkgdGhlIHN2YS1iYXNlZCBvbmVzLgpgYGAKCmBgYHtyIHNhdmVtZX0KbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCnBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAK