index.html 01_annotation.html 02_sample_estimations.html 03_differential_expression.html

1 Gene Ontology searches

Lets set up some simple data sets for goseq/clusterProfiler/topGO

I think a bunch of the material in this sheet is actually now obsolete.

1.1 Preparing to use goseq

I need a couple vectors before being able to use goseq I also need some rda files generated for clusterProfiler and topGO but I will do those later…

## goseq uses the gene lengths, clusterprofiler and topgo don't
## gene_lengths <- all_genes[,c("geneid","genesize")]
## colnames(gene_lengths) <- c("ID", "width")
colnames(all_lengths) <- c("ID", "width")
## go_ids needs to be a 2 column data frame with names 'ID', 'GO' which are
## gene names and GO names respectively.  I actually think I made my goseq() function
## smart enough that this is no longer needed, but nonetheless.

## go_ids <- read.table("reference/go/tcruzi_all_go.tab.gz", header=0, sep="\t")
## colnames(go_ids) <- c("ID","GO","ontology","term","source")
## Since there are multiple sources, I am doing a unique of the table...
## go_ids <- unique(go_ids[,c("ID","GO")])
## goid_file <- "reference/go/topgo_goids.tab.gz"

all_go <- as.data.frame(all_go)
all_go <- all_go[, c("GID", "GO")]
sig <- clbr_times_sigfilt$limma$ups$CLBr.Tryp_vs_CLBr.A96
clbr_up_a96tryp_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/clbr_up_a96tryp_goseq-v", ver, ".xlsx")))
clbr_up_a96tryp_goseq$pvalue_plots$bpp_plot_over

sig <- clbr_times_sigfilt$limma$downs$CLBr.Tryp_vs_CLBr.A96
clbr_down_a96tryp_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/clbr_down_a96tryp_goseq-v", ver, ".xlsx")))

clbr_down_a96tryp_goseq$pvalue_plots$bpp_plot_over

sig <- clbr_times_sigfilt$limma$ups$CLBr.A96_vs_CLBr.A60
clbr_up_a60a96_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/clbr_up_a60a96_goseq-v", ver, ".xlsx")))

clbr_up_a60a96_goseq$pvalue_plots$bpp_plot_over

sig <- clbr_times_sigfilt$limma$downs$CLBr.A96_vs_CLBr.A60
clbr_down_a60a96_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/clbr_down_a60a96_goseq-v", ver, ".xlsx")))

clbr_down_a60a96_goseq$pvalue_plots$bpp_plot_over

sig <- clbr_times_sigfilt$limma$ups$CLBr.A60_vs_CLBr.Tryp
clbr_up_trypa60_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/clbr_up_trypa60_goseq-v", ver, ".xlsx")))

clbr_up_trypa60_goseq$pvalue_plots$bpp_plot_over

sig <- clbr_times_sigfilt$limma$downs$CLBr.A60_vs_CLBr.Tryp
clbr_down_trypa60_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/clbr_down_trypa60_goseq-v", ver, ".xlsx")))

clbr_down_trypa60_goseq$pvalue_plots$bpp_plot_over

sig <- cl14_times_sigfilt$limma$ups$CL14.Tryp_vs_CL14.A96
cl14_up_a96tryp_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/cl14_up_a96tryp_goseq-v", ver, ".xlsx")))

cl14_up_a96tryp_goseq$pvalue_plots$bpp_plot_over

sig <- cl14_times_sigfilt$limma$downs$CL14.Tryp_vs_CL14.A96
cl14_down_a96tryp_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/cl14_down_a96tryp_goseq-v", ver, ".xlsx")))

cl14_down_a96tryp_goseq$pvalue_plots$bpp_plot_over

sig <- cl14_times_sigfilt$limma$ups$CL14.A96_vs_CL14.A60
cl14_up_a60a96_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/cl14_up_a60a96_goseq-v", ver, ".xlsx")))

cl14_up_a60a96_goseq$pvalue_plots$bpp_plot_over

sig <- cl14_times_sigfilt$limma$downs$CL14.A96_vs_CL14.A60
cl14_down_a60a96_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/cl14_down_a60a96_goseq-v", ver, ".xlsx")))

cl14_down_a60a96_goseq$pvalue_plots$bpp_plot_over

sig <- cl14_times_sigfilt$limma$ups$CL14.A60_vs_CL14.Tryp
cl14_up_trypa60_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/cl14_up_trypa60_goseq-v", ver, ".xlsx")))

cl14_up_trypa60_goseq$pvalue_plots$bpp_plot_over

