1. load libraries

#Differential Expression Analysis

2. load seurat object

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

3. Find Markers for Each Cell Line


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

4. generates an expression heatmap for given cells and features

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)

4. Heatmap of Top 10 Upregulated Genes (Sorted by avg_log2FC)

```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\)

```

LS0tCnRpdGxlOiAiU8OpemFyeSBTeW5kcm9tZSB0b3AxMCBDbHVzdGVycyIKYXV0aG9yOiBOYXNpciBNYWhtb29kIEFiYmFzaQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICAjIHBkZl9kb2N1bWVudDogZGVmYXVsdAogICMgd29yZF9kb2N1bWVudDogZGVmYXVsdAogICMgaHRtbF9kb2N1bWVudDogZGVmYXVsdAogICNybWRmb3JtYXRzOjpyZWFkdGhlZG93bgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQotLS0KCiMgMS4gbG9hZCBsaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CgoKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwaGVhdG1hcCkKbGlicmFyeShjbHVzdGVyUHJvZmlsZXIpCmxpYnJhcnkob3JnLkhzLmVnLmRiKQpsaWJyYXJ5KGVucmljaHBsb3QpCmxpYnJhcnkoZW5yaWNocGxvdCkKCgoKYGBgCiNEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbiBBbmFseXNpcwoKIyAyLiBsb2FkIHNldXJhdCBvYmplY3QKYGBge3IgbG9hZF9zZXVyYXQsICBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KI0xvYWQgU2V1cmF0IE9iamVjdCBMNwpsb2FkKCIvaG9tZS9iaW9pbmZvLzAtaW1wX1JvYmovSGFybW9ueV9pbnRlZ3JhdGVkX0FsbF9zYW1wbGVzX01lcmdlZF93aXRoX1BCTUMxMHhfd2l0aF9oYXJtb255X2NsdXN0ZXJpbmcuUm9iaiIpCgoKQWxsX3NhbXBsZXNfTWVyZ2VkCgpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gIkhhcm1vbnlfc25uX3Jlcy4wLjkiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKCiMgUHJlcGFyZSB0aGUgb2JqZWN0IGZvciBERSBhbmFseXNpcwpBbGxfc2FtcGxlc19NZXJnZWQgPC0gUHJlcFNDVEZpbmRNYXJrZXJzKEFsbF9zYW1wbGVzX01lcmdlZCkKCmBgYAoKI0RpZmZlcmVudGlhbCBFeHByZXNzaW9uIEFuYWx5c2lzCgojIDMuIEZpbmQgTWFya2VycyBmb3IgRWFjaCBDZWxsIExpbmUKYGBge3IgZmluZG1hcmtlcnMxLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCkRlZmF1bHRBc3NheShBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJTQ1QiCklkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpIDwtICJIYXJtb255X3Nubl9yZXMuMC45IgphbGxfbWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIG9ubHkucG9zID0gRkFMU0UsIGxvZ2ZjLnRocmVzaG9sZCA9IDAuMjUpCndyaXRlLmNzdihhbGxfbWFya2VycywgImFsbF9tYXJrZXJzLmNzdiIpCmhlYWQoYWxsX21hcmtlcnMpCgoKYGBgCiMgNC4gZ2VuZXJhdGVzIGFuIGV4cHJlc3Npb24gaGVhdG1hcCBmb3IgZ2l2ZW4gY2VsbHMgYW5kIGZlYXR1cmVzCmBgYHtyIGZpbmRtYXJrZXJzMiwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTE2fQpEZWZhdWx0QXNzYXkoQWxsX3NhbXBsZXNfTWVyZ2VkKSA8LSAiU0NUIiAgIyBvciB0aGUgYXNzYXkgd2hlcmUgdGhlIGdlbmVzIGFyZSBwcmVzZW50CgphbGxfbWFya2VycyAlPiUKICAgIGdyb3VwX2J5KGNsdXN0ZXIpICU+JQogICAgZHBseXI6OmZpbHRlcihhdmdfbG9nMkZDID4gMSkgJT4lCiAgICBzbGljZV9oZWFkKG4gPSA1KSAlPiUKICAgIHVuZ3JvdXAoKSAtPiB0b3A1CmhlYXRtYXBfcGxvdDUgPC1Eb0hlYXRtYXAoQWxsX3NhbXBsZXNfTWVyZ2VkLCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSkgKyBOb0xlZ2VuZCgpCgojIFNhdmUgdGhlIGhlYXRtYXAgYXMgYSBQTkcgZmlsZQpnZ3NhdmUoZmlsZW5hbWUgPSAiaGVhdG1hcF9yZXN1bHQ1LnBuZyIsIHBsb3QgPSBoZWF0bWFwX3Bsb3Q1LCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA4LCBkcGkgPSAzMDApCgphbGxfbWFya2VycyAlPiUKICAgIGdyb3VwX2J5KGNsdXN0ZXIpICU+JQogICAgZHBseXI6OmZpbHRlcihhdmdfbG9nMkZDID4gMSkgJT4lCiAgICBzbGljZV9oZWFkKG4gPSAxMCkgJT4lCiAgICB1bmdyb3VwKCkgLT4gdG9wMTAKaGVhdG1hcF9wbG90MTAgPC1Eb0hlYXRtYXAoQWxsX3NhbXBsZXNfTWVyZ2VkLCBmZWF0dXJlcyA9IHRvcDEwJGdlbmUpICsgTm9MZWdlbmQoKQoKIyBTYXZlIHRoZSBoZWF0bWFwIGFzIGEgUE5HIGZpbGUKZ2dzYXZlKGZpbGVuYW1lID0gImhlYXRtYXBfcmVzdWx0MTAucG5nIiwgcGxvdCA9IGhlYXRtYXBfcGxvdDEwLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA4LCBkcGkgPSAzMDApCgpgYGAKCmBgYHtyIGZpbmRtYXJrZXJzMywgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTE2fQojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHNjQ3VzdG9taXplKQoKIyBBc3N1bWluZyB5b3VyIFNldXJhdCBvYmplY3QgaXMgbmFtZWQgJ3NldXJhdF9vYmonCiMgSWYgbm90LCByZXBsYWNlICdzZXVyYXRfb2JqJyB3aXRoIHlvdXIgb2JqZWN0J3MgbmFtZQoKIyBGaW5kIG1hcmtlcnMgZm9yIGVhY2ggY2x1c3RlcgphbGxfbWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5LnBvcyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4ucGN0ID0gMC4xLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZmMudGhyZXNob2xkID0gMC4xKQoKIyBGaWx0ZXIgYW5kIHJhbmsgbWFya2Vycwp0b3AxMF9tYXJrZXJzIDwtIGFsbF9tYXJrZXJzICU+JQogIGdyb3VwX2J5KGNsdXN0ZXIpICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCAwLjA1KSAlPiUgICMgRmlsdGVyIGZvciBzaWduaWZpY2FudCBnZW5lcwogIHNsaWNlX21heChuID0gMTAsIG9yZGVyX2J5ID0gYXZnX2xvZzJGQykgJT4lICAjIFNlbGVjdCB0b3AgMTAgYnkgYXZnX2xvZzJGQwogIHVuZ3JvdXAoKQoKIyBWaWV3IHRoZSB0b3AgMTAgbWFya2VycyBmb3IgZWFjaCBjbHVzdGVyCnByaW50KHRvcDEwX21hcmtlcnMpCgojIENyZWF0ZSBhIGhlYXRtYXAgdXNpbmcgc2NDdXN0b21pemUKRG90UGxvdF9zY0N1c3RvbShBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gdW5pcXVlKHRvcDEwX21hcmtlcnMkZ2VuZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yc191c2UgPSB2aXJpZGlzX3BsYXNtYV9kYXJrX2hpZ2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICkgICMgQWRqdXN0IGsgdG8gbWF0Y2ggeW91ciBudW1iZXIgb2YgY2x1c3RlcnMKCgpgYGAKCgojIDQuIEhlYXRtYXAgb2YgVG9wIDEwIFVwcmVndWxhdGVkIEdlbmVzIChTb3J0ZWQgYnkgYXZnX2xvZzJGQykKYGBge3IgdG9wMTBfSGVhdG1hcCwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9Cgp0b3AxMF9tYXJrZXJzIDwtIGFsbF9tYXJrZXJzICU+JQogIGdyb3VwX2J5KGNsdXN0ZXIpICU+JQogIHRvcF9uKG4gPSAxMCwgd3QgPSBhdmdfbG9nMkZDKSAlPiUKICBhcnJhbmdlKGNsdXN0ZXIsIGRlc2MoYXZnX2xvZzJGQykpCgp0b3AxMF9nZW5lcyA8LSB1bmlxdWUodG9wMTBfbWFya2VycyRnZW5lKQoKaGVhdG1hcF9kYXRhIDwtIEdldEFzc2F5RGF0YShBbGxfc2FtcGxlc19NZXJnZWQsIGFzc2F5ID0gIlNDVCIsIHNsb3QgPSAiZGF0YSIpW3RvcDEwX2dlbmVzLCBdCmhlYXRtYXBfZGF0YSA8LSBoZWF0bWFwX2RhdGEgLSByb3dNZWFucyhoZWF0bWFwX2RhdGEpCgpjZWxsX2xpbmVfY29sb3JzIDwtIHJhaW5ib3cobGVuZ3RoKHVuaXF1ZShBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lKSkpCm5hbWVzKGNlbGxfbGluZV9jb2xvcnMpIDwtIHVuaXF1ZShBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lKQphbm5vdGF0aW9uX2NvbG9ycyA8LSBsaXN0KGNlbGxfbGluZSA9IGNlbGxfbGluZV9jb2xvcnMpCgpwIDwtIHBoZWF0bWFwKGhlYXRtYXBfZGF0YSwKICAgICAgICAgc2hvd19yb3duYW1lcyA9IFRSVUUsCiAgICAgICAgIHNob3dfY29sbmFtZXMgPSBGQUxTRSwKICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBBbGxfc2FtcGxlc19NZXJnZWRAbWV0YS5kYXRhWywgImNlbGxfbGluZSIsIGRyb3AgPSBGQUxTRV0sCiAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gYW5ub3RhdGlvbl9jb2xvcnMsCiAgICAgICAgIG1haW4gPSAiVG9wIDEwIFVwcmVndWxhdGVkIEdlbmVzIHBlciBDZWxsIExpbmUgKFNvcnRlZCBieSBhdmdfbG9nMkZDKSIsCiAgICAgICAgIGZvbnRzaXplX3JvdyA9IDYsCiAgICAgICAgIHRyZWVoZWlnaHRfY29sID0gMCwKICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRkFMU0UsCiAgICAgICAgIGNsdXN0ZXJfY29scyA9IEZBTFNFKQoKcHJpbnQocCkKcG5nKCJoZWF0bWFwX3RvcDEwX2xvZzJmY19zb3J0ZWQucG5nIiwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCnByaW50KHApCmRldi5vZmYoKQoKYGBgCgojIDUuIEhlYXRtYXAgb2YgVG9wIDEwIE1hcmtlcnMgKFNldXJhdCBEZWZhdWx0KQpgYGB7ciBoZWF0bWFwMiwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9Cgp0b3AxMF9tYXJrZXJzX3NldXJhdCA8LSBhbGxfbWFya2VycyAlPiUKICBncm91cF9ieShjbHVzdGVyKSAlPiUKICB0b3BfbihuID0gMTAsIHd0ID0gYXZnX2xvZzJGQykKCnRvcDEwX2dlbmVzX3NldXJhdCA8LSB1bmlxdWUodG9wMTBfbWFya2Vyc19zZXVyYXQkZ2VuZSkKCmhlYXRtYXBfZGF0YV9zZXVyYXQgPC0gR2V0QXNzYXlEYXRhKEFsbF9zYW1wbGVzX01lcmdlZCwgYXNzYXkgPSAiU0NUIiwgc2xvdCA9ICJkYXRhIilbdG9wMTBfZ2VuZXNfc2V1cmF0LCBdCmhlYXRtYXBfZGF0YV9zZXVyYXQgPC0gaGVhdG1hcF9kYXRhX3NldXJhdCAtIHJvd01lYW5zKGhlYXRtYXBfZGF0YV9zZXVyYXQpCgpwMiA8LSBwaGVhdG1hcChoZWF0bWFwX2RhdGFfc2V1cmF0LAogICAgICAgICBzaG93X3Jvd25hbWVzID0gVFJVRSwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IEZBTFNFLAogICAgICAgICBhbm5vdGF0aW9uX2NvbCA9IEFsbF9zYW1wbGVzX01lcmdlZEBtZXRhLmRhdGFbLCAiY2VsbF9saW5lIiwgZHJvcCA9IEZBTFNFXSwKICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5vdGF0aW9uX2NvbG9ycywKICAgICAgICAgbWFpbiA9ICJUb3AgMTAgTWFya2VycyBwZXIgQ2VsbCBMaW5lIChTZXVyYXQgRGVmYXVsdCkiLAogICAgICAgICBmb250c2l6ZV9yb3cgPSA2LAogICAgICAgICB0cmVlaGVpZ2h0X2NvbCA9IDApCgpwcmludChwMikKcG5nKCJoZWF0bWFwX3RvcDEwX3NldXJhdC5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIsIHJlcyA9IDMwMCkKcHJpbnQocDIpCmRldi5vZmYoKQoKYGBgCgojIDYuIFBhaXJ3aXNlIENvbXBhcmlzb25zCmBgYHtyIHBhaXJ3aXNlQ29tcCwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQoKcGVyZm9ybV9jb21wYXJpc29uX2FuZF92b2xjYW5vIDwtIGZ1bmN0aW9uKEFsbF9zYW1wbGVzX01lcmdlZCwgaWRlbnQxLCBpZGVudDIpIHsKICBJZGVudHMoQWxsX3NhbXBsZXNfTWVyZ2VkKSA8LSAiY2VsbF9saW5lIgogIG1hcmtlcnMgPC0gRmluZE1hcmtlcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCBpZGVudC4xID0gaWRlbnQxLCBpZGVudC4yID0gaWRlbnQyLCBhc3NheSA9ICJTQ1QiKQogIHdyaXRlLmNzdihtYXJrZXJzLCBwYXN0ZTAoImNvbXBhcmlzb25fIiwgaWRlbnQxLCAiX3ZzXyIsIGlkZW50MiwgIi5jc3YiKSkKICAKICAjIENyZWF0ZSB2b2xjYW5vIHBsb3QKICB2b2xjYW5vX3Bsb3QgPC0gRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSByb3duYW1lcyhtYXJrZXJzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAnYXZnX2xvZzJGQycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gJ3BfdmFsX2FkaicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IHBhc3RlKGlkZW50MSwgJ3ZzJywgaWRlbnQyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMS41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbCA9IGMoJ2dyZXknLCAnZGFya2dyZWVuJywgJ2JsdWUnLCAncmVkJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41KQogIAogIHByaW50KHZvbGNhbm9fcGxvdCkKICBwbmcocGFzdGUwKCJ2b2xjYW5vXyIsIGlkZW50MSwgIl92c18iLCBpZGVudDIsICIucG5nIiksIHdpZHRoID0gMTIsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJpbiIsIHJlcyA9IDMwMCkKICBwcmludCh2b2xjYW5vX3Bsb3QpCiAgZGV2Lm9mZigpCiAgCiAgcmV0dXJuKG1hcmtlcnMpCn0KCiMgUGF0aWVudCAxCnAxX2NvbXBhcmlzb24gPC0gcGVyZm9ybV9jb21wYXJpc29uX2FuZF92b2xjYW5vKEFsbF9zYW1wbGVzX01lcmdlZCwgIkwxIiwgIkwyIikKaGVhZChwMV9jb21wYXJpc29uKQoKIyBQYXRpZW50IDIKcDJfY29tcGFyaXNvbiA8LSBwZXJmb3JtX2NvbXBhcmlzb25fYW5kX3ZvbGNhbm8oQWxsX3NhbXBsZXNfTWVyZ2VkLCAiTDMiLCAiTDQiKQpoZWFkKHAyX2NvbXBhcmlzb24pCgojIFBhdGllbnQgMwpwM19jb21wYXJpc29uX0w1TDYgPC0gcGVyZm9ybV9jb21wYXJpc29uX2FuZF92b2xjYW5vKEFsbF9zYW1wbGVzX01lcmdlZCwgIkw1IiwgIkw2IikKcDNfY29tcGFyaXNvbl9MNUw3IDwtIHBlcmZvcm1fY29tcGFyaXNvbl9hbmRfdm9sY2FubyhBbGxfc2FtcGxlc19NZXJnZWQsICJMNSIsICJMNyIpCnAzX2NvbXBhcmlzb25fTDZMNyA8LSBwZXJmb3JtX2NvbXBhcmlzb25fYW5kX3ZvbGNhbm8oQWxsX3NhbXBsZXNfTWVyZ2VkLCAiTDYiLCAiTDciKQpoZWFkKHAzX2NvbXBhcmlzb25fTDVMNikKaGVhZChwM19jb21wYXJpc29uX0w1TDcpCmhlYWQocDNfY29tcGFyaXNvbl9MNkw3KQoKCmBgYAoKCiMgNy4gRW5yaWNobWVudCBBbmFseXNpcwpgYGB7ciBlbnJpY2htZW50LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCnBlcmZvcm1fZ29fZW5yaWNobWVudCA8LSBmdW5jdGlvbihnZW5lX2xpc3QsIGdlbmVfdW5pdmVyc2UsIHRpdGxlKSB7CiAgZWdvIDwtIGVucmljaEdPKGdlbmUgPSBnZW5lX2xpc3QsCiAgICAgICAgICAgICAgICAgIHVuaXZlcnNlID0gZ2VuZV91bml2ZXJzZSwKICAgICAgICAgICAgICAgICAgT3JnRGIgPSBvcmcuSHMuZWcuZGIsCiAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSAiU1lNQk9MIiwKICAgICAgICAgICAgICAgICAgb250ID0gIkJQIiwKICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsCiAgICAgICAgICAgICAgICAgIHF2YWx1ZUN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICAgIHJlYWRhYmxlID0gVFJVRSkKICAKICBwIDwtIGRvdHBsb3QoZWdvLCBzaG93Q2F0ZWdvcnkgPSAyMCwgdGl0bGUgPSBwYXN0ZSgiR08gLSIsIHRpdGxlKSkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQogIAogIHByaW50KHApCiAgcG5nKHBhc3RlMCgiR09fZW5yaWNobWVudF8iLCBnc3ViKCIgIiwgIl8iLCB0aXRsZSksICIucG5nIiksIHdpZHRoID0gMTIsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMzAwKQogIHByaW50KHApCiAgZGV2Lm9mZigpCiAgCiAgcmV0dXJuKGVnbykKfQoKcGVyZm9ybV9rZWdnX2VucmljaG1lbnQgPC0gZnVuY3Rpb24oZ2VuZV9saXN0LCBnZW5lX3VuaXZlcnNlLCB0aXRsZSkgewogICMgQ29udmVydCBnZW5lIHN5bWJvbHMgdG8gRW50cmV6IElEcwogIGVudHJlel9pZHMgPC0gYml0cihnZW5lX2xpc3QsIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKSRFTlRSRVpJRAogIHVuaXZlcnNlX2VudHJleiA8LSBiaXRyKGdlbmVfdW5pdmVyc2UsIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKSRFTlRSRVpJRAogIAogIGVrZWdnIDwtIGVucmljaEtFR0coZ2VuZSA9IGVudHJlel9pZHMsCiAgICAgICAgICAgICAgICAgICAgICB1bml2ZXJzZSA9IHVuaXZlcnNlX2VudHJleiwKICAgICAgICAgICAgICAgICAgICAgIG9yZ2FuaXNtID0gJ2hzYScsCiAgICAgICAgICAgICAgICAgICAgICBrZXlUeXBlID0gImtlZ2ciLAogICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiKQogIAogIHAgPC0gZG90cGxvdChla2VnZywgc2hvd0NhdGVnb3J5ID0gMjAsIHRpdGxlID0gcGFzdGUoIktFR0cgLSIsIHRpdGxlKSkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQogIAogIHByaW50KHApCiAgcG5nKHBhc3RlMCgiS0VHR19lbnJpY2htZW50XyIsIGdzdWIoIiAiLCAiXyIsIHRpdGxlKSwgIi5wbmciKSwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAzMDApCiAgcHJpbnQocCkKICBkZXYub2ZmKCkKICAKICByZXR1cm4oZWtlZ2cpCn0KCmdlbmVfdW5pdmVyc2UgPC0gcm93bmFtZXMoQWxsX3NhbXBsZXNfTWVyZ2VkKQoKIyBQYXRpZW50IDEgKFAxKSBjb21wYXJpc29uOiBMMSB2cyBMMgp1cHJlZ3VsYXRlZF9nZW5lc19QMSA8LSByb3duYW1lcyhwMV9jb21wYXJpc29uW3AxX2NvbXBhcmlzb24kYXZnX2xvZzJGQyA+IDEgJiBwMV9jb21wYXJpc29uJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDEgPC0gcm93bmFtZXMocDFfY29tcGFyaXNvbltwMV9jb21wYXJpc29uJGF2Z19sb2cyRkMgPCAtMSAmIHAxX2NvbXBhcmlzb24kcF92YWxfYWRqIDwgMC4wNSwgXSkKCmdvX3VwX1AxIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgIlVwcmVndWxhdGVkIEdlbmVzIGluIEwxIHZzIEwyIikKZ29fZG93bl9QMSA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgIkRvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDEgdnMgTDIiKQprZWdnX3VwX1AxIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AxLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDEgdnMgTDIiKQprZWdnX2Rvd25fUDEgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMSwgZ2VuZV91bml2ZXJzZSwgIkRvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDEgdnMgTDIiKQoKIyBQYXRpZW50IDIgKFAyKSBjb21wYXJpc29uOiBMMyB2cyBMNAp1cHJlZ3VsYXRlZF9nZW5lc19QMiA8LSByb3duYW1lcyhwMl9jb21wYXJpc29uW3AyX2NvbXBhcmlzb24kYXZnX2xvZzJGQyA+IDEgJiBwMl9jb21wYXJpc29uJHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDIgPC0gcm93bmFtZXMocDJfY29tcGFyaXNvbltwMl9jb21wYXJpc29uJGF2Z19sb2cyRkMgPCAtMSAmIHAyX2NvbXBhcmlzb24kcF92YWxfYWRqIDwgMC4wNSwgXSkKCmdvX3VwX1AyIDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QMiwgZ2VuZV91bml2ZXJzZSwgIlVwcmVndWxhdGVkIEdlbmVzIGluIEwzIHZzIEw0IikKZ29fZG93bl9QMiA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMiwgZ2VuZV91bml2ZXJzZSwgIkRvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDQiKQprZWdnX3VwX1AyIDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AyLCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDQiKQprZWdnX2Rvd25fUDIgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QMiwgZ2VuZV91bml2ZXJzZSwgIkRvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDMgdnMgTDQiKQoKIyBQYXRpZW50IDMgKFAzKSBjb21wYXJpc29ucwojIEw1IHZzIEw2CnVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDYgPC0gcm93bmFtZXMocDNfY29tcGFyaXNvbl9MNUw2W3AzX2NvbXBhcmlzb25fTDVMNiRhdmdfbG9nMkZDID4gMSAmIHAzX2NvbXBhcmlzb25fTDVMNiRwX3ZhbF9hZGogPCAwLjA1LCBdKQpkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDYgPC0gcm93bmFtZXMocDNfY29tcGFyaXNvbl9MNUw2W3AzX2NvbXBhcmlzb25fTDVMNiRhdmdfbG9nMkZDIDwgLTEgJiBwM19jb21wYXJpc29uX0w1TDYkcF92YWxfYWRqIDwgMC4wNSwgXSkKCmdvX3VwX1AzX0w1TDYgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDYsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNiIpCmdvX2Rvd25fUDNfTDVMNiA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNUw2LCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNiIpCmtlZ2dfdXBfUDNfTDVMNiA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QM19MNUw2LCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDYiKQprZWdnX2Rvd25fUDNfTDVMNiA8LSBwZXJmb3JtX2tlZ2dfZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDYsIGdlbmVfdW5pdmVyc2UsICJEb3ducmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw2IikKCiMgTDUgdnMgTDcKdXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNyA8LSByb3duYW1lcyhwM19jb21wYXJpc29uX0w1TDdbcDNfY29tcGFyaXNvbl9MNUw3JGF2Z19sb2cyRkMgPiAxICYgcDNfY29tcGFyaXNvbl9MNUw3JHBfdmFsX2FkaiA8IDAuMDUsIF0pCmRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNyA8LSByb3duYW1lcyhwM19jb21wYXJpc29uX0w1TDdbcDNfY29tcGFyaXNvbl9MNUw3JGF2Z19sb2cyRkMgPCAtMSAmIHAzX2NvbXBhcmlzb25fTDVMNyRwX3ZhbF9hZGogPCAwLjA1LCBdKQoKZ29fdXBfUDNfTDVMNyA8LSBwZXJmb3JtX2dvX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNywgZ2VuZV91bml2ZXJzZSwgIlVwcmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw3IikKZ29fZG93bl9QM19MNUw3IDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudChkb3ducmVndWxhdGVkX2dlbmVzX1AzX0w1TDcsIGdlbmVfdW5pdmVyc2UsICJEb3ducmVndWxhdGVkIEdlbmVzIGluIEw1IHZzIEw3IikKa2VnZ191cF9QM19MNUw3IDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KHVwcmVndWxhdGVkX2dlbmVzX1AzX0w1TDcsIGdlbmVfdW5pdmVyc2UsICJVcHJlZ3VsYXRlZCBHZW5lcyBpbiBMNSB2cyBMNyIpCmtlZ2dfZG93bl9QM19MNUw3IDwtIHBlcmZvcm1fa2VnZ19lbnJpY2htZW50KGRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDVMNywgZ2VuZV91bml2ZXJzZSwgIkRvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDUgdnMgTDciKQoKIyBMNiB2cyBMNwp1cHJlZ3VsYXRlZF9nZW5lc19QM19MNkw3IDwtIHJvd25hbWVzKHAzX2NvbXBhcmlzb25fTDZMN1twM19jb21wYXJpc29uX0w2TDckYXZnX2xvZzJGQyA+IDEgJiBwM19jb21wYXJpc29uX0w2TDckcF92YWxfYWRqIDwgMC4wNSwgXSkKZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNkw3IDwtIHJvd25hbWVzKHAzX2NvbXBhcmlzb25fTDZMN1twM19jb21wYXJpc29uX0w2TDckYXZnX2xvZzJGQyA8IC0xICYgcDNfY29tcGFyaXNvbl9MNkw3JHBfdmFsX2FkaiA8IDAuMDUsIF0pCgpnb191cF9QM19MNkw3IDwtIHBlcmZvcm1fZ29fZW5yaWNobWVudCh1cHJlZ3VsYXRlZF9nZW5lc19QM19MNkw3LCBnZW5lX3VuaXZlcnNlLCAiVXByZWd1bGF0ZWQgR2VuZXMgaW4gTDYgdnMgTDciKQpnb19kb3duX1AzX0w2TDcgPC0gcGVyZm9ybV9nb19lbnJpY2htZW50KGRvd25yZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNywgZ2VuZV91bml2ZXJzZSwgIkRvd25yZWd1bGF0ZWQgR2VuZXMgaW4gTDYgdnMgTDciKQprZWdnX3VwX1AzX0w2TDcgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQodXByZWd1bGF0ZWRfZ2VuZXNfUDNfTDZMNywgZ2VuZV91bml2ZXJzZSwgIlVwcmVndWxhdGVkIEdlbmVzIGluIEw2IHZzIEw3IikKa2VnZ19kb3duX1AzX0w2TDcgPC0gcGVyZm9ybV9rZWdnX2VucmljaG1lbnQoZG93bnJlZ3VsYXRlZF9nZW5lc19QM19MNkw3LCBnZW5lX3VuaXZlcnNlLCAiRG93bnJlZ3VsYXRlZCBHZW5lcyBpbiBMNiB2cyBMNyIpCgpgYGAKCiMgOC4gTmV0d29yayBBbmFseXNpcwpgYGB7ciBuZXR3b3JrX2FuYWx5c2lzLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTJ9CiMgRnVuY3Rpb24gdG8gZ2V0IHRvcCBnZW5lcyBmcm9tIGEgY29tcGFyaXNvbgoKbGlicmFyeShpZ3JhcGgpCmxpYnJhcnkoU1RSSU5HZGIpCmxpYnJhcnkoZ2dyYXBoKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0aWJibGUpCgpnZXRfdG9wX2dlbmVzIDwtIGZ1bmN0aW9uKGNvbXBhcmlzb25fcmVzdWx0LCBuID0gNTApIHsKICB0b3BfZ2VuZXMgPC0gY29tcGFyaXNvbl9yZXN1bHQgJT4lCiAgICByb3duYW1lc190b19jb2x1bW4oImdlbmUiKSAlPiUKICAgIGFycmFuZ2UoZGVzYyhhYnMoYXZnX2xvZzJGQykpKSAlPiUKICAgIGhlYWQobikgJT4lCiAgICBwdWxsKGdlbmUpCiAgcmV0dXJuKHRvcF9nZW5lcykKfQoKIyBDb21iaW5lIHRvcCBnZW5lcyBmcm9tIGFsbCBjb21wYXJpc29ucwphbGxfdG9wX2dlbmVzIDwtIHVuaXF1ZShjKAogIGdldF90b3BfZ2VuZXMocDFfY29tcGFyaXNvbiksCiAgZ2V0X3RvcF9nZW5lcyhwMl9jb21wYXJpc29uKSwKICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNiksCiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDcpLAogIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNkw3KQopKQoKIyBJbml0aWFsaXplIFNUUklOR2RiCnN0cmluZ19kYiA8LSBTVFJJTkdkYiRuZXcodmVyc2lvbj0iMTEiLCBzcGVjaWVzPTk2MDYsIHNjb3JlX3RocmVzaG9sZD03MDApCgojIE1hcCBnZW5lcyB0byBTVFJJTkcgaWRlbnRpZmllcnMKbWFwcGVkX2dlbmVzIDwtIHN0cmluZ19kYiRtYXAoZGF0YS5mcmFtZShnZW5lPWFsbF90b3BfZ2VuZXMpLCAiZ2VuZSIsIHJlbW92ZVVubWFwcGVkUm93cyA9IFRSVUUpCgojIEdldCBpbnRlcmFjdGlvbnMKaW50ZXJhY3Rpb25zIDwtIHN0cmluZ19kYiRnZXRfaW50ZXJhY3Rpb25zKG1hcHBlZF9nZW5lcyRTVFJJTkdfaWQpCgojIENyZWF0ZSBpZ3JhcGggb2JqZWN0CmcgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGludGVyYWN0aW9ucywgZGlyZWN0ZWQgPSBGQUxTRSkKCiMgQ2FsY3VsYXRlIG5vZGUgZGVncmVlcwpWKGcpJGRlZ3JlZSA8LSBkZWdyZWUoZykKCiMgQ2FsY3VsYXRlIGJldHdlZW5uZXNzIGNlbnRyYWxpdHkKVihnKSRiZXR3ZWVubmVzcyA8LSBiZXR3ZWVubmVzcyhnKQoKIyBJZGVudGlmeSBjb21tdW5pdGllcwpjb21tdW5pdGllcyA8LSBjbHVzdGVyX2xvdXZhaW4oZykKVihnKSRjb21tdW5pdHkgPC0gY29tbXVuaXRpZXMkbWVtYmVyc2hpcAoKIyBQbG90IHRoZSBuZXR3b3JrCnNldC5zZWVkKDEyMykgICMgZm9yIHJlcHJvZHVjaWJpbGl0eQpnZ3JhcGgoZywgbGF5b3V0ID0gImZyIikgKwogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gY29tYmluZWRfc2NvcmUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhjb2xvciA9IGZhY3Rvcihjb21tdW5pdHkpLCBzaXplID0gZGVncmVlKSkgKwogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUsIHNpemUgPSAzKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICB0aGVtZV92b2lkKCkgKwogIGxhYnModGl0bGUgPSAiR2VuZSBJbnRlcmFjdGlvbiBOZXR3b3JrIiwKICAgICAgIHN1YnRpdGxlID0gIkJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMiLAogICAgICAgY29sb3IgPSAiQ29tbXVuaXR5IiwKICAgICAgIHNpemUgPSAiRGVncmVlIikKCiMgU2F2ZSB0aGUgcGxvdApnZ3NhdmUoImdlbmVfaW50ZXJhY3Rpb25fbmV0d29yay5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKQoKIyBJZGVudGlmeSBodWIgZ2VuZXMKaHViX2dlbmVzIDwtIFYoZykkbmFtZVtvcmRlcihWKGcpJGRlZ3JlZSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXQpjYXQoIlRvcCAxMCBodWIgZ2VuZXM6XG4iKQpwcmludChodWJfZ2VuZXMpCgojIElkZW50aWZ5IGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5CmhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMgPC0gVihnKSRuYW1lW29yZGVyKFYoZykkYmV0d2Vlbm5lc3MsIGRlY3JlYXNpbmcgPSBUUlVFKV1bMToxMF0KY2F0KCJcblRvcCAxMCBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eTpcbiIpCnByaW50KGhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMpCgojIENhbGN1bGF0ZSBhbmQgcHJpbnQgc29tZSBuZXR3b3JrIHN0YXRpc3RpY3MKY2F0KCJcbk5ldHdvcmsgU3RhdGlzdGljczpcbiIpCmNhdCgiTnVtYmVyIG9mIG5vZGVzOiIsIHZjb3VudChnKSwgIlxuIikKY2F0KCJOdW1iZXIgb2YgZWRnZXM6IiwgZWNvdW50KGcpLCAiXG4iKQpjYXQoIk5ldHdvcmsgZGVuc2l0eToiLCBlZGdlX2RlbnNpdHkoZyksICJcbiIpCmNhdCgiQXZlcmFnZSBwYXRoIGxlbmd0aDoiLCBtZWFuX2Rpc3RhbmNlKGcpLCAiXG4iKQpjYXQoIkNsdXN0ZXJpbmcgY29lZmZpY2llbnQ6IiwgdHJhbnNpdGl2aXR5KGcpLCAiXG4iKQoKIyBFeHRyYWN0IGVkZ2UgaW5mb3JtYXRpb24KZWRnZXNfZGYgPC0gZGF0YS5mcmFtZSgKICBmcm9tID0gZW5kcyhnLCBFKGcpKVssMV0sCiAgdG8gPSBlbmRzKGcsIEUoZykpWywyXQopCgojIEFkZCBlZGdlIGF0dHJpYnV0ZXMgaWYgYW55CmVkZ2VfYXR0cnMgPC0gZWRnZV9hdHRyKGcpCmZvciAoYXR0ciBpbiBuYW1lcyhlZGdlX2F0dHJzKSkgewogIGVkZ2VzX2RmW1thdHRyXV0gPC0gZWRnZV9hdHRyc1tbYXR0cl1dCn0KCiMgU2F2ZSB0aGUgZWRnZXMgZGF0YSBmcmFtZQp3cml0ZS5jc3YoZWRnZXNfZGYsICJnZW5lX25ldHdvcmtfZWRnZXMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCgojIEV4dHJhY3Qgbm9kZSBpbmZvcm1hdGlvbgpub2Rlc19kZiA8LSBkYXRhLmZyYW1lKAogIGlkID0gVihnKSRuYW1lLAogIGRlZ3JlZSA9IGRlZ3JlZShnKSwKICBiZXR3ZWVubmVzcyA9IGJldHdlZW5uZXNzKGcpCikKCiMgQWRkIG90aGVyIHZlcnRleCBhdHRyaWJ1dGVzIGlmIGFueQp2ZXJ0ZXhfYXR0cnMgPC0gdmVydGV4X2F0dHIoZykKZm9yIChhdHRyIGluIG5hbWVzKHZlcnRleF9hdHRycykpIHsKICBpZiAoYXR0ciAhPSAibmFtZSIpIHsgICMgU2tpcCAnbmFtZScgYXMgd2UgYWxyZWFkeSBoYXZlIGl0IGFzICdpZCcKICAgIG5vZGVzX2RmW1thdHRyXV0gPC0gdmVydGV4X2F0dHJzW1thdHRyXV0KICB9Cn0KCiMgU2F2ZSB0aGUgbm9kZXMgZGF0YSBmcmFtZQp3cml0ZS5jc3Yobm9kZXNfZGYsICJnZW5lX25ldHdvcmtfbm9kZXMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCgojIFByaW50IGEgc3VtbWFyeSBvZiB0aGUgc2F2ZWQgZGF0YQpjYXQoIlNhdmVkIG5ldHdvcmsgZGF0YTpcbiIpCmNhdCgiRWRnZXMgZmlsZTogZ2VuZV9uZXR3b3JrX2VkZ2VzLmNzdiAtIiwgbnJvdyhlZGdlc19kZiksICJyb3dzXG4iKQpjYXQoIk5vZGVzIGZpbGU6IGdlbmVfbmV0d29ya19ub2Rlcy5jc3YgLSIsIG5yb3cobm9kZXNfZGYpLCAicm93c1xuIikKYGBgCgpgYGB7ciBuZXR3b3JrX2FuYWx5c2lzMiwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEyfQojIEZ1bmN0aW9uIHRvIGdldCB0b3AgZ2VuZXMgZnJvbSBhIGNvbXBhcmlzb24KCmxpYnJhcnkoaWdyYXBoKQpsaWJyYXJ5KFNUUklOR2RiKQpsaWJyYXJ5KGdncmFwaCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGliYmxlKQoKZ2V0X3RvcF9nZW5lcyA8LSBmdW5jdGlvbihjb21wYXJpc29uX3Jlc3VsdCwgbiA9IDUwKSB7CiAgdG9wX2dlbmVzIDwtIGNvbXBhcmlzb25fcmVzdWx0ICU+JQogICAgcm93bmFtZXNfdG9fY29sdW1uKCJnZW5lIikgJT4lCiAgICBhcnJhbmdlKGRlc2MoYWJzKGF2Z19sb2cyRkMpKSkgJT4lCiAgICBoZWFkKG4pICU+JQogICAgcHVsbChnZW5lKQogIHJldHVybih0b3BfZ2VuZXMpCn0KCiMgQ29tYmluZSB0b3AgZ2VuZXMgZnJvbSBhbGwgY29tcGFyaXNvbnMKYWxsX3RvcF9nZW5lcyA8LSB1bmlxdWUoYygKICBnZXRfdG9wX2dlbmVzKHAxX2NvbXBhcmlzb24pLAogIGdldF90b3BfZ2VuZXMocDJfY29tcGFyaXNvbiksCiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDYpLAogIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNUw3KSwKICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDZMNykKKSkKCiMgSW5pdGlhbGl6ZSBTVFJJTkdkYgpzdHJpbmdfZGIgPC0gU1RSSU5HZGIkbmV3KHZlcnNpb249IjExIiwgc3BlY2llcz05NjA2LCBzY29yZV90aHJlc2hvbGQ9NzAwKQoKIyBNYXAgZ2VuZXMgdG8gU1RSSU5HIGlkZW50aWZpZXJzCm1hcHBlZF9nZW5lcyA8LSBzdHJpbmdfZGIkbWFwKGRhdGEuZnJhbWUoZ2VuZT1hbGxfdG9wX2dlbmVzKSwgImdlbmUiLCByZW1vdmVVbm1hcHBlZFJvd3MgPSBUUlVFKQoKIyBHZXQgaW50ZXJhY3Rpb25zCmludGVyYWN0aW9ucyA8LSBzdHJpbmdfZGIkZ2V0X2ludGVyYWN0aW9ucyhtYXBwZWRfZ2VuZXMkU1RSSU5HX2lkKQoKIyBNYXAgU1RSSU5HIGlkZW50aWZpZXJzIGJhY2sgdG8gZ2VuZSBzeW1ib2xzCmludGVyYWN0aW9ucyRmcm9tIDwtIG1hcHBlZF9nZW5lcyRnZW5lW21hdGNoKGludGVyYWN0aW9ucyRmcm9tLCBtYXBwZWRfZ2VuZXMkU1RSSU5HX2lkKV0KaW50ZXJhY3Rpb25zJHRvIDwtIG1hcHBlZF9nZW5lcyRnZW5lW21hdGNoKGludGVyYWN0aW9ucyR0bywgbWFwcGVkX2dlbmVzJFNUUklOR19pZCldCgojIENyZWF0ZSBpZ3JhcGggb2JqZWN0CmcgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGludGVyYWN0aW9ucywgZGlyZWN0ZWQgPSBGQUxTRSkKCiMgQ2FsY3VsYXRlIG5vZGUgZGVncmVlcwpWKGcpJGRlZ3JlZSA8LSBkZWdyZWUoZykKCiMgQ2FsY3VsYXRlIGJldHdlZW5uZXNzIGNlbnRyYWxpdHkKVihnKSRiZXR3ZWVubmVzcyA8LSBiZXR3ZWVubmVzcyhnKQoKIyBJZGVudGlmeSBjb21tdW5pdGllcwpjb21tdW5pdGllcyA8LSBjbHVzdGVyX2xvdXZhaW4oZykKVihnKSRjb21tdW5pdHkgPC0gY29tbXVuaXRpZXMkbWVtYmVyc2hpcAoKIyBQbG90IHRoZSBuZXR3b3JrCnNldC5zZWVkKDEyMykgICMgZm9yIHJlcHJvZHVjaWJpbGl0eQpnZ3JhcGgoZywgbGF5b3V0ID0gImZyIikgKwogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gY29tYmluZWRfc2NvcmUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhjb2xvciA9IGZhY3Rvcihjb21tdW5pdHkpLCBzaXplID0gZGVncmVlKSkgKwogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUsIHNpemUgPSAzKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICB0aGVtZV92b2lkKCkgKwogIGxhYnModGl0bGUgPSAiR2VuZSBJbnRlcmFjdGlvbiBOZXR3b3JrIiwKICAgICAgIHN1YnRpdGxlID0gIkJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMiLAogICAgICAgY29sb3IgPSAiQ29tbXVuaXR5IiwKICAgICAgIHNpemUgPSAiRGVncmVlIikKCiMgU2F2ZSB0aGUgcGxvdApnZ3NhdmUoImdlbmVfaW50ZXJhY3Rpb25fbmV0d29yay5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKQoKIyBJZGVudGlmeSBodWIgZ2VuZXMKaHViX2dlbmVzIDwtIFYoZykkbmFtZVtvcmRlcihWKGcpJGRlZ3JlZSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXQpjYXQoIlRvcCAxMCBodWIgZ2VuZXM6XG4iKQpwcmludChodWJfZ2VuZXMpCgojIElkZW50aWZ5IGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5CmhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMgPC0gVihnKSRuYW1lW29yZGVyKFYoZykkYmV0d2Vlbm5lc3MsIGRlY3JlYXNpbmcgPSBUUlVFKV1bMToxMF0KY2F0KCJcblRvcCAxMCBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eTpcbiIpCnByaW50KGhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMpCgojIENhbGN1bGF0ZSBhbmQgcHJpbnQgc29tZSBuZXR3b3JrIHN0YXRpc3RpY3MKY2F0KCJcbk5ldHdvcmsgU3RhdGlzdGljczpcbiIpCmNhdCgiTnVtYmVyIG9mIG5vZGVzOiIsIHZjb3VudChnKSwgIlxuIikKY2F0KCJOdW1iZXIgb2YgZWRnZXM6IiwgZWNvdW50KGcpLCAiXG4iKQpjYXQoIk5ldHdvcmsgZGVuc2l0eToiLCBlZGdlX2RlbnNpdHkoZyksICJcbiIpCmNhdCgiQXZlcmFnZSBwYXRoIGxlbmd0aDoiLCBtZWFuX2Rpc3RhbmNlKGcpLCAiXG4iKQpjYXQoIkNsdXN0ZXJpbmcgY29lZmZpY2llbnQ6IiwgdHJhbnNpdGl2aXR5KGcpLCAiXG4iKQoKIyBFeHRyYWN0IGVkZ2UgaW5mb3JtYXRpb24KZWRnZXNfZGYgPC0gZGF0YS5mcmFtZSgKICBmcm9tID0gZW5kcyhnLCBFKGcpKVssMV0sCiAgdG8gPSBlbmRzKGcsIEUoZykpWywyXQopCgojIEFkZCBlZGdlIGF0dHJpYnV0ZXMgaWYgYW55CmVkZ2VfYXR0cnMgPC0gZWRnZV9hdHRyKGcpCmZvciAoYXR0ciBpbiBuYW1lcyhlZGdlX2F0dHJzKSkgewogIGVkZ2VzX2RmW1thdHRyXV0gPC0gZWRnZV9hdHRyc1tbYXR0cl1dCn0KCiMgU2F2ZSB0aGUgZWRnZXMgZGF0YSBmcmFtZQp3cml0ZS5jc3YoZWRnZXNfZGYsICJnZW5lX25ldHdvcmtfZWRnZXMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCgojIEV4dHJhY3Qgbm9kZSBpbmZvcm1hdGlvbgpub2Rlc19kZiA8LSBkYXRhLmZyYW1lKAogIGlkID0gVihnKSRuYW1lLAogIGRlZ3JlZSA9IGRlZ3JlZShnKSwKICBiZXR3ZWVubmVzcyA9IGJldHdlZW5uZXNzKGcpCikKCiMgQWRkIG90aGVyIHZlcnRleCBhdHRyaWJ1dGVzIGlmIGFueQp2ZXJ0ZXhfYXR0cnMgPC0gdmVydGV4X2F0dHIoZykKZm9yIChhdHRyIGluIG5hbWVzKHZlcnRleF9hdHRycykpIHsKICBpZiAoYXR0ciAhPSAibmFtZSIpIHsgICMgU2tpcCAnbmFtZScgYXMgd2UgYWxyZWFkeSBoYXZlIGl0IGFzICdpZCcKICAgIG5vZGVzX2RmW1thdHRyXV0gPC0gdmVydGV4X2F0dHJzW1thdHRyXV0KICB9Cn0KCiMgU2F2ZSB0aGUgbm9kZXMgZGF0YSBmcmFtZQp3cml0ZS5jc3Yobm9kZXNfZGYsICJnZW5lX25ldHdvcmtfbm9kZXMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCgojIFByaW50IGEgc3VtbWFyeSBvZiB0aGUgc2F2ZWQgZGF0YQpjYXQoIlNhdmVkIG5ldHdvcmsgZGF0YTpcbiIpCmNhdCgiRWRnZXMgZmlsZTogZ2VuZV9uZXR3b3JrX2VkZ2VzLmNzdiAtIiwgbnJvdyhlZGdlc19kZiksICJyb3dzXG4iKQpjYXQoIk5vZGVzIGZpbGU6IGdlbmVfbmV0d29ya19ub2Rlcy5jc3YgLSIsIG5yb3cobm9kZXNfZGYpLCAicm93c1xuIikKCmBgYAoKCiMgOS4gTmV0d29yayBBbmFseXNpcy1rZWdnCmBgYHtyIG5ldHdvcmtfYW5hbHlzaXMzLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTJ9CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoaWdyYXBoKQpsaWJyYXJ5KGdncmFwaCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKbGlicmFyeShHTy5kYikKbGlicmFyeShBbm5vdGF0aW9uRGJpKQpsaWJyYXJ5KGRwbHlyKQoKIyBGdW5jdGlvbiB0byBnZXQgdG9wIGdlbmVzIGZyb20gY29tcGFyaXNvbiByZXN1bHRzCmdldF90b3BfZ2VuZXMgPC0gZnVuY3Rpb24oY29tcGFyaXNvbl9yZXN1bHQsIG4gPSA1MCkgewogIHRvcF9nZW5lcyA8LSBjb21wYXJpc29uX3Jlc3VsdCAlPiUKICAgIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJnZW5lIikgJT4lCiAgICBkcGx5cjo6YXJyYW5nZShkZXNjKGFicyhhdmdfbG9nMkZDKSkpICU+JQogICAgaGVhZChuKSAlPiUKICAgIGRwbHlyOjpwdWxsKGdlbmUpCiAgcmV0dXJuKHRvcF9nZW5lcykKfQoKIyBDb21iaW5lIHRvcCBnZW5lcyBmcm9tIGFsbCBjb21wYXJpc29ucwphbGxfdG9wX2dlbmVzIDwtIHVuaXF1ZShjKAogIGdldF90b3BfZ2VuZXMocDFfY29tcGFyaXNvbiksCiAgZ2V0X3RvcF9nZW5lcyhwMl9jb21wYXJpc29uKSwKICBnZXRfdG9wX2dlbmVzKHAzX2NvbXBhcmlzb25fTDVMNiksCiAgZ2V0X3RvcF9nZW5lcyhwM19jb21wYXJpc29uX0w1TDcpLAogIGdldF90b3BfZ2VuZXMocDNfY29tcGFyaXNvbl9MNkw3KQopKQoKIyBHZXQgR08gdGVybXMgZm9yIGFsbCB0b3AgZ2VuZXMKZ29fdGVybXMgPC0gQW5ub3RhdGlvbkRiaTo6c2VsZWN0KG9yZy5Icy5lZy5kYiwga2V5cyA9IGFsbF90b3BfZ2VuZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucyA9IGMoIlNZTUJPTCIsICJHTyIsICJPTlRPTE9HWSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXR5cGUgPSAiU1lNQk9MIikKCiMgRmlsdGVyIGZvciBiaW9sb2dpY2FsIHByb2Nlc3MgR08gdGVybXMgYW5kIHJlbW92ZSBOQSB2YWx1ZXMKZ29fdGVybXNfYnAgPC0gZ29fdGVybXMgJT4lCiAgZHBseXI6OmZpbHRlcihPTlRPTE9HWSA9PSAiQlAiKSAlPiUKICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShHTykpCgojIENyZWF0ZSBlZGdlcyBkYXRhZnJhbWUKZWRnZXMgPC0gZ29fdGVybXNfYnAgJT4lCiAgZHBseXI6OnNlbGVjdChmcm9tID0gU1lNQk9MLCB0byA9IEdPKQoKIyBQcmludCBzdW1tYXJ5IG9mIGVkZ2VzCnByaW50KHBhc3RlKCJOdW1iZXIgb2YgZWRnZXM6IiwgbnJvdyhlZGdlcykpKQpwcmludChoZWFkKGVkZ2VzKSkKCiMgSWYgZWRnZXMgZGF0YWZyYW1lIGlzIGVtcHR5LCBzdG9wIGhlcmUKaWYgKG5yb3coZWRnZXMpID09IDApIHsKICBzdG9wKCJObyBHTyB0ZXJtcyBmb3VuZCBmb3IgYW55IGdlbmVzLiBDYW5ub3QgY3JlYXRlIG5ldHdvcmsuIikKfQoKIyBDcmVhdGUgZ3JhcGgKZyA8LSBpZ3JhcGg6OmdyYXBoX2Zyb21fZGF0YV9mcmFtZShlZGdlcywgZGlyZWN0ZWQgPSBGQUxTRSkKCiMgQ2FsY3VsYXRlIG5vZGUgZGVncmVlcwpWKGcpJGRlZ3JlZSA8LSBpZ3JhcGg6OmRlZ3JlZShnKQoKIyBDYWxjdWxhdGUgYmV0d2Vlbm5lc3MgY2VudHJhbGl0eQpWKGcpJGJldHdlZW5uZXNzIDwtIGlncmFwaDo6YmV0d2Vlbm5lc3MoZykKCiMgSWRlbnRpZnkgY29tbXVuaXRpZXMKY29tbXVuaXRpZXMgPC0gaWdyYXBoOjpjbHVzdGVyX2xvdXZhaW4oZykKVihnKSRjb21tdW5pdHkgPC0gY29tbXVuaXRpZXMkbWVtYmVyc2hpcAoKIyBHZXQgR08gdGVybSBkZXNjcmlwdGlvbnMKZ29fdGVybXNfZGVzYyA8LSBBbm5vdGF0aW9uRGJpOjpzZWxlY3QoR08uZGIsIGtleXMgPSB1bmlxdWUoZWRnZXMkdG8pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucyA9ICJURVJNIiwga2V5dHlwZSA9ICJHT0lEIikKCiMgQWRkIEdPIHRlcm0gZGVzY3JpcHRpb25zIHRvIHRoZSBncmFwaApWKGcpJGRlc2NyaXB0aW9uIDwtIGdvX3Rlcm1zX2Rlc2MkVEVSTVttYXRjaChWKGcpJG5hbWUsIGdvX3Rlcm1zX2Rlc2MkR09JRCldCgojIFBsb3QgdGhlIG5ldHdvcmsKc2V0LnNlZWQoMTIzKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5CnAgPC0gZ2dyYXBoKGcsIGxheW91dCA9ICJmciIpICsKICBnZW9tX2VkZ2VfbGluayhhbHBoYSA9IDAuMSkgKwogIGdlb21fbm9kZV9wb2ludChhZXMoY29sb3IgPSBmYWN0b3IoY29tbXVuaXR5KSwgc2l6ZSA9IGRlZ3JlZSkpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoZGVncmVlID4gcXVhbnRpbGUoZGVncmVlLCAwLjk1KSwgbmFtZSwgIiIpKSwgCiAgICAgICAgICAgICAgICAgcmVwZWwgPSBUUlVFLCBzaXplID0gMykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfdm9pZCgpICsKICBsYWJzKHRpdGxlID0gIkdlbmUtR08gVGVybSBJbnRlcmFjdGlvbiBOZXR3b3JrIiwKICAgICAgIHN1YnRpdGxlID0gIkJhc2VkIG9uIHRvcCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMiLAogICAgICAgY29sb3IgPSAiQ29tbXVuaXR5IiwKICAgICAgIHNpemUgPSAiRGVncmVlIikKCiMgU2F2ZSB0aGUgcGxvdApnZ3NhdmUoImdlbmVfZ29fbmV0d29yay5wbmciLCBwLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKQoKIyBJZGVudGlmeSBodWIgZ2VuZXMKaHViX2dlbmVzIDwtIFYoZykkbmFtZVtWKGcpJG5hbWUgJWluJSBhbGxfdG9wX2dlbmVzXVtvcmRlcihWKGcpJGRlZ3JlZVtWKGcpJG5hbWUgJWluJSBhbGxfdG9wX2dlbmVzXSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjEwXQpjYXQoIlRvcCAxMCBodWIgZ2VuZXM6XG4iKQpwcmludChodWJfZ2VuZXMpCgojIElkZW50aWZ5IGdlbmVzIHdpdGggaGlnaCBiZXR3ZWVubmVzcyBjZW50cmFsaXR5CmhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMgPC0gVihnKSRuYW1lW1YoZykkbmFtZSAlaW4lIGFsbF90b3BfZ2VuZXNdW29yZGVyKFYoZykkYmV0d2Vlbm5lc3NbVihnKSRuYW1lICVpbiUgYWxsX3RvcF9nZW5lc10sIGRlY3JlYXNpbmcgPSBUUlVFKV1bMToxMF0KY2F0KCJcblRvcCAxMCBnZW5lcyB3aXRoIGhpZ2ggYmV0d2Vlbm5lc3MgY2VudHJhbGl0eTpcbiIpCnByaW50KGhpZ2hfYmV0d2Vlbm5lc3NfZ2VuZXMpCgojIENhbGN1bGF0ZSBhbmQgcHJpbnQgc29tZSBuZXR3b3JrIHN0YXRpc3RpY3MKY2F0KCJcbk5ldHdvcmsgU3RhdGlzdGljczpcbiIpCmNhdCgiTnVtYmVyIG9mIG5vZGVzOiIsIGlncmFwaDo6dmNvdW50KGcpLCAiXG4iKQpjYXQoIk51bWJlciBvZiBlZGdlczoiLCBpZ3JhcGg6OmVjb3VudChnKSwgIlxuIikKY2F0KCJOZXR3b3JrIGRlbnNpdHk6IiwgaWdyYXBoOjplZGdlX2RlbnNpdHkoZyksICJcbiIpCmNhdCgiQXZlcmFnZSBwYXRoIGxlbmd0aDoiLCBpZ3JhcGg6Om1lYW5fZGlzdGFuY2UoZyksICJcbiIpCmNhdCgiQ2x1c3RlcmluZyBjb2VmZmljaWVudDoiLCBpZ3JhcGg6OnRyYW5zaXRpdml0eShnKSwgIlxuIikKCiMgRXh0cmFjdCBlZGdlIGluZm9ybWF0aW9uCmVkZ2VzX2RmIDwtIGlncmFwaDo6YXNfZGF0YV9mcmFtZShnLCB3aGF0ID0gImVkZ2VzIikKCiMgU2F2ZSB0aGUgZWRnZXMgZGF0YSBmcmFtZQp3cml0ZS5jc3YoZWRnZXNfZGYsICJnZW5lX2dvX2VkZ2VzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQoKIyBFeHRyYWN0IG5vZGUgaW5mb3JtYXRpb24Kbm9kZXNfZGYgPC0gaWdyYXBoOjphc19kYXRhX2ZyYW1lKGcsIHdoYXQgPSAidmVydGljZXMiKQoKIyBTYXZlIHRoZSBub2RlcyBkYXRhIGZyYW1lCndyaXRlLmNzdihub2Rlc19kZiwgImdlbmVfZ29fbm9kZXMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCgojIFByaW50IGEgc3VtbWFyeSBvZiB0aGUgc2F2ZWQgZGF0YQpjYXQoIlNhdmVkIG5ldHdvcmsgZGF0YTpcbiIpCmNhdCgiRWRnZXMgZmlsZTogZ2VuZV9nb19lZGdlcy5jc3YgLSIsIG5yb3coZWRnZXNfZGYpLCAicm93c1xuIikKY2F0KCJOb2RlcyBmaWxlOiBnZW5lX2dvX25vZGVzLmNzdiAtIiwgbnJvdyhub2Rlc19kZiksICJyb3dzXG4iKQoKIyBQcmludCB0b3AgR08gdGVybXMKdG9wX2dvX3Rlcm1zIDwtIFYoZykkbmFtZVshKFYoZykkbmFtZSAlaW4lIGFsbF90b3BfZ2VuZXMpXVtvcmRlcihWKGcpJGRlZ3JlZVshKFYoZykkbmFtZSAlaW4lIGFsbF90b3BfZ2VuZXMpXSwgZGVjcmVhc2luZyA9IFRSVUUpXVsxOjIwXQpjYXQoIlxuVG9wIDIwIEdPIHRlcm1zOlxuIikKZm9yICh0ZXJtIGluIHRvcF9nb190ZXJtcykgewogIGNhdCh0ZXJtLCAiLSIsIFYoZykkZGVzY3JpcHRpb25bVihnKSRuYW1lID09IHRlcm1dLCAiXG4iKQp9CmBgYAoKIyAxMC4gU2F2ZSB0aGUgU2V1cmF0IG9iamVjdCBhcyBhbiBSb2JqIGZpbGUKYGBge3Igc2F2ZVJPQkp9CgoKI3NhdmUoQWxsX3NhbXBsZXNfTWVyZ2VkLCBmaWxlID0gIkFsbF9zYW1wbGVzX01lcmdlZF9ERS5Sb2JqIikKCgpgYGAKCgoKCg==