1 Quick xlsx reader functions

My functions to perform the various overrepresentation/enrichment analyses generally assume the result of extract_significant_genes() as the input. Sadly, I do not want to save those data structures to disk because they can be quite monstrously large when serialized (because I keep a reference to the input in them which gets dereferenced on save()). As a result, it is far simpler/safer to just read the xlsx outputs produced by combine_de_tables and extract_significant_genes. Ergo the following two little functions.

table_reader <- function(xlsx, sheet = "outcome") {
  input_df <- openxlsx::readWorkbook(xlsx, sheet = sheet, startRow = 2)
  rownames(input_df) <- input_df[["row.names"]]
  input_df[["row.names"]] <- NULL
  print(dim(input_df))
  if (nrow(input_df) < 5000) {
    warning("Something appears wrong with the de table: ", input_xlsx)
  }
  return(input_df)
}

sig_reader <- function(xlsx, sheet = "outcome", direction = "up") {
  this_sheet <- paste0(direction, "_deseq_", sheet)
  input_df <- openxlsx::readWorkbook(xlsx, sheet = this_sheet, startRow = 2)
  rownames(input_df) <- input_df[["row.names"]]
  input_df[["row.names"]] <- NULL
  dim(input_df)
  if (nrow(input_df) < 20) {
    message("There are less than 20 rows in this significance table, it is unlikely to be interesting.")
  }
  return(input_df)
}

I have been having some difficulties getting the treeplot fonts to match our readability goals. The set of things I have tried so far are:

  1. Setting a geom_text(size = x): this failed because it didn’t know to which element(s) to apply the new size.
  2. Changing the options for theme_bw(): this does change some font elements, but not the ones that I wanted. I tried more than a few, most importantly theme(text = element_text(size = x))
  3. Changing the default for theme_bw via theme_update(text = element_text(size = x)): this also changes some text, but not all.
  4. Invoking update_geom_defaults(“text”, aes(size = 10)) at the stop of my document. This does not seem to do much of anything.
  5. Playing with options in enrichplot::treeplot(), notably the cex and fontsize options. These also help with some, but not all fonts. I also spent a fair amount of time reading the code for treeplot() and decided to try #6 before I got too frustrated.
  6. Just changing the canvas size of my output pdf. This worked great, though it may require setting the wordwrap options in treeplot.

With that in mind, the following two parameters are going to set the width and height of the output pdf documents which will be sent to Maria Adelaida in order to arrange into the final figures via inkscape.

treeplot_height <- 6
treeplot_width <- 12
wrap_width <- 24
desired_go_ont <- "BP"

2 Introduction

I once again moved the ontology analyses to their own document. This is primarily because I want a fresh notebook to play around with these and get some of the resulting clutter out of the DE notebooks.

The con of doing this is that some of my enrichment methods are smart enough to directly take the output from combine_de_tables()/extract_significant_genes(). I guess I can dispatch a method to take the xlsx file as input…

Thus, for each enrichment analysis that was in the differential expression documents, there will now be a few stanzas here, one which loads the appropriate xlsx file, one which performs gProfiler, and one which uses clusterProfiler. On occasion there may be another with random stuff like me poking at transcription factors or other side interests…

In addition, I am going to do the Tumaco-only analyses first, because they are what are actually in the paper.

2.1 Gene Set Enrichment

The gene set enrichment will follow each DE analysis during this document. I am adding a series of explicitly GSEA analyses in this most recent iteration, in these I will pass the full DE table and check the distribution of logFC values against the genes in each category as opposed to the simpler over-enrichment of the high/low DE genes.

Most (all?) of the gene set enrichment analyses performed in this document are a combination of gProfiler2 (Kolberg et al. (2020)) and clusterProfiler (Yu et al. (2012)). There are functions available in hpgltools to also perform a few other methods, but for the moment I am sticking to only these two. Oh yeah, I need to wrap clusterProfiler’s tree (taken from topGO) plotter because it spams plots everywhere

input_xlsx <- glue("analyses/3_cali_and_tumaco/DE_Cure_Fail/Clinical_Samples/tc_clinical_cf_table_sva-v{ver}.xlsx")
all_de_cf_table <- table_reader(input_xlsx, "outcome")
## [1] 12162    68
all_de_cf_up <- sig_reader(glue("analyses/3_cali_and_tumaco/DE_Cure_Fail/Clinical_Samples/tc_clinical_cf_sig_sva-v{ver}.xlsx"), "outcome", "up")
all_de_cf_down <- sig_reader(glue("analyses/3_cali_and_tumaco/DE_Cure_Fail/Clinical_Samples/tc_clinical_cf_sig_sva-v{ver}.xlsx"), "outcome", "down")
all_de_cf <- rbind.data.frame(all_de_cf_up, all_de_cf_down)

tumaco_xlsx <- glue("analyses/4_tumaco/DE_Cure_Fail/t_all_visitcf_sig_sva-v{ver}.xlsx")
t_de_cf <- openxlsx::readWorkbook(tumaco_xlsx, sheet = 3, startRow = 2)
rownames(t_de_cf) <- t_de_cf[["row.names"]]
t_de_cf[["row.names"]] <- NULL
t_de_cf_up <- t_de_cf[, c("deseq_logfc", "deseq_adjp", "deseq_basemean", "deseq_lfcse")]
t_de_cf <- openxlsx::readWorkbook(tumaco_xlsx, sheet = 4, startRow = 2)
rownames(t_de_cf) <- t_de_cf[["row.names"]]
t_de_cf[["row.names"]] <- NULL
t_de_cf_down <- t_de_cf[, c("deseq_logfc", "deseq_adjp", "deseq_basemean", "deseq_lfcse")]
t_de_cf <- rbind.data.frame(t_de_cf_up, t_de_cf_down)

2.2 gProfiler search of all Tumaco 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.

2.3 Shared paths

These are the paths from the DE document and which will be used to get the inputs for gprofiler/clusterprofiler.

xlsx_prefix <- "analyses/4_tumaco"
cf_prefix <- glue("{xlsx_prefix}/DE_Cure_Fail")

2.4 All Tumaco clinical samples cure/fail

The xlsx files are:

  • “{cf_prefix}/All_Samples/t_clinical_cf_table_sva-v{ver}.xlsx”
  • “{cf_prefix}/All_Samples/t_clinical_cf_sig_sva-v{ver}.xlsx”
input_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_cf_table_sva-v{ver}.xlsx")
t_clinical_cf_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 14156    68
input_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_cf_sig_sva-v{ver}.xlsx")
t_clinical_cf_sig_sva_up <- sig_reader(input_xlsx, "outcome")
t_clinical_cf_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")

And without biopsies

input_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_nobiop_cf_table_sva-v{ver}.xlsx")
t_clinicalnb_cf_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 11910    68
input_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_nobiop_cf_sig_sva-v{ver}.xlsx")
t_clinicalnb_cf_sig_sva_up <- sig_reader(input_xlsx, "outcome")
t_clinicalnb_cf_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
t_clinicalnb_cf_sig_sva_both <- rbind.data.frame(t_clinicalnb_cf_sig_sva_up,
                                                 t_clinicalnb_cf_sig_sva_down)

2.4.1 gProfiler

After most of the DE analyses, the set of significantly DE genes gets passed to gProfiler2 and clusterProfiler. One slightly neat thing in my gprofiler (and goseq/topGO/gostats) function(s): it coerces the result into the same datastructure produced by clusterProfiler, thus one may play with the various plotting functions in the enrichplot (Yu (n.d.)) package. This is kind of fun because gProfiler2 provides easy access to a few datasets:

  1. GO: (Ashburner et al. (2000))
  2. KEGG: (Kanehisa and Goto (2000))
  3. Reactome: (Croft et al. (2011))
  4. WikiPathways: (Kutmon et al. (2016))
  5. Transfac: (Wingender et al. (1996))
  6. miRTarBase: (Hsu et al. (2011))
  7. The Human Protein Atlas: (Pontén et al. (2011))
  8. Corum: (Giurgiu et al. (2019))
  9. Human phenotype ontology: (Köhler et al. (2017))

2.4.1.1 Genes higher in cure

My general sense is that the comparisons of primary interest are reactome and one or more GO. I suspect that if there are lots of transcription factors, that might prove interesting.

