1 PBMC Infection Differential Expression, Infection: 20180822 Rundate: 20181205

This document turns to the infection of PBMC cells with L.panamensis. This data is particularly strangely affected by the different strains used to infect the cells, and as a result is both useful and troubling.

Given the observations above, we have some ideas of ways to pass the data for differential expression analyses which may or may not be ‘better’. Lets try some and see what happens.

1.1 Create data sets to compare differential expression analyses

Given the above ways to massage the data, lets use a few of them for limma/deseq/edger. The main caveat in this is that those tools really do expect specific distributions of data which we horribly violate if we use log2() data, which is why in the previous blocks I named them l2blahblah, thus we can do the same sets of normalization but without that and forcibly push the resulting data into limma/edger/deseq.

2 The negative control

Everything I did in 02_estimation_infection.html suggests that there are no significant differences visible if one looks just at chronic/self-healing in this data. Further testing has seemingly proven this statement, as a result most of the following analyses will look at chronic/uninfected and self-healing/uninfected followed by attempts to reconcile those results.

2.1 Filter the data

To save some time and annoyance with sva, lets filter the data now. In addition, write down a small function used to extract the sets of significant genes across different contrasts (notably self/uninfected vs. chronic/uninfected).

2.2 No-batch data

In the following block, I will take the comparisons performed without any batch in the model/adjustment and use them to search for shared/unique genes among the self-healing vs. uninfected and the chronic vs. uninfected.

2.2.1 Review nobatch pca

##        change_counts_up change_counts_down
## sh_nil              926                173
## ch_nil              927                167
## ch_sh                 0                  0

2.3 Add patient to the model

Repeat the previous set of analyses with d107/108/110 in the model.

2.3.1 Review pca

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

##        change_counts_up change_counts_down
## sh_nil              906                298
## ch_nil              932                279
## ch_sh                 0                  0
##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  56    -none- character
## 01  82    -none- character
## 11 850    -none- character

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  65    -none- character
## 01  46    -none- character
## 11 233    -none- character
## 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.
## The first datum is missing method: ebseq.
## 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
## $sh_nil
## $sh_nil$logfc
## [1] 0.9916
## 
## $sh_nil$p
## [1] 0.9353
## 
## $sh_nil$adjp
## [1] 0.9353
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] 0.9925
## 
## $ch_nil$p
## [1] 0.9374
## 
## $ch_nil$adjp
## [1] 0.9374
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.9873
## 
## $ch_sh$p
## [1] 0.9304
## 
## $ch_sh$adjp
## [1] 0.06891

2.4 Write an excel workbook using the batch data.

The following block writes out the unique/shared genes observed among the contrasts which included donor in the model.

## Saving to: excel/figure_5a_stuff-v20180822.xlsx

2.5 Add ssva into the mix

Repeat, this time attmepting to tamp down the variance by person.

2.5.1 Review ssva

##        change_counts_up change_counts_down
## sh_nil              805                507
## ch_nil              991                553
## ch_sh                 0                  0
##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  38    -none- character
## 01 224    -none- character
## 11 767    -none- character

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  33    -none- character
## 01  79    -none- character
## 11 474    -none- character
## $sh_nil
## $sh_nil$logfc
## [1] 0.2856
## 
## $sh_nil$p
## [1] 0.008603
## 
## $sh_nil$adjp
## [1] 0.008606
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] 0.356
## 
## $ch_nil$p
## [1] 0.03392
## 
## $ch_nil$adjp
## [1] 0.03392
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.9571
## 
## $ch_sh$p
## [1] 0.8855
## 
## $ch_sh$adjp
## [1] 0.06088
## $sh_nil
## $sh_nil$logfc
## [1] 0.2982
## 
## $sh_nil$p
## [1] 0.1252
## 
## $sh_nil$adjp
## [1] 0.1252
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] 0.3653
## 
## $ch_nil$p
## [1] 0.1417
## 
## $ch_nil$adjp
## [1] 0.1417
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.9735
## 
## $ch_sh$p
## [1] 0.9305
## 
## $ch_sh$adjp
## [1] 0.9305

2.6 fsva

Repeat again using fsva.

2.6.1 Review fsva

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  64    -none- character
## 01  96    -none- character
## 11 864    -none- character

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  70    -none- character
## 01  45    -none- character
## 11 225    -none- character
## $sh_nil
## $sh_nil$logfc
## [1] 0.9937
## 
## $sh_nil$p
## [1] 0.922
## 
## $sh_nil$adjp
## [1] 0.922
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] 0.9937
## 
## $ch_nil$p
## [1] 0.9206
## 
## $ch_nil$adjp
## [1] 0.9206
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.9743
## 
## $ch_sh$p
## [1] 0.9012
## 
## $ch_sh$adjp
## [1] 0.06275
## $sh_nil
## $sh_nil$logfc
## [1] 0.2808
## 
## $sh_nil$p
## [1] 0.1256
## 
## $sh_nil$adjp
## [1] 0.1256
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] 0.3348
## 
## $ch_nil$p
## [1] 0.1355
## 
## $ch_nil$adjp
## [1] 0.1355
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.9896
## 
## $ch_sh$p
## [1] 0.9686
## 
## $ch_sh$adjp
## [1] 0.9686

2.7 Try with the combat modified data

Repeat once again, this time using combat to try to limit the contribution of the strain to the data. I do not think we will ever use this set of contrasts, so I will deactivate it but leave it here if it is required later.

## This function will replace the expt$expressionset slot with:
## combat_scale(quant(data))
## It backs up the current data into a slot named:
##  expt$backup_expressionset. It will also save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep the libsizes in mind
##  when invoking limma.  The appropriate libsize is the 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
## Filter is false, this should likely be set to something, good
##  choices include cbcb, kofa, pofa (anything but FALSE).  If you want this to
##  stay FALSE, keep in mind that if other normalizations are performed, then the
##  resulting libsizes are likely to be strange (potentially negative!)
## 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: not doing count filtering.
## 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.
## batch_counts: Before batch correction, 407 entries 0<=x<1.
## batch_counts: Before batch correction, 2 entries are >= 0.
## Passing off to all_adjusters.
## Found arglist convert! raw
## The detected scale of the data is: raw.
## Doing a raw conversion with a filter with 2 threshold.
## batch_counts: Before batch correction, 407 entries 0<=x<1.
## batch_counts: Before batch correction, 2 entries are >= 0.
## The be method chose 3 surrogate variable(s).
## The most likely error in sva::empirical.controls() is a call to density in irwsva.build. Setting control_likelihoods to zero and using unsupervised sva.
## Warning in all_adjusters(count_table, design = design, estimate_type =
## batch, : It is highly likely that the underlying reason for this error is
## too many 0's in the dataset, please try doing a filtering of the data and
## retry.
## batch_counts: Using combat with a prior and with scaling.
## The number of elements which are < 0 after batch correction is: 6181
## The variable low_to_zero sets whether to change <0 values to 0 and is: FALSE
## The new colors are a character, changing according to condition.

2.7.1 Review combat

##        change_counts_up change_counts_down
## sh_nil             1518                 22
## ch_nil             2289               2056
## ch_sh               470               1091
##    Length Class  Mode     
## 00    0   -none- NULL     
## 10    0   -none- NULL     
## 01  771   -none- character
## 11 1518   -none- character

##    Length Class  Mode     
## 00    0   -none- NULL     
## 10    0   -none- NULL     
## 01 2034   -none- character
## 11   22   -none- character
## $sh_nil
## $sh_nil$logfc
## [1] -0.07967
## 
## $sh_nil$p
## [1] -0.04815
## 
## $sh_nil$adjp
## [1] -0.04815
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] -0.1114
## 
## $ch_nil$p
## [1] -0.02765
## 
## $ch_nil$adjp
## [1] -0.02765
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.01295
## 
## $ch_sh$p
## [1] -0.1028
## 
## $ch_sh$adjp
## [1] 0.002389
## $sh_nil
## $sh_nil$logfc
## [1] -0.08732
## 
## $sh_nil$p
## [1] -0.004519
## 
## $sh_nil$adjp
## [1] -0.004516
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] -0.1309
## 
## $ch_nil$p
## [1] 0.04731
## 
## $ch_nil$adjp
## [1] 0.04731
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] -0.04856
## 
## $ch_sh$p
## [1] -0.02353
## 
## $ch_sh$adjp
## [1] -0.0235

2.8 Compare DE results

For each of the following, perform a simple DE and see what happens:

  1. no uninfected strain as batch, try to compare each of the 3 patients chronic/self
  2. no uninfected strain as batch, try to compare chronic/self for all
  3. Repeat #1 above with uninfected
  4. Repeat #2 with uninfected

2.8.1 DE: include uninfected, use strain as batch

The data used in the following is the quantile(cpm(filter())) where the condition was set to a concatenation of patient and healing state, combat was also performed, so we no longer want batch in the experimental model and also we need to pass ‘force=TRUE’ because deseq/edger will need to be coerced into accepting these modified data.

## chr_5430_d108 chr_5397_d108 chr_2504_d108  sh_2272_d108  sh_1022_d108 
##           chr           chr           chr            sh            sh 
##  sh_2189_d108 chr_5430_d110 chr_5397_d110 chr_2504_d110  sh_2272_d110 
##            sh           chr           chr           chr            sh 
##  sh_1022_d110  sh_2189_d110 chr_5430_d107 chr_5397_d107 chr_2504_d107 
##            sh            sh           chr           chr           chr 
##  sh_2272_d107  sh_1022_d107  sh_2189_d107 
##            sh            sh            sh 
## Levels: sh chr

2.9 Make some Venns

Now we want to look at intersections from the perspective of contrasts performed comparing the self-healing/chronic vs. uninfected for the three donors separately.

2.9.1 Perform venns of self-healing vs. uninfected

This time for each of the three donors: self-healing up vs. uninfected.

2.9.3 Perform venns of self-healing vs. uninfected

This time for each of the three donors: self-healing down vs. uninfected.

2.9.4 Perform venns of self-healing vs. uninfected

This time for each of the three donors: chronic down vs. uninfected.

At this point, we should have a set of genes which are up/down in the self/uninfected and chronic/uninfected, kept in variables with names like: ‘shared_shun_down’ and ‘shared_chun_down’

2.10 Get Meta! Intersect the above comparisons.

Now we want a sense of what genes are shared/unique among the self-healing vs. uninfected and the chronic vs. uninfected comparisons performed above. One would assume that the most interesting genes in these sets will prove to be the the ones which are not shared.

## Saving to: excel/figure_5c_stuff-v20180822.xlsx

2.10.1 Genes shared among the donors.

One further query: what genes are shared among the contrasts of self-healing/chronic vs. uninfected for the three donors? When doing this, we have once again to consider whether to use the nobatch/batch-in-model/sva/etc methods against our donors… Since they all agree pretty well until combat, I will arbitrarily choose fsva.

One idea suggested by Maria Adelaida was to compare the set of genes shared among d107/d108/d110 in this last comparison (which was each of the three donors separately) against the set of genes in the all-data analysis above.

2.10.1.1 Attempt to answer by the unique individual sets

In this block, I will attempt to answer the above query by intersecting the sets of genes shared among the individuals but unique to sh/chr vs. uninfected against the set of genes observed in the original sva-mediated DE analysis.

2.10.1.2 Answer by looking at the shared genes in both sets

3 Figure 5

Generate DE lists of each donor for all contrasts for PBMCs.

  1. Venn sh/uninf vs chr/uninf 2 venn diagram up. (donor in model)
  2. Venn sh/uninf vs chr/uninf 2 venn diagram down.
  3. Venn Sh/uninf up genes 3 venn diagram.
  4. Venn Sh/uninf down genes 3 venn.
  5. Venn Chr/uninf up genes 3 venn.
  6. Venn Chr/uninf down genes 3 venn.
  7. 2 way venn of (common up in 3 venn sh/uninf) vs. (common up in 3 venn chr/uninf)
  8. 2 way venn of (common down in 3 venn sh/uninf) vs. (common down in 3 venn chr/uninf)

