1 Revisiting my first tnseq analyses

In my continued effort to better document my work, I am rerunning my 2015 analyses of our S. pyogenes 5448 tnseq. Hopefully little effort will be required. One important caveat: this document used the precursor to the hpgltools: ‘myr’, which was a not-terrible first effort for an R package. But it was of much lower quality than its successor.

Looking further down, fairly significant changes will need to be made to get later analyses to work. So rather than delete what is here, I am going to create new code blocks following every existing code block with material which represents the current state of my work.

1.1 Loading myr

Here we can see how I used to load myr and its accessory code. This has been improved.

## Time-stamp: <Tue Dec  2 17:07:18 2014 Ashton Trey Belew (abelew@gmail.com)>
rm(list=ls())
load("RData.0")
library(myr)
autoloads()
save(list = ls(all=TRUE), file="RData.0")

1.2 Setting up options.

These options have also been significantly improved since I wrote the original document.

opts_knit$set(fig.width=800/192, fig.height=800/192, dpi=192, error=TRUE, stop_on_error=FALSE)
save(list = ls(all=TRUE), file="RData")
render("tnseq_v0.rmd", output_format="html_document")
#knit("rnaseq_mga.rmd")
render("tnseq_v0.rmd", output_format="pdf_document")
## A reminder for emacs (ess-resynch)

1.3 plot options?

This also has been improved, it is now maintained within hpgltools.

theme_set(theme_bw(base_size = 10))

2 Strain 5448

2.1 Genome annotation input

2.1.1 Note from the future

I am super curious to see how much of this old code works! I am thinking that I will just add some library invocations to try to change as little as possible of the original code.

library(rtracklayer) ## import.gff3
library(XLConnect) ## loadWorkBook and such
library(Biobase)  ## Creating annotateddataframes
library(Rsamtools) ## FaFile
library(ggplot2)
library(edgeR)
library(limma)
## annotations_5448 = import.gff3("reference/genbank/mgas_5005.gff", asRangedData=FALSE)
annotations_5448 = import.gff3("reference/genbank/mgas_5005.gff") ## asRangedData has been deprecated since I wrote this.
annotation_5448_info = as.data.frame(annotations_5448)
rownames(annotation_5448_info) = make.names(annotation_5448_info$locus_tag, unique=TRUE)
genes_5448 = annotation_5448_info[annotation_5448_info$type=="gene",]
rownames(genes_5448) = make.names(genes_5448$locus_tag, unique=TRUE)
gene_annotations_5448 = subset(genes_5448, select = c("start", "end", "width", "strand", "gene", "locus_tag", "old_locus_tag"))
short_annotations_5448 = gene_annotations_5448[,c("gene", "locus_tag", "old_locus_tag")]
write_xls(short_annotations_5448, "genes", rowname="ID", file="excel/5448_data_v0.xls")

microbes_5448 = read.csv(file="reference/microbesonline/MGAS_5005_annotations.tab.gz", header=1, sep="\t")
microbes_go_5448 = microbes_5448[,c("sysName","GO")]
go_entries_5448 = strsplit(as.character(microbes_go_5448$GO), split=",", perl=TRUE)
microbes_go_oneperrow_5448 = data.frame(name = rep(microbes_go_5448$sysName, sapply(go_entries_5448, length)), GO = unlist(go_entries_5448))
microbes_go_5448 = microbes_go_oneperrow_5448
rm(microbes_go_oneperrow_5448)
rm(go_entries_5448)
## These are used for gene ontology stuff...
microbes_lengths_5448 = microbes_5448[,c("sysName", "start","stop")]
microbes_lengths_5448$length = abs(microbes_5448$start - microbes_5448$stop)
microbes_lengths_5448 = microbes_lengths_5448[,c("sysName","length")]

2.1.2 Make tooltips for interactive graphs 5448

tooltip_data_5448 = genes_5448
tooltip_data_5448 = tooltip_data_5448[,c("gene", "locus_tag")]
tooltip_data_5448$tooltip = paste(tooltip_data_5448$gene, tooltip_data_5448$locus_tag, sep=": ")
tooltip_data_5448$tooltip = gsub("\\+", " ", tooltip_data_5448$tooltip)
tooltip_data_5448 = tooltip_data_5448[-1]
tooltip_data_5448 = tooltip_data_5448[-1]
head(tooltip_data_5448)
##                           tooltip
## M5005_Spy0001 dnaA: M5005_Spy0001
## M5005_Spy0002 dnaN: M5005_Spy0002
## M5005_Spy0003   NA: M5005_Spy0003
## M5005_Spy0004   NA: M5005_Spy0004
## M5005_Spy0005  pth: M5005_Spy0005
## M5005_Spy0006 trcF: M5005_Spy0006

2.1.3 Set up the experimental design 5448

library_colors = list("9"="yellow4",
    "11"="darkgreen",
    "12"="red",
    "34"="darkblue")
time_colors = list(t0="white",
    t1="lightgray",
    t2="darkgray",
    t3="black")

sample_definitions_5448 = read.csv(file="all_samples_5448_v0.csv", sep=",")
sample_definitions_5448 = sample_definitions_5448[grepl('^HPGL', sample_definitions_5448$Sample.ID, perl=TRUE),]
sample_definitions_5448$colors = library_colors[ as.character(sample_definitions_5448$Library) ]
sample_definitions_5448$counts = paste("data/count_tables/05v0M1l20gen_", sample_definitions_5448$Strain, "_",sample_definitions_5448$Replicate, sample_definitions_5448$Time, "_genome.count.gz", sep="")
sample_definitions_5448 = as.data.frame(sample_definitions_5448)
rownames(sample_definitions_5448) = sample_definitions_5448$Sample.ID
all_count_tables_5448 = my_read_files(as.character(sample_definitions_5448$Sample.ID), as.character(sample_definitions_5448$counts))
all_count_matrix_5448 = as.matrix(all_count_tables_5448)
gene_info_5448 = all_count_matrix_5448[rownames(all_count_matrix_5448) %in% genes_5448$locus_tag,]
all_count_matrix_5448 = all_count_matrix_5448[rownames(all_count_matrix_5448) %in% genes_5448$locus_tag,]
metadata_5448 = new("AnnotatedDataFrame", data.frame(sample=sample_definitions_5448$Sample.ID,
    condition=sample_definitions_5448$Time,
    batch=sample_definitions_5448$Library,
    strain=sample_definitions_5448$Strain,
    color=as.character(sample_definitions_5448$colors),
    counts=sample_definitions_5448$counts))

sampleNames(metadata_5448) = colnames(all_count_matrix_5448)
feature_data_5448 = new("AnnotatedDataFrame", as.data.frame(gene_info_5448))
featureNames(feature_data_5448) = rownames(all_count_matrix_5448)
experiment_5448 = new("ExpressionSet", exprs=all_count_matrix_5448,
    phenoData=metadata_5448, featureData=feature_data_5448)
print(experiment_5448)
## ExpressionSet (storageMode: lockedEnvironment)
## assayData: 1926 features, 16 samples 
##   element names: exprs 
## protocolData: none
## phenoData
##   sampleNames: HPGL0259 HPGL0260 ... HPGL0274 (16 total)
##   varLabels: sample condition ... counts (6 total)
##   varMetadata: labelDescription
## featureData
##   featureNames: M5005_Spy0001 M5005_Spy0002 ... M5005_SpyT0067
##     (1926 total)
##   fvarLabels: HPGL0259 HPGL0260 ... HPGL0274 (16 total)
##   fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
summary(exprs(experiment_5448))
##     HPGL0259         HPGL0260          HPGL0261          HPGL0262      
##  Min.   :     0   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:   111   1st Qu.:    185   1st Qu.:     36   1st Qu.:      0  
##  Median :   612   Median :   1849   Median :    467   Median :     64  
##  Mean   :  1433   Mean   :   5922   Mean   :   4840   Mean   :   4030  
##  3rd Qu.:  1519   3rd Qu.:   4636   3rd Qu.:   1398   3rd Qu.:    262  
##  Max.   :237128   Max.   :1402918   Max.   :2951209   Max.   :5625610  
##     HPGL0263         HPGL0264         HPGL0265         HPGL0266     
##  Min.   :     0   Min.   :     0   Min.   :     0   Min.   :     0  
##  1st Qu.:     1   1st Qu.:     0   1st Qu.:     0   1st Qu.:     1  
##  Median :    52   Median :    32   Median :     3   Median :    13  
##  Mean   :  4278   Mean   :  4898   Mean   :  4314   Mean   :  5936  
##  3rd Qu.:  1801   3rd Qu.:  1297   3rd Qu.:   945   3rd Qu.:  1062  
##  Max.   :149218   Max.   :444931   Max.   :288152   Max.   :709399  
##     HPGL0267          HPGL0268          HPGL0269          HPGL0270      
##  Min.   :      0   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:      0   1st Qu.:      1   1st Qu.:      0   1st Qu.:      0  
##  Median :    145   Median :    162   Median :     86   Median :     16  
##  Mean   :   4403   Mean   :   5614   Mean   :   4890   Mean   :   6657  
##  3rd Qu.:   1520   3rd Qu.:   1734   3rd Qu.:    957   3rd Qu.:    294  
##  Max.   :1578442   Max.   :1915635   Max.   :2516667   Max.   :6723426  
##     HPGL0271        HPGL0272          HPGL0273          HPGL0274      
##  Min.   :    0   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:    0   1st Qu.:     25   1st Qu.:      0   1st Qu.:      1  
##  Median :   78   Median :    576   Median :     48   Median :     32  
##  Mean   :  289   Mean   :   6819   Mean   :   4977   Mean   :   5931  
##  3rd Qu.:  321   3rd Qu.:   2311   3rd Qu.:    371   3rd Qu.:    150  
##  Max.   :31570   Max.   :4770693   Max.   :2709879   Max.   :2992917
head(fData(experiment_5448))
##               HPGL0259 HPGL0260 HPGL0261 HPGL0262 HPGL0263 HPGL0264
## M5005_Spy0001        1      115       34        0        1        0
## M5005_Spy0002       48      102       87       40        0        0
## M5005_Spy0003      169      521       44        0        0        0
## M5005_Spy0004     1165     2126      877      510        3       23
## M5005_Spy0005        0        5        1        0        3        0
## M5005_Spy0006    10774    34771    15317     7244     4341     2834
##               HPGL0265 HPGL0266 HPGL0267 HPGL0268 HPGL0269 HPGL0270
## M5005_Spy0001        0        3        2        2        0        0
## M5005_Spy0002        2        2        8        6        1        4
## M5005_Spy0003        4        0        0        1        0        1
## M5005_Spy0004        1        7      768      716     1029      409
## M5005_Spy0005        0        0        2        2        1        1
## M5005_Spy0006     5032     6313     7945    21140     9994     2537
##               HPGL0271 HPGL0272 HPGL0273 HPGL0274
## M5005_Spy0001        0       20        1        1
## M5005_Spy0002        0       43        1        1
## M5005_Spy0003        0        0        0        0
## M5005_Spy0004      176      924      261      301
## M5005_Spy0005       39        0        2        0
## M5005_Spy0006     1309    14618     2390     2729
head(pData(experiment_5448))
##            sample condition batch strain     color
## HPGL0259 HPGL0259        t0     9   5448   yellow4
## HPGL0260 HPGL0260        t1     9   5448   yellow4
## HPGL0261 HPGL0261        t2     9   5448   yellow4
## HPGL0262 HPGL0262        t3     9   5448   yellow4
## HPGL0263 HPGL0263        t0    11   5448 darkgreen
## HPGL0264 HPGL0264        t1    11   5448 darkgreen
##                                                            counts
## HPGL0259 data/count_tables/05v0M1l20gen_5448_l1t0_genome.count.gz
## HPGL0260 data/count_tables/05v0M1l20gen_5448_l1t1_genome.count.gz
## HPGL0261 data/count_tables/05v0M1l20gen_5448_l1t2_genome.count.gz
## HPGL0262 data/count_tables/05v0M1l20gen_5448_l1t3_genome.count.gz
## HPGL0263 data/count_tables/05v0M1l20gen_5448_l2t0_genome.count.gz
## HPGL0264 data/count_tables/05v0M1l20gen_5448_l2t1_genome.count.gz
raw_data_5448 = exprs(experiment_5448)
write_xls(raw_data_5448, "raw_data", rowname="row.names", file="excel/5448_data_v0.xls")

2.1.4 normalize on TAs 5448

gas_rawseq_5448 = FaFile("reference/genbank/mgas_5005.fasta")
cds_entries_5448 = import.gff3("reference/genbank/mgas_5005.gff")
cds_entries_5448 = subset(cds_entries_5448, type=="gene")
names(cds_entries_5448) = rownames(cds_entries_5448)
gas_cds_5448 = getSeq(gas_rawseq_5448, cds_entries_5448)
names(gas_cds_5448) = cds_entries_5448$locus_tag
pattern = "TA"
dict = PDict(pattern, max.mismatch=0)
result_5448 = vcountPDict(dict, gas_cds_5448)
num_tas_5448 = data.frame(name=names(gas_cds_5448), tas=as.data.frame(t(result_5448)))

2.1.5 Count TAs 5448

2.1.5.1 Note from the future

Wow, so far I only needed to add some library() and remove asRangedData. Interestingly, what is coming has been pulled into hpgltools and standardized.

plot_saturation = function(file) {
    ## Test arguments
    ##    file = "data/essentiality/mh_ess/5448/tas_t0v0.txt"
    ## End test arguments
    table = read.table(file=file, header=1)
    second_file = paste(file, "-inter", sep="")
    second_table = read.table(file=second_file, header=1)
    table = rbind(table, second_table)
    data_list = as.numeric(table$reads)
    max_reads = max(data_list, na.rm=TRUE)
    log2_data_list = as.numeric(log2(table$reads + 1))
    data_plot = my_histogram(log2_data_list, bins=500)
    data_plot = data_plot + scale_x_continuous(limits=c(0,6)) + scale_y_continuous(limits=c(0,2))
    print(sprintf("The maximum value is: %s ", max_reads))
    print(summary(data_list))
    raw = table(unlist(data_list))
    num_zeros = raw[as.numeric(names(raw)) == 0]
    num_zeros
    num_gt_ones = raw[as.numeric(names(raw)) >= 1]
    num_gt_one = sum(num_gt_ones)
    num_gt_one
    num_gt_twos = raw[as.numeric(names(raw)) >= 2]
    num_gt_two = sum(num_gt_twos)
    num_gt_two
    num_gt_fours = raw[as.numeric(names(raw)) >= 4]
    num_gt_four = sum(num_gt_fours)
    num_gt_four
    num_gt_eights = raw[as.numeric(names(raw)) >= 8]
    num_gt_eight = sum(num_gt_eights)
    num_gt_eight
    num_gt_sixteens = raw[as.numeric(names(raw)) >= 16]
    num_gt_sixteen = sum(num_gt_sixteens)
    num_gt_sixteen
    num_gt_thirtytwos = raw[as.numeric(names(raw)) >= 32]
    num_gt_thirtytwo = sum(num_gt_thirtytwos)
    num_gt_thirtytwo
    saturation_ratio_1 = num_gt_one / num_zeros
    print(sprintf("Saturation ratio of 1s to 0s is: %s", saturation_ratio_1))
    saturation_ratio_8 = num_gt_eight / num_zeros
    print(sprintf("Saturation ratio of 8 to 0s is: %s", saturation_ratio_8))
    saturation_ratio_32 = num_gt_thirtytwo / num_zeros
    print(sprintf("Saturation ratio of 32 to 0s is: %s", saturation_ratio_32))
    print(sprintf("The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: %s %s %s %s %s %s %s %s %s %s", num_zeros, num_gt_one, num_gt_two, num_gt_four, num_gt_eight, num_gt_sixteen, num_gt_thirtytwo, saturation_ratio_1, saturation_ratio_8, saturation_ratio_32))
    return(data_plot)
}

### The following information will be dumped into ta_summary.csv
## Start with the combined libraries
plot_saturation("data/essentiality/mh_ess/5448/tas_t0v0.txt")
## [1] "The maximum value is: 1201324 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0     192      20 1201324 
## [1] "Saturation ratio of 1s to 0s is: 0.666616652287533"
## [1] "Saturation ratio of 8 to 0s is: 0.525963714567938"
## [1] "Saturation ratio of 32 to 0s is: 0.338972454580692"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 79977 53314 48250 45092 42065 36865 27110 0.666616652287533 0.525963714567938 0.338972454580692"
## Warning: Removed 18489 rows containing non-finite values (stat_bin).
## Warning: Removed 18489 rows containing non-finite values (stat_density).
## Warning: Removed 2 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/5448/tas_t1v0.txt")
## [1] "The maximum value is: 2348282 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       5     412      67 2348282 
## [1] "Saturation ratio of 1s to 0s is: 1.52933697673536"
## [1] "Saturation ratio of 8 to 0s is: 1.18649664123876"
## [1] "Saturation ratio of 32 to 0s is: 0.845060533606589"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 52698 80593 74428 69199 62526 54309 44533 1.52933697673536 1.18649664123876 0.845060533606589"
## Warning: Removed 34206 rows containing non-finite values (stat_bin).
## Warning: Removed 34206 rows containing non-finite values (stat_density).
## Warning: Removed 2 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/5448/tas_t2v0.txt")
## [1] "The maximum value is: 2123076 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0     346      16 2123076 
## [1] "Saturation ratio of 1s to 0s is: 0.900762923351159"
## [1] "Saturation ratio of 8 to 0s is: 0.612249554367201"
## [1] "Saturation ratio of 32 to 0s is: 0.363065953654189"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 70125 63166 56967 51116 42934 33923 25460 0.900762923351159 0.612249554367201 0.363065953654189"
## Warning: Removed 17609 rows containing non-finite values (stat_bin).
## Warning: Removed 17609 rows containing non-finite values (stat_density).
## Warning: Removed 2 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/5448/tas_t3v0.txt")
## [1] "The maximum value is: 6867466 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0     425       0 6867466 
## [1] "Saturation ratio of 1s to 0s is: 0.296264599764653"
## [1] "Saturation ratio of 8 to 0s is: 0.182296478551353"
## [1] "Saturation ratio of 32 to 0s is: 0.118898732823091"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 102827 30464 24716 21800 18745 15547 12226 0.296264599764653 0.182296478551353 0.118898732823091"
## Warning: Removed 7990 rows containing non-finite values (stat_bin).
## Warning: Removed 7990 rows containing non-finite values (stat_density).
## Warning: Removed 1 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/nz131/tas_t0v0.txt")
## [1] "The maximum value is: 45032 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0      13      10   45032 
## [1] "Saturation ratio of 1s to 0s is: 0.487562357891879"
## [1] "Saturation ratio of 8 to 0s is: 0.387552177011572"
## [1] "Saturation ratio of 32 to 0s is: 0.196027194262508"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 88401 43101 39254 36826 34260 29125 17329 0.487562357891879 0.387552177011572 0.196027194262508"
## Warning: Removed 6483 rows containing non-finite values (stat_bin).
## Warning: Removed 6483 rows containing non-finite values (stat_density).
## Warning: Removed 1 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/nz131/tas_t1v0.txt")
## [1] "The maximum value is: 658647 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       9     166      55  658647 
## [1] "Saturation ratio of 1s to 0s is: 1.77993404363267"
## [1] "Saturation ratio of 8 to 0s is: 1.45317520717064"
## [1] "Saturation ratio of 32 to 0s is: 0.932606122103839"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 47304 84198 79307 75717 68741 57308 44116 1.77993404363267 1.45317520717064 0.932606122103839"
## Warning: Removed 30281 rows containing non-finite values (stat_bin).
## Warning: Removed 30281 rows containing non-finite values (stat_density).
## Warning: Removed 1 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/nz131/tas_t2v0.txt")
## [1] "The maximum value is: 2287096 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0      84       2 2287096 
## [1] "Saturation ratio of 1s to 0s is: 0.573197430283889"
## [1] "Saturation ratio of 8 to 0s is: 0.170429123449258"
## [1] "Saturation ratio of 32 to 0s is: 0.0511670195839165"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 83589 47913 35787 23800 14246 7879 4277 0.573197430283889 0.170429123449258 0.0511670195839165"
## Warning: Removed 2374 rows containing non-finite values (stat_bin).
## Warning: Removed 2374 rows containing non-finite values (stat_density).
## Warning: Removed 2 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/nz131/tas_t3v0.txt")
## [1] "The maximum value is: 13835514 "
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##        0        0        0      282        0 13835514 
## [1] "Saturation ratio of 1s to 0s is: 0.155157722748794"
## [1] "Saturation ratio of 8 to 0s is: 0.055350099702211"
## [1] "Saturation ratio of 32 to 0s is: 0.020160050597774"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 113839 17663 11487 8993 6301 3587 2295 0.155157722748794 0.055350099702211 0.020160050597774"
## Warning: Removed 1579 rows containing non-finite values (stat_bin).
## Warning: Removed 1579 rows containing non-finite values (stat_density).
## Warning: Removed 1 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/alabama/tas_t0v0.txt")
## [1] "The maximum value is: 3253458 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0      93       0 3253458 
## [1] "Saturation ratio of 1s to 0s is: 0.0646378350548637"
## [1] "Saturation ratio of 8 to 0s is: 0.0312851948386266"
## [1] "Saturation ratio of 32 to 0s is: 0.0230958586736171"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 124308 8035 5194 4433 3889 3340 2871 0.0646378350548637 0.0312851948386266 0.0230958586736171"
## Warning: Removed 2425 rows containing non-finite values (stat_bin).
## Warning: Removed 2425 rows containing non-finite values (stat_density).
## Warning: Removed 2 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/alabama/tas_t1v0.txt")
## [1] "The maximum value is: 983836 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0      89       0  983836 
## [1] "Saturation ratio of 1s to 0s is: 0.0528815554989817"
## [1] "Saturation ratio of 8 to 0s is: 0.024296715885947"
## [1] "Saturation ratio of 32 to 0s is: 0.0177571283095723"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 125696 6647 4152 3474 3054 2612 2232 0.0528815554989817 0.024296715885947 0.0177571283095723"
## Warning: Removed 1916 rows containing non-finite values (stat_bin).
## Warning: Removed 1916 rows containing non-finite values (stat_density).
## Warning: Removed 2 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/alabama/tas_t2v0.txt")
## [1] "The maximum value is: 4300087 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0      43       0 4300087 
## [1] "Saturation ratio of 1s to 0s is: 0.0474648979785668"
## [1] "Saturation ratio of 8 to 0s is: 0.0128773368369398"
## [1] "Saturation ratio of 32 to 0s is: 0.00768524527883748"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 126346 5997 2623 1926 1627 1299 971 0.0474648979785668 0.0128773368369398 0.00768524527883748"
## Warning: Removed 691 rows containing non-finite values (stat_bin).
## Warning: Removed 691 rows containing non-finite values (stat_density).
## Warning: Removed 1 rows containing missing values (geom_bar).

plot_saturation("data/essentiality/mh_ess/alabama/tas_t3v0.txt")
## [1] "The maximum value is: 5482386 "
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0      62       0 5482386 
## [1] "Saturation ratio of 1s to 0s is: 0.10607516861539"
## [1] "Saturation ratio of 8 to 0s is: 0.0133304360180859"
## [1] "Saturation ratio of 32 to 0s is: 0.00526531328614053"
## [1] "The number of zeros, ones, twos, fours, eights, sixteens, thirtytwos, saturation1, saturation8, saturation32 are: 119651 12692 5253 2654 1595 971 630 0.10607516861539 0.0133304360180859 0.00526531328614053"
## Warning: Removed 422 rows containing non-finite values (stat_bin).
## Warning: Removed 422 rows containing non-finite values (stat_density).
## Warning: Removed 1 rows containing missing values (geom_bar).

qqplot.data <- function (vec) {
### following four lines from base R's qqline()
    y <- quantile(vec[!is.na(vec)], c(0.25, 0.75))
    x <- qnorm(c(0.25, 0.75))
    slope <- diff(y)/diff(x)
    int <- y[1L] - slope * x[1L]
    d <- data.frame(resids = vec)
    ggplot(d, aes(sample = resids)) + stat_qq() + geom_abline(slope = slope, intercept = int)
}
ggQQ = function(lm) {
  # extract standardized residuals from the fit
  d <- data.frame(std.resid = rstandard(lm))
  # calculate 1Q/4Q line
  y <- quantile(d$std.resid[!is.na(d$std.resid)], c(0.25, 0.75))
  x <- qnorm(c(0.25, 0.75))
  slope <- diff(y)/diff(x)
  int <- y[1L] - slope * x[1L]
  p <- ggplot(data=d, aes(sample=std.resid)) +
    stat_qq(shape=1, size=3) +           # open circles
    labs(title="Normal Q-Q",             # plot title
         x="Theoretical Quantiles",      # x-axis label
         y="Standardized Residuals") +   # y-axis label
    geom_abline(slope = slope, intercept = int, linetype="dashed")  # dashed reference line
  return(p)
}

## This section wants the output from essentiality_tas.pl, which I deleted...
##qq_test = time0_tas[,c("forward","reverse")]
##qq_test$forward = log2(qq_test$forward + 1)
##qq_test$reverse = log2(qq_test$reverse + 1)
##qqplot(time0_tas_5448$forward, time1_tas_5448$forward)
##qqplot(qq_test$forward, qq_test$reverse)
##qq_df = data.frame(t0=time0_tas_5448$forward, t1=time1_tas_5448$forward)
####params = as.list(fitdistr(qq_df, "t")$estimate)
##qqplot.data(qq_df)
##ggQQ(lm(t0~t1,data=qq_df))
##ggQQ(lm(forward~reverse, data=qq_test))

2.2 Graph metrics 5448

2.2.1 From the future again

These plotting functions are certain to fail, as they have all been rewritten heavily.

all_expt_5448 = expt_subset(experiment_5448, "")
all_design_5448 = data.frame(all_expt_5448$design)
all_design_5448$longnames = paste(all_design_5448$strain,  all_design_5448$batch, all_design_5448$condition, sep="_")

metrics_5448 = graph_metrics(all_expt_5448, out_type="cpm", norm_type="quant", filter="log2", cormethod="spearman", names=all_design_5448$longnames)
metrics_5448$norm_pcaplot
head(exprs(all_expt_5448$expressionset))
head(gene_annotations_5448)

library(hpgltools)
colnames(all_design_5448)[[1]] <- "sampleid"
tt <- plot_pca(all_expt_5448, design=all_design_5448)


correlations_5448 = my_cor(exprs(all_expt_5448$expressionset), method="spearman")
write_xls(correlations_5448, "sp_cor_prenorm", rowname="row.names", file="excel/5448_data_v0.xls")

library(cbcbSEQ)
test2_5448 = my_norm(expt=all_expt_5448, out_type="cp_seq_m", norm_type="quant", filter="none", fasta="reference/genbank/mgas_5005.fasta", gff="reference/genbank/mgas_5005.gff")
head(test2_5448$counts)

id_gene_annotations_5448 = gene_annotations_5448
rownames(id_gene_annotations_5448) = make.names(id_gene_annotations_5448$locus_tag, unique=TRUE)
no_time3_5448 = expt_subset(all_expt_5448, "condition!='t3'")
notime3_metrics_5448 = graph_metrics(no_time3_5448, out_type="rpkm", norm_type="quant", filter="log2", cormethod="spearman", annotations=id_gene_annotations_5448)
notime3_metrics_5448$norm_corheat
notime3_metrics_5448$norm_pcaplot
all_qrpkm_5448 = my_norm(expt=all_expt_5448, norm="quant", filter="log2", filter_low=FALSE, out_type="rpkm", annotations=id_gene_annotations_5448)$counts
##all_qrpkm = my_norm(expt=all_expt, norm="quant", filter="log2", filter_low=FALSE, out_type="rpkm", annotations=id_gene_annotations)$counts
write_xls(all_qrpkm_5448, "norm_data", file="excel/5448_data_v0.xls", rowname="row.names")
all_norm_expt_5448 = all_expt_5448
correlations_5448 = my_cor(all_qrpkm_5448, method="spearman")
write_xls(correlations_5448, "sp_cor_norm", rowname="row.names", file="excel/5448_data_v0.xls")

## I did that so that I can replace the expressionset with the
## normalized data more easily...
normalized_expressionset_5448 = all_norm_expt_5448$expressionset
exprs(normalized_expressionset_5448) = all_qrpkm_5448
all_norm_expt_5448$expressionset = normalized_expressionset_5448

my_boxplot(expt=all_norm_expt_5448, names=all_design_5448$longnames)
my_disheat(expt=all_norm_expt_5448, names=all_design_5448$longnames, row="condition")
my_corheat(expt=all_norm_expt_5448, names=all_design_5448$longnames, row="condition")

2.3 A new graph_metrics block.

In order to redo the above work, I need to generate a valid expressionset. Sadly, my first efforts at this were imperfect – not terrible or anything, but incomplete.

library(hpgltools)
meta <- pData(experiment_5448)
new_5448 <- create_expt(metadata=pData(experiment_5448),
                        gene_info=annotations_5448$genes,
                        count_dataframe=exprs(experiment_5448),
                        sample_column="sample")
## Reading the sample metadata.
## The sample definitions comprises: 16, 7 rows, columns.
## Matched 1926 annotations and counts.
## Bringing together the count matrix and gene information.
new_norm <- normalize_expt(new_5448, normalize="quant", convert="cpm",
                           filter=TRUE, transform="log2")
## This function will replace the expt$expressionset slot with:
## log2(cpm(hpgl(data)))
## It backs up the current data into a slot named:
##  expt$backup_expressionset. It will also save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep the libsizes in mind
##  when invoking limma.  The appropriate libsize is the non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data unnormalized.  This is necessary for DESeq, but
##  EdgeR/limma might benefit from normalization.  Good choices include quantile,
##  size-factor, tmm, etc.
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: hpgl
## Removing 273 low-count genes (1653 remaining).
## Step 2: not normalizing the data.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 3984 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
new_metrics <- hpgltools::graph_metrics(new_5448)
## Graphing number of non-zero genes with respect to CPM by library.
## Graphing library sizes.
## The scale difference between the smallest and largest
## libraries is > 10. Assuming a log10 scale is better, set scale=FALSE if not.
## Graphing a boxplot.
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, adding 1 to the data.
## Changed 7426 zero count features.
## Graphing a correlation heatmap.
## Graphing a standard median correlation.
## Performing correlation.
## Graphing a distance heatmap.

## Graphing a standard median distance.
## Performing distance.
## Graphing a PCA plot.
## Graphing a T-SNE plot.
## Plotting a density plot.
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, setting them to 0.5.
## Changed 7426 zero count features.
## Plotting the representation of the top-n genes.
## Printing a color to condition legend.

new_norm_metrics <- hpgltools::graph_metrics(new_norm)
## Graphing number of non-zero genes with respect to CPM by library.
## Graphing library sizes.
## Graphing a boxplot.
## Graphing a correlation heatmap.
## Graphing a standard median correlation.
## Performing correlation.
## Graphing a distance heatmap.

## Graphing a standard median distance.
## Performing distance.
## Graphing a PCA plot.
## Graphing a T-SNE plot.
## Plotting a density plot.
## Plotting the representation of the top-n genes.
## Printing a color to condition legend.

new_metrics$libsize

new_metrics$nonzero

new_norm_metrics$pcaplot

new_norm_metrics$tsneplot

## Looks like I can plot pretty much anything for this data once again, yay!
## I am not sure what are good things to plot anymore though, so I might leave
## it at this unless I get to chat with Yoann and see what would be useful to
## revisit.

3 Get comparisons for Yoann

3.1 l1 t0t1

## Compare library 1, t0 t1
comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t0')|(batch=='9' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/intertime/lib1t0_vs_lib1t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l1t0t1v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
comp_5448 <- subset_expt(new_norm,
                         subset="(batch=='9' & condition=='t0')|(batch=='9' & condition=='t1')")
