1. load libraries
3. Create the EnhancedVolcano plot
library(dplyr)
library(EnhancedVolcano)
# Assuming you have a data frame named Malignant_CD4Tcells_vs_Normal_CD4Tcells
# Filter genes based on lowest p-values but include all genes
filtered_genes <- Malignant_CD4Tcells_vs_Normal_CD4Tcells %>%
arrange(p_val_adj, desc(abs(avg_log2FC)))
# Create the EnhancedVolcano plot with the filtered data
EnhancedVolcano(
filtered_genes,
lab = ifelse(filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0, filtered_genes$gene, NA),
x = "avg_log2FC",
y = "p_val_adj",
title = "Malignant CD4 T cells(cell lines) vs normal CD4 T cells",
pCutoff = 0.05,
FCcutoff = 1.0,
legendPosition = 'right',
labCol = 'black',
labFace = 'bold',
boxedLabels = FALSE, # Set to FALSE to remove boxed labels
pointSize = 3.0,
labSize = 5.0,
col = c('grey70', 'black', 'blue', 'red'), # Customize point colors
selectLab = filtered_genes$gene[filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0] # Only label significant genes
)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

EnhancedVolcano(
filtered_genes,
lab = ifelse(filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0, filtered_genes$gene, NA),
x = "avg_log2FC",
y = "p_val_adj",
title = "Malignant CD4 T cells (cell lines) vs Normal CD4 T cells",
subtitle = "Highlighting differentially expressed genes",
pCutoff = 0.05,
FCcutoff = 1.0,
legendPosition = 'right',
colAlpha = 0.8, # Slight transparency for non-significant points
col = c('grey70', 'black', 'blue', 'red'), # Custom color scheme
gridlines.major = TRUE,
gridlines.minor = FALSE,
selectLab = filtered_genes$gene[filtered_genes$p_val_adj <= 0.05 & abs(filtered_genes$avg_log2FC) >= 1.0]
)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

7. Save Hallmark and kegg to CSV
# # Assuming you have the results stored in fgsea_result_hallmark and fgsea_result_kegg
#
# # Flatten the list columns into character strings for Hallmark results
# fgsea_result_hallmark_flattened <- fgsea_result %>%
# mutate(across(where(is.list), ~ sapply(., toString)))
#
# # Write the flattened Hallmark results to a CSV file
# write.csv(fgsea_result_hallmark_flattened, "fgsea_results_hallmark.csv", row.names = FALSE)
#
# # Flatten the list columns into character strings for KEGG results
# fgsea_result_kegg_flattened <- fgsea_result_kegg %>%
# mutate(across(where(is.list), ~ sapply(., toString)))
#
# # Write the flattened KEGG results to a CSV file
# write.csv(fgsea_result_kegg_flattened, "fgsea_results_kegg.csv", row.names = FALSE)
ggplot(data.frame(gene_symbol = names(gene_list)[1:50], ranks = gene_list[1:50]), aes(gene_symbol, ranks)) +
geom_point() +
theme_classic() +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

8. Hallmark genes founf in multiple pathways
# Load necessary libraries
library(dplyr)
library(tidyr)
library(ggplot2)
# Assuming 'fgsea_results' is the output of your fgsea analysis
# Step 1: Extract the leading edge genes for each significant pathway
# 'leadingEdge' contains the gene names that contribute to the enrichment of the pathway
significant_gene_sets <- fgsea_result %>%
filter(padj < 0.05) %>%
select(pathway, leadingEdge)
# Step 2: Unnest the leadingEdge column (convert list to rows)
significant_gene_sets <- significant_gene_sets %>%
unnest(cols = leadingEdge)
# Step 3: Count how many times each gene appears across pathways
gene_count <- significant_gene_sets %>%
group_by(leadingEdge) %>%
summarise(count = n()) %>%
arrange(desc(count)) # Arrange genes by the number of pathways they appear in
# Step 4: Visualize the top regulator genes (genes that appear in multiple pathways)
top_regulator_genes <- gene_count %>%
filter(count > 1) # Genes involved in more than one pathway
# Plot top regulator genes involved in multiple pathways
ggplot(top_regulator_genes, aes(x = reorder(leadingEdge, -count), y = count)) +
geom_bar(stat = "identity", fill = "salmon") +
coord_flip() +
labs(title = "Top Regulator Genes Involved in Multiple Pathways",
x = "Gene",
y = "Number of Pathways") +
theme_minimal()

