1 TODO:

  1. Ensure that no variance partition includes biopsies beyond some initial cursory.

2 Changelog

  • Set input data to the new 202212 dataset. Looking for some messed up colors.
  • Reasonably certain I figured out the color discrepency. I was letting the eosinophil dataset choose its own colors rather than force them to be the same as the other cell types; even though I thought I told them to explicitly set their colors to be the same as the others. I think the changes I made in datasets.Rmd fixed this, so I regenerated the rda/etc in that document and am now testing the colors here.

3 Introduction

Moving all of the visualization and diagnostic tasks to this document. The metadata and gene annotation data collection tasks are therefore in tmrc3_data_structures.Rmd. The reasons for some of the data structure creation in that document is made clear here.

4 Notes

  1. Lesion vs Ulcer: Ulcer is the base of the crater of the lesion observed. The lesion is this, the border, and any region with signs of inflammation. It is not known if these metrics are equivalent, or if one is better than the other. Some people do not have ulcers and therefore in those cases we can only really consider the lesion size. E.g. most people in Colombia have ulcers, which are the cratered sore; however there are a few people who have a ‘plaque’ or some form of smaller, less intrusive presentation – these are still cutaneous.

Thus the lesion size is the more inclusive metric, but potentially ulcer size is more informative? Any inflammation in the skin causes the person to be defined as failure.

  1. Note from Maria Adelaida: Some chemokines are suggestive of Eosinophil recruitment.

4.1 Goals

These samples are from patients who either successfully cleared a Leishmania panamensis infection following treatment, or did not. They include biopsies from each patient along with purifications for Monocytes, Neutrophils, and Eosinophils. When possible, this process was repeated over three visits; but some patients did not return for the second or third visit.

The over-arching goal is to look for attributes(most likely genes) which distinguish patients who do and do not cure the infection after treatment. If possible, these will be apparent on the first visit.

plot_legend(hs_expt)
## The colors used in the expressionset are: #7570B3, #1B9E77, #D95F02.

plot_nonzero(hs_expt)
## The following samples have less than 12968.8 genes.
##  [1] "TMRC30010" "TMRC30140" "TMRC30280" "TMRC30284" "TMRC30050" "TMRC30056"
##  [7] "TMRC30052" "TMRC30058" "TMRC30031" "TMRC30038" "TMRC30265"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 210 samples.
## These samples have an average 45.18 CPM coverage and 14385 genes observed, ranging from 7647 to
## 16739.
## Warning: ggrepel: 194 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

4.2 Figure S2 + 1: Non-zero genes after sample filtering

The following plot is essentially identical to the previous with two exceptions:

  1. The samples with too few genes (11,000 currently) are gone. In the current iteration of the datasets Rmd, this comprises either two or three samples.
  2. The samples are colored by cure(purple)/fail(yellow)
plot_nonzero(tc_valid, plot_labels = FALSE)
## The following samples have less than 12968.8 genes.
## [1] "TMRC30140" "TMRC30280" "TMRC30284" "TMRC30056" "TMRC30058" "TMRC30031"
## [7] "TMRC30265"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## Not putting labels on the plot.
## 
## A non-zero genes plot of 184 samples.
## These samples have an average 48.79 CPM coverage and 14466 genes observed, ranging from 11448 to
## 16739.

4.3 Quick picture before removing miltefosine samples

Maria Adelaida’s quote: “I would like one picture of all samples including the miltefosine so that I can keep in my mind why we removed them.”

5 PCA with both drugs

The following block will illustrate why we chose to remove the samples which were treated with miltefosine. The short reason: too few samples. The slightly longer reason: miltefosine has a different mode of action.

tc_expt_norm <- normalize_expt(hs_expt, filter = TRUE, norm = "quant",
                               convert = "cpm", transform = "log2") %>%
  set_expt_batches(fact = "drug")
## Removing 5168 low-count genes (14784 remaining).
## transform_counts: Found 858 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##    antimony miltefosine 
##         202           8
tc_expt_drug_pca <- plot_pca(tc_expt_norm, cis = NULL)
tc_expt_drug_pca <- plot_pca(tc_expt_norm)
tc_expt_drug_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure, lost
## Shapes are defined by antimony, miltefosine.

tc_expt_nb <- normalize_expt(hs_expt, filter = TRUE, convert = "cpm",
                             transform = "log2", batch = "svaseq") %>%
  set_expt_batches(fact = "drug")
## Removing 5168 low-count genes (14784 remaining).
## Setting 35726 low elements to zero.
## transform_counts: Found 35726 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##    antimony miltefosine 
##         202           8
tc_expt_drug_nb_pca <- plot_pca(tc_expt_nb)
tc_expt_drug_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure, lost
## Shapes are defined by antimony, miltefosine.

t_expt_drug <- subset_expt(hs_expt, subset = "clinic=='tumaco'")
## The samples excluded are: TMRC30009, TMRC30010, TMRC30015, TMRC30011, TMRC30012, TMRC30013, TMRC30156, TMRC30185, TMRC30186, TMRC30178, TMRC30179, TMRC30221, TMRC30222, TMRC30223, TMRC30224, TMRC30269, TMRC30148, TMRC30149, TMRC30253, TMRC30150, TMRC30140, TMRC30138, TMRC30176, TMRC30153, TMRC30151, TMRC30234, TMRC30235, TMRC30270, TMRC30225, TMRC30226, TMRC30227, TMRC30228, TMRC30229, TMRC30230, TMRC30231, TMRC30232, TMRC30233, TMRC30209, TMRC30210, TMRC30211, TMRC30212, TMRC30213, TMRC30216, TMRC30214, TMRC30215, TMRC30271, TMRC30273, TMRC30275, TMRC30272, TMRC30274, TMRC30276, TMRC30254, TMRC30255, TMRC30256, TMRC30277, TMRC30239, TMRC30240, TMRC30278, TMRC30279, TMRC30280, TMRC30257, TMRC30258, TMRC30281, TMRC30283, TMRC30284, TMRC30282, TMRC30285.
## subset_expt(): There were 210, now there are 143 samples.
t_expt_norm <- normalize_expt(t_expt_drug, filter = TRUE, norm = "quant",
                              convert = "cpm", transform = "log2") %>%
  set_expt_batches(fact = "drug")
## Removing 5698 low-count genes (14254 remaining).
## transform_counts: Found 388 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##    antimony miltefosine 
##         135           8
t_expt_drug_pca <- plot_pca(t_expt_norm)
t_expt_drug_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure, lost
## Shapes are defined by antimony, miltefosine.

t_expt_nb <- normalize_expt(t_expt_drug, filter = TRUE, convert = "cpm",
                             transform = "log2", batch = "svaseq") %>%
  set_expt_batches(fact = "drug")
## Removing 5698 low-count genes (14254 remaining).
## Setting 18887 low elements to zero.
## transform_counts: Found 18887 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##    antimony miltefosine 
##         135           8
t_expt_drug_nb_pca <- plot_pca(t_expt_nb)
t_expt_drug_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure, lost
## Shapes are defined by antimony, miltefosine.

6 Host Distributions/Visualizations of interest

The sets of samples used to visualize the data will also comprise the sets used when later performing the various differential expression analyses.

6.1 Global metrics

Start out with some initial metrics of all samples. The most obvious are plots of the numbers of non-zero genes observed, heatmaps showing the relative relationships among the samples, the relative library sizes, and some PCA. It might be smart to split the library sizes up across subsets of the data, because they have expanded too far to see well on a computer screen.

The most likely factors to query when considering the entire dataset are cure/fail, visit, and cell type. This is the level at which we will choose samples to exclude from future analyses.

plot_legend(tc_biopsies)
## The colors used in the expressionset are: #1B9E77, #7670B3, #E7298A.

plot_libsize(tc_biopsies)
## Library sizes of 18 samples, 
## ranging from 3,592,709 to 35,274,577.

plot_nonzero(tc_biopsies)
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 18 samples.
## These samples have an average 14.35 CPM coverage and 15702 genes observed, ranging from 15246 to
## 16366.

plot_libsize_prepost attempts to provide an idea about how much data is lost when low-count filtering the data.

The first plot it produces is a barplot of the number of reads removed by the filter from each sample. The second plot has two bars, the top bar is labeled with the number of low-count genes before the filter. The lower bar represents the number after the filter and is assumed to be quite low.

biopsy_prepost <- plot_libsize_prepost(tc_biopsies)
biopsy_prepost
## A comparison of the counts before and after filtering.
## The number of genes with low coverage changes by NA-NA genes.
## Warning: Using alpha for a discrete variable is not advised.

#biopsy_prepost$count_plot
#biopsy_prepost$lowgene_plot
## Minimum number of biopsy genes: ~ 14,000

plot_libsize(tc_eosinophils)
## Library sizes of 41 samples, 
## ranging from 7,223,543 to 252,496,897.

plot_nonzero(tc_eosinophils)
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 41 samples.
## These samples have an average 51.77 CPM coverage and 14599 genes observed, ranging from 13052 to
## 16739.
## Warning: ggrepel: 25 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

eosinophil_prepost <- plot_libsize_prepost(tc_eosinophils)
eosinophil_prepost[["count_plot"]]

eosinophil_prepost[["lowgene_plot"]]
## Warning: Using alpha for a discrete variable is not advised.

## Minimum number of eosinophil genes: ~ 13,500

plot_libsize(tc_monocytes)
## Library sizes of 63 samples, 
## ranging from 2,922,176 to 260,933,745.

plot_nonzero(tc_monocytes)
## The following samples have less than 12968.8 genes.
## [1] "TMRC30056"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 63 samples.
## These samples have an average 51.28 CPM coverage and 14542 genes observed, ranging from 11448 to
## 16512.
## Warning: ggrepel: 47 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

monocyte_prepost <- plot_libsize_prepost(tc_monocytes)
monocyte_prepost[["count_plot"]]

monocyte_prepost[["lowgene_plot"]]
## Warning: Using alpha for a discrete variable is not advised.

## Minimum number of monocyte genes: ~ 7,500 before setting the minimum.

plot_libsize(tc_neutrophils)
## Library sizes of 62 samples, 
## ranging from 4,642,715 to 224,886,922.

plot_nonzero(tc_neutrophils)
## The following samples have less than 12968.8 genes.
## [1] "TMRC30140" "TMRC30280" "TMRC30284" "TMRC30058" "TMRC30031" "TMRC30265"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 62 samples.
## These samples have an average 54.28 CPM coverage and 13941 genes observed, ranging from 11759 to
## 16401.
## Warning: ggrepel: 38 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

neutrophil_prepost <- plot_libsize_prepost(tc_neutrophils)
neutrophil_prepost[["count_plot"]]

neutrophil_prepost[["lowgene_plot"]]
## Warning: Using alpha for a discrete variable is not advised.

## Minimum number of neutrophil genes: ~ 10,000 before setting minimum coverage.

The above block just repeats the same two plots on a per-celltype basis: the number of reads observed / sample and a plot of observed genes with respect to coverage. I made some comments with my observations about the number of genes.

7 Seeking Confounded/Correlated factors in the metadata

One task we were uncertain of how to address: how best to consider the many factors provided in the metadata and whether or not they are hightly correlated or completely confounded. Theresa provided some suggestions about how we might measure the degree to which correlated variables might be a problem and decide which variables we can(not) include in our statistical models of the data when performing the differential expression analyses.

7.1 Correlated factors in the Tumaco+Cali data

I am going to implement this in a few steps, first I will do a cross-correlation of a relatively large array of variables in the data, then focus on a few which we suspect to be problematic.

initial_queries <- c("Sex", "Ethnicity", "Age", "Weight", "Height",
                     "Previously_Diagnosed", "Evolution_Time",
                     "Num_Active_Lesions", "V2_New_Lesions",
                     "V3_New_Lesions", "Adherence", "Therapeutic_Outcome_Final")
initial_df <- demographics_filtered[, initial_queries]
summary(initial_df)
##  Sex    Ethnicity      Age           Weight          Height   
##  1:24   1:14      Min.   :18.0   Min.   : 53.9   Min.   :152  
##  2: 5   2: 5      1st Qu.:25.0   1st Qu.: 59.0   1st Qu.:160  
##         3:10      Median :29.0   Median : 75.0   Median :166  
##                   Mean   :30.4   Mean   : 73.2   Mean   :167  
##                   3rd Qu.:36.0   3rd Qu.: 83.3   3rd Qu.:174  
##                   Max.   :51.0   Max.   :100.8   Max.   :183  
##                                                               
##  Previously_Diagnosed Evolution_Time  Num_Active_Lesions V2_New_Lesions
##  0:28                 Min.   : 2.00   Min.   :1.00       Min.   :0     
##  1: 1                 1st Qu.: 4.00   1st Qu.:1.00       1st Qu.:0     
##                       Median : 6.00   Median :2.00       Median :0     
##                       Mean   : 8.35   Mean   :2.55       Mean   :0     
##                       3rd Qu.:12.00   3rd Qu.:3.00       3rd Qu.:0     
##                       Max.   :21.00   Max.   :9.00       Max.   :0     
##                                                          NA's   :1     
##  V3_New_Lesions   Adherence     Therapeutic_Outcome_Final
##  Min.   :0      Min.   : 95.0   0:19                     
##  1st Qu.:0      1st Qu.:100.0   1:10                     
##  Median :0      Median :100.0   2: 0                     
##  Mean   :0      Mean   : 99.7   3: 0                     
##  3rd Qu.:0      3rd Qu.:100.0                            
##  Max.   :0      Max.   :100.0                            
##  NA's   :2
initial_numeric <- initial_df
for (f in colnames(initial_numeric)) {
  initial_numeric[[f]] <- as.numeric(as.factor(initial_numeric[[f]]))
}
initial_cross <- corr_cross(initial_numeric)
## Returning only the top 20. You may override with the 'top' argument
pp(file = "images/initial_crosscor.pdf")
## Warning in pp(file = "images/initial_crosscor.pdf"): The directory: images does
## not exist, will attempt to create it.
initial_cross
dev.off()
## png 
##   2
initial_cross

We should remove height and weight, but I wanted first to see that everything was working as expected. We also will want to exclude final outcome when searching for factors which are unsuitable for model inclusion.

model_test_df <- initial_df
model_test_df[["Weight"]] <- NULL
model_test_df[["Height"]] <- NULL
model_test_df[["Therapeutic_Outcome_Final"]] <- NULL
model_test_numeric <- initial_numeric
model_test_numeric[["Weight"]] <- NULL
model_test_numeric[["Height"]] <- NULL
model_test_numeric[["Therapeutic_Outcome_Final"]] <- NULL

test_cross <- corr_cross(model_test_numeric)
## Returning only the top 20. You may override with the 'top' argument
pp(file = "images/model_test_crosscor.pdf")
test_cross
dev.off()
## png 
##   2
test_cross

At this point we have some factors which are flagged as highly correlated. Keep this in mind when building models later.

7.2 Regression analyses vs outcome

Now examine a more limited set of likely interesting factors.

!!An important note: 202408!!

In the following block I changed the input from the full merged demographics by sample (e.g. there are multiple rows for each person coming from the combination of multiple visits/celltypes), to the one row/person found in the demographics data.

In addition, in my initial implementation, I did all analyses using linear regression; Neal kindly pointed out this is not optimal.

Finally, it is probably pretty obvious that this is my first foray into the usage of regression analyses vis a vis comparing various metadata factors and estimating their significance with respect to our outcome variable. Thus, I kind of fool around in some of the following blocks.

regression_queries <- c("Therapeutic_Outcome_Final", "Weight", "Sex",
                        "Clinic", "Ethnicity", "Age")
regression_df <- demographics_filtered[, regression_queries]
regression_numeric <- regression_df
for (f in colnames(regression_numeric)) {
  regression_numeric[[f]] <- as.numeric(as.factor(regression_numeric[[f]]))
}
cross_df <- regression_df
cross_df[["Therapeutic_Outcome_Final"]] <- NULL
cross_numeric <- regression_numeric
cross_numeric[["Therapeutic_Outcome_Final"]] <- NULL

regression_cross <- corr_cross(cross_df, type = 1)
pp(file = "images/weight_sex_clinic_ethnicity_age_factor_crosscor.pdf")
regression_cross
dev.off()
## png 
##   2
regression_cross

The following is the version which we believe to be the most appropriate for the reader in a supplemental ~S1

regression_cross_numeric <- corr_cross(cross_numeric, type = 1)
pp(file = "figures/weight_sex_clinic_ethnicity_age_numeric_crosscor.svg")
regression_cross_numeric
dev.off()
## png 
##   2
regression_cross_numeric

7.2.1 Copy these with only the Tumaco people

tumaco_idx <- regression_numeric[["Clinic"]] == "2"
t_regression_numeric <- regression_numeric[tumaco_idx, ]
t_regression_df <- regression_df[tumaco_idx, ]

Similarly, when we look only at Tumaco, this will also be used in figure ~S1

t_regression_queries <- c("Weight", "Sex", "Ethnicity", "Age")
t_cross_df <- t_regression_numeric[, t_regression_queries]
t_regression_cross <- corr_cross(t_cross_df)
pp(file = "figures/tumaco_weight_sex_ethnicity_age_numeric_crosscor.svg")
t_regression_cross
dev.off()
## png 
##   2
t_regression_cross

Discussion with Maria Adelaida and Neal: 202408

There was a brief discussion regarding how we get to the numeric correlations in the cross correlation plot.

Najib wants to query the difference between the individual factor table and the various mixed model regression values.

Why do linear regression vs. logistical regression?

Multilevel regression vs. multiple regression:

multilevel would be used when there is a nested structure to the experimental design.

multiple regression: applying multiple factors to the regression.

Save confusion by explicitly stating multi-variable. For the purposes of this discussion we will avoid any multilevel regression because our experimental design isn’t crazytown.

“The main puzzle”: How did sex appear as a strong effect in the regression when we performed the wilcox test? It may be that the model used is inappropriate.

Najib query: when is a mixed effect model appropriate? lme4 and multilevel are more closely related and used when there are both fixed and random effects in the model. It is likely that if a multilevel model is not appropriate, then a mixed effect is also not appropriate (e.g. don’t use lmer/lme4).

regression_tests <- c("Age", "Clinic", "Ethnicity", "Sex", "Weight")
lm_regression_demographics <- extract_linear_regression(
  regression_numeric, query = "Therapeutic_Outcome_Final", factors = regression_tests,
  excel = glue("excel/numeric_demographics_regression_final_sex_clinic_ethnicity_age-v{ver}.xlsx"))
## Adding: Age
## Adding: Clinic
## Adding: Ethnicity
## Adding: Sex
## Adding: Weight
## Start:  AIC=-7.5
## scale(Therapeutic_Outcome_Final) ~ scale(Age) + scale(Clinic) + 
##     scale(Ethnicity) + scale(Sex) + scale(Weight)
## 
##                    Df Sum of Sq  RSS   AIC
## - scale(Sex)        1     0.316 15.1 -8.89
## - scale(Clinic)     1     0.593 15.4 -8.37
## - scale(Weight)     1     0.882 15.7 -7.83
## - scale(Age)        1     0.933 15.7 -7.73
## <none>                          14.8 -7.50
## - scale(Ethnicity)  1     1.107 15.9 -7.41
## 
## Step:  AIC=-8.89
## scale(Therapeutic_Outcome_Final) ~ scale(Age) + scale(Clinic) + 
##     scale(Ethnicity) + scale(Weight)
## 
##                    Df Sum of Sq  RSS   AIC
## - scale(Age)        1     0.620 15.7 -9.73
## - scale(Clinic)     1     0.693 15.8 -9.59
## <none>                          15.1 -8.89
## - scale(Weight)     1     1.251 16.4 -8.59
## - scale(Ethnicity)  1     2.095 17.2 -7.13
## 
## Step:  AIC=-9.73
## scale(Therapeutic_Outcome_Final) ~ scale(Clinic) + scale(Ethnicity) + 
##     scale(Weight)
## 
##                    Df Sum of Sq  RSS    AIC
## - scale(Weight)     1      0.89 16.6 -10.12
## <none>                          15.7  -9.73
## - scale(Clinic)     1      1.34 17.1  -9.36
## - scale(Ethnicity)  1      5.30 21.0  -3.31
## 
## Step:  AIC=-10.12
## scale(Therapeutic_Outcome_Final) ~ scale(Clinic) + scale(Ethnicity)
## 
##                    Df Sum of Sq  RSS    AIC
## - scale(Clinic)     1      0.78 17.4 -10.79
## <none>                          16.6 -10.12
## - scale(Ethnicity)  1      7.46 24.1  -1.38
## 
## Step:  AIC=-10.79
## scale(Therapeutic_Outcome_Final) ~ scale(Ethnicity)
## 
##                    Df Sum of Sq  RSS    AIC
## <none>                          17.4 -10.79
## - scale(Ethnicity)  1      10.6 28.0   0.98
pp(file = "figures/demographics_only_linear_regression.svg")
lm_regression_demographics[["forest"]]
dev.off()
## png 
##   2
lm_regression_demographics[["forest"]]

lm_regression_demographics[["summary"]]
## # A tibble: 6 x 7
##   term              estimate std.error statistic p.value conf.low conf.high
##   <chr>                <dbl>     <dbl>     <dbl>   <dbl>    <dbl>     <dbl>
## 1 (Intercept)      -1.36e-16     0.149 -9.11e-16   1.00    -0.308     0.308
## 2 scale(Age)       -3.08e- 1     0.256 -1.20e+ 0   0.241   -0.838     0.221
## 3 scale(Clinic)     1.76e- 1     0.184  9.60e- 1   0.347   -0.204     0.556
## 4 scale(Ethnicity) -3.03e- 1     0.231 -1.31e+ 0   0.203   -0.780     0.175
## 5 scale(Sex)       -1.40e- 1     0.199 -7.01e- 1   0.490   -0.552     0.273
## 6 scale(Weight)     2.06e- 1     0.176  1.17e+ 0   0.254   -0.158     0.571

The following will be used as supplemental figures as well, providing a delineation between a multi-variable logistic regression and multiple single variable regressions.

log_regression_demographics <- extract_logistic_regression(
  regression_df, query = "Therapeutic_Outcome_Final", factors = regression_tests,
  excel = glue("excel/tc_multivariable_logistic_regression-v{ver}.xlsx"))
## Adding: Age
## Adding: Clinic
## Adding: Ethnicity
## Adding: Sex
## Adding: Weight
## Waiting for profiling to be done...
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning in extract_logistic_regression(regression_df, query =
## "Therapeutic_Outcome_Final", : Dropped the row(s):
## -17.78979684901013063.02111299434-0.0058079249841080.995365972377391NA281.856435017743Ethnicity3
## from plotting.
pp(file = glue("figures/tc_multivariable_logistic_regression-v{ver}.svg"))
log_regression_demographics[["forest"]]
dev.off()
## png 
##   2
log_regression_demographics[["forest"]]

log_regression_demographics[["summary"]]
##               Estimate Std. Error   z value Pr(>|z|) conf.low conf.high
## (Intercept)    -1.0167     1.3772 -0.738214   0.4604  -4.3042    1.6516
## scale(Age)     -1.7014     1.3732 -1.238973   0.2154  -4.8823    0.7961
## Clinic2         0.8858     1.6012  0.553182   0.5801  -2.3409    4.4566
## Ethnicity2     -0.3151     1.8092 -0.174152   0.8617  -3.9818    3.9086
## Ethnicity3    -17.7898  3063.0211 -0.005808   0.9954       NA  281.8564
## Sex2           -2.0006     1.9973 -1.001689   0.3165  -6.4702    1.9663
## scale(Weight)   0.8402     0.7007  1.198991   0.2305  -0.4133    2.4429
##                        term
## (Intercept)     (Intercept)
## scale(Age)       scale(Age)
## Clinic2             Clinic2
## Ethnicity2       Ethnicity2
## Ethnicity3       Ethnicity3
## Sex2                   Sex2
## scale(Weight) scale(Weight)
tc_log_iterative_regression_demographics <- iterate_logistic_regression(
  regression_df, query = "Therapeutic_Outcome_Final", factors = regression_tests,
  excel = glue("excel/tc_simple_logistic_regression.xlsx"))
## Adding: Age
## Waiting for profiling to be done...
## Adding: Clinic
## Waiting for profiling to be done...
## Adding: Ethnicity
## Waiting for profiling to be done...
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Adding: Sex
## Waiting for profiling to be done...
## Adding: Weight
## Waiting for profiling to be done...
## Warning in iterate_logistic_regression(regression_df, query =
## "Therapeutic_Outcome_Final", : Dropped the row(s):
## -20.15385518341423400.71754346222-0.005926353755006620.99527148151595NA257.314594007577Ethnicity3
## from plotting.
pp(file = glue("figures/tc_simple_logistic_regression-v{ver}.svg"))
tc_log_iterative_regression_demographics[["forest"]]
dev.off()
## png 
##   2
tc_log_iterative_regression_demographics[["forest"]]

tc_log_iterative_regression_demographics[["summary"]]
##             estimate std_error         z    pr_z conf_low conf_high       term
## Age         -0.19383 8.181e-02 -2.369384 0.01782 -0.38559  -0.05527        Age
## Clinic2      2.09186 1.150e+00  1.819329 0.06886  0.15722   5.10546    Clinic2
## Ethnicity2  -1.97408 1.249e+00 -1.579967 0.11411 -5.09744   0.23233 Ethnicity2
## Ethnicity3 -20.15386 3.401e+03 -0.005926 0.99527       NA 257.31459 Ethnicity3
## Sex2        -0.87547 1.195e+00 -0.732673 0.46376 -3.93063   1.22279       Sex2
## Weight       0.02891 2.953e-02  0.978999 0.32758 -0.02824   0.09058     Weight

Discussion of regression with Neal:

The creation of correct models, the forest plots above were created from a model that looks like ~ 0 + age + sex + clinic + whatever… Neal is building (I think) toward a conclusion which says that some of these factors are confounded and may need to be separated.

rule of ten: for each variable in a logistic regression or survival analysis, one wants to have 10 more entries in the input data. Thus we ideally would have 50 cures and 50 fails in order to have this many factors in the model. In this data we only have ~ 30 separate people, so this is not tenable.

I think therefore the most likely thing to build in a plot like this forest plot would be 1 row each variable using its result from a x ~ y alone.

7.2.2 Repeat with only Tumaco

t_regression_tests <- c("Age", "Ethnicity", "Sex", "Weight")
t_lm_regression_demographics <- extract_linear_regression(
  t_regression_numeric, query = "Therapeutic_Outcome_Final", factors = t_regression_tests,
  excel = glue("excel/numeric_demographics_regression_tumaco_final_sex_ethnicity_age-v{ver}.xlsx"))
## Adding: Age
## Adding: Ethnicity
## Adding: Sex
## Adding: Weight
## Start:  AIC=-3.4
## scale(Therapeutic_Outcome_Final) ~ scale(Age) + scale(Ethnicity) + 
##     scale(Sex) + scale(Weight)
## 
##                    Df Sum of Sq   RSS   AIC
## - scale(Ethnicity)  1     0.105  9.49 -5.19
## - scale(Sex)        1     0.475  9.86 -4.46
## - scale(Age)        1     0.937 10.32 -3.59
## <none>                           9.39 -3.40
## - scale(Weight)     1     2.342 11.73 -1.17
## 
## Step:  AIC=-5.19
## scale(Therapeutic_Outcome_Final) ~ scale(Age) + scale(Sex) + 
##     scale(Weight)
## 
##                 Df Sum of Sq   RSS   AIC
## - scale(Sex)     1      0.98 10.47 -5.32
## <none>                        9.49 -5.19
## - scale(Age)     1      3.43 12.92 -1.33
## - scale(Weight)  1      3.58 13.07 -1.10
## 
## Step:  AIC=-5.32
## scale(Therapeutic_Outcome_Final) ~ scale(Age) + scale(Weight)
## 
##                 Df Sum of Sq  RSS   AIC
## <none>                       10.5 -5.32
## - scale(Age)     1      2.54 13.0 -3.18
## - scale(Weight)  1      5.36 15.8  0.53
pp(file = "images/demographics_only_tumaco_linear_regression.svg")
t_lm_regression_demographics[["forest"]]
dev.off()
## png 
##   2
t_lm_regression_demographics[["forest"]]

t_lm_regression_demographics[["summary"]]
## # A tibble: 5 x 7
##   term              estimate std.error statistic p.value conf.low conf.high
##   <chr>                <dbl>     <dbl>     <dbl>   <dbl>    <dbl>     <dbl>
## 1 (Intercept)       1.69e-16     0.188  9.00e-16  1.00    -0.403      0.403
## 2 scale(Age)       -3.77e- 1     0.319 -1.18e+ 0  0.257   -1.06       0.307
## 3 scale(Ethnicity) -1.29e- 1     0.325 -3.96e- 1  0.698   -0.825      0.568
## 4 scale(Sex)       -2.14e- 1     0.255 -8.42e- 1  0.414   -0.761      0.332
## 5 scale(Weight)     4.28e- 1     0.229  1.87e+ 0  0.0827  -0.0632     0.920

Now repeat with only Tumaco, this should also be a part of a supplemental Figure.

t_log_regression_demographics <- extract_logistic_regression(
  t_regression_df, query = "Therapeutic_Outcome_Final", factors = t_regression_tests,
  excel = glue("excel/t_multivariable_logistic_regression-v{ver}.xlsx"))
## Adding: Age
## Adding: Ethnicity
## Adding: Sex
## Adding: Weight
## Waiting for profiling to be done...
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm):
## collapsing to unique 'x' values
## Warning in extract_logistic_regression(t_regression_df, query =
## "Therapeutic_Outcome_Final", : Dropped the row(s):
## -16.9167022333494531.4906148794-0.003733142948106750.997021389796933NA514.551663296319Ethnicity3
## from plotting.
pp(file = glue("figures/t_multivariable_logistic_regression-v{ver}.svg"))
t_log_regression_demographics[["forest"]]
dev.off()
## png 
##   2
t_log_regression_demographics[["forest"]]

t_log_regression_demographics[["summary"]]
##                Estimate Std. Error   z value Pr(>|z|) conf.low conf.high
## (Intercept)     0.05342     0.9036  0.059121   0.9529  -1.8079     2.001
## scale(Age)     -1.78144     1.6287 -1.093764   0.2741  -5.6548     1.269
## Ethnicity2      0.82959     2.7205  0.304937   0.7604  -3.6626     8.182
## Ethnicity3    -16.91670  4531.4906 -0.003733   0.9970       NA   514.552
## Sex2           -1.73208     2.1588 -0.802329   0.4224  -6.7668     2.446
## scale(Weight)   1.30908     0.8307  1.575972   0.1150  -0.1001     3.367
##                        term
## (Intercept)     (Intercept)
## scale(Age)       scale(Age)
## Ethnicity2       Ethnicity2
## Ethnicity3       Ethnicity3
## Sex2                   Sex2
## scale(Weight) scale(Weight)
t_log_iterative_regression_demographics <- iterate_logistic_regression(
  t_regression_df, query = "Therapeutic_Outcome_Final", factors = t_regression_tests,
  excel = glue("excel/t_simple_logistic_regression-v{ver}.xlsx"))
## Adding: Age
## Waiting for profiling to be done...
## Adding: Ethnicity
## Waiting for profiling to be done...
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
## Adding: Sex
## Waiting for profiling to be done...
## Adding: Weight
## Waiting for profiling to be done...
## Warning in iterate_logistic_regression(t_regression_df, query =
## "Therapeutic_Outcome_Final", : Dropped the row(s):
## -19.25921569042382917.01272583434-0.006602376300883340.994732104157411NA280.4494004518Ethnicity3
## from plotting.
pp(file = glue("figures/t_simple_logistic_regression-v{ver}.svg"))
t_log_iterative_regression_demographics[["forest"]]
dev.off()
## png 
##   2
t_log_iterative_regression_demographics[["forest"]]

t_log_iterative_regression_demographics[["summary"]]
##             estimate std_error         z    pr_z conf_low conf_high       term
## Age         -0.11708 8.205e-02 -1.426932 0.15360 -0.31737   0.01768        Age
## Ethnicity2  -0.69315 1.541e+00 -0.449773 0.65287 -4.10258   2.70327 Ethnicity2
## Ethnicity3 -19.25922 2.917e+03 -0.006602 0.99473       NA 280.44940 Ethnicity3
## Sex2        -1.23214 1.265e+00 -0.973734 0.33019 -4.36467   1.06321       Sex2
## Weight       0.08691 4.410e-02  1.970601 0.04877  0.01048   0.18868     Weight

If we decide to add things like typeofcells/visitnumber/etc to the above, then we will absolutely need to use multilevel regression and use the full combined metadata of the sample sheet and demographics combined.

wanted_queries <- c("Therapeutic_Outcome_Final", "sex", "clinic", "Ethnicity", "Age")
full_meta <- pData(tc_valid)
full_meta_numeric <- full_meta
for (f in wanted_queries) {
  full_meta_numeric[[f]] <- as.numeric(as.factor(full_meta_numeric[[f]]))
}

corheat <- ggstatsplot::ggcorrmat(full_meta_numeric, cor.vars = wanted_queries)
## Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
## i Please use `all_of()` or `any_of()` instead.
##   # Was:
##   data %>% select(wanted_queries)
## 
##   # Now:
##   data %>% select(all_of(wanted_queries))
## 
## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
pp(file = "images/type_donor_final_visit_sex_clinic_etnia_age_corheat.pdf")
corheat
dev.off()
## png 
##   2
corheat

7.2.3 Repeat using a logistical model

In the previous block, the function extract_stepwise_regression() uses a linear model to extract the f/r values used for the forest plot and performs a series (or one) stepwise regression. In the following I will repeat that process using a logistic regression model.

I bet I wrote it down somewhere above, but wtf is up with the prefix tdfvscea?

Also, it may be because I have been messing around with wanted_mtrx, but it should be a set of factors, now numeric.

## Also, we are excluding donor
test_factors <- c("typeofcells", "visitnumber", "Sex", "clinic", "Ethnicity", "Age")
logit_regression_test <- extract_logistic_regression(pData(tc_clinical_nobiop), query = "finaloutcome",
                                                     factors = test_factors)
## Adding: typeofcells
## Adding: visitnumber
## Adding: Sex
## Adding: clinic
## Adding: Ethnicity
## Adding: Age
## Waiting for profiling to be done...
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
logit_regression_test[["forest"]]

logit_regression_test[["summary"]]
##                         Estimate Std. Error  z value  Pr(>|z|)  conf.low
## (Intercept)             -2.22557     0.8736 -2.54769 1.084e-02   -4.0430
## typeofcellsmonocytes     0.82314     0.6650  1.23775 2.158e-01   -0.4627
## typeofcellsneutrophils   0.82314     0.6650  1.23775 2.158e-01   -0.4627
## visitnumber2            -0.07623     0.6008 -0.12687 8.990e-01   -1.2643
## visitnumber1             0.38947     0.6025  0.64643 5.180e-01   -0.7890
## Sex2                    -4.36821     1.0329 -4.22921 2.345e-05   -6.5918
## clinictumaco            -0.40682     0.7781 -0.52282 6.011e-01   -1.9839
## Ethnicity2               1.08341     0.9228  1.17406 2.404e-01   -0.5519
## Ethnicity3             -15.62094  1274.1408 -0.01226 9.902e-01 -259.2506
## scale(Age)              -4.41422     1.0193 -4.33054 1.487e-05   -6.6655
##                        conf.high                   term
## (Intercept)              -0.5858            (Intercept)
## typeofcellsmonocytes      2.1719   typeofcellsmonocytes
## typeofcellsneutrophils    2.1719 typeofcellsneutrophils
## visitnumber2              1.1108           visitnumber2
## visitnumber1              1.5940           visitnumber1
## Sex2                     -2.4908                   Sex2
## clinictumaco              1.1002           clinictumaco
## Ethnicity2                3.1858             Ethnicity2
## Ethnicity3               51.7604             Ethnicity3
## scale(Age)               -2.6394             scale(Age)

The careful reader might notice an odd change in the next block: I changed from ‘Therapeutic_Final_Outcome’ to ‘finaloutcome’. This is because these two data structures have slightly different sources for the per-person and/or per-sample annotations. In the first instance (and all the previous blocks), that information is coming from the demographics worksheet provided by Maria Adelaida. In the second instance (the following block), it is coming from the individual sample sheet. The extremely careful reader would also note that there is a series of blocks in the data structures worksheet which seeks to ensure that these two data sources agree with each other, and that it throws a testthat-based hissy-fit if they do not.

test_queries <- c("clinic", "Sex", "Ethnicity", "Age", "finaloutcome")
tc_regression_numeric <- pData(tc_clinical_nobiop)[, test_queries]
numeric_mtrx <- pData(t_clinical_nobiop)[, test_queries]
for (f in colnames(numeric_mtrx)) {
  tc_regression_numeric[[f]] <- as.numeric(tc_regression_numeric[[f]])
  numeric_mtrx[[f]] <- as.numeric(numeric_mtrx[[f]])
}

corheat <- ggstatsplot::ggcorrmat(numeric_mtrx, label = TRUE, cor.vars = test_queries)
## Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
## i Please use `all_of()` or `any_of()` instead.
##   # Was:
##   data %>% select(test_queries)
## 
##   # Now:
##   data %>% select(all_of(test_queries))
## 
## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero

## Warning in cor(x, y): the standard deviation is zero
pp(file = "images/corheat_tumaco_cali.png")
corheat
dev.off()
## png 
##   2
corheat

This correlation heatmap tells us that it is a bad idea to simultaneously consider Age and Ethnicity in any models we create to express the data. It may be possible to make a guess about which is more appropriate to consider by performing a regression table of each individually?

Let us try once with all factors included, then remove Ethnicity and Age sequentially. It might be wiser to use the quartile’d version of age?

Fundamentally, this just repeats what we just saw, but makes clearer that Age and Ethnicity are problematic if placed in the same model. My reasoning: Theresa suggested that any correlation >= 0.65 is problematic.

The following block was originally a bit wrong-headed because it was performed before we realized that we were feeding the lm the full experimental design with multiple entries per person.

I modified it to use the more appropriate data and decided to leave it here as a reminder.

csea_extracted_regression <- extract_linear_regression(
  tc_regression_numeric, query = "finaloutcome",
  factors = c("clinic", "Sex", "Ethnicity", "Age"), scale = FALSE,
  excel = "excel/tc_regression_table_csea.xlsx")
## Adding: clinic
## Adding: Sex
## Adding: Ethnicity
## Adding: Age
## Start:  AIC=-327.7
## finaloutcome ~ clinic + Sex + Ethnicity + Age
## 
##             Df Sum of Sq  RSS  AIC
## <none>                   21.7 -328
## - Ethnicity  1      0.35 22.1 -327
## - clinic     1      0.78 22.5 -324
## - Sex        1      1.71 23.4 -317
## - Age        1      3.30 25.0 -306
pp(file = "images/tc_regression_csea.png")
csea_extracted_regression[["forest"]]
dev.off()
## png 
##   2
csea_extracted_regression[["forest"]]

csea_extracted_regression[["summary"]]
## # A tibble: 5 x 7
##   term        estimate std.error statistic  p.value conf.low conf.high
##   <chr>          <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>
## 1 (Intercept)   2.50     0.258        9.68 9.27e-18   1.99      3.01  
## 2 clinic        0.156    0.0651       2.40 1.76e- 2   0.0276    0.285 
## 3 Sex          -0.334    0.0937      -3.56 4.81e- 4  -0.519    -0.149 
## 4 Ethnicity    -0.0829   0.0514      -1.61 1.09e- 1  -0.184     0.0187
## 5 Age          -0.0287   0.00580     -4.95 1.89e- 6  -0.0402   -0.0172
csa_extracted_regression <- extract_linear_regression(
  tc_regression_numeric, query = "finaloutcome",
  factors = c("clinic", "Sex", "Age"),
  excel = "excel/tc_regression_table_csa.xlsx")
## Adding: clinic
## Adding: Sex
## Adding: Age
## Start:  AIC=-80.76
## scale(finaloutcome) ~ scale(clinic) + scale(Sex) + scale(Age)
## 
##                 Df Sum of Sq   RSS   AIC
## <none>                        97.2 -80.8
## - scale(clinic)  1       3.3 100.5 -77.3
## - scale(Sex)     1      11.6 108.8 -64.1
## - scale(Age)     1      45.6 142.8 -19.0
pp(file = "images/tc_regression_csa.png")
csa_extracted_regression[["forest"]]
dev.off()
## png 
##   2
csa_extracted_regression[["forest"]]

csa_extracted_regression[["summary"]]
## # A tibble: 4 x 7
##   term           estimate std.error statistic  p.value conf.low conf.high
##   <chr>             <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>
## 1 (Intercept)   -1.06e-16    0.0601 -1.77e-15 1.00e+ 0  -0.119      0.119
## 2 scale(clinic)  1.53e- 1    0.0654  2.34e+ 0 2.06e- 2   0.0238     0.282
## 3 scale(Sex)    -2.92e- 1    0.0664 -4.39e+ 0 2.01e- 5  -0.423     -0.161
## 4 scale(Age)    -6.23e- 1    0.0715 -8.71e+ 0 3.31e-15  -0.764     -0.482
cse_extracted_regression <- extract_linear_regression(
  tc_regression_numeric, query = "finaloutcome",
  factors = c("clinic", "Sex", "Ethnicity"),
  excel = "excel/tc_regression_table_cse.xlsx")
## Adding: clinic
## Adding: Sex
## Adding: Ethnicity
## Start:  AIC=-59.94
## scale(finaloutcome) ~ scale(clinic) + scale(Sex) + scale(Ethnicity)
## 
##                    Df Sum of Sq RSS   AIC
## - scale(Sex)        1       0.8 111 -60.7
## <none>                          110 -59.9
## - scale(clinic)     1       9.4 120 -48.4
## - scale(Ethnicity)  1      32.6 143 -19.0
## 
## Step:  AIC=-60.74
## scale(finaloutcome) ~ scale(clinic) + scale(Ethnicity)
## 
##                    Df Sum of Sq RSS   AIC
## <none>                          111 -60.7
## - scale(clinic)     1       9.0 120 -49.8
## - scale(Ethnicity)  1      32.3 143 -20.4
pp(file = "images/tc_regression_cse.png")
cse_extracted_regression[["forest"]]
dev.off()
## png 
##   2
cse_extracted_regression[["forest"]]

cse_extracted_regression[["summary"]]
## # A tibble: 4 x 7
##   term              estimate std.error statistic  p.value conf.low conf.high
##   <chr>                <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>
## 1 (Intercept)      -1.80e-16    0.0640 -2.81e-15 1.00e+ 0   -0.126    0.126 
## 2 scale(clinic)     2.48e- 1    0.0668  3.71e+ 0 2.81e- 4    0.116    0.380 
## 3 scale(Sex)       -7.01e- 2    0.0645 -1.09e+ 0 2.79e- 1   -0.197    0.0574
## 4 scale(Ethnicity) -4.61e- 1    0.0666 -6.92e+ 0 1.01e-10   -0.592   -0.329

7.3 Repeat with only Tumaco

Thus, clinic cannot be in the model. In addition I will remove height/weight because we know a priori how they correlate.

initial_queries <- c("Sex", "Ethnicity", "Age",
                     "Evolution_Time", "Num_Active_Lesions",
                     "V2_New_Lesions", "V3_New_Lesions",
                     "Adherence", "finaloutcome")
t_initial_mtrx <- pData(t_clinical_nobiop)[, initial_queries]

tumaco_cross <- corr_cross(t_initial_mtrx)
## Returning only the top 20. You may override with the 'top' argument
pp(file = "images/tumaco_crosscor.png")
tumaco_cross
dev.off()
## png 
##   2
tumaco_cross

Once again, let us consider a smaller set to identify factors that should not go into a model test together, we assume that once again this will prove to be Ethnicity and Age.

test_queries <- c("Sex", "Ethnicity", "Age", "finaloutcome")
t_numeric_mtrx <- t_initial_mtrx[, test_queries]
for (f in colnames(t_numeric_mtrx)) {
  t_numeric_mtrx[[f]] <- as.numeric(t_numeric_mtrx[[f]])
}

corheat <- ggstatsplot::ggcorrmat(t_numeric_mtrx, label = TRUE, cor.vars = test_queries)
corheat

It turns out they are even more tightly correlated in this subset than in the full dataset.

7.4 A series of linear regression models

Given the above, I know that I should not include some groups of factors in a model together, but I want to get a feel for which factor combinations are most/least informative with respect to final outcome.

t_sea_extracted_regression <- extract_linear_regression(
  t_regression_numeric, query = "Therapeutic_Outcome_Final",
  factors = c("Sex", "Ethnicity", "Age"),
  excel = "excel/t_regression_table_t_sea.xlsx")
## Adding: Sex
## Adding: Ethnicity
## Adding: Age
## Start:  AIC=-1.17
## scale(Therapeutic_Outcome_Final) ~ scale(Sex) + scale(Ethnicity) + 
##     scale(Age)
## 
##                    Df Sum of Sq  RSS   AIC
## - scale(Age)        1     0.273 12.0 -2.73
## - scale(Sex)        1     0.479 12.2 -2.41
## <none>                          11.7 -1.17
## - scale(Ethnicity)  1     1.347 13.1 -1.10
## 
## Step:  AIC=-2.73
## scale(Therapeutic_Outcome_Final) ~ scale(Sex) + scale(Ethnicity)
## 
##                    Df Sum of Sq  RSS   AIC
## - scale(Sex)        1      0.22 12.2 -4.39
## <none>                          12.0 -2.73
## - scale(Ethnicity)  1      5.04 17.0  1.93
## 
## Step:  AIC=-4.39
## scale(Therapeutic_Outcome_Final) ~ scale(Ethnicity)
## 
##                    Df Sum of Sq  RSS   AIC
## <none>                          12.2 -4.39
## - scale(Ethnicity)  1      5.78 18.0  0.97
pp(file = "images/tc_regression_t_sea.png")
t_sea_extracted_regression[["forest"]]
dev.off()
## png 
##   2
t_sea_extracted_regression[["forest"]]

t_sea_extracted_regression[["summary"]]
## # A tibble: 4 x 7
##   term              estimate std.error statistic p.value conf.low conf.high
##   <chr>                <dbl>     <dbl>     <dbl>   <dbl>    <dbl>     <dbl>
## 1 (Intercept)       1.96e-16     0.203  9.66e-16   1.00    -0.432     0.432
## 2 scale(Sex)       -2.15e- 1     0.275 -7.83e- 1   0.446   -0.802     0.371
## 3 scale(Ethnicity) -4.08e- 1     0.311 -1.31e+ 0   0.209   -1.07      0.255
## 4 scale(Age)       -1.94e- 1     0.328 -5.91e- 1   0.564   -0.893     0.505
t_sa_extracted_regression <- extract_linear_regression(
  t_regression_numeric, query = "Therapeutic_Outcome_Final",
  factors = c("Sex", "Age"),
  excel = "excel/t_regression_table_t_sa.xlsx")
## Adding: Sex
## Adding: Age
## Start:  AIC=-1.1
## scale(Therapeutic_Outcome_Final) ~ scale(Sex) + scale(Age)
## 
##              Df Sum of Sq  RSS    AIC
## <none>                    13.1 -1.102
## - scale(Sex)  1      2.76 15.8  0.535
## - scale(Age)  1      3.96 17.0  1.928
pp(file = "images/t_regression_sa.png")
t_sa_extracted_regression[["forest"]]
dev.off()
## png 
##   2
t_sa_extracted_regression[["forest"]]

t_sa_extracted_regression[["summary"]]
## # A tibble: 3 x 7
##   term         estimate std.error statistic p.value conf.low conf.high
##   <chr>           <dbl>     <dbl>     <dbl>   <dbl>    <dbl>     <dbl>
## 1 (Intercept)  1.69e-16     0.207  8.16e-16  1.00     -0.440    0.440 
## 2 scale(Sex)  -4.23e- 1     0.230 -1.84e+ 0  0.0848   -0.911    0.0650
## 3 scale(Age)  -5.07e- 1     0.230 -2.20e+ 0  0.0427   -0.995   -0.0189
t_se_extracted_regression <- extract_linear_regression(
  t_regression_numeric, query = "Therapeutic_Outcome_Final",
  factors = c("Sex", "Ethnicity"),
  excel = "excel/t_regression_table_se.xlsx")
## Adding: Sex
## Adding: Ethnicity
## Start:  AIC=-2.73
## scale(Therapeutic_Outcome_Final) ~ scale(Sex) + scale(Ethnicity)
## 
##                    Df Sum of Sq  RSS   AIC
## - scale(Sex)        1      0.22 12.2 -4.39
## <none>                          12.0 -2.73
## - scale(Ethnicity)  1      5.04 17.0  1.93
## 
## Step:  AIC=-4.39
## scale(Therapeutic_Outcome_Final) ~ scale(Ethnicity)
## 
##                    Df Sum of Sq  RSS   AIC
## <none>                          12.2 -4.39
## - scale(Ethnicity)  1      5.78 18.0  0.97
pp(file = "images/t_regression_se.png")
t_se_extracted_regression[["forest"]]
dev.off()
## png 
##   2
t_se_extracted_regression[["forest"]]

t_se_extracted_regression[["summary"]]
## # A tibble: 3 x 7
##   term              estimate std.error statistic p.value conf.low conf.high
##   <chr>                <dbl>     <dbl>     <dbl>   <dbl>    <dbl>     <dbl>
## 1 (Intercept)       2.08e-16     0.199  1.04e-15  1.00     -0.421    0.421 
## 2 scale(Sex)       -1.13e- 1     0.209 -5.40e- 1  0.597    -0.556    0.330 
## 3 scale(Ethnicity) -5.42e- 1     0.209 -2.59e+ 0  0.0197   -0.986   -0.0987

8 Global views of all cell types

Now that those ‘global’ metrics are out of the way, lets look at some global metrics of the data following normalization; the most likely plots are of course PCA but also a couple of heatmaps.

8.0.1 Figure 1

Over time the preference for which samples to include in a ‘global’ PCA has changed, as well as preferences for how to arrange/label/color them. The following shows a couple of perspectives.

tc_type <- set_expt_conditions(tc_valid, fact = "typeofcells") %>%
  set_expt_batches(fact = "finaloutcome") %>%
  set_expt_colors(color_choices[["type"]])
## The numbers of samples by condition are:
## 
##      biopsy eosinophils   monocytes neutrophils 
##          18          41          63          62
## The number of samples by batch are:
## 
##    cure failure 
##     122      62
tc_norm <- sm(normalize_expt(tc_type, transform = "log2", norm = "quant",
                             convert = "cpm", filter = TRUE))

tc_pca <- plot_pca(tc_norm, plot_labels = FALSE,
                    plot_title = "PCA - Cell type", size_column = "visitnumber")
pp(file = "figures/tc_pca_sized.pdf")
tc_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by biopsy, eosinophils, monocytes, neutrophils
## Shapes are defined by cure, failure.
dev.off()
## png 
##   2
tc_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by biopsy, eosinophils, monocytes, neutrophils
## Shapes are defined by cure, failure.

tc_pca <- plot_pca(tc_norm, plot_labels = FALSE,
                   plot_title = "PCA - Cell type")
pp(file = "figures/tc_pca_nosize.pdf")
tc_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by biopsy, eosinophils, monocytes, neutrophils
## Shapes are defined by cure, failure.
dev.off()
## png 
##   2
tc_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by biopsy, eosinophils, monocytes, neutrophils
## Shapes are defined by cure, failure.

write.csv(tc_pca[["table"]], file = "excel/tc_donor_pca_coords.csv")
tc_cf_norm <- set_expt_batches(tc_norm, fact = "visitnumber")
## The number of samples by batch are:
## 
##  3  2  1 
## 51 50 83
tc_cf_corheat <- plot_corheat(tc_cf_norm, plot_title = "Heirarchical clustering:
         cell types")
pp(file = "figures/tc_cf_corheat.svg")
tc_cf_corheat
## A heatmap of pairwise sample correlations ranging from: 
## 0.51183235766239 to 0.998356314777661.
dev.off()
## png 
##   2
tc_cf_corheat
## A heatmap of pairwise sample correlations ranging from: 
## 0.51183235766239 to 0.998356314777661.

tc_cf_disheat <- plot_disheat(tc_cf_norm, plot_title = "Heirarchical clustering:
         cell types")
tc_cf_disheat
## A heatmap of pairwise sample distances ranging from: 
## 18.6829431312211 to 322.033876692148.

8.1 Figure 1B: Transcriptomic profiles of primary innate cells

A potential figure legend for the following images might include:

The observed counts per gene for all of the clinical samples were filtered, log transformed, cpm converted, and quantile normalized. The colors were defined by cell types and shapes by patient visit. When the first two principle components were plotted, clustering was observed by cell type. The biopsy samples were significantly different from the innate immune cell types.

fig1v2_norm <- normalize_expt(tc_type, transform = "log2",
                              convert = "cpm", norm = "quant", filter = TRUE)
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 677 values equal to 0, adding 1 to the matrix.
fig1v2_pca <- plot_pca(fig1v2_norm, cis = FALSE)
pp(file = "figures/tc_type_v2.pdf")
fig1v2_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by biopsy, eosinophils, monocytes, neutrophils
## Shapes are defined by cure, failure.
dev.off()
## png 
##   2
fig1v2_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by biopsy, eosinophils, monocytes, neutrophils
## Shapes are defined by cure, failure.

9 Compare samples by clinic

Spoiler alert: This section will eventually suggest pretty strongly that we will not easily be able to use the Cali samples. Thus, after finishing it, we will likely exclude those samples.

Take a moment to view the biopsy samples. We separated them by clinic (Cali or Tumaco), and this view of the samples is the only one which does not suggest a strong difference between the two clinics. However, it also suggests that the biopsy samples will not prove very helpful.

9.1 Biopsies by clinic

There are too few biopsy samples to get a strong view of cure/fail. In addition, these are ‘messier’ than any other sample type. As a result, it is difficult to discern a pattern in them which help elucidate cure vs. fail. If we play with the various parameters used to perform the count modification via ruv/sva, we get slightly different views, some more evocative than others; but the following is our most canonical view.

9.1.1 Figure 3E: Biopsies

tc_biopsies_norm <- normalize_expt(tc_biopsies, transform = "log2",
                                   convert = "cpm", norm = "quant", filter = TRUE)
## Removing 6337 low-count genes (13615 remaining).
## transform_counts: Found 206 values equal to 0, adding 1 to the matrix.
tc_biopsies_pca <- plot_pca(tc_biopsies_norm)
tc_biopsies_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_cure, tumaco_cure, tumaco_failure
## Shapes are defined by 1.

pp(file = "figures/tc_biopsies_pca.svg")
tc_biopsies_pca[["plot"]]
dev.off()
## png 
##   2
tc_biopsies_nb <- normalize_expt(tc_biopsies, transform = "log2",
                                 convert = "cpm", batch = "svaseq", filter = TRUE)
## Removing 6337 low-count genes (13615 remaining).
## Setting 289 low elements to zero.
## transform_counts: Found 289 values equal to 0, adding 1 to the matrix.
tc_biopsies_nb_pca <- plot_pca(tc_biopsies_nb)
pp(file = "figures/figure3E_biopsies.svg")
tc_biopsies_nb_pca[["plot"]]
dev.off()
## png 
##   2
tc_biopsies_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_cure, tumaco_cure, tumaco_failure
## Shapes are defined by 1.

I worry that we rely too heavily on PCA.

9.2 Patient Race and clinic?

How strong is the effect of ethnicity/ethnicity+clinic? In the worst case scenario, these surrogates could make interpreting the results problematic. The following blocks will explore that question a little and I think come to the general conclusion that race and/or clinic are not significant problems.

9.2.1 All samples, both clinics

Compared to the cell type effect, clinic/race is, as we already know, utterly insignificant. The question still stands, how significant? There does appear to be an effect in the data which is relevant to race. I think if we want to be able to explore this fully, we would need more people.

etnia_expt <- set_expt_conditions(tc_valid, fact = "clinic_etnia") %>%
  set_expt_colors(color_choices[["clinic_etnia"]])
## The numbers of samples by condition are:
## 
##    cali_afrocol   cali_indigena    cali_mestiza  tumaco_afrocol tumaco_indigena 
##              15              27              19              76              19 
##  tumaco_mestiza 
##              28
etnia_norm <- normalize_expt(etnia_expt, transform = "log2", convert = "cpm",
                             filter = TRUE, norm = "quant")
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 677 values equal to 0, adding 1 to the matrix.
plot_pca(etnia_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 1, 2, 3.

etnia_nb <- normalize_expt(etnia_expt, transform = "log2", convert = "cpm",
                           filter = TRUE, batch = "svaseq")
## Removing 5654 low-count genes (14298 remaining).
## Setting 26479 low elements to zero.
## transform_counts: Found 26479 values equal to 0, adding 1 to the matrix.
plot_pca(etnia_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 1, 2, 3.

9.2.1.1 Only Tumaco

There is an imbalance in the identity of people who attended each clinic. Given that we are focusing on the Tumaco samples, here is the distribution of race/cell type:

t_etnia_norm <- normalize_expt(t_etnia_expt, transform = "log2", convert = "cpm",
                               filter = TRUE, norm = "quant")
## Removing 5796 low-count genes (14156 remaining).
## transform_counts: Found 299 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.

t_etnia_nb <- normalize_expt(t_etnia_expt, transform = "log2", convert = "cpm",
                             filter = TRUE, batch = "svaseq")
## Removing 5796 low-count genes (14156 remaining).
## Setting 15870 low elements to zero.
## transform_counts: Found 15870 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.

9.2.2 Biopsy samples, both clinics.

The biopsy samples are missing people of indigenous origin who went to the Tumaco clinic.

tc_bp_ec <- set_expt_conditions(tc_biopsies, fact = "clinic_etnia") %>%
  set_expt_colors(color_choices[["clinic_etnia"]])
## The numbers of samples by condition are:
## 
##    cali_afrocol   cali_indigena    cali_mestiza  tumaco_afrocol tumaco_indigena 
##               1               1               2               8               2 
##  tumaco_mestiza 
##               4
etnia_bp_norm <- normalize_expt(tc_bp_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, norm = "quant")
## Removing 6337 low-count genes (13615 remaining).
## transform_counts: Found 206 values equal to 0, adding 1 to the matrix.
plot_pca(etnia_bp_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 1.

9.2.2.1 Biopsy samples, Tumaco.

The biopsy samples are by far the ‘messiest,’ that remains true when considering the ethnicity of the individual patients.

t_bp_ec <- set_expt_conditions(tc_biopsies, fact = "etnia") %>%
  set_expt_colors(color_choices[["ethnicity"]])
## The numbers of samples by condition are:
## 
##  afrocol indigena  mestiza 
##        9        3        6
t_etnia_bp_norm <- normalize_expt(t_bp_ec, transform = "log2", convert = "cpm",
                                  filter = TRUE, norm = "quant")
## Removing 6337 low-count genes (13615 remaining).
## transform_counts: Found 206 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_bp_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 1.

I think there are not enough samples to try sva with this.

9.2.3 Eosinophil samples, both clinics.

When we ask the same question of the clinical cell types, it is possible to see more samples, but not a significantly clearer view of the race effect on the transcriptional profile.

tc_eo_ec <- set_expt_conditions(tc_eosinophils, fact = "clinic_etnia") %>%
  set_expt_colors(color_choices[["clinic_etnia"]])
## The numbers of samples by condition are:
## 
##    cali_afrocol   cali_indigena    cali_mestiza  tumaco_afrocol tumaco_indigena 
##               2               8               5              14               5 
##  tumaco_mestiza 
##               7
etnia_eo_norm <- normalize_expt(tc_eo_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, norm = "quant")
## Removing 9085 low-count genes (10867 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
plot_pca(etnia_eo_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 3, 2, 1.

etnia_eo_nb <- normalize_expt(tc_eo_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, batch = "svaseq")
## Removing 9085 low-count genes (10867 remaining).
## Setting 1079 low elements to zero.
## transform_counts: Found 1079 values equal to 0, adding 1 to the matrix.
ethnicity_pca <- plot_pca(etnia_eo_nb)
pp(file = "figures/ethnicity_eo_pca.svg")
ethnicity_pca[["plot"]]
dev.off()
## png 
##   2
ethnicity_pca[["plot"]]

9.2.3.1 Eosinophil samples, Tumaco.

The eosinophils are our least-abundant cell type, as such the view of ethnicity using them is particularly problematic; but we do at least have a few samples from each group. With that in mind, these appear to show some significant difference among the three groups.

t_eo_ec <- set_expt_conditions(t_eosinophils, fact = "etnia") %>%
  set_expt_colors(color_choices[["ethnicity"]])
## The numbers of samples by condition are:
## 
##  afrocol indigena  mestiza 
##       14        5        7
t_etnia_eo_norm <- normalize_expt(t_eo_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, norm = "quant")
## Removing 9420 low-count genes (10532 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_eo_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 3, 2, 1.

t_etnia_eo_nb <- normalize_expt(t_eo_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, batch = "svaseq")
## Removing 9420 low-count genes (10532 remaining).
## Setting 326 low elements to zero.
## transform_counts: Found 326 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_eo_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 3, 2, 1.

9.2.4 Monocyte samples, both clinics.

In general, the monocytes show the strongest differences in any comparison we have performed. This is true in the context of race as well. Thus, even before applying sva, we see some separation among the monocyte samples with respect to ethnicity.

tc_mo_ec <- set_expt_conditions(tc_monocytes, fact = "clinic_etnia") %>%
  set_expt_colors(color_choices[["clinic_etnia"]])
## The numbers of samples by condition are:
## 
##    cali_afrocol   cali_indigena    cali_mestiza  tumaco_afrocol tumaco_indigena 
##               6               9               6              27               6 
##  tumaco_mestiza 
##               9
etnia_mo_norm <- normalize_expt(tc_mo_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, norm = "quant")
## Removing 8844 low-count genes (11108 remaining).
## transform_counts: Found 12 values equal to 0, adding 1 to the matrix.
plot_pca(etnia_mo_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 3, 2, 1.

etnia_mo_nb <- normalize_expt(tc_mo_ec, transform = "log2", convert = "cpm",
                              filter = TRUE, batch = "svaseq")
## Removing 8844 low-count genes (11108 remaining).
## Setting 1590 low elements to zero.
## transform_counts: Found 1590 values equal to 0, adding 1 to the matrix.
etnia_mo_nb_pca <- plot_pca(etnia_mo_nb)
pp(file = "figures/etnia_mo_nb_pca.svg")
etnia_mo_nb_pca[["plot"]]
dev.off()
## png 
##   2
etnia_mo_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 3, 2, 1.

9.2.4.1 Monocyte samples, Tumaco.

The ability to see some separation by ethnicity among the monocyte samples remains, at least slightly, true when considering only the Tumaco samples.

t_mo_ec <- set_expt_conditions(t_monocytes, fact = "etnia") %>%
  set_expt_colors(color_choices[["ethnicity"]])
## The numbers of samples by condition are:
## 
##  afrocol indigena  mestiza 
##       27        6        9
t_etnia_mo_norm <- normalize_expt(t_mo_ec, transform = "log2", convert = "cpm",
                                  filter = TRUE, norm = "quant")
## Removing 9090 low-count genes (10862 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_mo_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 3, 2, 1.

t_etnia_mo_nb <- normalize_expt(t_mo_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, batch = "svaseq")
## Removing 9090 low-count genes (10862 remaining).
## Setting 765 low elements to zero.
## transform_counts: Found 765 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_mo_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 3, 2, 1.

9.2.5 Neutrophil samples, both clinics.

In a fashion similar to our other effects, the neutrophils are intermediate.

tc_ne_ec <- set_expt_conditions(tc_neutrophils, fact = "clinic_etnia") %>%
    set_expt_colors(color_choices[["clinic_etnia"]])
## The numbers of samples by condition are:
## 
##    cali_afrocol   cali_indigena    cali_mestiza  tumaco_afrocol tumaco_indigena 
##               6               9               6              27               6 
##  tumaco_mestiza 
##               8
etnia_ne_norm <- normalize_expt(tc_ne_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, norm = "quant")
## Removing 10708 low-count genes (9244 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(etnia_ne_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 3, 2, 1.

etnia_ne_nb <- normalize_expt(tc_ne_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, batch = "svaseq")
## Removing 10708 low-count genes (9244 remaining).
## Setting 1628 low elements to zero.
## transform_counts: Found 1628 values equal to 0, adding 1 to the matrix.
etnia_ne_nb_pca <- plot_pca(etnia_ne_nb)
pp(file = "figures/etnia_ne_nb_pca.svg")
etnia_ne_nb_pca[["plot"]]
dev.off()
## png 
##   2
etnia_ne_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_afrocol, cali_indigena, cali_mestiza, tumaco_afrocol, tumaco_indigena, tumaco_mestiza
## Shapes are defined by 3, 2, 1.

9.2.5.1 Neutrophil samples, Tumaco.

The Tumaco-only neutrophils are something of a counter example to the previous statement. The easiest to discern race-effect appears to me to come from the Neutrophils from Tumaco.

t_ne_ec <- set_expt_conditions(t_neutrophils, fact = "etnia") %>%
    set_expt_colors(color_choices[["ethnicity"]])
## The numbers of samples by condition are:
## 
##  afrocol indigena  mestiza 
##       27        6        8
t_etnia_ne_norm <- normalize_expt(t_ne_ec, transform = "log2", convert = "cpm",
                                  filter = TRUE, norm = "quant")
## Removing 10851 low-count genes (9101 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_ne_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 3, 2, 1.

t_etnia_ne_nb <- normalize_expt(t_ne_ec, transform = "log2", convert = "cpm",
                                filter = TRUE, batch = "svaseq")
## Removing 10851 low-count genes (9101 remaining).
## Setting 823 low elements to zero.
## transform_counts: Found 823 values equal to 0, adding 1 to the matrix.
plot_pca(t_etnia_ne_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by afrocol, indigena, mestiza
## Shapes are defined by 3, 2, 1.

9.3 Sex

The imbalances observed with respect to clinic/race are significantly less profound than those observed with respect to the sex of patients who participated in the study. It is almost certainly possible to see some degree of a sex-based effect in the available transcriptomes.

sex_expt <- set_expt_conditions(tc_valid, fact = "sex") %>%
  set_expt_colors(color_choices[["sex"]])
## The numbers of samples by condition are:
## 
## female   male 
##     28    156
sex_norm <- normalize_expt(sex_expt, transform = "log2", convert = "cpm",
                           filter = TRUE, norm = "quant")
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 677 values equal to 0, adding 1 to the matrix.
plot_pca(sex_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by female, male
## Shapes are defined by 1, 2, 3.

sex_nb <- normalize_expt(sex_expt, transform = "log2", convert = "cpm",
                         filter = TRUE, batch = "svaseq")
## Removing 5654 low-count genes (14298 remaining).
## Setting 26368 low elements to zero.
## transform_counts: Found 26368 values equal to 0, adding 1 to the matrix.
plot_pca(sex_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by female, male
## Shapes are defined by 1, 2, 3.

9.4 Sex and clinic

9.4.1 All samples, both clinics

clinic_sex_expt <- set_expt_conditions(tc_valid, fact = "clinic_sex") %>%
  set_expt_colors(color_choices[["clinic_sex"]])
## The numbers of samples by condition are:
## 
##   cali_female     cali_male tumaco_female   tumaco_male 
##             6            55            22           101
clinic_sex_norm <- normalize_expt(clinic_sex_expt, transform = "log2", convert = "cpm",
                                  filter = TRUE, norm = "quant")
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 677 values equal to 0, adding 1 to the matrix.
plot_pca(clinic_sex_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_female, cali_male, tumaco_female, tumaco_male
## Shapes are defined by 1, 2, 3.

clinic_sex_nb <- normalize_expt(clinic_sex_expt, transform = "log2", convert = "cpm",
                             filter = TRUE, batch = "svaseq")
## Removing 5654 low-count genes (14298 remaining).
## Setting 29063 low elements to zero.
## transform_counts: Found 29063 values equal to 0, adding 1 to the matrix.
plot_pca(clinic_sex_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_female, cali_male, tumaco_female, tumaco_male
## Shapes are defined by 1, 2, 3.

9.4.2 Biopsy samples, both clinics.

tc_bp_sc <- set_expt_conditions(tc_biopsies, fact = "clinic_sex") %>%
  set_expt_colors(color_choices[["clinic_sex"]])
## The numbers of samples by condition are:
## 
##     cali_male tumaco_female   tumaco_male 
##             4             3            11
## Warning in set_expt_colors(., color_choices[["clinic_sex"]]): Colors for the
## following categories are not being used: cali_female.
clinic_sex_bp_norm <- normalize_expt(tc_bp_sc, transform = "log2", convert = "cpm",
                                filter = TRUE, norm = "quant")
## Removing 6337 low-count genes (13615 remaining).
## transform_counts: Found 206 values equal to 0, adding 1 to the matrix.
plot_pca(clinic_sex_bp_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_male, tumaco_female, tumaco_male
## Shapes are defined by 1.

I think there are not enough samples to try sva with this.

9.4.3 Eosinophil samples, both clinics.

tc_eo_sc <- set_expt_conditions(tc_eosinophils, fact = "clinic_sex") %>%
  set_expt_colors(color_choices[["clinic_sex"]])
clinic_sex_eo_norm <- normalize_expt(tc_eo_sc, transform = "log2", convert = "cpm",
                                     filter = TRUE, norm = "quant")
plot_pca(clinic_sex_eo_norm)

9.4.4 Monocyte samples, both clinics.

tc_mo_clinic_sex <- set_expt_conditions(tc_monocytes, fact = "clinic_sex") %>%
  set_expt_colors(color_choices[["clinic_sex"]])
## The numbers of samples by condition are:
## 
##   cali_female     cali_male tumaco_female   tumaco_male 
##             2            19             7            35
tc_mo_clinic_sex_norm <- normalize_expt(tc_mo_clinic_sex, transform = "log2", convert = "cpm",
                                        filter = TRUE, norm = "quant")
## Removing 8844 low-count genes (11108 remaining).
## transform_counts: Found 12 values equal to 0, adding 1 to the matrix.
plot_pca(tc_mo_clinic_sex_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_female, cali_male, tumaco_female, tumaco_male
## Shapes are defined by 3, 2, 1.

tc_mo_clinic_sex_nb <- normalize_expt(tc_mo_clinic_sex, transform = "log2", convert = "cpm",
                                      filter = TRUE, batch = "svaseq")
## Removing 8844 low-count genes (11108 remaining).
## Setting 1425 low elements to zero.
## transform_counts: Found 1425 values equal to 0, adding 1 to the matrix.
plot_pca(tc_mo_clinic_sex_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_female, cali_male, tumaco_female, tumaco_male
## Shapes are defined by 3, 2, 1.

9.4.5 Neutrophil samples, both clinics.

tc_ne_clinic_sex <- set_expt_conditions(tc_neutrophils, fact = "clinic_sex") %>%
    set_expt_colors(color_choices[["clinic_sex"]])
## The numbers of samples by condition are:
## 
##   cali_female     cali_male tumaco_female   tumaco_male 
##             2            19             7            34
tc_ne_clinic_sex_norm <- normalize_expt(tc_ne_clinic_sex, transform = "log2", convert = "cpm",
                                        filter = TRUE, norm = "quant")
## Removing 10708 low-count genes (9244 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(tc_ne_clinic_sex_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_female, cali_male, tumaco_female, tumaco_male
## Shapes are defined by 3, 2, 1.

9.5 Eosinophils by clinic

In contrast, the Eosinophil samples do have significant amounts of variance which discriminates the two clinics. At the time of this writing, there are fewer eosinophil samples than monocytes and neutrophils; as a result there are no samples which failed from Cali. This is somewhat limiting is we wish to look for differences between the cure and fail samples which came from the two clinics.

9.5.1 Figure 3B: Eosinophils

tc_eosinophils_norm <- normalize_expt(tc_eosinophils, transform = "log2",
                                      convert = "cpm", norm = "quant", filter = TRUE)
## Removing 9085 low-count genes (10867 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
tc_eosinophils_pca <- plot_pca(tc_eosinophils_norm, plot_labels = FALSE)
tc_eosinophils_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_cure, tumaco_cure, tumaco_failure
## Shapes are defined by 3, 2, 1.

pp(file = "figures/tc_eosinophils.svg")
tc_eosinophils_pca[["plot"]]
dev.off()
## png 
##   2
tc_eosinophils_nb <- normalize_expt(tc_eosinophils, transform = "log2",
                                    convert = "cpm", batch = "svaseq", filter = TRUE)
## Removing 9085 low-count genes (10867 remaining).
## Setting 1048 low elements to zero.
## transform_counts: Found 1048 values equal to 0, adding 1 to the matrix.
tc_eosinophils_nb_pca <- plot_pca(tc_eosinophils_nb, plot_labels = FALSE)
pp(file = "figures/figure3B_eosinophils.svg")
tc_eosinophils_nb_pca$plot
dev.off()
## png 
##   2
tc_eosinophils_nb_pca$plot

9.6 Monocytes by clinic

In contrast with the eosinophil samples, we have one patient’s monocyte and neutrophil samples which did not cure. As we will see, there is one person from Cali who did not cure, this person is not different with respect to tracscriptome than the other people from Cali.

9.6.1 Figure 3C: Monocytes

tc_monocytes_norm <- normalize_expt(tc_monocytes, transform = "log2",
                                       convert = "cpm", norm = "quant", filter = TRUE)
## Removing 8844 low-count genes (11108 remaining).
## transform_counts: Found 12 values equal to 0, adding 1 to the matrix.
tc_monocytes_pca <- plot_pca(tc_monocytes_norm, plot_labels = FALSE)
tc_monocytes_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_cure, cali_failure, tumaco_cure, tumaco_failure
## Shapes are defined by 3, 2, 1.

pp(file = "figures/tc_monocytes_pca.svg")
tc_monocytes_pca[["plot"]]
dev.off()
## png 
##   2
tc_monocytes_nb <- normalize_expt(tc_monocytes, transform = "log2",
                                  convert = "cpm", batch = "svaseq", filter = TRUE)
## Removing 8844 low-count genes (11108 remaining).
## Setting 1455 low elements to zero.
## transform_counts: Found 1455 values equal to 0, adding 1 to the matrix.
tc_monocytes_nb_pca <- plot_pca(tc_monocytes_nb, plot_labels = FALSE)
pp(file = "figures/figure3C_monocytes.svg")
tc_monocytes_nb_pca$plot
dev.off()
## png 
##   2
tc_monocytes_nb_pca$plot

9.7 Neutrophils by clinic

Finally, that same one person does appear to be different than the others from Cali when looking at neutrophils.

9.7.1 Figure 3D: Neutrophils

tc_neutrophils_norm <- normalize_expt(tc_neutrophils, transform = "log2",
                                      convert = "cpm", norm = "quant", filter = TRUE)
## Removing 10708 low-count genes (9244 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
tc_neutrophils_pca <- plot_pca(tc_neutrophils_norm, plot_labels = FALSE)
tc_neutrophils_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali_cure, cali_failure, tumaco_cure, tumaco_failure
## Shapes are defined by 3, 2, 1.

pp(file = "figures/tc_neutrophils_pca.svg")
tc_neutrophils_pca[["plot"]]
dev.off()
## png 
##   2
tc_neutrophils_nb <- normalize_expt(tc_neutrophils, transform = "log2",
                                    convert = "cpm", batch = "svaseq", filter = TRUE)
## Removing 10708 low-count genes (9244 remaining).
## Setting 1539 low elements to zero.
## transform_counts: Found 1539 values equal to 0, adding 1 to the matrix.
tc_neutrophils_nb_pca <- plot_pca(tc_neutrophils_nb, plot_labels = FALSE)
pp(file = "figures/figure3D_neutrophils.svg")
tc_neutrophils_nb_pca$plot
dev.off()
## png 
##   2
tc_neutrophils_nb_pca$plot

9.8 PCA: Compare clinics

Now that we have these various subsets, perform an explicit comparison of the samples which came from the two clinics.

9.8.1 Figure 3, panel A: ‘ALL Samples’

tc_clinic_type <- tc_valid %>%
  set_expt_conditions(fact = "clinic") %>%
  set_expt_batches(fact = "typeofcells")
## The numbers of samples by condition are:
## 
##   cali tumaco 
##     61    123
## The number of samples by batch are:
## 
##      biopsy eosinophils   monocytes neutrophils 
##          18          41          63          62
tc_clinic_type_norm <- normalize_expt(tc_clinic_type, transform = "log2", convert = "cpm",
                                      norm = "quant", filter = TRUE)
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 677 values equal to 0, adding 1 to the matrix.
tc_clinic_type_pca <- plot_pca(tc_clinic_type_norm)
tc_clinic_type_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali, tumaco
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.

tc_clinic_type_nb <- normalize_expt(tc_clinic_type, transform = "log2", convert = "cpm",
                                    batch = "svaseq", filter = TRUE)
## Removing 5654 low-count genes (14298 remaining).
## Setting 31394 low elements to zero.
## transform_counts: Found 31394 values equal to 0, adding 1 to the matrix.
tc_clinic_type_nb_pca <- plot_pca(tc_clinic_type_nb)
tc_clinic_type_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cali, tumaco
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.

pp(file = "figures/figure3a_all_samples.svg")
tc_clinic_type_nb_pca$plot
dev.off()
## png 
##   2
tc_clinical_norm <- sm(normalize_expt(tc_clinical, filter = "simple", transform = "log2",
                                      norm = "quant", convert = "cpm"))
clinical_pca <- plot_pca(tc_clinical_norm, plot_labels = FALSE,
                         cis = NULL,
                         plot_title = "PCA - clinical samples")
clinical_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.

tc_clinical_nb <- normalize_expt(tc_clinical, filter = "simple", transform = "log2",
                                 batch = "svaseq", convert = "cpm")
## Removing 1881 low-count genes (18071 remaining).
## Setting 157339 low elements to zero.
## transform_counts: Found 157339 values equal to 0, adding 1 to the matrix.
tc_clinical_nb_pca <- plot_pca(tc_clinical_nb)
tc_clinical_nb_pca$plot

clinical_pca_info <- pca_information(
    tc_clinical_norm, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells", "finaloutcome",
                   "clinic", "donor"))
clinical_pca_info$anova_neglogp_heatmap

clinical_pca_info$pca_plots$PC4_PC7
## Warning: ggrepel: 113 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

clinical_scores <- pca_highscores(tc_clinical_norm)
clinical_scores[["highest"]][,"Comp.4"]
##  [1] "15.73:ENSG00000168329" "14.97:ENSG00000133574" "14.03:ENSG00000204389"
##  [4] "14.02:ENSG00000171115" "13.9:ENSG00000163563"  "13.47:ENSG00000179144"
##  [7] "13.18:ENSG00000004799" "13.12:ENSG00000180871" "13:ENSG00000172086"   
## [10] "12.77:ENSG00000091106" "12.62:ENSG00000121858" "12.37:ENSG00000123405"
## [13] "12.36:ENSG00000175538" "12.04:ENSG00000138449" "12.02:ENSG00000109971"
## [16] "11.84:ENSG00000165118" "11.6:ENSG00000088986"  "11.59:ENSG00000135828"
## [19] "11.38:ENSG00000038274" "11.17:ENSG00000130150"
test_factors <- c("visitnumber", "typeofcells", "finaloutcome",
                  "clinic", "sex", "etnia")
clinical_varpart <- simple_varpart(tc_clinical, factors = test_factors)
## Subsetting on features.
## remove_genes_expt(), before removal, there were 18071 genes, now there are 17909.
clinical_varpart
## The result of using variancePartition with the model:
## ~ visitnumber + typeofcells + finaloutcome + clinic + sex + etnia

9.9 Iterative SVA followed by PCA

Another way to explore the effect of SVA is to iteratively increase the number of SVs removed by it and look at some simple plots of the resulting data. Ideally, this should complement the comparison of individual SVs vs. PCs performed by Theresa (spoiler alert, I think it did).

first <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch = "svaseq", surrogates = 1)
## Removing 5654 low-count genes (14298 remaining).
## Setting 193257 low elements to zero.
## transform_counts: Found 193257 values equal to 0, adding 1 to the matrix.
first_info <- pca_information(
    first, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
first_info$anova_neglogp_heatmap

first_info$pca_plots[["PC1_PC2"]]
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure
## Warning: ggrepel: 175 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

second <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                         filter = TRUE, batch = "svaseq", surrogates = 2) %>%
  set_expt_batches(fact = "clinic")
## Removing 5654 low-count genes (14298 remaining).
## Setting 31359 low elements to zero.
## transform_counts: Found 31359 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##   cali tumaco 
##     61    123
second_info <- pca_information(
    second, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
second_info$anova_neglogp_heatmap

third <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch = "svaseq", surrogates = 3) %>%
  set_expt_batches(fact = "clinic")
## Removing 5654 low-count genes (14298 remaining).
## Setting 27378 low elements to zero.
## transform_counts: Found 27378 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##   cali tumaco 
##     61    123
third_info <- pca_information(
    third, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
third_info$anova_neglogp_heatmap

fourth <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                         filter = TRUE, batch = "svaseq", surrogates = 4) %>%
  set_expt_batches(fact = "clinic")
## Removing 5654 low-count genes (14298 remaining).
## Setting 26043 low elements to zero.
## transform_counts: Found 26043 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##   cali tumaco 
##     61    123
fourth_info <- pca_information(
    fourth, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
fourth_info$anova_neglogp_heatmap

fourth_info[["pca_plots"]][["PC1_PC2"]]
## Warning: ggrepel: 107 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

fifth <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch = "svaseq", surrogates = 5) %>%
  set_expt_batches(fact = "clinic")
## Removing 5654 low-count genes (14298 remaining).
## Setting 27144 low elements to zero.
## transform_counts: Found 27144 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##   cali tumaco 
##     61    123
fifth_info <- pca_information(
    fifth, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
fifth_info$anova_neglogp_heatmap

fifth_info[["pca_plots"]][["PC1_PC12"]]
## Warning: ggrepel: 106 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

sixth <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch="svaseq", surrogates = 6) %>%
  set_expt_batches(fact = "clinic")
## Removing 5654 low-count genes (14298 remaining).
## Setting 24054 low elements to zero.
## transform_counts: Found 24054 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##   cali tumaco 
##     61    123
sixth_info <- pca_information(
    sixth, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
sixth_info$anova_neglogp_heatmap

seventh <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                          filter = TRUE, batch = "svaseq", surrogates = 7) %>%
  set_expt_batches(fact = "clinic")
## Removing 5654 low-count genes (14298 remaining).
## Setting 24579 low elements to zero.
## transform_counts: Found 24579 values equal to 0, adding 1 to the matrix.
## The number of samples by batch are:
## 
##   cali tumaco 
##     61    123
seventh_info <- pca_information(
    seventh, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
seventh_info$anova_neglogp_heatmap

eighth <- normalize_expt(tc_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch = "svaseq", surrogates = 8)
## Removing 5654 low-count genes (14298 remaining).
## Setting 24194 low elements to zero.
## transform_counts: Found 24194 values equal to 0, adding 1 to the matrix.
eighth_info <- pca_information(
    eighth, plot_pcas = TRUE, num_components = 30,
    expt_factors = c("visitnumber", "typeofcells",
                     "finaloutcome", "clinic"))
eighth_info$anova_neglogp_heatmap

10 Variance Partition

variancePartition (Hoffman and Schadt (2016)) provides a nice toolbox of methods to examine the relationship between various metadata factors in a dataset with respect to the variance observed in the dataset’s expression. We usually use it as a quick way to see the relative likelihood that a differential expression of various factors will provide useful/helpful output.

## Mostly running twice to make sure that reordering the factors does not affect the end result.
tc_varpart <- simple_varpart(
  tc_clinical_nobiop, factors = c("visitnumber", "typeofcells",
                                  "finaloutcome", "clinic", "sex", "etnia"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17871 genes, now there are 17730.
tc_varpart
## The result of using variancePartition with the model:
## ~ visitnumber + typeofcells + finaloutcome + clinic + sex + etnia

tc_varpartv2 <- simple_varpart(
  tc_clinical_nobiop, factors = c("donor", "visitnumber", "typeofcells",
                                  "finaloutcome"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17871 genes, now there are 17730.
pp(file = "images/tc_donor_visit_type_finaloutcome_varpart.pdf")
tc_varpartv2
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells + finaloutcome
dev.off()
## png 
##   2
tc_varpartv2
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells + finaloutcome

tc_varpartv3 <- simple_varpart(
  tc_clinical_nobiop, factors = c("donor", "visitnumber", "typeofcells"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17871 genes, now there are 17730.
pp(file = "images/tc_donor_visit_type_varpart.pdf")
tc_varpartv3
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells
dev.off()
## png 
##   2
tc_varpartv3
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells

tc_varpartv4 <- simple_varpart(
  tc_clinical_nobiop, factors = c("finaloutcome", "sex", "Ethnicity"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17871 genes, now there are 17730.
pp(file = "images/tc_final_sex_ethnicity_varpart.pdf")
tc_varpartv4
## The result of using variancePartition with the model:
## ~ finaloutcome + sex + Ethnicity
dev.off()
## png 
##   2
tc_varpartv4
## The result of using variancePartition with the model:
## ~ finaloutcome + sex + Ethnicity

t_varpartv3 <- simple_varpart(
  t_clinical_nobiop, factors = c("donor", "visitnumber", "typeofcells"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17801 genes, now there are 17633.
pp(file = "images/t_donor_visit_type_varpart.pdf")
t_varpartv3
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells
dev.off()
## png 
##   2
t_varpartv3
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells

c_varpartv3 <- simple_varpart(
  c_clinical, factors = c("donor", "visitnumber", "typeofcells"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17545 genes, now there are 16170.
pp(file = "images/c_donor_visit_type_varpart.pdf")
c_varpartv3
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells
dev.off()
## png 
##   2
c_varpartv3
## The result of using variancePartition with the model:
## ~ donor + visitnumber + typeofcells

10.1 Some factors of later interest

Maria Adelaida asked about using variancePartition to query a few other factors in the Cali, Tumaco, and both datasets. These factors include: Sex, Age, Ethnicity, Clinic; and potentially Adherence, time of evolution, and previous diagnosis.

I am not sure if those factors are already in the expressionset metadata, but if not we can certainly bring them back. In the following block I will therefore repeat a simple variancePartition analysis using first the full dataset (Tumaco+Cali), then each clinic alone; in each instance I will do one round with sex, ethnicity, age, and clinic followed by the same and finaloutcome (as a reference point to something we are already looking at).

table(pData(tc_clinical_nobiop)$typeofcells)
## 
## eosinophils   monocytes neutrophils 
##          41          63          62
table(pData(t_clinical_nobiop)$typeofcells)
## 
## eosinophils   monocytes neutrophils 
##          26          42          41
table(pData(c_clinical_nobiop)$typeofcells)
## 
## eosinophils   monocytes neutrophils 
##          15          21          21
tc_fun_varpart <- simple_varpart(tc_clinical_nobiop,
                                 factors = c("sex", "etnia", "Age", "clinic"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17871 genes, now there are 17730.
pp(file = "images/tc_fun_varpart.pdf")
tc_fun_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + clinic
dev.off()
## png 
##   2
tc_fun_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + clinic

tc_fun_outcome_varpart <- simple_varpart(tc_clinical_nobiop,
                                         factors = c("sex", "etnia", "Age", "clinic", "finaloutcome"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17871 genes, now there are 17730.
pp(file = "images/tc_fun_outcome_varpart.pdf")
tc_fun_outcome_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + clinic + finaloutcome
dev.off()
## png 
##   2
tc_fun_outcome_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + clinic + finaloutcome

c_fun_varpart <- simple_varpart(c_clinical_nobiop,
                                factors = c("sex", "etnia", "Age"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17142 genes, now there are 16146.
pp(file = "images/c_fun_varpart.pdf")
c_fun_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age
dev.off()
## png 
##   2
c_fun_outcome_varpart <- simple_varpart(c_clinical_nobiop,
                                        factors = c("sex", "etnia", "Age", "finaloutcome"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17142 genes, now there are 16146.
pp(file = "images/c_fun_outcome_varpart.pdf")
c_fun_outcome_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + finaloutcome
dev.off()
## png 
##   2
c_fun_outcome_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + finaloutcome

t_fun_varpart <- simple_varpart(t_clinical_nobiop,
                                factors = c("sex", "etnia", "Age"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17801 genes, now there are 17633.
pp(file = "images/t_fun_varpart.pdf")
t_fun_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age
dev.off()
## png 
##   2
t_fun_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age

t_fun_outcome_varpart <- simple_varpart(t_clinical_nobiop,
                                        factors = c("sex", "etnia", "Age", "finaloutcome"))
## Subsetting on features.
## remove_genes_expt(), before removal, there were 17801 genes, now there are 17633.
pp(file = "images/t_fun_outcome_varpart.pdf")
t_fun_outcome_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + finaloutcome
dev.off()
## png 
##   2
t_fun_outcome_varpart
## The result of using variancePartition with the model:
## ~ sex + etnia + Age + finaloutcome

10.2 Visualize: Repeat plots using only the Tumaco samples

The following should be a nearly copy/pasted version of the above, but limited to the Tumaco samples.

10.2.1 All samples

10.2.1.1 Figure xx panels A+B

t_clinical_nobiop_norm <- normalize_expt(t_clinical_nobiop, filter = TRUE, norm = "quant",
                                         convert = "cpm", transform = "log2")
## Removing 8042 low-count genes (11910 remaining).
## transform_counts: Found 93 values equal to 0, adding 1 to the matrix.
t_clinical_nobiop_pca <- plot_pca(t_clinical_nobiop_norm, plot_labels = FALSE)
pp(file = "figures/t_clinical_nobiop_pca.svg")
t_clinical_nobiop_pca[["plot"]]
dev.off()
## png 
##   2
t_clinical_nobiop_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.

t_clinical_nobiop_nb <- normalize_expt(t_clinical_nobiop, filter = TRUE, convert = "cpm",
                                       transform = "log2", batch = "svaseq")
## Removing 8042 low-count genes (11910 remaining).
## Setting 9605 low elements to zero.
## transform_counts: Found 9605 values equal to 0, adding 1 to the matrix.
t_clinical_nobiop_nb_pca <- plot_pca(t_clinical_nobiop_nb, plot_labels = FALSE)
pp(file = "figures/t_clinical_nobiop_sva_figxxb.pdf")
t_clinical_nobiop_nb_pca[["plot"]]
dev.off()
## png 
##   2
t_clinical_nobiop_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.

10.2.1.2 Figure xx panels C+D

tc_clinical_nobiop_norm <- normalize_expt(tc_clinical_nobiop, filter = TRUE, norm = "quant",
                                          convert = "cpm", transform = "log2")
## Removing 7790 low-count genes (12162 remaining).
## transform_counts: Found 124 values equal to 0, adding 1 to the matrix.
tc_clinical_nobiop_pca <- plot_pca(tc_clinical_nobiop_norm, plot_labels = FALSE)
pp(file = "figures/tc_clinical_nobiop_pca.svg")
tc_clinical_nobiop_pca[["plot"]]
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure
dev.off()
## png 
##   2
tc_clinical_nobiop_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

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

tc_clinical_nobiop_nb <- normalize_expt(tc_clinical_nobiop, filter = TRUE, convert = "cpm",
                                        transform = "log2", batch = "svaseq")
## Removing 7790 low-count genes (12162 remaining).
## Setting 17777 low elements to zero.
## transform_counts: Found 17777 values equal to 0, adding 1 to the matrix.
tc_clinical_nobiop_nb_pca <- plot_pca(tc_clinical_nobiop_nb, plot_labels = FALSE)
pp(file = "figures/tc_clinical_nobiop_sva_pca.svg")
tc_clinical_nobiop_nb_pca[["plot"]]
dev.off()
## png 
##   2
tc_clinical_nobiop_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.

Now we have a new, smaller set of primary samples which are categorized by cell type.

10.2.2 Visualize: Biopsy samples only Tumaco

The biopsy samples remain basically impenetrable. I think it would be particularly nice if we could judge cure/fail from a visit 1 biopsy.

t_biopsies_norm <- normalize_expt(t_biopsies, transform = "log2", convert = "cpm",
  norm = "quant", filter = TRUE)
## Removing 6439 low-count genes (13513 remaining).
## transform_counts: Found 136 values equal to 0, adding 1 to the matrix.
t_biopsies_pca <- plot_pca(t_biopsies_norm,
  plot_labels = FALSE)
t_biopsies_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 1.

t_biopsies_nb <- normalize_expt(t_biopsies, transform = "log2", convert = "cpm",
                                batch = "svaseq", filter = TRUE)
## Removing 6439 low-count genes (13513 remaining).
## Setting 146 low elements to zero.
## transform_counts: Found 146 values equal to 0, adding 1 to the matrix.
t_biopsies_nb_pca <- plot_pca(t_biopsies_nb, plot_labels = FALSE)
t_biopsies_nb_pca$plot

10.2.3 Visualize: Monocyte samples only Tumaco

In contrast, I suspect that we can get meaningful data from the other cell types. The monocyte samples are still a bit messy.

10.2.4 Figure 4A: Monocytes

t_monocyte_norm <- normalize_expt(t_monocytes, transform = "log2", convert = "cpm",
                                  norm = "quant", filter = TRUE)
## Removing 9090 low-count genes (10862 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
t_monocyte_pca <- plot_pca(t_monocyte_norm,
  plot_labels = FALSE)
t_monocyte_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 3, 2, 1.

t_monocyte_nb <- normalize_expt(t_monocytes, transform = "log2", convert = "cpm",
                                batch = "svaseq", filter = TRUE)
## Removing 9090 low-count genes (10862 remaining).
## Setting 736 low elements to zero.
## transform_counts: Found 736 values equal to 0, adding 1 to the matrix.
t_monocyte_nb_pca <- plot_pca(t_monocyte_nb, plot_labels = FALSE)
pp(file = "figures/figure4A_monocytes.svg")
t_monocyte_nb_pca$plot
dev.off()
## png 
##   2
t_monocyte_nb_pca$plot

10.2.5 Visualize: Neutrophil samples only Tumaco

10.2.6 Figure 4A: Neutrophils

t_neutrophil_norm <- normalize_expt(t_neutrophils, transform = "log2", convert = "cpm",
                                    norm = "quant", filter = TRUE)
## Removing 10851 low-count genes (9101 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_neutrophil_pca <- plot_pca(t_neutrophil_norm,
                             plot_labels = FALSE)
t_neutrophil_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 3, 2, 1.

t_neutrophil_nb <- normalize_expt(t_neutrophils, transform = "log2", convert = "cpm",
                                     batch = "svaseq", filter = TRUE)
## Removing 10851 low-count genes (9101 remaining).
## Setting 754 low elements to zero.
## transform_counts: Found 754 values equal to 0, adding 1 to the matrix.
t_neutrophil_nb_pca <- plot_pca(t_neutrophil_nb, plot_labels = FALSE)
pp(file = "figures/figure4A_neutrophils.svg")
t_neutrophil_nb_pca$plot
dev.off()
## png 
##   2
t_neutrophil_nb_pca$plot

10.2.7 Visualize: Eosinophil samples only Tumaco

10.2.8 Figure 4A: Eosinophils

t_eosinophil_norm <- normalize_expt(t_eosinophils, transform = "log2", convert = "cpm",
                                    norm = "quant", filter = TRUE)
## Removing 9420 low-count genes (10532 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_eosinophil_pca <- plot_pca(t_eosinophil_norm,
                             plot_labels = FALSE)
t_eosinophil_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 3, 2, 1.

t_eosinophil_nb <- normalize_expt(t_eosinophils, transform = "log2", convert = "cpm",
                                  batch = "svaseq", filter = TRUE)
## Removing 9420 low-count genes (10532 remaining).
## Setting 327 low elements to zero.
## transform_counts: Found 327 values equal to 0, adding 1 to the matrix.
t_eosinophil_nb_pca <- plot_pca(t_eosinophil_nb, plot_labels = FALSE)
pp(file = "figures/figure4A_eosinophils.svg")
t_eosinophil_nb_pca$plot
dev.off()
## png 
##   2
t_eosinophil_nb_pca$plot

10.2.9 Visualize: Look at Cell types C/F by visit

10.2.9.1 Monocytes, Visit 1

t_monocyte_v1 <- subset_expt(t_monocytes, subset = "visitnumber=='1'")
## The samples excluded are: TMRC30056, TMRC30105, TMRC30082, TMRC30169, TMRC30096, TMRC30115, TMRC30030, TMRC30037, TMRC30194, TMRC30049, TMRC30055, TMRC30171, TMRC30139, TMRC30157, TMRC30183, TMRC30072, TMRC30078, TMRC30129, TMRC30172, TMRC30142, TMRC30145, TMRC30199, TMRC30201, TMRC30205, TMRC30217, TMRC30219.
## subset_expt(): There were 42, now there are 16 samples.
t_monocyte_v1_norm <- normalize_expt(t_monocyte_v1, norm = "quant", convert = "cpm",
                                     transform = "log2", filter = TRUE)
## Removing 9470 low-count genes (10482 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_monocyte_v1_pca <- plot_pca(t_monocyte_v1_norm, plot_labels = FALSE)
t_monocyte_v1_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 1.

t_monocyte_v1_nb <- normalize_expt(t_monocyte_v1, convert = "cpm",
                                   transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9470 low-count genes (10482 remaining).
## Setting 190 low elements to zero.
## transform_counts: Found 190 values equal to 0, adding 1 to the matrix.
t_monocyte_v1_nb_pca <- plot_pca(t_monocyte_v1_nb, plot_labels = FALSE)
t_monocyte_v1_nb_pca$plot

10.2.9.2 Monocytes Visit 2

t_monocyte_v2 <- subset_expt(t_monocytes, subset = "visitnumber=='2'")
## The samples excluded are: TMRC30105, TMRC30080, TMRC30169, TMRC30107, TMRC30115, TMRC30014, TMRC30037, TMRC30165, TMRC30046, TMRC30055, TMRC30191, TMRC30041, TMRC30139, TMRC30132, TMRC30183, TMRC30123, TMRC30078, TMRC30184, TMRC30172, TMRC30174, TMRC30145, TMRC30197, TMRC30201, TMRC30203, TMRC30205, TMRC30237, TMRC30207, TMRC30219, TMRC30264.
## subset_expt(): There were 42, now there are 13 samples.
t_monocyte_v2_norm <- normalize_expt(t_monocyte_v2, norm = "quant", convert = "cpm",
                                     transform = "log2", filter = TRUE)
## Removing 9429 low-count genes (10523 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_monocyte_v2_pca <- plot_pca(t_monocyte_v2_norm, plot_labels = FALSE)
t_monocyte_v2_pca$plot

t_monocyte_v2_nb <- normalize_expt(t_monocyte_v2, convert = "cpm",
                                   transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9429 low-count genes (10523 remaining).
## Setting 117 low elements to zero.
## transform_counts: Found 117 values equal to 0, adding 1 to the matrix.
t_monocyte_v2_nb_pca <- plot_pca(t_monocyte_v2_nb, plot_labels = FALSE)
t_monocyte_v2_nb_pca$plot

10.2.9.3 Monocytes Visit 3

t_monocyte_v3 <- subset_expt(t_monocytes, subset = "visitnumber=='3'")
## The samples excluded are: TMRC30056, TMRC30080, TMRC30082, TMRC30107, TMRC30096, TMRC30014, TMRC30030, TMRC30165, TMRC30194, TMRC30046, TMRC30049, TMRC30191, TMRC30041, TMRC30171, TMRC30132, TMRC30157, TMRC30123, TMRC30072, TMRC30184, TMRC30129, TMRC30174, TMRC30142, TMRC30197, TMRC30199, TMRC30203, TMRC30237, TMRC30207, TMRC30217, TMRC30264.
## subset_expt(): There were 42, now there are 13 samples.
t_monocyte_v3_norm <- normalize_expt(t_monocyte_v3, norm = "quant", convert = "cpm",
                                   transform = "log2", filter = TRUE)
## Removing 9575 low-count genes (10377 remaining).
## transform_counts: Found 16 values equal to 0, adding 1 to the matrix.
t_monocyte_v3_pca <- plot_pca(t_monocyte_v3_norm, plot_labels = FALSE)
t_monocyte_v3_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 3.

t_monocyte_v3_nb <- normalize_expt(t_monocyte_v3, convert = "cpm",
                                   transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9575 low-count genes (10377 remaining).
## Setting 58 low elements to zero.
## transform_counts: Found 58 values equal to 0, adding 1 to the matrix.
t_monocyte_v3_nb_pca <- plot_pca(t_monocyte_v3_nb, plot_labels = FALSE)
t_monocyte_v3_nb_pca$plot

10.2.9.4 Neutrophils, Visit 1

```{r} neutrophils_by_visit_v1} t_neutrophil_v1 <- subset_expt(t_neutrophils, subset = “visitnumber==‘1’”) t_neutrophil_v1_norm <- normalize_expt(t_neutrophil_v1, norm = “quant”, convert = “cpm”, transform = “log2”, filter = TRUE) t_neutrophil_v1_pca <- plot_pca(t_neutrophil_v1_norm, plot_labels = FALSE) t_neutrophil_v1_pca$plot

t_neutrophil_v1_nb <- normalize_expt(t_neutrophil_v1, convert = “cpm”, transform = “log2”, filter = TRUE, batch = “ruvg”) t_neutrophil_v1_nb_pca <- plot_pca(t_neutrophil_v1_nb, plot_labels = FALSE) t_neutrophil_v1_nb_pca$plot


#### Neutrophils Visit 2


```r
t_neutrophil_v2 <- subset_expt(t_neutrophils, subset = "visitnumber=='2'")
## The samples excluded are: TMRC30094, TMRC30103, TMRC30170, TMRC30083, TMRC30121, TMRC30021, TMRC30027, TMRC30166, TMRC30047, TMRC30068, TMRC30192, TMRC30042, TMRC30160, TMRC30167, TMRC30133, TMRC30116, TMRC30088, TMRC30134, TMRC30175, TMRC30146, TMRC30198, TMRC30202, TMRC30204, TMRC30206, TMRC30238, TMRC30208, TMRC30220, TMRC30265.
## subset_expt(): There were 41, now there are 13 samples.
t_neutrophil_v2_norm <- normalize_expt(t_neutrophil_v2, norm = "quant", convert = "cpm",
                                       transform = "log2", filter = TRUE)
## Removing 11500 low-count genes (8452 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
t_neutrophil_v2_pca <- plot_pca(t_neutrophil_v2_norm, plot_labels = FALSE)
t_neutrophil_v2_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 2.

t_neutrophil_v2_nb <- normalize_expt(t_neutrophil_v2, convert = "cpm",
                                     transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 11500 low-count genes (8452 remaining).
## Setting 78 low elements to zero.
## transform_counts: Found 78 values equal to 0, adding 1 to the matrix.
t_neutrophil_v2_nb_pca <- plot_pca(t_neutrophil_v2_nb, plot_labels = FALSE)
t_neutrophil_v2_nb_pca$plot

10.2.9.5 Neutrophils Visit 3

t_neutrophil_v3 <- subset_expt(t_neutrophils, subset = "visitnumber=='3'")
## The samples excluded are: TMRC30058, TMRC30103, TMRC30093, TMRC30083, TMRC30118, TMRC30021, TMRC30031, TMRC30166, TMRC30195, TMRC30047, TMRC30053, TMRC30192, TMRC30042, TMRC30158, TMRC30167, TMRC30181, TMRC30116, TMRC30076, TMRC30134, TMRC30137, TMRC30175, TMRC30143, TMRC30198, TMRC30200, TMRC30204, TMRC30238, TMRC30208, TMRC30218, TMRC30265.
## subset_expt(): There were 41, now there are 12 samples.
t_neutrophil_v3_norm <- normalize_expt(t_neutrophil_v3, norm = "quant", convert = "cpm",
                                       transform = "log3", filter = TRUE)
## Removing 11447 low-count genes (8505 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
## Did not recognize the transformation, leaving the table.
##  Recognized transformations include: 'log2', 'log10', 'log'
t_neutrophil_v3_pca <- plot_pca(t_neutrophil_v3_norm, plot_labels = FALSE)
t_neutrophil_v3_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 3.

t_neutrophil_v3_nb <- normalize_expt(t_neutrophil_v3, convert = "cpm",
                                     transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 11447 low-count genes (8505 remaining).
## Setting 83 low elements to zero.
## transform_counts: Found 83 values equal to 0, adding 1 to the matrix.
t_neutrophil_v3_nb_pca <- plot_pca(t_neutrophil_v3_nb, plot_labels = FALSE)
t_neutrophil_v3_nb_pca$plot

10.2.9.6 Eosinophils, Visit 1

t_eosinophil_v1 <- subset_expt(t_eosinophils, subset = "visitnumber=='1'")
## The samples excluded are: TMRC30113, TMRC30164, TMRC30119, TMRC30122, TMRC30032, TMRC30028, TMRC30196, TMRC30054, TMRC30070, TMRC30159, TMRC30161, TMRC30182, TMRC30136, TMRC30077, TMRC30079, TMRC30173, TMRC30144, TMRC30147.
## subset_expt(): There were 26, now there are 8 samples.
t_eosinophil_v1_norm <- normalize_expt(t_eosinophil_v1, norm = "quant", convert = "cpm",
                                   transform = "log2", filter = TRUE)
## Removing 9973 low-count genes (9979 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_eosinophil_v1_pca <- plot_pca(t_eosinophil_v1_norm, plot_labels = FALSE)
t_eosinophil_v1_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 1.

t_eosinophil_v1_nb <- normalize_expt(t_eosinophil_v1, convert = "cpm",
                                     transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9973 low-count genes (9979 remaining).
## Setting 57 low elements to zero.
## transform_counts: Found 57 values equal to 0, adding 1 to the matrix.
t_eosinophil_v1_nb_pca <- plot_pca(t_eosinophil_v1_nb, plot_labels = FALSE)
t_eosinophil_v1_nb_pca$plot

10.2.9.7 Eosinophils Visit 2

t_eosinophil_v2 <- subset_expt(t_eosinophils, subset = "visitnumber=='2'")
## The samples excluded are: TMRC30071, TMRC30164, TMRC30122, TMRC30029, TMRC30028, TMRC30180, TMRC30048, TMRC30070, TMRC30043, TMRC30161, TMRC30168, TMRC30136, TMRC30074, TMRC30079, TMRC30135, TMRC30173, TMRC30147.
## subset_expt(): There were 26, now there are 9 samples.
t_eosinophil_v2_norm <- normalize_expt(t_eosinophil_v2, norm = "quant", convert = "cpm",
                                       transform = "log2", filter = TRUE)
## Removing 9835 low-count genes (10117 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_eosinophil_v2_pca <- plot_pca(t_eosinophil_v2_norm, plot_labels = FALSE)
t_eosinophil_v2_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 2.

t_eosinophil_v2_nb <- normalize_expt(t_eosinophil_v2, convert = "cpm",
                                     transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9835 low-count genes (10117 remaining).
## Setting 60 low elements to zero.
## transform_counts: Found 60 values equal to 0, adding 1 to the matrix.
t_eosinophil_v2_nb_pca <- plot_pca(t_eosinophil_v2_nb, plot_labels = FALSE)
t_eosinophil_v2_nb_pca$plot

10.2.9.8 Eosinophils Visit 3

t_eosinophil_v3 <- subset_expt(t_eosinophils, subset = "visitnumber=='3'")
## The samples excluded are: TMRC30071, TMRC30113, TMRC30119, TMRC30029, TMRC30032, TMRC30180, TMRC30196, TMRC30048, TMRC30054, TMRC30043, TMRC30159, TMRC30168, TMRC30182, TMRC30074, TMRC30077, TMRC30135, TMRC30144.
## subset_expt(): There were 26, now there are 9 samples.
t_eosinophil_v3_norm <- normalize_expt(t_eosinophil_v3, norm = "quant", convert = "cpm",
                                       transform = "log3", filter = TRUE)
## Removing 9872 low-count genes (10080 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
## Did not recognize the transformation, leaving the table.
##  Recognized transformations include: 'log2', 'log10', 'log'
t_eosinophil_v3_pca <- plot_pca(t_eosinophil_v3_norm, plot_labels = FALSE)
t_eosinophil_v3_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by tumaco_cure, tumaco_failure
## Shapes are defined by 3.

t_eosinophil_v3_nb <- normalize_expt(t_eosinophil_v3, convert = "cpm",
                                     transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9872 low-count genes (10080 remaining).
## Setting 48 low elements to zero.
## transform_counts: Found 48 values equal to 0, adding 1 to the matrix.
t_eosinophil_v3_nb_pca <- plot_pca(t_eosinophil_v3_nb, plot_labels = FALSE)
t_eosinophil_v3_nb_pca$plot

10.3 Recategorize: Concatenate cure/fail and cell type

In the following block the experimental condition was reset to the concatenation of clinical outcome and type of cells. There are an insufficient number of biopsy samples for them to be useful in this visualization, so they are ignored.

desired_levels <- c("cure_biopsy", "failure_biopsy", "cure_eosinophils", "failure_eosinophils",
                    "cure_monocytes", "failure_monocytes", "cure_neutrophils", "failure_neutrophils")
new_fact <- factor(
    paste0(pData(t_clinical)[["condition"]], "_",
           pData(t_clinical)[["batch"]]),
    levels = desired_levels)

t_clinical_concat <- set_expt_conditions(t_clinical, fact = new_fact) %>%
  set_expt_batches(fact = "visitnumber") %>%
  set_expt_colors(color_choices[["cf_type"]]) %>%
  subset_expt(subset="typeofcells!='biopsy'")
## The numbers of samples by condition are:
## 
##         cure_biopsy      failure_biopsy    cure_eosinophils failure_eosinophils 
##                   9                   5                  17                   9 
##      cure_monocytes   failure_monocytes    cure_neutrophils failure_neutrophils 
##                  21                  21                  20                  21
## The number of samples by batch are:
## 
##  3  2  1 
## 34 35 54
## The samples excluded are: TMRC30016, TMRC30017, TMRC30018, TMRC30019, TMRC30020, TMRC30022, TMRC30026, TMRC30044, TMRC30045, TMRC30152, TMRC30177, TMRC30155, TMRC30154, TMRC30241.
## subset_expt(): There were 123, now there are 109 samples.
## Try to ensure that the levels stay in the order I want
meta <- pData(t_clinical_concat) %>%
  mutate(condition = fct_relevel(condition, desired_levels))
## Warning: There was 1 warning in `mutate()`.
## i In argument: `condition = fct_relevel(condition, desired_levels)`.
## Caused by warning:
## ! 2 unknown levels in `f`: cure_biopsy and failure_biopsy
pData(t_clinical_concat) <- meta

10.3.1 Visualize: Look at Tumaco-only samples by cell type and cure/fail

The following block is pretty wild to my eyes; it seems to me that the variances introduced by cell type basically wipe out the apparent differences between cure/fail that we were able to see previously.

I suppose this is not entirely surprising, but when we had the Cali samples it at least looked like there were differences which were explicitly between cure/fail across cell types. I suppose this means those differences were actually coming from the unbalanced state of the two clinics from the perspective of clinic.

t_clinical_concat_norm <- normalize_expt(t_clinical_concat, transform = "log2", convert = "cpm",
                                       norm = "quant", filter = TRUE)
## Removing 8042 low-count genes (11910 remaining).
## transform_counts: Found 93 values equal to 0, adding 1 to the matrix.
t_clinical_concat_norm_pca <- plot_pca(t_clinical_concat_norm)
t_clinical_concat_norm_pca$plot

t_clinical_concat_nb <- normalize_expt(t_clinical_concat, transform = "log2", convert = "cpm",
                                       batch = "svaseq", filter = TRUE)
## Removing 8042 low-count genes (11910 remaining).
## Setting 9595 low elements to zero.
## transform_counts: Found 9595 values equal to 0, adding 1 to the matrix.
t_clinical_concat_nb_pca <- plot_pca(t_clinical_concat_nb)
t_clinical_concat_nb_pca$plot

11 Visit comparisons

Let us shift the focus from cell type and/or Cure/Fail to the visit number. As you are likely aware, the three visits are significantly spread apart according to the clinical treatment of each patient. Thus we will now separate the samples by visit in order to more easily see what new patterns emerge.

11.1 Recategorize: All visits together

Now let us shift the view slightly to focus on changes observed over time.

I have a note from Maria Adelaida that she would like to flesh this section out with some more pdf versions of various pre/post SVA plots. If I understood/wrote down correctly her goals:

  1. 3 visits, all cell types.
  2. 3 visits, all clinical cell types (e.g. no biopsies), only Tumaco
  3. #1, #2 after sva
  4. Repeat the only C/F by visit with/out SVA and make pretty versions.
tc_visit_expt <- set_expt_conditions(tc_clinical, fact = "visitnumber") %>%
  set_expt_batches(fact = "finaloutcome") %>%
  set_expt_colors(color_choices[["visit2"]])
## The numbers of samples by condition are:
## 
##  3  2  1 
## 51 50 83
## The number of samples by batch are:
## 
##    cure failure 
##     122      62
tc_visit_norm <- normalize_expt(tc_visit_expt, filter = TRUE, transform = "log2",
                                convert = "cpm", norm = "quant")
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 677 values equal to 0, adding 1 to the matrix.
tc_visit_norm_pca <- plot_pca(tc_visit_norm)
pp(file = "images/tc_visit_norm_alltypes.pdf")
tc_visit_norm_pca$plot
dev.off()
## png 
##   2
tc_visit_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by 3, 2, 1
## Shapes are defined by cure, failure.

tc_visit_nb <- normalize_expt(tc_visit_expt, filter = TRUE, transform = "log2",
                              convert = "cpm", batch = "svaseq")
## Removing 5654 low-count genes (14298 remaining).
## Setting 39181 low elements to zero.
## transform_counts: Found 39181 values equal to 0, adding 1 to the matrix.
tc_visit_nb_pca <- plot_pca(tc_visit_nb)
pp(file = "images/tc_visit_sva_alltypes.pdf")
tc_visit_nb_pca$plot
dev.off()
## png 
##   2
tc_visit_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by 3, 2, 1
## Shapes are defined by cure, failure.

##  Repeat for only Tumaco
t_visit_expt <- subset_expt(tc_clinical, subset = "clinic=='tumaco'") %>%
  set_expt_conditions(fact = "visitnumber") %>%
  set_expt_batches(fact = "finaloutcome") %>%
  set_expt_colors(color_choices[["visit2"]])
## The samples excluded are: TMRC30156, TMRC30185, TMRC30186, TMRC30178, TMRC30179, TMRC30221, TMRC30222, TMRC30223, TMRC30224, TMRC30269, TMRC30148, TMRC30149, TMRC30253, TMRC30150, TMRC30140, TMRC30138, TMRC30176, TMRC30153, TMRC30151, TMRC30234, TMRC30235, TMRC30270, TMRC30225, TMRC30226, TMRC30227, TMRC30228, TMRC30229, TMRC30230, TMRC30231, TMRC30232, TMRC30233, TMRC30209, TMRC30210, TMRC30211, TMRC30212, TMRC30213, TMRC30216, TMRC30214, TMRC30215, TMRC30271, TMRC30273, TMRC30275, TMRC30272, TMRC30274, TMRC30276, TMRC30254, TMRC30255, TMRC30256, TMRC30277, TMRC30239, TMRC30240, TMRC30278, TMRC30279, TMRC30280, TMRC30257, TMRC30258, TMRC30281, TMRC30283, TMRC30284, TMRC30282, TMRC30285.
## subset_expt(): There were 184, now there are 123 samples.
## The numbers of samples by condition are:
## 
##  3  2  1 
## 34 35 54
## The number of samples by batch are:
## 
##    cure failure 
##      67      56
t_visit_norm <- normalize_expt(t_visit_expt, filter = TRUE, transform = "log2",
                                convert = "cpm", norm = "quant")
## Removing 5796 low-count genes (14156 remaining).
## transform_counts: Found 299 values equal to 0, adding 1 to the matrix.
t_visit_norm_pca <- plot_pca(t_visit_norm)
pp(file = "images/t_visit_norm_alltypes.pdf")
t_visit_norm_pca$plot
dev.off()
## png 
##   2
t_visit_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by 3, 2, 1
## Shapes are defined by cure, failure.

t_visit_nb <- normalize_expt(t_visit_expt, filter = TRUE, transform = "log2",
                             convert = "cpm", batch = "svaseq")
## Removing 5796 low-count genes (14156 remaining).
## Setting 19869 low elements to zero.
## transform_counts: Found 19869 values equal to 0, adding 1 to the matrix.
t_visit_nb_pca <- plot_pca(t_visit_nb)
pp(file = "images/t_visit_sva_alltypes.pdf")
t_visit_nb_pca$plot
dev.off()
## png 
##   2
t_visit_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by 3, 2, 1
## Shapes are defined by cure, failure.

## Finally, limit to only the clinical celltypes
t_visit_clinical_expt <- subset_expt(t_visit_expt, subset = "typeofcells!='biopsy'")
## The samples excluded are: TMRC30016, TMRC30017, TMRC30018, TMRC30019, TMRC30020, TMRC30022, TMRC30026, TMRC30044, TMRC30045, TMRC30152, TMRC30177, TMRC30155, TMRC30154, TMRC30241.
## subset_expt(): There were 123, now there are 109 samples.
t_visit_clinical_norm <- normalize_expt(t_visit_clinical_expt, filter = TRUE, transform = "log2",
                                        convert = "cpm", norm = "quant")
## Removing 8042 low-count genes (11910 remaining).
## transform_counts: Found 93 values equal to 0, adding 1 to the matrix.
t_visit_clinical_norm_pca <- plot_pca(t_visit_clinical_norm)
pp(file = "images/t_visit_clinical_norm_alltypes.pdf")
t_visit_clinical_norm_pca$plot
dev.off()
## png 
##   2
t_visit_clinical_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by 3, 2, 1
## Shapes are defined by cure, failure.

t_visit_clinical_nb <- normalize_expt(t_visit_clinical_expt, filter = TRUE,
                                      transform = "log2", convert = "cpm", batch = "svaseq")
## Removing 8042 low-count genes (11910 remaining).
## Setting 9636 low elements to zero.
## transform_counts: Found 9636 values equal to 0, adding 1 to the matrix.
t_visit_clinical_nb_pca <- plot_pca(t_visit_clinical_nb)
pp(file = "images/t_visit_nobiop_sva_alltypes.pdf")
t_visit_clinical_nb_pca$plot
dev.off()
## png 
##   2
t_visit_clinical_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by 3, 2, 1
## Shapes are defined by cure, failure.

When looking at all cell types, it is quite difficult to see differences among the three visits.

11.2 Visualize: C/F for only the visit 1 samples

Wen we had both Cali and Tumaco samples, it looked like there was variance suggesting differences between cure and fail for visit 1. I think the following block will suggest pretty strongly that this was not true.

tv1_samples <- set_expt_batches(tv1_samples, fact = "typeofcells")
## The number of samples by batch are:
## 
##      biopsy eosinophils   monocytes neutrophils 
##          14           8          16          16
tv1_norm <- normalize_expt(tv1_samples, transform = "log2", convert = "cpm",
                          norm = "quant", filter = TRUE)
## Removing 5929 low-count genes (14023 remaining).
## transform_counts: Found 272 values equal to 0, adding 1 to the matrix.
tv1_pca <- plot_pca(tv1_norm)
pp(file = "images/tv1_pca.pdf")
tv1_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.
dev.off()
## png 
##   2
tv1_pca$plot

tv1_nb <- normalize_expt(tv1_samples, transform = "log2", convert = "cpm",
                         filter = TRUE, batch = "svaseq")
## Removing 5929 low-count genes (14023 remaining).
## Setting 7655 low elements to zero.
## transform_counts: Found 7655 values equal to 0, adding 1 to the matrix.
tv1_nb_pca <- plot_pca(tv1_nb, plot_labels = FALSE)
pp(file = "images/tv1_sva_pca.pdf")
tv1_nb_pca$plot
dev.off()
## png 
##   2
tv1_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by biopsy, eosinophils, monocytes, neutrophils.

11.3 Visualize: C/F for only the visit 2 samples

tv2_samples <- set_expt_batches(tv2_samples, fact = "typeofcells")
## The number of samples by batch are:
## 
## eosinophils   monocytes neutrophils 
##           9          13          13
tv2_norm <- normalize_expt(tv2_samples, transform = "log2", convert = "cpm",
                          norm = "quant", filter = TRUE)
## Removing 8390 low-count genes (11562 remaining).
## transform_counts: Found 14 values equal to 0, adding 1 to the matrix.
tv2_pca <- plot_pca(tv2_norm)
pp(file = "images/tv2_pca.pdf")
tv2_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.
dev.off()
## png 
##   2
tv2_pca$plot

tv2_nb <- normalize_expt(tv2_samples, transform = "log2", convert = "cpm",
                         filter = TRUE, batch = "svaseq")
## Removing 8390 low-count genes (11562 remaining).
## Setting 2857 low elements to zero.
## transform_counts: Found 2857 values equal to 0, adding 1 to the matrix.
tv2_nb_pca <- plot_pca(tv2_nb, plot_labels = FALSE)
pp(file = "images/tv2_sva_pca.pdf")
tv2_nb_pca$plot
dev.off()
## png 
##   2
tv2_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.

11.4 Visualize: C/F for only the visit 3 samples

tv3_samples <- set_expt_batches(tv3_samples, fact = "typeofcells")
## The number of samples by batch are:
## 
## eosinophils   monocytes neutrophils 
##           9          13          12
tv3_norm <- normalize_expt(tv3_samples, transform = "log2", convert = "cpm",
                          norm = "quant", filter = TRUE)
## Removing 8500 low-count genes (11452 remaining).
## transform_counts: Found 35 values equal to 0, adding 1 to the matrix.
tv3_pca <- plot_pca(tv3_norm)
pp(file = "images/tv3_pca.pdf")
tv3_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.
dev.off()
## png 
##   2
tv3_pca$plot

tv3_nb <- normalize_expt(tv3_samples, transform = "log2", convert = "cpm",
                         filter = TRUE, batch = "svaseq")
## Removing 8500 low-count genes (11452 remaining).
## Setting 1887 low elements to zero.
## transform_counts: Found 1887 values equal to 0, adding 1 to the matrix.
tv3_nb_pca <- plot_pca(tv3_nb, plot_labels = FALSE)
pp(file = "images/tv3_sva_pca.pdf")
tv3_nb_pca$plot
dev.off()
## png 
##   2
tv3_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by eosinophils, monocytes, neutrophils.

11.4.1 Visualize: Comparing 3 visits by cell type

Separate the samples by cell type in order to more easily observe patterns with respect to visit and clinical outcome.

11.4.1.1 Monocytes across visits

In the following few blocks we are coloring the samples by visit and final outcome. We are also separating the three primary celltypes of interest. If I understand correctly, Maria Adelaida has an interest in a nice version of each of these 6 plots (normalized pca before/after SVA for each celltype).

t_visitcf_monocyte_norm <- normalize_expt(t_visitcf_monocyte, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 9090 low-count genes (10862 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
t_visitcf_monocyte_pca <- plot_pca(t_visitcf_monocyte_norm, plot_labels = FALSE)
pp(file = "images/t_monocyte_visitcf_norm_pca.pdf")
t_visitcf_monocyte_pca$plot
dev.off()
## png 
##   2
t_visitcf_monocyte_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by monocytes.

t_visitcf_monocyte_disheat <- plot_disheat(t_visitcf_monocyte_norm)
t_visitcf_monocyte_disheat$plot

t_visitcf_monocyte_nb <- normalize_expt(t_visitcf_monocyte, convert = "cpm",
                                    transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9090 low-count genes (10862 remaining).
## Setting 700 low elements to zero.
## transform_counts: Found 700 values equal to 0, adding 1 to the matrix.
t_visitcf_monocyte_nb_pca <- plot_pca(t_visitcf_monocyte_nb, plot_labels = FALSE)
pp(file = "images/t_monocyte_visitcf_sva_pca.pdf")
t_visitcf_monocyte_nb_pca$plot
dev.off()
## png 
##   2
t_visitcf_monocyte_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by monocytes.

11.4.1.2 Eosinophils across visits

Repeat the above with Eosinophils, we should therefore have slightly fewer glyphs on the plot.

t_visitcf_eosinophil_norm <- normalize_expt(t_visitcf_eosinophil, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 9420 low-count genes (10532 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_visitcf_eosinophil_pca <- plot_pca(t_visitcf_eosinophil_norm, plot_labels = FALSE)
pp(file = "images/t_eosinophil_visitcf_norm_pca.pdf")
t_visitcf_eosinophil_pca$plot
dev.off()
## png 
##   2
t_visitcf_eosinophil_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by eosinophils.

t_visitcf_eosinophil_disheat <- plot_disheat(t_visitcf_eosinophil_norm)
t_visitcf_eosinophil_disheat$plot

t_visitcf_eosinophil_nb <- normalize_expt(t_visitcf_eosinophil, convert = "cpm",
                                    transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9420 low-count genes (10532 remaining).
## Setting 373 low elements to zero.
## transform_counts: Found 373 values equal to 0, adding 1 to the matrix.
t_visitcf_eosinophil_nb_pca <- plot_pca(t_visitcf_eosinophil_nb, plot_labels = FALSE)
pp(file = "images/t_eosinophil_visitcf_sva_pca.pdf")
t_visitcf_eosinophil_nb_pca$plot
dev.off()
## png 
##   2
t_visitcf_eosinophil_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by eosinophils.

11.4.1.3 Neutrophils across visits

t_visitcf_neutrophil_norm <- normalize_expt(t_visitcf_neutrophil, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 10851 low-count genes (9101 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_visitcf_neutrophil_pca <- plot_pca(t_visitcf_neutrophil_norm, plot_labels = FALSE)
pp(file = "images/t_neutrophil_visitcf_norm_pca.pdf")
t_visitcf_neutrophil_pca$plot
dev.off()
## png 
##   2
t_visitcf_neutrophil_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by neutrophils.

t_visitcf_neutrophil_disheat <- plot_disheat(t_visitcf_neutrophil_norm)
t_visitcf_neutrophil_disheat$plot

t_visitcf_neutrophil_nb <- normalize_expt(t_visitcf_neutrophil, convert = "cpm",
                                          transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 10851 low-count genes (9101 remaining).
## Setting 685 low elements to zero.
## transform_counts: Found 685 values equal to 0, adding 1 to the matrix.
t_visitcf_neutrophil_nb_pca <- plot_pca(t_visitcf_neutrophil_nb, plot_labels = FALSE)
pp(file = "images/t_neutrophil_visitcf_sva_pca.pdf")
t_visitcf_neutrophil_nb_pca$plot
dev.off()
## png 
##   2
t_visitcf_neutrophil_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by neutrophils.

11.4.1.4 Celltypes by visit, C/F batch: Monocytes

We are backing off the granular view of visit and Fail/Cure in the following block and instead just considering the three visits. This previously only considered the normalized result, now we wish to add the sva modified result and print out pdfs thereof. Once again, we are repeating 3 times, once for each cell type.

t_visit_monocyte <- set_expt_conditions(t_visitcf_monocyte, prefix = "v",
                                        fact = "visitnumber") %>%
  set_expt_batches("finaloutcome") %>%
  set_expt_colors(color_choices[["visit"]])
## The numbers of samples by condition are:
## 
## v1 v2 v3 
## 16 13 13
## The number of samples by batch are:
## 
##    cure failure 
##      21      21
t_visit_monocyte_norm <- normalize_expt(t_visit_monocyte,
                                        transform = "log2", convert = "cpm",
                                        norm = "quant", filter = TRUE)
## Removing 9090 low-count genes (10862 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
t_visit_monocyte_norm_pca <- plot_pca(t_visit_monocyte_norm, plot_labels = FALSE)
pp(file = "figures/t_monocyte_visit_norm_pca.svg")
t_visit_monocyte_norm_pca[["plot"]]
dev.off()
## png 
##   2
t_visit_monocyte_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by cure, failure.

t_visitcf_monocyte_nb <- normalize_expt(t_visitcf_monocyte,
                                        transform = "log2", convert = "cpm",
                                        batch = "svaseq", filter = TRUE)
## Removing 9090 low-count genes (10862 remaining).
## Setting 700 low elements to zero.
## transform_counts: Found 700 values equal to 0, adding 1 to the matrix.
t_visitcf_monocyte_nb_pca <- plot_pca(t_visitcf_monocyte_nb, plot_labels = FALSE)
pp(file = "figures/t_monocyte_visit_sva_pca.svg")
t_visitcf_monocyte_nb_pca[["plot"]]
dev.off()
## png 
##   2
t_visitcf_monocyte_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1cure, v1failure, v2cure, v2failure, v3cure, v3failure
## Shapes are defined by monocytes.

11.4.1.5 Celltypes by visit, C/F batch: Eosinophils

t_visit_eosinophil <- set_expt_conditions(t_visitcf_eosinophil, prefix = "v",
                                            fact = "visitnumber") %>%
  set_expt_batches("finaloutcome") %>%
  set_expt_colors(color_choices[["visit"]])
## The numbers of samples by condition are:
## 
## v1 v2 v3 
##  8  9  9
## The number of samples by batch are:
## 
##    cure failure 
##      17       9
t_visit_eosinophil_norm <- normalize_expt(t_visit_eosinophil,
                                          transform = "log2", convert = "cpm",
                                          norm = "quant", filter = TRUE)
## Removing 9420 low-count genes (10532 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_visit_eosinophil_norm_pca <- plot_pca(t_visit_eosinophil_norm, plot_labels = FALSE)
pp(file = "figures/t_eosinophil_visit_norm_pca.svg")
t_visit_eosinophil_norm_pca[["plot"]]
dev.off()
## png 
##   2
t_visit_eosinophil_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by cure, failure.

t_visit_eosinophil_nb <- normalize_expt(t_visit_eosinophil,
                                        transform = "log2", convert = "cpm",
                                        batch = "svaseq", filter = TRUE)
## Removing 9420 low-count genes (10532 remaining).
## Setting 271 low elements to zero.
## transform_counts: Found 271 values equal to 0, adding 1 to the matrix.
t_visit_eosinophil_nb_pca <- plot_pca(t_visit_eosinophil_nb, plot_labels = FALSE)
pp(file = "figures/t_eosinophil_visit_sva_pca.svg")
t_visit_eosinophil_nb_pca[["plot"]]
dev.off()
## png 
##   2
t_visit_eosinophil_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by cure, failure.

11.4.1.6 Celltypes by visit, C/F batch: Neutrophils

t_visit_neutrophil <- set_expt_conditions(t_visitcf_neutrophil, prefix = "v",
                                          fact = "visitnumber") %>%
  set_expt_batches("finaloutcome") %>%
  set_expt_colors(color_choices[["visit"]])
## The numbers of samples by condition are:
## 
## v1 v2 v3 
## 16 13 12
## The number of samples by batch are:
## 
##    cure failure 
##      20      21
t_visit_neutrophil_norm <- normalize_expt(t_visit_neutrophil,
                                          transform = "log2", convert = "cpm",
                                          norm = "quant", filter = TRUE)
## Removing 10851 low-count genes (9101 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
t_visit_neutrophil_norm_pca <- plot_pca(t_visit_neutrophil_norm, plot_labels = FALSE)
pp(file = "figures/t_neutrophil_visit_norm_pca.svg")
t_visit_neutrophil_norm_pca[["plot"]]
dev.off()
## png 
##   2
t_visit_neutrophil_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by cure, failure.

t_visit_neutrophil_nb <- normalize_expt(t_visit_neutrophil,
                                        transform = "log2", convert = "cpm",
                                        batch = "svaseq", filter = TRUE)
## Removing 10851 low-count genes (9101 remaining).
## Setting 593 low elements to zero.
## transform_counts: Found 593 values equal to 0, adding 1 to the matrix.
t_visit_neutrophil_nb_pca <- plot_pca(t_visit_neutrophil_nb, plot_labels = FALSE)
pp(file = "figures/t_neutrophil_visit_sva_pca.svg")
t_visit_neutrophil_nb_pca[["plot"]]
dev.off()
## png 
##   2
t_visit_neutrophil_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by cure, failure.

12 Persistence

12.0.1 Take a look

See if there are any patterns which look usable.

## All
t_persistence_norm <- normalize_expt(t_persistence, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
plot_pca(t_persistence_norm)$plot
t_persistence_nb <- normalize_expt(t_persistence, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
plot_pca(t_persistence_nb)$plot

## Biopsies
##persistence_biopsy_norm <- normalize_expt(persistence_biopsy, transform = "log2", convert = "cpm",
##                                   norm = "quant", filter = TRUE)
##plot_pca(persistence_biopsy_norm)$plot
## Insufficient data

## Monocytes
t_persistence_monocyte_norm <- normalize_expt(t_persistence_monocyte, transform = "log2", convert = "cpm",
                                              norm = "quant", filter = TRUE)
plot_pca(t_persistence_monocyte_norm)$plot
t_persistence_monocyte_nb <- normalize_expt(t_persistence_monocyte, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
plot_pca(t_persistence_monocyte_nb)$plot

## Neutrophils
t_persistence_neutrophil_norm <- normalize_expt(t_persistence_neutrophil, transform = "log2", convert = "cpm",
                                                norm = "quant", filter = TRUE)
plot_pca(t_persistence_neutrophil_norm)$plot
t_persistence_neutrophil_nb <- normalize_expt(t_persistence_neutrophil, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
plot_pca(t_persistence_neutrophil_nb)$plot

## Eosinophils
t_persistence_eosinophil_norm <- normalize_expt(t_persistence_eosinophil, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
plot_pca(t_persistence_eosinophil_norm)$plot
t_persistence_eosinophil_nb <- normalize_expt(t_persistence_eosinophil, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
plot_pca(t_persistence_eosinophil_nb)$plot

13 Classify me!

I wrote out all the z2.2 and z2.3 specific variants to a couple files, I want to see if I can classify a human sample as infected with 2.2 or 2.3.

z22 <- read.csv("csv/variants_22.csv")
z23 <- read.csv("csv/variants_23.csv")
cure <- read.csv("csv/cure_variants.txt")
fail <- read.csv("csv/fail_variants.txt")
z22_vec <- gsub(pattern="\\-", replacement="_", x=z22[["x"]])
z23_vec <- gsub(pattern="\\-", replacement="_", x=z23[["x"]])
cure_vec <- gsub(pattern="\\-", replacement="_", x=cure)
fail_vec <- gsub(pattern="\\-", replacement="_", x=fail)

classify_zymo <- function(sample) {
  arbitrary_tags <- sm(readr::read_tsv(sample))
  arbitrary_ids <- arbitrary_tags[["position"]]
  message("Length: ", length(arbitrary_ids), ", z22: ",
          sum(arbitrary_ids %in% z22_vec) / (length(z22_vec)), " z23: ",
          sum(arbitrary_ids %in% z23_vec) / (length(z23_vec)))
}

arbitrary_sample <- "preprocessing/TMRC30156/outputs/40freebayes_lpanamensis_v36/all_tags.txt.xz"
classify_zymo(arbitrary_sample)

14 Visualizing composite scores

First lets get the gene IDs and colors for these plots.

library(viridis)
## Loading required package: viridisLite
wanted_genes <- c("IFI44L", "IFI27", "PRR5", "PRR5-ARHGAP8", "RHCE",
                  "FBXO39", "RSAD2", "SMTNL1", "USP18", "AFAP1")
wanted_idx <- fData(tc_valid)[["hgnc_symbol"]] %in% wanted_genes
wanted_ids <- rownames(fData(tc_valid))[wanted_idx]

14.1 All samples, all visits

few <-  subset_genes(tc_valid, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 184 samples which kept less than 90 percent counts.
## TMRC30156 TMRC30185 TMRC30186 TMRC30178 TMRC30179 TMRC30221 TMRC30222 TMRC30223 
##  0.074962  0.005211  0.004192  0.010342  0.012853  0.008657  0.011388  0.012338 
## TMRC30224 TMRC30269 TMRC30148 TMRC30149 TMRC30253 TMRC30150 TMRC30140 TMRC30138 
##  0.012827  0.113766  0.025329  0.080425  0.092054  0.022887  0.058740  0.013443 
## TMRC30176 TMRC30153 TMRC30151 TMRC30234 TMRC30235 TMRC30270 TMRC30225 TMRC30226 
##  0.033930  0.056567  0.010845  0.022164  0.036248  0.105898  0.018196  0.066755 
## TMRC30227 TMRC30016 TMRC30228 TMRC30229 TMRC30230 TMRC30017 TMRC30231 TMRC30232 
##  0.012886  0.053396  0.010446  0.017396  0.007234  0.163526  0.011375  0.015075 
## TMRC30233 TMRC30018 TMRC30209 TMRC30210 TMRC30211 TMRC30212 TMRC30213 TMRC30216 
##  0.007098  0.198302  0.014238  0.030266  0.013335  0.013080  0.013782  0.013332 
## TMRC30214 TMRC30215 TMRC30271 TMRC30273 TMRC30275 TMRC30272 TMRC30274 TMRC30276 
##  0.026954  0.037395  0.002904  0.008120  0.004977  0.003982  0.011099  0.009685 
## TMRC30254 TMRC30255 TMRC30256 TMRC30277 TMRC30239 TMRC30240 TMRC30278 TMRC30279 
##  0.002683  0.004997  0.003678  0.028913  0.011614  0.011747  0.005125  0.009030 
## TMRC30280 TMRC30257 TMRC30019 TMRC30258 TMRC30281 TMRC30283 TMRC30284 TMRC30282 
##  0.004587  0.056479  0.137228  0.042362  0.006149  0.006348  0.018823  0.007745 
## TMRC30285 TMRC30071 TMRC30020 TMRC30056 TMRC30113 TMRC30105 TMRC30058 TMRC30164 
##  0.011814  0.003604  0.069015  0.024331  0.003870  0.027699  0.064838  0.004041 
## TMRC30080 TMRC30094 TMRC30119 TMRC30082 TMRC30103 TMRC30122 TMRC30022 TMRC30169 
##  0.029852  0.057588  0.011127  0.004927  0.250987  0.005859  0.087372  0.007921 
## TMRC30093 TMRC30029 TMRC30107 TMRC30170 TMRC30032 TMRC30096 TMRC30083 TMRC30028 
##  0.008303  0.013187  0.007179  0.010832  0.010258  0.010897  0.026117  0.010995 
## TMRC30115 TMRC30118 TMRC30180 TMRC30014 TMRC30121 TMRC30196 TMRC30030 TMRC30021 
##  0.008703  0.021574  0.021135  0.004655  0.016174  0.010626  0.006697  0.011014 
## TMRC30026 TMRC30037 TMRC30031 TMRC30165 TMRC30027 TMRC30044 TMRC30194 TMRC30166 
##  0.110316  0.009305  0.011136  0.033554  0.010749  0.073281  0.006814  0.164852 
## TMRC30195 TMRC30048 TMRC30054 TMRC30045 TMRC30046 TMRC30070 TMRC30049 TMRC30055 
##  0.007850  0.019523  0.042559  0.073178  0.031598  0.015248  0.062950  0.026184 
## TMRC30047 TMRC30191 TMRC30053 TMRC30041 TMRC30068 TMRC30171 TMRC30192 TMRC30139 
##  0.171838  0.004217  0.318379  0.009402  0.055379  0.016379  0.003692  0.023784 
## TMRC30042 TMRC30158 TMRC30132 TMRC30160 TMRC30157 TMRC30183 TMRC30167 TMRC30123 
##  0.009871  0.018550  0.005344  0.033926  0.009121  0.007546  0.009458  0.129523 
## TMRC30181 TMRC30072 TMRC30133 TMRC30043 TMRC30078 TMRC30116 TMRC30184 TMRC30076 
##  0.010955  0.074089  0.012120  0.004400  0.077858  0.332468  0.008483  0.280252 
## TMRC30159 TMRC30129 TMRC30088 TMRC30172 TMRC30134 TMRC30174 TMRC30137 TMRC30161 
##  0.006340  0.023852  0.366218  0.020875  0.008721  0.007188  0.028016  0.008835 
## TMRC30142 TMRC30175 TMRC30145 TMRC30143 TMRC30168 TMRC30197 TMRC30146 TMRC30182 
##  0.016100  0.006401  0.014411  0.037261  0.002339  0.011999  0.016008  0.003287 
## TMRC30199 TMRC30198 TMRC30201 TMRC30200 TMRC30203 TMRC30202 TMRC30205 TMRC30204 
##  0.011593  0.040711  0.009860  0.012649  0.019503  0.007974  0.076899  0.070550 
## TMRC30152 TMRC30177 TMRC30155 TMRC30154 TMRC30241 TMRC30237 TMRC30206 TMRC30136 
##  0.081844  0.136279  0.178394  0.109730  0.191405  0.007216  0.234762  0.002704 
## TMRC30207 TMRC30238 TMRC30074 TMRC30217 TMRC30208 TMRC30077 TMRC30219 TMRC30218 
##  0.006025  0.015708  0.054751  0.008582  0.014484  0.043051  0.004538  0.006692 
## TMRC30079 TMRC30220 TMRC30135 TMRC30173 TMRC30264 TMRC30144 TMRC30147 TMRC30265 
##  0.065252  0.002911  0.010142  0.013178  0.062792  0.008604  0.007424  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##     122      62
## transform_counts: Found 102 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_clinical, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 123 samples which kept less than 90 percent counts.
## TMRC30016 TMRC30017 TMRC30018 TMRC30019 TMRC30071 TMRC30020 TMRC30056 TMRC30113 
##  0.053396  0.163526  0.198302  0.137228  0.003604  0.069015  0.024331  0.003870 
## TMRC30105 TMRC30058 TMRC30164 TMRC30080 TMRC30094 TMRC30119 TMRC30082 TMRC30103 
##  0.027699  0.064838  0.004041  0.029852  0.057588  0.011127  0.004927  0.250987 
## TMRC30122 TMRC30022 TMRC30169 TMRC30093 TMRC30029 TMRC30107 TMRC30170 TMRC30032 
##  0.005859  0.087372  0.007921  0.008303  0.013187  0.007179  0.010832  0.010258 
## TMRC30096 TMRC30083 TMRC30028 TMRC30115 TMRC30118 TMRC30180 TMRC30014 TMRC30121 
##  0.010897  0.026117  0.010995  0.008703  0.021574  0.021135  0.004655  0.016174 
## TMRC30196 TMRC30030 TMRC30021 TMRC30026 TMRC30037 TMRC30031 TMRC30165 TMRC30027 
##  0.010626  0.006697  0.011014  0.110316  0.009305  0.011136  0.033554  0.010749 
## TMRC30044 TMRC30194 TMRC30166 TMRC30195 TMRC30048 TMRC30054 TMRC30045 TMRC30046 
##  0.073281  0.006814  0.164852  0.007850  0.019523  0.042559  0.073178  0.031598 
## TMRC30070 TMRC30049 TMRC30055 TMRC30047 TMRC30191 TMRC30053 TMRC30041 TMRC30068 
##  0.015248  0.062950  0.026184  0.171838  0.004217  0.318379  0.009402  0.055379 
## TMRC30171 TMRC30192 TMRC30139 TMRC30042 TMRC30158 TMRC30132 TMRC30160 TMRC30157 
##  0.016379  0.003692  0.023784  0.009871  0.018550  0.005344  0.033926  0.009121 
## TMRC30183 TMRC30167 TMRC30123 TMRC30181 TMRC30072 TMRC30133 TMRC30043 TMRC30078 
##  0.007546  0.009458  0.129523  0.010955  0.074089  0.012120  0.004400  0.077858 
## TMRC30116 TMRC30184 TMRC30076 TMRC30159 TMRC30129 TMRC30088 TMRC30172 TMRC30134 
##  0.332468  0.008483  0.280252  0.006340  0.023852  0.366218  0.020875  0.008721 
## TMRC30174 TMRC30137 TMRC30161 TMRC30142 TMRC30175 TMRC30145 TMRC30143 TMRC30168 
##  0.007188  0.028016  0.008835  0.016100  0.006401  0.014411  0.037261  0.002339 
## TMRC30197 TMRC30146 TMRC30182 TMRC30199 TMRC30198 TMRC30201 TMRC30200 TMRC30203 
##  0.011999  0.016008  0.003287  0.011593  0.040711  0.009860  0.012649  0.019503 
## TMRC30202 TMRC30205 TMRC30204 TMRC30152 TMRC30177 TMRC30155 TMRC30154 TMRC30241 
##  0.007974  0.076899  0.070550  0.081844  0.136279  0.178394  0.109730  0.191405 
## TMRC30237 TMRC30206 TMRC30136 TMRC30207 TMRC30238 TMRC30074 TMRC30217 TMRC30208 
##  0.007216  0.234762  0.002704  0.006025  0.015708  0.054751  0.008582  0.014484 
## TMRC30077 TMRC30219 TMRC30218 TMRC30079 TMRC30220 TMRC30135 TMRC30173 TMRC30264 
##  0.043051  0.004538  0.006692  0.065252  0.002911  0.010142  0.013178  0.062792 
## TMRC30144 TMRC30147 TMRC30265 
##  0.008604  0.007424  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##      67      56
## transform_counts: Found 39 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.2 All samples, visit 1

few <- subset_genes(tc_clinical, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 184 samples which kept less than 90 percent counts.
## TMRC30156 TMRC30185 TMRC30186 TMRC30178 TMRC30179 TMRC30221 TMRC30222 TMRC30223 
##  0.074962  0.005211  0.004192  0.010342  0.012853  0.008657  0.011388  0.012338 
## TMRC30224 TMRC30269 TMRC30148 TMRC30149 TMRC30253 TMRC30150 TMRC30140 TMRC30138 
##  0.012827  0.113766  0.025329  0.080425  0.092054  0.022887  0.058740  0.013443 
## TMRC30176 TMRC30153 TMRC30151 TMRC30234 TMRC30235 TMRC30270 TMRC30225 TMRC30226 
##  0.033930  0.056567  0.010845  0.022164  0.036248  0.105898  0.018196  0.066755 
## TMRC30227 TMRC30016 TMRC30228 TMRC30229 TMRC30230 TMRC30017 TMRC30231 TMRC30232 
##  0.012886  0.053396  0.010446  0.017396  0.007234  0.163526  0.011375  0.015075 
## TMRC30233 TMRC30018 TMRC30209 TMRC30210 TMRC30211 TMRC30212 TMRC30213 TMRC30216 
##  0.007098  0.198302  0.014238  0.030266  0.013335  0.013080  0.013782  0.013332 
## TMRC30214 TMRC30215 TMRC30271 TMRC30273 TMRC30275 TMRC30272 TMRC30274 TMRC30276 
##  0.026954  0.037395  0.002904  0.008120  0.004977  0.003982  0.011099  0.009685 
## TMRC30254 TMRC30255 TMRC30256 TMRC30277 TMRC30239 TMRC30240 TMRC30278 TMRC30279 
##  0.002683  0.004997  0.003678  0.028913  0.011614  0.011747  0.005125  0.009030 
## TMRC30280 TMRC30257 TMRC30019 TMRC30258 TMRC30281 TMRC30283 TMRC30284 TMRC30282 
##  0.004587  0.056479  0.137228  0.042362  0.006149  0.006348  0.018823  0.007745 
## TMRC30285 TMRC30071 TMRC30020 TMRC30056 TMRC30113 TMRC30105 TMRC30058 TMRC30164 
##  0.011814  0.003604  0.069015  0.024331  0.003870  0.027699  0.064838  0.004041 
## TMRC30080 TMRC30094 TMRC30119 TMRC30082 TMRC30103 TMRC30122 TMRC30022 TMRC30169 
##  0.029852  0.057588  0.011127  0.004927  0.250987  0.005859  0.087372  0.007921 
## TMRC30093 TMRC30029 TMRC30107 TMRC30170 TMRC30032 TMRC30096 TMRC30083 TMRC30028 
##  0.008303  0.013187  0.007179  0.010832  0.010258  0.010897  0.026117  0.010995 
## TMRC30115 TMRC30118 TMRC30180 TMRC30014 TMRC30121 TMRC30196 TMRC30030 TMRC30021 
##  0.008703  0.021574  0.021135  0.004655  0.016174  0.010626  0.006697  0.011014 
## TMRC30026 TMRC30037 TMRC30031 TMRC30165 TMRC30027 TMRC30044 TMRC30194 TMRC30166 
##  0.110316  0.009305  0.011136  0.033554  0.010749  0.073281  0.006814  0.164852 
## TMRC30195 TMRC30048 TMRC30054 TMRC30045 TMRC30046 TMRC30070 TMRC30049 TMRC30055 
##  0.007850  0.019523  0.042559  0.073178  0.031598  0.015248  0.062950  0.026184 
## TMRC30047 TMRC30191 TMRC30053 TMRC30041 TMRC30068 TMRC30171 TMRC30192 TMRC30139 
##  0.171838  0.004217  0.318379  0.009402  0.055379  0.016379  0.003692  0.023784 
## TMRC30042 TMRC30158 TMRC30132 TMRC30160 TMRC30157 TMRC30183 TMRC30167 TMRC30123 
##  0.009871  0.018550  0.005344  0.033926  0.009121  0.007546  0.009458  0.129523 
## TMRC30181 TMRC30072 TMRC30133 TMRC30043 TMRC30078 TMRC30116 TMRC30184 TMRC30076 
##  0.010955  0.074089  0.012120  0.004400  0.077858  0.332468  0.008483  0.280252 
## TMRC30159 TMRC30129 TMRC30088 TMRC30172 TMRC30134 TMRC30174 TMRC30137 TMRC30161 
##  0.006340  0.023852  0.366218  0.020875  0.008721  0.007188  0.028016  0.008835 
## TMRC30142 TMRC30175 TMRC30145 TMRC30143 TMRC30168 TMRC30197 TMRC30146 TMRC30182 
##  0.016100  0.006401  0.014411  0.037261  0.002339  0.011999  0.016008  0.003287 
## TMRC30199 TMRC30198 TMRC30201 TMRC30200 TMRC30203 TMRC30202 TMRC30205 TMRC30204 
##  0.011593  0.040711  0.009860  0.012649  0.019503  0.007974  0.076899  0.070550 
## TMRC30152 TMRC30177 TMRC30155 TMRC30154 TMRC30241 TMRC30237 TMRC30206 TMRC30136 
##  0.081844  0.136279  0.178394  0.109730  0.191405  0.007216  0.234762  0.002704 
## TMRC30207 TMRC30238 TMRC30074 TMRC30217 TMRC30208 TMRC30077 TMRC30219 TMRC30218 
##  0.006025  0.015708  0.054751  0.008582  0.014484  0.043051  0.004538  0.006692 
## TMRC30079 TMRC30220 TMRC30135 TMRC30173 TMRC30264 TMRC30144 TMRC30147 TMRC30265 
##  0.065252  0.002911  0.010142  0.013178  0.062792  0.008604  0.007424  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##     122      62
## The samples excluded are: TMRC30178, TMRC30179, TMRC30223, TMRC30224, TMRC30150, TMRC30140, TMRC30176, TMRC30153, TMRC30151, TMRC30228, TMRC30229, TMRC30230, TMRC30231, TMRC30232, TMRC30233, TMRC30212, TMRC30213, TMRC30216, TMRC30214, TMRC30215, TMRC30272, TMRC30274, TMRC30276, TMRC30254, TMRC30255, TMRC30256, TMRC30277, TMRC30278, TMRC30279, TMRC30280, TMRC30282, TMRC30285, TMRC30056, TMRC30113, TMRC30105, TMRC30058, TMRC30164, TMRC30094, TMRC30119, TMRC30082, TMRC30122, TMRC30169, TMRC30093, TMRC30170, TMRC30032, TMRC30096, TMRC30028, TMRC30115, TMRC30118, TMRC30121, TMRC30196, TMRC30030, TMRC30037, TMRC30031, TMRC30027, TMRC30194, TMRC30195, TMRC30054, TMRC30070, TMRC30049, TMRC30055, TMRC30053, TMRC30068, TMRC30171, TMRC30139, TMRC30158, TMRC30160, TMRC30157, TMRC30183, TMRC30181, TMRC30072, TMRC30133, TMRC30078, TMRC30076, TMRC30159, TMRC30129, TMRC30088, TMRC30172, TMRC30137, TMRC30161, TMRC30142, TMRC30145, TMRC30143, TMRC30146, TMRC30182, TMRC30199, TMRC30201, TMRC30200, TMRC30202, TMRC30205, TMRC30206, TMRC30136, TMRC30217, TMRC30077, TMRC30219, TMRC30218, TMRC30079, TMRC30220, TMRC30173, TMRC30144, TMRC30147.
## subset_expt(): There were 184, now there are 83 samples.
## transform_counts: Found 43 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <- subset_genes(t_clinical, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 123 samples which kept less than 90 percent counts.
## TMRC30016 TMRC30017 TMRC30018 TMRC30019 TMRC30071 TMRC30020 TMRC30056 TMRC30113 
##  0.053396  0.163526  0.198302  0.137228  0.003604  0.069015  0.024331  0.003870 
## TMRC30105 TMRC30058 TMRC30164 TMRC30080 TMRC30094 TMRC30119 TMRC30082 TMRC30103 
##  0.027699  0.064838  0.004041  0.029852  0.057588  0.011127  0.004927  0.250987 
## TMRC30122 TMRC30022 TMRC30169 TMRC30093 TMRC30029 TMRC30107 TMRC30170 TMRC30032 
##  0.005859  0.087372  0.007921  0.008303  0.013187  0.007179  0.010832  0.010258 
## TMRC30096 TMRC30083 TMRC30028 TMRC30115 TMRC30118 TMRC30180 TMRC30014 TMRC30121 
##  0.010897  0.026117  0.010995  0.008703  0.021574  0.021135  0.004655  0.016174 
## TMRC30196 TMRC30030 TMRC30021 TMRC30026 TMRC30037 TMRC30031 TMRC30165 TMRC30027 
##  0.010626  0.006697  0.011014  0.110316  0.009305  0.011136  0.033554  0.010749 
## TMRC30044 TMRC30194 TMRC30166 TMRC30195 TMRC30048 TMRC30054 TMRC30045 TMRC30046 
##  0.073281  0.006814  0.164852  0.007850  0.019523  0.042559  0.073178  0.031598 
## TMRC30070 TMRC30049 TMRC30055 TMRC30047 TMRC30191 TMRC30053 TMRC30041 TMRC30068 
##  0.015248  0.062950  0.026184  0.171838  0.004217  0.318379  0.009402  0.055379 
## TMRC30171 TMRC30192 TMRC30139 TMRC30042 TMRC30158 TMRC30132 TMRC30160 TMRC30157 
##  0.016379  0.003692  0.023784  0.009871  0.018550  0.005344  0.033926  0.009121 
## TMRC30183 TMRC30167 TMRC30123 TMRC30181 TMRC30072 TMRC30133 TMRC30043 TMRC30078 
##  0.007546  0.009458  0.129523  0.010955  0.074089  0.012120  0.004400  0.077858 
## TMRC30116 TMRC30184 TMRC30076 TMRC30159 TMRC30129 TMRC30088 TMRC30172 TMRC30134 
##  0.332468  0.008483  0.280252  0.006340  0.023852  0.366218  0.020875  0.008721 
## TMRC30174 TMRC30137 TMRC30161 TMRC30142 TMRC30175 TMRC30145 TMRC30143 TMRC30168 
##  0.007188  0.028016  0.008835  0.016100  0.006401  0.014411  0.037261  0.002339 
## TMRC30197 TMRC30146 TMRC30182 TMRC30199 TMRC30198 TMRC30201 TMRC30200 TMRC30203 
##  0.011999  0.016008  0.003287  0.011593  0.040711  0.009860  0.012649  0.019503 
## TMRC30202 TMRC30205 TMRC30204 TMRC30152 TMRC30177 TMRC30155 TMRC30154 TMRC30241 
##  0.007974  0.076899  0.070550  0.081844  0.136279  0.178394  0.109730  0.191405 
## TMRC30237 TMRC30206 TMRC30136 TMRC30207 TMRC30238 TMRC30074 TMRC30217 TMRC30208 
##  0.007216  0.234762  0.002704  0.006025  0.015708  0.054751  0.008582  0.014484 
## TMRC30077 TMRC30219 TMRC30218 TMRC30079 TMRC30220 TMRC30135 TMRC30173 TMRC30264 
##  0.043051  0.004538  0.006692  0.065252  0.002911  0.010142  0.013178  0.062792 
## TMRC30144 TMRC30147 TMRC30265 
##  0.008604  0.007424  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##      67      56
## The samples excluded are: TMRC30056, TMRC30113, TMRC30105, TMRC30058, TMRC30164, TMRC30094, TMRC30119, TMRC30082, TMRC30122, TMRC30169, TMRC30093, TMRC30170, TMRC30032, TMRC30096, TMRC30028, TMRC30115, TMRC30118, TMRC30121, TMRC30196, TMRC30030, TMRC30037, TMRC30031, TMRC30027, TMRC30194, TMRC30195, TMRC30054, TMRC30070, TMRC30049, TMRC30055, TMRC30053, TMRC30068, TMRC30171, TMRC30139, TMRC30158, TMRC30160, TMRC30157, TMRC30183, TMRC30181, TMRC30072, TMRC30133, TMRC30078, TMRC30076, TMRC30159, TMRC30129, TMRC30088, TMRC30172, TMRC30137, TMRC30161, TMRC30142, TMRC30145, TMRC30143, TMRC30146, TMRC30182, TMRC30199, TMRC30201, TMRC30200, TMRC30202, TMRC30205, TMRC30206, TMRC30136, TMRC30217, TMRC30077, TMRC30219, TMRC30218, TMRC30079, TMRC30220, TMRC30173, TMRC30144, TMRC30147.
## subset_expt(): There were 123, now there are 54 samples.
## transform_counts: Found 16 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.3 Eosinophils, all times

few <-  subset_genes(tc_eosinophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 41 samples which kept less than 90 percent counts.
## TMRC30138 TMRC30151 TMRC30227 TMRC30230 TMRC30233 TMRC30211 TMRC30216 TMRC30271 
##  0.013443  0.010845  0.012886  0.007234  0.007098  0.013335  0.013332  0.002904 
## TMRC30272 TMRC30254 TMRC30277 TMRC30278 TMRC30257 TMRC30281 TMRC30282 TMRC30071 
##  0.003982  0.002683  0.028913  0.005125  0.056479  0.006149  0.007745  0.003604 
## TMRC30113 TMRC30164 TMRC30119 TMRC30122 TMRC30029 TMRC30032 TMRC30028 TMRC30180 
##  0.003870  0.004041  0.011127  0.005859  0.013187  0.010258  0.010995  0.021135 
## TMRC30196 TMRC30048 TMRC30054 TMRC30070 TMRC30043 TMRC30159 TMRC30161 TMRC30168 
##  0.010626  0.019523  0.042559  0.015248  0.004400  0.006340  0.008835  0.002339 
## TMRC30182 TMRC30136 TMRC30074 TMRC30077 TMRC30079 TMRC30135 TMRC30173 TMRC30144 
##  0.003287  0.002704  0.054751  0.043051  0.065252  0.010142  0.013178  0.008604 
## TMRC30147 
##  0.007424
## The numbers of samples by condition are:
## 
##    cure failure 
##      32       9
## transform_counts: Found 40 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_eosinophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 26 samples which kept less than 90 percent counts.
## TMRC30071 TMRC30113 TMRC30164 TMRC30119 TMRC30122 TMRC30029 TMRC30032 TMRC30028 
##  0.003604  0.003870  0.004041  0.011127  0.005859  0.013187  0.010258  0.010995 
## TMRC30180 TMRC30196 TMRC30048 TMRC30054 TMRC30070 TMRC30043 TMRC30159 TMRC30161 
##  0.021135  0.010626  0.019523  0.042559  0.015248  0.004400  0.006340  0.008835 
## TMRC30168 TMRC30182 TMRC30136 TMRC30074 TMRC30077 TMRC30079 TMRC30135 TMRC30173 
##  0.002339  0.003287  0.002704  0.054751  0.043051  0.065252  0.010142  0.013178 
## TMRC30144 TMRC30147 
##  0.008604  0.007424
## The numbers of samples by condition are:
## 
##    cure failure 
##      17       9
## transform_counts: Found 15 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.4 Eosinophils, v1

few <-  subset_genes(tc_eosinophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 41 samples which kept less than 90 percent counts.
## TMRC30138 TMRC30151 TMRC30227 TMRC30230 TMRC30233 TMRC30211 TMRC30216 TMRC30271 
##  0.013443  0.010845  0.012886  0.007234  0.007098  0.013335  0.013332  0.002904 
## TMRC30272 TMRC30254 TMRC30277 TMRC30278 TMRC30257 TMRC30281 TMRC30282 TMRC30071 
##  0.003982  0.002683  0.028913  0.005125  0.056479  0.006149  0.007745  0.003604 
## TMRC30113 TMRC30164 TMRC30119 TMRC30122 TMRC30029 TMRC30032 TMRC30028 TMRC30180 
##  0.003870  0.004041  0.011127  0.005859  0.013187  0.010258  0.010995  0.021135 
## TMRC30196 TMRC30048 TMRC30054 TMRC30070 TMRC30043 TMRC30159 TMRC30161 TMRC30168 
##  0.010626  0.019523  0.042559  0.015248  0.004400  0.006340  0.008835  0.002339 
## TMRC30182 TMRC30136 TMRC30074 TMRC30077 TMRC30079 TMRC30135 TMRC30173 TMRC30144 
##  0.003287  0.002704  0.054751  0.043051  0.065252  0.010142  0.013178  0.008604 
## TMRC30147 
##  0.007424
## The numbers of samples by condition are:
## 
##    cure failure 
##      32       9
## The samples excluded are: TMRC30151, TMRC30230, TMRC30233, TMRC30216, TMRC30272, TMRC30254, TMRC30277, TMRC30278, TMRC30282, TMRC30113, TMRC30164, TMRC30119, TMRC30122, TMRC30032, TMRC30028, TMRC30196, TMRC30054, TMRC30070, TMRC30159, TMRC30161, TMRC30182, TMRC30136, TMRC30077, TMRC30079, TMRC30173, TMRC30144, TMRC30147.
## subset_expt(): There were 41, now there are 14 samples.
## transform_counts: Found 15 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_eosinophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 26 samples which kept less than 90 percent counts.
## TMRC30071 TMRC30113 TMRC30164 TMRC30119 TMRC30122 TMRC30029 TMRC30032 TMRC30028 
##  0.003604  0.003870  0.004041  0.011127  0.005859  0.013187  0.010258  0.010995 
## TMRC30180 TMRC30196 TMRC30048 TMRC30054 TMRC30070 TMRC30043 TMRC30159 TMRC30161 
##  0.021135  0.010626  0.019523  0.042559  0.015248  0.004400  0.006340  0.008835 
## TMRC30168 TMRC30182 TMRC30136 TMRC30074 TMRC30077 TMRC30079 TMRC30135 TMRC30173 
##  0.002339  0.003287  0.002704  0.054751  0.043051  0.065252  0.010142  0.013178 
## TMRC30144 TMRC30147 
##  0.008604  0.007424
## The numbers of samples by condition are:
## 
##    cure failure 
##      17       9
## The samples excluded are: TMRC30113, TMRC30164, TMRC30119, TMRC30122, TMRC30032, TMRC30028, TMRC30196, TMRC30054, TMRC30070, TMRC30159, TMRC30161, TMRC30182, TMRC30136, TMRC30077, TMRC30079, TMRC30173, TMRC30144, TMRC30147.
## subset_expt(): There were 26, now there are 8 samples.
## transform_counts: Found 6 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.5 Monocytes all

few <-  subset_genes(tc_monocytes, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 63 samples which kept less than 90 percent counts.
## TMRC30185 TMRC30178 TMRC30221 TMRC30223 TMRC30148 TMRC30150 TMRC30176 TMRC30234 
##  0.005211  0.010342  0.008657  0.012338  0.025329  0.022887  0.033930  0.022164 
## TMRC30225 TMRC30228 TMRC30231 TMRC30209 TMRC30212 TMRC30214 TMRC30273 TMRC30274 
##  0.018196  0.010446  0.011375  0.014238  0.013080  0.026954  0.008120  0.011099 
## TMRC30255 TMRC30239 TMRC30279 TMRC30258 TMRC30283 TMRC30056 TMRC30105 TMRC30080 
##  0.004997  0.011614  0.009030  0.042362  0.006348  0.024331  0.027699  0.029852 
## TMRC30082 TMRC30169 TMRC30107 TMRC30096 TMRC30115 TMRC30014 TMRC30030 TMRC30037 
##  0.004927  0.007921  0.007179  0.010897  0.008703  0.004655  0.006697  0.009305 
## TMRC30165 TMRC30194 TMRC30046 TMRC30049 TMRC30055 TMRC30191 TMRC30041 TMRC30171 
##  0.033554  0.006814  0.031598  0.062950  0.026184  0.004217  0.009402  0.016379 
## TMRC30139 TMRC30132 TMRC30157 TMRC30183 TMRC30123 TMRC30072 TMRC30078 TMRC30184 
##  0.023784  0.005344  0.009121  0.007546  0.129523  0.074089  0.077858  0.008483 
## TMRC30129 TMRC30172 TMRC30174 TMRC30142 TMRC30145 TMRC30197 TMRC30199 TMRC30201 
##  0.023852  0.020875  0.007188  0.016100  0.014411  0.011999  0.011593  0.009860 
## TMRC30203 TMRC30205 TMRC30237 TMRC30207 TMRC30217 TMRC30219 TMRC30264 
##  0.019503  0.076899  0.007216  0.006025  0.008582  0.004538  0.062792
## The numbers of samples by condition are:
## 
##    cure failure 
##      39      24
## transform_counts: Found 10 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_monocytes, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 42 samples which kept less than 90 percent counts.
## TMRC30056 TMRC30105 TMRC30080 TMRC30082 TMRC30169 TMRC30107 TMRC30096 TMRC30115 
##  0.024331  0.027699  0.029852  0.004927  0.007921  0.007179  0.010897  0.008703 
## TMRC30014 TMRC30030 TMRC30037 TMRC30165 TMRC30194 TMRC30046 TMRC30049 TMRC30055 
##  0.004655  0.006697  0.009305  0.033554  0.006814  0.031598  0.062950  0.026184 
## TMRC30191 TMRC30041 TMRC30171 TMRC30139 TMRC30132 TMRC30157 TMRC30183 TMRC30123 
##  0.004217  0.009402  0.016379  0.023784  0.005344  0.009121  0.007546  0.129523 
## TMRC30072 TMRC30078 TMRC30184 TMRC30129 TMRC30172 TMRC30174 TMRC30142 TMRC30145 
##  0.074089  0.077858  0.008483  0.023852  0.020875  0.007188  0.016100  0.014411 
## TMRC30197 TMRC30199 TMRC30201 TMRC30203 TMRC30205 TMRC30237 TMRC30207 TMRC30217 
##  0.011999  0.011593  0.009860  0.019503  0.076899  0.007216  0.006025  0.008582 
## TMRC30219 TMRC30264 
##  0.004538  0.062792
## The numbers of samples by condition are:
## 
##    cure failure 
##      21      21
## transform_counts: Found 4 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.6 Monocytes v1

few <-  subset_genes(tc_monocytes, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 63 samples which kept less than 90 percent counts.
## TMRC30185 TMRC30178 TMRC30221 TMRC30223 TMRC30148 TMRC30150 TMRC30176 TMRC30234 
##  0.005211  0.010342  0.008657  0.012338  0.025329  0.022887  0.033930  0.022164 
## TMRC30225 TMRC30228 TMRC30231 TMRC30209 TMRC30212 TMRC30214 TMRC30273 TMRC30274 
##  0.018196  0.010446  0.011375  0.014238  0.013080  0.026954  0.008120  0.011099 
## TMRC30255 TMRC30239 TMRC30279 TMRC30258 TMRC30283 TMRC30056 TMRC30105 TMRC30080 
##  0.004997  0.011614  0.009030  0.042362  0.006348  0.024331  0.027699  0.029852 
## TMRC30082 TMRC30169 TMRC30107 TMRC30096 TMRC30115 TMRC30014 TMRC30030 TMRC30037 
##  0.004927  0.007921  0.007179  0.010897  0.008703  0.004655  0.006697  0.009305 
## TMRC30165 TMRC30194 TMRC30046 TMRC30049 TMRC30055 TMRC30191 TMRC30041 TMRC30171 
##  0.033554  0.006814  0.031598  0.062950  0.026184  0.004217  0.009402  0.016379 
## TMRC30139 TMRC30132 TMRC30157 TMRC30183 TMRC30123 TMRC30072 TMRC30078 TMRC30184 
##  0.023784  0.005344  0.009121  0.007546  0.129523  0.074089  0.077858  0.008483 
## TMRC30129 TMRC30172 TMRC30174 TMRC30142 TMRC30145 TMRC30197 TMRC30199 TMRC30201 
##  0.023852  0.020875  0.007188  0.016100  0.014411  0.011999  0.011593  0.009860 
## TMRC30203 TMRC30205 TMRC30237 TMRC30207 TMRC30217 TMRC30219 TMRC30264 
##  0.019503  0.076899  0.007216  0.006025  0.008582  0.004538  0.062792
## The numbers of samples by condition are:
## 
##    cure failure 
##      39      24
## The samples excluded are: TMRC30178, TMRC30223, TMRC30150, TMRC30176, TMRC30228, TMRC30231, TMRC30212, TMRC30214, TMRC30274, TMRC30255, TMRC30279, TMRC30056, TMRC30105, TMRC30082, TMRC30169, TMRC30096, TMRC30115, TMRC30030, TMRC30037, TMRC30194, TMRC30049, TMRC30055, TMRC30171, TMRC30139, TMRC30157, TMRC30183, TMRC30072, TMRC30078, TMRC30129, TMRC30172, TMRC30142, TMRC30145, TMRC30199, TMRC30201, TMRC30205, TMRC30217, TMRC30219.
## subset_expt(): There were 63, now there are 26 samples.
## transform_counts: Found 3 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_monocytes, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 42 samples which kept less than 90 percent counts.
## TMRC30056 TMRC30105 TMRC30080 TMRC30082 TMRC30169 TMRC30107 TMRC30096 TMRC30115 
##  0.024331  0.027699  0.029852  0.004927  0.007921  0.007179  0.010897  0.008703 
## TMRC30014 TMRC30030 TMRC30037 TMRC30165 TMRC30194 TMRC30046 TMRC30049 TMRC30055 
##  0.004655  0.006697  0.009305  0.033554  0.006814  0.031598  0.062950  0.026184 
## TMRC30191 TMRC30041 TMRC30171 TMRC30139 TMRC30132 TMRC30157 TMRC30183 TMRC30123 
##  0.004217  0.009402  0.016379  0.023784  0.005344  0.009121  0.007546  0.129523 
## TMRC30072 TMRC30078 TMRC30184 TMRC30129 TMRC30172 TMRC30174 TMRC30142 TMRC30145 
##  0.074089  0.077858  0.008483  0.023852  0.020875  0.007188  0.016100  0.014411 
## TMRC30197 TMRC30199 TMRC30201 TMRC30203 TMRC30205 TMRC30237 TMRC30207 TMRC30217 
##  0.011999  0.011593  0.009860  0.019503  0.076899  0.007216  0.006025  0.008582 
## TMRC30219 TMRC30264 
##  0.004538  0.062792
## The numbers of samples by condition are:
## 
##    cure failure 
##      21      21
## The samples excluded are: TMRC30056, TMRC30105, TMRC30082, TMRC30169, TMRC30096, TMRC30115, TMRC30030, TMRC30037, TMRC30194, TMRC30049, TMRC30055, TMRC30171, TMRC30139, TMRC30157, TMRC30183, TMRC30072, TMRC30078, TMRC30129, TMRC30172, TMRC30142, TMRC30145, TMRC30199, TMRC30201, TMRC30205, TMRC30217, TMRC30219.
## subset_expt(): There were 42, now there are 16 samples.
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.7 Neutrophils all

few <-  subset_genes(tc_neutrophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 62 samples which kept less than 90 percent counts.
## TMRC30186 TMRC30179 TMRC30222 TMRC30224 TMRC30149 TMRC30140 TMRC30153 TMRC30235 
##  0.004192  0.012853  0.011388  0.012827  0.080425  0.058740  0.056567  0.036248 
## TMRC30226 TMRC30229 TMRC30232 TMRC30210 TMRC30213 TMRC30215 TMRC30275 TMRC30276 
##  0.066755  0.017396  0.015075  0.030266  0.013782  0.037395  0.004977  0.009685 
## TMRC30256 TMRC30240 TMRC30280 TMRC30284 TMRC30285 TMRC30058 TMRC30094 TMRC30103 
##  0.003678  0.011747  0.004587  0.018823  0.011814  0.064838  0.057588  0.250987 
## TMRC30093 TMRC30170 TMRC30083 TMRC30118 TMRC30121 TMRC30021 TMRC30031 TMRC30027 
##  0.008303  0.010832  0.026117  0.021574  0.016174  0.011014  0.011136  0.010749 
## TMRC30166 TMRC30195 TMRC30047 TMRC30053 TMRC30068 TMRC30192 TMRC30042 TMRC30158 
##  0.164852  0.007850  0.171838  0.318379  0.055379  0.003692  0.009871  0.018550 
## TMRC30160 TMRC30167 TMRC30181 TMRC30133 TMRC30116 TMRC30076 TMRC30088 TMRC30134 
##  0.033926  0.009458  0.010955  0.012120  0.332468  0.280252  0.366218  0.008721 
## TMRC30137 TMRC30175 TMRC30143 TMRC30146 TMRC30198 TMRC30200 TMRC30202 TMRC30204 
##  0.028016  0.006401  0.037261  0.016008  0.040711  0.012649  0.007974  0.070550 
## TMRC30206 TMRC30238 TMRC30208 TMRC30218 TMRC30220 TMRC30265 
##  0.234762  0.015708  0.014484  0.006692  0.002911  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##      38      24
## transform_counts: Found 52 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_neutrophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 41 samples which kept less than 90 percent counts.
## TMRC30058 TMRC30094 TMRC30103 TMRC30093 TMRC30170 TMRC30083 TMRC30118 TMRC30121 
##  0.064838  0.057588  0.250987  0.008303  0.010832  0.026117  0.021574  0.016174 
## TMRC30021 TMRC30031 TMRC30027 TMRC30166 TMRC30195 TMRC30047 TMRC30053 TMRC30068 
##  0.011014  0.011136  0.010749  0.164852  0.007850  0.171838  0.318379  0.055379 
## TMRC30192 TMRC30042 TMRC30158 TMRC30160 TMRC30167 TMRC30181 TMRC30133 TMRC30116 
##  0.003692  0.009871  0.018550  0.033926  0.009458  0.010955  0.012120  0.332468 
## TMRC30076 TMRC30088 TMRC30134 TMRC30137 TMRC30175 TMRC30143 TMRC30146 TMRC30198 
##  0.280252  0.366218  0.008721  0.028016  0.006401  0.037261  0.016008  0.040711 
## TMRC30200 TMRC30202 TMRC30204 TMRC30206 TMRC30238 TMRC30208 TMRC30218 TMRC30220 
##  0.012649  0.007974  0.070550  0.234762  0.015708  0.014484  0.006692  0.002911 
## TMRC30265 
##  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##      20      21
## transform_counts: Found 20 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

14.8 Neutrophils v1

few <-  subset_genes(tc_neutrophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 62 samples which kept less than 90 percent counts.
## TMRC30186 TMRC30179 TMRC30222 TMRC30224 TMRC30149 TMRC30140 TMRC30153 TMRC30235 
##  0.004192  0.012853  0.011388  0.012827  0.080425  0.058740  0.056567  0.036248 
## TMRC30226 TMRC30229 TMRC30232 TMRC30210 TMRC30213 TMRC30215 TMRC30275 TMRC30276 
##  0.066755  0.017396  0.015075  0.030266  0.013782  0.037395  0.004977  0.009685 
## TMRC30256 TMRC30240 TMRC30280 TMRC30284 TMRC30285 TMRC30058 TMRC30094 TMRC30103 
##  0.003678  0.011747  0.004587  0.018823  0.011814  0.064838  0.057588  0.250987 
## TMRC30093 TMRC30170 TMRC30083 TMRC30118 TMRC30121 TMRC30021 TMRC30031 TMRC30027 
##  0.008303  0.010832  0.026117  0.021574  0.016174  0.011014  0.011136  0.010749 
## TMRC30166 TMRC30195 TMRC30047 TMRC30053 TMRC30068 TMRC30192 TMRC30042 TMRC30158 
##  0.164852  0.007850  0.171838  0.318379  0.055379  0.003692  0.009871  0.018550 
## TMRC30160 TMRC30167 TMRC30181 TMRC30133 TMRC30116 TMRC30076 TMRC30088 TMRC30134 
##  0.033926  0.009458  0.010955  0.012120  0.332468  0.280252  0.366218  0.008721 
## TMRC30137 TMRC30175 TMRC30143 TMRC30146 TMRC30198 TMRC30200 TMRC30202 TMRC30204 
##  0.028016  0.006401  0.037261  0.016008  0.040711  0.012649  0.007974  0.070550 
## TMRC30206 TMRC30238 TMRC30208 TMRC30218 TMRC30220 TMRC30265 
##  0.234762  0.015708  0.014484  0.006692  0.002911  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##      38      24
## The samples excluded are: TMRC30179, TMRC30224, TMRC30140, TMRC30153, TMRC30229, TMRC30232, TMRC30213, TMRC30215, TMRC30276, TMRC30256, TMRC30280, TMRC30285, TMRC30058, TMRC30094, TMRC30093, TMRC30170, TMRC30118, TMRC30121, TMRC30031, TMRC30027, TMRC30195, TMRC30053, TMRC30068, TMRC30158, TMRC30160, TMRC30181, TMRC30133, TMRC30076, TMRC30088, TMRC30137, TMRC30143, TMRC30146, TMRC30200, TMRC30202, TMRC30206, TMRC30218, TMRC30220.
## subset_expt(): There were 62, now there are 25 samples.
## transform_counts: Found 25 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

few <-  subset_genes(t_neutrophils, ids = wanted_ids, method = "keep") %>%
  set_expt_conditions(fact = "finaloutcome") %>%
  subset_expt(subset = "visitnumber=='1'") %>%
  normalize_expt(transform = "log2", convert = "rpkm",
                 column = "mean_cds_len")
## remove_genes_expt(), before removal, there were 19952 genes, now there are 10.
## There are 41 samples which kept less than 90 percent counts.
## TMRC30058 TMRC30094 TMRC30103 TMRC30093 TMRC30170 TMRC30083 TMRC30118 TMRC30121 
##  0.064838  0.057588  0.250987  0.008303  0.010832  0.026117  0.021574  0.016174 
## TMRC30021 TMRC30031 TMRC30027 TMRC30166 TMRC30195 TMRC30047 TMRC30053 TMRC30068 
##  0.011014  0.011136  0.010749  0.164852  0.007850  0.171838  0.318379  0.055379 
## TMRC30192 TMRC30042 TMRC30158 TMRC30160 TMRC30167 TMRC30181 TMRC30133 TMRC30116 
##  0.003692  0.009871  0.018550  0.033926  0.009458  0.010955  0.012120  0.332468 
## TMRC30076 TMRC30088 TMRC30134 TMRC30137 TMRC30175 TMRC30143 TMRC30146 TMRC30198 
##  0.280252  0.366218  0.008721  0.028016  0.006401  0.037261  0.016008  0.040711 
## TMRC30200 TMRC30202 TMRC30204 TMRC30206 TMRC30238 TMRC30208 TMRC30218 TMRC30220 
##  0.012649  0.007974  0.070550  0.234762  0.015708  0.014484  0.006692  0.002911 
## TMRC30265 
##  0.255306
## The numbers of samples by condition are:
## 
##    cure failure 
##      20      21
## The samples excluded are: TMRC30058, TMRC30094, TMRC30093, TMRC30170, TMRC30118, TMRC30121, TMRC30031, TMRC30027, TMRC30195, TMRC30053, TMRC30068, TMRC30158, TMRC30160, TMRC30181, TMRC30133, TMRC30076, TMRC30088, TMRC30137, TMRC30143, TMRC30146, TMRC30200, TMRC30202, TMRC30206, TMRC30218, TMRC30220.
## subset_expt(): There were 41, now there are 16 samples.
## transform_counts: Found 9 values equal to 0, adding 1 to the matrix.
shp <- plot_sample_heatmap(few, heatmap_colors = viridis, row_label = wanted_genes)
shp

15 An external dataset

Let us look at a moderately similar Biopsy dataset of braziliensis infected individuals. First, lets do a quick plot of their data, our biopsies, then combine them.

15.1 Load the data

## Load the scott-only and the scott+tmrc3 data
load(glue("rda/tmrc3_external_cf-v{ver}.rda"))
load(glue("rda/tmrc3_external-v{ver}.rda"))

15.2 Visualize the two datasets individually

our_biopsies <- set_expt_conditions(t_biopsies, "finaloutcome") %>%
  set_expt_colors(color_choices[["cf"]])
## The numbers of samples by condition are:
## 
##    cure failure 
##       9       5
our_biopsies_norm <- normalize_expt(our_biopsies, filter = TRUE, transform = "log2",
                                    convert = "cpm", batch = "svaseq")
## Removing 6439 low-count genes (13513 remaining).
## Setting 146 low elements to zero.
## transform_counts: Found 146 values equal to 0, adding 1 to the matrix.
plot_pca(our_biopsies_norm)$plot

scott_biopsies_norm <- normalize_expt(external_cf, filter = TRUE, transform = "log2",
                                      convert = "cpm", batch = "svaseq")
## Removing 7327 low-count genes (14154 remaining).
## Setting 171 low elements to zero.
## transform_counts: Found 171 values equal to 0, adding 1 to the matrix.
plot_pca(scott_biopsies_norm)$plot

15.3 Visualize them together

both_norm <- normalize_expt(tmrc3_external, filter = TRUE, transform = "log2",
                             convert = "cpm", norm = "quant")
## Removing 6904 low-count genes (14577 remaining).
## transform_counts: Found 18 values equal to 0, adding 1 to the matrix.
plot_pca(both_norm)$plot

both_nb <- normalize_expt(tmrc3_external, filter = TRUE, transform = "log2",
                           convert = "cpm", batch = "svaseq")
## Removing 6904 low-count genes (14577 remaining).
## Setting 3653 low elements to zero.
## transform_counts: Found 3653 values equal to 0, adding 1 to the matrix.
plot_pca(both_nb)$plot

external_species <- set_expt_conditions(tmrc3_external, fact = "ParasiteSpecies") %>%
  subset_expt(subset = "ParasiteSpecies!='notapplicable'") %>%
  set_expt_batches(fact = "lab")
## The numbers of samples by condition are:
## 
## lvbraziliensis   lvpanamensis  notapplicable 
##             22             14              3
## The samples excluded are: TMRC30018, TMRC30045, TMRC30155.
## subset_expt(): There were 39, now there are 36 samples.
## The number of samples by batch are:
## 
##   Brazil Colombia 
##       21       15
tt <- normalize_expt(external_species, transform = "log2", convert = "cpm", norm = "quant",
                     filter = TRUE)
## Removing 6955 low-count genes (14526 remaining).
## transform_counts: Found 17 values equal to 0, adding 1 to the matrix.
plot_pca(tt)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by lvbraziliensis, lvpanamensis
## Shapes are defined by Brazil, Colombia.

ttt <- normalize_expt(external_species, transform = "log2", convert = "cpm", batch = "svaseq",
                     filter = TRUE)
## Removing 6955 low-count genes (14526 remaining).
## Setting 2874 low elements to zero.
## transform_counts: Found 2874 values equal to 0, adding 1 to the matrix.
plot_pca(ttt)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by lvbraziliensis, lvpanamensis
## Shapes are defined by Brazil, Colombia.

16 Parasite distribution

I am resurrecting some of the comparisons of the parasite transcriptome in the host data.

lp_cf <- set_expt_conditions(lp_expt, fact = "finaloutcome")
## The numbers of samples by condition are:
## 
##    cure failure 
##       6       9
table(pData(lp_cf)[["typeofcells"]])
## 
##      Biopsy Eosinophils   Monocytes Neutrophils 
##           8           1           1           5
lp_cf_norm <- normalize_expt(lp_cf, transform = "log2", convert = "cpm",
                             norm = "quant", filter = TRUE)
## Removing 0 low-count genes (8778 remaining).
## transform_counts: Found 2072 values equal to 0, adding 1 to the matrix.
lp_cf_sm <- plot_sm(lp_cf_norm)
lp_cf_sm
## When the standard median metric was plotted, the values observed range
## from 0.292554428978019 to 1 with quartiles at 0.499410501748897 and 0.543725249643294.

lp_cf_corheat <- plot_corheat(lp_cf_norm)
lp_cf_corheat
## A heatmap of pairwise sample correlations ranging from: 
## 0.292554428978019 to 0.825046546195177.

lp_cf_norm_pca <- plot_pca(lp_cf_norm)
lp_cf_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by 1, 2, 3.

pp(file = "figures/lp_cf_norm_pca.svg")
lp_cf_norm_pca[["plot"]]
dev.off()
## png 
##   2
lp_cf_nb <- normalize_expt(lp_cf, transform = "log2", convert = "cpm",
                           batch = "svaseq", filter = "simple")
## Removing 205 low-count genes (8573 remaining).
## Setting 3761 low elements to zero.
## transform_counts: Found 3761 values equal to 0, adding 1 to the matrix.
lp_cf_nb_pca <- plot_pca(lp_cf_nb)
lp_cf_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by 1, 2, 3.

Note, the previous task includes visits 2/3 and multiple cell types and as a result is likely to include the most profoundly infected people (only those in whom we observe >30,000 reads and >3,000 genes of parasite reads. Thus, even though it sort of looks like there might be a C/F difference, the sva shows that to be a lie.

Nonetheless, we can make this clearer by excluding the visits2/3 and/or non-biopsies.

lp_cf_biop <- subset_expt(lp_cf, subset = "typeofcells=='Biopsy'")
## The samples excluded are: TMRC30071, TMRC30094, TMRC30093, TMRC30083, TMRC30121, TMRC30047, TMRC30072.
## subset_expt(): There were 15, now there are 8 samples.
lp_cf_biop_norm <- normalize_expt(lp_cf_biop, transform = "log2", convert = "cpm",
                                  norm = "quant", filter = TRUE)
## Removing 0 low-count genes (8778 remaining).
## transform_counts: Found 1420 values equal to 0, adding 1 to the matrix.
lp_cf_biop_sm <- plot_sm(lp_cf_biop_norm)
lp_cf_biop_sm
## When the standard median metric was plotted, the values observed range
## from 0.453068568209257 to 1 with quartiles at 0.600764256339962 and 0.705411079989924.

lp_cf_biop_corheat <- plot_corheat(lp_cf_biop_norm)
lp_cf_biop_corheat
## A heatmap of pairwise sample correlations ranging from: 
## 0.453068568209257 to 0.822965903624259.

lp_cf_biop_norm_pca <- plot_pca(lp_cf_biop_norm)
lp_cf_biop_norm_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by 1.

lp_cf_biop_nb <- normalize_expt(lp_cf_biop, transform = "log2", convert = "cpm",
                                batch = "svaseq", filter = "simple")
## Removing 274 low-count genes (8504 remaining).
## Setting 2348 low elements to zero.
## transform_counts: Found 2348 values equal to 0, adding 1 to the matrix.
lp_cf_biop_nb_pca <- plot_pca(lp_cf_biop_nb)
lp_cf_biop_nb_pca
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by 1.

17 Examining PCs and SVs vs. the metadata: SV loadings

This is coming out of the 09varcor_regression document and was initially performed by Theresa. If this works well and is sufficient, I might remove that document and therefore have that much less stuff to check on for correctness.

Note from atb: I need to make a few changes to this section, primarily we need to be able to automatically generate the tables of f-statistics; in case the data changes (which it did since Theresa performed this, one sample was removed I think). With that caveat, the following is coming directly out of her SVA_V3_Tumaco document. I also would like to compare the SV-fstats to similar metrics I took of PCs vs. metadata factors. My assumption (if I understand the math in sva at all) is that they should largely complement/agree with each other.

We would like to know what the heck SVA is actually correcting for when we do an SVA correction. Are there any metadatas that these SV’s are correlated with?

To do this, I will run SVA to get the SV loadings. I will then do something akin to PC loadings analysis to see how these individual SVs (and combinatorial SVs) are associated with any

I will use a computed F-statistic for this association to measure the between:within cluster variance in a model (and tell us if that factor is a “good” indicator of separation based on that sv loading).

\[\begin{equation} F-statistic = \frac{TSS - RSS}{RSS} \end{equation}\]

So for this, I will use a series of linear regressions which model each dimension of SVA as a function of the observed variables that describe the known underlying group structure (clinic, visit, patient, …)

\[\begin{equation} \underbrace{X_i}_\text{dimension i of SVA} = \underbrace{B_0 + B_1 celltype/visit/clinic/donor}_\text{underlying group structure} \end{equation}\]

We can do this breakdown in a few ways to answer different questions which I will explore further below.

We have decided the Cali samples don’t offer a lot of extra information for us, and there is significant clinic batch effect, so we are going to remove the Cali samples and evaluate the SV loadings.

The first thing to do is the actual SVA to get the loadings.

I may have changed a few of Theresa’s variable names when I first copy/pasted this document together without taking note of the modification; but I am reasonably certain that the intended data structures are the same.

clinic_sva <- normalize_expt(t_clinical, filter = TRUE)
## Removing 5796 low-count genes (14156 remaining).
pheno <- pData(clinic_sva)
edata <- exprs(clinic_sva)

mod <- model.matrix(~as.factor(finaloutcome), data = pheno)
mod0 <- model.matrix(~1, data = pheno)

svobj <- sva::svaseq(edata, mod, mod0)
## Number of significant surrogate variables is:  4 
## Iteration (out of 5 ):1  2  3  4  5

17.0.1 SV 1

SVA found 4 SV’s. We can plot them individually to visually inspect their separation w.r.t some metadata.

svs <- as.data.frame(svobj$sv)
colnames(svs) <- paste0("sv_", seq(1:4))
svs <- cbind(svs, pheno)

sv1_typeofcells <- ggplot(svs, aes(y = sv_1, x = typeofcells, fill = typeofcells)) +
  geom_violin() +
  geom_point(alpha = 0.75) +
  xlab("Type of Cells") +
  ylab("SV 1")  +
  theme_classic() +
  theme(legend.position = "none")

sv1_visit <-  ggplot(svs, aes(y = sv_1, x = visitnumber, fill = visitnumber)) +
  geom_violin() +
  geom_point(alpha = 0.75) +
  xlab("Visit Number") +
  ylab("SV 1")  +
  theme_classic() +
  theme(legend.position = "none")

sv1_donor <- ggplot(svs, aes(y = sv_1, x = donor, fill = donor)) +
  geom_violin() +
  geom_point(alpha = 0.75) +
  xlab("Donor") +
  ylab("SV 1")  +
  theme_classic() +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, vjust = 0.5, hjust = 0.5))

sv1_typeofcells

sv1_visit

sv1_donor
## Warning: Groups with fewer than two datapoints have been dropped.
## i Set `drop = FALSE` to consider such groups for position adjustment purposes.
## Groups with fewer than two datapoints have been dropped.
## i Set `drop = FALSE` to consider such groups for position adjustment purposes.

##grid.arrange(sv1_typeofcells, sv1_visit, sv1_donor, nrow = 2)

17.0.2 SV2

sv2_typeofcells <- ggplot(svs, aes(y = sv_2, x = typeofcells, fill = typeofcells)) +
  geom_violin() +
  geom_point(alpha = 0.75) +
  xlab("Type of Cells") +
  ylab("SV 2")  +
  theme_classic() +
  theme(legend.position = "none")

sv2_visit <-  ggplot(svs, aes(y = sv_2, x = visitnumber, fill = visitnumber)) +
  geom_violin() +
  geom_point(alpha = 0.75) +
  xlab("Visit Number") +
  ylab("SV 2")  +
  theme_classic() +
  theme(legend.position = "none")

sv2_donor <- ggplot(svs, aes(y = sv_2, x = donor, fill = donor)) +
  geom_violin() +
  geom_point(alpha = 0.75) +
  xlab("Donor") +
  ylab("SV 2")  +
  theme_classic() +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, vjust = 0.5, hjust = 0.5))


#grid.arrange(sv2_typeofcells, sv2_visit, sv2_donor, nrow = 2)
sv2_typeofcells

sv2_visit

sv2_donor
## Warning: Groups with fewer than two datapoints have been dropped.
## i Set `drop = FALSE` to consider such groups for position adjustment purposes.
## Groups with fewer than two datapoints have been dropped.
## i Set `drop = FALSE` to consider such groups for position adjustment purposes.

I spent a little time to simplify and try to make the reasoning above a little more robust so that I can regenerate Theresa’s xlsx table of f-statistics as well as add a little more information. The following block attempts this…

Najib correctly pointed out that I left off clinic in this first invocation.

queries <- c("typeofcells", "visitnumber", "clinic", "donor")
tc_clinical_fpstats <- svpc_fstats(tc_clinical, num_pcs = 5, queries = queries)
## The input appears raw, performing default normalization.
## Removing 5654 low-count genes (14298 remaining).
## transform_counts: Found 222365 values equal to 0, adding 1 to the matrix.
## Removing 5654 low-count genes (14298 remaining).
## Setting 27144 low elements to zero.
## transform_counts: Found 27144 values equal to 0, adding 1 to the matrix.
queries <- c("typeofcells", "visitnumber", "donor")
t_clinical_fpstats <- svpc_fstats(t_clinical, num_pcs = 5, queries = queries)
## The input appears raw, performing default normalization.
## Removing 5796 low-count genes (14156 remaining).
## transform_counts: Found 126745 values equal to 0, adding 1 to the matrix.
## Removing 5796 low-count genes (14156 remaining).
## Setting 17331 low elements to zero.
## transform_counts: Found 17331 values equal to 0, adding 1 to the matrix.
c_clinical_fpstats <- svpc_fstats(c_clinical, num_pcs = 5, queries = queries)
## The input appears raw, performing default normalization.
## Removing 6553 low-count genes (13399 remaining).
## transform_counts: Found 66487 values equal to 0, adding 1 to the matrix.
## Removing 6553 low-count genes (13399 remaining).
## Setting 5038 low elements to zero.
## transform_counts: Found 5038 values equal to 0, adding 1 to the matrix.

18 Send to an xlsx workbook

I am going to add a little code in this section to send this to an xlsx file. I might need to add a little bit of code as well because I am not certain that there is a document which contains this calculation for each data subset.

I put together a quick function which writes the results of one of these analyses to a xlsx file, but it very much assumes a single dataset and is not easily amendable to multiple; therefore I will strip the code out here into a new function to repeat itself for the Tumaco/Cali/Both data for an arbitrary combination.

Query from Maria Adelaida: Perform a similar f/p statistics plot/xlsx table but using the first 5 PCs and SVs; perhaps also include the amount of variance remaining tale (I forget its name: residuals).

But also do slightly different plots: 2 plots: 1 with PCs before SVA followed by the SVs, the 1 with SVs followed by post PCs.

Given this, perform this task with: Clinic, Donor, Visit, Celltype using the clinical samples (no biopsies).

write_combined_fpstats <- function(both = tc_clinical_fpstats, tumaco = t_clinical_fpstats,
                                   cali = c_clinical_fpstats,
                                   excel = "excel/combined_svpc_fstats.xlsx") {
  xlsx <- init_xlsx(excel)
  wb <- xlsx[["wb"]]
  excel_basename <- xlsx[["basename"]]
  do_excel <- TRUE
  if (is.null(wb)) {
    do_excel <- FALSE
  }

  current_row <- 1

  pref <- both[["pre_f"]]
  svf <- both[["sv_f"]]
  postf <- both[["post_f"]]
  ## Changing the rownames due to rbind rownames shenanigans.
  rownames(pref) <- paste0("PrePC", seq_len(nrow(pref)))
  rownames(postf) <- paste0("PostPC", seq_len(nrow(postf)))
  allf <- rbind(pref, svf, postf)

  prep <- both[["pre_p"]]
  svp <- both[["sv_p"]]
  postp <- both[["post_p"]]
  rownames(prep) <- paste0("PrePC", seq_len(nrow(prep)))
  rownames(postp) <- paste0("PostPC", seq_len(nrow(postp)))
  allp <- rbind(prep, svp, postp)

  fun_plot <- heatmap.3(as.matrix(allp), dendrogram = "none",
                        scale = "none", trace = "none",
                        Colv = FALSE, Rowv = FALSE)
  image <- grDevices::recordPlot()

  xlsx_result <- write_xlsx(data = allf, wb = wb, sheet = "Fvalues", start_row = current_row,
                            title = "Both clinics, SVA and PC analysis, F-values")
  xlsx_result <- write_xlsx(data = allp, wb = wb, sheet = "Pvalues", start_row = current_row,
                            title = "Both clinics, SVA and PC analysis, P-values")
  current_row <- xlsx_result[["end_row"]] + 2
  try_result <- xlsx_insert_png(
    a_plot = image, wb = wb, sheet = "Pvalues", start_col = ncol(allp) + 2)
  image_files = c()
  if (! "try-error" %in% class(try_result)) {
    image_files = try_result[["filename"]]
  }

  pref <- tumaco[["pre_f"]]
  svf <- tumaco[["sv_f"]]
  postf <- tumaco[["post_f"]]
  ## Changing the rownames due to rbind rownames shenanigans.
  rownames(pref) <- paste0("PrePC", seq_len(nrow(pref)))
  rownames(postf) <- paste0("PostPC", seq_len(nrow(postf)))
  allf <- rbind(pref, svf, postf)

  prep <- tumaco[["pre_p"]]
  svp <- tumaco[["sv_p"]]
  postp <- tumaco[["post_p"]]
  rownames(prep) <- paste0("PrePC", seq_len(nrow(prep)))
  rownames(postp) <- paste0("PostPC", seq_len(nrow(postp)))
  allp <- rbind(prep, svp, postp)

  xlsx_result <- write_xlsx(data = allf, wb = wb, sheet = "Fvalues", start_row = current_row,
                            title = "Tumaco, SVA and PC analysis, F-values")
  xlsx_result <- write_xlsx(data = allp, wb = wb, sheet = "Pvalues", start_row = current_row,
                            title = "Tumaco, SVA and PC analysis, P-values")
  current_row <- xlsx_result[["end_row"]] + 2

  pref <- cali[["pre_f"]]
  svf <- cali[["sv_f"]]
  postf <- cali[["post_f"]]
  ## Changing the rownames due to rbind rownames shenanigans.
  rownames(pref) <- paste0("PrePC", seq_len(nrow(pref)))
  rownames(postf) <- paste0("PostPC", seq_len(nrow(postf)))
  allf <- rbind(pref, svf, postf)

  prep <- cali[["pre_p"]]
  svp <- cali[["sv_p"]]
  postp <- cali[["post_p"]]
  rownames(prep) <- paste0("PrePC", seq_len(nrow(prep)))
  rownames(postp) <- paste0("PostPC", seq_len(nrow(postp)))
  allp <- rbind(prep, svp, postp)

  xlsx_result <- write_xlsx(data = allf, wb = wb, sheet = "Fvalues", start_row = current_row,
                            title = "Cali, SVA and PC analysis, F-values")
  xlsx_result <- write_xlsx(data = allp, sheet = "Pvalues", wb = wb, start_row = current_row,
                            title = "Cali, SVA and PC analysis, P-values")
  current_row <- xlsx_result[["end_row"]] + 2

  excel_ret <- try(openxlsx::saveWorkbook(wb, excel, overwrite = TRUE))
  removed <- try(suppressWarnings(file.remove(image_files)), silent = TRUE)
}

clinical_fpstats <- write_combined_fpstats(
  both = tc_clinical_fpstats, tumaco = t_clinical_fpstats, cali = c_clinical_fpstats,
  excel = glue("excel/clinical_fpstats-v{ver}.xlsx"))

The F-stat resulting from an anova for the model sv ~ metadata_factor shows that the main thing we are correcting for with an SVA correction (with cure/fail as the model factor) is the cell type. The factor donor contributes the next highest separation, with clinic falling in third. the visit contributes essentially no variance in this data, which we knew from the DE results.

Bibliography

Hoffman, Gabriel E., and Eric E. Schadt. 2016. variancePartition: Interpreting Drivers of Variation in Complex Gene Expression Studies.” BMC Bioinformatics 17 (1): 483. https://doi.org/10.1186/s12859-016-1323-z.
LS0tCnRpdGxlOiAiVE1SQzMgYHIgU3lzLmdldGVudignVkVSU0lPTicpYDogVmlzdWFsaXppbmcgQW5hbHlzZXMiCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCmJpYmxpb2dyYXBoeTogYXRiLmJpYgpvdXRwdXQ6CiBodG1sX2RvY3VtZW50OgogIGNvZGVfZG93bmxvYWQ6IHRydWUKICBjb2RlX2ZvbGRpbmc6IHNob3cKICBmaWdfY2FwdGlvbjogdHJ1ZQogIGZpZ19oZWlnaHQ6IDcKICBmaWdfd2lkdGg6IDcKICBoaWdobGlnaHQ6IHplbmJ1cm4KICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiByZWFkYWJsZQogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgY29sbGFwc2VkOiBmYWxzZQogICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHkgLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDE2MDBweDsKfQpib2R5LCB0ZCB7CiAgZm9udC1zaXplOiAxNnB4Owp9CmNvZGUucnsKICBmb250LXNpemU6IDE2cHg7Cn0KcHJlIHsKICBmb250LXNpemU6IDE2cHgKfQo8L3N0eWxlPgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoYnJvb20pICMjIFByb3ZpZGVzIHRpZHkgbWV0aG9kcyBmb3IgbG0vZ2xtL2V0YwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGZvcmNhdHMpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ3N0YXRzcGxvdCkKbGlicmFyeShnbHVlKQpsaWJyYXJ5KGhwZ2x0b29scykKbGlicmFyeShsYXJlcykKCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzID0gVFJVRSwgdmVyYm9zZSA9IFRSVUUsIHdpZHRoID0gOTAsIGVjaG8gPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZXJyb3IgPSBUUlVFLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gOCwgZmlnLnJldGluYSA9IDIsCiAgb3V0LndpZHRoID0gIjEwMCUiLCBkZXYgPSAicG5nIiwKICBkZXYuYXJncyA9IGxpc3QocG5nID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKSkKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHMgPSA0LCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemUgPSAxMikpCnZlciA8LSBTeXMuZ2V0ZW52KCJWRVJTSU9OIikKcnVuZGF0ZSA8LSBmb3JtYXQoU3lzLkRhdGUoKSwgZm9ybWF0ID0gIiVZJW0lZCIpCgpybWRfZmlsZSA8LSAiMDJ2aXN1YWxpemF0aW9uIgpzYXZlZmlsZSA8LSBnc3ViKHBhdHRlcm4gPSAiXFwuUm1kIiwgcmVwbGFjZT0iXFwucmRhXFwueHoiLCB4ID0gcm1kX2ZpbGUpCmxvYWRlZCA8LSBsb2FkKGZpbGUgPSBnbHVlKCJyZGEvdG1yYzNfZGF0YV9zdHJ1Y3R1cmVzLXZ7dmVyfS5yZGEiKSkKYGBgCgojIFRPRE86CgoxLiAgRW5zdXJlIHRoYXQgbm8gdmFyaWFuY2UgcGFydGl0aW9uIGluY2x1ZGVzIGJpb3BzaWVzIGJleW9uZCBzb21lCiAgICBpbml0aWFsIGN1cnNvcnkuCgojIENoYW5nZWxvZwoKKiBTZXQgaW5wdXQgZGF0YSB0byB0aGUgbmV3IDIwMjIxMiBkYXRhc2V0LiAgTG9va2luZyBmb3Igc29tZSBtZXNzZWQgdXAgY29sb3JzLgoqIFJlYXNvbmFibHkgY2VydGFpbiBJIGZpZ3VyZWQgb3V0IHRoZSBjb2xvciBkaXNjcmVwZW5jeS4gIEkgd2FzCiAgbGV0dGluZyB0aGUgZW9zaW5vcGhpbCBkYXRhc2V0IGNob29zZSBpdHMgb3duIGNvbG9ycyByYXRoZXIgdGhhbgogIGZvcmNlIHRoZW0gdG8gYmUgdGhlIHNhbWUgYXMgdGhlIG90aGVyIGNlbGwgdHlwZXM7IGV2ZW4gdGhvdWdoIEkKICBfdGhvdWdodF8gSSB0b2xkIHRoZW0gdG8gZXhwbGljaXRseSBzZXQgdGhlaXIgY29sb3JzIHRvIGJlIHRoZSBzYW1lCiAgYXMgdGhlIG90aGVycy4gIEkgdGhpbmsgdGhlIGNoYW5nZXMgSSBtYWRlIGluIGRhdGFzZXRzLlJtZCBmaXhlZAogIHRoaXMsIHNvIEkgcmVnZW5lcmF0ZWQgdGhlIHJkYS9ldGMgaW4gdGhhdCBkb2N1bWVudCBhbmQgYW0gbm93CiAgdGVzdGluZyB0aGUgY29sb3JzIGhlcmUuCgojIEludHJvZHVjdGlvbgoKTW92aW5nIGFsbCBvZiB0aGUgdmlzdWFsaXphdGlvbiBhbmQgZGlhZ25vc3RpYyB0YXNrcyB0byB0aGlzIGRvY3VtZW50LgpUaGUgbWV0YWRhdGEgYW5kIGdlbmUgYW5ub3RhdGlvbiBkYXRhIGNvbGxlY3Rpb24gdGFza3MgYXJlIHRoZXJlZm9yZQppbiB0bXJjM19kYXRhX3N0cnVjdHVyZXMuUm1kLiAgVGhlIHJlYXNvbnMgZm9yIHNvbWUgb2YgdGhlIGRhdGEKc3RydWN0dXJlIGNyZWF0aW9uIGluIHRoYXQgZG9jdW1lbnQgaXMgbWFkZSBjbGVhciBoZXJlLgoKIyBOb3RlcwoKMS4gIExlc2lvbiB2cyBVbGNlcjogVWxjZXIgaXMgdGhlIGJhc2Ugb2YgdGhlIGNyYXRlciBvZiB0aGUgbGVzaW9uCm9ic2VydmVkLiAgVGhlIGxlc2lvbiBpcyB0aGlzLCB0aGUgYm9yZGVyLCBhbmQgYW55IHJlZ2lvbiB3aXRoIHNpZ25zCm9mIGluZmxhbW1hdGlvbi4gIEl0IGlzIG5vdCBrbm93biBpZiB0aGVzZSBtZXRyaWNzIGFyZSBlcXVpdmFsZW50LCBvcgppZiBvbmUgaXMgYmV0dGVyIHRoYW4gdGhlIG90aGVyLiAgU29tZSBwZW9wbGUgZG8gbm90IGhhdmUgdWxjZXJzIGFuZAp0aGVyZWZvcmUgaW4gdGhvc2UgY2FzZXMgd2UgY2FuIG9ubHkgcmVhbGx5IGNvbnNpZGVyIHRoZSBsZXNpb24gc2l6ZS4KRS5nLiBtb3N0IHBlb3BsZSBpbiBDb2xvbWJpYSBoYXZlIHVsY2Vycywgd2hpY2ggYXJlIHRoZSBjcmF0ZXJlZCBzb3JlOwpob3dldmVyIHRoZXJlIGFyZSBhIGZldyBwZW9wbGUgd2hvIGhhdmUgYSAncGxhcXVlJyBvciBzb21lIGZvcm0gb2YKc21hbGxlciwgbGVzcyBpbnRydXNpdmUgcHJlc2VudGF0aW9uIC0tIHRoZXNlIGFyZSBzdGlsbCBjdXRhbmVvdXMuCgpUaHVzIHRoZSBsZXNpb24gc2l6ZSBpcyB0aGUgbW9yZSBpbmNsdXNpdmUgbWV0cmljLCBidXQgcG90ZW50aWFsbHkKdWxjZXIgc2l6ZSBpcyBtb3JlIGluZm9ybWF0aXZlPyAgQW55IGluZmxhbW1hdGlvbiBpbiB0aGUgc2tpbiBjYXVzZXMKdGhlIHBlcnNvbiB0byBiZSBkZWZpbmVkIGFzIGZhaWx1cmUuCgoyLiBOb3RlIGZyb20gTWFyaWEgQWRlbGFpZGE6IFNvbWUgY2hlbW9raW5lcyBhcmUgc3VnZ2VzdGl2ZSBvZgogICBFb3Npbm9waGlsIHJlY3J1aXRtZW50LgoKIyMgR29hbHMKClRoZXNlIHNhbXBsZXMgYXJlIGZyb20gcGF0aWVudHMgd2hvIGVpdGhlciBzdWNjZXNzZnVsbHkgY2xlYXJlZCBhCkxlaXNobWFuaWEgcGFuYW1lbnNpcyBpbmZlY3Rpb24gZm9sbG93aW5nIHRyZWF0bWVudCwgb3IgZGlkIG5vdC4gIFRoZXkKaW5jbHVkZSBiaW9wc2llcyBmcm9tIGVhY2ggcGF0aWVudCBhbG9uZyB3aXRoIHB1cmlmaWNhdGlvbnMgZm9yCk1vbm9jeXRlcywgTmV1dHJvcGhpbHMsIGFuZCBFb3Npbm9waGlscy4gIFdoZW4gcG9zc2libGUsIHRoaXMgcHJvY2Vzcwp3YXMgcmVwZWF0ZWQgb3ZlciB0aHJlZSB2aXNpdHM7IGJ1dCBzb21lIHBhdGllbnRzIGRpZCBub3QgcmV0dXJuCmZvciB0aGUgc2Vjb25kIG9yIHRoaXJkIHZpc2l0LgoKVGhlIG92ZXItYXJjaGluZyBnb2FsIGlzIHRvIGxvb2sgZm9yIGF0dHJpYnV0ZXMobW9zdCBsaWtlbHkgZ2VuZXMpCndoaWNoIGRpc3Rpbmd1aXNoIHBhdGllbnRzIHdobyBkbyBhbmQgZG8gbm90IGN1cmUgdGhlIGluZmVjdGlvbiBhZnRlcgp0cmVhdG1lbnQuICBJZiBwb3NzaWJsZSwgdGhlc2Ugd2lsbCBiZSBhcHBhcmVudCBvbiB0aGUgZmlyc3QgdmlzaXQuCgpgYGB7cn0KcGxvdF9sZWdlbmQoaHNfZXhwdCkKcGxvdF9ub256ZXJvKGhzX2V4cHQpCmBgYAoKIyMgRmlndXJlIFMyICsgMTogTm9uLXplcm8gZ2VuZXMgYWZ0ZXIgc2FtcGxlIGZpbHRlcmluZwoKVGhlIGZvbGxvd2luZyBwbG90IGlzIGVzc2VudGlhbGx5IGlkZW50aWNhbCB0byB0aGUgcHJldmlvdXMgd2l0aCB0d28KZXhjZXB0aW9uczoKCjEuICBUaGUgc2FtcGxlcyB3aXRoIHRvbyBmZXcgZ2VuZXMgKDExLDAwMCBjdXJyZW50bHkpIGFyZSBnb25lLiAgSW4KICAgIHRoZSBjdXJyZW50IGl0ZXJhdGlvbiBvZiB0aGUgZGF0YXNldHMgUm1kLCB0aGlzIGNvbXByaXNlcyBlaXRoZXIKICAgIHR3byBvciB0aHJlZSBzYW1wbGVzLgoyLiAgVGhlIHNhbXBsZXMgYXJlIGNvbG9yZWQgYnkgY3VyZShwdXJwbGUpL2ZhaWwoeWVsbG93KQoKYGBge3J9CnBsb3Rfbm9uemVybyh0Y192YWxpZCwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKYGBgCgojIyBRdWljayBwaWN0dXJlIGJlZm9yZSByZW1vdmluZyBtaWx0ZWZvc2luZSBzYW1wbGVzCgpNYXJpYSBBZGVsYWlkYSdzIHF1b3RlOiAiSSB3b3VsZCBsaWtlIG9uZSBwaWN0dXJlIG9mIGFsbCBzYW1wbGVzCmluY2x1ZGluZyB0aGUgbWlsdGVmb3NpbmUgc28gdGhhdCBJIGNhbiBrZWVwIGluIG15IG1pbmQgd2h5IHdlIHJlbW92ZWQKdGhlbS4iCgojIFBDQSB3aXRoIGJvdGggZHJ1Z3MKClRoZSBmb2xsb3dpbmcgYmxvY2sgd2lsbCBpbGx1c3RyYXRlIHdoeSB3ZSBjaG9zZSB0byByZW1vdmUgdGhlIHNhbXBsZXMKd2hpY2ggd2VyZSB0cmVhdGVkIHdpdGggbWlsdGVmb3NpbmUuICBUaGUgc2hvcnQgcmVhc29uOiB0b28gZmV3CnNhbXBsZXMuICBUaGUgc2xpZ2h0bHkgbG9uZ2VyIHJlYXNvbjogbWlsdGVmb3NpbmUgaGFzIGEgZGlmZmVyZW50IG1vZGUKb2YgYWN0aW9uLgoKYGBge3J9CnRjX2V4cHRfbm9ybSA8LSBub3JtYWxpemVfZXhwdChoc19leHB0LCBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgdHJhbnNmb3JtID0gImxvZzIiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiZHJ1ZyIpCgp0Y19leHB0X2RydWdfcGNhIDwtIHBsb3RfcGNhKHRjX2V4cHRfbm9ybSwgY2lzID0gTlVMTCkKdGNfZXhwdF9kcnVnX3BjYSA8LSBwbG90X3BjYSh0Y19leHB0X25vcm0pCnRjX2V4cHRfZHJ1Z19wY2EKCnRjX2V4cHRfbmIgPC0gbm9ybWFsaXplX2V4cHQoaHNfZXhwdCwgZmlsdGVyID0gVFJVRSwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgYmF0Y2ggPSAic3Zhc2VxIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImRydWciKQp0Y19leHB0X2RydWdfbmJfcGNhIDwtIHBsb3RfcGNhKHRjX2V4cHRfbmIpCnRjX2V4cHRfZHJ1Z19uYl9wY2EKCnRfZXhwdF9kcnVnIDwtIHN1YnNldF9leHB0KGhzX2V4cHQsIHN1YnNldCA9ICJjbGluaWM9PSd0dW1hY28nIikKdF9leHB0X25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9leHB0X2RydWcsIGZpbHRlciA9IFRSVUUsIG5vcm0gPSAicXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIHRyYW5zZm9ybSA9ICJsb2cyIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImRydWciKQp0X2V4cHRfZHJ1Z19wY2EgPC0gcGxvdF9wY2EodF9leHB0X25vcm0pCnRfZXhwdF9kcnVnX3BjYQoKdF9leHB0X25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfZXhwdF9kcnVnLCBmaWx0ZXIgPSBUUlVFLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBiYXRjaCA9ICJzdmFzZXEiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiZHJ1ZyIpCnRfZXhwdF9kcnVnX25iX3BjYSA8LSBwbG90X3BjYSh0X2V4cHRfbmIpCnRfZXhwdF9kcnVnX25iX3BjYQpgYGAKCiMgSG9zdCBEaXN0cmlidXRpb25zL1Zpc3VhbGl6YXRpb25zIG9mIGludGVyZXN0CgpUaGUgc2V0cyBvZiBzYW1wbGVzIHVzZWQgdG8gdmlzdWFsaXplIHRoZSBkYXRhIHdpbGwgYWxzbyBjb21wcmlzZSB0aGUKc2V0cyB1c2VkIHdoZW4gbGF0ZXIgcGVyZm9ybWluZyB0aGUgdmFyaW91cyBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbgphbmFseXNlcy4KCiMjIEdsb2JhbCBtZXRyaWNzCgpTdGFydCBvdXQgd2l0aCBzb21lIGluaXRpYWwgbWV0cmljcyBvZiBhbGwgc2FtcGxlcy4gIFRoZSBtb3N0IG9idmlvdXMKYXJlIHBsb3RzIG9mIHRoZSBudW1iZXJzIG9mIG5vbi16ZXJvIGdlbmVzIG9ic2VydmVkLCBoZWF0bWFwcyBzaG93aW5nCnRoZSByZWxhdGl2ZSByZWxhdGlvbnNoaXBzIGFtb25nIHRoZSBzYW1wbGVzLCB0aGUgcmVsYXRpdmUgbGlicmFyeQpzaXplcywgYW5kIHNvbWUgUENBLiAgSXQgbWlnaHQgYmUgc21hcnQgdG8gc3BsaXQgdGhlIGxpYnJhcnkgc2l6ZXMgdXAKYWNyb3NzIHN1YnNldHMgb2YgdGhlIGRhdGEsIGJlY2F1c2UgdGhleSBoYXZlIGV4cGFuZGVkIHRvbyBmYXIgdG8gc2VlCndlbGwgb24gYSBjb21wdXRlciBzY3JlZW4uCgpUaGUgbW9zdCBsaWtlbHkgZmFjdG9ycyB0byBxdWVyeSB3aGVuIGNvbnNpZGVyaW5nIHRoZSBlbnRpcmUgZGF0YXNldAphcmUgY3VyZS9mYWlsLCB2aXNpdCwgYW5kIGNlbGwgdHlwZS4gIFRoaXMgaXMgdGhlIGxldmVsIGF0IHdoaWNoIHdlCndpbGwgY2hvb3NlIHNhbXBsZXMgdG8gZXhjbHVkZSBmcm9tIGZ1dHVyZSBhbmFseXNlcy4KCmBgYHtyfQpwbG90X2xlZ2VuZCh0Y19iaW9wc2llcykKcGxvdF9saWJzaXplKHRjX2Jpb3BzaWVzKQpwbG90X25vbnplcm8odGNfYmlvcHNpZXMpCmBgYAoKcGxvdF9saWJzaXplX3ByZXBvc3QgYXR0ZW1wdHMgdG8gcHJvdmlkZSBhbiBpZGVhIGFib3V0IGhvdyBtdWNoIGRhdGEKaXMgbG9zdCB3aGVuIGxvdy1jb3VudCBmaWx0ZXJpbmcgdGhlIGRhdGEuCgpUaGUgZmlyc3QgcGxvdCBpdCBwcm9kdWNlcyBpcyBhIGJhcnBsb3Qgb2YgdGhlIG51bWJlciBvZiByZWFkcyByZW1vdmVkCmJ5IHRoZSBmaWx0ZXIgZnJvbSBlYWNoIHNhbXBsZS4gIFRoZSBzZWNvbmQgcGxvdCBoYXMgdHdvIGJhcnMsIHRoZSB0b3AKYmFyIGlzIGxhYmVsZWQgd2l0aCB0aGUgbnVtYmVyIG9mIGxvdy1jb3VudCBnZW5lcyBiZWZvcmUgdGhlIGZpbHRlci4KVGhlIGxvd2VyIGJhciByZXByZXNlbnRzIHRoZSBudW1iZXIgYWZ0ZXIgdGhlIGZpbHRlciBhbmQgaXMgYXNzdW1lZCB0bwpiZSBxdWl0ZSBsb3cuCgpgYGB7cn0KYmlvcHN5X3ByZXBvc3QgPC0gcGxvdF9saWJzaXplX3ByZXBvc3QodGNfYmlvcHNpZXMpCmJpb3BzeV9wcmVwb3N0CiNiaW9wc3lfcHJlcG9zdCRjb3VudF9wbG90CiNiaW9wc3lfcHJlcG9zdCRsb3dnZW5lX3Bsb3QKIyMgTWluaW11bSBudW1iZXIgb2YgYmlvcHN5IGdlbmVzOiB+IDE0LDAwMAoKcGxvdF9saWJzaXplKHRjX2Vvc2lub3BoaWxzKQpwbG90X25vbnplcm8odGNfZW9zaW5vcGhpbHMpCmVvc2lub3BoaWxfcHJlcG9zdCA8LSBwbG90X2xpYnNpemVfcHJlcG9zdCh0Y19lb3Npbm9waGlscykKZW9zaW5vcGhpbF9wcmVwb3N0W1siY291bnRfcGxvdCJdXQplb3Npbm9waGlsX3ByZXBvc3RbWyJsb3dnZW5lX3Bsb3QiXV0KIyMgTWluaW11bSBudW1iZXIgb2YgZW9zaW5vcGhpbCBnZW5lczogfiAxMyw1MDAKCnBsb3RfbGlic2l6ZSh0Y19tb25vY3l0ZXMpCnBsb3Rfbm9uemVybyh0Y19tb25vY3l0ZXMpCm1vbm9jeXRlX3ByZXBvc3QgPC0gcGxvdF9saWJzaXplX3ByZXBvc3QodGNfbW9ub2N5dGVzKQptb25vY3l0ZV9wcmVwb3N0W1siY291bnRfcGxvdCJdXQptb25vY3l0ZV9wcmVwb3N0W1sibG93Z2VuZV9wbG90Il1dCiMjIE1pbmltdW0gbnVtYmVyIG9mIG1vbm9jeXRlIGdlbmVzOiB+IDcsNTAwIGJlZm9yZSBzZXR0aW5nIHRoZSBtaW5pbXVtLgoKcGxvdF9saWJzaXplKHRjX25ldXRyb3BoaWxzKQpwbG90X25vbnplcm8odGNfbmV1dHJvcGhpbHMpCm5ldXRyb3BoaWxfcHJlcG9zdCA8LSBwbG90X2xpYnNpemVfcHJlcG9zdCh0Y19uZXV0cm9waGlscykKbmV1dHJvcGhpbF9wcmVwb3N0W1siY291bnRfcGxvdCJdXQpuZXV0cm9waGlsX3ByZXBvc3RbWyJsb3dnZW5lX3Bsb3QiXV0KIyMgTWluaW11bSBudW1iZXIgb2YgbmV1dHJvcGhpbCBnZW5lczogfiAxMCwwMDAgYmVmb3JlIHNldHRpbmcgbWluaW11bSBjb3ZlcmFnZS4KYGBgCgpUaGUgYWJvdmUgYmxvY2sganVzdCByZXBlYXRzIHRoZSBzYW1lIHR3byBwbG90cyBvbiBhIHBlci1jZWxsdHlwZQpiYXNpczogdGhlIG51bWJlciBvZiByZWFkcyBvYnNlcnZlZCAvIHNhbXBsZSBhbmQgYSBwbG90IG9mIG9ic2VydmVkCmdlbmVzIHdpdGggcmVzcGVjdCB0byBjb3ZlcmFnZS4gIEkgbWFkZSBzb21lIGNvbW1lbnRzIHdpdGggbXkKb2JzZXJ2YXRpb25zIGFib3V0IHRoZSBudW1iZXIgb2YgZ2VuZXMuCgojIFNlZWtpbmcgQ29uZm91bmRlZC9Db3JyZWxhdGVkIGZhY3RvcnMgaW4gdGhlIG1ldGFkYXRhCgpPbmUgdGFzayB3ZSB3ZXJlIHVuY2VydGFpbiBvZiBob3cgdG8gYWRkcmVzczogaG93IGJlc3QgdG8gY29uc2lkZXIgdGhlCm1hbnkgZmFjdG9ycyBwcm92aWRlZCBpbiB0aGUgbWV0YWRhdGEgYW5kIHdoZXRoZXIgb3Igbm90IHRoZXkgYXJlCmhpZ2h0bHkgY29ycmVsYXRlZCBvciBjb21wbGV0ZWx5IGNvbmZvdW5kZWQuICBUaGVyZXNhIHByb3ZpZGVkIHNvbWUKc3VnZ2VzdGlvbnMgYWJvdXQgaG93IHdlIG1pZ2h0IG1lYXN1cmUgdGhlIGRlZ3JlZSB0byB3aGljaCBjb3JyZWxhdGVkCnZhcmlhYmxlcyBtaWdodCBiZSBhIHByb2JsZW0gYW5kIGRlY2lkZSB3aGljaCB2YXJpYWJsZXMgd2UgY2FuKG5vdCkKaW5jbHVkZSBpbiBvdXIgc3RhdGlzdGljYWwgbW9kZWxzIG9mIHRoZSBkYXRhIHdoZW4gcGVyZm9ybWluZyB0aGUKZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXMuCgojIyBDb3JyZWxhdGVkIGZhY3RvcnMgaW4gdGhlIFR1bWFjbytDYWxpIGRhdGEKCkkgYW0gZ29pbmcgdG8gaW1wbGVtZW50IHRoaXMgaW4gYSBmZXcgc3RlcHMsIGZpcnN0IEkgd2lsbCBkbyBhCmNyb3NzLWNvcnJlbGF0aW9uIG9mIGEgcmVsYXRpdmVseSBsYXJnZSBhcnJheSBvZiB2YXJpYWJsZXMgaW4gdGhlCmRhdGEsIHRoZW4gZm9jdXMgb24gYSBmZXcgd2hpY2ggd2Ugc3VzcGVjdCB0byBiZSBwcm9ibGVtYXRpYy4KCmBgYHtyfQppbml0aWFsX3F1ZXJpZXMgPC0gYygiU2V4IiwgIkV0aG5pY2l0eSIsICJBZ2UiLCAiV2VpZ2h0IiwgIkhlaWdodCIsCiAgICAgICAgICAgICAgICAgICAgICJQcmV2aW91c2x5X0RpYWdub3NlZCIsICJFdm9sdXRpb25fVGltZSIsCiAgICAgICAgICAgICAgICAgICAgICJOdW1fQWN0aXZlX0xlc2lvbnMiLCAiVjJfTmV3X0xlc2lvbnMiLAogICAgICAgICAgICAgICAgICAgICAiVjNfTmV3X0xlc2lvbnMiLCAiQWRoZXJlbmNlIiwgIlRoZXJhcGV1dGljX091dGNvbWVfRmluYWwiKQppbml0aWFsX2RmIDwtIGRlbW9ncmFwaGljc19maWx0ZXJlZFssIGluaXRpYWxfcXVlcmllc10Kc3VtbWFyeShpbml0aWFsX2RmKQppbml0aWFsX251bWVyaWMgPC0gaW5pdGlhbF9kZgpmb3IgKGYgaW4gY29sbmFtZXMoaW5pdGlhbF9udW1lcmljKSkgewogIGluaXRpYWxfbnVtZXJpY1tbZl1dIDwtIGFzLm51bWVyaWMoYXMuZmFjdG9yKGluaXRpYWxfbnVtZXJpY1tbZl1dKSkKfQppbml0aWFsX2Nyb3NzIDwtIGNvcnJfY3Jvc3MoaW5pdGlhbF9udW1lcmljKQpwcChmaWxlID0gImltYWdlcy9pbml0aWFsX2Nyb3NzY29yLnBkZiIpCmluaXRpYWxfY3Jvc3MKZGV2Lm9mZigpCmluaXRpYWxfY3Jvc3MKYGBgCgpXZSBzaG91bGQgcmVtb3ZlIGhlaWdodCBhbmQgd2VpZ2h0LCBidXQgSSB3YW50ZWQgZmlyc3QgdG8gc2VlIHRoYXQKZXZlcnl0aGluZyB3YXMgd29ya2luZyBhcyBleHBlY3RlZC4gIFdlIGFsc28gd2lsbCB3YW50IHRvIGV4Y2x1ZGUKZmluYWwgb3V0Y29tZSB3aGVuIHNlYXJjaGluZyBmb3IgZmFjdG9ycyB3aGljaCBhcmUgdW5zdWl0YWJsZSBmb3IKbW9kZWwgaW5jbHVzaW9uLgoKYGBge3J9Cm1vZGVsX3Rlc3RfZGYgPC0gaW5pdGlhbF9kZgptb2RlbF90ZXN0X2RmW1siV2VpZ2h0Il1dIDwtIE5VTEwKbW9kZWxfdGVzdF9kZltbIkhlaWdodCJdXSA8LSBOVUxMCm1vZGVsX3Rlc3RfZGZbWyJUaGVyYXBldXRpY19PdXRjb21lX0ZpbmFsIl1dIDwtIE5VTEwKbW9kZWxfdGVzdF9udW1lcmljIDwtIGluaXRpYWxfbnVtZXJpYwptb2RlbF90ZXN0X251bWVyaWNbWyJXZWlnaHQiXV0gPC0gTlVMTAptb2RlbF90ZXN0X251bWVyaWNbWyJIZWlnaHQiXV0gPC0gTlVMTAptb2RlbF90ZXN0X251bWVyaWNbWyJUaGVyYXBldXRpY19PdXRjb21lX0ZpbmFsIl1dIDwtIE5VTEwKCnRlc3RfY3Jvc3MgPC0gY29ycl9jcm9zcyhtb2RlbF90ZXN0X251bWVyaWMpCnBwKGZpbGUgPSAiaW1hZ2VzL21vZGVsX3Rlc3RfY3Jvc3Njb3IucGRmIikKdGVzdF9jcm9zcwpkZXYub2ZmKCkKdGVzdF9jcm9zcwpgYGAKCkF0IHRoaXMgcG9pbnQgd2UgaGF2ZSBzb21lIGZhY3RvcnMgd2hpY2ggYXJlIGZsYWdnZWQgYXMgaGlnaGx5CmNvcnJlbGF0ZWQuICBLZWVwIHRoaXMgaW4gbWluZCB3aGVuIGJ1aWxkaW5nIG1vZGVscyBsYXRlci4KCiMjIFJlZ3Jlc3Npb24gYW5hbHlzZXMgdnMgb3V0Y29tZQoKTm93IGV4YW1pbmUgYSBtb3JlIGxpbWl0ZWQgc2V0IG9mIGxpa2VseSBpbnRlcmVzdGluZyBmYWN0b3JzLgoKISFBbiBpbXBvcnRhbnQgbm90ZTogMjAyNDA4ISEKCkluIHRoZSBmb2xsb3dpbmcgYmxvY2sgSSBjaGFuZ2VkIHRoZSBpbnB1dCBmcm9tIHRoZSBmdWxsIG1lcmdlZApkZW1vZ3JhcGhpY3MgYnkgc2FtcGxlIChlLmcuIHRoZXJlIGFyZSBtdWx0aXBsZSByb3dzIGZvciBlYWNoIHBlcnNvbgpjb21pbmcgZnJvbSB0aGUgY29tYmluYXRpb24gb2YgbXVsdGlwbGUgdmlzaXRzL2NlbGx0eXBlcyksIHRvIHRoZSBvbmUKcm93L3BlcnNvbiBmb3VuZCBpbiB0aGUgZGVtb2dyYXBoaWNzIGRhdGEuCgpJbiBhZGRpdGlvbiwgaW4gbXkgaW5pdGlhbCBpbXBsZW1lbnRhdGlvbiwgSSBkaWQgYWxsIGFuYWx5c2VzIHVzaW5nCmxpbmVhciByZWdyZXNzaW9uOyBOZWFsIGtpbmRseSBwb2ludGVkIG91dCB0aGlzIGlzIG5vdCBvcHRpbWFsLgoKRmluYWxseSwgaXQgaXMgcHJvYmFibHkgcHJldHR5IG9idmlvdXMgdGhhdCB0aGlzIGlzIG15IGZpcnN0IGZvcmF5CmludG8gdGhlIHVzYWdlIG9mIHJlZ3Jlc3Npb24gYW5hbHlzZXMgdmlzIGEgdmlzIGNvbXBhcmluZyB2YXJpb3VzCm1ldGFkYXRhIGZhY3RvcnMgYW5kIGVzdGltYXRpbmcgdGhlaXIgc2lnbmlmaWNhbmNlIHdpdGggcmVzcGVjdCB0byBvdXIKb3V0Y29tZSB2YXJpYWJsZS4gIFRodXMsIEkga2luZCBvZiBmb29sIGFyb3VuZCBpbiBzb21lIG9mIHRoZQpmb2xsb3dpbmcgYmxvY2tzLgoKYGBge3J9CnJlZ3Jlc3Npb25fcXVlcmllcyA8LSBjKCJUaGVyYXBldXRpY19PdXRjb21lX0ZpbmFsIiwgIldlaWdodCIsICJTZXgiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2xpbmljIiwgIkV0aG5pY2l0eSIsICJBZ2UiKQpyZWdyZXNzaW9uX2RmIDwtIGRlbW9ncmFwaGljc19maWx0ZXJlZFssIHJlZ3Jlc3Npb25fcXVlcmllc10KcmVncmVzc2lvbl9udW1lcmljIDwtIHJlZ3Jlc3Npb25fZGYKZm9yIChmIGluIGNvbG5hbWVzKHJlZ3Jlc3Npb25fbnVtZXJpYykpIHsKICByZWdyZXNzaW9uX251bWVyaWNbW2ZdXSA8LSBhcy5udW1lcmljKGFzLmZhY3RvcihyZWdyZXNzaW9uX251bWVyaWNbW2ZdXSkpCn0KY3Jvc3NfZGYgPC0gcmVncmVzc2lvbl9kZgpjcm9zc19kZltbIlRoZXJhcGV1dGljX091dGNvbWVfRmluYWwiXV0gPC0gTlVMTApjcm9zc19udW1lcmljIDwtIHJlZ3Jlc3Npb25fbnVtZXJpYwpjcm9zc19udW1lcmljW1siVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCJdXSA8LSBOVUxMCgpyZWdyZXNzaW9uX2Nyb3NzIDwtIGNvcnJfY3Jvc3MoY3Jvc3NfZGYsIHR5cGUgPSAxKQpwcChmaWxlID0gImltYWdlcy93ZWlnaHRfc2V4X2NsaW5pY19ldGhuaWNpdHlfYWdlX2ZhY3Rvcl9jcm9zc2Nvci5wZGYiKQpyZWdyZXNzaW9uX2Nyb3NzCmRldi5vZmYoKQpyZWdyZXNzaW9uX2Nyb3NzCmBgYAoKVGhlIGZvbGxvd2luZyBpcyB0aGUgdmVyc2lvbiB3aGljaCB3ZSBiZWxpZXZlIHRvIGJlIHRoZSBtb3N0CmFwcHJvcHJpYXRlIGZvciB0aGUgcmVhZGVyIGluIGEgc3VwcGxlbWVudGFsIH5TMQoKYGBge3J9CnJlZ3Jlc3Npb25fY3Jvc3NfbnVtZXJpYyA8LSBjb3JyX2Nyb3NzKGNyb3NzX251bWVyaWMsIHR5cGUgPSAxKQpwcChmaWxlID0gImZpZ3VyZXMvd2VpZ2h0X3NleF9jbGluaWNfZXRobmljaXR5X2FnZV9udW1lcmljX2Nyb3NzY29yLnN2ZyIpCnJlZ3Jlc3Npb25fY3Jvc3NfbnVtZXJpYwpkZXYub2ZmKCkKcmVncmVzc2lvbl9jcm9zc19udW1lcmljCmBgYAoKIyMjIENvcHkgdGhlc2Ugd2l0aCBvbmx5IHRoZSBUdW1hY28gcGVvcGxlCgpgYGB7cn0KdHVtYWNvX2lkeCA8LSByZWdyZXNzaW9uX251bWVyaWNbWyJDbGluaWMiXV0gPT0gIjIiCnRfcmVncmVzc2lvbl9udW1lcmljIDwtIHJlZ3Jlc3Npb25fbnVtZXJpY1t0dW1hY29faWR4LCBdCnRfcmVncmVzc2lvbl9kZiA8LSByZWdyZXNzaW9uX2RmW3R1bWFjb19pZHgsIF0KYGBgCgpTaW1pbGFybHksIHdoZW4gd2UgbG9vayBvbmx5IGF0IFR1bWFjbywgdGhpcyB3aWxsIGFsc28gYmUgdXNlZCBpbgpmaWd1cmUgflMxCgpgYGB7cn0KdF9yZWdyZXNzaW9uX3F1ZXJpZXMgPC0gYygiV2VpZ2h0IiwgIlNleCIsICJFdGhuaWNpdHkiLCAiQWdlIikKdF9jcm9zc19kZiA8LSB0X3JlZ3Jlc3Npb25fbnVtZXJpY1ssIHRfcmVncmVzc2lvbl9xdWVyaWVzXQp0X3JlZ3Jlc3Npb25fY3Jvc3MgPC0gY29ycl9jcm9zcyh0X2Nyb3NzX2RmKQpwcChmaWxlID0gImZpZ3VyZXMvdHVtYWNvX3dlaWdodF9zZXhfZXRobmljaXR5X2FnZV9udW1lcmljX2Nyb3NzY29yLnN2ZyIpCnRfcmVncmVzc2lvbl9jcm9zcwpkZXYub2ZmKCkKdF9yZWdyZXNzaW9uX2Nyb3NzCmBgYAoKRGlzY3Vzc2lvbiB3aXRoIE1hcmlhIEFkZWxhaWRhIGFuZCBOZWFsOiAyMDI0MDgKClRoZXJlIHdhcyBhIGJyaWVmIGRpc2N1c3Npb24gcmVnYXJkaW5nIGhvdyB3ZSBnZXQgdG8gdGhlIG51bWVyaWMKY29ycmVsYXRpb25zIGluIHRoZSBjcm9zcyBjb3JyZWxhdGlvbiBwbG90LgoKTmFqaWIgd2FudHMgdG8gcXVlcnkgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgaW5kaXZpZHVhbCBmYWN0b3IKdGFibGUgYW5kIHRoZSB2YXJpb3VzIG1peGVkIG1vZGVsIHJlZ3Jlc3Npb24gdmFsdWVzLgoKV2h5IGRvIGxpbmVhciByZWdyZXNzaW9uIHZzLiBsb2dpc3RpY2FsIHJlZ3Jlc3Npb24/CgpNdWx0aWxldmVsIHJlZ3Jlc3Npb24gdnMuIG11bHRpcGxlIHJlZ3Jlc3Npb246CgptdWx0aWxldmVsIHdvdWxkIGJlIHVzZWQgd2hlbiB0aGVyZSBpcyBhIG5lc3RlZCBzdHJ1Y3R1cmUgdG8gdGhlCmV4cGVyaW1lbnRhbCBkZXNpZ24uCgptdWx0aXBsZSByZWdyZXNzaW9uOiBhcHBseWluZyBtdWx0aXBsZSBmYWN0b3JzIHRvIHRoZSByZWdyZXNzaW9uLgoKU2F2ZSBjb25mdXNpb24gYnkgZXhwbGljaXRseSBzdGF0aW5nIG11bHRpLXZhcmlhYmxlLiAgRm9yIHRoZSBwdXJwb3NlcwpvZiB0aGlzIGRpc2N1c3Npb24gd2Ugd2lsbCBhdm9pZCBhbnkgbXVsdGlsZXZlbCByZWdyZXNzaW9uIGJlY2F1c2Ugb3VyCmV4cGVyaW1lbnRhbCBkZXNpZ24gaXNuJ3QgY3Jhenl0b3duLgoKIlRoZSBtYWluIHB1enpsZSI6IEhvdyBkaWQgc2V4IGFwcGVhciBhcyBhIHN0cm9uZyBlZmZlY3QgaW4gdGhlCnJlZ3Jlc3Npb24gd2hlbiB3ZSBwZXJmb3JtZWQgdGhlIHdpbGNveCB0ZXN0PyAgSXQgbWF5IGJlIHRoYXQgdGhlCm1vZGVsIHVzZWQgaXMgaW5hcHByb3ByaWF0ZS4KCk5hamliIHF1ZXJ5OiB3aGVuIGlzIGEgbWl4ZWQgZWZmZWN0IG1vZGVsIGFwcHJvcHJpYXRlPyAgbG1lNCBhbmQKbXVsdGlsZXZlbCBhcmUgbW9yZSBjbG9zZWx5IHJlbGF0ZWQgYW5kIHVzZWQgd2hlbiB0aGVyZSBhcmUgYm90aCBmaXhlZAphbmQgcmFuZG9tIGVmZmVjdHMgaW4gdGhlIG1vZGVsLiAgSXQgaXMgbGlrZWx5IHRoYXQgaWYgYSBtdWx0aWxldmVsCm1vZGVsIGlzIG5vdCBhcHByb3ByaWF0ZSwgdGhlbiBhIG1peGVkIGVmZmVjdCBpcyBhbHNvIG5vdCBhcHByb3ByaWF0ZQooZS5nLiBkb24ndCB1c2UgbG1lci9sbWU0KS4KCmBgYHtyfQpyZWdyZXNzaW9uX3Rlc3RzIDwtIGMoIkFnZSIsICJDbGluaWMiLCAiRXRobmljaXR5IiwgIlNleCIsICJXZWlnaHQiKQpsbV9yZWdyZXNzaW9uX2RlbW9ncmFwaGljcyA8LSBleHRyYWN0X2xpbmVhcl9yZWdyZXNzaW9uKAogIHJlZ3Jlc3Npb25fbnVtZXJpYywgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsIGZhY3RvcnMgPSByZWdyZXNzaW9uX3Rlc3RzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvbnVtZXJpY19kZW1vZ3JhcGhpY3NfcmVncmVzc2lvbl9maW5hbF9zZXhfY2xpbmljX2V0aG5pY2l0eV9hZ2Utdnt2ZXJ9Lnhsc3giKSkKcHAoZmlsZSA9ICJmaWd1cmVzL2RlbW9ncmFwaGljc19vbmx5X2xpbmVhcl9yZWdyZXNzaW9uLnN2ZyIpCmxtX3JlZ3Jlc3Npb25fZGVtb2dyYXBoaWNzW1siZm9yZXN0Il1dCmRldi5vZmYoKQpsbV9yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbImZvcmVzdCJdXQpsbV9yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbInN1bW1hcnkiXV0KYGBgCgpUaGUgZm9sbG93aW5nIHdpbGwgYmUgdXNlZCBhcyBzdXBwbGVtZW50YWwgZmlndXJlcyBhcyB3ZWxsLCBwcm92aWRpbmcKYSBkZWxpbmVhdGlvbiBiZXR3ZWVuIGEgbXVsdGktdmFyaWFibGUgbG9naXN0aWMgcmVncmVzc2lvbiBhbmQKbXVsdGlwbGUgc2luZ2xlIHZhcmlhYmxlIHJlZ3Jlc3Npb25zLgoKYGBge3J9CmxvZ19yZWdyZXNzaW9uX2RlbW9ncmFwaGljcyA8LSBleHRyYWN0X2xvZ2lzdGljX3JlZ3Jlc3Npb24oCiAgcmVncmVzc2lvbl9kZiwgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsIGZhY3RvcnMgPSByZWdyZXNzaW9uX3Rlc3RzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvdGNfbXVsdGl2YXJpYWJsZV9sb2dpc3RpY19yZWdyZXNzaW9uLXZ7dmVyfS54bHN4IikpCnBwKGZpbGUgPSBnbHVlKCJmaWd1cmVzL3RjX211bHRpdmFyaWFibGVfbG9naXN0aWNfcmVncmVzc2lvbi12e3Zlcn0uc3ZnIikpCmxvZ19yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbImZvcmVzdCJdXQpkZXYub2ZmKCkKbG9nX3JlZ3Jlc3Npb25fZGVtb2dyYXBoaWNzW1siZm9yZXN0Il1dCmxvZ19yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbInN1bW1hcnkiXV0KCnRjX2xvZ19pdGVyYXRpdmVfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3MgPC0gaXRlcmF0ZV9sb2dpc3RpY19yZWdyZXNzaW9uKAogIHJlZ3Jlc3Npb25fZGYsIHF1ZXJ5ID0gIlRoZXJhcGV1dGljX091dGNvbWVfRmluYWwiLCBmYWN0b3JzID0gcmVncmVzc2lvbl90ZXN0cywKICBleGNlbCA9IGdsdWUoImV4Y2VsL3RjX3NpbXBsZV9sb2dpc3RpY19yZWdyZXNzaW9uLnhsc3giKSkKcHAoZmlsZSA9IGdsdWUoImZpZ3VyZXMvdGNfc2ltcGxlX2xvZ2lzdGljX3JlZ3Jlc3Npb24tdnt2ZXJ9LnN2ZyIpKQp0Y19sb2dfaXRlcmF0aXZlX3JlZ3Jlc3Npb25fZGVtb2dyYXBoaWNzW1siZm9yZXN0Il1dCmRldi5vZmYoKQp0Y19sb2dfaXRlcmF0aXZlX3JlZ3Jlc3Npb25fZGVtb2dyYXBoaWNzW1siZm9yZXN0Il1dCnRjX2xvZ19pdGVyYXRpdmVfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3NbWyJzdW1tYXJ5Il1dCmBgYAoKRGlzY3Vzc2lvbiBvZiByZWdyZXNzaW9uIHdpdGggTmVhbDoKClRoZSBjcmVhdGlvbiBvZiBjb3JyZWN0IG1vZGVscywgdGhlIGZvcmVzdCBwbG90cyBhYm92ZSB3ZXJlIGNyZWF0ZWQKZnJvbSBhIG1vZGVsIHRoYXQgbG9va3MgbGlrZSB+IDAgKyBhZ2UgKyBzZXggKyBjbGluaWMgKyB3aGF0ZXZlci4uLgpOZWFsIGlzIGJ1aWxkaW5nIChJIHRoaW5rKSB0b3dhcmQgYSBjb25jbHVzaW9uIHdoaWNoIHNheXMgdGhhdCBzb21lIG9mCnRoZXNlIGZhY3RvcnMgYXJlIGNvbmZvdW5kZWQgYW5kIG1heSBuZWVkIHRvIGJlIHNlcGFyYXRlZC4KCnJ1bGUgb2YgdGVuOiBmb3IgZWFjaCB2YXJpYWJsZSBpbiBhIGxvZ2lzdGljIHJlZ3Jlc3Npb24gb3Igc3Vydml2YWwKYW5hbHlzaXMsIG9uZSB3YW50cyB0byBoYXZlIDEwIG1vcmUgZW50cmllcyBpbiB0aGUgaW5wdXQgZGF0YS4gIFRodXMKd2UgaWRlYWxseSB3b3VsZCBoYXZlIDUwIGN1cmVzIGFuZCA1MCBmYWlscyBpbiBvcmRlciB0byBoYXZlIHRoaXMgbWFueQpmYWN0b3JzIGluIHRoZSBtb2RlbC4gIEluIHRoaXMgZGF0YSB3ZSBvbmx5IGhhdmUgfiAzMCBzZXBhcmF0ZSBwZW9wbGUsCnNvIHRoaXMgaXMgbm90IHRlbmFibGUuCgpJIHRoaW5rIHRoZXJlZm9yZSB0aGUgbW9zdCBsaWtlbHkgdGhpbmcgdG8gYnVpbGQgaW4gYSBwbG90IGxpa2UgdGhpcwpmb3Jlc3QgcGxvdCB3b3VsZCBiZSAxIHJvdyBlYWNoIHZhcmlhYmxlIHVzaW5nIGl0cyByZXN1bHQgZnJvbSBhIHggfiB5CmFsb25lLgoKIyMjIFJlcGVhdCB3aXRoIG9ubHkgVHVtYWNvCgpgYGB7cn0KdF9yZWdyZXNzaW9uX3Rlc3RzIDwtIGMoIkFnZSIsICJFdGhuaWNpdHkiLCAiU2V4IiwgIldlaWdodCIpCnRfbG1fcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3MgPC0gZXh0cmFjdF9saW5lYXJfcmVncmVzc2lvbigKICB0X3JlZ3Jlc3Npb25fbnVtZXJpYywgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsIGZhY3RvcnMgPSB0X3JlZ3Jlc3Npb25fdGVzdHMsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9udW1lcmljX2RlbW9ncmFwaGljc19yZWdyZXNzaW9uX3R1bWFjb19maW5hbF9zZXhfZXRobmljaXR5X2FnZS12e3Zlcn0ueGxzeCIpKQpwcChmaWxlID0gImltYWdlcy9kZW1vZ3JhcGhpY3Nfb25seV90dW1hY29fbGluZWFyX3JlZ3Jlc3Npb24uc3ZnIikKdF9sbV9yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbImZvcmVzdCJdXQpkZXYub2ZmKCkKdF9sbV9yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbImZvcmVzdCJdXQp0X2xtX3JlZ3Jlc3Npb25fZGVtb2dyYXBoaWNzW1sic3VtbWFyeSJdXQpgYGAKCk5vdyByZXBlYXQgd2l0aCBvbmx5IFR1bWFjbywgdGhpcyBzaG91bGQgYWxzbyBiZSBhIHBhcnQgb2YgYQpzdXBwbGVtZW50YWwgRmlndXJlLgoKYGBge3J9CnRfbG9nX3JlZ3Jlc3Npb25fZGVtb2dyYXBoaWNzIDwtIGV4dHJhY3RfbG9naXN0aWNfcmVncmVzc2lvbigKICB0X3JlZ3Jlc3Npb25fZGYsIHF1ZXJ5ID0gIlRoZXJhcGV1dGljX091dGNvbWVfRmluYWwiLCBmYWN0b3JzID0gdF9yZWdyZXNzaW9uX3Rlc3RzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvdF9tdWx0aXZhcmlhYmxlX2xvZ2lzdGljX3JlZ3Jlc3Npb24tdnt2ZXJ9Lnhsc3giKSkKcHAoZmlsZSA9IGdsdWUoImZpZ3VyZXMvdF9tdWx0aXZhcmlhYmxlX2xvZ2lzdGljX3JlZ3Jlc3Npb24tdnt2ZXJ9LnN2ZyIpKQp0X2xvZ19yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbImZvcmVzdCJdXQpkZXYub2ZmKCkKdF9sb2dfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3NbWyJmb3Jlc3QiXV0KdF9sb2dfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3NbWyJzdW1tYXJ5Il1dCgp0X2xvZ19pdGVyYXRpdmVfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3MgPC0gaXRlcmF0ZV9sb2dpc3RpY19yZWdyZXNzaW9uKAogIHRfcmVncmVzc2lvbl9kZiwgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsIGZhY3RvcnMgPSB0X3JlZ3Jlc3Npb25fdGVzdHMsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC90X3NpbXBsZV9sb2dpc3RpY19yZWdyZXNzaW9uLXZ7dmVyfS54bHN4IikpCnBwKGZpbGUgPSBnbHVlKCJmaWd1cmVzL3Rfc2ltcGxlX2xvZ2lzdGljX3JlZ3Jlc3Npb24tdnt2ZXJ9LnN2ZyIpKQp0X2xvZ19pdGVyYXRpdmVfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3NbWyJmb3Jlc3QiXV0KZGV2Lm9mZigpCnRfbG9nX2l0ZXJhdGl2ZV9yZWdyZXNzaW9uX2RlbW9ncmFwaGljc1tbImZvcmVzdCJdXQp0X2xvZ19pdGVyYXRpdmVfcmVncmVzc2lvbl9kZW1vZ3JhcGhpY3NbWyJzdW1tYXJ5Il1dCmBgYAoKSWYgd2UgZGVjaWRlIHRvIGFkZCB0aGluZ3MgbGlrZSB0eXBlb2ZjZWxscy92aXNpdG51bWJlci9ldGMgdG8gdGhlCmFib3ZlLCB0aGVuIHdlIHdpbGwgYWJzb2x1dGVseSBuZWVkIHRvIHVzZSBtdWx0aWxldmVsIHJlZ3Jlc3Npb24gYW5kCnVzZSB0aGUgZnVsbCBjb21iaW5lZCBtZXRhZGF0YSBvZiB0aGUgc2FtcGxlIHNoZWV0IGFuZCBkZW1vZ3JhcGhpY3MKY29tYmluZWQuCgpgYGB7cn0Kd2FudGVkX3F1ZXJpZXMgPC0gYygiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsICJzZXgiLCAiY2xpbmljIiwgIkV0aG5pY2l0eSIsICJBZ2UiKQpmdWxsX21ldGEgPC0gcERhdGEodGNfdmFsaWQpCmZ1bGxfbWV0YV9udW1lcmljIDwtIGZ1bGxfbWV0YQpmb3IgKGYgaW4gd2FudGVkX3F1ZXJpZXMpIHsKICBmdWxsX21ldGFfbnVtZXJpY1tbZl1dIDwtIGFzLm51bWVyaWMoYXMuZmFjdG9yKGZ1bGxfbWV0YV9udW1lcmljW1tmXV0pKQp9Cgpjb3JoZWF0IDwtIGdnc3RhdHNwbG90OjpnZ2NvcnJtYXQoZnVsbF9tZXRhX251bWVyaWMsIGNvci52YXJzID0gd2FudGVkX3F1ZXJpZXMpCnBwKGZpbGUgPSAiaW1hZ2VzL3R5cGVfZG9ub3JfZmluYWxfdmlzaXRfc2V4X2NsaW5pY19ldG5pYV9hZ2VfY29yaGVhdC5wZGYiKQpjb3JoZWF0CmRldi5vZmYoKQpjb3JoZWF0CmBgYAoKIyMjIFJlcGVhdCB1c2luZyBhIGxvZ2lzdGljYWwgbW9kZWwKCkluIHRoZSBwcmV2aW91cyBibG9jaywgdGhlIGZ1bmN0aW9uIGV4dHJhY3Rfc3RlcHdpc2VfcmVncmVzc2lvbigpIHVzZXMKYSBsaW5lYXIgbW9kZWwgdG8gZXh0cmFjdCB0aGUgZi9yIHZhbHVlcyB1c2VkIGZvciB0aGUgZm9yZXN0IHBsb3QgYW5kCnBlcmZvcm1zIGEgc2VyaWVzIChvciBvbmUpIHN0ZXB3aXNlIHJlZ3Jlc3Npb24uICBJbiB0aGUgZm9sbG93aW5nIEkKd2lsbCByZXBlYXQgdGhhdCBwcm9jZXNzIHVzaW5nIGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbC4KCkkgYmV0IEkgd3JvdGUgaXQgZG93biBzb21ld2hlcmUgYWJvdmUsIGJ1dCB3dGYgaXMgdXAgd2l0aCB0aGUgcHJlZml4CnRkZnZzY2VhPwoKQWxzbywgaXQgbWF5IGJlIGJlY2F1c2UgSSBoYXZlIGJlZW4gbWVzc2luZyBhcm91bmQgd2l0aCB3YW50ZWRfbXRyeCwKYnV0IGl0IHNob3VsZCBiZSBhIHNldCBvZiBmYWN0b3JzLCBub3cgbnVtZXJpYy4KCmBgYHtyfQojIyBBbHNvLCB3ZSBhcmUgZXhjbHVkaW5nIGRvbm9yCnRlc3RfZmFjdG9ycyA8LSBjKCJ0eXBlb2ZjZWxscyIsICJ2aXNpdG51bWJlciIsICJTZXgiLCAiY2xpbmljIiwgIkV0aG5pY2l0eSIsICJBZ2UiKQpsb2dpdF9yZWdyZXNzaW9uX3Rlc3QgPC0gZXh0cmFjdF9sb2dpc3RpY19yZWdyZXNzaW9uKHBEYXRhKHRjX2NsaW5pY2FsX25vYmlvcCksIHF1ZXJ5ID0gImZpbmFsb3V0Y29tZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9ycyA9IHRlc3RfZmFjdG9ycykKCmxvZ2l0X3JlZ3Jlc3Npb25fdGVzdFtbImZvcmVzdCJdXQpsb2dpdF9yZWdyZXNzaW9uX3Rlc3RbWyJzdW1tYXJ5Il1dCmBgYAoKVGhlIGNhcmVmdWwgcmVhZGVyIG1pZ2h0IG5vdGljZSBhbiBvZGQgY2hhbmdlIGluIHRoZSBuZXh0IGJsb2NrOiBJCmNoYW5nZWQgZnJvbSAnVGhlcmFwZXV0aWNfRmluYWxfT3V0Y29tZScgdG8gJ2ZpbmFsb3V0Y29tZScuICBUaGlzIGlzCmJlY2F1c2UgdGhlc2UgdHdvIGRhdGEgc3RydWN0dXJlcyBoYXZlIHNsaWdodGx5IGRpZmZlcmVudCBzb3VyY2VzIGZvcgp0aGUgcGVyLXBlcnNvbiBhbmQvb3IgcGVyLXNhbXBsZSBhbm5vdGF0aW9ucy4gIEluIHRoZSBmaXJzdCBpbnN0YW5jZQooYW5kIGFsbCB0aGUgcHJldmlvdXMgYmxvY2tzKSwgdGhhdCBpbmZvcm1hdGlvbiBpcyBjb21pbmcgZnJvbSB0aGUKZGVtb2dyYXBoaWNzIHdvcmtzaGVldCBwcm92aWRlZCBieSBNYXJpYSBBZGVsYWlkYS4gIEluIHRoZSBzZWNvbmQKaW5zdGFuY2UgKHRoZSBmb2xsb3dpbmcgYmxvY2spLCBpdCBpcyBjb21pbmcgZnJvbSB0aGUgaW5kaXZpZHVhbApzYW1wbGUgc2hlZXQuICBUaGUgZXh0cmVtZWx5IGNhcmVmdWwgcmVhZGVyIHdvdWxkIGFsc28gbm90ZSB0aGF0IHRoZXJlCmlzIGEgc2VyaWVzIG9mIGJsb2NrcyBpbiB0aGUgZGF0YSBzdHJ1Y3R1cmVzIHdvcmtzaGVldCB3aGljaCBzZWVrcyB0bwplbnN1cmUgdGhhdCB0aGVzZSB0d28gZGF0YSBzb3VyY2VzIGFncmVlIHdpdGggZWFjaCBvdGhlciwgYW5kIHRoYXQgaXQKdGhyb3dzIGEgdGVzdHRoYXQtYmFzZWQgaGlzc3ktZml0IGlmIHRoZXkgZG8gbm90LgoKYGBge3J9CnRlc3RfcXVlcmllcyA8LSBjKCJjbGluaWMiLCAiU2V4IiwgIkV0aG5pY2l0eSIsICJBZ2UiLCAiZmluYWxvdXRjb21lIikKdGNfcmVncmVzc2lvbl9udW1lcmljIDwtIHBEYXRhKHRjX2NsaW5pY2FsX25vYmlvcClbLCB0ZXN0X3F1ZXJpZXNdCm51bWVyaWNfbXRyeCA8LSBwRGF0YSh0X2NsaW5pY2FsX25vYmlvcClbLCB0ZXN0X3F1ZXJpZXNdCmZvciAoZiBpbiBjb2xuYW1lcyhudW1lcmljX210cngpKSB7CiAgdGNfcmVncmVzc2lvbl9udW1lcmljW1tmXV0gPC0gYXMubnVtZXJpYyh0Y19yZWdyZXNzaW9uX251bWVyaWNbW2ZdXSkKICBudW1lcmljX210cnhbW2ZdXSA8LSBhcy5udW1lcmljKG51bWVyaWNfbXRyeFtbZl1dKQp9Cgpjb3JoZWF0IDwtIGdnc3RhdHNwbG90OjpnZ2NvcnJtYXQobnVtZXJpY19tdHJ4LCBsYWJlbCA9IFRSVUUsIGNvci52YXJzID0gdGVzdF9xdWVyaWVzKQpwcChmaWxlID0gImltYWdlcy9jb3JoZWF0X3R1bWFjb19jYWxpLnBuZyIpCmNvcmhlYXQKZGV2Lm9mZigpCmNvcmhlYXQKYGBgCgpUaGlzIGNvcnJlbGF0aW9uIGhlYXRtYXAgdGVsbHMgdXMgdGhhdCBpdCBpcyBhIGJhZCBpZGVhIHRvCnNpbXVsdGFuZW91c2x5IGNvbnNpZGVyIEFnZSBhbmQgRXRobmljaXR5IGluIGFueSBtb2RlbHMgd2UgY3JlYXRlIHRvCmV4cHJlc3MgdGhlIGRhdGEuICBJdCBtYXkgYmUgcG9zc2libGUgdG8gbWFrZSBhIGd1ZXNzIGFib3V0IHdoaWNoIGlzCm1vcmUgYXBwcm9wcmlhdGUgdG8gY29uc2lkZXIgYnkgcGVyZm9ybWluZyBhIHJlZ3Jlc3Npb24gdGFibGUgb2YgZWFjaAppbmRpdmlkdWFsbHk/CgpMZXQgdXMgdHJ5IG9uY2Ugd2l0aCBhbGwgZmFjdG9ycyBpbmNsdWRlZCwgdGhlbiByZW1vdmUgRXRobmljaXR5IGFuZApBZ2Ugc2VxdWVudGlhbGx5LiAgSXQgbWlnaHQgYmUgd2lzZXIgdG8gdXNlIHRoZSBxdWFydGlsZSdkIHZlcnNpb24gb2YKYWdlPwoKRnVuZGFtZW50YWxseSwgdGhpcyBqdXN0IHJlcGVhdHMgd2hhdCB3ZSBqdXN0IHNhdywgYnV0IG1ha2VzIGNsZWFyZXIKdGhhdCBBZ2UgYW5kIEV0aG5pY2l0eSBhcmUgcHJvYmxlbWF0aWMgaWYgcGxhY2VkIGluIHRoZSBzYW1lIG1vZGVsLgpNeSByZWFzb25pbmc6IFRoZXJlc2Egc3VnZ2VzdGVkIHRoYXQgYW55IGNvcnJlbGF0aW9uID49IDAuNjUgaXMKcHJvYmxlbWF0aWMuCgpUaGUgZm9sbG93aW5nIGJsb2NrIHdhcyBvcmlnaW5hbGx5IGEgYml0IHdyb25nLWhlYWRlZCBiZWNhdXNlIGl0IHdhcwpwZXJmb3JtZWQgYmVmb3JlIHdlIHJlYWxpemVkIHRoYXQgd2Ugd2VyZSBmZWVkaW5nIHRoZSBsbSB0aGUgZnVsbApleHBlcmltZW50YWwgZGVzaWduIHdpdGggbXVsdGlwbGUgZW50cmllcyBwZXIgcGVyc29uLgoKSSBtb2RpZmllZCBpdCB0byB1c2UgdGhlIG1vcmUgYXBwcm9wcmlhdGUgZGF0YSBhbmQgZGVjaWRlZCB0byBsZWF2ZSBpdApoZXJlIGFzIGEgcmVtaW5kZXIuCgpgYGB7cn0KY3NlYV9leHRyYWN0ZWRfcmVncmVzc2lvbiA8LSBleHRyYWN0X2xpbmVhcl9yZWdyZXNzaW9uKAogIHRjX3JlZ3Jlc3Npb25fbnVtZXJpYywgcXVlcnkgPSAiZmluYWxvdXRjb21lIiwKICBmYWN0b3JzID0gYygiY2xpbmljIiwgIlNleCIsICJFdGhuaWNpdHkiLCAiQWdlIiksIHNjYWxlID0gRkFMU0UsCiAgZXhjZWwgPSAiZXhjZWwvdGNfcmVncmVzc2lvbl90YWJsZV9jc2VhLnhsc3giKQpwcChmaWxlID0gImltYWdlcy90Y19yZWdyZXNzaW9uX2NzZWEucG5nIikKY3NlYV9leHRyYWN0ZWRfcmVncmVzc2lvbltbImZvcmVzdCJdXQpkZXYub2ZmKCkKY3NlYV9leHRyYWN0ZWRfcmVncmVzc2lvbltbImZvcmVzdCJdXQpjc2VhX2V4dHJhY3RlZF9yZWdyZXNzaW9uW1sic3VtbWFyeSJdXQoKY3NhX2V4dHJhY3RlZF9yZWdyZXNzaW9uIDwtIGV4dHJhY3RfbGluZWFyX3JlZ3Jlc3Npb24oCiAgdGNfcmVncmVzc2lvbl9udW1lcmljLCBxdWVyeSA9ICJmaW5hbG91dGNvbWUiLAogIGZhY3RvcnMgPSBjKCJjbGluaWMiLCAiU2V4IiwgIkFnZSIpLAogIGV4Y2VsID0gImV4Y2VsL3RjX3JlZ3Jlc3Npb25fdGFibGVfY3NhLnhsc3giKQpwcChmaWxlID0gImltYWdlcy90Y19yZWdyZXNzaW9uX2NzYS5wbmciKQpjc2FfZXh0cmFjdGVkX3JlZ3Jlc3Npb25bWyJmb3Jlc3QiXV0KZGV2Lm9mZigpCmNzYV9leHRyYWN0ZWRfcmVncmVzc2lvbltbImZvcmVzdCJdXQpjc2FfZXh0cmFjdGVkX3JlZ3Jlc3Npb25bWyJzdW1tYXJ5Il1dCgpjc2VfZXh0cmFjdGVkX3JlZ3Jlc3Npb24gPC0gZXh0cmFjdF9saW5lYXJfcmVncmVzc2lvbigKICB0Y19yZWdyZXNzaW9uX251bWVyaWMsIHF1ZXJ5ID0gImZpbmFsb3V0Y29tZSIsCiAgZmFjdG9ycyA9IGMoImNsaW5pYyIsICJTZXgiLCAiRXRobmljaXR5IiksCiAgZXhjZWwgPSAiZXhjZWwvdGNfcmVncmVzc2lvbl90YWJsZV9jc2UueGxzeCIpCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX3JlZ3Jlc3Npb25fY3NlLnBuZyIpCmNzZV9leHRyYWN0ZWRfcmVncmVzc2lvbltbImZvcmVzdCJdXQpkZXYub2ZmKCkKY3NlX2V4dHJhY3RlZF9yZWdyZXNzaW9uW1siZm9yZXN0Il1dCmNzZV9leHRyYWN0ZWRfcmVncmVzc2lvbltbInN1bW1hcnkiXV0KYGBgCgojIyBSZXBlYXQgd2l0aCBvbmx5IFR1bWFjbwoKVGh1cywgY2xpbmljIGNhbm5vdCBiZSBpbiB0aGUgbW9kZWwuICBJbiBhZGRpdGlvbiBJIHdpbGwgcmVtb3ZlCmhlaWdodC93ZWlnaHQgYmVjYXVzZSB3ZSBrbm93IGEgcHJpb3JpIGhvdyB0aGV5IGNvcnJlbGF0ZS4KCmBgYHtyfQppbml0aWFsX3F1ZXJpZXMgPC0gYygiU2V4IiwgIkV0aG5pY2l0eSIsICJBZ2UiLAogICAgICAgICAgICAgICAgICAgICAiRXZvbHV0aW9uX1RpbWUiLCAiTnVtX0FjdGl2ZV9MZXNpb25zIiwKICAgICAgICAgICAgICAgICAgICAgIlYyX05ld19MZXNpb25zIiwgIlYzX05ld19MZXNpb25zIiwKICAgICAgICAgICAgICAgICAgICAgIkFkaGVyZW5jZSIsICJmaW5hbG91dGNvbWUiKQp0X2luaXRpYWxfbXRyeCA8LSBwRGF0YSh0X2NsaW5pY2FsX25vYmlvcClbLCBpbml0aWFsX3F1ZXJpZXNdCgp0dW1hY29fY3Jvc3MgPC0gY29ycl9jcm9zcyh0X2luaXRpYWxfbXRyeCkKcHAoZmlsZSA9ICJpbWFnZXMvdHVtYWNvX2Nyb3NzY29yLnBuZyIpCnR1bWFjb19jcm9zcwpkZXYub2ZmKCkKdHVtYWNvX2Nyb3NzCmBgYAoKT25jZSBhZ2FpbiwgbGV0IHVzIGNvbnNpZGVyIGEgc21hbGxlciBzZXQgdG8gaWRlbnRpZnkgZmFjdG9ycyB0aGF0CnNob3VsZCBub3QgZ28gaW50byBhIG1vZGVsIHRlc3QgdG9nZXRoZXIsIHdlIGFzc3VtZSB0aGF0IG9uY2UgYWdhaW4KdGhpcyB3aWxsIHByb3ZlIHRvIGJlIEV0aG5pY2l0eSBhbmQgQWdlLgoKYGBge3J9CnRlc3RfcXVlcmllcyA8LSBjKCJTZXgiLCAiRXRobmljaXR5IiwgIkFnZSIsICJmaW5hbG91dGNvbWUiKQp0X251bWVyaWNfbXRyeCA8LSB0X2luaXRpYWxfbXRyeFssIHRlc3RfcXVlcmllc10KZm9yIChmIGluIGNvbG5hbWVzKHRfbnVtZXJpY19tdHJ4KSkgewogIHRfbnVtZXJpY19tdHJ4W1tmXV0gPC0gYXMubnVtZXJpYyh0X251bWVyaWNfbXRyeFtbZl1dKQp9Cgpjb3JoZWF0IDwtIGdnc3RhdHNwbG90OjpnZ2NvcnJtYXQodF9udW1lcmljX210cngsIGxhYmVsID0gVFJVRSwgY29yLnZhcnMgPSB0ZXN0X3F1ZXJpZXMpCmNvcmhlYXQKYGBgCgpJdCB0dXJucyBvdXQgdGhleSBhcmUgZXZlbiBtb3JlIHRpZ2h0bHkgY29ycmVsYXRlZCBpbiB0aGlzIHN1YnNldCB0aGFuIGluCnRoZSBmdWxsIGRhdGFzZXQuCgojIyBBIHNlcmllcyBvZiBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbHMKCkdpdmVuIHRoZSBhYm92ZSwgSSBrbm93IHRoYXQgSSBzaG91bGQgbm90IGluY2x1ZGUgc29tZSBncm91cHMgb2YKZmFjdG9ycyBpbiBhIG1vZGVsIHRvZ2V0aGVyLCBidXQgSSB3YW50IHRvIGdldCBhIGZlZWwgZm9yIHdoaWNoCmZhY3RvciBjb21iaW5hdGlvbnMgYXJlIG1vc3QvbGVhc3QgaW5mb3JtYXRpdmUgd2l0aCByZXNwZWN0IHRvIGZpbmFsCm91dGNvbWUuCgpgYGB7cn0KdF9zZWFfZXh0cmFjdGVkX3JlZ3Jlc3Npb24gPC0gZXh0cmFjdF9saW5lYXJfcmVncmVzc2lvbigKICB0X3JlZ3Jlc3Npb25fbnVtZXJpYywgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsCiAgZmFjdG9ycyA9IGMoIlNleCIsICJFdGhuaWNpdHkiLCAiQWdlIiksCiAgZXhjZWwgPSAiZXhjZWwvdF9yZWdyZXNzaW9uX3RhYmxlX3Rfc2VhLnhsc3giKQpwcChmaWxlID0gImltYWdlcy90Y19yZWdyZXNzaW9uX3Rfc2VhLnBuZyIpCnRfc2VhX2V4dHJhY3RlZF9yZWdyZXNzaW9uW1siZm9yZXN0Il1dCmRldi5vZmYoKQp0X3NlYV9leHRyYWN0ZWRfcmVncmVzc2lvbltbImZvcmVzdCJdXQp0X3NlYV9leHRyYWN0ZWRfcmVncmVzc2lvbltbInN1bW1hcnkiXV0KCnRfc2FfZXh0cmFjdGVkX3JlZ3Jlc3Npb24gPC0gZXh0cmFjdF9saW5lYXJfcmVncmVzc2lvbigKICB0X3JlZ3Jlc3Npb25fbnVtZXJpYywgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsCiAgZmFjdG9ycyA9IGMoIlNleCIsICJBZ2UiKSwKICBleGNlbCA9ICJleGNlbC90X3JlZ3Jlc3Npb25fdGFibGVfdF9zYS54bHN4IikKcHAoZmlsZSA9ICJpbWFnZXMvdF9yZWdyZXNzaW9uX3NhLnBuZyIpCnRfc2FfZXh0cmFjdGVkX3JlZ3Jlc3Npb25bWyJmb3Jlc3QiXV0KZGV2Lm9mZigpCnRfc2FfZXh0cmFjdGVkX3JlZ3Jlc3Npb25bWyJmb3Jlc3QiXV0KdF9zYV9leHRyYWN0ZWRfcmVncmVzc2lvbltbInN1bW1hcnkiXV0KCnRfc2VfZXh0cmFjdGVkX3JlZ3Jlc3Npb24gPC0gZXh0cmFjdF9saW5lYXJfcmVncmVzc2lvbigKICB0X3JlZ3Jlc3Npb25fbnVtZXJpYywgcXVlcnkgPSAiVGhlcmFwZXV0aWNfT3V0Y29tZV9GaW5hbCIsCiAgZmFjdG9ycyA9IGMoIlNleCIsICJFdGhuaWNpdHkiKSwKICBleGNlbCA9ICJleGNlbC90X3JlZ3Jlc3Npb25fdGFibGVfc2UueGxzeCIpCnBwKGZpbGUgPSAiaW1hZ2VzL3RfcmVncmVzc2lvbl9zZS5wbmciKQp0X3NlX2V4dHJhY3RlZF9yZWdyZXNzaW9uW1siZm9yZXN0Il1dCmRldi5vZmYoKQp0X3NlX2V4dHJhY3RlZF9yZWdyZXNzaW9uW1siZm9yZXN0Il1dCnRfc2VfZXh0cmFjdGVkX3JlZ3Jlc3Npb25bWyJzdW1tYXJ5Il1dCmBgYAoKIyBHbG9iYWwgdmlld3Mgb2YgYWxsIGNlbGwgdHlwZXMKCk5vdyB0aGF0IHRob3NlICdnbG9iYWwnIG1ldHJpY3MgYXJlIG91dCBvZiB0aGUgd2F5LCBsZXRzIGxvb2sgYXQgc29tZQpnbG9iYWwgbWV0cmljcyBvZiB0aGUgZGF0YSBmb2xsb3dpbmcgbm9ybWFsaXphdGlvbjsgdGhlIG1vc3QgbGlrZWx5CnBsb3RzIGFyZSBvZiBjb3Vyc2UgUENBIGJ1dCBhbHNvIGEgY291cGxlIG9mIGhlYXRtYXBzLgoKIyMjIEZpZ3VyZSAxCgpPdmVyIHRpbWUgdGhlIHByZWZlcmVuY2UgZm9yIHdoaWNoIHNhbXBsZXMgdG8gaW5jbHVkZSBpbiBhICdnbG9iYWwnClBDQSBoYXMgY2hhbmdlZCwgYXMgd2VsbCBhcyBwcmVmZXJlbmNlcyBmb3IgaG93IHRvIGFycmFuZ2UvbGFiZWwvY29sb3IKdGhlbS4gIFRoZSBmb2xsb3dpbmcgc2hvd3MgYSBjb3VwbGUgb2YgcGVyc3BlY3RpdmVzLgoKYGBge3J9CnRjX3R5cGUgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0Y192YWxpZCwgZmFjdCA9ICJ0eXBlb2ZjZWxscyIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbInR5cGUiXV0pCgp0Y19ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHRjX3R5cGUsIHRyYW5zZm9ybSA9ICJsb2cyIiwgbm9ybSA9ICJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydCA9ICJjcG0iLCBmaWx0ZXIgPSBUUlVFKSkKCnRjX3BjYSA8LSBwbG90X3BjYSh0Y19ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgIHBsb3RfdGl0bGUgPSAiUENBIC0gQ2VsbCB0eXBlIiwgc2l6ZV9jb2x1bW4gPSAidmlzaXRudW1iZXIiKQpwcChmaWxlID0gImZpZ3VyZXMvdGNfcGNhX3NpemVkLnBkZiIpCnRjX3BjYQpkZXYub2ZmKCkKdGNfcGNhCnRjX3BjYSA8LSBwbG90X3BjYSh0Y19ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgcGxvdF90aXRsZSA9ICJQQ0EgLSBDZWxsIHR5cGUiKQpwcChmaWxlID0gImZpZ3VyZXMvdGNfcGNhX25vc2l6ZS5wZGYiKQp0Y19wY2EKZGV2Lm9mZigpCnRjX3BjYQoKd3JpdGUuY3N2KHRjX3BjYVtbInRhYmxlIl1dLCBmaWxlID0gImV4Y2VsL3RjX2Rvbm9yX3BjYV9jb29yZHMuY3N2IikKdGNfY2Zfbm9ybSA8LSBzZXRfZXhwdF9iYXRjaGVzKHRjX25vcm0sIGZhY3QgPSAidmlzaXRudW1iZXIiKQp0Y19jZl9jb3JoZWF0IDwtIHBsb3RfY29yaGVhdCh0Y19jZl9ub3JtLCBwbG90X3RpdGxlID0gIkhlaXJhcmNoaWNhbCBjbHVzdGVyaW5nOgogICAgICAgICBjZWxsIHR5cGVzIikKcHAoZmlsZSA9ICJmaWd1cmVzL3RjX2NmX2NvcmhlYXQuc3ZnIikKdGNfY2ZfY29yaGVhdApkZXYub2ZmKCkKdGNfY2ZfY29yaGVhdAoKdGNfY2ZfZGlzaGVhdCA8LSBwbG90X2Rpc2hlYXQodGNfY2Zfbm9ybSwgcGxvdF90aXRsZSA9ICJIZWlyYXJjaGljYWwgY2x1c3RlcmluZzoKICAgICAgICAgY2VsbCB0eXBlcyIpCnRjX2NmX2Rpc2hlYXQKYGBgCgojIyBGaWd1cmUgMUI6IFRyYW5zY3JpcHRvbWljIHByb2ZpbGVzIG9mIHByaW1hcnkgaW5uYXRlIGNlbGxzCgpBIHBvdGVudGlhbCBmaWd1cmUgbGVnZW5kIGZvciB0aGUgZm9sbG93aW5nIGltYWdlcyBtaWdodCBpbmNsdWRlOgoKVGhlIG9ic2VydmVkIGNvdW50cyBwZXIgZ2VuZSBmb3IgYWxsIG9mIHRoZSBjbGluaWNhbCBzYW1wbGVzIHdlcmUKZmlsdGVyZWQsIGxvZyB0cmFuc2Zvcm1lZCwgY3BtIGNvbnZlcnRlZCwgYW5kIHF1YW50aWxlIG5vcm1hbGl6ZWQuClRoZSBjb2xvcnMgd2VyZSBkZWZpbmVkIGJ5IGNlbGwgdHlwZXMgYW5kIHNoYXBlcyBieSBwYXRpZW50IHZpc2l0LgpXaGVuIHRoZSBmaXJzdCB0d28gcHJpbmNpcGxlIGNvbXBvbmVudHMgd2VyZSBwbG90dGVkLCBjbHVzdGVyaW5nIHdhcwpvYnNlcnZlZCBieSBjZWxsIHR5cGUuICBUaGUgYmlvcHN5IHNhbXBsZXMgd2VyZSBzaWduaWZpY2FudGx5CmRpZmZlcmVudCBmcm9tIHRoZSBpbm5hdGUgaW1tdW5lIGNlbGwgdHlwZXMuCgpgYGB7cn0KZmlnMXYyX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodGNfdHlwZSwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpmaWcxdjJfcGNhIDwtIHBsb3RfcGNhKGZpZzF2Ml9ub3JtLCBjaXMgPSBGQUxTRSkKcHAoZmlsZSA9ICJmaWd1cmVzL3RjX3R5cGVfdjIucGRmIikKZmlnMXYyX3BjYQpkZXYub2ZmKCkKZmlnMXYyX3BjYQpgYGAKCiMgQ29tcGFyZSBzYW1wbGVzIGJ5IGNsaW5pYwoKU3BvaWxlciBhbGVydDogIFRoaXMgc2VjdGlvbiB3aWxsIGV2ZW50dWFsbHkgc3VnZ2VzdCBwcmV0dHkgc3Ryb25nbHkKdGhhdCB3ZSB3aWxsIG5vdCBlYXNpbHkgYmUgYWJsZSB0byB1c2UgdGhlIENhbGkgc2FtcGxlcy4gIFRodXMsIGFmdGVyCmZpbmlzaGluZyBpdCwgd2Ugd2lsbCBsaWtlbHkgZXhjbHVkZSB0aG9zZSBzYW1wbGVzLgoKVGFrZSBhIG1vbWVudCB0byB2aWV3IHRoZSBiaW9wc3kgc2FtcGxlcy4gIFdlIHNlcGFyYXRlZCB0aGVtIGJ5IGNsaW5pYwooQ2FsaSBvciBUdW1hY28pLCBhbmQgdGhpcyB2aWV3IG9mIHRoZSBzYW1wbGVzIGlzIHRoZSBvbmx5IG9uZSB3aGljaApkb2VzIG5vdCBzdWdnZXN0IGEgc3Ryb25nIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGNsaW5pY3MuCkhvd2V2ZXIsIGl0IGFsc28gc3VnZ2VzdHMgdGhhdCB0aGUgYmlvcHN5IHNhbXBsZXMgd2lsbCBub3QgcHJvdmUgdmVyeQpoZWxwZnVsLgoKIyMgQmlvcHNpZXMgYnkgY2xpbmljCgpUaGVyZSBhcmUgdG9vIGZldyBiaW9wc3kgc2FtcGxlcyB0byBnZXQgYSBzdHJvbmcgdmlldyBvZiBjdXJlL2ZhaWwuCkluIGFkZGl0aW9uLCB0aGVzZSBhcmUgJ21lc3NpZXInIHRoYW4gYW55IG90aGVyIHNhbXBsZSB0eXBlLiAgQXMgYQpyZXN1bHQsIGl0IGlzIGRpZmZpY3VsdCB0byBkaXNjZXJuIGEgcGF0dGVybiBpbiB0aGVtIHdoaWNoIGhlbHAKZWx1Y2lkYXRlIGN1cmUgdnMuIGZhaWwuICBJZiB3ZSBwbGF5IHdpdGggdGhlIHZhcmlvdXMgcGFyYW1ldGVycyB1c2VkCnRvIHBlcmZvcm0gdGhlIGNvdW50IG1vZGlmaWNhdGlvbiB2aWEgcnV2L3N2YSwgd2UgZ2V0IHNsaWdodGx5CmRpZmZlcmVudCB2aWV3cywgc29tZSBtb3JlIGV2b2NhdGl2ZSB0aGFuIG90aGVyczsgYnV0IHRoZSBmb2xsb3dpbmcgaXMKb3VyIG1vc3QgY2Fub25pY2FsIHZpZXcuCgojIyMgRmlndXJlIDNFOiBCaW9wc2llcwoKYGBge3J9CnRjX2Jpb3BzaWVzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodGNfYmlvcHNpZXMsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQp0Y19iaW9wc2llc19wY2EgPC0gcGxvdF9wY2EodGNfYmlvcHNpZXNfbm9ybSkKdGNfYmlvcHNpZXNfcGNhCnBwKGZpbGUgPSAiZmlndXJlcy90Y19iaW9wc2llc19wY2Euc3ZnIikKdGNfYmlvcHNpZXNfcGNhW1sicGxvdCJdXQpkZXYub2ZmKCkKCnRjX2Jpb3BzaWVzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2Jpb3BzaWVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdGNfYmlvcHNpZXNfbmJfcGNhIDwtIHBsb3RfcGNhKHRjX2Jpb3BzaWVzX25iKQpwcChmaWxlID0gImZpZ3VyZXMvZmlndXJlM0VfYmlvcHNpZXMuc3ZnIikKdGNfYmlvcHNpZXNfbmJfcGNhW1sicGxvdCJdXQpkZXYub2ZmKCkKdGNfYmlvcHNpZXNfbmJfcGNhCmBgYAoKSSB3b3JyeSB0aGF0IHdlIHJlbHkgdG9vIGhlYXZpbHkgb24gUENBLgoKIyMgUGF0aWVudCBSYWNlIGFuZCBjbGluaWM/CgpIb3cgc3Ryb25nIGlzIHRoZSBlZmZlY3Qgb2YgZXRobmljaXR5L2V0aG5pY2l0eStjbGluaWM/ICBJbiB0aGUgd29yc3QKY2FzZSBzY2VuYXJpbywgdGhlc2Ugc3Vycm9nYXRlcyBjb3VsZCBtYWtlIGludGVycHJldGluZyB0aGUgcmVzdWx0cwpwcm9ibGVtYXRpYy4gIFRoZSBmb2xsb3dpbmcgYmxvY2tzIHdpbGwgZXhwbG9yZSB0aGF0IHF1ZXN0aW9uIGEgbGl0dGxlCmFuZCBJIHRoaW5rIGNvbWUgdG8gdGhlIGdlbmVyYWwgY29uY2x1c2lvbiB0aGF0IHJhY2UgYW5kL29yIGNsaW5pYyBhcmUKbm90IHNpZ25pZmljYW50IHByb2JsZW1zLgoKIyMjIEFsbCBzYW1wbGVzLCBib3RoIGNsaW5pY3MKCkNvbXBhcmVkIHRvIHRoZSBjZWxsIHR5cGUgZWZmZWN0LCBjbGluaWMvcmFjZSBpcywgYXMgd2UgYWxyZWFkeSBrbm93LAp1dHRlcmx5IGluc2lnbmlmaWNhbnQuICBUaGUgcXVlc3Rpb24gc3RpbGwgc3RhbmRzLCBob3cgc2lnbmlmaWNhbnQ/ClRoZXJlIGRvZXMgYXBwZWFyIHRvIGJlIGFuIGVmZmVjdCBpbiB0aGUgZGF0YSB3aGljaCBpcyByZWxldmFudCB0bwpyYWNlLiAgSSB0aGluayBpZiB3ZSB3YW50IHRvIGJlIGFibGUgdG8gZXhwbG9yZSB0aGlzIGZ1bGx5LCB3ZSB3b3VsZApuZWVkIG1vcmUgcGVvcGxlLgoKYGBge3J9CmV0bmlhX2V4cHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0Y192YWxpZCwgZmFjdCA9ICJjbGluaWNfZXRuaWEiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19ldG5pYSJdXSkKZXRuaWFfbm9ybSA8LSBub3JtYWxpemVfZXhwdChldG5pYV9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKcGxvdF9wY2EoZXRuaWFfbm9ybSkKCmV0bmlhX25iIDwtIG5vcm1hbGl6ZV9leHB0KGV0bmlhX2V4cHQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYShldG5pYV9uYikKYGBgCgojIyMjIE9ubHkgVHVtYWNvCgpUaGVyZSBpcyBhbiBpbWJhbGFuY2UgaW4gdGhlIGlkZW50aXR5IG9mIHBlb3BsZSB3aG8gYXR0ZW5kZWQgZWFjaApjbGluaWMuICBHaXZlbiB0aGF0IHdlIGFyZSBmb2N1c2luZyBvbiB0aGUgVHVtYWNvIHNhbXBsZXMsIGhlcmUgaXMgdGhlCmRpc3RyaWJ1dGlvbiBvZiByYWNlL2NlbGwgdHlwZToKCmBgYHtyfQp0X2V0bmlhX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9ldG5pYV9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIG5vcm0gPSAicXVhbnQiKQpwbG90X3BjYSh0X2V0bmlhX25vcm0pCgp0X2V0bmlhX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfZXRuaWFfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EodF9ldG5pYV9uYikKYGBgCgojIyMgQmlvcHN5IHNhbXBsZXMsIGJvdGggY2xpbmljcy4KClRoZSBiaW9wc3kgc2FtcGxlcyBhcmUgbWlzc2luZyBwZW9wbGUgb2YgaW5kaWdlbm91cyBvcmlnaW4gd2hvIHdlbnQgdG8KdGhlIFR1bWFjbyBjbGluaWMuCgpgYGB7cn0KdGNfYnBfZWMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0Y19iaW9wc2llcywgZmFjdCA9ICJjbGluaWNfZXRuaWEiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19ldG5pYSJdXSkKZXRuaWFfYnBfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19icF9lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKGV0bmlhX2JwX25vcm0pCmBgYAoKIyMjIyBCaW9wc3kgc2FtcGxlcywgVHVtYWNvLgoKVGhlIGJpb3BzeSBzYW1wbGVzIGFyZSBieSBmYXIgdGhlICdtZXNzaWVzdCwnIHRoYXQgcmVtYWlucyB0cnVlIHdoZW4KY29uc2lkZXJpbmcgdGhlIGV0aG5pY2l0eSBvZiB0aGUgaW5kaXZpZHVhbCBwYXRpZW50cy4KCmBgYHtyfQp0X2JwX2VjIDwtIHNldF9leHB0X2NvbmRpdGlvbnModGNfYmlvcHNpZXMsIGZhY3QgPSAiZXRuaWEiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImV0aG5pY2l0eSJdXSkKdF9ldG5pYV9icF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfYnBfZWMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKHRfZXRuaWFfYnBfbm9ybSkKYGBgCgpJIHRoaW5rIHRoZXJlIGFyZSBub3QgZW5vdWdoIHNhbXBsZXMgdG8gdHJ5IHN2YSB3aXRoIHRoaXMuCgojIyMgRW9zaW5vcGhpbCBzYW1wbGVzLCBib3RoIGNsaW5pY3MuCgpXaGVuIHdlIGFzayB0aGUgc2FtZSBxdWVzdGlvbiBvZiB0aGUgY2xpbmljYWwgY2VsbCB0eXBlcywgaXQgaXMKcG9zc2libGUgdG8gc2VlIG1vcmUgc2FtcGxlcywgYnV0IG5vdCBhIHNpZ25pZmljYW50bHkgY2xlYXJlciB2aWV3IG9mCnRoZSByYWNlIGVmZmVjdCBvbiB0aGUgdHJhbnNjcmlwdGlvbmFsIHByb2ZpbGUuCgpgYGB7cn0KdGNfZW9fZWMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0Y19lb3Npbm9waGlscywgZmFjdCA9ICJjbGluaWNfZXRuaWEiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19ldG5pYSJdXSkKZXRuaWFfZW9fbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19lb19lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKGV0bmlhX2VvX25vcm0pCgpldG5pYV9lb19uYiA8LSBub3JtYWxpemVfZXhwdCh0Y19lb19lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKZXRobmljaXR5X3BjYSA8LSBwbG90X3BjYShldG5pYV9lb19uYikKcHAoZmlsZSA9ICJmaWd1cmVzL2V0aG5pY2l0eV9lb19wY2Euc3ZnIikKZXRobmljaXR5X3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCmV0aG5pY2l0eV9wY2FbWyJwbG90Il1dCmBgYAoKIyMjIyBFb3Npbm9waGlsIHNhbXBsZXMsIFR1bWFjby4KClRoZSBlb3Npbm9waGlscyBhcmUgb3VyIGxlYXN0LWFidW5kYW50IGNlbGwgdHlwZSwgYXMgc3VjaCB0aGUgdmlldyBvZgpldGhuaWNpdHkgdXNpbmcgdGhlbSBpcyBwYXJ0aWN1bGFybHkgcHJvYmxlbWF0aWM7IGJ1dCB3ZSBkbyBhdCBsZWFzdApoYXZlIGEgZmV3IHNhbXBsZXMgZnJvbSBlYWNoIGdyb3VwLiAgV2l0aCB0aGF0IGluIG1pbmQsIHRoZXNlIGFwcGVhcgp0byBzaG93IHNvbWUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBhbW9uZyB0aGUgdGhyZWUgZ3JvdXBzLgoKYGBge3J9CnRfZW9fZWMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X2Vvc2lub3BoaWxzLCBmYWN0ID0gImV0bmlhIikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJldGhuaWNpdHkiXV0pCnRfZXRuaWFfZW9fbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X2VvX2VjLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKcGxvdF9wY2EodF9ldG5pYV9lb19ub3JtKQoKdF9ldG5pYV9lb19uYiA8LSBub3JtYWxpemVfZXhwdCh0X2VvX2VjLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYSh0X2V0bmlhX2VvX25iKQpgYGAKCiMjIyBNb25vY3l0ZSBzYW1wbGVzLCBib3RoIGNsaW5pY3MuCgpJbiBnZW5lcmFsLCB0aGUgbW9ub2N5dGVzIHNob3cgdGhlIHN0cm9uZ2VzdCBkaWZmZXJlbmNlcyBpbiBhbnkKY29tcGFyaXNvbiB3ZSBoYXZlIHBlcmZvcm1lZC4gIFRoaXMgaXMgdHJ1ZSBpbiB0aGUgY29udGV4dCBvZiByYWNlIGFzCndlbGwuICBUaHVzLCBldmVuIGJlZm9yZSBhcHBseWluZyBzdmEsIHdlIHNlZSBzb21lIHNlcGFyYXRpb24gYW1vbmcKdGhlIG1vbm9jeXRlIHNhbXBsZXMgd2l0aCByZXNwZWN0IHRvIGV0aG5pY2l0eS4KCmBgYHtyfQp0Y19tb19lYyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRjX21vbm9jeXRlcywgZmFjdCA9ICJjbGluaWNfZXRuaWEiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19ldG5pYSJdXSkKZXRuaWFfbW9fbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19tb19lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKGV0bmlhX21vX25vcm0pCgpldG5pYV9tb19uYiA8LSBub3JtYWxpemVfZXhwdCh0Y19tb19lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCmV0bmlhX21vX25iX3BjYSA8LSBwbG90X3BjYShldG5pYV9tb19uYikKcHAoZmlsZSA9ICJmaWd1cmVzL2V0bmlhX21vX25iX3BjYS5zdmciKQpldG5pYV9tb19uYl9wY2FbWyJwbG90Il1dCmRldi5vZmYoKQpldG5pYV9tb19uYl9wY2EKYGBgCgojIyMjIE1vbm9jeXRlIHNhbXBsZXMsIFR1bWFjby4KClRoZSBhYmlsaXR5IHRvIHNlZSBzb21lIHNlcGFyYXRpb24gYnkgZXRobmljaXR5IGFtb25nIHRoZSBtb25vY3l0ZQpzYW1wbGVzIHJlbWFpbnMsIGF0IGxlYXN0IHNsaWdodGx5LCB0cnVlIHdoZW4gY29uc2lkZXJpbmcgb25seSB0aGUKVHVtYWNvIHNhbXBsZXMuCgpgYGB7cn0KdF9tb19lYyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRfbW9ub2N5dGVzLCBmYWN0ID0gImV0bmlhIikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJldGhuaWNpdHkiXV0pCnRfZXRuaWFfbW9fbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X21vX2VjLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIG5vcm0gPSAicXVhbnQiKQpwbG90X3BjYSh0X2V0bmlhX21vX25vcm0pCgp0X2V0bmlhX21vX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfbW9fZWMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKHRfZXRuaWFfbW9fbmIpCmBgYAoKIyMjIE5ldXRyb3BoaWwgc2FtcGxlcywgYm90aCBjbGluaWNzLgoKSW4gYSBmYXNoaW9uIHNpbWlsYXIgdG8gb3VyIG90aGVyIGVmZmVjdHMsIHRoZSBuZXV0cm9waGlscyBhcmUgaW50ZXJtZWRpYXRlLgoKYGBge3J9CnRjX25lX2VjIDwtIHNldF9leHB0X2NvbmRpdGlvbnModGNfbmV1dHJvcGhpbHMsIGZhY3QgPSAiY2xpbmljX2V0bmlhIikgJT4lCiAgICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19ldG5pYSJdXSkKZXRuaWFfbmVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19uZV9lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKGV0bmlhX25lX25vcm0pCgpldG5pYV9uZV9uYiA8LSBub3JtYWxpemVfZXhwdCh0Y19uZV9lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKZXRuaWFfbmVfbmJfcGNhIDwtIHBsb3RfcGNhKGV0bmlhX25lX25iKQpwcChmaWxlID0gImZpZ3VyZXMvZXRuaWFfbmVfbmJfcGNhLnN2ZyIpCmV0bmlhX25lX25iX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCmV0bmlhX25lX25iX3BjYQpgYGAKCiMjIyMgTmV1dHJvcGhpbCBzYW1wbGVzLCBUdW1hY28uCgpUaGUgVHVtYWNvLW9ubHkgbmV1dHJvcGhpbHMgYXJlIHNvbWV0aGluZyBvZiBhIGNvdW50ZXIgZXhhbXBsZSB0byB0aGUKcHJldmlvdXMgc3RhdGVtZW50LiAgVGhlIGVhc2llc3QgdG8gZGlzY2VybiByYWNlLWVmZmVjdCBhcHBlYXJzIHRvIG1lCnRvIGNvbWUgZnJvbSB0aGUgTmV1dHJvcGhpbHMgZnJvbSBUdW1hY28uCgpgYGB7cn0KdF9uZV9lYyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRfbmV1dHJvcGhpbHMsIGZhY3QgPSAiZXRuaWEiKSAlPiUKICAgIHNldF9leHB0X2NvbG9ycyhjb2xvcl9jaG9pY2VzW1siZXRobmljaXR5Il1dKQp0X2V0bmlhX25lX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9uZV9lYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKcGxvdF9wY2EodF9ldG5pYV9uZV9ub3JtKQoKdF9ldG5pYV9uZV9uYiA8LSBub3JtYWxpemVfZXhwdCh0X25lX2VjLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYSh0X2V0bmlhX25lX25iKQpgYGAKCiMjIFNleAoKVGhlIGltYmFsYW5jZXMgb2JzZXJ2ZWQgd2l0aCByZXNwZWN0IHRvIGNsaW5pYy9yYWNlIGFyZSBzaWduaWZpY2FudGx5Cmxlc3MgcHJvZm91bmQgdGhhbiB0aG9zZSBvYnNlcnZlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHNleCBvZiBwYXRpZW50cwp3aG8gcGFydGljaXBhdGVkIGluIHRoZSBzdHVkeS4gIEl0IGlzIGFsbW9zdCBjZXJ0YWlubHkgcG9zc2libGUgdG8gc2VlCnNvbWUgZGVncmVlIG9mIGEgc2V4LWJhc2VkIGVmZmVjdCBpbiB0aGUgYXZhaWxhYmxlIHRyYW5zY3JpcHRvbWVzLgoKYGBge3J9CnNleF9leHB0IDwtIHNldF9leHB0X2NvbmRpdGlvbnModGNfdmFsaWQsIGZhY3QgPSAic2V4IikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJzZXgiXV0pCnNleF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHNleF9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKHNleF9ub3JtKQoKc2V4X25iIDwtIG5vcm1hbGl6ZV9leHB0KHNleF9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKHNleF9uYikKYGBgCgojIyBTZXggYW5kIGNsaW5pYwoKIyMjIEFsbCBzYW1wbGVzLCBib3RoIGNsaW5pY3MKCmBgYHtyfQpjbGluaWNfc2V4X2V4cHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0Y192YWxpZCwgZmFjdCA9ICJjbGluaWNfc2V4IikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJjbGluaWNfc2V4Il1dKQpjbGluaWNfc2V4X25vcm0gPC0gbm9ybWFsaXplX2V4cHQoY2xpbmljX3NleF9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIG5vcm0gPSAicXVhbnQiKQpwbG90X3BjYShjbGluaWNfc2V4X25vcm0pCgpjbGluaWNfc2V4X25iIDwtIG5vcm1hbGl6ZV9leHB0KGNsaW5pY19zZXhfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EoY2xpbmljX3NleF9uYikKYGBgCgojIyMgQmlvcHN5IHNhbXBsZXMsIGJvdGggY2xpbmljcy4KCmBgYHtyfQp0Y19icF9zYyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRjX2Jpb3BzaWVzLCBmYWN0ID0gImNsaW5pY19zZXgiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19zZXgiXV0pCmNsaW5pY19zZXhfYnBfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19icF9zYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIpCnBsb3RfcGNhKGNsaW5pY19zZXhfYnBfbm9ybSkKYGBgCgpJIHRoaW5rIHRoZXJlIGFyZSBub3QgZW5vdWdoIHNhbXBsZXMgdG8gdHJ5IHN2YSB3aXRoIHRoaXMuCgojIyMgRW9zaW5vcGhpbCBzYW1wbGVzLCBib3RoIGNsaW5pY3MuCgpgYGB7cgp0Y19lb19zYyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRjX2Vvc2lub3BoaWxzLCBmYWN0ID0gImNsaW5pY19zZXgiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNsaW5pY19zZXgiXV0pCmNsaW5pY19zZXhfZW9fbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19lb19zYywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKcGxvdF9wY2EoY2xpbmljX3NleF9lb19ub3JtKQpgYGAKCiMjIyBNb25vY3l0ZSBzYW1wbGVzLCBib3RoIGNsaW5pY3MuCgpgYGB7cn0KdGNfbW9fY2xpbmljX3NleCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRjX21vbm9jeXRlcywgZmFjdCA9ICJjbGluaWNfc2V4IikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJjbGluaWNfc2V4Il1dKQp0Y19tb19jbGluaWNfc2V4X25vcm0gPC0gbm9ybWFsaXplX2V4cHQodGNfbW9fY2xpbmljX3NleCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKcGxvdF9wY2EodGNfbW9fY2xpbmljX3NleF9ub3JtKQoKdGNfbW9fY2xpbmljX3NleF9uYiA8LSBub3JtYWxpemVfZXhwdCh0Y19tb19jbGluaWNfc2V4LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYSh0Y19tb19jbGluaWNfc2V4X25iKQpgYGAKCiMjIyBOZXV0cm9waGlsIHNhbXBsZXMsIGJvdGggY2xpbmljcy4KCmBgYHtyfQp0Y19uZV9jbGluaWNfc2V4IDwtIHNldF9leHB0X2NvbmRpdGlvbnModGNfbmV1dHJvcGhpbHMsIGZhY3QgPSAiY2xpbmljX3NleCIpICU+JQogICAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJjbGluaWNfc2V4Il1dKQp0Y19uZV9jbGluaWNfc2V4X25vcm0gPC0gbm9ybWFsaXplX2V4cHQodGNfbmVfY2xpbmljX3NleCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKcGxvdF9wY2EodGNfbmVfY2xpbmljX3NleF9ub3JtKQpgYGAKCiMjIEVvc2lub3BoaWxzIGJ5IGNsaW5pYwoKSW4gY29udHJhc3QsIHRoZSBFb3Npbm9waGlsIHNhbXBsZXMgZG8gaGF2ZSBzaWduaWZpY2FudCBhbW91bnRzIG9mCnZhcmlhbmNlIHdoaWNoIGRpc2NyaW1pbmF0ZXMgdGhlIHR3byBjbGluaWNzLiAgQXQgdGhlIHRpbWUgb2YgdGhpcwp3cml0aW5nLCB0aGVyZSBhcmUgZmV3ZXIgZW9zaW5vcGhpbCBzYW1wbGVzIHRoYW4gbW9ub2N5dGVzIGFuZApuZXV0cm9waGlsczsgYXMgYSByZXN1bHQgdGhlcmUgYXJlIG5vIHNhbXBsZXMgd2hpY2ggZmFpbGVkIGZyb20gQ2FsaS4KVGhpcyBpcyBzb21ld2hhdCBsaW1pdGluZyBpcyB3ZSB3aXNoIHRvIGxvb2sgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4KdGhlIGN1cmUgYW5kIGZhaWwgc2FtcGxlcyB3aGljaCBjYW1lIGZyb20gdGhlIHR3byBjbGluaWNzLgoKIyMjIEZpZ3VyZSAzQjogRW9zaW5vcGhpbHMKCmBgYHtyfQp0Y19lb3Npbm9waGlsc19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2Vvc2lub3BoaWxzLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydCA9ICJjcG0iLCBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKdGNfZW9zaW5vcGhpbHNfcGNhIDwtIHBsb3RfcGNhKHRjX2Vvc2lub3BoaWxzX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRjX2Vvc2lub3BoaWxzX3BjYQpwcChmaWxlID0gImZpZ3VyZXMvdGNfZW9zaW5vcGhpbHMuc3ZnIikKdGNfZW9zaW5vcGhpbHNfcGNhW1sicGxvdCJdXQpkZXYub2ZmKCkKCnRjX2Vvc2lub3BoaWxzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2Vvc2lub3BoaWxzLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdGNfZW9zaW5vcGhpbHNfbmJfcGNhIDwtIHBsb3RfcGNhKHRjX2Vvc2lub3BoaWxzX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvZmlndXJlM0JfZW9zaW5vcGhpbHMuc3ZnIikKdGNfZW9zaW5vcGhpbHNfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRjX2Vvc2lub3BoaWxzX25iX3BjYSRwbG90CmBgYAoKIyMgTW9ub2N5dGVzIGJ5IGNsaW5pYwoKSW4gY29udHJhc3Qgd2l0aCB0aGUgZW9zaW5vcGhpbCBzYW1wbGVzLCB3ZSBoYXZlIG9uZSBwYXRpZW50J3MKbW9ub2N5dGUgYW5kIG5ldXRyb3BoaWwgc2FtcGxlcyB3aGljaCBkaWQgbm90IGN1cmUuICBBcyB3ZSB3aWxsIHNlZSwKdGhlcmUgaXMgb25lIHBlcnNvbiBmcm9tIENhbGkgd2hvIGRpZCBub3QgY3VyZSwgdGhpcyBwZXJzb24gaXMgbm90CmRpZmZlcmVudCB3aXRoIHJlc3BlY3QgdG8gdHJhY3NjcmlwdG9tZSB0aGFuIHRoZSBvdGhlciBwZW9wbGUgZnJvbSBDYWxpLgoKIyMjIEZpZ3VyZSAzQzogTW9ub2N5dGVzCgpgYGB7cn0KdGNfbW9ub2N5dGVzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodGNfbW9ub2N5dGVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnRjX21vbm9jeXRlc19wY2EgPC0gcGxvdF9wY2EodGNfbW9ub2N5dGVzX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRjX21vbm9jeXRlc19wY2EKcHAoZmlsZSA9ICJmaWd1cmVzL3RjX21vbm9jeXRlc19wY2Euc3ZnIikKdGNfbW9ub2N5dGVzX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCgp0Y19tb25vY3l0ZXNfbmIgPC0gbm9ybWFsaXplX2V4cHQodGNfbW9ub2N5dGVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRjX21vbm9jeXRlc19uYl9wY2EgPC0gcGxvdF9wY2EodGNfbW9ub2N5dGVzX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvZmlndXJlM0NfbW9ub2N5dGVzLnN2ZyIpCnRjX21vbm9jeXRlc19uYl9wY2EkcGxvdApkZXYub2ZmKCkKdGNfbW9ub2N5dGVzX25iX3BjYSRwbG90CmBgYAoKIyMgTmV1dHJvcGhpbHMgYnkgY2xpbmljCgpGaW5hbGx5LCB0aGF0IHNhbWUgb25lIHBlcnNvbiBkb2VzIGFwcGVhciB0byBiZSBkaWZmZXJlbnQgdGhhbiB0aGUKb3RoZXJzIGZyb20gQ2FsaSB3aGVuIGxvb2tpbmcgYXQgbmV1dHJvcGhpbHMuCgojIyMgRmlndXJlIDNEOiBOZXV0cm9waGlscwoKYGBge3J9CnRjX25ldXRyb3BoaWxzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodGNfbmV1dHJvcGhpbHMsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQp0Y19uZXV0cm9waGlsc19wY2EgPC0gcGxvdF9wY2EodGNfbmV1dHJvcGhpbHNfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdGNfbmV1dHJvcGhpbHNfcGNhCnBwKGZpbGUgPSAiZmlndXJlcy90Y19uZXV0cm9waGlsc19wY2Euc3ZnIikKdGNfbmV1dHJvcGhpbHNfcGNhW1sicGxvdCJdXQpkZXYub2ZmKCkKCnRjX25ldXRyb3BoaWxzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRjX25ldXRyb3BoaWxzLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdGNfbmV1dHJvcGhpbHNfbmJfcGNhIDwtIHBsb3RfcGNhKHRjX25ldXRyb3BoaWxzX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvZmlndXJlM0RfbmV1dHJvcGhpbHMuc3ZnIikKdGNfbmV1dHJvcGhpbHNfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRjX25ldXRyb3BoaWxzX25iX3BjYSRwbG90CmBgYAoKIyMgUENBOiBDb21wYXJlIGNsaW5pY3MKCk5vdyB0aGF0IHdlIGhhdmUgdGhlc2UgdmFyaW91cyBzdWJzZXRzLCBwZXJmb3JtIGFuIGV4cGxpY2l0IGNvbXBhcmlzb24Kb2YgdGhlIHNhbXBsZXMgd2hpY2ggY2FtZSBmcm9tIHRoZSB0d28gY2xpbmljcy4KCiMjIyBGaWd1cmUgMywgcGFuZWwgQTogJ0FMTCBTYW1wbGVzJwoKYGBge3J9CnRjX2NsaW5pY190eXBlIDwtIHRjX3ZhbGlkICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJjbGluaWMiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidHlwZW9mY2VsbHMiKQoKdGNfY2xpbmljX3R5cGVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19jbGluaWNfdHlwZSwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnRjX2NsaW5pY190eXBlX3BjYSA8LSBwbG90X3BjYSh0Y19jbGluaWNfdHlwZV9ub3JtKQp0Y19jbGluaWNfdHlwZV9wY2EKdGNfY2xpbmljX3R5cGVfbmIgPC0gbm9ybWFsaXplX2V4cHQodGNfY2xpbmljX3R5cGUsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0Y19jbGluaWNfdHlwZV9uYl9wY2EgPC0gcGxvdF9wY2EodGNfY2xpbmljX3R5cGVfbmIpCnRjX2NsaW5pY190eXBlX25iX3BjYQpwcChmaWxlID0gImZpZ3VyZXMvZmlndXJlM2FfYWxsX3NhbXBsZXMuc3ZnIikKdGNfY2xpbmljX3R5cGVfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCmBgYAoKCmBgYHtyfQp0Y19jbGluaWNhbF9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCBmaWx0ZXIgPSAic2ltcGxlIiwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIpKQpjbGluaWNhbF9wY2EgPC0gcGxvdF9wY2EodGNfY2xpbmljYWxfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNpcyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X3RpdGxlID0gIlBDQSAtIGNsaW5pY2FsIHNhbXBsZXMiKQpjbGluaWNhbF9wY2EKCnRjX2NsaW5pY2FsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCBmaWx0ZXIgPSAic2ltcGxlIiwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBjb252ZXJ0ID0gImNwbSIpCnRjX2NsaW5pY2FsX25iX3BjYSA8LSBwbG90X3BjYSh0Y19jbGluaWNhbF9uYikKdGNfY2xpbmljYWxfbmJfcGNhJHBsb3QKCmNsaW5pY2FsX3BjYV9pbmZvIDwtIHBjYV9pbmZvcm1hdGlvbigKICAgIHRjX2NsaW5pY2FsX25vcm0sIHBsb3RfcGNhcyA9IFRSVUUsIG51bV9jb21wb25lbnRzID0gMzAsCiAgICBleHB0X2ZhY3RvcnMgPSBjKCJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIsICJmaW5hbG91dGNvbWUiLAogICAgICAgICAgICAgICAgICAgImNsaW5pYyIsICJkb25vciIpKQpjbGluaWNhbF9wY2FfaW5mbyRhbm92YV9uZWdsb2dwX2hlYXRtYXAKY2xpbmljYWxfcGNhX2luZm8kcGNhX3Bsb3RzJFBDNF9QQzcKCmNsaW5pY2FsX3Njb3JlcyA8LSBwY2FfaGlnaHNjb3Jlcyh0Y19jbGluaWNhbF9ub3JtKQpjbGluaWNhbF9zY29yZXNbWyJoaWdoZXN0Il1dWywiQ29tcC40Il0KCnRlc3RfZmFjdG9ycyA8LSBjKCJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIsICJmaW5hbG91dGNvbWUiLAogICAgICAgICAgICAgICAgICAiY2xpbmljIiwgInNleCIsICJldG5pYSIpCmNsaW5pY2FsX3ZhcnBhcnQgPC0gc2ltcGxlX3ZhcnBhcnQodGNfY2xpbmljYWwsIGZhY3RvcnMgPSB0ZXN0X2ZhY3RvcnMpCmNsaW5pY2FsX3ZhcnBhcnQKYGBgCgojIyBJdGVyYXRpdmUgU1ZBIGZvbGxvd2VkIGJ5IFBDQQoKQW5vdGhlciB3YXkgdG8gZXhwbG9yZSB0aGUgZWZmZWN0IG9mIFNWQSBpcyB0byBpdGVyYXRpdmVseSBpbmNyZWFzZQp0aGUgbnVtYmVyIG9mIFNWcyByZW1vdmVkIGJ5IGl0IGFuZCBsb29rIGF0IHNvbWUgc2ltcGxlIHBsb3RzIG9mIHRoZQpyZXN1bHRpbmcgZGF0YS4gIElkZWFsbHksIHRoaXMgc2hvdWxkIGNvbXBsZW1lbnQgdGhlIGNvbXBhcmlzb24gb2YKaW5kaXZpZHVhbCBTVnMgdnMuIFBDcyBwZXJmb3JtZWQgYnkgVGhlcmVzYSAoc3BvaWxlciBhbGVydCwgSSB0aGluayBpdApkaWQpLgoKYGBge3J9CmZpcnN0IDwtIG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIiwgc3Vycm9nYXRlcyA9IDEpCmZpcnN0X2luZm8gPC0gcGNhX2luZm9ybWF0aW9uKAogICAgZmlyc3QsIHBsb3RfcGNhcyA9IFRSVUUsIG51bV9jb21wb25lbnRzID0gMzAsCiAgICBleHB0X2ZhY3RvcnMgPSBjKCJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIsCiAgICAgICAgICAgICAgICAgICAgICJmaW5hbG91dGNvbWUiLCAiY2xpbmljIikpCmZpcnN0X2luZm8kYW5vdmFfbmVnbG9ncF9oZWF0bWFwCmZpcnN0X2luZm8kcGNhX3Bsb3RzW1siUEMxX1BDMiJdXQoKc2Vjb25kIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIsIHN1cnJvZ2F0ZXMgPSAyKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljIikKc2Vjb25kX2luZm8gPC0gcGNhX2luZm9ybWF0aW9uKAogICAgc2Vjb25kLCBwbG90X3BjYXMgPSBUUlVFLCBudW1fY29tcG9uZW50cyA9IDMwLAogICAgZXhwdF9mYWN0b3JzID0gYygidmlzaXRudW1iZXIiLCAidHlwZW9mY2VsbHMiLAogICAgICAgICAgICAgICAgICAgICAiZmluYWxvdXRjb21lIiwgImNsaW5pYyIpKQpzZWNvbmRfaW5mbyRhbm92YV9uZWdsb2dwX2hlYXRtYXAKCnRoaXJkIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIiwgc3Vycm9nYXRlcyA9IDMpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJjbGluaWMiKQp0aGlyZF9pbmZvIDwtIHBjYV9pbmZvcm1hdGlvbigKICAgIHRoaXJkLCBwbG90X3BjYXMgPSBUUlVFLCBudW1fY29tcG9uZW50cyA9IDMwLAogICAgZXhwdF9mYWN0b3JzID0gYygidmlzaXRudW1iZXIiLCAidHlwZW9mY2VsbHMiLAogICAgICAgICAgICAgICAgICAgICAiZmluYWxvdXRjb21lIiwgImNsaW5pYyIpKQp0aGlyZF9pbmZvJGFub3ZhX25lZ2xvZ3BfaGVhdG1hcAoKZm91cnRoIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIsIHN1cnJvZ2F0ZXMgPSA0KSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljIikKZm91cnRoX2luZm8gPC0gcGNhX2luZm9ybWF0aW9uKAogICAgZm91cnRoLCBwbG90X3BjYXMgPSBUUlVFLCBudW1fY29tcG9uZW50cyA9IDMwLAogICAgZXhwdF9mYWN0b3JzID0gYygidmlzaXRudW1iZXIiLCAidHlwZW9mY2VsbHMiLAogICAgICAgICAgICAgICAgICAgICAiZmluYWxvdXRjb21lIiwgImNsaW5pYyIpKQpmb3VydGhfaW5mbyRhbm92YV9uZWdsb2dwX2hlYXRtYXAKZm91cnRoX2luZm9bWyJwY2FfcGxvdHMiXV1bWyJQQzFfUEMyIl1dCgpmaWZ0aCA8LSBub3JtYWxpemVfZXhwdCh0Y19jbGluaWNhbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIsIHN1cnJvZ2F0ZXMgPSA1KSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljIikKZmlmdGhfaW5mbyA8LSBwY2FfaW5mb3JtYXRpb24oCiAgICBmaWZ0aCwgcGxvdF9wY2FzID0gVFJVRSwgbnVtX2NvbXBvbmVudHMgPSAzMCwKICAgIGV4cHRfZmFjdG9ycyA9IGMoInZpc2l0bnVtYmVyIiwgInR5cGVvZmNlbGxzIiwKICAgICAgICAgICAgICAgICAgICAgImZpbmFsb3V0Y29tZSIsICJjbGluaWMiKSkKZmlmdGhfaW5mbyRhbm92YV9uZWdsb2dwX2hlYXRtYXAKZmlmdGhfaW5mb1tbInBjYV9wbG90cyJdXVtbIlBDMV9QQzEyIl1dCgpzaXh0aCA8LSBub3JtYWxpemVfZXhwdCh0Y19jbGluaWNhbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoPSJzdmFzZXEiLCBzdXJyb2dhdGVzID0gNikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pYyIpCnNpeHRoX2luZm8gPC0gcGNhX2luZm9ybWF0aW9uKAogICAgc2l4dGgsIHBsb3RfcGNhcyA9IFRSVUUsIG51bV9jb21wb25lbnRzID0gMzAsCiAgICBleHB0X2ZhY3RvcnMgPSBjKCJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIsCiAgICAgICAgICAgICAgICAgICAgICJmaW5hbG91dGNvbWUiLCAiY2xpbmljIikpCnNpeHRoX2luZm8kYW5vdmFfbmVnbG9ncF9oZWF0bWFwCgpzZXZlbnRoIDwtIG5vcm1hbGl6ZV9leHB0KHRjX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiLCBzdXJyb2dhdGVzID0gNykgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pYyIpCnNldmVudGhfaW5mbyA8LSBwY2FfaW5mb3JtYXRpb24oCiAgICBzZXZlbnRoLCBwbG90X3BjYXMgPSBUUlVFLCBudW1fY29tcG9uZW50cyA9IDMwLAogICAgZXhwdF9mYWN0b3JzID0gYygidmlzaXRudW1iZXIiLCAidHlwZW9mY2VsbHMiLAogICAgICAgICAgICAgICAgICAgICAiZmluYWxvdXRjb21lIiwgImNsaW5pYyIpKQpzZXZlbnRoX2luZm8kYW5vdmFfbmVnbG9ncF9oZWF0bWFwCgplaWdodGggPC0gbm9ybWFsaXplX2V4cHQodGNfY2xpbmljYWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiLCBzdXJyb2dhdGVzID0gOCkKZWlnaHRoX2luZm8gPC0gcGNhX2luZm9ybWF0aW9uKAogICAgZWlnaHRoLCBwbG90X3BjYXMgPSBUUlVFLCBudW1fY29tcG9uZW50cyA9IDMwLAogICAgZXhwdF9mYWN0b3JzID0gYygidmlzaXRudW1iZXIiLCAidHlwZW9mY2VsbHMiLAogICAgICAgICAgICAgICAgICAgICAiZmluYWxvdXRjb21lIiwgImNsaW5pYyIpKQplaWdodGhfaW5mbyRhbm92YV9uZWdsb2dwX2hlYXRtYXAKYGBgCgojIFZhcmlhbmNlIFBhcnRpdGlvbgoKdmFyaWFuY2VQYXJ0aXRpb24gKEBob2ZmbWFuVmFyaWFuY2VQYXJ0aXRpb25JbnRlcnByZXRpbmdEcml2ZXJzMjAxNikKcHJvdmlkZXMgYSBuaWNlIHRvb2xib3ggb2YgbWV0aG9kcyB0byBleGFtaW5lIHRoZSByZWxhdGlvbnNoaXAgYmV0d2Vlbgp2YXJpb3VzIG1ldGFkYXRhIGZhY3RvcnMgaW4gYSBkYXRhc2V0IHdpdGggcmVzcGVjdCB0byB0aGUgdmFyaWFuY2UKb2JzZXJ2ZWQgaW4gdGhlIGRhdGFzZXQncyBleHByZXNzaW9uLiAgV2UgdXN1YWxseSB1c2UgaXQgYXMgYSBxdWljawp3YXkgdG8gc2VlIHRoZSByZWxhdGl2ZSBsaWtlbGlob29kIHRoYXQgYSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbgpvZiB2YXJpb3VzIGZhY3RvcnMgd2lsbCBwcm92aWRlIHVzZWZ1bC9oZWxwZnVsIG91dHB1dC4KCmBgYHtyfQojIyBNb3N0bHkgcnVubmluZyB0d2ljZSB0byBtYWtlIHN1cmUgdGhhdCByZW9yZGVyaW5nIHRoZSBmYWN0b3JzIGRvZXMgbm90IGFmZmVjdCB0aGUgZW5kIHJlc3VsdC4KdGNfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCgKICB0Y19jbGluaWNhbF9ub2Jpb3AsIGZhY3RvcnMgPSBjKCJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmluYWxvdXRjb21lIiwgImNsaW5pYyIsICJzZXgiLCAiZXRuaWEiKSkKdGNfdmFycGFydAoKdGNfdmFycGFydHYyIDwtIHNpbXBsZV92YXJwYXJ0KAogIHRjX2NsaW5pY2FsX25vYmlvcCwgZmFjdG9ycyA9IGMoImRvbm9yIiwgInZpc2l0bnVtYmVyIiwgInR5cGVvZmNlbGxzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaW5hbG91dGNvbWUiKSkKcHAoZmlsZSA9ICJpbWFnZXMvdGNfZG9ub3JfdmlzaXRfdHlwZV9maW5hbG91dGNvbWVfdmFycGFydC5wZGYiKQp0Y192YXJwYXJ0djIKZGV2Lm9mZigpCnRjX3ZhcnBhcnR2MgoKdGNfdmFycGFydHYzIDwtIHNpbXBsZV92YXJwYXJ0KAogIHRjX2NsaW5pY2FsX25vYmlvcCwgZmFjdG9ycyA9IGMoImRvbm9yIiwgInZpc2l0bnVtYmVyIiwgInR5cGVvZmNlbGxzIikpCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX2Rvbm9yX3Zpc2l0X3R5cGVfdmFycGFydC5wZGYiKQp0Y192YXJwYXJ0djMKZGV2Lm9mZigpCnRjX3ZhcnBhcnR2MwoKdGNfdmFycGFydHY0IDwtIHNpbXBsZV92YXJwYXJ0KAogIHRjX2NsaW5pY2FsX25vYmlvcCwgZmFjdG9ycyA9IGMoImZpbmFsb3V0Y29tZSIsICJzZXgiLCAiRXRobmljaXR5IikpCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX2ZpbmFsX3NleF9ldGhuaWNpdHlfdmFycGFydC5wZGYiKQp0Y192YXJwYXJ0djQKZGV2Lm9mZigpCnRjX3ZhcnBhcnR2NAoKdF92YXJwYXJ0djMgPC0gc2ltcGxlX3ZhcnBhcnQoCiAgdF9jbGluaWNhbF9ub2Jpb3AsIGZhY3RvcnMgPSBjKCJkb25vciIsICJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIpKQpwcChmaWxlID0gImltYWdlcy90X2Rvbm9yX3Zpc2l0X3R5cGVfdmFycGFydC5wZGYiKQp0X3ZhcnBhcnR2MwpkZXYub2ZmKCkKdF92YXJwYXJ0djMKCmNfdmFycGFydHYzIDwtIHNpbXBsZV92YXJwYXJ0KAogIGNfY2xpbmljYWwsIGZhY3RvcnMgPSBjKCJkb25vciIsICJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIpKQpwcChmaWxlID0gImltYWdlcy9jX2Rvbm9yX3Zpc2l0X3R5cGVfdmFycGFydC5wZGYiKQpjX3ZhcnBhcnR2MwpkZXYub2ZmKCkKY192YXJwYXJ0djMKYGBgCgojIyBTb21lIGZhY3RvcnMgb2YgbGF0ZXIgaW50ZXJlc3QKCk1hcmlhIEFkZWxhaWRhIGFza2VkIGFib3V0IHVzaW5nIHZhcmlhbmNlUGFydGl0aW9uIHRvIHF1ZXJ5IGEgZmV3Cm90aGVyIGZhY3RvcnMgaW4gdGhlIENhbGksIFR1bWFjbywgYW5kIGJvdGggZGF0YXNldHMuICBUaGVzZSBmYWN0b3JzCmluY2x1ZGU6IFNleCwgQWdlLCBFdGhuaWNpdHksIENsaW5pYzsgYW5kIHBvdGVudGlhbGx5IEFkaGVyZW5jZSwgdGltZQpvZiBldm9sdXRpb24sIGFuZCBwcmV2aW91cyBkaWFnbm9zaXMuCgpJIGFtIG5vdCBzdXJlIGlmIHRob3NlIGZhY3RvcnMgYXJlIGFscmVhZHkgaW4gdGhlIGV4cHJlc3Npb25zZXQKbWV0YWRhdGEsIGJ1dCBpZiBub3Qgd2UgY2FuIGNlcnRhaW5seSBicmluZyB0aGVtIGJhY2suICBJbiB0aGUKZm9sbG93aW5nIGJsb2NrIEkgd2lsbCB0aGVyZWZvcmUgcmVwZWF0IGEgc2ltcGxlIHZhcmlhbmNlUGFydGl0aW9uCmFuYWx5c2lzIHVzaW5nIGZpcnN0IHRoZSBmdWxsIGRhdGFzZXQgKFR1bWFjbytDYWxpKSwgdGhlbiBlYWNoIGNsaW5pYwphbG9uZTsgaW4gZWFjaCBpbnN0YW5jZSBJIHdpbGwgZG8gb25lIHJvdW5kIHdpdGggc2V4LCBldGhuaWNpdHksIGFnZSwKYW5kIGNsaW5pYyBmb2xsb3dlZCBieSB0aGUgc2FtZSBhbmQgZmluYWxvdXRjb21lIChhcyBhIHJlZmVyZW5jZSBwb2ludAp0byBzb21ldGhpbmcgd2UgYXJlIGFscmVhZHkgbG9va2luZyBhdCkuCgpgYGB7cn0KdGFibGUocERhdGEodGNfY2xpbmljYWxfbm9iaW9wKSR0eXBlb2ZjZWxscykKdGFibGUocERhdGEodF9jbGluaWNhbF9ub2Jpb3ApJHR5cGVvZmNlbGxzKQp0YWJsZShwRGF0YShjX2NsaW5pY2FsX25vYmlvcCkkdHlwZW9mY2VsbHMpCgp0Y19mdW5fdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCh0Y19jbGluaWNhbF9ub2Jpb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3RvcnMgPSBjKCJzZXgiLCAiZXRuaWEiLCAiQWdlIiwgImNsaW5pYyIpKQpwcChmaWxlID0gImltYWdlcy90Y19mdW5fdmFycGFydC5wZGYiKQp0Y19mdW5fdmFycGFydApkZXYub2ZmKCkKdGNfZnVuX3ZhcnBhcnQKdGNfZnVuX291dGNvbWVfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCh0Y19jbGluaWNhbF9ub2Jpb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9ycyA9IGMoInNleCIsICJldG5pYSIsICJBZ2UiLCAiY2xpbmljIiwgImZpbmFsb3V0Y29tZSIpKQpwcChmaWxlID0gImltYWdlcy90Y19mdW5fb3V0Y29tZV92YXJwYXJ0LnBkZiIpCnRjX2Z1bl9vdXRjb21lX3ZhcnBhcnQKZGV2Lm9mZigpCnRjX2Z1bl9vdXRjb21lX3ZhcnBhcnQKY19mdW5fdmFycGFydCA8LSBzaW1wbGVfdmFycGFydChjX2NsaW5pY2FsX25vYmlvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JzID0gYygic2V4IiwgImV0bmlhIiwgIkFnZSIpKQpwcChmaWxlID0gImltYWdlcy9jX2Z1bl92YXJwYXJ0LnBkZiIpCmNfZnVuX3ZhcnBhcnQKZGV2Lm9mZigpCmNfZnVuX291dGNvbWVfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydChjX2NsaW5pY2FsX25vYmlvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3RvcnMgPSBjKCJzZXgiLCAiZXRuaWEiLCAiQWdlIiwgImZpbmFsb3V0Y29tZSIpKQpwcChmaWxlID0gImltYWdlcy9jX2Z1bl9vdXRjb21lX3ZhcnBhcnQucGRmIikKY19mdW5fb3V0Y29tZV92YXJwYXJ0CmRldi5vZmYoKQpjX2Z1bl9vdXRjb21lX3ZhcnBhcnQKdF9mdW5fdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCh0X2NsaW5pY2FsX25vYmlvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JzID0gYygic2V4IiwgImV0bmlhIiwgIkFnZSIpKQpwcChmaWxlID0gImltYWdlcy90X2Z1bl92YXJwYXJ0LnBkZiIpCnRfZnVuX3ZhcnBhcnQKZGV2Lm9mZigpCnRfZnVuX3ZhcnBhcnQKdF9mdW5fb3V0Y29tZV92YXJwYXJ0IDwtIHNpbXBsZV92YXJwYXJ0KHRfY2xpbmljYWxfbm9iaW9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9ycyA9IGMoInNleCIsICJldG5pYSIsICJBZ2UiLCAiZmluYWxvdXRjb21lIikpCnBwKGZpbGUgPSAiaW1hZ2VzL3RfZnVuX291dGNvbWVfdmFycGFydC5wZGYiKQp0X2Z1bl9vdXRjb21lX3ZhcnBhcnQKZGV2Lm9mZigpCnRfZnVuX291dGNvbWVfdmFycGFydApgYGAKCiMjIFZpc3VhbGl6ZTogUmVwZWF0IHBsb3RzIHVzaW5nIG9ubHkgdGhlIFR1bWFjbyBzYW1wbGVzCgpUaGUgZm9sbG93aW5nIHNob3VsZCBiZSBhIG5lYXJseSBjb3B5L3Bhc3RlZCB2ZXJzaW9uIG9mIHRoZSBhYm92ZSwgYnV0CmxpbWl0ZWQgdG8gdGhlIFR1bWFjbyBzYW1wbGVzLgoKIyMjIEFsbCBzYW1wbGVzCgojIyMjIEZpZ3VyZSB4eCBwYW5lbHMgQStCCgpgYGB7cn0KdF9jbGluaWNhbF9ub2Jpb3Bfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X2NsaW5pY2FsX25vYmlvcCwgZmlsdGVyID0gVFJVRSwgbm9ybSA9ICJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydCA9ICJjcG0iLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnRfY2xpbmljYWxfbm9iaW9wX3BjYSA8LSBwbG90X3BjYSh0X2NsaW5pY2FsX25vYmlvcF9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvdF9jbGluaWNhbF9ub2Jpb3BfcGNhLnN2ZyIpCnRfY2xpbmljYWxfbm9iaW9wX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCnRfY2xpbmljYWxfbm9iaW9wX3BjYQoKdF9jbGluaWNhbF9ub2Jpb3BfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9jbGluaWNhbF9ub2Jpb3AsIGZpbHRlciA9IFRSVUUsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBiYXRjaCA9ICJzdmFzZXEiKQp0X2NsaW5pY2FsX25vYmlvcF9uYl9wY2EgPC0gcGxvdF9wY2EodF9jbGluaWNhbF9ub2Jpb3BfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiZmlndXJlcy90X2NsaW5pY2FsX25vYmlvcF9zdmFfZmlneHhiLnBkZiIpCnRfY2xpbmljYWxfbm9iaW9wX25iX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCnRfY2xpbmljYWxfbm9iaW9wX25iX3BjYQpgYGAKCiMjIyMgRmlndXJlIHh4IHBhbmVscyBDK0QKCmBgYHtyfQp0Y19jbGluaWNhbF9ub2Jpb3Bfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y19jbGluaWNhbF9ub2Jpb3AsIGZpbHRlciA9IFRSVUUsIG5vcm0gPSAicXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIHRyYW5zZm9ybSA9ICJsb2cyIikKdGNfY2xpbmljYWxfbm9iaW9wX3BjYSA8LSBwbG90X3BjYSh0Y19jbGluaWNhbF9ub2Jpb3Bfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKcHAoZmlsZSA9ICJmaWd1cmVzL3RjX2NsaW5pY2FsX25vYmlvcF9wY2Euc3ZnIikKdGNfY2xpbmljYWxfbm9iaW9wX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCnRjX2NsaW5pY2FsX25vYmlvcF9wY2EKCnRjX2NsaW5pY2FsX25vYmlvcF9uYiA8LSBub3JtYWxpemVfZXhwdCh0Y19jbGluaWNhbF9ub2Jpb3AsIGZpbHRlciA9IFRSVUUsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgYmF0Y2ggPSAic3Zhc2VxIikKdGNfY2xpbmljYWxfbm9iaW9wX25iX3BjYSA8LSBwbG90X3BjYSh0Y19jbGluaWNhbF9ub2Jpb3BfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiZmlndXJlcy90Y19jbGluaWNhbF9ub2Jpb3Bfc3ZhX3BjYS5zdmciKQp0Y19jbGluaWNhbF9ub2Jpb3BfbmJfcGNhW1sicGxvdCJdXQpkZXYub2ZmKCkKdGNfY2xpbmljYWxfbm9iaW9wX25iX3BjYQpgYGAKCk5vdyB3ZSBoYXZlIGEgbmV3LCBzbWFsbGVyIHNldCBvZiBwcmltYXJ5IHNhbXBsZXMgd2hpY2ggYXJlCmNhdGVnb3JpemVkIGJ5IGNlbGwgdHlwZS4KCiMjIyBWaXN1YWxpemU6IEJpb3BzeSBzYW1wbGVzIG9ubHkgVHVtYWNvCgpUaGUgYmlvcHN5IHNhbXBsZXMgcmVtYWluIGJhc2ljYWxseSBpbXBlbmV0cmFibGUuIEkgdGhpbmsgaXQKd291bGQgYmUgcGFydGljdWxhcmx5IG5pY2UgaWYgd2UgY291bGQganVkZ2UgY3VyZS9mYWlsIGZyb20gYSB2aXNpdCAxCmJpb3BzeS4KCmBgYHtyfQp0X2Jpb3BzaWVzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9iaW9wc2llcywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCgp0X2Jpb3BzaWVzX3BjYSA8LSBwbG90X3BjYSh0X2Jpb3BzaWVzX25vcm0sCiAgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9iaW9wc2llc19wY2EKCnRfYmlvcHNpZXNfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9iaW9wc2llcywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9iaW9wc2llc19uYl9wY2EgPC0gcGxvdF9wY2EodF9iaW9wc2llc19uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9iaW9wc2llc19uYl9wY2EkcGxvdApgYGAKCiMjIyBWaXN1YWxpemU6IE1vbm9jeXRlIHNhbXBsZXMgb25seSBUdW1hY28KCkluIGNvbnRyYXN0LCBJIHN1c3BlY3QgdGhhdCB3ZSBjYW4gZ2V0IG1lYW5pbmdmdWwgZGF0YSBmcm9tIHRoZQpvdGhlciBjZWxsIHR5cGVzLiAgVGhlIG1vbm9jeXRlIHNhbXBsZXMgYXJlIHN0aWxsIGEgYml0IG1lc3N5LgoKIyMjIEZpZ3VyZSA0QTogTW9ub2N5dGVzCgpgYGB7cn0KdF9tb25vY3l0ZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfbW9ub2N5dGVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQoKdF9tb25vY3l0ZV9wY2EgPC0gcGxvdF9wY2EodF9tb25vY3l0ZV9ub3JtLAogIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfbW9ub2N5dGVfcGNhCgp0X21vbm9jeXRlX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfbW9ub2N5dGVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X21vbm9jeXRlX25iX3BjYSA8LSBwbG90X3BjYSh0X21vbm9jeXRlX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvZmlndXJlNEFfbW9ub2N5dGVzLnN2ZyIpCnRfbW9ub2N5dGVfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRfbW9ub2N5dGVfbmJfcGNhJHBsb3QKYGBgCgojIyMgVmlzdWFsaXplOiBOZXV0cm9waGlsIHNhbXBsZXMgb25seSBUdW1hY28KCiMjIyBGaWd1cmUgNEE6IE5ldXRyb3BoaWxzCgpgYGB7cn0KdF9uZXV0cm9waGlsX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9uZXV0cm9waGlscywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQoKdF9uZXV0cm9waGlsX3BjYSA8LSBwbG90X3BjYSh0X25ldXRyb3BoaWxfbm9ybSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X2xhYmVscyA9IEZBTFNFKQp0X25ldXRyb3BoaWxfcGNhCgp0X25ldXRyb3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9uZXV0cm9waGlscywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X25ldXRyb3BoaWxfbmJfcGNhIDwtIHBsb3RfcGNhKHRfbmV1dHJvcGhpbF9uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKcHAoZmlsZSA9ICJmaWd1cmVzL2ZpZ3VyZTRBX25ldXRyb3BoaWxzLnN2ZyIpCnRfbmV1dHJvcGhpbF9uYl9wY2EkcGxvdApkZXYub2ZmKCkKdF9uZXV0cm9waGlsX25iX3BjYSRwbG90CmBgYAoKIyMjIFZpc3VhbGl6ZTogRW9zaW5vcGhpbCBzYW1wbGVzIG9ubHkgVHVtYWNvCgojIyMgRmlndXJlIDRBOiBFb3Npbm9waGlscwoKYGBge3J9CnRfZW9zaW5vcGhpbF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfZW9zaW5vcGhpbHMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKCnRfZW9zaW5vcGhpbF9wY2EgPC0gcGxvdF9wY2EodF9lb3Npbm9waGlsX25vcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9lb3Npbm9waGlsX3BjYQoKdF9lb3Npbm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfZW9zaW5vcGhpbHMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9lb3Npbm9waGlsX25iX3BjYSA8LSBwbG90X3BjYSh0X2Vvc2lub3BoaWxfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiZmlndXJlcy9maWd1cmU0QV9lb3Npbm9waGlscy5zdmciKQp0X2Vvc2lub3BoaWxfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRfZW9zaW5vcGhpbF9uYl9wY2EkcGxvdApgYGAKCiMjIyBWaXN1YWxpemU6IExvb2sgYXQgQ2VsbCB0eXBlcyBDL0YgYnkgdmlzaXQKCiMjIyMgTW9ub2N5dGVzLCBWaXNpdCAxCgpgYGB7cn0KdF9tb25vY3l0ZV92MSA8LSBzdWJzZXRfZXhwdCh0X21vbm9jeXRlcywgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0nMSciKQp0X21vbm9jeXRlX3YxX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9tb25vY3l0ZV92MSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSkKdF9tb25vY3l0ZV92MV9wY2EgPC0gcGxvdF9wY2EodF9tb25vY3l0ZV92MV9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X21vbm9jeXRlX3YxX3BjYQoKdF9tb25vY3l0ZV92MV9uYiA8LSBub3JtYWxpemVfZXhwdCh0X21vbm9jeXRlX3YxLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0X21vbm9jeXRlX3YxX25iX3BjYSA8LSBwbG90X3BjYSh0X21vbm9jeXRlX3YxX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X21vbm9jeXRlX3YxX25iX3BjYSRwbG90CmBgYAoKIyMjIyBNb25vY3l0ZXMgVmlzaXQgMgoKYGBge3J9CnRfbW9ub2N5dGVfdjIgPC0gc3Vic2V0X2V4cHQodF9tb25vY3l0ZXMsIHN1YnNldCA9ICJ2aXNpdG51bWJlcj09JzInIikKdF9tb25vY3l0ZV92Ml9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfbW9ub2N5dGVfdjIsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnRfbW9ub2N5dGVfdjJfcGNhIDwtIHBsb3RfcGNhKHRfbW9ub2N5dGVfdjJfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9tb25vY3l0ZV92Ml9wY2EkcGxvdAoKdF9tb25vY3l0ZV92Ml9uYiA8LSBub3JtYWxpemVfZXhwdCh0X21vbm9jeXRlX3YyLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0X21vbm9jeXRlX3YyX25iX3BjYSA8LSBwbG90X3BjYSh0X21vbm9jeXRlX3YyX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X21vbm9jeXRlX3YyX25iX3BjYSRwbG90CmBgYAoKIyMjIyBNb25vY3l0ZXMgVmlzaXQgMwoKYGBge3J9CnRfbW9ub2N5dGVfdjMgPC0gc3Vic2V0X2V4cHQodF9tb25vY3l0ZXMsIHN1YnNldCA9ICJ2aXNpdG51bWJlcj09JzMnIikKdF9tb25vY3l0ZV92M19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfbW9ub2N5dGVfdjMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQp0X21vbm9jeXRlX3YzX3BjYSA8LSBwbG90X3BjYSh0X21vbm9jeXRlX3YzX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfbW9ub2N5dGVfdjNfcGNhCgp0X21vbm9jeXRlX3YzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfbW9ub2N5dGVfdjMsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnRfbW9ub2N5dGVfdjNfbmJfcGNhIDwtIHBsb3RfcGNhKHRfbW9ub2N5dGVfdjNfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfbW9ub2N5dGVfdjNfbmJfcGNhJHBsb3QKYGBgCgojIyMjIE5ldXRyb3BoaWxzLCBWaXNpdCAxCgpgYGB7cn0gbmV1dHJvcGhpbHNfYnlfdmlzaXRfdjF9CnRfbmV1dHJvcGhpbF92MSA8LSBzdWJzZXRfZXhwdCh0X25ldXRyb3BoaWxzLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PScxJyIpCnRfbmV1dHJvcGhpbF92MV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfbmV1dHJvcGhpbF92MSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnRfbmV1dHJvcGhpbF92MV9wY2EgPC0gcGxvdF9wY2EodF9uZXV0cm9waGlsX3YxX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfbmV1dHJvcGhpbF92MV9wY2EkcGxvdAoKdF9uZXV0cm9waGlsX3YxX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfbmV1dHJvcGhpbF92MSwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJydXZnIikKdF9uZXV0cm9waGlsX3YxX25iX3BjYSA8LSBwbG90X3BjYSh0X25ldXRyb3BoaWxfdjFfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfbmV1dHJvcGhpbF92MV9uYl9wY2EkcGxvdApgYGAKCiMjIyMgTmV1dHJvcGhpbHMgVmlzaXQgMgoKYGBge3J9CnRfbmV1dHJvcGhpbF92MiA8LSBzdWJzZXRfZXhwdCh0X25ldXRyb3BoaWxzLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PScyJyIpCnRfbmV1dHJvcGhpbF92Ml9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfbmV1dHJvcGhpbF92Miwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQp0X25ldXRyb3BoaWxfdjJfcGNhIDwtIHBsb3RfcGNhKHRfbmV1dHJvcGhpbF92Ml9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X25ldXRyb3BoaWxfdjJfcGNhCgp0X25ldXRyb3BoaWxfdjJfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9uZXV0cm9waGlsX3YyLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnRfbmV1dHJvcGhpbF92Ml9uYl9wY2EgPC0gcGxvdF9wY2EodF9uZXV0cm9waGlsX3YyX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X25ldXRyb3BoaWxfdjJfbmJfcGNhJHBsb3QKYGBgCgojIyMjIE5ldXRyb3BoaWxzIFZpc2l0IDMKCmBgYHtyfQp0X25ldXRyb3BoaWxfdjMgPC0gc3Vic2V0X2V4cHQodF9uZXV0cm9waGlscywgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0nMyciKQp0X25ldXRyb3BoaWxfdjNfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X25ldXRyb3BoaWxfdjMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2czIiwgZmlsdGVyID0gVFJVRSkKdF9uZXV0cm9waGlsX3YzX3BjYSA8LSBwbG90X3BjYSh0X25ldXRyb3BoaWxfdjNfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9uZXV0cm9waGlsX3YzX3BjYQoKdF9uZXV0cm9waGlsX3YzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfbmV1dHJvcGhpbF92MywgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0X25ldXRyb3BoaWxfdjNfbmJfcGNhIDwtIHBsb3RfcGNhKHRfbmV1dHJvcGhpbF92M19uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9uZXV0cm9waGlsX3YzX25iX3BjYSRwbG90CmBgYAoKIyMjIyBFb3Npbm9waGlscywgVmlzaXQgMQoKYGBge3J9CnRfZW9zaW5vcGhpbF92MSA8LSBzdWJzZXRfZXhwdCh0X2Vvc2lub3BoaWxzLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PScxJyIpCnRfZW9zaW5vcGhpbF92MV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfZW9zaW5vcGhpbF92MSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnRfZW9zaW5vcGhpbF92MV9wY2EgPC0gcGxvdF9wY2EodF9lb3Npbm9waGlsX3YxX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfZW9zaW5vcGhpbF92MV9wY2EKCnRfZW9zaW5vcGhpbF92MV9uYiA8LSBub3JtYWxpemVfZXhwdCh0X2Vvc2lub3BoaWxfdjEsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKdF9lb3Npbm9waGlsX3YxX25iX3BjYSA8LSBwbG90X3BjYSh0X2Vvc2lub3BoaWxfdjFfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnRfZW9zaW5vcGhpbF92MV9uYl9wY2EkcGxvdApgYGAKCiMjIyMgRW9zaW5vcGhpbHMgVmlzaXQgMgoKYGBge3J9CnRfZW9zaW5vcGhpbF92MiA8LSBzdWJzZXRfZXhwdCh0X2Vvc2lub3BoaWxzLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PScyJyIpCnRfZW9zaW5vcGhpbF92Ml9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfZW9zaW5vcGhpbF92Miwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQp0X2Vvc2lub3BoaWxfdjJfcGNhIDwtIHBsb3RfcGNhKHRfZW9zaW5vcGhpbF92Ml9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X2Vvc2lub3BoaWxfdjJfcGNhCgp0X2Vvc2lub3BoaWxfdjJfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9lb3Npbm9waGlsX3YyLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnRfZW9zaW5vcGhpbF92Ml9uYl9wY2EgPC0gcGxvdF9wY2EodF9lb3Npbm9waGlsX3YyX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQp0X2Vvc2lub3BoaWxfdjJfbmJfcGNhJHBsb3QKYGBgCgojIyMjIEVvc2lub3BoaWxzIFZpc2l0IDMKCmBgYHtyfQp0X2Vvc2lub3BoaWxfdjMgPC0gc3Vic2V0X2V4cHQodF9lb3Npbm9waGlscywgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0nMyciKQp0X2Vvc2lub3BoaWxfdjNfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X2Vvc2lub3BoaWxfdjMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2czIiwgZmlsdGVyID0gVFJVRSkKdF9lb3Npbm9waGlsX3YzX3BjYSA8LSBwbG90X3BjYSh0X2Vvc2lub3BoaWxfdjNfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9lb3Npbm9waGlsX3YzX3BjYQoKdF9lb3Npbm9waGlsX3YzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfZW9zaW5vcGhpbF92MywgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0X2Vvc2lub3BoaWxfdjNfbmJfcGNhIDwtIHBsb3RfcGNhKHRfZW9zaW5vcGhpbF92M19uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKdF9lb3Npbm9waGlsX3YzX25iX3BjYSRwbG90CmBgYAoKIyMgUmVjYXRlZ29yaXplOiBDb25jYXRlbmF0ZSBjdXJlL2ZhaWwgYW5kIGNlbGwgdHlwZQoKSW4gdGhlIGZvbGxvd2luZyBibG9jayB0aGUgZXhwZXJpbWVudGFsIGNvbmRpdGlvbiB3YXMgcmVzZXQgdG8gdGhlCmNvbmNhdGVuYXRpb24gb2YgY2xpbmljYWwgb3V0Y29tZSBhbmQgdHlwZSBvZiBjZWxscy4gIFRoZXJlIGFyZSBhbgppbnN1ZmZpY2llbnQgbnVtYmVyIG9mIGJpb3BzeSBzYW1wbGVzIGZvciB0aGVtIHRvIGJlIHVzZWZ1bCBpbiB0aGlzCnZpc3VhbGl6YXRpb24sIHNvIHRoZXkgYXJlIGlnbm9yZWQuCgpgYGB7cn0KZGVzaXJlZF9sZXZlbHMgPC0gYygiY3VyZV9iaW9wc3kiLCAiZmFpbHVyZV9iaW9wc3kiLCAiY3VyZV9lb3Npbm9waGlscyIsICJmYWlsdXJlX2Vvc2lub3BoaWxzIiwKICAgICAgICAgICAgICAgICAgICAiY3VyZV9tb25vY3l0ZXMiLCAiZmFpbHVyZV9tb25vY3l0ZXMiLCAiY3VyZV9uZXV0cm9waGlscyIsICJmYWlsdXJlX25ldXRyb3BoaWxzIikKbmV3X2ZhY3QgPC0gZmFjdG9yKAogICAgcGFzdGUwKHBEYXRhKHRfY2xpbmljYWwpW1siY29uZGl0aW9uIl1dLCAiXyIsCiAgICAgICAgICAgcERhdGEodF9jbGluaWNhbClbWyJiYXRjaCJdXSksCiAgICBsZXZlbHMgPSBkZXNpcmVkX2xldmVscykKCnRfY2xpbmljYWxfY29uY2F0IDwtIHNldF9leHB0X2NvbmRpdGlvbnModF9jbGluaWNhbCwgZmFjdCA9IG5ld19mYWN0KSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbImNmX3R5cGUiXV0pICU+JQogIHN1YnNldF9leHB0KHN1YnNldD0idHlwZW9mY2VsbHMhPSdiaW9wc3knIikKCiMjIFRyeSB0byBlbnN1cmUgdGhhdCB0aGUgbGV2ZWxzIHN0YXkgaW4gdGhlIG9yZGVyIEkgd2FudAptZXRhIDwtIHBEYXRhKHRfY2xpbmljYWxfY29uY2F0KSAlPiUKICBtdXRhdGUoY29uZGl0aW9uID0gZmN0X3JlbGV2ZWwoY29uZGl0aW9uLCBkZXNpcmVkX2xldmVscykpCnBEYXRhKHRfY2xpbmljYWxfY29uY2F0KSA8LSBtZXRhCmBgYAoKIyMjIFZpc3VhbGl6ZTogTG9vayBhdCBUdW1hY28tb25seSBzYW1wbGVzIGJ5IGNlbGwgdHlwZSBhbmQgY3VyZS9mYWlsCgpUaGUgZm9sbG93aW5nIGJsb2NrIGlzIHByZXR0eSB3aWxkIHRvIG15IGV5ZXM7IGl0IHNlZW1zIHRvIG1lIHRoYXQgdGhlCnZhcmlhbmNlcyBpbnRyb2R1Y2VkIGJ5IGNlbGwgdHlwZSBiYXNpY2FsbHkgd2lwZSBvdXQgdGhlIGFwcGFyZW50CmRpZmZlcmVuY2VzIGJldHdlZW4gY3VyZS9mYWlsIHRoYXQgd2Ugd2VyZSBhYmxlIHRvIHNlZSBwcmV2aW91c2x5LgoKSSBzdXBwb3NlIHRoaXMgaXMgbm90IGVudGlyZWx5IHN1cnByaXNpbmcsIGJ1dCB3aGVuIHdlIGhhZCB0aGUgQ2FsaQpzYW1wbGVzIGl0IGF0IGxlYXN0IGxvb2tlZCBsaWtlIHRoZXJlIHdlcmUgZGlmZmVyZW5jZXMgd2hpY2ggd2VyZQpleHBsaWNpdGx5IGJldHdlZW4gY3VyZS9mYWlsIGFjcm9zcyBjZWxsIHR5cGVzLiAgSSBzdXBwb3NlIHRoaXMgbWVhbnMKdGhvc2UgZGlmZmVyZW5jZXMgd2VyZSBhY3R1YWxseSBjb21pbmcgZnJvbSB0aGUgdW5iYWxhbmNlZCBzdGF0ZSBvZgp0aGUgdHdvIGNsaW5pY3MgZnJvbSB0aGUgcGVyc3BlY3RpdmUgb2YgY2xpbmljLgoKYGBge3J9CnRfY2xpbmljYWxfY29uY2F0X25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9jbGluaWNhbF9jb25jYXQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKdF9jbGluaWNhbF9jb25jYXRfbm9ybV9wY2EgPC0gcGxvdF9wY2EodF9jbGluaWNhbF9jb25jYXRfbm9ybSkKdF9jbGluaWNhbF9jb25jYXRfbm9ybV9wY2EkcGxvdAoKdF9jbGluaWNhbF9jb25jYXRfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9jbGluaWNhbF9jb25jYXQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X2NsaW5pY2FsX2NvbmNhdF9uYl9wY2EgPC0gcGxvdF9wY2EodF9jbGluaWNhbF9jb25jYXRfbmIpCnRfY2xpbmljYWxfY29uY2F0X25iX3BjYSRwbG90CmBgYAoKIyBWaXNpdCBjb21wYXJpc29ucwoKTGV0IHVzIHNoaWZ0IHRoZSBmb2N1cyBmcm9tIGNlbGwgdHlwZSBhbmQvb3IgQ3VyZS9GYWlsIHRvIHRoZSB2aXNpdApudW1iZXIuICBBcyB5b3UgYXJlIGxpa2VseSBhd2FyZSwgdGhlIHRocmVlIHZpc2l0cyBhcmUgc2lnbmlmaWNhbnRseQpzcHJlYWQgYXBhcnQgYWNjb3JkaW5nIHRvIHRoZSBjbGluaWNhbCB0cmVhdG1lbnQgb2YgZWFjaCBwYXRpZW50LgpUaHVzIHdlIHdpbGwgbm93IHNlcGFyYXRlIHRoZSBzYW1wbGVzIGJ5IHZpc2l0IGluIG9yZGVyIHRvIG1vcmUgZWFzaWx5CnNlZSB3aGF0IG5ldyBwYXR0ZXJucyBlbWVyZ2UuCgojIyBSZWNhdGVnb3JpemU6IEFsbCB2aXNpdHMgdG9nZXRoZXIKCk5vdyBsZXQgdXMgc2hpZnQgdGhlIHZpZXcgc2xpZ2h0bHkgdG8gZm9jdXMgb24gY2hhbmdlcyBvYnNlcnZlZCBvdmVyIHRpbWUuCgpJIGhhdmUgYSBub3RlIGZyb20gTWFyaWEgQWRlbGFpZGEgdGhhdCBzaGUgd291bGQgbGlrZSB0byBmbGVzaCB0aGlzCnNlY3Rpb24gb3V0IHdpdGggc29tZSBtb3JlIHBkZiB2ZXJzaW9ucyBvZiB2YXJpb3VzIHByZS9wb3N0IFNWQSBwbG90cy4KSWYgSSB1bmRlcnN0b29kL3dyb3RlIGRvd24gY29ycmVjdGx5IGhlciBnb2FsczoKCjEuICAzIHZpc2l0cywgYWxsIGNlbGwgdHlwZXMuCjIuICAzIHZpc2l0cywgYWxsIGNsaW5pY2FsIGNlbGwgdHlwZXMgKGUuZy4gbm8gYmlvcHNpZXMpLCBvbmx5IFR1bWFjbwozLiAgIzEsICMyIGFmdGVyIHN2YQo0LiAgUmVwZWF0IHRoZSBvbmx5IEMvRiBieSB2aXNpdCB3aXRoL291dCBTVkEgYW5kIG1ha2UgcHJldHR5IHZlcnNpb25zLgoKYGBge3J9CnRjX3Zpc2l0X2V4cHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0Y19jbGluaWNhbCwgZmFjdCA9ICJ2aXNpdG51bWJlciIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbInZpc2l0MiJdXSkKdGNfdmlzaXRfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0Y192aXNpdF9leHB0LCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydCA9ICJjcG0iLCBub3JtID0gInF1YW50IikKdGNfdmlzaXRfbm9ybV9wY2EgPC0gcGxvdF9wY2EodGNfdmlzaXRfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvdGNfdmlzaXRfbm9ybV9hbGx0eXBlcy5wZGYiKQp0Y192aXNpdF9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQp0Y192aXNpdF9ub3JtX3BjYQoKdGNfdmlzaXRfbmIgPC0gbm9ybWFsaXplX2V4cHQodGNfdmlzaXRfZXhwdCwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gInN2YXNlcSIpCnRjX3Zpc2l0X25iX3BjYSA8LSBwbG90X3BjYSh0Y192aXNpdF9uYikKcHAoZmlsZSA9ICJpbWFnZXMvdGNfdmlzaXRfc3ZhX2FsbHR5cGVzLnBkZiIpCnRjX3Zpc2l0X25iX3BjYSRwbG90CmRldi5vZmYoKQp0Y192aXNpdF9uYl9wY2EKCiMjICBSZXBlYXQgZm9yIG9ubHkgVHVtYWNvCnRfdmlzaXRfZXhwdCA8LSBzdWJzZXRfZXhwdCh0Y19jbGluaWNhbCwgc3Vic2V0ID0gImNsaW5pYz09J3R1bWFjbyciKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAidmlzaXRudW1iZXIiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJ2aXNpdDIiXV0pCnRfdmlzaXRfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0X2V4cHQsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIG5vcm0gPSAicXVhbnQiKQp0X3Zpc2l0X25vcm1fcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvdF92aXNpdF9ub3JtX2FsbHR5cGVzLnBkZiIpCnRfdmlzaXRfbm9ybV9wY2EkcGxvdApkZXYub2ZmKCkKdF92aXNpdF9ub3JtX3BjYQoKdF92aXNpdF9uYiA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0X2V4cHQsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gInN2YXNlcSIpCnRfdmlzaXRfbmJfcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL3RfdmlzaXRfc3ZhX2FsbHR5cGVzLnBkZiIpCnRfdmlzaXRfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRfdmlzaXRfbmJfcGNhCgojIyBGaW5hbGx5LCBsaW1pdCB0byBvbmx5IHRoZSBjbGluaWNhbCBjZWxsdHlwZXMKdF92aXNpdF9jbGluaWNhbF9leHB0IDwtIHN1YnNldF9leHB0KHRfdmlzaXRfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzIT0nYmlvcHN5JyIpCnRfdmlzaXRfY2xpbmljYWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0X2NsaW5pY2FsX2V4cHQsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJxdWFudCIpCnRfdmlzaXRfY2xpbmljYWxfbm9ybV9wY2EgPC0gcGxvdF9wY2EodF92aXNpdF9jbGluaWNhbF9ub3JtKQpwcChmaWxlID0gImltYWdlcy90X3Zpc2l0X2NsaW5pY2FsX25vcm1fYWxsdHlwZXMucGRmIikKdF92aXNpdF9jbGluaWNhbF9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQp0X3Zpc2l0X2NsaW5pY2FsX25vcm1fcGNhCgp0X3Zpc2l0X2NsaW5pY2FsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfdmlzaXRfY2xpbmljYWxfZXhwdCwgZmlsdGVyID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwgYmF0Y2ggPSAic3Zhc2VxIikKdF92aXNpdF9jbGluaWNhbF9uYl9wY2EgPC0gcGxvdF9wY2EodF92aXNpdF9jbGluaWNhbF9uYikKcHAoZmlsZSA9ICJpbWFnZXMvdF92aXNpdF9ub2Jpb3Bfc3ZhX2FsbHR5cGVzLnBkZiIpCnRfdmlzaXRfY2xpbmljYWxfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRfdmlzaXRfY2xpbmljYWxfbmJfcGNhCmBgYAoKV2hlbiBsb29raW5nIGF0IGFsbCBjZWxsIHR5cGVzLCBpdCBpcyBxdWl0ZSBkaWZmaWN1bHQgdG8gc2VlCmRpZmZlcmVuY2VzIGFtb25nIHRoZSB0aHJlZSB2aXNpdHMuCgojIyBWaXN1YWxpemU6IEMvRiBmb3Igb25seSB0aGUgdmlzaXQgMSBzYW1wbGVzCgpXZW4gd2UgaGFkIGJvdGggQ2FsaSBhbmQgVHVtYWNvIHNhbXBsZXMsIGl0IGxvb2tlZCBsaWtlIHRoZXJlIHdhcwp2YXJpYW5jZSBzdWdnZXN0aW5nIGRpZmZlcmVuY2VzIGJldHdlZW4gY3VyZSBhbmQgZmFpbCBmb3IgdmlzaXQgMS4gIEkKdGhpbmsgdGhlIGZvbGxvd2luZyBibG9jayB3aWxsIHN1Z2dlc3QgcHJldHR5IHN0cm9uZ2x5IHRoYXQgdGhpcyB3YXMKbm90IHRydWUuCgpgYGB7cn0KdHYxX3NhbXBsZXMgPC0gc2V0X2V4cHRfYmF0Y2hlcyh0djFfc2FtcGxlcywgZmFjdCA9ICJ0eXBlb2ZjZWxscyIpCnR2MV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHR2MV9zYW1wbGVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKdHYxX3BjYSA8LSBwbG90X3BjYSh0djFfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvdHYxX3BjYS5wZGYiKQp0djFfcGNhCmRldi5vZmYoKQp0djFfcGNhJHBsb3QKCnR2MV9uYiA8LSBub3JtYWxpemVfZXhwdCh0djFfc2FtcGxlcywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0djFfbmJfcGNhIDwtIHBsb3RfcGNhKHR2MV9uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKcHAoZmlsZSA9ICJpbWFnZXMvdHYxX3N2YV9wY2EucGRmIikKdHYxX25iX3BjYSRwbG90CmRldi5vZmYoKQp0djFfbmJfcGNhCmBgYAoKIyMgVmlzdWFsaXplOiBDL0YgZm9yIG9ubHkgdGhlIHZpc2l0IDIgc2FtcGxlcwoKYGBge3J9CnR2Ml9zYW1wbGVzIDwtIHNldF9leHB0X2JhdGNoZXModHYyX3NhbXBsZXMsIGZhY3QgPSAidHlwZW9mY2VsbHMiKQp0djJfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0djJfc2FtcGxlcywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnR2Ml9wY2EgPC0gcGxvdF9wY2EodHYyX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL3R2Ml9wY2EucGRmIikKdHYyX3BjYQpkZXYub2ZmKCkKdHYyX3BjYSRwbG90Cgp0djJfbmIgPC0gbm9ybWFsaXplX2V4cHQodHYyX3NhbXBsZXMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKdHYyX25iX3BjYSA8LSBwbG90X3BjYSh0djJfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiaW1hZ2VzL3R2Ml9zdmFfcGNhLnBkZiIpCnR2Ml9uYl9wY2EkcGxvdApkZXYub2ZmKCkKdHYyX25iX3BjYQpgYGAKCiMjIFZpc3VhbGl6ZTogQy9GIGZvciBvbmx5IHRoZSB2aXNpdCAzIHNhbXBsZXMKCmBgYHtyfQp0djNfc2FtcGxlcyA8LSBzZXRfZXhwdF9iYXRjaGVzKHR2M19zYW1wbGVzLCBmYWN0ID0gInR5cGVvZmNlbGxzIikKdHYzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodHYzX3NhbXBsZXMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQp0djNfcGNhIDwtIHBsb3RfcGNhKHR2M19ub3JtKQpwcChmaWxlID0gImltYWdlcy90djNfcGNhLnBkZiIpCnR2M19wY2EKZGV2Lm9mZigpCnR2M19wY2EkcGxvdAoKdHYzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHR2M19zYW1wbGVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnR2M19uYl9wY2EgPC0gcGxvdF9wY2EodHYzX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImltYWdlcy90djNfc3ZhX3BjYS5wZGYiKQp0djNfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnR2M19uYl9wY2EKYGBgCgojIyMgVmlzdWFsaXplOiBDb21wYXJpbmcgMyB2aXNpdHMgYnkgY2VsbCB0eXBlCgpTZXBhcmF0ZSB0aGUgc2FtcGxlcyBieSBjZWxsIHR5cGUgaW4gb3JkZXIgdG8gbW9yZSBlYXNpbHkgb2JzZXJ2ZQpwYXR0ZXJucyB3aXRoIHJlc3BlY3QgdG8gdmlzaXQgYW5kIGNsaW5pY2FsIG91dGNvbWUuCgojIyMjIE1vbm9jeXRlcyBhY3Jvc3MgdmlzaXRzCgpJbiB0aGUgZm9sbG93aW5nIGZldyBibG9ja3Mgd2UgYXJlIGNvbG9yaW5nIHRoZSBzYW1wbGVzIGJ5IHZpc2l0IGFuZApmaW5hbCBvdXRjb21lLiAgV2UgYXJlIGFsc28gc2VwYXJhdGluZyB0aGUgdGhyZWUgcHJpbWFyeSBjZWxsdHlwZXMgb2YKaW50ZXJlc3QuICBJZiBJIHVuZGVyc3RhbmQgY29ycmVjdGx5LCBNYXJpYSBBZGVsYWlkYSBoYXMgYW4gaW50ZXJlc3QKaW4gYSBuaWNlIHZlcnNpb24gb2YgZWFjaCBvZiB0aGVzZSA2IHBsb3RzIChub3JtYWxpemVkIHBjYQpiZWZvcmUvYWZ0ZXIgU1ZBIGZvciBlYWNoIGNlbGx0eXBlKS4KCmBgYHtyfQp0X3Zpc2l0Y2ZfbW9ub2N5dGVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0Y2ZfbW9ub2N5dGUsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQp0X3Zpc2l0Y2ZfbW9ub2N5dGVfcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRjZl9tb25vY3l0ZV9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImltYWdlcy90X21vbm9jeXRlX3Zpc2l0Y2Zfbm9ybV9wY2EucGRmIikKdF92aXNpdGNmX21vbm9jeXRlX3BjYSRwbG90CmRldi5vZmYoKQp0X3Zpc2l0Y2ZfbW9ub2N5dGVfcGNhCgp0X3Zpc2l0Y2ZfbW9ub2N5dGVfZGlzaGVhdCA8LSBwbG90X2Rpc2hlYXQodF92aXNpdGNmX21vbm9jeXRlX25vcm0pCnRfdmlzaXRjZl9tb25vY3l0ZV9kaXNoZWF0JHBsb3QKCnRfdmlzaXRjZl9tb25vY3l0ZV9uYiA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0Y2ZfbW9ub2N5dGUsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0X3Zpc2l0Y2ZfbW9ub2N5dGVfbmJfcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRjZl9tb25vY3l0ZV9uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKcHAoZmlsZSA9ICJpbWFnZXMvdF9tb25vY3l0ZV92aXNpdGNmX3N2YV9wY2EucGRmIikKdF92aXNpdGNmX21vbm9jeXRlX25iX3BjYSRwbG90CmRldi5vZmYoKQp0X3Zpc2l0Y2ZfbW9ub2N5dGVfbmJfcGNhCmBgYAoKIyMjIyBFb3Npbm9waGlscyBhY3Jvc3MgdmlzaXRzCgpSZXBlYXQgdGhlIGFib3ZlIHdpdGggRW9zaW5vcGhpbHMsIHdlIHNob3VsZCB0aGVyZWZvcmUgaGF2ZSBzbGlnaHRseQpmZXdlciBnbHlwaHMgb24gdGhlIHBsb3QuCgpgYGB7cn0KdF92aXNpdGNmX2Vvc2lub3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0Y2ZfZW9zaW5vcGhpbCwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnRfdmlzaXRjZl9lb3Npbm9waGlsX3BjYSA8LSBwbG90X3BjYSh0X3Zpc2l0Y2ZfZW9zaW5vcGhpbF9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImltYWdlcy90X2Vvc2lub3BoaWxfdmlzaXRjZl9ub3JtX3BjYS5wZGYiKQp0X3Zpc2l0Y2ZfZW9zaW5vcGhpbF9wY2EkcGxvdApkZXYub2ZmKCkKdF92aXNpdGNmX2Vvc2lub3BoaWxfcGNhCgp0X3Zpc2l0Y2ZfZW9zaW5vcGhpbF9kaXNoZWF0IDwtIHBsb3RfZGlzaGVhdCh0X3Zpc2l0Y2ZfZW9zaW5vcGhpbF9ub3JtKQp0X3Zpc2l0Y2ZfZW9zaW5vcGhpbF9kaXNoZWF0JHBsb3QKCnRfdmlzaXRjZl9lb3Npbm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfdmlzaXRjZl9lb3Npbm9waGlsLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKdF92aXNpdGNmX2Vvc2lub3BoaWxfbmJfcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRjZl9lb3Npbm9waGlsX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImltYWdlcy90X2Vvc2lub3BoaWxfdmlzaXRjZl9zdmFfcGNhLnBkZiIpCnRfdmlzaXRjZl9lb3Npbm9waGlsX25iX3BjYSRwbG90CmRldi5vZmYoKQp0X3Zpc2l0Y2ZfZW9zaW5vcGhpbF9uYl9wY2EKYGBgCgojIyMjIE5ldXRyb3BoaWxzIGFjcm9zcyB2aXNpdHMKCmBgYHtyfQp0X3Zpc2l0Y2ZfbmV1dHJvcGhpbF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfdmlzaXRjZl9uZXV0cm9waGlsLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSkKdF92aXNpdGNmX25ldXRyb3BoaWxfcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRjZl9uZXV0cm9waGlsX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiaW1hZ2VzL3RfbmV1dHJvcGhpbF92aXNpdGNmX25vcm1fcGNhLnBkZiIpCnRfdmlzaXRjZl9uZXV0cm9waGlsX3BjYSRwbG90CmRldi5vZmYoKQp0X3Zpc2l0Y2ZfbmV1dHJvcGhpbF9wY2EKCnRfdmlzaXRjZl9uZXV0cm9waGlsX2Rpc2hlYXQgPC0gcGxvdF9kaXNoZWF0KHRfdmlzaXRjZl9uZXV0cm9waGlsX25vcm0pCnRfdmlzaXRjZl9uZXV0cm9waGlsX2Rpc2hlYXQkcGxvdAoKdF92aXNpdGNmX25ldXRyb3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQodF92aXNpdGNmX25ldXRyb3BoaWwsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp0X3Zpc2l0Y2ZfbmV1dHJvcGhpbF9uYl9wY2EgPC0gcGxvdF9wY2EodF92aXNpdGNmX25ldXRyb3BoaWxfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiaW1hZ2VzL3RfbmV1dHJvcGhpbF92aXNpdGNmX3N2YV9wY2EucGRmIikKdF92aXNpdGNmX25ldXRyb3BoaWxfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnRfdmlzaXRjZl9uZXV0cm9waGlsX25iX3BjYQpgYGAKCiMjIyMgQ2VsbHR5cGVzIGJ5IHZpc2l0LCBDL0YgYmF0Y2g6IE1vbm9jeXRlcwoKV2UgYXJlIGJhY2tpbmcgb2ZmIHRoZSBncmFudWxhciB2aWV3IG9mIHZpc2l0IGFuZCBGYWlsL0N1cmUgaW4gdGhlCmZvbGxvd2luZyBibG9jayBhbmQgaW5zdGVhZCBqdXN0IGNvbnNpZGVyaW5nIHRoZSB0aHJlZSB2aXNpdHMuICBUaGlzCnByZXZpb3VzbHkgb25seSBjb25zaWRlcmVkIHRoZSBub3JtYWxpemVkIHJlc3VsdCwgbm93IHdlIHdpc2ggdG8gYWRkCnRoZSBzdmEgbW9kaWZpZWQgcmVzdWx0IGFuZCBwcmludCBvdXQgcGRmcyB0aGVyZW9mLiAgT25jZSBhZ2Fpbiwgd2UKYXJlIHJlcGVhdGluZyAzIHRpbWVzLCBvbmNlIGZvciBlYWNoIGNlbGwgdHlwZS4KCmBgYHtyfQp0X3Zpc2l0X21vbm9jeXRlIDwtIHNldF9leHB0X2NvbmRpdGlvbnModF92aXNpdGNmX21vbm9jeXRlLCBwcmVmaXggPSAidiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0ID0gInZpc2l0bnVtYmVyIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcygiZmluYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJ2aXNpdCJdXSkKdF92aXNpdF9tb25vY3l0ZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfdmlzaXRfbW9ub2N5dGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQoKdF92aXNpdF9tb25vY3l0ZV9ub3JtX3BjYSA8LSBwbG90X3BjYSh0X3Zpc2l0X21vbm9jeXRlX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiZmlndXJlcy90X21vbm9jeXRlX3Zpc2l0X25vcm1fcGNhLnN2ZyIpCnRfdmlzaXRfbW9ub2N5dGVfbm9ybV9wY2FbWyJwbG90Il1dCmRldi5vZmYoKQp0X3Zpc2l0X21vbm9jeXRlX25vcm1fcGNhCnRfdmlzaXRjZl9tb25vY3l0ZV9uYiA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0Y2ZfbW9ub2N5dGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfdmlzaXRjZl9tb25vY3l0ZV9uYl9wY2EgPC0gcGxvdF9wY2EodF92aXNpdGNmX21vbm9jeXRlX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvdF9tb25vY3l0ZV92aXNpdF9zdmFfcGNhLnN2ZyIpCnRfdmlzaXRjZl9tb25vY3l0ZV9uYl9wY2FbWyJwbG90Il1dCmRldi5vZmYoKQp0X3Zpc2l0Y2ZfbW9ub2N5dGVfbmJfcGNhCmBgYAoKIyMjIyBDZWxsdHlwZXMgYnkgdmlzaXQsIEMvRiBiYXRjaDogRW9zaW5vcGhpbHMKCmBgYHtyfQp0X3Zpc2l0X2Vvc2lub3BoaWwgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X3Zpc2l0Y2ZfZW9zaW5vcGhpbCwgcHJlZml4ID0gInYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3QgPSAidmlzaXRudW1iZXIiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKCJmaW5hbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbInZpc2l0Il1dKQp0X3Zpc2l0X2Vvc2lub3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3Zpc2l0X2Vvc2lub3BoaWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKdF92aXNpdF9lb3Npbm9waGlsX25vcm1fcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRfZW9zaW5vcGhpbF9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImZpZ3VyZXMvdF9lb3Npbm9waGlsX3Zpc2l0X25vcm1fcGNhLnN2ZyIpCnRfdmlzaXRfZW9zaW5vcGhpbF9ub3JtX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCnRfdmlzaXRfZW9zaW5vcGhpbF9ub3JtX3BjYQp0X3Zpc2l0X2Vvc2lub3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQodF92aXNpdF9lb3Npbm9waGlsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X3Zpc2l0X2Vvc2lub3BoaWxfbmJfcGNhIDwtIHBsb3RfcGNhKHRfdmlzaXRfZW9zaW5vcGhpbF9uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKcHAoZmlsZSA9ICJmaWd1cmVzL3RfZW9zaW5vcGhpbF92aXNpdF9zdmFfcGNhLnN2ZyIpCnRfdmlzaXRfZW9zaW5vcGhpbF9uYl9wY2FbWyJwbG90Il1dCmRldi5vZmYoKQp0X3Zpc2l0X2Vvc2lub3BoaWxfbmJfcGNhCmBgYAoKIyMjIyBDZWxsdHlwZXMgYnkgdmlzaXQsIEMvRiBiYXRjaDogTmV1dHJvcGhpbHMKCmBgYHtyfQp0X3Zpc2l0X25ldXRyb3BoaWwgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X3Zpc2l0Y2ZfbmV1dHJvcGhpbCwgcHJlZml4ID0gInYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0ID0gInZpc2l0bnVtYmVyIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcygiZmluYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJ2aXNpdCJdXSkKdF92aXNpdF9uZXV0cm9waGlsX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF92aXNpdF9uZXV0cm9waGlsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnRfdmlzaXRfbmV1dHJvcGhpbF9ub3JtX3BjYSA8LSBwbG90X3BjYSh0X3Zpc2l0X25ldXRyb3BoaWxfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkKcHAoZmlsZSA9ICJmaWd1cmVzL3RfbmV1dHJvcGhpbF92aXNpdF9ub3JtX3BjYS5zdmciKQp0X3Zpc2l0X25ldXRyb3BoaWxfbm9ybV9wY2FbWyJwbG90Il1dCmRldi5vZmYoKQp0X3Zpc2l0X25ldXRyb3BoaWxfbm9ybV9wY2EKdF92aXNpdF9uZXV0cm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfdmlzaXRfbmV1dHJvcGhpbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF92aXNpdF9uZXV0cm9waGlsX25iX3BjYSA8LSBwbG90X3BjYSh0X3Zpc2l0X25ldXRyb3BoaWxfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpCnBwKGZpbGUgPSAiZmlndXJlcy90X25ldXRyb3BoaWxfdmlzaXRfc3ZhX3BjYS5zdmciKQp0X3Zpc2l0X25ldXRyb3BoaWxfbmJfcGNhW1sicGxvdCJdXQpkZXYub2ZmKCkKdF92aXNpdF9uZXV0cm9waGlsX25iX3BjYQpgYGAKCiMgUGVyc2lzdGVuY2UKCiMjIyBUYWtlIGEgbG9vawoKU2VlIGlmIHRoZXJlIGFyZSBhbnkgcGF0dGVybnMgd2hpY2ggbG9vayB1c2FibGUuCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyMgQWxsCnRfcGVyc2lzdGVuY2Vfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3BlcnNpc3RlbmNlLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EodF9wZXJzaXN0ZW5jZV9ub3JtKSRwbG90CnRfcGVyc2lzdGVuY2VfbmIgPC0gbm9ybWFsaXplX2V4cHQodF9wZXJzaXN0ZW5jZSwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHRfcGVyc2lzdGVuY2VfbmIpJHBsb3QKCiMjIEJpb3BzaWVzCiMjcGVyc2lzdGVuY2VfYmlvcHN5X25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfYmlvcHN5LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQojI3Bsb3RfcGNhKHBlcnNpc3RlbmNlX2Jpb3BzeV9ub3JtKSRwbG90CiMjIEluc3VmZmljaWVudCBkYXRhCgojIyBNb25vY3l0ZXMKdF9wZXJzaXN0ZW5jZV9tb25vY3l0ZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHRfcGVyc2lzdGVuY2VfbW9ub2N5dGUsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHRfcGVyc2lzdGVuY2VfbW9ub2N5dGVfbm9ybSkkcGxvdAp0X3BlcnNpc3RlbmNlX21vbm9jeXRlX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfcGVyc2lzdGVuY2VfbW9ub2N5dGUsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYSh0X3BlcnNpc3RlbmNlX21vbm9jeXRlX25iKSRwbG90CgojIyBOZXV0cm9waGlscwp0X3BlcnNpc3RlbmNlX25ldXRyb3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh0X3BlcnNpc3RlbmNlX25ldXRyb3BoaWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EodF9wZXJzaXN0ZW5jZV9uZXV0cm9waGlsX25vcm0pJHBsb3QKdF9wZXJzaXN0ZW5jZV9uZXV0cm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfcGVyc2lzdGVuY2VfbmV1dHJvcGhpbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHRfcGVyc2lzdGVuY2VfbmV1dHJvcGhpbF9uYikkcGxvdAoKIyMgRW9zaW5vcGhpbHMKdF9wZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodF9wZXJzaXN0ZW5jZV9lb3Npbm9waGlsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EodF9wZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25vcm0pJHBsb3QKdF9wZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHRfcGVyc2lzdGVuY2VfZW9zaW5vcGhpbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHRfcGVyc2lzdGVuY2VfZW9zaW5vcGhpbF9uYikkcGxvdApgYGAKCiMgQ2xhc3NpZnkgbWUhCgpJIHdyb3RlIG91dCBhbGwgdGhlIHoyLjIgYW5kIHoyLjMgc3BlY2lmaWMgdmFyaWFudHMgdG8gYSBjb3VwbGUgZmlsZXMsCkkgd2FudCB0byBzZWUgaWYgSSBjYW4gY2xhc3NpZnkgYSBodW1hbiBzYW1wbGUgYXMgaW5mZWN0ZWQgd2l0aCAyLjIgb3IKMi4zLgoKYGBge3IsIGV2YWw9RkFMU0V9CnoyMiA8LSByZWFkLmNzdigiY3N2L3ZhcmlhbnRzXzIyLmNzdiIpCnoyMyA8LSByZWFkLmNzdigiY3N2L3ZhcmlhbnRzXzIzLmNzdiIpCmN1cmUgPC0gcmVhZC5jc3YoImNzdi9jdXJlX3ZhcmlhbnRzLnR4dCIpCmZhaWwgPC0gcmVhZC5jc3YoImNzdi9mYWlsX3ZhcmlhbnRzLnR4dCIpCnoyMl92ZWMgPC0gZ3N1YihwYXR0ZXJuPSJcXC0iLCByZXBsYWNlbWVudD0iXyIsIHg9ejIyW1sieCJdXSkKejIzX3ZlYyA8LSBnc3ViKHBhdHRlcm49IlxcLSIsIHJlcGxhY2VtZW50PSJfIiwgeD16MjNbWyJ4Il1dKQpjdXJlX3ZlYyA8LSBnc3ViKHBhdHRlcm49IlxcLSIsIHJlcGxhY2VtZW50PSJfIiwgeD1jdXJlKQpmYWlsX3ZlYyA8LSBnc3ViKHBhdHRlcm49IlxcLSIsIHJlcGxhY2VtZW50PSJfIiwgeD1mYWlsKQoKY2xhc3NpZnlfenltbyA8LSBmdW5jdGlvbihzYW1wbGUpIHsKICBhcmJpdHJhcnlfdGFncyA8LSBzbShyZWFkcjo6cmVhZF90c3Yoc2FtcGxlKSkKICBhcmJpdHJhcnlfaWRzIDwtIGFyYml0cmFyeV90YWdzW1sicG9zaXRpb24iXV0KICBtZXNzYWdlKCJMZW5ndGg6ICIsIGxlbmd0aChhcmJpdHJhcnlfaWRzKSwgIiwgejIyOiAiLAogICAgICAgICAgc3VtKGFyYml0cmFyeV9pZHMgJWluJSB6MjJfdmVjKSAvIChsZW5ndGgoejIyX3ZlYykpLCAiIHoyMzogIiwKICAgICAgICAgIHN1bShhcmJpdHJhcnlfaWRzICVpbiUgejIzX3ZlYykgLyAobGVuZ3RoKHoyM192ZWMpKSkKfQoKYXJiaXRyYXJ5X3NhbXBsZSA8LSAicHJlcHJvY2Vzc2luZy9UTVJDMzAxNTYvb3V0cHV0cy80MGZyZWViYXllc19scGFuYW1lbnNpc192MzYvYWxsX3RhZ3MudHh0Lnh6IgpjbGFzc2lmeV96eW1vKGFyYml0cmFyeV9zYW1wbGUpCmBgYAoKIyBWaXN1YWxpemluZyBjb21wb3NpdGUgc2NvcmVzCgpGaXJzdCBsZXRzIGdldCB0aGUgZ2VuZSBJRHMgYW5kIGNvbG9ycyBmb3IgdGhlc2UgcGxvdHMuCgpgYGB7cn0KbGlicmFyeSh2aXJpZGlzKQp3YW50ZWRfZ2VuZXMgPC0gYygiSUZJNDRMIiwgIklGSTI3IiwgIlBSUjUiLCAiUFJSNS1BUkhHQVA4IiwgIlJIQ0UiLAogICAgICAgICAgICAgICAgICAiRkJYTzM5IiwgIlJTQUQyIiwgIlNNVE5MMSIsICJVU1AxOCIsICJBRkFQMSIpCndhbnRlZF9pZHggPC0gZkRhdGEodGNfdmFsaWQpW1siaGduY19zeW1ib2wiXV0gJWluJSB3YW50ZWRfZ2VuZXMKd2FudGVkX2lkcyA8LSByb3duYW1lcyhmRGF0YSh0Y192YWxpZCkpW3dhbnRlZF9pZHhdCmBgYAoKIyMgQWxsIHNhbXBsZXMsIGFsbCB2aXNpdHMKCmBgYHtyfQpmZXcgPC0gIHN1YnNldF9nZW5lcyh0Y192YWxpZCwgaWRzID0gd2FudGVkX2lkcywgbWV0aG9kID0gImtlZXAiKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgbm9ybWFsaXplX2V4cHQodHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gInJwa20iLAogICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJtZWFuX2Nkc19sZW4iKQpzaHAgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChmZXcsIGhlYXRtYXBfY29sb3JzID0gdmlyaWRpcywgcm93X2xhYmVsID0gd2FudGVkX2dlbmVzKQpzaHAKCmZldyA8LSAgc3Vic2V0X2dlbmVzKHRfY2xpbmljYWwsIGlkcyA9IHdhbnRlZF9pZHMsIG1ldGhvZCA9ICJrZWVwIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImZpbmFsb3V0Y29tZSIpICU+JQogIG5vcm1hbGl6ZV9leHB0KHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJycGttIiwKICAgICAgICAgICAgICAgICBjb2x1bW4gPSAibWVhbl9jZHNfbGVuIikKc2hwIDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZmV3LCBoZWF0bWFwX2NvbG9ycyA9IHZpcmlkaXMsIHJvd19sYWJlbCA9IHdhbnRlZF9nZW5lcykKc2hwCmBgYAoKIyMgQWxsIHNhbXBsZXMsIHZpc2l0IDEKCmBgYHtyfQpmZXcgPC0gc3Vic2V0X2dlbmVzKHRjX2NsaW5pY2FsLCBpZHMgPSB3YW50ZWRfaWRzLCBtZXRob2QgPSAia2VlcCIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQgPSAidmlzaXRudW1iZXI9PScxJyIpICU+JQogIG5vcm1hbGl6ZV9leHB0KHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJycGttIiwKICAgICAgICAgICAgICAgICBjb2x1bW4gPSAibWVhbl9jZHNfbGVuIikKc2hwIDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZmV3LCBoZWF0bWFwX2NvbG9ycyA9IHZpcmlkaXMsIHJvd19sYWJlbCA9IHdhbnRlZF9nZW5lcykKc2hwCgpmZXcgPC0gc3Vic2V0X2dlbmVzKHRfY2xpbmljYWwsIGlkcyA9IHdhbnRlZF9pZHMsIG1ldGhvZCA9ICJrZWVwIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImZpbmFsb3V0Y29tZSIpICU+JQogIHN1YnNldF9leHB0KHN1YnNldCA9ICJ2aXNpdG51bWJlcj09JzEnIikgJT4lCiAgbm9ybWFsaXplX2V4cHQodHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gInJwa20iLAogICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJtZWFuX2Nkc19sZW4iKQpzaHAgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChmZXcsIGhlYXRtYXBfY29sb3JzID0gdmlyaWRpcywgcm93X2xhYmVsID0gd2FudGVkX2dlbmVzKQpzaHAKYGBgCgojIyBFb3Npbm9waGlscywgYWxsIHRpbWVzCgpgYGB7cn0KZmV3IDwtICBzdWJzZXRfZ2VuZXModGNfZW9zaW5vcGhpbHMsIGlkcyA9IHdhbnRlZF9pZHMsIG1ldGhvZCA9ICJrZWVwIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImZpbmFsb3V0Y29tZSIpICU+JQogIG5vcm1hbGl6ZV9leHB0KHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJycGttIiwKICAgICAgICAgICAgICAgICBjb2x1bW4gPSAibWVhbl9jZHNfbGVuIikKc2hwIDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZmV3LCBoZWF0bWFwX2NvbG9ycyA9IHZpcmlkaXMsIHJvd19sYWJlbCA9IHdhbnRlZF9nZW5lcykKc2hwCgpmZXcgPC0gIHN1YnNldF9nZW5lcyh0X2Vvc2lub3BoaWxzLCBpZHMgPSB3YW50ZWRfaWRzLCBtZXRob2QgPSAia2VlcCIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBub3JtYWxpemVfZXhwdCh0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAicnBrbSIsCiAgICAgICAgICAgICAgICAgY29sdW1uID0gIm1lYW5fY2RzX2xlbiIpCnNocCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKGZldywgaGVhdG1hcF9jb2xvcnMgPSB2aXJpZGlzLCByb3dfbGFiZWwgPSB3YW50ZWRfZ2VuZXMpCnNocApgYGAKCiMjIEVvc2lub3BoaWxzLCB2MQoKYGBge3J9CmZldyA8LSAgc3Vic2V0X2dlbmVzKHRjX2Vvc2lub3BoaWxzLCBpZHMgPSB3YW50ZWRfaWRzLCBtZXRob2QgPSAia2VlcCIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQgPSAidmlzaXRudW1iZXI9PScxJyIpICU+JQogIG5vcm1hbGl6ZV9leHB0KHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJycGttIiwKICAgICAgICAgICAgICAgICBjb2x1bW4gPSAibWVhbl9jZHNfbGVuIikKc2hwIDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZmV3LCBoZWF0bWFwX2NvbG9ycyA9IHZpcmlkaXMsIHJvd19sYWJlbCA9IHdhbnRlZF9nZW5lcykKc2hwCgpmZXcgPC0gIHN1YnNldF9nZW5lcyh0X2Vvc2lub3BoaWxzLCBpZHMgPSB3YW50ZWRfaWRzLCBtZXRob2QgPSAia2VlcCIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQgPSAidmlzaXRudW1iZXI9PScxJyIpICU+JQogIG5vcm1hbGl6ZV9leHB0KHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJycGttIiwKICAgICAgICAgICAgICAgICBjb2x1bW4gPSAibWVhbl9jZHNfbGVuIikKc2hwIDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZmV3LCBoZWF0bWFwX2NvbG9ycyA9IHZpcmlkaXMsIHJvd19sYWJlbCA9IHdhbnRlZF9nZW5lcykKc2hwCmBgYAoKIyMgTW9ub2N5dGVzIGFsbAoKYGBge3J9CmZldyA8LSAgc3Vic2V0X2dlbmVzKHRjX21vbm9jeXRlcywgaWRzID0gd2FudGVkX2lkcywgbWV0aG9kID0gImtlZXAiKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgbm9ybWFsaXplX2V4cHQodHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gInJwa20iLAogICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJtZWFuX2Nkc19sZW4iKQpzaHAgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChmZXcsIGhlYXRtYXBfY29sb3JzID0gdmlyaWRpcywgcm93X2xhYmVsID0gd2FudGVkX2dlbmVzKQpzaHAKCmZldyA8LSAgc3Vic2V0X2dlbmVzKHRfbW9ub2N5dGVzLCBpZHMgPSB3YW50ZWRfaWRzLCBtZXRob2QgPSAia2VlcCIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJmaW5hbG91dGNvbWUiKSAlPiUKICBub3JtYWxpemVfZXhwdCh0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAicnBrbSIsCiAgICAgICAgICAgICAgICAgY29sdW1uID0gIm1lYW5fY2RzX2xlbiIpCnNocCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKGZldywgaGVhdG1hcF9jb2xvcnMgPSB2aXJpZGlzLCByb3dfbGFiZWwgPSB3YW50ZWRfZ2VuZXMpCnNocApgYGAKCiMjIE1vbm9jeXRlcyB2MQoKYGBge3J9CmZldyA8LSAgc3Vic2V0X2dlbmVzKHRjX21vbm9jeXRlcywgaWRzID0gd2FudGVkX2lkcywgbWV0aG9kID0gImtlZXAiKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0nMSciKSAlPiUKICBub3JtYWxpemVfZXhwdCh0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAicnBrbSIsCiAgICAgICAgICAgICAgICAgY29sdW1uID0gIm1lYW5fY2RzX2xlbiIpCnNocCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKGZldywgaGVhdG1hcF9jb2xvcnMgPSB2aXJpZGlzLCByb3dfbGFiZWwgPSB3YW50ZWRfZ2VuZXMpCnNocAoKZmV3IDwtICBzdWJzZXRfZ2VuZXModF9tb25vY3l0ZXMsIGlkcyA9IHdhbnRlZF9pZHMsIG1ldGhvZCA9ICJrZWVwIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImZpbmFsb3V0Y29tZSIpICU+JQogIHN1YnNldF9leHB0KHN1YnNldCA9ICJ2aXNpdG51bWJlcj09JzEnIikgJT4lCiAgbm9ybWFsaXplX2V4cHQodHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gInJwa20iLAogICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJtZWFuX2Nkc19sZW4iKQpzaHAgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChmZXcsIGhlYXRtYXBfY29sb3JzID0gdmlyaWRpcywgcm93X2xhYmVsID0gd2FudGVkX2dlbmVzKQpzaHAKYGBgCgojIyBOZXV0cm9waGlscyBhbGwKCmBgYHtyfQpmZXcgPC0gIHN1YnNldF9nZW5lcyh0Y19uZXV0cm9waGlscywgaWRzID0gd2FudGVkX2lkcywgbWV0aG9kID0gImtlZXAiKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgbm9ybWFsaXplX2V4cHQodHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gInJwa20iLAogICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJtZWFuX2Nkc19sZW4iKQpzaHAgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChmZXcsIGhlYXRtYXBfY29sb3JzID0gdmlyaWRpcywgcm93X2xhYmVsID0gd2FudGVkX2dlbmVzKQpzaHAKCmZldyA8LSAgc3Vic2V0X2dlbmVzKHRfbmV1dHJvcGhpbHMsIGlkcyA9IHdhbnRlZF9pZHMsIG1ldGhvZCA9ICJrZWVwIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImZpbmFsb3V0Y29tZSIpICU+JQogIG5vcm1hbGl6ZV9leHB0KHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJycGttIiwKICAgICAgICAgICAgICAgICBjb2x1bW4gPSAibWVhbl9jZHNfbGVuIikKc2hwIDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZmV3LCBoZWF0bWFwX2NvbG9ycyA9IHZpcmlkaXMsIHJvd19sYWJlbCA9IHdhbnRlZF9nZW5lcykKc2hwCmBgYAoKIyMgTmV1dHJvcGhpbHMgdjEKCmBgYHtyfQpmZXcgPC0gIHN1YnNldF9nZW5lcyh0Y19uZXV0cm9waGlscywgaWRzID0gd2FudGVkX2lkcywgbWV0aG9kID0gImtlZXAiKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0nMSciKSAlPiUKICBub3JtYWxpemVfZXhwdCh0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAicnBrbSIsCiAgICAgICAgICAgICAgICAgY29sdW1uID0gIm1lYW5fY2RzX2xlbiIpCnNocCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKGZldywgaGVhdG1hcF9jb2xvcnMgPSB2aXJpZGlzLCByb3dfbGFiZWwgPSB3YW50ZWRfZ2VuZXMpCnNocAoKZmV3IDwtICBzdWJzZXRfZ2VuZXModF9uZXV0cm9waGlscywgaWRzID0gd2FudGVkX2lkcywgbWV0aG9kID0gImtlZXAiKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiZmluYWxvdXRjb21lIikgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0nMSciKSAlPiUKICBub3JtYWxpemVfZXhwdCh0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAicnBrbSIsCiAgICAgICAgICAgICAgICAgY29sdW1uID0gIm1lYW5fY2RzX2xlbiIpCnNocCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKGZldywgaGVhdG1hcF9jb2xvcnMgPSB2aXJpZGlzLCByb3dfbGFiZWwgPSB3YW50ZWRfZ2VuZXMpCnNocApgYGAKCiMgQW4gZXh0ZXJuYWwgZGF0YXNldAoKTGV0IHVzIGxvb2sgYXQgYSBtb2RlcmF0ZWx5IHNpbWlsYXIgQmlvcHN5IGRhdGFzZXQgb2YgYnJhemlsaWVuc2lzCmluZmVjdGVkIGluZGl2aWR1YWxzLiAgRmlyc3QsIGxldHMgZG8gYSBxdWljayBwbG90IG9mIHRoZWlyIGRhdGEsIG91cgpiaW9wc2llcywgdGhlbiBjb21iaW5lIHRoZW0uCgojIyBMb2FkIHRoZSBkYXRhCgpgYGB7cn0KIyMgTG9hZCB0aGUgc2NvdHQtb25seSBhbmQgdGhlIHNjb3R0K3RtcmMzIGRhdGEKbG9hZChnbHVlKCJyZGEvdG1yYzNfZXh0ZXJuYWxfY2Ytdnt2ZXJ9LnJkYSIpKQpsb2FkKGdsdWUoInJkYS90bXJjM19leHRlcm5hbC12e3Zlcn0ucmRhIikpCmBgYAoKIyMgVmlzdWFsaXplIHRoZSB0d28gZGF0YXNldHMgaW5kaXZpZHVhbGx5CgpgYGB7cn0Kb3VyX2Jpb3BzaWVzIDwtIHNldF9leHB0X2NvbmRpdGlvbnModF9iaW9wc2llcywgImZpbmFsb3V0Y29tZSIpICU+JQogIHNldF9leHB0X2NvbG9ycyhjb2xvcl9jaG9pY2VzW1siY2YiXV0pCm91cl9iaW9wc2llc19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KG91cl9iaW9wc2llcywgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKG91cl9iaW9wc2llc19ub3JtKSRwbG90CgpzY290dF9iaW9wc2llc19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGV4dGVybmFsX2NmLCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydCA9ICJjcG0iLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYShzY290dF9iaW9wc2llc19ub3JtKSRwbG90CmBgYAoKIyMgVmlzdWFsaXplIHRoZW0gdG9nZXRoZXIKCmBgYHtyfQpib3RoX25vcm0gPC0gbm9ybWFsaXplX2V4cHQodG1yYzNfZXh0ZXJuYWwsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIG5vcm0gPSAicXVhbnQiKQpwbG90X3BjYShib3RoX25vcm0pJHBsb3QKYm90aF9uYiA8LSBub3JtYWxpemVfZXhwdCh0bXJjM19leHRlcm5hbCwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKGJvdGhfbmIpJHBsb3QKCmV4dGVybmFsX3NwZWNpZXMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0bXJjM19leHRlcm5hbCwgZmFjdCA9ICJQYXJhc2l0ZVNwZWNpZXMiKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQgPSAiUGFyYXNpdGVTcGVjaWVzIT0nbm90YXBwbGljYWJsZSciKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAibGFiIikKCnR0IDwtIG5vcm1hbGl6ZV9leHB0KGV4dGVybmFsX3NwZWNpZXMsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLCBub3JtID0gInF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EodHQpCnR0dCA8LSBub3JtYWxpemVfZXhwdChleHRlcm5hbF9zcGVjaWVzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwgYmF0Y2ggPSAic3Zhc2VxIiwKICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EodHR0KQpgYGAKCiMgUGFyYXNpdGUgZGlzdHJpYnV0aW9uCgpJIGFtIHJlc3VycmVjdGluZyBzb21lIG9mIHRoZSBjb21wYXJpc29ucyBvZiB0aGUgcGFyYXNpdGUgdHJhbnNjcmlwdG9tZSBpbiB0aGUgaG9zdCBkYXRhLgoKYGBge3J9CmxwX2NmIDwtIHNldF9leHB0X2NvbmRpdGlvbnMobHBfZXhwdCwgZmFjdCA9ICJmaW5hbG91dGNvbWUiKQoKdGFibGUocERhdGEobHBfY2YpW1sidHlwZW9mY2VsbHMiXV0pCgpscF9jZl9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGxwX2NmLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKbHBfY2Zfc20gPC0gcGxvdF9zbShscF9jZl9ub3JtKQpscF9jZl9zbQpscF9jZl9jb3JoZWF0IDwtIHBsb3RfY29yaGVhdChscF9jZl9ub3JtKQpscF9jZl9jb3JoZWF0CmxwX2NmX25vcm1fcGNhIDwtIHBsb3RfcGNhKGxwX2NmX25vcm0pCmxwX2NmX25vcm1fcGNhCnBwKGZpbGUgPSAiZmlndXJlcy9scF9jZl9ub3JtX3BjYS5zdmciKQpscF9jZl9ub3JtX3BjYVtbInBsb3QiXV0KZGV2Lm9mZigpCgpscF9jZl9uYiA8LSBub3JtYWxpemVfZXhwdChscF9jZiwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9ICJzaW1wbGUiKQpscF9jZl9uYl9wY2EgPC0gcGxvdF9wY2EobHBfY2ZfbmIpCmxwX2NmX25iX3BjYQpgYGAKCk5vdGUsIHRoZSBwcmV2aW91cyB0YXNrIGluY2x1ZGVzIHZpc2l0cyAyLzMgYW5kIG11bHRpcGxlIGNlbGwgdHlwZXMKYW5kIGFzIGEgcmVzdWx0IGlzIGxpa2VseSB0byBpbmNsdWRlIHRoZSBtb3N0IHByb2ZvdW5kbHkgaW5mZWN0ZWQKcGVvcGxlIChvbmx5IHRob3NlIGluIHdob20gd2Ugb2JzZXJ2ZSA+MzAsMDAwIHJlYWRzIGFuZCA+MywwMDAgZ2VuZXMKb2YgcGFyYXNpdGUgcmVhZHMuICBUaHVzLCBldmVuIHRob3VnaCBpdCBzb3J0IG9mIGxvb2tzIGxpa2UgdGhlcmUKX21pZ2h0XyBiZSBhIEMvRiBkaWZmZXJlbmNlLCB0aGUgc3ZhIHNob3dzIHRoYXQgdG8gYmUgYSBsaWUuCgpOb25ldGhlbGVzcywgd2UgY2FuIG1ha2UgdGhpcyBjbGVhcmVyIGJ5IGV4Y2x1ZGluZyB0aGUgdmlzaXRzMi8zCmFuZC9vciBub24tYmlvcHNpZXMuCgpgYGB7cn0KbHBfY2ZfYmlvcCA8LSBzdWJzZXRfZXhwdChscF9jZiwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nQmlvcHN5JyIpCgpscF9jZl9iaW9wX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobHBfY2ZfYmlvcCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKbHBfY2ZfYmlvcF9zbSA8LSBwbG90X3NtKGxwX2NmX2Jpb3Bfbm9ybSkKbHBfY2ZfYmlvcF9zbQpscF9jZl9iaW9wX2NvcmhlYXQgPC0gcGxvdF9jb3JoZWF0KGxwX2NmX2Jpb3Bfbm9ybSkKbHBfY2ZfYmlvcF9jb3JoZWF0CmxwX2NmX2Jpb3Bfbm9ybV9wY2EgPC0gcGxvdF9wY2EobHBfY2ZfYmlvcF9ub3JtKQpscF9jZl9iaW9wX25vcm1fcGNhCgpscF9jZl9iaW9wX25iIDwtIG5vcm1hbGl6ZV9leHB0KGxwX2NmX2Jpb3AsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9ICJzaW1wbGUiKQpscF9jZl9iaW9wX25iX3BjYSA8LSBwbG90X3BjYShscF9jZl9iaW9wX25iKQpscF9jZl9iaW9wX25iX3BjYQpgYGAKCiMgRXhhbWluaW5nIFBDcyBhbmQgU1ZzIHZzLiB0aGUgbWV0YWRhdGE6IFNWIGxvYWRpbmdzCgpUaGlzIGlzIGNvbWluZyBvdXQgb2YgdGhlIDA5dmFyY29yX3JlZ3Jlc3Npb24gZG9jdW1lbnQgYW5kIHdhcwppbml0aWFsbHkgcGVyZm9ybWVkIGJ5IFRoZXJlc2EuICBJZiB0aGlzIHdvcmtzIHdlbGwgYW5kIGlzIHN1ZmZpY2llbnQsCkkgbWlnaHQgcmVtb3ZlIHRoYXQgZG9jdW1lbnQgYW5kIHRoZXJlZm9yZSBoYXZlIHRoYXQgbXVjaCBsZXNzIHN0dWZmCnRvIGNoZWNrIG9uIGZvciBjb3JyZWN0bmVzcy4KCjxzcGFuIHN0eWxlPSJjb2xvcjojMDA2NDAwIj4KTm90ZSBmcm9tIGF0YjogSSBuZWVkIHRvIG1ha2UgYSBmZXcgY2hhbmdlcyB0byB0aGlzIHNlY3Rpb24sIHByaW1hcmlseQp3ZSBuZWVkIHRvIGJlIGFibGUgdG8gYXV0b21hdGljYWxseSBnZW5lcmF0ZSB0aGUgdGFibGVzIG9mCmYtc3RhdGlzdGljczsgaW4gY2FzZSB0aGUgZGF0YSBjaGFuZ2VzICh3aGljaCBpdCBkaWQgc2luY2UgVGhlcmVzYQpwZXJmb3JtZWQgdGhpcywgb25lIHNhbXBsZSB3YXMgcmVtb3ZlZCBJIHRoaW5rKS4gIFdpdGggdGhhdCBjYXZlYXQsCnRoZSBmb2xsb3dpbmcgaXMgY29taW5nIGRpcmVjdGx5IG91dCBvZiBoZXIgU1ZBX1YzX1R1bWFjbyBkb2N1bWVudC4gIEkKYWxzbyB3b3VsZCBsaWtlIHRvIGNvbXBhcmUgdGhlIFNWLWZzdGF0cyB0byBzaW1pbGFyIG1ldHJpY3MgSSB0b29rIG9mClBDcyB2cy4gbWV0YWRhdGEgZmFjdG9ycy4gIE15IGFzc3VtcHRpb24gKGlmIEkgdW5kZXJzdGFuZCB0aGUgbWF0aCBpbgpzdmEgYXQgYWxsKSBpcyB0aGF0IHRoZXkgc2hvdWxkIGxhcmdlbHkgY29tcGxlbWVudC9hZ3JlZSB3aXRoIGVhY2gKb3RoZXIuCjwvc3Bhbj4KCldlIHdvdWxkIGxpa2UgdG8ga25vdyB3aGF0IHRoZSBoZWNrIFNWQSBpcyBhY3R1YWxseSBjb3JyZWN0aW5nIGZvcgp3aGVuIHdlIGRvIGFuIFNWQSBjb3JyZWN0aW9uLiBBcmUgdGhlcmUgYW55IG1ldGFkYXRhcyB0aGF0IHRoZXNlIFNW4oCZcwphcmUgY29ycmVsYXRlZCB3aXRoPwoKVG8gZG8gdGhpcywgSSB3aWxsIHJ1biBTVkEgdG8gZ2V0IHRoZSBTViBsb2FkaW5ncy4gSSB3aWxsIHRoZW4gZG8Kc29tZXRoaW5nIGFraW4gdG8gUEMgbG9hZGluZ3MgYW5hbHlzaXMgdG8gc2VlIGhvdyB0aGVzZSBpbmRpdmlkdWFsIFNWcwooYW5kIGNvbWJpbmF0b3JpYWwgU1ZzKSBhcmUgYXNzb2NpYXRlZCB3aXRoIGFueQoKSSB3aWxsIHVzZSBhIGNvbXB1dGVkIEYtc3RhdGlzdGljIGZvciB0aGlzIGFzc29jaWF0aW9uIHRvIG1lYXN1cmUgdGhlCmJldHdlZW46d2l0aGluIGNsdXN0ZXIgdmFyaWFuY2UgaW4gYSBtb2RlbCAoYW5kIHRlbGwgdXMgaWYgdGhhdCBmYWN0b3IKaXMgYSDigJxnb29k4oCdIGluZGljYXRvciBvZiBzZXBhcmF0aW9uIGJhc2VkIG9uIHRoYXQgc3YgbG9hZGluZykuCgokJFxiZWdpbntlcXVhdGlvbn0KRi1zdGF0aXN0aWMgPSBcZnJhY3tUU1MgLSBSU1N9e1JTU30KXGVuZHtlcXVhdGlvbn0kJAoKU28gZm9yIHRoaXMsIEkgd2lsbCB1c2UgYSBzZXJpZXMgb2YgbGluZWFyIHJlZ3Jlc3Npb25zIHdoaWNoIG1vZGVsCmVhY2ggZGltZW5zaW9uIG9mIFNWQSBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBvYnNlcnZlZCB2YXJpYWJsZXMgdGhhdApkZXNjcmliZSB0aGUga25vd24gdW5kZXJseWluZyBncm91cCBzdHJ1Y3R1cmUgKGNsaW5pYywgdmlzaXQsIHBhdGllbnQsCi4uLikKCiQkXGJlZ2lue2VxdWF0aW9ufQpcdW5kZXJicmFjZXtYX2l9X1x0ZXh0e2RpbWVuc2lvbiBpIG9mIFNWQX0gPSBcdW5kZXJicmFjZXtCXzAgKyBCXzEKY2VsbHR5cGUvdmlzaXQvY2xpbmljL2Rvbm9yfV9cdGV4dHt1bmRlcmx5aW5nIGdyb3VwIHN0cnVjdHVyZX0KXGVuZHtlcXVhdGlvbn0kJAoKV2UgY2FuIGRvIHRoaXMgYnJlYWtkb3duIGluIGEgZmV3IHdheXMgdG8gYW5zd2VyIGRpZmZlcmVudCBxdWVzdGlvbnMKd2hpY2ggSSB3aWxsIGV4cGxvcmUgZnVydGhlciBiZWxvdy4KCldlIGhhdmUgZGVjaWRlZCB0aGUgQ2FsaSBzYW1wbGVzIGRvbid0IG9mZmVyIGEgbG90IG9mIGV4dHJhCmluZm9ybWF0aW9uIGZvciB1cywgYW5kIHRoZXJlIGlzIHNpZ25pZmljYW50IGNsaW5pYyBiYXRjaCBlZmZlY3QsIHNvCndlIGFyZSBnb2luZyB0byByZW1vdmUgdGhlIENhbGkgc2FtcGxlcyBhbmQgZXZhbHVhdGUgdGhlIFNWIGxvYWRpbmdzLgoKVGhlIGZpcnN0IHRoaW5nIHRvIGRvIGlzIHRoZSBhY3R1YWwgU1ZBIHRvIGdldCB0aGUgbG9hZGluZ3MuCgo8c3BhbiBzdHlsZT0iY29sb3I6IzAwNjQwMCI+CkkgbWF5IGhhdmUgY2hhbmdlZCBhIGZldyBvZiBUaGVyZXNhJ3MgdmFyaWFibGUgbmFtZXMgd2hlbiBJIGZpcnN0CmNvcHkvcGFzdGVkIHRoaXMgZG9jdW1lbnQgdG9nZXRoZXIgd2l0aG91dCB0YWtpbmcgbm90ZSBvZiB0aGUKbW9kaWZpY2F0aW9uOyBidXQgSSBhbSByZWFzb25hYmx5IGNlcnRhaW4gdGhhdCB0aGUgaW50ZW5kZWQgZGF0YQpzdHJ1Y3R1cmVzIGFyZSB0aGUgc2FtZS4KPC9zcGFuPgoKYGBge3J9CmNsaW5pY19zdmEgPC0gbm9ybWFsaXplX2V4cHQodF9jbGluaWNhbCwgZmlsdGVyID0gVFJVRSkKcGhlbm8gPC0gcERhdGEoY2xpbmljX3N2YSkKZWRhdGEgPC0gZXhwcnMoY2xpbmljX3N2YSkKCm1vZCA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3RvcihmaW5hbG91dGNvbWUpLCBkYXRhID0gcGhlbm8pCm1vZDAgPC0gbW9kZWwubWF0cml4KH4xLCBkYXRhID0gcGhlbm8pCgpzdm9iaiA8LSBzdmE6OnN2YXNlcShlZGF0YSwgbW9kLCBtb2QwKQpgYGAKCiMjIyBTViAxCgpTVkEgZm91bmQgNCBTVuKAmXMuIFdlIGNhbiBwbG90IHRoZW0gaW5kaXZpZHVhbGx5IHRvIHZpc3VhbGx5IGluc3BlY3QKdGhlaXIgc2VwYXJhdGlvbiB3LnIudCBzb21lIG1ldGFkYXRhLgoKYGBge3J9CnN2cyA8LSBhcy5kYXRhLmZyYW1lKHN2b2JqJHN2KQpjb2xuYW1lcyhzdnMpIDwtIHBhc3RlMCgic3ZfIiwgc2VxKDE6NCkpCnN2cyA8LSBjYmluZChzdnMsIHBoZW5vKQoKc3YxX3R5cGVvZmNlbGxzIDwtIGdncGxvdChzdnMsIGFlcyh5ID0gc3ZfMSwgeCA9IHR5cGVvZmNlbGxzLCBmaWxsID0gdHlwZW9mY2VsbHMpKSArCiAgZ2VvbV92aW9saW4oKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNzUpICsKICB4bGFiKCJUeXBlIG9mIENlbGxzIikgKwogIHlsYWIoIlNWIDEiKSAgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKc3YxX3Zpc2l0IDwtICBnZ3Bsb3Qoc3ZzLCBhZXMoeSA9IHN2XzEsIHggPSB2aXNpdG51bWJlciwgZmlsbCA9IHZpc2l0bnVtYmVyKSkgKwogIGdlb21fdmlvbGluKCkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjc1KSArCiAgeGxhYigiVmlzaXQgTnVtYmVyIikgKwogIHlsYWIoIlNWIDEiKSAgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKc3YxX2Rvbm9yIDwtIGdncGxvdChzdnMsIGFlcyh5ID0gc3ZfMSwgeCA9IGRvbm9yLCBmaWxsID0gZG9ub3IpKSArCiAgZ2VvbV92aW9saW4oKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNzUpICsKICB4bGFiKCJEb25vciIpICsKICB5bGFiKCJTViAxIikgICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDAuNSwgaGp1c3QgPSAwLjUpKQoKc3YxX3R5cGVvZmNlbGxzCnN2MV92aXNpdApzdjFfZG9ub3IKIyNncmlkLmFycmFuZ2Uoc3YxX3R5cGVvZmNlbGxzLCBzdjFfdmlzaXQsIHN2MV9kb25vciwgbnJvdyA9IDIpCmBgYAoKIyMjIFNWMgoKYGBge3J9CnN2Ml90eXBlb2ZjZWxscyA8LSBnZ3Bsb3Qoc3ZzLCBhZXMoeSA9IHN2XzIsIHggPSB0eXBlb2ZjZWxscywgZmlsbCA9IHR5cGVvZmNlbGxzKSkgKwogIGdlb21fdmlvbGluKCkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjc1KSArCiAgeGxhYigiVHlwZSBvZiBDZWxscyIpICsKICB5bGFiKCJTViAyIikgICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnN2Ml92aXNpdCA8LSAgZ2dwbG90KHN2cywgYWVzKHkgPSBzdl8yLCB4ID0gdmlzaXRudW1iZXIsIGZpbGwgPSB2aXNpdG51bWJlcikpICsKICBnZW9tX3Zpb2xpbigpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC43NSkgKwogIHhsYWIoIlZpc2l0IE51bWJlciIpICsKICB5bGFiKCJTViAyIikgICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnN2Ml9kb25vciA8LSBnZ3Bsb3Qoc3ZzLCBhZXMoeSA9IHN2XzIsIHggPSBkb25vciwgZmlsbCA9IGRvbm9yKSkgKwogIGdlb21fdmlvbGluKCkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjc1KSArCiAgeGxhYigiRG9ub3IiKSArCiAgeWxhYigiU1YgMiIpICArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAwLjUsIGhqdXN0ID0gMC41KSkKCgojZ3JpZC5hcnJhbmdlKHN2Ml90eXBlb2ZjZWxscywgc3YyX3Zpc2l0LCBzdjJfZG9ub3IsIG5yb3cgPSAyKQpzdjJfdHlwZW9mY2VsbHMKc3YyX3Zpc2l0CnN2Ml9kb25vcgpgYGAKCjxzcGFuIHN0eWxlPSJjb2xvcjojMDA2NDAwIj4KSSBzcGVudCBhIGxpdHRsZSB0aW1lIHRvIHNpbXBsaWZ5IGFuZCB0cnkgdG8gbWFrZSB0aGUgcmVhc29uaW5nIGFib3ZlCmEgbGl0dGxlIG1vcmUgcm9idXN0IHNvIHRoYXQgSSBjYW4gcmVnZW5lcmF0ZSBUaGVyZXNhJ3MgeGxzeCB0YWJsZSBvZgpmLXN0YXRpc3RpY3MgYXMgd2VsbCBhcyBhZGQgYSBsaXR0bGUgbW9yZSBpbmZvcm1hdGlvbi4gIFRoZSBmb2xsb3dpbmcKYmxvY2sgYXR0ZW1wdHMgdGhpcy4uLgo8L3NwYW4+CgpOYWppYiBjb3JyZWN0bHkgcG9pbnRlZCBvdXQgdGhhdCBJIGxlZnQgb2ZmIGNsaW5pYyBpbiB0aGlzIGZpcnN0IGludm9jYXRpb24uCgpgYGB7cn0KcXVlcmllcyA8LSBjKCJ0eXBlb2ZjZWxscyIsICJ2aXNpdG51bWJlciIsICJjbGluaWMiLCAiZG9ub3IiKQp0Y19jbGluaWNhbF9mcHN0YXRzIDwtIHN2cGNfZnN0YXRzKHRjX2NsaW5pY2FsLCBudW1fcGNzID0gNSwgcXVlcmllcyA9IHF1ZXJpZXMpCnF1ZXJpZXMgPC0gYygidHlwZW9mY2VsbHMiLCAidmlzaXRudW1iZXIiLCAiZG9ub3IiKQp0X2NsaW5pY2FsX2Zwc3RhdHMgPC0gc3ZwY19mc3RhdHModF9jbGluaWNhbCwgbnVtX3BjcyA9IDUsIHF1ZXJpZXMgPSBxdWVyaWVzKQpjX2NsaW5pY2FsX2Zwc3RhdHMgPC0gc3ZwY19mc3RhdHMoY19jbGluaWNhbCwgbnVtX3BjcyA9IDUsIHF1ZXJpZXMgPSBxdWVyaWVzKQpgYGAKCiMgU2VuZCB0byBhbiB4bHN4IHdvcmtib29rCgo8c3BhbiBzdHlsZT0iY29sb3I6IzAwNjQwMCI+CkkgYW0gZ29pbmcgdG8gYWRkIGEgbGl0dGxlIGNvZGUgaW4gdGhpcyBzZWN0aW9uIHRvIHNlbmQgdGhpcyB0byBhbgp4bHN4IGZpbGUuICBJIG1pZ2h0IG5lZWQgdG8gYWRkIGEgbGl0dGxlIGJpdCBvZiBjb2RlIGFzIHdlbGwgYmVjYXVzZSBJCmFtIG5vdCBjZXJ0YWluIHRoYXQgdGhlcmUgaXMgYSBkb2N1bWVudCB3aGljaCBjb250YWlucyB0aGlzCmNhbGN1bGF0aW9uIGZvciBlYWNoIGRhdGEgc3Vic2V0LgoKSSBwdXQgdG9nZXRoZXIgYSBxdWljayBmdW5jdGlvbiB3aGljaCB3cml0ZXMgdGhlIHJlc3VsdHMgb2Ygb25lIG9mCnRoZXNlIGFuYWx5c2VzIHRvIGEgeGxzeCBmaWxlLCBidXQgaXQgdmVyeSBtdWNoIGFzc3VtZXMgYSBzaW5nbGUKZGF0YXNldCBhbmQgaXMgbm90IGVhc2lseSBhbWVuZGFibGUgdG8gbXVsdGlwbGU7IHRoZXJlZm9yZSBJIHdpbGwKc3RyaXAgdGhlIGNvZGUgb3V0IGhlcmUgaW50byBhIG5ldyBmdW5jdGlvbiB0byByZXBlYXQgaXRzZWxmIGZvciB0aGUKVHVtYWNvL0NhbGkvQm90aCBkYXRhIGZvciBhbiBhcmJpdHJhcnkgY29tYmluYXRpb24uCjwvc3Bhbj4KClF1ZXJ5IGZyb20gTWFyaWEgQWRlbGFpZGE6IFBlcmZvcm0gYSBzaW1pbGFyIGYvcCBzdGF0aXN0aWNzIHBsb3QveGxzeAp0YWJsZSBidXQgdXNpbmcgdGhlIGZpcnN0IDUgUENzIGFuZCBTVnM7IHBlcmhhcHMgYWxzbyBpbmNsdWRlIHRoZQphbW91bnQgb2YgdmFyaWFuY2UgcmVtYWluaW5nIHRhbGUgKEkgZm9yZ2V0IGl0cyBuYW1lOiByZXNpZHVhbHMpLgoKQnV0IGFsc28gZG8gc2xpZ2h0bHkgZGlmZmVyZW50IHBsb3RzOiAyIHBsb3RzOiAxIHdpdGggUENzIGJlZm9yZSBTVkEKZm9sbG93ZWQgYnkgdGhlIFNWcywgdGhlIDEgd2l0aCBTVnMgZm9sbG93ZWQgYnkgcG9zdCBQQ3MuCgpHaXZlbiB0aGlzLCBwZXJmb3JtIHRoaXMgdGFzayB3aXRoOiBDbGluaWMsIERvbm9yLCBWaXNpdCwgQ2VsbHR5cGUKdXNpbmcgdGhlIGNsaW5pY2FsIHNhbXBsZXMgKG5vIGJpb3BzaWVzKS4KCmBgYHtyfQp3cml0ZV9jb21iaW5lZF9mcHN0YXRzIDwtIGZ1bmN0aW9uKGJvdGggPSB0Y19jbGluaWNhbF9mcHN0YXRzLCB0dW1hY28gPSB0X2NsaW5pY2FsX2Zwc3RhdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsaSA9IGNfY2xpbmljYWxfZnBzdGF0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbCA9ICJleGNlbC9jb21iaW5lZF9zdnBjX2ZzdGF0cy54bHN4IikgewogIHhsc3ggPC0gaW5pdF94bHN4KGV4Y2VsKQogIHdiIDwtIHhsc3hbWyJ3YiJdXQogIGV4Y2VsX2Jhc2VuYW1lIDwtIHhsc3hbWyJiYXNlbmFtZSJdXQogIGRvX2V4Y2VsIDwtIFRSVUUKICBpZiAoaXMubnVsbCh3YikpIHsKICAgIGRvX2V4Y2VsIDwtIEZBTFNFCiAgfQoKICBjdXJyZW50X3JvdyA8LSAxCgogIHByZWYgPC0gYm90aFtbInByZV9mIl1dCiAgc3ZmIDwtIGJvdGhbWyJzdl9mIl1dCiAgcG9zdGYgPC0gYm90aFtbInBvc3RfZiJdXQogICMjIENoYW5naW5nIHRoZSByb3duYW1lcyBkdWUgdG8gcmJpbmQgcm93bmFtZXMgc2hlbmFuaWdhbnMuCiAgcm93bmFtZXMocHJlZikgPC0gcGFzdGUwKCJQcmVQQyIsIHNlcV9sZW4obnJvdyhwcmVmKSkpCiAgcm93bmFtZXMocG9zdGYpIDwtIHBhc3RlMCgiUG9zdFBDIiwgc2VxX2xlbihucm93KHBvc3RmKSkpCiAgYWxsZiA8LSByYmluZChwcmVmLCBzdmYsIHBvc3RmKQoKICBwcmVwIDwtIGJvdGhbWyJwcmVfcCJdXQogIHN2cCA8LSBib3RoW1sic3ZfcCJdXQogIHBvc3RwIDwtIGJvdGhbWyJwb3N0X3AiXV0KICByb3duYW1lcyhwcmVwKSA8LSBwYXN0ZTAoIlByZVBDIiwgc2VxX2xlbihucm93KHByZXApKSkKICByb3duYW1lcyhwb3N0cCkgPC0gcGFzdGUwKCJQb3N0UEMiLCBzZXFfbGVuKG5yb3cocG9zdHApKSkKICBhbGxwIDwtIHJiaW5kKHByZXAsIHN2cCwgcG9zdHApCgogIGZ1bl9wbG90IDwtIGhlYXRtYXAuMyhhcy5tYXRyaXgoYWxscCksIGRlbmRyb2dyYW0gPSAibm9uZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlID0gIm5vbmUiLCB0cmFjZSA9ICJub25lIiwKICAgICAgICAgICAgICAgICAgICAgICAgQ29sdiA9IEZBTFNFLCBSb3d2ID0gRkFMU0UpCiAgaW1hZ2UgPC0gZ3JEZXZpY2VzOjpyZWNvcmRQbG90KCkKCiAgeGxzeF9yZXN1bHQgPC0gd3JpdGVfeGxzeChkYXRhID0gYWxsZiwgd2IgPSB3Yiwgc2hlZXQgPSAiRnZhbHVlcyIsIHN0YXJ0X3JvdyA9IGN1cnJlbnRfcm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQm90aCBjbGluaWNzLCBTVkEgYW5kIFBDIGFuYWx5c2lzLCBGLXZhbHVlcyIpCiAgeGxzeF9yZXN1bHQgPC0gd3JpdGVfeGxzeChkYXRhID0gYWxscCwgd2IgPSB3Yiwgc2hlZXQgPSAiUHZhbHVlcyIsIHN0YXJ0X3JvdyA9IGN1cnJlbnRfcm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQm90aCBjbGluaWNzLCBTVkEgYW5kIFBDIGFuYWx5c2lzLCBQLXZhbHVlcyIpCiAgY3VycmVudF9yb3cgPC0geGxzeF9yZXN1bHRbWyJlbmRfcm93Il1dICsgMgogIHRyeV9yZXN1bHQgPC0geGxzeF9pbnNlcnRfcG5nKAogICAgYV9wbG90ID0gaW1hZ2UsIHdiID0gd2IsIHNoZWV0ID0gIlB2YWx1ZXMiLCBzdGFydF9jb2wgPSBuY29sKGFsbHApICsgMikKICBpbWFnZV9maWxlcyA9IGMoKQogIGlmICghICJ0cnktZXJyb3IiICVpbiUgY2xhc3ModHJ5X3Jlc3VsdCkpIHsKICAgIGltYWdlX2ZpbGVzID0gdHJ5X3Jlc3VsdFtbImZpbGVuYW1lIl1dCiAgfQoKICBwcmVmIDwtIHR1bWFjb1tbInByZV9mIl1dCiAgc3ZmIDwtIHR1bWFjb1tbInN2X2YiXV0KICBwb3N0ZiA8LSB0dW1hY29bWyJwb3N0X2YiXV0KICAjIyBDaGFuZ2luZyB0aGUgcm93bmFtZXMgZHVlIHRvIHJiaW5kIHJvd25hbWVzIHNoZW5hbmlnYW5zLgogIHJvd25hbWVzKHByZWYpIDwtIHBhc3RlMCgiUHJlUEMiLCBzZXFfbGVuKG5yb3cocHJlZikpKQogIHJvd25hbWVzKHBvc3RmKSA8LSBwYXN0ZTAoIlBvc3RQQyIsIHNlcV9sZW4obnJvdyhwb3N0ZikpKQogIGFsbGYgPC0gcmJpbmQocHJlZiwgc3ZmLCBwb3N0ZikKCiAgcHJlcCA8LSB0dW1hY29bWyJwcmVfcCJdXQogIHN2cCA8LSB0dW1hY29bWyJzdl9wIl1dCiAgcG9zdHAgPC0gdHVtYWNvW1sicG9zdF9wIl1dCiAgcm93bmFtZXMocHJlcCkgPC0gcGFzdGUwKCJQcmVQQyIsIHNlcV9sZW4obnJvdyhwcmVwKSkpCiAgcm93bmFtZXMocG9zdHApIDwtIHBhc3RlMCgiUG9zdFBDIiwgc2VxX2xlbihucm93KHBvc3RwKSkpCiAgYWxscCA8LSByYmluZChwcmVwLCBzdnAsIHBvc3RwKQoKICB4bHN4X3Jlc3VsdCA8LSB3cml0ZV94bHN4KGRhdGEgPSBhbGxmLCB3YiA9IHdiLCBzaGVldCA9ICJGdmFsdWVzIiwgc3RhcnRfcm93ID0gY3VycmVudF9yb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJUdW1hY28sIFNWQSBhbmQgUEMgYW5hbHlzaXMsIEYtdmFsdWVzIikKICB4bHN4X3Jlc3VsdCA8LSB3cml0ZV94bHN4KGRhdGEgPSBhbGxwLCB3YiA9IHdiLCBzaGVldCA9ICJQdmFsdWVzIiwgc3RhcnRfcm93ID0gY3VycmVudF9yb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJUdW1hY28sIFNWQSBhbmQgUEMgYW5hbHlzaXMsIFAtdmFsdWVzIikKICBjdXJyZW50X3JvdyA8LSB4bHN4X3Jlc3VsdFtbImVuZF9yb3ciXV0gKyAyCgogIHByZWYgPC0gY2FsaVtbInByZV9mIl1dCiAgc3ZmIDwtIGNhbGlbWyJzdl9mIl1dCiAgcG9zdGYgPC0gY2FsaVtbInBvc3RfZiJdXQogICMjIENoYW5naW5nIHRoZSByb3duYW1lcyBkdWUgdG8gcmJpbmQgcm93bmFtZXMgc2hlbmFuaWdhbnMuCiAgcm93bmFtZXMocHJlZikgPC0gcGFzdGUwKCJQcmVQQyIsIHNlcV9sZW4obnJvdyhwcmVmKSkpCiAgcm93bmFtZXMocG9zdGYpIDwtIHBhc3RlMCgiUG9zdFBDIiwgc2VxX2xlbihucm93KHBvc3RmKSkpCiAgYWxsZiA8LSByYmluZChwcmVmLCBzdmYsIHBvc3RmKQoKICBwcmVwIDwtIGNhbGlbWyJwcmVfcCJdXQogIHN2cCA8LSBjYWxpW1sic3ZfcCJdXQogIHBvc3RwIDwtIGNhbGlbWyJwb3N0X3AiXV0KICByb3duYW1lcyhwcmVwKSA8LSBwYXN0ZTAoIlByZVBDIiwgc2VxX2xlbihucm93KHByZXApKSkKICByb3duYW1lcyhwb3N0cCkgPC0gcGFzdGUwKCJQb3N0UEMiLCBzZXFfbGVuKG5yb3cocG9zdHApKSkKICBhbGxwIDwtIHJiaW5kKHByZXAsIHN2cCwgcG9zdHApCgogIHhsc3hfcmVzdWx0IDwtIHdyaXRlX3hsc3goZGF0YSA9IGFsbGYsIHdiID0gd2IsIHNoZWV0ID0gIkZ2YWx1ZXMiLCBzdGFydF9yb3cgPSBjdXJyZW50X3JvdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNhbGksIFNWQSBhbmQgUEMgYW5hbHlzaXMsIEYtdmFsdWVzIikKICB4bHN4X3Jlc3VsdCA8LSB3cml0ZV94bHN4KGRhdGEgPSBhbGxwLCBzaGVldCA9ICJQdmFsdWVzIiwgd2IgPSB3Yiwgc3RhcnRfcm93ID0gY3VycmVudF9yb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDYWxpLCBTVkEgYW5kIFBDIGFuYWx5c2lzLCBQLXZhbHVlcyIpCiAgY3VycmVudF9yb3cgPC0geGxzeF9yZXN1bHRbWyJlbmRfcm93Il1dICsgMgoKICBleGNlbF9yZXQgPC0gdHJ5KG9wZW54bHN4OjpzYXZlV29ya2Jvb2sod2IsIGV4Y2VsLCBvdmVyd3JpdGUgPSBUUlVFKSkKICByZW1vdmVkIDwtIHRyeShzdXBwcmVzc1dhcm5pbmdzKGZpbGUucmVtb3ZlKGltYWdlX2ZpbGVzKSksIHNpbGVudCA9IFRSVUUpCn0KCmNsaW5pY2FsX2Zwc3RhdHMgPC0gd3JpdGVfY29tYmluZWRfZnBzdGF0cygKICBib3RoID0gdGNfY2xpbmljYWxfZnBzdGF0cywgdHVtYWNvID0gdF9jbGluaWNhbF9mcHN0YXRzLCBjYWxpID0gY19jbGluaWNhbF9mcHN0YXRzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvY2xpbmljYWxfZnBzdGF0cy12e3Zlcn0ueGxzeCIpKQpgYGAKClRoZSBGLXN0YXQgcmVzdWx0aW5nIGZyb20gYW4gYW5vdmEgZm9yIHRoZSBtb2RlbCBzdiB+IG1ldGFkYXRhX2ZhY3RvcgpzaG93cyB0aGF0IHRoZSBtYWluIHRoaW5nIHdlIGFyZSBjb3JyZWN0aW5nIGZvciB3aXRoIGFuIFNWQSBjb3JyZWN0aW9uCih3aXRoIGN1cmUvZmFpbCBhcyB0aGUgbW9kZWwgZmFjdG9yKSBpcyB0aGUgY2VsbCB0eXBlLiBUaGUgZmFjdG9yCmRvbm9yIGNvbnRyaWJ1dGVzIHRoZSBuZXh0IGhpZ2hlc3Qgc2VwYXJhdGlvbiwgd2l0aCBjbGluaWMgZmFsbGluZyBpbgp0aGlyZC4gdGhlIHZpc2l0IGNvbnRyaWJ1dGVzIGVzc2VudGlhbGx5IG5vIHZhcmlhbmNlIGluIHRoaXMgZGF0YSwKd2hpY2ggd2Uga25ldyBmcm9tIHRoZSBERSByZXN1bHRzLgoKIyBCaWJsaW9ncmFwaHkK