1 Introduction

This worksheet attempts to describe some analyses performed as part of “Consolidation of a molecular and clinical signature of healing in cutaneous leishmaniasis is achieved during the first ten days of treatment.”

This dataset comprises 36 samples across 12 patient biopsies with varying drug treatment (Antimonial vs. Miltefosine), clinic visit (pre-treatment, mid treatment, end of treatment), Cure/Fail, and infecting parasite.

This dataset was initially analyzed by Najib as part of his goal to learn R and get a better understanding of how we process data. As a result I did not very closely examine the data. Given that we are likely to publish this data soon, that should be addressed.

samplesheet <- "sample_sheets/wellcome_trust_samples-v202209.xlsx"

rna_spec <- make_rnaseq_spec()
modified <- gather_preprocessing_metadata(samplesheet, specification = rna_spec, species = "hg38_100")
## Using provided specification
## Starting trimomatic_input.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*trimomatic/*-trimomatic.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*trimomatic/*-trimomatic.stderr.
## Not including new entries for: trimomatic_input, it is empty.
## Starting trimomatic_output.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*trimomatic/*-trimomatic.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*trimomatic/*-trimomatic.stderr.
## Not including new entries for: trimomatic_output, it is empty.
## Starting trimomatic_ratio.
## Checking input_file_spec: .
## Missing data to calculate the ratio between: trimomatic_output and trimomatic_input.
## Not including new entries for: trimomatic_percent, it is empty.
## Starting fastqc_pct_gc.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*fastqc/*_fastqc/fastqc_data.txt.
## Example filename: preprocessing/TMRC30097/outputs/*fastqc/*_fastqc/fastqc_data.txt.
## Starting fastqc_most_overrepresented.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*fastqc/*_fastqc/fastqc_data.txt.
## Skipping for now
## Not including new entries for: fastqc_most_overrepresented, it is empty.
## Starting hisat_rrna_single_concordant.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/hisat2_*rRNA*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hisat2_*rRNA*.stderr.
## Not including new entries for: hisat_rrna_single_concordant, it is empty.
## Starting hisat_rrna_multi_concordant.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/hisat2_*rRNA*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hisat2_*rRNA*.stderr.
## Not including new entries for: hisat_rrna_multi_concordant, it is empty.
## Starting hisat_rrna_percent.
## Checking input_file_spec: .
## Missing data to calculate the ratio between: hisat_rrna_multi_concordant and trimomatic_output.
## Not including new entries for: hisat_rrna_percent, it is empty.
## Starting hisat_genome_single_concordant.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/hisat2_*genome*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hisat2_*genome*.stderr.
## Not including new entries for: hisat_genome_single_concordant, it is empty.
## Starting hisat_genome_multi_concordant.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/hisat2_*genome*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hisat2_*genome*.stderr.
## Not including new entries for: hisat_genome_multi_concordant, it is empty.
## Starting hisat_genome_single_all.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/hisat2_*genome*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hisat2_*genome*.stderr.
## Not including new entries for: hisat_genome_single_all, it is empty.
## Starting hisat_genome_multi_all.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/hisat2_*genome*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hisat2_*genome*.stderr.
## Not including new entries for: hisat_genome_multi_all, it is empty.
## Starting hisat_genome_percent.
## Checking input_file_spec: .
## Missing data to calculate the ratio between: hisat_genome_single_concordant and trimomatic_output.
## Not including new entries for: hisat_genome_percent, it is empty.
## Starting hisat_count_table.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*hisat2_{species}/{species}_{type}*.count.xz.
## Example filename: preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30097/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30075/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30085/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30086/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30087/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30101/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30089/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30090/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30081/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30092/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30104/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30125/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30106/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30114/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30095/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30108/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30126/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30127/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30120/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30128/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30129/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30130/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30124/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30131/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30109/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30084/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30098/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30099/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30100/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30110/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30111/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30102/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30091/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30112/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30163/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30073/outputs/*hisat2_hg38_100/hg38_100_genome*.count.xz.
## Not including new entries for: hisat_count_table, it is empty.
## Starting salmon_stranded.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*salmon_{species}/salmon_*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*salmon_*/salmon_*.stderr.
## Starting salmon_count_table.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*salmon_{species}/quant.sf.
## Example filename: preprocessing/TMRC30097/outputs/*salmon_hg38_100/quant.sf.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30126/outputs/*salmon_hg38_100/quant.sf.
## Warning in dispatch_filename_search(meta, input_file_spec, verbose = verbose, : The input file is NA for:
## preprocessing/TMRC30129/outputs/*salmon_hg38_100/quant.sf.
## Starting salmon_mapped.
## Checking input_file_spec: {basedir}/{meta[['sampleid']]}/outputs/*salmon_{species}gg/salmon_*.stderr.
## Example filename: preprocessing/TMRC30097/outputs/*salmon_*gg/salmon_*.stderr.
## Not including new entries for: salmon_mapped, it is empty.
## Writing new metadata to: sample_sheets/wellcome_trust_samples-v202209_modified.xlsx
## Deleting the file sample_sheets/wellcome_trust_samples-v202209_modified.xlsx before writing the tables.

2 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")[["annotation"]]
## The biomart annotations file already exists, loading from it.
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")]

summary(hs_annot)
##  ensembl_transcript_id ensembl_gene_id       version     transcript_version hgnc_symbol        description        gene_biotype         cds_length    
##  Length:226754         Length:226754      Min.   : 1.0   Min.   : 1.00      Length:226754      Length:226754      Length:226754      Min.   :     3  
##  Class :character      Class :character   1st Qu.: 6.0   1st Qu.: 1.00      Class :character   Class :character   Class :character   1st Qu.:   357  
##  Mode  :character      Mode  :character   Median :12.0   Median : 1.00      Mode  :character   Mode  :character   Mode  :character   Median :   690  
##                                           Mean   :10.5   Mean   : 3.07                                                               Mean   :  1134  
##                                           3rd Qu.:15.0   3rd Qu.: 5.00                                                               3rd Qu.:  1440  
##                                           Max.   :26.0   Max.   :17.00                                                               Max.   :107976  
##                                                                                                                                      NA's   :126871  
##  chromosome_name       strand          start_position      end_position       transcript       
##  Length:226754      Length:226754      Min.   :5.77e+02   Min.   :6.47e+02   Length:226754     
##  Class :character   Class :character   1st Qu.:3.11e+07   1st Qu.:3.12e+07   Class :character  
##  Mode  :character   Mode  :character   Median :6.04e+07   Median :6.05e+07   Mode  :character  
##                                        Mean   :7.41e+07   Mean   :7.42e+07                     
##                                        3rd Qu.:1.09e+08   3rd Qu.:1.09e+08                     
##                                        Max.   :2.49e+08   Max.   :2.49e+08                     
## 

2.1 Gene Ontology data

hs_go <- load_biomart_go()[["go"]]
## The biomart annotations file already exists, loading from it.
hs_length <- hs_annot[, c("ensembl_gene_id", "cds_length")]
colnames(hs_length) <- c("ID", "length")

3 Create expressionsets

Start out by creating a few datastructures which define the primary questions in the data.

3.1 Color choices

I am going to grab colors from the TMRC3 data with the assumption that there are good choices there.

