Set Up
Load Libraries and Set Working Directory
Rename samples
# Define mappings for renaming organs and time point samples
organ_mapping <- c(
amyg = "Amygdala",
drg = "DRG",
heart = "Heart",
hypo = "Hypothalamus",
lhip = "Left_Hippocampus",
musc = "Muscle",
rhip = "Right_Hippocampus",
sc = "Spinal_Cord"
)
time_mapping <- c(
"2" = "2hrs",
"24" = "24hrs",
"72" = "72hrs"
)
Read + combine files
# Read all .txt files in the "miRNA results" folder and combine them into a single dataframe
df <- list.files("miRNA results", pattern = "\\.txt$", full.names = TRUE) %>%
set_names(~ tools::file_path_sans_ext(basename(.))) %>%
map_dfr(~ read_tsv(.x, skip = 2, show_col_types = FALSE), .id = "sample") %>%
select(-c(3, 7, 11)) %>%
mutate(
# Extract organ and timepoint information using regex
organ_code = str_extract(sample, "^[a-zA-Z]+"),
time_code = str_extract(sample, "\\d+$"),
# Map to full names
sample = paste0(organ_mapping[organ_code], "_", time_mapping[time_code])
) %>%
select(-organ_code, -time_code) # Remove intermediate columns for cleanliness
# Confirm successful processing
cat("All files have been read and combined successfully.\n")
All files have been read and combined successfully.
Rename columns
# Clean up column names to remove unwanted suffixes and clarify naming
names(df) <- gsub("\\.\\.\\.[0-9]+$", "", names(df)) # Remove trailing numbers from column names
names(df)[c(3, 5, 7)] <- c("Expr_Log_Ratio_miRNA", "confidence", "Expr_Log_Ratio_mRNA") # Rename relevant columns
df$ID <- sub("^rno-", "", df$ID) # Clean up 'rno-' prefix from miRNA IDs
symbol-pathway mapping
# Check for consistency in Symbol-Pathway mapping
inconsistent <- df %>%
group_by(Symbol) %>%
summarize(unique_pathways = n_distinct(Pathway)) %>%
filter(unique_pathways > 1)
# If the resulting dataframe is empty, there are no inconsistencies
if (nrow(inconsistent) == 0) {
cat("All Symbols have consistent Pathway associations.\n")
} else {
cat("Some Symbols have inconsistent Pathway associations:\n")
print(inconsistent)
}
All Symbols have consistent Pathway associations.
Analysis
Descriptives
# Count and summarize frequency of miRNAs
miRNA_freq <- df %>%
group_by(ID) %>%
summarize(Count = n()) %>%
arrange(desc(Count))
# Number of pathways detected per organ
pathway_freq <- df %>%
group_by(sample) %>%
summarize(Count = n()) %>%
arrange(desc(Count))
# Frequency of each confidence level
confidence_freq <- df %>%
group_by(confidence) %>%
summarize(Count = n()) %>%
arrange(desc(Count))
# Frequency of mRNA symbols and their associated pathways
mRNA_freq <- df %>%
group_by(Symbol, Pathway) %>%
summarize(Count = n(), .groups = "drop") %>%
arrange(desc(Count))
# Count unique miRNA-mRNA pairs
miRNA_mRNA_pairs <- df %>%
group_by(Symbol, ID) %>%
summarize(Frequency = n(), .groups = "drop") %>%
arrange(desc(Frequency))
# Render summary statistics
cat("The number of unique miRNA reviewed is:", length(unique(df$ID)), "\n")
The number of unique miRNA reviewed is: 62
cat("The number of unique mRNA reviewed is:", length(unique(df$Symbol)), "\n")
The number of unique mRNA reviewed is: 318
cat("The number of unique miRNA-mRNA pairs is:", nrow(miRNA_mRNA_pairs), "\n")
The number of unique miRNA-mRNA pairs is: 397
# Render interactive tables for visual inspection
datatable(miRNA_freq, caption = "Frequency of Each miRNA", options = list(pageLength = 10))
datatable(pathway_freq, caption = "Number of Detected Pathways per Organ", options = list(pageLength = 10))
datatable(confidence_freq, caption = "Frequency of Each Confidence Level", options = list(pageLength = 10))
datatable(mRNA_freq, caption = "Frequency of Each mRNA and Associated Pathway", options = list(pageLength = 10))
datatable(miRNA_mRNA_pairs, caption = "Frequency of miRNA-mRNA Pairs", options = list(pageLength = 10))
Visuals
Define plot elements
theme2 <- theme(
axis.text.x = element_text(face = "bold", color = "royalblue4", size = 12, angle = 30, hjust = 1), # Adjust label angle
axis.text.y = element_text(face = "bold", color = "royalblue3", size = 12),
axis.title = element_text(size = 14, face = "bold"),
plot.title = element_text(size = 16, face = "bold.italic")
)
plot top 15 miRNA
# Plot the top 15 most frequent miRNA
miRNA_freq %>%
slice_max(Count, n = 15) %>%
ggplot(aes(x = reorder(ID, -Count), y = Count, fill = Count)) +
geom_col() +
geom_text(aes(label = Count), vjust = -0.3, color = "black", size = 4, fontface = "bold") +
scale_fill_gradient(low = "lightblue", high = "royalblue4") +
labs(
title = "Top 15 Most Frequent miRNA",
x = "miRNA",
y = "Frequency"
) +
theme2 +
scale_y_continuous(
breaks = seq(0, max(miRNA_freq$Count), by = 5),
expand = expansion(mult = c(0, 0.1)) # Add space above the tallest bar
) +
theme(legend.position = "none")

