1. load libraries

2. Enrichment Analysis_part1

# Load necessary libraries ------------------------------------


# Read the TSV file into R
Significant_Genes <- read_csv("/home/bioinfo/18-Enrichment_Analysis_final_Results/2-filtered_All_cell_lines_cells_vs_CD4_Control.csv")
Rows: 3018 Columns: 9── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): gene
dbl (8): mean.All_cell_lines_cells, mean..CD4_Control, Relative.variance.All_cell_lines_cells, Relative.variance.CD4_Con...
ℹ 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.
SS_up  <- subset(Significant_Genes,
                    Significant_Genes$log2FC > 3
                      & Significant_Genes$pValueBH <  0.05)
SS_up_genes <- SS_up$gene


SS_down  <- subset(Significant_Genes,
                    Significant_Genes$log2FC < -1 
                      & Significant_Genes$pValueBH <  0.05)
SS_down_genes <- SS_down$gene


SS_vs_norm_go <- clusterProfiler::enrichGO(SS_up_genes,
                                            "org.Hs.eg.db",
                                            keyType = "SYMBOL",
                                            ont = "BP",
                                            minGSSize = 50)

print(SS_vs_norm_go@result)

enr_go <- clusterProfiler::simplify(SS_vs_norm_go)

print(enr_go@result)

enrichplot::emapplot(enrichplot::pairwise_termsim(enr_go),
                     showCategory = 50)



SS_vs_norm_go <- clusterProfiler::enrichGO(SS_down_genes,
                                            "org.Hs.eg.db",
                                            keyType = "SYMBOL",
                                            ont = "BP",
                                            minGSSize = 50)

print(SS_vs_norm_go@result)

enr_go <- clusterProfiler::simplify(SS_vs_norm_go)

print(enr_go@result)

enrichplot::emapplot(enrichplot::pairwise_termsim(enr_go),
                     showCategory = 50)

NA
NA

3. Enrichment Analysis_part2

gmt <- msigdbr::msigdbr(species = "human", category = "H")

SS_vs_norm_enrich_up <- clusterProfiler::enricher(gene = SS_up_genes,
                                                pAdjustMethod = "BH",
                                                pvalueCutoff  = 0.05,
                                                qvalueCutoff  = 0.05,
                                                TERM2GENE = gmt[,c("gs_name", "gene_symbol")])


print(SS_vs_norm_enrich_up@result[SS_vs_norm_enrich_up@result$p.adjust < 0.05,])


SS_vs_norm_enrich_down <- clusterProfiler::enricher(gene = SS_down_genes,
                                                pAdjustMethod = "BH",
                                                pvalueCutoff  = 0.05,
                                                qvalueCutoff  = 0.05,
                                                TERM2GENE = gmt[,c("gs_name", "gene_symbol")])


print(SS_vs_norm_enrich_down@result[SS_vs_norm_enrich_down@result$p.adjust < 0.05,])
NA

4. Enrichment Analysis_part3

# We use the function `barplot` from package `enrichplot`
graphics::barplot(
  # We provide the variable pointing to enrichment results
  height = SS_vs_norm_enrich_up,
  # We display the best 15 results
  showCategory=15
)



enrichplot::dotplot(
  # We provide the variable pointing to enrichment results
  object = SS_vs_norm_enrich_up,
  # We display the best 15 results
  showCategory=15
)

# We use the function `barplot` from package `enrichplot`
graphics::barplot(
  # We provide the variable pointing to enrichment results
  height = SS_vs_norm_enrich_down,
  # We display the best 15 results
  showCategory=15
)



enrichplot::dotplot(
  # We provide the variable pointing to enrichment results
  object = SS_vs_norm_enrich_down,
  # We display the best 15 results
  showCategory=15
)

5. Enrichment Analysis_part5


# We use the function `heatplot` from `enrichplot` package
# We use the function `upsetplot` from `enrichplot` package
enrichplot::upsetplot(
  # We probide the variable pointing to GSEA results
  x = SS_vs_norm_enrich_up,
  # We show the 10 best results
  n = 10
)


enrichplot::upsetplot(
  # We probide the variable pointing to GSEA results
  x = SS_vs_norm_enrich_down,
  # We show the 10 best results
  n = 10
)

6. Enrichment Analysis_part6


# Load the packages
library(clusterProfiler)
library(ReactomePA)
library(org.Hs.eg.db)
library(pathview)

# Extract the gene symbols and log2FC values for SS_up
gene_list_up <- as.character(SS_up$gene)
log2fc_values_up <- SS_up$log2FC

# Get a list of valid gene symbols from org.Hs.eg.db
valid_symbols <- keys(org.Hs.eg.db, keytype = "SYMBOL")

# Check which gene symbols are not valid
invalid_symbols_up <- setdiff(gene_list_up, valid_symbols)

# Print invalid gene symbols
if (length(invalid_symbols_up) > 0) {
    cat("The following gene symbols are not valid and will be excluded from SS_up:\n")
    print(invalid_symbols_up)
}
The following gene symbols are not valid and will be excluded from SS_up:
 [1] "C19orf48"    "H2AFX"       "WARS"        "VARS"        "WDR34"       "HLA.DMA"     "PALM2.AKAP2" "FAM126A"    
 [9] "AC016747.1"  "CD3EAP"      "AL441992.1"  "C3orf14"     "HLA.DMB"     "ARNTL2"      "AC006064.4"  "AC011603.2" 
