1 Introduction

This dataset contains multiple experiments.

2 Annotations

pa14_gff <- load_gff_annotations("reference/paeruginosa_pa14.gff", id_col="gene_id")
## Trying attempt: rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = TRUE)
## Had a successful gff import with rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo = TRUE)
## Returning a df with 16 columns and 11946 rows.
rownames(pa14_gff) <- pa14_gff[["gene_id"]]
## The Alias column has PA14_00010

pa14_microbes <- as.data.frame(load_microbesonline_annotations("PA14"))
## Found 1 entry.
## Pseudomonas aeruginosa UCBPP-PA14Proteobacteria2006-11-22yes105972208963
## The species being downloaded is: Pseudomonas aeruginosa UCBPP-PA14
## Downloading: http://www.microbesonline.org/cgi-bin/genomeInfo.cgi?tId=208963;export=tab
## The sysName column has PA14_0010

pa14_annot <- merge(pa14_gff, pa14_microbes, by.x="Alias", by.y="sysName")
rownames(pa14_annot) <- pa14_annot[["gene_id"]]

## The identifiers are a bit odd, so we need to do a little work
pa14_length <- pa14_annot[, c("gene_id", "width", "Alias")]
pa14_go <- load_microbesonline_go(species="PA14", id_column="sysName")
## Found 1 entry.
## Pseudomonas aeruginosa UCBPP-PA14Proteobacteria2006-11-22yes105972208963
## The species being downloaded is: Pseudomonas aeruginosa UCBPP-PA14 and is being downloaded as 208963.tab.
pa14_go_length <- merge(pa14_go, pa14_length, by.x="sysName", by.y="Alias")
pa14_go <- pa14_go_length[, c("gene_id", "GO")]
colnames(pa14_go) <- c("ID", "GO")
pa14_length <- pa14_go_length[, c("gene_id", "width")]
pa14_length_ids <- unique(pa14_length)[["gene_id"]]
pa14_length <- pa14_length[pa14_length_ids, ]
rownames(pa14_length) <- make.names(pa14_length[["gene_id"]], unique=TRUE)
colnames(pa14_length) <- c("ID", "width")

3 Make the expressionset

Given the above annotations, now lets pull in the counts.

I am switching to the sheet all_samples_modified_gcd.xlsx for the moment because I added a space in the strain name for the gcd sampl

pa14_expt <- create_expt("sample_sheets/all_samples_modified_gcd_202206.xlsx",
                         gene_info=pa14_annot, file_column="hisatcounttablereverse")
## Reading the sample metadata.
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## The sample definitions comprises: 105 rows(samples) and 32 columns(metadata fields).
## Matched 5972 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 5979 features and 105 samples.

4 Quick global look at the data

While we are at it, lets drop the two sad samples.

pa14_libsize <- plot_libsize(pa14_expt)
pa14_libsize$plot

pa14_nonzero <- plot_nonzero(pa14_expt)
pa14_nonzero$plot
## Warning: ggrepel: 100 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

pa14_expt <- subset_expt(pa14_expt, nonzero=5500)
## The samples (and read coverage) removed when filtering 5500 non-zero genes are:
##  SM040  SM046  SM048  SM053 
##  41248 787576 301043 844448
## subset_expt(): There were 105, now there are 101 samples.

4.1 A few queries

I know a priori that April is interested to see how the 4 library preparations look with respect to each other. Let us therefore create a data structure to look explicitly at that.

pa14_libprep <- set_expt_conditions(pa14_expt, fact="libraryprepbatch") %>%
  set_expt_batches(fact="organisms")

pa14_lib_norm <- normalize_expt(pa14_libprep, filter=TRUE,
                                convert="cpm", norm="quant", transform="log2")
## Removing 13 low-count genes (5966 remaining).
## transform_counts: Found 29 values equal to 0, adding 1 to the matrix.
plot_pca(pa14_lib_norm)$plot
## plot labels was not set and there are more than 100 samples, disabling it.
## Error: Continuous value supplied to discrete scale

plot_corheat(pa14_lib_norm)$plot

libprep_pca_info <- pca_information(
    pa14_lib_norm, plot_pcas=TRUE,
    expt_factors=c("libraryprepbatch", "organisms", "strains", "media", "bioreplicate"))
## plot labels was not set and there are more than 100 samples, disabling it.
libprep_pca_info$anova_f_heatmap

libprep_pca_info$pca_plots[[2]]
## Error: Continuous value supplied to discrete scale
libprep_pca_info$pca_plots[[3]]
## Error: Continuous value supplied to discrete scale
libprep_pca_info$pca_plots[[4]]
## Error: Continuous value supplied to discrete scale
libprep_pca_info$pca_plots[[5]]
## Error: Continuous value supplied to discrete scale

To my eyes they look reasonably mixed, suggesting that library prep batch is not a dominant factor in the data.

At this point, I am thinking that we should separate the data by the experiments, but I will first just show the relationships among all the data.

5 Looking at other factors

As far as I see, there are three factors which are of primary interest:

  1. PA14 strain
  2. Media used
  3. Bioreplicate

The last will be used as batch in the following plots.

pa14_media <- set_expt_conditions(pa14_expt, fact="media") %>%
  set_expt_batches(fact="bioreplicate")
pa14_media_norm <- normalize_expt(pa14_media, transform="log2", convert="cpm",
                                  filter=TRUE, norm="quant")
## Removing 13 low-count genes (5966 remaining).
## transform_counts: Found 29 values equal to 0, adding 1 to the matrix.
plot_pca(pa14_media_norm)$plot
## plot labels was not set and there are more than 100 samples, disabling it.

pa14_strains <- set_expt_conditions(pa14_expt, fact="strains") %>%
  set_expt_batches(fact="bioreplicate")
pa14_strains_norm <- normalize_expt(pa14_strains, transform="log2", convert="cpm",
                                  filter=TRUE, norm="quant")
## Removing 13 low-count genes (5966 remaining).
## transform_counts: Found 29 values equal to 0, adding 1 to the matrix.
plot_pca(pa14_strains_norm)$plot
## plot labels was not set and there are more than 100 samples, disabling it.

Disregarding the various experiments performed, I think we can state that media separates the data in a fashion which is more interesting than strain. Given the number of (what I assume are) closely related strains, I am thinking it might prove to be a good idea to perform my variant search tool on this data and see how well they held up with respect to the reference strain.

6 Separate the experiments

I have been told repeatedly that there are multiple experiments in this data, but apparently I have not paid proper attention because I cannot remember which is which, and to my eyes it is not obvious in the sample sheet.

With this in mind, I spoke with Solomon briefly and have an idea of the 3 logical groups in his data. Let us therefore separate and examine those first.

6.1 Metabolism and infection

For the moment, I am going to call Solomon’s samples ‘metabolism and infection.’ I will also complicate the ‘condition’ of the data by combining the media and strain, but shortly thereafter will split that back. I think the reason why will become clear.

initials_factor <- gsub(x=rownames(pData(pa14_expt)), pattern="^(..).*$", replacement="\\1")
pData(pa14_expt)[["initials"]] <- as.factor(initials_factor)
strain_media <- paste0(pData(pa14_expt)[["strains"]], "_",
                       pData(pa14_expt)[["media"]])
pData(pa14_expt)[["strain_media"]] <- strain_media

## Lets set some colors
## WT: grayscale, eda: blue, edd: green, gcd: purple, pgl: red, zwf: yellow
colors_by_strain <- list(
    "PA14 WT" = "#000000",
    "PA14 eda" = "#0000dd",
    "PA14 edd" = "#00dd00",
    "PA14 gcd" = "#dd00dd",
    "PA14 pgl" = "#dd0000",
    "PA14 zwf" = "#dddd00")

infect_metabolism <- subset_expt(pa14_expt, subset="initials=='SM'") %>%
  set_expt_conditions(fact="strains") %>%
  set_expt_batches(fact="media")
## subset_expt(): There were 101, now there are 56 samples.
plot_legend(infect_metabolism)$plot

written <- write_expt(infect_metabolism, excel="excel/pa14_sm_written.xlsx")
## Deleting the file excel/pa14_sm_written.xlsx before writing the tables.
## Writing the first sheet, containing a legend and some summary data.
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## The following object is masked from 'package:S4Vectors':
## 
##     expand
## 
## Total:65 s
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## 
## Total:58 s
metabolism_control <- subset_expt(infect_metabolism,
                                  subset="media=='LB'|media=='LB + 0.5 M urea'") %>%
  set_expt_conditions(fact="media") %>%
  set_expt_batches("bioreplicate")
## subset_expt(): There were 56, now there are 6 samples.
metabolism_starvation <- subset_expt(infect_metabolism,
                                     subset="media=='PBST'|media=='Urine'") %>%
  set_expt_colors(colors=colors_by_strain) %>%
  set_expt_conditions(fact="media") %>%
  set_expt_batches(fact="strains")
## subset_expt(): There were 56, now there are 35 samples.
metabolism_starvation_strain <- set_expt_conditions(metabolism_starvation, fact="strains") %>%
  set_expt_batches(fact="media")

metabolism_exudate <- subset_expt(infect_metabolism,
                                  subset="media=='Instilled'")