# Plot all mRNA (Symbol) with frequency above 3
mRNA_freq %>%
filter(Count > 3) %>%
ggplot(aes(x = reorder(Symbol, -Count), y = Count, fill = Count)) +
geom_col() +
geom_text(aes(label = Count), vjust = -0.3, color = "black", size = 4, fontface = "bold") +
scale_fill_gradient(low = "lightblue", high = "royalblue4") +
labs(
title = "mRNA with Frequency Above 3",
x = "mRNA",
y = "Frequency"
) +
theme2 +
scale_y_continuous(
breaks = seq(0, max(mRNA_freq$Count), by = 2),
expand = expansion(mult = c(0, 0.1))
) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Experimental Network libraries
#subset df to only right hippocamous 24 hours
df24_rh <- df %>%
filter(sample == "Right_Hippocampus_24hrs")
igraph
# Create an edge list from the subset
edges <- data.frame(from = df24_rh$ID, to = df24_rh$Symbol)
# Create the graph object
network <- graph_from_data_frame(edges)
# visualization
plot(
network,
vertex.size = 10,
vertex.label.cex = 0.8,
vertex.label.color = "black",
vertex.frame.color = NA,
vertex.color = ifelse(V(network)$name %in% df24_rh$ID, "skyblue", "salmon"),
edge.arrow.size = 0.4,
edge.color = "gray",
edge.width = 0.8,
main = "miRNA-mRNA Network (Right Hippocampus, 24hrs)"
)

ggraph
# Create an edge list and graph object
edges <- data.frame(from = df24_rh$ID, to = df24_rh$Symbol)
network <- graph_from_data_frame(edges, directed = FALSE) # Convert to undirected graph
# Detect communities for clustering
communities <- cluster_louvain(network)
V(network)$community <- communities$membership # Assign community memberships to nodes
# Identify node types (miRNA or mRNA)
V(network)$type <- ifelse(V(network)$name %in% df24_rh$ID, "miRNA", "mRNA")
# Visualize the network
ggraph(network, layout = "fr") + # Force-directed layout
geom_edge_link(aes(edge_alpha = 0.5), edge_color = "gray") +
geom_node_point(aes(color = factor(community), shape = type), size = 6) +
geom_node_text(aes(label = name), repel = TRUE, size = 3) +
scale_color_brewer(palette = "Set3") +
scale_shape_manual(values = c("miRNA" = 21, "mRNA" = 19)) +
theme_void() +
labs(
title = "miRNA-mRNA Network (Right Hippocampus, 24hrs)",
color = "Community",
shape = "Node Type"
) +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
legend.position = "none"
)