# Step 5: Output the gene counts to a CSV file for further inspection
write.csv(gene_count, "gene_count_in_multiple_pathways.csv")
8. Hallmark genes founf in multiple pathways
# Load necessary libraries
library(dplyr)
library(tidyr)
library(ggplot2)
# Assuming 'fgsea_results' is the output of your fgsea analysis
# Step 1: Extract the leading edge genes for each significant pathway
# 'leadingEdge' contains the gene names that contribute to the enrichment of the pathway
significant_gene_sets <- fgsea_result_kegg %>%
filter(padj < 0.05) %>%
select(pathway, leadingEdge)
# Step 2: Unnest the leadingEdge column (convert list to rows)
significant_gene_sets <- significant_gene_sets %>%
unnest(cols = leadingEdge)
# Step 3: Count how many times each gene appears across pathways
gene_count <- significant_gene_sets %>%
group_by(leadingEdge) %>%
summarise(count = n()) %>%
arrange(desc(count)) # Arrange genes by the number of pathways they appear in
# Step 4: Visualize the top regulator genes (genes that appear in multiple pathways)
top_regulator_genes <- gene_count %>%
filter(count > 1) # Genes involved in more than one pathway
# Plot top regulator genes involved in multiple pathways
ggplot(top_regulator_genes, aes(x = reorder(leadingEdge, -count), y = count)) +
geom_bar(stat = "identity", fill = "salmon") +
coord_flip() +
labs(title = "Top Regulator Genes Involved in Multiple Pathways",
x = "Gene",
y = "Number of Pathways") +
theme_minimal()

