1 Datasets

1.1 Code to get matched data

#------------------------------------------------------------------------------
# Datasets
# DNAm data – in file “ROSMAP_QNBMIQ_PCfiltered.RDS” at ~\coMethDMR_metaAnalysis\cohort_ROSMAP\data_final
# RNAseq data – in file “ROSMAP_RNAseq_FPKM_gene_plates_1_to_6_normalized.tsv” and “ROSMAP_RNAseq_FPKM_gene_plates_7_to_8_normalized.tsv”
# at ~\coMethDMR_metaAnalysis\DNAm_RNA
# Link for IDs – in file “ROSMAP_IDkey”, column “mwas_id” is for DNAm data, column “rnaseq_id” is for rnaseq
# Phenotype data:  ~\coMethDMR_metaAnalysis\cohort_ROSMAP\data_final\pheno721_withNeuronProp_df.RDS
#------------------------------------------------------------------------------

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Libraries
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
library(TCGAbiolinks)
library(dplyr)
library(DelayedMatrixStats)
library(GenomicRanges)
devtools::load_all("/Users/jennyzly/coMethDMR/")
devtools::load_all("/Users/jennyzly/Dropbox (BBSR)/PanCancer/methTF/")
library(doParallel)
registerDoParallel(4)

data.path <- "../code_validation/Meta_analysis_code/DATASETS/ROSMAP"
#------------------------------------------------------------------------------
# 1) RNA-SEQ
# Read and add gene name
#------------------------------------------------------------------------------

# retrieve gene information to map from ID to Symbol
gene.info <- TCGAbiolinks::get.GRCh.bioMart("hg19")

exp.plates_1_to_6 <-
    readr::read_tsv("data/ROSMAP_RNAseq_FPKM_gene_plates_1_to_6_normalized.tsv")
exp.plates_1_to_6$geneName <-  gene.info$external_gene_name[match(gsub("\\.[0-9]*", "", exp.plates_1_to_6$gene_id),
                                                                  gene.info$ensembl_gene_id)]

exp.plates_7_to_8 <-
    readr::read_tsv("data/ROSMAP_RNAseq_FPKM_gene_plates_7_to_8_normalized.tsv")
exp.plates_7_to_8$geneName <-
    gene.info$external_gene_name[match(gsub("\\.[0-9]*", "", exp.plates_7_to_8$gene_id),
                                       gene.info$ensembl_gene_id)]

# Merge data
rna.seq <-
    dplyr::full_join(exp.plates_1_to_6, exp.plates_7_to_8) %>%
    as.data.frame()


#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# DNA methylation
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
dnam.file <- dir(
    path = data.path,
    pattern = "ROSMAP_QNBMIQ_PCfiltered.RDS",
    ignore.case = T,
    full.names = T,
    recursive = T
)
dnam.file
dna.met <- readRDS(dnam.file)

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Clinical
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
clinical <-
    readr::read_csv("ROSMAP_clinical.csv", col_types = readr::cols())
pheno.file <- dir(
    path = data.path,
    pattern = "withNeuronProp",
    ignore.case = T,
    full.names = T,
    recursive = T
)
pheno.file
phenotype <- readRDS(pheno.file)

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Map RNA-seq and DNA methylation
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
map <- readr::read_csv("data/ROSMAP_IDkey.csv")
# Only keep samples with DNA methytlation and gene expression
map <- na.omit(unique(map[, c("mwas_id", "rnaseq_id")]))
map <- map[map$mwas_id %in% colnames(dna.met) &
               map$rnaseq_id %in% gsub("_[0-9]$", "", c(colnames(rna.seq))),]
dna.met <-
    dna.met[, colnames(dna.met) %in% map$mwas_id] #  Samples  529

matched.exp <- rna.seq[, c(2,
                           match(map$rnaseq_id, gsub("_[0-9]$", "", c(colnames(
                               rna.seq
                           )))))]

rownames(matched.exp) <- gsub("\\.[0-9]*$", "", matched.exp$gene_id)
matched.exp$gene_id <- NULL
matched.dnam <- dna.met[, match(map$mwas_id, colnames(dna.met))]
matched.phenotype <-
    phenotype[match(map$mwas_id , phenotype$Sample),]

#-----------------  CHECKS   ----------------------
table(is.na(matched.phenotype$Sample))
nrow(matched.phenotype)  == ncol(matched.dnam)
nrow(matched.phenotype)  == ncol(matched.exp)
#-------------------------------------------

matched.phenotype$rnaseq_id  <-
    map$rnaseq_id[match(matched.phenotype$Sample, map$mwas_id)]

#------------------------------------------------------------------------------
# Cell type markers
#------------------------------------------------------------------------------
genes <- c("ENO2", "OLIG2", "CD34", "CD68", "GFAP")
gene.ensg <-
    gene.info$ensembl_gene_id[match(genes, gene.info$external_gene_name)]

cell.type.markers  <-
    matched.exp[match(gene.ensg, rownames(matched.exp)),] %>% t
colnames(cell.type.markers) <- genes

cell.type.markers <-
    cell.type.markers %>% tibble::as_tibble(rownames = "rnaseq_id")

cell.type.markers$Sample <-
    map$mwas_id[match(gsub("_[0-9]$", "", cell.type.markers$rnaseq_id),
                      map$rnaseq_id)]
cell.type.markers <-
    cell.type.markers[!is.na(cell.type.markers$Sample),]
saveRDS(cell.type.markers, file = "data/cell.type.markers.Rds")


save(matched.phenotype,
     matched.dnam,
     matched.exp,
     map,
     file = "data/matched_data.rda")

2 Region analysis

2.1 Get metadata results

meta.analysis.folder <- "../code_validation/Meta_analysis_code/meta_analysis_region_results/"
# focus on significant methylation regions with FDR < 0.05 in file “meta_analysis_ALL_df.csv”
analysis <- readr::read_csv(
  file.path(meta.analysis.folder,"step1_meta_analysis/meta_analysis_ALL_df.csv"),
  col_types = readr::cols()
)

region.analysis <- readr::read_csv(
  file.path(meta.analysis.folder,"step4_dmr_vs_cpgs/meta_analysis_sig_no_crossHyb_smoking_ov_comb_p_with_sig_single_cpgs.csv"),
  col_types = readr::cols()
)

dmr <- region.analysis %>% filter(!is.na(ROSMAP_coMethRegion))
dim(dmr)
## [1] 118  67
dmr.hypo <- region.analysis %>% filter(estimate < 0)
dim(dmr.hypo)
## [1] 31 67
dmr.hyper <- region.analysis %>% filter(estimate > 0)
dim(dmr.hyper)
## [1] 88 67

2.2 Analysis: RNA vs DNAm

For each significant co-methylated region, we looked for genes within \(250Kbp\), removed confounding effects in gene expression and DNA methylation levels, and then correlated DNAm with gene expression with the following model, for cases and controls separately:

\[rna_{residual} \sim met_{residual} \]

2.2.1 Remove confounding effects in DNAm data

\(Median(\text{DNAm m-values in DMR}) \sim celltype.proportion + batch + \text{sample plate} + ageAtDeath + sex => \text{DNAm residuals}\)

file <- "results/ROSMAP.probes.all.meta.analysis.regions.rda"
if(!file.exists(file)){
  regions.name  <- na.omit(results.meta.analysis.region$ROSMAP_coMethRegion) %>% as.character() %>% unique()
  probes.all.regions <- GetCpGsInAllRegion(regions.name, progress = TRUE, nCores_int = 10)
  save(probes.all.regions, file = file)
} else {
  load(file)
}


median.met <- plyr::ldply(
  probes.all.regions[unique(dmr$ROSMAP_coMethRegion)],
  function(probes){
    aux <- colMedians(matched.dnam,rows = rownames(matched.dnam) %in% probes)
    aux
  },
  .progress = "time",
  .parallel = TRUE,
  .inform = TRUE,
  .id = "region" 
)

rownames(median.met) <- median.met$region %>% as.character()
median.met$region <- NULL
colnames(median.met) <- colnames(matched.dnam)

# 1) remove confounding effects in DNAm data: 
resid_met <- GetResiduals(
  dnam = median.met,
  betaToM = TRUE, #converts to Mvalues for fitting linear model 
  pheno_df = matched.phenotype,
  covariates_char = c("Sample_Plate", "prop.neuron", "batch","msex","age_death"), 
  nCores_int = 1,
  progressbar = TRUE  
)

2.2.2 Remove confounding effects in gene expression data

\(log2(RNA) \sim ageAtDeath + sex + \text{markers for cell types} => \text{RNA residuals}\)

matched.exp.log2 <- log2(matched.exp + 1)
markers <-
  t(matched.exp.log2[c(
    "ENSG00000111674",
    "ENSG00000129226",
    "ENSG00000131095",
    "ENSG00000205927",
    "ENSG00000174059"
  ), ])
colnames(markers) <- c("markers_ENO2",
                       "markers_OLIG2",
                       "markers_CD34",
                       "markers_CD68",
                       "markers_GFAP")
matched.phenotype$rnaseq_id  <- map$rnaseq_id[match(matched.phenotype$Sample,map$mwas_id)]
resid_exp <- plyr::adply(.data = matched.exp.log2,
                         .margins = 1, 
                         function(row){
                           val <- t(row)
                           colnames(val) <- "val"
                           dat <- cbind(val, 
                                        matched.phenotype,
                                        markers
                           )
                           dat$val <- as.numeric(dat$val)
                           fitE <- lm("val ~ age_death + msex + markers_ENO2 + markers_OLIG2 + markers_CD34 + markers_CD68 + markers_GFAP", 
                                      data = dat, 
                                      na.action = na.exclude)
                           residuals(fitE)
                         }, .progress = "time",
                         .parallel = TRUE)
rownames(resid_exp) <- rownames(matched.exp.log2)
save(resid_exp,
     resid_met,
     file = "data/residuals.rda")

2.3 Map region to genes +-250kb

The function getDNAm.target will extend the regions \(+-250Kbp\) and return the overlapping genes.

regions.gr <- rownames(resid_met) %>% 
  as.data.frame %>% 
  tidyr::separate(col = ".",into = c("chr","start","end"))  %>%
  makeGRangesFromDataFrame()
names(regions.gr) <- rownames(resid_met)
regions.gr
## GRanges object with 118 ranges and 0 metadata columns:
##                             seqnames              ranges strand
##                                <Rle>           <IRanges>  <Rle>
##     chr19:49220102-49220235    chr19   49220102-49220235      *
##      chr7:27153580-27153847     chr7   27153580-27153847      *
##      chr7:27146237-27146445     chr7   27146237-27146445      *
##      chr7:27154720-27155548     chr7   27154720-27155548      *
##      chr7:27179268-27179432     chr7   27179268-27179432      *
##                         ...      ...                 ...    ...
##      chr6:25042495-25042548     chr6   25042495-25042548      *
##      chr6:32906460-32906734     chr6   32906460-32906734      *
##   chr12:120835663-120835778    chr12 120835663-120835778      *
##     chr22:37608611-37608819    chr22   37608611-37608819      *
##     chr16:87886871-87886933    chr16   87886871-87886933      *
##   -------
##   seqinfo: 22 sequences from an unspecified genome; no seqlengths
# function available in methTF package https://gitlab.com/tiagochst/methtf
regions.genes <- get_region_target_gene(regions.gr = regions.gr,
                                        genome = "hg19",
                                        method = "window",
                                        window.width = 500 * 10 ^ 3) # 500 kb
regions.genes <- regions.genes %>%
  dplyr::filter(regions.genes$gene_ensembl_gene_id %in% rownames(resid_exp))

dim(regions.genes)
## [1] 2054   11
head(regions.genes)

2.4 Target vs DNAm residual

Linear models:

  • For cases (Braak stage 3-6): \(\text{RNA residuals} \sim \text{DNAm residuals}\)
  • For controls (Braak stage 0-2): \(\text{RNA residuals} \sim \text{DNAm residuals}\)
# http://www.r-tutor.com/elementary-statistics/simple-linear-regression/residual-plot
tab <- plyr::adply(
  regions.genes,
  .margins = 1,
  .fun = function(row) {
    tryCatch({
      rna.target <-
        resid_exp[rownames(resid_exp) == row$gene_ensembl_gene_id, , drop = FALSE]
      met.residual <- resid_met[rownames(resid_met) == as.character(row$regionID), ]
      
      df <- data.frame(
        rna.residual = rna.target %>% as.numeric,
        met.residual = met.residual %>% as.numeric,
        Braak_stage = matched.phenotype$braaksc,
        group = ifelse(matched.phenotype$braaksc < 3, "Control", "Case")
      )
      
      # 2) fit linear model to cases and controls seperately:
      # For cases (Braak stage 3-6)
      # RNA_residuals ~ DNAm_residuals
      results.cases <-  lm (
        rna.residual ~ met.residual,
        data = df[df$Braak_stage > 2, ]
      )
      results.cases.pval <- summary(results.cases)$coefficients[-1, 4, drop = F] %>% t %>% as.data.frame()
      results.cases.estimate <- summary(results.cases)$coefficients[-1, 1, drop = F] %>% t %>% as.data.frame()
      colnames(results.cases.pval) <- paste0("cases_pval_", colnames(results.cases.pval))
      colnames(results.cases.estimate) <- paste0("cases_estimate_", colnames(results.cases.estimate))
      
      # For controls (Braak stage 0 -2)
      # RNA_residuals ~ DNAm_residuals
      results.control <- lm (
        rna.residual ~ met.residual,
        data = df[df$Braak_stage < 3, ]
      )
      results.control.pval <- summary(results.control)$coefficients[-1, 4, drop = F] %>% t %>% as.data.frame()
      results.control.estimate <- summary(results.control)$coefficients[-1, 1, drop = F] %>% t %>% as.data.frame()
      colnames(results.control.pval) <- paste0("control_pval_", colnames(results.control.pval))
      colnames(results.control.estimate) <- paste0("control_estimate_", colnames(results.control.estimate))
      
      return(
        data.frame(
          cbind(
            results.cases.pval,
            results.cases.estimate,
            results.control.pval,
            results.control.estimate
          ),
          row.names = NULL,
          stringsAsFactors = FALSE
        ))
    }, error = function(e) {
      print(row)
      return()
    })
  },
  .id = NULL,
  .progress = "time",
  .parallel = TRUE,
  .inform = TRUE
)
readr::write_csv(tab,path = "results/results_regions_lm_250kb_window.csv")

2.4.1 Results

tab <- readr::read_csv("results/results_regions_lm_250kb_window.csv", col_types = readr::cols())
tab$fdr.controls <- p.adjust(tab$control_pval_met.residual,method = "fdr")
tab$fdr.cases <- p.adjust(tab$cases_pval_met.residual,method = "fdr")

output <- tab[,c("regionID","gene_external_gene_name",
                 "cases_estimate_met.residual","cases_pval_met.residual","fdr.cases",
                 "control_estimate_met.residual","control_pval_met.residual","fdr.controls")] 
colnames(output) <- c("coMethDMR",
                      "geneSymbol",
                      "estimate.cases",
                      "pval.cases",
                      "estimate.controls",
                      "pval.controls"
                      )


cols <- c(grep("ROSMAP_coMethRegion",colnames(region.analysis)),
          grep("Relation",colnames(region.analysis)):grep("^smoke_bi$",colnames(region.analysis)))
output2 <- merge(output,
                 region.analysis[,cols],
                 by.x = "coMethDMR", 
                 by.y = "ROSMAP_coMethRegion",
                 all.x = TRUE)
write.csv(output2,file = "results/results_regions_lm_250kb_window_renamed.csv")

3 Single cpg analysis

3.1 Get metadata results

single.cpg.analysis <- readr::read_csv(
  "../code_validation/Meta_analysis_code/meta_analysis_single_cpg_results/meta_analysis_single_cpg_sig_no_crossHyb_smoking_df.csv", 
  col_types = readr::cols()
)

dmc <- single.cpg.analysis %>% filter(!is.na(ROSMAP_pValue))
dim(dmc)
## [1] 3699   32
dmc.hypo <- dmc %>% filter(estimate < 0)
dim(dmc.hypo)
## [1] 1542   32
dmc.hyper <- dmc %>% filter(estimate > 0)
dim(dmc.hyper)
## [1] 2157   32

3.2 Analysis: RNA vs DNAm

For each CpG significantly associated with Braak stage, we looked for genes within \(250Kbp\), removed confounding effects in gene expression and DNA methylation levels, and then correlated residual methylation with gene expression levels with the following model, for cases and controls separately:

\[rna_{residual} \sim met_{residual} \]

3.2.1 Remove confounding effects in DNAm data

\(Median(\text{DNAm m-values in DMR}) \sim celltype.proportion + batch + \text{sample plate} + ageAtDeath + sex => \text{DNAm residuals}\)

# 1) remove confounding effects in DNAm data: 
resid_met_cpg <- GetResiduals(
  dnam = matched.dnam[dmc$cpg,],
  betaToM = TRUE, #converts to Mvalues for fitting linear model 
  pheno_df = matched.phenotype,
  covariates_char = c("Sample_Plate", "prop.neuron", "batch","msex","age_death"), 
  nCores_int = 1,
  progressbar = TRUE  
)
save(resid_exp,
     resid_met_cpg,
     file = "data/residuals_cpg.rda")

