1 TODO 20181210

  1. Show samples in current state.
  1. Show current p-value distributions by donor and together to illustrate the concerns.
  1. Show PCAs and loading analyses.
  2. Reperform default analyses after removing one and two samples.
  3. Perform quick GO of de tables after removing one and two.

2 PBMC Infection Differential Expression, Infection: 20180822 Rundate: 20181227

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.

2.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.

3 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.

3.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).

4 Queries from 20181205

4.1 Each individual, chr vs sh.

## There were 18, now there are 6 samples.
##           Length Class      Mode
## sh_vs_chr 46     data.frame list
## [1]  5 46

## There were 18, now there are 6 samples.
##           Length Class      Mode
## sh_vs_chr 46     data.frame list
##                 ensembltranscriptid   ensemblgeneid hgncsymbol
## ENSG00000119457     ENST00000374228 ENSG00000119457    SLC46A2
## ENSG00000162493     ENST00000294489 ENSG00000162493       PDPN
##                                                                           description
## ENSG00000119457 solute carrier family 46 member 2 [Source:HGNC Symbol;Acc:HGNC:16055]
## ENSG00000162493                        podoplanin [Source:HGNC Symbol;Acc:HGNC:29602]
##                    genebiotype deseq_logfc deseq_adjp edger_logfc
## ENSG00000119457 protein_coding       1.124     0.9999       1.110
## ENSG00000162493 protein_coding       1.054     0.9999       1.047
##                 edger_adjp limma_logfc limma_adjp basic_nummed
## ENSG00000119457          1      1.0310     0.9984       0.8026
## ENSG00000162493          1      0.9181     0.9984       1.5200
##                 basic_denmed basic_numvar basic_denvar basic_logfc basic_t
## ENSG00000119457     -0.09514    2.568e-01    6.194e-02      0.8977   3.281
## ENSG00000162493      0.80260    9.344e-01    5.950e-01      0.7173   1.414
##                   basic_p basic_adjp deseq_basemean deseq_lfcse deseq_stat
## ENSG00000119457 4.843e-02      1e+00          14.09      0.5510      2.039
## ENSG00000162493 2.335e-01      1e+00          22.92      0.5347      1.971
##                 deseq_p ebseq_fc ebseq_logfc ebseq_postfc ebseq_mean
## ENSG00000119457 0.04144    2.246       1.167        2.187      14.19
## ENSG00000162493 0.04873    2.177       1.122        2.143      23.12
##                 ebseq_ppee ebseq_ppde ebseq_adjp edger_logcpm edger_lr
## ENSG00000119457          1  2.896e-05          1       0.5923    6.374
## ENSG00000162493          1  4.423e-06          1       1.2200    4.785
##                 edger_p limma_ave limma_t limma_b limma_p limma_adjp_fdr
## ENSG00000119457 0.01158    0.2681   2.918  -4.453 0.01789      9.984e-01
## ENSG00000162493 0.02871    0.8417   1.655  -4.532 0.13370      9.984e-01
##                 deseq_adjp_fdr edger_adjp_fdr basic_adjp_fdr lfc_meta
## ENSG00000119457      1.000e+00      1.000e+00          1e+00    1.117
## ENSG00000162493      1.000e+00      1.000e+00          1e+00    1.017
##                   lfc_var lfc_varbymed    p_meta     p_var
## ENSG00000119457 0.000e+00    0.000e+00 2.364e-02 2.477e-04
## ENSG00000162493 3.373e-03    3.317e-03 7.038e-02 3.107e-03

## There were 18, now there are 6 samples.
##           Length Class      Mode
## sh_vs_chr 46     data.frame list
##                 ensembltranscriptid   ensemblgeneid hgncsymbol
## ENSG00000143333     ENST00000367558 ENSG00000143333      RGS16
## ENSG00000120436     ENST00000366834 ENSG00000120436      GPR31
## ENSG00000099985     ENST00000215781 ENSG00000099985        OSM
## ENSG00000137834     ENST00000288840 ENSG00000137834      SMAD6
## ENSG00000177807     ENST00000368089 ENSG00000177807     KCNJ10
## ENSG00000114115     ENST00000232219 ENSG00000114115       RBP1
##                                                                                              description
## ENSG00000143333                   regulator of G-protein signaling 16 [Source:HGNC Symbol;Acc:HGNC:9997]
## ENSG00000120436                         G protein-coupled receptor 31 [Source:HGNC Symbol;Acc:HGNC:4486]
## ENSG00000099985                                          oncostatin M [Source:HGNC Symbol;Acc:HGNC:8506]
## ENSG00000137834                                  SMAD family member 6 [Source:HGNC Symbol;Acc:HGNC:6772]
## ENSG00000177807 potassium voltage-gated channel subfamily J member 10 [Source:HGNC Symbol;Acc:HGNC:6256]
## ENSG00000114115                             retinol binding protein 1 [Source:HGNC Symbol;Acc:HGNC:9919]
##                    genebiotype deseq_logfc deseq_adjp edger_logfc
## ENSG00000143333 protein_coding       1.510  6.358e-05      1.4950
## ENSG00000120436 protein_coding       1.478  1.000e+00      1.4550
## ENSG00000099985 protein_coding       1.226  5.618e-06      1.2100
## ENSG00000137834 protein_coding       1.155  1.000e+00      1.1340
## ENSG00000177807 protein_coding       1.035  1.593e-01      1.0190
## ENSG00000114115 protein_coding       1.012  1.000e+00      0.9872
##                 edger_adjp limma_logfc limma_adjp basic_nummed
## ENSG00000143333  4.147e-06      1.5450     0.2282       2.7930
## ENSG00000120436  5.293e-02      1.4270     0.2438       1.1730
## ENSG00000099985  1.314e-06      1.2660     0.2282       5.6940
## ENSG00000137834  8.498e-02      1.1040     0.2282       0.7448
## ENSG00000177807  1.213e-01      0.9465     0.3169       3.0800
## ENSG00000114115  1.662e-01      1.1950     0.2322       1.0860
##                 basic_denmed basic_numvar basic_denvar basic_logfc basic_t
## ENSG00000143333      1.47500    1.042e-01    1.044e-01       1.319   5.790
## ENSG00000120436     -0.77380    8.287e-01    1.687e-01       1.946   2.391
## ENSG00000099985      4.19700    6.884e-02    1.701e-01       1.497   4.498
## ENSG00000137834     -0.53530    1.577e-01    9.161e-02       1.280   3.796
## ENSG00000177807      1.91800    9.209e-01    1.252e-01       1.162   1.501
## ENSG00000114115     -0.04987    1.772e-02    8.064e-01       1.136   2.286
##                   basic_p basic_adjp deseq_basemean deseq_lfcse deseq_stat
## ENSG00000143333 4.422e-03  4.809e-01          68.76      0.2758      5.477
## ENSG00000120436 1.034e-01  4.811e-01          16.89      0.5436      2.719
## ENSG00000099985 1.573e-02  4.809e-01         484.20      0.2032      6.031
## ENSG00000137834 2.169e-02  4.809e-01          15.79      0.4878      2.368
## ENSG00000177807 2.461e-01  5.601e-01          73.35      0.3745      2.765
## ENSG00000114115 1.442e-01  4.928e-01          21.96      0.4624      2.188
##                   deseq_p ebseq_fc ebseq_logfc ebseq_postfc ebseq_mean
## ENSG00000143333 4.315e-08    2.874       1.523        2.851      69.31
## ENSG00000120436 6.544e-03    2.807       1.489        2.719      16.93
## ENSG00000099985 1.634e-09    2.396       1.261        2.394     488.89
## ENSG00000137834 1.787e-02    2.256       1.174        2.201      15.95
## ENSG00000177807 5.700e-03    2.060       1.043        2.050      73.55
## ENSG00000114115 2.866e-02    2.073       1.051        2.040      22.14
##                 ebseq_ppee ebseq_ppde ebseq_adjp edger_logcpm edger_lr
## ENSG00000143333  4.467e-10  1.000e+00  4.467e-10       2.2710   36.250
## ENSG00000120436  2.182e-01  7.818e-01  2.182e-01       0.3850   11.210
## ENSG00000099985  1.874e-06  1.000e+00  1.874e-06       5.0590   39.490
## ENSG00000137834  1.000e+00  1.816e-12  1.000e+00       0.2622    9.693
## ENSG00000177807  7.014e-01  2.986e-01  7.014e-01       2.3790    8.339
## ENSG00000114115  2.122e-01  7.878e-01  2.122e-01       0.7058    6.987
##                   edger_p limma_ave limma_t limma_b   limma_p
## ENSG00000143333 1.736e-09   1.99000   6.492 -0.2393 0.0002045
## ENSG00000120436 8.155e-04  -0.09402   2.825 -3.3940 0.0227200
## ENSG00000099985 3.300e-10   4.85000   5.981  0.5318 0.0003530
## ENSG00000137834 1.850e-03  -0.02053   3.616 -2.8330 0.0070230
## ENSG00000177807 3.880e-03   2.09500   2.052 -3.9700 0.0748700
## ENSG00000114115 8.210e-03   0.38370   3.042 -3.1270 0.0163500
##                 limma_adjp_fdr deseq_adjp_fdr edger_adjp_fdr
## ENSG00000143333      2.282e-01      7.363e-05      4.147e-06
## ENSG00000120436      2.438e-01      1.888e-01      5.294e-02
## ENSG00000099985      2.282e-01      6.505e-06      1.314e-06
## ENSG00000137834      2.282e-01      2.751e-01      8.499e-02
## ENSG00000177807      3.169e-01      1.816e-01      1.213e-01
## ENSG00000114115      2.322e-01      3.192e-01      1.662e-01
##                 basic_adjp_fdr lfc_meta   lfc_var lfc_varbymed    p_meta
## ENSG00000143333      4.809e-01   1.5280 1.951e-03    1.277e-03 6.818e-05
## ENSG00000120436      4.811e-01   1.4780 4.320e-04    2.922e-04 1.003e-02
## ENSG00000099985      4.809e-01   1.3010 2.058e-02    1.582e-02 1.177e-04
## ENSG00000137834      4.809e-01   1.1050 4.602e-03    4.164e-03 8.914e-03
## ENSG00000177807      5.600e-01   0.9865 4.913e-03    4.980e-03 2.815e-02
## ENSG00000114115      4.928e-01   1.0720 1.590e-02    1.483e-02 1.774e-02
##                     p_var
## ENSG00000143333 1.394e-08
## ENSG00000120436 1.290e-04
## ENSG00000099985 4.154e-08
## ENSG00000137834 6.684e-05
## ENSG00000177807 1.638e-03
## ENSG00000114115 1.060e-04

5 Remove samples from strain 2504 and/or 2227

This block will first remove strain 2504, then 2272. The resulting subsets will be used for another round of these differential expression analyses.

## There were 18, now there are 15 samples.
## There were 18, now there are 15 samples.
## There were 15, now there are 12 samples.
## There were 21, now there are 18 samples.
## There were 21, now there are 18 samples.
## There were 18, now there are 15 samples.

5.1 Remove one analyses

Once using batch in model, once with svaseq. In my first round of doing this, I did not print out many metrics, let us be better about this.

5.1.1 First some summary plots

In these plots, we can see that the other strain is still a bit weird, particularly in donor 108.

5.1.2 Perform various DE tests

Now let us perform the likely differential expression analyses and see how they look.

5.1.2.2 Include uninfected samples

## Using limma's removeBatchEffect to visualize with/out batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh
## Comparing analyses 1/3: sh_vs_chr
## Comparing analyses 2/3: uninf_vs_chr
## Comparing analyses 3/3: uninf_vs_sh

5.2 Repeat with the removal of strain 2272

5.2.1 Perform de analyses

5.3 Remove two analyses

Repeat as above, removing both weirdo samples.

5.3.2 Perform de analyses

5.4 Interaction model(s)

Try building a donor*state interaction model.

I think I realized my confusion in this: the only interaction models I have used before were a experimental factor*experimental floating-point observation. If it is the case, that the following models are all x vs. factor_reference, then I guess it makes sense; but if not, then I have no clue what is going on in these.

5.4.1 Model matrices

First make sure that self-healing is the reference.

Then make some designs of potential interest.

##               conditionsh conditionchr
## chr_5430_d108           0            1
## chr_5397_d108           0            1
## chr_2504_d108           0            1
## sh_2272_d108            1            0
## sh_1022_d108            1            0
## sh_2189_d108            1            0
##               donord107 donord108 donord110
## chr_5430_d108         0         1         0
## chr_5397_d108         0         1         0
## chr_2504_d108         0         1         0
## sh_2272_d108          0         1         0
## sh_1022_d108          0         1         0
## sh_2189_d108          0         1         0
##               conditionsh conditionchr donord108 donord110
## chr_5430_d108           0            1         1         0
## chr_5397_d108           0            1         1         0
## chr_2504_d108           0            1         1         0
## sh_2272_d108            1            0         1         0
## sh_1022_d108            1            0         1         0
## sh_2189_d108            1            0         1         0
##               conditionchr:donord108 conditionchr:donord110
## chr_5430_d108                      1                      0
## chr_5397_d108                      1                      0
## chr_2504_d108                      1                      0
## sh_2272_d108                       0                      0
## sh_1022_d108                       0                      0
## sh_2189_d108                       0                      0
##               conditionsh conditionchr donord108 donord110
## chr_5430_d108           0            1         1         0
## chr_5397_d108           0            1         1         0
## chr_2504_d108           0            1         1         0
## sh_2272_d108            1            0         1         0
## sh_1022_d108            1            0         1         0
## sh_2189_d108            1            0         1         0
##               conditionchr:donord108 conditionchr:donord110
## chr_5430_d108                      1                      0
## chr_5397_d108                      1                      0
## chr_2504_d108                      1                      0
## sh_2272_d108                       0                      0
## sh_1022_d108                       0                      0
## sh_2189_d108                       0                      0
##               (Intercept) donord108 donord110 conditionchr
## chr_5430_d108           1         1         0            1
## chr_5397_d108           1         1         0            1
## chr_2504_d108           1         1         0            1
## sh_2272_d108            1         1         0            0
## sh_1022_d108            1         1         0            0
## sh_2189_d108            1         1         0            0
##               donord108:conditionchr donord110:conditionchr
## chr_5430_d108                      1                      0
## chr_5397_d108                      1                      0
## chr_2504_d108                      1                      0
## sh_2272_d108                       0                      0
## sh_1022_d108                       0                      0
## sh_2189_d108                       0                      0

5.4.3 edgeR implementation

##      logFC           logCPM           F             PValue        
##  Min.   :-14.9   Min.   :5.04   Min.   :21787   Min.   :2.58e-28  
##  1st Qu.:-14.3   1st Qu.:5.70   1st Qu.:22428   1st Qu.:7.45e-28  
##  Median :-13.6   Median :6.35   Median :23358   Median :1.01e-27  
##  Mean   :-13.8   Mean   :6.12   Mean   :23693   Mean   :1.05e-27  
##  3rd Qu.:-13.4   3rd Qu.:6.51   3rd Qu.:24216   3rd Qu.:1.42e-27  
##  Max.   :-13.1   Max.   :6.87   Max.   :27493   Max.   :1.80e-27  
##       FDR          
##  Min.   :8.93e-25  
##  1st Qu.:8.93e-25  
##  Median :8.93e-25  
##  Mean   :8.93e-25  
##  3rd Qu.:8.93e-25  
##  Max.   :8.93e-25
## [1] "conditionchr:donord108"
##      logFC            logCPM            F            PValue        
##  Min.   :-1.305   Min.   :0.762   Min.   :10.6   Min.   :0.000729  
##  1st Qu.:-0.659   1st Qu.:2.330   1st Qu.:10.9   1st Qu.:0.001731  
##  Median :-0.484   Median :3.884   Median :12.9   Median :0.002407  
##  Mean   :-0.393   Mean   :3.428   Mean   :13.0   Mean   :0.002769  
##  3rd Qu.:-0.395   3rd Qu.:4.252   3rd Qu.:13.9   3rd Qu.:0.004282  
##  Max.   : 1.133   Max.   :5.837   Max.   :17.0   Max.   :0.004813  
##       FDR   
##  Min.   :1  
##  1st Qu.:1  
##  Median :1  
##  Mean   :1  
##  3rd Qu.:1  
##  Max.   :1

5.4.4 DESeq2 implementation

## converting counts to integer mode
## estimating size factors
## estimating dispersions
## gene-wise dispersion estimates
## mean-dispersion relationship
## final dispersion estimates
## fitting model and testing
## [1] "Intercept"              "condition_chr_vs_sh"   
## [3] "donor_d108_vs_d107"     "donor_d110_vs_d107"    
## [5] "conditionchr.donord108" "conditionchr.donord110"
##       Length        Class         Mode 
##            6 DESeqResults           S4
## log2 fold change (MLE): condition chr vs sh 
## Wald test p-value: condition chr vs sh 
## DataFrame with 6 rows and 6 columns
##                         baseMean      log2FoldChange             lfcSE
##                        <numeric>           <numeric>         <numeric>
## ENSG00000000419 214.886619915588 -0.0934303786250254  0.12300393077645
## ENSG00000000457 318.115512380986  -0.068815027486115 0.120178565849457
## ENSG00000000460 102.031345099905   0.197578912145072 0.203833151567596
## ENSG00000000938 5676.81912456484  0.0269256146826752 0.197204584725487
## ENSG00000000971 53.5624271330181   0.344010769796456 0.293375111918845
## ENSG00000001036 460.076692835547  0.0156360632261453 0.148896600722685
##                               stat            pvalue              padj
##                          <numeric>         <numeric>         <numeric>
## ENSG00000000419 -0.759572300131027 0.447510281800118 0.997804083570582
## ENSG00000000457 -0.572606496006257 0.566911160357569 0.997804083570582
## ENSG00000000460  0.969316868358142 0.332387115533936 0.997804083570582
## ENSG00000000938  0.136536453856568 0.891397208363037 0.997804083570582
## ENSG00000000971   1.17259697847723 0.240957461669005 0.997804083570582
## ENSG00000001036  0.105012895863667 0.916365575881328 0.997804083570582
##       Length        Class         Mode 
##            6 DESeqResults           S4
## log2 fold change (MLE): conditionchr.donord110 
## Wald test p-value: conditionchr.donord110 
## DataFrame with 6 rows and 6 columns
##                         baseMean     log2FoldChange             lfcSE
##                        <numeric>          <numeric>         <numeric>
## ENSG00000000419 214.886619915588  0.295162897632013 0.172516639204641
## ENSG00000000457 318.115512380986  0.108194027119009 0.172637547612825
## ENSG00000000460 102.031345099905  0.376710409795487 0.293516835681214
## ENSG00000000938 5676.81912456484 0.0530822519196353 0.278697424287239
## ENSG00000000971 53.5624271330181 -0.388785003193931 0.436191950074646
## ENSG00000001036 460.076692835547   0.10657602357023 0.206872518783626
##                               stat             pvalue              padj
##                          <numeric>          <numeric>         <numeric>
## ENSG00000000419   1.71092422732562 0.0870951015388544 0.999936246663048
## ENSG00000000457  0.626712025368067  0.530848019781775 0.999936246663048
## ENSG00000000460    1.2834371456792  0.199338967059447 0.999936246663048
## ENSG00000000938   0.19046552746367  0.848944353796083 0.999936246663048
## ENSG00000000971 -0.891316318715644  0.372759496477825 0.999936246663048
## ENSG00000001036  0.515177289844383  0.606429137146659 0.999936246663048
##       Length        Class         Mode 
##            6 DESeqResults           S4
## log2 fold change (MLE): conditionchr.donord110 
## Wald test p-value: conditionchr.donord110 
## DataFrame with 6 rows and 6 columns
##                         baseMean     log2FoldChange             lfcSE
##                        <numeric>          <numeric>         <numeric>
## ENSG00000000419 214.886619915588  0.295162897632013 0.172516639204641
## ENSG00000000457 318.115512380986  0.108194027119009 0.172637547612825
## ENSG00000000460 102.031345099905  0.376710409795487 0.293516835681214
## ENSG00000000938 5676.81912456484 0.0530822519196353 0.278697424287239
## ENSG00000000971 53.5624271330181 -0.388785003193931 0.436191950074646
## ENSG00000001036 460.076692835547   0.10657602357023 0.206872518783626
##                               stat             pvalue              padj
##                          <numeric>          <numeric>         <numeric>
## ENSG00000000419   1.71092422732562 0.0870951015388544 0.999936246663048
## ENSG00000000457  0.626712025368067  0.530848019781775 0.999936246663048
## ENSG00000000460    1.2834371456792  0.199338967059447 0.999936246663048
## ENSG00000000938   0.19046552746367  0.848944353796083 0.999936246663048
## ENSG00000000971 -0.891316318715644  0.372759496477825 0.999936246663048
## ENSG00000001036  0.515177289844383  0.606429137146659 0.999936246663048
##       Length        Class         Mode 
##            6 DESeqResults           S4
## log2 fold change (MLE): donor d110 vs d107 
## Wald test p-value: donor d110 vs d107 
## DataFrame with 6 rows and 6 columns
##                         baseMean     log2FoldChange             lfcSE
##                        <numeric>          <numeric>         <numeric>
## ENSG00000000419 214.886619915588 -0.113766010123853 0.120483955620923
## ENSG00000000457 318.115512380986 -0.456556848180769 0.121122399221616
## ENSG00000000460 102.031345099905   -0.5010401182924 0.210579406027488
## ENSG00000000938 5676.81912456484  0.505694298463597 0.197026331645792
## ENSG00000000971 53.5624271330181 -0.842424805273729 0.308759375189539
## ENSG00000001036 460.076692835547  0.568390991546202 0.145482651751354
##                               stat               pvalue
##                          <numeric>            <numeric>
## ENSG00000000419 -0.944241990873823    0.345046001807488
## ENSG00000000457  -3.76938411982257 0.000163650866259048
## ENSG00000000460   -2.3793405430491   0.0173436449623682
## ENSG00000000938   2.56663307000365   0.0102691214578726
## ENSG00000000971  -2.72841854520721  0.00636388048892608
## ENSG00000001036   3.90693312710334  9.3475010176665e-05
##                                 padj
##                            <numeric>
## ENSG00000000419    0.476062375176819
## ENSG00000000457 0.000739090391073861
## ENSG00000000460   0.0422654009174772
## ENSG00000000938   0.0271711897470546
## ENSG00000000971   0.0181060512075926
## ENSG00000001036 0.000448806683671478

5.5 PC loadings

