This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.
First, install the package dependencies required for this analysis. Required package libraries will be loaded in their respective steps.
#Install Package Dependencies
install.packages(c("readr", "survival", "ranger", "dplyr", "ggplot2", "ggfortify", "survminer","ggrepel", "tidyr", "tibble", "pheatmap", "stringr"))
BiocManager::install(c("edgeR", "EnhancedVolcano", "DESeq2", "limma"))
#Load Libraries
library(readr)
library(survival)
library(ranger)
library(ggplot2)
library(dplyr)
library(ggfortify)
library(survminer)
library(ggrepel)
library(tidyr)
library(tibble)
library(limma)
library(edgeR)
library(stringr)
Download the Input datasets onto your desktop directory to load into R (available in Supplementary Information).
For the first analysis (Univariate Cox-Proportional Hazards Model and Kaplain-Meier analysis of genes) we will use “GSEsurvgenes.csv” and “TCGAsurvgenes.csv”. These are survival data for Overall Survival and Progression Free Survival from the respective cohorts: GSE107943 and TCGA-CHOL, appended with gene expression information of the 3017 genes from the Immune Gene Signature (Table S1)
#Data Loading
setwd("~/Desktop/Datasets/")
GSEsurvgenes <- read_csv("~/Desktop/Datasets/GSEsurvgenes.csv")
TCGAsurvgenes <- read_csv("~/Desktop/Datasets/TCGAsurvgenes.csv")
colnames(GSEsurvgenes) <- gsub(x = colnames(GSEsurvgenes), pattern = "\\-", replacement = "")
colnames(TCGAsurvgenes) <- gsub(x = colnames(TCGAsurvgenes), pattern = "\\-", replacement = "")
#Preparing the function
covariatesGSE <- colnames(GSEsurvgenes[,6:2598])
covariatesTCGA <- colnames(TCGAsurvgenes[,6:2659])
univ_formulas1 <- sapply(covariatesGSE, function(x) as.formula(paste('Surv(OS,Death)~', x)))
univ_formulas2 <- sapply(covariatesTCGA, function(x) as.formula(paste('Surv(OS,Death)~', x)))
univ_models1 <- lapply(univ_formulas1, function(x){coxph(x, data = GSEsurvgenes)})
univ_models2 <- lapply(univ_formulas2, function(x){coxph(x, data = TCGAsurvgenes)})
# Applying the function and extracting the results
univ_GSEresults <- lapply(univ_models1,
function(x){
x <- summary(x)
p.value<-signif(x$wald["pvalue"], digits=2)
wald.test<-signif(x$wald["test"], digits=2)
beta<-signif(x$coef[1], digits=2);#coeficient beta
HR <-signif(x$coef[2], digits=2);#exp(beta)
HR.confint.lower <- signif(x$conf.int[,"lower .95"], 2)
HR.confint.upper <- signif(x$conf.int[,"upper .95"],2)
HR <- paste0(HR, " (",
HR.confint.lower, "-", HR.confint.upper, ")")
res<-c(beta, HR, wald.test, p.value)
names(res)<-c("beta", "HR (95% CI for HR)", "wald.test",
"p.value")
return(res)
#return(exp(cbind(coef(x),confint(x))))
})
resGSE <- t(as.data.frame(univ_GSEresults, check.names = FALSE))
resGSE <- as.data.frame(resGSE)
univ_TCGAresults <- lapply(univ_models2,
function(x){
x <- summary(x)
p.value<-signif(x$wald["pvalue"], digits=2)
wald.test<-signif(x$wald["test"], digits=2)
beta<-signif(x$coef[1], digits=2);#coeficient beta
HR <-signif(x$coef[2], digits=2);#exp(beta)
HR.confint.lower <- signif(x$conf.int[,"lower .95"], 2)
HR.confint.upper <- signif(x$conf.int[,"upper .95"],2)
HR <- paste0(HR, " (",
HR.confint.lower, "-", HR.confint.upper, ")")
res<-c(beta, HR, wald.test, p.value)
names(res)<-c("beta", "HR (95% CI for HR)", "wald.test",
"p.value")
return(res)
#return(exp(cbind(coef(x),confint(x))))
})
resTCGA <- t(as.data.frame(univ_TCGAresults, check.names = FALSE))
resTCGA <- as.data.frame(resTCGA)
#Write the output files
write.csv(resGSE, "~/Desktop/Datasets/TableS2.csv")
write.csv(resTCGA, "~/Desktop/Datasets/TableS3.csv")
#Draw a scatter plot depicting significant and insignificant genes
resTCGA$color <- "Insignificant"
resGSE$color <- "Insignificant"
resGSE <- separate(resGSE, `HR (95% CI for HR)`, into = c("HR", "CI"), sep = " (?=[^ ]+$)")
resTCGA <- separate(resTCGA, `HR (95% CI for HR)`, into = c("HR", "CI"), sep = " (?=[^ ]+$)")
resGSE[,c(1,2,4,5)] <- sapply(resGSE[,c(1,2,4,5)], as.numeric)
resTCGA[,c(1,2,4,5)] <- sapply(resTCGA[,c(1,2,4,5)], as.numeric)
resTCGA$color[resTCGA$HR > 1 & resTCGA$p.value < 0.05] <- "Significant"
resGSE$color[resGSE$HR > 1 & resGSE$p.value < 0.05] <- "Significant"
#GSE Scatter Plot
ggplot(data=resGSE, aes(x=HR, y=-log10(p.value), col = color, label= rownames(resGSE))) +
geom_point() +
theme_minimal() +
geom_text_repel() +
scale_color_manual(values=c("black", "blue"))+xlim(0, 5) + geom_vline(xintercept= 1, col="red") + geom_hline(yintercept = 1.3, col = "red")
Warning: Removed 80 rows containing missing values (geom_point).
Warning: Removed 80 rows containing missing values (geom_text_repel).
Warning: ggrepel: 2482 unlabeled data points (too many overlaps). Consider increasing max.overlaps

#TCGA Scatter Plot
ggplot(data=resTCGA, aes(x=HR, y=-log10(p.value), col = color, label= rownames(resTCGA))) +
geom_point() +
theme_minimal() +
geom_text_repel() +
scale_color_manual(values=c("black", "blue"))+xlim(0, 3) + geom_vline(xintercept= 1, col="red") + geom_hline(yintercept = 1.3, col = "red")
Warning: Removed 5 rows containing missing values (geom_point).
Warning: Removed 5 rows containing missing values (geom_text_repel).
Warning: ggrepel: 2641 unlabeled data points (too many overlaps). Consider increasing max.overlaps

NA
Now that we have identified the clinically relevant genes in each cohort, we have enlisted the mutual significant entities in Table S4. We will now use this gene list as the CCA Immune Signature to stratify samples. We will first load the gene expression datasets: “GSEds.csv” and “data_RNA_Seq_v2_expression_median.txt”
#Load Libraries
library(dplyr)
library(pheatmap)
library(tidyr)
library(tibble)
#Load Data
Microarrayds <- read_csv("~/Desktop/Datasets/Microarrayds.csv")
GSEds <- read_csv("~/Desktop/Datasets/GSEds.csv")
GSEds <- GSEds[,-1]
TCGAds <- read_tsv("~/Desktop/Datasets/data_RNA_Seq_v2_expression_median.txt")
TCGAds <- TCGAds[30:20531,-2]
TCGAds <- TCGAds %>% group_by(Hugo_Symbol) %>% summarize_all(mean)
# 26 mortality-associated immune-related genes
genelist <- c("GGH", "ANXA1", "GLIPR1", "PDK1", "TPM2", "SNPH", "DMBT1", "SIGLEC1", "KRT6B", "PFKFB4", "CENPW", "RACGAP1", "CDCA4", "BCAT1", "QPCT", "VTA1", "TTK", "PLOD2", "MRC1", "GCNT1", "SERPINB7", "TP63", "AURKA", "CEACAM3", "NRIP3", "DEPDC1")
#Filter datasets for CCA Immune Signature
GSEimmune <- filter(GSEds, GSEds$Genes %in% genelist)
GSEimmune <- column_to_rownames(GSEimmune, "Genes")
#GSEimmune <- GSEimmune[,-1]
TCGAimmune <- filter(TCGAds, TCGAds$Hugo_Symbol %in% genelist)
TCGAimmune <- column_to_rownames(TCGAimmune, "Hugo_Symbol")
Microarrayimmune <- filter(Microarrayds, Microarrayds$GeneID %in% genelist)
Microarrayimmune <- column_to_rownames(Microarrayimmune, "GeneID")
#Hierarchical Clustering
x= pheatmap(GSEimmune, scale = "row", border_color = NA,
breaks = seq(-1.5, 1.5, length.out = 101),
clustering_method = "complete",
clustering_distance_cols = "canberra",
cutree_cols = 2)
y = pheatmap(TCGAimmune, scale = "row", border_color = NA,
breaks = seq(-1.5, 1.5, length.out = 101),
clustering_method = "complete",
clustering_distance_cols = "canberra",
cutree_cols = 4)
z = pheatmap(Microarrayimmune, scale = "row", clustering_method = "complete", clustering_distance_cols = "canberra", breaks = seq(-1, 1, length.out = 101), show_colnames = F, cutree_cols = 4)
#Identify Cluster IDs
indGSE <- cutree(x$tree_col, k = 2)
indTCGA <- cutree(y$tree_col, k = 4)
indMA <- cutree(z$tree_col, k = 4)
indGSE <- as.data.frame(indGSE)
indTCGA <- as.data.frame(indTCGA)
indMA <- as.data.frame(indMA)
indGSE$indGSE <- sapply(indGSE$indGSE, as.factor)
indTCGA$indTCGA <- sapply(indTCGA$indTCGA, as.factor)
indMA$indMA <- sapply(indMA$indMA, as.factor)
indMA$anno <- "High"
indMA$anno[indMA$indMA == 1] <- "Intermediate"
indMA$anno[indMA$indMA == 4] <- "Low"
write.csv(indGSE, "~/Desktop/Datasets/GSEhclustidentifiers.csv")
write.csv(indTCGA, "~/Desktop/Datasets/TCGAhclustidentifiers.csv")
write.csv(indMA, "~/Desktop/Datasets/MAhclustidentifiers.csv")
#Draw Heatmap for GSEimmune
pheatmap(GSEimmune, scale = "row", border_color = NA,
breaks = seq(-1.5, 1.5, length.out = 101),
clustering_method = "complete",
clustering_distance_cols = "canberra",
cutree_cols = 2, annotation = indGSE, main ="GSE107943")

#Draw Heatmap for TCGAimmune
pheatmap(TCGAimmune, scale = "row", border_color = NA,
breaks = seq(-1.5, 1.5, length.out = 101),
clustering_method = "complete",
clustering_distance_cols = "canberra",
clustering_distance_rows = "manhattan",
cutree_cols = 4, annotation = indTCGA, main = "TCGA-CHOL")

#Draw Heatmap for Microarrayimmune
pheatmap(Microarrayimmune, scale = "row",
clustering_method = "complete",
clustering_distance_cols = "canberra",
breaks = seq(-1, 1, length.out = 101),
show_colnames = F, cutree_cols = 4, annotation = indMA, main = "Microarray Datasets")

