1 load libraries

2 Load and Subset Herrera Data

Idents(ctrl) <- "seurat_clusters"
table(ctrl@active.ident)

   2    3    0   12    6   17    5    4    1   15   14   18    9   13    7    8   11   16   10 
3241 1006  185  124  404   44  223 2278   92   48  183   10   84  150  230  923  727    4  829 

2.1 Reference data


reference <- scPred::pbmc_1
reference
An object of class Seurat 
32838 features across 3500 samples within 1 assay 
Active assay: RNA (32838 features, 0 variable features)
 2 layers present: counts, data

2.2 Reference data analysis




# Run SCTransform (normalization + variance stabilization)
reference <- SCTransform(reference, verbose = FALSE)

# Find variable features is done inside SCTransform, no need to run separately

# Run PCA on SCT assay
reference <- RunPCA(reference, assay = "SCT", verbose = FALSE, reduction.name = "pca")
Registered S3 method overwritten by 'rmarkdown':
  method         from
  print.paged_df     
# Run UMAP on PCA
reference <- RunUMAP(reference, dims = 1:30)
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
DimPlot(reference, group.by = "cell_type", label = TRUE, repel = TRUE) + NoAxes()

2.3 Run all steps of the analysis for the ctrl sample as well

DimPlot(ctrl, group.by = "seurat_clusters", label = TRUE, repel = TRUE) + NoAxes()

DimPlot(ctrl, group.by = "condition", label = TRUE, repel = TRUE) + NoAxes()

DimPlot(ctrl, group.by = "seurat_clusters", label = TRUE, repel = TRUE) + NoAxes()

2.4 Label transfer

# Set default assay to SCT
DefaultAssay(reference) <- "SCT"

# 1. Make sure SCT is the default assay in your query (ctrl)
DefaultAssay(ctrl) <- "RNA"

# 2. (Optional but recommended) Run SCTransform if not already done
# If you already normalized with SCTransform, you can skip this.
 ctrl <- SCTransform(ctrl, verbose = FALSE)

# 3. Find anchors between reference and query
transfer.anchors <- FindTransferAnchors(
    reference = reference,
    query = ctrl,
    normalization.method = "SCT",   # MUST be SCT
    reference.reduction = "pca",   # Azimuth references use spca
    dims = 1:30
)

# 4. Transfer annotations (cell types, etc.)
predictions <- TransferData(
    anchorset = transfer.anchors,
    refdata = reference$cell_type,  # column from reference metadata
    dims = 1:30
)
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
# 5. Add predictions back into your query object
ctrl <- AddMetaData(ctrl, metadata = predictions)

2.5 Dimplot-myumap


DimPlot(ctrl, group.by = "predicted.id", label = T, repel = T) + NoAxes()

2.6 barplot Distributions


ggplot(ctrl@meta.data, aes(x = seurat_clusters, fill = predicted.id)) +
    geom_bar() +
    theme_classic()

3 SinlgeR


 # make sure you are on Seurat >= 5
DefaultAssay(ctrl) <- "RNA"

# merge all RNA layers into one
ctrl <- JoinLayers(ctrl, assay = "RNA")

# now convert to SCE
sce <- as.SingleCellExperiment(ctrl, assay = "RNA")

3.1 Immune cell reference


 immune = celldex::DatabaseImmuneCellExpressionData()
singler.immune <- SingleR(test = sce, ref = immune, assay.type.test=1,
    labels = immune$label.fine)

head(singler.immune)
DataFrame with 6 rows and 4 columns
                                                          scores                 labels delta.next          pruned.labels
                                                        <matrix>            <character>  <numeric>            <character>