3.3 Map region to genes +-250kb

The function get_region_target_gene will extend the regions \(+-250Kbp\) and return the overlapping genes.

dmc.gr <- sesameData::sesameDataGet("HM450.hg19.manifest")[dmc$cpg,] 
regions.genes <- get_region_target_gene(
  regions.gr = dmc.gr,
  genome = "hg19",
  method = "window",
  window.width = 500 * 10 ^ 3) # 500 kb

regions.genes <- regions.genes %>%
  dplyr::filter(regions.genes$gene_ensembl_gene_id %in% rownames(resid_exp))
regions.genes$cpg <- names(dmc.gr)[
  match(
    regions.genes$regionID,paste0(as.data.frame(dmc.gr)$seqnames,
                                  ":",
                                  as.data.frame(dmc.gr)$start,"-",as.data.frame(dmc.gr)$end)
  )
  ]

dim(regions.genes)
## [1] 29186    12
head(regions.genes)

3.4 Target vs DNAm residual

Linear models: - For cases (Braak stage 3-6): \(\text{RNA residuals} \sim \text{DNAm residuals}\) - For controls (Braak stage 0-2): \(\text{RNA residuals} \sim \text{DNAm residuals}\)

# http://www.r-tutor.com/elementary-statistics/simple-linear-regression/residual-plot
tab.cpg <- plyr::adply(
  regions.genes,
  .margins = 1,
  .fun = function(row) {
    tryCatch({
      rna.target <-
        resid_exp[rownames(resid_exp) == row$gene_ensembl_gene_id, , drop = FALSE]
      met.residual <-
        resid_met_cpg[rownames(resid_met_cpg) == as.character(row$cpg), ]
      
      df <-
        data.frame(
          rna.residual = rna.target %>% as.numeric,
          met.residual = met.residual %>% as.numeric,
          Braak_stage = matched.phenotype$braaksc,
          group = ifelse(matched.phenotype$braaksc < 3, "Control", "Case")
        )
      
      # 2) fit linear model to cases and controls seperately:
      # For cases (Braak stage 3-6)
      #  RNA_residuals ~ DNAm_residuals
      results.cases <-
        lm (
          rna.residual ~ met.residual,
          data = df[df$Braak_stage > 2, ]
        )
      results.cases.pval <-
        summary(results.cases)$coefficients[-1, 4, drop = F] %>% t %>% as.data.frame()
      results.cases.estimate <-
        summary(results.cases)$coefficients[-1, 1, drop = F] %>% t %>% as.data.frame()
      colnames(results.cases.pval) <-
        paste0("cases_pval_", colnames(results.cases.pval))
      colnames(results.cases.estimate) <-
        paste0("cases_estimate_", colnames(results.cases.estimate))
      
      # For controls (Braak stage 0 -2)
      #  RNA_residuals ~ DNAm_residuals
      results.control <-
        lm (
          rna.residual ~ met.residual,
          data = df[df$Braak_stage < 3, ]
        )
      results.control.pval <-
        summary(results.control)$coefficients[-1, 4, drop = F] %>% t %>% as.data.frame()
      results.control.estimate <-
        summary(results.control)$coefficients[-1, 1, drop = F] %>% t %>% as.data.frame()
      colnames(results.control.pval) <-
        paste0("control_pval_", colnames(results.control.pval))
      colnames(results.control.estimate) <-
        paste0("control_estimate_", colnames(results.control.estimate))
      
      
      return(
        data.frame(
          cbind(
            results.cases.pval,
            results.cases.estimate,
            results.control.pval,
            results.control.estimate
          ),
          row.names = NULL,
          stringsAsFactors = FALSE
        ))
    }, error = function(e) {
      print(row)
      return()
    })
  },
  .id = NULL,
  .progress = "time",
  .parallel = TRUE,
  .inform = TRUE
)
readr::write_csv(tab.cpg,path = "results/results_single_cpg_lm_250kb_window.csv")

3.4.1 Results

tab.cpg <- readr::read_csv("results/results_single_cpg_lm_250kb_window.csv", col_types = readr::cols())
tab.cpg$fdr.controls <- p.adjust(tab.cpg$control_pval_met.residual,method = "fdr")
tab.cpg$fdr.cases <- p.adjust(tab.cpg$cases_pval_met.residual,method = "fdr")

output <- tab.cpg[,c("cpg","gene_external_gene_name",
                     "cases_estimate_met.residual","cases_pval_met.residual","fdr.cases",
                     "control_estimate_met.residual","control_pval_met.residual","fdr.controls")] 
colnames(output) <- c("cpg",
                      "geneSymbol",
                      "estimate.cases",
                      "pval.cases",
                      "estimate.controls",
                      "pval.controls"
)
write.csv(output,file = "results/results_single_cpg_lm_250kb_window_renamed.csv")

4 Splitting results by group

4.1 DMRs

dmr <- read.csv(
  "results/results_regions_lm_250kb_window_renamed.csv"
)
pathDropbox <- file.path(dir("~", pattern = "Dropbox", full.names = TRUE))
dmr_meta <- read.csv(
  file.path(pathDropbox,
            "coMethDMR_metaAnalysis/",
            "code_validation/Meta_analysis_code/meta_analysis_region_results",
            "/step4_dmr_vs_cpgs/meta_analysis_sig_no_crossHyb_smoking_ov_comb_p_with_all.csv")
)[, c("ROSMAP_coMethRegion",
      "GREAT_annotation",
      "UCSC_RefGene_Group",
      "UCSC_RefGene_Accession",
      "UCSC_RefGene_Name",
      "state")
  ]

dmr.annot <- merge(
  dmr, dmr_meta,
  by.x = "coMethDMR",
  by.y = "ROSMAP_coMethRegion",
  sort = FALSE
)

dmr.annot <- dmr.annot[, c(1,3:9,21:24,10,25,11:18)]
write.csv(
  dmr.annot,
  "results_regions_lm_250kb_window_renamed_with_annot.csv"
)
dmr_case <- dmr.annot %>%
  group_by(coMethDMR) %>%
  filter(pval.cases == min(pval.cases)) %>%
  as.data.frame()

dmr_case$fdr.cases.adjusted <- p.adjust(
  dmr_case$pval.cases, method = "fdr"
)

dmr_case <- dmr_case[,c(1:4, 23,9:22)]
dmr_case
write.csv(
  dmr_case,
  "results_regions_lm_250kb_window_renamed_mostSigCases.csv",
  row.names = FALSE
)
dmr_control <- dmr.annot %>%
  group_by(coMethDMR) %>%
  filter(pval.controls == min(pval.controls)) %>%
  as.data.frame()
dmr_control$fdr.controls.adjusted <- p.adjust(
  dmr_control$pval.controls, method = "fdr"
)
dmr_control <- dmr_control[,c(1:2, 6:7, 23,9:22)]
dmr_control
write.csv(
  dmr_control,
  "results_regions_lm_250kb_window_renamed_mostSigControls.csv",
  row.names = FALSE
)

4.2 CpGs

cpg <- read.csv(
  "results/results_single_cpg_lm_250kb_window_renamed.csv"
)
cpg_meta <- read.csv(
    file.path(pathDropbox,
            "coMethDMR_metaAnalysis/",
            "code_validation/Meta_analysis_code/meta_analysis_single_cpg_results/",
            "/meta_analysis_single_cpg_sig_no_crossHyb_smoking_with_state_greatAnnot_df.csv")
)[, c("cpg",
      "GREAT_annotation",
      "UCSC_RefGene_Group",
      "UCSC_RefGene_Accession",
      "UCSC_RefGene_Name",
      "Relation_to_Island",
      "state",
      "estimate", 
      "se", 
      "pVal.fixed", 
      "pVal.random",
      "pValQ", 
      "direction", 
      "pVal.final", 
      "fdr")
  ]

cpg.annot <- merge(
  cpg, cpg_meta,
  by = "cpg",
  sort = FALSE
) %>%
  select(-X)
cpg.annot
write.csv(
  cpg.annot,
  "results_single_cpg_lm_250kb_window_renamed_with_annot.csv"
)
cpg_case <- cpg.annot %>%
  group_by(cpg) %>%
  filter(pval.cases == min(pval.cases)) %>%
  as.data.frame()

cpg_case$fdr.cases.adjusted <- p.adjust(
  cpg_case$pval.cases, method = "fdr"
)
cpg_case <- cpg_case[, c(1:4, 25, 15,17:24)]
cpg_case
write.csv(
  cpg_case,
  "results_single_cpg_lm_250kb_window_renamed_mostSigCases.csv",
  row.names = FALSE
)
cpg_control <- cpg.annot %>%
  group_by(cpg) %>%
  filter(pval.controls == min(pval.controls)) %>%
  distinct(cpg, .keep_all = TRUE) %>%
  as.data.frame()

cpg_control$fdr.controls.adjusted <- p.adjust(
  cpg_control$pval.controls, method = "fdr"
)
cpg_control <- cpg_control[, c(1:2,6:7, 25, 15, 17:24)]
cpg_control
write.csv(
  cpg_control,
  "results_single_cpg_lm_250kb_window_renamed_mostSigControls.csv",
  row.names = FALSE
)

5 Session information

