3. Data PREPARATION and Harmony Integration-1
# Create a new metadata column for grouping
All_samples_Merged$sample_group <- case_when(
grepl("^L", All_samples_Merged$cell_line) ~ "Cell_Line",
All_samples_Merged$cell_line == "PBMC" ~ "PBMC",
All_samples_Merged$cell_line == "PBMC_10x" ~ "PBMC_10x",
TRUE ~ "Other"
)
# Create the cell line grouping correctly
All_samples_Merged$cell_line_group <- case_when(
grepl("^L[1-2]", All_samples_Merged$cell_line) ~ "P1",
grepl("^L[3-4]", All_samples_Merged$cell_line) ~ "P2",
grepl("^L[5-7]", All_samples_Merged$cell_line) ~ "P3",
All_samples_Merged$cell_line == "PBMC" ~ "PBMC",
All_samples_Merged$cell_line == "PBMC_10x" ~ "PBMC_10x",
TRUE ~ "Other" # This catches any unexpected values
)
library(harmony)
All_samples_Merged <- RunHarmony(
object = All_samples_Merged,
group.by.vars = "sample_group",
dims.use = 1:22, # Increased to capture more variation
theta = c(0.5), # Adjust these values as needed
plot_convergence = TRUE
)
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 converged after 2 iterations

# Run UMAP on the new Harmony reduction
All_samples_Merged <- RunUMAP(All_samples_Merged, reduction = "harmony", dims = 1:22, reduction.name = "umap.harmony")
Avis : The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session09:31:02 UMAP embedding parameters a = 0.9922 b = 1.112
09:31:02 Read 59355 rows and found 22 numeric columns
09:31:02 Using Annoy for neighbor search, n_neighbors = 30
09:31:02 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
09:31:10 Writing NN index file to temp file /tmp/Rtmpcrhtj7/file3c27e46c0ca39
09:31:10 Searching Annoy index using 1 thread, search_k = 3000
09:31:36 Annoy recall = 100%
09:31:37 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 30
09:31:41 Initializing from normalized Laplacian + noise (using RSpectra)
09:31:50 Commencing optimization for 200 epochs, with 2508680 positive edges
Using method 'umap'
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
09:32:27 Optimization finished
# Find neighbors and clusters using the Harmony reduction
All_samples_Merged <- FindNeighbors(All_samples_Merged, reduction = "harmony", dims = 1:22)
Computing nearest neighbor graph
Computing SNN
All_samples_Merged <- FindClusters(All_samples_Merged, resolution = 0.5)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 59355
Number of edges: 1961526
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9505
Number of communities: 22
Elapsed time: 20 seconds
Harmony Visualization-1
p1 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "sample_group", label = T, label.box = T)
p2 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line_group",label = T, label.box = T)
p3 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)
p1 + p2 + p3

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "sample_group",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line_group",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)

