.libPaths("/n/data1/cores/ntc/R-4.0.1/library/")
setwd("/n/scratch3/groups/hms/cores/ntc/Weinstock008")

library(DESeq2)

working on master data file with scripts run (bedtools closest and intersect) to link GGA annot genes to dREG filtered annot enhancers. add in counts data from PRO and ATAC across dREG span.

full <- read.table("overall.bed", sep="\t")
colnames(full) <- c("chr_gene", "start_gene", "end_gene", "name_gene", "score_gene", "strand_gene", 
     "chr_peak", "start_peak", "end_peak", "name_peak", "score_peak", "strand_peak", "biotype", "distance")

write.table(full, "TCL_Gene_to_Enhancer_master.txt", quote = FALSE, sep = "\t", row.names = FALSE, col.names = TRUE)

load DEseq and normalize with DEseq size factors based on depth Import gene body counts table generated in O2 into R

normalizing counts for all data types with DEseq size factors and melding to full table

raw_atac <- read.table("TCL_ATAC_counts.txt", header = TRUE, sep = "\t", row.names = 1)
raw_pro <- read.table("TCL_PRO_counts.txt", header = TRUE, sep = "\t", row.names = 1)
raw_rna <- read.table("TCL_RNA_counts.txt", header = TRUE, sep = "\t", row.names = 1)

ATAC first

Create metadata object to categorize samples:

metadata_atac <- data.frame(row.names = colnames(raw_atac[, 6:ncol(raw_atac)]),
                       cell_line = c(rep("TCL",23),rep("Other",1)))
                       
metadata_atac # verify the table looks ok

#confirm that row and column names match
all(rownames(metadata_atac) %in% colnames(raw_atac))
all(rownames(metadata_atac) == colnames(raw_atac)[6:ncol(raw_atac)])


## Create DESeq Data Set from the count table, and sample list:

dds_atac <- DESeqDataSetFromMatrix(countData = raw_atac[, 6:ncol(raw_atac)],      # the matrix of counts from featureCounts;
                              colData = metadata_atac,                     # the sample table created in the last step;
                              design= ~cell_line)            # this is R's notation for models

dds_atac <- estimateSizeFactors(dds_atac)
deseq_sizes_atac <- as.data.frame(sizeFactors(dds_atac))
deseq_sizes_atac
write.table(deseq_sizes_atac, "ATAC_norm_factors.txt", quote = FALSE, sep = "\t", row.names = TRUE, col.names = TRUE)

# normalization of ATAC data

dds_atac <- estimateDispersions(dds_atac)
pdf("Dispersion_ATAC_norm.pdf")
plotDispEsts(dds_atac)
dev.off()

# check results of normalization
colSums(counts(dds_atac))                # raw read counts per sample
colSums(counts(dds_atac, normalized=T))  # Total number of normalized counts per sample
data.frame(colSums(counts(dds_atac)), (colSums(counts(dds_atac, normalized=T))), row.names=colnames(counts(dds_atac)))

write.table(counts(dds_atac, normalized=TRUE), file="ATAC_norm_counts.txt", sep="\t")
counts_atac <- read.table("ATAC_norm_counts.txt", sep="\t")
counts_atac$dREG <- row.names(counts_atac)

full <- merge(full, counts_atac, by.x = "name_peak", by.y = "dREG", all.x=TRUE)

Now PRO

### Create metadata object to categorize samples:

metadata_pro <- data.frame(row.names = colnames(raw_pro[, 6:ncol(raw_pro)]),
                            cell_line = c(rep("TCL_A",12),rep("TCL_B",12)))

metadata_pro # verify the table looks ok

#confirm that row and column names match
all(rownames(metadata_pro) %in% colnames(raw_pro))
all(rownames(metadata_pro) == colnames(raw_pro)[6:ncol(raw_pro)])


## Create DESeq Data Set from the count table, and sample list:

dds_pro <- DESeqDataSetFromMatrix(countData = raw_pro[, 6:ncol(raw_pro)],      # the matrix of counts from featureCounts;
                                   colData = metadata_pro,                     # the sample table created in the last step;
                                   design= ~cell_line)            # this is R's notation for models

dds_pro <- estimateSizeFactors(dds_pro)
deseq_sizes_pro <- as.data.frame(sizeFactors(dds_pro))
deseq_sizes_pro
write.table(deseq_sizes_pro, "PRO_norm_factors.txt", quote = FALSE, sep = "\t", row.names = TRUE, col.names = TRUE)

#normalization of PRO data

dds_pro <- estimateDispersions(dds_pro)
pdf("Dispersion_PRO_norm.pdf")
plotDispEsts(dds_pro)
dev.off()

# check results of normalization
colSums(counts(dds_pro))                # raw read counts per sample
colSums(counts(dds_pro, normalized=T))  # Total number of normalized counts per sample
data.frame(colSums(counts(dds_pro)), (colSums(counts(dds_pro, normalized=T))), row.names=colnames(counts(dds_pro)))

write.table(counts(dds_pro, normalized=TRUE), file="PRO_norm_counts.txt", sep="\t")
counts_pro <- read.table("PRO_norm_counts.txt", sep="\t")
counts_pro$dREG <- row.names(counts_pro)


full <- merge(full, counts_pro, by.x = "name_peak", by.y = "dREG", all.x=TRUE)

Now RNA

### Create metadata object to categorize samples:

metadata_rna <- data.frame(row.names = colnames(raw_rna[, 6:ncol(raw_rna)]),
                            cell_line = c(rep("TCL_A",12),rep("TCL_B",12)))

metadata_rna # verify the table looks ok

#confirm that row and column names match
all(rownames(metadata_rna) %in% colnames(raw_rna))
all(rownames(metadata_rna) == colnames(raw_rna)[6:ncol(raw_rna)])


## Create DESeq Data Set from the count table, and sample list:

dds_rna <- DESeqDataSetFromMatrix(countData = raw_rna[, 6:ncol(raw_rna)],      # the matrix of counts from featureCounts;
                                   colData = metadata_rna,                     # the sample table created in the last step;
                                   design= ~cell_line)            # this is R's notation for models

dds_rna <- estimateSizeFactors(dds_rna)
deseq_sizes_rna <- as.data.frame(sizeFactors(dds_rna))
deseq_sizes_rna
write.table(deseq_sizes_rna, "RNA_norm_factors.txt", quote = FALSE, sep = "\t", row.names = TRUE, col.names = TRUE)

#normalization of RNA data

dds_rna <- estimateDispersions(dds_rna)
pdf("Dispersion_RNA_norm.pdf")
plotDispEsts(dds_rna)
dev.off()

# check results of normalization
colSums(counts(dds_rna))                # raw read counts per sample
colSums(counts(dds_rna, normalized=T))  # Total number of normalized counts per sample
data.frame(colSums(counts(dds_rna)), (colSums(counts(dds_rna, normalized=T))), row.names=colnames(counts(dds_rna)))

write.table(counts(dds_rna, normalized=TRUE), file="RNA_norm_counts.txt", sep="\t")
counts_rna <- read.table("RNA_norm_counts.txt", sep="\t")
counts_rna$dREG <- row.names(counts_rna)

full <- merge(full, counts_rna, by.x = "name_peak", by.y = "dREG", all.x=TRUE)

final table completed

write.table(full, "TCL_Final_gene_to_enhancer.txt", quote = FALSE, sep = "\t", row.names = FALSE, col.names = TRUE)

# clean-up and save out DEseq data sets

saveRDS(dds_atac, file="ATAC.rds")
saveRDS(dds_pro, file="PRO.rds")
saveRDS(dds_rna, file="RNA.rds")