t_cf_clinical_gp_up <- simple_gprofiler(
  t_clinical_cf_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinical_cure_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinical_gp_up
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_up' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_clinical_gp_up[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinical_gp_up' not found
t_cf_clinical_gp_go_up_tree <- sm(enrichplot::treeplot(go_termsim,
                                                       label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinical_gp_up_tree.pdf",
   width = treeplot_width, height = treeplot_height)
## Warning in pp(file = "images/overrepresentation/t_cf_clinical_gp_up_tree.pdf",
## : The directory: images/overrepresentation does not exist, will attempt to
## create it.
t_cf_clinical_gp_go_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_go_up_tree' not found
dev.off()
## png 
##   2
t_cf_clinical_gp_go_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_go_up_tree' not found
enrichplot::dotplot(t_cf_clinical_gp_up[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_gp_up' not found
reactome_termsim <- enrichplot::pairwise_termsim(t_cf_clinical_gp_up[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinical_gp_up' not found
t_cf_clinical_gp_reac_up_tree <- sm(enrichplot::treeplot(reactome_termsim,
                                                         label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'reactome_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinical_gp_up_tree.pdf",
   width = treeplot_width, height = treeplot_height)
t_cf_clinical_gp_reac_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_reac_up_tree' not found
dev.off()
## png 
##   2
t_cf_clinical_gp_reac_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_reac_up_tree' not found
pp(file = "images/overrepresentation/t_cf_clinical_gp_up_dot.pdf",
   width = treeplot_width, height = treeplot_height)
enrichplot::dotplot(t_cf_clinical_gp_up[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_gp_up' not found
dev.off()
## png 
##   2
enrichplot::dotplot(t_cf_clinical_gp_up[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_gp_up' not found
tf_termsim <- enrichplot::pairwise_termsim(t_cf_clinical_gp_up[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinical_gp_up' not found
## The treeplot fails for this for some reason?
##t_cf_clinical_gp_tf_up_tree <- sm(enrichplot::treeplot(tf_termsim))
enrichplot::dotplot(t_cf_clinical_gp_up[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_gp_up' not found
enrichplot::dotplot(t_cf_clinical_gp_up[["WP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_gp_up' not found

No biopsies!

t_cf_clinicalnb_gp_up <- simple_gprofiler(
  t_clinicalnb_cf_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinicalnb_cure_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinicalnb_gp_up
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_up' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_clinicalnb_gp_up[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinicalnb_gp_up' not found
t_cf_clinicalnb_gp_go_up_tree <- sm(enrichplot::treeplot(go_termsim,
                                                         label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "figures/t_cf_clinicalnb_gp_up_tree.svg",
   width = treeplot_width, height = treeplot_height)
t_cf_clinicalnb_gp_go_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_go_up_tree' not found
dev.off()
## png 
##   2
t_cf_clinicalnb_gp_go_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_go_up_tree' not found
enrichplot::dotplot(t_cf_clinicalnb_gp_up[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinicalnb_gp_up' not found
reactome_termsim <- enrichplot::pairwise_termsim(t_cf_clinicalnb_gp_up[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinicalnb_gp_up' not found
t_cf_clinicalnb_gp_reac_up_tree <- sm(enrichplot::treeplot(reactome_termsim,
                                                           label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'reactome_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinicalnb_gp_up_tree.pdf",
   width = treeplot_width, height = treeplot_height)
t_cf_clinicalnb_gp_reac_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_reac_up_tree' not found
dev.off()
## png 
##   2
t_cf_clinicalnb_gp_reac_up_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_reac_up_tree' not found
pp(file = "images/overrepresentation/t_cf_clinicalnb_gp_up_dot.pdf",
   width = treeplot_width, height = treeplot_height)
enrichplot::dotplot(t_cf_clinicalnb_gp_up[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinicalnb_gp_up' not found
dev.off()
## png 
##   2
enrichplot::dotplot(t_cf_clinicalnb_gp_up[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinicalnb_gp_up' not found
tf_termsim <- enrichplot::pairwise_termsim(t_cf_clinicalnb_gp_up[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinicalnb_gp_up' not found
## The treeplot fails for this for some reason?
##t_cf_clinicalnb_gp_tf_up_tree <- sm(enrichplot::treeplot(tf_termsim))
enrichplot::dotplot(t_cf_clinicalnb_gp_up[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinicalnb_gp_up' not found
enrichplot::dotplot(t_cf_clinicalnb_gp_up[["WP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinicalnb_gp_up' not found

2.4.1.2 Genes higher in fail

The only significant results for this group appear to be GO.

t_cf_clinical_gp_down <- simple_gprofiler(
  t_clinical_cf_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinical_fail_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinical_gp_down
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_down' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_clinical_gp_down[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinical_gp_down' not found
t_cf_clinical_gp_go_down_tree <- sm(enrichplot::treeplot(go_termsim))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinical_gp_down_tree.pdf",
   width = treeplot_width, height = treeplot_height)
t_cf_clinical_gp_go_down_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinical_gp_go_down_tree' not found
dev.off()
## png 
##   2

No biopsies!

t_cf_clinicalnb_gp_down <- simple_gprofiler(
  t_clinicalnb_cf_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinicalnb_fail_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinicalnb_gp_down
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_down' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_clinicalnb_gp_down[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinicalnb_gp_down' not found
t_cf_clinicalnb_gp_go_down_tree <- sm(enrichplot::treeplot(go_termsim))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinicalnb_gp_down_tree.pdf",
   width = treeplot_width, height = treeplot_height)
t_cf_clinicalnb_gp_go_down_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_go_down_tree' not found
dev.off()
## png 
##   2
t_cf_clinicalnb_gp_go_down_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_go_down_tree' not found
## And both, this is not usually where I put this, but the
## clinical samples are a bit of a special case.
t_cf_clinicalnb_gp_both <- simple_gprofiler(
  t_clinicalnb_cf_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinicalnb_fail_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinicalnb_gp_both
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_both' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_clinicalnb_gp_both[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinicalnb_gp_both' not found
t_cf_clinicalnb_gp_go_both_tree <- sm(enrichplot::treeplot(go_termsim))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinicalnb_gp_both_tree.pdf",
   width = treeplot_width, height = treeplot_height)
t_cf_clinicalnb_gp_go_both_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_go_both_tree' not found
dev.off()
## png 
##   2
t_cf_clinicalnb_gp_go_both_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_go_both_tree' not found
reac_termsim <- enrichplot::pairwise_termsim(t_cf_clinicalnb_gp_both[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_clinicalnb_gp_both' not found
t_cf_clinicalnb_gp_reac_both_tree <- sm(enrichplot::treeplot(reac_termsim))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'reac_termsim' not found
pp(file = "images/overrepresentation/t_cf_clinicalnb_gp_both_reac_tree.pdf",
   width = treeplot_width, height = treeplot_height)
t_cf_clinicalnb_gp_reac_both_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_reac_both_tree' not found
dev.off()
## png 
##   2
t_cf_clinicalnb_gp_reac_both_tree
## Error in eval(expr, envir, enclos): object 't_cf_clinicalnb_gp_reac_both_tree' not found

2.4.2 clusterProfiler

The following essentially repeats the gProfiler2 invocation using clusterProfiler. I have a couple of functions which compare the GO results from various methods, perhaps I should dig it out and see how similar the results are using these two tools. My assumption is that the primary differences should arise from the fact that gProfiler theoretically is updating their GO data over time and cProfiler uses the information in org.Hs.eg.db, which afaik has not changed in quite a while.

2.4.2.1 Genes higher in cure

t_cf_clinical_cp_up <- simple_clusterprofiler(
  t_clinical_cf_sig_sva_up, de_table = t_clinical_cf_table_sva,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinical_cure_up_cp-v{ver}.xlsx"))
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Reading KEGG annotation online: "https://rest.kegg.jp/link/hsa/pathway"...
## Reading KEGG annotation online: "https://rest.kegg.jp/list/pathway/hsa"...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Loading required namespace: Vennerable
## 
## Writing the MF data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_clinical_cp_up[["enrich_objects"]][["BP_all"]])

2.4.2.2 Genes higher in fail

t_cf_clinical_cp_down <- simple_clusterprofiler(
  t_clinical_cf_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinical_fail_up_cp-v{ver}.xlsx"))
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_clinical_cp_down[["enrich_objects"]][["BP_all"]])

2.4.2.3 GSEA

GSEA is not associated with either up nor down, it takes the rank order of genes with respect (in this case) to fold-change.

t_cf_clinical_topn_gsea <- plot_topn_gsea(t_cf_clinical_cp_up)
t_cf_clinical_topn_gsea[["GO"]][[1]]

t_cf_clinical_topn_gsea[["GO"]][[2]]

t_cf_clinical_topn_gsea[["GO"]][[3]]

t_cf_clinical_topn_gsea[["GO"]][[4]]

t_cf_clinical_topn_gsea[["GO"]][[5]]

2.5 Visit 1 vs. other visits

The relevant xlsx files are:

  • “{xlsx_prefix}/DE_Visits/tv1_vs_later_tables-v{ver}.xlsx”
  • “{xlsx_prefix}/DE_Visits/tv1_vs_later_sig-v{ver}.xlsx”
input_xlsx <- glue("{xlsx_prefix}/DE_Visits/tv1_vs_later_tables-v{ver}.xlsx")
tv1_vs_later_table <- table_reader(input_xlsx, "later_vs_first")
## [1] 11910    68
input_xlsx <- glue("{xlsx_prefix}/DE_Visits/tv1_vs_later_sig-v{ver}.xlsx")
tv1_vs_later_up_sig <- sig_reader(input_xlsx, "later_vs_first")
tv1_vs_later_down_sig <- sig_reader(input_xlsx, "later_vs_first", "down")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.

2.5.1 Increased in visit 1

I am not likely to do the decreased in visit 1, there are only 7 genes.

2.5.1.1 enrichment: gProfiler

tv1later_up_gp <- simple_gprofiler(
  tv1_vs_later_up_sig,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/tv1_vs_later_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
tv1later_up_gp
## Error in eval(expr, envir, enclos): object 'tv1later_up_gp' not found
enrichplot::dotplot(tv1later_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_up_gp' not found
enrichplot::dotplot(tv1later_up_gp[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_up_gp' not found

2.5.1.2 enrichment: clusterProfiler

Note to self: make some classes for plot_topn_gsea so it can handle the various inputs it is likely to receive.

tv1later_up_cp <- simple_clusterprofiler(
  tv1_vs_later_up_sig, de_table = tv1_vs_later_table,
  orgdb = "org.Hs.eg.db", kegg_prefix = "hs", do_kegg = TRUE)
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
enrichplot::dotplot(tv1later_up_cp[["enrich_objects"]][["MF_all"]])

enrichplot::dotplot(tv1later_up_cp[["enrich_objects"]][["BP_all"]])

written <- write_cp_data(
  tv1later_up_cp,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/tv1_vs_later_up_cp-v{ver}.xlsx"))
## Writing a sheet containing the legend.
## Writing the MF data.
## Writing the CC data.
## Finished writing excel file.

2.5.1.3 GSEA: clusterProfiler

tv1later_topn_gsea <- plot_topn_gsea(tv1later_up_cp)
tv1later_topn_gsea[["GO"]][[1]]

tv1later_topn_gsea[["GO"]][[2]]

2.6 Patient Sex

The relevant input xlsx files are:

  • {xlsx_prefix}/DE_Sex/t_sex_table-v{ver}.xlsx”))
  • {xlsx_prefix}/DE_Sex/t_sex_sig-v{ver}.xlsx”))

Oh, I messed up and put the DE results in the GSEA directory!

Let us see if we observe general male/female differences in the data. This has an important caveat: there are few female failures in the dataset and so the results may reflect that.

input_xlsx <- glue("{xlsx_prefix}/DE_Sex/t_sex_cure_table-v{ver}.xlsx")
t_sex_table <- table_reader(input_xlsx, "male_vs_female")
## [1] 13971    68
input_xlsx <- glue("{xlsx_prefix}/DE_Sex/t_sex_cure_sig-v{ver}.xlsx")
t_sex_up_sig <- sig_reader(input_xlsx, "male_vs_female")
t_sex_down_sig <- sig_reader(input_xlsx, "male_vs_female", "down")

2.6.1 gProfiler

2.6.1.1 Increased in men

t_sex_up_gp <- simple_gprofiler(
  t_sex_up_sig,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/sex_male_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_sex_up_gp
## Error in eval(expr, envir, enclos): object 't_sex_up_gp' not found
enrichplot::dotplot(t_sex_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_sex_up_gp' not found
enrichplot::dotplot(t_sex_up_gp[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_sex_up_gp' not found
enrichplot::dotplot(t_sex_up_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_sex_up_gp' not found

2.6.1.2 Increased in women

t_sex_down_gp <- simple_gprofiler(
  t_sex_down_sig,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/sex_female_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_sex_down_gp
## Error in eval(expr, envir, enclos): object 't_sex_down_gp' not found

Given the results from gProfiler, I do not have high expectations for clusterProfiler, so I am not likely to take the time to write them out. It seems like male/female is confounded with cure/fail.

2.6.2 clusterProfiler

2.6.2.1 Increased in men

t_sex_up_cp <- simple_clusterprofiler(
  t_sex_up_sig, de_table = t_sex_table,
  orgdb = "org.Hs.eg.db", kegg_prefix = "hs", do_kegg = TRUE)
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
enrichplot::dotplot(t_sex_up_cp[["enrich_objects"]][["BP_all"]])

2.6.2.2 Increased in women

t_sex_down_cp <- simple_clusterprofiler(
  t_sex_down_sig, de_table = t_sex_table,
  orgdb = "org.Hs.eg.db", kegg_prefix = "hs", do_kegg = TRUE)
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
enrichplot::dotplot(t_sex_down_cp[["enrich_objects"]][["BP_all"]])

2.6.2.3 GSEA

t_sex_topn_gsea <- plot_topn_gsea(t_sex_up_cp)
t_sex_topn_gsea[["GO"]][[1]]

2.7 Ethnicity

Once again, the relevant files to load:

  • “{xlsx_prefix}/DE_Ethnicity/t_ethnicity_table-v{ver}.xlsx”
  • “{xlsx_prefix}/DE_Ethnicity/t_ethnicity_sig-v{ver}.xlsx”
input_xlsx <- glue("{xlsx_prefix}/DE_Ethnicity/t_ethnicity_table-v{ver}.xlsx")
t_ethnicity_mestizo_indigenous <- table_reader(input_xlsx, "mestizo_indigenous")
## [1] 14156    68
t_ethnicity_mestizo_afrocol <- table_reader(input_xlsx, "mestizo_afrocol")
## [1] 14156    68
t_ethnicity_indigenous_afrocol <- table_reader(input_xlsx, "indigenous_afrocol")
## [1] 14156    68
input_xlsx <- glue("{xlsx_prefix}/DE_Ethnicity/t_ethnicity_sig-v{ver}.xlsx")
t_ethnicity_mestizo_indigenous_up <- sig_reader(input_xlsx, "mestizo_indigenous")
t_ethnicity_mestizo_indigenous_down <- sig_reader(input_xlsx, "mestizo_indigenous", "down")
t_ethnicity_mestizo_afrocol_up <- sig_reader(input_xlsx, "mestizo_afrocol")
t_ethnicity_mestizo_afrocol_down <- sig_reader(input_xlsx, "mestizo_afrocol", "down")
t_ethnicity_indigenous_afrocol_up <- sig_reader(input_xlsx, "indigenous_afrocol")
t_ethnicity_indigenous_afrocol_down <- sig_reader(input_xlsx, "indigenous_afrocol", "down")

2.7.1 gProfiler

2.7.1.1 Increased in mestizo vs indigenous

mestizo_indigenous_up_gp <- simple_gprofiler(
  t_ethnicity_mestizo_indigenous_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_mi_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
mestizo_indigenous_up_gp
## Error in eval(expr, envir, enclos): object 'mestizo_indigenous_up_gp' not found

2.7.1.2 Increased in indigenous vs mestizo

indigenous_mestizo_up_gp <- simple_gprofiler(
  t_ethnicity_mestizo_indigenous_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_im_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
indigenous_mestizo_up_gp
## Error in eval(expr, envir, enclos): object 'indigenous_mestizo_up_gp' not found

2.7.1.3 Increased in mestizo vs afrocolombian

mestizo_afrocol_up_gp <- simple_gprofiler(
  t_ethnicity_mestizo_afrocol_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_ma_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
mestizo_afrocol_up_gp
## Error in eval(expr, envir, enclos): object 'mestizo_afrocol_up_gp' not found

2.7.1.4 Increased in afrocolombian vs mestizo

afrocol_mestizo_up_gp <- simple_gprofiler(
  t_ethnicity_mestizo_afrocol_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_am_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
afrocol_mestizo_up_gp
## Error in eval(expr, envir, enclos): object 'afrocol_mestizo_up_gp' not found

2.7.1.5 Increased in indigenous vs afrocolombian

indigenous_afrocol_up_gp <- simple_gprofiler(
  t_ethnicity_indigenous_afrocol_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_ia_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
indigenous_afrocol_up_gp
## Error in eval(expr, envir, enclos): object 'indigenous_afrocol_up_gp' not found

2.7.1.6 Increased in afrocolombian vs indigenous

afrocol_indigenous_up_gp <- simple_gprofiler(
  t_ethnicity_indigenous_afrocol_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_ai_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
afrocol_indigenous_up_gp
## Error in eval(expr, envir, enclos): object 'afrocol_indigenous_up_gp' not found

2.7.2 clusterProfiler

2.7.2.1 Increased in mestizo vs indigenous

mestizo_indigenous_up_cp <- simple_clusterprofiler(
  t_ethnicity_mestizo_indigenous_up,
  de_table = t_ethnicity_mestizo_indigenous)
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
mestizo_indigenous_up_cp
## A set of ontologies produced by clusterprofiler.

2.7.2.2 Increased in indigenous vs mestizo

indigenous_mestizo_up_cp <- simple_clusterprofiler(
  t_ethnicity_mestizo_indigenous_down)
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
indigenous_mestizo_up_cp
## A set of ontologies produced by clusterprofiler.

2.7.2.3 Increased in mestizo vs afrocolombian

mestizo_afrocol_up_cp <- simple_clusterprofiler(
  t_ethnicity_mestizo_afrocol_up,
  de_table = t_ethnicity_mestizo_afrocol)
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
mestizo_afrocol_up_cp
## A set of ontologies produced by clusterprofiler.

2.7.2.4 Increased in afrocolombian vs mestizo

afrocol_mestizo_up_cp <- simple_clusterprofiler(t_ethnicity_mestizo_afrocol_down)
## Unable to find the fold-change column in the de table, not doing gsea.
afrocol_mestizo_up_cp
## A set of ontologies produced by clusterprofiler.

2.7.2.5 Increased in indigenous vs afrocolombian

indigenous_afrocol_up_cp <- simple_clusterprofiler(
  t_ethnicity_indigenous_afrocol_up,
  de_table = t_ethnicity_indigenous_afrocol)
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
indigenous_afrocol_up_cp
## A set of ontologies produced by clusterprofiler.

2.7.2.6 Increased in afrocolombian vs indigenous

afrocol_indigenous_up_cp <- simple_clusterprofiler(t_ethnicity_indigenous_afrocol_down)
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
afrocol_indigenous_up_cp
## A set of ontologies produced by clusterprofiler.

2.8 Visit 1 cure/fail

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

The relevant xlsx files are:

  • “{cf_prefix}/Visits/t_clinical_v1_cf_table_sva-v{ver}.xlsx”
  • “{cf_prefix}/Visits/t_clinical_v1_cf_sig_sva-v{ver}.xlsx”
input_xlsx <- glue("{cf_prefix}/Visits/t_clinical_v1_cf_table_sva-v{ver}.xlsx")
t_cf_clinical_v1_table_sva <- table_reader(input_xlsx)
## [1] 14023    68
input_xlsx <- glue("{cf_prefix}/Visits/t_clinical_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_clinical_v1_sig_sva_up <- sig_reader(input_xlsx, "outcome")
t_cf_clinical_v1_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")

2.8.1 gProfiler

2.8.1.1 Increased in visit 1 cure/fail

t_cf_clinical_v1_sig_sva_up_gp <- simple_gprofiler(t_cf_clinical_v1_sig_sva_up)
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinical_v1_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_up_gp' not found

2.8.1.2 Increased in visit 1 fail/cure

t_cf_clinical_v1_sig_sva_down_gp <- simple_gprofiler(t_cf_clinical_v1_sig_sva_down)
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_clinical_v1_sig_sva_down_gp
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_down_gp' not found
enrichplot::dotplot(t_cf_clinical_v1_sig_sva_down_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_v1_sig_sva_down_gp' not found

2.8.2 clusterProfiler

2.8.2.1 Increased visit 1 cure/fail

t_cf_clinical_v1_sig_sva_up_cp <- simple_cprofiler(
  t_cf_clinical_v1_sig_sva_up,
  de_table = t_cf_clinical_v1_table_sva,
  orgdb = "org.Hs.eg.db")
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
t_cf_clinical_v1_sig_sva_up_cp
## A set of ontologies produced by clusterprofiler.
enrichplot::dotplot(t_cf_clinical_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])

2.8.2.2 Increased in visit 1 cure/fail

t_cf_clinical_v1_sig_sva_down_cp <- simple_cprofiler(
  t_cf_clinical_v1_sig_sva_down,
  orgdb = "org.Hs.eg.db")
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.

2.8.2.3 GSEA

It appears there are too few results to perform the gsea plots.

2.9 Cure/Fail, Biopsies

The relevant xlsx output may be found at:

  • “{cf_prefix}/Biopsies/t_biopsy_cf_table_sva-v{ver}.xlsx”
  • “{cf_prefix}/Biopsies/t_cf_biopsy_sig_sva-v{ver}.xlsx”
input_xlsx <- glue("{cf_prefix}/Biopsies/t_biopsy_cf_table_sva-v{ver}.xlsx")
t_cf_biopsy_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 13513    68
input_xlsx <- glue("{cf_prefix}/Biopsies/t_cf_biopsy_sig_sva-v{ver}.xlsx")
t_cf_biopsy_sig_sva_up <- sig_reader(input_xlsx, "outcome")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_biopsy_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_biopsy_sig_sva_both <- rbind.data.frame(t_cf_biopsy_sig_sva_up,
                                             t_cf_biopsy_sig_sva_down)

2.9.1 gProfiler

We only have 17 genes in the biopsies, but perhaps they are still interesting?

2.9.1.1 increased in cure vs fail

t_cf_biopsy_sig_sva_gp_up <- simple_gprofiler(
  t_cf_biopsy_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_biopsy_sig_sva_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_biopsy_sig_sva_gp_up
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_gp_up' not found
enrichplot::dotplot(t_cf_biopsy_sig_sva_gp_up[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_biopsy_sig_sva_gp_up' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_biopsy_sig_sva_gp_up[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_biopsy_sig_sva_gp_up' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_biopsy_up_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found

2.9.1.2 increased in fail vs cure

t_cf_biopsy_sig_sva_gp_down <- simple_gprofiler(
  t_cf_biopsy_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_biopsy_sig_sva_down_gp-v{ver}.xlsx"))
t_cf_biopsy_sig_sva_gp_down
## A set of ontologies produced by gprofiler using 11
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are: 
## 0 MF
## 0 BP
## 0 KEGG
## 0 REAC
## 0 WP
## 0 TF
## 0 MIRNA
## 0 HPA
## 0 CORUM
## 0 HP hits.
## Not nearly as interesting

2.9.2 clusterprofiler

Again, clusterprofiler version

2.9.2.1 increased in cure/fail

t_cf_biopsy_sig_sva_cp_up <- simple_cprofiler(
  t_cf_biopsy_sig_sva_up, de_table = t_cf_biopsy_table_sva,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_biopsy_sig_sva_up_cp-v{ver}.xlsx"))
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_biopsy_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])

2.9.2.2 GSEA of cure/fail

t_cf_biopsy_sig_topn_gsea <- plot_topn_gsea(t_cf_biopsy_sig_sva_cp_up)
t_cf_biopsy_sig_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

2.10 Eosinophils cure/fail

input_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_cf_table_sva-v{ver}.xlsx")
t_cf_eosinophil_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 10532    68
input_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_cf_sig_sva-v{ver}.xlsx")
t_cf_eosinophil_sig_sva_up <- sig_reader(input_xlsx, "outcome")
t_cf_eosinophil_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
t_cf_eosinophil_sig_sva_both <- rbind.data.frame(t_cf_eosinophil_sig_sva_up,
                                                 t_cf_eosinophil_sig_sva_down)

2.10.1 gProfiler

2.10.1.1 increased in cure vs fail

t_cf_eosinophil_sig_sva_up_gp <- simple_gprofiler(
  t_cf_eosinophil_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_eosinophil_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_up_gp' not found
enrichplot::dotplot(t_cf_eosinophil_sig_sva_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_eosinophil_sig_sva_up_gp' not found
enrichplot::dotplot(t_cf_eosinophil_sig_sva_up_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_eosinophil_sig_sva_up_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_eosinophil_sig_sva_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_eosinophil_sig_sva_up_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "figures/t_cf_eosinophil_up_gp_go.svg",
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
reac_termsim <- enrichplot::pairwise_termsim(t_cf_eosinophil_sig_sva_up_gp[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_eosinophil_sig_sva_up_gp' not found
reac_treeplot <- sm(treeplot(reac_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'reac_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_eosinophil_up_gp_reac-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
reac_treeplot
## Error in eval(expr, envir, enclos): object 'reac_treeplot' not found
dev.off()
## png 
##   2

2.10.1.2 increased in fail vs cure

t_cf_eosinophil_sig_sva_down_gp <- simple_gprofiler(
  t_cf_eosinophil_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
enrichplot::dotplot(t_cf_eosinophil_sig_sva_down_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_eosinophil_sig_sva_down_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_eosinophil_sig_sva_down_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_eosinophil_sig_sva_down_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_eosinophil_down_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
## There is only one reactome hit, so not plotting it.

2.10.1.3 Both up and down

I evaluated this and the ‘up’ set next to each other and they are extremely similar:

up: 148 GO hits, 68 TF, 0 HPA both: 169 GO, 69 TF, and 2 HPA

Otherwise I think they are the same.

t_cf_eosinophil_sig_sva_both_gp <- simple_gprofiler(
  t_cf_eosinophil_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_both_gp-v{ver}.xlsx"))
## Error in function (type, msg, asError = TRUE) : Recv failure: Connection reset by peer
t_cf_eosinophil_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_both_gp' not found
enrichplot::dotplot(t_cf_eosinophil_sig_sva_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_eosinophil_sig_sva_both_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_eosinophil_sig_sva_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_eosinophil_sig_sva_both_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_formap = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_eosinophil_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
reac_termsim <- enrichplot::pairwise_termsim(t_cf_eosinophil_sig_sva_both_gp[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_eosinophil_sig_sva_both_gp' not found
reac_treeplot <- sm(treeplot(reac_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'reac_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_eosinophil_both_gp_reac-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
reac_treeplot
## Error in eval(expr, envir, enclos): object 'reac_treeplot' not found
dev.off()
## png 
##   2

2.10.2 clusterprofiler

2.10.2.1 increased in cure vs fail

t_cf_eosinophil_sig_sva_cp_up <- simple_cprofiler(
  t_cf_eosinophil_sig_sva_up, de_table = t_cf_eosinophil_table_sva,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_sig_sva_up_cp-v{ver}.xlsx"))
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_eosinophil_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])

2.10.2.2 increased in fail vs cure

t_cf_eosinophil_sig_sva_cp_down <- simple_cprofiler(
  t_cf_eosinophil_sig_sva_down,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_sig_sva_down_cp-v{ver}.xlsx"))
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_eosinophil_sig_sva_cp_down[["enrich_objects"]][["BP_all"]])

2.10.2.3 GSEA

t_cf_eosinophil_sig_topn_gsea <- plot_topn_gsea(t_cf_eosinophil_sig_sva_cp_up)
t_cf_eosinophil_sig_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

2.11 Monocytes cure/fail

input_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_cf_table_sva-v{ver}.xlsx")
t_cf_monocyte_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 10862    68
input_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_cf_sig_sva-v{ver}.xlsx")
t_cf_monocyte_sig_sva_up <- sig_reader(input_xlsx, "outcome")
t_cf_monocyte_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
t_cf_monocyte_sig_sva_both <- rbind.data.frame(t_cf_monocyte_sig_sva_up,
                                               t_cf_monocyte_sig_sva_down)

2.11.1 gProfiler

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…

2.11.1.1 increased in cure vs fail

t_cf_monocyte_sig_sva_up_gp <- simple_gprofiler(
  t_cf_monocyte_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_monocyte_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_monocyte_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_up_gp' not found
enrichplot::dotplot(t_cf_monocyte_sig_sva_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_monocyte_sig_sva_up_gp' not found
enrichplot::dotplot(t_cf_monocyte_sig_sva_up_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_monocyte_sig_sva_up_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_monocyte_sig_sva_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_monocyte_sig_sva_up_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "figures/overrepresentation/t_cf_monocyte_up_gp_go.svg",
   height = treeplot_height, width = treeplot_width)
## Warning in pp(file = "figures/overrepresentation/t_cf_monocyte_up_gp_go.svg", :
## The directory: figures/overrepresentation does not exist, will attempt to
## create it.
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found

2.11.1.2 increased in fail vs cure

t_cf_monocyte_sig_sva_down_gp <- simple_gprofiler(
  t_cf_monocyte_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_monocyte_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
enrichplot::dotplot(t_cf_monocyte_sig_sva_down_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_monocyte_sig_sva_down_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_monocyte_sig_sva_down_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_monocyte_sig_sva_down_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_monocyte_down_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
## Insufficient results to make a tree plot.

2.11.1.3 Both up and down

t_cf_monocyte_sig_sva_both_gp <- simple_gprofiler(
  t_cf_monocyte_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_monocyte_both_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_monocyte_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_both_gp' not found
enrichplot::dotplot(t_cf_monocyte_sig_sva_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_monocyte_sig_sva_both_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_monocyte_sig_sva_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_monocyte_sig_sva_both_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_monocyte_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
## Insufficient results for reactome

tf_termsim <- enrichplot::pairwise_termsim(t_cf_monocyte_sig_sva_both_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_monocyte_sig_sva_both_gp' not found
tf_treeplot <- sm(treeplot(tf_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'tf_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_monocyte_both_gp_tf-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
tf_treeplot
## Error in eval(expr, envir, enclos): object 'tf_treeplot' not found
dev.off()
## png 
##   2
tf_treeplot
## Error in eval(expr, envir, enclos): object 'tf_treeplot' not found

2.11.2 clusterprofiler

2.11.2.1 increased in cure vs fail

t_cf_monocyte_sig_sva_cp_up <- simple_cprofiler(
  t_cf_monocyte_sig_sva_up, de_table = t_cf_monocyte_table_sva,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_monocyte_sig_sva_up_cp-v{ver}.xlsx"))
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_monocyte_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])

2.11.2.2 increased in fail vs cure

t_cf_monocyte_sig_sva_cp_down <- simple_cprofiler(
  t_cf_monocyte_sig_sva_down,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_monocyte_sig_sva_down_cp-v{ver}.xlsx"))
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_monocyte_sig_sva_cp_down[["enrich_objects"]][["BP_all"]])

2.11.2.3 GSEA

t_cf_monocyte_sig_topn_gsea <- plot_topn_gsea(t_cf_monocyte_sig_sva_cp_up)
t_cf_monocyte_sig_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

2.12 Neutrophils cure/fail

input_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_cf_table_sva-v{ver}.xlsx")
t_cf_neutrophil_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 9101   68
input_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_cf_sig_sva-v{ver}.xlsx")
t_cf_neutrophil_sig_sva_up <- sig_reader(input_xlsx, "outcome")
t_cf_neutrophil_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
t_cf_neutrophil_sig_sva_both <- rbind.data.frame(t_cf_neutrophil_sig_sva_up,
                                               t_cf_neutrophil_sig_sva_down)

2.12.1 gProfiler

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…

2.12.1.1 increased in cure vs fail

t_cf_neutrophil_sig_sva_up_gp <- simple_gprofiler(
  t_cf_neutrophil_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_neutrophil_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_up_gp' not found
enrichplot::dotplot(t_cf_neutrophil_sig_sva_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_neutrophil_sig_sva_up_gp' not found
enrichplot::dotplot(t_cf_neutrophil_sig_sva_up_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_neutrophil_sig_sva_up_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_neutrophil_sig_sva_up_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_neutrophil_sig_sva_up_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = "figures/t_cf_neutrophil_up_gp_go.svg",
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found

2.12.1.2 increased in fail vs cure

t_cf_neutrophil_sig_sva_down_gp <- simple_gprofiler(
  t_cf_neutrophil_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_neutrophil_sig_sva_down_gp
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_down_gp' not found
## Not much to work with here.

2.12.1.3 Both up and down

t_cf_neutrophil_sig_sva_both_gp <- simple_gprofiler(
  t_cf_neutrophil_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_both_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_neutrophil_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_both_gp' not found
enrichplot::dotplot(t_cf_neutrophil_sig_sva_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_neutrophil_sig_sva_both_gp' not found
enrichplot::dotplot(t_cf_neutrophil_sig_sva_both_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_neutrophil_sig_sva_both_gp' not found
go_termsim <- enrichplot::pairwise_termsim(t_cf_neutrophil_sig_sva_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'pairwise_termsim': object 't_cf_neutrophil_sig_sva_both_gp' not found
go_treeplot <- sm(treeplot(go_termsim, label_format = wrap_width))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'treeplot': object 'go_termsim' not found
pp(file = glue("images/overrepresentation/t_cf_neutrophil_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
dev.off()
## png 
##   2
go_treeplot
## Error in eval(expr, envir, enclos): object 'go_treeplot' not found
## Insufficient results for reactome

2.12.2 clusterprofiler

2.12.2.1 increased in cure vs fail

t_cf_neutrophil_sig_sva_cp_up <- simple_cprofiler(
  t_cf_neutrophil_sig_sva_up, de_table = t_cf_neutrophil_table_sva,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_sig_sva_up_cp-v{ver}.xlsx"))
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the BP data.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_neutrophil_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])

2.12.2.2 increased in fail vs cure

t_cf_neutrophil_sig_sva_cp_down <- simple_cprofiler(
  t_cf_neutrophil_sig_sva_down,
  orgdb = "org.Hs.eg.db",
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_sig_sva_down_cp-v{ver}.xlsx"))
## Unable to find the fold-change column in the de table, not doing gsea.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Writing a sheet containing the legend.
## 
## Writing the MF data.
## 
## Writing the CC data.
## 
## Writing the KEGG data.
## 
## Finished writing excel file.
enrichplot::dotplot(t_cf_neutrophil_sig_sva_cp_down[["enrich_objects"]][["BP_all"]])

2.12.2.3 GSEA

t_cf_neutrophil_sig_topn_gsea <- plot_topn_gsea(t_cf_neutrophil_sig_sva_cp_up)
t_cf_neutrophil_sig_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

2.13 Look at visit 1 and see if anything pops out

input_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_v1_cf_table_sva-v{ver}.xlsx")
t_cf_monocyte_v1_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 10482    68
input_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_monocyte_v1_sig_sva_up <- sig_reader(input_xlsx, "outcome")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_monocyte_v1_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
t_cf_monocyte_v1_sig_sva_both <- rbind.data.frame(t_cf_monocyte_v1_sig_sva_up,
                                                  t_cf_monocyte_v1_sig_sva_down)

2.13.1 Gene Set Enrichment: 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_up_gp <- simple_gprofiler(
  t_cf_monocyte_v1_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_up_gp-v{ver}.xlsx"))
t_cf_monocyte_v1_sig_sva_up_gp
## A set of ontologies produced by gprofiler using 14
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are: 
## 0 MF
## 0 BP
## 0 KEGG
## 0 REAC
## 0 WP
## 0 TF
## 0 MIRNA
## 0 HPA
## 0 CORUM
## 0 HP hits.
t_cf_monocyte_v1_sig_sva_down_gp <- simple_gprofiler(
  t_cf_monocyte_v1_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_monocyte_v1_sig_sva_down_gp
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_down_gp' not found
t_cf_monocyte_v1_sig_sva_both_gp <- simple_gprofiler(
  t_cf_monocyte_v1_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_monocyte_v1_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_both_gp' not found

I like cats!

2.13.1.1 clusterProfiler

t_cf_monocyte_v1_sig_sva_up_cp <- simple_cprofiler(t_cf_monocyte_v1_sig_sva_up,
                                                   t_cf_monocyte_v1_table_sva,
                                                   orgdb = "org.Hs.eg.db")
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
enrichplot::dotplot(t_cf_monocyte_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])

t_cf_monocyte_v1_topn_gsea <- plot_topn_gsea(t_cf_monocyte_v1_sig_sva_up_cp)
t_cf_monocyte_v1_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

2.13.2 Neutrophils v1

input_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_v1_cf_table_sva-v{ver}.xlsx")
t_cf_neutrophil_v1_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 8717   68
input_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_neutrophil_v1_sig_sva_up <- sig_reader(input_xlsx, "outcome")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_neutrophil_v1_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_neutrophil_v1_sig_sva_both <- rbind.data.frame(t_cf_neutrophil_v1_sig_sva_up,
                                                  t_cf_neutrophil_v1_sig_sva_down)

2.13.3 Gene Set Enrichment: gProfiler Neutrophils by visit, V1

t_cf_neutrophil_v1_sig_sva_up_gp <- simple_gprofiler(
  t_cf_neutrophil_v1_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_up_gp-v{ver}.xlsx"))
## There are only, 5 returning null.
t_cf_neutrophil_v1_sig_sva_up_gp
## NULL
t_cf_neutrophil_v1_sig_sva_down_gp <- simple_gprofiler(
  t_cf_neutrophil_v1_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_down_gp-v{ver}.xlsx"))
## There are only, 8 returning null.
t_cf_neutrophil_v1_sig_sva_down_gp
## NULL
t_cf_neutrophil_v1_sig_sva_both_gp <- simple_gprofiler(
  t_cf_neutrophil_v1_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_neutrophil_down_gp-v{ver}.xlsx"))
t_cf_neutrophil_v1_sig_sva_both_gp
## A set of ontologies produced by gprofiler using 13
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are: 
## 0 MF
## 0 BP
## 0 KEGG
## 0 REAC
## 0 WP
## 0 TF
## 0 MIRNA
## 0 HPA
## 0 CORUM
## 0 HP hits.

2.13.3.1 clusterProfiler

t_cf_neutrophil_v1_sig_sva_up_cp <- simple_cprofiler(t_cf_neutrophil_v1_sig_sva_up,
                                                     t_cf_neutrophil_v1_table_sva,
                                                     orgdb = "org.Hs.eg.db")
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
## Scale for size is already present.
## Adding another scale for size, which will replace the existing scale.
enrichplot::dotplot(t_cf_neutrophil_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])

t_cf_neutrophil_v1_topn_gsea <- plot_topn_gsea(t_cf_neutrophil_v1_sig_sva_up_cp)
t_cf_neutrophil_v1_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

2.13.4 Eosinophils v1

input_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_v1_cf_table_sva-v{ver}.xlsx")
t_cf_eosinophil_v1_table_sva <- table_reader(input_xlsx, "outcome")
## [1] 9979   68
input_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_eosinophil_v1_sig_sva_up <- sig_reader(input_xlsx, "outcome")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_eosinophil_v1_sig_sva_down <- sig_reader(input_xlsx, "outcome", "down")
## There are less than 20 rows in this significance table, it is unlikely to be interesting.
t_cf_eosinophil_v1_sig_sva_both <- rbind.data.frame(t_cf_eosinophil_v1_sig_sva_up,
                                                  t_cf_eosinophil_v1_sig_sva_down)

2.13.5 Gene Set Enrichment: gProfiler Eosinophils by visit, V1

t_cf_eosinophil_v1_sig_sva_up_gp <- simple_gprofiler(
  t_cf_eosinophil_v1_sig_sva_up,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_up_gp-v{ver}.xlsx"))
t_cf_eosinophil_v1_sig_sva_up_gp
## A set of ontologies produced by gprofiler using 13
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are: 
## 0 MF
## 0 BP
## 0 KEGG
## 0 REAC
## 0 WP
## 0 TF
## 0 MIRNA
## 0 HPA
## 0 CORUM
## 0 HP hits.
t_cf_eosinophil_v1_sig_sva_down_gp <- simple_gprofiler(
  t_cf_eosinophil_v1_sig_sva_down,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_eosinophil_v1_sig_sva_down_gp
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_down_gp' not found
t_cf_eosinophil_v1_sig_sva_both_gp <- simple_gprofiler(
  t_cf_eosinophil_v1_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_eosinophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body): There's an issue with your request to g:Profiler.
## Error code: 503.
## Please double check your input. If this doesn't help, then check your internet connection or contact us with a reproducible example on biit.support@ut.ee
t_cf_eosinophil_v1_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_both_gp' not found

2.13.5.1 clusterProfiler

t_cf_eosinophil_v1_sig_sva_up_cp <- simple_cprofiler(t_cf_eosinophil_v1_sig_sva_up,
                                                     t_cf_eosinophil_v1_table_sva,
                                                     orgdb = "org.Hs.eg.db")
## preparing geneSet collections...
## GSEA analysis...
## leading edge analysis...
## done...
enrichplot::dotplot(t_cf_eosinophil_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])

t_cf_eosinophil_v1_topn_gsea <- plot_topn_gsea(t_cf_eosinophil_v1_sig_sva_up_cp)
t_cf_eosinophil_v1_topn_gsea[["GO_outcome_up"]][[1]]
## NULL

Bibliography

Ashburner, Michael, Catherine A. Ball, Judith A. Blake, David Botstein, Heather Butler, J. Michael Cherry, Allan P. Davis, et al. 2000. “Gene Ontology: Tool for the Unification of Biology.” Nature Genetics 25 (1): 25–29. https://doi.org/10.1038/75556.
Croft, David, Gavin O’Kelly, Guanming Wu, Robin Haw, Marc Gillespie, Lisa Matthews, Michael Caudy, et al. 2011. “Reactome: A Database of Reactions, Pathways and Biological Processes.” Nucleic Acids Research 39 (suppl_1): D691–97. https://doi.org/10.1093/nar/gkq1018.
Giurgiu, Madalina, Julian Reinhard, Barbara Brauner, Irmtraud Dunger-Kaltenbach, Gisela Fobo, Goar Frishman, Corinna Montrone, and Andreas Ruepp. 2019. CORUM: The Comprehensive Resource of Mammalian Protein Complexes—2019.” Nucleic Acids Research 47 (D1): D559–63. https://doi.org/10.1093/nar/gky973.
Hsu, Sheng-Da, Feng-Mao Lin, Wei-Yun Wu, Chao Liang, Wei-Chih Huang, Wen-Ling Chan, Wen-Ting Tsai, et al. 2011. miRTarBase: A Database Curates Experimentally Validated microRNA–Target Interactions.” Nucleic Acids Research 39 (suppl_1): D163–69. https://doi.org/10.1093/nar/gkq1107.
Kanehisa, Minoru, and Susumu Goto. 2000. KEGG: Kyoto Encyclopedia of Genes and Genomes.” Nucleic Acids Research 28 (1): 27–30. https://doi.org/10.1093/nar/28.1.27.
Köhler, Sebastian, Nicole A. Vasilevsky, Mark Engelstad, Erin Foster, Julie McMurry, Ségolène Aymé, Gareth Baynam, et al. 2017. “The Human Phenotype Ontology in 2017.” Nucleic Acids Research 45 (D1): D865–76. https://doi.org/10.1093/nar/gkw1039.
Kolberg, Liis, Uku Raudvere, Ivan Kuzmin, Jaak Vilo, and Hedi Peterson. 2020. “Gprofiler2 – an R Package for Gene List Functional Enrichment Analysis and Namespace Conversion Toolset g:Profiler.” F1000Research 9: ELIXIR–709. https://doi.org/10.12688/f1000research.24956.2.
Kutmon, Martina, Anders Riutta, Nuno Nunes, Kristina Hanspers, Egon L. Willighagen, Anwesha Bohler, Jonathan Mélius, et al. 2016. WikiPathways: Capturing the Full Diversity of Pathway Knowledge.” Nucleic Acids Research 44 (D1): D488–94. https://doi.org/10.1093/nar/gkv1024.
Pontén, F., J. M. Schwenk, A. Asplund, and P.-H. D. Edqvist. 2011. “The Human Protein Atlas as a Proteomic Resource for Biomarker Discovery.” Journal of Internal Medicine 270 (5): 428–46. https://doi.org/10.1111/j.1365-2796.2011.02427.x.
Wingender, E., P. Dietze, H. Karas, and R. Knüppel. 1996. TRANSFAC: A Database on Transcription Factors and Their DNA Binding Sites.” Nucleic Acids Research 24 (1): 238–41. https://doi.org/10.1093/nar/24.1.238.
Yu, Guangchuang. n.d. 📖 Introduction Biomedical Knowledge Mining Using GOSemSim and clusterProfiler. Accessed June 21, 2024.
Yu, Guangchuang, Li-Gen Wang, Yanyan Han, and Qing-Yu He. 2012. clusterProfiler: An R Package for Comparing Biological Themes Among Gene Clusters.” Omics : A Journal of Integrative Biology 16 (5): 284–87. https://doi.org/10.1089/omi.2011.0118.
LS0tCnRpdGxlOiAiVE1SQzMgRW5yaWNobWVudCBhbmFseXNlcyBvZiB0aGUgREUgcmVzdWx0czogYHIgU3lzLmdldGVudignVkVSU0lPTicpYCIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKYmlibGlvZ3JhcGh5OiBhdGIuYmliCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KYm9keSAubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTYwMHB4Owp9CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogIGZvbnQtc2l6ZTogMTZweAp9Cjwvc3R5bGU+CgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShlbnJpY2hwbG90KQpsaWJyYXJ5KGdnc3RhdHNwbG90KQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoaHBnbHRvb2xzKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCB3aWR0aCA9IDkwLCBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVycm9yID0gVFJVRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDgsIGZpZy5yZXRpbmEgPSAyLAogIG91dC53aWR0aCA9ICIxMDAlIiwgZGV2ID0gInBuZyIsCiAgZGV2LmFyZ3MgPSBsaXN0KHBuZyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzID0gNCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBrbml0ci5kdXBsaWNhdGUubGFiZWwgPSAiYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplID0gMTIpKQp2ZXIgPC0gU3lzLmdldGVudigiVkVSU0lPTiIpCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdCA9ICIlWSVtJWQiKQpgYGAKCiMgUXVpY2sgeGxzeCByZWFkZXIgZnVuY3Rpb25zCgpNeSBmdW5jdGlvbnMgdG8gcGVyZm9ybSB0aGUgdmFyaW91cyBvdmVycmVwcmVzZW50YXRpb24vZW5yaWNobWVudAphbmFseXNlcyBnZW5lcmFsbHkgYXNzdW1lIHRoZSByZXN1bHQgb2YgZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygpIGFzCnRoZSBpbnB1dC4gIFNhZGx5LCBJIGRvIG5vdCB3YW50IHRvIHNhdmUgdGhvc2UgZGF0YSBzdHJ1Y3R1cmVzIHRvIGRpc2sKYmVjYXVzZSB0aGV5IGNhbiBiZSBxdWl0ZSBtb25zdHJvdXNseSBsYXJnZSB3aGVuIHNlcmlhbGl6ZWQgKGJlY2F1c2UgSQprZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSBpbnB1dCBpbiB0aGVtIHdoaWNoIGdldHMgZGVyZWZlcmVuY2VkIG9uCnNhdmUoKSkuICBBcyBhIHJlc3VsdCwgaXQgaXMgZmFyIHNpbXBsZXIvc2FmZXIgdG8ganVzdCByZWFkIHRoZSB4bHN4Cm91dHB1dHMgcHJvZHVjZWQgYnkgY29tYmluZV9kZV90YWJsZXMgYW5kIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMuCkVyZ28gdGhlIGZvbGxvd2luZyB0d28gbGl0dGxlIGZ1bmN0aW9ucy4KCmBgYHtyfQp0YWJsZV9yZWFkZXIgPC0gZnVuY3Rpb24oeGxzeCwgc2hlZXQgPSAib3V0Y29tZSIpIHsKICBpbnB1dF9kZiA8LSBvcGVueGxzeDo6cmVhZFdvcmtib29rKHhsc3gsIHNoZWV0ID0gc2hlZXQsIHN0YXJ0Um93ID0gMikKICByb3duYW1lcyhpbnB1dF9kZikgPC0gaW5wdXRfZGZbWyJyb3cubmFtZXMiXV0KICBpbnB1dF9kZltbInJvdy5uYW1lcyJdXSA8LSBOVUxMCiAgcHJpbnQoZGltKGlucHV0X2RmKSkKICBpZiAobnJvdyhpbnB1dF9kZikgPCA1MDAwKSB7CiAgICB3YXJuaW5nKCJTb21ldGhpbmcgYXBwZWFycyB3cm9uZyB3aXRoIHRoZSBkZSB0YWJsZTogIiwgaW5wdXRfeGxzeCkKICB9CiAgcmV0dXJuKGlucHV0X2RmKQp9CgpzaWdfcmVhZGVyIDwtIGZ1bmN0aW9uKHhsc3gsIHNoZWV0ID0gIm91dGNvbWUiLCBkaXJlY3Rpb24gPSAidXAiKSB7CiAgdGhpc19zaGVldCA8LSBwYXN0ZTAoZGlyZWN0aW9uLCAiX2Rlc2VxXyIsIHNoZWV0KQogIGlucHV0X2RmIDwtIG9wZW54bHN4OjpyZWFkV29ya2Jvb2soeGxzeCwgc2hlZXQgPSB0aGlzX3NoZWV0LCBzdGFydFJvdyA9IDIpCiAgcm93bmFtZXMoaW5wdXRfZGYpIDwtIGlucHV0X2RmW1sicm93Lm5hbWVzIl1dCiAgaW5wdXRfZGZbWyJyb3cubmFtZXMiXV0gPC0gTlVMTAogIGRpbShpbnB1dF9kZikKICBpZiAobnJvdyhpbnB1dF9kZikgPCAyMCkgewogICAgbWVzc2FnZSgiVGhlcmUgYXJlIGxlc3MgdGhhbiAyMCByb3dzIGluIHRoaXMgc2lnbmlmaWNhbmNlIHRhYmxlLCBpdCBpcyB1bmxpa2VseSB0byBiZSBpbnRlcmVzdGluZy4iKQogIH0KICByZXR1cm4oaW5wdXRfZGYpCn0KYGBgCgpJIGhhdmUgYmVlbiBoYXZpbmcgc29tZSBkaWZmaWN1bHRpZXMgZ2V0dGluZyB0aGUgdHJlZXBsb3QgZm9udHMgdG8KbWF0Y2ggb3VyIHJlYWRhYmlsaXR5IGdvYWxzLiAgVGhlIHNldCBvZiB0aGluZ3MgSSBoYXZlIHRyaWVkIHNvIGZhcgphcmU6CgoxLiAgU2V0dGluZyBhIGdlb21fdGV4dChzaXplID0geCk6IHRoaXMgZmFpbGVkIGJlY2F1c2UgaXQgZGlkbid0IGtub3cKICAgIHRvIHdoaWNoIGVsZW1lbnQocykgdG8gYXBwbHkgdGhlIG5ldyBzaXplLgoyLiAgQ2hhbmdpbmcgdGhlIG9wdGlvbnMgZm9yIHRoZW1lX2J3KCk6IHRoaXMgZG9lcyBjaGFuZ2Ugc29tZSBmb250CiAgICBlbGVtZW50cywgYnV0IG5vdCB0aGUgb25lcyB0aGF0IEkgd2FudGVkLiAgSSB0cmllZCBtb3JlIHRoYW4gYQogICAgZmV3LCBtb3N0IGltcG9ydGFudGx5IHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHgpKQozLiAgQ2hhbmdpbmcgdGhlIGRlZmF1bHQgZm9yIHRoZW1lX2J3IHZpYSB0aGVtZV91cGRhdGUodGV4dCA9CiAgICBlbGVtZW50X3RleHQoc2l6ZSA9IHgpKTogdGhpcyBhbHNvIGNoYW5nZXMgc29tZSB0ZXh0LCBidXQgbm90IGFsbC4KNC4gIEludm9raW5nIHVwZGF0ZV9nZW9tX2RlZmF1bHRzKCJ0ZXh0IiwgYWVzKHNpemUgPSAxMCkpIGF0IHRoZSBzdG9wCiAgICBvZiBteSBkb2N1bWVudC4gIFRoaXMgZG9lcyBub3Qgc2VlbSB0byBkbyBtdWNoIG9mIGFueXRoaW5nLgo1LiAgUGxheWluZyB3aXRoIG9wdGlvbnMgaW4gZW5yaWNocGxvdDo6dHJlZXBsb3QoKSwgbm90YWJseSB0aGUgY2V4CiAgICBhbmQgZm9udHNpemUgb3B0aW9ucy4gIFRoZXNlIGFsc28gaGVscCB3aXRoIHNvbWUsIGJ1dCBub3QgYWxsCiAgICBmb250cy4gIEkgYWxzbyBzcGVudCBhIGZhaXIgYW1vdW50IG9mIHRpbWUgcmVhZGluZyB0aGUgY29kZSBmb3IKICAgIHRyZWVwbG90KCkgYW5kIGRlY2lkZWQgdG8gdHJ5ICM2IGJlZm9yZSBJIGdvdCB0b28gZnJ1c3RyYXRlZC4KNi4gIEp1c3QgY2hhbmdpbmcgdGhlIGNhbnZhcyBzaXplIG9mIG15IG91dHB1dCBwZGYuICBUaGlzIHdvcmtlZAogICAgZ3JlYXQsIHRob3VnaCBpdCBtYXkgcmVxdWlyZSBzZXR0aW5nIHRoZSB3b3Jkd3JhcCBvcHRpb25zIGluCiAgICB0cmVlcGxvdC4KCldpdGggdGhhdCBpbiBtaW5kLCB0aGUgZm9sbG93aW5nIHR3byBwYXJhbWV0ZXJzIGFyZSBnb2luZyB0byBzZXQgdGhlCndpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIG91dHB1dCBwZGYgZG9jdW1lbnRzIHdoaWNoIHdpbGwgYmUgc2VudCB0bwpNYXJpYSBBZGVsYWlkYSBpbiBvcmRlciB0byBhcnJhbmdlIGludG8gdGhlIGZpbmFsIGZpZ3VyZXMgdmlhCmlua3NjYXBlLgoKYGBge3J9CnRyZWVwbG90X2hlaWdodCA8LSA2CnRyZWVwbG90X3dpZHRoIDwtIDEyCndyYXBfd2lkdGggPC0gMjQKZGVzaXJlZF9nb19vbnQgPC0gIkJQIgpgYGAKCiMgSW50cm9kdWN0aW9uCgpJIG9uY2UgYWdhaW4gbW92ZWQgdGhlIG9udG9sb2d5IGFuYWx5c2VzIHRvIHRoZWlyIG93biBkb2N1bWVudC4gIFRoaXMKaXMgcHJpbWFyaWx5IGJlY2F1c2UgSSB3YW50IGEgZnJlc2ggbm90ZWJvb2sgdG8gcGxheSBhcm91bmQgd2l0aCB0aGVzZQphbmQgZ2V0IHNvbWUgb2YgdGhlIHJlc3VsdGluZyBjbHV0dGVyIG91dCBvZiB0aGUgREUgbm90ZWJvb2tzLgoKVGhlIGNvbiBvZiBkb2luZyB0aGlzIGlzIHRoYXQgc29tZSBvZiBteSBlbnJpY2htZW50IG1ldGhvZHMgYXJlIHNtYXJ0CmVub3VnaCB0byBkaXJlY3RseSB0YWtlIHRoZSBvdXRwdXQgZnJvbQpjb21iaW5lX2RlX3RhYmxlcygpL2V4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoKS4gIEkgZ3Vlc3MgSSBjYW4KZGlzcGF0Y2ggYSBtZXRob2QgdG8gdGFrZSB0aGUgeGxzeCBmaWxlIGFzIGlucHV0Li4uCgpUaHVzLCBmb3IgZWFjaCBlbnJpY2htZW50IGFuYWx5c2lzIHRoYXQgX3dhc18gaW4gdGhlIGRpZmZlcmVudGlhbApleHByZXNzaW9uIGRvY3VtZW50cywgdGhlcmUgd2lsbCBub3cgYmUgYSBmZXcgc3RhbnphcyBoZXJlLCBvbmUKd2hpY2ggbG9hZHMgdGhlIGFwcHJvcHJpYXRlIHhsc3ggZmlsZSwgb25lIHdoaWNoIHBlcmZvcm1zIGdQcm9maWxlciwKYW5kIG9uZSB3aGljaCB1c2VzIGNsdXN0ZXJQcm9maWxlci4gIE9uIG9jY2FzaW9uIHRoZXJlIG1heSBiZSBhbm90aGVyCndpdGggcmFuZG9tIHN0dWZmIGxpa2UgbWUgcG9raW5nIGF0IHRyYW5zY3JpcHRpb24gZmFjdG9ycyBvciBvdGhlcgpzaWRlIGludGVyZXN0cy4uLgoKSW4gYWRkaXRpb24sIEkgYW0gZ29pbmcgdG8gZG8gdGhlIFR1bWFjby1vbmx5IGFuYWx5c2VzIGZpcnN0LCBiZWNhdXNlCnRoZXkgYXJlIHdoYXQgYXJlIGFjdHVhbGx5IGluIHRoZSBwYXBlci4KCiMjIEdlbmUgU2V0IEVucmljaG1lbnQKClRoZSBnZW5lIHNldCBlbnJpY2htZW50IHdpbGwgZm9sbG93IGVhY2ggREUgYW5hbHlzaXMgZHVyaW5nIHRoaXMKZG9jdW1lbnQuICBJIGFtIGFkZGluZyBhIHNlcmllcyBvZiBleHBsaWNpdGx5IEdTRUEgYW5hbHlzZXMgaW4gdGhpcwptb3N0IHJlY2VudCBpdGVyYXRpb24sIGluIHRoZXNlIEkgd2lsbCBwYXNzIHRoZSBmdWxsIERFIHRhYmxlIGFuZApjaGVjayB0aGUgZGlzdHJpYnV0aW9uIG9mIGxvZ0ZDIHZhbHVlcyBhZ2FpbnN0IHRoZSBnZW5lcyBpbiBlYWNoCmNhdGVnb3J5IGFzIG9wcG9zZWQgdG8gdGhlIHNpbXBsZXIgb3Zlci1lbnJpY2htZW50IG9mIHRoZSBoaWdoL2xvdyBERQpnZW5lcy4KCk1vc3QgKGFsbD8pIG9mIHRoZSBnZW5lIHNldCBlbnJpY2htZW50IGFuYWx5c2VzIHBlcmZvcm1lZCBpbiB0aGlzCmRvY3VtZW50IGFyZSBhIGNvbWJpbmF0aW9uIG9mIGdQcm9maWxlcjIKKEBrb2xiZXJnR3Byb2ZpbGVyMlBhY2thZ2VHZW5lMjAyMCkgYW5kIGNsdXN0ZXJQcm9maWxlcgooQHl1Q2x1c3RlclByb2ZpbGVyUGFja2FnZUNvbXBhcmluZzIwMTIpLiAgVGhlcmUgYXJlIGZ1bmN0aW9ucwphdmFpbGFibGUgaW4gaHBnbHRvb2xzIHRvIGFsc28gcGVyZm9ybSBhIGZldyBvdGhlciBtZXRob2RzLCBidXQgZm9yCnRoZSBtb21lbnQgSSBhbSBzdGlja2luZyB0byBvbmx5IHRoZXNlIHR3by4gIE9oIHllYWgsIEkgbmVlZCB0byB3cmFwCmNsdXN0ZXJQcm9maWxlcidzIHRyZWUgKHRha2VuIGZyb20gdG9wR08pIHBsb3R0ZXIgYmVjYXVzZSBpdCBzcGFtcwpwbG90cyBfZXZlcnl3aGVyZV8uLi4KCmBgYHtyfQppbnB1dF94bHN4IDwtIGdsdWUoImFuYWx5c2VzLzNfY2FsaV9hbmRfdHVtYWNvL0RFX0N1cmVfRmFpbC9DbGluaWNhbF9TYW1wbGVzL3RjX2NsaW5pY2FsX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCmFsbF9kZV9jZl90YWJsZSA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQoKYWxsX2RlX2NmX3VwIDwtIHNpZ19yZWFkZXIoZ2x1ZSgiYW5hbHlzZXMvM19jYWxpX2FuZF90dW1hY28vREVfQ3VyZV9GYWlsL0NsaW5pY2FsX1NhbXBsZXMvdGNfY2xpbmljYWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpLCAib3V0Y29tZSIsICJ1cCIpCmFsbF9kZV9jZl9kb3duIDwtIHNpZ19yZWFkZXIoZ2x1ZSgiYW5hbHlzZXMvM19jYWxpX2FuZF90dW1hY28vREVfQ3VyZV9GYWlsL0NsaW5pY2FsX1NhbXBsZXMvdGNfY2xpbmljYWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpLCAib3V0Y29tZSIsICJkb3duIikKYWxsX2RlX2NmIDwtIHJiaW5kLmRhdGEuZnJhbWUoYWxsX2RlX2NmX3VwLCBhbGxfZGVfY2ZfZG93bikKCnR1bWFjb194bHN4IDwtIGdsdWUoImFuYWx5c2VzLzRfdHVtYWNvL0RFX0N1cmVfRmFpbC90X2FsbF92aXNpdGNmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKQp0X2RlX2NmIDwtIG9wZW54bHN4OjpyZWFkV29ya2Jvb2sodHVtYWNvX3hsc3gsIHNoZWV0ID0gMywgc3RhcnRSb3cgPSAyKQpyb3duYW1lcyh0X2RlX2NmKSA8LSB0X2RlX2NmW1sicm93Lm5hbWVzIl1dCnRfZGVfY2ZbWyJyb3cubmFtZXMiXV0gPC0gTlVMTAp0X2RlX2NmX3VwIDwtIHRfZGVfY2ZbLCBjKCJkZXNlcV9sb2dmYyIsICJkZXNlcV9hZGpwIiwgImRlc2VxX2Jhc2VtZWFuIiwgImRlc2VxX2xmY3NlIildCnRfZGVfY2YgPC0gb3Blbnhsc3g6OnJlYWRXb3JrYm9vayh0dW1hY29feGxzeCwgc2hlZXQgPSA0LCBzdGFydFJvdyA9IDIpCnJvd25hbWVzKHRfZGVfY2YpIDwtIHRfZGVfY2ZbWyJyb3cubmFtZXMiXV0KdF9kZV9jZltbInJvdy5uYW1lcyJdXSA8LSBOVUxMCnRfZGVfY2ZfZG93biA8LSB0X2RlX2NmWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIsICJkZXNlcV9iYXNlbWVhbiIsICJkZXNlcV9sZmNzZSIpXQp0X2RlX2NmIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9kZV9jZl91cCwgdF9kZV9jZl9kb3duKQpgYGAKCiMjIGdQcm9maWxlciBzZWFyY2ggb2YgYWxsIFR1bWFjbyBzYW1wbGVzCgpUaGUgZm9sbG93aW5nIGdQcm9maWxlciBzZWFyY2hlcyB1c2UgdGhlIGFsbF9ncHJvZmlsZXIoKSBmdW5jdGlvbgppbnN0ZWFkIG9mIHNpbXBsZV9ncHJvZmlsZXIoKS4gIEFzIGEgcmVzdWx0LCB0aGUgcmVzdWx0cyBhcmUgc2VwYXJhdGVkCmJ5IHtjb250cmFzdH1fe2RpcmVjdGlvbn0uICBUaHVzICdvdXRjb21lX2Rvd24nLgoKVGhlIHNhbWUgcGxvdHMgYXJlIGF2YWlsYWJsZSBhcyB0aGUgcHJldmlvdXMgZ1Byb2ZpbGVyIHNlYXJjaGVzLCBidXQKaW4gbWFueSBvZiB0aGUgZm9sbG93aW5nIHJ1bnMsIEkgdXNlZCB0aGUgZG90cGxvdCgpIGZ1bmN0aW9uIHRvIGdldCBhCnNsaWdodGx5IGRpZmZlcmVudCB2aWV3IG9mIHRoZSByZXN1bHRzLgoKIyMgU2hhcmVkIHBhdGhzCgpUaGVzZSBhcmUgdGhlIHBhdGhzIGZyb20gdGhlIERFIGRvY3VtZW50IGFuZCB3aGljaCB3aWxsIGJlIHVzZWQgdG8gZ2V0CnRoZSBpbnB1dHMgZm9yIGdwcm9maWxlci9jbHVzdGVycHJvZmlsZXIuCgpgYGB7cn0KeGxzeF9wcmVmaXggPC0gImFuYWx5c2VzLzRfdHVtYWNvIgpjZl9wcmVmaXggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9DdXJlX0ZhaWwiKQpgYGAKCiMjIEFsbCBUdW1hY28gY2xpbmljYWwgc2FtcGxlcyBjdXJlL2ZhaWwKClRoZSB4bHN4IGZpbGVzIGFyZToKCiogIntjZl9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IgoqICJ7Y2ZfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giCgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2xpbmljYWxfY2ZfdGFibGVfc3ZhIDwtIHRhYmxlX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIpCgppbnB1dF94bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2xpbmljYWxfY2Zfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIikKdF9jbGluaWNhbF9jZl9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIsICJkb3duIikKYGBgCgpBbmQgd2l0aG91dCBiaW9wc2llcwoKYGBge3J9CmlucHV0X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vQWxsX1NhbXBsZXMvdF9jbGluaWNhbF9ub2Jpb3BfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jbGluaWNhbG5iX2NmX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQoKaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX25vYmlvcF9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfdXAgPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIpCnRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIsICJkb3duIikKdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfYm90aCA8LSByYmluZC5kYXRhLmZyYW1lKHRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfZG93bikKYGBgCgojIyMgZ1Byb2ZpbGVyCgpBZnRlciBtb3N0IG9mIHRoZSBERSBhbmFseXNlcywgdGhlIHNldCBvZiBzaWduaWZpY2FudGx5IERFIGdlbmVzIGdldHMKcGFzc2VkIHRvIGdQcm9maWxlcjIgYW5kIGNsdXN0ZXJQcm9maWxlci4gIE9uZSBzbGlnaHRseSBuZWF0IHRoaW5nIGluCm15IGdwcm9maWxlciAoYW5kIGdvc2VxL3RvcEdPL2dvc3RhdHMpIGZ1bmN0aW9uKHMpOiBpdCBjb2VyY2VzIHRoZQpyZXN1bHQgaW50byB0aGUgc2FtZSBkYXRhc3RydWN0dXJlIHByb2R1Y2VkIGJ5IGNsdXN0ZXJQcm9maWxlciwgdGh1cwpvbmUgbWF5IHBsYXkgd2l0aCB0aGUgdmFyaW91cyBwbG90dGluZyBmdW5jdGlvbnMgaW4gdGhlIGVucmljaHBsb3QKKEB5dUludHJvZHVjdGlvbkJpb21lZGljYWxLbm93bGVkZ2UpIHBhY2thZ2UuICBUaGlzIGlzIGtpbmQgb2YgZnVuCmJlY2F1c2UgZ1Byb2ZpbGVyMiBwcm92aWRlcyBlYXN5IGFjY2VzcyB0byBhIGZldyBkYXRhc2V0czoKCjEuIEdPOiAoQGFzaGJ1cm5lckdlbmVPbnRvbG9neVRvb2wyMDAwYSkKMi4gS0VHRzogKEBrYW5laGlzYUtFR0dLeW90b0VuY3ljbG9wZWRpYTIwMDApCjMuIFJlYWN0b21lOiAoQGNyb2Z0UmVhY3RvbWVEYXRhYmFzZVJlYWN0aW9uczIwMTEpCjQuIFdpa2lQYXRod2F5czogKEBrdXRtb25XaWtpUGF0aHdheXNDYXB0dXJpbmdGdWxsMjAxNikKNS4gVHJhbnNmYWM6IChAd2luZ2VuZGVyVFJBTlNGQUNEYXRhYmFzZVRyYW5zY3JpcHRpb24xOTk2KQo2LiBtaVJUYXJCYXNlOiAoQGhzdU1pUlRhckJhc2VEYXRhYmFzZUN1cmF0ZXMyMDExKQo3LiBUaGUgSHVtYW4gUHJvdGVpbiBBdGxhczogKEBwb250ZW5IdW1hblByb3RlaW5BdGxhczIwMTEpCjguIENvcnVtOiAoQGdpdXJnaXVDT1JVTUNvbXByZWhlbnNpdmVSZXNvdXJjZTIwMTkpCjkuIEh1bWFuIHBoZW5vdHlwZSBvbnRvbG9neTogKEBrb2hsZXJIdW1hblBoZW5vdHlwZU9udG9sb2d5MjAxNykKCiMjIyMgR2VuZXMgaGlnaGVyIGluIGN1cmUKCk15IGdlbmVyYWwgc2Vuc2UgaXMgdGhhdCB0aGUgY29tcGFyaXNvbnMgb2YgcHJpbWFyeSBpbnRlcmVzdCBhcmUKcmVhY3RvbWUgYW5kIG9uZSBvciBtb3JlIEdPLiAgSSBzdXNwZWN0IHRoYXQgaWYgdGhlcmUgYXJlIGxvdHMgb2YKdHJhbnNjcmlwdGlvbiBmYWN0b3JzLCB0aGF0IG1pZ2h0IHByb3ZlIGludGVyZXN0aW5nLgoKYGBge3J9CnRfY2ZfY2xpbmljYWxfZ3BfdXAgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NsaW5pY2FsX2NmX3NpZ19zdmFfdXAsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X092ZXJyZXByZXNlbnRhdGlvbi9jbGluaWNhbF9jdXJlX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfY2xpbmljYWxfZ3BfdXAKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsX2dwX3VwW1siQlBfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsX2dwX2dvX3VwX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QoZ29fdGVybXNpbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbF9ncF91cF90cmVlLnBkZiIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKdF9jZl9jbGluaWNhbF9ncF9nb191cF90cmVlCmRldi5vZmYoKQp0X2NmX2NsaW5pY2FsX2dwX2dvX3VwX3RyZWUKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwX3VwW1siQlBfZW5yaWNoIl1dKQoKcmVhY3RvbWVfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxfZ3BfdXBbWyJSRUFDX2VucmljaCJdXSkKdF9jZl9jbGluaWNhbF9ncF9yZWFjX3VwX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QocmVhY3RvbWVfdGVybXNpbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSAiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2NsaW5pY2FsX2dwX3VwX3RyZWUucGRmIiwKICAgd2lkdGggPSB0cmVlcGxvdF93aWR0aCwgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0KQp0X2NmX2NsaW5pY2FsX2dwX3JlYWNfdXBfdHJlZQpkZXYub2ZmKCkKdF9jZl9jbGluaWNhbF9ncF9yZWFjX3VwX3RyZWUKcHAoZmlsZSA9ICJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfY2xpbmljYWxfZ3BfdXBfZG90LnBkZiIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwX3VwW1siUkVBQ19lbnJpY2giXV0pCmRldi5vZmYoKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfZ3BfdXBbWyJSRUFDX2VucmljaCJdXSkKCnRmX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsX2dwX3VwW1siVEZfZW5yaWNoIl1dKQojIyBUaGUgdHJlZXBsb3QgZmFpbHMgZm9yIHRoaXMgZm9yIHNvbWUgcmVhc29uPwojI3RfY2ZfY2xpbmljYWxfZ3BfdGZfdXBfdHJlZSA8LSBzbShlbnJpY2hwbG90Ojp0cmVlcGxvdCh0Zl90ZXJtc2ltKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwX3VwW1siVEZfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfZ3BfdXBbWyJXUF9lbnJpY2giXV0pCmBgYAoKTm8gYmlvcHNpZXMhCgpgYGB7cn0KdF9jZl9jbGluaWNhbG5iX2dwX3VwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfdXAsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X092ZXJyZXByZXNlbnRhdGlvbi9jbGluaWNhbG5iX2N1cmVfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9jbGluaWNhbG5iX2dwX3VwCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9jbGluaWNhbG5iX2dwX3VwW1siQlBfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fdXBfdHJlZSA8LSBzbShlbnJpY2hwbG90Ojp0cmVlcGxvdChnb190ZXJtc2ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9ICJmaWd1cmVzL3RfY2ZfY2xpbmljYWxuYl9ncF91cF90cmVlLnN2ZyIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKdF9jZl9jbGluaWNhbG5iX2dwX2dvX3VwX3RyZWUKZGV2Lm9mZigpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb191cF90cmVlCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbG5iX2dwX3VwW1siQlBfZW5yaWNoIl1dKQoKcmVhY3RvbWVfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxuYl9ncF91cFtbIlJFQUNfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsbmJfZ3BfcmVhY191cF90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KHJlYWN0b21lX3Rlcm1zaW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSAiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2NsaW5pY2FsbmJfZ3BfdXBfdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxuYl9ncF9yZWFjX3VwX3RyZWUKZGV2Lm9mZigpCnRfY2ZfY2xpbmljYWxuYl9ncF9yZWFjX3VwX3RyZWUKcHAoZmlsZSA9ICJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfY2xpbmljYWxuYl9ncF91cF9kb3QucGRmIiwKICAgd2lkdGggPSB0cmVlcGxvdF93aWR0aCwgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0KQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxuYl9ncF91cFtbIlJFQUNfZW5yaWNoIl1dKQpkZXYub2ZmKCkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsbmJfZ3BfdXBbWyJSRUFDX2VucmljaCJdXSkKCnRmX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsbmJfZ3BfdXBbWyJURl9lbnJpY2giXV0pCiMjIFRoZSB0cmVlcGxvdCBmYWlscyBmb3IgdGhpcyBmb3Igc29tZSByZWFzb24/CiMjdF9jZl9jbGluaWNhbG5iX2dwX3RmX3VwX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QodGZfdGVybXNpbSkpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbG5iX2dwX3VwW1siVEZfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxuYl9ncF91cFtbIldQX2VucmljaCJdXSkKYGBgCgojIyMjIEdlbmVzIGhpZ2hlciBpbiBmYWlsCgpUaGUgb25seSBzaWduaWZpY2FudCByZXN1bHRzIGZvciB0aGlzIGdyb3VwIGFwcGVhciB0byBiZSBHTy4KCmBgYHtyfQp0X2NmX2NsaW5pY2FsX2dwX2Rvd24gPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NsaW5pY2FsX2NmX3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfT3ZlcnJlcHJlc2VudGF0aW9uL2NsaW5pY2FsX2ZhaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9jbGluaWNhbF9ncF9kb3duCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9jbGluaWNhbF9ncF9kb3duW1siQlBfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsX2dwX2dvX2Rvd25fdHJlZSA8LSBzbShlbnJpY2hwbG90Ojp0cmVlcGxvdChnb190ZXJtc2ltKSkKcHAoZmlsZSA9ICJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfY2xpbmljYWxfZ3BfZG93bl90cmVlLnBkZiIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKdF9jZl9jbGluaWNhbF9ncF9nb19kb3duX3RyZWUKZGV2Lm9mZigpCmBgYAoKTm8gYmlvcHNpZXMhCgoKYGBge3J9CnRfY2ZfY2xpbmljYWxuYl9ncF9kb3duIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfT3ZlcnJlcHJlc2VudGF0aW9uL2NsaW5pY2FsbmJfZmFpbF91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZG93bgoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxuYl9ncF9kb3duW1siQlBfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fZG93bl90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KGdvX3Rlcm1zaW0pKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbG5iX2dwX2Rvd25fdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb19kb3duX3RyZWUKZGV2Lm9mZigpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb19kb3duX3RyZWUKCiMjIEFuZCBib3RoLCB0aGlzIGlzIG5vdCB1c3VhbGx5IHdoZXJlIEkgcHV0IHRoaXMsIGJ1dCB0aGUKIyMgY2xpbmljYWwgc2FtcGxlcyBhcmUgYSBiaXQgb2YgYSBzcGVjaWFsIGNhc2UuCnRfY2ZfY2xpbmljYWxuYl9ncF9ib3RoIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfYm90aCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfT3ZlcnJlcHJlc2VudGF0aW9uL2NsaW5pY2FsbmJfZmFpbF91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2NsaW5pY2FsbmJfZ3BfYm90aAoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxuYl9ncF9ib3RoW1siQlBfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fYm90aF90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KGdvX3Rlcm1zaW0pKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbG5iX2dwX2JvdGhfdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb19ib3RoX3RyZWUKZGV2Lm9mZigpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb19ib3RoX3RyZWUKCnJlYWNfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxuYl9ncF9ib3RoW1siUkVBQ19lbnJpY2giXV0pCnRfY2ZfY2xpbmljYWxuYl9ncF9yZWFjX2JvdGhfdHJlZSA8LSBzbShlbnJpY2hwbG90Ojp0cmVlcGxvdChyZWFjX3Rlcm1zaW0pKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbG5iX2dwX2JvdGhfcmVhY190cmVlLnBkZiIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKdF9jZl9jbGluaWNhbG5iX2dwX3JlYWNfYm90aF90cmVlCmRldi5vZmYoKQp0X2NmX2NsaW5pY2FsbmJfZ3BfcmVhY19ib3RoX3RyZWUKYGBgCgojIyMgY2x1c3RlclByb2ZpbGVyCgpUaGUgZm9sbG93aW5nIGVzc2VudGlhbGx5IHJlcGVhdHMgdGhlIGdQcm9maWxlcjIgaW52b2NhdGlvbiB1c2luZwpjbHVzdGVyUHJvZmlsZXIuICBJIGhhdmUgYSBjb3VwbGUgb2YgZnVuY3Rpb25zIHdoaWNoIGNvbXBhcmUgdGhlIEdPCnJlc3VsdHMgZnJvbSB2YXJpb3VzIG1ldGhvZHMsIHBlcmhhcHMgSSBzaG91bGQgZGlnIGl0IG91dCBhbmQgc2VlIGhvdwpzaW1pbGFyIHRoZSByZXN1bHRzIGFyZSB1c2luZyB0aGVzZSB0d28gdG9vbHMuICBNeSBhc3N1bXB0aW9uIGlzIHRoYXQKdGhlIHByaW1hcnkgZGlmZmVyZW5jZXMgc2hvdWxkIGFyaXNlIGZyb20gdGhlIGZhY3QgdGhhdCBnUHJvZmlsZXIKdGhlb3JldGljYWxseSBpcyB1cGRhdGluZyB0aGVpciBHTyBkYXRhIG92ZXIgdGltZSBhbmQgY1Byb2ZpbGVyIHVzZXMKdGhlIGluZm9ybWF0aW9uIGluIG9yZy5Icy5lZy5kYiwgd2hpY2ggYWZhaWsgaGFzIG5vdCBjaGFuZ2VkIGluIHF1aXRlCmEgd2hpbGUuCgojIyMjIEdlbmVzIGhpZ2hlciBpbiBjdXJlCgpgYGB7cn0KdF9jZl9jbGluaWNhbF9jcF91cCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIHRfY2xpbmljYWxfY2Zfc2lnX3N2YV91cCwgZGVfdGFibGUgPSB0X2NsaW5pY2FsX2NmX3RhYmxlX3N2YSwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfT3ZlcnJlcHJlc2VudGF0aW9uL2NsaW5pY2FsX2N1cmVfdXBfY3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2NwX3VwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHZW5lcyBoaWdoZXIgaW4gZmFpbAoKYGBge3J9CnRfY2ZfY2xpbmljYWxfY3BfZG93biA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIHRfY2xpbmljYWxfY2Zfc2lnX3N2YV9kb3duLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9PdmVycmVwcmVzZW50YXRpb24vY2xpbmljYWxfZmFpbF91cF9jcC12e3Zlcn0ueGxzeCIpKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfY3BfZG93bltbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR1NFQQoKR1NFQSBpcyBub3QgYXNzb2NpYXRlZCB3aXRoIGVpdGhlciB1cCBub3IgZG93biwgaXQgdGFrZXMgdGhlIHJhbmsKb3JkZXIgb2YgZ2VuZXMgd2l0aCByZXNwZWN0IChpbiB0aGlzIGNhc2UpIHRvIGZvbGQtY2hhbmdlLgoKYGBge3J9CnRfY2ZfY2xpbmljYWxfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfY2xpbmljYWxfY3BfdXApCnRfY2ZfY2xpbmljYWxfdG9wbl9nc2VhW1siR08iXV1bWzFdXQp0X2NmX2NsaW5pY2FsX3RvcG5fZ3NlYVtbIkdPIl1dW1syXV0KdF9jZl9jbGluaWNhbF90b3BuX2dzZWFbWyJHTyJdXVtbM11dCnRfY2ZfY2xpbmljYWxfdG9wbl9nc2VhW1siR08iXV1bWzRdXQp0X2NmX2NsaW5pY2FsX3RvcG5fZ3NlYVtbIkdPIl1dW1s1XV0KYGBgCgojIyBWaXNpdCAxIHZzLiBvdGhlciB2aXNpdHMKClRoZSByZWxldmFudCB4bHN4IGZpbGVzIGFyZToKCiogInt4bHN4X3ByZWZpeH0vREVfVmlzaXRzL3R2MV92c19sYXRlcl90YWJsZXMtdnt2ZXJ9Lnhsc3giCiogInt4bHN4X3ByZWZpeH0vREVfVmlzaXRzL3R2MV92c19sYXRlcl9zaWctdnt2ZXJ9Lnhsc3giCgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0RFX1Zpc2l0cy90djFfdnNfbGF0ZXJfdGFibGVzLXZ7dmVyfS54bHN4IikKdHYxX3ZzX2xhdGVyX3RhYmxlIDwtIHRhYmxlX3JlYWRlcihpbnB1dF94bHN4LCAibGF0ZXJfdnNfZmlyc3QiKQoKaW5wdXRfeGxzeCA8LSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0RFX1Zpc2l0cy90djFfdnNfbGF0ZXJfc2lnLXZ7dmVyfS54bHN4IikKdHYxX3ZzX2xhdGVyX3VwX3NpZyA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJsYXRlcl92c19maXJzdCIpCnR2MV92c19sYXRlcl9kb3duX3NpZyA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJsYXRlcl92c19maXJzdCIsICJkb3duIikKYGBgCgojIyMgSW5jcmVhc2VkIGluIHZpc2l0IDEKCkkgYW0gbm90IGxpa2VseSB0byBkbyB0aGUgZGVjcmVhc2VkIGluIHZpc2l0IDEsIHRoZXJlIGFyZSBvbmx5IDcgZ2VuZXMuCgojIyMjIGVucmljaG1lbnQ6IGdQcm9maWxlcgoKYGBge3J9CnR2MWxhdGVyX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdHYxX3ZzX2xhdGVyX3VwX3NpZywKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90djFfdnNfbGF0ZXJfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdHYxbGF0ZXJfdXBfZ3AKCmVucmljaHBsb3Q6OmRvdHBsb3QodHYxbGF0ZXJfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodHYxbGF0ZXJfdXBfZ3BbWyJSRUFDX2VucmljaCJdXSkKYGBgCgojIyMjIGVucmljaG1lbnQ6IGNsdXN0ZXJQcm9maWxlcgoKTm90ZSB0byBzZWxmOiBtYWtlIHNvbWUgY2xhc3NlcyBmb3IgcGxvdF90b3BuX2dzZWEgc28gaXQgY2FuIGhhbmRsZQp0aGUgdmFyaW91cyBpbnB1dHMgaXQgaXMgbGlrZWx5IHRvIHJlY2VpdmUuCgpgYGB7cn0KdHYxbGF0ZXJfdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0djFfdnNfbGF0ZXJfdXBfc2lnLCBkZV90YWJsZSA9IHR2MV92c19sYXRlcl90YWJsZSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLCBrZWdnX3ByZWZpeCA9ICJocyIsIGRvX2tlZ2cgPSBUUlVFKQplbnJpY2hwbG90Ojpkb3RwbG90KHR2MWxhdGVyX3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJNRl9hbGwiXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodHYxbGF0ZXJfdXBfY3BbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKCndyaXR0ZW4gPC0gd3JpdGVfY3BfZGF0YSgKICB0djFsYXRlcl91cF9jcCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90djFfdnNfbGF0ZXJfdXBfY3Atdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEdTRUE6IGNsdXN0ZXJQcm9maWxlcgoKYGBge3J9CnR2MWxhdGVyX3RvcG5fZ3NlYSA8LSBwbG90X3RvcG5fZ3NlYSh0djFsYXRlcl91cF9jcCkKdHYxbGF0ZXJfdG9wbl9nc2VhW1siR08iXV1bWzFdXQp0djFsYXRlcl90b3BuX2dzZWFbWyJHTyJdXVtbMl1dCmBgYAoKIyMgUGF0aWVudCBTZXgKClRoZSByZWxldmFudCBpbnB1dCB4bHN4IGZpbGVzIGFyZToKCioge3hsc3hfcHJlZml4fS9ERV9TZXgvdF9zZXhfdGFibGUtdnt2ZXJ9Lnhsc3giKSkKKiB7eGxzeF9wcmVmaXh9L0RFX1NleC90X3NleF9zaWctdnt2ZXJ9Lnhsc3giKSkKCk9oLCBJIG1lc3NlZCB1cCBhbmQgcHV0IHRoZSBERSByZXN1bHRzIGluIHRoZSBHU0VBIGRpcmVjdG9yeSEKCkxldCB1cyBzZWUgaWYgd2Ugb2JzZXJ2ZSBnZW5lcmFsIG1hbGUvZmVtYWxlIGRpZmZlcmVuY2VzIGluIHRoZSBkYXRhLgpUaGlzIGhhcyBhbiBpbXBvcnRhbnQgY2F2ZWF0OiB0aGVyZSBhcmUgZmV3IGZlbWFsZSBmYWlsdXJlcyBpbiB0aGUKZGF0YXNldCBhbmQgc28gdGhlIHJlc3VsdHMgbWF5IHJlZmxlY3QgdGhhdC4KCmBgYHtyfQppbnB1dF94bHN4IDwtIGdsdWUoInt4bHN4X3ByZWZpeH0vREVfU2V4L3Rfc2V4X2N1cmVfdGFibGUtdnt2ZXJ9Lnhsc3giKQp0X3NleF90YWJsZSA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm1hbGVfdnNfZmVtYWxlIikKCmlucHV0X3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9TZXgvdF9zZXhfY3VyZV9zaWctdnt2ZXJ9Lnhsc3giKQp0X3NleF91cF9zaWcgPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAibWFsZV92c19mZW1hbGUiKQp0X3NleF9kb3duX3NpZyA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJtYWxlX3ZzX2ZlbWFsZSIsICJkb3duIikKYGBgCgojIyMgZ1Byb2ZpbGVyCgojIyMjIEluY3JlYXNlZCBpbiBtZW4KCmBgYHtyfQp0X3NleF91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfc2V4X3VwX3NpZywKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9zZXhfbWFsZV91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X3NleF91cF9ncAoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X3NleF91cF9ncFtbIkJQX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X3NleF91cF9ncFtbIlJFQUNfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfc2V4X3VwX2dwW1siVEZfZW5yaWNoIl1dKQpgYGAKCiMjIyMgSW5jcmVhc2VkIGluIHdvbWVuCgpgYGB7cn0KdF9zZXhfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfc2V4X2Rvd25fc2lnLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3NleF9mZW1hbGVfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9zZXhfZG93bl9ncApgYGAKCkdpdmVuIHRoZSByZXN1bHRzIGZyb20gZ1Byb2ZpbGVyLCBJIGRvIG5vdCBoYXZlIGhpZ2ggZXhwZWN0YXRpb25zIGZvcgpjbHVzdGVyUHJvZmlsZXIsIHNvIEkgYW0gbm90IGxpa2VseSB0byB0YWtlIHRoZSB0aW1lIHRvIHdyaXRlIHRoZW0gb3V0LgpJdCBzZWVtcyBsaWtlIG1hbGUvZmVtYWxlIGlzIGNvbmZvdW5kZWQgd2l0aCBjdXJlL2ZhaWwuCgojIyMgY2x1c3RlclByb2ZpbGVyCgojIyMjIEluY3JlYXNlZCBpbiBtZW4KCmBgYHtyfQp0X3NleF91cF9jcCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIHRfc2V4X3VwX3NpZywgZGVfdGFibGUgPSB0X3NleF90YWJsZSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLCBrZWdnX3ByZWZpeCA9ICJocyIsIGRvX2tlZ2cgPSBUUlVFKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfc2V4X3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gd29tZW4KCmBgYHtyfQp0X3NleF9kb3duX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9zZXhfZG93bl9zaWcsIGRlX3RhYmxlID0gdF9zZXhfdGFibGUsCiAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIiwga2VnZ19wcmVmaXggPSAiaHMiLCBkb19rZWdnID0gVFJVRSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X3NleF9kb3duX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHU0VBCgpgYGB7cn0KdF9zZXhfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfc2V4X3VwX2NwKQp0X3NleF90b3BuX2dzZWFbWyJHTyJdXVtbMV1dCmBgYAoKIyMgRXRobmljaXR5CgpPbmNlIGFnYWluLCB0aGUgcmVsZXZhbnQgZmlsZXMgdG8gbG9hZDoKCiogInt4bHN4X3ByZWZpeH0vREVfRXRobmljaXR5L3RfZXRobmljaXR5X3RhYmxlLXZ7dmVyfS54bHN4IgoqICJ7eGxzeF9wcmVmaXh9L0RFX0V0aG5pY2l0eS90X2V0aG5pY2l0eV9zaWctdnt2ZXJ9Lnhsc3giCgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0RFX0V0aG5pY2l0eS90X2V0aG5pY2l0eV90YWJsZS12e3Zlcn0ueGxzeCIpCnRfZXRobmljaXR5X21lc3Rpem9faW5kaWdlbm91cyA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm1lc3Rpem9faW5kaWdlbm91cyIpCnRfZXRobmljaXR5X21lc3Rpem9fYWZyb2NvbCA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm1lc3Rpem9fYWZyb2NvbCIpCnRfZXRobmljaXR5X2luZGlnZW5vdXNfYWZyb2NvbCA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgImluZGlnZW5vdXNfYWZyb2NvbCIpCgppbnB1dF94bHN4IDwtIGdsdWUoInt4bHN4X3ByZWZpeH0vREVfRXRobmljaXR5L3RfZXRobmljaXR5X3NpZy12e3Zlcn0ueGxzeCIpCnRfZXRobmljaXR5X21lc3Rpem9faW5kaWdlbm91c191cCA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJtZXN0aXpvX2luZGlnZW5vdXMiKQp0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXNfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJtZXN0aXpvX2luZGlnZW5vdXMiLCAiZG93biIpCnRfZXRobmljaXR5X21lc3Rpem9fYWZyb2NvbF91cCA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJtZXN0aXpvX2Fmcm9jb2wiKQp0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJtZXN0aXpvX2Fmcm9jb2wiLCAiZG93biIpCnRfZXRobmljaXR5X2luZGlnZW5vdXNfYWZyb2NvbF91cCA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJpbmRpZ2Vub3VzX2Fmcm9jb2wiKQp0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2xfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJpbmRpZ2Vub3VzX2Fmcm9jb2wiLCAiZG93biIpCmBgYAoKIyMjIGdQcm9maWxlcgoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBpbmRpZ2Vub3VzCgpgYGB7cn0KbWVzdGl6b19pbmRpZ2Vub3VzX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L2V0aG5pY2l0eV9taV91cF9ncC12e3Zlcn0ueGxzeCIpKQptZXN0aXpvX2luZGlnZW5vdXNfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBpbmRpZ2Vub3VzIHZzIG1lc3Rpem8KCmBgYHtyfQppbmRpZ2Vub3VzX21lc3Rpem9fdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXNfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9ldGhuaWNpdHlfaW1fdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKaW5kaWdlbm91c19tZXN0aXpvX3VwX2dwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KbWVzdGl6b19hZnJvY29sX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19hZnJvY29sX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L2V0aG5pY2l0eV9tYV91cF9ncC12e3Zlcn0ueGxzeCIpKQptZXN0aXpvX2Fmcm9jb2xfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIG1lc3Rpem8KCmBgYHtyfQphZnJvY29sX21lc3Rpem9fdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9ldGhuaWNpdHlfYW1fdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKYWZyb2NvbF9tZXN0aXpvX3VwX2dwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gaW5kaWdlbm91cyB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KaW5kaWdlbm91c19hZnJvY29sX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L2V0aG5pY2l0eV9pYV91cF9ncC12e3Zlcn0ueGxzeCIpKQppbmRpZ2Vub3VzX2Fmcm9jb2xfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIGluZGlnZW5vdXMKCmBgYHtyfQphZnJvY29sX2luZGlnZW5vdXNfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2xfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9ldGhuaWNpdHlfYWlfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKYWZyb2NvbF9pbmRpZ2Vub3VzX3VwX2dwCmBgYAoKIyMjIGNsdXN0ZXJQcm9maWxlcgoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBpbmRpZ2Vub3VzCgpgYGB7cn0KbWVzdGl6b19pbmRpZ2Vub3VzX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzX3VwLAogIGRlX3RhYmxlID0gdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzKQptZXN0aXpvX2luZGlnZW5vdXNfdXBfY3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBpbmRpZ2Vub3VzIHZzIG1lc3Rpem8KCmBgYHtyfQppbmRpZ2Vub3VzX21lc3Rpem9fdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXNfZG93bikKaW5kaWdlbm91c19tZXN0aXpvX3VwX2NwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KbWVzdGl6b19hZnJvY29sX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19hZnJvY29sX3VwLAogIGRlX3RhYmxlID0gdF9ldGhuaWNpdHlfbWVzdGl6b19hZnJvY29sKQptZXN0aXpvX2Fmcm9jb2xfdXBfY3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIG1lc3Rpem8KCmBgYHtyfQphZnJvY29sX21lc3Rpem9fdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfZG93bikKYWZyb2NvbF9tZXN0aXpvX3VwX2NwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gaW5kaWdlbm91cyB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KaW5kaWdlbm91c19hZnJvY29sX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sX3VwLAogIGRlX3RhYmxlID0gdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sKQppbmRpZ2Vub3VzX2Fmcm9jb2xfdXBfY3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIGluZGlnZW5vdXMKCmBgYHtyfQphZnJvY29sX2luZGlnZW5vdXNfdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2xfZG93bikKYWZyb2NvbF9pbmRpZ2Vub3VzX3VwX2NwCmBgYAoKIyMgVmlzaXQgMSBjdXJlL2ZhaWwKCkl0IGxvb2tzIGxpa2UgdGhlcmUgYXJlIHZlcnkgZmV3IGdyb3VwcyBpbiB0aGUgdmlzaXQgMSBzaWduaWZpY2FudApnZW5lcy4KClRoZSByZWxldmFudCB4bHN4IGZpbGVzIGFyZToKCiogIntjZl9wcmVmaXh9L1Zpc2l0cy90X2NsaW5pY2FsX3YxX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIKKiAie2NmX3ByZWZpeH0vVmlzaXRzL3RfY2xpbmljYWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIKCmBgYHtyfQppbnB1dF94bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L1Zpc2l0cy90X2NsaW5pY2FsX3YxX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfY2xpbmljYWxfdjFfdGFibGVfc3ZhIDwtIHRhYmxlX3JlYWRlcihpbnB1dF94bHN4KQoKaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9WaXNpdHMvdF9jbGluaWNhbF92MV9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIiwgImRvd24iKQpgYGAKCiMjIyBnUHJvZmlsZXIKCiMjIyMgSW5jcmVhc2VkIGluIHZpc2l0IDEgY3VyZS9mYWlsCgpgYGB7cn0KdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIodF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwKQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiB2aXNpdCAxIGZhaWwvY3VyZQoKYGBge3J9CnRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIodF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd24pCnRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9kb3duX2dwCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd25fZ3BbWyJCUF9lbnJpY2giXV0pCmBgYAoKIyMjIGNsdXN0ZXJQcm9maWxlcgoKIyMjIyBJbmNyZWFzZWQgdmlzaXQgMSBjdXJlL2ZhaWwKCmBgYHtyfQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXBfY3AgPC0gc2ltcGxlX2Nwcm9maWxlcigKICB0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXAsCiAgZGVfdGFibGUgPSB0X2NmX2NsaW5pY2FsX3YxX3RhYmxlX3N2YSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiKQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXBfY3AKCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gdmlzaXQgMSBjdXJlL2ZhaWwKCmBgYHtyfQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfZG93bl9jcCA8LSBzaW1wbGVfY3Byb2ZpbGVyKAogIHRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9kb3duLAogIG9yZ2RiID0gIm9yZy5Icy5lZy5kYiIpCmBgYAoKIyMjIyBHU0VBCgpJdCBhcHBlYXJzIHRoZXJlIGFyZSB0b28gZmV3IHJlc3VsdHMgdG8gcGVyZm9ybSB0aGUgZ3NlYSBwbG90cy4KCiMjIEN1cmUvRmFpbCwgQmlvcHNpZXMKClRoZSByZWxldmFudCB4bHN4IG91dHB1dCBtYXkgYmUgZm91bmQgYXQ6CgoqICJ7Y2ZfcHJlZml4fS9CaW9wc2llcy90X2Jpb3BzeV9jZl90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giCiogIntjZl9wcmVmaXh9L0Jpb3BzaWVzL3RfY2ZfYmlvcHN5X3NpZ19zdmEtdnt2ZXJ9Lnhsc3giCgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9CaW9wc2llcy90X2Jpb3BzeV9jZl90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX2Jpb3BzeV90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIikKCmlucHV0X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vQmlvcHNpZXMvdF9jZl9iaW9wc3lfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfYmlvcHN5X3NpZ19zdmFfdXAgPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIpCnRfY2ZfYmlvcHN5X3NpZ19zdmFfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX2Jpb3BzeV9zaWdfc3ZhX2JvdGggPC0gcmJpbmQuZGF0YS5mcmFtZSh0X2NmX2Jpb3BzeV9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX2Jpb3BzeV9zaWdfc3ZhX2Rvd24pCmBgYAoKIyMjIGdQcm9maWxlcgoKV2Ugb25seSBoYXZlIDE3IGdlbmVzIGluIHRoZSBiaW9wc2llcywgYnV0IHBlcmhhcHMgdGhleSBhcmUgc3RpbGwgaW50ZXJlc3Rpbmc/CgojIyMjIGluY3JlYXNlZCBpbiBjdXJlIHZzIGZhaWwKCmBgYHtyfQp0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwX3VwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9iaW9wc3lfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX2Jpb3BzeV9zaWdfc3ZhX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfYmlvcHN5X3NpZ19zdmFfZ3BfdXAKCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9iaW9wc3lfc2lnX3N2YV9ncF91cFtbIkJQX2VucmljaCJdXSkKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfYmlvcHN5X3NpZ19zdmFfZ3BfdXBbWyJCUF9lbnJpY2giXV0pCmdvX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGdvX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2Jpb3BzeV91cF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CmBgYAoKIyMjIyBpbmNyZWFzZWQgaW4gZmFpbCB2cyBjdXJlCgpgYGB7cn0KdF9jZl9iaW9wc3lfc2lnX3N2YV9ncF9kb3duIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9iaW9wc3lfc2lnX3N2YV9kb3duLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfYmlvcHN5X3NpZ19zdmFfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwX2Rvd24KCiMjIE5vdCBuZWFybHkgYXMgaW50ZXJlc3RpbmcKYGBgCgojIyMgY2x1c3RlcnByb2ZpbGVyCgpBZ2FpbiwgY2x1c3RlcnByb2ZpbGVyIHZlcnNpb24KCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUvZmFpbAoKYGBge3J9CnRfY2ZfYmlvcHN5X3NpZ19zdmFfY3BfdXAgPC0gc2ltcGxlX2Nwcm9maWxlcigKICB0X2NmX2Jpb3BzeV9zaWdfc3ZhX3VwLCBkZV90YWJsZSA9IHRfY2ZfYmlvcHN5X3RhYmxlX3N2YSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfYmlvcHN5X3NpZ19zdmFfdXBfY3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Jpb3BzeV9zaWdfc3ZhX2NwX3VwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHU0VBIG9mIGN1cmUvZmFpbAoKYGBge3J9CnRfY2ZfYmlvcHN5X3NpZ190b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9iaW9wc3lfc2lnX3N2YV9jcF91cCkKdF9jZl9iaW9wc3lfc2lnX3RvcG5fZ3NlYVtbIkdPX291dGNvbWVfdXAiXV1bWzFdXQpgYGAKCiMjIEVvc2lub3BoaWxzIGN1cmUvZmFpbAoKYGBge3J9CmlucHV0X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfZW9zaW5vcGhpbF90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIikKCmlucHV0X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vRW9zaW5vcGhpbHMvdF9lb3Npbm9waGlsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIikKdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ib3RoIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBnUHJvZmlsZXIKCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXAsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9lb3Npbm9waGlsX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwX2dwCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXBfZ3BbWyJURl9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmdvX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGdvX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gImZpZ3VyZXMvdF9jZl9lb3Npbm9waGlsX3VwX2dwX2dvLnN2ZyIsCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CgpyZWFjX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV91cF9ncFtbIlJFQUNfZW5yaWNoIl1dKQpyZWFjX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KHJlYWNfdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfZW9zaW5vcGhpbF91cF9ncF9yZWFjLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpyZWFjX3RyZWVwbG90CmRldi5vZmYoKQpgYGAKCiMjIyMgaW5jcmVhc2VkIGluIGZhaWwgdnMgY3VyZQoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9kb3duLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9kb3duX2dwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZG93bl9ncFtbIkJQX2VucmljaCJdXSkKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9kb3duX2dwW1siQlBfZW5yaWNoIl1dKQpnb190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChnb190ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9lb3Npbm9waGlsX2Rvd25fZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmdvX3RyZWVwbG90CmRldi5vZmYoKQpnb190cmVlcGxvdAoKIyMgVGhlcmUgaXMgb25seSBvbmUgcmVhY3RvbWUgaGl0LCBzbyBub3QgcGxvdHRpbmcgaXQuCmBgYAoKIyMjIyBCb3RoIHVwIGFuZCBkb3duCgpJIGV2YWx1YXRlZCB0aGlzIGFuZCB0aGUgJ3VwJyBzZXQgbmV4dCB0byBlYWNoIG90aGVyIGFuZCB0aGV5IGFyZQpleHRyZW1lbHkgc2ltaWxhcjoKCnVwOiAxNDggR08gaGl0cywgNjggVEYsIDAgSFBBCmJvdGg6IDE2OSBHTywgNjkgVEYsIGFuZCAyIEhQQQoKT3RoZXJ3aXNlIEkgdGhpbmsgdGhleSBhcmUgdGhlIHNhbWUuCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfYm90aF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2JvdGgsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9lb3Npbm9waGlsX2JvdGhfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfYm90aF9ncAplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2JvdGhfZ3BbWyJCUF9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfYm90aF9ncFtbIkJQX2VucmljaCJdXSkKZ29fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZ29fdGVybXNpbSwgbGFiZWxfZm9ybWFwID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfZW9zaW5vcGhpbF9ib3RoX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpnb190cmVlcGxvdApkZXYub2ZmKCkKZ29fdHJlZXBsb3QKCnJlYWNfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2JvdGhfZ3BbWyJSRUFDX2VucmljaCJdXSkKcmVhY190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChyZWFjX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2Vvc2lub3BoaWxfYm90aF9ncF9yZWFjLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpyZWFjX3RyZWVwbG90CmRldi5vZmYoKQpgYGAKCiMjIyBjbHVzdGVycHJvZmlsZXIKCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2NwX3VwIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXAsIGRlX3RhYmxlID0gdF9jZl9lb3Npbm9waGlsX3RhYmxlX3N2YSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfY3BfdXBbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMjIGluY3JlYXNlZCBpbiBmYWlsIHZzIGN1cmUKCmBgYHtyfQp0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9jcF9kb3duIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZG93biwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2Rvd25fY3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9jcF9kb3duW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHU0VBCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3NpZ190b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfY3BfdXApCnRfY2ZfZW9zaW5vcGhpbF9zaWdfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyMgTW9ub2N5dGVzIGN1cmUvZmFpbAoKYGBge3J9CmlucHV0X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9tb25vY3l0ZV90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIikKCmlucHV0X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIikKdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIsICJkb3duIikKdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGggPC0gcmJpbmQuZGF0YS5mcmFtZSh0X2NmX21vbm9jeXRlX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2Rvd24pCmBgYAoKIyMjIGdQcm9maWxlcgoKTm93IHRoYXQgSSBhbSBsb29raW5nIGJhY2sgb3ZlciB0aGVzZSByZXN1bHRzLCBJIGFtIG5vdCBjb21wZWx0ZWx5CmNlcnRhaW4gd2h5IEkgb25seSBkaWQgdGhlIGdwcm9maWxlciBzZWFyY2ggZm9yIHRoZSBzdmEgZGF0YS4uLgoKIyMjIyBpbmNyZWFzZWQgaW4gY3VyZSB2cyBmYWlsCgpgYGB7cn0KdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbW9ub2N5dGVfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwX2dwCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwX2dwW1siQlBfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cF9ncFtbIlRGX2VucmljaCJdXSkKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX21vbm9jeXRlX3NpZ19zdmFfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmdvX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGdvX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gImZpZ3VyZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfbW9ub2N5dGVfdXBfZ3BfZ28uc3ZnIiwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpnb190cmVlcGxvdApkZXYub2ZmKCkKZ29fdHJlZXBsb3QKYGBgCgojIyMjIGluY3JlYXNlZCBpbiBmYWlsIHZzIGN1cmUKCmBgYHtyfQp0X2NmX21vbm9jeXRlX3NpZ19zdmFfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9kb3duLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbW9ub2N5dGVfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9kb3duX2dwW1siQlBfZW5yaWNoIl1dKQoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9kb3duX2dwW1siQlBfZW5yaWNoIl1dKQpnb190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChnb190ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9tb25vY3l0ZV9kb3duX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpnb190cmVlcGxvdApkZXYub2ZmKCkKZ29fdHJlZXBsb3QKCiMjIEluc3VmZmljaWVudCByZXN1bHRzIHRvIG1ha2UgYSB0cmVlIHBsb3QuCmBgYAoKIyMjIyBCb3RoIHVwIGFuZCBkb3duCgpgYGB7cn0KdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGhfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX21vbm9jeXRlX3NpZ19zdmFfYm90aCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX21vbm9jeXRlX2JvdGhfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGhfZ3AKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX21vbm9jeXRlX3NpZ19zdmFfYm90aF9ncFtbIkJQX2VucmljaCJdXSkKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX21vbm9jeXRlX3NpZ19zdmFfYm90aF9ncFtbIkJQX2VucmljaCJdXSkKZ29fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZ29fdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfbW9ub2N5dGVfYm90aF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CgojIyBJbnN1ZmZpY2llbnQgcmVzdWx0cyBmb3IgcmVhY3RvbWUKCnRmX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX21vbm9jeXRlX3NpZ19zdmFfYm90aF9ncFtbIlRGX2VucmljaCJdXSkKdGZfdHJlZXBsb3QgPC0gc20odHJlZXBsb3QodGZfdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfbW9ub2N5dGVfYm90aF9ncF90Zi12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKdGZfdHJlZXBsb3QKZGV2Lm9mZigpCnRmX3RyZWVwbG90CmBgYAoKIyMjIGNsdXN0ZXJwcm9maWxlcgoKIyMjIyBpbmNyZWFzZWQgaW4gY3VyZSB2cyBmYWlsCgpgYGB7cn0KdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2NwX3VwIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwLCBkZV90YWJsZSA9IHRfY2ZfbW9ub2N5dGVfdGFibGVfc3ZhLAogIG9yZ2RiID0gIm9yZy5Icy5lZy5kYiIsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2NwX3VwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBpbmNyZWFzZWQgaW4gZmFpbCB2cyBjdXJlCgpgYGB7cn0KdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2NwX2Rvd24gPC0gc2ltcGxlX2Nwcm9maWxlcigKICB0X2NmX21vbm9jeXRlX3NpZ19zdmFfZG93biwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbW9ub2N5dGVfc2lnX3N2YV9kb3duX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2NwX2Rvd25bWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMjIEdTRUEKCmBgYHtyfQp0X2NmX21vbm9jeXRlX3NpZ190b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2NwX3VwKQp0X2NmX21vbm9jeXRlX3NpZ190b3BuX2dzZWFbWyJHT19vdXRjb21lX3VwIl1dW1sxXV0KYGBgCgojIyBOZXV0cm9waGlscyBjdXJlL2ZhaWwKCmBgYHtyfQppbnB1dF94bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L05ldXRyb3BoaWxzL3RfbmV1dHJvcGhpbF9jZl90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX25ldXRyb3BoaWxfdGFibGVfc3ZhIDwtIHRhYmxlX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIpCgppbnB1dF94bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L05ldXRyb3BoaWxzL3RfbmV1dHJvcGhpbF9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfdXAgPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIpCnRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcihpbnB1dF94bHN4LCAib3V0Y29tZSIsICJkb3duIikKdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfYm90aCA8LSByYmluZC5kYXRhLmZyYW1lKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2Rvd24pCmBgYAoKIyMjIGdQcm9maWxlcgoKTm93IHRoYXQgSSBhbSBsb29raW5nIGJhY2sgb3ZlciB0aGVzZSByZXN1bHRzLCBJIGFtIG5vdCBjb21wZWx0ZWx5CmNlcnRhaW4gd2h5IEkgb25seSBkaWQgdGhlIGdwcm9maWxlciBzZWFyY2ggZm9yIHRoZSBzdmEgZGF0YS4uLgoKIyMjIyBpbmNyZWFzZWQgaW4gY3VyZSB2cyBmYWlsCgpgYGB7cn0KdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfdXBfZ3AKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cF9ncFtbIkJQX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cF9ncFtbIlRGX2VucmljaCJdXSkKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cF9ncFtbIkJQX2VucmljaCJdXSkKZ29fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZ29fdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSAiZmlndXJlcy90X2NmX25ldXRyb3BoaWxfdXBfZ3BfZ28uc3ZnIiwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpnb190cmVlcGxvdApkZXYub2ZmKCkKZ29fdHJlZXBsb3QKYGBgCgojIyMjIGluY3JlYXNlZCBpbiBmYWlsIHZzIGN1cmUKCmBgYHtyfQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9kb3duX2dwCgojIyBOb3QgbXVjaCB0byB3b3JrIHdpdGggaGVyZS4KYGBgCgojIyMjIEJvdGggdXAgYW5kIGRvd24KCmBgYHtyfQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfYm90aCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfYm90aF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ib3RoX2dwCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfYm90aF9ncFtbIkJQX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ib3RoX2dwW1siVEZfZW5yaWNoIl1dKQoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2JvdGhfZ3BbWyJCUF9lbnJpY2giXV0pCmdvX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGdvX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX25ldXRyb3BoaWxfYm90aF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CgojIyBJbnN1ZmZpY2llbnQgcmVzdWx0cyBmb3IgcmVhY3RvbWUKYGBgCgojIyMgY2x1c3RlcnByb2ZpbGVyCgojIyMjIGluY3JlYXNlZCBpbiBjdXJlIHZzIGZhaWwKCmBgYHtyfQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9jcF91cCA8LSBzaW1wbGVfY3Byb2ZpbGVyKAogIHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwLCBkZV90YWJsZSA9IHRfY2ZfbmV1dHJvcGhpbF90YWJsZV9zdmEsCiAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIiwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cF9jcC12e3Zlcn0ueGxzeCIpKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2NwX3VwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBpbmNyZWFzZWQgaW4gZmFpbCB2cyBjdXJlCgpgYGB7cn0KdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfY3BfZG93biA8LSBzaW1wbGVfY3Byb2ZpbGVyKAogIHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2Rvd24sCiAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIiwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9kb3duX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfY3BfZG93bltbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR1NFQQoKYGBge3J9CnRfY2ZfbmV1dHJvcGhpbF9zaWdfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2NwX3VwKQp0X2NmX25ldXRyb3BoaWxfc2lnX3RvcG5fZ3NlYVtbIkdPX291dGNvbWVfdXAiXV1bWzFdXQpgYGAKCiMjIExvb2sgYXQgdmlzaXQgMSBhbmQgc2VlIGlmIGFueXRoaW5nIHBvcHMgb3V0CgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV92MV9jZl90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX21vbm9jeXRlX3YxX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQoKaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV92MV9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfZG93biA8LSBzaWdfcmVhZGVyKGlucHV0X3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfYm90aCA8LSByYmluZC5kYXRhLmZyYW1lKHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfZG93bikKYGBgCgojIyMgR2VuZSBTZXQgRW5yaWNobWVudDogZ1Byb2ZpbGVyIE1vbm9jeXRlcyBieSB2aXNpdCwgVjEKClYxOiBVcDogMTQgZ2VuZXM7IE5vIGNhdGVnb3JpZXMKVjE6IERvd246IDUyIGdlbmVzOyAyMCBHTywgNSBURgoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX3VwX2dwCnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9uZXV0cm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX2Rvd25fZ3AKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX2JvdGhfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfYm90aCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfYm90aF9ncApgYGAKCkkgbGlrZSBjYXRzIQoKIyMjIyBjbHVzdGVyUHJvZmlsZXIKCmBgYHtyfQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfdXBfY3AgPC0gc2ltcGxlX2Nwcm9maWxlcih0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfY2ZfbW9ub2N5dGVfdjFfdGFibGVfc3ZhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cF9jcFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQp0X2NmX21vbm9jeXRlX3YxX3RvcG5fZ3NlYSA8LSBwbG90X3RvcG5fZ3NlYSh0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfdXBfY3ApCnRfY2ZfbW9ub2N5dGVfdjFfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyMjIE5ldXRyb3BoaWxzIHYxCgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjFfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9uZXV0cm9waGlsX3YxX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQoKaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9kb3duIDwtIHNpZ19yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiLCAiZG93biIpCnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX2JvdGggPC0gcmJpbmQuZGF0YS5mcmFtZSh0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBHZW5lIFNldCBFbnJpY2htZW50OiBnUHJvZmlsZXIgTmV1dHJvcGhpbHMgYnkgdmlzaXQsIFYxCgpgYGB7cn0KdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AKdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9uZXV0cm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncAp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfYm90aCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9ib3RoX2dwCmBgYAoKIyMjIyBjbHVzdGVyUHJvZmlsZXIKCmBgYHtyfQp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV91cF9jcCA8LSBzaW1wbGVfY3Byb2ZpbGVyKHRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfY2ZfbmV1dHJvcGhpbF92MV90YWJsZV9zdmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIikKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV91cF9jcFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQp0X2NmX25ldXRyb3BoaWxfdjFfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX3VwX2NwKQp0X2NmX25ldXRyb3BoaWxfdjFfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyMjIEVvc2lub3BoaWxzIHYxCgpgYGB7cn0KaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdjFfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9lb3Npbm9waGlsX3YxX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQoKaW5wdXRfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiKQp0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9kb3duIDwtIHNpZ19yZWFkZXIoaW5wdXRfeGxzeCwgIm91dGNvbWUiLCAiZG93biIpCnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX2JvdGggPC0gcmJpbmQuZGF0YS5mcmFtZSh0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBHZW5lIFNldCBFbnJpY2htZW50OiBnUHJvZmlsZXIgRW9zaW5vcGhpbHMgYnkgdmlzaXQsIFYxCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX2Vvc2lub3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AKdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9lb3Npbm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncAp0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfYm90aCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX2Vvc2lub3BoaWxfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9ib3RoX2dwCmBgYAoKIyMjIyBjbHVzdGVyUHJvZmlsZXIKCmBgYHtyfQp0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV91cF9jcCA8LSBzaW1wbGVfY3Byb2ZpbGVyKHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfY2ZfZW9zaW5vcGhpbF92MV90YWJsZV9zdmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIikKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV91cF9jcFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQp0X2NmX2Vvc2lub3BoaWxfdjFfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX3VwX2NwKQp0X2NmX2Vvc2lub3BoaWxfdjFfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyBCaWJsaW9ncmFwaHkK