# Compare with original UMAP
p4 <- DimPlot(All_samples_Merged, reduction = "umap", group.by = "cell_line",label = T, label.box = T) +
ggtitle("Original Integration - By Cell Line")
p5 <- DimPlot(All_samples_Merged, reduction = "umap", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Original Integration - By Clusters")
# Print the plots
print(p4 + p5)

DimPlot(All_samples_Merged, reduction = "umap", group.by = "cell_line",label = T, label.box = T) +
ggtitle("Original Integration - By Cell Line")

DimPlot(All_samples_Merged, reduction = "umap", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Original Integration - By Clusters")

# Visualize results
p6 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line", label = T, label.box = T) +
ggtitle("Harmony Integration - By Cell Line")
p7 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Harmony Integration - By Clusters")
# Print the plots
print(p6 + p7)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line", label = T, label.box = T) +
ggtitle("Harmony Integration - By Cell Line")

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Harmony Integration - By Clusters")

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "predicted.celltype.l2",label = T, label.box = T) +
ggtitle("Harmony Integration - Annotations")

4. Data PREPARATION and Harmony Integration-2
library(harmony)
All_samples_Merged <- RunHarmony(
object = All_samples_Merged,
group.by.vars = "cell_line_group",
dims.use = 1:22, # Increased to capture more variation
theta = c(0.5), # Adjust these values as needed
plot_convergence = TRUE
)
Transposing data matrix
Initializing state using k-means centroids initialization
Avis : Les étapes de transfer (quick-TRANSfer stage) ont dépassé le maximum (= 2967750)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 converged after 2 iterations

# Run UMAP on the new Harmony reduction
All_samples_Merged <- RunUMAP(All_samples_Merged, reduction = "harmony", dims = 1:22, reduction.name = "umap.harmony")
09:43:42 UMAP embedding parameters a = 0.9922 b = 1.112
09:43:42 Read 59355 rows and found 22 numeric columns
09:43:42 Using Annoy for neighbor search, n_neighbors = 30
09:43:42 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
09:43:50 Writing NN index file to temp file /tmp/Rtmpcrhtj7/file3c27e72d964be
09:43:50 Searching Annoy index using 1 thread, search_k = 3000
09:44:15 Annoy recall = 100%
09:44:16 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 30
09:44:20 Initializing from normalized Laplacian + noise (using RSpectra)
09:44:27 Commencing optimization for 200 epochs, with 2541136 positive edges
Using method 'umap'
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
09:45:05 Optimization finished
# Find neighbors and clusters using the Harmony reduction
All_samples_Merged <- FindNeighbors(All_samples_Merged, reduction = "harmony", dims = 1:22)
Computing nearest neighbor graph
Computing SNN
All_samples_Merged <- FindClusters(All_samples_Merged, resolution = 0.5)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 59355
Number of edges: 1951462
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9474
Number of communities: 21
Elapsed time: 25 seconds
Harmony Visualization-2
p1 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "sample_group", label = T, label.box = T)
p2 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line_group",label = T, label.box = T)
p3 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)
p1 + p2 + p3

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "sample_group",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line_group",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)

# Compare with original UMAP
p4 <- DimPlot(All_samples_Merged, reduction = "umap", group.by = "cell_line",label = T, label.box = T) +
ggtitle("Original Integration - By Cell Line")
p5 <- DimPlot(All_samples_Merged, reduction = "umap", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Original Integration - By Clusters")
# Print the plots
print(p4 + p5)

DimPlot(All_samples_Merged, reduction = "umap", group.by = "cell_line",label = T, label.box = T) +
ggtitle("Original Integration - By Cell Line")

DimPlot(All_samples_Merged, reduction = "umap", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Original Integration - By Clusters")
Registered S3 method overwritten by 'rmarkdown':
method from
print.paged_df

# Visualize results
p6 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line", label = T, label.box = T) +
ggtitle("Harmony Integration - By Cell Line")
p7 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Harmony Integration - By Clusters")
# Print the plots
print(p6 + p7)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line", label = T, label.box = T) +
ggtitle("Harmony Integration - By Cell Line")

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Harmony Integration - By Clusters")

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "predicted.celltype.l2",label = T, label.box = T) +
ggtitle("Harmony Integration - Annotations")

7. Data PREPARATION and Harmony Integration-3
# Create a new metadata column for grouping
All_samples_Merged$sample_group <- case_when(
grepl("^L", All_samples_Merged$cell_line) ~ "Cell_Line",
All_samples_Merged$cell_line == "PBMC" ~ "PBMC",
All_samples_Merged$cell_line == "PBMC_10x" ~ "PBMC_10x",
TRUE ~ "Other"
)
# Create the cell line grouping correctly
All_samples_Merged$cell_line_group <- case_when(
grepl("^L[1-2]", All_samples_Merged$cell_line) ~ "P1",
grepl("^L[3-4]", All_samples_Merged$cell_line) ~ "P2",
grepl("^L[5-7]", All_samples_Merged$cell_line) ~ "P3",
All_samples_Merged$cell_line == "PBMC" ~ "PBMC",
All_samples_Merged$cell_line == "PBMC_10x" ~ "PBMC_10x",
TRUE ~ "Other" # This catches any unexpected values
)
library(harmony)
All_samples_Merged <- RunHarmony(
object = All_samples_Merged,
group.by.vars = "cell_line",
dims.use = 1:22, # Increased to capture more variation
theta = c(0.5), # Adjust these values as needed
plot_convergence = TRUE
)
Transposing data matrix
Initializing state using k-means centroids initialization
Avis : Les étapes de transfer (quick-TRANSfer stage) ont dépassé le maximum (= 2967750)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 converged after 2 iterations

# Run UMAP on the new Harmony reduction
All_samples_Merged <- RunUMAP(All_samples_Merged, reduction = "harmony", dims = 1:22, reduction.name = "umap.harmony")
09:53:56 UMAP embedding parameters a = 0.9922 b = 1.112
09:53:56 Read 59355 rows and found 22 numeric columns
09:53:56 Using Annoy for neighbor search, n_neighbors = 30
09:53:56 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
09:54:03 Writing NN index file to temp file /tmp/Rtmpcrhtj7/file3c27e24cfb76b
09:54:03 Searching Annoy index using 1 thread, search_k = 3000
09:54:29 Annoy recall = 100%
09:54:31 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 30
09:54:35 Initializing from normalized Laplacian + noise (using RSpectra)
09:54:40 Commencing optimization for 200 epochs, with 2543152 positive edges
Using method 'umap'
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
09:55:19 Optimization finished
# Find neighbors and clusters using the Harmony reduction
All_samples_Merged <- FindNeighbors(All_samples_Merged, reduction = "harmony", dims = 1:22)
Computing nearest neighbor graph
Computing SNN
All_samples_Merged <- FindClusters(All_samples_Merged, resolution = 0.5)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 59355
Number of edges: 1882456
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9226
Number of communities: 18
Elapsed time: 25 seconds
Harmony Visualization-3
p1 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "sample_group", label = T, label.box = T)
p2 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line_group",label = T, label.box = T)
p3 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)
p1 + p2 + p3

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "sample_group",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line_group",label = T, label.box = T)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line",label = T, label.box = T)