# Step 5: Output the gene counts to a CSV file for further inspection
write.csv(gene_count, "gene_count_in_multiple_pathways.csv")
LS0tCnRpdGxlOiAiRkdTRUEtIG9mIE1hbGlnbmFudCBDRDRUY2VsbHMgdnMgQ29udHJvbChOb3JtYWwgQ0Q0IFRjZWxscykiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgI3JtZGZvcm1hdHM6OnJlYWR0aGVkb3duCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBsb2FkIGxpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoU2V1cmF0T2JqZWN0KQpsaWJyYXJ5KFNldXJhdERhdGEpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGhhcm1vbnkpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KHJldGljdWxhdGUpCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShSdHNuZSkKbGlicmFyeShoYXJtb255KQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCn0pCiAgCmBgYAoKIyAyLiBQZXJmb3JtIERFIGFuYWx5c2lzIHVzaW5nIE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyBnZW5lcwpgYGB7ciBkYXRhMSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CgpNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgPC0gcmVhZC5jc3YoIi4uLzEtTUFTVF93aXRoX1NDVF9iYXRjaF9wYXRpZW50X2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIGhlYWRlciA9IFQpCmBgYAoKIyAzLiBDcmVhdGUgdGhlIEVuaGFuY2VkVm9sY2FubyBwbG90CmBgYHtyIGVuaGFuY2VkViwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTE2fQoKbGlicmFyeShkcGx5cikKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCgojIEFzc3VtaW5nIHlvdSBoYXZlIGEgZGF0YSBmcmFtZSBuYW1lZCBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMKIyBGaWx0ZXIgZ2VuZXMgYmFzZWQgb24gbG93ZXN0IHAtdmFsdWVzIGJ1dCBpbmNsdWRlIGFsbCBnZW5lcwpmaWx0ZXJlZF9nZW5lcyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgJT4lCiAgYXJyYW5nZShwX3ZhbF9hZGosIGRlc2MoYWJzKGF2Z19sb2cyRkMpKSkKCiMgQ3JlYXRlIHRoZSBFbmhhbmNlZFZvbGNhbm8gcGxvdCB3aXRoIHRoZSBmaWx0ZXJlZCBkYXRhCkVuaGFuY2VkVm9sY2FubygKICBmaWx0ZXJlZF9nZW5lcywgCiAgbGFiID0gaWZlbHNlKGZpbHRlcmVkX2dlbmVzJHBfdmFsX2FkaiA8PSAwLjA1ICYgYWJzKGZpbHRlcmVkX2dlbmVzJGF2Z19sb2cyRkMpID49IDEuMCwgZmlsdGVyZWRfZ2VuZXMkZ2VuZSwgTkEpLAogIHggPSAiYXZnX2xvZzJGQyIsIAogIHkgPSAicF92YWxfYWRqIiwKICB0aXRsZSA9ICJNYWxpZ25hbnQgQ0Q0IFQgY2VsbHMoY2VsbCBsaW5lcykgdnMgbm9ybWFsIENENCBUIGNlbGxzIiwKICBwQ3V0b2ZmID0gMC4wNSwKICBGQ2N1dG9mZiA9IDEuMCwKICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsIAogIGxhYkNvbCA9ICdibGFjaycsCiAgbGFiRmFjZSA9ICdib2xkJywKICBib3hlZExhYmVscyA9IEZBTFNFLCAgIyBTZXQgdG8gRkFMU0UgdG8gcmVtb3ZlIGJveGVkIGxhYmVscwogIHBvaW50U2l6ZSA9IDMuMCwKICBsYWJTaXplID0gNS4wLAogIGNvbCA9IGMoJ2dyZXk3MCcsICdibGFjaycsICdibHVlJywgJ3JlZCcpLCAgIyBDdXN0b21pemUgcG9pbnQgY29sb3JzCiAgc2VsZWN0TGFiID0gZmlsdGVyZWRfZ2VuZXMkZ2VuZVtmaWx0ZXJlZF9nZW5lcyRwX3ZhbF9hZGogPD0gMC4wNSAmIGFicyhmaWx0ZXJlZF9nZW5lcyRhdmdfbG9nMkZDKSA+PSAxLjBdICAjIE9ubHkgbGFiZWwgc2lnbmlmaWNhbnQgZ2VuZXMKKQoKCgpFbmhhbmNlZFZvbGNhbm8oCiAgZmlsdGVyZWRfZ2VuZXMsIAogIGxhYiA9IGlmZWxzZShmaWx0ZXJlZF9nZW5lcyRwX3ZhbF9hZGogPD0gMC4wNSAmIGFicyhmaWx0ZXJlZF9nZW5lcyRhdmdfbG9nMkZDKSA+PSAxLjAsIGZpbHRlcmVkX2dlbmVzJGdlbmUsIE5BKSwKICB4ID0gImF2Z19sb2cyRkMiLCAKICB5ID0gInBfdmFsX2FkaiIsCiAgdGl0bGUgPSAiTWFsaWduYW50IENENCBUIGNlbGxzIChjZWxsIGxpbmVzKSB2cyBOb3JtYWwgQ0Q0IFQgY2VsbHMiLAogIHN1YnRpdGxlID0gIkhpZ2hsaWdodGluZyBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMiLAogIHBDdXRvZmYgPSAwLjA1LAogIEZDY3V0b2ZmID0gMS4wLAogIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICBjb2xBbHBoYSA9IDAuOCwgICMgU2xpZ2h0IHRyYW5zcGFyZW5jeSBmb3Igbm9uLXNpZ25pZmljYW50IHBvaW50cwogIGNvbCA9IGMoJ2dyZXk3MCcsICdibGFjaycsICdibHVlJywgJ3JlZCcpLCAgIyBDdXN0b20gY29sb3Igc2NoZW1lCiAgZ3JpZGxpbmVzLm1ham9yID0gVFJVRSwKICBncmlkbGluZXMubWlub3IgPSBGQUxTRSwKICBzZWxlY3RMYWIgPSBmaWx0ZXJlZF9nZW5lcyRnZW5lW2ZpbHRlcmVkX2dlbmVzJHBfdmFsX2FkaiA8PSAwLjA1ICYgYWJzKGZpbHRlcmVkX2dlbmVzJGF2Z19sb2cyRkMpID49IDEuMF0KKSAKCgpgYGAKCiMgNC4gIFBlcmZvcm0gRmFzdCBHU0VBIHVzaW5nIEhhbGxtYXJrIEdlbmUgU2V0cwpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KGZnc2VhKQpsaWJyYXJ5KG1zaWdkYnIpCmxpYnJhcnkoZHBseXIpCgojIE9idGFpbiBIYWxsbWFyayBnZW5lIHNldHMgZnJvbSBtc2lnZGJyCmhhbGxtYXJrX2dlbmVzIDwtIG1zaWdkYnIoc3BlY2llcyA9ICJIb21vIHNhcGllbnMiLCBjYXRlZ29yeSA9ICJIIikKCiMgQ29udmVydCB0aGUgZ2VuZSBzZXRzIHRvIGEgbGlzdCBmb3JtYXQgZm9yIGZnc2VhCmhhbGxtYXJrX2xpc3QgPC0gaGFsbG1hcmtfZ2VuZXMgJT4lCiAgc3BsaXQoeCA9IC4kZ2VuZV9zeW1ib2wsIGYgPSAuJGdzX25hbWUpCgojIEFzc3VtaW5nIHlvdSBoYXZlIGEgZGF0YSBmcmFtZSBuYW1lZCBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMKIyBDcmVhdGUgYSByYW5rZWQgbGlzdCB3aXRoIFNJR05FRCBtZXRyaWMKTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzIDwtIE1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyAlPiUKICBtdXRhdGUocmFua19tZXRyaWMgPSBhdmdfbG9nMkZDICogLWxvZzEwKHBfdmFsX2FkaikpCgoKIyBFbnN1cmUgbm8gTkEgdmFsdWVzIGluIHJhbmtfbWV0cmljCk1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgJT4lCiAgZmlsdGVyKCFpcy5uYShyYW5rX21ldHJpYykpCgojIENyZWF0ZSBhIG5hbWVkIHZlY3RvciBmb3IgcmFua2luZwpnZW5lX2xpc3QgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHJhbmtfbWV0cmljCm5hbWVzKGdlbmVfbGlzdCkgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGdlbmUKCiMgUmVtb3ZlIGluZmluaXRlIHZhbHVlcyBhbmQgc29ydCBpbiBkZWNyZWFzaW5nIG9yZGVyCmdlbmVfbGlzdCA8LSBnZW5lX2xpc3RbaXMuZmluaXRlKGdlbmVfbGlzdCldCmdlbmVfbGlzdCA8LSBzb3J0KGdlbmVfbGlzdCwgZGVjcmVhc2luZyA9IFRSVUUpCgojIFBlcmZvcm0gZmFzdCBHU0VBIHVzaW5nIGZnc2VhTXVsdGlsZXZlbApmZ3NlYV9yZXN1bHQgPC0gZmdzZWEocGF0aHdheXMgPSBoYWxsbWFya19saXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IGdlbmVfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcHMgPSAwLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluU2l6ZSA9IDE1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFNpemUgPSA1MDApICAjIE5vIG5lZWQgZm9yIG5wZXJtCgojIFZpZXcgdGhlIGZnc2VhIHJlc3VsdHMKaGVhZChmZ3NlYV9yZXN1bHRbb3JkZXIocHZhbCksIF0pCgoKYGBgCgoKCiMgNC4gIFBlcmZvcm0gVmlzdWFsaXphdGlvbiBvZiBmZ3NlcSB1c2luZyBIYWxsbWFyayBHZW5lIFNldHMKYGBge3IgLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KGZnc2VhKQpsaWJyYXJ5KGdncGxvdDIpCgojIFBsb3QgdGhlIHRvcCBwYXRod2F5CnRvcF9wYXRod2F5IDwtIGZnc2VhX3Jlc3VsdFtvcmRlcihmZ3NlYV9yZXN1bHQkcGFkaiksIF1bMSwgXQpwbG90RW5yaWNobWVudChoYWxsbWFya19saXN0W1t0b3BfcGF0aHdheSRwYXRod2F5XV0sIGdlbmVfbGlzdCkgKwogIGxhYnModGl0bGUgPSB0b3BfcGF0aHdheSRwYXRod2F5KQoKdG9wUGF0aHdheXNVcCA8LSBmZ3NlYV9yZXN1bHRbRVMgPiAwXVtoZWFkKG9yZGVyKHBhZGopLCBuPTEwKSwgcGF0aHdheV0KdG9wUGF0aHdheXNEb3duIDwtIGZnc2VhX3Jlc3VsdFtFUyA8IDBdW2hlYWQob3JkZXIocGFkaiksIG49MTApLCBwYXRod2F5XQp0b3BQYXRod2F5cyA8LSBjKHRvcFBhdGh3YXlzVXAsIHJldih0b3BQYXRod2F5c0Rvd24pKQpwbG90R3NlYVRhYmxlKGhhbGxtYXJrX2xpc3RbdG9wUGF0aHdheXNdLCBnZW5lX2xpc3QsIGZnc2VhX3Jlc3VsdCwgCiAgICAgICAgICAgICAgZ3NlYVBhcmFtPTAuNSkKCgpgYGAKCiMjIC4gVmlzdWFsaXphdGlvbi1IYWxsbWFyawpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpmZ3NlYVJlc1RpZHkgPC0gZmdzZWFfcmVzdWx0ICU+JQogIGFzX3RpYmJsZSgpICU+JQogIGFycmFuZ2UoZGVzYyhORVMpKQoKIyBTaG93IGluIGEgbmljZSB0YWJsZSwgZXhjbHVkaW5nIGFueSBjb2x1bW5zIHRoYXQgZG8gbm90IGV4aXN0CmZnc2VhUmVzVGlkeSAlPiUgCiAgZHBseXI6OnNlbGVjdCgtbGVhZGluZ0VkZ2UsIC1FUykgJT4lIAogIGFycmFuZ2UocGFkaikgJT4lIAogIERUOjpkYXRhdGFibGUoKQoKZ2dwbG90KGZnc2VhUmVzVGlkeSwgYWVzKHJlb3JkZXIocGF0aHdheSwgTkVTKSwgTkVTKSkgKwogIGdlb21fY29sKGFlcyhmaWxsPXBhZGo8MC4wNSkpICsKICBjb29yZF9mbGlwKCkgKwogIGxhYnMoeD0iUGF0aHdheSIsIHk9Ik5vcm1hbGl6ZWQgRW5yaWNobWVudCBTY29yZSIsCiAgICAgICB0aXRsZT0iSGFsbG1hcmsgcGF0aHdheXMgTkVTIGZyb20gZmdzZWEiKSArIAogIHRoZW1lX21pbmltYWwoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlRSVUUiID0gInJlZCIsICJGQUxTRSIgPSAiZ3JleSIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSAgIyBBZGp1c3QgYXhpcyB0ZXh0IHNpemUgZm9yIHJlYWRhYmlsaXR5CgoKCmBgYAoKIyA1LiBPYnRhaW4gS0VHRyBHZW5lIFNldHMgYW5kIFBlcmZvcm0gZmdzZWEgVXNpbmcgS0VHRyBQYXRod2F5cwpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQpsaWJyYXJ5KGZnc2VhKQpsaWJyYXJ5KG1zaWdkYnIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocGhlYXRtYXApCgojIE9idGFpbiBLRUdHIGdlbmUgc2V0cyBmcm9tIG1zaWdkYnIKa2VnZ19nZW5lcyA8LSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIiwgY2F0ZWdvcnkgPSAiQzIiLCBzdWJjYXRlZ29yeSA9ICJDUDpLRUdHIikKCiMgQ29udmVydCB0aGUgZ2VuZSBzZXRzIHRvIGEgbGlzdCBmb3JtYXQgZm9yIGZnc2VhCmtlZ2dfbGlzdCA8LSBrZWdnX2dlbmVzICU+JQogIHNwbGl0KHggPSAuJGdlbmVfc3ltYm9sLCBmID0gLiRnc19uYW1lKQoKIyBBc3N1bWluZyB5b3UgaGF2ZSBhIGRhdGEgZnJhbWUgbmFtZWQgTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzCiMgQ3JlYXRlIGEgcmFua2VkIGxpc3QgYmFzZWQgb24gYXZnX2xvZzJGQyBhbmQgcF92YWxfYWRqCk1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgJT4lCiAgbXV0YXRlKHJhbmtfbWV0cmljID0gYXZnX2xvZzJGQyAqIC1sb2cxMChwX3ZhbF9hZGopKQoKIyBFbnN1cmUgbm8gTkEgdmFsdWVzIGluIHJhbmtfbWV0cmljCk1hbGlnbmFudF9DRDRUY2VsbHNfdnNfTm9ybWFsX0NENFRjZWxscyA8LSBNYWxpZ25hbnRfQ0Q0VGNlbGxzX3ZzX05vcm1hbF9DRDRUY2VsbHMgJT4lCiAgZmlsdGVyKCFpcy5uYShyYW5rX21ldHJpYykpCgojIENyZWF0ZSBhIG5hbWVkIHZlY3RvciBmb3IgcmFua2luZwpnZW5lX2xpc3QgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJHJhbmtfbWV0cmljCm5hbWVzKGdlbmVfbGlzdCkgPC0gTWFsaWduYW50X0NENFRjZWxsc192c19Ob3JtYWxfQ0Q0VGNlbGxzJGdlbmUKCiMgU29ydCB0aGUgbmFtZWQgdmVjdG9yIGluIGRlY3JlYXNpbmcgb3JkZXIKZ2VuZV9saXN0IDwtIHNvcnQoZ2VuZV9saXN0LCBkZWNyZWFzaW5nID0gVFJVRSkKCmdlbmVfbGlzdCA8LSBnZW5lX2xpc3RbaXMuZmluaXRlKGdlbmVfbGlzdCldCgojIFBlcmZvcm0gZmFzdCBHU0VBIHVzaW5nIEtFR0cgcGF0aHdheXMKZmdzZWFfcmVzdWx0X2tlZ2cgPC0gZmdzZWEocGF0aHdheXMgPSBrZWdnX2xpc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IGdlbmVfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBzPTAuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhTaXplID0gNTAwKSAgCgoKIyBWaWV3IHRoZSBmZ3NlYSByZXN1bHRzCmhlYWQoZmdzZWFfcmVzdWx0X2tlZ2dbb3JkZXIocHZhbCksIF0pCgoKYGBgCgojIDYuICBQZXJmb3JtIFZpc3VhbGl6YXRpb24gb2YgZmdzZXEgdXNpbmcgS0VHRyBHZW5lIFNldHMKYGBge3IgLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KGZnc2VhKQpsaWJyYXJ5KGdncGxvdDIpCgojIFBsb3QgdGhlIHRvcCBwYXRod2F5CnRvcF9wYXRod2F5IDwtIGZnc2VhX3Jlc3VsdF9rZWdnW29yZGVyKGZnc2VhX3Jlc3VsdF9rZWdnJHBhZGopLCBdWzEsIF0KcGxvdEVucmljaG1lbnQoa2VnZ19saXN0W1t0b3BfcGF0aHdheSRwYXRod2F5XV0sIGdlbmVfbGlzdCkgKwogIGxhYnModGl0bGUgPSB0b3BfcGF0aHdheSRwYXRod2F5KQoKdG9wUGF0aHdheXNVcCA8LSBmZ3NlYV9yZXN1bHRfa2VnZ1tFUyA+IDBdW2hlYWQob3JkZXIocGFkaiksIG49MTApLCBwYXRod2F5XQp0b3BQYXRod2F5c0Rvd24gPC0gZmdzZWFfcmVzdWx0X2tlZ2dbRVMgPCAwXVtoZWFkKG9yZGVyKHBhZGopLCBuPTEwKSwgcGF0aHdheV0KdG9wUGF0aHdheXMgPC0gYyh0b3BQYXRod2F5c1VwLCByZXYodG9wUGF0aHdheXNEb3duKSkKcGxvdEdzZWFUYWJsZShrZWdnX2xpc3RbdG9wUGF0aHdheXNdLCBnZW5lX2xpc3QsIGZnc2VhX3Jlc3VsdF9rZWdnLCAKICAgICAgICAgICAgICBnc2VhUGFyYW09MC41KQoKCmBgYAoKIyMgLiBWaXN1YWxpemF0aW9uLUtlZ2cxCmBgYHtyICwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CmZnc2VhUmVzVGlkeSA8LSBmZ3NlYV9yZXN1bHRfa2VnZyAlPiUKICBhc190aWJibGUoKSAlPiUKICBhcnJhbmdlKGRlc2MoTkVTKSkKCiMgU2hvdyBpbiBhIG5pY2UgdGFibGUsIGV4Y2x1ZGluZyBhbnkgY29sdW1ucyB0aGF0IGRvIG5vdCBleGlzdApmZ3NlYVJlc1RpZHkgJT4lIAogIGRwbHlyOjpzZWxlY3QoLWxlYWRpbmdFZGdlLCAtRVMpICU+JSAKICBhcnJhbmdlKHBhZGopICU+JSAKICBEVDo6ZGF0YXRhYmxlKCkKCmdncGxvdChmZ3NlYVJlc1RpZHksIGFlcyhyZW9yZGVyKHBhdGh3YXksIE5FUyksIE5FUykpICsKICBnZW9tX2NvbChhZXMoZmlsbD1wYWRqPDAuMDUpKSArCiAgY29vcmRfZmxpcCgpICsKICBsYWJzKHg9IlBhdGh3YXkiLCB5PSJOb3JtYWxpemVkIEVucmljaG1lbnQgU2NvcmUiLAogICAgICAgdGl0bGU9IkhhbGxtYXJrIHBhdGh3YXlzIE5FUyBmcm9tIGZnc2VhIikgKyAKICB0aGVtZV9taW5pbWFsKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJUUlVFIiA9ICJyZWQiLCAiRkFMU0UiID0gImdyZXkiKSkgKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgICMgQWRqdXN0IGF4aXMgdGV4dCBzaXplIGZvciByZWFkYWJpbGl0eQoKCgpgYGAKCiMjIC4gVmlzdWFsaXphdGlvbi1LZWdnMgpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojIEFycmFuZ2UgYnkgTkVTIGFuZCBzZWxlY3QgdG9wIDIwIHVwIGFuZCBkb3duIHBhdGh3YXlzCnRvcFVwIDwtIGZnc2VhUmVzVGlkeSAlPiUKICBkcGx5cjo6ZmlsdGVyKE5FUyA+IDApICU+JQogIGRwbHlyOjphcnJhbmdlKGRlc2MoTkVTKSkgJT4lCiAgZHBseXI6OnNsaWNlX2hlYWQobiA9IDIwKQoKdG9wRG93biA8LSBmZ3NlYVJlc1RpZHkgJT4lCiAgZHBseXI6OmZpbHRlcihORVMgPCAwKSAlPiUKICBkcGx5cjo6YXJyYW5nZShORVMpICU+JQogIGRwbHlyOjpzbGljZV9oZWFkKG4gPSAyMCkKCiMgQ29tYmluZSB0aGUgdG9wIHVwIGFuZCBkb3duIHBhdGh3YXlzCnRvcFBhdGh3YXlzIDwtIGRwbHlyOjpiaW5kX3Jvd3ModG9wVXAsIHRvcERvd24pCgoKZ2dwbG90KHRvcFBhdGh3YXlzLCBhZXMocmVvcmRlcihwYXRod2F5LCBORVMpLCBORVMpKSArCiAgZ2VvbV9jb2woYWVzKGZpbGwgPSBwYWRqIDwgMC4wNSkpICsKICBjb29yZF9mbGlwKCkgKwogIGxhYnMoeCA9ICJQYXRod2F5IiwgeSA9ICJOb3JtYWxpemVkIEVucmljaG1lbnQgU2NvcmUiLAogICAgICAgdGl0bGUgPSAiVG9wIDIwIFVwIGFuZCBEb3duIEtFR0cgUGF0aHdheXMgTkVTIGZyb20gR1NFQSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlRSVUUiID0gInJlZCIsICJGQUxTRSIgPSAiZ3JleSIpKQoKCgoKYGBgCgojIDcuIFNhdmUgSGFsbG1hcmsgYW5kIGtlZ2cgdG8gQ1NWCmBgYHtyICwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CgojICMgQXNzdW1pbmcgeW91IGhhdmUgdGhlIHJlc3VsdHMgc3RvcmVkIGluIGZnc2VhX3Jlc3VsdF9oYWxsbWFyayBhbmQgZmdzZWFfcmVzdWx0X2tlZ2cKIyAKIyAjIEZsYXR0ZW4gdGhlIGxpc3QgY29sdW1ucyBpbnRvIGNoYXJhY3RlciBzdHJpbmdzIGZvciBIYWxsbWFyayByZXN1bHRzCiMgZmdzZWFfcmVzdWx0X2hhbGxtYXJrX2ZsYXR0ZW5lZCA8LSBmZ3NlYV9yZXN1bHQgJT4lCiMgICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLmxpc3QpLCB+IHNhcHBseSguLCB0b1N0cmluZykpKQojIAojICMgV3JpdGUgdGhlIGZsYXR0ZW5lZCBIYWxsbWFyayByZXN1bHRzIHRvIGEgQ1NWIGZpbGUKIyB3cml0ZS5jc3YoZmdzZWFfcmVzdWx0X2hhbGxtYXJrX2ZsYXR0ZW5lZCwgImZnc2VhX3Jlc3VsdHNfaGFsbG1hcmsuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCiMgCiMgIyBGbGF0dGVuIHRoZSBsaXN0IGNvbHVtbnMgaW50byBjaGFyYWN0ZXIgc3RyaW5ncyBmb3IgS0VHRyByZXN1bHRzCiMgZmdzZWFfcmVzdWx0X2tlZ2dfZmxhdHRlbmVkIDwtIGZnc2VhX3Jlc3VsdF9rZWdnICU+JQojICAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5saXN0KSwgfiBzYXBwbHkoLiwgdG9TdHJpbmcpKSkKIyAKIyAjIFdyaXRlIHRoZSBmbGF0dGVuZWQgS0VHRyByZXN1bHRzIHRvIGEgQ1NWIGZpbGUKIyB3cml0ZS5jc3YoZmdzZWFfcmVzdWx0X2tlZ2dfZmxhdHRlbmVkLCAiZmdzZWFfcmVzdWx0c19rZWdnLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQoKCmdncGxvdChkYXRhLmZyYW1lKGdlbmVfc3ltYm9sID0gbmFtZXMoZ2VuZV9saXN0KVsxOjUwXSwgcmFua3MgPSBnZW5lX2xpc3RbMTo1MF0pLCBhZXMoZ2VuZV9zeW1ib2wsIHJhbmtzKSkgKyAKCWdlb21fcG9pbnQoKSArCgl0aGVtZV9jbGFzc2ljKCkgKyAKCXRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSkKCmBgYAojIDguICBIYWxsbWFyayBnZW5lcyBmb3VuZiBpbiBtdWx0aXBsZSBwYXRod2F5cwpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQoKIyBBc3N1bWluZyAnZmdzZWFfcmVzdWx0cycgaXMgdGhlIG91dHB1dCBvZiB5b3VyIGZnc2VhIGFuYWx5c2lzCgojIFN0ZXAgMTogRXh0cmFjdCB0aGUgbGVhZGluZyBlZGdlIGdlbmVzIGZvciBlYWNoIHNpZ25pZmljYW50IHBhdGh3YXkKIyAnbGVhZGluZ0VkZ2UnIGNvbnRhaW5zIHRoZSBnZW5lIG5hbWVzIHRoYXQgY29udHJpYnV0ZSB0byB0aGUgZW5yaWNobWVudCBvZiB0aGUgcGF0aHdheQpzaWduaWZpY2FudF9nZW5lX3NldHMgPC0gZmdzZWFfcmVzdWx0ICU+JQogIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lCiAgc2VsZWN0KHBhdGh3YXksIGxlYWRpbmdFZGdlKQoKIyBTdGVwIDI6IFVubmVzdCB0aGUgbGVhZGluZ0VkZ2UgY29sdW1uIChjb252ZXJ0IGxpc3QgdG8gcm93cykKc2lnbmlmaWNhbnRfZ2VuZV9zZXRzIDwtIHNpZ25pZmljYW50X2dlbmVfc2V0cyAlPiUKICB1bm5lc3QoY29scyA9IGxlYWRpbmdFZGdlKQoKIyBTdGVwIDM6IENvdW50IGhvdyBtYW55IHRpbWVzIGVhY2ggZ2VuZSBhcHBlYXJzIGFjcm9zcyBwYXRod2F5cwpnZW5lX2NvdW50IDwtIHNpZ25pZmljYW50X2dlbmVfc2V0cyAlPiUKICBncm91cF9ieShsZWFkaW5nRWRnZSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBhcnJhbmdlKGRlc2MoY291bnQpKSAgIyBBcnJhbmdlIGdlbmVzIGJ5IHRoZSBudW1iZXIgb2YgcGF0aHdheXMgdGhleSBhcHBlYXIgaW4KCiMgU3RlcCA0OiBWaXN1YWxpemUgdGhlIHRvcCByZWd1bGF0b3IgZ2VuZXMgKGdlbmVzIHRoYXQgYXBwZWFyIGluIG11bHRpcGxlIHBhdGh3YXlzKQp0b3BfcmVndWxhdG9yX2dlbmVzIDwtIGdlbmVfY291bnQgJT4lCiAgZmlsdGVyKGNvdW50ID4gMSkgICMgR2VuZXMgaW52b2x2ZWQgaW4gbW9yZSB0aGFuIG9uZSBwYXRod2F5CgojIFBsb3QgdG9wIHJlZ3VsYXRvciBnZW5lcyBpbnZvbHZlZCBpbiBtdWx0aXBsZSBwYXRod2F5cwpnZ3Bsb3QodG9wX3JlZ3VsYXRvcl9nZW5lcywgYWVzKHggPSByZW9yZGVyKGxlYWRpbmdFZGdlLCAtY291bnQpLCB5ID0gY291bnQpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAic2FsbW9uIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgbGFicyh0aXRsZSA9ICJUb3AgUmVndWxhdG9yIEdlbmVzIEludm9sdmVkIGluIE11bHRpcGxlIFBhdGh3YXlzIiwKICAgICAgIHggPSAiR2VuZSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBQYXRod2F5cyIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgU3RlcCA1OiBPdXRwdXQgdGhlIGdlbmUgY291bnRzIHRvIGEgQ1NWIGZpbGUgZm9yIGZ1cnRoZXIgaW5zcGVjdGlvbgp3cml0ZS5jc3YoZ2VuZV9jb3VudCwgImdlbmVfY291bnRfaW5fbXVsdGlwbGVfcGF0aHdheXMuY3N2IikKCgpgYGAKCgojIDguICBIYWxsbWFyayBnZW5lcyBmb3VuZiBpbiBtdWx0aXBsZSBwYXRod2F5cwpgYGB7ciAsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQoKIyBBc3N1bWluZyAnZmdzZWFfcmVzdWx0cycgaXMgdGhlIG91dHB1dCBvZiB5b3VyIGZnc2VhIGFuYWx5c2lzCgojIFN0ZXAgMTogRXh0cmFjdCB0aGUgbGVhZGluZyBlZGdlIGdlbmVzIGZvciBlYWNoIHNpZ25pZmljYW50IHBhdGh3YXkKIyAnbGVhZGluZ0VkZ2UnIGNvbnRhaW5zIHRoZSBnZW5lIG5hbWVzIHRoYXQgY29udHJpYnV0ZSB0byB0aGUgZW5yaWNobWVudCBvZiB0aGUgcGF0aHdheQpzaWduaWZpY2FudF9nZW5lX3NldHMgPC0gZmdzZWFfcmVzdWx0X2tlZ2cgJT4lCiAgZmlsdGVyKHBhZGogPCAwLjA1KSAlPiUKICBzZWxlY3QocGF0aHdheSwgbGVhZGluZ0VkZ2UpCgojIFN0ZXAgMjogVW5uZXN0IHRoZSBsZWFkaW5nRWRnZSBjb2x1bW4gKGNvbnZlcnQgbGlzdCB0byByb3dzKQpzaWduaWZpY2FudF9nZW5lX3NldHMgPC0gc2lnbmlmaWNhbnRfZ2VuZV9zZXRzICU+JQogIHVubmVzdChjb2xzID0gbGVhZGluZ0VkZ2UpCgojIFN0ZXAgMzogQ291bnQgaG93IG1hbnkgdGltZXMgZWFjaCBnZW5lIGFwcGVhcnMgYWNyb3NzIHBhdGh3YXlzCmdlbmVfY291bnQgPC0gc2lnbmlmaWNhbnRfZ2VuZV9zZXRzICU+JQogIGdyb3VwX2J5KGxlYWRpbmdFZGdlKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQogIGFycmFuZ2UoZGVzYyhjb3VudCkpICAjIEFycmFuZ2UgZ2VuZXMgYnkgdGhlIG51bWJlciBvZiBwYXRod2F5cyB0aGV5IGFwcGVhciBpbgoKIyBTdGVwIDQ6IFZpc3VhbGl6ZSB0aGUgdG9wIHJlZ3VsYXRvciBnZW5lcyAoZ2VuZXMgdGhhdCBhcHBlYXIgaW4gbXVsdGlwbGUgcGF0aHdheXMpCnRvcF9yZWd1bGF0b3JfZ2VuZXMgPC0gZ2VuZV9jb3VudCAlPiUKICBmaWx0ZXIoY291bnQgPiAxKSAgIyBHZW5lcyBpbnZvbHZlZCBpbiBtb3JlIHRoYW4gb25lIHBhdGh3YXkKCiMgUGxvdCB0b3AgcmVndWxhdG9yIGdlbmVzIGludm9sdmVkIGluIG11bHRpcGxlIHBhdGh3YXlzCmdncGxvdCh0b3BfcmVndWxhdG9yX2dlbmVzLCBhZXMoeCA9IHJlb3JkZXIobGVhZGluZ0VkZ2UsIC1jb3VudCksIHkgPSBjb3VudCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJzYWxtb24iKSArCiAgY29vcmRfZmxpcCgpICsKICBsYWJzKHRpdGxlID0gIlRvcCBSZWd1bGF0b3IgR2VuZXMgSW52b2x2ZWQgaW4gTXVsdGlwbGUgUGF0aHdheXMiLAogICAgICAgeCA9ICJHZW5lIiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIFBhdGh3YXlzIikgKwogIHRoZW1lX21pbmltYWwoKQoKIyBTdGVwIDU6IE91dHB1dCB0aGUgZ2VuZSBjb3VudHMgdG8gYSBDU1YgZmlsZSBmb3IgZnVydGhlciBpbnNwZWN0aW9uCndyaXRlLmNzdihnZW5lX2NvdW50LCAiZ2VuZV9jb3VudF9pbl9tdWx0aXBsZV9wYXRod2F5cy5jc3YiKQoKCmBgYA==