SS_SS1_Blood_H20_AAACGGGTCTGTACGA 0.126734:0.123792:0.127111:...     T cells, CD4+, Th2 0.01020391     T cells, CD4+, Th2
SS_SS1_Blood_H20_AAAGCAAAGTCCCACG 0.146714:0.150715:0.153418:...     T cells, CD4+, Th2 0.00787036     T cells, CD4+, Th2
SS_SS1_Blood_H20_AAAGTAGAGTTTCCTT 0.147983:0.135853:0.135882:...     T cells, CD4+, Th2 0.06289714     T cells, CD4+, Th2
SS_SS1_Blood_H20_AAAGTAGTCCACGACG 0.127739:0.115666:0.116248:...     T cells, CD4+, Th2 0.00174197     T cells, CD4+, Th2
SS_SS1_Blood_H20_AAATGCCCACCCATGG 0.140546:0.143729:0.155259:... T cells, CD4+, memor.. 0.00138212 T cells, CD4+, memor..
SS_SS1_Blood_H20_AACACGTAGCCCAATT 0.137978:0.121588:0.138889:...     T cells, CD4+, Th2 0.00429020     T cells, CD4+, Th2

3.2 HPCA reference


hpca <- celldex::HumanPrimaryCellAtlasData()
singler.hpca <- SingleR(test = sce, ref = hpca, assay.type.test=1,
    labels = hpca$label.fine)

head(singler.hpca)
DataFrame with 6 rows and 4 columns
                                                          scores                 labels delta.next          pruned.labels
                                                        <matrix>            <character>  <numeric>            <character>
SS_SS1_Blood_H20_AAACGGGTCTGTACGA 0.158345:0.252571:0.222786:... T_cell:CD4+_central_..  0.1610613 T_cell:CD4+_central_..
SS_SS1_Blood_H20_AAAGCAAAGTCCCACG 0.167377:0.305519:0.274721:... T_cell:CD4+_central_..  0.1069279 T_cell:CD4+_central_..
SS_SS1_Blood_H20_AAAGTAGAGTTTCCTT 0.182532:0.312291:0.278981:... T_cell:CD4+_central_..  0.0303539 T_cell:CD4+_central_..
SS_SS1_Blood_H20_AAAGTAGTCCACGACG 0.168245:0.274507:0.247855:... T_cell:CD4+_effector..  0.0999581 T_cell:CD4+_effector..
SS_SS1_Blood_H20_AAATGCCCACCCATGG 0.182977:0.305724:0.273373:... T_cell:CD4+_central_..  0.0980566 T_cell:CD4+_central_..
SS_SS1_Blood_H20_AACACGTAGCCCAATT 0.175543:0.282729:0.252079:... T_cell:CD4+_effector..  0.0399778 T_cell:CD4+_effector..

3.3 Compare results:


ctrl$singler.immune = singler.immune$pruned.labels
ctrl$singler.hpca = singler.hpca$pruned.labels

3.4 Compare results:



DimPlot(ctrl, group.by = "singler.hpca", label = T, repel = T) + NoAxes()

DimPlot(ctrl, group.by = "singler.immune", label = T, repel = T) + NoAxes()

NA
NA

3.5 Compare results:



DimPlot(ctrl, group.by = c("singler.hpca", "singler.immune"), ncol = 2, label = T, label.box = T, repel = T)

3.6 Compare results:


ctrl$singler.immune = singler.immune$pruned.labels
ctrl$singler.hpca = singler.hpca$pruned.labels


DimPlot(ctrl, group.by = c("singler.hpca", "singler.immune"), ncol = 2, label = F, label.box = F, repel = T)

4 Azimuth

options(future.globals.maxSize = 1e9)

library(SeuratData)

DefaultAssay(ctrl) <- "SCT"

ctrl <- RunAzimuth(ctrl, reference = "pbmcref")
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

  |                                                  | 0 % ~calculating  
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=01s  
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

4.1 Azimuth Dimplot

DimPlot(ctrl, group.by = "predicted.celltype.l1", label = T, repel = T) + NoAxes()


DimPlot(ctrl, group.by = "predicted.celltype.l2", label = T, repel = T) + NoAxes()