# Compare with original UMAP
p4 <- DimPlot(All_samples_Merged, reduction = "umap", group.by = "cell_line",label = T, label.box = T) +
ggtitle("Original Integration - By Cell Line")
p5 <- DimPlot(All_samples_Merged, reduction = "umap", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Original Integration - By Clusters")
# Print the plots
print(p4 + p5)

DimPlot(All_samples_Merged, reduction = "umap", group.by = "cell_line",label = T, label.box = T) +
ggtitle("Original Integration - By Cell Line")

DimPlot(All_samples_Merged, reduction = "umap", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Original Integration - By Clusters")

# Visualize results
p6 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line", label = T, label.box = T) +
ggtitle("Harmony Integration - By Cell Line")
p7 <- DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Harmony Integration - By Clusters")
# Print the plots
print(p6 + p7)

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "cell_line", label = T, label.box = T) +
ggtitle("Harmony Integration - By Cell Line")

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "seurat_clusters",label = T, label.box = T) +
ggtitle("Harmony Integration - By Clusters")

DimPlot(All_samples_Merged, reduction = "umap.harmony", group.by = "predicted.celltype.l2",label = T, label.box = T) +
ggtitle("Harmony Integration - Annotations")

Marker Gene Visualization
# Set marker genes specific to requested immune cell types
myfeatures <- c("CD19", "CD79A", "MS4A1", # B cells
"CD14", "LYZ", "FCGR3A", # Monocytes
"CSF1R", "CD68", # Macrophages
"NKG7", "GNLY", "KIR3DL1", # NK cells
"MKI67", # Proliferating NK cells
"CD34", "KIT", # HSPCs
"CD3E", "CCR7", # T cells
"SELL", "CD45RO", # Tnaive, Tcm
"CD44", "CD45RA") # Tem, Temra
# Visualize marker genes for Harmony
FeaturePlot(All_samples_Merged, features = myfeatures, reduction = "umap.harmony", ncol = 4) +
ggtitle("Marker Gene Expression - Harmony Integration") +
NoLegend()
Avis : Could not find CD45RO in the default search locations, found in 'ADT' assay insteadAvis : Could not find CD45RA in the default search locations, found in 'ADT' assay instead