[17] "BHLHE40.AS1" "AC093865.1"  "HLA.DPB1"    "HIST1H2AL"   "MSC.AS1"     "HLA.DRB5"    "HLA.DQB1"    "AL590550.1" 
[25] "HIST1H3B"    "AC010967.1"  "HLA.DPA1"    "HIST1H1A"    "HLA.DRA"     "TRBV23.1"    "HLA.DQA1"    "HLA.DRB1"   
[33] "HIST1H1B"    "SLC7A11.AS1" "HLA.DQA2"    "TRAV38.2DV8"
# Filter out invalid gene symbols
gene_list_up <- intersect(gene_list_up, valid_symbols)

# Convert gene symbols to Entrez IDs
entrez_ids_up <- bitr(gene_list_up, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)
'select()' returned 1:1 mapping between keys and columns
# Check for successful conversion
if (nrow(entrez_ids_up) == 0) {
    stop("No gene symbols were converted to Entrez IDs for SS_up.")
}

# Merge Entrez IDs with log2FC values
entrez_ids_up <- merge(entrez_ids_up, SS_up, by.x = "SYMBOL", by.y = "gene")

# Create a named vector of log2FC values with Entrez IDs as names
gene_data_up <- setNames(entrez_ids_up$log2FC, entrez_ids_up$ENTREZID)

7. Enrichment Analysis_part7


# Perform GO enrichment analysis
ego <- enrichGO(gene = entrez_ids_up$ENTREZID,
                OrgDb = org.Hs.eg.db,
                keyType = "ENTREZID",
                ont = "BP",  # "BP" for Biological Process
                pAdjustMethod = "BH",
                pvalueCutoff = 0.05,
                qvalueCutoff = 0.2)

# Perform KEGG pathway enrichment analysis
ekegg <- enrichKEGG(gene = entrez_ids_up$ENTREZID,
                    organism = "hsa",
                    pvalueCutoff = 0.001)
Reading KEGG annotation online: "https://rest.kegg.jp/link/hsa/pathway"...
Reading KEGG annotation online: "https://rest.kegg.jp/list/pathway/hsa"...
# Perform Reactome pathway enrichment analysis
reactome <- enrichPathway(gene = entrez_ids_up$ENTREZID,
                          organism = "human",
                          pvalueCutoff = 0.05)


# Visualize GO enrichment results
barplot(ego, showCategory = 10)

dotplot(ego, showCategory = 10)


# Visualize KEGG pathway enrichment results
barplot(ekegg, showCategory = 30)

dotplot(ekegg, showCategory = 30)


# Visualize Reactome pathway enrichment results
barplot(reactome, showCategory = 10)

dotplot(reactome, showCategory = 10)


# Pathway visualization with pathview
# Example: Visualize KEGG pathway hsa04010 (replace with your pathway of interest)
pathway_up <- pathview(gene.data = as.numeric(entrez_ids_up$ENTREZID),
         pathway.id = "hsa05200", # Example KEGG pathway ID
         species = "hsa")
Warning: None of the genes or compounds mapped to the pathway!
Argument gene.idtype or cpd.idtype may be wrong.
'select()' returned 1:1 mapping between keys and columns
Info: Working in directory /home/bioinfo/18-Enrichment_Analysis_final_Results
Info: Writing image file hsa05200.pathview.png
pathway_up
$plot.data.gene

$plot.data.cpd
# Assuming the image is saved with the name 'hsa05200.pathview.png'
image_path <- "hsa05200.hsa05200.png"

# Check if the image file exists and display it
if (file.exists(image_path)) {
    display_png(file = image_path)
} else {
    cat("Image file", image_path, "not found.")
}
Image file hsa05200.hsa05200.png not found.

8. Enrichment Analysis_part8

# Load the packages
library(clusterProfiler)
library(ReactomePA)
library(org.Hs.eg.db)
library(pathview)

# Extract the gene symbols and log2FC values for SS_down
gene_list_down <- as.character(SS_down$gene)
log2fc_values_down <- SS_down$log2FC

# Check which gene symbols are not valid
invalid_symbols_down <- setdiff(gene_list_down, valid_symbols)

# Print invalid gene symbols
if (length(invalid_symbols_down) > 0) {
    cat("The following gene symbols are not valid and will be excluded from SS_down:\n")
    print(invalid_symbols_down)
}
The following gene symbols are not valid and will be excluded from SS_down:
[1] "TMEM8A"     "PCED1B.AS1" "SATB1.AS1"  "PRKCQ.AS1"  "AC243960.1" "AC139720.1" "AC119396.1"
# Filter out invalid gene symbols
gene_list_down <- intersect(gene_list_down, valid_symbols)

# Convert gene symbols to Entrez IDs
entrez_ids_down <- bitr(gene_list_down, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)
'select()' returned 1:1 mapping between keys and columns
# Check for successful conversion
if (nrow(entrez_ids_down) == 0) {
    stop("No gene symbols were converted to Entrez IDs for SS_down.")
}

