1 Consolidation of a Molecular Signature of Healing in Cutaneous Leishmaniasis is Achieved During the First Ten Days of Treatment.

2 Introduction

This document performs a series of diagnostics and differential expression analyses which eventually helped inform the text of Lina Fernanda Giraldo Parra’s and Maria Adelaida Gomez’s paper. In it, they sought to use biopsies over time from people who were observed to cure/fail treatment of cutaneous leishmaniasis. Some of these people were treated with the antimonial ‘glucantime’, others with miltefosine. Biopsies were taken at the beginning, middle, and end of treatment. RNA was taken from the biopsies, made into libraries, and sequenced. The samples were mapped/counted against ensembl hg38 release 100 and the TritrypDB Leishmania panamensis MHOM/COL strain’s genome with hisat2 and salmon. There were very few reads observed from the parasite. As a result (at the time of this writing: 202310), those count tables are not included in the sample sheet (they are now, along with the salmon quantitations against hg38_100), and are not considered in this worksheet.

3 Changelog

  • 20231025: All the PCA plots were of non-filtered data. I removed two samples due to coverage, so the plots should not include them. While I am at it, rename a few variables to make everything more consistent. Also explicitly writing the figure-pieces to the ‘images/’ directory, previously I just created them on request.
  • 202309-202310: Copied the worksheet from my directory into the container build tree, reorganized it, and added some text to hopefully address queries/concerns from reviewers as well as clarify some tasks performed.
  • 2022-2023: Copied Najib’s worksheet to my directory, cleaned it up a bit, and finished what I think are the likely analyses.

I collected the available metadata into the sheet ‘all_samples.xlsx’.

4 Sample sheet

samplesheet <- "sample_sheets/all_samples.xlsx"

4.1 Extracting extra sample annotations

The function ‘gather_preprocessing_metadata()’ scans the working directory in which the various preprocessing tasks were performed, trimming, fastqc/fastp, mapping/quantitation, variant searching, etc. It is aware of my default output filenames for stdout/stderr/etc and extracts from them various metrics potentially of interest. I think the sample sheet I copied into this container is the result of the following block, so I am not going to evaluate it here.

rna_spec <- make_rnaseq_spec()
modified <- gather_preprocessing_metadata(samplesheet,
                                          specification = rna_spec,
                                          species = "hg38_100")

5 Annotation

We take the annotation data from ensembl’s biomart instance. The genome which was used to map the data was hg38 revision 100. My default when using biomart is to load the data from 1 year before the current date.

hs_annot <- load_biomart_annotations(year = "2019")
## Using mart: ENSEMBL_MART_ENSEMBL from host: Apr2019.archive.ensembl.org.
## Successfully connected to the hsapiens_gene_ensembl database.
## Finished downloading ensembl gene annotations.
## Finished downloading ensembl structure annotations.
## symbol columns is null, pattern matching 'symbol'.
## Including symbols, there are 65071 vs the 229428 gene annotations.
## Dropping haplotype chromosome annotations, set drop_haplotypes = FALSE if this is bad.
## Saving annotations to hsapiens_biomart_annotations.rda.
## Finished save().
hs_annot
## 12 annotation types for 208,460 genes/transcripts downloaded from Apr2019.archive.ensembl.org.
hs_annot <- hs_annot[["annotation"]]
hs_annot[["transcript"]] <- paste0(rownames(hs_annot), ".", hs_annot[["version"]])
rownames(hs_annot) <- make.names(hs_annot[["ensembl_gene_id"]], unique = TRUE)
tx_gene_map <- hs_annot[, c("transcript", "ensembl_gene_id")]

5.1 Gene Ontology data

Downloading the Ontology annotation information has a significant chance of failing because it sometimes takes longer than curl’s timeout of 300 seconds. As a result, I may decide to include the saved rda of ontology results in the container, or maybe improve my ontology downloader so that it is no longer susceptible to timeouts…

Actually, I do not think I am using clusterProfiler/gostats/goseq/topgo in this document, perhaps therefore I should just exclude this block? Yeah, it seems like there is a 50/50 chance that this will fail when run within the container, and I am currently not using this set of gene:GO mappings in this document.

hs_go <- load_biomart_go(overwrite = TRUE)
hs_go
hs_go <- hs_go[["go"]]
hs_length <- hs_annot[, c("ensembl_gene_id", "cds_length")]
colnames(hs_length) <- c("ID", "length")

6 Create expressionsets

The primary datastructure used throughout this document is the expressionSet or summarized Experiment. This document uses the former; but both are created by reading the sample sheet, extracting the filenames of the count data from it, and combining the metadata, annotation data, and counts. My implementation of this process also includes a few extra pieces of information. For example: the colors of various potential conditions in the data.

6.1 Color choices

Before we create the datastructures, I want to have the various color schemes in place. Many of these color choices are taken directly from another project which also looks at host responses.

color_choices <- list(
  "cf_visit" = list(
    "cure_v1" = "#D95F0E",
    "failure_v1" = "#FEC44F",
    "cure_v2" = "#DD1C77",
    "failure_v2" = "#C994C7",
    "cure_v3" = "#3182BD",
    "failure_v3" = "#9ECAE1"),
  "drug_visit" = list(
    "antimoniate_v1" = "#badeef",
    "miltefosine_v1" = "#e4a6c1",
    "antimoniate_v2" = "#7bc6ea",
    "miltefosine_v2" = "#d26895",
    "antimoniate_v3" = "#1d91ca",
    "miltefosine_v3" = "#d52e75"),
  "species_visit" = list(
    "lvpanamensis_v1" = "#ffe798",
    "lvbraziliensis_v1" = "#b5b5b5",
    "lvpanamensis_v2" = "#FFC300",
    "lvbraziliensis_v2" = "#888888",
    "lvpanamensis_v3" = "#b58b00",
    "lvbraziliensis_v3" = "#525252"),
  "cf" = list(
    "cure" = "#998EC3",
    "failure" = "#F1A340"),
  "visit" = list(
    "v1" = "#33EE33",
    "v2" = "#11AA11",
    "v3" = "#134413"),
  "visitbi" = list(
    "v1" = "#BB0000",
    "vother" = "#0000BB"),
  "species" = list(
    "lvpanamensis" = "#FFC300",
    "lvbraziliensis" = "#525252"),
  "donor" = list(
    "d2008" = "#B78415",
    "d1029" = "#93752C",
    "d1036" = "#7E6EA2",
    "d1037" = "#B3499C",
    "d1031" = "#BD6332",
    "d2002" = "#7D8F31",
    "d2009" = "#8E7037",
    "d2010" = "#666666",
    "d1019" = "#1B9E77",
    "d2004" = "#E0A604",
    "d2001" =  "#CF3F76",
    "d2003" = "#A0A811"),
  "drug" = list(
    "antimoniate" = "#3182AA",
    "miltefosine" = "#C994AA"))

The set of color choices demonstrates the complexity of the experimental design. We are looking at combinations of time, outcome, species, and drug. Inherent in all of these is an overarching donor effect.

6.2 Initial dataset: Combine clinical outcome with visit

The initial datastructure will use a factor combining the clinical outcome and visit as the experimental condition of interest. We will follow this up by splitting off the various factors of interest.

An aside: when testing the following block within the container, it did not print out the filenames as it was reading them, usually it does. I assume this is not a problem since the data looks fine, but this may warrant further exploration.

The call to sanitize_expt_pData() tries to ensure that Excel does not mess things up with random spaces/capitalization in the metadata.

wellcome_outtime <- create_expt(metadata = samplesheet, gene_info = hs_annot,
                                file_column = "hg38100hisatfile") %>%
  set_expt_batches(fact = "drug") %>%
  sanitize_expt_pData(spaces = TRUE)
## Reading the sample metadata.
## Did not find the column: sampleid.
## Setting the ID column to the first column.
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## The sample definitions comprises: 36 rows(samples) and 54 columns(metadata fields).
## Warning in file(file, "rt"): cannot open file
## '/mnt/nfs/z1/sw/singularity/CL_biopsies_Colombia/202404201249_outputs/preprocessing/TMRC30097/outputs/02hisat2_hg38_100/hg38_100_sno_gene_gene_id.count.xz':
## No such file or directory
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': cannot open the connection
wellcome_outtime
## Error in eval(expr, envir, enclos): object 'wellcome_outtime' not found

The previous block creates the primary datastructure, everything from now on will either:

  • Add categories to it (the next block)
  • Set various categories to the primary factor of interest (set_expt_conditions()/set_expt_batches())
  • Subset the data to highlight individual questions or remove the two (I think two, double check this) low-coverage samples.
  • Normalize/analyze the above.

The following block therefore creates a set of factors which are the concatenation of time+x where x is one of: outcome, drug, species.