## subset_expt(): There were 56, now there are 15 samples.

6.2 Glance at these 4 subsets

As a whole group, these samples are a bit confusing. The mouse instiled samples are prety obvious, but the other sources of variance remain a bit of a mystery to me.

global_norm <- normalize_expt(infect_metabolism, filter=TRUE, convert="cpm",
                              norm="quant", transform="log2") %>%
  set_expt_conditions(fact="media")
## Removing 40 low-count genes (5939 remaining).
## transform_counts: Found 6 values equal to 0, adding 1 to the matrix.
plot_pca(global_norm)$plot
## Warning: ggrepel: 13 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

tmp <- global_norm %>%
  set_expt_conditions(fact="strains")
plot_pca(tmp)$plot
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure
## Warning: ggrepel: 47 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

7 The smallest experiment: LB vs. LB+urea

This is a group of 6 samples, 3 in LB and three in LB+urea. This should therefore be the most straight forward comparison.

mc_norm <- normalize_expt(metabolism_control, transform="log2",
                          convert="cpm", norm="quant", filter=TRUE)
## Removing 253 low-count genes (5726 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(mc_norm)$plot

7.1 Metabolism control experiment, DE

mc_san <- sanitize_expt(metabolism_control)
mc_de <- all_pairwise(mc_san, model_batch=TRUE, filter=TRUE)
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
mc_tables <- combine_de_tables(
    mc_de,
    excel=glue::glue("excel/metabolism_control_tables-v{ver}.xlsx"))
mc_sig <- extract_significant_genes(
    mc_tables,
    excel=glue::glue("excel/metabolism_control_sig-v{ver}.xlsx"))

8 Starving strains

The second group is a little more complex, it seeks to simultaneously compare the strains (WT vs. mutants) and the environment (PBS vs. urine).

This design is complex enough that I think we need to choose colors more carefully.

Here is a query from Solomon:

Could you please generate me a table for the metabolism starvation strain analyses where the urine is the numerator and the PBST is the denominator?

I am interpreting this to mean we should have an experimental design in which we ignore the strains and just compare all urine and pbst samples. When I ran the following block, it looks to me that we currently return this in the following block:

ms_norm <- normalize_expt(metabolism_starvation, filter=TRUE, norm="quant",
                          convert="cpm", transform="log2")
## Removing 70 low-count genes (5909 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(ms_norm)$plot

ms_de <- all_pairwise(metabolism_starvation, model_batch=TRUE)
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
ms_de$comparison$comp
##                Urine_vs_PBST
## limma_vs_deseq        0.9846
## limma_vs_edger        0.9848
## limma_vs_ebseq        0.9800
## limma_vs_basic        0.9993
## deseq_vs_edger        0.9999
## deseq_vs_ebseq        0.9958
## deseq_vs_basic        0.9851
## edger_vs_ebseq        0.9964
## edger_vs_basic        0.9856
## ebseq_vs_basic        0.9828
ms_tables <- combine_de_tables(
    ms_de,
    excel=glue::glue("excel/metabolism_starvation_tables-v{ver}.xlsx"))
ms_sig <- extract_significant_genes(
    ms_tables,
    excel=glue::glue("excel/metabolism_starvation_sig-v{ver}.xlsx"))

9 Metabolism Starvation GO

ms_up <- ms_tables[["significant"]][["deseq"]][["ups"]][[1]]
ms_down <- ms_tables[["significant"]][["deseq"]][["downs"]][[1]]

## The go data from microbesonline is keyed by the gene name
## (e.g. dnaA), not gene ID or PA id or whatever.
pa14_lengths <- pa14_annot[, c("name.x", "width")]
colnames(pa14_lengths) <- c("ID", "width")

rownames(ms_up) <- make.names(ms_up[["namex"]], unique=TRUE)
## Error in `rownames<-`(`*tmp*`, value = character(0)): attempt to set 'rownames' on an object with no dimensions
ms_up_goseq <- simple_goseq(ms_up, go_db=pa14_go, length_db=pa14_lengths)
## Error in simple_goseq(ms_up, go_db = pa14_go, length_db = pa14_lengths): Not sure how to handle your set of significant gene ids.
ms_up_goseq[["pvalue_plots"]][["bpp_plot_over"]]
## Error in eval(expr, envir, enclos): object 'ms_up_goseq' not found
ms_up_goseq[["pvalue_plots"]][["mfp_plot_over"]]
## Error in eval(expr, envir, enclos): object 'ms_up_goseq' not found
rownames(ms_down) <- make.names(ms_down[["namex"]], unique=TRUE)
## Error in `rownames<-`(`*tmp*`, value = character(0)): attempt to set 'rownames' on an object with no dimensions
ms_down_goseq <- simple_goseq(ms_down, go_db=pa14_go, length_db=pa14_lengths)
## Error in simple_goseq(ms_down, go_db = pa14_go, length_db = pa14_lengths): Not sure how to handle your set of significant gene ids.
ms_down_goseq[["pvalue_plots"]][["bpp_plot_over"]]
## Error in eval(expr, envir, enclos): object 'ms_down_goseq' not found
ms_down_goseq[["pvalue_plots"]][["mfp_plot_over"]]
## Error in eval(expr, envir, enclos): object 'ms_down_goseq' not found

9.1 Compare strains

This time let us compare the strains and lower the variance from media.

mss_norm <- normalize_expt(metabolism_starvation_strain, filter=TRUE, convert="cpm", norm="quant",
                           transform="log2")
## Removing 70 low-count genes (5909 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(mss_norm)$plot

mss_urine <- subset_expt(metabolism_starvation_strain, subset="batch=='Urine'")
## subset_expt(): There were 35, now there are 18 samples.
mss_urine_norm <- normalize_expt(mss_urine, filter=TRUE, convert="cpm", norm="quant",
                                 batch="svaseq", transform="log2")
## Warning in normalize_expt(mss_urine, filter = TRUE, convert = "cpm", norm =
## "quant", : Quantile normalization and sva do not always play well together.
## Removing 92 low-count genes (5887 remaining).
## Setting 19 low elements to zero.
## transform_counts: Found 19 values equal to 0, adding 1 to the matrix.
plot_pca(mss_urine_norm)$plot

mss_pbst <- subset_expt(metabolism_starvation_strain, subset="batch=='PBST'")
## subset_expt(): There were 35, now there are 17 samples.
mss_pbst_norm <- normalize_expt(mss_pbst, filter=TRUE, convert="cpm",
                                batch="svaseq", transform="log2")
## Removing 177 low-count genes (5802 remaining).
## Setting 50 low elements to zero.
## transform_counts: Found 50 values equal to 0, adding 1 to the matrix.
plot_pca(mss_pbst_norm)$plot

interesting <- list(
    "eda_vs_wt" = c("PA14eda", "PA14WT"),
    "edd_vs_wt" = c("PA14edd", "PA14WT"),
    "gcd_vs_wt" = c("PA14gcd", "PA14WT"),
    "pgl_vs_wt" = c("PA14pgl", "PA14WT"),
    "zfw_vs_wt" = c("PA14zwf", "PA14WT"))
mss_urine_de <- all_pairwise(mss_urine, model_batch="svaseq", filter=TRUE)
## Removing 0 low-count genes (5887 remaining).
## Setting 40 low elements to zero.
## transform_counts: Found 40 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

mss_urine_table <- combine_de_tables(
    mss_urine_de, keepers=interesting,
    excel=glue::glue("excel/metabolism_starvation_strain_tables-v{ver}.xlsx"))
mss_urine_sig <- extract_significant_genes(
    mss_urine_table,
    excel=glue::glue("excel/metabolism_starvation_strain_sig-v{ver}.xlsx"))

Given that the strains are so similar, we can comfortably compare them across media (PBST/urine).

msm <- set_expt_conditions(metabolism_starvation_strain, fact="batch") %>%
  set_expt_batches(fact="bioreplicate")
msm_norm <- normalize_expt(msm, filter=TRUE, convert="cpm", norm="quant",
                           transform="log2")
## Removing 70 low-count genes (5909 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
plot_pca(msm_norm)$plot

10 Exudate

Compare the strains during the instillation process

exudate_norm <- normalize_expt(metabolism_exudate, filter=TRUE, convert="cpm",
                               norm="quant", transform="log2")
## Removing 227 low-count genes (5752 remaining).
## transform_counts: Found 285 values equal to 0, adding 1 to the matrix.
pp(file="images/compare_strains_exudate.pdf", image=plot_pca(exudate_norm)$plot)

exudate_nb <- normalize_expt(metabolism_exudate, filter=TRUE, convert="cpm",
                             transform="log2", batch="svaseq")
## Removing 227 low-count genes (5752 remaining).
## Setting 460 low elements to zero.
## transform_counts: Found 460 values equal to 0, adding 1 to the matrix.
plot_pca(exudate_nb)$plot

pp(file="images/compare_strains_exudate_sva.pdf", image=plot_pca(exudate_nb)$plot)

10.1 Exudate DE

exudate_de <- all_pairwise(metabolism_exudate, model_batch=TRUE, filter=TRUE)
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

exudate_tables <- combine_de_tables(
    exudate_de, keepers=interesting,
    excel=glue::glue("excel/exudate_tables-v{ver}.xlsx"))
