1. load libraries

2. Load Data into Seurat


ss_Herrera <- readRDS("Herrara_All_samples.rds")

3. Export to .h5ad (AnnData format)

# Step 1: Rejoin Layers to Get Unified Raw Counts
ss_Herrera[["RNA"]] <- JoinLayers(ss_Herrera[["RNA"]])
raw_counts <- ss_Herrera[["RNA"]]$counts


# Step 2: Transpose to Cells × Genes
# Transpose: genes × cells → cells × genes
counts_transposed <- t(as.matrix(raw_counts))
Warning: sparse->dense coercion: allocating vector of size 7.6 GiB
# Step 3: Prepare Metadata (Optional, Recommended)
cell_metadata <- ss_Herrera[[]]  # All cell metadata

# Step 4: Convert to SingleCellExperiment
library(SingleCellExperiment)
sce <- SingleCellExperiment(
  assays = list(counts = raw_counts),       # Keep raw_counts (genes × cells!)
  colData = cell_metadata                   # Attach cell metadata
)

#Step 5: Export to .h5ad
library(zellkonverter)
Registered S3 method overwritten by 'zellkonverter':
  method                                             from      
  py_to_r.pandas.core.arrays.categorical.Categorical reticulate
writeH5AD(sce, file = "STCAT/ss_Herrera_raw_counts.h5ad")
ℹ Using the 'counts' assay as the X matrix

4. Python Script to run (make sure you have right directory)

# import warnings
# warnings.filterwarnings("ignore")
# import STCAT
# import scanpy as sc
# 
# 
# # Load your .h5ad data
# adata = sc.read("/home/bioinfo/2025_NewHarmony_Integrated_Files/Year3_Analysis/Biomarkers_Validation_with_Public_Data/Borch_Combined/STCAT/STCAT_Annotation_Borcherding/ss_Herrera_raw_counts.h5ad")
# print(adata.var_names[:10])
# 
# 
# # Run STCAT
# results = STCAT.STCAT(adata)
# 
# # Save results
# results.write("/home/bioinfo/2025_NewHarmony_Integrated_Files/Year3_Analysis/Biomarkers_Validation_with_Public_Data/Borch_Combined/STCAT/STCAT_Annotation_Borcherding/STCAT_Annotation_ss_Herrera_raw_counts.h5ad")
# 
# 
# print(adata)
# 

5. Read and merge with Seurat (STCAT annotation)


# Load Seurat and read your annotated table
library(Seurat)
library(dplyr)

# Read your annotation table
annots <- read.csv("STCAT/STCAT_annotations.csv", row.names = 1)

# Confirm the rownames are cell barcodes
head(rownames(annots))  # e.g., AAACCTGGT...
[1] "SS1_Blood_H20_AAGGTTCCATATGAGA" "SS1_Blood_H20_CACTCCAGTGCACCAC" "SS1_Blood_H20_AACTCCCTCCGAACGC"
[4] "SS1_Blood_H20_AACTCTTAGACCGGAT" "SS1_Blood_H20_AAGGCAGAGTCAAGCG" "SS1_Blood_H20_AAGTCTGGTCTAAAGA"
# Match to your Seurat object (assuming your Seurat object is named `ss_Herrera`)
ss_Herrera$STCAT_Prediction <- annots[Cells(ss_Herrera), "Prediction"]
ss_Herrera$STCAT_Cluster <- annots[Cells(ss_Herrera), "Cluster"]
ss_Herrera$STCAT_Uncertainty <- annots[Cells(ss_Herrera), "Uncertainty.score"]

view(ss_Herrera@meta.data)

6. Read and merge with Seurat (STCAT annotation)


DimPlot(ss_Herrera, group.by = "tissue", label = TRUE, repel = T)

DimPlot(ss_Herrera, group.by = "sample_id", label = TRUE, repel = T)

DimPlot(ss_Herrera, group.by = "RNA_snn_res.0.5", label = TRUE, repel = T)

DimPlot(ss_Herrera, group.by = "STCAT_Prediction", label = TRUE, repel = T)

NA
NA
NA
NA

7. Read and merge with Seurat (STCAT annotation)


