Introduction
scRepertoire is designed to take filter contig outputs from
the 10x Genomics Cell Ranger pipeline, process that data to assign
clonotype based on two TCR or Ig chains and analyze the clonotype
dynamics. The latter can be separated into 1) clonotype-only analysis
functions, such as unique clonotypes or clonal space quantification, and
2) interaction with mRNA expression data using Seurat or
SingleCellExperiment packages.
Load libraries
Load Seurat Object
1. Load contigs
scRepertoire functions using the
filtered_contig_annotations.csv output from the 10x Genomics Cell
Ranger. This file is located in the ./outs/ directory of the VDJ
alignment folder. To generate a list of contigs to use for
scRepertoire:
2. Combining Contigs into Clones
contig_list <- list(L1, L2, L3_B, L4_B,L5,L6, L7)
contig_list_with_PBMC <- list(L1, L2, L3_B, L4_B,L5,L6, L7, PBMC)
combined.TCR <- combineTCR(contig_list,
samples = c("L1", "L2", "L3_B", "L4_B", "L5", "L6", "L7"),
removeNA = FALSE,
removeMulti = FALSE,
filterMulti = FALSE)
combined.TCR_with_PBMC <- combineTCR(contig_list_with_PBMC,
samples = c("L1", "L2", "L3_B", "L4_B", "L5", "L6", "L7",
"PBMC"),
removeNA = FALSE,
removeMulti = FALSE,
filterMulti = FALSE)
# exportClones(combined.TCR,
# write.file = TRUE,
# dir = "../TCR_Analysis/",
# file.name = "clones.csv")
#
# exportClones(combined.TCR_with_PBMC,
# write.file = TRUE,
# dir = "../TCR_Analysis/",
# file.name = "clones_with_PBMC.csv")
head(combined.TCR_with_PBMC[[1]])
NA
3. Basic Clonal Visualizations
3.1. clonalQuant
#clonalQuant
clonalQuant(combined.TCR,
cloneCall="strict",
chain = "both",
scale = TRUE)

clonalQuant(combined.TCR_with_PBMC,
cloneCall="strict",
chain = "both",
scale = TRUE)

clonalQuant(combined.TCR, cloneCall = "gene", group.by = "sample", scale = TRUE)

clonalQuant(combined.TCR_with_PBMC, cloneCall = "gene", group.by = "sample", scale = TRUE)

3.2 clonalAbundance
#clonalAbundance
clonalAbundance(combined.TCR_with_PBMC,
cloneCall = "gene", palette = "Zissou 1",
scale = FALSE)+
scale_fill_manual(values = hcl.colors(8,"geyser"))

clonalAbundance(combined.TCR_with_PBMC,
cloneCall = "gene", palette = "Zissou 1",
scale = TRUE)

3.3 clonalLength
#clonalLength
clonalLength(combined.TCR_with_PBMC,
cloneCall="nt",
chain = "both")

clonalLength(combined.TCR_with_PBMC,
cloneCall="aa",
chain = "both")

#TRA
clonalLength(combined.TCR_with_PBMC,
cloneCall="nt",
chain = "TRA",
scale = TRUE)

clonalLength(combined.TCR_with_PBMC,
cloneCall="aa",
chain = "TRA",
scale = TRUE)

#TRB
clonalLength(combined.TCR_with_PBMC,
cloneCall="nt",
chain = "TRB",
scale = TRUE)

clonalLength(combined.TCR_with_PBMC,
cloneCall="aa",
chain = "TRB",
scale = TRUE)

3.4 clonalCompare
# clonalCompare
clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L1", "L2"),
cloneCall="aa",
graph = "alluvial")

clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L3_B", "L4_B"),
cloneCall="aa",
graph = "alluvial")

clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L5", "L6","L7"),
cloneCall="aa",
graph = "alluvial")

clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L5","L6"),
cloneCall="aa",
graph = "alluvial")

clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L5","L7"),
cloneCall="aa",
graph = "alluvial")

clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L6","L7"),
cloneCall="aa",
graph = "alluvial")

clonalCompare(combined.TCR_with_PBMC,
top.clones = 10,
samples = c("L1", "L2", "L3_B", "L4_B", "L5", "L6", "L7", "PBMC"),
cloneCall="aa",
graph = "alluvial")

# clonalCompare(combined.TCR_with_PBMC,
# top.clones = 10,
# highlight.clones = c("CVVSDNTGGFKTIF_CASSVRRERANTGELFF", "NA_CASSVRRERANTGELFF"),
# relabel.clones = TRUE,
# samples = c("L1", "L2"),
# cloneCall="aa",
# graph = "alluvial")
#
#
# clonalCompare(combined.TCR_with_PBMC, clones = c("CVVSDNTGGFKTIF_CASSVRRERANTGELFF", "NA_CASSVRRERANTGELFF"),
# relabel.clones = TRUE, samples = c("L1", "L2"), cloneCall = "aa", graph = "alluvial")
3.5 clonalScatter
#clonalScatter
clonalScatter(combined.TCR_with_PBMC,
cloneCall ="gene",
x.axis = "L1",
y.axis = "L2",
dot.size = "total",
graph = "proportion")

clonalScatter(combined.TCR_with_PBMC,
cloneCall ="gene",
x.axis = "L3_B",
y.axis = "L4_B",
dot.size = "total",
graph = "proportion")

clonalScatter(combined.TCR_with_PBMC,
cloneCall ="gene",
x.axis = "L5",
y.axis = "L6",
dot.size = "total",
graph = "proportion")

clonalScatter(combined.TCR_with_PBMC,
cloneCall ="gene",
x.axis = "L5",
y.axis = "L7",
dot.size = "total",
graph = "proportion")

clonalScatter(combined.TCR_with_PBMC,
cloneCall ="gene",
x.axis = "L6",
y.axis = "L7",
dot.size = "total",
graph = "proportion")

4. Visualizing Clonal Dynamics
4.1 clonalHomeostasis
# Visualizing Clonal Dynamics
# clonalHomeostasis
clonalHomeostasis(combined.TCR_with_PBMC,
cloneCall = "gene")

clonalHomeostasis(combined.TCR_with_PBMC,
cloneCall = "gene",
cloneSize = c(Rare = 0.001, Small = 0.01, Medium = 0.1, Large = 0.3, Hyperexpanded =1))

4.2 clonalProportion
# clonalProportion
clonalProportion(combined.TCR_with_PBMC,
cloneCall = "gene")

clonalProportion(combined.TCR_with_PBMC,
cloneCall = "nt",
clonalSplit = c(1, 5, 10, 100, 1000, 10000))

5. Summarizing Repertoires
# Summarizing Repertoires
#percentAA
percentAA(combined.TCR,
chain = "TRB",
aa.length = 20)
Warning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generated

# positionalEntropy
# We can also quantify the level of entropy/diversity across amino acid residues along the cdr3 sequence. positionalEntropy() combines the quantification by residue of percentAA() with the diversity calls in clonalDiversity().
#
# method
#
# “shannon” - Shannon Diversity
# “inv.simpson” - Inverse Simpson Diversity
# “norm.entropy” - Normalized Entropy
positionalEntropy(combined.TCR_with_PBMC,
chain = "TRB",
aa.length = 20)
Warning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generatedWarning: invalid factor level, NA generated

# positionalProperty
# Like positionalEntropy(), we can also examine a series of amino acid properties along the cdr3 sequences using positionalProperty(). Important differences from the above function for positionalProperty() is dropping NA values as they would void the mean calculation. positionalProperty() also display a ribbon with the 95% confidence interval surrounding the mean value for the selected properties.
#
# method
#
# “Atchley” - Atchley Factors
# “Kidera” - Kidera Factors
# “stScales” - stScales Vectors
# “tScales” - tScales Vectors
# “VHSE” - Vectors of Hydrophobic, Steric, and Electronic properties
# positionalProperty(combined.TCR_with_PBMC[c(1,2)],
# chain = "TRB",
# aa.length = 20,
# method = "Atchley") +
# scale_color_manual(values = hcl.colors(5, "inferno")[c(2,4)])
#
# positionalProperty(combined.TCR_with_PBMC[c(3,4)],
# chain = "TRB",
# aa.length = 20,
# method = "Atchley") +
# scale_color_manual(values = hcl.colors(5, "inferno")[c(2,4)])
#
# positionalProperty(combined.TCR_with_PBMC[c(5,6)],
# chain = "TRB",
# aa.length = 20,
# method = "Atchley") +
# scale_color_manual(values = hcl.colors(5, "inferno")[c(2,4)])
#
# positionalProperty(combined.TCR_with_PBMC[c(5,7)],
# chain = "TRB",
# aa.length = 20,
# method = "Atchley") +
# scale_color_manual(values = hcl.colors(5, "inferno")[c(2,4)])
#
#
# positionalProperty(combined.TCR_with_PBMC[c(6,7)],
# chain = "TRB",
# aa.length = 20,
# method = "Atchley") +
# scale_color_manual(values = hcl.colors(5, "inferno")[c(2,4)])
#
# positionalProperty(combined.TCR_with_PBMC[c(5,6,7)],
# chain = "TRB",
# aa.length = 20,
# method = "Atchley") +
# scale_color_manual(values = hcl.colors(5, "inferno")[c(2,4)])
# vizGenes
# A visualization of the relative usage of genes of the TCR or BCR, using vizGenes(). There is some functional crossover between vizGenes() and two functions below called percentGenes() and percentVJ(). But vizGenes() is more adaptable to allow for comparisons across chains, scaling, etc.
vizGenes(combined.TCR_with_PBMC,
x.axis = "TRBV",
y.axis = NULL,
plot = "barplot",
scale = TRUE)

