1. load libraries

2. Load Seurat Object


load("AllSample_corrected_AzimuthAnnotated_L1.Robj")

All_samples_Merged

3. Data PREPERATION


alldata <- All_samples_Merged

alldata.list <- SplitObject(alldata, split.by = "orig.ident")

for (i in 1:length(alldata.list)) {
    alldata.list[[i]] <- NormalizeData(alldata.list[[i]], verbose = FALSE)
    alldata.list[[i]] <- FindVariableFeatures(alldata.list[[i]], selection.method = "vst", nfeatures = 2000,verbose = FALSE)
}

# get the variable genes from all the datasets.
hvgs_per_dataset <- lapply(alldata.list, function(x) { x@assays$RNA@var.features })

# also add in the variable genes that was selected on the whole dataset
hvgs_per_dataset$all = VariableFeatures(alldata)

temp <- unique(unlist(hvgs_per_dataset))
overlap <- sapply( hvgs_per_dataset , function(x) { temp %in% x } )
pheatmap::pheatmap(t(overlap*1),cluster_rows = F ,
                   color = c("grey90","grey20"))

hvgs_all = SelectIntegrationFeatures(alldata.list)
hvgs_per_dataset$all_ranks = hvgs_all

temp <- unique(unlist(hvgs_per_dataset))
overlap <- sapply( hvgs_per_dataset , function(x) { temp %in% x } )
pheatmap::pheatmap(t(overlap*1),cluster_rows = F ,
                   color = c("grey90","grey20"))


alldata.list <- lapply(X = alldata.list, FUN = function(x) {
    x <- ScaleData(x, features = hvgs_all, verbose = FALSE)
    x <- RunPCA(x, features = hvgs_all, verbose = FALSE)
})

4. CCA-integration

wrap_plots(

    DimPlot(alldata.int, reduction = "pca_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated"),
  
    DimPlot(alldata.int, reduction = "pca_CCA", group.by = "CCA_snn_res.0.5")+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "CCA_snn_res.0.5")+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_CCA", group.by = "CCA_snn_res.0.5")+NoAxes()+ggtitle("UMAP integrated"),
    
    DimPlot(alldata.int, reduction = "pca_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated"),
    
    ncol = 3) + plot_layout(guides = "collect")

