TMRC3 202305: Differential Expression analyses, Tumaco only

atb

2023-07-11

1 Changelog

  • Still hunting for messed up colors, changed input data to match new version.

2 Introduction

The various differential expression analyses of the data generated in tmrc3_datasets will occur in this document.

2.1 Naming conventions

I am going to try to standardize how I name the various data structures created in this document. Most of the large data created are either sets of differential expression analyses, their combined results, or the set of results deemed ‘significant’.

Hopefully by now they all follow these guidelines:

{clinic(s)}sample-subset}{primary-question(s)}{datatype}{batch-method}

  • {clinic}: This is either tc or t for Tumaco and Cali, or just Tumaco.
  • {sample-subset}: Things like ‘all’ or ‘monocytes’.
  • {primary-question}: Shorthand name for the primary contrasts performed, thus ‘clinics’ would suggest a comparison of Tumaco vs. Cali. ‘visits’ would compare v2/v1, etc.
  • {datatype}: de, table, sig
  • {batch-type}: nobatch, batch{factor}, sva. {factor} in this instance should be a column from the metadata.

With this in mind, ‘tc_biopsies_clinic_de_sva’ should be the Tumaco+Cali biopsy data after performing the differential expression analyses comparing the clinics using sva.

I suspect there remain some exceptions and/or errors.

2.2 Define contrasts for DE analyses

Each of the following lists describes the set of contrasts that I think are interesting for the various ways one might consider the TMRC3 dataset. The variables are named according to the assumed data with which they will be used, thus tc_cf_contrasts is expected to be used for the Tumaco+Cali data and provide a series of cure/fail comparisons which (to the extent possible) across both locations. In every case, the name of the list element will be used as the contrast name, and will thus be seen as the sheet name in the output xlsx file(s); the two pieces of the character vector value are the numerator and denominator of the associated contrast.

clinic_contrasts <- list(
  "clinics" = c("Cali", "Tumaco"))
## In some cases we have no Cali failure samples, so there remain only 2
## contrasts that are likely of interest
tc_cf_contrasts <- list(
  "tumaco" = c("Tumacofailure", "Tumacocure"),
  "cure" = c("Tumacocure", "Calicure"))
## In other cases, we have cure/fail for both places.
clinic_cf_contrasts <- list(
  "cali" = c("Califailure", "Calicure"),
  "tumaco" = c("Tumacofailure", "Tumacocure"),
  "cure" = c("Tumacocure", "Calicure"),
  "fail" = c("Tumacofailure", "Califailure"))
cf_contrast <- list(
  "outcome" = c("Tumacofailure", "Tumacocure"))
t_cf_contrast <- list(
  "outcome" = c("failure", "cure"))
visitcf_contrasts <- list(
  "v1cf" = c("v1failure", "v1cure"),
  "v2cf" = c("v2failure", "v2cure"),
  "v3cf" = c("v3failure", "v3cure"))
visit_contrasts <- list(
  "v2v1" = c("c2", "c1"),
  "v3v1" = c("c3", "c1"),
  "v3v2" = c("c3", "c2"))
visit_v1later <- list(
  "later_vs_first" = c("later", "first"))
celltypes <- list(
  "eo_mono" = c("eosinophils", "monocytes"),
  "ne_mono" = c("neutrophils", "monocytes"),
  "eo_ne" = c("eosinophils", "neutrophils"))
ethnicity_contrasts <- list(
  "mestizo_indigenous" = c("mestiza", "indigena"),
  "mestizo_afrocol" = c("mestiza", "afrocol"),
  "indigenous_afrocol" = c("indigena", "afrocol"))

3 Only Tumaco samples

Start over, this time with only the samples from Tumaco. We currently are assuming these will prove to be the only analyses used for final interpretation. This is primarily because we have insufficient failed treatment samples from Cali.

xlsx_prefix <- "analyses/4_tumaco/DE_Cure_vs_Fail"

3.1 All samples

Start by considering all Tumaco cell types. Note that in this case we only use SVA, primarily because I am not certain what would be an appropriate batch factor, perhaps visit?