LS0tCnRpdGxlOiAiSGFybW9ueSBpbnRlZ3JhdGlvbnMgb2YgUEJNQzEweC1wYXJ0NCIKYXV0aG9yOiBOYXNpciBNYWhtb29kIEFiYmFzaQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICAjcm1kZm9ybWF0czo6cmVhZHRoZWRvd24KICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKLS0tCgojIDEuIGxvYWQgbGlicmFyaWVzCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTZXVyYXRXcmFwcGVycykKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoaGFybW9ueSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJldGljdWxhdGUpCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShSdHNuZSkKbGlicmFyeShoYXJtb255KQoKb3B0aW9ucyhmdXR1cmUuZ2xvYmFscy5tYXhTaXplID0gMWU5KQoKYGBgCgoKCgojIDIuIExvYWQgU2V1cmF0IE9iamVjdCAKYGBge3IgbG9hZF9zZXVyYXR9CgojTG9hZCBTZXVyYXQgT2JqZWN0IG1lcmdlZCBmcm9tIGNlbGwgbGluZXMgYW5kIGEgY29udHJvbChQQk1DKSBhZnRlciBmaWx0cmF0aW9uCmxvYWQoIi4uLy4uLy4uLzAtSU1QLU9CSkVDVFMvQWxsX1NhbXBsZXNfTWVyZ2VkX3dpdGhfMTB4X0F6aXRtdXRoX0Fubm90YXRlZF9TQ1RfSFBDX3dpdGhvdXRfaGFybW9ueV9pbnRlZ3JhdGlvbi5yb2JqIikKCkFsbF9zYW1wbGVzX01lcmdlZAoKYGBgCgoKCiMgMy4gRGF0YSBQUkVQQVJBVElPTiBhbmQgSGFybW9ueSBJbnRlZ3JhdGlvbi0xCmBgYHtyIGRhdGExLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCiMgQ3JlYXRlIGEgbmV3IG1ldGFkYXRhIGNvbHVtbiBmb3IgZ3JvdXBpbmcKQWxsX3NhbXBsZXNfTWVyZ2VkJHNhbXBsZV9ncm91cCA8LSBjYXNlX3doZW4oCiAgZ3JlcGwoIl5MIiwgQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZSkgfiAiQ2VsbF9MaW5lIiwKICBBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lID09ICJQQk1DIiB+ICJQQk1DIiwKICBBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lID09ICJQQk1DXzEweCIgfiAiUEJNQ18xMHgiLAogIFRSVUUgfiAiT3RoZXIiCikKCiMgQ3JlYXRlIHRoZSBjZWxsIGxpbmUgZ3JvdXBpbmcgY29ycmVjdGx5CkFsbF9zYW1wbGVzX01lcmdlZCRjZWxsX2xpbmVfZ3JvdXAgPC0gY2FzZV93aGVuKAogIGdyZXBsKCJeTFsxLTJdIiwgQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZSkgfiAiUDEiLAogIGdyZXBsKCJeTFszLTRdIiwgQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZSkgfiAiUDIiLAogIGdyZXBsKCJeTFs1LTddIiwgQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZSkgfiAiUDMiLAogIEFsbF9zYW1wbGVzX01lcmdlZCRjZWxsX2xpbmUgPT0gIlBCTUMiIH4gIlBCTUMiLAogIEFsbF9zYW1wbGVzX01lcmdlZCRjZWxsX2xpbmUgPT0gIlBCTUNfMTB4IiB+ICJQQk1DXzEweCIsCiAgVFJVRSB+ICJPdGhlciIgICMgVGhpcyBjYXRjaGVzIGFueSB1bmV4cGVjdGVkIHZhbHVlcwopCgpsaWJyYXJ5KGhhcm1vbnkpCgpBbGxfc2FtcGxlc19NZXJnZWQgPC0gUnVuSGFybW9ueSgKICBvYmplY3QgPSBBbGxfc2FtcGxlc19NZXJnZWQsCiAgZ3JvdXAuYnkudmFycyA9ICJzYW1wbGVfZ3JvdXAiLAogIGRpbXMudXNlID0gMToyMiwgICMgSW5jcmVhc2VkIHRvIGNhcHR1cmUgbW9yZSB2YXJpYXRpb24KICB0aGV0YSA9IGMoMC41KSwgICMgQWRqdXN0IHRoZXNlIHZhbHVlcyBhcyBuZWVkZWQKICBwbG90X2NvbnZlcmdlbmNlID0gVFJVRQopCgojIFJ1biBVTUFQIG9uIHRoZSBuZXcgSGFybW9ueSByZWR1Y3Rpb24KQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFJ1blVNQVAoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIGRpbXMgPSAxOjIyLCByZWR1Y3Rpb24ubmFtZSA9ICJ1bWFwLmhhcm1vbnkiKQoKIyBGaW5kIG5laWdoYm9ycyBhbmQgY2x1c3RlcnMgdXNpbmcgdGhlIEhhcm1vbnkgcmVkdWN0aW9uCkFsbF9zYW1wbGVzX01lcmdlZCA8LSBGaW5kTmVpZ2hib3JzKEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gImhhcm1vbnkiLCBkaW1zID0gMToyMikKQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIEZpbmRDbHVzdGVycyhBbGxfc2FtcGxlc19NZXJnZWQsIHJlc29sdXRpb24gPSAwLjUpCgpgYGAKCiMjICBIYXJtb255IFZpc3VhbGl6YXRpb24tMQpgYGB7ciBoYXJtb255LXZpc3VhbGl6YXRpb24xLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCgpwMSA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gInNhbXBsZV9ncm91cCIsIGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKcDIgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJjZWxsX2xpbmVfZ3JvdXAiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKcDMgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKCnAxICsgcDIgKyBwMwoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJzYW1wbGVfZ3JvdXAiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJjZWxsX2xpbmVfZ3JvdXAiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKCgoKIyBDb21wYXJlIHdpdGggb3JpZ2luYWwgVU1BUApwNCA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJPcmlnaW5hbCBJbnRlZ3JhdGlvbiAtIEJ5IENlbGwgTGluZSIpCnA1IDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIk9yaWdpbmFsIEludGVncmF0aW9uIC0gQnkgQ2x1c3RlcnMiKQoKIyBQcmludCB0aGUgcGxvdHMKcHJpbnQocDQgKyBwNSkKCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIk9yaWdpbmFsIEludGVncmF0aW9uIC0gQnkgQ2VsbCBMaW5lIikKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiT3JpZ2luYWwgSW50ZWdyYXRpb24gLSBCeSBDbHVzdGVycyIpCgojIFZpc3VhbGl6ZSByZXN1bHRzCnA2IDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIiwgbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIkhhcm1vbnkgSW50ZWdyYXRpb24gLSBCeSBDZWxsIExpbmUiKQpwNyA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIkhhcm1vbnkgSW50ZWdyYXRpb24gLSBCeSBDbHVzdGVycyIpCiMgUHJpbnQgdGhlIHBsb3RzCnByaW50KHA2ICsgcDcpCgpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsIGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJIYXJtb255IEludGVncmF0aW9uIC0gQnkgQ2VsbCBMaW5lIikKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJzZXVyYXRfY2x1c3RlcnMiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJIYXJtb255IEludGVncmF0aW9uIC0gQnkgQ2x1c3RlcnMiKQpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIkhhcm1vbnkgSW50ZWdyYXRpb24gLSBBbm5vdGF0aW9ucyIpCgpgYGAKIyA0LiBEYXRhIFBSRVBBUkFUSU9OIGFuZCBIYXJtb255IEludGVncmF0aW9uLTIKYGBge3IgZGF0YTIsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKbGlicmFyeShoYXJtb255KQoKQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFJ1bkhhcm1vbnkoCiAgb2JqZWN0ID0gQWxsX3NhbXBsZXNfTWVyZ2VkLAogIGdyb3VwLmJ5LnZhcnMgPSAiY2VsbF9saW5lX2dyb3VwIiwKICBkaW1zLnVzZSA9IDE6MjIsICAjIEluY3JlYXNlZCB0byBjYXB0dXJlIG1vcmUgdmFyaWF0aW9uCiAgdGhldGEgPSBjKDAuNSksICAjIEFkanVzdCB0aGVzZSB2YWx1ZXMgYXMgbmVlZGVkCiAgcGxvdF9jb252ZXJnZW5jZSA9IFRSVUUKKQoKIyBSdW4gVU1BUCBvbiB0aGUgbmV3IEhhcm1vbnkgcmVkdWN0aW9uCkFsbF9zYW1wbGVzX01lcmdlZCA8LSBSdW5VTUFQKEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gImhhcm1vbnkiLCBkaW1zID0gMToyMiwgcmVkdWN0aW9uLm5hbWUgPSAidW1hcC5oYXJtb255IikKCiMgRmluZCBuZWlnaGJvcnMgYW5kIGNsdXN0ZXJzIHVzaW5nIHRoZSBIYXJtb255IHJlZHVjdGlvbgpBbGxfc2FtcGxlc19NZXJnZWQgPC0gRmluZE5laWdoYm9ycyhBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJoYXJtb255IiwgZGltcyA9IDE6MjIpCkFsbF9zYW1wbGVzX01lcmdlZCA8LSBGaW5kQ2x1c3RlcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZXNvbHV0aW9uID0gMC41KQoKYGBgCgojIyAgSGFybW9ueSBWaXN1YWxpemF0aW9uLTIKYGBge3IgaGFybW9ueS12aXN1YWxpemF0aW9uMiwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CgoKcDEgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJzYW1wbGVfZ3JvdXAiLCBsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCnAyIDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lX2dyb3VwIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCnAzIDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCgpwMSArIHAyICsgcDMKCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAic2FtcGxlX2dyb3VwIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lX2dyb3VwIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpCgoKCiMgQ29tcGFyZSB3aXRoIG9yaWdpbmFsIFVNQVAKcDQgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiT3JpZ2luYWwgSW50ZWdyYXRpb24gLSBCeSBDZWxsIExpbmUiKQpwNSA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJzZXVyYXRfY2x1c3RlcnMiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJPcmlnaW5hbCBJbnRlZ3JhdGlvbiAtIEJ5IENsdXN0ZXJzIikKCiMgUHJpbnQgdGhlIHBsb3RzCnByaW50KHA0ICsgcDUpCgpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJPcmlnaW5hbCBJbnRlZ3JhdGlvbiAtIEJ5IENlbGwgTGluZSIpCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIk9yaWdpbmFsIEludGVncmF0aW9uIC0gQnkgQ2x1c3RlcnMiKQoKIyBWaXN1YWxpemUgcmVzdWx0cwpwNiA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsIGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJIYXJtb255IEludGVncmF0aW9uIC0gQnkgQ2VsbCBMaW5lIikKcDcgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJzZXVyYXRfY2x1c3RlcnMiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJIYXJtb255IEludGVncmF0aW9uIC0gQnkgQ2x1c3RlcnMiKQojIFByaW50IHRoZSBwbG90cwpwcmludChwNiArIHA3KQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLCBsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiSGFybW9ueSBJbnRlZ3JhdGlvbiAtIEJ5IENlbGwgTGluZSIpCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiSGFybW9ueSBJbnRlZ3JhdGlvbiAtIEJ5IENsdXN0ZXJzIikKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJIYXJtb255IEludGVncmF0aW9uIC0gQW5ub3RhdGlvbnMiKQoKYGBgCgoKIyA3LiBEYXRhIFBSRVBBUkFUSU9OIGFuZCBIYXJtb255IEludGVncmF0aW9uLTMKYGBge3IgZGF0YTMsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBDcmVhdGUgYSBuZXcgbWV0YWRhdGEgY29sdW1uIGZvciBncm91cGluZwpBbGxfc2FtcGxlc19NZXJnZWQkc2FtcGxlX2dyb3VwIDwtIGNhc2Vfd2hlbigKICBncmVwbCgiXkwiLCBBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lKSB+ICJDZWxsX0xpbmUiLAogIEFsbF9zYW1wbGVzX01lcmdlZCRjZWxsX2xpbmUgPT0gIlBCTUMiIH4gIlBCTUMiLAogIEFsbF9zYW1wbGVzX01lcmdlZCRjZWxsX2xpbmUgPT0gIlBCTUNfMTB4IiB+ICJQQk1DXzEweCIsCiAgVFJVRSB+ICJPdGhlciIKKQoKIyBDcmVhdGUgdGhlIGNlbGwgbGluZSBncm91cGluZyBjb3JyZWN0bHkKQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZV9ncm91cCA8LSBjYXNlX3doZW4oCiAgZ3JlcGwoIl5MWzEtMl0iLCBBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lKSB+ICJQMSIsCiAgZ3JlcGwoIl5MWzMtNF0iLCBBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lKSB+ICJQMiIsCiAgZ3JlcGwoIl5MWzUtN10iLCBBbGxfc2FtcGxlc19NZXJnZWQkY2VsbF9saW5lKSB+ICJQMyIsCiAgQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZSA9PSAiUEJNQyIgfiAiUEJNQyIsCiAgQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZSA9PSAiUEJNQ18xMHgiIH4gIlBCTUNfMTB4IiwKICBUUlVFIH4gIk90aGVyIiAgIyBUaGlzIGNhdGNoZXMgYW55IHVuZXhwZWN0ZWQgdmFsdWVzCikKCmxpYnJhcnkoaGFybW9ueSkKCkFsbF9zYW1wbGVzX01lcmdlZCA8LSBSdW5IYXJtb255KAogIG9iamVjdCA9IEFsbF9zYW1wbGVzX01lcmdlZCwKICBncm91cC5ieS52YXJzID0gImNlbGxfbGluZSIsCiAgZGltcy51c2UgPSAxOjIyLCAgIyBJbmNyZWFzZWQgdG8gY2FwdHVyZSBtb3JlIHZhcmlhdGlvbgogIHRoZXRhID0gYygwLjUpLCAgIyBBZGp1c3QgdGhlc2UgdmFsdWVzIGFzIG5lZWRlZAogIHBsb3RfY29udmVyZ2VuY2UgPSBUUlVFCikKCiMgUnVuIFVNQVAgb24gdGhlIG5ldyBIYXJtb255IHJlZHVjdGlvbgpBbGxfc2FtcGxlc19NZXJnZWQgPC0gUnVuVU1BUChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJoYXJtb255IiwgZGltcyA9IDE6MjIsIHJlZHVjdGlvbi5uYW1lID0gInVtYXAuaGFybW9ueSIpCgojIEZpbmQgbmVpZ2hib3JzIGFuZCBjbHVzdGVycyB1c2luZyB0aGUgSGFybW9ueSByZWR1Y3Rpb24KQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIEZpbmROZWlnaGJvcnMoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIGRpbXMgPSAxOjIyKQpBbGxfc2FtcGxlc19NZXJnZWQgPC0gRmluZENsdXN0ZXJzKEFsbF9zYW1wbGVzX01lcmdlZCwgcmVzb2x1dGlvbiA9IDAuNSkKCmBgYAoKIyMgIEhhcm1vbnkgVmlzdWFsaXphdGlvbi0zCmBgYHtyIGhhcm1vbnktdmlzdWFsaXphdGlvbjMsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKCnAxIDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAic2FtcGxlX2dyb3VwIiwgbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQpwMiA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZV9ncm91cCIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQpwMyA8LSBEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQoKcDEgKyBwMiArIHAzCgpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gInNhbXBsZV9ncm91cCIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZV9ncm91cCIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQoKCgojIENvbXBhcmUgd2l0aCBvcmlnaW5hbCBVTUFQCnA0IDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gImNlbGxfbGluZSIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIk9yaWdpbmFsIEludGVncmF0aW9uIC0gQnkgQ2VsbCBMaW5lIikKcDUgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiT3JpZ2luYWwgSW50ZWdyYXRpb24gLSBCeSBDbHVzdGVycyIpCgojIFByaW50IHRoZSBwbG90cwpwcmludChwNCArIHA1KQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiT3JpZ2luYWwgSW50ZWdyYXRpb24gLSBCeSBDZWxsIExpbmUiKQpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJzZXVyYXRfY2x1c3RlcnMiLGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkgKyAKICBnZ3RpdGxlKCJPcmlnaW5hbCBJbnRlZ3JhdGlvbiAtIEJ5IENsdXN0ZXJzIikKCiMgVmlzdWFsaXplIHJlc3VsdHMKcDYgPC0gRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIHJlZHVjdGlvbiA9ICJ1bWFwLmhhcm1vbnkiLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLCBsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiSGFybW9ueSBJbnRlZ3JhdGlvbiAtIEJ5IENlbGwgTGluZSIpCnA3IDwtIERpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiSGFybW9ueSBJbnRlZ3JhdGlvbiAtIEJ5IENsdXN0ZXJzIikKIyBQcmludCB0aGUgcGxvdHMKcHJpbnQocDYgKyBwNykKCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAiY2VsbF9saW5lIiwgbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIkhhcm1vbnkgSW50ZWdyYXRpb24gLSBCeSBDZWxsIExpbmUiKQpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgcmVkdWN0aW9uID0gInVtYXAuaGFybW9ueSIsIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIsbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKSArIAogIGdndGl0bGUoIkhhcm1vbnkgSW50ZWdyYXRpb24gLSBCeSBDbHVzdGVycyIpCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIixsYWJlbCA9IFQsIGxhYmVsLmJveCA9IFQpICsgCiAgZ2d0aXRsZSgiSGFybW9ueSBJbnRlZ3JhdGlvbiAtIEFubm90YXRpb25zIikKCmBgYAoKIyMgIE1hcmtlciBHZW5lIFZpc3VhbGl6YXRpb24KYGBge3IgZmVhdHVyZXBsb3QtaGFybW9ueSwgZmlnLmhlaWdodD0xNCwgZmlnLndpZHRoPTE4fQoKCiMgU2V0IG1hcmtlciBnZW5lcyBzcGVjaWZpYyB0byByZXF1ZXN0ZWQgaW1tdW5lIGNlbGwgdHlwZXMKbXlmZWF0dXJlcyA8LSBjKCJDRDE5IiwgIkNENzlBIiwgIk1TNEExIiwgIyBCIGNlbGxzCiAgICAgICAgICAgICAgICAiQ0QxNCIsICJMWVoiLCAiRkNHUjNBIiwgIyBNb25vY3l0ZXMKICAgICAgICAgICAgICAgICJDU0YxUiIsICJDRDY4IiwgIyBNYWNyb3BoYWdlcwogICAgICAgICAgICAgICAgIk5LRzciLCAiR05MWSIsICJLSVIzREwxIiwgIyBOSyBjZWxscwogICAgICAgICAgICAgICAgIk1LSTY3IiwgIyBQcm9saWZlcmF0aW5nIE5LIGNlbGxzCiAgICAgICAgICAgICAgICAiQ0QzNCIsICJLSVQiLCAjIEhTUENzCiAgICAgICAgICAgICAgICAiQ0QzRSIsICJDQ1I3IiwgIyBUIGNlbGxzCiAgICAgICAgICAgICAgICAiU0VMTCIsICJDRDQ1Uk8iLCAjIFRuYWl2ZSwgVGNtCiAgICAgICAgICAgICAgICAiQ0Q0NCIsICJDRDQ1UkEiKSAjIFRlbSwgVGVtcmEKIyBWaXN1YWxpemUgbWFya2VyIGdlbmVzIGZvciBIYXJtb255CkZlYXR1cmVQbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgZmVhdHVyZXMgPSBteWZlYXR1cmVzLCByZWR1Y3Rpb24gPSAidW1hcC5oYXJtb255IiwgbmNvbCA9IDQpICsgCiAgZ2d0aXRsZSgiTWFya2VyIEdlbmUgRXhwcmVzc2lvbiAtIEhhcm1vbnkgSW50ZWdyYXRpb24iKSArCiAgTm9MZWdlbmQoKQpgYGAKCiMgNi4gU2F2ZSB0aGUgU2V1cmF0IG9iamVjdCBhcyBhbiBSb2JqIGZpbGUKYGBge3Igc2F2ZVJPQkp9CgpzYXZlKEFsbF9zYW1wbGVzX01lcmdlZCwgZmlsZSA9ICIuLi8uLi8uLi8wLUlNUC1PQkpFQ1RTL0hhcm1vbnlfaW50ZWdyYXRlZF9BbGxfc2FtcGxlc19NZXJnZWRfd2l0aF9QQk1DMTB4LlJvYmoiKQoKYGBgCgoKCgo=