Then, we applied Kaplan-Meier curve to elucidate the prognostic value of 26 immune gene signature classification in the pooled cohort of CCA patients (GSE107943 and TCGA-CHOL)
#Annotate Samples with Cluster Group name
indGSE$samples <- rownames(indGSE)
indGSE$anno <- "High"
indGSE$anno[indGSE$indGSE == 1] <- "Low"
indTCGA$samples <- rownames(indTCGA)
indTCGA$anno <- "High"
indTCGA$anno[indTCGA$indTCGA == 2] <- "Low"
annotation <- rbind(indGSE[,2:3], indTCGA[,2:3])
#Plot Kaplain-Meier Curve using the Cluster annotation as a factor
GSETCGA <- rbind(GSEsurvgenes[,1:5], TCGAsurvgenes[,1:5])
GSETCGA <- merge(GSETCGA, annotation, by.x = "Sample", by.y = "samples", all.y = TRUE)
km_fit <- survfit(Surv(OS, Death) ~ anno, data=GSETCGA)
ggsurv <- ggsurvplot(km_fit, data = GSETCGA, risk.table = TRUE, cumevents = TRUE, pval = TRUE, pval.method = TRUE, risk.table.col = "strata",
legend.labs=c("High", "Low"), palette = c("tomato", "cornflowerblue"))
ggsurv


We have identified low expressing and high expressing samples in each cohort. We would now like to assess the transcriptomic differences between these two groups, hence we will conduct Differential Gene Expression Analysis.
#Load Libraries and Pre-process Data
library(DESeq2)
library(EnhancedVolcano)
library(pheatmap)
library(dplyr)
library(tibble)
#Data Preprocessing
GSEds <- column_to_rownames(GSEds, "Genes")
counts.m <- as.matrix(GSEds)
LHgroup <- indGSE
dds <- DESeqDataSetFromMatrix(countData = round(counts.m),
colData = LHgroup,
design = ~ anno)
keep <- rowSums(counts(dds)) >= 10
summary(keep)
dds <- dds[keep,]
#Differential Gene Expression Analysis
dds <- DESeq(dds)
res <- results(dds)
res
resOrdered <- res[order(res$pvalue),]
summary(res)
sum(res$padj < 0.1, na.rm=TRUE)
res1 <- as.data.frame(res)
res1 <- filter(res1, res1$padj < 0.05, na.rm=TRUE)
write.csv(as.data.frame(resOrdered),
file="~/Desktop/Datasets/GSEimmune2DESeq2_HighLow.csv")
resSig <- subset(resOrdered, padj < 0.05)
resSig
write.csv(as.data.frame(resSig), file = "~/Desktop/Datasets/TableS5.csv")
#Plot PCA - GSE107943
rld <- rlog(dds, blind=TRUE)
rlog() may take a few minutes with 30 or more samples,
vst() is a much faster transformation
p <- plotPCA(rld, intgroup="anno")
p + scale_colour_manual(values = c("Low" = "cornflowerblue", "High" = "tomato"))

#Plot Volcano of Differentially Expressed Genes - GSE107943
EnhancedVolcano(res,
lab = rownames(res),
x = "log2FoldChange",
y = "padj",
ylim = c(0,4),
title = "GSE107943",
FCcutoff = log2(2),
pCutoff = 0.05,
legendPosition = "none",
xlim = c(-5,5))

#Plot Heatmap of Differentially Expressed Genes - GSE107943
hmapx = subset(counts.m, rownames(counts.m) %in% rownames(resSig))
anno = LHgroup[,2:3]
rownames(anno) = NULL
anno = column_to_rownames(anno, "samples")
hmapx = hmapx[,-1]
pheatmap(hmapx, breaks = seq(-1.5, 1.5, length.out = 101), scale = "row",
clustering_method = "complete", fontsize_row = 7, annotation_col = anno, annotation_colors = list(anno = c(Low = "cornflowerblue", High = "tomato")),
main = "GSE107943", border_color = NA, clustering_distance_cols = "canberra", annotation_names_col = F)

Now we will repeat this analysis for the TCGA-CHOL cohort
library(dplyr)
library(tibble)
library(tidyr)
#Repeat analysis in TCGA-CHOL cohort
#Data Pre-Processing
TCGAds = column_to_rownames(TCGAds, "Hugo_Symbol")
counts.m = as.matrix(TCGAds)
LHgroup = indTCGA
dds <- DESeqDataSetFromMatrix(countData = round(counts.m),
colData = LHgroup,
design = ~ anno)
keep <- rowSums(counts(dds)) >= 10
summary(keep)
dds <- dds[keep,]
#Differential Gene Expression Analysis
dds <- DESeq(dds)
res <- results(dds)
res
resOrdered <- res[order(res$pvalue),]
summary(res)
sum(res$padj < 0.1, na.rm=TRUE)
res1 = as.data.frame(res)
res1 = filter(res1, res1$padj < 0.05, na.rm=TRUE)
write.csv(as.data.frame(resOrdered),
file="~/Desktop/Datasets/TCGAimmune2DESeq2_HighLow.csv")
resSig <- subset(resOrdered, padj < 0.05)
resSig
write.csv(as.data.frame(resSig), file = "~/Desktop/Datasets/TableS6.csv")
#Plot PCA - TCGA-CHOL
rld <- rlog(dds, blind=TRUE)
rlog() may take a few minutes with 30 or more samples,
vst() is a much faster transformation
p = plotPCA(rld, intgroup="anno")
p + scale_colour_manual(values = c("Low" = "cornflowerblue", "High" = "tomato"))

#Plot Volcano of Differentially Expressed Genes
EnhancedVolcano(res,
lab = rownames(res),
x = "log2FoldChange",
y = "padj",
ylim = c(0,4),
title = "TCGA-CHOL",
FCcutoff = log2(2),
pCutoff = 0.05,
legendPosition = "none",
xlim = c(-5,5))

#Plot Heatmap of Differentially expressed genes
hmapx = subset(counts.m, rownames(counts.m) %in% rownames(resSig))
anno = LHgroup[,2:3]
rownames(anno) = NULL
anno = column_to_rownames(anno, "samples")
pheatmap(hmapx, breaks = seq(-1.5, 1.5, length.out = 101), show_colnames = T, scale = "row",
clustering_method = "complete", fontsize_row = 7, annotation_col = anno, annotation_colors = list(anno = c(Low = "cornflowerblue", High = "tomato")), clustering_distance_cols = "correlation",
main = "TCGA-CHOL", border_color = NA, annotation_names_col = F)

# Microarray DGE Validation
df <- as.data.frame(Microarrayds)
df = column_to_rownames(df, "GeneID")
counts <- as.matrix(df)
View(counts)
sample_id <- read_csv("~/Desktop/Datasets/MAhclustidentifiers.csv")
New names:
* `` -> ...1
Rows: 704 Columns: 3
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): ...1, anno
dbl (1): indMA
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(sample_id)
sample_id = filter(sample_id, sample_id$anno == "Low"| sample_id$anno == "High")
colnames(sample_id)[1] = "samples"
sample_id = column_to_rownames(sample_id, "samples")
counts = t(counts)
counts = subset(counts, rownames(counts) %in% rownames(sample_id))
counts = t(counts)
genelist <- rownames(counts)
genes = genelist
group <- sample_id$anno
counts.m<-as.matrix(counts)
is.numeric(counts.m)
[1] TRUE
#Remove genes that are 0
n <- which(is.na(counts.m))
counts.m[n]<-0
#Transformation from raw scale -->log2
counts.L = log2(counts.m + 1)
x <- DGEList(counts= counts.L, genes = genes, group = group, samples = sample_id$X1)
group <- as.factor(group)
x$samples$group <- group
x$genes <- genes
x <- calcNormFactors(x, method = "TMM")
#plotMDS for unsupervised clustering
par(mfrow=c(1,2))
group <- as.factor(group)
col.group <- group
levels(col.group) <- c("tomato", "cornflowerblue")
col.group <- as.character(col.group)
plotMDS(x, labels=group, col=col.group)

#title(main="Sample groups")



The differentially expressed gene list has been used as an input in iLINCS and EnrichR to obtain pathway enrichments and positively correlated connected perturbagens. These are presented in Table S6, S8, S10, S11 and S12. They have been visualized using the following script.
#Pathway Enrichment Plot
library(ggplot2)
Enrichment_GSE <- read_csv("~/Desktop/Datasets/Enrichment_GSE.csv")
Rows: 692 Columns: 10
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): Term, Overlap, Database
dbl (7): P-value, Adjusted P-value, Old P-value, Old Adjusted P-value, Odds Ratio, C...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Enrichment_TCGA <- read_csv("~/Desktop/Datasets/Enrichment_TCGA.csv")
Rows: 488 Columns: 10
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): Term, Overlap, Database
dbl (7): P-value, Adjusted P-value, Old P-value, Old Adjusted P-value, Odds Ratio, C...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Enrichment_MA <- read_csv("~/Desktop/Datasets/Enrichment_MA.csv")
Rows: 453 Columns: 10
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): Term, Overlap, Database
dbl (7): P-value, Adjusted P-value, Old P-value, Old Adjusted P-value, Odds Ratio, C...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ds <- data.frame(cbind(Enrichment_GSE$`Term`, Enrichment_GSE$`DEGs`, Enrichment_GSE$`Combined Score`, Enrichment_GSE$`Adjusted P-value`, Enrichment_GSE$Database))
colnames(ds) <- c("Pathways", "DEGs", "Combined Score", "Adjusted P.val", "Database")
Enrichment_GSE <- as.data.frame(Enrichment_GSE)
ds[,c(2:4)] <- sapply(ds[,c(2:4)], as.numeric)
pathway_GSE = ggplot(ds ,aes(x= `Combined Score`,
y= Pathways, size = DEGs))+geom_point(aes(col= `Adjusted P.val`), alpha=0.8)+scale_colour_gradient(low = "red", high = "blue")+scale_y_discrete(labels = function(x) str_wrap(x, width = 10))+facet_grid(~Database)+xlim(0, 500)
pathway_GSE
Warning: Removed 2 rows containing missing values (geom_point).

ds <- data.frame(cbind(Enrichment_TCGA$`Term`, Enrichment_TCGA$`DEGs`, Enrichment_TCGA$`Combined Score`, Enrichment_TCGA$`Adjusted P-value`, Enrichment_TCGA$Database))
colnames(ds) <- c("Pathways", "DEGs", "Combined Score", "Adjusted P.val", "Database")
Enrichment_TCGA <- as.data.frame(Enrichment_TCGA)
ds[,c(2:4)] <- sapply(ds[,c(2:4)], as.numeric)
pathway_TCGA <- ggplot(ds ,aes(x= `Combined Score`,
y= Pathways, size = DEGs))+geom_point(aes(col= `Adjusted P.val`), alpha=0.8)+scale_colour_gradient(low = "red", high = "blue")+scale_y_discrete(labels = function(x) str_wrap(x, width = 10))+facet_grid(~Database)+xlim(0, 500)
pathway_TCGA
Warning: Removed 1 rows containing missing values (geom_point).