##       Comp.1                  Comp.2                 
##  [1,] "31.7:ENSG00000129824"  "22.16:ENSG00000100079"
##  [2,] "30.31:ENSG00000012817" "16.86:ENSG00000128283"
##  [3,] "30:ENSG00000185736"    "15.92:ENSG00000170439"
##  [4,] "29.65:ENSG00000067048" "13.44:ENSG00000156113"
##  [5,] "27.68:ENSG00000114374" "13.39:ENSG00000007350"
##  [6,] "25.19:ENSG00000183878" "13.25:ENSG00000123219"
##  [7,] "21.54:ENSG00000198692" "13.11:ENSG00000205809"
##  [8,] "20.86:ENSG00000067646" "13.01:ENSG00000165810"
##  [9,] "18.84:ENSG00000074410" "12.6:ENSG00000150687" 
## [10,] "16.59:ENSG00000179344" "12.6:ENSG00000167880" 
## [11,] "15.01:ENSG00000134184" "12.36:ENSG00000150510"
## [12,] "14.9:ENSG00000196735"  "12.1:ENSG00000167094" 
## [13,] "14.46:ENSG00000122641" "12.09:ENSG00000146918"
## [14,] "14.37:ENSG00000121380" "11.77:ENSG00000173372"
## [15,] "14.37:ENSG00000161055" "11.67:ENSG00000214944"
## [16,] "13.88:ENSG00000154620" "11.34:ENSG00000174945"
## [17,] "13.76:ENSG00000166923" "11.01:ENSG00000240247"
## [18,] "13.5:ENSG00000123453"  "10.99:ENSG00000205810"
## [19,] "13.06:ENSG00000123454" "10.95:ENSG00000149635"
## [20,] "13.02:ENSG00000108688" "10.72:ENSG00000102837"
## [21,] "12.49:ENSG00000131435" "10.69:ENSG00000109956"
## [22,] "12.47:ENSG00000136449" "10.68:ENSG00000061337"
## [23,] "12.22:ENSG00000110092" "10.6:ENSG00000206047" 
## [24,] "12.05:ENSG00000120645" "10.51:ENSG00000205846"
## [25,] "11.83:ENSG00000205057" "10.5:ENSG00000183542" 
## [26,] "11.54:ENSG00000123689" "10.04:ENSG00000113721"
## [27,] "11.34:ENSG00000170160" "9.932:ENSG00000101188"
## [28,] "11.32:ENSG00000113302" "9.836:ENSG00000113657"
## [29,] "11.2:ENSG00000102970"  "9.783:ENSG00000196421"
## [30,] "11.08:ENSG00000198203" "9.572:ENSG00000145708"
## [31,] "11.08:ENSG00000184371" "9.241:ENSG00000133962"
## [32,] "11.07:ENSG00000149635" "9.213:ENSG00000148488"
## [33,] "10.94:ENSG00000204644" "8.953:ENSG00000125780"
## [34,] "10.83:ENSG00000050165" "8.802:ENSG00000243772"
## [35,] "10.66:ENSG00000150510" "8.796:ENSG00000170160"
## [36,] "10.47:ENSG00000182871" "8.76:ENSG00000162383" 
## [37,] "10.42:ENSG00000134668" "8.719:ENSG00000108370"
## [38,] "10.23:ENSG00000164530" "8.705:ENSG00000054793"
## [39,] "10.22:ENSG00000178860" "8.564:ENSG00000168329"
## [40,] "10.19:ENSG00000109471" "8.503:ENSG00000184349"
## [41,] "10.17:ENSG00000197121" "8.377:ENSG00000100450"
## [42,] "10.15:ENSG00000164400" "8.224:ENSG00000173239"
## [43,] "9.967:ENSG00000180616" "8.088:ENSG00000086548"
## [44,] "9.874:ENSG00000069482" "8.001:ENSG00000111199"
## [45,] "9.8:ENSG00000133687"   "7.934:ENSG00000239839"
## [46,] "9.786:ENSG00000134716" "7.928:ENSG00000139567"
## [47,] "9.778:ENSG00000115009" "7.858:ENSG00000188820"
## [48,] "9.737:ENSG00000197822" "7.744:ENSG00000101425"
## [49,] "9.705:ENSG00000172724" "7.624:ENSG00000176083"
## [50,] "9.686:ENSG00000181634" "7.616:ENSG00000169908"
## Before removal, there were 11944 entries.
## Now there are 50 entries.
## Percent kept: 0.140, 0.119, 0.075, 0.131, 0.083, 0.119, 0.017, 0.016, 0.009, 0.019, 0.010, 0.012, 0.210, 0.213, 0.183, 0.252, 0.162, 0.221
## Percent removed: 99.860, 99.881, 99.925, 99.869, 99.917, 99.881, 99.983, 99.984, 99.991, 99.981, 99.990, 99.988, 99.790, 99.787, 99.817, 99.748, 99.838, 99.779
ensembl_gene_id description
ENSG00000129824 ENSG00000129824 ribosomal protein S4, Y-linked 1 [Source:HGNC Symbol;Acc:HGNC:10425]
ENSG00000012817 ENSG00000012817 lysine demethylase 5D [Source:HGNC Symbol;Acc:HGNC:11115]
ENSG00000185736 ENSG00000185736 adenosine deaminase, RNA specific B2 (inactive) [Source:HGNC Symbol;Acc:HGNC:227]
ENSG00000067048 ENSG00000067048 DEAD-box helicase 3, Y-linked [Source:HGNC Symbol;Acc:HGNC:2699]
ENSG00000114374 ENSG00000114374 ubiquitin specific peptidase 9, Y-linked [Source:HGNC Symbol;Acc:HGNC:12633]
ENSG00000183878 ENSG00000183878 ubiquitously transcribed tetratricopeptide repeat containing, Y-linked [Source:HGNC Symbol;Acc:HGNC:12638]
ENSG00000198692 ENSG00000198692 eukaryotic translation initiation factor 1A, Y-linked [Source:HGNC Symbol;Acc:HGNC:3252]
ENSG00000067646 ENSG00000067646 zinc finger protein, Y-linked [Source:HGNC Symbol;Acc:HGNC:12870]
ENSG00000074410 ENSG00000074410 carbonic anhydrase 12 [Source:HGNC Symbol;Acc:HGNC:1371]
ENSG00000179344 ENSG00000179344 major histocompatibility complex, class II, DQ beta 1 [Source:HGNC Symbol;Acc:HGNC:4944]
ENSG00000134184 ENSG00000134184 glutathione S-transferase mu 1 [Source:HGNC Symbol;Acc:HGNC:4632]
ENSG00000196735 ENSG00000196735 major histocompatibility complex, class II, DQ alpha 1 [Source:HGNC Symbol;Acc:HGNC:4942]
ENSG00000122641 ENSG00000122641 inhibin beta A subunit [Source:HGNC Symbol;Acc:HGNC:6066]
ENSG00000121380 ENSG00000121380 BCL2 like 14 [Source:HGNC Symbol;Acc:HGNC:16657]
ENSG00000161055 ENSG00000161055 secretoglobin family 3A member 1 [Source:HGNC Symbol;Acc:HGNC:18384]
ENSG00000154620 ENSG00000154620 thymosin beta 4, Y-linked [Source:HGNC Symbol;Acc:HGNC:11882]
ENSG00000166923 ENSG00000166923 gremlin 1, DAN family BMP antagonist [Source:HGNC Symbol;Acc:HGNC:2001]
ENSG00000123453 ENSG00000123453 sarcosine dehydrogenase [Source:HGNC Symbol;Acc:HGNC:10536]
ENSG00000123454 ENSG00000123454 dopamine beta-hydroxylase [Source:HGNC Symbol;Acc:HGNC:2689]
ENSG00000108688 ENSG00000108688 C-C motif chemokine ligand 7 [Source:HGNC Symbol;Acc:HGNC:10634]
ENSG00000131435 ENSG00000131435 PDZ and LIM domain 4 [Source:HGNC Symbol;Acc:HGNC:16501]
ENSG00000136449 ENSG00000136449 MYCBP associated protein [Source:HGNC Symbol;Acc:HGNC:19677]
ENSG00000110092 ENSG00000110092 cyclin D1 [Source:HGNC Symbol;Acc:HGNC:1582]
ENSG00000120645 ENSG00000120645 IQ motif and Sec7 domain 3 [Source:HGNC Symbol;Acc:HGNC:29193]
ENSG00000205057 ENSG00000205057 chronic lymphocytic leukemia up-regulated 1 opposite strand [Source:HGNC Symbol;Acc:HGNC:24070]
ENSG00000123689 ENSG00000123689 G0/G1 switch 2 [Source:HGNC Symbol;Acc:HGNC:30229]
ENSG00000170160 ENSG00000170160 coiled-coil domain containing 144A [Source:HGNC Symbol;Acc:HGNC:29072]
ENSG00000113302 ENSG00000113302 interleukin 12B [Source:HGNC Symbol;Acc:HGNC:5970]
ENSG00000102970 ENSG00000102970 C-C motif chemokine ligand 17 [Source:HGNC Symbol;Acc:HGNC:10615]
ENSG00000198203 ENSG00000198203 sulfotransferase family 1C member 2 [Source:HGNC Symbol;Acc:HGNC:11456]
ENSG00000184371 ENSG00000184371 colony stimulating factor 1 [Source:HGNC Symbol;Acc:HGNC:2432]
ENSG00000149635 ENSG00000149635 osteoclast stimulatory transmembrane protein [Source:HGNC Symbol;Acc:HGNC:16116]
ENSG00000204644 ENSG00000204644 ZFP57 zinc finger protein [Source:HGNC Symbol;Acc:HGNC:18791]
ENSG00000050165 ENSG00000050165 dickkopf WNT signaling pathway inhibitor 3 [Source:HGNC Symbol;Acc:HGNC:2893]
ENSG00000150510 ENSG00000150510 family with sequence similarity 124 member A [Source:HGNC Symbol;Acc:HGNC:26413]
ENSG00000182871 ENSG00000182871 collagen type XVIII alpha 1 chain [Source:HGNC Symbol;Acc:HGNC:2195]
ENSG00000134668 ENSG00000134668 SPOC domain containing 1 [Source:HGNC Symbol;Acc:HGNC:26338]
ENSG00000164530 ENSG00000164530 peptidase inhibitor 16 [Source:HGNC Symbol;Acc:HGNC:21245]
ENSG00000178860 ENSG00000178860 musculin [Source:HGNC Symbol;Acc:HGNC:7321]
ENSG00000109471 ENSG00000109471 interleukin 2 [Source:HGNC Symbol;Acc:HGNC:6001]
ENSG00000197121 ENSG00000197121 post-GPI attachment to proteins 1 [Source:HGNC Symbol;Acc:HGNC:25712]
ENSG00000164400 ENSG00000164400 colony stimulating factor 2 [Source:HGNC Symbol;Acc:HGNC:2434]
ENSG00000180616 ENSG00000180616 somatostatin receptor 2 [Source:HGNC Symbol;Acc:HGNC:11331]
ENSG00000069482 ENSG00000069482 galanin and GMAP prepropeptide [Source:HGNC Symbol;Acc:HGNC:4114]
ENSG00000133687 ENSG00000133687 transmembrane and tetratricopeptide repeat containing 1 [Source:HGNC Symbol;Acc:HGNC:24099]
ENSG00000134716 ENSG00000134716 cytochrome P450 family 2 subfamily J member 2 [Source:HGNC Symbol;Acc:HGNC:2634]
ENSG00000115009 ENSG00000115009 C-C motif chemokine ligand 20 [Source:HGNC Symbol;Acc:HGNC:10619]
ENSG00000197822 ENSG00000197822 occludin [Source:HGNC Symbol;Acc:HGNC:8104]
ENSG00000172724 ENSG00000172724 C-C motif chemokine ligand 19 [Source:HGNC Symbol;Acc:HGNC:10617]
ENSG00000181634 ENSG00000181634 tumor necrosis factor superfamily member 15 [Source:HGNC Symbol;Acc:HGNC:11931]
## Before removal, there were 11944 entries.
## Now there are 50 entries.
## Percent kept: 0.097, 0.087, 0.077, 0.094, 0.077, 0.088, 0.053, 0.050, 0.059, 0.055, 0.063, 0.057, 0.024, 0.017, 0.015, 0.021, 0.017, 0.017
## Percent removed: 99.903, 99.913, 99.923, 99.906, 99.923, 99.912, 99.947, 99.950, 99.941, 99.945, 99.937, 99.943, 99.976, 99.983, 99.985, 99.979, 99.983, 99.983
ensembl_gene_id description
ENSG00000100079 ENSG00000100079 galectin 2 [Source:HGNC Symbol;Acc:HGNC:6562]
ENSG00000128283 ENSG00000128283 CDC42 effector protein 1 [Source:HGNC Symbol;Acc:HGNC:17014]
ENSG00000170439 ENSG00000170439 methyltransferase like 7B [Source:HGNC Symbol;Acc:HGNC:28276]
ENSG00000156113 ENSG00000156113 potassium calcium-activated channel subfamily M alpha 1 [Source:HGNC Symbol;Acc:HGNC:6284]
ENSG00000007350 ENSG00000007350 transketolase like 1 [Source:HGNC Symbol;Acc:HGNC:11835]
ENSG00000123219 ENSG00000123219 centromere protein K [Source:HGNC Symbol;Acc:HGNC:29479]
ENSG00000205809 ENSG00000205809 killer cell lectin like receptor C2 [Source:HGNC Symbol;Acc:HGNC:6375]
ENSG00000165810 ENSG00000165810 butyrophilin like 9 [Source:HGNC Symbol;Acc:HGNC:24176]
ENSG00000150687 ENSG00000150687 protease, serine 23 [Source:HGNC Symbol;Acc:HGNC:14370]
ENSG00000167880 ENSG00000167880 envoplakin [Source:HGNC Symbol;Acc:HGNC:3503]
ENSG00000150510 ENSG00000150510 family with sequence similarity 124 member A [Source:HGNC Symbol;Acc:HGNC:26413]
ENSG00000167094 ENSG00000167094 tetratricopeptide repeat domain 16 [Source:HGNC Symbol;Acc:HGNC:26536]
ENSG00000146918 ENSG00000146918 non-SMC condensin II complex subunit G2 [Source:HGNC Symbol;Acc:HGNC:21904]
ENSG00000173372 ENSG00000173372 complement C1q A chain [Source:HGNC Symbol;Acc:HGNC:1241]
ENSG00000214944 ENSG00000214944 Rho guanine nucleotide exchange factor 28 [Source:HGNC Symbol;Acc:HGNC:30322]
ENSG00000174945 ENSG00000174945 archaelysin family metallopeptidase 1 [Source:HGNC Symbol;Acc:HGNC:22231]
ENSG00000240247 ENSG00000240247 defensin alpha 1B [Source:HGNC Symbol;Acc:HGNC:33596]
ENSG00000205810 ENSG00000205810 killer cell lectin like receptor C3 [Source:HGNC Symbol;Acc:HGNC:6376]
ENSG00000149635 ENSG00000149635 osteoclast stimulatory transmembrane protein [Source:HGNC Symbol;Acc:HGNC:16116]
ENSG00000102837 ENSG00000102837 olfactomedin 4 [Source:HGNC Symbol;Acc:HGNC:17190]
ENSG00000109956 ENSG00000109956 beta-1,3-glucuronyltransferase 1 [Source:HGNC Symbol;Acc:HGNC:921]
ENSG00000061337 ENSG00000061337 leucine zipper tumor suppressor 1 [Source:HGNC Symbol;Acc:HGNC:13861]
ENSG00000206047 ENSG00000206047 defensin alpha 1 [Source:HGNC Symbol;Acc:HGNC:2761]
ENSG00000205846 ENSG00000205846 C-type lectin domain family 6 member A [Source:HGNC Symbol;Acc:HGNC:14556]
ENSG00000183542 ENSG00000183542 killer cell lectin like receptor C4 [Source:HGNC Symbol;Acc:HGNC:6377]
ENSG00000113721 ENSG00000113721 platelet derived growth factor receptor beta [Source:HGNC Symbol;Acc:HGNC:8804]
ENSG00000101188 ENSG00000101188 neurotensin receptor 1 [Source:HGNC Symbol;Acc:HGNC:8039]
ENSG00000113657 ENSG00000113657 dihydropyrimidinase like 3 [Source:HGNC Symbol;Acc:HGNC:3015]
ENSG00000196421 ENSG00000196421 long intergenic non-protein coding RNA 176 [Source:HGNC Symbol;Acc:HGNC:27655]
ENSG00000145708 ENSG00000145708 corticotropin releasing hormone binding protein [Source:HGNC Symbol;Acc:HGNC:2356]
ENSG00000133962 ENSG00000133962 cation channel sperm associated auxiliary subunit beta [Source:HGNC Symbol;Acc:HGNC:20500]
ENSG00000148488 ENSG00000148488 ST8 alpha-N-acetyl-neuraminide alpha-2,8-sialyltransferase 6 [Source:HGNC Symbol;Acc:HGNC:23317]
ENSG00000125780 ENSG00000125780 transglutaminase 3 [Source:HGNC Symbol;Acc:HGNC:11779]
ENSG00000243772 ENSG00000243772 killer cell immunoglobulin like receptor, two Ig domains and long cytoplasmic tail 3 [Source:HGNC Symbol;Acc:HGNC:6331]
ENSG00000170160 ENSG00000170160 coiled-coil domain containing 144A [Source:HGNC Symbol;Acc:HGNC:29072]
ENSG00000162383 ENSG00000162383 solute carrier family 1 member 7 [Source:HGNC Symbol;Acc:HGNC:10945]
ENSG00000108370 ENSG00000108370 regulator of G-protein signaling 9 [Source:HGNC Symbol;Acc:HGNC:10004]
ENSG00000054793 ENSG00000054793 ATPase phospholipid transporting 9A (putative) [Source:HGNC Symbol;Acc:HGNC:13540]
ENSG00000168329 ENSG00000168329 C-X3-C motif chemokine receptor 1 [Source:HGNC Symbol;Acc:HGNC:2558]
ENSG00000184349 ENSG00000184349 ephrin A5 [Source:HGNC Symbol;Acc:HGNC:3225]
ENSG00000100450 ENSG00000100450 granzyme H [Source:HGNC Symbol;Acc:HGNC:4710]
ENSG00000173239 ENSG00000173239 lipase family member M [Source:HGNC Symbol;Acc:HGNC:23455]
ENSG00000086548 ENSG00000086548 carcinoembryonic antigen related cell adhesion molecule 6 [Source:HGNC Symbol;Acc:HGNC:1818]
ENSG00000111199 ENSG00000111199 transient receptor potential cation channel subfamily V member 4 [Source:HGNC Symbol;Acc:HGNC:18083]
ENSG00000239839 ENSG00000239839 defensin alpha 3 [Source:HGNC Symbol;Acc:HGNC:2762]
ENSG00000139567 ENSG00000139567 activin A receptor like type 1 [Source:HGNC Symbol;Acc:HGNC:175]
ENSG00000188820 ENSG00000188820 family with sequence similarity 26 member F [Source:HGNC Symbol;Acc:HGNC:33391]
ENSG00000101425 ENSG00000101425 bactericidal/permeability-increasing protein [Source:HGNC Symbol;Acc:HGNC:1095]
ENSG00000176083 ENSG00000176083 zinc finger protein 683 [Source:HGNC Symbol;Acc:HGNC:28495]
ENSG00000169908 ENSG00000169908 transmembrane 4 L six family member 1 [Source:HGNC Symbol;Acc:HGNC:11853]
## Before removal, there were 11944 entries.
## Now there are 50 entries.
## Percent kept: 0.401, 0.316, 0.140, 0.384, 0.155, 0.370, 0.275, 0.242, 0.094, 0.218, 0.125, 0.158, 0.486, 0.395, 0.215, 0.493, 0.271, 0.316
## Percent removed: 99.599, 99.684, 99.860, 99.616, 99.845, 99.630, 99.725, 99.758, 99.906, 99.782, 99.875, 99.842, 99.514, 99.605, 99.785, 99.507, 99.729, 99.684
ensembl_gene_id description
ENSG00000137673 ENSG00000137673 matrix metallopeptidase 7 [Source:HGNC Symbol;Acc:HGNC:7174]
ENSG00000113302 ENSG00000113302 interleukin 12B [Source:HGNC Symbol;Acc:HGNC:5970]
ENSG00000169908 ENSG00000169908 transmembrane 4 L six family member 1 [Source:HGNC Symbol;Acc:HGNC:11853]
ENSG00000074410 ENSG00000074410 carbonic anhydrase 12 [Source:HGNC Symbol;Acc:HGNC:1371]
ENSG00000122641 ENSG00000122641 inhibin beta A subunit [Source:HGNC Symbol;Acc:HGNC:6066]
ENSG00000166923 ENSG00000166923 gremlin 1, DAN family BMP antagonist [Source:HGNC Symbol;Acc:HGNC:2001]
ENSG00000106178 ENSG00000106178 C-C motif chemokine ligand 24 [Source:HGNC Symbol;Acc:HGNC:10623]
ENSG00000125144 ENSG00000125144 metallothionein 1G [Source:HGNC Symbol;Acc:HGNC:7399]
ENSG00000197506 ENSG00000197506 solute carrier family 28 member 3 [Source:HGNC Symbol;Acc:HGNC:16484]
ENSG00000136695 ENSG00000136695 interleukin 36 receptor antagonist [Source:HGNC Symbol;Acc:HGNC:15561]
ENSG00000205362 ENSG00000205362 metallothionein 1A [Source:HGNC Symbol;Acc:HGNC:7393]
ENSG00000187848 ENSG00000187848 purinergic receptor P2X 2 [Source:HGNC Symbol;Acc:HGNC:15459]
ENSG00000111052 ENSG00000111052 lin-7 homolog A, crumbs cell polarity complex component [Source:HGNC Symbol;Acc:HGNC:17787]
ENSG00000069482 ENSG00000069482 galanin and GMAP prepropeptide [Source:HGNC Symbol;Acc:HGNC:4114]
ENSG00000113657 ENSG00000113657 dihydropyrimidinase like 3 [Source:HGNC Symbol;Acc:HGNC:3015]
ENSG00000186081 ENSG00000186081 keratin 5 [Source:HGNC Symbol;Acc:HGNC:6442]
ENSG00000148677 ENSG00000148677 ankyrin repeat domain 1 [Source:HGNC Symbol;Acc:HGNC:15819]
ENSG00000187134 ENSG00000187134 aldo-keto reductase family 1 member C1 [Source:HGNC Symbol;Acc:HGNC:384]
ENSG00000105976 ENSG00000105976 MET proto-oncogene, receptor tyrosine kinase [Source:HGNC Symbol;Acc:HGNC:7029]
ENSG00000105855 ENSG00000105855 integrin subunit beta 8 [Source:HGNC Symbol;Acc:HGNC:6163]
ENSG00000172724 ENSG00000172724 C-C motif chemokine ligand 19 [Source:HGNC Symbol;Acc:HGNC:10617]
ENSG00000133048 ENSG00000133048 chitinase 3 like 1 [Source:HGNC Symbol;Acc:HGNC:1932]
ENSG00000100234 ENSG00000100234 TIMP metallopeptidase inhibitor 3 [Source:HGNC Symbol;Acc:HGNC:11822]
ENSG00000138772 ENSG00000138772 annexin A3 [Source:HGNC Symbol;Acc:HGNC:541]
ENSG00000108688 ENSG00000108688 C-C motif chemokine ligand 7 [Source:HGNC Symbol;Acc:HGNC:10634]
ENSG00000151012 ENSG00000151012 solute carrier family 7 member 11 [Source:HGNC Symbol;Acc:HGNC:11059]
ENSG00000117594 ENSG00000117594 hydroxysteroid 11-beta dehydrogenase 1 [Source:HGNC Symbol;Acc:HGNC:5208]
ENSG00000039560 ENSG00000039560 retinoic acid induced 14 [Source:HGNC Symbol;Acc:HGNC:14873]
ENSG00000118785 ENSG00000118785 secreted phosphoprotein 1 [Source:HGNC Symbol;Acc:HGNC:11255]
ENSG00000154856 ENSG00000154856 APC down-regulated 1 [Source:HGNC Symbol;Acc:HGNC:15718]
ENSG00000110436 ENSG00000110436 solute carrier family 1 member 2 [Source:HGNC Symbol;Acc:HGNC:10940]
ENSG00000050730 ENSG00000050730 TNFAIP3 interacting protein 3 [Source:HGNC Symbol;Acc:HGNC:19315]
ENSG00000176076 ENSG00000176076 potassium voltage-gated channel subfamily E regulatory subunit 5 [Source:HGNC Symbol;Acc:HGNC:6241]
ENSG00000205358 ENSG00000205358 metallothionein 1H [Source:HGNC Symbol;Acc:HGNC:7400]
ENSG00000053747 ENSG00000053747 laminin subunit alpha 3 [Source:HGNC Symbol;Acc:HGNC:6483]
ENSG00000136689 ENSG00000136689 interleukin 1 receptor antagonist [Source:HGNC Symbol;Acc:HGNC:6000]
ENSG00000166165 ENSG00000166165 creatine kinase B [Source:HGNC Symbol;Acc:HGNC:1991]
ENSG00000102837 ENSG00000102837 olfactomedin 4 [Source:HGNC Symbol;Acc:HGNC:17190]
ENSG00000112139 ENSG00000112139 MAM domain containing glycosylphosphatidylinositol anchor 1 [Source:HGNC Symbol;Acc:HGNC:19267]
ENSG00000163687 ENSG00000163687 deoxyribonuclease 1 like 3 [Source:HGNC Symbol;Acc:HGNC:2959]
ENSG00000205364 ENSG00000205364 metallothionein 1M [Source:HGNC Symbol;Acc:HGNC:14296]
ENSG00000169429 ENSG00000169429 C-X-C motif chemokine ligand 8 [Source:HGNC Symbol;Acc:HGNC:6025]
ENSG00000255398 ENSG00000255398 hydroxycarboxylic acid receptor 3 [Source:HGNC Symbol;Acc:HGNC:16824]
ENSG00000178726 ENSG00000178726 thrombomodulin [Source:HGNC Symbol;Acc:HGNC:11784]
ENSG00000066056 ENSG00000066056 tyrosine kinase with immunoglobulin like and EGF like domains 1 [Source:HGNC Symbol;Acc:HGNC:11809]
ENSG00000136052 ENSG00000136052 solute carrier family 41 member 2 [Source:HGNC Symbol;Acc:HGNC:31045]
ENSG00000125780 ENSG00000125780 transglutaminase 3 [Source:HGNC Symbol;Acc:HGNC:11779]
ENSG00000178860 ENSG00000178860 musculin [Source:HGNC Symbol;Acc:HGNC:7321]
ENSG00000197632 ENSG00000197632 serpin family B member 2 [Source:HGNC Symbol;Acc:HGNC:8584]
ENSG00000162433 ENSG00000162433 adenylate kinase 4 [Source:HGNC Symbol;Acc:HGNC:363]

5.5.2 Shenanigans

## There were 21, now there are 18 samples.

##       Comp.1                  Comp.2                 
##  [1,] "20.51:ENSG00000137673" "11.92:ENSG00000125538"
##  [2,] "17.37:ENSG00000113657" "11.74:ENSG00000163735"
##  [3,] "16.95:ENSG00000122641" "11.2:ENSG00000113302" 
##  [4,] "15.07:ENSG00000108688" "11.14:ENSG00000122641"
##  [5,] "14.65:ENSG00000166923" "10.6:ENSG00000143333" 
##  [6,] "13.38:ENSG00000148677" "9.251:ENSG00000105976"
##  [7,] "12.64:ENSG00000133048" "8.576:ENSG00000113070"
##  [8,] "12.63:ENSG00000106178" "8.552:ENSG00000123689"
##  [9,] "12.44:ENSG00000100234" "8.265:ENSG00000074410"
## [10,] "12.1:ENSG00000197506"  "8.032:ENSG00000205846"
## [11,] "11.54:ENSG00000076716" "7.734:ENSG00000182782"
## [12,] "11.45:ENSG00000117594" "7.706:ENSG00000106178"
## [13,] "11.44:ENSG00000136689" "7.559:ENSG00000169429"
## [14,] "10.88:ENSG00000250033" "7.534:ENSG00000117594"
## [15,] "10.85:ENSG00000178852" "7.455:ENSG00000123610"
## [16,] "10.61:ENSG00000151012" "7.07:ENSG00000131203" 
## [17,] "10.15:ENSG00000136052" "7.011:ENSG00000166165"
## [18,] "9.835:ENSG00000125144" "6.981:ENSG00000162493"
## [19,] "9.762:ENSG00000162433" "6.847:ENSG00000255398"
## [20,] "9.583:ENSG00000178860" "6.579:ENSG00000173391"
## [21,] "9.51:ENSG00000175445"  "6.257:ENSG00000178860"
## [22,] "9.379:ENSG00000103855" "6.2:ENSG00000125144"  
## [23,] "9.357:ENSG00000184371" "6.177:ENSG00000106366"
## [24,] "9.292:ENSG00000118785" "6.16:ENSG00000172724" 
## [25,] "9.218:ENSG00000243742" "6.15:ENSG00000184557" 
## [26,] "8.921:ENSG00000251230" "6.126:ENSG00000099985"
## [27,] "8.869:ENSG00000105855" "6.113:ENSG00000105855"
## [28,] "8.847:ENSG00000138080" "6.054:ENSG00000183019"
## [29,] "8.654:ENSG00000110092" "5.984:ENSG00000137507"
## [30,] "8.548:ENSG00000138061" "5.959:ENSG00000196878"
## [31,] "8.543:ENSG00000176177" "5.907:ENSG00000105246"
## [32,] "8.54:ENSG00000151704"  "5.772:ENSG00000169184"
## [33,] "8.369:ENSG00000136810" "5.769:ENSG00000178726"
## [34,] "8.359:ENSG00000172070" "5.729:ENSG00000123700"
## [35,] "8.181:ENSG00000120217" "5.664:ENSG00000171049"
## [36,] "8.169:ENSG00000253123" "5.64:ENSG00000242048" 
## [37,] "8.165:ENSG00000174939" "5.527:ENSG00000186431"
## [38,] "8.09:ENSG00000111012"  "5.507:ENSG00000157227"
## [39,] "7.801:ENSG00000154277" "5.44:ENSG00000110436" 
## [40,] "7.73:ENSG00000069482"  "5.436:ENSG00000146555"
## [41,] "7.729:ENSG00000164935" "5.41:ENSG00000130222" 
## [42,] "7.53:ENSG00000180509"  "5.401:ENSG00000185614"
## [43,] "7.426:ENSG00000117525" "5.394:ENSG00000166527"
## [44,] "7.407:ENSG00000123689" "5.322:ENSG00000163739"
## [45,] "7.288:ENSG00000169418" "5.259:ENSG00000006118"
## [46,] "7.249:ENSG00000115919" "5.254:ENSG00000102794"
## [47,] "7.093:ENSG00000151726" "5.253:ENSG00000125657"
## [48,] "7.069:ENSG00000140450" "5.212:ENSG00000011422"
## [49,] "7.057:ENSG00000039560" "5.194:ENSG00000219682"
## [50,] "7.05:ENSG00000113302"  "5.115:ENSG00000075618"
## Before removal, there were 13557 entries.
## Now there are 50 entries.
## Percent kept: 0.385, 0.365, 0.289, 0.350, 0.301, 0.370, 0.422, 0.397, 0.262, 0.369, 0.308, 0.329, 0.384, 0.352, 0.293, 0.380, 0.333, 0.326
## Percent removed: 99.615, 99.635, 99.711, 99.650, 99.699, 99.630, 99.578, 99.603, 99.738, 99.631, 99.692, 99.671, 99.616, 99.648, 99.707, 99.620, 99.667, 99.674