vizGenes(combined.TCR_with_PBMC,
x.axis = "TRAV",
y.axis = NULL,
plot = "barplot",
scale = TRUE)

vizGenes(combined.TCR[c(1,2,3,4,5,6,7)],
x.axis = "TRBV",
y.axis = "TRBJ",
plot = "heatmap",
scale = TRUE)

vizGenes(combined.TCR[c(1,2,3,4,5,6,7)],
x.axis = "TRAV",
y.axis = "TRAJ",
plot = "heatmap",
scale = TRUE)

# For the P17 patient samples, what if we are interested in chain pairings, we can look at TRBV and TRAV at the same time using them as inputs to x.axis and y.axis.
vizGenes(combined.TCR[c(1,2)],
x.axis = "TRBV",
y.axis = "TRAV",
plot = "heatmap",
scale = FALSE)

# percentGenes
# Quantify the proportion of V or J gene usage with percentGenes(). Like percentAA(), we select the chain of interest and then indicate the gene of interest with the gene parameter. Two major limitations of percentGenes() are, 1) the function quantifies only V or J genes, and 2) the quantification of the genes are limited to all the V or J genes seen across the samples, not all possible V or J genes.
percentGenes(combined.TCR_with_PBMC,
chain = "TRB",
gene = "Vgene")

percentGenes(combined.TCR_with_PBMC,
chain = "TRA",
gene = "Vgene")

percentGenes(combined.TCR_with_PBMC,
chain = "TRB",
gene = "Jgene")

percentGenes(combined.TCR_with_PBMC,
chain = "TRA",
gene = "Jgene")

# percentVJ
# Quantify the proportion of V and J gene usage with percentVJ(). Like percentGenes(), this function will quantify the percentage of V and J paired together across individual repertoires. The output can be visualized using a heatmap or as input for further dimensional reduction.
percentVJ(combined.TCR_with_PBMC,
chain = "TRB")

percentVJ(combined.TCR_with_PBMC,
chain = "TRA")

# percentKmer
# Another quantification of the composition of the CDR3 sequence is to define motifs by sliding across the amino acid or nucleotide sequences at set intervals resulting in substrings or kmers.
#
# motif.length
#
# Numerical value for the length of the kmer.
# top.motifs
#
# Display the most variable genes determined by mean absolute deviation (MAD).
percentKmer(combined.TCR_with_PBMC,
cloneCall = "aa",
chain = "TRB",
motif.length = 3,
top.motifs = 25)

percentKmer(combined.TCR_with_PBMC,
cloneCall = "aa",
chain = "TRA",
motif.length = 3,
top.motifs = 25)

percentKmer(combined.TCR_with_PBMC,
cloneCall = "nt",
chain = "TRB",
motif.length = 3,
top.motifs = 25)

percentKmer(combined.TCR_with_PBMC,
cloneCall = "nt",
chain = "TRA",
motif.length = 3,
top.motifs = 25)

6. Comparing Clonal Diversity and Overlap
# clonalDiversity
clonalDiversity(combined.TCR_with_PBMC,
cloneCall = "gene")

#clonalSizeDistribution
clonalSizeDistribution(combined.TCR_with_PBMC,
cloneCall = "aa",
method= "ward.D2")

#clonalOverlap
clonalOverlap(combined.TCR_with_PBMC,
cloneCall = "strict",
method = "morisita")

clonalOverlap(combined.TCR_with_PBMC,
cloneCall = "strict",
method = "raw")

7. Combining Clones and Single-Cell Objects
# Combining Clones and Single-Cell Objects
#Getting a sample of a Seurat object
scRep_example <- get(data("All_samples_Merged"))
Warning: data set 'All_samples_Merged' not found
#Define color palette
colorblind_vector <- hcl.colors(n=7, palette = "inferno", fixup = TRUE)
scRep_example <- combineExpression(combined.TCR,
scRep_example,
cloneCall="gene",
group.by = "sample",
proportion = FALSE,
cloneSize=c(Single=1, Small=5, Medium=20, Large=100, Hyperexpanded=500))
DimPlot(scRep_example, group.by = "cloneSize")

DimPlot(scRep_example, group.by = "cloneSize") +
scale_color_manual(values=rev(colorblind_vector[c(1,3,4,5,6)]))

NA
NA
8. Visualizations for Single-Cell Objects
# Visualizations for Single-Cell Objects
# clonalOverlay
#Adding patient information
scRep_example$Patient_origin <- substr(scRep_example$orig.ident, 1,3)
clonalOverlay(scRep_example,
reduction = "umap",
freq.cutpoint = 1,
bins = 10,
facet.by = "Patient_origin") +
guides(color = "none")

#clonalNetwork
#ggraph needs to be loaded due to issues with ggplot
library(ggraph)
Attaching package: 'ggraph'
The following object is masked from 'package:sp':
geometry
clonalNetwork(scRep_example,
reduction = "umap",
group.by = "seurat_clusters",
filter.clones = NULL,
filter.identity = NULL,
cloneCall = "aa")

#Examining Cluster 3 only
clonalNetwork(scRep_example,
reduction = "umap",
group.by = "seurat_clusters",
filter.identity = 8,
cloneCall = "aa")

shared.clones <- clonalNetwork(scRep_example,
reduction = "umap",
group.by = "seurat_clusters",
cloneCall = "aa",
exportClones = TRUE)
head(shared.clones)
scRep_example <- highlightClones(scRep_example,
cloneCall= "aa",
sequence = c("CATGPNGSSNTGKLIF;CALSNNARLMF_CSATTGFYGYTF",
"CAYSESGGSNYKLTF_CSALAGGYTDTQYF",
"CLVGETGRRALTF_CSARGDRGQPQHF",
"CLVGETGRRALTF_CSARGDRGQPQHF;CATSDFKQVSNQPQHF",
"CATGPNGSSNTGKLIF_CSATTGFYGYTF",
"NA_CSARGDRGQPQHF"))
Seurat::DimPlot(scRep_example, group.by = "highlight") +
ggplot2::theme(plot.title = element_blank())

#clonalOccupy
clonalOccupy(scRep_example,
x.axis = "seurat_clusters")

clonalOccupy(scRep_example,
x.axis = "ident",
proportion = TRUE,
label = FALSE)

# alluvialClones
# scRep_example$Patient_origin <- substr(scRep_example$orig.ident, 8,8)
#
# alluvialClones(scRep_example,
# cloneCall = "aa",
# y.axes = c("Patient_origin", "orig.ident", "Cell_line_Immunophenotype"),
# color = c("CATGPNGSSNTGKLIF;CALSNNARLMF_CSATTGFYGYTF",
# "CAYSESGGSNYKLTF_CSALAGGYTDTQYF",
# "CLVGETGRRALTF_CSARGDRGQPQHF",
# "CLVGETGRRALTF_CSARGDRGQPQHF;CATSDFKQVSNQPQHF",
# "CATGPNGSSNTGKLIF_CSATTGFYGYTF",
# "NA_CSARGDRGQPQHF")) +
# scale_fill_manual(values = c("grey", colorblind_vector[3]))
#
#
#
# alluvialClones(scRep_example,
# cloneCall = "gene",
# y.axes = c("Patient_origin", "orig.ident", "Cell_line_Immunophenotype"),
# color = "ident")
library(circlize)
library(scales)
circles <- getCirclize(scRep_example,
group.by = "seurat_clusters")
#Just assigning the normal colors to each cluster
grid.cols <- hue_pal()(length(unique(scRep_example$seurat_clusters)))
names(grid.cols) <- unique(scRep_example$seurat_clusters)
#Graphing the chord diagram
chordDiagram(circles, self.link = 1, grid.col = grid.cols)