DimPlot(alldata.int, reduction = "pca_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated")

  
    DimPlot(alldata.int, reduction = "pca_CCA", group.by = "CCA_snn_res.0.5")+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "CCA_snn_res.0.5")+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_CCA", group.by = "CCA_snn_res.0.5")+NoAxes()+ggtitle("UMAP integrated")

    
    DimPlot(alldata.int, reduction = "pca_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_CCA", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated")

5. Harmony-integration


alldata.int@active.assay = "RNA"

VariableFeatures(alldata.int) = hvgs_all_final
alldata.int = ScaleData(alldata.int, verbose = TRUE)
Centering and scaling data matrix

  |                                                                                                            
  |                                                                                                      |   0%
  |                                                                                                            
  |===================================================                                                   |  50%
  |                                                                                                            
  |======================================================================================================| 100%
alldata.int = RunPCA(alldata.int, reduction.name = "pca_harmony")
PC_ 1 
Positive:  PNRC1, CD52, MALAT1, GIMAP5, TCF7, YPEL3, BTG1, BTG2, FCMR, LEF1 
       ZFP36, TXNIP, SELL, SH3BGRL3, ZFP36L2, FYB1, IL7R, CD44, PBXIP1, IKZF3 
       KLF2, LBH, GZMM, LAPTM5, LTB, SYNE2, CD27, NCF1, GAS5, CD7 
Negative:  TUBA1B, FABP5, H2AFZ, JPT1, MTHFD2, UBE2S, LGALS1, HMGB2, HSPD1, TXN 
       TYMS, PRDX1, PRELID1, PTTG1, GAPDH, IL2RA, CD70, NPM1, TUBB, CCND2 
       PKM, ENO1, PCLAF, HNRNPAB, NME1, CLIC1, ATP5MC3, BATF3, MTDH, RRM2 
PC_ 2 
Positive:  CST7, XCL1, MATK, ZBTB16, GZMM, XCL2, C1QBP, KIR2DL4, ESYT2, KRT86 
       TRBV23-1, KRT81, CXCR3, SRRT, TOX, NKG7, EIF4A1, PFN1, GYPC, TRBV20-1 
       NME2, IL32, LTB, CD7, CORO1B, IKZF2, MYO1E, LSR, MRPL12, IL12RB2 
Negative:  SQSTM1, ANXA1, NFKBIA, CD74, FAM107B, FTH1, KYNU, SAT1, LGALS3, ZEB2 
       EMP3, CFLAR, TYMP, SLC7A11, CXCL8, MARCKS, DOCK4, LMNA, TYROBP, C15orf48 
       FCER1G, CTSZ, NCF2, TIMP1, BCL3, BIRC3, CCR7, RBM47, CD2, AHNAK 
PC_ 3 
Positive:  RBPMS, TRAV17, TENM3, PPBP, PPP2R2B, LMNA, RPL22L1, PLD1, IQCG, NCR3 
       VAMP5, SRGN, SPOCK1, CTAG2, SLC7A11-AS1, STMN1, STAT1, ANXA2, KIF2A, FAM241A 
       TNFSF10, MACROD2, AC010967.1, MT2A, TK1, PLAAT3, TUBA4A, RYR2, CREB3L3, IGFBP3 
Negative:  TNFRSF4, SYT4, BACE2, CYBA, PHLDA2, CA2, CCL17, PTP4A3, ADGRB3, GRIA4 
       LY6E, ONECUT2, EEF1A2, IGHE, PON2, PRG4, MCTP2, KRT7, AC112770.1, THY1 
       MSC, ACTN1, SMIM3, FGGY, IGKC, PLPP1, CFI, MAP4K4, RHOC, NME4 
PC_ 4 
Positive:  TYROBP, DOCK4, FCER1G, C15orf48, THBS1, KYNU, CXCL8, MMP9, EPB41L3, MS4A7 
       SLC43A2, LYZ, TNFAIP2, CXCL5, SLC7A11, GLIS3, GAS7, CCR1, RBM47, LILRB4 
       RNF130, TIMP2, NCF2, LUCAT1, ZEB2, ZMIZ1, VCAN, PLEK, EMP1, MT1G 
Negative:  RPL7, CCR7, NPM1, CD74, EEF2, MIR155HG, GIMAP5, SELL, ALOX5AP, ARID5A 
       LTA, YBX3, SNHG8, CCL17, S1PR1, SLC35F3, TCF7, HSP90AB1, FCER2, TSHZ2 
       RPL22L1, RXFP1, BATF3, SOCS1, GAS5, DANCR, CCR4, AL590550.1, CA2, CD2 
PC_ 5 
Positive:  S100A4, DUSP4, ENTPD1, F2R, TP73, AL136456.1, RAB37, LINC02694, CD2, EEF1A2 
       S100A6, GPAT3, CRIP1, WNT5B, RPS6KA5, TMEM163, ITM2A, QPRT, TNFRSF18, TMSB4X 
       LIME1, HIST1H1C, PTCHD1-AS, LINC01934, PALLD, GAS2L1, IRX3, AHNAK, MYO1G, LAPTM5 
Negative:  FCER2, LTA, MIR155HG, DNAJC12, RPL23, C1QBP, PPBP, PPID, RXFP1, KYNU 
       SLC7A11-AS1, COL19A1, NFIB, MIR3945HG, TXNDC17, ZNF804A, CSMD1, AC068672.2, SLC35F3, CCL17 
       RBM47, ODC1, MPP1, UNC13C, EIF5A, DOCK4, ACSL1, ARL4A, IFNGR2, FCER1G 
Warning: Key 'PC_' taken, using 'pcaharmony_' instead
alldata.int <- RunHarmony(
  alldata.int,
  group.by.vars = "orig.ident",
  reduction.use = "pca_harmony",
  dims.use = 1:15,
  assay.use = "RNA")
Transposing data matrix
Initializing state using k-means centroids initialization
Harmony 1/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 5/10
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 5 iterations
alldata.int <- RunUMAP(alldata.int, dims = 1:15, reduction = "harmony", reduction.name = "umap_harmony")
11:59:08 UMAP embedding parameters a = 0.9922 b = 1.112
11:59:08 Read 49193 rows and found 15 numeric columns
11:59:08 Using Annoy for neighbor search, n_neighbors = 30
11:59:08 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
11:59:11 Writing NN index file to temp file /tmp/RtmpDstfLq/fileac4b85dd5c26a
11:59:11 Searching Annoy index using 1 thread, search_k = 3000
11:59:23 Annoy recall = 100%
11:59:23 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 30
11:59:25 Initializing from normalized Laplacian + noise (using RSpectra)
11:59:27 Commencing optimization for 200 epochs, with 2060712 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
11:59:43 Optimization finished
alldata.int <- RunTSNE(alldata.int, dims = 1:15, reduction = "harmony", reduction.name = "tsne_harmony")
Warning: Key 'tSNE_' taken, using 'tsneharmony_' instead
alldata.int <- FindNeighbors(alldata.int, reduction = "pca_harmony", dims = 1:15, verbose = FALSE)
alldata.int <- FindClusters(alldata.int, resolution = 0.5, verbose = FALSE)


 
 
 wrap_plots(

    
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated"),
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated"),
    
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("UMAP integrated"),
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.0.5", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated"),
    
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated"),
     DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated"),
    ncol = 2) + plot_layout(guides = "collect")