t_cf_clinical_de_sva <- all_pairwise(t_clinical, model_batch = "svaseq", filter = TRUE)
## 
##    cure failure 
##      67      56
## Removing 0 low-count genes (14149 remaining).
## Setting 17282 low elements to zero.
## transform_counts: Found 17282 values equal to 0, adding 1 to the matrix.
t_cf_clinical_de_sva
## A pairwise differential expression with results from: basic, deseq, edger, limma.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 6 comparisons.
## The logFC agreement among the methods follows:
##                failure_vs_cure
## limma_vs_deseq          0.8064
## limma_vs_edger          0.8179
## limma_vs_basic          0.8702
## deseq_vs_edger          0.9844
## deseq_vs_basic          0.8243
## edger_vs_basic          0.8286
t_cf_clinical_table_sva <- combine_de_tables(
  t_cf_clinical_de_sva, keepers = t_cf_contrast,
#  rda = glue("rda/t_clinical_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_clinical_table_sva
## A set of combined differential expression results.
##             table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup
## 1 failure_vs_cure          93           183         103           157          50
##   limma_sigdown
## 1            38
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

t_cf_clinical_table_sva[["plots"]][["outcome"]][["deseq_ma_plots"]]

t_cf_clinical_sig_sva <- extract_significant_genes(
  t_cf_clinical_table_sva,
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_cf_sig_sva-v202305.xlsx before writing the tables.
t_cf_clinical_sig_sva
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##         limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## outcome       50         38      103        157       93        183       16          4

dim(t_cf_clinical_sig_sva$deseq$ups[[1]])
## [1] 93 50
dim(t_cf_clinical_sig_sva$deseq$downs[[1]])
## [1] 183  50

3.2 gProfiler search of all samples

The following gProfiler searches use the all_gprofiler() function instead of simple_gprofiler(). As a result, the results are separated by {contrast}_{direction}. Thus ‘outcome_down’.

The same plots are available as the previous gProfiler searches, but in many of the following runs, I used the dotplot() function to get a slightly different view of the results.

t_cf_clinical_gp <- all_gprofiler(t_cf_clinical_sig_sva)
## Wikipathways of the up c/f genes
enrichplot::dotplot(t_cf_clinical_gp[["outcome_up"]][["WP_enrich"]])

## Transcription factor database of the up c/f genes
enrichplot::dotplot(t_cf_clinical_gp[["outcome_up"]][["TF_enrich"]])

## Reactome of the up c/f genes
enrichplot::dotplot(t_cf_clinical_gp[["outcome_up"]][["REAC_enrich"]])

## GO of the down c/f genes
enrichplot::dotplot(t_cf_clinical_gp[["outcome_down"]][["GO_enrich"]])

t_cf_clinical_gp[["outcome_up"]][["pvalue_plots"]][["BP"]]

## Reactome of the down c/f genes
enrichplot::dotplot(t_cf_clinical_gp[["outcome_down"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_clinical_gp[["outcome_up"]][["GO_enrich"]])

4 Visit comparisons

Later in this document I do a bunch of visit/cf comparisons. In this block I want to explicitly only compare v1 to other visits. This is something I did quite a lot in the 2019 datasets, but never actually moved to this document.

tv1_vs_later <- all_pairwise(t_v1vs, model_batch = "svaseq", filter = TRUE)
## 
## first later 
##    40    69
## Removing 0 low-count genes (11907 remaining).
## Setting 9616 low elements to zero.
## transform_counts: Found 9616 values equal to 0, adding 1 to the matrix.
tv1_vs_later_table <- combine_de_tables(
  tv1_vs_later, keepers = visit_v1later,
  excel = glue("excel/tv1_vs_later_tables-v{ver}.xlsx"))
## Deleting the file excel/tv1_vs_later_tables-v202305.xlsx before writing the tables.
## Adding venn plots for later_vs_first.
tv1_vs_later_sig <- extract_significant_genes(
  tv1_vs_later_table,
  excel = glue("excel/tv1_vs_later_sig-v{ver}.xlsx"))
## Deleting the file excel/tv1_vs_later_sig-v202305.xlsx before writing the tables.
tv1later_gp <- all_gprofiler(tv1_vs_later_sig)
tv1later_gp[[1]]$pvalue_plots$BP

tv1later_gp[[2]]$pvalue_plots$BP

5 Sex comparison

Can we observe consistent difference in the fe/male samples?

t_sex <- subset_expt(tc_sex, subset = "clinic == 'Tumaco'")
## subset_expt(): There were 184, now there are 123 samples.
t_sex
## An expressionSet containing experiment with 19923
## genes and 123 samples. There are 156 metadata columns and
## 14 annotation columns; the primary condition is comprised of:
## female, male.
## Its current state is: raw(data).
t_sex_de <- all_pairwise(t_sex, model_batch = "svaseq", filter = TRUE)
## 
## female   male 
##     22    101
## Removing 0 low-count genes (14149 remaining).
## Setting 17259 low elements to zero.
## transform_counts: Found 17259 values equal to 0, adding 1 to the matrix.
t_sex_de
## A pairwise differential expression with results from: basic, deseq, edger, limma.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 6 comparisons.
## The logFC agreement among the methods follows:
##                male_vs_female
## limma_vs_deseq         0.8603
## limma_vs_edger         0.8672
## limma_vs_basic         0.9482
## deseq_vs_edger         0.9909
## deseq_vs_basic         0.8712
## edger_vs_basic         0.8758
t_sex_table <- combine_de_tables(
  t_sex_de, excel = glue("excel/t_sex_table-v{ver}.xlsx"))
## Deleting the file excel/t_sex_table-v202305.xlsx before writing the tables.
## Adding venn plots for male_vs_female.
t_sex_table
## A set of combined differential expression results.
##            table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup
## 1 male_vs_female         128            96         116            95          53
##   limma_sigdown
## 1            74
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

t_sex_sig <- extract_significant_genes(
  t_sex_table, excel = glue("excel/t_sex_sig-v{ver}.xlsx"))
## Deleting the file excel/t_sex_sig-v202305.xlsx before writing the tables.
t_sex_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up
## male_vs_female       53         74      116         95      128         96       15
##                basic_down
## male_vs_female         10

t_sex_gp <- all_gprofiler(t_sex_sig)
t_sex_gp
## Running gProfiler on every set of significant genes found:
##                     GO KEGG REAC WP TF MIRNA HPA CORUM HP
## male_vs_female_up   63    0    4  1 46     0   0     0  2
## male_vs_female_down 22    0    0  0  0     0   0     0  0

What if we limit the question to only the people who cured?

tc_sex_cure <- subset_expt(tc_sex, subset = "finaloutcome=='cure'")
## subset_expt(): There were 184, now there are 122 samples.
t_sex_cure <- subset_expt(tc_sex_cure, subset = "clinic == 'Tumaco'")
## subset_expt(): There were 122, now there are 67 samples.
t_sex_cure_de <- all_pairwise(t_sex_cure, model_batch = "svaseq", filter = TRUE)
## 
## female   male 
##     13     54
## Removing 0 low-count genes (13964 remaining).
## Setting 8959 low elements to zero.
## transform_counts: Found 8959 values equal to 0, adding 1 to the matrix.
t_sex_cure_de
## A pairwise differential expression with results from: basic, deseq, edger, limma.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 6 comparisons.
## The logFC agreement among the methods follows:
##                male_vs_female
## limma_vs_deseq         0.7789
## limma_vs_edger         0.8383
## limma_vs_basic         0.9281
## deseq_vs_edger         0.9276
## deseq_vs_basic         0.7981
## edger_vs_basic         0.8480
t_sex_cure_table <- combine_de_tables(
  t_sex_cure_de, excel = glue("excel/t_sex_cure_table-v{ver}.xlsx"))
## Deleting the file excel/t_sex_cure_table-v202305.xlsx before writing the tables.
## Adding venn plots for male_vs_female.
t_sex_cure_table
## A set of combined differential expression results.
##            table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup
## 1 male_vs_female         172           129         161           143          63
##   limma_sigdown
## 1           107
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

t_sex_cure_sig <- extract_significant_genes(
  t_sex_cure_table, excel = glue("excel/t_sex_cure_sig-v{ver}.xlsx"))
## Deleting the file excel/t_sex_cure_sig-v202305.xlsx before writing the tables.
t_sex_cure_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up
## male_vs_female       63        107      161        143      172        129       12
##                basic_down
## male_vs_female          5

t_sex_cure_gp <- all_gprofiler(t_sex_cure_sig)
t_sex_cure_gp
## Running gProfiler on every set of significant genes found:
##                     GO KEGG REAC WP TF MIRNA HPA CORUM HP
## male_vs_female_up   63    2    7  0 35     0   0     0  9
## male_vs_female_down  0    0    0  0  0     0   0     0  0
t_sex_cure_gp[[1]][["pvalue_plots"]][["BP"]]

6 Ethnicity comparisons

The set of ethnicities observed in Tumaco is a bit different than that in Cali. Can we see differences among those groups? Note that this is confounded with cure/fail.

t_ethnicity_de <- all_pairwise(t_etnia_expt, model_batch = "svaseq", filter = TRUE)
## 
##  afrocol indigena  mestiza 
##       76       19       28
## Removing 0 low-count genes (14149 remaining).
## Setting 15817 low elements to zero.
## transform_counts: Found 15817 values equal to 0, adding 1 to the matrix.

t_ethnicity_de
## A pairwise differential expression with results from: basic, deseq, edger, limma.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 6 comparisons.
t_ethnicity_table <- combine_de_tables(
  t_ethnicity_de, excel = glue("excel/t_ethnicity_table-v{ver}.xlsx"))
## Deleting the file excel/t_ethnicity_table-v202305.xlsx before writing the tables.
## Adding venn plots for indigena_vs_afrocol.
## Adding venn plots for mestiza_vs_afrocol.
## Adding venn plots for mestiza_vs_indigena.
t_ethnicity_table
## A set of combined differential expression results.
##                 table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup
## 1 indigena_vs_afrocol         162           236         186           216         164
## 2  mestiza_vs_afrocol          56            92          51            96          41
## 3 mestiza_vs_indigena          83            97          67           108          58
##   limma_sigdown
## 1           146
## 2            53
## 3            56

t_ethnicity_sig <- extract_significant_genes(
  t_ethnicity_table, excel = glue("excel/t_ethnicity_sig-v{ver}.xlsx"))
## Deleting the file excel/t_ethnicity_sig-v202305.xlsx before writing the tables.
t_ethnicity_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                     limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up
## indigena_vs_afrocol      164        146      186        216      162        236       16
## mestiza_vs_afrocol        41         53       51         96       56         92        2
## mestiza_vs_indigena       58         56       67        108       83         97        2
##                     basic_down
## indigena_vs_afrocol         17
## mestiza_vs_afrocol           9
## mestiza_vs_indigena          2

t_ethnicity_gp <- all_gprofiler(t_ethnicity_sig)
t_ethnicity_gp
## Running gProfiler on every set of significant genes found:
##                          GO KEGG REAC WP TF MIRNA HPA CORUM HP
## indigena_vs_afrocol_up   57    1    2  0  0     0   1     0  0
## indigena_vs_afrocol_down 26    0    0  0  0     0   0     0  0
## mestiza_vs_afrocol_up     6    0    0  0  0     0   0     0  0
## mestiza_vs_afrocol_down  21    0    4  3  1     0   0     0  0
## mestiza_vs_indigena_up   20    0    2  0  7     0   0     0  0
## mestiza_vs_indigena_down 10    0    1  0  5     5   0     0  0

6.0.1 Separate the Tumaco data by visit

One of the most compelling ideas in the data is the opportunity to find genes in the first visit which may help predict the likelihood that a person will respond well to treatment. The following block will therefore look at cure/fail from Tumaco at visit 1.

6.0.1.1 Cure/Fail, Tumaco Visit 1

t_cf_clinical_v1_de_sva <- all_pairwise(tv1_samples, model_batch = "svaseq", filter = TRUE)
## 
##    cure failure 
##      30      24
## Removing 0 low-count genes (14016 remaining).
## Setting 7615 low elements to zero.
## transform_counts: Found 7615 values equal to 0, adding 1 to the matrix.
t_cf_clinical_v1_de_sva
## A pairwise differential expression with results from: basic, deseq, edger, limma.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 6 comparisons.
## The logFC agreement among the methods follows:
##                failure_vs_cure
## limma_vs_deseq          0.7393
## limma_vs_edger          0.7826
## limma_vs_basic          0.6896
## deseq_vs_edger          0.9534
## deseq_vs_basic          0.6956
## edger_vs_basic          0.7235
t_cf_clinical_v1_table_sva <- combine_de_tables(
  t_cf_clinical_v1_de_sva, keepers = t_cf_contrast,
#  rda = glue("rda/t_clinical_v1_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_v1_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_v1_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_clinical_v1_table_sva
## A set of combined differential expression results.
##             table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup
## 1 failure_vs_cure          28            74          28            54           3
##   limma_sigdown
## 1             3
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

t_cf_clinical_v1_sig_sva <- extract_significant_genes(
  t_cf_clinical_v1_table_sva,
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_v1_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_v1_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_clinical_v1_sig_sva$deseq$ups[[1]])
## [1] 28 50
dim(t_cf_clinical_v1_sig_sva$deseq$downs[[1]])
## [1] 74 50

6.0.1.2 Cure/Fail, Tumaco Visit 2

The visit 2 and visit 3 samples are interesting because they provide an opportunity to see if we can observe changes in response in the middle and end of treatment…

t_cf_clinical_v2_de_sva <- all_pairwise(tv2_samples, model_batch = "svaseq", filter = TRUE)
## 
##    cure failure 
##      20      15
## Removing 0 low-count genes (11559 remaining).
## Setting 2848 low elements to zero.
## transform_counts: Found 2848 values equal to 0, adding 1 to the matrix.
t_cf_clinical_v2_table_sva <- combine_de_tables(
  t_cf_clinical_v2_de_sva, keepers = t_cf_contrast,
#  rda = glue("rda/t_clinical_v2_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_v2_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_v2_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_clinical_v2_sig_sva <- extract_significant_genes(
  t_cf_clinical_v2_table_sva,
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_v2_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_v2_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_clinical_v2_sig_sva$deseq$ups[[1]])
## [1] 51 50
dim(t_cf_clinical_v2_sig_sva$deseq$downs[[1]])
## [1] 15 50

6.0.1.3 Cure/Fail, Tumaco Visit 3

t_cf_clinical_v3_de_sva <- all_pairwise(tv3_samples, model_batch = "svaseq", filter = TRUE)
## 
##    cure failure 
##      17      17
## Removing 0 low-count genes (11449 remaining).
## Setting 1878 low elements to zero.
## transform_counts: Found 1878 values equal to 0, adding 1 to the matrix.
t_cf_clinical_v3_table_sva <- combine_de_tables(
  t_cf_clinical_v3_de_sva, keepers = t_cf_contrast,
#  rda = glue("rda/t_clinical_v3_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_v3_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_v3_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_clinical_v3_sig_sva <- extract_significant_genes(
  t_cf_clinical_v3_table_sva,
  excel = glue("{xlsx_prefix}/All_Samples/t_clinical_v3_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/All_Samples/t_clinical_v3_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_clinical_v3_sig_sva$deseq$ups[[1]])
## [1] 120  50
dim(t_cf_clinical_v3_sig_sva$deseq$downs[[1]])
## [1] 62 50

6.0.1.4 Visit 1 gProfiler searches

It looks like there are very few groups in the visit 1 significant genes.

t_cf_clinical_v1_sig_sva_gp <- all_gprofiler(t_cf_clinical_v1_sig_sva)

## Wikipathways of the up c/f genes
enrichplot::dotplot(t_cf_clinical_v1_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_clinical_v1_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.1.5 Visit 2 gProfiler searches

Up: 74 GO, 4 KEGG, 6 reactome, 4 WP, 56 TF, 1 miRNA, 0 HP/HPA/CORUM. Down: 19 GO, 1 KEGG, 1 HP, 2 HPA, 0 reactome/wp/tf/corum

t_cf_clinical_v2_sig_sva_gp <- all_gprofiler(t_cf_clinical_v2_sig_sva)

## Wikipathways of the up c/f genes
enrichplot::dotplot(t_cf_clinical_v2_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_clinical_v2_sig_sva_gp[["outcome_up"]][["REAC_enrich"]])

enrichplot::dotplot(t_cf_clinical_v2_sig_sva_gp[["outcome_up"]][["TF_enrich"]])

enrichplot::dotplot(t_cf_clinical_v2_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.1.6 Visit 3 gProfiler searches

Up: 120 genes; 141 GO, 1 KEGG, 5 Reactome, 2 WP, 30 TF, 1 miRNA, 0 HPA/CORUM/HP Down: 62 genes; 30 GO, 2 KEGG, 1 Reactome, 0 WP/TF/miRNA/HPA/CORUM/HP,

t_cf_clinical_v3_sig_sva_gp <- all_gprofiler(t_cf_clinical_v3_sig_sva)

## Wikipathways of the up c/f genes
enrichplot::dotplot(t_cf_clinical_v3_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_clinical_v3_sig_sva_gp[["outcome_up"]][["REAC_enrich"]])

enrichplot::dotplot(t_cf_clinical_v3_sig_sva_gp[["outcome_up"]][["TF_enrich"]])

enrichplot::dotplot(t_cf_clinical_v3_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.2 Repeat no biopsies

The biopsy samples are problematic for a few reasons, so let us repeat without them.

t_cf_clinical_nobiop_de_sva <- all_pairwise(t_clinical_nobiop,
                                            model_batch = "svaseq", filter = TRUE)
## 
##    cure failure 
##      58      51
## Removing 0 low-count genes (11907 remaining).
## Setting 9578 low elements to zero.
## transform_counts: Found 9578 values equal to 0, adding 1 to the matrix.
t_cf_clinical_nobiop_table_sva <- combine_de_tables(
  t_cf_clinical_nobiop_de_sva, keepers = t_cf_contrast,
#  rda = glue("rda/t_clinical_nobiop_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/No_Biopsies/t_clinical_nobiop_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/No_Biopsies/t_clinical_nobiop_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_clinical_nobiop_sig_sva <- extract_significant_genes(
  t_cf_clinical_nobiop_table_sva,
  excel = glue("{xlsx_prefix}/No_Biopsies/t_clinical_nobiop_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/No_Biopsies/t_clinical_nobiop_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_clinical_nobiop_sig_sva$deseq$ups[[1]])
## [1] 137  50
dim(t_cf_clinical_nobiop_sig_sva$deseq$downs[[1]])
## [1] 73 50

6.0.2.1 gProfiler: Clinical no biopsies

Up: 137 genes; 88 GO, 0 KEGG, 6 Reactome, 1 WP, 46 TF, 1 miRNA, 0 others Down: 73 genes; 78 GO, 1 KEGG, 1 Reactome, 9 TF, 0 others

t_cf_clinical_nobiop_sig_sva_gp <- all_gprofiler(t_cf_clinical_nobiop_sig_sva)

enrichplot::dotplot(t_cf_clinical_nobiop_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_clinical_nobiop_sig_sva_gp[["outcome_up"]][["TF_enrich"]])

enrichplot::dotplot(t_cf_clinical_nobiop_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.3 By cell type

Now let us switch our view to each individual cell type collected. The hope here is that we will be able to learn some cell-specific differences in the response for people who did(not) respond well.

6.0.3.1 Cure/Fail, Biopsies

t_cf_biopsy_de_sva <- all_pairwise(t_biopsies, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              9              5
## Removing 0 low-count genes (13506 remaining).
## Setting 145 low elements to zero.
## transform_counts: Found 145 values equal to 0, adding 1 to the matrix.
t_cf_biopsy_table_sva <- combine_de_tables(
  t_cf_biopsy_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_biopsy_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Biopsies/t_biopsy_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Biopsies/t_biopsy_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_biopsy_sig_sva <- extract_significant_genes(
  t_cf_biopsy_table_sva,
  excel = glue("{xlsx_prefix}/Biopsies/t_cf_biopsy_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Biopsies/t_cf_biopsy_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_biopsy_sig_sva$deseq$ups[[1]])
## [1] 17 50
dim(t_cf_biopsy_sig_sva$deseq$downs[[1]])
## [1] 11 50

6.0.3.2 gProfiler: Biopsies

Up: 17 genes; 74 GO, 3 KEGG, 1 Reactome, 3 WP, 1 TF, 0 others Down: 11 genes; 2 GO, 0 others

t_cf_biopsy_sig_sva_gp <- all_gprofiler(t_cf_biopsy_sig_sva)

enrichplot::dotplot(t_cf_biopsy_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_biopsy_sig_sva_gp[["outcome_up"]][["WP_enrich"]])

enrichplot::dotplot(t_cf_biopsy_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.3.3 Cure/Fail, Monocytes

Same question, but this time looking at monocytes. In addition, this comparison was done twice, once using SVA and once using visit as a batch factor.

t_cf_monocyte_de_sva <- all_pairwise(t_monocytes, model_batch = "svaseq",
                                     filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##             21             21
## Removing 0 low-count genes (10859 remaining).
## Setting 730 low elements to zero.
## transform_counts: Found 730 values equal to 0, adding 1 to the matrix.
t_cf_monocyte_tables_sva <- combine_de_tables(
  t_cf_monocyte_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_monocyte_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_monocyte_sig_sva <- extract_significant_genes(
  t_cf_monocyte_tables_sva,
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_monocyte_sig_sva$deseq$ups[[1]])
## [1] 60 50
dim(t_cf_monocyte_sig_sva$deseq$downs[[1]])
## [1] 53 50
t_cf_monocyte_de_batchvisit <- all_pairwise(t_monocytes, model_batch = TRUE, filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##             21             21 
## 
##  3  2  1 
## 13 13 16
t_cf_monocyte_tables_batchvisit <- combine_de_tables(
  t_cf_monocyte_de_batchvisit, keepers = cf_contrast,
#  rda = glue("rda/t_monocyte_cf_table_batchvisit-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_cf_tables_batchvisit-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_cf_tables_batchvisit-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_monocyte_sig_batchvisit <- extract_significant_genes(
  t_cf_monocyte_tables_batchvisit,
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_cf_sig_batchvisit-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_cf_sig_batchvisit-v202305.xlsx before writing the tables.
dim(t_cf_monocyte_sig_batchvisit$deseq$ups[[1]])
## [1] 43 50
dim(t_cf_monocyte_sig_batchvisit$deseq$downs[[1]])
## [1] 93 50

6.0.3.4 gProfiler: Monocytes

Now that I am looking back over these results, I am not compeltely certain why I only did the gprofiler search for the sva data…

Up: 60 genes; 12 GO, 1 KEGG, 1 WP, 4 TF, 0 others Down: 53 genes; 26 GO, 1 KEGG, 1 Reactome, 2 TF, 0 others

t_cf_monocyte_sig_sva_gp <- all_gprofiler(t_cf_monocyte_sig_sva)

enrichplot::dotplot(t_cf_monocyte_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_monocyte_sig_sva_gp[["outcome_up"]][["TF_enrich"]])

enrichplot::dotplot(t_cf_monocyte_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

t_cf_monocyte_sig_batch_gp <- all_gprofiler(t_cf_monocyte_sig_batchvisit)
enrichplot::dotplot(t_cf_monocyte_sig_batch_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_monocyte_sig_batch_gp[["outcome_up"]][["HP_enrich"]])

6.0.4 Individual visits, Monocytes

Now focus in on the monocyte samples on a per-visit basis.

6.0.4.1 Visit 1

t_cf_monocyte_v1_de_sva <- all_pairwise(tv1_monocytes, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              8              8
## Removing 0 low-count genes (10479 remaining).
## Setting 187 low elements to zero.
## transform_counts: Found 187 values equal to 0, adding 1 to the matrix.
t_cf_monocyte_v1_tables_sva <- combine_de_tables(
  t_cf_monocyte_v1_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_monocyte_v1_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_v1_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_v1_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_monocyte_v1_sig_sva <- extract_significant_genes(
  t_cf_monocyte_v1_tables_sva,
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_v1_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_v1_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_monocyte_v1_sig_sva$deseq$ups[[1]])
## [1] 14 50
dim(t_cf_monocyte_v1_sig_sva$deseq$downs[[1]])
## [1] 52 50

6.0.4.2 Visit 2

t_cf_monocyte_v2_de_sva <- all_pairwise(tv2_monocytes, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              7              6
## Removing 0 low-count genes (10520 remaining).
## Setting 115 low elements to zero.
## transform_counts: Found 115 values equal to 0, adding 1 to the matrix.
t_cf_monocyte_v2_tables_sva <- combine_de_tables(
  t_cf_monocyte_v2_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_monocyte_v2_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_v2_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_v2_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_monocyte_v2_sig_sva <- extract_significant_genes(
  t_cf_monocyte_v2_tables_sva,
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_v2_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_v2_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_monocyte_v2_sig_sva$deseq$ups[[1]])
## [1]  0 50
dim(t_cf_monocyte_v2_sig_sva$deseq$downs[[1]])
## [1]  1 50

6.0.4.3 Visit 3

t_cf_monocyte_v3_de_sva <- all_pairwise(tv3_monocytes, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              6              7
## Removing 0 low-count genes (10374 remaining).
## Setting 55 low elements to zero.
## transform_counts: Found 55 values equal to 0, adding 1 to the matrix.
t_cf_monocyte_v3_tables_sva <- combine_de_tables(
  t_cf_monocyte_v3_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_monocyte_v3_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_v3_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_v3_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_monocyte_v3_sig_sva <- extract_significant_genes(
  t_cf_monocyte_v3_tables_sva,
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_v3_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_v3_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_monocyte_v3_sig_sva$deseq$ups[[1]])
## [1]  0 50
dim(t_cf_monocyte_v3_sig_sva$deseq$downs[[1]])
## [1]  4 50

6.0.4.4 Monocytes: Compare sva to batch-in-model

sva_aucc <- calculate_aucc(t_cf_monocyte_tables_sva[["data"]][[1]],
                           tbl2 = t_cf_monocyte_tables_batchvisit[["data"]][[1]],
                           py = "deseq_adjp", ly = "deseq_logfc")
sva_aucc
## These two tables have an aucc value of: 0.694262174264411 and correlation:
## 
##  Pearson's product-moment correlation
## 
## data:  tbl[[lx]] and tbl[[ly]]
## t = 180, df = 10857, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8611 0.8705
## sample estimates:
##    cor 
## 0.8659

shared_ids <- rownames(t_cf_monocyte_tables_sva[["data"]][[1]]) %in%
  rownames(t_cf_monocyte_tables_batchvisit[["data"]][[1]])
first <- t_cf_monocyte_tables_sva[["data"]][[1]][shared_ids, ]
second <- t_cf_monocyte_tables_batchvisit[["data"]][[1]][rownames(first), ]
cor.test(first[["deseq_logfc"]], second[["deseq_logfc"]])
## 
##  Pearson's product-moment correlation
## 
## data:  first[["deseq_logfc"]] and second[["deseq_logfc"]]
## t = 180, df = 10857, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8611 0.8705
## sample estimates:
##    cor 
## 0.8659
6.0.4.4.1 gProfiler: Monocytes by visit, V1

V1: Up: 14 genes; No categories V1: Down: 52 genes; 20 GO, 5 TF

t_cf_monocyte_v1_sig_sva_gp <- all_gprofiler(t_cf_monocyte_v1_sig_sva)

enrichplot::dotplot(t_cf_monocyte_v1_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.4.4.2 gProfiler: Monocytes by visit, V2

V2: Up: 1 gene V2: Down: 0 genes.

6.0.4.4.3 gProfiler: Monocytes by visit, V3

V3: Up: 4 genes. V3: Down: 0 genes.

6.0.5 Neutrophil samples

Switch context to the Neutrophils, once again repeat the analysis using SVA and visit as a batch factor.

t_cf_neutrophil_de_sva <- all_pairwise(t_neutrophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##             20             21
## Removing 0 low-count genes (9099 remaining).
## Setting 750 low elements to zero.
## transform_counts: Found 750 values equal to 0, adding 1 to the matrix.
t_cf_neutrophil_tables_sva <- combine_de_tables(
  t_cf_neutrophil_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_neutrophil_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_neutrophil_sig_sva <- extract_significant_genes(
  t_cf_neutrophil_tables_sva,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_neutrophil_sig_sva$deseq$ups[[1]])
## [1] 84 50
dim(t_cf_neutrophil_sig_sva$deseq$downs[[1]])
## [1] 29 50
t_cf_neutrophil_de_batchvisit <- all_pairwise(t_neutrophils, model_batch = TRUE, filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##             20             21 
## 
##  3  2  1 
## 12 13 16
t_cf_neutrophil_tables_batchvisit <- combine_de_tables(
  t_cf_neutrophil_de_batchvisit, keepers = cf_contrast,
#  rda = glue("rda/t_neutrophil_cf_table_batchvisit-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_cf_tables_batchvisit-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_cf_tables_batchvisit-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_neutrophil_sig_batchvisit <- extract_significant_genes(
  t_cf_neutrophil_tables_batchvisit,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_cf_sig_batchvisit-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_cf_sig_batchvisit-v202305.xlsx before writing the tables.
dim(t_cf_neutrophil_sig_batchvisit$deseq$ups[[1]])
## [1] 92 50
dim(t_cf_neutrophil_sig_batchvisit$deseq$downs[[1]])
## [1] 47 50

6.0.5.1 gProfiler: Neutrophils

Up: 84 genes; 5 GO, 2 Reactome, 3 TF, no others. Down: 29 genes: 12 GO, 1 Reactome, 1 TF, 1 miRNA, 11 HP, 0 others

t_cf_neutrophil_sig_sva_gp <- all_gprofiler(t_cf_neutrophil_sig_sva)

enrichplot::dotplot(t_cf_neutrophil_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_neutrophil_sig_sva_gp[["outcome_up"]][["TF_enrich"]])

enrichplot::dotplot(t_cf_neutrophil_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_neutrophil_sig_sva_gp[["outcome_down"]][["HP_enrich"]])

6.0.5.2 Neutrophils by visit

When I did this with the monocytes, I split it up into multiple blocks for each visit. This time I am just going to run them all together.

visitcf_factor <- paste0("v", pData(t_neutrophils)[["visitnumber"]],
                         pData(t_neutrophils)[["finaloutcome"]])
t_neutrophil_visitcf <- set_expt_conditions(t_neutrophils, fact=visitcf_factor)
## The numbers of samples by condition are:
## 
##    v1cure v1failure    v2cure v2failure    v3cure v3failure 
##         8         8         7         6         5         7
t_cf_neutrophil_visits_de_sva <- all_pairwise(t_neutrophil_visitcf, model_batch = "svaseq",
                                              filter = TRUE)
## 
##    v1cure v1failure    v2cure v2failure    v3cure v3failure 
##         8         8         7         6         5         7
## Removing 0 low-count genes (9099 remaining).
## Setting 686 low elements to zero.
## transform_counts: Found 686 values equal to 0, adding 1 to the matrix.

t_cf_neutrophil_visits_tables_sva <- combine_de_tables(
  t_cf_neutrophil_visits_de_sva, keepers = visitcf_contrasts,
#  rda = glue("rda/t_neutrophil_visitcf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_visitcf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_visitcf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for v1cf.
## Adding venn plots for v2cf.
## Adding venn plots for v3cf.
t_cf_neutrophil_visits_sig_sva <- extract_significant_genes(
  t_cf_neutrophil_visits_tables_sva,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_visitcf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_visitcf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_neutrophil_visits_sig_sva$deseq$ups[[1]])
## [1] 12 50
dim(t_cf_neutrophil_visits_sig_sva$deseq$downs[[1]])
## [1]  6 50
t_cf_neutrophil_v1_de_sva <- all_pairwise(tv1_neutrophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              8              8
## Removing 0 low-count genes (8715 remaining).
## Setting 145 low elements to zero.
## transform_counts: Found 145 values equal to 0, adding 1 to the matrix.
t_cf_neutrophil_v1_tables_sva <- combine_de_tables(
  t_cf_neutrophil_v1_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_neutrophil_v1_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_v1_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_v1_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_neutrophil_v1_sig_sva <- extract_significant_genes(
  t_cf_neutrophil_v1_tables_sva,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_v1_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_v1_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_neutrophil_v1_sig_sva$deseq$ups[[1]])
## [1]  5 50
dim(t_cf_neutrophil_v1_sig_sva$deseq$downs[[1]])
## [1]  8 50
t_cf_neutrophil_v2_de_sva <- all_pairwise(tv2_neutrophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              7              6
## Removing 0 low-count genes (8450 remaining).
## Setting 78 low elements to zero.
## transform_counts: Found 78 values equal to 0, adding 1 to the matrix.
t_cf_neutrophil_v2_tables_sva <- combine_de_tables(
  t_cf_neutrophil_v2_de_sva,
  keepers = cf_contrast,
#  rda = glue("rda/t_neutrophil_v2_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_v2_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_v2_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_neutrophil_v2_sig_sva <- extract_significant_genes(
  t_cf_neutrophil_v2_tables_sva,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_v2_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_v2_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_neutrophil_v2_sig_sva$deseq$ups[[1]])
## [1]  9 50
dim(t_cf_neutrophil_v2_sig_sva$deseq$downs[[1]])
## [1]  3 50
t_cf_neutrophil_v3_de_sva <- all_pairwise(tv3_neutrophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              5              7
## Removing 0 low-count genes (8503 remaining).
## Setting 83 low elements to zero.
## transform_counts: Found 83 values equal to 0, adding 1 to the matrix.
t_cf_neutrophil_v3_tables_sva <- combine_de_tables(
  t_cf_neutrophil_v3_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_neutrophil_v3_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_v3_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_v3_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_neutrophil_v3_sig_sva <- extract_significant_genes(
  t_cf_neutrophil_v3_tables_sva,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_v3_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_v3_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_neutrophil_v3_sig_sva$deseq$ups[[1]])
## [1]  5 50
dim(t_cf_monocyte_v3_sig_sva$deseq$downs[[1]])
## [1]  4 50
6.0.5.2.1 gProfiler: Neutrophils by visit, V1

V1: Up: 5 genes V1: Down: 8 genes; 14 GO.

t_cf_neutrophil_v1_sig_sva_gp <- all_gprofiler(t_cf_neutrophil_v1_sig_sva)

enrichplot::dotplot(t_cf_neutrophil_v1_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

6.0.5.2.2 gProfiler: Neutrophils by visit, V2

Up: 5 genes; 3 GO, 10 TF. Down: 1 gene.

6.0.5.3 Neutrophils: Compare sva to batch-in-model

sva_aucc <- calculate_aucc(t_cf_neutrophil_tables_sva[["data"]][[1]],
                           tbl2 = t_cf_neutrophil_tables_batchvisit[["data"]][[1]],
                           py = "deseq_adjp", ly = "deseq_logfc")
sva_aucc
## These two tables have an aucc value of: 0.610986598472877 and correlation:
## 
##  Pearson's product-moment correlation
## 
## data:  tbl[[lx]] and tbl[[ly]]
## t = 192, df = 9097, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8915 0.8996
## sample estimates:
##    cor 
## 0.8956

shared_ids <- rownames(t_cf_neutrophil_tables_sva[["data"]][[1]]) %in%
  rownames(t_cf_neutrophil_tables_batchvisit[["data"]][[1]])
first <- t_cf_neutrophil_tables_sva[["data"]][[1]][shared_ids, ]
second <- t_cf_neutrophil_tables_batchvisit[["data"]][[1]][rownames(first), ]
cor.test(first[["deseq_logfc"]], second[["deseq_logfc"]])
## 
##  Pearson's product-moment correlation
## 
## data:  first[["deseq_logfc"]] and second[["deseq_logfc"]]
## t = 192, df = 9097, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8915 0.8996
## sample estimates:
##    cor 
## 0.8956

6.0.6 Eosinophils

This time, with feeling! Repeating the same set of tasks with the eosinophil samples.

t_cf_eosinophil_de_sva <- all_pairwise(t_eosinophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##             17              9
## Removing 0 low-count genes (10530 remaining).
## Setting 325 low elements to zero.
## transform_counts: Found 325 values equal to 0, adding 1 to the matrix.
t_cf_eosinophil_tables_sva <- combine_de_tables(
  t_cf_eosinophil_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_eosinophil_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_eosinophil_sig_sva <- extract_significant_genes(
  t_cf_eosinophil_tables_sva,
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_eosinophil_sig_sva$deseq$ups[[1]])
## [1] 116  50
dim(t_cf_eosinophil_sig_sva$deseq$downs[[1]])
## [1] 74 50
t_cf_eosinophil_de_batchvisit <- all_pairwise(t_eosinophils, model_batch = TRUE, filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##             17              9 
## 
## 3 2 1 
## 9 9 8
t_cf_eosinophil_tables_batchvisit <- combine_de_tables(
  t_cf_eosinophil_de_batchvisit, keepers = cf_contrast,
#  rda = glue("rda/t_eosinophil_cf_table_batchvisit-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_cf_tables_batchvisit-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_cf_tables_batchvisit-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_eosinophil_sig_batchvisit <- extract_significant_genes(
  t_cf_eosinophil_tables_batchvisit,
  excel = glue("excel/t_eosinophil_cf_sig_batchvisit-v{ver}.xlsx"))
## Deleting the file excel/t_eosinophil_cf_sig_batchvisit-v202305.xlsx before writing the tables.
dim(t_cf_eosinophil_sig_batchvisit$deseq$ups[[1]])
## [1] 99 50
dim(t_cf_eosinophil_sig_batchvisit$deseq$downs[[1]])
## [1] 35 50
visitcf_factor <- paste0("v", pData(t_eosinophils)[["visitnumber"]],
                         pData(t_eosinophils)[["finaloutcome"]])
t_eosinophil_visitcf <- set_expt_conditions(t_eosinophils, fact = visitcf_factor)
## The numbers of samples by condition are:
## 
##    v1cure v1failure    v2cure v2failure    v3cure v3failure 
##         5         3         6         3         6         3
t_cf_eosinophil_visits_de_sva <- all_pairwise(t_eosinophil_visitcf, model_batch = "svaseq",
                                              filter = TRUE)
## 
##    v1cure v1failure    v2cure v2failure    v3cure v3failure 
##         5         3         6         3         6         3
## Removing 0 low-count genes (10530 remaining).
## Setting 374 low elements to zero.
## transform_counts: Found 374 values equal to 0, adding 1 to the matrix.

t_cf_eosinophil_visits_tables_sva <- combine_de_tables(
  t_cf_eosinophil_visits_de_sva, keepers = visitcf_contrasts,
#  rda = glue("rda/t_eosinophil_visitcf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_visitcf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_visitcf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for v1cf.
## Adding venn plots for v2cf.
## Adding venn plots for v3cf.
t_cf_eosinophil_visits_sig_sva <- extract_significant_genes(
  t_cf_eosinophil_visits_tables_sva,
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_visitcf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_visitcf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_eosinophil_visits_sig_sva$deseq$ups[[1]])
## [1]  9 50
dim(t_cf_eosinophil_visits_sig_sva$deseq$downs[[1]])
## [1] 11 50

6.0.6.1 C/F celltype volcano plots with specific labels

num_color <- color_choices[["clinic_cf"]][["Tumaco_failure"]]
den_color <- color_choices[["clinic_cf"]][["Tumaco_cure"]]
wanted_genes <- c("FI44L", "IFI27", "PRR5", "PRR5-ARHGAP8", "RHCE",
                  "FBXO39", "RSAD2", "SMTNL1", "USP18", "AFAP1")

cf_monocyte_table <- t_cf_monocyte_tables_sva[["data"]][["outcome"]]
cf_monocyte_volcano <- plot_volcano_condition_de(
  cf_monocyte_table, "outcome", label = wanted_genes,
  fc_col = "deseq_logfc", p_col = "deseq_adjp", line_position = NULL,
  color_high = num_color, color_low = den_color, label_size = 6)
pp(file = glue("images/cf_monocyte_volcano_labeled-v{ver}.svg"))
cf_monocyte_volcano$plot
dev.off()
## png 
##   2
cf_monocyte_volcano$plot

cf_eosinophil_table <- t_cf_eosinophil_tables_sva[["data"]][["outcome"]]
cf_eosinophil_volcano <- plot_volcano_condition_de(
  cf_eosinophil_table, "outcome", label = wanted_genes,
  fc_col = "deseq_logfc", p_col = "deseq_adjp", line_position = NULL,
  color_high = num_color, color_low = den_color, label_size = 6)
pp(file = glue("images/cf_eosinophil_volcano_labeled-v{ver}.svg"))
cf_eosinophil_volcano$plot
dev.off()
## png 
##   2
cf_eosinophil_volcano$plot

cf_neutrophil_table <- t_cf_neutrophil_tables_sva[["data"]][["outcome"]]
cf_neutrophil_volcano <- plot_volcano_condition_de(
  cf_neutrophil_table, "outcome", label = wanted_genes,
  fc_col = "deseq_logfc", p_col = "deseq_adjp", line_position = NULL,
  color_high = num_color, color_low = den_color, label_size = 6)
pp(file = glue("images/cf_neutrophil_volcano_labeled-v{ver}.svg"))
cf_neutrophil_volcano$plot
dev.off()
## png 
##   2
cf_neutrophil_volcano$plot

6.0.6.2 gProfiler: Eosinophils

Up: 116 genes; 123 GO, 2 KEGG, 7 Reactome, 5 WP, 69 TF, 1 miRNA, 0 others Down: 74 genes; 5 GO, 1 Reactome, 4 TF, 0 others

t_cf_eosinophil_sig_sva_gp <- all_gprofiler(t_cf_eosinophil_sig_sva)

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["REAC_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["WP_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["TF_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_down"]][["TF_enrich"]])

6.0.7 Eosinophil time comparisons

t_cf_eosinophil_v1_de_sva <- all_pairwise(tv1_eosinophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              5              3
## Removing 0 low-count genes (9977 remaining).
## Setting 57 low elements to zero.
## transform_counts: Found 57 values equal to 0, adding 1 to the matrix.
t_cf_eosinophil_v1_tables_sva <- combine_de_tables(
  t_cf_eosinophil_v1_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_eosinophil_v1_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_v1_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_v1_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_eosinophil_v1_sig_sva <- extract_significant_genes(
  t_cf_eosinophil_v1_tables_sva,
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_v1_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_v1_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_eosinophil_v1_sig_sva$deseq$ups[[1]])
## [1] 13 50
dim(t_cf_eosinophil_v1_sig_sva$deseq$downs[[1]])
## [1] 19 50
t_cf_eosinophil_v2_de_sva <- all_pairwise(tv2_eosinophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              6              3
## Removing 0 low-count genes (10115 remaining).
## Setting 90 low elements to zero.
## transform_counts: Found 90 values equal to 0, adding 1 to the matrix.
t_cf_eosinophil_v2_tables_sva <- combine_de_tables(
  t_cf_eosinophil_v2_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_eosinophil_v2_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_v2_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_v2_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_eosinophil_v2_sig_sva <- extract_significant_genes(
  t_cf_eosinophil_v2_tables_sva,
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_v2_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_v2_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_eosinophil_v2_sig_sva$deseq$ups[[1]])
## [1]  9 50
dim(t_cf_eosinophil_v2_sig_sva$deseq$downs[[1]])
## [1]  4 50
t_cf_eosinophil_v3_de_sva <- all_pairwise(tv3_eosinophils, model_batch = "svaseq", filter = TRUE)
## 
##    Tumaco_cure Tumaco_failure 
##              6              3
## Removing 0 low-count genes (10078 remaining).
## Setting 48 low elements to zero.
## transform_counts: Found 48 values equal to 0, adding 1 to the matrix.
t_cf_eosinophil_v3_tables_sva <- combine_de_tables(
  t_cf_eosinophil_v3_de_sva, keepers = cf_contrast,
#  rda = glue("rda/t_eosinophil_v3_cf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_v3_cf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_v3_cf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for outcome.
t_cf_eosinophil_v3_sig_sva <- extract_significant_genes(
  t_cf_eosinophil_v3_tables_sva,
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_v3_cf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_v3_cf_sig_sva-v202305.xlsx before writing the tables.
dim(t_cf_eosinophil_v3_sig_sva$deseq$ups[[1]])
## [1] 68 50
dim(t_cf_eosinophil_v3_sig_sva$deseq$downs[[1]])
## [1] 29 50

6.0.7.1 gProfiler: Eosinophils V1

Up: 13 genes, no hits. Down: 19 genes; 11 GO, 1 Reactome, 1 TF

t_cf_eosinophil_v1_sig_sva_gp <- all_gprofiler(t_cf_eosinophil_v1_sig_sva)

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_down"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_down"]][["TF_enrich"]])

6.0.7.2 gProfiler: Eosinophils V2

Up: 9 genes; 23 GO, 2 KEGG, 2 Reactome, 4 WP Down: 4 genes; no hits

t_cf_eosinophil_v2_sig_sva_gp <- all_gprofiler(t_cf_eosinophil_v2_sig_sva)

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["WP_enrich"]])

6.0.7.3 gProfiler: Eosinophils V3

Up: 68 genes; 95 GO, 2 KEGG, 12 Reactome, 3 WP, 63 TF, 1 miRNA Down: 29 genes; 3 GO, 1 WP, 1 TF, 3 miRNA

t_cf_eosinophil_v3_sig_sva_gp <- all_gprofiler(t_cf_eosinophil_v3_sig_sva)

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["GO_enrich"]])

enrichplot::dotplot(t_cf_eosinophil_sig_sva_gp[["outcome_up"]][["WP_enrich"]])

6.0.7.4 Eosinophils: Compare sva to batch-in-visit

sva_aucc <- calculate_aucc(t_cf_eosinophil_tables_sva[["data"]][[1]],
                           tbl2 = t_cf_eosinophil_tables_batchvisit[["data"]][[1]],
                           py = "deseq_adjp", ly = "deseq_logfc")
sva_aucc
## These two tables have an aucc value of: 0.576379766133087 and correlation:
## 
##  Pearson's product-moment correlation
## 
## data:  tbl[[lx]] and tbl[[ly]]
## t = 152, df = 10528, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8232 0.8352
## sample estimates:
##    cor 
## 0.8293

shared_ids <- rownames(t_cf_eosinophil_tables_sva[["data"]][[1]]) %in%
  rownames(t_cf_eosinophil_tables_batchvisit[["data"]][[1]])
first <- t_cf_eosinophil_tables_sva[["data"]][[1]][shared_ids, ]
second <- t_cf_eosinophil_tables_batchvisit[["data"]][[1]][rownames(first), ]
cor.test(first[["deseq_logfc"]], second[["deseq_logfc"]])
## 
##  Pearson's product-moment correlation
## 
## data:  first[["deseq_logfc"]] and second[["deseq_logfc"]]
## t = 152, df = 10528, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8232 0.8352
## sample estimates:
##    cor 
## 0.8293

6.0.7.5 Compare monocyte CF, neutrophil CF, eosinophil CF

t_mono_neut_sva_aucc <- calculate_aucc(t_cf_monocyte_tables_sva[["data"]][["outcome"]],
                                       tbl2 = t_cf_neutrophil_tables_sva[["data"]][["outcome"]],
                                       py = "deseq_adjp", ly = "deseq_logfc")
t_mono_neut_sva_aucc
## These two tables have an aucc value of: 0.205805764086195 and correlation:
## 
##  Pearson's product-moment correlation
## 
## data:  tbl[[lx]] and tbl[[ly]]
## t = 43, df = 8575, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.4033 0.4381
## sample estimates:
##    cor 
## 0.4209

t_mono_eo_sva_aucc <- calculate_aucc(t_cf_monocyte_tables_sva[["data"]][["outcome"]],
                                     tbl2 = t_cf_eosinophil_tables_sva[["data"]][["outcome"]],
                                     py = "deseq_adjp", ly = "deseq_logfc")
t_mono_eo_sva_aucc
## These two tables have an aucc value of: 0.0965690285832397 and correlation:
## 
##  Pearson's product-moment correlation
## 
## data:  tbl[[lx]] and tbl[[ly]]
## t = 22, df = 9763, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.2028 0.2405
## sample estimates:
##    cor 
## 0.2217

t_neut_eo_sva_aucc <- calculate_aucc(t_cf_neutrophil_tables_sva[["data"]][["outcome"]],
                                     tbl2 = t_cf_eosinophil_tables_sva[["data"]][["outcome"]],
                                     py = "deseq_adjp", ly = "deseq_logfc")
t_neut_eo_sva_aucc
## These two tables have an aucc value of: 0.158277945983764 and correlation:
## 
##  Pearson's product-moment correlation
## 
## data:  tbl[[lx]] and tbl[[ly]]
## t = 36, df = 8569, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.3467 0.3834
## sample estimates:
##    cor 
## 0.3652

6.0.8 By visit

For these contrasts, we want to see fail_v1 vs. cure_v1, fail_v2 vs. cure_v2 etc. As a result, we will need to juggle the data slightly and add another set of contrasts.

6.0.8.1 Cure/Fail by visits, all cell types

t_visit_cf_all_de_sva <- all_pairwise(t_visitcf, model_batch = "svaseq", filter = TRUE)
## 
##    v1cure v1failure    v2cure v2failure    v3cure v3failure 
##        30        24        20        15        17        17
## Removing 0 low-count genes (14149 remaining).
## Setting 17117 low elements to zero.
## transform_counts: Found 17117 values equal to 0, adding 1 to the matrix.

t_visit_cf_all_tables_sva <- combine_de_tables(
  t_visit_cf_all_de_sva, keepers = visitcf_contrasts,
#  rda = glue("rda/t_all_visitcf_table_sva-v{ver}.rda"),
  excel = glue("analyses/4_tumaco/DE_Cure_vs_Fail/t_all_visitcf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/t_all_visitcf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for v1cf.
## Adding venn plots for v2cf.
## Adding venn plots for v3cf.
t_visit_cf_all_sig_sva <- extract_significant_genes(
  t_visit_cf_all_tables_sva,
  excel = glue("analyses/4_tumaco/DE_Cure_vs_Fail/t_all_visitcf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/t_all_visitcf_sig_sva-v202305.xlsx before writing the tables.
t_visit_cf_all_gp <- all_gprofiler(t_visit_cf_all_sig_sva)

6.0.8.2 Cure/Fail by visit, Monocytes

visitcf_factor <- paste0("v", pData(t_monocytes)[["visitnumber"]], "_",
                         pData(t_monocytes)[["finaloutcome"]])
t_monocytes_visitcf <- set_expt_conditions(t_monocytes, fact = visitcf_factor)
## The numbers of samples by condition are:
## 
##    v1_cure v1_failure    v2_cure v2_failure    v3_cure v3_failure 
##          8          8          7          6          6          7
t_visit_cf_monocyte_de_sva <- all_pairwise(t_monocytes_visitcf, model_batch = "svaseq",
                                           filter = TRUE)
## 
##    v1_cure v1_failure    v2_cure v2_failure    v3_cure v3_failure 
##          8          8          7          6          6          7
## Removing 0 low-count genes (10859 remaining).
## Setting 688 low elements to zero.
## transform_counts: Found 688 values equal to 0, adding 1 to the matrix.

t_visit_cf_monocyte_tables_sva <- combine_de_tables(
  t_visit_cf_monocyte_de_sva, keepers = visitcf_contrasts,
#  rda = glue("rda/t_monocyte_visitcf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_visitcf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_visitcf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for v1cf.
## Adding venn plots for v2cf.
## Adding venn plots for v3cf.
t_visit_cf_monocyte_sig_sva <- extract_significant_genes(
  t_visit_cf_monocyte_tables_sva,
  excel = glue("{xlsx_prefix}/Monocytes/t_monocyte_visitcf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Monocytes/t_monocyte_visitcf_sig_sva-v202305.xlsx before writing the tables.
t_v1fc_deseq_ma <- t_visit_cf_monocyte_tables_sva[["plots"]][["v1cf"]][["deseq_ma_plots"]][["plot"]]
dev <- pp(file = "images/monocyte_cf_de_v1_maplot.png")
t_v1fc_deseq_ma
## NULL
closed <- dev.off()
t_v1fc_deseq_ma
## NULL
t_v2fc_deseq_ma <- t_visit_cf_monocyte_tables_sva[["plots"]][["v2cf"]][["deseq_ma_plots"]][["plot"]]
dev <- pp(file = "images/monocyte_cf_de_v2_maplot.png")
t_v2fc_deseq_ma
## NULL
closed <- dev.off()
t_v2fc_deseq_ma
## NULL
t_v3fc_deseq_ma <- t_visit_cf_monocyte_tables_sva[["plots"]][["v3cf"]][["deseq_ma_plots"]][["plot"]]
dev <- pp(file = "images/monocyte_cf_de_v3_maplot.png")
t_v3fc_deseq_ma
## NULL
closed <- dev.off()
t_v3fc_deseq_ma
## NULL

One query from Alejandro is to look at the genes shared up/down across visits. I am not entirely certain we have enough samples for this to work, but let us find out.

I am thinking this is a good place to use the AUCC curves I learned about thanks to Julie Cridland.

Note that the following is all monocyte samples, this should therefore potentially be moved up and a version of this with only the Tumaco samples put here?

v1cf <- t_visit_cf_monocyte_tables_sva[["data"]][["v1cf"]]
v2cf <- t_visit_cf_monocyte_tables_sva[["data"]][["v2cf"]]
v3cf <- t_visit_cf_monocyte_tables_sva[["data"]][["v3cf"]]

v1_sig <- c(
  rownames(t_visit_cf_monocyte_sig_sva[["deseq"]][["ups"]][["v1cf"]]),
  rownames(t_visit_cf_monocyte_sig_sva[["deseq"]][["downs"]][["v1cf"]]))
length(v1_sig)
## [1] 25
v2_sig <- c(
  rownames(t_visit_cf_monocyte_sig_sva[["deseq"]][["ups"]][["v2cf"]]),
  rownames(t_visit_cf_monocyte_sig_sva[["deseq"]][["downs"]][["v2cf"]]))
length(v2_sig)
## [1] 0
v3_sig <- c(
  rownames(t_visit_cf_monocyte_sig_sva[["deseq"]][["ups"]][["v2cf"]]),
  rownames(t_visit_cf_monocyte_sig_sva[["deseq"]][["downs"]][["v2cf"]]))
length(v3_sig)
## [1] 0
t_monocyte_visit_aucc_v2v1 <- calculate_aucc(v1cf, tbl2 = v2cf,
                                             py = "deseq_adjp", ly = "deseq_logfc")
dev <- pp(file = "images/monocyte_visit_v2v1_aucc.png")
t_monocyte_visit_aucc_v2v1[["plot"]]
closed <- dev.off()
t_monocyte_visit_aucc_v2v1[["plot"]]

t_monocyte_visit_aucc_v3v1 <- calculate_aucc(v1cf, tbl2 = v3cf,
                                             py = "deseq_adjp", ly = "deseq_logfc")
dev <- pp(file = "images/monocyte_visit_v3v1_aucc.png")
t_monocyte_visit_aucc_v3v1[["plot"]]
closed <- dev.off()
t_monocyte_visit_aucc_v3v1[["plot"]]

6.0.8.3 Cure/Fail by visit, Neutrophils

visitcf_factor <- paste0("v", pData(t_neutrophils)[["visitnumber"]], "_",
                         pData(t_neutrophils)[["finaloutcome"]])
t_neutrophil_visitcf <- set_expt_conditions(t_neutrophils, fact = visitcf_factor)
## The numbers of samples by condition are:
## 
##    v1_cure v1_failure    v2_cure v2_failure    v3_cure v3_failure 
##          8          8          7          6          5          7
t_visit_cf_neutrophil_de_sva <- all_pairwise(t_neutrophil_visitcf, model_batch = "svaseq",
                                             filter = TRUE)
## 
##    v1_cure v1_failure    v2_cure v2_failure    v3_cure v3_failure 
##          8          8          7          6          5          7
## Removing 0 low-count genes (9099 remaining).
## Setting 686 low elements to zero.
## transform_counts: Found 686 values equal to 0, adding 1 to the matrix.

t_visit_cf_neutrophil_tables_sva <- combine_de_tables(
  t_visit_cf_neutrophil_de_sva, keepers = visitcf_contrasts,
#  rda = glue("rda/t_neutrophil_visitcf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_visitcf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_visitcf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for v1cf.
## Adding venn plots for v2cf.
## Adding venn plots for v3cf.
t_visit_cf_neutrophil_sig_sva <- extract_significant_genes(
  t_visit_cf_neutrophil_tables_sva,
  excel = glue("{xlsx_prefix}/Neutrophils/t_neutrophil_visitcf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Neutrophils/t_neutrophil_visitcf_sig_sva-v202305.xlsx before writing the tables.

6.0.8.4 Cure/Fail by visit, Eosinophils

visitcf_factor <- paste0("v", pData(t_eosinophils)[["visitnumber"]], "_",
                         pData(t_eosinophils)[["finaloutcome"]])
t_eosinophil_visitcf <- set_expt_conditions(t_eosinophils, fact = visitcf_factor)
## The numbers of samples by condition are:
## 
##    v1_cure v1_failure    v2_cure v2_failure    v3_cure v3_failure 
##          5          3          6          3          6          3
t_visit_cf_eosinophil_de_sva <- all_pairwise(t_eosinophil_visitcf, model_batch = "svaseq",
                                             filter = TRUE)
## 
##    v1_cure v1_failure    v2_cure v2_failure    v3_cure v3_failure 
##          5          3          6          3          6          3
## Removing 0 low-count genes (10530 remaining).
## Setting 374 low elements to zero.
## transform_counts: Found 374 values equal to 0, adding 1 to the matrix.

t_visit_cf_eosinophil_tables_sva <- combine_de_tables(
  t_visit_cf_eosinophil_de_sva, keepers = visitcf_contrasts,
#  rda = glue("rda/t_eosinophil_visitcf_table_sva-v{ver}.rda"),
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_visitcf_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_visitcf_tables_sva-v202305.xlsx before writing the tables.
## Adding venn plots for v1cf.
## Adding venn plots for v2cf.
## Adding venn plots for v3cf.
t_visit_cf_eosinophil_sig_sva <- extract_significant_genes(
  t_visit_cf_eosinophil_tables_sva,
  excel = glue("{xlsx_prefix}/Eosinophils/t_eosinophil_visitcf_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Cure_vs_Fail/Eosinophils/t_eosinophil_visitcf_sig_sva-v202305.xlsx before writing the tables.

6.1 Persistence in visit 3

Having put some SL read mapping information in the sample sheet, Maria Adelaida added a new column using it with the putative persistence state on a per-sample basis. One question which arised from that: what differences are observable between the persistent yes vs. no samples on a per-cell-type basis among the visit 3 samples.

6.1.1 Setting up

First things first, create the datasets.

persistence_expt <- subset_expt(t_clinical, subset = "persistence=='Y'|persistence=='N'") %>%
  subset_expt(subset = 'visitnumber==3') %>%
  set_expt_conditions(fact = 'persistence')
## subset_expt(): There were 123, now there are 97 samples.
## subset_expt(): There were 97, now there are 30 samples.
## The numbers of samples by condition are:
## 
##  N  Y 
##  6 24
## persistence_biopsy <- subset_expt(persistence_expt, subset = "typeofcells=='biopsy'")
persistence_monocyte <- subset_expt(persistence_expt, subset = "typeofcells=='monocytes'")
## subset_expt(): There were 30, now there are 12 samples.
persistence_neutrophil <- subset_expt(persistence_expt, subset = "typeofcells=='neutrophils'")
## subset_expt(): There were 30, now there are 10 samples.
persistence_eosinophil <- subset_expt(persistence_expt, subset = "typeofcells=='eosinophils'")
## subset_expt(): There were 30, now there are 8 samples.

6.1.2 Take a look

See if there are any patterns which look usable.

## All
persistence_norm <- normalize_expt(persistence_expt, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
## Removing 8537 low-count genes (11386 remaining).
## transform_counts: Found 15 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_norm)$plot

persistence_nb <- normalize_expt(persistence_expt, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
## Removing 8537 low-count genes (11386 remaining).
## Setting 1538 low elements to zero.
## transform_counts: Found 1538 values equal to 0, adding 1 to the matrix.
plot_pca(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
persistence_monocyte_norm <- normalize_expt(persistence_monocyte, transform = "log2", convert = "cpm",
                                            norm = "quant", filter = TRUE)
## Removing 9597 low-count genes (10326 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_monocyte_norm)$plot

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

## Neutrophils
persistence_neutrophil_norm <- normalize_expt(persistence_neutrophil, transform = "log2", convert = "cpm",
                                              norm = "quant", filter = TRUE)
## Removing 11531 low-count genes (8392 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_neutrophil_norm)$plot

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

## Eosinophils
persistence_eosinophil_norm <- normalize_expt(persistence_eosinophil, transform = "log2", convert = "cpm",
                                              norm = "quant", filter = TRUE)
## Removing 9895 low-count genes (10028 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_eosinophil_norm)$plot

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

6.1.3 persistence DE

persistence_de_sva <- all_pairwise(persistence_expt, filter = TRUE, model_batch = "svaseq")
## 
##  N  Y 
##  6 24
## Removing 0 low-count genes (11386 remaining).
## Setting 1538 low elements to zero.
## transform_counts: Found 1538 values equal to 0, adding 1 to the matrix.
persistence_table_sva <- combine_de_tables(
  persistence_de_sva,
  excel = glue("analyses/4_tumaco/DE_Persistence/persistence_all_de_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Persistence/persistence_all_de_sva-v202305.xlsx before writing the tables.
## Adding venn plots for Y_vs_N.
persistence_monocyte_de_sva <- all_pairwise(persistence_monocyte, filter = TRUE, model_batch = "svaseq")
## 
##  N  Y 
##  2 10
## Removing 0 low-count genes (10326 remaining).
## Setting 46 low elements to zero.
## transform_counts: Found 46 values equal to 0, adding 1 to the matrix.
persistence_monocyte_table_sva <- combine_de_tables(
  persistence_monocyte_de_sva,
  excel = glue("analyses/4_tumaco/DE_Persistence/persistence_monocyte_de_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Persistence/persistence_monocyte_de_sva-v202305.xlsx before writing the tables.
## Adding venn plots for Y_vs_N.
persistence_neutrophil_de_sva <- all_pairwise(persistence_neutrophil, filter = TRUE, model_batch = "svaseq")
## 
## N Y 
## 3 7
## Removing 0 low-count genes (8392 remaining).
## Setting 46 low elements to zero.
## transform_counts: Found 46 values equal to 0, adding 1 to the matrix.
persistence_neutrophil_table_sva <- combine_de_tables(
  persistence_neutrophil_de_sva,
  excel = glue("analyses/4_tumaco/DE_Persistence/persistence_neutrophil_de_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Persistence/persistence_neutrophil_de_sva-v202305.xlsx before writing the tables.
## Adding venn plots for Y_vs_N.
persistence_eosinophil_de_sva <- all_pairwise(persistence_eosinophil, filter = TRUE, model_batch = "svaseq")
## 
## N Y 
## 1 7
## Removing 0 low-count genes (10028 remaining).
## Setting 25 low elements to zero.
## transform_counts: Found 25 values equal to 0, adding 1 to the matrix.
persistence_eosinophil_table_sva <- combine_de_tables(
  persistence_eosinophil_de_sva,
  excel = glue("analyses/4_tumaco/DE_Persistence/persistence_eosinophil_de_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Persistence/persistence_eosinophil_de_sva-v202305.xlsx before writing the tables.
## Adding venn plots for Y_vs_N.

6.2 Comparing visits without regard to cure/fail

6.2.1 All cell types

t_visit_all_de_sva <- all_pairwise(t_visit, filter = TRUE, model_batch = "svaseq")
## 
##  3  2  1 
## 34 35 40
## Removing 0 low-count genes (11907 remaining).
## Setting 9614 low elements to zero.
## transform_counts: Found 9614 values equal to 0, adding 1 to the matrix.

t_visit_all_table_sva <- combine_de_tables(
  t_visit_all_de_sva, keepers = visit_contrasts,
#  rda = glue("rda/t_all_visit_table_sva-v{ver}.rda"),
  excel = glue("analyses/4_tumaco/DE_Visits/t_all_visit_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/t_all_visit_tables_sva-v202305.xlsx before writing the tables.
## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.
## Adding venn plots for v2v1.
## Adding venn plots for v3v1.
## Adding venn plots for v3v2.
t_visit_all_sig_sva <- extract_significant_genes(
  t_visit_all_table_sva,
  excel = glue("analyses/4_tumaco/DE_Visits/t_all_visit_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/t_all_visit_sig_sva-v202305.xlsx before writing the tables.

6.2.2 Monocyte samples

t_visit_monocytes <- set_expt_conditions(t_monocytes, fact = "visitnumber")
## The numbers of samples by condition are:
## 
##  3  2  1 
## 13 13 16
t_visit_monocyte_de_sva <- all_pairwise(t_visit_monocytes, filter = TRUE, model_batch = "svaseq")
## 
##  3  2  1 
## 13 13 16
## Removing 0 low-count genes (10859 remaining).
## Setting 648 low elements to zero.
## transform_counts: Found 648 values equal to 0, adding 1 to the matrix.

t_visit_monocyte_table_sva <- combine_de_tables(
  t_visit_monocyte_de_sva, keepers = visit_contrasts,
#  rda = glue("rda/t_monocyte_visit_table_sva-v{ver}.rda"),
  excel = glue("analyses/4_tumaco/DE_Visits/Monocytes/t_monocyte_visit_tables_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/Monocytes/t_monocyte_visit_tables_sva-v202305.xlsx before writing the tables.
## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.
## Adding venn plots for v2v1.
## Adding venn plots for v3v1.
## Adding venn plots for v3v2.
t_visit_monocyte_sig_sva <- extract_significant_genes(
  t_visit_monocyte_table_sva,
  excel = glue("analyses/4_tumaco/DE_Visits/Monocytes/t_monocyte_visit_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/Monocytes/t_monocyte_visit_sig_sva-v202305.xlsx before writing the tables.

6.2.3 Neutrophil samples

t_visit_neutrophils <- set_expt_conditions(t_neutrophils, fact = "visitnumber")
## The numbers of samples by condition are:
## 
##  3  2  1 
## 12 13 16
t_visit_neutrophil_de_sva <- all_pairwise(t_visit_neutrophils, filter = TRUE, model_batch = "svaseq")
## 
##  3  2  1 
## 12 13 16
## Removing 0 low-count genes (9099 remaining).
## Setting 589 low elements to zero.
## transform_counts: Found 589 values equal to 0, adding 1 to the matrix.

t_visit_neutrophil_table_sva <- combine_de_tables(
  t_visit_neutrophil_de_sva, keepers = visit_contrasts,
#  rda = glue("rda/t_neutrophil_visit_table_sva-v{ver}.rda"),
  excel = glue("analyses/4_tumaco/DE_Visits/Neutrophils/t_neutrophil_visit_table_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/Neutrophils/t_neutrophil_visit_table_sva-v202305.xlsx before writing the tables.
## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.
## Adding venn plots for v2v1.
## Adding venn plots for v3v1.
## Adding venn plots for v3v2.
t_visit_neutrophil_sig_sva <- extract_significant_genes(
  t_visit_neutrophil_table_sva,
  excel = glue("analyses/4_tumaco/DE_Visits/Neutrophils/t_neutrophil_visit_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/Neutrophils/t_neutrophil_visit_sig_sva-v202305.xlsx before writing the tables.

6.2.4 Eosinophil samples

t_visit_eosinophils <- set_expt_conditions(t_eosinophils, fact="visitnumber")
## The numbers of samples by condition are:
## 
## 3 2 1 
## 9 9 8
t_visit_eosinophil_de <- all_pairwise(t_visit_eosinophils, filter = TRUE, model_batch = "svaseq")
## 
## 3 2 1 
## 9 9 8
## Removing 0 low-count genes (10530 remaining).
## Setting 272 low elements to zero.
## transform_counts: Found 272 values equal to 0, adding 1 to the matrix.

t_visit_eosinophil_table <- combine_de_tables(
  t_visit_eosinophil_de, keepers = visit_contrasts,
#  rda = glue("rda/t_eosinophil_visit_table_sva-v{ver}.rda"),
  excel = glue("analyses/4_tumaco/DE_Visits/Eosinophils/t_eosinophil_visit_table_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/Eosinophils/t_eosinophil_visit_table_sva-v202305.xlsx before writing the tables.
## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.

## Warning in combine_extracted_plots(entry_name, combined, wanted_denominator, : I think this
## is an extra contrast table, the plots may be weird.
## Adding venn plots for v2v1.
## Adding venn plots for v3v1.
## Adding venn plots for v3v2.
t_visit_eosinophil_sig <- extract_significant_genes(
  t_visit_eosinophil_table,
  excel = glue("analyses/4_tumaco/DE_Visits/Eosinophils/t_eosinophil_visit_sig_sva-v{ver}.xlsx"))
## Deleting the file analyses/4_tumaco/DE_Visits/Eosinophils/t_eosinophil_visit_sig_sva-v202305.xlsx before writing the tables.

7 Explore ROC

Alejandro showed some ROC curves for eosinophil data showing sensitivity vs. specificity of a couple genes which were observed in v1 eosinophils vs. all-times eosinophils across cure/fail. I am curious to better understand how this was done and what utility it might have in other contexts.

To that end, I want to try something similar myself. In order to properly perform the analysis with these various tools, I need to reconfigure the data in a pretty specific format:

  1. Single df with 1 row per set of observations (sample in this case I think)
  2. The outcome column(s) need to be 1 (or more?) metadata factor(s) (cure/fail or a paste0 of relevant queries (eo_v1_cure, eo_v123_cure, etc)
  3. The predictor column(s) are the measurements (rpkm of 1 or more genes), 1 column each gene.

If I intend to use this for our tx data, I will likely need a utility function to create the properly formatted input df.

For the purposes of my playing, I will choose three genes from the eosinophil C/F table, one which is significant, one which is not, and an arbitrary.

The input genes will therefore be chosen from the data structure: t_cf_eosinophil_tables_sva:

ENSG00000198178, ENSG00000179344, ENSG00000182628

eo_rpkm <- normalize_expt(tv1_eosinophils, convert = "rpkm", column = "cds_length")
## There appear to be 5391 genes without a length.
test <- all_pairwise(tmrc3_external, model_batch = "svaseq", filter = "simple")
## 
##   Brazil Colombia 
##       21       18
## Removing 4594 low-count genes (14576 remaining).
## Setting 3707 low elements to zero.
## transform_counts: Found 3707 values equal to 0, adding 1 to the matrix.
test_table <- combine_de_tables(test, excel = "excel/tmrc3_scott_biopsies.xlsx")
## Adding venn plots for Colombia_vs_Brazil.
test_sig <- extract_significant_genes(test_table, excel = "excel/tmrc3_scott_biopsies_sig.xlsx")

tmrc_external_species <- set_expt_conditions(tmrc3_external, fact = "ParasiteSpecies") %>%
  set_expt_colors(color_choices[["parasite"]])
## The numbers of samples by condition are:
## 
## lvbraziliensis   lvpanamensis  notapplicable 
##             22             14              3
## Warning in set_expt_colors(., color_choices[["parasite"]]): Colors for the following
## categories are not being used: lvguyanensis.
## Skipping this because it is taking too long.
##if (!isTRUE(get0("skip_load"))) {
##  pander::pander(sessionInfo())
##  message(paste0("This is hpgltools commit: ", get_git_commit()))
##  message(paste0("Saving to ", savefile))
##  tmp <- sm(saveme(filename=savefile))
##}
tmp <- loadme(filename = savefile)
LS0tCnRpdGxlOiAiVE1SQzMgMjAyMzA1OiBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbiBhbmFseXNlcywgVHVtYWNvIG9ubHkiCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCnJ1bnRpbWU6IHNoaW55Cm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KYm9keSAubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTYwMHB4Owp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGhwZ2x0b29scykKbGlicmFyeShkcGx5cikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KGdsdWUpCnR0IDwtIHNtKGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKSkKa25pdHI6Om9wdHNfa25pdCRzZXQoCiAgcHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgd2lkdGggPSA5MCwgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlcnJvciA9IFRSVUUsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4LCBmaWcucmV0aW5hID0gMiwKICBmaWcucG9zID0gInQiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZHBpID0gaWYgKGtuaXRyOjppc19sYXRleF9vdXRwdXQoKSkgNzIgZWxzZSAzMDAsCiAgb3V0LndpZHRoID0gIjEwMCUiLCBkZXYgPSAicG5nIiwKICBkZXYuYXJncyA9IGxpc3QocG5nID0gbGlzdCh0eXBlID0gImNhaXJvLXBuZyIpKSkKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHMgPSA0LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWwgPSAiYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplID0gMTIpKQp2ZXIgPC0gIjIwMjMwNSIKcHJldmlvdXNfZmlsZSA8LSAiIgpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQgPSAiJVklbSVkIikKIyN0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZSA9IGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLCByZXBsYWNlID0gIlxcLnJkYVxcLnh6IiwgeCA9IHByZXZpb3VzX2ZpbGUpKSkpCnJtZF9maWxlIDwtIGdsdWUoInRtcmMzX2RpZmZlcmVudGlhbF9leHByZXNzaW9uX3t2ZXJ9LlJtZCIpCnNhdmVmaWxlIDwtIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLCByZXBsYWNlID0gIlxcLnJkYVxcLnh6IiwgeCA9IHJtZF9maWxlKQpsb2FkZWQgPC0gbG9hZChmaWxlID0gZ2x1ZSgicmRhL3RtcmMzX2RhdGFfc3RydWN0dXJlcy12e3Zlcn0ucmRhIikpCmBgYAoKIyBDaGFuZ2Vsb2cKCiogU3RpbGwgaHVudGluZyBmb3IgbWVzc2VkIHVwIGNvbG9ycywgY2hhbmdlZCBpbnB1dCBkYXRhIHRvIG1hdGNoIG5ldyB2ZXJzaW9uLgoKIyBJbnRyb2R1Y3Rpb24KClRoZSB2YXJpb3VzIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzIG9mIHRoZSBkYXRhIGdlbmVyYXRlZCBpbiB0bXJjM19kYXRhc2V0cwp3aWxsIG9jY3VyIGluIHRoaXMgZG9jdW1lbnQuCgojIyBOYW1pbmcgY29udmVudGlvbnMKCkkgYW0gZ29pbmcgdG8gdHJ5IHRvIHN0YW5kYXJkaXplIGhvdyBJIG5hbWUgdGhlIHZhcmlvdXMgZGF0YQpzdHJ1Y3R1cmVzIGNyZWF0ZWQgaW4gdGhpcyBkb2N1bWVudC4gIE1vc3Qgb2YgdGhlIGxhcmdlIGRhdGEgY3JlYXRlZAphcmUgZWl0aGVyIHNldHMgb2YgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXMsIHRoZWlyIGNvbWJpbmVkCnJlc3VsdHMsIG9yIHRoZSBzZXQgb2YgcmVzdWx0cyBkZWVtZWQgJ3NpZ25pZmljYW50Jy4KCkhvcGVmdWxseSBieSBub3cgdGhleSBhbGwgZm9sbG93IHRoZXNlIGd1aWRlbGluZXM6Cgp7Y2xpbmljKHMpfV9zYW1wbGUtc3Vic2V0fV97cHJpbWFyeS1xdWVzdGlvbihzKX1fe2RhdGF0eXBlfV97YmF0Y2gtbWV0aG9kfQoKKiB7Y2xpbmljfTogVGhpcyBpcyBlaXRoZXIgdGMgb3IgdCBmb3IgVHVtYWNvIGFuZCBDYWxpLCBvciBqdXN0ClR1bWFjby4KKiB7c2FtcGxlLXN1YnNldH06IFRoaW5ncyBsaWtlICdhbGwnIG9yICdtb25vY3l0ZXMnLgoqIHtwcmltYXJ5LXF1ZXN0aW9ufTogU2hvcnRoYW5kIG5hbWUgZm9yIHRoZSBwcmltYXJ5IGNvbnRyYXN0cwpwZXJmb3JtZWQsIHRodXMgJ2NsaW5pY3MnIHdvdWxkIHN1Z2dlc3QgYSBjb21wYXJpc29uIG9mIFR1bWFjbwp2cy4gQ2FsaS4gICd2aXNpdHMnIHdvdWxkIGNvbXBhcmUgdjIvdjEsIGV0Yy4KKiB7ZGF0YXR5cGV9OiBkZSwgdGFibGUsIHNpZwoqIHtiYXRjaC10eXBlfTogbm9iYXRjaCwgYmF0Y2h7ZmFjdG9yfSwgc3ZhLiAge2ZhY3Rvcn0gaW4gdGhpcwppbnN0YW5jZSBzaG91bGQgYmUgYSBjb2x1bW4gZnJvbSB0aGUgbWV0YWRhdGEuCgpXaXRoIHRoaXMgaW4gbWluZCwgJ3RjX2Jpb3BzaWVzX2NsaW5pY19kZV9zdmEnIHNob3VsZCBiZSB0aGUgVHVtYWNvK0NhbGkKYmlvcHN5IGRhdGEgYWZ0ZXIgcGVyZm9ybWluZyB0aGUgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXMKY29tcGFyaW5nIHRoZSBjbGluaWNzIHVzaW5nIHN2YS4KCkkgc3VzcGVjdCB0aGVyZSByZW1haW4gc29tZSBleGNlcHRpb25zIGFuZC9vciBlcnJvcnMuCgojIyBEZWZpbmUgY29udHJhc3RzIGZvciBERSBhbmFseXNlcwoKRWFjaCBvZiB0aGUgZm9sbG93aW5nIGxpc3RzIGRlc2NyaWJlcyB0aGUgc2V0IG9mIGNvbnRyYXN0cyB0aGF0IEkKdGhpbmsgYXJlIGludGVyZXN0aW5nIGZvciB0aGUgdmFyaW91cyB3YXlzIG9uZSBtaWdodCBjb25zaWRlciB0aGUKVE1SQzMgZGF0YXNldC4gIFRoZSB2YXJpYWJsZXMgYXJlIG5hbWVkIGFjY29yZGluZyB0byB0aGUgYXNzdW1lZCBkYXRhCndpdGggd2hpY2ggdGhleSB3aWxsIGJlIHVzZWQsIHRodXMgdGNfY2ZfY29udHJhc3RzIGlzIGV4cGVjdGVkIHRvIGJlCnVzZWQgZm9yIHRoZSBUdW1hY28rQ2FsaSBkYXRhIGFuZCBwcm92aWRlIGEgc2VyaWVzIG9mIGN1cmUvZmFpbApjb21wYXJpc29ucyB3aGljaCAodG8gdGhlIGV4dGVudCBwb3NzaWJsZSkgYWNyb3NzIGJvdGggbG9jYXRpb25zLiAgSW4KZXZlcnkgY2FzZSwgdGhlIG5hbWUgb2YgdGhlIGxpc3QgZWxlbWVudCB3aWxsIGJlIHVzZWQgYXMgdGhlIGNvbnRyYXN0Cm5hbWUsIGFuZCB3aWxsIHRodXMgYmUgc2VlbiBhcyB0aGUgc2hlZXQgbmFtZSBpbiB0aGUgb3V0cHV0IHhsc3gKZmlsZShzKTsgdGhlIHR3byBwaWVjZXMgb2YgdGhlIGNoYXJhY3RlciB2ZWN0b3IgdmFsdWUgYXJlIHRoZQpudW1lcmF0b3IgYW5kIGRlbm9taW5hdG9yIG9mIHRoZSBhc3NvY2lhdGVkIGNvbnRyYXN0LgoKYGBge3Igc2V0dXBfY29udHJhc3RzfQpjbGluaWNfY29udHJhc3RzIDwtIGxpc3QoCiAgImNsaW5pY3MiID0gYygiQ2FsaSIsICJUdW1hY28iKSkKIyMgSW4gc29tZSBjYXNlcyB3ZSBoYXZlIG5vIENhbGkgZmFpbHVyZSBzYW1wbGVzLCBzbyB0aGVyZSByZW1haW4gb25seSAyCiMjIGNvbnRyYXN0cyB0aGF0IGFyZSBsaWtlbHkgb2YgaW50ZXJlc3QKdGNfY2ZfY29udHJhc3RzIDwtIGxpc3QoCiAgInR1bWFjbyIgPSBjKCJUdW1hY29mYWlsdXJlIiwgIlR1bWFjb2N1cmUiKSwKICAiY3VyZSIgPSBjKCJUdW1hY29jdXJlIiwgIkNhbGljdXJlIikpCiMjIEluIG90aGVyIGNhc2VzLCB3ZSBoYXZlIGN1cmUvZmFpbCBmb3IgYm90aCBwbGFjZXMuCmNsaW5pY19jZl9jb250cmFzdHMgPC0gbGlzdCgKICAiY2FsaSIgPSBjKCJDYWxpZmFpbHVyZSIsICJDYWxpY3VyZSIpLAogICJ0dW1hY28iID0gYygiVHVtYWNvZmFpbHVyZSIsICJUdW1hY29jdXJlIiksCiAgImN1cmUiID0gYygiVHVtYWNvY3VyZSIsICJDYWxpY3VyZSIpLAogICJmYWlsIiA9IGMoIlR1bWFjb2ZhaWx1cmUiLCAiQ2FsaWZhaWx1cmUiKSkKY2ZfY29udHJhc3QgPC0gbGlzdCgKICAib3V0Y29tZSIgPSBjKCJUdW1hY29mYWlsdXJlIiwgIlR1bWFjb2N1cmUiKSkKdF9jZl9jb250cmFzdCA8LSBsaXN0KAogICJvdXRjb21lIiA9IGMoImZhaWx1cmUiLCAiY3VyZSIpKQp2aXNpdGNmX2NvbnRyYXN0cyA8LSBsaXN0KAogICJ2MWNmIiA9IGMoInYxZmFpbHVyZSIsICJ2MWN1cmUiKSwKICAidjJjZiIgPSBjKCJ2MmZhaWx1cmUiLCAidjJjdXJlIiksCiAgInYzY2YiID0gYygidjNmYWlsdXJlIiwgInYzY3VyZSIpKQp2aXNpdF9jb250cmFzdHMgPC0gbGlzdCgKICAidjJ2MSIgPSBjKCJjMiIsICJjMSIpLAogICJ2M3YxIiA9IGMoImMzIiwgImMxIiksCiAgInYzdjIiID0gYygiYzMiLCAiYzIiKSkKdmlzaXRfdjFsYXRlciA8LSBsaXN0KAogICJsYXRlcl92c19maXJzdCIgPSBjKCJsYXRlciIsICJmaXJzdCIpKQpjZWxsdHlwZXMgPC0gbGlzdCgKICAiZW9fbW9ubyIgPSBjKCJlb3Npbm9waGlscyIsICJtb25vY3l0ZXMiKSwKICAibmVfbW9ubyIgPSBjKCJuZXV0cm9waGlscyIsICJtb25vY3l0ZXMiKSwKICAiZW9fbmUiID0gYygiZW9zaW5vcGhpbHMiLCAibmV1dHJvcGhpbHMiKSkKZXRobmljaXR5X2NvbnRyYXN0cyA8LSBsaXN0KAogICJtZXN0aXpvX2luZGlnZW5vdXMiID0gYygibWVzdGl6YSIsICJpbmRpZ2VuYSIpLAogICJtZXN0aXpvX2Fmcm9jb2wiID0gYygibWVzdGl6YSIsICJhZnJvY29sIiksCiAgImluZGlnZW5vdXNfYWZyb2NvbCIgPSBjKCJpbmRpZ2VuYSIsICJhZnJvY29sIikpCmBgYAoKIyBPbmx5IFR1bWFjbyBzYW1wbGVzCgpTdGFydCBvdmVyLCB0aGlzIHRpbWUgd2l0aCBvbmx5IHRoZSBzYW1wbGVzIGZyb20gVHVtYWNvLiAgV2UgY3VycmVudGx5CmFyZSBhc3N1bWluZyB0aGVzZSB3aWxsIHByb3ZlIHRvIGJlIHRoZSBvbmx5IGFuYWx5c2VzIHVzZWQgZm9yIGZpbmFsCmludGVycHJldGF0aW9uLiAgVGhpcyBpcyBwcmltYXJpbHkgYmVjYXVzZSB3ZSBoYXZlIGluc3VmZmljaWVudApmYWlsZWQgdHJlYXRtZW50IHNhbXBsZXMgZnJvbSBDYWxpLgoKYGBge3IgeGxzeF9wcmVmaXh9Cnhsc3hfcHJlZml4IDwtICJhbmFseXNlcy80X3R1bWFjby9ERV9DdXJlX3ZzX0ZhaWwiCmBgYAoKIyMgQWxsIHNhbXBsZXMKClN0YXJ0IGJ5IGNvbnNpZGVyaW5nIGFsbCBUdW1hY28gY2VsbCB0eXBlcy4gIE5vdGUgdGhhdCBpbiB0aGlzIGNhc2Ugd2UKb25seSB1c2UgU1ZBLCBwcmltYXJpbHkgYmVjYXVzZSBJIGFtIG5vdCBjZXJ0YWluIHdoYXQgd291bGQgYmUgYW4KYXBwcm9wcmlhdGUgYmF0Y2ggZmFjdG9yLCBwZXJoYXBzIHZpc2l0PwoKYGBge3IgY2ZfYWxsX2RlfQp0X2NmX2NsaW5pY2FsX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodF9jbGluaWNhbCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9jZl9jbGluaWNhbF9kZV9zdmEKCnRfY2ZfY2xpbmljYWxfdGFibGVfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfY2xpbmljYWxfZGVfc3ZhLCBrZWVwZXJzID0gdF9jZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfY2xpbmljYWxfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vQWxsX1NhbXBsZXMvdF9jbGluaWNhbF9jZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfY2ZfY2xpbmljYWxfdGFibGVfc3ZhCnRfY2ZfY2xpbmljYWxfdGFibGVfc3ZhW1sicGxvdHMiXV1bWyJvdXRjb21lIl1dW1siZGVzZXFfbWFfcGxvdHMiXV0KCnRfY2ZfY2xpbmljYWxfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfY2xpbmljYWxfdGFibGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF9jZl9jbGluaWNhbF9zaWdfc3ZhCgpkaW0odF9jZl9jbGluaWNhbF9zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9jbGluaWNhbF9zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCmBgYAoKIyMgZ1Byb2ZpbGVyIHNlYXJjaCBvZiBhbGwgc2FtcGxlcwoKVGhlIGZvbGxvd2luZyBnUHJvZmlsZXIgc2VhcmNoZXMgdXNlIHRoZSBhbGxfZ3Byb2ZpbGVyKCkgZnVuY3Rpb24KaW5zdGVhZCBvZiBzaW1wbGVfZ3Byb2ZpbGVyKCkuICBBcyBhIHJlc3VsdCwgdGhlIHJlc3VsdHMgYXJlIHNlcGFyYXRlZApieSB7Y29udHJhc3R9X3tkaXJlY3Rpb259LiAgVGh1cyAnb3V0Y29tZV9kb3duJy4KClRoZSBzYW1lIHBsb3RzIGFyZSBhdmFpbGFibGUgYXMgdGhlIHByZXZpb3VzIGdQcm9maWxlciBzZWFyY2hlcywgYnV0CmluIG1hbnkgb2YgdGhlIGZvbGxvd2luZyBydW5zLCBJIHVzZWQgdGhlIGRvdHBsb3QoKSBmdW5jdGlvbiB0byBnZXQgYQpzbGlnaHRseSBkaWZmZXJlbnQgdmlldyBvZiB0aGUgcmVzdWx0cy4KCmBgYHtyIHRfY2ZfY2xpbmljYWxfZ3Byb2ZpbGVyfQp0X2NmX2NsaW5pY2FsX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9jbGluaWNhbF9zaWdfc3ZhKQojIyBXaWtpcGF0aHdheXMgb2YgdGhlIHVwIGMvZiBnZW5lcwplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfZ3BbWyJvdXRjb21lX3VwIl1dW1siV1BfZW5yaWNoIl1dKQoKIyMgVHJhbnNjcmlwdGlvbiBmYWN0b3IgZGF0YWJhc2Ugb2YgdGhlIHVwIGMvZiBnZW5lcwplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfZ3BbWyJvdXRjb21lX3VwIl1dW1siVEZfZW5yaWNoIl1dKQoKIyMgUmVhY3RvbWUgb2YgdGhlIHVwIGMvZiBnZW5lcwplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfZ3BbWyJvdXRjb21lX3VwIl1dW1siUkVBQ19lbnJpY2giXV0pCgojIyBHTyBvZiB0aGUgZG93biBjL2YgZ2VuZXMKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwW1sib3V0Y29tZV9kb3duIl1dW1siR09fZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsX2dwW1sib3V0Y29tZV91cCJdXVtbInB2YWx1ZV9wbG90cyJdXVtbIkJQIl1dCgojIyBSZWFjdG9tZSBvZiB0aGUgZG93biBjL2YgZ2VuZXMKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwW1sib3V0Y29tZV9kb3duIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQpgYGAKCiMgVmlzaXQgY29tcGFyaXNvbnMKCkxhdGVyIGluIHRoaXMgZG9jdW1lbnQgSSBkbyBhIGJ1bmNoIG9mIHZpc2l0L2NmIGNvbXBhcmlzb25zLiAgSW4gdGhpcwpibG9jayBJIHdhbnQgdG8gZXhwbGljaXRseSBvbmx5IGNvbXBhcmUgdjEgdG8gb3RoZXIgdmlzaXRzLiAgVGhpcyBpcwpzb21ldGhpbmcgSSBkaWQgcXVpdGUgYSBsb3QgaW4gdGhlIDIwMTkgZGF0YXNldHMsIGJ1dCBuZXZlciBhY3R1YWxseQptb3ZlZCB0byB0aGlzIGRvY3VtZW50LgoKYGBge3IgZGVfdmlzaXRfY29tcGFyaXNvbnN9CnR2MV92c19sYXRlciA8LSBhbGxfcGFpcndpc2UodF92MXZzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0djFfdnNfbGF0ZXJfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdHYxX3ZzX2xhdGVyLCBrZWVwZXJzID0gdmlzaXRfdjFsYXRlciwKICBleGNlbCA9IGdsdWUoImV4Y2VsL3R2MV92c19sYXRlcl90YWJsZXMtdnt2ZXJ9Lnhsc3giKSkKdHYxX3ZzX2xhdGVyX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHR2MV92c19sYXRlcl90YWJsZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL3R2MV92c19sYXRlcl9zaWctdnt2ZXJ9Lnhsc3giKSkKCnR2MWxhdGVyX2dwIDwtIGFsbF9ncHJvZmlsZXIodHYxX3ZzX2xhdGVyX3NpZykKdHYxbGF0ZXJfZ3BbWzFdXSRwdmFsdWVfcGxvdHMkQlAKdHYxbGF0ZXJfZ3BbWzJdXSRwdmFsdWVfcGxvdHMkQlAKYGBgCgojIFNleCBjb21wYXJpc29uCgpDYW4gd2Ugb2JzZXJ2ZSBjb25zaXN0ZW50IGRpZmZlcmVuY2UgaW4gdGhlIGZlL21hbGUgc2FtcGxlcz8KCmBgYHtyIGRlX3NleH0KdF9zZXggPC0gc3Vic2V0X2V4cHQodGNfc2V4LCBzdWJzZXQgPSAiY2xpbmljID09ICdUdW1hY28nIikKdF9zZXgKdF9zZXhfZGUgPC0gYWxsX3BhaXJ3aXNlKHRfc2V4LCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X3NleF9kZQp0X3NleF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X3NleF9kZSwgZXhjZWwgPSBnbHVlKCJleGNlbC90X3NleF90YWJsZS12e3Zlcn0ueGxzeCIpKQp0X3NleF90YWJsZQp0X3NleF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X3NleF90YWJsZSwgZXhjZWwgPSBnbHVlKCJleGNlbC90X3NleF9zaWctdnt2ZXJ9Lnhsc3giKSkKdF9zZXhfc2lnCnRfc2V4X2dwIDwtIGFsbF9ncHJvZmlsZXIodF9zZXhfc2lnKQp0X3NleF9ncApgYGAKCldoYXQgaWYgd2UgbGltaXQgdGhlIHF1ZXN0aW9uIHRvIG9ubHkgdGhlIHBlb3BsZSB3aG8gY3VyZWQ/CgpgYGB7ciBzZXhfY3VyZV9vbmx5fQp0Y19zZXhfY3VyZSA8LSBzdWJzZXRfZXhwdCh0Y19zZXgsIHN1YnNldCA9ICJmaW5hbG91dGNvbWU9PSdjdXJlJyIpCnRfc2V4X2N1cmUgPC0gc3Vic2V0X2V4cHQodGNfc2V4X2N1cmUsIHN1YnNldCA9ICJjbGluaWMgPT0gJ1R1bWFjbyciKQp0X3NleF9jdXJlX2RlIDwtIGFsbF9wYWlyd2lzZSh0X3NleF9jdXJlLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X3NleF9jdXJlX2RlCnRfc2V4X2N1cmVfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9zZXhfY3VyZV9kZSwgZXhjZWwgPSBnbHVlKCJleGNlbC90X3NleF9jdXJlX3RhYmxlLXZ7dmVyfS54bHN4IikpCnRfc2V4X2N1cmVfdGFibGUKdF9zZXhfY3VyZV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X3NleF9jdXJlX3RhYmxlLCBleGNlbCA9IGdsdWUoImV4Y2VsL3Rfc2V4X2N1cmVfc2lnLXZ7dmVyfS54bHN4IikpCnRfc2V4X2N1cmVfc2lnCnRfc2V4X2N1cmVfZ3AgPC0gYWxsX2dwcm9maWxlcih0X3NleF9jdXJlX3NpZykKdF9zZXhfY3VyZV9ncAp0X3NleF9jdXJlX2dwW1sxXV1bWyJwdmFsdWVfcGxvdHMiXV1bWyJCUCJdXQpgYGAKCiMgRXRobmljaXR5IGNvbXBhcmlzb25zCgpUaGUgc2V0IG9mIGV0aG5pY2l0aWVzIG9ic2VydmVkIGluIFR1bWFjbyBpcyBhIGJpdCBkaWZmZXJlbnQgdGhhbiB0aGF0CmluIENhbGkuICBDYW4gd2Ugc2VlIGRpZmZlcmVuY2VzIGFtb25nIHRob3NlIGdyb3Vwcz8gIE5vdGUgdGhhdCB0aGlzCmlzIGNvbmZvdW5kZWQgd2l0aCBjdXJlL2ZhaWwuCgpgYGB7ciBkZV9ldG5pYX0KdF9ldGhuaWNpdHlfZGUgPC0gYWxsX3BhaXJ3aXNlKHRfZXRuaWFfZXhwdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9ldGhuaWNpdHlfZGUKdF9ldGhuaWNpdHlfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9ldGhuaWNpdHlfZGUsIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvdF9ldGhuaWNpdHlfdGFibGUtdnt2ZXJ9Lnhsc3giKSkKdF9ldGhuaWNpdHlfdGFibGUKdF9ldGhuaWNpdHlfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF9ldGhuaWNpdHlfdGFibGUsIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvdF9ldGhuaWNpdHlfc2lnLXZ7dmVyfS54bHN4IikpCnRfZXRobmljaXR5X3NpZwp0X2V0aG5pY2l0eV9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfZXRobmljaXR5X3NpZykKdF9ldGhuaWNpdHlfZ3AKYGBgCgojIyMgU2VwYXJhdGUgdGhlIFR1bWFjbyBkYXRhIGJ5IHZpc2l0CgpPbmUgb2YgdGhlIG1vc3QgY29tcGVsbGluZyBpZGVhcyBpbiB0aGUgZGF0YSBpcyB0aGUgb3Bwb3J0dW5pdHkgdG8KZmluZCBnZW5lcyBpbiB0aGUgZmlyc3QgdmlzaXQgd2hpY2ggbWF5IGhlbHAgcHJlZGljdCB0aGUgbGlrZWxpaG9vZAp0aGF0IGEgcGVyc29uIHdpbGwgcmVzcG9uZCB3ZWxsIHRvIHRyZWF0bWVudC4gIFRoZSBmb2xsb3dpbmcgYmxvY2sKd2lsbCB0aGVyZWZvcmUgbG9vayBhdCBjdXJlL2ZhaWwgZnJvbSBUdW1hY28gYXQgdmlzaXQgMS4KCiMjIyMgQ3VyZS9GYWlsLCBUdW1hY28gVmlzaXQgMQoKYGBge3IgdHVtYWNvX3RpbWVwb2ludHNfdjF9CnRfY2ZfY2xpbmljYWxfdjFfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZSh0djFfc2FtcGxlcywgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9jZl9jbGluaWNhbF92MV9kZV9zdmEKdF9jZl9jbGluaWNhbF92MV90YWJsZV9zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9jZl9jbGluaWNhbF92MV9kZV9zdmEsIGtlZXBlcnMgPSB0X2NmX2NvbnRyYXN0LAojICByZGEgPSBnbHVlKCJyZGEvdF9jbGluaWNhbF92MV9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX3YxX2NmX3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF9jZl9jbGluaWNhbF92MV90YWJsZV9zdmEKdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF9jZl9jbGluaWNhbF92MV90YWJsZV9zdmEsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkaW0odF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCmBgYAoKIyMjIyBDdXJlL0ZhaWwsIFR1bWFjbyBWaXNpdCAyCgpUaGUgdmlzaXQgMiBhbmQgdmlzaXQgMyBzYW1wbGVzIGFyZSBpbnRlcmVzdGluZyBiZWNhdXNlIHRoZXkgcHJvdmlkZQphbiBvcHBvcnR1bml0eSB0byBzZWUgaWYgd2UgY2FuIG9ic2VydmUgY2hhbmdlcyBpbiByZXNwb25zZSBpbiB0aGUKbWlkZGxlIGFuZCBlbmQgb2YgdHJlYXRtZW50Li4uCgpgYGB7ciB0dW1hY29fdGltZV92Mn0KdF9jZl9jbGluaWNhbF92Ml9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHR2Ml9zYW1wbGVzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X2NmX2NsaW5pY2FsX3YyX3RhYmxlX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX2NsaW5pY2FsX3YyX2RlX3N2YSwga2VlcGVycyA9IHRfY2ZfY29udHJhc3QsCiMgIHJkYSA9IGdsdWUoInJkYS90X2NsaW5pY2FsX3YyX2NmX3RhYmxlX3N2YS12e3Zlcn0ucmRhIiksCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfdjJfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX2NsaW5pY2FsX3YyX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX2NsaW5pY2FsX3YyX3RhYmxlX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vQWxsX1NhbXBsZXMvdF9jbGluaWNhbF92Ml9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmRpbSh0X2NmX2NsaW5pY2FsX3YyX3NpZ19zdmEkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX2NsaW5pY2FsX3YyX3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKYGBgCgojIyMjIEN1cmUvRmFpbCwgVHVtYWNvIFZpc2l0IDMKCmBgYHtyIHR1bWFjb190aW1lX3YzfQp0X2NmX2NsaW5pY2FsX3YzX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodHYzX3NhbXBsZXMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfY2ZfY2xpbmljYWxfdjNfdGFibGVfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfY2xpbmljYWxfdjNfZGVfc3ZhLCBrZWVwZXJzID0gdF9jZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfY2xpbmljYWxfdjNfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vQWxsX1NhbXBsZXMvdF9jbGluaWNhbF92M19jZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfY2ZfY2xpbmljYWxfdjNfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfY2xpbmljYWxfdjNfdGFibGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX3YzX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKZGltKHRfY2ZfY2xpbmljYWxfdjNfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfY2xpbmljYWxfdjNfc2lnX3N2YSRkZXNlcSRkb3duc1tbMV1dKQpgYGAKCiMjIyMgVmlzaXQgMSBnUHJvZmlsZXIgc2VhcmNoZXMKCkl0IGxvb2tzIGxpa2UgdGhlcmUgYXJlIHZlcnkgZmV3IGdyb3VwcyBpbiB0aGUgdmlzaXQgMSBzaWduaWZpY2FudCBnZW5lcy4KCmBgYHtyIHRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9ncH0KdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhKQoKIyMgV2lraXBhdGh3YXlzIG9mIHRoZSB1cCBjL2YgZ2VuZXMKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkdPX2VucmljaCJdXSkKYGBgCgojIyMjIFZpc2l0IDIgZ1Byb2ZpbGVyIHNlYXJjaGVzCgpVcDogNzQgR08sIDQgS0VHRywgNiByZWFjdG9tZSwgNCBXUCwgNTYgVEYsIDEgbWlSTkEsIDAgSFAvSFBBL0NPUlVNLgpEb3duOiAgMTkgR08sIDEgS0VHRywgMSBIUCwgMiBIUEEsIDAgcmVhY3RvbWUvd3AvdGYvY29ydW0KCmBgYHtyIHRfY2ZfY2xpbmljYWxfdjJfc2lnX3N2YV9ncH0KdF9jZl9jbGluaWNhbF92Ml9zaWdfc3ZhX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9jbGluaWNhbF92Ml9zaWdfc3ZhKQoKIyMgV2lraXBhdGh3YXlzIG9mIHRoZSB1cCBjL2YgZ2VuZXMKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YyX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfdjJfc2lnX3N2YV9ncFtbIm91dGNvbWVfdXAiXV1bWyJSRUFDX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YyX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siVEZfZW5yaWNoIl1dKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YyX3NpZ19zdmFfZ3BbWyJvdXRjb21lX2Rvd24iXV1bWyJHT19lbnJpY2giXV0pCmBgYAoKIyMjIyBWaXNpdCAzIGdQcm9maWxlciBzZWFyY2hlcwoKVXA6IDEyMCBnZW5lczsgMTQxIEdPLCAxIEtFR0csIDUgUmVhY3RvbWUsIDIgV1AsIDMwIFRGLCAxIG1pUk5BLCAwIEhQQS9DT1JVTS9IUApEb3duOiA2MiBnZW5lczsgMzAgR08sIDIgS0VHRywgMSBSZWFjdG9tZSwgMCBXUC9URi9taVJOQS9IUEEvQ09SVU0vSFAsCgpgYGB7ciB0X2NmX2NsaW5pY2FsX3YzX3NpZ19zdmFfZ3B2Mn0KdF9jZl9jbGluaWNhbF92M19zaWdfc3ZhX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9jbGluaWNhbF92M19zaWdfc3ZhKQoKIyMgV2lraXBhdGh3YXlzIG9mIHRoZSB1cCBjL2YgZ2VuZXMKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YzX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfdjNfc2lnX3N2YV9ncFtbIm91dGNvbWVfdXAiXV1bWyJSRUFDX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YzX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siVEZfZW5yaWNoIl1dKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YzX3NpZ19zdmFfZ3BbWyJvdXRjb21lX2Rvd24iXV1bWyJHT19lbnJpY2giXV0pCmBgYAoKIyMjIFJlcGVhdCBubyBiaW9wc2llcwoKVGhlIGJpb3BzeSBzYW1wbGVzIGFyZSBwcm9ibGVtYXRpYyBmb3IgYSBmZXcgcmVhc29ucywgc28gbGV0IHVzIHJlcGVhdAp3aXRob3V0IHRoZW0uCgpgYGB7ciBjZl9hbGxfZGVfbm9iaW9wfQp0X2NmX2NsaW5pY2FsX25vYmlvcF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfY2xpbmljYWxfbm9iaW9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfY2ZfY2xpbmljYWxfbm9iaW9wX3RhYmxlX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX2NsaW5pY2FsX25vYmlvcF9kZV9zdmEsIGtlZXBlcnMgPSB0X2NmX2NvbnRyYXN0LAojICByZGEgPSBnbHVlKCJyZGEvdF9jbGluaWNhbF9ub2Jpb3BfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTm9fQmlvcHNpZXMvdF9jbGluaWNhbF9ub2Jpb3BfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX2NsaW5pY2FsX25vYmlvcF9zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF9jZl9jbGluaWNhbF9ub2Jpb3BfdGFibGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Ob19CaW9wc2llcy90X2NsaW5pY2FsX25vYmlvcF9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCgpkaW0odF9jZl9jbGluaWNhbF9ub2Jpb3Bfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfY2xpbmljYWxfbm9iaW9wX3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKYGBgCgojIyMjIGdQcm9maWxlcjogQ2xpbmljYWwgbm8gYmlvcHNpZXMKClVwOiAxMzcgZ2VuZXM7IDg4IEdPLCAwIEtFR0csIDYgUmVhY3RvbWUsIDEgV1AsIDQ2IFRGLCAxIG1pUk5BLCAwIG90aGVycwpEb3duOiA3MyBnZW5lczsgNzggR08sIDEgS0VHRywgMSBSZWFjdG9tZSwgOSBURiwgMCBvdGhlcnMKCmBgYHtyIHRfY2Zfbm9iaW9wY2xpbmljYWxfdjNfc2lnX3N2YV9ncH0KdF9jZl9jbGluaWNhbF9ub2Jpb3Bfc2lnX3N2YV9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfY2ZfY2xpbmljYWxfbm9iaW9wX3NpZ19zdmEpCgplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfbm9iaW9wX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfbm9iaW9wX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siVEZfZW5yaWNoIl1dKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX25vYmlvcF9zaWdfc3ZhX2dwW1sib3V0Y29tZV9kb3duIl1dW1siR09fZW5yaWNoIl1dKQpgYGAKCiMjIyBCeSBjZWxsIHR5cGUKCk5vdyBsZXQgdXMgc3dpdGNoIG91ciB2aWV3IHRvIGVhY2ggaW5kaXZpZHVhbCBjZWxsIHR5cGUgY29sbGVjdGVkLgpUaGUgaG9wZSBoZXJlIGlzIHRoYXQgd2Ugd2lsbCBiZSBhYmxlIHRvIGxlYXJuIHNvbWUgY2VsbC1zcGVjaWZpYwpkaWZmZXJlbmNlcyBpbiB0aGUgcmVzcG9uc2UgZm9yIHBlb3BsZSB3aG8gZGlkKG5vdCkgcmVzcG9uZCB3ZWxsLgoKIyMjIyBDdXJlL0ZhaWwsIEJpb3BzaWVzCgpgYGB7ciBjZl9iaW9wc3lfZGV9CnRfY2ZfYmlvcHN5X2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodF9iaW9wc2llcywgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9jZl9iaW9wc3lfdGFibGVfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfYmlvcHN5X2RlX3N2YSwga2VlcGVycyA9IGNmX2NvbnRyYXN0LAojICByZGEgPSBnbHVlKCJyZGEvdF9iaW9wc3lfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vQmlvcHNpZXMvdF9iaW9wc3lfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX2Jpb3BzeV9zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF9jZl9iaW9wc3lfdGFibGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9CaW9wc2llcy90X2NmX2Jpb3BzeV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCgpkaW0odF9jZl9iaW9wc3lfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfYmlvcHN5X3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKYGBgCgojIyMjIGdQcm9maWxlcjogQmlvcHNpZXMKClVwOiAxNyBnZW5lczsgNzQgR08sIDMgS0VHRywgMSBSZWFjdG9tZSwgMyBXUCwgMSBURiwgMCBvdGhlcnMKRG93bjogMTEgZ2VuZXM7IDIgR08sIDAgb3RoZXJzCgpgYGB7ciB0X2NmX2NsaW5pY2FsX3YzX3NpZ19zdmFfZ3B9CnRfY2ZfYmlvcHN5X3NpZ19zdmFfZ3AgPC0gYWxsX2dwcm9maWxlcih0X2NmX2Jpb3BzeV9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwW1sib3V0Y29tZV91cCJdXVtbIkdPX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwW1sib3V0Y29tZV91cCJdXVtbIldQX2VucmljaCJdXSkKCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9iaW9wc3lfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkdPX2VucmljaCJdXSkKYGBgCgojIyMjIEN1cmUvRmFpbCwgTW9ub2N5dGVzCgpTYW1lIHF1ZXN0aW9uLCBidXQgdGhpcyB0aW1lIGxvb2tpbmcgYXQgbW9ub2N5dGVzLiAgSW4gYWRkaXRpb24sIHRoaXMKY29tcGFyaXNvbiB3YXMgZG9uZSB0d2ljZSwgb25jZSB1c2luZyBTVkEgYW5kIG9uY2UgdXNpbmcgdmlzaXQgYXMgYQpiYXRjaCBmYWN0b3IuCgpgYGB7ciBjZl9tb25vY3l0ZV9kZX0KdF9jZl9tb25vY3l0ZV9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfbW9ub2N5dGVzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSkKCnRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX21vbm9jeXRlX2RlX3N2YSwga2VlcGVycyA9IGNmX2NvbnRyYXN0LAojICByZGEgPSBnbHVlKCJyZGEvdF9tb25vY3l0ZV9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV9jZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfY2ZfbW9ub2N5dGVfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQoKZGltKHRfY2ZfbW9ub2N5dGVfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfbW9ub2N5dGVfc2lnX3N2YSRkZXNlcSRkb3duc1tbMV1dKQoKdF9jZl9tb25vY3l0ZV9kZV9iYXRjaHZpc2l0IDwtIGFsbF9wYWlyd2lzZSh0X21vbm9jeXRlcywgbW9kZWxfYmF0Y2ggPSBUUlVFLCBmaWx0ZXIgPSBUUlVFKQoKdF9jZl9tb25vY3l0ZV90YWJsZXNfYmF0Y2h2aXNpdCA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX21vbm9jeXRlX2RlX2JhdGNodmlzaXQsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbW9ub2N5dGVfY2ZfdGFibGVfYmF0Y2h2aXNpdC12e3Zlcn0ucmRhIiksCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L01vbm9jeXRlcy90X21vbm9jeXRlX2NmX3RhYmxlc19iYXRjaHZpc2l0LXZ7dmVyfS54bHN4IikpCnRfY2ZfbW9ub2N5dGVfc2lnX2JhdGNodmlzaXQgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX21vbm9jeXRlX3RhYmxlc19iYXRjaHZpc2l0LAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV9jZl9zaWdfYmF0Y2h2aXNpdC12e3Zlcn0ueGxzeCIpKQoKZGltKHRfY2ZfbW9ub2N5dGVfc2lnX2JhdGNodmlzaXQkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX21vbm9jeXRlX3NpZ19iYXRjaHZpc2l0JGRlc2VxJGRvd25zW1sxXV0pCmBgYAoKIyMjIyBnUHJvZmlsZXI6IE1vbm9jeXRlcwoKTm93IHRoYXQgSSBhbSBsb29raW5nIGJhY2sgb3ZlciB0aGVzZSByZXN1bHRzLCBJIGFtIG5vdCBjb21wZWx0ZWx5CmNlcnRhaW4gd2h5IEkgb25seSBkaWQgdGhlIGdwcm9maWxlciBzZWFyY2ggZm9yIHRoZSBzdmEgZGF0YS4uLgoKVXA6IDYwIGdlbmVzOyAxMiBHTywgMSBLRUdHLCAxIFdQLCA0IFRGLCAwIG90aGVycwpEb3duOiA1MyBnZW5lczsgMjYgR08sIDEgS0VHRywgMSBSZWFjdG9tZSwgMiBURiwgMCBvdGhlcnMKCmBgYHtyIHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9ncH0KdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9tb25vY3l0ZV9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX21vbm9jeXRlX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9ncFtbIm91dGNvbWVfdXAiXV1bWyJURl9lbnJpY2giXV0pCgplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkdPX2VucmljaCJdXSkKCnRfY2ZfbW9ub2N5dGVfc2lnX2JhdGNoX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9tb25vY3l0ZV9zaWdfYmF0Y2h2aXNpdCkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX21vbm9jeXRlX3NpZ19iYXRjaF9ncFtbIm91dGNvbWVfdXAiXV1bWyJHT19lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9tb25vY3l0ZV9zaWdfYmF0Y2hfZ3BbWyJvdXRjb21lX3VwIl1dW1siSFBfZW5yaWNoIl1dKQpgYGAKCiMjIyBJbmRpdmlkdWFsIHZpc2l0cywgTW9ub2N5dGVzCgpOb3cgZm9jdXMgaW4gb24gdGhlIG1vbm9jeXRlIHNhbXBsZXMgb24gYSBwZXItdmlzaXQgYmFzaXMuCgojIyMjIFZpc2l0IDEKCmBgYHtyIGNmX21vbm9jeXRlX2RlX3Zpc2l0c192MX0KdF9jZl9tb25vY3l0ZV92MV9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHR2MV9tb25vY3l0ZXMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfY2ZfbW9ub2N5dGVfdjFfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX21vbm9jeXRlX3YxX2RlX3N2YSwga2VlcGVycyA9IGNmX2NvbnRyYXN0LAojICByZGEgPSBnbHVlKCJyZGEvdF9tb25vY3l0ZV92MV9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV92MV9jZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbW9ub2N5dGVfdjFfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkaW0odF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCmBgYAoKIyMjIyBWaXNpdCAyCgpgYGB7ciBjZl9tb25vY3l0ZV9kZV92aXNpdHNfdjJ9CnRfY2ZfbW9ub2N5dGVfdjJfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZSh0djJfbW9ub2N5dGVzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X2NmX21vbm9jeXRlX3YyX3RhYmxlc19zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9jZl9tb25vY3l0ZV92Ml9kZV9zdmEsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbW9ub2N5dGVfdjJfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfdjJfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX21vbm9jeXRlX3YyX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX21vbm9jeXRlX3YyX3RhYmxlc19zdmEsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L01vbm9jeXRlcy90X21vbm9jeXRlX3YyX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKZGltKHRfY2ZfbW9ub2N5dGVfdjJfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfbW9ub2N5dGVfdjJfc2lnX3N2YSRkZXNlcSRkb3duc1tbMV1dKQpgYGAKCiMjIyMgVmlzaXQgMwoKYGBge3IgY2ZfbW9ub2N5dGVfZGVfdmlzaXRzX3YzfQp0X2NmX21vbm9jeXRlX3YzX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodHYzX21vbm9jeXRlcywgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9jZl9tb25vY3l0ZV92M190YWJsZXNfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfbW9ub2N5dGVfdjNfZGVfc3ZhLCBrZWVwZXJzID0gY2ZfY29udHJhc3QsCiMgIHJkYSA9IGdsdWUoInJkYS90X21vbm9jeXRlX3YzX2NmX3RhYmxlX3N2YS12e3Zlcn0ucmRhIiksCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L01vbm9jeXRlcy90X21vbm9jeXRlX3YzX2NmX3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV92M19zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF9jZl9tb25vY3l0ZV92M190YWJsZXNfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV92M19jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmRpbSh0X2NmX21vbm9jeXRlX3YzX3NpZ19zdmEkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX21vbm9jeXRlX3YzX3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKYGBgCgojIyMjIE1vbm9jeXRlczogQ29tcGFyZSBzdmEgdG8gYmF0Y2gtaW4tbW9kZWwKCmBgYHtyIGF1Y2NfbW9ub2N5dGV9CnN2YV9hdWNjIDwtIGNhbGN1bGF0ZV9hdWNjKHRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YVtbImRhdGEiXV1bWzFdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsMiA9IHRfY2ZfbW9ub2N5dGVfdGFibGVzX2JhdGNodmlzaXRbWyJkYXRhIl1dW1sxXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHB5ID0gImRlc2VxX2FkanAiLCBseSA9ICJkZXNlcV9sb2dmYyIpCnN2YV9hdWNjCgpzaGFyZWRfaWRzIDwtIHJvd25hbWVzKHRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YVtbImRhdGEiXV1bWzFdXSkgJWluJQogIHJvd25hbWVzKHRfY2ZfbW9ub2N5dGVfdGFibGVzX2JhdGNodmlzaXRbWyJkYXRhIl1dW1sxXV0pCmZpcnN0IDwtIHRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YVtbImRhdGEiXV1bWzFdXVtzaGFyZWRfaWRzLCBdCnNlY29uZCA8LSB0X2NmX21vbm9jeXRlX3RhYmxlc19iYXRjaHZpc2l0W1siZGF0YSJdXVtbMV1dW3Jvd25hbWVzKGZpcnN0KSwgXQpjb3IudGVzdChmaXJzdFtbImRlc2VxX2xvZ2ZjIl1dLCBzZWNvbmRbWyJkZXNlcV9sb2dmYyJdXSkKYGBgCgojIyMjIyBnUHJvZmlsZXI6IE1vbm9jeXRlcyBieSB2aXNpdCwgVjEKClYxOiBVcDogMTQgZ2VuZXM7IE5vIGNhdGVnb3JpZXMKVjE6IERvd246IDUyIGdlbmVzOyAyMCBHTywgNSBURgoKYGBge3IgdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2dwX3Zpc2l0c30KdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfZ3BbWyJvdXRjb21lX2Rvd24iXV1bWyJHT19lbnJpY2giXV0pCmBgYAoKIyMjIyMgZ1Byb2ZpbGVyOiBNb25vY3l0ZXMgYnkgdmlzaXQsIFYyCgpWMjogVXA6IDEgZ2VuZQpWMjogRG93bjogMCBnZW5lcy4KCiMjIyMjIGdQcm9maWxlcjogTW9ub2N5dGVzIGJ5IHZpc2l0LCBWMwoKVjM6IFVwOiA0IGdlbmVzLgpWMzogRG93bjogMCBnZW5lcy4KCiMjIyBOZXV0cm9waGlsIHNhbXBsZXMKClN3aXRjaCBjb250ZXh0IHRvIHRoZSBOZXV0cm9waGlscywgb25jZSBhZ2FpbiByZXBlYXQgdGhlIGFuYWx5c2lzCnVzaW5nIFNWQSBhbmQgdmlzaXQgYXMgYSBiYXRjaCBmYWN0b3IuCgpgYGB7ciBuZXV0cm9waGlsX29ubHl9CnRfY2ZfbmV1dHJvcGhpbF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfbmV1dHJvcGhpbHMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfY2ZfbmV1dHJvcGhpbF90YWJsZXNfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfbmV1dHJvcGhpbF9kZV9zdmEsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbmV1dHJvcGhpbF9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbmV1dHJvcGhpbF90YWJsZXNfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQoKZGltKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9uZXV0cm9waGlsX3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKCnRfY2ZfbmV1dHJvcGhpbF9kZV9iYXRjaHZpc2l0IDwtIGFsbF9wYWlyd2lzZSh0X25ldXRyb3BoaWxzLCBtb2RlbF9iYXRjaCA9IFRSVUUsIGZpbHRlciA9IFRSVUUpCgp0X2NmX25ldXRyb3BoaWxfdGFibGVzX2JhdGNodmlzaXQgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9jZl9uZXV0cm9waGlsX2RlX2JhdGNodmlzaXQsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbmV1dHJvcGhpbF9jZl90YWJsZV9iYXRjaHZpc2l0LXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX2NmX3RhYmxlc19iYXRjaHZpc2l0LXZ7dmVyfS54bHN4IikpCnRfY2ZfbmV1dHJvcGhpbF9zaWdfYmF0Y2h2aXNpdCA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbmV1dHJvcGhpbF90YWJsZXNfYmF0Y2h2aXNpdCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX2NmX3NpZ19iYXRjaHZpc2l0LXZ7dmVyfS54bHN4IikpCgpkaW0odF9jZl9uZXV0cm9waGlsX3NpZ19iYXRjaHZpc2l0JGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9uZXV0cm9waGlsX3NpZ19iYXRjaHZpc2l0JGRlc2VxJGRvd25zW1sxXV0pCmBgYAoKIyMjIyBnUHJvZmlsZXI6IE5ldXRyb3BoaWxzCgpVcDogODQgZ2VuZXM7IDUgR08sIDIgUmVhY3RvbWUsIDMgVEYsIG5vIG90aGVycy4KRG93bjogMjkgZ2VuZXM6IDEyIEdPLCAxIFJlYWN0b21lLCAxIFRGLCAxIG1pUk5BLCAxMSBIUCwgMCBvdGhlcnMKCmBgYHtyIHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2dwfQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfdXAiXV1bWyJHT19lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siVEZfZW5yaWNoIl1dKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkdPX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkhQX2VucmljaCJdXSkKYGBgCgojIyMjIE5ldXRyb3BoaWxzIGJ5IHZpc2l0CgpXaGVuIEkgZGlkIHRoaXMgd2l0aCB0aGUgbW9ub2N5dGVzLCBJIHNwbGl0IGl0IHVwIGludG8gbXVsdGlwbGUgYmxvY2tzCmZvciBlYWNoIHZpc2l0LiAgVGhpcyB0aW1lIEkgYW0ganVzdCBnb2luZyB0byBydW4gdGhlbSBhbGwgdG9nZXRoZXIuCgpgYGB7ciBuZXV0cm9waGlsX3Zpc2l0c30KdmlzaXRjZl9mYWN0b3IgPC0gcGFzdGUwKCJ2IiwgcERhdGEodF9uZXV0cm9waGlscylbWyJ2aXNpdG51bWJlciJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBEYXRhKHRfbmV1dHJvcGhpbHMpW1siZmluYWxvdXRjb21lIl1dKQp0X25ldXRyb3BoaWxfdmlzaXRjZiA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRfbmV1dHJvcGhpbHMsIGZhY3Q9dmlzaXRjZl9mYWN0b3IpCgp0X2NmX25ldXRyb3BoaWxfdmlzaXRzX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodF9uZXV0cm9waGlsX3Zpc2l0Y2YsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFKQoKdF9jZl9uZXV0cm9waGlsX3Zpc2l0c190YWJsZXNfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfbmV1dHJvcGhpbF92aXNpdHNfZGVfc3ZhLCBrZWVwZXJzID0gdmlzaXRjZl9jb250cmFzdHMsCiMgIHJkYSA9IGdsdWUoInJkYS90X25ldXRyb3BoaWxfdmlzaXRjZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdmlzaXRjZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfY2ZfbmV1dHJvcGhpbF92aXNpdHNfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbmV1dHJvcGhpbF92aXNpdHNfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX3Zpc2l0Y2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkaW0odF9jZl9uZXV0cm9waGlsX3Zpc2l0c19zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9uZXV0cm9waGlsX3Zpc2l0c19zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCgp0X2NmX25ldXRyb3BoaWxfdjFfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZSh0djFfbmV1dHJvcGhpbHMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfY2ZfbmV1dHJvcGhpbF92MV90YWJsZXNfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfbmV1dHJvcGhpbF92MV9kZV9zdmEsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbmV1dHJvcGhpbF92MV9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjFfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbmV1dHJvcGhpbF92MV90YWJsZXNfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkaW0odF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmEkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YSRkZXNlcSRkb3duc1tbMV1dKQoKdF9jZl9uZXV0cm9waGlsX3YyX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodHYyX25ldXRyb3BoaWxzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X2NmX25ldXRyb3BoaWxfdjJfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX25ldXRyb3BoaWxfdjJfZGVfc3ZhLAogIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbmV1dHJvcGhpbF92Ml9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjJfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfdjJfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfbmV1dHJvcGhpbF92Ml90YWJsZXNfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjJfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkaW0odF9jZl9uZXV0cm9waGlsX3YyX3NpZ19zdmEkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX25ldXRyb3BoaWxfdjJfc2lnX3N2YSRkZXNlcSRkb3duc1tbMV1dKQoKdF9jZl9uZXV0cm9waGlsX3YzX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodHYzX25ldXRyb3BoaWxzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X2NmX25ldXRyb3BoaWxfdjNfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX25ldXRyb3BoaWxfdjNfZGVfc3ZhLCBrZWVwZXJzID0gY2ZfY29udHJhc3QsCiMgIHJkYSA9IGdsdWUoInJkYS90X25ldXRyb3BoaWxfdjNfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX3YzX2NmX3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF9jZl9uZXV0cm9waGlsX3YzX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX25ldXRyb3BoaWxfdjNfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX3YzX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKZGltKHRfY2ZfbmV1dHJvcGhpbF92M19zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9tb25vY3l0ZV92M19zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCmBgYAoKIyMjIyMgZ1Byb2ZpbGVyOiBOZXV0cm9waGlscyBieSB2aXNpdCwgVjEKClYxOiBVcDogNSBnZW5lcwpWMTogRG93bjogOCBnZW5lczsgMTQgR08uCgpgYGB7ciB0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ncF92aXNpdHMxfQp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkdPX2VucmljaCJdXSkKYGBgCgojIyMjIyBnUHJvZmlsZXI6IE5ldXRyb3BoaWxzIGJ5IHZpc2l0LCBWMgoKVXA6IDUgZ2VuZXM7IDMgR08sIDEwIFRGLgpEb3duOiAxIGdlbmUuCgojIyMjIE5ldXRyb3BoaWxzOiBDb21wYXJlIHN2YSB0byBiYXRjaC1pbi1tb2RlbAoKYGBge3IgY29tcGFyZV9uZXV0cm9waGlsX2F1Y2N9CnN2YV9hdWNjIDwtIGNhbGN1bGF0ZV9hdWNjKHRfY2ZfbmV1dHJvcGhpbF90YWJsZXNfc3ZhW1siZGF0YSJdXVtbMV1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0YmwyID0gdF9jZl9uZXV0cm9waGlsX3RhYmxlc19iYXRjaHZpc2l0W1siZGF0YSJdXVtbMV1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICBweSA9ICJkZXNlcV9hZGpwIiwgbHkgPSAiZGVzZXFfbG9nZmMiKQpzdmFfYXVjYwoKc2hhcmVkX2lkcyA8LSByb3duYW1lcyh0X2NmX25ldXRyb3BoaWxfdGFibGVzX3N2YVtbImRhdGEiXV1bWzFdXSkgJWluJQogIHJvd25hbWVzKHRfY2ZfbmV1dHJvcGhpbF90YWJsZXNfYmF0Y2h2aXNpdFtbImRhdGEiXV1bWzFdXSkKZmlyc3QgPC0gdF9jZl9uZXV0cm9waGlsX3RhYmxlc19zdmFbWyJkYXRhIl1dW1sxXV1bc2hhcmVkX2lkcywgXQpzZWNvbmQgPC0gdF9jZl9uZXV0cm9waGlsX3RhYmxlc19iYXRjaHZpc2l0W1siZGF0YSJdXVtbMV1dW3Jvd25hbWVzKGZpcnN0KSwgXQpjb3IudGVzdChmaXJzdFtbImRlc2VxX2xvZ2ZjIl1dLCBzZWNvbmRbWyJkZXNlcV9sb2dmYyJdXSkKYGBgCgojIyMgRW9zaW5vcGhpbHMKClRoaXMgdGltZSwgd2l0aCBmZWVsaW5nISAgUmVwZWF0aW5nIHRoZSBzYW1lIHNldCBvZiB0YXNrcyB3aXRoIHRoZQplb3Npbm9waGlsIHNhbXBsZXMuCgpgYGB7ciBlb3Npbm9waGlsX29ubHl9CnRfY2ZfZW9zaW5vcGhpbF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfZW9zaW5vcGhpbHMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCgp0X2NmX2Vvc2lub3BoaWxfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX2Vvc2lub3BoaWxfZGVfc3ZhLCBrZWVwZXJzID0gY2ZfY29udHJhc3QsCiMgIHJkYSA9IGdsdWUoInJkYS90X2Vvc2lub3BoaWxfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX2NmX3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX2Vvc2lub3BoaWxfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKCmRpbSh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCgp0X2NmX2Vvc2lub3BoaWxfZGVfYmF0Y2h2aXNpdCA8LSBhbGxfcGFpcndpc2UodF9lb3Npbm9waGlscywgbW9kZWxfYmF0Y2ggPSBUUlVFLCBmaWx0ZXIgPSBUUlVFKQp0X2NmX2Vvc2lub3BoaWxfdGFibGVzX2JhdGNodmlzaXQgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9jZl9lb3Npbm9waGlsX2RlX2JhdGNodmlzaXQsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfZW9zaW5vcGhpbF9jZl90YWJsZV9iYXRjaHZpc2l0LXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX2NmX3RhYmxlc19iYXRjaHZpc2l0LXZ7dmVyfS54bHN4IikpCnRfY2ZfZW9zaW5vcGhpbF9zaWdfYmF0Y2h2aXNpdCA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfZW9zaW5vcGhpbF90YWJsZXNfYmF0Y2h2aXNpdCwKICBleGNlbCA9IGdsdWUoImV4Y2VsL3RfZW9zaW5vcGhpbF9jZl9zaWdfYmF0Y2h2aXNpdC12e3Zlcn0ueGxzeCIpKQoKZGltKHRfY2ZfZW9zaW5vcGhpbF9zaWdfYmF0Y2h2aXNpdCRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfZW9zaW5vcGhpbF9zaWdfYmF0Y2h2aXNpdCRkZXNlcSRkb3duc1tbMV1dKQoKdmlzaXRjZl9mYWN0b3IgPC0gcGFzdGUwKCJ2IiwgcERhdGEodF9lb3Npbm9waGlscylbWyJ2aXNpdG51bWJlciJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBEYXRhKHRfZW9zaW5vcGhpbHMpW1siZmluYWxvdXRjb21lIl1dKQp0X2Vvc2lub3BoaWxfdmlzaXRjZiA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRfZW9zaW5vcGhpbHMsIGZhY3QgPSB2aXNpdGNmX2ZhY3RvcikKdF9jZl9lb3Npbm9waGlsX3Zpc2l0c19kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfZW9zaW5vcGhpbF92aXNpdGNmLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSkKCnRfY2ZfZW9zaW5vcGhpbF92aXNpdHNfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX2Vvc2lub3BoaWxfdmlzaXRzX2RlX3N2YSwga2VlcGVycyA9IHZpc2l0Y2ZfY29udHJhc3RzLAojICByZGEgPSBnbHVlKCJyZGEvdF9lb3Npbm9waGlsX3Zpc2l0Y2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX3Zpc2l0Y2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX2Vvc2lub3BoaWxfdmlzaXRzX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX2Vvc2lub3BoaWxfdmlzaXRzX3RhYmxlc19zdmEsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0Vvc2lub3BoaWxzL3RfZW9zaW5vcGhpbF92aXNpdGNmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKCmRpbSh0X2NmX2Vvc2lub3BoaWxfdmlzaXRzX3NpZ19zdmEkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX2Vvc2lub3BoaWxfdmlzaXRzX3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKYGBgCgojIyMjIEMvRiBjZWxsdHlwZSB2b2xjYW5vIHBsb3RzIHdpdGggc3BlY2lmaWMgbGFiZWxzCgpgYGB7ciB2b2xjYW5vX2NvbmRpdGlvbl9kZV9sYWJlbHN9Cm51bV9jb2xvciA8LSBjb2xvcl9jaG9pY2VzW1siY2xpbmljX2NmIl1dW1siVHVtYWNvX2ZhaWx1cmUiXV0KZGVuX2NvbG9yIDwtIGNvbG9yX2Nob2ljZXNbWyJjbGluaWNfY2YiXV1bWyJUdW1hY29fY3VyZSJdXQp3YW50ZWRfZ2VuZXMgPC0gYygiRkk0NEwiLCAiSUZJMjciLCAiUFJSNSIsICJQUlI1LUFSSEdBUDgiLCAiUkhDRSIsCiAgICAgICAgICAgICAgICAgICJGQlhPMzkiLCAiUlNBRDIiLCAiU01UTkwxIiwgIlVTUDE4IiwgIkFGQVAxIikKCmNmX21vbm9jeXRlX3RhYmxlIDwtIHRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YVtbImRhdGEiXV1bWyJvdXRjb21lIl1dCmNmX21vbm9jeXRlX3ZvbGNhbm8gPC0gcGxvdF92b2xjYW5vX2NvbmRpdGlvbl9kZSgKICBjZl9tb25vY3l0ZV90YWJsZSwgIm91dGNvbWUiLCBsYWJlbCA9IHdhbnRlZF9nZW5lcywKICBmY19jb2wgPSAiZGVzZXFfbG9nZmMiLCBwX2NvbCA9ICJkZXNlcV9hZGpwIiwgbGluZV9wb3NpdGlvbiA9IE5VTEwsCiAgY29sb3JfaGlnaCA9IG51bV9jb2xvciwgY29sb3JfbG93ID0gZGVuX2NvbG9yLCBsYWJlbF9zaXplID0gNikKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9jZl9tb25vY3l0ZV92b2xjYW5vX2xhYmVsZWQtdnt2ZXJ9LnN2ZyIpKQpjZl9tb25vY3l0ZV92b2xjYW5vJHBsb3QKZGV2Lm9mZigpCmNmX21vbm9jeXRlX3ZvbGNhbm8kcGxvdAoKY2ZfZW9zaW5vcGhpbF90YWJsZSA8LSB0X2NmX2Vvc2lub3BoaWxfdGFibGVzX3N2YVtbImRhdGEiXV1bWyJvdXRjb21lIl1dCmNmX2Vvc2lub3BoaWxfdm9sY2FubyA8LSBwbG90X3ZvbGNhbm9fY29uZGl0aW9uX2RlKAogIGNmX2Vvc2lub3BoaWxfdGFibGUsICJvdXRjb21lIiwgbGFiZWwgPSB3YW50ZWRfZ2VuZXMsCiAgZmNfY29sID0gImRlc2VxX2xvZ2ZjIiwgcF9jb2wgPSAiZGVzZXFfYWRqcCIsIGxpbmVfcG9zaXRpb24gPSBOVUxMLAogIGNvbG9yX2hpZ2ggPSBudW1fY29sb3IsIGNvbG9yX2xvdyA9IGRlbl9jb2xvciwgbGFiZWxfc2l6ZSA9IDYpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvY2ZfZW9zaW5vcGhpbF92b2xjYW5vX2xhYmVsZWQtdnt2ZXJ9LnN2ZyIpKQpjZl9lb3Npbm9waGlsX3ZvbGNhbm8kcGxvdApkZXYub2ZmKCkKY2ZfZW9zaW5vcGhpbF92b2xjYW5vJHBsb3QKCmNmX25ldXRyb3BoaWxfdGFibGUgPC0gdF9jZl9uZXV0cm9waGlsX3RhYmxlc19zdmFbWyJkYXRhIl1dW1sib3V0Y29tZSJdXQpjZl9uZXV0cm9waGlsX3ZvbGNhbm8gPC0gcGxvdF92b2xjYW5vX2NvbmRpdGlvbl9kZSgKICBjZl9uZXV0cm9waGlsX3RhYmxlLCAib3V0Y29tZSIsIGxhYmVsID0gd2FudGVkX2dlbmVzLAogIGZjX2NvbCA9ICJkZXNlcV9sb2dmYyIsIHBfY29sID0gImRlc2VxX2FkanAiLCBsaW5lX3Bvc2l0aW9uID0gTlVMTCwKICBjb2xvcl9oaWdoID0gbnVtX2NvbG9yLCBjb2xvcl9sb3cgPSBkZW5fY29sb3IsIGxhYmVsX3NpemUgPSA2KQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL2NmX25ldXRyb3BoaWxfdm9sY2Fub19sYWJlbGVkLXZ7dmVyfS5zdmciKSkKY2ZfbmV1dHJvcGhpbF92b2xjYW5vJHBsb3QKZGV2Lm9mZigpCmNmX25ldXRyb3BoaWxfdm9sY2FubyRwbG90CmBgYAoKIyMjIyBnUHJvZmlsZXI6IEVvc2lub3BoaWxzCgpVcDogMTE2IGdlbmVzOyAxMjMgR08sIDIgS0VHRywgNyBSZWFjdG9tZSwgNSBXUCwgNjkgVEYsIDEgbWlSTkEsIDAgb3RoZXJzCkRvd246ICA3NCBnZW5lczsgNSBHTywgMSBSZWFjdG9tZSwgNCBURiwgMCBvdGhlcnMKCmBgYHtyIHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2dwfQp0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfdXAiXV1bWyJHT19lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siUkVBQ19lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siV1BfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2dwW1sib3V0Y29tZV91cCJdXVtbIlRGX2VucmljaCJdXSkKCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZ3BbWyJvdXRjb21lX2Rvd24iXV1bWyJHT19lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZ3BbWyJvdXRjb21lX2Rvd24iXV1bWyJURl9lbnJpY2giXV0pCmBgYAoKIyMjIEVvc2lub3BoaWwgdGltZSBjb21wYXJpc29ucwoKYGBge3IgZW9zaW5vcGhpbF92aXNpdHN9CnRfY2ZfZW9zaW5vcGhpbF92MV9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHR2MV9lb3Npbm9waGlscywgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdF9jZl9lb3Npbm9waGlsX3YxX3RhYmxlc19zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF9jZl9lb3Npbm9waGlsX3YxX2RlX3N2YSwga2VlcGVycyA9IGNmX2NvbnRyYXN0LAojICByZGEgPSBnbHVlKCJyZGEvdF9lb3Npbm9waGlsX3YxX2NmX3RhYmxlX3N2YS12e3Zlcn0ucmRhIiksCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0Vvc2lub3BoaWxzL3RfZW9zaW5vcGhpbF92MV9jZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF9jZl9lb3Npbm9waGlsX3YxX3RhYmxlc19zdmEsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0Vvc2lub3BoaWxzL3RfZW9zaW5vcGhpbF92MV9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmRpbSh0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YSRkZXNlcSR1cHNbWzFdXSkKZGltKHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhJGRlc2VxJGRvd25zW1sxXV0pCgp0X2NmX2Vvc2lub3BoaWxfdjJfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZSh0djJfZW9zaW5vcGhpbHMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRfY2ZfZW9zaW5vcGhpbF92Ml90YWJsZXNfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfY2ZfZW9zaW5vcGhpbF92Ml9kZV9zdmEsIGtlZXBlcnMgPSBjZl9jb250cmFzdCwKIyAgcmRhID0gZ2x1ZSgicmRhL3RfZW9zaW5vcGhpbF92Ml9jZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdjJfY2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X2NmX2Vvc2lub3BoaWxfdjJfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfY2ZfZW9zaW5vcGhpbF92Ml90YWJsZXNfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdjJfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkaW0odF9jZl9lb3Npbm9waGlsX3YyX3NpZ19zdmEkZGVzZXEkdXBzW1sxXV0pCmRpbSh0X2NmX2Vvc2lub3BoaWxfdjJfc2lnX3N2YSRkZXNlcSRkb3duc1tbMV1dKQoKdF9jZl9lb3Npbm9waGlsX3YzX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodHYzX2Vvc2lub3BoaWxzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0X2NmX2Vvc2lub3BoaWxfdjNfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X2NmX2Vvc2lub3BoaWxfdjNfZGVfc3ZhLCBrZWVwZXJzID0gY2ZfY29udHJhc3QsCiMgIHJkYSA9IGdsdWUoInJkYS90X2Vvc2lub3BoaWxfdjNfY2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX3YzX2NmX3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3YzX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X2NmX2Vvc2lub3BoaWxfdjNfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX3YzX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKZGltKHRfY2ZfZW9zaW5vcGhpbF92M19zaWdfc3ZhJGRlc2VxJHVwc1tbMV1dKQpkaW0odF9jZl9lb3Npbm9waGlsX3YzX3NpZ19zdmEkZGVzZXEkZG93bnNbWzFdXSkKYGBgCgojIyMjIGdQcm9maWxlcjogRW9zaW5vcGhpbHMgVjEKClVwOiAxMyBnZW5lcywgbm8gaGl0cy4KRG93bjogMTkgZ2VuZXM7IDExIEdPLCAxIFJlYWN0b21lLCAxIFRGCgpgYGB7ciB0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ncHYyfQp0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIkdPX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfZG93biJdXVtbIlRGX2VucmljaCJdXSkKYGBgCgojIyMjIGdQcm9maWxlcjogRW9zaW5vcGhpbHMgVjIKClVwOiA5IGdlbmVzOyAyMyBHTywgMiBLRUdHLCAyIFJlYWN0b21lLCA0IFdQCkRvd246IDQgZ2VuZXM7IG5vIGhpdHMKCmBgYHtyIHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2dwdjN9CnRfY2ZfZW9zaW5vcGhpbF92Ml9zaWdfc3ZhX2dwIDwtIGFsbF9ncHJvZmlsZXIodF9jZl9lb3Npbm9waGlsX3YyX3NpZ19zdmEpCgplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2dwW1sib3V0Y29tZV91cCJdXVtbIkdPX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ncFtbIm91dGNvbWVfdXAiXV1bWyJXUF9lbnJpY2giXV0pCmBgYAoKIyMjIyBnUHJvZmlsZXI6IEVvc2lub3BoaWxzIFYzCgpVcDogNjggZ2VuZXM7IDk1IEdPLCAyIEtFR0csIDEyIFJlYWN0b21lLCAzIFdQLCA2MyBURiwgMSBtaVJOQQpEb3duOiAyOSBnZW5lczsgMyBHTywgMSBXUCwgMSBURiwgMyBtaVJOQQoKYGBge3IgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZ3B2NH0KdF9jZl9lb3Npbm9waGlsX3YzX3NpZ19zdmFfZ3AgPC0gYWxsX2dwcm9maWxlcih0X2NmX2Vvc2lub3BoaWxfdjNfc2lnX3N2YSkKCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZ3BbWyJvdXRjb21lX3VwIl1dW1siR09fZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2dwW1sib3V0Y29tZV91cCJdXVtbIldQX2VucmljaCJdXSkKYGBgCgojIyMjIEVvc2lub3BoaWxzOiBDb21wYXJlIHN2YSB0byBiYXRjaC1pbi12aXNpdAoKYGBge3IgZW9zaW5vcGhpbF9hdWNjfQpzdmFfYXVjYyA8LSBjYWxjdWxhdGVfYXVjYyh0X2NmX2Vvc2lub3BoaWxfdGFibGVzX3N2YVtbImRhdGEiXV1bWzFdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsMiA9IHRfY2ZfZW9zaW5vcGhpbF90YWJsZXNfYmF0Y2h2aXNpdFtbImRhdGEiXV1bWzFdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHkgPSAiZGVzZXFfYWRqcCIsIGx5ID0gImRlc2VxX2xvZ2ZjIikKc3ZhX2F1Y2MKCnNoYXJlZF9pZHMgPC0gcm93bmFtZXModF9jZl9lb3Npbm9waGlsX3RhYmxlc19zdmFbWyJkYXRhIl1dW1sxXV0pICVpbiUKICByb3duYW1lcyh0X2NmX2Vvc2lub3BoaWxfdGFibGVzX2JhdGNodmlzaXRbWyJkYXRhIl1dW1sxXV0pCmZpcnN0IDwtIHRfY2ZfZW9zaW5vcGhpbF90YWJsZXNfc3ZhW1siZGF0YSJdXVtbMV1dW3NoYXJlZF9pZHMsIF0Kc2Vjb25kIDwtIHRfY2ZfZW9zaW5vcGhpbF90YWJsZXNfYmF0Y2h2aXNpdFtbImRhdGEiXV1bWzFdXVtyb3duYW1lcyhmaXJzdCksIF0KY29yLnRlc3QoZmlyc3RbWyJkZXNlcV9sb2dmYyJdXSwgc2Vjb25kW1siZGVzZXFfbG9nZmMiXV0pCmBgYAoKIyMjIyBDb21wYXJlIG1vbm9jeXRlIENGLCBuZXV0cm9waGlsIENGLCBlb3Npbm9waGlsIENGCgpgYGB7ciBjb21wYXJlX21vbm9fbmV1dF9lb30KdF9tb25vX25ldXRfc3ZhX2F1Y2MgPC0gY2FsY3VsYXRlX2F1Y2ModF9jZl9tb25vY3l0ZV90YWJsZXNfc3ZhW1siZGF0YSJdXVtbIm91dGNvbWUiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibDIgPSB0X2NmX25ldXRyb3BoaWxfdGFibGVzX3N2YVtbImRhdGEiXV1bWyJvdXRjb21lIl1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBweSA9ICJkZXNlcV9hZGpwIiwgbHkgPSAiZGVzZXFfbG9nZmMiKQp0X21vbm9fbmV1dF9zdmFfYXVjYwoKdF9tb25vX2VvX3N2YV9hdWNjIDwtIGNhbGN1bGF0ZV9hdWNjKHRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YVtbImRhdGEiXV1bWyJvdXRjb21lIl1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsMiA9IHRfY2ZfZW9zaW5vcGhpbF90YWJsZXNfc3ZhW1siZGF0YSJdXVtbIm91dGNvbWUiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBweSA9ICJkZXNlcV9hZGpwIiwgbHkgPSAiZGVzZXFfbG9nZmMiKQp0X21vbm9fZW9fc3ZhX2F1Y2MKCnRfbmV1dF9lb19zdmFfYXVjYyA8LSBjYWxjdWxhdGVfYXVjYyh0X2NmX25ldXRyb3BoaWxfdGFibGVzX3N2YVtbImRhdGEiXV1bWyJvdXRjb21lIl1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsMiA9IHRfY2ZfZW9zaW5vcGhpbF90YWJsZXNfc3ZhW1siZGF0YSJdXVtbIm91dGNvbWUiXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBweSA9ICJkZXNlcV9hZGpwIiwgbHkgPSAiZGVzZXFfbG9nZmMiKQp0X25ldXRfZW9fc3ZhX2F1Y2MKYGBgCgojIyMgQnkgdmlzaXQKCkZvciB0aGVzZSBjb250cmFzdHMsIHdlIHdhbnQgdG8gc2VlIGZhaWxfdjEgdnMuIGN1cmVfdjEsIGZhaWxfdjIKdnMuIGN1cmVfdjIgZXRjLiAgQXMgYSByZXN1bHQsIHdlIHdpbGwgbmVlZCB0byBqdWdnbGUgdGhlIGRhdGEKc2xpZ2h0bHkgYW5kIGFkZCBhbm90aGVyIHNldCBvZiBjb250cmFzdHMuCgojIyMjIEN1cmUvRmFpbCBieSB2aXNpdHMsIGFsbCBjZWxsIHR5cGVzCgpgYGB7ciB2aXNpdF9jZl9hbGxfZGV9CnRfdmlzaXRfY2ZfYWxsX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodF92aXNpdGNmLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQoKdF92aXNpdF9jZl9hbGxfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X3Zpc2l0X2NmX2FsbF9kZV9zdmEsIGtlZXBlcnMgPSB2aXNpdGNmX2NvbnRyYXN0cywKIyAgcmRhID0gZ2x1ZSgicmRhL3RfYWxsX3Zpc2l0Y2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoImFuYWx5c2VzLzRfdHVtYWNvL0RFX0N1cmVfdnNfRmFpbC90X2FsbF92aXNpdGNmX3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF92aXNpdF9jZl9hbGxfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfdmlzaXRfY2ZfYWxsX3RhYmxlc19zdmEsCiAgZXhjZWwgPSBnbHVlKCJhbmFseXNlcy80X3R1bWFjby9ERV9DdXJlX3ZzX0ZhaWwvdF9hbGxfdmlzaXRjZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmBgYAoKYGBge3IgdmlzaXRfZ3Byb2ZpbGVyfQp0X3Zpc2l0X2NmX2FsbF9ncCA8LSBhbGxfZ3Byb2ZpbGVyKHRfdmlzaXRfY2ZfYWxsX3NpZ19zdmEpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXQsIE1vbm9jeXRlcwoKYGBge3IgdmlzaXRfY2ZfbW9ub2N5dGVfZGV9CnZpc2l0Y2ZfZmFjdG9yIDwtIHBhc3RlMCgidiIsIHBEYXRhKHRfbW9ub2N5dGVzKVtbInZpc2l0bnVtYmVyIl1dLCAiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBwRGF0YSh0X21vbm9jeXRlcylbWyJmaW5hbG91dGNvbWUiXV0pCnRfbW9ub2N5dGVzX3Zpc2l0Y2YgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X21vbm9jeXRlcywgZmFjdCA9IHZpc2l0Y2ZfZmFjdG9yKQoKdF92aXNpdF9jZl9tb25vY3l0ZV9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfbW9ub2N5dGVzX3Zpc2l0Y2YsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFKQoKdF92aXNpdF9jZl9tb25vY3l0ZV90YWJsZXNfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfdmlzaXRfY2ZfbW9ub2N5dGVfZGVfc3ZhLCBrZWVwZXJzID0gdmlzaXRjZl9jb250cmFzdHMsCiMgIHJkYSA9IGdsdWUoInJkYS90X21vbm9jeXRlX3Zpc2l0Y2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfdmlzaXRjZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfdmlzaXRfY2ZfbW9ub2N5dGVfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfdmlzaXRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfdmlzaXRjZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCgp0X3YxZmNfZGVzZXFfbWEgPC0gdF92aXNpdF9jZl9tb25vY3l0ZV90YWJsZXNfc3ZhW1sicGxvdHMiXV1bWyJ2MWNmIl1dW1siZGVzZXFfbWFfcGxvdHMiXV1bWyJwbG90Il1dCmRldiA8LSBwcChmaWxlID0gImltYWdlcy9tb25vY3l0ZV9jZl9kZV92MV9tYXBsb3QucG5nIikKdF92MWZjX2Rlc2VxX21hCmNsb3NlZCA8LSBkZXYub2ZmKCkKdF92MWZjX2Rlc2VxX21hCgp0X3YyZmNfZGVzZXFfbWEgPC0gdF92aXNpdF9jZl9tb25vY3l0ZV90YWJsZXNfc3ZhW1sicGxvdHMiXV1bWyJ2MmNmIl1dW1siZGVzZXFfbWFfcGxvdHMiXV1bWyJwbG90Il1dCmRldiA8LSBwcChmaWxlID0gImltYWdlcy9tb25vY3l0ZV9jZl9kZV92Ml9tYXBsb3QucG5nIikKdF92MmZjX2Rlc2VxX21hCmNsb3NlZCA8LSBkZXYub2ZmKCkKdF92MmZjX2Rlc2VxX21hCgp0X3YzZmNfZGVzZXFfbWEgPC0gdF92aXNpdF9jZl9tb25vY3l0ZV90YWJsZXNfc3ZhW1sicGxvdHMiXV1bWyJ2M2NmIl1dW1siZGVzZXFfbWFfcGxvdHMiXV1bWyJwbG90Il1dCmRldiA8LSBwcChmaWxlID0gImltYWdlcy9tb25vY3l0ZV9jZl9kZV92M19tYXBsb3QucG5nIikKdF92M2ZjX2Rlc2VxX21hCmNsb3NlZCA8LSBkZXYub2ZmKCkKdF92M2ZjX2Rlc2VxX21hCmBgYAoKT25lIHF1ZXJ5IGZyb20gQWxlamFuZHJvIGlzIHRvIGxvb2sgYXQgdGhlIGdlbmVzIHNoYXJlZCB1cC9kb3duIGFjcm9zcwp2aXNpdHMuICBJIGFtIG5vdCBlbnRpcmVseSBjZXJ0YWluIHdlIGhhdmUgZW5vdWdoIHNhbXBsZXMgZm9yIHRoaXMgdG8Kd29yaywgYnV0IGxldCB1cyBmaW5kIG91dC4KCkkgYW0gdGhpbmtpbmcgdGhpcyBpcyBhIGdvb2QgcGxhY2UgdG8gdXNlIHRoZSBBVUNDIGN1cnZlcyBJIGxlYXJuZWQKYWJvdXQgdGhhbmtzIHRvIEp1bGllIENyaWRsYW5kLgoKTm90ZSB0aGF0IHRoZSBmb2xsb3dpbmcgaXMgYWxsIG1vbm9jeXRlIHNhbXBsZXMsIHRoaXMgc2hvdWxkIHRoZXJlZm9yZQpwb3RlbnRpYWxseSBiZSBtb3ZlZCB1cCBhbmQgYSB2ZXJzaW9uIG9mIHRoaXMgd2l0aCBvbmx5IHRoZSBUdW1hY28Kc2FtcGxlcyBwdXQgaGVyZT8KCmBgYHtyIG1vbm9jeXRlX3NoYXJlZF9kZV9nZW5lc30KdjFjZiA8LSB0X3Zpc2l0X2NmX21vbm9jeXRlX3RhYmxlc19zdmFbWyJkYXRhIl1dW1sidjFjZiJdXQp2MmNmIDwtIHRfdmlzaXRfY2ZfbW9ub2N5dGVfdGFibGVzX3N2YVtbImRhdGEiXV1bWyJ2MmNmIl1dCnYzY2YgPC0gdF92aXNpdF9jZl9tb25vY3l0ZV90YWJsZXNfc3ZhW1siZGF0YSJdXVtbInYzY2YiXV0KCnYxX3NpZyA8LSBjKAogIHJvd25hbWVzKHRfdmlzaXRfY2ZfbW9ub2N5dGVfc2lnX3N2YVtbImRlc2VxIl1dW1sidXBzIl1dW1sidjFjZiJdXSksCiAgcm93bmFtZXModF92aXNpdF9jZl9tb25vY3l0ZV9zaWdfc3ZhW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbInYxY2YiXV0pKQpsZW5ndGgodjFfc2lnKQoKdjJfc2lnIDwtIGMoCiAgcm93bmFtZXModF92aXNpdF9jZl9tb25vY3l0ZV9zaWdfc3ZhW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJ2MmNmIl1dKSwKICByb3duYW1lcyh0X3Zpc2l0X2NmX21vbm9jeXRlX3NpZ19zdmFbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sidjJjZiJdXSkpCmxlbmd0aCh2Ml9zaWcpCgp2M19zaWcgPC0gYygKICByb3duYW1lcyh0X3Zpc2l0X2NmX21vbm9jeXRlX3NpZ19zdmFbWyJkZXNlcSJdXVtbInVwcyJdXVtbInYyY2YiXV0pLAogIHJvd25hbWVzKHRfdmlzaXRfY2ZfbW9ub2N5dGVfc2lnX3N2YVtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJ2MmNmIl1dKSkKbGVuZ3RoKHYzX3NpZykKCnRfbW9ub2N5dGVfdmlzaXRfYXVjY192MnYxIDwtIGNhbGN1bGF0ZV9hdWNjKHYxY2YsIHRibDIgPSB2MmNmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBweSA9ICJkZXNlcV9hZGpwIiwgbHkgPSAiZGVzZXFfbG9nZmMiKQpkZXYgPC0gcHAoZmlsZSA9ICJpbWFnZXMvbW9ub2N5dGVfdmlzaXRfdjJ2MV9hdWNjLnBuZyIpCnRfbW9ub2N5dGVfdmlzaXRfYXVjY192MnYxW1sicGxvdCJdXQpjbG9zZWQgPC0gZGV2Lm9mZigpCnRfbW9ub2N5dGVfdmlzaXRfYXVjY192MnYxW1sicGxvdCJdXQoKdF9tb25vY3l0ZV92aXNpdF9hdWNjX3YzdjEgPC0gY2FsY3VsYXRlX2F1Y2ModjFjZiwgdGJsMiA9IHYzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB5ID0gImRlc2VxX2FkanAiLCBseSA9ICJkZXNlcV9sb2dmYyIpCmRldiA8LSBwcChmaWxlID0gImltYWdlcy9tb25vY3l0ZV92aXNpdF92M3YxX2F1Y2MucG5nIikKdF9tb25vY3l0ZV92aXNpdF9hdWNjX3YzdjFbWyJwbG90Il1dCmNsb3NlZCA8LSBkZXYub2ZmKCkKdF9tb25vY3l0ZV92aXNpdF9hdWNjX3YzdjFbWyJwbG90Il1dCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXQsIE5ldXRyb3BoaWxzCgpgYGB7ciB2aXNpdF9jZl9uZXV0cm9waGlsX2RlfQp2aXNpdGNmX2ZhY3RvciA8LSBwYXN0ZTAoInYiLCBwRGF0YSh0X25ldXRyb3BoaWxzKVtbInZpc2l0bnVtYmVyIl1dLCAiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBwRGF0YSh0X25ldXRyb3BoaWxzKVtbImZpbmFsb3V0Y29tZSJdXSkKdF9uZXV0cm9waGlsX3Zpc2l0Y2YgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X25ldXRyb3BoaWxzLCBmYWN0ID0gdmlzaXRjZl9mYWN0b3IpCnRfdmlzaXRfY2ZfbmV1dHJvcGhpbF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfbmV1dHJvcGhpbF92aXNpdGNmLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFKQoKdF92aXNpdF9jZl9uZXV0cm9waGlsX3RhYmxlc19zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF92aXNpdF9jZl9uZXV0cm9waGlsX2RlX3N2YSwga2VlcGVycyA9IHZpc2l0Y2ZfY29udHJhc3RzLAojICByZGEgPSBnbHVlKCJyZGEvdF9uZXV0cm9waGlsX3Zpc2l0Y2ZfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX3Zpc2l0Y2ZfdGFibGVzX3N2YS12e3Zlcn0ueGxzeCIpKQp0X3Zpc2l0X2NmX25ldXRyb3BoaWxfc2lnX3N2YSA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfdmlzaXRfY2ZfbmV1dHJvcGhpbF90YWJsZXNfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdmlzaXRjZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXQsIEVvc2lub3BoaWxzCgpgYGB7ciB2aXNpdF9jZl9lb3Npbm9waGlsX2RlfQp2aXNpdGNmX2ZhY3RvciA8LSBwYXN0ZTAoInYiLCBwRGF0YSh0X2Vvc2lub3BoaWxzKVtbInZpc2l0bnVtYmVyIl1dLCAiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBwRGF0YSh0X2Vvc2lub3BoaWxzKVtbImZpbmFsb3V0Y29tZSJdXSkKdF9lb3Npbm9waGlsX3Zpc2l0Y2YgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X2Vvc2lub3BoaWxzLCBmYWN0ID0gdmlzaXRjZl9mYWN0b3IpCnRfdmlzaXRfY2ZfZW9zaW5vcGhpbF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfZW9zaW5vcGhpbF92aXNpdGNmLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFKQp0X3Zpc2l0X2NmX2Vvc2lub3BoaWxfdGFibGVzX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0X3Zpc2l0X2NmX2Vvc2lub3BoaWxfZGVfc3ZhLCBrZWVwZXJzID0gdmlzaXRjZl9jb250cmFzdHMsCiMgIHJkYSA9IGdsdWUoInJkYS90X2Vvc2lub3BoaWxfdmlzaXRjZl90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdmlzaXRjZl90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfdmlzaXRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF92aXNpdF9jZl9lb3Npbm9waGlsX3RhYmxlc19zdmEsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0Vvc2lub3BoaWxzL3RfZW9zaW5vcGhpbF92aXNpdGNmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyBQZXJzaXN0ZW5jZSBpbiB2aXNpdCAzCgpIYXZpbmcgcHV0IHNvbWUgU0wgcmVhZCBtYXBwaW5nIGluZm9ybWF0aW9uIGluIHRoZSBzYW1wbGUgc2hlZXQsIE1hcmlhCkFkZWxhaWRhIGFkZGVkIGEgbmV3IGNvbHVtbiB1c2luZyBpdCB3aXRoIHRoZSBwdXRhdGl2ZSBwZXJzaXN0ZW5jZQpzdGF0ZSBvbiBhIHBlci1zYW1wbGUgYmFzaXMuICBPbmUgcXVlc3Rpb24gd2hpY2ggYXJpc2VkIGZyb20gdGhhdDoKd2hhdCBkaWZmZXJlbmNlcyBhcmUgb2JzZXJ2YWJsZSBiZXR3ZWVuIHRoZSBwZXJzaXN0ZW50IHllcyB2cy4gbm8Kc2FtcGxlcyBvbiBhIHBlci1jZWxsLXR5cGUgYmFzaXMgYW1vbmcgdGhlIHZpc2l0IDMgc2FtcGxlcy4KCiMjIyBTZXR0aW5nIHVwCgpGaXJzdCB0aGluZ3MgZmlyc3QsIGNyZWF0ZSB0aGUgZGF0YXNldHMuCgpgYGB7ciBwZXJzaXN0ZW5jZV9zZXR1cH0KcGVyc2lzdGVuY2VfZXhwdCA8LSBzdWJzZXRfZXhwdCh0X2NsaW5pY2FsLCBzdWJzZXQgPSAicGVyc2lzdGVuY2U9PSdZJ3xwZXJzaXN0ZW5jZT09J04nIikgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0ID0gJ3Zpc2l0bnVtYmVyPT0zJykgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gJ3BlcnNpc3RlbmNlJykKCiMjIHBlcnNpc3RlbmNlX2Jpb3BzeSA8LSBzdWJzZXRfZXhwdChwZXJzaXN0ZW5jZV9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSdiaW9wc3knIikKcGVyc2lzdGVuY2VfbW9ub2N5dGUgPC0gc3Vic2V0X2V4cHQocGVyc2lzdGVuY2VfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nbW9ub2N5dGVzJyIpCnBlcnNpc3RlbmNlX25ldXRyb3BoaWwgPC0gc3Vic2V0X2V4cHQocGVyc2lzdGVuY2VfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nbmV1dHJvcGhpbHMnIikKcGVyc2lzdGVuY2VfZW9zaW5vcGhpbCA8LSBzdWJzZXRfZXhwdChwZXJzaXN0ZW5jZV9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQpgYGAKCiMjIyBUYWtlIGEgbG9vawoKU2VlIGlmIHRoZXJlIGFyZSBhbnkgcGF0dGVybnMgd2hpY2ggbG9vayB1c2FibGUuCgpgYGB7ciBwZXJzaXN0ZW5jZV9wbG90fQojIyBBbGwKcGVyc2lzdGVuY2Vfbm9ybSA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2Vfbm9ybSkkcGxvdApwZXJzaXN0ZW5jZV9uYiA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2VfbmIpJHBsb3QKCiMjIEJpb3BzaWVzCiMjcGVyc2lzdGVuY2VfYmlvcHN5X25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfYmlvcHN5LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQojI3Bsb3RfcGNhKHBlcnNpc3RlbmNlX2Jpb3BzeV9ub3JtKSRwbG90CiMjIEluc3VmZmljaWVudCBkYXRhCgojIyBNb25vY3l0ZXMKcGVyc2lzdGVuY2VfbW9ub2N5dGVfbm9ybSA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9tb25vY3l0ZSwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX21vbm9jeXRlX25vcm0pJHBsb3QKcGVyc2lzdGVuY2VfbW9ub2N5dGVfbmIgPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfbW9ub2N5dGUsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9tb25vY3l0ZV9uYikkcGxvdAoKIyMgTmV1dHJvcGhpbHMKcGVyc2lzdGVuY2VfbmV1dHJvcGhpbF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX25ldXRyb3BoaWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX25ldXRyb3BoaWxfbm9ybSkkcGxvdApwZXJzaXN0ZW5jZV9uZXV0cm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX25ldXRyb3BoaWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX25ldXRyb3BoaWxfbmIpJHBsb3QKCiMjIEVvc2lub3BoaWxzCnBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9lb3Npbm9waGlsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25vcm0pJHBsb3QKcGVyc2lzdGVuY2VfZW9zaW5vcGhpbF9uYiA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9lb3Npbm9waGlsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25iKSRwbG90CmBgYAoKIyMjIHBlcnNpc3RlbmNlIERFCgpgYGB7ciBwZXJzaXN0ZW5jZV9kZX0KcGVyc2lzdGVuY2VfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZShwZXJzaXN0ZW5jZV9leHB0LCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQpwZXJzaXN0ZW5jZV90YWJsZV9zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgcGVyc2lzdGVuY2VfZGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgiYW5hbHlzZXMvNF90dW1hY28vREVfUGVyc2lzdGVuY2UvcGVyc2lzdGVuY2VfYWxsX2RlX3N2YS12e3Zlcn0ueGxzeCIpKQoKcGVyc2lzdGVuY2VfbW9ub2N5dGVfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZShwZXJzaXN0ZW5jZV9tb25vY3l0ZSwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKcGVyc2lzdGVuY2VfbW9ub2N5dGVfdGFibGVfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHBlcnNpc3RlbmNlX21vbm9jeXRlX2RlX3N2YSwKICBleGNlbCA9IGdsdWUoImFuYWx5c2VzLzRfdHVtYWNvL0RFX1BlcnNpc3RlbmNlL3BlcnNpc3RlbmNlX21vbm9jeXRlX2RlX3N2YS12e3Zlcn0ueGxzeCIpKQoKcGVyc2lzdGVuY2VfbmV1dHJvcGhpbF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHBlcnNpc3RlbmNlX25ldXRyb3BoaWwsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnBlcnNpc3RlbmNlX25ldXRyb3BoaWxfdGFibGVfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHBlcnNpc3RlbmNlX25ldXRyb3BoaWxfZGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgiYW5hbHlzZXMvNF90dW1hY28vREVfUGVyc2lzdGVuY2UvcGVyc2lzdGVuY2VfbmV1dHJvcGhpbF9kZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKCnBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZShwZXJzaXN0ZW5jZV9lb3Npbm9waGlsLCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQpwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX3RhYmxlX3N2YSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICBwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX2RlX3N2YSwKICBleGNlbCA9IGdsdWUoImFuYWx5c2VzLzRfdHVtYWNvL0RFX1BlcnNpc3RlbmNlL3BlcnNpc3RlbmNlX2Vvc2lub3BoaWxfZGVfc3ZhLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMgQ29tcGFyaW5nIHZpc2l0cyB3aXRob3V0IHJlZ2FyZCB0byBjdXJlL2ZhaWwKCiMjIyBBbGwgY2VsbCB0eXBlcwoKYGBge3IgZGVfY2ZfdmlzaXRfYWxsfQp0X3Zpc2l0X2FsbF9kZV9zdmEgPC0gYWxsX3BhaXJ3aXNlKHRfdmlzaXQsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCgp0X3Zpc2l0X2FsbF90YWJsZV9zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF92aXNpdF9hbGxfZGVfc3ZhLCBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAojICByZGEgPSBnbHVlKCJyZGEvdF9hbGxfdmlzaXRfdGFibGVfc3ZhLXZ7dmVyfS5yZGEiKSwKICBleGNlbCA9IGdsdWUoImFuYWx5c2VzLzRfdHVtYWNvL0RFX1Zpc2l0cy90X2FsbF92aXNpdF90YWJsZXNfc3ZhLXZ7dmVyfS54bHN4IikpCnRfdmlzaXRfYWxsX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X3Zpc2l0X2FsbF90YWJsZV9zdmEsCiAgZXhjZWwgPSBnbHVlKCJhbmFseXNlcy80X3R1bWFjby9ERV9WaXNpdHMvdF9hbGxfdmlzaXRfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyBNb25vY3l0ZSBzYW1wbGVzCgpgYGB7ciBkZV9jZl92aXNpdF9tb25vY3l0ZX0KdF92aXNpdF9tb25vY3l0ZXMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X21vbm9jeXRlcywgZmFjdCA9ICJ2aXNpdG51bWJlciIpCnRfdmlzaXRfbW9ub2N5dGVfZGVfc3ZhIDwtIGFsbF9wYWlyd2lzZSh0X3Zpc2l0X21vbm9jeXRlcywgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKCnRfdmlzaXRfbW9ub2N5dGVfdGFibGVfc3ZhIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfdmlzaXRfbW9ub2N5dGVfZGVfc3ZhLCBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAojICByZGEgPSBnbHVlKCJyZGEvdF9tb25vY3l0ZV92aXNpdF90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgiYW5hbHlzZXMvNF90dW1hY28vREVfVmlzaXRzL01vbm9jeXRlcy90X21vbm9jeXRlX3Zpc2l0X3RhYmxlc19zdmEtdnt2ZXJ9Lnhsc3giKSkKdF92aXNpdF9tb25vY3l0ZV9zaWdfc3ZhIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgdF92aXNpdF9tb25vY3l0ZV90YWJsZV9zdmEsCiAgZXhjZWwgPSBnbHVlKCJhbmFseXNlcy80X3R1bWFjby9ERV9WaXNpdHMvTW9ub2N5dGVzL3RfbW9ub2N5dGVfdmlzaXRfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyBOZXV0cm9waGlsIHNhbXBsZXMKCmBgYHtyIGRlX2NmX3Zpc2l0X25ldXRyb3BoaWx9CnRfdmlzaXRfbmV1dHJvcGhpbHMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0X25ldXRyb3BoaWxzLCBmYWN0ID0gInZpc2l0bnVtYmVyIikKdF92aXNpdF9uZXV0cm9waGlsX2RlX3N2YSA8LSBhbGxfcGFpcndpc2UodF92aXNpdF9uZXV0cm9waGlscywgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKCnRfdmlzaXRfbmV1dHJvcGhpbF90YWJsZV9zdmEgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgdF92aXNpdF9uZXV0cm9waGlsX2RlX3N2YSwga2VlcGVycyA9IHZpc2l0X2NvbnRyYXN0cywKIyAgcmRhID0gZ2x1ZSgicmRhL3RfbmV1dHJvcGhpbF92aXNpdF90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgiYW5hbHlzZXMvNF90dW1hY28vREVfVmlzaXRzL05ldXRyb3BoaWxzL3RfbmV1dHJvcGhpbF92aXNpdF90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKdF92aXNpdF9uZXV0cm9waGlsX3NpZ19zdmEgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0X3Zpc2l0X25ldXRyb3BoaWxfdGFibGVfc3ZhLAogIGV4Y2VsID0gZ2x1ZSgiYW5hbHlzZXMvNF90dW1hY28vREVfVmlzaXRzL05ldXRyb3BoaWxzL3RfbmV1dHJvcGhpbF92aXNpdF9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIEVvc2lub3BoaWwgc2FtcGxlcwoKYGBge3IgZGVfY2ZfdmlzaXRfZW9zaW5vcGhpbH0KdF92aXNpdF9lb3Npbm9waGlscyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHRfZW9zaW5vcGhpbHMsIGZhY3Q9InZpc2l0bnVtYmVyIikKdF92aXNpdF9lb3Npbm9waGlsX2RlIDwtIGFsbF9wYWlyd2lzZSh0X3Zpc2l0X2Vvc2lub3BoaWxzLCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQoKdF92aXNpdF9lb3Npbm9waGlsX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRfdmlzaXRfZW9zaW5vcGhpbF9kZSwga2VlcGVycyA9IHZpc2l0X2NvbnRyYXN0cywKIyAgcmRhID0gZ2x1ZSgicmRhL3RfZW9zaW5vcGhpbF92aXNpdF90YWJsZV9zdmEtdnt2ZXJ9LnJkYSIpLAogIGV4Y2VsID0gZ2x1ZSgiYW5hbHlzZXMvNF90dW1hY28vREVfVmlzaXRzL0Vvc2lub3BoaWxzL3RfZW9zaW5vcGhpbF92aXNpdF90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKdF92aXNpdF9lb3Npbm9waGlsX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRfdmlzaXRfZW9zaW5vcGhpbF90YWJsZSwKICBleGNlbCA9IGdsdWUoImFuYWx5c2VzLzRfdHVtYWNvL0RFX1Zpc2l0cy9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdmlzaXRfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpgYGAKCiMgRXhwbG9yZSBST0MKCkFsZWphbmRybyBzaG93ZWQgc29tZSBST0MgY3VydmVzIGZvciBlb3Npbm9waGlsIGRhdGEgc2hvd2luZwpzZW5zaXRpdml0eSB2cy4gc3BlY2lmaWNpdHkgb2YgYSBjb3VwbGUgZ2VuZXMgd2hpY2ggd2VyZSBvYnNlcnZlZCBpbgp2MSBlb3Npbm9waGlscyB2cy4gYWxsLXRpbWVzIGVvc2lub3BoaWxzIGFjcm9zcyBjdXJlL2ZhaWwuICBJIGFtCmN1cmlvdXMgdG8gYmV0dGVyIHVuZGVyc3RhbmQgaG93IHRoaXMgd2FzIGRvbmUgYW5kIHdoYXQgdXRpbGl0eSBpdAptaWdodCBoYXZlIGluIG90aGVyIGNvbnRleHRzLgoKVG8gdGhhdCBlbmQsIEkgd2FudCB0byB0cnkgc29tZXRoaW5nIHNpbWlsYXIgbXlzZWxmLiBJbiBvcmRlciB0bwpwcm9wZXJseSBwZXJmb3JtIHRoZSBhbmFseXNpcyB3aXRoIHRoZXNlIHZhcmlvdXMgdG9vbHMsIEkgbmVlZCB0bwpyZWNvbmZpZ3VyZSB0aGUgZGF0YSBpbiBhIHByZXR0eSBzcGVjaWZpYyBmb3JtYXQ6CgoxLiAgU2luZ2xlIGRmIHdpdGggMSByb3cgcGVyIHNldCBvZiBvYnNlcnZhdGlvbnMgKHNhbXBsZSBpbiB0aGlzIGNhc2UKSSB0aGluaykKMi4gIFRoZSBvdXRjb21lIGNvbHVtbihzKSBuZWVkIHRvIGJlIDEgKG9yIG1vcmU/KSBtZXRhZGF0YSBmYWN0b3IocykKKGN1cmUvZmFpbCBvciBhIHBhc3RlMCBvZiByZWxldmFudCBxdWVyaWVzIChlb192MV9jdXJlLAplb192MTIzX2N1cmUsIGV0YykKMy4gIFRoZSBwcmVkaWN0b3IgY29sdW1uKHMpIGFyZSB0aGUgbWVhc3VyZW1lbnRzIChycGttIG9mIDEgb3IgbW9yZQpnZW5lcyksIDEgY29sdW1uIGVhY2ggZ2VuZS4KCklmIEkgaW50ZW5kIHRvIHVzZSB0aGlzIGZvciBvdXIgdHggZGF0YSwgSSB3aWxsIGxpa2VseSBuZWVkIGEgdXRpbGl0eQpmdW5jdGlvbiB0byBjcmVhdGUgdGhlIHByb3Blcmx5IGZvcm1hdHRlZCBpbnB1dCBkZi4KCkZvciB0aGUgcHVycG9zZXMgb2YgbXkgcGxheWluZywgSSB3aWxsIGNob29zZSB0aHJlZSBnZW5lcyBmcm9tIHRoZQplb3Npbm9waGlsIEMvRiB0YWJsZSwgb25lIHdoaWNoIGlzIHNpZ25pZmljYW50LCBvbmUgd2hpY2ggaXMgbm90LCBhbmQKYW4gYXJiaXRyYXJ5LgoKVGhlIGlucHV0IGdlbmVzIHdpbGwgdGhlcmVmb3JlIGJlIGNob3NlbiBmcm9tIHRoZSBkYXRhIHN0cnVjdHVyZToKdF9jZl9lb3Npbm9waGlsX3RhYmxlc19zdmE6CgpFTlNHMDAwMDAxOTgxNzgsIEVOU0cwMDAwMDE3OTM0NCwgRU5TRzAwMDAwMTgyNjI4CgpgYGB7ciByb2N9CmVvX3Jwa20gPC0gbm9ybWFsaXplX2V4cHQodHYxX2Vvc2lub3BoaWxzLCBjb252ZXJ0ID0gInJwa20iLCBjb2x1bW4gPSAiY2RzX2xlbmd0aCIpCmBgYAoKYGBge3Igc2NvdHRfZXh0ZXJuYWx9CnRlc3QgPC0gYWxsX3BhaXJ3aXNlKHRtcmMzX2V4dGVybmFsLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSAic2ltcGxlIikKdGVzdF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcyh0ZXN0LCBleGNlbCA9ICJleGNlbC90bXJjM19zY290dF9iaW9wc2llcy54bHN4IikKdGVzdF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyh0ZXN0X3RhYmxlLCBleGNlbCA9ICJleGNlbC90bXJjM19zY290dF9iaW9wc2llc19zaWcueGxzeCIpCgp0bXJjX2V4dGVybmFsX3NwZWNpZXMgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh0bXJjM19leHRlcm5hbCwgZmFjdCA9ICJQYXJhc2l0ZVNwZWNpZXMiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY29sb3JfY2hvaWNlc1tbInBhcmFzaXRlIl1dKQoKYGBgCgpgYGB7ciBzYXZlbWV9CiMjIFNraXBwaW5nIHRoaXMgYmVjYXVzZSBpdCBpcyB0YWtpbmcgdG9vIGxvbmcuCiMjaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiMjICBwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQojIyAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiMjICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHNhdmVmaWxlKSkKIyMgIHRtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWU9c2F2ZWZpbGUpKQojI30KYGBgCgpgYGB7ciBsb2FkbWVfYWZ0ZXIsIGV2YWw9RkFMU0V9CnRtcCA8LSBsb2FkbWUoZmlsZW5hbWUgPSBzYXZlZmlsZSkKYGBgCg==