# Merge Entrez IDs with log2FC values
entrez_ids_down <- merge(entrez_ids_down, SS_down, by.x = "SYMBOL", by.y = "gene")

# Create a named vector of log2FC values with Entrez IDs as names
gene_data_down <- setNames(entrez_ids_down$log2FC, entrez_ids_down$ENTREZID)

9. Enrichment Analysis_part9

# # Install necessary packages if they are not already installed
# if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager")
# BiocManager::install(c("pathview", "IRdisplay"))

# Load the required packages
library(pathview)
library(IRdisplay)


# Perform GO enrichment analysis
ego_down <- enrichGO(gene = entrez_ids_down$ENTREZID,
                     OrgDb = org.Hs.eg.db,
                     keyType = "ENTREZID",
                     ont = "BP",  # "BP" for Biological Process
                     pAdjustMethod = "BH",
                     pvalueCutoff = 0.05,
                     qvalueCutoff = 0.2)

ekegg_down <- enrichKEGG(
  gene         = entrez_ids_down$ENTREZID,  # Your list of gene IDs
  organism     = "hsa",                # Human pathways
  pvalueCutoff = 0.05,                 # Adjust if needed
  qvalueCutoff = 0.2
)

# Perform Reactome pathway enrichment analysis
reactome_down <- enrichPathway(gene = entrez_ids_down$ENTREZID,
                               organism = "human",
                               pvalueCutoff = 0.05)

# Visualize GO enrichment results
barplot(ego_down, showCategory = 10)

dotplot(ego_down, showCategory = 10)


# Plot if the object is valid
if (!is.null(ekegg_down) && nrow(as.data.frame(ekegg_down)) > 0) {
  barplot(ekegg_down, showCategory = 30)
} else {
  print("No enriched categories found.")
}


dotplot(ekegg_down, showCategory = 30)


if (!is.null(reactome_down) && nrow(as.data.frame(reactome_down)) > 0) {
  barplot(reactome_down, showCategory = 30)
} else {
  print("No enriched categories found.")
}
[1] "No enriched categories found."
dotplot(reactome_down, showCategory = 10)
Error in ans[ypos] <- rep(yes, length.out = len)[ypos] : 
  replacement has length zero

10. Enrichment Analysis_part10

11. Enrichment Analysis_part11

12. Enrichment Analysis_part12

13. Enrichment Analysis_part13