exudate_sig <- extract_significant_genes(
    exudate_tables,
    excel=glue::glue("excel/exudate_sig-v{ver}.xlsx"))
## Warning in max(newdf[["avg"]]): no non-missing arguments to max; returning -Inf
wanted_table <- exudate_tables[["data"]][["eda_vs_wt"]]
eda_wt_volcano <- plot_volcano_de(wanted_table, logfc=2, fc_col="deseq_logfc", p_col="deseq_adjp")
pp(file="images/wt_vs_eda_de_volcano_instilled.pdf",
   image=eda_wt_volcano$plot)

11 Instilled vs. PBST/Urine

Vince and Najib are interested in a slightly different question:

instilled_vs <- subset_expt(
    pa14_expt,
    subset='media=="PBST"|media=="Urine"|media=="Instilled"') %>%
  set_expt_conditions(fact="media") %>%
  set_expt_batches(fact="bioreplicate")
## subset_expt(): There were 101, now there are 50 samples.
instilled_vs_norm <- normalize_expt(instilled_vs, transform="log2", convert="cpm",
                                    norm="quant", filter=TRUE)
## Removing 41 low-count genes (5938 remaining).
## transform_counts: Found 6 values equal to 0, adding 1 to the matrix.
inst_pca <- plot_pca(instilled_vs_norm)$plot
pp(file="images/instilled_vs_pca.pdf", image=inst_pca)
## Warning: ggrepel: 12 unlabeled data points (too many overlaps). Consider increasing max.overlaps
## ggrepel: 12 unlabeled data points (too many overlaps). Consider increasing max.overlaps

inst_vs_de <- all_pairwise(instilled_vs, filter=TRUE)
## Using limma's removeBatchEffect to visualize with(out) batch inclusion.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

inst_vs_tables <- combine_de_tables(
    inst_vs_de,
    excel=glue::glue("excel/instilled_vs_tables-v{ver}.xlsx"))
inst_vs_sig <- extract_significant_genes(
    inst_vs_tables,
    excel=glue::glue("excel/instilled_vs_sig-v{ver}.xlsx"))
pp(file="images/pbst_vs_instilled_de_volcano.pdf",
   image=inst_vs_tables[["plots"]][["PBST_vs_Instilled"]][["deseq_vol_plots"]][["plot"]])

12 Check mouse counts

mm_expt <- create_expt("sample_sheets/all_samples_modified2.xlsx",
                       gene_info=pa14_annot, file_column="mousetable")
## Reading the sample metadata.
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## The sample definitions comprises: 105 rows(samples) and 32 columns(metadata fields).
## Warning in create_expt("sample_sheets/all_samples_modified2.xlsx", gene_info
## = pa14_annot, : Some samples were removed when cross referencing the samples
## against the count data.
## Warning in create_expt("sample_sheets/all_samples_modified2.xlsx", gene_info =
## pa14_annot, : Even after changing the rownames in gene info, they do not match
## the count table.
## Even after changing the rownames in gene info, they do not match the count table.
## Here are the first few rownames from the count tables:
## gene:ENSMUSG00000000001, gene:ENSMUSG00000000003, gene:ENSMUSG00000000028, gene:ENSMUSG00000000037, gene:ENSMUSG00000000049, gene:ENSMUSG00000000056
## Here are the first few rownames from the gene information table:
## gene1650835, gene1650837, gene1650839, gene1650841, gene1650843, gene1650845
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
## Warning in create_expt("sample_sheets/all_samples_modified2.xlsx", gene_info =
## pa14_annot, : The following samples have no counts! SM029SM032SM038SM040
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 25753 features and 35 samples.
plot_libsize(mm_expt)$plot
## Warning: Transformation introduced infinite values in continuous y-axis
## Warning: Transformation introduced infinite values in continuous y-axis
## Warning: Removed 4 rows containing missing values (geom_bar).

13 Fun with circos

control_table <- mc_tables[["data"]][["LB05Murea_vs_LB"]]
urine_eda <- mss_urine_table[["data"]][["eda_vs_wt"]]
urine_edd <- mss_urine_table[["data"]][["edd_vs_wt"]]
urine_gcd <- mss_urine_table[["data"]][["gcd_vs_wt"]]
urine_pgl <- mss_urine_table[["data"]][["pgl_vs_wt"]]
urine_zfw <- mss_urine_table[["data"]][["zfw_vs_wt"]]

exudate_eda <- exudate_tables[["data"]][["eda_vs_wt"]]
exudate_edd <- exudate_tables[["data"]][["edd_vs_wt"]]
exudate_gcd <- exudate_tables[["data"]][["gcd_vs_wt"]]
exudate_pgl <- exudate_tables[["data"]][["pgl_vs_wt"]]
exudate_zfw <- exudate_tables[["data"]][["zfw_vs_wt"]]

pa14_annot[["chromosome"]] <- "Pseudomonas_aeruginosa_UCBPP_PA14"

sm_cfg <- circos_prefix(pa14_annot, name="sm", cog_column = "COGFun",
                        start_column="start.x", end_column="end", strand_column="strand.x",
                        chr_column="chromosome", id_column="gene_id")
## This assumes you have a colors.conf in circos/colors/ and fonts.conf in circos/fonts/
## It also assumes you have conf/ideogram.conf, conf/ticks.conf, and conf/housekeeping.conf
## It will write circos/conf/sm.conf with a reasonable first approximation config file.
## Wrote karyotype to circos/conf/ideograms/sm.conf
## This should match the ideogram= line in sm.conf
## Wrote ticks to circos/conf/ticks_sm.conf
sm_kary <- circos_karyotype(sm_cfg, fasta="reference/paeruginosah_pa14.fasta")
## Error in .Call2("new_input_filexp", filepath, PACKAGE = "XVector"): cannot open file 'reference/paeruginosah_pa14.fasta'
sm_plus_minus <- circos_plus_minus(sm_cfg, width=0.06, thickness=40)
## Writing data file: circos/data/sm_plus_go.txt with the + strand GO data.
## Writing data file: circos/data/sm_minus_go.txt with the - strand GO data.
## Wrote the +/- config files.  Appending their inclusion to the master file.
## Returning the inner width: 0.88.  Use it as the outer for the next ring.
## Put the plots here
sm_first_heat <- circos_heatmap(sm_cfg, control_table, colname="deseq_logfc",
                                basename="control", outer=sm_plus_minus, width=0.05)