ds = data.frame(cbind(Enrichment_MA$`Term`, Enrichment_MA$`DEGs`, Enrichment_MA$`Combined Score`, Enrichment_MA$`Adjusted P-value`, Enrichment_MA$Database))
colnames(ds) <- c("Pathways", "DEGs", "Combined Score", "Adjusted P.val", "Database")
Enrichment_MA <- as.data.frame(Enrichment_MA)
ds[,c(2:4)] <- sapply(ds[,c(2:4)], as.numeric)
pathway_MA <- ggplot(ds ,aes(x= `Combined Score`,
y= Pathways, size = DEGs))+geom_point(aes(col= `Adjusted P.val`), alpha=0.8)+scale_colour_gradient(low = "red", high = "blue")+scale_y_discrete(labels = function(x) str_wrap(x, width = 10))+facet_grid(~Database)+xlim(0, 500)
pathway_MA

#Connected Perturbagens Plot
GSEdrugs <- read_tsv("~/Desktop/Datasets/GSEdrugs.txt")
Rows: 312 Columns: 7
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (4): PerturbagenId, Perturbagen, GeneTargets, Correlation
dbl (3): NoOfSignatures, pValue, zScore
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
TCGAdrugs <- read_tsv("~/Desktop/Datasets/TCGAdrugs.txt")
Rows: 1604 Columns: 7
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (4): PerturbagenId, Perturbagen, GeneTargets, Correlation
dbl (3): NoOfSignatures, pValue, zScore
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
MAdrugs <- read_tsv("~/Desktop/Datasets/MAdrugs.txt")
Rows: 1780 Columns: 7
── Column specification ────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (4): PerturbagenId, Perturbagen, GeneTargets, Correlation
dbl (3): NoOfSignatures, pValue, zScore
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
GSEdrugs %>% arrange(desc(zScore)) %>% head(25) %>%ggplot(aes(reorder(Perturbagen, zScore), zScore))+
geom_col(aes(fill = pValue)) +
scale_fill_gradient(low = "darkgoldenrod1",
high = "darkgoldenrod4") +
scale_x_discrete(labels = function(x) str_wrap(x, width = 10))+
coord_flip() +
labs(x = "Connected Perturbagens", y = "Z score")

TCGAdrugs %>% arrange(desc(zScore)) %>% head(25) %>%ggplot(aes(reorder(Perturbagen, zScore), zScore))+
geom_col(aes(fill = pValue)) +
scale_fill_gradient(low = "darkolivegreen2",
high = "darkolivegreen4") +
coord_flip() +
labs(x = "Connected Perturbagens", y = "Z score")

MAdrugs %>% arrange(desc(zScore)) %>% head(25) %>%ggplot(aes(reorder(Perturbagen, zScore), zScore))+
geom_col(aes(fill = pValue)) +
scale_fill_gradient(low = "deepskyblue",
high = "deepskyblue4") +
coord_flip() +
labs(x = "Connected Perturbagens", y = "Z score")

