1 Examining some Wellcome Trust data with Lina

In the moment of writing this text, my brain cannot recall which set of samples these are. I remember primarily that Najib wished to use these to learn more about how I handle the data and through it, to learn some of the methods himself. In terms of the experimental goals and details, that is precious little. I presume though, that the sample sheet will teach me some useful and important details.

These are a group of Cure/Fail Biopsy samples across three visits, some used an antimonial drug while others used miltefosine. All samples except one were done on the same day, but sequenced across a few iterations with a relatively wide range of sequencing depths. There are a couple of samples which have not had their read numbers/mapping rates collected into the sample sheet.

TMRC30126 and TMRC30129

I see that I ran mappings against panamensis, but those do not appear to be in the sample sheet. Do we wish to look at the parasites?

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

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
##  Length:226754         Length:226754      Min.   : 1.0   Min.   : 1.00     
##  Class :character      Class :character   1st Qu.: 6.0   1st Qu.: 1.00     
##  Mode  :character      Mode  :character   Median :12.0   Median : 1.00     
##                                           Mean   :10.5   Mean   : 3.07     
##                                           3rd Qu.:15.0   3rd Qu.: 5.00     
##                                           Max.   :26.0   Max.   :17.00     
##                                                                            
##  hgnc_symbol        description        gene_biotype         cds_length    
##  Length:226754      Length:226754      Length:226754      Min.   :     3  
##  Class :character   Class :character   Class :character   1st Qu.:   357  
##  Mode  :character   Mode  :character   Mode  :character   Median :   690  
##                                                           Mean   :  1134  
##                                                           3rd Qu.:  1440  
##                                                           Max.   :107976  
##                                                           NA's   :126871  
##  chromosome_name       strand          start_position      end_position     
##  Length:226754      Length:226754      Min.   :5.77e+02   Min.   :6.47e+02  
##  Class :character   Class :character   1st Qu.:3.11e+07   1st Qu.:3.12e+07  
##  Mode  :character   Mode  :character   Median :6.04e+07   Median :6.05e+07  
##                                        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  
##                                                                             
##   transcript       
##  Length:226754     
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 
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")
wellcome_outtime <- create_expt(metadata = samplesheet, gene_info = hs_annot,
                             file_column = "hg38100hisatfile") %>%
  set_expt_batches(fact = "drug")
## Reading the sample metadata.
## The sample definitions comprises: 36 rows(samples) and 47 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.
outcome_time <- paste0(pData(wellcome_outtime)[["clinicaloutcome"]], "_v",
                       pData(wellcome_outtime)[["visitnumber"]])
wellcome_outtime <- set_expt_conditions(wellcome_outtime, fact = outcome_time)

wellcome_time <- set_expt_conditions(wellcome_outtime, fact = "visitnumber")
pData(wellcome_time)[["condition"]] <- paste0("t", pData(wellcome_time)[["condition"]])

wellcome_outcome <- set_expt_conditions(wellcome_outtime, fact = "clinicaloutcome") %>%
  set_expt_batches(fact = "visitnumber")
pData(wellcome_outcome)[["batch"]] <- paste0("t", pData(wellcome_outcome)[["batch"]])

wellcome_drug <- set_expt_conditions(wellcome_outtime, fact = "drug") %>%
  set_expt_batches(fact = "visitnumber")
pData(wellcome_drug)[["batch"]] <- paste0("t", pData(wellcome_drug)[["batch"]])

wellcome_parasite <- set_expt_conditions(wellcome_outtime, fact = "infectingspecie") %>%
  set_expt_batches(fact = "visitnumber")
pData(wellcome_outcome)[["batch"]] <- paste0("t", pData(wellcome_outcome)[["batch"]])

3 Wellcome plots

3.1 A few global metrics

plot_libsize(wellcome_time)$plot

plot_nonzero(wellcome_time)$plot
## 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.
## Warning: ggrepel: 15 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

plot_boxplot(wellcome_time)
## 174127 entries are 0.  We are on a log scale, adding 1 to the data.

3.2 By visit