DimPlot(ctrl, group.by = "predicted.celltype.l3", label = T, repel = T) + NoAxes()

5 ProjectTils Annotation_CD4T_human_ref_v1

6 Compare results from all Annotation methods


crossTab(ctrl, "predicted.id", "singler.hpca")

crossTab(ctrl, "predicted.id", "singler.immune")

crossTab(ctrl, "singler.hpca", "singler.immune")

crossTab(ctrl, "predicted.id", "predicted.celltype.l1")

crossTab(ctrl, "predicted.celltype.l2", "functional.cluster")
NA

6.1 Compare results


wrap_plots(
    DimPlot(ctrl, label = T, group.by = "predicted.id") + NoAxes() + ggtitle("LabelTransfer"),
    DimPlot(ctrl, label = F, group.by = "singler.hpca" ) + NoAxes() + ggtitle("SingleR HPCA"),
    DimPlot(ctrl, label = F, group.by = "singler.immune") + NoAxes() + ggtitle("SingleR Ref"),
    DimPlot(ctrl, label = T, group.by = "predicted.celltype.l1") + NoAxes() + ggtitle("Azimuth l1"),
    ncol = 2
)

6.2 Compare results


wrap_plots(
    DimPlot(ctrl, label = T, group.by = "predicted.id") + NoAxes() + ggtitle("LabelTransfer"),
    DimPlot(ctrl, label = F, group.by = "singler.hpca") + NoAxes() + ggtitle("SingleR HPCA"),
    DimPlot(ctrl, label = F, group.by = "singler.immune") + NoAxes() + ggtitle("SingleR Ref"),
    DimPlot(ctrl, label = F, group.by = "predicted.celltype.l2") + NoAxes() + ggtitle("LabelTransfer"),
    DimPlot(ctrl, label = T, group.by = "functional.cluster") + NoAxes() + ggtitle("ProjecTils CD4")
  
)

7 save all the annotation in object into RDS