circles <- getCirclize(scRep_example, group.by = "cell_line", proportion = TRUE)
grid.cols <- scales::hue_pal()(length(unique(scRep_example@active.ident)))
names(grid.cols) <- levels(scRep_example@active.ident)
chordDiagram(circles,
self.link = 1,
grid.col = grid.cols,
directional = 1,
direction.type = "arrows",
link.arr.type = "big.arrow")

LS0tCnRpdGxlOiAiVENSIEFuYWx5c2lzIgphdXRob3I6ICJOYXNpciBNYWhtb29kIEFiYmFzaSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgI3JtZGZvcm1hdHM6OnJlYWR0aGVkb3duCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3Rpb24KCioqc2NSZXBlcnRvaXJlIGlzIGRlc2lnbmVkIHRvIHRha2UgZmlsdGVyIGNvbnRpZyBvdXRwdXRzIGZyb20gdGhlIDEweCBHZW5vbWljcyBDZWxsIFJhbmdlciBwaXBlbGluZSwgcHJvY2VzcyB0aGF0IGRhdGEgdG8gYXNzaWduIGNsb25vdHlwZSBiYXNlZCBvbiB0d28gVENSIG9yIElnIGNoYWlucyBhbmQgYW5hbHl6ZSB0aGUgY2xvbm90eXBlIGR5bmFtaWNzLiBUaGUgbGF0dGVyIGNhbiBiZSBzZXBhcmF0ZWQgaW50byAxKSBjbG9ub3R5cGUtb25seSBhbmFseXNpcyBmdW5jdGlvbnMsIHN1Y2ggYXMgdW5pcXVlIGNsb25vdHlwZXMgb3IgY2xvbmFsIHNwYWNlIHF1YW50aWZpY2F0aW9uLCBhbmQgMikgaW50ZXJhY3Rpb24gd2l0aCBtUk5BIGV4cHJlc3Npb24gZGF0YSB1c2luZyBTZXVyYXQgb3IgU2luZ2xlQ2VsbEV4cGVyaW1lbnQgcGFja2FnZXMuKioKCiMgTG9hZCBsaWJyYXJpZXMKCmBgYHtyIGxpYnJhcmllcywgaW5jbHVkZT1GQUxTRX0KCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KFNldXJhdE9iamVjdCkKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KEF6aW11dGgpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocm1hcmtkb3duKQpsaWJyYXJ5KHRpbnl0ZXgpCgpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShwcmVzdG8pCiNUQ1IgQW5hbHlzaXMKbGlicmFyeShzY1JlcGVydG9pcmUpCmxpYnJhcnkoU2luZ2xlQ2VsbEV4cGVyaW1lbnQpCgpsaWJyYXJ5KGNpcmNsaXplKQpsaWJyYXJ5KHNjYWxlcykKYGBgCgojIExvYWQgU2V1cmF0IE9iamVjdAoKYGBge3IgbG9hZF9zZXVyYXQsIGluY2x1ZGU9RkFMU0V9CgojTG9hZCBTZXVyYXQgT2JqZWN0IG1lcmdlZCBmcm9tIGNlbGwgbGluZXMgYW5kIGEgY29udHJvbChQQk1DKSBhZnRlciBmaWx0cmF0aW9uCmxvYWQoIi9ob21lL2Jpb2luZm8vQ2x1c3Rlcl90b19Db21wdXRlcl9UcmFuc2Zlcl9maWxlc19mb2xkZXIvQWxsX05vcm1hbC1QQk1DX0Fibm9ybWFsLWNlbGxMaW5lc19UX2NlbGxzX01lcmdlZF9Bbm5vdGF0ZWRfVU1BUF9vbl9DbHVzdGVyc190b19VU0UuUm9iaiIpCgpgYGAKCiMgMS4gTG9hZCBjb250aWdzCgoqKnNjUmVwZXJ0b2lyZSBmdW5jdGlvbnMgdXNpbmcgdGhlIGZpbHRlcmVkX2NvbnRpZ19hbm5vdGF0aW9ucy5jc3Ygb3V0cHV0IGZyb20gdGhlIDEweCBHZW5vbWljcyBDZWxsIFJhbmdlci4gVGhpcyBmaWxlIGlzIGxvY2F0ZWQgaW4gdGhlIC4vb3V0cy8gZGlyZWN0b3J5IG9mIHRoZSBWREogYWxpZ25tZW50IGZvbGRlci4gVG8gZ2VuZXJhdGUgYSBsaXN0IG9mIGNvbnRpZ3MgdG8gdXNlIGZvciBzY1JlcGVydG9pcmU6KioKCi0gICBsb2FkIHRoZSBmaWx0ZXJlZF9jb250aWdfYW5ub3RhdGlvbnMuY3N2IGZvciBlYWNoIG9mIHRoZSBzYW1wbGVzLgoKLSAgIG1ha2UgYSBsaXN0IGluIHRoZSBSIGVudmlyb25tZW50LgoKCmBgYHtyIFRDUiwgaW5jbHVkZT1GQUxTRX0KCkwxIDwtIHJlYWQuY3N2KCIvcnVuL3VzZXIvMTAwMC9ndmZzL3NtYi1zaGFyZTpzZXJ2ZXI9MTAuMTQ0LjEzNS41LHNoYXJlPWNvbW11bi9OYXNpci9BbGxfRGF0YS9BdWRyZXlfR3Jvcy9DZWxsUmFuZ2VyL0wxL291dHMvcGVyX3NhbXBsZV9vdXRzL0wxL3Zkal90L2ZpbHRlcmVkX2NvbnRpZ19hbm5vdGF0aW9ucy5jc3YiKQpMMiA8LSByZWFkLmNzdigiL3J1bi91c2VyLzEwMDAvZ3Zmcy9zbWItc2hhcmU6c2VydmVyPTEwLjE0NC4xMzUuNSxzaGFyZT1jb21tdW4vTmFzaXIvQWxsX0RhdGEvQXVkcmV5X0dyb3MvQ2VsbFJhbmdlci9MMi9vdXRzL3Blcl9zYW1wbGVfb3V0cy9MMi92ZGpfdC9maWx0ZXJlZF9jb250aWdfYW5ub3RhdGlvbnMuY3N2IikKTDNfQiA8LSByZWFkLmNzdigiL3J1bi91c2VyLzEwMDAvZ3Zmcy9zbWItc2hhcmU6c2VydmVyPTEwLjE0NC4xMzUuNSxzaGFyZT1jb21tdW4vTmFzaXIvQWxsX0RhdGEvQXVkcmV5X0dyb3MvQ2VsbFJhbmdlci9MM19DSVRFX0IvL291dHMvcGVyX3NhbXBsZV9vdXRzL0wzX0NJVEVfQi8vdmRqX3QvZmlsdGVyZWRfY29udGlnX2Fubm90YXRpb25zLmNzdiIpCkw0X0IgPC0gcmVhZC5jc3YoIi9ydW4vdXNlci8xMDAwL2d2ZnMvc21iLXNoYXJlOnNlcnZlcj0xMC4xNDQuMTM1LjUsc2hhcmU9Y29tbXVuL05hc2lyL0FsbF9EYXRhL0F1ZHJleV9Hcm9zL0NlbGxSYW5nZXIvTDRfQi9vdXRzL3Blcl9zYW1wbGVfb3V0cy9MNF9CLy92ZGpfdC9maWx0ZXJlZF9jb250aWdfYW5ub3RhdGlvbnMuY3N2IikKTDUgPC0gcmVhZC5jc3YoIi9ydW4vdXNlci8xMDAwL2d2ZnMvc21iLXNoYXJlOnNlcnZlcj0xMC4xNDQuMTM1LjUsc2hhcmU9Y29tbXVuL05hc2lyL0FsbF9EYXRhL0F1ZHJleV9Hcm9zL0NlbGxSYW5nZXIvTDUvb3V0cy9wZXJfc2FtcGxlX291dHMvTDUvdmRqX3QvZmlsdGVyZWRfY29udGlnX2Fubm90YXRpb25zLmNzdiIpCkw2IDwtIHJlYWQuY3N2KCIvcnVuL3VzZXIvMTAwMC9ndmZzL3NtYi1zaGFyZTpzZXJ2ZXI9MTAuMTQ0LjEzNS41LHNoYXJlPWNvbW11bi9OYXNpci9BbGxfRGF0YS9BdWRyZXlfR3Jvcy9DZWxsUmFuZ2VyL0w2X0NJVEUvL291dHMvcGVyX3NhbXBsZV9vdXRzL0w2X0NJVEUvL3Zkal90L2ZpbHRlcmVkX2NvbnRpZ19hbm5vdGF0aW9ucy5jc3YiKQpMNyA8LSByZWFkLmNzdigiL3J1bi91c2VyLzEwMDAvZ3Zmcy9zbWItc2hhcmU6c2VydmVyPTEwLjE0NC4xMzUuNSxzaGFyZT1jb21tdW4vTmFzaXIvQWxsX0RhdGEvQXVkcmV5X0dyb3MvQ2VsbFJhbmdlci9MNy9vdXRzL3Blcl9zYW1wbGVfb3V0cy9MNy92ZGpfdC9maWx0ZXJlZF9jb250aWdfYW5ub3RhdGlvbnMuY3N2IikKUEJNQyA8LSByZWFkLmNzdigiL3J1bi91c2VyLzEwMDAvZ3Zmcy9zbWItc2hhcmU6c2VydmVyPTEwLjE0NC4xMzUuNSxzaGFyZT1jb21tdW4vTmFzaXIvQWxsX0RhdGEvQXVkcmV5X0dyb3MvQ2VsbFJhbmdlci9QQk1DL291dHMvcGVyX3NhbXBsZV9vdXRzL1BCTUMvdmRqX3QvZmlsdGVyZWRfY29udGlnX2Fubm90YXRpb25zLmNzdiIpCgpgYGAKCgojIDIuIENvbWJpbmluZyBDb250aWdzIGludG8gQ2xvbmVzCmBgYHtyIGNvbWJpbmVkVENSLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02fQoKY29udGlnX2xpc3QgPC0gbGlzdChMMSwgTDIsIEwzX0IsIEw0X0IsTDUsTDYsIEw3KQpjb250aWdfbGlzdF93aXRoX1BCTUMgPC0gbGlzdChMMSwgTDIsIEwzX0IsIEw0X0IsTDUsTDYsIEw3LCBQQk1DKQoKY29tYmluZWQuVENSIDwtIGNvbWJpbmVUQ1IoY29udGlnX2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZXMgPSBjKCJMMSIsICJMMiIsICJMM19CIiwgIkw0X0IiLCAiTDUiLCAiTDYiLCAiTDciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTkEgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTXVsdGkgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyTXVsdGkgPSBGQUxTRSkKCmNvbWJpbmVkLlRDUl93aXRoX1BCTUMgPC0gY29tYmluZVRDUihjb250aWdfbGlzdF93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDEiLCAiTDIiLCAiTDNfQiIsICJMNF9CIiwgIkw1IiwgIkw2IiwgIkw3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQQk1DIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZU5BID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVNdWx0aSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyTXVsdGkgPSBGQUxTRSkKCiMgIGV4cG9ydENsb25lcyhjb21iaW5lZC5UQ1IsIAojICAgICAgICAgICAgICAgd3JpdGUuZmlsZSA9IFRSVUUsCiMgICAgICAgICAgICAgICBkaXIgPSAiLi4vVENSX0FuYWx5c2lzLyIsCiMgICAgICAgICAgICAgIGZpbGUubmFtZSA9ICJjbG9uZXMuY3N2IikKIyAKIyBleHBvcnRDbG9uZXMoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiMgICAgICAgICAgICAgIHdyaXRlLmZpbGUgPSBUUlVFLAojICAgICAgICAgICAgICBkaXIgPSAiLi4vVENSX0FuYWx5c2lzLyIsCiMgICAgICAgICAgICAgIGZpbGUubmFtZSA9ICJjbG9uZXNfd2l0aF9QQk1DLmNzdiIpCgpoZWFkKGNvbWJpbmVkLlRDUl93aXRoX1BCTUNbWzFdXSkKCmBgYAojIDMuIEJhc2ljIENsb25hbCBWaXN1YWxpemF0aW9ucwoKIyMgMy4xLiBjbG9uYWxRdWFudApgYGB7ciBDbG9uYWwtVmlzdWFsaXphdGlvbiwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KI2Nsb25hbFF1YW50CiBjbG9uYWxRdWFudChjb21iaW5lZC5UQ1IsIAogICAgICAgICAgICBjbG9uZUNhbGw9InN0cmljdCIsIAogICAgICAgICAgICBjaGFpbiA9ICJib3RoIiwgCiAgICAgICAgICAgIHNjYWxlID0gVFJVRSkKCgpjbG9uYWxRdWFudChjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgY2xvbmVDYWxsPSJzdHJpY3QiLCAKICAgICAgICAgICAgY2hhaW4gPSAiYm90aCIsIAogICAgICAgICAgICBzY2FsZSA9IFRSVUUpCgpjbG9uYWxRdWFudChjb21iaW5lZC5UQ1IsIGNsb25lQ2FsbCA9ICJnZW5lIiwgZ3JvdXAuYnkgPSAic2FtcGxlIiwgc2NhbGUgPSBUUlVFKQoKY2xvbmFsUXVhbnQoY29tYmluZWQuVENSX3dpdGhfUEJNQywgY2xvbmVDYWxsID0gImdlbmUiLCBncm91cC5ieSA9ICJzYW1wbGUiLCBzY2FsZSA9IFRSVUUpCmBgYAojIyAzLjIgY2xvbmFsQWJ1bmRhbmNlCmBgYHtyIFYyLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02fQojY2xvbmFsQWJ1bmRhbmNlCgpjbG9uYWxBYnVuZGFuY2UoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgICAgICBjbG9uZUNhbGwgPSAiZ2VuZSIsICBwYWxldHRlID0gIlppc3NvdSAxIiwKICAgICAgICAgICAgICAgIHNjYWxlID0gRkFMU0UpKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBoY2wuY29sb3JzKDgsImdleXNlciIpKQoKY2xvbmFsQWJ1bmRhbmNlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgY2xvbmVDYWxsID0gImdlbmUiLCBwYWxldHRlID0gIlppc3NvdSAxIiwKICAgICAgICAgICAgICAgIHNjYWxlID0gVFJVRSkKYGBgCiMjIDMuMyBjbG9uYWxMZW5ndGgKYGBge3IgVjMsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9CiNjbG9uYWxMZW5ndGgKY2xvbmFsTGVuZ3RoKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgY2xvbmVDYWxsPSJudCIsIAogICAgICAgICAgICAgY2hhaW4gPSAiYm90aCIpIAoKY2xvbmFsTGVuZ3RoKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgY2hhaW4gPSAiYm90aCIpIAojVFJBCmNsb25hbExlbmd0aChjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgIGNsb25lQ2FsbD0ibnQiLCAKICAgICAgICAgICAgIGNoYWluID0gIlRSQSIsIAogICAgICAgICAgICAgc2NhbGUgPSBUUlVFKSAKCmNsb25hbExlbmd0aChjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgIGNsb25lQ2FsbD0iYWEiLCAKICAgICAgICAgICAgIGNoYWluID0gIlRSQSIsIAogICAgICAgICAgICAgc2NhbGUgPSBUUlVFKSAKCiNUUkIKY2xvbmFsTGVuZ3RoKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgY2xvbmVDYWxsPSJudCIsIAogICAgICAgICAgICAgY2hhaW4gPSAiVFJCIiwgCiAgICAgICAgICAgICBzY2FsZSA9IFRSVUUpIAoKY2xvbmFsTGVuZ3RoKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgY2hhaW4gPSAiVFJCIiwgCiAgICAgICAgICAgICBzY2FsZSA9IFRSVUUpIApgYGAKIyMgMy40IGNsb25hbENvbXBhcmUKYGBge3IgVjQsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9CiMgY2xvbmFsQ29tcGFyZQpjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICB0b3AuY2xvbmVzID0gMTAsIAogICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDEiLCAiTDIiKSwgCiAgICAgICAgICAgICAgICAgIGNsb25lQ2FsbD0iYWEiLCAKICAgICAgICAgICAgICAgICAgZ3JhcGggPSAiYWxsdXZpYWwiKQoKY2xvbmFsQ29tcGFyZShjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgICAgICAgdG9wLmNsb25lcyA9IDEwLCAKICAgICAgICAgICAgICAgICAgc2FtcGxlcyA9IGMoIkwzX0IiLCAiTDRfQiIpLCAKICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgICAgICBncmFwaCA9ICJhbGx1dmlhbCIpCgpjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICB0b3AuY2xvbmVzID0gMTAsIAogICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDUiLCAiTDYiLCJMNyIpLCAKICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgICAgICBncmFwaCA9ICJhbGx1dmlhbCIpCgpjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICB0b3AuY2xvbmVzID0gMTAsIAogICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDUiLCJMNiIpLCAKICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgICAgICBncmFwaCA9ICJhbGx1dmlhbCIpCgpjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICB0b3AuY2xvbmVzID0gMTAsIAogICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDUiLCJMNyIpLCAKICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgICAgICBncmFwaCA9ICJhbGx1dmlhbCIpCgpjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICB0b3AuY2xvbmVzID0gMTAsIAogICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDYiLCJMNyIpLCAKICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsPSJhYSIsIAogICAgICAgICAgICAgICAgICBncmFwaCA9ICJhbGx1dmlhbCIpCgpjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICB0b3AuY2xvbmVzID0gMTAsIAogICAgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDEiLCAiTDIiLCAiTDNfQiIsICJMNF9CIiwgIkw1IiwgIkw2IiwgIkw3IiwgIlBCTUMiKSwgCiAgICAgICAgICAgICAgICAgIGNsb25lQ2FsbD0iYWEiLCAKICAgICAgICAgICAgICAgICAgZ3JhcGggPSAiYWxsdXZpYWwiKQoKIyBjbG9uYWxDb21wYXJlKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAojICAgICAgICAgICAgICAgdG9wLmNsb25lcyA9IDEwLAojICAgICAgICAgICAgICAgaGlnaGxpZ2h0LmNsb25lcyA9IGMoIkNWVlNETlRHR0ZLVElGX0NBU1NWUlJFUkFOVEdFTEZGIiwgIk5BX0NBU1NWUlJFUkFOVEdFTEZGIiksCiMgICAgICAgICAgICAgICByZWxhYmVsLmNsb25lcyA9IFRSVUUsCiMgICAgICAgICAgICAgICBzYW1wbGVzID0gYygiTDEiLCAiTDIiKSwgCiMgICAgICAgICAgICAgICBjbG9uZUNhbGw9ImFhIiwgCiMgICAgICAgICAgICAgICBncmFwaCA9ICJhbGx1dmlhbCIpCiMgCiMgCiMgY2xvbmFsQ29tcGFyZShjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCBjbG9uZXMgPSBjKCJDVlZTRE5UR0dGS1RJRl9DQVNTVlJSRVJBTlRHRUxGRiIsICJOQV9DQVNTVlJSRVJBTlRHRUxGRiIpLAojICAgICByZWxhYmVsLmNsb25lcyA9IFRSVUUsIHNhbXBsZXMgPSBjKCJMMSIsICJMMiIpLCBjbG9uZUNhbGwgPSAiYWEiLCBncmFwaCA9ICJhbGx1dmlhbCIpCgpgYGAKIyMgMy41IGNsb25hbFNjYXR0ZXIKYGBge3IgVjUsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9CiNjbG9uYWxTY2F0dGVyCgpjbG9uYWxTY2F0dGVyKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgIGNsb25lQ2FsbCA9ImdlbmUiLCAKICAgICAgICAgICAgICB4LmF4aXMgPSAiTDEiLCAKICAgICAgICAgICAgICB5LmF4aXMgPSAiTDIiLAogICAgICAgICAgICAgIGRvdC5zaXplID0gInRvdGFsIiwKICAgICAgICAgICAgICBncmFwaCA9ICJwcm9wb3J0aW9uIikKCgpjbG9uYWxTY2F0dGVyKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgIGNsb25lQ2FsbCA9ImdlbmUiLCAKICAgICAgICAgICAgICB4LmF4aXMgPSAiTDNfQiIsIAogICAgICAgICAgICAgIHkuYXhpcyA9ICJMNF9CIiwKICAgICAgICAgICAgICBkb3Quc2l6ZSA9ICJ0b3RhbCIsCiAgICAgICAgICAgICAgZ3JhcGggPSAicHJvcG9ydGlvbiIpCgpjbG9uYWxTY2F0dGVyKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgIGNsb25lQ2FsbCA9ImdlbmUiLCAKICAgICAgICAgICAgICB4LmF4aXMgPSAiTDUiLCAKICAgICAgICAgICAgICB5LmF4aXMgPSAiTDYiLAogICAgICAgICAgICAgIGRvdC5zaXplID0gInRvdGFsIiwKICAgICAgICAgICAgICBncmFwaCA9ICJwcm9wb3J0aW9uIikKCmNsb25hbFNjYXR0ZXIoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgICAgY2xvbmVDYWxsID0iZ2VuZSIsIAogICAgICAgICAgICAgIHguYXhpcyA9ICJMNSIsIAogICAgICAgICAgICAgIHkuYXhpcyA9ICJMNyIsCiAgICAgICAgICAgICAgZG90LnNpemUgPSAidG90YWwiLAogICAgICAgICAgICAgIGdyYXBoID0gInByb3BvcnRpb24iKQoKY2xvbmFsU2NhdHRlcihjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgICBjbG9uZUNhbGwgPSJnZW5lIiwgCiAgICAgICAgICAgICAgeC5heGlzID0gIkw2IiwgCiAgICAgICAgICAgICAgeS5heGlzID0gIkw3IiwKICAgICAgICAgICAgICBkb3Quc2l6ZSA9ICJ0b3RhbCIsCiAgICAgICAgICAgICAgZ3JhcGggPSAicHJvcG9ydGlvbiIpCmBgYAojIDQuIFZpc3VhbGl6aW5nIENsb25hbCBEeW5hbWljcwoKIyMgNC4xIGNsb25hbEhvbWVvc3Rhc2lzCmBgYHtyIFY2LCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02fQojIFZpc3VhbGl6aW5nIENsb25hbCBEeW5hbWljcwoKIyBjbG9uYWxIb21lb3N0YXNpcwoKY2xvbmFsSG9tZW9zdGFzaXMoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJnZW5lIikKCgpjbG9uYWxIb21lb3N0YXNpcyhjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsID0gImdlbmUiLAogICAgICAgICAgICAgICAgICBjbG9uZVNpemUgPSBjKFJhcmUgPSAwLjAwMSwgU21hbGwgPSAwLjAxLCBNZWRpdW0gPSAwLjEsIExhcmdlID0gMC4zLCBIeXBlcmV4cGFuZGVkID0xKSkKCmBgYAojIyA0LjIgY2xvbmFsUHJvcG9ydGlvbgpgYGB7ciBTdGF0cywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KIyBjbG9uYWxQcm9wb3J0aW9uCgpjbG9uYWxQcm9wb3J0aW9uKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJnZW5lIikgCgpjbG9uYWxQcm9wb3J0aW9uKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJudCIsCiAgICAgICAgICAgICAgICAgY2xvbmFsU3BsaXQgPSBjKDEsIDUsIDEwLCAxMDAsIDEwMDAsIDEwMDAwKSkgCmBgYAojIDUuIFN1bW1hcml6aW5nIFJlcGVydG9pcmVzCmBgYHtyIERFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02fQojIFN1bW1hcml6aW5nIFJlcGVydG9pcmVzCgojcGVyY2VudEFBCgpwZXJjZW50QUEoY29tYmluZWQuVENSLCAKICAgICAgICAgIGNoYWluID0gIlRSQiIsIAogICAgICAgICAgYWEubGVuZ3RoID0gMjApCgojIHBvc2l0aW9uYWxFbnRyb3B5CiMgV2UgY2FuIGFsc28gcXVhbnRpZnkgdGhlIGxldmVsIG9mIGVudHJvcHkvZGl2ZXJzaXR5IGFjcm9zcyBhbWlubyBhY2lkIHJlc2lkdWVzIGFsb25nIHRoZSBjZHIzIHNlcXVlbmNlLiBwb3NpdGlvbmFsRW50cm9weSgpIGNvbWJpbmVzIHRoZSBxdWFudGlmaWNhdGlvbiBieSByZXNpZHVlIG9mIHBlcmNlbnRBQSgpIHdpdGggdGhlIGRpdmVyc2l0eSBjYWxscyBpbiBjbG9uYWxEaXZlcnNpdHkoKS4KIyAKIyBtZXRob2QKIyAKIyDigJxzaGFubm9u4oCdIC0gU2hhbm5vbiBEaXZlcnNpdHkKIyDigJxpbnYuc2ltcHNvbuKAnSAtIEludmVyc2UgU2ltcHNvbiBEaXZlcnNpdHkKIyDigJxub3JtLmVudHJvcHnigJ0gLSBOb3JtYWxpemVkIEVudHJvcHkKCnBvc2l0aW9uYWxFbnRyb3B5KGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICBjaGFpbiA9ICJUUkIiLCAKICAgICAgICAgICAgICAgICAgYWEubGVuZ3RoID0gMjApCgoKIyBwb3NpdGlvbmFsUHJvcGVydHkKIyBMaWtlIHBvc2l0aW9uYWxFbnRyb3B5KCksIHdlIGNhbiBhbHNvIGV4YW1pbmUgYSBzZXJpZXMgb2YgYW1pbm8gYWNpZCBwcm9wZXJ0aWVzIGFsb25nIHRoZSBjZHIzIHNlcXVlbmNlcyB1c2luZyBwb3NpdGlvbmFsUHJvcGVydHkoKS4gSW1wb3J0YW50IGRpZmZlcmVuY2VzIGZyb20gdGhlIGFib3ZlIGZ1bmN0aW9uIGZvciBwb3NpdGlvbmFsUHJvcGVydHkoKSBpcyBkcm9wcGluZyBOQSB2YWx1ZXMgYXMgdGhleSB3b3VsZCB2b2lkIHRoZSBtZWFuIGNhbGN1bGF0aW9uLiBwb3NpdGlvbmFsUHJvcGVydHkoKSBhbHNvIGRpc3BsYXkgYSByaWJib24gd2l0aCB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgc3Vycm91bmRpbmcgdGhlIG1lYW4gdmFsdWUgZm9yIHRoZSBzZWxlY3RlZCBwcm9wZXJ0aWVzLgojIAojIG1ldGhvZAojIAojIOKAnEF0Y2hsZXnigJ0gLSBBdGNobGV5IEZhY3RvcnMKIyDigJxLaWRlcmHigJ0gLSBLaWRlcmEgRmFjdG9ycwojIOKAnHN0U2NhbGVz4oCdIC0gc3RTY2FsZXMgVmVjdG9ycwojIOKAnHRTY2FsZXPigJ0gLSB0U2NhbGVzIFZlY3RvcnMKIyDigJxWSFNF4oCdIC0gVmVjdG9ycyBvZiBIeWRyb3Bob2JpYywgU3RlcmljLCBhbmQgRWxlY3Ryb25pYyBwcm9wZXJ0aWVzCgojIHBvc2l0aW9uYWxQcm9wZXJ0eShjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DW2MoMSwyKV0sIAojICAgICAgICAgICAgICAgICAgIGNoYWluID0gIlRSQiIsIAojICAgICAgICAgICAgICAgICAgIGFhLmxlbmd0aCA9IDIwLCAKIyAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAiQXRjaGxleSIpICsgCiMgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaGNsLmNvbG9ycyg1LCAiaW5mZXJubyIpW2MoMiw0KV0pCiMgCiMgcG9zaXRpb25hbFByb3BlcnR5KGNvbWJpbmVkLlRDUl93aXRoX1BCTUNbYygzLDQpXSwgCiMgICAgICAgICAgICAgICAgICAgY2hhaW4gPSAiVFJCIiwgCiMgICAgICAgICAgICAgICAgICAgYWEubGVuZ3RoID0gMjAsIAojICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJBdGNobGV5IikgKyAKIyAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBoY2wuY29sb3JzKDUsICJpbmZlcm5vIilbYygyLDQpXSkKIyAKIyBwb3NpdGlvbmFsUHJvcGVydHkoY29tYmluZWQuVENSX3dpdGhfUEJNQ1tjKDUsNildLCAKIyAgICAgICAgICAgICAgICAgICBjaGFpbiA9ICJUUkIiLCAKIyAgICAgICAgICAgICAgICAgICBhYS5sZW5ndGggPSAyMCwgCiMgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIkF0Y2hsZXkiKSArIAojICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGhjbC5jb2xvcnMoNSwgImluZmVybm8iKVtjKDIsNCldKQojIAojIHBvc2l0aW9uYWxQcm9wZXJ0eShjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DW2MoNSw3KV0sIAojICAgICAgICAgICAgICAgICAgIGNoYWluID0gIlRSQiIsIAojICAgICAgICAgICAgICAgICAgIGFhLmxlbmd0aCA9IDIwLCAKIyAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAiQXRjaGxleSIpICsgCiMgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaGNsLmNvbG9ycyg1LCAiaW5mZXJubyIpW2MoMiw0KV0pCiMgCiMgCiMgcG9zaXRpb25hbFByb3BlcnR5KGNvbWJpbmVkLlRDUl93aXRoX1BCTUNbYyg2LDcpXSwgCiMgICAgICAgICAgICAgICAgICAgY2hhaW4gPSAiVFJCIiwgCiMgICAgICAgICAgICAgICAgICAgYWEubGVuZ3RoID0gMjAsIAojICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJBdGNobGV5IikgKyAKIyAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBoY2wuY29sb3JzKDUsICJpbmZlcm5vIilbYygyLDQpXSkKIyAKIyBwb3NpdGlvbmFsUHJvcGVydHkoY29tYmluZWQuVENSX3dpdGhfUEJNQ1tjKDUsNiw3KV0sIAojICAgICAgICAgICAgICAgICAgIGNoYWluID0gIlRSQiIsIAojICAgICAgICAgICAgICAgICAgIGFhLmxlbmd0aCA9IDIwLCAKIyAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAiQXRjaGxleSIpICsgCiMgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaGNsLmNvbG9ycyg1LCAiaW5mZXJubyIpW2MoMiw0KV0pCgoKIyB2aXpHZW5lcwojIEEgdmlzdWFsaXphdGlvbiBvZiB0aGUgcmVsYXRpdmUgdXNhZ2Ugb2YgZ2VuZXMgb2YgdGhlIFRDUiBvciBCQ1IsIHVzaW5nIHZpekdlbmVzKCkuIFRoZXJlIGlzIHNvbWUgZnVuY3Rpb25hbCBjcm9zc292ZXIgYmV0d2VlbiB2aXpHZW5lcygpIGFuZCB0d28gZnVuY3Rpb25zIGJlbG93IGNhbGxlZCBwZXJjZW50R2VuZXMoKSBhbmQgcGVyY2VudFZKKCkuIEJ1dCB2aXpHZW5lcygpIGlzIG1vcmUgYWRhcHRhYmxlIHRvIGFsbG93IGZvciBjb21wYXJpc29ucyBhY3Jvc3MgY2hhaW5zLCBzY2FsaW5nLCBldGMuCgp2aXpHZW5lcyhjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgeC5heGlzID0gIlRSQlYiLAogICAgICAgICB5LmF4aXMgPSBOVUxMLAogICAgICAgICBwbG90ID0gImJhcnBsb3QiLCAgCiAgICAgICAgIHNjYWxlID0gVFJVRSkKCnZpekdlbmVzKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgIHguYXhpcyA9ICJUUkFWIiwKICAgICAgICB5LmF4aXMgPSBOVUxMLAogICAgICAgIHBsb3QgPSAiYmFycGxvdCIsICAKICAgICAgICBzY2FsZSA9IFRSVUUpCgp2aXpHZW5lcyhjb21iaW5lZC5UQ1JbYygxLDIsMyw0LDUsNiw3KV0sIAogICAgICAgICB4LmF4aXMgPSAiVFJCViIsCiAgICAgICAgIHkuYXhpcyA9ICJUUkJKIiwKICAgICAgICAgcGxvdCA9ICJoZWF0bWFwIiwgIAogICAgICAgICBzY2FsZSA9IFRSVUUpCgp2aXpHZW5lcyhjb21iaW5lZC5UQ1JbYygxLDIsMyw0LDUsNiw3KV0sIAogICAgICAgICB4LmF4aXMgPSAiVFJBViIsCiAgICAgICAgIHkuYXhpcyA9ICJUUkFKIiwKICAgICAgICAgcGxvdCA9ICJoZWF0bWFwIiwgIAogICAgICAgICBzY2FsZSA9IFRSVUUpCgojIEZvciB0aGUgUDE3IHBhdGllbnQgc2FtcGxlcywgd2hhdCBpZiB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBjaGFpbiBwYWlyaW5ncywgd2UgY2FuIGxvb2sgYXQgVFJCViBhbmQgVFJBViBhdCB0aGUgc2FtZSB0aW1lIHVzaW5nIHRoZW0gYXMgaW5wdXRzIHRvIHguYXhpcyBhbmQgeS5heGlzLgp2aXpHZW5lcyhjb21iaW5lZC5UQ1JbYygxLDIpXSwgCiAgICAgICAgIHguYXhpcyA9ICJUUkJWIiwKICAgICAgICAgeS5heGlzID0gIlRSQVYiLAogICAgICAgICBwbG90ID0gImhlYXRtYXAiLCAKICAgICAgICAgc2NhbGUgPSBGQUxTRSkKIyBwZXJjZW50R2VuZXMKIyBRdWFudGlmeSB0aGUgcHJvcG9ydGlvbiBvZiBWIG9yIEogZ2VuZSB1c2FnZSB3aXRoIHBlcmNlbnRHZW5lcygpLiBMaWtlIHBlcmNlbnRBQSgpLCB3ZSBzZWxlY3QgdGhlIGNoYWluIG9mIGludGVyZXN0IGFuZCB0aGVuIGluZGljYXRlIHRoZSBnZW5lIG9mIGludGVyZXN0IHdpdGggdGhlIGdlbmUgcGFyYW1ldGVyLiBUd28gbWFqb3IgbGltaXRhdGlvbnMgb2YgcGVyY2VudEdlbmVzKCkgYXJlLCAxKSB0aGUgZnVuY3Rpb24gcXVhbnRpZmllcyBvbmx5IFYgb3IgSiBnZW5lcywgYW5kIDIpIHRoZSBxdWFudGlmaWNhdGlvbiBvZiB0aGUgZ2VuZXMgYXJlIGxpbWl0ZWQgdG8gYWxsIHRoZSBWIG9yIEogZ2VuZXMgc2VlbiBhY3Jvc3MgdGhlIHNhbXBsZXMsIG5vdCBhbGwgcG9zc2libGUgViBvciBKIGdlbmVzLgoKcGVyY2VudEdlbmVzKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgY2hhaW4gPSAiVFJCIiwgCiAgICAgICAgICAgICBnZW5lID0gIlZnZW5lIikKCnBlcmNlbnRHZW5lcyhjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgIGNoYWluID0gIlRSQSIsIAogICAgICAgICAgICAgZ2VuZSA9ICJWZ2VuZSIpCgpwZXJjZW50R2VuZXMoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgICBjaGFpbiA9ICJUUkIiLCAKICAgICAgICAgICAgIGdlbmUgPSAiSmdlbmUiKQoKcGVyY2VudEdlbmVzKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgY2hhaW4gPSAiVFJBIiwgCiAgICAgICAgICAgICBnZW5lID0gIkpnZW5lIikKCgojIHBlcmNlbnRWSgojIFF1YW50aWZ5IHRoZSBwcm9wb3J0aW9uIG9mIFYgYW5kIEogZ2VuZSB1c2FnZSB3aXRoIHBlcmNlbnRWSigpLiBMaWtlIHBlcmNlbnRHZW5lcygpLCB0aGlzIGZ1bmN0aW9uIHdpbGwgcXVhbnRpZnkgdGhlIHBlcmNlbnRhZ2Ugb2YgViBhbmQgSiBwYWlyZWQgdG9nZXRoZXIgYWNyb3NzIGluZGl2aWR1YWwgcmVwZXJ0b2lyZXMuIFRoZSBvdXRwdXQgY2FuIGJlIHZpc3VhbGl6ZWQgdXNpbmcgYSBoZWF0bWFwIG9yIGFzIGlucHV0IGZvciBmdXJ0aGVyIGRpbWVuc2lvbmFsIHJlZHVjdGlvbi4KCnBlcmNlbnRWSihjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgIGNoYWluID0gIlRSQiIpCgpwZXJjZW50VkooY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICBjaGFpbiA9ICJUUkEiKQoKIyBwZXJjZW50S21lcgojIEFub3RoZXIgcXVhbnRpZmljYXRpb24gb2YgdGhlIGNvbXBvc2l0aW9uIG9mIHRoZSBDRFIzIHNlcXVlbmNlIGlzIHRvIGRlZmluZSBtb3RpZnMgYnkgc2xpZGluZyBhY3Jvc3MgdGhlIGFtaW5vIGFjaWQgb3IgbnVjbGVvdGlkZSBzZXF1ZW5jZXMgYXQgc2V0IGludGVydmFscyByZXN1bHRpbmcgaW4gc3Vic3RyaW5ncyBvciBrbWVycy4KIyAKIyBtb3RpZi5sZW5ndGgKIyAKIyBOdW1lcmljYWwgdmFsdWUgZm9yIHRoZSBsZW5ndGggb2YgdGhlIGttZXIuCiMgdG9wLm1vdGlmcwojIAojIERpc3BsYXkgdGhlIG1vc3QgdmFyaWFibGUgZ2VuZXMgZGV0ZXJtaW5lZCBieSBtZWFuIGFic29sdXRlIGRldmlhdGlvbiAoTUFEKS4KcGVyY2VudEttZXIoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJhYSIsCiAgICAgICAgICAgIGNoYWluID0gIlRSQiIsIAogICAgICAgICAgICBtb3RpZi5sZW5ndGggPSAzLCAKICAgICAgICAgICAgdG9wLm1vdGlmcyA9IDI1KQoKcGVyY2VudEttZXIoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJhYSIsCiAgICAgICAgICAgIGNoYWluID0gIlRSQSIsIAogICAgICAgICAgICBtb3RpZi5sZW5ndGggPSAzLCAKICAgICAgICAgICAgdG9wLm1vdGlmcyA9IDI1KQoKcGVyY2VudEttZXIoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJudCIsCiAgICAgICAgICAgIGNoYWluID0gIlRSQiIsIAogICAgICAgICAgICBtb3RpZi5sZW5ndGggPSAzLCAKICAgICAgICAgICAgdG9wLm1vdGlmcyA9IDI1KQoKcGVyY2VudEttZXIoY29tYmluZWQuVENSX3dpdGhfUEJNQywgCiAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJudCIsCiAgICAgICAgICAgIGNoYWluID0gIlRSQSIsIAogICAgICAgICAgICBtb3RpZi5sZW5ndGggPSAzLCAKICAgICAgICAgICAgdG9wLm1vdGlmcyA9IDI1KQpgYGAKIyA2LiBDb21wYXJpbmcgQ2xvbmFsIERpdmVyc2l0eSBhbmQgT3ZlcmxhcApgYGB7ciBjbG9uYWxEaXZlcnNpdHksIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9CiMgY2xvbmFsRGl2ZXJzaXR5CgoKY2xvbmFsRGl2ZXJzaXR5KGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgY2xvbmVDYWxsID0gImdlbmUiKQoKI2Nsb25hbFNpemVEaXN0cmlidXRpb24KCgpjbG9uYWxTaXplRGlzdHJpYnV0aW9uKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJhYSIsIAogICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0gIndhcmQuRDIiKQoKCgojY2xvbmFsT3ZlcmxhcAoKY2xvbmFsT3ZlcmxhcChjb21iaW5lZC5UQ1Jfd2l0aF9QQk1DLCAKICAgICAgICAgICAgICBjbG9uZUNhbGwgPSAic3RyaWN0IiwgCiAgICAgICAgICAgICAgbWV0aG9kID0gIm1vcmlzaXRhIikKCgpjbG9uYWxPdmVybGFwKGNvbWJpbmVkLlRDUl93aXRoX1BCTUMsIAogICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJzdHJpY3QiLCAKICAgICAgICAgICAgICBtZXRob2QgPSAicmF3IikKYGBgCiMgNy4gQ29tYmluaW5nIENsb25lcyBhbmQgU2luZ2xlLUNlbGwgT2JqZWN0cwpgYGB7ciBTQywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KCiMgQ29tYmluaW5nIENsb25lcyBhbmQgU2luZ2xlLUNlbGwgT2JqZWN0cwoKI0dldHRpbmcgYSBzYW1wbGUgb2YgYSBTZXVyYXQgb2JqZWN0CnNjUmVwX2V4YW1wbGUgPC0gZ2V0KGRhdGEoIkFsbF9zYW1wbGVzX01lcmdlZCIpKQoKCiNEZWZpbmUgY29sb3IgcGFsZXR0ZSAKY29sb3JibGluZF92ZWN0b3IgPC0gaGNsLmNvbG9ycyhuPTcsIHBhbGV0dGUgPSAiaW5mZXJubyIsIGZpeHVwID0gVFJVRSkKCgpzY1JlcF9leGFtcGxlIDwtIGNvbWJpbmVFeHByZXNzaW9uKGNvbWJpbmVkLlRDUiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NSZXBfZXhhbXBsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVDYWxsPSJnZW5lIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAuYnkgPSAic2FtcGxlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcG9ydGlvbiA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZVNpemU9YyhTaW5nbGU9MSwgU21hbGw9NSwgTWVkaXVtPTIwLCBMYXJnZT0xMDAsIEh5cGVyZXhwYW5kZWQ9NTAwKSkKCkRpbVBsb3Qoc2NSZXBfZXhhbXBsZSwgZ3JvdXAuYnkgPSAiY2xvbmVTaXplIikKCkRpbVBsb3Qoc2NSZXBfZXhhbXBsZSwgZ3JvdXAuYnkgPSAiY2xvbmVTaXplIikgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1yZXYoY29sb3JibGluZF92ZWN0b3JbYygxLDMsNCw1LDYpXSkpCgoKYGBgCiMgOC4gVmlzdWFsaXphdGlvbnMgZm9yIFNpbmdsZS1DZWxsIE9iamVjdHMKYGBge3IgVl9zYywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KCiMgVmlzdWFsaXphdGlvbnMgZm9yIFNpbmdsZS1DZWxsIE9iamVjdHMKIyBjbG9uYWxPdmVybGF5CgojQWRkaW5nIHBhdGllbnQgaW5mb3JtYXRpb24Kc2NSZXBfZXhhbXBsZSRQYXRpZW50X29yaWdpbiA8LSBzdWJzdHIoc2NSZXBfZXhhbXBsZSRvcmlnLmlkZW50LCAxLDMpCgpjbG9uYWxPdmVybGF5KHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwgCiAgICAgICAgICAgICAgZnJlcS5jdXRwb2ludCA9IDEsIAogICAgICAgICAgICAgIGJpbnMgPSAxMCwgCiAgICAgICAgICAgICAgZmFjZXQuYnkgPSAiUGF0aWVudF9vcmlnaW4iKSArIAogICAgICAgICAgICAgIGd1aWRlcyhjb2xvciA9ICJub25lIikKCiNjbG9uYWxOZXR3b3JrCiNnZ3JhcGggbmVlZHMgdG8gYmUgbG9hZGVkIGR1ZSB0byBpc3N1ZXMgd2l0aCBnZ3Bsb3QKbGlicmFyeShnZ3JhcGgpCgpjbG9uYWxOZXR3b3JrKHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwgCiAgICAgICAgICAgICAgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIiwKICAgICAgICAgICAgICBmaWx0ZXIuY2xvbmVzID0gTlVMTCwKICAgICAgICAgICAgICBmaWx0ZXIuaWRlbnRpdHkgPSBOVUxMLAogICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJhYSIpCgoKI0V4YW1pbmluZyBDbHVzdGVyIDMgb25seQpjbG9uYWxOZXR3b3JrKHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwgCiAgICAgICAgICAgICAgZ3JvdXAuYnkgPSAic2V1cmF0X2NsdXN0ZXJzIiwKICAgICAgICAgICAgICBmaWx0ZXIuaWRlbnRpdHkgPSA4LAogICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJhYSIpCgoKc2hhcmVkLmNsb25lcyA8LSBjbG9uYWxOZXR3b3JrKHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uID0gInVtYXAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZUNhbGwgPSAiYWEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydENsb25lcyA9IFRSVUUpCmhlYWQoc2hhcmVkLmNsb25lcykKCgpzY1JlcF9leGFtcGxlIDwtIGhpZ2hsaWdodENsb25lcyhzY1JlcF9leGFtcGxlLCAKICAgICAgICAgICAgICAgICAgICBjbG9uZUNhbGw9ICJhYSIsIAogICAgICAgICAgICAgICAgICAgIHNlcXVlbmNlID0gYygiQ0FUR1BOR1NTTlRHS0xJRjtDQUxTTk5BUkxNRl9DU0FUVEdGWUdZVEYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNBWVNFU0dHU05ZS0xURl9DU0FMQUdHWVREVFFZRiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDTFZHRVRHUlJBTFRGX0NTQVJHRFJHUVBRSEYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0xWR0VUR1JSQUxURl9DU0FSR0RSR1FQUUhGO0NBVFNERktRVlNOUVBRSEYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0FUR1BOR1NTTlRHS0xJRl9DU0FUVEdGWUdZVEYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkFfQ1NBUkdEUkdRUFFIRiIpKQoKU2V1cmF0OjpEaW1QbG90KHNjUmVwX2V4YW1wbGUsIGdyb3VwLmJ5ID0gImhpZ2hsaWdodCIpICsgCiAgZ2dwbG90Mjo6dGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCiNjbG9uYWxPY2N1cHkKY2xvbmFsT2NjdXB5KHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgIHguYXhpcyA9ICJzZXVyYXRfY2x1c3RlcnMiKQoKY2xvbmFsT2NjdXB5KHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgICAgICAgICB4LmF4aXMgPSAiaWRlbnQiLCAKICAgICAgICAgICAgICAgICAgICAgcHJvcG9ydGlvbiA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IEZBTFNFKQojIGFsbHV2aWFsQ2xvbmVzCgojIHNjUmVwX2V4YW1wbGUkUGF0aWVudF9vcmlnaW4gPC0gc3Vic3RyKHNjUmVwX2V4YW1wbGUkb3JpZy5pZGVudCwgOCw4KQojIAojIGFsbHV2aWFsQ2xvbmVzKHNjUmVwX2V4YW1wbGUsIAojICAgICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJhYSIsIAojICAgICAgICAgICAgICAgIHkuYXhlcyA9IGMoIlBhdGllbnRfb3JpZ2luIiwgIm9yaWcuaWRlbnQiLCAiQ2VsbF9saW5lX0ltbXVub3BoZW5vdHlwZSIpLCAKIyAgICAgICAgICAgICAgICBjb2xvciA9IGMoIkNBVEdQTkdTU05UR0tMSUY7Q0FMU05OQVJMTUZfQ1NBVFRHRllHWVRGIiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNBWVNFU0dHU05ZS0xURl9DU0FMQUdHWVREVFFZRiIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNMVkdFVEdSUkFMVEZfQ1NBUkdEUkdRUFFIRiIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNMVkdFVEdSUkFMVEZfQ1NBUkdEUkdRUFFIRjtDQVRTREZLUVZTTlFQUUhGIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0FUR1BOR1NTTlRHS0xJRl9DU0FUVEdGWUdZVEYiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQV9DU0FSR0RSR1FQUUhGIikpICsgCiMgICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImdyZXkiLCBjb2xvcmJsaW5kX3ZlY3RvclszXSkpCiMgCiMgCiMgCiMgYWxsdXZpYWxDbG9uZXMoc2NSZXBfZXhhbXBsZSwgCiMgICAgICAgICAgICAgICAgICAgIGNsb25lQ2FsbCA9ICJnZW5lIiwgCiMgICAgICAgICAgICAgICAgICAgIHkuYXhlcyA9IGMoIlBhdGllbnRfb3JpZ2luIiwgIm9yaWcuaWRlbnQiLCAiQ2VsbF9saW5lX0ltbXVub3BoZW5vdHlwZSIpLCAKIyAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiaWRlbnQiKSAKCgoKbGlicmFyeShjaXJjbGl6ZSkKbGlicmFyeShzY2FsZXMpCgpjaXJjbGVzIDwtIGdldENpcmNsaXplKHNjUmVwX2V4YW1wbGUsIAogICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIpCgojSnVzdCBhc3NpZ25pbmcgdGhlIG5vcm1hbCBjb2xvcnMgdG8gZWFjaCBjbHVzdGVyCmdyaWQuY29scyA8LSBodWVfcGFsKCkobGVuZ3RoKHVuaXF1ZShzY1JlcF9leGFtcGxlJHNldXJhdF9jbHVzdGVycykpKQpuYW1lcyhncmlkLmNvbHMpIDwtIHVuaXF1ZShzY1JlcF9leGFtcGxlJHNldXJhdF9jbHVzdGVycykKCiNHcmFwaGluZyB0aGUgY2hvcmQgZGlhZ3JhbQpjaG9yZERpYWdyYW0oY2lyY2xlcywgc2VsZi5saW5rID0gMSwgZ3JpZC5jb2wgPSBncmlkLmNvbHMpCgoKY2lyY2xlcyA8LSBnZXRDaXJjbGl6ZShzY1JlcF9leGFtcGxlLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLCBwcm9wb3J0aW9uID0gVFJVRSkKCmdyaWQuY29scyA8LSBzY2FsZXM6Omh1ZV9wYWwoKShsZW5ndGgodW5pcXVlKHNjUmVwX2V4YW1wbGVAYWN0aXZlLmlkZW50KSkpCm5hbWVzKGdyaWQuY29scykgPC0gbGV2ZWxzKHNjUmVwX2V4YW1wbGVAYWN0aXZlLmlkZW50KQoKY2hvcmREaWFncmFtKGNpcmNsZXMsIAogICAgICAgICAgICAgc2VsZi5saW5rID0gMSwgCiAgICAgICAgICAgICBncmlkLmNvbCA9IGdyaWQuY29scywgCiAgICAgICAgICAgICBkaXJlY3Rpb25hbCA9IDEsIAogICAgICAgICAgICAgZGlyZWN0aW9uLnR5cGUgPSAgImFycm93cyIsCiAgICAgICAgICAgICBsaW5rLmFyci50eXBlID0gImJpZy5hcnJvdyIpCmBgYA==