######### END #########
## MKJ 24JUL24
LS0tCnRpdGxlOiAiQ29tYmluZWQgVCBDZWxsIEx5bXBob21hIENlbGwgTGluZSBBbmFseXNpcyBvZiBSTkEtc2VxLCBQUk8tc2VxLCBhbmQgQVRBQy1zZXEiCm91dHB1dDogaHRtbF9ub3RlYm9vawplZGl0b3Jfb3B0aW9uczogCmNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7cn0KLmxpYlBhdGhzKCIvbi9kYXRhMS9jb3Jlcy9udGMvUi00LjAuMS9saWJyYXJ5LyIpCnNldHdkKCIvbi9zY3JhdGNoMy9ncm91cHMvaG1zL2NvcmVzL250Yy9XZWluc3RvY2swMDgiKQoKbGlicmFyeShERVNlcTIpCgpgYGAKCndvcmtpbmcgb24gbWFzdGVyIGRhdGEgZmlsZSB3aXRoIHNjcmlwdHMgcnVuIChiZWR0b29scyBjbG9zZXN0IGFuZCBpbnRlcnNlY3QpIHRvIGxpbmsgR0dBIGFubm90IGdlbmVzIHRvIGRSRUcgZmlsdGVyZWQgYW5ub3QgZW5oYW5jZXJzLgphZGQgaW4gY291bnRzIGRhdGEgZnJvbSBQUk8gYW5kIEFUQUMgYWNyb3NzIGRSRUcgc3Bhbi4KCmBgYHtyfQpmdWxsIDwtIHJlYWQudGFibGUoIm92ZXJhbGwuYmVkIiwgc2VwPSJcdCIpCmNvbG5hbWVzKGZ1bGwpIDwtIGMoImNocl9nZW5lIiwgInN0YXJ0X2dlbmUiLCAiZW5kX2dlbmUiLCAibmFtZV9nZW5lIiwgInNjb3JlX2dlbmUiLCAic3RyYW5kX2dlbmUiLCAKICAgICAiY2hyX3BlYWsiLCAic3RhcnRfcGVhayIsICJlbmRfcGVhayIsICJuYW1lX3BlYWsiLCAic2NvcmVfcGVhayIsICJzdHJhbmRfcGVhayIsICJiaW90eXBlIiwgImRpc3RhbmNlIikKCndyaXRlLnRhYmxlKGZ1bGwsICJUQ0xfR2VuZV90b19FbmhhbmNlcl9tYXN0ZXIudHh0IiwgcXVvdGUgPSBGQUxTRSwgc2VwID0gIlx0Iiwgcm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IFRSVUUpCmBgYAoKbG9hZCBERXNlcSBhbmQgbm9ybWFsaXplIHdpdGggREVzZXEgc2l6ZSBmYWN0b3JzIGJhc2VkIG9uIGRlcHRoCkltcG9ydCBnZW5lIGJvZHkgY291bnRzIHRhYmxlIGdlbmVyYXRlZCBpbiBPMiBpbnRvIFIKCm5vcm1hbGl6aW5nIGNvdW50cyBmb3IgYWxsIGRhdGEgdHlwZXMgd2l0aCBERXNlcSBzaXplIGZhY3RvcnMgYW5kIG1lbGRpbmcgdG8gZnVsbCB0YWJsZQoKYGBge3J9CnJhd19hdGFjIDwtIHJlYWQudGFibGUoIlRDTF9BVEFDX2NvdW50cy50eHQiLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiLCByb3cubmFtZXMgPSAxKQpyYXdfcHJvIDwtIHJlYWQudGFibGUoIlRDTF9QUk9fY291bnRzLnR4dCIsIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIsIHJvdy5uYW1lcyA9IDEpCnJhd19ybmEgPC0gcmVhZC50YWJsZSgiVENMX1JOQV9jb3VudHMudHh0IiwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0Iiwgcm93Lm5hbWVzID0gMSkKCmBgYAoKIyBBVEFDIGZpcnN0ICMjIyMjCiMjIyBDcmVhdGUgbWV0YWRhdGEgb2JqZWN0IHRvIGNhdGVnb3JpemUgc2FtcGxlczoKCmBgYHtyfQptZXRhZGF0YV9hdGFjIDwtIGRhdGEuZnJhbWUocm93Lm5hbWVzID0gY29sbmFtZXMocmF3X2F0YWNbLCA2Om5jb2wocmF3X2F0YWMpXSksCiAgICAgICAgICAgICAgICAgICAgICAgY2VsbF9saW5lID0gYyhyZXAoIlRDTCIsMjMpLHJlcCgiT3RoZXIiLDEpKSkKICAgICAgICAgICAgICAgICAgICAgICAKbWV0YWRhdGFfYXRhYyAjIHZlcmlmeSB0aGUgdGFibGUgbG9va3Mgb2sKCiNjb25maXJtIHRoYXQgcm93IGFuZCBjb2x1bW4gbmFtZXMgbWF0Y2gKYWxsKHJvd25hbWVzKG1ldGFkYXRhX2F0YWMpICVpbiUgY29sbmFtZXMocmF3X2F0YWMpKQphbGwocm93bmFtZXMobWV0YWRhdGFfYXRhYykgPT0gY29sbmFtZXMocmF3X2F0YWMpWzY6bmNvbChyYXdfYXRhYyldKQoKCiMjIENyZWF0ZSBERVNlcSBEYXRhIFNldCBmcm9tIHRoZSBjb3VudCB0YWJsZSwgYW5kIHNhbXBsZSBsaXN0OgoKZGRzX2F0YWMgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGEgPSByYXdfYXRhY1ssIDY6bmNvbChyYXdfYXRhYyldLCAgICAgICMgdGhlIG1hdHJpeCBvZiBjb3VudHMgZnJvbSBmZWF0dXJlQ291bnRzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhID0gbWV0YWRhdGFfYXRhYywgICAgICAgICAgICAgICAgICAgICAjIHRoZSBzYW1wbGUgdGFibGUgY3JlYXRlZCBpbiB0aGUgbGFzdCBzdGVwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpZ249IH5jZWxsX2xpbmUpICAgICAgICAgICAgIyB0aGlzIGlzIFIncyBub3RhdGlvbiBmb3IgbW9kZWxzCgpkZHNfYXRhYyA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkc19hdGFjKQpkZXNlcV9zaXplc19hdGFjIDwtIGFzLmRhdGEuZnJhbWUoc2l6ZUZhY3RvcnMoZGRzX2F0YWMpKQpkZXNlcV9zaXplc19hdGFjCndyaXRlLnRhYmxlKGRlc2VxX3NpemVzX2F0YWMsICJBVEFDX25vcm1fZmFjdG9ycy50eHQiLCBxdW90ZSA9IEZBTFNFLCBzZXAgPSAiXHQiLCByb3cubmFtZXMgPSBUUlVFLCBjb2wubmFtZXMgPSBUUlVFKQoKIyBub3JtYWxpemF0aW9uIG9mIEFUQUMgZGF0YQoKZGRzX2F0YWMgPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHNfYXRhYykKcGRmKCJEaXNwZXJzaW9uX0FUQUNfbm9ybS5wZGYiKQpwbG90RGlzcEVzdHMoZGRzX2F0YWMpCmRldi5vZmYoKQoKIyBjaGVjayByZXN1bHRzIG9mIG5vcm1hbGl6YXRpb24KY29sU3Vtcyhjb3VudHMoZGRzX2F0YWMpKSAgICAgICAgICAgICAgICAjIHJhdyByZWFkIGNvdW50cyBwZXIgc2FtcGxlCmNvbFN1bXMoY291bnRzKGRkc19hdGFjLCBub3JtYWxpemVkPVQpKSAgIyBUb3RhbCBudW1iZXIgb2Ygbm9ybWFsaXplZCBjb3VudHMgcGVyIHNhbXBsZQpkYXRhLmZyYW1lKGNvbFN1bXMoY291bnRzKGRkc19hdGFjKSksIChjb2xTdW1zKGNvdW50cyhkZHNfYXRhYywgbm9ybWFsaXplZD1UKSkpLCByb3cubmFtZXM9Y29sbmFtZXMoY291bnRzKGRkc19hdGFjKSkpCgp3cml0ZS50YWJsZShjb3VudHMoZGRzX2F0YWMsIG5vcm1hbGl6ZWQ9VFJVRSksIGZpbGU9IkFUQUNfbm9ybV9jb3VudHMudHh0Iiwgc2VwPSJcdCIpCmNvdW50c19hdGFjIDwtIHJlYWQudGFibGUoIkFUQUNfbm9ybV9jb3VudHMudHh0Iiwgc2VwPSJcdCIpCmNvdW50c19hdGFjJGRSRUcgPC0gcm93Lm5hbWVzKGNvdW50c19hdGFjKQoKZnVsbCA8LSBtZXJnZShmdWxsLCBjb3VudHNfYXRhYywgYnkueCA9ICJuYW1lX3BlYWsiLCBieS55ID0gImRSRUciLCBhbGwueD1UUlVFKQoKYGBgCgojIE5vdyBQUk8gIyMjIyMjIyMjIyMjIyMjCgpgYGB7cn0KIyMjIENyZWF0ZSBtZXRhZGF0YSBvYmplY3QgdG8gY2F0ZWdvcml6ZSBzYW1wbGVzOgoKbWV0YWRhdGFfcHJvIDwtIGRhdGEuZnJhbWUocm93Lm5hbWVzID0gY29sbmFtZXMocmF3X3Byb1ssIDY6bmNvbChyYXdfcHJvKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbF9saW5lID0gYyhyZXAoIlRDTF9BIiwxMikscmVwKCJUQ0xfQiIsMTIpKSkKCm1ldGFkYXRhX3BybyAjIHZlcmlmeSB0aGUgdGFibGUgbG9va3Mgb2sKCiNjb25maXJtIHRoYXQgcm93IGFuZCBjb2x1bW4gbmFtZXMgbWF0Y2gKYWxsKHJvd25hbWVzKG1ldGFkYXRhX3BybykgJWluJSBjb2xuYW1lcyhyYXdfcHJvKSkKYWxsKHJvd25hbWVzKG1ldGFkYXRhX3BybykgPT0gY29sbmFtZXMocmF3X3BybylbNjpuY29sKHJhd19wcm8pXSkKCgojIyBDcmVhdGUgREVTZXEgRGF0YSBTZXQgZnJvbSB0aGUgY291bnQgdGFibGUsIGFuZCBzYW1wbGUgbGlzdDoKCmRkc19wcm8gPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGEgPSByYXdfcHJvWywgNjpuY29sKHJhd19wcm8pXSwgICAgICAjIHRoZSBtYXRyaXggb2YgY291bnRzIGZyb20gZmVhdHVyZUNvdW50czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhID0gbWV0YWRhdGFfcHJvLCAgICAgICAgICAgICAgICAgICAgICMgdGhlIHNhbXBsZSB0YWJsZSBjcmVhdGVkIGluIHRoZSBsYXN0IHN0ZXA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduPSB+Y2VsbF9saW5lKSAgICAgICAgICAgICMgdGhpcyBpcyBSJ3Mgbm90YXRpb24gZm9yIG1vZGVscwoKZGRzX3BybyA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkc19wcm8pCmRlc2VxX3NpemVzX3BybyA8LSBhcy5kYXRhLmZyYW1lKHNpemVGYWN0b3JzKGRkc19wcm8pKQpkZXNlcV9zaXplc19wcm8Kd3JpdGUudGFibGUoZGVzZXFfc2l6ZXNfcHJvLCAiUFJPX25vcm1fZmFjdG9ycy50eHQiLCBxdW90ZSA9IEZBTFNFLCBzZXAgPSAiXHQiLCByb3cubmFtZXMgPSBUUlVFLCBjb2wubmFtZXMgPSBUUlVFKQoKI25vcm1hbGl6YXRpb24gb2YgUFJPIGRhdGEKCmRkc19wcm8gPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHNfcHJvKQpwZGYoIkRpc3BlcnNpb25fUFJPX25vcm0ucGRmIikKcGxvdERpc3BFc3RzKGRkc19wcm8pCmRldi5vZmYoKQoKIyBjaGVjayByZXN1bHRzIG9mIG5vcm1hbGl6YXRpb24KY29sU3Vtcyhjb3VudHMoZGRzX3BybykpICAgICAgICAgICAgICAgICMgcmF3IHJlYWQgY291bnRzIHBlciBzYW1wbGUKY29sU3Vtcyhjb3VudHMoZGRzX3Bybywgbm9ybWFsaXplZD1UKSkgICMgVG90YWwgbnVtYmVyIG9mIG5vcm1hbGl6ZWQgY291bnRzIHBlciBzYW1wbGUKZGF0YS5mcmFtZShjb2xTdW1zKGNvdW50cyhkZHNfcHJvKSksIChjb2xTdW1zKGNvdW50cyhkZHNfcHJvLCBub3JtYWxpemVkPVQpKSksIHJvdy5uYW1lcz1jb2xuYW1lcyhjb3VudHMoZGRzX3BybykpKQoKd3JpdGUudGFibGUoY291bnRzKGRkc19wcm8sIG5vcm1hbGl6ZWQ9VFJVRSksIGZpbGU9IlBST19ub3JtX2NvdW50cy50eHQiLCBzZXA9Ilx0IikKY291bnRzX3BybyA8LSByZWFkLnRhYmxlKCJQUk9fbm9ybV9jb3VudHMudHh0Iiwgc2VwPSJcdCIpCmNvdW50c19wcm8kZFJFRyA8LSByb3cubmFtZXMoY291bnRzX3BybykKCgpmdWxsIDwtIG1lcmdlKGZ1bGwsIGNvdW50c19wcm8sIGJ5LnggPSAibmFtZV9wZWFrIiwgYnkueSA9ICJkUkVHIiwgYWxsLng9VFJVRSkKCmBgYAoKIyBOb3cgUk5BICMjIyMjIyMjIyMjCgpgYGB7cn0KIyMjIENyZWF0ZSBtZXRhZGF0YSBvYmplY3QgdG8gY2F0ZWdvcml6ZSBzYW1wbGVzOgoKbWV0YWRhdGFfcm5hIDwtIGRhdGEuZnJhbWUocm93Lm5hbWVzID0gY29sbmFtZXMocmF3X3JuYVssIDY6bmNvbChyYXdfcm5hKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbF9saW5lID0gYyhyZXAoIlRDTF9BIiwxMikscmVwKCJUQ0xfQiIsMTIpKSkKCm1ldGFkYXRhX3JuYSAjIHZlcmlmeSB0aGUgdGFibGUgbG9va3Mgb2sKCiNjb25maXJtIHRoYXQgcm93IGFuZCBjb2x1bW4gbmFtZXMgbWF0Y2gKYWxsKHJvd25hbWVzKG1ldGFkYXRhX3JuYSkgJWluJSBjb2xuYW1lcyhyYXdfcm5hKSkKYWxsKHJvd25hbWVzKG1ldGFkYXRhX3JuYSkgPT0gY29sbmFtZXMocmF3X3JuYSlbNjpuY29sKHJhd19ybmEpXSkKCgojIyBDcmVhdGUgREVTZXEgRGF0YSBTZXQgZnJvbSB0aGUgY291bnQgdGFibGUsIGFuZCBzYW1wbGUgbGlzdDoKCmRkc19ybmEgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGEgPSByYXdfcm5hWywgNjpuY29sKHJhd19ybmEpXSwgICAgICAjIHRoZSBtYXRyaXggb2YgY291bnRzIGZyb20gZmVhdHVyZUNvdW50czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhID0gbWV0YWRhdGFfcm5hLCAgICAgICAgICAgICAgICAgICAgICMgdGhlIHNhbXBsZSB0YWJsZSBjcmVhdGVkIGluIHRoZSBsYXN0IHN0ZXA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaWduPSB+Y2VsbF9saW5lKSAgICAgICAgICAgICMgdGhpcyBpcyBSJ3Mgbm90YXRpb24gZm9yIG1vZGVscwoKZGRzX3JuYSA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkc19ybmEpCmRlc2VxX3NpemVzX3JuYSA8LSBhcy5kYXRhLmZyYW1lKHNpemVGYWN0b3JzKGRkc19ybmEpKQpkZXNlcV9zaXplc19ybmEKd3JpdGUudGFibGUoZGVzZXFfc2l6ZXNfcm5hLCAiUk5BX25vcm1fZmFjdG9ycy50eHQiLCBxdW90ZSA9IEZBTFNFLCBzZXAgPSAiXHQiLCByb3cubmFtZXMgPSBUUlVFLCBjb2wubmFtZXMgPSBUUlVFKQoKI25vcm1hbGl6YXRpb24gb2YgUk5BIGRhdGEKCmRkc19ybmEgPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHNfcm5hKQpwZGYoIkRpc3BlcnNpb25fUk5BX25vcm0ucGRmIikKcGxvdERpc3BFc3RzKGRkc19ybmEpCmRldi5vZmYoKQoKIyBjaGVjayByZXN1bHRzIG9mIG5vcm1hbGl6YXRpb24KY29sU3Vtcyhjb3VudHMoZGRzX3JuYSkpICAgICAgICAgICAgICAgICMgcmF3IHJlYWQgY291bnRzIHBlciBzYW1wbGUKY29sU3Vtcyhjb3VudHMoZGRzX3JuYSwgbm9ybWFsaXplZD1UKSkgICMgVG90YWwgbnVtYmVyIG9mIG5vcm1hbGl6ZWQgY291bnRzIHBlciBzYW1wbGUKZGF0YS5mcmFtZShjb2xTdW1zKGNvdW50cyhkZHNfcm5hKSksIChjb2xTdW1zKGNvdW50cyhkZHNfcm5hLCBub3JtYWxpemVkPVQpKSksIHJvdy5uYW1lcz1jb2xuYW1lcyhjb3VudHMoZGRzX3JuYSkpKQoKd3JpdGUudGFibGUoY291bnRzKGRkc19ybmEsIG5vcm1hbGl6ZWQ9VFJVRSksIGZpbGU9IlJOQV9ub3JtX2NvdW50cy50eHQiLCBzZXA9Ilx0IikKY291bnRzX3JuYSA8LSByZWFkLnRhYmxlKCJSTkFfbm9ybV9jb3VudHMudHh0Iiwgc2VwPSJcdCIpCmNvdW50c19ybmEkZFJFRyA8LSByb3cubmFtZXMoY291bnRzX3JuYSkKCmZ1bGwgPC0gbWVyZ2UoZnVsbCwgY291bnRzX3JuYSwgYnkueCA9ICJuYW1lX3BlYWsiLCBieS55ID0gImRSRUciLCBhbGwueD1UUlVFKQoKYGBgCgpmaW5hbCB0YWJsZSBjb21wbGV0ZWQKCmBgYHtyfQp3cml0ZS50YWJsZShmdWxsLCAiVENMX0ZpbmFsX2dlbmVfdG9fZW5oYW5jZXIudHh0IiwgcXVvdGUgPSBGQUxTRSwgc2VwID0gIlx0Iiwgcm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IFRSVUUpCgojIGNsZWFuLXVwIGFuZCBzYXZlIG91dCBERXNlcSBkYXRhIHNldHMKCnNhdmVSRFMoZGRzX2F0YWMsIGZpbGU9IkFUQUMucmRzIikKc2F2ZVJEUyhkZHNfcHJvLCBmaWxlPSJQUk8ucmRzIikKc2F2ZVJEUyhkZHNfcm5hLCBmaWxlPSJSTkEucmRzIikKCiMjIyMjIyMjIyBFTkQgIyMjIyMjIyMjCiMjIE1LSiAyNEpVTDI0CmBgYAoKCg==