1. load libraries

2. Load Seurat Object


#Load Seurat Object merged from cell lines and a control(PBMC) after filtration and Annotation
SS_All_samples_Merged <- load("SS_All_Sample_Merged_Azimuth_ProjectTils_singleR_ANNOTATION_on_My_UMAP0.7_HPC.Robj")

All_samples_Merged
An object of class Seurat 
63193 features across 49193 samples within 6 assays 
Active assay: SCT (26469 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
 4 dimensional reductions calculated: pca, umap, integrated_dr, ref.umap

3. QC Visualization



VlnPlot(
  All_samples_Merged,
  features = c("nFeature_RNA",
               "nCount_RNA",
               "percent.mito"),
  ncol = 3
)


FeatureScatter(All_samples_Merged,
               feature1 = "nCount_RNA",
               feature2 = "nFeature_RNA") +
  geom_smooth(method = 'lm')

##FeatureScatter is typically used to visualize feature-feature relationships ##for anything calculated by the object, ##i.e. columns in object metadata, PC scores etc.


FeatureScatter(All_samples_Merged, 
               feature1 = "nCount_RNA", 
               feature2 = "percent.mito")+
  geom_smooth(method = 'lm')


FeatureScatter(All_samples_Merged, 
               feature1 = "nCount_RNA", 
               feature2 = "nFeature_RNA")+
  geom_smooth(method = 'lm')

4. Normalize data



# Apply SCTransform
#All_samples_Merged <- SCTransform(All_samples_Merged, verbose = TRUE)
                                      

5. Perform PCA


# Variables_genes <- All_samples_Merged@assays$SCT@var.features
# 
# # Exclude genes starting with "HLA-" or "Xist"
# Variables_genes_after_exclusion <- Variables_genes[!grepl("^HLA-|^Xist", Variables_genes)]
# 
# 
# # These are now standard steps in the Seurat workflow for visualization and clustering
# All_samples_Merged <- RunPCA(All_samples_Merged,
#                         features = Variables_genes_after_exclusion,
#                         do.print = TRUE, 
#                         pcs.print = 1:5, 
#                         genes.print = 15)

# determine dimensionality of the data
ElbowPlot(All_samples_Merged)

6. Clustering

# All_samples_Merged <- FindNeighbors(All_samples_Merged, 
#                                 dims = 1:8, 
#                                 verbose = FALSE)
# 
# # understanding resolution
# All_samples_Merged <- FindClusters(All_samples_Merged, 
#                                     resolution = 1.2)

# non-linear dimensionality reduction --------------
# All_samples_Merged <- RunUMAP(All_samples_Merged, 
#                           dims = 1:8,
#                           verbose = FALSE)
                                  

# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
UMAPPlot(All_samples_Merged,group.by = "cell_line", 
        reduction = "umap",
        label.size = 3,
        repel = T,
        label = T)


UMAPPlot(All_samples_Merged,
        group.by = "SCT_snn_res.0.7", 
        reduction = "umap",
        label.size = 3,
        repel = T,
        label = T)


cluster_table <- table(Idents(All_samples_Merged))

head(cluster_table)

   0    1    2    3    4    5 
5521 5259 5230 3959 3866 3649 

7. Azimuth Annotation

# InstallData("pbmcsca")
# 
# UpdateSeuratObject("pbmcsca")
# 
# # The RunAzimuth function can take a Seurat object as input
# All_samples_Merged <- RunAzimuth(All_samples_Merged, reference = "pbmcsca")

DimPlot(All_samples_Merged,
        pt.size = 1,
         group.by = "predicted.celltype.l1",
         label = FALSE,
         label.size = 4)


DimPlot(All_samples_Merged,
        pt.size = 1,
         group.by = "predicted.celltype.l2",
         label = FALSE,
         label.size = 4)


DimPlot(All_samples_Merged,
        pt.size = 1,
         group.by = "predicted.celltype.l3",
         label = FALSE,
         label.size = 4)

8. ProjectTils Annotation

#Load reference atlas and query data
# ref <- readRDS(file = "CD4T_human_ref_v1.rds")
# 
# #Run Projection algorithm
# query.projected <- Run.ProjecTILs(All_samples_Merged, ref = ref)



#reference atlas
# DimPlot(ref, label = T)

#Visualize projection
# plot.projection(ref, query.projected, linesize = 0.5, pointsize = 0.5)
# 
# #Plot the predicted composition of the query in terms of reference T cell subtypes
# plot.statepred.composition(ref, query.projected, metric = "Percent")


#All_samples_Merged <- ProjecTILs.classifier(query = All_samples_Merged, ref = ref)
UMAPPlot(All_samples_Merged, group.by = "functional.cluster", 
        reduction = "umap",
        label.size = 3,
        repel = T,
        label = F)

9.SingleR Annotation

#get reference datasets from celldex package

# monaco.ref <- celldex::MonacoImmuneData()
# hpca.ref <- celldex::HumanPrimaryCellAtlasData()
# dice.ref <- celldex::DatabaseImmuneCellExpressionData()
# bpe.ref <- celldex::BlueprintEncodeData()
# 
# #convert our Seurat object to single cell experiment (SCE)
# sce <- as.SingleCellExperiment(DietSeurat(All_samples_Merged))
# 
# #using SingleR
# monaco.main <- SingleR(test = sce,assay.type.test = 1,ref = monaco.ref,labels = monaco.ref$label.main)
# monaco.fine <- SingleR(test = sce,assay.type.test = 1,ref = monaco.ref,labels = monaco.ref$label.fine)
# hpca.main <- SingleR(test = sce,assay.type.test = 1,ref = hpca.ref,labels = hpca.ref$label.main)
# hpca.fine <- SingleR(test = sce,assay.type.test = 1,ref = hpca.ref,labels = hpca.ref$label.fine)
# dice.main <- SingleR(test = sce,assay.type.test = 1,ref = dice.ref,labels = dice.ref$label.main)
# dice.fine <- SingleR(test = sce,assay.type.test = 1,ref = dice.ref,labels = dice.ref$label.fine)
# bpe.main <- SingleR(test = sce,assay.type.test = 1,ref = bpe.ref,labels = bpe.ref$label.main)
# bpe.fine <- SingleR(test = sce,assay.type.test = 1,ref = bpe.ref,labels = bpe.ref$label.fine)
# 

#summary of general cell type annotations

#table(monaco.main$pruned.labels)
#table(hpca.main$pruned.labels)
#table(dice.main$pruned.labels)
#table(bpe.main$pruned.labels)

#The finer cell types annotations are you after, the harder they are to get reliably. 
#This is where comparing many databases, as well as using individual markers from literature, 
#would all be very valuable.

#table(monaco.fine$pruned.labels)
#table(hpca.fine$pruned.labels)
#table(dice.fine$pruned.labels)
#table(bpe.fine$pruned.labels)



#add the annotations to the Seurat object metadata
# All_samples_Merged@meta.data$monaco.main <- monaco.main$pruned.labels
# All_samples_Merged@meta.data$monaco.fine <- monaco.fine$pruned.labels
# #
# All_samples_Merged@meta.data$hpca.main   <- hpca.main$pruned.labels
# All_samples_Merged@meta.data$hpca.fine   <- hpca.fine$pruned.labels
# #  
# All_samples_Merged@meta.data$dice.main   <- dice.main$pruned.labels
# All_samples_Merged@meta.data$dice.fine   <- dice.fine$pruned.labels
# # 
# All_samples_Merged@meta.data$bpe.main   <- bpe.main$pruned.labels
# All_samples_Merged@meta.data$bpe.fine   <- bpe.fine$pruned.labels


All_samples_Merged <- SetIdent(All_samples_Merged, value = "hpca.main")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 



 All_samples_Merged <- SetIdent(All_samples_Merged, value = "hpca.fine")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  
  
  All_samples_Merged <- SetIdent(All_samples_Merged, value = "dice.main")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 



 All_samples_Merged <- SetIdent(All_samples_Merged, value = "dice.fine")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 

  
  All_samples_Merged <- SetIdent(All_samples_Merged, value = "bpe.main")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 



 All_samples_Merged <- SetIdent(All_samples_Merged, value = "bpe.fine")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 




All_samples_Merged <- SetIdent(All_samples_Merged, value = "monaco.main")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 



 All_samples_Merged <- SetIdent(All_samples_Merged, value = "monaco.fine")
  DimPlot(All_samples_Merged, label = F , repel = T, label.size = 3) 

  DimPlot(All_samples_Merged, label = T , repel = T, label.size = 3) 

NA
LS0tCnRpdGxlOiAiVU1BUCB3aXRob3V0IGNvcnJlY3Rpb24rQW5ub3RhdGVkIgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICIyMDI0LTA0LTIzIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQogICAgdGhlbWU6IGRhcmtseQotLS0KCiMgMS4gbG9hZCBsaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKbGlicmFyeShwYXRjaHdvcmspCiMgCiMgbGlicmFyeShkcGx5cikKIyBsaWJyYXJ5KHRpZHl2ZXJzZSkKIyBsaWJyYXJ5KGdncGxvdDIpCiMgbGlicmFyeShSQ29sb3JCcmV3ZXIpCiMgbGlicmFyeShtYWdyaXR0cikKIyBsaWJyYXJ5KGRicGx5cikKIyBsaWJyYXJ5KHJtYXJrZG93bikKIyBsaWJyYXJ5KGtuaXRyKQojIGxpYnJhcnkodGlueXRleCkKIyAjQXppbXV0aCBBbm5vdGF0aW9uIGxpYnJhcmllcwojIGxpYnJhcnkoQXppbXV0aCkKIyAjUHJvamVjVGlscyBBbm5vdGF0aW9uIGxpYnJhcmllcwojIGxpYnJhcnkoU1RBQ0FTKQojIGxpYnJhcnkoUHJvamVjVElMcykKIyAjc2luZ2xlUiBBbm5vdGF0aW9uIGxpYnJhcmllcwojIGxpYnJhcnkoU2luZ2xlUikKIyBsaWJyYXJ5KGNlbGxkZXgpCiMgbGlicmFyeShTaW5nbGVDZWxsRXhwZXJpbWVudCkKCgpgYGAKIyAyLiBMb2FkIFNldXJhdCBPYmplY3QgCmBgYHtyIGxvYWRfc2V1cmF0fQoKI0xvYWQgU2V1cmF0IE9iamVjdCBtZXJnZWQgZnJvbSBjZWxsIGxpbmVzIGFuZCBhIGNvbnRyb2woUEJNQykgYWZ0ZXIgZmlsdHJhdGlvbiBhbmQgQW5ub3RhdGlvbgpTU19BbGxfc2FtcGxlc19NZXJnZWQgPC0gbG9hZCgiU1NfQWxsX1NhbXBsZV9NZXJnZWRfQXppbXV0aF9Qcm9qZWN0VGlsc19zaW5nbGVSX0FOTk9UQVRJT05fb25fTXlfVU1BUDAuN19IUEMuUm9iaiIpCgpBbGxfc2FtcGxlc19NZXJnZWQKYGBgCiMgMy4gUUMgVmlzdWFsaXphdGlvbgpgYGB7ciBRQywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgoKVmxuUGxvdCgKICBBbGxfc2FtcGxlc19NZXJnZWQsCiAgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLAogICAgICAgICAgICAgICAibkNvdW50X1JOQSIsCiAgICAgICAgICAgICAgICJwZXJjZW50Lm1pdG8iKSwKICBuY29sID0gMwopCgpGZWF0dXJlU2NhdHRlcihBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgICAgICAgIGZlYXR1cmUxID0gIm5Db3VudF9STkEiLAogICAgICAgICAgICAgICBmZWF0dXJlMiA9ICJuRmVhdHVyZV9STkEiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJykKCmBgYAoKIyNGZWF0dXJlU2NhdHRlciBpcyB0eXBpY2FsbHkgdXNlZCB0byB2aXN1YWxpemUgZmVhdHVyZS1mZWF0dXJlIHJlbGF0aW9uc2hpcHMKIyNmb3IgYW55dGhpbmcgY2FsY3VsYXRlZCBieSB0aGUgb2JqZWN0LCAKIyNpLmUuIGNvbHVtbnMgaW4gb2JqZWN0IG1ldGFkYXRhLCBQQyBzY29yZXMgZXRjLgoKYGBge3IgRkMsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKRmVhdHVyZVNjYXR0ZXIoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKICAgICAgICAgICAgICAgZmVhdHVyZTEgPSAibkNvdW50X1JOQSIsIAogICAgICAgICAgICAgICBmZWF0dXJlMiA9ICJwZXJjZW50Lm1pdG8iKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nKQoKRmVhdHVyZVNjYXR0ZXIoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKICAgICAgICAgICAgICAgZmVhdHVyZTEgPSAibkNvdW50X1JOQSIsIAogICAgICAgICAgICAgICBmZWF0dXJlMiA9ICJuRmVhdHVyZV9STkEiKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nKQoKYGBgCiMgNC4gTm9ybWFsaXplIGRhdGEKYGBge3IgTm9ybWFsaXplfQoKCiMgQXBwbHkgU0NUcmFuc2Zvcm0KI0FsbF9zYW1wbGVzX01lcmdlZCA8LSBTQ1RyYW5zZm9ybShBbGxfc2FtcGxlc19NZXJnZWQsIHZlcmJvc2UgPSBUUlVFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApgYGAKIyA1LiBQZXJmb3JtIFBDQQpgYGB7ciBQQ0EsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKIyBWYXJpYWJsZXNfZ2VuZXMgPC0gQWxsX3NhbXBsZXNfTWVyZ2VkQGFzc2F5cyRTQ1RAdmFyLmZlYXR1cmVzCiMgCiMgIyBFeGNsdWRlIGdlbmVzIHN0YXJ0aW5nIHdpdGggIkhMQS0iIG9yICJYaXN0IgojIFZhcmlhYmxlc19nZW5lc19hZnRlcl9leGNsdXNpb24gPC0gVmFyaWFibGVzX2dlbmVzWyFncmVwbCgiXkhMQS18Xlhpc3QiLCBWYXJpYWJsZXNfZ2VuZXMpXQojIAojIAojICMgVGhlc2UgYXJlIG5vdyBzdGFuZGFyZCBzdGVwcyBpbiB0aGUgU2V1cmF0IHdvcmtmbG93IGZvciB2aXN1YWxpemF0aW9uIGFuZCBjbHVzdGVyaW5nCiMgQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFJ1blBDQShBbGxfc2FtcGxlc19NZXJnZWQsCiMgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSBWYXJpYWJsZXNfZ2VuZXNfYWZ0ZXJfZXhjbHVzaW9uLAojICAgICAgICAgICAgICAgICAgICAgICAgIGRvLnByaW50ID0gVFJVRSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgcGNzLnByaW50ID0gMTo1LCAKIyAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcy5wcmludCA9IDE1KQoKIyBkZXRlcm1pbmUgZGltZW5zaW9uYWxpdHkgb2YgdGhlIGRhdGEKRWxib3dQbG90KEFsbF9zYW1wbGVzX01lcmdlZCkKYGBgCiMgNi4gQ2x1c3RlcmluZwpgYGB7ciBDMSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CiMgQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIEZpbmROZWlnaGJvcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjgsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFKQojIAojICMgdW5kZXJzdGFuZGluZyByZXNvbHV0aW9uCiMgQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIEZpbmRDbHVzdGVycyhBbGxfc2FtcGxlc19NZXJnZWQsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdXRpb24gPSAxLjIpCgpgYGAKCgpgYGB7ciBDMiwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgojIG5vbi1saW5lYXIgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIC0tLS0tLS0tLS0tLS0tCiMgQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFJ1blVNQVAoQWxsX3NhbXBsZXNfTWVyZ2VkLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjgsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCiMgbm90ZSB0aGF0IHlvdSBjYW4gc2V0IGBsYWJlbCA9IFRSVUVgIG9yIHVzZSB0aGUgTGFiZWxDbHVzdGVycyBmdW5jdGlvbiB0byBoZWxwIGxhYmVsCiMgaW5kaXZpZHVhbCBjbHVzdGVycwpVTUFQUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsZ3JvdXAuYnkgPSAiY2VsbF9saW5lIiwgCiAgICAgICAgcmVkdWN0aW9uID0gInVtYXAiLAogICAgICAgIGxhYmVsLnNpemUgPSAzLAogICAgICAgIHJlcGVsID0gVCwKICAgICAgICBsYWJlbCA9IFQpCgpVTUFQUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgZ3JvdXAuYnkgPSAiU0NUX3Nubl9yZXMuMC43IiwgCiAgICAgICAgcmVkdWN0aW9uID0gInVtYXAiLAogICAgICAgIGxhYmVsLnNpemUgPSAzLAogICAgICAgIHJlcGVsID0gVCwKICAgICAgICBsYWJlbCA9IFQpCgpjbHVzdGVyX3RhYmxlIDwtIHRhYmxlKElkZW50cyhBbGxfc2FtcGxlc19NZXJnZWQpKQoKaGVhZChjbHVzdGVyX3RhYmxlKQpgYGAKIyA3LiBBemltdXRoIEFubm90YXRpb24KYGBge3IgYXppbXV0aF9Bbm5vdGF0aW9uLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KIyBJbnN0YWxsRGF0YSgicGJtY3NjYSIpCiMgCiMgVXBkYXRlU2V1cmF0T2JqZWN0KCJwYm1jc2NhIikKIyAKIyAjIFRoZSBSdW5BemltdXRoIGZ1bmN0aW9uIGNhbiB0YWtlIGEgU2V1cmF0IG9iamVjdCBhcyBpbnB1dAojIEFsbF9zYW1wbGVzX01lcmdlZCA8LSBSdW5BemltdXRoKEFsbF9zYW1wbGVzX01lcmdlZCwgcmVmZXJlbmNlID0gInBibWNzY2EiKQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgcHQuc2l6ZSA9IDEsCiAgICAgICAgIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMSIsCiAgICAgICAgIGxhYmVsID0gRkFMU0UsCiAgICAgICAgIGxhYmVsLnNpemUgPSA0KQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgcHQuc2l6ZSA9IDEsCiAgICAgICAgIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsCiAgICAgICAgIGxhYmVsID0gRkFMU0UsCiAgICAgICAgIGxhYmVsLnNpemUgPSA0KQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgcHQuc2l6ZSA9IDEsCiAgICAgICAgIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMyIsCiAgICAgICAgIGxhYmVsID0gRkFMU0UsCiAgICAgICAgIGxhYmVsLnNpemUgPSA0KQpgYGAKIyA4LiBQcm9qZWN0VGlscyBBbm5vdGF0aW9uCmBgYHtyIFByb2plY1RpbHMsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQojTG9hZCByZWZlcmVuY2UgYXRsYXMgYW5kIHF1ZXJ5IGRhdGEKIyByZWYgPC0gcmVhZFJEUyhmaWxlID0gIkNENFRfaHVtYW5fcmVmX3YxLnJkcyIpCiMgCiMgI1J1biBQcm9qZWN0aW9uIGFsZ29yaXRobQojIHF1ZXJ5LnByb2plY3RlZCA8LSBSdW4uUHJvamVjVElMcyhBbGxfc2FtcGxlc19NZXJnZWQsIHJlZiA9IHJlZikKCgoKI3JlZmVyZW5jZSBhdGxhcwojIERpbVBsb3QocmVmLCBsYWJlbCA9IFQpCgojVmlzdWFsaXplIHByb2plY3Rpb24KIyBwbG90LnByb2plY3Rpb24ocmVmLCBxdWVyeS5wcm9qZWN0ZWQsIGxpbmVzaXplID0gMC41LCBwb2ludHNpemUgPSAwLjUpCiMgCiMgI1Bsb3QgdGhlIHByZWRpY3RlZCBjb21wb3NpdGlvbiBvZiB0aGUgcXVlcnkgaW4gdGVybXMgb2YgcmVmZXJlbmNlIFQgY2VsbCBzdWJ0eXBlcwojIHBsb3Quc3RhdGVwcmVkLmNvbXBvc2l0aW9uKHJlZiwgcXVlcnkucHJvamVjdGVkLCBtZXRyaWMgPSAiUGVyY2VudCIpCgoKI0FsbF9zYW1wbGVzX01lcmdlZCA8LSBQcm9qZWNUSUxzLmNsYXNzaWZpZXIocXVlcnkgPSBBbGxfc2FtcGxlc19NZXJnZWQsIHJlZiA9IHJlZikKVU1BUFBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBncm91cC5ieSA9ICJmdW5jdGlvbmFsLmNsdXN0ZXIiLCAKICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgbGFiZWwuc2l6ZSA9IDMsCiAgICAgICAgcmVwZWwgPSBULAogICAgICAgIGxhYmVsID0gRikKYGBgCiMgOS5TaW5nbGVSIEFubm90YXRpb24KYGBge3Igc2luZ2xlUiwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CiNnZXQgcmVmZXJlbmNlIGRhdGFzZXRzIGZyb20gY2VsbGRleCBwYWNrYWdlCgojIG1vbmFjby5yZWYgPC0gY2VsbGRleDo6TW9uYWNvSW1tdW5lRGF0YSgpCiMgaHBjYS5yZWYgPC0gY2VsbGRleDo6SHVtYW5QcmltYXJ5Q2VsbEF0bGFzRGF0YSgpCiMgZGljZS5yZWYgPC0gY2VsbGRleDo6RGF0YWJhc2VJbW11bmVDZWxsRXhwcmVzc2lvbkRhdGEoKQojIGJwZS5yZWYgPC0gY2VsbGRleDo6Qmx1ZXByaW50RW5jb2RlRGF0YSgpCiMgCiMgI2NvbnZlcnQgb3VyIFNldXJhdCBvYmplY3QgdG8gc2luZ2xlIGNlbGwgZXhwZXJpbWVudCAoU0NFKQojIHNjZSA8LSBhcy5TaW5nbGVDZWxsRXhwZXJpbWVudChEaWV0U2V1cmF0KEFsbF9zYW1wbGVzX01lcmdlZCkpCiMgCiMgI3VzaW5nIFNpbmdsZVIKIyBtb25hY28ubWFpbiA8LSBTaW5nbGVSKHRlc3QgPSBzY2UsYXNzYXkudHlwZS50ZXN0ID0gMSxyZWYgPSBtb25hY28ucmVmLGxhYmVscyA9IG1vbmFjby5yZWYkbGFiZWwubWFpbikKIyBtb25hY28uZmluZSA8LSBTaW5nbGVSKHRlc3QgPSBzY2UsYXNzYXkudHlwZS50ZXN0ID0gMSxyZWYgPSBtb25hY28ucmVmLGxhYmVscyA9IG1vbmFjby5yZWYkbGFiZWwuZmluZSkKIyBocGNhLm1haW4gPC0gU2luZ2xlUih0ZXN0ID0gc2NlLGFzc2F5LnR5cGUudGVzdCA9IDEscmVmID0gaHBjYS5yZWYsbGFiZWxzID0gaHBjYS5yZWYkbGFiZWwubWFpbikKIyBocGNhLmZpbmUgPC0gU2luZ2xlUih0ZXN0ID0gc2NlLGFzc2F5LnR5cGUudGVzdCA9IDEscmVmID0gaHBjYS5yZWYsbGFiZWxzID0gaHBjYS5yZWYkbGFiZWwuZmluZSkKIyBkaWNlLm1haW4gPC0gU2luZ2xlUih0ZXN0ID0gc2NlLGFzc2F5LnR5cGUudGVzdCA9IDEscmVmID0gZGljZS5yZWYsbGFiZWxzID0gZGljZS5yZWYkbGFiZWwubWFpbikKIyBkaWNlLmZpbmUgPC0gU2luZ2xlUih0ZXN0ID0gc2NlLGFzc2F5LnR5cGUudGVzdCA9IDEscmVmID0gZGljZS5yZWYsbGFiZWxzID0gZGljZS5yZWYkbGFiZWwuZmluZSkKIyBicGUubWFpbiA8LSBTaW5nbGVSKHRlc3QgPSBzY2UsYXNzYXkudHlwZS50ZXN0ID0gMSxyZWYgPSBicGUucmVmLGxhYmVscyA9IGJwZS5yZWYkbGFiZWwubWFpbikKIyBicGUuZmluZSA8LSBTaW5nbGVSKHRlc3QgPSBzY2UsYXNzYXkudHlwZS50ZXN0ID0gMSxyZWYgPSBicGUucmVmLGxhYmVscyA9IGJwZS5yZWYkbGFiZWwuZmluZSkKIyAKCiNzdW1tYXJ5IG9mIGdlbmVyYWwgY2VsbCB0eXBlIGFubm90YXRpb25zCgojdGFibGUobW9uYWNvLm1haW4kcHJ1bmVkLmxhYmVscykKI3RhYmxlKGhwY2EubWFpbiRwcnVuZWQubGFiZWxzKQojdGFibGUoZGljZS5tYWluJHBydW5lZC5sYWJlbHMpCiN0YWJsZShicGUubWFpbiRwcnVuZWQubGFiZWxzKQoKI1RoZSBmaW5lciBjZWxsIHR5cGVzIGFubm90YXRpb25zIGFyZSB5b3UgYWZ0ZXIsIHRoZSBoYXJkZXIgdGhleSBhcmUgdG8gZ2V0IHJlbGlhYmx5LiAKI1RoaXMgaXMgd2hlcmUgY29tcGFyaW5nIG1hbnkgZGF0YWJhc2VzLCBhcyB3ZWxsIGFzIHVzaW5nIGluZGl2aWR1YWwgbWFya2VycyBmcm9tIGxpdGVyYXR1cmUsIAojd291bGQgYWxsIGJlIHZlcnkgdmFsdWFibGUuCgojdGFibGUobW9uYWNvLmZpbmUkcHJ1bmVkLmxhYmVscykKI3RhYmxlKGhwY2EuZmluZSRwcnVuZWQubGFiZWxzKQojdGFibGUoZGljZS5maW5lJHBydW5lZC5sYWJlbHMpCiN0YWJsZShicGUuZmluZSRwcnVuZWQubGFiZWxzKQoKCgojYWRkIHRoZSBhbm5vdGF0aW9ucyB0byB0aGUgU2V1cmF0IG9iamVjdCBtZXRhZGF0YQojIEFsbF9zYW1wbGVzX01lcmdlZEBtZXRhLmRhdGEkbW9uYWNvLm1haW4gPC0gbW9uYWNvLm1haW4kcHJ1bmVkLmxhYmVscwojIEFsbF9zYW1wbGVzX01lcmdlZEBtZXRhLmRhdGEkbW9uYWNvLmZpbmUgPC0gbW9uYWNvLmZpbmUkcHJ1bmVkLmxhYmVscwojICMKIyBBbGxfc2FtcGxlc19NZXJnZWRAbWV0YS5kYXRhJGhwY2EubWFpbiAgIDwtIGhwY2EubWFpbiRwcnVuZWQubGFiZWxzCiMgQWxsX3NhbXBsZXNfTWVyZ2VkQG1ldGEuZGF0YSRocGNhLmZpbmUgICA8LSBocGNhLmZpbmUkcHJ1bmVkLmxhYmVscwojICMgIAojIEFsbF9zYW1wbGVzX01lcmdlZEBtZXRhLmRhdGEkZGljZS5tYWluICAgPC0gZGljZS5tYWluJHBydW5lZC5sYWJlbHMKIyBBbGxfc2FtcGxlc19NZXJnZWRAbWV0YS5kYXRhJGRpY2UuZmluZSAgIDwtIGRpY2UuZmluZSRwcnVuZWQubGFiZWxzCiMgIyAKIyBBbGxfc2FtcGxlc19NZXJnZWRAbWV0YS5kYXRhJGJwZS5tYWluICAgPC0gYnBlLm1haW4kcHJ1bmVkLmxhYmVscwojIEFsbF9zYW1wbGVzX01lcmdlZEBtZXRhLmRhdGEkYnBlLmZpbmUgICA8LSBicGUuZmluZSRwcnVuZWQubGFiZWxzCgoKQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFNldElkZW50KEFsbF9zYW1wbGVzX01lcmdlZCwgdmFsdWUgPSAiaHBjYS5tYWluIikKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBGICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCiAgRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGxhYmVsID0gVCAsIHJlcGVsID0gVCwgbGFiZWwuc2l6ZSA9IDMpIAoKCiBBbGxfc2FtcGxlc19NZXJnZWQgPC0gU2V0SWRlbnQoQWxsX3NhbXBsZXNfTWVyZ2VkLCB2YWx1ZSA9ICJocGNhLmZpbmUiKQogIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBsYWJlbCA9IEYgLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSAzKSAKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBGICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCiAgCiAgCiAgQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFNldElkZW50KEFsbF9zYW1wbGVzX01lcmdlZCwgdmFsdWUgPSAiZGljZS5tYWluIikKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBGICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCiAgRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGxhYmVsID0gVCAsIHJlcGVsID0gVCwgbGFiZWwuc2l6ZSA9IDMpIAoKCiBBbGxfc2FtcGxlc19NZXJnZWQgPC0gU2V0SWRlbnQoQWxsX3NhbXBsZXNfTWVyZ2VkLCB2YWx1ZSA9ICJkaWNlLmZpbmUiKQogIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBsYWJlbCA9IEYgLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSAzKSAKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBUICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCiAgCiAgQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFNldElkZW50KEFsbF9zYW1wbGVzX01lcmdlZCwgdmFsdWUgPSAiYnBlLm1haW4iKQogIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBsYWJlbCA9IEYgLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSAzKSAKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBUICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCgoKIEFsbF9zYW1wbGVzX01lcmdlZCA8LSBTZXRJZGVudChBbGxfc2FtcGxlc19NZXJnZWQsIHZhbHVlID0gImJwZS5maW5lIikKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBGICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCiAgRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGxhYmVsID0gVCAsIHJlcGVsID0gVCwgbGFiZWwuc2l6ZSA9IDMpIAoKCgpBbGxfc2FtcGxlc19NZXJnZWQgPC0gU2V0SWRlbnQoQWxsX3NhbXBsZXNfTWVyZ2VkLCB2YWx1ZSA9ICJtb25hY28ubWFpbiIpCiAgRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGxhYmVsID0gRiAsIHJlcGVsID0gVCwgbGFiZWwuc2l6ZSA9IDMpIAogIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBsYWJlbCA9IFQgLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSAzKSAKCgogQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFNldElkZW50KEFsbF9zYW1wbGVzX01lcmdlZCwgdmFsdWUgPSAibW9uYWNvLmZpbmUiKQogIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBsYWJlbCA9IEYgLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSAzKSAKICBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgbGFiZWwgPSBUICwgcmVwZWwgPSBULCBsYWJlbC5zaXplID0gMykgCiAgCmBgYAo=