# Save the Seurat object with all annotations
saveRDS(ctrl, file = "All_samples_Merged_with_all_annotations_ATLAS-Herrera-03-02-2026.rds")
LS0tCnRpdGxlOiAiQ2VsbHR5cGUgUHJlZGljdGlvbiB1c2luZyBIZXJyZXJhIGRhdGEiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogdHJ1ZQogICAgdGhlbWU6IGpvdXJuYWwKLS0tCgoKIyBsb2FkIGxpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KCiAgICBsaWJyYXJ5KFNldXJhdCkKICAgIGxpYnJhcnkoZHBseXIpCiAgICBsaWJyYXJ5KHBhdGNod29yaykKICAgIGxpYnJhcnkoZ2dwbG90MikKICAgIGxpYnJhcnkocGhlYXRtYXApCiAgICBsaWJyYXJ5KHNjUHJlZCkKICAgIGxpYnJhcnkoY2VsbGRleCkKICAgIGxpYnJhcnkoU2luZ2xlUikKICAgIGxpYnJhcnkocmVtb3RlcykKICAgIGxpYnJhcnkocHJlc3RvKQogICAgbGlicmFyeShTZXVyYXREaXNrKQogICAgbGlicmFyeShTZXVyYXREYXRhKQogICAgbGlicmFyeShBemltdXRoKQoKYGBgCgoKIyBMb2FkIGFuZCBTdWJzZXQgSGVycmVyYSBEYXRhCmBgYHtyIGxvYWRTZXVyYXR9CgpjdHJsIDwtIHJlYWRSRFMoIi9ob21lL2Jpb2luZm8vMS1UaGVzaXNfRmluYWxfWWVhcl8yMDI1LzIwMjUtWWVhcjNfQW5hbHlzaXMvMS1zY1JOQV9SRVNVTFRTLTE5LTExLTIwMjUvMS1CaW9tYXJrZXJzX1ZhbGlkYXRpb25fd2l0aF9QdWJsaWNfRGF0YS1BdWd1c3QyMDI1L0hlcnJlcmFfRGF0YS9IZXJyYXJhX1RDUl9BQi9BbmFseXNpcy9TZXphcnlfQmxvb2RfU2tpbl92c19IQ19UQ1JfZmlsdGVyZWQucmRzIikKCklkZW50cyhjdHJsKSA8LSAic2V1cmF0X2NsdXN0ZXJzIgp0YWJsZShjdHJsQGFjdGl2ZS5pZGVudCkKCgpgYGAKCgojIyBSZWZlcmVuY2UgZGF0YQpgYGB7cn0KCnJlZmVyZW5jZSA8LSBzY1ByZWQ6OnBibWNfMQpyZWZlcmVuY2UKCmBgYAoKCiMjIFJlZmVyZW5jZSBkYXRhIGFuYWx5c2lzCmBgYHtyfQoKCgojIFJ1biBTQ1RyYW5zZm9ybSAobm9ybWFsaXphdGlvbiArIHZhcmlhbmNlIHN0YWJpbGl6YXRpb24pCnJlZmVyZW5jZSA8LSBTQ1RyYW5zZm9ybShyZWZlcmVuY2UsIHZlcmJvc2UgPSBGQUxTRSkKCiMgRmluZCB2YXJpYWJsZSBmZWF0dXJlcyBpcyBkb25lIGluc2lkZSBTQ1RyYW5zZm9ybSwgbm8gbmVlZCB0byBydW4gc2VwYXJhdGVseQoKIyBSdW4gUENBIG9uIFNDVCBhc3NheQpyZWZlcmVuY2UgPC0gUnVuUENBKHJlZmVyZW5jZSwgYXNzYXkgPSAiU0NUIiwgdmVyYm9zZSA9IEZBTFNFLCByZWR1Y3Rpb24ubmFtZSA9ICJwY2EiKQoKCiMgUnVuIFVNQVAgb24gUENBCnJlZmVyZW5jZSA8LSBSdW5VTUFQKHJlZmVyZW5jZSwgZGltcyA9IDE6MzApCgoKRGltUGxvdChyZWZlcmVuY2UsIGdyb3VwLmJ5ID0gImNlbGxfdHlwZSIsIGxhYmVsID0gVFJVRSwgcmVwZWwgPSBUUlVFKSArIE5vQXhlcygpCgpgYGAKCiMjIFJ1biBhbGwgc3RlcHMgb2YgdGhlIGFuYWx5c2lzIGZvciB0aGUgY3RybCBzYW1wbGUgYXMgd2VsbApgYGB7cn0KRGltUGxvdChjdHJsLCBncm91cC5ieSA9ICJzZXVyYXRfY2x1c3RlcnMiLCBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVFJVRSkgKyBOb0F4ZXMoKQpEaW1QbG90KGN0cmwsIGdyb3VwLmJ5ID0gImNvbmRpdGlvbiIsIGxhYmVsID0gVFJVRSwgcmVwZWwgPSBUUlVFKSArIE5vQXhlcygpCkRpbVBsb3QoY3RybCwgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIiwgbGFiZWwgPSBUUlVFLCByZXBlbCA9IFRSVUUpICsgTm9BeGVzKCkKCmBgYAoKIyMgTGFiZWwgdHJhbnNmZXIKYGBge3J9CiMgU2V0IGRlZmF1bHQgYXNzYXkgdG8gU0NUCkRlZmF1bHRBc3NheShyZWZlcmVuY2UpIDwtICJTQ1QiCgojIDEuIE1ha2Ugc3VyZSBTQ1QgaXMgdGhlIGRlZmF1bHQgYXNzYXkgaW4geW91ciBxdWVyeSAoY3RybCkKRGVmYXVsdEFzc2F5KGN0cmwpIDwtICJSTkEiCgojIDIuIChPcHRpb25hbCBidXQgcmVjb21tZW5kZWQpIFJ1biBTQ1RyYW5zZm9ybSBpZiBub3QgYWxyZWFkeSBkb25lCiMgSWYgeW91IGFscmVhZHkgbm9ybWFsaXplZCB3aXRoIFNDVHJhbnNmb3JtLCB5b3UgY2FuIHNraXAgdGhpcy4KIGN0cmwgPC0gU0NUcmFuc2Zvcm0oY3RybCwgdmVyYm9zZSA9IEZBTFNFKQoKIyAzLiBGaW5kIGFuY2hvcnMgYmV0d2VlbiByZWZlcmVuY2UgYW5kIHF1ZXJ5CnRyYW5zZmVyLmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycygKICAgIHJlZmVyZW5jZSA9IHJlZmVyZW5jZSwKICAgIHF1ZXJ5ID0gY3RybCwKICAgIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIlNDVCIsICAgIyBNVVNUIGJlIFNDVAogICAgcmVmZXJlbmNlLnJlZHVjdGlvbiA9ICJwY2EiLCAgICMgQXppbXV0aCByZWZlcmVuY2VzIHVzZSBzcGNhCiAgICBkaW1zID0gMTozMAopCgojIDQuIFRyYW5zZmVyIGFubm90YXRpb25zIChjZWxsIHR5cGVzLCBldGMuKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoCiAgICBhbmNob3JzZXQgPSB0cmFuc2Zlci5hbmNob3JzLAogICAgcmVmZGF0YSA9IHJlZmVyZW5jZSRjZWxsX3R5cGUsICAjIGNvbHVtbiBmcm9tIHJlZmVyZW5jZSBtZXRhZGF0YQogICAgZGltcyA9IDE6MzAKKQoKIyA1LiBBZGQgcHJlZGljdGlvbnMgYmFjayBpbnRvIHlvdXIgcXVlcnkgb2JqZWN0CmN0cmwgPC0gQWRkTWV0YURhdGEoY3RybCwgbWV0YWRhdGEgPSBwcmVkaWN0aW9ucykKCgpgYGAKCgojIyBEaW1wbG90LW15dW1hcApgYGB7cn0KCkRpbVBsb3QoY3RybCwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmlkIiwgbGFiZWwgPSBULCByZXBlbCA9IFQpICsgTm9BeGVzKCkKCmBgYAojIyBiYXJwbG90IERpc3RyaWJ1dGlvbnMKYGBge3J9CgpnZ3Bsb3QoY3RybEBtZXRhLmRhdGEsIGFlcyh4ID0gc2V1cmF0X2NsdXN0ZXJzLCBmaWxsID0gcHJlZGljdGVkLmlkKSkgKwogICAgZ2VvbV9iYXIoKSArCiAgICB0aGVtZV9jbGFzc2ljKCkKCmBgYAoKCiMgU2lubGdlUgpgYGB7cn0KCiAjIG1ha2Ugc3VyZSB5b3UgYXJlIG9uIFNldXJhdCA+PSA1CkRlZmF1bHRBc3NheShjdHJsKSA8LSAiUk5BIgoKIyBtZXJnZSBhbGwgUk5BIGxheWVycyBpbnRvIG9uZQpjdHJsIDwtIEpvaW5MYXllcnMoY3RybCwgYXNzYXkgPSAiUk5BIikKCiMgbm93IGNvbnZlcnQgdG8gU0NFCnNjZSA8LSBhcy5TaW5nbGVDZWxsRXhwZXJpbWVudChjdHJsLCBhc3NheSA9ICJSTkEiKQoKCmBgYAoKCgoKCiMjIEltbXVuZSBjZWxsIHJlZmVyZW5jZQpgYGB7cn0KCiBpbW11bmUgPSBjZWxsZGV4OjpEYXRhYmFzZUltbXVuZUNlbGxFeHByZXNzaW9uRGF0YSgpCnNpbmdsZXIuaW1tdW5lIDwtIFNpbmdsZVIodGVzdCA9IHNjZSwgcmVmID0gaW1tdW5lLCBhc3NheS50eXBlLnRlc3Q9MSwKICAgIGxhYmVscyA9IGltbXVuZSRsYWJlbC5maW5lKQoKaGVhZChzaW5nbGVyLmltbXVuZSkKCmBgYAoKCgoKCgojIyBIUENBIHJlZmVyZW5jZQpgYGB7cn0KCmhwY2EgPC0gY2VsbGRleDo6SHVtYW5QcmltYXJ5Q2VsbEF0bGFzRGF0YSgpCnNpbmdsZXIuaHBjYSA8LSBTaW5nbGVSKHRlc3QgPSBzY2UsIHJlZiA9IGhwY2EsIGFzc2F5LnR5cGUudGVzdD0xLAogICAgbGFiZWxzID0gaHBjYSRsYWJlbC5maW5lKQoKaGVhZChzaW5nbGVyLmhwY2EpCgpgYGAKCgojIyBDb21wYXJlIHJlc3VsdHM6CmBgYHtyLCAgZmlnLmhlaWdodD0gMTIsIGZpZy53aWR0aD0gMTR9CgpjdHJsJHNpbmdsZXIuaW1tdW5lID0gc2luZ2xlci5pbW11bmUkcHJ1bmVkLmxhYmVscwpjdHJsJHNpbmdsZXIuaHBjYSA9IHNpbmdsZXIuaHBjYSRwcnVuZWQubGFiZWxzCgpgYGAKCiMjIENvbXBhcmUgcmVzdWx0czoKYGBge3IsICBmaWcuaGVpZ2h0PSAxMiwgZmlnLndpZHRoPSAxNH0KCgpEaW1QbG90KGN0cmwsIGdyb3VwLmJ5ID0gInNpbmdsZXIuaHBjYSIsIGxhYmVsID0gVCwgcmVwZWwgPSBUKSArIE5vQXhlcygpCkRpbVBsb3QoY3RybCwgZ3JvdXAuYnkgPSAic2luZ2xlci5pbW11bmUiLCBsYWJlbCA9IFQsIHJlcGVsID0gVCkgKyBOb0F4ZXMoKQoKCmBgYAoKIyMgQ29tcGFyZSByZXN1bHRzOgpgYGB7ciwgIGZpZy5oZWlnaHQ9IDEyLCBmaWcud2lkdGg9IDMwfQoKCkRpbVBsb3QoY3RybCwgZ3JvdXAuYnkgPSBjKCJzaW5nbGVyLmhwY2EiLCAic2luZ2xlci5pbW11bmUiKSwgbmNvbCA9IDIsIGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCwgcmVwZWwgPSBUKQoKYGBgCiMjIENvbXBhcmUgcmVzdWx0czoKYGBge3IsIGZpZy5oZWlnaHQ9IDYsIGZpZy53aWR0aD0gMjB9CgpjdHJsJHNpbmdsZXIuaW1tdW5lID0gc2luZ2xlci5pbW11bmUkcHJ1bmVkLmxhYmVscwpjdHJsJHNpbmdsZXIuaHBjYSA9IHNpbmdsZXIuaHBjYSRwcnVuZWQubGFiZWxzCgoKRGltUGxvdChjdHJsLCBncm91cC5ieSA9IGMoInNpbmdsZXIuaHBjYSIsICJzaW5nbGVyLmltbXVuZSIpLCBuY29sID0gMiwgbGFiZWwgPSBGLCBsYWJlbC5ib3ggPSBGLCByZXBlbCA9IFQpCgpgYGAKCgojIEF6aW11dGgKYGBge3J9Cm9wdGlvbnMoZnV0dXJlLmdsb2JhbHMubWF4U2l6ZSA9IDFlOSkKCmxpYnJhcnkoU2V1cmF0RGF0YSkKCkRlZmF1bHRBc3NheShjdHJsKSA8LSAiU0NUIgoKY3RybCA8LSBSdW5BemltdXRoKGN0cmwsIHJlZmVyZW5jZSA9ICJwYm1jcmVmIikKCmBgYAoKIyMgQXppbXV0aCBEaW1wbG90CmBgYHtyLCBmaWcuaGVpZ2h0PSA2LCBmaWcud2lkdGg9IDEwfQpEaW1QbG90KGN0cmwsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMSIsIGxhYmVsID0gVCwgcmVwZWwgPSBUKSArIE5vQXhlcygpCgpEaW1QbG90KGN0cmwsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsIGxhYmVsID0gVCwgcmVwZWwgPSBUKSArIE5vQXhlcygpCgpEaW1QbG90KGN0cmwsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMyIsIGxhYmVsID0gVCwgcmVwZWwgPSBUKSArIE5vQXhlcygpCgpgYGAKCgoKIyBQcm9qZWN0VGlscyBBbm5vdGF0aW9uX0NENFRfaHVtYW5fcmVmX3YxCmBgYHtyfQpsaWJyYXJ5KFNUQUNBUykKbGlicmFyeShQcm9qZWNUSUxzKQoKCiNMb2FkIHJlZmVyZW5jZSBhdGxhcyBhbmQgcXVlcnkgZGF0YQogcmVmIDwtIHJlYWRSRFMoZmlsZSA9ICJDRDRUX2h1bWFuX3JlZl92MS5yZHMiKQoKcXVlcnkucHJvamVjdGVkIDwtIFByb2plY1RJTHMuY2xhc3NpZmllcihxdWVyeSA9IGN0cmwsIHJlZiA9IHJlZikKCgojcmVmZXJlbmNlIGF0bGFzCiBEaW1QbG90KHJlZiwgbGFiZWwgPSBUKQogCiAKCgogI1Bsb3QgdGhlIHByZWRpY3RlZCBjb21wb3NpdGlvbiBvZiB0aGUgcXVlcnkgaW4gdGVybXMgb2YgcmVmZXJlbmNlIFQgY2VsbCBzdWJ0eXBlcwogcGxvdC5zdGF0ZXByZWQuY29tcG9zaXRpb24ocmVmLCBxdWVyeS5wcm9qZWN0ZWQsIG1ldHJpYyA9ICJQZXJjZW50IikKCgoKIyBOb3cgeW91IGNhbiBwbG90CkRpbVBsb3QoY3RybCwgZ3JvdXAuYnkgPSAiZnVuY3Rpb25hbC5jbHVzdGVyIiwgCiAgICAgICAgcmVkdWN0aW9uID0gInVtYXAiLAogICAgICAgIGxhYmVsLnNpemUgPSAzLAogICAgICAgIHJlcGVsID0gVFJVRSwKICAgICAgICBsYWJlbCA9IEZBTFNFKQogCiAKCmBgYAoKIyAgQ29tcGFyZSByZXN1bHRzIGZyb20gYWxsIEFubm90YXRpb24gbWV0aG9kcwpgYGB7cn0KCmNyb3NzVGFiKGN0cmwsICJwcmVkaWN0ZWQuaWQiLCAic2luZ2xlci5ocGNhIikKCmNyb3NzVGFiKGN0cmwsICJwcmVkaWN0ZWQuaWQiLCAic2luZ2xlci5pbW11bmUiKQoKY3Jvc3NUYWIoY3RybCwgInNpbmdsZXIuaHBjYSIsICJzaW5nbGVyLmltbXVuZSIpCgpjcm9zc1RhYihjdHJsLCAicHJlZGljdGVkLmlkIiwgInByZWRpY3RlZC5jZWxsdHlwZS5sMSIpCgpjcm9zc1RhYihjdHJsLCAicHJlZGljdGVkLmNlbGx0eXBlLmwyIiwgImZ1bmN0aW9uYWwuY2x1c3RlciIpCgpgYGAKCiMjICBDb21wYXJlIHJlc3VsdHMKYGBge3IsIGZpZy5oZWlnaHQ9IDgsIGZpZy53aWR0aD0gMjB9Cgp3cmFwX3Bsb3RzKAogICAgRGltUGxvdChjdHJsLCBsYWJlbCA9IFQsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5pZCIpICsgTm9BeGVzKCkgKyBnZ3RpdGxlKCJMYWJlbFRyYW5zZmVyIiksCiAgICBEaW1QbG90KGN0cmwsIGxhYmVsID0gRiwgZ3JvdXAuYnkgPSAic2luZ2xlci5ocGNhIiApICsgTm9BeGVzKCkgKyBnZ3RpdGxlKCJTaW5nbGVSIEhQQ0EiKSwKICAgIERpbVBsb3QoY3RybCwgbGFiZWwgPSBGLCBncm91cC5ieSA9ICJzaW5nbGVyLmltbXVuZSIpICsgTm9BeGVzKCkgKyBnZ3RpdGxlKCJTaW5nbGVSIFJlZiIpLAogICAgRGltUGxvdChjdHJsLCBsYWJlbCA9IFQsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMSIpICsgTm9BeGVzKCkgKyBnZ3RpdGxlKCJBemltdXRoIGwxIiksCiAgICBuY29sID0gMgopCgpgYGAKCgojIyAgQ29tcGFyZSByZXN1bHRzCmBgYHtyLCBmaWcuaGVpZ2h0PSAxMiwgZmlnLndpZHRoPSAyMH0KCndyYXBfcGxvdHMoCiAgICBEaW1QbG90KGN0cmwsIGxhYmVsID0gVCwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmlkIikgKyBOb0F4ZXMoKSArIGdndGl0bGUoIkxhYmVsVHJhbnNmZXIiKSwKICAgIERpbVBsb3QoY3RybCwgbGFiZWwgPSBGLCBncm91cC5ieSA9ICJzaW5nbGVyLmhwY2EiKSArIE5vQXhlcygpICsgZ2d0aXRsZSgiU2luZ2xlUiBIUENBIiksCiAgICBEaW1QbG90KGN0cmwsIGxhYmVsID0gRiwgZ3JvdXAuYnkgPSAic2luZ2xlci5pbW11bmUiKSArIE5vQXhlcygpICsgZ2d0aXRsZSgiU2luZ2xlUiBSZWYiKSwKICAgIERpbVBsb3QoY3RybCwgbGFiZWwgPSBGLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiKSArIE5vQXhlcygpICsgZ2d0aXRsZSgiTGFiZWxUcmFuc2ZlciIpLAogICAgRGltUGxvdChjdHJsLCBsYWJlbCA9IFQsIGdyb3VwLmJ5ID0gImZ1bmN0aW9uYWwuY2x1c3RlciIpICsgTm9BeGVzKCkgKyBnZ3RpdGxlKCJQcm9qZWNUaWxzIENENCIpCiAgCikKCmBgYAoKIyBzYXZlIGFsbCB0aGUgYW5ub3RhdGlvbiBpbiBvYmplY3QgaW50byBSRFMKYGBge3J9CgojIFNhdmUgdGhlIFNldXJhdCBvYmplY3Qgd2l0aCBhbGwgYW5ub3RhdGlvbnMKc2F2ZVJEUyhjdHJsLCBmaWxlID0gIkFsbF9zYW1wbGVzX01lcmdlZF93aXRoX2FsbF9hbm5vdGF0aW9uc19BVExBUy1IZXJyZXJhLTAzLTAyLTIwMjYucmRzIikKCmBgYAo=