outcome_time <- paste0(pData(wellcome_outtime)[["clinicaloutcome"]], "_v",
                       pData(wellcome_outtime)[["visitnumber"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
wellcome_outtime <- set_expt_conditions(wellcome_outtime, fact = outcome_time,
                                        colors = color_choices[["cf_visit"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
pData(wellcome_outtime)[["visitnumber"]] <- paste0("v", pData(wellcome_outtime)[["visitnumber"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
pData(wellcome_outtime)[["outcome_visit"]] <- outcome_time
## Error in eval(expr, envir, enclos): object 'outcome_time' not found
pData(wellcome_outtime)[["drug_visit"]] <- paste0(pData(wellcome_outtime)[["drug"]], "_",
                                                  pData(wellcome_outtime)[["visitnumber"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
pData(wellcome_outtime)[["species_visit"]] <- paste0(pData(wellcome_outtime)[["infectingspecies"]], "_",
                                                     pData(wellcome_outtime)[["visitnumber"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found

6.3 Check samples

First, let us get a quick view of the samples in their native state. There are a few samples which are candidates for removal due to lower coverage.

Random aside: I have some nifty code which tries to autodetect when to color the text in the colored bars white or black. The purple/pink color tricks that code into thinking it is dark enough to be colored white.

  • FIXME plot_libsize() text color heuristic.
plot_legend(wellcome_outtime)
## Error in eval(expr, envir, enclos): object 'wellcome_outtime' not found
plot_libsize(wellcome_outtime)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'data' in selecting a method for function 'plot_libsize': object 'wellcome_outtime' not found
plot_nonzero(wellcome_outtime, plot_labels = "repel")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'data' in selecting a method for function 'plot_nonzero': object 'wellcome_outtime' not found
wellcome_filtered <- subset_expt(wellcome_outtime, nonzero = 15000)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'wellcome_outtime' not found

6.4 Write all the sample data

The following writes out the data in two files, one before and after filtering for samples with less than 15,000 observed genes.

written <- write_expt(wellcome_outtime,
                      excel = glue("excel/CL_biopsies_all_data-v{ver}.xlsx"))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'wellcome_outtime' not found
written <- write_expt(wellcome_filtered,
                      excel = glue("excel/CL_biopsies_filtered_data-v{ver}.xlsx"))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'wellcome_filtered' not found

Looking at the nonzero plot, it seems that 15k genes is a reasonable cutoff, which would remove 2 samples. So, for the moment I will split the data up into two sets, pre/post removal.

6.5 Upload CPM values

Lina asked for a CSV copy of the data as CPM.

wellcome_cpm <- normalize_expt(wellcome_filtered, filter = TRUE, convert = "cpm")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_filtered' not found
wellcome_cpm_mtrx <- exprs(wellcome_cpm)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'wellcome_cpm' not found
wellcome_cpm_write <- write.csv(x = wellcome_cpm_mtrx, file = "excel/CL_biopsies_filtered_cpm.csv")
## Error in eval(expr, p): object 'wellcome_cpm_mtrx' not found
wellcome_scpm <- normalize_expt(wellcome_filtered, filter = TRUE, convert = "cpm", batch = "svaseq")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_filtered' not found
wellcome_scpm_mtrx <- exprs(wellcome_scpm)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'wellcome_scpm' not found
wellcome_scpm_write <- write.csv(x = wellcome_cpm_mtrx, file = "excel/CL_biopsies_filtered_cpm_sva.csv")
## Error in eval(expr, p): object 'wellcome_cpm_mtrx' not found

6.6 Check samples

We have in place some initial datastructures; let us mix and match them to get a sense of the data. There are a few factors in the experiment that are likely of primary interest: the donor, time, drug used, parasite species/strain, and clinical outcome. There are too many factors for the number of samples to do a full rank model, so I am going to make copies of the expressionset and model each factor separately with the help of sva.

6.7 Only donor

Start with the donor. There are 12 people, most of whom provided three samples. Two of them (d2002 and d2009) had samples which got excluded and so have only 2. I am separating the un/filtered datasets so that we may play with both if we want.

wellcome_donor <- set_expt_conditions(wellcome_outtime, fact = "donor",
                                      colors = color_choices)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
wellcome_donor_filt <- set_expt_conditions(wellcome_filtered, fact = "donor",
                                           colors = color_choices)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found

6.8 Only visit

In this case, the condition will only be visit number. We have 12 samples for each visit, except v1/v3 which are missing 1 each.

wellcome_time <- set_expt_conditions(wellcome_outtime, fact = "visitnumber",
                                     colors = color_choices[["visit"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
wellcome_time_filt <- set_expt_conditions(wellcome_filtered, fact = "visitnumber",
                                         colors = color_choices[["visit"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found

6.9 Only Cure/Fail

Conversely, we can split by clinical outcome. The unfiltered dataset has 15 cures and 21 failures; both filtered samples were failure.

wellcome_outcome <- set_expt_conditions(wellcome_outtime, fact = "clinicaloutcome",
                                        colors = color_choices[["cf"]]) %>%
  set_expt_batches(fact = "visitnumber")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
wellcome_outcome_filt <- set_expt_conditions(wellcome_filtered, fact = "clinicaloutcome",
                                             colors = color_choices[["cf"]]) %>%
  set_expt_batches(fact = "visitnumber")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found

6.10 Only drug

With respect to drug treatment, we started with 18 of each. The lost samples were both miltefosine.

wellcome_drug <- set_expt_conditions(wellcome_outtime, fact = "drug",
                                     colors = color_choices[["drug"]]) %>%
  set_expt_batches(fact = "visitnumber")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
wellcome_drug_filt <- set_expt_conditions(wellcome_filtered, fact = "drug",
                                          colors = color_choices[["drug"]]) %>%
  set_expt_batches(fact = "visitnumber")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found

6.11 Only parasite

We started with 12 braziliensis and 24 panamensis; one of each was lost.

wellcome_parasite <- set_expt_conditions(wellcome_outtime, fact = "infectingspecies",
                                         colors = color_choices[["species"]]) %>%
  set_expt_batches(fact = "visitnumber")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
wellcome_parasite_filt <- set_expt_conditions(wellcome_filtered, fact = "infectingspecies",
                                              colors = color_choices[["species"]]) %>%
  set_expt_batches(fact = "visitnumber")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found

6.12 Visualize the metadata

Everything I wrote above is visible in the following sankey plot. It is particularly noteworthy that we have no cure braziliensis for miltefosine treatment and only 1 for each of the antominial timepoints.

drug_visit_species_cf <- plot_meta_sankey(
  wellcome_filtered, factors = c("drug", "visitnumber", "clinicaloutcome", "infectingspecies"),
  color_choices = color_choices)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'design' in selecting a method for function 'plot_meta_sankey': object 'wellcome_filtered' not found
drug_visit_species_cf
## Error in eval(expr, envir, enclos): object 'drug_visit_species_cf' not found

7 Visualize samples

Given the large number of variables in this data, lets start by getting a feeling for the amount of variance in each. Given that we don’t have a full rank with respect to clinical outcome, I assume that trying variance partition with the 4 primary factors will fail, but let us see…

varpart_donor <- simple_varpart(
  wellcome_filtered,
  factors = c("donor", "visitnumber"))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
varpart_donor
## Error in eval(expr, envir, enclos): object 'varpart_donor' not found
varpart_dvic <- simple_varpart(
  wellcome_filtered,
  factors = c("drug", "visitnumber", "infectingspecies", "clinicaloutcome"))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
varpart_dvic
## Error in eval(expr, envir, enclos): object 'varpart_dvic' not found

To my eyes, it appears that donor is dominant factor, followed by: visit, species, drug, and outcome. I think this observation may have an effect on the current state of the manuscript - which if I recall properly states that donor is not a significant factor in the data.

7.1 Examine top-n genes with respect to variance of some factors

Let us ask if there are categories associated with the genes associated with each of these categories and see if they ‘make sense’.

top_300_donor_genes_idx <- order(varpart_donor[["fitted_df"]][["donor"]])
## Error in eval(expr, envir, enclos): object 'varpart_donor' not found
top_300_donor_genes <- tail(varpart_donor[["fitted_df"]][top_300_donor_genes_idx, ], n = 300)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'tail': object 'varpart_donor' not found
summary(top_300_donor_genes)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'summary': object 'top_300_donor_genes' not found
donor_genes_gp <- simple_gprofiler(rownames(top_300_donor_genes))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'top_300_donor_genes' not found
donor_genes_gp
## Error in eval(expr, envir, enclos): object 'donor_genes_gp' not found
donor_genes_gp$pvalue_plots$REAC
## Error in eval(expr, envir, enclos): object 'donor_genes_gp' not found

So, the top-300 genes with respect to putative donor effect, when passed to gprofiler’s over representation analyses, look like they have lots of variance related to categories that are explicitly important to the general questions we are asking. I think that counts as: Yay!

Now let us look at the other factors in the data and see if anything noteworthy pops out. Given that the dvic datastructure comprises the other factors of interest, we will need to reorder the results with respect to each factor separately.

7.1.1 Visit

Visit also is dominated by variance which is explicitly what one would expect: wound healing.

top_300_visit_genes_idx <- order(varpart_dvic[["fitted_df"]][["visitnumber"]])
## Error in eval(expr, envir, enclos): object 'varpart_dvic' not found
top_300_visit_genes <- tail(varpart_dvic[["fitted_df"]][top_300_visit_genes_idx, ], n = 300)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'tail': object 'varpart_dvic' not found
summary(top_300_visit_genes)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'summary': object 'top_300_visit_genes' not found
visit_genes_gp <- simple_gprofiler(rownames(top_300_visit_genes))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'top_300_visit_genes' not found
visit_genes_gp
## Error in eval(expr, envir, enclos): object 'visit_genes_gp' not found

7.1.2 Drug

I do not have any idea what one should expect vis a vis the two drugs. Looking at the following result, I guess one should not be surprised given that I am unaware of m/any experiments which explicitly compare antimonial treatments with respect to transcriptional profile.

top_300_drug_genes_idx <- order(varpart_dvic[["fitted_df"]][["drug"]])
## Error in eval(expr, envir, enclos): object 'varpart_dvic' not found
top_300_drug_genes <- tail(varpart_dvic[["fitted_df"]][top_300_drug_genes_idx, ], n = 300)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'tail': object 'varpart_dvic' not found
summary(top_300_drug_genes)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'summary': object 'top_300_drug_genes' not found
drug_genes_gp <- simple_gprofiler(rownames(top_300_drug_genes))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'top_300_drug_genes' not found
drug_genes_gp
## Error in eval(expr, envir, enclos): object 'drug_genes_gp' not found
drug_genes_gp$pvalue_plots$MF
## Error in eval(expr, envir, enclos): object 'drug_genes_gp' not found

7.1.3 Infecting species

The violin plot above suggests there is very limited variance with respect to the two species. In addition, there are significantly fewer braziliensis samples which failed treatment (for miltefosine in particular), so I presume variancePartition is going to have trouble extracting genes which are reliable in this context. In addition, I would assume that the human transcriptome has pretty similar responses to the two parasites, exacerbating this confounder.

top_300_species_genes_idx <- order(varpart_dvic[["fitted_df"]][["infectingspecies"]])
## Error in eval(expr, envir, enclos): object 'varpart_dvic' not found
top_300_species_genes <- tail(varpart_dvic[["fitted_df"]][top_300_species_genes_idx, ], n = 300)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'tail': object 'varpart_dvic' not found
summary(top_300_species_genes)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'summary': object 'top_300_species_genes' not found
species_genes_gp <- simple_gprofiler(rownames(top_300_species_genes))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'top_300_species_genes' not found
species_genes_gp
## Error in eval(expr, envir, enclos): object 'species_genes_gp' not found

7.1.4 Clinical outcome

In my mind, clinical outcome is the most generally interesting query. It is also one with limited information in the data, but lots of other studies have been performed in this realm, so it is more likely to have reliable overrepresentation results even with limited information. Thus, when I look at the bar/dot plot the categories look interesting.

The following block provides an example of one of the fun things my gProfiler2 function does: it coerces the gprofiler output to the datastructure used by clusterProfiler and thus may be plotted with the various functions in the ‘enrichplot’ package. It also provides a copy of the cute interactive plots produced by gprofiler.

top_300_cf_genes_idx <- order(varpart_dvic[["fitted_df"]][["clinicaloutcome"]])
## Error in eval(expr, envir, enclos): object 'varpart_dvic' not found
top_300_cf_genes <- tail(varpart_dvic[["fitted_df"]][top_300_cf_genes_idx, ], n = 300)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'tail': object 'varpart_dvic' not found
summary(top_300_cf_genes)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'summary': object 'top_300_cf_genes' not found
cf_genes_gp <- simple_gprofiler(rownames(top_300_cf_genes))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'top_300_cf_genes' not found
cf_genes_gp
## Error in eval(expr, envir, enclos): object 'cf_genes_gp' not found
enrichplot::dotplot(cf_genes_gp$GO_enrich)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'cf_genes_gp' not found

8 The samples’ distribution is similar without 2 samples

Here are the PCA results before/after removing the two samples that I called shenanigans on. They are quite similar. The most notable difference is the weirdo failure visit 3 sample on the left goes away.

wellcome_outtime_norm <- normalize_expt(wellcome_outtime, filter = TRUE,
                                        convert = "cpm", transform = "log2", norm = "quant")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_outtime' not found
pre_filter_pca <- plot_pca(wellcome_outtime_norm)
## Error in eval(expr, envir, enclos): object 'wellcome_outtime_norm' not found
pp(file = "images/all_samples_norm_pca.svg")
pre_filter_pca$plot
## Error in eval(expr, envir, enclos): object 'pre_filter_pca' not found
dev.off()
## png 
##   2
pre_filter_pca
## Error in eval(expr, envir, enclos): object 'pre_filter_pca' not found
wellcome_outfilt_norm <- normalize_expt(wellcome_filtered, filter = TRUE,
                                        convert = "cpm", transform = "log2", norm = "quant")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_filtered' not found
post_filter_pca <- plot_pca(wellcome_outfilt_norm)
## Error in eval(expr, envir, enclos): object 'wellcome_outfilt_norm' not found
pp(file = "images/filtered_samples_norm_pca.svg")
post_filter_pca$plot
## Error in eval(expr, envir, enclos): object 'post_filter_pca' not found
dev.off()
## png 
##   2
post_filter_pca
## Error in eval(expr, envir, enclos): object 'post_filter_pca' not found

9 Visualize Various PCA

Now that we have an initial sense of how the samples relate to each other, let us poke a bit further. In each of the following, I am likely to do one plot before and one after using sva.

9.1 By visit

I think the pattern of samples by visit is pretty or satisfying in a ‘hey, these things have some internal sense’ way. I guess modifying the counts with surrogates from sva makes it a little bit clearer? It does increase the PC1 variance a bit I suppose.

wellcome_time_norm <- normalize_expt(wellcome_time_filt, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_time_filt' not found
time_norm_pca <- plot_pca(wellcome_time_norm)
## Error in eval(expr, envir, enclos): object 'wellcome_time_norm' not found
pp(file = "images/time_norm_pca.svg")
time_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'time_norm_pca' not found
dev.off()
## png 
##   2
time_norm_pca
## Error in eval(expr, envir, enclos): object 'time_norm_pca' not found
wellcome_time_nb <- normalize_expt(wellcome_time_filt, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_time_filt' not found
time_nb_pca <- plot_pca(wellcome_time_nb)
## Error in eval(expr, envir, enclos): object 'wellcome_time_nb' not found
pp(file = "images/time_nb_pca.svg")
time_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'time_nb_pca' not found
dev.off()
## png 
##   2
time_nb_pca
## Error in eval(expr, envir, enclos): object 'time_nb_pca' not found

9.2 Cure/Fail

In contrast, the ability of sva to determine variance which is related to clinical outcome is very limited. The resulting PCA plot is a bit of a mess.

wellcome_outcome_norm <- normalize_expt(wellcome_outcome_filt, norm = "quant", convert = "cpm",
                                        filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_outcome_filt' not found
outcome_norm_pca <- plot_pca(wellcome_outcome_norm, plot_labels = FALSE)
## Error in eval(expr, envir, enclos): object 'wellcome_outcome_norm' not found
pp(file = "images/outcome_norm_pca.svg")
outcome_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_norm_pca' not found
dev.off()
## png 
##   2
outcome_norm_pca
## Error in eval(expr, envir, enclos): object 'outcome_norm_pca' not found
wellcome_outcome_nb <- normalize_expt(wellcome_outcome_filt, convert = "cpm",
                                      batch = "svaseq", filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_outcome_filt' not found
outcome_nb_pca <- plot_pca(wellcome_outcome_nb)
## Error in eval(expr, envir, enclos): object 'wellcome_outcome_nb' not found
pp(file = "images/outcome_nb_pca.svg")
outcome_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_nb_pca' not found
dev.off()
## png 
##   2
outcome_nb_pca
## Error in eval(expr, envir, enclos): object 'outcome_nb_pca' not found

9.3 Drug

At first glance, it at least appears possible that we can get a handle on differences between the two drug treatment regimes; but I kind of think that is a trick played by our eyes. Glancing at the plot from sva, it appears to disagree with me; at least this recapitulates the variancePartition result I think.

wellcome_drug_norm <- normalize_expt(wellcome_drug_filt, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_drug_filt' not found
drug_norm_pca <- plot_pca(wellcome_drug_norm)
## Error in eval(expr, envir, enclos): object 'wellcome_drug_norm' not found
pp(file = "images/drug_norm_pca.svg")
drug_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_norm_pca' not found
dev.off()
## png 
##   2
drug_norm_pca
## Error in eval(expr, envir, enclos): object 'drug_norm_pca' not found
wellcome_drug_nb <- normalize_expt(wellcome_drug_filt, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_drug_filt' not found
drug_nb_pca <- plot_pca(wellcome_drug_nb)
## Error in eval(expr, envir, enclos): object 'wellcome_drug_nb' not found
pp(file = "images/drug_nb_pca.svg")
drug_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_nb_pca' not found
dev.off()
## png 
##   2
drug_nb_pca
## Error in eval(expr, envir, enclos): object 'drug_nb_pca' not found

9.3.1 Separate drug treatment by time

Conversely, it is likely that we want to separate and/or combine the various factors with the visit. In the following block we will use the factor which is a combination of drug and visit.

drugtime <- set_expt_conditions(wellcome_filtered, fact = "drug_visit",
                                     colors = color_choices[["drug_visit"]]) %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
drugtime_norm <- normalize_expt(drugtime, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drugtime' not found
drugtime_norm_pca <- plot_pca(drugtime_norm)
## Error in eval(expr, envir, enclos): object 'drugtime_norm' not found
pp(file = "images/drugtime_norm_pca.svg")
drugtime_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'drugtime_norm_pca' not found
dev.off()
## png 
##   2
drugtime_norm_pca
## Error in eval(expr, envir, enclos): object 'drugtime_norm_pca' not found
drugtime_nb <- normalize_expt(drugtime, batch = "svaseq", convert = "cpm",
                              transform = "log2", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drugtime' not found
drugtime_nb_pca <- plot_pca(drugtime_nb)
## Error in eval(expr, envir, enclos): object 'drugtime_nb' not found
pp(file = "images/drugtime_nb_pca.svg")
drugtime_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'drugtime_nb_pca' not found
dev.off()
## png 
##   2
drugtime_nb_pca
## Error in eval(expr, envir, enclos): object 'drugtime_nb_pca' not found

9.3.1.1 Visit 1

One interpretation of some queries from reviewers would be to replot the various PCAs with the visits separated from each other. I am not completely sure that is the correct interpretation, but here it is.

drug_v1 <- subset_expt(drugtime, subset = "visitnumber=='v1'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'drugtime' not found
drug_v1_norm <- normalize_expt(drug_v1, norm = "quant", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drug_v1' not found
drug_v1_norm_pca <- plot_pca(drug_v1_norm)
## Error in eval(expr, envir, enclos): object 'drug_v1_norm' not found
pp(file = "images/drug_v1_norm_pca.svg")
drug_v1_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_v1_norm_pca' not found
dev.off()
## png 
##   2
drug_v1_norm_pca
## Error in eval(expr, envir, enclos): object 'drug_v1_norm_pca' not found
drug_v1_nb <- normalize_expt(drug_v1, batch = "svaseq", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drug_v1' not found
drug_v1_nb_pca <- plot_pca(drug_v1_nb)
## Error in eval(expr, envir, enclos): object 'drug_v1_nb' not found
pp(file = "images/drug_v1_nb_pca.svg")
drug_v1_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_v1_nb_pca' not found
dev.off()
## png 
##   2
drug_v1_nb_pca
## Error in eval(expr, envir, enclos): object 'drug_v1_nb_pca' not found

9.3.1.2 Visit 2

I would like to have something useful to say before every block. I don’t.

drug_v2 <- subset_expt(drugtime, subset = "visitnumber=='v2'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'drugtime' not found
drug_v2_norm <- normalize_expt(drug_v2, norm = "quant", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drug_v2' not found
drug_v2_norm_pca <- plot_pca(drug_v2_norm)
## Error in eval(expr, envir, enclos): object 'drug_v2_norm' not found
pp(file = "images/drug_v2_norm_pca.svg")
drug_v2_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_v2_norm_pca' not found
dev.off()
## png 
##   2
drug_v2_norm_pca
## Error in eval(expr, envir, enclos): object 'drug_v2_norm_pca' not found
drug_v2_nb <- normalize_expt(drug_v2, batch = "svaseq", convert = "cpm",
                             filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drug_v2' not found
drug_v2_nb_pca <- plot_pca(drug_v2_nb)
## Error in eval(expr, envir, enclos): object 'drug_v2_nb' not found
pp(file = "images/drug_v2_nb_pca.svg")
drug_v2_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_v2_nb_pca' not found
dev.off()
## png 
##   2
drug_v2_nb_pca
## Error in eval(expr, envir, enclos): object 'drug_v2_nb_pca' not found

9.3.1.3 Visit 3

drug_v3 <- subset_expt(drugtime, subset = "visitnumber=='v3'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'drugtime' not found
drug_v3_norm <- normalize_expt(drug_v3, norm = "quant", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drug_v3' not found
drug_v3_norm_pca <- plot_pca(drug_v3_norm)
## Error in eval(expr, envir, enclos): object 'drug_v3_norm' not found
pp(file = "images/drug_v3_norm_pca.svg")
drug_v3_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_v3_norm_pca' not found
dev.off()
## png 
##   2
drug_v3_nb <- normalize_expt(drug_v3, batch = "svaseq", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'drug_v3' not found
drug_v3_nb_pca <- plot_pca(drug_v3_nb)
## Error in eval(expr, envir, enclos): object 'drug_v3_nb' not found
pp(file = "images/drug_v3_nb_pca.svg")
drug_v3_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'drug_v3_nb_pca' not found
dev.off()
## png 
##   2
drug_v3_nb_pca
## Error in eval(expr, envir, enclos): object 'drug_v3_nb_pca' not found

9.3.2 Outcome alone

outcome <- set_expt_conditions(wellcome_filtered, fact = "clinicaloutcome",
                               colors = color_choices[["clinicaloutcome"]]) %>%
  set_expt_batches(fact = "drug")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
outcome_norm <- normalize_expt(outcome, norm = "quant", convert = "cpm",
                               transform = "log2", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome' not found
outcome_norm_pca <- plot_pca(outcome_norm)
## Error in eval(expr, envir, enclos): object 'outcome_norm' not found
pp(file = "images/outcome_norm_pca.svg")
outcome_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_norm_pca' not found
dev.off()
## png 
##   2
outcome_norm_pca
## Error in eval(expr, envir, enclos): object 'outcome_norm_pca' not found
outcome_nb <- normalize_expt(outcome, batch = "svaseq", convert = "cpm",
                             transform = "log2", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome' not found
outcome_nb_pca <- plot_pca(outcome_nb)
## Error in eval(expr, envir, enclos): object 'outcome_nb' not found
pp(file = "images/outcome_nb_pca.svg")
outcome_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_nb_pca' not found
dev.off()
## png 
##   2
outcome_nb_pca
## Error in eval(expr, envir, enclos): object 'outcome_nb_pca' not found

9.3.2.1 Visit 1

outcome_v1 <- subset_expt(outcome, subset = "visitnumber=='v1'")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'outcome' not found
outcome_v1_norm <- normalize_expt(outcome_v1, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome_v1' not found
outcome_v1_norm_pca <- plot_pca(outcome_v1_norm)
## Error in eval(expr, envir, enclos): object 'outcome_v1_norm' not found
pp(file = "images/outcome_v1_norm_pca.svg")
outcome_v1_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_v1_norm_pca' not found
dev.off()
## png 
##   2
outcome_v1_norm_pca
## Error in eval(expr, envir, enclos): object 'outcome_v1_norm_pca' not found
outcome_v1_nb <- normalize_expt(outcome_v1, batch = "svaseq", convert = "cpm",
                                filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome_v1' not found
outcome_v1_nb_pca <- plot_pca(outcome_v1_nb)
## Error in eval(expr, envir, enclos): object 'outcome_v1_nb' not found
pp(file = "images/outcome_v1_nb_pca.svg")
outcome_v1_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_v1_nb_pca' not found
dev.off()
## png 
##   2
outcome_v1_nb_pca
## Error in eval(expr, envir, enclos): object 'outcome_v1_nb_pca' not found

9.3.2.2 Visit 2

I would like to have something useful to say before every block. I don’t.

outcome_v2 <- subset_expt(outcome, subset = "visitnumber=='v2'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'outcome' not found
outcome_v2_norm <- normalize_expt(outcome_v2, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome_v2' not found
outcome_v2_norm_pca <- plot_pca(outcome_v2_norm)
## Error in eval(expr, envir, enclos): object 'outcome_v2_norm' not found
pp(file = "images/outcome_v2_norm_pca.svg")
outcome_v2_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_v2_norm_pca' not found
dev.off()
## png 
##   2
outcome_v2_norm_pca
## Error in eval(expr, envir, enclos): object 'outcome_v2_norm_pca' not found
outcome_v2_nb <- normalize_expt(outcome_v2, batch = "svaseq", convert = "cpm",
                             filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome_v2' not found
outcome_v2_nb_pca <- plot_pca(outcome_v2_nb)
## Error in eval(expr, envir, enclos): object 'outcome_v2_nb' not found
pp(file = "images/outcome_v2_nb_pca.svg")
outcome_v2_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_v2_nb_pca' not found
dev.off()
## png 
##   2
outcome_v2_nb_pca
## Error in eval(expr, envir, enclos): object 'outcome_v2_nb_pca' not found

9.3.2.3 Visit 3

outcome_v3 <- subset_expt(outcome, subset = "visitnumber=='v3'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'outcome' not found
outcome_v3_norm <- normalize_expt(outcome_v3, norm = "quant", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome_v3' not found
outcome_v3_norm_pca <- plot_pca(outcome_v3_norm)
## Error in eval(expr, envir, enclos): object 'outcome_v3_norm' not found
pp(file = "images/outcome_v3_norm_pca.svg")
outcome_v3_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_v3_norm_pca' not found
dev.off()
## png 
##   2
outcome_v3_norm_pca
## Error in eval(expr, envir, enclos): object 'outcome_v3_norm_pca' not found
outcome_v3_nb <- normalize_expt(outcome_v3, batch = "svaseq", convert = "cpm",
                                filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outcome_v3' not found
outcome_v3_nb_pca <- plot_pca(outcome_v3_nb)
## Error in eval(expr, envir, enclos): object 'outcome_v3_nb' not found
pp(file = "images/outcome_v3_nb_pca.svg")
outcome_v3_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'outcome_v3_nb_pca' not found
dev.off()
## png 
##   2
outcome_v3_nb_pca
## Error in eval(expr, envir, enclos): object 'outcome_v3_nb_pca' not found

9.3.3 Outcome and time

Repeat the above process, but this time using clinical outcome and time combined.

wellcome_outtime <- set_expt_conditions(wellcome_filtered, fact = "outcome_visit")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
wellcome_outtime_norm <- normalize_expt(wellcome_outtime, norm = "quant", convert = "cpm",
                                        filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_outtime' not found
outtime_norm_pca <- plot_pca(wellcome_outtime_norm)
## Error in eval(expr, envir, enclos): object 'wellcome_outtime_norm' not found
pp(file = "images/outtime_norm_pca.svg")
outtime_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_norm_pca' not found
dev.off()
## png 
##   2
outtime_norm_pca
## Error in eval(expr, envir, enclos): object 'outtime_norm_pca' not found
wellcome_outtime_nb <- normalize_expt(wellcome_outtime, convert = "cpm",
                                      batch = "svaseq", filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_outtime' not found
outtime_nb_pca <- plot_pca(wellcome_outtime_nb)
## Error in eval(expr, envir, enclos): object 'wellcome_outtime_nb' not found
pp(file = "images/outtime_nb_pca.svg")
outtime_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_nb_pca' not found
dev.off()
## png 
##   2
outtime_nb_pca
## Error in eval(expr, envir, enclos): object 'outtime_nb_pca' not found

9.3.3.1 Visit 1

outtime_v1 <- subset_expt(wellcome_outtime, subset = "visitnumber=='v1'") %>%
  set_expt_batches(fact = "drug")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'wellcome_outtime' not found
outtime_v1_norm <- normalize_expt(outtime_v1, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outtime_v1' not found
outtime_v1_norm_pca <- plot_pca(outtime_v1_norm)
## Error in eval(expr, envir, enclos): object 'outtime_v1_norm' not found
pp(file = "images/outtime_v1_norm_pca.svg")
outtime_v1_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_v1_norm_pca' not found
dev.off()
## png 
##   2
outtime_v1_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_v1_norm_pca' not found
outtime_v1_nb <- normalize_expt(outtime_v1, batch = "svaseq", convert = "cpm",
                                filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outtime_v1' not found
outtime_v1_nb_pca <- plot_pca(outtime_v1_nb)
## Error in eval(expr, envir, enclos): object 'outtime_v1_nb' not found
pp(file = "images/outtime_v1_nb_pca.svg")
outtime_v1_nb_pca
## Error in eval(expr, envir, enclos): object 'outtime_v1_nb_pca' not found

9.3.3.2 Visit 2

outtime_v2 <- subset_expt(wellcome_outtime, subset = "visitnumber=='v2'") %>%
  set_expt_batches(fact = "drug")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'wellcome_outtime' not found
outtime_v2_norm <- normalize_expt(outtime_v2, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outtime_v2' not found
outtime_v2_norm_pca <- plot_pca(outtime_v2_norm)
## Error in eval(expr, envir, enclos): object 'outtime_v2_norm' not found
pp(file = "images/outtime_v2_norm_pca.svg")
outtime_v2_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_v2_norm_pca' not found
dev.off()
## png 
##   2
outtime_v2_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_v2_norm_pca' not found
outtime_v2_nb <- normalize_expt(outtime_v2, batch = "svaseq", convert = "cpm",
                                filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outtime_v2' not found
outtime_v2_nb_pca <- plot_pca(outtime_v2_nb)
## Error in eval(expr, envir, enclos): object 'outtime_v2_nb' not found
pp(file = "images/outtime_v2_nb_pca.svg")
outtime_v2_nb_pca
## Error in eval(expr, envir, enclos): object 'outtime_v2_nb_pca' not found

9.3.3.3 Visit 3

outtime_v3 <- subset_expt(wellcome_outtime, subset = "visitnumber=='v3'") %>%
  set_expt_batches(fact = "drug")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'wellcome_outtime' not found
outtime_v3_norm <- normalize_expt(outtime_v3, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outtime_v3' not found
outtime_v3_norm_pca <- plot_pca(outtime_v3_norm)
## Error in eval(expr, envir, enclos): object 'outtime_v3_norm' not found
pp(file = "images/outtime_v3_norm_pca.svg")
outtime_v3_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_v3_norm_pca' not found
dev.off()
## png 
##   2
outtime_v3_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'outtime_v3_norm_pca' not found
outtime_v3_nb <- normalize_expt(outtime_v3, batch = "svaseq", convert = "cpm",
                                filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'outtime_v3' not found
outtime_v3_nb_pca <- plot_pca(outtime_v3_nb)
## Error in eval(expr, envir, enclos): object 'outtime_v3_nb' not found
pp(file = "images/outtime_v3_nb_pca.svg")
outtime_v3_nb_pca
## Error in eval(expr, envir, enclos): object 'outtime_v3_nb_pca' not found

9.4 Parasite Species

9.4.1 Separate species by time

speciestime <- set_expt_conditions(wellcome_outtime, fact = "species_visit",
                                   colors = color_choices[["species_visit"]]) %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outtime' not found
speciestime_norm <- normalize_expt(speciestime, norm = "quant", convert = "cpm",
                                   transform = "log2", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'speciestime' not found
speciestime_norm_pca <- plot_pca(speciestime_norm)
## Error in eval(expr, envir, enclos): object 'speciestime_norm' not found
pp(file = "images/speciestime_norm_pca.svg")
speciestime_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'speciestime_norm_pca' not found
dev.off()
## png 
##   2
speciestime_norm_pca
## Error in eval(expr, envir, enclos): object 'speciestime_norm_pca' not found
speciestime_nb <- normalize_expt(speciestime, batch = "svaseq", convert = "cpm",
                                 transform = "log2", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'speciestime' not found
speciestime_nb_pca <- plot_pca(speciestime_nb)
## Error in eval(expr, envir, enclos): object 'speciestime_nb' not found
pp(file = "images/speciestime_nb_pca.svg")
speciestime_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'speciestime_nb_pca' not found
dev.off()
## png 
##   2
speciestime_nb_pca
## Error in eval(expr, envir, enclos): object 'speciestime_nb_pca' not found

9.4.1.1 Visit 1

species_v1 <- subset_expt(speciestime, subset = "visitnumber=='v1'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'speciestime' not found
species_v1_norm <- normalize_expt(species_v1, norm = "quant", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'species_v1' not found
species_v1_norm_pca <- plot_pca(species_v1_norm)
## Error in eval(expr, envir, enclos): object 'species_v1_norm' not found
pp(file = "images/species_v1_norm_pca.svg")
species_v1_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'species_v1_norm_pca' not found
dev.off()
## png 
##   2
species_v1_norm_pca
## Error in eval(expr, envir, enclos): object 'species_v1_norm_pca' not found
species_v1_nb <- normalize_expt(species_v1, batch = "svaseq", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'species_v1' not found
species_v1_nb_pca <- plot_pca(species_v1_nb)
## Error in eval(expr, envir, enclos): object 'species_v1_nb' not found
pp(file = "images/species_v1_nb_pca.svg")
species_v1_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'species_v1_nb_pca' not found
dev.off()
## png 
##   2
species_v1_nb_pca
## Error in eval(expr, envir, enclos): object 'species_v1_nb_pca' not found

9.4.1.2 Visit 2

species_v2 <- subset_expt(speciestime, subset = "visitnumber=='v2'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'speciestime' not found
species_v2_norm <- normalize_expt(species_v2, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'species_v2' not found
species_v2_norm_pca <- plot_pca(species_v2_norm)
## Error in eval(expr, envir, enclos): object 'species_v2_norm' not found
pp(file = "images/species_v2_norm_pca.svg")
species_v2_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'species_v2_norm_pca' not found
dev.off()
## png 
##   2
species_v2_norm_pca
## Error in eval(expr, envir, enclos): object 'species_v2_norm_pca' not found
species_v2_nb <- normalize_expt(species_v2, batch = "svaseq", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'species_v2' not found
species_v2_nb_pca <- plot_pca(species_v2_nb)
## Error in eval(expr, envir, enclos): object 'species_v2_nb' not found
pp(file = "images/species_v2_nb_pca.svg")
species_v2_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'species_v2_nb_pca' not found
dev.off()
## png 
##   2
species_v2_nb_pca
## Error in eval(expr, envir, enclos): object 'species_v2_nb_pca' not found

9.4.1.3 Visit 3

species_v3 <- subset_expt(speciestime, subset = "visitnumber=='v3'") %>%
  set_expt_batches(fact = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': error in evaluating the argument 'expt' in selecting a method for function 'subset_expt': object 'speciestime' not found
species_v3_norm <- normalize_expt(species_v3, norm = "quant", convert = "cpm",
                                  filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'species_v3' not found
species_v3_norm_pca <- plot_pca(species_v3_norm)
## Error in eval(expr, envir, enclos): object 'species_v3_norm' not found
pp(file = "images/species_v3_norm_pca.svg")
species_v3_norm_pca$plot
## Error in eval(expr, envir, enclos): object 'species_v3_norm_pca' not found
dev.off()
## png 
##   2
species_v3_nb <- normalize_expt(species_v3, batch = "svaseq", convert = "cpm",
                               filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'species_v3' not found
species_v3_nb_pca <- plot_pca(species_v3_nb)
## Error in eval(expr, envir, enclos): object 'species_v3_nb' not found
pp(file = "images/species_v3_nb_pca.svg")
species_v3_nb_pca$plot
## Error in eval(expr, envir, enclos): object 'species_v3_nb_pca' not found
dev.off()
## png 
##   2
species_v3_nb_pca
## Error in eval(expr, envir, enclos): object 'species_v3_nb_pca' not found

9.4.1.4 Back to everything

wellcome_parasite_norm <- normalize_expt(wellcome_parasite_filt, norm = "quant", convert = "cpm",
                                         filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_parasite_filt' not found
plot_pca(wellcome_parasite_norm)
## Error in eval(expr, envir, enclos): object 'wellcome_parasite_norm' not found
wellcome_parasite_nb <- normalize_expt(wellcome_parasite_filt, norm = "quant", convert = "cpm",
                                       batch = "svaseq", filter = TRUE, transform = "log2")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'expt' in selecting a method for function 'normalize_expt': object 'wellcome_parasite_filt' not found
plot_pca(wellcome_parasite_nb)
## Error in eval(expr, envir, enclos): object 'wellcome_parasite_nb' not found

Ok, so that is a big pile of pictures, now let us perform some DE analyses and see what pops out.

10 DE analyses

Given the above variance partition and PCA plots, we can surmise that some metadata factors are much more likely to give interesting results than others (Drug far more than C/F, for example). With that in mind, let us perform the various possible DE analyses with each factor and see what comes out. Each of these runs of all pairwise will be performed once with SVA estimates in the model, and once with the drug treatment as the batch factor.

10.1 Outcome and time

One thing to recall, my sanitizer removes punctuation from concatenated factors; so ‘cure_v2’ turns into ‘curev2’.

10.2 The contrasts of interest

The following list names each contrast and the two element vector following provides each numerator and denominator.

outtime_keepers <- list(
  "curev1v2" = c("curev2", "curev1"),
  "curev1v3" = c("curev3", "curev1"),
  "curev2v3" = c("curev3", "curev2"),
  "failv1v2" = c("failurev2", "failurev1"),
  "failv1v3" = c("failurev3", "failurev1"),
  "failv2v3" = c("failurev3", "failurev2"),
  "cfv1" = c("failurev1", "curev1"),
  "cfv2" = c("failurev2", "curev2"),
  "cfv3" = c("failurev3", "curev3"))

Start with the combined factor of {outcome}_{visit}. Given the PCA, I expect to see a little bit of information with batch in the model, oddly less information with SVA.

10.2.1 SVA

One of the review comments seemed to me to suggest that using the variancePartition dream method might be useful. I am not certain if that is currently enabled. I definitely got it working, though. Also note that filter in this context is on a gene basis, not sample.

outtime_sva_de <- all_pairwise(wellcome_filtered, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
outtime_sva_de
## Error in eval(expr, envir, enclos): object 'outtime_sva_de' not found
outtime_sva_table <- combine_de_tables(
  outtime_sva_de,
  keepers = outtime_keepers,
  excel = glue("excel/CL_biopsies_outtime_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outtime_sva_de' not found
outtime_sva_table
## Error in eval(expr, envir, enclos): object 'outtime_sva_table' not found
outtime_sva_sig <- extract_significant_genes(
  outtime_sva_table,
  excel = glue("excel/CL_biopsies_outtime_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outtime_sva_table' not found
outtime_sva_sig
## Error in eval(expr, envir, enclos): object 'outtime_sva_sig' not found

10.2.2 Batch in model

outtime_batch_de <- all_pairwise(wellcome_filtered, model_batch = TRUE, filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_filtered' not found
outtime_batch_de
## Error in eval(expr, envir, enclos): object 'outtime_batch_de' not found
outtime_batch_table <- combine_de_tables(
  outtime_batch_de,
  keepers = outtime_keepers,
  excel = glue("excel/CL_biopsies_outtime_table_batch-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outtime_batch_de' not found
outtime_batch_table
## Error in eval(expr, envir, enclos): object 'outtime_batch_table' not found
outtime_batch_sig <- extract_significant_genes(
  outtime_batch_table,
  excel = glue("excel/CL_biopsies_outtime_sig_batch-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outtime_batch_table' not found
outtime_batch_sig
## Error in eval(expr, envir, enclos): object 'outtime_batch_sig' not found

11 PROPER

There was a request some time ago to provide a power analysis. I arbitrarily chose this dataset in order to invoke PROPER and provide the resulting plots…

outtime_batch_proper <- simple_proper(outtime_batch_table)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'outtime_batch_table' not found
outtime_batch_proper[["curev2_vs_curev1"]][["power_table"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found
outtime_batch_proper[["curev2_vs_curev1"]][["power_plot"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found
outtime_batch_proper[["curev2_vs_curev1"]][["powertd_plot"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found
outtime_batch_proper[["curev2_vs_curev1"]][["powerfd_plot"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found
outtime_batch_proper[["curev2_vs_curev1"]][["fdcost_plot"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found
outtime_batch_proper[["curev2_vs_curev1"]][["powerhist_plot"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found
outtime_batch_proper[["curev2_vs_curev1"]][["poweralpha_plot"]]
## Error in eval(expr, envir, enclos): object 'outtime_batch_proper' not found

11.1 Only time

Now let us compare the time points, with and without SVA.

11.2 Time contrasts

time_keepers <- list(
  "v1v2" = c("v2", "v1"),
  "v1v3" = c("v3", "v1"),
  "v2v3" = c("v3", "v2"))

11.2.1 SVA

time_sva_de <- all_pairwise(wellcome_time_filt, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_time_filt' not found
time_sva_de
## Error in eval(expr, envir, enclos): object 'time_sva_de' not found
time_sva_table <- combine_de_tables(
  time_sva_de,
  keepers = time_keepers,
  excel = glue("excel/CL_biopsies_time_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'time_sva_de' not found
time_sva_table
## Error in eval(expr, envir, enclos): object 'time_sva_table' not found
time_sva_sig <- extract_significant_genes(
  time_sva_table,
  excel = glue("excel/CL_biopsies_time_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'time_sva_table' not found
time_sva_sig
## Error in eval(expr, envir, enclos): object 'time_sva_sig' not found

11.2.2 Batch

time_batch_de <- all_pairwise(wellcome_time_filt, model_batch = "batchseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_time_filt' not found
time_batch_de
## Error in eval(expr, envir, enclos): object 'time_batch_de' not found
time_batch_table <- combine_de_tables(
  time_batch_de,
  keepers = time_keepers,
  excel = glue("excel/CL_biopsies_time_table_batch-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'time_batch_de' not found
time_batch_table
## Error in eval(expr, envir, enclos): object 'time_batch_table' not found
time_batch_sig <- extract_significant_genes(
  time_batch_table,
  excel = glue("excel/CL_biopsies_time_batch_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'time_batch_table' not found
time_batch_sig
## Error in eval(expr, envir, enclos): object 'time_batch_sig' not found

11.3 Strain

I neglected to set a contrast name/value for this.

## Oh, I just let the computer choose the numerator/denominator on its own.

The infecting strain I think should prove one of the more interesting comparisons.

11.3.1 SVA

parasite_sva_de <- all_pairwise(wellcome_parasite_filt, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_parasite_filt' not found
parasite_sva_de
## Error in eval(expr, envir, enclos): object 'parasite_sva_de' not found
parasite_sva_table <- combine_de_tables(
  parasite_sva_de,
  excel = glue("excel/CL_biopsies_parasite_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'parasite_sva_de' not found
parasite_sva_table
## Error in eval(expr, envir, enclos): object 'parasite_sva_table' not found
parasite_sva_sig <- extract_significant_genes(
  parasite_sva_table,
  excel = glue("excel/CL_biopsies_parasite_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'parasite_sva_table' not found
parasite_sva_sig
## Error in eval(expr, envir, enclos): object 'parasite_sva_sig' not found

11.3.2 Batch in model

parasite_batch_de <- all_pairwise(wellcome_parasite_filt, model_batch = TRUE, filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_parasite_filt' not found
parasite_batch_de
## Error in eval(expr, envir, enclos): object 'parasite_batch_de' not found
parasite_batch_table <- combine_de_tables(
  parasite_batch_de,
  excel = glue("excel/CL_biopsies_parasite_table_batch-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'parasite_batch_de' not found
parasite_batch_table
## Error in eval(expr, envir, enclos): object 'parasite_batch_table' not found
parasite_batch_sig <- extract_significant_genes(
  parasite_batch_table,
  excel = glue("excel/CL_biopsies_parasite_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'parasite_batch_table' not found
parasite_batch_sig
## Error in eval(expr, envir, enclos): object 'parasite_batch_sig' not found

11.4 Outcome

As stated above, clinical outcome by itself does not have much information content in this dataset.

11.4.1 SVA

outcome_sva_de <- all_pairwise(wellcome_outcome_filt, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outcome_filt' not found
outcome_sva_de
## Error in eval(expr, envir, enclos): object 'outcome_sva_de' not found
outcome_sva_table <- combine_de_tables(
  outcome_sva_de,
  excel = glue("excel/CL_biopsies_outcome_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outcome_sva_de' not found
outcome_sva_table
## Error in eval(expr, envir, enclos): object 'outcome_sva_table' not found
outcome_sva_sig <- extract_significant_genes(
  outcome_sva_table,
  excel = glue("excel/CL_biopsies_outcome_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outcome_sva_table' not found
outcome_sva_sig
## Error in eval(expr, envir, enclos): object 'outcome_sva_sig' not found

11.4.2 Batch in model

outcome_batch_de <- all_pairwise(wellcome_outcome_filt, model_batch = TRUE, filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_outcome_filt' not found
outcome_batch_de
## Error in eval(expr, envir, enclos): object 'outcome_batch_de' not found
outcome_batch_table <- combine_de_tables(
  outcome_batch_de,
  excel = glue("excel/CL_biopsies_outcome_table_batch-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outcome_batch_de' not found
outcome_batch_table
## Error in eval(expr, envir, enclos): object 'outcome_batch_table' not found
outcome_batch_sig <- extract_significant_genes(
  outcome_batch_table,
  excel = glue("excel/CL_biopsies_outcome_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'outcome_batch_table' not found
outcome_batch_sig
## Error in eval(expr, envir, enclos): object 'outcome_batch_sig' not found

11.5 Drug treatment

11.5.1 SVA

drug_sva_de <- all_pairwise(wellcome_drug_filt, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_drug_filt' not found
drug_sva_de
## Error in eval(expr, envir, enclos): object 'drug_sva_de' not found
drug_sva_table <- combine_de_tables(
  drug_sva_de,
  excel = glue("excel/CL_biopsies_drug_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drug_sva_de' not found
drug_sva_table
## Error in eval(expr, envir, enclos): object 'drug_sva_table' not found
drug_sva_sig <- extract_significant_genes(
  drug_sva_table,
  excel = glue("excel/CL_biopsies_drug_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drug_sva_table' not found
drug_sva_sig
## Error in eval(expr, envir, enclos): object 'drug_sva_sig' not found

11.5.2 Batch in model

drug_batch_de <- all_pairwise(wellcome_drug_filt, model_batch = TRUE, filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'wellcome_drug_filt' not found
drug_batch_de
## Error in eval(expr, envir, enclos): object 'drug_batch_de' not found
drug_batch_table <- combine_de_tables(
  drug_batch_de,
  excel = glue("excel/CL_biopsies_drug_table_batch-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drug_batch_de' not found
drug_batch_table
## Error in eval(expr, envir, enclos): object 'drug_batch_table' not found
drug_batch_sig <- extract_significant_genes(
  drug_batch_table,
  excel = glue("excel/CL_biopsies_drug_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drug_batch_table' not found
drug_batch_sig
## Error in eval(expr, envir, enclos): object 'drug_batch_sig' not found

11.6 Parasite and time

This requires setting up the contrasts of interest. I am going to assume cross species/cross time are not interesting, and that v3/v1 and v3/v2 are not interesting.

Note to self, do not forget that I sanitize the data by removing punctuation!

speciestime_keepers <- list(
  "pan_v2v1" = c("lvpanamensisv2", "lvpanamensisv1"),
  "pan_v3v1" = c("lvpanamensisv3", "lvpanamensisv1"),
  "braz_v2v1" = c("lvbraziliensisv2", "lvbraziliensisv1"),
  "braz_v3v1" = c("lvbraziliensisv3", "lvbraziliensisv1"),
  "v1_panbraz" = c("lvbraziliensisv1", "lvpanamensisv1"),
  "v2_panbraz" = c("lvbraziliensisv2", "lvpanamensisv2"),
  "v3_panbraz" = c("lvbraziliensisv3", "lvpanamensisv3"))

11.6.1 SVA

speciestime_sva_de <- all_pairwise(speciestime, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'speciestime' not found
speciestime_sva_de
## Error in eval(expr, envir, enclos): object 'speciestime_sva_de' not found
speciestime_sva_table <- combine_de_tables(
  speciestime_sva_de, keepers = speciestime_keepers,
  excel = glue("excel/CL_biopsies_speciestime_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'speciestime_sva_de' not found
speciestime_sva_table
## Error in eval(expr, envir, enclos): object 'speciestime_sva_table' not found
speciestime_sva_sig <- extract_significant_genes(
  speciestime_sva_table,
  excel = glue("excel/CL_biopsies_speciestime_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'speciestime_sva_table' not found
speciestime_sva_sig
## Error in eval(expr, envir, enclos): object 'speciestime_sva_sig' not found

11.6.2 Batch in model

speciestime_sva_de <- all_pairwise(speciestime, model_batch = TRUE, filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'speciestime' not found
speciestime_sva_de
## Error in eval(expr, envir, enclos): object 'speciestime_sva_de' not found
speciestime_sva_table <- combine_de_tables(
  speciestime_sva_de, keepers = speciestime_keepers,
  excel = glue("excel/CL_biopsies_speciestime_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'speciestime_sva_de' not found
speciestime_sva_table
## Error in eval(expr, envir, enclos): object 'speciestime_sva_table' not found
speciestime_sva_sig <- extract_significant_genes(
  speciestime_sva_table,
  excel = glue("excel/CL_biopsies_speciestime_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'speciestime_sva_table' not found
speciestime_sva_sig
## Error in eval(expr, envir, enclos): object 'speciestime_sva_sig' not found

11.7 Drug treatment and time

Same rules here as strain+time

drugtime_keepers <- list(
  "milt_v2v1" = c("miltefosinev2", "miltefosinev1"),
  "milt_v3v1" = c("miltefosinev3", "miltefosinev1"),
  "gluc_v2v1" = c("antimoniatev2", "antimoniatev1"),
  "gluc_v3v1" = c("antimoniatev3", "antimoniatev1"),
  "v1_miltgluc" = c("miltefosinev1", "antimoniatev1"),
  "v2_miltgluc" = c("miltefosinev2", "antimoniatev2"),
  "v3_miltgluc" = c("miltefosinev3", "antimoniatev3"))

11.7.1 SVA

drugtime_sva_de <- all_pairwise(drugtime, model_batch = "svaseq", filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'drugtime' not found
drugtime_sva_de
## Error in eval(expr, envir, enclos): object 'drugtime_sva_de' not found
drugtime_sva_table <- combine_de_tables(
  drugtime_sva_de, keepers = drugtime_keepers,
  excel = glue("excel/CL_biopsies_drugtime_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drugtime_sva_de' not found
drugtime_sva_table
## Error in eval(expr, envir, enclos): object 'drugtime_sva_table' not found
drugtime_sva_sig <- extract_significant_genes(
  drugtime_sva_table,
  excel = glue("excel/CL_biopsies_drugtime_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drugtime_sva_table' not found
drugtime_sva_sig
## Error in eval(expr, envir, enclos): object 'drugtime_sva_sig' not found

11.7.2 Batch in model

drugtime_sva_de <- all_pairwise(drugtime, model_batch = TRUE, filter = TRUE)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'drugtime' not found
drugtime_sva_de
## Error in eval(expr, envir, enclos): object 'drugtime_sva_de' not found
drugtime_sva_table <- combine_de_tables(
  drugtime_sva_de, keepers = drugtime_keepers,
  excel = glue("excel/CL_biopsies_drugtime_table_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drugtime_sva_de' not found
drugtime_sva_table
## Error in eval(expr, envir, enclos): object 'drugtime_sva_table' not found
drugtime_sva_sig <- extract_significant_genes(
  drugtime_sva_table,
  excel = glue("excel/CL_biopsies_drugtime_sig_sva-v{ver}.xlsx"))
## Error in eval(expr, envir, enclos): object 'drugtime_sva_table' not found
drugtime_sva_sig
## Error in eval(expr, envir, enclos): object 'drugtime_sva_sig' not found

12 Ontology searches

Given the results in the previous blocks, let us use gProfiler2 in look for over represented categories/ontologies in the suspect databases: GO/reactome/kegg/TF/wikipath/etc.

I think for the moment I will do this entirely with the sva results.

12.1 Outcome and time

I have a series of wrapper functions for gProfiler2/goseq/clusterProfiler/topGO/GOstats. Some of them are smart enough to take as input the result from extract_significant_genes().

There is also a function which writes pretty-ified ontology results, but it works on a single-table basis.

outtime_gprofiler <- all_gprofiler(outtime_sva_sig)
## Error in eval(expr, envir, enclos): object 'outtime_sva_sig' not found
outtime_gprofiler$curev1v2_up$pvalue_plots$BP
## Error in eval(expr, envir, enclos): object 'outtime_gprofiler' not found
outtime_gprofiler$failv1v2_up$pvalue_plots$KEGG
## Error in eval(expr, envir, enclos): object 'outtime_gprofiler' not found
outtime_gprofiler$cfv1_up$pvalue_plots$REAC
## Error in eval(expr, envir, enclos): object 'outtime_gprofiler' not found
## Note, I am writing a set of methods for write_gprofiler_data so that it is
## aware of the result from all_gprofiler and can handle either all contrasts
## or a set of desired contrasts.
write_all <- function(result) {
  for (n in names(result)) {
    name <- glue("excel/gprofiler_{n}.xlsx")
    res <- result[[n]]
    written <- try(write_gprofiler_data(res, excel = name))
  }
}

written <- write_all(outtime_gprofiler)
## Error in eval(expr, envir, enclos): object 'outtime_gprofiler' not found

12.2 Visit

visit_gprofiler <- all_gprofiler(time_sva_sig)
## Error in eval(expr, envir, enclos): object 'time_sva_sig' not found
written <- write_all(visit_gprofiler)
## Error in eval(expr, envir, enclos): object 'visit_gprofiler' not found

12.3 Strain

parasite_gprofiler <- all_gprofiler(parasite_sva_sig)
## Error in eval(expr, envir, enclos): object 'parasite_sva_sig' not found
written <- write_all(parasite_gprofiler)
## Error in eval(expr, envir, enclos): object 'parasite_gprofiler' not found

12.4 Outcome

outcome_gprofiler <- all_gprofiler(outcome_sva_sig)
## Error in eval(expr, envir, enclos): object 'outcome_sva_sig' not found
written <- write_all(outcome_gprofiler)
## Error in eval(expr, envir, enclos): object 'outcome_gprofiler' not found

12.5 Treatment

drug_gprofiler <- all_gprofiler(drug_sva_sig)
## Error in eval(expr, envir, enclos): object 'drug_sva_sig' not found
written <- write_all(drug_gprofiler)
## Error in eval(expr, envir, enclos): object 'drug_gprofiler' not found

12.6 Strain and time

speciestime_gprofiler <- all_gprofiler(speciestime_sva_sig)
## Error in eval(expr, envir, enclos): object 'speciestime_sva_sig' not found
written <- write_all(speciestime_gprofiler)
## Error in eval(expr, envir, enclos): object 'speciestime_gprofiler' not found

12.7 Drug and time

drugtime_gprofiler <- all_gprofiler(drugtime_sva_sig)
## Error in eval(expr, envir, enclos): object 'drugtime_sva_sig' not found
written <- write_all(drugtime_gprofiler)
## Error in eval(expr, envir, enclos): object 'drugtime_gprofiler' not found

13 GSVA

From my perspective, it seems that the most interesting GSVA comparison is to look for scores changing between the cure and fail samples. The following block therefore passes the raw expression data and performs the gene set variance analysis of it against the mSigDB C2 set of categories by default. We can pretty easily change the mSigDB release/category set; except I would need download the dataset to the container to use a newer revision and I am not sure about potential licensing restrictions; so this will just use the publicly available signatures in the ‘GSVAdata’ package.

wt_gsva <- simple_gsva(wellcome_outcome_filt, signature_category = "c7")
## Error in eval(expr, envir, enclos): object 'wellcome_outcome_filt' not found
wt_gsva
## Error in eval(expr, envir, enclos): object 'wt_gsva' not found
wt_gsva_sig <- get_sig_gsva_categories(wt_gsva, excel = "excel/CL_biopsies_gsva_outcome_c7.xlsx")
## Error in eval(expr, envir, enclos): object 'wt_gsva' not found
wt_gsva_sig
## Error in eval(expr, envir, enclos): object 'wt_gsva_sig' not found

Hmm, did I get confused, is C7 what I thought it was? Yeah, it is the immunologic signature sets. C2 is the larger set of experiments.

wellcome_gsva_c2 <- simple_gsva(wellcome_filtered, signature_category = "c2")
## Error in eval(expr, envir, enclos): object 'wellcome_filtered' not found
wellcome_gsva_c2_sig <- get_sig_gsva_categories(
  wellcome_gsva_c2,
  excel = "excel/CL_biopsies_gsva_outcome_c2.xlsx")
## Error in eval(expr, envir, enclos): object 'wellcome_gsva_c2' not found

The following blocks may be used to save and reload the state of the data.

pander::pander(sessionInfo())

R version 4.3.1 (2023-06-16)

Platform: x86_64-conda-linux-gnu (64-bit)

locale: C

attached base packages: stats4, stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: BiocParallel(v.1.36.0), variancePartition(v.1.32.5), hpgltools(v.1.0), Matrix(v.1.6-5), glue(v.1.7.0), SummarizedExperiment(v.1.32.0), GenomicRanges(v.1.54.1), GenomeInfoDb(v.1.38.8), IRanges(v.2.36.0), S4Vectors(v.0.40.2), MatrixGenerics(v.1.14.0), matrixStats(v.1.3.0), Biobase(v.2.62.0) and BiocGenerics(v.0.48.1)

loaded via a namespace (and not attached): splines(v.4.3.1), later(v.1.3.2), BiocIO(v.1.12.0), ggplotify(v.0.1.2), bitops(v.1.0-7), filelock(v.1.0.3), tibble(v.3.2.1), polyclip(v.1.10-6), graph(v.1.80.0), XML(v.3.99-0.16.1), lifecycle(v.1.0.4), Rdpack(v.2.6), doParallel(v.1.0.17), lattice(v.0.22-6), MASS(v.7.3-60.0.1), backports(v.1.4.1), magrittr(v.2.0.3), openxlsx(v.4.2.5.2), limma(v.3.58.1), plotly(v.4.10.4), sass(v.0.4.9), rmarkdown(v.2.26), jquerylib(v.0.1.4), yaml(v.2.3.8), httpuv(v.1.6.15), zip(v.2.3.1), RColorBrewer(v.1.1-3), cowplot(v.1.1.3), DBI(v.1.2.2), minqa(v.1.2.6), lubridate(v.1.9.3), abind(v.1.4-5), zlibbioc(v.1.48.2), EnvStats(v.2.8.1), purrr(v.1.0.2), ggraph(v.2.2.1), RCurl(v.1.98-1.14), yulab.utils(v.0.1.4), tweenr(v.2.0.3), rappdirs(v.0.3.3), GenomeInfoDbData(v.1.2.11), enrichplot(v.1.22.0), ggrepel(v.0.9.5), pbkrtest(v.0.5.2), tidytree(v.0.4.6), annotate(v.1.80.0), codetools(v.0.2-20), DelayedArray(v.0.28.0), ggforce(v.0.4.2), DOSE(v.3.28.2), xml2(v.1.3.6), tidyselect(v.1.2.1), aplot(v.0.2.2), farver(v.2.1.1), viridis(v.0.6.5), lme4(v.1.1-35.3), BiocFileCache(v.2.10.2), GenomicAlignments(v.1.38.2), jsonlite(v.1.8.8), tidygraph(v.1.3.1), iterators(v.1.0.14), foreach(v.1.5.2), tools(v.4.3.1), progress(v.1.2.3), treeio(v.1.26.0), Rcpp(v.1.0.12), gridExtra(v.2.3), SparseArray(v.1.2.4), xfun(v.0.43), qvalue(v.2.34.0), dplyr(v.1.1.4), withr(v.3.0.0), numDeriv(v.2016.8-1.1), BiocManager(v.1.30.22), fastmap(v.1.1.1), boot(v.1.3-30), fansi(v.1.0.6), caTools(v.1.18.2), digest(v.0.6.35), gridGraphics(v.0.5-1), timechange(v.0.3.0), R6(v.2.5.1), mime(v.0.12), colorspace(v.2.1-0), GO.db(v.3.18.0), gtools(v.3.9.5), biomaRt(v.2.58.2), RSQLite(v.2.3.6), RhpcBLASctl(v.0.23-42), utf8(v.1.2.4), tidyr(v.1.3.1), generics(v.0.1.3), data.table(v.1.15.4), corpcor(v.1.6.10), rtracklayer(v.1.62.0), graphlayouts(v.1.1.1), prettyunits(v.1.2.0), httr(v.1.4.7), htmlwidgets(v.1.6.4), S4Arrays(v.1.2.1), scatterpie(v.0.2.2), pkgconfig(v.2.0.3), gtable(v.0.3.4), blob(v.1.2.4), XVector(v.0.42.0), remaCor(v.0.0.18), shadowtext(v.0.1.3), htmltools(v.0.5.8.1), fgsea(v.1.28.0), GSEABase(v.1.64.0), scales(v.1.3.0), png(v.0.1-8), fANCOVA(v.0.6-1), ggfun(v.0.1.4), knitr(v.1.46), reshape2(v.1.4.4), rjson(v.0.2.21), nlme(v.3.1-164), curl(v.5.2.1), nloptr(v.2.0.3), cachem(v.1.0.8), stringr(v.1.5.1), KernSmooth(v.2.23-22), parallel(v.4.3.1), HDO.db(v.0.99.1), AnnotationDbi(v.1.64.1), restfulr(v.0.0.15), pillar(v.1.9.0), grid(v.4.3.1), vctrs(v.0.6.5), gplots(v.3.1.3.1), promises(v.1.3.0), dbplyr(v.2.3.4), xtable(v.1.8-4), evaluate(v.0.23), mvtnorm(v.1.2-4), cli(v.3.6.2), compiler(v.4.3.1), Rsamtools(v.2.18.0), rlang(v.1.1.3), crayon(v.1.5.2), plyr(v.1.8.9), fs(v.1.6.3), pander(v.0.6.5), stringi(v.1.8.3), viridisLite(v.0.4.2), lmerTest(v.3.1-3), munsell(v.0.5.1), Biostrings(v.2.70.3), lazyeval(v.0.2.2), aod(v.1.3.3), GOSemSim(v.2.28.1), patchwork(v.1.2.0), hms(v.1.1.3), bit64(v.4.0.5), ggplot2(v.3.5.0), KEGGREST(v.1.42.0), statmod(v.1.5.0), shiny(v.1.8.1.1), rbibutils(v.2.2.16), igraph(v.2.0.3), broom(v.1.0.5), memoise(v.2.0.1), bslib(v.0.7.0), ggtree(v.3.10.1), fastmatch(v.1.1-4), bit(v.4.0.5) and ape(v.5.8)

message("This is hpgltools commit: ", get_git_commit())
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 24f917df4a7665fa4d6050160cc8117a26eab4d5
## This is hpgltools commit: Thu Apr 18 16:11:22 2024 -0400: 24f917df4a7665fa4d6050160cc8117a26eab4d5
this_save <- paste0(gsub(pattern = "\\.Rmd", replace = "", x = rmd_file), "-v", ver, ".rda.xz")
#message("Saving to ", this_save)
tmp <- sm(saveme(filename = this_save))
## Error in save(list = ls(all.names = TRUE, envir = globalenv()), envir = globalenv(), : ignoring SIGPIPE signal
loadme(filename = this_save)
LS0tCnRpdGxlOiAiQW4gYW5hbHlzaXMgb2YgY3V0YW5lb3VzIGxlaXNobWFuaWFzaXMgYmlvcHNpZXM6IGByIFN5cy5nZXRlbnYoJ1ZFUlNJT04nKWAiCmF1dGhvcjogIk5hamliIEVsLVNheWVkIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KYm9keSwgdGQgewogIGZvbnQtc2l6ZTogMTZweDsKfQpjb2RlLnJ7CiAgZm9udC1zaXplOiAxNnB4Owp9CnByZSB7CiAgZm9udC1zaXplOiAxNnB4Cn0KYm9keSAubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTYwMHB4Owp9Cjwvc3R5bGU+CgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCmxpYnJhcnkoZ2x1ZSkKa25pdHI6Om9wdHNfa25pdCRzZXQoCiAgcHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgd2lkdGggPSA5MCwgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlcnJvciA9IFRSVUUsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4LCBmaWcucmV0aW5hID0gMiwKICBmaWcucG9zID0gInQiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZHBpID0gaWYgKGtuaXRyOjppc19sYXRleF9vdXRwdXQoKSkgNzIgZWxzZSAzMDAsCiAgb3V0LndpZHRoID0gIjEwMCUiLCBkZXYgPSAicG5nIiwKICBkZXYuYXJncyA9IGxpc3QoInBuZyIgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpKQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKAogIGRpZ2l0cyA9IDQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwga25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSkKdmVyIDwtIFN5cy5nZXRlbnYoIlZFUlNJT04iKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQgPSAiJVklbSVkIikKCnJtZF9maWxlIDwtICIwMWluZGV4LlJtZCIKc2F2ZWZpbGUgPC0gZ3N1YihwYXR0ZXJuID0gIlxcLlJtZCIsIHJlcGxhY2UgPSAiXFwucmRhXFwueHoiLCB4ID0gcm1kX2ZpbGUpCmBgYAoKIyBDb25zb2xpZGF0aW9uIG9mIGEgTW9sZWN1bGFyIFNpZ25hdHVyZSBvZiBIZWFsaW5nIGluIEN1dGFuZW91cyBMZWlzaG1hbmlhc2lzIGlzIEFjaGlldmVkIER1cmluZyB0aGUgRmlyc3QgVGVuIERheXMgb2YgVHJlYXRtZW50LgoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgZG9jdW1lbnQgcGVyZm9ybXMgYSBzZXJpZXMgb2YgZGlhZ25vc3RpY3MgYW5kIGRpZmZlcmVudGlhbApleHByZXNzaW9uIGFuYWx5c2VzIHdoaWNoIGV2ZW50dWFsbHkgaGVscGVkIGluZm9ybSB0aGUgdGV4dCBvZiBMaW5hCkZlcm5hbmRhIEdpcmFsZG8gUGFycmEncyBhbmQgTWFyaWEgQWRlbGFpZGEgR29tZXoncyBwYXBlci4gIEluIGl0LAp0aGV5IHNvdWdodCB0byB1c2UgYmlvcHNpZXMgb3ZlciB0aW1lIGZyb20gcGVvcGxlIHdobyB3ZXJlIG9ic2VydmVkIHRvCmN1cmUvZmFpbCB0cmVhdG1lbnQgb2YgY3V0YW5lb3VzIGxlaXNobWFuaWFzaXMuICBTb21lIG9mIHRoZXNlIHBlb3BsZQp3ZXJlIHRyZWF0ZWQgd2l0aCB0aGUgYW50aW1vbmlhbCAnZ2x1Y2FudGltZScsIG90aGVycyB3aXRoCm1pbHRlZm9zaW5lLiAgQmlvcHNpZXMgd2VyZSB0YWtlbiBhdCB0aGUgYmVnaW5uaW5nLCBtaWRkbGUsIGFuZCBlbmQgb2YKdHJlYXRtZW50LiAgUk5BIHdhcyB0YWtlbiBmcm9tIHRoZSBiaW9wc2llcywgbWFkZSBpbnRvIGxpYnJhcmllcywgYW5kCnNlcXVlbmNlZC4gIFRoZSBzYW1wbGVzIHdlcmUgbWFwcGVkL2NvdW50ZWQgYWdhaW5zdCBlbnNlbWJsIGhnMzgKcmVsZWFzZSAxMDAgYW5kIHRoZSBUcml0cnlwREIgTGVpc2htYW5pYSBwYW5hbWVuc2lzIE1IT00vQ09MIHN0cmFpbidzCmdlbm9tZSB3aXRoIGhpc2F0MiBhbmQgc2FsbW9uLiAgVGhlcmUgd2VyZSB2ZXJ5IGZldyByZWFkcyBvYnNlcnZlZApmcm9tIHRoZSBwYXJhc2l0ZS4gIEFzIGEgcmVzdWx0IChhdCB0aGUgdGltZSBvZiB0aGlzIHdyaXRpbmc6IDIwMjMxMCksCnRob3NlIGNvdW50IHRhYmxlcyBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSBzYW1wbGUgc2hlZXQgKHRoZXkgYXJlIG5vdywKYWxvbmcgd2l0aCB0aGUgc2FsbW9uIHF1YW50aXRhdGlvbnMgYWdhaW5zdCBoZzM4XzEwMCksIGFuZCBhcmUgbm90CmNvbnNpZGVyZWQgaW4gdGhpcyB3b3Jrc2hlZXQuCgojIENoYW5nZWxvZwoKKiAyMDIzMTAyNTogQWxsIHRoZSBQQ0EgcGxvdHMgd2VyZSBvZiBub24tZmlsdGVyZWQgZGF0YS4gIEkgcmVtb3ZlZAogIHR3byBzYW1wbGVzIGR1ZSB0byBjb3ZlcmFnZSwgc28gdGhlIHBsb3RzIHNob3VsZCBub3QKICBpbmNsdWRlIHRoZW0uICBXaGlsZSBJIGFtIGF0IGl0LCByZW5hbWUgYSBmZXcgdmFyaWFibGVzIHRvIG1ha2UKICBldmVyeXRoaW5nIG1vcmUgY29uc2lzdGVudC4gIEFsc28gZXhwbGljaXRseSB3cml0aW5nIHRoZQogIGZpZ3VyZS1waWVjZXMgdG8gdGhlICdpbWFnZXMvJyBkaXJlY3RvcnksIHByZXZpb3VzbHkgSSBqdXN0IGNyZWF0ZWQKICB0aGVtIG9uIHJlcXVlc3QuCiogMjAyMzA5LTIwMjMxMDogQ29waWVkIHRoZSB3b3Jrc2hlZXQgZnJvbSBteSBkaXJlY3RvcnkgaW50byB0aGUKICBjb250YWluZXIgYnVpbGQgdHJlZSwgcmVvcmdhbml6ZWQgaXQsIGFuZCBhZGRlZCBzb21lIHRleHQgdG8KICBob3BlZnVsbHkgYWRkcmVzcyBxdWVyaWVzL2NvbmNlcm5zIGZyb20gcmV2aWV3ZXJzIGFzIHdlbGwgYXMgY2xhcmlmeQogIHNvbWUgdGFza3MgcGVyZm9ybWVkLgoqIDIwMjItMjAyMzogQ29waWVkIE5hamliJ3Mgd29ya3NoZWV0IHRvIG15IGRpcmVjdG9yeSwgY2xlYW5lZCBpdCB1cCBhCiAgYml0LCBhbmQgZmluaXNoZWQgd2hhdCBJIHRoaW5rIGFyZSB0aGUgbGlrZWx5IGFuYWx5c2VzLgoKSSBjb2xsZWN0ZWQgdGhlIGF2YWlsYWJsZSBtZXRhZGF0YSBpbnRvIHRoZSBzaGVldCAnYWxsX3NhbXBsZXMueGxzeCcuCgojIFNhbXBsZSBzaGVldAoKYGBge3J9CnNhbXBsZXNoZWV0IDwtICJzYW1wbGVfc2hlZXRzL2FsbF9zYW1wbGVzLnhsc3giCmBgYAoKIyMgRXh0cmFjdGluZyBleHRyYSBzYW1wbGUgYW5ub3RhdGlvbnMKClRoZSBmdW5jdGlvbiAnZ2F0aGVyX3ByZXByb2Nlc3NpbmdfbWV0YWRhdGEoKScgc2NhbnMgdGhlIHdvcmtpbmcKZGlyZWN0b3J5IGluIHdoaWNoIHRoZSB2YXJpb3VzIHByZXByb2Nlc3NpbmcgdGFza3Mgd2VyZSBwZXJmb3JtZWQsCnRyaW1taW5nLCBmYXN0cWMvZmFzdHAsIG1hcHBpbmcvcXVhbnRpdGF0aW9uLCB2YXJpYW50IHNlYXJjaGluZywgZXRjLgpJdCBpcyBhd2FyZSBvZiBteSBkZWZhdWx0IG91dHB1dCBmaWxlbmFtZXMgZm9yIHN0ZG91dC9zdGRlcnIvZXRjIGFuZApleHRyYWN0cyBmcm9tIHRoZW0gdmFyaW91cyBtZXRyaWNzIHBvdGVudGlhbGx5IG9mIGludGVyZXN0LiAgSSB0aGluawp0aGUgc2FtcGxlIHNoZWV0IEkgY29waWVkIGludG8gdGhpcyBjb250YWluZXIgaXMgdGhlIHJlc3VsdCBvZiB0aGUKZm9sbG93aW5nIGJsb2NrLCBzbyBJIGFtIG5vdCBnb2luZyB0byBldmFsdWF0ZSBpdCBoZXJlLgoKYGBge3IgZ2F0aGVyX3ByZXByb2Nlc3NpbmcsIGV2YWw9RkFMU0V9CnJuYV9zcGVjIDwtIG1ha2Vfcm5hc2VxX3NwZWMoKQptb2RpZmllZCA8LSBnYXRoZXJfcHJlcHJvY2Vzc2luZ19tZXRhZGF0YShzYW1wbGVzaGVldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWNhdGlvbiA9IHJuYV9zcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhnMzhfMTAwIikKYGBgCgojIEFubm90YXRpb24KCldlIHRha2UgdGhlIGFubm90YXRpb24gZGF0YSBmcm9tIGVuc2VtYmwncyBiaW9tYXJ0IGluc3RhbmNlLiAgVGhlIGdlbm9tZSB3aGljaAp3YXMgdXNlZCB0byBtYXAgdGhlIGRhdGEgd2FzIGhnMzggcmV2aXNpb24gMTAwLiAgTXkgZGVmYXVsdCB3aGVuIHVzaW5nIGJpb21hcnQgaXMKdG8gbG9hZCB0aGUgZGF0YSBmcm9tIDEgeWVhciBiZWZvcmUgdGhlIGN1cnJlbnQgZGF0ZS4KCmBgYHtyfQpoc19hbm5vdCA8LSBsb2FkX2Jpb21hcnRfYW5ub3RhdGlvbnMoeWVhciA9ICIyMDE5IikKaHNfYW5ub3QKCmhzX2Fubm90IDwtIGhzX2Fubm90W1siYW5ub3RhdGlvbiJdXQpoc19hbm5vdFtbInRyYW5zY3JpcHQiXV0gPC0gcGFzdGUwKHJvd25hbWVzKGhzX2Fubm90KSwgIi4iLCBoc19hbm5vdFtbInZlcnNpb24iXV0pCnJvd25hbWVzKGhzX2Fubm90KSA8LSBtYWtlLm5hbWVzKGhzX2Fubm90W1siZW5zZW1ibF9nZW5lX2lkIl1dLCB1bmlxdWUgPSBUUlVFKQp0eF9nZW5lX21hcCA8LSBoc19hbm5vdFssIGMoInRyYW5zY3JpcHQiLCAiZW5zZW1ibF9nZW5lX2lkIildCmBgYAoKIyMgR2VuZSBPbnRvbG9neSBkYXRhCgpEb3dubG9hZGluZyB0aGUgT250b2xvZ3kgYW5ub3RhdGlvbiBpbmZvcm1hdGlvbiBoYXMgYSBzaWduaWZpY2FudApjaGFuY2Ugb2YgZmFpbGluZyBiZWNhdXNlIGl0IHNvbWV0aW1lcyB0YWtlcyBsb25nZXIgdGhhbiBjdXJsJ3MKdGltZW91dCBvZiAzMDAgc2Vjb25kcy4gIEFzIGEgcmVzdWx0LCBJIG1heSBkZWNpZGUgdG8gaW5jbHVkZSB0aGUKc2F2ZWQgcmRhIG9mIG9udG9sb2d5IHJlc3VsdHMgaW4gdGhlIGNvbnRhaW5lciwgb3IgbWF5YmUgaW1wcm92ZSBteQpvbnRvbG9neSBkb3dubG9hZGVyIHNvIHRoYXQgaXQgaXMgbm8gbG9uZ2VyIHN1c2NlcHRpYmxlIHRvIHRpbWVvdXRzLi4uCgpBY3R1YWxseSwgSSBkbyBub3QgdGhpbmsgSSBhbSB1c2luZwpjbHVzdGVyUHJvZmlsZXIvZ29zdGF0cy9nb3NlcS90b3BnbyBpbiB0aGlzIGRvY3VtZW50LCBwZXJoYXBzCnRoZXJlZm9yZSBJIHNob3VsZCBqdXN0IGV4Y2x1ZGUgdGhpcyBibG9jaz8gIFllYWgsIGl0IHNlZW1zIGxpa2UgdGhlcmUKaXMgYSA1MC81MCBjaGFuY2UgdGhhdCB0aGlzIHdpbGwgZmFpbCB3aGVuIHJ1biB3aXRoaW4gdGhlIGNvbnRhaW5lciwKYW5kIEkgYW0gY3VycmVudGx5IG5vdCB1c2luZyB0aGlzIHNldCBvZiBnZW5lOkdPIG1hcHBpbmdzIGluIHRoaXMgZG9jdW1lbnQuCgpgYGB7ciwgZXZhbD1GQUxTRX0KaHNfZ28gPC0gbG9hZF9iaW9tYXJ0X2dvKG92ZXJ3cml0ZSA9IFRSVUUpCmhzX2dvCmhzX2dvIDwtIGhzX2dvW1siZ28iXV0KaHNfbGVuZ3RoIDwtIGhzX2Fubm90WywgYygiZW5zZW1ibF9nZW5lX2lkIiwgImNkc19sZW5ndGgiKV0KY29sbmFtZXMoaHNfbGVuZ3RoKSA8LSBjKCJJRCIsICJsZW5ndGgiKQpgYGAKCiMgQ3JlYXRlIGV4cHJlc3Npb25zZXRzCgpUaGUgcHJpbWFyeSBkYXRhc3RydWN0dXJlIHVzZWQgdGhyb3VnaG91dCB0aGlzIGRvY3VtZW50IGlzIHRoZQpleHByZXNzaW9uU2V0IG9yIHN1bW1hcml6ZWQgRXhwZXJpbWVudC4gIFRoaXMgZG9jdW1lbnQgdXNlcyB0aGUKZm9ybWVyOyBidXQgYm90aCBhcmUgY3JlYXRlZCBieSByZWFkaW5nIHRoZSBzYW1wbGUgc2hlZXQsIGV4dHJhY3RpbmcKdGhlIGZpbGVuYW1lcyBvZiB0aGUgY291bnQgZGF0YSBmcm9tIGl0LCBhbmQgY29tYmluaW5nIHRoZSBtZXRhZGF0YSwKYW5ub3RhdGlvbiBkYXRhLCBhbmQgY291bnRzLiAgTXkgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBwcm9jZXNzIGFsc28KaW5jbHVkZXMgYSBmZXcgZXh0cmEgcGllY2VzIG9mIGluZm9ybWF0aW9uLiAgRm9yIGV4YW1wbGU6IHRoZSBjb2xvcnMKb2YgdmFyaW91cyBwb3RlbnRpYWwgY29uZGl0aW9ucyBpbiB0aGUgZGF0YS4KCiMjIENvbG9yIGNob2ljZXMKCkJlZm9yZSB3ZSBjcmVhdGUgdGhlIGRhdGFzdHJ1Y3R1cmVzLCBJIHdhbnQgdG8gaGF2ZSB0aGUgdmFyaW91cyBjb2xvcgpzY2hlbWVzIGluIHBsYWNlLiAgTWFueSBvZiB0aGVzZSBjb2xvciBjaG9pY2VzIGFyZSB0YWtlbiBkaXJlY3RseSBmcm9tCmFub3RoZXIgcHJvamVjdCB3aGljaCBhbHNvIGxvb2tzIGF0IGhvc3QgcmVzcG9uc2VzLgoKYGBge3J9CmNvbG9yX2Nob2ljZXMgPC0gbGlzdCgKICAiY2ZfdmlzaXQiID0gbGlzdCgKICAgICJjdXJlX3YxIiA9ICIjRDk1RjBFIiwKICAgICJmYWlsdXJlX3YxIiA9ICIjRkVDNDRGIiwKICAgICJjdXJlX3YyIiA9ICIjREQxQzc3IiwKICAgICJmYWlsdXJlX3YyIiA9ICIjQzk5NEM3IiwKICAgICJjdXJlX3YzIiA9ICIjMzE4MkJEIiwKICAgICJmYWlsdXJlX3YzIiA9ICIjOUVDQUUxIiksCiAgImRydWdfdmlzaXQiID0gbGlzdCgKICAgICJhbnRpbW9uaWF0ZV92MSIgPSAiI2JhZGVlZiIsCiAgICAibWlsdGVmb3NpbmVfdjEiID0gIiNlNGE2YzEiLAogICAgImFudGltb25pYXRlX3YyIiA9ICIjN2JjNmVhIiwKICAgICJtaWx0ZWZvc2luZV92MiIgPSAiI2QyNjg5NSIsCiAgICAiYW50aW1vbmlhdGVfdjMiID0gIiMxZDkxY2EiLAogICAgIm1pbHRlZm9zaW5lX3YzIiA9ICIjZDUyZTc1IiksCiAgInNwZWNpZXNfdmlzaXQiID0gbGlzdCgKICAgICJsdnBhbmFtZW5zaXNfdjEiID0gIiNmZmU3OTgiLAogICAgImx2YnJhemlsaWVuc2lzX3YxIiA9ICIjYjViNWI1IiwKICAgICJsdnBhbmFtZW5zaXNfdjIiID0gIiNGRkMzMDAiLAogICAgImx2YnJhemlsaWVuc2lzX3YyIiA9ICIjODg4ODg4IiwKICAgICJsdnBhbmFtZW5zaXNfdjMiID0gIiNiNThiMDAiLAogICAgImx2YnJhemlsaWVuc2lzX3YzIiA9ICIjNTI1MjUyIiksCiAgImNmIiA9IGxpc3QoCiAgICAiY3VyZSIgPSAiIzk5OEVDMyIsCiAgICAiZmFpbHVyZSIgPSAiI0YxQTM0MCIpLAogICJ2aXNpdCIgPSBsaXN0KAogICAgInYxIiA9ICIjMzNFRTMzIiwKICAgICJ2MiIgPSAiIzExQUExMSIsCiAgICAidjMiID0gIiMxMzQ0MTMiKSwKICAidmlzaXRiaSIgPSBsaXN0KAogICAgInYxIiA9ICIjQkIwMDAwIiwKICAgICJ2b3RoZXIiID0gIiMwMDAwQkIiKSwKICAic3BlY2llcyIgPSBsaXN0KAogICAgImx2cGFuYW1lbnNpcyIgPSAiI0ZGQzMwMCIsCiAgICAibHZicmF6aWxpZW5zaXMiID0gIiM1MjUyNTIiKSwKICAiZG9ub3IiID0gbGlzdCgKICAgICJkMjAwOCIgPSAiI0I3ODQxNSIsCiAgICAiZDEwMjkiID0gIiM5Mzc1MkMiLAogICAgImQxMDM2IiA9ICIjN0U2RUEyIiwKICAgICJkMTAzNyIgPSAiI0IzNDk5QyIsCiAgICAiZDEwMzEiID0gIiNCRDYzMzIiLAogICAgImQyMDAyIiA9ICIjN0Q4RjMxIiwKICAgICJkMjAwOSIgPSAiIzhFNzAzNyIsCiAgICAiZDIwMTAiID0gIiM2NjY2NjYiLAogICAgImQxMDE5IiA9ICIjMUI5RTc3IiwKICAgICJkMjAwNCIgPSAiI0UwQTYwNCIsCiAgICAiZDIwMDEiID0gICIjQ0YzRjc2IiwKICAgICJkMjAwMyIgPSAiI0EwQTgxMSIpLAogICJkcnVnIiA9IGxpc3QoCiAgICAiYW50aW1vbmlhdGUiID0gIiMzMTgyQUEiLAogICAgIm1pbHRlZm9zaW5lIiA9ICIjQzk5NEFBIikpCmBgYAoKVGhlIHNldCBvZiBjb2xvciBjaG9pY2VzIGRlbW9uc3RyYXRlcyB0aGUgY29tcGxleGl0eSBvZiB0aGUKZXhwZXJpbWVudGFsIGRlc2lnbi4gIFdlIGFyZSBsb29raW5nIGF0IGNvbWJpbmF0aW9ucyBvZiB0aW1lLCBvdXRjb21lLApzcGVjaWVzLCBhbmQgZHJ1Zy4gIEluaGVyZW50IGluIGFsbCBvZiB0aGVzZSBpcyBhbiBvdmVyYXJjaGluZyBkb25vcgplZmZlY3QuCgojIyBJbml0aWFsIGRhdGFzZXQ6IENvbWJpbmUgY2xpbmljYWwgb3V0Y29tZSB3aXRoIHZpc2l0CgpUaGUgaW5pdGlhbCBkYXRhc3RydWN0dXJlIHdpbGwgdXNlIGEgZmFjdG9yIGNvbWJpbmluZyB0aGUgY2xpbmljYWwKb3V0Y29tZSBhbmQgdmlzaXQgYXMgdGhlIGV4cGVyaW1lbnRhbCBjb25kaXRpb24gb2YgaW50ZXJlc3QuICBXZSB3aWxsCmZvbGxvdyB0aGlzIHVwIGJ5IHNwbGl0dGluZyBvZmYgdGhlIHZhcmlvdXMgZmFjdG9ycyBvZiBpbnRlcmVzdC4KCkFuIGFzaWRlOiB3aGVuIHRlc3RpbmcgdGhlIGZvbGxvd2luZyBibG9jayB3aXRoaW4gdGhlIGNvbnRhaW5lciwgaXQKZGlkIG5vdCBwcmludCBvdXQgdGhlIGZpbGVuYW1lcyBhcyBpdCB3YXMgcmVhZGluZyB0aGVtLCB1c3VhbGx5IGl0CmRvZXMuICBJIGFzc3VtZSB0aGlzIGlzIG5vdCBhIHByb2JsZW0gc2luY2UgdGhlIGRhdGEgbG9va3MgZmluZSwgYnV0CnRoaXMgbWF5IHdhcnJhbnQgZnVydGhlciBleHBsb3JhdGlvbi4KClRoZSBjYWxsIHRvIHNhbml0aXplX2V4cHRfcERhdGEoKSB0cmllcyB0byBlbnN1cmUgdGhhdCBFeGNlbCBkb2VzIG5vdAptZXNzIHRoaW5ncyB1cCB3aXRoIHJhbmRvbSBzcGFjZXMvY2FwaXRhbGl6YXRpb24gaW4gdGhlIG1ldGFkYXRhLgoKYGBge3J9CndlbGxjb21lX291dHRpbWUgPC0gY3JlYXRlX2V4cHQobWV0YWRhdGEgPSBzYW1wbGVzaGVldCwgZ2VuZV9pbmZvID0gaHNfYW5ub3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW4gPSAiaGczODEwMGhpc2F0ZmlsZSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJkcnVnIikgJT4lCiAgc2FuaXRpemVfZXhwdF9wRGF0YShzcGFjZXMgPSBUUlVFKQp3ZWxsY29tZV9vdXR0aW1lCmBgYAoKVGhlIHByZXZpb3VzIGJsb2NrIGNyZWF0ZXMgdGhlIHByaW1hcnkgZGF0YXN0cnVjdHVyZSwgZXZlcnl0aGluZyBmcm9tCm5vdyBvbiB3aWxsIGVpdGhlcjoKCiogQWRkIGNhdGVnb3JpZXMgdG8gaXQgKHRoZSBuZXh0IGJsb2NrKQoqIFNldCB2YXJpb3VzIGNhdGVnb3JpZXMgdG8gdGhlIHByaW1hcnkgZmFjdG9yIG9mIGludGVyZXN0CiAgKHNldF9leHB0X2NvbmRpdGlvbnMoKS9zZXRfZXhwdF9iYXRjaGVzKCkpCiogU3Vic2V0IHRoZSBkYXRhIHRvIGhpZ2hsaWdodCBpbmRpdmlkdWFsIHF1ZXN0aW9ucyBvciByZW1vdmUgdGhlIHR3bwogIChJIHRoaW5rIHR3bywgZG91YmxlIGNoZWNrIHRoaXMpIGxvdy1jb3ZlcmFnZSBzYW1wbGVzLgoqIE5vcm1hbGl6ZS9hbmFseXplIHRoZSBhYm92ZS4KClRoZSBmb2xsb3dpbmcgYmxvY2sgdGhlcmVmb3JlIGNyZWF0ZXMgYSBzZXQgb2YgZmFjdG9ycyB3aGljaCBhcmUgdGhlCmNvbmNhdGVuYXRpb24gb2YgdGltZSt4IHdoZXJlIHggaXMgb25lIG9mOiBvdXRjb21lLCBkcnVnLCBzcGVjaWVzLgoKYGBge3J9Cm91dGNvbWVfdGltZSA8LSBwYXN0ZTAocERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJjbGluaWNhbG91dGNvbWUiXV0sICJfdiIsCiAgICAgICAgICAgICAgICAgICAgICAgcERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJ2aXNpdG51bWJlciJdXSkKd2VsbGNvbWVfb3V0dGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSBvdXRjb21lX3RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnMgPSBjb2xvcl9jaG9pY2VzW1siY2ZfdmlzaXQiXV0pCgpwRGF0YSh3ZWxsY29tZV9vdXR0aW1lKVtbInZpc2l0bnVtYmVyIl1dIDwtIHBhc3RlMCgidiIsIHBEYXRhKHdlbGxjb21lX291dHRpbWUpW1sidmlzaXRudW1iZXIiXV0pCnBEYXRhKHdlbGxjb21lX291dHRpbWUpW1sib3V0Y29tZV92aXNpdCJdXSA8LSBvdXRjb21lX3RpbWUKcERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJkcnVnX3Zpc2l0Il1dIDwtIHBhc3RlMChwRGF0YSh3ZWxsY29tZV9vdXR0aW1lKVtbImRydWciXV0sICJfIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRGF0YSh3ZWxsY29tZV9vdXR0aW1lKVtbInZpc2l0bnVtYmVyIl1dKQpwRGF0YSh3ZWxsY29tZV9vdXR0aW1lKVtbInNwZWNpZXNfdmlzaXQiXV0gPC0gcGFzdGUwKHBEYXRhKHdlbGxjb21lX291dHRpbWUpW1siaW5mZWN0aW5nc3BlY2llcyJdXSwgIl8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBEYXRhKHdlbGxjb21lX291dHRpbWUpW1sidmlzaXRudW1iZXIiXV0pCmBgYAoKIyMgQ2hlY2sgc2FtcGxlcwoKRmlyc3QsIGxldCB1cyBnZXQgYSBxdWljayB2aWV3IG9mIHRoZSBzYW1wbGVzIGluIHRoZWlyIG5hdGl2ZSBzdGF0ZS4KVGhlcmUgYXJlIGEgZmV3IHNhbXBsZXMgd2hpY2ggYXJlIGNhbmRpZGF0ZXMgZm9yIHJlbW92YWwgZHVlIHRvIGxvd2VyCmNvdmVyYWdlLgoKUmFuZG9tIGFzaWRlOiBJIGhhdmUgc29tZSBuaWZ0eSBjb2RlIHdoaWNoIHRyaWVzIHRvIGF1dG9kZXRlY3Qgd2hlbiB0bwpjb2xvciB0aGUgdGV4dCBpbiB0aGUgY29sb3JlZCBiYXJzIHdoaXRlIG9yIGJsYWNrLiAgVGhlIHB1cnBsZS9waW5rCmNvbG9yIHRyaWNrcyB0aGF0IGNvZGUgaW50byB0aGlua2luZyBpdCBpcyBkYXJrIGVub3VnaCB0byBiZSBjb2xvcmVkCndoaXRlLgoKKiBGSVhNRSBwbG90X2xpYnNpemUoKSB0ZXh0IGNvbG9yIGhldXJpc3RpYy4KCmBgYHtyfQpwbG90X2xlZ2VuZCh3ZWxsY29tZV9vdXR0aW1lKQpwbG90X2xpYnNpemUod2VsbGNvbWVfb3V0dGltZSkKcGxvdF9ub256ZXJvKHdlbGxjb21lX291dHRpbWUsIHBsb3RfbGFiZWxzID0gInJlcGVsIikKCndlbGxjb21lX2ZpbHRlcmVkIDwtIHN1YnNldF9leHB0KHdlbGxjb21lX291dHRpbWUsIG5vbnplcm8gPSAxNTAwMCkKYGBgCgojIyBXcml0ZSBhbGwgdGhlIHNhbXBsZSBkYXRhCgpUaGUgZm9sbG93aW5nIHdyaXRlcyBvdXQgdGhlIGRhdGEgaW4gdHdvIGZpbGVzLCBvbmUgYmVmb3JlIGFuZCBhZnRlcgpmaWx0ZXJpbmcgZm9yIHNhbXBsZXMgd2l0aCBsZXNzIHRoYW4gMTUsMDAwIG9ic2VydmVkIGdlbmVzLgoKYGBge3J9CndyaXR0ZW4gPC0gd3JpdGVfZXhwdCh3ZWxsY29tZV9vdXR0aW1lLAogICAgICAgICAgICAgICAgICAgICAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19hbGxfZGF0YS12e3Zlcn0ueGxzeCIpKQp3cml0dGVuIDwtIHdyaXRlX2V4cHQod2VsbGNvbWVfZmlsdGVyZWQsCiAgICAgICAgICAgICAgICAgICAgICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX2ZpbHRlcmVkX2RhdGEtdnt2ZXJ9Lnhsc3giKSkKYGBgCgpMb29raW5nIGF0IHRoZSBub256ZXJvIHBsb3QsIGl0IHNlZW1zIHRoYXQgMTVrIGdlbmVzIGlzIGEgcmVhc29uYWJsZQpjdXRvZmYsIHdoaWNoIHdvdWxkIHJlbW92ZSAyIHNhbXBsZXMuICBTbywgZm9yIHRoZSBtb21lbnQgSSB3aWxsIHNwbGl0CnRoZSBkYXRhIHVwIGludG8gdHdvIHNldHMsIHByZS9wb3N0IHJlbW92YWwuCgojIyBVcGxvYWQgQ1BNIHZhbHVlcwoKTGluYSBhc2tlZCBmb3IgYSBDU1YgY29weSBvZiB0aGUgZGF0YSBhcyBDUE0uCgpgYGB7cn0Kd2VsbGNvbWVfY3BtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX2ZpbHRlcmVkLCBmaWx0ZXIgPSBUUlVFLCBjb252ZXJ0ID0gImNwbSIpCndlbGxjb21lX2NwbV9tdHJ4IDwtIGV4cHJzKHdlbGxjb21lX2NwbSkKd2VsbGNvbWVfY3BtX3dyaXRlIDwtIHdyaXRlLmNzdih4ID0gd2VsbGNvbWVfY3BtX210cngsIGZpbGUgPSAiZXhjZWwvQ0xfYmlvcHNpZXNfZmlsdGVyZWRfY3BtLmNzdiIpCgp3ZWxsY29tZV9zY3BtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX2ZpbHRlcmVkLCBmaWx0ZXIgPSBUUlVFLCBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gInN2YXNlcSIpCndlbGxjb21lX3NjcG1fbXRyeCA8LSBleHBycyh3ZWxsY29tZV9zY3BtKQp3ZWxsY29tZV9zY3BtX3dyaXRlIDwtIHdyaXRlLmNzdih4ID0gd2VsbGNvbWVfY3BtX210cngsIGZpbGUgPSAiZXhjZWwvQ0xfYmlvcHNpZXNfZmlsdGVyZWRfY3BtX3N2YS5jc3YiKQpgYGAKCiMjIENoZWNrIHNhbXBsZXMKCldlIGhhdmUgaW4gcGxhY2Ugc29tZSBpbml0aWFsIGRhdGFzdHJ1Y3R1cmVzOyBsZXQgdXMgbWl4IGFuZCBtYXRjaAp0aGVtIHRvIGdldCBhIHNlbnNlIG9mIHRoZSBkYXRhLiAgVGhlcmUgYXJlIGEgZmV3IGZhY3RvcnMgaW4gdGhlCmV4cGVyaW1lbnQgdGhhdCBhcmUgbGlrZWx5IG9mIHByaW1hcnkgaW50ZXJlc3Q6IHRoZSBkb25vciwgdGltZSwgZHJ1Zwp1c2VkLCBwYXJhc2l0ZSBzcGVjaWVzL3N0cmFpbiwgYW5kIGNsaW5pY2FsIG91dGNvbWUuICBUaGVyZSBhcmUgdG9vCm1hbnkgZmFjdG9ycyBmb3IgdGhlIG51bWJlciBvZiBzYW1wbGVzIHRvIGRvIGEgZnVsbCByYW5rIG1vZGVsLCBzbyBJCmFtIGdvaW5nIHRvIG1ha2UgY29waWVzIG9mIHRoZSBleHByZXNzaW9uc2V0IGFuZCBtb2RlbCBlYWNoIGZhY3RvcgpzZXBhcmF0ZWx5IHdpdGggdGhlIGhlbHAgb2Ygc3ZhLgoKIyMgT25seSBkb25vcgoKU3RhcnQgd2l0aCB0aGUgZG9ub3IuICBUaGVyZSBhcmUgMTIgcGVvcGxlLCBtb3N0IG9mIHdob20gcHJvdmlkZWQKdGhyZWUgc2FtcGxlcy4gVHdvIG9mIHRoZW0gKGQyMDAyIGFuZCBkMjAwOSkgaGFkIHNhbXBsZXMgd2hpY2ggZ290CmV4Y2x1ZGVkIGFuZCBzbyBoYXZlIG9ubHkgMi4gIEkgYW0gc2VwYXJhdGluZyB0aGUgdW4vZmlsdGVyZWQgZGF0YXNldHMKc28gdGhhdCB3ZSBtYXkgcGxheSB3aXRoIGJvdGggaWYgd2Ugd2FudC4KCmBgYHtyfQp3ZWxsY29tZV9kb25vciA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSAiZG9ub3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXMpCgp3ZWxsY29tZV9kb25vcl9maWx0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfZmlsdGVyZWQsIGZhY3QgPSAiZG9ub3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlcykKYGBgCgojIyBPbmx5IHZpc2l0CgpJbiB0aGlzIGNhc2UsIHRoZSBjb25kaXRpb24gd2lsbCBvbmx5IGJlIHZpc2l0IG51bWJlci4gIFdlIGhhdmUgMTIKc2FtcGxlcyBmb3IgZWFjaCB2aXNpdCwgZXhjZXB0IHYxL3YzIHdoaWNoIGFyZSBtaXNzaW5nIDEgZWFjaC4KCmBgYHtyfQp3ZWxsY29tZV90aW1lIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJ2aXNpdG51bWJlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnMgPSBjb2xvcl9jaG9pY2VzW1sidmlzaXQiXV0pCgp3ZWxsY29tZV90aW1lX2ZpbHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh3ZWxsY29tZV9maWx0ZXJlZCwgZmFjdCA9ICJ2aXNpdG51bWJlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbInZpc2l0Il1dKQpgYGAKCiMjIE9ubHkgQ3VyZS9GYWlsCgpDb252ZXJzZWx5LCB3ZSBjYW4gc3BsaXQgYnkgY2xpbmljYWwgb3V0Y29tZS4gIFRoZSB1bmZpbHRlcmVkIGRhdGFzZXQKaGFzIDE1IGN1cmVzIGFuZCAyMSBmYWlsdXJlczsgYm90aCBmaWx0ZXJlZCBzYW1wbGVzIHdlcmUgZmFpbHVyZS4KCmBgYHtyfQp3ZWxsY29tZV9vdXRjb21lIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbImNmIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQoKd2VsbGNvbWVfb3V0Y29tZV9maWx0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfZmlsdGVyZWQsIGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbImNmIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQpgYGAKCiMjIE9ubHkgZHJ1ZwoKV2l0aCByZXNwZWN0IHRvIGRydWcgdHJlYXRtZW50LCB3ZSBzdGFydGVkIHdpdGggMTggb2YgZWFjaC4gIFRoZSBsb3N0CnNhbXBsZXMgd2VyZSBib3RoIG1pbHRlZm9zaW5lLgoKYGBge3J9CndlbGxjb21lX2RydWcgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh3ZWxsY29tZV9vdXR0aW1lLCBmYWN0ID0gImRydWciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbImRydWciXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ2aXNpdG51bWJlciIpCgp3ZWxsY29tZV9kcnVnX2ZpbHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh3ZWxsY29tZV9maWx0ZXJlZCwgZmFjdCA9ICJkcnVnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbImRydWciXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ2aXNpdG51bWJlciIpCmBgYAoKIyMgT25seSBwYXJhc2l0ZQoKV2Ugc3RhcnRlZCB3aXRoIDEyIGJyYXppbGllbnNpcyBhbmQgMjQgcGFuYW1lbnNpczsgb25lIG9mIGVhY2ggd2FzIGxvc3QuCgpgYGB7cn0Kd2VsbGNvbWVfcGFyYXNpdGUgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh3ZWxsY29tZV9vdXR0aW1lLCBmYWN0ID0gImluZmVjdGluZ3NwZWNpZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXNbWyJzcGVjaWVzIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQoKd2VsbGNvbWVfcGFyYXNpdGVfZmlsdCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX2ZpbHRlcmVkLCBmYWN0ID0gImluZmVjdGluZ3NwZWNpZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbInNwZWNpZXMiXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ2aXNpdG51bWJlciIpCmBgYAoKIyMgVmlzdWFsaXplIHRoZSBtZXRhZGF0YQoKRXZlcnl0aGluZyBJIHdyb3RlIGFib3ZlIGlzIHZpc2libGUgaW4gdGhlIGZvbGxvd2luZyBzYW5rZXkgcGxvdC4gIEl0CmlzIHBhcnRpY3VsYXJseSBub3Rld29ydGh5IHRoYXQgd2UgaGF2ZSBubyBjdXJlIGJyYXppbGllbnNpcyBmb3IKbWlsdGVmb3NpbmUgdHJlYXRtZW50IGFuZCBvbmx5IDEgZm9yIGVhY2ggb2YgdGhlIGFudG9taW5pYWwKdGltZXBvaW50cy4KCmBgYHtyfQpkcnVnX3Zpc2l0X3NwZWNpZXNfY2YgPC0gcGxvdF9tZXRhX3NhbmtleSgKICB3ZWxsY29tZV9maWx0ZXJlZCwgZmFjdG9ycyA9IGMoImRydWciLCAidmlzaXRudW1iZXIiLCAiY2xpbmljYWxvdXRjb21lIiwgImluZmVjdGluZ3NwZWNpZXMiKSwKICBjb2xvcl9jaG9pY2VzID0gY29sb3JfY2hvaWNlcykKZHJ1Z192aXNpdF9zcGVjaWVzX2NmCmBgYAoKIyBWaXN1YWxpemUgc2FtcGxlcwoKR2l2ZW4gdGhlIGxhcmdlIG51bWJlciBvZiB2YXJpYWJsZXMgaW4gdGhpcyBkYXRhLCBsZXRzIHN0YXJ0IGJ5CmdldHRpbmcgYSBmZWVsaW5nIGZvciB0aGUgYW1vdW50IG9mIHZhcmlhbmNlIGluIGVhY2guICBHaXZlbiB0aGF0IHdlCmRvbid0IGhhdmUgYSBmdWxsIHJhbmsgd2l0aCByZXNwZWN0IHRvIGNsaW5pY2FsIG91dGNvbWUsIEkgYXNzdW1lIHRoYXQKdHJ5aW5nIHZhcmlhbmNlIHBhcnRpdGlvbiB3aXRoIHRoZSA0IHByaW1hcnkgZmFjdG9ycyB3aWxsIGZhaWwsIGJ1dApsZXQgdXMgc2VlLi4uCgpgYGB7cn0KdmFycGFydF9kb25vciA8LSBzaW1wbGVfdmFycGFydCgKICB3ZWxsY29tZV9maWx0ZXJlZCwKICBmYWN0b3JzID0gYygiZG9ub3IiLCAidmlzaXRudW1iZXIiKSkKdmFycGFydF9kb25vcgoKdmFycGFydF9kdmljIDwtIHNpbXBsZV92YXJwYXJ0KAogIHdlbGxjb21lX2ZpbHRlcmVkLAogIGZhY3RvcnMgPSBjKCJkcnVnIiwgInZpc2l0bnVtYmVyIiwgImluZmVjdGluZ3NwZWNpZXMiLCAiY2xpbmljYWxvdXRjb21lIikpCnZhcnBhcnRfZHZpYwpgYGAKClRvIG15IGV5ZXMsIGl0IGFwcGVhcnMgdGhhdCBkb25vciBpcyBkb21pbmFudCBmYWN0b3IsCmZvbGxvd2VkIGJ5OiB2aXNpdCwgc3BlY2llcywgZHJ1ZywgYW5kIG91dGNvbWUuICBJIHRoaW5rIHRoaXMKb2JzZXJ2YXRpb24gbWF5IGhhdmUgYW4gZWZmZWN0IG9uIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZQptYW51c2NyaXB0IC0gd2hpY2ggaWYgSSByZWNhbGwgcHJvcGVybHkgc3RhdGVzIHRoYXQgZG9ub3IgaXMgbm90IGEKc2lnbmlmaWNhbnQgZmFjdG9yIGluIHRoZSBkYXRhLgoKIyMgRXhhbWluZSB0b3AtbiBnZW5lcyB3aXRoIHJlc3BlY3QgdG8gdmFyaWFuY2Ugb2Ygc29tZSBmYWN0b3JzCgpMZXQgdXMgYXNrIGlmIHRoZXJlIGFyZSBjYXRlZ29yaWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2VuZXMKYXNzb2NpYXRlZCB3aXRoIGVhY2ggb2YgdGhlc2UgY2F0ZWdvcmllcyBhbmQgc2VlIGlmIHRoZXkgJ21ha2Ugc2Vuc2UnLgoKYGBge3J9CnRvcF8zMDBfZG9ub3JfZ2VuZXNfaWR4IDwtIG9yZGVyKHZhcnBhcnRfZG9ub3JbWyJmaXR0ZWRfZGYiXV1bWyJkb25vciJdXSkKdG9wXzMwMF9kb25vcl9nZW5lcyA8LSB0YWlsKHZhcnBhcnRfZG9ub3JbWyJmaXR0ZWRfZGYiXV1bdG9wXzMwMF9kb25vcl9nZW5lc19pZHgsIF0sIG4gPSAzMDApCnN1bW1hcnkodG9wXzMwMF9kb25vcl9nZW5lcykKZG9ub3JfZ2VuZXNfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihyb3duYW1lcyh0b3BfMzAwX2Rvbm9yX2dlbmVzKSkKZG9ub3JfZ2VuZXNfZ3AKZG9ub3JfZ2VuZXNfZ3AkcHZhbHVlX3Bsb3RzJFJFQUMKYGBgCgpTbywgdGhlIHRvcC0zMDAgZ2VuZXMgd2l0aCByZXNwZWN0IHRvIHB1dGF0aXZlIGRvbm9yIGVmZmVjdCwgd2hlbgpwYXNzZWQgdG8gZ3Byb2ZpbGVyJ3Mgb3ZlciByZXByZXNlbnRhdGlvbiBhbmFseXNlcywgbG9vayBsaWtlIHRoZXkKaGF2ZSBsb3RzIG9mIHZhcmlhbmNlIHJlbGF0ZWQgdG8gY2F0ZWdvcmllcyB0aGF0IGFyZSBleHBsaWNpdGx5CmltcG9ydGFudCB0byB0aGUgZ2VuZXJhbCBxdWVzdGlvbnMgd2UgYXJlIGFza2luZy4gIEkgdGhpbmsgdGhhdCBjb3VudHMKYXM6IFlheSEKCk5vdyBsZXQgdXMgbG9vayBhdCB0aGUgb3RoZXIgZmFjdG9ycyBpbiB0aGUgZGF0YSBhbmQgc2VlIGlmIGFueXRoaW5nCm5vdGV3b3J0aHkgcG9wcyBvdXQuICBHaXZlbiB0aGF0IHRoZSBkdmljIGRhdGFzdHJ1Y3R1cmUgY29tcHJpc2VzIHRoZQpvdGhlciBmYWN0b3JzIG9mIGludGVyZXN0LCB3ZSB3aWxsIG5lZWQgdG8gcmVvcmRlciB0aGUgcmVzdWx0cyB3aXRoCnJlc3BlY3QgdG8gZWFjaCBmYWN0b3Igc2VwYXJhdGVseS4KCiMjIyBWaXNpdAoKVmlzaXQgYWxzbyBpcyBkb21pbmF0ZWQgYnkgdmFyaWFuY2Ugd2hpY2ggaXMgZXhwbGljaXRseSB3aGF0IG9uZSB3b3VsZCBleHBlY3Q6CndvdW5kIGhlYWxpbmcuCgpgYGB7cn0KdG9wXzMwMF92aXNpdF9nZW5lc19pZHggPC0gb3JkZXIodmFycGFydF9kdmljW1siZml0dGVkX2RmIl1dW1sidmlzaXRudW1iZXIiXV0pCnRvcF8zMDBfdmlzaXRfZ2VuZXMgPC0gdGFpbCh2YXJwYXJ0X2R2aWNbWyJmaXR0ZWRfZGYiXV1bdG9wXzMwMF92aXNpdF9nZW5lc19pZHgsIF0sIG4gPSAzMDApCnN1bW1hcnkodG9wXzMwMF92aXNpdF9nZW5lcykKdmlzaXRfZ2VuZXNfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihyb3duYW1lcyh0b3BfMzAwX3Zpc2l0X2dlbmVzKSkKdmlzaXRfZ2VuZXNfZ3AKYGBgCgojIyMgRHJ1ZwoKSSBkbyBub3QgaGF2ZSBhbnkgaWRlYSB3aGF0IG9uZSBzaG91bGQgZXhwZWN0IHZpcyBhIHZpcyB0aGUgdHdvIGRydWdzLgpMb29raW5nIGF0IHRoZSBmb2xsb3dpbmcgcmVzdWx0LCBJIGd1ZXNzIG9uZSBzaG91bGQgbm90IGJlIHN1cnByaXNlZApnaXZlbiB0aGF0IEkgYW0gdW5hd2FyZSBvZiBtL2FueSBleHBlcmltZW50cyB3aGljaCBleHBsaWNpdGx5IGNvbXBhcmUKYW50aW1vbmlhbCB0cmVhdG1lbnRzIHdpdGggcmVzcGVjdCB0byB0cmFuc2NyaXB0aW9uYWwgcHJvZmlsZS4KCmBgYHtyfQp0b3BfMzAwX2RydWdfZ2VuZXNfaWR4IDwtIG9yZGVyKHZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVtbImRydWciXV0pCnRvcF8zMDBfZHJ1Z19nZW5lcyA8LSB0YWlsKHZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVt0b3BfMzAwX2RydWdfZ2VuZXNfaWR4LCBdLCBuID0gMzAwKQpzdW1tYXJ5KHRvcF8zMDBfZHJ1Z19nZW5lcykKZHJ1Z19nZW5lc19ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHJvd25hbWVzKHRvcF8zMDBfZHJ1Z19nZW5lcykpCmRydWdfZ2VuZXNfZ3AKZHJ1Z19nZW5lc19ncCRwdmFsdWVfcGxvdHMkTUYKYGBgCgojIyMgSW5mZWN0aW5nIHNwZWNpZXMKClRoZSB2aW9saW4gcGxvdCBhYm92ZSBzdWdnZXN0cyB0aGVyZSBpcyB2ZXJ5IGxpbWl0ZWQgdmFyaWFuY2Ugd2l0aApyZXNwZWN0IHRvIHRoZSB0d28gc3BlY2llcy4gIEluIGFkZGl0aW9uLCB0aGVyZSBhcmUgc2lnbmlmaWNhbnRseQpmZXdlciBicmF6aWxpZW5zaXMgc2FtcGxlcyB3aGljaCBmYWlsZWQgdHJlYXRtZW50IChmb3IgbWlsdGVmb3NpbmUgaW4KcGFydGljdWxhciksIHNvIEkgcHJlc3VtZSB2YXJpYW5jZVBhcnRpdGlvbiBpcyBnb2luZyB0byBoYXZlIHRyb3VibGUKZXh0cmFjdGluZyBnZW5lcyB3aGljaCBhcmUgcmVsaWFibGUgaW4gdGhpcyBjb250ZXh0LiAgSW4gYWRkaXRpb24sIEkKd291bGQgYXNzdW1lIHRoYXQgdGhlIGh1bWFuIHRyYW5zY3JpcHRvbWUgaGFzIHByZXR0eSBzaW1pbGFyIHJlc3BvbnNlcwp0byB0aGUgdHdvIHBhcmFzaXRlcywgZXhhY2VyYmF0aW5nIHRoaXMgY29uZm91bmRlci4KCmBgYHtyfQp0b3BfMzAwX3NwZWNpZXNfZ2VuZXNfaWR4IDwtIG9yZGVyKHZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVtbImluZmVjdGluZ3NwZWNpZXMiXV0pCnRvcF8zMDBfc3BlY2llc19nZW5lcyA8LSB0YWlsKHZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVt0b3BfMzAwX3NwZWNpZXNfZ2VuZXNfaWR4LCBdLCBuID0gMzAwKQpzdW1tYXJ5KHRvcF8zMDBfc3BlY2llc19nZW5lcykKc3BlY2llc19nZW5lc19ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHJvd25hbWVzKHRvcF8zMDBfc3BlY2llc19nZW5lcykpCnNwZWNpZXNfZ2VuZXNfZ3AKYGBgCgojIyMgQ2xpbmljYWwgb3V0Y29tZQoKSW4gbXkgbWluZCwgY2xpbmljYWwgb3V0Y29tZSBpcyB0aGUgbW9zdCBnZW5lcmFsbHkgaW50ZXJlc3RpbmcgcXVlcnkuCkl0IGlzIGFsc28gb25lIHdpdGggbGltaXRlZCBpbmZvcm1hdGlvbiBpbiB0aGUgZGF0YSwgX2J1dF8gbG90cyBvZgpvdGhlciBzdHVkaWVzIGhhdmUgYmVlbiBwZXJmb3JtZWQgaW4gdGhpcyByZWFsbSwgc28gaXQgaXMgbW9yZSBsaWtlbHkKdG8gaGF2ZSByZWxpYWJsZSBvdmVycmVwcmVzZW50YXRpb24gcmVzdWx0cyBldmVuIHdpdGggbGltaXRlZAppbmZvcm1hdGlvbi4gIFRodXMsIHdoZW4gSSBsb29rIGF0IHRoZSBiYXIvZG90IHBsb3QgdGhlIGNhdGVnb3JpZXMgbG9vawppbnRlcmVzdGluZy4KClRoZSBmb2xsb3dpbmcgYmxvY2sgcHJvdmlkZXMgYW4gZXhhbXBsZSBvZiBvbmUgb2YgdGhlIGZ1biB0aGluZ3MgbXkKZ1Byb2ZpbGVyMiBmdW5jdGlvbiBkb2VzOiBpdCBjb2VyY2VzIHRoZSBncHJvZmlsZXIgb3V0cHV0IHRvIHRoZQpkYXRhc3RydWN0dXJlIHVzZWQgYnkgY2x1c3RlclByb2ZpbGVyIGFuZCB0aHVzIG1heSBiZSBwbG90dGVkIHdpdGggdGhlCnZhcmlvdXMgZnVuY3Rpb25zIGluIHRoZSAnZW5yaWNocGxvdCcgcGFja2FnZS4gIEl0IGFsc28gcHJvdmlkZXMgYQpjb3B5IG9mIHRoZSBjdXRlIGludGVyYWN0aXZlIHBsb3RzIHByb2R1Y2VkIGJ5IGdwcm9maWxlci4KCmBgYHtyfQp0b3BfMzAwX2NmX2dlbmVzX2lkeCA8LSBvcmRlcih2YXJwYXJ0X2R2aWNbWyJmaXR0ZWRfZGYiXV1bWyJjbGluaWNhbG91dGNvbWUiXV0pCnRvcF8zMDBfY2ZfZ2VuZXMgPC0gdGFpbCh2YXJwYXJ0X2R2aWNbWyJmaXR0ZWRfZGYiXV1bdG9wXzMwMF9jZl9nZW5lc19pZHgsIF0sIG4gPSAzMDApCnN1bW1hcnkodG9wXzMwMF9jZl9nZW5lcykKY2ZfZ2VuZXNfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihyb3duYW1lcyh0b3BfMzAwX2NmX2dlbmVzKSkKY2ZfZ2VuZXNfZ3AKZW5yaWNocGxvdDo6ZG90cGxvdChjZl9nZW5lc19ncCRHT19lbnJpY2gpCmBgYAoKIyBUaGUgc2FtcGxlcycgZGlzdHJpYnV0aW9uIGlzIHNpbWlsYXIgd2l0aG91dCAyIHNhbXBsZXMKCkhlcmUgYXJlIHRoZSBQQ0EgcmVzdWx0cyBiZWZvcmUvYWZ0ZXIgcmVtb3ZpbmcgdGhlIHR3byBzYW1wbGVzIHRoYXQgSQpjYWxsZWQgc2hlbmFuaWdhbnMgb24uICBUaGV5IGFyZSBxdWl0ZSBzaW1pbGFyLiAgVGhlIG1vc3Qgbm90YWJsZQpkaWZmZXJlbmNlIGlzIHRoZSB3ZWlyZG8gZmFpbHVyZSB2aXNpdCAzIHNhbXBsZSBvbiB0aGUgbGVmdCBnb2VzIGF3YXkuCgpgYGB7cn0Kd2VsbGNvbWVfb3V0dGltZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX291dHRpbWUsIGZpbHRlciA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIHRyYW5zZm9ybSA9ICJsb2cyIiwgbm9ybSA9ICJxdWFudCIpCnByZV9maWx0ZXJfcGNhIDwtIHBsb3RfcGNhKHdlbGxjb21lX291dHRpbWVfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvYWxsX3NhbXBsZXNfbm9ybV9wY2Euc3ZnIikKcHJlX2ZpbHRlcl9wY2EkcGxvdApkZXYub2ZmKCkKcHJlX2ZpbHRlcl9wY2EKCndlbGxjb21lX291dGZpbHRfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9maWx0ZXJlZCwgZmlsdGVyID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgdHJhbnNmb3JtID0gImxvZzIiLCBub3JtID0gInF1YW50IikKcG9zdF9maWx0ZXJfcGNhIDwtIHBsb3RfcGNhKHdlbGxjb21lX291dGZpbHRfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvZmlsdGVyZWRfc2FtcGxlc19ub3JtX3BjYS5zdmciKQpwb3N0X2ZpbHRlcl9wY2EkcGxvdApkZXYub2ZmKCkKcG9zdF9maWx0ZXJfcGNhCmBgYAoKIyBWaXN1YWxpemUgVmFyaW91cyBQQ0EKCk5vdyB0aGF0IHdlIGhhdmUgYW4gaW5pdGlhbCBzZW5zZSBvZiBob3cgdGhlIHNhbXBsZXMgcmVsYXRlIHRvIGVhY2gKb3RoZXIsIGxldCB1cyBwb2tlIGEgYml0IGZ1cnRoZXIuICBJbiBlYWNoIG9mIHRoZSBmb2xsb3dpbmcsIEkgYW0KbGlrZWx5IHRvIGRvIG9uZSBwbG90IGJlZm9yZSBhbmQgb25lIGFmdGVyIHVzaW5nIHN2YS4KCiMjIEJ5IHZpc2l0CgpJIHRoaW5rIHRoZSBwYXR0ZXJuIG9mIHNhbXBsZXMgYnkgdmlzaXQgaXMgcHJldHR5IG9yIHNhdGlzZnlpbmcgaW4gYQonaGV5LCB0aGVzZSB0aGluZ3MgaGF2ZSBzb21lIGludGVybmFsIHNlbnNlJyB3YXkuICBJIGd1ZXNzIG1vZGlmeWluZwp0aGUgY291bnRzIHdpdGggc3Vycm9nYXRlcyBmcm9tIHN2YSBtYWtlcyBpdCBhIGxpdHRsZSBiaXQgY2xlYXJlcj8gIEl0CmRvZXMgaW5jcmVhc2UgdGhlIFBDMSB2YXJpYW5jZSBhIGJpdCBJIHN1cHBvc2UuCgpgYGB7cn0Kd2VsbGNvbWVfdGltZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX3RpbWVfZmlsdCwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKdGltZV9ub3JtX3BjYSA8LSBwbG90X3BjYSh3ZWxsY29tZV90aW1lX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL3RpbWVfbm9ybV9wY2Euc3ZnIikKdGltZV9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQp0aW1lX25vcm1fcGNhCgp3ZWxsY29tZV90aW1lX25iIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX3RpbWVfZmlsdCwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKdGltZV9uYl9wY2EgPC0gcGxvdF9wY2Eod2VsbGNvbWVfdGltZV9uYikKcHAoZmlsZSA9ICJpbWFnZXMvdGltZV9uYl9wY2Euc3ZnIikKdGltZV9uYl9wY2EkcGxvdApkZXYub2ZmKCkKdGltZV9uYl9wY2EKYGBgCgojIyBDdXJlL0ZhaWwKCkluIGNvbnRyYXN0LCB0aGUgYWJpbGl0eSBvZiBzdmEgdG8gZGV0ZXJtaW5lIHZhcmlhbmNlIHdoaWNoIGlzIHJlbGF0ZWQKdG8gY2xpbmljYWwgb3V0Y29tZSBpcyBfdmVyeV8gbGltaXRlZC4gIFRoZSByZXN1bHRpbmcgUENBIHBsb3QgaXMKYSBiaXQgb2YgYSBtZXNzLgoKYGBge3J9CndlbGxjb21lX291dGNvbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9vdXRjb21lX2ZpbHQsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dGNvbWVfbm9ybV9wY2EgPC0gcGxvdF9wY2Eod2VsbGNvbWVfb3V0Y29tZV9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKQpwcChmaWxlID0gImltYWdlcy9vdXRjb21lX25vcm1fcGNhLnN2ZyIpCm91dGNvbWVfbm9ybV9wY2EkcGxvdApkZXYub2ZmKCkKb3V0Y29tZV9ub3JtX3BjYQoKd2VsbGNvbWVfb3V0Y29tZV9uYiA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9vdXRjb21lX2ZpbHQsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dGNvbWVfbmJfcGNhIDwtIHBsb3RfcGNhKHdlbGxjb21lX291dGNvbWVfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL291dGNvbWVfbmJfcGNhLnN2ZyIpCm91dGNvbWVfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCm91dGNvbWVfbmJfcGNhCmBgYAoKIyMgRHJ1ZwoKQXQgZmlyc3QgZ2xhbmNlLCBpdCBhdCBsZWFzdCBhcHBlYXJzIHBvc3NpYmxlIHRoYXQgd2UgY2FuIGdldCBhIGhhbmRsZQpvbiBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gZHJ1ZyB0cmVhdG1lbnQgcmVnaW1lczsgYnV0IEkga2luZCBvZgp0aGluayB0aGF0IGlzIGEgdHJpY2sgcGxheWVkIGJ5IG91ciBleWVzLiAgR2xhbmNpbmcgYXQgdGhlIHBsb3QgZnJvbQpzdmEsIGl0IGFwcGVhcnMgdG8gZGlzYWdyZWUgd2l0aCBtZTsgYXQgbGVhc3QgdGhpcyByZWNhcGl0dWxhdGVzIHRoZQp2YXJpYW5jZVBhcnRpdGlvbiByZXN1bHQgSSB0aGluay4KCmBgYHtyfQp3ZWxsY29tZV9kcnVnX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfZHJ1Z19maWx0LCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpkcnVnX25vcm1fcGNhIDwtIHBsb3RfcGNhKHdlbGxjb21lX2RydWdfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvZHJ1Z19ub3JtX3BjYS5zdmciKQpkcnVnX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCmRydWdfbm9ybV9wY2EKCndlbGxjb21lX2RydWdfbmIgPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfZHJ1Z19maWx0LCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpkcnVnX25iX3BjYSA8LSBwbG90X3BjYSh3ZWxsY29tZV9kcnVnX25iKQpwcChmaWxlID0gImltYWdlcy9kcnVnX25iX3BjYS5zdmciKQpkcnVnX25iX3BjYSRwbG90CmRldi5vZmYoKQpkcnVnX25iX3BjYQpgYGAKCiMjIyBTZXBhcmF0ZSBkcnVnIHRyZWF0bWVudCBieSB0aW1lCgpDb252ZXJzZWx5LCBpdCBpcyBsaWtlbHkgdGhhdCB3ZSB3YW50IHRvIHNlcGFyYXRlIGFuZC9vciBjb21iaW5lIHRoZQp2YXJpb3VzIGZhY3RvcnMgd2l0aCB0aGUgdmlzaXQuICBJbiB0aGUgZm9sbG93aW5nIGJsb2NrIHdlIHdpbGwgdXNlCnRoZSBmYWN0b3Igd2hpY2ggaXMgYSBjb21iaW5hdGlvbiBvZiBkcnVnIGFuZCB2aXNpdC4KCmBgYHtyfQpkcnVndGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX2ZpbHRlcmVkLCBmYWN0ID0gImRydWdfdmlzaXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbImRydWdfdmlzaXQiXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiKQoKZHJ1Z3RpbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdChkcnVndGltZSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCmRydWd0aW1lX25vcm1fcGNhIDwtIHBsb3RfcGNhKGRydWd0aW1lX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL2RydWd0aW1lX25vcm1fcGNhLnN2ZyIpCmRydWd0aW1lX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCmRydWd0aW1lX25vcm1fcGNhCgpkcnVndGltZV9uYiA8LSBub3JtYWxpemVfZXhwdChkcnVndGltZSwgYmF0Y2ggPSAic3Zhc2VxIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCmRydWd0aW1lX25iX3BjYSA8LSBwbG90X3BjYShkcnVndGltZV9uYikKcHAoZmlsZSA9ICJpbWFnZXMvZHJ1Z3RpbWVfbmJfcGNhLnN2ZyIpCmRydWd0aW1lX25iX3BjYSRwbG90CmRldi5vZmYoKQpkcnVndGltZV9uYl9wY2EKYGBgCgojIyMjIFZpc2l0IDEKCk9uZSBpbnRlcnByZXRhdGlvbiBvZiBzb21lIHF1ZXJpZXMgZnJvbSByZXZpZXdlcnMgd291bGQgYmUgdG8gcmVwbG90CnRoZSB2YXJpb3VzIFBDQXMgd2l0aCB0aGUgdmlzaXRzIHNlcGFyYXRlZCBmcm9tIGVhY2ggb3RoZXIuICBJIGFtIG5vdApjb21wbGV0ZWx5IHN1cmUgdGhhdCBpcyB0aGUgY29ycmVjdCBpbnRlcnByZXRhdGlvbiwgYnV0IGhlcmUgaXQgaXMuCgpgYGB7cn0KZHJ1Z192MSA8LSBzdWJzZXRfZXhwdChkcnVndGltZSwgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0ndjEnIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpCgpkcnVnX3YxX25vcm0gPC0gbm9ybWFsaXplX2V4cHQoZHJ1Z192MSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKZHJ1Z192MV9ub3JtX3BjYSA8LSBwbG90X3BjYShkcnVnX3YxX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL2RydWdfdjFfbm9ybV9wY2Euc3ZnIikKZHJ1Z192MV9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQpkcnVnX3YxX25vcm1fcGNhCgpkcnVnX3YxX25iIDwtIG5vcm1hbGl6ZV9leHB0KGRydWdfdjEsIGJhdGNoID0gInN2YXNlcSIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKZHJ1Z192MV9uYl9wY2EgPC0gcGxvdF9wY2EoZHJ1Z192MV9uYikKcHAoZmlsZSA9ICJpbWFnZXMvZHJ1Z192MV9uYl9wY2Euc3ZnIikKZHJ1Z192MV9uYl9wY2EkcGxvdApkZXYub2ZmKCkKZHJ1Z192MV9uYl9wY2EKYGBgCgojIyMjIFZpc2l0IDIKCkkgd291bGQgbGlrZSB0byBoYXZlIHNvbWV0aGluZyB1c2VmdWwgdG8gc2F5IGJlZm9yZSBldmVyeSBibG9jay4gIEkgZG9uJ3QuCgpgYGB7cn0KZHJ1Z192MiA8LSBzdWJzZXRfZXhwdChkcnVndGltZSwgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0ndjInIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpCgpkcnVnX3YyX25vcm0gPC0gbm9ybWFsaXplX2V4cHQoZHJ1Z192Miwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKZHJ1Z192Ml9ub3JtX3BjYSA8LSBwbG90X3BjYShkcnVnX3YyX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL2RydWdfdjJfbm9ybV9wY2Euc3ZnIikKZHJ1Z192Ml9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQpkcnVnX3YyX25vcm1fcGNhCgpkcnVnX3YyX25iIDwtIG5vcm1hbGl6ZV9leHB0KGRydWdfdjIsIGJhdGNoID0gInN2YXNlcSIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCmRydWdfdjJfbmJfcGNhIDwtIHBsb3RfcGNhKGRydWdfdjJfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL2RydWdfdjJfbmJfcGNhLnN2ZyIpCmRydWdfdjJfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCmRydWdfdjJfbmJfcGNhCmBgYAoKIyMjIyBWaXNpdCAzCgpgYGB7cn0KZHJ1Z192MyA8LSBzdWJzZXRfZXhwdChkcnVndGltZSwgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0ndjMnIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpCgpkcnVnX3YzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQoZHJ1Z192Mywgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKZHJ1Z192M19ub3JtX3BjYSA8LSBwbG90X3BjYShkcnVnX3YzX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL2RydWdfdjNfbm9ybV9wY2Euc3ZnIikKZHJ1Z192M19ub3JtX3BjYSRwbG90CmRldi5vZmYoKQoKZHJ1Z192M19uYiA8LSBub3JtYWxpemVfZXhwdChkcnVnX3YzLCBiYXRjaCA9ICJzdmFzZXEiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCmRydWdfdjNfbmJfcGNhIDwtIHBsb3RfcGNhKGRydWdfdjNfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL2RydWdfdjNfbmJfcGNhLnN2ZyIpCmRydWdfdjNfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCmRydWdfdjNfbmJfcGNhCmBgYAoKIyMjIE91dGNvbWUgYWxvbmUKCmBgYHtyfQpvdXRjb21lIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfZmlsdGVyZWQsIGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXNbWyJjbGluaWNhbG91dGNvbWUiXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJkcnVnIikKCm91dGNvbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdChvdXRjb21lLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQpvdXRjb21lX25vcm1fcGNhIDwtIHBsb3RfcGNhKG91dGNvbWVfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvb3V0Y29tZV9ub3JtX3BjYS5zdmciKQpvdXRjb21lX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCm91dGNvbWVfbm9ybV9wY2EKCm91dGNvbWVfbmIgPC0gbm9ybWFsaXplX2V4cHQob3V0Y29tZSwgYmF0Y2ggPSAic3Zhc2VxIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSkKb3V0Y29tZV9uYl9wY2EgPC0gcGxvdF9wY2Eob3V0Y29tZV9uYikKcHAoZmlsZSA9ICJpbWFnZXMvb3V0Y29tZV9uYl9wY2Euc3ZnIikKb3V0Y29tZV9uYl9wY2EkcGxvdApkZXYub2ZmKCkKb3V0Y29tZV9uYl9wY2EKYGBgCgojIyMjIFZpc2l0IDEKCmBgYHtyfQpvdXRjb21lX3YxIDwtIHN1YnNldF9leHB0KG91dGNvbWUsIHN1YnNldCA9ICJ2aXNpdG51bWJlcj09J3YxJyIpCgpvdXRjb21lX3YxX25vcm0gPC0gbm9ybWFsaXplX2V4cHQob3V0Y29tZV92MSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKb3V0Y29tZV92MV9ub3JtX3BjYSA8LSBwbG90X3BjYShvdXRjb21lX3YxX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL291dGNvbWVfdjFfbm9ybV9wY2Euc3ZnIikKb3V0Y29tZV92MV9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQpvdXRjb21lX3YxX25vcm1fcGNhCgpvdXRjb21lX3YxX25iIDwtIG5vcm1hbGl6ZV9leHB0KG91dGNvbWVfdjEsIGJhdGNoID0gInN2YXNlcSIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dGNvbWVfdjFfbmJfcGNhIDwtIHBsb3RfcGNhKG91dGNvbWVfdjFfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL291dGNvbWVfdjFfbmJfcGNhLnN2ZyIpCm91dGNvbWVfdjFfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCm91dGNvbWVfdjFfbmJfcGNhCmBgYAoKIyMjIyBWaXNpdCAyCgpJIHdvdWxkIGxpa2UgdG8gaGF2ZSBzb21ldGhpbmcgdXNlZnVsIHRvIHNheSBiZWZvcmUgZXZlcnkgYmxvY2suICBJIGRvbid0LgoKYGBge3J9Cm91dGNvbWVfdjIgPC0gc3Vic2V0X2V4cHQob3V0Y29tZSwgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0ndjInIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpCgpvdXRjb21lX3YyX25vcm0gPC0gbm9ybWFsaXplX2V4cHQob3V0Y29tZV92Miwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKb3V0Y29tZV92Ml9ub3JtX3BjYSA8LSBwbG90X3BjYShvdXRjb21lX3YyX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL291dGNvbWVfdjJfbm9ybV9wY2Euc3ZnIikKb3V0Y29tZV92Ml9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQpvdXRjb21lX3YyX25vcm1fcGNhCgpvdXRjb21lX3YyX25iIDwtIG5vcm1hbGl6ZV9leHB0KG91dGNvbWVfdjIsIGJhdGNoID0gInN2YXNlcSIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dGNvbWVfdjJfbmJfcGNhIDwtIHBsb3RfcGNhKG91dGNvbWVfdjJfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL291dGNvbWVfdjJfbmJfcGNhLnN2ZyIpCm91dGNvbWVfdjJfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCm91dGNvbWVfdjJfbmJfcGNhCmBgYAoKIyMjIyBWaXNpdCAzCgpgYGB7cn0Kb3V0Y29tZV92MyA8LSBzdWJzZXRfZXhwdChvdXRjb21lLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PSd2MyciKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikKCm91dGNvbWVfdjNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChvdXRjb21lX3YzLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpvdXRjb21lX3YzX25vcm1fcGNhIDwtIHBsb3RfcGNhKG91dGNvbWVfdjNfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvb3V0Y29tZV92M19ub3JtX3BjYS5zdmciKQpvdXRjb21lX3YzX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCm91dGNvbWVfdjNfbm9ybV9wY2EKCm91dGNvbWVfdjNfbmIgPC0gbm9ybWFsaXplX2V4cHQob3V0Y29tZV92MywgYmF0Y2ggPSAic3Zhc2VxIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKb3V0Y29tZV92M19uYl9wY2EgPC0gcGxvdF9wY2Eob3V0Y29tZV92M19uYikKcHAoZmlsZSA9ICJpbWFnZXMvb3V0Y29tZV92M19uYl9wY2Euc3ZnIikKb3V0Y29tZV92M19uYl9wY2EkcGxvdApkZXYub2ZmKCkKb3V0Y29tZV92M19uYl9wY2EKYGBgCgojIyMgT3V0Y29tZSBhbmQgdGltZQoKUmVwZWF0IHRoZSBhYm92ZSBwcm9jZXNzLCBidXQgdGhpcyB0aW1lIHVzaW5nIGNsaW5pY2FsIG91dGNvbWUgYW5kCnRpbWUgY29tYmluZWQuCgpgYGB7cn0Kd2VsbGNvbWVfb3V0dGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX2ZpbHRlcmVkLCBmYWN0ID0gIm91dGNvbWVfdmlzaXQiKQoKd2VsbGNvbWVfb3V0dGltZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX291dHRpbWUsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dHRpbWVfbm9ybV9wY2EgPC0gcGxvdF9wY2Eod2VsbGNvbWVfb3V0dGltZV9ub3JtKQpwcChmaWxlID0gImltYWdlcy9vdXR0aW1lX25vcm1fcGNhLnN2ZyIpCm91dHRpbWVfbm9ybV9wY2EkcGxvdApkZXYub2ZmKCkKb3V0dGltZV9ub3JtX3BjYQoKd2VsbGNvbWVfb3V0dGltZV9uYiA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9vdXR0aW1lLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpvdXR0aW1lX25iX3BjYSA8LSBwbG90X3BjYSh3ZWxsY29tZV9vdXR0aW1lX25iKQpwcChmaWxlID0gImltYWdlcy9vdXR0aW1lX25iX3BjYS5zdmciKQpvdXR0aW1lX25iX3BjYSRwbG90CmRldi5vZmYoKQpvdXR0aW1lX25iX3BjYQpgYGAKCiMjIyMgVmlzaXQgMQoKYGBge3J9Cm91dHRpbWVfdjEgPC0gc3Vic2V0X2V4cHQod2VsbGNvbWVfb3V0dGltZSwgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0ndjEnIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImRydWciKQoKb3V0dGltZV92MV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KG91dHRpbWVfdjEsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dHRpbWVfdjFfbm9ybV9wY2EgPC0gcGxvdF9wY2Eob3V0dGltZV92MV9ub3JtKQpwcChmaWxlID0gImltYWdlcy9vdXR0aW1lX3YxX25vcm1fcGNhLnN2ZyIpCm91dHRpbWVfdjFfbm9ybV9wY2EkcGxvdApkZXYub2ZmKCkKb3V0dGltZV92MV9ub3JtX3BjYSRwbG90CgpvdXR0aW1lX3YxX25iIDwtIG5vcm1hbGl6ZV9leHB0KG91dHRpbWVfdjEsIGJhdGNoID0gInN2YXNlcSIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCm91dHRpbWVfdjFfbmJfcGNhIDwtIHBsb3RfcGNhKG91dHRpbWVfdjFfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL291dHRpbWVfdjFfbmJfcGNhLnN2ZyIpCm91dHRpbWVfdjFfbmJfcGNhCmBgYAoKIyMjIyBWaXNpdCAyCgpgYGB7cn0Kb3V0dGltZV92MiA8LSBzdWJzZXRfZXhwdCh3ZWxsY29tZV9vdXR0aW1lLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PSd2MiciKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiZHJ1ZyIpCgpvdXR0aW1lX3YyX25vcm0gPC0gbm9ybWFsaXplX2V4cHQob3V0dGltZV92Miwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKb3V0dGltZV92Ml9ub3JtX3BjYSA8LSBwbG90X3BjYShvdXR0aW1lX3YyX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL291dHRpbWVfdjJfbm9ybV9wY2Euc3ZnIikKb3V0dGltZV92Ml9ub3JtX3BjYSRwbG90CmRldi5vZmYoKQpvdXR0aW1lX3YyX25vcm1fcGNhJHBsb3QKCm91dHRpbWVfdjJfbmIgPC0gbm9ybWFsaXplX2V4cHQob3V0dGltZV92MiwgYmF0Y2ggPSAic3Zhc2VxIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKb3V0dGltZV92Ml9uYl9wY2EgPC0gcGxvdF9wY2Eob3V0dGltZV92Ml9uYikKcHAoZmlsZSA9ICJpbWFnZXMvb3V0dGltZV92Ml9uYl9wY2Euc3ZnIikKb3V0dGltZV92Ml9uYl9wY2EKYGBgCgojIyMjIFZpc2l0IDMKCmBgYHtyfQpvdXR0aW1lX3YzIDwtIHN1YnNldF9leHB0KHdlbGxjb21lX291dHRpbWUsIHN1YnNldCA9ICJ2aXNpdG51bWJlcj09J3YzJyIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJkcnVnIikKCm91dHRpbWVfdjNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChvdXR0aW1lX3YzLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpvdXR0aW1lX3YzX25vcm1fcGNhIDwtIHBsb3RfcGNhKG91dHRpbWVfdjNfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvb3V0dGltZV92M19ub3JtX3BjYS5zdmciKQpvdXR0aW1lX3YzX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCm91dHRpbWVfdjNfbm9ybV9wY2EkcGxvdAoKb3V0dGltZV92M19uYiA8LSBub3JtYWxpemVfZXhwdChvdXR0aW1lX3YzLCBiYXRjaCA9ICJzdmFzZXEiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpvdXR0aW1lX3YzX25iX3BjYSA8LSBwbG90X3BjYShvdXR0aW1lX3YzX25iKQpwcChmaWxlID0gImltYWdlcy9vdXR0aW1lX3YzX25iX3BjYS5zdmciKQpvdXR0aW1lX3YzX25iX3BjYQpgYGAKCiMjIFBhcmFzaXRlIFNwZWNpZXMKCiMjIyBTZXBhcmF0ZSBzcGVjaWVzIGJ5IHRpbWUKCmBgYHtyfQpzcGVjaWVzdGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSAic3BlY2llc192aXNpdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbInNwZWNpZXNfdmlzaXQiXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiKQoKc3BlY2llc3RpbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdChzcGVjaWVzdGltZSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnNwZWNpZXN0aW1lX25vcm1fcGNhIDwtIHBsb3RfcGNhKHNwZWNpZXN0aW1lX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL3NwZWNpZXN0aW1lX25vcm1fcGNhLnN2ZyIpCnNwZWNpZXN0aW1lX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCnNwZWNpZXN0aW1lX25vcm1fcGNhCgpzcGVjaWVzdGltZV9uYiA8LSBub3JtYWxpemVfZXhwdChzcGVjaWVzdGltZSwgYmF0Y2ggPSAic3Zhc2VxIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnNwZWNpZXN0aW1lX25iX3BjYSA8LSBwbG90X3BjYShzcGVjaWVzdGltZV9uYikKcHAoZmlsZSA9ICJpbWFnZXMvc3BlY2llc3RpbWVfbmJfcGNhLnN2ZyIpCnNwZWNpZXN0aW1lX25iX3BjYSRwbG90CmRldi5vZmYoKQpzcGVjaWVzdGltZV9uYl9wY2EKYGBgCgojIyMjIFZpc2l0IDEKCmBgYHtyfQpzcGVjaWVzX3YxIDwtIHN1YnNldF9leHB0KHNwZWNpZXN0aW1lLCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PSd2MSciKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikKCnNwZWNpZXNfdjFfbm9ybSA8LSBub3JtYWxpemVfZXhwdChzcGVjaWVzX3YxLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpzcGVjaWVzX3YxX25vcm1fcGNhIDwtIHBsb3RfcGNhKHNwZWNpZXNfdjFfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvc3BlY2llc192MV9ub3JtX3BjYS5zdmciKQpzcGVjaWVzX3YxX25vcm1fcGNhJHBsb3QKZGV2Lm9mZigpCnNwZWNpZXNfdjFfbm9ybV9wY2EKCnNwZWNpZXNfdjFfbmIgPC0gbm9ybWFsaXplX2V4cHQoc3BlY2llc192MSwgYmF0Y2ggPSAic3Zhc2VxIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpzcGVjaWVzX3YxX25iX3BjYSA8LSBwbG90X3BjYShzcGVjaWVzX3YxX25iKQpwcChmaWxlID0gImltYWdlcy9zcGVjaWVzX3YxX25iX3BjYS5zdmciKQpzcGVjaWVzX3YxX25iX3BjYSRwbG90CmRldi5vZmYoKQpzcGVjaWVzX3YxX25iX3BjYQpgYGAKCiMjIyMgVmlzaXQgMgoKYGBge3J9CnNwZWNpZXNfdjIgPC0gc3Vic2V0X2V4cHQoc3BlY2llc3RpbWUsIHN1YnNldCA9ICJ2aXNpdG51bWJlcj09J3YyJyIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiKQoKc3BlY2llc192Ml9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHNwZWNpZXNfdjIsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnNwZWNpZXNfdjJfbm9ybV9wY2EgPC0gcGxvdF9wY2Eoc3BlY2llc192Ml9ub3JtKQpwcChmaWxlID0gImltYWdlcy9zcGVjaWVzX3YyX25vcm1fcGNhLnN2ZyIpCnNwZWNpZXNfdjJfbm9ybV9wY2EkcGxvdApkZXYub2ZmKCkKc3BlY2llc192Ml9ub3JtX3BjYQoKc3BlY2llc192Ml9uYiA8LSBub3JtYWxpemVfZXhwdChzcGVjaWVzX3YyLCBiYXRjaCA9ICJzdmFzZXEiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnNwZWNpZXNfdjJfbmJfcGNhIDwtIHBsb3RfcGNhKHNwZWNpZXNfdjJfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL3NwZWNpZXNfdjJfbmJfcGNhLnN2ZyIpCnNwZWNpZXNfdjJfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnNwZWNpZXNfdjJfbmJfcGNhCmBgYAoKIyMjIyBWaXNpdCAzCgpgYGB7cn0Kc3BlY2llc192MyA8LSBzdWJzZXRfZXhwdChzcGVjaWVzdGltZSwgc3Vic2V0ID0gInZpc2l0bnVtYmVyPT0ndjMnIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpCgpzcGVjaWVzX3YzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQoc3BlY2llc192Mywgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKc3BlY2llc192M19ub3JtX3BjYSA8LSBwbG90X3BjYShzcGVjaWVzX3YzX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL3NwZWNpZXNfdjNfbm9ybV9wY2Euc3ZnIikKc3BlY2llc192M19ub3JtX3BjYSRwbG90CmRldi5vZmYoKQoKc3BlY2llc192M19uYiA8LSBub3JtYWxpemVfZXhwdChzcGVjaWVzX3YzLCBiYXRjaCA9ICJzdmFzZXEiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnNwZWNpZXNfdjNfbmJfcGNhIDwtIHBsb3RfcGNhKHNwZWNpZXNfdjNfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL3NwZWNpZXNfdjNfbmJfcGNhLnN2ZyIpCnNwZWNpZXNfdjNfbmJfcGNhJHBsb3QKZGV2Lm9mZigpCnNwZWNpZXNfdjNfbmJfcGNhCmBgYAoKIyMjIyBCYWNrIHRvIGV2ZXJ5dGhpbmcKCmBgYHtyfQp3ZWxsY29tZV9wYXJhc2l0ZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX3BhcmFzaXRlX2ZpbHQsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9wYXJhc2l0ZV9ub3JtKQoKd2VsbGNvbWVfcGFyYXNpdGVfbmIgPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfcGFyYXNpdGVfZmlsdCwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9wYXJhc2l0ZV9uYikKYGBgCgpPaywgc28gdGhhdCBpcyBhIGJpZyBwaWxlIG9mIHBpY3R1cmVzLCBub3cgbGV0IHVzIHBlcmZvcm0gc29tZSBERQphbmFseXNlcyBhbmQgc2VlIHdoYXQgcG9wcyBvdXQuCgojIERFIGFuYWx5c2VzCgpHaXZlbiB0aGUgYWJvdmUgdmFyaWFuY2UgcGFydGl0aW9uIGFuZCBQQ0EgcGxvdHMsIHdlIGNhbiBzdXJtaXNlIHRoYXQKc29tZSBtZXRhZGF0YSBmYWN0b3JzIGFyZSBtdWNoIG1vcmUgbGlrZWx5IHRvIGdpdmUgaW50ZXJlc3RpbmcgcmVzdWx0cwp0aGFuIG90aGVycyAoRHJ1ZyBmYXIgbW9yZSB0aGFuIEMvRiwgZm9yIGV4YW1wbGUpLiAgV2l0aCB0aGF0IGluIG1pbmQsCmxldCB1cyBwZXJmb3JtIHRoZSB2YXJpb3VzIHBvc3NpYmxlIERFIGFuYWx5c2VzIHdpdGggZWFjaApmYWN0b3IgYW5kIHNlZSB3aGF0IGNvbWVzIG91dC4gIEVhY2ggb2YgdGhlc2UgcnVucyBvZiBhbGwgcGFpcndpc2UKd2lsbCBiZSBwZXJmb3JtZWQgb25jZSB3aXRoIFNWQSBlc3RpbWF0ZXMgaW4gdGhlIG1vZGVsLCBhbmQgb25jZSB3aXRoCnRoZSBkcnVnIHRyZWF0bWVudCBhcyB0aGUgYmF0Y2ggZmFjdG9yLgoKIyMgT3V0Y29tZSBhbmQgdGltZQoKT25lIHRoaW5nIHRvIHJlY2FsbCwgbXkgc2FuaXRpemVyIHJlbW92ZXMgcHVuY3R1YXRpb24gZnJvbQpjb25jYXRlbmF0ZWQgZmFjdG9yczsgc28gJ2N1cmVfdjInIHR1cm5zIGludG8gJ2N1cmV2MicuCgojIyBUaGUgY29udHJhc3RzIG9mIGludGVyZXN0CgpUaGUgZm9sbG93aW5nIGxpc3QgbmFtZXMgZWFjaCBjb250cmFzdCBhbmQgdGhlIHR3byBlbGVtZW50IHZlY3Rvcgpmb2xsb3dpbmcgcHJvdmlkZXMgZWFjaCBudW1lcmF0b3IgYW5kIGRlbm9taW5hdG9yLgoKYGBge3J9Cm91dHRpbWVfa2VlcGVycyA8LSBsaXN0KAogICJjdXJldjF2MiIgPSBjKCJjdXJldjIiLCAiY3VyZXYxIiksCiAgImN1cmV2MXYzIiA9IGMoImN1cmV2MyIsICJjdXJldjEiKSwKICAiY3VyZXYydjMiID0gYygiY3VyZXYzIiwgImN1cmV2MiIpLAogICJmYWlsdjF2MiIgPSBjKCJmYWlsdXJldjIiLCAiZmFpbHVyZXYxIiksCiAgImZhaWx2MXYzIiA9IGMoImZhaWx1cmV2MyIsICJmYWlsdXJldjEiKSwKICAiZmFpbHYydjMiID0gYygiZmFpbHVyZXYzIiwgImZhaWx1cmV2MiIpLAogICJjZnYxIiA9IGMoImZhaWx1cmV2MSIsICJjdXJldjEiKSwKICAiY2Z2MiIgPSBjKCJmYWlsdXJldjIiLCAiY3VyZXYyIiksCiAgImNmdjMiID0gYygiZmFpbHVyZXYzIiwgImN1cmV2MyIpKQpgYGAKClN0YXJ0IHdpdGggdGhlIGNvbWJpbmVkIGZhY3RvciBvZiB7b3V0Y29tZX1fe3Zpc2l0fS4gIEdpdmVuIHRoZSBQQ0EsIEkKZXhwZWN0IHRvIHNlZSBhIGxpdHRsZSBiaXQgb2YgaW5mb3JtYXRpb24gd2l0aCBiYXRjaCBpbiB0aGUgbW9kZWwsCm9kZGx5IGxlc3MgaW5mb3JtYXRpb24gd2l0aCBTVkEuCgojIyMgU1ZBCgpPbmUgb2YgdGhlIHJldmlldyBjb21tZW50cyBzZWVtZWQgdG8gbWUgdG8gc3VnZ2VzdCB0aGF0IHVzaW5nIHRoZQp2YXJpYW5jZVBhcnRpdGlvbiBkcmVhbSBtZXRob2QgbWlnaHQgYmUgdXNlZnVsLiAgSSBhbSBub3QgY2VydGFpbiBpZgp0aGF0IGlzIGN1cnJlbnRseSBlbmFibGVkLiAgSSBkZWZpbml0ZWx5IGdvdCBpdCB3b3JraW5nLCB0aG91Z2guICBBbHNvCm5vdGUgdGhhdCBmaWx0ZXIgaW4gdGhpcyBjb250ZXh0IGlzIG9uIGEgZ2VuZSBiYXNpcywgbm90IHNhbXBsZS4KCmBgYHtyfQpvdXR0aW1lX3N2YV9kZSA8LSBhbGxfcGFpcndpc2Uod2VsbGNvbWVfZmlsdGVyZWQsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCm91dHRpbWVfc3ZhX2RlCgpvdXR0aW1lX3N2YV90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICBvdXR0aW1lX3N2YV9kZSwKICBrZWVwZXJzID0gb3V0dGltZV9rZWVwZXJzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfb3V0dGltZV90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKb3V0dGltZV9zdmFfdGFibGUKCm91dHRpbWVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIG91dHRpbWVfc3ZhX3RhYmxlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfb3V0dGltZV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCm91dHRpbWVfc3ZhX3NpZwpgYGAKCiMjIyBCYXRjaCBpbiBtb2RlbAoKYGBge3J9Cm91dHRpbWVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2ZpbHRlcmVkLCBtb2RlbF9iYXRjaCA9IFRSVUUsIGZpbHRlciA9IFRSVUUpCm91dHRpbWVfYmF0Y2hfZGUKCm91dHRpbWVfYmF0Y2hfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgb3V0dGltZV9iYXRjaF9kZSwKICBrZWVwZXJzID0gb3V0dGltZV9rZWVwZXJzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfb3V0dGltZV90YWJsZV9iYXRjaC12e3Zlcn0ueGxzeCIpKQpvdXR0aW1lX2JhdGNoX3RhYmxlCgpvdXR0aW1lX2JhdGNoX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIG91dHRpbWVfYmF0Y2hfdGFibGUsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19vdXR0aW1lX3NpZ19iYXRjaC12e3Zlcn0ueGxzeCIpKQpvdXR0aW1lX2JhdGNoX3NpZwpgYGAKCiMgUFJPUEVSCgpUaGVyZSB3YXMgYSByZXF1ZXN0IHNvbWUgdGltZSBhZ28gdG8gcHJvdmlkZSBhIHBvd2VyIGFuYWx5c2lzLiAgSQphcmJpdHJhcmlseSBjaG9zZSB0aGlzIGRhdGFzZXQgaW4gb3JkZXIgdG8gaW52b2tlIFBST1BFUiBhbmQgcHJvdmlkZQp0aGUgcmVzdWx0aW5nIHBsb3RzLi4uCgpgYGB7cn0Kb3V0dGltZV9iYXRjaF9wcm9wZXIgPC0gc2ltcGxlX3Byb3BlcihvdXR0aW1lX2JhdGNoX3RhYmxlKQpvdXR0aW1lX2JhdGNoX3Byb3BlcltbImN1cmV2Ml92c19jdXJldjEiXV1bWyJwb3dlcl90YWJsZSJdXQpvdXR0aW1lX2JhdGNoX3Byb3BlcltbImN1cmV2Ml92c19jdXJldjEiXV1bWyJwb3dlcl9wbG90Il1dCm91dHRpbWVfYmF0Y2hfcHJvcGVyW1siY3VyZXYyX3ZzX2N1cmV2MSJdXVtbInBvd2VydGRfcGxvdCJdXQpvdXR0aW1lX2JhdGNoX3Byb3BlcltbImN1cmV2Ml92c19jdXJldjEiXV1bWyJwb3dlcmZkX3Bsb3QiXV0Kb3V0dGltZV9iYXRjaF9wcm9wZXJbWyJjdXJldjJfdnNfY3VyZXYxIl1dW1siZmRjb3N0X3Bsb3QiXV0Kb3V0dGltZV9iYXRjaF9wcm9wZXJbWyJjdXJldjJfdnNfY3VyZXYxIl1dW1sicG93ZXJoaXN0X3Bsb3QiXV0Kb3V0dGltZV9iYXRjaF9wcm9wZXJbWyJjdXJldjJfdnNfY3VyZXYxIl1dW1sicG93ZXJhbHBoYV9wbG90Il1dCmBgYAoKIyMgT25seSB0aW1lCgpOb3cgbGV0IHVzIGNvbXBhcmUgdGhlIHRpbWUgcG9pbnRzLCB3aXRoIGFuZCB3aXRob3V0IFNWQS4KCiMjIFRpbWUgY29udHJhc3RzCgpgYGB7cn0KdGltZV9rZWVwZXJzIDwtIGxpc3QoCiAgInYxdjIiID0gYygidjIiLCAidjEiKSwKICAidjF2MyIgPSBjKCJ2MyIsICJ2MSIpLAogICJ2MnYzIiA9IGMoInYzIiwgInYyIikpCmBgYAoKIyMjIFNWQQoKYGBge3J9CnRpbWVfc3ZhX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV90aW1lX2ZpbHQsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnRpbWVfc3ZhX2RlCgp0aW1lX3N2YV90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICB0aW1lX3N2YV9kZSwKICBrZWVwZXJzID0gdGltZV9rZWVwZXJzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfdGltZV90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKdGltZV9zdmFfdGFibGUKCnRpbWVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHRpbWVfc3ZhX3RhYmxlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfdGltZV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCnRpbWVfc3ZhX3NpZwpgYGAKCiMjIyBCYXRjaAoKYGBge3J9CnRpbWVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX3RpbWVfZmlsdCwgbW9kZWxfYmF0Y2ggPSAiYmF0Y2hzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0aW1lX2JhdGNoX2RlCgp0aW1lX2JhdGNoX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHRpbWVfYmF0Y2hfZGUsCiAga2VlcGVycyA9IHRpbWVfa2VlcGVycywKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX3RpbWVfdGFibGVfYmF0Y2gtdnt2ZXJ9Lnhsc3giKSkKdGltZV9iYXRjaF90YWJsZQoKdGltZV9iYXRjaF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICB0aW1lX2JhdGNoX3RhYmxlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfdGltZV9iYXRjaF9zdmEtdnt2ZXJ9Lnhsc3giKSkKdGltZV9iYXRjaF9zaWcKYGBgCgojIyBTdHJhaW4KCkkgbmVnbGVjdGVkIHRvIHNldCBhIGNvbnRyYXN0IG5hbWUvdmFsdWUgZm9yIHRoaXMuCgpgYGB7cn0KIyMgT2gsIEkganVzdCBsZXQgdGhlIGNvbXB1dGVyIGNob29zZSB0aGUgbnVtZXJhdG9yL2Rlbm9taW5hdG9yIG9uIGl0cyBvd24uCmBgYAoKVGhlIGluZmVjdGluZyBzdHJhaW4gSSB0aGluayBzaG91bGQgcHJvdmUgb25lIG9mIHRoZSBtb3JlIGludGVyZXN0aW5nCmNvbXBhcmlzb25zLgoKIyMjIFNWQQoKYGBge3J9CnBhcmFzaXRlX3N2YV9kZSA8LSBhbGxfcGFpcndpc2Uod2VsbGNvbWVfcGFyYXNpdGVfZmlsdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKcGFyYXNpdGVfc3ZhX2RlCgpwYXJhc2l0ZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgcGFyYXNpdGVfc3ZhX2RlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfcGFyYXNpdGVfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikpCnBhcmFzaXRlX3N2YV90YWJsZQoKcGFyYXNpdGVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIHBhcmFzaXRlX3N2YV90YWJsZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX3BhcmFzaXRlX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKcGFyYXNpdGVfc3ZhX3NpZwpgYGAKCiMjIyBCYXRjaCBpbiBtb2RlbAoKYGBge3J9CnBhcmFzaXRlX2JhdGNoX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV9wYXJhc2l0ZV9maWx0LCBtb2RlbF9iYXRjaCA9IFRSVUUsIGZpbHRlciA9IFRSVUUpCnBhcmFzaXRlX2JhdGNoX2RlCgpwYXJhc2l0ZV9iYXRjaF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICBwYXJhc2l0ZV9iYXRjaF9kZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX3BhcmFzaXRlX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCnBhcmFzaXRlX2JhdGNoX3RhYmxlCgpwYXJhc2l0ZV9iYXRjaF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBwYXJhc2l0ZV9iYXRjaF90YWJsZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX3BhcmFzaXRlX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKcGFyYXNpdGVfYmF0Y2hfc2lnCmBgYAoKIyMgT3V0Y29tZQoKQXMgc3RhdGVkIGFib3ZlLCBjbGluaWNhbCBvdXRjb21lIGJ5IGl0c2VsZiBkb2VzIG5vdCBoYXZlIG11Y2gKaW5mb3JtYXRpb24gY29udGVudCBpbiB0aGlzIGRhdGFzZXQuCgojIyMgU1ZBCgpgYGB7cn0Kb3V0Y29tZV9zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX291dGNvbWVfZmlsdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKb3V0Y29tZV9zdmFfZGUKCm91dGNvbWVfc3ZhX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIG91dGNvbWVfc3ZhX2RlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfb3V0Y29tZV90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKb3V0Y29tZV9zdmFfdGFibGUKCm91dGNvbWVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIG91dGNvbWVfc3ZhX3RhYmxlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfb3V0Y29tZV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCm91dGNvbWVfc3ZhX3NpZwpgYGAKCiMjIyBCYXRjaCBpbiBtb2RlbAoKYGBge3J9Cm91dGNvbWVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX291dGNvbWVfZmlsdCwgbW9kZWxfYmF0Y2ggPSBUUlVFLCBmaWx0ZXIgPSBUUlVFKQpvdXRjb21lX2JhdGNoX2RlCgpvdXRjb21lX2JhdGNoX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIG91dGNvbWVfYmF0Y2hfZGUsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19vdXRjb21lX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCm91dGNvbWVfYmF0Y2hfdGFibGUKCm91dGNvbWVfYmF0Y2hfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgb3V0Y29tZV9iYXRjaF90YWJsZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX291dGNvbWVfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpvdXRjb21lX2JhdGNoX3NpZwpgYGAKCiMjIERydWcgdHJlYXRtZW50CgojIyMgU1ZBCgpgYGB7cn0KZHJ1Z19zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2RydWdfZmlsdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKZHJ1Z19zdmFfZGUKCmRydWdfc3ZhX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIGRydWdfc3ZhX2RlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfZHJ1Z190YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKZHJ1Z19zdmFfdGFibGUKCmRydWdfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIGRydWdfc3ZhX3RhYmxlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfZHJ1Z19zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmRydWdfc3ZhX3NpZwpgYGAKCiMjIyBCYXRjaCBpbiBtb2RlbAoKYGBge3J9CmRydWdfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2RydWdfZmlsdCwgbW9kZWxfYmF0Y2ggPSBUUlVFLCBmaWx0ZXIgPSBUUlVFKQpkcnVnX2JhdGNoX2RlCgpkcnVnX2JhdGNoX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIGRydWdfYmF0Y2hfZGUsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19kcnVnX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCmRydWdfYmF0Y2hfdGFibGUKCmRydWdfYmF0Y2hfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgZHJ1Z19iYXRjaF90YWJsZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX2RydWdfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpkcnVnX2JhdGNoX3NpZwpgYGAKCiMjIFBhcmFzaXRlIGFuZCB0aW1lCgpUaGlzIHJlcXVpcmVzIHNldHRpbmcgdXAgdGhlIGNvbnRyYXN0cyBvZiBpbnRlcmVzdC4gIEkgYW0gZ29pbmcgdG8KYXNzdW1lIGNyb3NzIHNwZWNpZXMvY3Jvc3MgdGltZSBhcmUgbm90IGludGVyZXN0aW5nLCBhbmQgdGhhdCB2My92MQphbmQgdjMvdjIgYXJlIG5vdCBpbnRlcmVzdGluZy4KCk5vdGUgdG8gc2VsZiwgZG8gbm90IGZvcmdldCB0aGF0IEkgc2FuaXRpemUgdGhlIGRhdGEgYnkgcmVtb3ZpbmcgcHVuY3R1YXRpb24hCgpgYGB7cn0Kc3BlY2llc3RpbWVfa2VlcGVycyA8LSBsaXN0KAogICJwYW5fdjJ2MSIgPSBjKCJsdnBhbmFtZW5zaXN2MiIsICJsdnBhbmFtZW5zaXN2MSIpLAogICJwYW5fdjN2MSIgPSBjKCJsdnBhbmFtZW5zaXN2MyIsICJsdnBhbmFtZW5zaXN2MSIpLAogICJicmF6X3YydjEiID0gYygibHZicmF6aWxpZW5zaXN2MiIsICJsdmJyYXppbGllbnNpc3YxIiksCiAgImJyYXpfdjN2MSIgPSBjKCJsdmJyYXppbGllbnNpc3YzIiwgImx2YnJhemlsaWVuc2lzdjEiKSwKICAidjFfcGFuYnJheiIgPSBjKCJsdmJyYXppbGllbnNpc3YxIiwgImx2cGFuYW1lbnNpc3YxIiksCiAgInYyX3BhbmJyYXoiID0gYygibHZicmF6aWxpZW5zaXN2MiIsICJsdnBhbmFtZW5zaXN2MiIpLAogICJ2M19wYW5icmF6IiA9IGMoImx2YnJhemlsaWVuc2lzdjMiLCAibHZwYW5hbWVuc2lzdjMiKSkKYGBgCgojIyMgU1ZBCgpgYGB7cn0Kc3BlY2llc3RpbWVfc3ZhX2RlIDwtIGFsbF9wYWlyd2lzZShzcGVjaWVzdGltZSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKc3BlY2llc3RpbWVfc3ZhX2RlCgpzcGVjaWVzdGltZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgc3BlY2llc3RpbWVfc3ZhX2RlLCBrZWVwZXJzID0gc3BlY2llc3RpbWVfa2VlcGVycywKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX3NwZWNpZXN0aW1lX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpKQpzcGVjaWVzdGltZV9zdmFfdGFibGUKCnNwZWNpZXN0aW1lX3N2YV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBzcGVjaWVzdGltZV9zdmFfdGFibGUsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19zcGVjaWVzdGltZV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCnNwZWNpZXN0aW1lX3N2YV9zaWcKYGBgCgojIyMgQmF0Y2ggaW4gbW9kZWwKCmBgYHtyfQpzcGVjaWVzdGltZV9zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKHNwZWNpZXN0aW1lLCBtb2RlbF9iYXRjaCA9IFRSVUUsIGZpbHRlciA9IFRSVUUpCnNwZWNpZXN0aW1lX3N2YV9kZQoKc3BlY2llc3RpbWVfc3ZhX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogIHNwZWNpZXN0aW1lX3N2YV9kZSwga2VlcGVycyA9IHNwZWNpZXN0aW1lX2tlZXBlcnMsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19zcGVjaWVzdGltZV90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKc3BlY2llc3RpbWVfc3ZhX3RhYmxlCgpzcGVjaWVzdGltZV9zdmFfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgc3BlY2llc3RpbWVfc3ZhX3RhYmxlLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfc3BlY2llc3RpbWVfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpzcGVjaWVzdGltZV9zdmFfc2lnCmBgYAoKIyMgRHJ1ZyB0cmVhdG1lbnQgYW5kIHRpbWUKClNhbWUgcnVsZXMgaGVyZSBhcyBzdHJhaW4rdGltZQoKYGBge3J9CmRydWd0aW1lX2tlZXBlcnMgPC0gbGlzdCgKICAibWlsdF92MnYxIiA9IGMoIm1pbHRlZm9zaW5ldjIiLCAibWlsdGVmb3NpbmV2MSIpLAogICJtaWx0X3YzdjEiID0gYygibWlsdGVmb3NpbmV2MyIsICJtaWx0ZWZvc2luZXYxIiksCiAgImdsdWNfdjJ2MSIgPSBjKCJhbnRpbW9uaWF0ZXYyIiwgImFudGltb25pYXRldjEiKSwKICAiZ2x1Y192M3YxIiA9IGMoImFudGltb25pYXRldjMiLCAiYW50aW1vbmlhdGV2MSIpLAogICJ2MV9taWx0Z2x1YyIgPSBjKCJtaWx0ZWZvc2luZXYxIiwgImFudGltb25pYXRldjEiKSwKICAidjJfbWlsdGdsdWMiID0gYygibWlsdGVmb3NpbmV2MiIsICJhbnRpbW9uaWF0ZXYyIiksCiAgInYzX21pbHRnbHVjIiA9IGMoIm1pbHRlZm9zaW5ldjMiLCAiYW50aW1vbmlhdGV2MyIpKQpgYGAKCiMjIyBTVkEKCmBgYHtyfQpkcnVndGltZV9zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKGRydWd0aW1lLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpkcnVndGltZV9zdmFfZGUKCmRydWd0aW1lX3N2YV90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICBkcnVndGltZV9zdmFfZGUsIGtlZXBlcnMgPSBkcnVndGltZV9rZWVwZXJzLAogIGV4Y2VsID0gZ2x1ZSgiZXhjZWwvQ0xfYmlvcHNpZXNfZHJ1Z3RpbWVfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikpCmRydWd0aW1lX3N2YV90YWJsZQoKZHJ1Z3RpbWVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIGRydWd0aW1lX3N2YV90YWJsZSwKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX2RydWd0aW1lX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKZHJ1Z3RpbWVfc3ZhX3NpZwpgYGAKCiMjIyBCYXRjaCBpbiBtb2RlbAoKYGBge3J9CmRydWd0aW1lX3N2YV9kZSA8LSBhbGxfcGFpcndpc2UoZHJ1Z3RpbWUsIG1vZGVsX2JhdGNoID0gVFJVRSwgZmlsdGVyID0gVFJVRSkKZHJ1Z3RpbWVfc3ZhX2RlCgpkcnVndGltZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgZHJ1Z3RpbWVfc3ZhX2RlLCBrZWVwZXJzID0gZHJ1Z3RpbWVfa2VlcGVycywKICBleGNlbCA9IGdsdWUoImV4Y2VsL0NMX2Jpb3BzaWVzX2RydWd0aW1lX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpKQpkcnVndGltZV9zdmFfdGFibGUKCmRydWd0aW1lX3N2YV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICBkcnVndGltZV9zdmFfdGFibGUsCiAgZXhjZWwgPSBnbHVlKCJleGNlbC9DTF9iaW9wc2llc19kcnVndGltZV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmRydWd0aW1lX3N2YV9zaWcKYGBgCgojIE9udG9sb2d5IHNlYXJjaGVzCgpHaXZlbiB0aGUgcmVzdWx0cyBpbiB0aGUgcHJldmlvdXMgYmxvY2tzLCBsZXQgdXMgdXNlIGdQcm9maWxlcjIgaW4KbG9vayBmb3Igb3ZlciByZXByZXNlbnRlZCBjYXRlZ29yaWVzL29udG9sb2dpZXMgaW4gdGhlIHN1c3BlY3QKZGF0YWJhc2VzOiBHTy9yZWFjdG9tZS9rZWdnL1RGL3dpa2lwYXRoL2V0Yy4KCkkgdGhpbmsgZm9yIHRoZSBtb21lbnQgSSB3aWxsIGRvIHRoaXMgZW50aXJlbHkgd2l0aCB0aGUgc3ZhIHJlc3VsdHMuCgojIyBPdXRjb21lIGFuZCB0aW1lCgpJIGhhdmUgYSBzZXJpZXMgb2Ygd3JhcHBlciBmdW5jdGlvbnMgZm9yCmdQcm9maWxlcjIvZ29zZXEvY2x1c3RlclByb2ZpbGVyL3RvcEdPL0dPc3RhdHMuICBTb21lIG9mIHRoZW0gYXJlCnNtYXJ0IGVub3VnaCB0byB0YWtlIGFzIGlucHV0IHRoZSByZXN1bHQgZnJvbQpleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKCkuCgpUaGVyZSBpcyBhbHNvIGEgZnVuY3Rpb24gd2hpY2ggd3JpdGVzIHByZXR0eS1pZmllZCBvbnRvbG9neSByZXN1bHRzLApidXQgaXQgd29ya3Mgb24gYSBzaW5nbGUtdGFibGUgYmFzaXMuCgpgYGB7cn0Kb3V0dGltZV9ncHJvZmlsZXIgPC0gYWxsX2dwcm9maWxlcihvdXR0aW1lX3N2YV9zaWcpCgpvdXR0aW1lX2dwcm9maWxlciRjdXJldjF2Ml91cCRwdmFsdWVfcGxvdHMkQlAKb3V0dGltZV9ncHJvZmlsZXIkZmFpbHYxdjJfdXAkcHZhbHVlX3Bsb3RzJEtFR0cKb3V0dGltZV9ncHJvZmlsZXIkY2Z2MV91cCRwdmFsdWVfcGxvdHMkUkVBQwoKIyMgTm90ZSwgSSBhbSB3cml0aW5nIGEgc2V0IG9mIG1ldGhvZHMgZm9yIHdyaXRlX2dwcm9maWxlcl9kYXRhIHNvIHRoYXQgaXQgaXMKIyMgYXdhcmUgb2YgdGhlIHJlc3VsdCBmcm9tIGFsbF9ncHJvZmlsZXIgYW5kIGNhbiBoYW5kbGUgZWl0aGVyIGFsbCBjb250cmFzdHMKIyMgb3IgYSBzZXQgb2YgZGVzaXJlZCBjb250cmFzdHMuCndyaXRlX2FsbCA8LSBmdW5jdGlvbihyZXN1bHQpIHsKICBmb3IgKG4gaW4gbmFtZXMocmVzdWx0KSkgewogICAgbmFtZSA8LSBnbHVlKCJleGNlbC9ncHJvZmlsZXJfe259Lnhsc3giKQogICAgcmVzIDwtIHJlc3VsdFtbbl1dCiAgICB3cml0dGVuIDwtIHRyeSh3cml0ZV9ncHJvZmlsZXJfZGF0YShyZXMsIGV4Y2VsID0gbmFtZSkpCiAgfQp9Cgp3cml0dGVuIDwtIHdyaXRlX2FsbChvdXR0aW1lX2dwcm9maWxlcikKYGBgCgojIyBWaXNpdAoKYGBge3J9CnZpc2l0X2dwcm9maWxlciA8LSBhbGxfZ3Byb2ZpbGVyKHRpbWVfc3ZhX3NpZykKCndyaXR0ZW4gPC0gd3JpdGVfYWxsKHZpc2l0X2dwcm9maWxlcikKYGBgCgojIyBTdHJhaW4KCmBgYHtyfQpwYXJhc2l0ZV9ncHJvZmlsZXIgPC0gYWxsX2dwcm9maWxlcihwYXJhc2l0ZV9zdmFfc2lnKQoKd3JpdHRlbiA8LSB3cml0ZV9hbGwocGFyYXNpdGVfZ3Byb2ZpbGVyKQpgYGAKCiMjIE91dGNvbWUKCmBgYHtyfQpvdXRjb21lX2dwcm9maWxlciA8LSBhbGxfZ3Byb2ZpbGVyKG91dGNvbWVfc3ZhX3NpZykKCndyaXR0ZW4gPC0gd3JpdGVfYWxsKG91dGNvbWVfZ3Byb2ZpbGVyKQpgYGAKCiMjIFRyZWF0bWVudAoKYGBge3J9CmRydWdfZ3Byb2ZpbGVyIDwtIGFsbF9ncHJvZmlsZXIoZHJ1Z19zdmFfc2lnKQoKd3JpdHRlbiA8LSB3cml0ZV9hbGwoZHJ1Z19ncHJvZmlsZXIpCmBgYAoKIyMgU3RyYWluIGFuZCB0aW1lCgpgYGB7cn0Kc3BlY2llc3RpbWVfZ3Byb2ZpbGVyIDwtIGFsbF9ncHJvZmlsZXIoc3BlY2llc3RpbWVfc3ZhX3NpZykKCndyaXR0ZW4gPC0gd3JpdGVfYWxsKHNwZWNpZXN0aW1lX2dwcm9maWxlcikKYGBgCgojIyBEcnVnIGFuZCB0aW1lCgpgYGB7cn0KZHJ1Z3RpbWVfZ3Byb2ZpbGVyIDwtIGFsbF9ncHJvZmlsZXIoZHJ1Z3RpbWVfc3ZhX3NpZykKCndyaXR0ZW4gPC0gd3JpdGVfYWxsKGRydWd0aW1lX2dwcm9maWxlcikKYGBgCgojIEdTVkEKCkZyb20gbXkgcGVyc3BlY3RpdmUsIGl0IHNlZW1zIHRoYXQgdGhlIG1vc3QgaW50ZXJlc3RpbmcgR1NWQQpjb21wYXJpc29uIGlzIHRvIGxvb2sgZm9yIHNjb3JlcyBjaGFuZ2luZyBiZXR3ZWVuIHRoZSBjdXJlIGFuZCBmYWlsCnNhbXBsZXMuICBUaGUgZm9sbG93aW5nIGJsb2NrIHRoZXJlZm9yZSBwYXNzZXMgdGhlIHJhdyBleHByZXNzaW9uIGRhdGEKYW5kIHBlcmZvcm1zIHRoZSBnZW5lIHNldCB2YXJpYW5jZSBhbmFseXNpcyBvZiBpdCBhZ2FpbnN0IHRoZSBtU2lnREIKQzIgc2V0IG9mIGNhdGVnb3JpZXMgYnkgZGVmYXVsdC4gIFdlIGNhbiBwcmV0dHkgZWFzaWx5IGNoYW5nZSB0aGUKbVNpZ0RCIHJlbGVhc2UvY2F0ZWdvcnkgc2V0OyBleGNlcHQgSSB3b3VsZCBuZWVkIGRvd25sb2FkIHRoZSBkYXRhc2V0CnRvIHRoZSBjb250YWluZXIgdG8gdXNlIGEgbmV3ZXIgcmV2aXNpb24gYW5kIEkgYW0gbm90IHN1cmUgYWJvdXQKcG90ZW50aWFsIGxpY2Vuc2luZyByZXN0cmljdGlvbnM7IHNvIHRoaXMgd2lsbCBqdXN0IHVzZSB0aGUgcHVibGljbHkKYXZhaWxhYmxlIHNpZ25hdHVyZXMgaW4gdGhlICdHU1ZBZGF0YScgcGFja2FnZS4KCmBgYHtyfQp3dF9nc3ZhIDwtIHNpbXBsZV9nc3ZhKHdlbGxjb21lX291dGNvbWVfZmlsdCwgc2lnbmF0dXJlX2NhdGVnb3J5ID0gImM3IikKd3RfZ3N2YQoKd3RfZ3N2YV9zaWcgPC0gZ2V0X3NpZ19nc3ZhX2NhdGVnb3JpZXMod3RfZ3N2YSwgZXhjZWwgPSAiZXhjZWwvQ0xfYmlvcHNpZXNfZ3N2YV9vdXRjb21lX2M3Lnhsc3giKQp3dF9nc3ZhX3NpZwpgYGAKCkhtbSwgZGlkIEkgZ2V0IGNvbmZ1c2VkLCBpcyBDNyB3aGF0IEkgdGhvdWdodCBpdCB3YXM/ICBZZWFoLCBpdCBpcyB0aGUKaW1tdW5vbG9naWMgc2lnbmF0dXJlIHNldHMuICBDMiBpcyB0aGUgbGFyZ2VyIHNldCBvZiBleHBlcmltZW50cy4KCmBgYHtyfQp3ZWxsY29tZV9nc3ZhX2MyIDwtIHNpbXBsZV9nc3ZhKHdlbGxjb21lX2ZpbHRlcmVkLCBzaWduYXR1cmVfY2F0ZWdvcnkgPSAiYzIiKQp3ZWxsY29tZV9nc3ZhX2MyX3NpZyA8LSBnZXRfc2lnX2dzdmFfY2F0ZWdvcmllcygKICB3ZWxsY29tZV9nc3ZhX2MyLAogIGV4Y2VsID0gImV4Y2VsL0NMX2Jpb3BzaWVzX2dzdmFfb3V0Y29tZV9jMi54bHN4IikKYGBgCgpUaGUgZm9sbG93aW5nIGJsb2NrcyBtYXkgYmUgdXNlZCB0byBzYXZlIGFuZCByZWxvYWQgdGhlIHN0YXRlIG9mIHRoZSBkYXRhLgoKYGBge3J9CnBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCm1lc3NhZ2UoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkKdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm4gPSAiXFwuUm1kIiwgcmVwbGFjZSA9ICIiLCB4ID0gcm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKI21lc3NhZ2UoIlNhdmluZyB0byAiLCB0aGlzX3NhdmUpCnRtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWUgPSB0aGlzX3NhdmUpKQpgYGAKCmBgYHtyIGxvYWRtZSwgZXZhbD1GQUxTRX0KbG9hZG1lKGZpbGVuYW1lID0gdGhpc19zYXZlKQpgYGAK