LS0tCnRpdGxlOiAiUiBTY3JpcHQgZm9yIENDQSBJbW11bmUgU2lnbmF0dXJlIEFuYWx5c2lzIgphdXRob3I6ICJTaW1yYW4gVmVua2F0cmFtYW4gYW5kIFNvbWNoYWkgQ2h1dGlwb25ndGFuYXRlIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIAoKRmlyc3QsIGluc3RhbGwgdGhlIHBhY2thZ2UgZGVwZW5kZW5jaWVzIHJlcXVpcmVkIGZvciB0aGlzIGFuYWx5c2lzLiBSZXF1aXJlZCBwYWNrYWdlIGxpYnJhcmllcyB3aWxsIGJlIGxvYWRlZCBpbiB0aGVpciByZXNwZWN0aXZlIHN0ZXBzLgoKYGBge3J9CiNJbnN0YWxsIFBhY2thZ2UgRGVwZW5kZW5jaWVzIAppbnN0YWxsLnBhY2thZ2VzKGMoInJlYWRyIiwgInN1cnZpdmFsIiwgInJhbmdlciIsICJkcGx5ciIsICJnZ3Bsb3QyIiwgImdnZm9ydGlmeSIsICJzdXJ2bWluZXIiLCJnZ3JlcGVsIiwgInRpZHlyIiwgInRpYmJsZSIsICJwaGVhdG1hcCIsICJzdHJpbmdyIikpCkJpb2NNYW5hZ2VyOjppbnN0YWxsKGMoImVkZ2VSIiwgIkVuaGFuY2VkVm9sY2FubyIsICJERVNlcTIiLCAibGltbWEiKSkKYGBgCgpgYGB7cn0KI0xvYWQgTGlicmFyaWVzCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoc3Vydml2YWwpCmxpYnJhcnkocmFuZ2VyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dmb3J0aWZ5KQpsaWJyYXJ5KHN1cnZtaW5lcikKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHRpYmJsZSkKbGlicmFyeShsaW1tYSkKbGlicmFyeShlZGdlUikKbGlicmFyeShzdHJpbmdyKQpgYGAKCkRvd25sb2FkIHRoZSBJbnB1dCBkYXRhc2V0cyBvbnRvIHlvdXIgZGVza3RvcCBkaXJlY3RvcnkgdG8gbG9hZCBpbnRvIFIgKGF2YWlsYWJsZSBpbiBTdXBwbGVtZW50YXJ5IEluZm9ybWF0aW9uKS4gCgpGb3IgdGhlIGZpcnN0IGFuYWx5c2lzIChVbml2YXJpYXRlIENveC1Qcm9wb3J0aW9uYWwgSGF6YXJkcyBNb2RlbCBhbmQgS2FwbGFpbi1NZWllciBhbmFseXNpcyBvZiBnZW5lcykgd2Ugd2lsbCB1c2UgIkdTRXN1cnZnZW5lcy5jc3YiIGFuZCAiVENHQXN1cnZnZW5lcy5jc3YiLiBUaGVzZSBhcmUgc3Vydml2YWwgZGF0YSBmb3IgT3ZlcmFsbCBTdXJ2aXZhbCBhbmQgUHJvZ3Jlc3Npb24gRnJlZSBTdXJ2aXZhbCBmcm9tIHRoZSByZXNwZWN0aXZlIGNvaG9ydHM6IEdTRTEwNzk0MyBhbmQgVENHQS1DSE9MLCBhcHBlbmRlZCB3aXRoIGdlbmUgZXhwcmVzc2lvbiBpbmZvcm1hdGlvbiBvZiB0aGUgMzAxNyBnZW5lcyBmcm9tIHRoZSBJbW11bmUgR2VuZSBTaWduYXR1cmUgKFRhYmxlIFMxKQpgYGB7cn0KI0RhdGEgTG9hZGluZwpzZXR3ZCgifi9EZXNrdG9wL0RhdGFzZXRzLyIpCkdTRXN1cnZnZW5lcyA8LSByZWFkX2Nzdigifi9EZXNrdG9wL0RhdGFzZXRzL0dTRXN1cnZnZW5lcy5jc3YiKQpUQ0dBc3VydmdlbmVzIDwtIHJlYWRfY3N2KCJ+L0Rlc2t0b3AvRGF0YXNldHMvVENHQXN1cnZnZW5lcy5jc3YiKQpjb2xuYW1lcyhHU0VzdXJ2Z2VuZXMpIDwtIGdzdWIoeCA9IGNvbG5hbWVzKEdTRXN1cnZnZW5lcyksIHBhdHRlcm4gPSAiXFwtIiwgcmVwbGFjZW1lbnQgPSAiIikKY29sbmFtZXMoVENHQXN1cnZnZW5lcykgPC0gZ3N1Yih4ID0gY29sbmFtZXMoVENHQXN1cnZnZW5lcyksIHBhdHRlcm4gPSAiXFwtIiwgcmVwbGFjZW1lbnQgPSAiIikKYGBgCgpgYGB7cn0KI1ByZXBhcmluZyB0aGUgZnVuY3Rpb24KY292YXJpYXRlc0dTRSA8LSBjb2xuYW1lcyhHU0VzdXJ2Z2VuZXNbLDY6MjU5OF0pCmNvdmFyaWF0ZXNUQ0dBIDwtIGNvbG5hbWVzKFRDR0FzdXJ2Z2VuZXNbLDY6MjY1OV0pCnVuaXZfZm9ybXVsYXMxIDwtIHNhcHBseShjb3ZhcmlhdGVzR1NFLCBmdW5jdGlvbih4KSBhcy5mb3JtdWxhKHBhc3RlKCdTdXJ2KE9TLERlYXRoKX4nLCB4KSkpCnVuaXZfZm9ybXVsYXMyIDwtIHNhcHBseShjb3ZhcmlhdGVzVENHQSwgZnVuY3Rpb24oeCkgYXMuZm9ybXVsYShwYXN0ZSgnU3VydihPUyxEZWF0aCl+JywgeCkpKQp1bml2X21vZGVsczEgPC0gbGFwcGx5KHVuaXZfZm9ybXVsYXMxLCBmdW5jdGlvbih4KXtjb3hwaCh4LCBkYXRhID0gR1NFc3VydmdlbmVzKX0pCnVuaXZfbW9kZWxzMiA8LSBsYXBwbHkodW5pdl9mb3JtdWxhczIsIGZ1bmN0aW9uKHgpe2NveHBoKHgsIGRhdGEgPSBUQ0dBc3VydmdlbmVzKX0pCiMgQXBwbHlpbmcgdGhlIGZ1bmN0aW9uIGFuZCBleHRyYWN0aW5nIHRoZSByZXN1bHRzCnVuaXZfR1NFcmVzdWx0cyA8LSBsYXBwbHkodW5pdl9tb2RlbHMxLAogICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpeyAKICAgICAgICAgICAgICAgICAgICAgICAgIHggPC0gc3VtbWFyeSh4KQogICAgICAgICAgICAgICAgICAgICAgICAgcC52YWx1ZTwtc2lnbmlmKHgkd2FsZFsicHZhbHVlIl0sIGRpZ2l0cz0yKQogICAgICAgICAgICAgICAgICAgICAgICAgd2FsZC50ZXN0PC1zaWduaWYoeCR3YWxkWyJ0ZXN0Il0sIGRpZ2l0cz0yKQogICAgICAgICAgICAgICAgICAgICAgICAgYmV0YTwtc2lnbmlmKHgkY29lZlsxXSwgZGlnaXRzPTIpOyNjb2VmaWNpZW50IGJldGEKICAgICAgICAgICAgICAgICAgICAgICAgIEhSIDwtc2lnbmlmKHgkY29lZlsyXSwgZGlnaXRzPTIpOyNleHAoYmV0YSkKICAgICAgICAgICAgICAgICAgICAgICAgIEhSLmNvbmZpbnQubG93ZXIgPC0gc2lnbmlmKHgkY29uZi5pbnRbLCJsb3dlciAuOTUiXSwgMikKICAgICAgICAgICAgICAgICAgICAgICAgIEhSLmNvbmZpbnQudXBwZXIgPC0gc2lnbmlmKHgkY29uZi5pbnRbLCJ1cHBlciAuOTUiXSwyKQogICAgICAgICAgICAgICAgICAgICAgICAgSFIgPC0gcGFzdGUwKEhSLCAiICgiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIUi5jb25maW50Lmxvd2VyLCAiLSIsIEhSLmNvbmZpbnQudXBwZXIsICIpIikKICAgICAgICAgICAgICAgICAgICAgICAgIHJlczwtYyhiZXRhLCBIUiwgd2FsZC50ZXN0LCBwLnZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMocmVzKTwtYygiYmV0YSIsICJIUiAoOTUlIENJIGZvciBIUikiLCAid2FsZC50ZXN0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwLnZhbHVlIikKICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybihyZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAjcmV0dXJuKGV4cChjYmluZChjb2VmKHgpLGNvbmZpbnQoeCkpKSkKICAgICAgICAgICAgICAgICAgICAgICB9KQpyZXNHU0UgPC0gdChhcy5kYXRhLmZyYW1lKHVuaXZfR1NFcmVzdWx0cywgY2hlY2submFtZXMgPSBGQUxTRSkpCnJlc0dTRSA8LSBhcy5kYXRhLmZyYW1lKHJlc0dTRSkKCnVuaXZfVENHQXJlc3VsdHMgPC0gbGFwcGx5KHVuaXZfbW9kZWxzMiwKICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KXsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4IDwtIHN1bW1hcnkoeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAudmFsdWU8LXNpZ25pZih4JHdhbGRbInB2YWx1ZSJdLCBkaWdpdHM9MikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhbGQudGVzdDwtc2lnbmlmKHgkd2FsZFsidGVzdCJdLCBkaWdpdHM9MikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJldGE8LXNpZ25pZih4JGNvZWZbMV0sIGRpZ2l0cz0yKTsjY29lZmljaWVudCBiZXRhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIUiA8LXNpZ25pZih4JGNvZWZbMl0sIGRpZ2l0cz0yKTsjZXhwKGJldGEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIUi5jb25maW50Lmxvd2VyIDwtIHNpZ25pZih4JGNvbmYuaW50WywibG93ZXIgLjk1Il0sIDIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIUi5jb25maW50LnVwcGVyIDwtIHNpZ25pZih4JGNvbmYuaW50WywidXBwZXIgLjk1Il0sMikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhSIDwtIHBhc3RlMChIUiwgIiAoIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSFIuY29uZmludC5sb3dlciwgIi0iLCBIUi5jb25maW50LnVwcGVyLCAiKSIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXM8LWMoYmV0YSwgSFIsIHdhbGQudGVzdCwgcC52YWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzKHJlcyk8LWMoImJldGEiLCAiSFIgKDk1JSBDSSBmb3IgSFIpIiwgIndhbGQudGVzdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicC52YWx1ZSIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ocmVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgI3JldHVybihleHAoY2JpbmQoY29lZih4KSxjb25maW50KHgpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKcmVzVENHQSA8LSB0KGFzLmRhdGEuZnJhbWUodW5pdl9UQ0dBcmVzdWx0cywgY2hlY2submFtZXMgPSBGQUxTRSkpCnJlc1RDR0EgPC0gYXMuZGF0YS5mcmFtZShyZXNUQ0dBKQoKI1dyaXRlIHRoZSBvdXRwdXQgZmlsZXMKd3JpdGUuY3N2KHJlc0dTRSwgIn4vRGVza3RvcC9EYXRhc2V0cy9UYWJsZVMyLmNzdiIpCndyaXRlLmNzdihyZXNUQ0dBLCAifi9EZXNrdG9wL0RhdGFzZXRzL1RhYmxlUzMuY3N2IikKYGBgCgpgYGB7cn0KI0RyYXcgYSBzY2F0dGVyIHBsb3QgZGVwaWN0aW5nIHNpZ25pZmljYW50IGFuZCBpbnNpZ25pZmljYW50IGdlbmVzCnJlc1RDR0EkY29sb3IgPC0gIkluc2lnbmlmaWNhbnQiCnJlc0dTRSRjb2xvciA8LSAiSW5zaWduaWZpY2FudCIKcmVzR1NFIDwtIHNlcGFyYXRlKHJlc0dTRSwgYEhSICg5NSUgQ0kgZm9yIEhSKWAsIGludG8gPSBjKCJIUiIsICJDSSIpLCBzZXAgPSAiICg/PVteIF0rJCkiKQpyZXNUQ0dBIDwtIHNlcGFyYXRlKHJlc1RDR0EsIGBIUiAoOTUlIENJIGZvciBIUilgLCBpbnRvID0gYygiSFIiLCAiQ0kiKSwgc2VwID0gIiAoPz1bXiBdKyQpIikKcmVzR1NFWyxjKDEsMiw0LDUpXSA8LSBzYXBwbHkocmVzR1NFWyxjKDEsMiw0LDUpXSwgYXMubnVtZXJpYykKcmVzVENHQVssYygxLDIsNCw1KV0gPC0gc2FwcGx5KHJlc1RDR0FbLGMoMSwyLDQsNSldLCBhcy5udW1lcmljKQpyZXNUQ0dBJGNvbG9yW3Jlc1RDR0EkSFIgPiAxICYgcmVzVENHQSRwLnZhbHVlIDwgMC4wNV0gPC0gIlNpZ25pZmljYW50IgpyZXNHU0UkY29sb3JbcmVzR1NFJEhSID4gMSAmIHJlc0dTRSRwLnZhbHVlIDwgMC4wNV0gPC0gIlNpZ25pZmljYW50IgpgYGAKCmBgYHtyfQojR1NFIFNjYXR0ZXIgUGxvdApnZ3Bsb3QoZGF0YT1yZXNHU0UsIGFlcyh4PUhSLCB5PS1sb2cxMChwLnZhbHVlKSwgY29sID0gY29sb3IsIGxhYmVsPSByb3duYW1lcyhyZXNHU0UpKSkgKwpnZW9tX3BvaW50KCkgKwp0aGVtZV9taW5pbWFsKCkgKwpnZW9tX3RleHRfcmVwZWwoKSArCnNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiYmxhY2siLCAiYmx1ZSIpKSt4bGltKDAsIDUpICsgIGdlb21fdmxpbmUoeGludGVyY2VwdD0gMSwgY29sPSJyZWQiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEuMywgY29sID0gInJlZCIpCmBgYAoKYGBge3J9CiNUQ0dBIFNjYXR0ZXIgUGxvdApnZ3Bsb3QoZGF0YT1yZXNUQ0dBLCBhZXMoeD1IUiwgeT0tbG9nMTAocC52YWx1ZSksIGNvbCA9IGNvbG9yLCBsYWJlbD0gcm93bmFtZXMocmVzVENHQSkpKSArCmdlb21fcG9pbnQoKSArCnRoZW1lX21pbmltYWwoKSArCmdlb21fdGV4dF9yZXBlbCgpICsKc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJibGFjayIsICJibHVlIikpK3hsaW0oMCwgMykgKyAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PSAxLCBjb2w9InJlZCIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMS4zLCBjb2wgPSAicmVkIikKICAKYGBgCgpOb3cgdGhhdCB3ZSBoYXZlIGlkZW50aWZpZWQgdGhlIGNsaW5pY2FsbHkgcmVsZXZhbnQgZ2VuZXMgaW4gZWFjaCBjb2hvcnQsIHdlIGhhdmUgZW5saXN0ZWQgdGhlIG11dHVhbCBzaWduaWZpY2FudCBlbnRpdGllcyBpbiBUYWJsZSBTNC4gV2Ugd2lsbCBub3cgdXNlIHRoaXMgZ2VuZSBsaXN0IGFzIHRoZSBDQ0EgSW1tdW5lIFNpZ25hdHVyZSB0byBzdHJhdGlmeSBzYW1wbGVzLiBXZSB3aWxsIGZpcnN0IGxvYWQgdGhlIGdlbmUgZXhwcmVzc2lvbiBkYXRhc2V0czogIkdTRWRzLmNzdiIgYW5kICJkYXRhX1JOQV9TZXFfdjJfZXhwcmVzc2lvbl9tZWRpYW4udHh0IgpgYGB7cn0KI0xvYWQgTGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkodGliYmxlKQoKI0xvYWQgRGF0YQpNaWNyb2FycmF5ZHMgPC0gcmVhZF9jc3YoIn4vRGVza3RvcC9EYXRhc2V0cy9NaWNyb2FycmF5ZHMuY3N2IikKR1NFZHMgPC0gcmVhZF9jc3YoIn4vRGVza3RvcC9EYXRhc2V0cy9HU0Vkcy5jc3YiKQpHU0VkcyA8LSBHU0Vkc1ssLTFdClRDR0FkcyA8LSByZWFkX3Rzdigifi9EZXNrdG9wL0RhdGFzZXRzL2RhdGFfUk5BX1NlcV92Ml9leHByZXNzaW9uX21lZGlhbi50eHQiKQpUQ0dBZHMgPC0gVENHQWRzWzMwOjIwNTMxLC0yXQpUQ0dBZHMgPC0gVENHQWRzICU+JSBncm91cF9ieShIdWdvX1N5bWJvbCkgJT4lIHN1bW1hcml6ZV9hbGwobWVhbikKCiMgMjYgbW9ydGFsaXR5LWFzc29jaWF0ZWQgaW1tdW5lLXJlbGF0ZWQgZ2VuZXMKZ2VuZWxpc3QgPC0gYygiR0dIIiwgIkFOWEExIiwgIkdMSVBSMSIsICJQREsxIiwgIlRQTTIiLCAiU05QSCIsICJETUJUMSIsICJTSUdMRUMxIiwgIktSVDZCIiwgIlBGS0ZCNCIsICJDRU5QVyIsICJSQUNHQVAxIiwgIkNEQ0E0IiwgIkJDQVQxIiwgIlFQQ1QiLCAiVlRBMSIsICJUVEsiLCAiUExPRDIiLCAiTVJDMSIsICJHQ05UMSIsICJTRVJQSU5CNyIsICJUUDYzIiwgIkFVUktBIiwgIkNFQUNBTTMiLCAiTlJJUDMiLCAiREVQREMxIikKCiNGaWx0ZXIgZGF0YXNldHMgZm9yIENDQSBJbW11bmUgU2lnbmF0dXJlCkdTRWltbXVuZSA8LSBmaWx0ZXIoR1NFZHMsIEdTRWRzJEdlbmVzICVpbiUgZ2VuZWxpc3QpCkdTRWltbXVuZSA8LSBjb2x1bW5fdG9fcm93bmFtZXMoR1NFaW1tdW5lLCAiR2VuZXMiKQojR1NFaW1tdW5lIDwtIEdTRWltbXVuZVssLTFdClRDR0FpbW11bmUgPC0gZmlsdGVyKFRDR0FkcywgVENHQWRzJEh1Z29fU3ltYm9sICVpbiUgZ2VuZWxpc3QpClRDR0FpbW11bmUgPC0gY29sdW1uX3RvX3Jvd25hbWVzKFRDR0FpbW11bmUsICJIdWdvX1N5bWJvbCIpCk1pY3JvYXJyYXlpbW11bmUgPC0gZmlsdGVyKE1pY3JvYXJyYXlkcywgTWljcm9hcnJheWRzJEdlbmVJRCAlaW4lIGdlbmVsaXN0KQpNaWNyb2FycmF5aW1tdW5lIDwtIGNvbHVtbl90b19yb3duYW1lcyhNaWNyb2FycmF5aW1tdW5lLCAiR2VuZUlEIikKCiNIaWVyYXJjaGljYWwgQ2x1c3RlcmluZwp4PSBwaGVhdG1hcChHU0VpbW11bmUsIHNjYWxlID0gInJvdyIsIGJvcmRlcl9jb2xvciA9IE5BLCAKICAgICAgICAgYnJlYWtzID0gc2VxKC0xLjUsIDEuNSwgbGVuZ3RoLm91dCA9IDEwMSksIAogICAgICAgICBjbHVzdGVyaW5nX21ldGhvZCA9ICJjb21wbGV0ZSIsIAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiY2FuYmVycmEiLCAKICAgICAgICAgY3V0cmVlX2NvbHMgPSAyKQp5ID0gcGhlYXRtYXAoVENHQWltbXVuZSwgc2NhbGUgPSAicm93IiwgYm9yZGVyX2NvbG9yID0gTkEsIAogICAgICAgICBicmVha3MgPSBzZXEoLTEuNSwgMS41LCBsZW5ndGgub3V0ID0gMTAxKSwgCiAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gImNvbXBsZXRlIiwgCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJjYW5iZXJyYSIsIAogICAgICAgICBjdXRyZWVfY29scyA9IDQpCnogPSBwaGVhdG1hcChNaWNyb2FycmF5aW1tdW5lLCBzY2FsZSA9ICJyb3ciLCBjbHVzdGVyaW5nX21ldGhvZCA9ICJjb21wbGV0ZSIsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJjYW5iZXJyYSIsIGJyZWFrcyA9IHNlcSgtMSwgMSwgbGVuZ3RoLm91dCA9IDEwMSksIHNob3dfY29sbmFtZXMgPSBGLCBjdXRyZWVfY29scyA9IDQpCgojSWRlbnRpZnkgQ2x1c3RlciBJRHMKaW5kR1NFIDwtIGN1dHJlZSh4JHRyZWVfY29sLCBrID0gMikKaW5kVENHQSA8LSBjdXRyZWUoeSR0cmVlX2NvbCwgayA9IDQpCmluZE1BIDwtIGN1dHJlZSh6JHRyZWVfY29sLCBrID0gNCkKaW5kR1NFIDwtIGFzLmRhdGEuZnJhbWUoaW5kR1NFKQppbmRUQ0dBIDwtIGFzLmRhdGEuZnJhbWUoaW5kVENHQSkKaW5kTUEgPC0gYXMuZGF0YS5mcmFtZShpbmRNQSkKaW5kR1NFJGluZEdTRSA8LSBzYXBwbHkoaW5kR1NFJGluZEdTRSwgYXMuZmFjdG9yKQppbmRUQ0dBJGluZFRDR0EgPC0gc2FwcGx5KGluZFRDR0EkaW5kVENHQSwgYXMuZmFjdG9yKQppbmRNQSRpbmRNQSA8LSBzYXBwbHkoaW5kTUEkaW5kTUEsIGFzLmZhY3RvcikKaW5kTUEkYW5ubyA8LSAiSGlnaCIKaW5kTUEkYW5ub1tpbmRNQSRpbmRNQSA9PSAxXSA8LSAiSW50ZXJtZWRpYXRlIgppbmRNQSRhbm5vW2luZE1BJGluZE1BID09IDRdIDwtICJMb3ciCndyaXRlLmNzdihpbmRHU0UsICJ+L0Rlc2t0b3AvRGF0YXNldHMvR1NFaGNsdXN0aWRlbnRpZmllcnMuY3N2IikKd3JpdGUuY3N2KGluZFRDR0EsICJ+L0Rlc2t0b3AvRGF0YXNldHMvVENHQWhjbHVzdGlkZW50aWZpZXJzLmNzdiIpCndyaXRlLmNzdihpbmRNQSwgIn4vRGVza3RvcC9EYXRhc2V0cy9NQWhjbHVzdGlkZW50aWZpZXJzLmNzdiIpCmBgYAoKYGBge3J9CiNEcmF3IEhlYXRtYXAgZm9yIEdTRWltbXVuZQpwaGVhdG1hcChHU0VpbW11bmUsIHNjYWxlID0gInJvdyIsIGJvcmRlcl9jb2xvciA9IE5BLCAKICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgtMS41LCAxLjUsIGxlbmd0aC5vdXQgPSAxMDEpLCAKICAgICAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gImNvbXBsZXRlIiwgCiAgICAgICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX2NvbHMgPSAiY2FuYmVycmEiLCAKICAgICAgICAgICAgIGN1dHJlZV9jb2xzID0gMiwgYW5ub3RhdGlvbiA9IGluZEdTRSwgbWFpbiA9IkdTRTEwNzk0MyIpCmBgYAoKYGBge3J9CiNEcmF3IEhlYXRtYXAgZm9yIFRDR0FpbW11bmUKcGhlYXRtYXAoVENHQWltbXVuZSwgc2NhbGUgPSAicm93IiwgYm9yZGVyX2NvbG9yID0gTkEsIAogICAgICAgICAgICAgYnJlYWtzID0gc2VxKC0xLjUsIDEuNSwgbGVuZ3RoLm91dCA9IDEwMSksIAogICAgICAgICAgICAgY2x1c3RlcmluZ19tZXRob2QgPSAiY29tcGxldGUiLCAKICAgICAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJjYW5iZXJyYSIsIAogICAgICAgICAgICAgY2x1c3RlcmluZ19kaXN0YW5jZV9yb3dzID0gIm1hbmhhdHRhbiIsCiAgICAgICAgICAgICBjdXRyZWVfY29scyA9IDQsIGFubm90YXRpb24gPSBpbmRUQ0dBLCBtYWluID0gIlRDR0EtQ0hPTCIpCmBgYAoKYGBge3J9CiNEcmF3IEhlYXRtYXAgZm9yIE1pY3JvYXJyYXlpbW11bmUKcGhlYXRtYXAoTWljcm9hcnJheWltbXVuZSwgc2NhbGUgPSAicm93IiwgCiAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gImNvbXBsZXRlIiwgCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJjYW5iZXJyYSIsIAogICAgICAgICBicmVha3MgPSBzZXEoLTEsIDEsIGxlbmd0aC5vdXQgPSAxMDEpLCAKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEYsIGN1dHJlZV9jb2xzID0gNCwgYW5ub3RhdGlvbiA9IGluZE1BLCBtYWluID0gIk1pY3JvYXJyYXkgRGF0YXNldHMiKQpgYGAKClRoZW4sIHdlIGFwcGxpZWQgS2FwbGFuLU1laWVyIGN1cnZlIHRvIGVsdWNpZGF0ZSB0aGUgcHJvZ25vc3RpYyB2YWx1ZSBvZiAyNiBpbW11bmUgZ2VuZSBzaWduYXR1cmUgY2xhc3NpZmljYXRpb24gaW4gdGhlIHBvb2xlZCBjb2hvcnQgb2YgQ0NBIHBhdGllbnRzIChHU0UxMDc5NDMgYW5kIFRDR0EtQ0hPTCkgCmBgYHtyIEtNIHBsb3QsIGVjaG89VFJVRX0KI0Fubm90YXRlIFNhbXBsZXMgd2l0aCBDbHVzdGVyIEdyb3VwIG5hbWUKaW5kR1NFJHNhbXBsZXMgPC0gcm93bmFtZXMoaW5kR1NFKQppbmRHU0UkYW5ubyA8LSAiSGlnaCIKaW5kR1NFJGFubm9baW5kR1NFJGluZEdTRSA9PSAxXSA8LSAiTG93IgoKaW5kVENHQSRzYW1wbGVzIDwtIHJvd25hbWVzKGluZFRDR0EpCmluZFRDR0EkYW5ubyA8LSAiSGlnaCIKaW5kVENHQSRhbm5vW2luZFRDR0EkaW5kVENHQSA9PSAyXSA8LSAiTG93Igphbm5vdGF0aW9uIDwtIHJiaW5kKGluZEdTRVssMjozXSwgaW5kVENHQVssMjozXSkKI1Bsb3QgS2FwbGFpbi1NZWllciBDdXJ2ZSB1c2luZyB0aGUgQ2x1c3RlciBhbm5vdGF0aW9uIGFzIGEgZmFjdG9yCkdTRVRDR0EgPC0gcmJpbmQoR1NFc3VydmdlbmVzWywxOjVdLCBUQ0dBc3VydmdlbmVzWywxOjVdKQpHU0VUQ0dBIDwtIG1lcmdlKEdTRVRDR0EsIGFubm90YXRpb24sIGJ5LnggPSAiU2FtcGxlIiwgYnkueSA9ICJzYW1wbGVzIiwgYWxsLnkgPSBUUlVFKQprbV9maXQgPC0gc3VydmZpdChTdXJ2KE9TLCBEZWF0aCkgfiBhbm5vLCBkYXRhPUdTRVRDR0EpCmdnc3VydiA8LSBnZ3N1cnZwbG90KGttX2ZpdCwgZGF0YSA9IEdTRVRDR0EsICByaXNrLnRhYmxlID0gVFJVRSwgY3VtZXZlbnRzID0gVFJVRSwgcHZhbCA9IFRSVUUsIHB2YWwubWV0aG9kID0gVFJVRSwgcmlzay50YWJsZS5jb2wgPSAic3RyYXRhIiwgCiAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmxhYnM9YygiSGlnaCIsICJMb3ciKSwgcGFsZXR0ZSA9IGMoInRvbWF0byIsICJjb3JuZmxvd2VyYmx1ZSIpKQpnZ3N1cnYKYGBgCgpXZSBoYXZlIGlkZW50aWZpZWQgbG93IGV4cHJlc3NpbmcgYW5kIGhpZ2ggZXhwcmVzc2luZyBzYW1wbGVzIGluIGVhY2ggY29ob3J0LiBXZSB3b3VsZCBub3cgbGlrZSB0byBhc3Nlc3MgdGhlIHRyYW5zY3JpcHRvbWljIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlc2UgdHdvIGdyb3VwcywgaGVuY2Ugd2Ugd2lsbCBjb25kdWN0IERpZmZlcmVudGlhbCBHZW5lIEV4cHJlc3Npb24gQW5hbHlzaXMuCmBgYHtyfQojTG9hZCBMaWJyYXJpZXMgYW5kIFByZS1wcm9jZXNzIERhdGEKbGlicmFyeShERVNlcTIpCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpYmJsZSkKCiNEYXRhIFByZXByb2Nlc3NpbmcKR1NFZHMgPC0gY29sdW1uX3RvX3Jvd25hbWVzKEdTRWRzLCAiR2VuZXMiKQpjb3VudHMubSA8LSBhcy5tYXRyaXgoR1NFZHMpCkxIZ3JvdXAgPC0gaW5kR1NFCmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50RGF0YSA9IHJvdW5kKGNvdW50cy5tKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IExIZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduID0gfiBhbm5vKSAKa2VlcCA8LSByb3dTdW1zKGNvdW50cyhkZHMpKSA+PSAxMApzdW1tYXJ5KGtlZXApCmRkcyA8LSBkZHNba2VlcCxdCiNEaWZmZXJlbnRpYWwgR2VuZSBFeHByZXNzaW9uIEFuYWx5c2lzCmRkcyA8LSBERVNlcShkZHMpCnJlcyA8LSByZXN1bHRzKGRkcykKcmVzCnJlc09yZGVyZWQgPC0gcmVzW29yZGVyKHJlcyRwdmFsdWUpLF0Kc3VtbWFyeShyZXMpCnN1bShyZXMkcGFkaiA8IDAuMSwgbmEucm09VFJVRSkKcmVzMSA8LSBhcy5kYXRhLmZyYW1lKHJlcykKcmVzMSA8LSBmaWx0ZXIocmVzMSwgcmVzMSRwYWRqIDwgMC4wNSwgbmEucm09VFJVRSkKd3JpdGUuY3N2KGFzLmRhdGEuZnJhbWUocmVzT3JkZXJlZCksIAogICAgICAgICAgZmlsZT0ifi9EZXNrdG9wL0RhdGFzZXRzL0dTRWltbXVuZTJERVNlcTJfSGlnaExvdy5jc3YiKQpyZXNTaWcgPC0gc3Vic2V0KHJlc09yZGVyZWQsIHBhZGogPCAwLjA1KQpyZXNTaWcKd3JpdGUuY3N2KGFzLmRhdGEuZnJhbWUocmVzU2lnKSwgZmlsZSA9ICJ+L0Rlc2t0b3AvRGF0YXNldHMvVGFibGVTNS5jc3YiKQpgYGAKCmBgYHtyfQojUGxvdCBQQ0EgLSBHU0UxMDc5NDMKcmxkIDwtIHJsb2coZGRzLCBibGluZD1UUlVFKQpwIDwtIHBsb3RQQ0EocmxkLCBpbnRncm91cD0iYW5ubyIpCnAgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIkxvdyIgPSAiY29ybmZsb3dlcmJsdWUiLCAiSGlnaCIgPSAidG9tYXRvIikpCmBgYAoKYGBge3J9CiNQbG90IFZvbGNhbm8gb2YgRGlmZmVyZW50aWFsbHkgRXhwcmVzc2VkIEdlbmVzIC0gR1NFMTA3OTQzCkVuaGFuY2VkVm9sY2FubyhyZXMsCiAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhyZXMpLAogICAgICAgICAgICAgICAgeCA9ICJsb2cyRm9sZENoYW5nZSIsCiAgICAgICAgICAgICAgICB5ID0gInBhZGoiLAogICAgICAgICAgICAgICAgeWxpbSA9IGMoMCw0KSwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkdTRTEwNzk0MyIsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IGxvZzIoMiksCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgICAgICAgICAgeGxpbSA9IGMoLTUsNSkpCmBgYAoKYGBge3J9CiNQbG90IEhlYXRtYXAgb2YgRGlmZmVyZW50aWFsbHkgRXhwcmVzc2VkIEdlbmVzIC0gR1NFMTA3OTQzCmhtYXB4ID0gc3Vic2V0KGNvdW50cy5tLCByb3duYW1lcyhjb3VudHMubSkgJWluJSByb3duYW1lcyhyZXNTaWcpKQphbm5vID0gTEhncm91cFssMjozXQpyb3duYW1lcyhhbm5vKSA9IE5VTEwKYW5ubyA9IGNvbHVtbl90b19yb3duYW1lcyhhbm5vLCAic2FtcGxlcyIpCmhtYXB4ID0gaG1hcHhbLC0xXQpwaGVhdG1hcChobWFweCwgYnJlYWtzID0gc2VxKC0xLjUsIDEuNSwgbGVuZ3RoLm91dCA9IDEwMSksIHNjYWxlID0gInJvdyIsCiAgICAgICAgIGNsdXN0ZXJpbmdfbWV0aG9kID0gImNvbXBsZXRlIiwgZm9udHNpemVfcm93ID0gNywgYW5ub3RhdGlvbl9jb2wgPSBhbm5vLCBhbm5vdGF0aW9uX2NvbG9ycyA9IGxpc3QoYW5ubyA9IGMoTG93ID0gImNvcm5mbG93ZXJibHVlIiwgSGlnaCA9ICJ0b21hdG8iKSksCiAgICAgICAgIG1haW4gPSAiR1NFMTA3OTQzIiwgYm9yZGVyX2NvbG9yID0gTkEsIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scyA9ICJjYW5iZXJyYSIsIGFubm90YXRpb25fbmFtZXNfY29sID0gRikKYGBgCgpOb3cgd2Ugd2lsbCByZXBlYXQgdGhpcyBhbmFseXNpcyBmb3IgdGhlIFRDR0EtQ0hPTCBjb2hvcnQKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHlyKQojUmVwZWF0IGFuYWx5c2lzIGluIFRDR0EtQ0hPTCBjb2hvcnQKI0RhdGEgUHJlLVByb2Nlc3NpbmcKVENHQWRzID0gY29sdW1uX3RvX3Jvd25hbWVzKFRDR0FkcywgIkh1Z29fU3ltYm9sIikKY291bnRzLm0gPSBhcy5tYXRyaXgoVENHQWRzKQpMSGdyb3VwID0gaW5kVENHQQpkZHMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGEgPSByb3VuZChjb3VudHMubSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGEgPSBMSGdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ24gPSB+IGFubm8pCmtlZXAgPC0gcm93U3Vtcyhjb3VudHMoZGRzKSkgPj0gMTAKc3VtbWFyeShrZWVwKQpkZHMgPC0gZGRzW2tlZXAsXQojRGlmZmVyZW50aWFsIEdlbmUgRXhwcmVzc2lvbiBBbmFseXNpcwpkZHMgPC0gREVTZXEoZGRzKQpyZXMgPC0gcmVzdWx0cyhkZHMpCnJlcwpyZXNPcmRlcmVkIDwtIHJlc1tvcmRlcihyZXMkcHZhbHVlKSxdCnN1bW1hcnkocmVzKQpzdW0ocmVzJHBhZGogPCAwLjEsIG5hLnJtPVRSVUUpCnJlczEgPSBhcy5kYXRhLmZyYW1lKHJlcykKcmVzMSA9IGZpbHRlcihyZXMxLCByZXMxJHBhZGogPCAwLjA1LCBuYS5ybT1UUlVFKQp3cml0ZS5jc3YoYXMuZGF0YS5mcmFtZShyZXNPcmRlcmVkKSwgCiAgICAgICAgICBmaWxlPSJ+L0Rlc2t0b3AvRGF0YXNldHMvVENHQWltbXVuZTJERVNlcTJfSGlnaExvdy5jc3YiKQpyZXNTaWcgPC0gc3Vic2V0KHJlc09yZGVyZWQsIHBhZGogPCAwLjA1KQpyZXNTaWcKd3JpdGUuY3N2KGFzLmRhdGEuZnJhbWUocmVzU2lnKSwgZmlsZSA9ICJ+L0Rlc2t0b3AvRGF0YXNldHMvVGFibGVTNi5jc3YiKQpgYGAKCmBgYHtyfQojUGxvdCBQQ0EgLSBUQ0dBLUNIT0wKcmxkIDwtIHJsb2coZGRzLCBibGluZD1UUlVFKQpwID0gcGxvdFBDQShybGQsIGludGdyb3VwPSJhbm5vIikKcCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiTG93IiA9ICJjb3JuZmxvd2VyYmx1ZSIsICJIaWdoIiA9ICJ0b21hdG8iKSkKYGBgCgpgYGB7cn0KI1Bsb3QgVm9sY2FubyBvZiBEaWZmZXJlbnRpYWxseSBFeHByZXNzZWQgR2VuZXMKRW5oYW5jZWRWb2xjYW5vKHJlcywKICAgICAgICAgICAgICAgIGxhYiA9IHJvd25hbWVzKHJlcyksCiAgICAgICAgICAgICAgICB4ID0gImxvZzJGb2xkQ2hhbmdlIiwKICAgICAgICAgICAgICAgIHkgPSAicGFkaiIsCiAgICAgICAgICAgICAgICB5bGltID0gYygwLDQpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiVENHQS1DSE9MIiwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gbG9nMigyKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgICAgICAgICB4bGltID0gYygtNSw1KSkKYGBgCgpgYGB7cn0KI1Bsb3QgSGVhdG1hcCBvZiBEaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMKaG1hcHggPSBzdWJzZXQoY291bnRzLm0sIHJvd25hbWVzKGNvdW50cy5tKSAlaW4lIHJvd25hbWVzKHJlc1NpZykpCmFubm8gPSBMSGdyb3VwWywyOjNdCnJvd25hbWVzKGFubm8pID0gTlVMTAphbm5vID0gY29sdW1uX3RvX3Jvd25hbWVzKGFubm8sICJzYW1wbGVzIikKcGhlYXRtYXAoaG1hcHgsIGJyZWFrcyA9IHNlcSgtMS41LCAxLjUsIGxlbmd0aC5vdXQgPSAxMDEpLCBzaG93X2NvbG5hbWVzID0gVCwgc2NhbGUgPSAicm93IiwKICAgICAgICAgY2x1c3RlcmluZ19tZXRob2QgPSAiY29tcGxldGUiLCBmb250c2l6ZV9yb3cgPSA3LCBhbm5vdGF0aW9uX2NvbCA9IGFubm8sIGFubm90YXRpb25fY29sb3JzID0gbGlzdChhbm5vID0gYyhMb3cgPSAiY29ybmZsb3dlcmJsdWUiLCBIaWdoID0gInRvbWF0byIpKSwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImNvcnJlbGF0aW9uIiwKICAgICAgICAgbWFpbiA9ICJUQ0dBLUNIT0wiLCBib3JkZXJfY29sb3IgPSBOQSwgYW5ub3RhdGlvbl9uYW1lc19jb2wgPSBGKSAKYGBgCgpgYGB7cn0KIyBNaWNyb2FycmF5IERHRSBWYWxpZGF0aW9uCmRmIDwtIGFzLmRhdGEuZnJhbWUoTWljcm9hcnJheWRzKQpkZiA9IGNvbHVtbl90b19yb3duYW1lcyhkZiwgIkdlbmVJRCIpCmNvdW50cyA8LSBhcy5tYXRyaXgoZGYpCnNhbXBsZV9pZCA8LSByZWFkX2Nzdigifi9EZXNrdG9wL0RhdGFzZXRzL01BaGNsdXN0aWRlbnRpZmllcnMuY3N2IikKc2FtcGxlX2lkID0gZmlsdGVyKHNhbXBsZV9pZCwgc2FtcGxlX2lkJGFubm8gPT0gIkxvdyJ8IHNhbXBsZV9pZCRhbm5vID09ICJIaWdoIikKY29sbmFtZXMoc2FtcGxlX2lkKVsxXSA9ICJzYW1wbGVzIgpzYW1wbGVfaWQgPSBjb2x1bW5fdG9fcm93bmFtZXMoc2FtcGxlX2lkLCAic2FtcGxlcyIpCmNvdW50cyA9IHQoY291bnRzKQpjb3VudHMgPSBzdWJzZXQoY291bnRzLCByb3duYW1lcyhjb3VudHMpICVpbiUgcm93bmFtZXMoc2FtcGxlX2lkKSkKY291bnRzID0gdChjb3VudHMpCmdlbmVsaXN0IDwtIHJvd25hbWVzKGNvdW50cykKZ2VuZXMgPSBnZW5lbGlzdApncm91cCA8LSBzYW1wbGVfaWQkYW5ubwpjb3VudHMubTwtYXMubWF0cml4KGNvdW50cykKaXMubnVtZXJpYyhjb3VudHMubSkKCiNSZW1vdmUgZ2VuZXMgdGhhdCBhcmUgMCAKbiA8LSB3aGljaChpcy5uYShjb3VudHMubSkpCmNvdW50cy5tW25dPC0wCgojVHJhbnNmb3JtYXRpb24gZnJvbSByYXcgIHNjYWxlIC0tPmxvZzIKY291bnRzLkwgPSBsb2cyKGNvdW50cy5tICsgMSkKeCA8LSBER0VMaXN0KGNvdW50cz0gY291bnRzLkwsIGdlbmVzID0gZ2VuZXMsIGdyb3VwID0gZ3JvdXAsIHNhbXBsZXMgPSBzYW1wbGVfaWQkWDEpCmdyb3VwIDwtIGFzLmZhY3Rvcihncm91cCkKeCRzYW1wbGVzJGdyb3VwIDwtIGdyb3VwCngkZ2VuZXMgPC0gZ2VuZXMKeCA8LSBjYWxjTm9ybUZhY3RvcnMoeCwgbWV0aG9kID0gIlRNTSIpCgojcGxvdE1EUyBmb3IgdW5zdXBlcnZpc2VkIGNsdXN0ZXJpbmcKcGFyKG1mcm93PWMoMSwyKSkKZ3JvdXAgPC0gYXMuZmFjdG9yKGdyb3VwKQpjb2wuZ3JvdXAgPC0gZ3JvdXAKbGV2ZWxzKGNvbC5ncm91cCkgPC0gIGMoInRvbWF0byIsICJjb3JuZmxvd2VyYmx1ZSIpCmNvbC5ncm91cCA8LSBhcy5jaGFyYWN0ZXIoY29sLmdyb3VwKQpwbG90TURTKHgsIGxhYmVscz1ncm91cCwgY29sPWNvbC5ncm91cCkKI3RpdGxlKG1haW49IlNhbXBsZSBncm91cHMiKQpgYGAKCmBgYHtyfQojM0QgcGxvdHMgLSBNaWNyb2FycmF5IGRhdGFzZXQKbGlicmFyeShyZ2wpCgojQ29tcHV0ZSBQQ0EKcCA8LSBjb3VudHMuTApwLnQgPC0gdChwKQpwLnRfZGYgPC0gYXMuZGF0YS5mcmFtZShwLnQpCnBjYSA8LSBwcmNvbXAocC50X2RmKQpzY29yZXMgPSBhcy5kYXRhLmZyYW1lKHBjYSR4KQpzdW1tYXJ5KHBjYSkKcGxvdDNkKHNjb3Jlcywgc2l6ZT0xMCwgdHlwZT0ncCcsIGNvbCA9IGNvbC5ncm91cCkKI3RleHQzZChzY29yZXMsIHRleHRzPWMoZ3JvdXApLCBjZXg9IDAuNywgcG9zPTMpCgojVG8gc2F2ZSB0aGUgYW5pbWF0ZWQgUENBIGdyYXBocwpkaXIuY3JlYXRlKCJ+L0Rlc2t0b3AvRGF0YXNldHMvYW5pbWF0aW9uX21lcmdlIikKZm9yIChpIGluIDE6MzYwKSB7CiAgdmlldzNkKHVzZXJNYXRyaXg9cm90YXRpb25NYXRyaXgoMipwaSAqIGkvMzYwLCAwLCAxLCAwKSkKICByZ2wuc25hcHNob3QoZmlsZW5hbWU9cGFzdGUoIn4vRGVza3RvcC9EYXRhc2V0cy9hbmltYXRpb25fbWVyZ2UvZnJhbWUtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZigiJTAzZCIsIGkpLCAiLnBuZyIsIHNlcD0iIikpfQoKI0Rlc2lnbiBtYXRyaXgKIyBsaW5lYXIgbW9kZWxzIGFyZSBmaXR0ZWQgdG8gdGhlIGRhdGEgd2l0aCB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSB1bmRlcmx5aW5nIGRhdGEgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCiNhIGRlc2lnbiBtYXRyaXggaXMgc2V0IHVwIHdpdGggYm90aCB0aGUgY2x1c3RlciBncm91cHMgKGdyb3VwKSBhbmQgc3R1ZHkgKGJhdGNoKSBpbmZvcm1hdGlvbi4KZ3JvdXAgPC0gYXMuZmFjdG9yKGdyb3VwKQpkZXNpZ24gPC0gbW9kZWwubWF0cml4KH4wK2dyb3VwKQpjb2xuYW1lcyhkZXNpZ24pIDwtIGMoIkxvdyIsICJIaWdoIikKICAgICAgICAgICAgICAgICAgICAgCmRlc2lnbgoKY29udHIubWF0cml4IDwtIG1ha2VDb250cmFzdHMoKExvdyAtIEhpZ2gpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gY29sbmFtZXMoZGVzaWduKSkKY29udHIubWF0cml4CgojbGltbWEtdHJlbmQKZml0IDwtIGxtRml0KHgkY291bnRzLCBkZXNpZ24sIG1ldGhvZCA9ICJscyIpCmZpdCA8LSBjb250cmFzdHMuZml0KGZpdCwgY29udHJhc3RzID0gY29udHIubWF0cml4KQpmaXQgPC0gZUJheWVzKGZpdCwgdHJlbmQgPSBUUlVFKQp0b3BUYWJsZShmaXQpCgojVk9PTUEKdiA8LSB2b29tYSh4JGNvdW50cywgZGVzaWduLAogICAgICAgICAgIHBsb3Q9VFJVRSkKdiA8LSB2b29tYUJ5R3JvdXAoeCRjb3VudHMsIGdyb3VwLCBkZXNpZ24sIHBsb3QgPSBUUlVFKQp2CnZmaXQgPC0gbG1GaXQodiwgZGVzaWduLCBtZXRob2QgPSAibHMiKQp2Zml0IDwtIGNvbnRyYXN0cy5maXQodmZpdCwgY29udHJhc3RzPWNvbnRyLm1hdHJpeCkKZWZpdCA8LSBlQmF5ZXModmZpdCkKcGxvdFNBKGVmaXQsIG1haW49IkZpbmFsIG1vZGVsOiBNZWFuLXZhcmlhbmNlIHRyZW5kIikKYGBgCgpgYGB7cn0KI0V4YW1pbmluZyB0aGUgbnVtYmVyIG9mIERFIGdlbmVzIC0gTWljcm9hcnJheSBkYXRhc2V0CnN1bW1hcnkoZGVjaWRlVGVzdHMoZWZpdCkpCnRmaXQgPC0gdHJlYXQoZWZpdCwgbGZjPSBsb2cyKDEpKQpkdCA8LSBkZWNpZGVUZXN0cyh0Zml0LCBtZXRob2QgPSAiaGllcmFyY2hpY2FsIiwgCiAgICAgICAgICAgICAgICAgIGFkanVzdC5tZXRob2QgPSAiQkgiLCBsZmMgPSBsb2cyKDIpLCAKICAgICAgICAgICAgICAgICAgcC52YWx1ZSA9IDAuMDEpCnN1bW1hcnkoZHQpCndyaXRlLmZpdCh0Zml0LCByZXN1bHRzID0gZHQsICJ+L0Rlc2t0b3AvRGF0YXNldHMvTUFfREdFLnR4dCIsIGFkanVzdCA9ICJCSCIpCgp0b3BUbiA8LSB0b3BUYWJsZSh0Zml0LCBjb2VmID0gTlVMTCwgbnVtYmVyID0gSW5mLCBnZW5lbGlzdCA9IHRmaXQkZ2VuZXMsIGFkanVzdC5tZXRob2QgPSAiQkgiLCBwLnZhbHVlID0gMSwgbGZjID0gbG9nMigxKSwgc29ydC5ieSA9ICJsb2dGQyIpCnRvcFRuX3NpZyA8LSB0b3BUYWJsZSh0Zml0LCBjb2VmID0gTlVMTCwgbnVtYmVyID0gSW5mLCBnZW5lbGlzdCA9IHRmaXQkZ2VuZXMsIGFkanVzdC5tZXRob2QgPSAiQkgiLCBwLnZhbHVlID0gMC4wMSwgbGZjID0gbG9nMigyKSwgc29ydC5ieSA9ICJsb2dGQyIpCndyaXRlLmNzdih0b3BUbl9zaWcsIGZpbGUgPSAifi9EZXNrdG9wL0RhdGFzZXRzL01BX3RvcFRuX3NpZy5jc3YiKQpFbmhhbmNlZFZvbGNhbm8odG9wVG4sCiAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyh0b3BUbiksCiAgICAgICAgICAgICAgICB4ID0gImxvZ0ZDIiwKICAgICAgICAgICAgICAgIHkgPSAiYWRqLlAuVmFsIiwKICAgICAgICAgICAgICAgIHhsaW0gPSBjKC01LCA1KSwKICAgICAgICAgICAgICAgIHlsaW0gPSBjKC0xLCAzMDApLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTWljcm9hcnJheSBER0UiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDEsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IGxvZzIoMiksCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAyLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCmBgYHtyfQojaGVhdG1hcCAtIE1pY3JvYXJyYXkgZGF0YXNldApjbHVzdGVyID0gYXMuZGF0YS5mcmFtZShncm91cCkKcm93bmFtZXMoY2x1c3RlcikgPSByb3duYW1lcyhzYW1wbGVfaWQpCmhtYXB4ID0gc3Vic2V0KGNvdW50cy5MLCByb3duYW1lcyhjb3VudHMuTCkgJWluJSByb3duYW1lcyh0b3BUbikpCnBoZWF0bWFwKGhtYXB4LCBicmVha3MgPSBzZXEoLTEuNSwgMS41LCBsZW5ndGgub3V0ID0gMTAxKSwgc2NhbGUgPSAicm93IiwgY2x1c3RlcmluZ19tZXRob2QgPSAiY29tcGxldGUiLCBmb250c2l6ZV9yb3cgPSA3LCBhbm5vdGF0aW9uX2NvbCA9IGNsdXN0ZXIsIGFubm90YXRpb25fY29sb3JzID0gbGlzdChjbHVzdGVyID0gYyhMb3cgPSAiY29ybmZsb3dlcmJsdWUiLCBIaWdoID0gInRvbWF0byIpKSwgY2x1c3RlcmluZ19kaXN0YW5jZV9jb2xzID0gImNvcnJlbGF0aW9uIiwgbWFpbiA9ICJNaWNyb2FycmF5IERHRSIsIGJvcmRlcl9jb2xvciA9IE5BLCBzaG93X2NvbG5hbWVzID0gRiwgYW5ub3RhdGlvbl9uYW1lc19jb2wgPSBGKSAKYGBgCgpUaGUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmUgbGlzdCBoYXMgYmVlbiB1c2VkIGFzIGFuIGlucHV0IGluIGlMSU5DUyBhbmQgRW5yaWNoUiB0byBvYnRhaW4gcGF0aHdheSBlbnJpY2htZW50cyBhbmQgcG9zaXRpdmVseSBjb3JyZWxhdGVkIGNvbm5lY3RlZCBwZXJ0dXJiYWdlbnMuIFRoZXNlIGFyZSBwcmVzZW50ZWQgaW4gVGFibGUgUzYsIFM4LCBTMTAsIFMxMSBhbmQgUzEyLiBUaGV5IGhhdmUgYmVlbiB2aXN1YWxpemVkIHVzaW5nIHRoZSBmb2xsb3dpbmcgc2NyaXB0LiAKYGBge3J9CiNQYXRod2F5IEVucmljaG1lbnQgUGxvdApsaWJyYXJ5KGdncGxvdDIpCkVucmljaG1lbnRfR1NFIDwtIHJlYWRfY3N2KCJ+L0Rlc2t0b3AvRGF0YXNldHMvRW5yaWNobWVudF9HU0UuY3N2IikKRW5yaWNobWVudF9UQ0dBIDwtIHJlYWRfY3N2KCJ+L0Rlc2t0b3AvRGF0YXNldHMvRW5yaWNobWVudF9UQ0dBLmNzdiIpCkVucmljaG1lbnRfTUEgPC0gcmVhZF9jc3YoIn4vRGVza3RvcC9EYXRhc2V0cy9FbnJpY2htZW50X01BLmNzdiIpCgpkcyA8LSBkYXRhLmZyYW1lKGNiaW5kKEVucmljaG1lbnRfR1NFJGBUZXJtYCwgRW5yaWNobWVudF9HU0UkYERFR3NgLCBFbnJpY2htZW50X0dTRSRgQ29tYmluZWQgU2NvcmVgLCBFbnJpY2htZW50X0dTRSRgQWRqdXN0ZWQgUC12YWx1ZWAsIEVucmljaG1lbnRfR1NFJERhdGFiYXNlKSkKY29sbmFtZXMoZHMpIDwtIGMoIlBhdGh3YXlzIiwgIkRFR3MiLCAiQ29tYmluZWQgU2NvcmUiLCAiQWRqdXN0ZWQgUC52YWwiLCAiRGF0YWJhc2UiKQpFbnJpY2htZW50X0dTRSA8LSBhcy5kYXRhLmZyYW1lKEVucmljaG1lbnRfR1NFKQpkc1ssYygyOjQpXSA8LSBzYXBwbHkoZHNbLGMoMjo0KV0sIGFzLm51bWVyaWMpCnBhdGh3YXlfR1NFID0gZ2dwbG90KGRzICxhZXMoeD0gYENvbWJpbmVkIFNjb3JlYCwgCiAgICAgICAgICAgICAgICAgIHk9IFBhdGh3YXlzLCBzaXplID0gREVHcykpK2dlb21fcG9pbnQoYWVzKGNvbD0gYEFkanVzdGVkIFAudmFsYCksIGFscGhhPTAuOCkrc2NhbGVfY29sb3VyX2dyYWRpZW50KGxvdyA9ICJyZWQiLCBoaWdoID0gImJsdWUiKStzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHN0cl93cmFwKHgsIHdpZHRoID0gMTApKStmYWNldF9ncmlkKH5EYXRhYmFzZSkreGxpbSgwLCA1MDApCnBhdGh3YXlfR1NFIApgYGAKCmBgYHtyfQpkcyA8LSBkYXRhLmZyYW1lKGNiaW5kKEVucmljaG1lbnRfVENHQSRgVGVybWAsIEVucmljaG1lbnRfVENHQSRgREVHc2AsIEVucmljaG1lbnRfVENHQSRgQ29tYmluZWQgU2NvcmVgLCBFbnJpY2htZW50X1RDR0EkYEFkanVzdGVkIFAtdmFsdWVgLCBFbnJpY2htZW50X1RDR0EkRGF0YWJhc2UpKQpjb2xuYW1lcyhkcykgPC0gYygiUGF0aHdheXMiLCAiREVHcyIsICJDb21iaW5lZCBTY29yZSIsICJBZGp1c3RlZCBQLnZhbCIsICJEYXRhYmFzZSIpCkVucmljaG1lbnRfVENHQSA8LSBhcy5kYXRhLmZyYW1lKEVucmljaG1lbnRfVENHQSkKZHNbLGMoMjo0KV0gPC0gc2FwcGx5KGRzWyxjKDI6NCldLCBhcy5udW1lcmljKQoKcGF0aHdheV9UQ0dBIDwtIGdncGxvdChkcyAsYWVzKHg9IGBDb21iaW5lZCBTY29yZWAsIAogICAgICAgICAgICAgICAgICAgeT0gUGF0aHdheXMsIHNpemUgPSBERUdzKSkrZ2VvbV9wb2ludChhZXMoY29sPSBgQWRqdXN0ZWQgUC52YWxgKSwgYWxwaGE9MC44KStzY2FsZV9jb2xvdXJfZ3JhZGllbnQobG93ID0gInJlZCIsIGhpZ2ggPSAiYmx1ZSIpK3NjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyX3dyYXAoeCwgd2lkdGggPSAxMCkpK2ZhY2V0X2dyaWQofkRhdGFiYXNlKSt4bGltKDAsIDUwMCkKcGF0aHdheV9UQ0dBCmBgYAoKYGBge3J9CmRzID0gZGF0YS5mcmFtZShjYmluZChFbnJpY2htZW50X01BJGBUZXJtYCwgRW5yaWNobWVudF9NQSRgREVHc2AsIEVucmljaG1lbnRfTUEkYENvbWJpbmVkIFNjb3JlYCwgRW5yaWNobWVudF9NQSRgQWRqdXN0ZWQgUC12YWx1ZWAsIEVucmljaG1lbnRfTUEkRGF0YWJhc2UpKQpjb2xuYW1lcyhkcykgPC0gYygiUGF0aHdheXMiLCAiREVHcyIsICJDb21iaW5lZCBTY29yZSIsICJBZGp1c3RlZCBQLnZhbCIsICJEYXRhYmFzZSIpCkVucmljaG1lbnRfTUEgPC0gYXMuZGF0YS5mcmFtZShFbnJpY2htZW50X01BKQpkc1ssYygyOjQpXSA8LSBzYXBwbHkoZHNbLGMoMjo0KV0sIGFzLm51bWVyaWMpCnBhdGh3YXlfTUEgPC0gZ2dwbG90KGRzICxhZXMoeD0gYENvbWJpbmVkIFNjb3JlYCwgCiAgICAgICAgICAgICAgICAgIHk9IFBhdGh3YXlzLCBzaXplID0gREVHcykpK2dlb21fcG9pbnQoYWVzKGNvbD0gYEFkanVzdGVkIFAudmFsYCksIGFscGhhPTAuOCkrc2NhbGVfY29sb3VyX2dyYWRpZW50KGxvdyA9ICJyZWQiLCBoaWdoID0gImJsdWUiKStzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHN0cl93cmFwKHgsIHdpZHRoID0gMTApKStmYWNldF9ncmlkKH5EYXRhYmFzZSkreGxpbSgwLCA1MDApCnBhdGh3YXlfTUEKYGBgCgpgYGB7cn0KI0Nvbm5lY3RlZCBQZXJ0dXJiYWdlbnMgUGxvdApHU0VkcnVncyA8LSByZWFkX3Rzdigifi9EZXNrdG9wL0RhdGFzZXRzL0dTRWRydWdzLnR4dCIpClRDR0FkcnVncyA8LSByZWFkX3Rzdigifi9EZXNrdG9wL0RhdGFzZXRzL1RDR0FkcnVncy50eHQiKQpNQWRydWdzIDwtIHJlYWRfdHN2KCJ+L0Rlc2t0b3AvRGF0YXNldHMvTUFkcnVncy50eHQiKQoKR1NFZHJ1Z3MgJT4lIGFycmFuZ2UoZGVzYyh6U2NvcmUpKSAlPiUgaGVhZCgyNSkgJT4lZ2dwbG90KGFlcyhyZW9yZGVyKFBlcnR1cmJhZ2VuLCB6U2NvcmUpLCB6U2NvcmUpKSsgCiAgZ2VvbV9jb2woYWVzKGZpbGwgPSBwVmFsdWUpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImRhcmtnb2xkZW5yb2QxIiwgCiAgICAgICAgICAgICAgICAgICAgICBoaWdoID0gImRhcmtnb2xkZW5yb2Q0IikgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyX3dyYXAoeCwgd2lkdGggPSAxMCkpKwogIGNvb3JkX2ZsaXAoKSArIAogIGxhYnMoeCA9ICJDb25uZWN0ZWQgUGVydHVyYmFnZW5zIiwgeSA9ICJaIHNjb3JlIikKYGBgCgpgYGB7cn0KVENHQWRydWdzICU+JSBhcnJhbmdlKGRlc2MoelNjb3JlKSkgJT4lIGhlYWQoMjUpICU+JWdncGxvdChhZXMocmVvcmRlcihQZXJ0dXJiYWdlbiwgelNjb3JlKSwgelNjb3JlKSkrIAogIGdlb21fY29sKGFlcyhmaWxsID0gcFZhbHVlKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJkYXJrb2xpdmVncmVlbjIiLCAKICAgICAgICAgICAgICAgICAgICAgIGhpZ2ggPSAiZGFya29saXZlZ3JlZW40IikgKyAKICBjb29yZF9mbGlwKCkgKyAKICBsYWJzKHggPSAiQ29ubmVjdGVkIFBlcnR1cmJhZ2VucyIsIHkgPSAiWiBzY29yZSIpCmBgYAoKYGBge3J9Ck1BZHJ1Z3MgJT4lIGFycmFuZ2UoZGVzYyh6U2NvcmUpKSAlPiUgaGVhZCgyNSkgJT4lZ2dwbG90KGFlcyhyZW9yZGVyKFBlcnR1cmJhZ2VuLCB6U2NvcmUpLCB6U2NvcmUpKSsKICBnZW9tX2NvbChhZXMoZmlsbCA9IHBWYWx1ZSkpICsgCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiZGVlcHNreWJsdWUiLCAKICAgICAgICAgICAgICAgICAgICAgIGhpZ2ggPSAiZGVlcHNreWJsdWU0IikgKyAKICBjb29yZF9mbGlwKCkgKyAKICBsYWJzKHggPSAiQ29ubmVjdGVkIFBlcnR1cmJhZ2VucyIsIHkgPSAiWiBzY29yZSIpCmBgYAoK