## Assuming the input is a dataframe.
## Writing data file: circos/data/smdeseq_logfc_heatmap.txt with the controldeseq_logfc column.
## Returning the inner width: 0.81.  Use it as the outer for the next ring.
##sm_eda_hist <- circos_hist(sm_cfg, urine_eda, colname="deseq_logfc",
##                           basename="ureda", outer=sm_first_hist, spacing=-0.05)
##sm_edd_hist <- circos_hist(sm_cfg, urine_edd, colname="deseq_logfc",
##                           basename="uredd", outer=sm_eda_hist, spacing=-0.05)
##sm_gcd_hist <- circos_hist(sm_cfg, urine_gcd, colname="deseq_logfc",
##                           basename="urgcd", outer=sm_edd_hist, spacing=-0.05)
##sm_pgl_hist <- circos_hist(sm_cfg, urine_pgl, colname="deseq_logfc",
##                           basename="urpgl", outer=sm_gcd_hist, spacing=-0.05)
##sm_zfw_hist <- circos_hist(sm_cfg, urine_zfw, colname="deseq_logfc",
##                           basename="urzfw", outer=sm_pgl_hist, spacing=-0.05)
##ex_eda_hist <- circos_hist(sm_cfg, exudate_eda, colname="deseq_logfc",
##                           basename="exeda", outer=sm_zfw_hist, spacing=-0.05)
##ex_edd_hist <- circos_hist(sm_cfg, exudate_edd, colname="deseq_logfc",
##                           basename="exedd", outer=ex_eda_hist, spacing=-0.05)
##ex_gcd_hist <- circos_hist(sm_cfg, exudate_gcd, colname="deseq_logfc",
##                           basename="exgcd", outer=ex_edd_hist, spacing=-0.05)
##ex_pgl_hist <- circos_hist(sm_cfg, exudate_pgl, colname="deseq_logfc",
##                           basename="expgl", outer=ex_gcd_hist, spacing=-0.05)
##ex_zfw_hist <- circos_hist(sm_cfg, exudate_zfw, colname="deseq_logfc",
##                           basename="exzfw", outer=ex_pgl_hist, spacing=-0.05)
sm_finish <- circos_suffix(sm_cfg)
sm_made <- circos_make(sm_cfg, target="sm")
pander::pander(sessionInfo())
message(paste0("This is hpgltools commit: ", get_git_commit()))
this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
message(paste0("Saving to ", this_save))
tmp <- sm(saveme(filename=this_save))
LS0tCnRpdGxlOiAiRUQgUHJvamVjdDogUHNldWRvbW9uYXMgUk5BU2VxIGRhdGFzZXQuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB3aWR0aDogMzAwCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCiAgQmlvY1N0eWxlOjpodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgZmlnX2hlaWdodDogNwogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KYm9keSwgdGQgewogIGZvbnQtc2l6ZTogMTZweDsKfQpjb2RlLnJ7CiAgZm9udC1zaXplOiAxNnB4Owp9CnByZSB7CiAgZm9udC1zaXplOiAxNnB4Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoImhwZ2x0b29scyIpCnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldCh3aWR0aD0xMjAsCiAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHM9NCwKICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplPTEwKSkKcnVuZGF0ZSA8LSBmb3JtYXQoU3lzLkRhdGUoKSwgZm9ybWF0PSIlWSVtJWQiKQpwcmV2aW91c19maWxlIDwtICIiCnZlciA8LSBmb3JtYXQoU3lzLkRhdGUoKSwgIiVZJW0lZCIpCgojI3RtcCA8LSBzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkKcm1kX2ZpbGUgPC0gImluZGV4X3NtLlJtZCIKYGBgCgojIEludHJvZHVjdGlvbgoKVGhpcyBkYXRhc2V0IGNvbnRhaW5zIG11bHRpcGxlIGV4cGVyaW1lbnRzLgoKIyBBbm5vdGF0aW9ucwoKYGBge3IgYW5ub3RhdGlvbn0KcGExNF9nZmYgPC0gbG9hZF9nZmZfYW5ub3RhdGlvbnMoInJlZmVyZW5jZS9wYWVydWdpbm9zYV9wYTE0LmdmZiIsIGlkX2NvbD0iZ2VuZV9pZCIpCnJvd25hbWVzKHBhMTRfZ2ZmKSA8LSBwYTE0X2dmZltbImdlbmVfaWQiXV0KIyMgVGhlIEFsaWFzIGNvbHVtbiBoYXMgUEExNF8wMDAxMAoKcGExNF9taWNyb2JlcyA8LSBhcy5kYXRhLmZyYW1lKGxvYWRfbWljcm9iZXNvbmxpbmVfYW5ub3RhdGlvbnMoIlBBMTQiKSkKIyMgVGhlIHN5c05hbWUgY29sdW1uIGhhcyBQQTE0XzAwMTAKCnBhMTRfYW5ub3QgPC0gbWVyZ2UocGExNF9nZmYsIHBhMTRfbWljcm9iZXMsIGJ5Lng9IkFsaWFzIiwgYnkueT0ic3lzTmFtZSIpCnJvd25hbWVzKHBhMTRfYW5ub3QpIDwtIHBhMTRfYW5ub3RbWyJnZW5lX2lkIl1dCgojIyBUaGUgaWRlbnRpZmllcnMgYXJlIGEgYml0IG9kZCwgc28gd2UgbmVlZCB0byBkbyBhIGxpdHRsZSB3b3JrCnBhMTRfbGVuZ3RoIDwtIHBhMTRfYW5ub3RbLCBjKCJnZW5lX2lkIiwgIndpZHRoIiwgIkFsaWFzIildCnBhMTRfZ28gPC0gbG9hZF9taWNyb2Jlc29ubGluZV9nbyhzcGVjaWVzPSJQQTE0IiwgaWRfY29sdW1uPSJzeXNOYW1lIikKcGExNF9nb19sZW5ndGggPC0gbWVyZ2UocGExNF9nbywgcGExNF9sZW5ndGgsIGJ5Lng9InN5c05hbWUiLCBieS55PSJBbGlhcyIpCnBhMTRfZ28gPC0gcGExNF9nb19sZW5ndGhbLCBjKCJnZW5lX2lkIiwgIkdPIildCmNvbG5hbWVzKHBhMTRfZ28pIDwtIGMoIklEIiwgIkdPIikKcGExNF9sZW5ndGggPC0gcGExNF9nb19sZW5ndGhbLCBjKCJnZW5lX2lkIiwgIndpZHRoIildCnBhMTRfbGVuZ3RoX2lkcyA8LSB1bmlxdWUocGExNF9sZW5ndGgpW1siZ2VuZV9pZCJdXQpwYTE0X2xlbmd0aCA8LSBwYTE0X2xlbmd0aFtwYTE0X2xlbmd0aF9pZHMsIF0Kcm93bmFtZXMocGExNF9sZW5ndGgpIDwtIG1ha2UubmFtZXMocGExNF9sZW5ndGhbWyJnZW5lX2lkIl1dLCB1bmlxdWU9VFJVRSkKY29sbmFtZXMocGExNF9sZW5ndGgpIDwtIGMoIklEIiwgIndpZHRoIikKYGBgCgojIE1ha2UgdGhlIGV4cHJlc3Npb25zZXQKCkdpdmVuIHRoZSBhYm92ZSBhbm5vdGF0aW9ucywgbm93IGxldHMgcHVsbCBpbiB0aGUgY291bnRzLgoKSSBhbSBzd2l0Y2hpbmcgdG8gdGhlIHNoZWV0IGFsbF9zYW1wbGVzX21vZGlmaWVkX2djZC54bHN4IGZvciB0aGUKbW9tZW50IGJlY2F1c2UgSSBhZGRlZCBhIHNwYWNlIGluIHRoZSBzdHJhaW4gbmFtZSBmb3IgdGhlIGdjZCBzYW1wbAoKYGBge3IgZXhwcmVzc2lvbnNldH0KcGExNF9leHB0IDwtIGNyZWF0ZV9leHB0KCJzYW1wbGVfc2hlZXRzL2FsbF9zYW1wbGVzX21vZGlmaWVkX2djZF8yMDIyMDYueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lX2luZm89cGExNF9hbm5vdCwgZmlsZV9jb2x1bW49Imhpc2F0Y291bnR0YWJsZXJldmVyc2UiKQpgYGAKCgojIFF1aWNrIGdsb2JhbCBsb29rIGF0IHRoZSBkYXRhCgpXaGlsZSB3ZSBhcmUgYXQgaXQsIGxldHMgZHJvcCB0aGUgdHdvIHNhZCBzYW1wbGVzLgoKYGBge3IgbWV0cmljc30KcGExNF9saWJzaXplIDwtIHBsb3RfbGlic2l6ZShwYTE0X2V4cHQpCnBhMTRfbGlic2l6ZSRwbG90CgpwYTE0X25vbnplcm8gPC0gcGxvdF9ub256ZXJvKHBhMTRfZXhwdCkKcGExNF9ub256ZXJvJHBsb3QKCnBhMTRfZXhwdCA8LSBzdWJzZXRfZXhwdChwYTE0X2V4cHQsIG5vbnplcm89NTUwMCkKYGBgCgojIyBBIGZldyBxdWVyaWVzCgpJIGtub3cgYSBwcmlvcmkgdGhhdCBBcHJpbCBpcyBpbnRlcmVzdGVkIHRvIHNlZSBob3cgdGhlIDQgbGlicmFyeQpwcmVwYXJhdGlvbnMgbG9vayB3aXRoIHJlc3BlY3QgdG8gZWFjaCBvdGhlci4gIExldCB1cyB0aGVyZWZvcmUgY3JlYXRlCmEgZGF0YSBzdHJ1Y3R1cmUgdG8gbG9vayBleHBsaWNpdGx5IGF0IHRoYXQuCgpgYGB7ciBsaWJwcmVwfQpwYTE0X2xpYnByZXAgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhwYTE0X2V4cHQsIGZhY3Q9ImxpYnJhcnlwcmVwYmF0Y2giKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3Q9Im9yZ2FuaXNtcyIpCgpwYTE0X2xpYl9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHBhMTRfbGlicHJlcCwgZmlsdGVyPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiLCB0cmFuc2Zvcm09ImxvZzIiKQpwbG90X3BjYShwYTE0X2xpYl9ub3JtKSRwbG90CnBsb3RfY29yaGVhdChwYTE0X2xpYl9ub3JtKSRwbG90CgpsaWJwcmVwX3BjYV9pbmZvIDwtIHBjYV9pbmZvcm1hdGlvbigKICAgIHBhMTRfbGliX25vcm0sIHBsb3RfcGNhcz1UUlVFLAogICAgZXhwdF9mYWN0b3JzPWMoImxpYnJhcnlwcmVwYmF0Y2giLCAib3JnYW5pc21zIiwgInN0cmFpbnMiLCAibWVkaWEiLCAiYmlvcmVwbGljYXRlIikpCmxpYnByZXBfcGNhX2luZm8kYW5vdmFfZl9oZWF0bWFwCmxpYnByZXBfcGNhX2luZm8kcGNhX3Bsb3RzW1syXV0KbGlicHJlcF9wY2FfaW5mbyRwY2FfcGxvdHNbWzNdXQpsaWJwcmVwX3BjYV9pbmZvJHBjYV9wbG90c1tbNF1dCmxpYnByZXBfcGNhX2luZm8kcGNhX3Bsb3RzW1s1XV0KYGBgCgpUbyBteSBleWVzIHRoZXkgbG9vayByZWFzb25hYmx5IG1peGVkLCBzdWdnZXN0aW5nIHRoYXQgbGlicmFyeSBwcmVwCmJhdGNoIGlzIG5vdCBhIGRvbWluYW50IGZhY3RvciBpbiB0aGUgZGF0YS4KCkF0IHRoaXMgcG9pbnQsIEkgYW0gdGhpbmtpbmcgdGhhdCB3ZSBzaG91bGQgc2VwYXJhdGUgdGhlIGRhdGEgYnkgdGhlCmV4cGVyaW1lbnRzLCBidXQgSSB3aWxsIGZpcnN0IGp1c3Qgc2hvdyB0aGUgcmVsYXRpb25zaGlwcyBhbW9uZyBhbGwKdGhlIGRhdGEuCgojIExvb2tpbmcgYXQgb3RoZXIgZmFjdG9ycwoKQXMgZmFyIGFzIEkgc2VlLCB0aGVyZSBhcmUgdGhyZWUgZmFjdG9ycyB3aGljaCBhcmUgb2YgcHJpbWFyeQppbnRlcmVzdDoKCjEuIFBBMTQgc3RyYWluCjIuIE1lZGlhIHVzZWQKMy4gQmlvcmVwbGljYXRlCgpUaGUgbGFzdCB3aWxsIGJlIHVzZWQgYXMgYmF0Y2ggaW4gdGhlIGZvbGxvd2luZyBwbG90cy4KCmBgYHtyIG90aGVyX2ZhY3RvcnN9CnBhMTRfbWVkaWEgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhwYTE0X2V4cHQsIGZhY3Q9Im1lZGlhIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0PSJiaW9yZXBsaWNhdGUiKQpwYTE0X21lZGlhX25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGExNF9tZWRpYSwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIpCnBsb3RfcGNhKHBhMTRfbWVkaWFfbm9ybSkkcGxvdAoKcGExNF9zdHJhaW5zIDwtIHNldF9leHB0X2NvbmRpdGlvbnMocGExNF9leHB0LCBmYWN0PSJzdHJhaW5zIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0PSJiaW9yZXBsaWNhdGUiKQpwYTE0X3N0cmFpbnNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChwYTE0X3N0cmFpbnMsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9VFJVRSwgbm9ybT0icXVhbnQiKQpwbG90X3BjYShwYTE0X3N0cmFpbnNfbm9ybSkkcGxvdApgYGAKCkRpc3JlZ2FyZGluZyB0aGUgdmFyaW91cyBleHBlcmltZW50cyBwZXJmb3JtZWQsIEkgdGhpbmsgd2UgY2FuIHN0YXRlCnRoYXQgbWVkaWEgc2VwYXJhdGVzIHRoZSBkYXRhIGluIGEgZmFzaGlvbiB3aGljaCBpcyBtb3JlIGludGVyZXN0aW5nCnRoYW4gc3RyYWluLiAgR2l2ZW4gdGhlIG51bWJlciBvZiAod2hhdCBJIGFzc3VtZSBhcmUpIGNsb3NlbHkgcmVsYXRlZApzdHJhaW5zLCBJIGFtIHRoaW5raW5nIGl0IG1pZ2h0IHByb3ZlIHRvIGJlIGEgZ29vZCBpZGVhIHRvIHBlcmZvcm0gbXkKdmFyaWFudCBzZWFyY2ggdG9vbCBvbiB0aGlzIGRhdGEgYW5kIHNlZSBob3cgd2VsbCB0aGV5IGhlbGQgdXAgd2l0aApyZXNwZWN0IHRvIHRoZSByZWZlcmVuY2Ugc3RyYWluLgoKIyBTZXBhcmF0ZSB0aGUgZXhwZXJpbWVudHMKCkkgaGF2ZSBiZWVuIHRvbGQgcmVwZWF0ZWRseSB0aGF0IHRoZXJlIGFyZSBtdWx0aXBsZSBleHBlcmltZW50cyBpbgp0aGlzIGRhdGEsIGJ1dCBhcHBhcmVudGx5IEkgaGF2ZSBub3QgcGFpZCBwcm9wZXIgYXR0ZW50aW9uIGJlY2F1c2UgSQpjYW5ub3QgcmVtZW1iZXIgd2hpY2ggaXMgd2hpY2gsIGFuZCB0byBteSBleWVzIGl0IGlzIG5vdCBvYnZpb3VzIGluCnRoZSBzYW1wbGUgc2hlZXQuCgpXaXRoIHRoaXMgaW4gbWluZCwgSSBzcG9rZSB3aXRoIFNvbG9tb24gYnJpZWZseSBhbmQgaGF2ZSBhbiBpZGVhIG9mCnRoZSAzIGxvZ2ljYWwgZ3JvdXBzIGluIGhpcyBkYXRhLiAgTGV0IHVzIHRoZXJlZm9yZSBzZXBhcmF0ZSBhbmQKZXhhbWluZSB0aG9zZSBmaXJzdC4KCiMjIE1ldGFib2xpc20gYW5kIGluZmVjdGlvbgoKRm9yIHRoZSBtb21lbnQsIEkgYW0gZ29pbmcgdG8gY2FsbCBTb2xvbW9uJ3Mgc2FtcGxlcyAnbWV0YWJvbGlzbSBhbmQKaW5mZWN0aW9uLicgIEkgd2lsbCBhbHNvIGNvbXBsaWNhdGUgdGhlICdjb25kaXRpb24nIG9mIHRoZSBkYXRhIGJ5CmNvbWJpbmluZyB0aGUgbWVkaWEgYW5kIHN0cmFpbiwgYnV0IHNob3J0bHkgdGhlcmVhZnRlciB3aWxsIHNwbGl0IHRoYXQKYmFjay4gIEkgdGhpbmsgdGhlIHJlYXNvbiB3aHkgd2lsbCBiZWNvbWUgY2xlYXIuCgpgYGB7ciBtZXRhYm9saXNtfQppbml0aWFsc19mYWN0b3IgPC0gZ3N1Yih4PXJvd25hbWVzKHBEYXRhKHBhMTRfZXhwdCkpLCBwYXR0ZXJuPSJeKC4uKS4qJCIsIHJlcGxhY2VtZW50PSJcXDEiKQpwRGF0YShwYTE0X2V4cHQpW1siaW5pdGlhbHMiXV0gPC0gYXMuZmFjdG9yKGluaXRpYWxzX2ZhY3RvcikKc3RyYWluX21lZGlhIDwtIHBhc3RlMChwRGF0YShwYTE0X2V4cHQpW1sic3RyYWlucyJdXSwgIl8iLAogICAgICAgICAgICAgICAgICAgICAgIHBEYXRhKHBhMTRfZXhwdClbWyJtZWRpYSJdXSkKcERhdGEocGExNF9leHB0KVtbInN0cmFpbl9tZWRpYSJdXSA8LSBzdHJhaW5fbWVkaWEKCiMjIExldHMgc2V0IHNvbWUgY29sb3JzCiMjIFdUOiBncmF5c2NhbGUsIGVkYTogYmx1ZSwgZWRkOiBncmVlbiwgZ2NkOiBwdXJwbGUsIHBnbDogcmVkLCB6d2Y6IHllbGxvdwpjb2xvcnNfYnlfc3RyYWluIDwtIGxpc3QoCiAgICAiUEExNCBXVCIgPSAiIzAwMDAwMCIsCiAgICAiUEExNCBlZGEiID0gIiMwMDAwZGQiLAogICAgIlBBMTQgZWRkIiA9ICIjMDBkZDAwIiwKICAgICJQQTE0IGdjZCIgPSAiI2RkMDBkZCIsCiAgICAiUEExNCBwZ2wiID0gIiNkZDAwMDAiLAogICAgIlBBMTQgendmIiA9ICIjZGRkZDAwIikKCmluZmVjdF9tZXRhYm9saXNtIDwtIHN1YnNldF9leHB0KHBhMTRfZXhwdCwgc3Vic2V0PSJpbml0aWFscz09J1NNJyIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdD0ic3RyYWlucyIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdD0ibWVkaWEiKQpwbG90X2xlZ2VuZChpbmZlY3RfbWV0YWJvbGlzbSkkcGxvdAoKd3JpdHRlbiA8LSB3cml0ZV9leHB0KGluZmVjdF9tZXRhYm9saXNtLCBleGNlbD0iZXhjZWwvcGExNF9zbV93cml0dGVuLnhsc3giKQoKbWV0YWJvbGlzbV9jb250cm9sIDwtIHN1YnNldF9leHB0KGluZmVjdF9tZXRhYm9saXNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2V0PSJtZWRpYT09J0xCJ3xtZWRpYT09J0xCICsgMC41IE0gdXJlYSciKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3Q9Im1lZGlhIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcygiYmlvcmVwbGljYXRlIikKCm1ldGFib2xpc21fc3RhcnZhdGlvbiA8LSBzdWJzZXRfZXhwdChpbmZlY3RfbWV0YWJvbGlzbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNldD0ibWVkaWE9PSdQQlNUJ3xtZWRpYT09J1VyaW5lJyIpICU+JQogIHNldF9leHB0X2NvbG9ycyhjb2xvcnM9Y29sb3JzX2J5X3N0cmFpbikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJtZWRpYSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdD0ic3RyYWlucyIpCgptZXRhYm9saXNtX3N0YXJ2YXRpb25fc3RyYWluIDwtIHNldF9leHB0X2NvbmRpdGlvbnMobWV0YWJvbGlzbV9zdGFydmF0aW9uLCBmYWN0PSJzdHJhaW5zIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0PSJtZWRpYSIpCgptZXRhYm9saXNtX2V4dWRhdGUgPC0gc3Vic2V0X2V4cHQoaW5mZWN0X21ldGFib2xpc20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzZXQ9Im1lZGlhPT0nSW5zdGlsbGVkJyIpCmBgYAoKIyMgR2xhbmNlIGF0IHRoZXNlIDQgc3Vic2V0cwoKQXMgYSB3aG9sZSBncm91cCwgdGhlc2Ugc2FtcGxlcyBhcmUgYSBiaXQgY29uZnVzaW5nLiAgVGhlIG1vdXNlCmluc3RpbGVkIHNhbXBsZXMgYXJlIHByZXR5IG9idmlvdXMsIGJ1dCB0aGUgb3RoZXIgc291cmNlcyBvZiB2YXJpYW5jZQpyZW1haW4gYSBiaXQgb2YgYSBteXN0ZXJ5IHRvIG1lLgoKYGBge3IgbWV0YWJvbGlzbV9zdWJzZXRzfQpnbG9iYWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChpbmZlY3RfbWV0YWJvbGlzbSwgZmlsdGVyPVRSVUUsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJtZWRpYSIpCnBsb3RfcGNhKGdsb2JhbF9ub3JtKSRwbG90Cgp0bXAgPC0gZ2xvYmFsX25vcm0gJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJzdHJhaW5zIikKcGxvdF9wY2EodG1wKSRwbG90CmBgYAoKIyBUaGUgc21hbGxlc3QgZXhwZXJpbWVudDogTEIgdnMuIExCK3VyZWEKClRoaXMgaXMgYSBncm91cCBvZiA2IHNhbXBsZXMsIDMgaW4gTEIgYW5kIHRocmVlIGluIExCK3VyZWEuICBUaGlzCnNob3VsZCB0aGVyZWZvcmUgYmUgdGhlIG1vc3Qgc3RyYWlnaHQgZm9yd2FyZCBjb21wYXJpc29uLgoKYGBge3IgY29udHJvbH0KbWNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChtZXRhYm9saXNtX2NvbnRyb2wsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiLCBmaWx0ZXI9VFJVRSkKcGxvdF9wY2EobWNfbm9ybSkkcGxvdApgYGAKCiMjIE1ldGFib2xpc20gY29udHJvbCBleHBlcmltZW50LCBERQoKYGBge3IgbWNfZGV9Cm1jX3NhbiA8LSBzYW5pdGl6ZV9leHB0KG1ldGFib2xpc21fY29udHJvbCkKbWNfZGUgPC0gYWxsX3BhaXJ3aXNlKG1jX3NhbiwgbW9kZWxfYmF0Y2g9VFJVRSwgZmlsdGVyPVRSVUUpCm1jX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIG1jX2RlLAogICAgZXhjZWw9Z2x1ZTo6Z2x1ZSgiZXhjZWwvbWV0YWJvbGlzbV9jb250cm9sX3RhYmxlcy12e3Zlcn0ueGxzeCIpKQptY19zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG1jX3RhYmxlcywKICAgIGV4Y2VsPWdsdWU6OmdsdWUoImV4Y2VsL21ldGFib2xpc21fY29udHJvbF9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIFN0YXJ2aW5nIHN0cmFpbnMKClRoZSBzZWNvbmQgZ3JvdXAgaXMgYSBsaXR0bGUgbW9yZSBjb21wbGV4LCBpdCBzZWVrcyB0byBzaW11bHRhbmVvdXNseQpjb21wYXJlIHRoZSBzdHJhaW5zIChXVCB2cy4gbXV0YW50cykgYW5kIHRoZSBlbnZpcm9ubWVudCAoUEJTCnZzLiB1cmluZSkuCgpUaGlzIGRlc2lnbiBpcyBjb21wbGV4IGVub3VnaCB0aGF0IEkgdGhpbmsgd2UgbmVlZCB0byBjaG9vc2UgY29sb3JzCm1vcmUgY2FyZWZ1bGx5LgoKSGVyZSBpcyBhIHF1ZXJ5IGZyb20gU29sb21vbjoKCkNvdWxkIHlvdSBwbGVhc2UgZ2VuZXJhdGUgbWUgYSB0YWJsZSBmb3IgdGhlIG1ldGFib2xpc20gc3RhcnZhdGlvbiBzdHJhaW4gYW5hbHlzZXMgd2hlcmUKdGhlIHVyaW5lIGlzIHRoZSBudW1lcmF0b3IgYW5kIHRoZSBQQlNUIGlzIHRoZSBkZW5vbWluYXRvcj8KCkkgYW0gaW50ZXJwcmV0aW5nIHRoaXMgdG8gbWVhbiB3ZSBzaG91bGQgaGF2ZSBhbiBleHBlcmltZW50YWwgZGVzaWduIGluIHdoaWNoIHdlIGlnbm9yZSB0aGUgc3RyYWlucwphbmQganVzdCBjb21wYXJlIGFsbCB1cmluZSBhbmQgcGJzdCBzYW1wbGVzLiAgV2hlbiBJIHJhbiB0aGUgZm9sbG93aW5nIGJsb2NrLCBpdCBsb29rcyB0byBtZSB0aGF0CndlIGN1cnJlbnRseSByZXR1cm4gdGhpcyBpbiB0aGUgZm9sbG93aW5nIGJsb2NrOgoKYGBge3Igc3RhcnZpbmdfc3RyYWluc30KbXNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChtZXRhYm9saXNtX3N0YXJ2YXRpb24sIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgdHJhbnNmb3JtPSJsb2cyIikKcGxvdF9wY2EobXNfbm9ybSkkcGxvdAoKbXNfZGUgPC0gYWxsX3BhaXJ3aXNlKG1ldGFib2xpc21fc3RhcnZhdGlvbiwgbW9kZWxfYmF0Y2g9VFJVRSkKbXNfZGUkY29tcGFyaXNvbiRjb21wCm1zX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIG1zX2RlLAogICAgZXhjZWw9Z2x1ZTo6Z2x1ZSgiZXhjZWwvbWV0YWJvbGlzbV9zdGFydmF0aW9uX3RhYmxlcy12e3Zlcn0ueGxzeCIpKQptc19zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcygKICAgIG1zX3RhYmxlcywKICAgIGV4Y2VsPWdsdWU6OmdsdWUoImV4Y2VsL21ldGFib2xpc21fc3RhcnZhdGlvbl9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIE1ldGFib2xpc20gU3RhcnZhdGlvbiBHTwoKYGBge3IgbXNfZ299Cm1zX3VwIDwtIG1zX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJ1cHMiXV1bWzFdXQptc19kb3duIDwtIG1zX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbMV1dCgojIyBUaGUgZ28gZGF0YSBmcm9tIG1pY3JvYmVzb25saW5lIGlzIGtleWVkIGJ5IHRoZSBnZW5lIG5hbWUKIyMgKGUuZy4gZG5hQSksIG5vdCBnZW5lIElEIG9yIFBBIGlkIG9yIHdoYXRldmVyLgpwYTE0X2xlbmd0aHMgPC0gcGExNF9hbm5vdFssIGMoIm5hbWUueCIsICJ3aWR0aCIpXQpjb2xuYW1lcyhwYTE0X2xlbmd0aHMpIDwtIGMoIklEIiwgIndpZHRoIikKCnJvd25hbWVzKG1zX3VwKSA8LSBtYWtlLm5hbWVzKG1zX3VwW1sibmFtZXgiXV0sIHVuaXF1ZT1UUlVFKQptc191cF9nb3NlcSA8LSBzaW1wbGVfZ29zZXEobXNfdXAsIGdvX2RiPXBhMTRfZ28sIGxlbmd0aF9kYj1wYTE0X2xlbmd0aHMpCm1zX3VwX2dvc2VxW1sicHZhbHVlX3Bsb3RzIl1dW1siYnBwX3Bsb3Rfb3ZlciJdXQptc191cF9nb3NlcVtbInB2YWx1ZV9wbG90cyJdXVtbIm1mcF9wbG90X292ZXIiXV0KCnJvd25hbWVzKG1zX2Rvd24pIDwtIG1ha2UubmFtZXMobXNfZG93bltbIm5hbWV4Il1dLCB1bmlxdWU9VFJVRSkKbXNfZG93bl9nb3NlcSA8LSBzaW1wbGVfZ29zZXEobXNfZG93biwgZ29fZGI9cGExNF9nbywgbGVuZ3RoX2RiPXBhMTRfbGVuZ3RocykKbXNfZG93bl9nb3NlcVtbInB2YWx1ZV9wbG90cyJdXVtbImJwcF9wbG90X292ZXIiXV0KbXNfZG93bl9nb3NlcVtbInB2YWx1ZV9wbG90cyJdXVtbIm1mcF9wbG90X292ZXIiXV0KYGBgCgojIyBDb21wYXJlIHN0cmFpbnMKClRoaXMgdGltZSBsZXQgdXMgY29tcGFyZSB0aGUgc3RyYWlucyBhbmQgbG93ZXIgdGhlIHZhcmlhbmNlIGZyb20KbWVkaWEuCgpgYGB7ciBzdGFydmF0aW9uX2J5X3N0cmFpbn0KbXNzX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobWV0YWJvbGlzbV9zdGFydmF0aW9uX3N0cmFpbiwgZmlsdGVyPVRSVUUsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtPSJsb2cyIikKcGxvdF9wY2EobXNzX25vcm0pJHBsb3QKCm1zc191cmluZSA8LSBzdWJzZXRfZXhwdChtZXRhYm9saXNtX3N0YXJ2YXRpb25fc3RyYWluLCBzdWJzZXQ9ImJhdGNoPT0nVXJpbmUnIikKbXNzX3VyaW5lX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobXNzX3VyaW5lLCBmaWx0ZXI9VFJVRSwgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaD0ic3Zhc2VxIiwgdHJhbnNmb3JtPSJsb2cyIikKcGxvdF9wY2EobXNzX3VyaW5lX25vcm0pJHBsb3QKCm1zc19wYnN0IDwtIHN1YnNldF9leHB0KG1ldGFib2xpc21fc3RhcnZhdGlvbl9zdHJhaW4sIHN1YnNldD0iYmF0Y2g9PSdQQlNUJyIpCm1zc19wYnN0X25vcm0gPC0gbm9ybWFsaXplX2V4cHQobXNzX3Bic3QsIGZpbHRlcj1UUlVFLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoPSJzdmFzZXEiLCB0cmFuc2Zvcm09ImxvZzIiKQpwbG90X3BjYShtc3NfcGJzdF9ub3JtKSRwbG90CgppbnRlcmVzdGluZyA8LSBsaXN0KAogICAgImVkYV92c193dCIgPSBjKCJQQTE0ZWRhIiwgIlBBMTRXVCIpLAogICAgImVkZF92c193dCIgPSBjKCJQQTE0ZWRkIiwgIlBBMTRXVCIpLAogICAgImdjZF92c193dCIgPSBjKCJQQTE0Z2NkIiwgIlBBMTRXVCIpLAogICAgInBnbF92c193dCIgPSBjKCJQQTE0cGdsIiwgIlBBMTRXVCIpLAogICAgInpmd192c193dCIgPSBjKCJQQTE0endmIiwgIlBBMTRXVCIpKQptc3NfdXJpbmVfZGUgPC0gYWxsX3BhaXJ3aXNlKG1zc191cmluZSwgbW9kZWxfYmF0Y2g9InN2YXNlcSIsIGZpbHRlcj1UUlVFKQptc3NfdXJpbmVfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBtc3NfdXJpbmVfZGUsIGtlZXBlcnM9aW50ZXJlc3RpbmcsCiAgICBleGNlbD1nbHVlOjpnbHVlKCJleGNlbC9tZXRhYm9saXNtX3N0YXJ2YXRpb25fc3RyYWluX3RhYmxlcy12e3Zlcn0ueGxzeCIpKQptc3NfdXJpbmVfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBtc3NfdXJpbmVfdGFibGUsCiAgICBleGNlbD1nbHVlOjpnbHVlKCJleGNlbC9tZXRhYm9saXNtX3N0YXJ2YXRpb25fc3RyYWluX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCkdpdmVuIHRoYXQgdGhlIHN0cmFpbnMgYXJlIHNvIHNpbWlsYXIsIHdlIGNhbiBjb21mb3J0YWJseSBjb21wYXJlIHRoZW0gYWNyb3NzIG1lZGlhIChQQlNUL3VyaW5lKS4KCmBgYHtyIGNvbXBhcmVfcGJzdF91cmluZX0KbXNtIDwtIHNldF9leHB0X2NvbmRpdGlvbnMobWV0YWJvbGlzbV9zdGFydmF0aW9uX3N0cmFpbiwgZmFjdD0iYmF0Y2giKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3Q9ImJpb3JlcGxpY2F0ZSIpCm1zbV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KG1zbSwgZmlsdGVyPVRSVUUsIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtPSJsb2cyIikKcGxvdF9wY2EobXNtX25vcm0pJHBsb3QKYGBgCgojIEV4dWRhdGUKCkNvbXBhcmUgdGhlIHN0cmFpbnMgZHVyaW5nIHRoZSBpbnN0aWxsYXRpb24gcHJvY2VzcwoKYGBge3IgZXh1ZGF0ZV9leHBlcmltZW50fQpleHVkYXRlX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobWV0YWJvbGlzbV9leHVkYXRlLCBmaWx0ZXI9VFJVRSwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgdHJhbnNmb3JtPSJsb2cyIikKcHAoZmlsZT0iaW1hZ2VzL2NvbXBhcmVfc3RyYWluc19leHVkYXRlLnBkZiIsIGltYWdlPXBsb3RfcGNhKGV4dWRhdGVfbm9ybSkkcGxvdCkKCmV4dWRhdGVfbmIgPC0gbm9ybWFsaXplX2V4cHQobWV0YWJvbGlzbV9leHVkYXRlLCBmaWx0ZXI9VFJVRSwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm09ImxvZzIiLCBiYXRjaD0ic3Zhc2VxIikKcGxvdF9wY2EoZXh1ZGF0ZV9uYikkcGxvdApwcChmaWxlPSJpbWFnZXMvY29tcGFyZV9zdHJhaW5zX2V4dWRhdGVfc3ZhLnBkZiIsIGltYWdlPXBsb3RfcGNhKGV4dWRhdGVfbmIpJHBsb3QpCmBgYAoKIyMgRXh1ZGF0ZSBERQoKYGBge3IgZXh1ZGF0ZV9kZX0KZXh1ZGF0ZV9kZSA8LSBhbGxfcGFpcndpc2UobWV0YWJvbGlzbV9leHVkYXRlLCBtb2RlbF9iYXRjaD1UUlVFLCBmaWx0ZXI9VFJVRSkKCmV4dWRhdGVfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgZXh1ZGF0ZV9kZSwga2VlcGVycz1pbnRlcmVzdGluZywKICAgIGV4Y2VsPWdsdWU6OmdsdWUoImV4Y2VsL2V4dWRhdGVfdGFibGVzLXZ7dmVyfS54bHN4IikpCmV4dWRhdGVfc2lnIDwtIGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoCiAgICBleHVkYXRlX3RhYmxlcywKICAgIGV4Y2VsPWdsdWU6OmdsdWUoImV4Y2VsL2V4dWRhdGVfc2lnLXZ7dmVyfS54bHN4IikpCgp3YW50ZWRfdGFibGUgPC0gZXh1ZGF0ZV90YWJsZXNbWyJkYXRhIl1dW1siZWRhX3ZzX3d0Il1dCmVkYV93dF92b2xjYW5vIDwtIHBsb3Rfdm9sY2Fub19kZSh3YW50ZWRfdGFibGUsIGxvZ2ZjPTIsIGZjX2NvbD0iZGVzZXFfbG9nZmMiLCBwX2NvbD0iZGVzZXFfYWRqcCIpCnBwKGZpbGU9ImltYWdlcy93dF92c19lZGFfZGVfdm9sY2Fub19pbnN0aWxsZWQucGRmIiwKICAgaW1hZ2U9ZWRhX3d0X3ZvbGNhbm8kcGxvdCkKYGBgCgojIEluc3RpbGxlZCB2cy4gUEJTVC9VcmluZQoKVmluY2UgYW5kIE5hamliIGFyZSBpbnRlcmVzdGVkIGluIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHF1ZXN0aW9uOgoKYGBge3IgaW5zdGlsbGVkX3ZzX290aGVyc30KaW5zdGlsbGVkX3ZzIDwtIHN1YnNldF9leHB0KAogICAgcGExNF9leHB0LAogICAgc3Vic2V0PSdtZWRpYT09IlBCU1QifG1lZGlhPT0iVXJpbmUifG1lZGlhPT0iSW5zdGlsbGVkIicpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdD0ibWVkaWEiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3Q9ImJpb3JlcGxpY2F0ZSIpCgppbnN0aWxsZWRfdnNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChpbnN0aWxsZWRfdnMsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpCmluc3RfcGNhIDwtIHBsb3RfcGNhKGluc3RpbGxlZF92c19ub3JtKSRwbG90CnBwKGZpbGU9ImltYWdlcy9pbnN0aWxsZWRfdnNfcGNhLnBkZiIsIGltYWdlPWluc3RfcGNhKQoKaW5zdF92c19kZSA8LSBhbGxfcGFpcndpc2UoaW5zdGlsbGVkX3ZzLCBmaWx0ZXI9VFJVRSkKaW5zdF92c190YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBpbnN0X3ZzX2RlLAogICAgZXhjZWw9Z2x1ZTo6Z2x1ZSgiZXhjZWwvaW5zdGlsbGVkX3ZzX3RhYmxlcy12e3Zlcn0ueGxzeCIpKQppbnN0X3ZzX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogICAgaW5zdF92c190YWJsZXMsCiAgICBleGNlbD1nbHVlOjpnbHVlKCJleGNlbC9pbnN0aWxsZWRfdnNfc2lnLXZ7dmVyfS54bHN4IikpCnBwKGZpbGU9ImltYWdlcy9wYnN0X3ZzX2luc3RpbGxlZF9kZV92b2xjYW5vLnBkZiIsCiAgIGltYWdlPWluc3RfdnNfdGFibGVzW1sicGxvdHMiXV1bWyJQQlNUX3ZzX0luc3RpbGxlZCJdXVtbImRlc2VxX3ZvbF9wbG90cyJdXVtbInBsb3QiXV0pCmBgYAoKIyBDaGVjayBtb3VzZSBjb3VudHMKCmBgYHtyIG1vdXNlX2NvdW50c30KbW1fZXhwdCA8LSBjcmVhdGVfZXhwdCgic2FtcGxlX3NoZWV0cy9hbGxfc2FtcGxlc19tb2RpZmllZDIueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPXBhMTRfYW5ub3QsIGZpbGVfY29sdW1uPSJtb3VzZXRhYmxlIikKcGxvdF9saWJzaXplKG1tX2V4cHQpJHBsb3QKYGBgCgojIEZ1biB3aXRoIGNpcmNvcwoKYGBge3Igc21fY2lyY29zfQpjb250cm9sX3RhYmxlIDwtIG1jX3RhYmxlc1tbImRhdGEiXV1bWyJMQjA1TXVyZWFfdnNfTEIiXV0KdXJpbmVfZWRhIDwtIG1zc191cmluZV90YWJsZVtbImRhdGEiXV1bWyJlZGFfdnNfd3QiXV0KdXJpbmVfZWRkIDwtIG1zc191cmluZV90YWJsZVtbImRhdGEiXV1bWyJlZGRfdnNfd3QiXV0KdXJpbmVfZ2NkIDwtIG1zc191cmluZV90YWJsZVtbImRhdGEiXV1bWyJnY2RfdnNfd3QiXV0KdXJpbmVfcGdsIDwtIG1zc191cmluZV90YWJsZVtbImRhdGEiXV1bWyJwZ2xfdnNfd3QiXV0KdXJpbmVfemZ3IDwtIG1zc191cmluZV90YWJsZVtbImRhdGEiXV1bWyJ6ZndfdnNfd3QiXV0KCmV4dWRhdGVfZWRhIDwtIGV4dWRhdGVfdGFibGVzW1siZGF0YSJdXVtbImVkYV92c193dCJdXQpleHVkYXRlX2VkZCA8LSBleHVkYXRlX3RhYmxlc1tbImRhdGEiXV1bWyJlZGRfdnNfd3QiXV0KZXh1ZGF0ZV9nY2QgPC0gZXh1ZGF0ZV90YWJsZXNbWyJkYXRhIl1dW1siZ2NkX3ZzX3d0Il1dCmV4dWRhdGVfcGdsIDwtIGV4dWRhdGVfdGFibGVzW1siZGF0YSJdXVtbInBnbF92c193dCJdXQpleHVkYXRlX3pmdyA8LSBleHVkYXRlX3RhYmxlc1tbImRhdGEiXV1bWyJ6ZndfdnNfd3QiXV0KCnBhMTRfYW5ub3RbWyJjaHJvbW9zb21lIl1dIDwtICJQc2V1ZG9tb25hc19hZXJ1Z2lub3NhX1VDQlBQX1BBMTQiCgpzbV9jZmcgPC0gY2lyY29zX3ByZWZpeChwYTE0X2Fubm90LCBuYW1lPSJzbSIsIGNvZ19jb2x1bW4gPSAiQ09HRnVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRfY29sdW1uPSJzdGFydC54IiwgZW5kX2NvbHVtbj0iZW5kIiwgc3RyYW5kX2NvbHVtbj0ic3RyYW5kLngiLAogICAgICAgICAgICAgICAgICAgICAgICBjaHJfY29sdW1uPSJjaHJvbW9zb21lIiwgaWRfY29sdW1uPSJnZW5lX2lkIikKc21fa2FyeSA8LSBjaXJjb3Nfa2FyeW90eXBlKHNtX2NmZywgZmFzdGE9InJlZmVyZW5jZS9wYWVydWdpbm9zYWhfcGExNC5mYXN0YSIpCnNtX3BsdXNfbWludXMgPC0gY2lyY29zX3BsdXNfbWludXMoc21fY2ZnLCB3aWR0aD0wLjA2LCB0aGlja25lc3M9NDApCiMjIFB1dCB0aGUgcGxvdHMgaGVyZQpzbV9maXJzdF9oZWF0IDwtIGNpcmNvc19oZWF0bWFwKHNtX2NmZywgY29udHJvbF90YWJsZSwgY29sbmFtZT0iZGVzZXFfbG9nZmMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VuYW1lPSJjb250cm9sIiwgb3V0ZXI9c21fcGx1c19taW51cywgd2lkdGg9MC4wNSkKIyNzbV9lZGFfaGlzdCA8LSBjaXJjb3NfaGlzdChzbV9jZmcsIHVyaW5lX2VkYSwgY29sbmFtZT0iZGVzZXFfbG9nZmMiLAojIyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VuYW1lPSJ1cmVkYSIsIG91dGVyPXNtX2ZpcnN0X2hpc3QsIHNwYWNpbmc9LTAuMDUpCiMjc21fZWRkX2hpc3QgPC0gY2lyY29zX2hpc3Qoc21fY2ZnLCB1cmluZV9lZGQsIGNvbG5hbWU9ImRlc2VxX2xvZ2ZjIiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlbmFtZT0idXJlZGQiLCBvdXRlcj1zbV9lZGFfaGlzdCwgc3BhY2luZz0tMC4wNSkKIyNzbV9nY2RfaGlzdCA8LSBjaXJjb3NfaGlzdChzbV9jZmcsIHVyaW5lX2djZCwgY29sbmFtZT0iZGVzZXFfbG9nZmMiLAojIyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VuYW1lPSJ1cmdjZCIsIG91dGVyPXNtX2VkZF9oaXN0LCBzcGFjaW5nPS0wLjA1KQojI3NtX3BnbF9oaXN0IDwtIGNpcmNvc19oaXN0KHNtX2NmZywgdXJpbmVfcGdsLCBjb2xuYW1lPSJkZXNlcV9sb2dmYyIsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZW5hbWU9InVycGdsIiwgb3V0ZXI9c21fZ2NkX2hpc3QsIHNwYWNpbmc9LTAuMDUpCiMjc21femZ3X2hpc3QgPC0gY2lyY29zX2hpc3Qoc21fY2ZnLCB1cmluZV96ZncsIGNvbG5hbWU9ImRlc2VxX2xvZ2ZjIiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlbmFtZT0idXJ6ZnciLCBvdXRlcj1zbV9wZ2xfaGlzdCwgc3BhY2luZz0tMC4wNSkKIyNleF9lZGFfaGlzdCA8LSBjaXJjb3NfaGlzdChzbV9jZmcsIGV4dWRhdGVfZWRhLCBjb2xuYW1lPSJkZXNlcV9sb2dmYyIsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZW5hbWU9ImV4ZWRhIiwgb3V0ZXI9c21femZ3X2hpc3QsIHNwYWNpbmc9LTAuMDUpCiMjZXhfZWRkX2hpc3QgPC0gY2lyY29zX2hpc3Qoc21fY2ZnLCBleHVkYXRlX2VkZCwgY29sbmFtZT0iZGVzZXFfbG9nZmMiLAojIyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VuYW1lPSJleGVkZCIsIG91dGVyPWV4X2VkYV9oaXN0LCBzcGFjaW5nPS0wLjA1KQojI2V4X2djZF9oaXN0IDwtIGNpcmNvc19oaXN0KHNtX2NmZywgZXh1ZGF0ZV9nY2QsIGNvbG5hbWU9ImRlc2VxX2xvZ2ZjIiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlbmFtZT0iZXhnY2QiLCBvdXRlcj1leF9lZGRfaGlzdCwgc3BhY2luZz0tMC4wNSkKIyNleF9wZ2xfaGlzdCA8LSBjaXJjb3NfaGlzdChzbV9jZmcsIGV4dWRhdGVfcGdsLCBjb2xuYW1lPSJkZXNlcV9sb2dmYyIsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZW5hbWU9ImV4cGdsIiwgb3V0ZXI9ZXhfZ2NkX2hpc3QsIHNwYWNpbmc9LTAuMDUpCiMjZXhfemZ3X2hpc3QgPC0gY2lyY29zX2hpc3Qoc21fY2ZnLCBleHVkYXRlX3pmdywgY29sbmFtZT0iZGVzZXFfbG9nZmMiLAojIyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VuYW1lPSJleHpmdyIsIG91dGVyPWV4X3BnbF9oaXN0LCBzcGFjaW5nPS0wLjA1KQpzbV9maW5pc2ggPC0gY2lyY29zX3N1ZmZpeChzbV9jZmcpCnNtX21hZGUgPC0gY2lyY29zX21ha2Uoc21fY2ZnLCB0YXJnZXQ9InNtIikKYGBgCgpgYGB7ciBzYXZlbWUsIGV2YWw9RkFMU0V9CnBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCm1lc3NhZ2UocGFzdGUwKCJUaGlzIGlzIGhwZ2x0b29scyBjb21taXQ6ICIsIGdldF9naXRfY29tbWl0KCkpKQp0aGlzX3NhdmUgPC0gcGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1ybWRfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKQptZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCnRtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWU9dGhpc19zYXZlKSkKYGBgCg==