#calling the libraries
library(DESeq2)
library(ggplot2)
#calling in the count matrix
counts_D5 <- read.delim("counts_D5", header = TRUE, row.names = 1)
#understanding the distribution of counts in the data set
total_counts_per_gene_D5 <- rowSums(counts_D5)
hist(total_counts_per_gene_D5,
breaks=100,
main="Distribution of Total Counts per Gene",
xlab="Total counts across all samples",
ylab="Number of genes")
summary(total_counts_per_gene_D5)
#ignoring low expressed gene to remove noise & get better results
counts_D5 <- counts_D5[which(rowSums(counts_D5) > 50), ]
#calling in the metadata
metadata_D5 <- read.csv("metadata_D5.csv", header = TRUE)
counts_D5 <- round(counts_D5)
dds_D5 <- DESeqDataSetFromMatrix(countData = counts_D5,
colData = metadata_D5,
design = ~ cell_line + treatment)
dds_D5
# Set reference levels
dds_D5$treatment <- relevel(dds_D5$treatment, ref = "DMSO")
dds_D5$cell_line <- relevel(dds_D5$cell_line, ref = "HCC827")
# Run DESeq2 analysis
dds_D5 <- DESeq(dds_D5)
# Extract results
res_treatment_D5 <- results(dds_D5, contrast = c("treatment", "Gefitinib", "DMSO"))
res_cellline_D5 <- results(dds_D5, contrast = c("cell_line", "HCC4006", "HCC827"))
summary(res_treatment_D5)
summary(res_cellline_D5)
# Data transformation for visualization
vst_D5 <- vst(dds_D5, blind = FALSE)
vst_matrix_D5 <- assay(vst_D5)
head(vst_matrix_D5[1:5, 1:3])
library(reshape2)
vst_df_D5 <- as.data.frame(vst_matrix_D5)
vst_df_D5$gene_id <- rownames(vst_df_D5)
vst_final_D5 <- melt(vst_df_D5,
id.vars = "gene_id",
variable.name = "sample_id",
value.name = "expression_value")
head(vst_final_D5)
pca_plot_D5 <- plotPCA(vst_D5, intgroup = c("treatment", "cell_line"))
ggsave(("D5_PCA.pdf"), pca_plot_D5, width = 6, height = 5)
ggsave(("D5_PCA.png"), pca_plot_D5, width = 6, height = 5, dpi = 300)
# Dispersion Plot
plotDispEsts(dds_D5, main = "Dispersion Estimates")
pdf("DispersionPlot_D5.pdf", width = 6, height = 5)
plotDispEsts(dds_D5)
dev.off()
png("DispersionPlot_D5.png", width = 2000, height = 1600, res = 300)
plotDispEsts(dds_D5)
dev.off()
resultsNames(dds_D5)
#loading annotation packages for gene symbol conversion
library(AnnotationDbi)
library(org.Hs.eg.db)
# I'm converting ENSEMBL IDs to gene symbols
gene_symbols_D5 <- mapIds(org.Hs.eg.db,
keys = rownames(dds_D5),
column = "SYMBOL",
keytype = "ENSEMBL",
multiVals = "first")
res_annotated_D5 <- res_treatment_D5
res_annotated_D5$gene_symbol <- gene_symbols_D5
as.data.frame(res_annotated_D5)
#LFC Shrinkage
res_treatment_D5 <- lfcShrink(dds_D5, coef = "treatment_Gefitinib_vs_DMSO", type = "apeglm")
res_cellline_D5 <- lfcShrink(dds_D5, coef = "cell_line_HCC4006_vs_HCC827", type = "apeglm")
res_treatment_annotated_D5 <- res_treatment_D5
res_treatment_annotated_D5$gene_symbol <- gene_symbols_D5
res_cellline_annotated_D5 <- res_cellline_D5
res_cellline_annotated_D5$gene_symbol <- gene_symbols_D5
# Get significant genes
sig_treatment_D5 <- res_treatment_annotated_D5[which(res_treatment_annotated_D5$padj < 0.05 &
abs(res_treatment_annotated_D5$log2FoldChange) > 1), ]
sig_cellline_D5 <- res_cellline_annotated_D5[which(res_cellline_annotated_D5$padj < 0.05 &
abs(res_cellline_annotated_D5$log2FoldChange) > 1), ]
nrow(sig_treatment_D5)
nrow(sig_cellline_D5)
# Top genes
top_treatment_D5 <- head(sig_treatment_D5[order(sig_treatment_D5$padj), ], 20)
top_cellline_D5 <- head(sig_cellline_D5[order(sig_cellline_D5$padj), ], 20)
# Overlaps
overlap_D5 <- intersect(rownames(sig_treatment_D5), rownames(sig_cellline_D5))
length(overlap_D5)
Visualization Plots
# MA Plot
plotMA(res_treatment_D5, main = "MA Plot - Gefitinib vs DMSO", ylim = c(-3, 3))
pdf(("MA_treatment_D5.pdf"), width = 6, height = 5)
plotMA(res_treatment_D5, ylim=c(-5,5), main="MA Plot - Gefitinib vs DMSO")
dev.off()
png(("MA_treatment_D5.png"), width = 2000, height = 1600, res = 300)
plotMA(res_treatment_D5, ylim=c(-5,5), main="MA Plot - Gefitinib vs DMSO")
dev.off()
plotMA(res_cellline_D5, main = "MA Plot - HCC4006 vs HCC827", ylim = c(-3, 3))
pdf(("MA_cellline_D5.pdf"), width = 6, height = 5)
plotMA(res_cellline_D5, ylim=c(-5,5), main="MA Plot - HCC4006 vs HCC827")
dev.off()
png(("MA_cellline_D5.png"), width = 2000, height = 1600, res = 300)
plotMA(res_cellline_D5, ylim=c(-5,5), main="MA Plot - HCC4006 vs HCC827")
dev.off()
# Volcano plots
library(EnhancedVolcano)
volcano_treatment_D5 <- EnhancedVolcano(res_treatment_annotated_D5, lab = res_treatment_annotated_D5$gene_symbol,
x = 'log2FoldChange', y = 'padj',
title = 'Gefitinib vs DMSO')
ggsave(("volcano_treatment_D5.pdf"), volcano_treatment_D5, width = 6, height = 5)
ggsave(("volcano_treatment_D5.png"), volcano_treatment_D5, width = 6, height = 5, dpi = 300)
volcano_cellline_D5 <- EnhancedVolcano(res_cellline_annotated_D5, lab = res_cellline_annotated_D5$gene_symbol,
x = 'log2FoldChange', y = 'padj',
title = 'HCC4006 vs HCC827')
ggsave(("volcano_cellline_D5.pdf"), volcano_cellline_D5, width = 6, height = 5)
ggsave(("volcano_cellline_D5.png"), volcano_cellline_D5, width = 6, height = 5, dpi = 300)
# Heatmap of top DE genes
library(pheatmap)
if(length(overlap_D5) > 0) {
top_overlap_D5 <- head(overlap_D5[order(sig_treatment_D5[overlap_D5,]$padj)], 50)
pheatmap::pheatmap(assay(vst_D5)[top_overlap_D5,],
annotation_col = as.data.frame(colData(dds_D5)[,c("cell_line", "treatment")]),
scale = "row", show_rownames = FALSE,
main = "Top 50 Overlapping DE Genes",
filename = "DEGs_D5.png")
}
library(ComplexHeatmap)
library(circlize)
library(dplyr)
library(RColorBrewer)
# Prepare top genes for treatment effect
top_treatment_heatmap_D5 <- res_treatment_annotated_D5[!is.na(res_treatment_annotated_D5$padj) &
res_treatment_annotated_D5$padj < 0.05 &
res_treatment_annotated_D5$baseMean > 50 &
abs(res_treatment_annotated_D5$log2FoldChange) > 2,]
top_treatment_heatmap_D5 <- head(as.data.frame(top_treatment_heatmap_D5), 50)
top_treatment_heatmap_D5 <- top_treatment_heatmap_D5[order(top_treatment_heatmap_D5$log2FoldChange, decreasing = TRUE),]
# Create matrices
rlog_D5 <- rlog(dds_D5, blind = FALSE)
mat_D5 <- assay(rlog_D5)[rownames(top_treatment_heatmap_D5), ]
mat_scaled_D5 <- t(apply(mat_D5, 1, scale))
colnames(mat_scaled_D5) <- colnames(mat_D5)
# Select top and bottom genes
num_keep <- min(25, floor(nrow(mat_scaled_D5)/2))
rows_keep_D5 <- c(seq(1:num_keep), seq((nrow(mat_scaled_D5) - num_keep + 1), nrow(mat_scaled_D5)))
# Prepare annotations
l2_val_D5 <- as.matrix(top_treatment_heatmap_D5[rows_keep_D5,]$log2FoldChange)
colnames(l2_val_D5) <- "logFC"
mean_val_D5 <- as.matrix(top_treatment_heatmap_D5[rows_keep_D5,]$baseMean)
colnames(mean_val_D5) <- "AveExpr"
# Colors
col_logFC_D5 <- colorRamp2(c(min(l2_val_D5), 0, max(l2_val_D5)), c("blue", "white", "red"))
col_AveExpr_D5 <- colorRamp2(c(quantile(mean_val_D5)[1], quantile(mean_val_D5)[4]), c("white", "red"))
col_zscore_D5 <- colorRamp2(c(-2, 0, 2), c("#4575b4", "white", "#d73027"))
# Create heatmaps
h1_D5 <- Heatmap(mat_scaled_D5[rows_keep_D5,], cluster_rows = TRUE,
name = "Z-score", col = col_zscore_D5,
show_row_names = FALSE)
h2_D5 <- Heatmap(l2_val_D5, row_labels = top_treatment_heatmap_D5$gene_symbol[rows_keep_D5],
cluster_rows = FALSE, name = "logFC", col = col_logFC_D5,
width = unit(15, "mm"),
row_names_gp = gpar(fontsize = 6), # Decreased from default (usually 10-12)
cell_fun = function(j, i, x, y, w, h, col) {
grid.text(round(l2_val_D5[i, j], 1), x, y, gp = gpar(fontsize = 7))
})
h3_D5 <- Heatmap(mean_val_D5, row_labels = top_treatment_heatmap_D5$gene_symbol[rows_keep_D5],
cluster_rows = FALSE, name = "AveExpr", col = col_AveExpr_D5,
width = unit(15, "mm"),
row_names_gp = gpar(fontsize = 6), # Decreased from default
cell_fun = function(j, i, x, y, w, h, col) {
grid.text(round(mean_val_D5[i, j], 0), x, y, gp = gpar(fontsize = 7))
})
h_D5 <- h1_D5 + h2_D5 + h3_D5
print(h_D5)
pdf("AnnotatedHeatmap_D5.pdf", width = 10, height = 6)
draw(h_D5)
dev.off()
png("AnnotatedHeatmap_D5.png", width = 3000, height = 2000, res = 300)
draw(h_D5)
dev.off()
library(clusterProfiler)
library(DOSE)
library(enrichplot)
# TREATMENT EFFECT PATHWAYS
# Separate up/down genes
sig_genes_up_treatment_D5 <- rownames(sig_treatment_D5)[sig_treatment_D5$log2FoldChange > 1]
sig_genes_down_treatment_D5 <- rownames(sig_treatment_D5)[sig_treatment_D5$log2FoldChange < -1]
print(paste("Upregulated:", length(sig_genes_up_treatment_D5)))
print(paste("Downregulated:", length(sig_genes_down_treatment_D5)))
# Convert to ENTREZ for KEGG
entrez_up_treatment_D5 <- mapIds(org.Hs.eg.db, sig_genes_up_treatment_D5, "ENTREZID", "ENSEMBL")
entrez_down_treatment_D5 <- mapIds(org.Hs.eg.db, sig_genes_down_treatment_D5, "ENTREZID", "ENSEMBL")
entrez_up_treatment_D5 <- entrez_up_treatment_D5[!is.na(entrez_up_treatment_D5)]
entrez_down_treatment_D5 <- entrez_down_treatment_D5[!is.na(entrez_down_treatment_D5)]
# GO Analysis - Treatment
go_up_treatment_D5 <- enrichGO(gene = sig_genes_up_treatment_D5, OrgDb = org.Hs.eg.db,
keyType = "ENSEMBL", ont = "ALL",
pAdjustMethod = "BH", pvalueCutoff = 0.05)
as.data.frame(go_up_treatment_D5)
go_treatment_up_D5 <- barplot(go_up_treatment_D5, showCategory = 15) + labs(title = "GO Up: Gefitinib vs DMSO")
ggsave("GO_treatment_up_D5.pdf", go_treatment_up_D5, width = 7, height = 6)
ggsave("GO_treatment_up_D5.png", go_treatment_up_D5, width = 7, height = 6, dpi = 300)
go_down_treatment_D5 <- enrichGO(gene = sig_genes_down_treatment_D5, OrgDb = org.Hs.eg.db,
keyType = "ENSEMBL", ont = "ALL",
pAdjustMethod = "BH", pvalueCutoff = 0.05)
as.data.frame(go_down_treatment_D5)
top_go_down_treatment_D5 <- go_down_treatment_D5@result[1:10, ]
as.data.frame(top_go_down_treatment_D5)
go_treatment_down_D5 <- barplot(go_down_treatment_D5, showCategory = 15) + labs(title = "GO Down: Gefitinib vs DMSO")
ggsave("GO_treatment_down_D5.pdf", go_treatment_down_D5, width = 7, height = 6)
ggsave("GO_treatment_down_D5.png", go_treatment_down_D5, width = 7, height = 6, dpi = 300)
# KEGG Analysis - Treatment
kegg_up_treatment_D5 <- enrichKEGG(gene = entrez_up_treatment_D5, organism = 'hsa',
pvalueCutoff = 0.1, pAdjustMethod = "BH")
as.data.frame(kegg_up_treatment_D5)
kegg_treatment_up_D5 <- barplot(kegg_up_treatment_D5, showCategory = 15) + labs(title = "KEGG Up: Gefitinib vs DMSO")
ggsave("KEGG_treatment_up_D5.pdf", kegg_treatment_up_D5, width = 7, height = 6)
ggsave("KEGG_treatment_up_D5.png", kegg_treatment_up_D5, width = 7, height = 6, dpi = 300)
kegg_down_treatment_D5 <- enrichKEGG(gene = entrez_down_treatment_D5, organism = 'hsa',
pvalueCutoff = 0.1, pAdjustMethod = "BH")
as.data.frame(kegg_down_treatment_D5)
kegg_treatment_down_D5 <- barplot(kegg_down_treatment_D5, showCategory = 15) + labs(title = "KEGG Down: Gefitinib vs DMSO")
ggsave("KEGG_treatment_down_D5.pdf", kegg_treatment_down_D5, width = 7, height = 6)
ggsave("KEGG_treatment_down_D5.png", kegg_treatment_down_D5, width = 7, height = 6, dpi = 300)
# CELL LINE EFFECT PATHWAYS
# Separate up/down genes
sig_genes_up_cellline_D5 <- rownames(sig_cellline_D5)[sig_cellline_D5$log2FoldChange > 1]
sig_genes_down_cellline_D5 <- rownames(sig_cellline_D5)[sig_cellline_D5$log2FoldChange < -1]
# Convert to ENTREZ
entrez_up_cellline_D5 <- mapIds(org.Hs.eg.db, sig_genes_up_cellline_D5, "ENTREZID", "ENSEMBL")
entrez_down_cellline_D5 <- mapIds(org.Hs.eg.db, sig_genes_down_cellline_D5, "ENTREZID", "ENSEMBL")
entrez_up_cellline_D5 <- entrez_up_cellline_D5[!is.na(entrez_up_cellline_D5)]
entrez_down_cellline_D5 <- entrez_down_cellline_D5[!is.na(entrez_down_cellline_D5)]
# GO Analysis - Cell Line
go_up_cellline_D5 <- enrichGO(gene = sig_genes_up_cellline_D5, OrgDb = org.Hs.eg.db,
keyType = "ENSEMBL", ont = "ALL",
pAdjustMethod = "BH", pvalueCutoff = 0.05)
as.data.frame(go_up_cellline_D5)
go_cellline_up_D5 <- barplot(go_up_cellline_D5, showCategory = 15) + labs(title = "GO Up: HCC4006 vs HCC827")
ggsave("GO_cellline_up_D5.pdf", go_cellline_up_D5, width = 7, height = 6)
ggsave("GO_cellline_up_D5.png", go_cellline_up_D5, width = 7, height = 6, dpi = 300)
go_down_cellline_D5 <- enrichGO(gene = sig_genes_down_cellline_D5, OrgDb = org.Hs.eg.db,
keyType = "ENSEMBL", ont = "ALL",
pAdjustMethod = "BH", pvalueCutoff = 0.05)
as.data.frame(go_down_cellline_D5)
go_cellline_down_D5 <- barplot(go_down_cellline_D5, showCategory = 15) + labs(title = "GO Down: HCC4006 vs HCC827")
ggsave("GO_cellline_down_D5.pdf", go_cellline_down_D5, width = 7, height = 6)
ggsave("GO_cellline_down_D5.png", go_cellline_down_D5, width = 7, height = 6, dpi = 300)
# KEGG Analysis - Cell Line
kegg_up_cellline_D5 <- enrichKEGG(gene = entrez_up_cellline_D5, organism = 'hsa',
pvalueCutoff = 0.05, pAdjustMethod = "BH")
as.data.frame(kegg_up_cellline_D5)
kegg_cellline_up_D5 <- barplot(kegg_up_cellline_D5, showCategory = 15) + labs(title = "KEGG Up: HCC4006 vs HCC827")
ggsave("KEGG_cellline_up_D5.pdf", kegg_cellline_up_D5, width = 7, height = 6)
ggsave("KEGG_cellline_up_D5.png", kegg_cellline_up_D5, width = 7, height = 6, dpi = 300)
kegg_down_cellline_D5 <- enrichKEGG(gene = entrez_down_cellline_D5, organism = 'hsa',
pvalueCutoff = 0.05, pAdjustMethod = "BH")
as.data.frame(kegg_down_cellline_D5)
kegg_cellline_down_D5 <- barplot(kegg_down_cellline_D5, showCategory = 15) + labs(title = "KEGG Down: HCC4006 vs HCC827")
ggsave("KEGG_cellline_down_D5.pdf", kegg_cellline_down_D5, width = 7, height = 6)
ggsave("KEGG_cellline_down_D5.png", kegg_cellline_down_D5, width = 7, height = 6, dpi = 300)
library(fgsea)
library(msigdbr)
# TREATMENT GSEA
# Prepare ranked gene list
gene_ranks_treatment_D5 <- res_treatment_D5$log2FoldChange
names(gene_ranks_treatment_D5) <- rownames(res_treatment_D5)
gene_ranks_treatment_D5 <- gene_ranks_treatment_D5[!is.na(gene_ranks_treatment_D5)]
gene_ranks_treatment_D5 <- sort(gene_ranks_treatment_D5, decreasing = TRUE)
# Get Hallmark pathways
hallmark_sets_D5 <- msigdbr(species = "Homo sapiens", category = "H")
hallmark_list_D5 <- split(hallmark_sets_D5$ensembl_gene, hallmark_sets_D5$gs_name)
BiocParallel::register(BiocParallel::SerialParam())
# Run GSEA
fgsea_treatment_D5 <- fgseaMultilevel(pathways = hallmark_list_D5, stats = gene_ranks_treatment_D5,
minSize = 15, maxSize = 500)
print("Top GSEA Results - Treatment (Gefitinib vs DMSO):")
print(head(fgsea_treatment_D5[order(pval), ], 10))
top_pathways_treatment_D5 <- head(fgsea_treatment_D5[order(pval), ], 3)
# Plot top 3 pathways
for(i in 1:3) {
p1_D5 <- top_pathways_treatment_D5$pathway[i]
pathways_treatment_D5 <- plotEnrichment(hallmark_list_D5[[p1_D5]], gene_ranks_treatment_D5) +
labs(title = paste("Pathway", i, ":", p1_D5))
print(pathways_treatment_D5)
ggsave("Top3_GSEAtreatment_D5.pdf", pathways_treatment_D5, width = 7, height = 6)
ggsave("Top3_GSEAtreatment_D5.png", pathways_treatment_D5, width = 7, height = 6, dpi = 300)
}
# CELL LINE GSEA
# Prepare ranked gene list
gene_ranks_cellline_D5 <- res_cellline_D5$log2FoldChange
names(gene_ranks_cellline_D5) <- rownames(res_cellline_D5)
gene_ranks_cellline_D5 <- gene_ranks_cellline_D5[!is.na(gene_ranks_cellline_D5)]
gene_ranks_cellline_D5 <- sort(gene_ranks_cellline_D5, decreasing = TRUE)
# Run GSEA
fgsea_cellline_D5 <- fgseaMultilevel(pathways = hallmark_list_D5, stats = gene_ranks_cellline_D5,
minSize = 15, maxSize = 500)
print("Top GSEA Results - Cell Line (HCC4006 vs HCC827):")
print(head(fgsea_cellline_D5[order(pval), ], 10))
top_pathways_cellline_D5 <- head(fgsea_cellline_D5[order(pval), ], 3)
# Plot top 3 pathways
for(i in 1:3) {
p2_D5 <- top_pathways_cellline_D5$pathway[i]
pathways_cellline_D5 <- plotEnrichment(hallmark_list_D5[[p2_D5]], gene_ranks_cellline_D5) +
labs(title = paste("Pathway", i, ":", p2_D5))
print(pathways_cellline_D5)
ggsave("Top3_GSEAcellline_D5.pdf", pathways_cellline_D5, width = 7, height = 6)
ggsave("Top3_GSEAcellline_D5.png", pathways_cellline_D5, width = 7, height = 6, dpi = 300)
}
# Summary statistics table for D5
summary_stats_D5 <- data.frame(
Metric = c("Total Samples", "Genes Analyzed - Tretament", "Gene Analyzed - Cell Line", "Significant DEGs - Treatment", "Significant DEGs - Cell Line","Upregulated genes - Treatment", "Downregulated genes - Treatment", "Upregulated genes - Cell Line", "Upregulated genes - Cell Line"),
Value = c(ncol(counts_D5),
nrow(res_treatment_annotated_D5),
nrow(res_cellline_annotated_D5),
nrow(sig_treatment_D5),
nrow(sig_cellline_D5),
length(sig_genes_up_treatment_D5),
length(sig_genes_down_treatment_D5),
length(sig_genes_up_cellline_D5),
length(sig_genes_down_cellline_D5))
)
summary_stats_D5
# Top genes table
top_genes_treatment_D5 <- data.frame(
Gene_Symbol = gene_symbols_D5[rownames(head(sig_treatment_D5[order(sig_treatment_D5$padj),], 20))],
ENSEMBL_ID = rownames(head(sig_treatment_D5[order(sig_treatment_D5$padj),], 20)),
Log2FC = round(head(sig_treatment_D5[order(sig_treatment_D5$padj),], 20)$log2FoldChange, 3),
Padj = format(head(sig_treatment_D5[order(sig_treatment_D5$padj),], 20)$padj, scientific = TRUE, digits = 3),
Direction = ifelse(head(sig_treatment_D5[order(sig_treatment_D5$padj),], 20)$log2FoldChange > 0, "Up", "Down")
)
print("Top 20 Significant Genes: Treatment")
print(top_genes_treatment_D5)
top_genes_cellline_D5 <- data.frame(
Gene_Symbol = gene_symbols_D5[rownames(head(sig_cellline_D5[order(sig_cellline_D5$padj),], 20))],
ENSEMBL_ID = rownames(head(sig_cellline_D5[order(sig_cellline_D5$padj),], 20)),
Log2FC = round(head(sig_cellline_D5[order(sig_cellline_D5$padj),], 20)$log2FoldChange, 3),
Padj = format(head(sig_cellline_D5[order(sig_cellline_D5$padj),], 20)$padj, scientific = TRUE, digits = 3),
Direction = ifelse(head(sig_cellline_D5[order(sig_cellline_D5$padj),], 20)$log2FoldChange > 0, "Up", "Down")
)
print("Top 20 Significant Genes: Cell Line")
print(top_genes_cellline_D5)
# Export main results
write.csv(as.data.frame(res_treatment_annotated_D5), "D5_treatment_results.csv", row.names = TRUE)
write.csv(sig_treatment_D5, "D5_sig_treatment_genes.csv", row.names = TRUE)
write.csv(summary_stats_D5, "D5_summary_statistics.csv", row.names = FALSE)
write.csv(top_genes_treatment_D5, "D5_top20_treatment_genes.csv", row.names = FALSE)
# Export normalized data
write.csv(counts(dds_D5, normalized=TRUE), "D5_normalized_counts.csv", row.names = TRUE)
write.csv(assay(vst_D5), "D5_vst_data.csv", row.names = TRUE)
# Export pathway results
write.csv(go_up_treatment_D5@result, "D5_GO_up.csv", row.names = FALSE)
write.csv(go_down_treatment_D5@result, "D5_GO_down.csv", row.names = FALSE)
write.csv(kegg_up_treatment_D5@result, "D5_KEGG_up.csv", row.names = FALSE)
write.csv(kegg_down_treatment_D5@result, "D5_KEGG_down.csv", row.names = FALSE)
# Remove the leadingEdge column (which contains lists)
fgsea_results_clean_D5 <- fgsea_treatment_D5 %>%
select(-leadingEdge)
write.csv(fgsea_results_clean_D5, "D5_GSEA_hallmarks.csv", row.names = FALSE)
LS0tDQp0aXRsZTogIkRhdGFzZXQgNSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyfQ0KI2NhbGxpbmcgdGhlIGxpYnJhcmllcw0KDQpsaWJyYXJ5KERFU2VxMikNCmxpYnJhcnkoZ2dwbG90MikNCmBgYA0KDQpgYGB7cn0NCiNjYWxsaW5nIGluIHRoZSBjb3VudCBtYXRyaXgNCmNvdW50c19ENSA8LSByZWFkLmRlbGltKCJjb3VudHNfRDUiLCBoZWFkZXIgPSBUUlVFLCByb3cubmFtZXMgPSAxKQ0KYGBgDQoNCmBgYHtyfQ0KI3VuZGVyc3RhbmRpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBjb3VudHMgaW4gdGhlIGRhdGEgc2V0DQoNCnRvdGFsX2NvdW50c19wZXJfZ2VuZV9ENSA8LSByb3dTdW1zKGNvdW50c19ENSkNCg0KaGlzdCh0b3RhbF9jb3VudHNfcGVyX2dlbmVfRDUsIA0KICAgICBicmVha3M9MTAwLCANCiAgICAgbWFpbj0iRGlzdHJpYnV0aW9uIG9mIFRvdGFsIENvdW50cyBwZXIgR2VuZSIsIA0KICAgICB4bGFiPSJUb3RhbCBjb3VudHMgYWNyb3NzIGFsbCBzYW1wbGVzIiwNCiAgICAgeWxhYj0iTnVtYmVyIG9mIGdlbmVzIikNCnN1bW1hcnkodG90YWxfY291bnRzX3Blcl9nZW5lX0Q1KQ0KYGBgDQoNCmBgYHtyfQ0KI2lnbm9yaW5nIGxvdyBleHByZXNzZWQgZ2VuZSB0byByZW1vdmUgbm9pc2UgJiBnZXQgYmV0dGVyIHJlc3VsdHMNCg0KY291bnRzX0Q1IDwtIGNvdW50c19ENVt3aGljaChyb3dTdW1zKGNvdW50c19ENSkgPiA1MCksIF0NCmBgYA0KDQpgYGB7cn0NCiNjYWxsaW5nIGluIHRoZSBtZXRhZGF0YQ0KbWV0YWRhdGFfRDUgPC0gcmVhZC5jc3YoIm1ldGFkYXRhX0Q1LmNzdiIsIGhlYWRlciA9IFRSVUUpDQpgYGANCg0KYGBge3J9DQpjb3VudHNfRDUgPC0gcm91bmQoY291bnRzX0Q1KQ0KZGRzX0Q1IDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhID0gY291bnRzX0Q1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhID0gbWV0YWRhdGFfRDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IH4gY2VsbF9saW5lICsgdHJlYXRtZW50KQ0KZGRzX0Q1DQpgYGANCg0KYGBge3J9DQojIFNldCByZWZlcmVuY2UgbGV2ZWxzDQpkZHNfRDUkdHJlYXRtZW50IDwtIHJlbGV2ZWwoZGRzX0Q1JHRyZWF0bWVudCwgcmVmID0gIkRNU08iKQ0KZGRzX0Q1JGNlbGxfbGluZSA8LSByZWxldmVsKGRkc19ENSRjZWxsX2xpbmUsIHJlZiA9ICJIQ0M4MjciKQ0KDQojIFJ1biBERVNlcTIgYW5hbHlzaXMNCmRkc19ENSA8LSBERVNlcShkZHNfRDUpDQoNCiMgRXh0cmFjdCByZXN1bHRzDQpyZXNfdHJlYXRtZW50X0Q1IDwtIHJlc3VsdHMoZGRzX0Q1LCBjb250cmFzdCA9IGMoInRyZWF0bWVudCIsICJHZWZpdGluaWIiLCAiRE1TTyIpKQ0KcmVzX2NlbGxsaW5lX0Q1IDwtIHJlc3VsdHMoZGRzX0Q1LCBjb250cmFzdCA9IGMoImNlbGxfbGluZSIsICJIQ0M0MDA2IiwgIkhDQzgyNyIpKQ0KDQpzdW1tYXJ5KHJlc190cmVhdG1lbnRfRDUpDQpzdW1tYXJ5KHJlc19jZWxsbGluZV9ENSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBEYXRhIHRyYW5zZm9ybWF0aW9uIGZvciB2aXN1YWxpemF0aW9uDQp2c3RfRDUgPC0gdnN0KGRkc19ENSwgYmxpbmQgPSBGQUxTRSkNCg0KdnN0X21hdHJpeF9ENSA8LSBhc3NheSh2c3RfRDUpDQoNCmhlYWQodnN0X21hdHJpeF9ENVsxOjUsIDE6M10pDQoNCmxpYnJhcnkocmVzaGFwZTIpDQoNCnZzdF9kZl9ENSA8LSBhcy5kYXRhLmZyYW1lKHZzdF9tYXRyaXhfRDUpDQp2c3RfZGZfRDUkZ2VuZV9pZCA8LSByb3duYW1lcyh2c3RfZGZfRDUpDQoNCnZzdF9maW5hbF9ENSA8LSBtZWx0KHZzdF9kZl9ENSwgDQogICAgICAgICAgICAgICAgIGlkLnZhcnMgPSAiZ2VuZV9pZCIsIA0KICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gInNhbXBsZV9pZCIsIA0KICAgICAgICAgICAgICAgICB2YWx1ZS5uYW1lID0gImV4cHJlc3Npb25fdmFsdWUiKQ0KDQpoZWFkKHZzdF9maW5hbF9ENSkNCg0KcGNhX3Bsb3RfRDUgPC0gcGxvdFBDQSh2c3RfRDUsIGludGdyb3VwID0gYygidHJlYXRtZW50IiwgImNlbGxfbGluZSIpKQ0KDQpnZ3NhdmUoKCJENV9QQ0EucGRmIiksIHBjYV9wbG90X0Q1LCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpDQpnZ3NhdmUoKCJENV9QQ0EucG5nIiksIHBjYV9wbG90X0Q1LCB3aWR0aCA9IDYsIGhlaWdodCA9IDUsIGRwaSA9IDMwMCkNCmBgYA0KDQpgYGB7cn0NCiMgRGlzcGVyc2lvbiBQbG90DQpwbG90RGlzcEVzdHMoZGRzX0Q1LCBtYWluID0gIkRpc3BlcnNpb24gRXN0aW1hdGVzIikNCg0KcGRmKCJEaXNwZXJzaW9uUGxvdF9ENS5wZGYiLCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpDQpwbG90RGlzcEVzdHMoZGRzX0Q1KQ0KZGV2Lm9mZigpDQoNCnBuZygiRGlzcGVyc2lvblBsb3RfRDUucG5nIiwgd2lkdGggPSAyMDAwLCBoZWlnaHQgPSAxNjAwLCByZXMgPSAzMDApDQpwbG90RGlzcEVzdHMoZGRzX0Q1KQ0KZGV2Lm9mZigpDQoNCnJlc3VsdHNOYW1lcyhkZHNfRDUpDQpgYGANCg0KYGBge3J9DQojbG9hZGluZyBhbm5vdGF0aW9uIHBhY2thZ2VzIGZvciBnZW5lIHN5bWJvbCBjb252ZXJzaW9uDQpsaWJyYXJ5KEFubm90YXRpb25EYmkpDQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikNCg0KIyBJJ20gY29udmVydGluZyBFTlNFTUJMIElEcyB0byBnZW5lIHN5bWJvbHMNCmdlbmVfc3ltYm9sc19ENSA8LSBtYXBJZHMob3JnLkhzLmVnLmRiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGtleXMgPSByb3duYW1lcyhkZHNfRDUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9ICJTWU1CT0wiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGtleXR5cGUgPSAiRU5TRU1CTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlWYWxzID0gImZpcnN0IikNCg0KcmVzX2Fubm90YXRlZF9ENSA8LSByZXNfdHJlYXRtZW50X0Q1DQpyZXNfYW5ub3RhdGVkX0Q1JGdlbmVfc3ltYm9sIDwtIGdlbmVfc3ltYm9sc19ENQ0KYXMuZGF0YS5mcmFtZShyZXNfYW5ub3RhdGVkX0Q1KQ0KYGBgDQoNCg0KYGBge3J9DQogI0xGQyBTaHJpbmthZ2UNCnJlc190cmVhdG1lbnRfRDUgPC0gbGZjU2hyaW5rKGRkc19ENSwgY29lZiA9ICJ0cmVhdG1lbnRfR2VmaXRpbmliX3ZzX0RNU08iLCB0eXBlID0gImFwZWdsbSIpDQpyZXNfY2VsbGxpbmVfRDUgPC0gbGZjU2hyaW5rKGRkc19ENSwgY29lZiA9ICJjZWxsX2xpbmVfSENDNDAwNl92c19IQ0M4MjciLCB0eXBlID0gImFwZWdsbSIpDQoNCnJlc190cmVhdG1lbnRfYW5ub3RhdGVkX0Q1IDwtIHJlc190cmVhdG1lbnRfRDUNCnJlc190cmVhdG1lbnRfYW5ub3RhdGVkX0Q1JGdlbmVfc3ltYm9sIDwtIGdlbmVfc3ltYm9sc19ENQ0KDQpyZXNfY2VsbGxpbmVfYW5ub3RhdGVkX0Q1IDwtIHJlc19jZWxsbGluZV9ENQ0KcmVzX2NlbGxsaW5lX2Fubm90YXRlZF9ENSRnZW5lX3N5bWJvbCA8LSBnZW5lX3N5bWJvbHNfRDUNCg0KIyBHZXQgc2lnbmlmaWNhbnQgZ2VuZXMNCnNpZ190cmVhdG1lbnRfRDUgPC0gcmVzX3RyZWF0bWVudF9hbm5vdGF0ZWRfRDVbd2hpY2gocmVzX3RyZWF0bWVudF9hbm5vdGF0ZWRfRDUkcGFkaiA8IDAuMDUgJiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzKHJlc190cmVhdG1lbnRfYW5ub3RhdGVkX0Q1JGxvZzJGb2xkQ2hhbmdlKSA+IDEpLCBdDQpzaWdfY2VsbGxpbmVfRDUgPC0gcmVzX2NlbGxsaW5lX2Fubm90YXRlZF9ENVt3aGljaChyZXNfY2VsbGxpbmVfYW5ub3RhdGVkX0Q1JHBhZGogPCAwLjA1ICYgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYnMocmVzX2NlbGxsaW5lX2Fubm90YXRlZF9ENSRsb2cyRm9sZENoYW5nZSkgPiAxKSwgXQ0KDQpucm93KHNpZ190cmVhdG1lbnRfRDUpDQpucm93KHNpZ19jZWxsbGluZV9ENSkNCg0KIyBUb3AgZ2VuZXMNCnRvcF90cmVhdG1lbnRfRDUgPC0gaGVhZChzaWdfdHJlYXRtZW50X0Q1W29yZGVyKHNpZ190cmVhdG1lbnRfRDUkcGFkaiksIF0sIDIwKQ0KdG9wX2NlbGxsaW5lX0Q1IDwtIGhlYWQoc2lnX2NlbGxsaW5lX0Q1W29yZGVyKHNpZ19jZWxsbGluZV9ENSRwYWRqKSwgXSwgMjApDQoNCiMgT3ZlcmxhcHMNCm92ZXJsYXBfRDUgPC0gaW50ZXJzZWN0KHJvd25hbWVzKHNpZ190cmVhdG1lbnRfRDUpLCByb3duYW1lcyhzaWdfY2VsbGxpbmVfRDUpKQ0KbGVuZ3RoKG92ZXJsYXBfRDUpDQpgYGANCg0KVmlzdWFsaXphdGlvbiBQbG90cw0KYGBge3J9DQojIE1BIFBsb3QNCnBsb3RNQShyZXNfdHJlYXRtZW50X0Q1LCBtYWluID0gIk1BIFBsb3QgLSBHZWZpdGluaWIgdnMgRE1TTyIsIHlsaW0gPSBjKC0zLCAzKSkNCg0KcGRmKCgiTUFfdHJlYXRtZW50X0Q1LnBkZiIpLCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpDQpwbG90TUEocmVzX3RyZWF0bWVudF9ENSwgeWxpbT1jKC01LDUpLCBtYWluPSJNQSBQbG90IC0gR2VmaXRpbmliIHZzIERNU08iKQ0KZGV2Lm9mZigpDQoNCnBuZygoIk1BX3RyZWF0bWVudF9ENS5wbmciKSwgd2lkdGggPSAyMDAwLCBoZWlnaHQgPSAxNjAwLCByZXMgPSAzMDApDQpwbG90TUEocmVzX3RyZWF0bWVudF9ENSwgeWxpbT1jKC01LDUpLCBtYWluPSJNQSBQbG90IC0gR2VmaXRpbmliIHZzIERNU08iKQ0KZGV2Lm9mZigpDQoNCnBsb3RNQShyZXNfY2VsbGxpbmVfRDUsIG1haW4gPSAiTUEgUGxvdCAtIEhDQzQwMDYgdnMgSENDODI3IiwgeWxpbSA9IGMoLTMsIDMpKQ0KDQpwZGYoKCJNQV9jZWxsbGluZV9ENS5wZGYiKSwgd2lkdGggPSA2LCBoZWlnaHQgPSA1KQ0KcGxvdE1BKHJlc19jZWxsbGluZV9ENSwgeWxpbT1jKC01LDUpLCBtYWluPSJNQSBQbG90IC0gSENDNDAwNiB2cyBIQ0M4MjciKQ0KZGV2Lm9mZigpDQoNCnBuZygoIk1BX2NlbGxsaW5lX0Q1LnBuZyIpLCB3aWR0aCA9IDIwMDAsIGhlaWdodCA9IDE2MDAsIHJlcyA9IDMwMCkNCnBsb3RNQShyZXNfY2VsbGxpbmVfRDUsIHlsaW09YygtNSw1KSwgbWFpbj0iTUEgUGxvdCAtIEhDQzQwMDYgdnMgSENDODI3IikNCmRldi5vZmYoKQ0KDQojIFZvbGNhbm8gcGxvdHMNCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQ0KDQp2b2xjYW5vX3RyZWF0bWVudF9ENSA8LSBFbmhhbmNlZFZvbGNhbm8ocmVzX3RyZWF0bWVudF9hbm5vdGF0ZWRfRDUsIGxhYiA9IHJlc190cmVhdG1lbnRfYW5ub3RhdGVkX0Q1JGdlbmVfc3ltYm9sLA0KICAgICAgICAgICAgICAgIHggPSAnbG9nMkZvbGRDaGFuZ2UnLCB5ID0gJ3BhZGonLA0KICAgICAgICAgICAgICAgIHRpdGxlID0gJ0dlZml0aW5pYiB2cyBETVNPJykNCg0KZ2dzYXZlKCgidm9sY2Fub190cmVhdG1lbnRfRDUucGRmIiksIHZvbGNhbm9fdHJlYXRtZW50X0Q1LCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpDQpnZ3NhdmUoKCJ2b2xjYW5vX3RyZWF0bWVudF9ENS5wbmciKSwgdm9sY2Fub190cmVhdG1lbnRfRDUsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQ0KDQoNCnZvbGNhbm9fY2VsbGxpbmVfRDUgPC0gRW5oYW5jZWRWb2xjYW5vKHJlc19jZWxsbGluZV9hbm5vdGF0ZWRfRDUsIGxhYiA9IHJlc19jZWxsbGluZV9hbm5vdGF0ZWRfRDUkZ2VuZV9zeW1ib2wsDQogICAgICAgICAgICAgICAgeCA9ICdsb2cyRm9sZENoYW5nZScsIHkgPSAncGFkaicsDQogICAgICAgICAgICAgICAgdGl0bGUgPSAnSENDNDAwNiB2cyBIQ0M4MjcnKQ0KDQpnZ3NhdmUoKCJ2b2xjYW5vX2NlbGxsaW5lX0Q1LnBkZiIpLCB2b2xjYW5vX2NlbGxsaW5lX0Q1LCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpDQpnZ3NhdmUoKCJ2b2xjYW5vX2NlbGxsaW5lX0Q1LnBuZyIpLCB2b2xjYW5vX2NlbGxsaW5lX0Q1LCB3aWR0aCA9IDYsIGhlaWdodCA9IDUsIGRwaSA9IDMwMCkNCg0KIyBIZWF0bWFwIG9mIHRvcCBERSBnZW5lcw0KbGlicmFyeShwaGVhdG1hcCkNCg0KaWYobGVuZ3RoKG92ZXJsYXBfRDUpID4gMCkgew0KICB0b3Bfb3ZlcmxhcF9ENSA8LSBoZWFkKG92ZXJsYXBfRDVbb3JkZXIoc2lnX3RyZWF0bWVudF9ENVtvdmVybGFwX0Q1LF0kcGFkaildLCA1MCkNCiAgcGhlYXRtYXA6OnBoZWF0bWFwKGFzc2F5KHZzdF9ENSlbdG9wX292ZXJsYXBfRDUsXSwgDQogICAgICAgICAgIGFubm90YXRpb25fY29sID0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKGRkc19ENSlbLGMoImNlbGxfbGluZSIsICJ0cmVhdG1lbnQiKV0pLA0KICAgICAgICAgICBzY2FsZSA9ICJyb3ciLCBzaG93X3Jvd25hbWVzID0gRkFMU0UsDQogICAgICAgICAgIG1haW4gPSAiVG9wIDUwIE92ZXJsYXBwaW5nIERFIEdlbmVzIiwNCiAgICAgICAgICAgZmlsZW5hbWUgPSAiREVHc19ENS5wbmciKQ0KfQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkoQ29tcGxleEhlYXRtYXApDQpsaWJyYXJ5KGNpcmNsaXplKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KDQojIFByZXBhcmUgdG9wIGdlbmVzIGZvciB0cmVhdG1lbnQgZWZmZWN0DQp0b3BfdHJlYXRtZW50X2hlYXRtYXBfRDUgPC0gcmVzX3RyZWF0bWVudF9hbm5vdGF0ZWRfRDVbIWlzLm5hKHJlc190cmVhdG1lbnRfYW5ub3RhdGVkX0Q1JHBhZGopICYgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzX3RyZWF0bWVudF9hbm5vdGF0ZWRfRDUkcGFkaiA8IDAuMDUgJiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNfdHJlYXRtZW50X2Fubm90YXRlZF9ENSRiYXNlTWVhbiA+IDUwICYgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJzKHJlc190cmVhdG1lbnRfYW5ub3RhdGVkX0Q1JGxvZzJGb2xkQ2hhbmdlKSA+IDIsXQ0KdG9wX3RyZWF0bWVudF9oZWF0bWFwX0Q1IDwtIGhlYWQoYXMuZGF0YS5mcmFtZSh0b3BfdHJlYXRtZW50X2hlYXRtYXBfRDUpLCA1MCkNCnRvcF90cmVhdG1lbnRfaGVhdG1hcF9ENSA8LSB0b3BfdHJlYXRtZW50X2hlYXRtYXBfRDVbb3JkZXIodG9wX3RyZWF0bWVudF9oZWF0bWFwX0Q1JGxvZzJGb2xkQ2hhbmdlLCBkZWNyZWFzaW5nID0gVFJVRSksXQ0KDQojIENyZWF0ZSBtYXRyaWNlcw0KcmxvZ19ENSA8LSBybG9nKGRkc19ENSwgYmxpbmQgPSBGQUxTRSkNCm1hdF9ENSA8LSBhc3NheShybG9nX0Q1KVtyb3duYW1lcyh0b3BfdHJlYXRtZW50X2hlYXRtYXBfRDUpLCBdDQptYXRfc2NhbGVkX0Q1IDwtIHQoYXBwbHkobWF0X0Q1LCAxLCBzY2FsZSkpDQpjb2xuYW1lcyhtYXRfc2NhbGVkX0Q1KSA8LSBjb2xuYW1lcyhtYXRfRDUpDQoNCiMgU2VsZWN0IHRvcCBhbmQgYm90dG9tIGdlbmVzDQpudW1fa2VlcCA8LSBtaW4oMjUsIGZsb29yKG5yb3cobWF0X3NjYWxlZF9ENSkvMikpDQpyb3dzX2tlZXBfRDUgPC0gYyhzZXEoMTpudW1fa2VlcCksIHNlcSgobnJvdyhtYXRfc2NhbGVkX0Q1KSAtIG51bV9rZWVwICsgMSksIG5yb3cobWF0X3NjYWxlZF9ENSkpKQ0KDQojIFByZXBhcmUgYW5ub3RhdGlvbnMNCmwyX3ZhbF9ENSA8LSBhcy5tYXRyaXgodG9wX3RyZWF0bWVudF9oZWF0bWFwX0Q1W3Jvd3Nfa2VlcF9ENSxdJGxvZzJGb2xkQ2hhbmdlKQ0KY29sbmFtZXMobDJfdmFsX0Q1KSA8LSAibG9nRkMiDQptZWFuX3ZhbF9ENSA8LSBhcy5tYXRyaXgodG9wX3RyZWF0bWVudF9oZWF0bWFwX0Q1W3Jvd3Nfa2VlcF9ENSxdJGJhc2VNZWFuKQ0KY29sbmFtZXMobWVhbl92YWxfRDUpIDwtICJBdmVFeHByIg0KDQojIENvbG9ycw0KY29sX2xvZ0ZDX0Q1IDwtIGNvbG9yUmFtcDIoYyhtaW4obDJfdmFsX0Q1KSwgMCwgbWF4KGwyX3ZhbF9ENSkpLCBjKCJibHVlIiwgIndoaXRlIiwgInJlZCIpKQ0KY29sX0F2ZUV4cHJfRDUgPC0gY29sb3JSYW1wMihjKHF1YW50aWxlKG1lYW5fdmFsX0Q1KVsxXSwgcXVhbnRpbGUobWVhbl92YWxfRDUpWzRdKSwgYygid2hpdGUiLCAicmVkIikpDQpjb2xfenNjb3JlX0Q1IDwtIGNvbG9yUmFtcDIoYygtMiwgMCwgMiksIGMoIiM0NTc1YjQiLCAid2hpdGUiLCAiI2Q3MzAyNyIpKQ0KDQojIENyZWF0ZSBoZWF0bWFwcw0KaDFfRDUgPC0gSGVhdG1hcChtYXRfc2NhbGVkX0Q1W3Jvd3Nfa2VlcF9ENSxdLCBjbHVzdGVyX3Jvd3MgPSBUUlVFLA0KICAgICAgICAgICAgICAgICBuYW1lID0gIlotc2NvcmUiLCBjb2wgPSBjb2xfenNjb3JlX0Q1LA0KICAgICAgICAgICAgICAgICBzaG93X3Jvd19uYW1lcyA9IEZBTFNFKQ0KDQpoMl9ENSA8LSBIZWF0bWFwKGwyX3ZhbF9ENSwgcm93X2xhYmVscyA9IHRvcF90cmVhdG1lbnRfaGVhdG1hcF9ENSRnZW5lX3N5bWJvbFtyb3dzX2tlZXBfRDVdLA0KICAgICAgICAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgbmFtZSA9ICJsb2dGQyIsIGNvbCA9IGNvbF9sb2dGQ19ENSwNCiAgICAgICAgICAgICAgICAgd2lkdGggPSB1bml0KDE1LCAibW0iKSwNCiAgICAgICAgICAgICAgICAgcm93X25hbWVzX2dwID0gZ3Bhcihmb250c2l6ZSA9IDYpLCAgIyBEZWNyZWFzZWQgZnJvbSBkZWZhdWx0ICh1c3VhbGx5IDEwLTEyKQ0KICAgICAgICAgICAgICAgICBjZWxsX2Z1biA9IGZ1bmN0aW9uKGosIGksIHgsIHksIHcsIGgsIGNvbCkgew0KICAgICAgICAgICAgICAgICAgIGdyaWQudGV4dChyb3VuZChsMl92YWxfRDVbaSwgal0sIDEpLCB4LCB5LCBncCA9IGdwYXIoZm9udHNpemUgPSA3KSkNCiAgICAgICAgICAgICAgICAgfSkNCg0KaDNfRDUgPC0gSGVhdG1hcChtZWFuX3ZhbF9ENSwgcm93X2xhYmVscyA9IHRvcF90cmVhdG1lbnRfaGVhdG1hcF9ENSRnZW5lX3N5bWJvbFtyb3dzX2tlZXBfRDVdLA0KICAgICAgICAgICAgICAgICBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgbmFtZSA9ICJBdmVFeHByIiwgY29sID0gY29sX0F2ZUV4cHJfRDUsDQogICAgICAgICAgICAgICAgIHdpZHRoID0gdW5pdCgxNSwgIm1tIiksDQogICAgICAgICAgICAgICAgIHJvd19uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSA2KSwgICMgRGVjcmVhc2VkIGZyb20gZGVmYXVsdA0KICAgICAgICAgICAgICAgICBjZWxsX2Z1biA9IGZ1bmN0aW9uKGosIGksIHgsIHksIHcsIGgsIGNvbCkgew0KICAgICAgICAgICAgICAgICAgIGdyaWQudGV4dChyb3VuZChtZWFuX3ZhbF9ENVtpLCBqXSwgMCksIHgsIHksIGdwID0gZ3Bhcihmb250c2l6ZSA9IDcpKQ0KICAgICAgICAgICAgICAgICB9KQ0KDQpoX0Q1IDwtIGgxX0Q1ICsgaDJfRDUgKyBoM19ENQ0KcHJpbnQoaF9ENSkNCg0KcGRmKCJBbm5vdGF0ZWRIZWF0bWFwX0Q1LnBkZiIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpDQpkcmF3KGhfRDUpDQpkZXYub2ZmKCkNCg0KcG5nKCJBbm5vdGF0ZWRIZWF0bWFwX0Q1LnBuZyIsIHdpZHRoID0gMzAwMCwgaGVpZ2h0ID0gMjAwMCwgcmVzID0gMzAwKQ0KZHJhdyhoX0Q1KQ0KZGV2Lm9mZigpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShjbHVzdGVyUHJvZmlsZXIpDQpsaWJyYXJ5KERPU0UpDQpsaWJyYXJ5KGVucmljaHBsb3QpDQoNCiMgVFJFQVRNRU5UIEVGRkVDVCBQQVRIV0FZUw0KIyBTZXBhcmF0ZSB1cC9kb3duIGdlbmVzDQpzaWdfZ2VuZXNfdXBfdHJlYXRtZW50X0Q1IDwtIHJvd25hbWVzKHNpZ190cmVhdG1lbnRfRDUpW3NpZ190cmVhdG1lbnRfRDUkbG9nMkZvbGRDaGFuZ2UgPiAxXQ0Kc2lnX2dlbmVzX2Rvd25fdHJlYXRtZW50X0Q1IDwtIHJvd25hbWVzKHNpZ190cmVhdG1lbnRfRDUpW3NpZ190cmVhdG1lbnRfRDUkbG9nMkZvbGRDaGFuZ2UgPCAtMV0NCg0KcHJpbnQocGFzdGUoIlVwcmVndWxhdGVkOiIsIGxlbmd0aChzaWdfZ2VuZXNfdXBfdHJlYXRtZW50X0Q1KSkpDQpwcmludChwYXN0ZSgiRG93bnJlZ3VsYXRlZDoiLCBsZW5ndGgoc2lnX2dlbmVzX2Rvd25fdHJlYXRtZW50X0Q1KSkpDQoNCiMgQ29udmVydCB0byBFTlRSRVogZm9yIEtFR0cNCmVudHJlel91cF90cmVhdG1lbnRfRDUgPC0gbWFwSWRzKG9yZy5Icy5lZy5kYiwgc2lnX2dlbmVzX3VwX3RyZWF0bWVudF9ENSwgIkVOVFJFWklEIiwgIkVOU0VNQkwiKQ0KZW50cmV6X2Rvd25fdHJlYXRtZW50X0Q1IDwtIG1hcElkcyhvcmcuSHMuZWcuZGIsIHNpZ19nZW5lc19kb3duX3RyZWF0bWVudF9ENSwgIkVOVFJFWklEIiwgIkVOU0VNQkwiKQ0KZW50cmV6X3VwX3RyZWF0bWVudF9ENSA8LSBlbnRyZXpfdXBfdHJlYXRtZW50X0Q1WyFpcy5uYShlbnRyZXpfdXBfdHJlYXRtZW50X0Q1KV0NCmVudHJlel9kb3duX3RyZWF0bWVudF9ENSA8LSBlbnRyZXpfZG93bl90cmVhdG1lbnRfRDVbIWlzLm5hKGVudHJlel9kb3duX3RyZWF0bWVudF9ENSldDQoNCiMgR08gQW5hbHlzaXMgLSBUcmVhdG1lbnQNCmdvX3VwX3RyZWF0bWVudF9ENSA8LSBlbnJpY2hHTyhnZW5lID0gc2lnX2dlbmVzX3VwX3RyZWF0bWVudF9ENSwgT3JnRGIgPSBvcmcuSHMuZWcuZGIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSAiRU5TRU1CTCIsIG9udCA9ICJBTEwiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIHB2YWx1ZUN1dG9mZiA9IDAuMDUpDQphcy5kYXRhLmZyYW1lKGdvX3VwX3RyZWF0bWVudF9ENSkNCg0KZ29fdHJlYXRtZW50X3VwX0Q1IDwtIGJhcnBsb3QoZ29fdXBfdHJlYXRtZW50X0Q1LCBzaG93Q2F0ZWdvcnkgPSAxNSkgKyBsYWJzKHRpdGxlID0gIkdPIFVwOiBHZWZpdGluaWIgdnMgRE1TTyIpDQoNCmdnc2F2ZSgiR09fdHJlYXRtZW50X3VwX0Q1LnBkZiIsIGdvX3RyZWF0bWVudF91cF9ENSwgd2lkdGggPSA3LCBoZWlnaHQgPSA2KQ0KZ2dzYXZlKCJHT190cmVhdG1lbnRfdXBfRDUucG5nIiwgZ29fdHJlYXRtZW50X3VwX0Q1LCB3aWR0aCA9IDcsIGhlaWdodCA9IDYsIGRwaSA9IDMwMCkNCg0KZ29fZG93bl90cmVhdG1lbnRfRDUgPC0gZW5yaWNoR08oZ2VuZSA9IHNpZ19nZW5lc19kb3duX3RyZWF0bWVudF9ENSwgT3JnRGIgPSBvcmcuSHMuZWcuZGIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJFTlNFTUJMIiwgb250ID0gIkFMTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIHB2YWx1ZUN1dG9mZiA9IDAuMDUpDQphcy5kYXRhLmZyYW1lKGdvX2Rvd25fdHJlYXRtZW50X0Q1KQ0KdG9wX2dvX2Rvd25fdHJlYXRtZW50X0Q1IDwtIGdvX2Rvd25fdHJlYXRtZW50X0Q1QHJlc3VsdFsxOjEwLCBdDQphcy5kYXRhLmZyYW1lKHRvcF9nb19kb3duX3RyZWF0bWVudF9ENSkNCg0KZ29fdHJlYXRtZW50X2Rvd25fRDUgPC0gYmFycGxvdChnb19kb3duX3RyZWF0bWVudF9ENSwgc2hvd0NhdGVnb3J5ID0gMTUpICsgbGFicyh0aXRsZSA9ICJHTyBEb3duOiBHZWZpdGluaWIgdnMgRE1TTyIpDQoNCmdnc2F2ZSgiR09fdHJlYXRtZW50X2Rvd25fRDUucGRmIiwgZ29fdHJlYXRtZW50X2Rvd25fRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNikNCmdnc2F2ZSgiR09fdHJlYXRtZW50X2Rvd25fRDUucG5nIiwgZ29fdHJlYXRtZW50X2Rvd25fRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNiwgZHBpID0gMzAwKQ0KDQoNCiMgS0VHRyBBbmFseXNpcyAtIFRyZWF0bWVudA0Ka2VnZ191cF90cmVhdG1lbnRfRDUgPC0gZW5yaWNoS0VHRyhnZW5lID0gZW50cmV6X3VwX3RyZWF0bWVudF9ENSwgb3JnYW5pc20gPSAnaHNhJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMSwgcEFkanVzdE1ldGhvZCA9ICJCSCIpDQphcy5kYXRhLmZyYW1lKGtlZ2dfdXBfdHJlYXRtZW50X0Q1KQ0Ka2VnZ190cmVhdG1lbnRfdXBfRDUgPC0gYmFycGxvdChrZWdnX3VwX3RyZWF0bWVudF9ENSwgc2hvd0NhdGVnb3J5ID0gMTUpICsgbGFicyh0aXRsZSA9ICJLRUdHIFVwOiBHZWZpdGluaWIgdnMgRE1TTyIpDQoNCmdnc2F2ZSgiS0VHR190cmVhdG1lbnRfdXBfRDUucGRmIiwga2VnZ190cmVhdG1lbnRfdXBfRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNikNCmdnc2F2ZSgiS0VHR190cmVhdG1lbnRfdXBfRDUucG5nIiwga2VnZ190cmVhdG1lbnRfdXBfRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNiwgZHBpID0gMzAwKQ0KDQprZWdnX2Rvd25fdHJlYXRtZW50X0Q1IDwtIGVucmljaEtFR0coZ2VuZSA9IGVudHJlel9kb3duX3RyZWF0bWVudF9ENSwgb3JnYW5pc20gPSAnaHNhJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4xLCBwQWRqdXN0TWV0aG9kID0gIkJIIikNCmFzLmRhdGEuZnJhbWUoa2VnZ19kb3duX3RyZWF0bWVudF9ENSkNCmtlZ2dfdHJlYXRtZW50X2Rvd25fRDUgPC0gYmFycGxvdChrZWdnX2Rvd25fdHJlYXRtZW50X0Q1LCBzaG93Q2F0ZWdvcnkgPSAxNSkgKyBsYWJzKHRpdGxlID0gIktFR0cgRG93bjogR2VmaXRpbmliIHZzIERNU08iKQ0KDQpnZ3NhdmUoIktFR0dfdHJlYXRtZW50X2Rvd25fRDUucGRmIiwga2VnZ190cmVhdG1lbnRfZG93bl9ENSwgd2lkdGggPSA3LCBoZWlnaHQgPSA2KQ0KZ2dzYXZlKCJLRUdHX3RyZWF0bWVudF9kb3duX0Q1LnBuZyIsIGtlZ2dfdHJlYXRtZW50X2Rvd25fRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNiwgZHBpID0gMzAwKQ0KDQojIENFTEwgTElORSBFRkZFQ1QgUEFUSFdBWVMNCiMgU2VwYXJhdGUgdXAvZG93biBnZW5lcw0Kc2lnX2dlbmVzX3VwX2NlbGxsaW5lX0Q1IDwtIHJvd25hbWVzKHNpZ19jZWxsbGluZV9ENSlbc2lnX2NlbGxsaW5lX0Q1JGxvZzJGb2xkQ2hhbmdlID4gMV0NCnNpZ19nZW5lc19kb3duX2NlbGxsaW5lX0Q1IDwtIHJvd25hbWVzKHNpZ19jZWxsbGluZV9ENSlbc2lnX2NlbGxsaW5lX0Q1JGxvZzJGb2xkQ2hhbmdlIDwgLTFdDQoNCiMgQ29udmVydCB0byBFTlRSRVoNCmVudHJlel91cF9jZWxsbGluZV9ENSA8LSBtYXBJZHMob3JnLkhzLmVnLmRiLCBzaWdfZ2VuZXNfdXBfY2VsbGxpbmVfRDUsICJFTlRSRVpJRCIsICJFTlNFTUJMIikNCmVudHJlel9kb3duX2NlbGxsaW5lX0Q1IDwtIG1hcElkcyhvcmcuSHMuZWcuZGIsIHNpZ19nZW5lc19kb3duX2NlbGxsaW5lX0Q1LCAiRU5UUkVaSUQiLCAiRU5TRU1CTCIpDQplbnRyZXpfdXBfY2VsbGxpbmVfRDUgPC0gZW50cmV6X3VwX2NlbGxsaW5lX0Q1WyFpcy5uYShlbnRyZXpfdXBfY2VsbGxpbmVfRDUpXQ0KZW50cmV6X2Rvd25fY2VsbGxpbmVfRDUgPC0gZW50cmV6X2Rvd25fY2VsbGxpbmVfRDVbIWlzLm5hKGVudHJlel9kb3duX2NlbGxsaW5lX0Q1KV0NCg0KIyBHTyBBbmFseXNpcyAtIENlbGwgTGluZQ0KZ29fdXBfY2VsbGxpbmVfRDUgPC0gZW5yaWNoR08oZ2VuZSA9IHNpZ19nZW5lc191cF9jZWxsbGluZV9ENSwgT3JnRGIgPSBvcmcuSHMuZWcuZGIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJFTlNFTUJMIiwgb250ID0gIkFMTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIHB2YWx1ZUN1dG9mZiA9IDAuMDUpDQphcy5kYXRhLmZyYW1lKGdvX3VwX2NlbGxsaW5lX0Q1KQ0KZ29fY2VsbGxpbmVfdXBfRDUgPC0gYmFycGxvdChnb191cF9jZWxsbGluZV9ENSwgc2hvd0NhdGVnb3J5ID0gMTUpICsgbGFicyh0aXRsZSA9ICJHTyBVcDogSENDNDAwNiB2cyBIQ0M4MjciKQ0KDQpnZ3NhdmUoIkdPX2NlbGxsaW5lX3VwX0Q1LnBkZiIsIGdvX2NlbGxsaW5lX3VwX0Q1LCB3aWR0aCA9IDcsIGhlaWdodCA9IDYpDQpnZ3NhdmUoIkdPX2NlbGxsaW5lX3VwX0Q1LnBuZyIsIGdvX2NlbGxsaW5lX3VwX0Q1LCB3aWR0aCA9IDcsIGhlaWdodCA9IDYsIGRwaSA9IDMwMCkNCg0KZ29fZG93bl9jZWxsbGluZV9ENSA8LSBlbnJpY2hHTyhnZW5lID0gc2lnX2dlbmVzX2Rvd25fY2VsbGxpbmVfRDUsIE9yZ0RiID0gb3JnLkhzLmVnLmRiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJFTlNFTUJMIiwgb250ID0gIkFMTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiwgcHZhbHVlQ3V0b2ZmID0gMC4wNSkNCmFzLmRhdGEuZnJhbWUoZ29fZG93bl9jZWxsbGluZV9ENSkNCmdvX2NlbGxsaW5lX2Rvd25fRDUgPC0gYmFycGxvdChnb19kb3duX2NlbGxsaW5lX0Q1LCBzaG93Q2F0ZWdvcnkgPSAxNSkgKyBsYWJzKHRpdGxlID0gIkdPIERvd246IEhDQzQwMDYgdnMgSENDODI3IikNCg0KZ2dzYXZlKCJHT19jZWxsbGluZV9kb3duX0Q1LnBkZiIsIGdvX2NlbGxsaW5lX2Rvd25fRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNikNCmdnc2F2ZSgiR09fY2VsbGxpbmVfZG93bl9ENS5wbmciLCBnb19jZWxsbGluZV9kb3duX0Q1LCB3aWR0aCA9IDcsIGhlaWdodCA9IDYsIGRwaSA9IDMwMCkNCg0KIyBLRUdHIEFuYWx5c2lzIC0gQ2VsbCBMaW5lDQprZWdnX3VwX2NlbGxsaW5lX0Q1IDwtIGVucmljaEtFR0coZ2VuZSA9IGVudHJlel91cF9jZWxsbGluZV9ENSwgb3JnYW5pc20gPSAnaHNhJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSwgcEFkanVzdE1ldGhvZCA9ICJCSCIpDQphcy5kYXRhLmZyYW1lKGtlZ2dfdXBfY2VsbGxpbmVfRDUpDQprZWdnX2NlbGxsaW5lX3VwX0Q1IDwtIGJhcnBsb3Qoa2VnZ191cF9jZWxsbGluZV9ENSwgc2hvd0NhdGVnb3J5ID0gMTUpICsgbGFicyh0aXRsZSA9ICJLRUdHIFVwOiBIQ0M0MDA2IHZzIEhDQzgyNyIpDQoNCmdnc2F2ZSgiS0VHR19jZWxsbGluZV91cF9ENS5wZGYiLCBrZWdnX2NlbGxsaW5lX3VwX0Q1LCB3aWR0aCA9IDcsIGhlaWdodCA9IDYpDQpnZ3NhdmUoIktFR0dfY2VsbGxpbmVfdXBfRDUucG5nIiwga2VnZ19jZWxsbGluZV91cF9ENSwgd2lkdGggPSA3LCBoZWlnaHQgPSA2LCBkcGkgPSAzMDApDQoNCmtlZ2dfZG93bl9jZWxsbGluZV9ENSA8LSBlbnJpY2hLRUdHKGdlbmUgPSBlbnRyZXpfZG93bl9jZWxsbGluZV9ENSwgb3JnYW5pc20gPSAnaHNhJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1LCBwQWRqdXN0TWV0aG9kID0gIkJIIikNCmFzLmRhdGEuZnJhbWUoa2VnZ19kb3duX2NlbGxsaW5lX0Q1KQ0Ka2VnZ19jZWxsbGluZV9kb3duX0Q1IDwtIGJhcnBsb3Qoa2VnZ19kb3duX2NlbGxsaW5lX0Q1LCBzaG93Q2F0ZWdvcnkgPSAxNSkgKyBsYWJzKHRpdGxlID0gIktFR0cgRG93bjogSENDNDAwNiB2cyBIQ0M4MjciKQ0KDQpnZ3NhdmUoIktFR0dfY2VsbGxpbmVfZG93bl9ENS5wZGYiLCBrZWdnX2NlbGxsaW5lX2Rvd25fRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNikNCmdnc2F2ZSgiS0VHR19jZWxsbGluZV9kb3duX0Q1LnBuZyIsIGtlZ2dfY2VsbGxpbmVfZG93bl9ENSwgd2lkdGggPSA3LCBoZWlnaHQgPSA2LCBkcGkgPSAzMDApDQoNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShmZ3NlYSkNCmxpYnJhcnkobXNpZ2RicikNCg0KIyBUUkVBVE1FTlQgR1NFQQ0KIyBQcmVwYXJlIHJhbmtlZCBnZW5lIGxpc3QNCmdlbmVfcmFua3NfdHJlYXRtZW50X0Q1IDwtIHJlc190cmVhdG1lbnRfRDUkbG9nMkZvbGRDaGFuZ2UNCm5hbWVzKGdlbmVfcmFua3NfdHJlYXRtZW50X0Q1KSA8LSByb3duYW1lcyhyZXNfdHJlYXRtZW50X0Q1KQ0KZ2VuZV9yYW5rc190cmVhdG1lbnRfRDUgPC0gZ2VuZV9yYW5rc190cmVhdG1lbnRfRDVbIWlzLm5hKGdlbmVfcmFua3NfdHJlYXRtZW50X0Q1KV0NCmdlbmVfcmFua3NfdHJlYXRtZW50X0Q1IDwtIHNvcnQoZ2VuZV9yYW5rc190cmVhdG1lbnRfRDUsIGRlY3JlYXNpbmcgPSBUUlVFKQ0KDQojIEdldCBIYWxsbWFyayBwYXRod2F5cw0KaGFsbG1hcmtfc2V0c19ENSA8LSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIiwgY2F0ZWdvcnkgPSAiSCIpDQpoYWxsbWFya19saXN0X0Q1IDwtIHNwbGl0KGhhbGxtYXJrX3NldHNfRDUkZW5zZW1ibF9nZW5lLCBoYWxsbWFya19zZXRzX0Q1JGdzX25hbWUpDQoNCkJpb2NQYXJhbGxlbDo6cmVnaXN0ZXIoQmlvY1BhcmFsbGVsOjpTZXJpYWxQYXJhbSgpKQ0KDQojIFJ1biBHU0VBDQpmZ3NlYV90cmVhdG1lbnRfRDUgPC0gZmdzZWFNdWx0aWxldmVsKHBhdGh3YXlzID0gaGFsbG1hcmtfbGlzdF9ENSwgc3RhdHMgPSBnZW5lX3JhbmtzX3RyZWF0bWVudF9ENSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5TaXplID0gMTUsIG1heFNpemUgPSA1MDApDQoNCnByaW50KCJUb3AgR1NFQSBSZXN1bHRzIC0gVHJlYXRtZW50IChHZWZpdGluaWIgdnMgRE1TTyk6IikNCnByaW50KGhlYWQoZmdzZWFfdHJlYXRtZW50X0Q1W29yZGVyKHB2YWwpLCBdLCAxMCkpDQp0b3BfcGF0aHdheXNfdHJlYXRtZW50X0Q1IDwtIGhlYWQoZmdzZWFfdHJlYXRtZW50X0Q1W29yZGVyKHB2YWwpLCBdLCAzKQ0KDQojIFBsb3QgdG9wIDMgcGF0aHdheXMNCmZvcihpIGluIDE6Mykgew0KICBwMV9ENSA8LSB0b3BfcGF0aHdheXNfdHJlYXRtZW50X0Q1JHBhdGh3YXlbaV0NCiAgcGF0aHdheXNfdHJlYXRtZW50X0Q1IDwtIHBsb3RFbnJpY2htZW50KGhhbGxtYXJrX2xpc3RfRDVbW3AxX0Q1XV0sIGdlbmVfcmFua3NfdHJlYXRtZW50X0Q1KSArIA0KICAgIGxhYnModGl0bGUgPSBwYXN0ZSgiUGF0aHdheSIsIGksICI6IiwgcDFfRDUpKQ0KICBwcmludChwYXRod2F5c190cmVhdG1lbnRfRDUpDQogIGdnc2F2ZSgiVG9wM19HU0VBdHJlYXRtZW50X0Q1LnBkZiIsIHBhdGh3YXlzX3RyZWF0bWVudF9ENSwgd2lkdGggPSA3LCBoZWlnaHQgPSA2KQ0KICBnZ3NhdmUoIlRvcDNfR1NFQXRyZWF0bWVudF9ENS5wbmciLCBwYXRod2F5c190cmVhdG1lbnRfRDUsIHdpZHRoID0gNywgaGVpZ2h0ID0gNiwgZHBpID0gMzAwKQ0KfQ0KIyBDRUxMIExJTkUgR1NFQQ0KIyBQcmVwYXJlIHJhbmtlZCBnZW5lIGxpc3QNCmdlbmVfcmFua3NfY2VsbGxpbmVfRDUgPC0gcmVzX2NlbGxsaW5lX0Q1JGxvZzJGb2xkQ2hhbmdlDQpuYW1lcyhnZW5lX3JhbmtzX2NlbGxsaW5lX0Q1KSA8LSByb3duYW1lcyhyZXNfY2VsbGxpbmVfRDUpDQpnZW5lX3JhbmtzX2NlbGxsaW5lX0Q1IDwtIGdlbmVfcmFua3NfY2VsbGxpbmVfRDVbIWlzLm5hKGdlbmVfcmFua3NfY2VsbGxpbmVfRDUpXQ0KZ2VuZV9yYW5rc19jZWxsbGluZV9ENSA8LSBzb3J0KGdlbmVfcmFua3NfY2VsbGxpbmVfRDUsIGRlY3JlYXNpbmcgPSBUUlVFKQ0KDQojIFJ1biBHU0VBDQpmZ3NlYV9jZWxsbGluZV9ENSA8LSBmZ3NlYU11bHRpbGV2ZWwocGF0aHdheXMgPSBoYWxsbWFya19saXN0X0Q1LCBzdGF0cyA9IGdlbmVfcmFua3NfY2VsbGxpbmVfRDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5TaXplID0gMTUsIG1heFNpemUgPSA1MDApDQoNCnByaW50KCJUb3AgR1NFQSBSZXN1bHRzIC0gQ2VsbCBMaW5lIChIQ0M0MDA2IHZzIEhDQzgyNyk6IikNCnByaW50KGhlYWQoZmdzZWFfY2VsbGxpbmVfRDVbb3JkZXIocHZhbCksIF0sIDEwKSkNCnRvcF9wYXRod2F5c19jZWxsbGluZV9ENSA8LSBoZWFkKGZnc2VhX2NlbGxsaW5lX0Q1W29yZGVyKHB2YWwpLCBdLCAzKQ0KDQojIFBsb3QgdG9wIDMgcGF0aHdheXMNCmZvcihpIGluIDE6Mykgew0KICBwMl9ENSA8LSB0b3BfcGF0aHdheXNfY2VsbGxpbmVfRDUkcGF0aHdheVtpXQ0KICBwYXRod2F5c19jZWxsbGluZV9ENSA8LSBwbG90RW5yaWNobWVudChoYWxsbWFya19saXN0X0Q1W1twMl9ENV1dLCBnZW5lX3JhbmtzX2NlbGxsaW5lX0Q1KSArIA0KICAgIGxhYnModGl0bGUgPSBwYXN0ZSgiUGF0aHdheSIsIGksICI6IiwgcDJfRDUpKQ0KICBwcmludChwYXRod2F5c19jZWxsbGluZV9ENSkNCiAgZ2dzYXZlKCJUb3AzX0dTRUFjZWxsbGluZV9ENS5wZGYiLCBwYXRod2F5c19jZWxsbGluZV9ENSwgd2lkdGggPSA3LCBoZWlnaHQgPSA2KQ0KICBnZ3NhdmUoIlRvcDNfR1NFQWNlbGxsaW5lX0Q1LnBuZyIsIHBhdGh3YXlzX2NlbGxsaW5lX0Q1LCB3aWR0aCA9IDcsIGhlaWdodCA9IDYsIGRwaSA9IDMwMCkNCn0NCmBgYA0KDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgdGFibGUgZm9yIEQ1DQpzdW1tYXJ5X3N0YXRzX0Q1IDwtIGRhdGEuZnJhbWUoDQogIE1ldHJpYyA9IGMoIlRvdGFsIFNhbXBsZXMiLCAiR2VuZXMgQW5hbHl6ZWQgLSBUcmV0YW1lbnQiLCAiR2VuZSBBbmFseXplZCAtIENlbGwgTGluZSIsICJTaWduaWZpY2FudCBERUdzIC0gVHJlYXRtZW50IiwgIlNpZ25pZmljYW50IERFR3MgLSBDZWxsIExpbmUiLCJVcHJlZ3VsYXRlZCBnZW5lcyAtIFRyZWF0bWVudCIsICJEb3ducmVndWxhdGVkIGdlbmVzIC0gVHJlYXRtZW50IiwgIlVwcmVndWxhdGVkIGdlbmVzIC0gQ2VsbCBMaW5lIiwgIlVwcmVndWxhdGVkIGdlbmVzIC0gQ2VsbCBMaW5lIiksDQogIFZhbHVlID0gYyhuY29sKGNvdW50c19ENSksIA0KICAgICAgICAgICAgbnJvdyhyZXNfdHJlYXRtZW50X2Fubm90YXRlZF9ENSksDQogICAgICAgICAgICBucm93KHJlc19jZWxsbGluZV9hbm5vdGF0ZWRfRDUpLA0KICAgICAgICAgICAgbnJvdyhzaWdfdHJlYXRtZW50X0Q1KSwNCiAgICAgICAgICAgIG5yb3coc2lnX2NlbGxsaW5lX0Q1KSwNCiAgICAgICAgICAgIGxlbmd0aChzaWdfZ2VuZXNfdXBfdHJlYXRtZW50X0Q1KSwNCiAgICAgICAgICAgIGxlbmd0aChzaWdfZ2VuZXNfZG93bl90cmVhdG1lbnRfRDUpLA0KICAgICAgICAgICAgbGVuZ3RoKHNpZ19nZW5lc191cF9jZWxsbGluZV9ENSksDQogICAgICAgICAgICBsZW5ndGgoc2lnX2dlbmVzX2Rvd25fY2VsbGxpbmVfRDUpKQ0KKQ0KDQpzdW1tYXJ5X3N0YXRzX0Q1DQoNCiMgVG9wIGdlbmVzIHRhYmxlDQp0b3BfZ2VuZXNfdHJlYXRtZW50X0Q1IDwtIGRhdGEuZnJhbWUoDQogIEdlbmVfU3ltYm9sID0gZ2VuZV9zeW1ib2xzX0Q1W3Jvd25hbWVzKGhlYWQoc2lnX3RyZWF0bWVudF9ENVtvcmRlcihzaWdfdHJlYXRtZW50X0Q1JHBhZGopLF0sIDIwKSldLA0KICBFTlNFTUJMX0lEID0gcm93bmFtZXMoaGVhZChzaWdfdHJlYXRtZW50X0Q1W29yZGVyKHNpZ190cmVhdG1lbnRfRDUkcGFkaiksXSwgMjApKSwNCiAgTG9nMkZDID0gcm91bmQoaGVhZChzaWdfdHJlYXRtZW50X0Q1W29yZGVyKHNpZ190cmVhdG1lbnRfRDUkcGFkaiksXSwgMjApJGxvZzJGb2xkQ2hhbmdlLCAzKSwNCiAgUGFkaiA9IGZvcm1hdChoZWFkKHNpZ190cmVhdG1lbnRfRDVbb3JkZXIoc2lnX3RyZWF0bWVudF9ENSRwYWRqKSxdLCAyMCkkcGFkaiwgc2NpZW50aWZpYyA9IFRSVUUsIGRpZ2l0cyA9IDMpLA0KICBEaXJlY3Rpb24gPSBpZmVsc2UoaGVhZChzaWdfdHJlYXRtZW50X0Q1W29yZGVyKHNpZ190cmVhdG1lbnRfRDUkcGFkaiksXSwgMjApJGxvZzJGb2xkQ2hhbmdlID4gMCwgIlVwIiwgIkRvd24iKQ0KKQ0KDQpwcmludCgiVG9wIDIwIFNpZ25pZmljYW50IEdlbmVzOiBUcmVhdG1lbnQiKQ0KcHJpbnQodG9wX2dlbmVzX3RyZWF0bWVudF9ENSkNCg0KdG9wX2dlbmVzX2NlbGxsaW5lX0Q1IDwtIGRhdGEuZnJhbWUoDQogIEdlbmVfU3ltYm9sID0gZ2VuZV9zeW1ib2xzX0Q1W3Jvd25hbWVzKGhlYWQoc2lnX2NlbGxsaW5lX0Q1W29yZGVyKHNpZ19jZWxsbGluZV9ENSRwYWRqKSxdLCAyMCkpXSwNCiAgRU5TRU1CTF9JRCA9IHJvd25hbWVzKGhlYWQoc2lnX2NlbGxsaW5lX0Q1W29yZGVyKHNpZ19jZWxsbGluZV9ENSRwYWRqKSxdLCAyMCkpLA0KICBMb2cyRkMgPSByb3VuZChoZWFkKHNpZ19jZWxsbGluZV9ENVtvcmRlcihzaWdfY2VsbGxpbmVfRDUkcGFkaiksXSwgMjApJGxvZzJGb2xkQ2hhbmdlLCAzKSwNCiAgUGFkaiA9IGZvcm1hdChoZWFkKHNpZ19jZWxsbGluZV9ENVtvcmRlcihzaWdfY2VsbGxpbmVfRDUkcGFkaiksXSwgMjApJHBhZGosIHNjaWVudGlmaWMgPSBUUlVFLCBkaWdpdHMgPSAzKSwNCiAgRGlyZWN0aW9uID0gaWZlbHNlKGhlYWQoc2lnX2NlbGxsaW5lX0Q1W29yZGVyKHNpZ19jZWxsbGluZV9ENSRwYWRqKSxdLCAyMCkkbG9nMkZvbGRDaGFuZ2UgPiAwLCAiVXAiLCAiRG93biIpDQopDQoNCnByaW50KCJUb3AgMjAgU2lnbmlmaWNhbnQgR2VuZXM6IENlbGwgTGluZSIpDQpwcmludCh0b3BfZ2VuZXNfY2VsbGxpbmVfRDUpDQoNCmBgYA0KDQpgYGB7cn0NCiMgRXhwb3J0IG1haW4gcmVzdWx0cw0Kd3JpdGUuY3N2KGFzLmRhdGEuZnJhbWUocmVzX3RyZWF0bWVudF9hbm5vdGF0ZWRfRDUpLCAiRDVfdHJlYXRtZW50X3Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCndyaXRlLmNzdihzaWdfdHJlYXRtZW50X0Q1LCAiRDVfc2lnX3RyZWF0bWVudF9nZW5lcy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0Kd3JpdGUuY3N2KHN1bW1hcnlfc3RhdHNfRDUsICJENV9zdW1tYXJ5X3N0YXRpc3RpY3MuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQp3cml0ZS5jc3YodG9wX2dlbmVzX3RyZWF0bWVudF9ENSwgIkQ1X3RvcDIwX3RyZWF0bWVudF9nZW5lcy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KIyBFeHBvcnQgbm9ybWFsaXplZCBkYXRhDQp3cml0ZS5jc3YocmVzX2Fubm90YXRlZF9ENSwgIkQ1X3Jlc3VsdHMuY3N2IikNCndyaXRlLmNzdihjb3VudHMoZGRzX0Q1LCBub3JtYWxpemVkPVRSVUUpLCAiRDVfbm9ybWFsaXplZF9jb3VudHMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCndyaXRlLmNzdih2c3RfZmluYWxfRDUsICJENV92c3RfZGF0YS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQojIEV4cG9ydCBwYXRod2F5IHJlc3VsdHMNCiAgd3JpdGUuY3N2KGdvX3VwX3RyZWF0bWVudF9ENUByZXN1bHQsICJENV9HT191cC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KICB3cml0ZS5jc3YoZ29fZG93bl90cmVhdG1lbnRfRDVAcmVzdWx0LCAiRDVfR09fZG93bi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KDQogIHdyaXRlLmNzdihrZWdnX3VwX3RyZWF0bWVudF9ENUByZXN1bHQsICJENV9LRUdHX3VwLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KICANCiAgd3JpdGUuY3N2KGtlZ2dfZG93bl90cmVhdG1lbnRfRDVAcmVzdWx0LCAiRDVfS0VHR19kb3duLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQojIFJlbW92ZSB0aGUgbGVhZGluZ0VkZ2UgY29sdW1uICh3aGljaCBjb250YWlucyBsaXN0cykNCmZnc2VhX3Jlc3VsdHNfY2xlYW5fRDUgPC0gZmdzZWFfdHJlYXRtZW50X0Q1ICU+JQ0KICBzZWxlY3QoLWxlYWRpbmdFZGdlKQ0KDQp3cml0ZS5jc3YoZmdzZWFfcmVzdWx0c19jbGVhbl9ENSwgIkQ1X0dTRUFfaGFsbG1hcmtzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQpgYGANCg0K