devtools::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                                             
##  version  R Under development (unstable) (2020-02-25 r77857)
##  os       macOS Catalina 10.15.3                            
##  system   x86_64, darwin15.6.0                              
##  ui       X11                                               
##  language (EN)                                              
##  collate  en_US.UTF-8                                       
##  ctype    en_US.UTF-8                                       
##  tz       America/New_York                                  
##  date     2020-04-26                                        
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  ! package                                       * version     date       lib
##    acepack                                         1.4.1       2016-10-29 [1]
##    annotate                                        1.65.1      2020-01-27 [1]
##    AnnotationDbi                                   1.49.1      2020-01-25 [1]
##    AnnotationFilter                                1.11.0      2019-11-06 [1]
##    AnnotationHub                                 * 2.19.11     2020-04-16 [1]
##    aroma.light                                     3.17.1      2019-12-09 [1]
##    askpass                                         1.1         2019-01-13 [1]
##    assertthat                                      0.2.1       2019-03-21 [1]
##    backports                                       1.1.6       2020-04-05 [1]
##    base64                                          2.0         2016-05-10 [1]
##    base64enc                                       0.1-3       2015-07-28 [1]
##    beanplot                                        1.2         2014-09-19 [1]
##    Biobase                                       * 2.47.3      2020-03-16 [1]
##    BiocFileCache                                 * 1.11.6      2020-04-16 [1]
##    BiocGenerics                                  * 0.33.3      2020-03-23 [1]
##    BiocManager                                     1.30.10     2019-11-16 [1]
##    BiocParallel                                    1.21.2      2019-12-21 [1]
##    BiocVersion                                     3.11.1      2019-11-13 [1]
##    biomaRt                                         2.43.5      2020-04-02 [1]
##    Biostrings                                      2.55.7      2020-03-24 [1]
##    biovizBase                                      1.35.1      2019-12-03 [1]
##    bit                                             1.1-15.2    2020-02-10 [1]
##    bit64                                           0.9-7       2017-05-08 [1]
##    bitops                                          1.0-6       2013-08-17 [1]
##    blob                                            1.2.1       2020-01-20 [1]
##    boot                                            1.3-24      2019-12-20 [1]
##    broom                                           0.5.6       2020-04-20 [1]
##    BSgenome                                        1.55.4      2020-03-19 [1]
##    bumphunter                                      1.29.0      2019-11-07 [1]
##    callr                                           3.4.3       2020-03-28 [1]
##    checkmate                                       2.0.0       2020-02-06 [1]
##    circlize                                        0.4.8       2019-09-08 [1]
##    cli                                             2.0.2       2020-02-28 [1]
##    clue                                            0.3-57      2019-02-25 [1]
##    cluster                                         2.1.0       2019-06-19 [1]
##    codetools                                       0.2-16      2018-12-24 [1]
##    colorspace                                      1.4-1       2019-03-18 [1]
##  P coMethDMR                                     * 0.0.0.9001  2020-03-24 [?]
##    ComplexHeatmap                                * 2.3.4       2020-04-02 [1]
##    crayon                                          1.3.4       2017-09-16 [1]
##    curl                                            4.3         2019-12-02 [1]
##    data.table                                      1.12.9      2020-02-26 [1]
##    DBI                                             1.1.0       2019-12-15 [1]
##    dbplyr                                        * 1.4.3       2020-04-19 [1]
##    DelayedArray                                  * 0.13.12     2020-04-10 [1]
##    DelayedMatrixStats                            * 1.9.1       2020-03-30 [1]
##    desc                                            1.2.0       2018-05-01 [1]
##    DESeq                                           1.39.0      2019-11-06 [1]
##    devtools                                        2.3.0       2020-04-10 [1]
##    dichromat                                       2.0-0       2013-01-24 [1]
##    digest                                          0.6.25      2020-02-23 [1]
##    doParallel                                    * 1.0.15      2019-08-02 [1]
##    doRNG                                           1.8.2       2020-01-27 [1]
##    downloader                                      0.4         2015-07-09 [1]
##    dplyr                                         * 0.8.99.9002 2020-04-02 [1]
##    EDASeq                                          2.21.2      2020-03-20 [1]
##    edgeR                                           3.29.1      2020-02-26 [1]
##    ellipsis                                        0.3.0       2019-09-20 [1]
##    ELMER                                           2.11.1      2020-04-20 [1]
##    ELMER.data                                      2.11.0      2019-10-31 [1]
##    ensembldb                                       2.11.4      2020-04-17 [1]
##    evaluate                                        0.14        2019-05-28 [1]
##    ExperimentHub                                 * 1.13.7      2020-04-16 [1]
##    fansi                                           0.4.1       2020-01-08 [1]
##    fastmap                                         1.0.1       2019-10-08 [1]
##    foreach                                       * 1.5.0       2020-03-30 [1]
##    foreign                                         0.8-78      2020-04-13 [1]
##    Formula                                         1.2-3       2018-05-03 [1]
##    fs                                              1.4.1       2020-04-04 [1]
##    genefilter                                      1.69.0      2019-11-06 [1]
##    geneplotter                                     1.65.0      2019-11-06 [1]
##    generics                                        0.0.2       2018-11-29 [1]
##    GenomeInfoDb                                  * 1.23.17     2020-04-13 [1]
##    GenomeInfoDbData                                1.2.3       2020-04-20 [1]
##    GenomicAlignments                               1.23.2      2020-03-24 [1]
##    GenomicFeatures                                 1.39.7      2020-03-19 [1]
##    GenomicRanges                                 * 1.39.3      2020-04-08 [1]
##    GEOquery                                        2.55.1      2019-11-18 [1]
##    GetoptLong                                      0.1.8       2020-01-08 [1]
##    ggplot2                                       * 3.3.0       2020-03-05 [1]
##    ggpubr                                        * 0.2.5       2020-02-13 [1]
##    ggrepel                                         0.8.2       2020-03-08 [1]
##    ggsignif                                        0.6.0       2019-08-08 [1]
##    ggthemes                                        4.2.0       2019-05-13 [1]
##    GlobalOptions                                   0.1.1       2019-09-30 [1]
##    glue                                            1.4.0       2020-04-03 [1]
##    gridExtra                                       2.3         2017-09-09 [1]
##    gtable                                          0.3.0       2019-03-25 [1]
##    Gviz                                            1.31.12     2020-03-05 [1]
##    HDF5Array                                       1.15.18     2020-04-10 [1]
##    Hmisc                                           4.4-0       2020-03-23 [1]
##    hms                                             0.5.3       2020-01-08 [1]
##    htmlTable                                       1.13.3      2019-12-04 [1]
##    htmltools                                       0.4.0       2019-10-04 [1]
##    htmlwidgets                                     1.5.1       2019-10-08 [1]
##    httpuv                                          1.5.2       2019-09-11 [1]
##    httr                                            1.4.1       2019-08-05 [1]
##    hwriter                                         1.3.2       2014-09-10 [1]
##    IlluminaHumanMethylation450kanno.ilmn12.hg19    0.6.0       2020-03-24 [1]
##    IlluminaHumanMethylationEPICanno.ilm10b2.hg19   0.6.0       2020-03-24 [1]
##    illuminaio                                      0.29.0      2019-11-06 [1]
##    interactiveDisplayBase                          1.25.0      2019-11-06 [1]
##    IRanges                                       * 2.21.8      2020-03-25 [1]
##    iterators                                     * 1.0.12      2019-07-26 [1]
##    jpeg                                            0.1-8.1     2019-10-24 [1]
##    jsonlite                                        1.6.1       2020-02-02 [1]
##    km.ci                                           0.5-2       2009-08-30 [1]
##    KMsurv                                          0.1-5       2012-12-03 [1]
##    knitr                                           1.28        2020-02-06 [1]
##    later                                           1.0.0       2019-10-04 [1]
##    lattice                                         0.20-41     2020-04-02 [1]
##    latticeExtra                                    0.6-29      2019-12-19 [1]
##    lazyeval                                        0.2.2       2019-03-15 [1]
##    lifecycle                                       0.2.0       2020-03-06 [1]
##    limma                                           3.43.8      2020-04-14 [1]
##    lme4                                            1.1-23      2020-04-07 [1]
##    lmerTest                                        3.1-2       2020-04-08 [1]
##    locfit                                          1.5-9.4     2020-03-25 [1]
##    magrittr                                      * 1.5         2014-11-22 [1]
##    MASS                                            7.3-51.5    2019-12-20 [1]
##    Matrix                                          1.2-18      2019-11-27 [1]
##    matrixStats                                   * 0.56.0      2020-03-13 [1]
##    mclust                                          5.4.6       2020-04-11 [1]
##    memoise                                         1.1.0       2017-04-21 [1]
##  P methTF                                        * 0.1.0       2020-03-24 [?]
##    mgcv                                            1.8-31      2019-11-09 [1]
##    mime                                            0.9         2020-02-04 [1]
##    minfi                                           1.33.1      2020-03-05 [1]
##    minqa                                           1.2.4       2014-10-09 [1]
##    MultiAssayExperiment                            1.13.21     2020-04-13 [1]
##    multtest                                        2.43.1      2020-03-12 [1]
##    munsell                                         0.5.0       2018-06-12 [1]
##    nlme                                            3.1-147     2020-04-13 [1]
##    nloptr                                          1.2.2.1     2020-03-11 [1]
##    nnet                                            7.3-13      2020-02-25 [1]
##    nor1mix                                         1.3-0       2019-06-13 [1]
##    numDeriv                                        2016.8-1.1  2019-06-06 [1]
##    openssl                                         1.4.1       2019-07-18 [1]
##    parsetools                                      0.1.3       2020-04-08 [1]
##    pillar                                          1.4.3       2019-12-20 [1]
##    pkgbuild                                        1.0.6       2019-10-09 [1]
##    pkgcond                                         0.1.0       2018-12-03 [1]
##    pkgconfig                                       2.0.3       2019-09-22 [1]
##    pkgload                                         1.0.2       2018-10-29 [1]
##    plotly                                          4.9.2.1     2020-04-04 [1]
##    plyr                                            1.8.6       2020-03-03 [1]
##    png                                             0.1-7       2013-12-03 [1]
##    postlogic                                       0.1.0.1     2019-12-18 [1]
##    preprocessCore                                  1.49.2      2020-02-01 [1]
##    prettyunits                                     1.1.1       2020-01-24 [1]
##    processx                                        3.4.2       2020-02-09 [1]
##    progress                                        1.2.2       2019-05-16 [1]
##    promises                                        1.1.0       2019-10-04 [1]
##    ProtGenerics                                    1.19.3      2019-12-25 [1]
##    ps                                              1.3.2       2020-02-13 [1]
##    purrr                                           0.3.4       2020-04-17 [1]
##    purrrogress                                     0.1.1       2019-07-22 [1]
##    quadprog                                        1.5-8       2019-11-20 [1]
##    R.methodsS3                                     1.8.0       2020-02-14 [1]
##    R.oo                                            1.23.0      2019-11-03 [1]
##    R.utils                                         2.9.2       2019-12-08 [1]
##    R6                                              2.4.1       2019-11-12 [1]
##    rappdirs                                        0.3.1       2016-03-28 [1]
##    RColorBrewer                                    1.1-2       2014-12-07 [1]
##    Rcpp                                            1.0.4.6     2020-04-09 [1]
##    RCurl                                           1.98-1.2    2020-04-18 [1]
##    readr                                           1.3.1       2018-12-21 [1]
##    remotes                                         2.1.1       2020-02-15 [1]
##    reshape                                         0.8.8       2018-10-23 [1]
##    reshape2                                        1.4.4       2020-04-09 [1]
##    rhdf5                                           2.31.10     2020-04-02 [1]
##    Rhdf5lib                                        1.9.3       2020-04-15 [1]
##    rjson                                           0.2.20      2018-06-08 [1]
##    rlang                                           0.4.5.9000  2020-03-20 [1]
##    rmarkdown                                       2.1         2020-01-20 [1]
##    rngtools                                        1.5         2020-01-23 [1]
##    rpart                                           4.1-15      2019-04-12 [1]
##    rprojroot                                       1.3-2       2018-01-03 [1]
##    Rsamtools                                       2.3.7       2020-03-18 [1]
##    RSQLite                                         2.2.0       2020-01-07 [1]
##    rstudioapi                                      0.11        2020-02-07 [1]
##    rtracklayer                                     1.47.0      2019-11-06 [1]
##    rvest                                           0.3.5       2019-11-08 [1]
##    S4Vectors                                     * 0.25.15     2020-04-04 [1]
##    scales                                          1.1.0       2019-11-18 [1]
##    scrime                                          1.3.5       2018-12-01 [1]
##    selectr                                         0.4-2       2019-11-20 [1]
##    sesameData                                    * 1.5.0       2019-10-31 [1]
##    sessioninfo                                     1.1.1       2018-11-05 [1]
##    shape                                           1.4.4       2018-02-07 [1]
##    shiny                                           1.4.0.2     2020-03-13 [1]
##    ShortRead                                       1.45.4      2020-03-18 [1]
##    siggenes                                        1.61.0      2019-11-06 [1]
##    statmod                                         1.4.34      2020-02-17 [1]
##    stringi                                         1.4.6       2020-02-17 [1]
##    stringr                                         1.4.0       2019-02-10 [1]
##    SummarizedExperiment                          * 1.17.5      2020-03-27 [1]
##    survival                                        3.1-12      2020-04-10 [1]
##    survminer                                       0.4.6       2019-09-03 [1]
##    survMisc                                        0.5.5       2018-07-05 [1]
##    sva                                             3.35.2      2020-03-22 [1]
##    TCGAbiolinks                                  * 2.15.3      2019-12-17 [1]
##    testextra                                       0.1.0.1     2019-12-18 [1]
##    testthat                                      * 2.3.2       2020-03-02 [1]
##    tibble                                          3.0.1       2020-04-20 [1]
##    tidyr                                         * 1.0.2       2020-01-24 [1]
##    tidyselect                                      1.0.0       2020-01-27 [1]
##    usethis                                         1.6.0       2020-04-09 [1]
##    VariantAnnotation                               1.33.4      2020-04-09 [1]
##    vctrs                                           0.2.99.9010 2020-04-02 [1]
##    viridisLite                                     0.3.0       2018-02-01 [1]
##    withr                                           2.1.2       2018-03-15 [1]
##    xfun                                            0.13        2020-04-13 [1]
##    XML                                             3.99-0.3    2020-01-20 [1]
##    xml2                                            1.3.1       2020-04-09 [1]
##    xtable                                          1.8-4       2019-04-21 [1]
##    XVector                                         0.27.2      2020-03-24 [1]
##    yaml                                            2.2.1       2020-02-01 [1]
##    zlibbioc                                        1.33.1      2020-01-24 [1]
##    zoo                                             1.8-7       2020-01-10 [1]
##  source                                     
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  local                                      
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Github (tidyverse/dplyr@affb977)           
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Github (Bioconductor/GenomicRanges@70e6e69)
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  local                                      
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Github (r-lib/rlang@a90b04b)               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Github (r-lib/vctrs@fd24927)               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
## 
## [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
## 
##  P ── Loaded and on-disk path mismatch.
LS0tCnRpdGxlOiAiQ29ycmVsYXRpb24gb2YgQUQgYXNzb2NpYXRlZCBtZXRoeWxhdGlvbiBjaGFuZ2VzIHdpdGggZXhwcmVzc2lvbnMgb2YgbmVhcmJ5IGdlbmVzIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiAlWScpYCIKYXV0aG9yOgotIFRpYWdvIEMuIFNpbHZhLCBMYW55dSBaaGFuZywgTGlseSBXYW5nCm91dHB1dDoKICBybWFya2Rvd246Omh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogbHVtZW4KICAgIHRvYzogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBkZl9wcmludDogcGFnZWQKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgdG9jX2Zsb2F0OiBmYWxzZQogICAgdG9jX2RlcHRoOiA0Ci0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDEwLCAKICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQgPSAxMykKa25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3MgPSBGQUxTRSwgdmVyYm9zZSA9IEZBTFNFLHJvb3QuZGlyID0gIi4uIikKc2hvdy5zZWN0aW9uLmNvZGUgPC0gRkFMU0UKYGBgCgoKYHIgaWYoc2hvdy5zZWN0aW9uLmNvZGUpeyIjIExvYWQgbGlicmFyaWVzIn1gCgoKYGBge3IsIGluY2x1ZGUgPSBzaG93LnNlY3Rpb24uY29kZX0Kc3VwcHJlc3NNZXNzYWdlcyh7CiAgbGlicmFyeShDb21wbGV4SGVhdG1hcCkKICBsaWJyYXJ5KFN1bW1hcml6ZWRFeHBlcmltZW50KQogIGxpYnJhcnkoR2Vub21pY1JhbmdlcykKICBkZXZ0b29sczo6bG9hZF9hbGwoIn4vRG9jdW1lbnRzL3BhY2thZ2VzL2NvTWV0aERNUi8vIikKICBsaWJyYXJ5KFRDR0FiaW9saW5rcykKICBsaWJyYXJ5KGdncHVicikKICBsaWJyYXJ5KGRwbHlyKQogIGxpYnJhcnkodGlkeXIpCiAgbGlicmFyeShnZ3B1YnIpCiAgbGlicmFyeShEZWxheWVkTWF0cml4U3RhdHMpCiAgZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L0RvY3VtZW50cy9wYWNrYWdlcy9jb01ldGhETVIvIikKICBkZXZ0b29sczo6bG9hZF9hbGwoIn4vRHJvcGJveCAoQkJTUikvUGFuQ2FuY2VyL21ldGhURi8iKQogIGxpYnJhcnkoZG9QYXJhbGxlbCkKICByZWdpc3RlckRvUGFyYWxsZWwoNCkKICBnZW5lLmluZm8gPC0gVENHQWJpb2xpbmtzOjpnZXQuR1JDaC5iaW9NYXJ0KCJoZzE5IikKfSkKYGBgCgoKIyBEYXRhc2V0cwoKLSBETkFtIGRhdGEg4oCTIGluIGZpbGUgJ1JPU01BUF9RTkJNSVFfUENmaWx0ZXJlZC5SRFMnIAotIFJOQXNlcSBkYXRhIOKAkyBpbiBmaWxlczoKLSAnUk9TTUFQX1JOQXNlcV9GUEtNX2dlbmVfcGxhdGVzXzFfdG9fNl9ub3JtYWxpemVkLnRzdicKLSAnUk9TTUFQX1JOQXNlcV9GUEtNX2dlbmVfcGxhdGVzXzdfdG9fOF9ub3JtYWxpemVkLnRzdicgIAotIExpbmsgZm9yIElEcyDigJMgaW4gZmlsZSAiUk9TTUFQX0lEa2V5IgotIGNvbHVtbiAibXdhc19pZCIgaXMgZm9yIEROQW0gZGF0YSAKLSBjb2x1bW4gInJuYXNlcV9pZCIgaXMgZm9yIHJuYXNlcQotIFBoZW5vdHlwZSBkYXRhOiAgcGhlbm9fd2l0aE5ldXJvblByb3BfZGYuUkRTCgojIyBDb2RlIHRvIGdldCBtYXRjaGVkIGRhdGEKYGBge1IsIGNvZGUgPSByZWFkTGluZXMoImRhdGEuUiIpLGV2YWwgPSBGQUxTRX0KYGBgCgoKYGBge1IsIGZpZy5oZWlnaHQgPSA2LCBpbmNsdWRlID0gRkFMU0UsIGV2YWwgPSBGQUxTRX0KCiMjIFJlYWRpbmcgZGF0YSBjcmVhdGVkIHByZXZpb3VzbHkKZGF0YS5wYXRoIDwtICIuLi9jb2RlX3ZhbGlkYXRpb24vTWV0YV9hbmFseXNpc19jb2RlL0RBVEFTRVRTL1JPU01BUCIKbG9hZCgiZGF0YS9tYXRjaGVkX2RhdGEucmRhIikKZGltKG1hdGNoZWQuZG5hbSkKZGltKG1hdGNoZWQuZXhwKQptYXRjaGVkLmV4cCA8LSBtYXRjaGVkLmV4cFtyb3dTdW1zKG1hdGNoZWQuZXhwKSA+IDAsXQptYXRjaGVkLnBoZW5vdHlwZQpnZ2hpc3RvZ3JhbShtYXRjaGVkLnBoZW5vdHlwZSRicmFha3NjLAogICAgICAgICAgICBiaW5zID0gNywKICAgICAgICAgICAgZmlsbCA9ICJibGFjayIsCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwKICAgICAgICAgICAgYWxwaGEgPSAxKQpgYGAKCgojIFJlZ2lvbiBhbmFseXNpcwojIyBHZXQgbWV0YWRhdGEgcmVzdWx0cwoKYGBge1J9Cm1ldGEuYW5hbHlzaXMuZm9sZGVyIDwtICIuLi9jb2RlX3ZhbGlkYXRpb24vTWV0YV9hbmFseXNpc19jb2RlL21ldGFfYW5hbHlzaXNfcmVnaW9uX3Jlc3VsdHMvIgojIGZvY3VzIG9uIHNpZ25pZmljYW50IG1ldGh5bGF0aW9uIHJlZ2lvbnMgd2l0aCBGRFIgPCAwLjA1IGluIGZpbGUg4oCcbWV0YV9hbmFseXNpc19BTExfZGYuY3N24oCdCmFuYWx5c2lzIDwtIHJlYWRyOjpyZWFkX2NzdigKICBmaWxlLnBhdGgobWV0YS5hbmFseXNpcy5mb2xkZXIsInN0ZXAxX21ldGFfYW5hbHlzaXMvbWV0YV9hbmFseXNpc19BTExfZGYuY3N2IiksCiAgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKQopCgpyZWdpb24uYW5hbHlzaXMgPC0gcmVhZHI6OnJlYWRfY3N2KAogIGZpbGUucGF0aChtZXRhLmFuYWx5c2lzLmZvbGRlciwic3RlcDRfZG1yX3ZzX2NwZ3MvbWV0YV9hbmFseXNpc19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19vdl9jb21iX3Bfd2l0aF9zaWdfc2luZ2xlX2NwZ3MuY3N2IiksCiAgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKQopCgpkbXIgPC0gcmVnaW9uLmFuYWx5c2lzICU+JSBmaWx0ZXIoIWlzLm5hKFJPU01BUF9jb01ldGhSZWdpb24pKQpkaW0oZG1yKQpkbXIuaHlwbyA8LSByZWdpb24uYW5hbHlzaXMgJT4lIGZpbHRlcihlc3RpbWF0ZSA8IDApCmRpbShkbXIuaHlwbykKZG1yLmh5cGVyIDwtIHJlZ2lvbi5hbmFseXNpcyAlPiUgZmlsdGVyKGVzdGltYXRlID4gMCkKZGltKGRtci5oeXBlcikKYGBgCgojIyBBbmFseXNpczogUk5BIHZzIEROQW0KCkZvciBlYWNoIHNpZ25pZmljYW50IGNvLW1ldGh5bGF0ZWQgcmVnaW9uLCB3ZSBsb29rZWQgZm9yIGdlbmVzIHdpdGhpbiAkMjUwS2JwJCwgcmVtb3ZlZCBjb25mb3VuZGluZyBlZmZlY3RzIGluIGdlbmUgZXhwcmVzc2lvbiBhbmQgRE5BIG1ldGh5bGF0aW9uIGxldmVscywgYW5kIHRoZW4gY29ycmVsYXRlZCBETkFtIHdpdGggZ2VuZSBleHByZXNzaW9uIHdpdGggdGhlIApmb2xsb3dpbmcgbW9kZWwsIGZvciBjYXNlcyBhbmQgY29udHJvbHMgc2VwYXJhdGVseToKCiQkcm5hX3tyZXNpZHVhbH0gXHNpbSBtZXRfe3Jlc2lkdWFsfSAkJAoKIyMjIFJlbW92ZSBjb25mb3VuZGluZyBlZmZlY3RzIGluIEROQW0gZGF0YQoKJE1lZGlhbihcdGV4dHtETkFtIG0tdmFsdWVzIGluIERNUn0pICBcc2ltIGNlbGx0eXBlLnByb3BvcnRpb24gKyBiYXRjaCArIFx0ZXh0e3NhbXBsZSBwbGF0ZX0gICsgYWdlQXREZWF0aCArIHNleCA9PiBcdGV4dHtETkFtIHJlc2lkdWFsc30kCgpgYGB7UiwgZXZhbCA9IEZBTFNFfQpmaWxlIDwtICJyZXN1bHRzL1JPU01BUC5wcm9iZXMuYWxsLm1ldGEuYW5hbHlzaXMucmVnaW9ucy5yZGEiCmlmKCFmaWxlLmV4aXN0cyhmaWxlKSl7CiAgcmVnaW9ucy5uYW1lICA8LSBuYS5vbWl0KHJlc3VsdHMubWV0YS5hbmFseXNpcy5yZWdpb24kUk9TTUFQX2NvTWV0aFJlZ2lvbikgJT4lIGFzLmNoYXJhY3RlcigpICU+JSB1bmlxdWUoKQogIHByb2Jlcy5hbGwucmVnaW9ucyA8LSBHZXRDcEdzSW5BbGxSZWdpb24ocmVnaW9ucy5uYW1lLCBwcm9ncmVzcyA9IFRSVUUsIG5Db3Jlc19pbnQgPSAxMCkKICBzYXZlKHByb2Jlcy5hbGwucmVnaW9ucywgZmlsZSA9IGZpbGUpCn0gZWxzZSB7CiAgbG9hZChmaWxlKQp9CgoKbWVkaWFuLm1ldCA8LSBwbHlyOjpsZHBseSgKICBwcm9iZXMuYWxsLnJlZ2lvbnNbdW5pcXVlKGRtciRST1NNQVBfY29NZXRoUmVnaW9uKV0sCiAgZnVuY3Rpb24ocHJvYmVzKXsKICAgIGF1eCA8LSBjb2xNZWRpYW5zKG1hdGNoZWQuZG5hbSxyb3dzID0gcm93bmFtZXMobWF0Y2hlZC5kbmFtKSAlaW4lIHByb2JlcykKICAgIGF1eAogIH0sCiAgLnByb2dyZXNzID0gInRpbWUiLAogIC5wYXJhbGxlbCA9IFRSVUUsCiAgLmluZm9ybSA9IFRSVUUsCiAgLmlkID0gInJlZ2lvbiIgCikKCnJvd25hbWVzKG1lZGlhbi5tZXQpIDwtIG1lZGlhbi5tZXQkcmVnaW9uICU+JSBhcy5jaGFyYWN0ZXIoKQptZWRpYW4ubWV0JHJlZ2lvbiA8LSBOVUxMCmNvbG5hbWVzKG1lZGlhbi5tZXQpIDwtIGNvbG5hbWVzKG1hdGNoZWQuZG5hbSkKCiMgMSkgcmVtb3ZlIGNvbmZvdW5kaW5nIGVmZmVjdHMgaW4gRE5BbSBkYXRhOiAKcmVzaWRfbWV0IDwtIEdldFJlc2lkdWFscygKICBkbmFtID0gbWVkaWFuLm1ldCwKICBiZXRhVG9NID0gVFJVRSwgI2NvbnZlcnRzIHRvIE12YWx1ZXMgZm9yIGZpdHRpbmcgbGluZWFyIG1vZGVsIAogIHBoZW5vX2RmID0gbWF0Y2hlZC5waGVub3R5cGUsCiAgY292YXJpYXRlc19jaGFyID0gYygiU2FtcGxlX1BsYXRlIiwgInByb3AubmV1cm9uIiwgImJhdGNoIiwibXNleCIsImFnZV9kZWF0aCIpLCAKICBuQ29yZXNfaW50ID0gMSwKICBwcm9ncmVzc2JhciA9IFRSVUUgIAopCmBgYAoKIyMjIFJlbW92ZSBjb25mb3VuZGluZyBlZmZlY3RzIGluIGdlbmUgZXhwcmVzc2lvbiBkYXRhCgoKJGxvZzIoUk5BKSBcc2ltIGFnZUF0RGVhdGggKyBzZXggICsgXHRleHR7bWFya2VycyBmb3IgY2VsbCB0eXBlc30gID0+IFx0ZXh0e1JOQSByZXNpZHVhbHN9JApgYGB7UiByZXNpZHVhbCwgZXZhbCA9IEZBTFNFfQptYXRjaGVkLmV4cC5sb2cyIDwtIGxvZzIobWF0Y2hlZC5leHAgKyAxKQptYXJrZXJzIDwtCiAgdChtYXRjaGVkLmV4cC5sb2cyW2MoCiAgICAiRU5TRzAwMDAwMTExNjc0IiwKICAgICJFTlNHMDAwMDAxMjkyMjYiLAogICAgIkVOU0cwMDAwMDEzMTA5NSIsCiAgICAiRU5TRzAwMDAwMjA1OTI3IiwKICAgICJFTlNHMDAwMDAxNzQwNTkiCiAgKSwgXSkKY29sbmFtZXMobWFya2VycykgPC0gYygibWFya2Vyc19FTk8yIiwKICAgICAgICAgICAgICAgICAgICAgICAibWFya2Vyc19PTElHMiIsCiAgICAgICAgICAgICAgICAgICAgICAgIm1hcmtlcnNfQ0QzNCIsCiAgICAgICAgICAgICAgICAgICAgICAgIm1hcmtlcnNfQ0Q2OCIsCiAgICAgICAgICAgICAgICAgICAgICAgIm1hcmtlcnNfR0ZBUCIpCm1hdGNoZWQucGhlbm90eXBlJHJuYXNlcV9pZCAgPC0gbWFwJHJuYXNlcV9pZFttYXRjaChtYXRjaGVkLnBoZW5vdHlwZSRTYW1wbGUsbWFwJG13YXNfaWQpXQpyZXNpZF9leHAgPC0gcGx5cjo6YWRwbHkoLmRhdGEgPSBtYXRjaGVkLmV4cC5sb2cyLAogICAgICAgICAgICAgICAgICAgICAgICAgLm1hcmdpbnMgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHJvdyl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA8LSB0KHJvdykKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbmFtZXModmFsKSA8LSAidmFsIgogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXQgPC0gY2JpbmQodmFsLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZWQucGhlbm90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VycwogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdCR2YWwgPC0gYXMubnVtZXJpYyhkYXQkdmFsKQogICAgICAgICAgICAgICAgICAgICAgICAgICBmaXRFIDwtIGxtKCJ2YWwgfiBhZ2VfZGVhdGggKyBtc2V4ICsgbWFya2Vyc19FTk8yICsgbWFya2Vyc19PTElHMiArIG1hcmtlcnNfQ0QzNCArIG1hcmtlcnNfQ0Q2OCArIG1hcmtlcnNfR0ZBUCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLmFjdGlvbiA9IG5hLmV4Y2x1ZGUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2lkdWFscyhmaXRFKQogICAgICAgICAgICAgICAgICAgICAgICAgfSwgLnByb2dyZXNzID0gInRpbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgLnBhcmFsbGVsID0gVFJVRSkKcm93bmFtZXMocmVzaWRfZXhwKSA8LSByb3duYW1lcyhtYXRjaGVkLmV4cC5sb2cyKQpgYGAKCmBgYHtSLGV2YWwgPSBGQUxTRX0Kc2F2ZShyZXNpZF9leHAsCiAgICAgcmVzaWRfbWV0LAogICAgIGZpbGUgPSAiZGF0YS9yZXNpZHVhbHMucmRhIikKYGBgCgpgYGB7UixldmFsID0gVFJVRSwgaW5jbHVkZSA9IEZBTFNFfQpsb2FkKCJkYXRhL3Jlc2lkdWFscy5yZGEiKQpgYGAKCgojIyBNYXAgcmVnaW9uIHRvIGdlbmVzICstMjUwa2IKClRoZSBmdW5jdGlvbiBgZ2V0RE5BbS50YXJnZXRgIHdpbGwgZXh0ZW5kIHRoZSByZWdpb25zICQrLTI1MEticCQgYW5kIHJldHVybiB0aGUgb3ZlcmxhcHBpbmcgZ2VuZXMuCgoKYGBge1J9CnJlZ2lvbnMuZ3IgPC0gcm93bmFtZXMocmVzaWRfbWV0KSAlPiUgCiAgYXMuZGF0YS5mcmFtZSAlPiUgCiAgdGlkeXI6OnNlcGFyYXRlKGNvbCA9ICIuIixpbnRvID0gYygiY2hyIiwic3RhcnQiLCJlbmQiKSkgICU+JQogIG1ha2VHUmFuZ2VzRnJvbURhdGFGcmFtZSgpCm5hbWVzKHJlZ2lvbnMuZ3IpIDwtIHJvd25hbWVzKHJlc2lkX21ldCkKcmVnaW9ucy5ncgoKIyBmdW5jdGlvbiBhdmFpbGFibGUgaW4gbWV0aFRGIHBhY2thZ2UgaHR0cHM6Ly9naXRsYWIuY29tL3RpYWdvY2hzdC9tZXRodGYKcmVnaW9ucy5nZW5lcyA8LSBnZXRfcmVnaW9uX3RhcmdldF9nZW5lKHJlZ2lvbnMuZ3IgPSByZWdpb25zLmdyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Vub21lID0gImhnMTkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIndpbmRvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cud2lkdGggPSA1MDAgKiAxMCBeIDMpICMgNTAwIGtiCnJlZ2lvbnMuZ2VuZXMgPC0gcmVnaW9ucy5nZW5lcyAlPiUKICBkcGx5cjo6ZmlsdGVyKHJlZ2lvbnMuZ2VuZXMkZ2VuZV9lbnNlbWJsX2dlbmVfaWQgJWluJSByb3duYW1lcyhyZXNpZF9leHApKQoKZGltKHJlZ2lvbnMuZ2VuZXMpCmhlYWQocmVnaW9ucy5nZW5lcykKYGBgCgoKIyMgVGFyZ2V0IHZzIEROQW0gcmVzaWR1YWwKCkxpbmVhciBtb2RlbHM6CgotIEZvciBjYXNlcyAoQnJhYWsgc3RhZ2UgMy02KTogJFx0ZXh0e1JOQSByZXNpZHVhbHN9IFxzaW0gXHRleHR7RE5BbSByZXNpZHVhbHN9JAotIEZvciBjb250cm9scyAoQnJhYWsgc3RhZ2UgMC0yKTogJFx0ZXh0e1JOQSByZXNpZHVhbHN9IFxzaW0gXHRleHR7RE5BbSByZXNpZHVhbHN9JAoKYGBge1IsIGV2YWwgPSBGQUxTRX0KIyBodHRwOi8vd3d3LnItdHV0b3IuY29tL2VsZW1lbnRhcnktc3RhdGlzdGljcy9zaW1wbGUtbGluZWFyLXJlZ3Jlc3Npb24vcmVzaWR1YWwtcGxvdAp0YWIgPC0gcGx5cjo6YWRwbHkoCiAgcmVnaW9ucy5nZW5lcywKICAubWFyZ2lucyA9IDEsCiAgLmZ1biA9IGZ1bmN0aW9uKHJvdykgewogICAgdHJ5Q2F0Y2goewogICAgICBybmEudGFyZ2V0IDwtCiAgICAgICAgcmVzaWRfZXhwW3Jvd25hbWVzKHJlc2lkX2V4cCkgPT0gcm93JGdlbmVfZW5zZW1ibF9nZW5lX2lkLCAsIGRyb3AgPSBGQUxTRV0KICAgICAgbWV0LnJlc2lkdWFsIDwtIHJlc2lkX21ldFtyb3duYW1lcyhyZXNpZF9tZXQpID09IGFzLmNoYXJhY3Rlcihyb3ckcmVnaW9uSUQpLCBdCiAgICAgIAogICAgICBkZiA8LSBkYXRhLmZyYW1lKAogICAgICAgIHJuYS5yZXNpZHVhbCA9IHJuYS50YXJnZXQgJT4lIGFzLm51bWVyaWMsCiAgICAgICAgbWV0LnJlc2lkdWFsID0gbWV0LnJlc2lkdWFsICU+JSBhcy5udW1lcmljLAogICAgICAgIEJyYWFrX3N0YWdlID0gbWF0Y2hlZC5waGVub3R5cGUkYnJhYWtzYywKICAgICAgICBncm91cCA9IGlmZWxzZShtYXRjaGVkLnBoZW5vdHlwZSRicmFha3NjIDwgMywgIkNvbnRyb2wiLCAiQ2FzZSIpCiAgICAgICkKICAgICAgCiAgICAgICMgMikgZml0IGxpbmVhciBtb2RlbCB0byBjYXNlcyBhbmQgY29udHJvbHMgc2VwZXJhdGVseToKICAgICAgIyBGb3IgY2FzZXMgKEJyYWFrIHN0YWdlIDMtNikKICAgICAgIyBSTkFfcmVzaWR1YWxzIH4gRE5BbV9yZXNpZHVhbHMKICAgICAgcmVzdWx0cy5jYXNlcyA8LSAgbG0gKAogICAgICAgIHJuYS5yZXNpZHVhbCB+IG1ldC5yZXNpZHVhbCwKICAgICAgICBkYXRhID0gZGZbZGYkQnJhYWtfc3RhZ2UgPiAyLCBdCiAgICAgICkKICAgICAgcmVzdWx0cy5jYXNlcy5wdmFsIDwtIHN1bW1hcnkocmVzdWx0cy5jYXNlcykkY29lZmZpY2llbnRzWy0xLCA0LCBkcm9wID0gRl0gJT4lIHQgJT4lIGFzLmRhdGEuZnJhbWUoKQogICAgICByZXN1bHRzLmNhc2VzLmVzdGltYXRlIDwtIHN1bW1hcnkocmVzdWx0cy5jYXNlcykkY29lZmZpY2llbnRzWy0xLCAxLCBkcm9wID0gRl0gJT4lIHQgJT4lIGFzLmRhdGEuZnJhbWUoKQogICAgICBjb2xuYW1lcyhyZXN1bHRzLmNhc2VzLnB2YWwpIDwtIHBhc3RlMCgiY2FzZXNfcHZhbF8iLCBjb2xuYW1lcyhyZXN1bHRzLmNhc2VzLnB2YWwpKQogICAgICBjb2xuYW1lcyhyZXN1bHRzLmNhc2VzLmVzdGltYXRlKSA8LSBwYXN0ZTAoImNhc2VzX2VzdGltYXRlXyIsIGNvbG5hbWVzKHJlc3VsdHMuY2FzZXMuZXN0aW1hdGUpKQogICAgICAKICAgICAgIyBGb3IgY29udHJvbHMgKEJyYWFrIHN0YWdlIDAgLTIpCiAgICAgICMgUk5BX3Jlc2lkdWFscyB+IEROQW1fcmVzaWR1YWxzCiAgICAgIHJlc3VsdHMuY29udHJvbCA8LSBsbSAoCiAgICAgICAgcm5hLnJlc2lkdWFsIH4gbWV0LnJlc2lkdWFsLAogICAgICAgIGRhdGEgPSBkZltkZiRCcmFha19zdGFnZSA8IDMsIF0KICAgICAgKQogICAgICByZXN1bHRzLmNvbnRyb2wucHZhbCA8LSBzdW1tYXJ5KHJlc3VsdHMuY29udHJvbCkkY29lZmZpY2llbnRzWy0xLCA0LCBkcm9wID0gRl0gJT4lIHQgJT4lIGFzLmRhdGEuZnJhbWUoKQogICAgICByZXN1bHRzLmNvbnRyb2wuZXN0aW1hdGUgPC0gc3VtbWFyeShyZXN1bHRzLmNvbnRyb2wpJGNvZWZmaWNpZW50c1stMSwgMSwgZHJvcCA9IEZdICU+JSB0ICU+JSBhcy5kYXRhLmZyYW1lKCkKICAgICAgY29sbmFtZXMocmVzdWx0cy5jb250cm9sLnB2YWwpIDwtIHBhc3RlMCgiY29udHJvbF9wdmFsXyIsIGNvbG5hbWVzKHJlc3VsdHMuY29udHJvbC5wdmFsKSkKICAgICAgY29sbmFtZXMocmVzdWx0cy5jb250cm9sLmVzdGltYXRlKSA8LSBwYXN0ZTAoImNvbnRyb2xfZXN0aW1hdGVfIiwgY29sbmFtZXMocmVzdWx0cy5jb250cm9sLmVzdGltYXRlKSkKICAgICAgCiAgICAgIHJldHVybigKICAgICAgICBkYXRhLmZyYW1lKAogICAgICAgICAgY2JpbmQoCiAgICAgICAgICAgIHJlc3VsdHMuY2FzZXMucHZhbCwKICAgICAgICAgICAgcmVzdWx0cy5jYXNlcy5lc3RpbWF0ZSwKICAgICAgICAgICAgcmVzdWx0cy5jb250cm9sLnB2YWwsCiAgICAgICAgICAgIHJlc3VsdHMuY29udHJvbC5lc3RpbWF0ZQogICAgICAgICAgKSwKICAgICAgICAgIHJvdy5uYW1lcyA9IE5VTEwsCiAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKICAgICAgICApKQogICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICAgIHByaW50KHJvdykKICAgICAgcmV0dXJuKCkKICAgIH0pCiAgfSwKICAuaWQgPSBOVUxMLAogIC5wcm9ncmVzcyA9ICJ0aW1lIiwKICAucGFyYWxsZWwgPSBUUlVFLAogIC5pbmZvcm0gPSBUUlVFCikKcmVhZHI6OndyaXRlX2Nzdih0YWIscGF0aCA9ICJyZXN1bHRzL3Jlc3VsdHNfcmVnaW9uc19sbV8yNTBrYl93aW5kb3cuY3N2IikKYGBgCgoKCmBgYHtSLCBpbmNsdWRlID0gRkFMU0V9CiMjIyBQbG90cwpwbG90VGFyZ2V0RE5BbSA8LSBmdW5jdGlvbihyb3cpewogIHJuYS50YXJnZXQgPC0gcmVzaWRfZXhwW3Jvd25hbWVzKHJlc2lkX2V4cCkgPT0gcm93JGdlbmVfZW5zZW1ibF9nZW5lX2lkLCAsIGRyb3AgPSBGQUxTRV0KICBtZXQucmVzaWR1YWwgPC0gcmVzaWRfbWV0W3Jvd25hbWVzKHJlc2lkX21ldCkgPT0gYXMuY2hhcmFjdGVyKHJvdyRyZWdpb25JRCksIF0KICAKICBkZiA8LSBkYXRhLmZyYW1lKAogICAgcm5hLnJlc2lkdWFsID0gcm5hLnRhcmdldCAlPiUgYXMubnVtZXJpYywKICAgIG1ldC5yZXNpZHVhbCA9IG1ldC5yZXNpZHVhbCAlPiUgYXMubnVtZXJpYywKICAgIEJyYWFrX3N0YWdlID0gbWF0Y2hlZC5waGVub3R5cGUkYnJhYWtzYywKICAgIEJyYWFrX2dyb3VwID0gaWZlbHNlKG1hdGNoZWQucGhlbm90eXBlJGJyYWFrc2MgPCAzLCAiQ29udHJvbCIsICJDYXNlIikKICApCiAgCiAgdGFyZ2V0LmxhYiA8LSBicXVvdGUoYXRvcCgiVGFyZ2V0IiB+Lihyb3ckZ2VuZV9leHRlcm5hbF9nZW5lX25hbWUpLCAiUmVzaWR1YWxzIikpCiAgcmVnaW9uLmxhYiA8LSAiRE5BIG1ldGh5bGF0aW9uIHJlc2lkdWFsLXZhbHVlcyIKICAKICBkbmFtLnRhcmdldC5wbG90IDwtIGdnc2NhdHRlcigKICAgIGRmLCAKICAgIHggPSAibWV0LnJlc2lkdWFsIiwgCiAgICB5ID0gInJuYS5yZXNpZHVhbCIsCiAgICBzaXplID0gMSwKICAgIGNvbG9yID0gIkJyYWFrX2dyb3VwIiwKICAgIGZpbGwgPSAiQnJhYWtfZ3JvdXAiLAogICAgYWRkID0gInJlZy5saW5lIiwgICMgQWRkIHJlZ3Jlc3NpbiBsaW5lCiAgICAjIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImJsdWUiLCBmaWxsID0gImxpZ2h0Z3JheSIpLCAjIEN1c3RvbWl6ZSByZWcuIGxpbmUKICAgIGNvbmYuaW50ID0gVFJVRSwgIyBBZGQgY29uZmlkZW5jZSBpbnRlcnZhbAogICAgI2Nvci5jb2VmID0gVFJVRSAjIEFkZCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudC4gc2VlID9zdGF0X2NvcgogICAgIyBjb3IuY29lZmYuYXJncyA9IGxpc3QobWV0aG9kID0gInBlYXJzb24iLCBsYWJlbC54ID0gMCwgbGFiZWwuc2VwID0gIlxuIikKICApICsgeWxhYih0YXJnZXQubGFiKSArIHhsYWIocmVnaW9uLmxhYikgKyAKICAgIGxhYnMoZmlsbCA9ICJCcmFhayBncm91cCIsIGNvbG9yID0gIkJyYWFrIGdyb3VwIikgKwogICAgc3RhdF9jb3IoYWVzKGNvbG9yID0gQnJhYWtfZ3JvdXApKSAgCiAgIyArIGdlb21fc21vb3RoKG1ldGhvZCA9IE1BU1M6OnJsbSwgc2UgPSBGQUxTRSkgCiAgCiAgIyBxdWludGlsZSBwbG90cyBETkFtCiAgcXVhbnQgPC0gIHF1YW50aWxlKGRmJEROQW0sbmEucm0gPSBUUlVFKQogIHF1YW50aWxlX2xvd2VyX2N1dG9mZiA8LSBxdWFudFsyXQogIHF1YW50aWxlX3VwcGVyX2N1dG9mZiA8LSBxdWFudFs0XQogIHJhbmdlMSA8LSBwYXN0ZTAoIlsiLHBhc3RlKHJvdW5kKHF1YW50WzE6Ml0sZGlnaXRzID0gMyksY29sbGFwc2UgPSAiLCIpLCJdIikKICByYW5nZTIgPC0gcGFzdGUwKCJbIixwYXN0ZShyb3VuZChxdWFudFs0OjVdLGRpZ2l0cyA9IDMpLGNvbGxhcHNlID0gIiwiKSwiXSIpCiAgCiAgZGYkZ3JvdXAgPC0gTkEKICBkZiRncm91cFtkZiRETkFtID4gcXVhbnRpbGVfdXBwZXJfY3V0b2ZmXSA8LSBwYXN0ZTAoIkROQW0gaGlnaCBxdWFydGlsZSAiLCByYW5nZTIpIAogIGRmJGdyb3VwW2RmJEROQW0gPCBxdWFudGlsZV9sb3dlcl9jdXRvZmZdIDwtIHBhc3RlMCgiRE5BbSBsb3cgcXVhcnRpbGUgIiAsIHJhbmdlMSkgCiAgCiAgIyBxdWludGlsZSBwbG90cyBURgogIHF1YW50IDwtICBxdWFudGlsZShkZiRURixuYS5ybSA9IFRSVUUpCiAgcXVhbnRpbGVfbG93ZXJfY3V0b2ZmIDwtIHF1YW50WzJdCiAgcXVhbnRpbGVfdXBwZXJfY3V0b2ZmIDwtIHF1YW50WzRdCiAgcmFuZ2UxIDwtIHBhc3RlMCgiWyIscGFzdGUocm91bmQocXVhbnRbMToyXSxkaWdpdHMgPSAzKSxjb2xsYXBzZSA9ICIsIiksIl0iKQogIHJhbmdlMiA8LSBwYXN0ZTAoIlsiLHBhc3RlKHJvdW5kKHF1YW50WzQ6NV0sZGlnaXRzID0gMyksY29sbGFwc2UgPSAiLCIpLCJdIikKICAKICBmb3IoaWR4IGluIGdyZXAoInB2YWx8ZmRyfHZhbHVlIixjb2xuYW1lcyhyb3cpKSkgcm93WyxpZHhdIDwtIGZvcm1hdC5wdmFsKHJvd1ssaWR4XSAgJT4lIHB1bGwoKSxkaWdpdHMgPSAzKQogIGZvcihpZHggaW4gZ3JlcCgiZXN0aW1hdGV8bWVkaWFufG1pbnVzIixjb2xuYW1lcyhyb3cpKSkgcm93WyxpZHhdIDwtIGZvcm1hdChyb3dbLGlkeF0gICU+JSBwdWxsKCksZGlnaXRzID0gMykKICAKICAjY29sbmFtZXMocm93KVsxNV0gPC0gIlR1bW9yX21lZGlhbiAtIE5vcm1hbF9tZWRpYW4iCiAgYmFzZV9zaXplIDwtIDkKICBhdXggPC0gcm93WyxjKCJyZWdpb25JRCIsCiAgICAgICAgICAgICAgICAiZ2VuZV9leHRlcm5hbF9nZW5lX25hbWUiLAogICAgICAgICAgICAgICAgIkRpc3RhbmNlLnJlZ2lvbi5nZW5lIildCiAgY29sbmFtZXMoYXV4KSA8LSBjKCJyZWdpb25JRCIsIkdlbmUiLCJEaXN0LiByZWdpb24vZ2VuZSAoYnApIikKICB0YWJsZS5wbG90MSA8LSBnZ3RleHR0YWJsZShhdXggJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCgpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJWYXJpYWJsZSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3dzID0gTlVMTCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29scyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0dGhlbWUoIm1PcmFuZ2UiLCBiYXNlX3NpemUgPSBiYXNlX3NpemUpCiAgKQogIAogIAogIHRhYmxlLnBsb3QyYSA8LSByb3dbLGdyZXAoImNhc2VzX2VzdGltYXRlIixjb2xuYW1lcyhyb3cpLHZhbHVlID0gVCksZHJvcCAgPSBGQUxTRV0gJT4lIAogICAgdCgpICU+JSAKICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJWYXJpYWJsZSIpCiAgY29sbmFtZXModGFibGUucGxvdDJhKVsyXSA8LSAiRXN0aW1hdGUiCiAgdGFibGUucGxvdDJhJFZhcmlhYmxlIDwtIGdzdWIoImNhc2VzX2VzdGltYXRlXyIsIiIsdGFibGUucGxvdDJhJFZhcmlhYmxlKQogIHRhYmxlLnBsb3QyYiA8LSByb3dbLGdyZXAoImNhc2VzX3B2YWwiLGNvbG5hbWVzKHJvdyksdmFsdWUgPSBUKSxkcm9wICA9IEZBTFNFXSAlPiUgCiAgICB0KCkgJT4lIAogICAgYXNfdGliYmxlKHJvd25hbWVzID0gIlZhcmlhYmxlIikKICB0YWJsZS5wbG90MmIkVmFyaWFibGUgPC0gZ3N1YigiY2FzZXNfcHZhbF8iLCIiLHRhYmxlLnBsb3QyYiRWYXJpYWJsZSkKICBjb2xuYW1lcyh0YWJsZS5wbG90MmIpWzJdIDwtICJQLXZhbHVlIgogIHRhYmxlLnBsb3QyIDwtIG1lcmdlKHRhYmxlLnBsb3QyYSx0YWJsZS5wbG90MmIsIGJ5ID0gIlZhcmlhYmxlIixzb3J0ID0gRkFMU0UpCiAgCiAgdGFibGUucGxvdDIgPC0gZ2d0ZXh0dGFibGUodGFibGUucGxvdDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93cyA9IE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHMgPSBjKCJETkFtIHZzIFRhcmdldFxuIENhc2VzIiwiRXN0aW1hdGUiLCJQLVZhbHVlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lID0gdHRoZW1lKCJtT3JhbmdlIiwgYmFzZV9zaXplID0gYmFzZV9zaXplKQogICkKICAKICB0YWJsZS5wbG90M2EgPC0gcm93WyxncmVwKCJjb250cm9sX2VzdGltYXRlIixjb2xuYW1lcyhyb3cpLHZhbHVlID0gVCksZHJvcCAgPSBGQUxTRV0gJT4lIAogICAgdCgpICU+JSAKICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJWYXJpYWJsZSIpCiAgCiAgY29sbmFtZXModGFibGUucGxvdDNhKVsyXSA8LSAiRXN0aW1hdGUiCiAgdGFibGUucGxvdDNhJFZhcmlhYmxlIDwtIGdzdWIoImNvbnRyb2xfZXN0aW1hdGVfIiwiIix0YWJsZS5wbG90M2EkVmFyaWFibGUpCiAgCiAgdGFibGUucGxvdDNiIDwtIHJvd1ssZ3JlcCgiY29udHJvbF9wdmFsIixjb2xuYW1lcyhyb3cpLHZhbHVlID0gVCksZHJvcCAgPSBGQUxTRV0gJT4lIAogICAgdCgpICU+JSAKICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJWYXJpYWJsZSIpCiAgCiAgdGFibGUucGxvdDNiJFZhcmlhYmxlIDwtIGdzdWIoImNvbnRyb2xfcHZhbF8iLCIiLHRhYmxlLnBsb3QzYiRWYXJpYWJsZSkKICBjb2xuYW1lcyh0YWJsZS5wbG90M2IpWzJdIDwtICJQLXZhbHVlIgogIHRhYmxlLnBsb3QzIDwtIG1lcmdlKHRhYmxlLnBsb3QzYSx0YWJsZS5wbG90M2IsIGJ5ID0gIlZhcmlhYmxlIixzb3J0ID0gRkFMU0UpCiAgCiAgdGFibGUucGxvdDMgPC0gZ2d0ZXh0dGFibGUodGFibGUucGxvdDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93cyA9IE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHMgPSBjKCJETkFtIHZzIFRhcmdldFxuIENvbnRyb2wiLCJFc3RpbWF0ZSIsIlAtVmFsdWVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0dGhlbWUoIm1PcmFuZ2UiLCBiYXNlX3NpemUgPSBiYXNlX3NpemUpCiAgKQogIAogIAogICMgQXJyYW5nZSB0aGUgcGxvdHMgb24gdGhlIHNhbWUgcGFnZQogIHBsb3QudGFibGUgPC0gZ2dhcnJhbmdlKAogICAgZ2dhcnJhbmdlKHRhYmxlLnBsb3QxLAogICAgICAgICAgICAgIHRhYmxlLnBsb3QyLAogICAgICAgICAgICAgIG5jb2wgPSAyKSwKICAgIGdnYXJyYW5nZSgKICAgICAgdGFibGUucGxvdDMsCiAgICAgIG5jb2wgPSAxKSwKICAgIGdnYXJyYW5nZShkbmFtLnRhcmdldC5wbG90LAogICAgICAgICAgICAgIG5jb2wgPSAxKSwKICAgIG5yb3cgPSAzLAogICAgaGVpZ2h0cyA9IGMoMC40LDAuNiwyKSkKICBwbG90LnRhYmxlCn0KYGBgCgoKCmBgYHtSICBtb2RlbF9hbGxfcGxvdF9uZWdfY3BnLCBzaG93ID0gRkFMU0UsIGZpZy5oZWlnaHQgPSA4LCBpbmNsdWRlID0gRkFMU0UsIGV2YWwgPSBGQUxTRX0KIyMjIyBMb3dlc3QgaW50ZXJhY3Rpb24gcC12YWx1ZXMKCnRhYiA8LSByZWFkcjo6cmVhZF9jc3YoInJlc3VsdHMvcmVzdWx0c19yZWdpb25zX2xtXzI1MGtiX3dpbmRvdy5jc3YiLCBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpKQpsaXN0IDwtIHBseXI6OmFscGx5KHRhYltvcmRlcih0YWIkYWxsX3B2YWxfbWV0LnJlc2lkdWFsLmdyb3VwQ29udHJvbClbMToxMF0sXSwKICAgICAgICAgICAgICAgICAgICAubWFyZ2lucyA9IDEsCiAgICAgICAgICAgICAgICAgICAgLmZ1biA9IGZ1bmN0aW9uKHJvdyl7CiAgICAgICAgICAgICAgICAgICAgICBwbG90VGFyZ2V0RE5BbShyb3cpCiAgICAgICAgICAgICAgICAgICAgfSwuaW5mb3JtID0gVFJVRQopCmxpc3QKYGBgCgoKCmBgYHtSLCBzaG93ID0gRkFMU0UsIGZpZy5oZWlnaHQgPSA4LCBpbmNsdWRlID0gRkFMU0UsIGV2YWwgPSBGQUxTRX0KIyMjIyBMb3dlc3QgRE5BbSBwLXZhbHVlcwoKdGFiIDwtIHJlYWRyOjpyZWFkX2NzdigicmVzdWx0cy9yZXN1bHRzX3JlZ2lvbnNfbG1fMjUwa2Jfd2luZG93LmNzdiIsIGNvbF90eXBlcyA9IHJlYWRyOjpjb2xzKCkpCmxpc3QgPC0gcGx5cjo6YWxwbHkodGFiW29yZGVyKHRhYiRhbGxfcHZhbF9tZXQucmVzaWR1YWwpWzE6MTBdLF0sCiAgICAgICAgICAgICAgICAgICAgLm1hcmdpbnMgPSAxLAogICAgICAgICAgICAgICAgICAgIC5mdW4gPSBmdW5jdGlvbihyb3cpewogICAgICAgICAgICAgICAgICAgICAgcGxvdFRhcmdldEROQW0ocm93KQogICAgICAgICAgICAgICAgICAgIH0sLmluZm9ybSA9IFRSVUUKKQpsaXN0CmBgYAoKCgpgYGB7Uiwgc2hvdyA9IEZBTFNFLCBmaWcuaGVpZ2h0ID0gOCwgaW5jbHVkZSA9IEZBTFNFLCBldmFsID0gRkFMU0V9CgojIyMjIExvd2VzdCBjYXNlcyBETkFtIHAtdmFsdWVzCgp0YWIgPC0gcmVhZHI6OnJlYWRfY3N2KCJyZXN1bHRzL3Jlc3VsdHNfcmVnaW9uc19sbV8yNTBrYl93aW5kb3cuY3N2IiwgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKSkKbGlzdCA8LSBwbHlyOjphbHBseSh0YWJbb3JkZXIodGFiJGNhc2VzX3B2YWxfbWV0LnJlc2lkdWFsKVsxOjEwXSxdLAogICAgICAgICAgICAgICAgICAgIC5tYXJnaW5zID0gMSwKICAgICAgICAgICAgICAgICAgICAuZnVuID0gZnVuY3Rpb24ocm93KXsKICAgICAgICAgICAgICAgICAgICAgIHBsb3RUYXJnZXRETkFtKHJvdykKICAgICAgICAgICAgICAgICAgICB9LC5pbmZvcm0gPSBUUlVFCikKbGlzdApgYGAKCgoKYGBge1IsIHNob3cgPSBGQUxTRSwgZmlnLmhlaWdodCA9IDgsIGluY2x1ZGUgPSBGQUxTRSwgZXZhbCA9IEZBTFNFfQoKIyMjIyBMb3dlc3QgY29udHJvbCBETkFtIHAtdmFsdWVzCnRhYiA8LSByZWFkcjo6cmVhZF9jc3YoInJlc3VsdHMvcmVzdWx0c19yZWdpb25zX2xtXzI1MGtiX3dpbmRvdy5jc3YiLCBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpKQpsaXN0IDwtIHBseXI6OmFscGx5KAogIHRhYltvcmRlcih0YWIkY29udHJvbF9wdmFsX21ldC5yZXNpZHVhbClbMToxMF0sXSwKICAubWFyZ2lucyA9IDEsCiAgLmZ1biA9IGZ1bmN0aW9uKHJvdyl7CiAgICBwbG90VGFyZ2V0RE5BbShyb3cpCiAgfSwuaW5mb3JtID0gVFJVRQopCmxpc3QKYGBgCgoKIyMjIFJlc3VsdHMKCmBgYHtSfQp0YWIgPC0gcmVhZHI6OnJlYWRfY3N2KCJyZXN1bHRzL3Jlc3VsdHNfcmVnaW9uc19sbV8yNTBrYl93aW5kb3cuY3N2IiwgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKSkKdGFiJGZkci5jb250cm9scyA8LSBwLmFkanVzdCh0YWIkY29udHJvbF9wdmFsX21ldC5yZXNpZHVhbCxtZXRob2QgPSAiZmRyIikKdGFiJGZkci5jYXNlcyA8LSBwLmFkanVzdCh0YWIkY2FzZXNfcHZhbF9tZXQucmVzaWR1YWwsbWV0aG9kID0gImZkciIpCgpvdXRwdXQgPC0gdGFiWyxjKCJyZWdpb25JRCIsImdlbmVfZXh0ZXJuYWxfZ2VuZV9uYW1lIiwKICAgICAgICAgICAgICAgICAiY2FzZXNfZXN0aW1hdGVfbWV0LnJlc2lkdWFsIiwiY2FzZXNfcHZhbF9tZXQucmVzaWR1YWwiLCJmZHIuY2FzZXMiLAogICAgICAgICAgICAgICAgICJjb250cm9sX2VzdGltYXRlX21ldC5yZXNpZHVhbCIsImNvbnRyb2xfcHZhbF9tZXQucmVzaWR1YWwiLCJmZHIuY29udHJvbHMiKV0gCmNvbG5hbWVzKG91dHB1dCkgPC0gYygiY29NZXRoRE1SIiwKICAgICAgICAgICAgICAgICAgICAgICJnZW5lU3ltYm9sIiwKICAgICAgICAgICAgICAgICAgICAgICJlc3RpbWF0ZS5jYXNlcyIsCiAgICAgICAgICAgICAgICAgICAgICAicHZhbC5jYXNlcyIsCiAgICAgICAgICAgICAgICAgICAgICAiZXN0aW1hdGUuY29udHJvbHMiLAogICAgICAgICAgICAgICAgICAgICAgInB2YWwuY29udHJvbHMiCiAgICAgICAgICAgICAgICAgICAgICApCgoKY29scyA8LSBjKGdyZXAoIlJPU01BUF9jb01ldGhSZWdpb24iLGNvbG5hbWVzKHJlZ2lvbi5hbmFseXNpcykpLAogICAgICAgICAgZ3JlcCgiUmVsYXRpb24iLGNvbG5hbWVzKHJlZ2lvbi5hbmFseXNpcykpOmdyZXAoIl5zbW9rZV9iaSQiLGNvbG5hbWVzKHJlZ2lvbi5hbmFseXNpcykpKQpvdXRwdXQyIDwtIG1lcmdlKG91dHB1dCwKICAgICAgICAgICAgICAgICByZWdpb24uYW5hbHlzaXNbLGNvbHNdLAogICAgICAgICAgICAgICAgIGJ5LnggPSAiY29NZXRoRE1SIiwgCiAgICAgICAgICAgICAgICAgYnkueSA9ICJST1NNQVBfY29NZXRoUmVnaW9uIiwKICAgICAgICAgICAgICAgICBhbGwueCA9IFRSVUUpCmBgYAoKYGBge1IsIGV2YWwgPSBGQUxTRX0Kd3JpdGUuY3N2KG91dHB1dDIsZmlsZSA9ICJyZXN1bHRzL3Jlc3VsdHNfcmVnaW9uc19sbV8yNTBrYl93aW5kb3dfcmVuYW1lZC5jc3YiKQpgYGAKCmBgYHtSLCBldmFsID0gRkFMU0UsIGluY2x1ZGUgPSBGQUxTRX0Kb3V0cHV0ICU+JSBkcGx5cjo6ZmlsdGVyKG91dHB1dCRmZHIuY2FzZXMgPCAwLjAxIHwgb3V0cHV0JGZkci5jb250cm9scyA8IDAuMDEpICU+JQogIERUOjpkYXRhdGFibGUoZmlsdGVyID0gJ3RvcCcsCiAgICAgICAgICAgICAgICBzdHlsZSA9ICJib290c3RyYXAiLAogICAgICAgICAgICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNjcm9sbFggPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IEkoJ2NvbHZpcycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5cyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwKSwgCiAgICAgICAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgY2FwdGlvbiA9ICJMaW5lciBtb2RlbCBUYXJnZXQvRE5BbSByZXN1bHRzIikKYGBgCgoKIyBTaW5nbGUgY3BnIGFuYWx5c2lzCiMjIEdldCBtZXRhZGF0YSByZXN1bHRzCgpgYGB7Un0Kc2luZ2xlLmNwZy5hbmFseXNpcyA8LSByZWFkcjo6cmVhZF9jc3YoCiAgIi4uL2NvZGVfdmFsaWRhdGlvbi9NZXRhX2FuYWx5c2lzX2NvZGUvbWV0YV9hbmFseXNpc19zaW5nbGVfY3BnX3Jlc3VsdHMvbWV0YV9hbmFseXNpc19zaW5nbGVfY3BnX3NpZ19ub19jcm9zc0h5Yl9zbW9raW5nX2RmLmNzdiIsIAogIGNvbF90eXBlcyA9IHJlYWRyOjpjb2xzKCkKKQoKZG1jIDwtIHNpbmdsZS5jcGcuYW5hbHlzaXMgJT4lIGZpbHRlcighaXMubmEoUk9TTUFQX3BWYWx1ZSkpCmRpbShkbWMpCmRtYy5oeXBvIDwtIGRtYyAlPiUgZmlsdGVyKGVzdGltYXRlIDwgMCkKZGltKGRtYy5oeXBvKQpkbWMuaHlwZXIgPC0gZG1jICU+JSBmaWx0ZXIoZXN0aW1hdGUgPiAwKQpkaW0oZG1jLmh5cGVyKQpgYGAKCgojIyBBbmFseXNpczogUk5BIHZzIEROQW0KCkZvciBlYWNoIENwRyBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCBCcmFhayBzdGFnZSwgd2UgbG9va2VkIGZvciBnZW5lcyB3aXRoaW4gJDI1MEticCQsIHJlbW92ZWQgY29uZm91bmRpbmcgZWZmZWN0cyBpbiBnZW5lIGV4cHJlc3Npb24gYW5kIEROQSBtZXRoeWxhdGlvbiBsZXZlbHMsIGFuZCB0aGVuIGNvcnJlbGF0ZWQgcmVzaWR1YWwgbWV0aHlsYXRpb24gd2l0aCBnZW5lIGV4cHJlc3Npb24gbGV2ZWxzIHdpdGggdGhlIGZvbGxvd2luZyBtb2RlbCwgZm9yIGNhc2VzIGFuZCBjb250cm9scyBzZXBhcmF0ZWx5OgoKJCRybmFfe3Jlc2lkdWFsfSBcc2ltIG1ldF97cmVzaWR1YWx9ICQkCgojIyMgUmVtb3ZlIGNvbmZvdW5kaW5nIGVmZmVjdHMgaW4gRE5BbSBkYXRhCgokTWVkaWFuKFx0ZXh0e0ROQW0gbS12YWx1ZXMgaW4gRE1SfSkgIFxzaW0gY2VsbHR5cGUucHJvcG9ydGlvbiArIGJhdGNoICsgXHRleHR7c2FtcGxlIHBsYXRlfSAgKyBhZ2VBdERlYXRoICsgc2V4ID0+IFx0ZXh0e0ROQW0gcmVzaWR1YWxzfSQKCmBgYHtSLCBldmFsID0gRkFMU0V9CgojIDEpIHJlbW92ZSBjb25mb3VuZGluZyBlZmZlY3RzIGluIEROQW0gZGF0YTogCnJlc2lkX21ldF9jcGcgPC0gR2V0UmVzaWR1YWxzKAogIGRuYW0gPSBtYXRjaGVkLmRuYW1bZG1jJGNwZyxdLAogIGJldGFUb00gPSBUUlVFLCAjY29udmVydHMgdG8gTXZhbHVlcyBmb3IgZml0dGluZyBsaW5lYXIgbW9kZWwgCiAgcGhlbm9fZGYgPSBtYXRjaGVkLnBoZW5vdHlwZSwKICBjb3ZhcmlhdGVzX2NoYXIgPSBjKCJTYW1wbGVfUGxhdGUiLCAicHJvcC5uZXVyb24iLCAiYmF0Y2giLCJtc2V4IiwiYWdlX2RlYXRoIiksIAogIG5Db3Jlc19pbnQgPSAxLAogIHByb2dyZXNzYmFyID0gVFJVRSAgCikKYGBgCgoKYGBge1IsZXZhbCA9IEZBTFNFfQpzYXZlKHJlc2lkX2V4cCwKICAgICByZXNpZF9tZXRfY3BnLAogICAgIGZpbGUgPSAiZGF0YS9yZXNpZHVhbHNfY3BnLnJkYSIpCmBgYAoKYGBge1IsZXZhbCA9IFRSVUUsIGluY2x1ZGUgPSBGQUxTRX0KbG9hZCgiZGF0YS9yZXNpZHVhbHNfY3BnLnJkYSIpCmBgYAoKCiMjIE1hcCByZWdpb24gdG8gZ2VuZXMgKy0yNTBrYgoKVGhlIGZ1bmN0aW9uIGBnZXRfcmVnaW9uX3RhcmdldF9nZW5lYCB3aWxsIGV4dGVuZCB0aGUgcmVnaW9ucyAkKy0yNTBLYnAkIGFuZCByZXR1cm4gdGhlIG92ZXJsYXBwaW5nIGdlbmVzLgoKCmBgYHtSfQpkbWMuZ3IgPC0gc2VzYW1lRGF0YTo6c2VzYW1lRGF0YUdldCgiSE00NTAuaGcxOS5tYW5pZmVzdCIpW2RtYyRjcGcsXSAKcmVnaW9ucy5nZW5lcyA8LSBnZXRfcmVnaW9uX3RhcmdldF9nZW5lKAogIHJlZ2lvbnMuZ3IgPSBkbWMuZ3IsCiAgZ2Vub21lID0gImhnMTkiLAogIG1ldGhvZCA9ICJ3aW5kb3ciLAogIHdpbmRvdy53aWR0aCA9IDUwMCAqIDEwIF4gMykgIyA1MDAga2IKCnJlZ2lvbnMuZ2VuZXMgPC0gcmVnaW9ucy5nZW5lcyAlPiUKICBkcGx5cjo6ZmlsdGVyKHJlZ2lvbnMuZ2VuZXMkZ2VuZV9lbnNlbWJsX2dlbmVfaWQgJWluJSByb3duYW1lcyhyZXNpZF9leHApKQpyZWdpb25zLmdlbmVzJGNwZyA8LSBuYW1lcyhkbWMuZ3IpWwogIG1hdGNoKAogICAgcmVnaW9ucy5nZW5lcyRyZWdpb25JRCxwYXN0ZTAoYXMuZGF0YS5mcmFtZShkbWMuZ3IpJHNlcW5hbWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMuZGF0YS5mcmFtZShkbWMuZ3IpJHN0YXJ0LCItIixhcy5kYXRhLmZyYW1lKGRtYy5ncikkZW5kKQogICkKICBdCgpkaW0ocmVnaW9ucy5nZW5lcykKaGVhZChyZWdpb25zLmdlbmVzKQpgYGAKCgojIyBUYXJnZXQgdnMgRE5BbSByZXNpZHVhbAoKTGluZWFyIG1vZGVsczoKLSBGb3IgY2FzZXMgKEJyYWFrIHN0YWdlIDMtNik6ICRcdGV4dHtSTkEgcmVzaWR1YWxzfSBcc2ltIFx0ZXh0e0ROQW0gcmVzaWR1YWxzfSQKLSBGb3IgY29udHJvbHMgKEJyYWFrIHN0YWdlIDAtMik6ICRcdGV4dHtSTkEgcmVzaWR1YWxzfSBcc2ltIFx0ZXh0e0ROQW0gcmVzaWR1YWxzfSQKCmBgYHtSLCBldmFsID0gRkFMU0V9CiMgaHR0cDovL3d3dy5yLXR1dG9yLmNvbS9lbGVtZW50YXJ5LXN0YXRpc3RpY3Mvc2ltcGxlLWxpbmVhci1yZWdyZXNzaW9uL3Jlc2lkdWFsLXBsb3QKdGFiLmNwZyA8LSBwbHlyOjphZHBseSgKICByZWdpb25zLmdlbmVzLAogIC5tYXJnaW5zID0gMSwKICAuZnVuID0gZnVuY3Rpb24ocm93KSB7CiAgICB0cnlDYXRjaCh7CiAgICAgIHJuYS50YXJnZXQgPC0KICAgICAgICByZXNpZF9leHBbcm93bmFtZXMocmVzaWRfZXhwKSA9PSByb3ckZ2VuZV9lbnNlbWJsX2dlbmVfaWQsICwgZHJvcCA9IEZBTFNFXQogICAgICBtZXQucmVzaWR1YWwgPC0KICAgICAgICByZXNpZF9tZXRfY3BnW3Jvd25hbWVzKHJlc2lkX21ldF9jcGcpID09IGFzLmNoYXJhY3Rlcihyb3ckY3BnKSwgXQogICAgICAKICAgICAgZGYgPC0KICAgICAgICBkYXRhLmZyYW1lKAogICAgICAgICAgcm5hLnJlc2lkdWFsID0gcm5hLnRhcmdldCAlPiUgYXMubnVtZXJpYywKICAgICAgICAgIG1ldC5yZXNpZHVhbCA9IG1ldC5yZXNpZHVhbCAlPiUgYXMubnVtZXJpYywKICAgICAgICAgIEJyYWFrX3N0YWdlID0gbWF0Y2hlZC5waGVub3R5cGUkYnJhYWtzYywKICAgICAgICAgIGdyb3VwID0gaWZlbHNlKG1hdGNoZWQucGhlbm90eXBlJGJyYWFrc2MgPCAzLCAiQ29udHJvbCIsICJDYXNlIikKICAgICAgICApCiAgICAgIAogICAgICAjIDIpIGZpdCBsaW5lYXIgbW9kZWwgdG8gY2FzZXMgYW5kIGNvbnRyb2xzIHNlcGVyYXRlbHk6CiAgICAgICMgRm9yIGNhc2VzIChCcmFhayBzdGFnZSAzLTYpCiAgICAgICMgIFJOQV9yZXNpZHVhbHMgfiBETkFtX3Jlc2lkdWFscwogICAgICByZXN1bHRzLmNhc2VzIDwtCiAgICAgICAgbG0gKAogICAgICAgICAgcm5hLnJlc2lkdWFsIH4gbWV0LnJlc2lkdWFsLAogICAgICAgICAgZGF0YSA9IGRmW2RmJEJyYWFrX3N0YWdlID4gMiwgXQogICAgICAgICkKICAgICAgcmVzdWx0cy5jYXNlcy5wdmFsIDwtCiAgICAgICAgc3VtbWFyeShyZXN1bHRzLmNhc2VzKSRjb2VmZmljaWVudHNbLTEsIDQsIGRyb3AgPSBGXSAlPiUgdCAlPiUgYXMuZGF0YS5mcmFtZSgpCiAgICAgIHJlc3VsdHMuY2FzZXMuZXN0aW1hdGUgPC0KICAgICAgICBzdW1tYXJ5KHJlc3VsdHMuY2FzZXMpJGNvZWZmaWNpZW50c1stMSwgMSwgZHJvcCA9IEZdICU+JSB0ICU+JSBhcy5kYXRhLmZyYW1lKCkKICAgICAgY29sbmFtZXMocmVzdWx0cy5jYXNlcy5wdmFsKSA8LQogICAgICAgIHBhc3RlMCgiY2FzZXNfcHZhbF8iLCBjb2xuYW1lcyhyZXN1bHRzLmNhc2VzLnB2YWwpKQogICAgICBjb2xuYW1lcyhyZXN1bHRzLmNhc2VzLmVzdGltYXRlKSA8LQogICAgICAgIHBhc3RlMCgiY2FzZXNfZXN0aW1hdGVfIiwgY29sbmFtZXMocmVzdWx0cy5jYXNlcy5lc3RpbWF0ZSkpCiAgICAgIAogICAgICAjIEZvciBjb250cm9scyAoQnJhYWsgc3RhZ2UgMCAtMikKICAgICAgIyAgUk5BX3Jlc2lkdWFscyB+IEROQW1fcmVzaWR1YWxzCiAgICAgIHJlc3VsdHMuY29udHJvbCA8LQogICAgICAgIGxtICgKICAgICAgICAgIHJuYS5yZXNpZHVhbCB+IG1ldC5yZXNpZHVhbCwKICAgICAgICAgIGRhdGEgPSBkZltkZiRCcmFha19zdGFnZSA8IDMsIF0KICAgICAgICApCiAgICAgIHJlc3VsdHMuY29udHJvbC5wdmFsIDwtCiAgICAgICAgc3VtbWFyeShyZXN1bHRzLmNvbnRyb2wpJGNvZWZmaWNpZW50c1stMSwgNCwgZHJvcCA9IEZdICU+JSB0ICU+JSBhcy5kYXRhLmZyYW1lKCkKICAgICAgcmVzdWx0cy5jb250cm9sLmVzdGltYXRlIDwtCiAgICAgICAgc3VtbWFyeShyZXN1bHRzLmNvbnRyb2wpJGNvZWZmaWNpZW50c1stMSwgMSwgZHJvcCA9IEZdICU+JSB0ICU+JSBhcy5kYXRhLmZyYW1lKCkKICAgICAgY29sbmFtZXMocmVzdWx0cy5jb250cm9sLnB2YWwpIDwtCiAgICAgICAgcGFzdGUwKCJjb250cm9sX3B2YWxfIiwgY29sbmFtZXMocmVzdWx0cy5jb250cm9sLnB2YWwpKQogICAgICBjb2xuYW1lcyhyZXN1bHRzLmNvbnRyb2wuZXN0aW1hdGUpIDwtCiAgICAgICAgcGFzdGUwKCJjb250cm9sX2VzdGltYXRlXyIsIGNvbG5hbWVzKHJlc3VsdHMuY29udHJvbC5lc3RpbWF0ZSkpCiAgICAgIAogICAgICAKICAgICAgcmV0dXJuKAogICAgICAgIGRhdGEuZnJhbWUoCiAgICAgICAgICBjYmluZCgKICAgICAgICAgICAgcmVzdWx0cy5jYXNlcy5wdmFsLAogICAgICAgICAgICByZXN1bHRzLmNhc2VzLmVzdGltYXRlLAogICAgICAgICAgICByZXN1bHRzLmNvbnRyb2wucHZhbCwKICAgICAgICAgICAgcmVzdWx0cy5jb250cm9sLmVzdGltYXRlCiAgICAgICAgICApLAogICAgICAgICAgcm93Lm5hbWVzID0gTlVMTCwKICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQogICAgICAgICkpCiAgICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgcHJpbnQocm93KQogICAgICByZXR1cm4oKQogICAgfSkKICB9LAogIC5pZCA9IE5VTEwsCiAgLnByb2dyZXNzID0gInRpbWUiLAogIC5wYXJhbGxlbCA9IFRSVUUsCiAgLmluZm9ybSA9IFRSVUUKKQpyZWFkcjo6d3JpdGVfY3N2KHRhYi5jcGcscGF0aCA9ICJyZXN1bHRzL3Jlc3VsdHNfc2luZ2xlX2NwZ19sbV8yNTBrYl93aW5kb3cuY3N2IikKYGBgCgoKCmBgYHtSLCBpbmNsdWRlID0gRkFMU0V9CiMjIyBQbG90cwpwbG90VGFyZ2V0RE5BbSA8LSBmdW5jdGlvbihyb3cpewogIHJuYS50YXJnZXQgPC0KICAgIHJlc2lkX2V4cFtyb3duYW1lcyhyZXNpZF9leHApID09IHJvdyRnZW5lX2Vuc2VtYmxfZ2VuZV9pZCwgLCBkcm9wID0gRkFMU0VdCiAgbWV0LnJlc2lkdWFsIDwtCiAgICByZXNpZF9tZXRfY3BnW3Jvd25hbWVzKHJlc2lkX21ldF9jcGcpID09IGFzLmNoYXJhY3Rlcihyb3ckY3BnKSwgXQogIAogIGRmIDwtCiAgICBkYXRhLmZyYW1lKAogICAgICBybmEucmVzaWR1YWwgPSBybmEudGFyZ2V0ICU+JSBhcy5udW1lcmljLAogICAgICBtZXQucmVzaWR1YWwgPSBtZXQucmVzaWR1YWwgJT4lIGFzLm51bWVyaWMsCiAgICAgIEJyYWFrX3N0YWdlID0gbWF0Y2hlZC5waGVub3R5cGUkYnJhYWtzYywKICAgICAgQnJhYWtfZ3JvdXAgPSBpZmVsc2UobWF0Y2hlZC5waGVub3R5cGUkYnJhYWtzYyA8IDMsICJDb250cm9sIiwgIkNhc2UiKQogICAgKQogIAogIHRhcmdldC5sYWIgPC0gYnF1b3RlKGF0b3AoIlRhcmdldCIgfi4ocm93JGdlbmVfZXh0ZXJuYWxfZ2VuZV9uYW1lKSwgIlJlc2lkdWFscyIpKQogIHJlZ2lvbi5sYWIgPC0gIkROQSBtZXRoeWxhdGlvbiByZXNpZHVhbC12YWx1ZXMiCiAgCiAgZG5hbS50YXJnZXQucGxvdCA8LSBnZ3NjYXR0ZXIoZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAibWV0LnJlc2lkdWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJybmEucmVzaWR1YWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIkJyYWFrX2dyb3VwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gIkJyYWFrX2dyb3VwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQgPSAicmVnLmxpbmUiLCAgIyBBZGQgcmVncmVzc2luIGxpbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImJsdWUiLCBmaWxsID0gImxpZ2h0Z3JheSIpLCAjIEN1c3RvbWl6ZSByZWcuIGxpbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mLmludCA9IFRSVUUsICMgQWRkIGNvbmZpZGVuY2UgaW50ZXJ2YWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY29yLmNvZWYgPSBUUlVFICMgQWRkIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50LiBzZWUgP3N0YXRfY29yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjb3IuY29lZmYuYXJncyA9IGxpc3QobWV0aG9kID0gInBlYXJzb24iLCBsYWJlbC54ID0gMCwgbGFiZWwuc2VwID0gIlxuIikKICApICsgeWxhYih0YXJnZXQubGFiKSArIHhsYWIocmVnaW9uLmxhYikgKyAKICAgIGxhYnMoZmlsbCA9ICJCcmFhayBncm91cCIsIGNvbG9yID0gIkJyYWFrIGdyb3VwIikgKwogICAgc3RhdF9jb3IoYWVzKGNvbG9yID0gQnJhYWtfZ3JvdXApKSAgCiAgCiAgIyBxdWludGlsZSBwbG90cyBETkFtCiAgcXVhbnQgPC0gIHF1YW50aWxlKGRmJEROQW0sbmEucm0gPSBUUlVFKQogIHF1YW50aWxlX2xvd2VyX2N1dG9mZiA8LSBxdWFudFsyXQogIHF1YW50aWxlX3VwcGVyX2N1dG9mZiA8LSBxdWFudFs0XQogIHJhbmdlMSA8LSBwYXN0ZTAoIlsiLHBhc3RlKHJvdW5kKHF1YW50WzE6Ml0sZGlnaXRzID0gMyksY29sbGFwc2UgPSAiLCIpLCJdIikKICByYW5nZTIgPC0gcGFzdGUwKCJbIixwYXN0ZShyb3VuZChxdWFudFs0OjVdLGRpZ2l0cyA9IDMpLGNvbGxhcHNlID0gIiwiKSwiXSIpCiAgCiAgZGYkZ3JvdXAgPC0gTkEKICBkZiRncm91cFtkZiRETkFtID4gcXVhbnRpbGVfdXBwZXJfY3V0b2ZmXSA8LSBwYXN0ZTAoIkROQW0gaGlnaCBxdWFydGlsZSAiLCByYW5nZTIpIAogIGRmJGdyb3VwW2RmJEROQW0gPCBxdWFudGlsZV9sb3dlcl9jdXRvZmZdIDwtIHBhc3RlMCgiRE5BbSBsb3cgcXVhcnRpbGUgIiAsIHJhbmdlMSkgCiAgCiAgIyBxdWludGlsZSBwbG90cyBURgogIHF1YW50IDwtICBxdWFudGlsZShkZiRURixuYS5ybSA9IFRSVUUpCiAgcXVhbnRpbGVfbG93ZXJfY3V0b2ZmIDwtIHF1YW50WzJdCiAgcXVhbnRpbGVfdXBwZXJfY3V0b2ZmIDwtIHF1YW50WzRdCiAgcmFuZ2UxIDwtIHBhc3RlMCgiWyIscGFzdGUocm91bmQocXVhbnRbMToyXSxkaWdpdHMgPSAzKSxjb2xsYXBzZSA9ICIsIiksIl0iKQogIHJhbmdlMiA8LSBwYXN0ZTAoIlsiLHBhc3RlKHJvdW5kKHF1YW50WzQ6NV0sZGlnaXRzID0gMyksY29sbGFwc2UgPSAiLCIpLCJdIikKICAKICBmb3IoaWR4IGluIGdyZXAoInB2YWx8ZmRyfHZhbHVlIixjb2xuYW1lcyhyb3cpKSkgcm93WyxpZHhdIDwtIGZvcm1hdC5wdmFsKHJvd1ssaWR4XSAgJT4lIHB1bGwoKSxkaWdpdHMgPSAzKQogIGZvcihpZHggaW4gZ3JlcCgiZXN0aW1hdGV8bWVkaWFufG1pbnVzIixjb2xuYW1lcyhyb3cpKSkgcm93WyxpZHhdIDwtIGZvcm1hdChyb3dbLGlkeF0gICU+JSBwdWxsKCksZGlnaXRzID0gMykKICAKICAjY29sbmFtZXMocm93KVsxNV0gPC0gIlR1bW9yX21lZGlhbiAtIE5vcm1hbF9tZWRpYW4iCiAgYmFzZV9zaXplIDwtIDkKICB0YWJsZS5wbG90MSA8LSBnZ3RleHR0YWJsZShyb3dbLGMoInJlZ2lvbklEIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdlbmVfZXh0ZXJuYWxfZ2VuZV9uYW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpc3RhbmNlLnJlZ2lvbi5nZW5lIildICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQoKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc190aWJibGUocm93bmFtZXMgPSAiVmFyaWFibGUiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93cyA9IE5VTEwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHMgPSBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lID0gdHRoZW1lKCJtT3JhbmdlIiwgYmFzZV9zaXplID0gYmFzZV9zaXplKQogICkKICAKICAKICB0YWJsZS5wbG90MmEgPC0gcm93WyxncmVwKCJjYXNlc19lc3RpbWF0ZSIsY29sbmFtZXMocm93KSx2YWx1ZSA9IFQpLGRyb3AgID0gRkFMU0VdICU+JSAKICAgIHQoKSAlPiUgCiAgICBhc190aWJibGUocm93bmFtZXMgPSAiVmFyaWFibGUiKQogIGNvbG5hbWVzKHRhYmxlLnBsb3QyYSlbMl0gPC0gIkVzdGltYXRlIgogIHRhYmxlLnBsb3QyYSRWYXJpYWJsZSA8LSBnc3ViKCJjYXNlc19lc3RpbWF0ZV8iLCIiLHRhYmxlLnBsb3QyYSRWYXJpYWJsZSkKICB0YWJsZS5wbG90MmIgPC0gcm93WyxncmVwKCJjYXNlc19wdmFsIixjb2xuYW1lcyhyb3cpLHZhbHVlID0gVCksZHJvcCAgPSBGQUxTRV0gJT4lIAogICAgdCgpICU+JSAKICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJWYXJpYWJsZSIpCiAgdGFibGUucGxvdDJiJFZhcmlhYmxlIDwtIGdzdWIoImNhc2VzX3B2YWxfIiwiIix0YWJsZS5wbG90MmIkVmFyaWFibGUpCiAgY29sbmFtZXModGFibGUucGxvdDJiKVsyXSA8LSAiUC12YWx1ZSIKICB0YWJsZS5wbG90MiA8LSBtZXJnZSh0YWJsZS5wbG90MmEsdGFibGUucGxvdDJiLCBieSA9ICJWYXJpYWJsZSIsc29ydCA9IEZBTFNFKQogIAogIHRhYmxlLnBsb3QyIDwtIGdndGV4dHRhYmxlKHRhYmxlLnBsb3QyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvd3MgPSBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzID0gYygiRE5BbSB2cyBUYXJnZXRcbiBDYXNlcyIsIkVzdGltYXRlIiwiUC1WYWx1ZXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSA9IHR0aGVtZSgibU9yYW5nZSIsIGJhc2Vfc2l6ZSA9IGJhc2Vfc2l6ZSkKICApCiAgCiAgdGFibGUucGxvdDNhIDwtIHJvd1ssZ3JlcCgiY29udHJvbF9lc3RpbWF0ZSIsY29sbmFtZXMocm93KSx2YWx1ZSA9IFQpLGRyb3AgID0gRkFMU0VdICU+JSAKICAgIHQoKSAlPiUgCiAgICBhc190aWJibGUocm93bmFtZXMgPSAiVmFyaWFibGUiKQogIGNvbG5hbWVzKHRhYmxlLnBsb3QzYSlbMl0gPC0gIkVzdGltYXRlIgogIHRhYmxlLnBsb3QzYSRWYXJpYWJsZSA8LSBnc3ViKCJjb250cm9sX2VzdGltYXRlXyIsIiIsdGFibGUucGxvdDNhJFZhcmlhYmxlKQogIHRhYmxlLnBsb3QzYiA8LSByb3dbLGdyZXAoImNvbnRyb2xfcHZhbCIsY29sbmFtZXMocm93KSx2YWx1ZSA9IFQpLGRyb3AgID0gRkFMU0VdICU+JSAKICAgIHQoKSAlPiUgCiAgICBhc190aWJibGUocm93bmFtZXMgPSAiVmFyaWFibGUiKQogIHRhYmxlLnBsb3QzYiRWYXJpYWJsZSA8LSBnc3ViKCJjb250cm9sX3B2YWxfIiwiIix0YWJsZS5wbG90M2IkVmFyaWFibGUpCiAgY29sbmFtZXModGFibGUucGxvdDNiKVsyXSA8LSAiUC12YWx1ZSIKICB0YWJsZS5wbG90MyA8LSBtZXJnZSh0YWJsZS5wbG90M2EsdGFibGUucGxvdDNiLCBieSA9ICJWYXJpYWJsZSIsc29ydCA9IEZBTFNFKQogIAogIHRhYmxlLnBsb3QzIDwtIGdndGV4dHRhYmxlKHRhYmxlLnBsb3QzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvd3MgPSBOVUxMLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzID0gYygiRE5BbSB2cyBUYXJnZXRcbiBDb250cm9sIiwiRXN0aW1hdGUiLCJQLVZhbHVlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lID0gdHRoZW1lKCJtT3JhbmdlIiwgYmFzZV9zaXplID0gYmFzZV9zaXplKQogICkKICAKICAKICAKICAjIEFycmFuZ2UgdGhlIHBsb3RzIG9uIHRoZSBzYW1lIHBhZ2UKICBwbG90LnRhYmxlIDwtIGdnYXJyYW5nZSgKICAgIGdnYXJyYW5nZSh0YWJsZS5wbG90MSwKICAgICAgICAgICAgICB0YWJsZS5wbG90MiwKICAgICAgICAgICAgICBuY29sID0gMiksCiAgICBnZ2FycmFuZ2UoCiAgICAgIHRhYmxlLnBsb3QzLAogICAgICBuY29sID0gMSksCiAgICBnZ2FycmFuZ2UoZG5hbS50YXJnZXQucGxvdCwKICAgICAgICAgICAgICBuY29sID0gMSksCiAgICBucm93ID0gMywKICAgIGhlaWdodHMgPSBjKDAuNCwwLjYsMikpCiAgcGxvdC50YWJsZQp9CmBgYAoKCgpgYGB7UiAgbW9kZWxfYWxsX3Bsb3RfbmVnX3JlZ2lvbiwgc2hvdyA9IEZBTFNFLCBmaWcuaGVpZ2h0ID0gOCwgaW5jbHVkZSA9IEZBTFNFLCBldmFsID0gRkFMU0V9CiMjIyMgTG93ZXN0IGludGVyYWN0aW9uIHAtdmFsdWVzCnRhYiA8LSByZWFkcjo6cmVhZF9jc3YoInJlc3VsdHMvcmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvdy5jc3YiLCBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpKQpsaXN0IDwtIHBseXI6OmFscGx5KHRhYltvcmRlcih0YWIkYWxsX3B2YWxfbWV0LnJlc2lkdWFsLmdyb3VwQ29udHJvbClbMToxMF0sXSwKICAgICAgICAgICAgICAgICAgICAubWFyZ2lucyA9IDEsCiAgICAgICAgICAgICAgICAgICAgLmZ1biA9IGZ1bmN0aW9uKHJvdyl7CiAgICAgICAgICAgICAgICAgICAgICBwbG90VGFyZ2V0RE5BbShyb3cpCiAgICAgICAgICAgICAgICAgICAgfSwuaW5mb3JtID0gVFJVRQopCmxpc3QKYGBgCgoKCgpgYGB7Uiwgc2hvdyA9IEZBTFNFLCBmaWcuaGVpZ2h0ID0gOCwgaW5jbHVkZSA9IEZBTFNFLCBldmFsID0gRkFMU0V9CiMjIyMgTG93ZXN0IEROQW0gcC12YWx1ZXMKdGFiIDwtIHJlYWRyOjpyZWFkX2NzdigicmVzdWx0cy9yZXN1bHRzX3NpbmdsZV9jcGdfbG1fMjUwa2Jfd2luZG93LmNzdiIsIGNvbF90eXBlcyA9IHJlYWRyOjpjb2xzKCkpCmxpc3QgPC0gcGx5cjo6YWxwbHkodGFiW29yZGVyKHRhYiRhbGxfcHZhbF9tZXQucmVzaWR1YWwpWzE6MTBdLF0sCiAgICAgICAgICAgICAgICAgICAgLm1hcmdpbnMgPSAxLAogICAgICAgICAgICAgICAgICAgIC5mdW4gPSBmdW5jdGlvbihyb3cpewogICAgICAgICAgICAgICAgICAgICAgcGxvdFRhcmdldEROQW0ocm93KQogICAgICAgICAgICAgICAgICAgIH0sLmluZm9ybSA9IFRSVUUKKQpsaXN0CmBgYAoKCgoKYGBge1IsIHNob3cgPSBGQUxTRSwgZmlnLmhlaWdodCA9IDgsIGluY2x1ZGUgPSBGQUxTRSwgZXZhbCA9IEZBTFNFfQojIyMjIExvd2VzdCBjYXNlcyBETkFtIHAtdmFsdWVzCnRhYiA8LSByZWFkcjo6cmVhZF9jc3YoInJlc3VsdHMvcmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvdy5jc3YiLCBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpKQpsaXN0IDwtIHBseXI6OmFscGx5KHRhYltvcmRlcih0YWIkY2FzZXNfcHZhbF9tZXQucmVzaWR1YWwpWzE6MTBdLF0sCiAgICAgICAgICAgICAgICAgICAgLm1hcmdpbnMgPSAxLAogICAgICAgICAgICAgICAgICAgIC5mdW4gPSBmdW5jdGlvbihyb3cpewogICAgICAgICAgICAgICAgICAgICAgcGxvdFRhcmdldEROQW0ocm93KQogICAgICAgICAgICAgICAgICAgIH0sLmluZm9ybSA9IFRSVUUKKQpsaXN0CmBgYAoKCgpgYGB7Uiwgc2hvdyA9IEZBTFNFLCBmaWcuaGVpZ2h0ID0gOCwgaW5jbHVkZSA9IEZBTFNFLCBldmFsID0gRkFMU0V9CiMjIyMgTG93ZXN0IGNvbnRyb2wgRE5BbSBwLXZhbHVlcwp0YWIgPC0gcmVhZHI6OnJlYWRfY3N2KCJyZXN1bHRzL3Jlc3VsdHNfc2luZ2xlX2NwZ19sbV8yNTBrYl93aW5kb3cuY3N2IiwgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKSkKbGlzdCA8LSBwbHlyOjphbHBseSh0YWJbb3JkZXIodGFiJGNvbnRyb2xfcHZhbF9tZXQucmVzaWR1YWwpWzE6MTBdLF0sCiAgICAgICAgICAgICAgICAgICAgLm1hcmdpbnMgPSAxLAogICAgICAgICAgICAgICAgICAgIC5mdW4gPSBmdW5jdGlvbihyb3cpewogICAgICAgICAgICAgICAgICAgICAgcGxvdFRhcmdldEROQW0ocm93KQogICAgICAgICAgICAgICAgICAgIH0sLmluZm9ybSA9IFRSVUUKKQpsaXN0CmBgYAoKCiMjIyBSZXN1bHRzCgpgYGB7Un0KdGFiLmNwZyA8LSByZWFkcjo6cmVhZF9jc3YoInJlc3VsdHMvcmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvdy5jc3YiLCBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpKQp0YWIuY3BnJGZkci5jb250cm9scyA8LSBwLmFkanVzdCh0YWIuY3BnJGNvbnRyb2xfcHZhbF9tZXQucmVzaWR1YWwsbWV0aG9kID0gImZkciIpCnRhYi5jcGckZmRyLmNhc2VzIDwtIHAuYWRqdXN0KHRhYi5jcGckY2FzZXNfcHZhbF9tZXQucmVzaWR1YWwsbWV0aG9kID0gImZkciIpCgpvdXRwdXQgPC0gdGFiLmNwZ1ssYygiY3BnIiwiZ2VuZV9leHRlcm5hbF9nZW5lX25hbWUiLAogICAgICAgICAgICAgICAgICAgICAiY2FzZXNfZXN0aW1hdGVfbWV0LnJlc2lkdWFsIiwiY2FzZXNfcHZhbF9tZXQucmVzaWR1YWwiLCJmZHIuY2FzZXMiLAogICAgICAgICAgICAgICAgICAgICAiY29udHJvbF9lc3RpbWF0ZV9tZXQucmVzaWR1YWwiLCJjb250cm9sX3B2YWxfbWV0LnJlc2lkdWFsIiwiZmRyLmNvbnRyb2xzIildIApjb2xuYW1lcyhvdXRwdXQpIDwtIGMoImNwZyIsCiAgICAgICAgICAgICAgICAgICAgICAiZ2VuZVN5bWJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAiZXN0aW1hdGUuY2FzZXMiLAogICAgICAgICAgICAgICAgICAgICAgInB2YWwuY2FzZXMiLAogICAgICAgICAgICAgICAgICAgICAgImVzdGltYXRlLmNvbnRyb2xzIiwKICAgICAgICAgICAgICAgICAgICAgICJwdmFsLmNvbnRyb2xzIgopCmBgYAoKYGBge1IsIGV2YWwgPSBGQUxTRX0Kd3JpdGUuY3N2KG91dHB1dCxmaWxlID0gInJlc3VsdHMvcmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvd19yZW5hbWVkLmNzdiIpCmBgYAoKYGBge1IsIGV2YWwgPSBGQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQpvdXRwdXQgJT4lIGRwbHlyOjpmaWx0ZXIob3V0cHV0JGZkci5jYXNlcyA8IDAuMDEgfCBvdXRwdXQkZmRyLmNvbnRyb2xzIDwgMC4wMSkgJT4lCiAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSAndG9wJywKICAgICAgICAgICAgICAgIHN0eWxlID0gImJvb3RzdHJhcCIsCiAgICAgICAgICAgICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLAogICAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JmcnRpcCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gSSgnY29sdmlzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlzID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApLCAKICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBjYXB0aW9uID0gIkxpbmVyIG1vZGVsIFRhcmdldC9ETkFtIHJlc3VsdHMgLSBzaW5nbGUgY3BnIikKYGBgCgoKIyBTcGxpdHRpbmcgcmVzdWx0cyBieSBncm91cCAKCiMjIERNUnMKYGBge1J9CmRtciA8LSByZWFkLmNzdigKICAicmVzdWx0cy9yZXN1bHRzX3JlZ2lvbnNfbG1fMjUwa2Jfd2luZG93X3JlbmFtZWQuY3N2IgopCnBhdGhEcm9wYm94IDwtIGZpbGUucGF0aChkaXIoIn4iLCBwYXR0ZXJuID0gIkRyb3Bib3giLCBmdWxsLm5hbWVzID0gVFJVRSkpCmRtcl9tZXRhIDwtIHJlYWQuY3N2KAogIGZpbGUucGF0aChwYXRoRHJvcGJveCwKICAgICAgICAgICAgImNvTWV0aERNUl9tZXRhQW5hbHlzaXMvIiwKICAgICAgICAgICAgImNvZGVfdmFsaWRhdGlvbi9NZXRhX2FuYWx5c2lzX2NvZGUvbWV0YV9hbmFseXNpc19yZWdpb25fcmVzdWx0cyIsCiAgICAgICAgICAgICIvc3RlcDRfZG1yX3ZzX2NwZ3MvbWV0YV9hbmFseXNpc19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19vdl9jb21iX3Bfd2l0aF9hbGwuY3N2IikKKVssIGMoIlJPU01BUF9jb01ldGhSZWdpb24iLAogICAgICAiR1JFQVRfYW5ub3RhdGlvbiIsCiAgICAgICJVQ1NDX1JlZkdlbmVfR3JvdXAiLAogICAgICAiVUNTQ19SZWZHZW5lX0FjY2Vzc2lvbiIsCiAgICAgICJVQ1NDX1JlZkdlbmVfTmFtZSIsCiAgICAgICJzdGF0ZSIpCiAgXQoKZG1yLmFubm90IDwtIG1lcmdlKAogIGRtciwgZG1yX21ldGEsCiAgYnkueCA9ICJjb01ldGhETVIiLAogIGJ5LnkgPSAiUk9TTUFQX2NvTWV0aFJlZ2lvbiIsCiAgc29ydCA9IEZBTFNFCikKCmRtci5hbm5vdCA8LSBkbXIuYW5ub3RbLCBjKDEsMzo5LDIxOjI0LDEwLDI1LDExOjE4KV0KYGBgCgpgYGB7UiwgZXZhbCA9IEZBTFNFfQp3cml0ZS5jc3YoCiAgZG1yLmFubm90LAogICJyZXN1bHRzX3JlZ2lvbnNfbG1fMjUwa2Jfd2luZG93X3JlbmFtZWRfd2l0aF9hbm5vdC5jc3YiCikKYGBgCgpgYGB7Un0KZG1yX2Nhc2UgPC0gZG1yLmFubm90ICU+JQogIGdyb3VwX2J5KGNvTWV0aERNUikgJT4lCiAgZmlsdGVyKHB2YWwuY2FzZXMgPT0gbWluKHB2YWwuY2FzZXMpKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkKCmRtcl9jYXNlJGZkci5jYXNlcy5hZGp1c3RlZCA8LSBwLmFkanVzdCgKICBkbXJfY2FzZSRwdmFsLmNhc2VzLCBtZXRob2QgPSAiZmRyIgopCgpkbXJfY2FzZSA8LSBkbXJfY2FzZVssYygxOjQsIDIzLDk6MjIpXQpkbXJfY2FzZQpgYGAKCmBgYHtSLCBldmFsID0gRkFMU0V9CndyaXRlLmNzdigKICBkbXJfY2FzZSwKICAicmVzdWx0c19yZWdpb25zX2xtXzI1MGtiX3dpbmRvd19yZW5hbWVkX21vc3RTaWdDYXNlcy5jc3YiLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKYGBgCgpgYGB7Un0KZG1yX2NvbnRyb2wgPC0gZG1yLmFubm90ICU+JQogIGdyb3VwX2J5KGNvTWV0aERNUikgJT4lCiAgZmlsdGVyKHB2YWwuY29udHJvbHMgPT0gbWluKHB2YWwuY29udHJvbHMpKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkKZG1yX2NvbnRyb2wkZmRyLmNvbnRyb2xzLmFkanVzdGVkIDwtIHAuYWRqdXN0KAogIGRtcl9jb250cm9sJHB2YWwuY29udHJvbHMsIG1ldGhvZCA9ICJmZHIiCikKZG1yX2NvbnRyb2wgPC0gZG1yX2NvbnRyb2xbLGMoMToyLCA2OjcsIDIzLDk6MjIpXQpkbXJfY29udHJvbApgYGAKCmBgYHtSLCBldmFsID0gRkFMU0V9CndyaXRlLmNzdigKICBkbXJfY29udHJvbCwKICAicmVzdWx0c19yZWdpb25zX2xtXzI1MGtiX3dpbmRvd19yZW5hbWVkX21vc3RTaWdDb250cm9scy5jc3YiLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKCmBgYAoKIyMgQ3BHcwpgYGB7Un0KY3BnIDwtIHJlYWQuY3N2KAogICJyZXN1bHRzL3Jlc3VsdHNfc2luZ2xlX2NwZ19sbV8yNTBrYl93aW5kb3dfcmVuYW1lZC5jc3YiCikKY3BnX21ldGEgPC0gcmVhZC5jc3YoCiAgICBmaWxlLnBhdGgocGF0aERyb3Bib3gsCiAgICAgICAgICAgICJjb01ldGhETVJfbWV0YUFuYWx5c2lzLyIsCiAgICAgICAgICAgICJjb2RlX3ZhbGlkYXRpb24vTWV0YV9hbmFseXNpc19jb2RlL21ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19yZXN1bHRzLyIsCiAgICAgICAgICAgICIvbWV0YV9hbmFseXNpc19zaW5nbGVfY3BnX3NpZ19ub19jcm9zc0h5Yl9zbW9raW5nX3dpdGhfc3RhdGVfZ3JlYXRBbm5vdF9kZi5jc3YiKQopWywgYygiY3BnIiwKICAgICAgIkdSRUFUX2Fubm90YXRpb24iLAogICAgICAiVUNTQ19SZWZHZW5lX0dyb3VwIiwKICAgICAgIlVDU0NfUmVmR2VuZV9BY2Nlc3Npb24iLAogICAgICAiVUNTQ19SZWZHZW5lX05hbWUiLAogICAgICAiUmVsYXRpb25fdG9fSXNsYW5kIiwKICAgICAgInN0YXRlIiwKICAgICAgImVzdGltYXRlIiwgCiAgICAgICJzZSIsIAogICAgICAicFZhbC5maXhlZCIsIAogICAgICAicFZhbC5yYW5kb20iLAogICAgICAicFZhbFEiLCAKICAgICAgImRpcmVjdGlvbiIsIAogICAgICAicFZhbC5maW5hbCIsIAogICAgICAiZmRyIikKICBdCgpjcGcuYW5ub3QgPC0gbWVyZ2UoCiAgY3BnLCBjcGdfbWV0YSwKICBieSA9ICJjcGciLAogIHNvcnQgPSBGQUxTRQopICU+JQogIHNlbGVjdCgtWCkKY3BnLmFubm90CmBgYAoKYGBge1IsIGV2YWwgPSBGQUxTRX0Kd3JpdGUuY3N2KAogIGNwZy5hbm5vdCwKICAicmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvd19yZW5hbWVkX3dpdGhfYW5ub3QuY3N2IgopCmBgYAoKYGBge1J9CmNwZ19jYXNlIDwtIGNwZy5hbm5vdCAlPiUKICBncm91cF9ieShjcGcpICU+JQogIGZpbHRlcihwdmFsLmNhc2VzID09IG1pbihwdmFsLmNhc2VzKSkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpCgpjcGdfY2FzZSRmZHIuY2FzZXMuYWRqdXN0ZWQgPC0gcC5hZGp1c3QoCiAgY3BnX2Nhc2UkcHZhbC5jYXNlcywgbWV0aG9kID0gImZkciIKKQpjcGdfY2FzZSA8LSBjcGdfY2FzZVssIGMoMTo0LCAyNSwgMTUsMTc6MjQpXQpjcGdfY2FzZQpgYGAKCmBgYHtSLCBldmFsID0gRkFMU0V9CndyaXRlLmNzdigKICBjcGdfY2FzZSwKICAicmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvd19yZW5hbWVkX21vc3RTaWdDYXNlcy5jc3YiLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKYGBgCgpgYGB7Un0KY3BnX2NvbnRyb2wgPC0gY3BnLmFubm90ICU+JQogIGdyb3VwX2J5KGNwZykgJT4lCiAgZmlsdGVyKHB2YWwuY29udHJvbHMgPT0gbWluKHB2YWwuY29udHJvbHMpKSAlPiUKICBkaXN0aW5jdChjcGcsIC5rZWVwX2FsbCA9IFRSVUUpICU+JQogIGFzLmRhdGEuZnJhbWUoKQoKY3BnX2NvbnRyb2wkZmRyLmNvbnRyb2xzLmFkanVzdGVkIDwtIHAuYWRqdXN0KAogIGNwZ19jb250cm9sJHB2YWwuY29udHJvbHMsIG1ldGhvZCA9ICJmZHIiCikKY3BnX2NvbnRyb2wgPC0gY3BnX2NvbnRyb2xbLCBjKDE6Miw2OjcsIDI1LCAxNSwgMTc6MjQpXQpjcGdfY29udHJvbApgYGAKCmBgYHtSLCBldmFsID0gRkFMU0V9CndyaXRlLmNzdigKICBjcGdfY29udHJvbCwKICAicmVzdWx0c19zaW5nbGVfY3BnX2xtXzI1MGtiX3dpbmRvd19yZW5hbWVkX21vc3RTaWdDb250cm9scy5jc3YiLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKYGBgCgoKIyBTZXNzaW9uIGluZm9ybWF0aW9uCmBgYHtSfQpkZXZ0b29sczo6c2Vzc2lvbl9pbmZvKCkKYGBgCg==