wrap_plots(

    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated"),
  
    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("UMAP integrated"),
    
    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated"),
    
    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("PCA integrated"),
    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("tSNE integrated"),
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated"),
    ncol = 3) + plot_layout(guides = "collect")


DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated")

    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated")

    
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("UMAP integrated")

    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.0.5", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated")

    
    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

     DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated")

   

DimPlot(alldata.int, reduction = "pca_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated")

  
    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.0.5")+NoAxes()+ggtitle("UMAP integrated")

    
    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

    
    DimPlot(alldata.int, reduction = "pca_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("PCA integrated")

    DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("tSNE integrated")

    DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2", label = TRUE, label.box = TRUE, repel = TRUE)+NoAxes()+ggtitle("UMAP integrated")

NA
NA

FeaturePlot



myfeatures <- c("CD3E", "CD4", "CD8A", "NKG7", "GNLY", "MS4A1", "CD14", "LYZ", "MS4A7", "FCGR3A", "CST3", "FCER1A")
FeaturePlot(alldata.int, reduction = "umap_harmony", dims = 1:2, features = myfeatures, ncol = 4, order = T) + NoLegend() + NoAxes() + NoGrid()


FeaturePlot(alldata.int, reduction = "umap_CCA", dims = 1:2, features = myfeatures, ncol = 4, order = T) + NoLegend() + NoAxes() + NoGrid()

6. Save the Seurat object as an Robj file


#save(alldata.int, file = "Integrated_by_CCA_Harmony.Robj")
LS0tCnRpdGxlOiAiSW50ZWdyYXRpb24gYnkgQ0NBLUhhcm1vbnkiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogIjIwMjQtMDQtMDYiCm91dHB1dDoKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCiAgICB0aGVtZTogZGFya2x5Ci0tLQojIDEuIGxvYWQgbGlicmFyaWVzCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoaGFybW9ueSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJldGljdWxhdGUpCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShSdHNuZSkKbGlicmFyeShoYXJtb255KQoKYGBgCgojIDIuIExvYWQgU2V1cmF0IE9iamVjdCAKYGBge3IgbG9hZF9zZXVyYXR9Cgpsb2FkKCJBbGxTYW1wbGVfY29ycmVjdGVkX0F6aW11dGhBbm5vdGF0ZWRfTDEuUm9iaiIpCgpBbGxfc2FtcGxlc19NZXJnZWQKCmBgYAoKCiMgMy4gRGF0YSBQUkVQRVJBVElPTgpgYGB7ciBkYXRhLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCmFsbGRhdGEgPC0gQWxsX3NhbXBsZXNfTWVyZ2VkCgphbGxkYXRhLmxpc3QgPC0gU3BsaXRPYmplY3QoYWxsZGF0YSwgc3BsaXQuYnkgPSAib3JpZy5pZGVudCIpCgpmb3IgKGkgaW4gMTpsZW5ndGgoYWxsZGF0YS5saXN0KSkgewogICAgYWxsZGF0YS5saXN0W1tpXV0gPC0gTm9ybWFsaXplRGF0YShhbGxkYXRhLmxpc3RbW2ldXSwgdmVyYm9zZSA9IEZBTFNFKQogICAgYWxsZGF0YS5saXN0W1tpXV0gPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoYWxsZGF0YS5saXN0W1tpXV0sIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCx2ZXJib3NlID0gRkFMU0UpCn0KCiMgZ2V0IHRoZSB2YXJpYWJsZSBnZW5lcyBmcm9tIGFsbCB0aGUgZGF0YXNldHMuCmh2Z3NfcGVyX2RhdGFzZXQgPC0gbGFwcGx5KGFsbGRhdGEubGlzdCwgZnVuY3Rpb24oeCkgeyB4QGFzc2F5cyRSTkFAdmFyLmZlYXR1cmVzIH0pCgojIGFsc28gYWRkIGluIHRoZSB2YXJpYWJsZSBnZW5lcyB0aGF0IHdhcyBzZWxlY3RlZCBvbiB0aGUgd2hvbGUgZGF0YXNldApodmdzX3Blcl9kYXRhc2V0JGFsbCA9IFZhcmlhYmxlRmVhdHVyZXMoYWxsZGF0YSkKCnRlbXAgPC0gdW5pcXVlKHVubGlzdChodmdzX3Blcl9kYXRhc2V0KSkKb3ZlcmxhcCA8LSBzYXBwbHkoIGh2Z3NfcGVyX2RhdGFzZXQgLCBmdW5jdGlvbih4KSB7IHRlbXAgJWluJSB4IH0gKQpwaGVhdG1hcDo6cGhlYXRtYXAodChvdmVybGFwKjEpLGNsdXN0ZXJfcm93cyA9IEYgLAogICAgICAgICAgICAgICAgICAgY29sb3IgPSBjKCJncmV5OTAiLCJncmV5MjAiKSkKCmh2Z3NfYWxsID0gU2VsZWN0SW50ZWdyYXRpb25GZWF0dXJlcyhhbGxkYXRhLmxpc3QpCmh2Z3NfcGVyX2RhdGFzZXQkYWxsX3JhbmtzID0gaHZnc19hbGwKCnRlbXAgPC0gdW5pcXVlKHVubGlzdChodmdzX3Blcl9kYXRhc2V0KSkKb3ZlcmxhcCA8LSBzYXBwbHkoIGh2Z3NfcGVyX2RhdGFzZXQgLCBmdW5jdGlvbih4KSB7IHRlbXAgJWluJSB4IH0gKQpwaGVhdG1hcDo6cGhlYXRtYXAodChvdmVybGFwKjEpLGNsdXN0ZXJfcm93cyA9IEYgLAogICAgICAgICAgICAgICAgICAgY29sb3IgPSBjKCJncmV5OTAiLCJncmV5MjAiKSkKCgphbGxkYXRhLmxpc3QgPC0gbGFwcGx5KFggPSBhbGxkYXRhLmxpc3QsIEZVTiA9IGZ1bmN0aW9uKHgpIHsKICAgIHggPC0gU2NhbGVEYXRhKHgsIGZlYXR1cmVzID0gaHZnc19hbGwsIHZlcmJvc2UgPSBGQUxTRSkKICAgIHggPC0gUnVuUENBKHgsIGZlYXR1cmVzID0gaHZnc19hbGwsIHZlcmJvc2UgPSBGQUxTRSkKfSkKYGBgCgojIDQuIENDQS1pbnRlZ3JhdGlvbgpgYGB7ciBpbnRlZ3JhdGlvbi1DQ0EsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKIyBFeGNsdWRlIGdlbmVzIHN0YXJ0aW5nIHdpdGggIkhMQS0iIG9yICJYaXN0IgpodmdzX2FsbF9maW5hbCA8LSBodmdzX2FsbFshZ3JlcGwoIl5ITEEtfF5YSVNUIiwgaHZnc19hbGwpXQoKCmFsbGRhdGEuYW5jaG9ycyA8LSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKG9iamVjdC5saXN0ID0gYWxsZGF0YS5saXN0LCByZWR1Y3Rpb24gPSAiY2NhIiwgYW5jaG9yLmZlYXR1cmVzID0gaHZnc19hbGxfZmluYWwpCgphbGxkYXRhLmludCA8LSBJbnRlZ3JhdGVEYXRhKGFuY2hvcnNldCA9IGFsbGRhdGEuYW5jaG9ycywgbmV3LmFzc2F5Lm5hbWUgPSAiQ0NBIikKCm5hbWVzKGFsbGRhdGEuaW50QGFzc2F5cykKCmFsbGRhdGEuaW50QGFjdGl2ZS5hc3NheQoKRGVmYXVsdEFzc2F5KGFsbGRhdGEuaW50KSA8LSAiQ0NBIgoKI1J1biBEaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gb24gaW50ZWdyYXRlZCBzcGFjZQphbGxkYXRhLmludCA8LSBTY2FsZURhdGEoYWxsZGF0YS5pbnQsIHZlcmJvc2UgPSBUUlVFKQphbGxkYXRhLmludCA8LSBSdW5QQ0EoYWxsZGF0YS5pbnQsIGZlYXR1cmVzID0gaHZnc19hbGwsIHJlZHVjdGlvbi5uYW1lID0gInBjYV9DQ0EiLCBkby5wcmludCA9IFRSVUUsIHBjcy5wcmludCA9IDE6NSwgZ2VuZXMucHJpbnQgPSAxNSwgdmVyYm9zZSA9IEZBTFNFKQphbGxkYXRhLmludCA8LSBSdW5VTUFQKGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIsIHJlZHVjdGlvbi5uYW1lID0gInVtYXBfQ0NBIiwgZGltcyA9IDE6MTUsIHZlcmJvc2UgPSBGQUxTRSkKYWxsZGF0YS5pbnQgPC0gUnVuVFNORShhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9DQ0EiLHJlZHVjdGlvbi5uYW1lID0gInRzbmVfQ0NBIixkaW1zID0gMToxNSwgdmVyYm9zZSA9IEZBTFNFKQphbGxkYXRhLmludCA8LSBGaW5kTmVpZ2hib3JzKGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIsIGRpbXMgPSAxOjE1LCB2ZXJib3NlID0gRkFMU0UpCmFsbGRhdGEuaW50IDwtIEZpbmRDbHVzdGVycyhhbGxkYXRhLmludCwgcmVzb2x1dGlvbiA9IDAuNSwgdmVyYm9zZSA9IEZBTFNFKQoKd3JhcF9wbG90cygKCiAgICAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgICAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfQ0NBIiwgZ3JvdXAuYnkgPSAiQ0NBX3Nubl9yZXMuMC41IiwgbGFiZWwgPSBUUlVFLCBsYWJlbC5ib3ggPSBUUlVFLCByZXBlbCA9IFRSVUUpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9DQ0EiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsIGxhYmVsID0gVFJVRSwgbGFiZWwuYm94ID0gVFJVRSwgcmVwZWwgPSBUUlVFKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKICAgIAogICAgbmNvbCA9IDIpICsgcGxvdF9sYXlvdXQoZ3VpZGVzID0gImNvbGxlY3QiKQoKCndyYXBfcGxvdHMoCgogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9DQ0EiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKICAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfQ0NBIiwgZ3JvdXAuYnkgPSAiQ0NBX3Nubl9yZXMuMC41IikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfQ0NBIiwgZ3JvdXAuYnkgPSAiQ0NBX3Nubl9yZXMuMC41IikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgICAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfQ0NBIiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfQ0NBIiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgICAKICAgIG5jb2wgPSAzKSArIHBsb3RfbGF5b3V0KGd1aWRlcyA9ICJjb2xsZWN0IikKCkRpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfQ0NBIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfQ0NBIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCiAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9DQ0EiLCBncm91cC5ieSA9ICJDQ0Ffc25uX3Jlcy4wLjUiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidHNuZV9DQ0EiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgidFNORSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCkRpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsIGxhYmVsID0gVFJVRSwgbGFiZWwuYm94ID0gVFJVRSwgcmVwZWwgPSBUUlVFKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQoKYGBgCiMgNS4gSGFybW9ueS1pbnRlZ3JhdGlvbgpgYGB7ciBIYXJtb255X2ludGVncmF0aW9uLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCmFsbGRhdGEuaW50QGFjdGl2ZS5hc3NheSA9ICJSTkEiCgpWYXJpYWJsZUZlYXR1cmVzKGFsbGRhdGEuaW50KSA9IGh2Z3NfYWxsX2ZpbmFsCmFsbGRhdGEuaW50ID0gU2NhbGVEYXRhKGFsbGRhdGEuaW50LCB2ZXJib3NlID0gVFJVRSkKYWxsZGF0YS5pbnQgPSBSdW5QQ0EoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbi5uYW1lID0gInBjYV9oYXJtb255IikKCgphbGxkYXRhLmludCA8LSBSdW5IYXJtb255KAogIGFsbGRhdGEuaW50LAogIGdyb3VwLmJ5LnZhcnMgPSAib3JpZy5pZGVudCIsCiAgcmVkdWN0aW9uLnVzZSA9ICJwY2FfaGFybW9ueSIsCiAgZGltcy51c2UgPSAxOjE1LAogIGFzc2F5LnVzZSA9ICJSTkEiKQoKCmFsbGRhdGEuaW50IDwtIFJ1blVNQVAoYWxsZGF0YS5pbnQsIGRpbXMgPSAxOjE1LCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIHJlZHVjdGlvbi5uYW1lID0gInVtYXBfaGFybW9ueSIpCmFsbGRhdGEuaW50IDwtIFJ1blRTTkUoYWxsZGF0YS5pbnQsIGRpbXMgPSAxOjE1LCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIHJlZHVjdGlvbi5uYW1lID0gInRzbmVfaGFybW9ueSIpCmFsbGRhdGEuaW50IDwtIEZpbmROZWlnaGJvcnMoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfaGFybW9ueSIsIGRpbXMgPSAxOjE1LCB2ZXJib3NlID0gRkFMU0UpCmFsbGRhdGEuaW50IDwtIEZpbmRDbHVzdGVycyhhbGxkYXRhLmludCwgcmVzb2x1dGlvbiA9IDAuNSwgdmVyYm9zZSA9IEZBTFNFKQoKCiAKIAogd3JhcF9wbG90cygKCiAgICAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIGxhYmVsID0gVFJVRSwgbGFiZWwuYm94ID0gVFJVRSwgcmVwZWwgPSBUUlVFKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKICAgIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIsIGxhYmVsID0gVFJVRSwgbGFiZWwuYm94ID0gVFJVRSwgcmVwZWwgPSBUUlVFKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKICAgIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgICBuY29sID0gMikgKyBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIpCgp3cmFwX3Bsb3RzKAoKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJQQ0EgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX2hhcm1vbnkiLCBncm91cC5ieSA9ICJSTkFfc25uX3Jlcy4wLjUiKStOb0F4ZXMoKStnZ3RpdGxlKCJQQ0EgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiKStOb0F4ZXMoKStnZ3RpdGxlKCJQQ0EgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgidFNORSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIiwgbGFiZWwgPSBUUlVFLCBsYWJlbC5ib3ggPSBUUlVFLCByZXBlbCA9IFRSVUUpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgbmNvbCA9IDMpICsgcGxvdF9sYXlvdXQoZ3VpZGVzID0gImNvbGxlY3QiKQoKRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKICAgIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMC41IiwgbGFiZWwgPSBUUlVFLCBsYWJlbC5ib3ggPSBUUlVFLCByZXBlbCA9IFRSVUUpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCiAgICAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKICAgCgpEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX2hhcm1vbnkiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMC41IikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuNSIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMC41IikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKICAgIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9oYXJtb255IiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKICAgIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9oYXJtb255IiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIiwgbGFiZWwgPSBUUlVFLCBsYWJlbC5ib3ggPSBUUlVFLCByZXBlbCA9IFRSVUUpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgidFNORSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCBsYWJlbCA9IFRSVUUsIGxhYmVsLmJveCA9IFRSVUUsIHJlcGVsID0gVFJVRSkrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKCgpgYGAKCiMgRmVhdHVyZVBsb3QKYGBge3IgZmVhdHVyZXBsb3QtaGFybW9ueSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgoKbXlmZWF0dXJlcyA8LSBjKCJDRDNFIiwgIkNENCIsICJDRDhBIiwgIk5LRzciLCAiR05MWSIsICJNUzRBMSIsICJDRDE0IiwgIkxZWiIsICJNUzRBNyIsICJGQ0dSM0EiLCAiQ1NUMyIsICJGQ0VSMUEiKQpGZWF0dXJlUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfaGFybW9ueSIsIGRpbXMgPSAxOjIsIGZlYXR1cmVzID0gbXlmZWF0dXJlcywgbmNvbCA9IDQsIG9yZGVyID0gVCkgKyBOb0xlZ2VuZCgpICsgTm9BeGVzKCkgKyBOb0dyaWQoKQoKRmVhdHVyZVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGRpbXMgPSAxOjIsIGZlYXR1cmVzID0gbXlmZWF0dXJlcywgbmNvbCA9IDQsIG9yZGVyID0gVCkgKyBOb0xlZ2VuZCgpICsgTm9BeGVzKCkgKyBOb0dyaWQoKQpgYGAKCgojIDYuIFNhdmUgdGhlIFNldXJhdCBvYmplY3QgYXMgYW4gUm9iaiBmaWxlCmBgYHtyIHNhdmVST0JKfQoKI3NhdmUoYWxsZGF0YS5pbnQsIGZpbGUgPSAiSW50ZWdyYXRlZF9ieV9DQ0FfSGFybW9ueS5Sb2JqIikKCgpgYGAKCgoKCg==