I renamed these plots and am now hopelessly confused as to which is which. I think I will not run this for now but instead generate the worksheet without them and then return to this in the hopes that I can do a better job.

4 Try again on the parasite data

4.1 Remember our data set

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

other attached packages: edgeR(v.3.24.0), ruv(v.0.9.7), bindrcpp(v.0.2.2), variancePartition(v.1.12.0), scales(v.1.0.0), foreach(v.1.4.4), limma(v.3.38.3), ggplot2(v.3.1.0), hpgltools(v.2018.11), Biobase(v.2.42.0) and BiocGenerics(v.0.28.0)

loaded via a namespace (and not attached): tidyselect(v.0.2.5), lme4(v.1.1-19), RSQLite(v.2.1.1), AnnotationDbi(v.1.44.0), htmlwidgets(v.1.3), grid(v.3.5.1), BiocParallel(v.1.16.2), devtools(v.2.0.1), munsell(v.0.5.0), codetools(v.0.2-15), preprocessCore(v.1.44.0), units(v.0.6-1), withr(v.2.1.2), colorspace(v.1.3-2), GOSemSim(v.2.8.0), OrganismDbi(v.1.24.0), knitr(v.1.20), rstudioapi(v.0.8), stats4(v.3.5.1), Vennerable(v.3.1.0.9000), robustbase(v.0.93-3), DOSE(v.3.8.0), labeling(v.0.3), urltools(v.1.7.1), GenomeInfoDbData(v.1.2.0), bit64(v.0.9-7), farver(v.1.1.0), rprojroot(v.1.3-2), 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), ggraph(v.1.0.2), nnet(v.7.3-12), enrichplot(v.1.2.0), gtable(v.0.2.0), sva(v.3.30.0), processx(v.3.2.0), rlang(v.0.3.0.1), genefilter(v.1.64.0), splines(v.3.5.1), rtracklayer(v.1.42.1), lazyeval(v.0.2.1), acepack(v.1.4.1), checkmate(v.1.8.5), europepmc(v.0.3), BiocManager(v.1.30.4), yaml(v.2.2.0), reshape2(v.1.4.3), GenomicFeatures(v.1.34.1), backports(v.1.1.2), qvalue(v.2.14.0), Hmisc(v.4.1-1), clusterProfiler(v.3.10.0), RBGL(v.1.58.1), tools(v.3.5.1), usethis(v.1.4.0), ggplotify(v.0.0.3), 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.2.1), prettyunits(v.1.0.2), rpart(v.4.1-13), viridis(v.0.5.1), cowplot(v.0.9.3), S4Vectors(v.0.20.1), SummarizedExperiment(v.1.12.0), ggrepel(v.0.8.0), cluster(v.2.0.7-1), colorRamps(v.2.3), fs(v.1.2.6), magrittr(v.1.5), data.table(v.1.11.8), openxlsx(v.4.1.0), DO.db(v.2.9), triebeard(v.0.3.0), packrat(v.0.5.0), matrixStats(v.0.54.0), pkgload(v.1.0.2), 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.1), biomaRt(v.2.38.0), tibble(v.1.4.2), KernSmooth(v.2.23-15), crayon(v.1.3.4), minqa(v.1.2.4), htmltools(v.0.3.6), mgcv(v.1.8-26), corpcor(v.1.6.9), snow(v.0.4-3), Formula(v.1.2-3), geneplotter(v.1.60.0), tidyr(v.0.8.2), DBI(v.1.0.0), tweenr(v.1.0.0), MASS(v.7.3-51.1), Matrix(v.1.2-15), cli(v.1.0.1), quadprog(v.1.5-5), 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.1), GenomicAlignments(v.1.18.0), foreign(v.0.8-71), plotly(v.4.8.0), xml2(v.1.2.0), annotate(v.1.60.0), XVector(v.0.22.0), stringr(v.1.3.1), callr(v.3.0.0), digest(v.0.6.18), graph(v.1.60.0), Biostrings(v.2.50.1), rmarkdown(v.1.10), fastmatch(v.1.1-0), htmlTable(v.1.12), 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.5), desc(v.1.2.0), viridisLite(v.0.3.0), pillar(v.1.3.0), lattice(v.0.20-38), DEoptimR(v.1.0-8), httr(v.1.3.1), 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), DESeq2(v.1.22.1), doSNOW(v.1.0.16), latticeExtra(v.0.6-28), caTools(v.1.17.1.1), memoise(v.1.1.0) and dplyr(v.0.7.8)

## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 242609d9ad73083ea13099760f8f0678a4befbf8
## This is hpgltools commit: Wed Dec 5 15:02:17 2018 -0500: 242609d9ad73083ea13099760f8f0678a4befbf8
## Saving to 03_expression_infection_20180822-v20180822.rda.xz
LS0tCnRpdGxlOiAiTC4gcGFuYW1lbnNpcyAyMDE4MDgyMjogRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gb2YgaW5mZWN0ZWQgUEJNQ3MuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB3aWR0aDogMzAwCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCiAgQmlvY1N0eWxlOjpodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KYm9keSwgdGQgewogIGZvbnQtc2l6ZTogMTZweDsKfQpjb2RlLnJ7CiAgZm9udC1zaXplOiAxNnB4Owp9CnByZSB7CiBmb250LXNpemU6IDE2cHgKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSgiaHBnbHRvb2xzIikKdHQgPC0gZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgd2lkdGg9MTIwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdD0iJVklbSVkIikKcHJldmlvdXNfZmlsZSA8LSAiMDJfZXN0aW1hdGlvbl9pbmZlY3Rpb25fMjAxODA4MjIuUm1kIgp2ZXIgPC0gIjIwMTgwODIyIgoKdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKQpybWRfZmlsZSA8LSAiMDNfZXhwcmVzc2lvbl9pbmZlY3Rpb25fMjAxODA4MjIuUm1kIgpgYGAKCiMgUEJNQyBJbmZlY3Rpb24gRGlmZmVyZW50aWFsIEV4cHJlc3Npb24sIEluZmVjdGlvbjogYHIgdmVyYCBSdW5kYXRlOiBgciBydW5kYXRlYAoKVGhpcyBkb2N1bWVudCB0dXJucyB0byB0aGUgaW5mZWN0aW9uIG9mIFBCTUMgY2VsbHMgd2l0aCBMLnBhbmFtZW5zaXMuICBUaGlzIGRhdGEKaXMgcGFydGljdWxhcmx5IHN0cmFuZ2VseSBhZmZlY3RlZCBieSB0aGUgZGlmZmVyZW50IHN0cmFpbnMgdXNlZCB0byBpbmZlY3QgdGhlCmNlbGxzLCBhbmQgYXMgYSByZXN1bHQgaXMgYm90aCB1c2VmdWwgYW5kIHRyb3VibGluZy4KCkdpdmVuIHRoZSBvYnNlcnZhdGlvbnMgYWJvdmUsIHdlIGhhdmUgc29tZSBpZGVhcyBvZiB3YXlzIHRvIHBhc3MgdGhlIGRhdGEgZm9yCmRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzIHdoaWNoIG1heSBvciBtYXkgbm90IGJlICdiZXR0ZXInLiAgTGV0cyB0cnkKc29tZSBhbmQgc2VlIHdoYXQgaGFwcGVucy4KCiMjIENyZWF0ZSBkYXRhIHNldHMgdG8gY29tcGFyZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcwoKR2l2ZW4gdGhlIGFib3ZlIHdheXMgdG8gbWFzc2FnZSB0aGUgZGF0YSwgbGV0cyB1c2UgYSBmZXcgb2YgdGhlbSBmb3IKbGltbWEvZGVzZXEvZWRnZXIuIFRoZSBtYWluIGNhdmVhdCBpbiB0aGlzIGlzIHRoYXQgdGhvc2UgdG9vbHMgcmVhbGx5IGRvIGV4cGVjdApzcGVjaWZpYyBkaXN0cmlidXRpb25zIG9mIGRhdGEgd2hpY2ggd2UgaG9ycmlibHkgdmlvbGF0ZSBpZiB3ZSB1c2UgbG9nMigpIGRhdGEsCndoaWNoIGlzIHdoeSBpbiB0aGUgcHJldmlvdXMgYmxvY2tzIEkgbmFtZWQgdGhlbSBsMmJsYWhibGFoLCB0aHVzIHdlIGNhbiBkbyB0aGUKc2FtZSBzZXRzIG9mIG5vcm1hbGl6YXRpb24gYnV0IHdpdGhvdXQgdGhhdCBhbmQgZm9yY2libHkgcHVzaCB0aGUgcmVzdWx0aW5nIGRhdGEKaW50byBsaW1tYS9lZGdlci9kZXNlcS4KCiMgVGhlIG5lZ2F0aXZlIGNvbnRyb2wKCkV2ZXJ5dGhpbmcgSSBkaWQgaW4gMDJfZXN0aW1hdGlvbl9pbmZlY3Rpb24uaHRtbCBzdWdnZXN0cyB0aGF0IHRoZXJlIGFyZSBubwpzaWduaWZpY2FudCBkaWZmZXJlbmNlcyB2aXNpYmxlIGlmIG9uZSBsb29rcyBqdXN0IGF0IGNocm9uaWMvc2VsZi1oZWFsaW5nIGluCnRoaXMgZGF0YS4gIEZ1cnRoZXIgdGVzdGluZyBoYXMgc2VlbWluZ2x5IHByb3ZlbiB0aGlzIHN0YXRlbWVudCwgYXMgYSByZXN1bHQKbW9zdCBvZiB0aGUgZm9sbG93aW5nIGFuYWx5c2VzIHdpbGwgbG9vayBhdCBjaHJvbmljL3VuaW5mZWN0ZWQgYW5kCnNlbGYtaGVhbGluZy91bmluZmVjdGVkIGZvbGxvd2VkIGJ5IGF0dGVtcHRzIHRvIHJlY29uY2lsZSB0aG9zZSByZXN1bHRzLgoKIyMgRmlsdGVyIHRoZSBkYXRhCgpUbyBzYXZlIHNvbWUgdGltZSBhbmQgYW5ub3lhbmNlIHdpdGggc3ZhLCBsZXRzIGZpbHRlciB0aGUgZGF0YSBub3cuICBJbgphZGRpdGlvbiwgd3JpdGUgZG93biBhIHNtYWxsIGZ1bmN0aW9uIHVzZWQgdG8gZXh0cmFjdCB0aGUgc2V0cyBvZiBzaWduaWZpY2FudApnZW5lcyBhY3Jvc3MgZGlmZmVyZW50IGNvbnRyYXN0cyAobm90YWJseSBzZWxmL3VuaW5mZWN0ZWQgdnMuIGNocm9uaWMvdW5pbmZlY3RlZCkuCgpgYGB7ciBmaWx0ZXJ9CmhzX2luZl9maWx0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX2Nkc19pbmYsIGZpbHRlcj1UUlVFKSkKaHNfdW5pbmZfZmlsdCA8LSBzbShub3JtYWxpemVfZXhwdChoc19jZHNfdW5pbmYsIGZpbHRlcj1UUlVFKSkKa2VlcGVycyA8LSBsaXN0KCJzaF9uaWwiID0gYygic2giLCAidW5pbmYiKSwKICAgICAgICAgICAgICAgICJjaF9uaWwiID0gYygiY2hyIiwgInVuaW5mIiksCiAgICAgICAgICAgICAgICAiY2hfc2giID0gYygiY2hyIiwgInNoIikpCmBgYAoKIyMgTm8tYmF0Y2ggZGF0YQoKSW4gdGhlIGZvbGxvd2luZyBibG9jaywgSSB3aWxsIHRha2UgdGhlIGNvbXBhcmlzb25zIHBlcmZvcm1lZCB3aXRob3V0IGFueSBiYXRjaAppbiB0aGUgbW9kZWwvYWRqdXN0bWVudCBhbmQgdXNlIHRoZW0gdG8gc2VhcmNoIGZvciBzaGFyZWQvdW5pcXVlIGdlbmVzIGFtb25nIHRoZQpzZWxmLWhlYWxpbmcgdnMuIHVuaW5mZWN0ZWQgYW5kIHRoZSBjaHJvbmljIHZzLiB1bmluZmVjdGVkLgoKIyMjIFJldmlldyBub2JhdGNoIHBjYQoKYGBge3IgcmV2aWV3X25vYmF0Y2h9CmhzX3BhaXJ3aXNlX25vYmF0Y2hfcGNhIDwtIHNtKHBsb3RfcGNhKGhzX2luZl9maWx0LCBjb252ZXJ0PSJjcG0iLCB0cmFuc2Zvcm09ImxvZzIiKSkKaHNfcGFpcndpc2Vfbm9iYXRjaF9wY2EkcGxvdApgYGAKCmBgYHtyIHRlc3RfY2hyX3NoMDEsIGZpZy5zaG93PSJoaWRlIn0KaHNfcGFpcndpc2Vfbm9iYXRjaCA8LSBzbShhbGxfcGFpcndpc2UoaHNfdW5pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX2Vic2VxPUZBTFNFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X25vYmF0Y2hfY29udHItdnt2ZXJ9Lnhsc3giKQpoc19jb21iaW5lZF9ub2JhdGNoIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKAogIGhzX3BhaXJ3aXNlX25vYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSwKICBrZWVwZXJzPWtlZXBlcnMpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3Rfbm9iYXRjaF9zaWctdnt2ZXJ9Lnhsc3giKQpoc19zaWdfbm9iYXRjaCA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIGhzX2NvbWJpbmVkX25vYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSkpCmhzX3NpZ19ub2JhdGNoJGRlc2VxJGNvdW50cwpgYGAKCmBgYHtyIHBsb3RfdGVzdF9jaHJfc2gwMX0KbGltbWFfZGVzZXFfb3JkZXIgPC0gcmFua19vcmRlcl9zY2F0dGVyKAogIGhzX3BhaXJ3aXNlX25vYmF0Y2gsCiAgZmlyc3RfdHlwZT0ibGltbWEiLCBzZWNvbmRfdHlwZT0iZGVzZXEiLAogIGZpcnN0X3RhYmxlPTEsIHNlY29uZF90YWJsZT0xKQpsaW1tYV9kZXNlcV9vcmRlciRwbG90CnVwX2xzdCA8LSBsaXN0KAogICJzaF91cCIgPSByb3duYW1lcyhoc19zaWdfbm9iYXRjaFtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX25vYmF0Y2hbWyJkZXNlcSJdXVtbInVwcyJdXVtbImNoX25pbCJdXSkpCm5vYmF0Y2hfdXBfdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9dXBfbHN0KQpWZW5uZXJhYmxlOjpwbG90KG5vYmF0Y2hfdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQoKIyMgTWFyaWEtQWRlbGFpZGEgYW5kIE5hamliIGFza2VkIGFib3V0IGNvbXBhcmluZyB0aGUgZm9sbG93aW5nIHBhaXIgb2YgZGF0YSBhZ2FpbnN0CiMjIFRoZSBpbnRlcnNlY3Rpb24gb2YgYSBidW5jaCBvZiBzdHVmZiBsYXRlci4uLiAgU28gZG9uJ3QgZm9yZ2V0IHRoaXMhCiMjIFRoaXMgZ2l2ZXMgbWUgdGhlIGdlbmVzIG9ubHkgdXAgaW4gc2VsZiB2cy4gbmlsCm5vYmF0Y2hfdXBfc2hfc29sbyA8LSBub2JhdGNoX3VwX3Zlbm5ASW50ZXJzZWN0aW9uU2V0c1tbIjEwIl1dCiMjIGFuZCBjaCB2cyBuaWwKbm9iYXRjaF91cF9jaF9zb2xvIDwtIG5vYmF0Y2hfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzW1siMDEiXV0KCmRvd25fbHN0IDwtIGxpc3QoCiAgInNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX25vYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfbm9iYXRjaFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pKQpub2JhdGNoX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9ZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3Qobm9iYXRjaF9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKYGBgCgojIyBBZGQgcGF0aWVudCB0byB0aGUgbW9kZWwKClJlcGVhdCB0aGUgcHJldmlvdXMgc2V0IG9mIGFuYWx5c2VzIHdpdGggZDEwNy8xMDgvMTEwIGluIHRoZSBtb2RlbC4KCiMjIyBSZXZpZXcgcGNhCgpgYGB7ciByZXZpZXdfYmF0Y2h9CmhzX3BhaXJ3aXNlX2JhdGNoX3BjYSA8LSBzbShwbG90X3BjYShoc19pbmZfZmlsdCwgYmF0Y2g9ImxpbW1hIiwgY29udmVydD0iY3BtIiwgdHJhbnNmb3JtPSJsb2cyIikpCmhzX3BhaXJ3aXNlX2JhdGNoX3BjYSRwbG90CmBgYAoKYGBge3IgdGVzdF9jaHJfc2gwMiwgZmlnLnNob3c9ImhpZGUifQpoc19wYWlyd2lzZV9iYXRjaCA8LSBzbShhbGxfcGFpcndpc2UoaHNfdW5pbmZfZmlsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2JhdGNoPVRSVUUsIGRvX2Vic2VxPUZBTFNFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X3BhdGJhdGNoX2NvbnRyLXZ7dmVyfS54bHN4IikKaHNfY29tYmluZWRfYmF0Y2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgaHNfcGFpcndpc2VfYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSwKICBrZWVwZXJzPWtlZXBlcnMpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcGF0YmF0Y2hfc2lnLXZ7dmVyfS54bHN4IikKaHNfc2lnX2JhdGNoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgaHNfY29tYmluZWRfYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSkpCmhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1siY291bnRzIl1dCmBgYAoKYGBge3IgcGxvdF90ZXN0X2NoYXJfc2gwMn0KdXBfbHN0IDwtIGxpc3QoCiAgInNoX3VwIiA9IHJvd25hbWVzKGhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX2JhdGNoW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJjaF9uaWwiXV0pKQpiYXRjaF91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz11cF9sc3QpCnN1bW1hcnkoYmF0Y2hfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzKQpWZW5uZXJhYmxlOjpwbG90KGJhdGNoX3VwX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKZG93bl9sc3QgPC0gbGlzdCgKICAic2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siY2hfbmlsIl1dKSkKYmF0Y2hfZG93bl92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1kb3duX2xzdCkKVmVubmVyYWJsZTo6cGxvdChiYXRjaF9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKc3VtbWFyeShiYXRjaF9kb3duX3Zlbm5ASW50ZXJzZWN0aW9uU2V0cykKCnNpbWlsYXIgPC0gY29tcGFyZV9kZV9yZXN1bHRzKGhzX2NvbWJpbmVkX25vYmF0Y2gsIGhzX2NvbWJpbmVkX2JhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JfbWV0aG9kPSJzcGVhcm1hbiIpCnNpbWlsYXJbWyJyZXN1bHQiXV1bWyJkZXNlcSJdXQpgYGAKCiMjIFdyaXRlIGFuIGV4Y2VsIHdvcmtib29rIHVzaW5nIHRoZSBiYXRjaCBkYXRhLgoKVGhlIGZvbGxvd2luZyBibG9jayB3cml0ZXMgb3V0IHRoZSB1bmlxdWUvc2hhcmVkIGdlbmVzIG9ic2VydmVkIGFtb25nIHRoZQpjb250cmFzdHMgd2hpY2ggaW5jbHVkZWQgZG9ub3IgaW4gdGhlIG1vZGVsLgoKYGBge3IgY2hzaF92ZW5uMDJ9CmtlcHRfY29sdW1ucyA8LSBjKCJlbnNlbWJsdHJhbnNjcmlwdGlkIiwgImVuc2VtYmxnZW5laWQiLCAiZGVzY3JpcHRpb24iLAogICAgICAgICAgICAgICAgICAiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpCnN0YXJ0X2RhdGEgPC0gaHNfc2lnX2JhdGNoW1siZGVzZXEiXV0Kc2hfdXBfc29sb19nZW5lcyA8LSBiYXRjaF91cF92ZW5uQEludGVyc2VjdGlvblNldHNbWyIxMCJdXQpjaF91cF9zb2xvX2dlbmVzIDwtIGJhdGNoX3VwX3Zlbm5ASW50ZXJzZWN0aW9uU2V0c1tbIjAxIl1dCnNoY2hfdXBfc2hhcmVkX2dlbmVzIDwtIGJhdGNoX3VwX3Zlbm5ASW50ZXJzZWN0aW9uU2V0c1tbIjExIl1dCnNoX2Rvd25fc29sb19nZW5lcyA8LSBiYXRjaF9kb3duX3Zlbm5ASW50ZXJzZWN0aW9uU2V0c1tbIjEwIl1dCmNoX2Rvd25fc29sb19nZW5lcyA8LSBiYXRjaF9kb3duX3Zlbm5ASW50ZXJzZWN0aW9uU2V0c1tbIjAxIl1dCnNoY2hfZG93bl9zaGFyZWRfZ2VuZXMgPC0gYmF0Y2hfZG93bl92ZW5uQEludGVyc2VjdGlvblNldHNbWyIxMSJdXQoKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoCiAgZGF0YT1zdGFydF9kYXRhW1sidXBzIl1dW1sic2hfbmlsIl1dW3NoX3VwX3NvbG9fZ2VuZXMsIGtlcHRfY29sdW1uc10sCiAgc2hlZXQ9InNoX3VwX3NvbG8iKQp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscygKICBkYXRhPXN0YXJ0X2RhdGFbWyJ1cHMiXV1bWyJjaF9uaWwiXV1bY2hfdXBfc29sb19nZW5lcywga2VwdF9jb2x1bW5zXSwKICBzaGVldD0iY2hfdXBfc29sbyIsIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSkKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoCiAgZGF0YT1zdGFydF9kYXRhW1sidXBzIl1dW1siY2hfbmlsIl1dW3NoY2hfdXBfc2hhcmVkX2dlbmVzLCBrZXB0X2NvbHVtbnNdLAogIHNoZWV0PSJzaGNoX3VwX3NoYXJlZCIsIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSkKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoCiAgZGF0YT1zdGFydF9kYXRhW1siZG93bnMiXV1bWyJzaF9uaWwiXV1bc2hfZG93bl9zb2xvX2dlbmVzLCBrZXB0X2NvbHVtbnNdLAogIHNoZWV0PSJzaF9kb3duX3NvbG8iKQp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscygKICBkYXRhPXN0YXJ0X2RhdGFbWyJkb3ducyJdXVtbImNoX25pbCJdXVtjaF9kb3duX3NvbG9fZ2VuZXMsIGtlcHRfY29sdW1uc10sCiAgc2hlZXQ9ImNoX2Rvd25fc29sbyIsIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSkKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoCiAgZGF0YT1zdGFydF9kYXRhW1siZG93bnMiXV1bWyJjaF9uaWwiXV1bc2hjaF9kb3duX3NoYXJlZF9nZW5lcywga2VwdF9jb2x1bW5zXSwKICBzaGVldD0ic2hjaF9kb3duX3NoYXJlZCIsIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSwKICBleGNlbD1wYXN0ZTAoImV4Y2VsL2ZpZ3VyZV81YV9zdHVmZi12IiwgdmVyLCAiLnhsc3giKSkKYGBgCgojIyBBZGQgc3N2YSBpbnRvIHRoZSBtaXgKClJlcGVhdCwgdGhpcyB0aW1lIGF0dG1lcHRpbmcgdG8gdGFtcCBkb3duIHRoZSB2YXJpYW5jZSBieSBwZXJzb24uCgojIyMgUmV2aWV3IHNzdmEKCmBgYHtyIHJldmlld19zc3ZhfQpoc19wYWlyd2lzZV9zc3ZhX3BjYSA8LSBzbShwbG90X3BjYShoc19pbmZfZmlsdCwgYmF0Y2g9InNzdmEiLCBub3JtPSJxdWFudCIsIHRyYW5zZm9ybT0ibG9nMiIpKQpoc19wYWlyd2lzZV9zc3ZhX3BjYSRwbG90CmBgYAoKYGBge3IgdGVzdF9jaHJfc2gwNSwgZmlnLnNob3c9ImhpZGUifQpoc19wYWlyd2lzZV9zc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShoc191bmluZl9maWx0LCBtb2RlbF9iYXRjaD0ic3N2YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFsbGVsPUZBTFNFLCBkb19lYnNlcT1GQUxTRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9mc3ZhX2NvbnRyLXZ7dmVyfS54bHN4IikKaHNfY29tYmluZWRfc3N2YSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcygKICBoc19wYWlyd2lzZV9zc3ZhLAogIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAga2VlcGVycz1rZWVwZXJzKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X2ZzdmFfc2lnLXZ7dmVyfS54bHN4IikKaHNfc2lnX3NzdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBoc19jb21iaW5lZF9zc3ZhLAogIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpoc19zaWdfc3N2YSRkZXNlcSRjb3VudHMKYGBgCgpgYGB7ciBwbG90X3Rlc3RfY2hyX3NoMDV9CnVwX2xzdCA8LSBsaXN0KAogICJzaF91cCIgPSByb3duYW1lcyhoc19zaWdfc3N2YVtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX3NzdmFbWyJkZXNlcSJdXVtbInVwcyJdXVtbImNoX25pbCJdXSkpCnNzdmFfdXBfdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9dXBfbHN0KQpzdW1tYXJ5KHNzdmFfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzKQpWZW5uZXJhYmxlOjpwbG90KHNzdmFfdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkb3duX2xzdCA8LSBsaXN0KAogICJzaF9kb3duIiA9IHJvd25hbWVzKGhzX3NpZ19zc3ZhW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbInNoX25pbCJdXSksCiAgImNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX3NzdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siY2hfbmlsIl1dKSkKc3N2YV9kb3duX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWRvd25fbHN0KQpWZW5uZXJhYmxlOjpwbG90KHNzdmFfZG93bl92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCnN1bW1hcnkoc3N2YV9kb3duX3Zlbm5ASW50ZXJzZWN0aW9uU2V0cykKCnNpbWlsYXIgPC0gc20oY29tcGFyZV9kZV9yZXN1bHRzKGhzX2NvbWJpbmVkX25vYmF0Y2gsIGhzX2NvbWJpbmVkX3NzdmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcl9tZXRob2Q9InNwZWFybWFuIikpCnNpbWlsYXIkcmVzdWx0JGRlc2VxCnNpbWlsYXIgPC0gc20oY29tcGFyZV9kZV9yZXN1bHRzKGhzX2NvbWJpbmVkX2JhdGNoLCBoc19jb21iaW5lZF9zc3ZhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JfbWV0aG9kPSJzcGVhcm1hbiIpKQpzaW1pbGFyJHJlc3VsdCRkZXNlcQpgYGAKCiMjIGZzdmEKClJlcGVhdCBhZ2FpbiB1c2luZyBmc3ZhLgoKIyMjIFJldmlldyBmc3ZhCgpgYGB7ciByZXZpZXdfZnN2YX0KaHNfcGFpcndpc2VfZnN2YV9wY2EgPC0gc20ocGxvdF9wY2EoaHNfaW5mX2ZpbHQsIGJhdGNoPSJmc3ZhIiwgbm9ybT0icXVhbnQiLCB0cmFuc2Zvcm09ImxvZzIiKSkKaHNfcGFpcndpc2VfZnN2YV9wY2EkcGxvdApgYGAKCmBgYHtyIHRlc3RfY2hyX3NoMDNfZnN2YSwgZmlnLnNob3c9ImhpZGUifQpoc19wYWlyd2lzZV9mc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShoc191bmluZl9maWx0LCBtb2RlbF9iYXRjaD0iZnN2YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFsbGVsPUZBTFNFLCBkb19lYnNlcT1GQUxTRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9mc3ZhX2NvbnRyLXZ7dmVyfS54bHN4IikKaHNfY29tYmluZWRfZnN2YSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcygKICBoc19wYWlyd2lzZV9mc3ZhLAogIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAga2VlcGVycz1rZWVwZXJzKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X2ZzdmFfc2lnLXZ7dmVyfS54bHN4IikKaHNfc2lnX2ZzdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBoc19jb21iaW5lZF9mc3ZhLAogIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpgYGAKCmBgYHtyIHBsb3RfdGVzdF9jaHJfc2gwM19mc3ZhfQp1cF9sc3QgPC0gbGlzdCgKICAic2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX2ZzdmFbWyJkZXNlcSJdXVtbInVwcyJdXVtbInNoX25pbCJdXSksCiAgImNoX3VwIiA9IHJvd25hbWVzKGhzX3NpZ19mc3ZhW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJjaF9uaWwiXV0pKQpmc3ZhX3VwX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXVwX2xzdCkKc3VtbWFyeShmc3ZhX3VwX3Zlbm5ASW50ZXJzZWN0aW9uU2V0cykKVmVubmVyYWJsZTo6cGxvdChmc3ZhX3VwX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKZG93bl9sc3QgPC0gbGlzdCgKICAic2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfZnN2YVtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF9kb3duIiA9IHJvd25hbWVzKGhzX3NpZ19mc3ZhW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImNoX25pbCJdXSkpCmZzdmFfZG93bl92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1kb3duX2xzdCkKVmVubmVyYWJsZTo6cGxvdChmc3ZhX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpzdW1tYXJ5KGZzdmFfZG93bl92ZW5uQEludGVyc2VjdGlvblNldHMpCgojI2hzX3NpZ19mc3ZhJGRlc2VxJGNvdW50cyRjb21tb25fc29sb3NfZnN2YSA8LSBzbShzdWJzZXRfc2lnbmlmaWNhbnRzKGhzX3NpZ19mc3ZhKSkKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfbm9iYXRjaCwgaHNfY29tYmluZWRfZnN2YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfc3N2YSwgaHNfY29tYmluZWRfZnN2YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKYGBgCgojIyBUcnkgd2l0aCB0aGUgY29tYmF0IG1vZGlmaWVkIGRhdGEKClJlcGVhdCBvbmNlIGFnYWluLCB0aGlzIHRpbWUgdXNpbmcgY29tYmF0IHRvIHRyeSB0byBsaW1pdCB0aGUgY29udHJpYnV0aW9uIG9mCnRoZSBzdHJhaW4gdG8gdGhlIGRhdGEuICBJIGRvIG5vdCB0aGluayB3ZSB3aWxsIGV2ZXIgdXNlIHRoaXMgc2V0IG9mIGNvbnRyYXN0cywKc28gSSB3aWxsIGRlYWN0aXZhdGUgaXQgYnV0IGxlYXZlIGl0IGhlcmUgaWYgaXQgaXMgcmVxdWlyZWQgbGF0ZXIuCgpgYGB7ciB0ZXN0X2Nocl9zaDA0LCBmaWcuc2hvdz0iaGlkZSJ9Cm9sZF9jb25kaXRpb24gPC0gaHNfdW5pbmYkZGVzaWduJGNvbmRpdGlvbgpuYW1lcyhvbGRfY29uZGl0aW9uKSA8LSBoc191bmluZiRkZXNpZ24kc2FtcGxlaWQKbmV3X2NvbmRpdGlvbiA8LSBwYXN0ZTAoaHNfdW5pbmYkZGVzaWduJHN0YXRlLCAnXycsIGhzX3VuaW5mJGRlc2lnbiRkb25vcikKaHNfdW5pbmZfcmVjb25kIDwtIHNldF9leHB0X2ZhY3RvcnMoaHNfdW5pbmZfZmlsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InBhdGhvZ2Vuc3RyYWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uPW5ld19jb25kaXRpb24pCmNvbWJhdF9pbnB1dCA8LSBub3JtYWxpemVfZXhwdChoc191bmluZl9yZWNvbmQsIG5vcm09InF1YW50IiwgYmF0Y2g9ImNvbWJhdF9zY2FsZSIpCmNvbWJhdF9pbnB1dCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKGNvbWJhdF9pbnB1dCwgZmFjdD1vbGRfY29uZGl0aW9uKQpjb21iYXRfaW5wdXQgPC0gc2V0X2V4cHRfY29sb3JzKGNvbWJhdF9pbnB1dCwgY29sb3JzPWMoImdyZWVuIiwiYmx1ZSIsInJlZCIpKQpgYGAKCiMjIyBSZXZpZXcgY29tYmF0CgpgYGB7ciByZXZpZXdfY29tYmF0fQpoc19wYWlyd2lzZV9jb21iYXRfcGNhIDwtIHBsb3RfcGNhKGNvbWJhdF9pbnB1dCkKaHNfcGFpcndpc2VfY29tYmF0X3BjYSRwbG90CmBgYAoKYGBge3IgcGVyZm9ybV9jb21iYXR9CmhzX3BhaXJ3aXNlX2NvbWJhdHBhdGggPC0gc20oYWxsX3BhaXJ3aXNlKGNvbWJhdF9pbnB1dCwgbW9kZWxfYmF0Y2g9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlPVRSVUUpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfY29tYmF0cGF0aF9jb250ci12e3Zlcn0ueGxzeCIpCmhzX2NvbWJpbmVkX2NvbWJhdHBhdGggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgaHNfcGFpcndpc2VfY29tYmF0cGF0aCwKICBleGNlbD1leGNlbF9maWxlLAogIGtlZXBlcnM9a2VlcGVycykpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9jb21iYXRwYXRoX3NpZy12e3Zlcn0ueGxzeCIpCmhzX3NpZ19jb21iYXRwYXRoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgaHNfY29tYmluZWRfY29tYmF0cGF0aCwKICBleGNlbD1leGNlbF9maWxlKSkKaHNfc2lnX2NvbWJhdHBhdGgkZGVzZXEkY291bnRzCmBgYAoKYGBge3IgcGxvdF90ZXN0X2Nocl9zaDA0X2NvbWJhdH0KdXBfbHN0IDwtIGxpc3QoCiAgInNoX3VwIiA9IHJvd25hbWVzKGhzX3NpZ19jb21iYXRwYXRoW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF91cCIgPSByb3duYW1lcyhoc19zaWdfY29tYmF0cGF0aFtbImRlc2VxIl1dW1sidXBzIl1dW1siY2hfbmlsIl1dKSkKY29tYmF0cGF0aF91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz11cF9sc3QpCnN1bW1hcnkoY29tYmF0cGF0aF91cF92ZW5uQEludGVyc2VjdGlvblNldHMpClZlbm5lcmFibGU6OnBsb3QoY29tYmF0cGF0aF91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRvd25fbHN0IDwtIGxpc3QoCiAgInNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX2NvbWJhdHBhdGhbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfY29tYmF0cGF0aFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pKQpjb21iYXRwYXRoX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9ZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3QoY29tYmF0cGF0aF9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKc3VtbWFyeShjb21iYXRwYXRoX2Rvd25fdmVubkBJbnRlcnNlY3Rpb25TZXRzKQoKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfbm9iYXRjaCwgaHNfY29tYmluZWRfY29tYmF0cGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfZnN2YSwgaHNfY29tYmluZWRfY29tYmF0cGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKIyMgT1VDSCEKYGBgCgojIyBDb21wYXJlIERFIHJlc3VsdHMKCkZvciBlYWNoIG9mIHRoZSBmb2xsb3dpbmcsIHBlcmZvcm0gYSBzaW1wbGUgREUgYW5kIHNlZSB3aGF0IGhhcHBlbnM6CgoxLiAgbm8gdW5pbmZlY3RlZCBzdHJhaW4gYXMgYmF0Y2gsIHRyeSB0byBjb21wYXJlIGVhY2ggb2YgdGhlIDMgcGF0aWVudHMgY2hyb25pYy9zZWxmCjIuICBubyB1bmluZmVjdGVkIHN0cmFpbiBhcyBiYXRjaCwgdHJ5IHRvIGNvbXBhcmUgY2hyb25pYy9zZWxmIGZvciBhbGwKMy4gIFJlcGVhdCAjMSBhYm92ZSB3aXRoIHVuaW5mZWN0ZWQKNC4gIFJlcGVhdCAjMiB3aXRoIHVuaW5mZWN0ZWQKCiMjIyBERTogaW5jbHVkZSB1bmluZmVjdGVkLCB1c2Ugc3RyYWluIGFzIGJhdGNoCgpUaGUgZGF0YSB1c2VkIGluIHRoZSBmb2xsb3dpbmcgaXMgdGhlIHF1YW50aWxlKGNwbShmaWx0ZXIoKSkpIHdoZXJlIHRoZQpjb25kaXRpb24gd2FzIHNldCB0byBhIGNvbmNhdGVuYXRpb24gb2YgcGF0aWVudCBhbmQgaGVhbGluZyBzdGF0ZSwgY29tYmF0IHdhcwphbHNvIHBlcmZvcm1lZCwgc28gd2Ugbm8gbG9uZ2VyIHdhbnQgYmF0Y2ggaW4gdGhlIGV4cGVyaW1lbnRhbCBtb2RlbCBhbmQgYWxzbyB3ZQpuZWVkIHRvIHBhc3MgJ2ZvcmNlPVRSVUUnIGJlY2F1c2UgZGVzZXEvZWRnZXIgd2lsbCBuZWVkIHRvIGJlIGNvZXJjZWQgaW50bwphY2NlcHRpbmcgdGhlc2UgbW9kaWZpZWQgZGF0YS4KCmBgYHtyIGRlX2NvbXBhcmlzb25zLCBmaWcuc2hvdz0iaGlkZSJ9CmhzX2luZiRjb25kaXRpb24KIyMgU3RhcnQgYnkgbGVhdmluZyB0aGUgZGF0YSByZWxhdGl2ZWx5IGFsb25lLCBlc3BlY2lhbGx5IG5vdGluZyB0aGF0IHdlIGRvIG5vdAojIyBoYXZlIGEgdXNhYmxlIGJhdGNoIGJ5IGRlZmF1bHQuCmhzX3VuaW5mX2ZpbHR2MiA8LSBoc191bmluZl9maWx0CmRvbm9yX3N0YXRlIDwtIHBhc3RlMChoc191bmluZl9maWx0djIkZGVzaWduJHN0YXRlLCAiXyIsIGhzX3VuaW5mX2ZpbHR2MiRkZXNpZ24kZG9ub3IpCmhzX3VuaW5mX2ZpbHR2MiA8LSBzZXRfZXhwdF9mYWN0b3JzKGhzX3VuaW5mX2ZpbHR2MiwgY29uZGl0aW9uPWRvbm9yX3N0YXRlKQoKdW5pbmZfcGF0aWVudF9rZWVwZXJzIDwtIGxpc3QoCiAgICAiZDEwN19jaHVuIiA9IGMoImNocm9uaWNfZDEwNyIsICJ1bmluZmVjdGVkX2QxMDciKSwKICAgICJkMTA3X3NodW4iID0gYygic2VsZl9oZWFsX2QxMDciLCAidW5pbmZlY3RlZF9kMTA3IiksCiAgICAiZDEwN19jaHNoIiA9IGMoImNocm9uaWNfZDEwNyIsICJzZWxmX2hlYWxfZDEwNyIpLAogICAgImQxMDhfY2h1biIgPSBjKCJjaHJvbmljX2QxMDgiLCAidW5pbmZlY3RlZF9kMTA4IiksCiAgICAiZDEwOF9zaHVuIiA9IGMoInNlbGZfaGVhbF9kMTA4IiwgInVuaW5mZWN0ZWRfZDEwOCIpLAogICAgImQxMDhfY2hzaCIgPSBjKCJjaHJvbmljX2QxMDgiLCAic2VsZl9oZWFsX2QxMDgiKSwKICAgICJkMTEwX2NodW4iID0gYygiY2hyb25pY19kMTEwIiwgInVuaW5mZWN0ZWRfZDExMCIpLAogICAgImQxMTBfc2h1biIgPSBjKCJzZWxmX2hlYWxfZDExMCIsICJ1bmluZmVjdGVkX2QxMTAiKSwKICAgICJkMTEwX2Noc2giID0gYygiY2hyb25pY19kMTEwIiwgInNlbGZfaGVhbF9kMTEwIikpCgpoc191bmluZl9maWx0djJfcGFpcndpc2UgPC0gc20oYWxsX3BhaXJ3aXNlKGhzX3VuaW5mX2ZpbHR2MiwgcGFyYWxsZWw9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxfYmF0Y2g9RkFMU0UsIGRvX2Vic2VxPUZBTFNFKSkKaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKAogIGhzX3VuaW5mX2ZpbHR2Ml9wYWlyd2lzZSwKICBrZWVwZXJzPXVuaW5mX3BhdGllbnRfa2VlcGVycywKICBleGNlbD1wYXN0ZTAoImV4Y2VsL2hzX2luZmVjdF9wYXRpZW50X25vYmF0Y2gtdiIsIHZlciwgIi54bHN4IikpKQpoc191bmluZl9maWx0djJfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkLCBhY2NvcmRpbmdfdG89ImRlc2VxIiwKICBleGNlbD1wYXN0ZTAoImV4Y2VsL2hzX2luZmVjdF9wYXRpZW50X25vYmF0Y2hfc2lnLXYiLCB2ZXIsICIueGxzeCIpKSkKCiMjaHNfdW5pbmZfZmlsdHYzX3BhaXJ3aXNlIDwtIGFsbF9wYWlyd2lzZShoc191bmluZl9maWx0djIsIG1vZGVsX2JhdGNoPSJzdmFzZXEiLCBzdXJyb2dhdGVzPTEpCiMjaHNfdW5pbmZfZmlsdHYzX2NvbWJpbmVkIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGhzX3VuaW5mX2ZpbHR2M19wYWlyd2lzZSwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz11bmluZl9wYXRpZW50X2tlZXBlcnMsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvaHNfaW5mZWN0X3BhdGllbnRfZnN2YS12IiwgdmVyLCAiLnhsc3giKSkpCiMjaHNfdW5pbmZfZmlsdHYzX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKGhzX3VuaW5mX2ZpbHR2M19jb21iaW5lZCwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9oc19pbmZlY3RfcGF0aWVudF9mc3ZhX3NpZy12IiwgdmVyLCAiLnhsc3giKSkpCmBgYAoKIyMgTWFrZSBzb21lIFZlbm5zCgpOb3cgd2Ugd2FudCB0byBsb29rIGF0IGludGVyc2VjdGlvbnMgZnJvbSB0aGUgcGVyc3BlY3RpdmUgb2YgY29udHJhc3RzIHBlcmZvcm1lZApjb21wYXJpbmcgdGhlIHNlbGYtaGVhbGluZy9jaHJvbmljIHZzLiB1bmluZmVjdGVkIGZvciB0aGUgdGhyZWUgZG9ub3JzIHNlcGFyYXRlbHkuCgojIyMgUGVyZm9ybSB2ZW5ucyBvZiBzZWxmLWhlYWxpbmcgdnMuIHVuaW5mZWN0ZWQKClRoaXMgdGltZSBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgZG9ub3JzOiBzZWxmLWhlYWxpbmcgdXAgdnMuIHVuaW5mZWN0ZWQuCgpgYGB7ciB2ZW5uX3VwX2Rlc2VxX3NofQp1cF9zaWcgPC0gaHNfdW5pbmZfZmlsdHYyX3NpZyRkZXNlcSR1cHMKCiMjIERvIHRoaXMgaW4gYSB3YXkgd2hpY2ggaXMgbm90IHN0dXBpZC4uLgpjb21wX2xzdCA8LSBsaXN0KAogICJkb25vcl8xMDciID0gcm93bmFtZXModXBfc2lnW1siZDEwN19zaHVuIl1dKSwKICAiZG9ub3JfMTA4IiA9IHJvd25hbWVzKHVwX3NpZ1tbImQxMDhfc2h1biJdXSksCiAgImRvbm9yXzExMCIgPSByb3duYW1lcyh1cF9zaWdbWyJkMTEwX3NodW4iXV0pKQpjb21wX3NodW5fdXAgPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWNvbXBfbHN0KQp1cF9yZXMgPC0gVmVubmVyYWJsZTo6cGxvdChjb21wX3NodW5fdXAsIGRvV2VpZ2h0cz1GQUxTRSkKCnNoYXJlZF9zaHVuX3VwIDwtIGNvbXBfc2h1bl91cEBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCmRlX3RhYmxlX3NoYXJlZF91cF9zaF9maXJzdCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDEwN19zaHVuIl1dW3NoYXJlZF9zaHVuX3VwLCBdCmRlX3RhYmxlX3NoYXJlZF91cF9zaF9zZWNvbmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMDhfc2h1biJdXVtzaGFyZWRfc2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfc2hfdGhpcmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMTBfc2h1biJdXVtzaGFyZWRfc2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfc2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF91cF9zaF9maXJzdFssIGMoImRlc2NyaXB0aW9uIiwgImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgZGVfdGFibGVfc2hhcmVkX3VwX3NoX3NlY29uZFssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgYnk9InJvdy5uYW1lcyIpCmRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwgPC0gbWVyZ2UoCiAgZGVfdGFibGVfc2hhcmVkX3VwX3NoX2FsbCwKICBkZV90YWJsZV9zaGFyZWRfdXBfc2hfdGhpcmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5Lng9IlJvdy5uYW1lcyIsIGJ5Lnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwpIDwtIGRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGxbWyJSb3cubmFtZXMiXV0KZGVfdGFibGVfc2hhcmVkX3VwX3NoX2FsbCA8LSBkZV90YWJsZV9zaGFyZWRfdXBfc2hfYWxsWywgLTFdCmNvbG5hbWVzKGRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwpIDwtIGMoImRlc2NyaXB0aW9uIiwgImxvZ2ZjXzEwNyIsICJhZGpwXzEwNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvZ2ZjXzEwOCIsICJhZGpwXzEwOCIsICJsb2dmY18xMTAiLCAiYWRqcF8xMTAiKQp3cml0ZS5jc3YoZGVfdGFibGVfc2hhcmVkX3VwX3NoX2FsbCwgZmlsZT0iaW1hZ2VzL2RlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwuY3N2IikKYGBgCgojIyMgUGVyZm9ybSB2ZW5ucyBvZiBjaHJvbmljIHZzLiB1bmluZmVjdGVkCgpUaGlzIHRpbWUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIGRvbm9yczogY2hyb25pYyB1cCB2cy4gdW5pbmZlY3RlZC4KCmBgYHtyIHZlbm5fdXBfZGVzZXFfY2hyfQp1cF9zaWcgPC0gaHNfdW5pbmZfZmlsdHYyX3NpZyRkZXNlcSR1cHMKY29tcF9sc3QgPC0gbGlzdCgKICAiZG9ub3JfMTA3IiA9IHJvd25hbWVzKHVwX3NpZ1tbImQxMDdfY2h1biJdXSksCiAgImRvbm9yXzEwOCIgPSByb3duYW1lcyh1cF9zaWdbWyJkMTA4X2NodW4iXV0pLAogICJkb25vcl8xMTAiID0gcm93bmFtZXModXBfc2lnW1siZDExMF9jaHVuIl1dKSkKY29tcF9jaHVuX3VwIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1jb21wX2xzdCkKdXBfcmVzIDwtIFZlbm5lcmFibGU6OnBsb3QoY29tcF9jaHVuX3VwLCBkb1dlaWdodHM9RkFMU0UpCgpzaGFyZWRfY2h1bl91cCA8LSBjb21wX2NodW5fdXBASW50ZXJzZWN0aW9uU2V0c1tbIjExMSJdXQpkZV90YWJsZV9zaGFyZWRfdXBfY2hfZmlyc3QgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMDdfY2h1biJdXVtzaGFyZWRfY2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfY2hfc2Vjb25kIDwtIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZFtbImRhdGEiXV1bWyJkMTA4X2NodW4iXV1bc2hhcmVkX2NodW5fdXAsIF0KZGVfdGFibGVfc2hhcmVkX3VwX2NoX3RoaXJkIDwtIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZFtbImRhdGEiXV1bWyJkMTEwX2NodW4iXV1bc2hhcmVkX2NodW5fdXAsIF0KZGVfdGFibGVfc2hhcmVkX3VwX2NoX2FsbCA8LSBtZXJnZSgKICBkZV90YWJsZV9zaGFyZWRfdXBfY2hfZmlyc3RbLCBjKCJkZXNjcmlwdGlvbiIsICJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGRlX3RhYmxlX3NoYXJlZF91cF9jaF9zZWNvbmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5PSJyb3cubmFtZXMiKQpkZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGwsCiAgZGVfdGFibGVfc2hhcmVkX3VwX2NoX3RoaXJkWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXSwKICBieS54PSJSb3cubmFtZXMiLCBieS55PSJyb3cubmFtZXMiKQpyb3duYW1lcyhkZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsKSA8LSBkZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsW1siUm93Lm5hbWVzIl1dCmRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGwgPC0gZGVfdGFibGVfc2hhcmVkX3VwX2NoX2FsbFssIC0xXQpjb2xuYW1lcyhkZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsKSA8LSBjKCJkZXNjcmlwdGlvbiIsICJsb2dmY18xMDciLCAiYWRqcF8xMDciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsb2dmY18xMDgiLCAiYWRqcF8xMDgiLCAibG9nZmNfMTEwIiwgImFkanBfMTEwIikKd3JpdGUuY3N2KGRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGwsIGZpbGU9ImltYWdlcy9kZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsLmNzdiIpCmBgYAoKIyMjIFBlcmZvcm0gdmVubnMgb2Ygc2VsZi1oZWFsaW5nIHZzLiB1bmluZmVjdGVkCgpUaGlzIHRpbWUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIGRvbm9yczogc2VsZi1oZWFsaW5nIGRvd24gdnMuIHVuaW5mZWN0ZWQuCgpgYGB7ciB2ZW5uX2Rvd25fZGVzZXFfc2h9CmRvd25fc2lnIDwtIGhzX3VuaW5mX2ZpbHR2Ml9zaWckZGVzZXEkZG93bnMKY29tcF9sc3QgPC0gbGlzdCgKICAiZG9ub3JfMTA3IiA9IHJvd25hbWVzKGRvd25fc2lnW1siZDEwN19zaHVuIl1dKSwKICAiZG9ub3JfMTA4IiA9IHJvd25hbWVzKGRvd25fc2lnW1siZDEwOF9zaHVuIl1dKSwKICAiZG9ub3JfMTEwIiA9IHJvd25hbWVzKGRvd25fc2lnW1siZDExMF9zaHVuIl1dKSkKY29tcF9zaHVuX2Rvd24gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWNvbXBfbHN0KQpkb3duX3JlcyA8LSBWZW5uZXJhYmxlOjpwbG90KGNvbXBfc2h1bl9kb3duLCBkb1dlaWdodHM9RkFMU0UpCgpzaGFyZWRfc2h1bl9kb3duIDwtIGNvbXBfc2h1bl9kb3duQEludGVyc2VjdGlvblNldHNbWyIxMTEiXV0KZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfZmlyc3QgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMDdfc2h1biJdXVtzaGFyZWRfc2h1bl9kb3duLCBdCmRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX3NlY29uZCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDEwOF9zaHVuIl1dW3NoYXJlZF9zaHVuX2Rvd24sIF0KZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfdGhpcmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMTBfc2h1biJdXVtzaGFyZWRfc2h1bl9kb3duLCBdCmRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbCA8LSBtZXJnZSgKICBkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9maXJzdFssIGMoImRlc2NyaXB0aW9uIiwgImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfc2Vjb25kWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXSwKICBieT0icm93Lm5hbWVzIikKZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbCwKICBkZV90YWJsZV9zaGFyZWRfZG93bl9zaF90aGlyZFssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgYnkueD0iUm93Lm5hbWVzIiwgYnkueT0icm93Lm5hbWVzIikKcm93bmFtZXMoZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsKSA8LSBkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9hbGxbWyJSb3cubmFtZXMiXV0KZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsIDwtIGRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbFssIC0xXQpjb2xuYW1lcyhkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9hbGwpIDwtIGMoImRlc2NyaXB0aW9uIiwgImxvZ2ZjXzEwNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWRqcF8xMDciLCAibG9nZmNfMTA4IiwgImFkanBfMTA4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsb2dmY18xMTAiLCAiYWRqcF8xMTAiKQp3cml0ZS5jc3YoZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsLCBmaWxlPSJpbWFnZXMvZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsLmNzdiIpCmBgYAoKIyMjIFBlcmZvcm0gdmVubnMgb2Ygc2VsZi1oZWFsaW5nIHZzLiB1bmluZmVjdGVkCgpUaGlzIHRpbWUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIGRvbm9yczogY2hyb25pYyBkb3duIHZzLiB1bmluZmVjdGVkLgoKYGBge3IgdmVubl9kb3duX2Rlc2VxX2Nocn0KZG93bl9zaWcgPC0gaHNfdW5pbmZfZmlsdHYyX3NpZyRkZXNlcSRkb3ducwpjb21wX2xzdCA8LSBsaXN0KAogICJkb25vcl8xMDciID0gcm93bmFtZXMoZG93bl9zaWdbWyJkMTA3X2NodW4iXV0pLAogICJkb25vcl8xMDgiID0gcm93bmFtZXMoZG93bl9zaWdbWyJkMTA4X2NodW4iXV0pLAogICJkb25vcl8xMTAiID0gcm93bmFtZXMoZG93bl9zaWdbWyJkMTEwX2NodW4iXV0pKQpjb21wX2NodW5fZG93biA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9Y29tcF9sc3QpCmRvd25fcmVzIDwtIFZlbm5lcmFibGU6OnBsb3QoY29tcF9jaHVuX2Rvd24sIGRvV2VpZ2h0cz1GQUxTRSkKCnNoYXJlZF9jaHVuX2Rvd24gPC0gY29tcF9jaHVuX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjExMSJdXQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9maXJzdCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDEwN19jaHVuIl1dW3NoYXJlZF9jaHVuX2Rvd24sIF0KZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfc2Vjb25kIDwtIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZFtbImRhdGEiXV1bWyJkMTA4X2NodW4iXV1bc2hhcmVkX2NodW5fZG93biwgXQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF90aGlyZCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDExMF9jaHVuIl1dW3NoYXJlZF9jaHVuX2Rvd24sIF0KZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX2ZpcnN0WywgYygiZGVzY3JpcHRpb24iLCAiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXSwKICBkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9zZWNvbmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5PSJyb3cubmFtZXMiKQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwgPC0gbWVyZ2UoCiAgZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsLAogIGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX3RoaXJkWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXSwKICBieS54PSJSb3cubmFtZXMiLCBieS55PSJyb3cubmFtZXMiKQpyb3duYW1lcyhkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwpIDwtIGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX2FsbFtbIlJvdy5uYW1lcyJdXQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwgPC0gZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsWywgLTFdCmNvbG5hbWVzKGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX2FsbCkgPC0gYygiZGVzY3JpcHRpb24iLCAibG9nZmNfMTA3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZGpwXzEwNyIsICJsb2dmY18xMDgiLCAiYWRqcF8xMDgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvZ2ZjXzExMCIsICJhZGpwXzExMCIpCndyaXRlLmNzdihkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwsIGZpbGU9ImltYWdlcy9kZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwuY3N2IikKYGBgCgpBdCB0aGlzIHBvaW50LCB3ZSBzaG91bGQgaGF2ZSBhIHNldCBvZiBnZW5lcyB3aGljaCBhcmUgdXAvZG93biBpbiB0aGUKc2VsZi91bmluZmVjdGVkIGFuZCBjaHJvbmljL3VuaW5mZWN0ZWQsIGtlcHQgaW4gdmFyaWFibGVzIHdpdGggbmFtZXMgbGlrZToKJ3NoYXJlZF9zaHVuX2Rvd24nIGFuZCAnc2hhcmVkX2NodW5fZG93bicKCiMjIEdldCBNZXRhISAgSW50ZXJzZWN0IHRoZSBhYm92ZSBjb21wYXJpc29ucy4KCk5vdyB3ZSB3YW50IGEgc2Vuc2Ugb2Ygd2hhdCBnZW5lcyBhcmUgc2hhcmVkL3VuaXF1ZSBhbW9uZyB0aGUgc2VsZi1oZWFsaW5nCnZzLiB1bmluZmVjdGVkIGFuZCB0aGUgY2hyb25pYyB2cy4gdW5pbmZlY3RlZCBjb21wYXJpc29ucyBwZXJmb3JtZWQgYWJvdmUuICBPbmUKd291bGQgYXNzdW1lIHRoYXQgdGhlIG1vc3QgaW50ZXJlc3RpbmcgZ2VuZXMgaW4gdGhlc2Ugc2V0cyB3aWxsIHByb3ZlIHRvIGJlIHRoZQp0aGUgb25lcyB3aGljaCBhcmUgX25vdF8gc2hhcmVkLgoKYGBge3Igc2hhcmVkX2ludGVyc2VjdGlvbnN9CnNoY2hfdXBfbHN0IDwtIGxpc3QoCiAgInVwX3NoIiA9IHNoYXJlZF9zaHVuX3VwLAogICJ1cF9jaCIgPSBzaGFyZWRfY2h1bl91cCkKc2hhcmVkX3VwIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1zaGNoX3VwX2xzdCkKVmVubmVyYWJsZTo6cGxvdChzaGFyZWRfdXAsIGRvV2VpZ2h0cz1GQUxTRSkKCnNoY2hfZG93bl9sc3QgPC0gbGlzdCgKICAidXBfc2giID0gc2hhcmVkX3NodW5fZG93biwKICAidXBfY2giID0gc2hhcmVkX2NodW5fZG93bikKc2hhcmVkX2Rvd24gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXNoY2hfZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3Qoc2hhcmVkX2Rvd24sIGRvV2VpZ2h0cz1GQUxTRSkKCnVwdXBfZ2VuZXMgPC0gc2hhcmVkX3VwQEludGVyc2VjdGlvblNldHNbWyIxMSJdXQp1cHNoX25vdGNoIDwtIHNoYXJlZF91cEBJbnRlcnNlY3Rpb25TZXRzW1siMTAiXV0KdXBjaF9ub3RzaCA8LSBzaGFyZWRfdXBASW50ZXJzZWN0aW9uU2V0c1tbIjAxIl1dCmRvd25kb3duX2dlbmVzIDwtIHNoYXJlZF9kb3duQEludGVyc2VjdGlvblNldHNbWyIxMSJdXQpkb3duc2hfbm90Y2ggPC0gc2hhcmVkX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjEwIl1dCmRvd25jaF9ub3RzaCA8LSBzaGFyZWRfZG93bkBJbnRlcnNlY3Rpb25TZXRzW1siMDEiXV0KCmtlcHRfY29sdW1ucyA8LSBjKCJlbnNlbWJsdHJhbnNjcmlwdGlkIiwgImVuc2VtYmxnZW5laWQiLCAiZGVzY3JpcHRpb24iLAogICAgICAgICAgICAgICAgICAiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpCiMjIEdldCB0aGUgc2hhcmVkIHRoaW5ncyBpbiB1cF9zaCBhbmQgdXBfY2gsIGVyZ28gY2FuIHVzZSBlaXRoZXIgc2hlZXQKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoZGF0YT11cF9zaWdbWyJkMTA3X3NodW4iXV1bdXB1cF9nZW5lcywga2VwdF9jb2x1bW5zXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQ9InVwc2hfdXBjaCIpCiMjIEdldCB0aGUgb25seS11cF9zaAp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscyhkYXRhPXVwX3NpZ1tbImQxMDdfc2h1biJdXVt1cHNoX25vdGNoLCBrZXB0X2NvbHVtbnNdLAogICAgICAgICAgICAgICAgICAgICAgICBzaGVldD0idXBzaF9ub2NoIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2I9eGxzX3Jlc3VsdFtbIndvcmtib29rIl1dKQojIyBHZXQgdGhlIG9ubHktdXBfY2gKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoZGF0YT11cF9zaWdbWyJkMTA3X2NodW4iXV1bdXBjaF9ub3RzaCwga2VwdF9jb2x1bW5zXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQ9InVwY2hfbm9zaCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSkKIyMgTm93IHJlcGVhdCBmb3IgdGhlIGRvd246IGRvd24tc2hhcmVkCiMjIEdldCBzaGFyZWQgZG93biBkb3duX3NoIGRvd25fY2gKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoZGF0YT1kb3duX3NpZ1tbImQxMDdfc2h1biJdXVtkb3duZG93bl9nZW5lcywga2VwdF9jb2x1bW5zXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQ9ImRvd25zaF9kb3duY2giLAogICAgICAgICAgICAgICAgICAgICAgICB3Yj14bHNfcmVzdWx0W1sid29ya2Jvb2siXV0pCiMjIFRoZSBkb3duX3NoIG9ubHkKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoZGF0YT1kb3duX3NpZ1tbImQxMDdfc2h1biJdXVtkb3duc2hfbm90Y2gsIGtlcHRfY29sdW1uc10sCiAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0PSJkb3duc2hfbm9jaCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSkKIyMgVGhlIGRvd25fY2gKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoZGF0YT1kb3duX3NpZ1tbImQxMDdfY2h1biJdXVtkb3duY2hfbm90c2gsIGtlcHRfY29sdW1uc10sCiAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0PSJkb3duY2hfbm9zaCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9maWd1cmVfNWNfc3R1ZmYtdiIsIHZlciwgIi54bHN4IikpCmBgYAoKIyMjIEdlbmVzIHNoYXJlZCBhbW9uZyB0aGUgZG9ub3JzLgoKT25lIGZ1cnRoZXIgcXVlcnk6IHdoYXQgZ2VuZXMgYXJlIHNoYXJlZCBhbW9uZyB0aGUgY29udHJhc3RzIG9mCnNlbGYtaGVhbGluZy9jaHJvbmljIHZzLiB1bmluZmVjdGVkIGZvciB0aGUgdGhyZWUgZG9ub3JzPwpXaGVuIGRvaW5nIHRoaXMsIHdlIGhhdmUgb25jZSBhZ2FpbiB0byBjb25zaWRlciB3aGV0aGVyIHRvIHVzZSB0aGUKbm9iYXRjaC9iYXRjaC1pbi1tb2RlbC9zdmEvZXRjIG1ldGhvZHMgYWdhaW5zdCBvdXIgZG9ub3JzLi4uICBTaW5jZSB0aGV5IGFsbAphZ3JlZSBwcmV0dHkgd2VsbCB1bnRpbCBjb21iYXQsIEkgd2lsbCBhcmJpdHJhcmlseSBjaG9vc2UgZnN2YS4KCk9uZSBpZGVhIHN1Z2dlc3RlZCBieSBNYXJpYSBBZGVsYWlkYSB3YXMgdG8gY29tcGFyZSB0aGUgc2V0IG9mIGdlbmVzIHNoYXJlZAphbW9uZyBkMTA3L2QxMDgvZDExMCBpbiB0aGlzIGxhc3QgY29tcGFyaXNvbiAod2hpY2ggd2FzIGVhY2ggb2YgdGhlIHRocmVlIGRvbm9ycwpzZXBhcmF0ZWx5KSBhZ2FpbnN0IHRoZSBzZXQgb2YgZ2VuZXMgaW4gdGhlIGFsbC1kYXRhIGFuYWx5c2lzIGFib3ZlLgoKIyMjIyBBdHRlbXB0IHRvIGFuc3dlciBieSB0aGUgdW5pcXVlIGluZGl2aWR1YWwgc2V0cwoKSW4gdGhpcyBibG9jaywgSSB3aWxsIGF0dGVtcHQgdG8gYW5zd2VyIHRoZSBhYm92ZSBxdWVyeSBieSBpbnRlcnNlY3RpbmcgdGhlIHNldHMKb2YgZ2VuZXMgc2hhcmVkIGFtb25nIHRoZSBpbmRpdmlkdWFscyBidXQgdW5pcXVlIHRvIHNoL2NociB2cy4gdW5pbmZlY3RlZAphZ2FpbnN0IHRoZSBzZXQgb2YgZ2VuZXMgb2JzZXJ2ZWQgaW4gdGhlIG9yaWdpbmFsIHN2YS1tZWRpYXRlZCBERSBhbmFseXNpcy4KCmBgYHtyIG90aGVyX3N0dWZmfQppbmRpdl9zaHVwX3VuaXF1ZSA8LSBzaGFyZWRfdXBASW50ZXJzZWN0aW9uU2V0c1tbIjEwIl1dCmF2Z192c19pbmRfc2h1bl91cCA8LSBsaXN0KAogICJmc3ZhX2F2ZyIgPSByb3duYW1lcyhoc19zaWdfZnN2YVtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiaW5kaXYiID0gaW5kaXZfc2h1cF91bmlxdWUpCmF2Z19pbmRfc2h1cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1hdmdfdnNfaW5kX3NodW5fdXApClZlbm5lcmFibGU6OnBsb3QoYXZnX2luZF9zaHVwX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKCmluZGl2X2NodXBfdW5pcXVlIDwtIHNoYXJlZF91cEBJbnRlcnNlY3Rpb25TZXRzW1siMDEiXV0KYXZnX3ZzX2luZF9jaHVuX3VwIDwtIGxpc3QoCiAgImZzdmFfYXZnIiA9IHJvd25hbWVzKGhzX3NpZ19mc3ZhW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJjaF9uaWwiXV0pLAogICJpbmRpdiIgPSBpbmRpdl9zaHVwX3VuaXF1ZSkKYXZnX2luZF9jaHVwX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWF2Z192c19pbmRfY2h1bl91cCkKVmVubmVyYWJsZTo6cGxvdChhdmdfaW5kX2NodXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQoKaW5kaXZfc2hkb3duX3VuaXF1ZSA8LSBzaGFyZWRfZG93bkBJbnRlcnNlY3Rpb25TZXRzW1siMTAiXV0KYXZnX3ZzX2luZF9zaHVuX2Rvd24gPC0gbGlzdCgKICAiZnN2YV9hdmciID0gcm93bmFtZXMoaHNfc2lnX2ZzdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiaW5kaXYiID0gaW5kaXZfc2hkb3duX3VuaXF1ZSkKYXZnX2luZF9zaGRvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9YXZnX3ZzX2luZF9zaHVuX2Rvd24pClZlbm5lcmFibGU6OnBsb3QoYXZnX2luZF9zaGRvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQoKaW5kaXZfY2hkb3duX3VuaXF1ZSA8LSBzaGFyZWRfZG93bkBJbnRlcnNlY3Rpb25TZXRzW1siMDEiXV0KYXZnX3ZzX2luZF9jaHVuX2Rvd24gPC0gbGlzdCgKICAiZnN2YV9hdmciID0gcm93bmFtZXMoaHNfc2lnX2ZzdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siY2hfbmlsIl1dKSwKICAiaW5kaXYiID0gaW5kaXZfc2hkb3duX3VuaXF1ZSkKYXZnX2luZF9jaGRvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9YXZnX3ZzX2luZF9jaHVuX2Rvd24pClZlbm5lcmFibGU6OnBsb3QoYXZnX2luZF9jaGRvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpgYGAKCiMjIyMgQW5zd2VyIGJ5IGxvb2tpbmcgYXQgdGhlIHNoYXJlZCBnZW5lcyBpbiBib3RoIHNldHMKCmBgYHtyIGNvbXBhcmVfYXZnX2Rvbm9yX2luZGl2aWR1YWxfZG9ub3J9CnNodW5fdXBfYXZnX2dlbmVzIDwtIHJvd25hbWVzKGhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKQpjaHVuX3VwX2F2Z19nZW5lcyA8LSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbInVwcyJdXVtbImNoX25pbCJdXSkKc2h1bl9kb3duX2F2Z19nZW5lcyA8LSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKQpjaHVuX2Rvd25fYXZnX2dlbmVzIDwtIHJvd25hbWVzKGhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pCgpzaHVuX3VwX2luZGl2aWR1YWxfZ2VuZXMgPC0gY29tcF9zaHVuX3VwQEludGVyc2VjdGlvblNldHNbWyIxMTEiXV0KY2h1bl91cF9pbmRpdmlkdWFsX2dlbmVzIDwtIGNvbXBfY2h1bl91cEBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCnNodW5fZG93bl9pbmRpdmlkdWFsX2dlbmVzIDwtIGNvbXBfc2h1bl9kb3duQEludGVyc2VjdGlvblNldHNbWyIxMTEiXV0KY2h1bl9kb3duX2luZGl2aWR1YWxfZ2VuZXMgPC0gY29tcF9jaHVuX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjExMSJdXQoKbGFzdF9zaHVuX3VwX2xzdCA8LSBsaXN0KAogICJhdmdfZ2VuZXMiID0gc2h1bl91cF9hdmdfZ2VuZXMsCiAgImluZF9nZW5lcyIgPSBzaHVuX3VwX2luZGl2aWR1YWxfZ2VuZXMpCmxhc3Rfc2h1bl91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1sYXN0X3NodW5fdXBfbHN0KQpWZW5uZXJhYmxlOjpwbG90KGxhc3Rfc2h1bl91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCgpsYXN0X2NodW5fdXBfbHN0IDwtIGxpc3QoCiAgImF2Z19nZW5lcyIgPSBjaHVuX3VwX2F2Z19nZW5lcywKICAiaW5kX2dlbmVzIiA9IGNodW5fdXBfaW5kaXZpZHVhbF9nZW5lcykKbGFzdF9jaHVuX3VwX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWxhc3RfY2h1bl91cF9sc3QpClZlbm5lcmFibGU6OnBsb3QobGFzdF9jaHVuX3VwX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKCmxhc3Rfc2h1bl9kb3duX2xzdCA8LSBsaXN0KAogICJhdmdfZ2VuZXMiID0gc2h1bl9kb3duX2F2Z19nZW5lcywKICAiaW5kX2dlbmVzIiA9IHNodW5fZG93bl9pbmRpdmlkdWFsX2dlbmVzKQpsYXN0X3NodW5fZG93bl92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1sYXN0X3NodW5fZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3QobGFzdF9zaHVuX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQoKbGFzdF9jaHVuX2Rvd25fbHN0IDwtIGxpc3QoCiAgImF2Z19nZW5lcyIgPSBjaHVuX2Rvd25fYXZnX2dlbmVzLAogICJpbmRfZ2VuZXMiID0gY2h1bl9kb3duX2luZGl2aWR1YWxfZ2VuZXMpCmxhc3RfY2h1bl9kb3duX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWxhc3RfY2h1bl9kb3duX2xzdCkKVmVubmVyYWJsZTo6cGxvdChsYXN0X2NodW5fZG93bl92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmBgYAoKIyMjIERFOiBpbmNsdWRlIHVuaW5mZWN0ZWQsIHJlcGVhdCB3aXRoIGNvbmRpdGlvbiBzaW1wbGlmaWVkIHRvIGNocm9uaWMvc2VsZgoKRG8gSSB0aGluayB0aGUgZXhhY3Qgc2FtZSB0aGluZyBhcyBpbiB0aGUgcHJldmlvdXMgY29tcGFyaXNvbiwgYnV0IG5vdyBzaW1wbGlmeSB0aGUgJ2NvbmRpdGlvbicKZmFjdG9yIHRvIGp1c3Qgc2VsZi1oZWFsaW5nIHZzLiBjaHJvbmljIGFuZCBzZWUgd2hhdCBoYXBwZW5zLgoKYGBge3IgZGVfY2hyb25pY3NoX3N0cmFpbmJhdGNoLCBldmFsPUZBTFNFfQp1bmluZl9zdHJhaW5iYXRjaF9xY2YgPC0gc2V0X2V4cHRfYmF0Y2hlcyhleHB0PWhzX2Nkc191bmluZiwgZmFjdD0icGF0aG9nZW5zdHJhaW4iKQp1bmluZl9zdHJhaW5iYXRjaF9xY2YgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhleHB0PXVuaW5mX3N0cmFpbmJhdGNoX3FjZiwgZmFjdD0ic3RhdGUiKQp3aXRodW5pbmZfc3RyYWluYmF0Y2hfcGFpcnNfY2hzaCA8LSBhbGxfcGFpcndpc2UoCiAgcGFyYWxsZWw9RkFMU0UsIHVuaW5mX3N0cmFpbmJhdGNoX3FjZiwKICBtb2RlbF9iYXRjaD1GQUxTRSwgZm9yY2U9VFJVRSwgZG9fZWJzZXE9RkFMU0UpCmNoc2hfa2VlcGVycyA8LSBsaXN0KAogICAgImNoX3NoIiA9IGMoImNocm9uaWMiLCAic2VsZl9oZWFsIiksCiAgICAiY2hfbmlsIiA9IGMoImNocm9uaWMiLCAidW5pbmZlY3RlZCIpLAogICAgInNoX25pbCIgPSBjKCJzZWxmX2hlYWwiLCAidW5pbmZlY3RlZCIpKQp3aXRodW5pbmZfc3RyYWluYmF0Y2hfdGFibGVzX2Noc2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3BhaXJzX2Noc2gsCiAga2VlcGVycz1jaHNoX2tlZXBlcnMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC93aXRodW5pbmZfc3RyYWluYmF0Y2hfY2hzaF9wYWlyd2lzZS12IiwgdmVyLCAiLnhsc3giKSkpCndpdGh1bmluZl9zdHJhaW5iYXRjaF9zaWdfY2hzaCA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHdpdGh1bmluZl9zdHJhaW5iYXRjaF90YWJsZXNfY2hzaCwKICBleGNlbD1wYXN0ZTAoImV4Y2VsL3dpdGh1bmluZl9zdHJhaW5iYXRjaF9jaHNoX3NpZy12IiwgdmVyLCAiLnhsc3giKSkKIyN3aXRodW5pbmZfc3RyYWluYmF0Y2hfdGFibGVzX2Noc2gkbGltbWFfcGxvdHMKIyN3aXRodW5pbmZfc3RyYWluYmF0Y2hfdGFibGVzX2Noc2gkZWRnZXJfcGxvdHMKIyN3aXRodW5pbmZfc3RyYWluYmF0Y2hfdGFibGVzX2Noc2gkZGVzZXFfcGxvdHMKYGBgCgojIEZpZ3VyZSA1CgpHZW5lcmF0ZSBERSBsaXN0cyBvZiBlYWNoIGRvbm9yIGZvciBhbGwgY29udHJhc3RzIGZvciBQQk1Dcy4KCiAgYS4gIFZlbm4gc2gvdW5pbmYgdnMgY2hyL3VuaW5mIDIgdmVubiBkaWFncmFtIHVwLiAoZG9ub3IgaW4gbW9kZWwpCiAgYi4gIFZlbm4gc2gvdW5pbmYgdnMgY2hyL3VuaW5mIDIgdmVubiBkaWFncmFtIGRvd24uCiAgYy4gIFZlbm4gU2gvdW5pbmYgdXAgZ2VuZXMgMyB2ZW5uIGRpYWdyYW0uCiAgZC4gIFZlbm4gU2gvdW5pbmYgZG93biBnZW5lcyAzIHZlbm4uCiAgZS4gIFZlbm4gQ2hyL3VuaW5mIHVwIGdlbmVzIDMgdmVubi4KICBmLiAgVmVubiBDaHIvdW5pbmYgZG93biBnZW5lcyAzIHZlbm4uCiAgZy4gIDIgd2F5IHZlbm4gb2YgKGNvbW1vbiB1cCBpbiAzIHZlbm4gc2gvdW5pbmYpIHZzLiAoY29tbW9uIHVwIGluIDMgdmVubiBjaHIvdW5pbmYpCiAgaC4gIDIgd2F5IHZlbm4gb2YgKGNvbW1vbiBkb3duIGluIDMgdmVubiBzaC91bmluZikgdnMuIChjb21tb24gZG93biBpbiAzIHZlbm4gY2hyL3VuaW5mKQoKSSByZW5hbWVkIHRoZXNlIHBsb3RzIGFuZCBhbSBub3cgaG9wZWxlc3NseSBjb25mdXNlZCBhcyB0byB3aGljaCBpcyB3aGljaC4gIEkKdGhpbmsgSSB3aWxsIG5vdCBydW4gdGhpcyBmb3Igbm93IGJ1dCBpbnN0ZWFkIGdlbmVyYXRlIHRoZSB3b3Jrc2hlZXQgd2l0aG91dAp0aGVtIGFuZCB0aGVuIHJldHVybiB0byB0aGlzIGluIHRoZSBob3BlcyB0aGF0IEkgY2FuIGRvIGEgYmV0dGVyIGpvYi4KCmBgYHtyIGZpZ3VyZV81LCBldmFsPUZBTFNFfQpwcChmaWxlPSJpbWFnZXMvZmlnXzA1YS1zaF91bmluZl92c19jaHJfdW5pbmZfdXAucGRmIikKVmVubmVyYWJsZTo6cGxvdChjb21tb25fc29sb3NfYmF0Y2gkdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkZXYub2ZmKCkKcHAoZmlsZT0iaW1hZ2VzL2ZpZ18wNWItc2hfdW5pbmZfdnNfY2hyX3VuaW5mX2Rvd24ucGRmIikKVmVubmVyYWJsZTo6cGxvdChjb21tb25fc29sb3NfYmF0Y2gkZG93bl92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPSJpbWFnZXMvZmlnXzA1Yy1zaF91bmluZl9kb25vcnNfdXAucGRmIikKVmVubmVyYWJsZTo6cGxvdChzaF91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPSJpbWFnZXMvZmlnXzA1ZC1zaF91bmluZl9kb25vcnNfZG93bi5wZGYiKQpWZW5uZXJhYmxlOjpwbG90KHNoX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkZXYub2ZmKCkKcHAoZmlsZT0iaW1hZ2VzL2ZpZ18wNWUtY2hyX3VuaW5mX2Rvbm9yc191cC5wZGYiKQpWZW5uZXJhYmxlOjpwbG90KGNocl91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPSJpbWFnZXMvZmlnXzA1Zi1jaHJfdW5pbmZfZG9ub3JzX2Rvd24ucGRmIikKVmVubmVyYWJsZTo6cGxvdChjaHJfZG93bl92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPSJpbWFnZXMvZmlnXzA1Zy11cF9jb21tb24ucGRmIikKVmVubmVyYWJsZTo6cGxvdChzaGFyZWRfdXAsIGRvV2VpZ2h0cz1GQUxTRSkKZGV2Lm9mZigpCnBwKGZpbGU9ImltYWdlcy9maWdfMDVoLWRvd25fY29tbW9uLnBkZiIpClZlbm5lcmFibGU6OnBsb3Qoc2hhcmVkX2Rvd24sIGRvV2VpZ2h0cz1GQUxTRSkKZGV2Lm9mZigpCmBgYAoKIyBUcnkgYWdhaW4gb24gdGhlIHBhcmFzaXRlIGRhdGEKCiMjIFJlbWVtYmVyIG91ciBkYXRhIHNldAoKYGBge3IgbHBfZXhwcmVzc2lvbjAxfQpscF9pbmZfZmlsdCA8LSBzbShub3JtYWxpemVfZXhwdChscF9pbmYsIGZpbHRlcj1UUlVFKSkKYGBgCgpgYGB7ciBscF9ub2JhdGNoLCBzaG93LmZpZz0iaGlkZSJ9CmxwX3BhaXJ3aXNlX25vYmF0Y2ggPC0gc20oYWxsX3BhaXJ3aXNlKGxwX2luZl9maWx0LCBtb2RlbF9iYXRjaD1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYWxsZWw9RkFMU0UsIGRvX2Vic2VxPUZBTFNFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1fbHBfaW5mZWN0X25vYmF0Y2hfY29udHItdnt2ZXJ9Lnhsc3giKQpscF9jb21iaW5lZF9ub2JhdGNoIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGxwX3BhaXJ3aXNlX25vYmF0Y2gsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9scF9pbmZlY3Rfbm9iYXRjaF9zaWctdnt2ZXJ9Lnhsc3giKQpscF9zaWdfbm9iYXRjaCA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKGxwX2NvbWJpbmVkX25vYmF0Y2gsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpgYGAKCmBgYHtyIGxwX2JhdGNoLCBzaG93LmZpZz0iaGlkZSJ9CmxwX3BhaXJ3aXNlX2JhdGNoIDwtIHNtKGFsbF9wYWlyd2lzZShscF9pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9VFJVRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2xwX2luZmVjdF9iYXRjaF9jb250ci12e3Zlcn0ueGxzeCIpCmxwX2NvbWJpbmVkX2JhdGNoIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGxwX3BhaXJ3aXNlX2JhdGNoLCBleGNlbD1leGNlbF9maWxlKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1fbHBfaW5mZWN0X2JhdGNoX3NpZy12e3Zlcn0ueGxzeCIpCmxwX3NpZ19iYXRjaCA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKGxwX2NvbWJpbmVkX2JhdGNoLCBleGNlbD1leGNlbF9maWxlKSkKYGBgCgpgYGB7ciBscF9zc3ZhLCBzaG93LmZpZz0iaGlkZSJ9CmxwX3BhaXJ3aXNlX3NzdmEgPC0gc20oYWxsX3BhaXJ3aXNlKGxwX2luZl9maWx0LCBtb2RlbF9iYXRjaD0ic3N2YSIpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9scF9pbmZlY3Rfc3N2YV9jb250ci12e3Zlcn0ueGxzeCIpCmxwX2NvbWJpbmVkX3NzdmEgPC0gc20oY29tYmluZV9kZV90YWJsZXMobHBfcGFpcndpc2Vfc3N2YSwgZXhjZWw9ZXhjZWxfZmlsZSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2xwX2luZmVjdF9zc3ZhX3NpZy12e3Zlcn0ueGxzeCIpCmxwX3NpZ19zc3ZhIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobHBfY29tYmluZWRfc3N2YSwgZXhjZWw9ZXhjZWxfZmlsZSkpCmBgYAoKYGBge3IgbHBfZnN2YSwgc2hvdy5maWc9ImhpZGUifQpscF9wYWlyd2lzZV9mc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShscF9pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9ImZzdmEiKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1fbHBfaW5mZWN0X2ZzdmFfY29udHItdnt2ZXJ9Lnhsc3giKQpscF9jb21iaW5lZF9mc3ZhIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGxwX3BhaXJ3aXNlX2ZzdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9scF9pbmZlY3RfZnN2YV9zaWctdnt2ZXJ9Lnhsc3giKQpscF9zaWdfZnN2YSA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKGxwX2NvbWJpbmVkX2ZzdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpgYGAKCmBgYHtyIHNhdmVtZX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCnRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQpgYGAKCmBgYHtyIHJlbG9hZCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KbG9hZG1lKGZpbGVuYW1lPXRoaXNfc2F2ZSkKYGBgCg==