1 A version of Kajal’s R markdown document with some more minor changes

1.1 Libraries

In this version of Kajal’s document, I will repeat each step with some changes to see if I can make things a little easier for future modification.

I will therefore leave Kajal’s work unchanged and follow each block with an alternative.

1.4 Create counts table

## Note: importing `abundance.h5` is typically faster than `abundance.tsv`
## reading in files with read_tsv
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 
## transcripts missing from tx2gene: 14613
## summarizing abundance
## summarizing counts
## summarizing length
## [1] 34431

This is a potentially important difference in how I and Kajal treated the data. This is because I created the expressionset without using ‘lengthScaledTPM’, but let tximport use the raw counts so that the various normalizations are not affected. E.g. using these scaled numbers results in less variance in the data and may lead to some confusion for the downstream tools (edger/limma/deseq/etc). On the other hand, it may lead to cleaner plots, I am not sure.

1.5 Create DESeqDataSet

Not sure what this is actually doing

## Warning in DESeqDataSet(se, design = design, ignoreRank): some variables in
## design formula are characters, converting to factors
## using just counts from tximport
## [1] 34431

1.6 My version of the above

## The biomart annotations file already exists, loading from it.
## Reading the sample metadata.
## The sample definitions comprises: 39 rows(samples) and 8 columns(metadata fields).
## Reading count tables.
## Using the transcript to gene mapping.
## Reading kallisto data with tximport.
## Finished reading count data.
## Matched 34431 annotations and counts.
## Bringing together the count matrix and gene information.
## The mapped IDs are not the rownames of your gene information, changing them now.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 34431 rows and 39 columns.
## Using a subset expression.
## There were 39, now there are 30 samples.

1.8 My Barplot of counts

##    condition      min      1st   median     mean      3rd      max
## 1:        NS 14327794 16797487 17086171 18433743 17427077 25536756
## 2:       LPS 14788518 17005543 18507594 19201561 20567000 26005826
## 3:        LA 16014957 18662352 19800400 21804785 23207183 35215275
## 4:        LP 15864738 17917203 19813259 20710341 22113833 28681140

1.12 Median Pairwise Correlation

## Performing correlation.

## Performing correlation.

1.13 PCA

##   propVar cumPropVar cond.R2 batch.R2
## 1   28.82      28.82   69.66    25.21
## 2   13.93      42.75   41.92    44.39
## 3   10.96      53.71   73.10    18.68
## 4    7.39      61.10    9.06    75.08
## 5    5.80      66.90    5.43    78.47
##   propVar cumPropVar cond.R2 batch.R2
## 1   28.82      28.82   69.66    30.95
## 2   13.93      42.75   41.92    46.07
## 3   10.96      53.71   73.10    20.98
## 4    7.39      61.10    9.06    80.68
## 5    5.80      66.90    5.43    91.16
##   propVar cumPropVar cond.R2 batch.R2
## 1   19.48      19.48   63.12    32.88
## 2   11.01      30.49   26.93    54.19
## 3    6.91      37.40    1.42    70.89
## 4    5.79      43.19    2.32    70.10
## 5    5.08      48.27    4.32    81.90
##   propVar cumPropVar cond.R2 batch.R2
## 1   19.48      19.48   63.12    35.52
## 2   11.01      30.49   26.93    53.86
## 3    6.91      37.40    1.42    88.21
## 4    5.79      43.19    2.32    94.87
## 5    5.08      48.27    4.32    82.44

1.14 Euclidian Distance Heat Map

1.15 Plot PC1 v PC2

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

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

1.16 Correct for Patient in Limma model

##   propVar cumPropVar cond.R2 batch.R2
## 1   36.04      36.04   95.47     5.38
## 2   17.81      53.85   91.87     6.83
## 3    8.05      61.90   29.00    25.52
## 4    5.39      67.29   78.12    21.01
## 5    3.06      70.35    9.63     8.75
##   propVar cumPropVar cond.R2 batch.R2
## 1   36.04      36.04   95.47        0
## 2   17.81      53.85   91.87        0
## 3    8.05      61.90   29.00        0
## 4    5.39      67.29   78.12        0
## 5    3.06      70.35    9.63        0
## [1] 34431    30
##   propVar cumPropVar cond.R2 batch.R2
## 1   23.26      23.26   95.02    13.72
## 2    8.03      31.29   18.28    26.78
## 3    6.01      37.30   81.15    22.10
## 4    4.60      41.90   13.36     4.61
## 5    4.35      46.25    6.15    28.65
##   propVar cumPropVar cond.R2 batch.R2
## 1   23.26      23.26   95.02        0
## 2    8.03      31.29   18.28        0
## 3    6.01      37.30   81.15        0
## 4    4.60      41.90   13.36        0
## 5    4.35      46.25    6.15        0

1.17 Plot PC1 and PC2 with patient correction

1.21 M_LPS v M_NS

eBayes finds an F-statistic from the set of t-statistics for that gene

Limit list to genes with an adjusted p value < 0.05

## [1] 4840

Filter out rows with less than 2-fold change (log2 fold change of > 1)

## [1] 1350

Filter out rows with less than 4-fold change (log2 fold change of > 2)

## [1] 431

Make an MA plot

Annotate sigGenes list using Biomart

## Cache found

1.22 M_LPS v M_LA

## [1] 955
## [1] 256
## [1] 57

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.23 M_LPS v M_LP

## [1] 1993
## [1] 489
## [1] 91

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.24 M_LP v M_NS

## [1] 4603
## [1] 1422
## [1] 448

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.25 M_LA v M_NS

## [1] 4922
## [1] 1493
## [1] 478

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.26 GM_LPS v. GM_NS

## [1] 653
## [1] 260
## [1] 99

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.27 GM_LPS v GM_LP

This contrast was written in the opposite order as the others, I think this is the reason some of my plots keep looking backwards/upsidedown… I am going to comment out the original line and rewrite it so that it is identical in order to what I found in: M_LP.M_LP.contr.mat.

## [1] 350
## [1] 126
## [1] 28

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.28 GM_LPS v GM_LA

I think I observe the same flipping here.

## [1] 12
## [1] 7
## [1] 1

## pdf 
##   3
## png 
##   2
## png 
##   3
## png 
##   2
## Cache found

1.29 Barplots of Fold-Changes, e.g. Figure 3C/D

It appears to me that these figures are created by merging the M/GM tables for the LP-LPS and LA-LPS contrasts, taking the top ~20 for the M table, and plotting the log2FC on the linear scale. I believe I can trivially modify this to add the logFC / t-stat. The caveat will be that doing this gives me a log2 error bar, not linear… My inclination therefore is to just plot the logFC rather than convert it to linear, but whatever.

1.29.2 Figure 3C top-left

Kajal’s variables to create this are…

  1. M_LPS.M_LP.topTab
  2. GM_LPS.GM_LP.topTab

These were passed to biomart to get the gene names rather than ensembl IDs. I am going to be lazy and just copy/paste Kajal’s code for these tasks.

Having done the top-left piece of this, it seems to me that if you are going to take the top 20 genes and exclude based on the M-CSF adjusted p-value, perhaps you should also exclude based on the GM-CSF adjusted p-value, but the way this was done, only the M is used. In its current state, I am only using the M as per the figures in their current state.

Note, that if you want error bars from the standard error, then it is waaaay easier to stay on the log2 scale rather than convert back to linear because the math for converting the standard error back to linear is weird. If the table had a few more parameters in it, I could do it without struggling, but it doesn’t.

## Cache found
colnames(desc) <- c("ID", "Symbol", "Description", "Type")
fig3c_lp_df <- merge(fig3c_lp_df, desc, by="ID", all.x=TRUE)

tl_order_idx <- order(fig3c_lp_df[["logFC.x"]], decreasing=TRUE)
fig3c_tl_df <- fig3c_lp_df[tl_order_idx, ]
sig_idx <- fig3c_tl_df[["adj.P.Val.x"]] <= 0.05
fig3c_tl_df <- head(fig3c_tl_df[sig_idx, ], n=25)
fig3c_tl_df <- fig3c_tl_df[, wanted_columns]
colnames(fig3c_tl_df) <- renamed_columns
rownames(fig3c_tl_df) <- fig3c_tl_df[["ID"]]
fig3c_tl_df[["ID"]] <- NULL
fig3c_tl_df[["m_lfcerr"]] <- fig3c_tl_df[["m_logfc"]] / fig3c_tl_df[["m_t"]]
fig3c_tl_df[["gm_lfcerr"]] <- fig3c_tl_df[["gm_logfc"]] / fig3c_tl_df[["gm_t"]]

fig3c_tl_m <- fig3c_tl_df[, c("m_logfc", "symbol", "m_lfcerr")]
fig3c_tl_m[["type"]] <- "m"
colnames(fig3c_tl_m) <- c("logfc", "symbol", "lfcerr", "type")
fig3c_tl_gm <- fig3c_tl_df[, c("gm_logfc", "symbol", "gm_lfcerr")]
fig3c_tl_gm[["type"]] <- "gm"
colnames(fig3c_tl_gm) <- c("logfc", "symbol", "lfcerr", "type")
melted_fig3c_tl <- rbind(fig3c_tl_m, fig3c_tl_gm)
melted_fig3c_tl[["symbol"]] <- factor(melted_fig3c_tl[["symbol"]],
                                      levels=fig3c_tl_m[["symbol"]])
melted_fig3c_tl[["type"]] <- factor(melted_fig3c_tl[["type"]],
                                    levels=c("m", "gm"))

p <- ggplot(data=melted_fig3c_tl, aes(x=symbol, y=logfc, fill=type)) +
  geom_bar(stat="identity", color="black", position=position_dodge())+
  scale_fill_manual(values=c("cornflowerblue", "darkgrey")) +
  geom_errorbar(aes(ymin=logfc - (lfcerr / 2), ymax=logfc + (lfcerr / 2)), width=.2,
                position=position_dodge(0.9)) +
  theme_minimal() +
  theme(axis.text.x=element_text(angle=45, hjust=1, vjust=0.5))
p

##            Symbol   P.Value adj.P.Val
## LYPD3       LYPD3 5.612e-02  0.622381
## ACKR3       ACKR3 3.963e-02  0.553822
## AREG         AREG 3.531e-02  0.529726
## KBTBD11   KBTBD11 2.706e-07  0.001740
## IGLON5     IGLON5 2.474e-04  0.067686
## CXCR4       CXCR4 3.205e-06  0.006153
## LIPN         LIPN 4.199e-02  0.562948
## GNG4         GNG4 7.213e-02  0.672602
## DUSP4       DUSP4 9.261e-01  0.998546
## ALPK2       ALPK2 9.460e-01  0.998546
## THBS1       THBS1 9.879e-01  0.999432
## KRT17       KRT17 9.604e-01  0.998546
## CD300E     CD300E 3.864e-01  0.949738
## HAS1         HAS1 9.206e-02  0.723115
## NR4A2       NR4A2 2.170e-02  0.441905
## CMSS1       CMSS1 9.074e-04  0.115520
## ADAMTS17 ADAMTS17 3.629e-01  0.942674
## CRLF2       CRLF2 9.997e-01  0.999882
## ZNF331     ZNF331 9.113e-05  0.043085
## FFAR3       FFAR3 2.981e-01  0.926399
## RGS2         RGS2 8.436e-01  0.998041
## CREM         CREM 1.370e-01  0.799699
## ABHD17C   ABHD17C 1.694e-02  0.408765
## THAP2       THAP2 6.660e-02  0.651783
## SLC16A10 SLC16A10 5.415e-03  0.260782

1.29.3 Figure 3C bottom-left

##          Symbol   P.Value adj.P.Val
## IL12B     IL12B 1.029e-04  0.043085
## CCL3L1   CCL3L1 1.685e-03  0.147786
## CCL3L3   CCL3L3 1.685e-03  0.147786
## CCL8       CCL8 2.933e-02  0.492300
## TIFAB     TIFAB 1.334e-03  0.138546
## CCL4L2   CCL4L2 1.543e-05  0.018032
## CCL2       CCL2 1.434e-02  0.388755
## IL36G     IL36G 1.229e-02  0.359328
## TNF         TNF 3.561e-04  0.080319
## CCL15     CCL15 1.284e-03  0.137488
## P2RX7     P2RX7 1.745e-03  0.149671
## CCL3       CCL3 2.702e-05  0.024818
## CCL1       CCL1 1.894e-02  0.427142
## ZACN       ZACN 1.614e-03  0.146148
## CISH       CISH 1.314e-04  0.049681
## RGS16     RGS16 2.319e-03  0.175535
## CCL4       CCL4 2.820e-03  0.194541
## F3           F3 1.874e-04  0.066918
## IL27       IL27 8.285e-03  0.304500
## ANKRD22 ANKRD22 2.656e-06  0.006153

1.29.4 Figure 3C top-right

The right side of the plot is LA rather than LP, otherwise this is the same.

## Cache found
colnames(desc) <- c("ID", "Symbol", "Description", "Type")
fig3c_la_df <- merge(fig3c_la_df, desc, by="ID", all.x=TRUE)

tr_order_idx <- order(fig3c_la_df[["logFC.x"]], decreasing=TRUE)
fig3c_tr_df <- fig3c_la_df[tr_order_idx, ]
sig_idx <- fig3c_tr_df[["adj.P.Val.x"]] <= 0.05
fig3c_tr_df <- head(fig3c_tr_df[sig_idx, ], n=25)
fig3c_tr_df <- fig3c_tr_df[, wanted_columns]
colnames(fig3c_tr_df) <- renamed_columns
rownames(fig3c_tr_df) <- fig3c_tr_df[["ID"]]
fig3c_tr_df[["ID"]] <- NULL
fig3c_tr_df[["m_lfcerr"]] <- fig3c_tr_df[["m_logfc"]] / fig3c_tr_df[["m_t"]]
fig3c_tr_df[["gm_lfcerr"]] <- fig3c_tr_df[["gm_logfc"]] / fig3c_tr_df[["gm_t"]]

fig3c_tr_m <- fig3c_tr_df[, c("m_logfc", "symbol", "m_lfcerr")]
fig3c_tr_m[["type"]] <- "m"
colnames(fig3c_tr_m) <- c("logfc", "symbol", "lfcerr", "type")
fig3c_tr_gm <- fig3c_tr_df[, c("gm_logfc", "symbol", "gm_lfcerr")]
fig3c_tr_gm[["type"]] <- "gm"
colnames(fig3c_tr_gm) <- c("logfc", "symbol", "lfcerr", "type")
melted_fig3c_tr <- rbind(fig3c_tr_m, fig3c_tr_gm)
melted_fig3c_tr[["symbol"]] <- factor(melted_fig3c_tr[["symbol"]],
                                      levels=fig3c_tr_m[["symbol"]])
melted_fig3c_tr[["type"]] <- factor(melted_fig3c_tr[["type"]],
                                    levels=c("m", "gm"))

p <- ggplot(data=melted_fig3c_tr, aes(x=symbol, y=logfc, fill=type)) +
  geom_bar(stat="identity", color="black", position=position_dodge())+
  scale_fill_manual(values=c("cornflowerblue", "darkgrey")) +
  geom_errorbar(aes(ymin=logfc-lfcerr, ymax=logfc+lfcerr), width=.2,
                position=position_dodge(0.9)) +
  theme_minimal() +
  theme(axis.text.x=element_text(angle=45, hjust=1, vjust=0.5))
p

##            Symbol   P.Value adj.P.Val
## LYPD3       LYPD3 5.624e-03   0.45401
## IGLON5     IGLON5 5.678e-05   0.09926
## LIPN         LIPN 6.852e-03   0.47369
## KRT17       KRT17 5.861e-01   0.99598
## ADAMTS17 ADAMTS17 1.844e-01   0.99433
## KBTBD11   KBTBD11 6.888e-06   0.04428
## CMSS1       CMSS1 1.561e-04   0.13098
## CREM         CREM 4.686e-04   0.15856
## MYO5C       MYO5C 9.445e-03   0.53818
## GPR3         GPR3 9.244e-02   0.92149
## GNG4         GNG4 2.665e-01   0.99433
## THAP2       THAP2 6.334e-03   0.46871
## SV2B         SV2B 3.161e-01   0.99433
## CASP9       CASP9 3.884e-04   0.14458
## SGIP1       SGIP1 4.732e-02   0.82196
## COBL         COBL 5.187e-03   0.44874
## TGFA         TGFA 4.926e-02   0.82814
## AREG         AREG 9.583e-02   0.92296
## CXCR4       CXCR4 1.016e-04   0.11555
## TGFB2       TGFB2 1.503e-01   0.99433
## ALPK2       ALPK2 2.187e-01   0.99433
## RBKS         RBKS 1.971e-01   0.99433
## MYOM2       MYOM2 4.319e-04   0.15009
## AKAP12     AKAP12 1.345e-02   0.58700
## BEX1         BEX1 8.732e-02   0.91475

1.29.5 Figure 3C bottom-right

##            Symbol   P.Value adj.P.Val
## IL12B       IL12B 6.948e-05   0.09926
## CCL3L1     CCL3L1 1.038e-03   0.24713
## CCL3L3     CCL3L3 1.038e-03   0.24713
## CCL8         CCL8 9.417e-04   0.23733
## CCL1         CCL1 1.647e-02   0.63204
## TIFAB       TIFAB 3.711e-03   0.41853
## CSF2         CSF2 4.480e-03   0.44388
## UNC13A     UNC13A 1.836e-02   0.65262
## IL6           IL6 2.380e-02   0.70136
## CCL4L2     CCL4L2 1.147e-03   0.24991
## CMKLR1     CMKLR1 1.508e-03   0.29448
## SERPINE1 SERPINE1 1.581e-02   0.62443
## KCNA3       KCNA3 2.625e-03   0.38893
## CCL2         CCL2 2.135e-02   0.67555
## F3             F3 1.078e-04   0.11555
## CCL15       CCL15 5.612e-04   0.18039
## CFAP46     CFAP46 1.137e-02   0.56691
## CASS4       CASS4 1.121e-02   0.56691
## OCSTAMP   OCSTAMP 7.040e-04   0.19903
## GP1BA       GP1BA 1.109e-02   0.56575

1.29.6 Figure 2A

Kajal responded to my query about this figure, and I am a little embarrassed to say that I should have seen what it is. It seems to me that it is a bit redundant though with 3c, as it is precisely a subset of that data, though slightly reordered.

1.29.7 Figure 2D

I created a table of shared DEG between L+PGE2/LPS and L+Ado/LPS (table attached below) by merging the 2 DE tables based on common gene symbol. In this table, logFC.x corresponds to L+Ado/LPS and logFC.y corresponds to L+PGE2/LPS. I averaged the fold changes between logFC.x and logFC.y in order to determine the rank order of the genes in the figure but plotted the fold changes individually. Instead of plotting log2FC I manually converted those values to just FC. I don’t know how to calculate standard error if I am plotting just FC. It would be nice if this could all be done in R.

2 M_LPS v M_LP

##                ID logFC AveExpr     t   P.Value adj.P.Val     B
## 1 ENSG00000121966 4.167   5.148 13.64 9.189e-15 1.182e-10 23.50
## 2 ENSG00000182568 2.467   3.922 13.00 3.316e-14 2.132e-10 22.23
## 3 ENSG00000176595 4.467   1.729 11.43 9.698e-13 4.157e-09 18.60
## 4 ENSG00000198814 2.443   6.435 11.18 1.695e-12 4.986e-09 18.53
## 5 ENSG00000112394 2.502   5.836 10.96 2.791e-12 5.982e-09 18.04
## 6 ENSG00000109321 4.500   1.516 11.12 1.939e-12 4.986e-09 17.86

## png 
##   3
## png 
##   2

2.1 Rich Factor Graphs

2.2 GO terms shared LA LP

3 Volcano plot M_LPS_4 v M_LP_4

3.1 Figure 3B top-left

##                ID logFC AveExpr     t   P.Value adj.P.Val     B
## 1 ENSG00000121966 4.167   5.148 13.64 9.189e-15 1.182e-10 23.50
## 2 ENSG00000182568 2.467   3.922 13.00 3.316e-14 2.132e-10 22.23
## 3 ENSG00000176595 4.467   1.729 11.43 9.698e-13 4.157e-09 18.60
## 4 ENSG00000198814 2.443   6.435 11.18 1.695e-12 4.986e-09 18.53
## 5 ENSG00000112394 2.502   5.836 10.96 2.791e-12 5.982e-09 18.04
## 6 ENSG00000109321 4.500   1.516 11.12 1.939e-12 4.986e-09 17.86

## png 
##   3
## png 
##   2

3.1.1 The number of up significant genes

## [1] 232
## [1] "ENSG00000121966" "ENSG00000182568" "ENSG00000176595" "ENSG00000198814"
## [5] "ENSG00000112394" "ENSG00000109321"

3.1.2 The number of down significant genes

## [1] 257
## [1] "ENSG00000166068" "ENSG00000089041" "ENSG00000140968" "ENSG00000196449"
## [5] "ENSG00000181915" "ENSG00000104549"

4 Volcano plot M_LPS_4 v M_LA_4

4.1 Figure 3B top-right

##                ID  logFC AveExpr      t   P.Value adj.P.Val     B
## 1 ENSG00000139112  1.346   6.583 11.281 1.346e-12 1.730e-08 18.74
## 2 ENSG00000095794  2.802   6.009 10.697 5.130e-12 3.298e-08 17.42
## 3 ENSG00000132906  2.466   4.467  9.520 8.693e-11 2.235e-07 14.62
## 4 ENSG00000124466  5.662   1.526  9.775 4.642e-11 1.492e-07 14.59
## 5 ENSG00000163235  2.390   4.942  9.241 1.745e-10 3.739e-07 13.98
## 6 ENSG00000068305 -1.155   6.819 -9.117 2.391e-10 4.392e-07 13.67

## png 
##   3
## png 
##   2

4.1.1 The number of up significant genes

## [1] 128
## [1] "ENSG00000139112" "ENSG00000095794" "ENSG00000132906" "ENSG00000124466"
## [5] "ENSG00000163235" "ENSG00000164674"

4.1.2 The number of down significant genes

## [1] 128
## [1] "ENSG00000068305" "ENSG00000140968" "ENSG00000125657" "ENSG00000089041"
## [5] "ENSG00000149635" "ENSG00000117525"

5 Volcano plot GM_LPS_4 v GM_LA_4

5.1 Figure 3B bottom-right

##                ID   logFC AveExpr      t   P.Value adj.P.Val     B
## 1 ENSG00000163235  1.6278  4.9419  6.048 1.005e-06  0.006463 5.477
## 2 ENSG00000099625  1.9849  0.7463  6.726 1.459e-07  0.001876 4.817
## 3 ENSG00000108702 -1.4830  2.3455 -5.497 4.914e-06  0.021061 4.032
## 4 ENSG00000095794  1.3592  6.0086  5.201 1.155e-05  0.026752 3.310
## 5 ENSG00000071205 -0.6386  5.8815 -5.174 1.248e-05  0.026752 3.245
## 6 ENSG00000166886 -1.0612  4.2945 -5.092 1.584e-05  0.029088 2.971

## png 
##   3
## png 
##   2

5.1.1 The number of up significant genes

## [1] 5
## [1] "ENSG00000163235" "ENSG00000099625" "ENSG00000095794" "ENSG00000197555"
## [5] "ENSG00000128422"

5.1.2 The number of down significant genes

## [1] 2
## [1] "ENSG00000108702" "ENSG00000166886"

6 Volcano plot GM_LPS_4 v GM_LP_4

6.1 Figure 3B bottom-left

So, it appears I get the inverse of what is in the figure. Did the contrast get reversed?

I went back to the section which defines this, it has the heading ‘GM_LPS_v_GM_LP’ and the contrast appears to me to be correct. At least it is written like this:

GM_LPS.GM_LP.contr.mat <- makeContrasts(GM_LPSvGM_LP=((condGM_LPS-condGM_NS)-(condGM_LP-condGM_NS)), levels=v$design)

My inclination is therefore that this got flipped?

##                ID logFC AveExpr     t   P.Value adj.P.Val      B
## 1 ENSG00000163235 2.244  4.9419 8.405 1.501e-09 1.609e-05 11.866
## 2 ENSG00000095794 2.099  6.0086 8.059 3.753e-09 1.609e-05 10.995
## 3 ENSG00000099625 2.359  0.7463 8.098 3.377e-09 1.609e-05  9.933
## 4 ENSG00000120875 3.357  4.0494 7.671 1.065e-08 3.425e-05  9.931
## 5 ENSG00000188042 2.337  5.0272 6.987 7.011e-08 1.663e-04  8.154
## 6 ENSG00000197872 1.919  5.9633 6.909 8.739e-08 1.663e-04  7.939

## png 
##   3
## png 
##   2

6.1.1 The number of up significant genes

## [1] 104
## [1] "ENSG00000163235" "ENSG00000095794" "ENSG00000099625" "ENSG00000120875"
## [5] "ENSG00000188042" "ENSG00000197872"

6.1.2 The number of down significant genes

## [1] 22
## [1] "ENSG00000089041" "ENSG00000108702" "ENSG00000136997" "ENSG00000105810"
## [5] "ENSG00000181856" "ENSG00000244398"

6.1.3 Figure 2B

I think the code I used for the venn diagrams is in the Rmarkdown file towards the end. However, I have 2 files saved for the venn diagrams that are different from what I have in figure 2B. I think I need to swap the current 2B with the venn diagrams I have attached below because the numbers here match with the volcano plots. Are these the numbers you are getting also?

6.1.3.3 Correlation of logFCs for LP/LPS and LA/LPS

One request in our conversation was to have a calculation of the correlation coefficient between the LP/LPS and LA/LPS comparisons.

## 
##  Pearson's product-moment correlation
## 
## data:  m_cor_table[["logFC.x"]] and m_cor_table[["logFC.y"]]
## t = 138, df = 12856, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7646 0.7786
## sample estimates:
##    cor 
## 0.7717
## 
##  Pearson's product-moment correlation
## 
## data:  gm_cor_table[["logFC.x"]] and gm_cor_table[["logFC.y"]]
## t = 74, df = 12856, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.5368 0.5610
## sample estimates:
##   cor 
## 0.549

