#Differential Expression Analysis
All_samples_Merged
An object of class Seurat
64169 features across 59355 samples within 6 assays
Active assay: SCT (27417 features, 3000 variable features)
3 layers present: counts, data, scale.data
5 other assays present: RNA, ADT, prediction.score.celltype.l1, prediction.score.celltype.l2, prediction.score.celltype.l3
6 dimensional reductions calculated: integrated_dr, ref.umap, pca, umap, harmony, umap.harmony
DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)
DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "Harmony_snn_res.0.9",label = T, label.box = T)
# Prepare the object for DE analysis
All_samples_Merged <- PrepSCTFindMarkers(All_samples_Merged)
Only one SCT model is stored - skipping recalculating corrected counts
#Differential Expression Analysis
DefaultAssay(All_samples_Merged) <- "SCT"
Idents(All_samples_Merged) <- "Harmony_snn_res.0.9"
all_markers <- FindAllMarkers(All_samples_Merged, only.pos = FALSE, logfc.threshold = 0.25)
Calculating cluster 0
Calculating cluster 1
Calculating cluster 2
Calculating cluster 3
Calculating cluster 4
Calculating cluster 5
Calculating cluster 6
Calculating cluster 7
Calculating cluster 8
Calculating cluster 9
Calculating cluster 10
Calculating cluster 11
Calculating cluster 12
Calculating cluster 13
Calculating cluster 14
Calculating cluster 15
Calculating cluster 16
Calculating cluster 17
Calculating cluster 18
Calculating cluster 19
Calculating cluster 20
Calculating cluster 21
Calculating cluster 22
Calculating cluster 23
Calculating cluster 24
write.csv(all_markers, "all_markers.csv")
head(all_markers)
NA
NA
DefaultAssay(All_samples_Merged) <- "SCT" # or the assay where the genes are present
all_markers %>%
group_by(cluster) %>%
dplyr::filter(avg_log2FC > 1) %>%
slice_head(n = 5) %>%
ungroup() -> top5
heatmap_plot5 <-DoHeatmap(All_samples_Merged, features = top5$gene) + NoLegend()
Warning: The following features were omitted as they were not found in the scale.data slot for the SCT assay: MMP2, AC111000.4, PROM1, AC092979.1, CPA3, ITGA2B, AL137230.1, EFNA1
# Save the heatmap as a PNG file
ggsave(filename = "heatmap_result5.png", plot = heatmap_plot5, width = 12, height = 8, dpi = 300)
all_markers %>%
group_by(cluster) %>%
dplyr::filter(avg_log2FC > 1) %>%
slice_head(n = 10) %>%
ungroup() -> top10
heatmap_plot10 <-DoHeatmap(All_samples_Merged, features = top10$gene) + NoLegend()
# Save the heatmap as a PNG file
ggsave(filename = "heatmap_result10.png", plot = heatmap_plot10, width = 12, height = 8, dpi = 300)
```r
top10_markers <- all_markers %>%
group_by(cluster) %>%
top_n(n = 10, wt = avg_log2FC) %>%
arrange(cluster, desc(avg_log2FC))
top10_genes <- unique(top10_markers$gene)
heatmap_data <- GetAssayData(All_samples_Merged, assay = \SCT\, slot = \data\)[top10_genes, ]
heatmap_data <- heatmap_data - rowMeans(heatmap_data)
cell_line_colors <- rainbow(length(unique(All_samples_Merged$cell_line)))
names(cell_line_colors) <- unique(All_samples_Merged$cell_line)
annotation_colors <- list(cell_line = cell_line_colors)
p <- pheatmap(heatmap_data,
show_rownames = TRUE,
show_colnames = FALSE,
annotation_col = All_samples_Merged@meta.data[, \cell_line\, drop = FALSE],
annotation_colors = annotation_colors,
main = \Top 10 Upregulated Genes per Cell Line (Sorted by avg_log2FC)\,
fontsize_row = 6,
treeheight_col = 0,
cluster_rows = FALSE,
cluster_cols = FALSE)
print(p)
png(\heatmap_top10_log2fc_sorted.png\, width = 12, height = 8, units = \in\, res = 300)
print(p)
dev.off()
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# 5. Heatmap of Top 10 Markers (Seurat Default)
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dVhHNTBiM0F4TUY5dFlYSnJaWEp6WDNObGRYSmhkQ0E4TFNCaGJHeGZiV0Z5YTJWeWN5QWxQaVZjYmlBZ1ozSnZkWEJmWW5rb1kyeDFjM1JsY2lrZ0pUNGxYRzRnSUhSdmNGOXVLRzRnUFNBeE1Dd2dkM1FnUFNCaGRtZGZiRzluTWtaREtWeHVYRzUwYjNBeE1GOW5aVzVsYzE5elpYVnlZWFFnUEMwZ2RXNXBjWFZsS0hSdmNERXdYMjFoY210bGNuTmZjMlYxY21GMEpHZGxibVVwWEc1Y2JtaGxZWFJ0WVhCZlpHRjBZVjl6WlhWeVlYUWdQQzBnUjJWMFFYTnpZWGxFWVhSaEtFRnNiRjl6WVcxd2JHVnpYMDFsY21kbFpDd2dZWE56WVhrZ1BTQmNYRk5EVkZ4Y0xDQnpiRzkwSUQwZ1hGeGtZWFJoWEZ3cFczUnZjREV3WDJkbGJtVnpYM05sZFhKaGRDd2dYVnh1YUdWaGRHMWhjRjlrWVhSaFgzTmxkWEpoZENBOExTQm9aV0YwYldGd1gyUmhkR0ZmYzJWMWNtRjBJQzBnY205M1RXVmhibk1vYUdWaGRHMWhjRjlrWVhSaFgzTmxkWEpoZENsY2JseHVjRElnUEMwZ2NHaGxZWFJ0WVhBb2FHVmhkRzFoY0Y5a1lYUmhYM05sZFhKaGRDeGNiaUFnSUNBZ0lDQWdJSE5vYjNkZmNtOTNibUZ0WlhNZ1BTQlVVbFZGTEZ4dUlDQWdJQ0FnSUNBZ2MyaHZkMTlqYjJ4dVlXMWxjeUE5SUVaQlRGTkZMRnh1SUNBZ0lDQWdJQ0FnWVc1dWIzUmhkR2x2Ymw5amIyd2dQU0JCYkd4ZmMyRnRjR3hsYzE5TlpYSm5aV1JBYldWMFlTNWtZWFJoV3l3Z1hGeGpaV3hzWDJ4cGJtVmNYQ3dnWkhKdmNDQTlJRVpCVEZORlhTeGNiaUFnSUNBZ0lDQWdJR0Z1Ym05MFlYUnBiMjVmWTI5c2IzSnpJRDBnWVc1dWIzUmhkR2x2Ymw5amIyeHZjbk1zWEc0Z0lDQWdJQ0FnSUNCdFlXbHVJRDBnWEZ4VWIzQWdNVEFnVFdGeWEyVnljeUJ3WlhJZ1EyVnNiQ0JNYVc1bElDaFRaWFZ5WVhRZ1JHVm1ZWFZzZENsY1hDeGNiaUFnSUNBZ0lDQWdJR1p2Ym5SemFYcGxYM0p2ZHlBOUlEWXNYRzRnSUNBZ0lDQWdJQ0IwY21WbGFHVnBaMmgwWDJOdmJDQTlJREFwWEc1Y2JuQnlhVzUwS0hBeUtWeHVjRzVuS0Z4Y2FHVmhkRzFoY0Y5MGIzQXhNRjl6WlhWeVlYUXVjRzVuWEZ3c0lIZHBaSFJvSUQwZ01USXNJR2hsYVdkb2RDQTlJRGdzSUhWdWFYUnpJRDBnWEZ4cGJseGNMQ0J5WlhNZ1BTQXpNREFwWEc1d2NtbHVkQ2h3TWlsY2JtUmxkaTV2Wm1Zb0tWeHVYRzVnWUdCY2JtQmdZQ0o5IC0tPlxuXG5gYGByXG5gYGByXG5cbnRvcDEwX21hcmtlcnNfc2V1cmF0IDwtIGFsbF9tYXJrZXJzICU+JVxuICBncm91cF9ieShjbHVzdGVyKSAlPiVcbiAgdG9wX24obiA9IDEwLCB3dCA9IGF2Z19sb2cyRkMpXG5cbnRvcDEwX2dlbmVzX3NldXJhdCA8LSB1bmlxdWUodG9wMTBfbWFya2Vyc19zZXVyYXQkZ2VuZSlcblxuaGVhdG1hcF9kYXRhX3NldXJhdCA8LSBHZXRBc3NheURhdGEoQWxsX3NhbXBsZXNfTWVyZ2VkLCBhc3NheSA9IFxcU0NUXFwsIHNsb3QgPSBcXGRhdGFcXClbdG9wMTBfZ2VuZXNfc2V1cmF0LCBdXG5oZWF0bWFwX2RhdGFfc2V1cmF0IDwtIGhlYXRtYXBfZGF0YV9zZXVyYXQgLSByb3dNZWFucyhoZWF0bWFwX2RhdGFfc2V1cmF0KVxuXG5wMiA8LSBwaGVhdG1hcChoZWF0bWFwX2RhdGFfc2V1cmF0LFxuICAgICAgICAgc2hvd19yb3duYW1lcyA9IFRSVUUsXG4gICAgICAgICBzaG93X2NvbG5hbWVzID0gRkFMU0UsXG4gICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IEFsbF9zYW1wbGVzX01lcmdlZEBtZXRhLmRhdGFbLCBcXGNlbGxfbGluZVxcLCBkcm9wID0gRkFMU0VdLFxuICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5vdGF0aW9uX2NvbG9ycyxcbiAgICAgICAgIG1haW4gPSBcXFRvcCAxMCBNYXJrZXJzIHBlciBDZWxsIExpbmUgKFNldXJhdCBEZWZhdWx0KVxcLFxuICAgICAgICAgZm9udHNpemVfcm93ID0gNixcbiAgICAgICAgIHRyZWVoZWlnaHRfY29sID0gMClcblxucHJpbnQocDIpXG5wbmcoXFxoZWF0bWFwX3RvcDEwX3NldXJhdC5wbmdcXCwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOCwgdW5pdHMgPSBcXGluXFwsIHJlcyA9IDMwMClcbnByaW50KHAyKVxuZGV2Lm9mZigpXG5cbmBgYFxuYGBgXG5cbjwhLS0gcm5iLXNvdXJjZS1lbmQgLS0+XG4ifQ== -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuXG50b3AxMF9tYXJrZXJzX3NldXJhdCA8LSBhbGxfbWFya2VycyAlPiVcbiAgZ3JvdXBfYnkoY2x1c3RlcikgJT4lXG4gIHRvcF9uKG4gPSAxMCwgd3QgPSBhdmdfbG9nMkZDKVxuXG50b3AxMF9nZW5lc19zZXVyYXQgPC0gdW5pcXVlKHRvcDEwX21hcmtlcnNfc2V1cmF0JGdlbmUpXG5cbmhlYXRtYXBfZGF0YV9zZXVyYXQgPC0gR2V0QXNzYXlEYXRhKEFsbF9zYW1wbGVzX01lcmdlZCwgYXNzYXkgPSBcXFNDVFxcLCBzbG90ID0gXFxkYXRhXFwpW3RvcDEwX2dlbmVzX3NldXJhdCwgXVxuaGVhdG1hcF9kYXRhX3NldXJhdCA8LSBoZWF0bWFwX2RhdGFfc2V1cmF0IC0gcm93TWVhbnMoaGVhdG1hcF9kYXRhX3NldXJhdClcblxucDIgPC0gcGhlYXRtYXAoaGVhdG1hcF9kYXRhX3NldXJhdCxcbiAgICAgICAgIHNob3dfcm93bmFtZXMgPSBUUlVFLFxuICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEZBTFNFLFxuICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBBbGxfc2FtcGxlc19NZXJnZWRAbWV0YS5kYXRhWywgXFxjZWxsX2xpbmVcXCwgZHJvcCA9IEZBTFNFXSxcbiAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gYW5ub3RhdGlvbl9jb2xvcnMsXG4gICAgICAgICBtYWluID0gXFxUb3AgMTAgTWFya2VycyBwZXIgQ2VsbCBMaW5lIChTZXVyYXQgRGVmYXVsdClcXCxcbiAgICAgICAgIGZvbnRzaXplX3JvdyA9IDYsXG4gICAgICAgICB0cmVlaGVpZ2h0X2NvbCA9IDApXG5cbnByaW50KHAyKVxucG5nKFxcaGVhdG1hcF90b3AxMF9zZXVyYXQucG5nXFwsIHdpZHRoID0gMTIsIGhlaWdodCA9IDgsIHVuaXRzID0gXFxpblxcLCByZXMgPSAzMDApXG5wcmludChwMilcbmRldi5vZmYoKVxuXG5gYGBcbmBgYCJ9 -->
```r
```r
top10_markers_seurat <- all_markers %>%
group_by(cluster) %>%
top_n(n = 10, wt = avg_log2FC)
top10_genes_seurat <- unique(top10_markers_seurat$gene)
heatmap_data_seurat <- GetAssayData(All_samples_Merged, assay = \SCT\, slot = \data\)[top10_genes_seurat, ]
heatmap_data_seurat <- heatmap_data_seurat - rowMeans(heatmap_data_seurat)
p2 <- pheatmap(heatmap_data_seurat,
show_rownames = TRUE,
show_colnames = FALSE,
annotation_col = All_samples_Merged@meta.data[, \cell_line\, drop = FALSE],
annotation_colors = annotation_colors,
main = \Top 10 Markers per Cell Line (Seurat Default)\,
fontsize_row = 6,
treeheight_col = 0)
print(p2)
png(\heatmap_top10_seurat.png\, width = 12, height = 8, units = \in\, res = 300)
print(p2)
dev.off()
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# 6. Pairwise Comparisons
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dWJHbGljbUZ5ZVNoRmJtaGhibU5sWkZadmJHTmhibThwWEc1Y2JuQmxjbVp2Y20xZlkyOXRjR0Z5YVhOdmJsOWhibVJmZG05c1kyRnVieUE4TFNCbWRXNWpkR2x2YmloQmJHeGZjMkZ0Y0d4bGMxOU5aWEpuWldRc0lHbGtaVzUwTVN3Z2FXUmxiblF5S1NCN1hHNGdJRWxrWlc1MGN5aEJiR3hmYzJGdGNHeGxjMTlOWlhKblpXUXBJRHd0SUZ4Y1kyVnNiRjlzYVc1bFhGeGNiaUFnYldGeWEyVnljeUE4TFNCR2FXNWtUV0Z5YTJWeWN5aEJiR3hmYzJGdGNHeGxjMTlOWlhKblpXUXNJR2xrWlc1MExqRWdQU0JwWkdWdWRERXNJR2xrWlc1MExqSWdQU0JwWkdWdWRESXNJR0Z6YzJGNUlEMGdYRnhUUTFSY1hDbGNiaUFnZDNKcGRHVXVZM04yS0cxaGNtdGxjbk1zSUhCaGMzUmxNQ2hjWEdOdmJYQmhjbWx6YjI1ZlhGd3NJR2xrWlc1ME1Td2dYRnhmZG5OZlhGd3NJR2xrWlc1ME1pd2dYRnd1WTNOMlhGd3BLVnh1SUNCY2JpQWdJeUJEY21WaGRHVWdkbTlzWTJGdWJ5QndiRzkwWEc0Z0lIWnZiR05oYm05ZmNHeHZkQ0E4TFNCRmJtaGhibU5sWkZadmJHTmhibThvYldGeWEyVnljeXhjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JzWVdJZ1BTQnliM2R1WVcxbGN5aHRZWEpyWlhKektTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjRJRDBnSjJGMloxOXNiMmN5UmtNbkxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIa2dQU0FuY0Y5MllXeGZZV1JxSnl4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFYUnNaU0E5SUhCaGMzUmxLR2xrWlc1ME1Td2dKM1p6Snl3Z2FXUmxiblF5S1N4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd1EzVjBiMlptSUQwZ01DNHdOU3hjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JHUTJOMWRHOW1aaUE5SURFc1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NHOXBiblJUYVhwbElEMGdNUzQxTEZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUd4aFlsTnBlbVVnUFNBMExqQXNYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZMjlzSUQwZ1l5Z25aM0psZVNjc0lDZGtZWEpyWjNKbFpXNG5MQ0FuWW14MVpTY3NJQ2R5WldRbktTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmpiMnhCYkhCb1lTQTlJREF1TlN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCc1pXZGxibVJRYjNOcGRHbHZiaUE5SUNkeWFXZG9kQ2NzWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYkdWblpXNWtUR0ZpVTJsNlpTQTlJREV3TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUd4bFoyVnVaRWxqYjI1VGFYcGxJRDBnTkM0d0xGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHUnlZWGREYjI1dVpXTjBiM0p6SUQwZ1ZGSlZSU3hjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IzYVdSMGFFTnZibTVsWTNSdmNuTWdQU0F3TGpVcFhHNGdJRnh1SUNCd2NtbHVkQ2gyYjJ4allXNXZYM0JzYjNRcFhHNGdJSEJ1Wnlod1lYTjBaVEFvWEZ4MmIyeGpZVzV2WDF4Y0xDQnBaR1Z1ZERFc0lGeGNYM1p6WDF4Y0xDQnBaR1Z1ZERJc0lGeGNMbkJ1WjF4Y0tTd2dkMmxrZEdnZ1BTQXhNaXdnYUdWcFoyaDBJRDBnTVRBc0lIVnVhWFJ6SUQwZ1hGeHBibHhjTENCeVpYTWdQU0F6TURBcFhHNGdJSEJ5YVc1MEtIWnZiR05oYm05ZmNHeHZkQ2xjYmlBZ1pHVjJMbTltWmlncFhHNGdJRnh1SUNCeVpYUjFjbTRvYldGeWEyVnljeWxjYm4xY2JseHVJeUJRWVhScFpXNTBJREZjYm5BeFgyTnZiWEJoY21semIyNGdQQzBnY0dWeVptOXliVjlqYjIxd1lYSnBjMjl1WDJGdVpGOTJiMnhqWVc1dktFRnNiRjl6WVcxd2JHVnpYMDFsY21kbFpDd2dYRnhNTVZ4Y0xDQmNYRXd5WEZ3cFhHNW9aV0ZrS0hBeFgyTnZiWEJoY21semIyNHBYRzVjYmlNZ1VHRjBhV1Z1ZENBeVhHNXdNbDlqYjIxd1lYSnBjMjl1SUR3dElIQmxjbVp2Y20xZlkyOXRjR0Z5YVhOdmJsOWhibVJmZG05c1kyRnVieWhCYkd4ZmMyRnRjR3hsYzE5TlpYSm5aV1FzSUZ4Y1RETmNYQ3dnWEZ4TU5GeGNLVnh1YUdWaFpDaHdNbDlqYjIxd1lYSnBjMjl1S1Z4dVhHNGpJRkJoZEdsbGJuUWdNMXh1Y0ROZlkyOXRjR0Z5YVhOdmJsOU1OVXcySUR3dElIQmxjbVp2Y20xZlkyOXRjR0Z5YVhOdmJsOWhibVJmZG05c1kyRnVieWhCYkd4ZmMyRnRjR3hsYzE5TlpYSm5aV1FzSUZ4Y1REVmNYQ3dnWEZ4TU5seGNLVnh1Y0ROZlkyOXRjR0Z5YVhOdmJsOU1OVXczSUR3dElIQmxjbVp2Y20xZlkyOXRjR0Z5YVhOdmJsOWhibVJmZG05c1kyRnVieWhCYkd4ZmMyRnRjR3hsYzE5TlpYSm5aV1FzSUZ4Y1REVmNYQ3dnWEZ4TU4xeGNLVnh1Y0ROZlkyOXRjR0Z5YVhOdmJsOU1Oa3czSUR3dElIQmxjbVp2Y20xZlkyOXRjR0Z5YVhOdmJsOWhibVJmZG05c1kyRnVieWhCYkd4ZmMyRnRjR3hsYzE5TlpYSm5aV1FzSUZ4Y1REWmNYQ3dnWEZ4TU4xeGNLVnh1YUdWaFpDaHdNMTlqYjIxd1lYSnBjMjl1WDB3MVREWXBYRzVvWldGa0tIQXpYMk52YlhCaGNtbHpiMjVmVERWTU55bGNibWhsWVdRb2NETmZZMjl0Y0dGeWFYTnZibDlNTmt3M0tWeHVYRzVjYm1CZ1lGeHVZR0JnSW4wPSAtLT5cblxuYGBgclxuYGBgclxubGlicmFyeShFbmhhbmNlZFZvbGNhbm8pXG5cbnBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyA8LSBmdW5jdGlvbihBbGxfc2FtcGxlc19NZXJnZWQsIGlkZW50MSwgaWRlbnQyKSB7XG4gIElkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpIDwtIFxcY2VsbF9saW5lXFxcbiAgbWFya2VycyA8LSBGaW5kTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIGlkZW50LjEgPSBpZGVudDEsIGlkZW50LjIgPSBpZGVudDIsIGFzc2F5ID0gXFxTQ1RcXClcbiAgd3JpdGUuY3N2KG1hcmtlcnMsIHBhc3RlMChcXGNvbXBhcmlzb25fXFwsIGlkZW50MSwgXFxfdnNfXFwsIGlkZW50MiwgXFwuY3N2XFwpKVxuICBcbiAgIyBDcmVhdGUgdm9sY2FubyBwbG90XG4gIHZvbGNhbm9fcGxvdCA8LSBFbmhhbmNlZFZvbGNhbm8obWFya2VycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhtYXJrZXJzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gJ2F2Z19sb2cyRkMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncF92YWxfYWRqJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IHBhc3RlKGlkZW50MSwgJ3ZzJywgaWRlbnQyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMS41LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYlNpemUgPSA0LjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gYygnZ3JleScsICdkYXJrZ3JlZW4nLCAnYmx1ZScsICdyZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUpXG4gIFxuICBwcmludCh2b2xjYW5vX3Bsb3QpXG4gIHBuZyhwYXN0ZTAoXFx2b2xjYW5vX1xcLCBpZGVudDEsIFxcX3ZzX1xcLCBpZGVudDIsIFxcLnBuZ1xcKSwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gXFxpblxcLCByZXMgPSAzMDApXG4gIHByaW50KHZvbGNhbm9fcGxvdClcbiAgZGV2Lm9mZigpXG4gIFxuICByZXR1cm4obWFya2Vycylcbn1cblxuIyBQYXRpZW50IDFcbnAxX2NvbXBhcmlzb24gPC0gcGVyZm9ybV9jb21wYXJpc29uX2FuZF92b2xjYW5vKEFsbF9zYW1wbGVzX01lcmdlZCwgXFxMMVxcLCBcXEwyXFwpXG5oZWFkKHAxX2NvbXBhcmlzb24pXG5cbiMgUGF0aWVudCAyXG5wMl9jb21wYXJpc29uIDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDNcXCwgXFxMNFxcKVxuaGVhZChwMl9jb21wYXJpc29uKVxuXG4jIFBhdGllbnQgM1xucDNfY29tcGFyaXNvbl9MNUw2IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDVcXCwgXFxMNlxcKVxucDNfY29tcGFyaXNvbl9MNUw3IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDVcXCwgXFxMN1xcKVxucDNfY29tcGFyaXNvbl9MNkw3IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDZcXCwgXFxMN1xcKVxuaGVhZChwM19jb21wYXJpc29uX0w1TDYpXG5oZWFkKHAzX2NvbXBhcmlzb25fTDVMNylcbmhlYWQocDNfY29tcGFyaXNvbl9MNkw3KVxuXG5cbmBgYFxuYGBgXG5cbjwhLS0gcm5iLXNvdXJjZS1lbmQgLS0+XG4ifQ== -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxubGlicmFyeShFbmhhbmNlZFZvbGNhbm8pXG5cbnBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyA8LSBmdW5jdGlvbihBbGxfc2FtcGxlc19NZXJnZWQsIGlkZW50MSwgaWRlbnQyKSB7XG4gIElkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpIDwtIFxcY2VsbF9saW5lXFxcbiAgbWFya2VycyA8LSBGaW5kTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIGlkZW50LjEgPSBpZGVudDEsIGlkZW50LjIgPSBpZGVudDIsIGFzc2F5ID0gXFxTQ1RcXClcbiAgd3JpdGUuY3N2KG1hcmtlcnMsIHBhc3RlMChcXGNvbXBhcmlzb25fXFwsIGlkZW50MSwgXFxfdnNfXFwsIGlkZW50MiwgXFwuY3N2XFwpKVxuICBcbiAgIyBDcmVhdGUgdm9sY2FubyBwbG90XG4gIHZvbGNhbm9fcGxvdCA8LSBFbmhhbmNlZFZvbGNhbm8obWFya2VycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhtYXJrZXJzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gJ2F2Z19sb2cyRkMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAncF92YWxfYWRqJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IHBhc3RlKGlkZW50MSwgJ3ZzJywgaWRlbnQyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMS41LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYlNpemUgPSA0LjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gYygnZ3JleScsICdkYXJrZ3JlZW4nLCAnYmx1ZScsICdyZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUpXG4gIFxuICBwcmludCh2b2xjYW5vX3Bsb3QpXG4gIHBuZyhwYXN0ZTAoXFx2b2xjYW5vX1xcLCBpZGVudDEsIFxcX3ZzX1xcLCBpZGVudDIsIFxcLnBuZ1xcKSwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gXFxpblxcLCByZXMgPSAzMDApXG4gIHByaW50KHZvbGNhbm9fcGxvdClcbiAgZGV2Lm9mZigpXG4gIFxuICByZXR1cm4obWFya2Vycylcbn1cblxuIyBQYXRpZW50IDFcbnAxX2NvbXBhcmlzb24gPC0gcGVyZm9ybV9jb21wYXJpc29uX2FuZF92b2xjYW5vKEFsbF9zYW1wbGVzX01lcmdlZCwgXFxMMVxcLCBcXEwyXFwpXG5oZWFkKHAxX2NvbXBhcmlzb24pXG5cbiMgUGF0aWVudCAyXG5wMl9jb21wYXJpc29uIDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDNcXCwgXFxMNFxcKVxuaGVhZChwMl9jb21wYXJpc29uKVxuXG4jIFBhdGllbnQgM1xucDNfY29tcGFyaXNvbl9MNUw2IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDVcXCwgXFxMNlxcKVxucDNfY29tcGFyaXNvbl9MNUw3IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDVcXCwgXFxMN1xcKVxucDNfY29tcGFyaXNvbl9MNkw3IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsIFxcTDZcXCwgXFxMN1xcKVxuaGVhZChwM19jb21wYXJpc29uX0w1TDYpXG5oZWFkKHAzX2NvbXBhcmlzb25fTDVMNylcbmhlYWQocDNfY29tcGFyaXNvbl9MNkw3KVxuXG5cbmBgYFxuYGBgIn0= -->
```r
```r
library(EnhancedVolcano)
perform_comparison_and_volcano <- function(All_samples_Merged, ident1, ident2) {
Idents(All_samples_Merged) <- \cell_line\
markers <- FindMarkers(All_samples_Merged, ident.1 = ident1, ident.2 = ident2, assay = \SCT\)
write.csv(markers, paste0(\comparison_\, ident1, \_vs_\, ident2, \.csv\))
# Create volcano plot
volcano_plot <- EnhancedVolcano(markers,
lab = rownames(markers),
x = 'avg_log2FC',
y = 'p_val_adj',
title = paste(ident1, 'vs', ident2),
pCutoff = 0.05,
FCcutoff = 1,
pointSize = 1.5,
labSize = 4.0,
col = c('grey', 'darkgreen', 'blue', 'red'),
colAlpha = 0.5,
legendPosition = 'right',
legendLabSize = 10,
legendIconSize = 4.0,
drawConnectors = TRUE,
widthConnectors = 0.5)
print(volcano_plot)
png(paste0(\volcano_\, ident1, \_vs_\, ident2, \.png\), width = 12, height = 10, units = \in\, res = 300)
print(volcano_plot)
dev.off()
return(markers)
}
# Patient 1
p1_comparison <- perform_comparison_and_volcano(All_samples_Merged, \L1\, \L2\)
head(p1_comparison)
# Patient 2
p2_comparison <- perform_comparison_and_volcano(All_samples_Merged, \L3\, \L4\)
head(p2_comparison)
# Patient 3
p3_comparison_L5L6 <- perform_comparison_and_volcano(All_samples_Merged, \L5\, \L6\)
p3_comparison_L5L7 <- perform_comparison_and_volcano(All_samples_Merged, \L5\, \L7\)
p3_comparison_L6L7 <- perform_comparison_and_volcano(All_samples_Merged, \L6\, \L7\)
head(p3_comparison_L5L6)
head(p3_comparison_L5L7)
head(p3_comparison_L6L7)
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# 7. Enrichment Analysis
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dVhHNXdaWEptYjNKdFgyZHZYMlZ1Y21samFHMWxiblFnUEMwZ1puVnVZM1JwYjI0b1oyVnVaVjlzYVhOMExDQm5aVzVsWDNWdWFYWmxjbk5sTENCMGFYUnNaU2tnZTF4dUlDQmxaMjhnUEMwZ1pXNXlhV05vUjA4b1oyVnVaU0E5SUdkbGJtVmZiR2x6ZEN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIVnVhWFpsY25ObElEMGdaMlZ1WlY5MWJtbDJaWEp6WlN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lFOXlaMFJpSUQwZ2IzSm5Ma2h6TG1WbkxtUmlMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYTJWNVZIbHdaU0E5SUZ4Y1UxbE5RazlNWEZ3c1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnZiblFnUFNCY1hFSlFYRndzWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd1FXUnFkWE4wVFdWMGFHOWtJRDBnWEZ4Q1NGeGNMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY1haaGJIVmxRM1YwYjJabUlEMGdNQzR3TlN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxZV1JoWW14bElEMGdWRkpWUlNsY2JpQWdYRzRnSUhBZ1BDMGdaRzkwY0d4dmRDaGxaMjhzSUhOb2IzZERZWFJsWjI5eWVTQTlJREl3TENCMGFYUnNaU0E5SUhCaGMzUmxLRnhjUjA4Z0xWeGNMQ0IwYVhSc1pTa3BJQ3RjYmlBZ0lDQjBhR1Z0WlNoaGVHbHpMblJsZUhRdWVTQTlJR1ZzWlcxbGJuUmZkR1Y0ZENoemFYcGxJRDBnT0NrcFhHNGdJRnh1SUNCd2NtbHVkQ2h3S1Z4dUlDQndibWNvY0dGemRHVXdLRnhjUjA5ZlpXNXlhV05vYldWdWRGOWNYQ3dnWjNOMVlpaGNYQ0JjWEN3Z1hGeGZYRndzSUhScGRHeGxLU3dnWEZ3dWNHNW5YRndwTENCM2FXUjBhQ0E5SURFeUxDQm9aV2xuYUhRZ1BTQTRMQ0IxYm1sMGN5QTlJRnhjYVc1Y1hDd2djbVZ6SUQwZ016QXdLVnh1SUNCd2NtbHVkQ2h3S1Z4dUlDQmtaWFl1YjJabUtDbGNiaUFnWEc0Z0lISmxkSFZ5YmlobFoyOHBYRzU5WEc1Y2JuQmxjbVp2Y20xZmEyVm5aMTlsYm5KcFkyaHRaVzUwSUR3dElHWjFibU4wYVc5dUtHZGxibVZmYkdsemRDd2daMlZ1WlY5MWJtbDJaWEp6WlN3Z2RHbDBiR1VwSUh0Y2JpQWdJeUJEYjI1MlpYSjBJR2RsYm1VZ2MzbHRZbTlzY3lCMGJ5QkZiblJ5WlhvZ1NVUnpYRzRnSUdWdWRISmxlbDlwWkhNZ1BDMGdZbWwwY2loblpXNWxYMnhwYzNRc0lHWnliMjFVZVhCbElEMGdYRnhUV1UxQ1QweGNYQ3dnZEc5VWVYQmxJRDBnWEZ4RlRsUlNSVnBKUkZ4Y0xDQlBjbWRFWWlBOUlHOXlaeTVJY3k1bFp5NWtZaWtrUlU1VVVrVmFTVVJjYmlBZ2RXNXBkbVZ5YzJWZlpXNTBjbVY2SUR3dElHSnBkSElvWjJWdVpWOTFibWwyWlhKelpTd2dabkp2YlZSNWNHVWdQU0JjWEZOWlRVSlBURnhjTENCMGIxUjVjR1VnUFNCY1hFVk9WRkpGV2tsRVhGd3NJRTl5WjBSaUlEMGdiM0puTGtoekxtVm5MbVJpS1NSRlRsUlNSVnBKUkZ4dUlDQmNiaUFnWld0bFoyY2dQQzBnWlc1eWFXTm9TMFZIUnloblpXNWxJRDBnWlc1MGNtVjZYMmxrY3l4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IxYm1sMlpYSnpaU0E5SUhWdWFYWmxjbk5sWDJWdWRISmxlaXhjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnZjbWRoYm1semJTQTlJQ2RvYzJFbkxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUd0bGVWUjVjR1VnUFNCY1hHdGxaMmRjWEN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3ZG1Gc2RXVkRkWFJ2Wm1ZZ1BTQXdMakExTEZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEJCWkdwMWMzUk5aWFJvYjJRZ1BTQmNYRUpJWEZ3cFhHNGdJRnh1SUNCd0lEd3RJR1J2ZEhCc2IzUW9aV3RsWjJjc0lITm9iM2REWVhSbFoyOXllU0E5SURJd0xDQjBhWFJzWlNBOUlIQmhjM1JsS0Z4Y1MwVkhSeUF0WEZ3c0lIUnBkR3hsS1NrZ0sxeHVJQ0FnSUhSb1pXMWxLR0Y0YVhNdWRHVjRkQzU1SUQwZ1pXeGxiV1Z1ZEY5MFpYaDBLSE5wZW1VZ1BTQTRLU2xjYmlBZ1hHNGdJSEJ5YVc1MEtIQXBYRzRnSUhCdVp5aHdZWE4wWlRBb1hGeExSVWRIWDJWdWNtbGphRzFsYm5SZlhGd3NJR2R6ZFdJb1hGd2dYRndzSUZ4Y1gxeGNMQ0IwYVhSc1pTa3NJRnhjTG5CdVoxeGNLU3dnZDJsa2RHZ2dQU0F4TWl3Z2FHVnBaMmgwSUQwZ09Dd2dkVzVwZEhNZ1BTQmNYR2x1WEZ3c0lISmxjeUE5SURNd01DbGNiaUFnY0hKcGJuUW9jQ2xjYmlBZ1pHVjJMbTltWmlncFhHNGdJRnh1SUNCeVpYUjFjbTRvWld0bFoyY3BYRzU5WEc1Y2JtZGxibVZmZFc1cGRtVnljMlVnUEMwZ2NtOTNibUZ0WlhNb1FXeHNYM05oYlhCc1pYTmZUV1Z5WjJWa0tWeHVYRzRqSUZCaGRHbGxiblFnTVNBb1VERXBJR052YlhCaGNtbHpiMjQ2SUV3eElIWnpJRXd5WEc1MWNISmxaM1ZzWVhSbFpGOW5aVzVsYzE5UU1TQThMU0J5YjNkdVlXMWxjeWh3TVY5amIyMXdZWEpwYzI5dVczQXhYMk52YlhCaGNtbHpiMjRrWVhablgyeHZaekpHUXlBK0lERWdKaUJ3TVY5amIyMXdZWEpwYzI5dUpIQmZkbUZzWDJGa2FpQThJREF1TURVc0lGMHBYRzVrYjNkdWNtVm5kV3hoZEdWa1gyZGxibVZ6WDFBeElEd3RJSEp2ZDI1aGJXVnpLSEF4WDJOdmJYQmhjbWx6YjI1YmNERmZZMjl0Y0dGeWFYTnZiaVJoZG1kZmJHOW5Na1pESUR3Z0xURWdKaUJ3TVY5amIyMXdZWEpwYzI5dUpIQmZkbUZzWDJGa2FpQThJREF1TURVc0lGMHBYRzVjYm1kdlgzVndYMUF4SUR3dElIQmxjbVp2Y20xZloyOWZaVzV5YVdOb2JXVnVkQ2gxY0hKbFozVnNZWFJsWkY5blpXNWxjMTlRTVN3Z1oyVnVaVjkxYm1sMlpYSnpaU3dnWEZ4VmNISmxaM1ZzWVhSbFpDQkhaVzVsY3lCcGJpQk1NU0IyY3lCTU1seGNLVnh1WjI5ZlpHOTNibDlRTVNBOExTQndaWEptYjNKdFgyZHZYMlZ1Y21samFHMWxiblFvWkc5M2JuSmxaM1ZzWVhSbFpGOW5aVzVsYzE5UU1Td2daMlZ1WlY5MWJtbDJaWEp6WlN3Z1hGeEViM2R1Y21WbmRXeGhkR1ZrSUVkbGJtVnpJR2x1SUV3eElIWnpJRXd5WEZ3cFhHNXJaV2RuWDNWd1gxQXhJRHd0SUhCbGNtWnZjbTFmYTJWbloxOWxibkpwWTJodFpXNTBLSFZ3Y21WbmRXeGhkR1ZrWDJkbGJtVnpYMUF4TENCblpXNWxYM1Z1YVhabGNuTmxMQ0JjWEZWd2NtVm5kV3hoZEdWa0lFZGxibVZ6SUdsdUlFd3hJSFp6SUV3eVhGd3BYRzVyWldkblgyUnZkMjVmVURFZ1BDMGdjR1Z5Wm05eWJWOXJaV2RuWDJWdWNtbGphRzFsYm5Rb1pHOTNibkpsWjNWc1lYUmxaRjluWlc1bGMxOVFNU3dnWjJWdVpWOTFibWwyWlhKelpTd2dYRnhFYjNkdWNtVm5kV3hoZEdWa0lFZGxibVZ6SUdsdUlFd3hJSFp6SUV3eVhGd3BYRzVjYmlNZ1VHRjBhV1Z1ZENBeUlDaFFNaWtnWTI5dGNHRnlhWE52YmpvZ1RETWdkbk1nVERSY2JuVndjbVZuZFd4aGRHVmtYMmRsYm1WelgxQXlJRHd0SUhKdmQyNWhiV1Z6S0hBeVgyTnZiWEJoY21semIyNWJjREpmWTI5dGNHRnlhWE52YmlSaGRtZGZiRzluTWtaRElENGdNU0FtSUhBeVgyTnZiWEJoY21semIyNGtjRjkyWVd4ZllXUnFJRHdnTUM0d05Td2dYU2xjYm1SdmQyNXlaV2QxYkdGMFpXUmZaMlZ1WlhOZlVESWdQQzBnY205M2JtRnRaWE1vY0RKZlkyOXRjR0Z5YVhOdmJsdHdNbDlqYjIxd1lYSnBjMjl1SkdGMloxOXNiMmN5UmtNZ1BDQXRNU0FtSUhBeVgyTnZiWEJoY21semIyNGtjRjkyWVd4ZllXUnFJRHdnTUM0d05Td2dYU2xjYmx4dVoyOWZkWEJmVURJZ1BDMGdjR1Z5Wm05eWJWOW5iMTlsYm5KcFkyaHRaVzUwS0hWd2NtVm5kV3hoZEdWa1gyZGxibVZ6WDFBeUxDQm5aVzVsWDNWdWFYWmxjbk5sTENCY1hGVndjbVZuZFd4aGRHVmtJRWRsYm1WeklHbHVJRXd6SUhaeklFdzBYRndwWEc1bmIxOWtiM2R1WDFBeUlEd3RJSEJsY21admNtMWZaMjlmWlc1eWFXTm9iV1Z1ZENoa2IzZHVjbVZuZFd4aGRHVmtYMmRsYm1WelgxQXlMQ0JuWlc1bFgzVnVhWFpsY25ObExDQmNYRVJ2ZDI1eVpXZDFiR0YwWldRZ1IyVnVaWE1nYVc0Z1RETWdkbk1nVERSY1hDbGNibXRsWjJkZmRYQmZVRElnUEMwZ2NHVnlabTl5YlY5clpXZG5YMlZ1Y21samFHMWxiblFvZFhCeVpXZDFiR0YwWldSZloyVnVaWE5mVURJc0lHZGxibVZmZFc1cGRtVnljMlVzSUZ4Y1ZYQnlaV2QxYkdGMFpXUWdSMlZ1WlhNZ2FXNGdURE1nZG5NZ1REUmNYQ2xjYm10bFoyZGZaRzkzYmw5UU1pQThMU0J3WlhKbWIzSnRYMnRsWjJkZlpXNXlhV05vYldWdWRDaGtiM2R1Y21WbmRXeGhkR1ZrWDJkbGJtVnpYMUF5TENCblpXNWxYM1Z1YVhabGNuTmxMQ0JjWEVSdmQyNXlaV2QxYkdGMFpXUWdSMlZ1WlhNZ2FXNGdURE1nZG5NZ1REUmNYQ2xjYmx4dUl5QlFZWFJwWlc1MElETWdLRkF6S1NCamIyMXdZWEpwYzI5dWMxeHVJeUJNTlNCMmN5Qk1ObHh1ZFhCeVpXZDFiR0YwWldSZloyVnVaWE5mVUROZlREVk1OaUE4TFNCeWIzZHVZVzFsY3lod00xOWpiMjF3WVhKcGMyOXVYMHcxVERaYmNETmZZMjl0Y0dGeWFYTnZibDlNTlV3MkpHRjJaMTlzYjJjeVJrTWdQaUF4SUNZZ2NETmZZMjl0Y0dGeWFYTnZibDlNTlV3MkpIQmZkbUZzWDJGa2FpQThJREF1TURVc0lGMHBYRzVrYjNkdWNtVm5kV3hoZEdWa1gyZGxibVZ6WDFBelgwdzFURFlnUEMwZ2NtOTNibUZ0WlhNb2NETmZZMjl0Y0dGeWFYTnZibDlNTlV3MlczQXpYMk52YlhCaGNtbHpiMjVmVERWTU5pUmhkbWRmYkc5bk1rWkRJRHdnTFRFZ0ppQndNMTlqYjIxd1lYSnBjMjl1WDB3MVREWWtjRjkyWVd4ZllXUnFJRHdnTUM0d05Td2dYU2xjYmx4dVoyOWZkWEJmVUROZlREVk1OaUE4TFNCd1pYSm1iM0p0WDJkdlgyVnVjbWxqYUcxbGJuUW9kWEJ5WldkMWJHRjBaV1JmWjJWdVpYTmZVRE5mVERWTU5pd2daMlZ1WlY5MWJtbDJaWEp6WlN3Z1hGeFZjSEpsWjNWc1lYUmxaQ0JIWlc1bGN5QnBiaUJNTlNCMmN5Qk1ObHhjS1Z4dVoyOWZaRzkzYmw5UU0xOU1OVXcySUR3dElIQmxjbVp2Y20xZloyOWZaVzV5YVdOb2JXVnVkQ2hrYjNkdWNtVm5kV3hoZEdWa1gyZGxibVZ6WDFBelgwdzFURFlzSUdkbGJtVmZkVzVwZG1WeWMyVXNJRnhjUkc5M2JuSmxaM1ZzWVhSbFpDQkhaVzVsY3lCcGJpQk1OU0IyY3lCTU5seGNLVnh1YTJWbloxOTFjRjlRTTE5TU5VdzJJRHd0SUhCbGNtWnZjbTFmYTJWbloxOWxibkpwWTJodFpXNTBLSFZ3Y21WbmRXeGhkR1ZrWDJkbGJtVnpYMUF6WDB3MVREWXNJR2RsYm1WZmRXNXBkbVZ5YzJVc0lGeGNWWEJ5WldkMWJHRjBaV1FnUjJWdVpYTWdhVzRnVERVZ2RuTWdURFpjWENsY2JtdGxaMmRmWkc5M2JsOVFNMTlNTlV3MklEd3RJSEJsY21admNtMWZhMlZuWjE5bGJuSnBZMmh0Wlc1MEtHUnZkMjV5WldkMWJHRjBaV1JmWjJWdVpYTmZVRE5mVERWTU5pd2daMlZ1WlY5MWJtbDJaWEp6WlN3Z1hGeEViM2R1Y21WbmRXeGhkR1ZrSUVkbGJtVnpJR2x1SUV3MUlIWnpJRXcyWEZ3cFhHNWNiaU1nVERVZ2RuTWdURGRjYm5Wd2NtVm5kV3hoZEdWa1gyZGxibVZ6WDFBelgwdzFURGNnUEMwZ2NtOTNibUZ0WlhNb2NETmZZMjl0Y0dGeWFYTnZibDlNTlV3M1czQXpYMk52YlhCaGNtbHpiMjVmVERWTU55UmhkbWRmYkc5bk1rWkRJRDRnTVNBbUlIQXpYMk52YlhCaGNtbHpiMjVmVERWTU55UndYM1poYkY5aFpHb2dQQ0F3TGpBMUxDQmRLVnh1Wkc5M2JuSmxaM1ZzWVhSbFpGOW5aVzVsYzE5UU0xOU1OVXczSUR3dElISnZkMjVoYldWektIQXpYMk52YlhCaGNtbHpiMjVmVERWTU4xdHdNMTlqYjIxd1lYSnBjMjl1WDB3MVREY2tZWFpuWDJ4dlp6SkdReUE4SUMweElDWWdjRE5mWTI5dGNHRnlhWE52Ymw5TU5VdzNKSEJmZG1Gc1gyRmthaUE4SURBdU1EVXNJRjBwWEc1Y2JtZHZYM1Z3WDFBelgwdzFURGNnUEMwZ2NHVnlabTl5YlY5bmIxOWxibkpwWTJodFpXNTBLSFZ3Y21WbmRXeGhkR1ZrWDJkbGJtVnpYMUF6WDB3MVREY3NJR2RsYm1WZmRXNXBkbVZ5YzJVc0lGeGNWWEJ5WldkMWJHRjBaV1FnUjJWdVpYTWdhVzRnVERVZ2RuTWdURGRjWENsY2JtZHZYMlJ2ZDI1ZlVETmZURFZNTnlBOExTQndaWEptYjNKdFgyZHZYMlZ1Y21samFHMWxiblFvWkc5M2JuSmxaM1ZzWVhSbFpGOW5aVzVsYzE5UU0xOU1OVXczTENCblpXNWxYM1Z1YVhabGNuTmxMQ0JjWEVSdmQyNXlaV2QxYkdGMFpXUWdSMlZ1WlhNZ2FXNGdURFVnZG5NZ1REZGNYQ2xjYm10bFoyZGZkWEJmVUROZlREVk1OeUE4TFNCd1pYSm1iM0p0WDJ0bFoyZGZaVzV5YVdOb2JXVnVkQ2gxY0hKbFozVnNZWFJsWkY5blpXNWxjMTlRTTE5TU5VdzNMQ0JuWlc1bFgzVnVhWFpsY25ObExDQmNYRlZ3Y21WbmRXeGhkR1ZrSUVkbGJtVnpJR2x1SUV3MUlIWnpJRXczWEZ3cFhHNXJaV2RuWDJSdmQyNWZVRE5mVERWTU55QThMU0J3WlhKbWIzSnRYMnRsWjJkZlpXNXlhV05vYldWdWRDaGtiM2R1Y21WbmRXeGhkR1ZrWDJkbGJtVnpYMUF6WDB3MVREY3NJR2RsYm1WZmRXNXBkbVZ5YzJVc0lGeGNSRzkzYm5KbFozVnNZWFJsWkNCSFpXNWxjeUJwYmlCTU5TQjJjeUJNTjF4Y0tWeHVYRzRqSUV3MklIWnpJRXczWEc1MWNISmxaM1ZzWVhSbFpGOW5aVzVsYzE5UU0xOU1Oa3czSUR3dElISnZkMjVoYldWektIQXpYMk52YlhCaGNtbHpiMjVmVERaTU4xdHdNMTlqYjIxd1lYSnBjMjl1WDB3MlREY2tZWFpuWDJ4dlp6SkdReUErSURFZ0ppQndNMTlqYjIxd1lYSnBjMjl1WDB3MlREY2tjRjkyWVd4ZllXUnFJRHdnTUM0d05Td2dYU2xjYm1SdmQyNXlaV2QxYkdGMFpXUmZaMlZ1WlhOZlVETmZURFpNTnlBOExTQnliM2R1WVcxbGN5aHdNMTlqYjIxd1lYSnBjMjl1WDB3MlREZGJjRE5mWTI5dGNHRnlhWE52Ymw5TU5rdzNKR0YyWjE5c2IyY3lSa01nUENBdE1TQW1JSEF6WDJOdmJYQmhjbWx6YjI1ZlREWk1OeVJ3WDNaaGJGOWhaR29nUENBd0xqQTFMQ0JkS1Z4dVhHNW5iMTkxY0Y5UU0xOU1Oa3czSUR3dElIQmxjbVp2Y20xZloyOWZaVzV5YVdOb2JXVnVkQ2gxY0hKbFozVnNZWFJsWkY5blpXNWxjMTlRTTE5TU5rdzNMQ0JuWlc1bFgzVnVhWFpsY25ObExDQmNYRlZ3Y21WbmRXeGhkR1ZrSUVkbGJtVnpJR2x1SUV3MklIWnpJRXczWEZ3cFhHNW5iMTlrYjNkdVgxQXpYMHcyVERjZ1BDMGdjR1Z5Wm05eWJWOW5iMTlsYm5KcFkyaHRaVzUwS0dSdmQyNXlaV2QxYkdGMFpXUmZaMlZ1WlhOZlVETmZURFpNTnl3Z1oyVnVaVjkxYm1sMlpYSnpaU3dnWEZ4RWIzZHVjbVZuZFd4aGRHVmtJRWRsYm1WeklHbHVJRXcySUhaeklFdzNYRndwWEc1clpXZG5YM1Z3WDFBelgwdzJURGNnUEMwZ2NHVnlabTl5YlY5clpXZG5YMlZ1Y21samFHMWxiblFvZFhCeVpXZDFiR0YwWldSZloyVnVaWE5mVUROZlREWk1OeXdnWjJWdVpWOTFibWwyWlhKelpTd2dYRnhWY0hKbFozVnNZWFJsWkNCSFpXNWxjeUJwYmlCTU5pQjJjeUJNTjF4Y0tWeHVhMlZuWjE5a2IzZHVYMUF6WDB3MlREY2dQQzBnY0dWeVptOXliVjlyWldkblgyVnVjbWxqYUcxbGJuUW9aRzkzYm5KbFozVnNZWFJsWkY5blpXNWxjMTlRTTE5TU5rdzNMQ0JuWlc1bFgzVnVhWFpsY25ObExDQmNYRVJ2ZDI1eVpXZDFiR0YwWldRZ1IyVnVaWE1nYVc0Z1REWWdkbk1nVERkY1hDbGNibHh1WUdCZ1hHNWdZR0FpZlE9PSAtLT5cblxuYGBgclxuYGBgclxuXG5wZXJmb3JtX2dvX2VucmljaG1lbnQgPC0gZnVuY3Rpb24oZ2VuZV9saXN0LCBnZW5lX3VuaXZlcnNlLCB0aXRsZSkge1xuICBlZ28gPC0gZW5yaWNoR08oZ2VuZSA9IGdlbmVfbGlzdCxcbiAgICAgICAgICAgICAgICAgIHVuaXZlcnNlID0gZ2VuZV91bml2ZXJzZSxcbiAgICAgICAgICAgICAgICAgIE9yZ0RiID0gb3JnLkhzLmVnLmRiLFxuICAgICAgICAgICAgICAgICAga2V5VHlwZSA9IFxcU1lNQk9MXFwsXG4gICAgICAgICAgICAgICAgICBvbnQgPSBcXEJQXFwsXG4gICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gXFxCSFxcLFxuICAgICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmID0gMC4wNSxcbiAgICAgICAgICAgICAgICAgIHJlYWRhYmxlID0gVFJVRSlcbiAgXG4gIHAgPC0gZG90cGxvdChlZ28sIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9IHBhc3RlKFxcR08gLVxcLCB0aXRsZSkpICtcbiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpXG4gIFxuICBwcmludChwKVxuICBwbmcocGFzdGUwKFxcR09fZW5yaWNobWVudF9cXCwgZ3N1YihcXCBcXCwgXFxfXFwsIHRpdGxlKSwgXFwucG5nXFwpLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA4LCB1bml0cyA9IFxcaW5cXCwgcmVzID0gMzAwKVxuICBwcmludChwKVxuICBkZXYub2ZmKClcbiAgXG4gIHJldHVybihlZ28pXG59XG5cbnBlcmZvcm1fa2VnZ19lbnJpY2htZW50IDwtIGZ1bmN0aW9uKGdlbmVfbGlzdCwgZ2VuZV91bml2ZXJzZSwgdGl0bGUpIHtcbiAgIyBDb252ZXJ0IGdlbmUgc3ltYm9scyB0byBFbnRyZXogSURzXG4gIGVudHJlel9pZHMgPC0gYml0cihnZW5lX2xpc3QsIGZyb21UeXBlID0gXFxTWU1CT0xcXCwgdG9UeXBlID0gXFxFTlRSRVpJRFxcLCBPcmdEYiA9IG9yZy5Icy5lZy5kYikkRU5UUkVaSURcbiAgdW5pdmVyc2VfZW50cmV6IDwtIGJpdHIoZ2VuZV91bml2ZXJzZSwgZnJvbVR5cGUgPSBcXFNZTUJPTFxcLCB0b1R5cGUgPSBcXEVOVFJFWklEXFwsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKSRFTlRSRVpJRFxuICBcbiAgZWtlZ2cgPC0gZW5yaWNoS0VHRyhnZW5lID0gZW50cmV6X2lkcyxcbiAgICAgICAgICAgICAgICAgICAgICB1bml2ZXJzZSA9IHVuaXZlcnNlX2VudHJleixcbiAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICdoc2EnLFxuICAgICAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSBcXGtlZ2dcXCxcbiAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1LFxuICAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSBcXEJIXFwpXG4gIFxuICBwIDwtIGRvdHBsb3QoZWtlZ2csIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9IHBhc3RlKFxcS0VHRyAtXFwsIHRpdGxlKSkgK1xuICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSlcbiAgXG4gIHByaW50KHApXG4gIHBuZyhwYXN0ZTAoXFxLRUdHX2VucmljaG1lbnRfXFwsIGdzdWIoXFwgXFwsIFxcX1xcLCB0aXRsZSksIFxcLnBuZ1xcKSwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOCwgdW5pdHMgPSBcXGluXFwsIHJlcyA9IDMwMClcbiAgcHJpbnQocClcbiAgZGV2Lm9mZigpXG4gIFxuICByZXR1cm4oZWtlZ2cpXG59XG5cbmdlbmVfdW5pdmVyc2UgPC0gcm93bmFtZXMoQWxsX3NhbXBsZXNfTWVyZ2VkKVxuXG4jIFBhdGllbnQgMSAoUDEpIGNvbXBhcmlzb246IEwxIHZzIEwyXG51cHJlZ3VsYXRlZF9nZW5lc19QMSA8LSByb3duYW1lcyhwMV9jb21wYXJpc29uW3AxX2NvbXBhcmlzb24kYXZnX2xvZzJGQyA+IDEgJiBwMV9jb21wYXJpc29uJHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5kb3ducmVndWxhdGVkX2dlbmVzX1AxIDwtIHJvd25hbWVzKHAxX2NvbXBhcmlzb25bcDFfY29tcGFyaXNvbiRhdmdfbG9nMkZDIDwgLTEgJiBwMV9jb21wYXJpc29uJHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5cbmdvX3VwX1AxIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgXFxVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMMSB2cyBMMlxcKVxuZ29fZG93bl9QMSA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyXFwpXG5rZWdnX3VwX1AxIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AxLCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyXFwpXG5rZWdnX2Rvd25fUDEgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyXFwpXG5cbiMgUGF0aWVudCAyIChQMikgY29tcGFyaXNvbjogTDMgdnMgTDRcbnVwcmVndWxhdGVkX2dlbmVzX1AyIDwtIHJvd25hbWVzKHAyX2NvbXBhcmlzb25bcDJfY29tcGFyaXNvbiRhdmdfbG9nMkZDID4gMSAmIHAyX2NvbXBhcmlzb24kcF92YWxfYWRqIDwgMC4wNSwgXSlcbmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDIgPC0gcm93bmFtZXMocDJfY29tcGFyaXNvbltwMl9jb21wYXJpc29uJGF2Z19sb2cyRkMgPCAtMSAmIHAyX2NvbXBhcmlzb24kcF92YWxfYWRqIDwgMC4wNSwgXSlcblxuZ29fdXBfUDIgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEwzIHZzIEw0XFwpXG5nb19kb3duX1AyIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDRcXClcbmtlZ2dfdXBfUDIgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDIsIGdlbmVfdW5pdmVyc2UsIFxcVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDRcXClcbmtlZ2dfZG93bl9QMiA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDRcXClcblxuIyBQYXRpZW50IDMgKFAzKSBjb21wYXJpc29uc1xuIyBMNSB2cyBMNlxudXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNiA8LSByb3duYW1lcyhwM19jb21wYXJpc29uX0w1TDZbcDNfY29tcGFyaXNvbl9MNUw2JGF2Z19sb2cyRkMgPiAxICYgcDNfY29tcGFyaXNvbl9MNUw2JHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5kb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDYgPC0gcm93bmFtZXMocDNfY29tcGFyaXNvbl9MNUw2W3AzX2NvbXBhcmlzb25fTDVMNiRhdmdfbG9nMkZDIDwgLTEgJiBwM19jb21wYXJpc29uX0w1TDYkcF92YWxfYWRqIDwgMC4wNSwgXSlcblxuZ29fdXBfUDNfTDVMNiA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNiwgZ2VuZV91bml2ZXJzZSwgXFxVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNlxcKVxuZ29fZG93bl9QM19MNUw2IDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDYsIGdlbmVfdW5pdmVyc2UsIFxcRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNlxcKVxua2VnZ191cF9QM19MNUw2IDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDYsIGdlbmVfdW5pdmVyc2UsIFxcVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDZcXClcbmtlZ2dfZG93bl9QM19MNUw2IDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KGRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNiwgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw2XFwpXG5cbiMgTDUgdnMgTDdcbnVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDcgPC0gcm93bmFtZXMocDNfY29tcGFyaXNvbl9MNUw3W3AzX2NvbXBhcmlzb25fTDVMNyRhdmdfbG9nMkZDID4gMSAmIHAzX2NvbXBhcmlzb25fTDVMNyRwX3ZhbF9hZGogPCAwLjA1LCBdKVxuZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNUw3IDwtIHJvd25hbWVzKHAzX2NvbXBhcmlzb25fTDVMN1twM19jb21wYXJpc29uX0w1TDckYXZnX2xvZzJGQyA8IC0xICYgcDNfY29tcGFyaXNvbl9MNUw3JHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5cbmdvX3VwX1AzX0w1TDcgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDcsIGdlbmVfdW5pdmVyc2UsIFxcVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDdcXClcbmdvX2Rvd25fUDNfTDVMNyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNUw3LCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDdcXClcbmtlZ2dfdXBfUDNfTDVMNyA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QM19MNUw3LCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw3XFwpXG5rZWdnX2Rvd25fUDNfTDVMNyA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDcsIGdlbmVfdW5pdmVyc2UsIFxcRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMN1xcKVxuXG4jIEw2IHZzIEw3XG51cHJlZ3VsYXRlZF9nZW5lc19QM19MNkw3IDwtIHJvd25hbWVzKHAzX2NvbXBhcmlzb25fTDZMN1twM19jb21wYXJpc29uX0w2TDckYXZnX2xvZzJGQyA+IDEgJiBwM19jb21wYXJpc29uX0w2TDckcF92YWxfYWRqIDwgMC4wNSwgXSlcbmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNyA8LSByb3duYW1lcyhwM19jb21wYXJpc29uX0w2TDdbcDNfY29tcGFyaXNvbl9MNkw3JGF2Z19sb2cyRkMgPCAtMSAmIHAzX2NvbXBhcmlzb25fTDZMNyRwX3ZhbF9hZGogPCAwLjA1LCBdKVxuXG5nb191cF9QM19MNkw3IDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QM19MNkw3LCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEw2IHZzIEw3XFwpXG5nb19kb3duX1AzX0w2TDcgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KGRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNywgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEw2IHZzIEw3XFwpXG5rZWdnX3VwX1AzX0w2TDcgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNywgZ2VuZV91bml2ZXJzZSwgXFxVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNiB2cyBMN1xcKVxua2VnZ19kb3duX1AzX0w2TDcgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNkw3LCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDYgdnMgTDdcXClcblxuYGBgXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuXG5wZXJmb3JtX2dvX2VucmljaG1lbnQgPC0gZnVuY3Rpb24oZ2VuZV9saXN0LCBnZW5lX3VuaXZlcnNlLCB0aXRsZSkge1xuICBlZ28gPC0gZW5yaWNoR08oZ2VuZSA9IGdlbmVfbGlzdCxcbiAgICAgICAgICAgICAgICAgIHVuaXZlcnNlID0gZ2VuZV91bml2ZXJzZSxcbiAgICAgICAgICAgICAgICAgIE9yZ0RiID0gb3JnLkhzLmVnLmRiLFxuICAgICAgICAgICAgICAgICAga2V5VHlwZSA9IFxcU1lNQk9MXFwsXG4gICAgICAgICAgICAgICAgICBvbnQgPSBcXEJQXFwsXG4gICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gXFxCSFxcLFxuICAgICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmID0gMC4wNSxcbiAgICAgICAgICAgICAgICAgIHJlYWRhYmxlID0gVFJVRSlcbiAgXG4gIHAgPC0gZG90cGxvdChlZ28sIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9IHBhc3RlKFxcR08gLVxcLCB0aXRsZSkpICtcbiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpXG4gIFxuICBwcmludChwKVxuICBwbmcocGFzdGUwKFxcR09fZW5yaWNobWVudF9cXCwgZ3N1YihcXCBcXCwgXFxfXFwsIHRpdGxlKSwgXFwucG5nXFwpLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA4LCB1bml0cyA9IFxcaW5cXCwgcmVzID0gMzAwKVxuICBwcmludChwKVxuICBkZXYub2ZmKClcbiAgXG4gIHJldHVybihlZ28pXG59XG5cbnBlcmZvcm1fa2VnZ19lbnJpY2htZW50IDwtIGZ1bmN0aW9uKGdlbmVfbGlzdCwgZ2VuZV91bml2ZXJzZSwgdGl0bGUpIHtcbiAgIyBDb252ZXJ0IGdlbmUgc3ltYm9scyB0byBFbnRyZXogSURzXG4gIGVudHJlel9pZHMgPC0gYml0cihnZW5lX2xpc3QsIGZyb21UeXBlID0gXFxTWU1CT0xcXCwgdG9UeXBlID0gXFxFTlRSRVpJRFxcLCBPcmdEYiA9IG9yZy5Icy5lZy5kYikkRU5UUkVaSURcbiAgdW5pdmVyc2VfZW50cmV6IDwtIGJpdHIoZ2VuZV91bml2ZXJzZSwgZnJvbVR5cGUgPSBcXFNZTUJPTFxcLCB0b1R5cGUgPSBcXEVOVFJFWklEXFwsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKSRFTlRSRVpJRFxuICBcbiAgZWtlZ2cgPC0gZW5yaWNoS0VHRyhnZW5lID0gZW50cmV6X2lkcyxcbiAgICAgICAgICAgICAgICAgICAgICB1bml2ZXJzZSA9IHVuaXZlcnNlX2VudHJleixcbiAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICdoc2EnLFxuICAgICAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSBcXGtlZ2dcXCxcbiAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1LFxuICAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSBcXEJIXFwpXG4gIFxuICBwIDwtIGRvdHBsb3QoZWtlZ2csIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9IHBhc3RlKFxcS0VHRyAtXFwsIHRpdGxlKSkgK1xuICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSlcbiAgXG4gIHByaW50KHApXG4gIHBuZyhwYXN0ZTAoXFxLRUdHX2VucmljaG1lbnRfXFwsIGdzdWIoXFwgXFwsIFxcX1xcLCB0aXRsZSksIFxcLnBuZ1xcKSwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOCwgdW5pdHMgPSBcXGluXFwsIHJlcyA9IDMwMClcbiAgcHJpbnQocClcbiAgZGV2Lm9mZigpXG4gIFxuICByZXR1cm4oZWtlZ2cpXG59XG5cbmdlbmVfdW5pdmVyc2UgPC0gcm93bmFtZXMoQWxsX3NhbXBsZXNfTWVyZ2VkKVxuXG4jIFBhdGllbnQgMSAoUDEpIGNvbXBhcmlzb246IEwxIHZzIEwyXG51cHJlZ3VsYXRlZF9nZW5lc19QMSA8LSByb3duYW1lcyhwMV9jb21wYXJpc29uW3AxX2NvbXBhcmlzb24kYXZnX2xvZzJGQyA+IDEgJiBwMV9jb21wYXJpc29uJHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5kb3ducmVndWxhdGVkX2dlbmVzX1AxIDwtIHJvd25hbWVzKHAxX2NvbXBhcmlzb25bcDFfY29tcGFyaXNvbiRhdmdfbG9nMkZDIDwgLTEgJiBwMV9jb21wYXJpc29uJHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5cbmdvX3VwX1AxIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgXFxVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMMSB2cyBMMlxcKVxuZ29fZG93bl9QMSA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyXFwpXG5rZWdnX3VwX1AxIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AxLCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyXFwpXG5rZWdnX2Rvd25fUDEgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyXFwpXG5cbiMgUGF0aWVudCAyIChQMikgY29tcGFyaXNvbjogTDMgdnMgTDRcbnVwcmVndWxhdGVkX2dlbmVzX1AyIDwtIHJvd25hbWVzKHAyX2NvbXBhcmlzb25bcDJfY29tcGFyaXNvbiRhdmdfbG9nMkZDID4gMSAmIHAyX2NvbXBhcmlzb24kcF92YWxfYWRqIDwgMC4wNSwgXSlcbmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDIgPC0gcm93bmFtZXMocDJfY29tcGFyaXNvbltwMl9jb21wYXJpc29uJGF2Z19sb2cyRkMgPCAtMSAmIHAyX2NvbXBhcmlzb24kcF92YWxfYWRqIDwgMC4wNSwgXSlcblxuZ29fdXBfUDIgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEwzIHZzIEw0XFwpXG5nb19kb3duX1AyIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDRcXClcbmtlZ2dfdXBfUDIgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDIsIGdlbmVfdW5pdmVyc2UsIFxcVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDRcXClcbmtlZ2dfZG93bl9QMiA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDRcXClcblxuIyBQYXRpZW50IDMgKFAzKSBjb21wYXJpc29uc1xuIyBMNSB2cyBMNlxudXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNiA8LSByb3duYW1lcyhwM19jb21wYXJpc29uX0w1TDZbcDNfY29tcGFyaXNvbl9MNUw2JGF2Z19sb2cyRkMgPiAxICYgcDNfY29tcGFyaXNvbl9MNUw2JHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5kb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDYgPC0gcm93bmFtZXMocDNfY29tcGFyaXNvbl9MNUw2W3AzX2NvbXBhcmlzb25fTDVMNiRhdmdfbG9nMkZDIDwgLTEgJiBwM19jb21wYXJpc29uX0w1TDYkcF92YWxfYWRqIDwgMC4wNSwgXSlcblxuZ29fdXBfUDNfTDVMNiA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNiwgZ2VuZV91bml2ZXJzZSwgXFxVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNlxcKVxuZ29fZG93bl9QM19MNUw2IDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDYsIGdlbmVfdW5pdmVyc2UsIFxcRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNlxcKVxua2VnZ191cF9QM19MNUw2IDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDYsIGdlbmVfdW5pdmVyc2UsIFxcVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDZcXClcbmtlZ2dfZG93bl9QM19MNUw2IDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KGRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNiwgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw2XFwpXG5cbiMgTDUgdnMgTDdcbnVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDcgPC0gcm93bmFtZXMocDNfY29tcGFyaXNvbl9MNUw3W3AzX2NvbXBhcmlzb25fTDVMNyRhdmdfbG9nMkZDID4gMSAmIHAzX2NvbXBhcmlzb25fTDVMNyRwX3ZhbF9hZGogPCAwLjA1LCBdKVxuZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNUw3IDwtIHJvd25hbWVzKHAzX2NvbXBhcmlzb25fTDVMN1twM19jb21wYXJpc29uX0w1TDckYXZnX2xvZzJGQyA8IC0xICYgcDNfY29tcGFyaXNvbl9MNUw3JHBfdmFsX2FkaiA8IDAuMDUsIF0pXG5cbmdvX3VwX1AzX0w1TDcgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDcsIGdlbmVfdW5pdmVyc2UsIFxcVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDdcXClcbmdvX2Rvd25fUDNfTDVMNyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNUw3LCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDdcXClcbmtlZ2dfdXBfUDNfTDVMNyA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QM19MNUw3LCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw3XFwpXG5rZWdnX2Rvd25fUDNfTDVMNyA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDcsIGdlbmVfdW5pdmVyc2UsIFxcRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMN1xcKVxuXG4jIEw2IHZzIEw3XG51cHJlZ3VsYXRlZF9nZW5lc19QM19MNkw3IDwtIHJvd25hbWVzKHAzX2NvbXBhcmlzb25fTDZMN1twM19jb21wYXJpc29uX0w2TDckYXZnX2xvZzJGQyA+IDEgJiBwM19jb21wYXJpc29uX0w2TDckcF92YWxfYWRqIDwgMC4wNSwgXSlcbmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNyA8LSByb3duYW1lcyhwM19jb21wYXJpc29uX0w2TDdbcDNfY29tcGFyaXNvbl9MNkw3JGF2Z19sb2cyRkMgPCAtMSAmIHAzX2NvbXBhcmlzb25fTDZMNyRwX3ZhbF9hZGogPCAwLjA1LCBdKVxuXG5nb191cF9QM19MNkw3IDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QM19MNkw3LCBnZW5lX3VuaXZlcnNlLCBcXFVwcmVndWxhdGVkIEdlbmVzIGluIEw2IHZzIEw3XFwpXG5nb19kb3duX1AzX0w2TDcgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KGRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNywgZ2VuZV91bml2ZXJzZSwgXFxEb3ducmVndWxhdGVkIEdlbmVzIGluIEw2IHZzIEw3XFwpXG5rZWdnX3VwX1AzX0w2TDcgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNywgZ2VuZV91bml2ZXJzZSwgXFxVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNiB2cyBMN1xcKVxua2VnZ19kb3duX1AzX0w2TDcgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNkw3LCBnZW5lX3VuaXZlcnNlLCBcXERvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDYgdnMgTDdcXClcblxuYGBgXG5gYGAifQ== -->
```r
```r
perform_go_enrichment <- function(gene_list, gene_universe, title) {
ego <- enrichGO(gene = gene_list,
universe = gene_universe,
OrgDb = org.Hs.eg.db,
keyType = \SYMBOL\,
ont = \BP\,
pAdjustMethod = \BH\,
qvalueCutoff = 0.05,
readable = TRUE)
p <- dotplot(ego, showCategory = 20, title = paste(\GO -\, title)) +
theme(axis.text.y = element_text(size = 8))
print(p)
png(paste0(\GO_enrichment_\, gsub(\ \, \_\, title), \.png\), width = 12, height = 8, units = \in\, res = 300)
print(p)
dev.off()
return(ego)
}
perform_kegg_enrichment <- function(gene_list, gene_universe, title) {
# Convert gene symbols to Entrez IDs
entrez_ids <- bitr(gene_list, fromType = \SYMBOL\, toType = \ENTREZID\, OrgDb = org.Hs.eg.db)$ENTREZID
universe_entrez <- bitr(gene_universe, fromType = \SYMBOL\, toType = \ENTREZID\, OrgDb = org.Hs.eg.db)$ENTREZID
ekegg <- enrichKEGG(gene = entrez_ids,
universe = universe_entrez,
organism = 'hsa',
keyType = \kegg\,
pvalueCutoff = 0.05,
pAdjustMethod = \BH\)
p <- dotplot(ekegg, showCategory = 20, title = paste(\KEGG -\, title)) +
theme(axis.text.y = element_text(size = 8))
print(p)
png(paste0(\KEGG_enrichment_\, gsub(\ \, \_\, title), \.png\), width = 12, height = 8, units = \in\, res = 300)
print(p)
dev.off()
return(ekegg)
}
gene_universe <- rownames(All_samples_Merged)
# Patient 1 (P1) comparison: L1 vs L2
upregulated_genes_P1 <- rownames(p1_comparison[p1_comparison$avg_log2FC > 1 & p1_comparison$p_val_adj < 0.05, ])
downregulated_genes_P1 <- rownames(p1_comparison[p1_comparison$avg_log2FC < -1 & p1_comparison$p_val_adj < 0.05, ])
go_up_P1 <- perform_go_enrichment(upregulated_genes_P1, gene_universe, \Upregulated Genes in L1 vs L2\)
go_down_P1 <- perform_go_enrichment(downregulated_genes_P1, gene_universe, \Downregulated Genes in L1 vs L2\)
kegg_up_P1 <- perform_kegg_enrichment(upregulated_genes_P1, gene_universe, \Upregulated Genes in L1 vs L2\)
kegg_down_P1 <- perform_kegg_enrichment(downregulated_genes_P1, gene_universe, \Downregulated Genes in L1 vs L2\)
# Patient 2 (P2) comparison: L3 vs L4
upregulated_genes_P2 <- rownames(p2_comparison[p2_comparison$avg_log2FC > 1 & p2_comparison$p_val_adj < 0.05, ])
downregulated_genes_P2 <- rownames(p2_comparison[p2_comparison$avg_log2FC < -1 & p2_comparison$p_val_adj < 0.05, ])
go_up_P2 <- perform_go_enrichment(upregulated_genes_P2, gene_universe, \Upregulated Genes in L3 vs L4\)
go_down_P2 <- perform_go_enrichment(downregulated_genes_P2, gene_universe, \Downregulated Genes in L3 vs L4\)
kegg_up_P2 <- perform_kegg_enrichment(upregulated_genes_P2, gene_universe, \Upregulated Genes in L3 vs L4\)
kegg_down_P2 <- perform_kegg_enrichment(downregulated_genes_P2, gene_universe, \Downregulated Genes in L3 vs L4\)
# Patient 3 (P3) comparisons
# L5 vs L6
upregulated_genes_P3_L5L6 <- rownames(p3_comparison_L5L6[p3_comparison_L5L6$avg_log2FC > 1 & p3_comparison_L5L6$p_val_adj < 0.05, ])
downregulated_genes_P3_L5L6 <- rownames(p3_comparison_L5L6[p3_comparison_L5L6$avg_log2FC < -1 & p3_comparison_L5L6$p_val_adj < 0.05, ])
go_up_P3_L5L6 <- perform_go_enrichment(upregulated_genes_P3_L5L6, gene_universe, \Upregulated Genes in L5 vs L6\)
go_down_P3_L5L6 <- perform_go_enrichment(downregulated_genes_P3_L5L6, gene_universe, \Downregulated Genes in L5 vs L6\)
kegg_up_P3_L5L6 <- perform_kegg_enrichment(upregulated_genes_P3_L5L6, gene_universe, \Upregulated Genes in L5 vs L6\)
kegg_down_P3_L5L6 <- perform_kegg_enrichment(downregulated_genes_P3_L5L6, gene_universe, \Downregulated Genes in L5 vs L6\)
# L5 vs L7
upregulated_genes_P3_L5L7 <- rownames(p3_comparison_L5L7[p3_comparison_L5L7$avg_log2FC > 1 & p3_comparison_L5L7$p_val_adj < 0.05, ])
downregulated_genes_P3_L5L7 <- rownames(p3_comparison_L5L7[p3_comparison_L5L7$avg_log2FC < -1 & p3_comparison_L5L7$p_val_adj < 0.05, ])
go_up_P3_L5L7 <- perform_go_enrichment(upregulated_genes_P3_L5L7, gene_universe, \Upregulated Genes in L5 vs L7\)
go_down_P3_L5L7 <- perform_go_enrichment(downregulated_genes_P3_L5L7, gene_universe, \Downregulated Genes in L5 vs L7\)
kegg_up_P3_L5L7 <- perform_kegg_enrichment(upregulated_genes_P3_L5L7, gene_universe, \Upregulated Genes in L5 vs L7\)
kegg_down_P3_L5L7 <- perform_kegg_enrichment(downregulated_genes_P3_L5L7, gene_universe, \Downregulated Genes in L5 vs L7\)
# L6 vs L7
upregulated_genes_P3_L6L7 <- rownames(p3_comparison_L6L7[p3_comparison_L6L7$avg_log2FC > 1 & p3_comparison_L6L7$p_val_adj < 0.05, ])
downregulated_genes_P3_L6L7 <- rownames(p3_comparison_L6L7[p3_comparison_L6L7$avg_log2FC < -1 & p3_comparison_L6L7$p_val_adj < 0.05, ])
go_up_P3_L6L7 <- perform_go_enrichment(upregulated_genes_P3_L6L7, gene_universe, \Upregulated Genes in L6 vs L7\)
go_down_P3_L6L7 <- perform_go_enrichment(downregulated_genes_P3_L6L7, gene_universe, \Downregulated Genes in L6 vs L7\)
kegg_up_P3_L6L7 <- perform_kegg_enrichment(upregulated_genes_P3_L6L7, gene_universe, \Upregulated Genes in L6 vs L7\)
kegg_down_P3_L6L7 <- perform_kegg_enrichment(downregulated_genes_P3_L6L7, gene_universe, \Downregulated Genes in L6 vs L7\)
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# 8. Network Analysis
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dUl5QkdkVzVqZEdsdmJpQjBieUJuWlhRZ2RHOXdJR2RsYm1WeklHWnliMjBnWVNCamIyMXdZWEpwYzI5dVhHNWNibXhwWW5KaGNua29hV2R5WVhCb0tWeHViR2xpY21GeWVTaFRWRkpKVGtka1lpbGNibXhwWW5KaGNua29aMmR5WVhCb0tWeHViR2xpY21GeWVTaDBhV1I1ZG1WeWMyVXBYRzVzYVdKeVlYSjVLSFJwWW1Kc1pTbGNibHh1WjJWMFgzUnZjRjluWlc1bGN5QThMU0JtZFc1amRHbHZiaWhqYjIxd1lYSnBjMjl1WDNKbGMzVnNkQ3dnYmlBOUlEVXdLU0I3WEc0Z0lIUnZjRjluWlc1bGN5QThMU0JqYjIxd1lYSnBjMjl1WDNKbGMzVnNkQ0FsUGlWY2JpQWdJQ0J5YjNkdVlXMWxjMTkwYjE5amIyeDFiVzRvWEZ4blpXNWxYRndwSUNVK0pWeHVJQ0FnSUdGeWNtRnVaMlVvWkdWell5aGhZbk1vWVhablgyeHZaekpHUXlrcEtTQWxQaVZjYmlBZ0lDQm9aV0ZrS0c0cElDVStKVnh1SUNBZ0lIQjFiR3dvWjJWdVpTbGNiaUFnY21WMGRYSnVLSFJ2Y0Y5blpXNWxjeWxjYm4xY2JseHVJeUJEYjIxaWFXNWxJSFJ2Y0NCblpXNWxjeUJtY205dElHRnNiQ0JqYjIxd1lYSnBjMjl1YzF4dVlXeHNYM1J2Y0Y5blpXNWxjeUE4TFNCMWJtbHhkV1VvWXloY2JpQWdaMlYwWDNSdmNGOW5aVzVsY3lod01WOWpiMjF3WVhKcGMyOXVLU3hjYmlBZ1oyVjBYM1J2Y0Y5blpXNWxjeWh3TWw5amIyMXdZWEpwYzI5dUtTeGNiaUFnWjJWMFgzUnZjRjluWlc1bGN5aHdNMTlqYjIxd1lYSnBjMjl1WDB3MVREWXBMRnh1SUNCblpYUmZkRzl3WDJkbGJtVnpLSEF6WDJOdmJYQmhjbWx6YjI1ZlREVk1OeWtzWEc0Z0lHZGxkRjkwYjNCZloyVnVaWE1vY0ROZlkyOXRjR0Z5YVhOdmJsOU1Oa3czS1Z4dUtTbGNibHh1SXlCSmJtbDBhV0ZzYVhwbElGTlVVa2xPUjJSaVhHNXpkSEpwYm1kZlpHSWdQQzBnVTFSU1NVNUhaR0lrYm1WM0tIWmxjbk5wYjI0OVhGd3hNVnhjTENCemNHVmphV1Z6UFRrMk1EWXNJSE5qYjNKbFgzUm9jbVZ6YUc5c1pEMDNNREFwWEc1Y2JpTWdUV0Z3SUdkbGJtVnpJSFJ2SUZOVVVrbE9SeUJwWkdWdWRHbG1hV1Z5YzF4dWJXRndjR1ZrWDJkbGJtVnpJRHd0SUhOMGNtbHVaMTlrWWlSdFlYQW9aR0YwWVM1bWNtRnRaU2huWlc1bFBXRnNiRjkwYjNCZloyVnVaWE1wTENCY1hHZGxibVZjWEN3Z2NtVnRiM1psVlc1dFlYQndaV1JTYjNkeklEMGdWRkpWUlNsY2JseHVJeUJIWlhRZ2FXNTBaWEpoWTNScGIyNXpYRzVwYm5SbGNtRmpkR2x2Ym5NZ1BDMGdjM1J5YVc1blgyUmlKR2RsZEY5cGJuUmxjbUZqZEdsdmJuTW9iV0Z3Y0dWa1gyZGxibVZ6SkZOVVVrbE9SMTlwWkNsY2JseHVJeUJEY21WaGRHVWdhV2R5WVhCb0lHOWlhbVZqZEZ4dVp5QThMU0JuY21Gd2FGOW1jbTl0WDJSaGRHRmZabkpoYldVb2FXNTBaWEpoWTNScGIyNXpMQ0JrYVhKbFkzUmxaQ0E5SUVaQlRGTkZLVnh1WEc0aklFTmhiR04xYkdGMFpTQnViMlJsSUdSbFozSmxaWE5jYmxZb1p5a2taR1ZuY21WbElEd3RJR1JsWjNKbFpTaG5LVnh1WEc0aklFTmhiR04xYkdGMFpTQmlaWFIzWldWdWJtVnpjeUJqWlc1MGNtRnNhWFI1WEc1V0tHY3BKR0psZEhkbFpXNXVaWE56SUR3dElHSmxkSGRsWlc1dVpYTnpLR2NwWEc1Y2JpTWdTV1JsYm5ScFpua2dZMjl0YlhWdWFYUnBaWE5jYm1OdmJXMTFibWwwYVdWeklEd3RJR05zZFhOMFpYSmZiRzkxZG1GcGJpaG5LVnh1VmlobktTUmpiMjF0ZFc1cGRIa2dQQzBnWTI5dGJYVnVhWFJwWlhNa2JXVnRZbVZ5YzJocGNGeHVYRzRqSUZCc2IzUWdkR2hsSUc1bGRIZHZjbXRjYm5ObGRDNXpaV1ZrS0RFeU15a2dJQ01nWm05eUlISmxjSEp2WkhWamFXSnBiR2wwZVZ4dVoyZHlZWEJvS0djc0lHeGhlVzkxZENBOUlGeGNabkpjWENrZ0sxeHVJQ0JuWlc5dFgyVmtaMlZmYkdsdWF5aGhaWE1vWldSblpWOWhiSEJvWVNBOUlHTnZiV0pwYm1Wa1gzTmpiM0psS1N3Z2MyaHZkeTVzWldkbGJtUWdQU0JHUVV4VFJTa2dLMXh1SUNCblpXOXRYMjV2WkdWZmNHOXBiblFvWVdWektHTnZiRzl5SUQwZ1ptRmpkRzl5S0dOdmJXMTFibWwwZVNrc0lITnBlbVVnUFNCa1pXZHlaV1VwS1NBclhHNGdJR2RsYjIxZmJtOWtaVjkwWlhoMEtHRmxjeWhzWVdKbGJDQTlJRzVoYldVcExDQnlaWEJsYkNBOUlGUlNWVVVzSUhOcGVtVWdQU0F6S1NBclhHNGdJSE5qWVd4bFgyTnZiRzl5WDJKeVpYZGxjaWh3WVd4bGRIUmxJRDBnWEZ4VFpYUXhYRndwSUN0Y2JpQWdkR2hsYldWZmRtOXBaQ2dwSUN0Y2JpQWdiR0ZpY3loMGFYUnNaU0E5SUZ4Y1IyVnVaU0JKYm5SbGNtRmpkR2x2YmlCT1pYUjNiM0pyWEZ3c1hHNGdJQ0FnSUNBZ2MzVmlkR2wwYkdVZ1BTQmNYRUpoYzJWa0lHOXVJSFJ2Y0NCa2FXWm1aWEpsYm5ScFlXeHNlU0JsZUhCeVpYTnpaV1FnWjJWdVpYTmNYQ3hjYmlBZ0lDQWdJQ0JqYjJ4dmNpQTlJRnhjUTI5dGJYVnVhWFI1WEZ3c1hHNGdJQ0FnSUNBZ2MybDZaU0E5SUZ4Y1JHVm5jbVZsWEZ3cFhHNWNiaU1nVTJGMlpTQjBhR1VnY0d4dmRGeHVaMmR6WVhabEtGeGNaMlZ1WlY5cGJuUmxjbUZqZEdsdmJsOXVaWFIzYjNKckxuQnVaMXhjTENCM2FXUjBhQ0E5SURFeUxDQm9aV2xuYUhRZ1BTQXhNQ3dnWkhCcElEMGdNekF3S1Z4dVhHNGpJRWxrWlc1MGFXWjVJR2gxWWlCblpXNWxjMXh1YUhWaVgyZGxibVZ6SUR3dElGWW9aeWtrYm1GdFpWdHZjbVJsY2loV0tHY3BKR1JsWjNKbFpTd2daR1ZqY21WaGMybHVaeUE5SUZSU1ZVVXBYVnN4T2pFd1hWeHVZMkYwS0Z4Y1ZHOXdJREV3SUdoMVlpQm5aVzVsY3pwY1hHNWNYQ2xjYm5CeWFXNTBLR2gxWWw5blpXNWxjeWxjYmx4dUl5QkpaR1Z1ZEdsbWVTQm5aVzVsY3lCM2FYUm9JR2hwWjJnZ1ltVjBkMlZsYm01bGMzTWdZMlZ1ZEhKaGJHbDBlVnh1YUdsbmFGOWlaWFIzWldWdWJtVnpjMTluWlc1bGN5QThMU0JXS0djcEpHNWhiV1ZiYjNKa1pYSW9WaWhuS1NSaVpYUjNaV1Z1Ym1WemN5d2daR1ZqY21WaGMybHVaeUE5SUZSU1ZVVXBYVnN4T2pFd1hWeHVZMkYwS0Z4Y1hGeHVWRzl3SURFd0lHZGxibVZ6SUhkcGRHZ2dhR2xuYUNCaVpYUjNaV1Z1Ym1WemN5QmpaVzUwY21Gc2FYUjVPbHhjYmx4Y0tWeHVjSEpwYm5Rb2FHbG5hRjlpWlhSM1pXVnVibVZ6YzE5blpXNWxjeWxjYmx4dUl5QkRZV3hqZFd4aGRHVWdZVzVrSUhCeWFXNTBJSE52YldVZ2JtVjBkMjl5YXlCemRHRjBhWE4wYVdOelhHNWpZWFFvWEZ4Y1hHNU9aWFIzYjNKcklGTjBZWFJwYzNScFkzTTZYRnh1WEZ3cFhHNWpZWFFvWEZ4T2RXMWlaWElnYjJZZ2JtOWtaWE02WEZ3c0lIWmpiM1Z1ZENobktTd2dYRnhjWEc1Y1hDbGNibU5oZENoY1hFNTFiV0psY2lCdlppQmxaR2RsY3pwY1hDd2daV052ZFc1MEtHY3BMQ0JjWEZ4Y2JseGNLVnh1WTJGMEtGeGNUbVYwZDI5eWF5QmtaVzV6YVhSNU9seGNMQ0JsWkdkbFgyUmxibk5wZEhrb1p5a3NJRnhjWEZ4dVhGd3BYRzVqWVhRb1hGeEJkbVZ5WVdkbElIQmhkR2dnYkdWdVozUm9PbHhjTENCdFpXRnVYMlJwYzNSaGJtTmxLR2NwTENCY1hGeGNibHhjS1Z4dVkyRjBLRnhjUTJ4MWMzUmxjbWx1WnlCamIyVm1abWxqYVdWdWREcGNYQ3dnZEhKaGJuTnBkR2wyYVhSNUtHY3BMQ0JjWEZ4Y2JseGNLVnh1WEc0aklFVjRkSEpoWTNRZ1pXUm5aU0JwYm1admNtMWhkR2x2Ymx4dVpXUm5aWE5mWkdZZ1BDMGdaR0YwWVM1bWNtRnRaU2hjYmlBZ1puSnZiU0E5SUdWdVpITW9aeXdnUlNobktTbGJMREZkTEZ4dUlDQjBieUE5SUdWdVpITW9aeXdnUlNobktTbGJMREpkWEc0cFhHNWNiaU1nUVdSa0lHVmtaMlVnWVhSMGNtbGlkWFJsY3lCcFppQmhibmxjYm1Wa1oyVmZZWFIwY25NZ1BDMGdaV1JuWlY5aGRIUnlLR2NwWEc1bWIzSWdLR0YwZEhJZ2FXNGdibUZ0WlhNb1pXUm5aVjloZEhSeWN5a3BJSHRjYmlBZ1pXUm5aWE5mWkdaYlcyRjBkSEpkWFNBOExTQmxaR2RsWDJGMGRISnpXMXRoZEhSeVhWMWNibjFjYmx4dUl5QlRZWFpsSUhSb1pTQmxaR2RsY3lCa1lYUmhJR1p5WVcxbFhHNTNjbWwwWlM1amMzWW9aV1JuWlhOZlpHWXNJRnhjWjJWdVpWOXVaWFIzYjNKclgyVmtaMlZ6TG1OemRseGNMQ0J5YjNjdWJtRnRaWE1nUFNCR1FVeFRSU2xjYmx4dUl5QkZlSFJ5WVdOMElHNXZaR1VnYVc1bWIzSnRZWFJwYjI1Y2JtNXZaR1Z6WDJSbUlEd3RJR1JoZEdFdVpuSmhiV1VvWEc0Z0lHbGtJRDBnVmlobktTUnVZVzFsTEZ4dUlDQmtaV2R5WldVZ1BTQmtaV2R5WldVb1p5a3NYRzRnSUdKbGRIZGxaVzV1WlhOeklEMGdZbVYwZDJWbGJtNWxjM01vWnlsY2JpbGNibHh1SXlCQlpHUWdiM1JvWlhJZ2RtVnlkR1Y0SUdGMGRISnBZblYwWlhNZ2FXWWdZVzU1WEc1MlpYSjBaWGhmWVhSMGNuTWdQQzBnZG1WeWRHVjRYMkYwZEhJb1p5bGNibVp2Y2lBb1lYUjBjaUJwYmlCdVlXMWxjeWgyWlhKMFpYaGZZWFIwY25NcEtTQjdYRzRnSUdsbUlDaGhkSFJ5SUNFOUlGeGNibUZ0WlZ4Y0tTQjdJQ0FqSUZOcmFYQWdKMjVoYldVbklHRnpJSGRsSUdGc2NtVmhaSGtnYUdGMlpTQnBkQ0JoY3lBbmFXUW5YRzRnSUNBZ2JtOWtaWE5mWkdaYlcyRjBkSEpkWFNBOExTQjJaWEowWlhoZllYUjBjbk5iVzJGMGRISmRYVnh1SUNCOVhHNTlYRzVjYmlNZ1UyRjJaU0IwYUdVZ2JtOWtaWE1nWkdGMFlTQm1jbUZ0WlZ4dWQzSnBkR1V1WTNOMktHNXZaR1Z6WDJSbUxDQmNYR2RsYm1WZmJtVjBkMjl5YTE5dWIyUmxjeTVqYzNaY1hDd2djbTkzTG01aGJXVnpJRDBnUmtGTVUwVXBYRzVjYmlNZ1VISnBiblFnWVNCemRXMXRZWEo1SUc5bUlIUm9aU0J6WVhabFpDQmtZWFJoWEc1allYUW9YRnhUWVhabFpDQnVaWFIzYjNKcklHUmhkR0U2WEZ4dVhGd3BYRzVqWVhRb1hGeEZaR2RsY3lCbWFXeGxPaUJuWlc1bFgyNWxkSGR2Y210ZlpXUm5aWE11WTNOMklDMWNYQ3dnYm5KdmR5aGxaR2RsYzE5a1ppa3NJRnhjY205M2MxeGNibHhjS1Z4dVkyRjBLRnhjVG05a1pYTWdabWxzWlRvZ1oyVnVaVjl1WlhSM2IzSnJYMjV2WkdWekxtTnpkaUF0WEZ3c0lHNXliM2NvYm05a1pYTmZaR1lwTENCY1hISnZkM05jWEc1Y1hDbGNibUJnWUZ4dVlHQmdJbjA9IC0tPlxuXG5gYGByXG5gYGByXG4jIEZ1bmN0aW9uIHRvIGdldCB0b3AgZ2VuZXMgZnJvbSBhIGNvbXBhcmlzb25cblxubGlicmFyeShpZ3JhcGgpXG5saWJyYXJ5KFNUUklOR2RiKVxubGlicmFyeShnZ3JhcGgpXG5saWJyYXJ5KHRpZHl2ZXJzZSlcbmxpYnJhcnkodGliYmxlKVxuXG5nZXRfdG9wX2dlbmVzIDwtIGZ1bmN0aW9uKGNvbXBhcmlzb25fcmVzdWx0LCBuID0gNTApIHtcbiAgdG9wX2dlbmVzIDwtIGNvbXBhcmlzb25fcmVzdWx0ICU+JVxuICAgIHJvd25hbWVzX3RvX2NvbHVtbihcXGdlbmVcXCkgJT4lXG4gICAgYXJyYW5nZShkZXNjKGFicyhhdmdfbG9nMkZDKSkpICU+JVxuICAgIGhlYWQobikgJT4lXG4gICAgcHVsbChnZW5lKVxuICByZXR1cm4odG9wX2dlbmVzKVxufVxuXG4jIENvbWJpbmUgdG9wIGdlbmVzIGZyb20gYWxsIGNvbXBhcmlzb25zXG5hbGxfdG9wX2dlbmVzIDwtIHVuaXF1ZShjKFxuICBnZXRfdG9wX2dlbmVzKHAxX2NvbXBhcmlzb24pLFxuICBnZXRfdG9wX2dlbmVzKHAyX2NvbXBhcmlzb24pLFxuICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNiksXG4gIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNUw3KSxcbiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w2TDcpXG4pKVxuXG4jIEluaXRpYWxpemUgU1RSSU5HZGJcbnN0cmluZ19kYiA8LSBTVFJJTkdkYiRuZXcodmVyc2lvbj1cXDExXFwsIHNwZWNpZXM9OTYwNiwgc2NvcmVfdGhyZXNob2xkPTcwMClcblxuIyBNYXAgZ2VuZXMgdG8gU1RSSU5HIGlkZW50aWZpZXJzXG5tYXBwZWRfZ2VuZXMgPC0gc3RyaW5nX2RiJG1hcChkYXRhLmZyYW1lKGdlbmU9YWxsX3RvcF9nZW5lcyksIFxcZ2VuZVxcLCByZW1vdmVVbm1hcHBlZFJvd3MgPSBUUlVFKVxuXG4jIEdldCBpbnRlcmFjdGlvbnNcbmludGVyYWN0aW9ucyA8LSBzdHJpbmdfZGIkZ2V0X2ludGVyYWN0aW9ucyhtYXBwZWRfZ2VuZXMkU1RSSU5HX2lkKVxuXG4jIENyZWF0ZSBpZ3JhcGggb2JqZWN0XG5nIDwtIGdyYXBoX2Zyb21fZGF0YV9mcmFtZShpbnRlcmFjdGlvbnMsIGRpcmVjdGVkID0gRkFMU0UpXG5cbiMgQ2FsY3VsYXRlIG5vZGUgZGVncmVlc1xuVihnKSRkZWdyZWUgPC0gZGVncmVlKGcpXG5cbiMgQ2FsY3VsYXRlIGJldHdlZW5uZXNzIGNlbnRyYWxpdHlcblYoZykkYmV0d2Vlbm5lc3MgPC0gYmV0d2Vlbm5lc3MoZylcblxuIyBJZGVudGlmeSBjb21tdW5pdGllc1xuY29tbXVuaXRpZXMgPC0gY2x1c3Rlcl9sb3V2YWluKGcpXG5WKGcpJGNvbW11bml0eSA8LSBjb21tdW5pdGllcyRtZW1iZXJzaGlwXG5cbiMgUGxvdCB0aGUgbmV0d29ya1xuc2V0LnNlZWQoMTIzKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5XG5nZ3JhcGgoZywgbGF5b3V0ID0gXFxmclxcKSArXG4gIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gY29tYmluZWRfc2NvcmUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArXG4gIGdlb21fbm9kZV9wb2ludChhZXMoY29sb3IgPSBmYWN0b3IoY29tbXVuaXR5KSwgc2l6ZSA9IGRlZ3JlZSkpICtcbiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHJlcGVsID0gVFJVRSwgc2l6ZSA9IDMpICtcbiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSBcXFNldDFcXCkgK1xuICB0aGVtZV92b2lkKCkgK1xuICBsYWJzKHRpdGxlID0gXFxHZW5lIEludGVyYWN0aW9uIE5ldHdvcmtcXCxcbiAgICAgICBzdWJ0aXRsZSA9IFxcQmFzZWQgb24gdG9wIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lc1xcLFxuICAgICAgIGNvbG9yID0gXFxDb21tdW5pdHlcXCxcbiAgICAgICBzaXplID0gXFxEZWdyZWVcXClcblxuIyBTYXZlIHRoZSBwbG90XG5nZ3NhdmUoXFxnZW5lX2ludGVyYWN0aW9uX25ldHdvcmsucG5nXFwsIHdpZHRoID0gMTIsIGhlaWdodCA9IDEwLCBkcGkgPSAzMDApXG5cbiMgSWRlbnRpZnkgaHViIGdlbmVzXG5odWJfZ2VuZXMgPC0gVihnKSRuYW1lW29yZGVyKFYoZykkZGVncmVlLCBkZWNyZWFzaW5nID0gVFJVRSldWzE6MTBdXG5jYXQoXFxUb3AgMTAgaHViIGdlbmVzOlxcblxcKVxucHJpbnQoaHViX2dlbmVzKVxuXG4jIElkZW50aWZ5IGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5XG5oaWdoX2JldHdlZW5uZXNzX2dlbmVzIDwtIFYoZykkbmFtZVtvcmRlcihWKGcpJGJldHdlZW5uZXNzLCBkZWNyZWFzaW5nID0gVFJVRSldWzE6MTBdXG5jYXQoXFxcXG5Ub3AgMTAgZ2VuZXMgd2l0aCBoaWdoIGJldHdlZW5uZXNzIGNlbnRyYWxpdHk6XFxuXFwpXG5wcmludChoaWdoX2JldHdlZW5uZXNzX2dlbmVzKVxuXG4jIENhbGN1bGF0ZSBhbmQgcHJpbnQgc29tZSBuZXR3b3JrIHN0YXRpc3RpY3NcbmNhdChcXFxcbk5ldHdvcmsgU3RhdGlzdGljczpcXG5cXClcbmNhdChcXE51bWJlciBvZiBub2RlczpcXCwgdmNvdW50KGcpLCBcXFxcblxcKVxuY2F0KFxcTnVtYmVyIG9mIGVkZ2VzOlxcLCBlY291bnQoZyksIFxcXFxuXFwpXG5jYXQoXFxOZXR3b3JrIGRlbnNpdHk6XFwsIGVkZ2VfZGVuc2l0eShnKSwgXFxcXG5cXClcbmNhdChcXEF2ZXJhZ2UgcGF0aCBsZW5ndGg6XFwsIG1lYW5fZGlzdGFuY2UoZyksIFxcXFxuXFwpXG5jYXQoXFxDbHVzdGVyaW5nIGNvZWZmaWNpZW50OlxcLCB0cmFuc2l0aXZpdHkoZyksIFxcXFxuXFwpXG5cbiMgRXh0cmFjdCBlZGdlIGluZm9ybWF0aW9uXG5lZGdlc19kZiA8LSBkYXRhLmZyYW1lKFxuICBmcm9tID0gZW5kcyhnLCBFKGcpKVssMV0sXG4gIHRvID0gZW5kcyhnLCBFKGcpKVssMl1cbilcblxuIyBBZGQgZWRnZSBhdHRyaWJ1dGVzIGlmIGFueVxuZWRnZV9hdHRycyA8LSBlZGdlX2F0dHIoZylcbmZvciAoYXR0ciBpbiBuYW1lcyhlZGdlX2F0dHJzKSkge1xuICBlZGdlc19kZltbYXR0cl1dIDwtIGVkZ2VfYXR0cnNbW2F0dHJdXVxufVxuXG4jIFNhdmUgdGhlIGVkZ2VzIGRhdGEgZnJhbWVcbndyaXRlLmNzdihlZGdlc19kZiwgXFxnZW5lX25ldHdvcmtfZWRnZXMuY3N2XFwsIHJvdy5uYW1lcyA9IEZBTFNFKVxuXG4jIEV4dHJhY3Qgbm9kZSBpbmZvcm1hdGlvblxubm9kZXNfZGYgPC0gZGF0YS5mcmFtZShcbiAgaWQgPSBWKGcpJG5hbWUsXG4gIGRlZ3JlZSA9IGRlZ3JlZShnKSxcbiAgYmV0d2Vlbm5lc3MgPSBiZXR3ZWVubmVzcyhnKVxuKVxuXG4jIEFkZCBvdGhlciB2ZXJ0ZXggYXR0cmlidXRlcyBpZiBhbnlcbnZlcnRleF9hdHRycyA8LSB2ZXJ0ZXhfYXR0cihnKVxuZm9yIChhdHRyIGluIG5hbWVzKHZlcnRleF9hdHRycykpIHtcbiAgaWYgKGF0dHIgIT0gXFxuYW1lXFwpIHsgICMgU2tpcCAnbmFtZScgYXMgd2UgYWxyZWFkeSBoYXZlIGl0IGFzICdpZCdcbiAgICBub2Rlc19kZltbYXR0cl1dIDwtIHZlcnRleF9hdHRyc1tbYXR0cl1dXG4gIH1cbn1cblxuIyBTYXZlIHRoZSBub2RlcyBkYXRhIGZyYW1lXG53cml0ZS5jc3Yobm9kZXNfZGYsIFxcZ2VuZV9uZXR3b3JrX25vZGVzLmNzdlxcLCByb3cubmFtZXMgPSBGQUxTRSlcblxuIyBQcmludCBhIHN1bW1hcnkgb2YgdGhlIHNhdmVkIGRhdGFcbmNhdChcXFNhdmVkIG5ldHdvcmsgZGF0YTpcXG5cXClcbmNhdChcXEVkZ2VzIGZpbGU6IGdlbmVfbmV0d29ya19lZGdlcy5jc3YgLVxcLCBucm93KGVkZ2VzX2RmKSwgXFxyb3dzXFxuXFwpXG5jYXQoXFxOb2RlcyBmaWxlOiBnZW5lX25ldHdvcmtfbm9kZXMuY3N2IC1cXCwgbnJvdyhub2Rlc19kZiksIFxccm93c1xcblxcKVxuYGBgXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuIyBGdW5jdGlvbiB0byBnZXQgdG9wIGdlbmVzIGZyb20gYSBjb21wYXJpc29uXG5cbmxpYnJhcnkoaWdyYXBoKVxubGlicmFyeShTVFJJTkdkYilcbmxpYnJhcnkoZ2dyYXBoKVxubGlicmFyeSh0aWR5dmVyc2UpXG5saWJyYXJ5KHRpYmJsZSlcblxuZ2V0X3RvcF9nZW5lcyA8LSBmdW5jdGlvbihjb21wYXJpc29uX3Jlc3VsdCwgbiA9IDUwKSB7XG4gIHRvcF9nZW5lcyA8LSBjb21wYXJpc29uX3Jlc3VsdCAlPiVcbiAgICByb3duYW1lc190b19jb2x1bW4oXFxnZW5lXFwpICU+JVxuICAgIGFycmFuZ2UoZGVzYyhhYnMoYXZnX2xvZzJGQykpKSAlPiVcbiAgICBoZWFkKG4pICU+JVxuICAgIHB1bGwoZ2VuZSlcbiAgcmV0dXJuKHRvcF9nZW5lcylcbn1cblxuIyBDb21iaW5lIHRvcCBnZW5lcyBmcm9tIGFsbCBjb21wYXJpc29uc1xuYWxsX3RvcF9nZW5lcyA8LSB1bmlxdWUoYyhcbiAgZ2V0X3RvcF9nZW5lcyhwMV9jb21wYXJpc29uKSxcbiAgZ2V0X3RvcF9nZW5lcyhwMl9jb21wYXJpc29uKSxcbiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDYpLFxuICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNyksXG4gIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNkw3KVxuKSlcblxuIyBJbml0aWFsaXplIFNUUklOR2RiXG5zdHJpbmdfZGIgPC0gU1RSSU5HZGIkbmV3KHZlcnNpb249XFwxMVxcLCBzcGVjaWVzPTk2MDYsIHNjb3JlX3RocmVzaG9sZD03MDApXG5cbiMgTWFwIGdlbmVzIHRvIFNUUklORyBpZGVudGlmaWVyc1xubWFwcGVkX2dlbmVzIDwtIHN0cmluZ19kYiRtYXAoZGF0YS5mcmFtZShnZW5lPWFsbF90b3BfZ2VuZXMpLCBcXGdlbmVcXCwgcmVtb3ZlVW5tYXBwZWRSb3dzID0gVFJVRSlcblxuIyBHZXQgaW50ZXJhY3Rpb25zXG5pbnRlcmFjdGlvbnMgPC0gc3RyaW5nX2RiJGdldF9pbnRlcmFjdGlvbnMobWFwcGVkX2dlbmVzJFNUUklOR19pZClcblxuIyBDcmVhdGUgaWdyYXBoIG9iamVjdFxuZyA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoaW50ZXJhY3Rpb25zLCBkaXJlY3RlZCA9IEZBTFNFKVxuXG4jIENhbGN1bGF0ZSBub2RlIGRlZ3JlZXNcblYoZykkZGVncmVlIDwtIGRlZ3JlZShnKVxuXG4jIENhbGN1bGF0ZSBiZXR3ZWVubmVzcyBjZW50cmFsaXR5XG5WKGcpJGJldHdlZW5uZXNzIDwtIGJldHdlZW5uZXNzKGcpXG5cbiMgSWRlbnRpZnkgY29tbXVuaXRpZXNcbmNvbW11bml0aWVzIDwtIGNsdXN0ZXJfbG91dmFpbihnKVxuVihnKSRjb21tdW5pdHkgPC0gY29tbXVuaXRpZXMkbWVtYmVyc2hpcFxuXG4jIFBsb3QgdGhlIG5ldHdvcmtcbnNldC5zZWVkKDEyMykgICMgZm9yIHJlcHJvZHVjaWJpbGl0eVxuZ2dyYXBoKGcsIGxheW91dCA9IFxcZnJcXCkgK1xuICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IGNvbWJpbmVkX3Njb3JlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgK1xuICBnZW9tX25vZGVfcG9pbnQoYWVzKGNvbG9yID0gZmFjdG9yKGNvbW11bml0eSksIHNpemUgPSBkZWdyZWUpKSArXG4gIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUsIHNpemUgPSAzKSArXG4gIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gXFxTZXQxXFwpICtcbiAgdGhlbWVfdm9pZCgpICtcbiAgbGFicyh0aXRsZSA9IFxcR2VuZSBJbnRlcmFjdGlvbiBOZXR3b3JrXFwsXG4gICAgICAgc3VidGl0bGUgPSBcXEJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXNcXCxcbiAgICAgICBjb2xvciA9IFxcQ29tbXVuaXR5XFwsXG4gICAgICAgc2l6ZSA9IFxcRGVncmVlXFwpXG5cbiMgU2F2ZSB0aGUgcGxvdFxuZ2dzYXZlKFxcZ2VuZV9pbnRlcmFjdGlvbl9uZXR3b3JrLnBuZ1xcLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKVxuXG4jIElkZW50aWZ5IGh1YiBnZW5lc1xuaHViX2dlbmVzIDwtIFYoZykkbmFtZVtvcmRlcihWKGcpJGRlZ3JlZSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcVG9wIDEwIGh1YiBnZW5lczpcXG5cXClcbnByaW50KGh1Yl9nZW5lcylcblxuIyBJZGVudGlmeSBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eVxuaGlnaF9iZXR3ZWVubmVzc19nZW5lcyA8LSBWKGcpJG5hbWVbb3JkZXIoVihnKSRiZXR3ZWVubmVzcywgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcXFxuVG9wIDEwIGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5OlxcblxcKVxucHJpbnQoaGlnaF9iZXR3ZWVubmVzc19nZW5lcylcblxuIyBDYWxjdWxhdGUgYW5kIHByaW50IHNvbWUgbmV0d29yayBzdGF0aXN0aWNzXG5jYXQoXFxcXG5OZXR3b3JrIFN0YXRpc3RpY3M6XFxuXFwpXG5jYXQoXFxOdW1iZXIgb2Ygbm9kZXM6XFwsIHZjb3VudChnKSwgXFxcXG5cXClcbmNhdChcXE51bWJlciBvZiBlZGdlczpcXCwgZWNvdW50KGcpLCBcXFxcblxcKVxuY2F0KFxcTmV0d29yayBkZW5zaXR5OlxcLCBlZGdlX2RlbnNpdHkoZyksIFxcXFxuXFwpXG5jYXQoXFxBdmVyYWdlIHBhdGggbGVuZ3RoOlxcLCBtZWFuX2Rpc3RhbmNlKGcpLCBcXFxcblxcKVxuY2F0KFxcQ2x1c3RlcmluZyBjb2VmZmljaWVudDpcXCwgdHJhbnNpdGl2aXR5KGcpLCBcXFxcblxcKVxuXG4jIEV4dHJhY3QgZWRnZSBpbmZvcm1hdGlvblxuZWRnZXNfZGYgPC0gZGF0YS5mcmFtZShcbiAgZnJvbSA9IGVuZHMoZywgRShnKSlbLDFdLFxuICB0byA9IGVuZHMoZywgRShnKSlbLDJdXG4pXG5cbiMgQWRkIGVkZ2UgYXR0cmlidXRlcyBpZiBhbnlcbmVkZ2VfYXR0cnMgPC0gZWRnZV9hdHRyKGcpXG5mb3IgKGF0dHIgaW4gbmFtZXMoZWRnZV9hdHRycykpIHtcbiAgZWRnZXNfZGZbW2F0dHJdXSA8LSBlZGdlX2F0dHJzW1thdHRyXV1cbn1cblxuIyBTYXZlIHRoZSBlZGdlcyBkYXRhIGZyYW1lXG53cml0ZS5jc3YoZWRnZXNfZGYsIFxcZ2VuZV9uZXR3b3JrX2VkZ2VzLmNzdlxcLCByb3cubmFtZXMgPSBGQUxTRSlcblxuIyBFeHRyYWN0IG5vZGUgaW5mb3JtYXRpb25cbm5vZGVzX2RmIDwtIGRhdGEuZnJhbWUoXG4gIGlkID0gVihnKSRuYW1lLFxuICBkZWdyZWUgPSBkZWdyZWUoZyksXG4gIGJldHdlZW5uZXNzID0gYmV0d2Vlbm5lc3MoZylcbilcblxuIyBBZGQgb3RoZXIgdmVydGV4IGF0dHJpYnV0ZXMgaWYgYW55XG52ZXJ0ZXhfYXR0cnMgPC0gdmVydGV4X2F0dHIoZylcbmZvciAoYXR0ciBpbiBuYW1lcyh2ZXJ0ZXhfYXR0cnMpKSB7XG4gIGlmIChhdHRyICE9IFxcbmFtZVxcKSB7ICAjIFNraXAgJ25hbWUnIGFzIHdlIGFscmVhZHkgaGF2ZSBpdCBhcyAnaWQnXG4gICAgbm9kZXNfZGZbW2F0dHJdXSA8LSB2ZXJ0ZXhfYXR0cnNbW2F0dHJdXVxuICB9XG59XG5cbiMgU2F2ZSB0aGUgbm9kZXMgZGF0YSBmcmFtZVxud3JpdGUuY3N2KG5vZGVzX2RmLCBcXGdlbmVfbmV0d29ya19ub2Rlcy5jc3ZcXCwgcm93Lm5hbWVzID0gRkFMU0UpXG5cbiMgUHJpbnQgYSBzdW1tYXJ5IG9mIHRoZSBzYXZlZCBkYXRhXG5jYXQoXFxTYXZlZCBuZXR3b3JrIGRhdGE6XFxuXFwpXG5jYXQoXFxFZGdlcyBmaWxlOiBnZW5lX25ldHdvcmtfZWRnZXMuY3N2IC1cXCwgbnJvdyhlZGdlc19kZiksIFxccm93c1xcblxcKVxuY2F0KFxcTm9kZXMgZmlsZTogZ2VuZV9uZXR3b3JrX25vZGVzLmNzdiAtXFwsIG5yb3cobm9kZXNfZGYpLCBcXHJvd3NcXG5cXClcbmBgYFxuYGBgIn0= -->
```r
```r
# Function to get top genes from a comparison
library(igraph)
library(STRINGdb)
library(ggraph)
library(tidyverse)
library(tibble)
get_top_genes <- function(comparison_result, n = 50) {
top_genes <- comparison_result %>%
rownames_to_column(\gene\) %>%
arrange(desc(abs(avg_log2FC))) %>%
head(n) %>%
pull(gene)
return(top_genes)
}
# Combine top genes from all comparisons
all_top_genes <- unique(c(
get_top_genes(p1_comparison),
get_top_genes(p2_comparison),
get_top_genes(p3_comparison_L5L6),
get_top_genes(p3_comparison_L5L7),
get_top_genes(p3_comparison_L6L7)
))
# Initialize STRINGdb
string_db <- STRINGdb$new(version=\11\, species=9606, score_threshold=700)
# Map genes to STRING identifiers
mapped_genes <- string_db$map(data.frame(gene=all_top_genes), \gene\, removeUnmappedRows = TRUE)
# Get interactions
interactions <- string_db$get_interactions(mapped_genes$STRING_id)
# Create igraph object
g <- graph_from_data_frame(interactions, directed = FALSE)
# Calculate node degrees
V(g)$degree <- degree(g)
# Calculate betweenness centrality
V(g)$betweenness <- betweenness(g)
# Identify communities
communities <- cluster_louvain(g)
V(g)$community <- communities$membership
# Plot the network
set.seed(123) # for reproducibility
ggraph(g, layout = \fr\) +
geom_edge_link(aes(edge_alpha = combined_score), show.legend = FALSE) +
geom_node_point(aes(color = factor(community), size = degree)) +
geom_node_text(aes(label = name), repel = TRUE, size = 3) +
scale_color_brewer(palette = \Set1\) +
theme_void() +
labs(title = \Gene Interaction Network\,
subtitle = \Based on top differentially expressed genes\,
color = \Community\,
size = \Degree\)
# Save the plot
ggsave(\gene_interaction_network.png\, width = 12, height = 10, dpi = 300)
# Identify hub genes
hub_genes <- V(g)$name[order(V(g)$degree, decreasing = TRUE)][1:10]
cat(\Top 10 hub genes:\n\)
print(hub_genes)
# Identify genes with high betweenness centrality
high_betweenness_genes <- V(g)$name[order(V(g)$betweenness, decreasing = TRUE)][1:10]
cat(\\nTop 10 genes with high betweenness centrality:\n\)
print(high_betweenness_genes)
# Calculate and print some network statistics
cat(\\nNetwork Statistics:\n\)
cat(\Number of nodes:\, vcount(g), \\n\)
cat(\Number of edges:\, ecount(g), \\n\)
cat(\Network density:\, edge_density(g), \\n\)
cat(\Average path length:\, mean_distance(g), \\n\)
cat(\Clustering coefficient:\, transitivity(g), \\n\)
# Extract edge information
edges_df <- data.frame(
from = ends(g, E(g))[,1],
to = ends(g, E(g))[,2]
)
# Add edge attributes if any
edge_attrs <- edge_attr(g)
for (attr in names(edge_attrs)) {
edges_df[[attr]] <- edge_attrs[[attr]]
}
# Save the edges data frame
write.csv(edges_df, \gene_network_edges.csv\, row.names = FALSE)
# Extract node information
nodes_df <- data.frame(
id = V(g)$name,
degree = degree(g),
betweenness = betweenness(g)
)
# Add other vertex attributes if any
vertex_attrs <- vertex_attr(g)
for (attr in names(vertex_attrs)) {
if (attr != \name\) { # Skip 'name' as we already have it as 'id'
nodes_df[[attr]] <- vertex_attrs[[attr]]
}
}
# Save the nodes data frame
write.csv(nodes_df, \gene_network_nodes.csv\, row.names = FALSE)
# Print a summary of the saved data
cat(\Saved network data:\n\)
cat(\Edges file: gene_network_edges.csv -\, nrow(edges_df), \rows\n\)
cat(\Nodes file: gene_network_nodes.csv -\, nrow(nodes_df), \rows\n\)
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dUl5QkdkVzVqZEdsdmJpQjBieUJuWlhRZ2RHOXdJR2RsYm1WeklHWnliMjBnWVNCamIyMXdZWEpwYzI5dVhHNWNibXhwWW5KaGNua29hV2R5WVhCb0tWeHViR2xpY21GeWVTaFRWRkpKVGtka1lpbGNibXhwWW5KaGNua29aMmR5WVhCb0tWeHViR2xpY21GeWVTaDBhV1I1ZG1WeWMyVXBYRzVzYVdKeVlYSjVLSFJwWW1Kc1pTbGNibHh1WjJWMFgzUnZjRjluWlc1bGN5QThMU0JtZFc1amRHbHZiaWhqYjIxd1lYSnBjMjl1WDNKbGMzVnNkQ3dnYmlBOUlEVXdLU0I3WEc0Z0lIUnZjRjluWlc1bGN5QThMU0JqYjIxd1lYSnBjMjl1WDNKbGMzVnNkQ0FsUGlWY2JpQWdJQ0J5YjNkdVlXMWxjMTkwYjE5amIyeDFiVzRvWEZ4blpXNWxYRndwSUNVK0pWeHVJQ0FnSUdGeWNtRnVaMlVvWkdWell5aGhZbk1vWVhablgyeHZaekpHUXlrcEtTQWxQaVZjYmlBZ0lDQm9aV0ZrS0c0cElDVStKVnh1SUNBZ0lIQjFiR3dvWjJWdVpTbGNiaUFnY21WMGRYSnVLSFJ2Y0Y5blpXNWxjeWxjYm4xY2JseHVJeUJEYjIxaWFXNWxJSFJ2Y0NCblpXNWxjeUJtY205dElHRnNiQ0JqYjIxd1lYSnBjMjl1YzF4dVlXeHNYM1J2Y0Y5blpXNWxjeUE4TFNCMWJtbHhkV1VvWXloY2JpQWdaMlYwWDNSdmNGOW5aVzVsY3lod01WOWpiMjF3WVhKcGMyOXVLU3hjYmlBZ1oyVjBYM1J2Y0Y5blpXNWxjeWh3TWw5amIyMXdZWEpwYzI5dUtTeGNiaUFnWjJWMFgzUnZjRjluWlc1bGN5aHdNMTlqYjIxd1lYSnBjMjl1WDB3MVREWXBMRnh1SUNCblpYUmZkRzl3WDJkbGJtVnpLSEF6WDJOdmJYQmhjbWx6YjI1ZlREVk1OeWtzWEc0Z0lHZGxkRjkwYjNCZloyVnVaWE1vY0ROZlkyOXRjR0Z5YVhOdmJsOU1Oa3czS1Z4dUtTbGNibHh1SXlCSmJtbDBhV0ZzYVhwbElGTlVVa2xPUjJSaVhHNXpkSEpwYm1kZlpHSWdQQzBnVTFSU1NVNUhaR0lrYm1WM0tIWmxjbk5wYjI0OVhGd3hNVnhjTENCemNHVmphV1Z6UFRrMk1EWXNJSE5qYjNKbFgzUm9jbVZ6YUc5c1pEMDNNREFwWEc1Y2JpTWdUV0Z3SUdkbGJtVnpJSFJ2SUZOVVVrbE9SeUJwWkdWdWRHbG1hV1Z5YzF4dWJXRndjR1ZrWDJkbGJtVnpJRHd0SUhOMGNtbHVaMTlrWWlSdFlYQW9aR0YwWVM1bWNtRnRaU2huWlc1bFBXRnNiRjkwYjNCZloyVnVaWE1wTENCY1hHZGxibVZjWEN3Z2NtVnRiM1psVlc1dFlYQndaV1JTYjNkeklEMGdWRkpWUlNsY2JseHVJeUJIWlhRZ2FXNTBaWEpoWTNScGIyNXpYRzVwYm5SbGNtRmpkR2x2Ym5NZ1BDMGdjM1J5YVc1blgyUmlKR2RsZEY5cGJuUmxjbUZqZEdsdmJuTW9iV0Z3Y0dWa1gyZGxibVZ6SkZOVVVrbE9SMTlwWkNsY2JseHVJeUJOWVhBZ1UxUlNTVTVISUdsa1pXNTBhV1pwWlhKeklHSmhZMnNnZEc4Z1oyVnVaU0J6ZVcxaWIyeHpYRzVwYm5SbGNtRmpkR2x2Ym5Na1puSnZiU0E4TFNCdFlYQndaV1JmWjJWdVpYTWtaMlZ1WlZ0dFlYUmphQ2hwYm5SbGNtRmpkR2x2Ym5Na1puSnZiU3dnYldGd2NHVmtYMmRsYm1WekpGTlVVa2xPUjE5cFpDbGRYRzVwYm5SbGNtRmpkR2x2Ym5Na2RHOGdQQzBnYldGd2NHVmtYMmRsYm1WekpHZGxibVZiYldGMFkyZ29hVzUwWlhKaFkzUnBiMjV6SkhSdkxDQnRZWEJ3WldSZloyVnVaWE1rVTFSU1NVNUhYMmxrS1YxY2JseHVJeUJEY21WaGRHVWdhV2R5WVhCb0lHOWlhbVZqZEZ4dVp5QThMU0JuY21Gd2FGOW1jbTl0WDJSaGRHRmZabkpoYldVb2FXNTBaWEpoWTNScGIyNXpMQ0JrYVhKbFkzUmxaQ0E5SUVaQlRGTkZLVnh1WEc0aklFTmhiR04xYkdGMFpTQnViMlJsSUdSbFozSmxaWE5jYmxZb1p5a2taR1ZuY21WbElEd3RJR1JsWjNKbFpTaG5LVnh1WEc0aklFTmhiR04xYkdGMFpTQmlaWFIzWldWdWJtVnpjeUJqWlc1MGNtRnNhWFI1WEc1V0tHY3BKR0psZEhkbFpXNXVaWE56SUR3dElHSmxkSGRsWlc1dVpYTnpLR2NwWEc1Y2JpTWdTV1JsYm5ScFpua2dZMjl0YlhWdWFYUnBaWE5jYm1OdmJXMTFibWwwYVdWeklEd3RJR05zZFhOMFpYSmZiRzkxZG1GcGJpaG5LVnh1VmlobktTUmpiMjF0ZFc1cGRIa2dQQzBnWTI5dGJYVnVhWFJwWlhNa2JXVnRZbVZ5YzJocGNGeHVYRzRqSUZCc2IzUWdkR2hsSUc1bGRIZHZjbXRjYm5ObGRDNXpaV1ZrS0RFeU15a2dJQ01nWm05eUlISmxjSEp2WkhWamFXSnBiR2wwZVZ4dVoyZHlZWEJvS0djc0lHeGhlVzkxZENBOUlGeGNabkpjWENrZ0sxeHVJQ0JuWlc5dFgyVmtaMlZmYkdsdWF5aGhaWE1vWldSblpWOWhiSEJvWVNBOUlHTnZiV0pwYm1Wa1gzTmpiM0psS1N3Z2MyaHZkeTVzWldkbGJtUWdQU0JHUVV4VFJTa2dLMXh1SUNCblpXOXRYMjV2WkdWZmNHOXBiblFvWVdWektHTnZiRzl5SUQwZ1ptRmpkRzl5S0dOdmJXMTFibWwwZVNrc0lITnBlbVVnUFNCa1pXZHlaV1VwS1NBclhHNGdJR2RsYjIxZmJtOWtaVjkwWlhoMEtHRmxjeWhzWVdKbGJDQTlJRzVoYldVcExDQnlaWEJsYkNBOUlGUlNWVVVzSUhOcGVtVWdQU0F6S1NBclhHNGdJSE5qWVd4bFgyTnZiRzl5WDJKeVpYZGxjaWh3WVd4bGRIUmxJRDBnWEZ4VFpYUXhYRndwSUN0Y2JpQWdkR2hsYldWZmRtOXBaQ2dwSUN0Y2JpQWdiR0ZpY3loMGFYUnNaU0E5SUZ4Y1IyVnVaU0JKYm5SbGNtRmpkR2x2YmlCT1pYUjNiM0pyWEZ3c1hHNGdJQ0FnSUNBZ2MzVmlkR2wwYkdVZ1BTQmNYRUpoYzJWa0lHOXVJSFJ2Y0NCa2FXWm1aWEpsYm5ScFlXeHNlU0JsZUhCeVpYTnpaV1FnWjJWdVpYTmNYQ3hjYmlBZ0lDQWdJQ0JqYjJ4dmNpQTlJRnhjUTI5dGJYVnVhWFI1WEZ3c1hHNGdJQ0FnSUNBZ2MybDZaU0E5SUZ4Y1JHVm5jbVZsWEZ3cFhHNWNiaU1nVTJGMlpTQjBhR1VnY0d4dmRGeHVaMmR6WVhabEtGeGNaMlZ1WlY5cGJuUmxjbUZqZEdsdmJsOXVaWFIzYjNKckxuQnVaMXhjTENCM2FXUjBhQ0E5SURFeUxDQm9aV2xuYUhRZ1BTQXhNQ3dnWkhCcElEMGdNekF3S1Z4dVhHNGpJRWxrWlc1MGFXWjVJR2gxWWlCblpXNWxjMXh1YUhWaVgyZGxibVZ6SUR3dElGWW9aeWtrYm1GdFpWdHZjbVJsY2loV0tHY3BKR1JsWjNKbFpTd2daR1ZqY21WaGMybHVaeUE5SUZSU1ZVVXBYVnN4T2pFd1hWeHVZMkYwS0Z4Y1ZHOXdJREV3SUdoMVlpQm5aVzVsY3pwY1hHNWNYQ2xjYm5CeWFXNTBLR2gxWWw5blpXNWxjeWxjYmx4dUl5QkpaR1Z1ZEdsbWVTQm5aVzVsY3lCM2FYUm9JR2hwWjJnZ1ltVjBkMlZsYm01bGMzTWdZMlZ1ZEhKaGJHbDBlVnh1YUdsbmFGOWlaWFIzWldWdWJtVnpjMTluWlc1bGN5QThMU0JXS0djcEpHNWhiV1ZiYjNKa1pYSW9WaWhuS1NSaVpYUjNaV1Z1Ym1WemN5d2daR1ZqY21WaGMybHVaeUE5SUZSU1ZVVXBYVnN4T2pFd1hWeHVZMkYwS0Z4Y1hGeHVWRzl3SURFd0lHZGxibVZ6SUhkcGRHZ2dhR2xuYUNCaVpYUjNaV1Z1Ym1WemN5QmpaVzUwY21Gc2FYUjVPbHhjYmx4Y0tWeHVjSEpwYm5Rb2FHbG5hRjlpWlhSM1pXVnVibVZ6YzE5blpXNWxjeWxjYmx4dUl5QkRZV3hqZFd4aGRHVWdZVzVrSUhCeWFXNTBJSE52YldVZ2JtVjBkMjl5YXlCemRHRjBhWE4wYVdOelhHNWpZWFFvWEZ4Y1hHNU9aWFIzYjNKcklGTjBZWFJwYzNScFkzTTZYRnh1WEZ3cFhHNWpZWFFvWEZ4T2RXMWlaWElnYjJZZ2JtOWtaWE02WEZ3c0lIWmpiM1Z1ZENobktTd2dYRnhjWEc1Y1hDbGNibU5oZENoY1hFNTFiV0psY2lCdlppQmxaR2RsY3pwY1hDd2daV052ZFc1MEtHY3BMQ0JjWEZ4Y2JseGNLVnh1WTJGMEtGeGNUbVYwZDI5eWF5QmtaVzV6YVhSNU9seGNMQ0JsWkdkbFgyUmxibk5wZEhrb1p5a3NJRnhjWEZ4dVhGd3BYRzVqWVhRb1hGeEJkbVZ5WVdkbElIQmhkR2dnYkdWdVozUm9PbHhjTENCdFpXRnVYMlJwYzNSaGJtTmxLR2NwTENCY1hGeGNibHhjS1Z4dVkyRjBLRnhjUTJ4MWMzUmxjbWx1WnlCamIyVm1abWxqYVdWdWREcGNYQ3dnZEhKaGJuTnBkR2wyYVhSNUtHY3BMQ0JjWEZ4Y2JseGNLVnh1WEc0aklFVjRkSEpoWTNRZ1pXUm5aU0JwYm1admNtMWhkR2x2Ymx4dVpXUm5aWE5mWkdZZ1BDMGdaR0YwWVM1bWNtRnRaU2hjYmlBZ1puSnZiU0E5SUdWdVpITW9aeXdnUlNobktTbGJMREZkTEZ4dUlDQjBieUE5SUdWdVpITW9aeXdnUlNobktTbGJMREpkWEc0cFhHNWNiaU1nUVdSa0lHVmtaMlVnWVhSMGNtbGlkWFJsY3lCcFppQmhibmxjYm1Wa1oyVmZZWFIwY25NZ1BDMGdaV1JuWlY5aGRIUnlLR2NwWEc1bWIzSWdLR0YwZEhJZ2FXNGdibUZ0WlhNb1pXUm5aVjloZEhSeWN5a3BJSHRjYmlBZ1pXUm5aWE5mWkdaYlcyRjBkSEpkWFNBOExTQmxaR2RsWDJGMGRISnpXMXRoZEhSeVhWMWNibjFjYmx4dUl5QlRZWFpsSUhSb1pTQmxaR2RsY3lCa1lYUmhJR1p5WVcxbFhHNTNjbWwwWlM1amMzWW9aV1JuWlhOZlpHWXNJRnhjWjJWdVpWOXVaWFIzYjNKclgyVmtaMlZ6TG1OemRseGNMQ0J5YjNjdWJtRnRaWE1nUFNCR1FVeFRSU2xjYmx4dUl5QkZlSFJ5WVdOMElHNXZaR1VnYVc1bWIzSnRZWFJwYjI1Y2JtNXZaR1Z6WDJSbUlEd3RJR1JoZEdFdVpuSmhiV1VvWEc0Z0lHbGtJRDBnVmlobktTUnVZVzFsTEZ4dUlDQmtaV2R5WldVZ1BTQmtaV2R5WldVb1p5a3NYRzRnSUdKbGRIZGxaVzV1WlhOeklEMGdZbVYwZDJWbGJtNWxjM01vWnlsY2JpbGNibHh1SXlCQlpHUWdiM1JvWlhJZ2RtVnlkR1Y0SUdGMGRISnBZblYwWlhNZ2FXWWdZVzU1WEc1MlpYSjBaWGhmWVhSMGNuTWdQQzBnZG1WeWRHVjRYMkYwZEhJb1p5bGNibVp2Y2lBb1lYUjBjaUJwYmlCdVlXMWxjeWgyWlhKMFpYaGZZWFIwY25NcEtTQjdYRzRnSUdsbUlDaGhkSFJ5SUNFOUlGeGNibUZ0WlZ4Y0tTQjdJQ0FqSUZOcmFYQWdKMjVoYldVbklHRnpJSGRsSUdGc2NtVmhaSGtnYUdGMlpTQnBkQ0JoY3lBbmFXUW5YRzRnSUNBZ2JtOWtaWE5mWkdaYlcyRjBkSEpkWFNBOExTQjJaWEowWlhoZllYUjBjbk5iVzJGMGRISmRYVnh1SUNCOVhHNTlYRzVjYmlNZ1UyRjJaU0IwYUdVZ2JtOWtaWE1nWkdGMFlTQm1jbUZ0WlZ4dWQzSnBkR1V1WTNOMktHNXZaR1Z6WDJSbUxDQmNYR2RsYm1WZmJtVjBkMjl5YTE5dWIyUmxjeTVqYzNaY1hDd2djbTkzTG01aGJXVnpJRDBnUmtGTVUwVXBYRzVjYmlNZ1VISnBiblFnWVNCemRXMXRZWEo1SUc5bUlIUm9aU0J6WVhabFpDQmtZWFJoWEc1allYUW9YRnhUWVhabFpDQnVaWFIzYjNKcklHUmhkR0U2WEZ4dVhGd3BYRzVqWVhRb1hGeEZaR2RsY3lCbWFXeGxPaUJuWlc1bFgyNWxkSGR2Y210ZlpXUm5aWE11WTNOMklDMWNYQ3dnYm5KdmR5aGxaR2RsYzE5a1ppa3NJRnhjY205M2MxeGNibHhjS1Z4dVkyRjBLRnhjVG05a1pYTWdabWxzWlRvZ1oyVnVaVjl1WlhSM2IzSnJYMjV2WkdWekxtTnpkaUF0WEZ3c0lHNXliM2NvYm05a1pYTmZaR1lwTENCY1hISnZkM05jWEc1Y1hDbGNibHh1WUdCZ1hHNWdZR0FpZlE9PSAtLT5cblxuYGBgclxuYGBgclxuIyBGdW5jdGlvbiB0byBnZXQgdG9wIGdlbmVzIGZyb20gYSBjb21wYXJpc29uXG5cbmxpYnJhcnkoaWdyYXBoKVxubGlicmFyeShTVFJJTkdkYilcbmxpYnJhcnkoZ2dyYXBoKVxubGlicmFyeSh0aWR5dmVyc2UpXG5saWJyYXJ5KHRpYmJsZSlcblxuZ2V0X3RvcF9nZW5lcyA8LSBmdW5jdGlvbihjb21wYXJpc29uX3Jlc3VsdCwgbiA9IDUwKSB7XG4gIHRvcF9nZW5lcyA8LSBjb21wYXJpc29uX3Jlc3VsdCAlPiVcbiAgICByb3duYW1lc190b19jb2x1bW4oXFxnZW5lXFwpICU+JVxuICAgIGFycmFuZ2UoZGVzYyhhYnMoYXZnX2xvZzJGQykpKSAlPiVcbiAgICBoZWFkKG4pICU+JVxuICAgIHB1bGwoZ2VuZSlcbiAgcmV0dXJuKHRvcF9nZW5lcylcbn1cblxuIyBDb21iaW5lIHRvcCBnZW5lcyBmcm9tIGFsbCBjb21wYXJpc29uc1xuYWxsX3RvcF9nZW5lcyA8LSB1bmlxdWUoYyhcbiAgZ2V0X3RvcF9nZW5lcyhwMV9jb21wYXJpc29uKSxcbiAgZ2V0X3RvcF9nZW5lcyhwMl9jb21wYXJpc29uKSxcbiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDYpLFxuICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNyksXG4gIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNkw3KVxuKSlcblxuIyBJbml0aWFsaXplIFNUUklOR2RiXG5zdHJpbmdfZGIgPC0gU1RSSU5HZGIkbmV3KHZlcnNpb249XFwxMVxcLCBzcGVjaWVzPTk2MDYsIHNjb3JlX3RocmVzaG9sZD03MDApXG5cbiMgTWFwIGdlbmVzIHRvIFNUUklORyBpZGVudGlmaWVyc1xubWFwcGVkX2dlbmVzIDwtIHN0cmluZ19kYiRtYXAoZGF0YS5mcmFtZShnZW5lPWFsbF90b3BfZ2VuZXMpLCBcXGdlbmVcXCwgcmVtb3ZlVW5tYXBwZWRSb3dzID0gVFJVRSlcblxuIyBHZXQgaW50ZXJhY3Rpb25zXG5pbnRlcmFjdGlvbnMgPC0gc3RyaW5nX2RiJGdldF9pbnRlcmFjdGlvbnMobWFwcGVkX2dlbmVzJFNUUklOR19pZClcblxuIyBNYXAgU1RSSU5HIGlkZW50aWZpZXJzIGJhY2sgdG8gZ2VuZSBzeW1ib2xzXG5pbnRlcmFjdGlvbnMkZnJvbSA8LSBtYXBwZWRfZ2VuZXMkZ2VuZVttYXRjaChpbnRlcmFjdGlvbnMkZnJvbSwgbWFwcGVkX2dlbmVzJFNUUklOR19pZCldXG5pbnRlcmFjdGlvbnMkdG8gPC0gbWFwcGVkX2dlbmVzJGdlbmVbbWF0Y2goaW50ZXJhY3Rpb25zJHRvLCBtYXBwZWRfZ2VuZXMkU1RSSU5HX2lkKV1cblxuIyBDcmVhdGUgaWdyYXBoIG9iamVjdFxuZyA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoaW50ZXJhY3Rpb25zLCBkaXJlY3RlZCA9IEZBTFNFKVxuXG4jIENhbGN1bGF0ZSBub2RlIGRlZ3JlZXNcblYoZykkZGVncmVlIDwtIGRlZ3JlZShnKVxuXG4jIENhbGN1bGF0ZSBiZXR3ZWVubmVzcyBjZW50cmFsaXR5XG5WKGcpJGJldHdlZW5uZXNzIDwtIGJldHdlZW5uZXNzKGcpXG5cbiMgSWRlbnRpZnkgY29tbXVuaXRpZXNcbmNvbW11bml0aWVzIDwtIGNsdXN0ZXJfbG91dmFpbihnKVxuVihnKSRjb21tdW5pdHkgPC0gY29tbXVuaXRpZXMkbWVtYmVyc2hpcFxuXG4jIFBsb3QgdGhlIG5ldHdvcmtcbnNldC5zZWVkKDEyMykgICMgZm9yIHJlcHJvZHVjaWJpbGl0eVxuZ2dyYXBoKGcsIGxheW91dCA9IFxcZnJcXCkgK1xuICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IGNvbWJpbmVkX3Njb3JlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgK1xuICBnZW9tX25vZGVfcG9pbnQoYWVzKGNvbG9yID0gZmFjdG9yKGNvbW11bml0eSksIHNpemUgPSBkZWdyZWUpKSArXG4gIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUsIHNpemUgPSAzKSArXG4gIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gXFxTZXQxXFwpICtcbiAgdGhlbWVfdm9pZCgpICtcbiAgbGFicyh0aXRsZSA9IFxcR2VuZSBJbnRlcmFjdGlvbiBOZXR3b3JrXFwsXG4gICAgICAgc3VidGl0bGUgPSBcXEJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXNcXCxcbiAgICAgICBjb2xvciA9IFxcQ29tbXVuaXR5XFwsXG4gICAgICAgc2l6ZSA9IFxcRGVncmVlXFwpXG5cbiMgU2F2ZSB0aGUgcGxvdFxuZ2dzYXZlKFxcZ2VuZV9pbnRlcmFjdGlvbl9uZXR3b3JrLnBuZ1xcLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKVxuXG4jIElkZW50aWZ5IGh1YiBnZW5lc1xuaHViX2dlbmVzIDwtIFYoZykkbmFtZVtvcmRlcihWKGcpJGRlZ3JlZSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcVG9wIDEwIGh1YiBnZW5lczpcXG5cXClcbnByaW50KGh1Yl9nZW5lcylcblxuIyBJZGVudGlmeSBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eVxuaGlnaF9iZXR3ZWVubmVzc19nZW5lcyA8LSBWKGcpJG5hbWVbb3JkZXIoVihnKSRiZXR3ZWVubmVzcywgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcXFxuVG9wIDEwIGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5OlxcblxcKVxucHJpbnQoaGlnaF9iZXR3ZWVubmVzc19nZW5lcylcblxuIyBDYWxjdWxhdGUgYW5kIHByaW50IHNvbWUgbmV0d29yayBzdGF0aXN0aWNzXG5jYXQoXFxcXG5OZXR3b3JrIFN0YXRpc3RpY3M6XFxuXFwpXG5jYXQoXFxOdW1iZXIgb2Ygbm9kZXM6XFwsIHZjb3VudChnKSwgXFxcXG5cXClcbmNhdChcXE51bWJlciBvZiBlZGdlczpcXCwgZWNvdW50KGcpLCBcXFxcblxcKVxuY2F0KFxcTmV0d29yayBkZW5zaXR5OlxcLCBlZGdlX2RlbnNpdHkoZyksIFxcXFxuXFwpXG5jYXQoXFxBdmVyYWdlIHBhdGggbGVuZ3RoOlxcLCBtZWFuX2Rpc3RhbmNlKGcpLCBcXFxcblxcKVxuY2F0KFxcQ2x1c3RlcmluZyBjb2VmZmljaWVudDpcXCwgdHJhbnNpdGl2aXR5KGcpLCBcXFxcblxcKVxuXG4jIEV4dHJhY3QgZWRnZSBpbmZvcm1hdGlvblxuZWRnZXNfZGYgPC0gZGF0YS5mcmFtZShcbiAgZnJvbSA9IGVuZHMoZywgRShnKSlbLDFdLFxuICB0byA9IGVuZHMoZywgRShnKSlbLDJdXG4pXG5cbiMgQWRkIGVkZ2UgYXR0cmlidXRlcyBpZiBhbnlcbmVkZ2VfYXR0cnMgPC0gZWRnZV9hdHRyKGcpXG5mb3IgKGF0dHIgaW4gbmFtZXMoZWRnZV9hdHRycykpIHtcbiAgZWRnZXNfZGZbW2F0dHJdXSA8LSBlZGdlX2F0dHJzW1thdHRyXV1cbn1cblxuIyBTYXZlIHRoZSBlZGdlcyBkYXRhIGZyYW1lXG53cml0ZS5jc3YoZWRnZXNfZGYsIFxcZ2VuZV9uZXR3b3JrX2VkZ2VzLmNzdlxcLCByb3cubmFtZXMgPSBGQUxTRSlcblxuIyBFeHRyYWN0IG5vZGUgaW5mb3JtYXRpb25cbm5vZGVzX2RmIDwtIGRhdGEuZnJhbWUoXG4gIGlkID0gVihnKSRuYW1lLFxuICBkZWdyZWUgPSBkZWdyZWUoZyksXG4gIGJldHdlZW5uZXNzID0gYmV0d2Vlbm5lc3MoZylcbilcblxuIyBBZGQgb3RoZXIgdmVydGV4IGF0dHJpYnV0ZXMgaWYgYW55XG52ZXJ0ZXhfYXR0cnMgPC0gdmVydGV4X2F0dHIoZylcbmZvciAoYXR0ciBpbiBuYW1lcyh2ZXJ0ZXhfYXR0cnMpKSB7XG4gIGlmIChhdHRyICE9IFxcbmFtZVxcKSB7ICAjIFNraXAgJ25hbWUnIGFzIHdlIGFscmVhZHkgaGF2ZSBpdCBhcyAnaWQnXG4gICAgbm9kZXNfZGZbW2F0dHJdXSA8LSB2ZXJ0ZXhfYXR0cnNbW2F0dHJdXVxuICB9XG59XG5cbiMgU2F2ZSB0aGUgbm9kZXMgZGF0YSBmcmFtZVxud3JpdGUuY3N2KG5vZGVzX2RmLCBcXGdlbmVfbmV0d29ya19ub2Rlcy5jc3ZcXCwgcm93Lm5hbWVzID0gRkFMU0UpXG5cbiMgUHJpbnQgYSBzdW1tYXJ5IG9mIHRoZSBzYXZlZCBkYXRhXG5jYXQoXFxTYXZlZCBuZXR3b3JrIGRhdGE6XFxuXFwpXG5jYXQoXFxFZGdlcyBmaWxlOiBnZW5lX25ldHdvcmtfZWRnZXMuY3N2IC1cXCwgbnJvdyhlZGdlc19kZiksIFxccm93c1xcblxcKVxuY2F0KFxcTm9kZXMgZmlsZTogZ2VuZV9uZXR3b3JrX25vZGVzLmNzdiAtXFwsIG5yb3cobm9kZXNfZGYpLCBcXHJvd3NcXG5cXClcblxuYGBgXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuIyBGdW5jdGlvbiB0byBnZXQgdG9wIGdlbmVzIGZyb20gYSBjb21wYXJpc29uXG5cbmxpYnJhcnkoaWdyYXBoKVxubGlicmFyeShTVFJJTkdkYilcbmxpYnJhcnkoZ2dyYXBoKVxubGlicmFyeSh0aWR5dmVyc2UpXG5saWJyYXJ5KHRpYmJsZSlcblxuZ2V0X3RvcF9nZW5lcyA8LSBmdW5jdGlvbihjb21wYXJpc29uX3Jlc3VsdCwgbiA9IDUwKSB7XG4gIHRvcF9nZW5lcyA8LSBjb21wYXJpc29uX3Jlc3VsdCAlPiVcbiAgICByb3duYW1lc190b19jb2x1bW4oXFxnZW5lXFwpICU+JVxuICAgIGFycmFuZ2UoZGVzYyhhYnMoYXZnX2xvZzJGQykpKSAlPiVcbiAgICBoZWFkKG4pICU+JVxuICAgIHB1bGwoZ2VuZSlcbiAgcmV0dXJuKHRvcF9nZW5lcylcbn1cblxuIyBDb21iaW5lIHRvcCBnZW5lcyBmcm9tIGFsbCBjb21wYXJpc29uc1xuYWxsX3RvcF9nZW5lcyA8LSB1bmlxdWUoYyhcbiAgZ2V0X3RvcF9nZW5lcyhwMV9jb21wYXJpc29uKSxcbiAgZ2V0X3RvcF9nZW5lcyhwMl9jb21wYXJpc29uKSxcbiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDYpLFxuICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNyksXG4gIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNkw3KVxuKSlcblxuIyBJbml0aWFsaXplIFNUUklOR2RiXG5zdHJpbmdfZGIgPC0gU1RSSU5HZGIkbmV3KHZlcnNpb249XFwxMVxcLCBzcGVjaWVzPTk2MDYsIHNjb3JlX3RocmVzaG9sZD03MDApXG5cbiMgTWFwIGdlbmVzIHRvIFNUUklORyBpZGVudGlmaWVyc1xubWFwcGVkX2dlbmVzIDwtIHN0cmluZ19kYiRtYXAoZGF0YS5mcmFtZShnZW5lPWFsbF90b3BfZ2VuZXMpLCBcXGdlbmVcXCwgcmVtb3ZlVW5tYXBwZWRSb3dzID0gVFJVRSlcblxuIyBHZXQgaW50ZXJhY3Rpb25zXG5pbnRlcmFjdGlvbnMgPC0gc3RyaW5nX2RiJGdldF9pbnRlcmFjdGlvbnMobWFwcGVkX2dlbmVzJFNUUklOR19pZClcblxuIyBNYXAgU1RSSU5HIGlkZW50aWZpZXJzIGJhY2sgdG8gZ2VuZSBzeW1ib2xzXG5pbnRlcmFjdGlvbnMkZnJvbSA8LSBtYXBwZWRfZ2VuZXMkZ2VuZVttYXRjaChpbnRlcmFjdGlvbnMkZnJvbSwgbWFwcGVkX2dlbmVzJFNUUklOR19pZCldXG5pbnRlcmFjdGlvbnMkdG8gPC0gbWFwcGVkX2dlbmVzJGdlbmVbbWF0Y2goaW50ZXJhY3Rpb25zJHRvLCBtYXBwZWRfZ2VuZXMkU1RSSU5HX2lkKV1cblxuIyBDcmVhdGUgaWdyYXBoIG9iamVjdFxuZyA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoaW50ZXJhY3Rpb25zLCBkaXJlY3RlZCA9IEZBTFNFKVxuXG4jIENhbGN1bGF0ZSBub2RlIGRlZ3JlZXNcblYoZykkZGVncmVlIDwtIGRlZ3JlZShnKVxuXG4jIENhbGN1bGF0ZSBiZXR3ZWVubmVzcyBjZW50cmFsaXR5XG5WKGcpJGJldHdlZW5uZXNzIDwtIGJldHdlZW5uZXNzKGcpXG5cbiMgSWRlbnRpZnkgY29tbXVuaXRpZXNcbmNvbW11bml0aWVzIDwtIGNsdXN0ZXJfbG91dmFpbihnKVxuVihnKSRjb21tdW5pdHkgPC0gY29tbXVuaXRpZXMkbWVtYmVyc2hpcFxuXG4jIFBsb3QgdGhlIG5ldHdvcmtcbnNldC5zZWVkKDEyMykgICMgZm9yIHJlcHJvZHVjaWJpbGl0eVxuZ2dyYXBoKGcsIGxheW91dCA9IFxcZnJcXCkgK1xuICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IGNvbWJpbmVkX3Njb3JlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgK1xuICBnZW9tX25vZGVfcG9pbnQoYWVzKGNvbG9yID0gZmFjdG9yKGNvbW11bml0eSksIHNpemUgPSBkZWdyZWUpKSArXG4gIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUsIHNpemUgPSAzKSArXG4gIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gXFxTZXQxXFwpICtcbiAgdGhlbWVfdm9pZCgpICtcbiAgbGFicyh0aXRsZSA9IFxcR2VuZSBJbnRlcmFjdGlvbiBOZXR3b3JrXFwsXG4gICAgICAgc3VidGl0bGUgPSBcXEJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXNcXCxcbiAgICAgICBjb2xvciA9IFxcQ29tbXVuaXR5XFwsXG4gICAgICAgc2l6ZSA9IFxcRGVncmVlXFwpXG5cbiMgU2F2ZSB0aGUgcGxvdFxuZ2dzYXZlKFxcZ2VuZV9pbnRlcmFjdGlvbl9uZXR3b3JrLnBuZ1xcLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKVxuXG4jIElkZW50aWZ5IGh1YiBnZW5lc1xuaHViX2dlbmVzIDwtIFYoZykkbmFtZVtvcmRlcihWKGcpJGRlZ3JlZSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcVG9wIDEwIGh1YiBnZW5lczpcXG5cXClcbnByaW50KGh1Yl9nZW5lcylcblxuIyBJZGVudGlmeSBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eVxuaGlnaF9iZXR3ZWVubmVzc19nZW5lcyA8LSBWKGcpJG5hbWVbb3JkZXIoVihnKSRiZXR3ZWVubmVzcywgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcXFxuVG9wIDEwIGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5OlxcblxcKVxucHJpbnQoaGlnaF9iZXR3ZWVubmVzc19nZW5lcylcblxuIyBDYWxjdWxhdGUgYW5kIHByaW50IHNvbWUgbmV0d29yayBzdGF0aXN0aWNzXG5jYXQoXFxcXG5OZXR3b3JrIFN0YXRpc3RpY3M6XFxuXFwpXG5jYXQoXFxOdW1iZXIgb2Ygbm9kZXM6XFwsIHZjb3VudChnKSwgXFxcXG5cXClcbmNhdChcXE51bWJlciBvZiBlZGdlczpcXCwgZWNvdW50KGcpLCBcXFxcblxcKVxuY2F0KFxcTmV0d29yayBkZW5zaXR5OlxcLCBlZGdlX2RlbnNpdHkoZyksIFxcXFxuXFwpXG5jYXQoXFxBdmVyYWdlIHBhdGggbGVuZ3RoOlxcLCBtZWFuX2Rpc3RhbmNlKGcpLCBcXFxcblxcKVxuY2F0KFxcQ2x1c3RlcmluZyBjb2VmZmljaWVudDpcXCwgdHJhbnNpdGl2aXR5KGcpLCBcXFxcblxcKVxuXG4jIEV4dHJhY3QgZWRnZSBpbmZvcm1hdGlvblxuZWRnZXNfZGYgPC0gZGF0YS5mcmFtZShcbiAgZnJvbSA9IGVuZHMoZywgRShnKSlbLDFdLFxuICB0byA9IGVuZHMoZywgRShnKSlbLDJdXG4pXG5cbiMgQWRkIGVkZ2UgYXR0cmlidXRlcyBpZiBhbnlcbmVkZ2VfYXR0cnMgPC0gZWRnZV9hdHRyKGcpXG5mb3IgKGF0dHIgaW4gbmFtZXMoZWRnZV9hdHRycykpIHtcbiAgZWRnZXNfZGZbW2F0dHJdXSA8LSBlZGdlX2F0dHJzW1thdHRyXV1cbn1cblxuIyBTYXZlIHRoZSBlZGdlcyBkYXRhIGZyYW1lXG53cml0ZS5jc3YoZWRnZXNfZGYsIFxcZ2VuZV9uZXR3b3JrX2VkZ2VzLmNzdlxcLCByb3cubmFtZXMgPSBGQUxTRSlcblxuIyBFeHRyYWN0IG5vZGUgaW5mb3JtYXRpb25cbm5vZGVzX2RmIDwtIGRhdGEuZnJhbWUoXG4gIGlkID0gVihnKSRuYW1lLFxuICBkZWdyZWUgPSBkZWdyZWUoZyksXG4gIGJldHdlZW5uZXNzID0gYmV0d2Vlbm5lc3MoZylcbilcblxuIyBBZGQgb3RoZXIgdmVydGV4IGF0dHJpYnV0ZXMgaWYgYW55XG52ZXJ0ZXhfYXR0cnMgPC0gdmVydGV4X2F0dHIoZylcbmZvciAoYXR0ciBpbiBuYW1lcyh2ZXJ0ZXhfYXR0cnMpKSB7XG4gIGlmIChhdHRyICE9IFxcbmFtZVxcKSB7ICAjIFNraXAgJ25hbWUnIGFzIHdlIGFscmVhZHkgaGF2ZSBpdCBhcyAnaWQnXG4gICAgbm9kZXNfZGZbW2F0dHJdXSA8LSB2ZXJ0ZXhfYXR0cnNbW2F0dHJdXVxuICB9XG59XG5cbiMgU2F2ZSB0aGUgbm9kZXMgZGF0YSBmcmFtZVxud3JpdGUuY3N2KG5vZGVzX2RmLCBcXGdlbmVfbmV0d29ya19ub2Rlcy5jc3ZcXCwgcm93Lm5hbWVzID0gRkFMU0UpXG5cbiMgUHJpbnQgYSBzdW1tYXJ5IG9mIHRoZSBzYXZlZCBkYXRhXG5jYXQoXFxTYXZlZCBuZXR3b3JrIGRhdGE6XFxuXFwpXG5jYXQoXFxFZGdlcyBmaWxlOiBnZW5lX25ldHdvcmtfZWRnZXMuY3N2IC1cXCwgbnJvdyhlZGdlc19kZiksIFxccm93c1xcblxcKVxuY2F0KFxcTm9kZXMgZmlsZTogZ2VuZV9uZXR3b3JrX25vZGVzLmNzdiAtXFwsIG5yb3cobm9kZXNfZGYpLCBcXHJvd3NcXG5cXClcblxuYGBgXG5gYGAifQ== -->
```r
```r
# Function to get top genes from a comparison
library(igraph)
library(STRINGdb)
library(ggraph)
library(tidyverse)
library(tibble)
get_top_genes <- function(comparison_result, n = 50) {
top_genes <- comparison_result %>%
rownames_to_column(\gene\) %>%
arrange(desc(abs(avg_log2FC))) %>%
head(n) %>%
pull(gene)
return(top_genes)
}
# Combine top genes from all comparisons
all_top_genes <- unique(c(
get_top_genes(p1_comparison),
get_top_genes(p2_comparison),
get_top_genes(p3_comparison_L5L6),
get_top_genes(p3_comparison_L5L7),
get_top_genes(p3_comparison_L6L7)
))
# Initialize STRINGdb
string_db <- STRINGdb$new(version=\11\, species=9606, score_threshold=700)
# Map genes to STRING identifiers
mapped_genes <- string_db$map(data.frame(gene=all_top_genes), \gene\, removeUnmappedRows = TRUE)
# Get interactions
interactions <- string_db$get_interactions(mapped_genes$STRING_id)
# Map STRING identifiers back to gene symbols
interactions$from <- mapped_genes$gene[match(interactions$from, mapped_genes$STRING_id)]
interactions$to <- mapped_genes$gene[match(interactions$to, mapped_genes$STRING_id)]
# Create igraph object
g <- graph_from_data_frame(interactions, directed = FALSE)
# Calculate node degrees
V(g)$degree <- degree(g)
# Calculate betweenness centrality
V(g)$betweenness <- betweenness(g)
# Identify communities
communities <- cluster_louvain(g)
V(g)$community <- communities$membership
# Plot the network
set.seed(123) # for reproducibility
ggraph(g, layout = \fr\) +
geom_edge_link(aes(edge_alpha = combined_score), show.legend = FALSE) +
geom_node_point(aes(color = factor(community), size = degree)) +
geom_node_text(aes(label = name), repel = TRUE, size = 3) +
scale_color_brewer(palette = \Set1\) +
theme_void() +
labs(title = \Gene Interaction Network\,
subtitle = \Based on top differentially expressed genes\,
color = \Community\,
size = \Degree\)
# Save the plot
ggsave(\gene_interaction_network.png\, width = 12, height = 10, dpi = 300)
# Identify hub genes
hub_genes <- V(g)$name[order(V(g)$degree, decreasing = TRUE)][1:10]
cat(\Top 10 hub genes:\n\)
print(hub_genes)
# Identify genes with high betweenness centrality
high_betweenness_genes <- V(g)$name[order(V(g)$betweenness, decreasing = TRUE)][1:10]
cat(\\nTop 10 genes with high betweenness centrality:\n\)
print(high_betweenness_genes)
# Calculate and print some network statistics
cat(\\nNetwork Statistics:\n\)
cat(\Number of nodes:\, vcount(g), \\n\)
cat(\Number of edges:\, ecount(g), \\n\)
cat(\Network density:\, edge_density(g), \\n\)
cat(\Average path length:\, mean_distance(g), \\n\)
cat(\Clustering coefficient:\, transitivity(g), \\n\)
# Extract edge information
edges_df <- data.frame(
from = ends(g, E(g))[,1],
to = ends(g, E(g))[,2]
)
# Add edge attributes if any
edge_attrs <- edge_attr(g)
for (attr in names(edge_attrs)) {
edges_df[[attr]] <- edge_attrs[[attr]]
}
# Save the edges data frame
write.csv(edges_df, \gene_network_edges.csv\, row.names = FALSE)
# Extract node information
nodes_df <- data.frame(
id = V(g)$name,
degree = degree(g),
betweenness = betweenness(g)
)
# Add other vertex attributes if any
vertex_attrs <- vertex_attr(g)
for (attr in names(vertex_attrs)) {
if (attr != \name\) { # Skip 'name' as we already have it as 'id'
nodes_df[[attr]] <- vertex_attrs[[attr]]
}
}
# Save the nodes data frame
write.csv(nodes_df, \gene_network_nodes.csv\, row.names = FALSE)
# Print a summary of the saved data
cat(\Saved network data:\n\)
cat(\Edges file: gene_network_edges.csv -\, nrow(edges_df), \rows\n\)
cat(\Nodes file: gene_network_nodes.csv -\, nrow(nodes_df), \rows\n\)
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# 9. Network Analysis-kegg
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dVhHNGpJRXh2WVdRZ2NtVnhkV2x5WldRZ2JHbGljbUZ5YVdWelhHNXNhV0p5WVhKNUtHbG5jbUZ3YUNsY2JteHBZbkpoY25rb1oyZHlZWEJvS1Z4dWJHbGljbUZ5ZVNoMGFXUjVkbVZ5YzJVcFhHNXNhV0p5WVhKNUtIUnBZbUpzWlNsY2JteHBZbkpoY25rb2IzSm5Ma2h6TG1WbkxtUmlLVnh1YkdsaWNtRnllU2hIVHk1a1lpbGNibXhwWW5KaGNua29RVzV1YjNSaGRHbHZia1JpYVNsY2JteHBZbkpoY25rb1pIQnNlWElwWEc1Y2JpTWdSblZ1WTNScGIyNGdkRzhnWjJWMElIUnZjQ0JuWlc1bGN5Qm1jbTl0SUdOdmJYQmhjbWx6YjI0Z2NtVnpkV3gwYzF4dVoyVjBYM1J2Y0Y5blpXNWxjeUE4TFNCbWRXNWpkR2x2YmloamIyMXdZWEpwYzI5dVgzSmxjM1ZzZEN3Z2JpQTlJRFV3S1NCN1hHNGdJSFJ2Y0Y5blpXNWxjeUE4TFNCamIyMXdZWEpwYzI5dVgzSmxjM1ZzZENBbFBpVmNiaUFnSUNCMGFXSmliR1U2T25KdmQyNWhiV1Z6WDNSdlgyTnZiSFZ0YmloY1hHZGxibVZjWENrZ0pUNGxYRzRnSUNBZ1pIQnNlWEk2T21GeWNtRnVaMlVvWkdWell5aGhZbk1vWVhablgyeHZaekpHUXlrcEtTQWxQaVZjYmlBZ0lDQm9aV0ZrS0c0cElDVStKVnh1SUNBZ0lHUndiSGx5T2pwd2RXeHNLR2RsYm1VcFhHNGdJSEpsZEhWeWJpaDBiM0JmWjJWdVpYTXBYRzU5WEc1Y2JpTWdRMjl0WW1sdVpTQjBiM0FnWjJWdVpYTWdabkp2YlNCaGJHd2dZMjl0Y0dGeWFYTnZibk5jYm1Gc2JGOTBiM0JmWjJWdVpYTWdQQzBnZFc1cGNYVmxLR01vWEc0Z0lHZGxkRjkwYjNCZloyVnVaWE1vY0RGZlkyOXRjR0Z5YVhOdmJpa3NYRzRnSUdkbGRGOTBiM0JmWjJWdVpYTW9jREpmWTI5dGNHRnlhWE52Ymlrc1hHNGdJR2RsZEY5MGIzQmZaMlZ1WlhNb2NETmZZMjl0Y0dGeWFYTnZibDlNTlV3MktTeGNiaUFnWjJWMFgzUnZjRjluWlc1bGN5aHdNMTlqYjIxd1lYSnBjMjl1WDB3MVREY3BMRnh1SUNCblpYUmZkRzl3WDJkbGJtVnpLSEF6WDJOdmJYQmhjbWx6YjI1ZlREWk1OeWxjYmlrcFhHNWNiaU1nUjJWMElFZFBJSFJsY20xeklHWnZjaUJoYkd3Z2RHOXdJR2RsYm1WelhHNW5iMTkwWlhKdGN5QThMU0JCYm01dmRHRjBhVzl1UkdKcE9qcHpaV3hsWTNRb2IzSm5Ma2h6TG1WbkxtUmlMQ0JyWlhseklEMGdZV3hzWDNSdmNGOW5aVzVsY3l3Z1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1kyOXNkVzF1Y3lBOUlHTW9YRnhUV1UxQ1QweGNYQ3dnWEZ4SFQxeGNMQ0JjWEU5T1ZFOU1UMGRaWEZ3cExDQmNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnJaWGwwZVhCbElEMGdYRnhUV1UxQ1QweGNYQ2xjYmx4dUl5QkdhV3gwWlhJZ1ptOXlJR0pwYjJ4dloybGpZV3dnY0hKdlkyVnpjeUJIVHlCMFpYSnRjeUJoYm1RZ2NtVnRiM1psSUU1QklIWmhiSFZsYzF4dVoyOWZkR1Z5YlhOZlluQWdQQzBnWjI5ZmRHVnliWE1nSlQ0bFhHNGdJR1J3YkhseU9qcG1hV3gwWlhJb1QwNVVUMHhQUjFrZ1BUMGdYRnhDVUZ4Y0tTQWxQaVZjYmlBZ1pIQnNlWEk2T21acGJIUmxjaWdoYVhNdWJtRW9SMDhwS1Z4dVhHNGpJRU55WldGMFpTQmxaR2RsY3lCa1lYUmhabkpoYldWY2JtVmtaMlZ6SUR3dElHZHZYM1JsY20xelgySndJQ1UrSlZ4dUlDQmtjR3g1Y2pvNmMyVnNaV04wS0daeWIyMGdQU0JUV1UxQ1Qwd3NJSFJ2SUQwZ1IwOHBYRzVjYmlNZ1VISnBiblFnYzNWdGJXRnllU0J2WmlCbFpHZGxjMXh1Y0hKcGJuUW9jR0Z6ZEdVb1hGeE9kVzFpWlhJZ2IyWWdaV1JuWlhNNlhGd3NJRzV5YjNjb1pXUm5aWE1wS1NsY2JuQnlhVzUwS0dobFlXUW9aV1JuWlhNcEtWeHVYRzRqSUVsbUlHVmtaMlZ6SUdSaGRHRm1jbUZ0WlNCcGN5QmxiWEIwZVN3Z2MzUnZjQ0JvWlhKbFhHNXBaaUFvYm5KdmR5aGxaR2RsY3lrZ1BUMGdNQ2tnZTF4dUlDQnpkRzl3S0Z4Y1RtOGdSMDhnZEdWeWJYTWdabTkxYm1RZ1ptOXlJR0Z1ZVNCblpXNWxjeTRnUTJGdWJtOTBJR055WldGMFpTQnVaWFIzYjNKckxseGNLVnh1ZlZ4dVhHNGpJRU55WldGMFpTQm5jbUZ3YUZ4dVp5QThMU0JwWjNKaGNHZzZPbWR5WVhCb1gyWnliMjFmWkdGMFlWOW1jbUZ0WlNobFpHZGxjeXdnWkdseVpXTjBaV1FnUFNCR1FVeFRSU2xjYmx4dUl5QkRZV3hqZFd4aGRHVWdibTlrWlNCa1pXZHlaV1Z6WEc1V0tHY3BKR1JsWjNKbFpTQThMU0JwWjNKaGNHZzZPbVJsWjNKbFpTaG5LVnh1WEc0aklFTmhiR04xYkdGMFpTQmlaWFIzWldWdWJtVnpjeUJqWlc1MGNtRnNhWFI1WEc1V0tHY3BKR0psZEhkbFpXNXVaWE56SUR3dElHbG5jbUZ3YURvNlltVjBkMlZsYm01bGMzTW9aeWxjYmx4dUl5QkpaR1Z1ZEdsbWVTQmpiMjF0ZFc1cGRHbGxjMXh1WTI5dGJYVnVhWFJwWlhNZ1BDMGdhV2R5WVhCb09qcGpiSFZ6ZEdWeVgyeHZkWFpoYVc0b1p5bGNibFlvWnlra1kyOXRiWFZ1YVhSNUlEd3RJR052YlcxMWJtbDBhV1Z6SkcxbGJXSmxjbk5vYVhCY2JseHVJeUJIWlhRZ1IwOGdkR1Z5YlNCa1pYTmpjbWx3ZEdsdmJuTmNibWR2WDNSbGNtMXpYMlJsYzJNZ1BDMGdRVzV1YjNSaGRHbHZia1JpYVRvNmMyVnNaV04wS0VkUExtUmlMQ0JyWlhseklEMGdkVzVwY1hWbEtHVmtaMlZ6SkhSdktTd2dYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCamIyeDFiVzV6SUQwZ1hGeFVSVkpOWEZ3c0lHdGxlWFI1Y0dVZ1BTQmNYRWRQU1VSY1hDbGNibHh1SXlCQlpHUWdSMDhnZEdWeWJTQmtaWE5qY21sd2RHbHZibk1nZEc4Z2RHaGxJR2R5WVhCb1hHNVdLR2NwSkdSbGMyTnlhWEIwYVc5dUlEd3RJR2R2WDNSbGNtMXpYMlJsYzJNa1ZFVlNUVnR0WVhSamFDaFdLR2NwSkc1aGJXVXNJR2R2WDNSbGNtMXpYMlJsYzJNa1IwOUpSQ2xkWEc1Y2JpTWdVR3h2ZENCMGFHVWdibVYwZDI5eWExeHVjMlYwTG5ObFpXUW9NVEl6S1NBZ0l5Qm1iM0lnY21Wd2NtOWtkV05wWW1sc2FYUjVYRzV3SUR3dElHZG5jbUZ3YUNobkxDQnNZWGx2ZFhRZ1BTQmNYR1p5WEZ3cElDdGNiaUFnWjJWdmJWOWxaR2RsWDJ4cGJtc29ZV3h3YUdFZ1BTQXdMakVwSUN0Y2JpQWdaMlZ2YlY5dWIyUmxYM0J2YVc1MEtHRmxjeWhqYjJ4dmNpQTlJR1poWTNSdmNpaGpiMjF0ZFc1cGRIa3BMQ0J6YVhwbElEMGdaR1ZuY21WbEtTa2dLMXh1SUNCblpXOXRYMjV2WkdWZmRHVjRkQ2hoWlhNb2JHRmlaV3dnUFNCcFptVnNjMlVvWkdWbmNtVmxJRDRnY1hWaGJuUnBiR1VvWkdWbmNtVmxMQ0F3TGprMUtTd2dibUZ0WlN3Z1hGeGNYQ2twTENCY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVndaV3dnUFNCVVVsVkZMQ0J6YVhwbElEMGdNeWtnSzF4dUlDQnpZMkZzWlY5amIyeHZjbDlpY21WM1pYSW9jR0ZzWlhSMFpTQTlJRnhjVTJWME1WeGNLU0FyWEc0Z0lIUm9aVzFsWDNadmFXUW9LU0FyWEc0Z0lHeGhZbk1vZEdsMGJHVWdQU0JjWEVkbGJtVXRSMDhnVkdWeWJTQkpiblJsY21GamRHbHZiaUJPWlhSM2IzSnJYRndzWEc0Z0lDQWdJQ0FnYzNWaWRHbDBiR1VnUFNCY1hFSmhjMlZrSUc5dUlIUnZjQ0JrYVdabVpYSmxiblJwWVd4c2VTQmxlSEJ5WlhOelpXUWdaMlZ1WlhOY1hDeGNiaUFnSUNBZ0lDQmpiMnh2Y2lBOUlGeGNRMjl0YlhWdWFYUjVYRndzWEc0Z0lDQWdJQ0FnYzJsNlpTQTlJRnhjUkdWbmNtVmxYRndwWEc1Y2JpTWdVMkYyWlNCMGFHVWdjR3h2ZEZ4dVoyZHpZWFpsS0Z4Y1oyVnVaVjluYjE5dVpYUjNiM0pyTG5CdVoxeGNMQ0J3TENCM2FXUjBhQ0E5SURFeUxDQm9aV2xuYUhRZ1BTQXhNQ3dnWkhCcElEMGdNekF3S1Z4dVhHNGpJRWxrWlc1MGFXWjVJR2gxWWlCblpXNWxjMXh1YUhWaVgyZGxibVZ6SUR3dElGWW9aeWtrYm1GdFpWdFdLR2NwSkc1aGJXVWdKV2x1SlNCaGJHeGZkRzl3WDJkbGJtVnpYVnR2Y21SbGNpaFdLR2NwSkdSbFozSmxaVnRXS0djcEpHNWhiV1VnSldsdUpTQmhiR3hmZEc5d1gyZGxibVZ6WFN3Z1pHVmpjbVZoYzJsdVp5QTlJRlJTVlVVcFhWc3hPakV3WFZ4dVkyRjBLRnhjVkc5d0lERXdJR2gxWWlCblpXNWxjenBjWEc1Y1hDbGNibkJ5YVc1MEtHaDFZbDluWlc1bGN5bGNibHh1SXlCSlpHVnVkR2xtZVNCblpXNWxjeUIzYVhSb0lHaHBaMmdnWW1WMGQyVmxibTVsYzNNZ1kyVnVkSEpoYkdsMGVWeHVhR2xuYUY5aVpYUjNaV1Z1Ym1WemMxOW5aVzVsY3lBOExTQldLR2NwSkc1aGJXVmJWaWhuS1NSdVlXMWxJQ1ZwYmlVZ1lXeHNYM1J2Y0Y5blpXNWxjMTFiYjNKa1pYSW9WaWhuS1NSaVpYUjNaV1Z1Ym1WemMxdFdLR2NwSkc1aGJXVWdKV2x1SlNCaGJHeGZkRzl3WDJkbGJtVnpYU3dnWkdWamNtVmhjMmx1WnlBOUlGUlNWVVVwWFZzeE9qRXdYVnh1WTJGMEtGeGNYRnh1Vkc5d0lERXdJR2RsYm1WeklIZHBkR2dnYUdsbmFDQmlaWFIzWldWdWJtVnpjeUJqWlc1MGNtRnNhWFI1T2x4Y2JseGNLVnh1Y0hKcGJuUW9hR2xuYUY5aVpYUjNaV1Z1Ym1WemMxOW5aVzVsY3lsY2JseHVJeUJEWVd4amRXeGhkR1VnWVc1a0lIQnlhVzUwSUhOdmJXVWdibVYwZDI5eWF5QnpkR0YwYVhOMGFXTnpYRzVqWVhRb1hGeGNYRzVPWlhSM2IzSnJJRk4wWVhScGMzUnBZM002WEZ4dVhGd3BYRzVqWVhRb1hGeE9kVzFpWlhJZ2IyWWdibTlrWlhNNlhGd3NJR2xuY21Gd2FEbzZkbU52ZFc1MEtHY3BMQ0JjWEZ4Y2JseGNLVnh1WTJGMEtGeGNUblZ0WW1WeUlHOW1JR1ZrWjJWek9seGNMQ0JwWjNKaGNHZzZPbVZqYjNWdWRDaG5LU3dnWEZ4Y1hHNWNYQ2xjYm1OaGRDaGNYRTVsZEhkdmNtc2daR1Z1YzJsMGVUcGNYQ3dnYVdkeVlYQm9PanBsWkdkbFgyUmxibk5wZEhrb1p5a3NJRnhjWEZ4dVhGd3BYRzVqWVhRb1hGeEJkbVZ5WVdkbElIQmhkR2dnYkdWdVozUm9PbHhjTENCcFozSmhjR2c2T20xbFlXNWZaR2x6ZEdGdVkyVW9aeWtzSUZ4Y1hGeHVYRndwWEc1allYUW9YRnhEYkhWemRHVnlhVzVuSUdOdlpXWm1hV05wWlc1ME9seGNMQ0JwWjNKaGNHZzZPblJ5WVc1emFYUnBkbWwwZVNobktTd2dYRnhjWEc1Y1hDbGNibHh1SXlCRmVIUnlZV04wSUdWa1oyVWdhVzVtYjNKdFlYUnBiMjVjYm1Wa1oyVnpYMlJtSUR3dElHbG5jbUZ3YURvNllYTmZaR0YwWVY5bWNtRnRaU2huTENCM2FHRjBJRDBnWEZ4bFpHZGxjMXhjS1Z4dVhHNGpJRk5oZG1VZ2RHaGxJR1ZrWjJWeklHUmhkR0VnWm5KaGJXVmNibmR5YVhSbExtTnpkaWhsWkdkbGMxOWtaaXdnWEZ4blpXNWxYMmR2WDJWa1oyVnpMbU56ZGx4Y0xDQnliM2N1Ym1GdFpYTWdQU0JHUVV4VFJTbGNibHh1SXlCRmVIUnlZV04wSUc1dlpHVWdhVzVtYjNKdFlYUnBiMjVjYm01dlpHVnpYMlJtSUR3dElHbG5jbUZ3YURvNllYTmZaR0YwWVY5bWNtRnRaU2huTENCM2FHRjBJRDBnWEZ4MlpYSjBhV05sYzF4Y0tWeHVYRzRqSUZOaGRtVWdkR2hsSUc1dlpHVnpJR1JoZEdFZ1puSmhiV1ZjYm5keWFYUmxMbU56ZGlodWIyUmxjMTlrWml3Z1hGeG5aVzVsWDJkdlgyNXZaR1Z6TG1OemRseGNMQ0J5YjNjdWJtRnRaWE1nUFNCR1FVeFRSU2xjYmx4dUl5QlFjbWx1ZENCaElITjFiVzFoY25rZ2IyWWdkR2hsSUhOaGRtVmtJR1JoZEdGY2JtTmhkQ2hjWEZOaGRtVmtJRzVsZEhkdmNtc2daR0YwWVRwY1hHNWNYQ2xjYm1OaGRDaGNYRVZrWjJWeklHWnBiR1U2SUdkbGJtVmZaMjlmWldSblpYTXVZM04ySUMxY1hDd2dibkp2ZHlobFpHZGxjMTlrWmlrc0lGeGNjbTkzYzF4Y2JseGNLVnh1WTJGMEtGeGNUbTlrWlhNZ1ptbHNaVG9nWjJWdVpWOW5iMTl1YjJSbGN5NWpjM1lnTFZ4Y0xDQnVjbTkzS0c1dlpHVnpYMlJtS1N3Z1hGeHliM2R6WEZ4dVhGd3BYRzVjYmlNZ1VISnBiblFnZEc5d0lFZFBJSFJsY20xelhHNTBiM0JmWjI5ZmRHVnliWE1nUEMwZ1ZpaG5LU1J1WVcxbFd5RW9WaWhuS1NSdVlXMWxJQ1ZwYmlVZ1lXeHNYM1J2Y0Y5blpXNWxjeWxkVzI5eVpHVnlLRllvWnlra1pHVm5jbVZsV3lFb1ZpaG5LU1J1WVcxbElDVnBiaVVnWVd4c1gzUnZjRjluWlc1bGN5bGRMQ0JrWldOeVpXRnphVzVuSUQwZ1ZGSlZSU2xkV3pFNk1qQmRYRzVqWVhRb1hGeGNYRzVVYjNBZ01qQWdSMDhnZEdWeWJYTTZYRnh1WEZ3cFhHNW1iM0lnS0hSbGNtMGdhVzRnZEc5d1gyZHZYM1JsY20xektTQjdYRzRnSUdOaGRDaDBaWEp0TENCY1hDMWNYQ3dnVmlobktTUmtaWE5qY21sd2RHbHZibHRXS0djcEpHNWhiV1VnUFQwZ2RHVnliVjBzSUZ4Y1hGeHVYRndwWEc1OVhHNWdZR0JjYm1CZ1lDSjkgLS0+XG5cbmBgYHJcbmBgYHJcblxuIyBMb2FkIHJlcXVpcmVkIGxpYnJhcmllc1xubGlicmFyeShpZ3JhcGgpXG5saWJyYXJ5KGdncmFwaClcbmxpYnJhcnkodGlkeXZlcnNlKVxubGlicmFyeSh0aWJibGUpXG5saWJyYXJ5KG9yZy5Icy5lZy5kYilcbmxpYnJhcnkoR08uZGIpXG5saWJyYXJ5KEFubm90YXRpb25EYmkpXG5saWJyYXJ5KGRwbHlyKVxuXG4jIEZ1bmN0aW9uIHRvIGdldCB0b3AgZ2VuZXMgZnJvbSBjb21wYXJpc29uIHJlc3VsdHNcbmdldF90b3BfZ2VuZXMgPC0gZnVuY3Rpb24oY29tcGFyaXNvbl9yZXN1bHQsIG4gPSA1MCkge1xuICB0b3BfZ2VuZXMgPC0gY29tcGFyaXNvbl9yZXN1bHQgJT4lXG4gICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oXFxnZW5lXFwpICU+JVxuICAgIGRwbHlyOjphcnJhbmdlKGRlc2MoYWJzKGF2Z19sb2cyRkMpKSkgJT4lXG4gICAgaGVhZChuKSAlPiVcbiAgICBkcGx5cjo6cHVsbChnZW5lKVxuICByZXR1cm4odG9wX2dlbmVzKVxufVxuXG4jIENvbWJpbmUgdG9wIGdlbmVzIGZyb20gYWxsIGNvbXBhcmlzb25zXG5hbGxfdG9wX2dlbmVzIDwtIHVuaXF1ZShjKFxuICBnZXRfdG9wX2dlbmVzKHAxX2NvbXBhcmlzb24pLFxuICBnZXRfdG9wX2dlbmVzKHAyX2NvbXBhcmlzb24pLFxuICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNiksXG4gIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNUw3KSxcbiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w2TDcpXG4pKVxuXG4jIEdldCBHTyB0ZXJtcyBmb3IgYWxsIHRvcCBnZW5lc1xuZ29fdGVybXMgPC0gQW5ub3RhdGlvbkRiaTo6c2VsZWN0KG9yZy5Icy5lZy5kYiwga2V5cyA9IGFsbF90b3BfZ2VuZXMsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnMgPSBjKFxcU1lNQk9MXFwsIFxcR09cXCwgXFxPTlRPTE9HWVxcKSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5dHlwZSA9IFxcU1lNQk9MXFwpXG5cbiMgRmlsdGVyIGZvciBiaW9sb2dpY2FsIHByb2Nlc3MgR08gdGVybXMgYW5kIHJlbW92ZSBOQSB2YWx1ZXNcbmdvX3Rlcm1zX2JwIDwtIGdvX3Rlcm1zICU+JVxuICBkcGx5cjo6ZmlsdGVyKE9OVE9MT0dZID09IFxcQlBcXCkgJT4lXG4gIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKEdPKSlcblxuIyBDcmVhdGUgZWRnZXMgZGF0YWZyYW1lXG5lZGdlcyA8LSBnb190ZXJtc19icCAlPiVcbiAgZHBseXI6OnNlbGVjdChmcm9tID0gU1lNQk9MLCB0byA9IEdPKVxuXG4jIFByaW50IHN1bW1hcnkgb2YgZWRnZXNcbnByaW50KHBhc3RlKFxcTnVtYmVyIG9mIGVkZ2VzOlxcLCBucm93KGVkZ2VzKSkpXG5wcmludChoZWFkKGVkZ2VzKSlcblxuIyBJZiBlZGdlcyBkYXRhZnJhbWUgaXMgZW1wdHksIHN0b3AgaGVyZVxuaWYgKG5yb3coZWRnZXMpID09IDApIHtcbiAgc3RvcChcXE5vIEdPIHRlcm1zIGZvdW5kIGZvciBhbnkgZ2VuZXMuIENhbm5vdCBjcmVhdGUgbmV0d29yay5cXClcbn1cblxuIyBDcmVhdGUgZ3JhcGhcbmcgPC0gaWdyYXBoOjpncmFwaF9mcm9tX2RhdGFfZnJhbWUoZWRnZXMsIGRpcmVjdGVkID0gRkFMU0UpXG5cbiMgQ2FsY3VsYXRlIG5vZGUgZGVncmVlc1xuVihnKSRkZWdyZWUgPC0gaWdyYXBoOjpkZWdyZWUoZylcblxuIyBDYWxjdWxhdGUgYmV0d2Vlbm5lc3MgY2VudHJhbGl0eVxuVihnKSRiZXR3ZWVubmVzcyA8LSBpZ3JhcGg6OmJldHdlZW5uZXNzKGcpXG5cbiMgSWRlbnRpZnkgY29tbXVuaXRpZXNcbmNvbW11bml0aWVzIDwtIGlncmFwaDo6Y2x1c3Rlcl9sb3V2YWluKGcpXG5WKGcpJGNvbW11bml0eSA8LSBjb21tdW5pdGllcyRtZW1iZXJzaGlwXG5cbiMgR2V0IEdPIHRlcm0gZGVzY3JpcHRpb25zXG5nb190ZXJtc19kZXNjIDwtIEFubm90YXRpb25EYmk6OnNlbGVjdChHTy5kYiwga2V5cyA9IHVuaXF1ZShlZGdlcyR0byksIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucyA9IFxcVEVSTVxcLCBrZXl0eXBlID0gXFxHT0lEXFwpXG5cbiMgQWRkIEdPIHRlcm0gZGVzY3JpcHRpb25zIHRvIHRoZSBncmFwaFxuVihnKSRkZXNjcmlwdGlvbiA8LSBnb190ZXJtc19kZXNjJFRFUk1bbWF0Y2goVihnKSRuYW1lLCBnb190ZXJtc19kZXNjJEdPSUQpXVxuXG4jIFBsb3QgdGhlIG5ldHdvcmtcbnNldC5zZWVkKDEyMykgICMgZm9yIHJlcHJvZHVjaWJpbGl0eVxucCA8LSBnZ3JhcGgoZywgbGF5b3V0ID0gXFxmclxcKSArXG4gIGdlb21fZWRnZV9saW5rKGFscGhhID0gMC4xKSArXG4gIGdlb21fbm9kZV9wb2ludChhZXMoY29sb3IgPSBmYWN0b3IoY29tbXVuaXR5KSwgc2l6ZSA9IGRlZ3JlZSkpICtcbiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKGRlZ3JlZSA+IHF1YW50aWxlKGRlZ3JlZSwgMC45NSksIG5hbWUsIFxcXFwpKSwgXG4gICAgICAgICAgICAgICAgIHJlcGVsID0gVFJVRSwgc2l6ZSA9IDMpICtcbiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSBcXFNldDFcXCkgK1xuICB0aGVtZV92b2lkKCkgK1xuICBsYWJzKHRpdGxlID0gXFxHZW5lLUdPIFRlcm0gSW50ZXJhY3Rpb24gTmV0d29ya1xcLFxuICAgICAgIHN1YnRpdGxlID0gXFxCYXNlZCBvbiB0b3AgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzXFwsXG4gICAgICAgY29sb3IgPSBcXENvbW11bml0eVxcLFxuICAgICAgIHNpemUgPSBcXERlZ3JlZVxcKVxuXG4jIFNhdmUgdGhlIHBsb3Rcbmdnc2F2ZShcXGdlbmVfZ29fbmV0d29yay5wbmdcXCwgcCwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gMTAsIGRwaSA9IDMwMClcblxuIyBJZGVudGlmeSBodWIgZ2VuZXNcbmh1Yl9nZW5lcyA8LSBWKGcpJG5hbWVbVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lc11bb3JkZXIoVihnKSRkZWdyZWVbVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lc10sIGRlY3JlYXNpbmcgPSBUUlVFKV1bMToxMF1cbmNhdChcXFRvcCAxMCBodWIgZ2VuZXM6XFxuXFwpXG5wcmludChodWJfZ2VuZXMpXG5cbiMgSWRlbnRpZnkgZ2VuZXMgd2l0aCBoaWdoIGJldHdlZW5uZXNzIGNlbnRyYWxpdHlcbmhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMgPC0gVihnKSRuYW1lW1YoZykkbmFtZSAlaW4lIGFsbF90b3BfZ2VuZXNdW29yZGVyKFYoZykkYmV0d2Vlbm5lc3NbVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lc10sIGRlY3JlYXNpbmcgPSBUUlVFKV1bMToxMF1cbmNhdChcXFxcblRvcCAxMCBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eTpcXG5cXClcbnByaW50KGhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMpXG5cbiMgQ2FsY3VsYXRlIGFuZCBwcmludCBzb21lIG5ldHdvcmsgc3RhdGlzdGljc1xuY2F0KFxcXFxuTmV0d29yayBTdGF0aXN0aWNzOlxcblxcKVxuY2F0KFxcTnVtYmVyIG9mIG5vZGVzOlxcLCBpZ3JhcGg6OnZjb3VudChnKSwgXFxcXG5cXClcbmNhdChcXE51bWJlciBvZiBlZGdlczpcXCwgaWdyYXBoOjplY291bnQoZyksIFxcXFxuXFwpXG5jYXQoXFxOZXR3b3JrIGRlbnNpdHk6XFwsIGlncmFwaDo6ZWRnZV9kZW5zaXR5KGcpLCBcXFxcblxcKVxuY2F0KFxcQXZlcmFnZSBwYXRoIGxlbmd0aDpcXCwgaWdyYXBoOjptZWFuX2Rpc3RhbmNlKGcpLCBcXFxcblxcKVxuY2F0KFxcQ2x1c3RlcmluZyBjb2VmZmljaWVudDpcXCwgaWdyYXBoOjp0cmFuc2l0aXZpdHkoZyksIFxcXFxuXFwpXG5cbiMgRXh0cmFjdCBlZGdlIGluZm9ybWF0aW9uXG5lZGdlc19kZiA8LSBpZ3JhcGg6OmFzX2RhdGFfZnJhbWUoZywgd2hhdCA9IFxcZWRnZXNcXClcblxuIyBTYXZlIHRoZSBlZGdlcyBkYXRhIGZyYW1lXG53cml0ZS5jc3YoZWRnZXNfZGYsIFxcZ2VuZV9nb19lZGdlcy5jc3ZcXCwgcm93Lm5hbWVzID0gRkFMU0UpXG5cbiMgRXh0cmFjdCBub2RlIGluZm9ybWF0aW9uXG5ub2Rlc19kZiA8LSBpZ3JhcGg6OmFzX2RhdGFfZnJhbWUoZywgd2hhdCA9IFxcdmVydGljZXNcXClcblxuIyBTYXZlIHRoZSBub2RlcyBkYXRhIGZyYW1lXG53cml0ZS5jc3Yobm9kZXNfZGYsIFxcZ2VuZV9nb19ub2Rlcy5jc3ZcXCwgcm93Lm5hbWVzID0gRkFMU0UpXG5cbiMgUHJpbnQgYSBzdW1tYXJ5IG9mIHRoZSBzYXZlZCBkYXRhXG5jYXQoXFxTYXZlZCBuZXR3b3JrIGRhdGE6XFxuXFwpXG5jYXQoXFxFZGdlcyBmaWxlOiBnZW5lX2dvX2VkZ2VzLmNzdiAtXFwsIG5yb3coZWRnZXNfZGYpLCBcXHJvd3NcXG5cXClcbmNhdChcXE5vZGVzIGZpbGU6IGdlbmVfZ29fbm9kZXMuY3N2IC1cXCwgbnJvdyhub2Rlc19kZiksIFxccm93c1xcblxcKVxuXG4jIFByaW50IHRvcCBHTyB0ZXJtc1xudG9wX2dvX3Rlcm1zIDwtIFYoZykkbmFtZVshKFYoZykkbmFtZSAlaW4lIGFsbF90b3BfZ2VuZXMpXVtvcmRlcihWKGcpJGRlZ3JlZVshKFYoZykkbmFtZSAlaW4lIGFsbF90b3BfZ2VuZXMpXSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjIwXVxuY2F0KFxcXFxuVG9wIDIwIEdPIHRlcm1zOlxcblxcKVxuZm9yICh0ZXJtIGluIHRvcF9nb190ZXJtcykge1xuICBjYXQodGVybSwgXFwtXFwsIFYoZykkZGVzY3JpcHRpb25bVihnKSRuYW1lID09IHRlcm1dLCBcXFxcblxcKVxufVxuYGBgXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuXG4jIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzXG5saWJyYXJ5KGlncmFwaClcbmxpYnJhcnkoZ2dyYXBoKVxubGlicmFyeSh0aWR5dmVyc2UpXG5saWJyYXJ5KHRpYmJsZSlcbmxpYnJhcnkob3JnLkhzLmVnLmRiKVxubGlicmFyeShHTy5kYilcbmxpYnJhcnkoQW5ub3RhdGlvbkRiaSlcbmxpYnJhcnkoZHBseXIpXG5cbiMgRnVuY3Rpb24gdG8gZ2V0IHRvcCBnZW5lcyBmcm9tIGNvbXBhcmlzb24gcmVzdWx0c1xuZ2V0X3RvcF9nZW5lcyA8LSBmdW5jdGlvbihjb21wYXJpc29uX3Jlc3VsdCwgbiA9IDUwKSB7XG4gIHRvcF9nZW5lcyA8LSBjb21wYXJpc29uX3Jlc3VsdCAlPiVcbiAgICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbihcXGdlbmVcXCkgJT4lXG4gICAgZHBseXI6OmFycmFuZ2UoZGVzYyhhYnMoYXZnX2xvZzJGQykpKSAlPiVcbiAgICBoZWFkKG4pICU+JVxuICAgIGRwbHlyOjpwdWxsKGdlbmUpXG4gIHJldHVybih0b3BfZ2VuZXMpXG59XG5cbiMgQ29tYmluZSB0b3AgZ2VuZXMgZnJvbSBhbGwgY29tcGFyaXNvbnNcbmFsbF90b3BfZ2VuZXMgPC0gdW5pcXVlKGMoXG4gIGdldF90b3BfZ2VuZXMocDFfY29tcGFyaXNvbiksXG4gIGdldF90b3BfZ2VuZXMocDJfY29tcGFyaXNvbiksXG4gIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNUw2KSxcbiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDcpLFxuICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDZMNylcbikpXG5cbiMgR2V0IEdPIHRlcm1zIGZvciBhbGwgdG9wIGdlbmVzXG5nb190ZXJtcyA8LSBBbm5vdGF0aW9uRGJpOjpzZWxlY3Qob3JnLkhzLmVnLmRiLCBrZXlzID0gYWxsX3RvcF9nZW5lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucyA9IGMoXFxTWU1CT0xcXCwgXFxHT1xcLCBcXE9OVE9MT0dZXFwpLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXl0eXBlID0gXFxTWU1CT0xcXClcblxuIyBGaWx0ZXIgZm9yIGJpb2xvZ2ljYWwgcHJvY2VzcyBHTyB0ZXJtcyBhbmQgcmVtb3ZlIE5BIHZhbHVlc1xuZ29fdGVybXNfYnAgPC0gZ29fdGVybXMgJT4lXG4gIGRwbHlyOjpmaWx0ZXIoT05UT0xPR1kgPT0gXFxCUFxcKSAlPiVcbiAgZHBseXI6OmZpbHRlcighaXMubmEoR08pKVxuXG4jIENyZWF0ZSBlZGdlcyBkYXRhZnJhbWVcbmVkZ2VzIDwtIGdvX3Rlcm1zX2JwICU+JVxuICBkcGx5cjo6c2VsZWN0KGZyb20gPSBTWU1CT0wsIHRvID0gR08pXG5cbiMgUHJpbnQgc3VtbWFyeSBvZiBlZGdlc1xucHJpbnQocGFzdGUoXFxOdW1iZXIgb2YgZWRnZXM6XFwsIG5yb3coZWRnZXMpKSlcbnByaW50KGhlYWQoZWRnZXMpKVxuXG4jIElmIGVkZ2VzIGRhdGFmcmFtZSBpcyBlbXB0eSwgc3RvcCBoZXJlXG5pZiAobnJvdyhlZGdlcykgPT0gMCkge1xuICBzdG9wKFxcTm8gR08gdGVybXMgZm91bmQgZm9yIGFueSBnZW5lcy4gQ2Fubm90IGNyZWF0ZSBuZXR3b3JrLlxcKVxufVxuXG4jIENyZWF0ZSBncmFwaFxuZyA8LSBpZ3JhcGg6OmdyYXBoX2Zyb21fZGF0YV9mcmFtZShlZGdlcywgZGlyZWN0ZWQgPSBGQUxTRSlcblxuIyBDYWxjdWxhdGUgbm9kZSBkZWdyZWVzXG5WKGcpJGRlZ3JlZSA8LSBpZ3JhcGg6OmRlZ3JlZShnKVxuXG4jIENhbGN1bGF0ZSBiZXR3ZWVubmVzcyBjZW50cmFsaXR5XG5WKGcpJGJldHdlZW5uZXNzIDwtIGlncmFwaDo6YmV0d2Vlbm5lc3MoZylcblxuIyBJZGVudGlmeSBjb21tdW5pdGllc1xuY29tbXVuaXRpZXMgPC0gaWdyYXBoOjpjbHVzdGVyX2xvdXZhaW4oZylcblYoZykkY29tbXVuaXR5IDwtIGNvbW11bml0aWVzJG1lbWJlcnNoaXBcblxuIyBHZXQgR08gdGVybSBkZXNjcmlwdGlvbnNcbmdvX3Rlcm1zX2Rlc2MgPC0gQW5ub3RhdGlvbkRiaTo6c2VsZWN0KEdPLmRiLCBrZXlzID0gdW5pcXVlKGVkZ2VzJHRvKSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zID0gXFxURVJNXFwsIGtleXR5cGUgPSBcXEdPSURcXClcblxuIyBBZGQgR08gdGVybSBkZXNjcmlwdGlvbnMgdG8gdGhlIGdyYXBoXG5WKGcpJGRlc2NyaXB0aW9uIDwtIGdvX3Rlcm1zX2Rlc2MkVEVSTVttYXRjaChWKGcpJG5hbWUsIGdvX3Rlcm1zX2Rlc2MkR09JRCldXG5cbiMgUGxvdCB0aGUgbmV0d29ya1xuc2V0LnNlZWQoMTIzKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5XG5wIDwtIGdncmFwaChnLCBsYXlvdXQgPSBcXGZyXFwpICtcbiAgZ2VvbV9lZGdlX2xpbmsoYWxwaGEgPSAwLjEpICtcbiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhjb2xvciA9IGZhY3Rvcihjb21tdW5pdHkpLCBzaXplID0gZGVncmVlKSkgK1xuICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoZGVncmVlID4gcXVhbnRpbGUoZGVncmVlLCAwLjk1KSwgbmFtZSwgXFxcXCkpLCBcbiAgICAgICAgICAgICAgICAgcmVwZWwgPSBUUlVFLCBzaXplID0gMykgK1xuICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9IFxcU2V0MVxcKSArXG4gIHRoZW1lX3ZvaWQoKSArXG4gIGxhYnModGl0bGUgPSBcXEdlbmUtR08gVGVybSBJbnRlcmFjdGlvbiBOZXR3b3JrXFwsXG4gICAgICAgc3VidGl0bGUgPSBcXEJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXNcXCxcbiAgICAgICBjb2xvciA9IFxcQ29tbXVuaXR5XFwsXG4gICAgICAgc2l6ZSA9IFxcRGVncmVlXFwpXG5cbiMgU2F2ZSB0aGUgcGxvdFxuZ2dzYXZlKFxcZ2VuZV9nb19uZXR3b3JrLnBuZ1xcLCBwLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKVxuXG4jIElkZW50aWZ5IGh1YiBnZW5lc1xuaHViX2dlbmVzIDwtIFYoZykkbmFtZVtWKGcpJG5hbWUgJWluJSBhbGxfdG9wX2dlbmVzXVtvcmRlcihWKGcpJGRlZ3JlZVtWKGcpJG5hbWUgJWluJSBhbGxfdG9wX2dlbmVzXSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcVG9wIDEwIGh1YiBnZW5lczpcXG5cXClcbnByaW50KGh1Yl9nZW5lcylcblxuIyBJZGVudGlmeSBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eVxuaGlnaF9iZXR3ZWVubmVzc19nZW5lcyA8LSBWKGcpJG5hbWVbVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lc11bb3JkZXIoVihnKSRiZXR3ZWVubmVzc1tWKGcpJG5hbWUgJWluJSBhbGxfdG9wX2dlbmVzXSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXVxuY2F0KFxcXFxuVG9wIDEwIGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5OlxcblxcKVxucHJpbnQoaGlnaF9iZXR3ZWVubmVzc19nZW5lcylcblxuIyBDYWxjdWxhdGUgYW5kIHByaW50IHNvbWUgbmV0d29yayBzdGF0aXN0aWNzXG5jYXQoXFxcXG5OZXR3b3JrIFN0YXRpc3RpY3M6XFxuXFwpXG5jYXQoXFxOdW1iZXIgb2Ygbm9kZXM6XFwsIGlncmFwaDo6dmNvdW50KGcpLCBcXFxcblxcKVxuY2F0KFxcTnVtYmVyIG9mIGVkZ2VzOlxcLCBpZ3JhcGg6OmVjb3VudChnKSwgXFxcXG5cXClcbmNhdChcXE5ldHdvcmsgZGVuc2l0eTpcXCwgaWdyYXBoOjplZGdlX2RlbnNpdHkoZyksIFxcXFxuXFwpXG5jYXQoXFxBdmVyYWdlIHBhdGggbGVuZ3RoOlxcLCBpZ3JhcGg6Om1lYW5fZGlzdGFuY2UoZyksIFxcXFxuXFwpXG5jYXQoXFxDbHVzdGVyaW5nIGNvZWZmaWNpZW50OlxcLCBpZ3JhcGg6OnRyYW5zaXRpdml0eShnKSwgXFxcXG5cXClcblxuIyBFeHRyYWN0IGVkZ2UgaW5mb3JtYXRpb25cbmVkZ2VzX2RmIDwtIGlncmFwaDo6YXNfZGF0YV9mcmFtZShnLCB3aGF0ID0gXFxlZGdlc1xcKVxuXG4jIFNhdmUgdGhlIGVkZ2VzIGRhdGEgZnJhbWVcbndyaXRlLmNzdihlZGdlc19kZiwgXFxnZW5lX2dvX2VkZ2VzLmNzdlxcLCByb3cubmFtZXMgPSBGQUxTRSlcblxuIyBFeHRyYWN0IG5vZGUgaW5mb3JtYXRpb25cbm5vZGVzX2RmIDwtIGlncmFwaDo6YXNfZGF0YV9mcmFtZShnLCB3aGF0ID0gXFx2ZXJ0aWNlc1xcKVxuXG4jIFNhdmUgdGhlIG5vZGVzIGRhdGEgZnJhbWVcbndyaXRlLmNzdihub2Rlc19kZiwgXFxnZW5lX2dvX25vZGVzLmNzdlxcLCByb3cubmFtZXMgPSBGQUxTRSlcblxuIyBQcmludCBhIHN1bW1hcnkgb2YgdGhlIHNhdmVkIGRhdGFcbmNhdChcXFNhdmVkIG5ldHdvcmsgZGF0YTpcXG5cXClcbmNhdChcXEVkZ2VzIGZpbGU6IGdlbmVfZ29fZWRnZXMuY3N2IC1cXCwgbnJvdyhlZGdlc19kZiksIFxccm93c1xcblxcKVxuY2F0KFxcTm9kZXMgZmlsZTogZ2VuZV9nb19ub2Rlcy5jc3YgLVxcLCBucm93KG5vZGVzX2RmKSwgXFxyb3dzXFxuXFwpXG5cbiMgUHJpbnQgdG9wIEdPIHRlcm1zXG50b3BfZ29fdGVybXMgPC0gVihnKSRuYW1lWyEoVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lcyldW29yZGVyKFYoZykkZGVncmVlWyEoVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lcyldLCBkZWNyZWFzaW5nID0gVFJVRSldWzE6MjBdXG5jYXQoXFxcXG5Ub3AgMjAgR08gdGVybXM6XFxuXFwpXG5mb3IgKHRlcm0gaW4gdG9wX2dvX3Rlcm1zKSB7XG4gIGNhdCh0ZXJtLCBcXC1cXCwgVihnKSRkZXNjcmlwdGlvbltWKGcpJG5hbWUgPT0gdGVybV0sIFxcXFxuXFwpXG59XG5gYGBcbmBgYCJ9 -->
```r
```r
# Load required libraries
library(igraph)
library(ggraph)
library(tidyverse)
library(tibble)
library(org.Hs.eg.db)
library(GO.db)
library(AnnotationDbi)
library(dplyr)
# Function to get top genes from comparison results
get_top_genes <- function(comparison_result, n = 50) {
top_genes <- comparison_result %>%
tibble::rownames_to_column(\gene\) %>%
dplyr::arrange(desc(abs(avg_log2FC))) %>%
head(n) %>%
dplyr::pull(gene)
return(top_genes)
}
# Combine top genes from all comparisons
all_top_genes <- unique(c(
get_top_genes(p1_comparison),
get_top_genes(p2_comparison),
get_top_genes(p3_comparison_L5L6),
get_top_genes(p3_comparison_L5L7),
get_top_genes(p3_comparison_L6L7)
))
# Get GO terms for all top genes
go_terms <- AnnotationDbi::select(org.Hs.eg.db, keys = all_top_genes,
columns = c(\SYMBOL\, \GO\, \ONTOLOGY\),
keytype = \SYMBOL\)
# Filter for biological process GO terms and remove NA values
go_terms_bp <- go_terms %>%
dplyr::filter(ONTOLOGY == \BP\) %>%
dplyr::filter(!is.na(GO))
# Create edges dataframe
edges <- go_terms_bp %>%
dplyr::select(from = SYMBOL, to = GO)
# Print summary of edges
print(paste(\Number of edges:\, nrow(edges)))
print(head(edges))
# If edges dataframe is empty, stop here
if (nrow(edges) == 0) {
stop(\No GO terms found for any genes. Cannot create network.\)
}
# Create graph
g <- igraph::graph_from_data_frame(edges, directed = FALSE)
# Calculate node degrees
V(g)$degree <- igraph::degree(g)
# Calculate betweenness centrality
V(g)$betweenness <- igraph::betweenness(g)
# Identify communities
communities <- igraph::cluster_louvain(g)
V(g)$community <- communities$membership
# Get GO term descriptions
go_terms_desc <- AnnotationDbi::select(GO.db, keys = unique(edges$to),
columns = \TERM\, keytype = \GOID\)
# Add GO term descriptions to the graph
V(g)$description <- go_terms_desc$TERM[match(V(g)$name, go_terms_desc$GOID)]
# Plot the network
set.seed(123) # for reproducibility
p <- ggraph(g, layout = \fr\) +
geom_edge_link(alpha = 0.1) +
geom_node_point(aes(color = factor(community), size = degree)) +
geom_node_text(aes(label = ifelse(degree > quantile(degree, 0.95), name, \\)),
repel = TRUE, size = 3) +
scale_color_brewer(palette = \Set1\) +
theme_void() +
labs(title = \Gene-GO Term Interaction Network\,
subtitle = \Based on top differentially expressed genes\,
color = \Community\,
size = \Degree\)
# Save the plot
ggsave(\gene_go_network.png\, p, width = 12, height = 10, dpi = 300)
# Identify hub genes
hub_genes <- V(g)$name[V(g)$name %in% all_top_genes][order(V(g)$degree[V(g)$name %in% all_top_genes], decreasing = TRUE)][1:10]
cat(\Top 10 hub genes:\n\)
print(hub_genes)
# Identify genes with high betweenness centrality
high_betweenness_genes <- V(g)$name[V(g)$name %in% all_top_genes][order(V(g)$betweenness[V(g)$name %in% all_top_genes], decreasing = TRUE)][1:10]
cat(\\nTop 10 genes with high betweenness centrality:\n\)
print(high_betweenness_genes)
# Calculate and print some network statistics
cat(\\nNetwork Statistics:\n\)
cat(\Number of nodes:\, igraph::vcount(g), \\n\)
cat(\Number of edges:\, igraph::ecount(g), \\n\)
cat(\Network density:\, igraph::edge_density(g), \\n\)
cat(\Average path length:\, igraph::mean_distance(g), \\n\)
cat(\Clustering coefficient:\, igraph::transitivity(g), \\n\)
# Extract edge information
edges_df <- igraph::as_data_frame(g, what = \edges\)
# Save the edges data frame
write.csv(edges_df, \gene_go_edges.csv\, row.names = FALSE)
# Extract node information
nodes_df <- igraph::as_data_frame(g, what = \vertices\)
# Save the nodes data frame
write.csv(nodes_df, \gene_go_nodes.csv\, row.names = FALSE)
# Print a summary of the saved data
cat(\Saved network data:\n\)
cat(\Edges file: gene_go_edges.csv -\, nrow(edges_df), \rows\n\)
cat(\Nodes file: gene_go_nodes.csv -\, nrow(nodes_df), \rows\n\)
# Print top GO terms
top_go_terms <- V(g)$name[!(V(g)$name %in% all_top_genes)][order(V(g)$degree[!(V(g)$name %in% all_top_genes)], decreasing = TRUE)][1:20]
cat(\\nTop 20 GO terms:\n\)
for (term in top_go_terms) {
cat(term, \-\, V(g)$description[V(g)$name == term], \\n\)
}
<!-- rnb-source-end -->
<!-- rnb-output-end -->
<!-- rnb-chunk-end -->
<!-- rnb-text-begin -->
# 10. Save the Seurat object as an Robj file
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVZR0JnY2x4dVhHNWNiaU56WVhabEtFRnNiRjl6WVcxd2JHVnpYMDFsY21kbFpDd2dabWxzWlNBOUlGeGNRV3hzWDNOaGJYQnNaWE5mVFdWeVoyVmtYMFJGTGxKdlltcGNYQ2xjYmx4dVhHNWdZR0JjYm1CZ1lDSjkgLS0+XG5cbmBgYHJcbmBgYHJcblxuXG4jc2F2ZShBbGxfc2FtcGxlc19NZXJnZWQsIGZpbGUgPSBcXEFsbF9zYW1wbGVzX01lcmdlZF9ERS5Sb2JqXFwpXG5cblxuYGBgXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuXG5cbiNzYXZlKEFsbF9zYW1wbGVzX01lcmdlZCwgZmlsZSA9IFxcQWxsX3NhbXBsZXNfTWVyZ2VkX0RFLlJvYmpcXClcblxuXG5gYGBcbmBgYCJ9 -->
```r
```r
#save(All_samples_Merged, file = \All_samples_Merged_DE.Robj\)
```