Pathview
library(pathview)
##############################################################################
Pathview is an open source software package distributed under GNU General
Public License version 3 (GPLv3). Details of GPLv3 is available at
http://www.gnu.org/licenses/gpl-3.0.html. Particullary, users are required to
formally cite the original Pathview paper (not just mention it) in publications
or products. For details, do citation("pathview") within R.
The pathview downloads and uses KEGG data. Non-academic uses may require a KEGG
license agreement (details at http://www.kegg.jp/kegg/legal.html).
##############################################################################
# Summarize mRNA frequencies
gene_data <- df24_rh %>%
group_by(Symbol) %>%
summarize(Frequency = n())
# Convert to a named vector
gene_data_vector <- setNames(gene_data$Frequency, gene_data$Symbol)
# Specify the KEGG pathway ID for Inflammatory Mediator Regulation of TRP Channels
pathway_id <- "hsa04750"
# Visualize the pathway
pathview(
gene.data = gene_data_vector,
pathway.id = pathway_id,
species = "hsa",
gene.idtype = "SYMBOL",
limit = list(gene = max(gene_data$Frequency)),
kegg.native = TRUE
)
'select()' returned 1:1 mapping between keys and columns
[1] "Note: 1 of 53 unique input IDs unmapped."
'select()' returned 1:1 mapping between keys and columns
Info: Working in directory /Users/alicewoolard/Library/Mobile Documents/com~apple~CloudDocs
Info: Writing image file hsa04750.pathview.png
LS0tCnRpdGxlOiAiSVBBIG1pUk5BLW1STkEiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIyBTZXQgVXAKCiMjIyMgTG9hZCBMaWJyYXJpZXMgYW5kIFNldCBXb3JraW5nIERpcmVjdG9yeQpgYGB7ciBzZXR1cCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Kcm0obGlzdCA9IGxzKCkpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncmFwaCkKbGlicmFyeShpZ3JhcGgpCmxpYnJhcnkoRFQpCgoKbGlicmFyeShoZXJlKQpzZXR3ZChoZXJlKCkpCmBgYAoKIyMjIyBSZW5hbWUgc2FtcGxlcwpgYGB7cn0KIyBEZWZpbmUgbWFwcGluZ3MgZm9yIHJlbmFtaW5nIG9yZ2FucyBhbmQgdGltZSBwb2ludCBzYW1wbGVzCm9yZ2FuX21hcHBpbmcgPC0gYygKICBhbXlnID0gIkFteWdkYWxhIiwKICBkcmcgPSAiRFJHIiwKICBoZWFydCA9ICJIZWFydCIsCiAgaHlwbyA9ICJIeXBvdGhhbGFtdXMiLAogIGxoaXAgPSAiTGVmdF9IaXBwb2NhbXB1cyIsCiAgbXVzYyA9ICJNdXNjbGUiLAogIHJoaXAgPSAiUmlnaHRfSGlwcG9jYW1wdXMiLAogIHNjID0gIlNwaW5hbF9Db3JkIgopCgp0aW1lX21hcHBpbmcgPC0gYygKICAiMiIgPSAiMmhycyIsCiAgIjI0IiA9ICIyNGhycyIsCiAgIjcyIiA9ICI3MmhycyIKKQpgYGAKCiMjIyMgUmVhZCArIGNvbWJpbmUgZmlsZXMKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgUmVhZCBhbGwgLnR4dCBmaWxlcyBpbiB0aGUgIm1pUk5BIHJlc3VsdHMiIGZvbGRlciBhbmQgY29tYmluZSB0aGVtIGludG8gYSBzaW5nbGUgZGF0YWZyYW1lCmRmIDwtIGxpc3QuZmlsZXMoIm1pUk5BIHJlc3VsdHMiLCBwYXR0ZXJuID0gIlxcLnR4dCQiLCBmdWxsLm5hbWVzID0gVFJVRSkgJT4lCiAgc2V0X25hbWVzKH4gdG9vbHM6OmZpbGVfcGF0aF9zYW5zX2V4dChiYXNlbmFtZSguKSkpICU+JQogIG1hcF9kZnIofiByZWFkX3RzdigueCwgc2tpcCA9IDIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpLCAuaWQgPSAic2FtcGxlIikgJT4lCiAgc2VsZWN0KC1jKDMsIDcsIDExKSkgJT4lCiAgbXV0YXRlKAogICAgIyBFeHRyYWN0IG9yZ2FuIGFuZCB0aW1lcG9pbnQgaW5mb3JtYXRpb24gdXNpbmcgcmVnZXgKICAgIG9yZ2FuX2NvZGUgPSBzdHJfZXh0cmFjdChzYW1wbGUsICJeW2EtekEtWl0rIiksCiAgICB0aW1lX2NvZGUgPSBzdHJfZXh0cmFjdChzYW1wbGUsICJcXGQrJCIpLAogICAgIyBNYXAgdG8gZnVsbCBuYW1lcwogICAgc2FtcGxlID0gcGFzdGUwKG9yZ2FuX21hcHBpbmdbb3JnYW5fY29kZV0sICJfIiwgdGltZV9tYXBwaW5nW3RpbWVfY29kZV0pCiAgKSAlPiUKICBzZWxlY3QoLW9yZ2FuX2NvZGUsIC10aW1lX2NvZGUpICAjIFJlbW92ZSBpbnRlcm1lZGlhdGUgY29sdW1ucyBmb3IgY2xlYW5saW5lc3MKCiMgQ29uZmlybSBzdWNjZXNzZnVsIHByb2Nlc3NpbmcKY2F0KCJBbGwgZmlsZXMgaGF2ZSBiZWVuIHJlYWQgYW5kIGNvbWJpbmVkIHN1Y2Nlc3NmdWxseS5cbiIpCmBgYAoKIyMjIyBSZW5hbWUgY29sdW1ucwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBDbGVhbiB1cCBjb2x1bW4gbmFtZXMgdG8gcmVtb3ZlIHVud2FudGVkIHN1ZmZpeGVzIGFuZCBjbGFyaWZ5IG5hbWluZwpuYW1lcyhkZikgPC0gZ3N1YigiXFwuXFwuXFwuWzAtOV0rJCIsICIiLCBuYW1lcyhkZikpICAjIFJlbW92ZSB0cmFpbGluZyBudW1iZXJzIGZyb20gY29sdW1uIG5hbWVzCm5hbWVzKGRmKVtjKDMsIDUsIDcpXSA8LSBjKCJFeHByX0xvZ19SYXRpb19taVJOQSIsICJjb25maWRlbmNlIiwgIkV4cHJfTG9nX1JhdGlvX21STkEiKSAgIyBSZW5hbWUgcmVsZXZhbnQgY29sdW1ucwpkZiRJRCA8LSBzdWIoIl5ybm8tIiwgIiIsIGRmJElEKSAgIyBDbGVhbiB1cCAncm5vLScgcHJlZml4IGZyb20gbWlSTkEgSURzCmBgYAoKIyMjIyBzeW1ib2wtcGF0aHdheSBtYXBwaW5nCmBgYHtyfQojIENoZWNrIGZvciBjb25zaXN0ZW5jeSBpbiBTeW1ib2wtUGF0aHdheSBtYXBwaW5nCmluY29uc2lzdGVudCA8LSBkZiAlPiUKICBncm91cF9ieShTeW1ib2wpICU+JQogIHN1bW1hcml6ZSh1bmlxdWVfcGF0aHdheXMgPSBuX2Rpc3RpbmN0KFBhdGh3YXkpKSAlPiUKICBmaWx0ZXIodW5pcXVlX3BhdGh3YXlzID4gMSkKCiMgSWYgdGhlIHJlc3VsdGluZyBkYXRhZnJhbWUgaXMgZW1wdHksIHRoZXJlIGFyZSBubyBpbmNvbnNpc3RlbmNpZXMKaWYgKG5yb3coaW5jb25zaXN0ZW50KSA9PSAwKSB7CiAgY2F0KCJBbGwgU3ltYm9scyBoYXZlIGNvbnNpc3RlbnQgUGF0aHdheSBhc3NvY2lhdGlvbnMuXG4iKQp9IGVsc2UgewogIGNhdCgiU29tZSBTeW1ib2xzIGhhdmUgaW5jb25zaXN0ZW50IFBhdGh3YXkgYXNzb2NpYXRpb25zOlxuIikKICBwcmludChpbmNvbnNpc3RlbnQpCn0KYGBgCgojIyMgQW5hbHlzaXMKCiMjIyMgRGVzY3JpcHRpdmVzCmBgYHtyfQojIENvdW50IGFuZCBzdW1tYXJpemUgZnJlcXVlbmN5IG9mIG1pUk5BcwptaVJOQV9mcmVxIDwtIGRmICU+JQogIGdyb3VwX2J5KElEKSAlPiUKICBzdW1tYXJpemUoQ291bnQgPSBuKCkpICU+JQogIGFycmFuZ2UoZGVzYyhDb3VudCkpCgojIE51bWJlciBvZiBwYXRod2F5cyBkZXRlY3RlZCBwZXIgb3JnYW4KcGF0aHdheV9mcmVxIDwtIGRmICU+JQogIGdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgc3VtbWFyaXplKENvdW50ID0gbigpKSAlPiUKICBhcnJhbmdlKGRlc2MoQ291bnQpKQoKIyBGcmVxdWVuY3kgb2YgZWFjaCBjb25maWRlbmNlIGxldmVsCmNvbmZpZGVuY2VfZnJlcSA8LSBkZiAlPiUKICBncm91cF9ieShjb25maWRlbmNlKSAlPiUKICBzdW1tYXJpemUoQ291bnQgPSBuKCkpICU+JQogIGFycmFuZ2UoZGVzYyhDb3VudCkpCgojIEZyZXF1ZW5jeSBvZiBtUk5BIHN5bWJvbHMgYW5kIHRoZWlyIGFzc29jaWF0ZWQgcGF0aHdheXMKbVJOQV9mcmVxIDwtIGRmICU+JQogIGdyb3VwX2J5KFN5bWJvbCwgUGF0aHdheSkgJT4lICAgICAgCiAgc3VtbWFyaXplKENvdW50ID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgYXJyYW5nZShkZXNjKENvdW50KSkKCiMgQ291bnQgdW5pcXVlIG1pUk5BLW1STkEgcGFpcnMKbWlSTkFfbVJOQV9wYWlycyA8LSBkZiAlPiUKICBncm91cF9ieShTeW1ib2wsIElEKSAlPiUKICBzdW1tYXJpemUoRnJlcXVlbmN5ID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBhcnJhbmdlKGRlc2MoRnJlcXVlbmN5KSkKCiMgUmVuZGVyIHN1bW1hcnkgc3RhdGlzdGljcwpjYXQoIlRoZSBudW1iZXIgb2YgdW5pcXVlIG1pUk5BIHJldmlld2VkIGlzOiIsIGxlbmd0aCh1bmlxdWUoZGYkSUQpKSwgIlxuIikKY2F0KCJUaGUgbnVtYmVyIG9mIHVuaXF1ZSBtUk5BIHJldmlld2VkIGlzOiIsIGxlbmd0aCh1bmlxdWUoZGYkU3ltYm9sKSksICJcbiIpCmNhdCgiVGhlIG51bWJlciBvZiB1bmlxdWUgbWlSTkEtbVJOQSBwYWlycyBpczoiLCBucm93KG1pUk5BX21STkFfcGFpcnMpLCAiXG4iKQoKIyBSZW5kZXIgaW50ZXJhY3RpdmUgdGFibGVzIGZvciB2aXN1YWwgaW5zcGVjdGlvbgpkYXRhdGFibGUobWlSTkFfZnJlcSwgY2FwdGlvbiA9ICJGcmVxdWVuY3kgb2YgRWFjaCBtaVJOQSIsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCkpCmRhdGF0YWJsZShwYXRod2F5X2ZyZXEsIGNhcHRpb24gPSAiTnVtYmVyIG9mIERldGVjdGVkIFBhdGh3YXlzIHBlciBPcmdhbiIsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCkpCmRhdGF0YWJsZShjb25maWRlbmNlX2ZyZXEsIGNhcHRpb24gPSAiRnJlcXVlbmN5IG9mIEVhY2ggQ29uZmlkZW5jZSBMZXZlbCIsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCkpCmRhdGF0YWJsZShtUk5BX2ZyZXEsIGNhcHRpb24gPSAiRnJlcXVlbmN5IG9mIEVhY2ggbVJOQSBhbmQgQXNzb2NpYXRlZCBQYXRod2F5Iiwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDEwKSkKZGF0YXRhYmxlKG1pUk5BX21STkFfcGFpcnMsIGNhcHRpb24gPSAiRnJlcXVlbmN5IG9mIG1pUk5BLW1STkEgUGFpcnMiLCBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTApKQpgYGAKCgoKCiMjIyMgVmlzdWFscwoKIyMjIyBEZWZpbmUgcGxvdCBlbGVtZW50cwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KdGhlbWUyIDwtIHRoZW1lKAogIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gInJveWFsYmx1ZTQiLCBzaXplID0gMTIsIGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksICAjIEFkanVzdCBsYWJlbCBhbmdsZQogIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gInJveWFsYmx1ZTMiLCBzaXplID0gMTIpLAogIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwKICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgZmFjZSA9ICJib2xkLml0YWxpYyIpCikKYGBgCgojIyMjIHBsb3QgdG9wIDE1IG1pUk5BCmBgYHtyfQojIFBsb3QgdGhlIHRvcCAxNSBtb3N0IGZyZXF1ZW50IG1pUk5BCm1pUk5BX2ZyZXEgJT4lCiAgc2xpY2VfbWF4KENvdW50LCBuID0gMTUpICU+JQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoSUQsIC1Db3VudCksIHkgPSBDb3VudCwgZmlsbCA9IENvdW50KSkgKyAKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjMsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDQsIGZvbnRmYWNlID0gImJvbGQiKSArICAKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJsaWdodGJsdWUiLCBoaWdoID0gInJveWFsYmx1ZTQiKSArIAogIGxhYnMoCiAgICB0aXRsZSA9ICJUb3AgMTUgTW9zdCBGcmVxdWVudCBtaVJOQSIsCiAgICB4ID0gIm1pUk5BIiwKICAgIHkgPSAiRnJlcXVlbmN5IgogICkgKwogIHRoZW1lMiArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgYnJlYWtzID0gc2VxKDAsIG1heChtaVJOQV9mcmVxJENvdW50KSwgYnkgPSA1KSwgCiAgICBleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMCwgMC4xKSkgICAgICAgICAgICAjIEFkZCBzcGFjZSBhYm92ZSB0aGUgdGFsbGVzdCBiYXIKICApICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgojIFBsb3QgYWxsIG1STkEgKFN5bWJvbCkgd2l0aCBmcmVxdWVuY3kgYWJvdmUgMwptUk5BX2ZyZXEgJT4lCiAgZmlsdGVyKENvdW50ID4gMykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihTeW1ib2wsIC1Db3VudCksIHkgPSBDb3VudCwgZmlsbCA9IENvdW50KSkgKyAKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gQ291bnQpLCB2anVzdCA9IC0wLjMsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDQsIGZvbnRmYWNlID0gImJvbGQiKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImxpZ2h0Ymx1ZSIsIGhpZ2ggPSAicm95YWxibHVlNCIpICsgIAogIGxhYnMoCiAgICB0aXRsZSA9ICJtUk5BIHdpdGggRnJlcXVlbmN5IEFib3ZlIDMiLAogICAgeCA9ICJtUk5BIiwKICAgIHkgPSAiRnJlcXVlbmN5IgogICkgKwogIHRoZW1lMiArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgYnJlYWtzID0gc2VxKDAsIG1heChtUk5BX2ZyZXEkQ291bnQpLCBieSA9IDIpLAogICAgZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAsIDAuMSkpICAgICAgICAgIAogICkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKIyMjIEV4cGVyaW1lbnRhbCBOZXR3b3JrIGxpYnJhcmllcwpgYGB7cn0KI3N1YnNldCBkZiB0byBvbmx5IHJpZ2h0IGhpcHBvY2Ftb3VzIDI0IGhvdXJzCmRmMjRfcmggPC0gZGYgJT4lCiAgZmlsdGVyKHNhbXBsZSA9PSAiUmlnaHRfSGlwcG9jYW1wdXNfMjRocnMiKQpgYGAKCiMjIyMgaWdyYXBoCmBgYHtyfQojIENyZWF0ZSBhbiBlZGdlIGxpc3QgZnJvbSB0aGUgc3Vic2V0CmVkZ2VzIDwtIGRhdGEuZnJhbWUoZnJvbSA9IGRmMjRfcmgkSUQsIHRvID0gZGYyNF9yaCRTeW1ib2wpCgojIENyZWF0ZSB0aGUgZ3JhcGggb2JqZWN0Cm5ldHdvcmsgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGVkZ2VzKQoKIyB2aXN1YWxpemF0aW9uCnBsb3QoCiAgbmV0d29yaywKICB2ZXJ0ZXguc2l6ZSA9IDEwLCAgICAgICAgICAgICAgICAgCiAgdmVydGV4LmxhYmVsLmNleCA9IDAuOCwgICAgICAgICAgCiAgdmVydGV4LmxhYmVsLmNvbG9yID0gImJsYWNrIiwgICAgCiAgdmVydGV4LmZyYW1lLmNvbG9yID0gTkEsICAgICAgICAgCiAgdmVydGV4LmNvbG9yID0gaWZlbHNlKFYobmV0d29yaykkbmFtZSAlaW4lIGRmMjRfcmgkSUQsICJza3libHVlIiwgInNhbG1vbiIpLCAgCiAgZWRnZS5hcnJvdy5zaXplID0gMC40LCAgICAgICAgICAgIAogIGVkZ2UuY29sb3IgPSAiZ3JheSIsICAgICAgICAgIAogIGVkZ2Uud2lkdGggPSAwLjgsICAgICAgICAgICAgICAKICBtYWluID0gIm1pUk5BLW1STkEgTmV0d29yayAoUmlnaHQgSGlwcG9jYW1wdXMsIDI0aHJzKSIKKQpgYGAKIyMjIyBnZ3JhcGgKYGBge3J9CiMgQ3JlYXRlIGFuIGVkZ2UgbGlzdCBhbmQgZ3JhcGggb2JqZWN0CmVkZ2VzIDwtIGRhdGEuZnJhbWUoZnJvbSA9IGRmMjRfcmgkSUQsIHRvID0gZGYyNF9yaCRTeW1ib2wpCm5ldHdvcmsgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGVkZ2VzLCBkaXJlY3RlZCA9IEZBTFNFKSAgIyBDb252ZXJ0IHRvIHVuZGlyZWN0ZWQgZ3JhcGgKCiMgRGV0ZWN0IGNvbW11bml0aWVzIGZvciBjbHVzdGVyaW5nCmNvbW11bml0aWVzIDwtIGNsdXN0ZXJfbG91dmFpbihuZXR3b3JrKQpWKG5ldHdvcmspJGNvbW11bml0eSA8LSBjb21tdW5pdGllcyRtZW1iZXJzaGlwICAjIEFzc2lnbiBjb21tdW5pdHkgbWVtYmVyc2hpcHMgdG8gbm9kZXMKCiMgSWRlbnRpZnkgbm9kZSB0eXBlcyAobWlSTkEgb3IgbVJOQSkKVihuZXR3b3JrKSR0eXBlIDwtIGlmZWxzZShWKG5ldHdvcmspJG5hbWUgJWluJSBkZjI0X3JoJElELCAibWlSTkEiLCAibVJOQSIpCgojIFZpc3VhbGl6ZSB0aGUgbmV0d29yawpnZ3JhcGgobmV0d29yaywgbGF5b3V0ID0gImZyIikgKyAgIyBGb3JjZS1kaXJlY3RlZCBsYXlvdXQKICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IDAuNSksIGVkZ2VfY29sb3IgPSAiZ3JheSIpICsgIAogIGdlb21fbm9kZV9wb2ludChhZXMoY29sb3IgPSBmYWN0b3IoY29tbXVuaXR5KSwgc2hhcGUgPSB0eXBlKSwgc2l6ZSA9IDYpICsgIAogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUsIHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDMiKSArICAKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygibWlSTkEiID0gMjEsICJtUk5BIiA9IDE5KSkgKyAKICB0aGVtZV92b2lkKCkgKyAgCiAgbGFicygKICAgIHRpdGxlID0gIm1pUk5BLW1STkEgTmV0d29yayAoUmlnaHQgSGlwcG9jYW1wdXMsIDI0aHJzKSIsCiAgICBjb2xvciA9ICJDb21tdW5pdHkiLAogICAgc2hhcGUgPSAiTm9kZSBUeXBlIgogICkgICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIgCiAgKQpgYGAKCiMjIyMgUGF0aHZpZXcKYGBge3J9CmxpYnJhcnkocGF0aHZpZXcpCgojIFN1bW1hcml6ZSBtUk5BIGZyZXF1ZW5jaWVzCmdlbmVfZGF0YSA8LSBkZjI0X3JoICU+JQogIGdyb3VwX2J5KFN5bWJvbCkgJT4lCiAgc3VtbWFyaXplKEZyZXF1ZW5jeSA9IG4oKSkKCiMgQ29udmVydCB0byBhIG5hbWVkIHZlY3RvcgpnZW5lX2RhdGFfdmVjdG9yIDwtIHNldE5hbWVzKGdlbmVfZGF0YSRGcmVxdWVuY3ksIGdlbmVfZGF0YSRTeW1ib2wpCgojIFNwZWNpZnkgdGhlIEtFR0cgcGF0aHdheSBJRCBmb3IgSW5mbGFtbWF0b3J5IE1lZGlhdG9yIFJlZ3VsYXRpb24gb2YgVFJQIENoYW5uZWxzCnBhdGh3YXlfaWQgPC0gImhzYTA0NzUwIgoKIyBWaXN1YWxpemUgdGhlIHBhdGh3YXkKcGF0aHZpZXcoCiAgZ2VuZS5kYXRhID0gZ2VuZV9kYXRhX3ZlY3RvciwKICBwYXRod2F5LmlkID0gcGF0aHdheV9pZCwKICBzcGVjaWVzID0gImhzYSIsICAgICAgICAgCiAgZ2VuZS5pZHR5cGUgPSAiU1lNQk9MIiwgCiAgbGltaXQgPSBsaXN0KGdlbmUgPSBtYXgoZ2VuZV9kYXRhJEZyZXF1ZW5jeSkpLAogIGtlZ2cubmF0aXZlID0gVFJVRSAgICAKKQpgYGAKCgo=