LS0tCnRpdGxlOiAiSHVtYW4gTWFjcm9waGFnZXM6IE0tQ1NGIHYgR00tQ1NGOiBMUFMsIExQUytBZGVub3NpbmUsIExQUytQR0UyIgphdXRob3I6ICJLYWphbCBIYW1pZHphZGVoIGFuZCBhdGIiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCiAgICAgIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOgogICAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgICAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgICAgICBkZl9wcmludDogcGFnZWQKICAgICAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgICAgIGZpZ19oZWlnaHQ6IDcKICAgICAgICBmaWdfd2lkdGg6IDcKICAgICAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICAgICAgd2lkdGg6IDMwMAogICAgICAgIGtlZXBfbWQ6IGZhbHNlCiAgICAgICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgICAgIHRvY19mbG9hdDogdHJ1ZQogICAgICAgIEJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudDoKICAgICAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgICAgICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgICAgICAgZmlnX2NhcHRpb246IHRydWUKICAgICAgICAgIGZpZ19oZWlnaHQ6IDcKICAgICAgICAgIGZpZ193aWR0aDogNwogICAgICAgICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgICAgICAga2VlcF9tZDogZmFsc2UKICAgICAgICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogIGZvbnQtc2l6ZTogMTZweAp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KCJocGdsdG9vbHMiKQp0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIi9kYXRhL2hwZ2x0b29scyIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHdpZHRoPTEyMCwKICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZT1UUlVFLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQ9IiVZJW0lZCIpCnByZXZpb3VzX2ZpbGUgPC0gIiIKdmVyIDwtICIyMDIwMDMzMCIKCiMjIHRtcCA8LSBzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkKIyMgcm1kX2ZpbGUgPC0gIjAzX2V4cHJlc3Npb25faW5mZWN0aW9uXzIwMTgwODIyLlJtZCIKYGBgCgojIEEgdmVyc2lvbiBvZiBLYWphbCdzIFIgbWFya2Rvd24gZG9jdW1lbnQgd2l0aCBzb21lIG1vcmUgbWlub3IgY2hhbmdlcwoKIyMgTGlicmFyaWVzCgpgYGB7ciBsaWJyYXJpZXMsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZGV2dG9vbHMpCmxpYnJhcnkodHhpbXBvcnQpCmxpYnJhcnkoYmlvbWFSdCkKbGlicmFyeShocGdsdG9vbHMpCmxpYnJhcnkoREVTZXEyKQpsaWJyYXJ5KGdwbG90cykKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNiY2JTRVEpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KFZlbm5lcmFibGUpCmxpYnJhcnkoZWRnZVIpCmxpYnJhcnkoY2FsaWJyYXRlKQpsaWJyYXJ5KHNjYWxlcykKYGBgCgpJbiB0aGlzIHZlcnNpb24gb2YgS2FqYWwncyBkb2N1bWVudCwgSSB3aWxsIHJlcGVhdCBlYWNoIHN0ZXAgd2l0aCBzb21lIGNoYW5nZXMKdG8gc2VlIGlmIEkgY2FuIG1ha2UgdGhpbmdzIGEgbGl0dGxlIGVhc2llciBmb3IgZnV0dXJlIG1vZGlmaWNhdGlvbi4KCkkgd2lsbCB0aGVyZWZvcmUgbGVhdmUgS2FqYWwncyB3b3JrIHVuY2hhbmdlZCBhbmQgZm9sbG93IGVhY2ggYmxvY2sgd2l0aCBhbiBhbHRlcm5hdGl2ZS4KCiMjIFNldCB3b3JraW5nIGRpcmVjdG9yeSwgaW1wb3J0IG1ldGFkYXRhIGFuZCBhYnVuZGFuY2UgZmlsZXMKCmBgYHtyIHJlYWRfZGF0YX0KZGVzaWduIDwtIHJlYWQudGFibGUoInNhbXBsZV9zaGVldHMvTWV0YURhdGEgb25seSA0IGhvdXIudHh0IiwgaGVhZGVyPVRSVUUsIHNlcD0iXHQiKQpkZXNpZ25bWyJQYXRpZW50Il1dIDwtIGFzLmZhY3RvcihkZXNpZ25bWyJQYXRpZW50Il1dKQpkZXNpZ25bWyJTdGltdWxhdGlvbiJdXSA8LSBhcy5mYWN0b3IoZGVzaWduW1siU3RpbXVsYXRpb24iXV0pCmRlc2lnbltbIkJhdGNoIl1dIDwtIGFzLmZhY3RvcihkZXNpZ25bWyJCYXRjaCJdXSkKZGVzaWduW1siR3Jvd3RoIl1dIDwtIGFzLmZhY3RvcihkZXNpZ25bWyJHcm93dGgiXV0pCmZpbGVzIDwtIGZpbGUucGF0aCgia2FsbGlzdG8gYWJ1bmRhbmNlIGZpbGVzLyIsIGRlc2lnbiRIUEdMLklkZW50aWZpZXIsICJhYnVuZGFuY2UudHN2IikKbmFtZXMoZmlsZXMpIDwtIHBhc3RlMCgiSFBHTDA5IiwgYygxMjozMSwgNDI6NjApKQpyb3duYW1lcyhkZXNpZ24pIDwtIGRlc2lnbltbMV1dCgpzdGltX2Rlc2lnbl9pZHggPC0gZGVzaWduW1siU3RpbXVsYXRpb24iXV0gIT0gIk5TIgpzdGltX2Rlc2lnbiA8LSBkZXNpZ25bc3RpbV9kZXNpZ25faWR4LCBdCmBgYAoKIyMgQ29udmVydCB0cmFuc2NyaXB0IElEIHRvIGdlbmUgSUQKCmBgYHtyIGVuc2VtYmx9CmVuc2VtYmwgPC0gdXNlTWFydCgiRU5TRU1CTF9NQVJUX0VOU0VNQkwiLCBkYXRhc2V0PSJoc2FwaWVuc19nZW5lX2Vuc2VtYmwiLAogICAgICAgICAgICAgICAgICAgaG9zdD0idXNlYXN0LmVuc2VtYmwub3JnIikKdHgyZ2VuZSA8LSBnZXRCTShhdHRyaWJ1dGVzPWMoImVuc2VtYmxfdHJhbnNjcmlwdF9pZCIsICJlbnNlbWJsX2dlbmVfaWQiLCAiY2hyb21vc29tZV9uYW1lIiksCiAgICAgICAgICAgICAgICAgbWFydD1lbnNlbWJsKQpnb29kX2lkeCA8LSBncmVwbCh4PXR4MmdlbmVbWyJjaHJvbW9zb21lX25hbWUiXV0sIHBhdHRlcm49Il5bWzphbG51bTpdXXsxLDJ9JCIpCmdvb2Rfb25lcyA8LSB0eDJnZW5lW2dvb2RfaWR4LCAtM10KYGBgCgojIyBDcmVhdGUgY291bnRzIHRhYmxlCgpgYGB7cn0KdHhpLmthbGxpc3RvLnRzdiA8LSB0eGltcG9ydChmaWxlcywgdHlwZT0ia2FsbGlzdG8iLCB0eDJnZW5lPWdvb2Rfb25lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudHNGcm9tQWJ1bmRhbmNlPSJsZW5ndGhTY2FsZWRUUE0iKQpucm93KHR4aS5rYWxsaXN0by50c3YkY291bnRzKQoKd3JpdGUudGFibGUodHhpLmthbGxpc3RvLnRzdiRjb3VudHMsICJUUE1fTXZHTV9DRFNfMjAxODA3MTEudHh0IiwKICAgICAgICAgICAgY29sLm5hbWVzPVRSVUUsIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCndyaXRlLmNzdih0eGkua2FsbGlzdG8udHN2JGNvdW50cywgImNzdi9UUE1fTXZHTV8yMDE4MDcxMS5jc3YiLAogICAgICAgICAgcm93Lm5hbWVzPVRSVUUsIHF1b3RlPUZBTFNFKQoKc3RpbV9jb3VudHMgPC0gdHhpLmthbGxpc3RvLnRzdiRjb3VudHMKc3RpbV9jb3VudHNfaWR4IDwtIGNvbG5hbWVzKHN0aW1fY291bnRzKSAlaW4lIHJvd25hbWVzKHN0aW1fZGVzaWduKQpzdGltX2NvdW50cyA8LSBzdGltX2NvdW50c1ssIHN0aW1fY291bnRzX2lkeF0KYGBgCgpUaGlzIGlzIGEgcG90ZW50aWFsbHkgaW1wb3J0YW50IGRpZmZlcmVuY2UgaW4gaG93IEkgYW5kIEthamFsIHRyZWF0ZWQgdGhlIGRhdGEuClRoaXMgaXMgYmVjYXVzZSBJIGNyZWF0ZWQgdGhlIGV4cHJlc3Npb25zZXQgd2l0aG91dCB1c2luZyAnbGVuZ3RoU2NhbGVkVFBNJywKYnV0IGxldCB0eGltcG9ydCB1c2UgdGhlIHJhdyBjb3VudHMgc28gdGhhdCB0aGUgdmFyaW91cyBub3JtYWxpemF0aW9ucyBhcmUgbm90CmFmZmVjdGVkLiAgRS5nLiB1c2luZyB0aGVzZSBzY2FsZWQgbnVtYmVycyByZXN1bHRzIGluIGxlc3MgdmFyaWFuY2UgaW4gdGhlIGRhdGEKYW5kIG1heSBsZWFkIHRvIHNvbWUgY29uZnVzaW9uIGZvciB0aGUgZG93bnN0cmVhbSB0b29scwooZWRnZXIvbGltbWEvZGVzZXEvZXRjKS4gIE9uIHRoZSBvdGhlciBoYW5kLCBpdCBtYXkgbGVhZCB0byBjbGVhbmVyIHBsb3RzLCBJIGFtCm5vdCBzdXJlLgoKIyMgQ3JlYXRlIERFU2VxRGF0YVNldAoKTm90IHN1cmUgd2hhdCB0aGlzIGlzIGFjdHVhbGx5IGRvaW5nCgpgYGB7ciBkZXNlcV9kZHN9CmRmIDwtIGRhdGEuZnJhbWUoY29uZGl0aW9uPXBhc3RlKGRlc2lnbiRIUEdMLklkZW50aWZpZXIsIGRlc2lnbiRHcm93dGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiRTdGltdWxhdGlvbiwgZGVzaWduJFBhdGllbnQsIHNlcD0iXyIpKQpyb3duYW1lcyhkZikgPC0gY29sbmFtZXModHhpLmthbGxpc3RvLnRzdiRjb3VudHMpCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tVHhpbXBvcnQodHhpLmthbGxpc3RvLnRzdiwgZGYsIH5jb25kaXRpb24pCm5yb3coZGRzKQoKZGRzX3N0aW0gPC0gZGRzWywgcm93bmFtZXMoc3RpbV9kZXNpZ24pXQpgYGAKCiMjIE15IHZlcnNpb24gb2YgdGhlIGFib3ZlCgpgYGB7ciBhdGJfcmVhZF9kYXRhfQpteV9kZXNpZ24gPC0gZGVzaWduCnJvd25hbWVzKG15X2Rlc2lnbikgPC0gZGVzaWduW1sxXV0KbXlfZGVzaWduW1siY29uZGl0aW9uIl1dIDwtIG15X2Rlc2lnbltbIlN0aW11bGF0aW9uIl1dCm15X2Rlc2lnbltbImZpbGUiXV0gPC0gZ2x1ZTo6Z2x1ZSgicHJlcHJvY2Vzc2luZy97cm93bmFtZXMobXlfZGVzaWduKX0vYWJ1bmRhbmNlLnRzdiIpCmNvbG5hbWVzKG15X2Rlc2lnbikgPC0gdG9sb3dlcihjb2xuYW1lcyhteV9kZXNpZ24pKQpnZW5lX2luZm8gPC0gbG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKGhvc3Q9InVzZWFzdC5lbnNlbWJsLm9yZyIpJGFubm90YXRpb24Kcm93bmFtZXMoZ2VuZV9pbmZvKSA8LSBtYWtlLm5hbWVzKGdlbmVfaW5mb1tbImVuc2VtYmxfZ2VuZV9pZCJdXSwgdW5pcXVlPVRSVUUpCnR4X2dlbmVfbWFwIDwtIGdlbmVfaW5mb1ssIGMoImVuc2VtYmxfdHJhbnNjcmlwdF9pZCIsICJlbnNlbWJsX2dlbmVfaWQiKV0KaHNfZXhwdCA8LSBjcmVhdGVfZXhwdChtZXRhZGF0YT1teV9kZXNpZ24sIGdlbmVfaW5mbz1nZW5lX2luZm8sIHR4X2dlbmVfbWFwPXR4X2dlbmVfbWFwKQpoc19leHB0IDwtIHNldF9leHB0X2JhdGNoZXMoaHNfZXhwdCwgZmFjdD0iZ3Jvd3RoIikKCnN0aW1fZXhwdCA8LSBzdWJzZXRfZXhwdChoc19leHB0LCBzdWJzZXQ9InN0aW11bGF0aW9uIT0nTlMnIikKYGBgCgojIyBCYXIgUGxvdCBvZiBDb3VudHMKCmBgYHtyIGJhcnBsb3R9CnBhcihtYXI9YygxMCwgNC41LCAzLjUsIDEpKQpwYXIob21hPWMoMCwgMCwgMCwgMCkpCmJhcnBsb3QoY29sU3Vtcyh0eGkua2FsbGlzdG8udHN2JGNvdW50cyksIGxhcz0zLCBtYWluPSJSYXcgQ291bnRzIEJ5IFNhbXBsZSIpCmJhcnBsb3QoY29sU3VtcyhzdGltX2NvdW50cyksIGxhcz0zLCBtYWluPSJSYXcgQ291bnRzIEJ5IFNhbXBsZSIpCmBgYAoKIyMgTXkgQmFycGxvdCBvZiBjb3VudHMKCmBgYHtyIG15X2JhcnBsb3R9CmxpYnNpemUgPC0gcGxvdF9saWJzaXplKGhzX2V4cHQpCmxpYnNpemUkcGxvdApsaWJzaXplJHN1bW1hcnkKCnBsb3RfbGlic2l6ZShzdGltX2V4cHQpJHBsb3QKYGBgCgojIyBCb3ggUGxvdCBvZiBDb3VudHMKCmBgYHtyIGNvdW50X2JhcnBsb3R9CmRkcyA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkcykKbmN0cyA8LSBjb3VudHMoZGRzLCBub3JtYWxpemVkPVRSVUUpCnkgPC0gbG9nKG5jdHMgKyAxKQoKcGFyKG1hcj1jKDUsIDUsIDIsIDEpKQpwYXIob21hPWMoMCwgMCwgMCwgMCkpCmJveHBsb3QoeSwgbmFtZXM9Y29sbmFtZXModHhpLmthbGxpc3RvLnRzdiRjb3VudHMpLAogICAgICAgIGxhcz0zLCBtYWluPSJQZXIgU2FtcGxlIExvZyBvZiBTaXplLWZhY3RvciBDb3VudHMiKQoKZGRzX3N0aW0gPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHNfc3RpbSkKc3RpbV9uY3RzIDwtIGNvdW50cyhkZHNfc3RpbSwgbm9ybWFsaXplZD1UUlVFKQpzdGltX3kgPC0gbG9nKHN0aW1fbmN0cyArIDEpCgpwYXIobWFyPWMoNSwgNSwgMiwgMSkpCnBhcihvbWE9YygwLCAwLCAwLCAwKSkKYm94cGxvdChzdGltX3ksIG5hbWVzPWNvbG5hbWVzKHN0aW1fY291bnRzKSwgbGFzPTMsCiAgICAgICAgbWFpbj0iUGVyIFNhbXBsZSBMb2cgb2YgU2l6ZS1mYWN0b3IgQ291bnRzIikKYGBgCgpgYGB7ciBteV9ib3hwbG90fQpib3hwbG90IDwtIHBsb3RfYm94cGxvdChoc19leHB0KQpib3hwbG90CmBgYAoKIyMgSGVhdG1hcCBvZiBQZWFyc29uIENvcnJlbGF0aW9uCgpgYGB7ciBjb3JoZWF0fQpkYXRDb3IgPC0gY29yKHR4aS5rYWxsaXN0by50c3YkY291bnRzKQpoZWF0bWFwLjIoZGF0Q29yLCBSb3d2PU5BLCBDb2x2PU5BLCBtYXJnaW5zPWMoMTAsIDEwKSwKICAgICAgICAgIGxhYlJvdz1kZiRjb25kaXRpb24sIGxhYkNvbD1kZiRjb25kaXRpb24sCiAgICAgICAgICBkZW5kcm9ncmFtPSJub25lIiwgc2NhbGU9Im5vbmUiLCB0cmFjZT0ibm9uZSIsCiAgICAgICAgICBzcnRDb2w9NDUsIG1haW49IlBlYXJzb24gQ29ycmVsYXRpb24iKQoKc3RpbV9kYXRDb3IgPC0gY29yKHN0aW1fY291bnRzKQpoZWF0bWFwLjIoc3RpbV9kYXRDb3IsIFJvd3Y9TkEsIENvbHY9TkEsIG1hcmdpbnM9YygxMCwgMTApLAogICAgICAgICAgbGFiUm93PWRmJGNvbmRpdGlvbiwgbGFiQ29sPWRmJGNvbmRpdGlvbiwKICAgICAgICAgIGRlbmRyb2dyYW09Im5vbmUiLCBzY2FsZT0ibm9uZSIsIHRyYWNlPSJub25lIiwKICAgICAgICAgIHNydENvbD00NSwgbWFpbj0iUGVhcnNvbiBDb3JyZWxhdGlvbiIpCmBgYAoKYGBge3IgbXlfY29yaGVhdH0KcGxvdF9jb3JoZWF0KGhzX2V4cHQpJHBsb3QKcGxvdF9jb3JoZWF0KHN0aW1fZXhwdCkkcGxvdApgYGAKCiMjIEZpbHRlciBhbmQgTm9ybWFsaXplIENvdW50cwoKYGBge3J9CmZpbHRlckNvdW50cyA8LSBmdW5jdGlvbiAoY291bnRzLCBsaWIuc2l6ZT1OVUxMLCB0aHJlc2g9MSwgbWluU2FtcGxlcz0yKSB7CiAgY3BtcyA8LSAyIF4gbG9nMkNQTShjb3VudHMsIGxpYi5zaXplID0gbGliLnNpemUpJHkKICBrZWVwIDwtIHJvd1N1bXMoY3BtcyA+IHRocmVzaCkgPj0gbWluU2FtcGxlcwogIGNvdW50cyA8LSBjb3VudHNba2VlcCwgXQogIGNvdW50cwp9Cgp4X3RhYmxlIDwtIHRhYmxlKGRlc2lnbiRTdGltdWxhdGlvbikKZGltKHR4aS5rYWxsaXN0by50c3YkY291bnRzKQoKY291bnRzIDwtIGZpbHRlckNvdW50cyh0eGkua2FsbGlzdG8udHN2JGNvdW50cywgdGhyZXNoPTEsIG1pblNhbXBsZXM9bWluKHhfdGFibGUpKQpkaW0oY291bnRzKQpjb3VudHNTdWJRIDwtIHFOb3JtKGNvdW50cykKeCA8LSBsb2cyQ1BNKGNvdW50c1N1YlEpCnMgPC0gbWFrZVNWRCh4JHkpCgpzdGltX3RhYmxlIDwtIHRhYmxlKHN0aW1fZGVzaWduJFN0aW11bGF0aW9uKQpzdGltX2NvdW50cyA8LSBmaWx0ZXJDb3VudHMoc3RpbV9jb3VudHMsIHRocmVzaD0xLCBtaW5TYW1wbGVzPW1pbihzdGltX3RhYmxlKSkKZGltKHN0aW1fY291bnRzKQpzdGltX2NvdW50c1N1YlEgPC0gcU5vcm0oc3RpbV9jb3VudHMpCnN0aW1feCA8LSBsb2cyQ1BNKHN0aW1fY291bnRzU3ViUSkKc3RpbV9zIDwtIG1ha2VTVkQoc3RpbV94JHkpCmBgYAoKIyMgTWVkaWFuIFBhaXJ3aXNlIENvcnJlbGF0aW9uCgpgYGB7ciBzbWN9CmNvck0gPC0gbWF0cml4U3RhdHM6OnJvd01lZGlhbnMoY29yKHR4aS5rYWxsaXN0by50c3YkY291bnRzKSkKcXMgPC0gcXVhbnRpbGUoY29yTSwgcD1jKDEsIDMpIC8gNCkKaXFyIDwtIGRpZmYocXMpCm91dExpbWl0IDwtIHFzWzFdIC0gMS41ICogaXFyCnlsaW0gPC0gYyhwbWluKG1pbihjb3JNKSwgb3V0TGltaXQpLCBtYXgoY29yTSkpCmNvbmQgPC0gcGFzdGUoZGVzaWduJEdyb3d0aCwgZGVzaWduJFN0aW11bGF0aW9uLCBzZXA9Il8iKQpjb2wgPC0gaWZlbHNlKGNvbmQgPT0gIk1fTlMiLCAiZ3JheTYwIiwKICAgICAgIGlmZWxzZShjb25kID09ICJNX0xQUyIsICJkZWVwcGluazMiLAogICAgICAgaWZlbHNlKGNvbmQgPT0gIk1fTEEiLCAiZGFya3NlYWdyZWVuMiIsCiAgICAgICBpZmVsc2UoY29uZCA9PSAiTV9MUCIsICJsYXZlbmRlciIsCiAgICAgICBpZmVsc2UoY29uZCA9PSAiR01fTlMiLCAibGlnaHRwaW5rMSIsCiAgICAgICBpZmVsc2UoY29uZCA9PSAiR01fTFBTIiwgIm1vY2Nhc2luIiwKICAgICAgIGlmZWxzZShjb25kID09ICJHTV9MQSIsICJibGFjayIsCiAgICAgICBpZmVsc2UoY29uZCA9PSAiR01fTFAiLCAic3ByaW5nZ3JlZW40IiwgImJsdWUyIikpKSkpKSkpCnBhcihtYXI9Yyg1LCA0LjUsIDIsIDEpKQpwbG90KGNvck0sIHhheHQ9Im4iLCB5bGltPXlsaW0sIHlsYWI9Ik1lZGlhbiBQYWlyd2lzZSBDb3JyZWxhdGlvbiIsCiAgICAgeGxhYj0iIiwgbWFpbj0iIiwgY29sPWNvbCwgcGNoPTE2LCBjZXg9MS41KQpheGlzKHNpZGU9MSwgYXQ9c2VxKGFsb25nPWNvck0pLCBsYWJlbHM9Y29sbmFtZXModHhpLmthbGxpc3RvLnRzdiRjb3VudHMpLCBsYXM9MikKYWJsaW5lKGg9b3V0TGltaXQsIGx0eT0yKQphYmxpbmUodj0xOm5jb2wodHhpLmthbGxpc3RvLnRzdiRjb3VudHMpLCBsdHk9MywgY29sPSJibGFjayIpCgpzdGltX2Nvck0gPC0gbWF0cml4U3RhdHM6OnJvd01lZGlhbnMoY29yKHN0aW1fY291bnRzKSkKc3RpbV9xcyA8LSBxdWFudGlsZShzdGltX2Nvck0sIHA9YygxLCAzKSAvIDQpCnN0aW1faXFyIDwtIGRpZmYoc3RpbV9xcykKc3RpbV9vdXRMaW1pdCA8LSBzdGltX3FzWzFdIC0gKDEuNSAqIGlxcikKc3RpbV95bGltIDwtIGMocG1pbihtaW4oc3RpbV9jb3JNKSwgc3RpbV9vdXRMaW1pdCksIG1heChzdGltX2Nvck0pKQpzdGltX2NvbmQgPC0gcGFzdGUoc3RpbV9kZXNpZ24kR3Jvd3RoLCBzdGltX2Rlc2lnbiRTdGltdWxhdGlvbiwgc2VwPSJfIikKY29sIDwtIGlmZWxzZShjb25kPT0iTV9OUyIsICJncmF5NjAiLAogICAgICAgaWZlbHNlKGNvbmQ9PSJNX0xQUyIsICJkZWVwcGluazMiLAogICAgICAgaWZlbHNlKGNvbmQ9PSJNX0xBIiwgImRhcmtzZWFncmVlbjIiLAogICAgICAgaWZlbHNlKGNvbmQ9PSJNX0xQIiwgImxhdmVuZGVyIiwKICAgICAgIGlmZWxzZShjb25kPT0iR01fTlMiLCAibGlnaHRwaW5rMSIsCiAgICAgICBpZmVsc2UoY29uZD09IkdNX0xQUyIsICJtb2NjYXNpbiIsCiAgICAgICBpZmVsc2UoY29uZD09IkdNX0xBIiwgImJsYWNrIiwKICAgICAgIGlmZWxzZShjb25kPT0iR01fTFAiLCAic3ByaW5nZ3JlZW40IiwgImJsdWUyIikpKSkpKSkpCnBhcihtYXI9Yyg1LCA0LjUsIDIsIDEpKQpwbG90KHN0aW1fY29yTSwgeGF4dD0ibiIsIHlsaW09eWxpbSwgeWxhYj0iTWVkaWFuIFBhaXJ3aXNlIENvcnJlbGF0aW9uIiwKICAgICB4bGFiPSIiLCBtYWluPSIiLCBjb2w9Y29sLCBwY2g9MTYsIGNleD0xLjUpCmF4aXMoc2lkZT0xLCBhdD1zZXEoYWxvbmc9c3RpbV9jb3JNKSwgbGFiZWxzPWNvbG5hbWVzKHN0aW1fY291bnRzKSwgbGFzPTIpCmFibGluZShoPXN0aW1fb3V0TGltaXQsIGx0eT0yKQphYmxpbmUodj0xOm5jb2woc3RpbV9jb3VudHMpLCBsdHk9MywgY29sPSJibGFjayIpCmBgYAoKYGBge3IgbXlfc21jfQpwbG90X3NtKGhzX2V4cHQpJHBsb3QKcGxvdF9zbShzdGltX2V4cHQpJHBsb3QKYGBgCgojIyBQQ0EKCmBgYHtyfQpjYmNiU0VROjpwY1JlcyhzJHYsIHMkZCwgY29uZCwgZGVzaWduJEJhdGNoKVsxOjUsIF0KY2JjYlNFUTo6cGNSZXMocyR2LCBzJGQsIGNvbmQsIGRlc2lnbiRQYXRpZW50KVsxOjUsIF0KY2JjYlNFUTo6cGNSZXMoc3RpbV9zJHYsIHN0aW1fcyRkLCBzdGltX2NvbmQsIHN0aW1fZGVzaWduJEJhdGNoKVsxOjUsIF0KY2JjYlNFUTo6cGNSZXMoc3RpbV9zJHYsIHN0aW1fcyRkLCBzdGltX2NvbmQsIHN0aW1fZGVzaWduJFBhdGllbnQpWzE6NSwgXQpgYGAKCiMjIEV1Y2xpZGlhbiBEaXN0YW5jZSBIZWF0IE1hcAoKYGBge3IgZGlzaGVhdH0KZGlzdHMgPC0gZGlzdCh0KGNvdW50cykpCm1hdCA8LSBhcy5tYXRyaXgoZGlzdHMpCnJvd25hbWVzKG1hdCkgPC0gY29sbmFtZXMobWF0KSA8LSBjb25kCmhtY29sIDwtIGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCg5LCAiR25CdSIpKSgxMDApCnZlYy5wYXRpZW50IDwtIHJhaW5ib3cobmxldmVscyhkZXNpZ24kUGF0aWVudCksIHN0YXJ0PTAsIGVuZD0wLjgpCnBhdGllbnQuY29sb3IgPC0gcmVwKDAsIGxlbmd0aChkZXNpZ24kUGF0aWVudCkpCmZvciAoaSBpbiAxOmxlbmd0aChkZXNpZ24kUGF0aWVudCkpIHsKICBwYXRpZW50LmNvbG9yW2ldIDwtIHZlYy5wYXRpZW50W2Rlc2lnbiRQYXRpZW50W2ldID09IGxldmVscyhkZXNpZ24kUGF0aWVudCldCn0KdmVjLmNvbmRpdGlvbiA8LSBjKCJncmVlbiIsICJsaWdodGJsdWUiLCAicGluayIsICJwdXJwbGUiKQpjb25kaXRpb24uY29sb3IgPC0gcmVwKDAsIGxlbmd0aChkZXNpZ24kU3RpbXVsYXRpb24pKQpmb3IgKGkgaW4gMTpsZW5ndGgoZGVzaWduJFN0aW11bGF0aW9uKSkgewogIGNvbmRpdGlvbi5jb2xvcltpXSA8LSB2ZWMuY29uZGl0aW9uW2Rlc2lnbiRTdGltdWxhdGlvbltpXSA9PSBsZXZlbHMoZGVzaWduJFN0aW11bGF0aW9uKV0KfQoKaGVhdG1hcCA8LSBoZWF0bWFwLjIobWF0LCB0cmFjZT0ibm9uZSIsIGNvbD1yZXYoaG1jb2wpLCBtYXJnaW49YygxMSwgMTEpLAogICAgICAgICAgICAgICAgICAgICBDb2xTaWRlQ29sb3JzPWNvbmRpdGlvbi5jb2xvciwKICAgICAgICAgICAgICAgICAgICAgUm93U2lkZUNvbG9ycz1wYXRpZW50LmNvbG9yLCBrZXk9RkFMU0UsIHNydENvbD00NSkKCnN0aW1fZGlzdHMgPC0gZGlzdCh0KHN0aW1fY291bnRzKSkKc3RpbV9tYXQgPC0gYXMubWF0cml4KHN0aW1fZGlzdHMpCnJvd25hbWVzKHN0aW1fbWF0KSA8LSBjb2xuYW1lcyhzdGltX21hdCkgPC0gc3RpbV9jb25kCnN0aW1faG1jb2wgPC0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDksICJHbkJ1IikpKDEwMCkKc3RpbV92ZWMucGF0aWVudCA8LSByYWluYm93KG5sZXZlbHMoc3RpbV9kZXNpZ24kUGF0aWVudCksIHN0YXJ0PTAsIGVuZD0wLjgpCnN0aW1fcGF0aWVudC5jb2xvciA8LSByZXAoMCwgbGVuZ3RoKHN0aW1fZGVzaWduJFBhdGllbnQpKQpmb3IgKGkgaW4gMTpsZW5ndGgoc3RpbV9kZXNpZ24kUGF0aWVudCkpIHsKICBpZHggPC0gc3RpbV9kZXNpZ24kUGF0aWVudFtpXSA9PSBsZXZlbHMoc3RpbV9kZXNpZ24kUGF0aWVudCkKICBzdGltX3BhdGllbnQuY29sb3JbaV0gPC0gc3RpbV92ZWMucGF0aWVudFtpZHhdCn0Kc3RpbV92ZWMuY29uZGl0aW9uIDwtIGMoImdyZWVuIiwgImxpZ2h0Ymx1ZSIsICJwaW5rIiwgInB1cnBsZSIpCnN0aW1fY29uZGl0aW9uLmNvbG9yIDwtIHJlcCgwLCBsZW5ndGgoc3RpbV9kZXNpZ24kU3RpbXVsYXRpb24pKQpmb3IgKGkgaW4gMTpsZW5ndGgoc3RpbV9kZXNpZ24kU3RpbXVsYXRpb24pKSB7CiAgaWR4IDwtIHN0aW1fZGVzaWduJFN0aW11bGF0aW9uW2ldID09IGxldmVscyhzdGltX2Rlc2lnbiRTdGltdWxhdGlvbikKICBzdGltX2NvbmRpdGlvbi5jb2xvcltpXSA8LSBzdGltX3ZlYy5jb25kaXRpb25baWR4XQp9CmhlYXRtYXAgPC0gaGVhdG1hcC4yKHN0aW1fbWF0LCB0cmFjZT0ibm9uZSIsIGNvbD1yZXYoaG1jb2wpLCBtYXJnaW49YygxMSwgMTEpLAogICAgICAgICAgICAgICAgICAgICBDb2xTaWRlQ29sb3JzPXN0aW1fY29uZGl0aW9uLmNvbG9yLAogICAgICAgICAgICAgICAgICAgICBSb3dTaWRlQ29sb3JzPXN0aW1fcGF0aWVudC5jb2xvciwga2V5PUZBTFNFLCBzcnRDb2w9NDUpCmBgYAoKYGBge3IgbXlfZGlzaGVhdH0KbXlfZGlzaGVhdCA8LSBwbG90X2Rpc2hlYXQoaHNfZXhwdCkKc3RpbV9kaXNoZWF0IDwtIHBsb3RfZGlzaGVhdChzdGltX2V4cHQpCmBgYAoKIyMgUGxvdCBQQzEgdiBQQzIKCmBgYHtyIG9yaWdpbmFsX3BjYX0KY29uZG51bSA8LSBhcy5udW1lcmljKGFzLmZhY3RvcihkZXNpZ24kU3RpbXVsYXRpb24pKQpjb25kbnVtIDwtIGlmZWxzZShjb25kbnVtID09IDQsICJncmVlbiIsCiAgICAgICAgICAgaWZlbHNlKGNvbmRudW0gPT0gMywgImxpZ2h0Ymx1ZSIsCiAgICAgICAgICAgaWZlbHNlKGNvbmRudW0gPT0gMiwgInBpbmsiLAogICAgICAgICAgIGlmZWxzZShjb25kbnVtID09IDEsICJwdXJwbGUiLCAiYmxhY2siKSkpKQpwYXRudW0gPC0gYXMubnVtZXJpYyhhcy5mYWN0b3IoZGVzaWduJFBhdGllbnQpKQpwYXRudW0gPC0gaWZlbHNlKHBhdG51bSA9PSA0LCAyMSwKICAgICAgICAgIGlmZWxzZShwYXRudW0gPT0gMywgMjIsCiAgICAgICAgICBpZmVsc2UocGF0bnVtID09IDIsIDIzLAogICAgICAgICAgaWZlbHNlKHBhdG51bSA9PSAxLCAyNCwKICAgICAgICAgIGlmZWxzZShwYXRudW0gPT0gNSwgMjUsIDEpKSkpKQpjYmNiU0VROjpwbG90UEMocyR2LCBzJGQsIGNvbD0iYmxhY2siLCBwY2g9cGF0bnVtLCBiZz1jb25kbnVtKQpsZWdlbmQoeD0wLjIsIHk9MC4yLCBsZWdlbmQ9dW5pcXVlKGRlc2lnbiRTdGltdWxhdGlvbiksIHBjaD0yMiwgY29sPTAsCiAgICAgICBwdC5iZz1jKCJncmVlbiIsICJsaWdodGJsdWUiLCAicGluayIsICJwdXJwbGUiKSwgcHQuY2V4PTEuNSwgY2V4PTAuNSwgYnR5PSJuIikKbGVnZW5kKHg9MC4yLCB5PS0wLjEsIGxlZ2VuZD11bmlxdWUoZGVzaWduJFBhdGllbnQpLCBwY2g9dW5pcXVlKHBhdG51bSksIGNvbD0wLAogICAgICAgcHQuYmc9ImdyYXk5MCIsIHB0LmNleD0xLjUsIGNleD0wLjUsIGJ0eT0ibiIpCgpzdGltX2NvbmRudW0gPC0gYXMubnVtZXJpYyhhcy5mYWN0b3Ioc3RpbV9kZXNpZ24kU3RpbXVsYXRpb24pKQpzdGltX2NvbmRudW0gPC0gaWZlbHNlKHN0aW1fY29uZG51bSA9PSA0LCAiZ3JlZW4iLAogICAgICAgICAgICAgICAgaWZlbHNlKHN0aW1fY29uZG51bSA9PSAzLCAibGlnaHRibHVlIiwKICAgICAgICAgICAgICAgIGlmZWxzZShzdGltX2NvbmRudW0gPT0gMiwgInBpbmsiLAogICAgICAgICAgICAgICAgaWZlbHNlKHN0aW1fY29uZG51bSA9PSAxLCAicHVycGxlIiwgImJsYWNrIikpKSkKc3RpbV9wYXRudW0gPC0gYXMubnVtZXJpYyhhcy5mYWN0b3Ioc3RpbV9kZXNpZ24kUGF0aWVudCkpCnN0aW1fcGF0bnVtIDwtIGlmZWxzZShzdGltX3BhdG51bSA9PSA0LCAyMSwKICAgICAgICAgICAgICAgaWZlbHNlKHN0aW1fcGF0bnVtID09IDMsIDIyLAogICAgICAgICAgICAgICBpZmVsc2Uoc3RpbV9wYXRudW0gPT0gMiwgMjMsCiAgICAgICAgICAgICAgIGlmZWxzZShzdGltX3BhdG51bSA9PSAxLCAyNCwKICAgICAgICAgICAgICAgaWZlbHNlKHN0aW1fcGF0bnVtID09IDUsIDI1LCAxKSkpKSkKY2JjYlNFUTo6cGxvdFBDKHN0aW1fcyR2LCBzdGltX3MkZCwgY29sPSJibGFjayIsIHBjaD1zdGltX3BhdG51bSwgYmc9c3RpbV9jb25kbnVtKQpsZWdlbmQoeD0wLjIsIHk9MC4yLCBsZWdlbmQ9dW5pcXVlKHN0aW1fZGVzaWduJFN0aW11bGF0aW9uKSwgcGNoPTIyLCBjb2w9MCwKICAgICAgIHB0LmJnPWMoImdyZWVuIiwibGlnaHRibHVlIiwicGluayIsInB1cnBsZSIpLCBwdC5jZXg9MS41LCBjZXg9MC41LCBidHk9Im4iKQpsZWdlbmQoeD0wLjIsIHk9LTAuMSwgbGVnZW5kPXVuaXF1ZShzdGltX2Rlc2lnbiRQYXRpZW50KSwgcGNoPXVuaXF1ZShzdGltX3BhdG51bSksIGNvbD0wLAogICAgICAgcHQuYmc9ImdyYXk5MCIsIHB0LmNleD0xLjUsIGNleD0wLjUsIGJ0eT0ibiIpCmBgYAoKYGBge3IgbXlfcGNhfQpoc19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGhzX2V4cHQsIG5vcm09InF1YW50IiwgZmlsdGVyPSJjYmNiIiwgdHJhbnNmb3JtPSJsb2cyIikKbXlfcGNhIDwtIHBsb3RfcGNhKGhzX25vcm0sIHBsb3RfbGFiZWxzPUZBTFNFLCBjaXM9TlVMTCkKbXlfcGNhJHBsb3QKCmhzc3RpbV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHN0aW1fZXhwdCwgbm9ybT0icXVhbnQiLCBmaWx0ZXI9ImNiY2IiLCB0cmFuc2Zvcm09ImxvZzIiKQpzdGltX3BjYSA8LSBwbG90X3BjYShoc3N0aW1fbm9ybSwgcGxvdF9sYWJlbHM9RkFMU0UsIGNpcz1OVUxMKQpzdGltX3BjYSRwbG90CmBgYAoKIyMgQ29ycmVjdCBmb3IgUGF0aWVudCBpbiBMaW1tYSBtb2RlbAoKYGBge3J9Cm1vZCA8LSBtb2RlbC5tYXRyaXgofmRlc2lnbiRQYXRpZW50KQp2IDwtIHZvb20oY291bnRzU3ViUSwgbW9kKQpmaXQgPC0gbG1GaXQodikKbmV3RGF0YSA8LSByZXNpZHVhbHMoZml0LCB2KQpzIDwtIG1ha2VTVkQobmV3RGF0YSkKcGNSZXMocyR2LCBzJGQsIGNvbmQsIGRlc2lnbiRCYXRjaClbMTo1LCBdCnBjUmVzKHMkdiwgcyRkLCBjb25kLCBkZXNpZ24kUGF0aWVudClbMTo1LCBdCgpzdGltX3RhYmxlIDwtIHRhYmxlKHN0aW1fZGVzaWduJFN0aW11bGF0aW9uKQpzdGltX2NvdW50cyA8LSBmaWx0ZXJDb3VudHMoc3RpbV9jb3VudHMsIHRocmVzaD0yLCBtaW5TYW1wbGVzPW1pbihzdGltX3RhYmxlKSkKZGltKHN0aW1fY291bnRzKQpzdGltX2NvdW50c1N1YlEgPC0gcU5vcm0oc3RpbV9jb3VudHMpCnN0aW1fbW9kIDwtIG1vZGVsLm1hdHJpeCh+c3RpbV9kZXNpZ24kUGF0aWVudCkKc3RpbV92IDwtIHZvb20oc3RpbV9jb3VudHNTdWJRLCBzdGltX21vZCkKc3RpbV9maXQgPC0gbG1GaXQoc3RpbV92KQpzdGltX25ld0RhdGEgPC0gcmVzaWR1YWxzKHN0aW1fZml0LCBzdGltX3YpCnN0aW1fcyA8LSBtYWtlU1ZEKHN0aW1fbmV3RGF0YSkKcGNSZXMoc3RpbV9zJHYsIHN0aW1fcyRkLCBzdGltX2NvbmQsIHN0aW1fZGVzaWduJEJhdGNoKVsxOjUsIF0KcGNSZXMoc3RpbV9zJHYsIHN0aW1fcyRkLCBzdGltX2NvbmQsIHN0aW1fZGVzaWduJFBhdGllbnQpWzE6NSwgXQpgYGAKCiMjIFBsb3QgUEMxIGFuZCBQQzIgd2l0aCBwYXRpZW50IGNvcnJlY3Rpb24KCmBgYHtyfQpncm9udW0gPC0gYXMubnVtZXJpYyhhcy5mYWN0b3IoZGVzaWduJEdyb3d0aCkpCmdyb251bSA8LSBpZmVsc2UoZ3JvbnVtID09IDIsIDE5LAogICAgICAgICAgaWZlbHNlKGdyb251bSA9PSAxLCAxNSwgMSkpCnBhdG51bSA8LSBhcy5udW1lcmljKGFzLmZhY3RvcihkZXNpZ24kUGF0aWVudCkpCnBhdG51bSA8LSBpZmVsc2UocGF0bnVtID09IDEsICJwaW5rIiwKICAgICAgICAgIGlmZWxzZShwYXRudW0gPT0gMiwgImdyZWVuIiwKICAgICAgICAgIGlmZWxzZShwYXRudW0gPT0gMywgImJsdWUiLAogICAgICAgICAgaWZlbHNlKHBhdG51bSA9PSA0LCAieWVsbG93IiwKICAgICAgICAgIGlmZWxzZShwYXRudW0gPT0gNSwgImJsYWNrIiwgIm9yYW5nZSIpKSkpKQpzYW1wbGVudW0gPC0gYXMubnVtZXJpYyhhcy5mYWN0b3IoZGVzaWduJFN0aW11bGF0aW9uKSkKc2FtcGxlbnVtIDwtIGlmZWxzZShzYW1wbGVudW0gPT0gNCwgImdyZWVuIiwKICAgICAgICAgICAgIGlmZWxzZShzYW1wbGVudW0gPT0gMywgImJsdWUiLAogICAgICAgICAgICAgaWZlbHNlKHNhbXBsZW51bSA9PSAxLCAiYmxhY2siLAogICAgICAgICAgICAgaWZlbHNlKHNhbXBsZW51bSA9PSAyLCAieWVsbG93IiwgImdyZXkiKSkpKQpwbG90UEMocyR2LCBzJGQsIHBjaD1ncm9udW0sIGNvbD1zYW1wbGVudW0sIGNleD0yKQpsZWdlbmQoeD0wLjA1LCB5PTAuMywgbGVnZW5kPWMoIk5TIiwgIkxQUyIsICJMUCIsICJMQSIpLCBwY2g9MjIsIGNvbD0wLAogICAgICAgcHQuYmc9YygiZ3JlZW4iLCAiYmx1ZSIsICJibGFjayIsICJ5ZWxsb3ciKSwgcHQuY2V4PTEuNSwgY2V4PTEsIGJ0eT0ibiIpCmxlZ2VuZCh4PTAuMDUsIHk9MC4xLCBsZWdlbmQ9dW5pcXVlKGRlc2lnbiRHcm93dGgpLCBwY2g9dW5pcXVlKGdyb251bSksIGNvbD0iYmxhY2siLAogICAgICAgcHQuYmc9ImJsYWNrIiwgcHQuY2V4PTEuMCwgY2V4PTEsIGJ0eT0ibiIpCgpzdGltX2dyb251bSA8LSBhcy5udW1lcmljKGFzLmZhY3RvcihzdGltX2Rlc2lnbiRHcm93dGgpKQpzdGltX2dyb251bSA8LSBpZmVsc2Uoc3RpbV9ncm9udW0gPT0gMiwgMTksCiAgICAgICAgICAgICAgIGlmZWxzZShzdGltX2dyb251bSA9PSAxLCAxNSwgMSkpCnN0aW1fcGF0bnVtIDwtIGFzLm51bWVyaWMoYXMuZmFjdG9yKHN0aW1fZGVzaWduJFBhdGllbnQpKQpzdGltX3BhdG51bSA8LSBpZmVsc2Uoc3RpbV9wYXRudW0gPT0gMSwgInBpbmsiLAogICAgICAgICAgICAgICBpZmVsc2Uoc3RpbV9wYXRudW0gPT0gMiwgImdyZWVuIiwKICAgICAgICAgICAgICAgaWZlbHNlKHN0aW1fcGF0bnVtID09IDMsICJibHVlIiwKICAgICAgICAgICAgICAgaWZlbHNlKHN0aW1fcGF0bnVtID09IDQsICJ5ZWxsb3ciLAogICAgICAgICAgICAgICBpZmVsc2Uoc3RpbV9wYXRudW0gPT0gNSwgImJsYWNrIiwgIm9yYW5nZSIpKSkpKQpzdGltX3NhbXBsZW51bSA8LSBhcy5udW1lcmljKGFzLmZhY3RvcihzdGltX2Rlc2lnbiRTdGltdWxhdGlvbikpCnN0aW1fc2FtcGxlbnVtIDwtIGlmZWxzZShzdGltX3NhbXBsZW51bSA9PSAzLCAiZ3JlZW4iLAogICAgICAgICAgICAgICAgICBpZmVsc2Uoc3RpbV9zYW1wbGVudW0gPT0gMiwgImJsdWUiLAogICAgICAgICAgICAgICAgICBpZmVsc2Uoc3RpbV9zYW1wbGVudW0gPT0gMSwgImJsYWNrIiwgImdyZXkiKSkpCnBsb3RQQyhzdGltX3Mkdiwgc3RpbV9zJGQsIHBjaD1zdGltX2dyb251bSwgY29sPXN0aW1fc2FtcGxlbnVtLCBjZXg9MikKbGVnZW5kKHg9MC4wNSwgeT0wLjMsIGxlZ2VuZD1jKCJMUFMiLCAiTFAiLCAiTEEiKSwgcGNoPTIyLCBjb2w9MCwKICAgICAgIHB0LmJnPWMoImdyZWVuIiwgImJsdWUiLCAiYmxhY2siLCAieWVsbG93IiksIHB0LmNleD0xLjUsIGNleD0xLCBidHk9Im4iKQpsZWdlbmQoeD0wLjA1LCB5PTAuMSwgbGVnZW5kPXVuaXF1ZShzdGltX2Rlc2lnbiRHcm93dGgpLCBwY2g9dW5pcXVlKHN0aW1fZ3JvbnVtKSwKICAgICAgIGNvbD0iYmxhY2siLCBwdC5iZz0iYmxhY2siLCBwdC5jZXg9MS4wLCBjZXg9MSwgYnR5PSJuIikKYGBgCgojIyBNeSBGaWd1cmUgM0EKCmBgYHtyIG15X3BjYTJ9CiMjc3RpbV9jb3VudHMgPC0gZmlsdGVyQ291bnRzKHN0aW1fY291bnRzLCB0aHJlc2g9MSwgbWluU2FtcGxlcz1taW4oeCkpCiMjZGltKHN0aW1fY291bnRzKQojI3N0aW1fY291bnRzU3ViUSA8LSBxTm9ybShzdGltX2NvdW50cykKIyNzdGltX3ggPC0gbG9nMkNQTShzdGltX2NvdW50c1N1YlEpCiMjc3RpbV9zIDwtIG1ha2VTVkQoc3RpbV94JHkpCmhzcyA8LSBzZXRfZXhwdF9iYXRjaGVzKHN0aW1fZXhwdCwgZmFjdD0icGF0aWVudCIpCmhzcyA8LSBzbShub3JtYWxpemVfZXhwdChoc3MsIGZpbHRlcj1UUlVFKSkKaHNzIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzcywgbm9ybT0icXVhbnQiKSkKaHNzIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzcywgY29udmVydD0iY3BtIikpCmhzcyA8LSBzbShub3JtYWxpemVfZXhwdChoc3MsIHRyYW5zZm9ybT0ibG9nMiIpKQpoc3MgPC0gc20obm9ybWFsaXplX2V4cHQoaHNzLCBiYXRjaD0ibGltbWEiKSkKaHNzIDwtIHNtKHNldF9leHB0X2JhdGNoZXMoaHNzLCBmYWN0PSJncm93dGgiKSkKcGxvdF9wY2EoaHNzLCBwbG90X2xhYmVscz1GQUxTRSkkcGxvdApgYGAKCiMjIEhlYXRtYXAgd2l0aCBwYXRpZW50IGNvcnJlY3Rpb24/PwoKYGBge3J9CmRpc3RzIDwtIGRpc3QodChuZXdEYXRhKSkKbWF0IDwtIGFzLm1hdHJpeChkaXN0cykKcm93bmFtZXMobWF0KSA8LSBjb2xuYW1lcyhtYXQpIDwtIGNvbmQKaGVhdG1hcCA8LSBoZWF0bWFwLjIobWF0LCB0cmFjZT0ibm9uZSIsIGNvbD1yZXYoaG1jb2wpLCBtYXJnaW49YygxMSwgMTEpLAogICAgICAgICAgICAgICAgICAgICBDb2xTaWRlQ29sb3JzPWNvbmRpdGlvbi5jb2xvciwKICAgICAgICAgICAgICAgICAgICAgUm93U2lkZUNvbG9ycz1wYXRpZW50LmNvbG9yLCBrZXk9RkFMU0UsIHNydENvbD00NSkKYGBgCgojIyBERSBhbmFseXNpcwoKYGBge3J9CmNvdW50c1N1YlEgPC0gcU5vcm0oY291bnRzKQpwYXRpZW50IDwtIGRlc2lnbiRQYXRpZW50Cm1vZCA8LSBtb2RlbC5tYXRyaXgofiAwICsgY29uZCArIHBhdGllbnQsIGRhdGE9ZGVzaWduKQp2IDwtIHZvb20oY291bnRzU3ViUSwgbW9kLCBwbG90PVRSVUUpCmZpdCA8LSBsbUZpdCh2KQpgYGAKCiMjIE1fTFBTIHYgTV9OUwoKZUJheWVzIGZpbmRzIGFuIEYtc3RhdGlzdGljIGZyb20gdGhlIHNldCBvZiB0LXN0YXRpc3RpY3MgZm9yIHRoYXQgZ2VuZQoKYGBge3J9Ck1fTFBTLk1fTlMuY29udHIubWF0IDwtIG1ha2VDb250cmFzdHMoTV9MUFN2TV9OUz0oY29uZE1fTFBTIC0gY29uZE1fTlMpLCBsZXZlbHM9diRkZXNpZ24pCk1fTFBTLk1fTlMuZml0IDwtIGNvbnRyYXN0cy5maXQoZml0LCBNX0xQUy5NX05TLmNvbnRyLm1hdCkKTV9MUFMuTV9OUy5lYiA8LSBlQmF5ZXMoTV9MUFMuTV9OUy5maXQpCk1fTFBTLk1fTlMudG9wVGFiIDwtIHRvcFRhYmxlKE1fTFBTLk1fTlMuZWIsIGNvZWY9Ik1fTFBTdk1fTlMiLCBudW1iZXI9bnJvdyh2JEUpKQpNX0xQUy5NX05TLnRvcFRhYiA8LSBjYmluZChyb3duYW1lcyhNX0xQUy5NX05TLnRvcFRhYiksIE1fTFBTLk1fTlMudG9wVGFiKQpjb2xuYW1lcyhNX0xQUy5NX05TLnRvcFRhYikgPC0gYygiSUQiLCAibG9nRkMiLCAiQXZlRXhwciIsICJ0IiwgIlAuVmFsdWUiLCAiYWRqLlAuVmFsIiwgIkIiKQpyb3duYW1lcyhNX0xQUy5NX05TLnRvcFRhYikgPC0gYygxOm5yb3coTV9MUFMuTV9OUy50b3BUYWIpKQoKbHBzX25zX3RhYmxlIDwtICJjc3YvdG9wVGFiX01fTFBTdk1fTlNfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLmNzdiIKd3JpdGUuY3N2KE1fTFBTLk1fTlMudG9wVGFiLCBmaWxlPWxwc19uc190YWJsZSwKICAgICAgICAgIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCmBgYAoKTGltaXQgbGlzdCB0byBnZW5lcyB3aXRoIGFuIGFkanVzdGVkIHAgdmFsdWUgPCAwLjA1CgpgYGB7cn0KTV9MUFMuTV9OUy5zaWdHZW5lcyA8LSBNX0xQUy5NX05TLnRvcFRhYltNX0xQUy5NX05TLnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1LCBdCmxlbmd0aChNX0xQUy5NX05TLnNpZ0dlbmVzJElEKQpgYGAKCkZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiAyLWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMSkKCmBgYHtyfQpNX0xQUy5NX05TLnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KE1fTFBTLk1fTlMuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAxKQpsZW5ndGgoTV9MUFMuTV9OUy5zaWdHZW5lc0ZvbGQxJElEKQpgYGAKCkZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiA0LWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMikKCmBgYHtyfQpNX0xQUy5NX05TLnNpZ0dlbmVzRm9sZDIgPC0gc3Vic2V0KE1fTFBTLk1fTlMuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAyKQpsZW5ndGgoTV9MUFMuTV9OUy5zaWdHZW5lc0ZvbGQyJElEKQpgYGAKCk1ha2UgYW4gTUEgcGxvdAoKYGBge3J9CnNlbCA8LSBNX0xQUy5NX05TLnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1CnRvcCA8LSBNX0xQUy5NX05TLnRvcFRhYgpzdWIgPC0gcGFzdGUoIk5vLiBvZiBzaWcuIGdlbmVzOiAiLCBzdW0oc2VsKSwgIi8iLCBsZW5ndGgoc2VsKSkKY3BtIDwtIHYkRQoKcGxvdChyb3dNZWFucyhjcG1bdG9wJElELF0pLCB0b3AkbG9nRkMsIHBjaD0xNiwgY2V4PTAuNSwgY29sPSJkYXJrZ3JleSIsCiAgICAgbWFpbj0iTV9MUFN2TV9OUyBhZGp1c3RlZCIsIHlsYWI9ImxvZyBGQyIsCiAgICAgeGxhYj0iQXZlcmFnZSBFeHByZXNzaW9uIiwgc3ViPXN1YikKcG9pbnRzKHJvd01lYW5zKGNwbVt0b3AkSUQsIF0pW3NlbF0sIHRvcCRsb2dGQ1tzZWxdLCBjb2w9InJlZCIsIGNleD0wLjUpCmFibGluZShoPWMoLTEsIDAsIDEpLCBjb2w9InJlZCIpCmBgYAoKQW5ub3RhdGUgc2lnR2VuZXMgbGlzdCB1c2luZyBCaW9tYXJ0CgpgYGB7cn0KTV9MUFMuTV9OUy5zaWdHZW5lcyA8LSBNX0xQUy5NX05TLnNpZ0dlbmVzW29yZGVyKC1NX0xQUy5NX05TLnNpZ0dlbmVzJGxvZ0ZDKSwgXQpzaWdHZW5lcyA8LSBNX0xQUy5NX05TLnNpZ0dlbmVzCmlkcyA8LSBzaWdHZW5lcyRJRAoKZGVzYyA8LSBnZXRCTShhdHRyaWJ1dGVzPWMoImVuc2VtYmxfZ2VuZV9pZCIsICJoZ25jX3N5bWJvbCIsICJkZXNjcmlwdGlvbiIsICJnZW5lX2Jpb3R5cGUiKSwKICAgICAgICAgICAgICBmaWx0ZXJzPSJlbnNlbWJsX2dlbmVfaWQiLCB2YWx1ZXM9aWRzLCBtYXJ0PWVuc2VtYmwpCmNvbG5hbWVzKGRlc2MpIDwtIGMoIklEIiwgIlN5bWJvbCIsICJEZXNjcmlwdGlvbiIsICJUeXBlIikKZGVzYyREZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwgIiIsIGRlc2MkRGVzY3JpcHRpb24pCgpERUdfTFBTIDwtIG1lcmdlKHNpZ0dlbmVzLCBkZXNjLCBieT0iSUQiLCBhbGw9VFJVRSkKREVHX0xQUyA8LSBzdWJzZXQoREVHX0xQUywKICAgICAgICAgICAgICAgICAgc2VsZWN0PWMoSUQsIFN5bWJvbCwgRGVzY3JpcHRpb24sIGxvZ0ZDLCBhZGouUC5WYWwsIEF2ZUV4cHIsIFR5cGUpLAogICAgICAgICAgICAgICAgICBGUz0iL3QiKQpERUdfTFBTIDwtIERFR19MUFNbb3JkZXIoLURFR19MUFMkbG9nRkMpLCBdCiMjIEZpbHRlciBvdXQgR2VuZXMgLTE8RkM8MQpERUdfTFBTIDwtIHN1YnNldChERUdfTFBTLCBhYnMoREVHX0xQUyRsb2dGQyk+MSkKCiMjIFNhdmUgREUgZ2VuZXMKd3JpdGUudGFibGUoREVHX0xQUywgImNzdi9ERUdfTV9MUFN2TV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjAudHh0IiwKICAgICAgICAgICAgY29sLm5hbWVzPVRSVUUsIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCndyaXRlLmNzdihERUdfTFBTLCAiY3N2L0RFR19NX0xQU3ZNX05TX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC5jc3YiLAogICAgICAgICAgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKYGBgCgojIyBNX0xQUyB2IE1fTEEKCmBgYHtyfQojZUJheWVzIGZpbmRzIGFuIEYtc3RhdGlzdGljIGZyb20gdGhlIHNldCBvZiB0LXN0YXRpc3RpY3MgZm9yIHRoYXQgZ2VuZQpNX0xQUy5NX0xBLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKE1fTFBTdk1fTEE9KChjb25kTV9MQSAtIGNvbmRNX05TKSAtIChjb25kTV9MUFMgLSBjb25kTV9OUykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscz12JGRlc2lnbikKTV9MUFMuTV9MQS5maXQgPC0gY29udHJhc3RzLmZpdChmaXQsIE1fTFBTLk1fTEEuY29udHIubWF0KQpNX0xQUy5NX0xBLmViIDwtIGVCYXllcyhNX0xQUy5NX0xBLmZpdCkKTV9MUFMuTV9MQS50b3BUYWIgPC0gdG9wVGFibGUoTV9MUFMuTV9MQS5lYiwgY29lZj0iTV9MUFN2TV9MQSIsIG51bWJlcj1ucm93KHYkRSkpCk1fTFBTLk1fTEEudG9wVGFiIDwtIGNiaW5kKHJvd25hbWVzKE1fTFBTLk1fTEEudG9wVGFiKSwgTV9MUFMuTV9MQS50b3BUYWIpCmNvbG5hbWVzKE1fTFBTLk1fTEEudG9wVGFiKSA8LSBjKCJJRCIsICJsb2dGQyIsICJBdmVFeHByIiwgInQiLCAiUC5WYWx1ZSIsICJhZGouUC5WYWwiLCAiQiIpCnJvd25hbWVzKE1fTFBTLk1fTEEudG9wVGFiKSA8LSBjKDE6bnJvdyhNX0xQUy5NX0xBLnRvcFRhYikpCgpscHNfbGFfdGFibGUgPC0gImNzdi90b3BUYWJfTV9MUFN2TV9MQV9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjByZXYuY3N2Igp3cml0ZS5jc3YoTV9MUFMuTV9MQS50b3BUYWIsIGZpbGU9bHBzX2xhX3RhYmxlLCByb3cubmFtZXM9RkFMU0UsIHF1b3RlPUZBTFNFKQoKIyNMaW1pdCBsaXN0IHRvIGdlbmVzIHdpdGggYW4gYWRqdXN0ZWQgcCB2YWx1ZSA8IDAuMDUKTV9MUFMuTV9MQS5zaWdHZW5lcyA8LSBNX0xQUy5NX0xBLnRvcFRhYltNX0xQUy5NX0xBLnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1LCBdCmxlbmd0aChNX0xQUy5NX0xBLnNpZ0dlbmVzJElEKQojI1sxXSA2MTcKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDItZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAxKQpNX0xQUy5NX0xBLnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KE1fTFBTLk1fTEEuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAxKQpsZW5ndGgoTV9MUFMuTV9MQS5zaWdHZW5lc0ZvbGQxJElEKQojI1sxXSAyNDAKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDQtZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAyKQpNX0xQUy5NX0xBLnNpZ0dlbmVzRm9sZDIgPC0gc3Vic2V0KE1fTFBTLk1fTEEuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAyKQpsZW5ndGgoTV9MUFMuTV9MQS5zaWdHZW5lc0ZvbGQyJElEKQojI1sxXSA2OQoKIyNNYWtlIGFuIE1BIHBsb3QKc2VsIDwtIE1fTFBTLk1fTEEudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUKdG9wIDwtIE1fTFBTLk1fTEEudG9wVGFiCnN1YiA8LSBwYXN0ZSgiTm8uIG9mIHNpZy4gZ2VuZXM6ICIsIHN1bShzZWwpLCAiLyIsIGxlbmd0aChzZWwpKQpjcG0gPC0gdiRFCgpwbG90KHJvd01lYW5zKGNwbVt0b3AkSUQsXSksIHRvcCRsb2dGQywgcGNoPTE2LCBjZXg9MC41LCBjb2w9ImRhcmtncmV5IiwKICAgICBtYWluPSJNX0xQU3ZNX0xBIGFkanVzdGVkIiwKICAgICB5bGFiPSJsb2cgRkMiLCB4bGFiPSJBdmVyYWdlIEV4cHJlc3Npb24iLAogICAgIHN1Yj1zdWIpCnBvaW50cyhyb3dNZWFucyhjcG1bdG9wJElELCBdKVtzZWxdLCB0b3AkbG9nRkNbc2VsXSwgY29sPSJyZWQiLCBjZXg9MC41KQphYmxpbmUoaD1jKC0xLCAwLCAxKSwgY29sPSJyZWQiKQoKZGV2LmNvcHkocGRmLCAiaW1hZ2VzL01BcGxvdF9NX0xQU3ZNX0xBX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMHJldi5wZGYiLAogICAgICAgICB3aWR0aD04LCBoZWlnaHQ9OCkKZGV2Lm9mZigpCmRldi5jb3B5KHBuZywgImltYWdlcy9NQXBsb3RfTV9MUFN2TV9MQV9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjByZXYucG5nIiwKICAgICAgICAgd2lkdGg9NzAwLCBoZWlnaHQ9NzAwKQpkZXYub2ZmKCkKCk1fTFBTLk1fTEEuc2lnR2VuZXMgPC0gTV9MUFMuTV9MQS5zaWdHZW5lc1tvcmRlcigtTV9MUFMuTV9MQS5zaWdHZW5lcyRsb2dGQyksIF0KCiMjQW5ub3RhdGUgc2lnR2VuZXMgbGlzdCB1c2luZyBCaW9tYXJ0CnNpZ0dlbmVzIDwtIE1fTFBTLk1fTEEuc2lnR2VuZXMKaWRzIDwtIHNpZ0dlbmVzJElECgpkZXNjIDwtIGdldEJNKGF0dHJpYnV0ZXM9YygiZW5zZW1ibF9nZW5lX2lkIiwgImhnbmNfc3ltYm9sIiwgImRlc2NyaXB0aW9uIiwgImdlbmVfYmlvdHlwZSIpLAogICAgICAgICAgICAgIGZpbHRlcnM9ImVuc2VtYmxfZ2VuZV9pZCIsCiAgICAgICAgICAgICAgdmFsdWVzPWlkcywgbWFydD1lbnNlbWJsKQpjb2xuYW1lcyhkZXNjKSA8LSBjKCJJRCIsICJTeW1ib2wiLCAiRGVzY3JpcHRpb24iLCAiVHlwZSIpCgojI1JlbW92ZSBjb21tYXMgZnJvbSBkZXNjcmlwdGlvbgpkZXNjJERlc2NyaXB0aW9uIDwtIGdzdWIoIiwiLCAiIiwgZGVzYyREZXNjcmlwdGlvbikKCkRFRyA8LSBtZXJnZShzaWdHZW5lcywgZGVzYywgYnk9IklEIiwgYWxsPVRSVUUpCkRFRyA8LSBzdWJzZXQoREVHLCBzZWxlY3Q9YyhJRCwgU3ltYm9sLCBEZXNjcmlwdGlvbiwgbG9nRkMsIGFkai5QLlZhbCwgQXZlRXhwciwgVHlwZSksIEZTPSIvdCIpCkRFRyA8LSBERUdbb3JkZXIoLURFRyRsb2dGQyksIF0KCiMjRmlsdGVyIG91dCBHZW5lcyAtMTxGQzwxCkRFRyA8LSBzdWJzZXQoREVHLCBhYnMoREVHJGxvZ0ZDKSA+IDEpCgojI1NhdmUgREUgZ2VuZXMKd3JpdGUudGFibGUoREVHLCAiY3N2L0RFR19NX0xQU3ZNX0xBX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMHJldi50eHQiLAogICAgICAgICAgICBjb2wubmFtZXM9VFJVRSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKd3JpdGUuY3N2KERFRywgImNzdi9ERUdfTV9MUFN2TV9MQV9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjByZXYuY3N2IiwKICAgICAgICAgIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCmBgYAoKIyMgTV9MUFMgdiBNX0xQCgpgYGB7cn0KI2VCYXllcyBmaW5kcyBhbiBGLXN0YXRpc3RpYyBmcm9tIHRoZSBzZXQgb2YgdC1zdGF0aXN0aWNzIGZvciB0aGF0IGdlbmUKTV9MUFMuTV9MUC5jb250ci5tYXQgPC0gbWFrZUNvbnRyYXN0cygKICAgIE1fTFBTdk1fTFA9KChjb25kTV9MUCAtIGNvbmRNX05TKSAtIChjb25kTV9MUFMgLSBjb25kTV9OUykpLAogICAgbGV2ZWxzPXYkZGVzaWduKQpNX0xQUy5NX0xQLmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgTV9MUFMuTV9MUC5jb250ci5tYXQpCk1fTFBTLk1fTFAuZWIgPC0gZUJheWVzKE1fTFBTLk1fTFAuZml0KQpNX0xQUy5NX0xQLnRvcFRhYiA8LSB0b3BUYWJsZShNX0xQUy5NX0xQLmViLCBjb2VmPSJNX0xQU3ZNX0xQIiwgbnVtYmVyPW5yb3codiRFKSkKTV9MUFMuTV9MUC50b3BUYWIgPC0gY2JpbmQocm93bmFtZXMoTV9MUFMuTV9MUC50b3BUYWIpLCBNX0xQUy5NX0xQLnRvcFRhYikKY29sbmFtZXMoTV9MUFMuTV9MUC50b3BUYWIpIDwtIGMoIklEIiwgImxvZ0ZDIiwgIkF2ZUV4cHIiLCAidCIsICJQLlZhbHVlIiwgImFkai5QLlZhbCIsICJCIikKcm93bmFtZXMoTV9MUFMuTV9MUC50b3BUYWIpIDwtIGMoMTpucm93KE1fTFBTLk1fTFAudG9wVGFiKSkKCmxwc19scF90YWJsZSA8LSAiY3N2L3RvcFRhYl9NX0xQU3ZNX0xQX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMHJldi5jc3YiCndyaXRlLmNzdihNX0xQUy5NX0xQLnRvcFRhYiwgZmlsZT1scHNfbHBfdGFibGUsIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCgojI0xpbWl0IGxpc3QgdG8gZ2VuZXMgd2l0aCBhbiBhZGp1c3RlZCBwIHZhbHVlIDwgMC4wNQpNX0xQUy5NX0xQLnNpZ0dlbmVzIDwtIE1fTFBTLk1fTFAudG9wVGFiW01fTFBTLk1fTFAudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUsIF0KbGVuZ3RoKE1fTFBTLk1fTFAuc2lnR2VuZXMkSUQpCiMjWzFdIDE0NzMKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDItZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAxKQpNX0xQUy5NX0xQLnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KE1fTFBTLk1fTFAuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAxKQpsZW5ndGgoTV9MUFMuTV9MUC5zaWdHZW5lc0ZvbGQxJElEKQojI1sxXSA0NjcKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDQtZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAyKQpNX0xQUy5NX0xQLnNpZ0dlbmVzRm9sZDIgPC0gc3Vic2V0KE1fTFBTLk1fTFAuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAyKQpsZW5ndGgoTV9MUFMuTV9MUC5zaWdHZW5lc0ZvbGQyJElEKQojI1sxXSAxMjUKCiMjTWFrZSBhbiBNQSBwbG90CnNlbCA8LSBNX0xQUy5NX0xQLnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1CnRvcCA8LSBNX0xQUy5NX0xQLnRvcFRhYgpzdWIgPC0gcGFzdGUoIk5vLiBvZiBzaWcuIGdlbmVzOiAiLCBzdW0oc2VsKSwgIi8iLCBsZW5ndGgoc2VsKSkKY3BtIDwtIHYkRQoKcGxvdChyb3dNZWFucyhjcG1bdG9wJElELF0pLCB0b3AkbG9nRkMsIHBjaD0xNiwgY2V4PTAuNSwgY29sPSJkYXJrZ3JleSIsCiAgICAgbWFpbj0iTV9MUFN2TV9MUCBhZGp1c3RlZCIsCiAgICAgeWxhYj0ibG9nIEZDIiwgeGxhYj0iQXZlcmFnZSBFeHByZXNzaW9uIiwKICAgICBzdWI9c3ViKQpwb2ludHMocm93TWVhbnMoY3BtW3RvcCRJRCwgXSlbc2VsXSwgdG9wJGxvZ0ZDW3NlbF0sIGNvbD0icmVkIiwgY2V4PTAuNSkKYWJsaW5lKGg9YygtMSwgMCwgMSksIGNvbD0icmVkIikKCmRldi5jb3B5KHBkZiwgImltYWdlcy9NQXBsb3RfTV9MUFN2TV9MUF9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjByZXYucGRmIiwKICAgICAgICAgd2lkdGg9OCwgaGVpZ2h0PTgpCmRldi5vZmYoKQpkZXYuY29weShwbmcsICJpbWFnZXMvTUFwbG90X01fTFBTdk1fTFBfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwcmV2LnBuZyIsCiAgICAgICAgIHdpZHRoPTcwMCwgaGVpZ2h0PTcwMCkKZGV2Lm9mZigpCgpNX0xQUy5NX0xQLnNpZ0dlbmVzIDwtIE1fTFBTLk1fTFAuc2lnR2VuZXNbb3JkZXIoLU1fTFBTLk1fTFAuc2lnR2VuZXMkbG9nRkMpLCBdCgojI0Fubm90YXRlIHNpZ0dlbmVzIGxpc3QgdXNpbmcgQmlvbWFydApzaWdHZW5lcyA8LSBNX0xQUy5NX0xQLnNpZ0dlbmVzCmlkcyA8LSBzaWdHZW5lcyRJRAoKIyNUbyBzZWUgcG9zc2liaWxpdGllcyBmb3IgYXR0cmlidXRlcywgdXNlIGhlYWQobGlzdEF0dHJpYnV0ZXMoZW5zZW1ibCksIG49MjBMKQpkZXNjIDwtIGdldEJNKGF0dHJpYnV0ZXM9YygiZW5zZW1ibF9nZW5lX2lkIiwgImhnbmNfc3ltYm9sIiwgImRlc2NyaXB0aW9uIiwgImdlbmVfYmlvdHlwZSIpLAogICAgICAgICAgICAgIGZpbHRlcnM9ImVuc2VtYmxfZ2VuZV9pZCIsCiAgICAgICAgICAgICAgdmFsdWVzPWlkcywgbWFydD1lbnNlbWJsKQpjb2xuYW1lcyhkZXNjKSA8LSBjKCJJRCIsICJTeW1ib2wiLCAiRGVzY3JpcHRpb24iLCAiVHlwZSIpCgojI1JlbW92ZSBjb21tYXMgZnJvbSBkZXNjcmlwdGlvbgpkZXNjJERlc2NyaXB0aW9uIDwtIGdzdWIoIiwiLCAiIiwgZGVzYyREZXNjcmlwdGlvbikKCkRFRyA8LSBtZXJnZShzaWdHZW5lcywgZGVzYywgYnk9IklEIiwgYWxsPVRSVUUpCkRFRyA8LSBzdWJzZXQoREVHLCBzZWxlY3Q9YyhJRCwgU3ltYm9sLCBEZXNjcmlwdGlvbiwgbG9nRkMsIGFkai5QLlZhbCwgQXZlRXhwciwgVHlwZSksIEZTPSIvdCIpCkRFRyA8LSBERUdbb3JkZXIoLURFRyRsb2dGQyksIF0KCiMjRmlsdGVyIG91dCBHZW5lcyAtMTxGQzwxCkRFRyA8LSBzdWJzZXQoREVHLCBhYnMoREVHJGxvZ0ZDKSA+IDEpCgojI1NhdmUgREUgZ2VuZXMKd3JpdGUudGFibGUoREVHLCAiY3N2L0RFR19NX0xQU3ZNX0xQX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMHJldi50eHQiLAogICAgICAgICAgICBjb2wubmFtZXM9VFJVRSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKd3JpdGUuY3N2KERFRywgImNzdi9ERUdfTV9MUFN2TV9MUF9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjByZXYuY3N2IiwKICAgICAgICAgIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCmBgYAoKIyMgTV9MUCB2IE1fTlMKCmBgYHtyfQojI2VCYXllcyBmaW5kcyBhbiBGLXN0YXRpc3RpYyBmcm9tIHRoZSBzZXQgb2YgdC1zdGF0aXN0aWNzIGZvciB0aGF0IGdlbmUKTV9MUC5NX05TLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKE1fTFB2TV9OUz0oY29uZE1fTFAgLSBjb25kTV9OUyksIGxldmVscz12JGRlc2lnbikKTV9MUC5NX05TLmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgTV9MUC5NX05TLmNvbnRyLm1hdCkKTV9MUC5NX05TLmViIDwtIGVCYXllcyhNX0xQLk1fTlMuZml0KQpNX0xQLk1fTlMudG9wVGFiIDwtIHRvcFRhYmxlKE1fTFAuTV9OUy5lYiwgY29lZj0iTV9MUHZNX05TIiwgbnVtYmVyPW5yb3codiRFKSkKTV9MUC5NX05TLnRvcFRhYiA8LSBjYmluZChyb3duYW1lcyhNX0xQLk1fTlMudG9wVGFiKSwgTV9MUC5NX05TLnRvcFRhYikKY29sbmFtZXMoTV9MUC5NX05TLnRvcFRhYikgPC0gYygiSUQiLCAibG9nRkMiLCAiQXZlRXhwciIsICJ0IiwgIlAuVmFsdWUiLCAiYWRqLlAuVmFsIiwgIkIiKQpyb3duYW1lcyhNX0xQLk1fTlMudG9wVGFiKSA8LSBjKDE6bnJvdyhNX0xQLk1fTlMudG9wVGFiKSkKCmxwX25zX3RhYmxlIDwtICJjc3YvdG9wVGFiX01fTFB2TV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzEwMTguY3N2Igp3cml0ZS5jc3YoTV9MUC5NX05TLnRvcFRhYiwgZmlsZT1scF9uc190YWJsZSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKCiMjTGltaXQgbGlzdCB0byBnZW5lcyB3aXRoIGFuIGFkanVzdGVkIHAgdmFsdWUgPCAwLjA1Ck1fTFAuTV9OUy5zaWdHZW5lcyA8LSBNX0xQLk1fTlMudG9wVGFiW01fTFAuTV9OUy50b3BUYWIkYWRqLlAuVmFsIDwgMC4wNSwgXQpsZW5ndGgoTV9MUC5NX05TLnNpZ0dlbmVzJElEKQojI1sxXSA0Mzg2CgojI0ZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiAyLWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMSkKTV9MUC5NX05TLnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KE1fTFAuTV9OUy5zaWdHZW5lcywgYWJzKGxvZ0ZDKSA+IDEpCmxlbmd0aChNX0xQLk1fTlMuc2lnR2VuZXNGb2xkMSRJRCkKIyNbMV0gMTQ1NQoKIyNGaWx0ZXIgb3V0IHJvd3Mgd2l0aCBsZXNzIHRoYW4gNC1mb2xkIGNoYW5nZSAobG9nMiBmb2xkIGNoYW5nZSBvZiA+IDIpCk1fTFAuTV9OUy5zaWdHZW5lc0ZvbGQyIDwtIHN1YnNldChNX0xQLk1fTlMuc2lnR2VuZXMsIGFicyhsb2dGQykgPiAyKQpsZW5ndGgoTV9MUC5NX05TLnNpZ0dlbmVzRm9sZDIkSUQpCiMjWzFdIDUxOQoKIyNNYWtlIGFuIE1BIHBsb3QKc2VsIDwtIE1fTFAuTV9OUy50b3BUYWIkYWRqLlAuVmFsIDwgMC4wNQp0b3AgPC0gTV9MUC5NX05TLnRvcFRhYgpzdWIgPC0gcGFzdGUoIk5vLiBvZiBzaWcuIGdlbmVzOiAiLCBzdW0oc2VsKSwgIi8iLCBsZW5ndGgoc2VsKSkKY3BtIDwtIHYkRQoKcGxvdChyb3dNZWFucyhjcG1bdG9wJElELF0pLCB0b3AkbG9nRkMsIHBjaD0xNiwgY2V4PTAuNSwgY29sPSJkYXJrZ3JleSIsCiAgICAgbWFpbj0iTV9MUHZNX05TIGFkanVzdGVkIiwKICAgICB5bGFiPSJsb2cgRkMiLCB4bGFiPSJBdmVyYWdlIEV4cHJlc3Npb24iLAogICAgIHN1Yj1zdWIpCnBvaW50cyhyb3dNZWFucyhjcG1bdG9wJElELF0pW3NlbF0sIHRvcCRsb2dGQ1tzZWxdLCBjb2w9InJlZCIsIGNleD0wLjUpCmFibGluZShoPWMoLTEsIDAsIDEpLCBjb2w9InJlZCIpCgpkZXYuY29weShwZGYsICJpbWFnZXMvTUFwbG90X01fTFB2TV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzEwMTgucGRmIiwKICAgICAgICAgd2lkdGg9OCwgaGVpZ2h0PTgpCmRldi5vZmYoKQpkZXYuY29weShwbmcsICJpbWFnZXMvTUFwbG90X01fTFB2TV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzEwMTgucG5nIiwKICAgICAgICAgd2lkdGg9NzAwLCBoZWlnaHQ9NzAwKQpkZXYub2ZmKCkKCk1fTFAuTV9OUy5zaWdHZW5lcyA8LSBNX0xQLk1fTlMuc2lnR2VuZXNbb3JkZXIoLU1fTFAuTV9OUy5zaWdHZW5lcyRsb2dGQyksIF0KCiMjQW5ub3RhdGUgc2lnR2VuZXMgbGlzdCB1c2luZyBCaW9tYXJ0CnNpZ0dlbmVzIDwtIE1fTFAuTV9OUy5zaWdHZW5lcwppZHMgPC0gc2lnR2VuZXMkSUQKCiMjVG8gc2VlIHBvc3NpYmlsaXRpZXMgZm9yIGF0dHJpYnV0ZXMsIHVzZSBoZWFkKGxpc3RBdHRyaWJ1dGVzKGVuc2VtYmwpLCBuPTIwTCkKZGVzYyA8LSBnZXRCTShhdHRyaWJ1dGVzPWMoImVuc2VtYmxfZ2VuZV9pZCIsICJoZ25jX3N5bWJvbCIsICJkZXNjcmlwdGlvbiIsICJnZW5lX2Jpb3R5cGUiKSwKICAgICAgICAgICAgICBmaWx0ZXJzPSJlbnNlbWJsX2dlbmVfaWQiLAogICAgICAgICAgICAgIHZhbHVlcz1pZHMsIG1hcnQ9ZW5zZW1ibCkKY29sbmFtZXMoZGVzYyk9YygiSUQiLCAiU3ltYm9sIiwgIkRlc2NyaXB0aW9uIiwgIlR5cGUiKQoKIyNSZW1vdmUgY29tbWFzIGZyb20gZGVzY3JpcHRpb24KZGVzYyREZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwgIiIsIGRlc2MkRGVzY3JpcHRpb24pCgpERUdfTFA0IDwtIG1lcmdlKHNpZ0dlbmVzLCBkZXNjLCBieT0iSUQiLCBhbGw9VFJVRSkKREVHX0xQNCA8LSBzdWJzZXQoREVHX0xQNCwgc2VsZWN0PWMoSUQsIFN5bWJvbCwgRGVzY3JpcHRpb24sIGxvZ0ZDLCBhZGouUC5WYWwsIEF2ZUV4cHIsIFR5cGUpLAogICAgICAgICAgICAgICAgICBGUz0iL3QiKQpERUdfTFA0IDwtIERFR19MUDRbb3JkZXIoLURFR19MUDQkbG9nRkMpLCBdCgojI0ZpbHRlciBvdXQgR2VuZXMgLTE8RkM8MQpERUdfTFA0IDwtIHN1YnNldChERUdfTFA0LCBhYnMoREVHX0xQNCRsb2dGQykgPiAxKQoKIyNTYXZlIERFIGdlbmVzCndyaXRlLnRhYmxlKERFR19MUDQsICJjc3YvREVHX01fTFB2TV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzEwMTgudHh0IiwKICAgICAgICAgICAgY29sLm5hbWVzPVRSVUUsIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCndyaXRlLmNzdihERUdfTFA0LCAiY3N2L0RFR19NX0xQdk1fTlNfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMDE4LmNzdiIsCiAgICAgICAgICByb3cubmFtZXM9RkFMU0UsIHF1b3RlPUZBTFNFKQpgYGAKCiMjIE1fTEEgdiBNX05TCgpgYGB7cn0KI2VCYXllcyBmaW5kcyBhbiBGLXN0YXRpc3RpYyBmcm9tIHRoZSBzZXQgb2YgdC1zdGF0aXN0aWNzIGZvciB0aGF0IGdlbmUKTV9MQS5NX05TLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKE1fTEF2TV9OUz0oY29uZE1fTEEgLSBjb25kTV9OUyksIGxldmVscz12JGRlc2lnbikKTV9MQS5NX05TLmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgTV9MQS5NX05TLmNvbnRyLm1hdCkKTV9MQS5NX05TLmViIDwtIGVCYXllcyhNX0xBLk1fTlMuZml0KQpNX0xBLk1fTlMudG9wVGFiIDwtIHRvcFRhYmxlKE1fTEEuTV9OUy5lYiwgY29lZj0iTV9MQXZNX05TIiwgbnVtYmVyPW5yb3codiRFKSkKTV9MQS5NX05TLnRvcFRhYiA8LSBjYmluZChyb3duYW1lcyhNX0xBLk1fTlMudG9wVGFiKSwgTV9MQS5NX05TLnRvcFRhYikKY29sbmFtZXMoTV9MQS5NX05TLnRvcFRhYikgPC0gYygiSUQiLCAibG9nRkMiLCAiQXZlRXhwciIsICJ0IiwgIlAuVmFsdWUiLCAiYWRqLlAuVmFsIiwgIkIiKQpyb3duYW1lcyhNX0xBLk1fTlMudG9wVGFiKSA8LSBjKDE6bnJvdyhNX0xBLk1fTlMudG9wVGFiKSkKCmxhX25zX3RhYmxlIDwtICJjc3YvdG9wVGFiX01fTEF2TV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjAuY3N2Igp3cml0ZS5jc3YoTV9MQS5NX05TLnRvcFRhYiwgZmlsZT1sYV9uc190YWJsZSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKCiMjTGltaXQgbGlzdCB0byBnZW5lcyB3aXRoIGFuIGFkanVzdGVkIHAgdmFsdWUgPCAwLjA1Ck1fTEEuTV9OUy5zaWdHZW5lcyA8LSBNX0xBLk1fTlMudG9wVGFiW01fTEEuTV9OUy50b3BUYWIkYWRqLlAuVmFsIDwgMC4wNSwgXQpsZW5ndGgoTV9MQS5NX05TLnNpZ0dlbmVzJElEKQojI1sxXSA2MTcKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDItZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAxKQpNX0xBLk1fTlMuc2lnR2VuZXNGb2xkMSA8LSBzdWJzZXQoTV9MQS5NX05TLnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMSkKbGVuZ3RoKE1fTEEuTV9OUy5zaWdHZW5lc0ZvbGQxJElEKQojI1sxXSAyNDAKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDQtZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAyKQpNX0xBLk1fTlMuc2lnR2VuZXNGb2xkMiA8LSBzdWJzZXQoTV9MQS5NX05TLnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMikKbGVuZ3RoKE1fTEEuTV9OUy5zaWdHZW5lc0ZvbGQyJElEKQojI1sxXSA2OQoKIyNNYWtlIGFuIE1BIHBsb3QKc2VsIDwtIE1fTEEuTV9OUy50b3BUYWIkYWRqLlAuVmFsIDwgMC4wNQp0b3AgPC0gTV9MQS5NX05TLnRvcFRhYgpzdWIgPC0gcGFzdGUoIk5vLiBvZiBzaWcuIGdlbmVzOiAiLCBzdW0oc2VsKSwgIi8iLCBsZW5ndGgoc2VsKSkKY3BtIDwtIHYkRQoKcGxvdChyb3dNZWFucyhjcG1bdG9wJElELF0pLCB0b3AkbG9nRkMsIHBjaD0xNiwgY2V4PTAuNSwgY29sPSJkYXJrZ3JleSIsCiAgICAgbWFpbj0iTV9MQXZNX05TIGFkanVzdGVkIiwKICAgICB5bGFiPSJsb2cgRkMiLCB4bGFiPSJBdmVyYWdlIEV4cHJlc3Npb24iLAogICAgIHN1Yj1zdWIpCnBvaW50cyhyb3dNZWFucyhjcG1bdG9wJElELCBdKVtzZWxdLCB0b3AkbG9nRkNbc2VsXSwgY29sPSJyZWQiLCBjZXg9MC41KQphYmxpbmUoaD1jKC0xLCAwLCAxKSwgY29sPSJyZWQiKQoKZGV2LmNvcHkocGRmLCAiaW1hZ2VzL01BcGxvdF9NX0xBdk1fTlNfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLnBkZiIsIHdpZHRoPTgsIGhlaWdodD04KQpkZXYub2ZmKCkKZGV2LmNvcHkocG5nLCAiaW1hZ2VzL01BcGxvdF9NX0xBdk1fTlNfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLnBuZyIsIHdpZHRoPTcwMCwgaGVpZ2h0PTcwMCkKZGV2Lm9mZigpCgpNX0xBLk1fTlMuc2lnR2VuZXMgPC0gTV9MQS5NX05TLnNpZ0dlbmVzW29yZGVyKC1NX0xBLk1fTlMuc2lnR2VuZXMkbG9nRkMpLCBdCgojI0Fubm90YXRlIHNpZ0dlbmVzIGxpc3QgdXNpbmcgQmlvbWFydApzaWdHZW5lcyA8LSBNX0xBLk1fTlMuc2lnR2VuZXMKaWRzIDwtIHNpZ0dlbmVzJElECgojI1RvIHNlZSBwb3NzaWJpbGl0aWVzIGZvciBhdHRyaWJ1dGVzLCB1c2UgaGVhZChsaXN0QXR0cmlidXRlcyhlbnNlbWJsKSwgbj0yMEwpCmRlc2MgPC0gZ2V0Qk0oYXR0cmlidXRlcz1jKCJlbnNlbWJsX2dlbmVfaWQiLCAiaGduY19zeW1ib2wiLCAiZGVzY3JpcHRpb24iLCAiZ2VuZV9iaW90eXBlIiksCiAgICAgICAgICAgICAgZmlsdGVycz0iZW5zZW1ibF9nZW5lX2lkIiwKICAgICAgICAgICAgICB2YWx1ZXM9aWRzLCBtYXJ0PWVuc2VtYmwpCmNvbG5hbWVzKGRlc2MpIDwtIGMoIklEIiwgIlN5bWJvbCIsICJEZXNjcmlwdGlvbiIsICJUeXBlIikKCiMjUmVtb3ZlIGNvbW1hcyBmcm9tIGRlc2NyaXB0aW9uCmRlc2MkRGVzY3JpcHRpb24gPC0gZ3N1YigiLCIsICIiLCBkZXNjJERlc2NyaXB0aW9uKQoKREVHX0xBNCA8LSBtZXJnZShzaWdHZW5lcywgZGVzYywgYnk9IklEIiwgYWxsPVRSVUUpCkRFR19MQTQgPC0gc3Vic2V0KERFR19MQTQsIHNlbGVjdD1jKElELCBTeW1ib2wsIERlc2NyaXB0aW9uLCBsb2dGQywgYWRqLlAuVmFsLCBBdmVFeHByLCBUeXBlKSwKICAgICAgICAgICAgICAgICAgRlM9Ii90IikKREVHX0xBNCA8LSBERUdfTEE0W29yZGVyKC1ERUdfTEE0JGxvZ0ZDKSwgXQoKIyNGaWx0ZXIgb3V0IEdlbmVzIC0xPEZDPDEKREVHX0xBNCA8LSBzdWJzZXQoREVHX0xBNCwgYWJzKERFR19MQTQkbG9nRkMpID4gMSkKCiMjU2F2ZSBERSBnZW5lcwp3cml0ZS50YWJsZShERUdfTEE0LCAiY3N2L0RFR19NX0xBdk1fTlNfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLnR4dCIsCiAgICAgICAgICAgIGNvbC5uYW1lcz1UUlVFLCByb3cubmFtZXM9RkFMU0UsIHF1b3RlPUZBTFNFKQp3cml0ZS5jc3YoREVHX0xBNCwgImNzdi9ERUdfTV9MQXZNX05TX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC5jc3YiLAogICAgICAgICAgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKYGBgCgojIyBHTV9MUFMgdi4gR01fTlMKCmBgYHtyfQojZUJheWVzIGZpbmRzIGFuIEYtc3RhdGlzdGljIGZyb20gdGhlIHNldCBvZiB0LXN0YXRpc3RpY3MgZm9yIHRoYXQgZ2VuZQpHTV9MUFMuR01fTlMuY29udHIubWF0IDwtIG1ha2VDb250cmFzdHMoR01fTFBTdkdNX05TPShjb25kR01fTFBTLWNvbmRHTV9OUyksIGxldmVscz12JGRlc2lnbikKR01fTFBTLkdNX05TLmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgR01fTFBTLkdNX05TLmNvbnRyLm1hdCkKR01fTFBTLkdNX05TLmViIDwtIGVCYXllcyhHTV9MUFMuR01fTlMuZml0KQpHTV9MUFMuR01fTlMudG9wVGFiIDwtIHRvcFRhYmxlKEdNX0xQUy5HTV9OUy5lYiwgY29lZj0iR01fTFBTdkdNX05TIiwgbnVtYmVyPW5yb3codiRFKSkKR01fTFBTLkdNX05TLnRvcFRhYiA8LSBjYmluZChyb3duYW1lcyhHTV9MUFMuR01fTlMudG9wVGFiKSwgR01fTFBTLkdNX05TLnRvcFRhYikKY29sbmFtZXMoR01fTFBTLkdNX05TLnRvcFRhYikgPC0gYygiSUQiLCAibG9nRkMiLCAiQXZlRXhwciIsICJ0IiwgIlAuVmFsdWUiLCAiYWRqLlAuVmFsIiwgIkIiKQpyb3duYW1lcyhHTV9MUFMuR01fTlMudG9wVGFiKSA8LSBjKDE6bnJvdyhHTV9MUFMuR01fTlMudG9wVGFiKSkKCmdtX2xwc19uc190YWJsZSA8LSAiY3N2L3RvcFRhYl9HTV9MUFN2R01fTlNfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLmNzdiIKd3JpdGUuY3N2KEdNX0xQUy5HTV9OUy50b3BUYWIsIGZpbGU9IGdtX2xwc19uc190YWJsZSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKCiMjTGltaXQgbGlzdCB0byBnZW5lcyB3aXRoIGFuIGFkanVzdGVkIHAgdmFsdWUgPCAwLjA1CkdNX0xQUy5HTV9OUy5zaWdHZW5lcyA8LSBHTV9MUFMuR01fTlMudG9wVGFiW0dNX0xQUy5HTV9OUy50b3BUYWIkYWRqLlAuVmFsIDwgMC4wNSwgXQpsZW5ndGgoR01fTFBTLkdNX05TLnNpZ0dlbmVzJElEKQojI1sxXSAzMDIKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDItZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAxKQpHTV9MUFMuR01fTlMuc2lnR2VuZXNGb2xkMSA8LSBzdWJzZXQoR01fTFBTLkdNX05TLnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMSkKbGVuZ3RoKEdNX0xQUy5HTV9OUy5zaWdHZW5lc0ZvbGQxJElEKQojI1sxXSAxOTcKCiMjRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDQtZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAyKQpHTV9MUFMuR01fTlMuc2lnR2VuZXNGb2xkMiA8LSBzdWJzZXQoR01fTFBTLkdNX05TLnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMikKbGVuZ3RoKEdNX0xQUy5HTV9OUy5zaWdHZW5lc0ZvbGQyJElEKQojI1sxXSAxMDEKCiMjTWFrZSBhbiBNQSBwbG90CnNlbCA8LSBHTV9MUFMuR01fTlMudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUKdG9wIDwtIEdNX0xQUy5HTV9OUy50b3BUYWIKc3ViIDwtIHBhc3RlKCJOby4gb2Ygc2lnLiBnZW5lczogIiwgc3VtKHNlbCksICIvIiwgbGVuZ3RoKHNlbCkpCmNwbSA8LSB2JEUKCnBsb3Qocm93TWVhbnMoY3BtW3RvcCRJRCxdKSwgdG9wJGxvZ0ZDLCBwY2g9MTYsIGNleD0wLjUsIGNvbD0iZGFya2dyZXkiLAogICAgIG1haW49IkdNX0xQU3ZHTV9OUyBhZGp1c3RlZCIsIHlsYWI9ImxvZyBGQyIsCiAgICAgeGxhYj0iQXZlcmFnZSBFeHByZXNzaW9uIiwgc3ViPXN1YikKcG9pbnRzKHJvd01lYW5zKGNwbVt0b3AkSUQsIF0pW3NlbF0sIHRvcCRsb2dGQ1tzZWxdLCBjb2w9InJlZCIsIGNleD0wLjUpCmFibGluZShoPWMoLTEsIDAsIDEpLCBjb2w9InJlZCIpCgpkZXYuY29weShwZGYsICJpbWFnZXMvTUFwbG90X0dNX0xQU3ZHTV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjAucGRmIiwKICAgICAgICAgd2lkdGg9OCwgaGVpZ2h0PTgpCmRldi5vZmYoKQpkZXYuY29weShwbmcsICJpbWFnZXMvTUFwbG90X0dNX0xQU3ZHTV9OU19DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjAucG5nIiwKICAgICAgICAgd2lkdGg9NzAwLCBoZWlnaHQ9NzAwKQpkZXYub2ZmKCkKCkdNX0xQUy5HTV9OUy5zaWdHZW5lcyA8LSBHTV9MUFMuR01fTlMuc2lnR2VuZXNbb3JkZXIoLUdNX0xQUy5HTV9OUy5zaWdHZW5lcyRsb2dGQyksIF0KCiMjQW5ub3RhdGUgc2lnR2VuZXMgbGlzdCB1c2luZyBCaW9tYXJ0CnNpZ0dlbmVzIDwtIEdNX0xQUy5HTV9OUy5zaWdHZW5lcwppZHMgPC0gc2lnR2VuZXMkSUQKCiMjVG8gc2VlIHBvc3NpYmlsaXRpZXMgZm9yIGF0dHJpYnV0ZXMsIHVzZSBoZWFkKGxpc3RBdHRyaWJ1dGVzKGVuc2VtYmwpLCBuPTIwTCkKZGVzYyA8LSBnZXRCTShhdHRyaWJ1dGVzPWMoImVuc2VtYmxfZ2VuZV9pZCIsICJoZ25jX3N5bWJvbCIsICJkZXNjcmlwdGlvbiIsICJnZW5lX2Jpb3R5cGUiKSwKICAgICAgICAgICAgICBmaWx0ZXJzPSJlbnNlbWJsX2dlbmVfaWQiLAogICAgICAgICAgICAgIHZhbHVlcz1pZHMsIG1hcnQ9ZW5zZW1ibCkKY29sbmFtZXMoZGVzYykgPC0gYygiSUQiLCAiU3ltYm9sIiwgIkRlc2NyaXB0aW9uIiwgIlR5cGUiKQoKIyNSZW1vdmUgY29tbWFzIGZyb20gZGVzY3JpcHRpb24KZGVzYyREZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwgIiIsIGRlc2MkRGVzY3JpcHRpb24pCgpERUcgPC0gbWVyZ2Uoc2lnR2VuZXMsIGRlc2MsIGJ5PSJJRCIsIGFsbD1UUlVFKQpERUcgPC0gc3Vic2V0KERFRywgc2VsZWN0PWMoSUQsIFN5bWJvbCwgRGVzY3JpcHRpb24sIGxvZ0ZDLCBhZGouUC5WYWwsIEF2ZUV4cHIsIFR5cGUpLCBGUz0iL3QiKQpERUcgPC0gREVHW29yZGVyKC1ERUckbG9nRkMpLCBdCgojI0ZpbHRlciBvdXQgR2VuZXMgLTE8RkM8MQpERUcgPC0gc3Vic2V0KERFRywgYWJzKERFRyRsb2dGQykgPiAxKQoKIyNTYXZlIERFIGdlbmVzCndyaXRlLnRhYmxlKERFRywgImNzdi9ERUdfR01fTFBTdkdNX05TX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC50eHQiLAogICAgICAgICAgICBjb2wubmFtZXM9VFJVRSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKd3JpdGUuY3N2KERFRywgImNzdi9ERUdfR01fTFBTdkdNX05TX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC5jc3YiLAogICAgICAgICAgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKYGBgCgojIyBHTV9MUFMgdiBHTV9MUAoKVGhpcyBjb250cmFzdCB3YXMgd3JpdHRlbiBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIgYXMgdGhlIG90aGVycywgSSB0aGluayB0aGlzIGlzCnRoZSByZWFzb24gc29tZSBvZiBteSBwbG90cyBrZWVwIGxvb2tpbmcgYmFja3dhcmRzL3Vwc2lkZWRvd24uLi4gIEkgYW0gZ29pbmcgdG8KY29tbWVudCBvdXQgdGhlIG9yaWdpbmFsIGxpbmUgYW5kIHJld3JpdGUgaXQgc28gdGhhdCBpdCBpcyBpZGVudGljYWwgaW4gb3JkZXIgdG8Kd2hhdCBJIGZvdW5kIGluOiBNX0xQLk1fTFAuY29udHIubWF0LgoKYGBge3J9CiNlQmF5ZXMgZmluZHMgYW4gRi1zdGF0aXN0aWMgZnJvbSB0aGUgc2V0IG9mIHQtc3RhdGlzdGljcyBmb3IgdGhhdCBnZW5lCgojIyBIZXJlIGlzIHRoZSBvcmlnaW5hbCBsaW5lCiMjIGxvb2sgaGVyZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4gICB2ICAgICAgICAgICAgICAgICAgICAgdgojI0dNX0xQUy5HTV9MUC5jb250ci5tYXQgPC0gbWFrZUNvbnRyYXN0cyhHTV9MUFN2R01fTFA9KChjb25kR01fTFBTLWNvbmRHTV9OUyktKGNvbmRHTV9MUC1jb25kR01fTlMpKSwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPXYkZGVzaWduKQojIwoKIyMgQW5kIGhlcmUgaXMgbXkgdmVyc2lvbjoKIyMgbG9vayBoZXJlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPiAgdiAgICAgICAgICAgICAgICAgICAgIHYKR01fTFBTLkdNX0xQLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKAogICAgR01fTFBTdkdNX0xQPSgoY29uZEdNX0xQIC0gY29uZEdNX05TKSAtIChjb25kR01fTFBTIC0gY29uZEdNX05TKSksCiAgICBsZXZlbHM9diRkZXNpZ24pCiMjIEVuZCBvZiBteSBjaGFuZ2UuCgpHTV9MUFMuR01fTFAuZml0IDwtIGNvbnRyYXN0cy5maXQoZml0LCBHTV9MUFMuR01fTFAuY29udHIubWF0KQpHTV9MUFMuR01fTFAuZWIgPC0gZUJheWVzKEdNX0xQUy5HTV9MUC5maXQpCkdNX0xQUy5HTV9MUC50b3BUYWIgPC0gdG9wVGFibGUoR01fTFBTLkdNX0xQLmViLCBjb2VmPSJHTV9MUFN2R01fTFAiLCBudW1iZXI9bnJvdyh2JEUpKQpHTV9MUFMuR01fTFAudG9wVGFiIDwtIGNiaW5kKHJvd25hbWVzKEdNX0xQUy5HTV9MUC50b3BUYWIpLCBHTV9MUFMuR01fTFAudG9wVGFiKQpjb2xuYW1lcyhHTV9MUFMuR01fTFAudG9wVGFiKSA8LSBjKCJJRCIsICJsb2dGQyIsICJBdmVFeHByIiwgInQiLCAiUC5WYWx1ZSIsICJhZGouUC5WYWwiLCAiQiIpCnJvd25hbWVzKEdNX0xQUy5HTV9MUC50b3BUYWIpIDwtIGMoMTpucm93KEdNX0xQUy5HTV9MUC50b3BUYWIpKQoKZ21fbHBzX2xwX3RhYmxlIDwtICJjc3YvdG9wVGFiX0dNX0xQU3ZHTV9MUF9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzEwMjMuY3N2Igp3cml0ZS5jc3YoR01fTFBTLkdNX0xQLnRvcFRhYiwgZmlsZT1nbV9scHNfbHBfdGFibGUsIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCgojI0xpbWl0IGxpc3QgdG8gZ2VuZXMgd2l0aCBhbiBhZGp1c3RlZCBwIHZhbHVlIDwgMC4wNQpHTV9MUFMuR01fTFAuc2lnR2VuZXMgPC0gR01fTFBTLkdNX0xQLnRvcFRhYltHTV9MUFMuR01fTFAudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUsIF0KbGVuZ3RoKEdNX0xQUy5HTV9MUC5zaWdHZW5lcyRJRCkKIyNbMV0gMTk0CgojI0ZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiAyLWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMSkKR01fTFBTLkdNX0xQLnNpZ0dlbmVzRm9sZDEgPC0gc3Vic2V0KEdNX0xQUy5HTV9MUC5zaWdHZW5lcywgYWJzKGxvZ0ZDKSA+IDEpCmxlbmd0aChHTV9MUFMuR01fTFAuc2lnR2VuZXNGb2xkMSRJRCkKIyNbMV0gMTE0CgojI0ZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiA0LWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMikKR01fTFBTLkdNX0xQLnNpZ0dlbmVzRm9sZDIgPC0gc3Vic2V0KEdNX0xQUy5HTV9MUC5zaWdHZW5lcywgYWJzKGxvZ0ZDKSA+IDIpCmxlbmd0aChHTV9MUFMuR01fTFAuc2lnR2VuZXNGb2xkMiRJRCkKIyNbMV0gMjcKCiMjTWFrZSBhbiBNQSBwbG90CnNlbCA8LSBHTV9MUFMuR01fTFAudG9wVGFiJGFkai5QLlZhbCA8IDAuMDUKdG9wIDwtIEdNX0xQUy5HTV9MUC50b3BUYWIKc3ViIDwtIHBhc3RlKCJOby4gb2Ygc2lnLiBnZW5lczogIiwgc3VtKHNlbCksICIvIiwgbGVuZ3RoKHNlbCkpCmNwbSA8LSB2JEUKCnBsb3Qocm93TWVhbnMoY3BtW3RvcCRJRCxdKSwgdG9wJGxvZ0ZDLCBwY2g9MTYsIGNleD0wLjUsIGNvbD0iZGFya2dyZXkiLAogICAgIG1haW49IkdNX0xQU3ZHTV9MUCBhZGp1c3RlZCIsCiAgICAgeWxhYj0ibG9nIEZDIiwgeGxhYj0iQXZlcmFnZSBFeHByZXNzaW9uIiwKICAgICBzdWI9c3ViKQpwb2ludHMocm93TWVhbnMoY3BtW3RvcCRJRCwgXSlbc2VsXSwgdG9wJGxvZ0ZDW3NlbF0sIGNvbD0icmVkIiwgY2V4PTAuNSkKYWJsaW5lKGg9YygtMSwgMCwgMSksIGNvbD0icmVkIikKCmRldi5jb3B5KHBkZiwgImltYWdlcy9NQXBsb3RfR01fTFBTdkdNX0xQX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC5wZGYiLAogICAgICAgICB3aWR0aD04LCBoZWlnaHQ9OCkKZGV2Lm9mZigpCmRldi5jb3B5KHBuZywgImltYWdlcy9NQXBsb3RfR01fTFBTdkdNX0xQX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC5wbmciLAogICAgICAgICB3aWR0aD03MDAsIGhlaWdodD03MDApCmRldi5vZmYoKQoKR01fTFBTLkdNX0xQLnNpZ0dlbmVzIDwtIEdNX0xQUy5HTV9MUC5zaWdHZW5lc1tvcmRlcigtR01fTFBTLkdNX0xQLnNpZ0dlbmVzJGxvZ0ZDKSwgXQoKIyMgQW5ub3RhdGUgc2lnR2VuZXMgbGlzdCB1c2luZyBCaW9tYXJ0CnNpZ0dlbmVzIDwtIEdNX0xQUy5HTV9MUC5zaWdHZW5lcwppZHMgPC0gc2lnR2VuZXMkSUQKCiMjIFRvIHNlZSBwb3NzaWJpbGl0aWVzIGZvciBhdHRyaWJ1dGVzLCB1c2UgaGVhZChsaXN0QXR0cmlidXRlcyhlbnNlbWJsKSwgbj0yMEwpCmRlc2MgPC0gZ2V0Qk0oYXR0cmlidXRlcz1jKCJlbnNlbWJsX2dlbmVfaWQiLCAiaGduY19zeW1ib2wiLCAiZGVzY3JpcHRpb24iLCAiZ2VuZV9iaW90eXBlIiksCiAgICAgICAgICAgICAgZmlsdGVycz0iZW5zZW1ibF9nZW5lX2lkIiwgdmFsdWVzPWlkcywgbWFydD1lbnNlbWJsKQpjb2xuYW1lcyhkZXNjKSA8LSBjKCJJRCIsICJTeW1ib2wiLCAiRGVzY3JpcHRpb24iLCAiVHlwZSIpCgojI1JlbW92ZSBjb21tYXMgZnJvbSBkZXNjcmlwdGlvbgpkZXNjJERlc2NyaXB0aW9uIDwtIGdzdWIoIiwiLCAiIiwgZGVzYyREZXNjcmlwdGlvbikKCkRFRyA8LSBtZXJnZShzaWdHZW5lcywgZGVzYywgYnk9IklEIiwgYWxsPVRSVUUpCkRFRyA8LSBzdWJzZXQoREVHLCBzZWxlY3Q9YyhJRCwgU3ltYm9sLCBEZXNjcmlwdGlvbiwgbG9nRkMsIGFkai5QLlZhbCwgQXZlRXhwciwgVHlwZSksIEZTPSIvdCIpCkRFRyA8LSBERUdbb3JkZXIoLURFRyRsb2dGQyksIF0KCiMjRmlsdGVyIG91dCBHZW5lcyAtMTxGQzwxCkRFRyA8LSBzdWJzZXQoREVHLCBhYnMoREVHJGxvZ0ZDKSA+IDEpCgojI1NhdmUgREUgZ2VuZXMKd3JpdGUudGFibGUoREVHLCAiY3N2L0RFR19HTV9MUFN2R01fTFBfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLnR4dCIsCiAgICAgICAgICAgIGNvbC5uYW1lcz1UUlVFLCByb3cubmFtZXM9RkFMU0UsIHF1b3RlPUZBTFNFKQp3cml0ZS5jc3YoREVHLCAiY3N2L0RFR19HTV9MUFN2R01fTFBfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwLmNzdiIsCiAgICAgICAgICByb3cubmFtZXM9RkFMU0UsIHF1b3RlPUZBTFNFKQpgYGAKCiMjIEdNX0xQUyB2IEdNX0xBCgpJIHRoaW5rIEkgb2JzZXJ2ZSB0aGUgc2FtZSBmbGlwcGluZyBoZXJlLgoKYGBge3J9CiMjIGVCYXllcyBmaW5kcyBhbiBGLXN0YXRpc3RpYyBmcm9tIHRoZSBzZXQgb2YgdC1zdGF0aXN0aWNzIGZvciB0aGF0IGdlbmUKIyMgR01fTFBTLkdNX0xBLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKEdNX0xQU3ZHTV9MQT0oKGNvbmRHTV9MUFMtY29uZEdNX05TKS0oY29uZEdNX0xBLWNvbmRHTV9OUykpLAojIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPXYkZGVzaWduKQpHTV9MUFMuR01fTEEuY29udHIubWF0IDwtIG1ha2VDb250cmFzdHMoCiAgICBHTV9MUFN2R01fTEE9KChjb25kR01fTEEgLSBjb25kR01fTlMpIC0gKGNvbmRHTV9MUFMgLSBjb25kR01fTlMpKSwKICAgIGxldmVscz12JGRlc2lnbikKIyMgRW5kIG9mIG15IGNoYW5nZQpHTV9MUFMuR01fTEEuZml0IDwtIGNvbnRyYXN0cy5maXQoZml0LCBHTV9MUFMuR01fTEEuY29udHIubWF0KQpHTV9MUFMuR01fTEEuZWIgPC0gZUJheWVzKEdNX0xQUy5HTV9MQS5maXQpCkdNX0xQUy5HTV9MQS50b3BUYWIgPC0gdG9wVGFibGUoR01fTFBTLkdNX0xBLmViLCBjb2VmPSJHTV9MUFN2R01fTEEiLCBudW1iZXI9bnJvdyh2JEUpKQpHTV9MUFMuR01fTEEudG9wVGFiIDwtIGNiaW5kKHJvd25hbWVzKEdNX0xQUy5HTV9MQS50b3BUYWIpLCBHTV9MUFMuR01fTEEudG9wVGFiKQpjb2xuYW1lcyhHTV9MUFMuR01fTEEudG9wVGFiKSA8LSBjKCJJRCIsICJsb2dGQyIsICJBdmVFeHByIiwgInQiLCAiUC5WYWx1ZSIsICJhZGouUC5WYWwiLCAiQiIpCnJvd25hbWVzKEdNX0xQUy5HTV9MQS50b3BUYWIpIDwtIGMoMTpucm93KEdNX0xQUy5HTV9MQS50b3BUYWIpKQoKZ21fbHBzX2xhX3RhYmxlIDwtICJjc3YvdG9wVGFiX0dNX0xQU3ZHTV9MQV9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzEwMjMuY3N2Igp3cml0ZS5jc3YoR01fTFBTLkdNX0xBLnRvcFRhYiwgZmlsZT1nbV9scHNfbGFfdGFibGUsIHJvdy5uYW1lcz1GQUxTRSwgcXVvdGU9RkFMU0UpCgojIyBMaW1pdCBsaXN0IHRvIGdlbmVzIHdpdGggYW4gYWRqdXN0ZWQgcCB2YWx1ZSA8IDAuMDUKR01fTFBTLkdNX0xBLnNpZ0dlbmVzIDwtIEdNX0xQUy5HTV9MQS50b3BUYWJbR01fTFBTLkdNX0xBLnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1LCBdCmxlbmd0aChHTV9MUFMuR01fTEEuc2lnR2VuZXMkSUQpCiMjIFsxXSAxNwoKIyMgRmlsdGVyIG91dCByb3dzIHdpdGggbGVzcyB0aGFuIDItZm9sZCBjaGFuZ2UgKGxvZzIgZm9sZCBjaGFuZ2Ugb2YgPiAxKQpHTV9MUFMuR01fTEEuc2lnR2VuZXNGb2xkMSA8LSBzdWJzZXQoR01fTFBTLkdNX0xBLnNpZ0dlbmVzLCBhYnMobG9nRkMpID4gMSkKbGVuZ3RoKEdNX0xQUy5HTV9MQS5zaWdHZW5lc0ZvbGQxJElEKQojIyBbMV0gMTUKCiMjIEZpbHRlciBvdXQgcm93cyB3aXRoIGxlc3MgdGhhbiA0LWZvbGQgY2hhbmdlIChsb2cyIGZvbGQgY2hhbmdlIG9mID4gMikKR01fTFBTLkdNX0xBLnNpZ0dlbmVzRm9sZDIgPC0gc3Vic2V0KEdNX0xQUy5HTV9MQS5zaWdHZW5lcywgYWJzKGxvZ0ZDKSA+IDIpCmxlbmd0aChHTV9MUFMuR01fTEEuc2lnR2VuZXNGb2xkMiRJRCkKIyMgWzFdIDcKCiMjIE1ha2UgYW4gTUEgcGxvdApzZWwgPC0gR01fTFBTLkdNX0xBLnRvcFRhYiRhZGouUC5WYWwgPCAwLjA1CnRvcCA8LSBHTV9MUFMuR01fTEEudG9wVGFiCnN1YiA8LSBwYXN0ZSgiTm8uIG9mIHNpZy4gZ2VuZXM6ICIsIHN1bShzZWwpLCIvIiwgbGVuZ3RoKHNlbCkpCmNwbSA8LSB2JEUKCnBsb3Qocm93TWVhbnMoY3BtW3RvcCRJRCxdKSwgdG9wJGxvZ0ZDLCBwY2g9MTYsIGNleD0wLjUsIGNvbD0iZGFya2dyZXkiLAogICAgIG1haW49IkdNX0xQU3ZHTV9MQSBhZGp1c3RlZCIsIHlsYWI9ImxvZyBGQyIsIHhsYWI9IkF2ZXJhZ2UgRXhwcmVzc2lvbiIsIHN1Yj1zdWIpCnBvaW50cyhyb3dNZWFucyhjcG1bdG9wJElELF0pW3NlbF0sIHRvcCRsb2dGQ1tzZWxdLCBjb2w9InJlZCIsIGNleD0wLjUpCmFibGluZShoPWMoLTEsIDAsIDEpLCBjb2w9InJlZCIpCgpkZXYuY29weShwZGYsICJpbWFnZXMvTUFwbG90X0dNX0xQU3ZHTV9MQV9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjAucGRmIiwKICAgICAgICAgd2lkdGg9OCwgaGVpZ2h0PTgpCmRldi5vZmYoKQpkZXYuY29weShwbmcsICJpbWFnZXMvTUFwbG90X0dNX0xQU3ZHTV9MQV9DRFNfbGltbWFiYXRjaGNvcnJlY3Rpb25fMjAxNzExMjAucG5nIiwKICAgICAgICAgd2lkdGg9NzAwLCBoZWlnaHQ9NzAwKQpkZXYub2ZmKCkKCkdNX0xQUy5HTV9MQS5zaWdHZW5lcyA8LSBHTV9MUFMuR01fTEEuc2lnR2VuZXNbb3JkZXIoLUdNX0xQUy5HTV9MQS5zaWdHZW5lcyRsb2dGQyksIF0KCiMjIEFubm90YXRlIHNpZ0dlbmVzIGxpc3QgdXNpbmcgQmlvbWFydApzaWdHZW5lcyA8LSBHTV9MUFMuR01fTEEuc2lnR2VuZXMKaWRzIDwtIHNpZ0dlbmVzJElECgojIyBUbyBzZWUgcG9zc2liaWxpdGllcyBmb3IgYXR0cmlidXRlcywgdXNlIGhlYWQobGlzdEF0dHJpYnV0ZXMoZW5zZW1ibCksIG49MjBMKQpkZXNjIDwtIGdldEJNKGF0dHJpYnV0ZXM9YygiZW5zZW1ibF9nZW5lX2lkIiwgImhnbmNfc3ltYm9sIiwgImRlc2NyaXB0aW9uIiwgImdlbmVfYmlvdHlwZSIpLAogICAgICAgICAgICAgIGZpbHRlcnM9ImVuc2VtYmxfZ2VuZV9pZCIsIHZhbHVlcz1pZHMsIG1hcnQ9ZW5zZW1ibCkKY29sbmFtZXMoZGVzYykgPC0gYygiSUQiLCAiU3ltYm9sIiwgIkRlc2NyaXB0aW9uIiwgIlR5cGUiKQoKIyMgUmVtb3ZlIGNvbW1hcyBmcm9tIGRlc2NyaXB0aW9uCmRlc2MkRGVzY3JpcHRpb24gPC0gZ3N1YigiLCIsICIiLCBkZXNjJERlc2NyaXB0aW9uKQoKREVHIDwtIG1lcmdlKHNpZ0dlbmVzLCBkZXNjLCBieT0iSUQiLCBhbGw9VFJVRSkKREVHIDwtIHN1YnNldChERUcsIHNlbGVjdD1jKElELCBTeW1ib2wsIERlc2NyaXB0aW9uLCBsb2dGQywgYWRqLlAuVmFsLCBBdmVFeHByLCBUeXBlKSwgRlM9Ii90IikKREVHIDwtIERFR1tvcmRlcigtREVHJGxvZ0ZDKSwgXQoKIyMgRmlsdGVyIG91dCBHZW5lcyAtMTxGQzwxCkRFRyA8LSBzdWJzZXQoREVHLCBhYnMoREVHJGxvZ0ZDKSA+IDEpCgojIyBTYXZlIERFIGdlbmVzCndyaXRlLnRhYmxlKERFRywgImNzdi9ERUdfR01fTFBTdkdNX0xBX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC50eHQiLAogICAgICAgICAgICBjb2wubmFtZXM9VFJVRSwgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKd3JpdGUuY3N2KERFRywgImNzdi9ERUdfR01fTFBTdkdNX0xBX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMC5jc3YiLAogICAgICAgICAgcm93Lm5hbWVzPUZBTFNFLCBxdW90ZT1GQUxTRSkKYGBgCgojIyBCYXJwbG90cyBvZiBGb2xkLUNoYW5nZXMsIGUuZy4gRmlndXJlIDNDL0QKCkl0IGFwcGVhcnMgdG8gbWUgdGhhdCB0aGVzZSBmaWd1cmVzIGFyZSBjcmVhdGVkIGJ5IG1lcmdpbmcgdGhlIE0vR00gdGFibGVzIGZvcgp0aGUgTFAtTFBTIGFuZCBMQS1MUFMgY29udHJhc3RzLCB0YWtpbmcgdGhlIHRvcCB+MjAgZm9yIHRoZSBNIHRhYmxlLCBhbmQKcGxvdHRpbmcgdGhlIGxvZzJGQyBvbiB0aGUgbGluZWFyIHNjYWxlLiAgSSBiZWxpZXZlIEkgY2FuIHRyaXZpYWxseSBtb2RpZnkgdGhpcwp0byBhZGQgdGhlIGxvZ0ZDIC8gdC1zdGF0LiAgVGhlIGNhdmVhdCB3aWxsIGJlIHRoYXQgZG9pbmcgdGhpcyBnaXZlcyBtZSBhIGxvZzIKZXJyb3IgYmFyLCBub3QgbGluZWFyLi4uICBNeSBpbmNsaW5hdGlvbiB0aGVyZWZvcmUgaXMgdG8ganVzdCBwbG90IHRoZSBsb2dGQwpyYXRoZXIgdGhhbiBjb252ZXJ0IGl0IHRvIGxpbmVhciwgYnV0IHdoYXRldmVyLgoKIyMjIEZpZ3VyZSAzQwoKTmFqaWIgYW5kIERhdmUgd2FudCBzb21lIHNpZ25pZmljYW5jZSB0ZXN0IGJldHdlZW4gdGhlIE0vR00gYmFycyBmb3IgdGhlc2UgMjAKZ2VuZXMuICBBcyBJIHRoaW5rIGFib3V0IGl0LCBJIHRoaW5rIHRoZSBvbmx5IHZhbGlkIHdheSB0byBkbyB0aGlzIGlzIHRvCmNhbGN1bGF0ZSB0aGUgbG9nRkMgb2YgR00oUEcvTFApIC8gTShQRy9MUCkuICBUaGVuIGxldCBsaW1tYSBjYWxjdWxhdGUgdGhlIHQKc3RhdGlzdGljIGFuZCBwLXZhbHVlIHVzaW5nIGl0cyB2b29tKCkgbW9kaWZpZWQgdmFsdWVzLgoKYGBge3IgbXlfZmlnM2Nfc3RhdHN9CkdNX1BHLk1fUEcuY29udHIubWF0IDwtIG1ha2VDb250cmFzdHMoCiAgICBHTV9QR3ZNX1BHPSgoY29uZEdNX0xQIC0gY29uZEdNX0xQUykgLSAoY29uZE1fTFAgLSBjb25kTV9MUFMpKSwKICAgIGxldmVscz12JGRlc2lnbikKR01fUEcuTV9QRy5maXQgPC0gY29udHJhc3RzLmZpdChmaXQsIEdNX1BHLk1fUEcuY29udHIubWF0KQpHTV9QRy5NX1BHLmViIDwtIGVCYXllcyhHTV9QRy5NX1BHLmZpdCkKR01fUEcuTV9QRy50b3BUYWIgPC0gdG9wVGFibGUoR01fUEcuTV9QRy5lYiwgY29lZj0iR01fUEd2TV9QRyIsIG51bWJlcj1ucm93KHYkRSkpCgpkZXNjIDwtIGdldEJNKGF0dHJpYnV0ZXM9YygiZW5zZW1ibF9nZW5lX2lkIiwgImhnbmNfc3ltYm9sIiwgImRlc2NyaXB0aW9uIiwgImdlbmVfYmlvdHlwZSIpLAogICAgICAgICAgICAgIGZpbHRlcnM9ImVuc2VtYmxfZ2VuZV9pZCIsIHZhbHVlcz1yb3duYW1lcyhHTV9QRy5NX1BHLnRvcFRhYiksIG1hcnQ9ZW5zZW1ibCkKY29sbmFtZXMoZGVzYykgPC0gYygiSUQiLCAiU3ltYm9sIiwgIkRlc2NyaXB0aW9uIiwgIlR5cGUiKQpnZW5lX3N5bWJvbHMgPC0gZGVzY1ssIGMoIklEIiwgIlN5bWJvbCIpXQoKR01fUEcuTV9QRy50b3BUYWIgPC0gbWVyZ2UoZ2VuZV9zeW1ib2xzLCBHTV9QRy5NX1BHLnRvcFRhYiwgYnkueD0iSUQiLCBieS55PSJyb3cubmFtZXMiKQoKR01fTEEuTV9MQS5jb250ci5tYXQgPC0gbWFrZUNvbnRyYXN0cygKICAgIEdNX0xBdk1fTEE9KChjb25kR01fTEEgLSBjb25kR01fTFBTKSAtIChjb25kTV9MQSAtIGNvbmRNX0xQUykpLAogICAgbGV2ZWxzPXYkZGVzaWduKQpHTV9MQS5NX0xBLmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgR01fTEEuTV9MQS5jb250ci5tYXQpCkdNX0xBLk1fTEEuZWIgPC0gZUJheWVzKEdNX0xBLk1fTEEuZml0KQpHTV9MQS5NX0xBLnRvcFRhYiA8LSB0b3BUYWJsZShHTV9MQS5NX0xBLmViLCBjb2VmPSJHTV9MQXZNX0xBIiwgbnVtYmVyPW5yb3codiRFKSkKCkdNX0xBLk1fTEEudG9wVGFiIDwtIG1lcmdlKGdlbmVfc3ltYm9scywgR01fTEEuTV9MQS50b3BUYWIsIGJ5Lng9IklEIiwgYnkueT0icm93Lm5hbWVzIikKYGBgCgojIyMgRmlndXJlIDNDIHRvcC1sZWZ0CgpLYWphbCdzIHZhcmlhYmxlcyB0byBjcmVhdGUgdGhpcyBhcmUuLi4KCjEuICBNX0xQUy5NX0xQLnRvcFRhYgoyLiAgR01fTFBTLkdNX0xQLnRvcFRhYgoKVGhlc2Ugd2VyZSBwYXNzZWQgdG8gYmlvbWFydCB0byBnZXQgdGhlIGdlbmUgbmFtZXMgcmF0aGVyIHRoYW4gZW5zZW1ibCBJRHMuCkkgYW0gZ29pbmcgdG8gYmUgbGF6eSBhbmQganVzdCBjb3B5L3Bhc3RlIEthamFsJ3MgY29kZSBmb3IgdGhlc2UgdGFza3MuCgpIYXZpbmcgZG9uZSB0aGUgdG9wLWxlZnQgcGllY2Ugb2YgdGhpcywgaXQgc2VlbXMgdG8gbWUgdGhhdCBpZiB5b3UgYXJlIGdvaW5nIHRvCnRha2UgdGhlIHRvcCAyMCBnZW5lcyBhbmQgZXhjbHVkZSBiYXNlZCBvbiB0aGUgTS1DU0YgYWRqdXN0ZWQgcC12YWx1ZSwgcGVyaGFwcwp5b3Ugc2hvdWxkIGFsc28gZXhjbHVkZSBiYXNlZCBvbiB0aGUgR00tQ1NGIGFkanVzdGVkIHAtdmFsdWUsIGJ1dCB0aGUgd2F5IHRoaXMKd2FzIGRvbmUsIG9ubHkgdGhlIE0gaXMgdXNlZC4gIEluIGl0cyBjdXJyZW50IHN0YXRlLCBJIGFtIG9ubHkgdXNpbmcgdGhlIE0gYXMKcGVyIHRoZSBmaWd1cmVzIGluIHRoZWlyIGN1cnJlbnQgc3RhdGUuCgpOb3RlLCB0aGF0IGlmIHlvdSB3YW50IGVycm9yIGJhcnMgZnJvbSB0aGUgc3RhbmRhcmQgZXJyb3IsIHRoZW4gaXQgaXMgd2FhYWF5CmVhc2llciB0byBzdGF5IG9uIHRoZSBsb2cyIHNjYWxlIHJhdGhlciB0aGFuIGNvbnZlcnQgYmFjayB0byBsaW5lYXIgYmVjYXVzZSB0aGUKbWF0aCBmb3IgY29udmVydGluZyB0aGUgc3RhbmRhcmQgZXJyb3IgYmFjayB0byBsaW5lYXIgaXMgd2VpcmQuICBJZiB0aGUgdGFibGUKaGFkIGEgZmV3IG1vcmUgcGFyYW1ldGVycyBpbiBpdCwgSSBjb3VsZCBkbyBpdCB3aXRob3V0IHN0cnVnZ2xpbmcsIGJ1dCBpdCBkb2Vzbid0LgoKYGBge3IgZmlnM2NfdG9wbGVmdH0Kd2FudGVkX2NvbHVtbnMgPC0gYygiSUQiLCAibG9nRkMueCIsICJsb2dGQy55IiwgInQueCIsICJ0LnkiLCAiU3ltYm9sIikKcmVuYW1lZF9jb2x1bW5zIDwtIGMoIklEIiwgIm1fbG9nZmMiLCAiZ21fbG9nZmMiLCAibV90IiwgImdtX3QiLCAic3ltYm9sIikKCmZpZzNjX2xwX2RmIDwtIG1lcmdlKE1fTFBTLk1fTFAudG9wVGFiLCBHTV9MUFMuR01fTFAudG9wVGFiLCBieT0iSUQiKQpkZXNjIDwtIGdldEJNKGF0dHJpYnV0ZXM9YygiZW5zZW1ibF9nZW5lX2lkIiwgImhnbmNfc3ltYm9sIiwgImRlc2NyaXB0aW9uIiwgImdlbmVfYmlvdHlwZSIpLAogICAgICAgICAgICAgIGZpbHRlcnM9ImVuc2VtYmxfZ2VuZV9pZCIsIHZhbHVlcz1maWczY19scF9kZltbIklEIl1dLCBtYXJ0PWVuc2VtYmwpCmNvbG5hbWVzKGRlc2MpIDwtIGMoIklEIiwgIlN5bWJvbCIsICJEZXNjcmlwdGlvbiIsICJUeXBlIikKZmlnM2NfbHBfZGYgPC0gbWVyZ2UoZmlnM2NfbHBfZGYsIGRlc2MsIGJ5PSJJRCIsIGFsbC54PVRSVUUpCgp0bF9vcmRlcl9pZHggPC0gb3JkZXIoZmlnM2NfbHBfZGZbWyJsb2dGQy54Il1dLCBkZWNyZWFzaW5nPVRSVUUpCmZpZzNjX3RsX2RmIDwtIGZpZzNjX2xwX2RmW3RsX29yZGVyX2lkeCwgXQpzaWdfaWR4IDwtIGZpZzNjX3RsX2RmW1siYWRqLlAuVmFsLngiXV0gPD0gMC4wNQpmaWczY190bF9kZiA8LSBoZWFkKGZpZzNjX3RsX2RmW3NpZ19pZHgsIF0sIG49MjUpCmZpZzNjX3RsX2RmIDwtIGZpZzNjX3RsX2RmWywgd2FudGVkX2NvbHVtbnNdCmNvbG5hbWVzKGZpZzNjX3RsX2RmKSA8LSByZW5hbWVkX2NvbHVtbnMKcm93bmFtZXMoZmlnM2NfdGxfZGYpIDwtIGZpZzNjX3RsX2RmW1siSUQiXV0KZmlnM2NfdGxfZGZbWyJJRCJdXSA8LSBOVUxMCmZpZzNjX3RsX2RmW1sibV9sZmNlcnIiXV0gPC0gZmlnM2NfdGxfZGZbWyJtX2xvZ2ZjIl1dIC8gZmlnM2NfdGxfZGZbWyJtX3QiXV0KZmlnM2NfdGxfZGZbWyJnbV9sZmNlcnIiXV0gPC0gZmlnM2NfdGxfZGZbWyJnbV9sb2dmYyJdXSAvIGZpZzNjX3RsX2RmW1siZ21fdCJdXQoKZmlnM2NfdGxfbSA8LSBmaWczY190bF9kZlssIGMoIm1fbG9nZmMiLCAic3ltYm9sIiwgIm1fbGZjZXJyIildCmZpZzNjX3RsX21bWyJ0eXBlIl1dIDwtICJtIgpjb2xuYW1lcyhmaWczY190bF9tKSA8LSBjKCJsb2dmYyIsICJzeW1ib2wiLCAibGZjZXJyIiwgInR5cGUiKQpmaWczY190bF9nbSA8LSBmaWczY190bF9kZlssIGMoImdtX2xvZ2ZjIiwgInN5bWJvbCIsICJnbV9sZmNlcnIiKV0KZmlnM2NfdGxfZ21bWyJ0eXBlIl1dIDwtICJnbSIKY29sbmFtZXMoZmlnM2NfdGxfZ20pIDwtIGMoImxvZ2ZjIiwgInN5bWJvbCIsICJsZmNlcnIiLCAidHlwZSIpCm1lbHRlZF9maWczY190bCA8LSByYmluZChmaWczY190bF9tLCBmaWczY190bF9nbSkKbWVsdGVkX2ZpZzNjX3RsW1sic3ltYm9sIl1dIDwtIGZhY3RvcihtZWx0ZWRfZmlnM2NfdGxbWyJzeW1ib2wiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWZpZzNjX3RsX21bWyJzeW1ib2wiXV0pCm1lbHRlZF9maWczY190bFtbInR5cGUiXV0gPC0gZmFjdG9yKG1lbHRlZF9maWczY190bFtbInR5cGUiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscz1jKCJtIiwgImdtIikpCgpwIDwtIGdncGxvdChkYXRhPW1lbHRlZF9maWczY190bCwgYWVzKHg9c3ltYm9sLCB5PWxvZ2ZjLCBmaWxsPXR5cGUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBjb2xvcj0iYmxhY2siLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiY29ybmZsb3dlcmJsdWUiLCAiZGFya2dyZXkiKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bG9nZmMgLSAobGZjZXJyIC8gMiksIHltYXg9bG9nZmMgKyAobGZjZXJyIC8gMikpLCB3aWR0aD0uMiwKICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuOSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3Q9MSwgdmp1c3Q9MC41KSkKcAoKc2lnX2lkeCA8LSBHTV9QRy5NX1BHLnRvcFRhYltbIlN5bWJvbCJdXSAlaW4lIGZpZzNjX3RsX2dtW1sic3ltYm9sIl1dCnNpZ192YWx1ZXMgPC0gR01fUEcuTV9QRy50b3BUYWJbc2lnX2lkeCwgYygiU3ltYm9sIiwgIlAuVmFsdWUiLCAiYWRqLlAuVmFsIildCnJvd25hbWVzKHNpZ192YWx1ZXMpIDwtIHNpZ192YWx1ZXNbWyJTeW1ib2wiXV0Kc2lnX3ZhbHVlc1tsZXZlbHMobWVsdGVkX2ZpZzNjX3RsW1sic3ltYm9sIl1dKSwgXQpgYGAKCiMjIyBGaWd1cmUgM0MgYm90dG9tLWxlZnQKCmBgYHtyIGZpZzNDX2JvdHRvbWxlZnR9CmJsX29yZGVyX2lkeCA8LSBvcmRlcihmaWczY19scF9kZltbImxvZ0ZDLngiXV0sIGRlY3JlYXNpbmc9RkFMU0UpCmZpZzNjX2JsX2RmIDwtIGZpZzNjX2xwX2RmW2JsX29yZGVyX2lkeCwgXQpzaWdfaWR4IDwtIGZpZzNjX2JsX2RmW1siYWRqLlAuVmFsLngiXV0gPD0gMC4wNQpmaWczY19ibF9kZiA8LSBoZWFkKGZpZzNjX2JsX2RmW3NpZ19pZHgsIF0sIG49MjApCmZpZzNjX2JsX2RmIDwtIGZpZzNjX2JsX2RmWywgd2FudGVkX2NvbHVtbnNdCmNvbG5hbWVzKGZpZzNjX2JsX2RmKSA8LSByZW5hbWVkX2NvbHVtbnMKZmlnM2NfYmxfZGZbWyJJRCJdXSA8LSBOVUxMCmZpZzNjX2JsX2RmW1sibV9sZmNlcnIiXV0gPC0gZmlnM2NfYmxfZGZbWyJtX2xvZ2ZjIl1dIC8gZmlnM2NfYmxfZGZbWyJtX3QiXV0KZmlnM2NfYmxfZGZbWyJnbV9sZmNlcnIiXV0gPC0gZmlnM2NfYmxfZGZbWyJnbV9sb2dmYyJdXSAvIGZpZzNjX2JsX2RmW1siZ21fdCJdXQoKZmlnM2NfYmxfbSA8LSBmaWczY19ibF9kZlssIGMoIm1fbG9nZmMiLCAic3ltYm9sIiwgIm1fbGZjZXJyIildCmZpZzNjX2JsX21bWyJ0eXBlIl1dIDwtICJtIgpjb2xuYW1lcyhmaWczY19ibF9tKSA8LSBjKCJsb2dmYyIsICJzeW1ib2wiLCAibGZjZXJyIiwgInR5cGUiKQpmaWczY19ibF9nbSA8LSBmaWczY19ibF9kZlssIGMoImdtX2xvZ2ZjIiwgInN5bWJvbCIsICJnbV9sZmNlcnIiKV0KZmlnM2NfYmxfZ21bWyJ0eXBlIl1dIDwtICJnbSIKY29sbmFtZXMoZmlnM2NfYmxfZ20pIDwtIGMoImxvZ2ZjIiwgInN5bWJvbCIsICJsZmNlcnIiLCAidHlwZSIpCm1lbHRlZF9maWczY19ibCA8LSByYmluZChmaWczY19ibF9tLCBmaWczY19ibF9nbSkKbWVsdGVkX2ZpZzNjX2JsW1sic3ltYm9sIl1dIDwtIGZhY3RvcihtZWx0ZWRfZmlnM2NfYmxbWyJzeW1ib2wiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWZpZzNjX2JsX21bWyJzeW1ib2wiXV0pCm1lbHRlZF9maWczY19ibFtbInR5cGUiXV0gPC0gZmFjdG9yKG1lbHRlZF9maWczY19ibFtbInR5cGUiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscz1jKCJtIiwgImdtIikpCgpwIDwtIGdncGxvdChkYXRhPW1lbHRlZF9maWczY19ibCwgYWVzKHg9c3ltYm9sLCB5PWxvZ2ZjLCBmaWxsPXR5cGUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBjb2xvcj0iYmxhY2siLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiY29ybmZsb3dlcmJsdWUiLCAiZGFya2dyZXkiKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bG9nZmMtbGZjZXJyLCB5bWF4PWxvZ2ZjK2xmY2VyciksIHdpZHRoPS4yLAogICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC45KSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xLCB2anVzdD0wLjUpKQpwCgpzaWdfaWR4IDwtIEdNX1BHLk1fUEcudG9wVGFiW1siU3ltYm9sIl1dICVpbiUgZmlnM2NfYmxfZ21bWyJzeW1ib2wiXV0Kc2lnX3ZhbHVlcyA8LSBHTV9QRy5NX1BHLnRvcFRhYltzaWdfaWR4LCBjKCJTeW1ib2wiLCAiUC5WYWx1ZSIsICJhZGouUC5WYWwiKV0Kcm93bmFtZXMoc2lnX3ZhbHVlcykgPC0gc2lnX3ZhbHVlc1tbIlN5bWJvbCJdXQpzaWdfdmFsdWVzW2xldmVscyhtZWx0ZWRfZmlnM2NfYmxbWyJzeW1ib2wiXV0pLCBdCmBgYAoKIyMjIEZpZ3VyZSAzQyB0b3AtcmlnaHQKClRoZSByaWdodCBzaWRlIG9mIHRoZSBwbG90IGlzIExBIHJhdGhlciB0aGFuIExQLCBvdGhlcndpc2UgdGhpcyBpcyB0aGUgc2FtZS4KCmBgYHtyIGZpZzNjX3RvcHJpZ2h0fQp3YW50ZWRfY29sdW1ucyA8LSBjKCJJRCIsICJsb2dGQy54IiwgImxvZ0ZDLnkiLCAidC54IiwgInQueSIsICJTeW1ib2wiKQpyZW5hbWVkX2NvbHVtbnMgPC0gYygiSUQiLCAibV9sb2dmYyIsICJnbV9sb2dmYyIsICJtX3QiLCAiZ21fdCIsICJzeW1ib2wiKQoKZmlnM2NfbGFfZGYgPC0gbWVyZ2UoTV9MUFMuTV9MQS50b3BUYWIsIEdNX0xQUy5HTV9MQS50b3BUYWIsIGJ5PSJJRCIpCmRlc2MgPC0gZ2V0Qk0oYXR0cmlidXRlcz1jKCJlbnNlbWJsX2dlbmVfaWQiLCAiaGduY19zeW1ib2wiLCAiZGVzY3JpcHRpb24iLCAiZ2VuZV9iaW90eXBlIiksCiAgICAgICAgICAgICAgZmlsdGVycz0iZW5zZW1ibF9nZW5lX2lkIiwgdmFsdWVzPWZpZzNjX2xhX2RmW1siSUQiXV0sIG1hcnQ9ZW5zZW1ibCkKY29sbmFtZXMoZGVzYykgPC0gYygiSUQiLCAiU3ltYm9sIiwgIkRlc2NyaXB0aW9uIiwgIlR5cGUiKQpmaWczY19sYV9kZiA8LSBtZXJnZShmaWczY19sYV9kZiwgZGVzYywgYnk9IklEIiwgYWxsLng9VFJVRSkKCnRyX29yZGVyX2lkeCA8LSBvcmRlcihmaWczY19sYV9kZltbImxvZ0ZDLngiXV0sIGRlY3JlYXNpbmc9VFJVRSkKZmlnM2NfdHJfZGYgPC0gZmlnM2NfbGFfZGZbdHJfb3JkZXJfaWR4LCBdCnNpZ19pZHggPC0gZmlnM2NfdHJfZGZbWyJhZGouUC5WYWwueCJdXSA8PSAwLjA1CmZpZzNjX3RyX2RmIDwtIGhlYWQoZmlnM2NfdHJfZGZbc2lnX2lkeCwgXSwgbj0yNSkKZmlnM2NfdHJfZGYgPC0gZmlnM2NfdHJfZGZbLCB3YW50ZWRfY29sdW1uc10KY29sbmFtZXMoZmlnM2NfdHJfZGYpIDwtIHJlbmFtZWRfY29sdW1ucwpyb3duYW1lcyhmaWczY190cl9kZikgPC0gZmlnM2NfdHJfZGZbWyJJRCJdXQpmaWczY190cl9kZltbIklEIl1dIDwtIE5VTEwKZmlnM2NfdHJfZGZbWyJtX2xmY2VyciJdXSA8LSBmaWczY190cl9kZltbIm1fbG9nZmMiXV0gLyBmaWczY190cl9kZltbIm1fdCJdXQpmaWczY190cl9kZltbImdtX2xmY2VyciJdXSA8LSBmaWczY190cl9kZltbImdtX2xvZ2ZjIl1dIC8gZmlnM2NfdHJfZGZbWyJnbV90Il1dCgpmaWczY190cl9tIDwtIGZpZzNjX3RyX2RmWywgYygibV9sb2dmYyIsICJzeW1ib2wiLCAibV9sZmNlcnIiKV0KZmlnM2NfdHJfbVtbInR5cGUiXV0gPC0gIm0iCmNvbG5hbWVzKGZpZzNjX3RyX20pIDwtIGMoImxvZ2ZjIiwgInN5bWJvbCIsICJsZmNlcnIiLCAidHlwZSIpCmZpZzNjX3RyX2dtIDwtIGZpZzNjX3RyX2RmWywgYygiZ21fbG9nZmMiLCAic3ltYm9sIiwgImdtX2xmY2VyciIpXQpmaWczY190cl9nbVtbInR5cGUiXV0gPC0gImdtIgpjb2xuYW1lcyhmaWczY190cl9nbSkgPC0gYygibG9nZmMiLCAic3ltYm9sIiwgImxmY2VyciIsICJ0eXBlIikKbWVsdGVkX2ZpZzNjX3RyIDwtIHJiaW5kKGZpZzNjX3RyX20sIGZpZzNjX3RyX2dtKQptZWx0ZWRfZmlnM2NfdHJbWyJzeW1ib2wiXV0gPC0gZmFjdG9yKG1lbHRlZF9maWczY190cltbInN5bWJvbCJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHM9ZmlnM2NfdHJfbVtbInN5bWJvbCJdXSkKbWVsdGVkX2ZpZzNjX3RyW1sidHlwZSJdXSA8LSBmYWN0b3IobWVsdGVkX2ZpZzNjX3RyW1sidHlwZSJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWMoIm0iLCAiZ20iKSkKCnAgPC0gZ2dwbG90KGRhdGE9bWVsdGVkX2ZpZzNjX3RyLCBhZXMoeD1zeW1ib2wsIHk9bG9nZmMsIGZpbGw9dHlwZSkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGNvbG9yPSJibGFjayIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCkpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJjb3JuZmxvd2VyYmx1ZSIsICJkYXJrZ3JleSIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sb2dmYy1sZmNlcnIsIHltYXg9bG9nZmMrbGZjZXJyKSwgd2lkdGg9LjIsCiAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjkpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0PTEsIHZqdXN0PTAuNSkpCnAKCnNpZ19pZHggPC0gR01fTEEuTV9MQS50b3BUYWJbWyJTeW1ib2wiXV0gJWluJSBmaWczY190cl9nbVtbInN5bWJvbCJdXQpzaWdfdmFsdWVzIDwtIEdNX0xBLk1fTEEudG9wVGFiW3NpZ19pZHgsIGMoIlN5bWJvbCIsICJQLlZhbHVlIiwgImFkai5QLlZhbCIpXQpyb3duYW1lcyhzaWdfdmFsdWVzKSA8LSBzaWdfdmFsdWVzW1siU3ltYm9sIl1dCnNpZ192YWx1ZXNbbGV2ZWxzKG1lbHRlZF9maWczY190cltbInN5bWJvbCJdXSksIF0KYGBgCgojIyMgRmlndXJlIDNDIGJvdHRvbS1yaWdodAoKYGBge3IgZmlnM0NfYm90dG9tcmlnaHR9CmJyX29yZGVyX2lkeCA8LSBvcmRlcihmaWczY19sYV9kZltbImxvZ0ZDLngiXV0sIGRlY3JlYXNpbmc9RkFMU0UpCmZpZzNjX2JyX2RmIDwtIGZpZzNjX2xhX2RmW2JyX29yZGVyX2lkeCwgXQpzaWdfaWR4IDwtIGZpZzNjX2JyX2RmW1siYWRqLlAuVmFsLngiXV0gPD0gMC4wNQpmaWczY19icl9kZiA8LSBoZWFkKGZpZzNjX2JyX2RmW3NpZ19pZHgsIF0sIG49MjApCmZpZzNjX2JyX2RmIDwtIGZpZzNjX2JyX2RmWywgd2FudGVkX2NvbHVtbnNdCmNvbG5hbWVzKGZpZzNjX2JyX2RmKSA8LSByZW5hbWVkX2NvbHVtbnMKZmlnM2NfYnJfZGZbWyJJRCJdXSA8LSBOVUxMCmZpZzNjX2JyX2RmW1sibV9sZmNlcnIiXV0gPC0gZmlnM2NfYnJfZGZbWyJtX2xvZ2ZjIl1dIC8gZmlnM2NfYnJfZGZbWyJtX3QiXV0KZmlnM2NfYnJfZGZbWyJnbV9sZmNlcnIiXV0gPC0gZmlnM2NfYnJfZGZbWyJnbV9sb2dmYyJdXSAvIGZpZzNjX2JyX2RmW1siZ21fdCJdXQoKZmlnM2NfYnJfbSA8LSBmaWczY19icl9kZlssIGMoIm1fbG9nZmMiLCAic3ltYm9sIiwgIm1fbGZjZXJyIildCmZpZzNjX2JyX21bWyJ0eXBlIl1dIDwtICJtIgpjb2xuYW1lcyhmaWczY19icl9tKSA8LSBjKCJsb2dmYyIsICJzeW1ib2wiLCAibGZjZXJyIiwgInR5cGUiKQpmaWczY19icl9nbSA8LSBmaWczY19icl9kZlssIGMoImdtX2xvZ2ZjIiwgInN5bWJvbCIsICJnbV9sZmNlcnIiKV0KZmlnM2NfYnJfZ21bWyJ0eXBlIl1dIDwtICJnbSIKY29sbmFtZXMoZmlnM2NfYnJfZ20pIDwtIGMoImxvZ2ZjIiwgInN5bWJvbCIsICJsZmNlcnIiLCAidHlwZSIpCm1lbHRlZF9maWczY19iciA8LSByYmluZChmaWczY19icl9tLCBmaWczY19icl9nbSkKbWVsdGVkX2ZpZzNjX2JyW1sic3ltYm9sIl1dIDwtIGZhY3RvcihtZWx0ZWRfZmlnM2NfYnJbWyJzeW1ib2wiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWZpZzNjX2JyX21bWyJzeW1ib2wiXV0pCm1lbHRlZF9maWczY19icltbInR5cGUiXV0gPC0gZmFjdG9yKG1lbHRlZF9maWczY19icltbInR5cGUiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscz1jKCJtIiwgImdtIikpCgpwIDwtIGdncGxvdChkYXRhPW1lbHRlZF9maWczY19iciwgYWVzKHg9c3ltYm9sLCB5PWxvZ2ZjLCBmaWxsPXR5cGUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBjb2xvcj0iYmxhY2siLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiY29ybmZsb3dlcmJsdWUiLCAiZGFya2dyZXkiKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bG9nZmMtbGZjZXJyLCB5bWF4PWxvZ2ZjK2xmY2VyciksIHdpZHRoPS4yLAogICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC45KSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xLCB2anVzdD0wLjUpKQpwCgpzaWdfaWR4IDwtIEdNX0xBLk1fTEEudG9wVGFiW1siU3ltYm9sIl1dICVpbiUgZmlnM2NfYnJfZ21bWyJzeW1ib2wiXV0Kc2lnX3ZhbHVlcyA8LSBHTV9MQS5NX0xBLnRvcFRhYltzaWdfaWR4LCBjKCJTeW1ib2wiLCAiUC5WYWx1ZSIsICJhZGouUC5WYWwiKV0Kcm93bmFtZXMoc2lnX3ZhbHVlcykgPC0gc2lnX3ZhbHVlc1tbIlN5bWJvbCJdXQpzaWdfdmFsdWVzW2xldmVscyhtZWx0ZWRfZmlnM2NfYnJbWyJzeW1ib2wiXV0pLCBdCmBgYAoKIyMjIEZpZ3VyZSAyQQoKS2FqYWwgcmVzcG9uZGVkIHRvIG15IHF1ZXJ5IGFib3V0IHRoaXMgZmlndXJlLCBhbmQgSSBhbSBhIGxpdHRsZSBlbWJhcnJhc3NlZCB0bwpzYXkgdGhhdCBJIHNob3VsZCBoYXZlIHNlZW4gd2hhdCBpdCBpcy4gIEl0IHNlZW1zIHRvIG1lIHRoYXQgaXQgaXMgYSBiaXQKcmVkdW5kYW50IHRob3VnaCB3aXRoIDNjLCBhcyBpdCBpcyBwcmVjaXNlbHkgYSBzdWJzZXQgb2YgdGhhdCBkYXRhLCB0aG91Z2gKc2xpZ2h0bHkgcmVvcmRlcmVkLgoKIyMjIyBGaWd1cmUgMkEgTGVmdAoKYGBge3IgZmlnMmExfQpmaWcyYV9kZiA8LSBNX0xQUy5NX0xQLnNpZ0dlbmVzCm9yZGVyX2lkeCA8LSBvcmRlcihmaWcyYV9kZltbImxvZ0ZDIl1dLCBkZWNyZWFzaW5nPUZBTFNFKQpmaWcyYV9kZiA8LSBmaWcyYV9kZltvcmRlcl9pZHgsIF0KdG9wIDwtIGhlYWQoZmlnMmFfZGYsIG49MTApCmJvdCA8LSB0YWlsKGZpZzJhX2RmLCBuPTEwKQpwbG90dGVkIDwtIHJiaW5kKHRvcCwgYm90KQpyb3duYW1lcyhwbG90dGVkKSA8LSBwbG90dGVkW1siSUQiXV0KZGVzY19pZHggPC0gZGVzY1tbIklEIl1dICVpbiUgcGxvdHRlZFtbIklEIl1dCnRoaXNfZGVzYyA8LSBkZXNjW2Rlc2NfaWR4LCBdCmN1cnJlbnQgPC0gcm93bmFtZXMocGxvdHRlZCkKcGxvdHRlZCA8LSBtZXJnZSh0aGlzX2Rlc2MsIHBsb3R0ZWQsIGJ5Lng9IklEIiwgYnkueT0iSUQiLCBhbGw9VFJVRSkKcm93bmFtZXMocGxvdHRlZCkgPC0gbWFrZS5uYW1lcyhwbG90dGVkW1siSUQiXV0sIHVuaXF1ZT1UUlVFKQpwbG90dGVkIDwtIHBsb3R0ZWRbY3VycmVudCwgXQpwbG90dGVkW1sibGZjZXJyIl1dIDwtIHBsb3R0ZWRbWyJsb2dGQyJdXSAvIHBsb3R0ZWRbWyJ0Il1dCnBsb3R0ZWRbWyJTeW1ib2wiXV0gPC0gZmFjdG9yKHBsb3R0ZWRbWyJTeW1ib2wiXV0sIGxldmVscz1wbG90dGVkW1siU3ltYm9sIl1dKQoKcCA8LSBnZ3Bsb3QoZGF0YT1wbG90dGVkLCBhZXMoeD1TeW1ib2wsIHk9bG9nRkMpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsPSIjODlBOEREIiwgY29sb3I9ImJsYWNrIiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sb2dGQyAtIChsZmNlcnIgLyAyKSwgeW1heD1sb2dGQyArIChsZmNlcnIgLyAyKSksIHdpZHRoPTAuMiwKICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuOSkpICsKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xLCB2anVzdD0wLjUpKQpwCmBgYAoKIyMjIyBGaWd1cmUgMkEgUmlnaHQKCmBgYHtyIGZpZzJhfQpmaWcyYV9kZiA8LSBNX0xQUy5NX0xBLnNpZ0dlbmVzCm9yZGVyX2lkeCA8LSBvcmRlcihmaWcyYV9kZltbImxvZ0ZDIl1dLCBkZWNyZWFzaW5nPUZBTFNFKQpmaWcyYV9kZiA8LSBmaWcyYV9kZltvcmRlcl9pZHgsIF0KdG9wIDwtIGhlYWQoZmlnMmFfZGYsIG49MTApCmJvdCA8LSB0YWlsKGZpZzJhX2RmLCBuPTEwKQpwbG90dGVkIDwtIHJiaW5kKHRvcCwgYm90KQpyb3duYW1lcyhwbG90dGVkKSA8LSBwbG90dGVkW1siSUQiXV0KZGVzY19pZHggPC0gZGVzY1tbIklEIl1dICVpbiUgcGxvdHRlZFtbIklEIl1dCnRoaXNfZGVzYyA8LSBkZXNjW2Rlc2NfaWR4LCBdCmN1cnJlbnQgPC0gcm93bmFtZXMocGxvdHRlZCkKcGxvdHRlZCA8LSBtZXJnZSh0aGlzX2Rlc2MsIHBsb3R0ZWQsIGJ5Lng9IklEIiwgYnkueT0iSUQiLCBhbGw9VFJVRSkKcm93bmFtZXMocGxvdHRlZCkgPC0gbWFrZS5uYW1lcyhwbG90dGVkW1siSUQiXV0sIHVuaXF1ZT1UUlVFKQpwbG90dGVkIDwtIHBsb3R0ZWRbY3VycmVudCwgXQpwbG90dGVkW1sibGZjZXJyIl1dIDwtIHBsb3R0ZWRbWyJsb2dGQyJdXSAvIHBsb3R0ZWRbWyJ0Il1dCnBsb3R0ZWRbWyJTeW1ib2wiXV0gPC0gZmFjdG9yKHBsb3R0ZWRbWyJTeW1ib2wiXV0sIGxldmVscz1wbG90dGVkW1siU3ltYm9sIl1dKQoKcCA8LSBnZ3Bsb3QoZGF0YT1wbG90dGVkLCBhZXMoeD1TeW1ib2wsIHk9bG9nRkMpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsPSIjN0JEMTlDIiwgY29sb3I9ImJsYWNrIiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sb2dGQyAtIChsZmNlcnIgLyAyKSwgeW1heD1sb2dGQyArIChsZmNlcnIgLyAyKSksIHdpZHRoPTAuMiwKICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuOSkpICsKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xLCB2anVzdD0wLjUpKQpwCmBgYAoKIyMjIEZpZ3VyZSAyRAoKSSBjcmVhdGVkIGEgdGFibGUgb2Ygc2hhcmVkIERFRyBiZXR3ZWVuIEwrUEdFMi9MUFMgYW5kIEwrQWRvL0xQUyAodGFibGUgYXR0YWNoZWQKYmVsb3cpIGJ5IG1lcmdpbmcgdGhlIDIgREUgdGFibGVzIGJhc2VkIG9uIGNvbW1vbiBnZW5lIHN5bWJvbC4gIEluIHRoaXMgdGFibGUsCmxvZ0ZDLnggY29ycmVzcG9uZHMgdG8gTCtBZG8vTFBTIGFuZCBsb2dGQy55IGNvcnJlc3BvbmRzIHRvIEwrUEdFMi9MUFMuICBJCmF2ZXJhZ2VkIHRoZSBmb2xkIGNoYW5nZXMgYmV0d2VlbiBsb2dGQy54IGFuZCBsb2dGQy55IGluIG9yZGVyIHRvIGRldGVybWluZSB0aGUKcmFuayBvcmRlciBvZiB0aGUgZ2VuZXMgaW4gdGhlIGZpZ3VyZSBidXQgcGxvdHRlZCB0aGUgZm9sZCBjaGFuZ2VzCmluZGl2aWR1YWxseS4gIEluc3RlYWQgb2YgcGxvdHRpbmcgbG9nMkZDIEkgbWFudWFsbHkgY29udmVydGVkIHRob3NlIHZhbHVlcyB0bwpqdXN0IEZDLiBJIGRvbuKAmXQga25vdyBob3cgdG8gY2FsY3VsYXRlIHN0YW5kYXJkIGVycm9yIGlmIEkgYW0gcGxvdHRpbmcganVzdCBGQy4KSXQgd291bGQgYmUgbmljZSBpZiB0aGlzIGNvdWxkIGFsbCBiZSBkb25lIGluIFIuCgpgYGB7ciBmaWcyZHR9CmZpZzJkX2RmIDwtIG1lcmdlKE1fTFBTLk1fTFAuc2lnR2VuZXMsIE1fTFBTLk1fTEEuc2lnR2VuZXMsIGJ5PSJJRCIpCmZpZzJkX2RmIDwtIG1lcmdlKGZpZzJkX2RmLCBkZXNjLCBieT0iSUQiKQpmaWcyZF9kZltbImF2ZyJdXSA8LSAoZmlnMmRfZGZbWyJsb2dGQy54Il1dICsgZmlnMmRfZGZbWyJsb2dGQy55Il1dKSAvIDIKCm9yZGVyX2lkeCA8LSBvcmRlcihmaWcyZF9kZltbImF2ZyJdXSwgZGVjcmVhc2luZz1UUlVFKQpmaWcyZHRfZGYgPC0gaGVhZChmaWcyZF9kZltvcmRlcl9pZHgsIF0sIG49MjIpCmZpZzJkdF9kZltbImxwX2xmY2VyciJdXSA8LSBmaWcyZHRfZGZbWyJsb2dGQy54Il1dIC8gZmlnMmR0X2RmW1sidC54Il1dCmZpZzJkdF9kZltbImxhX2xmY2VyciJdXSA8LSBmaWcyZHRfZGZbWyJsb2dGQy55Il1dIC8gZmlnMmR0X2RmW1sidC55Il1dCgpmaWcyZHRfbHAgPC0gZmlnMmR0X2RmWywgYygiU3ltYm9sIiwgImxvZ0ZDLngiLCAibHBfbGZjZXJyIildCmNvbG5hbWVzKGZpZzJkdF9scCkgPC0gYygic3ltYm9sIiwgImxvZ2ZjIiwgImxmY2VyciIpCmZpZzJkdF9scFtbInR5cGUiXV0gPC0gIkxQUytQR0UiCmZpZzJkdF9sYSA8LSBmaWcyZHRfZGZbLCBjKCJTeW1ib2wiLCAibG9nRkMueSIsICJsYV9sZmNlcnIiKV0KY29sbmFtZXMoZmlnMmR0X2xhKSA8LSBjKCJzeW1ib2wiLCAibG9nZmMiLCAibGZjZXJyIikKZmlnMmR0X2xhW1sidHlwZSJdXSA8LSAiTFBTK0FkbyIKbWVsdGVkX2ZpZzJkdCA8LSByYmluZChmaWcyZHRfbGEsIGZpZzJkdF9scCkKbWVsdGVkX2ZpZzJkdFtbInN5bWJvbCJdXSA8LSBmYWN0b3IobWVsdGVkX2ZpZzJkdFtbInN5bWJvbCJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPXVuaXF1ZShtZWx0ZWRfZmlnMmR0W1sic3ltYm9sIl1dKSkKbWVsdGVkX2ZpZzJkdFtbInR5cGUiXV0gPC0gZmFjdG9yKG1lbHRlZF9maWcyZHRbWyJ0eXBlIl1dLCBsZXZlbHM9YygiTFBTK0FkbyIsICJMUFMrUEdFIikpCgpwIDwtIGdncGxvdChkYXRhPW1lbHRlZF9maWcyZHQsIGFlcyh4PXN5bWJvbCwgeT1sb2dmYywgZmlsbD10eXBlKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgY29sb3I9ImJsYWNrIiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiM3QkQxOUMiLCAiIzg5QThERCIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sb2dmYyAtIChsZmNlcnIgLyAyKSwgeW1heD1sb2dmYyArIChsZmNlcnIgLyAyKSksIHdpZHRoPTAuMiwKICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuOSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3Q9MSwgdmp1c3Q9MC41KSkKcApgYGAKCmBgYHtyIGZpZzJkYn0KZmlnMmRfZGYgPC0gbWVyZ2UoTV9MUFMuTV9MUC5zaWdHZW5lcywgTV9MUFMuTV9MQS5zaWdHZW5lcywgYnk9IklEIikKZmlnMmRfZGYgPC0gbWVyZ2UoZmlnMmRfZGYsIGRlc2MsIGJ5PSJJRCIpCmZpZzJkX2RmW1siYXZnIl1dIDwtIChmaWcyZF9kZltbImxvZ0ZDLngiXV0gKyBmaWcyZF9kZltbImxvZ0ZDLnkiXV0pIC8gMgoKb3JkZXJfaWR4IDwtIG9yZGVyKGZpZzJkX2RmW1siYXZnIl1dLCBkZWNyZWFzaW5nPUZBTFNFKQpmaWcyZGJfZGYgPC0gaGVhZChmaWcyZF9kZltvcmRlcl9pZHgsIF0sIG49MjIpCmZpZzJkYl9kZltbImxwX2xmY2VyciJdXSA8LSBmaWcyZGJfZGZbWyJsb2dGQy54Il1dIC8gZmlnMmRiX2RmW1sidC54Il1dCmZpZzJkYl9kZltbImxhX2xmY2VyciJdXSA8LSBmaWcyZGJfZGZbWyJsb2dGQy55Il1dIC8gZmlnMmRiX2RmW1sidC55Il1dCgpmaWcyZGJfbHAgPC0gZmlnMmRiX2RmWywgYygiU3ltYm9sIiwgImxvZ0ZDLngiLCAibHBfbGZjZXJyIildCmNvbG5hbWVzKGZpZzJkYl9scCkgPC0gYygic3ltYm9sIiwgImxvZ2ZjIiwgImxmY2VyciIpCmZpZzJkYl9scFtbInR5cGUiXV0gPC0gIkxQUytQR0UiCmZpZzJkYl9sYSA8LSBmaWcyZGJfZGZbLCBjKCJTeW1ib2wiLCAibG9nRkMueSIsICJsYV9sZmNlcnIiKV0KY29sbmFtZXMoZmlnMmRiX2xhKSA8LSBjKCJzeW1ib2wiLCAibG9nZmMiLCAibGZjZXJyIikKZmlnMmRiX2xhW1sidHlwZSJdXSA8LSAiTFBTK0FkbyIKbWVsdGVkX2ZpZzJkYiA8LSByYmluZChmaWcyZGJfbGEsIGZpZzJkYl9scCkKbWVsdGVkX2ZpZzJkYltbInN5bWJvbCJdXSA8LSBmYWN0b3IobWVsdGVkX2ZpZzJkYltbInN5bWJvbCJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPXVuaXF1ZShtZWx0ZWRfZmlnMmRiW1sic3ltYm9sIl1dKSkKbWVsdGVkX2ZpZzJkYltbInR5cGUiXV0gPC0gZmFjdG9yKG1lbHRlZF9maWcyZGJbWyJ0eXBlIl1dLCBsZXZlbHM9YygiTFBTK0FkbyIsICJMUFMrUEdFIikpCgpwIDwtIGdncGxvdChkYXRhPW1lbHRlZF9maWcyZGIsIGFlcyh4PXN5bWJvbCwgeT1sb2dmYywgZmlsbD10eXBlKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgY29sb3I9ImJsYWNrIiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiM3QkQxOUMiLCAiIzg5QThERCIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sb2dmYyAtIChsZmNlcnIgLyAyKSwgeW1heD1sb2dmYyArIChsZmNlcnIgLyAyKSksIHdpZHRoPTAuMiwKICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuOSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT00NSwgaGp1c3Q9MSwgdmp1c3Q9MC41KSkKcApgYGAKCiMjIFZlbm4gRGlhZ3JhbSBvZiBzaGFyZWQgREVHIGJldHdlZW4gTS1DU0YgTFBTIHYgTEEgdiBMUAoKVXByZWd1bGF0ZWQgZ2VuZXMgY29tcGFyZWQgdG8gTlMKCmBgYHtyfQp2X2RhdGEgPC0gbGlzdChERUdfTEE0W0RFR19MQTQkbG9nRkMgPiAwLCBdJElELAogICAgICAgICAgICAgICBERUdfTFA0W0RFR19MUDQkbG9nRkMgPiAwLCBdJElELAogICAgICAgICAgICAgICBERUdfTFBTW0RFR19MUFMkbG9nRkMgPiAwLCBdJElEKQp2X2RhdGEgPC0gVmVubih2X2RhdGEsIFNldE5hbWVzPWMoIkxQUytBZG8iLCAiTFBTK1BHRTIiLCAiTFBTIiksIG51bWJlck9mU2V0cz0zKQpWZW5uZXJhYmxlOjpwbG90KHZfZGF0YSwgZG9XZWlnaHRzPUZBTFNFKQojIyBkZXYuY29weShwbmcsICJWZW5uRGlhZ3JhbSBVcHJlZ3VsYXRlZCBMUFMgTEEgTFAiLCB3aWR0aD03MDAsIGhlaWdodD03MDApCiMjIGRldi5vZmYoKTsKYGBgCgpEb3ducmVndWxhdGVkIGdlbmVzIGNvbXBhcmVkIHRvIE5TCgpgYGB7cn0Kdl9kYXRhIDwtIGxpc3QoREVHX0xBNFtERUdfTEE0JGxvZ0ZDIDwgMCwgXSRJRCwKICAgICAgICAgICAgICAgREVHX0xQNFtERUdfTFA0JGxvZ0ZDIDwgMCwgXSRJRCwKICAgICAgICAgICAgICAgREVHX0xQU1tERUdfTFBTJGxvZ0ZDIDwgMCwgXSRJRCkKdl9kYXRhIDwtIFZlbm4odl9kYXRhLCBTZXROYW1lcz1jKCJMUFMrQWRvIiwgIkxQUytQR0UyIiwgIkxQUyIpLCBudW1iZXJPZlNldHM9MykKVmVubmVyYWJsZTo6cGxvdCh2X2RhdGEsIGRvV2VpZ2h0cz1GQUxTRSkKIyMgZGV2LmNvcHkocG5nLCAiVmVubkRpYWdyYW0gRG93bnJlZ3VsYXRlZCBMUFMgTEEgTFAiLCB3aWR0aD03MDAsIGhlaWdodD03MDApCiMjIGRldi5vZmYoKTsKYGBgCgojIyBWb2xjYW5vIFBsb3RzCgpNX0xQUyB2IE1fTEEKCmBgYHtyIHByZXZpb3VzX3ZvbGNhbm99CnJlcyA8LSByZWFkLmNzdihscHNfbGFfdGFibGUpCndpdGgocmVzLCBwbG90KGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsIHBjaD0yMCwKICAgICAgICAgICAgICAgbWFpbj0iVm9sY2FubyBwbG90IE1fTFBTIHYgTV9MQSIsIHhsaW09YygtNywgNykpKQojIyBBZGQgY29sb3JlZCBwb2ludHM6IHJlZCBpZiBwYWRqPDAuMDUsIG9yYW5nZSBvZiBsb2cyRkM+MSwgZ3JlZW4gaWYgYm90aCkKd2l0aChzdWJzZXQocmVzLCBhZGouUC5WYWwgPCAwLjA1ICksCiAgICAgcG9pbnRzKGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsIHBjaD0yMCwgY29sPSJ2aW9sZXRyZWQyIikpCndpdGgoc3Vic2V0KHJlcywgYWJzKGxvZ0ZDKSA+IDEpLAogICAgIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LCBwY2g9MjAsIGNvbD0ib3JhbmdlIikpCndpdGgoc3Vic2V0KHJlcywgYWRqLlAuVmFsIDwgMC4wNSAmIGFicyhsb2dGQykgPiAxKSwKICAgICBwb2ludHMobG9nRkMsIC1sb2cxMChQLlZhbHVlKSwgY2V4PTAuOCwgcGNoPTIwLCBjb2w9InR1cnF1b2lzZTMiKSkKZGV2LmNvcHkocG5nLCAiaW1hZ2VzL1ZvbGNhbm9QbG90X01fTFBTX3ZfTV9MQS5wbmciLCB3aWR0aD03MDAsIGhlaWdodD03MDApCmRldi5vZmYoKQpgYGAKCmBgYHtyIHByaW50X251bWJlcnNfZG93bmxhfQpzaWdfdXBfaWR4IDwtIHJlc1ssICJhZGouUC5WYWwiXSA8IDAuMDUgJiByZXNbLCAibG9nRkMiXSA+IDEKc3VtKHNpZ191cF9pZHgpCnNpZ191cF9pZHMgPC0gcmVzW3NpZ191cF9pZHgsICJJRCJdCm1fbHBzX21fbGFfdXBfaWRzIDwtIHNpZ191cF9pZHMKCnNpZ19kb3duX2lkeCA8LSByZXNbLCAiYWRqLlAuVmFsIl0gPCAwLjA1ICYgcmVzWywgImxvZ0ZDIl0gPCAtMQpzdW0oc2lnX2Rvd25faWR4KQpzaWdfZG93bl9pZHMgPC0gcmVzW3NpZ19kb3duX2lkeCwgIklEIl0KbV9scHNfbV9sYV9kb3duX2lkcyA8LSBzaWdfZG93bl9pZHMKYGBgCgojIE1fTFBTIHYgTV9MUAoKYGBge3IgdW5ldmFsX3ZvbGNhbm99CnJlcyA8LSByZWFkLmNzdigiY3N2L3RvcFRhYl9NX0xQU3ZNX0xQX0NEU19saW1tYWJhdGNoY29ycmVjdGlvbl8yMDE3MTEyMHJldi5jc3YiLCBoZWFkZXI9VFJVRSkKaGVhZChyZXMpCndpdGgocmVzLCBwbG90KGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsIHBjaD0yMCwKICAgICAgICAgICAgICAgbWFpbj0iVm9sY2FubyBwbG90IE1fTFBTIHYgTV9MUCIsIHhsaW09YygtNywgNykpKQoKIyMgQWRkIGNvbG9yZWQgcG9pbnRzOiByZWQgaWYgcGFkajwwLjA1LCBvcmFuZ2Ugb2YgbG9nMkZDPjEsIGdyZWVuIGlmIGJvdGgpCndpdGgoc3Vic2V0KHJlcywgYWRqLlAuVmFsIDwgMC4wNSApLAogICAgIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LCBwY2g9MjAsIGNvbD0idmlvbGV0cmVkMiIpKQp3aXRoKHN1YnNldChyZXMsIGFicyhsb2dGQykgPiAxKSwKICAgICBwb2ludHMobG9nRkMsIC1sb2cxMChQLlZhbHVlKSwgY2V4PTAuOCwgcGNoPTIwLCBjb2w9Im9yYW5nZSIpKQp3aXRoKHN1YnNldChyZXMsIGFkai5QLlZhbCA8IDAuMDUgJiBhYnMobG9nRkMpID4gMSksCiAgICAgcG9pbnRzKGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsIHBjaD0yMCwgY29sPSJ0dXJxdW9pc2UzIikpCmRldi5jb3B5KHBuZywgImltYWdlcy9Wb2xjYW5vUGxvdF9NX0xQU192X01fTFAucG5nIiwgd2lkdGg9NzAwLCBoZWlnaHQ9NzAwKQpkZXYub2ZmKCkKYGBgCgojIyBSaWNoIEZhY3RvciBHcmFwaHMKCiMjIEdPIHRlcm1zIHNoYXJlZCBMQSBMUAoKYGBge3J9CkdPU2hhcmVkcGF0aHdheXMgPC0gcmVhZC50YWJsZSgiY3N2L0dPIE1GIEZEUiAuMDUgVE9QIDUgb25seS0yLnR4dCIsIGhlYWRlcj1UUlVFLCBzZXA9J1x0JykKR09TaGFyZWRwYXRod2F5cyA8LSBHT1NoYXJlZHBhdGh3YXlzW29yZGVyKEdPU2hhcmVkcGF0aHdheXMkcC5WYWx1ZSwgZGVjcmVhc2luZz1UUlVFKSwgXQoKY29sb3JSYW1wIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygidHVycXVvaXNlMSIsICJtZWRpdW1ibHVlIikpKDUwKQpwYXIobWFyPWMoNSwgMTgsIDMsIDgpKQpwbG90KEdPU2hhcmVkcGF0aHdheXMkUmljaC5GYWN0b3IsIGMoMTo1KSwgYXhlcz1GQUxTRSwKICAgICBwYW5lbC5maXJzdD1hYmxpbmUoaD0xOjUsIHY9c2VxKDAuMSwgMC42LCAwLjEpLCBjb2w9ImdyZXk5MCIpLAogICAgIGNleD1hcy5udW1lcmljKEdPU2hhcmVkcGF0aHdheXMkR2VuZS5OdW1iZXIpIC8gNCwKICAgICBjb2w9Y29sb3JSYW1wW2N1dChhcy5udW1lcmljKEdPU2hhcmVkcGF0aHdheXMkcC5WYWx1ZSksIGJyZWFrcz01MCldLAogICAgIHBjaD0yMCwgeWxhYj0iICIsIHhsYWI9IlJpY2ggRmFjdG9yIiwgbWFpbj0iUGF0aHdheXMgRW5yaWNoZWQiLAogICAgIHhsaW09YygwLCAwLjA0KSkKYXhpcyhzaWRlPTIsIGF0PTE6NSwgbGFiZWxzPWFzLmNoYXJhY3RlcihHT1NoYXJlZHBhdGh3YXlzJEdlbmVTZXQpLCBsYXM9MiwgY2V4LmF4aXM9MC41KQpheGlzKHNpZGU9MSwgdGljaz1HT1NoYXJlZHBhdGh3YXlzW1siUmljaC5GYWN0b3IiXV0pCmBgYAoKIyMjIEtFR0cgTEEKCmBgYHtyLCBldmFsPUZBTFNFfQpMQXBhdGh3YXlzIDwtIHJlYWQudGFibGUoImNzdi9DeXRvc2NhcGUgUGF0aHdheXMvTEEgdiBMUFMudHh0IiwgaGVhZGVyPVRSVUUsIHNlcD0nXHQnKQpMQXBhdGh3YXlzIDwtIExBcGF0aHdheXNbb3JkZXIoTEFwYXRod2F5cyRwLlZhbHVlLCBkZWNyZWFzaW5nPVRSVUUpLCBdCiMjIHBsb3QgeCB2LiB5LCBjaGFuZ2Ugc2l6ZSwgYXNzaWduIGNvbG9yIHRvIHAtdmFsdWUKY29sb3JSYW1wIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygidHVycXVvaXNlMSIsICJtZWRpdW1ibHVlIikpKDUwKQpwYXIobWFyPWMoNSwgMTgsIDMsIDgpKQpwbG90KExBcGF0aHdheXMkUmljaC5GYWN0b3IsIGMoMToyOCksIGF4ZXM9RkFMU0UsCiAgICAgcGFuZWwuZmlyc3Q9YWJsaW5lKGg9MToyOCwgdj1zZXEoMC4xLCAwLjQsIDAuMSksIGNvbD0iZ3JleTkwIiksCiAgICAgY2V4PWFzLm51bWVyaWMoTEFwYXRod2F5cyRHZW5lLk51bWJlcikgLyAxMCwKICAgICBjb2w9Y29sb3JSYW1wW2N1dChhcy5udW1lcmljKExBcGF0aHdheXMkcC5WYWx1ZSksIGJyZWFrcz01MCldLAogICAgIHBjaD0yMCwgeWxhYj0iICIsIHhsYWI9IlJpY2ggRmFjdG9yIiwgbWFpbj0iUGF0aHdheXMgRW5yaWNoZWQiLAogICAgIHhsaW09YygwLCAwLjQpKQpheGlzKHNpZGU9MiwgYXQ9MToyOCwgbGFiZWxzPWFzLmNoYXJhY3RlcihMQXBhdGh3YXlzJFBhdGh3YXkpLCBsYXM9MiwgY2V4LmF4aXM9MC44KQpheGlzKHNpZGU9MSwgdGljaz1MQXBhdGh3YXlzJFJpY2guRmFjdG9yLCBwb3M9MC40KQpgYGAKCiMjIyBHTyBMQQoKYGBge3IsIGV2YWw9RkFMU0V9CkdPTEFwYXRod2F5cyA8LSByZWFkLnRhYmxlKCJjc3YvQ3l0b3NjYXBlIFBhdGh3YXlzL0dPIEJQIExBIHdob2xlIG5ldHdvcmsudHh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyPVRSVUUsIHNlcD0nXHQnKQpHT0xBcGF0aHdheXMgPC0gR09MQXBhdGh3YXlzW29yZGVyKEdPTEFwYXRod2F5cyRwLlZhbHVlLCBkZWNyZWFzaW5nPVRSVUUpLCBdCiMjcGxvdCB4IHYuIHksIGNoYW5nZSBzaXplLCBhc3NpZ24gY29sb3IgdG8gcC12YWx1ZQpjb2xvclJhbXAgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJ0dXJxdW9pc2UxIiwgIm1lZGl1bWJsdWUiKSkoNTApCnBhcihtYXI9Yyg1LCAyMCwgMywgOCkpCnBsb3QoR09MQXBhdGh3YXlzJFJpY2guRmFjdG9yLCBjKDE6NTcpLCBheGVzPUYsCiAgICAgcGFuZWwuZmlyc3Q9YWJsaW5lKGg9MTo1Nywgdj1zZXEoMC4xLCAwLjUsIDAuMSksIGNvbD0iZ3JleTkwIiksCiAgICAgY2V4PWFzLm51bWVyaWMoR09MQXBhdGh3YXlzJEdlbmUuTnVtYmVyKSAvIDEwLAogICAgIGNvbD1jb2xvclJhbXBbY3V0KGFzLm51bWVyaWMoR09MQXBhdGh3YXlzJHAuVmFsdWUpLCBicmVha3M9NTApXSwKICAgICBwY2g9MjAsIHlsYWI9IiAiLCB4bGFiPSJSaWNoIEZhY3RvciIsIG1haW49IlBhdGh3YXlzIEVucmljaGVkIiwKICAgICB4bGltPWMoMCwgMC41KSkKYXhpcyhzaWRlPTIsYXQ9MTo1NywgbGFiZWxzPWFzLmNoYXJhY3RlcihHT0xBcGF0aHdheXMkUGF0aHdheSksIGxhcz0yLCBjZXguYXhpcz0wLjgpCmF4aXMoc2lkZT0xLCB0aWNrPUdPTEFwYXRod2F5cyRSaWNoLkZhY3RvciwgcG9zPTAuNCkKYGBgCgojIyMgR08gTFAKCmBgYHtyLCBldmFsPUZBTFNFfQpHT0xQcGF0aHdheXMgPC0gcmVhZC50YWJsZSgiY3N2L0N5dG9zY2FwZSBQYXRod2F5cy9HT19CUF9MUHZMUFMudHh0IiwgaGVhZGVyPVRSVUUsIHNlcD0iXHQiKQpHT0xQcGF0aHdheXMgPC0gR09MUHBhdGh3YXlzW29yZGVyKEdPTFBwYXRod2F5cyRwLlZhbHVlLCBkZWNyZWFzaW5nPVRSVUUpLCBdCgpjb2xvclJhbXAgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJ0dXJxdW9pc2UxIiwgIm1lZGl1bWJsdWUiKSkoNTApCnBhcihtYXI9Yyg1LCAxOCwgMywgOCkpCnBsb3QoR09MUHBhdGh3YXlzJFJpY2guRmFjdG9yLCBjKDE6MzUpLCBheGVzPUZBTFNFLAogICAgIHBhbmVsLmZpcnN0PWFibGluZShoPTE6MzUsIHY9c2VxKDAuMSwgMC42LCAwLjEpLCBjb2w9ImdyZXk5MCIpLAogICAgIGNleD1hcy5udW1lcmljKEdPTFBwYXRod2F5cyRHZW5lLk51bWJlcikgLyAyMCwKICAgICBjb2w9Y29sb3JSYW1wW2N1dChhcy5udW1lcmljKEdPTFBwYXRod2F5cyRwLlZhbHVlKSwgYnJlYWtzPTUwKV0sCiAgICAgcGNoPTIwLCB5bGFiPSIgIiwgeGxhYj0iUmljaCBGYWN0b3IiLCBtYWluPSJQYXRod2F5cyBFbnJpY2hlZCIsCiAgICAgeGxpbT1jKDAsIDAuNikpCmF4aXMoc2lkZT0yLCBhdD0xOjM1LCBsYWJlbHM9YXMuY2hhcmFjdGVyKEdPTFBwYXRod2F5cyRQYXRod2F5KSwgbGFzPTIsIGNleC5heGlzPTAuNSkKYXhpcyhzaWRlPTEsIHRpY2s9R09MUHBhdGh3YXlzJFJpY2guRmFjdG9yLCBwb3M9MC40KQpgYGAKCiMgVm9sY2FubyBwbG90IE1fTFBTXzQgdiBNX0xQXzQKCiMjIEZpZ3VyZSAzQiB0b3AtbGVmdAoKYGBge3IgZmlyc3Rfdm9sY2Fub30KcmVzIDwtIHJlYWQuY3N2KCJjc3YvdG9wVGFiX01fTFBTdk1fTFBfQ0RTX2xpbW1hYmF0Y2hjb3JyZWN0aW9uXzIwMTcxMTIwcmV2LmNzdiIsCiAgICAgICAgICAgICAgICBoZWFkZXI9VFJVRSkKaGVhZChyZXMpCndpdGgocmVzLCBwbG90KGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsCiAgICAgICAgICAgICAgIHBjaD0yMCwgbWFpbj0iVm9sY2FubyBwbG90IE1fTFBTIHYgTV9MUCIsIHhsaW09YygtNywgNykpKQojIyBBZGQgY29sb3JlZCBwb2ludHM6IHJlZCBpZiBwYWRqPDAuMDUsIG9yYW5nZSBvZiBsb2cyRkM+MSwgZ3JlZW4gaWYgYm90aCkKd2l0aChzdWJzZXQocmVzLCBhZGouUC5WYWwgPCAwLjA1ICksIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjaD0yMCwgY29sPSJ2aW9sZXRyZWQyIikpCndpdGgoc3Vic2V0KHJlcywgYWJzKGxvZ0ZDKSA+IDEpLCBwb2ludHMobG9nRkMsIC1sb2cxMChQLlZhbHVlKSwgY2V4PTAuOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2g9MjAsIGNvbD0ib3JhbmdlIikpCndpdGgoc3Vic2V0KHJlcywgYWRqLlAuVmFsIDwgMC4wNSAmIGFicyhsb2dGQykgPiAxKSwKICAgICBwb2ludHMobG9nRkMsIC1sb2cxMChQLlZhbHVlKSwKICAgICAgICAgICAgY2V4PTAuOCwgcGNoPTIwLCBjb2w9InR1cnF1b2lzZTMiKSkKZGV2LmNvcHkocG5nLCAiaW1hZ2VzL1ZvbGNhbm9QbG90X01fTFBTX3ZzX01fTFAucG5nIiwgd2lkdGg9NzAwLCBoZWlnaHQ9NzAwKQpkZXYub2ZmKCkKYGBgCgojIyMgVGhlIG51bWJlciBvZiB1cCBzaWduaWZpY2FudCBnZW5lcwoKYGBge3IgcHJpbnRfbnVtYmVyc191cDF9CnNpZ191cF9pZHggPC0gcmVzWywgImFkai5QLlZhbCJdIDwgMC4wNSAmIHJlc1ssICJsb2dGQyJdID4gMQpzdW0oc2lnX3VwX2lkeCkKc2lnX3VwX2lkcyA8LSByZXNbc2lnX3VwX2lkeCwgIklEIl0KaGVhZChzaWdfdXBfaWRzKQptX2xwc19tX2xwX3VwX2lkcyA8LSBzaWdfdXBfaWRzCmBgYAoKIyMjIFRoZSBudW1iZXIgb2YgZG93biBzaWduaWZpY2FudCBnZW5lcwoKYGBge3IgcHJpbnRfbnVtYmVyc19kb3duMX0Kc2lnX2Rvd25faWR4IDwtIHJlc1ssICJhZGouUC5WYWwiXSA8IDAuMDUgJiByZXNbLCAibG9nRkMiXSA8IC0xCnN1bShzaWdfZG93bl9pZHgpCnNpZ19kb3duX2lkcyA8LSByZXNbc2lnX2Rvd25faWR4LCAiSUQiXQpoZWFkKHNpZ19kb3duX2lkcykKbV9scHNfbV9scF9kb3duX2lkcyA8LSBzaWdfZG93bl9pZHMKYGBgCgojIFZvbGNhbm8gcGxvdCBNX0xQU180IHYgTV9MQV80CgojIyBGaWd1cmUgM0IgdG9wLXJpZ2h0CgpgYGB7ciBzZWNvbmRfdm9sY2Fub30KcmVzIDwtIHJlYWQuY3N2KGxwc19sYV90YWJsZSkKaGVhZChyZXMpCndpdGgocmVzLCBwbG90KGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsIHBjaD0yMCwKICAgICAgICAgICAgICAgbWFpbj0iVm9sY2FubyBwbG90IE1fTFBTIHYgTV9MQSIsIHhsaW09YygtNywgNykpKQojIyBBZGQgY29sb3JlZCBwb2ludHM6IHJlZCBpZiBwYWRqPDAuMDUsIG9yYW5nZSBvZiBsb2cyRkM+MSwgZ3JlZW4gaWYgYm90aCkKd2l0aChzdWJzZXQocmVzLCBhZGouUC5WYWwgPCAwLjA1ICksIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjaD0yMCwgY29sPSJ2aW9sZXRyZWQyIikpCndpdGgoc3Vic2V0KHJlcywgYWJzKGxvZ0ZDKSA+IDEpLCBwb2ludHMobG9nRkMsIC1sb2cxMChQLlZhbHVlKSwgY2V4PTAuOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2g9MjAsIGNvbD0ib3JhbmdlIikpCndpdGgoc3Vic2V0KHJlcywgYWRqLlAuVmFsPC4wNSAmIGFicyhsb2dGQykgPiAxKSwKICAgICBwb2ludHMobG9nRkMsIC1sb2cxMChQLlZhbHVlKSwKICAgICAgICAgICAgY2V4PTAuOCwgcGNoPTIwLCBjb2w9InR1cnF1b2lzZTMiKSkKZGV2LmNvcHkocG5nLCAiaW1hZ2VzL1ZvbGNhbm9QbG90X01fTFBTX3ZfTV9MQS5wbmciLCB3aWR0aD03MDAsIGhlaWdodD03MDApCmRldi5vZmYoKQpgYGAKCiMjIyBUaGUgbnVtYmVyIG9mIHVwIHNpZ25pZmljYW50IGdlbmVzCgpgYGB7ciBwcmludF9udW1iZXJzX3VwMn0Kc2lnX3VwX2lkeCA8LSByZXNbLCAiYWRqLlAuVmFsIl0gPCAwLjA1ICYgcmVzWywgImxvZ0ZDIl0gPiAxCnN1bShzaWdfdXBfaWR4KQpzaWdfdXBfaWRzIDwtIHJlc1tzaWdfdXBfaWR4LCAiSUQiXQpoZWFkKHNpZ191cF9pZHMpCm1fbHBzX21fbGFfc2lnX2lkcyA8LSBzaWdfdXBfaWRzCmBgYAoKIyMjIFRoZSBudW1iZXIgb2YgZG93biBzaWduaWZpY2FudCBnZW5lcwoKYGBge3IgcHJpbnRfbnVtYmVyc19kb3duMn0Kc2lnX2Rvd25faWR4IDwtIHJlc1ssICJhZGouUC5WYWwiXSA8IDAuMDUgJiByZXNbLCAibG9nRkMiXSA8IC0xCnN1bShzaWdfZG93bl9pZHgpCnNpZ19kb3duX2lkcyA8LSByZXNbc2lnX2Rvd25faWR4LCAiSUQiXQpoZWFkKHNpZ19kb3duX2lkcykKYGBgCgojIFZvbGNhbm8gcGxvdCBHTV9MUFNfNCB2IEdNX0xBXzQKCiMjIEZpZ3VyZSAzQiBib3R0b20tcmlnaHQKCmBgYHtyIHRoaXJkX3ZvbGNhbm99CnJlcyA8LSByZWFkLmNzdihnbV9scHNfbGFfdGFibGUpCmhlYWQocmVzKQp3aXRoKHJlcywgcGxvdChsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LCBwY2g9MjAsCiAgICAgICAgICAgICAgIG1haW49IlZvbGNhbm8gcGxvdCBHTV9MUFNfNCB2IEdNX0xBXzQiLCB4bGltPWMoLTcsIDcpKSkKIyMgQWRkIGNvbG9yZWQgcG9pbnRzOiByZWQgaWYgcGFkajwwLjA1LCBvcmFuZ2Ugb2YgbG9nMkZDPjEsIGdyZWVuIGlmIGJvdGgpCndpdGgoc3Vic2V0KHJlcywgYWRqLlAuVmFsIDwgMC4wNSksIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNoPTIwLCBjb2w9InZpb2xldHJlZDIiKSkKd2l0aChzdWJzZXQocmVzLCBhYnMobG9nRkMpID4gMSksIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjaD0yMCwgY29sPSJvcmFuZ2UiKSkKd2l0aChzdWJzZXQocmVzLCBhZGouUC5WYWwgPCAwLjA1ICYgYWJzKGxvZ0ZDKSA+IDEpLAogICAgIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LCBwY2g9MjAsIGNvbD0idHVycXVvaXNlMyIpKQpkZXYuY29weShwbmcsICJpbWFnZXMvVm9sY2Fub1Bsb3QgR01fTFBTIHYgR01fTEEiLCB3aWR0aD03MDAsIGhlaWdodD03MDApCmRldi5vZmYoKQpgYGAKCiMjIyBUaGUgbnVtYmVyIG9mIHVwIHNpZ25pZmljYW50IGdlbmVzCgpgYGB7ciBwcmludF9udW1iZXJzX3VwM30Kc2lnX3VwX2lkeCA8LSByZXNbLCAiYWRqLlAuVmFsIl0gPCAwLjA1ICYgcmVzWywgImxvZ0ZDIl0gPiAxCnN1bShzaWdfdXBfaWR4KQpzaWdfdXBfaWRzIDwtIHJlc1tzaWdfdXBfaWR4LCAiSUQiXQpoZWFkKHNpZ191cF9pZHMpCmBgYAoKIyMjIFRoZSBudW1iZXIgb2YgZG93biBzaWduaWZpY2FudCBnZW5lcwoKYGBge3IgcHJpbnRfbnVtYmVyc19kb3duM30Kc2lnX2Rvd25faWR4IDwtIHJlc1ssICJhZGouUC5WYWwiXSA8IDAuMDUgJiByZXNbLCAibG9nRkMiXSA8IC0xCnN1bShzaWdfZG93bl9pZHgpCnNpZ19kb3duX2lkcyA8LSByZXNbc2lnX2Rvd25faWR4LCAiSUQiXQpoZWFkKHNpZ19kb3duX2lkcykKYGBgCgojIFZvbGNhbm8gcGxvdCBHTV9MUFNfNCB2IEdNX0xQXzQKCiMjIEZpZ3VyZSAzQiBib3R0b20tbGVmdAoKU28sIGl0IGFwcGVhcnMgSSBnZXQgdGhlIGludmVyc2Ugb2Ygd2hhdCBpcyBpbiB0aGUgZmlndXJlLiAgRGlkIHRoZSBjb250cmFzdCBnZXQgcmV2ZXJzZWQ/CgpJIHdlbnQgYmFjayB0byB0aGUgc2VjdGlvbiB3aGljaCBkZWZpbmVzIHRoaXMsIGl0IGhhcyB0aGUgaGVhZGluZwonR01fTFBTX3ZfR01fTFAnIGFuZCB0aGUgY29udHJhc3QgYXBwZWFycyB0byBtZSB0byBiZSBjb3JyZWN0LiAgQXQgbGVhc3QgaXQgaXMKd3JpdHRlbiBsaWtlIHRoaXM6Cgo8Y29kZT4KR01fTFBTLkdNX0xQLmNvbnRyLm1hdCA8LSBtYWtlQ29udHJhc3RzKEdNX0xQU3ZHTV9MUD0oKGNvbmRHTV9MUFMtY29uZEdNX05TKS0oY29uZEdNX0xQLWNvbmRHTV9OUykpLApsZXZlbHM9diRkZXNpZ24pCjwvY29kZT4KCk15IGluY2xpbmF0aW9uIGlzIHRoZXJlZm9yZSB0aGF0IHRoaXMgZ290IGZsaXBwZWQ/CgpgYGB7ciBmb3VydGhfdm9sY2Fub30KcmVzIDwtIHJlYWQuY3N2KGdtX2xwc19scF90YWJsZSkKaGVhZChyZXMpCndpdGgocmVzLCBwbG90KGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsIHBjaD0yMCwKICAgICAgICAgICAgICAgbWFpbj0iVm9sY2FubyBwbG90IEdNX0xQUyB2IEdNX0xQIiwgeGxpbT1jKC03LCA3KSkpCiMjIEFkZCBjb2xvcmVkIHBvaW50czogcmVkIGlmIHBhZGo8MC4wNSwgb3JhbmdlIG9mIGxvZzJGQz4xLCBncmVlbiBpZiBib3RoKQp3aXRoKHN1YnNldChyZXMsIGFkai5QLlZhbCA8IDAuMDUgKSwgcG9pbnRzKGxvZ0ZDLCAtbG9nMTAoUC5WYWx1ZSksIGNleD0wLjgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNoPTIwLCBjb2w9InZpb2xldHJlZDIiKSkKd2l0aChzdWJzZXQocmVzLCBhYnMobG9nRkMpID4gMSksIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjaD0yMCwgY29sPSJvcmFuZ2UiKSkKd2l0aChzdWJzZXQocmVzLCBhZGouUC5WYWwgPCAwLjA1ICYgYWJzKGxvZ0ZDKSA+IDEpLAogICAgIHBvaW50cyhsb2dGQywgLWxvZzEwKFAuVmFsdWUpLCBjZXg9MC44LCBwY2g9MjAsIGNvbD0idHVycXVvaXNlMyIpKQpkZXYuY29weShwbmcsICJpbWFnZXMvVm9sY2Fub1Bsb3QgR01fTFBTIHYgR01fTFAiLCB3aWR0aD03MDAsIGhlaWdodD03MDApCmRldi5vZmYoKQpgYGAKCiMjIyBUaGUgbnVtYmVyIG9mIHVwIHNpZ25pZmljYW50IGdlbmVzCgpgYGB7ciBwcmludF9udW1iZXJzX3VwNH0Kc2lnX3VwX2lkeCA8LSByZXNbLCAiYWRqLlAuVmFsIl0gPCAwLjA1ICYgcmVzWywgImxvZ0ZDIl0gPiAxCnN1bShzaWdfdXBfaWR4KQpzaWdfdXBfaWRzIDwtIHJlc1tzaWdfdXBfaWR4LCAiSUQiXQpoZWFkKHNpZ191cF9pZHMpCmBgYAoKIyMjIFRoZSBudW1iZXIgb2YgZG93biBzaWduaWZpY2FudCBnZW5lcwoKYGBge3IgcHJpbnRfbnVtYmVyc19kb3duNH0Kc2lnX2Rvd25faWR4IDwtIHJlc1ssICJhZGouUC5WYWwiXSA8IDAuMDUgJiByZXNbLCAibG9nRkMiXSA8IC0xCnN1bShzaWdfZG93bl9pZHgpCnNpZ19kb3duX2lkcyA8LSByZXNbc2lnX2Rvd25faWR4LCAiSUQiXQpoZWFkKHNpZ19kb3duX2lkcykKYGBgCgojIyMgRmlndXJlIDJCCgpJIHRoaW5rIHRoZSBjb2RlIEkgdXNlZCBmb3IgdGhlIHZlbm4gZGlhZ3JhbXMgaXMgaW4gdGhlIFJtYXJrZG93biBmaWxlIHRvd2FyZHMKdGhlIGVuZC4gIEhvd2V2ZXIsIEkgaGF2ZSAyIGZpbGVzIHNhdmVkIGZvciB0aGUgdmVubiBkaWFncmFtcyB0aGF0IGFyZSBkaWZmZXJlbnQKZnJvbSB3aGF0IEkgaGF2ZSBpbiBmaWd1cmUgMkIuICBJIHRoaW5rIEkgbmVlZCB0byBzd2FwIHRoZSBjdXJyZW50IDJCIHdpdGggdGhlCnZlbm4gZGlhZ3JhbXMgSSBoYXZlIGF0dGFjaGVkIGJlbG93IGJlY2F1c2UgdGhlIG51bWJlcnMgaGVyZSBtYXRjaCB3aXRoIHRoZQp2b2xjYW5vIHBsb3RzLiAgQXJlIHRoZXNlIHRoZSBudW1iZXJzIHlvdSBhcmUgZ2V0dGluZyBhbHNvPwoKIyMjIyBBdHRlbXB0IDEKClRoaXMgaXMganVzdCBwdWxsaW5nIHRoZSBNIExQL0xQUyBMQS9MUFMgc2lnbmlmaWNhbnQgZ2VuZXMuClRoaXMgYXBwZWFycyB0byBub3QgYmUgdGhlIGFuc3dlci4KCmBgYHtyIGZpZzJifQpscHNfcGdlX3NpZyA8LSBNX0xQUy5NX0xQLnNpZ0dlbmVzCnVwX2lkeCA8LSBscHNfcGdlX3NpZ1tbImxvZ0ZDIl1dID4gMApkb3duX2lkeCA8LSBscHNfcGdlX3NpZ1tbImxvZ0ZDIl1dIDwgMApscHNfcGdlX3VwX2lkcyA8LSBscHNfcGdlX3NpZ1t1cF9pZHgsICJJRCJdCmxwc19wZ2VfZG93bl9pZHMgPC0gbHBzX3BnZV9zaWdbZG93bl9pZHgsICJJRCJdCmxwc19hX3NpZyA8LSBNX0xQUy5NX0xBLnNpZ0dlbmVzCnVwX2lkeCA8LSBscHNfYV9zaWdbWyJsb2dGQyJdXSA+IDAKZG93bl9pZHggPC0gbHBzX2Ffc2lnW1sibG9nRkMiXV0gPCAwCmxwc19hX3VwX2lkcyA8LSBscHNfYV9zaWdbdXBfaWR4LCAiSUQiXQpscHNfYV9kb3duX2lkcyA8LSBscHNfYV9zaWdbZG93bl9pZHgsICJJRCJdCgp2X2RhdGEgPC0gbGlzdChscHNfcGdlX3VwX2lkcywgbHBzX2FfdXBfaWRzKQp2X2RhdGEgPC0gVmVubih2X2RhdGEsIFNldE5hbWVzPWMoIkxQUytQR0UyIiwgIkxQUytBZG8iKSwgbnVtYmVyT2ZTZXRzPTIpClZlbm5lcmFibGU6OnBsb3Qodl9kYXRhLCBkb1dlaWdodHM9RkFMU0UpCgp2X2RhdGEgPC0gbGlzdChscHNfcGdlX2Rvd25faWRzLCBscHNfYV9kb3duX2lkcykKdl9kYXRhIDwtIFZlbm4odl9kYXRhLCBTZXROYW1lcz1jKCJMUFMrUEdFMiIsICJMUFMrQWRvIiksIG51bWJlck9mU2V0cz0yKQpWZW5uZXJhYmxlOjpwbG90KHZfZGF0YSwgZG9XZWlnaHRzPUZBTFNFKQpgYGAKCiMjIyMgQXR0ZW1wdCAyCgpMZXRzIGFzc3VtZSB0aGVyZSBpcyBhIGhpbnQgaW4gdGhlIHRleHQgYW5kIHRoYXQgSSBzaG91bGQgcHVsbCBmcm9tIHRoZSB2b2xjYW5vCnBsb3QgbnVtYmVycyBmb3IgTSBMUC9MUFMgYW5kIE0gTEEvTFBTCgpgYGB7ciBhdHRlbXB0Mn0Kdl9kYXRhIDwtIFZlbm4obGlzdChtX2xwc19tX2xwX3VwX2lkcywgbV9scHNfbV9sYV91cF9pZHMpLAogICAgICAgICAgICAgICBTZXROYW1lcz1jKCJMUFMrUEdFMiIsICJMUFMrQWRvIikpClZlbm5lcmFibGU6OnBsb3Qodl9kYXRhKQoKdl9kYXRhIDwtIFZlbm4obGlzdChtX2xwc19tX2xwX2Rvd25faWRzLCBtX2xwc19tX2xhX2Rvd25faWRzKSwKICAgICAgICAgICAgICAgU2V0TmFtZXM9YygiTFBTK1BHRTIiLCAiTFBTK0FkbyIpKQpWZW5uZXJhYmxlOjpwbG90KHZfZGF0YSkKYGBgCgojIyMjIENvcnJlbGF0aW9uIG9mIGxvZ0ZDcyBmb3IgTFAvTFBTIGFuZCBMQS9MUFMKCk9uZSByZXF1ZXN0IGluIG91ciBjb252ZXJzYXRpb24gd2FzIHRvIGhhdmUgYSBjYWxjdWxhdGlvbiBvZiB0aGUgY29ycmVsYXRpb24KY29lZmZpY2llbnQgYmV0d2VlbiB0aGUgTFAvTFBTIGFuZCBMQS9MUFMgY29tcGFyaXNvbnMuCgpgYGB7ciBscGxhX2Nvcn0KbV9jb3JfdGFibGUgPC0gbWVyZ2UoTV9MUFMuTV9MUC50b3BUYWIsIE1fTFBTLk1fTEEudG9wVGFiLCBieT0iSUQiKQpjb3IudGVzdCh4PW1fY29yX3RhYmxlW1sibG9nRkMueCJdXSwgeT1tX2Nvcl90YWJsZVtbImxvZ0ZDLnkiXV0pCgpnbV9jb3JfdGFibGUgPC0gbWVyZ2UoR01fTFBTLkdNX0xQLnRvcFRhYiwgR01fTFBTLkdNX0xBLnRvcFRhYiwgYnk9IklEIikKY29yLnRlc3QoeD1nbV9jb3JfdGFibGVbWyJsb2dGQy54Il1dLCB5PWdtX2Nvcl90YWJsZVtbImxvZ0ZDLnkiXV0pCgptX3NjYXR0ZXIgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihtX2Nvcl90YWJsZVssIGMoImxvZ0ZDLngiLCAibG9nRkMueSIpXSkKbV9zY2F0dGVyJHNjYXR0ZXIKCmdtX3NjYXR0ZXIgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihnbV9jb3JfdGFibGVbLCBjKCJsb2dGQy54IiwgImxvZ0ZDLnkiKV0pCmdtX3NjYXR0ZXIkc2NhdHRlcgpgYGAK