LS0tCnRpdGxlOiAiRW5yaWNobWVudCBhZnRlciBGQyBTY2FubmVyIEFuYWx5c2lzLXBhcnQyIgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogICMgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgIyB3b3JkX2RvY3VtZW50OiBkZWZhdWx0CiAgIyBodG1sX2RvY3VtZW50OiBkZWZhdWx0CiAgI3JtZGZvcm1hdHM6OnJlYWR0aGVkb3duCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBsb2FkIGxpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGZvcmVhY2gpCmxpYnJhcnkoZG9QYXJhbGxlbCkKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmVhZHIpICAjICdyZWFkcicgcGFja2FnZSBpcyByZWNvbW1lbmRlZCBmb3IgcmVhZGluZyAuY3N2IGFuZCAudHN2IGZpbGVzIGVmZmljaWVudGx5CmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQojIExvYWQgdGhlIHBhY2thZ2VzCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KFJlYWN0b21lUEEpCmxpYnJhcnkob3JnLkhzLmVnLmRiKQpsaWJyYXJ5KHBhdGh2aWV3KQoKYGBgCgoKIyAyLiBFbnJpY2htZW50IEFuYWx5c2lzX3BhcnQxCmBgYHtyIEVucmljaG1lbnQxLCBmaWcuaGVpZ2h0PTE0LCBmaWcud2lkdGg9MTh9CiMgTG9hZCBuZWNlc3NhcnkgbGlicmFyaWVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiMgUmVhZCB0aGUgVFNWIGZpbGUgaW50byBSClNpZ25pZmljYW50X0dlbmVzIDwtIHJlYWRfY3N2KCIvaG9tZS9iaW9pbmZvLzE4LUVucmljaG1lbnRfQW5hbHlzaXNfZmluYWxfUmVzdWx0cy8yLWZpbHRlcmVkX0FsbF9jZWxsX2xpbmVzX2NlbGxzX3ZzX0NENF9Db250cm9sLmNzdiIpCgpTU191cCAgPC0gc3Vic2V0KFNpZ25pZmljYW50X0dlbmVzLAogICAgICAgICAgICAgICAgICAgIFNpZ25pZmljYW50X0dlbmVzJGxvZzJGQyA+IDMKICAgICAgICAgICAgICAgICAgICAgICYgU2lnbmlmaWNhbnRfR2VuZXMkcFZhbHVlQkggPCAgMC4wNSkKU1NfdXBfZ2VuZXMgPC0gU1NfdXAkZ2VuZQoKClNTX2Rvd24gIDwtIHN1YnNldChTaWduaWZpY2FudF9HZW5lcywKICAgICAgICAgICAgICAgICAgICBTaWduaWZpY2FudF9HZW5lcyRsb2cyRkMgPCAtMSAKICAgICAgICAgICAgICAgICAgICAgICYgU2lnbmlmaWNhbnRfR2VuZXMkcFZhbHVlQkggPCAgMC4wNSkKU1NfZG93bl9nZW5lcyA8LSBTU19kb3duJGdlbmUKCgpTU192c19ub3JtX2dvIDwtIGNsdXN0ZXJQcm9maWxlcjo6ZW5yaWNoR08oU1NfdXBfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5Icy5lZy5kYiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJTWU1CT0wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9udCA9ICJCUCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluR1NTaXplID0gNTApCgpwcmludChTU192c19ub3JtX2dvQHJlc3VsdCkKCmVucl9nbyA8LSBjbHVzdGVyUHJvZmlsZXI6OnNpbXBsaWZ5KFNTX3ZzX25vcm1fZ28pCgpwcmludChlbnJfZ29AcmVzdWx0KQoKZW5yaWNocGxvdDo6ZW1hcHBsb3QoZW5yaWNocGxvdDo6cGFpcndpc2VfdGVybXNpbShlbnJfZ28pLAogICAgICAgICAgICAgICAgICAgICBzaG93Q2F0ZWdvcnkgPSA1MCkKCgpTU192c19ub3JtX2dvIDwtIGNsdXN0ZXJQcm9maWxlcjo6ZW5yaWNoR08oU1NfZG93bl9nZW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JnLkhzLmVnLmRiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlUeXBlID0gIlNZTUJPTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb250ID0gIkJQIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5HU1NpemUgPSA1MCkKCnByaW50KFNTX3ZzX25vcm1fZ29AcmVzdWx0KQoKZW5yX2dvIDwtIGNsdXN0ZXJQcm9maWxlcjo6c2ltcGxpZnkoU1NfdnNfbm9ybV9nbykKCnByaW50KGVucl9nb0ByZXN1bHQpCgplbnJpY2hwbG90OjplbWFwcGxvdChlbnJpY2hwbG90OjpwYWlyd2lzZV90ZXJtc2ltKGVucl9nbyksCiAgICAgICAgICAgICAgICAgICAgIHNob3dDYXRlZ29yeSA9IDUwKQoKCmBgYAoKIyAzLiBFbnJpY2htZW50IEFuYWx5c2lzX3BhcnQyCmBgYHtyIEVucmljaG1lbnQyLCBmaWcuaGVpZ2h0PTE0LCBmaWcud2lkdGg9MTh9CmdtdCA8LSBtc2lnZGJyOjptc2lnZGJyKHNwZWNpZXMgPSAiaHVtYW4iLCBjYXRlZ29yeSA9ICJIIikKClNTX3ZzX25vcm1fZW5yaWNoX3VwIDwtIGNsdXN0ZXJQcm9maWxlcjo6ZW5yaWNoZXIoZ2VuZSA9IFNTX3VwX2dlbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmICA9IDAuMDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF2YWx1ZUN1dG9mZiAgPSAwLjA1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBURVJNMkdFTkUgPSBnbXRbLGMoImdzX25hbWUiLCAiZ2VuZV9zeW1ib2wiKV0pCgoKcHJpbnQoU1NfdnNfbm9ybV9lbnJpY2hfdXBAcmVzdWx0W1NTX3ZzX25vcm1fZW5yaWNoX3VwQHJlc3VsdCRwLmFkanVzdCA8IDAuMDUsXSkKCgpTU192c19ub3JtX2VucmljaF9kb3duIDwtIGNsdXN0ZXJQcm9maWxlcjo6ZW5yaWNoZXIoZ2VuZSA9IFNTX2Rvd25fZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgID0gMC4wNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmICA9IDAuMDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRFUk0yR0VORSA9IGdtdFssYygiZ3NfbmFtZSIsICJnZW5lX3N5bWJvbCIpXSkKCgpwcmludChTU192c19ub3JtX2VucmljaF9kb3duQHJlc3VsdFtTU192c19ub3JtX2VucmljaF9kb3duQHJlc3VsdCRwLmFkanVzdCA8IDAuMDUsXSkKCmBgYAojIDQuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDMKYGBge3IgRW5yaWNobWVudDQsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojIFdlIHVzZSB0aGUgZnVuY3Rpb24gYGJhcnBsb3RgIGZyb20gcGFja2FnZSBgZW5yaWNocGxvdGAKZ3JhcGhpY3M6OmJhcnBsb3QoCiAgIyBXZSBwcm92aWRlIHRoZSB2YXJpYWJsZSBwb2ludGluZyB0byBlbnJpY2htZW50IHJlc3VsdHMKICBoZWlnaHQgPSBTU192c19ub3JtX2VucmljaF91cCwKICAjIFdlIGRpc3BsYXkgdGhlIGJlc3QgMTUgcmVzdWx0cwogIHNob3dDYXRlZ29yeT0xNQopCgoKZW5yaWNocGxvdDo6ZG90cGxvdCgKICAjIFdlIHByb3ZpZGUgdGhlIHZhcmlhYmxlIHBvaW50aW5nIHRvIGVucmljaG1lbnQgcmVzdWx0cwogIG9iamVjdCA9IFNTX3ZzX25vcm1fZW5yaWNoX3VwLAogICMgV2UgZGlzcGxheSB0aGUgYmVzdCAxNSByZXN1bHRzCiAgc2hvd0NhdGVnb3J5PTE1CikKIyBXZSB1c2UgdGhlIGZ1bmN0aW9uIGBiYXJwbG90YCBmcm9tIHBhY2thZ2UgYGVucmljaHBsb3RgCmdyYXBoaWNzOjpiYXJwbG90KAogICMgV2UgcHJvdmlkZSB0aGUgdmFyaWFibGUgcG9pbnRpbmcgdG8gZW5yaWNobWVudCByZXN1bHRzCiAgaGVpZ2h0ID0gU1NfdnNfbm9ybV9lbnJpY2hfZG93biwKICAjIFdlIGRpc3BsYXkgdGhlIGJlc3QgMTUgcmVzdWx0cwogIHNob3dDYXRlZ29yeT0xNQopCgoKZW5yaWNocGxvdDo6ZG90cGxvdCgKICAjIFdlIHByb3ZpZGUgdGhlIHZhcmlhYmxlIHBvaW50aW5nIHRvIGVucmljaG1lbnQgcmVzdWx0cwogIG9iamVjdCA9IFNTX3ZzX25vcm1fZW5yaWNoX2Rvd24sCiAgIyBXZSBkaXNwbGF5IHRoZSBiZXN0IDE1IHJlc3VsdHMKICBzaG93Q2F0ZWdvcnk9MTUKKQoKYGBgCgojIDUuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDUKYGBge3IgRW5yaWNobWVudDUsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBXZSB1c2UgdGhlIGZ1bmN0aW9uIGBoZWF0cGxvdGAgZnJvbSBgZW5yaWNocGxvdGAgcGFja2FnZQojIFdlIHVzZSB0aGUgZnVuY3Rpb24gYHVwc2V0cGxvdGAgZnJvbSBgZW5yaWNocGxvdGAgcGFja2FnZQplbnJpY2hwbG90Ojp1cHNldHBsb3QoCiAgIyBXZSBwcm9iaWRlIHRoZSB2YXJpYWJsZSBwb2ludGluZyB0byBHU0VBIHJlc3VsdHMKICB4ID0gU1NfdnNfbm9ybV9lbnJpY2hfdXAsCiAgIyBXZSBzaG93IHRoZSAxMCBiZXN0IHJlc3VsdHMKICBuID0gMTAKKQoKZW5yaWNocGxvdDo6dXBzZXRwbG90KAogICMgV2UgcHJvYmlkZSB0aGUgdmFyaWFibGUgcG9pbnRpbmcgdG8gR1NFQSByZXN1bHRzCiAgeCA9IFNTX3ZzX25vcm1fZW5yaWNoX2Rvd24sCiAgIyBXZSBzaG93IHRoZSAxMCBiZXN0IHJlc3VsdHMKICBuID0gMTAKKQoKYGBgCgojIDYuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDYKYGBge3IgRW5yaWNobWVudDYsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBMb2FkIHRoZSBwYWNrYWdlcwpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKbGlicmFyeShSZWFjdG9tZVBBKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShwYXRodmlldykKCiMgRXh0cmFjdCB0aGUgZ2VuZSBzeW1ib2xzIGFuZCBsb2cyRkMgdmFsdWVzIGZvciBTU191cApnZW5lX2xpc3RfdXAgPC0gYXMuY2hhcmFjdGVyKFNTX3VwJGdlbmUpCmxvZzJmY192YWx1ZXNfdXAgPC0gU1NfdXAkbG9nMkZDCgojIEdldCBhIGxpc3Qgb2YgdmFsaWQgZ2VuZSBzeW1ib2xzIGZyb20gb3JnLkhzLmVnLmRiCnZhbGlkX3N5bWJvbHMgPC0ga2V5cyhvcmcuSHMuZWcuZGIsIGtleXR5cGUgPSAiU1lNQk9MIikKCiMgQ2hlY2sgd2hpY2ggZ2VuZSBzeW1ib2xzIGFyZSBub3QgdmFsaWQKaW52YWxpZF9zeW1ib2xzX3VwIDwtIHNldGRpZmYoZ2VuZV9saXN0X3VwLCB2YWxpZF9zeW1ib2xzKQoKIyBQcmludCBpbnZhbGlkIGdlbmUgc3ltYm9scwppZiAobGVuZ3RoKGludmFsaWRfc3ltYm9sc191cCkgPiAwKSB7CiAgICBjYXQoIlRoZSBmb2xsb3dpbmcgZ2VuZSBzeW1ib2xzIGFyZSBub3QgdmFsaWQgYW5kIHdpbGwgYmUgZXhjbHVkZWQgZnJvbSBTU191cDpcbiIpCiAgICBwcmludChpbnZhbGlkX3N5bWJvbHNfdXApCn0KCiMgRmlsdGVyIG91dCBpbnZhbGlkIGdlbmUgc3ltYm9scwpnZW5lX2xpc3RfdXAgPC0gaW50ZXJzZWN0KGdlbmVfbGlzdF91cCwgdmFsaWRfc3ltYm9scykKCiMgQ29udmVydCBnZW5lIHN5bWJvbHMgdG8gRW50cmV6IElEcwplbnRyZXpfaWRzX3VwIDwtIGJpdHIoZ2VuZV9saXN0X3VwLCBmcm9tVHlwZSA9ICJTWU1CT0wiLCB0b1R5cGUgPSAiRU5UUkVaSUQiLCBPcmdEYiA9IG9yZy5Icy5lZy5kYikKCiMgQ2hlY2sgZm9yIHN1Y2Nlc3NmdWwgY29udmVyc2lvbgppZiAobnJvdyhlbnRyZXpfaWRzX3VwKSA9PSAwKSB7CiAgICBzdG9wKCJObyBnZW5lIHN5bWJvbHMgd2VyZSBjb252ZXJ0ZWQgdG8gRW50cmV6IElEcyBmb3IgU1NfdXAuIikKfQoKIyBNZXJnZSBFbnRyZXogSURzIHdpdGggbG9nMkZDIHZhbHVlcwplbnRyZXpfaWRzX3VwIDwtIG1lcmdlKGVudHJlel9pZHNfdXAsIFNTX3VwLCBieS54ID0gIlNZTUJPTCIsIGJ5LnkgPSAiZ2VuZSIpCgojIENyZWF0ZSBhIG5hbWVkIHZlY3RvciBvZiBsb2cyRkMgdmFsdWVzIHdpdGggRW50cmV6IElEcyBhcyBuYW1lcwpnZW5lX2RhdGFfdXAgPC0gc2V0TmFtZXMoZW50cmV6X2lkc191cCRsb2cyRkMsIGVudHJlel9pZHNfdXAkRU5UUkVaSUQpCgoKYGBgCgojIDcuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDcKYGBge3IgRW5yaWNobWVudDcsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBQZXJmb3JtIEdPIGVucmljaG1lbnQgYW5hbHlzaXMKZWdvIDwtIGVucmljaEdPKGdlbmUgPSBlbnRyZXpfaWRzX3VwJEVOVFJFWklELAogICAgICAgICAgICAgICAgT3JnRGIgPSBvcmcuSHMuZWcuZGIsCiAgICAgICAgICAgICAgICBrZXlUeXBlID0gIkVOVFJFWklEIiwKICAgICAgICAgICAgICAgIG9udCA9ICJCUCIsICAjICJCUCIgZm9yIEJpb2xvZ2ljYWwgUHJvY2VzcwogICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsCiAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmID0gMC4yKQoKIyBQZXJmb3JtIEtFR0cgcGF0aHdheSBlbnJpY2htZW50IGFuYWx5c2lzCmVrZWdnIDwtIGVucmljaEtFR0coZ2VuZSA9IGVudHJlel9pZHNfdXAkRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAiaHNhIiwKICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjAwMSkKCgojIFBlcmZvcm0gUmVhY3RvbWUgcGF0aHdheSBlbnJpY2htZW50IGFuYWx5c2lzCnJlYWN0b21lIDwtIGVucmljaFBhdGh3YXkoZ2VuZSA9IGVudHJlel9pZHNfdXAkRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAiaHVtYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUpCgoKIyBWaXN1YWxpemUgR08gZW5yaWNobWVudCByZXN1bHRzCmJhcnBsb3QoZWdvLCBzaG93Q2F0ZWdvcnkgPSAxMCkKZG90cGxvdChlZ28sIHNob3dDYXRlZ29yeSA9IDEwKQoKIyBWaXN1YWxpemUgS0VHRyBwYXRod2F5IGVucmljaG1lbnQgcmVzdWx0cwpiYXJwbG90KGVrZWdnLCBzaG93Q2F0ZWdvcnkgPSAzMCkKZG90cGxvdChla2VnZywgc2hvd0NhdGVnb3J5ID0gMzApCgojIFZpc3VhbGl6ZSBSZWFjdG9tZSBwYXRod2F5IGVucmljaG1lbnQgcmVzdWx0cwpiYXJwbG90KHJlYWN0b21lLCBzaG93Q2F0ZWdvcnkgPSAxMCkKZG90cGxvdChyZWFjdG9tZSwgc2hvd0NhdGVnb3J5ID0gMTApCgojIFBhdGh3YXkgdmlzdWFsaXphdGlvbiB3aXRoIHBhdGh2aWV3CiMgRXhhbXBsZTogVmlzdWFsaXplIEtFR0cgcGF0aHdheSBoc2EwNDAxMCAocmVwbGFjZSB3aXRoIHlvdXIgcGF0aHdheSBvZiBpbnRlcmVzdCkKcGF0aHdheV91cCA8LSBwYXRodmlldyhnZW5lLmRhdGEgPSBhcy5udW1lcmljKGVudHJlel9pZHNfdXAkRU5UUkVaSUQpLAogICAgICAgICBwYXRod2F5LmlkID0gImhzYTA1MjAwIiwgIyBFeGFtcGxlIEtFR0cgcGF0aHdheSBJRAogICAgICAgICBzcGVjaWVzID0gImhzYSIpCgpwYXRod2F5X3VwCgoKIyBBc3N1bWluZyB0aGUgaW1hZ2UgaXMgc2F2ZWQgd2l0aCB0aGUgbmFtZSAnaHNhMDUyMDAucGF0aHZpZXcucG5nJwppbWFnZV9wYXRoIDwtICJoc2EwNTIwMC5oc2EwNTIwMC5wbmciCgojIENoZWNrIGlmIHRoZSBpbWFnZSBmaWxlIGV4aXN0cyBhbmQgZGlzcGxheSBpdAppZiAoZmlsZS5leGlzdHMoaW1hZ2VfcGF0aCkpIHsKICAgIGRpc3BsYXlfcG5nKGZpbGUgPSBpbWFnZV9wYXRoKQp9IGVsc2UgewogICAgY2F0KCJJbWFnZSBmaWxlIiwgaW1hZ2VfcGF0aCwgIm5vdCBmb3VuZC4iKQp9CgpgYGAKCgoKIyA4LiBFbnJpY2htZW50IEFuYWx5c2lzX3BhcnQ4CmBgYHtyIEVucmljaG1lbnQ4LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KIyBMb2FkIHRoZSBwYWNrYWdlcwpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKbGlicmFyeShSZWFjdG9tZVBBKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShwYXRodmlldykKCiMgRXh0cmFjdCB0aGUgZ2VuZSBzeW1ib2xzIGFuZCBsb2cyRkMgdmFsdWVzIGZvciBTU19kb3duCmdlbmVfbGlzdF9kb3duIDwtIGFzLmNoYXJhY3RlcihTU19kb3duJGdlbmUpCmxvZzJmY192YWx1ZXNfZG93biA8LSBTU19kb3duJGxvZzJGQwoKIyBDaGVjayB3aGljaCBnZW5lIHN5bWJvbHMgYXJlIG5vdCB2YWxpZAppbnZhbGlkX3N5bWJvbHNfZG93biA8LSBzZXRkaWZmKGdlbmVfbGlzdF9kb3duLCB2YWxpZF9zeW1ib2xzKQoKIyBQcmludCBpbnZhbGlkIGdlbmUgc3ltYm9scwppZiAobGVuZ3RoKGludmFsaWRfc3ltYm9sc19kb3duKSA+IDApIHsKICAgIGNhdCgiVGhlIGZvbGxvd2luZyBnZW5lIHN5bWJvbHMgYXJlIG5vdCB2YWxpZCBhbmQgd2lsbCBiZSBleGNsdWRlZCBmcm9tIFNTX2Rvd246XG4iKQogICAgcHJpbnQoaW52YWxpZF9zeW1ib2xzX2Rvd24pCn0KCiMgRmlsdGVyIG91dCBpbnZhbGlkIGdlbmUgc3ltYm9scwpnZW5lX2xpc3RfZG93biA8LSBpbnRlcnNlY3QoZ2VuZV9saXN0X2Rvd24sIHZhbGlkX3N5bWJvbHMpCgojIENvbnZlcnQgZ2VuZSBzeW1ib2xzIHRvIEVudHJleiBJRHMKZW50cmV6X2lkc19kb3duIDwtIGJpdHIoZ2VuZV9saXN0X2Rvd24sIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKQoKIyBDaGVjayBmb3Igc3VjY2Vzc2Z1bCBjb252ZXJzaW9uCmlmIChucm93KGVudHJlel9pZHNfZG93bikgPT0gMCkgewogICAgc3RvcCgiTm8gZ2VuZSBzeW1ib2xzIHdlcmUgY29udmVydGVkIHRvIEVudHJleiBJRHMgZm9yIFNTX2Rvd24uIikKfQoKIyBNZXJnZSBFbnRyZXogSURzIHdpdGggbG9nMkZDIHZhbHVlcwplbnRyZXpfaWRzX2Rvd24gPC0gbWVyZ2UoZW50cmV6X2lkc19kb3duLCBTU19kb3duLCBieS54ID0gIlNZTUJPTCIsIGJ5LnkgPSAiZ2VuZSIpCgojIENyZWF0ZSBhIG5hbWVkIHZlY3RvciBvZiBsb2cyRkMgdmFsdWVzIHdpdGggRW50cmV6IElEcyBhcyBuYW1lcwpnZW5lX2RhdGFfZG93biA8LSBzZXROYW1lcyhlbnRyZXpfaWRzX2Rvd24kbG9nMkZDLCBlbnRyZXpfaWRzX2Rvd24kRU5UUkVaSUQpCgoKYGBgCgojIDkuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDkKYGBge3IgRW5yaWNobWVudDksIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojICMgSW5zdGFsbCBuZWNlc3NhcnkgcGFja2FnZXMgaWYgdGhleSBhcmUgbm90IGFscmVhZHkgaW5zdGFsbGVkCiMgaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJCaW9jTWFuYWdlciIsIHF1aWV0bHkgPSBUUlVFKSkgaW5zdGFsbC5wYWNrYWdlcygiQmlvY01hbmFnZXIiKQojIEJpb2NNYW5hZ2VyOjppbnN0YWxsKGMoInBhdGh2aWV3IiwgIklSZGlzcGxheSIpKQoKIyBMb2FkIHRoZSByZXF1aXJlZCBwYWNrYWdlcwpsaWJyYXJ5KHBhdGh2aWV3KQpsaWJyYXJ5KElSZGlzcGxheSkKCgojIFBlcmZvcm0gR08gZW5yaWNobWVudCBhbmFseXNpcwplZ29fZG93biA8LSBlbnJpY2hHTyhnZW5lID0gZW50cmV6X2lkc19kb3duJEVOVFJFWklELAogICAgICAgICAgICAgICAgICAgICBPcmdEYiA9IG9yZy5Icy5lZy5kYiwKICAgICAgICAgICAgICAgICAgICAga2V5VHlwZSA9ICJFTlRSRVpJRCIsCiAgICAgICAgICAgICAgICAgICAgIG9udCA9ICJCUCIsICAjICJCUCIgZm9yIEJpb2xvZ2ljYWwgUHJvY2VzcwogICAgICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiwKICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmID0gMC4yKQoKZWtlZ2dfZG93biA8LSBlbnJpY2hLRUdHKAogIGdlbmUgICAgICAgICA9IGVudHJlel9pZHNfZG93biRFTlRSRVpJRCwgICMgWW91ciBsaXN0IG9mIGdlbmUgSURzCiAgb3JnYW5pc20gICAgID0gImhzYSIsICAgICAgICAgICAgICAgICMgSHVtYW4gcGF0aHdheXMKICBwdmFsdWVDdXRvZmYgPSAwLjA1LCAgICAgICAgICAgICAgICAgIyBBZGp1c3QgaWYgbmVlZGVkCiAgcXZhbHVlQ3V0b2ZmID0gMC4yCikKCiMgUGVyZm9ybSBSZWFjdG9tZSBwYXRod2F5IGVucmljaG1lbnQgYW5hbHlzaXMKcmVhY3RvbWVfZG93biA8LSBlbnJpY2hQYXRod2F5KGdlbmUgPSBlbnRyZXpfaWRzX2Rvd24kRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJodW1hbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBWaXN1YWxpemUgR08gZW5yaWNobWVudCByZXN1bHRzCmJhcnBsb3QoZWdvX2Rvd24sIHNob3dDYXRlZ29yeSA9IDEwKQpkb3RwbG90KGVnb19kb3duLCBzaG93Q2F0ZWdvcnkgPSAxMCkKCiMgUGxvdCBpZiB0aGUgb2JqZWN0IGlzIHZhbGlkCmlmICghaXMubnVsbChla2VnZ19kb3duKSAmJiBucm93KGFzLmRhdGEuZnJhbWUoZWtlZ2dfZG93bikpID4gMCkgewogIGJhcnBsb3QoZWtlZ2dfZG93biwgc2hvd0NhdGVnb3J5ID0gMzApCn0gZWxzZSB7CiAgcHJpbnQoIk5vIGVucmljaGVkIGNhdGVnb3JpZXMgZm91bmQuIikKfQoKZG90cGxvdChla2VnZ19kb3duLCBzaG93Q2F0ZWdvcnkgPSAzMCkKCmlmICghaXMubnVsbChyZWFjdG9tZV9kb3duKSAmJiBucm93KGFzLmRhdGEuZnJhbWUocmVhY3RvbWVfZG93bikpID4gMCkgewogIGJhcnBsb3QocmVhY3RvbWVfZG93biwgc2hvd0NhdGVnb3J5ID0gMzApCn0gZWxzZSB7CiAgcHJpbnQoIk5vIGVucmljaGVkIGNhdGVnb3JpZXMgZm91bmQuIikKfQoKZG90cGxvdChyZWFjdG9tZV9kb3duLCBzaG93Q2F0ZWdvcnkgPSAxMCkKCgoKIyBQYXRod2F5IHZpc3VhbGl6YXRpb24gd2l0aCBwYXRodmlldyBmb3IgZG93bnJlZ3VsYXRlZCBnZW5lcwpwYXRod2F5X2Rvd24gPC0gcGF0aHZpZXcoZ2VuZS5kYXRhID0gZ2VuZV9kYXRhX2Rvd24sCiAgICAgICAgIHBhdGh3YXkuaWQgPSAiaHNhMDUyMDAiLCAjIEV4YW1wbGUgS0VHRyBwYXRod2F5IElECiAgICAgICAgIHNwZWNpZXMgPSAiaHNhIiwKICAgICAgICAga2VnZy5uYXRpdmUgPSBUUlVFKSAjIFVzZSBLRUdHJ3MgbmF0aXZlIHBhdGh3YXkgZGlhZ3JhbQoKcGF0aHdheV9kb3duCgpgYGAKCiMgMTAuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDEwCmBgYHtyIEVucmljaG1lbnQxMCwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CgpsaWJyYXJ5KGlERUEpCgpgYGAKCgojIDExLiBFbnJpY2htZW50IEFuYWx5c2lzX3BhcnQxMQpgYGB7ciBFbnJpY2htZW50MTEsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKYGBgCgoKIyAxMi4gRW5yaWNobWVudCBBbmFseXNpc19wYXJ0MTIKYGBge3IgRW5yaWNobWVudDEyLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCmBgYAoKCiMgMTMuIEVucmljaG1lbnQgQW5hbHlzaXNfcGFydDEzCmBgYHtyIEVucmljaG1lbnQxMywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CgpgYGA=