data <- exprs(comp_5448)
sc <- plot_linear_scatter(data)
## Used Bon Ferroni corrected t test(s) between columns.
sc$scatter

sc$correlation
## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 90, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.9032 0.9195
## sample estimates:
##    cor 
## 0.9117

3.2 l1t0t2

## Compare library 1, t0 t2
comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t0')|(batch=='9' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib1t0_vs_lib1t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l1t0t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
comp_5448 <- subset_expt(new_norm,
                         subset="(batch=='9' & condition=='t0')|(batch=='9' & condition=='t2')")
data <- exprs(comp_5448)
sc <- plot_linear_scatter(data)
## Used Bon Ferroni corrected t test(s) between columns.
sc$scatter

sc$correlation
## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 63, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.8250 0.8535
## sample estimates:
##    cor 
## 0.8398

3.3 Compare library 1, t0 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t0')|(batch=='9' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib1t0_vs_lib1t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l1t0t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
comp_5448 <- subset_expt(new_norm,
                         subset="(batch=='9' & condition=='t0')|(batch=='9' & condition=='t3')")
data <- exprs(comp_5448)
sc <- plot_linear_scatter(data)
## Used Bon Ferroni corrected t test(s) between columns.
sc$scatter

sc$correlation
## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 44, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.715 0.759
## sample estimates:
##    cor 
## 0.7378

3.4 Compare library 1, t1 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t1')|(batch=='9' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib1t1_vs_lib1t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l1t1t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
png(file="figures/l1t1t2_hist.png")
sc$both_histogram + scale_y_continuous(limits=c(0,0.25))
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
comp_5448 <- subset_expt(new_norm,
                         subset="(batch=='9' & condition=='t1')|(batch=='9' & condition=='t2')")
data <- exprs(comp_5448)
sc <- plot_linear_scatter(data)
## Used Bon Ferroni corrected t test(s) between columns.
sc$scatter

sc$correlation
## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 120, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.9433 0.9530
## sample estimates:
##    cor 
## 0.9484

3.5 Compare library 1, t1 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t1')|(batch=='9' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib1t1_vs_lib1t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l1t1t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
comp_5448 <- subset_expt(new_norm,
                         subset="(batch=='9' & condition=='t1')|(batch=='9' & condition=='t3')")
data <- exprs(comp_5448)
sc <- plot_linear_scatter(data)
## Used Bon Ferroni corrected t test(s) between columns.
sc$scatter

sc$correlation
## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 53, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7721 0.8083
## sample estimates:
##    cor 
## 0.7909

3.5.1 Stopping here.

Ok, so I demonstrated I can remake all my old plots, but I am not sure how much I care beyond that. I think that demonstrates that I can in fact reproduce my old results.

3.6 Compare library 1, t2 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t2')|(batch=='9' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib1t2_vs_lib1t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l1t2t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.7 Compare library 2, t0 t1

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t0')|(batch=='11' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/intertime/lib2t0_vs_lib2t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l2t0t1v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.8 Compare library 2, t0 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t0')|(batch=='11' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib2t0_vs_lib2t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l2t0t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.9 Compare library 2, t0 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t0')|(batch=='11' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib2t0_vs_lib2t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l2t0t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.10 Compare library 2, t1 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t1')|(batch=='11' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib2t1_vs_lib2t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l2t1t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.11 Compare library 2, t1 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t1')|(batch=='11' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib2t1_vs_lib2t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l2t1t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.12 Compare library 2, t2 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t2')|(batch=='11' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib2t2_vs_lib2t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l2t2t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.13 Compare library 3, t0 t1

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t0')|(batch=='12' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/intertime/lib3t0_vs_lib3t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l3t0t1v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.14 Compare library 3, t0 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t0')|(batch=='12' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib3t0_vs_lib3t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l3t0t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.15 Compare library 3, t0 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t0')|(batch=='12' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib3t0_vs_lib3t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l3t0t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.16 Compare library 3, t1 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t1')|(batch=='12' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib3t1_vs_lib3t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l3t1t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.17 Compare library 3, t1 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t1')|(batch=='12' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib3t1_vs_lib3t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l3t1t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.18 Compare library 3, t2 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t2')|(batch=='12' & condition=='t3')")$expressionset)
## Error in expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t2')|(batch=='12' & condition=='t3')"): object 'all_norm_expt_5448' not found
pdf(file="figures/comparisons/intertime/lib3t2_vs_lib3t3_scatter_v0.pdf")
## Error in Cairo(width, height, file, "pdf", pointsize = pointsize, bg = bg, : could not find function "Cairo"
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l3t2t3v0.html")
## Error in df[, c(1, 2)]: incorrect number of dimensions
sc$scatter

sc$x_histogram

sc$y_histogram

sc$both_histogram
## $plot

## 
## $data_summary
##      first           second      
##  Min.   : 0.00   Min.   : 0.000  
##  1st Qu.: 5.94   1st Qu.: 0.331  
##  Median : 7.74   Median : 3.899  
##  Mean   : 7.18   Mean   : 3.483  
##  3rd Qu.: 8.85   3rd Qu.: 5.360  
##  Max.   :16.91   Max.   :19.467  
## 
## $uncor_t
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  play_all[["expression"]] and play_all[["cond"]] 
## 
##        first 
## second <2e-16
## 
## P value adjustment method: none 
## 
## $bon_t
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  play_all[["expression"]] and play_all[["cond"]] 
## 
##        first 
## second <2e-16
## 
## P value adjustment method: bonferroni
dev.off()
## X11cairo 
##        2
sc$correlation

## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 53, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7721 0.8083
## sample estimates:
##    cor 
## 0.7909
sc$lm_model
## 
## Call:
## robustbase::lmrob(formula = second ~ first, data = df, method = "SMDM")
## 
## Coefficients:
## (Intercept)        first  
##      -2.472        0.833
sc$lm_summary
## 
## Call:
## robustbase::lmrob(formula = second ~ first, data = df, method = "SMDM")
##  \--> method = "SMDM"
## Residuals:
##    Min     1Q Median     3Q    Max 
## -4.869 -0.935  0.140  0.948  7.860 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -2.4715     0.1184   -20.9   <2e-16 ***
## first         0.8327     0.0156    53.2   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Robust residual standard error: 1.53 
## Multiple R-squared:  0.641,  Adjusted R-squared:  0.641 
## Convergence in 8 IRWLS iterations
## 
## Robustness weights: 
##  1176 weights are ~= 1. The remaining 477 ones are summarized as
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.067   0.763   0.895   0.831   0.966   0.999 
## Algorithmic parameters: 
##       tuning.chi1       tuning.chi2       tuning.chi3       tuning.chi4 
##  -0.5000000000000   1.5000000000000                NA   0.5000000000000 
##                bb       tuning.psi1       tuning.psi2       tuning.psi3 
##   0.5000000000000  -0.5000000000000   1.5000000000000   0.9500000000000 
##       tuning.psi4        refine.tol           rel.tol         solve.tol 
##                NA   0.0000001000000   0.0000001000000   0.0000001000000 
##       eps.outlier             eps.x warn.limit.reject warn.limit.meanrw 
##   0.0000604960678   0.0000000000308   0.5000000000000   0.5000000000000 
##      nResample         max.it       best.r.s       k.fast.s          k.max 
##            500             50              2              1            200 
##    maxit.scale      trace.lev            mts     compute.rd      numpoints 
##            200              0           1000              0             10 
## fast.s.large.n 
##           2000 
##                   psi           subsampling                   cov 
##                 "lqq"         "nonsingular"             ".vcov.w" 
## compute.outlier.stats 
##                "SMDM" 
## seed : int(0)

3.19 Compare library 4, t0 t1

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t0')|(batch=='34' & condition=='t1')")$expressionset)
## Error in expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t0')|(batch=='34' & condition=='t1')"): object 'all_norm_expt_5448' not found
pdf(file="figures/comparisons/intertime/lib4t0_vs_lib4t1_scatter_v0.pdf")
## Error in Cairo(width, height, file, "pdf", pointsize = pointsize, bg = bg, : could not find function "Cairo"
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l4t0t1v0.html")
## Error in df[, c(1, 2)]: incorrect number of dimensions
sc$scatter

sc$x_histogram

sc$y_histogram

sc$both_histogram
## $plot

## 
## $data_summary
##      first           second      
##  Min.   : 0.00   Min.   : 0.000  
##  1st Qu.: 5.94   1st Qu.: 0.331  
##  Median : 7.74   Median : 3.899  
##  Mean   : 7.18   Mean   : 3.483  
##  3rd Qu.: 8.85   3rd Qu.: 5.360  
##  Max.   :16.91   Max.   :19.467  
## 
## $uncor_t
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  play_all[["expression"]] and play_all[["cond"]] 
## 
##        first 
## second <2e-16
## 
## P value adjustment method: none 
## 
## $bon_t
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  play_all[["expression"]] and play_all[["cond"]] 
## 
##        first 
## second <2e-16
## 
## P value adjustment method: bonferroni
dev.off()
## X11cairo 
##        2
sc$correlation

## 
##  Pearson's product-moment correlation
## 
## data:  df[, 1] and df[, 2]
## t = 53, df = 1700, p-value <2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7721 0.8083
## sample estimates:
##    cor 
## 0.7909
sc$lm_model
## 
## Call:
## robustbase::lmrob(formula = second ~ first, data = df, method = "SMDM")
## 
## Coefficients:
## (Intercept)        first  
##      -2.472        0.833
sc$lm_summary
## 
## Call:
## robustbase::lmrob(formula = second ~ first, data = df, method = "SMDM")
##  \--> method = "SMDM"
## Residuals:
##    Min     1Q Median     3Q    Max 
## -4.869 -0.935  0.140  0.948  7.860 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -2.4715     0.1184   -20.9   <2e-16 ***
## first         0.8327     0.0156    53.2   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Robust residual standard error: 1.53 
## Multiple R-squared:  0.641,  Adjusted R-squared:  0.641 
## Convergence in 8 IRWLS iterations
## 
## Robustness weights: 
##  1176 weights are ~= 1. The remaining 477 ones are summarized as
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.067   0.763   0.895   0.831   0.966   0.999 
## Algorithmic parameters: 
##       tuning.chi1       tuning.chi2       tuning.chi3       tuning.chi4 
##  -0.5000000000000   1.5000000000000                NA   0.5000000000000 
##                bb       tuning.psi1       tuning.psi2       tuning.psi3 
##   0.5000000000000  -0.5000000000000   1.5000000000000   0.9500000000000 
##       tuning.psi4        refine.tol           rel.tol         solve.tol 
##                NA   0.0000001000000   0.0000001000000   0.0000001000000 
##       eps.outlier             eps.x warn.limit.reject warn.limit.meanrw 
##   0.0000604960678   0.0000000000308   0.5000000000000   0.5000000000000 
##      nResample         max.it       best.r.s       k.fast.s          k.max 
##            500             50              2              1            200 
##    maxit.scale      trace.lev            mts     compute.rd      numpoints 
##            200              0           1000              0             10 
## fast.s.large.n 
##           2000 
##                   psi           subsampling                   cov 
##                 "lqq"         "nonsingular"             ".vcov.w" 
## compute.outlier.stats 
##                "SMDM" 
## seed : int(0)