color_choices <- list(
  "cf_visit" = list(
    "cure_v1" = "#D95F0E",
    "failure_v1" = "#FEC44F",
    "cure_v2" = "#DD1C77",
    "failure_v2" = "#C994C7",
    "cure_v3" = "#3182BD",
    "failure_v3" = "#9ECAE1"),
  "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 these is an unspecified donor effect.

3.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.

wellcome_outtime <- create_expt(metadata = samplesheet, gene_info = hs_annot,
                             file_column = "hg38100hisatfile") %>%
  set_expt_batches(fact = "drug") %>%
  sanitize_metadata(spaces = TRUE)
## Reading the sample metadata.
## The sample definitions comprises: 36 rows(samples) and 48 columns(metadata fields).
## Matched 21433 annotations and counts.
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 21481 features and 36 samples.
## The number of samples by batch are:
## 
## Antimoniate Miltefosine 
##          18          18
outcome_time <- paste0(pData(wellcome_outtime)[["clinicaloutcome"]], "_v",
                       pData(wellcome_outtime)[["visitnumber"]])
wellcome_outtime <- set_expt_conditions(wellcome_outtime, fact = outcome_time) %>%
  set_expt_colors(color_choices[["cf_visit"]])
## The numbers of samples by condition are:
## 
##    cure_v1    cure_v2    cure_v3 failure_v1 failure_v2 failure_v3 
##          5          5          5          7          7          7
pData(wellcome_outtime)[["visitnumber"]] <- paste0("v", pData(wellcome_outtime)[["visitnumber"]])

3.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.

legend <- plot_legend(wellcome_outtime)
legend$plot

plot_libsize(wellcome_outtime)
## Library sizes of 36 samples, \
## ranging from 2,410,677 to 220,494,183.

plot_nonzero(wellcome_outtime, plot_labels = "repel")
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## A non-zero genes plot of 36 samples.
## These samples have an average 45.52 CPM coverage and 16644 genes observed, ranging from 14215 to
## 17990.
## Warning: ggrepel: 15 unlabeled data points (too many overlaps). Consider increasing max.overlaps

wellcome_filtered <- subset_expt(wellcome_outtime, nonzero = 15000)
## The samples (and read coverage) removed when filtering 15000 non-zero genes are: 
## subset_expt(): There were 36, now there are 34 samples.

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.

3.4 Only donor

Given that we don’t have enough samples for a full rank matrix of donor/drug/time/cf, I am going to create separate data structures where each individual factor is the condition, starting with donor.

wellcome_donor <- set_expt_conditions(wellcome_outtime, fact = "donor",
                                      colors = color_choices)
## The numbers of samples by condition are:
## 
## d1019 d1029 d1031 d1036 d1037 d2001 d2002 d2003 d2004 d2008 d2009 d2010 
##     3     3     3     3     3     3     3     3     3     3     3     3
## Error in set_expt_conditions(wellcome_outtime, fact = "donor", colors = color_choices): object 'color' not found
wellcome_filtdonor <- set_expt_conditions(wellcome_filtered, fact = "donor",
                                         colors = color_choices)
## The numbers of samples by condition are:
## 
## d1019 d1029 d1031 d1036 d1037 d2001 d2002 d2003 d2004 d2008 d2009 d2010 
##     3     3     3     3     3     3     3     2     3     3     2     3
## Error in set_expt_conditions(wellcome_filtered, fact = "donor", colors = color_choices): object 'color' not found

3.5 Only visit

In this case, the condition will only be visit number.

wellcome_time <- set_expt_conditions(wellcome_outtime, fact = "visitnumber",
                                     colors = color_choices[["visit"]])
## The numbers of samples by condition are:
## 
## v1 v2 v3 
## 12 12 12
wellcome_filttime <- set_expt_conditions(wellcome_filtered, fact = "visitnumber",
                                         colors = color_choices[["visit"]])
## The numbers of samples by condition are:
## 
## v1 v2 v3 
## 11 12 11

3.6 Only Cure/Fail

Conversely, we can split by clinical outcome.

wellcome_outcome <- set_expt_conditions(wellcome_outtime, fact = "clinicaloutcome",
                                        colors = color_choices[["cf"]]) %>%
  set_expt_batches(fact = "visitnumber")
## The numbers of samples by condition are:
## 
##    cure failure 
##      15      21
## The number of samples by batch are:
## 
## v1 v2 v3 
## 12 12 12
wellcome_outcome_filt <- set_expt_conditions(wellcome_filtered, fact = "clinicaloutcome",
                                        colors = color_choices[["cf"]]) %>%
  set_expt_batches(fact = "visitnumber")
## The numbers of samples by condition are:
## 
##    cure failure 
##      15      19
## The number of samples by batch are:
## 
## v1 v2 v3 
## 11 12 11

3.7 Only drug

… or drug used.

wellcome_drug <- set_expt_conditions(wellcome_outtime, fact = "drug",
                                     colors = color_choices[["drug"]]) %>%
  set_expt_batches(fact = "visitnumber")
## The numbers of samples by condition are:
## 
## antimoniate miltefosine 
##          18          18
## The number of samples by batch are:
## 
## v1 v2 v3 
## 12 12 12
wellcome_drugfilt <- set_expt_conditions(wellcome_filtered, fact = "drug",
                                     colors = color_choices[["drug"]]) %>%
  set_expt_batches(fact = "visitnumber")
## The numbers of samples by condition are:
## 
## antimoniate miltefosine 
##          18          16
## The number of samples by batch are:
## 
## v1 v2 v3 
## 11 12 11

3.8 Only parasite

… and the infecting parasite.

wellcome_parasite <- set_expt_conditions(wellcome_outtime, fact = "infectingspecies",
                                         colors = color_choices[["species"]]) %>%
  set_expt_batches(fact = "visitnumber")
## The numbers of samples by condition are:
## 
## lvbraziliensis   lvpanamensis 
##             12             24
## The number of samples by batch are:
## 
## v1 v2 v3 
## 12 12 12
wellcome_parafilt <- set_expt_conditions(wellcome_filtered, fact = "infectingspecies",
                                         colors = color_choices[["species"]]) %>%
  set_expt_batches(fact = "visitnumber")
## The numbers of samples by condition are:
## 
## lvbraziliensis   lvpanamensis 
##             11             23
## The number of samples by batch are:
## 
## v1 v2 v3 
## 11 12 11

3.9 Visualize the metadata

drug_visit_species_cf <- plot_meta_sankey(
  wellcome_outtime, factors = c("drug", "visitnumber", "infectingspecies", "clinicaloutcome"),
  color_choices = color_choices)
## Warning: attributes are not identical across measure variables; they will be dropped
drug_visit_species_cf
## A sankey plot describing the metadata of 36 samples,
## including 41 out of 44 nodes and traversing metadata factors:
## drug, visitnumber, infectingspecies, clinicaloutcome.

Note that there do not appear to be any miltefosine, braziliensis, fails.

4 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…

all_varpart_donor <- simple_varpart(
  wellcome_filtered,
  factors = c("donor", "visitnumber"))
## Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## The following object is masked from 'package:S4Vectors':
## 
##     expand
## Warning in summary.lm(object, ...): essentially perfect fit: summary may be unreliable

## Warning in summary.lm(object, ...): essentially perfect fit: summary may be unreliable

## Warning in summary.lm(object, ...): essentially perfect fit: summary may be unreliable
## 
## Total:117 s
all_varpart_donor
## The result of using variancePartition with the model: x[['model_string']]

all_varpart_dvic <- simple_varpart(
  wellcome_filtered,
  factors = c("drug", "visitnumber", "infectingspecies", "clinicaloutcome"))
## 
## Total:136 s
all_varpart_dvic
## The result of using variancePartition with the model: x[['model_string']]

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.

4.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(all_varpart_donor[["fitted_df"]][["donor"]])
top_300_donor_genes <- tail(all_varpart_donor[["fitted_df"]][top_300_donor_genes_idx, ], n = 300)
summary(top_300_donor_genes)
##      donor        visitnumber       Residuals    
##  Min.   :0.634   Min.   :0.0000   Min.   :0.000  
##  1st Qu.:0.648   1st Qu.:0.0329   1st Qu.:0.213  
##  Median :0.673   Median :0.0661   Median :0.246  
##  Mean   :0.697   Mean   :0.0635   Mean   :0.239  
##  3rd Qu.:0.729   3rd Qu.:0.0910   3rd Qu.:0.271  
##  Max.   :1.000   Max.   :0.1494   Max.   :0.345
donor_genes_gp <- simple_gprofiler(rownames(top_300_donor_genes))
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
donor_genes_gp
## A set of ontologies produced by gprofiler using 300
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are 83 GO hits, 0, KEGG hits, 18 reactome hits, 0 wikipathway hits, 8 transcription factor hits, 0 miRNA hits, 0 HPA hits, 0 HP hits, and 0 CORUM hits.
## Category BP is the most populated with 30 hits.

top_300_visit_genes_idx <- order(all_varpart_dvic[["fitted_df"]][["visitnumber"]])
top_300_visit_genes <- tail(all_varpart_dvic[["fitted_df"]][top_300_visit_genes_idx, ], n = 300)
summary(top_300_visit_genes)
##       drug          visitnumber    infectingspecies  clinicaloutcome     Residuals    
##  Min.   :0.00000   Min.   :0.351   Min.   :0.00000   Min.   :0.00000   Min.   :0.380  
##  1st Qu.:0.00098   1st Qu.:0.369   1st Qu.:0.00206   1st Qu.:0.00074   1st Qu.:0.523  
##  Median :0.00353   Median :0.392   Median :0.01071   Median :0.00336   Median :0.568  
##  Mean   :0.00941   Mean   :0.405   Mean   :0.01937   Mean   :0.00789   Mean   :0.559  
##  3rd Qu.:0.01049   3rd Qu.:0.429   3rd Qu.:0.02541   3rd Qu.:0.00890   3rd Qu.:0.601  
##  Max.   :0.08742   Max.   :0.599   Max.   :0.20026   Max.   :0.08396   Max.   :0.645
visit_genes_gp <- simple_gprofiler(rownames(top_300_visit_genes))
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
visit_genes_gp
## A set of ontologies produced by gprofiler using 300
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are 39 GO hits, 0, KEGG hits, 2 reactome hits, 0 wikipathway hits, 5 transcription factor hits, 0 miRNA hits, 2 HPA hits, 0 HP hits, and 0 CORUM hits.
## Category BP is the most populated with 22 hits.

top_300_drug_genes_idx <- order(all_varpart_dvic[["fitted_df"]][["drug"]])
top_300_drug_genes <- tail(all_varpart_dvic[["fitted_df"]][top_300_drug_genes_idx, ], n = 300)
summary(top_300_drug_genes)
##       drug         visitnumber     infectingspecies clinicaloutcome     Residuals    
##  Min.   :0.0855   Min.   :0.0005   Min.   :0.0000   Min.   :0.00000   Min.   :0.475  
##  1st Qu.:0.0952   1st Qu.:0.0384   1st Qu.:0.0035   1st Qu.:0.00241   1st Qu.:0.682  
##  Median :0.1068   Median :0.0819   Median :0.0121   Median :0.01358   Median :0.733  
##  Mean   :0.1166   Mean   :0.0934   Mean   :0.0330   Mean   :0.02867   Mean   :0.728  
##  3rd Qu.:0.1281   3rd Qu.:0.1316   3rd Qu.:0.0434   3rd Qu.:0.04383   3rd Qu.:0.789  
##  Max.   :0.2484   Max.   :0.4005   Max.   :0.3613   Max.   :0.17113   Max.   :0.890
drug_genes_gp <- simple_gprofiler(rownames(top_300_drug_genes))
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
drug_genes_gp
## A set of ontologies produced by gprofiler using 300
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are 29 GO hits, 0, KEGG hits, 0 reactome hits, 0 wikipathway hits, 0 transcription factor hits, 0 miRNA hits, 2 HPA hits, 0 HP hits, and 0 CORUM hits.
## Category BP is the most populated with 14 hits.

top_300_species_genes_idx <- order(all_varpart_dvic[["fitted_df"]][["infectingspecies"]])
top_300_species_genes <- tail(all_varpart_dvic[["fitted_df"]][top_300_species_genes_idx, ], n = 300)
summary(top_300_species_genes)
##       drug          visitnumber      infectingspecies clinicaloutcome     Residuals    
##  Min.   :0.00000   Min.   :0.00027   Min.   :0.201    Min.   :0.00000   Min.   :0.450  
##  1st Qu.:0.00194   1st Qu.:0.03845   1st Qu.:0.214    1st Qu.:0.00116   1st Qu.:0.604  
##  Median :0.00678   Median :0.06786   Median :0.238    Median :0.00505   Median :0.650  
##  Mean   :0.01451   Mean   :0.07222   Mean   :0.254    Mean   :0.01734   Mean   :0.642  
##  3rd Qu.:0.01880   3rd Qu.:0.10072   3rd Qu.:0.273    3rd Qu.:0.02279   3rd Qu.:0.693  
##  Max.   :0.20728   Max.   :0.30268   Max.   :0.440    Max.   :0.17757   Max.   :0.775
species_genes_gp <- simple_gprofiler(rownames(top_300_species_genes))
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
species_genes_gp
## A set of ontologies produced by gprofiler using 300
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are 32 GO hits, 0, KEGG hits, 0 reactome hits, 0 wikipathway hits, 4 transcription factor hits, 3 miRNA hits, 0 HPA hits, 0 HP hits, and 0 CORUM hits.
## Category CC is the most populated with 15 hits.

top_300_cf_genes_idx <- order(all_varpart_dvic[["fitted_df"]][["clinicaloutcome"]])
top_300_cf_genes <- tail(all_varpart_dvic[["fitted_df"]][top_300_cf_genes_idx, ], n = 300)
summary(top_300_cf_genes)
##       drug         visitnumber      infectingspecies clinicaloutcome   Residuals    
##  Min.   :0.0000   Min.   :0.00014   Min.   :0.0000   Min.   :0.101   Min.   :0.405  
##  1st Qu.:0.0070   1st Qu.:0.04878   1st Qu.:0.0057   1st Qu.:0.111   1st Qu.:0.641  
##  Median :0.0228   Median :0.09591   Median :0.0204   Median :0.126   Median :0.693  
##  Mean   :0.0313   Mean   :0.10356   Mean   :0.0416   Mean   :0.131   Mean   :0.692  
##  3rd Qu.:0.0441   3rd Qu.:0.14862   3rd Qu.:0.0547   3rd Qu.:0.144   3rd Qu.:0.752  
##  Max.   :0.2115   Max.   :0.31194   Max.   :0.3507   Max.   :0.255   Max.   :0.864
cf_genes_gp <- simple_gprofiler(rownames(top_300_cf_genes))
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
## No results to show
## Please make sure that the organism is correct or set significant = FALSE
cf_genes_gp
## A set of ontologies produced by gprofiler using 300
## genes against the hsapiens annotations and significance cutoff 0.05.
## There are 112 GO hits, 1, KEGG hits, 5 reactome hits, 0 wikipathway hits, 0 transcription factor hits, 0 miRNA hits, 0 HPA hits, 0 HP hits, and 0 CORUM hits.
## Category BP is the most populated with 30 hits.

5 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.

wellcome_outtime_norm <- normalize_expt(wellcome_outtime, filter = TRUE,
                                        convert = "cpm", transform = "log2", norm = "quant")
## Removing 7327 low-count genes (14154 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outtime_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure_v1, cure_v2, cure_v3, failure_v1, failure_v2, failure_v3
## Shapes are defined by antimoniate, miltefosine.

wellcome_outfilt_norm <- normalize_expt(wellcome_filtered, filter = TRUE,
                                        convert = "cpm", transform = "log2", norm = "quant")
## Removing 7361 low-count genes (14120 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outfilt_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure_v1, cure_v2, cure_v3, failure_v1, failure_v2, failure_v3
## Shapes are defined by antimoniate, miltefosine.

6 GSVA

From my perspective, it seems that the most interesting GSVA comparison is to look for scores changing between the cure and fail samples.

wt_gsva <- simple_gsva(wellcome_outcome_filt)
## Converting the rownames() of the expressionset to ENTREZID.
## 1630 ENSEMBL ID's didn't have a matching ENTEREZ ID. Dropping them now.
## Before conversion, the expressionset has 21481 entries.
## After conversion, the expressionset has 20006 entries.
wt_gsva
## GSVA result using method: ssgsea against the c2 dataset.
## Scores range from: -0.4572 to: 0.5428.
wt_gsva_sig <- get_sig_gsva_categories(wt_gsva, excel = "excel/wellcome_outcome_filt_gsva.xlsx")
## Starting limma pairwise comparison.
## libsize was not specified, this parameter has profound effects on limma's result.
## Using the libsize from expt$libsize.
## Limma step 1/6: choosing model.
## Assuming this data is similar to a micro array and not performign voom.
## Limma step 3/6: running lmFit with method: ls.
## Limma step 4/6: making and fitting contrasts with no intercept. (~ 0 + factors)
## Limma step 5/6: Running eBayes with robust = FALSE and trend = FALSE.
## Limma step 6/6: Writing limma outputs.
## Limma step 6/6: 1/1: Creating table: failure_vs_cure.  Adjust = BH
## Limma step 6/6: 1/2: Creating table: cure.  Adjust = BH
## Limma step 6/6: 2/2: Creating table: failure.  Adjust = BH
## The factor cure has 15 rows.
## The factor failure has 19 rows.
## Testing each factor against the others.
## Scoring cure against everything else.
## Scoring failure against everything else.
## Deleting the file excel/wellcome_outcome_filt_gsva.xlsx before writing the tables.
wt_gsva_sig
## The set of GSVA categories deemed significantly higher than the
## distribution of all scores.  It comprises 44 gene sets.
## Error in xy.coords(x, y, xlabel, ylabel, log): 'x' is a list, but does not have components 'x' and 'y'

7 Visualize Various PCA

7.1 By visit

wellcome_time_norm <- normalize_expt(wellcome_filttime, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_time_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by antimoniate, miltefosine.

wellcome_time_nb <- normalize_expt(wellcome_filttime, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## Setting 904 low elements to zero.
## transform_counts: Found 904 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_time_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by v1, v2, v3
## Shapes are defined by antimoniate, miltefosine.

7.2 Cure/Fail

wellcome_outcome_norm <- normalize_expt(wellcome_outcome_filt, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outcome_norm, plot_labels=FALSE)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by v1, v2, v3.

wellcome_outcome_nb <- normalize_expt(wellcome_outcome_filt, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## Setting 819 low elements to zero.
## transform_counts: Found 819 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outcome_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure, failure
## Shapes are defined by v1, v2, v3.

Wow, there really isn’t much C/F variance, is there.

7.3 Drug

wellcome_drug_norm <- normalize_expt(wellcome_drugfilt, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_drug_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by antimoniate, miltefosine
## Shapes are defined by v1, v2, v3.

wellcome_drug_nb <- normalize_expt(wellcome_drugfilt, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## Setting 868 low elements to zero.
## transform_counts: Found 868 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_drug_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by antimoniate, miltefosine
## Shapes are defined by v1, v2, v3.

7.4 Outcome and time

wellcome_outtime_norm <- normalize_expt(wellcome_filtered, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outtime_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure_v1, cure_v2, cure_v3, failure_v1, failure_v2, failure_v3
## Shapes are defined by antimoniate, miltefosine.

wellcome_outtime_nb <- normalize_expt(wellcome_filtered, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## Setting 928 low elements to zero.
## transform_counts: Found 928 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outtime_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by cure_v1, cure_v2, cure_v3, failure_v1, failure_v2, failure_v3
## Shapes are defined by antimoniate, miltefosine.

7.5 Parasite Species

wellcome_parasite_norm <- normalize_expt(wellcome_parafilt, norm = "quant", convert = "cpm",
                                         filter = TRUE, transform = "log2")
## Removing 7361 low-count genes (14120 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_parasite_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by lvbraziliensis, lvpanamensis
## Shapes are defined by v1, v2, v3.

wellcome_parasite_nb <- normalize_expt(wellcome_parafilt, norm = "quant", convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Warning in normalize_expt(wellcome_parafilt, norm = "quant", convert = "cpm", : Quantile normalization and sva do not always play well together.
## Removing 7361 low-count genes (14120 remaining).
## Setting 649 low elements to zero.
## transform_counts: Found 649 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_parasite_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by lvbraziliensis, lvpanamensis
## Shapes are defined by v1, v2, v3.

8 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.

8.1 Outcome and time

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.

outtime_sva_de <- all_pairwise(wellcome_filtered, model_batch = "svaseq", filter = TRUE)
## 
##    cure_v1    cure_v2    cure_v3 failure_v1 failure_v2 failure_v3 
##          5          5          5          6          7          6
## Removing 0 low-count genes (14120 remaining).
## Setting 928 low elements to zero.
## transform_counts: Found 928 values equal to 0, adding 1 to the matrix.
outtime_sva_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
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"))
outtime_sva_table <- combine_de_tables(
    outtime_sva_de,
    keepers = outtime_keepers,
    excel = glue::glue("excel/wellcome_outtime_table_sva-v{ver}.xlsx"))
## Deleting the file excel/wellcome_outtime_table_sva-v20230626.xlsx before writing the tables.
## Adding venn plots for curev1v2.
## Adding venn plots for curev1v3.
## Adding venn plots for curev2v3.
## Adding venn plots for failv1v2.
## Adding venn plots for failv1v3.
## Adding venn plots for failv2v3.
## Adding venn plots for cfv1.
## Adding venn plots for cfv2.
## Adding venn plots for cfv3.
outtime_sva_table
## A set of combined differential expression results.

##                    table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1       curev2_vs_curev1         539           335         528           292         162           187
## 2       curev3_vs_curev1         803           684         803           618         489           549
## 3       curev3_vs_curev2          13             3           6             3           1             0
## 4 failurev2_vs_failurev1         256            59         195            51           0             0
## 5 failurev3_vs_failurev1        1232           617        1186           611         827           791
## 6 failurev3_vs_failurev2         136            86          99            65          16            36
## 7    failurev1_vs_curev1          34           210          24           149           1            12
## 8    failurev2_vs_curev2          12            17           4             6           0             0
## 9    failurev3_vs_curev3           4             0           0             0           0             0

outtime_sva_sig <- extract_significant_genes(
    outtime_sva_table,
    excel = glue::glue("excel/wellcome_outtime_sig_sva-v{ver}.xlsx"))
## Deleting the file excel/wellcome_outtime_sig_sva-v20230626.xlsx before writing the tables.
outtime_sva_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##          limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## curev1v2      162        187      528        292      539        335        0          0
## curev1v3      489        549      803        618      803        684       20         61
## curev2v3        1          0        6          3       13          3        0          0
## failv1v2        0          0      195         51      256         59        0          0
## failv1v3      827        791     1186        611     1232        617        0          0
## failv2v3       16         36       99         65      136         86        0          0
## cfv1            1         12       24        149       34        210        0          0
## cfv2            0          0        4          6       12         17        0          0
## cfv3            0          0        0          0        4          0        0          0

outtime_batch_de <- all_pairwise(wellcome_filtered, model_batch = TRUE, filter = TRUE)
## 
##    cure_v1    cure_v2    cure_v3 failure_v1 failure_v2 failure_v3 
##          5          5          5          6          7          6 
## 
## antimoniate miltefosine 
##          18          16

outtime_batch_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: batch in model/limma.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
outtime_batch_table <- combine_de_tables(
    outtime_batch_de,
    keepers = outtime_keepers,
    excel = glue::glue("excel/wellcome_outtime_table_batch-v{ver}.xlsx"))
## Adding venn plots for curev1v2.
## Adding venn plots for curev1v3.
## Adding venn plots for curev2v3.
## Adding venn plots for failv1v2.
## Adding venn plots for failv1v3.
## Adding venn plots for failv2v3.
## Adding venn plots for cfv1.
## Adding venn plots for cfv2.
## Adding venn plots for cfv3.
outtime_batch_table
## A set of combined differential expression results.
##                    table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1       curev2_vs_curev1         437           260         392           217         159           147
## 2       curev3_vs_curev1         624           580         611           523         455           489
## 3       curev3_vs_curev2           5             4           1             1           1             0
## 4 failurev2_vs_failurev1         196            33         128            28           0             2
## 5 failurev3_vs_failurev1        1028           526         960           514         707           726
## 6 failurev3_vs_failurev2          46            40          24            23           0             7
## 7    failurev1_vs_curev1          69           266          49           216           9            36
## 8    failurev2_vs_curev2           8             7           0             5           0             0
## 9    failurev3_vs_curev3           0             0           0             0           0             0

outtime_batch_sig <- extract_significant_genes(
    outtime_batch_table,
    excel = glue::glue("excel/wellcome_outtime_sig_batch-v{ver}.xlsx"))
outtime_batch_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##          limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## curev1v2      159        147      392        217      437        260        0          0
## curev1v3      455        489      611        523      624        580       20         61
## curev2v3        1          0        1          1        5          4        0          0
## failv1v2        0          2      128         28      196         33        0          0
## failv1v3      707        726      960        514     1028        526        0          0
## failv2v3        0          7       24         23       46         40        0          0
## cfv1            9         36       49        216       69        266        0          0
## cfv2            0          0        0          5        8          7        0          0
## cfv3            0          0        0          0        0          0        0          0

8.2 Only time

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

time_sva_de <- all_pairwise(wellcome_filttime, model_batch = "svaseq", filter = TRUE)
## 
## v1 v2 v3 
## 11 12 11
## Removing 0 low-count genes (14120 remaining).
## Setting 904 low elements to zero.
## transform_counts: Found 904 values equal to 0, adding 1 to the matrix.

time_sva_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
time_keepers <- list(
    "v1v2" = c("v2", "v1"),
    "v1v3" = c("v3", "v1"),
    "v2v3" = c("v3", "v2"))
time_sva_table <- combine_de_tables(
    time_sva_de,
    keepers = time_keepers,
    excel = glue::glue("excel/wellcome_time_table_sva-v{ver}.xlsx"))
## Adding venn plots for v1v2.
## Adding venn plots for v1v3.
## Adding venn plots for v2v3.
time_sva_table
## A set of combined differential expression results.
##      table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1 v2_vs_v1         626           217         619           217         315           290
## 2 v3_vs_v1        1254           669        1274           650         904           789
## 3 v3_vs_v2         205           184         189           170          54            52

time_sva_sig <- extract_significant_genes(
    time_sva_table,
    excel = glue::glue("excel/wellcome_time_sig_sva-v{ver}.xlsx"))
time_sva_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##      limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## v1v2      315        290      619        217      626        217      142        190
## v1v3      904        789     1274        650     1254        669      656        650
## v2v3       54         52      189        170      205        184        0          0

time_batch_de <- all_pairwise(wellcome_filttime, model_batch = "batchseq", filter = TRUE)
## 
## v1 v2 v3 
## 11 12 11 
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  2
## Removing 0 low-count genes (14120 remaining).
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  7
## Setting 831 low elements to zero.
## transform_counts: Found 831 values equal to 0, adding 1 to the matrix.

time_batch_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: batchseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
time_batch_table <- combine_de_tables(
    time_batch_de,
    keepers = time_keepers,
    excel = glue::glue("excel/wellcome_time_table_batch-v{ver}.xlsx"))
## Adding venn plots for v1v2.
## Adding venn plots for v1v3.
## Adding venn plots for v2v3.
time_batch_table
## A set of combined differential expression results.
##      table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1 v2_vs_v1         342            92         314            94         141            77
## 2 v3_vs_v1         416           242         340           206          37            39
## 3 v3_vs_v2          12            39           6            35           0             0

time_batch_sig <- extract_significant_genes(
    time_batch_table,
    excel = glue::glue("excel/wellcome_time_batch_sva-v{ver}.xlsx"))
time_batch_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##      limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## v1v2      141         77      314         94      342         92      142        190
## v1v3       37         39      340        206      416        242      656        650
## v2v3        0          0        6         35       12         39        0          0

8.3 Strain

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

parasite_sva_de <- all_pairwise(wellcome_parafilt, model_batch = "svaseq", filter = TRUE)
## 
## lvbraziliensis   lvpanamensis 
##             11             23
## Removing 0 low-count genes (14120 remaining).
## Setting 922 low elements to zero.
## transform_counts: Found 922 values equal to 0, adding 1 to the matrix.
parasite_sva_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
##                 lvpanamensis_vs_lvbraziliensis
## limma_vs_deseq                          0.6960
## limma_vs_edger                          0.8564
## limma_vs_basic                          0.9152
## limma_vs_noiseq                        -0.8289
## deseq_vs_edger                          0.8951
## deseq_vs_basic                          0.6937
## deseq_vs_noiseq                        -0.6436
## edger_vs_basic                          0.8441
## edger_vs_noiseq                        -0.8205
## basic_vs_noiseq                        -0.8786
parasite_sva_table <- combine_de_tables(
    parasite_sva_de,
    excel = glue::glue("excel/wellcome_parasite_table_sva-v{ver}.xlsx"))
## Adding venn plots for lvpanamensis_vs_lvbraziliensis.
parasite_sva_table
## A set of combined differential expression results.
##                            table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1 lvpanamensis_vs_lvbraziliensis         110            80          83            79          44            70
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

parasite_sva_sig <- extract_significant_genes(
    parasite_sva_table,
    excel = glue::glue("excel/wellcome_parasite_sig_sva-v{ver}.xlsx"))
parasite_sva_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                                limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## lvpanamensis_vs_lvbraziliensis       44         70       83         79      110         80        1          3

parasite_batch_de <- all_pairwise(wellcome_parafilt, model_batch = "batchseq", filter = TRUE)
## 
## lvbraziliensis   lvpanamensis 
##             11             23 
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  2
## Removing 0 low-count genes (14120 remaining).
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  6
## Setting 899 low elements to zero.
## transform_counts: Found 899 values equal to 0, adding 1 to the matrix.
parasite_batch_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: batchseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
##                 lvpanamensis_vs_lvbraziliensis
## limma_vs_deseq                          0.7055
## limma_vs_edger                          0.8580
## limma_vs_basic                          0.9070
## limma_vs_noiseq                        -0.8221
## deseq_vs_edger                          0.9041
## deseq_vs_basic                          0.6906
## deseq_vs_noiseq                        -0.6408
## edger_vs_basic                          0.8268
## edger_vs_noiseq                        -0.8024
## basic_vs_noiseq                        -0.8786
parasite_batch_table <- combine_de_tables(
    parasite_batch_de,
    excel = glue::glue("excel/wellcome_parasite_table_batch-v{ver}.xlsx"))
## Adding venn plots for lvpanamensis_vs_lvbraziliensis.
parasite_batch_table
## A set of combined differential expression results.
##                            table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1 lvpanamensis_vs_lvbraziliensis         136            93         113           103          47           103
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

parasite_batch_sig <- extract_significant_genes(
    parasite_batch_table,
    excel = glue::glue("excel/wellcome_parasite_sig_sva-v{ver}.xlsx"))
## Deleting the file excel/wellcome_parasite_sig_sva-v20230626.xlsx before writing the tables.
parasite_batch_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                                limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## lvpanamensis_vs_lvbraziliensis       47        103      113        103      136         93        1          3

8.4 Outcome

outcome_sva_de <- all_pairwise(wellcome_outcome_filt, model_batch = "svaseq", filter = TRUE)
## 
##    cure failure 
##      15      19
## Removing 0 low-count genes (14120 remaining).
## Setting 819 low elements to zero.
## transform_counts: Found 819 values equal to 0, adding 1 to the matrix.
outcome_sva_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
##                 failure_vs_cure
## limma_vs_deseq           0.8086
## limma_vs_edger           0.8238
## limma_vs_basic           0.7541
## limma_vs_noiseq         -0.6946
## deseq_vs_edger           0.9959
## deseq_vs_basic           0.6992
## deseq_vs_noiseq         -0.6866
## edger_vs_basic           0.7174
## edger_vs_noiseq         -0.7037
## basic_vs_noiseq         -0.9077
outcome_sva_table <- combine_de_tables(
    outcome_sva_de,
    excel = glue::glue("excel/wellcome_outcome_table_sva-v{ver}.xlsx"))
## Deleting the file excel/wellcome_outcome_table_sva-v20230626.xlsx before writing the tables.
## Adding venn plots for failure_vs_cure.
outcome_sva_table
## A set of combined differential expression results.
##             table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1 failure_vs_cure          11            28          10            18           0             0
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

outcome_sva_sig <- extract_significant_genes(
    outcome_sva_table,
    excel = glue::glue("excel/wellcome_outcome_sig_sva-v{ver}.xlsx"))
## Deleting the file excel/wellcome_outcome_sig_sva-v20230626.xlsx before writing the tables.
outcome_sva_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                 limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## failure_vs_cure        0          0       10         18       11         28        0          0

outcome_batch_de <- all_pairwise(wellcome_outcome_filt, model_batch = "batchseq", filter = TRUE)
## 
##    cure failure 
##      15      19 
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  2
## Removing 0 low-count genes (14120 remaining).
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  7
## Setting 836 low elements to zero.
## transform_counts: Found 836 values equal to 0, adding 1 to the matrix.
outcome_batch_de
## A pairwise differential expression with results from: basic, deseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: batchseq.
## The primary analysis performed 10 comparisons.
## The logFC agreement among the methods follows:
##                 failure_vs_cure
## limma_vs_deseq           0.7606
## limma_vs_edger           0.7912
## limma_vs_basic           0.4550
## limma_vs_noiseq         -0.3958
## deseq_vs_edger           0.9920
## deseq_vs_basic           0.3760
## deseq_vs_noiseq         -0.3833
## edger_vs_basic           0.3961
## edger_vs_noiseq         -0.4019
## basic_vs_noiseq         -0.9077
outcome_batch_table <- combine_de_tables(
    outcome_batch_de,
    excel = glue::glue("excel/wellcome_outcome_table_batch-v{ver}.xlsx"))
## Deleting the file excel/wellcome_outcome_table_batch-v20230626.xlsx before writing the tables.
## Adding venn plots for failure_vs_cure.
outcome_batch_table
## A set of combined differential expression results.
##             table deseq_sigup deseq_sigdown edger_sigup edger_sigdown limma_sigup limma_sigdown
## 1 failure_vs_cure           7             9           1             3           0             0
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

outcome_batch_sig <- extract_significant_genes(
    outcome_batch_table,
    excel = glue::glue("excel/wellcome_outcome_sig_sva-v{ver}.xlsx"))
## Deleting the file excel/wellcome_outcome_sig_sva-v20230626.xlsx before writing the tables.
outcome_batch_sig
## A set of genes deemed significant according to limma, edger, deseq, basic.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                 limma_up limma_down edger_up edger_down deseq_up deseq_down basic_up basic_down
## failure_vs_cure        0          0        1          3        7          9        0          0

9 Additional GSVA

wellcome_gsva_c2 <- simple_gsva(wellcome_filtered, signature_category="c2")
## Converting the rownames() of the expressionset to ENTREZID.
## 1630 ENSEMBL ID's didn't have a matching ENTEREZ ID. Dropping them now.
## Before conversion, the expressionset has 21481 entries.
## After conversion, the expressionset has 20006 entries.
wellcome_gsva_c2_sig <- get_sig_gsva_categories(
    wellcome_gsva_c2,
    excel="excel/wellcome_gsva_c2.xlsx")
## Starting limma pairwise comparison.
## libsize was not specified, this parameter has profound effects on limma's result.
## Using the libsize from expt$libsize.
## Limma step 1/6: choosing model.
## Assuming this data is similar to a micro array and not performign voom.
## Limma step 3/6: running lmFit with method: ls.
## Limma step 4/6: making and fitting contrasts with no intercept. (~ 0 + factors)
## Limma step 5/6: Running eBayes with robust = FALSE and trend = FALSE.
## Limma step 6/6: Writing limma outputs.
## Limma step 6/6: 1/15: Creating table: curev2_vs_curev1.  Adjust = BH
## Limma step 6/6: 2/15: Creating table: curev3_vs_curev1.  Adjust = BH
## Limma step 6/6: 3/15: Creating table: failurev1_vs_curev1.  Adjust = BH
## Limma step 6/6: 4/15: Creating table: failurev2_vs_curev1.  Adjust = BH
## Limma step 6/6: 5/15: Creating table: failurev3_vs_curev1.  Adjust = BH
## Limma step 6/6: 6/15: Creating table: curev3_vs_curev2.  Adjust = BH
## Limma step 6/6: 7/15: Creating table: failurev1_vs_curev2.  Adjust = BH
## Limma step 6/6: 8/15: Creating table: failurev2_vs_curev2.  Adjust = BH
## Limma step 6/6: 9/15: Creating table: failurev3_vs_curev2.  Adjust = BH
## Limma step 6/6: 10/15: Creating table: failurev1_vs_curev3.  Adjust = BH
## Limma step 6/6: 11/15: Creating table: failurev2_vs_curev3.  Adjust = BH
## Limma step 6/6: 12/15: Creating table: failurev3_vs_curev3.  Adjust = BH
## Limma step 6/6: 13/15: Creating table: failurev2_vs_failurev1.  Adjust = BH
## Limma step 6/6: 14/15: Creating table: failurev3_vs_failurev1.  Adjust = BH
## Limma step 6/6: 15/15: Creating table: failurev3_vs_failurev2.  Adjust = BH
## Limma step 6/6: 1/6: Creating table: curev1.  Adjust = BH
## Limma step 6/6: 2/6: Creating table: curev2.  Adjust = BH
## Limma step 6/6: 3/6: Creating table: curev3.  Adjust = BH
## Limma step 6/6: 4/6: Creating table: failurev1.  Adjust = BH
## Limma step 6/6: 5/6: Creating table: failurev2.  Adjust = BH
## Limma step 6/6: 6/6: Creating table: failurev3.  Adjust = BH
## The factor cure_v1 has 5 rows.
## The factor cure_v2 has 5 rows.
## The factor cure_v3 has 5 rows.
## The factor failure_v1 has 6 rows.
## The factor failure_v2 has 7 rows.
## The factor failure_v3 has 6 rows.
## Testing each factor against the others.
## Scoring cure_v1 against everything else.
## Scoring cure_v2 against everything else.
## Scoring cure_v3 against everything else.
## Scoring failure_v1 against everything else.
## Scoring failure_v2 against everything else.
## Scoring failure_v3 against everything else.
## Deleting the file excel/wellcome_gsva_c2.xlsx before writing the tables.
wellcome_gsva_c7 <- simple_gsva(wellcome_filtered, signature_category="c7")
## Converting the rownames() of the expressionset to ENTREZID.
## 1630 ENSEMBL ID's didn't have a matching ENTEREZ ID. Dropping them now.
## Before conversion, the expressionset has 21481 entries.
## After conversion, the expressionset has 20006 entries.
wellcome_gsva_c7_sig <- get_sig_gsva_categories(
    wellcome_gsva_c7,
    excel="excel/wellcome_gsva_c7.xlsx")
## Starting limma pairwise comparison.
## libsize was not specified, this parameter has profound effects on limma's result.
## Using the libsize from expt$libsize.
## Limma step 1/6: choosing model.
## Assuming this data is similar to a micro array and not performign voom.
## Limma step 3/6: running lmFit with method: ls.
## Limma step 4/6: making and fitting contrasts with no intercept. (~ 0 + factors)
## Limma step 5/6: Running eBayes with robust = FALSE and trend = FALSE.
## Limma step 6/6: Writing limma outputs.
## Limma step 6/6: 1/15: Creating table: curev2_vs_curev1.  Adjust = BH
## Limma step 6/6: 2/15: Creating table: curev3_vs_curev1.  Adjust = BH
## Limma step 6/6: 3/15: Creating table: failurev1_vs_curev1.  Adjust = BH
## Limma step 6/6: 4/15: Creating table: failurev2_vs_curev1.  Adjust = BH
## Limma step 6/6: 5/15: Creating table: failurev3_vs_curev1.  Adjust = BH
## Limma step 6/6: 6/15: Creating table: curev3_vs_curev2.  Adjust = BH
## Limma step 6/6: 7/15: Creating table: failurev1_vs_curev2.  Adjust = BH
## Limma step 6/6: 8/15: Creating table: failurev2_vs_curev2.  Adjust = BH
## Limma step 6/6: 9/15: Creating table: failurev3_vs_curev2.  Adjust = BH
## Limma step 6/6: 10/15: Creating table: failurev1_vs_curev3.  Adjust = BH
## Limma step 6/6: 11/15: Creating table: failurev2_vs_curev3.  Adjust = BH
## Limma step 6/6: 12/15: Creating table: failurev3_vs_curev3.  Adjust = BH
## Limma step 6/6: 13/15: Creating table: failurev2_vs_failurev1.  Adjust = BH
## Limma step 6/6: 14/15: Creating table: failurev3_vs_failurev1.  Adjust = BH
## Limma step 6/6: 15/15: Creating table: failurev3_vs_failurev2.  Adjust = BH
## Limma step 6/6: 1/6: Creating table: curev1.  Adjust = BH
## Limma step 6/6: 2/6: Creating table: curev2.  Adjust = BH
## Limma step 6/6: 3/6: Creating table: curev3.  Adjust = BH
## Limma step 6/6: 4/6: Creating table: failurev1.  Adjust = BH
## Limma step 6/6: 5/6: Creating table: failurev2.  Adjust = BH
## Limma step 6/6: 6/6: Creating table: failurev3.  Adjust = BH
## The factor cure_v1 has 5 rows.
## The factor cure_v2 has 5 rows.
## The factor cure_v3 has 5 rows.
## The factor failure_v1 has 6 rows.
## The factor failure_v2 has 7 rows.
## The factor failure_v3 has 6 rows.
## Testing each factor against the others.
## Scoring cure_v1 against everything else.
## Scoring cure_v2 against everything else.
## Scoring cure_v3 against everything else.
## Scoring failure_v1 against everything else.
## Scoring failure_v2 against everything else.
## Scoring failure_v3 against everything else.
## Deleting the file excel/wellcome_gsva_c7.xlsx before writing the tables.
outtime_gprofiler <- all_gprofiler(outtime_sva_sig)
outtime_gprofiler$curev1v2_up$pvalue_plots$bpp_plot_over
## NULL
outtime_gprofiler$failv1v2_up$pvalue_plots$kegg_plot_over
## NULL
outtime_gprofiler$cfv1_up$pvalue_plots$reactome_plot_over
## NULL
outtime_gprofiler$cfv1_down$pvalue_plots$reactome_plot_over
## NULL
LS0tCnRpdGxlOiAiV2VsbGNvbWUgdG8gTGluYSdzIFJOQVNlcSBhbmFseXNlczogMjAyMjA5IgphdXRob3I6ICJOYWppYiBFbC1TYXllZCIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB6ZW5idXJuCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogZm9udC1zaXplOiAxNnB4Cn0KYm9keSAubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTYwMHB4Owp9Cjwvc3R5bGU+CgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShnbHVlKQpsaWJyYXJ5KGhwZ2x0b29scykKdHQgPC0gc20oZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpKQprbml0cjo6b3B0c19rbml0JHNldCgKICBwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCB3aWR0aCA9IDkwLCBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVycm9yID0gVFJVRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDgsIGZpZy5yZXRpbmEgPSAyLAogIGZpZy5wb3MgPSAidCIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBkcGkgPSBpZiAoa25pdHI6OmlzX2xhdGV4X291dHB1dCgpKSA3MiBlbHNlIDMwMCwKICBvdXQud2lkdGggPSAiMTAwJSIsIGRldiA9ICJwbmciLAogIGRldi5hcmdzID0gbGlzdChwbmcgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpKQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cyA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemUgPSAxMikpCnZlciA8LSAiMjAyMzA1IgpwcmV2aW91c19maWxlIDwtICIiCnZlciA8LSBmb3JtYXQoU3lzLkRhdGUoKSwgIiVZJW0lZCIpCnJtZF9maWxlIDwtIGdsdWUoIndlbGxjb21lX3t2ZXJ9LlJtZCIpCmBgYAoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgd29ya3NoZWV0IGF0dGVtcHRzIHRvIGRlc2NyaWJlIHNvbWUgYW5hbHlzZXMgcGVyZm9ybWVkIGFzIHBhcnQgb2YKIkNvbnNvbGlkYXRpb24gb2YgYSBtb2xlY3VsYXIgYW5kIGNsaW5pY2FsIHNpZ25hdHVyZSBvZiBoZWFsaW5nIGluCmN1dGFuZW91cyBsZWlzaG1hbmlhc2lzIGlzIGFjaGlldmVkIGR1cmluZyB0aGUgZmlyc3QgdGVuIGRheXMgb2YKdHJlYXRtZW50LiIKClRoaXMgZGF0YXNldCBjb21wcmlzZXMgMzYgc2FtcGxlcyBhY3Jvc3MgMTIgcGF0aWVudCBiaW9wc2llcyB3aXRoCnZhcnlpbmcgZHJ1ZyB0cmVhdG1lbnQgKEFudGltb25pYWwgdnMuIE1pbHRlZm9zaW5lKSwgY2xpbmljIHZpc2l0CihwcmUtdHJlYXRtZW50LCBtaWQgdHJlYXRtZW50LCBlbmQgb2YgdHJlYXRtZW50KSwgQ3VyZS9GYWlsLCBhbmQKaW5mZWN0aW5nIHBhcmFzaXRlLgoKVGhpcyBkYXRhc2V0IHdhcyBpbml0aWFsbHkgYW5hbHl6ZWQgYnkgTmFqaWIgYXMgcGFydCBvZiBoaXMgZ29hbCB0bwpsZWFybiBSIGFuZCBnZXQgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiBob3cgd2UgcHJvY2VzcyBkYXRhLiAgQXMgYQpyZXN1bHQgSSBkaWQgbm90IHZlcnkgY2xvc2VseSBleGFtaW5lIHRoZSBkYXRhLiAgR2l2ZW4gdGhhdCB3ZSBhcmUKbGlrZWx5IHRvIHB1Ymxpc2ggdGhpcyBkYXRhIHNvb24sIHRoYXQgc2hvdWxkIGJlIGFkZHJlc3NlZC4KCmBgYHtyIHNhbXBsZXNoZWV0fQpzYW1wbGVzaGVldCA8LSAic2FtcGxlX3NoZWV0cy93ZWxsY29tZV90cnVzdF9zYW1wbGVzLXYyMDIyMDkueGxzeCIKCnJuYV9zcGVjIDwtIG1ha2Vfcm5hc2VxX3NwZWMoKQptb2RpZmllZCA8LSBnYXRoZXJfcHJlcHJvY2Vzc2luZ19tZXRhZGF0YShzYW1wbGVzaGVldCwgc3BlY2lmaWNhdGlvbiA9IHJuYV9zcGVjLCBzcGVjaWVzID0gImhnMzhfMTAwIikKYGBgCgojIEFubm90YXRpb24KCldlIHRha2UgdGhlIGFubm90YXRpb24gZGF0YSBmcm9tIGVuc2VtYmwncyBiaW9tYXJ0IGluc3RhbmNlLiAgVGhlIGdlbm9tZSB3aGljaAp3YXMgdXNlZCB0byBtYXAgdGhlIGRhdGEgd2FzIGhnMzggcmV2aXNpb24gMTAwLiAgTXkgZGVmYXVsdCB3aGVuIHVzaW5nIGJpb21hcnQgaXMKdG8gbG9hZCB0aGUgZGF0YSBmcm9tIDEgeWVhciBiZWZvcmUgdGhlIGN1cnJlbnQgZGF0ZS4KCmBgYHtyIGhzX2Fubm90fQpoc19hbm5vdCA8LSBsb2FkX2Jpb21hcnRfYW5ub3RhdGlvbnMoeWVhciA9ICIyMDE5IilbWyJhbm5vdGF0aW9uIl1dCmhzX2Fubm90W1sidHJhbnNjcmlwdCJdXSA8LSBwYXN0ZTAocm93bmFtZXMoaHNfYW5ub3QpLCAiLiIsIGhzX2Fubm90W1sidmVyc2lvbiJdXSkKcm93bmFtZXMoaHNfYW5ub3QpIDwtIG1ha2UubmFtZXMoaHNfYW5ub3RbWyJlbnNlbWJsX2dlbmVfaWQiXV0sIHVuaXF1ZSA9IFRSVUUpCnR4X2dlbmVfbWFwIDwtIGhzX2Fubm90WywgYygidHJhbnNjcmlwdCIsICJlbnNlbWJsX2dlbmVfaWQiKV0KCnN1bW1hcnkoaHNfYW5ub3QpCmBgYAoKIyMgR2VuZSBPbnRvbG9neSBkYXRhCgpgYGB7ciBoc19nb30KaHNfZ28gPC0gbG9hZF9iaW9tYXJ0X2dvKClbWyJnbyJdXQpoc19sZW5ndGggPC0gaHNfYW5ub3RbLCBjKCJlbnNlbWJsX2dlbmVfaWQiLCAiY2RzX2xlbmd0aCIpXQpjb2xuYW1lcyhoc19sZW5ndGgpIDwtIGMoIklEIiwgImxlbmd0aCIpCmBgYAoKIyBDcmVhdGUgZXhwcmVzc2lvbnNldHMKClN0YXJ0IG91dCBieSBjcmVhdGluZyBhIGZldyBkYXRhc3RydWN0dXJlcyB3aGljaCBkZWZpbmUgdGhlIHByaW1hcnkKcXVlc3Rpb25zIGluIHRoZSBkYXRhLgoKIyMgQ29sb3IgY2hvaWNlcwoKSSBhbSBnb2luZyB0byBncmFiIGNvbG9ycyBmcm9tIHRoZSBUTVJDMyBkYXRhIHdpdGggdGhlIGFzc3VtcHRpb24gdGhhdAp0aGVyZSBhcmUgZ29vZCBjaG9pY2VzIHRoZXJlLgoKYGBge3IgY29sb3JfY2hvaWNlc30KY29sb3JfY2hvaWNlcyA8LSBsaXN0KAogICJjZl92aXNpdCIgPSBsaXN0KAogICAgImN1cmVfdjEiID0gIiNEOTVGMEUiLAogICAgImZhaWx1cmVfdjEiID0gIiNGRUM0NEYiLAogICAgImN1cmVfdjIiID0gIiNERDFDNzciLAogICAgImZhaWx1cmVfdjIiID0gIiNDOTk0QzciLAogICAgImN1cmVfdjMiID0gIiMzMTgyQkQiLAogICAgImZhaWx1cmVfdjMiID0gIiM5RUNBRTEiKSwKICAiY2YiID0gbGlzdCgKICAgICJjdXJlIiA9ICIjOTk4RUMzIiwKICAgICJmYWlsdXJlIiA9ICIjRjFBMzQwIiksCiAgInZpc2l0IiA9IGxpc3QoCiAgICAidjEiID0gIiMzM0VFMzMiLAogICAgInYyIiA9ICIjMTFBQTExIiwKICAgICJ2MyIgPSAiIzEzNDQxMyIpLAogICJ2aXNpdGJpIiA9IGxpc3QoCiAgICAidjEiID0gIiNCQjAwMDAiLAogICAgInZvdGhlciIgPSAiIzAwMDBCQiIpLAogICJzcGVjaWVzIiA9IGxpc3QoCiAgICAibHZwYW5hbWVuc2lzIiA9ICIjRkZDMzAwIiwKICAgICJsdmJyYXppbGllbnNpcyIgPSAiIzUyNTI1MiIpLAogICJkb25vciIgPSBsaXN0KAogICAgImQyMDA4IiA9ICIjQjc4NDE1IiwKICAgICJkMTAyOSIgPSAiIzkzNzUyQyIsCiAgICAiZDEwMzYiID0gIiM3RTZFQTIiLAogICAgImQxMDM3IiA9ICIjQjM0OTlDIiwKICAgICJkMTAzMSIgPSAiI0JENjMzMiIsCiAgICAiZDIwMDIiID0gIiM3RDhGMzEiLAogICAgImQyMDA5IiA9ICIjOEU3MDM3IiwKICAgICJkMjAxMCIgPSAiIzY2NjY2NiIsCiAgICAiZDEwMTkiID0gIiMxQjlFNzciLAogICAgImQyMDA0IiA9ICIjRTBBNjA0IiwKICAgICJkMjAwMSIgPSAgIiNDRjNGNzYiLAogICAgImQyMDAzIiA9ICIjQTBBODExIiksCiAgImRydWciID0gbGlzdCgKICAgICJhbnRpbW9uaWF0ZSIgPSAiIzMxODJBQSIsCiAgICAibWlsdGVmb3NpbmUiID0gIiNDOTk0QUEiKSkKYGBgCgpUaGUgc2V0IG9mIGNvbG9yIGNob2ljZXMgZGVtb25zdHJhdGVzIHRoZSBjb21wbGV4aXR5IG9mIHRoZQpleHBlcmltZW50YWwgZGVzaWduLiAgV2UgYXJlIGxvb2tpbmcgYXQgY29tYmluYXRpb25zIG9mIHRpbWUsIG91dGNvbWUsCnNwZWNpZXMsIGFuZCBkcnVnLiAgSW5oZXJlbnQgaW4gdGhlc2UgaXMgYW4gdW5zcGVjaWZpZWQgZG9ub3IgZWZmZWN0LgoKIyMgSW5pdGlhbCBkYXRhc2V0OiBDb21iaW5lIGNsaW5pY2FsIG91dGNvbWUgd2l0aCB2aXNpdAoKVGhlIGluaXRpYWwgZGF0YXN0cnVjdHVyZSB3aWxsIHVzZSBhIGZhY3RvciBjb21iaW5pbmcgdGhlIGNsaW5pY2FsCm91dGNvbWUgYW5kIHZpc2l0IGFzIHRoZSBleHBlcmltZW50YWwgY29uZGl0aW9uIG9mIGludGVyZXN0LiAgV2Ugd2lsbApmb2xsb3cgdGhpcyB1cCBieSBzcGxpdHRpbmcgb2ZmIHRoZSB2YXJpb3VzIGZhY3RvcnMgb2YgaW50ZXJlc3QuCgpgYGB7ciBleHB0fQp3ZWxsY29tZV9vdXR0aW1lIDwtIGNyZWF0ZV9leHB0KG1ldGFkYXRhID0gc2FtcGxlc2hlZXQsIGdlbmVfaW5mbyA9IGhzX2Fubm90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uID0gImhnMzgxMDBoaXNhdGZpbGUiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiZHJ1ZyIpICU+JQogIHNhbml0aXplX21ldGFkYXRhKHNwYWNlcyA9IFRSVUUpCm91dGNvbWVfdGltZSA8LSBwYXN0ZTAocERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJjbGluaWNhbG91dGNvbWUiXV0sICJfdiIsCiAgICAgICAgICAgICAgICAgICAgICAgcERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJ2aXNpdG51bWJlciJdXSkKd2VsbGNvbWVfb3V0dGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSBvdXRjb21lX3RpbWUpICU+JQogIHNldF9leHB0X2NvbG9ycyhjb2xvcl9jaG9pY2VzW1siY2ZfdmlzaXQiXV0pCnBEYXRhKHdlbGxjb21lX291dHRpbWUpW1sidmlzaXRudW1iZXIiXV0gPC0gcGFzdGUwKCJ2IiwgcERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJ2aXNpdG51bWJlciJdXSkKYGBgCgojIyBDaGVjayBzYW1wbGVzCgpGaXJzdCwgbGV0IHVzIGdldCBhIHF1aWNrIHZpZXcgb2YgdGhlIHNhbXBsZXMgaW4gdGhlaXIgbmF0aXZlIHN0YXRlLgpUaGVyZSBhcmUgYSBmZXcgc2FtcGxlcyB3aGljaCBhcmUgY2FuZGlkYXRlcyBmb3IgcmVtb3ZhbCBkdWUgdG8gbG93ZXIKY292ZXJhZ2UuCgpgYGB7ciBjaGVja193ZWxsY29tZX0KbGVnZW5kIDwtIHBsb3RfbGVnZW5kKHdlbGxjb21lX291dHRpbWUpCmxlZ2VuZCRwbG90CnBsb3RfbGlic2l6ZSh3ZWxsY29tZV9vdXR0aW1lKQpwbG90X25vbnplcm8od2VsbGNvbWVfb3V0dGltZSwgcGxvdF9sYWJlbHMgPSAicmVwZWwiKQoKd2VsbGNvbWVfZmlsdGVyZWQgPC0gc3Vic2V0X2V4cHQod2VsbGNvbWVfb3V0dGltZSwgbm9uemVybyA9IDE1MDAwKQpgYGAKCkxvb2tpbmcgYXQgdGhlIG5vbnplcm8gcGxvdCwgaXQgc2VlbXMgdGhhdCAxNWsgZ2VuZXMgaXMgYSByZWFzb25hYmxlCmN1dG9mZiwgd2hpY2ggd291bGQgcmVtb3ZlIDIgc2FtcGxlcy4gIFNvLCBmb3IgdGhlIG1vbWVudCBJIHdpbGwgc3BsaXQKdGhlIGRhdGEgdXAgaW50byB0d28gc2V0cywgcHJlL3Bvc3QgcmVtb3ZhbC4KCiMjIE9ubHkgZG9ub3IKCkdpdmVuIHRoYXQgd2UgZG9uJ3QgaGF2ZSBlbm91Z2ggc2FtcGxlcyBmb3IgYSBmdWxsIHJhbmsgbWF0cml4IG9mCmRvbm9yL2RydWcvdGltZS9jZiwgSSBhbSBnb2luZyB0byBjcmVhdGUgc2VwYXJhdGUgZGF0YSBzdHJ1Y3R1cmVzCndoZXJlIGVhY2ggaW5kaXZpZHVhbCBmYWN0b3IgaXMgdGhlIGNvbmRpdGlvbiwgc3RhcnRpbmcgd2l0aCBkb25vci4KCmBgYHtyIGV4cHRfZG9ub3J9CndlbGxjb21lX2Rvbm9yIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJkb25vciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlcykKCndlbGxjb21lX2ZpbHRkb25vciA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX2ZpbHRlcmVkLCBmYWN0ID0gImRvbm9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnMgPSBjb2xvcl9jaG9pY2VzKQpgYGAKCiMjIE9ubHkgdmlzaXQKCkluIHRoaXMgY2FzZSwgdGhlIGNvbmRpdGlvbiB3aWxsIG9ubHkgYmUgdmlzaXQgbnVtYmVyLgoKYGBge3IgZXhwdF92aXNpdH0Kd2VsbGNvbWVfdGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSAidmlzaXRudW1iZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbInZpc2l0Il1dKQoKd2VsbGNvbWVfZmlsdHRpbWUgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh3ZWxsY29tZV9maWx0ZXJlZCwgZmFjdCA9ICJ2aXNpdG51bWJlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbInZpc2l0Il1dKQpgYGAKCiMjIE9ubHkgQ3VyZS9GYWlsCgpDb252ZXJzZWx5LCB3ZSBjYW4gc3BsaXQgYnkgY2xpbmljYWwgb3V0Y29tZS4KCmBgYHtyIGNmfQp3ZWxsY29tZV9vdXRjb21lIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbImNmIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQoKd2VsbGNvbWVfb3V0Y29tZV9maWx0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfZmlsdGVyZWQsIGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXNbWyJjZiJdXSkgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gInZpc2l0bnVtYmVyIikKYGBgCgojIyBPbmx5IGRydWcKCi4uLiBvciBkcnVnIHVzZWQuCgpgYGB7ciBkcnVnfQp3ZWxsY29tZV9kcnVnIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJkcnVnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXNbWyJkcnVnIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQoKd2VsbGNvbWVfZHJ1Z2ZpbHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyh3ZWxsY29tZV9maWx0ZXJlZCwgZmFjdCA9ICJkcnVnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXNbWyJkcnVnIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQpgYGAKCiMjIE9ubHkgcGFyYXNpdGUKCi4uLiBhbmQgdGhlIGluZmVjdGluZyBwYXJhc2l0ZS4KCmBgYHtyIHBhcmFzaXRlfQp3ZWxsY29tZV9wYXJhc2l0ZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSAiaW5mZWN0aW5nc3BlY2llcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gY29sb3JfY2hvaWNlc1tbInNwZWNpZXMiXV0pICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ2aXNpdG51bWJlciIpCgp3ZWxsY29tZV9wYXJhZmlsdCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX2ZpbHRlcmVkLCBmYWN0ID0gImluZmVjdGluZ3NwZWNpZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IGNvbG9yX2Nob2ljZXNbWyJzcGVjaWVzIl1dKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQpgYGAKCiMjIFZpc3VhbGl6ZSB0aGUgbWV0YWRhdGEKCmBgYHtyIG1ldGFfc2Fua2V5fQpkcnVnX3Zpc2l0X3NwZWNpZXNfY2YgPC0gcGxvdF9tZXRhX3NhbmtleSgKICB3ZWxsY29tZV9vdXR0aW1lLCBmYWN0b3JzID0gYygiZHJ1ZyIsICJ2aXNpdG51bWJlciIsICJpbmZlY3RpbmdzcGVjaWVzIiwgImNsaW5pY2Fsb3V0Y29tZSIpLAogIGNvbG9yX2Nob2ljZXMgPSBjb2xvcl9jaG9pY2VzKQpkcnVnX3Zpc2l0X3NwZWNpZXNfY2YKYGBgCgpOb3RlIHRoYXQgdGhlcmUgZG8gbm90IGFwcGVhciB0byBiZSBhbnkgbWlsdGVmb3NpbmUsIGJyYXppbGllbnNpcywgZmFpbHMuCgojIFZpc3VhbGl6ZSBzYW1wbGVzCgpHaXZlbiB0aGUgbGFyZ2UgbnVtYmVyIG9mIHZhcmlhYmxlcyBpbiB0aGlzIGRhdGEsIGxldHMgc3RhcnQgYnkKZ2V0dGluZyBhIGZlZWxpbmcgZm9yIHRoZSBhbW91bnQgb2YgdmFyaWFuY2UgaW4gZWFjaC4gIEdpdmVuIHRoYXQgd2UKZG9uJ3QgaGF2ZSBhIGZ1bGwgcmFuayB3aXRoIHJlc3BlY3QgdG8gY2xpbmljYWwgb3V0Y29tZSwgSSBhc3N1bWUgdGhhdAp0cnlpbmcgdmFyaWFuY2UgcGFydGl0aW9uIHdpdGggdGhlIDQgcHJpbWFyeSBmYWN0b3JzIHdpbGwgZmFpbCwgYnV0CmxldCB1cyBzZWUuLi4KCmBgYHtyIHZhcnBhcnR9CmFsbF92YXJwYXJ0X2Rvbm9yIDwtIHNpbXBsZV92YXJwYXJ0KAogIHdlbGxjb21lX2ZpbHRlcmVkLAogIGZhY3RvcnMgPSBjKCJkb25vciIsICJ2aXNpdG51bWJlciIpKQphbGxfdmFycGFydF9kb25vcgoKYWxsX3ZhcnBhcnRfZHZpYyA8LSBzaW1wbGVfdmFycGFydCgKICB3ZWxsY29tZV9maWx0ZXJlZCwKICBmYWN0b3JzID0gYygiZHJ1ZyIsICJ2aXNpdG51bWJlciIsICJpbmZlY3RpbmdzcGVjaWVzIiwgImNsaW5pY2Fsb3V0Y29tZSIpKQphbGxfdmFycGFydF9kdmljCmBgYAoKVG8gbXkgZXllcywgaXQgYXBwZWFycyB0aGF0IGRvbm9yIGlzIGRvbWluYW50IGZhY3RvciwKZm9sbG93ZWQgYnk6IHZpc2l0LCBzcGVjaWVzLCBkcnVnLCBhbmQgb3V0Y29tZS4gIEkgdGhpbmsgdGhpcwpvYnNlcnZhdGlvbiBtYXkgaGF2ZSBhbiBlZmZlY3Qgb24gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlCm1hbnVzY3JpcHQgLSB3aGljaCBpZiBJIHJlY2FsbCBwcm9wZXJseSBzdGF0ZXMgdGhhdCBkb25vciBpcyBub3QgYQpzaWduaWZpY2FudCBmYWN0b3IgaW4gdGhlIGRhdGEuCgojIyBFeGFtaW5lIHRvcC1uIGdlbmVzIHdpdGggcmVzcGVjdCB0byB2YXJpYW5jZSBvZiBzb21lIGZhY3RvcnMKCkxldCB1cyBhc2sgaWYgdGhlcmUgYXJlIGNhdGVnb3JpZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBnZW5lcwphc3NvY2lhdGVkIHdpdGggZWFjaCBvZiB0aGVzZSBjYXRlZ29yaWVzIGFuZCBzZWUgaWYgdGhleSAnbWFrZSBzZW5zZScuCgpgYGB7ciB0b3BuX2ZhY3RvcnN9CnRvcF8zMDBfZG9ub3JfZ2VuZXNfaWR4IDwtIG9yZGVyKGFsbF92YXJwYXJ0X2Rvbm9yW1siZml0dGVkX2RmIl1dW1siZG9ub3IiXV0pCnRvcF8zMDBfZG9ub3JfZ2VuZXMgPC0gdGFpbChhbGxfdmFycGFydF9kb25vcltbImZpdHRlZF9kZiJdXVt0b3BfMzAwX2Rvbm9yX2dlbmVzX2lkeCwgXSwgbiA9IDMwMCkKc3VtbWFyeSh0b3BfMzAwX2Rvbm9yX2dlbmVzKQpkb25vcl9nZW5lc19ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHJvd25hbWVzKHRvcF8zMDBfZG9ub3JfZ2VuZXMpKQpkb25vcl9nZW5lc19ncAoKdG9wXzMwMF92aXNpdF9nZW5lc19pZHggPC0gb3JkZXIoYWxsX3ZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVtbInZpc2l0bnVtYmVyIl1dKQp0b3BfMzAwX3Zpc2l0X2dlbmVzIDwtIHRhaWwoYWxsX3ZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVt0b3BfMzAwX3Zpc2l0X2dlbmVzX2lkeCwgXSwgbiA9IDMwMCkKc3VtbWFyeSh0b3BfMzAwX3Zpc2l0X2dlbmVzKQp2aXNpdF9nZW5lc19ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHJvd25hbWVzKHRvcF8zMDBfdmlzaXRfZ2VuZXMpKQp2aXNpdF9nZW5lc19ncAoKdG9wXzMwMF9kcnVnX2dlbmVzX2lkeCA8LSBvcmRlcihhbGxfdmFycGFydF9kdmljW1siZml0dGVkX2RmIl1dW1siZHJ1ZyJdXSkKdG9wXzMwMF9kcnVnX2dlbmVzIDwtIHRhaWwoYWxsX3ZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVt0b3BfMzAwX2RydWdfZ2VuZXNfaWR4LCBdLCBuID0gMzAwKQpzdW1tYXJ5KHRvcF8zMDBfZHJ1Z19nZW5lcykKZHJ1Z19nZW5lc19ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHJvd25hbWVzKHRvcF8zMDBfZHJ1Z19nZW5lcykpCmRydWdfZ2VuZXNfZ3AKCnRvcF8zMDBfc3BlY2llc19nZW5lc19pZHggPC0gb3JkZXIoYWxsX3ZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVtbImluZmVjdGluZ3NwZWNpZXMiXV0pCnRvcF8zMDBfc3BlY2llc19nZW5lcyA8LSB0YWlsKGFsbF92YXJwYXJ0X2R2aWNbWyJmaXR0ZWRfZGYiXV1bdG9wXzMwMF9zcGVjaWVzX2dlbmVzX2lkeCwgXSwgbiA9IDMwMCkKc3VtbWFyeSh0b3BfMzAwX3NwZWNpZXNfZ2VuZXMpCnNwZWNpZXNfZ2VuZXNfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihyb3duYW1lcyh0b3BfMzAwX3NwZWNpZXNfZ2VuZXMpKQpzcGVjaWVzX2dlbmVzX2dwCgp0b3BfMzAwX2NmX2dlbmVzX2lkeCA8LSBvcmRlcihhbGxfdmFycGFydF9kdmljW1siZml0dGVkX2RmIl1dW1siY2xpbmljYWxvdXRjb21lIl1dKQp0b3BfMzAwX2NmX2dlbmVzIDwtIHRhaWwoYWxsX3ZhcnBhcnRfZHZpY1tbImZpdHRlZF9kZiJdXVt0b3BfMzAwX2NmX2dlbmVzX2lkeCwgXSwgbiA9IDMwMCkKc3VtbWFyeSh0b3BfMzAwX2NmX2dlbmVzKQpjZl9nZW5lc19ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKHJvd25hbWVzKHRvcF8zMDBfY2ZfZ2VuZXMpKQpjZl9nZW5lc19ncApgYGAKCiMgVGhlIHNhbXBsZXMnIGRpc3RyaWJ1dGlvbiBpcyBzaW1pbGFyIHdpdGhvdXQgMiBzYW1wbGVzCgpIZXJlIGFyZSB0aGUgUENBIHJlc3VsdHMgYmVmb3JlL2FmdGVyIHJlbW92aW5nIHRoZSB0d28gc2FtcGxlcyB0aGF0IEkKY2FsbGVkIHNoZW5hbmlnYW5zIG9uLiAgVGhleSBhcmUgcXVpdGUgc2ltaWxhci4KCmBgYHtyIHByZV9wb3N0X2ZpbHRlcl9wY2F9CndlbGxjb21lX291dHRpbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9vdXR0aW1lLCBmaWx0ZXIgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydCA9ICJjcG0iLCB0cmFuc2Zvcm0gPSAibG9nMiIsIG5vcm0gPSAicXVhbnQiKQpwbG90X3BjYSh3ZWxsY29tZV9vdXR0aW1lX25vcm0pCndlbGxjb21lX291dGZpbHRfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9maWx0ZXJlZCwgZmlsdGVyID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQgPSAiY3BtIiwgdHJhbnNmb3JtID0gImxvZzIiLCBub3JtID0gInF1YW50IikKcGxvdF9wY2Eod2VsbGNvbWVfb3V0ZmlsdF9ub3JtKQpgYGAKCiMgR1NWQQoKRnJvbSBteSBwZXJzcGVjdGl2ZSwgaXQgc2VlbXMgdGhhdCB0aGUgbW9zdCBpbnRlcmVzdGluZyBHU1ZBCmNvbXBhcmlzb24gaXMgdG8gbG9vayBmb3Igc2NvcmVzIGNoYW5naW5nIGJldHdlZW4gdGhlIGN1cmUgYW5kIGZhaWwgc2FtcGxlcy4KCmBgYHtyIGdzdmF9Cnd0X2dzdmEgPC0gc2ltcGxlX2dzdmEod2VsbGNvbWVfb3V0Y29tZV9maWx0KQp3dF9nc3ZhCgp3dF9nc3ZhX3NpZyA8LSBnZXRfc2lnX2dzdmFfY2F0ZWdvcmllcyh3dF9nc3ZhLCBleGNlbCA9ICJleGNlbC93ZWxsY29tZV9vdXRjb21lX2ZpbHRfZ3N2YS54bHN4IikKd3RfZ3N2YV9zaWcKYGBgCgojIFZpc3VhbGl6ZSBWYXJpb3VzIFBDQQoKIyMgQnkgdmlzaXQKCmBgYHtyIHdlbGxjb21lX3RpbWV9CndlbGxjb21lX3RpbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9maWx0dGltZSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfdGltZV9ub3JtKQoKd2VsbGNvbWVfdGltZV9uYiA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9maWx0dGltZSwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfdGltZV9uYikKYGBgCgojIyBDdXJlL0ZhaWwKCmBgYHtyIHdlbGxjb21lX291dGNvbWV2MX0Kd2VsbGNvbWVfb3V0Y29tZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX291dGNvbWVfZmlsdCwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfb3V0Y29tZV9ub3JtLCBwbG90X2xhYmVscz1GQUxTRSkKCndlbGxjb21lX291dGNvbWVfbmIgPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfb3V0Y29tZV9maWx0LCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9vdXRjb21lX25iKQpgYGAKCldvdywgdGhlcmUgcmVhbGx5IGlzbid0IG11Y2ggQy9GIHZhcmlhbmNlLCBpcyB0aGVyZS4KCiMjIERydWcKCmBgYHtyIHdlbGxjb21lX291dGNvbWV2Mn0Kd2VsbGNvbWVfZHJ1Z19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX2RydWdmaWx0LCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9kcnVnX25vcm0pCgp3ZWxsY29tZV9kcnVnX25iIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX2RydWdmaWx0LCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9kcnVnX25iKQpgYGAKCiMjIE91dGNvbWUgYW5kIHRpbWUKCmBgYHtyIHdlbGxjb21lX3Bsb3RzfQp3ZWxsY29tZV9vdXR0aW1lX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfZmlsdGVyZWQsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnBsb3RfcGNhKHdlbGxjb21lX291dHRpbWVfbm9ybSkKCndlbGxjb21lX291dHRpbWVfbmIgPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfZmlsdGVyZWQsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnBsb3RfcGNhKHdlbGxjb21lX291dHRpbWVfbmIpCmBgYAoKIyMgUGFyYXNpdGUgU3BlY2llcwoKYGBge3Igd2VsbGNvbWVfcGFyYXNpdGV9CndlbGxjb21lX3BhcmFzaXRlX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfcGFyYWZpbHQsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9wYXJhc2l0ZV9ub3JtKQoKd2VsbGNvbWVfcGFyYXNpdGVfbmIgPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfcGFyYWZpbHQsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9wYXJhc2l0ZV9uYikKYGBgCgojIERFIGFuYWx5c2VzCgpHaXZlbiB0aGUgYWJvdmUgdmFyaWFuY2UgcGFydGl0aW9uIGFuZCBQQ0EgcGxvdHMsIHdlIGNhbiBzdXJtaXNlIHRoYXQKc29tZSBtZXRhZGF0YSBmYWN0b3JzIGFyZSBtdWNoIG1vcmUgbGlrZWx5IHRvIGdpdmUgaW50ZXJlc3RpbmcgcmVzdWx0cwp0aGFuIG90aGVycyAoRHJ1ZyBmYXIgbW9yZSB0aGFuIEMvRiwgZm9yIGV4YW1wbGUpLiAgV2l0aCB0aGF0IGluIG1pbmQsCmxldCB1cyBwZXJmb3JtIHRoZSB2YXJpb3VzIHBvc3NpYmxlIERFIGFuYWx5c2VzIHdpdGggZWFjaApmYWN0b3IgYW5kIHNlZSB3aGF0IGNvbWVzIG91dC4gIEVhY2ggb2YgdGhlc2UgcnVucyBvZiBhbGwgcGFpcndpc2UKd2lsbCBiZSBwZXJmb3JtZWQgb25jZSB3aXRoIFNWQSBlc3RpbWF0ZXMgaW4gdGhlIG1vZGVsLCBhbmQgb25jZSB3aXRoCnRoZSBkcnVnIHRyZWF0bWVudCBhcyB0aGUgYmF0Y2ggZmFjdG9yLgoKIyMgT3V0Y29tZSBhbmQgdGltZQoKU3RhcnQgd2l0aCB0aGUgY29tYmluZWQgZmFjdG9yIG9mIHtvdXRjb21lfV97dmlzaXR9LiAgR2l2ZW4gdGhlIFBDQSwgSQpleHBlY3QgdG8gc2VlIGEgbGl0dGxlIGJpdCBvZiBpbmZvcm1hdGlvbiB3aXRoIGJhdGNoIGluIHRoZSBtb2RlbCwKb2RkbHkgbGVzcyBpbmZvcm1hdGlvbiB3aXRoIFNWQS4KCmBgYHtyIG91dHRpbWVfZGV2MX0Kb3V0dGltZV9zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2ZpbHRlcmVkLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpvdXR0aW1lX3N2YV9kZQpvdXR0aW1lX2tlZXBlcnMgPC0gbGlzdCgKICAgICJjdXJldjF2MiIgPSBjKCJjdXJldjIiLCAiY3VyZXYxIiksCiAgICAiY3VyZXYxdjMiID0gYygiY3VyZXYzIiwgImN1cmV2MSIpLAogICAgImN1cmV2MnYzIiA9IGMoImN1cmV2MyIsICJjdXJldjIiKSwKICAgICJmYWlsdjF2MiIgPSBjKCJmYWlsdXJldjIiLCAiZmFpbHVyZXYxIiksCiAgICAiZmFpbHYxdjMiID0gYygiZmFpbHVyZXYzIiwgImZhaWx1cmV2MSIpLAogICAgImZhaWx2MnYzIiA9IGMoImZhaWx1cmV2MyIsICJmYWlsdXJldjIiKSwKICAgICJjZnYxIiA9IGMoImZhaWx1cmV2MSIsICJjdXJldjEiKSwKICAgICJjZnYyIiA9IGMoImZhaWx1cmV2MiIsICJjdXJldjIiKSwKICAgICJjZnYzIiA9IGMoImZhaWx1cmV2MyIsICJjdXJldjMiKSkKb3V0dGltZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBvdXR0aW1lX3N2YV9kZSwKICAgIGtlZXBlcnMgPSBvdXR0aW1lX2tlZXBlcnMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX291dHRpbWVfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikpCm91dHRpbWVfc3ZhX3RhYmxlCm91dHRpbWVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogICAgb3V0dGltZV9zdmFfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX291dHRpbWVfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpvdXR0aW1lX3N2YV9zaWcKCm91dHRpbWVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2ZpbHRlcmVkLCBtb2RlbF9iYXRjaCA9IFRSVUUsIGZpbHRlciA9IFRSVUUpCm91dHRpbWVfYmF0Y2hfZGUKb3V0dGltZV9iYXRjaF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIG91dHRpbWVfYmF0Y2hfZGUsCiAgICBrZWVwZXJzID0gb3V0dGltZV9rZWVwZXJzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXR0aW1lX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCm91dHRpbWVfYmF0Y2hfdGFibGUKb3V0dGltZV9iYXRjaF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG91dHRpbWVfYmF0Y2hfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX291dHRpbWVfc2lnX2JhdGNoLXZ7dmVyfS54bHN4IikpCm91dHRpbWVfYmF0Y2hfc2lnCmBgYAoKIyMgT25seSB0aW1lCgpOb3cgbGV0IHVzIGNvbXBhcmUgdGhlIHRpbWUgcG9pbnRzLCB3aXRoIGFuZCB3aXRob3V0IFNWQS4KCmBgYHtyIG91dHRpbWVfZGV2Mn0KdGltZV9zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2ZpbHR0aW1lLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0aW1lX3N2YV9kZQp0aW1lX2tlZXBlcnMgPC0gbGlzdCgKICAgICJ2MXYyIiA9IGMoInYyIiwgInYxIiksCiAgICAidjF2MyIgPSBjKCJ2MyIsICJ2MSIpLAogICAgInYydjMiID0gYygidjMiLCAidjIiKSkKdGltZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB0aW1lX3N2YV9kZSwKICAgIGtlZXBlcnMgPSB0aW1lX2tlZXBlcnMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3RpbWVfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikpCnRpbWVfc3ZhX3RhYmxlCnRpbWVfc3ZhX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogICAgdGltZV9zdmFfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3RpbWVfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQp0aW1lX3N2YV9zaWcKCnRpbWVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX2ZpbHR0aW1lLCBtb2RlbF9iYXRjaCA9ICJiYXRjaHNlcSIsIGZpbHRlciA9IFRSVUUpCnRpbWVfYmF0Y2hfZGUKdGltZV9iYXRjaF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHRpbWVfYmF0Y2hfZGUsCiAgICBrZWVwZXJzID0gdGltZV9rZWVwZXJzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV90aW1lX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCnRpbWVfYmF0Y2hfdGFibGUKdGltZV9iYXRjaF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIHRpbWVfYmF0Y2hfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3RpbWVfYmF0Y2hfc3ZhLXZ7dmVyfS54bHN4IikpCnRpbWVfYmF0Y2hfc2lnCmBgYAoKIyMgU3RyYWluCgpUaGUgaW5mZWN0aW5nIHN0cmFpbiBJIHRoaW5rIHNob3VsZCBwcm92ZSBvbmUgb2YgdGhlIG1vcmUgaW50ZXJlc3RpbmcgY29tcGFyaXNvbnMuCgpgYGB7ciBkZV9vbmx5X3BhcmFzaXRlX3N0cmFpbn0KcGFyYXNpdGVfc3ZhX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV9wYXJhZmlsdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKcGFyYXNpdGVfc3ZhX2RlCnBhcmFzaXRlX3N2YV90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHBhcmFzaXRlX3N2YV9kZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfcGFyYXNpdGVfdGFibGVfc3ZhLXZ7dmVyfS54bHN4IikpCnBhcmFzaXRlX3N2YV90YWJsZQpwYXJhc2l0ZV9zdmFfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBwYXJhc2l0ZV9zdmFfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3BhcmFzaXRlX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKcGFyYXNpdGVfc3ZhX3NpZwoKcGFyYXNpdGVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX3BhcmFmaWx0LCBtb2RlbF9iYXRjaCA9ICJiYXRjaHNlcSIsIGZpbHRlciA9IFRSVUUpCnBhcmFzaXRlX2JhdGNoX2RlCnBhcmFzaXRlX2JhdGNoX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgcGFyYXNpdGVfYmF0Y2hfZGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3BhcmFzaXRlX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCnBhcmFzaXRlX2JhdGNoX3RhYmxlCnBhcmFzaXRlX2JhdGNoX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogICAgcGFyYXNpdGVfYmF0Y2hfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3BhcmFzaXRlX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKcGFyYXNpdGVfYmF0Y2hfc2lnCmBgYAoKIyMgT3V0Y29tZQoKYGBge3IgZGVfb25seV9vdXRjb21lfQpvdXRjb21lX3N2YV9kZSA8LSBhbGxfcGFpcndpc2Uod2VsbGNvbWVfb3V0Y29tZV9maWx0LCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpvdXRjb21lX3N2YV9kZQpvdXRjb21lX3N2YV90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIG91dGNvbWVfc3ZhX2RlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpKQpvdXRjb21lX3N2YV90YWJsZQpvdXRjb21lX3N2YV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG91dGNvbWVfc3ZhX3RhYmxlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKb3V0Y29tZV9zdmFfc2lnCgpvdXRjb21lX2JhdGNoX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV9vdXRjb21lX2ZpbHQsIG1vZGVsX2JhdGNoID0gImJhdGNoc2VxIiwgZmlsdGVyID0gVFJVRSkKb3V0Y29tZV9iYXRjaF9kZQpvdXRjb21lX2JhdGNoX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgb3V0Y29tZV9iYXRjaF9kZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfb3V0Y29tZV90YWJsZV9iYXRjaC12e3Zlcn0ueGxzeCIpKQpvdXRjb21lX2JhdGNoX3RhYmxlCm91dGNvbWVfYmF0Y2hfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBvdXRjb21lX2JhdGNoX3RhYmxlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKb3V0Y29tZV9iYXRjaF9zaWcKYGBgCgojIEFkZGl0aW9uYWwgR1NWQQoKYGBge3Igd2VsbGNvbWVfZ3N2YX0Kd2VsbGNvbWVfZ3N2YV9jMiA8LSBzaW1wbGVfZ3N2YSh3ZWxsY29tZV9maWx0ZXJlZCwgc2lnbmF0dXJlX2NhdGVnb3J5PSJjMiIpCndlbGxjb21lX2dzdmFfYzJfc2lnIDwtIGdldF9zaWdfZ3N2YV9jYXRlZ29yaWVzKAogICAgd2VsbGNvbWVfZ3N2YV9jMiwKICAgIGV4Y2VsPSJleGNlbC93ZWxsY29tZV9nc3ZhX2MyLnhsc3giKQoKd2VsbGNvbWVfZ3N2YV9jNyA8LSBzaW1wbGVfZ3N2YSh3ZWxsY29tZV9maWx0ZXJlZCwgc2lnbmF0dXJlX2NhdGVnb3J5PSJjNyIpCndlbGxjb21lX2dzdmFfYzdfc2lnIDwtIGdldF9zaWdfZ3N2YV9jYXRlZ29yaWVzKAogICAgd2VsbGNvbWVfZ3N2YV9jNywKICAgIGV4Y2VsPSJleGNlbC93ZWxsY29tZV9nc3ZhX2M3Lnhsc3giKQpgYGAKCmBgYHtyIHdlbGxjb21lX2dzZWF9Cm91dHRpbWVfZ3Byb2ZpbGVyIDwtIGFsbF9ncHJvZmlsZXIob3V0dGltZV9zdmFfc2lnKQpvdXR0aW1lX2dwcm9maWxlciRjdXJldjF2Ml91cCRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgpvdXR0aW1lX2dwcm9maWxlciRmYWlsdjF2Ml91cCRwdmFsdWVfcGxvdHMka2VnZ19wbG90X292ZXIKCm91dHRpbWVfZ3Byb2ZpbGVyJGNmdjFfdXAkcHZhbHVlX3Bsb3RzJHJlYWN0b21lX3Bsb3Rfb3ZlcgpvdXR0aW1lX2dwcm9maWxlciRjZnYxX2Rvd24kcHZhbHVlX3Bsb3RzJHJlYWN0b21lX3Bsb3Rfb3ZlcgpgYGAK