table(ss_Herrera$STCAT_Prediction)  # should show all predicted labels

      CD4 activated   CD4 proliferation              CD4 Tc             CD4 Tcm             CD4 Tem           CD4 Temra 
                 40                 108                 361                4935                 272                  62 
            CD4 Tex             CD4 Tfh            CD4 Th17            CD4 Tisg              CD4 Tn     CD4 Tn adhesion 
                906                  31                 137                 702                3927                 163 
           CD4 Treg CD4 Treg naive-like             CD4 Trm  CD4 Trm cell-death   CD8 proliferation      CD8 senescence 
                228                 142                 615                1134                 134                   4 
             CD8 Tc             CD8 Tcm             CD8 Tem           CD8 Temra             CD8 Tex              CD8 Tn 
                743                  19                 669                1264                   2                1381 
            CD8 Trm  CD8 Trm naive-like            CD8 Tstr     Double Negative                MAIT              None T 
                142                 476                  26                  32                 385                9622 
        other CD8 T                 Tgd 
                  9                1531 
table(ss_Herrera$sample_id)         # should show L1–L7

Healthy_Blood  Healthy_Skin     MF1_Blood      MF1_Skin     SS1_Blood      SS1_Skin     SS2_Blood      SS2_Skin 
         4386            33          4880           293          3631           374          6078           244 
    SS3_Blood      SS3_Skin     SS4_Blood      SS4_Skin     SS5_Blood     SS6_Blood 
         2109           272          2072           320          2832          2821 
table(ss_Herrera$tissue) 

Blood  Skin 
28809  1536 
# Contingency table 
table_annotation_tissue <- table(ss_Herrera$STCAT_Prediction, ss_Herrera$tissue)
table_annotation_sample_id <- table(ss_Herrera$STCAT_Prediction, ss_Herrera$sample_id)
table_annotation_cluster <- table(ss_Herrera$STCAT_Prediction, ss_Herrera$RNA_snn_res.0.5)

library(pheatmap)

# Proportion table (color scale)
prop_table <- prop.table(table_annotation_cluster, margin = 1)

# Heatmap with raw counts as labels
pheatmap(prop_table,
         display_numbers = table_annotation_cluster,
         cluster_rows = TRUE,
         cluster_cols = TRUE,
         color = colorRampPalette(c("lightyellow", "yellow", "lightgreen", "white"))(100),
         fontsize_row = 10,
         fontsize_col = 10,
         main = "STCAT Prediction vs Clusters")



library(pheatmap)

# Proportion table (color scale)
prop_table <- prop.table(table_annotation_sample_id, margin = 1)

# Heatmap with raw counts as labels
pheatmap(prop_table,
         display_numbers = table_annotation_sample_id,
         cluster_rows = TRUE,
         cluster_cols = TRUE,
         color = colorRampPalette(c("lightyellow", "yellow", "lightgreen", "white"))(100),
         fontsize_row = 10,
         fontsize_col = 10,
         main = "STCAT Prediction vs Patients")



# Proportion table (color scale)
prop_table <- prop.table(table_annotation_tissue, margin = 1)

# Heatmap with raw counts as labels
pheatmap(prop_table,
         display_numbers = table_annotation_tissue,
         cluster_rows = TRUE,
         cluster_cols = TRUE,
         color = colorRampPalette(c("lightyellow", "yellow", "lightgreen", "white"))(100),
         fontsize_row = 10,
         fontsize_col = 10,
         main = "STCAT Prediction vs Patients")

Save the Seurat object as an RDS