3.20 Compare library 4, t0 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t0')|(batch=='34' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib4t0_vs_lib4t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l4t0t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.21 Compare library 4, t0 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t0')|(batch=='34' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib4t0_vs_lib4t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l4t0t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.22 Compare library 4, t1 t2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t1')|(batch=='34' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/intertime/lib4t1_vs_lib4t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l4t1t2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.23 Compare library 4, t1 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t1')|(batch=='34' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib4t1_vs_lib4t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l4t1t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.24 Compare library 4, t2 t3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='34' & condition=='t2')|(batch=='34' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/intertime/lib4t2_vs_lib4t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/l4t2t3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.25 Repeat correlations keeping time the same, but for each library set

3.26 t0l1l2

## Compare t0, lib1 lib2
comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t0')|(batch=='11' & condition=='t0')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t0_vs_lib2t0_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t0l1l2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.27 Compare t0, lib1 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t0')|(batch=='12' & condition=='t0')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t0_vs_lib3t0_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t0l1l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.28 Compare t0, lib1 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t0')|(batch=='34' & condition=='t0')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t0_vs_lib4t0_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t0l1l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.29 Compare t0, lib2 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t0')|(batch=='12' & condition=='t0')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t0_vs_lib3t0_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t0l2l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.30 Compare t0, lib2 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t0')|(batch=='34' & condition=='t0')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t0_vs_lib4t0_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t0l2l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.31 Compare t0, lib3 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t0')|(batch=='34' & condition=='t0')")$expressionset)
pdf(file="figures/comparisons/interlib/lib3t0_vs_lib4t0_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t0l3l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.32 Compare t1, lib1 lib2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t1')|(batch=='11' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t1_vs_lib2t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t1l1l2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.33 Compare t1, lib1 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t1')|(batch=='12' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t1_vs_lib3t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t1l1l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.34 Compare t1, lib1 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t1')|(batch=='34' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t1_vs_lib4t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t1l1l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.35 Compare t1, lib2 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t1')|(batch=='12' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t1_vs_lib3t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t1l2l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.36 Compare t1, lib2 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t1')|(batch=='34' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t1_vs_lib4t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t1l2l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.37 Compare t1, lib3 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t1')|(batch=='34' & condition=='t1')")$expressionset)
pdf(file="figures/comparisons/interlib/lib3t1_vs_lib4t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t1l3l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.38 Compare t2, lib1 lib2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t2')|(batch=='11' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t2_vs_lib2t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t2l1l2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.39 Compare t2, lib1 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t2')|(batch=='12' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t2_vs_lib3t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t2l1l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.40 Compare t2, lib1 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t2')|(batch=='34' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t2_vs_lib4t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t2l1l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.41 Compare t2, lib2 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t2')|(batch=='12' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t2_vs_lib3t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t2l2l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.42 Compare t2, lib2 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t2')|(batch=='34' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t2_vs_lib4t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t2l2l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.43 Compare t2, lib3 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t2')|(batch=='34' & condition=='t2')")$expressionset)
pdf(file="figures/comparisons/interlib/lib3t2_vs_lib4t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t2l3l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.44 Compare t3, lib1 lib2

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t3')|(batch=='11' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t3_vs_lib2t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t3l1l2v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.45 Compare t3, lib1 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t3')|(batch=='12' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t3_vs_lib3t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t3l1l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.46 Compare t3, lib1 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='9' & condition=='t3')|(batch=='34' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/interlib/lib1t3_vs_lib4t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t3l1l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.47 Compare t3, lib2 lib3

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t3')|(batch=='12' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t3_vs_lib3t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t3l2l3v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.48 Compare t3, lib2 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='11' & condition=='t3')|(batch=='34' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/interlib/lib2t3_vs_lib4t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t3l2l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.49 Compare t3, lib3 lib4

comp_5448 = exprs(expt_subset(all_norm_expt_5448, "(batch=='12' & condition=='t3')|(batch=='34' & condition=='t3')")$expressionset)
pdf(file="figures/comparisons/interlib/lib3t3_vs_lib4t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_5448, cormethod="spearman", gvis_filename="html/t3l3l4v0.html")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

3.50 Simple comparisons

I want to do some simple voom/limma comparisons of the times: 1. t0 to t1 2. t0 to t2 3. t0 to t3 4. t1 to t2 5. t1 to t3 6. t2 to t3

3.51 Simple comparisons

3.52 Time 0 to time 1

comp_5448 = expt_subset(all_norm_expt_5448, "condition=='t0' | condition=='t1'")
t0t1 = simple_comparison(comp_5448, sheet="t0t1", workbook="excel/5448_comparisons_v0.xls", basename="html/t0t1v0", tooltip_data=tooltip_data_5448)
pdf(file="figures/comparisons/combined_libs/t0t1v0.pdf")
t0t1$contrast_histogram
t0t1$amean_histogram
t0t1$pvalue_histogram
t0t1$ma_plot
t0t1$volcano_plot
png(file="figures/combined_t0t1v0.png")
t0t1$coefficient_scatter
dev.off()
t0t1$coefficient_x
t0t1$coefficient_y
t0t1$coefficient_both
dev.off()

3.53 Time 0 to time 2

comp_5448 = expt_subset(all_norm_expt_5448, "condition=='t0' | condition=='t2'")
t0t2 = simple_comparison(comp_5448, sheet="t0t2", workbook="excel/5448_comparisons_v0.xls", basename="html/t0t2v0", tooltip_data=tooltip_data_5448)
pdf(file="figures/comparisons/combined_libs/t0t2v0.pdf")
t0t2$contrast_histogram
t0t2$amean_histogram
t0t2$pvalue_histogram
t0t2$ma_plot
t0t2$volcano_plot
t0t2$coefficient_scatter
t0t2$coefficient_x
t0t2$coefficient_y
t0t2$coefficient_both
dev.off()

3.54 Time 0 to time 3

comp_5448 = expt_subset(all_norm_expt_5448, "condition=='t0' | condition=='t3'")
t0t3 = simple_comparison(comp_5448, sheet="t0t3", workbook="excel/5448_comparisons_v0.xls", basename="html/t0t3v0", tooltip_data=tooltip_data_5448)
pdf(file="figures/comparisons/combined_libs/t0t3v0.pdf")
t0t3$contrast_histogram
t0t3$amean_histogram
t0t3$pvalue_histogram
t0t3$ma_plot
t0t3$volcano_plot
t0t3$coefficient_scatter
t0t3$coefficient_x
t0t3$coefficient_y
t0t3$coefficient_both
dev.off()

3.55 Time 1 to time 2

comp_5448 = expt_subset(all_norm_expt_5448, "condition=='t1' | condition=='t2'")
t1t2 = simple_comparison(comp_5448, sheet="t1t2", workbook="excel/5448_comparisons_v0.xls", basename="html/t1t2v0", tooltip_data=tooltip_data_5448)
##t1t2 = simple_comparison(comp_5448, sheet="t1t2", workbook="excel/5448_comparisons_v0.xls")
pdf(file="figures/comparisons/combined_libs/t1t2v0.pdf")
t1t2$contrast_histogram
t1t2$amean_histogram
t1t2$pvalue_histogram
t1t2$ma_plot
t1t2$volcano_plot
t1t2$coefficient_scatter
t1t2$coefficient_x
t1t2$coefficient_y
t1t2$coefficient_both
dev.off()

3.56 Time 1 to time 3

comp_5448 = expt_subset(all_norm_expt_5448, "condition=='t1' | condition=='t3'")
t1t3 = simple_comparison(comp_5448, sheet="t1t3", workbook="excel/5448_comparisons_v0.xls", basename="html/t1t3v0", tooltip_data=tooltip_data_5448)
pdf(file="figures/comparisons/combined_libs/t1t3v0.pdf")
t1t3$contrast_histogram
t1t3$amean_histogram
t1t3$pvalue_histogram
t1t3$ma_plot
t1t3$volcano_plot
t1t3$coefficient_scatter
t1t3$coefficient_x
t1t3$coefficient_y
t1t3$coefficient_both
dev.off()

3.57 Time 2 to time 3

comp_5448 = expt_subset(all_norm_expt_5448, "condition=='t2' | condition=='t3'")
t2t3 = simple_comparison(comp_5448, sheet="t2t3", workbook="excel/5448_comparisons_v0.xls", basename="html/t2t3", tooltip_data=tooltip_data_5448)
pdf(file="figures/comparisons/combined_libs/t2t3v0.pdf")
t2t3$contrast_histogram
t2t3$amean_histogram
t2t3$pvalue_histogram
t2t3$ma_plot
t2t3$volcano_plot
t2t3$coefficient_scatter
t2t3$coefficient_x
t2t3$coefficient_y
t2t3$coefficient_both
dev.off()

4 Compare t1 to t2 using goseq?

It seems to me that those genes which go up/down in hits from times 1 to 2 are likely of interest Once simple task to perform is a simple goseq analysis of them.

```{r t1t2goseq, eval=FALSE summary(t1t2$downsignificant) head(annotation_5448_info) head(microbes_5448)

4.1 The first item

up_significant_table01 = subset(t0t1\(upsignificant, logFC > 0.8) up_significant_table01\)ID = rownames(up_significant_table01) down_significant_table01 = subset(t0t1\(downsignificant, logFC < -0.8) down_significant_table01\)ID = rownames(down_significant_table01)

up_significant_table02 = subset(t0t2\(upsignificant, logFC > 0.8) up_significant_table02\)ID = rownames(up_significant_table02) down_significant_table02 = subset(t0t2\(downsignificant, logFC < -0.8) down_significant_table02\)ID = rownames(down_significant_table02)

up_significant_table03 = subset(t0t3\(upsignificant, logFC > 0.8) up_significant_table03\)ID = rownames(up_significant_table03) down_significant_table03 = subset(t0t3\(downsignificant, logFC < -0.8) down_significant_table03\)ID = rownames(down_significant_table03)

up_significant_table12 = subset(t1t2\(upsignificant, logFC > 0.8) up_significant_table12\)ID = rownames(up_significant_table12) down_significant_table12 = subset(t1t2\(downsignificant, logFC < -0.8) down_significant_table12\)ID = rownames(down_significant_table12)

up_significant_table13 = subset(t1t3\(upsignificant, logFC > 0.8) up_significant_table13\)ID = rownames(up_significant_table13) down_significant_table13 = subset(t1t3\(downsignificant, logFC < -0.8) down_significant_table13\)ID = rownames(down_significant_table13)

4.2 The second item:

gene_lengths_5448 = annotation_5448_info[,c(“locus_tag”,“width”)] colnames(gene_lengths_5448) = c(“ID”,“width”) ## The third item colnames(microbes_go_5448) = c(“ID”,“GO”) microbes_go_5448\(ID = gsub("Spy_", "Spy", microbes_go_5448\)ID)

4.3 Need to set up the non-default GO mapping for clusterProfiler

4.4 This is now included in dirty_go()

4.5 Gff2GeneTable(“../reference/genbank/mgas_5005.gff”)

4.6 gomap = microbes_go

4.7 colnames(gomap) = c(“entrezgene”,“go_accession”)

4.8 buildGOmap(gomap)

up_go01 = dirty_go(up_significant_table01, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism=“gas_5005”, include_cnetplots=FALSE) up_go01\(pvalue_plot up_go01\)mf_group_barplot up_go01\(mf_enriched_barplot down_go01 = dirty_go(down_significant_table01, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism="gas_5005") down_go01\)pvalue_plot down_go01\(mf_group_barplot down_go01\)mf_enriched_barplot

up_go02 = dirty_go(up_significant_table02, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism=“gas_5005”, include_cnetplots=FALSE) up_go02\(pvalue_plot up_go02\)mf_group_barplot up_go02\(mf_enriched_barplot down_go02 = dirty_go(down_significant_table02, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism="gas_5005") down_go02\)pvalue_plot down_go02\(mf_group_barplot down_go02\)mf_enriched_barplot

up_go03 = dirty_go(up_significant_table03, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism=“gas_5005”, include_cnetplots=FALSE) up_go03\(pvalue_plot up_go03\)mf_group_barplot up_go03\(mf_enriched_barplot down_go03 = dirty_go(down_significant_table03, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism="gas_5005") down_go03\)pvalue_plot down_go03\(mf_group_barplot down_go03\)mf_enriched_barplot

up_go12 = dirty_go(up_significant_table12, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism=“gas_5005”, include_cnetplots=FALSE) summary(up_go12) up_go12\(pvalue_plot up_go12\)mf_group_barplot up_go12\(mf_enriched_barplot down_go12 = dirty_go(down_significant_table12, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism="gas_5005") down_go12\)pvalue_plot down_go12\(mf_group_barplot down_go12\)mf_enriched_barplot

up_go13 = dirty_go(up_significant_table13, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism=“gas_5005”, include_cnetplots=FALSE) summary(up_go13) up_go13\(pvalue_plot up_go13\)mf_group_barplot up_go13\(mf_enriched_barplot down_go13 = dirty_go(down_significant_table13, lengths=gene_lengths_5448, goids=microbes_go_5448, adjust=NULL, organism="gas_5005") down_go13\)pvalue_plot down_go13\(mf_group_barplot down_go13\)mf_enriched_barplot ```

4.9 Essentiality examination

plot_essentiality = function(file) {
    ess = read.csv(file=file, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    zbar_plot = ggplot(data=ess, aes(x=rank, y=posterior_zbar)) +
        geom_point(stat="identity", size=2) +
        geom_hline(color="grey", yintercept=0.0371) +
        geom_hline(color="grey", yintercept=0.9902) +
        theme_bw()
    span_df = ess[,c("max_run","max_run_span")]
    span_plot = my_linear_scatter(span_df)
    returns = list(zbar=zbar_plot, scatter=span_plot$scatter)
    return(returns)
}

plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m32.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m32.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m32.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m32.csv")

plot_essentiality("data/essentiality/mh_ess/nz131/t0v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t1v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t2v0_essentiality_m1.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t3v0_essentiality_m1.csv")


plot_essentiality("data/essentiality/mh_ess/nz131/t0v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t1v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t2v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t3v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t0v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t1v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t2v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t3v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t0v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t1v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t2v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t3v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t0v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t1v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t2v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t3v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t0v0_essentiality_m32.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t1v0_essentiality_m32.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t2v0_essentiality_m32.csv")
plot_essentiality("data/essentiality/mh_ess/nz131/t3v0_essentiality_m32.csv")

plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m2.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m4.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m8.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t0v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t1v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t2v0_essentiality_m16.csv")
plot_essentiality("data/essentiality/mh_ess/5448/t3v0_essentiality_m16.csv")

zbars_5448 = c("data/essentiality/mh_ess/5448/t0v0_essentiality_m1.csv", "data/essentiality/mh_ess/5448/t0v0_essentiality_m2.csv", "data/essentiality/mh_ess/5448/t0v0_essentiality_m4.csv", "data/essentiality/mh_ess/5448/t0v0_essentiality_m8.csv", "data/essentiality/mh_ess/5448/t0v0_essentiality_m16.csv", "data/essentiality/mh_ess/5448/t0v0_essentiality_m32.csv")
zbar_df = data.frame()
count = 0
for (z in zbars_5448) {
    count = count + 1
    ess = read.csv(file=z, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    print(summary(ess$posterior_zbar))
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    if (count == 1) {
        zbar_df = ess[,c("rank","posterior_zbar")]
        print(head(zbar_df))
    } else {
        zbar_df[, z] = as.vector(ess$posterior_zbar)
    }
}
colnames(zbar_df) = c("rank","one","two","four","eight","sixteen","thirtytwo")

ggplot(data=zbar_df) +
    geom_point(stat="identity", colour="yellow", size=2, aes(x=rank, y=one)) +
    geom_point(stat="identity", colour="orange", size=2, aes(x=rank, y=two)) +
    geom_point(stat="identity", colour="red", size=2, aes(x=rank, y=four)) +
    geom_point(stat="identity", colour="green", size=2, aes(x=rank, y=eight)) +
    geom_point(stat="identity", colour="blue", size=2, aes(x=rank, y=sixteen)) +
    geom_point(stat="identity", colour="black", size=2, aes(x=rank, y=thirtytwo)) +
    geom_hline(color="grey", yintercept=0.0371) +
    geom_hline(color="grey", yintercept=0.9902) +
    theme_bw()

zbars_5448 = c("data/essentiality/mh_ess/5448/t1v0_essentiality_m1.csv", "data/essentiality/mh_ess/5448/t1v0_essentiality_m2.csv", "data/essentiality/mh_ess/5448/t1v0_essentiality_m4.csv", "data/essentiality/mh_ess/5448/t1v0_essentiality_m8.csv", "data/essentiality/mh_ess/5448/t1v0_essentiality_m16.csv","data/essentiality/mh_ess/5448/t1v0_essentiality_m32.csv")
zbar_df = data.frame()
count = 0
for (z in zbars_5448) {
    count = count + 1
    ess = read.csv(file=z, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    print(summary(ess$posterior_zbar))
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    if (count == 1) {
        zbar_df = ess[,c("rank","posterior_zbar")]
        print(head(zbar_df))
    } else {
        zbar_df[, z] = as.vector(ess$posterior_zbar)
    }
}
colnames(zbar_df) = c("rank","one","two","four","eight","sixteen", "thirtytwo")

ggplot(data=zbar_df) +
    geom_point(stat="identity", colour="yellow", size=2, aes(x=rank, y=one)) +
    geom_point(stat="identity", colour="orange", size=2, aes(x=rank, y=two)) +
    geom_point(stat="identity", colour="red", size=2, aes(x=rank, y=four)) +
    geom_point(stat="identity", colour="green", size=2, aes(x=rank, y=eight)) +
    geom_point(stat="identity", colour="blue", size=2, aes(x=rank, y=sixteen)) +
    geom_point(stat="identity", colour="black", size=2, aes(x=rank, y=thirtytwo)) +
    geom_hline(color="grey", yintercept=0.0371) +
        geom_hline(color="grey", yintercept=0.9902) +
        theme_bw()

zbars_5448 = c("data/essentiality/mh_ess/5448/t2v0_essentiality_m2.csv", "data/essentiality/mh_ess/5448/t2v0_essentiality_m4.csv", "data/essentiality/mh_ess/5448/t2v0_essentiality_m8.csv", "data/essentiality/mh_ess/5448/t2v0_essentiality_m16.csv")
zbar_df = data.frame()
count = 0
for (z in zbars_5448) {
    count = count + 1
    ess = read.csv(file=z, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    print(summary(ess$posterior_zbar))
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    if (count == 1) {
        zbar_df = ess[,c("rank","posterior_zbar")]
        print(head(zbar_df))
    } else {
        zbar_df[, z] = as.vector(ess$posterior_zbar)
    }
}
colnames(zbar_df) = c("rank","two","four","eight","sixteen")

ggplot(data=zbar_df) +
        geom_point(stat="identity", colour="red", size=2, aes(x=rank, y=two)) +
        geom_point(stat="identity", colour="blue", size=2, aes(x=rank, y=four)) +
        geom_point(stat="identity", colour="black", size=2, aes(x=rank, y=eight)) +
        geom_point(stat="identity", colour="green", size=2, aes(x=rank, y=sixteen)) +
        geom_hline(color="grey", yintercept=0.0371) +
        geom_hline(color="grey", yintercept=0.9902) +
        theme_bw()

zbars_5448 = c("data/essentiality/mh_ess/5448/t3v0_essentiality_m2.csv", "data/essentiality/mh_ess/5448/t3v0_essentiality_m4.csv", "data/essentiality/mh_ess/5448/t3v0_essentiality_m8.csv", "data/essentiality/mh_ess/5448/t3v0_essentiality_m16.csv")
zbar_df = data.frame()
count = 0
for (z in zbars_5448) {
    count = count + 1
    ess = read.csv(file=z, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    print(summary(ess$posterior_zbar))
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    if (count == 1) {
        zbar_df = ess[,c("rank","posterior_zbar")]
        print(head(zbar_df))
    } else {
        zbar_df[, z] = as.vector(ess$posterior_zbar)
    }
}
colnames(zbar_df) = c("rank","two","four","eight","sixteen")

ggplot(data=zbar_df) +
        geom_point(stat="identity", colour="red", size=2, aes(x=rank, y=two)) +
        geom_point(stat="identity", colour="blue", size=2, aes(x=rank, y=four)) +
        geom_point(stat="identity", colour="black", size=2, aes(x=rank, y=eight)) +
        geom_point(stat="identity", colour="green", size=2, aes(x=rank, y=sixteen)) +
        geom_hline(color="grey", yintercept=0.0371) +
        geom_hline(color="grey", yintercept=0.9902) +
        theme_bw()

## Repeat for NZ131

zbars_nz131 = c("data/essentiality/mh_ess/nz131/t0v0_essentiality_m1.csv", "data/essentiality/mh_ess/nz131/t0v0_essentiality_m2.csv", "data/essentiality/mh_ess/nz131/t0v0_essentiality_m4.csv", "data/essentiality/mh_ess/nz131/t0v0_essentiality_m8.csv", "data/essentiality/mh_ess/nz131/t0v0_essentiality_m16.csv", "data/essentiality/mh_ess/nz131/t0v0_essentiality_m32.csv")
zbar_df = data.frame()
count = 0
for (z in zbars_nz131) {
    count = count + 1
    ess = read.csv(file=z, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    print(summary(ess$posterior_zbar))
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    if (count == 1) {
        zbar_df = ess[,c("rank","posterior_zbar")]
        print(head(zbar_df))
    } else {
        zbar_df[, z] = as.vector(ess$posterior_zbar)
    }
}
colnames(zbar_df) = c("rank","one","two","four","eight","sixteen","thirtytwo")
ggplot(data=zbar_df) +
    geom_point(stat="identity", colour="yellow", size=2, aes(x=rank, y=one)) +
    geom_point(stat="identity", colour="orange", size=2, aes(x=rank, y=two)) +
    geom_point(stat="identity", colour="red", size=2, aes(x=rank, y=four)) +
    geom_point(stat="identity", colour="green", size=2, aes(x=rank, y=eight)) +
    geom_point(stat="identity", colour="blue", size=2, aes(x=rank, y=sixteen)) +
    geom_point(stat="identity", colour="black", size=2, aes(x=rank, y=thirtytwo)) +
    geom_hline(color="grey", yintercept=0.0371) +
    geom_hline(color="grey", yintercept=0.9902) +
    theme_bw()



zbars_nz131 = c("data/essentiality/mh_ess/nz131/t1v0_essentiality_m1.csv", "data/essentiality/mh_ess/nz131/t1v0_essentiality_m2.csv", "data/essentiality/mh_ess/nz131/t1v0_essentiality_m4.csv", "data/essentiality/mh_ess/nz131/t1v0_essentiality_m8.csv", "data/essentiality/mh_ess/nz131/t1v0_essentiality_m16.csv", "data/essentiality/mh_ess/nz131/t1v0_essentiality_m32.csv")
zbar_df = data.frame()
count = 0
for (z in zbars_nz131) {
    count = count + 1
    ess = read.csv(file=z, comment.char="#", sep="\t", header=FALSE)
    colnames(ess) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    print(summary(ess$posterior_zbar))
    ess = ess[with(ess, order(posterior_zbar)), ]
    ess = subset(ess, posterior_zbar > -1)
    ess = transform(ess, rank=ave(posterior_zbar, FUN=function(x) order(x,decreasing=FALSE)))
    if (count == 1) {
        zbar_df = ess[,c("rank","posterior_zbar")]
        print(head(zbar_df))
    } else {
        zbar_df[, z] = as.vector(ess$posterior_zbar)
    }
}
colnames(zbar_df) = c("rank","one","two","four","eight","sixteen","thirtytwo")
ggplot(data=zbar_df) +
    geom_point(stat="identity", colour="yellow", size=2, aes(x=rank, y=one)) +
    geom_point(stat="identity", colour="orange", size=2, aes(x=rank, y=two)) +
    geom_point(stat="identity", colour="red", size=2, aes(x=rank, y=four)) +
    geom_point(stat="identity", colour="green", size=2, aes(x=rank, y=eight)) +
    geom_point(stat="identity", colour="blue", size=2, aes(x=rank, y=sixteen)) +
    geom_point(stat="identity", colour="black", size=2, aes(x=rank, y=thirtytwo)) +
    geom_hline(color="grey", yintercept=0.0371) +
    geom_hline(color="grey", yintercept=0.9902) +
    theme_bw()

5 NZ131 data

5.1 Genome annotation input

annotations_nz = import.gff3("reference/genbank/mgas_nz131.gff", asRangedData=FALSE)
annotation_info_nz = as.data.frame(annotations_nz)
rownames(annotation_info_nz) = make.names(annotations_nz$locus_tag, unique=TRUE)
genes_nz = annotation_info_nz[annotation_info_nz$type=="gene",]
gene_annotations_nz = subset(genes_nz, select = c("start", "end", "width", "strand", "gene", "locus_tag"))
short_annotations_nz = gene_annotations_nz[,c("gene", "locus_tag")]
write_xls(gene_annotations_nz, "annotations", rowname="ID", file="excel/nz131_data_v0.xls")

microbes_nz = read.csv(file="reference/microbesonline/nz131_annotations.tab.gz", header=1, sep="\t")
microbes_go_nz = microbes_nz[,c("sysName","GO")]
go_entries_nz = strsplit(as.character(microbes_go_nz$GO), split=",", perl=TRUE)
microbes_go_oneperrow_nz = data.frame(name = rep(microbes_go_nz$sysName, sapply(go_entries_nz, length)), GO = unlist(go_entries_nz))
microbes_go_nz = microbes_go_oneperrow_nz
rm(microbes_go_oneperrow_nz)
rm(go_entries_nz)
## These are used for gene ontology stuff...
microbes_lengths_nz = microbes_nz[,c("sysName", "start","stop")]
microbes_lengths_nz$length = abs(microbes_nz$start - microbes_nz$stop)
microbes_lengths_nz = microbes_lengths_nz[,c("sysName","length")]

5.1.1 Make tooltips for interactive graphs

tooltip_data_nz = annotation_info_nz
## Error in eval(expr, envir, enclos): object 'annotation_info_nz' not found
tooltip_data_nz = tooltip_data_nz[,c("gene", "locus_tag")]
## Error in eval(expr, envir, enclos): object 'tooltip_data_nz' not found
tooltip_data_nz$tooltip = paste(tooltip_data_nz$gene, tooltip_data_nz$locus_tag, sep=": ")
## Error in eval(quote(list(...)), env): object 'tooltip_data_nz' not found
tooltip_data_nz$tooltip = gsub("\\+", " ", tooltip_data_nz$tooltip)
## Error in gsub("\\+", " ", tooltip_data_nz$tooltip): object 'tooltip_data_nz' not found
head(tooltip_data_nz)
## Error in head(tooltip_data_nz): object 'tooltip_data_nz' not found

5.1.2 Set up the experimental design

## The all_samples.csv controls the experimental settings
## all the following lines manipulate the information therein
## in order to set up media types, replicates, etc
sample_definitions_nz = read.csv(file="all_samples_nz131_v0.csv", sep=",")
## If I have summary lines in the csv, they will not start with 'HPGL' and so should be dropped.
sample_definitions_nz = sample_definitions_nz[grepl('^HPGL', sample_definitions_nz$Sample.ID, perl=TRUE),]
## Pre set the color scheme
sample_definitions_nz$colors = library_colors
## This long statement just writes out a computer path name containing the count files to read by sample name.
sample_definitions_nz$counts = paste("data/count_tables/05v0M1l20gen_", sample_definitions_nz$Strain, "_", sample_definitions_nz$Time, "_genome.count.gz", sep="")
sample_definitions_nz = as.data.frame(sample_definitions_nz)
rownames(sample_definitions_nz) = sample_definitions_nz$Sample.ID
## my_read_files does just that, it reads the count tables and makes a large raw count table from them.
all_count_tables_nz = my_read_files(as.character(sample_definitions_nz$Sample.ID), as.character(sample_definitions_nz$counts))
## make it into a matrix for use as an expressionset
all_count_matrix_nz = as.matrix(all_count_tables_nz)

gene_info_nz = all_count_matrix_nz[rownames(all_count_matrix_nz) %in% annotations_nz$locus_tag,]
## Error in rownames(all_count_matrix_nz) %in% annotations_nz$locus_tag: object 'annotations_nz' not found
all_count_matrix_nz = all_count_matrix_nz[rownames(all_count_matrix_nz) %in% annotations_nz$locus_tag,]
## Error in rownames(all_count_matrix_nz) %in% annotations_nz$locus_tag: object 'annotations_nz' not found
metadata_nz = new("AnnotatedDataFrame", data.frame(sample=sample_definitions_nz$Sample.ID,
    condition=sample_definitions_nz$Time,
    batch=sample_definitions_nz$Library,
    strain=sample_definitions_nz$Strain,
    color=as.character(sample_definitions_nz$colors),
    counts=sample_definitions_nz$counts))

## Now generate the expressionset object
sampleNames(metadata_nz) = colnames(all_count_matrix_nz)
feature_data_nz = new("AnnotatedDataFrame", as.data.frame(gene_info_nz))
## Error in value[[3L]](cond): object 'gene_info_nz' not found
##   AnnotatedDataFrame 'initialize' could not update varMetadata:
##   perhaps pData and varMetadata are inconsistent?
featureNames(feature_data_nz) = rownames(all_count_matrix_nz)
## Error in featureNames(feature_data_nz) = rownames(all_count_matrix_nz): object 'feature_data_nz' not found
experiment_nz = new("ExpressionSet", exprs=all_count_matrix_nz,
    phenoData=metadata_nz, featureData=feature_data_nz)
## Error in is(object, expected): object 'feature_data_nz' not found
## print some information to see that it worked
print(experiment_nz)
## Error in print(experiment_nz): object 'experiment_nz' not found
summary(exprs(experiment_nz))
## Error in exprs(experiment_nz): object 'experiment_nz' not found
head(fData(experiment_nz))
## Error in fData(experiment_nz): object 'experiment_nz' not found
head(pData(experiment_nz))
## Error in pData(experiment_nz): object 'experiment_nz' not found
dim(fData(experiment_nz))
## Error in fData(experiment_nz): object 'experiment_nz' not found
raw_data_nz = exprs(experiment_nz)
## Error in exprs(experiment_nz): object 'experiment_nz' not found
write_xls(raw_data_nz, "raw_data", file="excel/nz131_data_v0.xls")
## Error in writeWorksheet(xls, data, sheet = sheet): object 'raw_data_nz' not found

5.2 Graph metrics

all_expt_nz = expt_subset(experiment_nz, "")
head(exprs(all_expt_nz$expressionset))

all_qrpkm_nz = my_norm(expt=all_expt_nz, norm="quant", filter="log2", filter_low=FALSE, out_type="rpkm", annotations=annotation_info_nz)$counts
write_xls(all_qrpkm_nz, "norm_data", file="excel/nz131_data_v0.xls", rowname="row.names")
all_norm_expt_nz = all_expt_nz
## I did that so that I can replace the expressionset with the
## normalized data more easily...
normalized_expressionset_nz = all_norm_expt_nz$expressionset
exprs(normalized_expressionset_nz) = all_qrpkm_nz
all_norm_expt_nz$expressionset = normalized_expressionset_nz

all_design_nz = data.frame(all_norm_expt_nz$design)
all_design_nz$longnames = paste(all_design_nz$strain,  all_design_nz$batch, all_design_nz$condition, sep="_")

my_boxplot(expt=all_norm_expt_nz, names=all_design_nz$longnames)
my_disheat(expt=all_norm_expt_nz, names=all_design_nz$longnames)
my_corheat(expt=all_norm_expt_nz, names=all_design_nz$longnames)

correlations_nz = my_cor(exprs(all_expt_nz$expressionset), method="spearman")
write_xls(correlations_nz, "sp_cor", file="excel/nz131_data_v0.xls")

5.3 Get comparisons for Yoann

## Compare library t0 t1
comp_nz = exprs(expt_subset(all_norm_expt_nz, "condition=='t0'|condition=='t1'")$expressionset)
pdf(file="figures/comparisons/nz131/t0_vs_t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_nz, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t0 t2
comp_nz = exprs(expt_subset(all_norm_expt_nz, "condition=='t0'|condition=='t2'")$expressionset)
pdf(file="figures/comparisons/nz131/t0_vs_t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_nz, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t0 t3
comp_nz = exprs(expt_subset(all_norm_expt_nz, "condition=='t0'|condition=='t3'")$expressionset)
pdf(file="figures/comparisons/nz131/t0_vs_t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_nz, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t1 t2
comp_nz = exprs(expt_subset(all_norm_expt_nz, "condition=='t1'|condition=='t2'")$expressionset)
pdf(file="figures/comparisons/nz131/t1_vs_t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_nz, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t1 t3
comp_nz = exprs(expt_subset(all_norm_expt_nz, "condition=='t1'|condition=='t3'")$expressionset)
pdf(file="figures/comparisons/nz131/t1_vs_t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_nz, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t2 t3
comp_nz = exprs(expt_subset(all_norm_expt_nz, "condition=='t2'|condition=='t3'")$expressionset)
pdf(file="figures/comparisons/nz131/t2_vs_t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_nz, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

6 Alabama

6.1 Genome annotation input

annotations_ala = import.gff3("reference/genbank/mgas_alabama.gff", asRangedData=FALSE)
annotation_info_ala = as.data.frame(annotations_ala)
rownames(annotation_info_ala) = make.names(annotations_ala$locus_tag, unique=TRUE)
genes_ala = annotation_info_ala[annotation_info_ala$type=="gene",]
gene_annotations_ala = subset(genes_ala, select = c("start", "end", "width", "strand", "gene", "locus_tag"))
short_annotations_ala = gene_annotations_ala[,c("gene", "locus_tag")]
write_xls(gene_annotations_ala, "annotations", rowname="ID", file="excel/alabama_data_v0.xls")

##microbes_ala = read.csv(file="reference/microbesonline/alabama_annotations.tab.gz", header=1, sep="\t")
##microbes_go_ala = microbes_ala[,c("sysName","GO")]
##go_entries_ala = strsplit(as.character(microbes_go_ala$GO), split=",", perl=TRUE)
##microbes_go_oneperrow_ala = data.frame(name = rep(microbes_go_ala$sysName, sapply(go_entries_ala, length)), GO = unlist(go_entries_ala))
##microbes_go_ala = microbes_go_oneperrow_ala
##rm(microbes_go_oneperrow_ala)
##rm(go_entries_ala)
## These are used for gene ontology stuff...
##microbes_lengths_ala = microbes_ala[,c("sysName", "start","stop")]
##microbes_lengths_ala$length = abs(microbes_ala$start - microbes_ala$stop)
##microbes_lengths_ala = microbes_lengths_ala[,c("sysName","length")]

6.1.1 Make tooltips for interactive graphs

tooltip_data_ala = annotation_info_ala
tooltip_data_ala = tooltip_data_ala[,c("gene", "locus_tag")]
tooltip_data_ala$tooltip = paste(tooltip_data_ala$gene, tooltip_data_ala$locus_tag, sep=": ")
tooltip_data_ala$tooltip = gsub("\\+", " ", tooltip_data_ala$tooltip)
head(tooltip_data_ala)

6.1.2 Set up the experimental design

## The all_samples.csv controls the experimental settings
## all the following lines manipulate the information therein
## in order to set up media types, replicates, etc
sample_definitions_ala = read.csv(file="all_samples_alabama_v0.csv", sep=",")
## If I have summary lines in the csv, they will not start with 'HPGL' and so should be dropped.
sample_definitions_ala = sample_definitions_ala[grepl('^HPGL', sample_definitions_ala$Sample.ID, perl=TRUE),]
## Pre set the color scheme
sample_definitions_ala$colors = library_colors
## This long statement just writes out a computer path name containing the count files to read by sample name.
sample_definitions_ala$counts = paste("data/count_tables/05v0M1l20gen_", "alab49", "_", sample_definitions_ala$Time, "_genome.count.gz", sep="")
sample_definitions_ala = as.data.frame(sample_definitions_ala)
rownames(sample_definitions_ala) = sample_definitions_ala$Sample.ID
## my_read_files does just that, it reads the count tables and makes a large raw count table from them.
all_count_tables_ala = my_read_files(as.character(sample_definitions_ala$Sample.ID), as.character(sample_definitions_ala$counts))
## make it into a matrix for use as an expressionset
all_count_matrix_ala = as.matrix(all_count_tables_ala)

gene_info_ala = all_count_matrix_ala[rownames(all_count_matrix_ala) %in% annotations_ala$locus_tag,]
all_count_matrix_ala = all_count_matrix_ala[rownames(all_count_matrix_ala) %in% annotations_ala$locus_tag,]
metadata_ala = new("AnnotatedDataFrame", data.frame(sample=sample_definitions_ala$Sample.ID,
    condition=sample_definitions_ala$Time,
    batch=sample_definitions_ala$Library,
    strain=sample_definitions_ala$Strain,
    color=as.character(sample_definitions_ala$colors),
    counts=sample_definitions_ala$counts))

## Now generate the expressionset object
sampleNames(metadata_ala) = colnames(all_count_matrix_ala)
feature_data_ala = new("AnnotatedDataFrame", as.data.frame(gene_info_ala))
featureNames(feature_data_ala) = rownames(all_count_matrix_ala)
experiment_ala = new("ExpressionSet", exprs=all_count_matrix_ala,
    phenoData=metadata_ala, featureData=feature_data_ala)
## print some information to see that it worked
print(experiment_ala)
summary(exprs(experiment_ala))
head(fData(experiment_ala))
head(pData(experiment_ala))
dim(fData(experiment_ala))

raw_data_ala = exprs(experiment_ala)
write_xls(raw_data_ala, "raw_data", file="excel/alabama_data_v0.xls")

6.2 Graph metrics

all_expt_ala = expt_subset(experiment_ala, "")
head(exprs(all_expt_ala$expressionset))

all_qrpkm_ala = my_norm(expt=all_expt_ala, norm="quant", filter="log2", filter_low=FALSE, out_type="rpkm", annotations=annotation_info_ala)$counts
write_xls(all_qrpkm_ala, "norm_data", file="excel/alabama_data_v0.xls", rowname="row.names")
all_norm_expt_ala = all_expt_ala
## I did that so that I can replace the expressionset with the
## normalized data more easily...
normalized_expressionset_ala = all_norm_expt_ala$expressionset
exprs(normalized_expressionset_ala) = all_qrpkm_ala
all_norm_expt_ala$expressionset = normalized_expressionset_ala

all_design_ala = data.frame(all_norm_expt_ala$design)
all_design_ala$longnames = paste(all_design_ala$strain,  all_design_ala$batch, all_design_ala$condition, sep="_")

my_boxplot(expt=all_norm_expt_ala, names=all_design_ala$longnames)
my_disheat(expt=all_norm_expt_ala, names=all_design_ala$longnames)
my_corheat(expt=all_norm_expt_ala, names=all_design_ala$longnames)

correlations_ala = my_cor(exprs(all_expt_ala$expressionset), method="spearman")
write_xls(correlations_ala, "sp_cor", file="excel/alabama_data_v0.xls")

6.3 Get comparisons for Yoann

## Compare library t0 t1
comp_ala = exprs(expt_subset(all_norm_expt_ala, "condition=='t0'|condition=='t1'")$expressionset)
pdf(file="figures/comparisons/alabama/t0_vs_t1_scatter_v0.pdf")
sc = my_linear_scatter(comp_ala, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t0 t2
comp_ala = exprs(expt_subset(all_norm_expt_ala, "condition=='t0'|condition=='t2'")$expressionset)
pdf(file="figures/comparisons/alabama/t0_vs_t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_ala, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t0 t3
comp_ala = exprs(expt_subset(all_norm_expt_ala, "condition=='t0'|condition=='t3'")$expressionset)
pdf(file="figures/comparisons/alabama/t0_vs_t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_ala, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t1 t2
comp_ala = exprs(expt_subset(all_norm_expt_ala, "condition=='t1'|condition=='t2'")$expressionset)
pdf(file="figures/comparisons/alabama/t1_vs_t2_scatter_v0.pdf")
sc = my_linear_scatter(comp_ala, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t1 t3
comp_ala = exprs(expt_subset(all_norm_expt_ala, "condition=='t1'|condition=='t3'")$expressionset)
pdf(file="figures/comparisons/alabama/t1_vs_t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_ala, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary
## Compare library t2 t3
comp_ala = exprs(expt_subset(all_norm_expt_ala, "condition=='t2'|condition=='t3'")$expressionset)
pdf(file="figures/comparisons/alabama/t2_vs_t3_scatter_v0.pdf")
sc = my_linear_scatter(comp_ala, cormethod="spearman")
sc$scatter
sc$x_histogram
sc$y_histogram
sc$both_histogram
dev.off()
sc$correlation
sc$lm_model
sc$lm_summary

7 Playing with distribution of hits

all_tas = read.table(file="data/essentiality/mh_ess/5448/tas_t0v0.txt", header=TRUE)
all_tas = all_tas[,c("Start", "reads", "TAs")]
head(all_tas)
by_thousands = group_by(all_tas, floor(Start / 1000))
setnames(by_thousands, "floor(Start/1000)", "thousands")
## The last row is broken
by_thousands = by_thousands[-nrow(by_thousands),]
by_thousands = aggregate(. ~ thousands, data=by_thousands, FUN=sum)
by_thousands = as.data.frame(by_thousands)
by_thousands = by_thousands[,c("thousands","reads", "TAs")]
by_thousands$log_reads = log2(by_thousands$reads + 1)
by_thousands$norm = by_thousands$reads / by_thousands$TAs
by_thousands$log_norm = log2(by_thousands$norm + 1)

scatter_df = by_thousands[,c("thousands","log_reads")]
thousands_plot = my_scatter(scatter_df)
thousands_plot + stat_smooth(method="loess", size=1.5)
scatter_df = by_thousands[,c("thousands","log_norm")]
thousands_plot = my_scatter(scatter_df)
thousands_plot + stat_smooth(method="loess", size=1.5)
make_circos = function(csv, annotations=gene_annotations_5448, offset=0, chr="chr1") {
    ## Testing parameters
    ##write.table(make_circos("data/essentiality/mh_ess/nz131/time0_essentiality_m2.csv", gene_annotations_nz), file="circos/data/essentiality_nz131_t0.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
    #csv = "data/essentiality/mh_ess/nz131/t0v0_essentiality_m2.csv"
    #annotations = gene_annotations_nz
    ## End testing parameters
    data = read.csv(file=csv, sep="\t", comment.char="#", header=FALSE)
    colnames(data) = c("gene","orf_hits","orf_tas","max_run","max_run_span","posterior_zbar","call")
    data$gene = gsub("^cds_", "", data$gene, perl=TRUE)
    rownames(data) = make.names(data$gene, unique=TRUE)
    data = merge(data, annotations, by="row.names")
    data[, chr ] = chr
    data = data[,c(chr, "start", "end", "posterior_zbar")]
    data$posterior_zbar = paste("value=", data$posterior_zbar, sep="")
    data$start = data$start + offset
    data$end = data$end + offset
    return(data)
}
write.table(make_circos("data/essentiality/mh_ess/5448/t0v0_essentiality_m4.csv", gene_annotations_5448), file="circos/data/essentiality_5448_t1.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(make_circos("data/essentiality/mh_ess/5448/t1v0_essentiality_m4.csv", gene_annotations_5448), file="circos/data/essentiality_5448_t1.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(make_circos("data/essentiality/mh_ess/5448/t2v0_essentiality_m4.csv", gene_annotations_5448), file="circos/data/essentiality_5448_t2.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(make_circos("data/essentiality/mh_ess/5448/t3v0_essentiality_m4.csv", gene_annotations_5448), file="circos/data/essentiality_5448_t3.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)

write.table(make_circos("data/essentiality/mh_ess/nz131/t0v0_essentiality_m2.csv", gene_annotations_nz), file="circos/data/essentiality_nz131_t0.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(make_circos("data/essentiality/mh_ess/nz131/t1v0_essentiality_m2.csv", gene_annotations_nz), file="circos/data/essentiality_nz131_t1.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(make_circos("data/essentiality/mh_ess/nz131/t2v0_essentiality_m2.csv", gene_annotations_nz), file="circos/data/essentiality_nz131_t2.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(make_circos("data/essentiality/mh_ess/nz131/t3v0_essentiality_m2.csv", gene_annotations_nz), file="circos/data/essentiality_nz131_t3.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)

gas_plus = read.table(file="circos/data/gas_plus.txt")
nz131_plus = read.table(file="circos/data/nz131_plus.txt")
gas_minus = read.table(file="circos/data/gas_minus.txt")
nz131_minus = read.table(file="circos/data/nz131_minus.txt")

nz131_plus_offset = nz131_plus
colnames(nz131_plus_offset) = c("chr","start","end","value")
nz131_plus_offset$chr = "chr2"
nz131_minus_offset = nz131_minus
colnames(nz131_minus_offset) = c("chr","start","end","value")
nz131_minus_offset$chr = "chr2"
write.table(nz131_plus_offset, file="circos/data/nz131_offset_plus.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)
write.table(nz131_minus_offset, file="circos/data/nz131_offset_minus.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)

essential_cross = read.csv(file="reference/core_genome/reduced.csv")
head(gene_annotations_5448)
head(gene_annotations_nz)
dim(essential_cross)
essential_cross$Spy_5448 = gsub("_Spy_", "_Spy", essential_cross$Spy_5448)
essential_cross = merge(essential_cross, gene_annotations_5448, by.x="Spy_5448", by.y="row.names", all.x=TRUE)
essential_cross = essential_cross[,c("Spy_5448","State_5448","Spy_NZ131","State_NZ131","start","end")]
setnames(essential_cross, "start", "5448_start")
setnames(essential_cross, "end", "5448_end")
essential_cross = merge(essential_cross, gene_annotations_nz, by.x="Spy_NZ131", by.y="row.names", all.x=TRUE)
essential_cross = essential_cross[,c("Spy_5448","State_5448","Spy_NZ131","State_NZ131","5448_start","5448_end","start","end")]
setnames(essential_cross, "start", "nz131_start")
setnames(essential_cross, "end", "nz131_end")
essential_cross = essential_cross[complete.cases(essential_cross),]

print_arc = function(x) {
    cat(x[5], " chr1 ", x[1], " ", x[2], "\n", x[5], " chr2 ", x[3], " ", x[4], "\n\n", file="circos/data/5448_nz131_arcs.txt", append=TRUE, sep="")
}

apply(essential_cross[,c("5448_start","5448_end","nz131_start","nz131_end","Spy_5448")], 1, print_arc)
if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
  message(paste0("Saving to ", this_save))
  tmp <- sm(saveme(filename=this_save))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 5d8c266e48bb9f73cdac8300e5c7c9f5baf003dc
## R> packrat::restore()
## This is hpgltools commit: Wed Mar 21 15:55:32 2018 -0400: 5d8c266e48bb9f73cdac8300e5c7c9f5baf003dc
## Saving to tnseq_v0.rmd-v201605.rda.xz
LS0tCnRpdGxlOiAiUy5weW9nZW5lcyAyMDE1MDU6IDAgbWlzbWF0Y2ggYW5hbHlzZXMuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiBodG1sX2RvY3VtZW50OgogIGNvZGVfZG93bmxvYWQ6IHRydWUKICBjb2RlX2ZvbGRpbmc6IHNob3cKICBmaWdfY2FwdGlvbjogdHJ1ZQogIGZpZ19oZWlnaHQ6IDcKICBmaWdfd2lkdGg6IDcKICBoaWdobGlnaHQ6IGRlZmF1bHQKICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiByZWFkYWJsZQogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgogIGJvZHkgLm1haW4tY29udGFpbmVyIHsKICAgIG1heC13aWR0aDogMTYwMHB4OwogIH0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmlmICghaXNUUlVFKGdldDAoInNraXBfbG9hZCIpKSkgewogIGxpYnJhcnkoaHBnbHRvb2xzKQogIHR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQogIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZT1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICAgIGVjaG89VFJVRSkKICBrbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQ9OCwKICAgICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQogIG9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCiAgZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCiAgdmVyIDwtICIyMDE2MDUiCiAgcHJldmlvdXNfZmlsZSA8LSAibWVyZ2VfYW5ub3RhdGlvbnMucm1kIgoKICB0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKSkKICBybWRfZmlsZSA8LSAidG5zZXFfdjAucm1kIgp9CmBgYAoKIyBSZXZpc2l0aW5nIG15IGZpcnN0IHRuc2VxIGFuYWx5c2VzCgpJbiBteSBjb250aW51ZWQgZWZmb3J0IHRvIGJldHRlciBkb2N1bWVudCBteSB3b3JrLCBJIGFtIHJlcnVubmluZyBteSAyMDE1CmFuYWx5c2VzIG9mIG91ciBTLiBweW9nZW5lcyA1NDQ4IHRuc2VxLiAgSG9wZWZ1bGx5IGxpdHRsZSBlZmZvcnQgd2lsbCBiZQpyZXF1aXJlZC4gIE9uZSBpbXBvcnRhbnQgY2F2ZWF0OiB0aGlzIGRvY3VtZW50IHVzZWQgdGhlIHByZWN1cnNvciB0byB0aGUKaHBnbHRvb2xzOiAnbXlyJywgd2hpY2ggd2FzIGEgbm90LXRlcnJpYmxlIGZpcnN0IGVmZm9ydCBmb3IgYW4gUiBwYWNrYWdlLiAgQnV0Cml0IHdhcyBvZiBtdWNoIGxvd2VyIHF1YWxpdHkgdGhhbiBpdHMgc3VjY2Vzc29yLgoKTG9va2luZyBmdXJ0aGVyIGRvd24sIGZhaXJseSBzaWduaWZpY2FudCBjaGFuZ2VzIHdpbGwgbmVlZCB0byBiZSBtYWRlIHRvIGdldApsYXRlciBhbmFseXNlcyB0byB3b3JrLiAgU28gcmF0aGVyIHRoYW4gZGVsZXRlIHdoYXQgaXMgaGVyZSwgSSBhbSBnb2luZyB0bwpjcmVhdGUgbmV3IGNvZGUgYmxvY2tzIGZvbGxvd2luZyBldmVyeSBleGlzdGluZyBjb2RlIGJsb2NrIHdpdGggbWF0ZXJpYWwgd2hpY2gKcmVwcmVzZW50cyB0aGUgY3VycmVudCBzdGF0ZSBvZiBteSB3b3JrLgoKIyMgTG9hZGluZyBteXIKCkhlcmUgd2UgY2FuIHNlZSBob3cgSSB1c2VkIHRvIGxvYWQgbXlyIGFuZCBpdHMgYWNjZXNzb3J5IGNvZGUuICBUaGlzIGhhcyBiZWVuIGltcHJvdmVkLgoKYGBge3Igc2V0dXAsIGV2YWw9RkFMU0V9CiMjIFRpbWUtc3RhbXA6IDxUdWUgRGVjICAyIDE3OjA3OjE4IDIwMTQgQXNodG9uIFRyZXkgQmVsZXcgKGFiZWxld0BnbWFpbC5jb20pPgpybShsaXN0PWxzKCkpCmxvYWQoIlJEYXRhLjAiKQpsaWJyYXJ5KG15cikKYXV0b2xvYWRzKCkKc2F2ZShsaXN0ID0gbHMoYWxsPVRSVUUpLCBmaWxlPSJSRGF0YS4wIikKYGBgCgojIyBTZXR0aW5nIHVwIG9wdGlvbnMuCgpUaGVzZSBvcHRpb25zIGhhdmUgYWxzbyBiZWVuIHNpZ25pZmljYW50bHkgaW1wcm92ZWQgc2luY2UgSSB3cm90ZSB0aGUgb3JpZ2luYWwgZG9jdW1lbnQuCgpgYGB7ciBzYXZlX2RhdGEsIGV2YWw9RkFMU0V9Cm9wdHNfa25pdCRzZXQoZmlnLndpZHRoPTgwMC8xOTIsIGZpZy5oZWlnaHQ9ODAwLzE5MiwgZHBpPTE5MiwgZXJyb3I9VFJVRSwgc3RvcF9vbl9lcnJvcj1GQUxTRSkKc2F2ZShsaXN0ID0gbHMoYWxsPVRSVUUpLCBmaWxlPSJSRGF0YSIpCnJlbmRlcigidG5zZXFfdjAucm1kIiwgb3V0cHV0X2Zvcm1hdD0iaHRtbF9kb2N1bWVudCIpCiNrbml0KCJybmFzZXFfbWdhLnJtZCIpCnJlbmRlcigidG5zZXFfdjAucm1kIiwgb3V0cHV0X2Zvcm1hdD0icGRmX2RvY3VtZW50IikKIyMgQSByZW1pbmRlciBmb3IgZW1hY3MgKGVzcy1yZXN5bmNoKQpgYGAKCiMjIHBsb3Qgb3B0aW9ucz8KClRoaXMgYWxzbyBoYXMgYmVlbiBpbXByb3ZlZCwgaXQgaXMgbm93IG1haW50YWluZWQgd2l0aGluIGhwZ2x0b29scy4KCmBgYHtyIHBsb3Rfb3B0aW9ucywgZXZhbD1GQUxTRX0KdGhlbWVfc2V0KHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEwKSkKYGBgCgojIFN0cmFpbiA1NDQ4CgojIyBHZW5vbWUgYW5ub3RhdGlvbiBpbnB1dAoKIyMjIE5vdGUgZnJvbSB0aGUgZnV0dXJlCgpJIGFtIHN1cGVyIGN1cmlvdXMgdG8gc2VlIGhvdyBtdWNoIG9mIHRoaXMgb2xkIGNvZGUgd29ya3MhCkkgYW0gdGhpbmtpbmcgdGhhdCBJIHdpbGwganVzdCBhZGQgc29tZSBsaWJyYXJ5IGludm9jYXRpb25zIHRvIHRyeSB0byBjaGFuZ2UgYXMKbGl0dGxlIGFzIHBvc3NpYmxlIG9mIHRoZSBvcmlnaW5hbCBjb2RlLgoKYGBge3IgbGlicmFyaWVzfQpsaWJyYXJ5KHJ0cmFja2xheWVyKSAjIyBpbXBvcnQuZ2ZmMwpsaWJyYXJ5KFhMQ29ubmVjdCkgIyMgbG9hZFdvcmtCb29rIGFuZCBzdWNoCmxpYnJhcnkoQmlvYmFzZSkgICMjIENyZWF0aW5nIGFubm90YXRlZGRhdGFmcmFtZXMKbGlicmFyeShSc2FtdG9vbHMpICMjIEZhRmlsZQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZWRnZVIpCmxpYnJhcnkobGltbWEpCmBgYAoKYGBge3IgZGF0YV9pbnB1dF9nZW5vbWVfNTQ0OH0KIyMgYW5ub3RhdGlvbnNfNTQ0OCA9IGltcG9ydC5nZmYzKCJyZWZlcmVuY2UvZ2VuYmFuay9tZ2FzXzUwMDUuZ2ZmIiwgYXNSYW5nZWREYXRhPUZBTFNFKQphbm5vdGF0aW9uc181NDQ4ID0gaW1wb3J0LmdmZjMoInJlZmVyZW5jZS9nZW5iYW5rL21nYXNfNTAwNS5nZmYiKSAjIyBhc1JhbmdlZERhdGEgaGFzIGJlZW4gZGVwcmVjYXRlZCBzaW5jZSBJIHdyb3RlIHRoaXMuCmFubm90YXRpb25fNTQ0OF9pbmZvID0gYXMuZGF0YS5mcmFtZShhbm5vdGF0aW9uc181NDQ4KQpyb3duYW1lcyhhbm5vdGF0aW9uXzU0NDhfaW5mbykgPSBtYWtlLm5hbWVzKGFubm90YXRpb25fNTQ0OF9pbmZvJGxvY3VzX3RhZywgdW5pcXVlPVRSVUUpCmdlbmVzXzU0NDggPSBhbm5vdGF0aW9uXzU0NDhfaW5mb1thbm5vdGF0aW9uXzU0NDhfaW5mbyR0eXBlPT0iZ2VuZSIsXQpyb3duYW1lcyhnZW5lc181NDQ4KSA9IG1ha2UubmFtZXMoZ2VuZXNfNTQ0OCRsb2N1c190YWcsIHVuaXF1ZT1UUlVFKQpnZW5lX2Fubm90YXRpb25zXzU0NDggPSBzdWJzZXQoZ2VuZXNfNTQ0OCwgc2VsZWN0ID0gYygic3RhcnQiLCAiZW5kIiwgIndpZHRoIiwgInN0cmFuZCIsICJnZW5lIiwgImxvY3VzX3RhZyIsICJvbGRfbG9jdXNfdGFnIikpCnNob3J0X2Fubm90YXRpb25zXzU0NDggPSBnZW5lX2Fubm90YXRpb25zXzU0NDhbLGMoImdlbmUiLCAibG9jdXNfdGFnIiwgIm9sZF9sb2N1c190YWciKV0Kd3JpdGVfeGxzKHNob3J0X2Fubm90YXRpb25zXzU0NDgsICJnZW5lcyIsIHJvd25hbWU9IklEIiwgZmlsZT0iZXhjZWwvNTQ0OF9kYXRhX3YwLnhscyIpCgptaWNyb2Jlc181NDQ4ID0gcmVhZC5jc3YoZmlsZT0icmVmZXJlbmNlL21pY3JvYmVzb25saW5lL01HQVNfNTAwNV9hbm5vdGF0aW9ucy50YWIuZ3oiLCBoZWFkZXI9MSwgc2VwPSJcdCIpCm1pY3JvYmVzX2dvXzU0NDggPSBtaWNyb2Jlc181NDQ4WyxjKCJzeXNOYW1lIiwiR08iKV0KZ29fZW50cmllc181NDQ4ID0gc3Ryc3BsaXQoYXMuY2hhcmFjdGVyKG1pY3JvYmVzX2dvXzU0NDgkR08pLCBzcGxpdD0iLCIsIHBlcmw9VFJVRSkKbWljcm9iZXNfZ29fb25lcGVycm93XzU0NDggPSBkYXRhLmZyYW1lKG5hbWUgPSByZXAobWljcm9iZXNfZ29fNTQ0OCRzeXNOYW1lLCBzYXBwbHkoZ29fZW50cmllc181NDQ4LCBsZW5ndGgpKSwgR08gPSB1bmxpc3QoZ29fZW50cmllc181NDQ4KSkKbWljcm9iZXNfZ29fNTQ0OCA9IG1pY3JvYmVzX2dvX29uZXBlcnJvd181NDQ4CnJtKG1pY3JvYmVzX2dvX29uZXBlcnJvd181NDQ4KQpybShnb19lbnRyaWVzXzU0NDgpCiMjIFRoZXNlIGFyZSB1c2VkIGZvciBnZW5lIG9udG9sb2d5IHN0dWZmLi4uCm1pY3JvYmVzX2xlbmd0aHNfNTQ0OCA9IG1pY3JvYmVzXzU0NDhbLGMoInN5c05hbWUiLCAic3RhcnQiLCJzdG9wIildCm1pY3JvYmVzX2xlbmd0aHNfNTQ0OCRsZW5ndGggPSBhYnMobWljcm9iZXNfNTQ0OCRzdGFydCAtIG1pY3JvYmVzXzU0NDgkc3RvcCkKbWljcm9iZXNfbGVuZ3Roc181NDQ4ID0gbWljcm9iZXNfbGVuZ3Roc181NDQ4WyxjKCJzeXNOYW1lIiwibGVuZ3RoIildCmBgYAoKIyMjIE1ha2UgdG9vbHRpcHMgZm9yIGludGVyYWN0aXZlIGdyYXBocyA1NDQ4CgpgYGB7ciB0b29sdGlwX2RhdGF9CnRvb2x0aXBfZGF0YV81NDQ4ID0gZ2VuZXNfNTQ0OAp0b29sdGlwX2RhdGFfNTQ0OCA9IHRvb2x0aXBfZGF0YV81NDQ4WyxjKCJnZW5lIiwgImxvY3VzX3RhZyIpXQp0b29sdGlwX2RhdGFfNTQ0OCR0b29sdGlwID0gcGFzdGUodG9vbHRpcF9kYXRhXzU0NDgkZ2VuZSwgdG9vbHRpcF9kYXRhXzU0NDgkbG9jdXNfdGFnLCBzZXA9IjogIikKdG9vbHRpcF9kYXRhXzU0NDgkdG9vbHRpcCA9IGdzdWIoIlxcKyIsICIgIiwgdG9vbHRpcF9kYXRhXzU0NDgkdG9vbHRpcCkKdG9vbHRpcF9kYXRhXzU0NDggPSB0b29sdGlwX2RhdGFfNTQ0OFstMV0KdG9vbHRpcF9kYXRhXzU0NDggPSB0b29sdGlwX2RhdGFfNTQ0OFstMV0KaGVhZCh0b29sdGlwX2RhdGFfNTQ0OCkKYGBgCgojIyMgU2V0IHVwIHRoZSBleHBlcmltZW50YWwgZGVzaWduIDU0NDgKCmBgYHtyIGV4cGVyaW1lbnRhbF9kZXNpZ25fNTQ0OH0KbGlicmFyeV9jb2xvcnMgPSBsaXN0KCI5Ij0ieWVsbG93NCIsCiAgICAiMTEiPSJkYXJrZ3JlZW4iLAogICAgIjEyIj0icmVkIiwKICAgICIzNCI9ImRhcmtibHVlIikKdGltZV9jb2xvcnMgPSBsaXN0KHQwPSJ3aGl0ZSIsCiAgICB0MT0ibGlnaHRncmF5IiwKICAgIHQyPSJkYXJrZ3JheSIsCiAgICB0Mz0iYmxhY2siKQoKc2FtcGxlX2RlZmluaXRpb25zXzU0NDggPSByZWFkLmNzdihmaWxlPSJhbGxfc2FtcGxlc181NDQ4X3YwLmNzdiIsIHNlcD0iLCIpCnNhbXBsZV9kZWZpbml0aW9uc181NDQ4ID0gc2FtcGxlX2RlZmluaXRpb25zXzU0NDhbZ3JlcGwoJ15IUEdMJywgc2FtcGxlX2RlZmluaXRpb25zXzU0NDgkU2FtcGxlLklELCBwZXJsPVRSVUUpLF0Kc2FtcGxlX2RlZmluaXRpb25zXzU0NDgkY29sb3JzID0gbGlicmFyeV9jb2xvcnNbIGFzLmNoYXJhY3RlcihzYW1wbGVfZGVmaW5pdGlvbnNfNTQ0OCRMaWJyYXJ5KSBdCnNhbXBsZV9kZWZpbml0aW9uc181NDQ4JGNvdW50cyA9IHBhc3RlKCJkYXRhL2NvdW50X3RhYmxlcy8wNXYwTTFsMjBnZW5fIiwgc2FtcGxlX2RlZmluaXRpb25zXzU0NDgkU3RyYWluLCAiXyIsc2FtcGxlX2RlZmluaXRpb25zXzU0NDgkUmVwbGljYXRlLCBzYW1wbGVfZGVmaW5pdGlvbnNfNTQ0OCRUaW1lLCAiX2dlbm9tZS5jb3VudC5neiIsIHNlcD0iIikKc2FtcGxlX2RlZmluaXRpb25zXzU0NDggPSBhcy5kYXRhLmZyYW1lKHNhbXBsZV9kZWZpbml0aW9uc181NDQ4KQpyb3duYW1lcyhzYW1wbGVfZGVmaW5pdGlvbnNfNTQ0OCkgPSBzYW1wbGVfZGVmaW5pdGlvbnNfNTQ0OCRTYW1wbGUuSUQKYWxsX2NvdW50X3RhYmxlc181NDQ4ID0gbXlfcmVhZF9maWxlcyhhcy5jaGFyYWN0ZXIoc2FtcGxlX2RlZmluaXRpb25zXzU0NDgkU2FtcGxlLklEKSwgYXMuY2hhcmFjdGVyKHNhbXBsZV9kZWZpbml0aW9uc181NDQ4JGNvdW50cykpCmFsbF9jb3VudF9tYXRyaXhfNTQ0OCA9IGFzLm1hdHJpeChhbGxfY291bnRfdGFibGVzXzU0NDgpCmdlbmVfaW5mb181NDQ4ID0gYWxsX2NvdW50X21hdHJpeF81NDQ4W3Jvd25hbWVzKGFsbF9jb3VudF9tYXRyaXhfNTQ0OCkgJWluJSBnZW5lc181NDQ4JGxvY3VzX3RhZyxdCmFsbF9jb3VudF9tYXRyaXhfNTQ0OCA9IGFsbF9jb3VudF9tYXRyaXhfNTQ0OFtyb3duYW1lcyhhbGxfY291bnRfbWF0cml4XzU0NDgpICVpbiUgZ2VuZXNfNTQ0OCRsb2N1c190YWcsXQptZXRhZGF0YV81NDQ4ID0gbmV3KCJBbm5vdGF0ZWREYXRhRnJhbWUiLCBkYXRhLmZyYW1lKHNhbXBsZT1zYW1wbGVfZGVmaW5pdGlvbnNfNTQ0OCRTYW1wbGUuSUQsCiAgICBjb25kaXRpb249c2FtcGxlX2RlZmluaXRpb25zXzU0NDgkVGltZSwKICAgIGJhdGNoPXNhbXBsZV9kZWZpbml0aW9uc181NDQ4JExpYnJhcnksCiAgICBzdHJhaW49c2FtcGxlX2RlZmluaXRpb25zXzU0NDgkU3RyYWluLAogICAgY29sb3I9YXMuY2hhcmFjdGVyKHNhbXBsZV9kZWZpbml0aW9uc181NDQ4JGNvbG9ycyksCiAgICBjb3VudHM9c2FtcGxlX2RlZmluaXRpb25zXzU0NDgkY291bnRzKSkKCnNhbXBsZU5hbWVzKG1ldGFkYXRhXzU0NDgpID0gY29sbmFtZXMoYWxsX2NvdW50X21hdHJpeF81NDQ4KQpmZWF0dXJlX2RhdGFfNTQ0OCA9IG5ldygiQW5ub3RhdGVkRGF0YUZyYW1lIiwgYXMuZGF0YS5mcmFtZShnZW5lX2luZm9fNTQ0OCkpCmZlYXR1cmVOYW1lcyhmZWF0dXJlX2RhdGFfNTQ0OCkgPSByb3duYW1lcyhhbGxfY291bnRfbWF0cml4XzU0NDgpCmV4cGVyaW1lbnRfNTQ0OCA9IG5ldygiRXhwcmVzc2lvblNldCIsIGV4cHJzPWFsbF9jb3VudF9tYXRyaXhfNTQ0OCwKICAgIHBoZW5vRGF0YT1tZXRhZGF0YV81NDQ4LCBmZWF0dXJlRGF0YT1mZWF0dXJlX2RhdGFfNTQ0OCkKcHJpbnQoZXhwZXJpbWVudF81NDQ4KQpzdW1tYXJ5KGV4cHJzKGV4cGVyaW1lbnRfNTQ0OCkpCmhlYWQoZkRhdGEoZXhwZXJpbWVudF81NDQ4KSkKaGVhZChwRGF0YShleHBlcmltZW50XzU0NDgpKQoKcmF3X2RhdGFfNTQ0OCA9IGV4cHJzKGV4cGVyaW1lbnRfNTQ0OCkKd3JpdGVfeGxzKHJhd19kYXRhXzU0NDgsICJyYXdfZGF0YSIsIHJvd25hbWU9InJvdy5uYW1lcyIsIGZpbGU9ImV4Y2VsLzU0NDhfZGF0YV92MC54bHMiKQpgYGAKCiMjIyBub3JtYWxpemUgb24gVEFzIDU0NDgKCmBgYHtyIG5vcm1hbGl6ZV90YXNfNTQ0OH0KZ2FzX3Jhd3NlcV81NDQ4ID0gRmFGaWxlKCJyZWZlcmVuY2UvZ2VuYmFuay9tZ2FzXzUwMDUuZmFzdGEiKQpjZHNfZW50cmllc181NDQ4ID0gaW1wb3J0LmdmZjMoInJlZmVyZW5jZS9nZW5iYW5rL21nYXNfNTAwNS5nZmYiKQpjZHNfZW50cmllc181NDQ4ID0gc3Vic2V0KGNkc19lbnRyaWVzXzU0NDgsIHR5cGU9PSJnZW5lIikKbmFtZXMoY2RzX2VudHJpZXNfNTQ0OCkgPSByb3duYW1lcyhjZHNfZW50cmllc181NDQ4KQpnYXNfY2RzXzU0NDggPSBnZXRTZXEoZ2FzX3Jhd3NlcV81NDQ4LCBjZHNfZW50cmllc181NDQ4KQpuYW1lcyhnYXNfY2RzXzU0NDgpID0gY2RzX2VudHJpZXNfNTQ0OCRsb2N1c190YWcKcGF0dGVybiA9ICJUQSIKZGljdCA9IFBEaWN0KHBhdHRlcm4sIG1heC5taXNtYXRjaD0wKQpyZXN1bHRfNTQ0OCA9IHZjb3VudFBEaWN0KGRpY3QsIGdhc19jZHNfNTQ0OCkKbnVtX3Rhc181NDQ4ID0gZGF0YS5mcmFtZShuYW1lPW5hbWVzKGdhc19jZHNfNTQ0OCksIHRhcz1hcy5kYXRhLmZyYW1lKHQocmVzdWx0XzU0NDgpKSkKYGBgCgojIyMgQ291bnQgVEFzIDU0NDgKCiMjIyMgTm90ZSBmcm9tIHRoZSBmdXR1cmUKCldvdywgc28gZmFyIEkgb25seSBuZWVkZWQgdG8gYWRkIHNvbWUgbGlicmFyeSgpIGFuZCByZW1vdmUgYXNSYW5nZWREYXRhLgpJbnRlcmVzdGluZ2x5LCB3aGF0IGlzIGNvbWluZyBoYXMgYmVlbiBwdWxsZWQgaW50byBocGdsdG9vbHMgYW5kIHN0YW5kYXJkaXplZC4KCmBgYHtyIGZ1bl9jb3VudF90YXNfNTQ0OH0KcGxvdF9zYXR1cmF0aW9uID0gZnVuY3Rpb24oZmlsZSkgewogICAgIyMgVGVzdCBhcmd1bWVudHMKICAgICMjICAgIGZpbGUgPSAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdGFzX3QwdjAudHh0IgogICAgIyMgRW5kIHRlc3QgYXJndW1lbnRzCiAgICB0YWJsZSA9IHJlYWQudGFibGUoZmlsZT1maWxlLCBoZWFkZXI9MSkKICAgIHNlY29uZF9maWxlID0gcGFzdGUoZmlsZSwgIi1pbnRlciIsIHNlcD0iIikKICAgIHNlY29uZF90YWJsZSA9IHJlYWQudGFibGUoZmlsZT1zZWNvbmRfZmlsZSwgaGVhZGVyPTEpCiAgICB0YWJsZSA9IHJiaW5kKHRhYmxlLCBzZWNvbmRfdGFibGUpCiAgICBkYXRhX2xpc3QgPSBhcy5udW1lcmljKHRhYmxlJHJlYWRzKQogICAgbWF4X3JlYWRzID0gbWF4KGRhdGFfbGlzdCwgbmEucm09VFJVRSkKICAgIGxvZzJfZGF0YV9saXN0ID0gYXMubnVtZXJpYyhsb2cyKHRhYmxlJHJlYWRzICsgMSkpCiAgICBkYXRhX3Bsb3QgPSBteV9oaXN0b2dyYW0obG9nMl9kYXRhX2xpc3QsIGJpbnM9NTAwKQogICAgZGF0YV9wbG90ID0gZGF0YV9wbG90ICsgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1jKDAsNikpICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMikpCiAgICBwcmludChzcHJpbnRmKCJUaGUgbWF4aW11bSB2YWx1ZSBpczogJXMgIiwgbWF4X3JlYWRzKSkKICAgIHByaW50KHN1bW1hcnkoZGF0YV9saXN0KSkKICAgIHJhdyA9IHRhYmxlKHVubGlzdChkYXRhX2xpc3QpKQogICAgbnVtX3plcm9zID0gcmF3W2FzLm51bWVyaWMobmFtZXMocmF3KSkgPT0gMF0KICAgIG51bV96ZXJvcwogICAgbnVtX2d0X29uZXMgPSByYXdbYXMubnVtZXJpYyhuYW1lcyhyYXcpKSA+PSAxXQogICAgbnVtX2d0X29uZSA9IHN1bShudW1fZ3Rfb25lcykKICAgIG51bV9ndF9vbmUKICAgIG51bV9ndF90d29zID0gcmF3W2FzLm51bWVyaWMobmFtZXMocmF3KSkgPj0gMl0KICAgIG51bV9ndF90d28gPSBzdW0obnVtX2d0X3R3b3MpCiAgICBudW1fZ3RfdHdvCiAgICBudW1fZ3RfZm91cnMgPSByYXdbYXMubnVtZXJpYyhuYW1lcyhyYXcpKSA+PSA0XQogICAgbnVtX2d0X2ZvdXIgPSBzdW0obnVtX2d0X2ZvdXJzKQogICAgbnVtX2d0X2ZvdXIKICAgIG51bV9ndF9laWdodHMgPSByYXdbYXMubnVtZXJpYyhuYW1lcyhyYXcpKSA+PSA4XQogICAgbnVtX2d0X2VpZ2h0ID0gc3VtKG51bV9ndF9laWdodHMpCiAgICBudW1fZ3RfZWlnaHQKICAgIG51bV9ndF9zaXh0ZWVucyA9IHJhd1thcy5udW1lcmljKG5hbWVzKHJhdykpID49IDE2XQogICAgbnVtX2d0X3NpeHRlZW4gPSBzdW0obnVtX2d0X3NpeHRlZW5zKQogICAgbnVtX2d0X3NpeHRlZW4KICAgIG51bV9ndF90aGlydHl0d29zID0gcmF3W2FzLm51bWVyaWMobmFtZXMocmF3KSkgPj0gMzJdCiAgICBudW1fZ3RfdGhpcnR5dHdvID0gc3VtKG51bV9ndF90aGlydHl0d29zKQogICAgbnVtX2d0X3RoaXJ0eXR3bwogICAgc2F0dXJhdGlvbl9yYXRpb18xID0gbnVtX2d0X29uZSAvIG51bV96ZXJvcwogICAgcHJpbnQoc3ByaW50ZigiU2F0dXJhdGlvbiByYXRpbyBvZiAxcyB0byAwcyBpczogJXMiLCBzYXR1cmF0aW9uX3JhdGlvXzEpKQogICAgc2F0dXJhdGlvbl9yYXRpb184ID0gbnVtX2d0X2VpZ2h0IC8gbnVtX3plcm9zCiAgICBwcmludChzcHJpbnRmKCJTYXR1cmF0aW9uIHJhdGlvIG9mIDggdG8gMHMgaXM6ICVzIiwgc2F0dXJhdGlvbl9yYXRpb184KSkKICAgIHNhdHVyYXRpb25fcmF0aW9fMzIgPSBudW1fZ3RfdGhpcnR5dHdvIC8gbnVtX3plcm9zCiAgICBwcmludChzcHJpbnRmKCJTYXR1cmF0aW9uIHJhdGlvIG9mIDMyIHRvIDBzIGlzOiAlcyIsIHNhdHVyYXRpb25fcmF0aW9fMzIpKQogICAgcHJpbnQoc3ByaW50ZigiVGhlIG51bWJlciBvZiB6ZXJvcywgb25lcywgdHdvcywgZm91cnMsIGVpZ2h0cywgc2l4dGVlbnMsIHRoaXJ0eXR3b3MsIHNhdHVyYXRpb24xLCBzYXR1cmF0aW9uOCwgc2F0dXJhdGlvbjMyIGFyZTogJXMgJXMgJXMgJXMgJXMgJXMgJXMgJXMgJXMgJXMiLCBudW1femVyb3MsIG51bV9ndF9vbmUsIG51bV9ndF90d28sIG51bV9ndF9mb3VyLCBudW1fZ3RfZWlnaHQsIG51bV9ndF9zaXh0ZWVuLCBudW1fZ3RfdGhpcnR5dHdvLCBzYXR1cmF0aW9uX3JhdGlvXzEsIHNhdHVyYXRpb25fcmF0aW9fOCwgc2F0dXJhdGlvbl9yYXRpb18zMikpCiAgICByZXR1cm4oZGF0YV9wbG90KQp9CgojIyMgVGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbiB3aWxsIGJlIGR1bXBlZCBpbnRvIHRhX3N1bW1hcnkuY3N2CiMjIFN0YXJ0IHdpdGggdGhlIGNvbWJpbmVkIGxpYnJhcmllcwpwbG90X3NhdHVyYXRpb24oImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3Rhc190MHYwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdGFzX3QxdjAudHh0IikKcGxvdF9zYXR1cmF0aW9uKCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90YXNfdDJ2MC50eHQiKQpwbG90X3NhdHVyYXRpb24oImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3Rhc190M3YwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3Rhc190MHYwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3Rhc190MXYwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3Rhc190MnYwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3Rhc190M3YwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL2FsYWJhbWEvdGFzX3QwdjAudHh0IikKcGxvdF9zYXR1cmF0aW9uKCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvYWxhYmFtYS90YXNfdDF2MC50eHQiKQpwbG90X3NhdHVyYXRpb24oImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9hbGFiYW1hL3Rhc190MnYwLnR4dCIpCnBsb3Rfc2F0dXJhdGlvbigiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL2FsYWJhbWEvdGFzX3QzdjAudHh0IikKCnFxcGxvdC5kYXRhIDwtIGZ1bmN0aW9uICh2ZWMpIHsKIyMjIGZvbGxvd2luZyBmb3VyIGxpbmVzIGZyb20gYmFzZSBSJ3MgcXFsaW5lKCkKICAgIHkgPC0gcXVhbnRpbGUodmVjWyFpcy5uYSh2ZWMpXSwgYygwLjI1LCAwLjc1KSkKICAgIHggPC0gcW5vcm0oYygwLjI1LCAwLjc1KSkKICAgIHNsb3BlIDwtIGRpZmYoeSkvZGlmZih4KQogICAgaW50IDwtIHlbMUxdIC0gc2xvcGUgKiB4WzFMXQogICAgZCA8LSBkYXRhLmZyYW1lKHJlc2lkcyA9IHZlYykKICAgIGdncGxvdChkLCBhZXMoc2FtcGxlID0gcmVzaWRzKSkgKyBzdGF0X3FxKCkgKyBnZW9tX2FibGluZShzbG9wZSA9IHNsb3BlLCBpbnRlcmNlcHQgPSBpbnQpCn0KZ2dRUSA9IGZ1bmN0aW9uKGxtKSB7CiAgIyBleHRyYWN0IHN0YW5kYXJkaXplZCByZXNpZHVhbHMgZnJvbSB0aGUgZml0CiAgZCA8LSBkYXRhLmZyYW1lKHN0ZC5yZXNpZCA9IHJzdGFuZGFyZChsbSkpCiAgIyBjYWxjdWxhdGUgMVEvNFEgbGluZQogIHkgPC0gcXVhbnRpbGUoZCRzdGQucmVzaWRbIWlzLm5hKGQkc3RkLnJlc2lkKV0sIGMoMC4yNSwgMC43NSkpCiAgeCA8LSBxbm9ybShjKDAuMjUsIDAuNzUpKQogIHNsb3BlIDwtIGRpZmYoeSkvZGlmZih4KQogIGludCA8LSB5WzFMXSAtIHNsb3BlICogeFsxTF0KICBwIDwtIGdncGxvdChkYXRhPWQsIGFlcyhzYW1wbGU9c3RkLnJlc2lkKSkgKwogICAgc3RhdF9xcShzaGFwZT0xLCBzaXplPTMpICsgICAgICAgICAgICMgb3BlbiBjaXJjbGVzCiAgICBsYWJzKHRpdGxlPSJOb3JtYWwgUS1RIiwgICAgICAgICAgICAgIyBwbG90IHRpdGxlCiAgICAgICAgIHg9IlRoZW9yZXRpY2FsIFF1YW50aWxlcyIsICAgICAgIyB4LWF4aXMgbGFiZWwKICAgICAgICAgeT0iU3RhbmRhcmRpemVkIFJlc2lkdWFscyIpICsgICAjIHktYXhpcyBsYWJlbAogICAgZ2VvbV9hYmxpbmUoc2xvcGUgPSBzbG9wZSwgaW50ZXJjZXB0ID0gaW50LCBsaW5ldHlwZT0iZGFzaGVkIikgICMgZGFzaGVkIHJlZmVyZW5jZSBsaW5lCiAgcmV0dXJuKHApCn0KCiMjIFRoaXMgc2VjdGlvbiB3YW50cyB0aGUgb3V0cHV0IGZyb20gZXNzZW50aWFsaXR5X3Rhcy5wbCwgd2hpY2ggSSBkZWxldGVkLi4uCiMjcXFfdGVzdCA9IHRpbWUwX3Rhc1ssYygiZm9yd2FyZCIsInJldmVyc2UiKV0KIyNxcV90ZXN0JGZvcndhcmQgPSBsb2cyKHFxX3Rlc3QkZm9yd2FyZCArIDEpCiMjcXFfdGVzdCRyZXZlcnNlID0gbG9nMihxcV90ZXN0JHJldmVyc2UgKyAxKQojI3FxcGxvdCh0aW1lMF90YXNfNTQ0OCRmb3J3YXJkLCB0aW1lMV90YXNfNTQ0OCRmb3J3YXJkKQojI3FxcGxvdChxcV90ZXN0JGZvcndhcmQsIHFxX3Rlc3QkcmV2ZXJzZSkKIyNxcV9kZiA9IGRhdGEuZnJhbWUodDA9dGltZTBfdGFzXzU0NDgkZm9yd2FyZCwgdDE9dGltZTFfdGFzXzU0NDgkZm9yd2FyZCkKIyMjI3BhcmFtcyA9IGFzLmxpc3QoZml0ZGlzdHIocXFfZGYsICJ0IikkZXN0aW1hdGUpCiMjcXFwbG90LmRhdGEocXFfZGYpCiMjZ2dRUShsbSh0MH50MSxkYXRhPXFxX2RmKSkKIyNnZ1FRKGxtKGZvcndhcmR+cmV2ZXJzZSwgZGF0YT1xcV90ZXN0KSkKYGBgCgojIyBHcmFwaCBtZXRyaWNzIDU0NDgKCiMjIyBGcm9tIHRoZSBmdXR1cmUgYWdhaW4KClRoZXNlIHBsb3R0aW5nIGZ1bmN0aW9ucyBhcmUgY2VydGFpbiB0byBmYWlsLCBhcyB0aGV5IGhhdmUgYWxsIGJlZW4gcmV3cml0dGVuIGhlYXZpbHkuCgpgYGB7ciBncmFwaF9tZXRyaWNzLCBldmFsPUZBTFNFfQphbGxfZXhwdF81NDQ4ID0gZXhwdF9zdWJzZXQoZXhwZXJpbWVudF81NDQ4LCAiIikKYWxsX2Rlc2lnbl81NDQ4ID0gZGF0YS5mcmFtZShhbGxfZXhwdF81NDQ4JGRlc2lnbikKYWxsX2Rlc2lnbl81NDQ4JGxvbmduYW1lcyA9IHBhc3RlKGFsbF9kZXNpZ25fNTQ0OCRzdHJhaW4sICBhbGxfZGVzaWduXzU0NDgkYmF0Y2gsIGFsbF9kZXNpZ25fNTQ0OCRjb25kaXRpb24sIHNlcD0iXyIpCgptZXRyaWNzXzU0NDggPSBncmFwaF9tZXRyaWNzKGFsbF9leHB0XzU0NDgsIG91dF90eXBlPSJjcG0iLCBub3JtX3R5cGU9InF1YW50IiwgZmlsdGVyPSJsb2cyIiwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIG5hbWVzPWFsbF9kZXNpZ25fNTQ0OCRsb25nbmFtZXMpCm1ldHJpY3NfNTQ0OCRub3JtX3BjYXBsb3QKaGVhZChleHBycyhhbGxfZXhwdF81NDQ4JGV4cHJlc3Npb25zZXQpKQpoZWFkKGdlbmVfYW5ub3RhdGlvbnNfNTQ0OCkKCmxpYnJhcnkoaHBnbHRvb2xzKQpjb2xuYW1lcyhhbGxfZGVzaWduXzU0NDgpW1sxXV0gPC0gInNhbXBsZWlkIgp0dCA8LSBwbG90X3BjYShhbGxfZXhwdF81NDQ4LCBkZXNpZ249YWxsX2Rlc2lnbl81NDQ4KQoKCmNvcnJlbGF0aW9uc181NDQ4ID0gbXlfY29yKGV4cHJzKGFsbF9leHB0XzU0NDgkZXhwcmVzc2lvbnNldCksIG1ldGhvZD0ic3BlYXJtYW4iKQp3cml0ZV94bHMoY29ycmVsYXRpb25zXzU0NDgsICJzcF9jb3JfcHJlbm9ybSIsIHJvd25hbWU9InJvdy5uYW1lcyIsIGZpbGU9ImV4Y2VsLzU0NDhfZGF0YV92MC54bHMiKQoKbGlicmFyeShjYmNiU0VRKQp0ZXN0Ml81NDQ4ID0gbXlfbm9ybShleHB0PWFsbF9leHB0XzU0NDgsIG91dF90eXBlPSJjcF9zZXFfbSIsIG5vcm1fdHlwZT0icXVhbnQiLCBmaWx0ZXI9Im5vbmUiLCBmYXN0YT0icmVmZXJlbmNlL2dlbmJhbmsvbWdhc181MDA1LmZhc3RhIiwgZ2ZmPSJyZWZlcmVuY2UvZ2VuYmFuay9tZ2FzXzUwMDUuZ2ZmIikKaGVhZCh0ZXN0Ml81NDQ4JGNvdW50cykKCmlkX2dlbmVfYW5ub3RhdGlvbnNfNTQ0OCA9IGdlbmVfYW5ub3RhdGlvbnNfNTQ0OApyb3duYW1lcyhpZF9nZW5lX2Fubm90YXRpb25zXzU0NDgpID0gbWFrZS5uYW1lcyhpZF9nZW5lX2Fubm90YXRpb25zXzU0NDgkbG9jdXNfdGFnLCB1bmlxdWU9VFJVRSkKbm9fdGltZTNfNTQ0OCA9IGV4cHRfc3Vic2V0KGFsbF9leHB0XzU0NDgsICJjb25kaXRpb24hPSd0MyciKQpub3RpbWUzX21ldHJpY3NfNTQ0OCA9IGdyYXBoX21ldHJpY3Mobm9fdGltZTNfNTQ0OCwgb3V0X3R5cGU9InJwa20iLCBub3JtX3R5cGU9InF1YW50IiwgZmlsdGVyPSJsb2cyIiwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGFubm90YXRpb25zPWlkX2dlbmVfYW5ub3RhdGlvbnNfNTQ0OCkKbm90aW1lM19tZXRyaWNzXzU0NDgkbm9ybV9jb3JoZWF0Cm5vdGltZTNfbWV0cmljc181NDQ4JG5vcm1fcGNhcGxvdAphbGxfcXJwa21fNTQ0OCA9IG15X25vcm0oZXhwdD1hbGxfZXhwdF81NDQ4LCBub3JtPSJxdWFudCIsIGZpbHRlcj0ibG9nMiIsIGZpbHRlcl9sb3c9RkFMU0UsIG91dF90eXBlPSJycGttIiwgYW5ub3RhdGlvbnM9aWRfZ2VuZV9hbm5vdGF0aW9uc181NDQ4KSRjb3VudHMKIyNhbGxfcXJwa20gPSBteV9ub3JtKGV4cHQ9YWxsX2V4cHQsIG5vcm09InF1YW50IiwgZmlsdGVyPSJsb2cyIiwgZmlsdGVyX2xvdz1GQUxTRSwgb3V0X3R5cGU9InJwa20iLCBhbm5vdGF0aW9ucz1pZF9nZW5lX2Fubm90YXRpb25zKSRjb3VudHMKd3JpdGVfeGxzKGFsbF9xcnBrbV81NDQ4LCAibm9ybV9kYXRhIiwgZmlsZT0iZXhjZWwvNTQ0OF9kYXRhX3YwLnhscyIsIHJvd25hbWU9InJvdy5uYW1lcyIpCmFsbF9ub3JtX2V4cHRfNTQ0OCA9IGFsbF9leHB0XzU0NDgKY29ycmVsYXRpb25zXzU0NDggPSBteV9jb3IoYWxsX3FycGttXzU0NDgsIG1ldGhvZD0ic3BlYXJtYW4iKQp3cml0ZV94bHMoY29ycmVsYXRpb25zXzU0NDgsICJzcF9jb3Jfbm9ybSIsIHJvd25hbWU9InJvdy5uYW1lcyIsIGZpbGU9ImV4Y2VsLzU0NDhfZGF0YV92MC54bHMiKQoKIyMgSSBkaWQgdGhhdCBzbyB0aGF0IEkgY2FuIHJlcGxhY2UgdGhlIGV4cHJlc3Npb25zZXQgd2l0aCB0aGUKIyMgbm9ybWFsaXplZCBkYXRhIG1vcmUgZWFzaWx5Li4uCm5vcm1hbGl6ZWRfZXhwcmVzc2lvbnNldF81NDQ4ID0gYWxsX25vcm1fZXhwdF81NDQ4JGV4cHJlc3Npb25zZXQKZXhwcnMobm9ybWFsaXplZF9leHByZXNzaW9uc2V0XzU0NDgpID0gYWxsX3FycGttXzU0NDgKYWxsX25vcm1fZXhwdF81NDQ4JGV4cHJlc3Npb25zZXQgPSBub3JtYWxpemVkX2V4cHJlc3Npb25zZXRfNTQ0OAoKbXlfYm94cGxvdChleHB0PWFsbF9ub3JtX2V4cHRfNTQ0OCwgbmFtZXM9YWxsX2Rlc2lnbl81NDQ4JGxvbmduYW1lcykKbXlfZGlzaGVhdChleHB0PWFsbF9ub3JtX2V4cHRfNTQ0OCwgbmFtZXM9YWxsX2Rlc2lnbl81NDQ4JGxvbmduYW1lcywgcm93PSJjb25kaXRpb24iKQpteV9jb3JoZWF0KGV4cHQ9YWxsX25vcm1fZXhwdF81NDQ4LCBuYW1lcz1hbGxfZGVzaWduXzU0NDgkbG9uZ25hbWVzLCByb3c9ImNvbmRpdGlvbiIpCmBgYAoKIyMgQSBuZXcgZ3JhcGhfbWV0cmljcyBibG9jay4KCkluIG9yZGVyIHRvIHJlZG8gdGhlIGFib3ZlIHdvcmssIEkgbmVlZCB0byBnZW5lcmF0ZSBhIHZhbGlkIGV4cHJlc3Npb25zZXQuClNhZGx5LCBteSBmaXJzdCBlZmZvcnRzIGF0IHRoaXMgd2VyZSBpbXBlcmZlY3QgLS0gbm90IHRlcnJpYmxlIG9yIGFueXRoaW5nLCBidXQgaW5jb21wbGV0ZS4KCmBgYHtyIGdyYXBoX21ldHJpY3NfbmV3fQpsaWJyYXJ5KGhwZ2x0b29scykKbWV0YSA8LSBwRGF0YShleHBlcmltZW50XzU0NDgpCm5ld181NDQ4IDwtIGNyZWF0ZV9leHB0KG1ldGFkYXRhPXBEYXRhKGV4cGVyaW1lbnRfNTQ0OCksCiAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfaW5mbz1hbm5vdGF0aW9uc181NDQ4JGdlbmVzLAogICAgICAgICAgICAgICAgICAgICAgICBjb3VudF9kYXRhZnJhbWU9ZXhwcnMoZXhwZXJpbWVudF81NDQ4KSwKICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlX2NvbHVtbj0ic2FtcGxlIikKbmV3X25vcm0gPC0gbm9ybWFsaXplX2V4cHQobmV3XzU0NDgsIG5vcm1hbGl6ZT0icXVhbnQiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9VFJVRSwgdHJhbnNmb3JtPSJsb2cyIikKbmV3X21ldHJpY3MgPC0gaHBnbHRvb2xzOjpncmFwaF9tZXRyaWNzKG5ld181NDQ4KQpuZXdfbm9ybV9tZXRyaWNzIDwtIGhwZ2x0b29sczo6Z3JhcGhfbWV0cmljcyhuZXdfbm9ybSkKbmV3X21ldHJpY3MkbGlic2l6ZQpuZXdfbWV0cmljcyRub256ZXJvCm5ld19ub3JtX21ldHJpY3MkcGNhcGxvdApuZXdfbm9ybV9tZXRyaWNzJHRzbmVwbG90CiMjIExvb2tzIGxpa2UgSSBjYW4gcGxvdCBwcmV0dHkgbXVjaCBhbnl0aGluZyBmb3IgdGhpcyBkYXRhIG9uY2UgYWdhaW4sIHlheSEKIyMgSSBhbSBub3Qgc3VyZSB3aGF0IGFyZSBnb29kIHRoaW5ncyB0byBwbG90IGFueW1vcmUgdGhvdWdoLCBzbyBJIG1pZ2h0IGxlYXZlCiMjIGl0IGF0IHRoaXMgdW5sZXNzIEkgZ2V0IHRvIGNoYXQgd2l0aCBZb2FubiBhbmQgc2VlIHdoYXQgd291bGQgYmUgdXNlZnVsIHRvCiMjIHJldmlzaXQuCmBgYAoKIyBHZXQgY29tcGFyaXNvbnMgZm9yIFlvYW5uCgojIyBsMSB0MHQxCgpgYGB7ciBnYXNfNTQ0OF9sMXQwdDEsIGV2YWw9RkFMU0V9CiMjIENvbXBhcmUgbGlicmFyeSAxLCB0MCB0MQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QwJyl8KGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MScpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjF0MF92c19saWIxdDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDF0MHQxdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgpgYGB7ciBsMXQwdDFfbmV3fQpjb21wXzU0NDggPC0gc3Vic2V0X2V4cHQobmV3X25vcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzZXQ9IihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QxJykiKQpkYXRhIDwtIGV4cHJzKGNvbXBfNTQ0OCkKc2MgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihkYXRhKQpzYyRzY2F0dGVyCnNjJGNvcnJlbGF0aW9uCmBgYAoKIyMgbDF0MHQyCgpgYGB7ciBsMXQwdDIsIGV2YWw9RkFMU0V9CiMjIENvbXBhcmUgbGlicmFyeSAxLCB0MCB0Mgpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QwJyl8KGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjF0MF92c19saWIxdDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDF0MHQydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgpgYGB7ciBsMXQwdDJfbmV3fQpjb21wXzU0NDggPC0gc3Vic2V0X2V4cHQobmV3X25vcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzZXQ9IihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QyJykiKQpkYXRhIDwtIGV4cHJzKGNvbXBfNTQ0OCkKc2MgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihkYXRhKQpzYyRzY2F0dGVyCnNjJGNvcnJlbGF0aW9uCmBgYAoKIyMgQ29tcGFyZSBsaWJyYXJ5IDEsIHQwIHQzCgpgYGB7ciBsMXQwdDMsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QzJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcnRpbWUvbGliMXQwX3ZzX2xpYjF0M19zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC9sMXQwdDN2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCmBgYHtyIGwxdDB0M19uZXd9CmNvbXBfNTQ0OCA8LSBzdWJzZXRfZXhwdChuZXdfbm9ybSwKICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNldD0iKGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MCcpfChiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDMnKSIpCmRhdGEgPC0gZXhwcnMoY29tcF81NDQ4KQpzYyA8LSBwbG90X2xpbmVhcl9zY2F0dGVyKGRhdGEpCnNjJHNjYXR0ZXIKc2MkY29ycmVsYXRpb24KYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMSwgdDEgdDIKCmBgYHtyIGwxdDF0MiwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MScpfChiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDInKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWIxdDFfdnNfbGliMXQyX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2wxdDF0MnYwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnBuZyhmaWxlPSJmaWd1cmVzL2wxdDF0Ml9oaXN0LnBuZyIpCnNjJGJvdGhfaGlzdG9ncmFtICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMC4yNSkpCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKYGBge3IgbDF0MXQyX25ld30KY29tcF81NDQ4IDwtIHN1YnNldF9leHB0KG5ld19ub3JtLAogICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2V0PSIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QxJyl8KGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MicpIikKZGF0YSA8LSBleHBycyhjb21wXzU0NDgpCnNjIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIoZGF0YSkKc2Mkc2NhdHRlcgpzYyRjb3JyZWxhdGlvbgpgYGAKCiMjIENvbXBhcmUgbGlicmFyeSAxLCB0MSB0MwoKYGBge3IgbDF0MXQzLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QxJyl8KGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjF0MV92c19saWIxdDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDF0MXQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgpgYGB7ciBsMXQxdDNfbmV3fQpjb21wXzU0NDggPC0gc3Vic2V0X2V4cHQobmV3X25vcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzZXQ9IihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QzJykiKQpkYXRhIDwtIGV4cHJzKGNvbXBfNTQ0OCkKc2MgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihkYXRhKQpzYyRzY2F0dGVyCnNjJGNvcnJlbGF0aW9uCmBgYAoKIyMjIFN0b3BwaW5nIGhlcmUuCgpPaywgc28gSSBkZW1vbnN0cmF0ZWQgSSBjYW4gcmVtYWtlIGFsbCBteSBvbGQgcGxvdHMsIGJ1dCBJCmFtIG5vdCBzdXJlIGhvdyBtdWNoIEkgY2FyZSBiZXlvbmQgdGhhdC4gIEkgdGhpbmsgdGhhdCBkZW1vbnN0cmF0ZXMgdGhhdCBJIGNhbgppbiBmYWN0IHJlcHJvZHVjZSBteSBvbGQgcmVzdWx0cy4KCiMjIENvbXBhcmUgbGlicmFyeSAxLCB0MiB0MwoKYGBge3IgbDF0MnQzLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QyJyl8KGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjF0Ml92c19saWIxdDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDF0MnQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMiwgdDAgdDEKCmBgYHtyIGwydDB0MSwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MScpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjJ0MF92c19saWIydDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDJ0MHQxdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMiwgdDAgdDIKCmBgYHtyIGwydDB0MiwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjJ0MF92c19saWIydDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDJ0MHQydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMiwgdDAgdDMKCmBgYHtyIGwydDB0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjJ0MF92c19saWIydDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDJ0MHQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMiwgdDEgdDIKCmBgYHtyIGwydDF0MiwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjJ0MV92c19saWIydDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDJ0MXQydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMiwgdDEgdDMKCmBgYHtyIGwydDF0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjJ0MV92c19saWIydDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDJ0MXQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMiwgdDIgdDMKCmBgYHtyIGwydDJ0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDInKXwoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjJ0Ml92c19saWIydDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDJ0MnQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMywgdDAgdDEKCmBgYHtyIGwzdDB0MSwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PScxMicgJiBjb25kaXRpb249PSd0MScpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjN0MF92c19saWIzdDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDN0MHQxdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMywgdDAgdDIKCmBgYHtyIGwzdDB0MiwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PScxMicgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjN0MF92c19saWIzdDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDN0MHQydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMywgdDAgdDMKCmBgYHtyIGwzdDB0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PScxMicgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjN0MF92c19saWIzdDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDN0MHQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMywgdDEgdDIKCmBgYHtyIGwzdDF0MiwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PScxMicgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjN0MV92c19saWIzdDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDN0MXQydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMywgdDEgdDMKCmBgYHtyIGwzdDF0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PScxMicgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjN0MV92c19saWIzdDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDN0MXQzdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIGxpYnJhcnkgMywgdDIgdDMKCmBgYHtyIGwzdDJ0M30KCmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QyJyl8KGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDMnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWIzdDJfdnNfbGliM3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2wzdDJ0M3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CgpgYGAKCiMjIENvbXBhcmUgbGlicmFyeSA0LCB0MCB0MQoKYGBge3IgbDR0MHQxfQoKY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MScpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJ0aW1lL2xpYjR0MF92c19saWI0dDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvbDR0MHQxdjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKCmBgYAoKIyMgQ29tcGFyZSBsaWJyYXJ5IDQsIHQwIHQyCgpgYGB7ciBsNHQwdDIsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzM0JyAmIGNvbmRpdGlvbj09J3QwJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDInKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWI0dDBfdnNfbGliNHQyX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2w0dDB0MnYwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSBsaWJyYXJ5IDQsIHQwIHQzCgpgYGB7ciBsNHQwdDMsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzM0JyAmIGNvbmRpdGlvbj09J3QwJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDMnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWI0dDBfdnNfbGliNHQzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2w0dDB0M3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSBsaWJyYXJ5IDQsIHQxIHQyCgpgYGB7ciBsNHQxdDIsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzM0JyAmIGNvbmRpdGlvbj09J3QxJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDInKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWI0dDFfdnNfbGliNHQyX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2w0dDF0MnYwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSBsaWJyYXJ5IDQsIHQxIHQzCgpgYGB7ciBsNHQxdDMsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzM0JyAmIGNvbmRpdGlvbj09J3QxJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDMnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWI0dDFfdnNfbGliNHQzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2w0dDF0M3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSBsaWJyYXJ5IDQsIHQyIHQzCgpgYGB7ciBsNHQydDMsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzM0JyAmIGNvbmRpdGlvbj09J3QyJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDMnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVydGltZS9saWI0dDJfdnNfbGliNHQzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL2w0dDJ0M3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgUmVwZWF0IGNvcnJlbGF0aW9ucyBrZWVwaW5nIHRpbWUgdGhlIHNhbWUsIGJ1dCBmb3IgZWFjaCBsaWJyYXJ5IHNldAoKIyMgdDBsMWwyCgpgYGB7ciB0MGwxbDIsIGV2YWw9RkFMU0V9CiMjIENvbXBhcmUgdDAsIGxpYjEgbGliMgpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QwJyl8KGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDAnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjF0MF92c19saWIydDBfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDBsMWwydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQwLCBsaWIxIGxpYjMKCmBgYHtyIHQwbDFsMywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MCcpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QwJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIxdDBfdnNfbGliM3QwX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QwbDFsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MCwgbGliMSBsaWI0CgpgYGB7ciB0MGwxbDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MCcpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliMXQwX3ZzX2xpYjR0MF9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90MGwxbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDAsIGxpYjIgbGliMwoKYGBge3IgdDBsMmwzLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MCcpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QwJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIydDBfdnNfbGliM3QwX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QwbDJsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MCwgbGliMiBsaWI0CgpgYGB7ciB0MGwybDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzExJyAmIGNvbmRpdGlvbj09J3QwJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDAnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjJ0MF92c19saWI0dDBfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDBsMmw0djAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQwLCBsaWIzIGxpYjQKCmBgYHtyIHQwbDNsNCwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDAnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MCcpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliM3QwX3ZzX2xpYjR0MF9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90MGwzbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDEsIGxpYjEgbGliMgoKYGBge3IgdDFsMWwyLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QxJyl8KGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDEnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjF0MV92c19saWIydDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDFsMWwydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQxLCBsaWIxIGxpYjMKCmBgYHtyIHQxbDFsMywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MScpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QxJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIxdDFfdnNfbGliM3QxX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QxbDFsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MSwgbGliMSBsaWI0CgpgYGB7ciB0MWwxbDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MScpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliMXQxX3ZzX2xpYjR0MV9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90MWwxbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDEsIGxpYjIgbGliMwoKYGBge3IgdDFsMmwzLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MScpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QxJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIydDFfdnNfbGliM3QxX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QxbDJsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MSwgbGliMiBsaWI0CgpgYGB7ciB0MWwybDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzExJyAmIGNvbmRpdGlvbj09J3QxJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDEnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjJ0MV92c19saWI0dDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDFsMmw0djAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQxLCBsaWIzIGxpYjQKCmBgYHtyIHQxbDNsNCwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDEnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MScpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliM3QxX3ZzX2xpYjR0MV9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90MWwzbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDIsIGxpYjEgbGliMgoKYGBge3IgdDJsMWwyLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QyJyl8KGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDInKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjF0Ml92c19saWIydDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDJsMWwydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQyLCBsaWIxIGxpYjMKCmBgYHtyIHQybDFsMywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MicpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QyJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIxdDJfdnNfbGliM3QyX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QybDFsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MiwgbGliMSBsaWI0CgpgYGB7ciB0MmwxbDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDInKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliMXQyX3ZzX2xpYjR0Ml9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90MmwxbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDIsIGxpYjIgbGliMwoKYGBge3IgdDJsMmwzLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MicpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QyJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIydDJfdnNfbGliM3QyX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QybDJsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MiwgbGliMiBsaWI0CgpgYGB7ciB0MmwybDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzExJyAmIGNvbmRpdGlvbj09J3QyJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDInKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjJ0Ml92c19saWI0dDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDJsMmw0djAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQyLCBsaWIzIGxpYjQKCmBgYHtyIHQybDNsNCwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDInKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MicpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliM3QyX3ZzX2xpYjR0Ml9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90MmwzbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDMsIGxpYjEgbGliMgoKYGBge3IgdDNsMWwyLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PSc5JyAmIGNvbmRpdGlvbj09J3QzJyl8KGJhdGNoPT0nMTEnICYgY29uZGl0aW9uPT0ndDMnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjF0M192c19saWIydDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDNsMWwydjAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQzLCBsaWIxIGxpYjMKCmBgYHtyIHQzbDFsMywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nOScgJiBjb25kaXRpb249PSd0MycpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QzJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIxdDNfdnNfbGliM3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QzbDFsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MywgbGliMSBsaWI0CgpgYGB7ciB0M2wxbDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzknICYgY29uZGl0aW9uPT0ndDMnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliMXQzX3ZzX2xpYjR0M19zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90M2wxbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIENvbXBhcmUgdDMsIGxpYjIgbGliMwoKYGBge3IgdDNsMmwzLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICIoYmF0Y2g9PScxMScgJiBjb25kaXRpb249PSd0MycpfChiYXRjaD09JzEyJyAmIGNvbmRpdGlvbj09J3QzJykiKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9pbnRlcmxpYi9saWIydDNfdnNfbGliM3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wXzU0NDgsIGNvcm1ldGhvZD0ic3BlYXJtYW4iLCBndmlzX2ZpbGVuYW1lPSJodG1sL3QzbDJsM3YwLmh0bWwiKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CmBgYAoKIyMgQ29tcGFyZSB0MywgbGliMiBsaWI0CgpgYGB7ciB0M2wybDQsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgIihiYXRjaD09JzExJyAmIGNvbmRpdGlvbj09J3QzJyl8KGJhdGNoPT0nMzQnICYgY29uZGl0aW9uPT0ndDMnKSIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2ludGVybGliL2xpYjJ0M192c19saWI0dDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfNTQ0OCwgY29ybWV0aG9kPSJzcGVhcm1hbiIsIGd2aXNfZmlsZW5hbWU9Imh0bWwvdDNsMmw0djAuaHRtbCIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIyBDb21wYXJlIHQzLCBsaWIzIGxpYjQKCmBgYHtyIHQzbDNsNCwgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiKGJhdGNoPT0nMTInICYgY29uZGl0aW9uPT0ndDMnKXwoYmF0Y2g9PSczNCcgJiBjb25kaXRpb249PSd0MycpIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvaW50ZXJsaWIvbGliM3QzX3ZzX2xpYjR0M19zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF81NDQ4LCBjb3JtZXRob2Q9InNwZWFybWFuIiwgZ3Zpc19maWxlbmFtZT0iaHRtbC90M2wzbDR2MC5odG1sIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMjIFNpbXBsZSBjb21wYXJpc29ucwoKSSB3YW50IHRvIGRvIHNvbWUgc2ltcGxlIHZvb20vbGltbWEgY29tcGFyaXNvbnMgb2YgdGhlIHRpbWVzOgoxLiAgdDAgdG8gdDEKMi4gIHQwIHRvIHQyCjMuICB0MCB0byB0Mwo0LiAgdDEgdG8gdDIKNS4gIHQxIHRvIHQzCjYuICB0MiB0byB0MwoKIyMgU2ltcGxlIGNvbXBhcmlzb25zCgojIyBUaW1lIDAgdG8gdGltZSAxCgpgYGB7ciB0MHQxLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICJjb25kaXRpb249PSd0MCcgfCBjb25kaXRpb249PSd0MSciKQp0MHQxID0gc2ltcGxlX2NvbXBhcmlzb24oY29tcF81NDQ4LCBzaGVldD0idDB0MSIsIHdvcmtib29rPSJleGNlbC81NDQ4X2NvbXBhcmlzb25zX3YwLnhscyIsIGJhc2VuYW1lPSJodG1sL3QwdDF2MCIsIHRvb2x0aXBfZGF0YT10b29sdGlwX2RhdGFfNTQ0OCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvY29tYmluZWRfbGlicy90MHQxdjAucGRmIikKdDB0MSRjb250cmFzdF9oaXN0b2dyYW0KdDB0MSRhbWVhbl9oaXN0b2dyYW0KdDB0MSRwdmFsdWVfaGlzdG9ncmFtCnQwdDEkbWFfcGxvdAp0MHQxJHZvbGNhbm9fcGxvdApwbmcoZmlsZT0iZmlndXJlcy9jb21iaW5lZF90MHQxdjAucG5nIikKdDB0MSRjb2VmZmljaWVudF9zY2F0dGVyCmRldi5vZmYoKQp0MHQxJGNvZWZmaWNpZW50X3gKdDB0MSRjb2VmZmljaWVudF95CnQwdDEkY29lZmZpY2llbnRfYm90aApkZXYub2ZmKCkKYGBgCgojIyBUaW1lIDAgdG8gdGltZSAyCgpgYGB7ciB0MHQyLCBldmFsPUZBTFNFfQpjb21wXzU0NDggPSBleHB0X3N1YnNldChhbGxfbm9ybV9leHB0XzU0NDgsICJjb25kaXRpb249PSd0MCcgfCBjb25kaXRpb249PSd0MiciKQp0MHQyID0gc2ltcGxlX2NvbXBhcmlzb24oY29tcF81NDQ4LCBzaGVldD0idDB0MiIsIHdvcmtib29rPSJleGNlbC81NDQ4X2NvbXBhcmlzb25zX3YwLnhscyIsIGJhc2VuYW1lPSJodG1sL3QwdDJ2MCIsIHRvb2x0aXBfZGF0YT10b29sdGlwX2RhdGFfNTQ0OCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvY29tYmluZWRfbGlicy90MHQydjAucGRmIikKdDB0MiRjb250cmFzdF9oaXN0b2dyYW0KdDB0MiRhbWVhbl9oaXN0b2dyYW0KdDB0MiRwdmFsdWVfaGlzdG9ncmFtCnQwdDIkbWFfcGxvdAp0MHQyJHZvbGNhbm9fcGxvdAp0MHQyJGNvZWZmaWNpZW50X3NjYXR0ZXIKdDB0MiRjb2VmZmljaWVudF94CnQwdDIkY29lZmZpY2llbnRfeQp0MHQyJGNvZWZmaWNpZW50X2JvdGgKZGV2Lm9mZigpCmBgYAoKIyMgVGltZSAwIHRvIHRpbWUgMwoKYGBge3IgdDB0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiY29uZGl0aW9uPT0ndDAnIHwgY29uZGl0aW9uPT0ndDMnIikKdDB0MyA9IHNpbXBsZV9jb21wYXJpc29uKGNvbXBfNTQ0OCwgc2hlZXQ9InQwdDMiLCB3b3JrYm9vaz0iZXhjZWwvNTQ0OF9jb21wYXJpc29uc192MC54bHMiLCBiYXNlbmFtZT0iaHRtbC90MHQzdjAiLCB0b29sdGlwX2RhdGE9dG9vbHRpcF9kYXRhXzU0NDgpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2NvbWJpbmVkX2xpYnMvdDB0M3YwLnBkZiIpCnQwdDMkY29udHJhc3RfaGlzdG9ncmFtCnQwdDMkYW1lYW5faGlzdG9ncmFtCnQwdDMkcHZhbHVlX2hpc3RvZ3JhbQp0MHQzJG1hX3Bsb3QKdDB0MyR2b2xjYW5vX3Bsb3QKdDB0MyRjb2VmZmljaWVudF9zY2F0dGVyCnQwdDMkY29lZmZpY2llbnRfeAp0MHQzJGNvZWZmaWNpZW50X3kKdDB0MyRjb2VmZmljaWVudF9ib3RoCmRldi5vZmYoKQpgYGAKCiMjIFRpbWUgMSB0byB0aW1lIDIKCmBgYHtyIHQxdDIsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgImNvbmRpdGlvbj09J3QxJyB8IGNvbmRpdGlvbj09J3QyJyIpCnQxdDIgPSBzaW1wbGVfY29tcGFyaXNvbihjb21wXzU0NDgsIHNoZWV0PSJ0MXQyIiwgd29ya2Jvb2s9ImV4Y2VsLzU0NDhfY29tcGFyaXNvbnNfdjAueGxzIiwgYmFzZW5hbWU9Imh0bWwvdDF0MnYwIiwgdG9vbHRpcF9kYXRhPXRvb2x0aXBfZGF0YV81NDQ4KQojI3QxdDIgPSBzaW1wbGVfY29tcGFyaXNvbihjb21wXzU0NDgsIHNoZWV0PSJ0MXQyIiwgd29ya2Jvb2s9ImV4Y2VsLzU0NDhfY29tcGFyaXNvbnNfdjAueGxzIikKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvY29tYmluZWRfbGlicy90MXQydjAucGRmIikKdDF0MiRjb250cmFzdF9oaXN0b2dyYW0KdDF0MiRhbWVhbl9oaXN0b2dyYW0KdDF0MiRwdmFsdWVfaGlzdG9ncmFtCnQxdDIkbWFfcGxvdAp0MXQyJHZvbGNhbm9fcGxvdAp0MXQyJGNvZWZmaWNpZW50X3NjYXR0ZXIKdDF0MiRjb2VmZmljaWVudF94CnQxdDIkY29lZmZpY2llbnRfeQp0MXQyJGNvZWZmaWNpZW50X2JvdGgKZGV2Lm9mZigpCmBgYAoKIyMgVGltZSAxIHRvIHRpbWUgMwoKYGBge3IgdDF0MywgZXZhbD1GQUxTRX0KY29tcF81NDQ4ID0gZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF81NDQ4LCAiY29uZGl0aW9uPT0ndDEnIHwgY29uZGl0aW9uPT0ndDMnIikKdDF0MyA9IHNpbXBsZV9jb21wYXJpc29uKGNvbXBfNTQ0OCwgc2hlZXQ9InQxdDMiLCB3b3JrYm9vaz0iZXhjZWwvNTQ0OF9jb21wYXJpc29uc192MC54bHMiLCBiYXNlbmFtZT0iaHRtbC90MXQzdjAiLCB0b29sdGlwX2RhdGE9dG9vbHRpcF9kYXRhXzU0NDgpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2NvbWJpbmVkX2xpYnMvdDF0M3YwLnBkZiIpCnQxdDMkY29udHJhc3RfaGlzdG9ncmFtCnQxdDMkYW1lYW5faGlzdG9ncmFtCnQxdDMkcHZhbHVlX2hpc3RvZ3JhbQp0MXQzJG1hX3Bsb3QKdDF0MyR2b2xjYW5vX3Bsb3QKdDF0MyRjb2VmZmljaWVudF9zY2F0dGVyCnQxdDMkY29lZmZpY2llbnRfeAp0MXQzJGNvZWZmaWNpZW50X3kKdDF0MyRjb2VmZmljaWVudF9ib3RoCmRldi5vZmYoKQpgYGAKCiMjIFRpbWUgMiB0byB0aW1lIDMKCmBgYHtyIHQydDMsIGV2YWw9RkFMU0V9CmNvbXBfNTQ0OCA9IGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfNTQ0OCwgImNvbmRpdGlvbj09J3QyJyB8IGNvbmRpdGlvbj09J3QzJyIpCnQydDMgPSBzaW1wbGVfY29tcGFyaXNvbihjb21wXzU0NDgsIHNoZWV0PSJ0MnQzIiwgd29ya2Jvb2s9ImV4Y2VsLzU0NDhfY29tcGFyaXNvbnNfdjAueGxzIiwgYmFzZW5hbWU9Imh0bWwvdDJ0MyIsIHRvb2x0aXBfZGF0YT10b29sdGlwX2RhdGFfNTQ0OCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvY29tYmluZWRfbGlicy90MnQzdjAucGRmIikKdDJ0MyRjb250cmFzdF9oaXN0b2dyYW0KdDJ0MyRhbWVhbl9oaXN0b2dyYW0KdDJ0MyRwdmFsdWVfaGlzdG9ncmFtCnQydDMkbWFfcGxvdAp0MnQzJHZvbGNhbm9fcGxvdAp0MnQzJGNvZWZmaWNpZW50X3NjYXR0ZXIKdDJ0MyRjb2VmZmljaWVudF94CnQydDMkY29lZmZpY2llbnRfeQp0MnQzJGNvZWZmaWNpZW50X2JvdGgKZGV2Lm9mZigpCmBgYAoKIyBDb21wYXJlIHQxIHRvIHQyIHVzaW5nIGdvc2VxPwoKSXQgc2VlbXMgdG8gbWUgdGhhdCB0aG9zZSBnZW5lcyB3aGljaCBnbyB1cC9kb3duIGluIGhpdHMgZnJvbSB0aW1lcyAxIHRvIDIgYXJlIGxpa2VseSBvZiBpbnRlcmVzdApPbmNlIHNpbXBsZSB0YXNrIHRvIHBlcmZvcm0gaXMgYSBzaW1wbGUgZ29zZXEgYW5hbHlzaXMgb2YgdGhlbS4KCmBgYHtyIHQxdDJnb3NlcSwgZXZhbD1GQUxTRQpzdW1tYXJ5KHQxdDIkZG93bnNpZ25pZmljYW50KQpoZWFkKGFubm90YXRpb25fNTQ0OF9pbmZvKQpoZWFkKG1pY3JvYmVzXzU0NDgpCgojIyBUaGUgZmlyc3QgaXRlbQoKdXBfc2lnbmlmaWNhbnRfdGFibGUwMSA9IHN1YnNldCh0MHQxJHVwc2lnbmlmaWNhbnQsIGxvZ0ZDID4gMC44KQp1cF9zaWduaWZpY2FudF90YWJsZTAxJElEID0gcm93bmFtZXModXBfc2lnbmlmaWNhbnRfdGFibGUwMSkKZG93bl9zaWduaWZpY2FudF90YWJsZTAxID0gc3Vic2V0KHQwdDEkZG93bnNpZ25pZmljYW50LCBsb2dGQyA8IC0wLjgpCmRvd25fc2lnbmlmaWNhbnRfdGFibGUwMSRJRCA9IHJvd25hbWVzKGRvd25fc2lnbmlmaWNhbnRfdGFibGUwMSkKCnVwX3NpZ25pZmljYW50X3RhYmxlMDIgPSBzdWJzZXQodDB0MiR1cHNpZ25pZmljYW50LCBsb2dGQyA+IDAuOCkKdXBfc2lnbmlmaWNhbnRfdGFibGUwMiRJRCA9IHJvd25hbWVzKHVwX3NpZ25pZmljYW50X3RhYmxlMDIpCmRvd25fc2lnbmlmaWNhbnRfdGFibGUwMiA9IHN1YnNldCh0MHQyJGRvd25zaWduaWZpY2FudCwgbG9nRkMgPCAtMC44KQpkb3duX3NpZ25pZmljYW50X3RhYmxlMDIkSUQgPSByb3duYW1lcyhkb3duX3NpZ25pZmljYW50X3RhYmxlMDIpCgp1cF9zaWduaWZpY2FudF90YWJsZTAzID0gc3Vic2V0KHQwdDMkdXBzaWduaWZpY2FudCwgbG9nRkMgPiAwLjgpCnVwX3NpZ25pZmljYW50X3RhYmxlMDMkSUQgPSByb3duYW1lcyh1cF9zaWduaWZpY2FudF90YWJsZTAzKQpkb3duX3NpZ25pZmljYW50X3RhYmxlMDMgPSBzdWJzZXQodDB0MyRkb3duc2lnbmlmaWNhbnQsIGxvZ0ZDIDwgLTAuOCkKZG93bl9zaWduaWZpY2FudF90YWJsZTAzJElEID0gcm93bmFtZXMoZG93bl9zaWduaWZpY2FudF90YWJsZTAzKQoKdXBfc2lnbmlmaWNhbnRfdGFibGUxMiA9IHN1YnNldCh0MXQyJHVwc2lnbmlmaWNhbnQsIGxvZ0ZDID4gMC44KQp1cF9zaWduaWZpY2FudF90YWJsZTEyJElEID0gcm93bmFtZXModXBfc2lnbmlmaWNhbnRfdGFibGUxMikKZG93bl9zaWduaWZpY2FudF90YWJsZTEyID0gc3Vic2V0KHQxdDIkZG93bnNpZ25pZmljYW50LCBsb2dGQyA8IC0wLjgpCmRvd25fc2lnbmlmaWNhbnRfdGFibGUxMiRJRCA9IHJvd25hbWVzKGRvd25fc2lnbmlmaWNhbnRfdGFibGUxMikKCnVwX3NpZ25pZmljYW50X3RhYmxlMTMgPSBzdWJzZXQodDF0MyR1cHNpZ25pZmljYW50LCBsb2dGQyA+IDAuOCkKdXBfc2lnbmlmaWNhbnRfdGFibGUxMyRJRCA9IHJvd25hbWVzKHVwX3NpZ25pZmljYW50X3RhYmxlMTMpCmRvd25fc2lnbmlmaWNhbnRfdGFibGUxMyA9IHN1YnNldCh0MXQzJGRvd25zaWduaWZpY2FudCwgbG9nRkMgPCAtMC44KQpkb3duX3NpZ25pZmljYW50X3RhYmxlMTMkSUQgPSByb3duYW1lcyhkb3duX3NpZ25pZmljYW50X3RhYmxlMTMpCgojIyBUaGUgc2Vjb25kIGl0ZW06CmdlbmVfbGVuZ3Roc181NDQ4ID0gYW5ub3RhdGlvbl81NDQ4X2luZm9bLGMoImxvY3VzX3RhZyIsIndpZHRoIildCmNvbG5hbWVzKGdlbmVfbGVuZ3Roc181NDQ4KSA9IGMoIklEIiwid2lkdGgiKQojIyBUaGUgdGhpcmQgaXRlbQpjb2xuYW1lcyhtaWNyb2Jlc19nb181NDQ4KSA9IGMoIklEIiwiR08iKQptaWNyb2Jlc19nb181NDQ4JElEID0gZ3N1YigiU3B5XyIsICJTcHkiLCBtaWNyb2Jlc19nb181NDQ4JElEKQoKIyMgTmVlZCB0byBzZXQgdXAgdGhlIG5vbi1kZWZhdWx0IEdPIG1hcHBpbmcgZm9yIGNsdXN0ZXJQcm9maWxlcgojIyBUaGlzIGlzIG5vdyBpbmNsdWRlZCBpbiBkaXJ0eV9nbygpCiMjR2ZmMkdlbmVUYWJsZSgiLi4vcmVmZXJlbmNlL2dlbmJhbmsvbWdhc181MDA1LmdmZiIpCiMjZ29tYXAgPSBtaWNyb2Jlc19nbwojI2NvbG5hbWVzKGdvbWFwKSA9IGMoImVudHJlemdlbmUiLCJnb19hY2Nlc3Npb24iKQojI2J1aWxkR09tYXAoZ29tYXApCgp1cF9nbzAxID0gZGlydHlfZ28odXBfc2lnbmlmaWNhbnRfdGFibGUwMSwgbGVuZ3Rocz1nZW5lX2xlbmd0aHNfNTQ0OCwgZ29pZHM9bWljcm9iZXNfZ29fNTQ0OCwgYWRqdXN0PU5VTEwsIG9yZ2FuaXNtPSJnYXNfNTAwNSIsIGluY2x1ZGVfY25ldHBsb3RzPUZBTFNFKQp1cF9nbzAxJHB2YWx1ZV9wbG90CnVwX2dvMDEkbWZfZ3JvdXBfYmFycGxvdAp1cF9nbzAxJG1mX2VucmljaGVkX2JhcnBsb3QKZG93bl9nbzAxID0gZGlydHlfZ28oZG93bl9zaWduaWZpY2FudF90YWJsZTAxLCBsZW5ndGhzPWdlbmVfbGVuZ3Roc181NDQ4LCBnb2lkcz1taWNyb2Jlc19nb181NDQ4LCBhZGp1c3Q9TlVMTCwgb3JnYW5pc209Imdhc181MDA1IikKZG93bl9nbzAxJHB2YWx1ZV9wbG90CmRvd25fZ28wMSRtZl9ncm91cF9iYXJwbG90CmRvd25fZ28wMSRtZl9lbnJpY2hlZF9iYXJwbG90Cgp1cF9nbzAyID0gZGlydHlfZ28odXBfc2lnbmlmaWNhbnRfdGFibGUwMiwgbGVuZ3Rocz1nZW5lX2xlbmd0aHNfNTQ0OCwgZ29pZHM9bWljcm9iZXNfZ29fNTQ0OCwgYWRqdXN0PU5VTEwsIG9yZ2FuaXNtPSJnYXNfNTAwNSIsIGluY2x1ZGVfY25ldHBsb3RzPUZBTFNFKQp1cF9nbzAyJHB2YWx1ZV9wbG90CnVwX2dvMDIkbWZfZ3JvdXBfYmFycGxvdAp1cF9nbzAyJG1mX2VucmljaGVkX2JhcnBsb3QKZG93bl9nbzAyID0gZGlydHlfZ28oZG93bl9zaWduaWZpY2FudF90YWJsZTAyLCBsZW5ndGhzPWdlbmVfbGVuZ3Roc181NDQ4LCBnb2lkcz1taWNyb2Jlc19nb181NDQ4LCBhZGp1c3Q9TlVMTCwgb3JnYW5pc209Imdhc181MDA1IikKZG93bl9nbzAyJHB2YWx1ZV9wbG90CmRvd25fZ28wMiRtZl9ncm91cF9iYXJwbG90CmRvd25fZ28wMiRtZl9lbnJpY2hlZF9iYXJwbG90Cgp1cF9nbzAzID0gZGlydHlfZ28odXBfc2lnbmlmaWNhbnRfdGFibGUwMywgbGVuZ3Rocz1nZW5lX2xlbmd0aHNfNTQ0OCwgZ29pZHM9bWljcm9iZXNfZ29fNTQ0OCwgYWRqdXN0PU5VTEwsIG9yZ2FuaXNtPSJnYXNfNTAwNSIsIGluY2x1ZGVfY25ldHBsb3RzPUZBTFNFKQp1cF9nbzAzJHB2YWx1ZV9wbG90CnVwX2dvMDMkbWZfZ3JvdXBfYmFycGxvdAp1cF9nbzAzJG1mX2VucmljaGVkX2JhcnBsb3QKZG93bl9nbzAzID0gZGlydHlfZ28oZG93bl9zaWduaWZpY2FudF90YWJsZTAzLCBsZW5ndGhzPWdlbmVfbGVuZ3Roc181NDQ4LCBnb2lkcz1taWNyb2Jlc19nb181NDQ4LCBhZGp1c3Q9TlVMTCwgb3JnYW5pc209Imdhc181MDA1IikKZG93bl9nbzAzJHB2YWx1ZV9wbG90CmRvd25fZ28wMyRtZl9ncm91cF9iYXJwbG90CmRvd25fZ28wMyRtZl9lbnJpY2hlZF9iYXJwbG90Cgp1cF9nbzEyID0gZGlydHlfZ28odXBfc2lnbmlmaWNhbnRfdGFibGUxMiwgbGVuZ3Rocz1nZW5lX2xlbmd0aHNfNTQ0OCwgZ29pZHM9bWljcm9iZXNfZ29fNTQ0OCwgYWRqdXN0PU5VTEwsIG9yZ2FuaXNtPSJnYXNfNTAwNSIsIGluY2x1ZGVfY25ldHBsb3RzPUZBTFNFKQpzdW1tYXJ5KHVwX2dvMTIpCnVwX2dvMTIkcHZhbHVlX3Bsb3QKdXBfZ28xMiRtZl9ncm91cF9iYXJwbG90CnVwX2dvMTIkbWZfZW5yaWNoZWRfYmFycGxvdApkb3duX2dvMTIgPSBkaXJ0eV9nbyhkb3duX3NpZ25pZmljYW50X3RhYmxlMTIsIGxlbmd0aHM9Z2VuZV9sZW5ndGhzXzU0NDgsIGdvaWRzPW1pY3JvYmVzX2dvXzU0NDgsIGFkanVzdD1OVUxMLCBvcmdhbmlzbT0iZ2FzXzUwMDUiKQpkb3duX2dvMTIkcHZhbHVlX3Bsb3QKZG93bl9nbzEyJG1mX2dyb3VwX2JhcnBsb3QKZG93bl9nbzEyJG1mX2VucmljaGVkX2JhcnBsb3QKCnVwX2dvMTMgPSBkaXJ0eV9nbyh1cF9zaWduaWZpY2FudF90YWJsZTEzLCBsZW5ndGhzPWdlbmVfbGVuZ3Roc181NDQ4LCBnb2lkcz1taWNyb2Jlc19nb181NDQ4LCBhZGp1c3Q9TlVMTCwgb3JnYW5pc209Imdhc181MDA1IiwgaW5jbHVkZV9jbmV0cGxvdHM9RkFMU0UpCnN1bW1hcnkodXBfZ28xMykKdXBfZ28xMyRwdmFsdWVfcGxvdAp1cF9nbzEzJG1mX2dyb3VwX2JhcnBsb3QKdXBfZ28xMyRtZl9lbnJpY2hlZF9iYXJwbG90CmRvd25fZ28xMyA9IGRpcnR5X2dvKGRvd25fc2lnbmlmaWNhbnRfdGFibGUxMywgbGVuZ3Rocz1nZW5lX2xlbmd0aHNfNTQ0OCwgZ29pZHM9bWljcm9iZXNfZ29fNTQ0OCwgYWRqdXN0PU5VTEwsIG9yZ2FuaXNtPSJnYXNfNTAwNSIpCmRvd25fZ28xMyRwdmFsdWVfcGxvdApkb3duX2dvMTMkbWZfZ3JvdXBfYmFycGxvdApkb3duX2dvMTMkbWZfZW5yaWNoZWRfYmFycGxvdApgYGAKCiMjIEVzc2VudGlhbGl0eSBleGFtaW5hdGlvbgoKYGBge3IgZXNzZW50aWFsaXR5XzU0NDgsIGV2YWw9RkFMU0V9CnBsb3RfZXNzZW50aWFsaXR5ID0gZnVuY3Rpb24oZmlsZSkgewogICAgZXNzID0gcmVhZC5jc3YoZmlsZT1maWxlLCBjb21tZW50LmNoYXI9IiMiLCBzZXA9Ilx0IiwgaGVhZGVyPUZBTFNFKQogICAgY29sbmFtZXMoZXNzKSA9IGMoImdlbmUiLCJvcmZfaGl0cyIsIm9yZl90YXMiLCJtYXhfcnVuIiwibWF4X3J1bl9zcGFuIiwicG9zdGVyaW9yX3piYXIiLCJjYWxsIikKICAgIGVzcyA9IGVzc1t3aXRoKGVzcywgb3JkZXIocG9zdGVyaW9yX3piYXIpKSwgXQogICAgZXNzID0gc3Vic2V0KGVzcywgcG9zdGVyaW9yX3piYXIgPiAtMSkKICAgIGVzcyA9IHRyYW5zZm9ybShlc3MsIHJhbms9YXZlKHBvc3Rlcmlvcl96YmFyLCBGVU49ZnVuY3Rpb24oeCkgb3JkZXIoeCxkZWNyZWFzaW5nPUZBTFNFKSkpCiAgICB6YmFyX3Bsb3QgPSBnZ3Bsb3QoZGF0YT1lc3MsIGFlcyh4PXJhbmssIHk9cG9zdGVyaW9yX3piYXIpKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIHNpemU9MikgKwogICAgICAgIGdlb21faGxpbmUoY29sb3I9ImdyZXkiLCB5aW50ZXJjZXB0PTAuMDM3MSkgKwogICAgICAgIGdlb21faGxpbmUoY29sb3I9ImdyZXkiLCB5aW50ZXJjZXB0PTAuOTkwMikgKwogICAgICAgIHRoZW1lX2J3KCkKICAgIHNwYW5fZGYgPSBlc3NbLGMoIm1heF9ydW4iLCJtYXhfcnVuX3NwYW4iKV0KICAgIHNwYW5fcGxvdCA9IG15X2xpbmVhcl9zY2F0dGVyKHNwYW5fZGYpCiAgICByZXR1cm5zID0gbGlzdCh6YmFyPXpiYXJfcGxvdCwgc2NhdHRlcj1zcGFuX3Bsb3Qkc2NhdHRlcikKICAgIHJldHVybihyZXR1cm5zKQp9CgpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTEuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QxdjBfZXNzZW50aWFsaXR5X20xLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MnYwX2Vzc2VudGlhbGl0eV9tMS5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTEuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QwdjBfZXNzZW50aWFsaXR5X20yLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MXYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDJ2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QzdjBfZXNzZW50aWFsaXR5X20yLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MHYwX2Vzc2VudGlhbGl0eV9tNC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDF2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QydjBfZXNzZW50aWFsaXR5X200LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90M3YwX2Vzc2VudGlhbGl0eV9tNC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTguY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QxdjBfZXNzZW50aWFsaXR5X204LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MnYwX2Vzc2VudGlhbGl0eV9tOC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTguY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QwdjBfZXNzZW50aWFsaXR5X20xNi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDF2MF9lc3NlbnRpYWxpdHlfbTE2LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MnYwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QzdjBfZXNzZW50aWFsaXR5X20xNi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTMyLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MXYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QydjBfZXNzZW50aWFsaXR5X20zMi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTMyLmNzdiIpCgpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QwdjBfZXNzZW50aWFsaXR5X20xLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDF2MF9lc3NlbnRpYWxpdHlfbTEuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MnYwX2Vzc2VudGlhbGl0eV9tMS5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QzdjBfZXNzZW50aWFsaXR5X20xLmNzdiIpCgoKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MHYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QxdjBfZXNzZW50aWFsaXR5X20yLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDJ2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90M3YwX2Vzc2VudGlhbGl0eV9tMi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QwdjBfZXNzZW50aWFsaXR5X200LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDF2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MnYwX2Vzc2VudGlhbGl0eV9tNC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QzdjBfZXNzZW50aWFsaXR5X200LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDB2MF9lc3NlbnRpYWxpdHlfbTguY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tOC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QydjBfZXNzZW50aWFsaXR5X204LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDN2MF9lc3NlbnRpYWxpdHlfbTguY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MHYwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MnYwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90M3YwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MHYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MnYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90M3YwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MHYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDF2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QydjBfZXNzZW50aWFsaXR5X20yLmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90M3YwX2Vzc2VudGlhbGl0eV9tMi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QxdjBfZXNzZW50aWFsaXR5X200LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MnYwX2Vzc2VudGlhbGl0eV9tNC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QwdjBfZXNzZW50aWFsaXR5X204LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MXYwX2Vzc2VudGlhbGl0eV9tOC5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDJ2MF9lc3NlbnRpYWxpdHlfbTguY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QzdjBfZXNzZW50aWFsaXR5X204LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MHYwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKcGxvdF9lc3NlbnRpYWxpdHkoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QxdjBfZXNzZW50aWFsaXR5X20xNi5jc3YiKQpwbG90X2Vzc2VudGlhbGl0eSgiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDJ2MF9lc3NlbnRpYWxpdHlfbTE2LmNzdiIpCnBsb3RfZXNzZW50aWFsaXR5KCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90M3YwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IikKCnpiYXJzXzU0NDggPSBjKCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MHYwX2Vzc2VudGlhbGl0eV9tMS5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QwdjBfZXNzZW50aWFsaXR5X200LmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MHYwX2Vzc2VudGlhbGl0eV9tOC5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTE2LmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MHYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKemJhcl9kZiA9IGRhdGEuZnJhbWUoKQpjb3VudCA9IDAKZm9yICh6IGluIHpiYXJzXzU0NDgpIHsKICAgIGNvdW50ID0gY291bnQgKyAxCiAgICBlc3MgPSByZWFkLmNzdihmaWxlPXosIGNvbW1lbnQuY2hhcj0iIyIsIHNlcD0iXHQiLCBoZWFkZXI9RkFMU0UpCiAgICBjb2xuYW1lcyhlc3MpID0gYygiZ2VuZSIsIm9yZl9oaXRzIiwib3JmX3RhcyIsIm1heF9ydW4iLCJtYXhfcnVuX3NwYW4iLCJwb3N0ZXJpb3JfemJhciIsImNhbGwiKQogICAgcHJpbnQoc3VtbWFyeShlc3MkcG9zdGVyaW9yX3piYXIpKQogICAgZXNzID0gZXNzW3dpdGgoZXNzLCBvcmRlcihwb3N0ZXJpb3JfemJhcikpLCBdCiAgICBlc3MgPSBzdWJzZXQoZXNzLCBwb3N0ZXJpb3JfemJhciA+IC0xKQogICAgZXNzID0gdHJhbnNmb3JtKGVzcywgcmFuaz1hdmUocG9zdGVyaW9yX3piYXIsIEZVTj1mdW5jdGlvbih4KSBvcmRlcih4LGRlY3JlYXNpbmc9RkFMU0UpKSkKICAgIGlmIChjb3VudCA9PSAxKSB7CiAgICAgICAgemJhcl9kZiA9IGVzc1ssYygicmFuayIsInBvc3Rlcmlvcl96YmFyIildCiAgICAgICAgcHJpbnQoaGVhZCh6YmFyX2RmKSkKICAgIH0gZWxzZSB7CiAgICAgICAgemJhcl9kZlssIHpdID0gYXMudmVjdG9yKGVzcyRwb3N0ZXJpb3JfemJhcikKICAgIH0KfQpjb2xuYW1lcyh6YmFyX2RmKSA9IGMoInJhbmsiLCJvbmUiLCJ0d28iLCJmb3VyIiwiZWlnaHQiLCJzaXh0ZWVuIiwidGhpcnR5dHdvIikKCmdncGxvdChkYXRhPXpiYXJfZGYpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9InllbGxvdyIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT1vbmUpKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJvcmFuZ2UiLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9dHdvKSkgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0icmVkIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PWZvdXIpKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJncmVlbiIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT1laWdodCkpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9ImJsdWUiLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9c2l4dGVlbikpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9ImJsYWNrIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PXRoaXJ0eXR3bykpICsKICAgIGdlb21faGxpbmUoY29sb3I9ImdyZXkiLCB5aW50ZXJjZXB0PTAuMDM3MSkgKwogICAgZ2VvbV9obGluZShjb2xvcj0iZ3JleSIsIHlpbnRlcmNlcHQ9MC45OTAyKSArCiAgICB0aGVtZV9idygpCgp6YmFyc181NDQ4ID0gYygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDF2MF9lc3NlbnRpYWxpdHlfbTEuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QxdjBfZXNzZW50aWFsaXR5X20yLmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MXYwX2Vzc2VudGlhbGl0eV9tNC5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDF2MF9lc3NlbnRpYWxpdHlfbTguY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QxdjBfZXNzZW50aWFsaXR5X20xNi5jc3YiLCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MXYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKemJhcl9kZiA9IGRhdGEuZnJhbWUoKQpjb3VudCA9IDAKZm9yICh6IGluIHpiYXJzXzU0NDgpIHsKICAgIGNvdW50ID0gY291bnQgKyAxCiAgICBlc3MgPSByZWFkLmNzdihmaWxlPXosIGNvbW1lbnQuY2hhcj0iIyIsIHNlcD0iXHQiLCBoZWFkZXI9RkFMU0UpCiAgICBjb2xuYW1lcyhlc3MpID0gYygiZ2VuZSIsIm9yZl9oaXRzIiwib3JmX3RhcyIsIm1heF9ydW4iLCJtYXhfcnVuX3NwYW4iLCJwb3N0ZXJpb3JfemJhciIsImNhbGwiKQogICAgcHJpbnQoc3VtbWFyeShlc3MkcG9zdGVyaW9yX3piYXIpKQogICAgZXNzID0gZXNzW3dpdGgoZXNzLCBvcmRlcihwb3N0ZXJpb3JfemJhcikpLCBdCiAgICBlc3MgPSBzdWJzZXQoZXNzLCBwb3N0ZXJpb3JfemJhciA+IC0xKQogICAgZXNzID0gdHJhbnNmb3JtKGVzcywgcmFuaz1hdmUocG9zdGVyaW9yX3piYXIsIEZVTj1mdW5jdGlvbih4KSBvcmRlcih4LGRlY3JlYXNpbmc9RkFMU0UpKSkKICAgIGlmIChjb3VudCA9PSAxKSB7CiAgICAgICAgemJhcl9kZiA9IGVzc1ssYygicmFuayIsInBvc3Rlcmlvcl96YmFyIildCiAgICAgICAgcHJpbnQoaGVhZCh6YmFyX2RmKSkKICAgIH0gZWxzZSB7CiAgICAgICAgemJhcl9kZlssIHpdID0gYXMudmVjdG9yKGVzcyRwb3N0ZXJpb3JfemJhcikKICAgIH0KfQpjb2xuYW1lcyh6YmFyX2RmKSA9IGMoInJhbmsiLCJvbmUiLCJ0d28iLCJmb3VyIiwiZWlnaHQiLCJzaXh0ZWVuIiwgInRoaXJ0eXR3byIpCgpnZ3Bsb3QoZGF0YT16YmFyX2RmKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJ5ZWxsb3ciLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9b25lKSkgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0ib3JhbmdlIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PXR3bykpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9InJlZCIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT1mb3VyKSkgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iZ3JlZW4iLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9ZWlnaHQpKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJibHVlIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PXNpeHRlZW4pKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJibGFjayIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT10aGlydHl0d28pKSArCiAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjAzNzEpICsKICAgICAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjk5MDIpICsKICAgICAgICB0aGVtZV9idygpCgp6YmFyc181NDQ4ID0gYygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDJ2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QydjBfZXNzZW50aWFsaXR5X200LmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90MnYwX2Vzc2VudGlhbGl0eV9tOC5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDJ2MF9lc3NlbnRpYWxpdHlfbTE2LmNzdiIpCnpiYXJfZGYgPSBkYXRhLmZyYW1lKCkKY291bnQgPSAwCmZvciAoeiBpbiB6YmFyc181NDQ4KSB7CiAgICBjb3VudCA9IGNvdW50ICsgMQogICAgZXNzID0gcmVhZC5jc3YoZmlsZT16LCBjb21tZW50LmNoYXI9IiMiLCBzZXA9Ilx0IiwgaGVhZGVyPUZBTFNFKQogICAgY29sbmFtZXMoZXNzKSA9IGMoImdlbmUiLCJvcmZfaGl0cyIsIm9yZl90YXMiLCJtYXhfcnVuIiwibWF4X3J1bl9zcGFuIiwicG9zdGVyaW9yX3piYXIiLCJjYWxsIikKICAgIHByaW50KHN1bW1hcnkoZXNzJHBvc3Rlcmlvcl96YmFyKSkKICAgIGVzcyA9IGVzc1t3aXRoKGVzcywgb3JkZXIocG9zdGVyaW9yX3piYXIpKSwgXQogICAgZXNzID0gc3Vic2V0KGVzcywgcG9zdGVyaW9yX3piYXIgPiAtMSkKICAgIGVzcyA9IHRyYW5zZm9ybShlc3MsIHJhbms9YXZlKHBvc3Rlcmlvcl96YmFyLCBGVU49ZnVuY3Rpb24oeCkgb3JkZXIoeCxkZWNyZWFzaW5nPUZBTFNFKSkpCiAgICBpZiAoY291bnQgPT0gMSkgewogICAgICAgIHpiYXJfZGYgPSBlc3NbLGMoInJhbmsiLCJwb3N0ZXJpb3JfemJhciIpXQogICAgICAgIHByaW50KGhlYWQoemJhcl9kZikpCiAgICB9IGVsc2UgewogICAgICAgIHpiYXJfZGZbLCB6XSA9IGFzLnZlY3Rvcihlc3MkcG9zdGVyaW9yX3piYXIpCiAgICB9Cn0KY29sbmFtZXMoemJhcl9kZikgPSBjKCJyYW5rIiwidHdvIiwiZm91ciIsImVpZ2h0Iiwic2l4dGVlbiIpCgpnZ3Bsb3QoZGF0YT16YmFyX2RmKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0icmVkIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PXR3bykpICsKICAgICAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJibHVlIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PWZvdXIpKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iYmxhY2siLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9ZWlnaHQpKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iZ3JlZW4iLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9c2l4dGVlbikpICsKICAgICAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjAzNzEpICsKICAgICAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjk5MDIpICsKICAgICAgICB0aGVtZV9idygpCgp6YmFyc181NDQ4ID0gYygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy81NDQ4L3QzdjBfZXNzZW50aWFsaXR5X200LmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvNTQ0OC90M3YwX2Vzc2VudGlhbGl0eV9tOC5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTE2LmNzdiIpCnpiYXJfZGYgPSBkYXRhLmZyYW1lKCkKY291bnQgPSAwCmZvciAoeiBpbiB6YmFyc181NDQ4KSB7CiAgICBjb3VudCA9IGNvdW50ICsgMQogICAgZXNzID0gcmVhZC5jc3YoZmlsZT16LCBjb21tZW50LmNoYXI9IiMiLCBzZXA9Ilx0IiwgaGVhZGVyPUZBTFNFKQogICAgY29sbmFtZXMoZXNzKSA9IGMoImdlbmUiLCJvcmZfaGl0cyIsIm9yZl90YXMiLCJtYXhfcnVuIiwibWF4X3J1bl9zcGFuIiwicG9zdGVyaW9yX3piYXIiLCJjYWxsIikKICAgIHByaW50KHN1bW1hcnkoZXNzJHBvc3Rlcmlvcl96YmFyKSkKICAgIGVzcyA9IGVzc1t3aXRoKGVzcywgb3JkZXIocG9zdGVyaW9yX3piYXIpKSwgXQogICAgZXNzID0gc3Vic2V0KGVzcywgcG9zdGVyaW9yX3piYXIgPiAtMSkKICAgIGVzcyA9IHRyYW5zZm9ybShlc3MsIHJhbms9YXZlKHBvc3Rlcmlvcl96YmFyLCBGVU49ZnVuY3Rpb24oeCkgb3JkZXIoeCxkZWNyZWFzaW5nPUZBTFNFKSkpCiAgICBpZiAoY291bnQgPT0gMSkgewogICAgICAgIHpiYXJfZGYgPSBlc3NbLGMoInJhbmsiLCJwb3N0ZXJpb3JfemJhciIpXQogICAgICAgIHByaW50KGhlYWQoemJhcl9kZikpCiAgICB9IGVsc2UgewogICAgICAgIHpiYXJfZGZbLCB6XSA9IGFzLnZlY3Rvcihlc3MkcG9zdGVyaW9yX3piYXIpCiAgICB9Cn0KY29sbmFtZXMoemJhcl9kZikgPSBjKCJyYW5rIiwidHdvIiwiZm91ciIsImVpZ2h0Iiwic2l4dGVlbiIpCgpnZ3Bsb3QoZGF0YT16YmFyX2RmKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0icmVkIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PXR3bykpICsKICAgICAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJibHVlIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PWZvdXIpKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iYmxhY2siLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9ZWlnaHQpKSArCiAgICAgICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iZ3JlZW4iLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9c2l4dGVlbikpICsKICAgICAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjAzNzEpICsKICAgICAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjk5MDIpICsKICAgICAgICB0aGVtZV9idygpCgojIyBSZXBlYXQgZm9yIE5aMTMxCgp6YmFyc19uejEzMSA9IGMoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MHYwX2Vzc2VudGlhbGl0eV9tMS5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QwdjBfZXNzZW50aWFsaXR5X20yLmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDB2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MHYwX2Vzc2VudGlhbGl0eV9tOC5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QwdjBfZXNzZW50aWFsaXR5X20xNi5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QwdjBfZXNzZW50aWFsaXR5X20zMi5jc3YiKQp6YmFyX2RmID0gZGF0YS5mcmFtZSgpCmNvdW50ID0gMApmb3IgKHogaW4gemJhcnNfbnoxMzEpIHsKICAgIGNvdW50ID0gY291bnQgKyAxCiAgICBlc3MgPSByZWFkLmNzdihmaWxlPXosIGNvbW1lbnQuY2hhcj0iIyIsIHNlcD0iXHQiLCBoZWFkZXI9RkFMU0UpCiAgICBjb2xuYW1lcyhlc3MpID0gYygiZ2VuZSIsIm9yZl9oaXRzIiwib3JmX3RhcyIsIm1heF9ydW4iLCJtYXhfcnVuX3NwYW4iLCJwb3N0ZXJpb3JfemJhciIsImNhbGwiKQogICAgcHJpbnQoc3VtbWFyeShlc3MkcG9zdGVyaW9yX3piYXIpKQogICAgZXNzID0gZXNzW3dpdGgoZXNzLCBvcmRlcihwb3N0ZXJpb3JfemJhcikpLCBdCiAgICBlc3MgPSBzdWJzZXQoZXNzLCBwb3N0ZXJpb3JfemJhciA+IC0xKQogICAgZXNzID0gdHJhbnNmb3JtKGVzcywgcmFuaz1hdmUocG9zdGVyaW9yX3piYXIsIEZVTj1mdW5jdGlvbih4KSBvcmRlcih4LGRlY3JlYXNpbmc9RkFMU0UpKSkKICAgIGlmIChjb3VudCA9PSAxKSB7CiAgICAgICAgemJhcl9kZiA9IGVzc1ssYygicmFuayIsInBvc3Rlcmlvcl96YmFyIildCiAgICAgICAgcHJpbnQoaGVhZCh6YmFyX2RmKSkKICAgIH0gZWxzZSB7CiAgICAgICAgemJhcl9kZlssIHpdID0gYXMudmVjdG9yKGVzcyRwb3N0ZXJpb3JfemJhcikKICAgIH0KfQpjb2xuYW1lcyh6YmFyX2RmKSA9IGMoInJhbmsiLCJvbmUiLCJ0d28iLCJmb3VyIiwiZWlnaHQiLCJzaXh0ZWVuIiwidGhpcnR5dHdvIikKZ2dwbG90KGRhdGE9emJhcl9kZikgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0ieWVsbG93Iiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PW9uZSkpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9Im9yYW5nZSIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT10d28pKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJyZWQiLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9Zm91cikpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9ImdyZWVuIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PWVpZ2h0KSkgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iYmx1ZSIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT1zaXh0ZWVuKSkgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0iYmxhY2siLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9dGhpcnR5dHdvKSkgKwogICAgZ2VvbV9obGluZShjb2xvcj0iZ3JleSIsIHlpbnRlcmNlcHQ9MC4wMzcxKSArCiAgICBnZW9tX2hsaW5lKGNvbG9yPSJncmV5IiwgeWludGVyY2VwdD0wLjk5MDIpICsKICAgIHRoZW1lX2J3KCkKCgoKemJhcnNfbnoxMzEgPSBjKCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDF2MF9lc3NlbnRpYWxpdHlfbTEuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiLCAiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzL256MTMxL3QxdjBfZXNzZW50aWFsaXR5X200LmNzdiIsICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDF2MF9lc3NlbnRpYWxpdHlfbTguY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tMTYuY3N2IiwgImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tMzIuY3N2IikKemJhcl9kZiA9IGRhdGEuZnJhbWUoKQpjb3VudCA9IDAKZm9yICh6IGluIHpiYXJzX256MTMxKSB7CiAgICBjb3VudCA9IGNvdW50ICsgMQogICAgZXNzID0gcmVhZC5jc3YoZmlsZT16LCBjb21tZW50LmNoYXI9IiMiLCBzZXA9Ilx0IiwgaGVhZGVyPUZBTFNFKQogICAgY29sbmFtZXMoZXNzKSA9IGMoImdlbmUiLCJvcmZfaGl0cyIsIm9yZl90YXMiLCJtYXhfcnVuIiwibWF4X3J1bl9zcGFuIiwicG9zdGVyaW9yX3piYXIiLCJjYWxsIikKICAgIHByaW50KHN1bW1hcnkoZXNzJHBvc3Rlcmlvcl96YmFyKSkKICAgIGVzcyA9IGVzc1t3aXRoKGVzcywgb3JkZXIocG9zdGVyaW9yX3piYXIpKSwgXQogICAgZXNzID0gc3Vic2V0KGVzcywgcG9zdGVyaW9yX3piYXIgPiAtMSkKICAgIGVzcyA9IHRyYW5zZm9ybShlc3MsIHJhbms9YXZlKHBvc3Rlcmlvcl96YmFyLCBGVU49ZnVuY3Rpb24oeCkgb3JkZXIoeCxkZWNyZWFzaW5nPUZBTFNFKSkpCiAgICBpZiAoY291bnQgPT0gMSkgewogICAgICAgIHpiYXJfZGYgPSBlc3NbLGMoInJhbmsiLCJwb3N0ZXJpb3JfemJhciIpXQogICAgICAgIHByaW50KGhlYWQoemJhcl9kZikpCiAgICB9IGVsc2UgewogICAgICAgIHpiYXJfZGZbLCB6XSA9IGFzLnZlY3Rvcihlc3MkcG9zdGVyaW9yX3piYXIpCiAgICB9Cn0KY29sbmFtZXMoemJhcl9kZikgPSBjKCJyYW5rIiwib25lIiwidHdvIiwiZm91ciIsImVpZ2h0Iiwic2l4dGVlbiIsInRoaXJ0eXR3byIpCmdncGxvdChkYXRhPXpiYXJfZGYpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9InllbGxvdyIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT1vbmUpKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJvcmFuZ2UiLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9dHdvKSkgKwogICAgZ2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIGNvbG91cj0icmVkIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PWZvdXIpKSArCiAgICBnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSJncmVlbiIsIHNpemU9MiwgYWVzKHg9cmFuaywgeT1laWdodCkpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9ImJsdWUiLCBzaXplPTIsIGFlcyh4PXJhbmssIHk9c2l4dGVlbikpICsKICAgIGdlb21fcG9pbnQoc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9ImJsYWNrIiwgc2l6ZT0yLCBhZXMoeD1yYW5rLCB5PXRoaXJ0eXR3bykpICsKICAgIGdlb21faGxpbmUoY29sb3I9ImdyZXkiLCB5aW50ZXJjZXB0PTAuMDM3MSkgKwogICAgZ2VvbV9obGluZShjb2xvcj0iZ3JleSIsIHlpbnRlcmNlcHQ9MC45OTAyKSArCiAgICB0aGVtZV9idygpCmBgYAojIE5aMTMxIGRhdGEKCiMjIEdlbm9tZSBhbm5vdGF0aW9uIGlucHV0CgpgYGB7ciBkYXRhX2lucHV0X2dlbm9tZV9uejEzMSwgZXZhbD1GQUxTRX0KYW5ub3RhdGlvbnNfbnogPSBpbXBvcnQuZ2ZmMygicmVmZXJlbmNlL2dlbmJhbmsvbWdhc19uejEzMS5nZmYiLCBhc1JhbmdlZERhdGE9RkFMU0UpCmFubm90YXRpb25faW5mb19ueiA9IGFzLmRhdGEuZnJhbWUoYW5ub3RhdGlvbnNfbnopCnJvd25hbWVzKGFubm90YXRpb25faW5mb19ueikgPSBtYWtlLm5hbWVzKGFubm90YXRpb25zX256JGxvY3VzX3RhZywgdW5pcXVlPVRSVUUpCmdlbmVzX256ID0gYW5ub3RhdGlvbl9pbmZvX256W2Fubm90YXRpb25faW5mb19ueiR0eXBlPT0iZ2VuZSIsXQpnZW5lX2Fubm90YXRpb25zX256ID0gc3Vic2V0KGdlbmVzX256LCBzZWxlY3QgPSBjKCJzdGFydCIsICJlbmQiLCAid2lkdGgiLCAic3RyYW5kIiwgImdlbmUiLCAibG9jdXNfdGFnIikpCnNob3J0X2Fubm90YXRpb25zX256ID0gZ2VuZV9hbm5vdGF0aW9uc19uelssYygiZ2VuZSIsICJsb2N1c190YWciKV0Kd3JpdGVfeGxzKGdlbmVfYW5ub3RhdGlvbnNfbnosICJhbm5vdGF0aW9ucyIsIHJvd25hbWU9IklEIiwgZmlsZT0iZXhjZWwvbnoxMzFfZGF0YV92MC54bHMiKQoKbWljcm9iZXNfbnogPSByZWFkLmNzdihmaWxlPSJyZWZlcmVuY2UvbWljcm9iZXNvbmxpbmUvbnoxMzFfYW5ub3RhdGlvbnMudGFiLmd6IiwgaGVhZGVyPTEsIHNlcD0iXHQiKQptaWNyb2Jlc19nb19ueiA9IG1pY3JvYmVzX256WyxjKCJzeXNOYW1lIiwiR08iKV0KZ29fZW50cmllc19ueiA9IHN0cnNwbGl0KGFzLmNoYXJhY3RlcihtaWNyb2Jlc19nb19ueiRHTyksIHNwbGl0PSIsIiwgcGVybD1UUlVFKQptaWNyb2Jlc19nb19vbmVwZXJyb3dfbnogPSBkYXRhLmZyYW1lKG5hbWUgPSByZXAobWljcm9iZXNfZ29fbnokc3lzTmFtZSwgc2FwcGx5KGdvX2VudHJpZXNfbnosIGxlbmd0aCkpLCBHTyA9IHVubGlzdChnb19lbnRyaWVzX256KSkKbWljcm9iZXNfZ29fbnogPSBtaWNyb2Jlc19nb19vbmVwZXJyb3dfbnoKcm0obWljcm9iZXNfZ29fb25lcGVycm93X256KQpybShnb19lbnRyaWVzX256KQojIyBUaGVzZSBhcmUgdXNlZCBmb3IgZ2VuZSBvbnRvbG9neSBzdHVmZi4uLgptaWNyb2Jlc19sZW5ndGhzX256ID0gbWljcm9iZXNfbnpbLGMoInN5c05hbWUiLCAic3RhcnQiLCJzdG9wIildCm1pY3JvYmVzX2xlbmd0aHNfbnokbGVuZ3RoID0gYWJzKG1pY3JvYmVzX256JHN0YXJ0IC0gbWljcm9iZXNfbnokc3RvcCkKbWljcm9iZXNfbGVuZ3Roc19ueiA9IG1pY3JvYmVzX2xlbmd0aHNfbnpbLGMoInN5c05hbWUiLCJsZW5ndGgiKV0KYGBgCgojIyMgTWFrZSB0b29sdGlwcyBmb3IgaW50ZXJhY3RpdmUgZ3JhcGhzCgpgYGB7ciB0b29sdGlwX2RhdGFfbnp9CnRvb2x0aXBfZGF0YV9ueiA9IGFubm90YXRpb25faW5mb19uegp0b29sdGlwX2RhdGFfbnogPSB0b29sdGlwX2RhdGFfbnpbLGMoImdlbmUiLCAibG9jdXNfdGFnIildCnRvb2x0aXBfZGF0YV9ueiR0b29sdGlwID0gcGFzdGUodG9vbHRpcF9kYXRhX256JGdlbmUsIHRvb2x0aXBfZGF0YV9ueiRsb2N1c190YWcsIHNlcD0iOiAiKQp0b29sdGlwX2RhdGFfbnokdG9vbHRpcCA9IGdzdWIoIlxcKyIsICIgIiwgdG9vbHRpcF9kYXRhX256JHRvb2x0aXApCmhlYWQodG9vbHRpcF9kYXRhX256KQpgYGAKCiMjIyBTZXQgdXAgdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24KCmBgYHtyIGV4cGVyaW1lbnRhbF9kZXNpZ25fbnp9CiMjIFRoZSBhbGxfc2FtcGxlcy5jc3YgY29udHJvbHMgdGhlIGV4cGVyaW1lbnRhbCBzZXR0aW5ncwojIyBhbGwgdGhlIGZvbGxvd2luZyBsaW5lcyBtYW5pcHVsYXRlIHRoZSBpbmZvcm1hdGlvbiB0aGVyZWluCiMjIGluIG9yZGVyIHRvIHNldCB1cCBtZWRpYSB0eXBlcywgcmVwbGljYXRlcywgZXRjCnNhbXBsZV9kZWZpbml0aW9uc19ueiA9IHJlYWQuY3N2KGZpbGU9ImFsbF9zYW1wbGVzX256MTMxX3YwLmNzdiIsIHNlcD0iLCIpCiMjIElmIEkgaGF2ZSBzdW1tYXJ5IGxpbmVzIGluIHRoZSBjc3YsIHRoZXkgd2lsbCBub3Qgc3RhcnQgd2l0aCAnSFBHTCcgYW5kIHNvIHNob3VsZCBiZSBkcm9wcGVkLgpzYW1wbGVfZGVmaW5pdGlvbnNfbnogPSBzYW1wbGVfZGVmaW5pdGlvbnNfbnpbZ3JlcGwoJ15IUEdMJywgc2FtcGxlX2RlZmluaXRpb25zX256JFNhbXBsZS5JRCwgcGVybD1UUlVFKSxdCiMjIFByZSBzZXQgdGhlIGNvbG9yIHNjaGVtZQpzYW1wbGVfZGVmaW5pdGlvbnNfbnokY29sb3JzID0gbGlicmFyeV9jb2xvcnMKIyMgVGhpcyBsb25nIHN0YXRlbWVudCBqdXN0IHdyaXRlcyBvdXQgYSBjb21wdXRlciBwYXRoIG5hbWUgY29udGFpbmluZyB0aGUgY291bnQgZmlsZXMgdG8gcmVhZCBieSBzYW1wbGUgbmFtZS4Kc2FtcGxlX2RlZmluaXRpb25zX256JGNvdW50cyA9IHBhc3RlKCJkYXRhL2NvdW50X3RhYmxlcy8wNXYwTTFsMjBnZW5fIiwgc2FtcGxlX2RlZmluaXRpb25zX256JFN0cmFpbiwgIl8iLCBzYW1wbGVfZGVmaW5pdGlvbnNfbnokVGltZSwgIl9nZW5vbWUuY291bnQuZ3oiLCBzZXA9IiIpCnNhbXBsZV9kZWZpbml0aW9uc19ueiA9IGFzLmRhdGEuZnJhbWUoc2FtcGxlX2RlZmluaXRpb25zX256KQpyb3duYW1lcyhzYW1wbGVfZGVmaW5pdGlvbnNfbnopID0gc2FtcGxlX2RlZmluaXRpb25zX256JFNhbXBsZS5JRAojIyBteV9yZWFkX2ZpbGVzIGRvZXMganVzdCB0aGF0LCBpdCByZWFkcyB0aGUgY291bnQgdGFibGVzIGFuZCBtYWtlcyBhIGxhcmdlIHJhdyBjb3VudCB0YWJsZSBmcm9tIHRoZW0uCmFsbF9jb3VudF90YWJsZXNfbnogPSBteV9yZWFkX2ZpbGVzKGFzLmNoYXJhY3RlcihzYW1wbGVfZGVmaW5pdGlvbnNfbnokU2FtcGxlLklEKSwgYXMuY2hhcmFjdGVyKHNhbXBsZV9kZWZpbml0aW9uc19ueiRjb3VudHMpKQojIyBtYWtlIGl0IGludG8gYSBtYXRyaXggZm9yIHVzZSBhcyBhbiBleHByZXNzaW9uc2V0CmFsbF9jb3VudF9tYXRyaXhfbnogPSBhcy5tYXRyaXgoYWxsX2NvdW50X3RhYmxlc19ueikKCmdlbmVfaW5mb19ueiA9IGFsbF9jb3VudF9tYXRyaXhfbnpbcm93bmFtZXMoYWxsX2NvdW50X21hdHJpeF9ueikgJWluJSBhbm5vdGF0aW9uc19ueiRsb2N1c190YWcsXQphbGxfY291bnRfbWF0cml4X256ID0gYWxsX2NvdW50X21hdHJpeF9ueltyb3duYW1lcyhhbGxfY291bnRfbWF0cml4X256KSAlaW4lIGFubm90YXRpb25zX256JGxvY3VzX3RhZyxdCm1ldGFkYXRhX256ID0gbmV3KCJBbm5vdGF0ZWREYXRhRnJhbWUiLCBkYXRhLmZyYW1lKHNhbXBsZT1zYW1wbGVfZGVmaW5pdGlvbnNfbnokU2FtcGxlLklELAogICAgY29uZGl0aW9uPXNhbXBsZV9kZWZpbml0aW9uc19ueiRUaW1lLAogICAgYmF0Y2g9c2FtcGxlX2RlZmluaXRpb25zX256JExpYnJhcnksCiAgICBzdHJhaW49c2FtcGxlX2RlZmluaXRpb25zX256JFN0cmFpbiwKICAgIGNvbG9yPWFzLmNoYXJhY3RlcihzYW1wbGVfZGVmaW5pdGlvbnNfbnokY29sb3JzKSwKICAgIGNvdW50cz1zYW1wbGVfZGVmaW5pdGlvbnNfbnokY291bnRzKSkKCiMjIE5vdyBnZW5lcmF0ZSB0aGUgZXhwcmVzc2lvbnNldCBvYmplY3QKc2FtcGxlTmFtZXMobWV0YWRhdGFfbnopID0gY29sbmFtZXMoYWxsX2NvdW50X21hdHJpeF9ueikKZmVhdHVyZV9kYXRhX256ID0gbmV3KCJBbm5vdGF0ZWREYXRhRnJhbWUiLCBhcy5kYXRhLmZyYW1lKGdlbmVfaW5mb19ueikpCmZlYXR1cmVOYW1lcyhmZWF0dXJlX2RhdGFfbnopID0gcm93bmFtZXMoYWxsX2NvdW50X21hdHJpeF9ueikKZXhwZXJpbWVudF9ueiA9IG5ldygiRXhwcmVzc2lvblNldCIsIGV4cHJzPWFsbF9jb3VudF9tYXRyaXhfbnosCiAgICBwaGVub0RhdGE9bWV0YWRhdGFfbnosIGZlYXR1cmVEYXRhPWZlYXR1cmVfZGF0YV9ueikKIyMgcHJpbnQgc29tZSBpbmZvcm1hdGlvbiB0byBzZWUgdGhhdCBpdCB3b3JrZWQKcHJpbnQoZXhwZXJpbWVudF9ueikKc3VtbWFyeShleHBycyhleHBlcmltZW50X256KSkKaGVhZChmRGF0YShleHBlcmltZW50X256KSkKaGVhZChwRGF0YShleHBlcmltZW50X256KSkKZGltKGZEYXRhKGV4cGVyaW1lbnRfbnopKQoKcmF3X2RhdGFfbnogPSBleHBycyhleHBlcmltZW50X256KQp3cml0ZV94bHMocmF3X2RhdGFfbnosICJyYXdfZGF0YSIsIGZpbGU9ImV4Y2VsL256MTMxX2RhdGFfdjAueGxzIikKYGBgCgojIyBHcmFwaCBtZXRyaWNzCgpgYGB7ciBncmFwaF9tZXRyaWNzX256LCBldmFsPUZBTFNFfQphbGxfZXhwdF9ueiA9IGV4cHRfc3Vic2V0KGV4cGVyaW1lbnRfbnosICIiKQpoZWFkKGV4cHJzKGFsbF9leHB0X256JGV4cHJlc3Npb25zZXQpKQoKYWxsX3FycGttX256ID0gbXlfbm9ybShleHB0PWFsbF9leHB0X256LCBub3JtPSJxdWFudCIsIGZpbHRlcj0ibG9nMiIsIGZpbHRlcl9sb3c9RkFMU0UsIG91dF90eXBlPSJycGttIiwgYW5ub3RhdGlvbnM9YW5ub3RhdGlvbl9pbmZvX256KSRjb3VudHMKd3JpdGVfeGxzKGFsbF9xcnBrbV9ueiwgIm5vcm1fZGF0YSIsIGZpbGU9ImV4Y2VsL256MTMxX2RhdGFfdjAueGxzIiwgcm93bmFtZT0icm93Lm5hbWVzIikKYWxsX25vcm1fZXhwdF9ueiA9IGFsbF9leHB0X256CiMjIEkgZGlkIHRoYXQgc28gdGhhdCBJIGNhbiByZXBsYWNlIHRoZSBleHByZXNzaW9uc2V0IHdpdGggdGhlCiMjIG5vcm1hbGl6ZWQgZGF0YSBtb3JlIGVhc2lseS4uLgpub3JtYWxpemVkX2V4cHJlc3Npb25zZXRfbnogPSBhbGxfbm9ybV9leHB0X256JGV4cHJlc3Npb25zZXQKZXhwcnMobm9ybWFsaXplZF9leHByZXNzaW9uc2V0X256KSA9IGFsbF9xcnBrbV9uegphbGxfbm9ybV9leHB0X256JGV4cHJlc3Npb25zZXQgPSBub3JtYWxpemVkX2V4cHJlc3Npb25zZXRfbnoKCmFsbF9kZXNpZ25fbnogPSBkYXRhLmZyYW1lKGFsbF9ub3JtX2V4cHRfbnokZGVzaWduKQphbGxfZGVzaWduX256JGxvbmduYW1lcyA9IHBhc3RlKGFsbF9kZXNpZ25fbnokc3RyYWluLCAgYWxsX2Rlc2lnbl9ueiRiYXRjaCwgYWxsX2Rlc2lnbl9ueiRjb25kaXRpb24sIHNlcD0iXyIpCgpteV9ib3hwbG90KGV4cHQ9YWxsX25vcm1fZXhwdF9ueiwgbmFtZXM9YWxsX2Rlc2lnbl9ueiRsb25nbmFtZXMpCm15X2Rpc2hlYXQoZXhwdD1hbGxfbm9ybV9leHB0X256LCBuYW1lcz1hbGxfZGVzaWduX256JGxvbmduYW1lcykKbXlfY29yaGVhdChleHB0PWFsbF9ub3JtX2V4cHRfbnosIG5hbWVzPWFsbF9kZXNpZ25fbnokbG9uZ25hbWVzKQoKY29ycmVsYXRpb25zX256ID0gbXlfY29yKGV4cHJzKGFsbF9leHB0X256JGV4cHJlc3Npb25zZXQpLCBtZXRob2Q9InNwZWFybWFuIikKd3JpdGVfeGxzKGNvcnJlbGF0aW9uc19ueiwgInNwX2NvciIsIGZpbGU9ImV4Y2VsL256MTMxX2RhdGFfdjAueGxzIikKYGBgCgojIyBHZXQgY29tcGFyaXNvbnMgZm9yIFlvYW5uCgpgYGB7ciBnYXNfbnoxMzFfc2NhdHRlcnBsb3RzX256LCBldmFsPUZBTFNFfQojIyBDb21wYXJlIGxpYnJhcnkgdDAgdDEKY29tcF9ueiA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfbnosICJjb25kaXRpb249PSd0MCd8Y29uZGl0aW9uPT0ndDEnIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvbnoxMzEvdDBfdnNfdDFfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfbnosIGNvcm1ldGhvZD0ic3BlYXJtYW4iKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CiMjIENvbXBhcmUgbGlicmFyeSB0MCB0Mgpjb21wX256ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF9ueiwgImNvbmRpdGlvbj09J3QwJ3xjb25kaXRpb249PSd0MiciKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9uejEzMS90MF92c190Ml9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF9ueiwgY29ybWV0aG9kPSJzcGVhcm1hbiIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKIyMgQ29tcGFyZSBsaWJyYXJ5IHQwIHQzCmNvbXBfbnogPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0X256LCAiY29uZGl0aW9uPT0ndDAnfGNvbmRpdGlvbj09J3QzJyIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL256MTMxL3QwX3ZzX3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wX256LCBjb3JtZXRob2Q9InNwZWFybWFuIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQojIyBDb21wYXJlIGxpYnJhcnkgdDEgdDIKY29tcF9ueiA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfbnosICJjb25kaXRpb249PSd0MSd8Y29uZGl0aW9uPT0ndDInIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvbnoxMzEvdDFfdnNfdDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfbnosIGNvcm1ldGhvZD0ic3BlYXJtYW4iKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CiMjIENvbXBhcmUgbGlicmFyeSB0MSB0Mwpjb21wX256ID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF9ueiwgImNvbmRpdGlvbj09J3QxJ3xjb25kaXRpb249PSd0MyciKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9uejEzMS90MV92c190M19zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF9ueiwgY29ybWV0aG9kPSJzcGVhcm1hbiIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKIyMgQ29tcGFyZSBsaWJyYXJ5IHQyIHQzCmNvbXBfbnogPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0X256LCAiY29uZGl0aW9uPT0ndDInfGNvbmRpdGlvbj09J3QzJyIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL256MTMxL3QyX3ZzX3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wX256LCBjb3JtZXRob2Q9InNwZWFybWFuIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQpgYGAKCiMgQWxhYmFtYQoKIyMgR2Vub21lIGFubm90YXRpb24gaW5wdXQKCmBgYHtyIGRhdGFfaW5wdXRfZ2Vub21lX2FsYTEzMSwgZXZhbD1GQUxTRX0KYW5ub3RhdGlvbnNfYWxhID0gaW1wb3J0LmdmZjMoInJlZmVyZW5jZS9nZW5iYW5rL21nYXNfYWxhYmFtYS5nZmYiLCBhc1JhbmdlZERhdGE9RkFMU0UpCmFubm90YXRpb25faW5mb19hbGEgPSBhcy5kYXRhLmZyYW1lKGFubm90YXRpb25zX2FsYSkKcm93bmFtZXMoYW5ub3RhdGlvbl9pbmZvX2FsYSkgPSBtYWtlLm5hbWVzKGFubm90YXRpb25zX2FsYSRsb2N1c190YWcsIHVuaXF1ZT1UUlVFKQpnZW5lc19hbGEgPSBhbm5vdGF0aW9uX2luZm9fYWxhW2Fubm90YXRpb25faW5mb19hbGEkdHlwZT09ImdlbmUiLF0KZ2VuZV9hbm5vdGF0aW9uc19hbGEgPSBzdWJzZXQoZ2VuZXNfYWxhLCBzZWxlY3QgPSBjKCJzdGFydCIsICJlbmQiLCAid2lkdGgiLCAic3RyYW5kIiwgImdlbmUiLCAibG9jdXNfdGFnIikpCnNob3J0X2Fubm90YXRpb25zX2FsYSA9IGdlbmVfYW5ub3RhdGlvbnNfYWxhWyxjKCJnZW5lIiwgImxvY3VzX3RhZyIpXQp3cml0ZV94bHMoZ2VuZV9hbm5vdGF0aW9uc19hbGEsICJhbm5vdGF0aW9ucyIsIHJvd25hbWU9IklEIiwgZmlsZT0iZXhjZWwvYWxhYmFtYV9kYXRhX3YwLnhscyIpCgojI21pY3JvYmVzX2FsYSA9IHJlYWQuY3N2KGZpbGU9InJlZmVyZW5jZS9taWNyb2Jlc29ubGluZS9hbGFiYW1hX2Fubm90YXRpb25zLnRhYi5neiIsIGhlYWRlcj0xLCBzZXA9Ilx0IikKIyNtaWNyb2Jlc19nb19hbGEgPSBtaWNyb2Jlc19hbGFbLGMoInN5c05hbWUiLCJHTyIpXQojI2dvX2VudHJpZXNfYWxhID0gc3Ryc3BsaXQoYXMuY2hhcmFjdGVyKG1pY3JvYmVzX2dvX2FsYSRHTyksIHNwbGl0PSIsIiwgcGVybD1UUlVFKQojI21pY3JvYmVzX2dvX29uZXBlcnJvd19hbGEgPSBkYXRhLmZyYW1lKG5hbWUgPSByZXAobWljcm9iZXNfZ29fYWxhJHN5c05hbWUsIHNhcHBseShnb19lbnRyaWVzX2FsYSwgbGVuZ3RoKSksIEdPID0gdW5saXN0KGdvX2VudHJpZXNfYWxhKSkKIyNtaWNyb2Jlc19nb19hbGEgPSBtaWNyb2Jlc19nb19vbmVwZXJyb3dfYWxhCiMjcm0obWljcm9iZXNfZ29fb25lcGVycm93X2FsYSkKIyNybShnb19lbnRyaWVzX2FsYSkKIyMgVGhlc2UgYXJlIHVzZWQgZm9yIGdlbmUgb250b2xvZ3kgc3R1ZmYuLi4KIyNtaWNyb2Jlc19sZW5ndGhzX2FsYSA9IG1pY3JvYmVzX2FsYVssYygic3lzTmFtZSIsICJzdGFydCIsInN0b3AiKV0KIyNtaWNyb2Jlc19sZW5ndGhzX2FsYSRsZW5ndGggPSBhYnMobWljcm9iZXNfYWxhJHN0YXJ0IC0gbWljcm9iZXNfYWxhJHN0b3ApCiMjbWljcm9iZXNfbGVuZ3Roc19hbGEgPSBtaWNyb2Jlc19sZW5ndGhzX2FsYVssYygic3lzTmFtZSIsImxlbmd0aCIpXQpgYGAKCiMjIyBNYWtlIHRvb2x0aXBzIGZvciBpbnRlcmFjdGl2ZSBncmFwaHMKCmBgYHtyIHRvb2x0aXBfZGF0YV9hbGEsIGV2YWw9RkFMU0V9CnRvb2x0aXBfZGF0YV9hbGEgPSBhbm5vdGF0aW9uX2luZm9fYWxhCnRvb2x0aXBfZGF0YV9hbGEgPSB0b29sdGlwX2RhdGFfYWxhWyxjKCJnZW5lIiwgImxvY3VzX3RhZyIpXQp0b29sdGlwX2RhdGFfYWxhJHRvb2x0aXAgPSBwYXN0ZSh0b29sdGlwX2RhdGFfYWxhJGdlbmUsIHRvb2x0aXBfZGF0YV9hbGEkbG9jdXNfdGFnLCBzZXA9IjogIikKdG9vbHRpcF9kYXRhX2FsYSR0b29sdGlwID0gZ3N1YigiXFwrIiwgIiAiLCB0b29sdGlwX2RhdGFfYWxhJHRvb2x0aXApCmhlYWQodG9vbHRpcF9kYXRhX2FsYSkKYGBgCgojIyMgU2V0IHVwIHRoZSBleHBlcmltZW50YWwgZGVzaWduCgpgYGB7ciBleHBlcmltZW50YWxfZGVzaWduX2FsYSwgZXZhbD1GQUxTRX0KIyMgVGhlIGFsbF9zYW1wbGVzLmNzdiBjb250cm9scyB0aGUgZXhwZXJpbWVudGFsIHNldHRpbmdzCiMjIGFsbCB0aGUgZm9sbG93aW5nIGxpbmVzIG1hbmlwdWxhdGUgdGhlIGluZm9ybWF0aW9uIHRoZXJlaW4KIyMgaW4gb3JkZXIgdG8gc2V0IHVwIG1lZGlhIHR5cGVzLCByZXBsaWNhdGVzLCBldGMKc2FtcGxlX2RlZmluaXRpb25zX2FsYSA9IHJlYWQuY3N2KGZpbGU9ImFsbF9zYW1wbGVzX2FsYWJhbWFfdjAuY3N2Iiwgc2VwPSIsIikKIyMgSWYgSSBoYXZlIHN1bW1hcnkgbGluZXMgaW4gdGhlIGNzdiwgdGhleSB3aWxsIG5vdCBzdGFydCB3aXRoICdIUEdMJyBhbmQgc28gc2hvdWxkIGJlIGRyb3BwZWQuCnNhbXBsZV9kZWZpbml0aW9uc19hbGEgPSBzYW1wbGVfZGVmaW5pdGlvbnNfYWxhW2dyZXBsKCdeSFBHTCcsIHNhbXBsZV9kZWZpbml0aW9uc19hbGEkU2FtcGxlLklELCBwZXJsPVRSVUUpLF0KIyMgUHJlIHNldCB0aGUgY29sb3Igc2NoZW1lCnNhbXBsZV9kZWZpbml0aW9uc19hbGEkY29sb3JzID0gbGlicmFyeV9jb2xvcnMKIyMgVGhpcyBsb25nIHN0YXRlbWVudCBqdXN0IHdyaXRlcyBvdXQgYSBjb21wdXRlciBwYXRoIG5hbWUgY29udGFpbmluZyB0aGUgY291bnQgZmlsZXMgdG8gcmVhZCBieSBzYW1wbGUgbmFtZS4Kc2FtcGxlX2RlZmluaXRpb25zX2FsYSRjb3VudHMgPSBwYXN0ZSgiZGF0YS9jb3VudF90YWJsZXMvMDV2ME0xbDIwZ2VuXyIsICJhbGFiNDkiLCAiXyIsIHNhbXBsZV9kZWZpbml0aW9uc19hbGEkVGltZSwgIl9nZW5vbWUuY291bnQuZ3oiLCBzZXA9IiIpCnNhbXBsZV9kZWZpbml0aW9uc19hbGEgPSBhcy5kYXRhLmZyYW1lKHNhbXBsZV9kZWZpbml0aW9uc19hbGEpCnJvd25hbWVzKHNhbXBsZV9kZWZpbml0aW9uc19hbGEpID0gc2FtcGxlX2RlZmluaXRpb25zX2FsYSRTYW1wbGUuSUQKIyMgbXlfcmVhZF9maWxlcyBkb2VzIGp1c3QgdGhhdCwgaXQgcmVhZHMgdGhlIGNvdW50IHRhYmxlcyBhbmQgbWFrZXMgYSBsYXJnZSByYXcgY291bnQgdGFibGUgZnJvbSB0aGVtLgphbGxfY291bnRfdGFibGVzX2FsYSA9IG15X3JlYWRfZmlsZXMoYXMuY2hhcmFjdGVyKHNhbXBsZV9kZWZpbml0aW9uc19hbGEkU2FtcGxlLklEKSwgYXMuY2hhcmFjdGVyKHNhbXBsZV9kZWZpbml0aW9uc19hbGEkY291bnRzKSkKIyMgbWFrZSBpdCBpbnRvIGEgbWF0cml4IGZvciB1c2UgYXMgYW4gZXhwcmVzc2lvbnNldAphbGxfY291bnRfbWF0cml4X2FsYSA9IGFzLm1hdHJpeChhbGxfY291bnRfdGFibGVzX2FsYSkKCmdlbmVfaW5mb19hbGEgPSBhbGxfY291bnRfbWF0cml4X2FsYVtyb3duYW1lcyhhbGxfY291bnRfbWF0cml4X2FsYSkgJWluJSBhbm5vdGF0aW9uc19hbGEkbG9jdXNfdGFnLF0KYWxsX2NvdW50X21hdHJpeF9hbGEgPSBhbGxfY291bnRfbWF0cml4X2FsYVtyb3duYW1lcyhhbGxfY291bnRfbWF0cml4X2FsYSkgJWluJSBhbm5vdGF0aW9uc19hbGEkbG9jdXNfdGFnLF0KbWV0YWRhdGFfYWxhID0gbmV3KCJBbm5vdGF0ZWREYXRhRnJhbWUiLCBkYXRhLmZyYW1lKHNhbXBsZT1zYW1wbGVfZGVmaW5pdGlvbnNfYWxhJFNhbXBsZS5JRCwKICAgIGNvbmRpdGlvbj1zYW1wbGVfZGVmaW5pdGlvbnNfYWxhJFRpbWUsCiAgICBiYXRjaD1zYW1wbGVfZGVmaW5pdGlvbnNfYWxhJExpYnJhcnksCiAgICBzdHJhaW49c2FtcGxlX2RlZmluaXRpb25zX2FsYSRTdHJhaW4sCiAgICBjb2xvcj1hcy5jaGFyYWN0ZXIoc2FtcGxlX2RlZmluaXRpb25zX2FsYSRjb2xvcnMpLAogICAgY291bnRzPXNhbXBsZV9kZWZpbml0aW9uc19hbGEkY291bnRzKSkKCiMjIE5vdyBnZW5lcmF0ZSB0aGUgZXhwcmVzc2lvbnNldCBvYmplY3QKc2FtcGxlTmFtZXMobWV0YWRhdGFfYWxhKSA9IGNvbG5hbWVzKGFsbF9jb3VudF9tYXRyaXhfYWxhKQpmZWF0dXJlX2RhdGFfYWxhID0gbmV3KCJBbm5vdGF0ZWREYXRhRnJhbWUiLCBhcy5kYXRhLmZyYW1lKGdlbmVfaW5mb19hbGEpKQpmZWF0dXJlTmFtZXMoZmVhdHVyZV9kYXRhX2FsYSkgPSByb3duYW1lcyhhbGxfY291bnRfbWF0cml4X2FsYSkKZXhwZXJpbWVudF9hbGEgPSBuZXcoIkV4cHJlc3Npb25TZXQiLCBleHBycz1hbGxfY291bnRfbWF0cml4X2FsYSwKICAgIHBoZW5vRGF0YT1tZXRhZGF0YV9hbGEsIGZlYXR1cmVEYXRhPWZlYXR1cmVfZGF0YV9hbGEpCiMjIHByaW50IHNvbWUgaW5mb3JtYXRpb24gdG8gc2VlIHRoYXQgaXQgd29ya2VkCnByaW50KGV4cGVyaW1lbnRfYWxhKQpzdW1tYXJ5KGV4cHJzKGV4cGVyaW1lbnRfYWxhKSkKaGVhZChmRGF0YShleHBlcmltZW50X2FsYSkpCmhlYWQocERhdGEoZXhwZXJpbWVudF9hbGEpKQpkaW0oZkRhdGEoZXhwZXJpbWVudF9hbGEpKQoKcmF3X2RhdGFfYWxhID0gZXhwcnMoZXhwZXJpbWVudF9hbGEpCndyaXRlX3hscyhyYXdfZGF0YV9hbGEsICJyYXdfZGF0YSIsIGZpbGU9ImV4Y2VsL2FsYWJhbWFfZGF0YV92MC54bHMiKQpgYGAKCiMjIEdyYXBoIG1ldHJpY3MKCmBgYHtyIGdyYXBoX21ldHJpY3NfYWxhLCBldmFsPUZBTFNFfQphbGxfZXhwdF9hbGEgPSBleHB0X3N1YnNldChleHBlcmltZW50X2FsYSwgIiIpCmhlYWQoZXhwcnMoYWxsX2V4cHRfYWxhJGV4cHJlc3Npb25zZXQpKQoKYWxsX3FycGttX2FsYSA9IG15X25vcm0oZXhwdD1hbGxfZXhwdF9hbGEsIG5vcm09InF1YW50IiwgZmlsdGVyPSJsb2cyIiwgZmlsdGVyX2xvdz1GQUxTRSwgb3V0X3R5cGU9InJwa20iLCBhbm5vdGF0aW9ucz1hbm5vdGF0aW9uX2luZm9fYWxhKSRjb3VudHMKd3JpdGVfeGxzKGFsbF9xcnBrbV9hbGEsICJub3JtX2RhdGEiLCBmaWxlPSJleGNlbC9hbGFiYW1hX2RhdGFfdjAueGxzIiwgcm93bmFtZT0icm93Lm5hbWVzIikKYWxsX25vcm1fZXhwdF9hbGEgPSBhbGxfZXhwdF9hbGEKIyMgSSBkaWQgdGhhdCBzbyB0aGF0IEkgY2FuIHJlcGxhY2UgdGhlIGV4cHJlc3Npb25zZXQgd2l0aCB0aGUKIyMgbm9ybWFsaXplZCBkYXRhIG1vcmUgZWFzaWx5Li4uCm5vcm1hbGl6ZWRfZXhwcmVzc2lvbnNldF9hbGEgPSBhbGxfbm9ybV9leHB0X2FsYSRleHByZXNzaW9uc2V0CmV4cHJzKG5vcm1hbGl6ZWRfZXhwcmVzc2lvbnNldF9hbGEpID0gYWxsX3FycGttX2FsYQphbGxfbm9ybV9leHB0X2FsYSRleHByZXNzaW9uc2V0ID0gbm9ybWFsaXplZF9leHByZXNzaW9uc2V0X2FsYQoKYWxsX2Rlc2lnbl9hbGEgPSBkYXRhLmZyYW1lKGFsbF9ub3JtX2V4cHRfYWxhJGRlc2lnbikKYWxsX2Rlc2lnbl9hbGEkbG9uZ25hbWVzID0gcGFzdGUoYWxsX2Rlc2lnbl9hbGEkc3RyYWluLCAgYWxsX2Rlc2lnbl9hbGEkYmF0Y2gsIGFsbF9kZXNpZ25fYWxhJGNvbmRpdGlvbiwgc2VwPSJfIikKCm15X2JveHBsb3QoZXhwdD1hbGxfbm9ybV9leHB0X2FsYSwgbmFtZXM9YWxsX2Rlc2lnbl9hbGEkbG9uZ25hbWVzKQpteV9kaXNoZWF0KGV4cHQ9YWxsX25vcm1fZXhwdF9hbGEsIG5hbWVzPWFsbF9kZXNpZ25fYWxhJGxvbmduYW1lcykKbXlfY29yaGVhdChleHB0PWFsbF9ub3JtX2V4cHRfYWxhLCBuYW1lcz1hbGxfZGVzaWduX2FsYSRsb25nbmFtZXMpCgpjb3JyZWxhdGlvbnNfYWxhID0gbXlfY29yKGV4cHJzKGFsbF9leHB0X2FsYSRleHByZXNzaW9uc2V0KSwgbWV0aG9kPSJzcGVhcm1hbiIpCndyaXRlX3hscyhjb3JyZWxhdGlvbnNfYWxhLCAic3BfY29yIiwgZmlsZT0iZXhjZWwvYWxhYmFtYV9kYXRhX3YwLnhscyIpCmBgYAoKIyMgR2V0IGNvbXBhcmlzb25zIGZvciBZb2FubgoKYGBge3IgZ2FzX2FsYWJhbWFfc2NhdHRlcnBsb3RzX2FsYSwgZXZhbD1GQUxTRX0KIyMgQ29tcGFyZSBsaWJyYXJ5IHQwIHQxCmNvbXBfYWxhID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF9hbGEsICJjb25kaXRpb249PSd0MCd8Y29uZGl0aW9uPT0ndDEnIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvYWxhYmFtYS90MF92c190MV9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF9hbGEsIGNvcm1ldGhvZD0ic3BlYXJtYW4iKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CiMjIENvbXBhcmUgbGlicmFyeSB0MCB0Mgpjb21wX2FsYSA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfYWxhLCAiY29uZGl0aW9uPT0ndDAnfGNvbmRpdGlvbj09J3QyJyIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2FsYWJhbWEvdDBfdnNfdDJfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfYWxhLCBjb3JtZXRob2Q9InNwZWFybWFuIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQojIyBDb21wYXJlIGxpYnJhcnkgdDAgdDMKY29tcF9hbGEgPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0X2FsYSwgImNvbmRpdGlvbj09J3QwJ3xjb25kaXRpb249PSd0MyciKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9hbGFiYW1hL3QwX3ZzX3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wX2FsYSwgY29ybWV0aG9kPSJzcGVhcm1hbiIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKIyMgQ29tcGFyZSBsaWJyYXJ5IHQxIHQyCmNvbXBfYWxhID0gZXhwcnMoZXhwdF9zdWJzZXQoYWxsX25vcm1fZXhwdF9hbGEsICJjb25kaXRpb249PSd0MSd8Y29uZGl0aW9uPT0ndDInIikkZXhwcmVzc2lvbnNldCkKcGRmKGZpbGU9ImZpZ3VyZXMvY29tcGFyaXNvbnMvYWxhYmFtYS90MV92c190Ml9zY2F0dGVyX3YwLnBkZiIpCnNjID0gbXlfbGluZWFyX3NjYXR0ZXIoY29tcF9hbGEsIGNvcm1ldGhvZD0ic3BlYXJtYW4iKQpzYyRzY2F0dGVyCnNjJHhfaGlzdG9ncmFtCnNjJHlfaGlzdG9ncmFtCnNjJGJvdGhfaGlzdG9ncmFtCmRldi5vZmYoKQpzYyRjb3JyZWxhdGlvbgpzYyRsbV9tb2RlbApzYyRsbV9zdW1tYXJ5CiMjIENvbXBhcmUgbGlicmFyeSB0MSB0Mwpjb21wX2FsYSA9IGV4cHJzKGV4cHRfc3Vic2V0KGFsbF9ub3JtX2V4cHRfYWxhLCAiY29uZGl0aW9uPT0ndDEnfGNvbmRpdGlvbj09J3QzJyIpJGV4cHJlc3Npb25zZXQpCnBkZihmaWxlPSJmaWd1cmVzL2NvbXBhcmlzb25zL2FsYWJhbWEvdDFfdnNfdDNfc2NhdHRlcl92MC5wZGYiKQpzYyA9IG15X2xpbmVhcl9zY2F0dGVyKGNvbXBfYWxhLCBjb3JtZXRob2Q9InNwZWFybWFuIikKc2Mkc2NhdHRlcgpzYyR4X2hpc3RvZ3JhbQpzYyR5X2hpc3RvZ3JhbQpzYyRib3RoX2hpc3RvZ3JhbQpkZXYub2ZmKCkKc2MkY29ycmVsYXRpb24Kc2MkbG1fbW9kZWwKc2MkbG1fc3VtbWFyeQojIyBDb21wYXJlIGxpYnJhcnkgdDIgdDMKY29tcF9hbGEgPSBleHBycyhleHB0X3N1YnNldChhbGxfbm9ybV9leHB0X2FsYSwgImNvbmRpdGlvbj09J3QyJ3xjb25kaXRpb249PSd0MyciKSRleHByZXNzaW9uc2V0KQpwZGYoZmlsZT0iZmlndXJlcy9jb21wYXJpc29ucy9hbGFiYW1hL3QyX3ZzX3QzX3NjYXR0ZXJfdjAucGRmIikKc2MgPSBteV9saW5lYXJfc2NhdHRlcihjb21wX2FsYSwgY29ybWV0aG9kPSJzcGVhcm1hbiIpCnNjJHNjYXR0ZXIKc2MkeF9oaXN0b2dyYW0Kc2MkeV9oaXN0b2dyYW0Kc2MkYm90aF9oaXN0b2dyYW0KZGV2Lm9mZigpCnNjJGNvcnJlbGF0aW9uCnNjJGxtX21vZGVsCnNjJGxtX3N1bW1hcnkKYGBgCgojIFBsYXlpbmcgd2l0aCBkaXN0cmlidXRpb24gb2YgaGl0cwoKYGBge3IgaGl0X2Rpc3RyaWJ1dGlvbiwgZXZhbD1GQUxTRX0KYWxsX3RhcyA9IHJlYWQudGFibGUoZmlsZT0iZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdGFzX3QwdjAudHh0IiwgaGVhZGVyPVRSVUUpCmFsbF90YXMgPSBhbGxfdGFzWyxjKCJTdGFydCIsICJyZWFkcyIsICJUQXMiKV0KaGVhZChhbGxfdGFzKQpieV90aG91c2FuZHMgPSBncm91cF9ieShhbGxfdGFzLCBmbG9vcihTdGFydCAvIDEwMDApKQpzZXRuYW1lcyhieV90aG91c2FuZHMsICJmbG9vcihTdGFydC8xMDAwKSIsICJ0aG91c2FuZHMiKQojIyBUaGUgbGFzdCByb3cgaXMgYnJva2VuCmJ5X3Rob3VzYW5kcyA9IGJ5X3Rob3VzYW5kc1stbnJvdyhieV90aG91c2FuZHMpLF0KYnlfdGhvdXNhbmRzID0gYWdncmVnYXRlKC4gfiB0aG91c2FuZHMsIGRhdGE9YnlfdGhvdXNhbmRzLCBGVU49c3VtKQpieV90aG91c2FuZHMgPSBhcy5kYXRhLmZyYW1lKGJ5X3Rob3VzYW5kcykKYnlfdGhvdXNhbmRzID0gYnlfdGhvdXNhbmRzWyxjKCJ0aG91c2FuZHMiLCJyZWFkcyIsICJUQXMiKV0KYnlfdGhvdXNhbmRzJGxvZ19yZWFkcyA9IGxvZzIoYnlfdGhvdXNhbmRzJHJlYWRzICsgMSkKYnlfdGhvdXNhbmRzJG5vcm0gPSBieV90aG91c2FuZHMkcmVhZHMgLyBieV90aG91c2FuZHMkVEFzCmJ5X3Rob3VzYW5kcyRsb2dfbm9ybSA9IGxvZzIoYnlfdGhvdXNhbmRzJG5vcm0gKyAxKQoKc2NhdHRlcl9kZiA9IGJ5X3Rob3VzYW5kc1ssYygidGhvdXNhbmRzIiwibG9nX3JlYWRzIildCnRob3VzYW5kc19wbG90ID0gbXlfc2NhdHRlcihzY2F0dGVyX2RmKQp0aG91c2FuZHNfcGxvdCArIHN0YXRfc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzaXplPTEuNSkKc2NhdHRlcl9kZiA9IGJ5X3Rob3VzYW5kc1ssYygidGhvdXNhbmRzIiwibG9nX25vcm0iKV0KdGhvdXNhbmRzX3Bsb3QgPSBteV9zY2F0dGVyKHNjYXR0ZXJfZGYpCnRob3VzYW5kc19wbG90ICsgc3RhdF9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNpemU9MS41KQpgYGAKCmBgYHtyIG1ha2VfY2lyY29zLCBldmFsPUZBTFNFfQptYWtlX2NpcmNvcyA9IGZ1bmN0aW9uKGNzdiwgYW5ub3RhdGlvbnM9Z2VuZV9hbm5vdGF0aW9uc181NDQ4LCBvZmZzZXQ9MCwgY2hyPSJjaHIxIikgewogICAgIyMgVGVzdGluZyBwYXJhbWV0ZXJzCiAgICAjI3dyaXRlLnRhYmxlKG1ha2VfY2lyY29zKCJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdGltZTBfZXNzZW50aWFsaXR5X20yLmNzdiIsIGdlbmVfYW5ub3RhdGlvbnNfbnopLCBmaWxlPSJjaXJjb3MvZGF0YS9lc3NlbnRpYWxpdHlfbnoxMzFfdDAudHh0IiwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSwgY29sLm5hbWVzPUZBTFNFKQogICAgI2NzdiA9ICJkYXRhL2Vzc2VudGlhbGl0eS9taF9lc3MvbnoxMzEvdDB2MF9lc3NlbnRpYWxpdHlfbTIuY3N2IgogICAgI2Fubm90YXRpb25zID0gZ2VuZV9hbm5vdGF0aW9uc19uegogICAgIyMgRW5kIHRlc3RpbmcgcGFyYW1ldGVycwogICAgZGF0YSA9IHJlYWQuY3N2KGZpbGU9Y3N2LCBzZXA9Ilx0IiwgY29tbWVudC5jaGFyPSIjIiwgaGVhZGVyPUZBTFNFKQogICAgY29sbmFtZXMoZGF0YSkgPSBjKCJnZW5lIiwib3JmX2hpdHMiLCJvcmZfdGFzIiwibWF4X3J1biIsIm1heF9ydW5fc3BhbiIsInBvc3Rlcmlvcl96YmFyIiwiY2FsbCIpCiAgICBkYXRhJGdlbmUgPSBnc3ViKCJeY2RzXyIsICIiLCBkYXRhJGdlbmUsIHBlcmw9VFJVRSkKICAgIHJvd25hbWVzKGRhdGEpID0gbWFrZS5uYW1lcyhkYXRhJGdlbmUsIHVuaXF1ZT1UUlVFKQogICAgZGF0YSA9IG1lcmdlKGRhdGEsIGFubm90YXRpb25zLCBieT0icm93Lm5hbWVzIikKICAgIGRhdGFbLCBjaHIgXSA9IGNocgogICAgZGF0YSA9IGRhdGFbLGMoY2hyLCAic3RhcnQiLCAiZW5kIiwgInBvc3Rlcmlvcl96YmFyIildCiAgICBkYXRhJHBvc3Rlcmlvcl96YmFyID0gcGFzdGUoInZhbHVlPSIsIGRhdGEkcG9zdGVyaW9yX3piYXIsIHNlcD0iIikKICAgIGRhdGEkc3RhcnQgPSBkYXRhJHN0YXJ0ICsgb2Zmc2V0CiAgICBkYXRhJGVuZCA9IGRhdGEkZW5kICsgb2Zmc2V0CiAgICByZXR1cm4oZGF0YSkKfQp3cml0ZS50YWJsZShtYWtlX2NpcmNvcygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDB2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IiwgZ2VuZV9hbm5vdGF0aW9uc181NDQ4KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5XzU0NDhfdDEudHh0IiwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSwgY29sLm5hbWVzPUZBTFNFKQp3cml0ZS50YWJsZShtYWtlX2NpcmNvcygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDF2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IiwgZ2VuZV9hbm5vdGF0aW9uc181NDQ4KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5XzU0NDhfdDEudHh0IiwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSwgY29sLm5hbWVzPUZBTFNFKQp3cml0ZS50YWJsZShtYWtlX2NpcmNvcygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDJ2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IiwgZ2VuZV9hbm5vdGF0aW9uc181NDQ4KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5XzU0NDhfdDIudHh0IiwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSwgY29sLm5hbWVzPUZBTFNFKQp3cml0ZS50YWJsZShtYWtlX2NpcmNvcygiZGF0YS9lc3NlbnRpYWxpdHkvbWhfZXNzLzU0NDgvdDN2MF9lc3NlbnRpYWxpdHlfbTQuY3N2IiwgZ2VuZV9hbm5vdGF0aW9uc181NDQ4KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5XzU0NDhfdDMudHh0IiwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSwgY29sLm5hbWVzPUZBTFNFKQoKd3JpdGUudGFibGUobWFrZV9jaXJjb3MoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MHYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiLCBnZW5lX2Fubm90YXRpb25zX256KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5X256MTMxX3QwLnR4dCIsIHF1b3RlPUZBTFNFLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKd3JpdGUudGFibGUobWFrZV9jaXJjb3MoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MXYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiLCBnZW5lX2Fubm90YXRpb25zX256KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5X256MTMxX3QxLnR4dCIsIHF1b3RlPUZBTFNFLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKd3JpdGUudGFibGUobWFrZV9jaXJjb3MoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90MnYwX2Vzc2VudGlhbGl0eV9tMi5jc3YiLCBnZW5lX2Fubm90YXRpb25zX256KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5X256MTMxX3QyLnR4dCIsIHF1b3RlPUZBTFNFLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKd3JpdGUudGFibGUobWFrZV9jaXJjb3MoImRhdGEvZXNzZW50aWFsaXR5L21oX2Vzcy9uejEzMS90M3YwX2Vzc2VudGlhbGl0eV9tMi5jc3YiLCBnZW5lX2Fubm90YXRpb25zX256KSwgZmlsZT0iY2lyY29zL2RhdGEvZXNzZW50aWFsaXR5X256MTMxX3QzLnR4dCIsIHF1b3RlPUZBTFNFLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKCmdhc19wbHVzID0gcmVhZC50YWJsZShmaWxlPSJjaXJjb3MvZGF0YS9nYXNfcGx1cy50eHQiKQpuejEzMV9wbHVzID0gcmVhZC50YWJsZShmaWxlPSJjaXJjb3MvZGF0YS9uejEzMV9wbHVzLnR4dCIpCmdhc19taW51cyA9IHJlYWQudGFibGUoZmlsZT0iY2lyY29zL2RhdGEvZ2FzX21pbnVzLnR4dCIpCm56MTMxX21pbnVzID0gcmVhZC50YWJsZShmaWxlPSJjaXJjb3MvZGF0YS9uejEzMV9taW51cy50eHQiKQoKbnoxMzFfcGx1c19vZmZzZXQgPSBuejEzMV9wbHVzCmNvbG5hbWVzKG56MTMxX3BsdXNfb2Zmc2V0KSA9IGMoImNociIsInN0YXJ0IiwiZW5kIiwidmFsdWUiKQpuejEzMV9wbHVzX29mZnNldCRjaHIgPSAiY2hyMiIKbnoxMzFfbWludXNfb2Zmc2V0ID0gbnoxMzFfbWludXMKY29sbmFtZXMobnoxMzFfbWludXNfb2Zmc2V0KSA9IGMoImNociIsInN0YXJ0IiwiZW5kIiwidmFsdWUiKQpuejEzMV9taW51c19vZmZzZXQkY2hyID0gImNocjIiCndyaXRlLnRhYmxlKG56MTMxX3BsdXNfb2Zmc2V0LCBmaWxlPSJjaXJjb3MvZGF0YS9uejEzMV9vZmZzZXRfcGx1cy50eHQiLCBxdW90ZT1GQUxTRSwgcm93Lm5hbWVzPUZBTFNFLCBjb2wubmFtZXM9RkFMU0UpCndyaXRlLnRhYmxlKG56MTMxX21pbnVzX29mZnNldCwgZmlsZT0iY2lyY29zL2RhdGEvbnoxMzFfb2Zmc2V0X21pbnVzLnR4dCIsIHF1b3RlPUZBTFNFLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKCmVzc2VudGlhbF9jcm9zcyA9IHJlYWQuY3N2KGZpbGU9InJlZmVyZW5jZS9jb3JlX2dlbm9tZS9yZWR1Y2VkLmNzdiIpCmhlYWQoZ2VuZV9hbm5vdGF0aW9uc181NDQ4KQpoZWFkKGdlbmVfYW5ub3RhdGlvbnNfbnopCmRpbShlc3NlbnRpYWxfY3Jvc3MpCmVzc2VudGlhbF9jcm9zcyRTcHlfNTQ0OCA9IGdzdWIoIl9TcHlfIiwgIl9TcHkiLCBlc3NlbnRpYWxfY3Jvc3MkU3B5XzU0NDgpCmVzc2VudGlhbF9jcm9zcyA9IG1lcmdlKGVzc2VudGlhbF9jcm9zcywgZ2VuZV9hbm5vdGF0aW9uc181NDQ4LCBieS54PSJTcHlfNTQ0OCIsIGJ5Lnk9InJvdy5uYW1lcyIsIGFsbC54PVRSVUUpCmVzc2VudGlhbF9jcm9zcyA9IGVzc2VudGlhbF9jcm9zc1ssYygiU3B5XzU0NDgiLCJTdGF0ZV81NDQ4IiwiU3B5X05aMTMxIiwiU3RhdGVfTloxMzEiLCJzdGFydCIsImVuZCIpXQpzZXRuYW1lcyhlc3NlbnRpYWxfY3Jvc3MsICJzdGFydCIsICI1NDQ4X3N0YXJ0IikKc2V0bmFtZXMoZXNzZW50aWFsX2Nyb3NzLCAiZW5kIiwgIjU0NDhfZW5kIikKZXNzZW50aWFsX2Nyb3NzID0gbWVyZ2UoZXNzZW50aWFsX2Nyb3NzLCBnZW5lX2Fubm90YXRpb25zX256LCBieS54PSJTcHlfTloxMzEiLCBieS55PSJyb3cubmFtZXMiLCBhbGwueD1UUlVFKQplc3NlbnRpYWxfY3Jvc3MgPSBlc3NlbnRpYWxfY3Jvc3NbLGMoIlNweV81NDQ4IiwiU3RhdGVfNTQ0OCIsIlNweV9OWjEzMSIsIlN0YXRlX05aMTMxIiwiNTQ0OF9zdGFydCIsIjU0NDhfZW5kIiwic3RhcnQiLCJlbmQiKV0Kc2V0bmFtZXMoZXNzZW50aWFsX2Nyb3NzLCAic3RhcnQiLCAibnoxMzFfc3RhcnQiKQpzZXRuYW1lcyhlc3NlbnRpYWxfY3Jvc3MsICJlbmQiLCAibnoxMzFfZW5kIikKZXNzZW50aWFsX2Nyb3NzID0gZXNzZW50aWFsX2Nyb3NzW2NvbXBsZXRlLmNhc2VzKGVzc2VudGlhbF9jcm9zcyksXQoKcHJpbnRfYXJjID0gZnVuY3Rpb24oeCkgewogICAgY2F0KHhbNV0sICIgY2hyMSAiLCB4WzFdLCAiICIsIHhbMl0sICJcbiIsIHhbNV0sICIgY2hyMiAiLCB4WzNdLCAiICIsIHhbNF0sICJcblxuIiwgZmlsZT0iY2lyY29zL2RhdGEvNTQ0OF9uejEzMV9hcmNzLnR4dCIsIGFwcGVuZD1UUlVFLCBzZXA9IiIpCn0KCmFwcGx5KGVzc2VudGlhbF9jcm9zc1ssYygiNTQ0OF9zdGFydCIsIjU0NDhfZW5kIiwibnoxMzFfc3RhcnQiLCJuejEzMV9lbmQiLCJTcHlfNTQ0OCIpXSwgMSwgcHJpbnRfYXJjKQpgYGAKCgpgYGB7ciBzYXZlbWV9CmlmICghaXNUUlVFKGdldDAoInNraXBfbG9hZCIpKSkgewogIHBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCiAgbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCiAgdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKICBtZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHRoaXNfc2F2ZSkpCiAgdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZT10aGlzX3NhdmUpKQp9CmBgYAo=