ensembl_gene_id description
ENSG00000137673 ENSG00000137673 matrix metallopeptidase 7 [Source:HGNC Symbol;Acc:HGNC:7174]
ENSG00000113657 ENSG00000113657 dihydropyrimidinase like 3 [Source:HGNC Symbol;Acc:HGNC:3015]
ENSG00000122641 ENSG00000122641 inhibin beta A subunit [Source:HGNC Symbol;Acc:HGNC:6066]
ENSG00000108688 ENSG00000108688 C-C motif chemokine ligand 7 [Source:HGNC Symbol;Acc:HGNC:10634]
ENSG00000166923 ENSG00000166923 gremlin 1, DAN family BMP antagonist [Source:HGNC Symbol;Acc:HGNC:2001]
ENSG00000148677 ENSG00000148677 ankyrin repeat domain 1 [Source:HGNC Symbol;Acc:HGNC:15819]
ENSG00000133048 ENSG00000133048 chitinase 3 like 1 [Source:HGNC Symbol;Acc:HGNC:1932]
ENSG00000106178 ENSG00000106178 C-C motif chemokine ligand 24 [Source:HGNC Symbol;Acc:HGNC:10623]
ENSG00000100234 ENSG00000100234 TIMP metallopeptidase inhibitor 3 [Source:HGNC Symbol;Acc:HGNC:11822]
ENSG00000197506 ENSG00000197506 solute carrier family 28 member 3 [Source:HGNC Symbol;Acc:HGNC:16484]
ENSG00000076716 ENSG00000076716 glypican 4 [Source:HGNC Symbol;Acc:HGNC:4452]
ENSG00000117594 ENSG00000117594 hydroxysteroid 11-beta dehydrogenase 1 [Source:HGNC Symbol;Acc:HGNC:5208]
ENSG00000136689 ENSG00000136689 interleukin 1 receptor antagonist [Source:HGNC Symbol;Acc:HGNC:6000]
NA NA NA
ENSG00000178852 ENSG00000178852 EF-hand calcium binding domain 13 [Source:HGNC Symbol;Acc:HGNC:26864]
ENSG00000151012 ENSG00000151012 solute carrier family 7 member 11 [Source:HGNC Symbol;Acc:HGNC:11059]
ENSG00000136052 ENSG00000136052 solute carrier family 41 member 2 [Source:HGNC Symbol;Acc:HGNC:31045]
ENSG00000125144 ENSG00000125144 metallothionein 1G [Source:HGNC Symbol;Acc:HGNC:7399]
ENSG00000162433 ENSG00000162433 adenylate kinase 4 [Source:HGNC Symbol;Acc:HGNC:363]
ENSG00000178860 ENSG00000178860 musculin [Source:HGNC Symbol;Acc:HGNC:7321]
ENSG00000175445 ENSG00000175445 lipoprotein lipase [Source:HGNC Symbol;Acc:HGNC:6677]
ENSG00000103855 ENSG00000103855 CD276 molecule [Source:HGNC Symbol;Acc:HGNC:19137]
ENSG00000184371 ENSG00000184371 colony stimulating factor 1 [Source:HGNC Symbol;Acc:HGNC:2432]
ENSG00000118785 ENSG00000118785 secreted phosphoprotein 1 [Source:HGNC Symbol;Acc:HGNC:11255]
NA.1 NA NA
NA.2 NA NA
ENSG00000105855 ENSG00000105855 integrin subunit beta 8 [Source:HGNC Symbol;Acc:HGNC:6163]
ENSG00000138080 ENSG00000138080 elastin microfibril interfacer 1 [Source:HGNC Symbol;Acc:HGNC:19880]
ENSG00000110092 ENSG00000110092 cyclin D1 [Source:HGNC Symbol;Acc:HGNC:1582]
ENSG00000138061 ENSG00000138061 cytochrome P450 family 1 subfamily B member 1 [Source:HGNC Symbol;Acc:HGNC:2597]
ENSG00000176177 ENSG00000176177 ENTH domain containing 1 [Source:HGNC Symbol;Acc:HGNC:26352]
ENSG00000151704 ENSG00000151704 potassium voltage-gated channel subfamily J member 1 [Source:HGNC Symbol;Acc:HGNC:6255]
ENSG00000136810 ENSG00000136810 thioredoxin [Source:HGNC Symbol;Acc:HGNC:12435]
NA.3 NA NA
ENSG00000120217 ENSG00000120217 CD274 molecule [Source:HGNC Symbol;Acc:HGNC:17635]
NA.4 NA NA
ENSG00000174939 ENSG00000174939 aspartate beta-hydroxylase domain containing 1 [Source:HGNC Symbol;Acc:HGNC:27380]
ENSG00000111012 ENSG00000111012 cytochrome P450 family 27 subfamily B member 1 [Source:HGNC Symbol;Acc:HGNC:2606]
ENSG00000154277 ENSG00000154277 ubiquitin C-terminal hydrolase L1 [Source:HGNC Symbol;Acc:HGNC:12513]
ENSG00000069482 ENSG00000069482 galanin and GMAP prepropeptide [Source:HGNC Symbol;Acc:HGNC:4114]
ENSG00000164935 ENSG00000164935 dendrocyte expressed seven transmembrane protein [Source:HGNC Symbol;Acc:HGNC:18549]
ENSG00000180509 ENSG00000180509 potassium voltage-gated channel subfamily E regulatory subunit 1 [Source:HGNC Symbol;Acc:HGNC:6240]
ENSG00000117525 ENSG00000117525 coagulation factor III, tissue factor [Source:HGNC Symbol;Acc:HGNC:3541]
ENSG00000123689 ENSG00000123689 G0/G1 switch 2 [Source:HGNC Symbol;Acc:HGNC:30229]
ENSG00000169418 ENSG00000169418 natriuretic peptide receptor 1 [Source:HGNC Symbol;Acc:HGNC:7943]
ENSG00000115919 ENSG00000115919 kynureninase [Source:HGNC Symbol;Acc:HGNC:6469]
ENSG00000151726 ENSG00000151726 acyl-CoA synthetase long-chain family member 1 [Source:HGNC Symbol;Acc:HGNC:3569]
ENSG00000140450 ENSG00000140450 arrestin domain containing 4 [Source:HGNC Symbol;Acc:HGNC:28087]
ENSG00000039560 ENSG00000039560 retinoic acid induced 14 [Source:HGNC Symbol;Acc:HGNC:14873]
ENSG00000113302 ENSG00000113302 interleukin 12B [Source:HGNC Symbol;Acc:HGNC:5970]

##                 deseq_logfc deseq_adjp edger_logfc edger_adjp limma_logfc
## ENSG00000115414       2.153  0.0024550       2.144  3.068e-04       1.799
## ENSG00000177675       2.015  0.0468000       1.943  1.084e-02       1.346
## ENSG00000155659       1.626  0.0006777       1.606  1.692e-05       1.392
## ENSG00000050767       1.607  0.0016020       1.587  3.668e-05       1.516
## ENSG00000182853       1.448  0.0033350       1.379  7.238e-06       1.232
## ENSG00000171631       1.372  0.0055770       1.359  3.068e-04       1.231
##                 limma_adjp basic_nummed basic_denmed basic_numvar
## ENSG00000115414    0.10420        8.283       5.3510    5.412e+00
## ENSG00000177675    0.35000        1.616      -0.9318    6.552e+00
## ENSG00000155659    0.13110        4.262       2.2720    1.758e+00
## ENSG00000050767    0.07678        2.703       1.1920    2.675e+00
## ENSG00000182853    0.04845        1.912       0.7903    6.430e+00
## ENSG00000171631    0.07678        3.666       2.2430    1.505e+00
##                 basic_denvar basic_logfc basic_t   basic_p basic_adjp
## ENSG00000115414    5.728e+00       2.931  1.5310 1.573e-01  9.287e-01
## ENSG00000177675    7.569e+00       2.548  1.2170 2.532e-01  9.803e-01
## ENSG00000155659    2.192e+00       1.989  2.1840 5.632e-02  7.679e-01
## ENSG00000050767    2.278e+00       1.511  1.8860 8.626e-02  8.359e-01
## ENSG00000182853    7.233e+00       1.121  0.9952 3.441e-01  9.999e-01
## ENSG00000171631    1.499e+00       1.423  2.1210 5.964e-02  7.736e-01
##                 deseq_basemean deseq_lfcse deseq_stat   deseq_p ebseq_fc
## ENSG00000115414         9426.0      0.4814      4.473 7.709e-06    3.195
## ENSG00000177675          106.4      0.6284      3.207 1.340e-03    2.907
## ENSG00000155659          183.7      0.3333      4.879 1.065e-06    2.833
## ENSG00000050767          116.1      0.3450      4.656 3.217e-06    3.038
## ENSG00000182853          261.3      0.3311      4.373 1.223e-05    2.447
## ENSG00000171631          194.8      0.3281      4.181 2.902e-05    2.472
##                 ebseq_logfc ebseq_postfc ebseq_mean ebseq_ppee ebseq_ppde
## ENSG00000115414       1.676        3.435     9412.4     0.9999  1.034e-04
## ENSG00000177675       1.539        3.163      106.3     0.9992  7.759e-04
## ENSG00000155659       1.502        2.894      184.1     0.9988  1.241e-03
## ENSG00000050767       1.603        3.141      116.1     0.9992  7.803e-04
## ENSG00000182853       1.291        2.640      260.8     0.9997  2.598e-04
## ENSG00000171631       1.306        2.531      194.5     0.9994  6.066e-04
##                 ebseq_adjp edger_logcpm edger_lr   edger_p limma_ave
## ENSG00000115414     0.9999        9.468    24.91 6.020e-07     7.720
## ENSG00000177675     0.9992        3.065    14.84 1.172e-04     1.022
## ENSG00000155659     0.9988        3.808    32.41 1.248e-08     3.156
## ENSG00000050767     0.9992        3.167    30.12 4.059e-08     2.277
## ENSG00000182853     0.9997        4.328    35.06 3.203e-09     2.367
## ENSG00000171631     0.9994        3.909    24.82 6.308e-07     3.328
##                 limma_t limma_b   limma_p limma_adjp_fdr deseq_adjp_fdr
## ENSG00000115414   3.457 -1.6420 0.0025910      1.042e-01      2.683e-03
## ENSG00000177675   1.904 -4.0050 0.0719400      3.499e-01      5.090e-02
## ENSG00000155659   3.233 -1.8970 0.0043150      1.312e-01      7.599e-04
## ENSG00000050767   3.893 -0.8535 0.0009530      7.678e-02      1.677e-03
## ENSG00000182853   4.650  0.7091 0.0001680      4.846e-02      3.628e-03
## ENSG00000171631   3.888 -0.6062 0.0009655      7.678e-02      6.058e-03
##                 edger_adjp_fdr basic_adjp_fdr lfc_meta   lfc_var
## ENSG00000115414      3.069e-04      9.284e-01    2.092 9.577e-03
## ENSG00000177675      1.085e-02      9.801e-01    1.780 1.190e-01
## ENSG00000155659      1.692e-05      7.678e-01    1.544 1.541e-02
## ENSG00000050767      3.669e-05      8.359e-01    1.603 1.203e-04
## ENSG00000182853      7.237e-06      9.998e-01    1.346 2.010e-02
## ENSG00000171631      3.069e-04      7.736e-01    1.295 1.491e-02
##                 lfc_varbymed    p_meta     p_var
## ENSG00000115414    4.578e-03 8.664e-04 2.231e-06
## ENSG00000177675    6.686e-02 2.447e-02 1.691e-03
## ENSG00000155659    9.977e-03 1.439e-03 6.205e-06
## ENSG00000050767    7.505e-05 3.188e-04 3.017e-07
## ENSG00000182853    1.493e-02 6.008e-05 8.773e-09
## ENSG00000171631    1.151e-02 3.317e-04 3.015e-07

5.6 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.

5.6.1 Review nobatch pca

##       change_counts_up change_counts_down
## ch_sh                0                  0

6 Perform the ‘qualitative’ analysis of sh and ch vs uninfected

In the following blocks, a series of queries of the self-healing and chronic samples vs. the uninfected will be performed. The assumption is that the effect of infection, which is so much stronger than the difference of self-healing and chronic, will highlight some differences when performed using the chronic and self-healing samples.

In addition, we will be applying all of these tasks with and without strain 2504. I am guessing that the above results will cause one to want to see this with the removal of both troublesome strains (2504 and 2272). But for the moment I am think I will limit my self to only the 2504 removal in an attempt to avoid confusion.

6.1 Add patient to the model

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

6.1.3 Perform qualitative analysis

In the following blocks we will perform the intersections of (self-healing vs. uninfected) against (chronic vs. uninfected).

6.1.3.1 With 2504

##    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
## $ch_sh
## $ch_sh$logfc
## [1] 0.9873
## 
## $ch_sh$p
## [1] 0.9304
## 
## $ch_sh$adjp
## [1] 0.06891

6.2 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

6.3 Add ssva into the mix

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

6.3.3 Now plot the intersections

6.3.3.1 Once again, all strains first

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  47    -none- character
## 01  69    -none- character
## 11 830    -none- character

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  52    -none- character
## 01  49    -none- character
## 11 278    -none- character
## $ch_sh
## $ch_sh$logfc
## [1] 0.9708
## 
## $ch_sh$p
## [1] 0.8871
## 
## $ch_sh$adjp
## [1] 0.05923
## $sh_nil
## $sh_nil$logfc
## [1] 0.9912
## 
## $sh_nil$p
## [1] 0.9683
## 
## $sh_nil$adjp
## [1] 0.9683
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] 0.9894
## 
## $ch_nil$p
## [1] 0.963
## 
## $ch_nil$adjp
## [1] 0.963
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.9829
## 
## $ch_sh$p
## [1] 0.9558
## 
## $ch_sh$adjp
## [1] 0.9558

6.4 fsva

Repeat again using fsva.

6.4.1 Review fsva

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  69    -none- character
## 01  81    -none- character
## 11 860    -none- character

##    Length Class  Mode     
## 00   0    -none- NULL     
## 10  61    -none- character
## 01  69    -none- character
## 11 242    -none- character
## $ch_sh
## $ch_sh$logfc
## [1] 0.9465
## 
## $ch_sh$p
## [1] 0.8312
## 
## $ch_sh$adjp
## [1] 0.04638
## Error in compare_de_results(hs_combined_ssva, hs_combined_fsva, cor_method = "spearman"): object 'hs_combined_ssva' not found
## $ch_sh
## $ch_sh$logfc
## [1] 0.9465
## 
## $ch_sh$p
## [1] 0.8312
## 
## $ch_sh$adjp
## [1] 0.04638