sig <- cl14_times_sigfilt$limma$downs$CL14.A60_vs_CL14.Tryp
cl14_down_trypa60_goseq <- sm(simple_goseq(
  sig_genes=sig,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/cl14_down_trypa60_goseq-v", ver, ".xlsx")))

cl14_down_trypa60_goseq$pvalue_plots$bpp_plot_over

strains_up_a60_goseq <- sm(simple_goseq(
  sig_genes=strains_sigfilt$limma$ups$CLBr.A60_vs_CL14.A60,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/strains_upa60_goseq-v", ver, ".xlsx")))

strains_up_a96_goseq <- sm(simple_goseq(
  sig_genes=strains_sigfilt$limma$ups$CLBr.A96_vs_CL14.A96,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/strains_upa96_goseq-v", ver, ".xlsx")))

strains_up_tryp_goseq <- sm(simple_goseq(
  sig_genes=strains_sigfilt$limma$ups$CLBr.Tryp_vs_CL14.Tryp,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/strains_uptryp_goseq-v", ver, ".xlsx")))

strains_down_a60_goseq <- sm(simple_goseq(
  sig_genes=strains_sigfilt$limma$downs$CLBr.A60_vs_CL14.A60,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/strains_downa60_goseq-v", ver, ".xlsx")))

strains_down_a96_goseq <- sm(simple_goseq(
  sig_genes=strains_sigfilt$limma$downs$CLBr.A96_vs_CL14.A96,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/strains_downa96_goseq-v", ver, ".xlsx")))

strains_down_tryp_goseq <- sm(simple_goseq(
  sig_genes=strains_sigfilt$limma$downs$CLBr.Tryp_vs_CL14.Tryp,
  go_db=all_go,
  length_db=all_lengths,
  excel=paste0("excel/strains_downtryp_goseq-v", ver, ".xlsx")))

1.2 Compare Epimastigotes between CL14 and CLBr, high expression

One important note here, I needed to modify the data structure from readGff() in clusterProfiler before it was able to successfully generate the file ‘geneTable.rda’ Unfortunately, I was watching a movie at the time and didn’t properly write down what I did. However, I did write it out in the function myr::Gff2GeneTable() but in order to make it work one must load readGff() from clusterProfiler. I think the real solution is for me to grab a version of readGff() from clusterProfiler and make it exportable so that it will work consistently.

## Changes in epimastigotes from CLBrener to CL14
pval_thresh <- 0.0001
epi_cl14clbr_table <- all_tables$epi_cl14clbr
epi_cl14clbr_summary <- summary(epi_cl14clbr_table$logFC)
epi_cl14clbr_pvals <- epi_cl14clbr_table$adj.P.Val
names(epi_cl14clbr_pvals) <- rownames(epi_cl14clbr_table)
## Extract the genes with high expression in CL14 compared to Brener and very low pvalues
epi_cl14clbr_high <- subset(epi_cl14clbr_table, logFC >= epi_cl14clbr_summary[5] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the high genes
epi_cl14clbr_high_go <- simple_goseq(epi_cl14clbr_high, lengths=gene_lengths, goids=go_ids)
epi_cl14clbr_high_go$pvalue_histogram
epi_cl14clbr_high_go$bpp_plot

summary(epi_cl14clbr_high_go)
fun <- epi_cl14clbr_high_go$godata_interesting
goseq_annotation <- goseq_table(fun)
## Oh crap, I cannot make trees until I generate a id2go R mapping, I will need to check my previous
## script for how to do that (I think I do it automatically in simple_topgo()...
##epi_cl14clbr_high_trees = goseq_trees(degenes=epi_cl14clbr_high, epi_cl14clbr_high_go)
## I had to hack the geneTable() function in order to make it not take infinite memory because it
## was trying to do some stupid merge of every gff column against every other column...
## Once the geneTable.rda file exists and included real information, this seems to work fine, though.
epi_cl14clbr_high_cl <- simple_clusterprofiler(epi_cl14clbr_high)
epi_cl14clbr_high_cl$bp_all_barplot
## The first time this is run in a fresh directory, it needs to be run like this:
## simple_topgo(epi_cl14clbr_high, goids_df=go_ids)
## setting goids_df will tell it to generate a table of genes->GO<-genes in the format expected.
epi_cl14clbr_high_top <- simple_topgo(epi_cl14clbr_high, goids=goid_file, pvals=epi_cl14clbr_pvals)

topgo_pval <- topgo_pval_plot(epi_cl14clbr_high_top)
topgo_pval$BP
top_trees <- topgo_trees(epi_cl14clbr_high_top)
top_trees$bp_fisher_tree

1.3 Compare Epimastigotes between CL14 and CLBr, low expression

## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
epi_cl14clbr_low = subset(epi_cl14clbr_table, logFC <= epi_cl14clbr_summary[2] & adj.P.Val <= pval_thresh)
epi_cl14clbr_low_go = simple_goseq(de_genes=epi_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
epi_cl14clbr_low_go$pvalue_histogram
epi_cl14clbr_low_go$bpp_plot
##epi_cl14clbr_low_cl = simple_clusterprofiler(epi_cl14clbr_low, gff="reference/gff/clbrener_8.1_complete_genes.gff.gz")
##epi_cl14clbr_low_cl$bp_all_barplot
epi_cl14clbr_low_top = simple_topgo(epi_cl14clbr_low, goids=goid_file, pvals=epi_cl14clbr_pvals)
topgo_pval = topgo_pval_plot(epi_cl14clbr_high_top)
topgo_pval$BP
top_trees = topgo_trees(epi_cl14clbr_low_top)
top_trees$bp_fisher_tree

1.4 Compare trypo CL14/CLBr

## Changes in epimastigotes from CLBrener to CL14
tryp_cl14clbr_table = all_tables$tryp_cl14clbr
tryp_cl14clbr_summary = summary(tryp_cl14clbr_table$logFC)
tryp_cl14clbr_pvals = tryp_cl14clbr_table$adj.P.Val
names(tryp_cl14clbr_pvals) = rownames(tryp_cl14clbr_table)
## Extract the genes with high expression in CL14 compared to Brener and very low pvalues
tryp_cl14clbr_high = subset(tryp_cl14clbr_table, logFC >= tryp_cl14clbr_summary[5] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the high genes
tryp_cl14clbr_high_go = simple_goseq(tryp_cl14clbr_high, lengths=gene_lengths, goids=go_ids)
tryp_cl14clbr_high_go$pvalue_histogram
tryp_cl14clbr_high_go$bpp_plot
tryp_cl14clbr_high_cl = simple_clusterprofiler(tryp_cl14clbr_high)
tryp_cl14clbr_high_cl$bp_all_barplot
tryp_cl14clbr_high_top = simple_topgo(tryp_cl14clbr_high, goids=goid_file, pvals=tryp_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(tryp_cl14clbr_high_top)
topgo_pval$BP
top_trees = topgo_trees(tryp_cl14clbr_high_top)
top_trees$bp_fisher_tree

1.5 Compare cl14/clbr tryp other side

## Changes in epimastigotes from CLBrener to CL14
tryp_cl14clbr_table = all_tables$tryp_cl14clbr
tryp_cl14clbr_summary = summary(tryp_cl14clbr_table$logFC)
tryp_cl14clbr_pvals = tryp_cl14clbr_table$adj.P.Val
names(tryp_cl14clbr_pvals) = rownames(tryp_cl14clbr_table)
## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
tryp_cl14clbr_low = subset(tryp_cl14clbr_table, logFC <= tryp_cl14clbr_summary[2] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the low genes
tryp_cl14clbr_low_go = simple_goseq(tryp_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
tryp_cl14clbr_low_go$pvalue_histogram
tryp_cl14clbr_low_go$bpp_plot
tryp_cl14clbr_low_cl = simple_clusterprofiler(tryp_cl14clbr_low)
tryp_cl14clbr_low_cl$bp_all_barplot
tryp_cl14clbr_low_top = simple_topgo(tryp_cl14clbr_low, goids=goid_file, pvals=tryp_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(tryp_cl14clbr_low_top)
topgo_pval$BP
top_trees = topgo_trees(tryp_cl14clbr_low_top)
top_trees$bp_fisher_tree

1.6 Amastigote a96 cl14/clbr

## Changes in epimastigotes from CLBrener to CL14
a96_cl14clbr_table = all_tables$a96_cl14clbr
a96_cl14clbr_summary = summary(a96_cl14clbr_table$logFC)
a96_cl14clbr_pvals = a96_cl14clbr_table$adj.P.Val
names(a96_cl14clbr_pvals) = rownames(a96_cl14clbr_table)
## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
a96_cl14clbr_low = subset(a96_cl14clbr_table, logFC >= a96_cl14clbr_summary[5] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the low genes
a96_cl14clbr_low_go = simple_goseq(a96_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
a96_cl14clbr_low_go$pvalue_histogram
a96_cl14clbr_low_go$bpp_plot
a96_cl14clbr_low_cl = simple_clusterprofiler(a96_cl14clbr_low)
a96_cl14clbr_low_cl$bp_all_barplot
a96_cl14clbr_low_top = simple_topgo(a96_cl14clbr_low, goids=goid_file, pvals=a96_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(a96_cl14clbr_low_top)
topgo_pval$BP
top_trees = topgo_trees(a96_cl14clbr_low_top)
top_trees$bp_fisher_tree
## Changes in epimastigotes from CLBrener to CL14
a96_cl14clbr_table = strain_comparisons$data$a96_clbr_over_cl14
a96_cl14clbr_summary = summary(a96_cl14clbr_table$logFC)
a96_cl14clbr_pvals = a96_cl14clbr_table$adj.P.Val
names(a96_cl14clbr_pvals) = rownames(a96_cl14clbr_table)
## Extract the genes with low expression in CL14 compared to Brener and very low pvalues
a96_cl14clbr_low = subset(a96_cl14clbr_table, logFC <= a96_cl14clbr_summary[2] & adj.P.Val <= pval_thresh)
## Do a goseq comparison of the low genes
a96_cl14clbr_low_go = simple_goseq(a96_cl14clbr_low, lengths=gene_lengths, goids=go_ids)
a96_cl14clbr_low_go$pvalue_histogram
a96_cl14clbr_low_go$bpp_plot
a96_cl14clbr_low_cl = simple_clusterprofiler(a96_cl14clbr_low)
a96_cl14clbr_low_cl$bp_all_barplot
a96_cl14clbr_low_top = simple_topgo(a96_cl14clbr_low, goids=goid_file, pvals=a96_cl14clbr_pvals)

topgo_pval = topgo_pval_plot(a96_cl14clbr_low_top)
topgo_pval$BP
top_trees = topgo_trees(a96_cl14clbr_low_top)
top_trees$bp_fisher_tree

## Ways to look
a60_cl14clbr_table = all_tables$a60_cl14clbr
tmp = merge(a60_cl14clbr_table, a96_cl14clbr_table, by="row.names")
tmp_b_t = data.frame(a60=tmp$B.x, a96=tmp$B.y)
tt = hpgl_linear_scatter(tmp_b_t)
tt$scatter
a60_cl14clbr_table = all_tables$a60_cl14clbr
tmp = merge(a60_cl14clbr_table, a96_cl14clbr_table, by="row.names")
tmp_b_t = data.frame(a60=tmp$t.x, a96=tmp$t.y)
tt = hpgl_scatter(tmp_b_t)
tt$scatter

2 KG

Oh yeah, I wrote a toy to wrap KEGG pathway stuff, lets try that. The KEGG abbreviation for t. cruzi is tcr

In theory, the _paths data structure returned by hpgl_pathview() should be a table of the numer of up/down genes observed in each KEGG path. However, there are some weird NAs getting returned. Effing hippies. – fixed.

kegg_list <- ""
##names(kegg_list) = rownames(epi_cl14clbr_table)
##epi_cl14clbr_paths = hpgl_pathview(kegg_list, species="tcr", indir="pathview_in", outdir="pathview_epi_cl14clbr", string_from="TcCLB.", string_to="")
##head(epi_cl14clbr_paths)


##a60_cl14clbr_table = all_tables$a60_cl14clbr
a60_cl14clbr_table <- strain_comparisons$data$a60_clbr_over_cl14
##kegg_list <- a60_cl14clbr_table$logFC
kegg_list <- a60_cl14clbr_table$limma_logfc
names(kegg_list) <- rownames(a60_cl14clbr_table)
a60_cl14clbr_paths <- hpgl_pathview(kegg_list, species="tcr",
                                    indir="pathview_in", outdir="pathview_a60_cl14clbr",
                                    from_list="TcCLB.", to_list="")
head(a60_cl14clbr_paths)

a96_cl14clbr_table = all_tables$a96_cl14clbr
kegg_list = a96_cl14clbr_table$logFC
names(kegg_list) = rownames(a96_cl14clbr_table)
a96_cl14clbr_paths = hpgl_pathview(kegg_list, species="tcr", indir="pathview_in", outdir="pathview_a96_cl14clbr", string_from="TcCLB.", string_to="")
head(a96_cl14clbr_paths)

tryp_cl14clbr_table = all_tables$a96_cl14clbr
kegg_list = tryp_cl14clbr_table$logFC
names(kegg_list) = rownames(tryp_cl14clbr_table)
tryp_cl14clbr_paths = hpgl_pathview(kegg_list, species="tcr", indir="pathview_in", outdir="pathview_tryp_cl14clbr", string_from="TcCLB.", string_to="")
head(tryp_cl14clbr_paths)
LS0tCnRpdGxlOiAiUk5Bc2VxIG9mIFQuY3J1emkgQ0wxNC9DTEJyOiBHZW5lIE9udG9sb2d5LiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KCJocGdsdG9vbHMiKQp0dCA8LSBzbShkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHByb2dyZXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgd2lkdGg9OTAsCiAgICAgICAgICAgICAgICAgICAgIGVjaG89TlVMTCkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGg9OCwKICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQ9OCwKICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhlcnJvcj1OVUxMLAogICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQpzZXQuc2VlZCgxKQp2ZXIgPC0gIjIwMTcwODEwIgpwcmV2aW91c19maWxlIDwtICIwM19kaWZmZXJlbnRpYWxfZXhwcmVzc2lvbi5SbWQiCgp0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKSkKCnJtZF9maWxlIDwtICIwNF9nZW5lX29udG9sb2d5LlJtZCIKYGBgCgpbaW5kZXguaHRtbF0oaW5kZXguaHRtbCkKWzAxX2Fubm90YXRpb24uaHRtbF0oMDFfYW5ub3RhdGlvbi5odG1sKQpbMDJfc2FtcGxlX2VzdGltYXRpb25zLmh0bWxdKDAyX3NhbXBsZV9lc3RpbWF0aW9ucy5odG1sKQpbMDNfZGlmZmVyZW50aWFsX2V4cHJlc3Npb24uaHRtbF0oMDNfZGlmZmVyZW50aWFsX2V4cHJlc3Npb24uaHRtbCkKCmBgYHtyIHJlbmRlcmluZywgaW5jbHVkZT1GQUxTRSwgZXZhbD1GQUxTRX0Kcm1hcmtkb3duOjpyZW5kZXIocm1kX2ZpbGUpCgpybWFya2Rvd246OnJlbmRlcihybWRfZmlsZSwgb3V0cHV0X2Zvcm1hdD0icGRmX2RvY3VtZW50Iiwgb3V0cHV0X29wdGlvbnM9Yygic2tpcF9odG1sIikpCmBgYAojIEdlbmUgT250b2xvZ3kgc2VhcmNoZXMKCkxldHMgc2V0IHVwIHNvbWUgc2ltcGxlIGRhdGEgc2V0cyBmb3IgZ29zZXEvY2x1c3RlclByb2ZpbGVyL3RvcEdPCgpJIHRoaW5rIGEgYnVuY2ggb2YgdGhlIG1hdGVyaWFsIGluIHRoaXMgc2hlZXQgaXMgYWN0dWFsbHkgbm93IG9ic29sZXRlLgoKIyMgUHJlcGFyaW5nIHRvIHVzZSBnb3NlcQoKSSBuZWVkIGEgY291cGxlIHZlY3RvcnMgYmVmb3JlIGJlaW5nIGFibGUgdG8gdXNlIGdvc2VxCkkgYWxzbyBuZWVkIHNvbWUgcmRhIGZpbGVzIGdlbmVyYXRlZCBmb3IgY2x1c3RlclByb2ZpbGVyIGFuZCB0b3BHTwpidXQgSSB3aWxsIGRvIHRob3NlIGxhdGVyLi4uCgpgYGB7ciBnb3NlcV9wcmVwYXJhdGlvbn0KIyMgZ29zZXEgdXNlcyB0aGUgZ2VuZSBsZW5ndGhzLCBjbHVzdGVycHJvZmlsZXIgYW5kIHRvcGdvIGRvbid0CiMjIGdlbmVfbGVuZ3RocyA8LSBhbGxfZ2VuZXNbLGMoImdlbmVpZCIsImdlbmVzaXplIildCiMjIGNvbG5hbWVzKGdlbmVfbGVuZ3RocykgPC0gYygiSUQiLCAid2lkdGgiKQpjb2xuYW1lcyhhbGxfbGVuZ3RocykgPC0gYygiSUQiLCAid2lkdGgiKQojIyBnb19pZHMgbmVlZHMgdG8gYmUgYSAyIGNvbHVtbiBkYXRhIGZyYW1lIHdpdGggbmFtZXMgJ0lEJywgJ0dPJyB3aGljaCBhcmUKIyMgZ2VuZSBuYW1lcyBhbmQgR08gbmFtZXMgcmVzcGVjdGl2ZWx5LiAgSSBhY3R1YWxseSB0aGluayBJIG1hZGUgbXkgZ29zZXEoKSBmdW5jdGlvbgojIyBzbWFydCBlbm91Z2ggdGhhdCB0aGlzIGlzIG5vIGxvbmdlciBuZWVkZWQsIGJ1dCBub25ldGhlbGVzcy4KCiMjIGdvX2lkcyA8LSByZWFkLnRhYmxlKCJyZWZlcmVuY2UvZ28vdGNydXppX2FsbF9nby50YWIuZ3oiLCBoZWFkZXI9MCwgc2VwPSJcdCIpCiMjIGNvbG5hbWVzKGdvX2lkcykgPC0gYygiSUQiLCJHTyIsIm9udG9sb2d5IiwidGVybSIsInNvdXJjZSIpCiMjIFNpbmNlIHRoZXJlIGFyZSBtdWx0aXBsZSBzb3VyY2VzLCBJIGFtIGRvaW5nIGEgdW5pcXVlIG9mIHRoZSB0YWJsZS4uLgojIyBnb19pZHMgPC0gdW5pcXVlKGdvX2lkc1ssYygiSUQiLCJHTyIpXSkKIyMgZ29pZF9maWxlIDwtICJyZWZlcmVuY2UvZ28vdG9wZ29fZ29pZHMudGFiLmd6IgoKYWxsX2dvIDwtIGFzLmRhdGEuZnJhbWUoYWxsX2dvKQphbGxfZ28gPC0gYWxsX2dvWywgYygiR0lEIiwgIkdPIildCmBgYAoKYGBge3IgZ29zZXFfY2xicl90aW1lczF9CnNpZyA8LSBjbGJyX3RpbWVzX3NpZ2ZpbHQkbGltbWEkdXBzJENMQnIuVHJ5cF92c19DTEJyLkE5NgpjbGJyX3VwX2E5NnRyeXBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zaWcsCiAgZ29fZGI9YWxsX2dvLAogIGxlbmd0aF9kYj1hbGxfbGVuZ3RocywKICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYnJfdXBfYTk2dHJ5cF9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCmNsYnJfdXBfYTk2dHJ5cF9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgoKc2lnIDwtIGNsYnJfdGltZXNfc2lnZmlsdCRsaW1tYSRkb3ducyRDTEJyLlRyeXBfdnNfQ0xCci5BOTYKY2xicl9kb3duX2E5NnRyeXBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zaWcsCiAgZ29fZGI9YWxsX2dvLAogIGxlbmd0aF9kYj1hbGxfbGVuZ3RocywKICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYnJfZG93bl9hOTZ0cnlwX2dvc2VxLXYiLCB2ZXIsICIueGxzeCIpKSkKY2xicl9kb3duX2E5NnRyeXBfZ29zZXEkcHZhbHVlX3Bsb3RzJGJwcF9wbG90X292ZXIKCnNpZyA8LSBjbGJyX3RpbWVzX3NpZ2ZpbHQkbGltbWEkdXBzJENMQnIuQTk2X3ZzX0NMQnIuQTYwCmNsYnJfdXBfYTYwYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c2lnLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbGJyX3VwX2E2MGE5Nl9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCmNsYnJfdXBfYTYwYTk2X2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCgpzaWcgPC0gY2xicl90aW1lc19zaWdmaWx0JGxpbW1hJGRvd25zJENMQnIuQTk2X3ZzX0NMQnIuQTYwCmNsYnJfZG93bl9hNjBhOTZfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zaWcsCiAgZ29fZGI9YWxsX2dvLAogIGxlbmd0aF9kYj1hbGxfbGVuZ3RocywKICBleGNlbD1wYXN0ZTAoImV4Y2VsL2NsYnJfZG93bl9hNjBhOTZfZ29zZXEtdiIsIHZlciwgIi54bHN4IikpKQpjbGJyX2Rvd25fYTYwYTk2X2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCgpzaWcgPC0gY2xicl90aW1lc19zaWdmaWx0JGxpbW1hJHVwcyRDTEJyLkE2MF92c19DTEJyLlRyeXAKY2xicl91cF90cnlwYTYwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c2lnLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbGJyX3VwX3RyeXBhNjBfZ29zZXEtdiIsIHZlciwgIi54bHN4IikpKQpjbGJyX3VwX3RyeXBhNjBfZ29zZXEkcHZhbHVlX3Bsb3RzJGJwcF9wbG90X292ZXIKCnNpZyA8LSBjbGJyX3RpbWVzX3NpZ2ZpbHQkbGltbWEkZG93bnMkQ0xCci5BNjBfdnNfQ0xCci5UcnlwCmNsYnJfZG93bl90cnlwYTYwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c2lnLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbGJyX2Rvd25fdHJ5cGE2MF9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCmNsYnJfZG93bl90cnlwYTYwX2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCgpzaWcgPC0gY2wxNF90aW1lc19zaWdmaWx0JGxpbW1hJHVwcyRDTDE0LlRyeXBfdnNfQ0wxNC5BOTYKY2wxNF91cF9hOTZ0cnlwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c2lnLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbDE0X3VwX2E5NnRyeXBfZ29zZXEtdiIsIHZlciwgIi54bHN4IikpKQpjbDE0X3VwX2E5NnRyeXBfZ29zZXEkcHZhbHVlX3Bsb3RzJGJwcF9wbG90X292ZXIKCnNpZyA8LSBjbDE0X3RpbWVzX3NpZ2ZpbHQkbGltbWEkZG93bnMkQ0wxNC5UcnlwX3ZzX0NMMTQuQTk2CmNsMTRfZG93bl9hOTZ0cnlwX2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c2lnLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbDE0X2Rvd25fYTk2dHJ5cF9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCmNsMTRfZG93bl9hOTZ0cnlwX2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCgpzaWcgPC0gY2wxNF90aW1lc19zaWdmaWx0JGxpbW1hJHVwcyRDTDE0LkE5Nl92c19DTDE0LkE2MApjbDE0X3VwX2E2MGE5Nl9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoCiAgc2lnX2dlbmVzPXNpZywKICBnb19kYj1hbGxfZ28sCiAgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2wxNF91cF9hNjBhOTZfZ29zZXEtdiIsIHZlciwgIi54bHN4IikpKQpjbDE0X3VwX2E2MGE5Nl9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgoKc2lnIDwtIGNsMTRfdGltZXNfc2lnZmlsdCRsaW1tYSRkb3ducyRDTDE0LkE5Nl92c19DTDE0LkE2MApjbDE0X2Rvd25fYTYwYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c2lnLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9jbDE0X2Rvd25fYTYwYTk2X2dvc2VxLXYiLCB2ZXIsICIueGxzeCIpKSkKY2wxNF9kb3duX2E2MGE5Nl9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgoKc2lnIDwtIGNsMTRfdGltZXNfc2lnZmlsdCRsaW1tYSR1cHMkQ0wxNC5BNjBfdnNfQ0wxNC5UcnlwCmNsMTRfdXBfdHJ5cGE2MF9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoCiAgc2lnX2dlbmVzPXNpZywKICBnb19kYj1hbGxfZ28sCiAgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2wxNF91cF90cnlwYTYwX2dvc2VxLXYiLCB2ZXIsICIueGxzeCIpKSkKY2wxNF91cF90cnlwYTYwX2dvc2VxJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCgpzaWcgPC0gY2wxNF90aW1lc19zaWdmaWx0JGxpbW1hJGRvd25zJENMMTQuQTYwX3ZzX0NMMTQuVHJ5cApjbDE0X2Rvd25fdHJ5cGE2MF9nb3NlcSA8LSBzbShzaW1wbGVfZ29zZXEoCiAgc2lnX2dlbmVzPXNpZywKICBnb19kYj1hbGxfZ28sCiAgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvY2wxNF9kb3duX3RyeXBhNjBfZ29zZXEtdiIsIHZlciwgIi54bHN4IikpKQpjbDE0X2Rvd25fdHJ5cGE2MF9nb3NlcSRwdmFsdWVfcGxvdHMkYnBwX3Bsb3Rfb3ZlcgoKc3RyYWluc191cF9hNjBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zdHJhaW5zX3NpZ2ZpbHQkbGltbWEkdXBzJENMQnIuQTYwX3ZzX0NMMTQuQTYwLAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9zdHJhaW5zX3VwYTYwX2dvc2VxLXYiLCB2ZXIsICIueGxzeCIpKSkKCnN0cmFpbnNfdXBfYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c3RyYWluc19zaWdmaWx0JGxpbW1hJHVwcyRDTEJyLkE5Nl92c19DTDE0LkE5NiwKICBnb19kYj1hbGxfZ28sCiAgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvc3RyYWluc191cGE5Nl9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCgpzdHJhaW5zX3VwX3RyeXBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zdHJhaW5zX3NpZ2ZpbHQkbGltbWEkdXBzJENMQnIuVHJ5cF92c19DTDE0LlRyeXAsCiAgZ29fZGI9YWxsX2dvLAogIGxlbmd0aF9kYj1hbGxfbGVuZ3RocywKICBleGNlbD1wYXN0ZTAoImV4Y2VsL3N0cmFpbnNfdXB0cnlwX2dvc2VxLXYiLCB2ZXIsICIueGxzeCIpKSkKICAgICAgICAgICAgICAgICAgICAgICAgCnN0cmFpbnNfZG93bl9hNjBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zdHJhaW5zX3NpZ2ZpbHQkbGltbWEkZG93bnMkQ0xCci5BNjBfdnNfQ0wxNC5BNjAsCiAgZ29fZGI9YWxsX2dvLAogIGxlbmd0aF9kYj1hbGxfbGVuZ3RocywKICBleGNlbD1wYXN0ZTAoImV4Y2VsL3N0cmFpbnNfZG93bmE2MF9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCgpzdHJhaW5zX2Rvd25fYTk2X2dvc2VxIDwtIHNtKHNpbXBsZV9nb3NlcSgKICBzaWdfZ2VuZXM9c3RyYWluc19zaWdmaWx0JGxpbW1hJGRvd25zJENMQnIuQTk2X3ZzX0NMMTQuQTk2LAogIGdvX2RiPWFsbF9nbywKICBsZW5ndGhfZGI9YWxsX2xlbmd0aHMsCiAgZXhjZWw9cGFzdGUwKCJleGNlbC9zdHJhaW5zX2Rvd25hOTZfZ29zZXEtdiIsIHZlciwgIi54bHN4IikpKQoKc3RyYWluc19kb3duX3RyeXBfZ29zZXEgPC0gc20oc2ltcGxlX2dvc2VxKAogIHNpZ19nZW5lcz1zdHJhaW5zX3NpZ2ZpbHQkbGltbWEkZG93bnMkQ0xCci5UcnlwX3ZzX0NMMTQuVHJ5cCwKICBnb19kYj1hbGxfZ28sCiAgbGVuZ3RoX2RiPWFsbF9sZW5ndGhzLAogIGV4Y2VsPXBhc3RlMCgiZXhjZWwvc3RyYWluc19kb3dudHJ5cF9nb3NlcS12IiwgdmVyLCAiLnhsc3giKSkpCmBgYAoKIyMgQ29tcGFyZSBFcGltYXN0aWdvdGVzIGJldHdlZW4gQ0wxNCBhbmQgQ0xCciwgaGlnaCBleHByZXNzaW9uCgpPbmUgaW1wb3J0YW50IG5vdGUgaGVyZSwgSSBuZWVkZWQgdG8gbW9kaWZ5IHRoZSBkYXRhIHN0cnVjdHVyZSBmcm9tIHJlYWRHZmYoKSBpbiBjbHVzdGVyUHJvZmlsZXIKYmVmb3JlIGl0IHdhcyBhYmxlIHRvIHN1Y2Nlc3NmdWxseSBnZW5lcmF0ZSB0aGUgZmlsZSAnZ2VuZVRhYmxlLnJkYScKVW5mb3J0dW5hdGVseSwgSSB3YXMgd2F0Y2hpbmcgYSBtb3ZpZSBhdCB0aGUgdGltZSBhbmQgZGlkbid0IHByb3Blcmx5IHdyaXRlIGRvd24gd2hhdCBJIGRpZC4KSG93ZXZlciwgSSBkaWQgd3JpdGUgaXQgb3V0IGluIHRoZSBmdW5jdGlvbiBteXI6OkdmZjJHZW5lVGFibGUoKQpidXQgaW4gb3JkZXIgdG8gbWFrZSBpdCB3b3JrIG9uZSBtdXN0IGxvYWQgcmVhZEdmZigpIGZyb20gY2x1c3RlclByb2ZpbGVyLgpJIHRoaW5rIHRoZSByZWFsIHNvbHV0aW9uIGlzIGZvciBtZSB0byBncmFiIGEgdmVyc2lvbiBvZiByZWFkR2ZmKCkgZnJvbSBjbHVzdGVyUHJvZmlsZXIKYW5kIG1ha2UgaXQgZXhwb3J0YWJsZSBzbyB0aGF0IGl0IHdpbGwgd29yayBjb25zaXN0ZW50bHkuCgpgYGB7ciBvbnRvbG9neV9lcGlfY2wxNGNscl9oaWdoLCBldmFsPUZBTFNFfQojIyBDaGFuZ2VzIGluIGVwaW1hc3RpZ290ZXMgZnJvbSBDTEJyZW5lciB0byBDTDE0CnB2YWxfdGhyZXNoIDwtIDAuMDAwMQplcGlfY2wxNGNsYnJfdGFibGUgPC0gYWxsX3RhYmxlcyRlcGlfY2wxNGNsYnIKZXBpX2NsMTRjbGJyX3N1bW1hcnkgPC0gc3VtbWFyeShlcGlfY2wxNGNsYnJfdGFibGUkbG9nRkMpCmVwaV9jbDE0Y2xicl9wdmFscyA8LSBlcGlfY2wxNGNsYnJfdGFibGUkYWRqLlAuVmFsCm5hbWVzKGVwaV9jbDE0Y2xicl9wdmFscykgPC0gcm93bmFtZXMoZXBpX2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGhpZ2ggZXhwcmVzc2lvbiBpbiBDTDE0IGNvbXBhcmVkIHRvIEJyZW5lciBhbmQgdmVyeSBsb3cgcHZhbHVlcwplcGlfY2wxNGNsYnJfaGlnaCA8LSBzdWJzZXQoZXBpX2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA+PSBlcGlfY2wxNGNsYnJfc3VtbWFyeVs1XSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBoaWdoIGdlbmVzCmVwaV9jbDE0Y2xicl9oaWdoX2dvIDwtIHNpbXBsZV9nb3NlcShlcGlfY2wxNGNsYnJfaGlnaCwgbGVuZ3Rocz1nZW5lX2xlbmd0aHMsIGdvaWRzPWdvX2lkcykKZXBpX2NsMTRjbGJyX2hpZ2hfZ28kcHZhbHVlX2hpc3RvZ3JhbQplcGlfY2wxNGNsYnJfaGlnaF9nbyRicHBfcGxvdAoKc3VtbWFyeShlcGlfY2wxNGNsYnJfaGlnaF9nbykKZnVuIDwtIGVwaV9jbDE0Y2xicl9oaWdoX2dvJGdvZGF0YV9pbnRlcmVzdGluZwpnb3NlcV9hbm5vdGF0aW9uIDwtIGdvc2VxX3RhYmxlKGZ1bikKIyMgT2ggY3JhcCwgSSBjYW5ub3QgbWFrZSB0cmVlcyB1bnRpbCBJIGdlbmVyYXRlIGEgaWQyZ28gUiBtYXBwaW5nLCBJIHdpbGwgbmVlZCB0byBjaGVjayBteSBwcmV2aW91cwojIyBzY3JpcHQgZm9yIGhvdyB0byBkbyB0aGF0IChJIHRoaW5rIEkgZG8gaXQgYXV0b21hdGljYWxseSBpbiBzaW1wbGVfdG9wZ28oKS4uLgojI2VwaV9jbDE0Y2xicl9oaWdoX3RyZWVzID0gZ29zZXFfdHJlZXMoZGVnZW5lcz1lcGlfY2wxNGNsYnJfaGlnaCwgZXBpX2NsMTRjbGJyX2hpZ2hfZ28pCiMjIEkgaGFkIHRvIGhhY2sgdGhlIGdlbmVUYWJsZSgpIGZ1bmN0aW9uIGluIG9yZGVyIHRvIG1ha2UgaXQgbm90IHRha2UgaW5maW5pdGUgbWVtb3J5IGJlY2F1c2UgaXQKIyMgd2FzIHRyeWluZyB0byBkbyBzb21lIHN0dXBpZCBtZXJnZSBvZiBldmVyeSBnZmYgY29sdW1uIGFnYWluc3QgZXZlcnkgb3RoZXIgY29sdW1uLi4uCiMjIE9uY2UgdGhlIGdlbmVUYWJsZS5yZGEgZmlsZSBleGlzdHMgYW5kIGluY2x1ZGVkIHJlYWwgaW5mb3JtYXRpb24sIHRoaXMgc2VlbXMgdG8gd29yayBmaW5lLCB0aG91Z2guCmVwaV9jbDE0Y2xicl9oaWdoX2NsIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoZXBpX2NsMTRjbGJyX2hpZ2gpCmVwaV9jbDE0Y2xicl9oaWdoX2NsJGJwX2FsbF9iYXJwbG90CiMjIFRoZSBmaXJzdCB0aW1lIHRoaXMgaXMgcnVuIGluIGEgZnJlc2ggZGlyZWN0b3J5LCBpdCBuZWVkcyB0byBiZSBydW4gbGlrZSB0aGlzOgojIyBzaW1wbGVfdG9wZ28oZXBpX2NsMTRjbGJyX2hpZ2gsIGdvaWRzX2RmPWdvX2lkcykKIyMgc2V0dGluZyBnb2lkc19kZiB3aWxsIHRlbGwgaXQgdG8gZ2VuZXJhdGUgYSB0YWJsZSBvZiBnZW5lcy0+R088LWdlbmVzIGluIHRoZSBmb3JtYXQgZXhwZWN0ZWQuCmVwaV9jbDE0Y2xicl9oaWdoX3RvcCA8LSBzaW1wbGVfdG9wZ28oZXBpX2NsMTRjbGJyX2hpZ2gsIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9ZXBpX2NsMTRjbGJyX3B2YWxzKQoKdG9wZ29fcHZhbCA8LSB0b3Bnb19wdmFsX3Bsb3QoZXBpX2NsMTRjbGJyX2hpZ2hfdG9wKQp0b3Bnb19wdmFsJEJQCnRvcF90cmVlcyA8LSB0b3Bnb190cmVlcyhlcGlfY2wxNGNsYnJfaGlnaF90b3ApCnRvcF90cmVlcyRicF9maXNoZXJfdHJlZQpgYGAKCiMjIENvbXBhcmUgRXBpbWFzdGlnb3RlcyBiZXR3ZWVuIENMMTQgYW5kIENMQnIsIGxvdyBleHByZXNzaW9uCgpgYGB7ciBvbnRvbG9neV9lcGlfY2wxNGNsYnJfbG93LCBldmFsPUZBTFNFfQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCmVwaV9jbDE0Y2xicl9sb3cgPSBzdWJzZXQoZXBpX2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA8PSBlcGlfY2wxNGNsYnJfc3VtbWFyeVsyXSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKZXBpX2NsMTRjbGJyX2xvd19nbyA9IHNpbXBsZV9nb3NlcShkZV9nZW5lcz1lcGlfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQplcGlfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KZXBpX2NsMTRjbGJyX2xvd19nbyRicHBfcGxvdAojI2VwaV9jbDE0Y2xicl9sb3dfY2wgPSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKGVwaV9jbDE0Y2xicl9sb3csIGdmZj0icmVmZXJlbmNlL2dmZi9jbGJyZW5lcl84LjFfY29tcGxldGVfZ2VuZXMuZ2ZmLmd6IikKIyNlcGlfY2wxNGNsYnJfbG93X2NsJGJwX2FsbF9iYXJwbG90CmVwaV9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKGVwaV9jbDE0Y2xicl9sb3csIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9ZXBpX2NsMTRjbGJyX3B2YWxzKQp0b3Bnb19wdmFsID0gdG9wZ29fcHZhbF9wbG90KGVwaV9jbDE0Y2xicl9oaWdoX3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyhlcGlfY2wxNGNsYnJfbG93X3RvcCkKdG9wX3RyZWVzJGJwX2Zpc2hlcl90cmVlCmBgYAoKIyMgQ29tcGFyZSB0cnlwbyBDTDE0L0NMQnIKCmBgYHtyIHRyeXBfY2wxNGNsYnJfaGlnaF9nb3NlcSwgZXZhbD1GQUxTRX0KIyMgQ2hhbmdlcyBpbiBlcGltYXN0aWdvdGVzIGZyb20gQ0xCcmVuZXIgdG8gQ0wxNAp0cnlwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyR0cnlwX2NsMTRjbGJyCnRyeXBfY2wxNGNsYnJfc3VtbWFyeSA9IHN1bW1hcnkodHJ5cF9jbDE0Y2xicl90YWJsZSRsb2dGQykKdHJ5cF9jbDE0Y2xicl9wdmFscyA9IHRyeXBfY2wxNGNsYnJfdGFibGUkYWRqLlAuVmFsCm5hbWVzKHRyeXBfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXModHJ5cF9jbDE0Y2xicl90YWJsZSkKIyMgRXh0cmFjdCB0aGUgZ2VuZXMgd2l0aCBoaWdoIGV4cHJlc3Npb24gaW4gQ0wxNCBjb21wYXJlZCB0byBCcmVuZXIgYW5kIHZlcnkgbG93IHB2YWx1ZXMKdHJ5cF9jbDE0Y2xicl9oaWdoID0gc3Vic2V0KHRyeXBfY2wxNGNsYnJfdGFibGUsIGxvZ0ZDID49IHRyeXBfY2wxNGNsYnJfc3VtbWFyeVs1XSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBoaWdoIGdlbmVzCnRyeXBfY2wxNGNsYnJfaGlnaF9nbyA9IHNpbXBsZV9nb3NlcSh0cnlwX2NsMTRjbGJyX2hpZ2gsIGxlbmd0aHM9Z2VuZV9sZW5ndGhzLCBnb2lkcz1nb19pZHMpCnRyeXBfY2wxNGNsYnJfaGlnaF9nbyRwdmFsdWVfaGlzdG9ncmFtCnRyeXBfY2wxNGNsYnJfaGlnaF9nbyRicHBfcGxvdAp0cnlwX2NsMTRjbGJyX2hpZ2hfY2wgPSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKHRyeXBfY2wxNGNsYnJfaGlnaCkKdHJ5cF9jbDE0Y2xicl9oaWdoX2NsJGJwX2FsbF9iYXJwbG90CnRyeXBfY2wxNGNsYnJfaGlnaF90b3AgPSBzaW1wbGVfdG9wZ28odHJ5cF9jbDE0Y2xicl9oaWdoLCBnb2lkcz1nb2lkX2ZpbGUsIHB2YWxzPXRyeXBfY2wxNGNsYnJfcHZhbHMpCgp0b3Bnb19wdmFsID0gdG9wZ29fcHZhbF9wbG90KHRyeXBfY2wxNGNsYnJfaGlnaF90b3ApCnRvcGdvX3B2YWwkQlAKdG9wX3RyZWVzID0gdG9wZ29fdHJlZXModHJ5cF9jbDE0Y2xicl9oaWdoX3RvcCkKdG9wX3RyZWVzJGJwX2Zpc2hlcl90cmVlCmBgYAoKIyMgQ29tcGFyZSBjbDE0L2NsYnIgdHJ5cCBvdGhlciBzaWRlCgpgYGB7ciB0cnlwX2NsMTRjbGJyX2xvd19nb3NlcSwgZXZhbD1GQUxTRX0KIyMgQ2hhbmdlcyBpbiBlcGltYXN0aWdvdGVzIGZyb20gQ0xCcmVuZXIgdG8gQ0wxNAp0cnlwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyR0cnlwX2NsMTRjbGJyCnRyeXBfY2wxNGNsYnJfc3VtbWFyeSA9IHN1bW1hcnkodHJ5cF9jbDE0Y2xicl90YWJsZSRsb2dGQykKdHJ5cF9jbDE0Y2xicl9wdmFscyA9IHRyeXBfY2wxNGNsYnJfdGFibGUkYWRqLlAuVmFsCm5hbWVzKHRyeXBfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXModHJ5cF9jbDE0Y2xicl90YWJsZSkKIyMgRXh0cmFjdCB0aGUgZ2VuZXMgd2l0aCBsb3cgZXhwcmVzc2lvbiBpbiBDTDE0IGNvbXBhcmVkIHRvIEJyZW5lciBhbmQgdmVyeSBsb3cgcHZhbHVlcwp0cnlwX2NsMTRjbGJyX2xvdyA9IHN1YnNldCh0cnlwX2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA8PSB0cnlwX2NsMTRjbGJyX3N1bW1hcnlbMl0gJiBhZGouUC5WYWwgPD0gcHZhbF90aHJlc2gpCiMjIERvIGEgZ29zZXEgY29tcGFyaXNvbiBvZiB0aGUgbG93IGdlbmVzCnRyeXBfY2wxNGNsYnJfbG93X2dvID0gc2ltcGxlX2dvc2VxKHRyeXBfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQp0cnlwX2NsMTRjbGJyX2xvd19nbyRwdmFsdWVfaGlzdG9ncmFtCnRyeXBfY2wxNGNsYnJfbG93X2dvJGJwcF9wbG90CnRyeXBfY2wxNGNsYnJfbG93X2NsID0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcih0cnlwX2NsMTRjbGJyX2xvdykKdHJ5cF9jbDE0Y2xicl9sb3dfY2wkYnBfYWxsX2JhcnBsb3QKdHJ5cF9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKHRyeXBfY2wxNGNsYnJfbG93LCBnb2lkcz1nb2lkX2ZpbGUsIHB2YWxzPXRyeXBfY2wxNGNsYnJfcHZhbHMpCgp0b3Bnb19wdmFsID0gdG9wZ29fcHZhbF9wbG90KHRyeXBfY2wxNGNsYnJfbG93X3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyh0cnlwX2NsMTRjbGJyX2xvd190b3ApCnRvcF90cmVlcyRicF9maXNoZXJfdHJlZQpgYGAKCiMjIEFtYXN0aWdvdGUgYTk2IGNsMTQvY2xicgoKYGBge3Igb250b2xvZ3lfYTk2X2NsMTRjbGJyX2hpZ2gsIGV2YWw9RkFMU0V9CiMjIENoYW5nZXMgaW4gZXBpbWFzdGlnb3RlcyBmcm9tIENMQnJlbmVyIHRvIENMMTQKYTk2X2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyRhOTZfY2wxNGNsYnIKYTk2X2NsMTRjbGJyX3N1bW1hcnkgPSBzdW1tYXJ5KGE5Nl9jbDE0Y2xicl90YWJsZSRsb2dGQykKYTk2X2NsMTRjbGJyX3B2YWxzID0gYTk2X2NsMTRjbGJyX3RhYmxlJGFkai5QLlZhbApuYW1lcyhhOTZfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXMoYTk2X2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCmE5Nl9jbDE0Y2xicl9sb3cgPSBzdWJzZXQoYTk2X2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA+PSBhOTZfY2wxNGNsYnJfc3VtbWFyeVs1XSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBsb3cgZ2VuZXMKYTk2X2NsMTRjbGJyX2xvd19nbyA9IHNpbXBsZV9nb3NlcShhOTZfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQphOTZfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KYTk2X2NsMTRjbGJyX2xvd19nbyRicHBfcGxvdAphOTZfY2wxNGNsYnJfbG93X2NsID0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcihhOTZfY2wxNGNsYnJfbG93KQphOTZfY2wxNGNsYnJfbG93X2NsJGJwX2FsbF9iYXJwbG90CmE5Nl9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKGE5Nl9jbDE0Y2xicl9sb3csIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9YTk2X2NsMTRjbGJyX3B2YWxzKQoKdG9wZ29fcHZhbCA9IHRvcGdvX3B2YWxfcGxvdChhOTZfY2wxNGNsYnJfbG93X3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyhhOTZfY2wxNGNsYnJfbG93X3RvcCkKdG9wX3RyZWVzJGJwX2Zpc2hlcl90cmVlCmBgYAoKYGBge3Igb250b2xvZ3lfYTk2X2NsMTRjbGJyX2xvdywgZXZhbD1GQUxTRX0KIyMgQ2hhbmdlcyBpbiBlcGltYXN0aWdvdGVzIGZyb20gQ0xCcmVuZXIgdG8gQ0wxNAphOTZfY2wxNGNsYnJfdGFibGUgPSBzdHJhaW5fY29tcGFyaXNvbnMkZGF0YSRhOTZfY2xicl9vdmVyX2NsMTQKYTk2X2NsMTRjbGJyX3N1bW1hcnkgPSBzdW1tYXJ5KGE5Nl9jbDE0Y2xicl90YWJsZSRsb2dGQykKYTk2X2NsMTRjbGJyX3B2YWxzID0gYTk2X2NsMTRjbGJyX3RhYmxlJGFkai5QLlZhbApuYW1lcyhhOTZfY2wxNGNsYnJfcHZhbHMpID0gcm93bmFtZXMoYTk2X2NsMTRjbGJyX3RhYmxlKQojIyBFeHRyYWN0IHRoZSBnZW5lcyB3aXRoIGxvdyBleHByZXNzaW9uIGluIENMMTQgY29tcGFyZWQgdG8gQnJlbmVyIGFuZCB2ZXJ5IGxvdyBwdmFsdWVzCmE5Nl9jbDE0Y2xicl9sb3cgPSBzdWJzZXQoYTk2X2NsMTRjbGJyX3RhYmxlLCBsb2dGQyA8PSBhOTZfY2wxNGNsYnJfc3VtbWFyeVsyXSAmIGFkai5QLlZhbCA8PSBwdmFsX3RocmVzaCkKIyMgRG8gYSBnb3NlcSBjb21wYXJpc29uIG9mIHRoZSBsb3cgZ2VuZXMKYTk2X2NsMTRjbGJyX2xvd19nbyA9IHNpbXBsZV9nb3NlcShhOTZfY2wxNGNsYnJfbG93LCBsZW5ndGhzPWdlbmVfbGVuZ3RocywgZ29pZHM9Z29faWRzKQphOTZfY2wxNGNsYnJfbG93X2dvJHB2YWx1ZV9oaXN0b2dyYW0KYTk2X2NsMTRjbGJyX2xvd19nbyRicHBfcGxvdAphOTZfY2wxNGNsYnJfbG93X2NsID0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcihhOTZfY2wxNGNsYnJfbG93KQphOTZfY2wxNGNsYnJfbG93X2NsJGJwX2FsbF9iYXJwbG90CmE5Nl9jbDE0Y2xicl9sb3dfdG9wID0gc2ltcGxlX3RvcGdvKGE5Nl9jbDE0Y2xicl9sb3csIGdvaWRzPWdvaWRfZmlsZSwgcHZhbHM9YTk2X2NsMTRjbGJyX3B2YWxzKQoKdG9wZ29fcHZhbCA9IHRvcGdvX3B2YWxfcGxvdChhOTZfY2wxNGNsYnJfbG93X3RvcCkKdG9wZ29fcHZhbCRCUAp0b3BfdHJlZXMgPSB0b3Bnb190cmVlcyhhOTZfY2wxNGNsYnJfbG93X3RvcCkKdG9wX3RyZWVzJGJwX2Zpc2hlcl90cmVlCgojIyBXYXlzIHRvIGxvb2sKYTYwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyRhNjBfY2wxNGNsYnIKdG1wID0gbWVyZ2UoYTYwX2NsMTRjbGJyX3RhYmxlLCBhOTZfY2wxNGNsYnJfdGFibGUsIGJ5PSJyb3cubmFtZXMiKQp0bXBfYl90ID0gZGF0YS5mcmFtZShhNjA9dG1wJEIueCwgYTk2PXRtcCRCLnkpCnR0ID0gaHBnbF9saW5lYXJfc2NhdHRlcih0bXBfYl90KQp0dCRzY2F0dGVyCmE2MF9jbDE0Y2xicl90YWJsZSA9IGFsbF90YWJsZXMkYTYwX2NsMTRjbGJyCnRtcCA9IG1lcmdlKGE2MF9jbDE0Y2xicl90YWJsZSwgYTk2X2NsMTRjbGJyX3RhYmxlLCBieT0icm93Lm5hbWVzIikKdG1wX2JfdCA9IGRhdGEuZnJhbWUoYTYwPXRtcCR0LngsIGE5Nj10bXAkdC55KQp0dCA9IGhwZ2xfc2NhdHRlcih0bXBfYl90KQp0dCRzY2F0dGVyCmBgYAoKIyBLRwoKT2ggeWVhaCwgSSB3cm90ZSBhIHRveSB0byB3cmFwIEtFR0cgcGF0aHdheSBzdHVmZiwgbGV0cyB0cnkgdGhhdC4KVGhlIEtFR0cgYWJicmV2aWF0aW9uIGZvciB0LiBjcnV6aSBpcyB0Y3IKCkluIHRoZW9yeSwgdGhlIF9wYXRocyBkYXRhIHN0cnVjdHVyZSByZXR1cm5lZCBieSBocGdsX3BhdGh2aWV3KCkgc2hvdWxkIGJlIGEgdGFibGUKb2YgdGhlIG51bWVyIG9mIHVwL2Rvd24gZ2VuZXMgb2JzZXJ2ZWQgaW4gZWFjaCBLRUdHIHBhdGguICBIb3dldmVyLCB0aGVyZSBhcmUgc29tZQp3ZWlyZCBOQXMgZ2V0dGluZyByZXR1cm5lZC4gICBFZmZpbmcgaGlwcGllcy4gLS0gZml4ZWQuCgpgYGB7ciBrZWdnX2Z1bl92MX0Ka2VnZ19saXN0IDwtICIiCmBgYAoKYGBge3Iga2VnZ19mdW5fdjIsIGV2YWw9RkFMU0V9CiMjbmFtZXMoa2VnZ19saXN0KSA9IHJvd25hbWVzKGVwaV9jbDE0Y2xicl90YWJsZSkKIyNlcGlfY2wxNGNsYnJfcGF0aHMgPSBocGdsX3BhdGh2aWV3KGtlZ2dfbGlzdCwgc3BlY2llcz0idGNyIiwgaW5kaXI9InBhdGh2aWV3X2luIiwgb3V0ZGlyPSJwYXRodmlld19lcGlfY2wxNGNsYnIiLCBzdHJpbmdfZnJvbT0iVGNDTEIuIiwgc3RyaW5nX3RvPSIiKQojI2hlYWQoZXBpX2NsMTRjbGJyX3BhdGhzKQoKCiMjYTYwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyRhNjBfY2wxNGNsYnIKYTYwX2NsMTRjbGJyX3RhYmxlIDwtIHN0cmFpbl9jb21wYXJpc29ucyRkYXRhJGE2MF9jbGJyX292ZXJfY2wxNAojI2tlZ2dfbGlzdCA8LSBhNjBfY2wxNGNsYnJfdGFibGUkbG9nRkMKa2VnZ19saXN0IDwtIGE2MF9jbDE0Y2xicl90YWJsZSRsaW1tYV9sb2dmYwpuYW1lcyhrZWdnX2xpc3QpIDwtIHJvd25hbWVzKGE2MF9jbDE0Y2xicl90YWJsZSkKYTYwX2NsMTRjbGJyX3BhdGhzIDwtIGhwZ2xfcGF0aHZpZXcoa2VnZ19saXN0LCBzcGVjaWVzPSJ0Y3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRpcj0icGF0aHZpZXdfaW4iLCBvdXRkaXI9InBhdGh2aWV3X2E2MF9jbDE0Y2xiciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21fbGlzdD0iVGNDTEIuIiwgdG9fbGlzdD0iIikKaGVhZChhNjBfY2wxNGNsYnJfcGF0aHMpCgphOTZfY2wxNGNsYnJfdGFibGUgPSBhbGxfdGFibGVzJGE5Nl9jbDE0Y2xicgprZWdnX2xpc3QgPSBhOTZfY2wxNGNsYnJfdGFibGUkbG9nRkMKbmFtZXMoa2VnZ19saXN0KSA9IHJvd25hbWVzKGE5Nl9jbDE0Y2xicl90YWJsZSkKYTk2X2NsMTRjbGJyX3BhdGhzID0gaHBnbF9wYXRodmlldyhrZWdnX2xpc3QsIHNwZWNpZXM9InRjciIsIGluZGlyPSJwYXRodmlld19pbiIsIG91dGRpcj0icGF0aHZpZXdfYTk2X2NsMTRjbGJyIiwgc3RyaW5nX2Zyb209IlRjQ0xCLiIsIHN0cmluZ190bz0iIikKaGVhZChhOTZfY2wxNGNsYnJfcGF0aHMpCgp0cnlwX2NsMTRjbGJyX3RhYmxlID0gYWxsX3RhYmxlcyRhOTZfY2wxNGNsYnIKa2VnZ19saXN0ID0gdHJ5cF9jbDE0Y2xicl90YWJsZSRsb2dGQwpuYW1lcyhrZWdnX2xpc3QpID0gcm93bmFtZXModHJ5cF9jbDE0Y2xicl90YWJsZSkKdHJ5cF9jbDE0Y2xicl9wYXRocyA9IGhwZ2xfcGF0aHZpZXcoa2VnZ19saXN0LCBzcGVjaWVzPSJ0Y3IiLCBpbmRpcj0icGF0aHZpZXdfaW4iLCBvdXRkaXI9InBhdGh2aWV3X3RyeXBfY2wxNGNsYnIiLCBzdHJpbmdfZnJvbT0iVGNDTEIuIiwgc3RyaW5nX3RvPSIiKQpoZWFkKHRyeXBfY2wxNGNsYnJfcGF0aHMpCmBgYAo=