wellcome_time_norm <- normalize_expt(wellcome_time, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7327 low-count genes (14154 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_time_norm, plot_labels=FALSE)$plot

wellcome_time_varpart <- simple_varpart(wellcome_time_norm)
## Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## The following object is masked from 'package:S4Vectors':
## 
##     expand
## 
## Total:112 s
wellcome_time_varpart$partition_plot

wellcome_time_nb <- normalize_expt(wellcome_time, norm = "quant", convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Warning in normalize_expt(wellcome_time, norm = "quant", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Removing 7327 low-count genes (14154 remaining).
## Setting 591 low elements to zero.
## transform_counts: Found 591 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_time_nb, plot_labels=FALSE)$plot

wellcome_time_nb_varpart <- simple_varpart(wellcome_time_nb)
## 
## Total:106 s
wellcome_time_nb_varpart$partition_plot

3.3 Cure/Fail

wellcome_outcome_norm <- normalize_expt(wellcome_outcome, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7327 low-count genes (14154 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outcome_norm, plot_labels=FALSE)$plot

wellcome_outcome_varpart <- simple_varpart(wellcome_outcome_norm)
## 
## Total:121 s
wellcome_outcome_varpart$partition_plot

wellcome_outcome_nb <- normalize_expt(wellcome_outcome, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Removing 7327 low-count genes (14154 remaining).
## Setting 1240 low elements to zero.
## transform_counts: Found 1240 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outcome_nb, plot_labels=FALSE)$plot

wellcome_outcome_nb_varpart <- simple_varpart(wellcome_outcome_nb)
## 
## Total:103 s
wellcome_outcome_nb_varpart$partition_plot

3.4 Drug

wellcome_drug_norm <- normalize_expt(wellcome_drug, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## Removing 7327 low-count genes (14154 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_drug_norm, plot_labels=FALSE)$plot

wellcome_drug_varpart <- simple_varpart(wellcome_drug_norm)
## 
## Total:102 s
wellcome_drug_varpart$partition_plot

wellcome_drug_nb <- normalize_expt(wellcome_drug, convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Removing 7327 low-count genes (14154 remaining).
## Setting 1263 low elements to zero.
## transform_counts: Found 1263 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_drug_nb, plot_labels=FALSE)$plot

wellcome_drug_nb_varpart <- simple_varpart(wellcome_drug_nb)
## 
## Total:105 s
wellcome_drug_nb_varpart$partition_plot

3.5 Outcome and time

wellcome_outtime_norm <- normalize_expt(wellcome_outtime, norm = "quant", convert = "cpm",
                                     filter = TRUE, transform = "log2")
## 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, plot_labels=FALSE)$plot

wellcome_outtime_varpart <- simple_varpart(wellcome_outtime_norm)
## 
## Total:108 s
wellcome_outtime_varpart$partition_plot

wellcome_outtime_nb <- normalize_expt(wellcome_outtime, norm = "quant", convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Warning in normalize_expt(wellcome_outtime, norm = "quant", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Removing 7327 low-count genes (14154 remaining).
## Setting 705 low elements to zero.
## transform_counts: Found 705 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_outtime_nb)$plot

wellcome_outtime_nb_varpart <- simple_varpart(wellcome_outtime_nb)
## 
## Total:108 s
wellcome_outtime_nb_varpart$partition_plot

3.6 Parasite Species

wellcome_parasite_norm <- normalize_expt(wellcome_parasite, norm = "quant", convert = "cpm",
                                         filter = TRUE, transform = "log2")
## Removing 7327 low-count genes (14154 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_parasite_norm, plot_labels=FALSE)$plot

wellcome_parasite_varpart <- simple_varpart(wellcome_parasite_norm)
## 
## Total:95 s
wellcome_parasite_varpart$partition_plot

wellcome_parasite_nb <- normalize_expt(wellcome_parasite, norm = "quant", convert = "cpm",
                                   batch = "svaseq", filter = TRUE, transform = "log2")
## Warning in normalize_expt(wellcome_parasite, norm = "quant", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Removing 7327 low-count genes (14154 remaining).
## Setting 630 low elements to zero.
## transform_counts: Found 630 values equal to 0, adding 1 to the matrix.
plot_pca(wellcome_parasite_nb)$plot

wellcome_parasite_nb_varpart <- simple_varpart(wellcome_parasite_nb)
## 
## Total:92 s
wellcome_parasite_nb_varpart$partition_plot

4 DE analyses

4.1 Outcome and time

TODO: Also do this without sva.

outtime_de <- all_pairwise(wellcome_outtime, model_batch = "svaseq", filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
##    Cure_v1    Cure_v2    Cure_v3 Failure_v1 Failure_v2 Failure_v3 
##          5          5          5          7          7          7
## This analysis will include surrogate estimates from: svaseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Removing 0 low-count genes (14154 remaining).
## Setting 1167 low elements to zero.
## transform_counts: Found 1167 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

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"))
outtime_table <- combine_de_tables(
    outtime_de,
    keepers = outtime_keepers,
    excel = glue::glue("excel/wellcome_outtime_table_sva-v{ver}.xlsx"))
outtime_sig <- extract_significant_genes(
    outtime_table,
    excel = glue::glue("excel/wellcome_outtime_sig_sva-v{ver}.xlsx"))

outtime_batch_de <- all_pairwise(wellcome_outtime, model_batch = TRUE, filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
##    Cure_v1    Cure_v2    Cure_v3 Failure_v1 Failure_v2 Failure_v3 
##          5          5          5          7          7          7
## This analysis will include a batch factor in the model comprised of:
## 
## Antimoniate Miltefosine 
##          18          18
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

outtime_batch_table <- combine_de_tables(
    outtime_batch_de,
    keepers = outtime_keepers,
    excel = glue::glue("excel/wellcome_outtime_table_batch-v{ver}.xlsx"))
outtime_sig <- extract_significant_genes(
    outtime_batch_table,
    excel = glue::glue("excel/wellcome_outtime_sig_batch-v{ver}.xlsx"))
time_de <- all_pairwise(wellcome_time, model_batch = "svaseq", filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
## t1 t2 t3 
## 12 12 12
## This analysis will include surrogate estimates from: svaseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Removing 0 low-count genes (14154 remaining).
## Setting 1125 low elements to zero.
## transform_counts: Found 1125 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

time_keepers <- list(
    "v1v2" = c("t2", "t1"),
    "v1v3" = c("t3", "t1"),
    "v2v3" = c("t3", "t2"))
time_sva_table <- combine_de_tables(
    time_de,
    keepers = time_keepers,
    excel = glue::glue("excel/wellcome_time_table_sva-v{ver}.xlsx"))
time_sva_sig <- extract_significant_genes(
    time_sva_table,
    excel = glue::glue("excel/wellcome_time_sig_sva-v{ver}.xlsx"))

4.2 Outcome

parasite_sva_de <- all_pairwise(wellcome_parasite, model_batch = "svaseq", filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
## L. V. braziliensis   L. V. panamensis 
##                 12                 24
## This analysis will include surrogate estimates from: svaseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Removing 0 low-count genes (14154 remaining).
## Setting 1256 low elements to zero.
## transform_counts: Found 1256 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
parasite_sva_table <- combine_de_tables(
    parasite_sva_de,
    excel = glue::glue("excel/wellcome_parasite_table_sva-v{ver}.xlsx"))
parasite_sva_sig <- extract_significant_genes(
    parasite_sva_table,
    excel = glue::glue("excel/wellcome_parasite_sig_sva-v{ver}.xlsx"))

parasite_batch_de <- all_pairwise(wellcome_parasite, model_batch = "batchseq", filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
## L. V. braziliensis   L. V. panamensis 
##                 12                 24
## This analysis will include surrogate estimates from: batchseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  3
## Removing 0 low-count genes (14154 remaining).
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  6
## Setting 1256 low elements to zero.
## transform_counts: Found 1256 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
parasite_batch_table <- combine_de_tables(
    parasite_batch_de,
    excel = glue::glue("excel/wellcome_parasite_table_batch-v{ver}.xlsx"))
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-v202209.xlsx before writing the tables.

4.3 Parasite

## wellcome_outcome_norm <- normalize_expt(wellcome_outcome, norm = "quant", convert = "cpm",

outcome_sva_de <- all_pairwise(wellcome_outcome, model_batch = "svaseq", filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
##    Cure Failure 
##      15      21
## This analysis will include surrogate estimates from: svaseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## Removing 0 low-count genes (14154 remaining).
## Setting 1240 low elements to zero.
## transform_counts: Found 1240 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
outcome_sva_table <- combine_de_tables(
    outcome_sva_de,
    excel = glue::glue("excel/wellcome_outcome_table_sva-v{ver}.xlsx"))
outcome_sva_sig <- extract_significant_genes(
    outcome_sva_table,
    excel = glue::glue("excel/wellcome_outcome_sig_sva-v{ver}.xlsx"))

outcome_batch_de <- all_pairwise(wellcome_outcome, model_batch = "batchseq", filter = TRUE)
## This DE analysis will perform all pairwise comparisons among:
## 
##    Cure Failure 
##      15      21
## This analysis will include surrogate estimates from: batchseq.
## This will pre-filter the input data using normalize_expt's: TRUE argument.
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  2
## Removing 0 low-count genes (14154 remaining).
## sva warning: controls provided so supervised sva is being performed.
## Number of significant surrogate variables is:  6
## Setting 1245 low elements to zero.
## transform_counts: Found 1245 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
outcome_batch_table <- combine_de_tables(
    outcome_batch_de,
    excel = glue::glue("excel/wellcome_outcome_table_batch-v{ver}.xlsx"))
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-v202209.xlsx before writing the tables.
wellcome_gsva_c2 <- simple_gsva(wellcome_outcome, signature_category="c2")
## Converting the rownames() of the expressionset to ENTREZID.
## 1622 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 20013 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.
## Choosing the non-intercept containing 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 21 rows.
## Testing each factor against the others.
## Scoring Cure against everything else.
## Scoring Failure against everything else.
## Deleting the file excel/wellcome_gsva_c2.xlsx before writing the tables.
wellcome_gsva_c7 <- simple_gsva(wellcome_outcome, signature_category="c7")
## Converting the rownames() of the expressionset to ENTREZID.
## 1622 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 20013 entries.
wellcome_gsva_c7_sig <- get_sig_gsva_categories(
    wellcome_gsva,
    excel="excel/wellcome_gsva_c7.xlsx")
## Error in get_sig_gsva_categories(wellcome_gsva, excel = "excel/wellcome_gsva_c7.xlsx"): object 'wellcome_gsva' not found
LS0tCnRpdGxlOiAiV2VsbGNvbWUgdG8gTGluYSdzIFJOQVNlcSBhbmFseXNlczogMjAyMjA5IgphdXRob3I6ICJOYWppYiBFbC1TYXllZCIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiBodG1sX2RvY3VtZW50OgogIGNvZGVfZG93bmxvYWQ6IHRydWUKICBjb2RlX2ZvbGRpbmc6IHNob3cKICBmaWdfY2FwdGlvbjogdHJ1ZQogIGZpZ19oZWlnaHQ6IDcKICBmaWdfd2lkdGg6IDcKICBoaWdobGlnaHQ6IGRlZmF1bHQKICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiByZWFkYWJsZQogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgY29sbGFwc2VkOiBmYWxzZQogICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGhwZ2x0b29scykKdHQgPC0gc20oZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMikpCnZlciA8LSAiMjAyMjA5IgpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQ9IiVZJW0lZCIpCmBgYAoKIyBFeGFtaW5pbmcgc29tZSBXZWxsY29tZSBUcnVzdCBkYXRhIHdpdGggTGluYQoKSW4gdGhlIG1vbWVudCBvZiB3cml0aW5nIHRoaXMgdGV4dCwgbXkgYnJhaW4gY2Fubm90IHJlY2FsbCB3aGljaCBzZXQKb2Ygc2FtcGxlcyB0aGVzZSBhcmUuICBJIHJlbWVtYmVyIHByaW1hcmlseSB0aGF0IE5hamliIHdpc2hlZCB0byB1c2UKdGhlc2UgdG8gbGVhcm4gbW9yZSBhYm91dCBob3cgSSBoYW5kbGUgdGhlIGRhdGEgYW5kIHRocm91Z2ggaXQsIHRvCmxlYXJuIHNvbWUgb2YgdGhlIG1ldGhvZHMgaGltc2VsZi4gIEluIHRlcm1zIG9mIHRoZSBleHBlcmltZW50YWwgZ29hbHMKYW5kIGRldGFpbHMsIHRoYXQgaXMgcHJlY2lvdXMgbGl0dGxlLiAgSSBwcmVzdW1lIHRob3VnaCwgdGhhdCB0aGUKc2FtcGxlIHNoZWV0IHdpbGwgdGVhY2ggbWUgc29tZSB1c2VmdWwgYW5kIGltcG9ydGFudCBkZXRhaWxzLgoKVGhlc2UgYXJlIGEgZ3JvdXAgb2YgQ3VyZS9GYWlsIEJpb3BzeSBzYW1wbGVzIGFjcm9zcyB0aHJlZSB2aXNpdHMsCnNvbWUgdXNlZCBhbiBhbnRpbW9uaWFsIGRydWcgd2hpbGUgb3RoZXJzIHVzZWQgbWlsdGVmb3NpbmUuICBBbGwKc2FtcGxlcyBleGNlcHQgb25lIHdlcmUgZG9uZSBvbiB0aGUgc2FtZSBkYXksIGJ1dCBzZXF1ZW5jZWQgYWNyb3NzIGEKZmV3IGl0ZXJhdGlvbnMgd2l0aCBhIHJlbGF0aXZlbHkgd2lkZSByYW5nZSBvZiBzZXF1ZW5jaW5nIGRlcHRocy4KVGhlcmUgYXJlIGEgY291cGxlIG9mIHNhbXBsZXMgd2hpY2ggaGF2ZSBub3QgaGFkIHRoZWlyIHJlYWQKbnVtYmVycy9tYXBwaW5nIHJhdGVzIGNvbGxlY3RlZCBpbnRvIHRoZSBzYW1wbGUgc2hlZXQuCgpUTVJDMzAxMjYgYW5kIFRNUkMzMDEyOQoKSSBzZWUgdGhhdCBJIHJhbiBtYXBwaW5ncyBhZ2FpbnN0IHBhbmFtZW5zaXMsIGJ1dCB0aG9zZSBkbyBub3QgYXBwZWFyCnRvIGJlIGluIHRoZSBzYW1wbGUgc2hlZXQuICBEbyB3ZSB3aXNoIHRvIGxvb2sgYXQgdGhlIHBhcmFzaXRlcz8KCmBgYHtyIHNhbXBsZXNoZWV0fQpzYW1wbGVzaGVldCA8LSAic2FtcGxlX3NoZWV0cy93ZWxsY29tZV90cnVzdF9zYW1wbGVzLXYyMDIyMDkueGxzeCIKYGBgCgojIEFubm90YXRpb24KCldlIHRha2UgdGhlIGFubm90YXRpb24gZGF0YSBmcm9tIGVuc2VtYmwncyBiaW9tYXJ0IGluc3RhbmNlLiAgVGhlIGdlbm9tZSB3aGljaAp3YXMgdXNlZCB0byBtYXAgdGhlIGRhdGEgd2FzIGhnMzggcmV2aXNpb24gMTAwLiAgTXkgZGVmYXVsdCB3aGVuIHVzaW5nIGJpb21hcnQgaXMKdG8gbG9hZCB0aGUgZGF0YSBmcm9tIDEgeWVhciBiZWZvcmUgdGhlIGN1cnJlbnQgZGF0ZS4KCmBgYHtyIGhzX2Fubm90fQpoc19hbm5vdCA8LSBsb2FkX2Jpb21hcnRfYW5ub3RhdGlvbnMoeWVhciA9ICIyMDE5IilbWyJhbm5vdGF0aW9uIl1dCmhzX2Fubm90W1sidHJhbnNjcmlwdCJdXSA8LSBwYXN0ZTAocm93bmFtZXMoaHNfYW5ub3QpLCAiLiIsIGhzX2Fubm90W1sidmVyc2lvbiJdXSkKcm93bmFtZXMoaHNfYW5ub3QpIDwtIG1ha2UubmFtZXMoaHNfYW5ub3RbWyJlbnNlbWJsX2dlbmVfaWQiXV0sIHVuaXF1ZSA9IFRSVUUpCnR4X2dlbmVfbWFwIDwtIGhzX2Fubm90WywgYygidHJhbnNjcmlwdCIsICJlbnNlbWJsX2dlbmVfaWQiKV0KCnN1bW1hcnkoaHNfYW5ub3QpCmBgYAoKYGBge3IgaHNfZ299CmhzX2dvIDwtIGxvYWRfYmlvbWFydF9nbygpW1siZ28iXV0KaHNfbGVuZ3RoIDwtIGhzX2Fubm90WywgYygiZW5zZW1ibF9nZW5lX2lkIiwgImNkc19sZW5ndGgiKV0KY29sbmFtZXMoaHNfbGVuZ3RoKSA8LSBjKCJJRCIsICJsZW5ndGgiKQpgYGAKCmBgYHtyIGV4cHR9CndlbGxjb21lX291dHRpbWUgPC0gY3JlYXRlX2V4cHQobWV0YWRhdGEgPSBzYW1wbGVzaGVldCwgZ2VuZV9pbmZvID0gaHNfYW5ub3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW4gPSAiaGczODEwMGhpc2F0ZmlsZSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJkcnVnIikKCm91dGNvbWVfdGltZSA8LSBwYXN0ZTAocERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJjbGluaWNhbG91dGNvbWUiXV0sICJfdiIsCiAgICAgICAgICAgICAgICAgICAgICAgcERhdGEod2VsbGNvbWVfb3V0dGltZSlbWyJ2aXNpdG51bWJlciJdXSkKd2VsbGNvbWVfb3V0dGltZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSBvdXRjb21lX3RpbWUpCgp3ZWxsY29tZV90aW1lIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJ2aXNpdG51bWJlciIpCnBEYXRhKHdlbGxjb21lX3RpbWUpW1siY29uZGl0aW9uIl1dIDwtIHBhc3RlMCgidCIsIHBEYXRhKHdlbGxjb21lX3RpbWUpW1siY29uZGl0aW9uIl1dKQoKd2VsbGNvbWVfb3V0Y29tZSA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gInZpc2l0bnVtYmVyIikKcERhdGEod2VsbGNvbWVfb3V0Y29tZSlbWyJiYXRjaCJdXSA8LSBwYXN0ZTAoInQiLCBwRGF0YSh3ZWxsY29tZV9vdXRjb21lKVtbImJhdGNoIl1dKQoKd2VsbGNvbWVfZHJ1ZyA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHdlbGxjb21lX291dHRpbWUsIGZhY3QgPSAiZHJ1ZyIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ2aXNpdG51bWJlciIpCnBEYXRhKHdlbGxjb21lX2RydWcpW1siYmF0Y2giXV0gPC0gcGFzdGUwKCJ0IiwgcERhdGEod2VsbGNvbWVfZHJ1ZylbWyJiYXRjaCJdXSkKCndlbGxjb21lX3BhcmFzaXRlIDwtIHNldF9leHB0X2NvbmRpdGlvbnMod2VsbGNvbWVfb3V0dGltZSwgZmFjdCA9ICJpbmZlY3RpbmdzcGVjaWUiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKQpwRGF0YSh3ZWxsY29tZV9vdXRjb21lKVtbImJhdGNoIl1dIDwtIHBhc3RlMCgidCIsIHBEYXRhKHdlbGxjb21lX291dGNvbWUpW1siYmF0Y2giXV0pCmBgYAoKIyBXZWxsY29tZSBwbG90cwoKIyMgQSBmZXcgZ2xvYmFsIG1ldHJpY3MKCmBgYHtyIGdsb2JhbH0KcGxvdF9saWJzaXplKHdlbGxjb21lX3RpbWUpJHBsb3QKcGxvdF9ub256ZXJvKHdlbGxjb21lX3RpbWUpJHBsb3QKcGxvdF9ib3hwbG90KHdlbGxjb21lX3RpbWUpCmBgYAoKIyMgQnkgdmlzaXQKCmBgYHtyIHdlbGxjb21lX3RpbWV9CndlbGxjb21lX3RpbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV90aW1lLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV90aW1lX25vcm0sIHBsb3RfbGFiZWxzPUZBTFNFKSRwbG90CndlbGxjb21lX3RpbWVfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCh3ZWxsY29tZV90aW1lX25vcm0pCndlbGxjb21lX3RpbWVfdmFycGFydCRwYXJ0aXRpb25fcGxvdAoKd2VsbGNvbWVfdGltZV9uYiA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV90aW1lLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfdGltZV9uYiwgcGxvdF9sYWJlbHM9RkFMU0UpJHBsb3QKd2VsbGNvbWVfdGltZV9uYl92YXJwYXJ0IDwtIHNpbXBsZV92YXJwYXJ0KHdlbGxjb21lX3RpbWVfbmIpCndlbGxjb21lX3RpbWVfbmJfdmFycGFydCRwYXJ0aXRpb25fcGxvdApgYGAKCiMjIEN1cmUvRmFpbAoKYGBge3Igd2VsbGNvbWVfb3V0Y29tZXYxfQp3ZWxsY29tZV9vdXRjb21lX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfb3V0Y29tZSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfb3V0Y29tZV9ub3JtLCBwbG90X2xhYmVscz1GQUxTRSkkcGxvdAoKd2VsbGNvbWVfb3V0Y29tZV92YXJwYXJ0IDwtIHNpbXBsZV92YXJwYXJ0KHdlbGxjb21lX291dGNvbWVfbm9ybSkKd2VsbGNvbWVfb3V0Y29tZV92YXJwYXJ0JHBhcnRpdGlvbl9wbG90Cgp3ZWxsY29tZV9vdXRjb21lX25iIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX291dGNvbWUsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnBsb3RfcGNhKHdlbGxjb21lX291dGNvbWVfbmIsIHBsb3RfbGFiZWxzPUZBTFNFKSRwbG90Cgp3ZWxsY29tZV9vdXRjb21lX25iX3ZhcnBhcnQgPC0gc2ltcGxlX3ZhcnBhcnQod2VsbGNvbWVfb3V0Y29tZV9uYikKd2VsbGNvbWVfb3V0Y29tZV9uYl92YXJwYXJ0JHBhcnRpdGlvbl9wbG90CmBgYAoKIyMgRHJ1ZwoKYGBge3Igd2VsbGNvbWVfb3V0Y29tZXYyfQp3ZWxsY29tZV9kcnVnX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfZHJ1Zywgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfZHJ1Z19ub3JtLCBwbG90X2xhYmVscz1GQUxTRSkkcGxvdAoKd2VsbGNvbWVfZHJ1Z192YXJwYXJ0IDwtIHNpbXBsZV92YXJwYXJ0KHdlbGxjb21lX2RydWdfbm9ybSkKd2VsbGNvbWVfZHJ1Z192YXJwYXJ0JHBhcnRpdGlvbl9wbG90Cgp3ZWxsY29tZV9kcnVnX25iIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX2RydWcsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnBsb3RfcGNhKHdlbGxjb21lX2RydWdfbmIsIHBsb3RfbGFiZWxzPUZBTFNFKSRwbG90Cgp3ZWxsY29tZV9kcnVnX25iX3ZhcnBhcnQgPC0gc2ltcGxlX3ZhcnBhcnQod2VsbGNvbWVfZHJ1Z19uYikKd2VsbGNvbWVfZHJ1Z19uYl92YXJwYXJ0JHBhcnRpdGlvbl9wbG90CmBgYAoKIyMgT3V0Y29tZSBhbmQgdGltZQoKYGBge3Igd2VsbGNvbWVfcGxvdHN9CndlbGxjb21lX291dHRpbWVfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9vdXR0aW1lLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9vdXR0aW1lX25vcm0sIHBsb3RfbGFiZWxzPUZBTFNFKSRwbG90CndlbGxjb21lX291dHRpbWVfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCh3ZWxsY29tZV9vdXR0aW1lX25vcm0pCndlbGxjb21lX291dHRpbWVfdmFycGFydCRwYXJ0aXRpb25fcGxvdAoKd2VsbGNvbWVfb3V0dGltZV9uYiA8LSBub3JtYWxpemVfZXhwdCh3ZWxsY29tZV9vdXR0aW1lLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfb3V0dGltZV9uYikkcGxvdAp3ZWxsY29tZV9vdXR0aW1lX25iX3ZhcnBhcnQgPC0gc2ltcGxlX3ZhcnBhcnQod2VsbGNvbWVfb3V0dGltZV9uYikKd2VsbGNvbWVfb3V0dGltZV9uYl92YXJwYXJ0JHBhcnRpdGlvbl9wbG90CmBgYAoKIyMgUGFyYXNpdGUgU3BlY2llcwoKYGBge3Igd2VsbGNvbWVfcGFyYXNpdGV9CndlbGxjb21lX3BhcmFzaXRlX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfcGFyYXNpdGUsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgdHJhbnNmb3JtID0gImxvZzIiKQpwbG90X3BjYSh3ZWxsY29tZV9wYXJhc2l0ZV9ub3JtLCBwbG90X2xhYmVscz1GQUxTRSkkcGxvdAp3ZWxsY29tZV9wYXJhc2l0ZV92YXJwYXJ0IDwtIHNpbXBsZV92YXJwYXJ0KHdlbGxjb21lX3BhcmFzaXRlX25vcm0pCndlbGxjb21lX3BhcmFzaXRlX3ZhcnBhcnQkcGFydGl0aW9uX3Bsb3QKCndlbGxjb21lX3BhcmFzaXRlX25iIDwtIG5vcm1hbGl6ZV9leHB0KHdlbGxjb21lX3BhcmFzaXRlLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKcGxvdF9wY2Eod2VsbGNvbWVfcGFyYXNpdGVfbmIpJHBsb3QKd2VsbGNvbWVfcGFyYXNpdGVfbmJfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydCh3ZWxsY29tZV9wYXJhc2l0ZV9uYikKd2VsbGNvbWVfcGFyYXNpdGVfbmJfdmFycGFydCRwYXJ0aXRpb25fcGxvdApgYGAKCiMgREUgYW5hbHlzZXMKCiMjIE91dGNvbWUgYW5kIHRpbWUKClRPRE86IEFsc28gZG8gdGhpcyB3aXRob3V0IHN2YS4KCmBgYHtyIG91dHRpbWVfZGV2MX0Kb3V0dGltZV9kZSA8LSBhbGxfcGFpcndpc2Uod2VsbGNvbWVfb3V0dGltZSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKb3V0dGltZV9rZWVwZXJzIDwtIGxpc3QoCiAgICAiY3VyZXYxdjIiID0gYygiQ3VyZXYyIiwgIkN1cmV2MSIpLAogICAgImN1cmV2MXYzIiA9IGMoIkN1cmV2MyIsICJDdXJldjEiKSwKICAgICJjdXJldjJ2MyIgPSBjKCJDdXJldjMiLCAiQ3VyZXYyIiksCiAgICAiZmFpbHYxdjIiID0gYygiRmFpbHVyZXYyIiwgIkZhaWx1cmV2MSIpLAogICAgImZhaWx2MXYzIiA9IGMoIkZhaWx1cmV2MyIsICJGYWlsdXJldjEiKSwKICAgICJmYWlsdjJ2MyIgPSBjKCJGYWlsdXJldjMiLCAiRmFpbHVyZXYyIikpCm91dHRpbWVfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBvdXR0aW1lX2RlLAogICAga2VlcGVycyA9IG91dHRpbWVfa2VlcGVycywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfb3V0dGltZV90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKb3V0dGltZV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG91dHRpbWVfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX291dHRpbWVfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQoKb3V0dGltZV9iYXRjaF9kZSA8LSBhbGxfcGFpcndpc2Uod2VsbGNvbWVfb3V0dGltZSwgbW9kZWxfYmF0Y2ggPSBUUlVFLCBmaWx0ZXIgPSBUUlVFKQpvdXR0aW1lX2JhdGNoX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgb3V0dGltZV9iYXRjaF9kZSwKICAgIGtlZXBlcnMgPSBvdXR0aW1lX2tlZXBlcnMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX291dHRpbWVfdGFibGVfYmF0Y2gtdnt2ZXJ9Lnhsc3giKSkKb3V0dGltZV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG91dHRpbWVfYmF0Y2hfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX291dHRpbWVfc2lnX2JhdGNoLXZ7dmVyfS54bHN4IikpCmBgYAoKYGBge3Igb3V0dGltZV9kZXYyfQp0aW1lX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV90aW1lLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp0aW1lX2tlZXBlcnMgPC0gbGlzdCgKICAgICJ2MXYyIiA9IGMoInQyIiwgInQxIiksCiAgICAidjF2MyIgPSBjKCJ0MyIsICJ0MSIpLAogICAgInYydjMiID0gYygidDMiLCAidDIiKSkKdGltZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB0aW1lX2RlLAogICAga2VlcGVycyA9IHRpbWVfa2VlcGVycywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfdGltZV90YWJsZV9zdmEtdnt2ZXJ9Lnhsc3giKSkKdGltZV9zdmFfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICB0aW1lX3N2YV90YWJsZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfdGltZV9zaWdfc3ZhLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMgT3V0Y29tZQoKYGBge3IgZGVfb25seV9vdXRjb21lfQpwYXJhc2l0ZV9zdmFfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX3BhcmFzaXRlLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwYXJhc2l0ZV9zdmFfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBwYXJhc2l0ZV9zdmFfZGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3BhcmFzaXRlX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpKQpwYXJhc2l0ZV9zdmFfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBwYXJhc2l0ZV9zdmFfdGFibGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3dlbGxjb21lX3BhcmFzaXRlX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKCnBhcmFzaXRlX2JhdGNoX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV9wYXJhc2l0ZSwgbW9kZWxfYmF0Y2ggPSAiYmF0Y2hzZXEiLCBmaWx0ZXIgPSBUUlVFKQoKcGFyYXNpdGVfYmF0Y2hfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBwYXJhc2l0ZV9iYXRjaF9kZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfcGFyYXNpdGVfdGFibGVfYmF0Y2gtdnt2ZXJ9Lnhsc3giKSkKcGFyYXNpdGVfYmF0Y2hfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBwYXJhc2l0ZV9iYXRjaF90YWJsZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvd2VsbGNvbWVfcGFyYXNpdGVfc2lnX3N2YS12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIFBhcmFzaXRlCgpgYGB7ciBkZV9vbmx5X3BhcmFzaXRlfQojIyB3ZWxsY29tZV9vdXRjb21lX25vcm0gPC0gbm9ybWFsaXplX2V4cHQod2VsbGNvbWVfb3V0Y29tZSwgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKCm91dGNvbWVfc3ZhX2RlIDwtIGFsbF9wYWlyd2lzZSh3ZWxsY29tZV9vdXRjb21lLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpvdXRjb21lX3N2YV90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIG91dGNvbWVfc3ZhX2RlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3RhYmxlX3N2YS12e3Zlcn0ueGxzeCIpKQpvdXRjb21lX3N2YV9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG91dGNvbWVfc3ZhX3RhYmxlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKCm91dGNvbWVfYmF0Y2hfZGUgPC0gYWxsX3BhaXJ3aXNlKHdlbGxjb21lX291dGNvbWUsIG1vZGVsX2JhdGNoID0gImJhdGNoc2VxIiwgZmlsdGVyID0gVFJVRSkKCm91dGNvbWVfYmF0Y2hfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBvdXRjb21lX2JhdGNoX2RlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3RhYmxlX2JhdGNoLXZ7dmVyfS54bHN4IikpCm91dGNvbWVfYmF0Y2hfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBvdXRjb21lX2JhdGNoX3RhYmxlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC93ZWxsY29tZV9vdXRjb21lX3NpZ19zdmEtdnt2ZXJ9Lnhsc3giKSkKYGBgCgoKCmBgYHtyIHdlbGxjb21lX2dzdmF9CndlbGxjb21lX2dzdmFfYzIgPC0gc2ltcGxlX2dzdmEod2VsbGNvbWVfb3V0Y29tZSwgc2lnbmF0dXJlX2NhdGVnb3J5PSJjMiIpCndlbGxjb21lX2dzdmFfYzJfc2lnIDwtIGdldF9zaWdfZ3N2YV9jYXRlZ29yaWVzKAogICAgd2VsbGNvbWVfZ3N2YV9jMiwKICAgIGV4Y2VsPSJleGNlbC93ZWxsY29tZV9nc3ZhX2MyLnhsc3giKQoKd2VsbGNvbWVfZ3N2YV9jNyA8LSBzaW1wbGVfZ3N2YSh3ZWxsY29tZV9vdXRjb21lLCBzaWduYXR1cmVfY2F0ZWdvcnk9ImM3IikKd2VsbGNvbWVfZ3N2YV9jN19zaWcgPC0gZ2V0X3NpZ19nc3ZhX2NhdGVnb3JpZXMoCiAgICB3ZWxsY29tZV9nc3ZhLAogICAgZXhjZWw9ImV4Y2VsL3dlbGxjb21lX2dzdmFfYzcueGxzeCIpCmBgYAo=