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

tc_clinical_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(tc_clinical_xlsx, "outcome")
## [1] 12162    85
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)

t_clinical_xlsx <- glue("analyses/4_tumaco/DE_Cure_Fail/t_all_visitcf_sig_sva-v{ver}.xlsx")
t_de_cf <- openxlsx::readWorkbook(t_clinical_xlsx, sheet = 3, startRow = 2)
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
rownames(t_de_cf) <- t_de_cf[["row.names"]]
## Error in eval(expr, envir, enclos): object 't_de_cf' not found
t_de_cf[["row.names"]] <- NULL
## Error: object 't_de_cf' not found
t_de_cf_up <- t_de_cf[, c("deseq_logfc", "deseq_adjp", "deseq_basemean", "deseq_lfcse")]
## Error in eval(expr, envir, enclos): object 't_de_cf' not found
t_de_cf <- openxlsx::readWorkbook(t_clinical_xlsx, sheet = 4, startRow = 2)
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
rownames(t_de_cf) <- t_de_cf[["row.names"]]
## Error in eval(expr, envir, enclos): object 't_de_cf' not found
t_de_cf[["row.names"]] <- NULL
## Error: object 't_de_cf' not found
t_de_cf_down <- t_de_cf[, c("deseq_logfc", "deseq_adjp", "deseq_basemean", "deseq_lfcse")]
## Error in eval(expr, envir, enclos): object 't_de_cf' not found
t_de_cf <- rbind.data.frame(t_de_cf_up, t_de_cf_down)
## Error in eval(expr, envir, enclos): object 't_de_cf_up' not found

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”
t_clinical_cf_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_cf_table_sva-v{ver}.xlsx")
t_clinical_cf_table_sva <- table_reader(t_clinical_cf_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_clinical_cf_sig_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_cf_sig_sva-v{ver}.xlsx")
t_clinical_cf_sig_sva_up <- sig_reader(t_clinical_cf_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_clinical_cf_sig_sva_down <- sig_reader(t_clinical_cf_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.

And without biopsies

t_clinical_nobiop_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_nobiop_cf_table_sva-v{ver}.xlsx")
t_clinicalnb_cf_table_sva <- table_reader(t_clinical_nobiop_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_clinical_nobiop_sig_xlsx <- glue("{cf_prefix}/All_Samples/t_clinical_nobiop_cf_sig_sva-v{ver}.xlsx")
t_clinicalnb_cf_sig_sva_up <- sig_reader(t_clinical_nobiop_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_clinicalnb_cf_sig_sva_down <- sig_reader(t_clinical_nobiop_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_clinicalnb_cf_sig_sva_both <- rbind.data.frame(t_clinicalnb_cf_sig_sva_up,
                                                 t_clinicalnb_cf_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_clinicalnb_cf_sig_sva_up' not found

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 eval(expr, envir, enclos): object 't_clinical_cf_sig_sva_up' not found
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 eval(expr, envir, enclos): object 't_clinicalnb_cf_sig_sva_up' not found
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 eval(expr, envir, enclos): object 't_clinical_cf_sig_sva_down' not found
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 eval(expr, envir, enclos): object 't_clinicalnb_cf_sig_sva_down' not found
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

2.4.1.3 And gene higher in either

## 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 eval(expr, envir, enclos): object 't_clinicalnb_cf_sig_sva_both' not found
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"))
## Error in eval(expr, envir, enclos): object 't_clinical_cf_table_sva' not found
enrichplot::dotplot(t_cf_clinical_cp_up[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_cp_up' not found

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"))
## Error in eval(expr, envir, enclos): object 't_clinical_cf_sig_sva_down' not found
enrichplot::dotplot(t_cf_clinical_cp_down[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_cp_down' not found

2.4.2.3 And both higher in cure or fail

Note that for both I did not bother with the analysis that included biopsies.

t_cf_clinicalnb_cp_both <- simple_clusterprofiler(
  t_clinicalnb_cf_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Overrepresentation/clinical_fail_up_cp-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 't_clinicalnb_cf_sig_sva_both' not found
enrichplot::dotplot(t_cf_clinical_cp_both[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_clinical_cp_both' not found

2.4.2.4 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)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_clinical_cp_up' not found
t_cf_clinical_topn_gsea[["GO"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_clinical_topn_gsea' not found
t_cf_clinical_topn_gsea[["GO"]][[2]]
## Error in eval(expr, envir, enclos): object 't_cf_clinical_topn_gsea' not found
t_cf_clinical_topn_gsea[["GO"]][[3]]
## Error in eval(expr, envir, enclos): object 't_cf_clinical_topn_gsea' not found
t_cf_clinical_topn_gsea[["GO"]][[4]]
## Error in eval(expr, envir, enclos): object 't_cf_clinical_topn_gsea' not found
t_cf_clinical_topn_gsea[["GO"]][[5]]
## Error in eval(expr, envir, enclos): object 't_cf_clinical_topn_gsea' not found

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”
tv1_later_xlsx <- glue("{xlsx_prefix}/DE_Visits/tv1_vs_later_tables-v{ver}.xlsx")
tv1_vs_later_table <- table_reader(tv1_later_xlsx, "later_vs_first")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
tv1_later_sig_xlsx <- glue("{xlsx_prefix}/DE_Visits/tv1_vs_later_sig-v{ver}.xlsx")
tv1_vs_later_up_sig <- sig_reader(tv1_later_sig_xlsx, "later_vs_first")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
tv1_vs_later_down_sig <- sig_reader(tv1_later_sig_xlsx, "later_vs_first", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
tv1_vs_later_both <- rbind.data.frame(tv1_vs_later_up_sig, tv1_vs_later_down_sig)
## Error in eval(expr, envir, enclos): object 'tv1_vs_later_up_sig' not found

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 increased in visit 1

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 eval(expr, envir, enclos): object 'tv1_vs_later_up_sig' not found
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 increased and decreased in visit 1

tv1later_both_gp <- simple_gprofiler(
  tv1_vs_later_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/tv1_vs_later_both_gp-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'tv1_vs_later_both' not found
tv1later_both_gp
## Error in eval(expr, envir, enclos): object 'tv1later_both_gp' not found
enrichplot::dotplot(tv1later_both_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_both_gp' not found
enrichplot::dotplot(tv1later_both_gp[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_both_gp' not found

2.5.1.3 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)
## Error in eval(expr, envir, enclos): object 'tv1_vs_later_table' not found
enrichplot::dotplot(tv1later_up_cp[["enrich_objects"]][["MF_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_up_cp' not found
enrichplot::dotplot(tv1later_up_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_up_cp' not found
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.
## Error in eval(expr, envir, enclos): object 'tv1later_up_cp' not found
tv1later_both_cp <- simple_clusterprofiler(
  tv1_vs_later_both, de_table = tv1_vs_later_table,
  orgdb = "org.Hs.eg.db", kegg_prefix = "hs", do_kegg = TRUE)
## Error in eval(expr, envir, enclos): object 'tv1_vs_later_table' not found
enrichplot::dotplot(tv1later_both_cp[["enrich_objects"]][["MF_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_both_cp' not found
enrichplot::dotplot(tv1later_both_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tv1later_both_cp' not found
written <- write_cp_data(
  tv1later_both_cp,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/tv1_vs_later_both_cp-v{ver}.xlsx"))
## Writing a sheet containing the legend.
## Error in eval(expr, envir, enclos): object 'tv1later_both_cp' not found

2.5.1.4 GSEA: clusterProfiler

tv1later_topn_gsea <- plot_topn_gsea(tv1later_up_cp)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 'tv1later_up_cp' not found
tv1later_topn_gsea[["GO"]][[1]]
## Error in eval(expr, envir, enclos): object 'tv1later_topn_gsea' not found
tv1later_topn_gsea[["GO"]][[2]]
## Error in eval(expr, envir, enclos): object 'tv1later_topn_gsea' not found

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.

t_sex_xlsx <- glue("{xlsx_prefix}/DE_Sex/t_sex_cure_table-v{ver}.xlsx")
t_sex_table <- table_reader(t_sex_xlsx, "male_vs_female")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_sex_sig_xlsx <- glue("{xlsx_prefix}/DE_Sex/t_sex_cure_sig-v{ver}.xlsx")
t_sex_up_sig <- sig_reader(t_sex_sig_xlsx, "male_vs_female")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_sex_down_sig <- sig_reader(t_sex_sig_xlsx, "male_vs_female", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_sex_both_sig <- rbind.data.frame(t_sex_up_sig, t_sex_down_sig)
## Error in eval(expr, envir, enclos): object 't_sex_up_sig' not found

x ### gProfiler

2.6.0.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 eval(expr, envir, enclos): object 't_sex_up_sig' not found
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.0.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 eval(expr, envir, enclos): object 't_sex_down_sig' not found
t_sex_down_gp
## Error in eval(expr, envir, enclos): object 't_sex_down_gp' not found

2.6.0.3 In either

t_sex_both_gp <- simple_gprofiler(
  t_sex_both_sig,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/sex_female_up_gp-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 't_sex_both_sig' not found
t_sex_both_gp
## Error in eval(expr, envir, enclos): object 't_sex_both_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.1 clusterProfiler

2.6.1.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)
## Error in eval(expr, envir, enclos): object 't_sex_table' not found
enrichplot::dotplot(t_sex_up_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_sex_up_cp' not found

2.6.1.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)
## Error in eval(expr, envir, enclos): object 't_sex_table' not found
enrichplot::dotplot(t_sex_down_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_sex_down_cp' not found

2.6.2 Either

t_sex_both_cp <- simple_clusterprofiler(
  t_sex_both_sig, de_table = t_sex_table,
  orgdb = "org.Hs.eg.db", kegg_prefix = "hs", do_kegg = TRUE)
## Error in eval(expr, envir, enclos): object 't_sex_table' not found
enrichplot::dotplot(t_sex_both_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_sex_both_cp' not found

2.6.2.1 GSEA

t_sex_topn_gsea <- plot_topn_gsea(t_sex_up_cp)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_sex_up_cp' not found
t_sex_topn_gsea[["GO"]][[1]]
## Error in eval(expr, envir, enclos): object 't_sex_topn_gsea' not found

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”
t_ethnicity_xlsx <- glue("{xlsx_prefix}/DE_Ethnicity/t_ethnicity_table-v{ver}.xlsx")
t_ethnicity_mestizo_indigenous <- table_reader(t_ethnicity_xlsx, "mestizo_indigenous")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_mestizo_afrocol <- table_reader(t_ethnicity_xlsx, "mestizo_afrocol")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_indigenous_afrocol <- table_reader(t_ethnicity_xlsx, "indigenous_afrocol")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_sig_xlsx <- glue("{xlsx_prefix}/DE_Ethnicity/t_ethnicity_sig-v{ver}.xlsx")
t_ethnicity_mestizo_indigenous_up <- sig_reader(t_ethnicity_sig_xlsx, "mestizo_indigenous")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_mestizo_indigenous_down <- sig_reader(t_ethnicity_sig_xlsx, "mestizo_indigenous", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_mestizo_afrocol_up <- sig_reader(t_ethnicity_sig_xlsx, "mestizo_afrocol")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_mestizo_afrocol_down <- sig_reader(t_ethnicity_sig_xlsx, "mestizo_afrocol", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_indigenous_afrocol_up <- sig_reader(t_ethnicity_sig_xlsx, "indigenous_afrocol")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_indigenous_afrocol_down <- sig_reader(t_ethnicity_sig_xlsx, "indigenous_afrocol", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_ethnicity_any <- rbind.data.frame(
  t_ethnicity_mestizo_indigenous_up,
  t_ethnicity_mestizo_indigenous_down,
  t_ethnicity_mestizo_afrocol_up,
  t_ethnicity_mestizo_afrocol_down,
  t_ethnicity_indigenous_afrocol_up,
  t_ethnicity_indigenous_afrocol_down)
## Error in eval(expr, envir, enclos): object 't_ethnicity_mestizo_indigenous_up' not found

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 eval(expr, envir, enclos): object 't_ethnicity_mestizo_indigenous_up' not found
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 eval(expr, envir, enclos): object 't_ethnicity_mestizo_indigenous_down' not found
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 eval(expr, envir, enclos): object 't_ethnicity_mestizo_afrocol_up' not found
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 eval(expr, envir, enclos): object 't_ethnicity_mestizo_afrocol_down' not found
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 eval(expr, envir, enclos): object 't_ethnicity_indigenous_afrocol_up' not found
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 eval(expr, envir, enclos): object 't_ethnicity_indigenous_afrocol_down' not found
afrocol_indigenous_up_gp
## Error in eval(expr, envir, enclos): object 'afrocol_indigenous_up_gp' not found

2.7.1.7 Changed in any group

ethnicity_any_gp <- simple_gprofiler(
  t_ethnicity_any,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/ethnicity_any_gp-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 't_ethnicity_any' not found
ethnicity_any_gp
## Error in eval(expr, envir, enclos): object 'ethnicity_any_gp' not found
enrichplot::dotplot(ethnicity_any_gp[["BP_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'ethnicity_any_gp' not found
enrichplot::dotplot(ethnicity_any_gp[["REAC_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'ethnicity_any_gp' not found
enrichplot::dotplot(ethnicity_any_gp[["TF_enrich"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'ethnicity_any_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)
## Error in eval(expr, envir, enclos): object 't_ethnicity_mestizo_indigenous' not found
mestizo_indigenous_up_cp
## Error in eval(expr, envir, enclos): object 'mestizo_indigenous_up_cp' not found

2.7.2.2 Increased in indigenous vs mestizo

indigenous_mestizo_up_cp <- simple_clusterprofiler(
  t_ethnicity_mestizo_indigenous_down)
## Error in eval(expr, envir, enclos): object 't_ethnicity_mestizo_indigenous_down' not found
indigenous_mestizo_up_cp
## Error in eval(expr, envir, enclos): object 'indigenous_mestizo_up_cp' not found

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)
## Error in eval(expr, envir, enclos): object 't_ethnicity_mestizo_afrocol' not found
mestizo_afrocol_up_cp
## Error in eval(expr, envir, enclos): object 'mestizo_afrocol_up_cp' not found

2.7.2.4 Increased in afrocolombian vs mestizo

afrocol_mestizo_up_cp <- simple_clusterprofiler(t_ethnicity_mestizo_afrocol_down)
## Error in eval(expr, envir, enclos): object 't_ethnicity_mestizo_afrocol_down' not found
afrocol_mestizo_up_cp
## Error in eval(expr, envir, enclos): object 'afrocol_mestizo_up_cp' not found

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)
## Error in eval(expr, envir, enclos): object 't_ethnicity_indigenous_afrocol' not found
indigenous_afrocol_up_cp
## Error in eval(expr, envir, enclos): object 'indigenous_afrocol_up_cp' not found

2.7.2.6 Increased in afrocolombian vs indigenous

afrocol_indigenous_up_cp <- simple_clusterprofiler(t_ethnicity_indigenous_afrocol_down)
## Error in eval(expr, envir, enclos): object 't_ethnicity_indigenous_afrocol_down' not found
afrocol_indigenous_up_cp
## Error in eval(expr, envir, enclos): object 'afrocol_indigenous_up_cp' not found

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”
t_clinical_v1_xlsx <- glue("{cf_prefix}/Visits/t_clinical_v1_cf_table_sva-v{ver}.xlsx")
t_cf_clinical_v1_table_sva <- table_reader(t_clinical_v1_xlsx)
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_clinical_v1_sig_xlsx <- glue("{cf_prefix}/Visits/t_clinical_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_clinical_v1_sig_sva_up <- sig_reader(t_clinical_v1_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_clinical_v1_sig_sva_down <- sig_reader(t_clinical_v1_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_clinical_v1_sig_sva_both <- rbind.data.frame(
  t_cf_clinical_v1_sig_sva_up,
  t_cf_clinical_v1_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_up' not found

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 eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_up' not found
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 eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_down' not found
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.1.3 Increased in either

t_cf_clinical_v1_sig_sva_both_gp <- simple_gprofiler(t_cf_clinical_v1_sig_sva_both)
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_both' not found
t_cf_clinical_v1_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_both_gp' not found
enrichplot::dotplot(t_cf_clinical_v1_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_clinical_v1_sig_sva_both_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")
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_table_sva' not found
t_cf_clinical_v1_sig_sva_up_cp
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_up_cp' not found
enrichplot::dotplot(t_cf_clinical_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])
## 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_up_cp' not found

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")
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_down' not found

2.8.2.3 Either increased or decreased v1 c/f

t_cf_clinical_v1_sig_sva_both_cp <- simple_cprofiler(
  t_cf_clinical_v1_sig_sva_both,
  orgdb = "org.Hs.eg.db")
## Error in eval(expr, envir, enclos): object 't_cf_clinical_v1_sig_sva_both' not found
enrichplot::dotplot(t_cf_clinical_v1_sig_sva_both_cp[["enrich_objects"]][["BP_all"]])
## 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_both_cp' not found

2.8.2.4 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”
t_biopsy_xlsx <- glue("{cf_prefix}/Biopsies/t_biopsy_cf_table_sva-v{ver}.xlsx")
t_cf_biopsy_table_sva <- table_reader(t_biopsy_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_biopsy_sig_xlsx <- glue("{cf_prefix}/Biopsies/t_cf_biopsy_sig_sva-v{ver}.xlsx")
t_cf_biopsy_sig_sva_up <- sig_reader(t_biopsy_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_biopsy_sig_sva_down <- sig_reader(t_biopsy_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_biopsy_sig_sva_both <- rbind.data.frame(t_cf_biopsy_sig_sva_up,
                                             t_cf_biopsy_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_up' not found

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 eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_up' not found
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"))
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_down' not found
t_cf_biopsy_sig_sva_gp_down
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_gp_down' not found
## Not nearly as interesting

2.9.1.3 increased in either

t_cf_biopsy_sig_sva_gp_both <- simple_gprofiler(
  t_cf_biopsy_sig_sva_both,
  excel = glue("{xlsx_prefix}/Gene_Set_Enrichment/t_cf_biopsy_sig_sva_both_gp-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_both' not found
t_cf_biopsy_sig_sva_gp_both
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_sva_gp_both' not found
enrichplot::dotplot(t_cf_biopsy_sig_sva_gp_both[["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_both' not found

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"))
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_table_sva' not found
enrichplot::dotplot(t_cf_biopsy_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])
## 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_cp_up' not found

2.9.2.2 GSEA of cure/fail

t_cf_biopsy_sig_topn_gsea <- plot_topn_gsea(t_cf_biopsy_sig_sva_cp_up)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_biopsy_sig_sva_cp_up' not found
t_cf_biopsy_sig_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_biopsy_sig_topn_gsea' not found

2.10 Eosinophils cure/fail

t_eosinophil_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_cf_table_sva-v{ver}.xlsx")
t_cf_eosinophil_table_sva <- table_reader(t_eosinophil_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_eosinophil_sig_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_cf_sig_sva-v{ver}.xlsx")
t_cf_eosinophil_sig_sva_up <- sig_reader(t_eosinophil_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_eosinophil_sig_sva_down <- sig_reader(t_eosinophil_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_eosinophil_sig_sva_both <- rbind.data.frame(t_cf_eosinophil_sig_sva_up,
                                                 t_cf_eosinophil_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_up' not found

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 eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_up' not found
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 eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_down' not found
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 eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_both' not found
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"))
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_table_sva' not found
enrichplot::dotplot(t_cf_eosinophil_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])
## 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_cp_up' not found

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"))
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_sig_sva_down' not found
enrichplot::dotplot(t_cf_eosinophil_sig_sva_cp_down[["enrich_objects"]][["BP_all"]])
## 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_cp_down' not found

2.10.2.3 GSEA

t_cf_eosinophil_sig_topn_gsea <- plot_topn_gsea(t_cf_eosinophil_sig_sva_cp_up)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_eosinophil_sig_sva_cp_up' not found
t_cf_eosinophil_sig_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_sig_topn_gsea' not found

2.11 Monocytes cure/fail

t_monocyte_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_cf_table_sva-v{ver}.xlsx")
t_cf_monocyte_table_sva <- table_reader(t_monocyte_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_monocyte_sig_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_cf_sig_sva-v{ver}.xlsx")
t_cf_monocyte_sig_sva_up <- sig_reader(t_monocyte_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_monocyte_sig_sva_down <- sig_reader(t_monocyte_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_monocyte_sig_sva_both <- rbind.data.frame(t_cf_monocyte_sig_sva_up,
                                               t_cf_monocyte_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_up' not found

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 eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_up' not found
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 eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_down' not found
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 eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_both' not found
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"))
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_table_sva' not found
enrichplot::dotplot(t_cf_monocyte_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])
## 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_cp_up' not found

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"))
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_sig_sva_down' not found
enrichplot::dotplot(t_cf_monocyte_sig_sva_cp_down[["enrich_objects"]][["BP_all"]])
## 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_cp_down' not found

2.11.2.3 GSEA

t_cf_monocyte_sig_topn_gsea <- plot_topn_gsea(t_cf_monocyte_sig_sva_cp_up)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_monocyte_sig_sva_cp_up' not found
t_cf_monocyte_sig_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_sig_topn_gsea' not found

2.12 Neutrophils cure/fail

t_neutrophil_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_cf_table_sva-v{ver}.xlsx")
t_cf_neutrophil_table_sva <- table_reader(t_neutrophil_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_neutrophil_sig_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_cf_sig_sva-v{ver}.xlsx")
t_cf_neutrophil_sig_sva_up <- sig_reader(t_neutrophil_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_neutrophil_sig_sva_down <- sig_reader(t_neutrophil_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_neutrophil_sig_sva_both <- rbind.data.frame(t_cf_neutrophil_sig_sva_up,
                                                 t_cf_neutrophil_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_up' not found

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 eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_up' not found
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 eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_down' not found
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 eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_both' not found
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"))
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_table_sva' not found
enrichplot::dotplot(t_cf_neutrophil_sig_sva_cp_up[["enrich_objects"]][["BP_all"]])
## 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_cp_up' not found

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"))
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_sig_sva_down' not found
enrichplot::dotplot(t_cf_neutrophil_sig_sva_cp_down[["enrich_objects"]][["BP_all"]])
## 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_cp_down' not found

2.12.2.3 GSEA

t_cf_neutrophil_sig_topn_gsea <- plot_topn_gsea(t_cf_neutrophil_sig_sva_cp_up)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_neutrophil_sig_sva_cp_up' not found
t_cf_neutrophil_sig_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_sig_topn_gsea' not found

2.13 Look at visit 1 and see if anything pops out

t_monocyte_v1_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_v1_cf_table_sva-v{ver}.xlsx")
t_cf_monocyte_v1_table_sva <- table_reader(t_monocyte_v1_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_monocyte_v1_sig_xlsx <- glue("{cf_prefix}/Monocytes/t_monocyte_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_monocyte_v1_sig_sva_up <- sig_reader(t_monocyte_v1_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_monocyte_v1_sig_sva_down <- sig_reader(t_monocyte_v1_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_monocyte_v1_sig_sva_both <- rbind.data.frame(t_cf_monocyte_v1_sig_sva_up,
                                                  t_cf_monocyte_v1_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_up' not found

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

2.13.1.1 Increased in cure

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"))
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_up' not found
t_cf_monocyte_v1_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_up_gp' not found

2.13.1.2 Increased in fail

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 eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_down' not found
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

2.13.1.3 Increased in either

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 eval(expr, envir, enclos): object 't_cf_monocyte_v1_sig_sva_both' not found
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.4 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")
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_table_sva' not found
enrichplot::dotplot(t_cf_monocyte_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_monocyte_v1_sig_sva_up_cp' not found
t_cf_monocyte_v1_topn_gsea <- plot_topn_gsea(t_cf_monocyte_v1_sig_sva_up_cp)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_monocyte_v1_sig_sva_up_cp' not found
t_cf_monocyte_v1_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_monocyte_v1_topn_gsea' not found

2.13.2 Neutrophils v1

t_neutrophil_v1_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_v1_cf_table_sva-v{ver}.xlsx")
t_cf_neutrophil_v1_table_sva <- table_reader(t_neutrophil_v1_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_neutrophil_v1_sig_xlsx <- glue("{cf_prefix}/Neutrophils/t_neutrophil_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_neutrophil_v1_sig_sva_up <- sig_reader(t_neutrophil_v1_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_neutrophil_v1_sig_sva_down <- sig_reader(t_neutrophil_v1_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_neutrophil_v1_sig_sva_both <- rbind.data.frame(t_cf_neutrophil_v1_sig_sva_up,
                                                    t_cf_neutrophil_v1_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_up' not found

2.13.3 Gene Set Enrichment: gProfiler Neutrophils by visit, V1

2.13.3.1 Increased in cure

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"))
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_up' not found
t_cf_neutrophil_v1_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_up_gp' not found

2.13.3.2 Increased in fail

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"))
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_down' not found
t_cf_neutrophil_v1_sig_sva_down_gp
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_down_gp' not found

2.13.3.3 Increased in either

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"))
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_both' not found
t_cf_neutrophil_v1_sig_sva_both_gp
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_sig_sva_both_gp' not found

2.13.3.4 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")
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_table_sva' not found
enrichplot::dotplot(t_cf_neutrophil_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_neutrophil_v1_sig_sva_up_cp' not found
t_cf_neutrophil_v1_topn_gsea <- plot_topn_gsea(t_cf_neutrophil_v1_sig_sva_up_cp)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_neutrophil_v1_sig_sva_up_cp' not found
t_cf_neutrophil_v1_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_neutrophil_v1_topn_gsea' not found

2.13.4 Eosinophils v1

t_eosinophil_v1_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_v1_cf_table_sva-v{ver}.xlsx")
t_cf_eosinophil_v1_table_sva <- table_reader(t_eosinophil_v1_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_eosinophil_v1_sig_xlsx <- glue("{cf_prefix}/Eosinophils/t_eosinophil_v1_cf_sig_sva-v{ver}.xlsx")
t_cf_eosinophil_v1_sig_sva_up <- sig_reader(t_eosinophil_v1_sig_xlsx, "outcome")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_eosinophil_v1_sig_sva_down <- sig_reader(t_eosinophil_v1_sig_xlsx, "outcome", "down")
## Error in read.xlsx.default(xlsxFile = xlsxFile, sheet = sheet, startRow = startRow, : File does not exist.
t_cf_eosinophil_v1_sig_sva_both <- rbind.data.frame(t_cf_eosinophil_v1_sig_sva_up,
                                                    t_cf_eosinophil_v1_sig_sva_down)
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_up' not found

2.13.5 Gene Set Enrichment: gProfiler Eosinophils by visit, V1

2.13.5.1 Increased in cure

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"))
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_up' not found
t_cf_eosinophil_v1_sig_sva_up_gp
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_up_gp' not found

2.13.5.2 Increased in fail

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 eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_down' not found
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

2.13.5.3 Increased in either

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 eval(expr, envir, enclos): object 't_cf_eosinophil_v1_sig_sva_both' not found
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.4 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")
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_table_sva' not found
enrichplot::dotplot(t_cf_eosinophil_v1_sig_sva_up_cp[["enrich_objects"]][["BP_all"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 't_cf_eosinophil_v1_sig_sva_up_cp' not found
t_cf_eosinophil_v1_topn_gsea <- plot_topn_gsea(t_cf_eosinophil_v1_sig_sva_up_cp)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'gse' in selecting a method for function 'plot_topn_gsea': object 't_cf_eosinophil_v1_sig_sva_up_cp' not found
t_cf_eosinophil_v1_topn_gsea[["GO_outcome_up"]][[1]]
## Error in eval(expr, envir, enclos): object 't_cf_eosinophil_v1_topn_gsea' not found

3 Repeat some of this for the mixed linear model results

Speaking with Maria Adelaida, it sounds like the most appropriate set to try for now is |logFC| >= 0.58 and p <= 0.05. I wrote out the dream results in a simpler and less fun way than everything else.

3.1 All celltypes

3.1.1 Collect the gene sets

mixed_all_tbl <- table_reader(
  glue("excel/mixed_all_celltypes_nobiop_table-v{ver}.xlsx"),
  sheet = "failure_vs_cure")
## [1] 19952    22
all_sig_up_idx <- mixed_all_tbl[["logfc"]] >= 0.58 &
  mixed_all_tbl[["p_value"]] <= 0.05
all_sig_down_idx <- mixed_all_tbl[["logfc"]] <= -0.58 &
  mixed_all_tbl[["p_value"]] <= 0.05

all_up_genes <- rownames(mixed_all_tbl)[all_sig_up_idx]
all_down_genes <- rownames(mixed_all_tbl)[all_sig_down_idx]
all_both_genes <- c(all_up_genes, all_down_genes)

3.1.2 Genes increased in cure

t_dream_all_up_gp <- simple_gprofiler(
  all_up_genes,
  excel = glue("excel/dream_all_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
all_up_termsim <- enrichplot::pairwise_termsim(t_dream_all_up_gp[["BP_enrich"]])
all_up_treeplot <- sm(treeplot(all_up_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_all_up_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
all_up_treeplot
dev.off()
## png 
##   2
all_up_treeplot

3.1.3 Genes increased in fail

t_dream_all_down_gp <- simple_gprofiler(
  all_down_genes,
  excel = glue("excel/dream_all_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
all_down_termsim <- enrichplot::pairwise_termsim(t_dream_all_down_gp[["BP_enrich"]])
all_down_treeplot <- sm(treeplot(all_down_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_all_down_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
all_down_treeplot
dev.off()
## png 
##   2
all_down_treeplot

3.1.4 Increased in either

t_dream_all_both_gp <- simple_gprofiler(
  all_both_genes,
  excel = glue("excel/dream_all_both_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
all_both_termsim <- enrichplot::pairwise_termsim(t_dream_all_both_gp[["BP_enrich"]])
all_both_treeplot <- sm(treeplot(all_both_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_all_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
all_both_treeplot
dev.off()
## png 
##   2
all_both_treeplot

3.2 Monocytes

3.2.1 Collecting gene sets

mixed_monocyte_tbl <- table_reader(
  glue("excel/mixed_monocyte_table-v{ver}.xlsx"),
  sheet = "failure_vs_cure")
## [1] 19952    22
monocyte_sig_up_idx <- mixed_monocyte_tbl[["logfc"]] >= 0.58 &
  mixed_monocyte_tbl[["p_value"]] <= 0.05
monocyte_sig_down_idx <- mixed_monocyte_tbl[["logfc"]] <= -0.58 &
  mixed_monocyte_tbl[["p_value"]] <= 0.05

monocyte_up_genes <- rownames(mixed_monocyte_tbl)[monocyte_sig_up_idx]
monocyte_down_genes <- rownames(mixed_monocyte_tbl)[monocyte_sig_down_idx]
monocyte_both_genes <- c(monocyte_up_genes, monocyte_down_genes)

3.2.2 Increased in fail

t_dream_monocyte_up_gp <- simple_gprofiler(
  monocyte_up_genes,
  excel = glue("excel/dream_monocyte_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
monocyte_up_termsim <- enrichplot::pairwise_termsim(t_dream_monocyte_up_gp[["BP_enrich"]])
monocyte_up_treeplot <- sm(treeplot(monocyte_up_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_monocyte_up_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
monocyte_up_treeplot
dev.off()
## png 
##   2
monocyte_up_treeplot

3.2.3 Increased in cure

t_dream_monocyte_down_gp <- simple_gprofiler(
  monocyte_down_genes,
  excel = glue("excel/dream_monocyte_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
monocyte_down_termsim <- enrichplot::pairwise_termsim(t_dream_monocyte_down_gp[["BP_enrich"]])
monocyte_down_treeplot <- sm(treeplot(monocyte_down_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_monocyte_down_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
monocyte_down_treeplot
dev.off()
## png 
##   2
monocyte_down_treeplot

3.2.4 Increased in either

t_dream_monocyte_both_gp <- simple_gprofiler(
  monocyte_both_genes,
  excel = glue("excel/dream_monocyte_both_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
monocyte_both_termsim <- enrichplot::pairwise_termsim(t_dream_monocyte_both_gp[["BP_enrich"]])
monocyte_both_treeplot <- sm(treeplot(monocyte_both_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_monocyte_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
monocyte_both_treeplot
dev.off()
## png 
##   2
monocyte_both_treeplot

3.3 Neutrophils

3.3.1 Collecting gene sets

neutrophil_tbl <- table_reader(
  glue("excel/mixed_neutrophil_table-v{ver}.xlsx"),
  sheet = "failure_vs_cure")
## [1] 19952    22
neutrophil_sig_up_idx <- neutrophil_tbl[["logfc"]] >= 0.58 &
  neutrophil_tbl[["p_value"]] <= 0.05
neutrophil_sig_down_idx <- neutrophil_tbl[["logfc"]] <= -0.58 &
  neutrophil_tbl[["p_value"]] <= 0.05

neutrophil_up_genes <- rownames(neutrophil_tbl)[neutrophil_sig_up_idx]
neutrophil_down_genes <- rownames(neutrophil_tbl)[neutrophil_sig_down_idx]
neutrophil_both_genes <- c(neutrophil_up_genes, neutrophil_down_genes)

### Increased in fail
t_dream_neutrophil_up_gp <- simple_gprofiler(
  neutrophil_up_genes,
  excel = glue("excel/dream_neutrophil_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
neutrophil_up_termsim <- enrichplot::pairwise_termsim(t_dream_neutrophil_up_gp[["BP_enrich"]])
neutrophil_up_treeplot <- sm(treeplot(neutrophil_up_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_neutrophil_up_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
neutrophil_up_treeplot
dev.off()
## png 
##   2
neutrophil_up_treeplot

3.3.2 Increased in cure

t_dream_neutrophil_down_gp <- simple_gprofiler(
  neutrophil_down_genes,
  excel = glue("excel/dream_neutrophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
neutrophil_down_termsim <- enrichplot::pairwise_termsim(t_dream_neutrophil_down_gp[["BP_enrich"]])
neutrophil_down_treeplot <- sm(treeplot(neutrophil_down_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_neutrophil_down_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
neutrophil_down_treeplot
dev.off()
## png 
##   2
neutrophil_down_treeplot

3.3.3 Increased in either

t_dream_neutrophil_both_gp <- simple_gprofiler(
  neutrophil_both_genes,
  excel = glue("excel/dream_neutrophil_both_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
neutrophil_both_termsim <- enrichplot::pairwise_termsim(t_dream_neutrophil_both_gp[["BP_enrich"]])
neutrophil_both_treeplot <- sm(treeplot(neutrophil_both_termsim, label_format = wrap_width))
## Error in stats::cutree(hc, nCluster): elements of 'k' must be between 1 and 4
pp(file = glue("images/overrepresentation/t_dream_neutrophil_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
neutrophil_both_treeplot
## Error in eval(expr, envir, enclos): object 'neutrophil_both_treeplot' not found
dev.off()
## png 
##   2
neutrophil_both_treeplot
## Error in eval(expr, envir, enclos): object 'neutrophil_both_treeplot' not found

3.4 Eosinophils

3.4.1 Collect gene sets

eosinophil_tbl <- table_reader(
  glue("excel/mixed_eosinophil_table-v{ver}.xlsx"),
  sheet = "failure_vs_cure")
## [1] 19952    22
eosinophil_sig_up_idx <- eosinophil_tbl[["logfc"]] >= 0.58 &
  eosinophil_tbl[["p_value"]] <= 0.05
eosinophil_sig_down_idx <- eosinophil_tbl[["logfc"]] <= -0.58 &
  eosinophil_tbl[["p_value"]] <= 0.05

eosinophil_up_genes <- rownames(eosinophil_tbl)[eosinophil_sig_up_idx]
eosinophil_down_genes <- rownames(eosinophil_tbl)[eosinophil_sig_down_idx]
eosinophil_both_genes <- c(eosinophil_up_genes, eosinophil_down_genes)

3.4.2 Increased in fail

t_dream_eosinophil_up_gp <- simple_gprofiler(
  eosinophil_up_genes,
  excel = glue("excel/dream_eosinophil_up_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
eosinophil_up_termsim <- enrichplot::pairwise_termsim(t_dream_eosinophil_up_gp[["BP_enrich"]])
eosinophil_up_treeplot <- sm(treeplot(eosinophil_up_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_eosinophil_up_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
eosinophil_up_treeplot
dev.off()
## png 
##   2
eosinophil_up_treeplot

3.4.3 Increased in cure

t_dream_eosinophil_down_gp <- simple_gprofiler(
  eosinophil_down_genes,
  excel = glue("excel/dream_eosinophil_down_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
eosinophil_down_termsim <- enrichplot::pairwise_termsim(t_dream_eosinophil_down_gp[["BP_enrich"]])
eosinophil_down_treeplot <- sm(treeplot(eosinophil_down_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_eosinophil_down_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
eosinophil_down_treeplot
dev.off()
## png 
##   2
eosinophil_down_treeplot

3.4.4 Increased in either

t_dream_eosinophil_both_gp <- simple_gprofiler(
  eosinophil_both_genes,
  excel = glue("excel/dream_eosinophil_both_gp-v{ver}.xlsx"))
## Error in gprofiler_request(url, body) : 
##   There's an issue with your request to g:Profiler.
## Error code: 400. API message: No legal source provided. Saw ['KEGG']
## 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
eosinophil_both_termsim <- enrichplot::pairwise_termsim(t_dream_eosinophil_both_gp[["BP_enrich"]])
eosinophil_both_treeplot <- sm(treeplot(eosinophil_both_termsim, label_format = wrap_width))
pp(file = glue("images/overrepresentation/t_dream_eosinophil_both_gp_go-v{ver}.pdf"),
   height = treeplot_height, width = treeplot_width)
eosinophil_both_treeplot
dev.off()
## png 
##   2
eosinophil_both_treeplot

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+CgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShlbnJpY2hwbG90KQpsaWJyYXJ5KGdnc3RhdHNwbG90KQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoaHBnbHRvb2xzKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCB3aWR0aCA9IDkwLCBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVycm9yID0gVFJVRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDgsIGZpZy5yZXRpbmEgPSAyLAogIG91dC53aWR0aCA9ICIxMDAlIiwgZGV2ID0gInBuZyIsCiAgZGV2LmFyZ3MgPSBsaXN0KHBuZyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzID0gNCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBrbml0ci5kdXBsaWNhdGUubGFiZWwgPSAiYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplID0gMTIpKQp2ZXIgPC0gU3lzLmdldGVudigiVkVSU0lPTiIpCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdCA9ICIlWSVtJWQiKQpgYGAKCiMgUXVpY2sgeGxzeCByZWFkZXIgZnVuY3Rpb25zCgpNeSBmdW5jdGlvbnMgdG8gcGVyZm9ybSB0aGUgdmFyaW91cyBvdmVycmVwcmVzZW50YXRpb24vZW5yaWNobWVudAphbmFseXNlcyBnZW5lcmFsbHkgYXNzdW1lIHRoZSByZXN1bHQgb2YgZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygpIGFzCnRoZSBpbnB1dC4gIFNhZGx5LCBJIGRvIG5vdCB3YW50IHRvIHNhdmUgdGhvc2UgZGF0YSBzdHJ1Y3R1cmVzIHRvIGRpc2sKYmVjYXVzZSB0aGV5IGNhbiBiZSBxdWl0ZSBtb25zdHJvdXNseSBsYXJnZSB3aGVuIHNlcmlhbGl6ZWQgKGJlY2F1c2UgSQprZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSBpbnB1dCBpbiB0aGVtIHdoaWNoIGdldHMgZGVyZWZlcmVuY2VkIG9uCnNhdmUoKSkuICBBcyBhIHJlc3VsdCwgaXQgaXMgZmFyIHNpbXBsZXIvc2FmZXIgdG8ganVzdCByZWFkIHRoZSB4bHN4Cm91dHB1dHMgcHJvZHVjZWQgYnkgY29tYmluZV9kZV90YWJsZXMgYW5kIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMuCkVyZ28gdGhlIGZvbGxvd2luZyB0d28gbGl0dGxlIGZ1bmN0aW9ucy4KCmBgYHtyfQp0YWJsZV9yZWFkZXIgPC0gZnVuY3Rpb24oeGxzeCwgc2hlZXQgPSAib3V0Y29tZSIpIHsKICBpbnB1dF9kZiA8LSBvcGVueGxzeDo6cmVhZFdvcmtib29rKHhsc3gsIHNoZWV0ID0gc2hlZXQsIHN0YXJ0Um93ID0gMikKICByb3duYW1lcyhpbnB1dF9kZikgPC0gaW5wdXRfZGZbWyJyb3cubmFtZXMiXV0KICBpbnB1dF9kZltbInJvdy5uYW1lcyJdXSA8LSBOVUxMCiAgcHJpbnQoZGltKGlucHV0X2RmKSkKICBpZiAobnJvdyhpbnB1dF9kZikgPCA1MDAwKSB7CiAgICB3YXJuaW5nKCJTb21ldGhpbmcgYXBwZWFycyB3cm9uZyB3aXRoIHRoZSBkZSB0YWJsZTogIiwgaW5wdXRfeGxzeCkKICB9CiAgcmV0dXJuKGlucHV0X2RmKQp9CgpzaWdfcmVhZGVyIDwtIGZ1bmN0aW9uKHhsc3gsIHNoZWV0ID0gIm91dGNvbWUiLCBkaXJlY3Rpb24gPSAidXAiKSB7CiAgdGhpc19zaGVldCA8LSBwYXN0ZTAoZGlyZWN0aW9uLCAiX2Rlc2VxXyIsIHNoZWV0KQogIGlucHV0X2RmIDwtIG9wZW54bHN4OjpyZWFkV29ya2Jvb2soeGxzeCwgc2hlZXQgPSB0aGlzX3NoZWV0LCBzdGFydFJvdyA9IDIpCiAgcm93bmFtZXMoaW5wdXRfZGYpIDwtIGlucHV0X2RmW1sicm93Lm5hbWVzIl1dCiAgaW5wdXRfZGZbWyJyb3cubmFtZXMiXV0gPC0gTlVMTAogIGRpbShpbnB1dF9kZikKICBpZiAobnJvdyhpbnB1dF9kZikgPCAyMCkgewogICAgbWVzc2FnZSgiVGhlcmUgYXJlIGxlc3MgdGhhbiAyMCByb3dzIGluIHRoaXMgc2lnbmlmaWNhbmNlIHRhYmxlLCBpdCBpcyB1bmxpa2VseSB0byBiZSBpbnRlcmVzdGluZy4iKQogIH0KICByZXR1cm4oaW5wdXRfZGYpCn0KYGBgCgpJIGhhdmUgYmVlbiBoYXZpbmcgc29tZSBkaWZmaWN1bHRpZXMgZ2V0dGluZyB0aGUgdHJlZXBsb3QgZm9udHMgdG8KbWF0Y2ggb3VyIHJlYWRhYmlsaXR5IGdvYWxzLiAgVGhlIHNldCBvZiB0aGluZ3MgSSBoYXZlIHRyaWVkIHNvIGZhcgphcmU6CgoxLiAgU2V0dGluZyBhIGdlb21fdGV4dChzaXplID0geCk6IHRoaXMgZmFpbGVkIGJlY2F1c2UgaXQgZGlkbid0IGtub3cKICAgIHRvIHdoaWNoIGVsZW1lbnQocykgdG8gYXBwbHkgdGhlIG5ldyBzaXplLgoyLiAgQ2hhbmdpbmcgdGhlIG9wdGlvbnMgZm9yIHRoZW1lX2J3KCk6IHRoaXMgZG9lcyBjaGFuZ2Ugc29tZSBmb250CiAgICBlbGVtZW50cywgYnV0IG5vdCB0aGUgb25lcyB0aGF0IEkgd2FudGVkLiAgSSB0cmllZCBtb3JlIHRoYW4gYQogICAgZmV3LCBtb3N0IGltcG9ydGFudGx5IHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHgpKQozLiAgQ2hhbmdpbmcgdGhlIGRlZmF1bHQgZm9yIHRoZW1lX2J3IHZpYSB0aGVtZV91cGRhdGUodGV4dCA9CiAgICBlbGVtZW50X3RleHQoc2l6ZSA9IHgpKTogdGhpcyBhbHNvIGNoYW5nZXMgc29tZSB0ZXh0LCBidXQgbm90IGFsbC4KNC4gIEludm9raW5nIHVwZGF0ZV9nZW9tX2RlZmF1bHRzKCJ0ZXh0IiwgYWVzKHNpemUgPSAxMCkpIGF0IHRoZSBzdG9wCiAgICBvZiBteSBkb2N1bWVudC4gIFRoaXMgZG9lcyBub3Qgc2VlbSB0byBkbyBtdWNoIG9mIGFueXRoaW5nLgo1LiAgUGxheWluZyB3aXRoIG9wdGlvbnMgaW4gZW5yaWNocGxvdDo6dHJlZXBsb3QoKSwgbm90YWJseSB0aGUgY2V4CiAgICBhbmQgZm9udHNpemUgb3B0aW9ucy4gIFRoZXNlIGFsc28gaGVscCB3aXRoIHNvbWUsIGJ1dCBub3QgYWxsCiAgICBmb250cy4gIEkgYWxzbyBzcGVudCBhIGZhaXIgYW1vdW50IG9mIHRpbWUgcmVhZGluZyB0aGUgY29kZSBmb3IKICAgIHRyZWVwbG90KCkgYW5kIGRlY2lkZWQgdG8gdHJ5ICM2IGJlZm9yZSBJIGdvdCB0b28gZnJ1c3RyYXRlZC4KNi4gIEp1c3QgY2hhbmdpbmcgdGhlIGNhbnZhcyBzaXplIG9mIG15IG91dHB1dCBwZGYuICBUaGlzIHdvcmtlZAogICAgZ3JlYXQsIHRob3VnaCBpdCBtYXkgcmVxdWlyZSBzZXR0aW5nIHRoZSB3b3Jkd3JhcCBvcHRpb25zIGluCiAgICB0cmVlcGxvdC4KCldpdGggdGhhdCBpbiBtaW5kLCB0aGUgZm9sbG93aW5nIHR3byBwYXJhbWV0ZXJzIGFyZSBnb2luZyB0byBzZXQgdGhlCndpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIG91dHB1dCBwZGYgZG9jdW1lbnRzIHdoaWNoIHdpbGwgYmUgc2VudCB0bwpNYXJpYSBBZGVsYWlkYSBpbiBvcmRlciB0byBhcnJhbmdlIGludG8gdGhlIGZpbmFsIGZpZ3VyZXMgdmlhCmlua3NjYXBlLgoKYGBge3J9CnRyZWVwbG90X2hlaWdodCA8LSA2CnRyZWVwbG90X3dpZHRoIDwtIDEyCndyYXBfd2lkdGggPC0gMjQKZGVzaXJlZF9nb19vbnQgPC0gIkJQIgpgYGAKCiMgSW50cm9kdWN0aW9uCgpJIG9uY2UgYWdhaW4gbW92ZWQgdGhlIG9udG9sb2d5IGFuYWx5c2VzIHRvIHRoZWlyIG93biBkb2N1bWVudC4gIFRoaXMKaXMgcHJpbWFyaWx5IGJlY2F1c2UgSSB3YW50IGEgZnJlc2ggbm90ZWJvb2sgdG8gcGxheSBhcm91bmQgd2l0aCB0aGVzZQphbmQgZ2V0IHNvbWUgb2YgdGhlIHJlc3VsdGluZyBjbHV0dGVyIG91dCBvZiB0aGUgREUgbm90ZWJvb2tzLgoKVGhlIGNvbiBvZiBkb2luZyB0aGlzIGlzIHRoYXQgc29tZSBvZiBteSBlbnJpY2htZW50IG1ldGhvZHMgYXJlIHNtYXJ0CmVub3VnaCB0byBkaXJlY3RseSB0YWtlIHRoZSBvdXRwdXQgZnJvbQpjb21iaW5lX2RlX3RhYmxlcygpL2V4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoKS4gIEkgZ3Vlc3MgSSBjYW4KZGlzcGF0Y2ggYSBtZXRob2QgdG8gdGFrZSB0aGUgeGxzeCBmaWxlIGFzIGlucHV0Li4uCgpUaHVzLCBmb3IgZWFjaCBlbnJpY2htZW50IGFuYWx5c2lzIHRoYXQgX3dhc18gaW4gdGhlIGRpZmZlcmVudGlhbApleHByZXNzaW9uIGRvY3VtZW50cywgdGhlcmUgd2lsbCBub3cgYmUgYSBmZXcgc3RhbnphcyBoZXJlLCBvbmUKd2hpY2ggbG9hZHMgdGhlIGFwcHJvcHJpYXRlIHhsc3ggZmlsZSwgb25lIHdoaWNoIHBlcmZvcm1zIGdQcm9maWxlciwKYW5kIG9uZSB3aGljaCB1c2VzIGNsdXN0ZXJQcm9maWxlci4gIE9uIG9jY2FzaW9uIHRoZXJlIG1heSBiZSBhbm90aGVyCndpdGggcmFuZG9tIHN0dWZmIGxpa2UgbWUgcG9raW5nIGF0IHRyYW5zY3JpcHRpb24gZmFjdG9ycyBvciBvdGhlcgpzaWRlIGludGVyZXN0cy4uLgoKSW4gYWRkaXRpb24sIEkgYW0gZ29pbmcgdG8gZG8gdGhlIFR1bWFjby1vbmx5IGFuYWx5c2VzIGZpcnN0LCBiZWNhdXNlCnRoZXkgYXJlIHdoYXQgYXJlIGFjdHVhbGx5IGluIHRoZSBwYXBlci4KCiMjIEdlbmUgU2V0IEVucmljaG1lbnQKClRoZSBnZW5lIHNldCBlbnJpY2htZW50IHdpbGwgZm9sbG93IGVhY2ggREUgYW5hbHlzaXMgZHVyaW5nIHRoaXMKZG9jdW1lbnQuICBJIGFtIGFkZGluZyBhIHNlcmllcyBvZiBleHBsaWNpdGx5IEdTRUEgYW5hbHlzZXMgaW4gdGhpcwptb3N0IHJlY2VudCBpdGVyYXRpb24sIGluIHRoZXNlIEkgd2lsbCBwYXNzIHRoZSBmdWxsIERFIHRhYmxlIGFuZApjaGVjayB0aGUgZGlzdHJpYnV0aW9uIG9mIGxvZ0ZDIHZhbHVlcyBhZ2FpbnN0IHRoZSBnZW5lcyBpbiBlYWNoCmNhdGVnb3J5IGFzIG9wcG9zZWQgdG8gdGhlIHNpbXBsZXIgb3Zlci1lbnJpY2htZW50IG9mIHRoZSBoaWdoL2xvdyBERQpnZW5lcy4KCk1vc3QgKGFsbD8pIG9mIHRoZSBnZW5lIHNldCBlbnJpY2htZW50IGFuYWx5c2VzIHBlcmZvcm1lZCBpbiB0aGlzCmRvY3VtZW50IGFyZSBhIGNvbWJpbmF0aW9uIG9mIGdQcm9maWxlcjIKKEBrb2xiZXJnR3Byb2ZpbGVyMlBhY2thZ2VHZW5lMjAyMCkgYW5kIGNsdXN0ZXJQcm9maWxlcgooQHl1Q2x1c3RlclByb2ZpbGVyUGFja2FnZUNvbXBhcmluZzIwMTIpLiAgVGhlcmUgYXJlIGZ1bmN0aW9ucwphdmFpbGFibGUgaW4gaHBnbHRvb2xzIHRvIGFsc28gcGVyZm9ybSBhIGZldyBvdGhlciBtZXRob2RzLCBidXQgZm9yCnRoZSBtb21lbnQgSSBhbSBzdGlja2luZyB0byBvbmx5IHRoZXNlIHR3by4gIE9oIHllYWgsIEkgbmVlZCB0byB3cmFwCmNsdXN0ZXJQcm9maWxlcidzIHRyZWUgKHRha2VuIGZyb20gdG9wR08pIHBsb3R0ZXIgYmVjYXVzZSBpdCBzcGFtcwpwbG90cyBfZXZlcnl3aGVyZV8uLi4KCmBgYHtyfQp0Y19jbGluaWNhbF94bHN4IDwtIGdsdWUoImFuYWx5c2VzLzNfY2FsaV9hbmRfdHVtYWNvL0RFX0N1cmVfRmFpbC9DbGluaWNhbF9TYW1wbGVzL3RjX2NsaW5pY2FsX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCmFsbF9kZV9jZl90YWJsZSA8LSB0YWJsZV9yZWFkZXIodGNfY2xpbmljYWxfeGxzeCwgIm91dGNvbWUiKQoKYWxsX2RlX2NmX3VwIDwtIHNpZ19yZWFkZXIoZ2x1ZSgiYW5hbHlzZXMvM19jYWxpX2FuZF90dW1hY28vREVfQ3VyZV9GYWlsL0NsaW5pY2FsX1NhbXBsZXMvdGNfY2xpbmljYWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpLCAib3V0Y29tZSIsICJ1cCIpCmFsbF9kZV9jZl9kb3duIDwtIHNpZ19yZWFkZXIoZ2x1ZSgiYW5hbHlzZXMvM19jYWxpX2FuZF90dW1hY28vREVfQ3VyZV9GYWlsL0NsaW5pY2FsX1NhbXBsZXMvdGNfY2xpbmljYWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpLCAib3V0Y29tZSIsICJkb3duIikKYWxsX2RlX2NmIDwtIHJiaW5kLmRhdGEuZnJhbWUoYWxsX2RlX2NmX3VwLCBhbGxfZGVfY2ZfZG93bikKCnRfY2xpbmljYWxfeGxzeCA8LSBnbHVlKCJhbmFseXNlcy80X3R1bWFjby9ERV9DdXJlX0ZhaWwvdF9hbGxfdmlzaXRjZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9kZV9jZiA8LSBvcGVueGxzeDo6cmVhZFdvcmtib29rKHRfY2xpbmljYWxfeGxzeCwgc2hlZXQgPSAzLCBzdGFydFJvdyA9IDIpCnJvd25hbWVzKHRfZGVfY2YpIDwtIHRfZGVfY2ZbWyJyb3cubmFtZXMiXV0KdF9kZV9jZltbInJvdy5uYW1lcyJdXSA8LSBOVUxMCnRfZGVfY2ZfdXAgPC0gdF9kZV9jZlssIGMoImRlc2VxX2xvZ2ZjIiwgImRlc2VxX2FkanAiLCAiZGVzZXFfYmFzZW1lYW4iLCAiZGVzZXFfbGZjc2UiKV0KdF9kZV9jZiA8LSBvcGVueGxzeDo6cmVhZFdvcmtib29rKHRfY2xpbmljYWxfeGxzeCwgc2hlZXQgPSA0LCBzdGFydFJvdyA9IDIpCnJvd25hbWVzKHRfZGVfY2YpIDwtIHRfZGVfY2ZbWyJyb3cubmFtZXMiXV0KdF9kZV9jZltbInJvdy5uYW1lcyJdXSA8LSBOVUxMCnRfZGVfY2ZfZG93biA8LSB0X2RlX2NmWywgYygiZGVzZXFfbG9nZmMiLCAiZGVzZXFfYWRqcCIsICJkZXNlcV9iYXNlbWVhbiIsICJkZXNlcV9sZmNzZSIpXQp0X2RlX2NmIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9kZV9jZl91cCwgdF9kZV9jZl9kb3duKQpgYGAKCiMjIGdQcm9maWxlciBzZWFyY2ggb2YgYWxsIFR1bWFjbyBzYW1wbGVzCgpUaGUgZm9sbG93aW5nIGdQcm9maWxlciBzZWFyY2hlcyB1c2UgdGhlIGFsbF9ncHJvZmlsZXIoKSBmdW5jdGlvbgppbnN0ZWFkIG9mIHNpbXBsZV9ncHJvZmlsZXIoKS4gIEFzIGEgcmVzdWx0LCB0aGUgcmVzdWx0cyBhcmUgc2VwYXJhdGVkCmJ5IHtjb250cmFzdH1fe2RpcmVjdGlvbn0uICBUaHVzICdvdXRjb21lX2Rvd24nLgoKVGhlIHNhbWUgcGxvdHMgYXJlIGF2YWlsYWJsZSBhcyB0aGUgcHJldmlvdXMgZ1Byb2ZpbGVyIHNlYXJjaGVzLCBidXQKaW4gbWFueSBvZiB0aGUgZm9sbG93aW5nIHJ1bnMsIEkgdXNlZCB0aGUgZG90cGxvdCgpIGZ1bmN0aW9uIHRvIGdldCBhCnNsaWdodGx5IGRpZmZlcmVudCB2aWV3IG9mIHRoZSByZXN1bHRzLgoKIyMgU2hhcmVkIHBhdGhzCgpUaGVzZSBhcmUgdGhlIHBhdGhzIGZyb20gdGhlIERFIGRvY3VtZW50IGFuZCB3aGljaCB3aWxsIGJlIHVzZWQgdG8gZ2V0CnRoZSBpbnB1dHMgZm9yIGdwcm9maWxlci9jbHVzdGVycHJvZmlsZXIuCgpgYGB7cn0KeGxzeF9wcmVmaXggPC0gImFuYWx5c2VzLzRfdHVtYWNvIgpjZl9wcmVmaXggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9DdXJlX0ZhaWwiKQpgYGAKCiMjIEFsbCBUdW1hY28gY2xpbmljYWwgc2FtcGxlcyBjdXJlL2ZhaWwKClRoZSB4bHN4IGZpbGVzIGFyZToKCiogIntjZl9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IgoqICJ7Y2ZfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giCgpgYGB7cn0KdF9jbGluaWNhbF9jZl94bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jbGluaWNhbF9jZl90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKHRfY2xpbmljYWxfY2ZfeGxzeCwgIm91dGNvbWUiKQoKdF9jbGluaWNhbF9jZl9zaWdfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9BbGxfU2FtcGxlcy90X2NsaW5pY2FsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NsaW5pY2FsX2NmX3NpZ19zdmFfdXAgPC0gc2lnX3JlYWRlcih0X2NsaW5pY2FsX2NmX3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2xpbmljYWxfY2Zfc2lnX3N2YV9kb3duIDwtIHNpZ19yZWFkZXIodF9jbGluaWNhbF9jZl9zaWdfeGxzeCwgIm91dGNvbWUiLCAiZG93biIpCmBgYAoKQW5kIHdpdGhvdXQgYmlvcHNpZXMKCmBgYHtyfQp0X2NsaW5pY2FsX25vYmlvcF94bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfbm9iaW9wX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2xpbmljYWxuYl9jZl90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKHRfY2xpbmljYWxfbm9iaW9wX3hsc3gsICJvdXRjb21lIikKCnRfY2xpbmljYWxfbm9iaW9wX3NpZ194bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L0FsbF9TYW1wbGVzL3RfY2xpbmljYWxfbm9iaW9wX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NsaW5pY2FsbmJfY2Zfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKHRfY2xpbmljYWxfbm9iaW9wX3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcih0X2NsaW5pY2FsX25vYmlvcF9zaWdfeGxzeCwgIm91dGNvbWUiLCAiZG93biIpCnRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX2JvdGggPC0gcmJpbmQuZGF0YS5mcmFtZSh0X2NsaW5pY2FsbmJfY2Zfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX2Rvd24pCmBgYAoKIyMjIGdQcm9maWxlcgoKQWZ0ZXIgbW9zdCBvZiB0aGUgREUgYW5hbHlzZXMsIHRoZSBzZXQgb2Ygc2lnbmlmaWNhbnRseSBERSBnZW5lcyBnZXRzCnBhc3NlZCB0byBnUHJvZmlsZXIyIGFuZCBjbHVzdGVyUHJvZmlsZXIuICBPbmUgc2xpZ2h0bHkgbmVhdCB0aGluZyBpbgpteSBncHJvZmlsZXIgKGFuZCBnb3NlcS90b3BHTy9nb3N0YXRzKSBmdW5jdGlvbihzKTogaXQgY29lcmNlcyB0aGUKcmVzdWx0IGludG8gdGhlIHNhbWUgZGF0YXN0cnVjdHVyZSBwcm9kdWNlZCBieSBjbHVzdGVyUHJvZmlsZXIsIHRodXMKb25lIG1heSBwbGF5IHdpdGggdGhlIHZhcmlvdXMgcGxvdHRpbmcgZnVuY3Rpb25zIGluIHRoZSBlbnJpY2hwbG90CihAeXVJbnRyb2R1Y3Rpb25CaW9tZWRpY2FsS25vd2xlZGdlKSBwYWNrYWdlLiAgVGhpcyBpcyBraW5kIG9mIGZ1bgpiZWNhdXNlIGdQcm9maWxlcjIgcHJvdmlkZXMgZWFzeSBhY2Nlc3MgdG8gYSBmZXcgZGF0YXNldHM6CgoxLiBHTzogKEBhc2hidXJuZXJHZW5lT250b2xvZ3lUb29sMjAwMGEpCjIuIEtFR0c6IChAa2FuZWhpc2FLRUdHS3lvdG9FbmN5Y2xvcGVkaWEyMDAwKQozLiBSZWFjdG9tZTogKEBjcm9mdFJlYWN0b21lRGF0YWJhc2VSZWFjdGlvbnMyMDExKQo0LiBXaWtpUGF0aHdheXM6IChAa3V0bW9uV2lraVBhdGh3YXlzQ2FwdHVyaW5nRnVsbDIwMTYpCjUuIFRyYW5zZmFjOiAoQHdpbmdlbmRlclRSQU5TRkFDRGF0YWJhc2VUcmFuc2NyaXB0aW9uMTk5NikKNi4gbWlSVGFyQmFzZTogKEBoc3VNaVJUYXJCYXNlRGF0YWJhc2VDdXJhdGVzMjAxMSkKNy4gVGhlIEh1bWFuIFByb3RlaW4gQXRsYXM6IChAcG9udGVuSHVtYW5Qcm90ZWluQXRsYXMyMDExKQo4LiBDb3J1bTogKEBnaXVyZ2l1Q09SVU1Db21wcmVoZW5zaXZlUmVzb3VyY2UyMDE5KQo5LiBIdW1hbiBwaGVub3R5cGUgb250b2xvZ3k6IChAa29obGVySHVtYW5QaGVub3R5cGVPbnRvbG9neTIwMTcpCgojIyMjIEdlbmVzIGhpZ2hlciBpbiBjdXJlCgpNeSBnZW5lcmFsIHNlbnNlIGlzIHRoYXQgdGhlIGNvbXBhcmlzb25zIG9mIHByaW1hcnkgaW50ZXJlc3QgYXJlCnJlYWN0b21lIGFuZCBvbmUgb3IgbW9yZSBHTy4gIEkgc3VzcGVjdCB0aGF0IGlmIHRoZXJlIGFyZSBsb3RzIG9mCnRyYW5zY3JpcHRpb24gZmFjdG9ycywgdGhhdCBtaWdodCBwcm92ZSBpbnRlcmVzdGluZy4KCmBgYHtyfQp0X2NmX2NsaW5pY2FsX2dwX3VwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jbGluaWNhbF9jZl9zaWdfc3ZhX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9PdmVycmVwcmVzZW50YXRpb24vY2xpbmljYWxfY3VyZV91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2NsaW5pY2FsX2dwX3VwCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9jbGluaWNhbF9ncF91cFtbIkJQX2VucmljaCJdXSkKdF9jZl9jbGluaWNhbF9ncF9nb191cF90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KGdvX3Rlcm1zaW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9ICJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfY2xpbmljYWxfZ3BfdXBfdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxfZ3BfZ29fdXBfdHJlZQpkZXYub2ZmKCkKdF9jZl9jbGluaWNhbF9ncF9nb191cF90cmVlCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbF9ncF91cFtbIkJQX2VucmljaCJdXSkKCnJlYWN0b21lX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsX2dwX3VwW1siUkVBQ19lbnJpY2giXV0pCnRfY2ZfY2xpbmljYWxfZ3BfcmVhY191cF90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KHJlYWN0b21lX3Rlcm1zaW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbF9ncF91cF90cmVlLnBkZiIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKdF9jZl9jbGluaWNhbF9ncF9yZWFjX3VwX3RyZWUKZGV2Lm9mZigpCnRfY2ZfY2xpbmljYWxfZ3BfcmVhY191cF90cmVlCnBwKGZpbGUgPSAiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2NsaW5pY2FsX2dwX3VwX2RvdC5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbF9ncF91cFtbIlJFQUNfZW5yaWNoIl1dKQpkZXYub2ZmKCkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwX3VwW1siUkVBQ19lbnJpY2giXV0pCgp0Zl90ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9jbGluaWNhbF9ncF91cFtbIlRGX2VucmljaCJdXSkKIyMgVGhlIHRyZWVwbG90IGZhaWxzIGZvciB0aGlzIGZvciBzb21lIHJlYXNvbj8KIyN0X2NmX2NsaW5pY2FsX2dwX3RmX3VwX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QodGZfdGVybXNpbSkpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbF9ncF91cFtbIlRGX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2dwX3VwW1siV1BfZW5yaWNoIl1dKQpgYGAKCk5vIGJpb3BzaWVzIQoKYGBge3J9CnRfY2ZfY2xpbmljYWxuYl9ncF91cCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9PdmVycmVwcmVzZW50YXRpb24vY2xpbmljYWxuYl9jdXJlX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfY2xpbmljYWxuYl9ncF91cAoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxuYl9ncF91cFtbIkJQX2VucmljaCJdXSkKdF9jZl9jbGluaWNhbG5iX2dwX2dvX3VwX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QoZ29fdGVybXNpbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSAiZmlndXJlcy90X2NmX2NsaW5pY2FsbmJfZ3BfdXBfdHJlZS5zdmciLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb191cF90cmVlCmRldi5vZmYoKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fdXBfdHJlZQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxuYl9ncF91cFtbIkJQX2VucmljaCJdXSkKCnJlYWN0b21lX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsbmJfZ3BfdXBbWyJSRUFDX2VucmljaCJdXSkKdF9jZl9jbGluaWNhbG5iX2dwX3JlYWNfdXBfdHJlZSA8LSBzbShlbnJpY2hwbG90Ojp0cmVlcGxvdChyZWFjdG9tZV90ZXJtc2ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbG5iX2dwX3VwX3RyZWUucGRmIiwKICAgd2lkdGggPSB0cmVlcGxvdF93aWR0aCwgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0KQp0X2NmX2NsaW5pY2FsbmJfZ3BfcmVhY191cF90cmVlCmRldi5vZmYoKQp0X2NmX2NsaW5pY2FsbmJfZ3BfcmVhY191cF90cmVlCnBwKGZpbGUgPSAiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2NsaW5pY2FsbmJfZ3BfdXBfZG90LnBkZiIsCiAgIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgsIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsbmJfZ3BfdXBbWyJSRUFDX2VucmljaCJdXSkKZGV2Lm9mZigpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbG5iX2dwX3VwW1siUkVBQ19lbnJpY2giXV0pCgp0Zl90ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9jbGluaWNhbG5iX2dwX3VwW1siVEZfZW5yaWNoIl1dKQojIyBUaGUgdHJlZXBsb3QgZmFpbHMgZm9yIHRoaXMgZm9yIHNvbWUgcmVhc29uPwojI3RfY2ZfY2xpbmljYWxuYl9ncF90Zl91cF90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KHRmX3Rlcm1zaW0pKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxuYl9ncF91cFtbIlRGX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsbmJfZ3BfdXBbWyJXUF9lbnJpY2giXV0pCmBgYAoKIyMjIyBHZW5lcyBoaWdoZXIgaW4gZmFpbAoKVGhlIG9ubHkgc2lnbmlmaWNhbnQgcmVzdWx0cyBmb3IgdGhpcyBncm91cCBhcHBlYXIgdG8gYmUgR08uCgpgYGB7cn0KdF9jZl9jbGluaWNhbF9ncF9kb3duIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jbGluaWNhbF9jZl9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X092ZXJyZXByZXNlbnRhdGlvbi9jbGluaWNhbF9mYWlsX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfY2xpbmljYWxfZ3BfZG93bgoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxfZ3BfZG93bltbIkJQX2VucmljaCJdXSkKdF9jZl9jbGluaWNhbF9ncF9nb19kb3duX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QoZ29fdGVybXNpbSkpCnBwKGZpbGUgPSAiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2NsaW5pY2FsX2dwX2Rvd25fdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxfZ3BfZ29fZG93bl90cmVlCmRldi5vZmYoKQpgYGAKCk5vIGJpb3BzaWVzIQoKYGBge3J9CnRfY2ZfY2xpbmljYWxuYl9ncF9kb3duIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jbGluaWNhbG5iX2NmX3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfT3ZlcnJlcHJlc2VudGF0aW9uL2NsaW5pY2FsbmJfZmFpbF91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZG93bgoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfY2xpbmljYWxuYl9ncF9kb3duW1siQlBfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fZG93bl90cmVlIDwtIHNtKGVucmljaHBsb3Q6OnRyZWVwbG90KGdvX3Rlcm1zaW0pKQpwcChmaWxlID0gImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9jbGluaWNhbG5iX2dwX2Rvd25fdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb19kb3duX3RyZWUKZGV2Lm9mZigpCnRfY2ZfY2xpbmljYWxuYl9ncF9nb19kb3duX3RyZWUKYGBgCgojIyMjIEFuZCBnZW5lIGhpZ2hlciBpbiBlaXRoZXIKCmBgYHtyfQojIyBBbmQgYm90aCwgdGhpcyBpcyBub3QgdXN1YWxseSB3aGVyZSBJIHB1dCB0aGlzLCBidXQgdGhlCiMjIGNsaW5pY2FsIHNhbXBsZXMgYXJlIGEgYml0IG9mIGEgc3BlY2lhbCBjYXNlLgp0X2NmX2NsaW5pY2FsbmJfZ3BfYm90aCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2xpbmljYWxuYl9jZl9zaWdfc3ZhX2JvdGgsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X092ZXJyZXByZXNlbnRhdGlvbi9jbGluaWNhbG5iX2ZhaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9jbGluaWNhbG5iX2dwX2JvdGgKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsbmJfZ3BfYm90aFtbIkJQX2VucmljaCJdXSkKdF9jZl9jbGluaWNhbG5iX2dwX2dvX2JvdGhfdHJlZSA8LSBzbShlbnJpY2hwbG90Ojp0cmVlcGxvdChnb190ZXJtc2ltKSkKcHAoZmlsZSA9ICJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfY2xpbmljYWxuYl9ncF9ib3RoX3RyZWUucGRmIiwKICAgd2lkdGggPSB0cmVlcGxvdF93aWR0aCwgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0KQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fYm90aF90cmVlCmRldi5vZmYoKQp0X2NmX2NsaW5pY2FsbmJfZ3BfZ29fYm90aF90cmVlCgpyZWFjX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2NsaW5pY2FsbmJfZ3BfYm90aFtbIlJFQUNfZW5yaWNoIl1dKQp0X2NmX2NsaW5pY2FsbmJfZ3BfcmVhY19ib3RoX3RyZWUgPC0gc20oZW5yaWNocGxvdDo6dHJlZXBsb3QocmVhY190ZXJtc2ltKSkKcHAoZmlsZSA9ICJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfY2xpbmljYWxuYl9ncF9ib3RoX3JlYWNfdHJlZS5wZGYiLAogICB3aWR0aCA9IHRyZWVwbG90X3dpZHRoLCBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQpCnRfY2ZfY2xpbmljYWxuYl9ncF9yZWFjX2JvdGhfdHJlZQpkZXYub2ZmKCkKdF9jZl9jbGluaWNhbG5iX2dwX3JlYWNfYm90aF90cmVlCmBgYAoKIyMjIGNsdXN0ZXJQcm9maWxlcgoKVGhlIGZvbGxvd2luZyBlc3NlbnRpYWxseSByZXBlYXRzIHRoZSBnUHJvZmlsZXIyIGludm9jYXRpb24gdXNpbmcKY2x1c3RlclByb2ZpbGVyLiAgSSBoYXZlIGEgY291cGxlIG9mIGZ1bmN0aW9ucyB3aGljaCBjb21wYXJlIHRoZSBHTwpyZXN1bHRzIGZyb20gdmFyaW91cyBtZXRob2RzLCBwZXJoYXBzIEkgc2hvdWxkIGRpZyBpdCBvdXQgYW5kIHNlZSBob3cKc2ltaWxhciB0aGUgcmVzdWx0cyBhcmUgdXNpbmcgdGhlc2UgdHdvIHRvb2xzLiAgTXkgYXNzdW1wdGlvbiBpcyB0aGF0CnRoZSBwcmltYXJ5IGRpZmZlcmVuY2VzIHNob3VsZCBhcmlzZSBmcm9tIHRoZSBmYWN0IHRoYXQgZ1Byb2ZpbGVyCnRoZW9yZXRpY2FsbHkgaXMgdXBkYXRpbmcgdGhlaXIgR08gZGF0YSBvdmVyIHRpbWUgYW5kIGNQcm9maWxlciB1c2VzCnRoZSBpbmZvcm1hdGlvbiBpbiBvcmcuSHMuZWcuZGIsIHdoaWNoIGFmYWlrIGhhcyBub3QgY2hhbmdlZCBpbiBxdWl0ZQphIHdoaWxlLgoKIyMjIyBHZW5lcyBoaWdoZXIgaW4gY3VyZQoKYGBge3J9CnRfY2ZfY2xpbmljYWxfY3BfdXAgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0X2NsaW5pY2FsX2NmX3NpZ19zdmFfdXAsIGRlX3RhYmxlID0gdF9jbGluaWNhbF9jZl90YWJsZV9zdmEsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X092ZXJyZXByZXNlbnRhdGlvbi9jbGluaWNhbF9jdXJlX3VwX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9jbGluaWNhbF9jcF91cFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR2VuZXMgaGlnaGVyIGluIGZhaWwKCmBgYHtyfQp0X2NmX2NsaW5pY2FsX2NwX2Rvd24gPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0X2NsaW5pY2FsX2NmX3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfT3ZlcnJlcHJlc2VudGF0aW9uL2NsaW5pY2FsX2ZhaWxfdXBfY3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX2NwX2Rvd25bWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMjIEFuZCBib3RoIGhpZ2hlciBpbiBjdXJlIG9yIGZhaWwKCk5vdGUgdGhhdCBmb3IgYm90aCBJIGRpZCBub3QgYm90aGVyIHdpdGggdGhlIGFuYWx5c2lzIHRoYXQgaW5jbHVkZWQgYmlvcHNpZXMuCgpgYGB7cn0KdF9jZl9jbGluaWNhbG5iX2NwX2JvdGggPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0X2NsaW5pY2FsbmJfY2Zfc2lnX3N2YV9ib3RoLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9PdmVycmVwcmVzZW50YXRpb24vY2xpbmljYWxfZmFpbF91cF9jcC12e3Zlcn0ueGxzeCIpKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfY3BfYm90aFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR1NFQQoKR1NFQSBpcyBub3QgYXNzb2NpYXRlZCB3aXRoIGVpdGhlciB1cCBub3IgZG93biwgaXQgdGFrZXMgdGhlIHJhbmsKb3JkZXIgb2YgZ2VuZXMgd2l0aCByZXNwZWN0IChpbiB0aGlzIGNhc2UpIHRvIGZvbGQtY2hhbmdlLgoKYGBge3J9CnRfY2ZfY2xpbmljYWxfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfY2xpbmljYWxfY3BfdXApCnRfY2ZfY2xpbmljYWxfdG9wbl9nc2VhW1siR08iXV1bWzFdXQp0X2NmX2NsaW5pY2FsX3RvcG5fZ3NlYVtbIkdPIl1dW1syXV0KdF9jZl9jbGluaWNhbF90b3BuX2dzZWFbWyJHTyJdXVtbM11dCnRfY2ZfY2xpbmljYWxfdG9wbl9nc2VhW1siR08iXV1bWzRdXQp0X2NmX2NsaW5pY2FsX3RvcG5fZ3NlYVtbIkdPIl1dW1s1XV0KYGBgCgojIyBWaXNpdCAxIHZzLiBvdGhlciB2aXNpdHMKClRoZSByZWxldmFudCB4bHN4IGZpbGVzIGFyZToKCiogInt4bHN4X3ByZWZpeH0vREVfVmlzaXRzL3R2MV92c19sYXRlcl90YWJsZXMtdnt2ZXJ9Lnhsc3giCiogInt4bHN4X3ByZWZpeH0vREVfVmlzaXRzL3R2MV92c19sYXRlcl9zaWctdnt2ZXJ9Lnhsc3giCgpgYGB7cn0KdHYxX2xhdGVyX3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9WaXNpdHMvdHYxX3ZzX2xhdGVyX3RhYmxlcy12e3Zlcn0ueGxzeCIpCnR2MV92c19sYXRlcl90YWJsZSA8LSB0YWJsZV9yZWFkZXIodHYxX2xhdGVyX3hsc3gsICJsYXRlcl92c19maXJzdCIpCgp0djFfbGF0ZXJfc2lnX3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9WaXNpdHMvdHYxX3ZzX2xhdGVyX3NpZy12e3Zlcn0ueGxzeCIpCnR2MV92c19sYXRlcl91cF9zaWcgPC0gc2lnX3JlYWRlcih0djFfbGF0ZXJfc2lnX3hsc3gsICJsYXRlcl92c19maXJzdCIpCnR2MV92c19sYXRlcl9kb3duX3NpZyA8LSBzaWdfcmVhZGVyKHR2MV9sYXRlcl9zaWdfeGxzeCwgImxhdGVyX3ZzX2ZpcnN0IiwgImRvd24iKQp0djFfdnNfbGF0ZXJfYm90aCA8LSByYmluZC5kYXRhLmZyYW1lKHR2MV92c19sYXRlcl91cF9zaWcsIHR2MV92c19sYXRlcl9kb3duX3NpZykKYGBgCgojIyMgSW5jcmVhc2VkIGluIHZpc2l0IDEKCkkgYW0gbm90IGxpa2VseSB0byBkbyB0aGUgZGVjcmVhc2VkIGluIHZpc2l0IDEsIHRoZXJlIGFyZSBvbmx5IDcgZ2VuZXMuCgojIyMjIGVucmljaG1lbnQ6IGdQcm9maWxlciBpbmNyZWFzZWQgaW4gdmlzaXQgMQoKYGBge3J9CnR2MWxhdGVyX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdHYxX3ZzX2xhdGVyX3VwX3NpZywKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90djFfdnNfbGF0ZXJfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdHYxbGF0ZXJfdXBfZ3AKCmVucmljaHBsb3Q6OmRvdHBsb3QodHYxbGF0ZXJfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodHYxbGF0ZXJfdXBfZ3BbWyJSRUFDX2VucmljaCJdXSkKYGBgCgojIyMjIGluY3JlYXNlZCBhbmQgZGVjcmVhc2VkIGluIHZpc2l0IDEKCmBgYHtyfQp0djFsYXRlcl9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdHYxX3ZzX2xhdGVyX2JvdGgsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdHYxX3ZzX2xhdGVyX2JvdGhfZ3Atdnt2ZXJ9Lnhsc3giKSkKdHYxbGF0ZXJfYm90aF9ncAoKZW5yaWNocGxvdDo6ZG90cGxvdCh0djFsYXRlcl9ib3RoX2dwW1siQlBfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHR2MWxhdGVyX2JvdGhfZ3BbWyJSRUFDX2VucmljaCJdXSkKYGBgCgojIyMjIGVucmljaG1lbnQ6IGNsdXN0ZXJQcm9maWxlcgoKTm90ZSB0byBzZWxmOiBtYWtlIHNvbWUgY2xhc3NlcyBmb3IgcGxvdF90b3BuX2dzZWEgc28gaXQgY2FuIGhhbmRsZQp0aGUgdmFyaW91cyBpbnB1dHMgaXQgaXMgbGlrZWx5IHRvIHJlY2VpdmUuCgpgYGB7cn0KdHYxbGF0ZXJfdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0djFfdnNfbGF0ZXJfdXBfc2lnLCBkZV90YWJsZSA9IHR2MV92c19sYXRlcl90YWJsZSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLCBrZWdnX3ByZWZpeCA9ICJocyIsIGRvX2tlZ2cgPSBUUlVFKQplbnJpY2hwbG90Ojpkb3RwbG90KHR2MWxhdGVyX3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJNRl9hbGwiXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodHYxbGF0ZXJfdXBfY3BbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKCndyaXR0ZW4gPC0gd3JpdGVfY3BfZGF0YSgKICB0djFsYXRlcl91cF9jcCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90djFfdnNfbGF0ZXJfdXBfY3Atdnt2ZXJ9Lnhsc3giKSkKYGBgCgpgYGB7cn0KdHYxbGF0ZXJfYm90aF9jcCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIHR2MV92c19sYXRlcl9ib3RoLCBkZV90YWJsZSA9IHR2MV92c19sYXRlcl90YWJsZSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLCBrZWdnX3ByZWZpeCA9ICJocyIsIGRvX2tlZ2cgPSBUUlVFKQplbnJpY2hwbG90Ojpkb3RwbG90KHR2MWxhdGVyX2JvdGhfY3BbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIk1GX2FsbCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0djFsYXRlcl9ib3RoX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCgp3cml0dGVuIDwtIHdyaXRlX2NwX2RhdGEoCiAgdHYxbGF0ZXJfYm90aF9jcCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90djFfdnNfbGF0ZXJfYm90aF9jcC12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyMgR1NFQTogY2x1c3RlclByb2ZpbGVyCgpgYGB7cn0KdHYxbGF0ZXJfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHR2MWxhdGVyX3VwX2NwKQp0djFsYXRlcl90b3BuX2dzZWFbWyJHTyJdXVtbMV1dCnR2MWxhdGVyX3RvcG5fZ3NlYVtbIkdPIl1dW1syXV0KYGBgCgojIyBQYXRpZW50IFNleAoKVGhlIHJlbGV2YW50IGlucHV0IHhsc3ggZmlsZXMgYXJlOgoKKiB7eGxzeF9wcmVmaXh9L0RFX1NleC90X3NleF90YWJsZS12e3Zlcn0ueGxzeCIpKQoqIHt4bHN4X3ByZWZpeH0vREVfU2V4L3Rfc2V4X3NpZy12e3Zlcn0ueGxzeCIpKQoKT2gsIEkgbWVzc2VkIHVwIGFuZCBwdXQgdGhlIERFIHJlc3VsdHMgaW4gdGhlIEdTRUEgZGlyZWN0b3J5IQoKTGV0IHVzIHNlZSBpZiB3ZSBvYnNlcnZlIGdlbmVyYWwgbWFsZS9mZW1hbGUgZGlmZmVyZW5jZXMgaW4gdGhlIGRhdGEuClRoaXMgaGFzIGFuIGltcG9ydGFudCBjYXZlYXQ6IHRoZXJlIGFyZSBmZXcgZmVtYWxlIGZhaWx1cmVzIGluIHRoZQpkYXRhc2V0IGFuZCBzbyB0aGUgcmVzdWx0cyBtYXkgcmVmbGVjdCB0aGF0LgoKYGBge3J9CnRfc2V4X3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9TZXgvdF9zZXhfY3VyZV90YWJsZS12e3Zlcn0ueGxzeCIpCnRfc2V4X3RhYmxlIDwtIHRhYmxlX3JlYWRlcih0X3NleF94bHN4LCAibWFsZV92c19mZW1hbGUiKQoKdF9zZXhfc2lnX3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9TZXgvdF9zZXhfY3VyZV9zaWctdnt2ZXJ9Lnhsc3giKQp0X3NleF91cF9zaWcgPC0gc2lnX3JlYWRlcih0X3NleF9zaWdfeGxzeCwgIm1hbGVfdnNfZmVtYWxlIikKdF9zZXhfZG93bl9zaWcgPC0gc2lnX3JlYWRlcih0X3NleF9zaWdfeGxzeCwgIm1hbGVfdnNfZmVtYWxlIiwgImRvd24iKQp0X3NleF9ib3RoX3NpZyA8LSByYmluZC5kYXRhLmZyYW1lKHRfc2V4X3VwX3NpZywgdF9zZXhfZG93bl9zaWcpCmBgYAp4CiMjIyBnUHJvZmlsZXIKCiMjIyMgSW5jcmVhc2VkIGluIG1lbgoKYGBge3J9CnRfc2V4X3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9zZXhfdXBfc2lnLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3NleF9tYWxlX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfc2V4X3VwX2dwCgplbnJpY2hwbG90Ojpkb3RwbG90KHRfc2V4X3VwX2dwW1siQlBfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfc2V4X3VwX2dwW1siUkVBQ19lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9zZXhfdXBfZ3BbWyJURl9lbnJpY2giXV0pCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gd29tZW4KCmBgYHtyfQp0X3NleF9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9zZXhfZG93bl9zaWcsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvc2V4X2ZlbWFsZV91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X3NleF9kb3duX2dwCmBgYAoKIyMjIyBJbiBlaXRoZXIKCmBgYHtyfQp0X3NleF9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9zZXhfYm90aF9zaWcsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvc2V4X2ZlbWFsZV91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X3NleF9ib3RoX2dwCmBgYAoKR2l2ZW4gdGhlIHJlc3VsdHMgZnJvbSBnUHJvZmlsZXIsIEkgZG8gbm90IGhhdmUgaGlnaCBleHBlY3RhdGlvbnMgZm9yCmNsdXN0ZXJQcm9maWxlciwgc28gSSBhbSBub3QgbGlrZWx5IHRvIHRha2UgdGhlIHRpbWUgdG8gd3JpdGUgdGhlbSBvdXQuCkl0IHNlZW1zIGxpa2UgbWFsZS9mZW1hbGUgaXMgY29uZm91bmRlZCB3aXRoIGN1cmUvZmFpbC4KCiMjIyBjbHVzdGVyUHJvZmlsZXIKCiMjIyMgSW5jcmVhc2VkIGluIG1lbgoKYGBge3J9CnRfc2V4X3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9zZXhfdXBfc2lnLCBkZV90YWJsZSA9IHRfc2V4X3RhYmxlLAogIG9yZ2RiID0gIm9yZy5Icy5lZy5kYiIsIGtlZ2dfcHJlZml4ID0gImhzIiwgZG9fa2VnZyA9IFRSVUUpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9zZXhfdXBfY3BbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMjIEluY3JlYXNlZCBpbiB3b21lbgoKYGBge3J9CnRfc2V4X2Rvd25fY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0X3NleF9kb3duX3NpZywgZGVfdGFibGUgPSB0X3NleF90YWJsZSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLCBrZWdnX3ByZWZpeCA9ICJocyIsIGRvX2tlZ2cgPSBUUlVFKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfc2V4X2Rvd25fY3BbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMgRWl0aGVyCgpgYGB7cn0KdF9zZXhfYm90aF9jcCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIHRfc2V4X2JvdGhfc2lnLCBkZV90YWJsZSA9IHRfc2V4X3RhYmxlLAogIG9yZ2RiID0gIm9yZy5Icy5lZy5kYiIsIGtlZ2dfcHJlZml4ID0gImhzIiwgZG9fa2VnZyA9IFRSVUUpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9zZXhfYm90aF9jcFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR1NFQQoKYGBge3J9CnRfc2V4X3RvcG5fZ3NlYSA8LSBwbG90X3RvcG5fZ3NlYSh0X3NleF91cF9jcCkKdF9zZXhfdG9wbl9nc2VhW1siR08iXV1bWzFdXQpgYGAKCiMjIEV0aG5pY2l0eQoKT25jZSBhZ2FpbiwgdGhlIHJlbGV2YW50IGZpbGVzIHRvIGxvYWQ6CgoqICJ7eGxzeF9wcmVmaXh9L0RFX0V0aG5pY2l0eS90X2V0aG5pY2l0eV90YWJsZS12e3Zlcn0ueGxzeCIKKiAie3hsc3hfcHJlZml4fS9ERV9FdGhuaWNpdHkvdF9ldGhuaWNpdHlfc2lnLXZ7dmVyfS54bHN4IgoKYGBge3J9CnRfZXRobmljaXR5X3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9FdGhuaWNpdHkvdF9ldGhuaWNpdHlfdGFibGUtdnt2ZXJ9Lnhsc3giKQp0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXMgPC0gdGFibGVfcmVhZGVyKHRfZXRobmljaXR5X3hsc3gsICJtZXN0aXpvX2luZGlnZW5vdXMiKQp0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2wgPC0gdGFibGVfcmVhZGVyKHRfZXRobmljaXR5X3hsc3gsICJtZXN0aXpvX2Fmcm9jb2wiKQp0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2wgPC0gdGFibGVfcmVhZGVyKHRfZXRobmljaXR5X3hsc3gsICJpbmRpZ2Vub3VzX2Fmcm9jb2wiKQoKdF9ldGhuaWNpdHlfc2lnX3hsc3ggPC0gZ2x1ZSgie3hsc3hfcHJlZml4fS9ERV9FdGhuaWNpdHkvdF9ldGhuaWNpdHlfc2lnLXZ7dmVyfS54bHN4IikKdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzX3VwIDwtIHNpZ19yZWFkZXIodF9ldGhuaWNpdHlfc2lnX3hsc3gsICJtZXN0aXpvX2luZGlnZW5vdXMiKQp0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXNfZG93biA8LSBzaWdfcmVhZGVyKHRfZXRobmljaXR5X3NpZ194bHN4LCAibWVzdGl6b19pbmRpZ2Vub3VzIiwgImRvd24iKQp0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfdXAgPC0gc2lnX3JlYWRlcih0X2V0aG5pY2l0eV9zaWdfeGxzeCwgIm1lc3Rpem9fYWZyb2NvbCIpCnRfZXRobmljaXR5X21lc3Rpem9fYWZyb2NvbF9kb3duIDwtIHNpZ19yZWFkZXIodF9ldGhuaWNpdHlfc2lnX3hsc3gsICJtZXN0aXpvX2Fmcm9jb2wiLCAiZG93biIpCnRfZXRobmljaXR5X2luZGlnZW5vdXNfYWZyb2NvbF91cCA8LSBzaWdfcmVhZGVyKHRfZXRobmljaXR5X3NpZ194bHN4LCAiaW5kaWdlbm91c19hZnJvY29sIikKdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sX2Rvd24gPC0gc2lnX3JlYWRlcih0X2V0aG5pY2l0eV9zaWdfeGxzeCwgImluZGlnZW5vdXNfYWZyb2NvbCIsICJkb3duIikKdF9ldGhuaWNpdHlfYW55IDwtIHJiaW5kLmRhdGEuZnJhbWUoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzX3VwLAogIHRfZXRobmljaXR5X21lc3Rpem9faW5kaWdlbm91c19kb3duLAogIHRfZXRobmljaXR5X21lc3Rpem9fYWZyb2NvbF91cCwKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfZG93biwKICB0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2xfdXAsCiAgdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sX2Rvd24pCmBgYAoKIyMjIGdQcm9maWxlcgoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBpbmRpZ2Vub3VzCgpgYGB7cn0KbWVzdGl6b19pbmRpZ2Vub3VzX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L2V0aG5pY2l0eV9taV91cF9ncC12e3Zlcn0ueGxzeCIpKQptZXN0aXpvX2luZGlnZW5vdXNfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBpbmRpZ2Vub3VzIHZzIG1lc3Rpem8KCmBgYHtyfQppbmRpZ2Vub3VzX21lc3Rpem9fdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXNfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9ldGhuaWNpdHlfaW1fdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKaW5kaWdlbm91c19tZXN0aXpvX3VwX2dwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KbWVzdGl6b19hZnJvY29sX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19hZnJvY29sX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L2V0aG5pY2l0eV9tYV91cF9ncC12e3Zlcn0ueGxzeCIpKQptZXN0aXpvX2Fmcm9jb2xfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIG1lc3Rpem8KCmBgYHtyfQphZnJvY29sX21lc3Rpem9fdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9ldGhuaWNpdHlfYW1fdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKYWZyb2NvbF9tZXN0aXpvX3VwX2dwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gaW5kaWdlbm91cyB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KaW5kaWdlbm91c19hZnJvY29sX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L2V0aG5pY2l0eV9pYV91cF9ncC12e3Zlcn0ueGxzeCIpKQppbmRpZ2Vub3VzX2Fmcm9jb2xfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIGluZGlnZW5vdXMKCmBgYHtyfQphZnJvY29sX2luZGlnZW5vdXNfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2xfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC9ldGhuaWNpdHlfYWlfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKYWZyb2NvbF9pbmRpZ2Vub3VzX3VwX2dwCmBgYAoKIyMjIyBDaGFuZ2VkIGluIGFueSBncm91cAoKYGBge3J9CmV0aG5pY2l0eV9hbnlfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2V0aG5pY2l0eV9hbnksCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvZXRobmljaXR5X2FueV9ncC12e3Zlcn0ueGxzeCIpKQpldGhuaWNpdHlfYW55X2dwCgplbnJpY2hwbG90Ojpkb3RwbG90KGV0aG5pY2l0eV9hbnlfZ3BbWyJCUF9lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QoZXRobmljaXR5X2FueV9ncFtbIlJFQUNfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KGV0aG5pY2l0eV9hbnlfZ3BbWyJURl9lbnJpY2giXV0pCmBgYAoKIyMjIGNsdXN0ZXJQcm9maWxlcgoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBpbmRpZ2Vub3VzCgpgYGB7cn0KbWVzdGl6b19pbmRpZ2Vub3VzX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzX3VwLAogIGRlX3RhYmxlID0gdF9ldGhuaWNpdHlfbWVzdGl6b19pbmRpZ2Vub3VzKQptZXN0aXpvX2luZGlnZW5vdXNfdXBfY3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBpbmRpZ2Vub3VzIHZzIG1lc3Rpem8KCmBgYHtyfQppbmRpZ2Vub3VzX21lc3Rpem9fdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICB0X2V0aG5pY2l0eV9tZXN0aXpvX2luZGlnZW5vdXNfZG93bikKaW5kaWdlbm91c19tZXN0aXpvX3VwX2NwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gbWVzdGl6byB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KbWVzdGl6b19hZnJvY29sX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfbWVzdGl6b19hZnJvY29sX3VwLAogIGRlX3RhYmxlID0gdF9ldGhuaWNpdHlfbWVzdGl6b19hZnJvY29sKQptZXN0aXpvX2Fmcm9jb2xfdXBfY3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIG1lc3Rpem8KCmBgYHtyfQphZnJvY29sX21lc3Rpem9fdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0X2V0aG5pY2l0eV9tZXN0aXpvX2Fmcm9jb2xfZG93bikKYWZyb2NvbF9tZXN0aXpvX3VwX2NwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gaW5kaWdlbm91cyB2cyBhZnJvY29sb21iaWFuCgpgYGB7cn0KaW5kaWdlbm91c19hZnJvY29sX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAgdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sX3VwLAogIGRlX3RhYmxlID0gdF9ldGhuaWNpdHlfaW5kaWdlbm91c19hZnJvY29sKQppbmRpZ2Vub3VzX2Fmcm9jb2xfdXBfY3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBhZnJvY29sb21iaWFuIHZzIGluZGlnZW5vdXMKCmBgYHtyfQphZnJvY29sX2luZGlnZW5vdXNfdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0X2V0aG5pY2l0eV9pbmRpZ2Vub3VzX2Fmcm9jb2xfZG93bikKYWZyb2NvbF9pbmRpZ2Vub3VzX3VwX2NwCmBgYAoKIyMgVmlzaXQgMSBjdXJlL2ZhaWwKCkl0IGxvb2tzIGxpa2UgdGhlcmUgYXJlIHZlcnkgZmV3IGdyb3VwcyBpbiB0aGUgdmlzaXQgMSBzaWduaWZpY2FudApnZW5lcy4KClRoZSByZWxldmFudCB4bHN4IGZpbGVzIGFyZToKCiogIntjZl9wcmVmaXh9L1Zpc2l0cy90X2NsaW5pY2FsX3YxX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIKKiAie2NmX3ByZWZpeH0vVmlzaXRzL3RfY2xpbmljYWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIKCmBgYHtyfQp0X2NsaW5pY2FsX3YxX3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vVmlzaXRzL3RfY2xpbmljYWxfdjFfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9jbGluaWNhbF92MV90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKHRfY2xpbmljYWxfdjFfeGxzeCkKCnRfY2xpbmljYWxfdjFfc2lnX3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vVmlzaXRzL3RfY2xpbmljYWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKHRfY2xpbmljYWxfdjFfc2lnX3hsc3gsICJvdXRjb21lIikKdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcih0X2NsaW5pY2FsX3YxX3NpZ194bHN4LCAib3V0Y29tZSIsICJkb3duIikKdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2JvdGggPC0gcmJpbmQuZGF0YS5mcmFtZSgKICB0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXAsCiAgdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd24pCmBgYAoKIyMjIGdQcm9maWxlcgoKIyMjIyBJbmNyZWFzZWQgaW4gdmlzaXQgMSBjdXJlL2ZhaWwKCmBgYHtyfQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcih0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfdXApCnRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV91cF9ncApgYGAKCiMjIyMgSW5jcmVhc2VkIGluIHZpc2l0IDEgZmFpbC9jdXJlCgpgYGB7cn0KdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcih0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfZG93bikKdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd25fZ3AKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfZG93bl9ncFtbIkJQX2VucmljaCJdXSkKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBlaXRoZXIKCmBgYHtyfQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfYm90aF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9ib3RoKQp0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfYm90aF9ncAplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV9ib3RoX2dwW1siQlBfZW5yaWNoIl1dKQpgYGAKCiMjIyBjbHVzdGVyUHJvZmlsZXIKCiMjIyMgSW5jcmVhc2VkIHZpc2l0IDEgY3VyZS9mYWlsCgpgYGB7cn0KdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwX2NwIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwLAogIGRlX3RhYmxlID0gdF9jZl9jbGluaWNhbF92MV90YWJsZV9zdmEsCiAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIikKdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX3VwX2NwCgplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfY2xpbmljYWxfdjFfc2lnX3N2YV91cF9jcFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgSW5jcmVhc2VkIGluIHZpc2l0IDEgY3VyZS9mYWlsCgpgYGB7cn0KdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2Rvd25fY3AgPC0gc2ltcGxlX2Nwcm9maWxlcigKICB0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfZG93biwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiKQpgYGAKCiMjIyMgRWl0aGVyIGluY3JlYXNlZCBvciBkZWNyZWFzZWQgdjEgYy9mCgpgYGB7cn0KdF9jZl9jbGluaWNhbF92MV9zaWdfc3ZhX2JvdGhfY3AgPC0gc2ltcGxlX2Nwcm9maWxlcigKICB0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfYm90aCwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiKQoKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2NsaW5pY2FsX3YxX3NpZ19zdmFfYm90aF9jcFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR1NFQQoKSXQgYXBwZWFycyB0aGVyZSBhcmUgdG9vIGZldyByZXN1bHRzIHRvIHBlcmZvcm0gdGhlIGdzZWEgcGxvdHMuCgojIyBDdXJlL0ZhaWwsIEJpb3BzaWVzCgpUaGUgcmVsZXZhbnQgeGxzeCBvdXRwdXQgbWF5IGJlIGZvdW5kIGF0OgoKKiAie2NmX3ByZWZpeH0vQmlvcHNpZXMvdF9iaW9wc3lfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IgoqICJ7Y2ZfcHJlZml4fS9CaW9wc2llcy90X2NmX2Jpb3BzeV9zaWdfc3ZhLXZ7dmVyfS54bHN4IgoKYGBge3J9CnRfYmlvcHN5X3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vQmlvcHNpZXMvdF9iaW9wc3lfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9iaW9wc3lfdGFibGVfc3ZhIDwtIHRhYmxlX3JlYWRlcih0X2Jpb3BzeV94bHN4LCAib3V0Y29tZSIpCgp0X2Jpb3BzeV9zaWdfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9CaW9wc2llcy90X2NmX2Jpb3BzeV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9iaW9wc3lfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKHRfYmlvcHN5X3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2ZfYmlvcHN5X3NpZ19zdmFfZG93biA8LSBzaWdfcmVhZGVyKHRfYmlvcHN5X3NpZ194bHN4LCAib3V0Y29tZSIsICJkb3duIikKdF9jZl9iaW9wc3lfc2lnX3N2YV9ib3RoIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9jZl9iaW9wc3lfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jZl9iaW9wc3lfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBnUHJvZmlsZXIKCldlIG9ubHkgaGF2ZSAxNyBnZW5lcyBpbiB0aGUgYmlvcHNpZXMsIGJ1dCBwZXJoYXBzIHRoZXkgYXJlIHN0aWxsIGludGVyZXN0aW5nPwoKIyMjIyBpbmNyZWFzZWQgaW4gY3VyZSB2cyBmYWlsCgpgYGB7cn0KdF9jZl9iaW9wc3lfc2lnX3N2YV9ncF91cCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfYmlvcHN5X3NpZ19zdmFfdXAsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9iaW9wc3lfc2lnX3N2YV91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwX3VwCgplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfYmlvcHN5X3NpZ19zdmFfZ3BfdXBbWyJCUF9lbnJpY2giXV0pCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwX3VwW1siQlBfZW5yaWNoIl1dKQpnb190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChnb190ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9iaW9wc3lfdXBfZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmdvX3RyZWVwbG90CmRldi5vZmYoKQpnb190cmVlcGxvdApgYGAKCiMjIyMgaW5jcmVhc2VkIGluIGZhaWwgdnMgY3VyZQoKYGBge3J9CnRfY2ZfYmlvcHN5X3NpZ19zdmFfZ3BfZG93biA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfYmlvcHN5X3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX2Jpb3BzeV9zaWdfc3ZhX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9iaW9wc3lfc2lnX3N2YV9ncF9kb3duCgojIyBOb3QgbmVhcmx5IGFzIGludGVyZXN0aW5nCmBgYAoKIyMjIyBpbmNyZWFzZWQgaW4gZWl0aGVyCgpgYGB7cn0KdF9jZl9iaW9wc3lfc2lnX3N2YV9ncF9ib3RoIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9iaW9wc3lfc2lnX3N2YV9ib3RoLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfYmlvcHN5X3NpZ19zdmFfYm90aF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwX2JvdGgKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Jpb3BzeV9zaWdfc3ZhX2dwX2JvdGhbWyJCUF9lbnJpY2giXV0pCmBgYAoKIyMjIGNsdXN0ZXJwcm9maWxlcgoKQWdhaW4sIGNsdXN0ZXJwcm9maWxlciB2ZXJzaW9uCgojIyMjIGluY3JlYXNlZCBpbiBjdXJlL2ZhaWwKCmBgYHtyfQp0X2NmX2Jpb3BzeV9zaWdfc3ZhX2NwX3VwIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9iaW9wc3lfc2lnX3N2YV91cCwgZGVfdGFibGUgPSB0X2NmX2Jpb3BzeV90YWJsZV9zdmEsCiAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIiwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX2Jpb3BzeV9zaWdfc3ZhX3VwX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9iaW9wc3lfc2lnX3N2YV9jcF91cFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgR1NFQSBvZiBjdXJlL2ZhaWwKCmBgYHtyfQp0X2NmX2Jpb3BzeV9zaWdfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfYmlvcHN5X3NpZ19zdmFfY3BfdXApCnRfY2ZfYmlvcHN5X3NpZ190b3BuX2dzZWFbWyJHT19vdXRjb21lX3VwIl1dW1sxXV0KYGBgCgojIyBFb3Npbm9waGlscyBjdXJlL2ZhaWwKCmBgYHtyfQp0X2Vvc2lub3BoaWxfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9lb3Npbm9waGlsX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIodF9lb3Npbm9waGlsX3hsc3gsICJvdXRjb21lIikKCnRfZW9zaW5vcGhpbF9zaWdfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIodF9lb3Npbm9waGlsX3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcih0X2Vvc2lub3BoaWxfc2lnX3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9ib3RoIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBnUHJvZmlsZXIKCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXAsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9lb3Npbm9waGlsX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwX2dwCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXBfZ3BbWyJURl9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmdvX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGdvX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gImZpZ3VyZXMvdF9jZl9lb3Npbm9waGlsX3VwX2dwX2dvLnN2ZyIsCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CgpyZWFjX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV91cF9ncFtbIlJFQUNfZW5yaWNoIl1dKQpyZWFjX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KHJlYWNfdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfZW9zaW5vcGhpbF91cF9ncF9yZWFjLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpyZWFjX3RyZWVwbG90CmRldi5vZmYoKQpgYGAKCiMjIyMgaW5jcmVhc2VkIGluIGZhaWwgdnMgY3VyZQoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9kb3duLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9kb3duX2dwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZG93bl9ncFtbIkJQX2VucmljaCJdXSkKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9kb3duX2dwW1siQlBfZW5yaWNoIl1dKQpnb190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChnb190ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9jZl9lb3Npbm9waGlsX2Rvd25fZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmdvX3RyZWVwbG90CmRldi5vZmYoKQpnb190cmVlcGxvdAoKIyMgVGhlcmUgaXMgb25seSBvbmUgcmVhY3RvbWUgaGl0LCBzbyBub3QgcGxvdHRpbmcgaXQuCmBgYAoKIyMjIyBCb3RoIHVwIGFuZCBkb3duCgpJIGV2YWx1YXRlZCB0aGlzIGFuZCB0aGUgJ3VwJyBzZXQgbmV4dCB0byBlYWNoIG90aGVyIGFuZCB0aGV5IGFyZQpleHRyZW1lbHkgc2ltaWxhcjoKCnVwOiAxNDggR08gaGl0cywgNjggVEYsIDAgSFBBCmJvdGg6IDE2OSBHTywgNjkgVEYsIGFuZCAyIEhQQQoKT3RoZXJ3aXNlIEkgdGhpbmsgdGhleSBhcmUgdGhlIHNhbWUuCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfYm90aF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2JvdGgsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9lb3Npbm9waGlsX2JvdGhfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfYm90aF9ncAplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2JvdGhfZ3BbWyJCUF9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfYm90aF9ncFtbIkJQX2VucmljaCJdXSkKZ29fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZ29fdGVybXNpbSwgbGFiZWxfZm9ybWFwID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfZW9zaW5vcGhpbF9ib3RoX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpnb190cmVlcGxvdApkZXYub2ZmKCkKZ29fdHJlZXBsb3QKCnJlYWNfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2JvdGhfZ3BbWyJSRUFDX2VucmljaCJdXSkKcmVhY190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChyZWFjX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX2Vvc2lub3BoaWxfYm90aF9ncF9yZWFjLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpyZWFjX3RyZWVwbG90CmRldi5vZmYoKQpgYGAKCiMjIyBjbHVzdGVycHJvZmlsZXIKCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2NwX3VwIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfdXAsIGRlX3RhYmxlID0gdF9jZl9lb3Npbm9waGlsX3RhYmxlX3N2YSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX3VwX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfY3BfdXBbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMjIGluY3JlYXNlZCBpbiBmYWlsIHZzIGN1cmUKCmBgYHtyfQp0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9jcF9kb3duIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfZG93biwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9zaWdfc3ZhX2Rvd25fY3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX2Vvc2lub3BoaWxfc2lnX3N2YV9jcF9kb3duW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHU0VBCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3NpZ190b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9lb3Npbm9waGlsX3NpZ19zdmFfY3BfdXApCnRfY2ZfZW9zaW5vcGhpbF9zaWdfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyMgTW9ub2N5dGVzIGN1cmUvZmFpbAoKYGBge3J9CnRfbW9ub2N5dGVfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV9jZl90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX21vbm9jeXRlX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIodF9tb25vY3l0ZV94bHN4LCAib3V0Y29tZSIpCgp0X21vbm9jeXRlX3NpZ194bHN4IDwtIGdsdWUoIntjZl9wcmVmaXh9L01vbm9jeXRlcy90X21vbm9jeXRlX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX21vbm9jeXRlX3NpZ19zdmFfdXAgPC0gc2lnX3JlYWRlcih0X21vbm9jeXRlX3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9kb3duIDwtIHNpZ19yZWFkZXIodF9tb25vY3l0ZV9zaWdfeGxzeCwgIm91dGNvbWUiLCAiZG93biIpCnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9ib3RoIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBnUHJvZmlsZXIKCk5vdyB0aGF0IEkgYW0gbG9va2luZyBiYWNrIG92ZXIgdGhlc2UgcmVzdWx0cywgSSBhbSBub3QgY29tcGVsdGVseQpjZXJ0YWluIHdoeSBJIG9ubHkgZGlkIHRoZSBncHJvZmlsZXIgc2VhcmNoIGZvciB0aGUgc3ZhIGRhdGEuLi4KCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX21vbm9jeXRlX3VwX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cF9ncAplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cF9ncFtbIkJQX2VucmljaCJdXSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX21vbm9jeXRlX3NpZ19zdmFfdXBfZ3BbWyJURl9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9tb25vY3l0ZV9zaWdfc3ZhX3VwX2dwW1siQlBfZW5yaWNoIl1dKQpnb190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChnb190ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9ICJmaWd1cmVzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX21vbm9jeXRlX3VwX2dwX2dvLnN2ZyIsCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CmBgYAoKIyMjIyBpbmNyZWFzZWQgaW4gZmFpbCB2cyBjdXJlCgpgYGB7cn0KdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX21vbm9jeXRlX3NpZ19zdmFfZG93biwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX21vbm9jeXRlX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX21vbm9jeXRlX3NpZ19zdmFfZG93bl9ncFtbIkJQX2VucmljaCJdXSkKCmdvX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2NmX21vbm9jeXRlX3NpZ19zdmFfZG93bl9ncFtbIkJQX2VucmljaCJdXSkKZ29fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZ29fdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfbW9ub2N5dGVfZG93bl9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZ29fdHJlZXBsb3QKZGV2Lm9mZigpCmdvX3RyZWVwbG90CgojIyBJbnN1ZmZpY2llbnQgcmVzdWx0cyB0byBtYWtlIGEgdHJlZSBwbG90LgpgYGAKCiMjIyMgQm90aCB1cCBhbmQgZG93bgoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGgsCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9tb25vY3l0ZV9ib3RoX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9ib3RoX2dwCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGhfZ3BbWyJCUF9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGhfZ3BbWyJCUF9lbnJpY2giXV0pCmdvX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGdvX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX21vbm9jeXRlX2JvdGhfZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmdvX3RyZWVwbG90CmRldi5vZmYoKQpnb190cmVlcGxvdAoKIyMgSW5zdWZmaWNpZW50IHJlc3VsdHMgZm9yIHJlYWN0b21lCgp0Zl90ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2JvdGhfZ3BbWyJURl9lbnJpY2giXV0pCnRmX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KHRmX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2NmX21vbm9jeXRlX2JvdGhfZ3BfdGYtdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCnRmX3RyZWVwbG90CmRldi5vZmYoKQp0Zl90cmVlcGxvdApgYGAKCiMjIyBjbHVzdGVycHJvZmlsZXIKCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9jcF91cCA8LSBzaW1wbGVfY3Byb2ZpbGVyKAogIHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cCwgZGVfdGFibGUgPSB0X2NmX21vbm9jeXRlX3RhYmxlX3N2YSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbW9ub2N5dGVfc2lnX3N2YV91cF9jcC12e3Zlcn0ueGxzeCIpKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9jcF91cFtbImVucmljaF9vYmplY3RzIl1dW1siQlBfYWxsIl1dKQpgYGAKCiMjIyMgaW5jcmVhc2VkIGluIGZhaWwgdnMgY3VyZQoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9jcF9kb3duIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9tb25vY3l0ZV9zaWdfc3ZhX2Rvd24sCiAgb3JnZGIgPSAib3JnLkhzLmVnLmRiIiwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX21vbm9jeXRlX3NpZ19zdmFfZG93bl9jcC12e3Zlcn0ueGxzeCIpKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9jcF9kb3duW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHU0VBCgpgYGB7cn0KdF9jZl9tb25vY3l0ZV9zaWdfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfbW9ub2N5dGVfc2lnX3N2YV9jcF91cCkKdF9jZl9tb25vY3l0ZV9zaWdfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyMgTmV1dHJvcGhpbHMgY3VyZS9mYWlsCgpgYGB7cn0KdF9uZXV0cm9waGlsX3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX2NmX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfbmV1dHJvcGhpbF90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKHRfbmV1dHJvcGhpbF94bHN4LCAib3V0Y29tZSIpCgp0X25ldXRyb3BoaWxfc2lnX3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vTmV1dHJvcGhpbHMvdF9uZXV0cm9waGlsX2NmX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cCA8LSBzaWdfcmVhZGVyKHRfbmV1dHJvcGhpbF9zaWdfeGxzeCwgIm91dGNvbWUiKQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9kb3duIDwtIHNpZ19yZWFkZXIodF9uZXV0cm9waGlsX3NpZ194bHN4LCAib3V0Y29tZSIsICJkb3duIikKdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfYm90aCA8LSByYmluZC5kYXRhLmZyYW1lKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfZG93bikKYGBgCgojIyMgZ1Byb2ZpbGVyCgpOb3cgdGhhdCBJIGFtIGxvb2tpbmcgYmFjayBvdmVyIHRoZXNlIHJlc3VsdHMsIEkgYW0gbm90IGNvbXBlbHRlbHkKY2VydGFpbiB3aHkgSSBvbmx5IGRpZCB0aGUgZ3Byb2ZpbGVyIHNlYXJjaCBmb3IgdGhlIHN2YSBkYXRhLi4uCgojIyMjIGluY3JlYXNlZCBpbiBjdXJlIHZzIGZhaWwKCmBgYHtyfQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF91cF9ncC12e3Zlcn0ueGxzeCIpKQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV91cF9ncAplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwX2dwW1siQlBfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwX2dwW1siVEZfZW5yaWNoIl1dKQoKZ29fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwX2dwW1siQlBfZW5yaWNoIl1dKQpnb190cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChnb190ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9ICJmaWd1cmVzL3RfY2ZfbmV1dHJvcGhpbF91cF9ncF9nby5zdmciLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmdvX3RyZWVwbG90CmRldi5vZmYoKQpnb190cmVlcGxvdApgYGAKCiMjIyMgaW5jcmVhc2VkIGluIGZhaWwgdnMgY3VyZQoKYGBge3J9CnRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9kb3duLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF9kb3duX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2Rvd25fZ3AKCiMjIE5vdCBtdWNoIHRvIHdvcmsgd2l0aCBoZXJlLgpgYGAKCiMjIyMgQm90aCB1cCBhbmQgZG93bgoKYGBge3J9CnRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2JvdGhfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ib3RoLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF9ib3RoX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2JvdGhfZ3AKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9ib3RoX2dwW1siQlBfZW5yaWNoIl1dKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2JvdGhfZ3BbWyJURl9lbnJpY2giXV0pCgpnb190ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfYm90aF9ncFtbIkJQX2VucmljaCJdXSkKZ29fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZ29fdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfY2ZfbmV1dHJvcGhpbF9ib3RoX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpnb190cmVlcGxvdApkZXYub2ZmKCkKZ29fdHJlZXBsb3QKCiMjIEluc3VmZmljaWVudCByZXN1bHRzIGZvciByZWFjdG9tZQpgYGAKCiMjIyBjbHVzdGVycHJvZmlsZXIKCiMjIyMgaW5jcmVhc2VkIGluIGN1cmUgdnMgZmFpbAoKYGBge3J9CnRfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2NwX3VwIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfdXAsIGRlX3RhYmxlID0gdF9jZl9uZXV0cm9waGlsX3RhYmxlX3N2YSwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX3VwX2NwLXZ7dmVyfS54bHN4IikpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfY3BfdXBbWyJlbnJpY2hfb2JqZWN0cyJdXVtbIkJQX2FsbCJdXSkKYGBgCgojIyMjIGluY3JlYXNlZCBpbiBmYWlsIHZzIGN1cmUKCmBgYHtyfQp0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9jcF9kb3duIDwtIHNpbXBsZV9jcHJvZmlsZXIoCiAgdF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfZG93biwKICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF9zaWdfc3ZhX2Rvd25fY3Atdnt2ZXJ9Lnhsc3giKSkKZW5yaWNocGxvdDo6ZG90cGxvdCh0X2NmX25ldXRyb3BoaWxfc2lnX3N2YV9jcF9kb3duW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCmBgYAoKIyMjIyBHU0VBCgpgYGB7cn0KdF9jZl9uZXV0cm9waGlsX3NpZ190b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9uZXV0cm9waGlsX3NpZ19zdmFfY3BfdXApCnRfY2ZfbmV1dHJvcGhpbF9zaWdfdG9wbl9nc2VhW1siR09fb3V0Y29tZV91cCJdXVtbMV1dCmBgYAoKIyMgTG9vayBhdCB2aXNpdCAxIGFuZCBzZWUgaWYgYW55dGhpbmcgcG9wcyBvdXQKCmBgYHtyfQp0X21vbm9jeXRlX3YxX3hsc3ggPC0gZ2x1ZSgie2NmX3ByZWZpeH0vTW9ub2N5dGVzL3RfbW9ub2N5dGVfdjFfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9tb25vY3l0ZV92MV90YWJsZV9zdmEgPC0gdGFibGVfcmVhZGVyKHRfbW9ub2N5dGVfdjFfeGxzeCwgIm91dGNvbWUiKQoKdF9tb25vY3l0ZV92MV9zaWdfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Nb25vY3l0ZXMvdF9tb25vY3l0ZV92MV9jZl9zaWdfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIodF9tb25vY3l0ZV92MV9zaWdfeGxzeCwgIm91dGNvbWUiKQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfZG93biA8LSBzaWdfcmVhZGVyKHRfbW9ub2N5dGVfdjFfc2lnX3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfYm90aCA8LSByYmluZC5kYXRhLmZyYW1lKHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfZG93bikKYGBgCgojIyMgR2VuZSBTZXQgRW5yaWNobWVudDogZ1Byb2ZpbGVyIE1vbm9jeXRlcyBieSB2aXNpdCwgVjEKClYxOiBVcDogMTQgZ2VuZXM7IE5vIGNhdGVnb3JpZXMKVjE6IERvd246IDUyIGdlbmVzOyAyMCBHTywgNSBURgoKIyMjIyBJbmNyZWFzZWQgaW4gY3VyZQoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX3VwX2dwCmBgYAoKIyMjIyBJbmNyZWFzZWQgaW4gZmFpbAoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9uZXV0cm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX2Rvd25fZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBlaXRoZXIKCmBgYHtyfQp0X2NmX21vbm9jeXRlX3YxX3NpZ19zdmFfYm90aF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV9ib3RoLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF9kb3duX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV9ib3RoX2dwCmBgYAoKSSBsaWtlIGNhdHMhCgojIyMjIGNsdXN0ZXJQcm9maWxlcgoKYGBge3J9CnRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cF9jcCA8LSBzaW1wbGVfY3Byb2ZpbGVyKHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jZl9tb25vY3l0ZV92MV90YWJsZV9zdmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZ2RiID0gIm9yZy5Icy5lZy5kYiIpCmVucmljaHBsb3Q6OmRvdHBsb3QodF9jZl9tb25vY3l0ZV92MV9zaWdfc3ZhX3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCnRfY2ZfbW9ub2N5dGVfdjFfdG9wbl9nc2VhIDwtIHBsb3RfdG9wbl9nc2VhKHRfY2ZfbW9ub2N5dGVfdjFfc2lnX3N2YV91cF9jcCkKdF9jZl9tb25vY3l0ZV92MV90b3BuX2dzZWFbWyJHT19vdXRjb21lX3VwIl1dW1sxXV0KYGBgCgojIyMgTmV1dHJvcGhpbHMgdjEKCmBgYHtyfQp0X25ldXRyb3BoaWxfdjFfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjFfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9uZXV0cm9waGlsX3YxX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIodF9uZXV0cm9waGlsX3YxX3hsc3gsICJvdXRjb21lIikKCnRfbmV1dHJvcGhpbF92MV9zaWdfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9OZXV0cm9waGlscy90X25ldXRyb3BoaWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIodF9uZXV0cm9waGlsX3YxX3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcih0X25ldXRyb3BoaWxfdjFfc2lnX3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9ib3RoIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBHZW5lIFNldCBFbnJpY2htZW50OiBnUHJvZmlsZXIgTmV1dHJvcGhpbHMgYnkgdmlzaXQsIFYxCgojIyMjIEluY3JlYXNlZCBpbiBjdXJlCgpgYGB7cn0KdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX25ldXRyb3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBmYWlsCgpgYGB7cn0KdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9uZXV0cm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncApgYGAKCiMjIyMgSW5jcmVhc2VkIGluIGVpdGhlcgoKYGBge3J9CnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX2JvdGhfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX25ldXRyb3BoaWxfdjFfc2lnX3N2YV9ib3RoLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfbmV1dHJvcGhpbF9kb3duX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX2JvdGhfZ3AKYGBgCgojIyMjIGNsdXN0ZXJQcm9maWxlcgoKYGBge3J9CnRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX3VwX2NwIDwtIHNpbXBsZV9jcHJvZmlsZXIodF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jZl9uZXV0cm9waGlsX3YxX3RhYmxlX3N2YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfbmV1dHJvcGhpbF92MV9zaWdfc3ZhX3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCnRfY2ZfbmV1dHJvcGhpbF92MV90b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9uZXV0cm9waGlsX3YxX3NpZ19zdmFfdXBfY3ApCnRfY2ZfbmV1dHJvcGhpbF92MV90b3BuX2dzZWFbWyJHT19vdXRjb21lX3VwIl1dW1sxXV0KYGBgCgojIyMgRW9zaW5vcGhpbHMgdjEKCmBgYHtyfQp0X2Vvc2lub3BoaWxfdjFfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdjFfY2ZfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikKdF9jZl9lb3Npbm9waGlsX3YxX3RhYmxlX3N2YSA8LSB0YWJsZV9yZWFkZXIodF9lb3Npbm9waGlsX3YxX3hsc3gsICJvdXRjb21lIikKCnRfZW9zaW5vcGhpbF92MV9zaWdfeGxzeCA8LSBnbHVlKCJ7Y2ZfcHJlZml4fS9Fb3Npbm9waGlscy90X2Vvc2lub3BoaWxfdjFfY2Zfc2lnX3N2YS12e3Zlcn0ueGxzeCIpCnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX3VwIDwtIHNpZ19yZWFkZXIodF9lb3Npbm9waGlsX3YxX3NpZ194bHN4LCAib3V0Y29tZSIpCnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX2Rvd24gPC0gc2lnX3JlYWRlcih0X2Vvc2lub3BoaWxfdjFfc2lnX3hsc3gsICJvdXRjb21lIiwgImRvd24iKQp0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9ib3RoIDwtIHJiaW5kLmRhdGEuZnJhbWUodF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9kb3duKQpgYGAKCiMjIyBHZW5lIFNldCBFbnJpY2htZW50OiBnUHJvZmlsZXIgRW9zaW5vcGhpbHMgYnkgdmlzaXQsIFYxCgojIyMjIEluY3JlYXNlZCBpbiBjdXJlCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV91cCwKICBleGNlbCA9IGdsdWUoInt4bHN4X3ByZWZpeH0vR2VuZV9TZXRfRW5yaWNobWVudC90X2NmX2Vvc2lub3BoaWxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXBfZ3AKYGBgCgojIyMjIEluY3JlYXNlZCBpbiBmYWlsCgpgYGB7cn0KdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX2Rvd24sCiAgZXhjZWwgPSBnbHVlKCJ7eGxzeF9wcmVmaXh9L0dlbmVfU2V0X0VucmljaG1lbnQvdF9jZl9lb3Npbm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKdF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfZG93bl9ncApgYGAKCiMjIyMgSW5jcmVhc2VkIGluIGVpdGhlcgoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX2JvdGhfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICB0X2NmX2Vvc2lub3BoaWxfdjFfc2lnX3N2YV9ib3RoLAogIGV4Y2VsID0gZ2x1ZSgie3hsc3hfcHJlZml4fS9HZW5lX1NldF9FbnJpY2htZW50L3RfY2ZfZW9zaW5vcGhpbF9kb3duX2dwLXZ7dmVyfS54bHN4IikpCnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX2JvdGhfZ3AKYGBgCgojIyMjIGNsdXN0ZXJQcm9maWxlcgoKYGBge3J9CnRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX3VwX2NwIDwtIHNpbXBsZV9jcHJvZmlsZXIodF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9jZl9lb3Npbm9waGlsX3YxX3RhYmxlX3N2YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdkYiA9ICJvcmcuSHMuZWcuZGIiKQplbnJpY2hwbG90Ojpkb3RwbG90KHRfY2ZfZW9zaW5vcGhpbF92MV9zaWdfc3ZhX3VwX2NwW1siZW5yaWNoX29iamVjdHMiXV1bWyJCUF9hbGwiXV0pCnRfY2ZfZW9zaW5vcGhpbF92MV90b3BuX2dzZWEgPC0gcGxvdF90b3BuX2dzZWEodF9jZl9lb3Npbm9waGlsX3YxX3NpZ19zdmFfdXBfY3ApCnRfY2ZfZW9zaW5vcGhpbF92MV90b3BuX2dzZWFbWyJHT19vdXRjb21lX3VwIl1dW1sxXV0KYGBgCgojIFJlcGVhdCBzb21lIG9mIHRoaXMgZm9yIHRoZSBtaXhlZCBsaW5lYXIgbW9kZWwgcmVzdWx0cwoKU3BlYWtpbmcgd2l0aCBNYXJpYSBBZGVsYWlkYSwgaXQgc291bmRzIGxpa2UgdGhlIG1vc3QgYXBwcm9wcmlhdGUgc2V0CnRvIHRyeSBmb3Igbm93IGlzIHxsb2dGQ3wgPj0gMC41OCBhbmQgcCA8PSAwLjA1LiAgSSB3cm90ZSBvdXQgdGhlCmRyZWFtIHJlc3VsdHMgaW4gYSBzaW1wbGVyIGFuZCBsZXNzIGZ1biB3YXkgdGhhbiBldmVyeXRoaW5nIGVsc2UuCgojIyBBbGwgY2VsbHR5cGVzCgojIyMgQ29sbGVjdCB0aGUgZ2VuZSBzZXRzCgpgYGB7cn0KbWl4ZWRfYWxsX3RibCA8LSB0YWJsZV9yZWFkZXIoCiAgZ2x1ZSgiZXhjZWwvbWl4ZWRfYWxsX2NlbGx0eXBlc19ub2Jpb3BfdGFibGUtdnt2ZXJ9Lnhsc3giKSwKICBzaGVldCA9ICJmYWlsdXJlX3ZzX2N1cmUiKQphbGxfc2lnX3VwX2lkeCA8LSBtaXhlZF9hbGxfdGJsW1sibG9nZmMiXV0gPj0gMC41OCAmCiAgbWl4ZWRfYWxsX3RibFtbInBfdmFsdWUiXV0gPD0gMC4wNQphbGxfc2lnX2Rvd25faWR4IDwtIG1peGVkX2FsbF90YmxbWyJsb2dmYyJdXSA8PSAtMC41OCAmCiAgbWl4ZWRfYWxsX3RibFtbInBfdmFsdWUiXV0gPD0gMC4wNQoKYWxsX3VwX2dlbmVzIDwtIHJvd25hbWVzKG1peGVkX2FsbF90YmwpW2FsbF9zaWdfdXBfaWR4XQphbGxfZG93bl9nZW5lcyA8LSByb3duYW1lcyhtaXhlZF9hbGxfdGJsKVthbGxfc2lnX2Rvd25faWR4XQphbGxfYm90aF9nZW5lcyA8LSBjKGFsbF91cF9nZW5lcywgYWxsX2Rvd25fZ2VuZXMpCmBgYAoKIyMjIEdlbmVzIGluY3JlYXNlZCBpbiBjdXJlCgpgYGB7cn0KdF9kcmVhbV9hbGxfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICBhbGxfdXBfZ2VuZXMsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9kcmVhbV9hbGxfdXBfZ3Atdnt2ZXJ9Lnhsc3giKSkKYWxsX3VwX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2RyZWFtX2FsbF91cF9ncFtbIkJQX2VucmljaCJdXSkKYWxsX3VwX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGFsbF91cF90ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9kcmVhbV9hbGxfdXBfZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmFsbF91cF90cmVlcGxvdApkZXYub2ZmKCkKYWxsX3VwX3RyZWVwbG90CmBgYAoKIyMjIEdlbmVzIGluY3JlYXNlZCBpbiBmYWlsCgpgYGB7cn0KdF9kcmVhbV9hbGxfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIGFsbF9kb3duX2dlbmVzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvZHJlYW1fYWxsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKYWxsX2Rvd25fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfZHJlYW1fYWxsX2Rvd25fZ3BbWyJCUF9lbnJpY2giXV0pCmFsbF9kb3duX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGFsbF9kb3duX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2RyZWFtX2FsbF9kb3duX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQphbGxfZG93bl90cmVlcGxvdApkZXYub2ZmKCkKYWxsX2Rvd25fdHJlZXBsb3QKYGBgCgojIyMgSW5jcmVhc2VkIGluIGVpdGhlcgoKYGBge3J9CnRfZHJlYW1fYWxsX2JvdGhfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICBhbGxfYm90aF9nZW5lcywKICBleGNlbCA9IGdsdWUoImV4Y2VsL2RyZWFtX2FsbF9ib3RoX2dwLXZ7dmVyfS54bHN4IikpCmFsbF9ib3RoX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2RyZWFtX2FsbF9ib3RoX2dwW1siQlBfZW5yaWNoIl1dKQphbGxfYm90aF90cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChhbGxfYm90aF90ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9kcmVhbV9hbGxfYm90aF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKYWxsX2JvdGhfdHJlZXBsb3QKZGV2Lm9mZigpCmFsbF9ib3RoX3RyZWVwbG90CmBgYAoKIyMgTW9ub2N5dGVzCgojIyMgQ29sbGVjdGluZyBnZW5lIHNldHMKCmBgYHtyfQptaXhlZF9tb25vY3l0ZV90YmwgPC0gdGFibGVfcmVhZGVyKAogIGdsdWUoImV4Y2VsL21peGVkX21vbm9jeXRlX3RhYmxlLXZ7dmVyfS54bHN4IiksCiAgc2hlZXQgPSAiZmFpbHVyZV92c19jdXJlIikKbW9ub2N5dGVfc2lnX3VwX2lkeCA8LSBtaXhlZF9tb25vY3l0ZV90YmxbWyJsb2dmYyJdXSA+PSAwLjU4ICYKICBtaXhlZF9tb25vY3l0ZV90YmxbWyJwX3ZhbHVlIl1dIDw9IDAuMDUKbW9ub2N5dGVfc2lnX2Rvd25faWR4IDwtIG1peGVkX21vbm9jeXRlX3RibFtbImxvZ2ZjIl1dIDw9IC0wLjU4ICYKICBtaXhlZF9tb25vY3l0ZV90YmxbWyJwX3ZhbHVlIl1dIDw9IDAuMDUKCm1vbm9jeXRlX3VwX2dlbmVzIDwtIHJvd25hbWVzKG1peGVkX21vbm9jeXRlX3RibClbbW9ub2N5dGVfc2lnX3VwX2lkeF0KbW9ub2N5dGVfZG93bl9nZW5lcyA8LSByb3duYW1lcyhtaXhlZF9tb25vY3l0ZV90YmwpW21vbm9jeXRlX3NpZ19kb3duX2lkeF0KbW9ub2N5dGVfYm90aF9nZW5lcyA8LSBjKG1vbm9jeXRlX3VwX2dlbmVzLCBtb25vY3l0ZV9kb3duX2dlbmVzKQpgYGAKCiMjIyBJbmNyZWFzZWQgaW4gZmFpbAoKYGBge3J9CnRfZHJlYW1fbW9ub2N5dGVfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICBtb25vY3l0ZV91cF9nZW5lcywKICBleGNlbCA9IGdsdWUoImV4Y2VsL2RyZWFtX21vbm9jeXRlX3VwX2dwLXZ7dmVyfS54bHN4IikpCm1vbm9jeXRlX3VwX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2RyZWFtX21vbm9jeXRlX3VwX2dwW1siQlBfZW5yaWNoIl1dKQptb25vY3l0ZV91cF90cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChtb25vY3l0ZV91cF90ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9kcmVhbV9tb25vY3l0ZV91cF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKbW9ub2N5dGVfdXBfdHJlZXBsb3QKZGV2Lm9mZigpCm1vbm9jeXRlX3VwX3RyZWVwbG90CmBgYAoKIyMjIEluY3JlYXNlZCBpbiBjdXJlCgpgYGB7cn0KdF9kcmVhbV9tb25vY3l0ZV9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgbW9ub2N5dGVfZG93bl9nZW5lcywKICBleGNlbCA9IGdsdWUoImV4Y2VsL2RyZWFtX21vbm9jeXRlX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKbW9ub2N5dGVfZG93bl90ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9kcmVhbV9tb25vY3l0ZV9kb3duX2dwW1siQlBfZW5yaWNoIl1dKQptb25vY3l0ZV9kb3duX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KG1vbm9jeXRlX2Rvd25fdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfZHJlYW1fbW9ub2N5dGVfZG93bl9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKbW9ub2N5dGVfZG93bl90cmVlcGxvdApkZXYub2ZmKCkKbW9ub2N5dGVfZG93bl90cmVlcGxvdApgYGAKCiMjIyBJbmNyZWFzZWQgaW4gZWl0aGVyCgpgYGB7cn0KdF9kcmVhbV9tb25vY3l0ZV9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgbW9ub2N5dGVfYm90aF9nZW5lcywKICBleGNlbCA9IGdsdWUoImV4Y2VsL2RyZWFtX21vbm9jeXRlX2JvdGhfZ3Atdnt2ZXJ9Lnhsc3giKSkKbW9ub2N5dGVfYm90aF90ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9kcmVhbV9tb25vY3l0ZV9ib3RoX2dwW1siQlBfZW5yaWNoIl1dKQptb25vY3l0ZV9ib3RoX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KG1vbm9jeXRlX2JvdGhfdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfZHJlYW1fbW9ub2N5dGVfYm90aF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKbW9ub2N5dGVfYm90aF90cmVlcGxvdApkZXYub2ZmKCkKbW9ub2N5dGVfYm90aF90cmVlcGxvdApgYGAKCiMjIE5ldXRyb3BoaWxzCgojIyMgQ29sbGVjdGluZyBnZW5lIHNldHMKCmBgYHtyfQpuZXV0cm9waGlsX3RibCA8LSB0YWJsZV9yZWFkZXIoCiAgZ2x1ZSgiZXhjZWwvbWl4ZWRfbmV1dHJvcGhpbF90YWJsZS12e3Zlcn0ueGxzeCIpLAogIHNoZWV0ID0gImZhaWx1cmVfdnNfY3VyZSIpCm5ldXRyb3BoaWxfc2lnX3VwX2lkeCA8LSBuZXV0cm9waGlsX3RibFtbImxvZ2ZjIl1dID49IDAuNTggJgogIG5ldXRyb3BoaWxfdGJsW1sicF92YWx1ZSJdXSA8PSAwLjA1Cm5ldXRyb3BoaWxfc2lnX2Rvd25faWR4IDwtIG5ldXRyb3BoaWxfdGJsW1sibG9nZmMiXV0gPD0gLTAuNTggJgogIG5ldXRyb3BoaWxfdGJsW1sicF92YWx1ZSJdXSA8PSAwLjA1CgpuZXV0cm9waGlsX3VwX2dlbmVzIDwtIHJvd25hbWVzKG5ldXRyb3BoaWxfdGJsKVtuZXV0cm9waGlsX3NpZ191cF9pZHhdCm5ldXRyb3BoaWxfZG93bl9nZW5lcyA8LSByb3duYW1lcyhuZXV0cm9waGlsX3RibClbbmV1dHJvcGhpbF9zaWdfZG93bl9pZHhdCm5ldXRyb3BoaWxfYm90aF9nZW5lcyA8LSBjKG5ldXRyb3BoaWxfdXBfZ2VuZXMsIG5ldXRyb3BoaWxfZG93bl9nZW5lcykKCiMjIyBJbmNyZWFzZWQgaW4gZmFpbAoKYGBge3J9CnRfZHJlYW1fbmV1dHJvcGhpbF91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIG5ldXRyb3BoaWxfdXBfZ2VuZXMsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9kcmVhbV9uZXV0cm9waGlsX3VwX2dwLXZ7dmVyfS54bHN4IikpCm5ldXRyb3BoaWxfdXBfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfZHJlYW1fbmV1dHJvcGhpbF91cF9ncFtbIkJQX2VucmljaCJdXSkKbmV1dHJvcGhpbF91cF90cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChuZXV0cm9waGlsX3VwX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2RyZWFtX25ldXRyb3BoaWxfdXBfZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCm5ldXRyb3BoaWxfdXBfdHJlZXBsb3QKZGV2Lm9mZigpCm5ldXRyb3BoaWxfdXBfdHJlZXBsb3QKYGBgCgojIyMgSW5jcmVhc2VkIGluIGN1cmUKCmBgYHtyfQp0X2RyZWFtX25ldXRyb3BoaWxfZG93bl9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIG5ldXRyb3BoaWxfZG93bl9nZW5lcywKICBleGNlbCA9IGdsdWUoImV4Y2VsL2RyZWFtX25ldXRyb3BoaWxfZG93bl9ncC12e3Zlcn0ueGxzeCIpKQpuZXV0cm9waGlsX2Rvd25fdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfZHJlYW1fbmV1dHJvcGhpbF9kb3duX2dwW1siQlBfZW5yaWNoIl1dKQpuZXV0cm9waGlsX2Rvd25fdHJlZXBsb3QgPC0gc20odHJlZXBsb3QobmV1dHJvcGhpbF9kb3duX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2RyZWFtX25ldXRyb3BoaWxfZG93bl9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKbmV1dHJvcGhpbF9kb3duX3RyZWVwbG90CmRldi5vZmYoKQpuZXV0cm9waGlsX2Rvd25fdHJlZXBsb3QKYGBgCgojIyMgSW5jcmVhc2VkIGluIGVpdGhlcgoKYGBge3J9CnRfZHJlYW1fbmV1dHJvcGhpbF9ib3RoX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoCiAgbmV1dHJvcGhpbF9ib3RoX2dlbmVzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvZHJlYW1fbmV1dHJvcGhpbF9ib3RoX2dwLXZ7dmVyfS54bHN4IikpCm5ldXRyb3BoaWxfYm90aF90ZXJtc2ltIDwtIGVucmljaHBsb3Q6OnBhaXJ3aXNlX3Rlcm1zaW0odF9kcmVhbV9uZXV0cm9waGlsX2JvdGhfZ3BbWyJCUF9lbnJpY2giXV0pCm5ldXRyb3BoaWxfYm90aF90cmVlcGxvdCA8LSBzbSh0cmVlcGxvdChuZXV0cm9waGlsX2JvdGhfdGVybXNpbSwgbGFiZWxfZm9ybWF0ID0gd3JhcF93aWR0aCkpCnBwKGZpbGUgPSBnbHVlKCJpbWFnZXMvb3ZlcnJlcHJlc2VudGF0aW9uL3RfZHJlYW1fbmV1dHJvcGhpbF9ib3RoX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQpuZXV0cm9waGlsX2JvdGhfdHJlZXBsb3QKZGV2Lm9mZigpCm5ldXRyb3BoaWxfYm90aF90cmVlcGxvdApgYGAKCiMjIEVvc2lub3BoaWxzCgojIyMgQ29sbGVjdCBnZW5lIHNldHMKCmBgYHtyfQplb3Npbm9waGlsX3RibCA8LSB0YWJsZV9yZWFkZXIoCiAgZ2x1ZSgiZXhjZWwvbWl4ZWRfZW9zaW5vcGhpbF90YWJsZS12e3Zlcn0ueGxzeCIpLAogIHNoZWV0ID0gImZhaWx1cmVfdnNfY3VyZSIpCmVvc2lub3BoaWxfc2lnX3VwX2lkeCA8LSBlb3Npbm9waGlsX3RibFtbImxvZ2ZjIl1dID49IDAuNTggJgogIGVvc2lub3BoaWxfdGJsW1sicF92YWx1ZSJdXSA8PSAwLjA1CmVvc2lub3BoaWxfc2lnX2Rvd25faWR4IDwtIGVvc2lub3BoaWxfdGJsW1sibG9nZmMiXV0gPD0gLTAuNTggJgogIGVvc2lub3BoaWxfdGJsW1sicF92YWx1ZSJdXSA8PSAwLjA1Cgplb3Npbm9waGlsX3VwX2dlbmVzIDwtIHJvd25hbWVzKGVvc2lub3BoaWxfdGJsKVtlb3Npbm9waGlsX3NpZ191cF9pZHhdCmVvc2lub3BoaWxfZG93bl9nZW5lcyA8LSByb3duYW1lcyhlb3Npbm9waGlsX3RibClbZW9zaW5vcGhpbF9zaWdfZG93bl9pZHhdCmVvc2lub3BoaWxfYm90aF9nZW5lcyA8LSBjKGVvc2lub3BoaWxfdXBfZ2VuZXMsIGVvc2lub3BoaWxfZG93bl9nZW5lcykKYGBgCgojIyMgSW5jcmVhc2VkIGluIGZhaWwKCmBgYHtyfQp0X2RyZWFtX2Vvc2lub3BoaWxfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICBlb3Npbm9waGlsX3VwX2dlbmVzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvZHJlYW1fZW9zaW5vcGhpbF91cF9ncC12e3Zlcn0ueGxzeCIpKQplb3Npbm9waGlsX3VwX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2RyZWFtX2Vvc2lub3BoaWxfdXBfZ3BbWyJCUF9lbnJpY2giXV0pCmVvc2lub3BoaWxfdXBfdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZW9zaW5vcGhpbF91cF90ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9kcmVhbV9lb3Npbm9waGlsX3VwX2dwX2dvLXZ7dmVyfS5wZGYiKSwKICAgaGVpZ2h0ID0gdHJlZXBsb3RfaGVpZ2h0LCB3aWR0aCA9IHRyZWVwbG90X3dpZHRoKQplb3Npbm9waGlsX3VwX3RyZWVwbG90CmRldi5vZmYoKQplb3Npbm9waGlsX3VwX3RyZWVwbG90CmBgYAoKIyMjIEluY3JlYXNlZCBpbiBjdXJlCgpgYGB7cn0KdF9kcmVhbV9lb3Npbm9waGlsX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcigKICBlb3Npbm9waGlsX2Rvd25fZ2VuZXMsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9kcmVhbV9lb3Npbm9waGlsX2Rvd25fZ3Atdnt2ZXJ9Lnhsc3giKSkKZW9zaW5vcGhpbF9kb3duX3Rlcm1zaW0gPC0gZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbSh0X2RyZWFtX2Vvc2lub3BoaWxfZG93bl9ncFtbIkJQX2VucmljaCJdXSkKZW9zaW5vcGhpbF9kb3duX3RyZWVwbG90IDwtIHNtKHRyZWVwbG90KGVvc2lub3BoaWxfZG93bl90ZXJtc2ltLCBsYWJlbF9mb3JtYXQgPSB3cmFwX3dpZHRoKSkKcHAoZmlsZSA9IGdsdWUoImltYWdlcy9vdmVycmVwcmVzZW50YXRpb24vdF9kcmVhbV9lb3Npbm9waGlsX2Rvd25fZ3BfZ28tdnt2ZXJ9LnBkZiIpLAogICBoZWlnaHQgPSB0cmVlcGxvdF9oZWlnaHQsIHdpZHRoID0gdHJlZXBsb3Rfd2lkdGgpCmVvc2lub3BoaWxfZG93bl90cmVlcGxvdApkZXYub2ZmKCkKZW9zaW5vcGhpbF9kb3duX3RyZWVwbG90CmBgYAoKIyMjIEluY3JlYXNlZCBpbiBlaXRoZXIKCmBgYHtyfQp0X2RyZWFtX2Vvc2lub3BoaWxfYm90aF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKAogIGVvc2lub3BoaWxfYm90aF9nZW5lcywKICBleGNlbCA9IGdsdWUoImV4Y2VsL2RyZWFtX2Vvc2lub3BoaWxfYm90aF9ncC12e3Zlcn0ueGxzeCIpKQplb3Npbm9waGlsX2JvdGhfdGVybXNpbSA8LSBlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKHRfZHJlYW1fZW9zaW5vcGhpbF9ib3RoX2dwW1siQlBfZW5yaWNoIl1dKQplb3Npbm9waGlsX2JvdGhfdHJlZXBsb3QgPC0gc20odHJlZXBsb3QoZW9zaW5vcGhpbF9ib3RoX3Rlcm1zaW0sIGxhYmVsX2Zvcm1hdCA9IHdyYXBfd2lkdGgpKQpwcChmaWxlID0gZ2x1ZSgiaW1hZ2VzL292ZXJyZXByZXNlbnRhdGlvbi90X2RyZWFtX2Vvc2lub3BoaWxfYm90aF9ncF9nby12e3Zlcn0ucGRmIiksCiAgIGhlaWdodCA9IHRyZWVwbG90X2hlaWdodCwgd2lkdGggPSB0cmVlcGxvdF93aWR0aCkKZW9zaW5vcGhpbF9ib3RoX3RyZWVwbG90CmRldi5vZmYoKQplb3Npbm9waGlsX2JvdGhfdHJlZXBsb3QKYGBgCgojIEJpYmxpb2dyYXBoeQo=