6.5 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(hpgl(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
## 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).
## Leaving the data unnormalized.  This is necessary for DESeq, but
##  EdgeR/limma might benefit from normalization.  Good choices include quantile,
##  size-factor, tmm, etc.
## Step 1: performing count filter with option: hpgl
## Removing 0 low-count genes (12086 remaining).
## Step 2: not normalizing the data.
## 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, 320 entries are >= 0.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 320 entries are x<=0.
## The be method chose 2 surrogate variable(s).
## batch_counts: Using combat with a prior and with scaling.
## The number of elements which are < 0 after batch correction is: 6972
## 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.

6.5.1 Review combat

##        change_counts_up change_counts_down
## sh_nil             1634                  2
## ch_nil             2464               2042
## ch_sh               495                955
##    Length Class  Mode     
## 00    0   -none- NULL     
## 10    0   -none- NULL     
## 01  830   -none- character
## 11 1634   -none- character

##    Length Class  Mode     
## 00    0   -none- NULL     
## 10    0   -none- NULL     
## 01 2040   -none- character
## 11    2   -none- character
## $ch_sh
## $ch_sh$logfc
## [1] -0.02286
## 
## $ch_sh$p
## [1] -0.132
## 
## $ch_sh$adjp
## [1] -0.001533
## $sh_nil
## $sh_nil$logfc
## [1] -0.08734
## 
## $sh_nil$p
## [1] 0.01233
## 
## $sh_nil$adjp
## [1] 0.01233
## 
## 
## $ch_nil
## $ch_nil$logfc
## [1] -0.1004
## 
## $ch_nil$p
## [1] 0.05137
## 
## $ch_nil$adjp
## [1] 0.05137
## 
## 
## $ch_sh
## $ch_sh$logfc
## [1] 0.1955
## 
## $ch_sh$p
## [1] -0.03469
## 
## $ch_sh$adjp
## [1] -0.0347

6.6 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

6.6.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.

6.6.1.1 All strains

## 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

6.7 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.

6.7.1 Perform venns of self-healing vs. uninfected

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

6.7.2 Perform venns of chronic vs. uninfected

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

6.7.3 Perform venns of self-healing vs. uninfected

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

6.7.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’

6.8 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/20181227_figure_5c_stuff-v20180822.xlsx

6.8.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.

6.8.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.

6.8.1.2 Answer by looking at the shared genes in both sets

7 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.

8 Try again on the parasite data

8.1 Remember our data set

LS0tCnRpdGxlOiAiTC4gcGFuYW1lbnNpcyAyMDE4MDgyMjogRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gb2YgaW5mZWN0ZWQgUEJNQ3MuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB3aWR0aDogMzAwCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCiAgQmlvY1N0eWxlOjpodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KYm9keSwgdGQgewogIGZvbnQtc2l6ZTogMTZweDsKfQpjb2RlLnJ7CiAgZm9udC1zaXplOiAxNnB4Owp9CnByZSB7CiBmb250LXNpemU6IDE2cHgKfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSgiaHBnbHRvb2xzIikKdHQgPC0gZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgd2lkdGg9MTIwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdD0iJVklbSVkIikKcHJldmlvdXNfZmlsZSA8LSAiMDJfZXN0aW1hdGlvbl9pbmZlY3Rpb25fMjAxODA4MjIuUm1kIgp2ZXIgPC0gIjIwMTgwODIyIgoKdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKQpybWRfZmlsZSA8LSAiMDNfZXhwcmVzc2lvbl9pbmZlY3Rpb25fMjAxODA4MjIuUm1kIgpgYGAKCiMgVE9ETyAyMDE4MTIxMAoKMS4gIFNob3cgc2FtcGxlcyBpbiBjdXJyZW50IHN0YXRlLgogIGEuICBTaG93IGN1cnJlbnQgcC12YWx1ZSBkaXN0cmlidXRpb25zIGJ5IGRvbm9yIGFuZCB0b2dldGhlciB0byBpbGx1c3RyYXRlIHRoZSBjb25jZXJucy4KMi4gIFNob3cgUENBcyBhbmQgbG9hZGluZyBhbmFseXNlcy4KMy4gIFJlcGVyZm9ybSBkZWZhdWx0IGFuYWx5c2VzIGFmdGVyIHJlbW92aW5nIG9uZSBhbmQgdHdvIHNhbXBsZXMuCjQuICBQZXJmb3JtIHF1aWNrIEdPIG9mIGRlIHRhYmxlcyBhZnRlciByZW1vdmluZyBvbmUgYW5kIHR3by4KCiMgUEJNQyBJbmZlY3Rpb24gRGlmZmVyZW50aWFsIEV4cHJlc3Npb24sIEluZmVjdGlvbjogYHIgdmVyYCBSdW5kYXRlOiBgciBydW5kYXRlYAoKVGhpcyBkb2N1bWVudCB0dXJucyB0byB0aGUgaW5mZWN0aW9uIG9mIFBCTUMgY2VsbHMgd2l0aCBMLnBhbmFtZW5zaXMuICBUaGlzIGRhdGEKaXMgcGFydGljdWxhcmx5IHN0cmFuZ2VseSBhZmZlY3RlZCBieSB0aGUgZGlmZmVyZW50IHN0cmFpbnMgdXNlZCB0byBpbmZlY3QgdGhlCmNlbGxzLCBhbmQgYXMgYSByZXN1bHQgaXMgYm90aCB1c2VmdWwgYW5kIHRyb3VibGluZy4KCkdpdmVuIHRoZSBvYnNlcnZhdGlvbnMgYWJvdmUsIHdlIGhhdmUgc29tZSBpZGVhcyBvZiB3YXlzIHRvIHBhc3MgdGhlIGRhdGEgZm9yCmRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzIHdoaWNoIG1heSBvciBtYXkgbm90IGJlICdiZXR0ZXInLiAgTGV0cyB0cnkKc29tZSBhbmQgc2VlIHdoYXQgaGFwcGVucy4KCiMjIENyZWF0ZSBkYXRhIHNldHMgdG8gY29tcGFyZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcwoKR2l2ZW4gdGhlIGFib3ZlIHdheXMgdG8gbWFzc2FnZSB0aGUgZGF0YSwgbGV0cyB1c2UgYSBmZXcgb2YgdGhlbSBmb3IKbGltbWEvZGVzZXEvZWRnZXIuIFRoZSBtYWluIGNhdmVhdCBpbiB0aGlzIGlzIHRoYXQgdGhvc2UgdG9vbHMgcmVhbGx5IGRvIGV4cGVjdApzcGVjaWZpYyBkaXN0cmlidXRpb25zIG9mIGRhdGEgd2hpY2ggd2UgaG9ycmlibHkgdmlvbGF0ZSBpZiB3ZSB1c2UgbG9nMigpIGRhdGEsCndoaWNoIGlzIHdoeSBpbiB0aGUgcHJldmlvdXMgYmxvY2tzIEkgbmFtZWQgdGhlbSBsMmJsYWhibGFoLCB0aHVzIHdlIGNhbiBkbyB0aGUKc2FtZSBzZXRzIG9mIG5vcm1hbGl6YXRpb24gYnV0IHdpdGhvdXQgdGhhdCBhbmQgZm9yY2libHkgcHVzaCB0aGUgcmVzdWx0aW5nIGRhdGEKaW50byBsaW1tYS9lZGdlci9kZXNlcS4KCiMgVGhlIG5lZ2F0aXZlIGNvbnRyb2wKCkV2ZXJ5dGhpbmcgSSBkaWQgaW4gMDJfZXN0aW1hdGlvbl9pbmZlY3Rpb24uaHRtbCBzdWdnZXN0cyB0aGF0IHRoZXJlIGFyZSBubwpzaWduaWZpY2FudCBkaWZmZXJlbmNlcyB2aXNpYmxlIGlmIG9uZSBsb29rcyBqdXN0IGF0IGNocm9uaWMvc2VsZi1oZWFsaW5nIGluCnRoaXMgZGF0YS4gIEZ1cnRoZXIgdGVzdGluZyBoYXMgc2VlbWluZ2x5IHByb3ZlbiB0aGlzIHN0YXRlbWVudCwgYXMgYSByZXN1bHQKbW9zdCBvZiB0aGUgZm9sbG93aW5nIGFuYWx5c2VzIHdpbGwgbG9vayBhdCBjaHJvbmljL3VuaW5mZWN0ZWQgYW5kCnNlbGYtaGVhbGluZy91bmluZmVjdGVkIGZvbGxvd2VkIGJ5IGF0dGVtcHRzIHRvIHJlY29uY2lsZSB0aG9zZSByZXN1bHRzLgoKIyMgRmlsdGVyIHRoZSBkYXRhCgpUbyBzYXZlIHNvbWUgdGltZSBhbmQgYW5ub3lhbmNlIHdpdGggc3ZhLCBsZXRzIGZpbHRlciB0aGUgZGF0YSBub3cuICBJbgphZGRpdGlvbiwgd3JpdGUgZG93biBhIHNtYWxsIGZ1bmN0aW9uIHVzZWQgdG8gZXh0cmFjdCB0aGUgc2V0cyBvZiBzaWduaWZpY2FudApnZW5lcyBhY3Jvc3MgZGlmZmVyZW50IGNvbnRyYXN0cyAobm90YWJseSBzZWxmL3VuaW5mZWN0ZWQgdnMuIGNocm9uaWMvdW5pbmZlY3RlZCkuCgpgYGB7ciBmaWx0ZXJ9CmhzX2luZl9maWx0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX2Nkc19pbmYsIGZpbHRlcj1UUlVFKSkKaHNfdW5pbmZfZmlsdCA8LSBzbShub3JtYWxpemVfZXhwdChoc19jZHNfdW5pbmYsIGZpbHRlcj1UUlVFKSkKa2VlcGVyc191bmluZiA8LSBsaXN0KCJzaF9uaWwiID0gYygic2giLCAidW5pbmYiKSwKICAgICAgICAgICAgICAgICAgICAgICJjaF9uaWwiID0gYygiY2hyIiwgInVuaW5mIiksCiAgICAgICAgICAgICAgICAgICAgICAiY2hfc2giID0gYygiY2hyIiwgInNoIikpCmtlZXBlcnNfaW5mIDwtIGxpc3QoImNoX3NoIiA9IGMoImNociIsICJzaCIpKQpgYGAKCiMgUXVlcmllcyBmcm9tIDIwMTgxMjA1CgojIyBFYWNoIGluZGl2aWR1YWwsIGNociB2cyBzaC4KCmBgYHtyIGVhY2hfaW5kaXZpZHVhbH0KZDEwNyA8LSBzdWJzZXRfZXhwdChoc19pbmZfZmlsdCwgc3Vic2V0PSJkb25vcj09J2QxMDcnIikKZDEwN19wYWlyd2lzZSA8LSBzbShhbGxfcGFpcndpc2UoZDEwNywgbW9kZWxfYmF0Y2g9RkFMU0UpKQpkMTA3X3RhYmxlIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGQxMDdfcGFpcndpc2UpKQpzdW1tYXJ5KGQxMDdfdGFibGUkZGF0YSkKZDEwN19zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhkMTA3X3RhYmxlLCBhY2NvcmRpbmdfdG89ImRlc2VxIiwgcD0wLjEsIHBfdHlwZT0icmF3IikpCmRpbShkMTA3X3NpZ1tbImRlc2VxIl1dW1sidXBzIl1dW1sxXV0pCmQxMDdfbWEgPC0gZXh0cmFjdF9kZV9wbG90cyhkMTA3X3BhaXJ3aXNlLCBsb2dmYz0wLjYsIHA9MC4xLCBwX3R5cGU9InJhdyIpCmQxMDdfbWEkbWEkcGxvdApwbG90X2hpc3RvZ3JhbShkMTA3X3RhYmxlW1siZGF0YSJdXVtbInNoX3ZzX2NociJdXVssIGMoImRlc2VxX3AiKV0pCnBsb3RfcGNhKHNtKG5vcm1hbGl6ZV9leHB0KGQxMDcsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpKSkkcGxvdAoKZDEwOCA8LSBzdWJzZXRfZXhwdChoc19pbmZfZmlsdCwgc3Vic2V0PSJkb25vcj09J2QxMDgnIikKZDEwOF9wYWlyd2lzZSA8LSBzbShhbGxfcGFpcndpc2UoZDEwOCwgbW9kZWxfYmF0Y2g9RkFMU0UpKQpkMTA4X3RhYmxlIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGQxMDhfcGFpcndpc2UpKQpzdW1tYXJ5KGQxMDhfdGFibGUkZGF0YSkKZDEwOF9zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhkMTA4X3RhYmxlLCBhY2NvcmRpbmdfdG89ImRlc2VxIiwgcD0wLjEsIHBfdHlwZT0icmF3IikpCmhlYWQoZDEwOF9zaWckZGVzZXEkdXBzW1sxXV0pCmQxMDhfbWEgPC0gZXh0cmFjdF9kZV9wbG90cyhkMTA4X3BhaXJ3aXNlLCBwPTAuMSwgdHlwZT0iZGVzZXEiLCBwX3R5cGU9InJhdyIpJG1hJHBsb3QKZDEwOF9tYQpwbG90X2hpc3RvZ3JhbShkMTA4X3RhYmxlW1siZGF0YSJdXVtbInNoX3ZzX2NociJdXVssIGMoImRlc2VxX3AiKV0pCnBsb3RfcGNhKHNtKG5vcm1hbGl6ZV9leHB0KGQxMDgsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpKSkkcGxvdAoKZDExMCA8LSBzdWJzZXRfZXhwdChoc19pbmZfZmlsdCwgc3Vic2V0PSJkb25vcj09J2QxMTAnIikKZDExMF9wYWlyd2lzZSA8LSBzbShhbGxfcGFpcndpc2UoZDExMCwgbW9kZWxfYmF0Y2g9RkFMU0UpKQpkMTEwX3RhYmxlIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKGQxMTBfcGFpcndpc2UpKQpzdW1tYXJ5KGQxMTBfdGFibGUkZGF0YSkKZDExMF9zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhkMTEwX3RhYmxlLCBhY2NvcmRpbmdfdG89ImRlc2VxIiwgcD0wLjEsIHBfdHlwZT0icmF3IikpCmhlYWQoZDExMF9zaWckZGVzZXEkdXBzW1sxXV0pCmQxMTBfbWEgPC0gZXh0cmFjdF9kZV9wbG90cyhkMTEwX3BhaXJ3aXNlLCBwPTAuMSwgbG9nZmM9MC42LCBwX3R5cGU9InJhdyIpJG1hJHBsb3QKZDExMF9tYQpwbG90X2hpc3RvZ3JhbShkMTEwX3RhYmxlW1siZGF0YSJdXVtbInNoX3ZzX2NociJdXVssIGMoImRlc2VxX3AiKV0pCnBsb3RfcGNhKHNtKG5vcm1hbGl6ZV9leHB0KGQxMTAsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpKSkkcGxvdAoKaHNfdG1wIDwtIHNldF9leHB0X2JhdGNoZXMoaHNfaW5mX2ZpbHQsIGZhY3Q9InBhdGhvZ2Vuc3RyYWluIikKaHNfdG1wMiA8LSBzbShub3JtYWxpemVfZXhwdChoc190bXAsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpKQpwbG90X3BjYShoc190bXAyKSRwbG90CmBgYAoKIyBSZW1vdmUgc2FtcGxlcyBmcm9tIHN0cmFpbiAyNTA0IGFuZC9vciAyMjI3CgpUaGlzIGJsb2NrIHdpbGwgZmlyc3QgcmVtb3ZlIHN0cmFpbiAyNTA0LCB0aGVuIDIyNzIuICBUaGUgcmVzdWx0aW5nIHN1YnNldHMgd2lsbApiZSB1c2VkIGZvciBhbm90aGVyIHJvdW5kIG9mIHRoZXNlIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzLgoKYGBge3IgcmVtb3ZlX3NhbXBsZXN9CnJlbW92ZV8yNTA0X2luZiA8LSBzdWJzZXRfZXhwdChoc19pbmZfZmlsdCwgc3Vic2V0PSJwYXRob2dlbnN0cmFpbiE9J3MyNTA0JyIpCnJlbW92ZV8yNTA0X2luZl9maWx0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV8yNTA0X2luZiwgZmlsdGVyPVRSVUUpKQpyZW1vdmVfMjI3Ml9pbmYgPC0gc3Vic2V0X2V4cHQoaHNfaW5mX2ZpbHQsIHN1YnNldD0icGF0aG9nZW5zdHJhaW4hPSdzMjI3MiciKQpyZW1vdmVfMjI3Ml9pbmZfZmlsdCA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfMjI3Ml9pbmYsIGZpbHRlcj1UUlVFKSkKcmVtb3ZlX2JvdGhfaW5mIDwtIHN1YnNldF9leHB0KHJlbW92ZV8yNTA0X2luZiwgc3Vic2V0PSJwYXRob2dlbnN0cmFpbiE9J3MyMjcyJyIpCnJlbW92ZV9ib3RoX2luZl9maWx0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV9ib3RoX2luZiwgZmlsdGVyPVRSVUUpKQoKcmVtb3ZlXzI1MDRfdW5pbmYgPC0gc3Vic2V0X2V4cHQoaHNfdW5pbmZfZmlsdCwgc3Vic2V0PSJwYXRob2dlbnN0cmFpbiE9J3MyNTA0JyIpCnJlbW92ZV8yNTA0X3VuaW5mX2ZpbHQgPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlXzI1MDRfdW5pbmYsIGZpbHRlcj1UUlVFKSkKcmVtb3ZlXzIyNzJfdW5pbmYgPC0gc3Vic2V0X2V4cHQoaHNfdW5pbmZfZmlsdCwgc3Vic2V0PSJwYXRob2dlbnN0cmFpbiE9J3MyMjcyJyIpCnJlbW92ZV8yMjcyX3VuaW5mX2ZpbHQgPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlXzIyNzJfdW5pbmYsIGZpbHRlcj1UUlVFKSkKcmVtb3ZlX2JvdGhfdW5pbmYgPC0gc3Vic2V0X2V4cHQocmVtb3ZlXzI1MDRfdW5pbmYsIHN1YnNldD0icGF0aG9nZW5zdHJhaW4hPSdzMjI3MiciKQpyZW1vdmVfYm90aF91bmluZl9maWx0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV9ib3RoX3VuaW5mLCBmaWx0ZXI9VFJVRSkpCmBgYAoKIyMgUmVtb3ZlIG9uZSBhbmFseXNlcwoKT25jZSB1c2luZyBiYXRjaCBpbiBtb2RlbCwgb25jZSB3aXRoIHN2YXNlcS4KSW4gbXkgZmlyc3Qgcm91bmQgb2YgZG9pbmcgdGhpcywgSSBkaWQgbm90IHByaW50IG91dCBtYW55IG1ldHJpY3MsIGxldCB1cyBiZQpiZXR0ZXIgYWJvdXQgdGhpcy4KCiMjIyBGaXJzdCBzb21lIHN1bW1hcnkgcGxvdHMKCkluIHRoZXNlIHBsb3RzLCB3ZSBjYW4gc2VlIHRoYXQgdGhlIG90aGVyIHN0cmFpbiBpcyBzdGlsbCBhIGJpdCB3ZWlyZCwKcGFydGljdWxhcmx5IGluIGRvbm9yIDEwOC4KCiMjIyMgTm8gdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciByZW1vdmVvbmVfc3VtbWFyeX0KcmVtb3ZlXzI1MDRfaW5mX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlXzI1MDRfaW5mX2ZpbHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpCnBsb3RfcGNhKHJlbW92ZV8yNTA0X2luZl9ub3JtKSRwbG90CnJlbW92ZV8yNTA0X2luZl9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV8yNTA0X2luZl9maWx0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0ic3Zhc2VxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybT0icXVhbnQiKSkKcGxvdF9wY2EocmVtb3ZlXzI1MDRfaW5mX25vcm0pJHBsb3QKcGxvdF9jb3JoZWF0KHJlbW92ZV8yNTA0X2luZl9ub3JtKSRwbG90CgpyZW1vdmVfMjI3Ml9pbmZfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfMjI3Ml9pbmZfZmlsdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiKSkKcGxvdF9wY2EocmVtb3ZlXzIyNzJfaW5mX25vcm0pJHBsb3QKcmVtb3ZlXzIyNzJfaW5mX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlXzIyNzJfaW5mX2ZpbHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtPSJxdWFudCIpKQpwbG90X3BjYShyZW1vdmVfMjI3Ml9pbmZfbm9ybSkkcGxvdApwbG90X2NvcmhlYXQocmVtb3ZlXzIyNzJfaW5mX25vcm0pJHBsb3QKCnJlbW92ZV9ib3RoX2luZl9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV9ib3RoX2luZl9maWx0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0PSJjcG0iLCBub3JtPSJxdWFudCIpKQpwbG90X3BjYShyZW1vdmVfYm90aF9pbmZfbm9ybSkkcGxvdApyZW1vdmVfYm90aF9pbmZfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfYm90aF9pbmZfZmlsdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YXNlcSIsIG5vcm09InF1YW50IikpCgpwbG90X3BjYShyZW1vdmVfYm90aF9pbmZfbm9ybSkkcGxvdApwbG90X2NvcmhlYXQocmVtb3ZlX2JvdGhfaW5mX25vcm0pJHBsb3QKYGBgCgojIyMjIEluY2x1ZGUgdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciByZW1vdmVvbmVfdW5pbmZfc3VtbWFyeX0KcmVtb3ZlXzI1MDRfdW5pbmZfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfMjUwNF91bmluZl9maWx0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0PSJjcG0iLCBub3JtPSJxdWFudCIpKQpwbG90X3BjYShyZW1vdmVfMjUwNF91bmluZl9ub3JtKSRwbG90CnJlbW92ZV8yNTA0X3VuaW5mX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlXzI1MDRfdW5pbmZfZmlsdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IikpCnBsb3RfcGNhKHJlbW92ZV8yNTA0X3VuaW5mX25vcm0pJHBsb3QKcGxvdF9jb3JoZWF0KHJlbW92ZV8yNTA0X3VuaW5mX25vcm0pJHBsb3QKCnJlbW92ZV8yMjcyX3VuaW5mX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlXzIyNzJfdW5pbmZfZmlsdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiKSkKcGxvdF9wY2EocmVtb3ZlXzIyNzJfdW5pbmZfbm9ybSkkcGxvdApyZW1vdmVfMjI3Ml91bmluZl9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV8yMjcyX3VuaW5mX2ZpbHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtPSJxdWFudCIpKQpwbG90X3BjYShyZW1vdmVfMjI3Ml91bmluZl9ub3JtKSRwbG90CnBsb3RfY29yaGVhdChyZW1vdmVfMjI3Ml91bmluZl9ub3JtKSRwbG90CgpyZW1vdmVfYm90aF91bmluZl9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV9ib3RoX3VuaW5mX2ZpbHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpCnBsb3RfcGNhKHJlbW92ZV9ib3RoX3VuaW5mX25vcm0pJHBsb3QKcmVtb3ZlX2JvdGhfdW5pbmZfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfYm90aF91bmluZl9maWx0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJzdmFzZXEiLCBub3JtPSJxdWFudCIpKQoKcGxvdF9wY2EocmVtb3ZlX2JvdGhfdW5pbmZfbm9ybSkkcGxvdApwbG90X2NvcmhlYXQocmVtb3ZlX2JvdGhfdW5pbmZfbm9ybSkkcGxvdApgYGAKCiMjIyBQZXJmb3JtIHZhcmlvdXMgREUgdGVzdHMKCk5vdyBsZXQgdXMgcGVyZm9ybSB0aGUgbGlrZWx5IGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzIGFuZCBzZWUgaG93IHRoZXkKbG9vay4KCiMjIyMgTm8gdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciByZW1vdmUyNTA0LCBmaWcuc2hvdz0iaGlkZSJ9CnJlbW92ZV8yNTA0X2luZl9kZSA8LSBzbShhbGxfcGFpcndpc2UocmVtb3ZlXzI1MDRfaW5mX2ZpbHQsIG1vZGVsX2JhdGNoPVRSVUUpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcmVtb3ZlMjUwNGluZl9iYXRjaG1vZGVsX2NvbnRyLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzI1MDRfaW5mX3RhYmxlIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKHJlbW92ZV8yNTA0X2luZl9kZSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwZXJzPWtlZXBlcnNfaW5mKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X3JlbW92ZTI1MDRpbmZfYmF0Y2htb2RlbF9zaWctdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjUwNF9pbmZfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMocmVtb3ZlXzI1MDRfaW5mX3RhYmxlLCBleGNlbD1leGNlbF9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iZGVzZXEiLCBwPTAuMSwgbGZjPTAuNikpCgpyZW1vdmVfMjUwNF9pbmZfZGVfc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShyZW1vdmVfMjUwNF9pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9InN2YXNlcSIpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcmVtb3ZlMjUwNGluZl9zdmFzZXFfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjUwNF9pbmZfdGFibGVfc3ZhIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKHJlbW92ZV8yNTA0X2luZl9kZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBlcnM9a2VlcGVyc19pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcmVtb3ZlMjUwNGluZl9zdmFzZXFfc2lnLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzI1MDRfaW5mX3NpZ19zdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhyZW1vdmVfMjUwNF9pbmZfdGFibGVfc3ZhLCBleGNlbD1leGNlbF9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iZGVzZXEiLCBwPTAuMSwgbGZjPTAuNikpCmBgYAoKIyMjIyBJbmNsdWRlIHVuaW5mZWN0ZWQgc2FtcGxlcwoKYGBge3IgcmVtb3ZlMjUwNF91bmluZiwgZmlnLnNob3c9ImhpZGUifQpyZW1vdmVfMjUwNF91bmluZl9kZSA8LSBhbGxfcGFpcndpc2UocmVtb3ZlXzI1MDRfdW5pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9VFJVRSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfdW5pbmZlY3RfcmVtb3ZlMjUwNHVuaW5mX2JhdGNobW9kZWxfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjUwNF91bmluZl90YWJsZSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhyZW1vdmVfMjUwNF91bmluZl9kZSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwZXJzPWtlZXBlcnNfdW5pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc191bmluZmVjdF9yZW1vdmUyNTA0dW5pbmZfYmF0Y2htb2RlbF9zaWctdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjUwNF91bmluZl9zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhyZW1vdmVfMjUwNF91bmluZl90YWJsZSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NvcmRpbmdfdG89ImRlc2VxIiwgcD0wLjEsIGxmYz0wLjYpKQoKcmVtb3ZlXzI1MDRfdW5pbmZfZGVfc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShyZW1vdmVfMjUwNF91bmluZl9maWx0LCBtb2RlbF9iYXRjaD0ic3Zhc2VxIikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX3VuaW5mZWN0X3JlbW92ZTI1MDR1bmluZl9zdmFzZXFfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjUwNF91bmluZl90YWJsZV9zdmEgPC0gc20oY29tYmluZV9kZV90YWJsZXMocmVtb3ZlXzI1MDRfdW5pbmZfZGVfc3ZhLCBleGNlbD1leGNlbF9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwZXJzPWtlZXBlcnNfdW5pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc191bmluZmVjdF9yZW1vdmUyNTA0dW5pbmZfc3Zhc2VxX3NpZy12e3Zlcn0ueGxzeCIpCnJlbW92ZV8yNTA0X3VuaW5mX3NpZ19zdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhyZW1vdmVfMjUwNF91bmluZl90YWJsZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iZGVzZXEiLCBwPTAuMSwgbGZjPTAuNikpCmBgYAoKIyMjIFBsb3RzIG9mIHJlbW92ZSAyNTA0CgpQcmludCBhIGZldyBwbG90cyBkZXNjcmliaW5nIHdoYXQganVzdCBoYXBwZW5lZC4KCiMjIyMgTm8gdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciBwbG90MjUwNH0KcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV8yNTA0X2luZl90YWJsZSRkYXRhW1sxXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlXzI1MDRfaW5mX3RhYmxlJGRlc2VxX21hX3Bsb3RzW1sxXV0kcGxvdApwdmFsdWVzIDwtIHNtKHBsb3RfZGVfcHZhbHMocmVtb3ZlXzI1MDRfaW5mX3RhYmxlX3N2YSRkYXRhW1sxXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlXzI1MDRfaW5mX3RhYmxlX3N2YSRkZXNlcV9tYV9wbG90c1tbMV1dJHBsb3QKYGBgCgojIyMjIEluY2x1ZGUgdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciBwbG90XzI1MDR1bmluZn0KcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV8yNTA0X3VuaW5mX3RhYmxlJGRhdGFbWyJjaF9zaCJdXSkpCnB2YWx1ZXMkcGxvdApyZW1vdmVfMjUwNF91bmluZl90YWJsZSRkZXNlcV9tYV9wbG90c1tbImNoX3NoIl1dJHBsb3QKcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV8yNTA0X3VuaW5mX3RhYmxlX3N2YSRkYXRhW1siY2hfc2giXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlXzI1MDRfdW5pbmZfdGFibGVfc3ZhJGRlc2VxX21hX3Bsb3RzW1siY2hfc2giXV0kcGxvdApgYGAKCiMjIFJlcGVhdCB3aXRoIHRoZSByZW1vdmFsIG9mIHN0cmFpbiAyMjcyCgojIyMgUGVyZm9ybSBkZSBhbmFseXNlcwoKIyMjIyBObyB1bmluZmVjdGVkIHNhbXBsZXMKCmBgYHtyIHJlbW92ZTIyNzIsIGZpZy5zaG93PSJoaWRlIn0KcmVtb3ZlXzIyNzJfaW5mX2RlIDwtIHNtKGFsbF9wYWlyd2lzZShyZW1vdmVfMjI3Ml9pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9VFJVRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9yZW1vdmUyMjcyaW5mX2JhdGNobW9kZWxfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjI3Ml9pbmZfdGFibGUgPC0gc20oY29tYmluZV9kZV90YWJsZXMocmVtb3ZlXzIyNzJfaW5mX2RlLCBleGNlbD1leGNlbF9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBlcnM9a2VlcGVyc19pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcmVtb3ZlMjI3MmluZl9iYXRjaG1vZGVsX3NpZy12e3Zlcn0ueGxzeCIpCnJlbW92ZV8yMjcyX2luZl9zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhyZW1vdmVfMjI3Ml9pbmZfdGFibGUsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvPSJkZXNlcSIsIHA9MC4xLCBsZmM9MC42KSkKCnJlbW92ZV8yMjcyX2luZl9kZV9zdmEgPC0gc20oYWxsX3BhaXJ3aXNlKHJlbW92ZV8yMjcyX2luZl9maWx0LCBtb2RlbF9iYXRjaD0ic3Zhc2VxIikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9yZW1vdmUyMjcyaW5mX3N2YXNlcV9jb250ci12e3Zlcn0ueGxzeCIpCnJlbW92ZV8yMjcyX2luZl90YWJsZV9zdmEgPC0gc20oY29tYmluZV9kZV90YWJsZXMocmVtb3ZlXzIyNzJfaW5mX2RlX3N2YSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1rZWVwZXJzX2luZikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9yZW1vdmUyMjcyaW5mX3N2YXNlcV9zaWctdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjI3Ml9pbmZfc2lnX3N2YSA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHJlbW92ZV8yMjcyX2luZl90YWJsZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvPSJkZXNlcSIsIHA9MC4xLCBsZmM9MC42KSkKYGBgCgojIyMjIE5vIHVuaW5mZWN0ZWQgc2FtcGxlcwoKYGBge3IgcmVtb3ZlMjI3Ml91bmluZiwgZmlnLnNob3c9ImhpZGUifQpyZW1vdmVfMjI3Ml91bmluZl9kZSA8LSBzbShhbGxfcGFpcndpc2UocmVtb3ZlXzIyNzJfdW5pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9VFJVRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX3VuaW5mZWN0X3JlbW92ZTIyNzJ1bmluZl9iYXRjaG1vZGVsX2NvbnRyLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzIyNzJfdW5pbmZfdGFibGUgPC0gc20oY29tYmluZV9kZV90YWJsZXMocmVtb3ZlXzIyNzJfdW5pbmZfZGUsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1rZWVwZXJzX3VuaW5mKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfdW5pbmZlY3RfcmVtb3ZlMjI3MnVuaW5mX2JhdGNobW9kZWxfc2lnLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzIyNzJfdW5pbmZfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMocmVtb3ZlXzIyNzJfdW5pbmZfdGFibGUsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvPSJkZXNlcSIsIHA9MC4xLCBsZmM9MC42KSkKCnJlbW92ZV8yMjcyX3VuaW5mX2RlX3N2YSA8LSBzbShhbGxfcGFpcndpc2UocmVtb3ZlXzIyNzJfdW5pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9InN2YXNlcSIpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc191bmluZmVjdF9yZW1vdmUyMjcydW5pbmZfc3Zhc2VxX2NvbnRyLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzIyNzJfdW5pbmZfdGFibGVfc3ZhIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKHJlbW92ZV8yMjcyX3VuaW5mX2RlX3N2YSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1rZWVwZXJzX3VuaW5mKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfdW5pbmZlY3RfcmVtb3ZlMjI3MnVuaW5mX3N2YXNlcV9zaWctdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfMjI3Ml91bmluZl9zaWdfc3ZhIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMocmVtb3ZlXzIyNzJfdW5pbmZfdGFibGVfc3ZhLCBleGNlbD1leGNlbF9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NvcmRpbmdfdG89ImRlc2VxIiwgcD0wLjEsIGxmYz0wLjYpKQpgYGAKCiMjIyBQbG90cyBvZiByZW1vdmUgMjI3MgoKUHJpbnQgYSBmZXcgcGxvdHMgZGVzY3JpYmluZyB3aGF0IGp1c3QgaGFwcGVuZWQuCgojIyMjIE5vIHVuaW5mZWN0ZWQgc2FtcGxlcwoKYGBge3IgcGxvdDIyNzJ9CnB2YWx1ZXMgPC0gc20ocGxvdF9kZV9wdmFscyhyZW1vdmVfMjI3Ml9pbmZfdGFibGUkZGF0YVtbMV1dKSkKcHZhbHVlcyRwbG90CnJlbW92ZV8yMjcyX2luZl90YWJsZSRkZXNlcV9tYV9wbG90c1tbMV1dJHBsb3QKcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV8yMjcyX2luZl90YWJsZV9zdmEkZGF0YVtbMV1dKSkKcHZhbHVlcyRwbG90CnJlbW92ZV8yMjcyX2luZl90YWJsZV9zdmEkZGVzZXFfbWFfcGxvdHNbWzFdXSRwbG90CmBgYAoKIyMjIyBJbmNsdWRlIHVuaW5mZWN0ZWQgc2FtcGxlcwoKYGBge3IgcGxvdDIyNzJfdW5pbmZ9CnB2YWx1ZXMgPC0gc20ocGxvdF9kZV9wdmFscyhyZW1vdmVfMjI3Ml91bmluZl90YWJsZSRkYXRhW1siY2hfc2giXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlXzIyNzJfdW5pbmZfdGFibGUkZGVzZXFfbWFfcGxvdHNbWyJjaF9zaCJdXSRwbG90CnB2YWx1ZXMgPC0gc20ocGxvdF9kZV9wdmFscyhyZW1vdmVfMjI3Ml91bmluZl90YWJsZV9zdmEkZGF0YVtbImNoX3NoIl1dKSkKcHZhbHVlcyRwbG90CnJlbW92ZV8yMjcyX3VuaW5mX3RhYmxlX3N2YSRkZXNlcV9tYV9wbG90c1tbImNoX3NoIl1dJHBsb3QKYGBgCgojIyBSZW1vdmUgdHdvIGFuYWx5c2VzCgpSZXBlYXQgYXMgYWJvdmUsIHJlbW92aW5nIGJvdGggd2VpcmRvIHNhbXBsZXMuCgojIyMgUGVyZm9ybSBzdW1tYXJ5IFBDQQoKV2hlbiB3ZSBwbG90IHRoZSBwY2EvY29yaGVhdCB0aG91Z2gsIHRoZXNlIGxvb2sgYSBiaXQgbGVzcyBjbGVhci4KCiMjIyMgTm8gdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciByZW1vdmVib3RoX3N1bW1hcnl9CnJlbW92ZV9ib3RoX2luZl9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHJlbW92ZV9ib3RoX2luZl9maWx0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0PSJjcG0iLCBub3JtPSJxdWFudCIpKQpwbG90X3BjYShyZW1vdmVfYm90aF9pbmZfbm9ybSkkcGxvdApyZW1vdmVfYm90aF9pbmZfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfYm90aF9pbmZfZmlsdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IikpCnBsb3RfcGNhKHJlbW92ZV9ib3RoX2luZl9ub3JtKSRwbG90CnBsb3RfY29yaGVhdChyZW1vdmVfYm90aF9pbmZfbm9ybSkkcGxvdApgYGAKCiMjIyMgSW5jbHVkZSB1bmluZmVjdGVkIHNhbXBsZXMKCmBgYHtyIHJlbW92ZWJvdGhfc3VtbWFyeV91bmluZn0KcmVtb3ZlX2JvdGhfdW5pbmZfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChyZW1vdmVfYm90aF91bmluZl9maWx0LCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0PSJjcG0iLCBub3JtPSJxdWFudCIpKQpwbG90X3BjYShyZW1vdmVfYm90aF91bmluZl9ub3JtKSRwbG90CnJlbW92ZV9ib3RoX3VuaW5mX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQocmVtb3ZlX2JvdGhfdW5pbmZfZmlsdCwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IikpCnBsb3RfcGNhKHJlbW92ZV9ib3RoX3VuaW5mX25vcm0pJHBsb3QKcGxvdF9jb3JoZWF0KHJlbW92ZV9ib3RoX3VuaW5mX25vcm0pJHBsb3QKYGBgCgojIyMgUGVyZm9ybSBkZSBhbmFseXNlcwoKIyMjIyBObyB1bmluZmVjdGVkIHNhbXBsZXMKCmBgYHtyIHJlbW92ZWJvdGhfZGUsIGZpZy5zaG93PSJoaWRlIn0KcmVtb3ZlX2JvdGhfaW5mX2RlIDwtIHNtKGFsbF9wYWlyd2lzZShyZW1vdmVfYm90aF9pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9VFJVRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9yZW1vdmVib3RoaW5mX2JhdGNobW9kZWxfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfYm90aF9pbmZfdGFibGUgPC0gc20oY29tYmluZV9kZV90YWJsZXMocmVtb3ZlX2JvdGhfaW5mX2RlLCBleGNlbD1leGNlbF9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1rZWVwZXJzX2luZikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9yZW1vdmVib3RoaW5mX2JhdGNobW9kZWxfc2lnLXZ7dmVyfS54bHN4IikKcmVtb3ZlX2JvdGhfaW5mX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHJlbW92ZV9ib3RoX2luZl90YWJsZSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iZGVzZXEiLCBwPTAuMSwgbGZjPTAuNikpCgpyZW1vdmVfYm90aF9pbmZfZGVfc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShyZW1vdmVfYm90aF9pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9InN2YXNlcSIpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcmVtb3ZlYm90aGluZl9zdmFzZXFfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfYm90aF9pbmZfdGFibGVfc3ZhIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKHJlbW92ZV9ib3RoX2luZl9kZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1rZWVwZXJzX2luZikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9yZW1vdmVib3RoaW5mX3N2YXNlcV9zaWctdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfYm90aF9pbmZfc2lnX3N2YSA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHJlbW92ZV9ib3RoX2luZl90YWJsZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvPSJkZXNlcSIsIHA9MC4xLCBsZmM9MC42KSkKYGBgCgojIyMjIEluY2x1ZGUgdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciByZW1vdmVib3RoX2RlX3VuaW5mLCBmaWcuc2hvdz0iaGlkZSJ9CnJlbW92ZV9ib3RoX3VuaW5mX2RlIDwtIHNtKGFsbF9wYWlyd2lzZShyZW1vdmVfYm90aF91bmluZl9maWx0LCBtb2RlbF9iYXRjaD1UUlVFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfdW5pbmZlY3RfcmVtb3ZlYm90aHVuaW5mX2JhdGNobW9kZWxfY29udHItdnt2ZXJ9Lnhsc3giKQpyZW1vdmVfYm90aF91bmluZl90YWJsZSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhyZW1vdmVfYm90aF91bmluZl9kZSwgZXhjZWw9ZXhjZWxfZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1rZWVwZXJzX3VuaW5mKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfdW5pbmZlY3RfcmVtb3ZlYm90aHVuaW5mX2JhdGNobW9kZWxfc2lnLXZ7dmVyfS54bHN4IikKcmVtb3ZlX2JvdGhfdW5pbmZfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMocmVtb3ZlX2JvdGhfdW5pbmZfdGFibGUsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iZGVzZXEiLCBwPTAuMSwgbGZjPTAuNikpCgpyZW1vdmVfYm90aF91bmluZl9kZV9zdmEgPC0gc20oYWxsX3BhaXJ3aXNlKHJlbW92ZV9ib3RoX3VuaW5mX2ZpbHQsIG1vZGVsX2JhdGNoPSJzdmFzZXEiKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfdW5pbmZlY3RfcmVtb3ZlYm90aHVuaW5mX3N2YXNlcV9jb250ci12e3Zlcn0ueGxzeCIpCnJlbW92ZV9ib3RoX3VuaW5mX3RhYmxlX3N2YSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhyZW1vdmVfYm90aF91bmluZl9kZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwZXJzPWtlZXBlcnNfdW5pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc191bmluZmVjdF9yZW1vdmVib3RodW5pbmZfc3Zhc2VxX3NpZy12e3Zlcn0ueGxzeCIpCnJlbW92ZV9ib3RoX3VuaW5mX3NpZ19zdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhyZW1vdmVfYm90aF91bmluZl90YWJsZV9zdmEsIGV4Y2VsPWV4Y2VsX2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NvcmRpbmdfdG89ImRlc2VxIiwgcD0wLjEsIGxmYz0wLjYpKQpgYGAKCiMjIyBQbG90IHJlc3VsdHMKCiMjIyMgTm8gdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciBwbG90Ym90aH0KcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV9ib3RoX2luZl90YWJsZSRkYXRhW1sxXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlX2JvdGhfaW5mX3RhYmxlJGRlc2VxX21hX3Bsb3RzW1sxXV0kcGxvdApwdmFsdWVzIDwtIHNtKHBsb3RfZGVfcHZhbHMocmVtb3ZlX2JvdGhfaW5mX3RhYmxlX3N2YSRkYXRhW1sxXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlX2JvdGhfaW5mX3RhYmxlX3N2YSRkZXNlcV9tYV9wbG90c1tbMV1dJHBsb3QKYGBgCgojIyMjIEluY2x1ZGUgdW5pbmZlY3RlZCBzYW1wbGVzCgpgYGB7ciBwbG90Ym90aF91bmluZn0KcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV9ib3RoX3VuaW5mX3RhYmxlJGRhdGFbWyJjaF9zaCJdXSkpCnB2YWx1ZXMkcGxvdApyZW1vdmVfYm90aF91bmluZl90YWJsZSRkZXNlcV9tYV9wbG90c1tbImNoX3NoIl1dJHBsb3QKcHZhbHVlcyA8LSBzbShwbG90X2RlX3B2YWxzKHJlbW92ZV9ib3RoX3VuaW5mX3RhYmxlX3N2YSRkYXRhW1siY2hfc2giXV0pKQpwdmFsdWVzJHBsb3QKcmVtb3ZlX2JvdGhfdW5pbmZfdGFibGVfc3ZhJGRlc2VxX21hX3Bsb3RzW1siY2hfc2giXV0kcGxvdApgYGAKCiMjIEludGVyYWN0aW9uIG1vZGVsKHMpCgpUcnkgYnVpbGRpbmcgYSBkb25vcipzdGF0ZSBpbnRlcmFjdGlvbiBtb2RlbC4KCkkgdGhpbmsgSSByZWFsaXplZCBteSBjb25mdXNpb24gaW4gdGhpczogdGhlIG9ubHkgaW50ZXJhY3Rpb24gbW9kZWxzIEkgaGF2ZSB1c2VkIGJlZm9yZSB3ZXJlIGEKZXhwZXJpbWVudGFsIGZhY3RvcipleHBlcmltZW50YWwgZmxvYXRpbmctcG9pbnQgb2JzZXJ2YXRpb24uICBJZiBpdCBpcyB0aGUgY2FzZSwgdGhhdCB0aGUgZm9sbG93aW5nCm1vZGVscyBhcmUgYWxsIHggdnMuIGZhY3Rvcl9yZWZlcmVuY2UsIHRoZW4gSSBndWVzcyBpdCBtYWtlcyBzZW5zZTsgYnV0IGlmIG5vdCwgdGhlbiBJIGhhdmUgbm8KY2x1ZSB3aGF0IGlzIGdvaW5nIG9uIGluIHRoZXNlLgoKIyMjIE1vZGVsIG1hdHJpY2VzCgpGaXJzdCBtYWtlIHN1cmUgdGhhdCBzZWxmLWhlYWxpbmcgaXMgdGhlIHJlZmVyZW5jZS4KClRoZW4gbWFrZSBzb21lIGRlc2lnbnMgb2YgcG90ZW50aWFsIGludGVyZXN0LgoKYGBge3IgbWFrZV9tb2RlbHN9CmRhdGEgPC0gZWRnZVI6OkRHRUxpc3QoZXhwcnMoaHNfaW5mX2ZpbHQpKQpkYXRhIDwtIGVkZ2VSOjpjYWxjTm9ybUZhY3RvcnMoZGF0YSkKZGVzaWduIDwtIHBEYXRhKGhzX2luZl9maWx0KQoKZGVzaWduW1siY29uZGl0aW9uIl1dIDwtIHJlbGV2ZWwoZGVzaWduW1siY29uZGl0aW9uIl1dLCByZWY9InNoIikKZGVzaWduW1siZG9ub3IiXV0gPC0gYXMuZmFjdG9yKGRlc2lnbltbImRvbm9yIl1dKQpkZXNpZ25bWyJkb25vciJdXSA8LSByZWxldmVsKGRlc2lnbltbImRvbm9yIl1dLCByZWY9ImQxMDciKQoKY2hzaCA8LSBtb2RlbC5tYXRyaXgob2JqZWN0PX4wK2NvbmRpdGlvbiwgZGF0YT1kZXNpZ24pCmhlYWQoY2hzaCkgIyMgTG9va3MgZ29vZCB0byBtZS4KZG9ub3JzIDwtIG1vZGVsLm1hdHJpeChvYmplY3Q9fjArZG9ub3IsIGRhdGE9ZGVzaWduKQpoZWFkKGRvbm9ycykKCmNvbmRfZG9ub3JfaW50ZXIgPC0gbW9kZWwubWF0cml4KG9iamVjdD1+MCtjb25kaXRpb24rZG9ub3IrY29uZGl0aW9uOmRvbm9yLCBkYXRhPWRlc2lnbikKaGVhZChjb25kX2Rvbm9yX2ludGVyKQojIyBXaHkgYXJlIHRoZXJlIG5vIGNvbmRpdGlvbmNocjpkb25vcjEwNyBjb25kaXRpb25zaDpkb25vcjEwNyBjb2x1bW5zPwojIyBJIGtub3cgdGhhdCBpZiBJIHJlbGV2ZWwgdGhlIGRvbm9yIGZhY3RvciB0byBzZXQgdGhlIHJlZmVyZW5jZSB0byBhbm90aGVyIGRvbm9yLCB0aGF0IGNoYW5nZXMKIyMgYnV0IHRoaXMgc3RpbGwgZG9lcyBub3QgbWFrZSBzZW5zZSB0byBtZS4KCiMjIEkgdGhpbmsgdGhlIGFib3ZlIG1vZGVsIHNob3VsZCBiZSB0aGUgc2FtZSBhczoKY29uZF9kb25vcl9pbnRlcnYyIDwtIG1vZGVsLm1hdHJpeChvYmplY3Q9fjArY29uZGl0aW9uKmRvbm9yLCBkYXRhPWRlc2lnbikKaGVhZChjb25kX2Rvbm9yX2ludGVydjIpCnRlc3R0aGF0OjpleHBlY3RfZXF1YWwoY29uZF9kb25vcl9pbnRlciwgY29uZF9kb25vcl9pbnRlcnYyKQoKIyMgU28gYXMgSSB1bmRlcnN0YW5kIGl0LCBpZiBJIGRvIGEgdGVzdCBvZiBjb2VmPSdjb25kaXRpb25jaHInLCB0aGlzIGlzIGxvb2tpbmcgYXQKIyMgY2hyIHZzLiBzaAojIyBJZiBJIGRvIGNvZWY9J2NvbmRpdGlvbmNocjpkb25vcjExMCcgdGhpcyBpcyB0aGUgZG9ub3IgZWZmZWN0IGZvciBjaHIvc2ggZm9yIGRvbm9yMTEwPwojIyBJZiB0aGlzIGlzIHRydWUsIHRoZW4gaG93IGRvIEkgZ2V0IHRoaXMgZm9yIGRvbm9yMTA3PwojIyBQZXJoYXBzIG15IHVuZGVyc3RhbmRpbmcgaXMgYmFja3dhcmRzPwoKZG9ub3JfY29uZF9pbnRlciA8LSBtb2RlbC5tYXRyaXgob2JqZWN0PX5kb25vcitjb25kaXRpb24rZG9ub3I6Y29uZGl0aW9uLCBkYXRhPWRlc2lnbikKZG9ub3JfY29uZF9pbnRlcnYyIDwtIG1vZGVsLm1hdHJpeChvYmplY3Q9fmRvbm9yKmNvbmRpdGlvbiwgZGF0YT1kZXNpZ24pCnRlc3R0aGF0OjpleHBlY3RfZXF1YWwoZG9ub3JfY29uZF9pbnRlciwgZG9ub3JfY29uZF9pbnRlcnYyKQpoZWFkKGRvbm9yX2NvbmRfaW50ZXIpCmBgYAoKIyMjIExpbW1hIGltcGxlbWVudGF0aW9uCgpgYGB7ciBpbnRlcmFjdGlvbl90ZXN0fQp2b29tIDwtIGxpbW1hOjp2b29tKGNvdW50cz1kYXRhLCBkZXNpZ249Y29uZF9kb25vcl9pbnRlciwKICAgICAgICAgICAgICAgICAgICBub3JtYWxpemUubWV0aG9kPSJxdWFudCIsIHBsb3Q9VFJVRSkKZml0dGVkIDwtIGxpbW1hOjpsbUZpdChvYmplY3Q9dm9vbSwgZGVzaWduPWNvbmRfZG9ub3JfaW50ZXIpCmJheWVzIDwtIGxpbW1hOjplQmF5ZXMoZml0dGVkKQpyZXN1bHQgPC0gdG9wVGFibGUoYmF5ZXMpCmBgYAoKIyMjIGVkZ2VSIGltcGxlbWVudGF0aW9uCgpgYGB7ciBpbnRlcmFjdGlvbl9lZGdlcn0KZGlzcCA8LSBlZGdlUjo6ZXN0aW1hdGVEaXNwKGRhdGEsIGRlc2lnbj1jb25kX2Rvbm9yX2ludGVyKQpmaXQgPC0gZWRnZVI6OmdsbVFMRml0KGRpc3AsIGNvbmRfZG9ub3JfaW50ZXIpCgojIyBJIHRoaW5rIHRoaXMgaXMgbXkgZ2xvYmFsIGNoci9zaApjaHJfc2hfcWxmIDwtIGVkZ2VSOjpnbG1RTEZUZXN0KGZpdCwgY29lZj0iY29uZGl0aW9uY2hyIikKY2hyX3NoX3Jlc3VsdCA8LSBlZGdlUjo6dG9wVGFncyhjaHJfc2hfcWxmKQpzdW1tYXJ5KGNocl9zaF9yZXN1bHQkdGFibGUpCgojIyBUaGlzIHNob3VsZCBiZSB0aGUgaW50ZXJhY3Rpb24gZm9yIGNoci9zaCBhbmQgZG9ub3IxMTAuCmNvbG5hbWVzKGNvbmRfZG9ub3JfaW50ZXIpWzVdCmQxMTBfY2hfcWxmIDwtIGVkZ2VSOjpnbG1RTEZUZXN0KGZpdCwgY29lZj0iY29uZGl0aW9uY2hyOmRvbm9yZDExMCIpCmQxMTBfY2hfcmVzdWx0IDwtIGVkZ2VSOjp0b3BUYWdzKGQxMTBfY2hfcWxmKQpzdW1tYXJ5KGQxMTBfY2hfcmVzdWx0JHRhYmxlKQpgYGAKCiMjIyBERVNlcTIgaW1wbGVtZW50YXRpb24KCmBgYHtyIGludGVyYWN0aW9uX2Rlc2VxfQpzdW1tYXJpemVkIDwtIERFU2VxMjo6REVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGE9ZXhwcnMoaHNfaW5mX2ZpbHQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhPWRlc2lnbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduPX5jb25kaXRpb24qZG9ub3IpCmRhdGFzZXQgPC0gREVTZXEyOjpERVNlcURhdGFTZXQoc2U9c3VtbWFyaXplZCwgZGVzaWduPX5jb25kaXRpb24qZG9ub3IpCnJ1biA8LSBERVNlcTI6OkRFU2VxKGRhdGFzZXQpCkRFU2VxMjo6cmVzdWx0c05hbWVzKHJ1bikKcmVzX2Nocl9zaCA8LSBERVNlcTI6OnJlc3VsdHMocnVuLCBuYW1lPSJjb25kaXRpb25fY2hyX3ZzX3NoIikKc3VtbWFyeShyZXNfY2hyX3NoKQpoZWFkKHJlc19jaHJfc2gpCgojIyBNYXliZSBteSB0aGlua2luZyBpcyBqdXN0IGEgbGl0dGxlIHdyb25nOiBpcyB0aGlzIHRoZSBpbnRlcmFjdGlvbiBvZiBjaHIvc2ggd2l0aCBkMTEwL2QxMDc/CiMjIFRoYXQgd291bGQgbWFrZSBtb3JlIHNlbnNlIEkgdGhpbmsuCnJlc19kb25vcjExMF9jaHJzaCA8LSBERVNlcTI6OnJlc3VsdHMocnVuLCBuYW1lPSJjb25kaXRpb25jaHIuZG9ub3JkMTEwIikKc3VtbWFyeShyZXNfZG9ub3IxMTBfY2hyc2gpCmhlYWQocmVzX2Rvbm9yMTEwX2NocnNoKQoKcmVzX2Rvbm9yMTA4X2NocnNoIDwtIERFU2VxMjo6cmVzdWx0cyhydW4sIG5hbWU9ImNvbmRpdGlvbmNoci5kb25vcmQxMDgiKQpzdW1tYXJ5KHJlc19kb25vcjExMF9jaHJzaCkKaGVhZChyZXNfZG9ub3IxMTBfY2hyc2gpCgpyZXNfZG9ub3IxMTBfdnNfMTA3IDwtIERFU2VxMjo6cmVzdWx0cyhydW4sIG5hbWU9ImRvbm9yX2QxMTBfdnNfZDEwNyIpCnN1bW1hcnkocmVzX2Rvbm9yMTEwX3ZzXzEwNykKaGVhZChyZXNfZG9ub3IxMTBfdnNfMTA3KQpgYGAKCiMjIFBDIGxvYWRpbmdzCgpgYGB7ciBwY19sb2FkaW5nLCBmaWcuc2hvdz0iaGlkZSJ9CnNjb3JlcyA8LSBwY2FfaGlnaHNjb3Jlcyhoc19pbmZfZmlsdCwgbj01MCkKc2NvcmVzJGhpZ2hlc3RbLCAxOjJdCmFubm90IDwtIGZEYXRhKGhzX2luZl9maWx0KQoKY29tcDFfZ2VuZXMgPC0gdW5saXN0KHN0cnNwbGl0KHg9YXMuY2hhcmFjdGVyKHNjb3JlcyRoaWdoZXN0WywgMV0pLCBzcGxpdD0iOiIpKQppZHggPC0gZ3JlcChwYXR0ZXJuPSJeRU5TRyIsIHg9Y29tcDFfZ2VuZXMpCmNvbXAxX2dlbmVzIDwtIGNvbXAxX2dlbmVzW2lkeF0KY29tcDFfaGlnaF9zY29yZXMgPC0gZXhjbHVkZV9nZW5lc19leHB0KGhzX2luZl9maWx0LCBpZHM9Y29tcDFfZ2VuZXMsIG1ldGhvZD0ia2VlcCIpCmtuaXRyOjprYWJsZShhbm5vdFtjb21wMV9nZW5lcywgYygiZW5zZW1ibF9nZW5lX2lkIiwgImRlc2NyaXB0aW9uIildKQoKY29tcDJfZ2VuZXMgPC0gdW5saXN0KHN0cnNwbGl0KHg9YXMuY2hhcmFjdGVyKHNjb3JlcyRoaWdoZXN0WywgMl0pLCBzcGxpdD0iOiIpKQppZHggPC0gZ3JlcChwYXR0ZXJuPSJeRU5TRyIsIHg9Y29tcDJfZ2VuZXMpCmNvbXAyX2dlbmVzIDwtIGNvbXAyX2dlbmVzW2lkeF0KY29tcDJfaGlnaF9zY29yZXMgPC0gZXhjbHVkZV9nZW5lc19leHB0KGhzX2luZl9maWx0LCBpZHM9Y29tcDJfZ2VuZXMsIG1ldGhvZD0ia2VlcCIpCmtuaXRyOjprYWJsZShhbm5vdFtjb21wMl9nZW5lcywgYygiZW5zZW1ibF9nZW5lX2lkIiwgImRlc2NyaXB0aW9uIildKQoKY29tcDNfZ2VuZXMgPC0gdW5saXN0KHN0cnNwbGl0KHg9YXMuY2hhcmFjdGVyKHNjb3JlcyRoaWdoZXN0WywgM10pLCBzcGxpdD0iOiIpKQppZHggPC0gZ3JlcChwYXR0ZXJuPSJeRU5TRyIsIHg9Y29tcDNfZ2VuZXMpCmNvbXAzX2dlbmVzIDwtIGNvbXAzX2dlbmVzW2lkeF0KY29tcDNfaGlnaF9zY29yZXMgPC0gZXhjbHVkZV9nZW5lc19leHB0KGhzX2luZl9maWx0LCBpZHM9Y29tcDNfZ2VuZXMsIG1ldGhvZD0ia2VlcCIpCmtuaXRyOjprYWJsZShhbm5vdFtjb21wM19nZW5lcywgYygiZW5zZW1ibF9nZW5lX2lkIiwgImRlc2NyaXB0aW9uIildKQpgYGAKCiMjIyBQQyBsb2FkaW5nIHBsb3RzCgpgYGB7ciBwY19sb2FkaW5nX3Bsb3R9CnNjb3JlcyRwY2FfaGlzdApwbG90X3NhbXBsZV9oZWF0bWFwKAogIGRhdGE9c20obm9ybWFsaXplX2V4cHQoY29tcDFfaGlnaF9zY29yZXMsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpLAogIHJvd19sYWJlbD1OVUxMKQpwbG90X3NhbXBsZV9oZWF0bWFwKAogIGRhdGE9c20obm9ybWFsaXplX2V4cHQoY29tcDJfaGlnaF9zY29yZXMsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpLAogIHJvd19sYWJlbD1OVUxMKQpwbG90X3NhbXBsZV9oZWF0bWFwKAogIGRhdGE9c20obm9ybWFsaXplX2V4cHQoY29tcDNfaGlnaF9zY29yZXMsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpLAogIHJvd19sYWJlbD1OVUxMKQpgYGAKCiMjIyBTaGVuYW5pZ2FucwoKYGBge3IgaHNfc2hlbmFuaWdhbnN9CnRlc3QgPC0gc20oY3JlYXRlX2V4cHQobWV0YWRhdGE9InNhbXBsZV9zaGVldHMvcGJtY19zYW1wbGVzLW1hbnVhbF9zd2l0Y2gueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW49Imh1bWFuZmlsZSIpKQp0ZXN0IDwtIHN1YnNldF9leHB0KHRlc3QsIHN1YnNldD0iY29uZGl0aW9uIT0ndW5pbmYnIikKdGVzdF9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHRlc3QsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIpKQpwbG90X3BjYSh0ZXN0X25vcm0pJHBsb3QKCnRlc3RfYmF0Y2ggPC0gc20obm9ybWFsaXplX2V4cHQodGVzdCwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwgZmlsdGVyPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybT0icXVhbnQiLCBiYXRjaD0icnV2ZyIpKQpwbG90X3BjYSh0ZXN0X2JhdGNoKSRwbG90CgpzY29yZXMgPC0gcGNhX2hpZ2hzY29yZXModGVzdF9iYXRjaCwgbj01MCkKc2NvcmVzJGhpZ2hlc3RbLCAxOjJdCmFubm90IDwtIGZEYXRhKGhzX2luZl9maWx0KQpjb21wMV9nZW5lcyA8LSB1bmxpc3Qoc3Ryc3BsaXQoeD1hcy5jaGFyYWN0ZXIoc2NvcmVzJGhpZ2hlc3RbLCAxXSksIHNwbGl0PSI6IikpCmlkeCA8LSBncmVwKHBhdHRlcm49Il5FTlNHIiwgeD1jb21wMV9nZW5lcykKY29tcDFfZ2VuZXMgPC0gY29tcDFfZ2VuZXNbaWR4XQpjb21wMV9oaWdoX3Njb3JlcyA8LSBleGNsdWRlX2dlbmVzX2V4cHQodGVzdF9iYXRjaCwgaWRzPWNvbXAxX2dlbmVzLCBtZXRob2Q9ImtlZXAiKQpwbG90X3NhbXBsZV9oZWF0bWFwKAogIGRhdGE9c20obm9ybWFsaXplX2V4cHQoY29tcDFfaGlnaF9zY29yZXMsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpLAogIHJvd19sYWJlbD1OVUxMKQprbml0cjo6a2FibGUoYW5ub3RbY29tcDFfZ2VuZXMsIGMoImVuc2VtYmxfZ2VuZV9pZCIsICJkZXNjcmlwdGlvbiIpXSkKCnRlc3RfZmlsdCA8LSBzbShub3JtYWxpemVfZXhwdCh0ZXN0LCBmaWx0ZXI9VFJVRSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9zd2l0Y2hvbmVfY29udHItdnt2ZXJ9Lnhsc3giKQp0ZXN0X2RlIDwtIHNtKGFsbF9wYWlyd2lzZSh0ZXN0X2ZpbHQsIG1vZGVsX2JhdGNoPVRSVUUpKQp0ZXN0X3Bsb3RzIDwtIGV4dHJhY3RfZGVfcGxvdHModGVzdF9kZSkKdGVzdF90YWJsZSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyh0ZXN0X2RlLCBleGNlbD1leGNlbF9maWxlKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X3N3aXRjaG9uZV9zaWctdnt2ZXJ9Lnhsc3giKQp0ZXN0X3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHRlc3RfdGFibGUsIGFjY29yZGluZ190bz0iZGVzZXEiLCBwPTAuMDUsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpoZWFkKHRlc3Rfc2lnJGRlc2VxJHVwc1tbMV1dKQp0ZXN0X21hIDwtIGV4dHJhY3RfZGVfcGxvdHModGVzdF9kZSwgcD0wLjEpJG1hJHBsb3QKdGVzdF9tYQpwbG90X2hpc3RvZ3JhbSh0ZXN0X3RhYmxlW1siZGF0YSJdXVtbInNoX3ZzX2NociJdXVssIGMoImRlc2VxX3AiKV0pCgpxdWVyeSA8LSB0ZXN0X3RhYmxlJGRhdGFbWzFdXVssICJkZXNlcV9wIl0KYGBgCgojIyBOby1iYXRjaCBkYXRhCgpJbiB0aGUgZm9sbG93aW5nIGJsb2NrLCBJIHdpbGwgdGFrZSB0aGUgY29tcGFyaXNvbnMgcGVyZm9ybWVkIHdpdGhvdXQgYW55IGJhdGNoCmluIHRoZSBtb2RlbC9hZGp1c3RtZW50IGFuZCB1c2UgdGhlbSB0byBzZWFyY2ggZm9yIHNoYXJlZC91bmlxdWUgZ2VuZXMgYW1vbmcgdGhlCnNlbGYtaGVhbGluZyB2cy4gdW5pbmZlY3RlZCBhbmQgdGhlIGNocm9uaWMgdnMuIHVuaW5mZWN0ZWQuCgojIyMgUmV2aWV3IG5vYmF0Y2ggcGNhCgpgYGB7ciByZXZpZXdfbm9iYXRjaH0KaHNfcGFpcndpc2Vfbm9iYXRjaF9wY2EgPC0gc20ocGxvdF9wY2EoaHNfaW5mX2ZpbHQsIGNvbnZlcnQ9ImNwbSIsIHRyYW5zZm9ybT0ibG9nMiIpKQpoc19wYWlyd2lzZV9ub2JhdGNoX3BjYSRwbG90CmBgYAoKYGBge3IgdGVzdF9jaHJfc2gwMSwgZmlnLnNob3c9ImhpZGUifQpoc19wYWlyd2lzZV9ub2JhdGNoIDwtIHNtKGFsbF9wYWlyd2lzZShoc191bmluZl9maWx0LCBtb2RlbF9iYXRjaD1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9fZWJzZXE9RkFMU0UpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3Rfbm9iYXRjaF9jb250ci12e3Zlcn0ueGxzeCIpCmhzX2NvbWJpbmVkX25vYmF0Y2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgaHNfcGFpcndpc2Vfbm9iYXRjaCwKICBleGNlbD1leGNlbF9maWxlLAogIGtlZXBlcnM9a2VlcGVyc19pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3Rfbm9iYXRjaF9zaWctdnt2ZXJ9Lnhsc3giKQpoc19zaWdfbm9iYXRjaCA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIGhzX2NvbWJpbmVkX25vYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSkpCmhzX3NpZ19ub2JhdGNoJGRlc2VxJGNvdW50cwpgYGAKCmBgYHtyIHBsb3RfdGVzdF9jaHJfc2gwMX0KbGltbWFfZGVzZXFfb3JkZXIgPC0gcmFua19vcmRlcl9zY2F0dGVyKAogIGhzX3BhaXJ3aXNlX25vYmF0Y2gsCiAgZmlyc3RfdHlwZT0ibGltbWEiLCBzZWNvbmRfdHlwZT0iZGVzZXEiLAogIGZpcnN0X3RhYmxlPTEsIHNlY29uZF90YWJsZT0xKQpsaW1tYV9kZXNlcV9vcmRlciRwbG90CnVwX2xzdCA8LSBsaXN0KAogICJzaF91cCIgPSByb3duYW1lcyhoc19zaWdfbm9iYXRjaFtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX25vYmF0Y2hbWyJkZXNlcSJdXVtbInVwcyJdXVtbImNoX25pbCJdXSkpCm5vYmF0Y2hfdXBfdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9dXBfbHN0KQpWZW5uZXJhYmxlOjpwbG90KG5vYmF0Y2hfdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQoKIyMgTWFyaWEtQWRlbGFpZGEgYW5kIE5hamliIGFza2VkIGFib3V0IGNvbXBhcmluZyB0aGUgZm9sbG93aW5nIHBhaXIgb2YgZGF0YSBhZ2FpbnN0CiMjIFRoZSBpbnRlcnNlY3Rpb24gb2YgYSBidW5jaCBvZiBzdHVmZiBsYXRlci4uLiAgU28gZG9uJ3QgZm9yZ2V0IHRoaXMhCiMjIFRoaXMgZ2l2ZXMgbWUgdGhlIGdlbmVzIG9ubHkgdXAgaW4gc2VsZiB2cy4gbmlsCm5vYmF0Y2hfdXBfc2hfc29sbyA8LSBub2JhdGNoX3VwX3Zlbm5ASW50ZXJzZWN0aW9uU2V0c1tbIjEwIl1dCiMjIGFuZCBjaCB2cyBuaWwKbm9iYXRjaF91cF9jaF9zb2xvIDwtIG5vYmF0Y2hfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzW1siMDEiXV0KCmRvd25fbHN0IDwtIGxpc3QoCiAgInNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX25vYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfbm9iYXRjaFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pKQpub2JhdGNoX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9ZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3Qobm9iYXRjaF9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKYGBgCgojIFBlcmZvcm0gdGhlICdxdWFsaXRhdGl2ZScgYW5hbHlzaXMgb2Ygc2ggYW5kIGNoIHZzIHVuaW5mZWN0ZWQKCkluIHRoZSBmb2xsb3dpbmcgYmxvY2tzLCBhIHNlcmllcyBvZiBxdWVyaWVzIG9mIHRoZSBzZWxmLWhlYWxpbmcgYW5kIGNocm9uaWMKc2FtcGxlcyB2cy4gdGhlIHVuaW5mZWN0ZWQgd2lsbCBiZSBwZXJmb3JtZWQuICBUaGUgYXNzdW1wdGlvbiBpcyB0aGF0IHRoZSBlZmZlY3QKb2YgaW5mZWN0aW9uLCB3aGljaCBpcyBzbyBtdWNoIHN0cm9uZ2VyIHRoYW4gdGhlIGRpZmZlcmVuY2Ugb2Ygc2VsZi1oZWFsaW5nIGFuZApjaHJvbmljLCB3aWxsIGhpZ2hsaWdodCBzb21lIGRpZmZlcmVuY2VzIHdoZW4gcGVyZm9ybWVkIHVzaW5nIHRoZSBjaHJvbmljIGFuZApzZWxmLWhlYWxpbmcgc2FtcGxlcy4KCkluIGFkZGl0aW9uLCB3ZSB3aWxsIGJlIGFwcGx5aW5nIGFsbCBvZiB0aGVzZSB0YXNrcyB3aXRoIGFuZCB3aXRob3V0CnN0cmFpbiAyNTA0LiAgSSBhbSBndWVzc2luZyB0aGF0IHRoZSBhYm92ZSByZXN1bHRzIHdpbGwgY2F1c2Ugb25lIHRvIHdhbnQgdG8gc2VlCnRoaXMgd2l0aCB0aGUgcmVtb3ZhbCBvZiBib3RoIHRyb3VibGVzb21lIHN0cmFpbnMgKDI1MDQgYW5kIDIyNzIpLiAgQnV0IGZvciB0aGUKbW9tZW50IEkgYW0gdGhpbmsgSSB3aWxsIGxpbWl0IG15IHNlbGYgdG8gb25seSB0aGUgMjUwNCByZW1vdmFsIGluIGFuIGF0dGVtcHQgdG8KYXZvaWQgY29uZnVzaW9uLgoKIyMgQWRkIHBhdGllbnQgdG8gdGhlIG1vZGVsCgpSZXBlYXQgdGhlIHByZXZpb3VzIHNldCBvZiBhbmFseXNlcyB3aXRoIGQxMDcvMTA4LzExMCBpbiB0aGUgbW9kZWwuCgojIyMgUmV2aWV3IHBjYQoKV2UgaGF2ZSBzZWVuIHZhcmlhbnRzIG9mIHRoZXNlIHBsb3RzIGFib3ZlLCBidXQgaG9wZWZ1bGx5IHRoZXNlIHdpbGwgc2VydmUgYXMgYQpyZW1pbmRlciBvZiB0aGUgc2hhZGVzIG9mIGRpZmZlcmVuY2Ugd2UgYXJlIGhvcGluZyB0byBvYnNlcnZlLgoKIyMjIyBXaXRoIDI1MDQKCmBgYHtyIHJldmlld19iYXRjaH0KaHNfcGFpcndpc2VfYmF0Y2hfcGNhIDwtIHNtKHBsb3RfcGNhKGhzX2luZl9maWx0LCBiYXRjaD0ibGltbWEiLCBjb252ZXJ0PSJjcG0iLCB0cmFuc2Zvcm09ImxvZzIiKSkKaHNfcGFpcndpc2VfYmF0Y2hfcGNhJHBsb3QKCmhzX3BhaXJ3aXNlX2JhdGNoX3VuaW5mX3BjYSA8LSBzbShwbG90X3BjYShoc191bmluZl9maWx0LCBiYXRjaD0ibGltbWEiLCBjb252ZXJ0PSJjcG0iLCB0cmFuc2Zvcm09ImxvZzIiKSkKaHNfcGFpcndpc2VfYmF0Y2hfdW5pbmZfcGNhJHBsb3QKYGBgCgojIyMjIFdpdGhvdXQgMjUwNAoKYGBge3IgcmV2aWV3X2JhdGNoXzI1MDR9CnJlbW92ZV8yNTA0X3BhaXJ3aXNlX2JhdGNoX3VuaW5mX3BjYSA8LSBzbShwbG90X3BjYShyZW1vdmVfMjUwNF91bmluZl9maWx0LCBiYXRjaD0ibGltbWEiLCBjb252ZXJ0PSJjcG0iLCB0cmFuc2Zvcm09ImxvZzIiKSkKcmVtb3ZlXzI1MDRfcGFpcndpc2VfYmF0Y2hfdW5pbmZfcGNhJHBsb3QKYGBgCgojIyMgSW52b2tlIGRlIGFuYWx5c2VzCgpOb3cgcGVyZm9ybSB0aGUgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXMsIGZpcnN0IHdpdGggYW5kIHRoZW4gd2l0aG91dAoyNTA0CgojIyMjIFdpdGggMjUwNAoKYGBge3IgdGVzdF9jaHJfc2gwMiwgZmlnLnNob3c9ImhpZGUifQpoc19wYWlyd2lzZV9iYXRjaCA8LSBzbShhbGxfcGFpcndpc2UoaHNfdW5pbmZfZmlsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2JhdGNoPVRSVUUsIGRvX2Vic2VxPUZBTFNFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X3BhdGJhdGNoX2NvbnRyLXZ7dmVyfS54bHN4IikKaHNfY29tYmluZWRfYmF0Y2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgaHNfcGFpcndpc2VfYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSwKICBrZWVwZXJzPWtlZXBlcnNfdW5pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfcGF0YmF0Y2hfc2lnLXZ7dmVyfS54bHN4IikKaHNfc2lnX2JhdGNoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgaHNfY29tYmluZWRfYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSkpCmhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1siY291bnRzIl1dCmBgYAoKIyMjIyBXaXRob3V0IDI1MDQKCmBgYHtyIHRlc3RfY2hyX3NoMDJfMjUwNCwgZmlnLnNob3c9ImhpZGUifQpyZW1vdmVfMjUwNF9wYWlyd2lzZV9iYXRjaCA8LSBzbShhbGxfcGFpcndpc2UocmVtb3ZlXzI1MDRfdW5pbmZfZmlsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2JhdGNoPVRSVUUsIGRvX2Vic2VxPUZBTFNFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1fcmVtb3ZlXzI1MDRfaW5mZWN0X3BhdGJhdGNoX2NvbnRyLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzI1MDRfY29tYmluZWRfYmF0Y2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgcmVtb3ZlXzI1MDRfcGFpcndpc2VfYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSwKICBrZWVwZXJzPWtlZXBlcnNfdW5pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9yZW1vdmVfMjUwNF9pbmZlY3RfcGF0YmF0Y2hfc2lnLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzI1MDRfc2lnX2JhdGNoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgcmVtb3ZlXzI1MDRfY29tYmluZWRfYmF0Y2gsCiAgZXhjZWw9ZXhjZWxfZmlsZSkpCnJlbW92ZV8yNTA0X3NpZ19iYXRjaFtbImRlc2VxIl1dW1siY291bnRzIl1dCmBgYAoKIyMjIFBlcmZvcm0gcXVhbGl0YXRpdmUgYW5hbHlzaXMKCkluIHRoZSBmb2xsb3dpbmcgYmxvY2tzIHdlIHdpbGwgcGVyZm9ybSB0aGUgaW50ZXJzZWN0aW9ucyBvZiAoc2VsZi1oZWFsaW5nCnZzLiB1bmluZmVjdGVkKSBhZ2FpbnN0IChjaHJvbmljIHZzLiB1bmluZmVjdGVkKS4KCiMjIyMgV2l0aCAyNTA0CgpgYGB7ciBwbG90X3Rlc3RfY2hhcl9zaDAyfQp1cF9sc3QgPC0gbGlzdCgKICAic2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX2JhdGNoW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF91cCIgPSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbInVwcyJdXVtbImNoX25pbCJdXSkpCmJhdGNoX3VwX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXVwX2xzdCkKc3VtbWFyeShiYXRjaF91cF92ZW5uQEludGVyc2VjdGlvblNldHMpClZlbm5lcmFibGU6OnBsb3QoYmF0Y2hfdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkb3duX2xzdCA8LSBsaXN0KAogICJzaF9kb3duIiA9IHJvd25hbWVzKGhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF9kb3duIiA9IHJvd25hbWVzKGhzX3NpZ19iYXRjaFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pKQpiYXRjaF9kb3duX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWRvd25fbHN0KQpWZW5uZXJhYmxlOjpwbG90KGJhdGNoX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpzdW1tYXJ5KGJhdGNoX2Rvd25fdmVubkBJbnRlcnNlY3Rpb25TZXRzKQoKc2ltaWxhciA8LSBjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfbm9iYXRjaCwgaHNfY29tYmluZWRfYmF0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcl9tZXRob2Q9InNwZWFybWFuIikKc2ltaWxhcltbInJlc3VsdCJdXVtbImRlc2VxIl1dCmBgYAoKIyMjIyBXaXRob3V0IDI1MDQKCmBgYHtyIHBsb3RfdGVzdF9jaGFyX3NoMDJfMjUwNH0KdXBfbHN0IDwtIGxpc3QoCiAgInNoX3VwIiA9IHJvd25hbWVzKHJlbW92ZV8yNTA0X3NpZ19iYXRjaFtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfdXAiID0gcm93bmFtZXMocmVtb3ZlXzI1MDRfc2lnX2JhdGNoW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJjaF9uaWwiXV0pKQpiYXRjaF91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz11cF9sc3QpCnN1bW1hcnkoYmF0Y2hfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzKQpWZW5uZXJhYmxlOjpwbG90KGJhdGNoX3VwX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKZG93bl9sc3QgPC0gbGlzdCgKICAic2hfZG93biIgPSByb3duYW1lcyhyZW1vdmVfMjUwNF9zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhyZW1vdmVfMjUwNF9zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siY2hfbmlsIl1dKSkKYmF0Y2hfZG93bl92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1kb3duX2xzdCkKVmVubmVyYWJsZTo6cGxvdChiYXRjaF9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKc3VtbWFyeShiYXRjaF9kb3duX3Zlbm5ASW50ZXJzZWN0aW9uU2V0cykKYGBgCgojIyBXcml0ZSBhbiBleGNlbCB3b3JrYm9vayB1c2luZyB0aGUgYmF0Y2ggZGF0YS4KClRoZSBmb2xsb3dpbmcgYmxvY2sgd3JpdGVzIG91dCB0aGUgdW5pcXVlL3NoYXJlZCBnZW5lcyBvYnNlcnZlZCBhbW9uZyB0aGUKY29udHJhc3RzIHdoaWNoIGluY2x1ZGVkIGRvbm9yIGluIHRoZSBtb2RlbC4KCmBgYHtyIGNoc2hfdmVubjAyfQprZXB0X2NvbHVtbnMgPC0gYygiZW5zZW1ibHRyYW5zY3JpcHRpZCIsICJlbnNlbWJsZ2VuZWlkIiwgImRlc2NyaXB0aW9uIiwKICAgICAgICAgICAgICAgICAgImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKQpzdGFydF9kYXRhIDwtIGhzX3NpZ19iYXRjaFtbImRlc2VxIl1dCnNoX3VwX3NvbG9fZ2VuZXMgPC0gYmF0Y2hfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzW1siMTAiXV0KY2hfdXBfc29sb19nZW5lcyA8LSBiYXRjaF91cF92ZW5uQEludGVyc2VjdGlvblNldHNbWyIwMSJdXQpzaGNoX3VwX3NoYXJlZF9nZW5lcyA8LSBiYXRjaF91cF92ZW5uQEludGVyc2VjdGlvblNldHNbWyIxMSJdXQpzaF9kb3duX3NvbG9fZ2VuZXMgPC0gYmF0Y2hfZG93bl92ZW5uQEludGVyc2VjdGlvblNldHNbWyIxMCJdXQpjaF9kb3duX3NvbG9fZ2VuZXMgPC0gYmF0Y2hfZG93bl92ZW5uQEludGVyc2VjdGlvblNldHNbWyIwMSJdXQpzaGNoX2Rvd25fc2hhcmVkX2dlbmVzIDwtIGJhdGNoX2Rvd25fdmVubkBJbnRlcnNlY3Rpb25TZXRzW1siMTEiXV0KCnhsc19yZXN1bHQgPC0gd3JpdGVfeGxzKAogIGRhdGE9c3RhcnRfZGF0YVtbInVwcyJdXVtbInNoX25pbCJdXVtzaF91cF9zb2xvX2dlbmVzLCBrZXB0X2NvbHVtbnNdLAogIHNoZWV0PSJzaF91cF9zb2xvIikKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoCiAgZGF0YT1zdGFydF9kYXRhW1sidXBzIl1dW1siY2hfbmlsIl1dW2NoX3VwX3NvbG9fZ2VuZXMsIGtlcHRfY29sdW1uc10sCiAgc2hlZXQ9ImNoX3VwX3NvbG8iLCB3Yj14bHNfcmVzdWx0W1sid29ya2Jvb2siXV0pCnhsc19yZXN1bHQgPC0gd3JpdGVfeGxzKAogIGRhdGE9c3RhcnRfZGF0YVtbInVwcyJdXVtbImNoX25pbCJdXVtzaGNoX3VwX3NoYXJlZF9nZW5lcywga2VwdF9jb2x1bW5zXSwKICBzaGVldD0ic2hjaF91cF9zaGFyZWQiLCB3Yj14bHNfcmVzdWx0W1sid29ya2Jvb2siXV0pCnhsc19yZXN1bHQgPC0gd3JpdGVfeGxzKAogIGRhdGE9c3RhcnRfZGF0YVtbImRvd25zIl1dW1sic2hfbmlsIl1dW3NoX2Rvd25fc29sb19nZW5lcywga2VwdF9jb2x1bW5zXSwKICBzaGVldD0ic2hfZG93bl9zb2xvIikKeGxzX3Jlc3VsdCA8LSB3cml0ZV94bHMoCiAgZGF0YT1zdGFydF9kYXRhW1siZG93bnMiXV1bWyJjaF9uaWwiXV1bY2hfZG93bl9zb2xvX2dlbmVzLCBrZXB0X2NvbHVtbnNdLAogIHNoZWV0PSJjaF9kb3duX3NvbG8iLCB3Yj14bHNfcmVzdWx0W1sid29ya2Jvb2siXV0pCnhsc19yZXN1bHQgPC0gd3JpdGVfeGxzKAogIGRhdGE9c3RhcnRfZGF0YVtbImRvd25zIl1dW1siY2hfbmlsIl1dW3NoY2hfZG93bl9zaGFyZWRfZ2VuZXMsIGtlcHRfY29sdW1uc10sCiAgc2hlZXQ9InNoY2hfZG93bl9zaGFyZWQiLCB3Yj14bHNfcmVzdWx0W1sid29ya2Jvb2siXV0sCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9maWd1cmVfNWFfc3R1ZmYtdiIsIHZlciwgIi54bHN4IikpCmBgYAoKIyMgQWRkIHNzdmEgaW50byB0aGUgbWl4CgpSZXBlYXQsIHRoaXMgdGltZSBhdHRtZXB0aW5nIHRvIHRhbXAgZG93biB0aGUgdmFyaWFuY2UgYnkgcGVyc29uLgoKIyMjIFJldmlldyBzdmEKCiMjIyMgRmlyc3Qgd2l0aCAyNTA0CgpgYGB7ciByZXZpZXdfc3N2YX0KaHNfcGFpcndpc2Vfc3ZhX3BjYSA8LSBzbShwbG90X3BjYShoc19pbmZfZmlsdCwgYmF0Y2g9InN2YXNlcSIsIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikpCmhzX3BhaXJ3aXNlX3N2YV9wY2EkcGxvdApgYGAKCiMjIyMgQWdhaW4gd2l0aG91dAoKYGBge3IgcmV2aWV3X3NzdmFfMjUwNH0KcmVtb3ZlXzI1MDRfcGFpcndpc2Vfc3ZhX3BjYSA8LSBzbShwbG90X3BjYShyZW1vdmVfMjUwNF9pbmZfZmlsdCwgYmF0Y2g9InN2YXNlcSIsIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikpCnJlbW92ZV8yNTA0X3BhaXJ3aXNlX3N2YV9wY2EkcGxvdApgYGAKCiMjIyBQZXJmb3JtIHRoaXMgcm91bmQgb2YgREUKCiMjIyMgRmlyc3Qgd2l0aCBzdHJhaW4gMjUwNAoKYGBge3IgdGVzdF9jaHJfc2gwNSwgZmlnLnNob3c9ImhpZGUifQpoc19wYWlyd2lzZV9zdmEgPC0gc20oYWxsX3BhaXJ3aXNlKGhzX3VuaW5mX2ZpbHQsIG1vZGVsX2JhdGNoPSJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX2Vic2VxPUZBTFNFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1faHNfaW5mZWN0X3N2YV9jb250ci12e3Zlcn0ueGxzeCIpCmhzX2NvbWJpbmVkX3N2YSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcygKICBoc19wYWlyd2lzZV9zdmEsCiAgZXhjZWw9ZXhjZWxfZmlsZSwKICBrZWVwZXJzPWtlZXBlcnNfdW5pbmYpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3Rfc3ZhX3NpZy12e3Zlcn0ueGxzeCIpCmhzX3NpZ19zdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBoc19jb21iaW5lZF9zdmEsCiAgZXhjZWw9ZXhjZWxfZmlsZSkpCmhzX3NpZ19zdmEkZGVzZXEkY291bnRzCmBgYAoKIyMjIyBBbmQgYWdhaW4gd2l0aG91dAoKYGBge3IgdGVzdF9jaHJfc2gwNV8yNTA0LCBmaWcuc2hvdz0iaGlkZSJ9CnJlbW92ZV8yNTA0X3BhaXJ3aXNlX3N2YSA8LSBzbShhbGxfcGFpcndpc2UocmVtb3ZlXzI1MDRfdW5pbmZfZmlsdCwgbW9kZWxfYmF0Y2g9InN2YXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9fZWJzZXE9RkFMU0UpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9yZW1vdmVfMjUwNF9pbmZlY3Rfc3ZhX2NvbnRyLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzI1MDRfY29tYmluZWRfc3ZhIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKAogIHJlbW92ZV8yNTA0X3BhaXJ3aXNlX3N2YSwKICBleGNlbD1leGNlbF9maWxlLAogIGtlZXBlcnM9a2VlcGVyc191bmluZikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X3JlbW92ZV8yNTA0X2luZmVjdF9zdmFfc2lnLXZ7dmVyfS54bHN4IikKcmVtb3ZlXzI1MDRfc2lnX3N2YSA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHJlbW92ZV8yNTA0X2NvbWJpbmVkX3N2YSwKICBleGNlbD1leGNlbF9maWxlKSkKcmVtb3ZlXzI1MDRfc2lnX3N2YSRkZXNlcSRjb3VudHMKYGBgCgojIyMgTm93IHBsb3QgdGhlIGludGVyc2VjdGlvbnMKCiMjIyMgT25jZSBhZ2FpbiwgYWxsIHN0cmFpbnMgZmlyc3QKCmBgYHtyIHBsb3RfdGVzdF9jaHJfc2gwNTAxfQp1cF9sc3QgPC0gbGlzdCgKICAic2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX3N2YVtbImRlc2VxIl1dW1sidXBzIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfdXAiID0gcm93bmFtZXMoaHNfc2lnX3N2YVtbImRlc2VxIl1dW1sidXBzIl1dW1siY2hfbmlsIl1dKSkKc3ZhX3VwX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXVwX2xzdCkKc3VtbWFyeShzdmFfdXBfdmVubkBJbnRlcnNlY3Rpb25TZXRzKQpWZW5uZXJhYmxlOjpwbG90KHN2YV91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRvd25fbHN0IDwtIGxpc3QoCiAgInNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX3N2YVtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF9kb3duIiA9IHJvd25hbWVzKGhzX3NpZ19zdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siY2hfbmlsIl1dKSkKc3ZhX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9ZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3Qoc3ZhX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpzdW1tYXJ5KHN2YV9kb3duX3Zlbm5ASW50ZXJzZWN0aW9uU2V0cykKCnNpbWlsYXIgPC0gc20oY29tcGFyZV9kZV9yZXN1bHRzKGhzX2NvbWJpbmVkX25vYmF0Y2gsIGhzX2NvbWJpbmVkX3N2YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfYmF0Y2gsIGhzX2NvbWJpbmVkX3N2YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKYGBgCgojIyMjIE9uY2UgYWdhaW4sIG5vIDI1MDQKCmBgYHtyIHBsb3RfdGVzdF9jaHJfc2gwNX0KdXBfbHN0IDwtIGxpc3QoCiAgInNoX3VwIiA9IHJvd25hbWVzKHJlbW92ZV8yNTA0X3NpZ19zdmFbWyJkZXNlcSJdXVtbInVwcyJdXVtbInNoX25pbCJdXSksCiAgImNoX3VwIiA9IHJvd25hbWVzKHJlbW92ZV8yNTA0X3NpZ19zdmFbWyJkZXNlcSJdXVtbInVwcyJdXVtbImNoX25pbCJdXSkpCnN2YV91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz11cF9sc3QpCnN1bW1hcnkoc3ZhX3VwX3Zlbm5ASW50ZXJzZWN0aW9uU2V0cykKVmVubmVyYWJsZTo6cGxvdChzdmFfdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkb3duX2xzdCA8LSBsaXN0KAogICJzaF9kb3duIiA9IHJvd25hbWVzKHJlbW92ZV8yNTA0X3NpZ19zdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhyZW1vdmVfMjUwNF9zaWdfc3ZhW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImNoX25pbCJdXSkpCnN2YV9kb3duX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWRvd25fbHN0KQpWZW5uZXJhYmxlOjpwbG90KHN2YV9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKc3VtbWFyeShzdmFfZG93bl92ZW5uQEludGVyc2VjdGlvblNldHMpCmBgYAoKIyMgZnN2YQoKUmVwZWF0IGFnYWluIHVzaW5nIGZzdmEuCgojIyMgUmV2aWV3IGZzdmEKCmBgYHtyIHJldmlld19mc3ZhfQpoc19wYWlyd2lzZV9mc3ZhX3BjYSA8LSBzbShwbG90X3BjYShoc19pbmZfZmlsdCwgYmF0Y2g9ImZzdmEiLCBub3JtPSJxdWFudCIsIHRyYW5zZm9ybT0ibG9nMiIpKQpoc19wYWlyd2lzZV9mc3ZhX3BjYSRwbG90CmBgYAoKYGBge3IgdGVzdF9jaHJfc2gwM19mc3ZhLCBmaWcuc2hvdz0iaGlkZSJ9CmhzX3BhaXJ3aXNlX2ZzdmEgPC0gc20oYWxsX3BhaXJ3aXNlKGhzX3VuaW5mX2ZpbHQsIG1vZGVsX2JhdGNoPSJmc3ZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9fZWJzZXE9RkFMU0UpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfZnN2YV9jb250ci12e3Zlcn0ueGxzeCIpCmhzX2NvbWJpbmVkX2ZzdmEgPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgaHNfcGFpcndpc2VfZnN2YSwKICBleGNlbD1leGNlbF9maWxlLAogIGtlZXBlcnM9a2VlcGVyc191bmluZikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9mc3ZhX3NpZy12e3Zlcn0ueGxzeCIpCmhzX3NpZ19mc3ZhIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgaHNfY29tYmluZWRfZnN2YSwKICBleGNlbD1leGNlbF9maWxlKSkKYGBgCgpgYGB7ciBwbG90X3Rlc3RfY2hyX3NoMDNfZnN2YX0KdXBfbHN0IDwtIGxpc3QoCiAgInNoX3VwIiA9IHJvd25hbWVzKGhzX3NpZ19mc3ZhW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF91cCIgPSByb3duYW1lcyhoc19zaWdfZnN2YVtbImRlc2VxIl1dW1sidXBzIl1dW1siY2hfbmlsIl1dKSkKZnN2YV91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz11cF9sc3QpCnN1bW1hcnkoZnN2YV91cF92ZW5uQEludGVyc2VjdGlvblNldHMpClZlbm5lcmFibGU6OnBsb3QoZnN2YV91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRvd25fbHN0IDwtIGxpc3QoCiAgInNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX2ZzdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfZnN2YVtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pKQpmc3ZhX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9ZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3QoZnN2YV9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKc3VtbWFyeShmc3ZhX2Rvd25fdmVubkBJbnRlcnNlY3Rpb25TZXRzKQoKIyNoc19zaWdfZnN2YSRkZXNlcSRjb3VudHMkY29tbW9uX3NvbG9zX2ZzdmEgPC0gc20oc3Vic2V0X3NpZ25pZmljYW50cyhoc19zaWdfZnN2YSkpCnNpbWlsYXIgPC0gc20oY29tcGFyZV9kZV9yZXN1bHRzKGhzX2NvbWJpbmVkX25vYmF0Y2gsIGhzX2NvbWJpbmVkX2ZzdmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcl9tZXRob2Q9InNwZWFybWFuIikpCnNpbWlsYXIkcmVzdWx0JGRlc2VxCnNpbWlsYXIgPC0gc20oY29tcGFyZV9kZV9yZXN1bHRzKGhzX2NvbWJpbmVkX3NzdmEsIGhzX2NvbWJpbmVkX2ZzdmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcl9tZXRob2Q9InNwZWFybWFuIikpCnNpbWlsYXIkcmVzdWx0JGRlc2VxCmBgYAoKIyMgVHJ5IHdpdGggdGhlIGNvbWJhdCBtb2RpZmllZCBkYXRhCgpSZXBlYXQgb25jZSBhZ2FpbiwgdGhpcyB0aW1lIHVzaW5nIGNvbWJhdCB0byB0cnkgdG8gbGltaXQgdGhlIGNvbnRyaWJ1dGlvbiBvZgp0aGUgc3RyYWluIHRvIHRoZSBkYXRhLiAgSSBkbyBub3QgdGhpbmsgd2Ugd2lsbCBldmVyIHVzZSB0aGlzIHNldCBvZiBjb250cmFzdHMsCnNvIEkgd2lsbCBkZWFjdGl2YXRlIGl0IGJ1dCBsZWF2ZSBpdCBoZXJlIGlmIGl0IGlzIHJlcXVpcmVkIGxhdGVyLgoKYGBge3IgdGVzdF9jaHJfc2gwNCwgZmlnLnNob3c9ImhpZGUifQpvbGRfY29uZGl0aW9uIDwtIGhzX3VuaW5mJGRlc2lnbiRjb25kaXRpb24KbmFtZXMob2xkX2NvbmRpdGlvbikgPC0gaHNfdW5pbmYkZGVzaWduJHNhbXBsZWlkCm5ld19jb25kaXRpb24gPC0gcGFzdGUwKGhzX3VuaW5mJGRlc2lnbiRzdGF0ZSwgJ18nLCBoc191bmluZiRkZXNpZ24kZG9ub3IpCmhzX3VuaW5mX3JlY29uZCA8LSBzZXRfZXhwdF9mYWN0b3JzKGhzX3VuaW5mX2ZpbHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJwYXRob2dlbnN0cmFpbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbj1uZXdfY29uZGl0aW9uKQpjb21iYXRfaW5wdXQgPC0gbm9ybWFsaXplX2V4cHQoaHNfdW5pbmZfcmVjb25kLCBiYXRjaD0iY29tYmF0X3NjYWxlIiwgZmlsdGVyPVRSVUUpCmNvbWJhdF9pbnB1dCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKGNvbWJhdF9pbnB1dCwgZmFjdD1vbGRfY29uZGl0aW9uKQpjb21iYXRfaW5wdXQgPC0gc2V0X2V4cHRfY29sb3JzKGNvbWJhdF9pbnB1dCwgY29sb3JzPWMoImdyZWVuIiwiYmx1ZSIsInJlZCIpKQpgYGAKCiMjIyBSZXZpZXcgY29tYmF0CgpgYGB7ciByZXZpZXdfY29tYmF0fQpoc19wYWlyd2lzZV9jb21iYXRfcGNhIDwtIHBsb3RfcGNhKGNvbWJhdF9pbnB1dCkKaHNfcGFpcndpc2VfY29tYmF0X3BjYSRwbG90CmBgYAoKYGBge3IgcGVyZm9ybV9jb21iYXR9CmhzX3BhaXJ3aXNlX2NvbWJhdHBhdGggPC0gc20oYWxsX3BhaXJ3aXNlKGNvbWJhdF9pbnB1dCwgbW9kZWxfYmF0Y2g9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlPVRSVUUpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9oc19pbmZlY3RfY29tYmF0cGF0aF9jb250ci12e3Zlcn0ueGxzeCIpCmhzX2NvbWJpbmVkX2NvbWJhdHBhdGggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgaHNfcGFpcndpc2VfY29tYmF0cGF0aCwKICBleGNlbD1leGNlbF9maWxlLAogIGtlZXBlcnM9a2VlcGVyc191bmluZikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2hzX2luZmVjdF9jb21iYXRwYXRoX3NpZy12e3Zlcn0ueGxzeCIpCmhzX3NpZ19jb21iYXRwYXRoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgaHNfY29tYmluZWRfY29tYmF0cGF0aCwKICBleGNlbD1leGNlbF9maWxlKSkKaHNfc2lnX2NvbWJhdHBhdGgkZGVzZXEkY291bnRzCmBgYAoKYGBge3IgcGxvdF90ZXN0X2Nocl9zaDA0X2NvbWJhdH0KdXBfbHN0IDwtIGxpc3QoCiAgInNoX3VwIiA9IHJvd25hbWVzKGhzX3NpZ19jb21iYXRwYXRoW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJzaF9uaWwiXV0pLAogICJjaF91cCIgPSByb3duYW1lcyhoc19zaWdfY29tYmF0cGF0aFtbImRlc2VxIl1dW1sidXBzIl1dW1siY2hfbmlsIl1dKSkKY29tYmF0cGF0aF91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz11cF9sc3QpCnN1bW1hcnkoY29tYmF0cGF0aF91cF92ZW5uQEludGVyc2VjdGlvblNldHMpClZlbm5lcmFibGU6OnBsb3QoY29tYmF0cGF0aF91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRvd25fbHN0IDwtIGxpc3QoCiAgInNoX2Rvd24iID0gcm93bmFtZXMoaHNfc2lnX2NvbWJhdHBhdGhbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sic2hfbmlsIl1dKSwKICAiY2hfZG93biIgPSByb3duYW1lcyhoc19zaWdfY29tYmF0cGF0aFtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJjaF9uaWwiXV0pKQpjb21iYXRwYXRoX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9ZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3QoY29tYmF0cGF0aF9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKc3VtbWFyeShjb21iYXRwYXRoX2Rvd25fdmVubkBJbnRlcnNlY3Rpb25TZXRzKQoKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfbm9iYXRjaCwgaHNfY29tYmluZWRfY29tYmF0cGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKc2ltaWxhciA8LSBzbShjb21wYXJlX2RlX3Jlc3VsdHMoaHNfY29tYmluZWRfZnN2YSwgaHNfY29tYmluZWRfY29tYmF0cGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yX21ldGhvZD0ic3BlYXJtYW4iKSkKc2ltaWxhciRyZXN1bHQkZGVzZXEKIyMgT1VDSCEKYGBgCgojIyBDb21wYXJlIERFIHJlc3VsdHMKCkZvciBlYWNoIG9mIHRoZSBmb2xsb3dpbmcsIHBlcmZvcm0gYSBzaW1wbGUgREUgYW5kIHNlZSB3aGF0IGhhcHBlbnM6CgoxLiAgbm8gdW5pbmZlY3RlZCBzdHJhaW4gYXMgYmF0Y2gsIHRyeSB0byBjb21wYXJlIGVhY2ggb2YgdGhlIDMgcGF0aWVudHMgY2hyb25pYy9zZWxmCjIuICBubyB1bmluZmVjdGVkIHN0cmFpbiBhcyBiYXRjaCwgdHJ5IHRvIGNvbXBhcmUgY2hyb25pYy9zZWxmIGZvciBhbGwKMy4gIFJlcGVhdCAjMSBhYm92ZSB3aXRoIHVuaW5mZWN0ZWQKNC4gIFJlcGVhdCAjMiB3aXRoIHVuaW5mZWN0ZWQKCiMjIyBERTogaW5jbHVkZSB1bmluZmVjdGVkLCB1c2Ugc3RyYWluIGFzIGJhdGNoCgpUaGUgZGF0YSB1c2VkIGluIHRoZSBmb2xsb3dpbmcgaXMgdGhlIHF1YW50aWxlKGNwbShmaWx0ZXIoKSkpIHdoZXJlIHRoZQpjb25kaXRpb24gd2FzIHNldCB0byBhIGNvbmNhdGVuYXRpb24gb2YgcGF0aWVudCBhbmQgaGVhbGluZyBzdGF0ZSwgY29tYmF0IHdhcwphbHNvIHBlcmZvcm1lZCwgc28gd2Ugbm8gbG9uZ2VyIHdhbnQgYmF0Y2ggaW4gdGhlIGV4cGVyaW1lbnRhbCBtb2RlbCBhbmQgYWxzbyB3ZQpuZWVkIHRvIHBhc3MgJ2ZvcmNlPVRSVUUnIGJlY2F1c2UgZGVzZXEvZWRnZXIgd2lsbCBuZWVkIHRvIGJlIGNvZXJjZWQgaW50bwphY2NlcHRpbmcgdGhlc2UgbW9kaWZpZWQgZGF0YS4KCiMjIyMgQWxsIHN0cmFpbnMKCmBgYHtyIGRlX2NvbXBhcmlzb25zMDEsIGZpZy5zaG93PSJoaWRlIn0KaHNfaW5mJGNvbmRpdGlvbgojIyBTdGFydCBieSBsZWF2aW5nIHRoZSBkYXRhIHJlbGF0aXZlbHkgYWxvbmUsIGVzcGVjaWFsbHkgbm90aW5nIHRoYXQgd2UgZG8gbm90CiMjIGhhdmUgYSB1c2FibGUgYmF0Y2ggYnkgZGVmYXVsdC4KaHNfdW5pbmZfZmlsdHYyIDwtIGhzX3VuaW5mX2ZpbHQKZG9ub3Jfc3RhdGUgPC0gcGFzdGUwKGhzX3VuaW5mX2ZpbHR2MiRkZXNpZ24kc3RhdGUsICJfIiwgaHNfdW5pbmZfZmlsdHYyJGRlc2lnbiRkb25vcikKaHNfdW5pbmZfZmlsdHYyIDwtIHNldF9leHB0X2ZhY3RvcnMoaHNfdW5pbmZfZmlsdHYyLCBjb25kaXRpb249ZG9ub3Jfc3RhdGUpCgp1bmluZl9wYXRpZW50X2tlZXBlcnMgPC0gbGlzdCgKICAgICJkMTA3X2NodW4iID0gYygiY2hyb25pY19kMTA3IiwgInVuaW5mZWN0ZWRfZDEwNyIpLAogICAgImQxMDdfc2h1biIgPSBjKCJzZWxmX2hlYWxfZDEwNyIsICJ1bmluZmVjdGVkX2QxMDciKSwKICAgICJkMTA3X2Noc2giID0gYygiY2hyb25pY19kMTA3IiwgInNlbGZfaGVhbF9kMTA3IiksCiAgICAiZDEwOF9jaHVuIiA9IGMoImNocm9uaWNfZDEwOCIsICJ1bmluZmVjdGVkX2QxMDgiKSwKICAgICJkMTA4X3NodW4iID0gYygic2VsZl9oZWFsX2QxMDgiLCAidW5pbmZlY3RlZF9kMTA4IiksCiAgICAiZDEwOF9jaHNoIiA9IGMoImNocm9uaWNfZDEwOCIsICJzZWxmX2hlYWxfZDEwOCIpLAogICAgImQxMTBfY2h1biIgPSBjKCJjaHJvbmljX2QxMTAiLCAidW5pbmZlY3RlZF9kMTEwIiksCiAgICAiZDExMF9zaHVuIiA9IGMoInNlbGZfaGVhbF9kMTEwIiwgInVuaW5mZWN0ZWRfZDExMCIpLAogICAgImQxMTBfY2hzaCIgPSBjKCJjaHJvbmljX2QxMTAiLCAic2VsZl9oZWFsX2QxMTAiKSkKCmhzX3VuaW5mX2ZpbHR2Ml9wYWlyd2lzZSA8LSBzbShhbGxfcGFpcndpc2UoaHNfdW5pbmZfZmlsdHYyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2JhdGNoPUZBTFNFLCBkb19lYnNlcT1GQUxTRSkpCmhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZCA8LSBzbShjb21iaW5lX2RlX3RhYmxlcygKICBoc191bmluZl9maWx0djJfcGFpcndpc2UsCiAga2VlcGVycz11bmluZl9wYXRpZW50X2tlZXBlcnMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9oc19pbmZlY3RfcGF0aWVudF9ub2JhdGNoLXYiLCB2ZXIsICIueGxzeCIpKSkKaHNfdW5pbmZfZmlsdHYyX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZCwgYWNjb3JkaW5nX3RvPSJkZXNlcSIsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC8iLCBydW5kYXRlLCAiaHNfaW5mZWN0X3BhdGllbnRfbm9iYXRjaF9zaWctdiIsIHZlciwgIi54bHN4IikpKQpgYGAKCiMjIyMgTm8gMjUwNAoKYGBge3IgZGVfY29tcGFyaXNvbnMsIGZpZy5zaG93PSJoaWRlIn0KcmVtb3ZlXzI1MDRfaW5mJGNvbmRpdGlvbgojIyBTdGFydCBieSBsZWF2aW5nIHRoZSBkYXRhIHJlbGF0aXZlbHkgYWxvbmUsIGVzcGVjaWFsbHkgbm90aW5nIHRoYXQgd2UgZG8gbm90CiMjIGhhdmUgYSB1c2FibGUgYmF0Y2ggYnkgZGVmYXVsdC4KcmVtb3ZlXzI1MDRfdW5pbmZfZmlsdHYyIDwtIHJlbW92ZV8yNTA0X3VuaW5mX2ZpbHQKZG9ub3Jfc3RhdGUgPC0gcGFzdGUwKHJlbW92ZV8yNTA0X3VuaW5mX2ZpbHR2MiRkZXNpZ24kc3RhdGUsICJfIiwgcmVtb3ZlXzI1MDRfdW5pbmZfZmlsdHYyJGRlc2lnbiRkb25vcikKcmVtb3ZlXzI1MDRfdW5pbmZfZmlsdHYyIDwtIHNldF9leHB0X2ZhY3RvcnMocmVtb3ZlXzI1MDRfdW5pbmZfZmlsdHYyLCBjb25kaXRpb249ZG9ub3Jfc3RhdGUpCgpyZW1vdmVfMjUwNF91bmluZl9maWx0djJfcGFpcndpc2UgPC0gc20oYWxsX3BhaXJ3aXNlKHJlbW92ZV8yNTA0X3VuaW5mX2ZpbHR2MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbF9iYXRjaD1GQUxTRSwgZG9fZWJzZXE9RkFMU0UpKQpyZW1vdmVfMjUwNF91bmluZl9maWx0djJfY29tYmluZWQgPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgcmVtb3ZlXzI1MDRfdW5pbmZfZmlsdHYyX3BhaXJ3aXNlLAogIGtlZXBlcnM9dW5pbmZfcGF0aWVudF9rZWVwZXJzLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvcmVtb3ZlXzI1MDRfaW5mZWN0X3BhdGllbnRfbm9iYXRjaC12IiwgdmVyLCAiLnhsc3giKSkpCnJlbW92ZV8yNTA0X3VuaW5mX2ZpbHR2Ml9zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICByZW1vdmVfMjUwNF91bmluZl9maWx0djJfY29tYmluZWQsIGFjY29yZGluZ190bz0iZGVzZXEiLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvIiwgcnVuZGF0ZSwgInJlbW92ZV8yNTA0X2luZmVjdF9wYXRpZW50X25vYmF0Y2hfc2lnLXYiLCB2ZXIsICIueGxzeCIpKSkKYGBgCgoKIyMgTWFrZSBzb21lIFZlbm5zCgpOb3cgd2Ugd2FudCB0byBsb29rIGF0IGludGVyc2VjdGlvbnMgZnJvbSB0aGUgcGVyc3BlY3RpdmUgb2YgY29udHJhc3RzIHBlcmZvcm1lZApjb21wYXJpbmcgdGhlIHNlbGYtaGVhbGluZy9jaHJvbmljIHZzLiB1bmluZmVjdGVkIGZvciB0aGUgdGhyZWUgZG9ub3JzIHNlcGFyYXRlbHkuCgojIyMgUGVyZm9ybSB2ZW5ucyBvZiBzZWxmLWhlYWxpbmcgdnMuIHVuaW5mZWN0ZWQKClRoaXMgdGltZSBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgZG9ub3JzOiBzZWxmLWhlYWxpbmcgdXAgdnMuIHVuaW5mZWN0ZWQuCgpgYGB7ciB2ZW5uX3VwX2Rlc2VxX3NofQp1cF9zaWcgPC0gaHNfdW5pbmZfZmlsdHYyX3NpZyRkZXNlcSR1cHMKCiMjIERvIHRoaXMgaW4gYSB3YXkgd2hpY2ggaXMgbm90IHN0dXBpZC4uLgpjb21wX2xzdCA8LSBsaXN0KAogICJkb25vcl8xMDciID0gcm93bmFtZXModXBfc2lnW1siZDEwN19zaHVuIl1dKSwKICAiZG9ub3JfMTA4IiA9IHJvd25hbWVzKHVwX3NpZ1tbImQxMDhfc2h1biJdXSksCiAgImRvbm9yXzExMCIgPSByb3duYW1lcyh1cF9zaWdbWyJkMTEwX3NodW4iXV0pKQpjb21wX3NodW5fdXAgPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWNvbXBfbHN0KQp1cF9yZXMgPC0gVmVubmVyYWJsZTo6cGxvdChjb21wX3NodW5fdXAsIGRvV2VpZ2h0cz1GQUxTRSkKCnNoYXJlZF9zaHVuX3VwIDwtIGNvbXBfc2h1bl91cEBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCmRlX3RhYmxlX3NoYXJlZF91cF9zaF9maXJzdCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDEwN19zaHVuIl1dW3NoYXJlZF9zaHVuX3VwLCBdCmRlX3RhYmxlX3NoYXJlZF91cF9zaF9zZWNvbmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMDhfc2h1biJdXVtzaGFyZWRfc2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfc2hfdGhpcmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMTBfc2h1biJdXVtzaGFyZWRfc2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfc2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF91cF9zaF9maXJzdFssIGMoImRlc2NyaXB0aW9uIiwgImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgZGVfdGFibGVfc2hhcmVkX3VwX3NoX3NlY29uZFssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgYnk9InJvdy5uYW1lcyIpCmRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwgPC0gbWVyZ2UoCiAgZGVfdGFibGVfc2hhcmVkX3VwX3NoX2FsbCwKICBkZV90YWJsZV9zaGFyZWRfdXBfc2hfdGhpcmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5Lng9IlJvdy5uYW1lcyIsIGJ5Lnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwpIDwtIGRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGxbWyJSb3cubmFtZXMiXV0KZGVfdGFibGVfc2hhcmVkX3VwX3NoX2FsbCA8LSBkZV90YWJsZV9zaGFyZWRfdXBfc2hfYWxsWywgLTFdCmNvbG5hbWVzKGRlX3RhYmxlX3NoYXJlZF91cF9zaF9hbGwpIDwtIGMoImRlc2NyaXB0aW9uIiwgImxvZ2ZjXzEwNyIsICJhZGpwXzEwNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvZ2ZjXzEwOCIsICJhZGpwXzEwOCIsICJsb2dmY18xMTAiLCAiYWRqcF8xMTAiKQp3cml0ZS5jc3YoZGVfdGFibGVfc2hhcmVkX3VwX3NoX2FsbCwKICAgICAgICAgIGZpbGU9cGFzdGUwKCJpbWFnZXMvIiwgcnVuZGF0ZSwgIl9kZV90YWJsZV9zaGFyZWRfdXBfc2hfYWxsLmNzdiIpKQpgYGAKCiMjIyBQZXJmb3JtIHZlbm5zIG9mIGNocm9uaWMgdnMuIHVuaW5mZWN0ZWQKClRoaXMgdGltZSBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgZG9ub3JzOiBjaHJvbmljIHVwIHZzLiB1bmluZmVjdGVkLgoKYGBge3IgdmVubl91cF9kZXNlcV9jaHJ9CnVwX3NpZyA8LSBoc191bmluZl9maWx0djJfc2lnJGRlc2VxJHVwcwpjb21wX2xzdCA8LSBsaXN0KAogICJkb25vcl8xMDciID0gcm93bmFtZXModXBfc2lnW1siZDEwN19jaHVuIl1dKSwKICAiZG9ub3JfMTA4IiA9IHJvd25hbWVzKHVwX3NpZ1tbImQxMDhfY2h1biJdXSksCiAgImRvbm9yXzExMCIgPSByb3duYW1lcyh1cF9zaWdbWyJkMTEwX2NodW4iXV0pKQpjb21wX2NodW5fdXAgPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWNvbXBfbHN0KQp1cF9yZXMgPC0gVmVubmVyYWJsZTo6cGxvdChjb21wX2NodW5fdXAsIGRvV2VpZ2h0cz1GQUxTRSkKCnNoYXJlZF9jaHVuX3VwIDwtIGNvbXBfY2h1bl91cEBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCmRlX3RhYmxlX3NoYXJlZF91cF9jaF9maXJzdCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDEwN19jaHVuIl1dW3NoYXJlZF9jaHVuX3VwLCBdCmRlX3RhYmxlX3NoYXJlZF91cF9jaF9zZWNvbmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMDhfY2h1biJdXVtzaGFyZWRfY2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfY2hfdGhpcmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMTBfY2h1biJdXVtzaGFyZWRfY2h1bl91cCwgXQpkZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF91cF9jaF9maXJzdFssIGMoImRlc2NyaXB0aW9uIiwgImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgZGVfdGFibGVfc2hhcmVkX3VwX2NoX3NlY29uZFssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgYnk9InJvdy5uYW1lcyIpCmRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGwgPC0gbWVyZ2UoCiAgZGVfdGFibGVfc2hhcmVkX3VwX2NoX2FsbCwKICBkZV90YWJsZV9zaGFyZWRfdXBfY2hfdGhpcmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5Lng9IlJvdy5uYW1lcyIsIGJ5Lnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGwpIDwtIGRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGxbWyJSb3cubmFtZXMiXV0KZGVfdGFibGVfc2hhcmVkX3VwX2NoX2FsbCA8LSBkZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsWywgLTFdCmNvbG5hbWVzKGRlX3RhYmxlX3NoYXJlZF91cF9jaF9hbGwpIDwtIGMoImRlc2NyaXB0aW9uIiwgImxvZ2ZjXzEwNyIsICJhZGpwXzEwNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvZ2ZjXzEwOCIsICJhZGpwXzEwOCIsICJsb2dmY18xMTAiLCAiYWRqcF8xMTAiKQp3cml0ZS5jc3YoZGVfdGFibGVfc2hhcmVkX3VwX2NoX2FsbCwKICAgICAgICAgIGZpbGU9cGFzdGUwKCJpbWFnZXMvIiwgcnVuZGF0ZSwgIl9kZV90YWJsZV9zaGFyZWRfdXBfY2hfYWxsLmNzdiIpKQpgYGAKCiMjIyBQZXJmb3JtIHZlbm5zIG9mIHNlbGYtaGVhbGluZyB2cy4gdW5pbmZlY3RlZAoKVGhpcyB0aW1lIGZvciBlYWNoIG9mIHRoZSB0aHJlZSBkb25vcnM6IHNlbGYtaGVhbGluZyBkb3duIHZzLiB1bmluZmVjdGVkLgoKYGBge3IgdmVubl9kb3duX2Rlc2VxX3NofQpkb3duX3NpZyA8LSBoc191bmluZl9maWx0djJfc2lnJGRlc2VxJGRvd25zCmNvbXBfbHN0IDwtIGxpc3QoCiAgImRvbm9yXzEwNyIgPSByb3duYW1lcyhkb3duX3NpZ1tbImQxMDdfc2h1biJdXSksCiAgImRvbm9yXzEwOCIgPSByb3duYW1lcyhkb3duX3NpZ1tbImQxMDhfc2h1biJdXSksCiAgImRvbm9yXzExMCIgPSByb3duYW1lcyhkb3duX3NpZ1tbImQxMTBfc2h1biJdXSkpCmNvbXBfc2h1bl9kb3duIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1jb21wX2xzdCkKZG93bl9yZXMgPC0gVmVubmVyYWJsZTo6cGxvdChjb21wX3NodW5fZG93biwgZG9XZWlnaHRzPUZBTFNFKQoKc2hhcmVkX3NodW5fZG93biA8LSBjb21wX3NodW5fZG93bkBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCmRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2ZpcnN0IDwtIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZFtbImRhdGEiXV1bWyJkMTA3X3NodW4iXV1bc2hhcmVkX3NodW5fZG93biwgXQpkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9zZWNvbmQgPC0gaHNfdW5pbmZfZmlsdHYyX2NvbWJpbmVkW1siZGF0YSJdXVtbImQxMDhfc2h1biJdXVtzaGFyZWRfc2h1bl9kb3duLCBdCmRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX3RoaXJkIDwtIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZFtbImRhdGEiXV1bWyJkMTEwX3NodW4iXV1bc2hhcmVkX3NodW5fZG93biwgXQpkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9hbGwgPC0gbWVyZ2UoCiAgZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfZmlyc3RbLCBjKCJkZXNjcmlwdGlvbiIsICJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX3NlY29uZFssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiKV0sCiAgYnk9InJvdy5uYW1lcyIpCmRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbCA8LSBtZXJnZSgKICBkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9hbGwsCiAgZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfdGhpcmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5Lng9IlJvdy5uYW1lcyIsIGJ5Lnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbCkgPC0gZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsW1siUm93Lm5hbWVzIl1dCmRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbCA8LSBkZV90YWJsZV9zaGFyZWRfZG93bl9zaF9hbGxbLCAtMV0KY29sbmFtZXMoZGVfdGFibGVfc2hhcmVkX2Rvd25fc2hfYWxsKSA8LSBjKCJkZXNjcmlwdGlvbiIsICJsb2dmY18xMDciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFkanBfMTA3IiwgImxvZ2ZjXzEwOCIsICJhZGpwXzEwOCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibG9nZmNfMTEwIiwgImFkanBfMTEwIikKd3JpdGUuY3N2KGRlX3RhYmxlX3NoYXJlZF9kb3duX3NoX2FsbCwKICAgICAgICAgIGZpbGU9cGFzdGUwKCJpbWFnZXMvIiwgcnVuZGF0ZSwgIl9kZV90YWJsZV9zaGFyZWRfZG93bl9zaF9hbGwuY3N2IikpCmBgYAoKIyMjIFBlcmZvcm0gdmVubnMgb2Ygc2VsZi1oZWFsaW5nIHZzLiB1bmluZmVjdGVkCgpUaGlzIHRpbWUgZm9yIGVhY2ggb2YgdGhlIHRocmVlIGRvbm9yczogY2hyb25pYyBkb3duIHZzLiB1bmluZmVjdGVkLgoKYGBge3IgdmVubl9kb3duX2Rlc2VxX2Nocn0KZG93bl9zaWcgPC0gaHNfdW5pbmZfZmlsdHYyX3NpZyRkZXNlcSRkb3ducwpjb21wX2xzdCA8LSBsaXN0KAogICJkb25vcl8xMDciID0gcm93bmFtZXMoZG93bl9zaWdbWyJkMTA3X2NodW4iXV0pLAogICJkb25vcl8xMDgiID0gcm93bmFtZXMoZG93bl9zaWdbWyJkMTA4X2NodW4iXV0pLAogICJkb25vcl8xMTAiID0gcm93bmFtZXMoZG93bl9zaWdbWyJkMTEwX2NodW4iXV0pKQpjb21wX2NodW5fZG93biA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9Y29tcF9sc3QpCmRvd25fcmVzIDwtIFZlbm5lcmFibGU6OnBsb3QoY29tcF9jaHVuX2Rvd24sIGRvV2VpZ2h0cz1GQUxTRSkKCnNoYXJlZF9jaHVuX2Rvd24gPC0gY29tcF9jaHVuX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjExMSJdXQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9maXJzdCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDEwN19jaHVuIl1dW3NoYXJlZF9jaHVuX2Rvd24sIF0KZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfc2Vjb25kIDwtIGhzX3VuaW5mX2ZpbHR2Ml9jb21iaW5lZFtbImRhdGEiXV1bWyJkMTA4X2NodW4iXV1bc2hhcmVkX2NodW5fZG93biwgXQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF90aGlyZCA8LSBoc191bmluZl9maWx0djJfY29tYmluZWRbWyJkYXRhIl1dW1siZDExMF9jaHVuIl1dW3NoYXJlZF9jaHVuX2Rvd24sIF0KZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsIDwtIG1lcmdlKAogIGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX2ZpcnN0WywgYygiZGVzY3JpcHRpb24iLCAiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXSwKICBkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9zZWNvbmRbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIildLAogIGJ5PSJyb3cubmFtZXMiKQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwgPC0gbWVyZ2UoCiAgZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsLAogIGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX3RoaXJkWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIpXSwKICBieS54PSJSb3cubmFtZXMiLCBieS55PSJyb3cubmFtZXMiKQpyb3duYW1lcyhkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwpIDwtIGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX2FsbFtbIlJvdy5uYW1lcyJdXQpkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwgPC0gZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsWywgLTFdCmNvbG5hbWVzKGRlX3RhYmxlX3NoYXJlZF9kb3duX2NoX2FsbCkgPC0gYygiZGVzY3JpcHRpb24iLCAibG9nZmNfMTA3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZGpwXzEwNyIsICJsb2dmY18xMDgiLCAiYWRqcF8xMDgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvZ2ZjXzExMCIsICJhZGpwXzExMCIpCndyaXRlLmNzdihkZV90YWJsZV9zaGFyZWRfZG93bl9jaF9hbGwsCiAgICAgICAgICBmaWxlPXBhc3RlMCgiaW1hZ2VzLyIsIHJ1bmRhdGUsICJfZGVfdGFibGVfc2hhcmVkX2Rvd25fY2hfYWxsLmNzdiIpKQpgYGAKCkF0IHRoaXMgcG9pbnQsIHdlIHNob3VsZCBoYXZlIGEgc2V0IG9mIGdlbmVzIHdoaWNoIGFyZSB1cC9kb3duIGluIHRoZQpzZWxmL3VuaW5mZWN0ZWQgYW5kIGNocm9uaWMvdW5pbmZlY3RlZCwga2VwdCBpbiB2YXJpYWJsZXMgd2l0aCBuYW1lcyBsaWtlOgonc2hhcmVkX3NodW5fZG93bicgYW5kICdzaGFyZWRfY2h1bl9kb3duJwoKIyMgR2V0IE1ldGEhICBJbnRlcnNlY3QgdGhlIGFib3ZlIGNvbXBhcmlzb25zLgoKTm93IHdlIHdhbnQgYSBzZW5zZSBvZiB3aGF0IGdlbmVzIGFyZSBzaGFyZWQvdW5pcXVlIGFtb25nIHRoZSBzZWxmLWhlYWxpbmcKdnMuIHVuaW5mZWN0ZWQgYW5kIHRoZSBjaHJvbmljIHZzLiB1bmluZmVjdGVkIGNvbXBhcmlzb25zIHBlcmZvcm1lZCBhYm92ZS4gIE9uZQp3b3VsZCBhc3N1bWUgdGhhdCB0aGUgbW9zdCBpbnRlcmVzdGluZyBnZW5lcyBpbiB0aGVzZSBzZXRzIHdpbGwgcHJvdmUgdG8gYmUgdGhlCnRoZSBvbmVzIHdoaWNoIGFyZSBfbm90XyBzaGFyZWQuCgpgYGB7ciBzaGFyZWRfaW50ZXJzZWN0aW9uc30Kc2hjaF91cF9sc3QgPC0gbGlzdCgKICAidXBfc2giID0gc2hhcmVkX3NodW5fdXAsCiAgInVwX2NoIiA9IHNoYXJlZF9jaHVuX3VwKQpzaGFyZWRfdXAgPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPXNoY2hfdXBfbHN0KQpWZW5uZXJhYmxlOjpwbG90KHNoYXJlZF91cCwgZG9XZWlnaHRzPUZBTFNFKQoKc2hjaF9kb3duX2xzdCA8LSBsaXN0KAogICJ1cF9zaCIgPSBzaGFyZWRfc2h1bl9kb3duLAogICJ1cF9jaCIgPSBzaGFyZWRfY2h1bl9kb3duKQpzaGFyZWRfZG93biA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9c2hjaF9kb3duX2xzdCkKVmVubmVyYWJsZTo6cGxvdChzaGFyZWRfZG93biwgZG9XZWlnaHRzPUZBTFNFKQoKdXB1cF9nZW5lcyA8LSBzaGFyZWRfdXBASW50ZXJzZWN0aW9uU2V0c1tbIjExIl1dCnVwc2hfbm90Y2ggPC0gc2hhcmVkX3VwQEludGVyc2VjdGlvblNldHNbWyIxMCJdXQp1cGNoX25vdHNoIDwtIHNoYXJlZF91cEBJbnRlcnNlY3Rpb25TZXRzW1siMDEiXV0KZG93bmRvd25fZ2VuZXMgPC0gc2hhcmVkX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjExIl1dCmRvd25zaF9ub3RjaCA8LSBzaGFyZWRfZG93bkBJbnRlcnNlY3Rpb25TZXRzW1siMTAiXV0KZG93bmNoX25vdHNoIDwtIHNoYXJlZF9kb3duQEludGVyc2VjdGlvblNldHNbWyIwMSJdXQoKa2VwdF9jb2x1bW5zIDwtIGMoImVuc2VtYmx0cmFuc2NyaXB0aWQiLCAiZW5zZW1ibGdlbmVpZCIsICJkZXNjcmlwdGlvbiIsCiAgICAgICAgICAgICAgICAgICJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIikKIyMgR2V0IHRoZSBzaGFyZWQgdGhpbmdzIGluIHVwX3NoIGFuZCB1cF9jaCwgZXJnbyBjYW4gdXNlIGVpdGhlciBzaGVldAp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscyhkYXRhPXVwX3NpZ1tbImQxMDdfc2h1biJdXVt1cHVwX2dlbmVzLCBrZXB0X2NvbHVtbnNdLAogICAgICAgICAgICAgICAgICAgICAgICBzaGVldD0idXBzaF91cGNoIikKIyMgR2V0IHRoZSBvbmx5LXVwX3NoCnhsc19yZXN1bHQgPC0gd3JpdGVfeGxzKGRhdGE9dXBfc2lnW1siZDEwN19zaHVuIl1dW3Vwc2hfbm90Y2gsIGtlcHRfY29sdW1uc10sCiAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0PSJ1cHNoX25vY2giLAogICAgICAgICAgICAgICAgICAgICAgICB3Yj14bHNfcmVzdWx0W1sid29ya2Jvb2siXV0pCiMjIEdldCB0aGUgb25seS11cF9jaAp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscyhkYXRhPXVwX3NpZ1tbImQxMDdfY2h1biJdXVt1cGNoX25vdHNoLCBrZXB0X2NvbHVtbnNdLAogICAgICAgICAgICAgICAgICAgICAgICBzaGVldD0idXBjaF9ub3NoIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2I9eGxzX3Jlc3VsdFtbIndvcmtib29rIl1dKQojIyBOb3cgcmVwZWF0IGZvciB0aGUgZG93bjogZG93bi1zaGFyZWQKIyMgR2V0IHNoYXJlZCBkb3duIGRvd25fc2ggZG93bl9jaAp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscyhkYXRhPWRvd25fc2lnW1siZDEwN19zaHVuIl1dW2Rvd25kb3duX2dlbmVzLCBrZXB0X2NvbHVtbnNdLAogICAgICAgICAgICAgICAgICAgICAgICBzaGVldD0iZG93bnNoX2Rvd25jaCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdiPXhsc19yZXN1bHRbWyJ3b3JrYm9vayJdXSkKIyMgVGhlIGRvd25fc2ggb25seQp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscyhkYXRhPWRvd25fc2lnW1siZDEwN19zaHVuIl1dW2Rvd25zaF9ub3RjaCwga2VwdF9jb2x1bW5zXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQ9ImRvd25zaF9ub2NoIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2I9eGxzX3Jlc3VsdFtbIndvcmtib29rIl1dKQojIyBUaGUgZG93bl9jaAp4bHNfcmVzdWx0IDwtIHdyaXRlX3hscyhkYXRhPWRvd25fc2lnW1siZDEwN19jaHVuIl1dW2Rvd25jaF9ub3RzaCwga2VwdF9jb2x1bW5zXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2hlZXQ9ImRvd25jaF9ub3NoIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2I9eGxzX3Jlc3VsdFtbIndvcmtib29rIl1dLAogICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsLyIsIHJ1bmRhdGUsICJfZmlndXJlXzVjX3N0dWZmLXYiLCB2ZXIsICIueGxzeCIpKQpgYGAKCiMjIyBHZW5lcyBzaGFyZWQgYW1vbmcgdGhlIGRvbm9ycy4KCk9uZSBmdXJ0aGVyIHF1ZXJ5OiB3aGF0IGdlbmVzIGFyZSBzaGFyZWQgYW1vbmcgdGhlIGNvbnRyYXN0cyBvZgpzZWxmLWhlYWxpbmcvY2hyb25pYyB2cy4gdW5pbmZlY3RlZCBmb3IgdGhlIHRocmVlIGRvbm9ycz8KV2hlbiBkb2luZyB0aGlzLCB3ZSBoYXZlIG9uY2UgYWdhaW4gdG8gY29uc2lkZXIgd2hldGhlciB0byB1c2UgdGhlCm5vYmF0Y2gvYmF0Y2gtaW4tbW9kZWwvc3ZhL2V0YyBtZXRob2RzIGFnYWluc3Qgb3VyIGRvbm9ycy4uLiAgU2luY2UgdGhleSBhbGwKYWdyZWUgcHJldHR5IHdlbGwgdW50aWwgY29tYmF0LCBJIHdpbGwgYXJiaXRyYXJpbHkgY2hvb3NlIGZzdmEuCgpPbmUgaWRlYSBzdWdnZXN0ZWQgYnkgTWFyaWEgQWRlbGFpZGEgd2FzIHRvIGNvbXBhcmUgdGhlIHNldCBvZiBnZW5lcyBzaGFyZWQKYW1vbmcgZDEwNy9kMTA4L2QxMTAgaW4gdGhpcyBsYXN0IGNvbXBhcmlzb24gKHdoaWNoIHdhcyBlYWNoIG9mIHRoZSB0aHJlZSBkb25vcnMKc2VwYXJhdGVseSkgYWdhaW5zdCB0aGUgc2V0IG9mIGdlbmVzIGluIHRoZSBhbGwtZGF0YSBhbmFseXNpcyBhYm92ZS4KCiMjIyMgQXR0ZW1wdCB0byBhbnN3ZXIgYnkgdGhlIHVuaXF1ZSBpbmRpdmlkdWFsIHNldHMKCkluIHRoaXMgYmxvY2ssIEkgd2lsbCBhdHRlbXB0IHRvIGFuc3dlciB0aGUgYWJvdmUgcXVlcnkgYnkgaW50ZXJzZWN0aW5nIHRoZSBzZXRzCm9mIGdlbmVzIHNoYXJlZCBhbW9uZyB0aGUgaW5kaXZpZHVhbHMgYnV0IHVuaXF1ZSB0byBzaC9jaHIgdnMuIHVuaW5mZWN0ZWQKYWdhaW5zdCB0aGUgc2V0IG9mIGdlbmVzIG9ic2VydmVkIGluIHRoZSBvcmlnaW5hbCBzdmEtbWVkaWF0ZWQgREUgYW5hbHlzaXMuCgpgYGB7ciBvdGhlcl9zdHVmZn0KaW5kaXZfc2h1cF91bmlxdWUgPC0gc2hhcmVkX3VwQEludGVyc2VjdGlvblNldHNbWyIxMCJdXQphdmdfdnNfaW5kX3NodW5fdXAgPC0gbGlzdCgKICAiZnN2YV9hdmciID0gcm93bmFtZXMoaHNfc2lnX2ZzdmFbWyJkZXNlcSJdXVtbInVwcyJdXVtbInNoX25pbCJdXSksCiAgImluZGl2IiA9IGluZGl2X3NodXBfdW5pcXVlKQphdmdfaW5kX3NodXBfdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9YXZnX3ZzX2luZF9zaHVuX3VwKQpWZW5uZXJhYmxlOjpwbG90KGF2Z19pbmRfc2h1cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCgppbmRpdl9jaHVwX3VuaXF1ZSA8LSBzaGFyZWRfdXBASW50ZXJzZWN0aW9uU2V0c1tbIjAxIl1dCmF2Z192c19pbmRfY2h1bl91cCA8LSBsaXN0KAogICJmc3ZhX2F2ZyIgPSByb3duYW1lcyhoc19zaWdfZnN2YVtbImRlc2VxIl1dW1sidXBzIl1dW1siY2hfbmlsIl1dKSwKICAiaW5kaXYiID0gaW5kaXZfc2h1cF91bmlxdWUpCmF2Z19pbmRfY2h1cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1hdmdfdnNfaW5kX2NodW5fdXApClZlbm5lcmFibGU6OnBsb3QoYXZnX2luZF9jaHVwX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKCmluZGl2X3NoZG93bl91bmlxdWUgPC0gc2hhcmVkX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjEwIl1dCmF2Z192c19pbmRfc2h1bl9kb3duIDwtIGxpc3QoCiAgImZzdmFfYXZnIiA9IHJvd25hbWVzKGhzX3NpZ19mc3ZhW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbInNoX25pbCJdXSksCiAgImluZGl2IiA9IGluZGl2X3NoZG93bl91bmlxdWUpCmF2Z19pbmRfc2hkb3duX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWF2Z192c19pbmRfc2h1bl9kb3duKQpWZW5uZXJhYmxlOjpwbG90KGF2Z19pbmRfc2hkb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKCmluZGl2X2NoZG93bl91bmlxdWUgPC0gc2hhcmVkX2Rvd25ASW50ZXJzZWN0aW9uU2V0c1tbIjAxIl1dCmF2Z192c19pbmRfY2h1bl9kb3duIDwtIGxpc3QoCiAgImZzdmFfYXZnIiA9IHJvd25hbWVzKGhzX3NpZ19mc3ZhW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImNoX25pbCJdXSksCiAgImluZGl2IiA9IGluZGl2X3NoZG93bl91bmlxdWUpCmF2Z19pbmRfY2hkb3duX3Zlbm4gPC0gVmVubmVyYWJsZTo6VmVubihTZXRzPWF2Z192c19pbmRfY2h1bl9kb3duKQpWZW5uZXJhYmxlOjpwbG90KGF2Z19pbmRfY2hkb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKYGBgCgojIyMjIEFuc3dlciBieSBsb29raW5nIGF0IHRoZSBzaGFyZWQgZ2VuZXMgaW4gYm90aCBzZXRzCgpgYGB7ciBjb21wYXJlX2F2Z19kb25vcl9pbmRpdmlkdWFsX2Rvbm9yfQpzaHVuX3VwX2F2Z19nZW5lcyA8LSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbInVwcyJdXVtbInNoX25pbCJdXSkKY2h1bl91cF9hdmdfZ2VuZXMgPC0gcm93bmFtZXMoaHNfc2lnX2JhdGNoW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJjaF9uaWwiXV0pCnNodW5fZG93bl9hdmdfZ2VuZXMgPC0gcm93bmFtZXMoaHNfc2lnX2JhdGNoW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbInNoX25pbCJdXSkKY2h1bl9kb3duX2F2Z19nZW5lcyA8LSByb3duYW1lcyhoc19zaWdfYmF0Y2hbWyJkZXNlcSJdXVtbImRvd25zIl1dW1siY2hfbmlsIl1dKQoKc2h1bl91cF9pbmRpdmlkdWFsX2dlbmVzIDwtIGNvbXBfc2h1bl91cEBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCmNodW5fdXBfaW5kaXZpZHVhbF9nZW5lcyA8LSBjb21wX2NodW5fdXBASW50ZXJzZWN0aW9uU2V0c1tbIjExMSJdXQpzaHVuX2Rvd25faW5kaXZpZHVhbF9nZW5lcyA8LSBjb21wX3NodW5fZG93bkBJbnRlcnNlY3Rpb25TZXRzW1siMTExIl1dCmNodW5fZG93bl9pbmRpdmlkdWFsX2dlbmVzIDwtIGNvbXBfY2h1bl9kb3duQEludGVyc2VjdGlvblNldHNbWyIxMTEiXV0KCmxhc3Rfc2h1bl91cF9sc3QgPC0gbGlzdCgKICAiYXZnX2dlbmVzIiA9IHNodW5fdXBfYXZnX2dlbmVzLAogICJpbmRfZ2VuZXMiID0gc2h1bl91cF9pbmRpdmlkdWFsX2dlbmVzKQpsYXN0X3NodW5fdXBfdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9bGFzdF9zaHVuX3VwX2xzdCkKVmVubmVyYWJsZTo6cGxvdChsYXN0X3NodW5fdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQoKbGFzdF9jaHVuX3VwX2xzdCA8LSBsaXN0KAogICJhdmdfZ2VuZXMiID0gY2h1bl91cF9hdmdfZ2VuZXMsCiAgImluZF9nZW5lcyIgPSBjaHVuX3VwX2luZGl2aWR1YWxfZ2VuZXMpCmxhc3RfY2h1bl91cF92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1sYXN0X2NodW5fdXBfbHN0KQpWZW5uZXJhYmxlOjpwbG90KGxhc3RfY2h1bl91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCgpsYXN0X3NodW5fZG93bl9sc3QgPC0gbGlzdCgKICAiYXZnX2dlbmVzIiA9IHNodW5fZG93bl9hdmdfZ2VuZXMsCiAgImluZF9nZW5lcyIgPSBzaHVuX2Rvd25faW5kaXZpZHVhbF9nZW5lcykKbGFzdF9zaHVuX2Rvd25fdmVubiA8LSBWZW5uZXJhYmxlOjpWZW5uKFNldHM9bGFzdF9zaHVuX2Rvd25fbHN0KQpWZW5uZXJhYmxlOjpwbG90KGxhc3Rfc2h1bl9kb3duX3Zlbm4sIGRvV2VpZ2h0cz1GQUxTRSkKCmxhc3RfY2h1bl9kb3duX2xzdCA8LSBsaXN0KAogICJhdmdfZ2VuZXMiID0gY2h1bl9kb3duX2F2Z19nZW5lcywKICAiaW5kX2dlbmVzIiA9IGNodW5fZG93bl9pbmRpdmlkdWFsX2dlbmVzKQpsYXN0X2NodW5fZG93bl92ZW5uIDwtIFZlbm5lcmFibGU6OlZlbm4oU2V0cz1sYXN0X2NodW5fZG93bl9sc3QpClZlbm5lcmFibGU6OnBsb3QobGFzdF9jaHVuX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpgYGAKCiMjIyBERTogaW5jbHVkZSB1bmluZmVjdGVkLCByZXBlYXQgd2l0aCBjb25kaXRpb24gc2ltcGxpZmllZCB0byBjaHJvbmljL3NlbGYKCkRvIEkgdGhpbmsgdGhlIGV4YWN0IHNhbWUgdGhpbmcgYXMgaW4gdGhlIHByZXZpb3VzIGNvbXBhcmlzb24sIGJ1dCBub3cgc2ltcGxpZnkgdGhlICdjb25kaXRpb24nCmZhY3RvciB0byBqdXN0IHNlbGYtaGVhbGluZyB2cy4gY2hyb25pYyBhbmQgc2VlIHdoYXQgaGFwcGVucy4KCmBgYHtyIGRlX2Nocm9uaWNzaF9zdHJhaW5iYXRjaCwgZXZhbD1GQUxTRX0KdW5pbmZfc3RyYWluYmF0Y2hfcWNmIDwtIHNldF9leHB0X2JhdGNoZXMoZXhwdD1oc19jZHNfdW5pbmYsIGZhY3Q9InBhdGhvZ2Vuc3RyYWluIikKdW5pbmZfc3RyYWluYmF0Y2hfcWNmIDwtIHNldF9leHB0X2NvbmRpdGlvbnMoZXhwdD11bmluZl9zdHJhaW5iYXRjaF9xY2YsIGZhY3Q9InN0YXRlIikKd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3BhaXJzX2Noc2ggPC0gYWxsX3BhaXJ3aXNlKAogIHVuaW5mX3N0cmFpbmJhdGNoX3FjZiwKICBtb2RlbF9iYXRjaD1GQUxTRSwgZm9yY2U9VFJVRSwgZG9fZWJzZXE9RkFMU0UpCmNoc2hfa2VlcGVycyA8LSBsaXN0KAogICAgImNoX3NoIiA9IGMoImNocm9uaWMiLCAic2VsZl9oZWFsIiksCiAgICAiY2hfbmlsIiA9IGMoImNocm9uaWMiLCAidW5pbmZlY3RlZCIpLAogICAgInNoX25pbCIgPSBjKCJzZWxmX2hlYWwiLCAidW5pbmZlY3RlZCIpKQp3aXRodW5pbmZfc3RyYWluYmF0Y2hfdGFibGVzX2Noc2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMoCiAgd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3BhaXJzX2Noc2gsCiAga2VlcGVycz1jaHNoX2tlZXBlcnMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC8iLCBydW5kYXRlLCAiX3dpdGh1bmluZl9zdHJhaW5iYXRjaF9jaHNoX3BhaXJ3aXNlLXYiLCB2ZXIsICIueGxzeCIpKSkKd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3NpZ19jaHNoIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3RhYmxlc19jaHNoLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvIiwgcnVuZGF0ZSwgIl93aXRodW5pbmZfc3RyYWluYmF0Y2hfY2hzaF9zaWctdiIsIHZlciwgIi54bHN4IikpCiMjd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3RhYmxlc19jaHNoJGxpbW1hX3Bsb3RzCiMjd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3RhYmxlc19jaHNoJGVkZ2VyX3Bsb3RzCiMjd2l0aHVuaW5mX3N0cmFpbmJhdGNoX3RhYmxlc19jaHNoJGRlc2VxX3Bsb3RzCmBgYAoKIyBGaWd1cmUgNQoKR2VuZXJhdGUgREUgbGlzdHMgb2YgZWFjaCBkb25vciBmb3IgYWxsIGNvbnRyYXN0cyBmb3IgUEJNQ3MuCgogIGEuICBWZW5uIHNoL3VuaW5mIHZzIGNoci91bmluZiAyIHZlbm4gZGlhZ3JhbSB1cC4gKGRvbm9yIGluIG1vZGVsKQogIGIuICBWZW5uIHNoL3VuaW5mIHZzIGNoci91bmluZiAyIHZlbm4gZGlhZ3JhbSBkb3duLgogIGMuICBWZW5uIFNoL3VuaW5mIHVwIGdlbmVzIDMgdmVubiBkaWFncmFtLgogIGQuICBWZW5uIFNoL3VuaW5mIGRvd24gZ2VuZXMgMyB2ZW5uLgogIGUuICBWZW5uIENoci91bmluZiB1cCBnZW5lcyAzIHZlbm4uCiAgZi4gIFZlbm4gQ2hyL3VuaW5mIGRvd24gZ2VuZXMgMyB2ZW5uLgogIGcuICAyIHdheSB2ZW5uIG9mIChjb21tb24gdXAgaW4gMyB2ZW5uIHNoL3VuaW5mKSB2cy4gKGNvbW1vbiB1cCBpbiAzIHZlbm4gY2hyL3VuaW5mKQogIGguICAyIHdheSB2ZW5uIG9mIChjb21tb24gZG93biBpbiAzIHZlbm4gc2gvdW5pbmYpIHZzLiAoY29tbW9uIGRvd24gaW4gMyB2ZW5uIGNoci91bmluZikKCkkgcmVuYW1lZCB0aGVzZSBwbG90cyBhbmQgYW0gbm93IGhvcGVsZXNzbHkgY29uZnVzZWQgYXMgdG8gd2hpY2ggaXMgd2hpY2guICBJCnRoaW5rIEkgd2lsbCBub3QgcnVuIHRoaXMgZm9yIG5vdyBidXQgaW5zdGVhZCBnZW5lcmF0ZSB0aGUgd29ya3NoZWV0IHdpdGhvdXQKdGhlbSBhbmQgdGhlbiByZXR1cm4gdG8gdGhpcyBpbiB0aGUgaG9wZXMgdGhhdCBJIGNhbiBkbyBhIGJldHRlciBqb2IuCgpgYGB7ciBmaWd1cmVfNSwgZXZhbD1GQUxTRX0KcHAoZmlsZT1wYXN0ZTAoImltYWdlcy8iLCBydW5kYXRlLCAiX2ZpZ18wNWEtc2hfdW5pbmZfdnNfY2hyX3VuaW5mX3VwLnBkZiIpKQpWZW5uZXJhYmxlOjpwbG90KGNvbW1vbl9zb2xvc19iYXRjaCR1cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLyIsIHJ1bmRhdGUsICJfZmlnXzA1Yi1zaF91bmluZl92c19jaHJfdW5pbmZfZG93bi5wZGYiKSkKVmVubmVyYWJsZTo6cGxvdChjb21tb25fc29sb3NfYmF0Y2gkZG93bl92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLyIsIHJ1bmRhdGUsICJfZmlnXzA1Yy1zaF91bmluZl9kb25vcnNfdXAucGRmIikpClZlbm5lcmFibGU6OnBsb3Qoc2hfdXBfdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkZXYub2ZmKCkKcHAoZmlsZT1wYXN0ZTAoImltYWdlcy8iLCBydW5kYXRlLCAiX2ZpZ18wNWQtc2hfdW5pbmZfZG9ub3JzX2Rvd24ucGRmIikpClZlbm5lcmFibGU6OnBsb3Qoc2hfZG93bl92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLyIsIHJ1bmRhdGUsICJfZmlnXzA1ZS1jaHJfdW5pbmZfZG9ub3JzX3VwLnBkZiIpKQpWZW5uZXJhYmxlOjpwbG90KGNocl91cF92ZW5uLCBkb1dlaWdodHM9RkFMU0UpCmRldi5vZmYoKQpwcChmaWxlPXBhc3RlMCgiaW1hZ2VzLyIsIHJ1bmRhdGUsICJfZmlnXzA1Zi1jaHJfdW5pbmZfZG9ub3JzX2Rvd24ucGRmIikpClZlbm5lcmFibGU6OnBsb3QoY2hyX2Rvd25fdmVubiwgZG9XZWlnaHRzPUZBTFNFKQpkZXYub2ZmKCkKcHAoZmlsZT1wYXN0ZTAoImltYWdlcy8iLCBydW5kYXRlLCAiX2ZpZ18wNWctdXBfY29tbW9uLnBkZiIpKQpWZW5uZXJhYmxlOjpwbG90KHNoYXJlZF91cCwgZG9XZWlnaHRzPUZBTFNFKQpkZXYub2ZmKCkKcHAoZmlsZT1wYXN0ZTAoImltYWdlcy8iLCBydW5kYXRlLCAiX2ZpZ18wNWgtZG93bl9jb21tb24ucGRmIikpClZlbm5lcmFibGU6OnBsb3Qoc2hhcmVkX2Rvd24sIGRvV2VpZ2h0cz1GQUxTRSkKZGV2Lm9mZigpCmBgYAoKIyBUcnkgYWdhaW4gb24gdGhlIHBhcmFzaXRlIGRhdGEKCiMjIFJlbWVtYmVyIG91ciBkYXRhIHNldAoKYGBge3IgbHBfZXhwcmVzc2lvbjAxfQpscF9pbmZfZmlsdCA8LSBzbShub3JtYWxpemVfZXhwdChscF9pbmYsIGZpbHRlcj1UUlVFKSkKYGBgCgpgYGB7ciBscF9ub2JhdGNoLCBzaG93LmZpZz0iaGlkZSJ9CmxwX3BhaXJ3aXNlX25vYmF0Y2ggPC0gc20oYWxsX3BhaXJ3aXNlKGxwX2luZl9maWx0LCBtb2RlbF9iYXRjaD1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9fZWJzZXE9RkFMU0UpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9scF9pbmZlY3Rfbm9iYXRjaF9jb250ci12e3Zlcn0ueGxzeCIpCmxwX2NvbWJpbmVkX25vYmF0Y2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMobHBfcGFpcndpc2Vfbm9iYXRjaCwgZXhjZWw9ZXhjZWxfZmlsZSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2xwX2luZmVjdF9ub2JhdGNoX3NpZy12e3Zlcn0ueGxzeCIpCmxwX3NpZ19ub2JhdGNoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobHBfY29tYmluZWRfbm9iYXRjaCwgZXhjZWw9ZXhjZWxfZmlsZSkpCmBgYAoKYGBge3IgbHBfYmF0Y2gsIHNob3cuZmlnPSJoaWRlIn0KbHBfcGFpcndpc2VfYmF0Y2ggPC0gc20oYWxsX3BhaXJ3aXNlKGxwX2luZl9maWx0LCBtb2RlbF9iYXRjaD1UUlVFKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1fbHBfaW5mZWN0X2JhdGNoX2NvbnRyLXZ7dmVyfS54bHN4IikKbHBfY29tYmluZWRfYmF0Y2ggPC0gc20oY29tYmluZV9kZV90YWJsZXMobHBfcGFpcndpc2VfYmF0Y2gsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9scF9pbmZlY3RfYmF0Y2hfc2lnLXZ7dmVyfS54bHN4IikKbHBfc2lnX2JhdGNoIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobHBfY29tYmluZWRfYmF0Y2gsIGV4Y2VsPWV4Y2VsX2ZpbGUpKQpgYGAKCmBgYHtyIGxwX3NzdmEsIHNob3cuZmlnPSJoaWRlIn0KbHBfcGFpcndpc2Vfc3N2YSA8LSBzbShhbGxfcGFpcndpc2UobHBfaW5mX2ZpbHQsIG1vZGVsX2JhdGNoPSJzc3ZhIikpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2xwX2luZmVjdF9zc3ZhX2NvbnRyLXZ7dmVyfS54bHN4IikKbHBfY29tYmluZWRfc3N2YSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhscF9wYWlyd2lzZV9zc3ZhLCBleGNlbD1leGNlbF9maWxlKSkKZXhjZWxfZmlsZSA8LSBnbHVlOjpnbHVlKCJleGNlbC97cnVuZGF0ZX1fbHBfaW5mZWN0X3NzdmFfc2lnLXZ7dmVyfS54bHN4IikKbHBfc2lnX3NzdmEgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhscF9jb21iaW5lZF9zc3ZhLCBleGNlbD1leGNlbF9maWxlKSkKYGBgCgpgYGB7ciBscF9mc3ZhLCBzaG93LmZpZz0iaGlkZSJ9CmxwX3BhaXJ3aXNlX2ZzdmEgPC0gc20oYWxsX3BhaXJ3aXNlKGxwX2luZl9maWx0LCBtb2RlbF9iYXRjaD0iZnN2YSIpKQpleGNlbF9maWxlIDwtIGdsdWU6OmdsdWUoImV4Y2VsL3tydW5kYXRlfV9scF9pbmZlY3RfZnN2YV9jb250ci12e3Zlcn0ueGxzeCIpCmxwX2NvbWJpbmVkX2ZzdmEgPC0gc20oY29tYmluZV9kZV90YWJsZXMobHBfcGFpcndpc2VfZnN2YSwgZXhjZWw9ZXhjZWxfZmlsZSkpCmV4Y2VsX2ZpbGUgPC0gZ2x1ZTo6Z2x1ZSgiZXhjZWwve3J1bmRhdGV9X2xwX2luZmVjdF9mc3ZhX3NpZy12e3Zlcn0ueGxzeCIpCmxwX3NpZ19mc3ZhIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobHBfY29tYmluZWRfZnN2YSwgZXhjZWw9ZXhjZWxfZmlsZSkpCmBgYAoKYGBge3Igc2F2ZW1lLCBldmFsPUZBTFNFfQpwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQptZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKbWVzc2FnZShwYXN0ZTAoIlNhdmluZyB0byAiLCB0aGlzX3NhdmUpKQp0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lPXRoaXNfc2F2ZSkpCmBgYAoKYGBge3IgcmVsb2FkLCBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpsb2FkbWUoZmlsZW5hbWU9dGhpc19zYXZlKQpgYGAK