saveRDS(ss_Herrera, file = "STCAT/All_Patients_Integrated_ss_Herrera_annotated.RDS")
LS0tCnRpdGxlOiAiSG93IHRvIGNyZWF0ZSAuaDVhZCBmb3IgU1RDQVQgb2YgSGVycmVyYSBkYXRhIgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogICNybWRmb3JtYXRzOjpyZWFkdGhlZG93bgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQotLS0KCiMgMS4gbG9hZCBsaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShybWFya2Rvd24pCmxpYnJhcnkodGlueXRleCkKCgpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGRpdHRvU2VxKQpsaWJyYXJ5KGdncmVwZWwpCiNsaWJyYXJ5KGdndHJlZSkKbGlicmFyeShwYXJhbGxlbCkKbGlicmFyeShwbG90bHkpICAjIDNEIHBsb3QKbGlicmFyeShTZXVyYXQpICAjIElkZW50cygpCmxpYnJhcnkoU2V1cmF0RGlzaykgICMgU2F2ZUg1U2V1cmF0KCkKbGlicmFyeSh0aWJibGUpICAjIHJvd25uYW1lc190b19jb2x1bW4KbGlicmFyeShoYXJtb255KSAjIFJ1bkhhcm1vbnkoKQojb3B0aW9ucyhtYy5jb3JlcyA9IGRldGVjdENvcmVzKCkgLSAxKQoKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoZGJwbHlyKQpsaWJyYXJ5KHJtYXJrZG93bikKbGlicmFyeShrbml0cikKbGlicmFyeSh0aW55dGV4KQojQXppbXV0aCBBbm5vdGF0aW9uIGxpYnJhcmllcwpsaWJyYXJ5KEF6aW11dGgpCiNQcm9qZWNUaWxzIEFubm90YXRpb24gbGlicmFyaWVzCmxpYnJhcnkoU1RBQ0FTKQpsaWJyYXJ5KFByb2plY1RJTHMpCiNzaW5nbGVSIEFubm90YXRpb24gbGlicmFyaWVzCgpsaWJyYXJ5KFNpbmdsZUNlbGxFeHBlcmltZW50KQoKYGBgCgoKIyAyLiBMb2FkIERhdGEgaW50byBTZXVyYXQKYGBge3IgbG9hZF9zZXVyYXR9Cgpzc19IZXJyZXJhIDwtIHJlYWRSRFMoIkhlcnJhcmFfQWxsX3NhbXBsZXMucmRzIikKCmBgYAoKIyAzLiBFeHBvcnQgdG8gLmg1YWQgKEFubkRhdGEgZm9ybWF0KQpgYGB7ciBBbm5EYXRhLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KIyBTdGVwIDE6IFJlam9pbiBMYXllcnMgdG8gR2V0IFVuaWZpZWQgUmF3IENvdW50cwpzc19IZXJyZXJhW1siUk5BIl1dIDwtIEpvaW5MYXllcnMoc3NfSGVycmVyYVtbIlJOQSJdXSkKcmF3X2NvdW50cyA8LSBzc19IZXJyZXJhW1siUk5BIl1dJGNvdW50cwoKCiMgU3RlcCAyOiBUcmFuc3Bvc2UgdG8gQ2VsbHMgw5cgR2VuZXMKIyBUcmFuc3Bvc2U6IGdlbmVzIMOXIGNlbGxzIOKGkiBjZWxscyDDlyBnZW5lcwpjb3VudHNfdHJhbnNwb3NlZCA8LSB0KGFzLm1hdHJpeChyYXdfY291bnRzKSkKCiMgU3RlcCAzOiBQcmVwYXJlIE1ldGFkYXRhIChPcHRpb25hbCwgUmVjb21tZW5kZWQpCmNlbGxfbWV0YWRhdGEgPC0gc3NfSGVycmVyYVtbXV0gICMgQWxsIGNlbGwgbWV0YWRhdGEKCiMgU3RlcCA0OiBDb252ZXJ0IHRvIFNpbmdsZUNlbGxFeHBlcmltZW50CmxpYnJhcnkoU2luZ2xlQ2VsbEV4cGVyaW1lbnQpCnNjZSA8LSBTaW5nbGVDZWxsRXhwZXJpbWVudCgKICBhc3NheXMgPSBsaXN0KGNvdW50cyA9IHJhd19jb3VudHMpLCAgICAgICAjIEtlZXAgcmF3X2NvdW50cyAoZ2VuZXMgw5cgY2VsbHMhKQogIGNvbERhdGEgPSBjZWxsX21ldGFkYXRhICAgICAgICAgICAgICAgICAgICMgQXR0YWNoIGNlbGwgbWV0YWRhdGEKKQoKI1N0ZXAgNTogRXhwb3J0IHRvIC5oNWFkCmxpYnJhcnkoemVsbGtvbnZlcnRlcikKd3JpdGVINUFEKHNjZSwgZmlsZSA9ICJTVENBVC9zc19IZXJyZXJhX3Jhd19jb3VudHMuaDVhZCIpCgpgYGAKCgojIDQuIFB5dGhvbiBTY3JpcHQgdG8gcnVuIChtYWtlIHN1cmUgeW91IGhhdmUgcmlnaHQgZGlyZWN0b3J5KQpgYGB7ciBQeXRob25TVENBVCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CiMgaW1wb3J0IHdhcm5pbmdzCiMgd2FybmluZ3MuZmlsdGVyd2FybmluZ3MoImlnbm9yZSIpCiMgaW1wb3J0IFNUQ0FUCiMgaW1wb3J0IHNjYW5weSBhcyBzYwojIAojIAojICMgTG9hZCB5b3VyIC5oNWFkIGRhdGEKIyBhZGF0YSA9IHNjLnJlYWQoIi9ob21lL2Jpb2luZm8vMjAyNV9OZXdIYXJtb255X0ludGVncmF0ZWRfRmlsZXMvWWVhcjNfQW5hbHlzaXMvQmlvbWFya2Vyc19WYWxpZGF0aW9uX3dpdGhfUHVibGljX0RhdGEvQm9yY2hfQ29tYmluZWQvU1RDQVQvU1RDQVRfQW5ub3RhdGlvbl9Cb3JjaGVyZGluZy9zc19IZXJyZXJhX3Jhd19jb3VudHMuaDVhZCIpCiMgcHJpbnQoYWRhdGEudmFyX25hbWVzWzoxMF0pCiMgCiMgCiMgIyBSdW4gU1RDQVQKIyByZXN1bHRzID0gU1RDQVQuU1RDQVQoYWRhdGEpCiMgCiMgIyBTYXZlIHJlc3VsdHMKIyByZXN1bHRzLndyaXRlKCIvaG9tZS9iaW9pbmZvLzIwMjVfTmV3SGFybW9ueV9JbnRlZ3JhdGVkX0ZpbGVzL1llYXIzX0FuYWx5c2lzL0Jpb21hcmtlcnNfVmFsaWRhdGlvbl93aXRoX1B1YmxpY19EYXRhL0JvcmNoX0NvbWJpbmVkL1NUQ0FUL1NUQ0FUX0Fubm90YXRpb25fQm9yY2hlcmRpbmcvU1RDQVRfQW5ub3RhdGlvbl9zc19IZXJyZXJhX3Jhd19jb3VudHMuaDVhZCIpCiMgCiMgCiMgcHJpbnQoYWRhdGEpCiMgCgpgYGAKCiMgNS4gUmVhZCBhbmQgbWVyZ2Ugd2l0aCBTZXVyYXQgKFNUQ0FUIGFubm90YXRpb24pCmBgYHtyIFNUQ0FULCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCiMgTG9hZCBTZXVyYXQgYW5kIHJlYWQgeW91ciBhbm5vdGF0ZWQgdGFibGUKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoZHBseXIpCgojIFJlYWQgeW91ciBhbm5vdGF0aW9uIHRhYmxlCmFubm90cyA8LSByZWFkLmNzdigiU1RDQVQvU1RDQVRfYW5ub3RhdGlvbnMuY3N2Iiwgcm93Lm5hbWVzID0gMSkKCiMgQ29uZmlybSB0aGUgcm93bmFtZXMgYXJlIGNlbGwgYmFyY29kZXMKaGVhZChyb3duYW1lcyhhbm5vdHMpKSAgIyBlLmcuLCBBQUFDQ1RHR1QuLi4KCiMgTWF0Y2ggdG8geW91ciBTZXVyYXQgb2JqZWN0IChhc3N1bWluZyB5b3VyIFNldXJhdCBvYmplY3QgaXMgbmFtZWQgYHNzX0hlcnJlcmFgKQpzc19IZXJyZXJhJFNUQ0FUX1ByZWRpY3Rpb24gPC0gYW5ub3RzW0NlbGxzKHNzX0hlcnJlcmEpLCAiUHJlZGljdGlvbiJdCnNzX0hlcnJlcmEkU1RDQVRfQ2x1c3RlciA8LSBhbm5vdHNbQ2VsbHMoc3NfSGVycmVyYSksICJDbHVzdGVyIl0Kc3NfSGVycmVyYSRTVENBVF9VbmNlcnRhaW50eSA8LSBhbm5vdHNbQ2VsbHMoc3NfSGVycmVyYSksICJVbmNlcnRhaW50eS5zY29yZSJdCgp2aWV3KHNzX0hlcnJlcmFAbWV0YS5kYXRhKQoKYGBgCgoKIyA2LiBSZWFkIGFuZCBtZXJnZSB3aXRoIFNldXJhdCAoU1RDQVQgYW5ub3RhdGlvbikKYGBge3IgU1RDQVRfdmlzLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTR9CgpEaW1QbG90KHNzX0hlcnJlcmEsIGdyb3VwLmJ5ID0gInRpc3N1ZSIsIGxhYmVsID0gVFJVRSwgcmVwZWwgPSBUKQpEaW1QbG90KHNzX0hlcnJlcmEsIGdyb3VwLmJ5ID0gInNhbXBsZV9pZCIsIGxhYmVsID0gVFJVRSwgcmVwZWwgPSBUKQpEaW1QbG90KHNzX0hlcnJlcmEsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIsIGxhYmVsID0gVFJVRSwgcmVwZWwgPSBUKQpEaW1QbG90KHNzX0hlcnJlcmEsIGdyb3VwLmJ5ID0gIlNUQ0FUX1ByZWRpY3Rpb24iLCBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVCkKCgoKCmBgYAoKIyA3LiBSZWFkIGFuZCBtZXJnZSB3aXRoIFNldXJhdCAoU1RDQVQgYW5ub3RhdGlvbikKYGBge3IgU1RDQVRfdmlzMiwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KCnRhYmxlKHNzX0hlcnJlcmEkU1RDQVRfUHJlZGljdGlvbikgICMgc2hvdWxkIHNob3cgYWxsIHByZWRpY3RlZCBsYWJlbHMKdGFibGUoc3NfSGVycmVyYSRzYW1wbGVfaWQpICAgICAgICAgIyBzaG91bGQgc2hvdyBMMeKAk0w3CnRhYmxlKHNzX0hlcnJlcmEkdGlzc3VlKSAKCiMgQ29udGluZ2VuY3kgdGFibGUgCnRhYmxlX2Fubm90YXRpb25fdGlzc3VlIDwtIHRhYmxlKHNzX0hlcnJlcmEkU1RDQVRfUHJlZGljdGlvbiwgc3NfSGVycmVyYSR0aXNzdWUpCnRhYmxlX2Fubm90YXRpb25fc2FtcGxlX2lkIDwtIHRhYmxlKHNzX0hlcnJlcmEkU1RDQVRfUHJlZGljdGlvbiwgc3NfSGVycmVyYSRzYW1wbGVfaWQpCnRhYmxlX2Fubm90YXRpb25fY2x1c3RlciA8LSB0YWJsZShzc19IZXJyZXJhJFNUQ0FUX1ByZWRpY3Rpb24sIHNzX0hlcnJlcmEkUk5BX3Nubl9yZXMuMC41KQoKbGlicmFyeShwaGVhdG1hcCkKCiMgUHJvcG9ydGlvbiB0YWJsZSAoY29sb3Igc2NhbGUpCnByb3BfdGFibGUgPC0gcHJvcC50YWJsZSh0YWJsZV9hbm5vdGF0aW9uX2NsdXN0ZXIsIG1hcmdpbiA9IDEpCgojIEhlYXRtYXAgd2l0aCByYXcgY291bnRzIGFzIGxhYmVscwpwaGVhdG1hcChwcm9wX3RhYmxlLAogICAgICAgICBkaXNwbGF5X251bWJlcnMgPSB0YWJsZV9hbm5vdGF0aW9uX2NsdXN0ZXIsCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsCiAgICAgICAgIGNsdXN0ZXJfY29scyA9IFRSVUUsCiAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShjKCJsaWdodHllbGxvdyIsICJ5ZWxsb3ciLCAibGlnaHRncmVlbiIsICJ3aGl0ZSIpKSgxMDApLAogICAgICAgICBmb250c2l6ZV9yb3cgPSAxMCwKICAgICAgICAgZm9udHNpemVfY29sID0gMTAsCiAgICAgICAgIG1haW4gPSAiU1RDQVQgUHJlZGljdGlvbiB2cyBDbHVzdGVycyIpCgoKbGlicmFyeShwaGVhdG1hcCkKCiMgUHJvcG9ydGlvbiB0YWJsZSAoY29sb3Igc2NhbGUpCnByb3BfdGFibGUgPC0gcHJvcC50YWJsZSh0YWJsZV9hbm5vdGF0aW9uX3NhbXBsZV9pZCwgbWFyZ2luID0gMSkKCiMgSGVhdG1hcCB3aXRoIHJhdyBjb3VudHMgYXMgbGFiZWxzCnBoZWF0bWFwKHByb3BfdGFibGUsCiAgICAgICAgIGRpc3BsYXlfbnVtYmVycyA9IHRhYmxlX2Fubm90YXRpb25fc2FtcGxlX2lkLAogICAgICAgICBjbHVzdGVyX3Jvd3MgPSBUUlVFLAogICAgICAgICBjbHVzdGVyX2NvbHMgPSBUUlVFLAogICAgICAgICBjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYygibGlnaHR5ZWxsb3ciLCAieWVsbG93IiwgImxpZ2h0Z3JlZW4iLCAid2hpdGUiKSkoMTAwKSwKICAgICAgICAgZm9udHNpemVfcm93ID0gMTAsCiAgICAgICAgIGZvbnRzaXplX2NvbCA9IDEwLAogICAgICAgICBtYWluID0gIlNUQ0FUIFByZWRpY3Rpb24gdnMgUGF0aWVudHMiKQoKCiMgUHJvcG9ydGlvbiB0YWJsZSAoY29sb3Igc2NhbGUpCnByb3BfdGFibGUgPC0gcHJvcC50YWJsZSh0YWJsZV9hbm5vdGF0aW9uX3Rpc3N1ZSwgbWFyZ2luID0gMSkKCiMgSGVhdG1hcCB3aXRoIHJhdyBjb3VudHMgYXMgbGFiZWxzCnBoZWF0bWFwKHByb3BfdGFibGUsCiAgICAgICAgIGRpc3BsYXlfbnVtYmVycyA9IHRhYmxlX2Fubm90YXRpb25fdGlzc3VlLAogICAgICAgICBjbHVzdGVyX3Jvd3MgPSBUUlVFLAogICAgICAgICBjbHVzdGVyX2NvbHMgPSBUUlVFLAogICAgICAgICBjb2xvciA9IGNvbG9yUmFtcFBhbGV0dGUoYygibGlnaHR5ZWxsb3ciLCAieWVsbG93IiwgImxpZ2h0Z3JlZW4iLCAid2hpdGUiKSkoMTAwKSwKICAgICAgICAgZm9udHNpemVfcm93ID0gMTAsCiAgICAgICAgIGZvbnRzaXplX2NvbCA9IDEwLAogICAgICAgICBtYWluID0gIlNUQ0FUIFByZWRpY3Rpb24gdnMgUGF0aWVudHMiKQoKYGBgCgoKCgoKCiMgU2F2ZSB0aGUgU2V1cmF0IG9iamVjdCBhcyBhbiBSRFMKYGBge3Igc2F2ZVJEU30KCgpzYXZlUkRTKHNzX0hlcnJlcmEsIGZpbGUgPSAiU1RDQVQvQWxsX1BhdGllbnRzX0ludGVncmF0ZWRfc3NfSGVycmVyYV9hbm5vdGF0ZWQuUkRTIikKCgpgYGAKCgoKCg==