Some Graphical
Exploration
We next explore the distributions of the created composite scores and
perform some empirical comparisons. The primary goal of this survey
study is to investigate factors that are associated with mathematics
anxiety (MA) levels. To this end, we also look the distributions each
individual items in the MA instrument.
Distributions of
Composite Scores
The following are distributions of four generated composite scores
across all instruments. The purpose is to examine the behaviors of these
composite scores, especially the doubly weighted composite score based
on the principal component analysis.
plotly.fun <- function(in.data){
in.avg <- density(in.data[,1])
in.pc1 <- density(in.data[,2])
in.pcw <- density(in.data[,3])
in.cfa <- density(in.data[, 4])
dat.name <- sub("\\..*", "",names(in.data)[1]) #sub( text)
# plot density curves
fig <- plot_ly(x = ~in.avg$x, y = ~in.avg$y,
type = 'scatter',
mode = 'lines',
name = 'avg',
fill = 'tozeroy') %>%
# adding more density curves
add_trace(x = ~in.pc1$x, y = ~in.pc1$y,
name = 'pca1',
fill = 'tozeroy') %>%
add_trace(x = ~in.pcw$x, y = ~in.pcw$y,
name = 'pca.wt',
fill = 'tozeroy') %>%
add_trace(x = ~in.cfa$x, y = ~in.cfa$y,
name = 'cfa',
fill = 'tozeroy') %>%
layout(xaxis = list(title = 'scores'),
yaxis = list(title = 'Density'),
#title = dat.name,
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
fig
}
####
in.anxiety.mea = final.anxiety.dat[, c( "Anxiety.mea.avg", "Anxiety.mea.pca1", "Anxiety.mea.wt.pca","Anxiety.mea.cfa")]
in.anxiety.mla = final.anxiety.dat[, c("Anxiety.mla.avg","Anxiety.mla.pca1", "Anxiety.mla.wt.pca","Anxiety.mla.cfa")]
###
in.anxiety = final.anxiety.dat[, c( "Anxiety.avg", "Anxiety.pca1", "Anxiety.wt.pca", "Anxiety.cfa")]
in.efficacy = final.anxiety.dat[, c( "SelfEfficacy.avg", "SelfEfficacy.pca1","SelfEfficacy.wt.pca","SelfEfficacy.cfa")]
in.technology = final.anxiety.dat[, c( "Technology.avg","Technology.pca1", "Technology.wt.pca","Technology.cfa")]
in.cooporative = final.anxiety.dat[, c("Cooporative.avg","Cooporative.pca1", "Cooporative.wt.pca","Cooporative.cfa")]
in.deductive = final.anxiety.dat[, c("Deductive.avg","Deductive.pca1","Deductive.wt.pca","Deductive.cfa")]
in.demonstration = final.anxiety.dat[, c("Demonstration.avg","Demonstration.pca1","Demonstration.wt.pca","Demonstration.cfa")]
in.inductive = final.anxiety.dat[, c( "Inductive.avg","Inductive.pca1","Inductive.wt.pca","Inductive.cfa")]
in.integrative = final.anxiety.dat[, c( "Integrative.avg", "Integrative.pca1","Integrative.wt.pca","Integrative.cfa")]
in.lectureType = final.anxiety.dat[, c( "LectureType.avg", "LectureType.pca1", "LectureType.wt.pca","LectureType.cfa")]
in.repetitive = final.anxiety.dat[, c( "Repetitive.avg", "Repetitive.pca1", "Repetitive.wt.pca","Repetitive.cfa")]
in.engage = final.anxiety.dat[, c( "Engage.avg", "Engage.pca1", "Engage.wt.pca","Engage.cfa")]
in.resource = final.anxiety.dat[, c( "Resource.avg", "Resource.pca1", "Resource.wt.pca", "Resource.cfa")]
p.mea <- plotly.fun(in.anxiety.mea)
p.mla <- plotly.fun(in.anxiety.mla)
# Arrange in 1x2 grid
subplot(p.mea, p.mla, nrows = 1, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Anxiety.mea",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Anxiety.mla",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
p1 <- plotly.fun(in.anxiety)
p2 <- plotly.fun(in.efficacy)
p3 <- plotly.fun(in.technology)
p4 <- plotly.fun(in.cooporative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Anxiety",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Self-efficacy",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.05, y = 0.4, text = "Technology",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Coorporative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
p1 <- plotly.fun(in.deductive)
p2 <- plotly.fun(in.demonstration)
p3 <- plotly.fun(in.inductive)
p4 <- plotly.fun(in.integrative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Deductive",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Demonstrative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.05, y = 0.4, text = "Inductive",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Intergrative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
p1 <- plotly.fun(in.lectureType)
p2 <- plotly.fun(in.repetitive)
p3 <- plotly.fun(in.engage)
p4 <- plotly.fun(in.resource)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.05, y = .99, text = "Lecture Type",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Repetative",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.05, y = 0.4, text = "Engagement",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Resource",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
These density curves illustrate the distributions of the four
composite scores (avg, cfa, pc1, and
pca.wt) for all single-factor instruments in the
survey. The avg is a naive measure, derived from the
arithmetic mean of the item scores. The cfa and
pc1 composites are weighted averages, where the weights
(loadings) are derived from distinct latent variable models. The
pca.wt composite is a doubly
weighted average, based on both the original item scores
and all of the resulting principal components.
- Three model-based composite scores (cfa, pc1, and
pca.wt) are centered at 0 but exhibit different
behaviors:
- pc1 has the largest variance.
- cfa has the smallest variance.
- avg and pca.wt behave similarly,
differing primarily in their locations.
The composite score avg serves as a reference point,
analogous to an empirical distribution, as it uses all item scores
directly. In contrast, pca.wt uses a doubly weighted
average of all item scores without imposing complex distributional
assumptions. This demonstrates that pca.wt is a
reliable and robust composite score. For the remainder of this report,
the pca.wt score will be used, with
cfa occasionally employed for illustrative purposes for
some special cases.
Distribution of
Demographics
The distribution of demographic factors are reported in the following
figures.
# Enhanced hover information
Demographic.bar <-function(in.cat, varname){
freq.tbl <- table(in.cat)
df <- data.frame(
category <- names(freq.tbl),
values <- as.vector(freq.tbl)
)
# High-contrast colors (manually defined)
accessible_colors <- c(
'#D55E00', # Vermillion
'#0072B2', # Blue
'#F0E442', # Yellow
'#009E73', # Green
'#56B4E9', # Sky Blue
'#E69F00', # Orange
'#CC79A7' # Pink
)
fig <- plot_ly(df, x = ~category, y = ~values, type = 'bar',
hoverinfo = 'text',
text = ~paste('Category:', category, '<br>Value:', values, '<br>Percentage:', round(values/sum(values)*100, 1), '%'),
#text = ~paste("Value:", values),
textposition = 'auto',
marker = list(
color = accessible_colors[1:nrow(df)],
line = list(color = 'black', width = 2)
),
textfont = list(color = 'white', size = 12)) %>%
layout(
# title = list(text = varname,
# font = list(size = 18, color = 'black')),
xaxis = list(title = "Categories",
tickfont = list(color = 'black')),
yaxis = list(title = "Values",
gridcolor = 'lightgray',
tickfont = list(color = 'black')),
plot_bgcolor = 'white',
paper_bgcolor = 'white',
showlegend = FALSE,
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
fig
}
in.cat.sex <- final.anxiety.dat$sex
in.cat.race <- final.anxiety.dat$race
in.cat.class <- final.anxiety.dat$class
in.cat.major <- final.anxiety.dat$major
in.cat.math.level <- final.anxiety.dat$math.level
in.cat.modality <- final.anxiety.dat$modality
##
g.sex <- Demographic.bar(in.cat.sex, "Gender Distribution")
g.race <- Demographic.bar(in.cat.race, "Racial Distribution")
g.class <- Demographic.bar(in.cat.class, "Class Distribution")
g.major <- Demographic.bar(in.cat.major, "Major Distribution")
g.math.level <- Demographic.bar(in.cat.math.level, "Math Course Level")
g.modality <- Demographic.bar(in.cat.modality, "Learning Modality")
# Arrange in 2x2 grid
subplot(g.sex, g.race, g.class, g.major, nrows = 2, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.35, y = .99, text = "Gender",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Race",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.35, y = 0.4, text = "Class Level",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.4, text = "Major",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
# Arrange in 2x2 grid
subplot(g.math.level, g.modality, nrows = 1, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
layout(
annotations = list(
list(x = 0.35, y = .99, text = "Math Course Level",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
list(x = 0.75, y = 0.99, text = "Learning Modality",
xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
),
showlegend = FALSE
)
Only one category in variable class is less than 3%
with 21 observations. Other variables don’t have issues on sparse
categories.
Relationship Between
Math Anxiety and Demographic Factors
A student’s demographic profile doesn’t determine their math anxiety,
but it significantly influences which type of anxiety they are most
vulnerable to and why. The next subsections present visual explorations
of the relationship between demographic factors and the two dimensions
of mathematical anxiety.
Mathematical
Evaluation Anxiety
This is the anxiety a student feels when their mathematical ability
is being formally or informally assessed. The primary fear is not of the
math itself, but of the negative consequences of performing poorly. It’s
performance-oriented. The stress comes from the situation of being
evaluated, not necessarily from the content.
## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
gender.anxiety <- plot_ly(final.anxiety.dat,
x = ~sex,
y = ~Anxiety.mea.wt.pca,
color = as.formula(paste0("~",in.var1)),
type = "box",
boxpoints = "no",
jitter = 0.3,
pointpos = 0,
hoverinfo = "y + x + name",
hovertext = ~paste("Group:", in.var1,
"<br>Factor:", sex,
"<br>Score:", round(Anxiety.mea.wt.pca, 2)),
marker = list(size = 5, opacity = 0.7)) %>%
layout(title = paste("Math Evaluation Anxiety (wt.PCA): Gender vs ", in.var2,""),
xaxis = list(title = ""),
yaxis = list(title = "Evaluation Anxiety Score"),
boxmode = "group",
hoverlabel = list(bgcolor = "white", font = list(size = 12)),
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
gender.anxiety
}
gender.math.level = gender.plotly("math.level", "Math Course Level")
gender.math.level
gender.race = gender.plotly("race", "Race")
gender.race
gender.class = gender.plotly("class", "Class")
gender.class
gender.major = gender.plotly("major", "Major")
gender.major
gender.modality = gender.plotly("modality", "Modality")
gender.modality
Some of the patterns observed in this study are consistent with the
existing literature.
- Female students have relatively higher evaluation anxiety level than
male students.
- The discrepancy of evaluation anxiety level across ethnic groups
also consistent with what reported in the existing literature.
Mathematical
Learning Anxiety
Mathematical learning anxiety stems directly from the subject matter,
where the primary source of distress is the act of engaging with
mathematical concepts. This engagement triggers an internal state of
confusion, frustration, and cognitive overload.
The next few figures examine the relationship between mathematical
learning anxiety and demographic factors, using the same visual approach
as we did for mathematical evaluation anxiety.
## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
gender.anxiety <- plot_ly(final.anxiety.dat,
x = ~sex,
y = ~Anxiety.mla.wt.pca,
color = as.formula(paste0("~",in.var1)),
type = "box",
boxpoints = "no",
jitter = 0.3,
pointpos = 0,
hoverinfo = "y + x + name",
hovertext = ~paste("Group:", in.var1,
"<br>Factor:", sex,
"<br>Score:", round(Anxiety.mla.wt.pca, 2)),
marker = list(size = 5, opacity = 0.7)) %>%
layout(title = paste("Math Learning Anxiety (wt.PCA): Gender vs ", in.var2,""),
xaxis = list(title = ""),
yaxis = list(title = "Learning Anxiety Score"),
boxmode = "group",
hoverlabel = list(bgcolor = "white", font = list(size = 12)),
margin = list(
t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
gender.anxiety
}
gender.math.level.mla = gender.plotly("math.level", "Math Course Level")
gender.math.level.mla
gender.race.mla = gender.plotly("race", "Race")
gender.race.mla
gender.class.mla = gender.plotly("class", "Class")
gender.class.mla
gender.major.mla = gender.plotly("major", "Major")
gender.major.mla
gender.modality.mla = gender.plotly("modality", "Modality")
gender.modality.mla
The Gender Gap in
Evaluation and Learning Anxiety
It turns out that, comparing to math learning anxiety, evaluation
anxiety manifests the gender gap. This observation is supported by
academic research. The key insight is that the gender gap in math
performance is more strongly linked to the anxiety generated by the
testing situation than by anxiety toward the subject matter itself
(leading potential learning anxiety).
A robust body of evidence, from foundational meta-analyses (Hembree,
1990) to contemporary studies (Devine et al., 2012; Goetz et al., 2013),
establishes that female students experience disproportionately high
levels of math test anxiety—a factor more predictive of academic
outcomes than learning anxiety. This finding illuminates the work of
Else-Quest et al. (2010), demonstrating that the gender gap in math
performance is profoundly shaped by anxiety in evaluative environments.
Therefore, addressing the specific pressures of testing situations is
essential for closing this gap.
The following figure illustrates the relationship between gender and
the two types of math anxiety: learning anxiety and evaluation
anxiety.
mea0 <- final.anxiety.dat[, c("sex", "Anxiety.mea.wt.pca")]
mla0 <- final.anxiety.dat[, c("sex", "Anxiety.mla.wt.pca")]
names(mea0) = c("sex", "anxiety.score")
names(mla0) = c("sex", "anxiety.score")
mea.mla <- rbind(mea0, mla0)
anxiety.type <- c(rep("mea", dim(mea0)[1]), rep("mla", dim(mea0)[1]))
mea.mla$anxiety.type <- anxiety.type
####
df = na.omit(mea.mla)
# Create more complex grouped boxplot with statistical annotations
# Custom hover information
fig <- plot_ly(df,
x = ~anxiety.type,
y = ~anxiety.score,
color = ~sex,
type = "box",
hoverinfo = "y+x+name",
hovertemplate = paste(
"Gender: %{x}<br>",
"Anxiety Type: %{fullData.name}<br>",
"Anxiety Score: %{y:.2f}<br>",
"<extra></extra>"
)) %>%
layout(
title = "Gender Disparities in Math Evaluation and Learning Anxiety",
xaxis = list(title = ""),
yaxis = list(title = "Anxiety Score"),
boxmode = "group",
hoverlabel = list(bgcolor = "white", font = list(size = 12)),
margin = list( t = 100, # Adjust this value to increase or decrease the top margin
b = 50,
l = 50,
r = 50)
)
fig
Our results are also consistent with existing results in
literature.
Student Perceived
Teaching Strategies, Math Anxiety, and Self-efficicay
The following heatmap illustrates the pairwise correlations between
anxiety levels, student-perceived teaching strategies, and other
associated cognitive factors. A negative correlation between anxiety and
another composite score (shown in blue) indicates that anxiety decreases
as that composite score increases.
var.name <-c( "Anxiety.mea.wt.pca", "Anxiety.mla.wt.pca", "SelfEfficacy.wt.pca", "Technology.wt.pca",
"Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca",
"Inductive.wt.pca", "Integrative.wt.pca", "LectureType.wt.pca",
"Repetitive.wt.pca", "Engage.wt.pca", "Resource.wt.pca")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c( "Anxiety.mea", "Anxiety.mla", "SelfEfficacy", "Technology",
"Cooporative", "Deductive.", "Demonstration",
"Inductive", "Integrative", "LectureType",
"Repetitive", "Engage", "Resource.")
# Calculate correlation matrix
cor_matrix <- cor(all.composite.scores, use = "complete.obs")
# Convert to long format using melt
cor_long <- melt(cor_matrix)
names(cor_long) <- c("x", "y", "r")
# Remove self-correlations and upper triangle if desired
cor_long <- cor_long[cor_long$x != cor_long$y, ]
# Create interactive heatmap
plot_ly(cor_long, x = ~x, y = ~y, z = ~r, type = "heatmap",
colorscale = "RdBu", zmin = -1, zmax = 1,
hoverinfo = "text",
text = ~paste("X:", x, "<br>Y:", y, "<br>r =", round(r, 3))) %>%
layout(title = "Correlation Matrix",
xaxis = list(title = ""),
yaxis = list(title = ""),
margin = list(l = 100, r = 50, b = 100, t = 50))
The figure above shows that all perceived teaching strategies are
negatively correlated with both types of anxiety. In addition, students
with high levels of self-efficacy tend to have low levels of math
anxiety. Furthermore, the composite score for technology use is
negatively correlated with both learning and evaluation anxiety,
implying that technology can help reduce math anxiety. Conversely, we
also see that students who use more learning resources tend to have
higher learning anxiety.
In the next few subsections, we analyze relationships between the
scales in this survey and compare our results with those in the existing
literature.
Interrelationship
Between Evaluation and Learning Anxieties
A positive correlation was found between mathematics evaluation
anxiety and mathematics learning anxiety, which is consistent with
previous research.
Mathematics learning anxiety is often the broader, foundational
issue, stemming from negative experiences and beliefs about one’s own
mathematical ability. Mathematics test anxiety is a more specific,
situational manifestation of this broader anxiety, triggered by the
evaluative pressure of exams.
The primary relationship is cyclical: learning anxiety fosters test
anxiety, and a negative test experience reinforces learning anxiety.
Gierl and Bisanz (1995) highlighted this cyclical nature. They suggested
that early negative experiences with math (leading to learning anxiety)
set the stage for later test anxiety. Conversely, a single traumatic
test experience (e.g., a disastrous final exam) can generalize to a
long-lasting, pervasive anxiety toward all math-related activities,
solidifying learning anxiety. Zakaria et al. (2012) found a significant
positive correlation between general mathematics anxiety and test
anxiety. Students who are already anxious in daily math classes are
primed for heightened anxiety when the stakes are raised in a test.
Both anxieties often stem from common roots, which explains their
high positive inter-relationship.
Negative Past Experiences: Repeated failure or
humiliation in math classes during K-12 education is a powerful
predictor for both types of anxiety in college (Maloney & Beilock,
2012).
Societal and Environmental Factors: Cultural stereotypes
(e.g., “math is for boys,” “some people just aren’t math people”) and
teacher anxiety can be transmitted to students, fostering a general
sense of apprehension toward the subject.
Fixed Mindset: The work of Carol Dweck (2006) on
mindset is highly relevant. Students with a “fixed mindset” (the belief
that math ability is an innate, unchangeable trait) are more vulnerable
to both learning and test anxiety. Any struggle is seen as evidence of a
lack of ability, causing them to avoid challenging learning and to
crumble under the evaluative pressure of tests.
Student Perceived
Teaching Strategies
We can see from the above correlation matrix (heatmap) that the seven
dimesions of student perceived teaching strategies are highly positively
correlated. This positive correlation among diverse teaching strategies
like cooperative, deductive, and lecture-type methods suggests that
students do not necessarily view these approaches as mutually exclusive.
Instead, they may perceive them as complementary tools within an
effective instructor’s repertoire. The reasons for this observed
intercorrelation can be attributed to several factors.
Instructor Versatility and Strategic Blending: A
single lesson might begin with a brief lecture to introduce a concept,
use a demonstrative example, and then engage students in a cooperative
problem-solving activity to apply the concept inductively. Students
perceive this blending, leading to positive correlations among the
strategies they observe.
Student Recognition of a Coherent Learning
Cycle: Students may perceive that different strategies serve
different, but interconnected, purposes in their learning journey. For
instance, a repetitive practice session might logically follow a
deductive explanation of a formula to build fluency, and an integrative
project might cap a unit to show real-world application. When these
strategies are sequenced effectively, students see them as parts of a
whole, coherent experience, leading to positive ratings across the board
(Boaler, 2016).
The Halo Effect of Pedagogical Richness: A
classroom environment rich with varied pedagogical approaches is often
more engaging. The positive affect generated by one engaging strategy
(e.g., a fun cooperative activity) can create a “halo effect,” leading
students to rate all the strategies used in that positive context more
highly, even the more traditional ones like lecture-type instruction
(Hattie, 2012).
However, these correlations can also be inflated by generalized
student attitudes rather than precise reflections of discrete teaching
acts. For example, the correlations might not reflect the actual
frequency of use but a generalized student perception of their
instructor. A student who holds a positive overall view of the teacher
might rate all teaching strategies highly, regardless of how effectively
each was individually deployed. This is a common form of response bias
in student evaluations (Spooren et al., 2013).
The correlation might also be confounded due to lack of discriminant
validity in perception. For ewxample, students, especially those without
pedagogical training, may not finely discriminate between the nuanced
definitions of each strategy. They might broadly perceive “the teacher
explains things clearly,” which could lead them to rate deductive,
demonstrative, and integrative strategies similarly because they all
contribute to that overarching feeling of clarity.
The Triad of Anxiety,
Self-Efficacy, and Teaching Strategies
Math self-efficacy, a concept derived from Albert Bandura’s social
cognitive theory, refers to an individual’s conviction in their ability
to successfully perform specific mathematical tasks. It is not a general
feeling of confidence but a situation-specific belief and a robust
predictor of perseverance, engagement, and academic success in
mathematics (Bandura, 1997).
Conversely, math anxiety is a state of tension, apprehension, or fear
that interferes with math performance. It is more than a simple dislike;
it is a debilitating emotional reaction that can create a vicious cycle:
anxiety leads to avoidance, which leads to poorer skills, which in turn
heightens anxiety (Ashcraft, 2002).
These two constructs are typically strongly and inversely correlated.
A student with high self-efficacy is less likely to experience anxiety
when faced with a math problem, while a student with high anxiety will
likely have their sense of efficacy eroded.
Critically, teaching strategies are not merely methods of content
delivery; they are powerful environmental forces that directly shape
students’ emotional and self-evaluative landscapes. Together, the triad
of Perceived Teaching Strategies, Math Anxiety, and Math Self-Efficacy
forms a dynamic, interconnected system that significantly influences a
student’s math achievement and overall relationship with the
subject.
The relationships within this triad are reciprocal. A student with
high math self-efficacy may thrive in a fast-paced lecture, viewing it
as an efficient way to acquire information. An anxious student in the
same environment, however, may become overwhelmed and disengaged.
Furthermore, students with high anxiety may actively avoid participating
in cooperative groups for fear of being judged, thereby missing out on
the very experiences that could build their confidence. In this way, a
student’s pre-existing anxiety and self-efficacy directly shape their
perception of and response to the learning environment itself.
include_graphics("TechingStrategies-Anxiety-Self-efficacy.png")

Grouping Teaching
Strategies
The following density curves represent naive composite
scores derived from the average of item scores for each of the seven
teaching strategies. These curves illustrate the students’ perceptions
of their instructors’ teaching strategies. A higher score indicates that
students were more likely to perceive the use of that strategy.
var.name <-c( "Cooporative.avg", "Deductive.avg", "Demonstration.avg",
"Inductive.avg", "Integrative.avg", "LectureType.avg",
"Repetitive.avg")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c("Cooperative", "Deductive", "Demonstrative",
"Inductive", "Integrative", "Lecture", "Repetitive")
# For older versions of tidyr
long_data <- all.composite.scores %>%
pivot_longer(
cols = c( Cooperative, Deductive, Demonstrative, Inductive, Integrative, Lecture, Repetitive), # Columns to reshape
names_to = "variable", # New column name for variable names
values_to = "value" # New column name for values
)
## Summarized stats
summary_stats <- long_data %>%
group_by(variable) %>%
summarise(
mean_val = mean(value),
median_val = median(value),
sd_val = sd(value),
n = n(),
.groups = 'drop'
)
# Create ridge plot with ggridges and convert to plotly
ridge_gg <- ggplot(long_data, aes(x = value, y = variable, fill = variable
)) +
geom_density_ridges(
alpha = 0.7,
scale = 2, # Adjust overlap
color = "white",
size = 0.5,
) +
scale_fill_brewer(palette = "Set1") +
#theme(plot.title = element_text(hjust = 0)) +
theme_ridges() +
labs(
title = "Distributions of Students' Perceived \n Teaching Strategy Indices",
x = "Perceived Teaching Strategy Score",
y = ""
) +
theme(legend.position = "none",
plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 1.2, unit = "cm"))
# Convert to plotly
ggplotly(ridge_gg)
As shown in the figure, the repetitive,
lecture-type, inductive, and
demonstrative approaches were perceived as more popular
than the integrative, deductive, and
cooperative approaches. This observation aligns with
the established classification of teaching styles in educational and
psychological research and classic textbooks.
| Deductive (Teacher provides rules and
examples: Joyce et al., 2015) |
Cooperative (Students work together:
Johnson, 2014) |
| Lecture Type (Teacher transmits
information: Brown,2007) |
Inductive (Students discover rules:
Bruner, 1961; Prince & Felder, 2006) |
| Demonstrative (Teacher shows how:
Borich, 2017) |
Integrative (Students connect ideas:
Jacobs, 1989; Fogarty,1991) |
| Repetitive (Teacher drills the
information: Ormrod, 2020) |
|
The above classification is consistent with the one based on
cognitive demand (Bloom’s Taxonomy), which categorizes strategies as
requiring either lower-level thinking (remember, understand) or
higher-level thinking (apply, analyze, evaluate, create).
Note: The Demonstrative Approach
sub-scale in this survey measures constructs associated with
both Traditional Teacher-Centered and
Student-Centered Strategies. It encompasses not only
the teacher’s direct demonstration of knowledge but also the use of
these demonstrations to facilitate student-led solution building,
characterizing it as a hybrid teaching strategy.
This classification demonstrates a spectrum of pedagogical
approaches, from traditional, highly structured methods like Lecture and
Deductive teaching, to modern, student-driven methods like Inductive,
Cooperative, and Integrative learning. Demonstration and Repetitive
practice serve specific, often complementary, roles within this
spectrum.
Teaching Strategies
Modulate the Triad
Teaching strategies are not merely methods of content delivery; they
are powerful environmental forces that directly shape students’
emotional and self-evaluative landscapes.
Teacher-Centered Strategies
Lecture-type and Deductive Approaches: These
methods, where the instructor presents established rules and procedures
first (deductive) in a largely one-way format (lecture), can
inadvertently exacerbate the triad’s negative potential. For a student
with low self-efficacy or high anxiety, the rapid, impersonal pace of a
lecture can reinforce feelings of inadequacy and inability to keep up.
The focus on a single “correct” method can stifle the exploratory
behaviors that build genuine understanding and confidence.
Repetitive (Drill-and-Practice) Approach: While
necessary for developing procedural fluency, an over-reliance on
repetitive practice can be a double-edged sword. For highly efficacious
students, it can solidify skills. However, for anxious students, it can
become a source of immense stress, framing mathematics as a monotonous,
performance-oriented subject where mistakes are failures. This can
directly undermine self-efficacy, as noted by researchers who found that
environments overly focused on speed and correct answers increase
anxiety (Ramirez et al., 2018).
Student-Centered Strategies
Inductive and Demonstrative Approaches: These
strategies, which involve presenting specific examples or phenomena from
which students derive patterns and rules (inductive) or visually
illustrating a concept (demonstrative), actively engage students in the
process of “doing mathematics.” By discovering relationships themselves,
students build a more robust and personal understanding. This process of
successful discovery is a potent source of mastery experience, the most
influential source of self-efficacy (Bandura, 1997). As understanding
deepens, anxiety often diminishes because the subject feels less
mysterious and more manageable.
Cooperative Learning: This is perhaps one of the
most powerful strategies for positively influencing the triad. Working
in small groups on meaningful tasks provides multiple psychological
benefits:
- Vicarious Experience: Students observe peers, who they
perceive as similar to themselves, successfully solving problems. This
is a key source of self-efficacy, showing them that “if they can do it,
so can I.”
- Verbal Persuasion: Peers and the teacher can offer
encouragement and feedback within a supportive, low-stakes setting.
- Reduced Anxiety: The burden of performance is shared,
mitigating the fear of public failure that can occur when a student is
called on alone in a whole-class setting. Studies consistently show that
cooperative learning environments are associated with lower levels of
math anxiety and higher levels of self-efficacy and achievement.
Integrative Approach: Connecting mathematics to
real-world problems and other disciplines makes the subject feel
relevant and meaningful. This can help students reframe math from a set
of abstract, intimidating rules to a useful tool for understanding the
world. This perceived utility can increase motivation and engagement,
which in turn can bolster self-efficacy and reduce anxiety by providing
a compelling reason to persist through challenges.
Create Single
Composite Score for the Classification
We next define two single indices to represent the teaching
strategies based on the above classification. We conceptualize
teacher-centered and student-centered strategies as two single-factor
constructs. The indices are defined using a doubly weighted average of
the principal components. Following common practice, we report the
validity and reliability measures before calculating the composite
scores for the two classified teaching strategies.
Validity Measures
var.name <-c("Cooporative.cfa", "Deductive.cfa", "Demonstration.cfa",
"Inductive.cfa", "Integrative.cfa", "LectureType.cfa",
"Repetitive.cfa")
Stratege.wt.pca <- final.anxiety.dat[, var.name]
names(Stratege.wt.pca) <- c("Cooperative", "Deductive", "Demonstrative",
"Inductive", "Integrative", "Lecture", "Repetitive")
teacher0 <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student0 <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative", "Deductive")]
###
###
teacher.vlid <-cfa.analysis(teacher0)
student.vlid <-cfa.analysis(student0)
##
vlid.table <-rbind(teacher.ctrd = teacher.vlid, student.ctrd = student.vlid)
row.name <- c("teacher.ctrd", "student.ctrd")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- c("std.all.min", "pval.max", "srmr", "cfi", "tli")
pander(vlid.table)
| teacher.ctrd |
0.561 |
0 |
1.582e-09 |
1 |
1 |
| student.ctrd |
0.4888 |
0 |
1.526e-08 |
1 |
1 |
Reliability Measures
teacher <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative")]
##
teacher.reliability <- Reliability.fun(teacher)
student.reliability <- Reliability.fun(student)
##
Rel.table <-rbind(teach = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel)
row.name <- c("Teacher", "Student")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
| Teacher |
0.842 |
0.8465 |
| Student |
0.8035 |
0.8066 |
The above goodness-of-fit and reliability measures exceed the
required thresholds of validity and reliability of an instrument. The
doubly weighted average of the original composite
scores of teaching strategies and appended to the analytic dataset.
######################################
#####
scores = function(df, dn){
###########################
## single factor score
##########################
x.var <- names(df)
n0 <- length(x.var)
cfa.model <- paste("latent =~", paste(x.var, collapse = " + "))
cfa.fit <- cfa(cfa.model, data = df, estimator = "MLM")
composite.cfa <- lavPredict(cfa.fit)
##########################
# pca analysis
##########################
pca.mdl <- prcomp(df, scale = TRUE)
pca0 <- pca.mdl$x[, 1]
r0 = cor(pca0, composite.cfa)
if(r0 < 0) {
pca.all <- -pca.mdl$x
}else{
pca.all <- pca.mdl$x
}
first.pca = pca.all[,1]
##########################
# weighted pca score
##########################
var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)
outdata <- as.data.frame(cbind(pca1 = first.pca,
wt.pca = as.vector(composite_weighted_pca),
cfa = as.vector(composite.cfa)))
names(outdata) <- paste0(dn,".", names(outdata), sep = "")
outdata
}
###
teacher <- scores(teacher, "Teacher.ctrd")
student <- scores(student, "Student.ctrd")
Anxiety.Analytic.Data <- cbind(finalDat, teacher, student)
Structural Equation
Modeling Approach
When working with multiple constructs, each measured by multiple
survey items, we are working with latent variables. Structural
equation modeling (SEM) is ideal because it explicitly models
the measurement (relationships between items and their latent construct)
and structural (relationships between the constructs) parts
simultaneously. Models such as linear regression, multivariate
regression, path analysis, confirmatory factor analysis, and structural
regression can be thought of as special cases of SEM. The following
relationships are possible in SEM:
- observed to observed variables (\(\gamma\), e.g., regression)
- latent to observed variables (\(\lambda\), e.g., confirmatory factor
analysis)
- latent to latent variables (\(\gamma, \beta\), e.g., structural
regression)
SEM uniquely encompasses both measurement and structural models. The
measurement model relates observed to latent variables and the
structural model relates latent to latent variables. Kline’s (2023) is a
classic and modern text covers up-to-date methods and applications. The
estimation of model parameters in SEM is based on the maximum likelihood
function with the assumption that all observed variables following
multivariate normal distribution.
Notations and
Technical Terms in SEM
Some Technical Terms in SEM:
observed variable: a variable that exists in the
data, a.k.a item or manifest variable
latent variable: a variable that is constructed
and does not exist in the data
exogenous variable: an independent variable
either observed (x) or latent (\(\xi\))
that explains an endogenous variable
endogenous variable: a dependent variable,
either observed (y) or latent (\(\eta\)) that has a causal path leading to
it
measurement model: a model that links observed
variables with latent variables
indicator: an observed variable in a measurement
model (can be exogenous or endogenous)
factor: a latent variable defined by its
indicators (can be exogenous or endogenous)
loading: a path between an indicator and a
factor
structural model: a model that specifies causal
relationships among exogenous variables to endogenous variables (can be
observed or latent)
regression path: a path between exogenous and
endogenous variables (can be observed or latent)
SEM Path Model
A path model serves as the visual and mathematical blueprint for a
Structural Equation Model (SEM). This diagram employs a standardized
notation to represent hypothesized relationships between variables. The
specific model to be tested, which examines the complex structural
relationships between endogenous and exogenous variables, has the
following structure:
include_graphics("HypotheticalSEM.png")

To better understand the advantages and disadvantages of Structural
Equation Modeling (SEM) for analyzing complex relationships—such as
those between latent variables like math evaluation and learning
anxiety. we will briefly describe its mathematical formulation and MLE
of all model parameters using the above hypothetical SEM path model in
the appendix.
SEM
Implementation
We use the R lavaan library to implement the SEM to
assess the relationship between math evaluation, learning anxiety, and
related exogenous variables. The output presents results based on
standardized variables. The interpretation of the regression
coefficients is similar to that in a regular regression model,
indicating the change in the outcome (in standard deviations) for a
one-standard-deviation increase in a predictor.
Quick Reference of lavaan Syntax
~ predict, used for regression of observed outcome to
observed predictors (e.g., y ~ x)
1=~ indicator1, used for latent variable to observed
indicator in factor analysis measurement models (e.g.,
f =~ q + r + s)
- `
~~ covariance (e.g., x ~~ x)
~1 intercept or mean (e.g., x ~ 1
estimates the mean of variable x)
1* fixes parameter or loading to one (e.g.,
f =~ 1*q)
NA* frees parameter or loading (useful to override
default marker method, (e.g., f =~ NA*q)
a* labels the parameter ‘a’, used for model constraints
(e.g., f =~ a*q)
set.seed(12321)
Anxiety.mea <- Comp.Anxiety[, c("AMAS.2", "AMAS.4", "AMAS.5", "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]
names(Anxiety.mea) <- c("MEA2", "MEA4", "MEA5", "MEA8")
names(Anxiety.mla) <- c("MLA1", "MLA3", "MLA6", "MLA7", "MLA9")
factor.names <- c("Technology.wt.pca", "SelfEfficacy.wt.pca", "Engage.wt.pca", "sex",
"Teacher.ctrd.wt.pca", "Student.ctrd.wt.pca", "Resource.wt.pca")
##
factor.var <- Anxiety.Analytic.Data[, factor.names]
names(factor.var) <- c("Tech", "Efficacy", "Engage", "gender",
"Teacher.ctrd", "Student.ctrd", "Resource")
### strategies var
stratgy.var <-c("Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca", "Inductive.wt.pca","Integrative.wt.pca" ,"LectureType.wt.pca", "Repetitive.wt.pca" )
strategy.name <- c("Coop", "Deduc", "Demon", "Induc","Integ" ,"Lect", "Repet" )
teachingstrategy <- Anxiety.Analytic.Data[, stratgy.var]
names(teachingstrategy) <- strategy.name
SEM.data <- cbind(Anxiety.mea, Anxiety.mla, factor.var,teachingstrategy )
### SEM models
SEMModel <-
' Eval.Anxiety =~ MEA2 + MEA4 + MEA5 + MEA8 ## measurement model for Eval.Anxiety
Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9 ## measurement model for Learn.Anxiety
TeacherCtrd =~ Deduc + Lect + Demon + Repet # Teacher centered
StudentCtrd =~ Coop + Induc + Integ # Student centered
Eval.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd + StudentCtrd + Resource ## Eval.Anxiety as an outcome
Learn.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd+ StudentCtrd + Resource ## Learn.Anxiety as an outcome
Eval.Anxiety ~~ Learn.Anxiety ## correlation between Eval.Anxiety and Learn.Anxiety
'
output <- sem(model = SEMModel, data = SEM.data, std.lv = TRUE, estimator = "WLSMV",
mimic = "Mplus")
results <- summary(output, standardized = TRUE, fit.measures = TRUE)
The component regression and latent models in the SEM are specified
in the following.
## measurement model for Eval.Anxiety
Eval.Anxiety =~ MEA2 + MEA4 + MEA5 + MEA8
## measurement model for Learn.Anxiety
Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9
# Latent regression of teaching Strategies
TeacherCtrd =~ Deduc + Lect + Demon + Repet # Teacher centered
StudentCtrd =~ Coop + Induc + Integ # Student centered
## Eval.Anxiety as an outcome
Eval.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race
## Learn.Anxiety as an outcome
Learn.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race
Eval.Anxiety ~~ Learn.Anxiety ## correlation between Eval.Anxiety and Learn.Anxiety
The key goodness-of-fit statistics and estimated parameters are
summarized in the following.
The regression coefficients and factor loadings in the above table
are summarized in the following SEM path diagram generated using
lavaanPlot function.
lavaanPlot(model = output,
coefs = TRUE,
stand = TRUE,
stars = c("regress")) # Add significance stars
The path diagram generated by R for the SEM analysis is not easy to
read. Therefore, we sketched a new path diagram that includes only the
significant regression coefficients and factor loadings.
include_graphics("FittedlSEM.png")

Results and
Discussion of SEM Anlysis
A structural equation model (SEM) was estimated to examine the
effects of perceived teaching strategies and student characteristics on
two dimensions of mathematics anxiety: Math Evaluation Anxiety
(MEA) and Math Learning Anxiety (MLA). The
model demonstrated excellent fit to the data:
\[
\chi^2(168) = 542.75, \, p < .001, \,
\text{CFI} = .968, \,
\text{TLI} = .962, \,
\text{RMSEA} = .057 \, [90\% \text{CI } .051, .062], \,
\text{SRMR} = .059.
\]
Measurement Model
Standardized loadings were consistently strong across latent factors
(\(\lambda = .53\)–.89), supporting
reliability and convergent validity. The model explained 42.9% of the
variance in MEA and 29.7% in MLA.
Table 1. Standardized Factor Loadings and Variance Explained
for Latent Constructs
| Math Evaluation Anxiety |
MEA2 |
0.88 |
0.77 |
|
MEA4 |
0.84 |
0.70 |
|
MEA5 |
0.67 |
0.45 |
|
MEA8 |
0.65 |
0.42 |
| Math Learning Anxiety |
MLA1 |
0.53 |
0.28 |
|
MLA3 |
0.71 |
0.51 |
|
MLA6 |
0.74 |
0.54 |
|
MLA7 |
0.64 |
0.40 |
|
MLA9 |
0.73 |
0.54 |
| Teacher-Centered |
Deductive |
0.88 |
0.78 |
|
Lecture Type |
0.89 |
0.79 |
|
Demonstration |
0.80 |
0.64 |
|
Repetitive |
0.75 |
0.56 |
| Student-Centered |
Cooperative |
0.73 |
0.54 |
|
Inductive |
0.87 |
0.76 |
|
Integrative |
0.68 |
0.46 |
Structural Model
Standardized regression coefficients are shown in Table 2. Negative
coefficients indicate reduced anxiety.
Table2 <- data.frame(
Predictor = c("Technology Use","Self-Efficacy","Gender",
"Technology Use","Self-Efficacy","Engagement",
"Teacher-Centered Strategies","Student-Centered Strategies","Resource Availability"),
Outcome = c("Evaluation Anxiety","Evaluation Anxiety","Evaluation Anxiety",
"Learning Anxiety","Learning Anxiety","Learning Anxiety",
"Learning Anxiety","Learning Anxiety","Learning Anxiety"),
Beta = c(-.16,-.49,-.14,
-.22,-.45,-.09,
1.54,-1.87,.13),
SE = c(.04,.03,.04,
.04,.04,.04,
.82,.82,.04),
z = c(-3.91,-14.56,-3.88,
-5.14,-12.58,-2.50,
1.88,-2.29,3.07),
p = c("< .001","< .001","< .001",
"< .001","< .001",".012",
".060",".022",".002")
)
kable(Table2, caption = "Table 2. Standardized Structural Regression Paths Predicting Math Anxiety")
Table 2. Standardized Structural Regression Paths Predicting
Math Anxiety
| Technology Use |
Evaluation Anxiety |
-0.16 |
0.04 |
-3.91 |
< .001 |
| Self-Efficacy |
Evaluation Anxiety |
-0.49 |
0.03 |
-14.56 |
< .001 |
| Gender |
Evaluation Anxiety |
-0.14 |
0.04 |
-3.88 |
< .001 |
| Technology Use |
Learning Anxiety |
-0.22 |
0.04 |
-5.14 |
< .001 |
| Self-Efficacy |
Learning Anxiety |
-0.45 |
0.04 |
-12.58 |
< .001 |
| Engagement |
Learning Anxiety |
-0.09 |
0.04 |
-2.50 |
.012 |
| Teacher-Centered Strategies |
Learning Anxiety |
1.54 |
0.82 |
1.88 |
.060 |
| Student-Centered Strategies |
Learning Anxiety |
-1.87 |
0.82 |
-2.29 |
.022 |
| Resource Availability |
Learning Anxiety |
0.13 |
0.04 |
3.07 |
.002 |
Consistent with expectations, * More effectively using
technology reduced MEA (\(\beta =
-0.16\), \(p < .001\)) and
MLA (\(\beta = -0.22\), \(p < .001\)). * Higher
Self-efficacy students tended to have lower MEA (\(\beta = -0.49\), \(p < .001\)) and MLA (\(\beta = -0.45\), \(p < .001\)). * More
Engagement reduced MLA (\(\beta =
-0.09\), \(p = .012\)), and *
**gender* was significant. Male students tended to have lower MEA (\(\beta = -0.14\), \(p < .001\)).
Regarding teaching approaches, * student-centered
strategies significantly reduced MLA (\(\beta = -1.87\), \(p = .022\)). * Teacher-centered
strategies showed a marginally positive association with MLA
(\(\beta = 1.54\), \(p = .060\)); however, confidence intervals
included zero. Neither strategy significantly predicted MEA (\(p > .10\)).
A moderate, positive covariance remained between MEA and MLA:
\[
\phi_{MEA,MLA} = 0.50.
\]
indicating that students who experienced anxiety during learning also
tended to experience anxiety in evaluative situations. This is
consistent with eixting research as reviewed earlier.
These findings suggest that supportive instructional
approaches—particularly those emphasizing collaboration, inquiry, and
student participation—play an important role in reducing students’
emotional barriers to mathematics learning.
Discussion
The purpose of this study was to examine how perceived teaching
strategies, self-efficacy, technology use, engagement, and resource
availability relate to two forms of mathematics anxiety: Math
Evaluation Anxiety (MEA) and Math Learning Anxiety
(MLA). The results of the structural equation model (SEM)
provided strong support for the hypothesized associations and
highlighted instructional practices that may be particularly effective
for reducing students’ emotional challenges in mathematics contexts.
Interpretation of
Key Findings
Consistent with previous research, student-centered
strategies significantly reduced learning-related anxiety,
suggesting that learning environments promoting collaboration, inquiry,
and active engagement can mitigate negative emotional responses. Such
practices may help students feel more competent and supported, reducing
anxiety during math learning.
Teacher-centered approaches showed a marginally
positive association with learning anxiety. While direct instruction may
provide clarity and structure, excessive emphasis on performance and
correctness may inadvertently heighten pressure and lead to increased
anxiety (Ramirez et al., 2018). These results suggest that although
teacher guidance remains important, balanced instructional approaches
may be necessary to prevent adverse emotional effects.
Both self-efficacy and technology
use consistently predicted lower MEA and MLA. Students who
believe in their ability to succeed tend to approach math tasks with
more confidence and persistence, which protects against anxiety
(Bandura, 1997; Usher et al., 2019). Technology-enhanced learning
opportunities—such as immediate feedback and interactive practice—may
also increase comfort and control when engaging with math content.
Although smaller in magnitude, engagement also
contributed to reduced anxiety during learning. When students are
emotionally and behaviorally invested in math activities, they may
experience increased enjoyment and reduced avoidance tendencies (Dowker
et al., 2016). In contrast, resource availability was
associated with slightly higher learning anxiety. This may reflect
heightened expectations or perceived pressure to meet academic standards
when more supports are available.
Finally, the positive covariance between MEA and MLA
indicated meaningful overlap between the two constructs, consistent with
the literature showing shared emotional, cognitive, and motivational
underpinnings of different forms of math anxiety (Ashcraft & Moore,
2009). Together, these findings emphasize the importance of
instructional and motivational factors in shaping students’ math-related
emotional experiences.
Implications
These findings suggest that educators should foster environments that
promote student autonomy and confidence, while using instructional
supports that enhance understanding without increasing perceived
pressure. Professional learning programs may benefit from emphasizing
strategies that build emotional safety and support students’ belief in
their mathematical capability (Hembree, 1990). Additionally, technology
tools should be leveraged strategically to promote active participation
and self-paced engagement, rather than as stand-alone resources.
Limitations and
Future Directions
The cross-sectional design limits the ability to draw causal
conclusions. Longitudinal and intervention-based research could
strengthen understanding of how the identified factors contribute to
anxiety reduction over time. Self-report survey methods may introduce
social desirability or recall bias; therefore, multimethod approaches
incorporating observational or physiological data could further validate
findings. Future work may also explore instructional context, such as
classroom climate or teacher attitudes, as moderators of the
anxiety–strategy relationship.
Conclusion
Overall, this study demonstrates that math anxiety is shaped by a
combination of instructional practices and personal beliefs. Encouraging
student-centered instruction, self-efficacy building, technology
integration, and high-quality engagement can substantially reduce both
learning-related and evaluation-related anxiety. These results
underscore the importance of supporting students’ emotional well-being
as a foundation for their mathematical success.
References
Ashcraft, M. H. (2002). Math anxiety: Personal, educational, and
cognitive consequences. Current directions in psychological science,
11(5), 181-185.
Ashcraft, M. H., & Moore, A. M. (2009). Mathematics anxiety and
the affective drop in performance. Journal of Psychoeducational
assessment, 27(3), 197-205.
Asparouhov, T., & Muthén, B. (2005, November). Multivariate
statistical modeling with survey data. In Proceedings of the Federal
Committee on Statistical Methodology (FCSM) research conference
(pp. 14-16).
Bandalos, D. L. (2018). Measurement theory and applications for the
social sciences. Guilford Publications.
Bandura, A. (1997). Self-efficacy: The exercise of control (Vol. 11).
Freeman.
Boaler, J. (2015). Mathematical mindsets: Unleashing students’
potential through creative math, inspiring messages and innovative
teaching. John Wiley & Sons.
Borich, G. D. (2017). Effective Teaching Methods: Research-Based
Practice (9th ed.). Pearson.
Brown, H. D., & Lee, H. (1994). Teaching by principles: An
interactive approach to language pedagogy (Vol. 1, p. 994). Englewood
Cliffs, NJ: Prentice Hall Regents.
Brown, T. A. (2015). Confirmatory factor analysis for applied
research. Guilford publications.
Bruner, J. S. (1961). The act of discovery. Harvard educational
review. Cattell, R. B. (1952). Factor analysis: an introduction and
manual for the psychologist and social scientist.
Chang, H., & Beilock, S. L. (2016). The math anxiety-math
performance link and its relation to individual and environmental
factors: A review of current behavioral and psychophysiological
research. Current Opinion in Behavioral Sciences, 10, 33–38.
Cronbach, L. J. (1951). Coefficient alpha and the internal structure
of tests. Biometrika, 16, 297–335.
Daker, R. J., Gattas, S. U., Sokolowski, H. M., Green, A. E., &
Lyons, I. M. (2021). First-year students’ math anxiety predicts STEM
avoidance and underperformance throughout university, independently of
math ability. Npj Science of Learning, 6(1), 17.
Devine, A., Fawcett, K., Szűcs, D., & Dowker, A. (2012). Gender
differences in mathematics anxiety and the relation to mathematics
performance while controlling for test anxiety. Behavioral and brain
functions, 8(1), 33.
DiStefano, C., Zhu, M., & Mindrila, D. (2009). Understanding and
using factor scores: Considerations for the applied researcher.
Practical assessment, research, and evaluation, 14(1).
Dowker, A., Sarkar, A., & Looi, C. Y. (2016). Mathematics
anxiety: What have we learned in 60 years?. Frontiers in psychology, 7,
508.
Dreger, R. M., & Aiken Jr, L. R. (1957). The identification of
number anxiety in a college population. Journal of Educational
Psychology, 48(6), 344.
Duncan, O. D. (1961). A socioeconomic index for all occupations.
Occupations and social status..
Dweck, C. S. (2006). Mindset: The new psychology of success. Random
house.
Else-Quest, N. M., Hyde, J. S., & Linn, M. C. (2010).
Cross-national patterns of gender differences in mathematics: a
meta-analysis. Psychological bulletin, 136(1), 103.
Finney, S. J., & DiStefano, C. (2006). Non-normal and categorical
data in structural equation modeling. Structural equation modeling: A
second course, 10(6), 269-314.
Flora, D. B. (2017). Statistical Methods for the Social and
Behavioural Sciences: A Model-Based Approach. SAGE.
Fogarty, R. (1991). The mindful school: How to integrate the
curricula. Palatine, IL. SkyLight Publishing, Inc. Retrieved February,
22, 2002.
Gierl, M. J., & Bisanz, J. (1995). Anxieties and attitudes
related to mathematics in grades 3 and 6. The Journal of experimental
education, 63(2), 139-158.
Goetz, T., Bieg, M., Lüdtke, O., Pekrun, R., & Hall, N. C.
(2013). Do girls really experience more anxiety in mathematics?.
Psychological science, 24(10), 2079-2087.
Gough, Mary O. (1954). Why failures in mathematics? Mathemaphobia:
Causes and treatments. The Clearing House: A Journal of Educational
Strategies, Issues and Ideas, 28(5), 290–294.
Guttman, L. (1954). Some necessary conditions for common-factor
analysis. Psychometrika, 19(2), 149-161.
Hattie, J. (2012). Visible learning for teachers: Maximizing impact
on learning. Routledge.
Hembree, R. (1990). The nature, effects, and relief of mathematics
anxiety. Journal for research in mathematics education, 21(1),
33-46.
Hopko, D. R., Mahadevan, R., Bare, R. L., & Hunt, M. K. (2003).
The abbreviated math anxiety scale (AMAS) construction, validity, and
reliability. Assessment, 10(2), 178–182.
Hirschberg, E., & Standish, C. V. (1959). A method of deriving a
stratification score by using the principal components of the
correlation matrix. American Statistical Association, Proceedings of the
Social Statistics Section, 1959, 220-225.
Jacobs, H. H. (1989). Interdisciplinary curriculum: Design and
implementation. Association for Supervision and Curriculum Development,
1250 N. Pitt Street, Alexandria, VA 22314.
Jolliffe, I. T., & Cadima, J. (2016). Principal Component
Analysis: A Review and Recent Developments. Philosophical Transactions
of the Royal Society A, 374(2065), 20150202.
Johnson, D. W., Johnson, R. T., & Smith, K. A. (2014).
Cooperative learning: Improving university instruction by basing
practice on validated theory. Journal on excellence in college teaching,
25(3&4).
Jose M. Cardino Jr. and Ruth A. Ortega-Dela Cruz, Understanding of
learning styles and teaching strategies towards improving the teaching
and learning of mathematics, LUMAT General Issue, Vol 8 No 1 (2020),
19–43. Doi: 10.31129/ LUMAT.8.1.1348
Joyce, B., Weil, M., & Calhoun, E. (2015). Models of Teaching
(9th ed.). Pearson.
Klee, H. L., Buehl, M. M., & Miller, A. D. (2022). Strategies for
alleviating students’ math anxiety: Control-value theory in practice.
Theory Into Practice, 61(1), 49–61.
Kline, R. B. (2023). Principles and practice of structural equation
modeling. Guilford publications.
Lazarsfeld, P. F., Stouffer, S. A., Guttman, L., & Suchman, E. A.
(1950). Measurement and prediction. SA Stouffer (éd.) Studies in social
psychology in world war II, 4.
Li, C. H. (2016). The performance of ML, DWLS, and ULS estimation
with robust corrections in structural equation models with ordinal
variables. Psychological methods, 21(3), 369.
López-Bonilla, J. M.l and López-Bonilla, L. M. (2012), Validation of
an information technology anxiety scale in undergraduates, British
Journal of Educational Technology Vol 43. No 2. E56–E58. doi:10.1111/j.1467-8535.2011.01256.x
Maloney, E. A., & Beilock, S. L. (2012). Math anxiety: Who has
it, why it develops, and how to guard against it. Trends in cognitive
sciences, 16(8), 404-406.
Marsh, H. W. (1996). Positive and negative self-esteem: A
substantively meaningful distinction or artifactors? Journal of
Personality and Social Psychology, 70(4), 810–819.
McDonald, R. P. (1999). Test theory: A unified treatment. Mahwah:
Erlbaum.
Moliner, L., & Alegre, F. (2020). Peer tutoring effects on
students’ mathematics anxiety: A middle school experience. Frontiers in
Psychology, 11, 1610.
Muthén, B. (1984). A general structural equation model with
dichotomous, ordered categorical, and continuous latent variable
indicators. Psychometrika, 49(1), 115-132.
O’Leary, K., Fitzpatrick, C. L., & Hallett, D. (2017). Math
anxiety is related to some, but not all, experiences with math.
Frontiers in Psychology, 8, 2067.
Ormrod, J. E. (2020). Human Learning (8th ed.). Pearson
Olsson, U. (1979). Maximum likelihood estimation of the polychoric
correlation coefficient. Psychometrika, 44(4), 443-460.
Pletzer, B., Wood, G., Scherndl, T., Kerschbaum, H. H., & Nuerk,
H.C. (2016). Components of mathematics anxiety: Factor modeling of the
MARS30-brief. Frontiers in Psychology, 7, 91.
Prince, M. J., & Felder, R. M. (2006). Inductive teaching and
learning methods: Definitions, comparisons, and research bases. Journal
of engineering education, 95(2), 123-138.
Ramirez, G., Shaw, S. T., & Maloney, E. A. (2018). Math anxiety:
Past research, promising interventions, and a new interpretation
framework. Educational psychologist, 53(3), 145-164.
Richardson, F. C., & Suinn, R. M. (1972). The mathematics anxiety
rating scale: Psychometric data. Journal of Counseling Psychology,
19(6), 551.
Rozgonjuk, D., Kraav, T., Mikkor, K., Orav-Puurand, K., & Täht,
K. (2020). Mathematics anxiety among STEM and social science students:
The roles of mathematics self-efficacy, and deep and surface approach to
learning. International Journal of STEM Education, 7(1), 1–11.
Segool, N. K., Carlson, J. S., Goforth, A. N., Von Der Embse, N.,
& Barterian, J. A. (2013). Heightened test anxiety among young
children: Elementary school students’ anxious responses to high-stakes
testing. Psychology in the Schools, 50(5), 489–499.
Spooren, P., Brockx, B., & Mortelmans, D. (2013). On the validity
of student evaluation of teaching: The state of the art. Review of
Educational Research, 83(4), 598-642.
Usher, E. L., Li, C. R., Butz, A. R., & Rojas, J. P. (2019).
Perseverant grit and self-efficacy: Are both essential for children’s
academic success?. Journal of Educational Psychology, 111(5), 877.
Watson, D., Clark, L. A., & Tellegen, A. (1988). Development and
validation of brief measures of positive and negative affect: The PANAS
scales. Journal of Personality and Social Psychology, 54(6),
1063–1070.
Wilson, S. (2013). Mature age pre-service teachers’ mathematics
anxiety and factors impacting on university retention. Mathematics
Education: Yesterday, Today and Tomorrow (MERGA36), 666–673.
Zakaria, E., Zain, N. M., Ahmad, N. A., & Erlina, A. (2012).
Mathematics anxiety and achievement among secondary school students.
American Journal of Applied Sciences, 9(11), 1828.
Appendices
Mathematics of
PCA
1. Problem Definition
We will use a questionnaire with four items that assess math
evaluation anxiety to demonstrate the procedure.
- \(x_1\): Thinking about a math test
the day before you take it.
- \(x_2\): Taking a math test.
- \(x_3\): Being given a homework
assignment of many difficult problems that is due for the next class
meeting.
- \(x_4\): Being given a quiz on math
without knowing in advance.
Let \(\mathbf{x} = [x_1, x_2, x_3,
x_4]^T\) be a random vector representing the responses of a
randomly selected individual to the four items. We assume \(\mathbf{x}\) has a population mean vector
\(\boldsymbol{\mu}\) and population
covariance matrix \(\boldsymbol{\Sigma}\).
We collect a sample of \(n\)
individuals. The data matrix is \(\mathbf{X}_{n \times 4}\), where each row
is an individual’s response vector. The sample mean vector is \(\bar{\mathbf{x}}\), and the sample
covariance matrix is \(\mathbf{S}\).
2. Preprocessing: Centering the Data
The first step is to center the data. We subtract the mean of each
variable, creating a new data matrix \(\mathbf{Y}\):
\[
\mathbf{Y} = \mathbf{X} - \mathbf{1}\bar{\mathbf{x}}^T
\]
where \(\mathbf{1}\) is an \(n \times 1\) vector of ones. The elements
of \(\mathbf{Y}\) are \(y_{ij} = x_{ij} - \bar{x}_j\). From this
point forward, we work with the centered data \(\mathbf{Y}\), ensuring \(E[\mathbf{y}] = \mathbf{0}\).
3. Goal of Principal Component Analysis (PCA)
The goal of PCA is to find a new set of uncorrelated variables \(\mathbf{z} = [z_1, z_2, z_3, z_4]^T\),
called the (PCs), which are linear combinations of the original centered
variables \(\mathbf{y}\).
\[
\mathbf{z} = \mathbf{W}^T\mathbf{y}
\]
The matrix \(\mathbf{W}\) is an
orthogonal matrix (\(\mathbf{W}^T\mathbf{W} =
\mathbf{I}\)) whose columns \(\mathbf{w}_i\) are the . The components
must satisfy:
- The first component, \(z_1 =
\mathbf{w}_1^T \mathbf{y}\), has the maximum possible
variance.
- The \(k\)-th component, \(z_k = \mathbf{w}_k^T \mathbf{y}\), has the
maximum possible variance subject to being uncorrelated with (orthogonal
to) all previous components \(z_1, \dots,
z_{k-1}\).
4. Derivation of the First Principal Component
Let \(\mathbf{w}_1\) be the vector
of weights for the first PC, \(z_1 =
\mathbf{w}_1^T \mathbf{y}\). The sample variance of \(z_1\) is given by:
\[
\begin{align*}
\text{Var}(z_1) &= \text{Var}(\mathbf{w}_1^T \mathbf{y}) \\
&= E[(\mathbf{w}_1^T \mathbf{y})(\mathbf{w}_1^T
\mathbf{y})^T] \quad \text{(since} E[\mathbf{y}]=\mathbf{0}) \\
&= E[\mathbf{w}_1^T \mathbf{y} \mathbf{y}^T
\mathbf{w}_1] \\
&= \mathbf{w}_1^T E[\mathbf{y} \mathbf{y}^T]
\mathbf{w}_1 \\
&= \mathbf{w}_1^T \boldsymbol{\Sigma} \mathbf{w}_1
\end{align*}
\]
In practice, we use the sample covariance matrix \(\mathbf{S} = \frac{1}{n-1} \mathbf{Y}^T
\mathbf{Y}\).
We wish to maximize \(\mathbf{w}_1^T
\mathbf{S} \mathbf{w}_1\) subject to the normalization constraint
\(\mathbf{w}_1^T \mathbf{w}_1 = 1\) (to
prevent the variance from growing arbitrarily large). We solve this
using the method of Lagrange multipliers.
The Lagrangian is:
\[
\mathcal{L}(\mathbf{w}_1, \lambda_1) = \mathbf{w}_1^T \mathbf{S}
\mathbf{w}_1 - \lambda_1 (\mathbf{w}_1^T \mathbf{w}_1 - 1)
\]
Taking the gradient with respect to \(\mathbf{w}_1\) and setting it to zero:
\[
\frac{\partial \mathcal{L}}{\partial \mathbf{w}_1} =
2\mathbf{S}\mathbf{w}_1 - 2\lambda_1 \mathbf{w}_1 = 0
\]
This yields the key :
\[
\begin{equation}
\mathbf{S} \mathbf{w}_1 = \lambda_1 \mathbf{w}_1
\end{equation}
\]
Substituting the above equation back into the variance
expression:
\[
\text{Var}(z_1) = \mathbf{w}_1^T \mathbf{S} \mathbf{w}_1 =
\mathbf{w}_1^T (\lambda_1 \mathbf{w}_1) = \lambda_1 \mathbf{w}_1^T
\mathbf{w}_1 = \lambda_1
\]
Thus, the variance of the first principal component \(z_1\) is the eigenvalue \(\lambda_1\). To maximize the variance, we
must choose the .
5. Derivation of the Second Principal Component
We now seek the second component \(z_2 =
\mathbf{w}_2^T \mathbf{y}\) that has maximum variance, subject to
\(\mathbf{w}_2^T \mathbf{w}_2 = 1\) and
\(\mathbf{w}_2^T \mathbf{w}_1 = 0\)
(ensuring \(z_2\) is uncorrelated with
\(z_1\)).
The Lagrangian for this problem is:
\[
\mathcal{L}(\mathbf{w}_2, \lambda_2, \phi) = \mathbf{w}_2^T \mathbf{S}
\mathbf{w}_2 - \lambda_2 (\mathbf{w}_2^T \mathbf{w}_2 - 1) - \phi
(\mathbf{w}_2^T \mathbf{w}_1)
\]
Taking the gradient with respect to \(\mathbf{w}_2\) and setting it to zero:
\[
\frac{\partial \mathcal{L}}{\partial \mathbf{w}_2} =
2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 - \phi \mathbf{w}_1 =
0
\]
Multiply this equation on the left by \(\mathbf{w}_1^T\):
\[
2\mathbf{w}_1^T\mathbf{S}\mathbf{w}_2 - 2\lambda_2
\mathbf{w}_1^T\mathbf{w}_2 - \phi \mathbf{w}_1^T\mathbf{w}_1 = 0
\]
From the eigenvalue equation for \(\mathbf{w}_1\), we know \(\mathbf{w}_1^T\mathbf{S} = \lambda_1
\mathbf{w}_1^T\). The orthogonality constraint gives \(\mathbf{w}_1^T\mathbf{w}_2=0\).
Substituting these:
\[
2\lambda_1 \mathbf{w}_1^T\mathbf{w}_2 - 0 - \phi (1) = 0 \implies
2\lambda_1 (0) - \phi = 0 \implies \phi = 0
\]
With \(\phi=0\), the gradient
equation simplifies to:
\[
2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 = 0 \implies
\mathbf{S} \mathbf{w}_2 = \lambda_2 \mathbf{w}_2
\]
This is again an eigenvalue equation. The variance of \(z_2\) is \(\lambda_2\). To maximize the variance, we
choose the eigenvector \(\mathbf{w}_2\)
corresponding to the \(\lambda_2\). The
orthogonality \(\mathbf{w}_2^T \mathbf{w}_1 =
0\) is automatically satisfied for distinct eigenvalues since
\(\mathbf{S}\) is symmetric.
6. Subsequent Components and Full Solution
This process continues for all four components. The solution to the
PCA problem is found by performing the
eigendecomposition of the sample covariance matrix
\(\mathbf{S}\):
\[
\mathbf{S} = \mathbf{W} \boldsymbol{\Lambda} \mathbf{W}^T
\]
where:
- \(\boldsymbol{\Lambda}\) is a
diagonal matrix containing the eigenvalues in descending order: \(\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge
\lambda_4 \ge 0\).
- \(\mathbf{W} = [\mathbf{w}_1,
\mathbf{w}_2, \mathbf{w}_3, \mathbf{w}_4]\) is an orthogonal
matrix whose columns are the corresponding eigenvectors.
The principal components for an individual with centered response
vector \(\mathbf{y}\) are then computed
as:
\[
\mathbf{z} = \mathbf{W}^T \mathbf{y}
\]
The \(k\)-th PC score is \(z_k = \mathbf{w}_k^T \mathbf{y}\).
7. Variance Explained
The total variance in the original data is the sum of the variances
of the centered variables, which is the trace of \(\mathbf{S}\).
\[
\text{Total Variance} = \text{tr}(\mathbf{S}) = s_{11}^2 + s_{22}^2 +
s_{33}^2 + s_{44}^2
\]
For a symmetric matrix, this is also equal to the sum of its
eigenvalues:
\[
\text{Total Variance} = \lambda_1 + \lambda_2 + \lambda_3 + \lambda_4
\] The proportion of total variance explained by the \(k\)-th principal component is:
\[
\text{Proportion}_k = \frac{\lambda_k}{\sum_{i=1}^{4} \lambda_i}
\]
The cumulative variance explained by the first \(m\) components is:
\[
\text{Cumulative}_m = \frac{\sum_{i=1}^{m} \lambda_i}{\sum_{i=1}^{4}
\lambda_i}
\]
8. Interpretation in our Context
In the context of our math evaluation anxiety questionnaire:
The loading vector \(\mathbf{w}_1 =
[w_{11}, w_{12}, w_{13}, w_{14}]^T\) reveals how the original
items combine to form the primary latent dimension of anxiety. For
example, if all loadings are positive and similar, \(z_1\) might represent general Math
Evaluation Anxiety.
The second component \(\mathbf{w}_2\) might contrast different
types of anxiety. For instance, if \(w_{21}\) and \(w_{22}\) (test-related) are positive while
\(w_{23}\) and \(w_{24}\) (pop quiz/homework) are negative,
\(z_2\) might represent Test
Anxiety vs. Spontaneous Evaluation Anxiety.
By examining the loadings, we can interpret the underlying
psychological constructs that drive the correlations between the four
questionnaire items.
Confirmative Factor
Analysis (CFA)
This appendix provides a detailed mathematical derivation of a
Confirmatory Factor Analysis (CFA) model. The observed variables are
nine items related to mathematical anxiety, which are hypothesized to
load onto two latent factors: Test Anxiety (TA) and
Learning Anxiety (LA).
1. Latent Factors and Observed Variables
We define two latent factors:
- \(\eta_1\): Test Anxiety (TA)
- \(\eta_2\): Learning Anxiety
(LA)
We have nine observed variables (items/questions), \(y_1\) to \(y_9\):
- \(y_1\): Having to use tables in
the back of a math book.
- \(y_2\): Thinking about a math test
the day before you take it.
- \(y_3\): Watching the teacher work
out a math problem on the board.
- \(y_4\): Taking a math test.
- \(y_5\): Being given a homework
assignment of many difficult problems that is due for the next class
meeting.
- \(y_6\): Listening to a lecture in
math class.
- \(y_7\): Listening to another
student explain how to do a math problem.
- \(y_8\): Being given a quiz on math
without knowing in advance.
- \(y_9\): Starting a new chapter in
a math book.
2. Factor Loadings and Model Structure
We hypothesize the following factor structure:
- Factor \(\eta_1\) (Test Anxiety)
loads on items \(y_2\), \(y_4\), \(y_5\), and \(y_8\).
- Factor \(\eta_2\) (Learning
Anxiety) loads on items \(y_1\), \(y_3\), \(y_6\), \(y_7\), and \(y_9\).
The fundamental equation for a CFA model for a single observed
variable \(y_i\) is:
\[
y_i = \nu_i + \lambda_{i1} \eta_1 + \lambda_{i2} \eta_2 + \epsilon_i
\]
where:
- \(\nu_i\) is the intercept for
observed variable \(y_i\).
- \(\lambda_{i1}\) is the factor
loading of \(y_i\) on latent factor
\(\eta_1\).
- \(\lambda_{i2}\) is the factor
loading of \(y_i\) on latent factor
\(\eta_2\).
- \(\epsilon_i\) is the unique factor
(measurement error) for \(y_i\).
3. The Measurement Model in Matrix Form
The model for all nine observed variables can be written compactly in
matrix form. We define the following vectors and matrices:
- \(\mathbf{y} = (y_1, y_2, \dots,
y_9)^T\) is a \(9 \times 1\)
vector of observed variables.
- \(\boldsymbol{\nu} = (\nu_1, \nu_2, \dots,
\nu_9)^T\) is a \(9 \times 1\)
vector of intercepts.
- \(\boldsymbol{\eta} = (\eta_1,
\eta_2)^T\) is a \(2 \times 1\)
vector of latent factors.
- \(\boldsymbol{\Lambda}\) is a \(9 \times 2\) matrix of factor loadings
\(\lambda_{ij}\).
- \(\boldsymbol{\epsilon} = (\epsilon_1,
\epsilon_2, \dots, \epsilon_9)^T\) is a \(9 \times 1\) vector of measurement
errors.
The full measurement model is:
\[
\mathbf{y} = \boldsymbol{\nu} + \boldsymbol{\Lambda} \boldsymbol{\eta} +
\boldsymbol{\epsilon}
\]
Given our hypothesized factor structure, the loading matrix \(\boldsymbol{\Lambda}\) has a specific form
with many elements fixed to zero. To ensure model identification, we
need to set the scale of each latent variable. This is typically done by
factor standardization, where the variance of the
latent factor is fixed to 1, or by marker variable
method, where one loading per factor is fixed to 1. We will use the
latter.
Let us define:
- \(y_2\) as the marker variable for
\(\eta_1\) (Test Anxiety), so \(\lambda_{21} = 1\).
- \(y_1\) as the marker variable for
\(\eta_2\) (Learning Anxiety), so \(\lambda_{12} = 1\).
The \(\boldsymbol{\Lambda}\) matrix
is then:
\[
\boldsymbol{\Lambda} =
\begin{bmatrix}
0 & 1 \\ % y1 loads on eta2 (LA)
1 & 0 \\ % y2 loads on eta1 (TA)
0 & \lambda_{32} \\ % y3 loads on eta2 (LA)
\lambda_{41} & 0 \\ % y4 loads on eta1 (TA)
\lambda_{51} & 0 \\ % y5 loads on eta1 (TA)
0 & \lambda_{62} \\ % y6 loads on eta2 (LA)
0 & \lambda_{72} \\ % y7 loads on eta2 (LA)
\lambda_{81} & 0 \\ % y8 loads on eta1 (TA)
0 & \lambda_{92} \\ % y9 loads on eta2 (LA)
\end{bmatrix}
\]
4. Model Assumptions
The CFA model relies on several key assumptions:
The latent factors and errors are multivariate normally
distributed: \(\boldsymbol{\eta} \sim
N(\mathbf{0}, \boldsymbol{\Psi})\) and \(\boldsymbol{\epsilon} \sim N(\mathbf{0},
\boldsymbol{\Theta}_\epsilon)\).
The errors and factors are independent: \(\mathrm{Cov}(\boldsymbol{\eta},
\boldsymbol{\epsilon}) = \mathbf{0}\).
The observed variables, being linear combinations of normal
random variables, are therefore also multivariate normal: \(\mathbf{y} \sim N(\boldsymbol{\nu},
\boldsymbol{\Sigma})\).
5. Derivation of the Implied Covariance Matrix
The core of CFA is to model the population covariance matrix of the
observed variables, \(\boldsymbol{\Sigma}\). The model-implied
covariance matrix, denoted \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\),
is a function of the model parameters \(\boldsymbol{\theta}\) (loadings, factor
variances/covariances, error variances).
Let \(\boldsymbol{\Psi}\) be the
\(2 \times 2\) covariance matrix of the
latent factors:
\[
\boldsymbol{\Psi} = \mathrm{Cov}(\boldsymbol{\eta}) =
\begin{bmatrix}
\psi_{11} & \psi_{12} \\
\psi_{21} & \psi_{22}
\end{bmatrix}
=
\begin{bmatrix}
\mathrm{Var}(\eta_1) & \mathrm{Cov}(\eta_1, \eta_2) \\
\mathrm{Cov}(\eta_1, \eta_2) & \mathrm{Var}(\eta_2)
\end{bmatrix}
\]
The implied covariance matrix \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\)
is derived as follows:
\[
\begin{align*}
\boldsymbol{\Sigma}(\boldsymbol{\theta}) &= \mathrm{Cov}(\mathbf{y})
\\
&= \mathrm{Cov}(\boldsymbol{\nu} +
\boldsymbol{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}) \\
&= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta} +
\boldsymbol{\epsilon}) \quad \text{(since } \boldsymbol{\nu} \text{ is a
constant)} \\
&= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) +
\mathrm{Cov}(\boldsymbol{\epsilon}) +
\mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta},
\boldsymbol{\epsilon}) + \mathrm{Cov}(\boldsymbol{\epsilon},
\boldsymbol{\Lambda}\boldsymbol{\eta})
\end{align*}
\]
Using assumption 2 (\(\mathrm{Cov}(\boldsymbol{\eta},
\boldsymbol{\epsilon}) = \mathbf{0}\)), the cross-terms
vanish:
\[
\mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta},
\boldsymbol{\epsilon}) = \boldsymbol{\Lambda}
\mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0},
\quad \mathrm{Cov}(\boldsymbol{\epsilon},
\boldsymbol{\Lambda}\boldsymbol{\eta}) = \mathbf{0}
\]
Therefore,
\[
\begin{align*}
\boldsymbol{\Sigma}(\boldsymbol{\theta}) &=
\mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) +
\mathrm{Cov}(\boldsymbol{\epsilon}) \\
&= \boldsymbol{\Lambda} \mathrm{Cov}(\boldsymbol{\eta})
\boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon} \\
&= \boldsymbol{\Lambda} \boldsymbol{\Psi} \boldsymbol{\Lambda}^T +
\boldsymbol{\Theta}_{\epsilon}
\end{align*}
\]
This is the fundamental equation for the implied covariance matrix in
CFA:
\[
\boxed{\boldsymbol{\Sigma}(\boldsymbol{\theta}) = \boldsymbol{\Lambda}
\boldsymbol{\Psi} \boldsymbol{\Lambda}^T +
\boldsymbol{\Theta}_{\epsilon}}
\]
6. Parameter Estimation and Model Identification
The goal of estimation is to find parameter values \(\hat{\boldsymbol{\theta}}\) such that \(\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})\)
is as close as possible to the sample covariance matrix \(\mathbf{S}\) obtained from the data.
For identification, the number of free parameters \(t\) must be less than or equal to the
number of non-redundant elements in \(\mathbf{S}\), which is \(\frac{p(p+1)}{2}\) where \(p\) is the number of observed variables
(\(p=9\)).
Let’s count our free parameters \(t\):
Factor Loadings (\(\boldsymbol{\Lambda}\))}: We fixed \(\lambda_{21}\) and \(\lambda_{12}\) to 1. We have 7 free
loadings: \(\lambda_{32}\), \(\lambda_{41}\), \(\lambda_{51}\), \(\lambda_{62}\), \(\lambda_{72}\), \(\lambda_{81}\), \(\lambda_{92}\).
Latent Factor Covariances (\(\boldsymbol{\Psi}\))}: We have 3 free
parameters: \(\psi_{11}\) (variance of
TA), \(\psi_{22}\) (variance of LA),
and \(\psi_{12}\) (covariance between
TA and LA).
Error Variances (\(\boldsymbol{\Theta}_{\epsilon}\))}: We have
9 free parameters: \(\theta_{11}, \theta_{22},
\dots, \theta_{99}\).
Total free parameters: \(t = 7 + 3 + 9 =
19\).
The number of non-redundant elements in \(\mathbf{S}\) is \(\frac{9 \times (9+1)}{2} = 45\).
Since \(45 > 19\), the model is
over-identified with \(df =
45 - 19 = 26\) degrees of freedom. This is a necessary condition
for identification, and with the scaling constraints we placed, the
model is identified.
7. Maximum Likelihood Estimation of Parameters
This derivation has outlined the complete mathematical setup for a
two-factor CFA model of mathematical anxiety. The model posits that the
covariation among the nine observed items can be explained by two
correlated latent factors. The next step would be to use an estimation
algorithm (e.g., Maximum Likelihood) to find the parameter values that
minimize the difference between \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\)
and the sample covariance matrix \(\mathbf{S}\), and then assess the model’s
fit to the data.
The goal is to find the parameter values \(\hat{\boldsymbol{\theta}}\) that make the
model-implied covariance matrix \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\)
most likely to have produced the observed sample data.
Given a sample of \(N\) independent
and identically distributed (i.i.d.) observations \(\mathbf{y}_1, \mathbf{y}_2, \dots,
\mathbf{y}_N\), the likelihood function \(L(\boldsymbol{\theta})\) is the joint
probability density of observing all the data, given the parameters.
Under the i.i.d. assumption, this is the product of the individual
probability density functions (PDFs):
\[
L(\boldsymbol{\theta}) = \prod_{i=1}^{N} f(\mathbf{y}_i |
\boldsymbol{\theta})
\]
Where \(f(\mathbf{y}_i |
\boldsymbol{\theta})\) is the multivariate normal PDF for a
single observation vector \(\mathbf{y}_i\):
\[
f(\mathbf{y}_i | \boldsymbol{\theta}) = \frac{1}{(2\pi)^{p/2}
|\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{1/2}} \exp\left[
-\frac{1}{2} (\mathbf{y}_i - \boldsymbol{\nu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i -
\boldsymbol{\nu}) \right]
\]
Thus, the full likelihood function is:
\[
L(\boldsymbol{\theta}) = \prod_{i=1}^{N} \left[ \frac{1}{(2\pi)^{p/2}
|\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{1/2}} \exp\left(
-\frac{1}{2} (\mathbf{y}_i - \boldsymbol{\nu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i -
\boldsymbol{\nu}) \right) \right]
\]
7.1 The Log-Likelihood Function
It is computationally easier to work with the natural logarithm of
the likelihood function, the log-likelihood \(\ell(\boldsymbol{\theta}) = \ln
L(\boldsymbol{\theta})\). Converting the product into a sum
simplifies the expression:
\[
\begin{align*}
\ell(\boldsymbol{\theta}) &= \sum_{i=1}^{N} \ln f(\mathbf{y}_i |
\boldsymbol{\theta}) \\
&= \sum_{i=1}^{N} \left[ -\frac{p}{2} \ln(2\pi) - \frac{1}{2} \ln
|\boldsymbol{\Sigma}(\boldsymbol{\theta})| - \frac{1}{2} (\mathbf{y}_i -
\boldsymbol{\nu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}
(\mathbf{y}_i - \boldsymbol{\nu}) \right]
\end{align*}
\]
We can factor out the terms that do not depend on the summation index
\(i\):
\[
\ell(\boldsymbol{\theta}) = -\frac{Np}{2} \ln(2\pi) - \frac{N}{2} \ln
|\boldsymbol{\Sigma}(\boldsymbol{\theta})| - \frac{1}{2} \sum_{i=1}^{N}
\left[ (\mathbf{y}_i - \boldsymbol{\nu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i -
\boldsymbol{\nu}) \right]
\]
7.2. Simplifying with the Sample Covariance Matrix
The summation term is related to the sample covariance matrix. Let’s
define the sample mean vector as \(\bar{\mathbf{y}} = \frac{1}{N} \sum_{i=1}^N
\mathbf{y}_i\). It can be shown that:
\[
\sum_{i=1}^{N} (\mathbf{y}_i - \boldsymbol{\nu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i -
\boldsymbol{\nu}) = N \cdot \mathrm{tr}\left(
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} \mathbf{S} \right) + N
(\bar{\mathbf{y}} - \boldsymbol{\nu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\bar{\mathbf{y}} -
\boldsymbol{\nu})
\]
where \(\mathbf{S}\) is the unbiased
sample covariance matrix:
\[
\mathbf{S} = \frac{1}{N-1} \sum_{i=1}^{N} (\mathbf{y}_i -
\bar{\mathbf{y}})(\mathbf{y}_i - \bar{\mathbf{y}})^T
\]
and \(\mathrm{tr}(\cdot)\) is the
trace operator.
In the typical setup where the model for the means is saturated
(i.e., we set \(\boldsymbol{\nu} =
\bar{\mathbf{y}}\)), the last term vanishes. Furthermore, for
simplicity in derivation, if we use the Maximum Likelihood estimator for
the covariance matrix \(\mathbf{S}_{ML} =
\frac{1}{N} \sum_{i=1}^{N} (\mathbf{y}_i -
\bar{\mathbf{y}})(\mathbf{y}_i - \bar{\mathbf{y}})^T\), the
expression simplifies significantly.
With \(\boldsymbol{\nu} =
\bar{\mathbf{y}}\), we get:
\[
\sum_{i=1}^{N} (\mathbf{y}_i - \boldsymbol{\nu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{y}_i -
\boldsymbol{\nu}) = N \cdot \mathrm{tr}\left(
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} \mathbf{S}_{ML} \right)
\]
Substituting this back into the log-likelihood function, and ignoring
the constant term \(-\frac{Np}{2}
\ln(2\pi)\) as it does not affect optimization, we arrive at the
core function minimized in ML-CFA:
\[
\boxed{\ell(\boldsymbol{\theta}) = -\frac{N}{2} \left[ \ln
|\boldsymbol{\Sigma}(\boldsymbol{\theta})| + \mathrm{tr}\left(
\mathbf{S}_{ML} \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} \right)
\right] + \text{constant}}
\]
7.3. Maximum Likelihood Estimation
The Maximum Likelihood estimates \(\hat{\boldsymbol{\theta}}\) are found by
maximizing the log-likelihood function:
\[
\hat{\boldsymbol{\theta}}_{ML} =
\underset{\boldsymbol{\theta}}{\arg\max} \ \ell(\boldsymbol{\theta})
\]
In practice, this is done using iterative numerical algorithms (e.g.,
Newton-Raphson, Fisher Scoring) because the function \(\ell(\boldsymbol{\theta})\) is highly
nonlinear in the parameters \(\boldsymbol{\theta}\).
The value of the likelihood at the maximum is also used to compute
goodness-of-fit statistics, most notably the likelihood ratio test (or
chi-square test of model fit), which compares the fitted model to a
saturated model:
\[
\chi^2 = (N-1) F_{ML}
\]
where \(F_{ML}\) is the minimum
value of the discrepancy function, derived from the log-likelihood:
\[
F_{ML} = \ln |\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})| +
\mathrm{tr}\left( \mathbf{S}
\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})^{-1} \right) - \ln
|\mathbf{S}| - p
\]
Mathematical
Formulation of SEM Model
1. Model Specification
Let the model consist of the following components:
- Exogenous latent variables: \(\boldsymbol{\xi} = (\xi_1, \xi_2)^T\),
where:
- \(\xi_1\): Teacher-centered
- \(\xi_2\): Student-centered
- Endogenous latent variables: \(\boldsymbol{\eta} = (\eta_1, \eta_2)^T\),
where:
- \(\eta_1\): Math Evaluation Anxiety
(MEA)
- \(\eta_2\): Math Learning Anxiety
(MLA)
- Observed indicators for Teacher-centered: \(\mathbf{x}_1 = (x_1, x_2, x_3, x_4)^T\)
where:
- \(x_1\): Deductive
- \(x_2\): Lecture
- \(x_3\): Demonstration
- \(x_4\): Repetitive
- Observed indicators for Student-centered: \(\mathbf{x}_2 = (x_5, x_6, x_7)^T\) where:
- \(x_5\): Cooperative
- \(x_6\): Inductive
- \(x_7\): Integrative
- Observed indicators for MEA: \(\mathbf{y}_1 = (y_1, y_2, y_3, y_4)^T\)
(MEA1-MEA4)
- Observed indicators for MLA: \(\mathbf{y}_2 = (y_5, y_6, y_7, y_8,
y_9)^T\) (MLA1, MLA3, MLA6, MLA7, MLA9)
- Exogenous observed variables: \(\mathbf{w} = (w_1, w_2, w_3, w_4, w_5)^T\)
where:
- \(w_1\): Self-efficacy
- \(w_2\): Technology
- \(w_3\): Engagement
- \(w_4\): Gender
- \(w_5\): Resource
2. Measurement Models
For exogenous latent variables:
\[
\begin{align*}
\mathbf{x} &= \boldsymbol{\Lambda}_x \boldsymbol{\xi} +
\boldsymbol{\delta} \\
\begin{bmatrix}
x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7
\end{bmatrix}
&=
\begin{bmatrix}
\lambda_{1,1} & 0 \\
\lambda_{2,1} & 0 \\
\lambda_{3,1} & 0 \\
\lambda_{4,1} & 0 \\
0 & \lambda_{5,2} \\
0 & \lambda_{6,2} \\
0 & \lambda_{7,2}
\end{bmatrix}
\begin{bmatrix}
\xi_1 \\ \xi_2
\end{bmatrix}
+
\begin{bmatrix}
\delta_1 \\ \delta_2 \\ \delta_3 \\ \delta_4 \\ \delta_5 \\ \delta_6 \\
\delta_7
\end{bmatrix}
\end{align*}
\]
For endogenous latent variables:
\[
\begin{align*}
\mathbf{y} &= \boldsymbol{\Lambda}_y \boldsymbol{\eta} +
\boldsymbol{\epsilon} \\
\begin{bmatrix}
y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ y_6 \\ y_7 \\ y_8 \\ y_9
\end{bmatrix}
&=
\begin{bmatrix}
\lambda_{1,1}^y & 0 \\
\lambda_{2,1}^y & 0 \\
\lambda_{3,1}^y & 0 \\
\lambda_{4,1}^y & 0 \\
0 & \lambda_{5,2}^y \\
0 & \lambda_{6,2}^y \\
0 & \lambda_{7,2}^y \\
0 & \lambda_{8,2}^y \\
0 & \lambda_{9,2}^y
\end{bmatrix}
\begin{bmatrix}
\eta_1 \\ \eta_2
\end{bmatrix}
+
\begin{bmatrix}
\epsilon_1 \\ \epsilon_2 \\ \epsilon_3 \\ \epsilon_4 \\ \epsilon_5 \\
\epsilon_6 \\ \epsilon_7 \\ \epsilon_8 \\ \epsilon_9
\end{bmatrix}
\end{align*}
\]
3. Structural Model
The relationships between latent and observed variables:
\[
\begin{align*}
\boldsymbol{\eta} &= \mathbf{B} \boldsymbol{\eta} +
\boldsymbol{\Gamma} \boldsymbol{\xi} + \boldsymbol{\Gamma}_w \mathbf{w}
+ \boldsymbol{\zeta} \\
\begin{bmatrix}
\eta_1 \\ \eta_2
\end{bmatrix}
&=
\begin{bmatrix}
0 & 0 \\
\beta_{21} & 0
\end{bmatrix}
\begin{bmatrix}
\eta_1 \\ \eta_2
\end{bmatrix}
+
\begin{bmatrix}
\gamma_{11} & \gamma_{12} \\
\gamma_{21} & \gamma_{22}
\end{bmatrix}
\begin{bmatrix}
\xi_1 \\ \xi_2
\end{bmatrix}
+
\begin{bmatrix}
\gamma_{13} & \gamma_{14} & \gamma_{15} & \gamma_{16} &
\gamma_{17} \\
\gamma_{23} & \gamma_{24} & \gamma_{25} & \gamma_{26} &
\gamma_{27}
\end{bmatrix}
\begin{bmatrix}
w_1 \\ w_2 \\ w_3 \\ w_4 \\ w_5
\end{bmatrix}
+
\begin{bmatrix}
\zeta_1 \\ \zeta_2
\end{bmatrix}
\end{align*}
\]
4. Assumptions
- The measurement errors are uncorrelated with the latent
variables:
\[
\begin{align*}
E(\boldsymbol{\delta}|\boldsymbol{\xi}) = \mathbf{0}, \quad
E(\boldsymbol{\epsilon}|\boldsymbol{\eta}) = \mathbf{0}
\end{align*}
\]
- The structural disturbances have zero mean and are uncorrelated with
the exogenous variables:
\[
\begin{align*}
E(\boldsymbol{\zeta}) = \mathbf{0}, \quad
\text{Cov}(\boldsymbol{\zeta}, \boldsymbol{\xi}) = \mathbf{0}, \quad
\text{Cov}(\boldsymbol{\zeta}, \mathbf{w}) = \mathbf{0}
\end{align*}
\]
- The measurement errors and structural disturbances are mutually
uncorrelated:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\delta}, \boldsymbol{\epsilon}) = \mathbf{0},
\quad \text{Cov}(\boldsymbol{\delta}, \boldsymbol{\zeta}) = \mathbf{0},
\quad \text{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\zeta}) = \mathbf{0}
\end{align*}
\]
- The measurement errors are mutually uncorrelated:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\delta}) = \boldsymbol{\Theta}_{\delta} =
\text{diag}(\theta_{\delta,1}, \dots, \theta_{\delta,7})
\end{align*}
\]
\[
\begin{align*}
\text{Cov}(\boldsymbol{\epsilon}) = \boldsymbol{\Theta}_{\epsilon} =
\text{diag}(\theta_{\epsilon,1}, \dots, \theta_{\epsilon,9})
\end{align*}
\]
- The structural disturbances have covariance matrix:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\zeta}) = \boldsymbol{\Psi} =
\begin{bmatrix}
\psi_{11} & \psi_{12} \\
\psi_{21} & \psi_{22}
\end{bmatrix}
\end{align*}
\]
- The exogenous latent variables have covariance matrix:
\[
\begin{align*}
\text{Cov}(\boldsymbol{\xi}) = \boldsymbol{\Phi} =
\begin{bmatrix}
\phi_{11} & \phi_{12} \\
\phi_{21} & \phi_{22}
\end{bmatrix}
\end{align*}
\]
- The exogenous observed variables have covariance matrix:
\[
\begin{align*}
\text{Cov}(\mathbf{w}) = \boldsymbol{\Phi}_w
\end{align*}
\]
- All variables are multivariate normally distributed.
5. Implied Covariance Matrix
Let \(\boldsymbol{\theta}\)
represent all model parameters. The implied covariance matrix of the
observed variables \(\mathbf{z} =
(\mathbf{x}^T, \mathbf{y}^T, \mathbf{w}^T)^T\) is:
\[
\begin{align*}
\boldsymbol{\Sigma}(\boldsymbol{\theta}) =
\begin{bmatrix}
\boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) \\
\boldsymbol{\Sigma}_{yx}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) \\
\boldsymbol{\Sigma}_{wx}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{wy}(\boldsymbol{\theta}) &
\boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta})
\end{bmatrix}
\end{align*}
\]
where:
\[
\begin{align*}
\boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Lambda}_x^T +
\boldsymbol{\Theta}_{\delta} \\
\boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma}
\boldsymbol{\Phi} \boldsymbol{\Gamma}^T + \boldsymbol{\Gamma}_w
\boldsymbol{\Phi}_w \boldsymbol{\Gamma}_w^T + \boldsymbol{\Psi})
[(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T +
\boldsymbol{\Theta}_{\epsilon} \\
\boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta}) &= \boldsymbol{\Phi}_w
\\
\boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Gamma}^T
[(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T \\
\boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_x \text{Cov}(\boldsymbol{\xi}, \mathbf{w}) \\
\boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) &=
\boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma}
\text{Cov}(\boldsymbol{\xi}, \mathbf{w}) + \boldsymbol{\Gamma}_w
\boldsymbol{\Phi}_w)
\end{align*}
\]
6. Likelihood Function
Assuming multivariate normality of the observed variables \(\mathbf{z} \sim N(\boldsymbol{\mu},
\boldsymbol{\Sigma}(\boldsymbol{\theta}))\), the likelihood
function for a sample of \(n\)
independent observations is:
\[
\begin{align*}
L(\boldsymbol{\theta}) &= \prod_{i=1}^n (2\pi)^{-p/2}
|\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{-1/2}
\exp\left[-\frac{1}{2}(\mathbf{z}_i - \boldsymbol{\mu})^T
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{z}_i -
\boldsymbol{\mu})\right]
\end{align*}
\]
where \(p = 7 + 9 + 5 = 21\) is the
total number of observed variables.
The log-likelihood function is:
\[
\begin{align*}
\ell(\boldsymbol{\theta}) &= -\frac{np}{2} \log(2\pi) - \frac{n}{2}
\log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| \\
&\quad - \frac{1}{2} \sum_{i=1}^n (\mathbf{z}_i -
\boldsymbol{\mu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}
(\mathbf{z}_i - \boldsymbol{\mu})
\end{align*}
\]
For estimation, we typically use the discrepancy function:
\[
\begin{align*}
F_{ML}(\boldsymbol{\theta}) &=
\log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| + \text{tr}(\mathbf{S}
\boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}) - \log|\mathbf{S}| - p
\end{align*}
\]
where \(\mathbf{S}\) is the sample
covariance matrix.
7. Parameters to Estimate
The model parameters include:
- Factor loadings: \(\lambda_{ij}\)
in \(\boldsymbol{\Lambda}_x\) and \(\boldsymbol{\Lambda}_y\)
- Structural coefficients: \(\beta_{ij}\) in \(\mathbf{B}\), \(\gamma_{ij}\) in \(\boldsymbol{\Gamma}\), \(\gamma_{ij}^w\) in \(\boldsymbol{\Gamma}_w\)
- Variances and covariances: \(\phi_{ij}\) in \(\boldsymbol{\Phi}\), \(\psi_{ij}\) in \(\boldsymbol{\Psi}\), \(\phi_{w,ij}\) in \(\boldsymbol{\Phi}_w\)
- Measurement error variances: \(\theta_{\delta,i}\) in \(\boldsymbol{\Theta}_{\delta}\), \(\theta_{\epsilon,i}\) in \(\boldsymbol{\Theta}_{\epsilon}\)
Typically, we set one loading per latent variable to 1 for
identification.
8. Model Identification
The model is identified if:
- Each latent variable has at least 3 indicators (satisfied)
- The scale of each latent variable is set by fixing one loading to
1
- The model meets the order condition and rank condition for
identification
WLSMV for Likert
Data in SEM
The Weighted Least Squares Mean and Variance Adjusted (WLSMV)
estimator is a robust estimation method designed specifically for
structural equation modeling (SEM) with categorical or ordinal data,
particularly multi-item Likert scales. When working with ordered
categorical indicators (e.g., Likert-type items with 2-7 response
categories), traditional maximum likelihood (ML) estimation assumes
continuous normally distributed variables, which violates the discrete
nature of ordinal data.
Mathematical
Foundation
Let \(\mathbf{x}^*\) represent the
latent continuous variables underlying the observed ordinal responses
\(\mathbf{x}\). The measurement model
can be expressed as:
\[
\mathbf{x}^* = \boldsymbol{\Lambda} \boldsymbol{\xi} +
\boldsymbol{\delta}
\]
where \(\boldsymbol{\Lambda}\) is
the factor loading matrix, \(\boldsymbol{\xi}\) represents latent
variables, and \(\boldsymbol{\delta}\)
denotes measurement errors.
The WLSMV estimator minimizes the discrepancy function:
\[
F_{WLSMV} = (\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta}))'
\mathbf{W}^{-1} (\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta}))
\]
- \(\mathbf{s}\) is the vector of
sample polychoric correlations and threshold estimates
- \(\boldsymbol{\sigma}(\boldsymbol{\theta})\)
contains the model-implied correlations and thresholds
- \(\mathbf{W}\) is the consistent
asymptotic covariance matrix of \(\mathbf{s}\)
Key Features for Multi-item Likert Data
- Polychoric Correlations: WLSMV utilizes polychoric
correlations that estimate the linear relationship between underlying
continuous variables, providing more accurate estimates than Pearson
correlations for ordinal data.
- Threshold Estimation: The method estimates
thresholds \(\boldsymbol{\tau}\) that
define the boundaries between response categories:
\[
x_i = k \quad \text{if} \quad \tau_{k-1} < x_i^* \leq \tau_k
\]
Diagonal Weight Matrix: WLSMV employs a diagonal
weight matrix containing asymptotic variances of polychoric
correlations, making it computationally efficient while maintaining
robustness.
Mean and Variance Adjustment: The estimator
incorporates scaling corrections to the test statistics, providing
better approximation to \(\chi^2\)
distributions with small to moderate sample sizes.
Introduction to the Estimator
The Weighted Least Squares Mean and Variance adjusted (WLSMV)
estimator is a robust estimation method developed for structural
equation modeling (SEM) with categorical, and in particular, ordinal
observed variables. It is the recommended estimator for confirmatory
factor analysis (CFA) and SEM when the indicators are measured on an
ordinal scale, such as multi-item Likert scales common in social and
behavioral sciences (Brown, 2015, Flora, 2022).
The need for WLSMV arises from the violation of assumptions
underlying maximum likelihood (ML) estimation when observed variables
are ordinal. ML assumes continuous, multivariate normal data.
Likert-scale items are discrete, have limited scale points, and their
distributions are often non-normal, leading to:
- Inflated Chi-square (\(\chi^2\))
test statistics.
- Biased standard errors.
- Incorrect model fit indices .
Computational
Procedure
The WLSMV estimator is part of a family of diagonally weighted least
squares (DWLS) estimators. Its computation involves a specific sequence
of steps to handle the categorical nature of the data.
Step 1: Estimation of Polychoric Correlations
Since the ordinal categories are manifestations of an assumed
continuous, latent response distribution underlying each item, the first
step involves estimating the polychoric correlation
matrix. A polychoric correlation estimates the linear relationship
between two assumed continuous latent response variables based on the
observed ordinal data (Olsson, 1979). For each pair of items, a two-step
threshold estimation is performed, followed by the estimation of their
correlation.
Step 2: Estimation of the Asymptotic Covariance
Matrix
The next step is to compute the full asymptotic covariance
matrix of the polychoric correlation coefficients.
This matrix contains the variances and covariances of the estimated
polychoric correlations. It is a large matrix of dimension
\(p^*(p^*-1)/2\) (where \(p\) is the number of items) and accounts
for the precision of each correlation estimate. This matrix is used as
the weight matrix in the fitting function (Muthen, 1984).
Step 3: The Fitting Function and Mean-Variance
Adjustment
The parameter estimates are obtained by minimizing the DWLS fitting
function:
\[
F_{\text{DWLS}} = (\mathbf{s} -
\boldsymbol{\sigma}(\boldsymbol{\theta}))' \mathbf{W}^{-1}
(\mathbf{s} - \boldsymbol{\sigma}(\boldsymbol{\theta}))
\]
where \(\mathbf{s}\) is the vector
of estimated polychoric correlations, \(\boldsymbol{\sigma}(\boldsymbol{\theta})\)
is the vector of model-implied correlations, and \(\mathbf{W}^{-1}\) is the
diagonal of the inverse of the asymptotic covariance
matrix from Step 2. Using only the diagonal makes the computation more
stable and feasible with smaller sample sizes compared to the full WLS
estimator which uses the full matrix.
The “Mean and Variance” adjustment (MV) is the crucial final step
that makes WLSMV superior to plain WLS or DWLS. Instead of using the
\(\chi^2\) statistic and standard
errors derived directly from the DWLS fitting function, WLSMV applies a
correction:
- The test statistic is scaled (mean-adjusted) and shifted
(variance-adjusted) to more closely approximate a central \(\chi^2\) distribution.
- Standard errors for parameter estimates are computed using a robust
method (e.g., the sandwich estimator) that does not rely on the
assumption of correct model specification (Asparouhov, 2005).
This adjustment makes the WLSMV estimator far more robust in small to
moderate sample sizes and with large models where the asymptotic
assumptions of plain WLS are not met.
Advantages for
Multi-Item Likert Data
The WLSMV estimator provides specific advantages for modeling
multi-item Likert scale data:
- Realistic Assumptions: It does not assume
continuous normality for the observed Likert items, instead leveraging
the underlying continuous variable formulation.
- Accuracy: It generally produces the most accurate
parameter estimates, model fit statistics, and standard errors for
ordinal data compared to ML with a robust correction or plain DWLS (Li,
2016).
- Efficiency with Common Scales: It performs well
with the typical 5- to 7-point Likert scales ubiquitous in psychological
and survey research.
- Robustness to Sample Size: While larger samples are
always preferable, WLSMV performs adequately with smaller samples (e.g.,
\(N > 200\)) than what is required
for the full WLS estimator (Bandalos, 2014).
In conclusion, WLSMV is a robust, diagonally weighted least squares
estimator that uses a polychoric correlation matrix and applies a mean-
and variance-adjustment to the test statistics and standard errors,
making it the gold-standard choice for SEM with ordinal multi-item
Likert data.
Survey
Instruments
Abbreviated Math
Anxiety Scale (AMAS)
Please rate your feelings during different activities on a scale from
1 to 5. Try not to spend too much time on any one item. There are no
right or wrong answers.
1 = No bad feelings, 2 = Somewhat bad, 3 = nervous, 4 = Very bad feelings, 5 = Worst feelings
Having to use tables in the back of a math book.
Thinking about a math test the day before you take it.
Watching the teacher work out a math problem on the
board.
Taking a math test.
Being given a homework assignment of many difficult problems that
is due for the next class meeting.
Listening to a lecture in math class. [Listening to the teacher
talk for a long time in math]
Listening to another student explain how to do a math
problem.
Being given a quiz on math without knowing in advance.
Starting a new chapter in a math book. [Starting a new topic in
math]
Math Self-efficacy
Scale
Select the response that matches how much you now agree with each
statement. Try not to spend too much time on any one item. There are no
right or wrong answers.
1 = Strongly disagree 2 = disagree 3 = neutral 4 = agree 5 = Strongly agree
I usually understand a mathematical idea quickly.
I have to work very hard to understand mathematics.
I can connect the mathematical ideas that I have
learned.
Teaching
Strategies Questionnaire
The following statements are the ways your teacher teaches
mathematics. Respond to the items listed below:
5 – Always, 4 – Often, 3 – Sometimes, 2 – Seldom, 1 – Never
Cooperative-Approach
The teacher encourages students to work with others to generate
as many alternatives as they can for the problem discussed.
The teacher gives students enough time to think and to
investigate with others to achieve a desirable result.
The teacher gives students a chance to generate new
concepts.
The teacher applies group work in the class to serve desired
objectives.
The teacher distributes different teaching-learning tasks to
students.
The teacher lets students have their own conversations
positively.
Lecture Type
The teacher provides students with feedback regarding their
answers at all times.
The teacher ends the teaching-learning situation by clarifying
and discussing diagrams suitable for students.
The teacher trains students on generating specific answers to the
questions raised to them.
Teachers’ cognitive teaching strategies harmonize with students’
learning strategies.
The teacher allows students to have more clarifications and
explanations on a certain topic.
The teacher trains students to solve their problems in a
comfortable way.
The teacher makes students take part in different roles.
Deductive Approach
The teacher trains students to determine the whole idea of the
topic.
The teacher provides students with a chance to apply new
knowledge in new real-life situations.
The teacher trains students on learning the whole concept before
the specific idea.
Students tend to generate new information by making comparisons
between their previous knowledge and the new information.
The teacher moves from the abstract to the concrete
examples.
The teacher asks students to do written or verbal summaries of
the information they get.
The teacher distributes different teaching-learning tasks to
students.
Inductive Approach
The teacher uses specific questions to discuss the whole
topic.
The teacher disassembles the teaching-learning material into
specific tasks that need specific responses.
The teacher trains his students on distinguishing between
different characteristics of the same concept.
The teacher begins by presenting the main ideas of the topic at
the beginning of the class.
The teacher uses specific problem-solving strategies in the
teaching process.
The teacher assigns students a specific task within a general
task.
The teacher helps students to analyze the main idea to be used in
discussing the topic as a whole.
Demonstration
The teacher uses direct presentation to provide students with
information.
The teacher helps his students imitate desired models by showing
them.
The teacher begins the teaching-learning situation by presenting
a problem to students.
The teacher trains students to plan, observe, and evaluate their
teaching activities.
The teacher shows students how to verify information and facts
before making judgments.
The teacher begins with examples of the concept in the
teaching-learning situation.
The teacher teaches students the way to identify those simple
tricks to understand the lesson.
Repetitive Exercises
The teacher takes advantage of providing different activities to
secure the teaching-learning process.
The teacher cares about correcting students by providing many
worksheets.
The teacher gives similar examples during the discussion to
secure the mastery of the topic.
The teacher takes part in training students by providing
different learning activities.
The teacher helps students identify their own mistakes by doing
similar worksheets.
The teacher gives students the chance to correct their mistakes
by answering similar questions.
The teacher trains students by providing different sets of
worksheets.
Integrative Approach
The teacher awards students for their correct answer.
Teacher depends on criteria in evaluating their
students.
The teacher neglects undesired behaviors in teaching-learning
situations.
The teacher makes use of concept maps during the
teaching-learning process.
The teacher facilitates students to make use of the procedures
that organize memory potentials (symbolizing information).
The teacher guides students to references such as dictionaries,
encyclopedias, internet sites, etc.
The teacher supports students in using different learning tools
for the purpose of teaching the learning process.
Use of
technologies Scale
1: strongly disagree, 2: disagree, 3. Neutral, 4 agree, 5. Strongly agree
I feel apprehensive about using information technologies
(ITs)
Technological information sounds like confusing jargon to
me
I have avoided ITs because it is unfamiliar to me
I hesitate to use ITs for fear of making mistakes I cannot
correct
ITs do not scare me at all
Working with ITs would make me very nervous
I do not feel threatened when others talk about ITs
I feel aggressive and hostile toward ITs
IT makes me feel uncomfortable
I get a sinking feeling when I think of trying to use
ITs
IT makes me feel uneasy
IT makes me feel confused
Learning
modalities
- When I listen to a class lecture…
- I listen very closely.
- I try to be close to the speaker and watch the speaker.
- I take notes during the lecture.
- I like to solve word problems by…
- talking to a friend or to myself.
- using an organized approach with lists or charts.
- walking, pacing, or doing something active.
- When someone tells me numbers, but I am unable to write them down,
I…
- Repeat the numbers to myself out loud.
- visualize or see the numbers in my mind.
- Write the numbers in the air or on the table.
- I learn something new by…
- having someone explain it to me while I listen.
- having someone do it for me while I watch.
- doing it myself.
- When I watch a movie, I remember…
- everything (what was said, music, background noises).
- the costumes, environment, and scenery.
- how it made me feel.
- When I am trying to remember something, I…
- hear what was said or what sounds were around me.
- visualize it happening again in my mind.
- feel the way I did when it happened.
- When I do not know how to spell a word, I…
- sound it out.
- see the word in my mind.
- Write the word on paper until it looks right.
- I enjoy reading when the story has…
- a lot of dialogue (characters talking to each other).
- a lot of descriptive words.
- a lot of action.
- I remember new people by…
- their names.
- their faces.
- their actions.
- I have a hard time concentrating when…
- There is a lot of noise.
- There are a lot of people.
- I am uncomfortable (too hot, too cold, uncomfortable chair,
etc.).
- When it comes to clothes, I prefer to dress…
- in any way, since clothes are not that important to me.
- well – and I have a particular style.
- comfortably, so I can move around easily.
- If I cannot read aloud or get up and move around, I…
- Talk with a friend.
- look out a window.
- rock in my chair, tap my foot, drum my fingers, or jiggle my
pencil.
Engagement and
Resources
During the current school year at school, how often have you done the
following:
1 - Very often, 2 - Often, 3 - Sometimes, 4 – Never
Engagement
Asked questions in class.
Answered questions from professors or peers in class.
Contributed to class or group discussions.
Practice exercises/examples.
Took detailed class notes.
Previewed the content before class.
Reviewed class notes and other recommended exercises
Worked with other students on the course materials.
Use of Resources
Got help from professors via email.
Went to the professor’s in-person/Zoom office hours.
Used free peer tutoring through the Math Learning Center
Used private tutoring services.
LS0tDQp0aXRsZTogIk1hdGhlbWF0aWNzIEFueGlldHkgU3VydmV5IFJlcG9ydCINCmF1dGhvcjogIkNoZW5nIFBlbmcgJiBMYXVyYSBQeWF0dCINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KI1RPQzo6YmVmb3JlIHsNCiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc2l6ZTogMS4yZW07DQogIGRpc3BsYXk6IGJsb2NrOw0KICBjb2xvcjogbmF2eTsNCiAgbWFyZ2luLWJvdHRvbTogMTBweDsNCn0NCg0KDQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovDQogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQoNCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovDQogIGZvbnQtc2l6ZTogMjJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxNXB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCmxpYnJhcnkoR0dhbGx5KQ0KfQ0KIyBJbnN0YWxsIGFuZCBsb2FkIHRoZSBwYWNrYWdlDQppZiAoIXJlcXVpcmUoImljYSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImljYSIpDQpsaWJyYXJ5KGljYSkNCn0NCmlmICghcmVxdWlyZSgiZmFzdElDQSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImZhc3RJQ0EiKQ0KICBsaWJyYXJ5KGZhc3RJQ0EpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJNQVNTIikNCiAgbGlicmFyeShNQVNTKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0gDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfSANCmlmICghcmVxdWlyZSgibGF2YWFuIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygibGF2YWFuIikNCiAgbGlicmFyeShsYXZhYW4pDQp9IA0KaWYgKCFyZXF1aXJlKCJzZW1Ub29scyIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVRvb2xzIikNCiAgbGlicmFyeShzZW1Ub29scykNCn0NCmlmICghcmVxdWlyZSgic3RyaW5nciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInN0cmluZ3IiKQ0KICBsaWJyYXJ5KHN0cmluZ3IpDQp9DQppZiAoIXJlcXVpcmUoInJlc2hhcGUyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicmVzaGFwZTIiKQ0KICBsaWJyYXJ5KHJlc2hhcGUyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwc3ljaCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBzeWNoIikNCiAgbGlicmFyeShwc3ljaCkNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpDQogIGxpYnJhcnkoZ2dyaWRnZXMpDQp9DQppZiAoIXJlcXVpcmUoIlJDb2xvckJyZXdlciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQogIGxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJoZWF0bWFwbHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJoZWF0bWFwbHkiKQ0KICBsaWJyYXJ5KGhlYXRtYXBseSkNCn0NCmlmICghcmVxdWlyZSgic2VtUGxvdCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVBsb3QiKQ0KICBsaWJyYXJ5KHNlbVBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImxhdmFhblBsb3QiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsYXZhYW5QbG90IikNCiAgbGlicmFyeShsYXZhYW5QbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJib290IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiYm9vdCIpDQogIGxpYnJhcnkoYm9vdCkNCn0NCmlmICghcmVxdWlyZSgibGVhcHMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFwcyIpDQogIGxpYnJhcnkobGVhcHMpDQp9DQojIyBsaWJyYXJ5KGxlYXBzKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCg0KXA0KDQojIEludHJvZHVjdGlvbg0KDQpUaGUgc3ViamVjdCBvZiBtYXRoZW1hdGljcyBjYXVzZXMgZmVhciBhbmQgZGlmZmljdWx0eSBmb3IgYSB3aWRlIHJhbmdlIG9mIHN0dWRlbnRzLiBXZSBvZnRlbiBoZWFyIHN0dWRlbnRzIGNsYWltLCAiSSBkb24ndCBsaWtlIG1hdGgiLCAiSSdtIGp1c3Qgbm90IGdvb2QgYXQgbWF0aCIsICJJJ20gbm90IGEgbWF0aCBwZXJzb24iLCBvciAiSSB3YXNuJ3QgYm9ybiB3aXRoIHRoZSBtYXRoIGdlbmUiLCBldGMuIEFsdGhvdWdoIHRoZXNlIGNsYWltcyBhcmUgbm90IHBlcmZlY3QgaW5kaWNhdG9ycyBvZiBtYXRoIGFueGlldHksIHN0dWRlbnRzIHdobyBoYXZlIHRoZXNlIGZpeGVkIG1pbmRzZXRzIHdpbGwgYmUgbW9yZSBsaWtlbHkgdG8gZXhwZXJpZW5jZSBtYXRoIGFueGlldHkuDQoNCldoaWxlIG1hdGggYW54aWV0eSBjYW4gaGF2ZSBhIHNlcmlvdXMgaW1wYWN0IG9uIGFjYWRlbWljIHBlcmZvcm1hbmNlLCBpdCBkb2VzIG5vdCBtZWFuIGEgbGFjayBvZiBtYXRoZW1hdGljcyBhYmlsaXR5LiBQcm9mLiBMYXVyZW50IFNjaHdhcnR6IGV4cGVyaWVuY2VkIG1hdGggYW54aWV0eSBpbiB0aGUgMTF0aCBncmFkZSwgYnV0IHRoaXMgZGlkIG5vdCBwcmV2ZW50IGhpbSBmcm9tIGJlY29taW5nIGEgcHJvbWluZW50IG1hdGhlbWF0aWNpYW4uIEluIGZhY3QsIGhlIHdvbiB0aGUgRmllbGRzIE1vZGVsICh0aGUgbWF0aGVtYXRpY2lhbidzIE5vYmVsIFByaXplKSBpbiAxOTUwLiBFZmZlY3RpdmVseSBtYW5hZ2luZyBtYXRoIGFueGlldHkgcmVxdWlyZXMgYSBkZWVwIHVuZGVyc3RhbmRpbmcgb2YgbWF0aCBhbnhpZXR5Lg0KDQpUaGlzIHByb2plY3QgYWltcyB0byBpZGVudGlmeSBmYWN0b3JzIHRoYXQgYXJlIHN0cm9uZ2x5IGFzc29jaWF0ZWQgd2l0aCBtYXRoIGFueGlldHkgYW5kIHVzZSB0aGVtIHRvIHJlZHVjZSBtYXRoIGFueGlldHkgYW5kLCBjb25zZXF1ZW50bHksIGltcHJvdmUgYWNhZGVtaWMgcGVyZm9ybWFuY2UuIFNwZWNpZmljYWxseToNCg0KMS4gIFRoZSByZXN1bHRzIG9mIHRoaXMgcHJvamVjdCB3aWxsIGNvbnRyaWJ1dGUgdG8gdGhlIGJvZHkgb2YgZXhpc3Rpbmcga25vd2xlZGdlLg0KDQoyLiAgSWRlbnRpZmljYXRpb24gb2YgZW52aXJvbm1lbnRhbCBmYWN0b3JzIGFpZHMgdGhlIGRldmVsb3BtZW50IG9mIGludGVydmVudGlvbiB0b29scyBmb3IgZWR1Y2F0b3JzIGFuZCBzdXBwb3J0IHN0YWZmIHRvIGhlbHAgc3R1ZGVudHMgcmVkdWNlIG1hdGggYW54aWV0eSBhbmQgaW1wcm92ZSB0aGVpciBhY2FkZW1pYyBwZXJmb3JtYW5jZS4NCg0KMy4gIFRoZSBvdXRjb21lcyBvZiB0aGlzIHByb2plY3QgY2FuIGJlIHVzZWQgdG8gaW1wbGljaXRseSBpbXByb3ZlIHJldGVudGlvbi4NCg0KIyBMaXRlcmF0dXJlIFJldmlldw0KDQpNYXRoZW1hdGljcyBhbnhpZXR5IGludm9sdmVzIGZlZWxpbmdzIG9mIGZlYXIsIHRlbnNpb24sIGFwcHJlaGVuc2lvbiwgYW5kIHBoeXNpb2xvZ2ljYWwgcmVhY3Rpdml0eSBpbnRlcmZlcmluZyB3aGVuIGluZGl2aWR1YWxzIGVuZ2FnZSB3aXRoIG51bWJlciBtYW5pcHVsYXRpb24gYW5kIG1hdGhlbWF0aWNhbCBwcm9ibGVtLXNvbHZpbmcgKHNlZSwgZm9yIGV4YW1wbGUsIFBsZXR6ZXIgZXQgYWwuIDIwMTYpLiBJbiB0aGUgVS5TLiwgYW4gZXN0aW1hdGVkIDI1JSBvZiBmb3VyLXllYXIgY29sbGVnZSBzdHVkZW50cyBhbmQgdXAgdG8gODAlIG9mIGNvbW11bml0eSBjb2xsZWdlIHN0dWRlbnRzIHN1ZmZlciBmcm9tIGEgbW9kZXJhdGUgdG8gYSBoaWdoIGRlZ3JlZSBvZiBtYXRoZW1hdGljcyBhbnhpZXR5IChDaGFuZyAmIEJlaWxvY2ssIDIwMTYpLiBUaGUgZnJlcXVlbmN5IG9mIG5lZ2F0aXZlIGVmZmVjdHMgb2YgbWF0aCBhbnhpZXR5IG9uIGNvbGxlZ2Ugc3R1ZGVudHMgaXMgaW5jcmVhc2luZy4NCg0KVGhlIGVhcmxpZXN0IHJlc2VhcmNoIG9uIG1hdGggYW54aWV0eSBjYW4gYmUgdHJhY2VkIGJhY2sgdG8gR291Z2ggKDE5NTQpIHdobyB1c2VkIHRoZSB0ZXJtIG1hdGhlbWFwaG9iaWEuIFRoZSB0ZXJtIG1hdGggYW54aWV0eSB3YXMgZmlyc3QgdXNlZCBieSBEcmVnZXIgYW5kIEFpa2VuICgxOTU3KS4gVGhlIGZpcnN0IGRlZmluaXRpb24gb2YgbWF0aCBhbnhpZXR5IGlzIGNyZWRpdGVkIHRvIFJpY2hhcmRzb24gYW5kIFN1aW5uICgxOTcyKSwgd2hvIGRlc2NyaWJlZCBtYXRoIGFueGlldHkgYXMgImZlZWxpbmdzIG9mIHRlbnNpb24gYW5kIGFueGlldHkgdGhhdCBpbnRlcmZlcmUgd2l0aCB0aGUgbWFuaXB1bGF0aW9uIG9mIG51bWJlcnMgYW5kIHNvbHZpbmcgb2YgbWF0aGVtYXRpY2FsIHByb2JsZW1zIGluIGEgd2lkZSB2YXJpZXR5IG9mIG9yZGluYXJ5IGxpZmUgYW5kIGFjYWRlbWljIHNpdHVhdGlvbnMiLg0KDQpJbiB0aGUgcGFzdCA3MCB5ZWFycywgbnVtZXJvdXMgYXV0aG9ycyBjb25kdWN0ZWQgZXh0ZW5zaXZlIHJlc2VhcmNoIG9uIG1hdGggYW54aWV0eS4gUGFydGljdWxhcmx5LCBpbiB0aGUgcGFzdCAyMCB5ZWFycywgcmVzZWFyY2hlcnMgZnJvbSBkaWZmZXJlbnQgZGlzY2lwbGluZXMgaW5jbHVkaW5nIG1hdGhlbWF0aWNzIGhhdmUgaW52ZXN0aWdhdGVkIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIG1hdGggYW54aWV0eSBhbmQgbWF0aCBhY2hpZXZlbWVudCwgdGhlIGNhdXNlcyBvZiBtYXRoIGFueGlldHksIGNoYXJhY3RlcmlzdGljcyBvZiBzdHVkZW50cyB0aGF0IGluY3JlYXNlIHN1c2NlcHRpYmlsaXR5IHRvIG1hdGggYW54aWV0eSwgYW5kIGVmZm9ydHMgdGhhdCBlZHVjYXRvcnMgY2FuIHRha2UgdG8gcmVtZWR5IGl0Lg0KDQpNYXRoIGFueGlldHkgaXMgcmVhbC4gSXRzIG5lZ2F0aXZlIGltcGFjdCBvbiBzdHVkZW50cycgYWNhZGVtaWMgcGVyZm9ybWFuY2UgYW5kIHRoZWlyIGZ1dHVyZSBwcm9mZXNzaW9uYWwgbGlmZSBpcyBwcm9mb3VuZC4gRXh0ZW5zaXZlIHJlc2VhcmNoIHB1YmxpY2F0aW9ucyBzaW5jZSAyMDAwIGhhdmUgc2hvd24gdGhhdCBtYXRoIGFueGlldHkgcmVsYXRlcyBpbnZlcnNlbHkgdG8gcG9zaXRpdmUgYXR0aXR1ZGVzIHRvd2FyZCBtYXRoZW1hdGljcyBhbmQgaXMgYm91bmQgZGlyZWN0bHkgdG8gYXZvaWRhbmNlIG9mIHRoZSBzdWJqZWN0IChzZWUgZm9yIGV4YW1wbGUsIFNlZ29vbCBldCBhbC4sIDIwMTMpLiBJdCBhZmZlY3RzIGJvdGggbWF0aCBhbmQgb3ZlcmFsbCBhY2FkZW1pYyBwZXJmb3JtYW5jZSBzaW5jZSBtYXRoIGFueGlldHkgbGVhZHMgdG8gdGhlIGRyYWluYWdlIG9mIGNvZ25pdGl2ZSByZXNvdXJjZXMsIG1vdGl2YXRpb24gcmVkdWN0aW9uLCBhbmQgc3RyYXRlZ3kgaW1wYWlybWVudCAoS2xlZSBldCBhbC4sIDIwMjIpLg0KDQpNYXRoIGFueGlldHkgY2FuIGFsc28gbGVhZCB0byBwb29yIGFjYWRlbWljIHBlcmZvcm1hbmNlIGFuZCBjb3Vyc2Ugd2l0aGRyYXdhbCwgcHV0dGluZyBzdHVkZW50cyBiZWhpbmQgc2NoZWR1bGUgYW5kIGluY3JlYXNpbmcgdGhlIHJpc2sgb2YgZHJvcCBvdXQsIHdoaWNoIHJlZHVjZXMgc3R1ZGVudCByZXRlbnRpb24gcmF0ZXMuIFdpbHNvbiAoMjAxMykgc3R1ZGllZCBtYXRoIGFueGlldHkgb2YgbWF0dXJlLWFnZSBwcmUtc2VydmljZSB0ZWFjaGVycyBhcyBhIHBvdGVudGlhbCBjb250cmlidXRpbmcgZmFjdG9yIHRoYXQgaW1wYWN0cyBzdHVkZW50IHJldGVudGlvbi4gRGFrZXIgZXQgYWwuICgyMDIxKSByZWNlbnRseSBzdHVkaWVkIHRoZSBpbXBhY3Qgb2YgbWF0aCBhbnhpZXR5IG9uIGZpcnN0LXllYXIgU1RFTSBzdHVkZW50cyBhbmQgY29uY2x1ZGVkIHRoYXQgbWF0aCBhbnhpZXR5IHByZWRpY3RzIFNURU0gYXZvaWRhbmNlIGFuZCB1bmRlcnBlcmZvcm1hbmNlIHRocm91Z2hvdXQgdGhlIHVuaXZlcnNpdHksIGluZGVwZW5kZW50bHkgb2YgbWF0aCBhYmlsaXR5Lg0KDQpBIHdlYWx0aCBvZiBlbXBpcmljYWwgc3R1ZGllcyBvbiB2YXJpb3VzIGFzcGVjdHMgb2YgbWF0aCBhbnhpZXR5IGhhdmUgYmVlbiBjb25kdWN0ZWQgc2luY2UgRHJlZ2VyICYgQWlrZW4ncyAoMTk1Nykgc2VtaW5hbCB3b3JrLiBEdWUgdG8gdGhlIGNvbXBsZXggcGF0aHdheXMgdG93YXJkIHRoZSBkZXZlbG9wbWVudCBvZiBtYXRoIGFueGlldHkgYW5kIGl0cyBsaW5rcyB3aXRoIGFjaGlldmVtZW50cyBhbmQgY29uZm91bmRlcnMsIHRoZSBvcmlnaW5zIGFuZCBvdXRjb21lcyBvZiBtYXRoIGFueGlldHkgYXJlIHN0aWxsIG5vdCBmdWxseSB1bmRlcnN0b29kLg0KDQpSZWNlbnQgYW5kIG9uZ29pbmcgcmVzZWFyY2ggZm9jdXNlcyBvbiB0aGUgZGV2ZWxvcG1lbnQgYW5kIGR5bmFtaWMgaW50ZXJwbGF5IGJldHdlZW4gZmFjdG9ycyB0aGF0IGNhdXNlIG1hdGggYW54aWV0eS4gTW9zdCBvZiB0aGUgcmVzZWFyY2ggY2FuIGJlIGNsYXNzaWZpZWQgaW50byB0aHJlZSBjYXRlZ29yaWVzOiBzaXR1YXRpb25hbCwgZGlzcG9zaXRpb25hbCwgYW5kIGVudmlyb25tZW50YWwgKE8nTGVhcnkgZXQgYWwuLCAyMDE3KS4gVGhlIGN1cnJlbnQgcHJvamVjdCB3aWxsIGV4cGxvcmUgYWxsIHRocmVlIHR5cGVzIG9mIGZhY3RvcnMsIGJ1dCB0aGUgcHJpbWFyeSBmb2N1cyBpcyBvbiB0aGUgZW52aXJvbm1lbnRhbCBmYWN0b3JzIHN1Y2ggYXMgcHJpb3IgcGVyY2VwdGlvbnMsIGF0dGl0dWRlcywgYW5kIGV4cGVyaWVuY2VzIHRoYXQgaGF2ZSBhZmZlY3RlZCB0aGUgaW5kaXZpZHVhbC4NCg0KIyBSZXNlYXJjaCBPYmplY3RpdmVzDQoNClNpbmNlIGxvd2VyIG1hdGhlbWF0aWNzIGFjaGlldmVtZW50IHByZWRpY3RzIGhpZ2hlciBzdWJzZXF1ZW50IG1hdGggYW54aWV0eSBhbmQgaGlnaGVyIG1hdGggYW54aWV0eSBwcmVkaWN0cyBsb3dlciBmdXR1cmUgYWNoaWV2ZW1lbnQsIHJlZHVjaW5nIG1hdGggYW54aWV0eSB3aWxsIGhlbHAgc3R1ZGVudHMgZGV2ZWxvcCBhIHBvc2l0aXZlIGF0dGl0dWRlIHRvIG1hdGhlbWF0aWNzLCBidWlsZCBjb25maWRlbmNlLCBib29zdCBtb3RpdmF0aW9uLCBhbmQgY29uc2VxdWVudGx5IGltcHJvdmUgdGhlaXIgYWNoaWV2ZW1lbnRzLiBUaGlzIHN0dWR5IGFpbWVkIHRvIGlkZW50aWZ5IHRoZSBmYWN0b3JzIHRoYXQgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkgaW4gY29sbGVnZSBzdHVkZW50cy4gU3BlY2lmaWMgb2JqZWN0aXZlcyBhcmUNCg0KKipPYmplY3RpdmUgMSoqOiBBZG9wdGluZyB3ZWxsLWVzdGFibGlzaGVkIHBzeWNob21ldHJpYyBzdXJ2ZXkgaW5zdHJ1bWVudHMgQU1BUyBhbmQgc2VsZi1lZmZpY2FjeSBpbnN0cnVtZW50cyB0byBjb2xsZWN0IG1hdGggYW54aWV0eSBhbmQgc2VsZi1lZmZpY2FjeSBkYXRhLg0KDQoqKk9iamVjdGl2ZSAyKio6IEluY2x1ZGUgc29tZSBkZW1vZ3JhcGhpYyBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyBhZ2UgYW5kIGdlbmRlciB0byBjb21wYXJlIHRoZSByZXN1bHRzIHdpdGggdGhhdCBvZiBleGlzdGluZyByZXNlYXJjaCBhbmQgdXNlIHRoZW0gYXMgYSBiYXNlbGluZS4NCg0KKipPYmplY3RpdmUgMyoqOiBUZWFjaGluZyBzdHJhdGVnaWVzIGNhbiByZWR1Y2UgbWF0aCBhbnhpZXR5IGFuZCBpbXByb3ZlIGxlYXJuaW5nIG91dGNvbWVzLiBXZSB3aWxsIGludmVzdGlnYXRlIHNldmVyYWwgZGlmZmVyZW50IHN0cmF0ZWdpZXMgaW4gbWF0aGVtYXRpY3MgdGVhY2hpbmcgc3VjaCBhcyBjb25jZXB0dWFsLCBwcm9jZWR1cmUsIGV0Yy4sIHRvIHNlZSBpZiB0aGVzZSBzdHJhdGVnaWVzIGFmZmVjdCB0aGUgbGV2ZWwgb2YgbWF0aCBhbnhpZXR5Lg0KDQoqKk9iamVjdGl2ZSA0Kio6IEVmZmVjdGl2ZWx5IHVzaW5nIHRoZSB0ZWNobm9sb2dpZXMgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkuIFRoZSByZWNlbnRseSBkZXZlbG9wZWQgZWR1Y2F0aW9uYWwgdGVjaG5vbG9naWVzIGR1cmluZyB0aGUgcGFuZGVtaWMgaGF2ZSBub3QgYmVlbiBkaXNjdXNzZWQgaW4gdGhlIGxpdGVyYXR1cmUgb24gbWF0aCBhbnhpZXR5LiBXZSB3aWxsIGludmVzdGlnYXRlIGhvdyB0aGVzZSBuZXcgdGVjaG5vbG9naWVzIGFmZmVjdCBtYXRoIGFueGlldHkuDQoNCioqT2JqZWN0aXZlIDUqKjogTGVhcm5pbmcgbW9kYWxpdGllcyBhbmQgc3R5bGVzIGFyZSBhbHNvIGFzc29jaWF0ZWQgd2l0aCBtYXRoIGFueGlldHkuIE1vc3Qgb2YgdGhlIHJlc2VhcmNoIGluIHRoaXMgZGlyZWN0aW9uIGlzIGJhc2VkIG9uIGhpZ2ggc2Nob29sIHN0dWRlbnRzLiBXZSB3aWxsIGV4cGxvcmUgaG93IHRoZXNlIGxlYXJuaW5nIG1vZGFsaXRpZXMgYW5kIHN0eWxlcyBhZmZlY3QgbWF0aCBhbnhpZXR5IGFtb25nIGNvbGxlZ2Ugc3R1ZGVudHMuDQoNCioqT2JqZWN0aXZlIDYqKjogQ3JlYXRpbmcgYW5kIHVzaW5nIGNhbXB1cyBsZWFybmluZyByZXNvdXJjZXMgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkgYW5kIGltcHJvdmUgdGhlaXIgYWNhZGVtaWMgcGVyZm9ybWFuY2UgKE1vbGluZXIgJiBBbGVncmUsIDIwMjApLiBXZSB3aWxsIGV4cGxvcmUgd2hldGhlciBhbmQgaG93IGxlYXJuaW5nIHJlc291cmNlcyBvbiBjb2xsZWdlIGNhbXB1c2VzIHJlZHVjZSBhbnhpZXR5Lg0KDQojIE1hdGVyaWFscw0KDQojIyBQYXJ0aWNpcGFudHMNCg0KVGhlIHN1cnZleSB3YXMgYXBwcm92ZWQgYnkgV0NVJ3MgSVJCLiBXZSBpbnZpdGUgYWxsIFdDVSBzdHVkZW50cyB3aG8gdGFrZSB0aGVpciBmaXJzdCBXQ1UgbWF0aGVtYXRpY3MgYW5kIHN0YXRpc3RpY3MgY2xhc3MgaW4gdGhlIGZhbGwgc2VtZXN0ZXJzIG9mIDIwMjQgYW5kIHRoZSBzcHJpbmcgc2VtZXN0ZXIgb2YgMjAyNS4gUGFydGljaXBhdGlvbiBpbiB0aGUgc3R1ZHkgYXJlIHZvbHVudGFyeSBhbmQgcmVzcG9uc2VzIHJlbWFpbiBhbm9ueW1vdXMuIFRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgaW4gdGhlIHNwcmluZyBhbmQgZmFsbCBzZW1lc3RlcnMgb2YgMjAyNCBiYXNlZCBvbiB0aGUgcHJvdG9jb2xzIHNldCBieSBXQ1UncyBJbnN0aXR1dGlvbmFsIFJlc2VhcmNoLiBWaWEgUXVhbHRyaWNzLCB3ZSBzZW50IGFuIGludml0YXRpb24gZW1haWwgdG8gYWxsIHF1YWxpZmllZCBzdHVkZW50cyBzcHJpbmcgYW5kIGZhbGwgbWlkLXNlbWVzdGVyLiBBIHJlbWluZGVyIGVtYWlsIHdhcyBzZW50IGF0IHRoZSBlbmQgb2YgdGhlIHNlbWVzdGVyIHRvIG5vbi1yZXNwb25kaW5nIHN0dWRlbnRzIHRvIGJvb3N0IHRoZSBwYXJ0aWNpcGF0aW9uIHJhdGUuIEEgXCQxMCBBbWF6b24gZ2lmdCBjYXJkIHdhcyBvZmZlcmVkIHRvIHN1cnZleSBjb21wbGV0ZXJzIGFuZCBkaXN0cmlidXRlZCB0aHJvdWdoIFF1YWx0cmljcyBzbyBhbm9ueW1pdHkgaXMgZ3VhcmFudGVlZC4NCg0KVGhlIHN0dWR5IHBvcHVsYXRpb24gaW4gdGhpcyBzdHVkeSBpcyBkZWZpbmVkIGFzIFdDVSBzdHVkZW50cyBhZ2VkIDE4IHllYXJzIG9yIG9sZGVyIHdobyB0b29rIHRoZWlyIGZpcnN0IE1BVCBjbGFzcyBhdCBXQ1UuIFRoZSByZXN1bHRzIGluIHRoaXMgc3R1ZHkgY2FuIGJlIGdlbmVyYWxpemVkIHRvIHNpbWlsYXIgcmVnaW9uYWwgdW5pdmVyc2l0aWVzIGFuZCB0aG9zZSByZWNlbnRseSByZWNsYXNzaWZpZWQgUjIgaW5zdGl0dXRpb25zLg0KDQojIyBTdXJ2ZXkgSW5zdHJ1bWVudHMNCg0KVGhlIHN1cnZleSB3aWxsIGhhdmUgdGhyZWUgY29tcG9uZW50czoNCg0KMS4gICoqTXVsdGktaXRlbSBTdXJ2ZXkgSW5zdHJ1bWVudCBNYXRoIEFueGlldHkqKjogQU1BUy4gV2Ugd2lsbCB1c2UgdGhlIGZyZXF1ZW50bHkgdXNlZCBBTUFTIHdpdGggbmluZSBpdGVtcyBjb250cmlidXRpbmcgdG8gdHdvIHNjYWxlczogTWF0aCBMZWFybmluZyBhbmQgTWF0aCBUZXN0aW5nLiBBTUFTIG9yaWdpbmF0ZXMgZnJvbSBhIHJlYW5hbHlzaXMgb2YgYSBNQVJTLVIgYnkgSG9wa28gZXQgYWwuICgyMDAzKS4gQU1BUyBpcyBzaG9ydCAoY29tcGxldGlvbiB0YWtlcyBhYm91dCA1IG1pbnV0ZXMpIGFuZCBoYXMgZ29vZCBwc3ljaG9tZXRyaWMgcHJvcGVydGllczogaGlnaCByZWxpYWJpbGl0eSBhcyBtZWFzdXJlZCBieSBpbnRlcm5hbCBjb25zaXN0ZW5jeSBhbmQgdGVzdC1yZXRlc3QgbWV0aG9kLCBjb25zdHJ1Y3QgdmFsaWRpdHkgYXMgbWVhc3VyZWQgYnkgZXhwbG9yYXRvcnkgYW5kIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzZXMsIGFuZCBjb252ZXJnZW50IGFuZCBkaXNjcmltaW5hbnQgdmFsaWRpdHkuIChOdW1lcm91cyBzdWJzZXF1ZW50IHN0dWRpZXMgaGF2ZSBjb25maXJtZWQgdGhlc2UgcmVzdWx0cy4pIFdlIHdpbGwgdXNlIEFNQVMgdG8gbWVhc3VyZSBtYXRoIGFueGlldHkgaW4gdGhpcyBwcm9qZWN0Lg0KDQoyLiAgKipNdWx0aS1pdGVtIFN1cnZleSBJbnN0cnVtZW50IGZvciBNYXRoIFNlbGYtZWZmaWNhY3kqKi4gTWF0aCBhbnhpZXR5IGFuZCBtYXRoIHNlbGYtZWZmaWNhY3kgYXJlIG5lZ2F0aXZlbHkgY29ycmVsYXRlZC4gVGhlIHRocmVlLWl0ZW0gc2hvcnQgdmVyc2lvbiBvZiBtYXRoIHNlbGYtZWZmaWNhY3kgcXVlc3Rpb25uYWlyZXM6ICgxKSBJIHVzdWFsbHkgdW5kZXJzdGFuZCBhIG1hdGhlbWF0aWNhbCBpZGVhIHF1aWNrbHk7ICgyKSBJIGhhdmUgdG8gd29yayB2ZXJ5IGhhcmQgdG8gdW5kZXJzdGFuZCBtYXRoZW1hdGljczsgKDMpIEkgY2FuIGNvbm5lY3QgbWF0aGVtYXRpY2FsIGlkZWFzIHRoYXQgSSBoYXZlIGxlYXJuZWQ7IHVzZWQgYnkgUm96Z29uanVrIGV0IGFsLiAoMjAyMCkuDQoNCjMuICAqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIFN0dWRlbnQncyBQZXJjZXB0aW9uIG9uIEZhY3VsdHkgVGVhY2hpbmcgU3RyYXRlZ2llcyoqOiBTdHVkZW50cycgbWF0aGVtYXRpY3MgYW54aWV0eSBpcyBkaXJlY3RseSBpbmZsdWVuY2VkIGJ5IHRoZWlyIGluc3RydWN0b3JzJyB0ZWFjaGluZyBzdHJhdGVnaWVzLiBUaGlzIHN0dWR5IGVtcGxveXMgdGhlIFRlYWNoaW5nIFN0cmF0ZWdpZXMgSW52ZW50b3J5IHVzZWQgYnkgQ2FyZGlubyBKci4gYW5kIE9ydGVnYS1EZWxhIENydXogKDIwMjApIHRvIGFzc2VzcyBzdHVkZW50cycgcGVyY2VwdGlvbnMgb2YgdGhlc2Ugc3RyYXRlZ2llcy4gVGhlIGludmVudG9yeSBjb21wcmlzZXMgZWlnaHQgZGlzdGluY3QgZGltZW5zaW9ucyAoc3Vic2NhbGVzKS4NCg0KNC4gICoqTXVsdGktaXRlbSBTdXJ2ZXkgSW5zdHJ1bWVudCBmb3IgU3R1ZGVudCBMZWFybmluZyBNb2RhbGl0aWVzKio6IEFWSUQgKEFkdmFuY2VtZW50IFZpYSBJbmRpdmlkdWFsIERldGVybWluYXRpb24pIGlzIGEgcHJvZ3JhbSBpbnRyb2R1Y2VkIGJ5IE1lYWRvd2xhcmsgRWxlbWVudGFyeSBTY2hvb2wgdGhhdCBhaW1zIHRvIGNsb3NlIHRoZSBhY2hpZXZlbWVudCBnYXAgYnkgcHJlcGFyaW5nIGFsbCBzdHVkZW50cyBmb3IgY29sbGVnZSByZWFkaW5lc3MgYW5kIHN1Y2Nlc3MgaW4gYSBnbG9iYWwgc29jaWV0eS4gV2UgdXNlZCBBVklEJ3MgU3R1ZGVudCBMZWFybmluZyBNb2RhbGl0eSBJbnZlbnRvcnkgdG8gaWRlbnRpZnkgc3R1ZGVudCBsZWFybmluZyBzdHlsZXMgKGF1ZGl0b3J5LCB2aXN1YWwsIGFuZCBraW5lc3RoZXRpYykgaW4gdGhpcyBzdHVkeS4gVGhlIGludmVudG9yeSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL01hdGhBbnhpZXR5L0FWSURfTGVhcm5pbmdfU3R5bGVfSW52ZW50b3J5LnBkZj4uDQoNCjUuICAqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIFN0dWRlbnQncyBFbmdhZ2VtZW50Kio6IFdlIHNlbGVjdCAxMiBxdWVzdGlvbm5haXJlcyBmcm9tIHRoZSBOU1NFIChOYXRpb25hbCBTdXJ2ZXkgb2YgU3R1ZGVudCBFbmdhZ2VtZW50KSB0byBhc3Nlc3Mgc3R1ZGVudHMgaW4tY2xhc3MgYW5kIGFmdGVyLWNsYXNzIGVuZ2FnZW1lbnQgYW5kIHVzZSBvZiBsZWFybmluZyByZXNvdXJjZXMuIFRoZSBUaGUgY29yZSBOU1NFIHN1cnZleSBmb3IgYSBmaXJzdC15ZWFyIG9yIHNlbmlvciBzdHVkZW50IGNvbnNpc3RzIG9mIGFwcHJveGltYXRlbHkgNDAgdG8gNTAgcmVxdWlyZWQgaXRlbXMsIGJ1dCB0aGUgdG90YWwgYmFuayBvZiBwb3RlbnRpYWwgcXVlc3Rpb25zIGlzIG11Y2ggbGFyZ2VyLiBUaGUgY29tcGxldCBpbnN0cnVtZW50IGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9uc3NlLmluZGlhbmEuZWR1L25zc2Uvc3VydmV5LWluc3RydW1lbnRzL3VzLWVuZ2xpc2guaHRtbD4uDQoNCjYuICAqKlNpbmdsZS1pdGVtIHF1ZXN0aW9ucyoqOiBUaGVzZSBxdWVzdGlvbnMgY2FwdHVyZSBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbi4NCg0KIyBSYXcgRGF0YSBQcm9jZXNzaW5nDQoNCkF0IHRoZSBlbmQgb2YgZGF0YSBjb2xsZWN0aW9uLCB3ZSByZWNlaXZlZCA4OTUgcmVzcG9uc2VzLiBPZiB0aGVzZSwgMTk5IHBhcnRpY2lwYW50cyBkaWQgbm90IGNvbXBsZXRlIHRoZSBtYWluIHN1cnZleSBzdWJzY2FsZXMuIFRoZSBhbmFseXNpcyBpcyBiYXNlZCBvbiB0aGUgcmVtYWluaW5nIDY5NiByZXNwb25zZXMgZm9yIHdoaWNoIHRoZSBtYWluIHN1YnNjYWxlcyB3ZXJlIGNvbXBsZXRlZCwgd2hpY2ggY29udGFpbmVkIG9ubHkgYSBmZXcgbWlzc2luZyB2YWx1ZXMuIFNldmVyYWwgcmVkdW5kYW50IHZhcmlhYmxlcyB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgcmF3IGRhdGEuIEluIGFkZGl0aW9uLCBzb21lIG9yaWdpbmFsIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB3ZXJlIHJlY2F0ZWdvcml6ZWQgdG8gYXZvaWQgc3BhcnNlIGdyb3VwcyBhbmQgaW1wcm92ZSBpbnRlcnByZXRhYmlsaXR5Lg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KV29ya2luZ0RhdGEgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcNzVDUEVOR1xcT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQVxcRGVza3RvcFxcY3BlbmdcXFdDVS1UZWFjaGluZ1xcMjAyNUZhbGxcXE1hdGhBeGlldHlcXFdvcmtpbmdEYXRhU2V0Tm9NaXNzaW5nczAyLmNzdiIpDQpXb3JraW5nRGF0YSRJRCA8LSAxOmRpbShXb3JraW5nRGF0YSlbMV0NCiMgRGVtb2dyYXBoaWNzDQpEZW1vZ3JhcGhpY3MgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTZXgiLCAiR2VuZGVyIiwgIkNsYXNzIiwgIk1ham9yIiwgIkV0aG5pY2l0eSIsICJDb3Vyc2UyIildDQojIE1hdGggQW54aWV0eQ0KQW54aWV0eSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgIkFNQVMuMSIsICJBTUFTLjIiLCAiQU1BUy4zIiwgIkFNQVMuNCIsICJBTUFTLjUiLCAiQU1BUy42IiwgIkFNQVMuNyIsICJBTUFTLjgiLCAiQU1BUy45IildDQojIFNlbGYtZWZmaWNhY3kNClNlbGZFZmZpY2FjeSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJNU0VTLjEiLCAiTVNFUy4yIiwgIk1TRVMuMyIgKV0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyAgIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMgQ29vcGVyYXRpdmUNCkNvb3BvcmF0aXZlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIlMuQ0EuMSIsICJTLkNBLjIiLCAiUy5DQS4zIiwgIlMuQ0EuNCIsICJTLkNBLjUiLCAiUy5DQS42IildDQojIyBMZWN0dXJlIFR5cGUNCkxlY3R1cmVUeXBlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIlMuTFQuMSIsICJTLkxULjIiLCAiUy5MVC4zIiwgICJTLkxULjQiLCAgIlMuTFQuNSIsICJTLkxULjYiLCAiUy5MVC43IildDQojIyBEZWR1Y3RpdmUgQXBwcm9hY2gNCkRlZHVjdGl2ZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJTLkRBLjEiICwgIlMuREEuMiIsICJTLkRBLjMiLCAiUy5EQS40IiwgIlMuREEuNSIsICJTLkRBLjYiLCAiUy5EQS43IildDQojIyBJbmR1Y3RpdmUgQXBwcm9hY2gNCkluZHVjdGl2ZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgIlMuSUEuMSIsICJTLklBLjIiLCAgIlMuSUEuMyIsICAiUy5JQS40IiwgIlMuSUEuNSIsIlMuSUEuNiIsICJTLklBLjciKV0NCiMjIERlbW9uc3RyYXRpb24NCkRlbW9uc3RyYXRpb24gPC1Xb3JraW5nRGF0YVssIGMoIklEIiwgIlMuRC4xIiwgIlMuRC4yIiwgIlMuRC4zIiwgIlMuRC40IiwgIlMuRC41IiwgICJTLkQuNiIsICJTLkQuNyIpXQ0KIyMgUmVwZXRpdGl2ZSBFeGVyY2lzZXMNClJlcGV0aXRpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLlJFLjEiLCAgIlMuUkUuMiIsICJTLlJFLjMiLCAiUy5SRS40IiwgIlMuUkUuNSIsICJTLlJFLjYiLCAiUy5SRS43IildDQojIyBJbnRlZ3JhdGl2ZSBBcHByb2FjaA0KSW50ZWdyYXRpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLklBLjEuMSIsICJTLklBLjIuMSIsICJTLklBLjMuMSIsICJTLklBLjQuMSIsICJTLklBLjUuMSIsICJTLklBLjYuMSIsICJTLklBLjcuMSIpXQ0KIyBVc2luZyBUZWNobm9sb2d5OiBkcm9wIFQxIGFuZCBUNw0KVGVjaG5vbG9neSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgIlQuMiIsICJULjMiLCAiVC40IiwgIlQuNSIsICJULjYiLCAiVC44IiwgIlQuOSIsICJULjEwIiwgIlQuMTEiLCJULjEyIildDQojIExlYXJuaW5nIE1vZGFsaXRpZXMNCk1vZGFsaXR5IDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIk1TLjEiLCAiTVMuMiIsICJNUy4zIiwgIk1TLjQiLCAiTVMuNSIsICJNUy42IiwgIk1TLjciLCAiTVMuOCIsICJNUy45IiwgIk1TLjEwIiwgIk1TLjExIiwgIk1TLjEyIildDQojIEVuZ2FnZW1lbnQ6IGtlZXAgb25seSBmaXJzdCB0aHJlZSBpdGVtcw0KRW5nYWdlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAgIkNSLjEiLCAiQ1IuMiIsICJDUi4zIildDQojIFJlc291cmNlcw0KUmVzb3VyY2UgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJDUi45IiwgIkNSLjEwIiwgIkNSLjExIiwgIkNSLjEyIildDQpgYGANCg0KIyMgTWlzc2luZyBWYWx1ZSBJbXB1dGF0aW9uDQoNClRvIG1haW4gdGhpcyBzYW1wbGUgc2l6ZSwgd2UgdXNlIHJhbmRvbSBpbXB1dGF0aW9uIGFwcHJvYWNoIHRvIGZpbGwgaW4gdGhlIG1pc3NpbmcgdmFsdWVzLiBTaW5jZSBhbGwgbXVsdGktaXRlbSBzdWItc2NhbGVzIHdlcmUgbWVhc3VyZWQgdXNpbmcgYSBMaWtlcnQgc2NhbGUsIHRoZSBzY29yZXMgZm9sbG93cyBhIG11bHRpbm9taWFsIGRpc3RyaWJ1dGlvbi4gVGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gd2lsbCBiZSB1c2VkIGluIHRoZSByYW5kb20gaW1wdXRhdGlvbiB0byBtYWluIHRoZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gb2YgdGhlIG9ic2VydmVkIGRhdGEuIFRoZSBmb2xsb3dpbmcgY29kZSBpbXB1dGVzIHRoZSBtaXNzaW5nIHZhbHVlcyBpbiBhbGwgbXVsdGktaXRlbSBzdWJzY2FsZXMuDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCkltcHV0YXRpb24gPSBmdW5jdGlvbihEYXRhTmFtZSl7DQogIGZvciAoaSBpbiAxOihkaW0oRGF0YU5hbWUpWzJdKSl7DQogICAgdmVjID0gYXMudmVjdG9yKERhdGFOYW1lWywgaV0pDQogICAgbmEuaWQgPSB3aGljaChpcy5uYSh2ZWMpKQ0KICAgIG4wID0gbGVuZ3RoKG5hLmlkKQ0KICAgIHByb2IwID0gdGFibGUodmVjKS9sZW5ndGgodmVjKQ0KICAgIGltcHV0LnZhbCA9IE5VTEwNCiAgICAgIGZvciAoaiBpbiAxOm4wKXsNCiAgICAgIGltcHV0LnZhbFtqXSA9IHNhbXBsZSgxOmxlbmd0aChwcm9iMCksIHNpemUgPSAxLCBwcm9iID0gcHJvYjApDQogICAgfQ0KICAgIERhdGFOYW1lW25hLmlkLCBpXSA9IGltcHV0LnZhbA0KICB9DQogICBEYXRhTmFtZQ0KfQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQpDb21wLkFueGlldHkgPSBJbXB1dGF0aW9uKEFueGlldHkpDQpDb21wLlNlbGZFZmZpY2FjeTAgPSBJbXB1dGF0aW9uKFNlbGZFZmZpY2FjeSkNCiMgcmV2ZXJzZSBjb2RpbmcgaW4gU2VsZi1FZmZpY2FjeQ0KQ29tcC5TZWxmRWZmaWNhY3kgPSBDb21wLlNlbGZFZmZpY2FjeTANCkNvbXAuU2VsZkVmZmljYWN5JE1TRVMuMSA9Ni0gQ29tcC5TZWxmRWZmaWNhY3kwJE1TRVMuMQ0KQ29tcC5TZWxmRWZmaWNhY3kkTVNFUy4zID02LSBDb21wLlNlbGZFZmZpY2FjeTAkTVNFUy4zDQojIw0KQ29tcC5Db29wb3JhdGl2ZSA9IEltcHV0YXRpb24oQ29vcG9yYXRpdmUpDQpDb21wLkxlY3R1cmVUeXBlID0gSW1wdXRhdGlvbihMZWN0dXJlVHlwZSkNCkNvbXAuRGVkdWN0aXZlID0gSW1wdXRhdGlvbihEZWR1Y3RpdmUpDQpDb21wLkluZHVjdGl2ZSA9IEltcHV0YXRpb24oSW5kdWN0aXZlKQ0KQ29tcC5EZW1vbnN0cmF0aW9uID0gSW1wdXRhdGlvbihEZW1vbnN0cmF0aW9uKQ0KQ29tcC5SZXBldGl0aXZlID0gSW1wdXRhdGlvbihSZXBldGl0aXZlKQ0KQ29tcC5JbnRlZ3JhdGl2ZSA9IEltcHV0YXRpb24oSW50ZWdyYXRpdmUpDQojIyByZXZlcnNlIGNvZGluZyBpbiA1IGFuZCA3IGluIFRlY2hub2xvZ3kNCkNvbXAuVGVjaG5vbG9neTAgPSBJbXB1dGF0aW9uKFRlY2hub2xvZ3kpDQpDb21wLlRlY2hub2xvZ3kxID0gQ29tcC5UZWNobm9sb2d5MA0KQ29tcC5UZWNobm9sb2d5MSRULjUgPTYtIENvbXAuVGVjaG5vbG9neTAkVC41DQojIw0KQ29tcC5UZWNobm9sb2d5ID0gNiAtIENvbXAuVGVjaG5vbG9neTENCiMjDQpDb21wLkVuZ2FnZSA9IDUtSW1wdXRhdGlvbihFbmdhZ2UpDQpDb21wLlJlc291cmNlID0gNS1JbXB1dGF0aW9uKFJlc291cmNlKQ0KIyMgTW9kYWxpdHkNCkNvbXAuTW9kYWxpdHkgPSBJbXB1dGF0aW9uKE1vZGFsaXR5KQ0KYGBgDQoNCiMjIFJldmVyc2UgU2NvcmluZw0KDQoqKlJldmVyc2Ugc2NvcmluZyoqIGlzIGEgY3J1Y2lhbCBkYXRhIHByZXBhcmF0aW9uIHN0ZXAgZm9yIG11bHRpLWl0ZW0gc3VydmV5cyB3aGVyZSBzb21lIGl0ZW1zIGFyZSB3b3JkZWQgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiB0byBwcmV2ZW50IHJlc3BvbnNlIGJpYXMuIEFmdGVyIGl0ZW0td2lzZSByZXZpZXcgb2YgYWxsIGluc3RydW1lbnRzIGFsb25nIHdpdGggc3RhdGlzdGljYWwgcHJvY2VkdXJlcyBvZiBjb3JyZWxhdGlvbiBhbmQgY29uZmlybWF0b3J5IGZhY3RvciBhbmFseXNpcyAoQ0ZBKSwgaXRlbSAyIGluIHRoZSAqU2VsZi1lZmZpY2FjeSBJbnN0cnVtZW50KiBhbmQgKiphbGwgcXVlc3Rpb25zKiogZXhjZXB0IGl0ZW1zIDUgYW5kIDcgaW4gdGhlICpUZWNobm9sb2d5IEluc3RydW1lbnQqIHdlcmUgbmVnYXRpdmVseSB3b3JkZWQuIFRoZSBzY29yZXMgb2YgdGhlc2UgaXRlbXMgd2VyZSByZXZlcnNlZC4NCg0KSW4gYWRkaXRpb24sIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIGVuZ2FnZW1lbnQgYW5kIHJlc291cmNlIHVzZSB3ZXJlIHJldmVyc2Utd29yZGVkLCBzbyB0aGVpciBzY29yZXMgd2VyZSByZXZlcnNlZCBmb3IgdGhlIHN1YnNlcXVlbnQgYW5hbHlzaXMuDQoNCiMjIFNwYXJzZSBDYXRlZ29yeSBSZWdyb3VwaW5nDQoNClR3byB2YXJpYWJsZXMgbmVlZCB0byBiZSByZWdyb3VwZWQgaW4gdGhlIGZvbGxvd2luZzogY291cnNlIGxldmVsIGFuZCBldGhuaWNpdHkuDQoNCi0gICAqKk1hdGhDb3Vyc2VMZXZlbCoqDQogICAgLSAgICpNYXRoLkkqOiBNQVRRMzAsIE1BVDEwMCwgTUFUMTAxLCBNQVQxMDIsDQogICAgLSAgICpNYXRoLklJKjogTUFUMTkzLCBNQVQxMDQsIE1BVDExMiwgTUFUMTEzLCBNQVQxMTUsIE1BVDEzMQ0KICAgIC0gICAqTWF0aC5JSUkqOiBNQVQxNDMsIE1BVDE0NSwgTUFUMTUxLCBNQVQxNjENCiAgICAtICAgKk1hdGguSVYqOiBNQVQxNjItTUFUNDgwDQogICAgLSAgICpTdGF0cyo6IE1BVDEyMSwgTUFUMTI1LCBTVEEyMDANCiAgICAtICAgKk90aGVyKjogQWxsIGNvdXJzZXMgbm90IGxpc3RlZCBhYm92ZQ0KLSAgICoqRXRobmljaXR5KioNCiAgICAtICAgKldoaXRlKg0KICAgIC0gICAqQmxhY2sqOiBCbGFjayBhbmQgQWZyaWNhbiBBbWVyaWNhbg0KICAgIC0gICAqQXNpYW4qDQogICAgLSAgICpPdGhlcio6IE5hdGl2ZSBIYXdhaWlhbiBvciBQYWNpZmljIElzbGFuZGVyLCBNdWx0aXBsZSBFdGhuaWNpdHkgb3IgT3RoZXIsIFByZWZlciBOb3QgVG8gQW5zd2VyDQotICAgKipMZWFybmluZyBNb2RhbGl0aWVzKioNCg0KYGBge3J9DQpkZl93aXRoX2ZyZXEgPC0gQ29tcC5Nb2RhbGl0eSAlPiUNCiAgcm93d2lzZSgpICU+JQ0KICBtdXRhdGUoDQogICAgZnJlcV9BID0gc3VtKGNfYWNyb3NzKE1TLjE6TVMuMTIpID09ICIxIiksDQogICAgZnJlcV9CID0gc3VtKGNfYWNyb3NzKE1TLjE6TVMuMTIpID09ICIyIiksDQogICAgZnJlcV9DID0gc3VtKGNfYWNyb3NzKE1TLjE6TVMuMTIpID09ICIzIikNCiAgKSAlPiUNCiAgdW5ncm91cCgpDQojIyMNCmRmX3dpdGhfZnJlcSRtYXhfZnJlcV9jb2wgPC0gbmFtZXMoZGZfd2l0aF9mcmVxKVttYXguY29sKGRmX3dpdGhfZnJlcVssIGMoImZyZXFfQSIsICJmcmVxX0IiLCAiZnJlcV9DIildKSArIDFdDQpkZl93aXRoX2ZyZXEkbWF4X2ZyZXFfdmFsdWUgPC0gYXBwbHkoZGZfd2l0aF9mcmVxWywgYygiZnJlcV9BIiwgImZyZXFfQiIsICJmcmVxX0MiKV0sIDEsIG1heCkNCmRmX3dpdGhfZnJlcSRtb2RhbGl0eSA8LSBpZmVsc2UoZGZfd2l0aF9mcmVxJG1heF9mcmVxX2NvbD09Ik1TLjEiLCAiQXVkaXRvcnkiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRmX3dpdGhfZnJlcSRtYXhfZnJlcV9jb2w9PSJNUy4yIiwgIlZpc3VhbCIsICJLaW5lc3RoZXRpYyIpKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQpEZW1vZ3JhcGhpY3MkbWF0aC5sZXZlbCA9IGlmZWxzZShEZW1vZ3JhcGhpY3MkQ291cnNlMiAlaW4lIGMoMSwgMiwgMywgNCksICJtYXRoMDEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ291cnNlMiAlaW4lIGMoNSwgNiwgNywgOCwgOSwgMTIpLCAibWF0aDAyIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYygxMywgMTQsIDE1LCAxNiksICJtYXRoMDMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYygxMCwgMTEsIDM2LCAzNywgMzgsIDM5LCA0MCwgNDEsIDQyKSwgInN0YXRzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ291cnNlMiAlaW4lIGMoNDMsIDQ0KSwgIm90aGVyIiwgIm1hdGgwNCIpKSkpKSANCkRlbW9ncmFwaGljcyRyYWNlID0gaWZlbHNlKERlbW9ncmFwaGljcyRFdGhuaWNpdHkgPT0gMSwgIndoaXRlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJEV0aG5pY2l0eSA9PSAyLCAiQmxhY2siLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJEV0aG5pY2l0eSA9PSA0LCAiQXNpYW4iLCAib3RoZXIiKSkpDQpEZW1vZ3JhcGhpY3Mkc2V4ID0gaWZlbHNlKERlbW9ncmFwaGljcyRTZXggPT0gMSwgImZlbWFsZSIsICJtYWxlIikNCkRlbW9ncmFwaGljcyRtYWpvciA9IGlmZWxzZShEZW1vZ3JhcGhpY3MkTWFqb3IgPT0gMSwgIlNURU0iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJE1ham9yID09IDIsICJCdXNpbmVzcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkTWFqb3IgPT0gMywgIkhlYWx0aCIsICJPdGhlciIpKSkNCkRlbW9ncmFwaGljcyRjbGFzcyA9IGlmZWxzZShEZW1vZ3JhcGhpY3MkQ2xhc3MgPT0gMSwgInlyMSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ2xhc3MgPT0gMiwgInlyMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkQ2xhc3MgPT0gMywgInlyMyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRNYWpvciA9PSA0LCAieXI0IiwgInlyNSsiKSkpKQ0KRGVtb2dyYXBoaWNzJG1vZGFsaXR5IDwtIGRmX3dpdGhfZnJlcSRtb2RhbGl0eQ0KDQpkZW1vZ3JhcGhpY3MgPSBEZW1vZ3JhcGhpY3NbLCBjKCJJRCIsICJzZXgiLCAicmFjZSIsICJjbGFzcyIsICJtYWpvciIsICJtYXRoLmxldmVsIiwgIm1vZGFsaXR5IildDQpgYGANCg0KIyMgRXhwbG9yYXRvcnkgRmFjdG9yIEFuYWx5c2lzIChFRkEpIG9uIEFueGlldHkNCg0KVGhlIGFiYnJldmlhdGVkIG1hdGhlbWF0aWNhbCBhbnhpZXR5IChNQSkgaW5zdHJ1bWVudCBkZXZlbG9wZWQgYnkgSG9wa28gZXQgYWwuICgyMDAzKSBpcyBjaGFyYWN0ZXJpemVkIGJ5IGEgdHdvLWZhY3RvciBzdHJ1Y3R1cmUgdGhhdCBkaXZpZGVzIGludG8gdHdvIHN1YnNjYWxlczogbWF0aGVtYXRpY3MgZXZhbHVhdGlvbiBhbnhpZXR5IChNRUEpIGFuZCBtYXRoZW1hdGljcyBsZWFybmluZyBhbnhpZXR5IChNTEEpLiBUaGUgc3Vic2VxdWVudCBleHBsb3JhdG9yeSBmYWN0b3IgYW5hbHlzaXMgc2VydmVzIHRvIHZhbGlkYXRlIHRoaXMgY29uc3RydWN0Lg0KDQpgYGB7ciByZXN1bHRzID0gRkFMU0V9DQojIENoZWNrIGNvcnJlbGF0aW9ucyAodmlzdWFsbHkpDQpuID0gZGltKENvbXAuQW54aWV0eVssLTFdKVsxXQ0KY29yX21hdHJpeCA8LSBjb3IoQ29tcC5BbnhpZXR5WywtMV0pDQojY29yUGxvdChjb3JfbWF0cml4LCB1cHBlciA9IEZBTFNFKQ0KIyBCYXJ0bGV0dCdzIFRlc3Qgb2YgU3BoZXJpY2l0eSAod2Ugd2FudCBhIHNpZ25pZmljYW50IHAtdmFsdWUsIHAgPCAuMDUpDQpjb3J0ZXN0LmJhcnRsZXR0KGNvcl9tYXRyaXgsIG4gPSBuKQ0KDQojIEtNTyBNZWFzdXJlIG9mIFNhbXBsaW5nIEFkZXF1YWN5IChNU0EpIChXZSB3YW50IG92ZXJhbGwgTVNBID4gMC42LCBpZGVhbGx5ID4gMC44KQ0KS01PKGNvcl9tYXRyaXgpDQpgYGANCg0KQmFydGxldHQncyB0ZXN0IG9mIHNwaGVyaWNpdHkgcHJvZHVjZWQgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlc3VsdCAocCBcPCAuMDAxKSwgY29uZmlybWluZyB0aGF0IHRoZSB2YXJpYWJsZXMgYXJlIHN1ZmZpY2llbnRseSBjb3JyZWxhdGVkIHRvIHByb2NlZWQgd2l0aCBmYWN0b3IgYW5hbHlzaXMuIFRoZSBLYWlzZXItTWV5ZXItT2xraW4gKEtNTykgTWVhc3VyZSBvZiBTYW1wbGluZyBBZGVxdWFjeSwgd2l0aCBib3RoIG92ZXJhbGwgYW5kIGl0ZW0tbGV2ZWwgdmFsdWVzIGV4Y2VlZGluZyAwLjgwLCBpbmRpY2F0ZXMgdGhhdCB0aGUgZGF0YSBjb250YWluIGFkZXF1YXRlIGNvbW1vbiB2YXJpYW5jZSB0byB3YXJyYW50IGZhY3RvciBhbmFseXNpcy4gRnVydGhlcm1vcmUsIHRoZSBzY3JlZSBwbG90IGNsZWFybHkgZGVtb25zdHJhdGVzIHRoZSBhbnRpY2lwYXRlZCB0d28tZmFjdG9yIHN0cnVjdHVyZSBvZiB0aGUgY29uc3RydWN0Lg0KDQpgYGB7cn0NCg0KIyBHZXQgZWlnZW52YWx1ZXMNCmZhX3Jlc3VsdCA8LSBmYShDb21wLkFueGlldHlbLC0xXSwgbmZhY3RvcnMgPSBuY29sKENvbXAuQW54aWV0eVssLTFdKSwgcm90YXRlID0gIm5vbmUiKQ0KZWlnZW52YWx1ZXMgPC0gZmFfcmVzdWx0JGUudmFsdWVzDQoNCiMgU2NyZWUgcGxvdCB3aXRoIGhvcml6b250YWwgbGluZSB1c2luZyBzaGFwZXMNCnNjcmVlX3Bsb3QgPC0gcGxvdF9seSh4ID0gMTpsZW5ndGgoZWlnZW52YWx1ZXMpLCB5ID0gZWlnZW52YWx1ZXMsDQogICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcyttYXJrZXJzJywNCiAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdCh3aWR0aCA9IDMpLA0KICAgICAgICAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDgpKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gIlNjcmVlIFBsb3Qgd2l0aCBLYWlzZXIgQ3JpdGVyaW9uIChFaWdlbnZhbHVlKSIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkZhY3RvciBOdW1iZXIiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRWlnZW52YWx1ZSIpLA0KICAgIHNoYXBlcyA9IGxpc3QoDQogICAgICBsaXN0KA0KICAgICAgICB0eXBlID0gImxpbmUiLA0KICAgICAgICB4MCA9IDAsDQogICAgICAgIHgxID0gbGVuZ3RoKGVpZ2VudmFsdWVzKSwNCiAgICAgICAgeTAgPSAxLA0KICAgICAgICB5MSA9IDEsDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gInJlZCIsIHdpZHRoID0gMiwgZGFzaCA9ICJkYXNoIikNCiAgICAgICkNCiAgICApLA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoDQogICAgICAgIHggPSBsZW5ndGgoZWlnZW52YWx1ZXMpICogMC44LA0KICAgICAgICB5ID0gMS4xLA0KICAgICAgICB0ZXh0ID0gIkthaXNlciBDcml0ZXJpb24gKM67ID0gMSkiLA0KICAgICAgICBzaG93YXJyb3cgPSBGQUxTRSwNCiAgICAgICAgZm9udCA9IGxpc3QoY29sb3IgPSAicmVkIikNCiAgICAgICkNCiAgICApLA0KICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgKQ0KDQpzY3JlZV9wbG90DQpgYGANCg0KTmV4dCwgd2UgcGVyZm9ybSBFRkEgdG8gaWRlbnRpZnkgdGhlIGl0ZW1zIG9mIE1FQSBhbmQgTUxBIHRocm91Z2ggZmFjdG9yIGxvYWRpbmdzLg0KDQpgYGB7cn0NCiMjIHR3by1mYWN0b3IgYUVGQQ0KZWZhXzJmYWN0b3IgPC0gZmEoQ29tcC5BbnhpZXR5WywtMV0sIG5mYWN0b3JzID0gMiwgcm90YXRlID0gIm9ibGltaW4iLCANCiAgICAgICAgICAgICAgICAgIGZtID0gInBhIiwgc2NvcmVzID0gInJlZ3Jlc3Npb24iKQ0KIyBDcmVhdGUgYSBjbGVhbiBsb2FkaW5ncyB0YWJsZQ0KbG9hZGluZ3NfdGFibGUgPC0gZmEuc29ydChlZmFfMmZhY3RvciRsb2FkaW5nc1tdKQ0KcGFuZGVyKGxvYWRpbmdzX3RhYmxlLCBkaWdpdHMgPSAyLCBjdXRvZmYgPSAwLjMpDQpgYGANCg0KQXMgc2hvd24gaW4gdGhlIHRhYmxlIGFib3ZlLCBpdGVtcyAyLCA0LCA1LCBhbmQgOCBsb2FkIG9udG8gdGhlIGV2YWx1YXRpb24gYW54aWV0eSBmYWN0b3IsIHdoZXJlYXMgdGhlIHJlbWFpbmluZyBpdGVtcyBsb2FkIG9udG8gdGhlIGxlYXJuaW5nIGFueGlldHkgZmFjdG9yLiBUd28gZGlzdGluY3Qgc3Vic2NhbGVzIHdpbGwgYmUgZXN0YWJsaXNoZWQgZm9yIHN1YnNlcXVlbnQgYW5hbHlzZXMuDQoNCmBgYHtyfQ0KQW54aWV0eS5tZWEgPC0gQ29tcC5BbnhpZXR5WywgYygiSUQiLCAgIkFNQVMuMiIsICJBTUFTLjQiLCAiQU1BUy41IiwgICJBTUFTLjgiKV0NCkFueGlldHkubWxhIDwtIENvbXAuQW54aWV0eVssIGMoIklEIiwgIkFNQVMuMSIsICJBTUFTLjMiLCAiQU1BUy42IiwgIkFNQVMuNyIsICJBTUFTLjkiKV0NCmBgYA0KDQojIFZhbGlkYXRpb24gYW5kIFJlbGlhYmlsaXR5DQoNClRoZSBtYWpvciBtdWx0aS1pdGVtIGluc3RydW1lbnRzIHVzZWQgaW4gdGhpcyBzdHVkeSBhcmUgd2VsbC1lc3RhYmxpc2hlZCBhbmQgaGF2ZSBiZWVuIHVzZWQgaW4gdmFyaW91cyBwdWJsaXNoZWQgcmVzZWFyY2guIEluIHByYWN0aWNlLCB0aGUgdmFsaWRpdHkgYW5kIHJlbGlhYmlsaXR5IG9mIHN1Y2ggZXN0YWJsaXNoZWQgaW5zdHJ1bWVudHMgbXVzdCBiZSBjb25maXJtZWQgYmVmb3JlIGFueSBzdGF0aXN0aWNhbCBhbmFseXNpcy4gV2UgbmV4dCBwZXJmb3JtIHJlbGlhYmlsaXR5IGFuZCB2YWxpZGl0eSBhbmFseXNlcyB0byB3YXJyYW50IHRoZSBjcmVkaWJpbGl0eSBvZiB0aGUgb3ZlcmFsbCBzdXJ2ZXkgZGVzaWduIGFuZCB0aGUgcXVhbGl0eSBvZiB0aGUgY29sbGVjdGVkIGRhdGEuDQoNCiMjIFZhbGlkaXR5IEFuYWx5c2lzDQoNCioqVmFsaWRpdHkqKiBvZiBhIG11bHRpLWl0ZW0gc3VydmV5IGluc3RydW1lbnQgYW5zd2VycyB0aGUgcXVlc3Rpb246ICJBbSBJIGFjdHVhbGx5IG1lYXN1cmluZyB3aGF0IEkgaW50ZW5kIHRvIG1lYXN1cmU/IiBJdCdzIGFib3V0IHRoZSBzb3VuZG5lc3Mgb2YgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBzY29yZXMuIEluIHBzeWNob21ldHJpY3MsICoqdmFsaWRpdHkqKiByZWZlcnMgdG8gdGhlIGRlZ3JlZSB0byB3aGljaCBhIHNjYWxlIG1lYXN1cmVzIHdoYXQgaXQgY2xhaW1zIHRvIG1lYXN1cmUuIEZvciBhIHNpbmdsZS1mYWN0b3IgaW5zdHJ1bWVudCwgdGhpcyBtZWFucyBhbGwgaXRlbXMgYXJlIGluZGljYXRvcnMgb2Ygb25lIHVuZGVybHlpbmcgY29uc3RydWN0IHN1Y2ggYXMgbWF0aHMgYW54aWV0eSwgc2VsZi1lZmZpY2FjeSwgZW5nYWdlbWVudCwgZXRjLiBpbiB0aGlzIGNvbXByZWhlbnNpdmUgc3VydmV5LiBUaGUgQ0ZBIGhhcyBiZWVuIHVzZWQgaW4gc3VydmV5IHJlc2VhcmNoIHdpZGVseSwgc2VlIFdhdHNvbiwgZXQgYWwgKDE5ODgpIGFuZCBNYXJzaCAoMTk5NikuDQoNCioqQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKSoqIGlzIGEgcG93ZXJmdWwgc3RhdGlzdGljYWwgdGVjaG5pcXVlIHVzZWQgdG8gdGVzdCBhIHByZS1zcGVjaWZpZWQgdGhlb3J5IGFib3V0IHRoZSBzdHJ1Y3R1cmUgb2YgeW91ciBpbnN0cnVtZW50LiBXZSB1c2UgQ0ZBIHRvIGNvbmZpcm0gdGhhdCB5b3VyIGh5cG90aGVzaXplZCBzaW5nbGUtZmFjdG9yIG1vZGVsIGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgb2JzZXJ2ZWQgZGF0YS4gSXQgcHJvdmlkZXMgcmlnb3JvdXMgZXZpZGVuY2UgZm9yIGNvbnN0cnVjdCB2YWxpZGl0eSBpbiBhIGxpc3Qgb2YgY29udmVudGlvbmFsIG1lYXN1cmVzOg0KDQotICAgKipGYWN0b3IgTG9hZGluZ3MqKiBhcmUgdGhlIHN0YW5kYXJkaXplZCB3ZWlnaHRzIGZyb20gdGhlIENvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkuIFRoZSBzdWdnZXN0ZWQgZ3VpZGVsaW5lcyBhcmU6DQoNCiAgICAtICAgQSBsb2FkaW5nICoqbWFnbml0dWRlIGdyZWF0ZXIgdGhhbiAwLjUqKiBpbmRpY2F0ZXMgdGhhdCB0aGUgaXRlbSBzaGFyZXMgYXQgbGVhc3QgMjUlIG9mIGl0cyB2YXJpYW5jZSB3aXRoIHRoZSBsYXRlbnQgZmFjdG9yLiBJbiB0aGUgZm9sbG93aW5nIHRhYmxlLCB3ZSByZXBvcnQgdGhlIG1pbmltdW0gbG9hZGluZyBmb3IgZWFjaCBpbnN0cnVtZW50IHVuZGVyIHRoZSBjb2x1bW4gYHN0ZC5hbGwubWluYC4NCiAgICAtICAgQWxsIGxvYWRpbmdzIG11c3QgYmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAocCBcPCAwLjA1KS4gV2UgcmVwb3J0IHRoZSBtYXhpbXVtIHAtdmFsdWUgZm9yIGVhY2ggaW5zdHJ1bWVudCB1bmRlciB0aGUgY29sdW1uIGBwdmFsLm1heGAuDQoNCi0gICAqKlN0YW5kYXJkaXplZCBSb290IE1lYW4gU3F1YXJlIFJlc2lkdWFsIChTUk1SKSoqIG1lYXN1cmVzIHRoZSBnb29kbmVzcy1vZi1maXQgb2YgdGhlIENGQSBtb2RlbC4gSXQgcmVwcmVzZW50cyB0aGUgYXZlcmFnZSBzdGFuZGFyZGl6ZWQgcmVzaWR1YWwgYmV0d2VlbiB0aGUgb2JzZXJ2ZWQgYW5kIHByZWRpY3RlZCBjb3JyZWxhdGlvbiBtYXRyaWNlcy4gQSBsb3dlciB2YWx1ZSBpbmRpY2F0ZXMgYSBiZXR0ZXIgZml0LCB3aXRoIGEgc3VnZ2VzdGVkIGN1dG9mZiBvZiAqKmxlc3MgdGhhbiAwLjA4KiouDQoNCi0gICAqKkNvbXBhcmF0aXZlIEZpdCBJbmRleCAoQ0ZJKSoqIGlzIGFub3RoZXIgZ29vZG5lc3Mtb2YtZml0IG1lYXN1cmUgZm9yIHRoZSBDRkEuIEl0IGNvbXBhcmVzIHRoZSBzcGVjaWZpZWQgbW9kZWwgdG8gYSBudWxsIChpbmRlcGVuZGVuY2UpIG1vZGVsLiBBIGhpZ2hlciB2YWx1ZSBpbmRpY2F0ZXMgYSBiZXR0ZXIgZml0LCB3aXRoIGEgc3VnZ2VzdGVkIGN1dG9mZiBvZiAqKmdyZWF0ZXIgdGhhbiAwLjkqKi4NCg0KLSAgICoqVHVja2VyLUxld2lzIEluZGV4IChUTEkpKiogYWxzbyBtZWFzdXJlcyB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIHRoZSBDRkEuIEl0cyBpbnRlcnByZXRhdGlvbiBhbmQgdXNhZ2UgYXJlIHNpbWlsYXIgdG8gdGhvc2Ugb2YgdGhlIENGSS4NCg0KQWZ0ZXIgc29tZSBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgZHJvcHBlZCBhIGZldyBpdGVtcyBmcm9tIHRoZSBUZWNobm9sb2d5IEluc3RydW1lbnQgYW5kIGRlZmluZWQgdHdvIHN1Y3NjYWxlcyBvZiB0aGUgaW5pdGlhbCByZXNvdXJjZSBpbnN0cnVtZW50czogKip1c2Ugb2YgcmVzb3VyY2UqKiBhbmQgKipzdHVkZW50IGVuZ2FnZW1lbnQqKi4NCg0KVGhlIGZpbmFsIHJlc3VsdHMgb24gdGhlIHN0cnVjdCB2YWxpZGl0eSBtZWFzdXJlcyBhcmUgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQpjZmEuYW5hbHlzaXMgPC0gZnVuY3Rpb24oZGF0YXNldCl7DQogICNkYXRhc2V0IDwtIENvbXAuQW54aWV0eQ0KICBwcmVkaWN0b3JzIDwtIG5hbWVzKGRhdGFzZXRbLCAtMV0pICANCiAgbjAgPC0gbGVuZ3RoKHByZWRpY3RvcnMpDQogIGNmYS5tb2RlbCA8LSAgcGFzdGUoImxhdGVudCA9fiIsIHBhc3RlKHByZWRpY3RvcnMsIGNvbGxhcHNlID0gIiArICIpKQ0KICBjZmEuZml0IDwtIGNmYShjZmEubW9kZWwsIGRhdGEgPSBkYXRhc2V0WywgLTFdLCBlc3RpbWF0b3IgPSAiTUxNIikNCiAgcmVzdWx0cyA8LSBzdW1tYXJ5KGNmYS5maXQsIHN0YW5kYXJkaXplZCA9IFRSVUUsIGZpdC5tZWFzdXJlcyA9IFRSVUUsIHJzcXVhcmUgPSBUUlVFKQ0KICBzdGQuYWxsLm1pbiA8LSBtaW4ocmVzdWx0cyRwZSRzdGQubHZbMTpuMF0pDQogIHB2YWwubWF4IDwtIG1heChyZXN1bHRzJHBlJHB2YWx1ZVsyOm4wXSkNCiAgc3JtciA8LSByZXN1bHRzJGZpdFsic3JtciJdDQogIGNmaSA8LSByZXN1bHRzJGZpdFsiY2ZpIl0NCiAgdGxpIDwtIHJlc3VsdHMkZml0WyJ0bGkiXQ0KICAjcm1zZWEgPC0gcmVzdWx0cyRmaXRbInJtc2VhIl0NCiAgY2JpbmQoc3RkLmFsbC5taW4gPSBzdGQuYWxsLm1pbiwgcHZhbC5tYXggPSBwdmFsLm1heCwgc3JtciA9IHNybXIsIGNmaSA9IGNmaSwgIHRsaSA9IHRsaSkNCn0NCmBgYA0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCmFueGlldHkubWVhLnZsaWQgPC1jZmEuYW5hbHlzaXMoQW54aWV0eS5tZWEpDQphbnhpZXR5Lm1sYS52bGlkIDwtY2ZhLmFuYWx5c2lzKEFueGlldHkubWxhKQ0KYW54aWV0eS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuQW54aWV0eSkNCmVmZmljYWN5LnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5TZWxmRWZmaWNhY3kpDQp0ZWNoLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5UZWNobm9sb2d5KQ0KY29vcGVyYXRpdmUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkNvb3BvcmF0aXZlKQ0KZGVkdWN0aXZlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5EZWR1Y3RpdmUpDQpkZW1vLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5EZW1vbnN0cmF0aW9uKQ0KaW5kdWN0aXZlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5JbmR1Y3RpdmUpDQppbnRlZ3JhdGUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkludGVncmF0aXZlKQ0KbGVjdHVyZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuTGVjdHVyZVR5cGUpDQpyZXBldGl2ZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuUmVwZXRpdGl2ZSkNCmVuZ2FnZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuRW5nYWdlKQ0KcmVzb3VyY2UudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLlJlc291cmNlKQ0KIyMNCnZsaWQudGFibGUgPC1yYmluZChhbnhpZXR5Lm1lYSA9IGFueGlldHkubWVhLnZsaWQsIGFueGlldHkubWxhID0gYW54aWV0eS5tbGEudmxpZCwgDQogICAgICAgICAgICAgICAgICBhbnhpZXR5ID0gYW54aWV0eS52bGlkLCBzZWxmLmVmZmljYWN5ID0gZWZmaWNhY3kudmxpZCwNCiAgICAgICAgICAgICAgICAgIHRlY2hub2xvZ3kgPSB0ZWNoLnZsaWQsIGNvb3BlcmF0aXZlID0gY29vcGVyYXRpdmUudmxpZCwNCiAgICAgICAgICAgICAgICAgIGRlZHVjdGl2ZSA9IGRlZHVjdGl2ZS52bGlkLCBkZW1vbnN0cmF0aW9uID0gZGVtby52bGlkLA0KICAgICAgICAgICAgICAgICAgaW5kdWN0aXZlID0gaW5kdWN0aXZlLnZsaWQsIGludGVncmF0ZSA9IGludGVncmF0ZS52bGlkLA0KICAgICAgICAgICAgICAgICAgbGVjdHVyZSA9IGxlY3R1cmUudmxpZCwgcmVwZXRpdGl2ZSA9IHJlcGV0aXZlLnZsaWQsIA0KICAgICAgICAgICAgICAgICAgZW5nYWdlID0gZW5nYWdlLnZsaWQsIHJlc291cmNlID0gcmVzb3VyY2UudmxpZCkNCnJvdy5uYW1lIDwtIGMoImFueGlldHkubWVhIiwgImFueGlldHkubWxhIiwgImFueGlldHkiLCAic2VsZi5lZmZpY2FjeSIsIA0KICAgICAgICAgICAgICAidGVjaG5vbG9neSIsICJjb29wZXJhdGl2ZSIsDQogICAgICAgICAgICAgICJkZWR1Y3RpdmUiLCAiZGVtb25zdHJhdGlvbiIsICJpbmR1Y3RpdmUiLCAiaW50ZWdyYXRlIiwNCiAgICAgICAgICAgICAgImxlY3R1cmUiLCAicmVwZXRpdGl2ZSIsICJlbmdhZ2UiLCAicmVzb3VyY2UiKQ0KY29sLm5hbWUgPC0gYygic3RkLmFsbC5taW4iLCAicHZhbC5tYXgiLCAic3JtciIsICJjZmkiLCAgInRsaSIpDQpyb3duYW1lcyh2bGlkLnRhYmxlKSA8LSByb3cubmFtZQ0KY29sbmFtZXModmxpZC50YWJsZSkgPC0gY29sLm5hbWUNCnBhbmRlcih2bGlkLnRhYmxlKQ0KYGBgDQoNClRoZSBjb25zdHJ1Y3QgdmFsaWRpdHkgb2YgYWxsIG11bHRpLWl0ZW0gaW5zdHJ1bWVudHMgd2FzIGFzc2Vzc2VkIHVzaW5nIENvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGSSkuIFRoZSByZXN1bHRzIGNvbmZpcm1lZCB0aGF0IG1vc3Qgc2NhbGVzIG1lZXQgZXN0YWJsaXNoZWQgcHN5Y2hvbWV0cmljIHN0YW5kYXJkcy4gVGhlIG1vanByaXR5IG9mIHRoZSBrZXkgZml0IGluZGljZXMsIGluY2x1ZGluZyBDRkkgYW5kIFRMSSwgZXhjZWVkZWQgdGhlIHJlY29tbWVuZGVkIHRocmVzaG9sZCBvZiAwLjkwLCB3aGlsZSB0aGUgU1JNUiBmZWxsIGJlbG93IHRoZSAwLjA4IGN1dG9mZiwgaW5kaWNhdGluZyBhIGdvb2QgbW9kZWwgZml0LiBGdXJ0aGVybW9yZSwgYWxsIGZhY3RvciBsb2FkaW5ncyB3ZXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHAgXDwgLjA1KSBhbmQgc3Vic3RhbnRpYWwgaW4gbWFnbml0dWRlIChleGNlZWRpbmcgMC40KSwgZGVtb25zdHJhdGluZyBzdHJvbmcgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBpdGVtcyBhbmQgdGhlaXIgaW50ZW5kZWQgbGF0ZW50IGNvbnN0cnVjdHMuIEluIHN1bW1hcnksIHRoZSB2YWxpZGl0eSBhbmFseXNpcyBjb25maXJtcyB0aGF0IHRoZSBpbnN0cnVtZW50cyB1c2VkIGluIHRoaXMgc3R1ZHkgYXJlIHJvYnVzdCBhbmQgYXBwcm9wcmlhdGUgZm9yIG1lYXN1cmluZyB0aGVpciByZXNwZWN0aXZlIGNvbmNlcHRzLg0KDQoqKlJlbWFya3MqKjogKDEpLiBUaGUgYWJvdmUgdmFsaWRpdHkgbWVhc3VyZXMgYmFzZWQgb24gdGhlIGl0ZW1zIGZvbGxvdyBtdWx0aS12YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24sIFRoaXMgaXMgYSBzdHJvbmcgYXNzdW1wdGlvbi4gVGhlIGl0ZW1zIGluIGVhY2ggaW5zdHJ1bWVudCBhcmUgbm90IGNvbnRpbm91cy4gVGhpcyBpbmZsdWVuY2VzIHNvbWUgb2YgdGhlIHZhbGlkaXR5IG1lYXN1cmUuICgyKS4gSW4gcHJhY3RpY2UsIHdlIGNhbiB1c2Ugc29tZSBkZXNjcmlwdGl2ZSBhcHByb2FjaGVzIHRvIHZpc3VhbCBjaGVjayB3aXRoIGFzc3VtaW5nIG11bHRpLXZhcmlhdGUgbm9ybWFsaXR5Lg0KDQojIyBSZWxpYW5iaWxpdHkgQW5hbHlzaXMNCg0KKipSZWxpYWJpbGl0eSoqIG9mIGEgbXVsdGktaXRlbSBzdXJ2ZXkgaW5zdHJ1bWVudCBhbnN3ZXJzIHRoZSBxdWVzdGlvbjogIklmIEkgbWVhc3VyZSB0aGUgc2FtZSB0aGluZyBtdWx0aXBsZSB0aW1lcywgd2lsbCBJIGdldCBhIGNvbnNpc3RlbnQgcmVzdWx0PyIgSXQgbWVhc3VyZXMgaG93IHdlbGwgdGhlIGl0ZW1zIHRoYXQgYXJlIHN1cHBvc2VkIHRvIG1lYXN1cmUgdGhlIHNhbWUgY29uc3RydWN0IGhhbmcgdG9nZXRoZXIuDQoNCioqSW50ZXJuYWwgQ29uc2lzdGVuY3kqKiBpcyB0aGUgbW9zdCBjb21tb24gYXNzZXNzbWVudCBmb3IgYSBzdXJ2ZXkgYWRtaW5pc3RlcmVkIG9uY2UuIEl0IG1lYXN1cmVzIHRoZSBkZWdyZWUgdG8gd2hpY2ggaXRlbXMgaW4gYSBzY2FsZSBhcmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIuIFR3byB3ZWxsLWtub3duIGludGVybmFsIGNvbnNpc3RlbmN5IG1lYXN1cmVzIGFyZSBDcm9uYmFjaCdzIEFscGhhIChDcm9uYWJjaywgMTk1MSkgYW5kIE1jRG9uYWxkJ3MgT21lZ2EgKDE5OTkpLiAqKk1jRG9uYWxkJ3MgT21lZ2EqKiBpcyBtb3JlIHJvYnVzdCB0aGFuICoqQ3JvbmJhY2gncyBBbHBoYSoqLg0KDQoqKkNyb25iYWNoJ3MgQWxwaGEqKiBhbmQgKipNY0RvbmFsZCdzIE9tZWdhKiogdHlwaWNhbGx5IHJhbmdlIGZyb20gMCB0byAxLiBUaGUgc3VnZ2VzdGVkIGN1dC1vZmZzIGFyZSBnaXZlbiBiZWxvdy4NCg0KLSAgIGA+IDAuOWA6IEV4Y2VsbGVudA0KDQotICAgYDAuOCAtIDAuOWA6IEdvb2QNCg0KLSAgIGAwLjcgLSAwLjhgOiBBY2NlcHRhYmxlDQoNCi0gICBgPCAwLjdgOiBQb29yIChtYXkgaGF2ZSBpdGVtcyB0aGF0IGRvbid0ICJiZWxvbmciKQ0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KUmVsaWFiaWxpdHkuZnVuID0gZnVuY3Rpb24oZGF0YWZyYW1lKXsNCiAgb21lZ2EgPC0gcHN5Y2g6Om9tZWdhKGRhdGFmcmFtZVssIC0xXSwgbmZhY3RvcnMgPSAxLCBwbG90ID0gRkFMU0UpDQogIHJlbGlhYiA8LWNiaW5kKG9tZWdhJGFscGhhLCBvbWVnYSRvbWVnYS50b3QpDQogIHJlbGlhYg0KICB9DQpgYGANCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9DQphbnhpZXR5Lm1lYS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKEFueGlldHkubWVhKQ0KYW54aWV0eS5tbGEucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihBbnhpZXR5Lm1sYSkNCmFueGlldHkucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkFueGlldHkpDQplZmZpY2FjeS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuU2VsZkVmZmljYWN5KQ0KdGVjaC5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuVGVjaG5vbG9neSkNCmNvb3BlcmF0aXZlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5Db29wb3JhdGl2ZSkNCmRlZHVjdGl2ZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuRGVkdWN0aXZlKQ0KZGVtby5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuRGVtb25zdHJhdGlvbikNCmluZHVjdGl2ZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuSW5kdWN0aXZlKQ0KaW50ZWdyYXRlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5JbnRlZ3JhdGl2ZSkNCmxlY3R1cmUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkxlY3R1cmVUeXBlKQ0KcmVwZXRpdmUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLlJlcGV0aXRpdmUpDQojYWZ0ZXIucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkFmdGVyQ2xhc3MpDQojaW4uY2xhc3MucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkluQ2xhc3MpDQplbmdhZ2UucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkVuZ2FnZSkNCnJlc291cmNlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5SZXNvdXJjZSkNCiMjDQpSZWwudGFibGUgPC1yYmluZChhbnhpZXR5Lm1lYSA9IGFueGlldHkubWVhLnJlbCwgYW54aWV0eS5tbGEgPSBhbnhpZXR5Lm1sYS5yZWwsDQogICAgICAgICAgICAgICAgICBhbnhpZXR5ID0gYW54aWV0eS5yZWwsIHNlbGYuZWZmaWNhY3kgPSBlZmZpY2FjeS5yZWwsDQogICAgICAgICAgICAgICAgICB0ZWNobm9sb2d5ID0gdGVjaC5yZWwsIGNvb3BlcmF0aXZlID0gY29vcGVyYXRpdmUucmVsLA0KICAgICAgICAgICAgICAgICAgZGVkdWN0aXZlID0gZGVkdWN0aXZlLnJlbCwgZGVtb25zdHJhdGlvbiA9IGRlbW8ucmVsLA0KICAgICAgICAgICAgICAgICAgaW5kdWN0aXZlID0gaW5kdWN0aXZlLnJlbCwgaW50ZWdyYXRlID0gaW50ZWdyYXRlLnJlbCwNCiAgICAgICAgICAgICAgICAgIGxlY3R1cmUgPSBsZWN0dXJlLnJlbCwgcmVwZXRpdGl2ZSA9IHJlcGV0aXZlLnJlbCwgDQogICAgICAgICAgICAgICAgICBlbmdhZ2UgPSBlbmdhZ2UucmVsLCByZXNvdXJjZSA9IHJlc291cmNlLnJlbCkNCnJvdy5uYW1lIDwtIGMoImFueGlldHkubWVhIiwgImFueGlldHkubWxhIiwNCiAgICAgICAgICAgICAgImFueGlldHkiLCAic2VsZi5lZmZpY2FjeSIsICJ0ZWNobm9sb2d5IiwgImNvb3BlcmF0aXZlIiwNCiAgICAgICAgICAgICAgImRlZHVjdGl2ZSIsICJkZW1vbnN0cmF0aW9uIiwgImluZHVjdGl2ZSIsICJpbnRlZ3JhdGUiLA0KICAgICAgICAgICAgICAibGVjdHVyZSIsICJyZXBldGl0aXZlIiwgImVuZ2FnZSIsICJyZXNvdXJjZSIpDQpjb2wubmFtZSA8LSBjKCJDcm9uYmFjaCBhbHBoYSIsICJNY0RvbmFsZCdzIE9tZWdhIikNCnJvd25hbWVzKFJlbC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKFJlbC50YWJsZSkgPC0gY29sLm5hbWUNCnBhbmRlcihSZWwudGFibGUpDQpgYGANCg0KV2UgY2FuIHNlZSBmcm9tIHRoZSBhYm92ZSB0YWJsZSB0aGF0IGFsbCBjYWxjdWxhdGVkIGNvZWZmaWNpZW50cyBleGNlZWRlZCB0aGUgcmVjb21tZW5kZWQgdGhyZXNob2xkIG9mIDAuNywgaW5kaWNhdGluZyBnb29kIHJlbGlhYmlsaXR5LiBUaGUgcmVzdWx0cyBjb25maXJtIHRoYXQgdGhlIGluc3RydW1lbnRzIHVzZWQgaW4gdGhpcyBzdHVkeSBkZW1vbnN0cmF0ZSBzdHJvbmcgaW50ZXJuYWwgY29uc2lzdGVuY3ksIG1lYW5pbmcgdGhlIGl0ZW1zIHdpdGhpbiBlYWNoIHNjYWxlIHJlbGlhYmx5IG1lYXN1cmUgdGhlIHNhbWUgdW5kZXJseWluZyBjb25zdHJ1Y3QuDQoNCiMgQ29tcG9zaXRlIFNjb3JpbmcNCg0KVGhlIGNvcmUgcHVycG9zZSBvZiBjb25zdHJ1Y3RpbmcgbXVsdGktaXRlbSBzdXJ2ZXlzIGlzIHRvIG1lYXN1cmUgY29tcGxleCBjb25jZXB0cyB3aXRoIGdyZWF0ZXIgYWNjdXJhY3ksIHJlbGlhYmlsaXR5LCBhbmQgZGVwdGggdGhhbiBhIHNpbmdsZSBxdWVzdGlvbiBldmVyIGNvdWxkLiBBbGwgaW5zdHJ1bWVudHMgdXNlZCBpbiB0aGlzIHN0dWR5IGFyZSBiYXNlZCBvbiBhIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IHVzaW5nIHRoZSBMaWtlcnQgc2NhbGVzLiBUaGUgY29tbW9ubHkgdXNlZCBtZXRob2RzIGZvciBkZWZpbmluZyBzaW5nbGUgaW5kZXggdG8gY2FwdHVyZSB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IGFyZSBjbGFzc2lmaWVkIGluIHRocmVlIGNhdGVnb3JpZXMNCg0KIyMgU3VtbWluZyB0aGUgUmF3IExpa2VydCBTY29yZXMNCg0KVGhlIHNpbXBsZXN0IGFwcHJvYWNoIGlzIHRvIHN1bSB0aGUgcmF3IExpa2VydCBzY29yZXMgaW50byBhIGNvbXBvc2l0ZSBzY29yZSB0aGF0IHJlcHJlc2VudHMgYSBzaW5nbGUgZmFjdG9yIHdpdGhpbiB0aGUgc3VydmV5IGNvbnN0cnVjdC4gVGhpcyBtZXRob2QgaXMgdmFsaWQgcHJvdmlkZWQgdGhhdCBhbGwgcXVlc3Rpb25uYWlyZSBpdGVtcyBhcmUgZXF1YWxseSBpbXBvcnRhbnQsIGFzIGVhY2ggY2FwdHVyZXMgYSBzaW1pbGFyIGFtb3VudCBvZiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdW5kZXJseWluZyBmYWN0b3IuDQoNCkhvd2V2ZXIsIHRoaXMgYXBwcm9hY2ggaXMgdmlvbGF0ZWQgaW4gc2V2ZXJhbCBjcml0aWNhbCBzY2VuYXJpb3MsIGxlYWRpbmcgdG8gYSBiaWFzZWQgYW5kIHVucmVsaWFibGUgY29tcG9zaXRlIHNjb3JlLiBGb3IgZXhhbXBsZSwgKipWaW9sYXRpb24gb2YgRXF1YWwgSW1wb3J0YW5jZSoqOiBUaGUgY29yZSBhc3N1bXB0aW9uIGlzIHRoYXQgZWFjaCBpdGVtIGlzIGEgZXF1YWxseSBzdHJvbmcgaW5kaWNhdG9yIG9mIHRoZSBjb25zdHJ1Y3QuIEluIHJlYWxpdHksIGl0ZW1zIG9mdGVuIGhhdmUgZGlmZmVyZW50IGxldmVscyBvZiBpbXBvcnRhbmNlLiBTdW1taW5nIGl0ZW1zIHdpdGggaGlnaCBhbmQgbG93IGxldmVscyBvZiBpbXBvcnRhbmNlIGVxdWFsbHkgZ2l2ZXMgdW5kdWUgd2VpZ2h0IHRvIHdlYWtlciBpbmRpY2F0b3JzLCBlZmZlY3RpdmVseSBkaWx1dGluZyB0aGUgY29tcG9zaXRlIHNjb3JlIHdpdGggbm9pc2UgYW5kIHJlZHVjaW5nIGl0cyB2YWxpZGl0eS4NCg0KIyMgRkEgQXBwcm9hY2gNCg0KQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKSBpcyBhIHZlcnkgY29tbW9uIGFuZCBvZnRlbiBwcmFjdGljYWwgYXBwcm9hY2ggdG8gdmFsaWRhdGluZyBzdXJ2ZXkgaW5zdHJ1bWVudHMgYW5kIGNyZWF0ZSAod2VpZ2h0ZWQpIGNvbXBvc2l0ZSBzY29yZS4gSXQgaXMgYSBkaXN0cmlidXRpb24gZGVwZW5kZW50IHN0YXRpc3RpY2FsIG1ldGhvZC4gSG93ZXZlciwgaXQgY29tZXMgd2l0aCBhIHNldCBvZiBkaXN0aW5jdCBzb21lIGRpc2FkdmFudGFnZXMgcGFydGljdWxhcmx5IHRoZSBhc3N1bXB0aW9uIG9mIG11bHRpLXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gRmFjdG9yIGxvYWRpbmdzIGluIENGQSBhcmUgZXN0aW1hdGVkIGJhc2VkIG9uIHRoZSBtYXhpbXVtIGxpa2VsaWhvb2Qgd2hpY2ggaXMgZGVmaW5lZCBiYXNlZCBvbiBtdWx0aXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KV2UgaGF2ZSB1c2VkIENGQSB0byB2YWxpZGF0ZSB0aGUgaW5zdHJ1bWVudC4gU2luY2UgYWxsIGluc3RydW1lbnRzIGluIHRoaXMgc3R1ZHkgYXJlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0cywgd2Ugd2lsbCBjYWxjdWxhdGUgdGhlIHNpbmdsZSBjb21wb3NpdGUgc2NvcmUgZm9yIGVhY2ggaW5zdHJ1bWVudCB1c2luZyBDRkEuDQoNCiMjIFBDQSBBcHByb2FjaA0KDQpQQ0EgaXMgYSBkaXN0cmlidXRpb24tZnJlZSBtZXRob2Qgd2hpY2ggdXNlcyBhIG1hdGhlbWF0aWNhbCB0cmFuc2Zvcm1hdGlvbiAob3J0aG9nb25hbCByb3RhdGlvbikgdG8gb2J0YWluIGEgbmV3IGNvb3JkaW5hdGUgc3lzdGVtIHN1Y2ggdGhhdCB0aGUgZmlyc3QgbmV3IGF4aXMgKFByaW5jaXBhbCBDb21wb25lbnQgMSkgcG9pbnRzIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIG1heGltdW0gdmFyaWFuY2UgaW4gdGhlIGRhdGEuIFRoZSBzZWNvbmQgYXhpcyBpcyBvcnRob2dvbmFsIHRvIHRoZSBmaXJzdCBhbmQgcG9pbnRzIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIG5leHQgZ3JlYXRlc3QgdmFyaWFuY2UsIGFuZCBzbyBvbi4gVGhlIG5ldyBheGVzIChjb21wb25lbnRzKSBhcmUgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiB0aGUgb3JpZ2luYWwgdmFyaWFibGVzLiBDb25zZXF1ZW50bHksIGEgay1pdGVtIGluc3RydW1lbnQgd2lsbCBnZW5lcmF0ZSBrIHByaW5jaXBhbCBjb21wb25lbnRzLg0KDQpBbHRob3VnaCB0aGVyZSBkZWJhdGVzIG9uIHVzaW5nIFBDQSBpbiBwc3ljaG9tZXRyaWNzLCB0aGUgZWFybGllc3QgYXBwbGljYXRpb25zIG9mIFBDQSBpbiBzdXJ2ZXkgcmVzZWFyY2ggY2FuIGJlIHRyYWNlZCBiYWNrIHRvIDE5NTBzIChTdG91ZmZlciBldCBhbC4sIDE5NTA7IENhdHRlbGwsIDE5NTI7IER1bmNhbiwgMTkgKS4gVGhlIGdvYWwgd2FzIGNvbnNpc3RlbnRseSB0aGUgc2FtZSBhcyBpdCBpcyB0b2RheTogdG8gdW5jb3ZlciB0aGUgc2ltcGxlLCBsYXRlbnQgc3RydWN0dXJlcyB0aGF0IHVuZGVybGllIHRoZSBjb21wbGV4IGNvcnJlbGF0aW9ucyBhbW9uZyBtYW55IG9ic2VydmVkIHN1cnZleSBxdWVzdGlvbnMuDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipBZGp1c3RpbmcgRGlyZWN0aW9uIG9mIFBDcyoqPC9mb250Pg0KDQpQcmluY2lwYWwgQ29tcG9uZW50cyAoUENzKSBhcmUgbmV3LCB1bmNvcnJlbGF0ZWQgYXhlcywgd2hlcmVhcyBMaWtlcnQgc2NvcmVzIGFyZSBvcmRpbmFsIHJhdGluZyBzY2FsZXMuIFdoZW4gdXNpbmcgUENzIHRvIHJlcHJlc2VudCB0aGVzZSByYXRpbmcgc2NhbGVzLCB0aGVpciBkaXJlY3Rpb24gbXVzdCBiZSBhbGlnbmVkLiBBIHNpbXBsZSBtZXRob2QgdG8gZGV0ZXJtaW5lIGlmIGEgUEMncyBkaXJlY3Rpb24gbmVlZHMgdG8gYmUgcmV2ZXJzZWQgaXMgdG8gZXhhbWluZSB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGJldHdlZW4gdGhlIG5haXZlIGNvbXBvc2l0ZSBhdmVyYWdlIHNjb3JlcyBhbmQgdGhlIFBDIHNjb3Jlcy4gSWYgdGhlIGNvcnJlbGF0aW9uIGlzIG5lZ2F0aXZlLCB0aGUgY29ycmVzcG9uZGluZyBQQyBzaG91bGQgYmUgcmV2ZXJzZWQ7IG90aGVyd2lzZSwgdGhlIGRlZmF1bHQgYXhpcyBzaG91bGQgYmUgcmV0YWluZWQuDQoNCioqQ29tcG9zaXRlIFNjb3JpbmcgVXNpbmcgVGhlIGZpcnN0IFByaW5jaXBhbCBDb21wb25lbnQgKFBDMSkqKg0KDQpUaGlzIGFwcHJvYWNoIGhhcyBiZWVuIGVtcGxveWVkIHNpbmNlIHRoZSAxOTUwcyAoZS5nLiwgR3V0dG1hbiwgMTk1NDsgSGlyc2NoYmVyZyAmIFN0YW5kaXNoLCAxOTU5OyBEdW5jYW4sIDE5NjEpLiBUaGUgcmF0aW9uYWxlIGZvciB1c2luZyB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudCBpcyB0aGF0IGl0IGFjY291bnRzIGZvciB0aGUgbWF4aW11bSB2YXJpYW5jZSBpbiB0aGUgZGF0YSBhbmQgY29uc3RpdHV0ZXMgYSBsaW5lYXIgY29tYmluYXRpb24gb2YgYWxsIGl0ZW1zLiBNdWNoIGxpa2UgaW4gY29uZmlybWF0b3J5IGZhY3RvciBhbmFseXNpcyAoQ0ZBKSwgdGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnQgY2FuIGJlIGludGVycHJldGVkIGFzIGEgd2VpZ2h0ZWQgYXZlcmFnZSBvZiBpbmRpdmlkdWFsIGl0ZW0gc2NvcmVzLg0KDQoqKkNvbXBvc2l0ZSBTY29yaW5nIFVzaW5nIFdlaWdodGVkIEF2ZXJhZ2Ugb2YgSXRlbSBTY29yZXMgQWNyb3NzIEFsbCBQQ3M6KiogPGZvbnQgY29sb3IgPSAicmVkIj5Eb3VibHkgV2VpZ2h0ZWQgQXZlcmFnZTwvZm9udD4NCg0KSW4gbWFueSByZWFsLXdvcmxkIGRhdGFzZXRzLCB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RzIGFyZSBpbmhlcmVudGx5IG11bHRpZGltZW5zaW9uYWwuIENvbnNlcXVlbnRseSwgbGltaXRpbmcgdGhlIGFuYWx5c2lzIHRvIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IG1lYW5zIGRpc2NhcmRpbmcgc3RydWN0dXJlZCBpbmZvcm1hdGlvbiBjYXB0dXJlZCBieSBzdWJzZXF1ZW50IGNvbXBvbmVudHMgKFBDMiwgUEMzLCBldGMuKS4gQSBjb21wb3NpdGUgc2NvcmUgdGhhdCBpbnRlZ3JhdGVzIGFsbCBzaWduaWZpY2FudCBjb21wb25lbnRzIG9mZmVycyBhIG1vcmUgaG9saXN0aWMgYW5kIGFjY3VyYXRlIHN1bW1hcnkgbWVhc3VyZS4gVGhlIHByaW1hcnkgYmFycmllciB0byB0aGUgd2lkZXNwcmVhZCBhZG9wdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyB0aGUgY2hhbGxlbmdlIGFzc29jaWF0ZWQgd2l0aCBpbnRlcnByZXRpbmcgdGhlIGNvbXBvc2l0ZSBpbmRleCdzIHN0cnVjdHVyZS4NCg0KIyMgQ29tcG9zaXRlIFNjb3JlcyBUbyBCZSBDcmVhdGVkDQoNCldlIHdpbGwgZ2VuZXJhdGUgZm91ciB0eXBlcyBvZiBjb21wb3NpdGUgc2NvcmVzIGZvciBlYWNoIG9mIHRoZSAxMSBpbnN0cnVtZW50cyBmb3IgdGhlIHB1cnBvc2Ugb2YgZW1waXJpY2FsIGNvbXBhcmlzb24uDQoNCi0gICAqKmF2ZyoqOiBUaGUgYXZlcmFnZSBvZiB0aGUgcmF3IGl0ZW0gc2NvcmVzLg0KLSAgICoqY2ZhKio6IFRoZSBleHRyYWN0IGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKGNmYSkgc2NvcmUgKGFsbCBpbnN0cnVtZW50cyBhcmUgYmFzZWQgb24gdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0KS4NCi0gICAqKnBjYTEqKjogVGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnQgc2NvcmVzLg0KLSAgICoqcGNhLnd0Kio6IFRoZSB3ZWlnaHRlZCBhdmVyYWdlIG9mIHBjYSBzY29yZXMgYWNyb3NzIGFsbCBwcmluY2lwYWwgY29tcG9uZW50cy4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFfQ0KIyMjIyMNCiBzY29yZXMgPSBmdW5jdGlvbihkZiwgZG4pew0KICAjIyMjIyMjIyMjIyMjIyMNCiAgIyBtZWFuIHNjb3JlDQogICMjIyMjIyMjIyMjIyMjDQogIGRmLm1lYW4gPC0gcm93TWVhbnMoZGZbLCAtMV0pDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIyBzaW5nbGUgZmFjdG9yIHNjb3JlDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHgudmFyIDwtIG5hbWVzKGRmWywgLTFdKQ0KICBuMCA8LSBsZW5ndGgoeC52YXIpDQogIGNmYS5tb2RlbCA8LSAgcGFzdGUoImxhdGVudCA9fiIsIHBhc3RlKHgudmFyLCBjb2xsYXBzZSA9ICIgKyAiKSkNCiAgY2ZhLmZpdCA8LSBjZmEoY2ZhLm1vZGVsLCBkYXRhID0gZGZbLCAtMV0sIGVzdGltYXRvciA9ICJNTE0iKQ0KICBjb21wb3NpdGUuY2ZhIDwtIGxhdlByZWRpY3QoY2ZhLmZpdCkNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyBwY2EgYW5hbHlzaXMNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgcGNhLm1kbCA8LSBwcmNvbXAoZGZbLC0xXSwgc2NhbGUgPSBUUlVFKQ0KICBwY2EwIDwtIHBjYS5tZGwkeFssIDFdDQogIHIwID0gY29yKHBjYTAsIGRmLm1lYW4pDQogIGlmKHIwIDwgMCkgew0KICAgICBwY2EuYWxsIDwtIC1wY2EubWRsJHgNCiAgfWVsc2V7DQogICAgcGNhLmFsbCA8LSBwY2EubWRsJHgNCiAgfQ0KICBmaXJzdC5wY2EgPSBwY2EuYWxsWywxXQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIHdlaWdodGVkIHBjYSBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB2YXIuZXhwbGFpbmVkIDwtKChwY2EubWRsJHNkZXYpXjIpIC8gc3VtKChwY2EubWRsJHNkZXYpXjIpICMNCiAgY29tcG9zaXRlX3dlaWdodGVkX3BjYSA8LSBhcy5tYXRyaXgocGNhLmFsbCkgJSolICh2YXIuZXhwbGFpbmVkKQ0KDQogIG91dGRhdGEgPC0gYXMuZGF0YS5mcmFtZShjYmluZChhdmcgPSBkZi5tZWFuLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjYTEgPSBmaXJzdC5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgd3QucGNhID0gYXMudmVjdG9yKGNvbXBvc2l0ZV93ZWlnaHRlZF9wY2EpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmYSA9IGFzLnZlY3Rvcihjb21wb3NpdGUuY2ZhKSkpDQogIG5hbWVzKG91dGRhdGEpIDwtIHBhc3RlMChkbiwiLiIsIG5hbWVzKG91dGRhdGEpLCBzZXAgPSAiIikNCiAgb3V0ZGF0YQ0KICB9DQojIyMNCkFueGlldHkubWVhLnNjb3JlID0gc2NvcmVzKEFueGlldHkubWVhLCAiQW54aWV0eS5tZWEiKQ0KQW54aWV0eS5tbGEuc2NvcmUgPSBzY29yZXMoQW54aWV0eS5tbGEsICJBbnhpZXR5Lm1sYSIpDQpBbnhpZXR5LnNjb3JlID0gc2NvcmVzKENvbXAuQW54aWV0eSwgIkFueGlldHkiKQ0KU2VsZkVmZmljYWN5LnNjb3JlID0gc2NvcmVzKENvbXAuU2VsZkVmZmljYWN5MCwgIlNlbGZFZmZpY2FjeSIpDQpUZWNobm9sb2d5LnNjb3JlID0gc2NvcmVzKENvbXAuVGVjaG5vbG9neSwgIlRlY2hub2xvZ3kiKQ0KQ29vcG9yYXRpdmUuc2NvcmUgPSBzY29yZXMoQ29tcC5Db29wb3JhdGl2ZSwgIkNvb3BvcmF0aXZlIikNCkRlZHVjdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLkRlZHVjdGl2ZSwgIkRlZHVjdGl2ZSIpDQpEZW1vbnN0cmF0aW9uLnNjb3JlID0gc2NvcmVzKENvbXAuRGVtb25zdHJhdGlvbiwgIkRlbW9uc3RyYXRpb24iKQ0KSW5kdWN0aXZlLnNjb3JlID0gc2NvcmVzKENvbXAuSW5kdWN0aXZlLCAiSW5kdWN0aXZlIikNCkludGVncmF0aXZlLnNjb3JlID0gc2NvcmVzKENvbXAuSW50ZWdyYXRpdmUsICJJbnRlZ3JhdGl2ZSIpDQpMZWN0dXJlVHlwZS5zY29yZSA9IHNjb3JlcyhDb21wLkxlY3R1cmVUeXBlLCAiTGVjdHVyZVR5cGUiKQ0KUmVwZXRpdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLlJlcGV0aXRpdmUsICJSZXBldGl0aXZlIikNCkVuZ2FnZS5zY29yZSA9IHNjb3JlcyhDb21wLkVuZ2FnZSwgIkVuZ2FnZSIpDQpSZXNvdXJjZS5zY29yZSA9IHNjb3JlcyhDb21wLlJlc291cmNlLCAiUmVzb3VyY2UiKQ0KIyMNCmZpbmFsRGF0IDwtIGNiaW5kKGRlbW9ncmFwaGljcywgQW54aWV0eS5zY29yZSwgQW54aWV0eS5tZWEuc2NvcmUsDQogICAgICAgICAgICAgICAgICBBbnhpZXR5Lm1sYS5zY29yZSwgU2VsZkVmZmljYWN5LnNjb3JlLCBUZWNobm9sb2d5LnNjb3JlLA0KICAgICAgICAgICAgICAgICAgQ29vcG9yYXRpdmUuc2NvcmUsIERlZHVjdGl2ZS5zY29yZSwgRGVtb25zdHJhdGlvbi5zY29yZSxJbmR1Y3RpdmUuc2NvcmUsDQogICAgICAgICAgICAgICAgICBJbnRlZ3JhdGl2ZS5zY29yZSwgTGVjdHVyZVR5cGUuc2NvcmUsIFJlcGV0aXRpdmUuc2NvcmUsDQogICAgICAgICAgICAgICAgICBFbmdhZ2Uuc2NvcmUsIFJlc291cmNlLnNjb3JlKQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbCA9IEZBTFNFfQ0Kd3JpdGUuY3N2KGZpbmFsRGF0LCAiQzpcXFVzZXJzXFw3NUNQRU5HXFxPbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBXFxEZXNrdG9wXFxjcGVuZ1xcV0NVLVRlYWNoaW5nXFwyMDI1RmFsbFxcTWF0aEF4aWV0eVxcY29tcGxldGVBbnhpZXR5RGF0YS5jc3YiKQ0KYGBgDQoNCiMgU29tZSBHcmFwaGljYWwgRXhwbG9yYXRpb24NCg0KV2UgbmV4dCBleHBsb3JlIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBjcmVhdGVkIGNvbXBvc2l0ZSBzY29yZXMgYW5kIHBlcmZvcm0gc29tZSBlbXBpcmljYWwgY29tcGFyaXNvbnMuIFRoZSBwcmltYXJ5IGdvYWwgb2YgdGhpcyBzdXJ2ZXkgc3R1ZHkgaXMgdG8gaW52ZXN0aWdhdGUgZmFjdG9ycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggbWF0aGVtYXRpY3MgYW54aWV0eSAoTUEpIGxldmVscy4gVG8gdGhpcyBlbmQsIHdlIGFsc28gbG9vayB0aGUgZGlzdHJpYnV0aW9ucyBlYWNoIGluZGl2aWR1YWwgaXRlbXMgaW4gdGhlIE1BIGluc3RydW1lbnQuDQoNCiMjIERpc3RyaWJ1dGlvbnMgb2YgQ29tcG9zaXRlIFNjb3Jlcw0KDQpUaGUgZm9sbG93aW5nIGFyZSBkaXN0cmlidXRpb25zIG9mIGZvdXIgZ2VuZXJhdGVkIGNvbXBvc2l0ZSBzY29yZXMgYWNyb3NzIGFsbCBpbnN0cnVtZW50cy4gVGhlIHB1cnBvc2UgaXMgdG8gZXhhbWluZSB0aGUgYmVoYXZpb3JzIG9mIHRoZXNlIGNvbXBvc2l0ZSBzY29yZXMsIGVzcGVjaWFsbHkgdGhlIGRvdWJseSB3ZWlnaHRlZCBjb21wb3NpdGUgc2NvcmUgYmFzZWQgb24gdGhlIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMuDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCiNmaW5hbC5hbnhpZXR5LmRhdCA8LSByZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTWF0aEFueGlldHkvY29tcGxldGVBbnhpZXR5RGF0YS5jc3YiKQ0KZmluYWwuYW54aWV0eS5kYXQgPC0gZmluYWxEYXQNCmBgYA0KDQpgYGB7cn0NCnBsb3RseS5mdW4gPC0gZnVuY3Rpb24oaW4uZGF0YSl7DQogICBpbi5hdmcgPC0gZGVuc2l0eShpbi5kYXRhWywxXSkNCiAgIGluLnBjMSA8LSBkZW5zaXR5KGluLmRhdGFbLDJdKQ0KICAgaW4ucGN3IDwtIGRlbnNpdHkoaW4uZGF0YVssM10pDQogICBpbi5jZmEgPC0gZGVuc2l0eShpbi5kYXRhWywgNF0pDQogICBkYXQubmFtZSA8LSBzdWIoIlxcLi4qIiwgIiIsbmFtZXMoaW4uZGF0YSlbMV0pICAjc3ViKCB0ZXh0KQ0KICAgIyBwbG90IGRlbnNpdHkgY3VydmVzDQogIGZpZyA8LSBwbG90X2x5KHggPSB+aW4uYXZnJHgsIHkgPSB+aW4uYXZnJHksIA0KICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgDQogICAgICAgICAgICAgICBtb2RlID0gJ2xpbmVzJywgDQogICAgICAgICAgICAgICBuYW1lID0gJ2F2ZycsIA0KICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICAgICAgIyBhZGRpbmcgbW9yZSBkZW5zaXR5IGN1cnZlcw0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLnBjMSR4LCB5ID0gfmluLnBjMSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdwY2ExJywgDQogICAgICAgICAgICAgICAgIGZpbGwgPSAndG96ZXJveScpICAlPiUgDQogICAgICAgYWRkX3RyYWNlKHggPSB+aW4ucGN3JHgsIHkgPSB+aW4ucGN3JHksIA0KICAgICAgICAgICAgICAgICBuYW1lID0gJ3BjYS53dCcsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gJ3RvemVyb3knKSAgJT4lIA0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLmNmYSR4LCB5ID0gfmluLmNmYSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdjZmEnLCANCiAgICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ3Njb3JlcycpLA0KICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnRGVuc2l0eScpLA0KICAgICAgICAgICAgICAjdGl0bGUgPSBkYXQubmFtZSwNCiAgICAgICAgICAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICB0ID0gMTAwLCAgIyBBZGp1c3QgdGhpcyB2YWx1ZSB0byBpbmNyZWFzZSBvciBkZWNyZWFzZSB0aGUgdG9wIG1hcmdpbg0KICAgICAgICAgICAgICAgICAgYiA9IDUwLA0KICAgICAgICAgICAgICAgICAgbCA9IDUwLA0KICAgICAgICAgICAgICAgICAgciA9IDUwKQ0KICAgICAgICAgICAgICkNCiAgICAgZmlnDQogICAgIH0NCiMjIyMNCmluLmFueGlldHkubWVhID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiQW54aWV0eS5tZWEuYXZnIiwgIkFueGlldHkubWVhLnBjYTEiLCAiQW54aWV0eS5tZWEud3QucGNhIiwiQW54aWV0eS5tZWEuY2ZhIildDQppbi5hbnhpZXR5Lm1sYSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQW54aWV0eS5tbGEuYXZnIiwiQW54aWV0eS5tbGEucGNhMSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCJBbnhpZXR5Lm1sYS5jZmEiKV0NCiMjIw0KaW4uYW54aWV0eSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIkFueGlldHkuYXZnIiwgIkFueGlldHkucGNhMSIsICJBbnhpZXR5Lnd0LnBjYSIsICJBbnhpZXR5LmNmYSIpXQ0KaW4uZWZmaWNhY3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJTZWxmRWZmaWNhY3kuYXZnIiwgIlNlbGZFZmZpY2FjeS5wY2ExIiwiU2VsZkVmZmljYWN5Lnd0LnBjYSIsIlNlbGZFZmZpY2FjeS5jZmEiKV0NCmluLnRlY2hub2xvZ3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJUZWNobm9sb2d5LmF2ZyIsIlRlY2hub2xvZ3kucGNhMSIsICJUZWNobm9sb2d5Lnd0LnBjYSIsIlRlY2hub2xvZ3kuY2ZhIildDQppbi5jb29wb3JhdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQ29vcG9yYXRpdmUuYXZnIiwiQ29vcG9yYXRpdmUucGNhMSIsICJDb29wb3JhdGl2ZS53dC5wY2EiLCJDb29wb3JhdGl2ZS5jZmEiKV0NCmluLmRlZHVjdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiRGVkdWN0aXZlLmF2ZyIsIkRlZHVjdGl2ZS5wY2ExIiwiRGVkdWN0aXZlLnd0LnBjYSIsIkRlZHVjdGl2ZS5jZmEiKV0NCmluLmRlbW9uc3RyYXRpb24gPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoIkRlbW9uc3RyYXRpb24uYXZnIiwiRGVtb25zdHJhdGlvbi5wY2ExIiwiRGVtb25zdHJhdGlvbi53dC5wY2EiLCJEZW1vbnN0cmF0aW9uLmNmYSIpXQ0KaW4uaW5kdWN0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW5kdWN0aXZlLmF2ZyIsIkluZHVjdGl2ZS5wY2ExIiwiSW5kdWN0aXZlLnd0LnBjYSIsIkluZHVjdGl2ZS5jZmEiKV0NCmluLmludGVncmF0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW50ZWdyYXRpdmUuYXZnIiwgIkludGVncmF0aXZlLnBjYTEiLCJJbnRlZ3JhdGl2ZS53dC5wY2EiLCJJbnRlZ3JhdGl2ZS5jZmEiKV0NCmluLmxlY3R1cmVUeXBlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiTGVjdHVyZVR5cGUuYXZnIiwgIkxlY3R1cmVUeXBlLnBjYTEiLCAiTGVjdHVyZVR5cGUud3QucGNhIiwiTGVjdHVyZVR5cGUuY2ZhIildDQppbi5yZXBldGl0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiUmVwZXRpdGl2ZS5hdmciLCAiUmVwZXRpdGl2ZS5wY2ExIiwgIlJlcGV0aXRpdmUud3QucGNhIiwiUmVwZXRpdGl2ZS5jZmEiKV0NCmluLmVuZ2FnZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggICJFbmdhZ2UuYXZnIiwgIkVuZ2FnZS5wY2ExIiwgIkVuZ2FnZS53dC5wY2EiLCJFbmdhZ2UuY2ZhIildDQppbi5yZXNvdXJjZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIlJlc291cmNlLmF2ZyIsICJSZXNvdXJjZS5wY2ExIiwgIlJlc291cmNlLnd0LnBjYSIsICJSZXNvdXJjZS5jZmEiKV0NCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTN9DQpwLm1lYSA8LSBwbG90bHkuZnVuKGluLmFueGlldHkubWVhKQ0KcC5tbGEgPC0gcGxvdGx5LmZ1bihpbi5hbnhpZXR5Lm1sYSkNCiMgQXJyYW5nZSBpbiAxeDIgZ3JpZA0Kc3VicGxvdChwLm1lYSwgcC5tbGEsIG5yb3dzID0gMSwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiQW54aWV0eS5tZWEiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJBbnhpZXR5Lm1sYSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKQ0KICAgICksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9DQpwMSA8LSBwbG90bHkuZnVuKGluLmFueGlldHkpDQpwMiA8LSBwbG90bHkuZnVuKGluLmVmZmljYWN5KQ0KcDMgPC0gcGxvdGx5LmZ1bihpbi50ZWNobm9sb2d5KQ0KcDQgPC0gcGxvdGx5LmZ1bihpbi5jb29wb3JhdGl2ZSkNCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChwMSwgcDIsIHAyLCBwNCwgbnJvd3MgPSAyLCB0aXRsZVggPSBUUlVFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4wNSwgeSA9IC45OSwgdGV4dCA9ICJBbnhpZXR5IiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiU2VsZi1lZmZpY2FjeSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAwLjQsIHRleHQgPSAiVGVjaG5vbG9neSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiQ29vcnBvcmF0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCnAxIDwtIHBsb3RseS5mdW4oaW4uZGVkdWN0aXZlKQ0KcDIgPC0gcGxvdGx5LmZ1bihpbi5kZW1vbnN0cmF0aW9uKQ0KcDMgPC0gcGxvdGx5LmZ1bihpbi5pbmR1Y3RpdmUpDQpwNCA8LSBwbG90bHkuZnVuKGluLmludGVncmF0aXZlKQ0KIyBBcnJhbmdlIGluIDJ4MiBncmlkDQpzdWJwbG90KHAxLCBwMiwgcDIsIHA0LCBucm93cyA9IDIsIHRpdGxlWCA9IFRSVUUsIHRpdGxlWSA9IFRSVUUsIG1hcmdpbiA9IDAuMSkgJT4lDQogIGxheW91dCgNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gLjk5LCB0ZXh0ID0gIkRlZHVjdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIkRlbW9uc3RyYXRpdmUiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gMC40LCB0ZXh0ID0gIkluZHVjdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiSW50ZXJncmF0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0NCnAxIDwtIHBsb3RseS5mdW4oaW4ubGVjdHVyZVR5cGUpDQpwMiA8LSBwbG90bHkuZnVuKGluLnJlcGV0aXRpdmUpDQpwMyA8LSBwbG90bHkuZnVuKGluLmVuZ2FnZSkNCnA0IDwtIHBsb3RseS5mdW4oaW4ucmVzb3VyY2UpDQojIEFycmFuZ2UgaW4gMngyIGdyaWQNCnN1YnBsb3QocDEsIHAyLCBwMiwgcDQsIG5yb3dzID0gMiwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiTGVjdHVyZSBUeXBlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiUmVwZXRhdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAwLjQsIHRleHQgPSAiRW5nYWdlbWVudCIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiUmVzb3VyY2UiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KVGhlc2UgZGVuc2l0eSBjdXJ2ZXMgaWxsdXN0cmF0ZSB0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgZm91ciBjb21wb3NpdGUgc2NvcmVzICgqKmF2ZywgY2ZhLCBwYzEqKiwgYW5kICoqcGNhLnd0KiopIGZvciBhbGwgc2luZ2xlLWZhY3RvciBpbnN0cnVtZW50cyBpbiB0aGUgc3VydmV5LiBUaGUgKiphdmcqKiBpcyBhIG5haXZlIG1lYXN1cmUsIGRlcml2ZWQgZnJvbSB0aGUgYXJpdGhtZXRpYyBtZWFuIG9mIHRoZSBpdGVtIHNjb3Jlcy4gVGhlICoqY2ZhKiogYW5kICoqcGMxKiogY29tcG9zaXRlcyBhcmUgd2VpZ2h0ZWQgYXZlcmFnZXMsIHdoZXJlIHRoZSB3ZWlnaHRzIChsb2FkaW5ncykgYXJlIGRlcml2ZWQgZnJvbSBkaXN0aW5jdCBsYXRlbnQgdmFyaWFibGUgbW9kZWxzLiBUaGUgKipwY2Eud3QgY29tcG9zaXQqKmUgaXMgYSA8Zm9udCBjb2xvcj0icmVkIj4qKmRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlKio8L2ZvbnQ+LCBiYXNlZCBvbiBib3RoIHRoZSBvcmlnaW5hbCBpdGVtIHNjb3JlcyBhbmQgYWxsIG9mIHRoZSByZXN1bHRpbmcgcHJpbmNpcGFsIGNvbXBvbmVudHMuDQoNCi0gICBUaHJlZSBtb2RlbC1iYXNlZCBjb21wb3NpdGUgc2NvcmVzICgqKmNmYSwgcGMxKiosIGFuZCAqKnBjYS53dCoqKSBhcmUgY2VudGVyZWQgYXQgMCBidXQgZXhoaWJpdCBkaWZmZXJlbnQgYmVoYXZpb3JzOg0KICAgIC0gICAqKnBjMSoqIGhhcyB0aGUgbGFyZ2VzdCB2YXJpYW5jZS4NCiAgICAtICAgKipjZmEqKiBoYXMgdGhlIHNtYWxsZXN0IHZhcmlhbmNlLg0KLSAgICoqYXZnKiogYW5kICoqcGNhLnd0KiogYmVoYXZlIHNpbWlsYXJseSwgZGlmZmVyaW5nIHByaW1hcmlseSBpbiB0aGVpciBsb2NhdGlvbnMuDQoNClRoZSBjb21wb3NpdGUgc2NvcmUgKiphdmcqKiBzZXJ2ZXMgYXMgYSByZWZlcmVuY2UgcG9pbnQsIGFuYWxvZ291cyB0byBhbiBlbXBpcmljYWwgZGlzdHJpYnV0aW9uLCBhcyBpdCB1c2VzIGFsbCBpdGVtIHNjb3JlcyBkaXJlY3RseS4gSW4gY29udHJhc3QsICoqcGNhLnd0KiogdXNlcyBhIGRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlIG9mIGFsbCBpdGVtIHNjb3JlcyB3aXRob3V0IGltcG9zaW5nIGNvbXBsZXggZGlzdHJpYnV0aW9uYWwgYXNzdW1wdGlvbnMuIFRoaXMgZGVtb25zdHJhdGVzIHRoYXQgKipwY2Eud3QqKiBpcyBhIHJlbGlhYmxlIGFuZCByb2J1c3QgY29tcG9zaXRlIHNjb3JlLiBGb3IgdGhlIHJlbWFpbmRlciBvZiB0aGlzIHJlcG9ydCwgdGhlICoqcGNhLnd0Kiogc2NvcmUgd2lsbCBiZSB1c2VkLCB3aXRoICoqY2ZhKiogb2NjYXNpb25hbGx5IGVtcGxveWVkIGZvciBpbGx1c3RyYXRpdmUgcHVycG9zZXMgZm9yIHNvbWUgc3BlY2lhbCBjYXNlcy4NCg0KIyMgRGlzdHJpYnV0aW9uIG9mIERlbW9ncmFwaGljcw0KDQpUaGUgZGlzdHJpYnV0aW9uIG9mIGRlbW9ncmFwaGljIGZhY3RvcnMgYXJlIHJlcG9ydGVkIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlcy4NCg0KYGBge3J9DQojIEVuaGFuY2VkIGhvdmVyIGluZm9ybWF0aW9uDQpEZW1vZ3JhcGhpYy5iYXIgPC1mdW5jdGlvbihpbi5jYXQsIHZhcm5hbWUpew0KICBmcmVxLnRibCA8LSB0YWJsZShpbi5jYXQpDQogIGRmIDwtIGRhdGEuZnJhbWUoDQogICAgICBjYXRlZ29yeSA8LSBuYW1lcyhmcmVxLnRibCksDQogICAgICB2YWx1ZXMgPC0gYXMudmVjdG9yKGZyZXEudGJsKQ0KICApDQogICMgSGlnaC1jb250cmFzdCBjb2xvcnMgKG1hbnVhbGx5IGRlZmluZWQpDQogIGFjY2Vzc2libGVfY29sb3JzIDwtIGMoDQogICcjRDU1RTAwJywgICMgVmVybWlsbGlvbg0KICAnIzAwNzJCMicsICAjIEJsdWUNCiAgJyNGMEU0NDInLCAgIyBZZWxsb3cNCiAgJyMwMDlFNzMnLCAgIyBHcmVlbg0KICAnIzU2QjRFOScsICAjIFNreSBCbHVlDQogICcjRTY5RjAwJywgICMgT3JhbmdlDQogICcjQ0M3OUE3JyAgICMgUGluaw0KICApDQogIGZpZyA8LSBwbG90X2x5KGRmLCB4ID0gfmNhdGVnb3J5LCB5ID0gfnZhbHVlcywgdHlwZSA9ICdiYXInLA0KICAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICd0ZXh0JywNCiAgICAgICAgICAgICAgIHRleHQgPSB+cGFzdGUoJ0NhdGVnb3J5OicsIGNhdGVnb3J5LCAnPGJyPlZhbHVlOicsIHZhbHVlcywgJzxicj5QZXJjZW50YWdlOicsIHJvdW5kKHZhbHVlcy9zdW0odmFsdWVzKSoxMDAsIDEpLCAnJScpLA0KICAgICAgICAgICAgICAgI3RleHQgPSB+cGFzdGUoIlZhbHVlOiIsIHZhbHVlcyksIA0KICAgICAgICAgICAgICAgdGV4dHBvc2l0aW9uID0gJ2F1dG8nLA0KICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgY29sb3IgPSBhY2Nlc3NpYmxlX2NvbG9yc1sxOm5yb3coZGYpXSwNCiAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnYmxhY2snLCB3aWR0aCA9IDIpDQogICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgICAgdGV4dGZvbnQgPSBsaXN0KGNvbG9yID0gJ3doaXRlJywgc2l6ZSA9IDEyKSkgJT4lDQogICBsYXlvdXQoDQogICAjIHRpdGxlID0gbGlzdCh0ZXh0ID0gdmFybmFtZSwgDQogICAgICAgICAgICAgICAgIyBmb250ID0gbGlzdChzaXplID0gMTgsIGNvbG9yID0gJ2JsYWNrJykpLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJDYXRlZ29yaWVzIiwgDQogICAgICAgICAgICAgICAgIHRpY2tmb250ID0gbGlzdChjb2xvciA9ICdibGFjaycpKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiVmFsdWVzIiwgDQogICAgICAgICAgICAgICAgIGdyaWRjb2xvciA9ICdsaWdodGdyYXknLA0KICAgICAgICAgICAgICAgICB0aWNrZm9udCA9IGxpc3QoY29sb3IgPSAnYmxhY2snKSksDQogICAgcGxvdF9iZ2NvbG9yID0gJ3doaXRlJywNCiAgICBwYXBlcl9iZ2NvbG9yID0gJ3doaXRlJywNCiAgICBzaG93bGVnZW5kID0gRkFMU0UsDQogICAgbWFyZ2luID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgIHQgPSAxMDAsICAjIEFkanVzdCB0aGlzIHZhbHVlIHRvIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSB0b3AgbWFyZ2luDQogICAgICAgICAgICAgICAgICBiID0gNTAsDQogICAgICAgICAgICAgICAgICBsID0gNTAsDQogICAgICAgICAgICAgICAgICByID0gNTApDQogICkNCmZpZw0KfQ0KYGBgDQoNCmBgYHtyfQ0KaW4uY2F0LnNleCA8LSAgZmluYWwuYW54aWV0eS5kYXQkc2V4DQppbi5jYXQucmFjZSA8LSAgZmluYWwuYW54aWV0eS5kYXQkcmFjZQ0KaW4uY2F0LmNsYXNzIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRjbGFzcw0KaW4uY2F0Lm1ham9yIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRtYWpvcg0KaW4uY2F0Lm1hdGgubGV2ZWwgPC0gIGZpbmFsLmFueGlldHkuZGF0JG1hdGgubGV2ZWwNCmluLmNhdC5tb2RhbGl0eSA8LSAgZmluYWwuYW54aWV0eS5kYXQkbW9kYWxpdHkNCiMjDQpnLnNleCA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LnNleCwgIkdlbmRlciBEaXN0cmlidXRpb24iKQ0KZy5yYWNlIDwtIERlbW9ncmFwaGljLmJhcihpbi5jYXQucmFjZSwgIlJhY2lhbCBEaXN0cmlidXRpb24iKQ0KZy5jbGFzcyA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LmNsYXNzLCAiQ2xhc3MgRGlzdHJpYnV0aW9uIikNCmcubWFqb3IgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYWpvciwgIk1ham9yIERpc3RyaWJ1dGlvbiIpDQpnLm1hdGgubGV2ZWwgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYXRoLmxldmVsLCAiTWF0aCBDb3Vyc2UgTGV2ZWwiKQ0KZy5tb2RhbGl0eSA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0Lm1vZGFsaXR5LCAiTGVhcm5pbmcgTW9kYWxpdHkiKQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9OH0NCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChnLnNleCwgZy5yYWNlLCBnLmNsYXNzLCBnLm1ham9yLCBucm93cyA9IDIsIHRpdGxlWCA9IEZBTFNFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IC45OSwgdGV4dCA9ICJHZW5kZXIiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJSYWNlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IDAuNCwgdGV4dCA9ICJDbGFzcyBMZXZlbCIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiTWFqb3IiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00fQ0KIyBBcnJhbmdlIGluIDJ4MiBncmlkDQpzdWJwbG90KGcubWF0aC5sZXZlbCwgZy5tb2RhbGl0eSwgbnJvd3MgPSAxLCB0aXRsZVggPSBGQUxTRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMzUsIHkgPSAuOTksIHRleHQgPSAiTWF0aCBDb3Vyc2UgTGV2ZWwiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJMZWFybmluZyBNb2RhbGl0eSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKQ0KICAgICksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCmBgYA0KDQpPbmx5IG9uZSBjYXRlZ29yeSBpbiB2YXJpYWJsZSAqKmNsYXNzKiogaXMgbGVzcyB0aGFuIDMlIHdpdGggMjEgb2JzZXJ2YXRpb25zLiBPdGhlciB2YXJpYWJsZXMgZG9uJ3QgaGF2ZSBpc3N1ZXMgb24gc3BhcnNlIGNhdGVnb3JpZXMuDQoNCiMjIFJlbGF0aW9uc2hpcCBCZXR3ZWVuIE1hdGggQW54aWV0eSBhbmQgRGVtb2dyYXBoaWMgRmFjdG9ycw0KDQpBIHN0dWRlbnQncyBkZW1vZ3JhcGhpYyBwcm9maWxlIGRvZXNuJ3QgZGV0ZXJtaW5lIHRoZWlyIG1hdGggYW54aWV0eSwgYnV0IGl0IHNpZ25pZmljYW50bHkgaW5mbHVlbmNlcyB3aGljaCB0eXBlIG9mIGFueGlldHkgdGhleSBhcmUgbW9zdCB2dWxuZXJhYmxlIHRvIGFuZCB3aHkuIFRoZSBuZXh0IHN1YnNlY3Rpb25zIHByZXNlbnQgdmlzdWFsIGV4cGxvcmF0aW9ucyBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZGVtb2dyYXBoaWMgZmFjdG9ycyBhbmQgdGhlIHR3byBkaW1lbnNpb25zIG9mIG1hdGhlbWF0aWNhbCBhbnhpZXR5Lg0KDQojIyMgTWF0aGVtYXRpY2FsIEV2YWx1YXRpb24gQW54aWV0eQ0KDQpUaGlzIGlzIHRoZSBhbnhpZXR5IGEgc3R1ZGVudCBmZWVscyB3aGVuIHRoZWlyIG1hdGhlbWF0aWNhbCBhYmlsaXR5IGlzIGJlaW5nIGZvcm1hbGx5IG9yIGluZm9ybWFsbHkgYXNzZXNzZWQuIFRoZSBwcmltYXJ5IGZlYXIgaXMgbm90IG9mIHRoZSBtYXRoIGl0c2VsZiwgYnV0IG9mIHRoZSBuZWdhdGl2ZSBjb25zZXF1ZW5jZXMgb2YgcGVyZm9ybWluZyBwb29ybHkuIEl0J3MgcGVyZm9ybWFuY2Utb3JpZW50ZWQuIFRoZSBzdHJlc3MgY29tZXMgZnJvbSB0aGUgc2l0dWF0aW9uIG9mIGJlaW5nIGV2YWx1YXRlZCwgbm90IG5lY2Vzc2FyaWx5IGZyb20gdGhlIGNvbnRlbnQuDQoNCmBgYHtyfQ0KIyMgcGxvdGx5IGZvciBhbnhpZXR5IHZzIGdlbmRlciBhbmQgb3RoZXIgY2F0ZWdvcmljYWwgZGVtb2dyYXBoaWMgZmFjdG9yDQpnZW5kZXIucGxvdGx5IDwtIGZ1bmN0aW9uKGluLnZhcjEsIGluLnZhcjIpew0KICAgICAgZ2VuZGVyLmFueGlldHkgPC0gcGxvdF9seShmaW5hbC5hbnhpZXR5LmRhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfnNleCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gfkFueGlldHkubWVhLnd0LnBjYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGFzLmZvcm11bGEocGFzdGUwKCJ+Iixpbi52YXIxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImJveCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hwb2ludHMgPSAibm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyID0gMC4zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRwb3MgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkgKyB4ICsgbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcnRleHQgPSB+cGFzdGUoIkdyb3VwOiIsIGluLnZhcjEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkZhY3RvcjoiLCBzZXgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlNjb3JlOiIsIHJvdW5kKEFueGlldHkubWVhLnd0LnBjYSwgMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgb3BhY2l0eSA9IDAuNykpICU+JQ0KICAgIGxheW91dCh0aXRsZSA9IHBhc3RlKCJNYXRoIEV2YWx1YXRpb24gQW54aWV0eSAod3QuUENBKTogR2VuZGVyIHZzICIsIGluLnZhcjIsIiIpLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkV2YWx1YXRpb24gQW54aWV0eSBTY29yZSIpLA0KICAgICAgICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgICAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgICAgICAgICkNCg0KIGdlbmRlci5hbnhpZXR5IA0KfQ0KDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1hdGgubGV2ZWwgPSBnZW5kZXIucGxvdGx5KCJtYXRoLmxldmVsIiwgIk1hdGggQ291cnNlIExldmVsIikNCmdlbmRlci5tYXRoLmxldmVsDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLnJhY2UgPSBnZW5kZXIucGxvdGx5KCJyYWNlIiwgIlJhY2UiKQ0KZ2VuZGVyLnJhY2UNCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIuY2xhc3MgPSBnZW5kZXIucGxvdGx5KCJjbGFzcyIsICJDbGFzcyIpDQpnZW5kZXIuY2xhc3MNCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubWFqb3IgPSBnZW5kZXIucGxvdGx5KCJtYWpvciIsICJNYWpvciIpDQpnZW5kZXIubWFqb3INCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubW9kYWxpdHkgPSBnZW5kZXIucGxvdGx5KCJtb2RhbGl0eSIsICJNb2RhbGl0eSIpDQpnZW5kZXIubW9kYWxpdHkNCmBgYA0KDQpTb21lIG9mIHRoZSBwYXR0ZXJucyBvYnNlcnZlZCBpbiB0aGlzIHN0dWR5IGFyZSBjb25zaXN0ZW50IHdpdGggdGhlIGV4aXN0aW5nIGxpdGVyYXR1cmUuDQoNCi0gICBGZW1hbGUgc3R1ZGVudHMgaGF2ZSByZWxhdGl2ZWx5IGhpZ2hlciBldmFsdWF0aW9uIGFueGlldHkgbGV2ZWwgdGhhbiBtYWxlIHN0dWRlbnRzLg0KLSAgIFRoZSBkaXNjcmVwYW5jeSBvZiBldmFsdWF0aW9uIGFueGlldHkgbGV2ZWwgYWNyb3NzIGV0aG5pYyBncm91cHMgYWxzbyBjb25zaXN0ZW50IHdpdGggd2hhdCByZXBvcnRlZCBpbiB0aGUgZXhpc3RpbmcgbGl0ZXJhdHVyZS4NCg0KIyMjIE1hdGhlbWF0aWNhbCBMZWFybmluZyBBbnhpZXR5DQoNCk1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IHN0ZW1zIGRpcmVjdGx5IGZyb20gdGhlIHN1YmplY3QgbWF0dGVyLCB3aGVyZSB0aGUgcHJpbWFyeSBzb3VyY2Ugb2YgZGlzdHJlc3MgaXMgdGhlIGFjdCBvZiBlbmdhZ2luZyB3aXRoIG1hdGhlbWF0aWNhbCBjb25jZXB0cy4gVGhpcyBlbmdhZ2VtZW50IHRyaWdnZXJzIGFuIGludGVybmFsIHN0YXRlIG9mIGNvbmZ1c2lvbiwgZnJ1c3RyYXRpb24sIGFuZCBjb2duaXRpdmUgb3ZlcmxvYWQuDQoNClRoZSBuZXh0IGZldyBmaWd1cmVzIGV4YW1pbmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IGFuZCBkZW1vZ3JhcGhpYyBmYWN0b3JzLCB1c2luZyB0aGUgc2FtZSB2aXN1YWwgYXBwcm9hY2ggYXMgd2UgZGlkIGZvciBtYXRoZW1hdGljYWwgZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQpgYGB7cn0NCiMjIHBsb3RseSBmb3IgYW54aWV0eSB2cyBnZW5kZXIgYW5kIG90aGVyIGNhdGVnb3JpY2FsIGRlbW9ncmFwaGljIGZhY3Rvcg0KZ2VuZGVyLnBsb3RseSA8LSBmdW5jdGlvbihpbi52YXIxLCBpbi52YXIyKXsNCiAgICAgIGdlbmRlci5hbnhpZXR5IDwtIHBsb3RfbHkoZmluYWwuYW54aWV0eS5kYXQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IH5zZXgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IH5BbnhpZXR5Lm1sYS53dC5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBhcy5mb3JtdWxhKHBhc3RlMCgifiIsaW4udmFyMSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJib3giLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94cG9pbnRzID0gIm5vIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlciA9IDAuMywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cG9zID0gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ5ICsgeCArIG5hbWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJ0ZXh0ID0gfnBhc3RlKCJHcm91cDoiLCBpbi52YXIxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5GYWN0b3I6Iiwgc2V4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5TY29yZToiLCByb3VuZChBbnhpZXR5Lm1sYS53dC5wY2EsIDIpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDUsIG9wYWNpdHkgPSAwLjcpKSAlPiUNCiAgICBsYXlvdXQodGl0bGUgPSBwYXN0ZSgiTWF0aCBMZWFybmluZyBBbnhpZXR5ICh3dC5QQ0EpOiBHZW5kZXIgdnMgIiwgaW4udmFyMiwiIiksDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTGVhcm5pbmcgQW54aWV0eSBTY29yZSIpLA0KICAgICAgICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgICAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgICAgICAgICkNCg0KIGdlbmRlci5hbnhpZXR5IA0KfQ0KDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1hdGgubGV2ZWwubWxhID0gZ2VuZGVyLnBsb3RseSgibWF0aC5sZXZlbCIsICJNYXRoIENvdXJzZSBMZXZlbCIpDQpnZW5kZXIubWF0aC5sZXZlbC5tbGENCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIucmFjZS5tbGEgPSBnZW5kZXIucGxvdGx5KCJyYWNlIiwgIlJhY2UiKQ0KZ2VuZGVyLnJhY2UubWxhDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLmNsYXNzLm1sYSA9IGdlbmRlci5wbG90bHkoImNsYXNzIiwgIkNsYXNzIikNCmdlbmRlci5jbGFzcy5tbGENCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubWFqb3IubWxhID0gZ2VuZGVyLnBsb3RseSgibWFqb3IiLCAiTWFqb3IiKQ0KZ2VuZGVyLm1ham9yLm1sYQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5tb2RhbGl0eS5tbGEgPSBnZW5kZXIucGxvdGx5KCJtb2RhbGl0eSIsICJNb2RhbGl0eSIpDQpnZW5kZXIubW9kYWxpdHkubWxhDQpgYGANCg0KIyMgVGhlIEdlbmRlciBHYXAgaW4gRXZhbHVhdGlvbiBhbmQgTGVhcm5pbmcgQW54aWV0eQ0KDQpJdCB0dXJucyBvdXQgdGhhdCwgY29tcGFyaW5nIHRvIG1hdGggbGVhcm5pbmcgYW54aWV0eSwgZXZhbHVhdGlvbiBhbnhpZXR5IG1hbmlmZXN0cyB0aGUgZ2VuZGVyIGdhcC4gVGhpcyBvYnNlcnZhdGlvbiBpcyBzdXBwb3J0ZWQgYnkgYWNhZGVtaWMgcmVzZWFyY2guIFRoZSBrZXkgaW5zaWdodCBpcyB0aGF0IHRoZSBnZW5kZXIgZ2FwIGluIG1hdGggcGVyZm9ybWFuY2UgaXMgbW9yZSBzdHJvbmdseSBsaW5rZWQgdG8gdGhlIGFueGlldHkgZ2VuZXJhdGVkIGJ5IHRoZSB0ZXN0aW5nIHNpdHVhdGlvbiB0aGFuIGJ5IGFueGlldHkgdG93YXJkIHRoZSBzdWJqZWN0IG1hdHRlciBpdHNlbGYgKGxlYWRpbmcgcG90ZW50aWFsIGxlYXJuaW5nIGFueGlldHkpLg0KDQpBIHJvYnVzdCBib2R5IG9mIGV2aWRlbmNlLCBmcm9tIGZvdW5kYXRpb25hbCBtZXRhLWFuYWx5c2VzIChIZW1icmVlLCAxOTkwKSB0byBjb250ZW1wb3Jhcnkgc3R1ZGllcyAoRGV2aW5lIGV0IGFsLiwgMjAxMjsgR29ldHogZXQgYWwuLCAyMDEzKSwgZXN0YWJsaXNoZXMgdGhhdCBmZW1hbGUgc3R1ZGVudHMgZXhwZXJpZW5jZSBkaXNwcm9wb3J0aW9uYXRlbHkgaGlnaCBsZXZlbHMgb2YgbWF0aCB0ZXN0IGFueGlldHktLS1hIGZhY3RvciBtb3JlIHByZWRpY3RpdmUgb2YgYWNhZGVtaWMgb3V0Y29tZXMgdGhhbiBsZWFybmluZyBhbnhpZXR5LiBUaGlzIGZpbmRpbmcgaWxsdW1pbmF0ZXMgdGhlIHdvcmsgb2YgRWxzZS1RdWVzdCBldCBhbC4gKDIwMTApLCBkZW1vbnN0cmF0aW5nIHRoYXQgdGhlIGdlbmRlciBnYXAgaW4gbWF0aCBwZXJmb3JtYW5jZSBpcyBwcm9mb3VuZGx5IHNoYXBlZCBieSBhbnhpZXR5IGluIGV2YWx1YXRpdmUgZW52aXJvbm1lbnRzLiBUaGVyZWZvcmUsIGFkZHJlc3NpbmcgdGhlIHNwZWNpZmljIHByZXNzdXJlcyBvZiB0ZXN0aW5nIHNpdHVhdGlvbnMgaXMgZXNzZW50aWFsIGZvciBjbG9zaW5nIHRoaXMgZ2FwLg0KDQpUaGUgZm9sbG93aW5nIGZpZ3VyZSBpbGx1c3RyYXRlcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZ2VuZGVyIGFuZCB0aGUgdHdvIHR5cGVzIG9mIG1hdGggYW54aWV0eTogbGVhcm5pbmcgYW54aWV0eSBhbmQgZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9DQptZWEwIDwtIGZpbmFsLmFueGlldHkuZGF0WywgYygic2V4IiwgIkFueGlldHkubWVhLnd0LnBjYSIpXQ0KbWxhMCA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoInNleCIsICJBbnhpZXR5Lm1sYS53dC5wY2EiKV0NCm5hbWVzKG1lYTApID0gYygic2V4IiwgImFueGlldHkuc2NvcmUiKQ0KbmFtZXMobWxhMCkgPSBjKCJzZXgiLCAiYW54aWV0eS5zY29yZSIpDQptZWEubWxhIDwtIHJiaW5kKG1lYTAsIG1sYTApDQphbnhpZXR5LnR5cGUgPC0gYyhyZXAoIm1lYSIsIGRpbShtZWEwKVsxXSksIHJlcCgibWxhIiwgZGltKG1lYTApWzFdKSkNCm1lYS5tbGEkYW54aWV0eS50eXBlIDwtIGFueGlldHkudHlwZQ0KIyMjIw0KZGYgPSBuYS5vbWl0KG1lYS5tbGEpDQojIENyZWF0ZSBtb3JlIGNvbXBsZXggZ3JvdXBlZCBib3hwbG90IHdpdGggc3RhdGlzdGljYWwgYW5ub3RhdGlvbnMNCiMgQ3VzdG9tIGhvdmVyIGluZm9ybWF0aW9uDQpmaWcgPC0gcGxvdF9seShkZiwgDQogICAgICAgICAgICAgICB4ID0gfmFueGlldHkudHlwZSwgDQogICAgICAgICAgICAgICB5ID0gfmFueGlldHkuc2NvcmUsIA0KICAgICAgICAgICAgICAgY29sb3IgPSB+c2V4LA0KICAgICAgICAgICAgICAgdHlwZSA9ICJib3giLA0KICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkreCtuYW1lIiwNCiAgICAgICAgICAgICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgNCiAgICAgICAgICAgICAgICAgIkdlbmRlcjogJXt4fTxicj4iLA0KICAgICAgICAgICAgICAgICAiQW54aWV0eSBUeXBlOiAle2Z1bGxEYXRhLm5hbWV9PGJyPiIsDQogICAgICAgICAgICAgICAgICJBbnhpZXR5IFNjb3JlOiAle3k6LjJmfTxicj4iLA0KICAgICAgICAgICAgICAgICAiPGV4dHJhPjwvZXh0cmE+Ig0KICAgICAgICAgICAgICAgKSkgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJHZW5kZXIgRGlzcGFyaXRpZXMgaW4gTWF0aCBFdmFsdWF0aW9uIGFuZCBMZWFybmluZyBBbnhpZXR5IiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkFueGlldHkgU2NvcmUiKSwNCiAgICBib3htb2RlID0gImdyb3VwIiwNCiAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgbWFyZ2luID0gbGlzdCggdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgKQ0KDQpmaWcNCg0KYGBgDQoNCk91ciByZXN1bHRzIGFyZSBhbHNvIGNvbnNpc3RlbnQgd2l0aCBleGlzdGluZyByZXN1bHRzIGluIGxpdGVyYXR1cmUuDQoNCiMgU3R1ZGVudCBQZXJjZWl2ZWQgVGVhY2hpbmcgU3RyYXRlZ2llcywgTWF0aCBBbnhpZXR5LCBhbmQgU2VsZi1lZmZpY2ljYXkNCg0KVGhlIGZvbGxvd2luZyBoZWF0bWFwIGlsbHVzdHJhdGVzIHRoZSBwYWlyd2lzZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiBhbnhpZXR5IGxldmVscywgc3R1ZGVudC1wZXJjZWl2ZWQgdGVhY2hpbmcgc3RyYXRlZ2llcywgYW5kIG90aGVyIGFzc29jaWF0ZWQgY29nbml0aXZlIGZhY3RvcnMuIEEgbmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBhbnhpZXR5IGFuZCBhbm90aGVyIGNvbXBvc2l0ZSBzY29yZSAoc2hvd24gaW4gYmx1ZSkgaW5kaWNhdGVzIHRoYXQgYW54aWV0eSBkZWNyZWFzZXMgYXMgdGhhdCBjb21wb3NpdGUgc2NvcmUgaW5jcmVhc2VzLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9DQoNCnZhci5uYW1lIDwtYyggIkFueGlldHkubWVhLnd0LnBjYSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCAiU2VsZkVmZmljYWN5Lnd0LnBjYSIsICJUZWNobm9sb2d5Lnd0LnBjYSIsDQogICAgICAgICAgICAgICJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsDQogICAgICAgICAgICAgICJJbmR1Y3RpdmUud3QucGNhIiwgIkludGVncmF0aXZlLnd0LnBjYSIsICJMZWN0dXJlVHlwZS53dC5wY2EiLA0KICAgICAgICAgICAgICAiUmVwZXRpdGl2ZS53dC5wY2EiLCAiRW5nYWdlLnd0LnBjYSIsICJSZXNvdXJjZS53dC5wY2EiKQ0KYWxsLmNvbXBvc2l0ZS5zY29yZXMgPC0gZmluYWwuYW54aWV0eS5kYXRbLCB2YXIubmFtZV0NCm5hbWVzKGFsbC5jb21wb3NpdGUuc2NvcmVzKSA8LSBjKCAiQW54aWV0eS5tZWEiLCAiQW54aWV0eS5tbGEiLCAiU2VsZkVmZmljYWN5IiwgIlRlY2hub2xvZ3kiLA0KICAgICAgICAgICAgICAiQ29vcG9yYXRpdmUiLCAiRGVkdWN0aXZlLiIsICJEZW1vbnN0cmF0aW9uIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlVHlwZSIsDQogICAgICAgICAgICAgICJSZXBldGl0aXZlIiwgIkVuZ2FnZSIsICJSZXNvdXJjZS4iKQ0KDQojIENhbGN1bGF0ZSBjb3JyZWxhdGlvbiBtYXRyaXgNCmNvcl9tYXRyaXggPC0gY29yKGFsbC5jb21wb3NpdGUuc2NvcmVzLCB1c2UgPSAiY29tcGxldGUub2JzIikNCg0KIyBDb252ZXJ0IHRvIGxvbmcgZm9ybWF0IHVzaW5nIG1lbHQNCmNvcl9sb25nIDwtIG1lbHQoY29yX21hdHJpeCkNCm5hbWVzKGNvcl9sb25nKSA8LSBjKCJ4IiwgInkiLCAiciIpDQoNCiMgUmVtb3ZlIHNlbGYtY29ycmVsYXRpb25zIGFuZCB1cHBlciB0cmlhbmdsZSBpZiBkZXNpcmVkDQpjb3JfbG9uZyA8LSBjb3JfbG9uZ1tjb3JfbG9uZyR4ICE9IGNvcl9sb25nJHksIF0NCg0KIyBDcmVhdGUgaW50ZXJhY3RpdmUgaGVhdG1hcA0KcGxvdF9seShjb3JfbG9uZywgeCA9IH54LCB5ID0gfnksIHogPSB+ciwgdHlwZSA9ICJoZWF0bWFwIiwNCiAgICAgICAgY29sb3JzY2FsZSA9ICJSZEJ1Iiwgem1pbiA9IC0xLCB6bWF4ID0gMSwNCiAgICAgICAgaG92ZXJpbmZvID0gInRleHQiLA0KICAgICAgICB0ZXh0ID0gfnBhc3RlKCJYOiIsIHgsICI8YnI+WToiLCB5LCAiPGJyPnIgPSIsIHJvdW5kKHIsIDMpKSkgJT4lDQogIGxheW91dCh0aXRsZSA9ICJDb3JyZWxhdGlvbiBNYXRyaXgiLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgbWFyZ2luID0gbGlzdChsID0gMTAwLCByID0gNTAsIGIgPSAxMDAsIHQgPSA1MCkpDQpgYGANCg0KVGhlIGZpZ3VyZSBhYm92ZSBzaG93cyB0aGF0IGFsbCBwZXJjZWl2ZWQgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggYm90aCB0eXBlcyBvZiBhbnhpZXR5LiBJbiBhZGRpdGlvbiwgc3R1ZGVudHMgd2l0aCBoaWdoIGxldmVscyBvZiBzZWxmLWVmZmljYWN5IHRlbmQgdG8gaGF2ZSBsb3cgbGV2ZWxzIG9mIG1hdGggYW54aWV0eS4gRnVydGhlcm1vcmUsIHRoZSBjb21wb3NpdGUgc2NvcmUgZm9yIHRlY2hub2xvZ3kgdXNlIGlzIG5lZ2F0aXZlbHkgY29ycmVsYXRlZCB3aXRoIGJvdGggbGVhcm5pbmcgYW5kIGV2YWx1YXRpb24gYW54aWV0eSwgaW1wbHlpbmcgdGhhdCB0ZWNobm9sb2d5IGNhbiBoZWxwIHJlZHVjZSBtYXRoIGFueGlldHkuIENvbnZlcnNlbHksIHdlIGFsc28gc2VlIHRoYXQgc3R1ZGVudHMgd2hvIHVzZSBtb3JlIGxlYXJuaW5nIHJlc291cmNlcyB0ZW5kIHRvIGhhdmUgaGlnaGVyIGxlYXJuaW5nIGFueGlldHkuDQoNCkluIHRoZSBuZXh0IGZldyBzdWJzZWN0aW9ucywgd2UgYW5hbHl6ZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIHNjYWxlcyBpbiB0aGlzIHN1cnZleSBhbmQgY29tcGFyZSBvdXIgcmVzdWx0cyB3aXRoIHRob3NlIGluIHRoZSBleGlzdGluZyBsaXRlcmF0dXJlLg0KDQojIyBJbnRlcnJlbGF0aW9uc2hpcCBCZXR3ZWVuIEV2YWx1YXRpb24gYW5kIExlYXJuaW5nIEFueGlldGllcw0KDQpBIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdhcyBmb3VuZCBiZXR3ZWVuIG1hdGhlbWF0aWNzIGV2YWx1YXRpb24gYW54aWV0eSBhbmQgbWF0aGVtYXRpY3MgbGVhcm5pbmcgYW54aWV0eSwgd2hpY2ggaXMgY29uc2lzdGVudCB3aXRoIHByZXZpb3VzIHJlc2VhcmNoLg0KDQpNYXRoZW1hdGljcyBsZWFybmluZyBhbnhpZXR5IGlzIG9mdGVuIHRoZSBicm9hZGVyLCBmb3VuZGF0aW9uYWwgaXNzdWUsIHN0ZW1taW5nIGZyb20gbmVnYXRpdmUgZXhwZXJpZW5jZXMgYW5kIGJlbGllZnMgYWJvdXQgb25lJ3Mgb3duIG1hdGhlbWF0aWNhbCBhYmlsaXR5LiBNYXRoZW1hdGljcyB0ZXN0IGFueGlldHkgaXMgYSBtb3JlIHNwZWNpZmljLCBzaXR1YXRpb25hbCBtYW5pZmVzdGF0aW9uIG9mIHRoaXMgYnJvYWRlciBhbnhpZXR5LCB0cmlnZ2VyZWQgYnkgdGhlIGV2YWx1YXRpdmUgcHJlc3N1cmUgb2YgZXhhbXMuDQoNClRoZSBwcmltYXJ5IHJlbGF0aW9uc2hpcCBpcyBjeWNsaWNhbDogbGVhcm5pbmcgYW54aWV0eSBmb3N0ZXJzIHRlc3QgYW54aWV0eSwgYW5kIGEgbmVnYXRpdmUgdGVzdCBleHBlcmllbmNlIHJlaW5mb3JjZXMgbGVhcm5pbmcgYW54aWV0eS4gR2llcmwgYW5kIEJpc2FueiAoMTk5NSkgaGlnaGxpZ2h0ZWQgdGhpcyBjeWNsaWNhbCBuYXR1cmUuIFRoZXkgc3VnZ2VzdGVkIHRoYXQgZWFybHkgbmVnYXRpdmUgZXhwZXJpZW5jZXMgd2l0aCBtYXRoIChsZWFkaW5nIHRvIGxlYXJuaW5nIGFueGlldHkpIHNldCB0aGUgc3RhZ2UgZm9yIGxhdGVyIHRlc3QgYW54aWV0eS4gQ29udmVyc2VseSwgYSBzaW5nbGUgdHJhdW1hdGljIHRlc3QgZXhwZXJpZW5jZSAoZS5nLiwgYSBkaXNhc3Ryb3VzIGZpbmFsIGV4YW0pIGNhbiBnZW5lcmFsaXplIHRvIGEgbG9uZy1sYXN0aW5nLCBwZXJ2YXNpdmUgYW54aWV0eSB0b3dhcmQgYWxsIG1hdGgtcmVsYXRlZCBhY3Rpdml0aWVzLCBzb2xpZGlmeWluZyBsZWFybmluZyBhbnhpZXR5LiBaYWthcmlhIGV0IGFsLiAoMjAxMikgZm91bmQgYSBzaWduaWZpY2FudCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGdlbmVyYWwgbWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgdGVzdCBhbnhpZXR5LiBTdHVkZW50cyB3aG8gYXJlIGFscmVhZHkgYW54aW91cyBpbiBkYWlseSBtYXRoIGNsYXNzZXMgYXJlIHByaW1lZCBmb3IgaGVpZ2h0ZW5lZCBhbnhpZXR5IHdoZW4gdGhlIHN0YWtlcyBhcmUgcmFpc2VkIGluIGEgdGVzdC4NCg0KQm90aCBhbnhpZXRpZXMgb2Z0ZW4gc3RlbSBmcm9tIGNvbW1vbiByb290cywgd2hpY2ggZXhwbGFpbnMgdGhlaXIgaGlnaCBwb3NpdGl2ZSBpbnRlci1yZWxhdGlvbnNoaXAuDQoNCi0gICAqKk5lZ2F0aXZlIFBhc3QgRXhwZXJpZW5jZXMqKjogUmVwZWF0ZWQgZmFpbHVyZSBvciBodW1pbGlhdGlvbiBpbiBtYXRoIGNsYXNzZXMgZHVyaW5nIEstMTIgZWR1Y2F0aW9uIGlzIGEgcG93ZXJmdWwgcHJlZGljdG9yIGZvciBib3RoIHR5cGVzIG9mIGFueGlldHkgaW4gY29sbGVnZSAoTWFsb25leSAmIEJlaWxvY2ssIDIwMTIpLg0KDQotICAgKlNvY2lldGFsIGFuZCBFbnZpcm9ubWVudGFsIEZhY3RvcnMqOiBDdWx0dXJhbCBzdGVyZW90eXBlcyAoZS5nLiwgIm1hdGggaXMgZm9yIGJveXMsIiAic29tZSBwZW9wbGUganVzdCBhcmVuJ3QgbWF0aCBwZW9wbGUiKSBhbmQgdGVhY2hlciBhbnhpZXR5IGNhbiBiZSB0cmFuc21pdHRlZCB0byBzdHVkZW50cywgZm9zdGVyaW5nIGEgZ2VuZXJhbCBzZW5zZSBvZiBhcHByZWhlbnNpb24gdG93YXJkIHRoZSBzdWJqZWN0Lg0KDQotICAgKipGaXhlZCBNaW5kc2V0Kio6IFRoZSB3b3JrIG9mIENhcm9sIER3ZWNrICgyMDA2KSBvbiBtaW5kc2V0IGlzIGhpZ2hseSByZWxldmFudC4gU3R1ZGVudHMgd2l0aCBhICJmaXhlZCBtaW5kc2V0IiAodGhlIGJlbGllZiB0aGF0IG1hdGggYWJpbGl0eSBpcyBhbiBpbm5hdGUsIHVuY2hhbmdlYWJsZSB0cmFpdCkgYXJlIG1vcmUgdnVsbmVyYWJsZSB0byBib3RoIGxlYXJuaW5nIGFuZCB0ZXN0IGFueGlldHkuIEFueSBzdHJ1Z2dsZSBpcyBzZWVuIGFzIGV2aWRlbmNlIG9mIGEgbGFjayBvZiBhYmlsaXR5LCBjYXVzaW5nIHRoZW0gdG8gYXZvaWQgY2hhbGxlbmdpbmcgbGVhcm5pbmcgYW5kIHRvIGNydW1ibGUgdW5kZXIgdGhlIGV2YWx1YXRpdmUgcHJlc3N1cmUgb2YgdGVzdHMuDQoNCiMjIFN0dWRlbnQgUGVyY2VpdmVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KV2UgY2FuIHNlZSBmcm9tIHRoZSBhYm92ZSBjb3JyZWxhdGlvbiBtYXRyaXggKGhlYXRtYXApIHRoYXQgdGhlIHNldmVuIGRpbWVzaW9ucyBvZiBzdHVkZW50IHBlcmNlaXZlZCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFyZSBoaWdobHkgcG9zaXRpdmVseSBjb3JyZWxhdGVkLiBUaGlzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGFtb25nIGRpdmVyc2UgdGVhY2hpbmcgc3RyYXRlZ2llcyBsaWtlIGNvb3BlcmF0aXZlLCBkZWR1Y3RpdmUsIGFuZCBsZWN0dXJlLXR5cGUgbWV0aG9kcyBzdWdnZXN0cyB0aGF0IHN0dWRlbnRzIGRvIG5vdCBuZWNlc3NhcmlseSB2aWV3IHRoZXNlIGFwcHJvYWNoZXMgYXMgbXV0dWFsbHkgZXhjbHVzaXZlLiBJbnN0ZWFkLCB0aGV5IG1heSBwZXJjZWl2ZSB0aGVtIGFzIGNvbXBsZW1lbnRhcnkgdG9vbHMgd2l0aGluIGFuIGVmZmVjdGl2ZSBpbnN0cnVjdG9yJ3MgcmVwZXJ0b2lyZS4gVGhlIHJlYXNvbnMgZm9yIHRoaXMgb2JzZXJ2ZWQgaW50ZXJjb3JyZWxhdGlvbiBjYW4gYmUgYXR0cmlidXRlZCB0byBzZXZlcmFsIGZhY3RvcnMuDQoNCi0gICAqKkluc3RydWN0b3IgVmVyc2F0aWxpdHkgYW5kIFN0cmF0ZWdpYyBCbGVuZGluZyoqOiBBIHNpbmdsZSBsZXNzb24gbWlnaHQgYmVnaW4gd2l0aCBhIGJyaWVmIGxlY3R1cmUgdG8gaW50cm9kdWNlIGEgY29uY2VwdCwgdXNlIGEgZGVtb25zdHJhdGl2ZSBleGFtcGxlLCBhbmQgdGhlbiBlbmdhZ2Ugc3R1ZGVudHMgaW4gYSBjb29wZXJhdGl2ZSBwcm9ibGVtLXNvbHZpbmcgYWN0aXZpdHkgdG8gYXBwbHkgdGhlIGNvbmNlcHQgaW5kdWN0aXZlbHkuIFN0dWRlbnRzIHBlcmNlaXZlIHRoaXMgYmxlbmRpbmcsIGxlYWRpbmcgdG8gcG9zaXRpdmUgY29ycmVsYXRpb25zIGFtb25nIHRoZSBzdHJhdGVnaWVzIHRoZXkgb2JzZXJ2ZS4NCg0KLSAgICoqU3R1ZGVudCBSZWNvZ25pdGlvbiBvZiBhIENvaGVyZW50IExlYXJuaW5nIEN5Y2xlKio6IFN0dWRlbnRzIG1heSBwZXJjZWl2ZSB0aGF0IGRpZmZlcmVudCBzdHJhdGVnaWVzIHNlcnZlIGRpZmZlcmVudCwgYnV0IGludGVyY29ubmVjdGVkLCBwdXJwb3NlcyBpbiB0aGVpciBsZWFybmluZyBqb3VybmV5LiBGb3IgaW5zdGFuY2UsIGEgcmVwZXRpdGl2ZSBwcmFjdGljZSBzZXNzaW9uIG1pZ2h0IGxvZ2ljYWxseSBmb2xsb3cgYSBkZWR1Y3RpdmUgZXhwbGFuYXRpb24gb2YgYSBmb3JtdWxhIHRvIGJ1aWxkIGZsdWVuY3ksIGFuZCBhbiBpbnRlZ3JhdGl2ZSBwcm9qZWN0IG1pZ2h0IGNhcCBhIHVuaXQgdG8gc2hvdyByZWFsLXdvcmxkIGFwcGxpY2F0aW9uLiBXaGVuIHRoZXNlIHN0cmF0ZWdpZXMgYXJlIHNlcXVlbmNlZCBlZmZlY3RpdmVseSwgc3R1ZGVudHMgc2VlIHRoZW0gYXMgcGFydHMgb2YgYSB3aG9sZSwgY29oZXJlbnQgZXhwZXJpZW5jZSwgbGVhZGluZyB0byBwb3NpdGl2ZSByYXRpbmdzIGFjcm9zcyB0aGUgYm9hcmQgKEJvYWxlciwgMjAxNikuDQoNCi0gICAqKlRoZSBIYWxvIEVmZmVjdCBvZiBQZWRhZ29naWNhbCBSaWNobmVzcyoqOiBBIGNsYXNzcm9vbSBlbnZpcm9ubWVudCByaWNoIHdpdGggdmFyaWVkIHBlZGFnb2dpY2FsIGFwcHJvYWNoZXMgaXMgb2Z0ZW4gbW9yZSBlbmdhZ2luZy4gVGhlIHBvc2l0aXZlIGFmZmVjdCBnZW5lcmF0ZWQgYnkgb25lIGVuZ2FnaW5nIHN0cmF0ZWd5IChlLmcuLCBhIGZ1biBjb29wZXJhdGl2ZSBhY3Rpdml0eSkgY2FuIGNyZWF0ZSBhICJoYWxvIGVmZmVjdCwiIGxlYWRpbmcgc3R1ZGVudHMgdG8gcmF0ZSBhbGwgdGhlIHN0cmF0ZWdpZXMgdXNlZCBpbiB0aGF0IHBvc2l0aXZlIGNvbnRleHQgbW9yZSBoaWdobHksIGV2ZW4gdGhlIG1vcmUgdHJhZGl0aW9uYWwgb25lcyBsaWtlIGxlY3R1cmUtdHlwZSBpbnN0cnVjdGlvbiAoSGF0dGllLCAyMDEyKS4NCg0KSG93ZXZlciwgdGhlc2UgY29ycmVsYXRpb25zIGNhbiBhbHNvIGJlIGluZmxhdGVkIGJ5IGdlbmVyYWxpemVkIHN0dWRlbnQgYXR0aXR1ZGVzIHJhdGhlciB0aGFuIHByZWNpc2UgcmVmbGVjdGlvbnMgb2YgZGlzY3JldGUgdGVhY2hpbmcgYWN0cy4gRm9yIGV4YW1wbGUsIHRoZSBjb3JyZWxhdGlvbnMgbWlnaHQgbm90IHJlZmxlY3QgdGhlIGFjdHVhbCBmcmVxdWVuY3kgb2YgdXNlIGJ1dCBhIGdlbmVyYWxpemVkIHN0dWRlbnQgcGVyY2VwdGlvbiBvZiB0aGVpciBpbnN0cnVjdG9yLiBBIHN0dWRlbnQgd2hvIGhvbGRzIGEgcG9zaXRpdmUgb3ZlcmFsbCB2aWV3IG9mIHRoZSB0ZWFjaGVyIG1pZ2h0IHJhdGUgYWxsIHRlYWNoaW5nIHN0cmF0ZWdpZXMgaGlnaGx5LCByZWdhcmRsZXNzIG9mIGhvdyBlZmZlY3RpdmVseSBlYWNoIHdhcyBpbmRpdmlkdWFsbHkgZGVwbG95ZWQuIFRoaXMgaXMgYSBjb21tb24gZm9ybSBvZiByZXNwb25zZSBiaWFzIGluIHN0dWRlbnQgZXZhbHVhdGlvbnMgKFNwb29yZW4gZXQgYWwuLCAyMDEzKS4NCg0KVGhlIGNvcnJlbGF0aW9uIG1pZ2h0IGFsc28gYmUgY29uZm91bmRlZCBkdWUgdG8gbGFjayBvZiBkaXNjcmltaW5hbnQgdmFsaWRpdHkgaW4gcGVyY2VwdGlvbi4gRm9yIGV3eGFtcGxlLCBzdHVkZW50cywgZXNwZWNpYWxseSB0aG9zZSB3aXRob3V0IHBlZGFnb2dpY2FsIHRyYWluaW5nLCBtYXkgbm90IGZpbmVseSBkaXNjcmltaW5hdGUgYmV0d2VlbiB0aGUgbnVhbmNlZCBkZWZpbml0aW9ucyBvZiBlYWNoIHN0cmF0ZWd5LiBUaGV5IG1pZ2h0IGJyb2FkbHkgcGVyY2VpdmUgInRoZSB0ZWFjaGVyIGV4cGxhaW5zIHRoaW5ncyBjbGVhcmx5LCIgd2hpY2ggY291bGQgbGVhZCB0aGVtIHRvIHJhdGUgZGVkdWN0aXZlLCBkZW1vbnN0cmF0aXZlLCBhbmQgaW50ZWdyYXRpdmUgc3RyYXRlZ2llcyBzaW1pbGFybHkgYmVjYXVzZSB0aGV5IGFsbCBjb250cmlidXRlIHRvIHRoYXQgb3ZlcmFyY2hpbmcgZmVlbGluZyBvZiBjbGFyaXR5Lg0KDQojIyBUaGUgVHJpYWQgb2YgQW54aWV0eSwgU2VsZi1FZmZpY2FjeSwgYW5kIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KTWF0aCBzZWxmLWVmZmljYWN5LCBhIGNvbmNlcHQgZGVyaXZlZCBmcm9tIEFsYmVydCBCYW5kdXJhJ3Mgc29jaWFsIGNvZ25pdGl2ZSB0aGVvcnksIHJlZmVycyB0byBhbiBpbmRpdmlkdWFsJ3MgY29udmljdGlvbiBpbiB0aGVpciBhYmlsaXR5IHRvIHN1Y2Nlc3NmdWxseSBwZXJmb3JtIHNwZWNpZmljIG1hdGhlbWF0aWNhbCB0YXNrcy4gSXQgaXMgbm90IGEgZ2VuZXJhbCBmZWVsaW5nIG9mIGNvbmZpZGVuY2UgYnV0IGEgc2l0dWF0aW9uLXNwZWNpZmljIGJlbGllZiBhbmQgYSByb2J1c3QgcHJlZGljdG9yIG9mIHBlcnNldmVyYW5jZSwgZW5nYWdlbWVudCwgYW5kIGFjYWRlbWljIHN1Y2Nlc3MgaW4gbWF0aGVtYXRpY3MgKEJhbmR1cmEsIDE5OTcpLg0KDQpDb252ZXJzZWx5LCBtYXRoIGFueGlldHkgaXMgYSBzdGF0ZSBvZiB0ZW5zaW9uLCBhcHByZWhlbnNpb24sIG9yIGZlYXIgdGhhdCBpbnRlcmZlcmVzIHdpdGggbWF0aCBwZXJmb3JtYW5jZS4gSXQgaXMgbW9yZSB0aGFuIGEgc2ltcGxlIGRpc2xpa2U7IGl0IGlzIGEgZGViaWxpdGF0aW5nIGVtb3Rpb25hbCByZWFjdGlvbiB0aGF0IGNhbiBjcmVhdGUgYSB2aWNpb3VzIGN5Y2xlOiBhbnhpZXR5IGxlYWRzIHRvIGF2b2lkYW5jZSwgd2hpY2ggbGVhZHMgdG8gcG9vcmVyIHNraWxscywgd2hpY2ggaW4gdHVybiBoZWlnaHRlbnMgYW54aWV0eSAoQXNoY3JhZnQsIDIwMDIpLg0KDQpUaGVzZSB0d28gY29uc3RydWN0cyBhcmUgdHlwaWNhbGx5IHN0cm9uZ2x5IGFuZCBpbnZlcnNlbHkgY29ycmVsYXRlZC4gQSBzdHVkZW50IHdpdGggaGlnaCBzZWxmLWVmZmljYWN5IGlzIGxlc3MgbGlrZWx5IHRvIGV4cGVyaWVuY2UgYW54aWV0eSB3aGVuIGZhY2VkIHdpdGggYSBtYXRoIHByb2JsZW0sIHdoaWxlIGEgc3R1ZGVudCB3aXRoIGhpZ2ggYW54aWV0eSB3aWxsIGxpa2VseSBoYXZlIHRoZWlyIHNlbnNlIG9mIGVmZmljYWN5IGVyb2RlZC4NCg0KQ3JpdGljYWxseSwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgbm90IG1lcmVseSBtZXRob2RzIG9mIGNvbnRlbnQgZGVsaXZlcnk7IHRoZXkgYXJlIHBvd2VyZnVsIGVudmlyb25tZW50YWwgZm9yY2VzIHRoYXQgZGlyZWN0bHkgc2hhcGUgc3R1ZGVudHMnIGVtb3Rpb25hbCBhbmQgc2VsZi1ldmFsdWF0aXZlIGxhbmRzY2FwZXMuIFRvZ2V0aGVyLCB0aGUgdHJpYWQgb2YgUGVyY2VpdmVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMsIE1hdGggQW54aWV0eSwgYW5kIE1hdGggU2VsZi1FZmZpY2FjeSBmb3JtcyBhIGR5bmFtaWMsIGludGVyY29ubmVjdGVkIHN5c3RlbSB0aGF0IHNpZ25pZmljYW50bHkgaW5mbHVlbmNlcyBhIHN0dWRlbnQncyBtYXRoIGFjaGlldmVtZW50IGFuZCBvdmVyYWxsIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBzdWJqZWN0Lg0KDQpUaGUgcmVsYXRpb25zaGlwcyB3aXRoaW4gdGhpcyB0cmlhZCBhcmUgcmVjaXByb2NhbC4gQSBzdHVkZW50IHdpdGggaGlnaCBtYXRoIHNlbGYtZWZmaWNhY3kgbWF5IHRocml2ZSBpbiBhIGZhc3QtcGFjZWQgbGVjdHVyZSwgdmlld2luZyBpdCBhcyBhbiBlZmZpY2llbnQgd2F5IHRvIGFjcXVpcmUgaW5mb3JtYXRpb24uIEFuIGFueGlvdXMgc3R1ZGVudCBpbiB0aGUgc2FtZSBlbnZpcm9ubWVudCwgaG93ZXZlciwgbWF5IGJlY29tZSBvdmVyd2hlbG1lZCBhbmQgZGlzZW5nYWdlZC4gRnVydGhlcm1vcmUsIHN0dWRlbnRzIHdpdGggaGlnaCBhbnhpZXR5IG1heSBhY3RpdmVseSBhdm9pZCBwYXJ0aWNpcGF0aW5nIGluIGNvb3BlcmF0aXZlIGdyb3VwcyBmb3IgZmVhciBvZiBiZWluZyBqdWRnZWQsIHRoZXJlYnkgbWlzc2luZyBvdXQgb24gdGhlIHZlcnkgZXhwZXJpZW5jZXMgdGhhdCBjb3VsZCBidWlsZCB0aGVpciBjb25maWRlbmNlLiBJbiB0aGlzIHdheSwgYSBzdHVkZW50J3MgcHJlLWV4aXN0aW5nIGFueGlldHkgYW5kIHNlbGYtZWZmaWNhY3kgZGlyZWN0bHkgc2hhcGUgdGhlaXIgcGVyY2VwdGlvbiBvZiBhbmQgcmVzcG9uc2UgdG8gdGhlIGxlYXJuaW5nIGVudmlyb25tZW50IGl0c2VsZi4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjcwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJUZWNoaW5nU3RyYXRlZ2llcy1BbnhpZXR5LVNlbGYtZWZmaWNhY3kucG5nIikNCmBgYA0KDQojIyBHcm91cGluZyBUZWFjaGluZyBTdHJhdGVnaWVzDQoNClRoZSBmb2xsb3dpbmcgZGVuc2l0eSBjdXJ2ZXMgcmVwcmVzZW50ICpuYWl2ZSogY29tcG9zaXRlIHNjb3JlcyBkZXJpdmVkIGZyb20gdGhlIGF2ZXJhZ2Ugb2YgaXRlbSBzY29yZXMgZm9yIGVhY2ggb2YgdGhlIHNldmVuIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIFRoZXNlIGN1cnZlcyBpbGx1c3RyYXRlIHRoZSBzdHVkZW50cycgcGVyY2VwdGlvbnMgb2YgdGhlaXIgaW5zdHJ1Y3RvcnMnIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIEEgaGlnaGVyIHNjb3JlIGluZGljYXRlcyB0aGF0IHN0dWRlbnRzIHdlcmUgbW9yZSBsaWtlbHkgdG8gcGVyY2VpdmUgdGhlIHVzZSBvZiB0aGF0IHN0cmF0ZWd5Lg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsIHdhcm5pbmcgPSBGQUxTRX0NCnZhci5uYW1lIDwtYyggIkNvb3BvcmF0aXZlLmF2ZyIsICJEZWR1Y3RpdmUuYXZnIiwgIkRlbW9uc3RyYXRpb24uYXZnIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZS5hdmciLCAiSW50ZWdyYXRpdmUuYXZnIiwgIkxlY3R1cmVUeXBlLmF2ZyIsDQogICAgICAgICAgICAgICJSZXBldGl0aXZlLmF2ZyIpDQphbGwuY29tcG9zaXRlLnNjb3JlcyA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIHZhci5uYW1lXQ0KbmFtZXMoYWxsLmNvbXBvc2l0ZS5zY29yZXMpIDwtIGMoIkNvb3BlcmF0aXZlIiwgIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlIiwgICAiUmVwZXRpdGl2ZSIpDQoNCiMgRm9yIG9sZGVyIHZlcnNpb25zIG9mIHRpZHlyDQpsb25nX2RhdGEgPC0gYWxsLmNvbXBvc2l0ZS5zY29yZXMgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gYyggQ29vcGVyYXRpdmUsIERlZHVjdGl2ZSwgRGVtb25zdHJhdGl2ZSwgSW5kdWN0aXZlLCBJbnRlZ3JhdGl2ZSwgTGVjdHVyZSwgUmVwZXRpdGl2ZSksICAjIENvbHVtbnMgdG8gcmVzaGFwZQ0KICAgIG5hbWVzX3RvID0gInZhcmlhYmxlIiwgICAgICAgICAgIyBOZXcgY29sdW1uIG5hbWUgZm9yIHZhcmlhYmxlIG5hbWVzDQogICAgdmFsdWVzX3RvID0gInZhbHVlIiAgICAgICAgICAgICAjIE5ldyBjb2x1bW4gbmFtZSBmb3IgdmFsdWVzDQogICkNCg0KIyMgU3VtbWFyaXplZCBzdGF0cw0KDQpzdW1tYXJ5X3N0YXRzIDwtIGxvbmdfZGF0YSAlPiUNCiAgZ3JvdXBfYnkodmFyaWFibGUpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbl92YWwgPSBtZWFuKHZhbHVlKSwNCiAgICBtZWRpYW5fdmFsID0gbWVkaWFuKHZhbHVlKSwNCiAgICBzZF92YWwgPSBzZCh2YWx1ZSksDQogICAgbiA9IG4oKSwNCiAgICAuZ3JvdXBzID0gJ2Ryb3AnDQogICkNCg0KIyBDcmVhdGUgcmlkZ2UgcGxvdCB3aXRoIGdncmlkZ2VzIGFuZCBjb252ZXJ0IHRvIHBsb3RseQ0KcmlkZ2VfZ2cgPC0gZ2dwbG90KGxvbmdfZGF0YSwgYWVzKHggPSB2YWx1ZSwgeSA9IHZhcmlhYmxlLCBmaWxsID0gdmFyaWFibGUNCiAgKSkgKw0KICBnZW9tX2RlbnNpdHlfcmlkZ2VzKA0KICAgIGFscGhhID0gMC43LA0KICAgIHNjYWxlID0gMiwgICMgQWRqdXN0IG92ZXJsYXANCiAgICBjb2xvciA9ICJ3aGl0ZSIsDQogICAgc2l6ZSA9IDAuNSwNCiAgICAgKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgI3RoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkgKw0KICB0aGVtZV9yaWRnZXMoKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9ucyBvZiBTdHVkZW50cycgUGVyY2VpdmVkIFxuIFRlYWNoaW5nIFN0cmF0ZWd5IEluZGljZXMiLA0KICAgIHggPSAiUGVyY2VpdmVkIFRlYWNoaW5nIFN0cmF0ZWd5IFNjb3JlIiwNCiAgICB5ID0gIiINCiAgKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSAxLjIsIHVuaXQgPSAiY20iKSkNCg0KIyBDb252ZXJ0IHRvIHBsb3RseQ0KZ2dwbG90bHkocmlkZ2VfZ2cpDQpgYGANCg0KQXMgc2hvd24gaW4gdGhlIGZpZ3VyZSwgdGhlICoqcmVwZXRpdGl2ZSoqLCAqKmxlY3R1cmUtdHlwZSoqLCAqKmluZHVjdGl2ZSoqLCBhbmQgKipkZW1vbnN0cmF0aXZlKiogYXBwcm9hY2hlcyB3ZXJlIHBlcmNlaXZlZCBhcyBtb3JlIHBvcHVsYXIgdGhhbiB0aGUgKippbnRlZ3JhdGl2ZSoqLCAqKmRlZHVjdGl2ZSoqLCBhbmQgKipjb29wZXJhdGl2ZSoqIGFwcHJvYWNoZXMuIFRoaXMgb2JzZXJ2YXRpb24gYWxpZ25zIHdpdGggdGhlIGVzdGFibGlzaGVkIGNsYXNzaWZpY2F0aW9uIG9mIHRlYWNoaW5nIHN0eWxlcyBpbiBlZHVjYXRpb25hbCBhbmQgcHN5Y2hvbG9naWNhbCByZXNlYXJjaCBhbmQgY2xhc3NpYyB0ZXh0Ym9va3MuDQoNCnwgVGVhY2hlci1jZW50ZXJlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTdHVkZW50LWNlbnRlcmVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCAqKkRlZHVjdGl2ZSoqIChUZWFjaGVyIHByb3ZpZGVzIHJ1bGVzIGFuZCBleGFtcGxlczogSm95Y2UgZXQgYWwuLCAyMDE1KSB8ICoqQ29vcGVyYXRpdmUqKiAoU3R1ZGVudHMgd29yayB0b2dldGhlcjogSm9obnNvbiwgMjAxNCkgICAgICAgICAgICAgICAgICAgICAgfA0KfCAqKkxlY3R1cmUgVHlwZSoqIChUZWFjaGVyIHRyYW5zbWl0cyBpbmZvcm1hdGlvbjogQnJvd24sMjAwNykgICAgICAgICAgICB8ICoqSW5kdWN0aXZlKiogKFN0dWRlbnRzIGRpc2NvdmVyIHJ1bGVzOiBCcnVuZXIsIDE5NjE7IFByaW5jZSAmIEZlbGRlciwgMjAwNikgfA0KfCAqKkRlbW9uc3RyYXRpdmUqKiAoVGVhY2hlciBzaG93cyBob3c6IEJvcmljaCwgMjAxNykgICAgICAgICAgICAgICAgICAgICB8ICoqSW50ZWdyYXRpdmUqKiAoU3R1ZGVudHMgY29ubmVjdCBpZGVhczogSmFjb2JzLCAxOTg5OyBGb2dhcnR5LDE5OTEpICAgICAgICAgfA0KfCAqKlJlcGV0aXRpdmUqKiAoVGVhY2hlciBkcmlsbHMgdGhlIGluZm9ybWF0aW9uOiBPcm1yb2QsIDIwMjApICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KDQpUaGUgYWJvdmUgY2xhc3NpZmljYXRpb24gaXMgY29uc2lzdGVudCB3aXRoIHRoZSBvbmUgYmFzZWQgb24gY29nbml0aXZlIGRlbWFuZCAoQmxvb20ncyBUYXhvbm9teSksIHdoaWNoIGNhdGVnb3JpemVzIHN0cmF0ZWdpZXMgYXMgcmVxdWlyaW5nIGVpdGhlciBsb3dlci1sZXZlbCB0aGlua2luZyAocmVtZW1iZXIsIHVuZGVyc3RhbmQpIG9yIGhpZ2hlci1sZXZlbCB0aGlua2luZyAoYXBwbHksIGFuYWx5emUsIGV2YWx1YXRlLCBjcmVhdGUpLg0KDQoqKk5vdGUqKjogVGhlICoqRGVtb25zdHJhdGl2ZSBBcHByb2FjaCBzdWItc2NhbGUqKiBpbiB0aGlzIHN1cnZleSBtZWFzdXJlcyBjb25zdHJ1Y3RzIGFzc29jaWF0ZWQgd2l0aCBib3RoICoqVHJhZGl0aW9uYWwgVGVhY2hlci1DZW50ZXJlZCoqIGFuZCAqKlN0dWRlbnQtQ2VudGVyZWQgU3RyYXRlZ2llcyoqLiBJdCBlbmNvbXBhc3NlcyBub3Qgb25seSB0aGUgdGVhY2hlcidzIGRpcmVjdCBkZW1vbnN0cmF0aW9uIG9mIGtub3dsZWRnZSBidXQgYWxzbyB0aGUgdXNlIG9mIHRoZXNlIGRlbW9uc3RyYXRpb25zIHRvIGZhY2lsaXRhdGUgc3R1ZGVudC1sZWQgc29sdXRpb24gYnVpbGRpbmcsIGNoYXJhY3Rlcml6aW5nIGl0IGFzIGEgaHlicmlkIHRlYWNoaW5nIHN0cmF0ZWd5Lg0KDQpUaGlzIGNsYXNzaWZpY2F0aW9uIGRlbW9uc3RyYXRlcyBhIHNwZWN0cnVtIG9mIHBlZGFnb2dpY2FsIGFwcHJvYWNoZXMsIGZyb20gdHJhZGl0aW9uYWwsIGhpZ2hseSBzdHJ1Y3R1cmVkIG1ldGhvZHMgbGlrZSBMZWN0dXJlIGFuZCBEZWR1Y3RpdmUgdGVhY2hpbmcsIHRvIG1vZGVybiwgc3R1ZGVudC1kcml2ZW4gbWV0aG9kcyBsaWtlIEluZHVjdGl2ZSwgQ29vcGVyYXRpdmUsIGFuZCBJbnRlZ3JhdGl2ZSBsZWFybmluZy4gRGVtb25zdHJhdGlvbiBhbmQgUmVwZXRpdGl2ZSBwcmFjdGljZSBzZXJ2ZSBzcGVjaWZpYywgb2Z0ZW4gY29tcGxlbWVudGFyeSwgcm9sZXMgd2l0aGluIHRoaXMgc3BlY3RydW0uDQoNCiMjIFRlYWNoaW5nIFN0cmF0ZWdpZXMgTW9kdWxhdGUgdGhlIFRyaWFkDQoNClRlYWNoaW5nIHN0cmF0ZWdpZXMgYXJlIG5vdCBtZXJlbHkgbWV0aG9kcyBvZiBjb250ZW50IGRlbGl2ZXJ5OyB0aGV5IGFyZSBwb3dlcmZ1bCBlbnZpcm9ubWVudGFsIGZvcmNlcyB0aGF0IGRpcmVjdGx5IHNoYXBlIHN0dWRlbnRzJyBlbW90aW9uYWwgYW5kIHNlbGYtZXZhbHVhdGl2ZSBsYW5kc2NhcGVzLg0KDQoqKlRlYWNoZXItQ2VudGVyZWQgU3RyYXRlZ2llcyoqDQoNCi0gICAqKkxlY3R1cmUtdHlwZSBhbmQgRGVkdWN0aXZlIEFwcHJvYWNoZXMqKjogVGhlc2UgbWV0aG9kcywgd2hlcmUgdGhlIGluc3RydWN0b3IgcHJlc2VudHMgZXN0YWJsaXNoZWQgcnVsZXMgYW5kIHByb2NlZHVyZXMgZmlyc3QgKGRlZHVjdGl2ZSkgaW4gYSBsYXJnZWx5IG9uZS13YXkgZm9ybWF0IChsZWN0dXJlKSwgY2FuIGluYWR2ZXJ0ZW50bHkgZXhhY2VyYmF0ZSB0aGUgdHJpYWQncyBuZWdhdGl2ZSBwb3RlbnRpYWwuIEZvciBhIHN0dWRlbnQgd2l0aCBsb3cgc2VsZi1lZmZpY2FjeSBvciBoaWdoIGFueGlldHksIHRoZSByYXBpZCwgaW1wZXJzb25hbCBwYWNlIG9mIGEgbGVjdHVyZSBjYW4gcmVpbmZvcmNlIGZlZWxpbmdzIG9mIGluYWRlcXVhY3kgYW5kIGluYWJpbGl0eSB0byBrZWVwIHVwLiBUaGUgZm9jdXMgb24gYSBzaW5nbGUgImNvcnJlY3QiIG1ldGhvZCBjYW4gc3RpZmxlIHRoZSBleHBsb3JhdG9yeSBiZWhhdmlvcnMgdGhhdCBidWlsZCBnZW51aW5lIHVuZGVyc3RhbmRpbmcgYW5kIGNvbmZpZGVuY2UuDQoNCi0gICAqKlJlcGV0aXRpdmUgKERyaWxsLWFuZC1QcmFjdGljZSkgQXBwcm9hY2gqKjogV2hpbGUgbmVjZXNzYXJ5IGZvciBkZXZlbG9waW5nIHByb2NlZHVyYWwgZmx1ZW5jeSwgYW4gb3Zlci1yZWxpYW5jZSBvbiByZXBldGl0aXZlIHByYWN0aWNlIGNhbiBiZSBhIGRvdWJsZS1lZGdlZCBzd29yZC4gRm9yIGhpZ2hseSBlZmZpY2FjaW91cyBzdHVkZW50cywgaXQgY2FuIHNvbGlkaWZ5IHNraWxscy4gSG93ZXZlciwgZm9yIGFueGlvdXMgc3R1ZGVudHMsIGl0IGNhbiBiZWNvbWUgYSBzb3VyY2Ugb2YgaW1tZW5zZSBzdHJlc3MsIGZyYW1pbmcgbWF0aGVtYXRpY3MgYXMgYSBtb25vdG9ub3VzLCBwZXJmb3JtYW5jZS1vcmllbnRlZCBzdWJqZWN0IHdoZXJlIG1pc3Rha2VzIGFyZSBmYWlsdXJlcy4gVGhpcyBjYW4gZGlyZWN0bHkgdW5kZXJtaW5lIHNlbGYtZWZmaWNhY3ksIGFzIG5vdGVkIGJ5IHJlc2VhcmNoZXJzIHdobyBmb3VuZCB0aGF0IGVudmlyb25tZW50cyBvdmVybHkgZm9jdXNlZCBvbiBzcGVlZCBhbmQgY29ycmVjdCBhbnN3ZXJzIGluY3JlYXNlIGFueGlldHkgKFJhbWlyZXogZXQgYWwuLCAyMDE4KS4NCg0KKipTdHVkZW50LUNlbnRlcmVkIFN0cmF0ZWdpZXMqKg0KDQotICAgKipJbmR1Y3RpdmUgYW5kIERlbW9uc3RyYXRpdmUgQXBwcm9hY2hlcyoqOiBUaGVzZSBzdHJhdGVnaWVzLCB3aGljaCBpbnZvbHZlIHByZXNlbnRpbmcgc3BlY2lmaWMgZXhhbXBsZXMgb3IgcGhlbm9tZW5hIGZyb20gd2hpY2ggc3R1ZGVudHMgZGVyaXZlIHBhdHRlcm5zIGFuZCBydWxlcyAoaW5kdWN0aXZlKSBvciB2aXN1YWxseSBpbGx1c3RyYXRpbmcgYSBjb25jZXB0IChkZW1vbnN0cmF0aXZlKSwgYWN0aXZlbHkgZW5nYWdlIHN0dWRlbnRzIGluIHRoZSBwcm9jZXNzIG9mICJkb2luZyBtYXRoZW1hdGljcy4iIEJ5IGRpc2NvdmVyaW5nIHJlbGF0aW9uc2hpcHMgdGhlbXNlbHZlcywgc3R1ZGVudHMgYnVpbGQgYSBtb3JlIHJvYnVzdCBhbmQgcGVyc29uYWwgdW5kZXJzdGFuZGluZy4gVGhpcyBwcm9jZXNzIG9mIHN1Y2Nlc3NmdWwgZGlzY292ZXJ5IGlzIGEgcG90ZW50IHNvdXJjZSBvZiBtYXN0ZXJ5IGV4cGVyaWVuY2UsIHRoZSBtb3N0IGluZmx1ZW50aWFsIHNvdXJjZSBvZiBzZWxmLWVmZmljYWN5IChCYW5kdXJhLCAxOTk3KS4gQXMgdW5kZXJzdGFuZGluZyBkZWVwZW5zLCBhbnhpZXR5IG9mdGVuIGRpbWluaXNoZXMgYmVjYXVzZSB0aGUgc3ViamVjdCBmZWVscyBsZXNzIG15c3RlcmlvdXMgYW5kIG1vcmUgbWFuYWdlYWJsZS4NCg0KLSAgICoqQ29vcGVyYXRpdmUgTGVhcm5pbmc6KiogVGhpcyBpcyBwZXJoYXBzIG9uZSBvZiB0aGUgbW9zdCBwb3dlcmZ1bCBzdHJhdGVnaWVzIGZvciBwb3NpdGl2ZWx5IGluZmx1ZW5jaW5nIHRoZSB0cmlhZC4gV29ya2luZyBpbiBzbWFsbCBncm91cHMgb24gbWVhbmluZ2Z1bCB0YXNrcyBwcm92aWRlcyBtdWx0aXBsZSBwc3ljaG9sb2dpY2FsIGJlbmVmaXRzOg0KDQogICAgLSAgICpWaWNhcmlvdXMgRXhwZXJpZW5jZSo6IFN0dWRlbnRzIG9ic2VydmUgcGVlcnMsIHdobyB0aGV5IHBlcmNlaXZlIGFzIHNpbWlsYXIgdG8gdGhlbXNlbHZlcywgc3VjY2Vzc2Z1bGx5IHNvbHZpbmcgcHJvYmxlbXMuIFRoaXMgaXMgYSBrZXkgc291cmNlIG9mIHNlbGYtZWZmaWNhY3ksIHNob3dpbmcgdGhlbSB0aGF0ICJpZiB0aGV5IGNhbiBkbyBpdCwgc28gY2FuIEkuIg0KICAgIC0gICAqVmVyYmFsIFBlcnN1YXNpb24qOiBQZWVycyBhbmQgdGhlIHRlYWNoZXIgY2FuIG9mZmVyIGVuY291cmFnZW1lbnQgYW5kIGZlZWRiYWNrIHdpdGhpbiBhIHN1cHBvcnRpdmUsIGxvdy1zdGFrZXMgc2V0dGluZy4NCiAgICAtICAgKlJlZHVjZWQgQW54aWV0eSo6IFRoZSBidXJkZW4gb2YgcGVyZm9ybWFuY2UgaXMgc2hhcmVkLCBtaXRpZ2F0aW5nIHRoZSBmZWFyIG9mIHB1YmxpYyBmYWlsdXJlIHRoYXQgY2FuIG9jY3VyIHdoZW4gYSBzdHVkZW50IGlzIGNhbGxlZCBvbiBhbG9uZSBpbiBhIHdob2xlLWNsYXNzIHNldHRpbmcuIFN0dWRpZXMgY29uc2lzdGVudGx5IHNob3cgdGhhdCBjb29wZXJhdGl2ZSBsZWFybmluZyBlbnZpcm9ubWVudHMgYXJlIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBsZXZlbHMgb2YgbWF0aCBhbnhpZXR5IGFuZCBoaWdoZXIgbGV2ZWxzIG9mIHNlbGYtZWZmaWNhY3kgYW5kIGFjaGlldmVtZW50Lg0KDQotICAgKipJbnRlZ3JhdGl2ZSBBcHByb2FjaCoqOiBDb25uZWN0aW5nIG1hdGhlbWF0aWNzIHRvIHJlYWwtd29ybGQgcHJvYmxlbXMgYW5kIG90aGVyIGRpc2NpcGxpbmVzIG1ha2VzIHRoZSBzdWJqZWN0IGZlZWwgcmVsZXZhbnQgYW5kIG1lYW5pbmdmdWwuIFRoaXMgY2FuIGhlbHAgc3R1ZGVudHMgcmVmcmFtZSBtYXRoIGZyb20gYSBzZXQgb2YgYWJzdHJhY3QsIGludGltaWRhdGluZyBydWxlcyB0byBhIHVzZWZ1bCB0b29sIGZvciB1bmRlcnN0YW5kaW5nIHRoZSB3b3JsZC4gVGhpcyBwZXJjZWl2ZWQgdXRpbGl0eSBjYW4gaW5jcmVhc2UgbW90aXZhdGlvbiBhbmQgZW5nYWdlbWVudCwgd2hpY2ggaW4gdHVybiBjYW4gYm9sc3RlciBzZWxmLWVmZmljYWN5IGFuZCByZWR1Y2UgYW54aWV0eSBieSBwcm92aWRpbmcgYSBjb21wZWxsaW5nIHJlYXNvbiB0byBwZXJzaXN0IHRocm91Z2ggY2hhbGxlbmdlcy4NCg0KIyMgQ3JlYXRlIFNpbmdsZSBDb21wb3NpdGUgU2NvcmUgZm9yIHRoZSBDbGFzc2lmaWNhdGlvbg0KDQpXZSBuZXh0IGRlZmluZSB0d28gc2luZ2xlIGluZGljZXMgdG8gcmVwcmVzZW50IHRoZSB0ZWFjaGluZyBzdHJhdGVnaWVzIGJhc2VkIG9uIHRoZSBhYm92ZSBjbGFzc2lmaWNhdGlvbi4gV2UgY29uY2VwdHVhbGl6ZSB0ZWFjaGVyLWNlbnRlcmVkIGFuZCBzdHVkZW50LWNlbnRlcmVkIHN0cmF0ZWdpZXMgYXMgdHdvIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0cy4gVGhlIGluZGljZXMgYXJlIGRlZmluZWQgdXNpbmcgYSBkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSBvZiB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMuIEZvbGxvd2luZyBjb21tb24gcHJhY3RpY2UsIHdlIHJlcG9ydCB0aGUgdmFsaWRpdHkgYW5kIHJlbGlhYmlsaXR5IG1lYXN1cmVzIGJlZm9yZSBjYWxjdWxhdGluZyB0aGUgY29tcG9zaXRlIHNjb3JlcyBmb3IgdGhlIHR3byBjbGFzc2lmaWVkIHRlYWNoaW5nIHN0cmF0ZWdpZXMuDQoNCioqVmFsaWRpdHkgTWVhc3VyZXMqKg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCnZhci5uYW1lIDwtYygiQ29vcG9yYXRpdmUuY2ZhIiwgIkRlZHVjdGl2ZS5jZmEiLCAiRGVtb25zdHJhdGlvbi5jZmEiLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlLmNmYSIsICJJbnRlZ3JhdGl2ZS5jZmEiLCAiTGVjdHVyZVR5cGUuY2ZhIiwNCiAgICAgICAgICAgICAgIlJlcGV0aXRpdmUuY2ZhIikNClN0cmF0ZWdlLnd0LnBjYSA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIHZhci5uYW1lXQ0KbmFtZXMoU3RyYXRlZ2Uud3QucGNhKSA8LSBjKCJDb29wZXJhdGl2ZSIsICJEZWR1Y3RpdmUiLCAiRGVtb25zdHJhdGl2ZSIsDQogICAgICAgICAgICAgICJJbmR1Y3RpdmUiLCAiSW50ZWdyYXRpdmUiLCAiTGVjdHVyZSIsICAgIlJlcGV0aXRpdmUiKQ0KDQoNCg0KdGVhY2hlcjAgPC0gU3RyYXRlZ2Uud3QucGNhWyxjKCJEZWR1Y3RpdmUiLCAiRGVtb25zdHJhdGl2ZSIsICJMZWN0dXJlIiwgIlJlcGV0aXRpdmUiKV0NCnN0dWRlbnQwIDwtIFN0cmF0ZWdlLnd0LnBjYVssYygiQ29vcGVyYXRpdmUiLCAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIiwgIkRlZHVjdGl2ZSIpXQ0KIyMjDQojIyMNCnRlYWNoZXIudmxpZCA8LWNmYS5hbmFseXNpcyh0ZWFjaGVyMCkNCnN0dWRlbnQudmxpZCA8LWNmYS5hbmFseXNpcyhzdHVkZW50MCkNCiMjDQp2bGlkLnRhYmxlIDwtcmJpbmQodGVhY2hlci5jdHJkID0gdGVhY2hlci52bGlkLCBzdHVkZW50LmN0cmQgPSBzdHVkZW50LnZsaWQpDQpyb3cubmFtZSA8LSBjKCJ0ZWFjaGVyLmN0cmQiLCAic3R1ZGVudC5jdHJkIikNCnJvd25hbWVzKHZsaWQudGFibGUpIDwtIHJvdy5uYW1lDQpjb2xuYW1lcyh2bGlkLnRhYmxlKSA8LSBjKCJzdGQuYWxsLm1pbiIsCSJwdmFsLm1heCIsCSJzcm1yIiwJImNmaSIsCSJ0bGkiKQ0KcGFuZGVyKHZsaWQudGFibGUpDQpgYGANCg0KKipSZWxpYWJpbGl0eSBNZWFzdXJlcyoqDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGVhY2hlciA8LSBTdHJhdGVnZS53dC5wY2FbLGMoIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwgIkxlY3R1cmUiLCAiUmVwZXRpdGl2ZSIpXQ0Kc3R1ZGVudCA8LSBTdHJhdGVnZS53dC5wY2FbLGMoIkNvb3BlcmF0aXZlIiwgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIpXQ0KIyMNCnRlYWNoZXIucmVsaWFiaWxpdHkgPC0gUmVsaWFiaWxpdHkuZnVuKHRlYWNoZXIpDQpzdHVkZW50LnJlbGlhYmlsaXR5IDwtIFJlbGlhYmlsaXR5LmZ1bihzdHVkZW50KQ0KIyMNClJlbC50YWJsZSA8LXJiaW5kKHRlYWNoID0gYW54aWV0eS5tZWEucmVsLCBhbnhpZXR5Lm1sYSA9IGFueGlldHkubWxhLnJlbCkNCnJvdy5uYW1lIDwtIGMoIlRlYWNoZXIiLCAiU3R1ZGVudCIpDQpjb2wubmFtZSA8LSBjKCJDcm9uYmFjaCBhbHBoYSIsICJNY0RvbmFsZCdzIE9tZWdhIikNCnJvd25hbWVzKFJlbC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKFJlbC50YWJsZSkgPC0gY29sLm5hbWUNCnBhbmRlcihSZWwudGFibGUpDQpgYGANCg0KVGhlIGFib3ZlIGdvb2RuZXNzLW9mLWZpdCBhbmQgcmVsaWFiaWxpdHkgbWVhc3VyZXMgZXhjZWVkIHRoZSByZXF1aXJlZCB0aHJlc2hvbGRzIG9mIHZhbGlkaXR5IGFuZCByZWxpYWJpbGl0eSBvZiBhbiBpbnN0cnVtZW50LiBUaGUgKipkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSoqIG9mIHRoZSBvcmlnaW5hbCBjb21wb3NpdGUgc2NvcmVzIG9mIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYW5kIGFwcGVuZGVkIHRvIHRoZSBhbmFseXRpYyBkYXRhc2V0Lg0KDQpgYGB7cn0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMgDQpzY29yZXMgPSBmdW5jdGlvbihkZiwgZG4pew0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyMgc2luZ2xlIGZhY3RvciBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB4LnZhciA8LSBuYW1lcyhkZikNCiAgbjAgPC0gbGVuZ3RoKHgudmFyKQ0KICBjZmEubW9kZWwgPC0gIHBhc3RlKCJsYXRlbnQgPX4iLCBwYXN0ZSh4LnZhciwgY29sbGFwc2UgPSAiICsgIikpDQogIGNmYS5maXQgPC0gY2ZhKGNmYS5tb2RlbCwgZGF0YSA9IGRmLCBlc3RpbWF0b3IgPSAiTUxNIikNCiAgY29tcG9zaXRlLmNmYSA8LSBsYXZQcmVkaWN0KGNmYS5maXQpDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMgcGNhIGFuYWx5c2lzDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHBjYS5tZGwgPC0gcHJjb21wKGRmLCBzY2FsZSA9IFRSVUUpDQogIHBjYTAgPC0gcGNhLm1kbCR4WywgMV0NCiAgcjAgPSBjb3IocGNhMCwgY29tcG9zaXRlLmNmYSkNCiAgaWYocjAgPCAwKSB7DQogICAgIHBjYS5hbGwgPC0gLXBjYS5tZGwkeA0KICB9ZWxzZXsNCiAgICBwY2EuYWxsIDwtIHBjYS5tZGwkeA0KICB9DQogIGZpcnN0LnBjYSA9IHBjYS5hbGxbLDFdDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMgd2VpZ2h0ZWQgcGNhIHNjb3JlDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHZhci5leHBsYWluZWQgPC0oKHBjYS5tZGwkc2RldileMikgLyBzdW0oKHBjYS5tZGwkc2RldileMikgIw0KICBjb21wb3NpdGVfd2VpZ2h0ZWRfcGNhIDwtIGFzLm1hdHJpeChwY2EuYWxsKSAlKiUgKHZhci5leHBsYWluZWQpDQoNCiAgb3V0ZGF0YSA8LSBhcy5kYXRhLmZyYW1lKGNiaW5kKHBjYTEgPSBmaXJzdC5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgd3QucGNhID0gYXMudmVjdG9yKGNvbXBvc2l0ZV93ZWlnaHRlZF9wY2EpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNmYSA9IGFzLnZlY3Rvcihjb21wb3NpdGUuY2ZhKSkpDQogIG5hbWVzKG91dGRhdGEpIDwtIHBhc3RlMChkbiwiLiIsIG5hbWVzKG91dGRhdGEpLCBzZXAgPSAiIikNCiAgb3V0ZGF0YQ0KIH0NCiMjIw0KdGVhY2hlciA8LSBzY29yZXModGVhY2hlciwgIlRlYWNoZXIuY3RyZCIpDQpzdHVkZW50IDwtIHNjb3JlcyhzdHVkZW50LCAiU3R1ZGVudC5jdHJkIikNCkFueGlldHkuQW5hbHl0aWMuRGF0YSA8LSBjYmluZChmaW5hbERhdCwgdGVhY2hlciwgc3R1ZGVudCkNCmBgYA0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBGQUxTRX0NCndyaXRlLmNzdihBbnhpZXR5LkFuYWx5dGljLkRhdGEsICJDOlxcVXNlcnNcXDc1Q1BFTkdcXE9uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEFcXERlc2t0b3BcXGNwZW5nXFxXQ1UtVGVhY2hpbmdcXDIwMjVGYWxsXFxNYXRoQXhpZXR5XFxBbnhpZXR5LkFuYWx5dGljLkRhdGEuY3N2IikNCmBgYA0KDQojIExpbmVhciBSZWdyZXNzaW9uIEFuYWx5c2lzDQoNClRoaXMgc2VjdGlvbiBtb3ZlcyBmcm9tIHRoZSBwcmV2aW91cyBkZXNjcmlwdGl2ZSBhbmFseXNlcyB0byBhIHJlZ3Jlc3Npb24gYW5hbHlzaXMgb2YgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gbWF0aCBhbnhpZXR5IGFuZCByZWxhdGVkIGZhY3RvcnMuIFdlIGV4YW1pbmUgdHdvIGRpc3RpbmN0IGJ1dCBpbnRlcmNvbm5lY3RlZCB0eXBlcyBvZiBtYXRoIGFueGlldHksIGV2YWx1YXRpb24gYW54aWV0eSBhbmQgbGVhcm5pbmcgYW54aWV0eSwgd2hpbGUgdGVtcG9yYXJpbHkgc2V0dGluZyBhc2lkZSB0aGVpciBpbnRlcmNvbm5lY3Rpb24uDQoNClRoZSByZWdyZXNzaW9uIG1vZGVsIGFsc28gaW5jb3Jwb3JhdGVzIHRoZSB0d28gdGVhY2hpbmcgc3RyYXRlZ2llcyBhcyBwcmVkaWN0b3IgdmFyaWFibGVzLiBXZSBhbHNvIHJlYWxpemVkIHRoYXQgdGhlIHR3byB2YXJpYWJsZXMgYXJlIGNvcnJlbGF0ZWQuDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZXZhbCA9IFRSVUV9DQphbnhpZXR5LmluZi5kYXRhMCA8LSByZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTWF0aEFueGlldHkvQW54aWV0eS5BbmFseXRpYy5EYXRhLmNzdiIpDQppbmYudmFyIDwtIGMoIkFueGlldHkubWVhLnd0LnBjYSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCAic2V4IiwgInJhY2UiLCAiY2xhc3MiLCAibWFqb3IiLCAibWF0aC5sZXZlbCIsICJtb2RhbGl0eSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIlRlY2hub2xvZ3kud3QucGNhIiwNCiAiQ29vcG9yYXRpdmUud3QucGNhIiwgIkRlZHVjdGl2ZS53dC5wY2EiLCAiRGVtb25zdHJhdGlvbi53dC5wY2EiLCAiSW5kdWN0aXZlLnd0LnBjYSIsICAgICJJbnRlZ3JhdGl2ZS53dC5wY2EiLCAiTGVjdHVyZVR5cGUud3QucGNhIiwgIlJlcGV0aXRpdmUud3QucGNhIiwgIkVuZ2FnZS53dC5wY2EiLCAiUmVzb3VyY2Uud3QucGNhIiwiVGVhY2hlci5jdHJkLnd0LnBjYSIsICJTdHVkZW50LmN0cmQud3QucGNhIikNCiMjDQphbnhpZXR5LnJlZy5kYXRhIDwtIGFueGlldHkuaW5mLmRhdGEwWywgaW5mLnZhcl0NCnJlZy52YXIubmFtZSA8LSBjKCJNRUEiLCAiTUxBIiwgInNleCIsICJyYWNlIiwgImNsYXNzIiwgIm1ham9yIiwgIm1hdGgubGV2ZWwiLCAibW9kYWxpdHkiLCAiU2VsZkVmZmljYWN5IiwgIlRlY2hub2xvZ3kiLA0KICJDb29wb3JhdGl2ZSIsICJEZWR1Y3RpdmUiLCAiRGVtb25zdHJhdGlvbiIsICJJbmR1Y3RpdmUiLCAgICAiSW50ZWdyYXRpdmUiLCAiTGVjdHVyZSIsICJSZXBldGl0aXZlIiwgIkVuZ2FnZSIsICJSZXNvdXJjZSIsIlRlYWNoZXJDdHJkIiwgIlN0dWRlbnRDdHJkIikNCm5hbWVzKGFueGlldHkucmVnLmRhdGEpIDwtIHJlZy52YXIubmFtZSANCmBgYA0KDQojIyBGYWN0b3JzIEFzc29jaWF0ZWQgd2l0aCBFdmFsdWF0aW9uIEFueGlldHkNCg0KRm9yIHRoZSBhc3NvY2lhdGlvbiBhbmFseXNpcywgd2Ugd2lsbCBidWlsZCB0d28gcmVncmVzc2lvbiBtb2RlbHMuIEJvdGggbW9kZWxzIGluY2x1ZGUgYSBjb21tb24gc2V0IG9mIGRlbW9ncmFwaGljIHByZWRpY3RvcnMuIFRoZSBmaXJzdCBtb2RlbCB1c2VzIGluZGl2aWR1YWwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcyBhZGRpdGlvbmFsIHByZWRpY3RvcnMsIHdoaWxlIHRoZSBzZWNvbmQgdXNlcyBncm91cGVkIHRlYWNoaW5nIHN0cmF0ZWdpZXMuDQoNCiMjIyBVc2luZyBJbmRpdmlkdWFsIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KVGhlIGFuYWx5c2lzIGJlZ2lucyB3aXRoIGEgcmVncmVzc2lvbiBtb2RlbCBpbmNvcnBvcmF0aW5nIGFsbCBpbmRpdmlkdWFsIHRlYWNoaW5nIGFwcHJvYWNoZXMgYWxvbmdzaWRlIGRlbW9ncmFwaGljIGFuZCByZWxhdGVkIHZhcmlhYmxlcyBhcyBwcmVkaWN0b3JzLg0KDQpgYGB7cn0NCkJlc3RTdWJzZXRzUmVnIDwtIGZ1bmN0aW9uKGJlc3Quc3Vic2V0Lm1vZGVsKXsNCiAgICMgVmlldyB0aGUgcmVzdWx0cw0KICAgcmVnLnN1bW1hcnkgPC0gc3VtbWFyeShiZXN0LnN1YnNldC5tb2RlbCkNCiANCiAgICMgUGxvdHRpbmcgdGhlIHJlc3VsdHMgKG9wdGlvbmFsLCBmb3IgdmlzdWFsaXphdGlvbikNCiAgICMgcGxvdChiZXN0LnN1YnNldC5tb2RlbCwgc2NhbGUgPSAiYWRqcjIiLCBjb2wgPSAic2t5Ymx1ZSIpICMgb3IgImJpYyIsICJjcCIsIGV0Yy4NCiAgIHBhcihtZnJvdyA9IGMoMiwyKSkNCiAgIHBsb3QocmVnLnN1bW1hcnkkcnNzLCB4bGFiID0gIk51bWJlciBvZiBWYXJpYWJsZXMiLCB5bGFiID0gIlJTUyIsIHR5cGUgPSAibCIsIGNvbCA9ICJuYXZ5IikNCiAgIHBsb3QocmVnLnN1bW1hcnkkYWRqcjIsIHhsYWIgPSAiTnVtYmVyIG9mIFZhcmlhYmxlcyIsIHlsYWIgPSAiQWRqdXN0ZWQgUlNxIiwgdHlwZSA9ICJsIiwgY29sID0gIm5hdnkiKQ0KICAgIyBXZSB3aWxsIG5vdyBwbG90IGEgcmVkIGRvdCB0byBpbmRpY2F0ZSB0aGUgbW9kZWwgd2l0aCB0aGUgbGFyZ2VzdCBhZGp1c3RlZCBSXjIgc3RhdGlzdGljLg0KICAgIyBUaGUgd2hpY2gubWF4KCkgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBtYXhpbXVtIHBvaW50IG9mIGEgdmVjdG9yDQogICBhZGoucjIubWF4ID0gd2hpY2gubWF4KHJlZy5zdW1tYXJ5JGFkanIyKSANCg0KICAgIyBUaGUgcG9pbnRzKCkgY29tbWFuZCB3b3JrcyBsaWtlIHRoZSBwbG90KCkgY29tbWFuZCwgZXhjZXB0IHRoYXQgaXQgcHV0cyBwb2ludHMgDQogICAjIG9uIGEgcGxvdCB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY3JlYXRlZCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IHBsb3QNCiAgIHBvaW50cyhhZGoucjIubWF4LCByZWcuc3VtbWFyeSRhZGpyMlthZGoucjIubWF4XSwgY29sID0iZGFya3JlZCIsIGNleCA9IDIsIHBjaCA9IDIwKQ0KICAgIyBXZSdsbCBkbyB0aGUgc2FtZSBmb3IgQ19wIGFuZCBCSUMsIHRoaXMgdGltZSBsb29raW5nIGZvciB0aGUgbW9kZWxzIHdpdGggdGhlIFNNQUxMRVNUIHN0YXRpc3RpYw0KICAgcGxvdChyZWcuc3VtbWFyeSRjcCwgeGxhYiA9ICJOdW1iZXIgb2YgVmFyaWFibGVzIiwgeWxhYiA9ICJDcCIsIHR5cGUgPSAibCIpDQogICBjcC5taW4gPSB3aGljaC5taW4ocmVnLnN1bW1hcnkkY3ApICMgMTANCiAgIHBvaW50cyhjcC5taW4sIHJlZy5zdW1tYXJ5JGNwW2NwLm1pbl0sIGNvbCA9ICJkYXJrcmVkIiwgY2V4ID0gMiwgcGNoID0gMjApDQoNCiAgIHBsb3QocmVnLnN1bW1hcnkkYmljLCB4bGFiID0gIk51bWJlciBvZiBWYXJpYWJsZXMiLCB5bGFiID0gIkJJQyIsIHR5cGUgPSAibCIpDQogICBiaWMubWluID0gd2hpY2gubWluKHJlZy5zdW1tYXJ5JGJpYykgIyA2DQogICBwb2ludHMoYmljLm1pbiwgcmVnLnN1bW1hcnkkYmljW2JpYy5taW5dLCBjb2wgPSAiZGFya3JlZCIsIGNleCA9IDIsIHBjaCA9IDIwKQ0KfQ0KYGBgDQoNCldlIHVzZSB0aGUgYmVzdCBzdWJzZXQgYXBwcm9hY2ggdG8gbW9kZWwgaWRlbnRpZmljYXRpb24uIFRoZSBmb2xsb3dpbmcgYXJlIHBsb3RzIG9mIGEgZmV3IHBlcmZvcm1hbmNlIG1lYXN1cmVzIGFnYWlzdCB0aGUgbnVtYmVyIG9mIHByZWRpY3RvciB2YXJpYWJsZXMgdG8gYmUgcmV0YWluZWQgaW4gdGhlIGZpbmFsIG1vZGVsLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KbWVhLmxtLmRhdGEgPC0gYW54aWV0eS5yZWcuZGF0YVssLWMoMiwyMCwyMSldDQptZWEuYmVzdC5zdWJzZXRzLmxtIDwtIHJlZ3N1YnNldHMoTUVBIH4uLCBkYXRhID0gbWVhLmxtLmRhdGEsIG52bWF4ID0gOCwgIG1ldGhvZCA9ICJiYWNrd2FyZCIgKQ0KQmVzdFN1YnNldHNSZWcobWVhLmJlc3Quc3Vic2V0cy5sbSkNCmBgYA0KDQpUaGUgYWJvdmUgZmlndXJlIGluZGljYXRlcyB0aGF0IHRoZSA2LXByZWRpY3RvciBtb2RlbCBpcyB0aGUgb3B0aW1hbCBjaG9pY2UuIFRoZSByZXN1bHRzIG9idGFpbmVkIGZyb20gdGhpcyBzdWJzZXQgc2VsZWN0aW9uIG1ldGhvZCBhcmUgaWRlbnRpY2FsIHRvIHRob3NlIG9idGFpbmVkIHZpYSBzdGVwd2lzZSB2YXJpYWJsZSBzZWxlY3Rpb24uDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTd9DQptZWEubG0uZGF0YSA8LSBhbnhpZXR5LnJlZy5kYXRhWywtYygyLDIwLDIxKV0NCm1lYS5sbSA8LSBsbShNRUEgflNlbGZFZmZpY2FjeSArIEluZHVjdGl2ZSArIEludGVncmF0aXZlICsgbWF0aC5sZXZlbCArIHNleCArDQogICAgVGVjaG5vbG9neSwgZGF0YSA9IG1lYS5sbS5kYXRhKQ0Kc3RlcHdpc2UubWVhLm1vZGVsIDwtIHN0ZXBBSUMobWVhLmxtLCBkaXJlY3Rpb24gPSAiYm90aCIsIHRyYWNlID0gMCkNCiNzdW1tYXJ5KHN0ZXB3aXNlLm1lYS5tb2RlbCkNCnBhcihtZnJvdyA9IGMoMiwyKSkNCnBsb3Qoc3RlcHdpc2UubWVhLm1vZGVsICkNCmBgYA0KDQpUaGUgZmlndXJlIGFib3ZlIHJldmVhbHMgYSBjbGVhciBwYXR0ZXJuIG9mIG5vbi1jb25zdGFudCByZXNpZHVhbCB2YXJpYW5jZSAoaGV0ZXJvc2NlZGFzdGljaXR5KSBhcyB0aGUgZml0dGVkIHZhbHVlcyBpbmNyZWFzZS4gQmVjYXVzZSB0aGUgcmVzcG9uc2UgdmFyaWFibGUgaW5jbHVkZXMgbmVnYXRpdmUgdmFsdWVzLCBhIHN0YW5kYXJkIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gaXMgbm90IGFwcGxpY2FibGUgZm9yIGlkZW50aWZ5aW5nIGEgcG93ZXIgdHJhbnNmb3JtYXRpb24uIEluc3RlYWQsIHdlIHdpbGwgdXNlIGJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscyBmb3IgYWxsIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIHRvIGFzc2VzcyB0aGVpciBzaWduaWZpY2FuY2UsIHRoZXJlYnkgbWFpbnRhaW5pbmcgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIG9uIGl0cyBvcmlnaW5hbCBzY2FsZS4NCg0KYGBge3J9DQojIyMgQm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpib290LmNvZWYgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICBkIDwtIGRhdGFbaW5kaWNlcywgXSAgIyByZXNhbXBsZSByb3dzDQogIGZpdCA8LSBsbShNRUEgfiBTZWxmRWZmaWNhY3kgKyBJbnRlZ3JhdGl2ZSArIG1hdGgubGV2ZWwgKyANCiAgICBzZXggKyBUZWNobm9sb2d5LCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCiMjIyMjIw0KIyBFeHRyYWN0IENJcyBmb3IgYWxsIGNvZWZmaWNpZW50cw0KZ2V0LmFsbC5ib290LmNpcyA8LSBmdW5jdGlvbihib290Lm91dHB1dCwgdHlwZSA9ICJwZXJjIikgew0KICBuLmNvZWYgPC0gbmNvbChib290Lm91dHB1dCR0KQ0KICBjaS5tYXRyaXggPC0gbWF0cml4KE5BLCBucm93ID0gbi5jb2VmLCBuY29sID0gMikNCiAgcm93bmFtZXMoY2kubWF0cml4KSA8LSBjb2xuYW1lcyhib290Lm91dHB1dCR0KQ0KICBjb2xuYW1lcyhjaS5tYXRyaXgpIDwtIGMoImJ0Lmxvdy45NSUiLCAiYnQudXAuOTUlIikNCiAgDQogIGZvciAoaSBpbiAxOm4uY29lZikgew0KICAgIGNpLm9iaiA8LSBib290LmNpKGJvb3Qub3V0cHV0LCB0eXBlID0gdHlwZSwgaW5kZXggPSBpKQ0KICAgIGlmICh0eXBlID09ICJwZXJjIikgew0KICAgICAgY2kubWF0cml4W2ksIF0gPC0gY2kub2JqJHBlcmNlbnRbNDo1XQ0KICAgIH0NCiAgfQ0KICANCiAgcmV0dXJuKGNpLm1hdHJpeCkNCn0NCg0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTEpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cyA8LSBib290KG1lYS5sbS5kYXRhLCBib290LmNvZWYsIFIgPSAxMDAwKQ0KIyMgYm9vdHN0cmFwIENJDQphbGwuY2lzIDwtIGdldC5hbGwuYm9vdC5jaXMoYm9vdC5yZXN1bHRzKQ0KSW5mZXJlbmNlVGFibGUgPC0gcm91bmQoY2JpbmQoc3VtbWFyeShzdGVwd2lzZS5tZWEubW9kZWwpJGNvZWYsIGFsbC5jaXMpLDQpDQpwcmludChJbmZlcmVuY2VUYWJsZSkgDQpgYGANCg0KVGhlIGFib3ZlIHRhYmxlIHJldmVhbGVkIHNldmVyYWwgc2lnbmlmaWNhbnQgcHJlZGljdG9ycyBvZiBtYXRoIGV2YWx1YXRpb24gYW54aWV0eS4gSGlnaGVyICoqc2VsZi1lZmZpY2FjeSoqIHdhcyBzdHJvbmdseSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgYW54aWV0eSAoJFxiZXRhID0gLTAuNTc3LCBwIDwgMC4wMDEkKSwgaW5kaWNhdGluZyB0aGF0IHN0dWRlbnRzIHdobyBhcmUgbW9yZSBjb25maWRlbnQgaW4gdGhlaXIgbWF0aGVtYXRpY2FsIGFiaWxpdGllcyBleHBlcmllbmNlIGxlc3MgKipldmFsdWF0aW9uLXJlbGF0ZWQgc3RyZXNzKiouIFNpbWlsYXJseSwgKippbnRlZ3JhdGl2ZSBpbnN0cnVjdGlvbiBhcHByb2FjaCoqIHNob3dlZCBhIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcCB3aXRoIGFueGlldHkgKCRcYmV0YSA9IC0wLjE3OCwgcCA8IDAuMDAxJCksIGltcGx5aW5nIHRoYXQgdGhpcyB0ZWFjaGluZyBtZXRob2QgbWF5IGhlbHAgcmVkdWNlIHN0dWRlbnQgYW54aWV0eS4gKipDb3Vyc2UgbGV2ZWwqKiBhbHNvIHBsYXllZCBhIHJvbGU6IHN0dWRlbnRzIGVucm9sbGVkIGluIG1hdGgwMyAoY2FsYyBBIGFuZCBicmllZiBDYWxjKSAoJFxiZXRhID0gMC4yNzYsIHAgPSAwLjA0MCQpIGFuZCBtYXRoMDQgKGFib3ZlIENhbGMgQSkgKCRcYmV0YSA9IDAuMzYzLCBwID0gMC4wMjMkKSBjb3Vyc2VzIGV4aGliaXRlZCBoaWdoZXIgYW54aWV0eSBjb21wYXJlZCB0byB0aGUgcmVmZXJlbmNlIGdyb3VwLCB3aGlsZSBvdGhlciBjb3Vyc2UgbGV2ZWxzIHdlcmUgbm90IHNpZ25pZmljYW50LiAqKkdlbmRlcioqIHdhcyBhIHNpZ25pZmljYW50IGZhY3Rvciwgd2l0aCBtYWxlIHN0dWRlbnRzIHJlcG9ydGluZyBsb3dlciBhbnhpZXR5IHRoYW4gZmVtYWxlcyAoJFxiZXRhID0gLTAuMzQ0LCBwIDwgMC4wMDEkKS4gRmluYWxseSwgKip0ZWNobm9sb2d5IHVzZSoqIHdhcyBuZWdhdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBhbnhpZXR5ICgkXGJldGEgPSAtMC4xMzcsIHAgPCAwLjAwMSQpLCBpbmRpY2F0aW5nIHRoYXQgZ3JlYXRlciBlbmdhZ2VtZW50IHdpdGggdGVjaG5vbG9neSBjb3JyZXNwb25kcyB0byByZWR1Y2VkIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQpJbiBzdW1tYXJ5LCBtYXRoIGV2YWx1YXRpb24gYW54aWV0eSB3YXMgc2lnbmlmaWNhbnRseSBsb3dlciBhbW9uZyBzdHVkZW50cyB3aXRoIGhpZ2hlciAqKnNlbGYtZWZmaWNhY3kqKi4gQW4gKippbnRlZ3JhdGl2ZSB0ZWFjaGluZyBhcHByb2FjaCoqIGFuZCBhcHByb3ByaWF0ZSAqKnVzZSBvZiB0ZWNobm9sb2d5KiogbWF5IGhlbHAgcmVkdWNlIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LiBNYWxlIHN0dWRlbnRzIHRlbmRlZCB0byBleHBlcmllbmNlIGxlc3Mgc3RyZXNzLiBDb252ZXJzZWx5LCBzdHVkZW50cyBlbnJvbGxlZCBpbiBoaWdoZXItbGV2ZWwgbWF0aCBjb3Vyc2VzIChtYXRoMDMgYW5kIG1hdGgwNCkgcmVwb3J0ZWQgc2xpZ2h0bHkgaGlnaGVyIGFueGlldHkuDQoNCiMjIyBVc2luZyBHcm91cGVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KTmV4dCwgd2UgYnVpbGQgYSByZWdyZXNzaW9uIG1vZGVsIHVzaW5nIHRoZSBhZ2dyZWdhdGVkIHRlYWNoaW5nIHN0eWxlczogdGVhY2hlci1jZW50ZXJlZCBhbmQgc3R1ZGVudC1jZW50ZXJlZCwgcGx1cyBzb21lIGRlbW9ncmFwaGljIGZhY3RvcnMuIFdlIHdpbGwgc3RpbGwgdXNlIHRoZSBiZXN0IHN1YnNldCBzZWxlY3Rpb24gbWV0aG9kIGpvaW50bHkgd2l0aCBvdGhlciByZWxhdGVkIG1ldGhvZHMgdG8gaWRlbnRpZnkgdGhlIGZpbmFsIG1vZGVsLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTZ9DQojIFBlcmZvcm0gYmVzdCBzdWJzZXQgc2VsZWN0aW9uDQojICdudm1heCcgc3BlY2lmaWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZiB2YXJpYWJsZXMgdG8gY29uc2lkZXIgaW4gYSBzdWJzZXQNCmJlc3Quc3Vic2V0Lm1vZGVsLmN0cmQgPC0gcmVnc3Vic2V0cyhNRUF+IHNleCsgcmFjZSsgY2xhc3MrIG1ham9yKyBtYXRoLmxldmVsKyBtb2RhbGl0eSsgU2VsZkVmZmljYWN5KyBUZWNobm9sb2d5ICsgVGVhY2hlckN0cmQrIFN0dWRlbnRDdHJkLCBkYXRhID0gYW54aWV0eS5yZWcuZGF0YSwgbnZtYXggPSAxMCwgIG1ldGhvZCA9ICJiYWNrd2FyZCIgKQ0KQmVzdFN1YnNldHNSZWcoYmVzdC5zdWJzZXQubW9kZWwuY3RyZCkNCmBgYA0KDQpUaGUgZm9sbG93aW5nIHJlc2lkdWFsIGRpYWdub3N0aWMgcGxvdHMgaW5kaWNhdGUgYWJub3JtYWwgcGF0dGVybnMuIFBhcnRpY3VsYXIsIG5vbi1jb25zdGFudCB2YXJpYW5jZSBvZiB0aGUgcmVzaWR1YWwgdmFyaWFuY2UuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCiMgVGhlIGZpbmFsIG1vZGVsDQpiZXN0LnN1YnNldC5jdHJkIDwtIGxtKE1FQX4gc2V4KyBtYXRoLmxldmVsKyAgU2VsZkVmZmljYWN5KyBUZWNobm9sb2d5ICsgU3R1ZGVudEN0cmQsIGRhdGEgPSBhbnhpZXR5LnJlZy5kYXRhKQ0KI3N1bW1hcnkoYmVzdC5zdWJzZXQuY3RyZCkkY29lZg0KcGFyKG1mcm93ID0gYygyLDIpKQ0KcGxvdChiZXN0LnN1YnNldC5jdHJkKQ0KYGBgDQoNCldlIG5leHQgcGVyZm9ybSBCb290c3RyYXAgcmVncmVzc2lvbiB0byBjb25zdHJ1Y3Qgcm9idXN0IGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMuDQoNCmBgYHtyfQ0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLmN0cmQgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICBkIDwtIGRhdGFbaW5kaWNlcywgXSAgIyByZXNhbXBsZSByb3dzDQogIGZpdCA8LSBsbShNRUF+IHNleCsgbWF0aC5sZXZlbCsgIFNlbGZFZmZpY2FjeSsgVGVjaG5vbG9neSArIFN0dWRlbnRDdHJkLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCg0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTIpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cy5jdHJkIDwtIGJvb3QoYW54aWV0eS5yZWcuZGF0YSwgYm9vdC5jb2VmLmN0cmQsIFIgPSAxMDAwKQ0KIyBDb21iaW5lIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBvdXRwdXQgd2l0aCB0aGUgYm9vdHN0cmFwIENJDQphbGwuY3RyZC5jaXMgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMuY3RyZCApDQpJbmZlcmVuY2VUYWJsZSA8LSByb3VuZChjYmluZChzdW1tYXJ5KGJlc3Quc3Vic2V0LmN0cmQpJGNvZWYsIGFsbC5jdHJkLmNpcyApLDQpDQpwcmludChJbmZlcmVuY2VUYWJsZSkgDQpgYGANCg0KVGhlIHJlc3VsdHMgYWJvdmUgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgcHJldmlvdXMgcmVncmVzc2lvbiB0aGF0IHVzZWQgaW5kaXZpZHVhbCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIHByZWRpY3RvcnMuIFRoZSBrZXkgZGlmZmVyZW5jZSBpcyB0aGF0IHRoZSAqKmludGVncmF0aXZlIHRlYWNoaW5nIGFwcHJvYWNoKiogd2FzIHNpZ25pZmljYW50IGluIHRoZSBmb3JtZXIgbW9kZWwsIHdoZXJlYXMgKipzdHVkZW50LWNlbnRlcmVkKiogdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgc2lnbmlmaWNhbnQgaW4gdGhlIGN1cnJlbnQgb25lLiBIb3dldmVyLCBzaW5jZSBhbiBpbnRlZ3JhdGl2ZSBhcHByb2FjaCBpcyBhIHNwZWNpZmljIHR5cGUgb2Ygc3R1ZGVudC1jZW50ZXJlZCBzdHJhdGVneSwgdGhlIG1vZGVscyB1bHRpbWF0ZWx5IHlpZWxkIGNvbmdydWVudCBmaW5kaW5ncy4NCg0KIyMgRmFjdG9ycyBBc3NvY2lhdGVkIHdpdGggTGVhcm5pbmcgQW54aWV0eQ0KDQpVbmxpa2UgbWF0aCBldmFsdWF0aW9uIGFueGlldHksIHdoaWNoIGlzIGZ1ZWxlZCBtb3JlIGJ5IGVtb3Rpb25hbCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzLCBtYXRoIGxlYXJuaW5nIGFueGlldHkgaXMgYSBkaXJlY3QgcmVzcG9uc2UgdG8gdGhlIGxlYXJuaW5nIGVjb3N5c3RlbS4gSXQgaXMgY2xvc2VseSBsaW5rZWQgdG8gdGhlIGRlbnNpdHkgb2YgdGhlIGxlYXJuaW5nIG1hdGVyaWFscywgdGhlIHNpZ25pZmljYW50IGNvZ25pdGl2ZSBsb2FkIHJlcXVpcmVkIGZvciBwcm9ibGVtLXNvbHZpbmcsIGFuZCBjcml0aWNhbCBleHRlcm5hbCBmYWN0b3JzIHN1Y2ggYXMgaW5zdHJ1Y3RvcnMnIHRlYWNoaW5nIHN0cmF0ZWdpZXMuDQoNClRoZSBuZXh0IHJlZ3Jlc3Npb24gbW9kZWwgYWltcyB0byBpZGVudGlmeSBmYWN0b3JzIHRoYXQgYXJlIGRpcmVjdGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgbWF0aCBsZWFybmluZyBhbnhpZXR5LiBXZSBzdGlsbCB0YWtlIHRoZSBiZXN0IHN1YnNldCBzZWxlY3Rpb24gYXBwcm9hY2ggdG8gaWRlbnRpZnlpbmcgdGhlIGJlc3QgbW9kZWwuDQoNCiMjIyBVc2luZyBJbmRpdmlkdWFsIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KVGhlIGZvbGxvd2luZyBtb2RlbCB1c2VzIGluZGl2aWR1YWwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcyBwcmVkaWN0b3JzLiBUaGlzIHdpbGwgaGVscCBpZGVudGlmeSBwYXJ0aWN1bGFyIHRlYWNoaW5nIHN0cmF0ZWdpZXMgdGhhdCBhcmUgc2lnbmlmaWNhbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIGxlYW5pbmcgYW54aWV0eS4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCm1sYS5sbS5kYXRhIDwtIGFueGlldHkucmVnLmRhdGFbLC1jKDEsMjAsMjEpXQ0KbWxhLmZ1bGwubG0gPC0gbG0oTUxBIH4uLCBkYXRhID0gbWxhLmxtLmRhdGEpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KG1sYS5mdWxsLmxtKQ0KI3N1bW1hcnkobWxhLmZ1bGwubG0pDQpgYGANCg0KVGhpcyBpbml0aWFsIG1vZGVsJ3MgcmVzaWR1YWwgZGlhZ25vc3RpYyBwbG90IHNob3dzIG5vbi1jb25zdGFudCB2YXJpYW5jZS4gV2Ugd2lsbCBub3QgcGVyZm9ybSBhbnkgcG93ZXIgdHJhbnNmb3JtYXRpb25zIG9uIHRoZSByZXNwb25zZSB2YXJpYWJsZSBmb3IgdGhlIHNhbWUgcmVhc29ucyBzdGF0ZWQgaW4gdGhlIHByZXZpb3VzIHN1YnNlY3Rpb24uIFRoZSBpbmZlcmVuY2Ugb24gdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIHdpbGwgYmFzZWQgb24gbm9ucGFyYW1ldHJpYyBCb290c3RyYXAgYW5kIHRoZSBjbGFzc2ljYWwgdC10ZXN0cy4NCg0KV2UgbmV4dCB1c2UgYmVzdCBzdWJzZXQgbW9kZWwgc2VsZWN0aW9uIGFwcHJvYWNoIHRvIGlkZW50aWZ5IHRoZSBvcHRpbWFsIG1vZGVsIHVzaW5nIHZhcmlvdXMgcGVyZm9ybWFuY2UgbWVhc3VyZXMgc3VjaCBhcyBDcCwgQklDLCBBZGp1c3RlZCBjb2VmZmljaWVudCBvZiBkZXRlcm1pbmF0aW9uIGFuZCB0aGUgbGlzdCBvZiB0aGUgc2lnbmlmaWNhbnQgcHJlZGljdG9ycyBpbiB0aGUgaW5pdGlhbCBtb2RlbCB3aXRoIG1vc3Qgb2YgdGhlIGNhbmRpZGF0ZSBwcmVkaWN0b3IgdmFyaWFibGVzLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KbWxhLmJlc3Quc3Vic2V0cy5sbSA8LSByZWdzdWJzZXRzKE1MQSB+LiwgZGF0YSA9IG1sYS5sbS5kYXRhLCBudm1heCA9IDE2LCAgbWV0aG9kID0gImJhY2t3YXJkIiApDQpCZXN0U3Vic2V0c1JlZyhtbGEuYmVzdC5zdWJzZXRzLmxtKQ0KYGBgDQoNClNpbmNlIHRoZXJlIGFyZSBzb21lIHBhdHRlcm4ncyBpbiB0aGUgcmVzaWR1YWwgcGxvdHMuIHdlIGFsc28gcmVwb3J0IGEgbm9uLXBhcmFtZXRyaWMgYm9vdHN0cmFwIG1ldGhvZCB0byBjb25zdHJ1Y3QgcGVyY2VudGlsZS1iYXNlZCBib29zdHJhcCBjb25maWRlbmNlIGludGVydmFscyBvZiBlYWNoIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzLiBUaGUgcmVzdWx0cyBhcmUgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlLg0KDQpgYGB7cn0NCnByZWQudmFyIDwtIG5hbWVzKGNvZWYobWxhLmJlc3Quc3Vic2V0cy5sbSAsNykpWy0oMToyKV0NCmFjdXRhbC52YXIgPC1jKCJyYWNlIiwgcHJlZC52YXIpDQpmb3JtdWxhLnN0ciA8LSBwYXN0ZSgiTUxBIiwgIn4iLCBwYXN0ZShhY3V0YWwudmFyLCBjb2xsYXBzZSA9ICIgKyAiKSkNCk1MQS5tb2RlbC5mb3JtdWxhIDwtIGFzLmZvcm11bGEoZm9ybXVsYS5zdHIpDQpNTEEubW9kZWwgPC0gbG0oTUxBLm1vZGVsLmZvcm11bGEgLCBkYXRhID0gbWxhLmxtLmRhdGEpDQojc3VtbWFyeShNTEEubW9kZWwgKQ0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLm1sYSA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCg0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTIpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cy5tbGE8LSBib290KG1sYS5sbS5kYXRhLCBib290LmNvZWYubWxhLCBSID0gMTAwMCkNCiMjIGNvbWJpbmUgcmVndWxhciByZWdyZXNzaW9uIG91dHB1dCBhbmQgdGhlIGJvb3RzdHJhcCBDSQ0KYWxsLmNpcy5tbGEgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMubWxhKQ0KSW5mZXJlbmNlVGFibGUgPC0gcm91bmQoY2JpbmQoc3VtbWFyeShNTEEubW9kZWwpJGNvZWYsIGFsbC5jaXMubWxhKSw0KQ0KcHJpbnQoSW5mZXJlbmNlVGFibGUpIA0KYGBgDQoNClRoZSBhYm92ZSByZXN1bHRzIGluZGljYXRlIHRoYXQgKipTZWxmLUVmZmljYWN5KiosICoqVGVjaG5vbG9neSB1c2UqKiwgKipEZW1vbnN0cmF0aW9uKiosIGFuZCAqKkxlY3R1cmUtYmFzZWQqKiB0ZWFjaGluZyBzdHJhdGVnaWVzIGFyZSBzaWduaWZpY2FudCBuZWdhdGl2ZSBwcmVkaWN0b3JzIG9mIGFueGlldHkuIFNwZWNpZmljYWxseSwgaGlnaGVyIHNlbGYtZWZmaWNhY3kgKCRcYmV0YSA9IC0wLjQwLCBwIDwgLjAwMSQpIGFuZCBncmVhdGVyIHVzZSBvZiAqKnRlY2hub2xvZ3kqKiBpbiBsZWFybmluZyAoJFxiZXRhID0gLTAuMTEsIHAgPCAuMDAxJCkgYXJlIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBsZXZlbHMgb2YgbWF0aCBsZWFybmluZyBhbnhpZXR5LiBTaW1pbGFybHksIG1vcmUgZnJlcXVlbnQgdXNlIG9mICoqZGVtb25zdHJhdGl2ZSoqICgkXGJldGEgPSAtMC4xMCwgcCA9IC4wMDYkKSBhbmQgKipsZWN0dXJlIGFwcHJvYWNoZXMqKiAoJFxiZXRhID0gLTAuMTQsIHAgPCAuMDAxJCkgY29ycmVzcG9uZCB3aXRoIGRlY3JlYXNlZCBhbnhpZXR5Lg0KDQpDb252ZXJzZWx5LCB0aGUgcGVyY2VpdmVkICoqQ29vcGVyYXRpdmUqKiB0ZWFjaGluZyBhcHByb2FjaCBpcyBwb3NpdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBsZWFybmluZyBhbnhpZXR5ICgkXGJldGEgPSAwLjA3LCBwID0gLjAzMSQpLiAqKlJlc291cmNlLWJhc2VkKiogbGVhcm5pbmcgKCRcYmV0YSA9IDAuMDgsIHAgPSAuMDEzJCkgaXMgYWxzbyBwb3NpdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBhbnhpZXR5LCBzdWdnZXN0aW5nIHRoYXQgc3R1ZGVudCB1c2VkIGxlYXJuaW5nIHJlc291cmNlcyB0ZW5kZWQgdG8gaGF2ZSBoaWdoZXIgYW54aWV0eSBpbiBtYXRoIGNvbnRleHRzLg0KDQpUaGUgcmFjZSB2YXJpYWJsZSBhcHByb2FjaGVkIG1hcmdpbmFsIHNpZ25pZmljYW5jZSAocCA9MC4wNTgpLCBpbmRpY2F0aW5nIHRoYXQgQmxhY2sgc3R1ZGVudHMgdGVuZGVkIHRvIGhhdmUgaGlnaGVyIGxlYXJuaW5nIGFueGlldHkgKCRcYmV0YSA9IDAuMzIwMiwgcCA9IC4wNTgkKS4NCg0KT3ZlcmFsbCwgdGhlc2UgcmVzdWx0cyBoaWdobGlnaHQgdGhhdCBzdHVkZW50cycgY29uZmlkZW5jZSBpbiB0aGVpciBtYXRoIGFiaWxpdGllcyBhbmQgY2VydGFpbiBpbnN0cnVjdGlvbmFsIHByYWN0aWNlcyBwbGF5IGEga2V5IHJvbGUgaW4gcmVkdWNpbmcgbWF0aCBsZWFybmluZyBhbnhpZXR5LCB3aGlsZSBvdGhlcnMgbWF5IGluYWR2ZXJ0ZW50bHkgaW5jcmVhc2UgaXQuDQoNCiMjIyBVc2luZyBHcm91cGVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KV2UgbmV4dCBidWlsZCBhIHJlZ3Jlc3Npb24gc2ltaWxhciB0byB0aGUgYWJvdmUgb25lIGJ1dCByZXBsYWNlIHRoZSBpbmRpdmlkdWFsIHRlYWNoaW5nIHN0cmF0ZWd5IHZhcmlhYmxlcyB3aXRoIHRoZSB0d28gZ3JvdXBlZCB0ZWFjaGluZyBzdHJhdGVneSB2YXJpYWJsZXM6IHRlYWNoZXItY2VudGVyZWQgYW1kIHN0dWRlbnQtY2VudGVyZWQgYXBwcm9hY2hlcy4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCm1sYS5sbS5kYXRhLmN0cmQgPC0gYW54aWV0eS5yZWcuZGF0YVssLWMoMSwgMTE6MTcpXQ0KbWxhLmZ1bGwuY3RyZCA8LSBsbShNTEEgfi4sIGRhdGEgPSBtbGEubG0uZGF0YS5jdHJkKQ0KcGFyKG1mcm93ID0gYygyLDIpKQ0KcGxvdChtbGEuZnVsbC5jdHJkKQ0KIyBzdW1tYXJ5KG1sYS5mdWxsLmN0cmQpDQpgYGANCg0KVGhlIHNhbWUgbm9uLWNvbnN0YW50IHZhcmlhbmNlIHBhdHRlcm5zIHdhcyBvYnNlcnZlZCBpbiB0aGUgYWJvdmUgcmVzaWR1YWwgcGxvdC4gV2Ugc3RpbGwgdXNlIHN1YnNldCBzZWxlY3Rpb24gcHJvY2VkdXJlIHRvIGlkZW50aWZ5IHRoZSBmaW5hbCBtb2RlbC4NCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0NCm1sYS5iZXN0LnN1YnNldHMuY3RyZCA8LSByZWdzdWJzZXRzKE1MQSB+LiwgZGF0YSA9IG1sYS5sbS5kYXRhLmN0cmQsIG52bWF4ID0gMTYsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKG1sYS5iZXN0LnN1YnNldHMuY3RyZCkNCiMjIGZpbmFsIG1vZGVsDQpwcmVkLnZhci5jdHJkIDwtIG5hbWVzKGNvZWYobWxhLmJlc3Quc3Vic2V0cy5jdHJkLDcpKVstKDE6NCldDQphY3V0YWwudmFyLmN0cmQgPC1jKCJyYWNlIiwgIm1ham9yIiwgcHJlZC52YXIuY3RyZCkNCmZvcm11bGEuc3RyLmN0cmQgPC0gcGFzdGUoIk1MQSIsICJ+IiwgcGFzdGUoYWN1dGFsLnZhci5jdHJkLCBjb2xsYXBzZSA9ICIgKyAiKSkNCk1MQS5tb2RlbC5mb3JtdWxhIDwtIGFzLmZvcm11bGEoZm9ybXVsYS5zdHIuY3RyZCkNCk1MQS5tb2RlbC5jdHJkIDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhICwgZGF0YSA9IG1sYS5sbS5kYXRhLmN0cmQpDQojc3VtbWFyeShNTEEubW9kZWwuY3RyZCkkY29lZg0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLm1sYS5jdHJkIDwtIGZ1bmN0aW9uKGRhdGEsIGluZGljZXMpIHsNCiAgZCA8LSBkYXRhW2luZGljZXMsIF0gICMgcmVzYW1wbGUgcm93cw0KICBmaXQgPC0gbG0oTUxBLm1vZGVsLmZvcm11bGEgLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCiMgUGVyZm9ybSBib290c3RyYXAgKFIgPSBudW1iZXIgb2YgcmVzYW1wbGVzKQ0Kc2V0LnNlZWQoMzEyKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5DQpib290LnJlc3VsdHMuY3RyZCA8LSBib290KG1sYS5sbS5kYXRhLmN0cmQsIGJvb3QuY29lZi5tbGEuY3RyZCwgUiA9IDEwMDApDQojIyBjb21iaW5pbmcgYm9vdHN0cmFwIENJcyB3aXRoIHRoZSBkZWZhdWx0IG91dHB1dCBpbiB0aGUgbG0oKQ0KYWxsLmN0cmQuY2lzIDwtIGdldC5hbGwuYm9vdC5jaXMoYm9vdC5yZXN1bHRzLmN0cmQgKQ0KSW5mZXJlbmNlVGFibGUgPC0gcm91bmQoY2JpbmQoc3VtbWFyeShNTEEubW9kZWwuY3RyZCkkY29lZiwgYWxsLmN0cmQuY2lzICksNCkNCnByaW50KEluZmVyZW5jZVRhYmxlKSANCmBgYA0KDQpUaGUgb3ZlcmFsbCBtb2RlbCB3YXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgaW5kaWNhdGluZyB0aGF0IHRoZSBzZXQgb2YgcHJlZGljdG9ycyBtZWFuaW5nZnVsbHkgZXhwbGFpbmVkIHZhcmlhbmNlIGluIG1hdGggbGVhcm5pbmcgYW54aWV0eS4NCg0KQW1vbmcgZGVtb2dyYXBoaWMgdmFyaWFibGVzLCAqKnJhY2UqKiB3YXMgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IuIFNwZWNpZmljYWxseSwgQmxhY2sgc3R1ZGVudHMgcmVwb3J0ZWQgc2lnbmlmaWNhbnRseSBoaWdoZXIgYW54aWV0eSB0aGFuIHRoZSByZWZlcmVuY2UgQXNpYW4gZ3JvdXAgKCRcYmV0YSA9IDAuMzQsIHAgPSAuMDQzJCksIHdoZXJlYXMgc3R1ZGVudHMgaWRlbnRpZnlpbmcgYXMgV2hpdGUgb3IgT3RoZXIgcmFjaWFsIGdyb3VwcyBkaWQgbm90IGRpZmZlciBzaWduaWZpY2FudGx5IGZyb20gdGhlIHJlZmVyZW5jZSBncm91cCAoJHAgPiAuMDUkKS4gQWRkaXRpb25hbGx5LCBzdHVkZW50cyBtYWpvcmluZyBpbiAqKlNURU0qKiBmaWVsZHMgcmVwb3J0ZWQgc2lnbmlmaWNhbnRseSBsb3dlciBhbnhpZXR5IGNvbXBhcmVkIHRvIHRob3NlIG91dHNpZGUgU1RFTSBtYWpvcnMgKCRcYmV0YSA9IOKIkjAuMTcsIHAgPSAuMDM5JCkuIEFjYWRlbWljICoqbWFqb3JzKiogY2F0ZWdvcml6ZWQgYXMgSGVhbHRoIG9yIE90aGVyIGRpZCBub3Qgc2hvdyBzaWduaWZpY2FudCByZWxhdGlvbnNoaXBzIHdpdGggYW54aWV0eSAoJHAgPiAuMDUkKS4NCg0KUHN5Y2hvbG9naWNhbCBhbmQgaW5zdHJ1Y3Rpb25hbCBmYWN0b3JzIGRlbW9uc3RyYXRlZCBub3RhYmxlIGFzc29jaWF0aW9ucyB3aXRoIG1hdGggbGVhcm5pbmcgYW54aWV0eS4gSGlnaGVyIGxldmVscyBvZiAqKnNlbGYtZWZmaWNhY3kqKiB3ZXJlIHN0cm9uZ2x5IGFzc29jaWF0ZWQgd2l0aCBsb3dlciBhbnhpZXR5ICgkXGJldGEgPSDiiJIwLjM5LCBwIDwgLjAwMSQpLCByZXByZXNlbnRpbmcgdGhlIGxhcmdlc3QgZWZmZWN0IGluIHRoZSBtb2RlbC4gTW9yZSBmcmVxdWVudCB1c2Ugb2YgdGVjaG5vbG9neS1zdXBwb3J0ZWQgbGVhcm5pbmcgKCRcYmV0YSA9IOKIkjAuMTAsIHAgPCAuMDAxJCkgYW5kICoqdGVhY2hlci1jZW50ZXJlZCoqIGFwcHJvYWNoZXMgKCRcYmV0YSA9IOKIkjAuMTgsIHAgPCAuMDAxJCkgd2lsbCBoZWxwIHJlZHVjZSBhbnhpZXR5IGxldmVscy4gSW4gY29udHJhc3QsIGluY3JlYXNlZCByZWxpYW5jZSBvbiAqKnJlc291cmNlLWJhc2VkIGxlYXJuaW5nKiogc3RyYXRlZ2llcyB3YXMgcG9zaXRpdmVseSBhc3NvY2lhdGVkIHdpdGggYW54aWV0eSAoJFxiZXRhID0gMC4wOSwgcCA9IC4wMTEkKS4gQWx0aG91Z2ggKipzdHVkZW50LWNlbnRlcmVkKiogaW5zdHJ1Y3Rpb24gc2hvd2VkIGEgcG9zaXRpdmUgYXNzb2NpYXRpb24gd2l0aCBhbnhpZXR5LCB0aGlzIGVmZmVjdCBkaWQgbm90IHJlYWNoIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSAoJFxiZXRhID0gMC4wNiwgcCA9IC4wNzQkKS4NCg0KVG9nZXRoZXIsIHRoZXNlIHJlc3VsdHMgZGVtb25zdHJhdGUgdGhhdCBjb25maWRlbmNlIGluIG9uZSdzIG1hdGhlbWF0aWNhbCBhYmlsaXR5IGFuZCBzcGVjaWZpYyBpbnN0cnVjdGlvbmFsIG1ldGhvZHMgcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiBzaGFwaW5nIHN0dWRlbnRzJyBtYXRoIGxlYXJuaW5nIGFueGlldHkuIEFwcHJvYWNoZXMgdGhhdCBwcm92aWRlIHN0cnVjdHVyZWQgZ3VpZGFuY2UtLS1zdWNoIGFzIHRlYWNoZXItY2VudGVyZWQgZGVsaXZlcnkgYW5kIHRlY2hub2xvZ3kgaW50ZWdyYXRpb24tLS1hcHBlYXIgdG8gcmVkdWNlIGFueGlldHksIHdoZXJlYXMgZ3JlYXRlciBlbXBoYXNpcyBvbiBpbmRlcGVuZGVudCByZXNvdXJjZS1iYXNlZCBsZWFybmluZyBtYXkgY29udHJpYnV0ZSB0byBpbmNyZWFzZWQgYW54aWV0eS4NCg0KIyBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nIEFwcHJvYWNoDQoNCldoZW4gd29ya2luZyB3aXRoIG11bHRpcGxlIGNvbnN0cnVjdHMsIGVhY2ggbWVhc3VyZWQgYnkgbXVsdGlwbGUgc3VydmV5IGl0ZW1zLCB3ZSBhcmUgd29ya2luZyB3aXRoIGxhdGVudCB2YXJpYWJsZXMuICoqU3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZyAoU0VNKSoqIGlzIGlkZWFsIGJlY2F1c2UgaXQgZXhwbGljaXRseSBtb2RlbHMgdGhlIG1lYXN1cmVtZW50IChyZWxhdGlvbnNoaXBzIGJldHdlZW4gaXRlbXMgYW5kIHRoZWlyIGxhdGVudCBjb25zdHJ1Y3QpIGFuZCBzdHJ1Y3R1cmFsIChyZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIGNvbnN0cnVjdHMpIHBhcnRzIHNpbXVsdGFuZW91c2x5LiBNb2RlbHMgc3VjaCBhcyBsaW5lYXIgcmVncmVzc2lvbiwgbXVsdGl2YXJpYXRlIHJlZ3Jlc3Npb24sIHBhdGggYW5hbHlzaXMsIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMsIGFuZCBzdHJ1Y3R1cmFsIHJlZ3Jlc3Npb24gY2FuIGJlIHRob3VnaHQgb2YgYXMgc3BlY2lhbCBjYXNlcyBvZiBTRU0uIFRoZSBmb2xsb3dpbmcgcmVsYXRpb25zaGlwcyBhcmUgcG9zc2libGUgaW4gU0VNOg0KDQotICAgKm9ic2VydmVkIHRvIG9ic2VydmVkIHZhcmlhYmxlcyogKCRcZ2FtbWEkLCBlLmcuLCByZWdyZXNzaW9uKQ0KLSAgICpsYXRlbnQgdG8gb2JzZXJ2ZWQgdmFyaWFibGVzKiAoJFxsYW1iZGEkLCBlLmcuLCBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzKQ0KLSAgICpsYXRlbnQgdG8gbGF0ZW50IHZhcmlhYmxlcyogKCRcZ2FtbWEsIFxiZXRhJCwgZS5nLiwgc3RydWN0dXJhbCByZWdyZXNzaW9uKQ0KDQpTRU0gdW5pcXVlbHkgZW5jb21wYXNzZXMgYm90aCBtZWFzdXJlbWVudCBhbmQgc3RydWN0dXJhbCBtb2RlbHMuIFRoZSBtZWFzdXJlbWVudCBtb2RlbCByZWxhdGVzIG9ic2VydmVkIHRvIGxhdGVudCB2YXJpYWJsZXMgYW5kIHRoZSBzdHJ1Y3R1cmFsIG1vZGVsIHJlbGF0ZXMgbGF0ZW50IHRvIGxhdGVudCB2YXJpYWJsZXMuIEtsaW5lJ3MgKDIwMjMpIGlzIGEgY2xhc3NpYyBhbmQgbW9kZXJuIHRleHQgY292ZXJzIHVwLXRvLWRhdGUgbWV0aG9kcyBhbmQgYXBwbGljYXRpb25zLiBUaGUgZXN0aW1hdGlvbiBvZiBtb2RlbCBwYXJhbWV0ZXJzIGluIFNFTSBpcyBiYXNlZCBvbiB0aGUgbWF4aW11bSBsaWtlbGlob29kIGZ1bmN0aW9uIHdpdGggdGhlIGFzc3VtcHRpb24gdGhhdCBhbGwgb2JzZXJ2ZWQgdmFyaWFibGVzIGZvbGxvd2luZyBtdWx0aXZhcmlhdGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KIyMgTm90YXRpb25zIGFuZCBUZWNobmljYWwgVGVybXMgaW4gU0VNDQoNCioqU29tZSBUZWNobmljYWwgVGVybXMgaW4gU0VNKio6DQoNCi0gICAqKm9ic2VydmVkIHZhcmlhYmxlKio6IGEgdmFyaWFibGUgdGhhdCBleGlzdHMgaW4gdGhlIGRhdGEsIGEuay5hIGl0ZW0gb3IgbWFuaWZlc3QgdmFyaWFibGUNCg0KLSAgICoqbGF0ZW50IHZhcmlhYmxlKio6IGEgdmFyaWFibGUgdGhhdCBpcyBjb25zdHJ1Y3RlZCBhbmQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGRhdGENCg0KLSAgICoqZXhvZ2Vub3VzIHZhcmlhYmxlKio6IGFuIGluZGVwZW5kZW50IHZhcmlhYmxlIGVpdGhlciBvYnNlcnZlZCAoeCkgb3IgbGF0ZW50ICgkXHhpJCkgdGhhdCBleHBsYWlucyBhbiBlbmRvZ2Vub3VzIHZhcmlhYmxlDQoNCi0gICAqKmVuZG9nZW5vdXMgdmFyaWFibGUqKjogYSBkZXBlbmRlbnQgdmFyaWFibGUsIGVpdGhlciBvYnNlcnZlZCAoeSkgb3IgbGF0ZW50ICgkXGV0YSQpIHRoYXQgaGFzIGEgY2F1c2FsIHBhdGggbGVhZGluZyB0byBpdA0KDQotICAgKiptZWFzdXJlbWVudCBtb2RlbCoqOiBhIG1vZGVsIHRoYXQgbGlua3Mgb2JzZXJ2ZWQgdmFyaWFibGVzIHdpdGggbGF0ZW50IHZhcmlhYmxlcw0KDQotICAgKippbmRpY2F0b3IqKjogYW4gb2JzZXJ2ZWQgdmFyaWFibGUgaW4gYSBtZWFzdXJlbWVudCBtb2RlbCAoY2FuIGJlIGV4b2dlbm91cyBvciBlbmRvZ2Vub3VzKQ0KDQotICAgKipmYWN0b3IqKjogYSBsYXRlbnQgdmFyaWFibGUgZGVmaW5lZCBieSBpdHMgaW5kaWNhdG9ycyAoY2FuIGJlIGV4b2dlbm91cyBvciBlbmRvZ2Vub3VzKQ0KDQotICAgKipsb2FkaW5nKio6IGEgcGF0aCBiZXR3ZWVuIGFuIGluZGljYXRvciBhbmQgYSBmYWN0b3INCg0KLSAgICoqc3RydWN0dXJhbCBtb2RlbCoqOiBhIG1vZGVsIHRoYXQgc3BlY2lmaWVzIGNhdXNhbCByZWxhdGlvbnNoaXBzIGFtb25nIGV4b2dlbm91cyB2YXJpYWJsZXMgdG8gZW5kb2dlbm91cyB2YXJpYWJsZXMgKGNhbiBiZSBvYnNlcnZlZCBvciBsYXRlbnQpDQoNCi0gICAqKnJlZ3Jlc3Npb24gcGF0aCoqOiBhIHBhdGggYmV0d2VlbiBleG9nZW5vdXMgYW5kIGVuZG9nZW5vdXMgdmFyaWFibGVzIChjYW4gYmUgb2JzZXJ2ZWQgb3IgbGF0ZW50KQ0KDQojIyBTRU0gUGF0aCBNb2RlbA0KDQpBIHBhdGggbW9kZWwgc2VydmVzIGFzIHRoZSB2aXN1YWwgYW5kIG1hdGhlbWF0aWNhbCBibHVlcHJpbnQgZm9yIGEgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbCAoU0VNKS4gVGhpcyBkaWFncmFtIGVtcGxveXMgYSBzdGFuZGFyZGl6ZWQgbm90YXRpb24gdG8gcmVwcmVzZW50IGh5cG90aGVzaXplZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzLiBUaGUgc3BlY2lmaWMgbW9kZWwgdG8gYmUgdGVzdGVkLCB3aGljaCBleGFtaW5lcyB0aGUgY29tcGxleCBzdHJ1Y3R1cmFsIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBlbmRvZ2Vub3VzIGFuZCBleG9nZW5vdXMgdmFyaWFibGVzLCBoYXMgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6DQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI3MCUifQ0KaW5jbHVkZV9ncmFwaGljcygiSHlwb3RoZXRpY2FsU0VNLnBuZyIpDQpgYGANCg0KVG8gYmV0dGVyIHVuZGVyc3RhbmQgdGhlIGFkdmFudGFnZXMgYW5kIGRpc2FkdmFudGFnZXMgb2YgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbGluZyAoU0VNKSBmb3IgYW5hbHl6aW5nIGNvbXBsZXggcmVsYXRpb25zaGlwcy0tLXN1Y2ggYXMgdGhvc2UgYmV0d2VlbiBsYXRlbnQgdmFyaWFibGVzIGxpa2UgbWF0aCBldmFsdWF0aW9uIGFuZCBsZWFybmluZyBhbnhpZXR5LiB3ZSB3aWxsIGJyaWVmbHkgZGVzY3JpYmUgaXRzIG1hdGhlbWF0aWNhbCBmb3JtdWxhdGlvbiBhbmQgTUxFIG9mIGFsbCBtb2RlbCBwYXJhbWV0ZXJzIHVzaW5nIHRoZSBhYm92ZSBoeXBvdGhldGljYWwgU0VNIHBhdGggbW9kZWwgaW4gdGhlIGFwcGVuZGl4Lg0KDQojIyBTRU0gSW1wbGVtZW50YXRpb24NCg0KV2UgdXNlIHRoZSBSIGBsYXZhYW5gIGxpYnJhcnkgdG8gaW1wbGVtZW50IHRoZSBTRU0gdG8gYXNzZXNzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtYXRoIGV2YWx1YXRpb24sIGxlYXJuaW5nIGFueGlldHksIGFuZCByZWxhdGVkIGV4b2dlbm91cyB2YXJpYWJsZXMuIFRoZSBvdXRwdXQgcHJlc2VudHMgcmVzdWx0cyBiYXNlZCBvbiBzdGFuZGFyZGl6ZWQgdmFyaWFibGVzLiBUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGlzIHNpbWlsYXIgdG8gdGhhdCBpbiBhIHJlZ3VsYXIgcmVncmVzc2lvbiBtb2RlbCwgaW5kaWNhdGluZyB0aGUgY2hhbmdlIGluIHRoZSBvdXRjb21lIChpbiBzdGFuZGFyZCBkZXZpYXRpb25zKSBmb3IgYSBvbmUtc3RhbmRhcmQtZGV2aWF0aW9uIGluY3JlYXNlIGluIGEgcHJlZGljdG9yLg0KDQoqKlF1aWNrIFJlZmVyZW5jZSBvZiBgbGF2YWFuYCBTeW50YXgqKg0KDQotICAgYH4gcHJlZGljdGAsIHVzZWQgZm9yIHJlZ3Jlc3Npb24gb2Ygb2JzZXJ2ZWQgb3V0Y29tZSB0byBvYnNlcnZlZCBwcmVkaWN0b3JzIChlLmcuLCB5IFx+IHgpDQotICAgYDE9fiBpbmRpY2F0b3IxYCwgdXNlZCBmb3IgbGF0ZW50IHZhcmlhYmxlIHRvIG9ic2VydmVkIGluZGljYXRvciBpbiBmYWN0b3IgYW5hbHlzaXMgbWVhc3VyZW1lbnQgbW9kZWxzIChlLmcuLCBgZiA9fiBxICsgciArIHNgKQ0KLSAgIFxgYH5+YCBjb3ZhcmlhbmNlIChlLmcuLCBgeCB+fiB4YCkNCi0gICBgfjFgIGludGVyY2VwdCBvciBtZWFuIChlLmcuLCBgeCB+IDFgIGVzdGltYXRlcyB0aGUgbWVhbiBvZiB2YXJpYWJsZSB4KQ0KLSAgIGAxKmAgZml4ZXMgcGFyYW1ldGVyIG9yIGxvYWRpbmcgdG8gb25lIChlLmcuLCBgZiA9fiAxKnFgKQ0KLSAgIGBOQSpgIGZyZWVzIHBhcmFtZXRlciBvciBsb2FkaW5nICh1c2VmdWwgdG8gb3ZlcnJpZGUgZGVmYXVsdCBtYXJrZXIgbWV0aG9kLCAoZS5nLiwgYGYgPX4gTkEqcWApDQotICAgYGEqYCBsYWJlbHMgdGhlIHBhcmFtZXRlciAnYScsIHVzZWQgZm9yIG1vZGVsIGNvbnN0cmFpbnRzIChlLmcuLCBgZiA9fiBhKnFgKQ0KDQoNCg0KDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzMjEpDQpBbnhpZXR5Lm1lYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjIiLCAiQU1BUy40IiwgIkFNQVMuNSIsICAiQU1BUy44IildDQpBbnhpZXR5Lm1sYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjEiLCAiQU1BUy4zIiwgIkFNQVMuNiIsICJBTUFTLjciLCAiQU1BUy45IildDQpuYW1lcyhBbnhpZXR5Lm1lYSkgPC0gYygiTUVBMiIsICJNRUE0IiwgIk1FQTUiLCAgIk1FQTgiKSAgDQpuYW1lcyhBbnhpZXR5Lm1sYSkgPC0gYygiTUxBMSIsICJNTEEzIiwgIk1MQTYiLCAiTUxBNyIsICJNTEE5IikNCmZhY3Rvci5uYW1lcyA8LSBjKCJUZWNobm9sb2d5Lnd0LnBjYSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIkVuZ2FnZS53dC5wY2EiLCAic2V4IiwNCiAgICAgICAgICAgICAgICAgICJUZWFjaGVyLmN0cmQud3QucGNhIiwgIlN0dWRlbnQuY3RyZC53dC5wY2EiLCAiUmVzb3VyY2Uud3QucGNhIikNCiMjDQpmYWN0b3IudmFyIDwtIEFueGlldHkuQW5hbHl0aWMuRGF0YVssIGZhY3Rvci5uYW1lc10NCm5hbWVzKGZhY3Rvci52YXIpIDwtIGMoIlRlY2giLCAiRWZmaWNhY3kiLCAiRW5nYWdlIiwgImdlbmRlciIsDQogICAgICAgICAgICAgICAgICAiVGVhY2hlci5jdHJkIiwgIlN0dWRlbnQuY3RyZCIsICJSZXNvdXJjZSIpDQoNCiMjIyBzdHJhdGVnaWVzIHZhcg0Kc3RyYXRneS52YXIgPC1jKCJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsICJJbmR1Y3RpdmUud3QucGNhIiwiSW50ZWdyYXRpdmUud3QucGNhIiAsIkxlY3R1cmVUeXBlLnd0LnBjYSIsICJSZXBldGl0aXZlLnd0LnBjYSIgKQ0Kc3RyYXRlZ3kubmFtZSA8LSBjKCJDb29wIiwgIkRlZHVjIiwgIkRlbW9uIiwgIkluZHVjIiwiSW50ZWciICwiTGVjdCIsICJSZXBldCIgKQ0KdGVhY2hpbmdzdHJhdGVneSA8LSBBbnhpZXR5LkFuYWx5dGljLkRhdGFbLCBzdHJhdGd5LnZhcl0NCm5hbWVzKHRlYWNoaW5nc3RyYXRlZ3kpIDwtIHN0cmF0ZWd5Lm5hbWUgDQpTRU0uZGF0YSA8LSBjYmluZChBbnhpZXR5Lm1lYSwgQW54aWV0eS5tbGEsIGZhY3Rvci52YXIsdGVhY2hpbmdzdHJhdGVneSApDQoNCiMjIyAgU0VNIG1vZGVscw0KDQpTRU1Nb2RlbCA8LQ0KJyBFdmFsLkFueGlldHkgPX4gIE1FQTIgKyBNRUE0ICsgTUVBNSArIE1FQTggICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBFdmFsLkFueGlldHkNCiAgTGVhcm4uQW54aWV0eSA9fiBNTEExICsgTUxBMyArIE1MQTYgKyBNTEE3ICsgTUxBOSAgICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBMZWFybi5BbnhpZXR5IA0KICBUZWFjaGVyQ3RyZCA9fiBEZWR1YyArIExlY3QgKyBEZW1vbiArIFJlcGV0ICAjIFRlYWNoZXIgY2VudGVyZWQNCiAgU3R1ZGVudEN0cmQgPX4gQ29vcCArIEluZHVjICsgSW50ZWcgICMgU3R1ZGVudCBjZW50ZXJlZA0KICBFdmFsLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyQ3RyZCArIFN0dWRlbnRDdHJkICsgUmVzb3VyY2UgICAgIyMgRXZhbC5BbnhpZXR5IGFzIGFuIG91dGNvbWUNCiAgTGVhcm4uQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXJDdHJkKyBTdHVkZW50Q3RyZCArIFJlc291cmNlICAgICMjIExlYXJuLkFueGlldHkgYXMgYW4gb3V0Y29tZQ0KICBFdmFsLkFueGlldHkgfn4gTGVhcm4uQW54aWV0eSAgICAgIyMgY29ycmVsYXRpb24gYmV0d2VlbiBFdmFsLkFueGlldHkgYW5kIExlYXJuLkFueGlldHkgDQonDQogDQpvdXRwdXQgPC0gc2VtKG1vZGVsID0gU0VNTW9kZWwsIGRhdGEgPSBTRU0uZGF0YSwgc3RkLmx2ID0gVFJVRSwgIGVzdGltYXRvciA9ICJXTFNNViIsDQogICAgICAgICAgICAgIG1pbWljID0gIk1wbHVzIikNCnJlc3VsdHMgPC0gc3VtbWFyeShvdXRwdXQsIHN0YW5kYXJkaXplZCA9IFRSVUUsIGZpdC5tZWFzdXJlcyA9IFRSVUUpDQoNCmBgYA0KDQpUaGUgY29tcG9uZW50IHJlZ3Jlc3Npb24gYW5kIGxhdGVudCBtb2RlbHMgaW4gdGhlIFNFTSBhcmUgc3BlY2lmaWVkIGluIHRoZSBmb2xsb3dpbmcuDQoNCmBgYCAgICAgICAgIA0KICAjIyBtZWFzdXJlbWVudCBtb2RlbCBmb3IgRXZhbC5BbnhpZXR5DQogIEV2YWwuQW54aWV0eSA9fiAgTUVBMiArIE1FQTQgKyBNRUE1ICsgTUVBOCAgICAgICAgICAgIA0KICAjIyBtZWFzdXJlbWVudCBtb2RlbCBmb3IgTGVhcm4uQW54aWV0eSANCiAgTGVhcm4uQW54aWV0eSA9fiBNTEExICsgTUxBMyArIE1MQTYgKyBNTEE3ICsgTUxBOSAgDQogICMgTGF0ZW50IHJlZ3Jlc3Npb24gb2YgdGVhY2hpbmcgU3RyYXRlZ2llcw0KICBUZWFjaGVyQ3RyZCA9fiBEZWR1YyArIExlY3QgKyBEZW1vbiArIFJlcGV0ICAjIFRlYWNoZXIgY2VudGVyZWQNCiAgU3R1ZGVudEN0cmQgPX4gQ29vcCArIEluZHVjICsgSW50ZWcgICMgU3R1ZGVudCBjZW50ZXJlZA0KICAjIyBFdmFsLkFueGlldHkgYXMgYW4gb3V0Y29tZQ0KICBFdmFsLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyLmN0cmQgKyBTdHVkZW50LmN0cmQgKyBSZXNvdXJjZSArIHJhY2UgICANCiAgIyMgTGVhcm4uQW54aWV0eSBhcyBhbiBvdXRjb21lDQogIExlYXJuLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyLmN0cmQgKyBTdHVkZW50LmN0cmQgKyBSZXNvdXJjZSArIHJhY2UgIA0KICBFdmFsLkFueGlldHkgfn4gTGVhcm4uQW54aWV0eSAgICAgIyMgY29ycmVsYXRpb24gYmV0d2VlbiBFdmFsLkFueGlldHkgYW5kIExlYXJuLkFueGlldHkgDQpgYGANCg0KVGhlIGtleSBnb29kbmVzcy1vZi1maXQgc3RhdGlzdGljcyBhbmQgZXN0aW1hdGVkIHBhcmFtZXRlcnMgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZy4NCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0KaW50ZXJwcmV0X2ZpdCA8LSBmdW5jdGlvbihmaXRfb2JqKSB7DQogIG1lYXN1cmVzIDwtIGZpdE1lYXN1cmVzKGZpdF9vYmopDQogIA0KICAjY2F0KCI9PT0gU0VNIE1PREVMIEZJVCBBU1NFU1NNRU5UID09PVxuIikNCiAgY2F0KHNwcmludGYoIkNoaS1TcXVhcmU6IM+HwrIoJWQpID0gJS4yZiwgcCA9ICUuM2ZcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1siZGYiXSwgbWVhc3VyZXNbImNoaXNxIl0sIG1lYXN1cmVzWyJwdmFsdWUiXSkpDQogIGNhdChzcHJpbnRmKCJDRkk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJjZmkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJUTEk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJ0bGkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJSTVNFQTogJS4zZiBbOTAlJSBDSTogJS4zZiwgJS4zZl0gJXNcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1sicm1zZWEiXSwgbWVhc3VyZXNbInJtc2VhLmNpLmxvd2VyIl0sIG1lYXN1cmVzWyJybXNlYS5jaS51cHBlciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInJtc2VhIl0gPD0gMC4wNiwgIihFeGNlbGxlbnQpIiwNCiAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShtZWFzdXJlc1sicm1zZWEiXSA8PSAwLjA4LCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJTUk1SOiAlLjNmICVzXG4iLCBtZWFzdXJlc1sic3JtciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInNybXIiXSA8PSAwLjA4LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJzcm1yIl0gPD0gMC4xMCwgIihBY2NlcHRhYmxlKSIsICIoUG9vcikiKSkpKQ0KfQ0KDQojIyMNCnJlcG9ydF9zZW0gPC0gZnVuY3Rpb24oZml0LCBtb2RlbF9uYW1lID0gIlRoZSBTRU0iKSB7DQogIA0KICAjIEZpdCBtZWFzdXJlcw0KICBmaXRfbWVhcyA8LSBmaXRNZWFzdXJlcyhmaXQsIGMoImNoaXNxIiwgImRmIiwgInB2YWx1ZSIsICJjZmkiLCAidGxpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJybXNlYSIsICJybXNlYS5jaS5sb3dlciIsICJybXNlYS5jaS51cHBlciIsICJzcm1yIikpDQogIA0KICAjIFBhcmFtZXRlcnMNCiAgcGFyYW1zIDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogIHN0ZF9wYXJhbXMgPC0gc3RhbmRhcmRpemVkU29sdXRpb24oZml0KQ0KICANCiAgY2F0KCI9PT0gU1RSVUNUVVJBTCBFUVVBVElPTiBNT0RFTElORyBSRVNVTFRTID09PVxuXG4iKQ0KICBjYXQoIk1PREVMIEZJVDpcbiIpDQogIA0KICAjIFVzZSB0aGUgZnVuY3Rpb24NCiAgaW50ZXJwcmV0X2ZpdChvdXRwdXQpDQogIGNhdCgiXG5cbiIpDQogICMgU2lnbmlmaWNhbnQgc3RydWN0dXJhbCBwYXRocw0KICBzaWdfcGF0aHMgPC0gc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiAmIHN0ZF9wYXJhbXMkcHZhbHVlIDwgMC4xLCBdDQogIGlmIChucm93KHNpZ19wYXRocykgPiAwKSB7DQogICAgY2F0KCJTSUdOSUZJQ0FOVCBTVFJVQ1RVUkFMIFBBVEhTOlxuIikNCiAgICBmb3IgKGkgaW4gMTpucm93KHNpZ19wYXRocykpIHsNCiAgICAgIGNhdChzcHJpbnRmKCItICVzIOKGkiAlczogzrIgPSAlLjJmLCBwID0gJS4zZlxuIiwNCiAgICAgICAgICAgICAgICAgIHNpZ19wYXRocyRyaHNbaV0sIHNpZ19wYXRocyRsaHNbaV0sDQogICAgICAgICAgICAgICAgICBzaWdfcGF0aHMkZXN0W2ldLCBzaWdfcGF0aHMkcHZhbHVlW2ldKSkNCiAgICB9DQogICAgY2F0KCJcbiIpDQogIH0NCiAgDQogICMgZmFjdG9yIGxvYWRpbmcgZm9yIGxhdGVudCB2YXJpYWJsZXMNCiAgY2F0KCJcblxuRkFDVE9SIExPQURJTkdTXG5cbiIpDQogIA0KICBwcmludChzdGRfcGFyYW1zW3N0ZF9wYXJhbXMkb3AgPT0gIj1+IiwgXSkNCiAgDQogICMjIyMjDQogICMgUi1zcXVhcmVkDQogIHIyIDwtIGluc3BlY3QoZml0LCAicjIiKQ0KICBpZiAobGVuZ3RoKHIyKSA+IDApIHsNCiAgICBjYXQoIlZBUklBTkNFIEVYUExBSU5FRCAoUsKyKTpcblxuIikNCiAgICBmb3IgKGkgaW4gMTpsZW5ndGgocjIpKSB7DQogICAgICBjYXQoc3ByaW50ZigiLSAlczogJS4xZiUlXG4iLCBuYW1lcyhyMilbaV0sIHIyW2ldICogMTAwKSkNCiAgICB9DQogIH0NCiAgDQogICMjIFJlZ3Jlc3Npb24gY29lZmZpY2llbnRzDQogIA0KICBjYXQoIlxuXG5DT0VGRklDSUVOVFMgT0YgUkVHUkVTU0lPTlxuXG4iKQ0KICANCiAgcHJpbnQoc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiwgXSkNCiAgDQogICAgICMgQ292YXJpYW5jZSBiZXR3ZWVuIE1hdGggQW54aWV0aWVzDQogICAgICAjcGFyYW1fZXN0IDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogICAgIGNvdl9sYXRlbnQgPC0gc3RkX3BhcmFtc1sNCiAgICAgICAgICAgICAgc3RkX3BhcmFtcyRsaHMgPT0gIk1hdGhFdmFsIiAmIA0KICAgICAgICAgICAgICBzdGRfcGFyYW1zJHJocyA9PSAiTGVhcm5BbngiICYgDQogICAgICAgICAgICAgIHN0ZF9wYXJhbXMkb3AgPT0gIn5+IiwNCiAgICAgICAgICBdDQogICAgICMjIw0KICAgICBjYXQoIlxuXG5DT1ZBUklBTkNFIDpcbiIpDQogICAgIGxhdGVudF9jb3ZfbWF0cml4IDwtIGxhdkluc3BlY3QoZml0LCAiZXN0IikkcHNpDQogICAgIGNvdl9vdXQgPC0gbGF0ZW50X2Nvdl9tYXRyaXhbIkxlYXJuLkFueGlldHkiLCAiRXZhbC5BbnhpZXR5Il0NCiAgICAgY2F0KCItIExlYXJuLkFueGlldHkgYW5kIEV2YWwuQW54aWV0eToiLCBjb3Zfb3V0KQ0KfQ0KDQojIFVzZSB0aGUgZnVuY3Rpb24NCiNyZXBvcnRfc2VtKG91dHB1dCwgIk1hdGggQW54aWV0eSIpDQpgYGANCg0KVGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGFuZCBmYWN0b3IgbG9hZGluZ3MgaW4gdGhlIGFib3ZlIHRhYmxlIGFyZSBzdW1tYXJpemVkIGluIHRoZSBmb2xsb3dpbmcgU0VNIHBhdGggZGlhZ3JhbSBnZW5lcmF0ZWQgdXNpbmcgYGxhdmFhblBsb3RgIGZ1bmN0aW9uLg0KDQpgYGB7cn0NCmxhdmFhblBsb3QobW9kZWwgPSBvdXRwdXQsDQogICAgICAgICAgIGNvZWZzID0gVFJVRSwNCiAgICAgICAgICAgc3RhbmQgPSBUUlVFLA0KICAgICAgICAgICBzdGFycyA9IGMoInJlZ3Jlc3MiKSkgICMgQWRkIHNpZ25pZmljYW5jZSBzdGFycw0KYGBgDQoNClRoZSBwYXRoIGRpYWdyYW0gZ2VuZXJhdGVkIGJ5IFIgZm9yIHRoZSBTRU0gYW5hbHlzaXMgaXMgbm90IGVhc3kgdG8gcmVhZC4gVGhlcmVmb3JlLCB3ZSBza2V0Y2hlZCBhIG5ldyBwYXRoIGRpYWdyYW0gdGhhdCBpbmNsdWRlcyBvbmx5IHRoZSBzaWduaWZpY2FudCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBhbmQgZmFjdG9yIGxvYWRpbmdzLg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIkZpdHRlZGxTRU0ucG5nIikNCmBgYA0KDQojIyBSZXN1bHRzIGFuZCBEaXNjdXNzaW9uIG9mIFNFTSBBbmx5c2lzDQoNCkEgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCAoU0VNKSB3YXMgZXN0aW1hdGVkIHRvIGV4YW1pbmUgdGhlIGVmZmVjdHMgb2YgcGVyY2VpdmVkIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYW5kIHN0dWRlbnQgY2hhcmFjdGVyaXN0aWNzIG9uIHR3byBkaW1lbnNpb25zIG9mIG1hdGhlbWF0aWNzIGFueGlldHk6ICoqTWF0aCBFdmFsdWF0aW9uIEFueGlldHkgKE1FQSkqKiBhbmQgKipNYXRoIExlYXJuaW5nIEFueGlldHkgKE1MQSkqKi4gVGhlIG1vZGVsIGRlbW9uc3RyYXRlZCBleGNlbGxlbnQgZml0IHRvIHRoZSBkYXRhOg0KDQokJA0KXGNoaV4yKDE2OCkgPSA1NDIuNzUsIFwsIHAgPCAuMDAxLCBcLA0KXHRleHR7Q0ZJfSA9IC45NjgsIFwsDQpcdGV4dHtUTEl9ID0gLjk2MiwgXCwNClx0ZXh0e1JNU0VBfSA9IC4wNTcgXCwgWzkwXCUgXHRleHR7Q0kgfSAuMDUxLCAuMDYyXSwgXCwNClx0ZXh0e1NSTVJ9ID0gLjA1OS4NCiQkDQoNClwNCg0KKipNZWFzdXJlbWVudCBNb2RlbCoqDQoNClN0YW5kYXJkaXplZCBsb2FkaW5ncyB3ZXJlIGNvbnNpc3RlbnRseSBzdHJvbmcgYWNyb3NzIGxhdGVudCBmYWN0b3JzICgkXGxhbWJkYSA9IC41MyTigJMuODkpLCBzdXBwb3J0aW5nIHJlbGlhYmlsaXR5IGFuZCBjb252ZXJnZW50IHZhbGlkaXR5LiBUaGUgbW9kZWwgZXhwbGFpbmVkIDQyLjklIG9mIHRoZSB2YXJpYW5jZSBpbiBNRUEgYW5kIDI5LjclIGluIE1MQS4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0KVGFibGUxIDwtIGRhdGEuZnJhbWUoDQogIExhdGVudF9WYXJpYWJsZSA9IGMoIk1hdGggRXZhbHVhdGlvbiBBbnhpZXR5IiwgIiIsICIiLCAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAiTWF0aCBMZWFybmluZyBBbnhpZXR5IiwgIiIsICIiLCAiIiwgIiIsDQogICAgICAgICAgICAgICAgICAgICAgIlRlYWNoZXItQ2VudGVyZWQiLCAiIiwgIiIsICIiLA0KICAgICAgICAgICAgICAgICAgICAgICJTdHVkZW50LUNlbnRlcmVkIiwgIiIsICIiKSwNCiAgSW5kaWNhdG9yID0gYygiTUVBMiIsIk1FQTQiLCJNRUE1IiwiTUVBOCIsDQogICAgICAgICAgICAgICAgIk1MQTEiLCJNTEEzIiwiTUxBNiIsIk1MQTciLCJNTEE5IiwNCiAgICAgICAgICAgICAgICAiRGVkdWN0aXZlIiwiTGVjdHVyZSBUeXBlIiwiRGVtb25zdHJhdGlvbiIsIlJlcGV0aXRpdmUiLA0KICAgICAgICAgICAgICAgICJDb29wZXJhdGl2ZSIsIkluZHVjdGl2ZSIsIkludGVncmF0aXZlIiksDQogIExhbWJkYSA9IGMoLjg4LC44NCwuNjcsLjY1LA0KICAgICAgICAgICAgIC41MywuNzEsLjc0LC42NCwuNzMsDQogICAgICAgICAgICAgLjg4LC44OSwuODAsLjc1LA0KICAgICAgICAgICAgIC43MywuODcsLjY4KSwNCiAgUjIgPSBjKC43NywuNzAsLjQ1LC40MiwNCiAgICAgICAgIC4yOCwuNTEsLjU0LC40MCwuNTQsDQogICAgICAgICAuNzgsLjc5LC42NCwuNTYsDQogICAgICAgICAuNTQsLjc2LC40NikNCikNCg0Ka2FibGUoVGFibGUxLCBjYXB0aW9uID0gIlRhYmxlIDEuIFN0YW5kYXJkaXplZCBGYWN0b3IgTG9hZGluZ3MgYW5kIFZhcmlhbmNlIEV4cGxhaW5lZCBmb3IgTGF0ZW50IENvbnN0cnVjdHMiKQ0KYGBgDQoNCg0KKipTdHJ1Y3R1cmFsIE1vZGVsKioNCg0KDQpTdGFuZGFyZGl6ZWQgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgYXJlIHNob3duIGluIFRhYmxlIDIuIE5lZ2F0aXZlIGNvZWZmaWNpZW50cyBpbmRpY2F0ZSByZWR1Y2VkIGFueGlldHkuDQoNCmBgYHtyfQ0KVGFibGUyIDwtIGRhdGEuZnJhbWUoDQpQcmVkaWN0b3IgPSBjKCJUZWNobm9sb2d5IFVzZSIsIlNlbGYtRWZmaWNhY3kiLCJHZW5kZXIiLA0KIlRlY2hub2xvZ3kgVXNlIiwiU2VsZi1FZmZpY2FjeSIsIkVuZ2FnZW1lbnQiLA0KIlRlYWNoZXItQ2VudGVyZWQgU3RyYXRlZ2llcyIsIlN0dWRlbnQtQ2VudGVyZWQgU3RyYXRlZ2llcyIsIlJlc291cmNlIEF2YWlsYWJpbGl0eSIpLA0KT3V0Y29tZSA9IGMoIkV2YWx1YXRpb24gQW54aWV0eSIsIkV2YWx1YXRpb24gQW54aWV0eSIsIkV2YWx1YXRpb24gQW54aWV0eSIsDQoiTGVhcm5pbmcgQW54aWV0eSIsIkxlYXJuaW5nIEFueGlldHkiLCJMZWFybmluZyBBbnhpZXR5IiwNCiJMZWFybmluZyBBbnhpZXR5IiwiTGVhcm5pbmcgQW54aWV0eSIsIkxlYXJuaW5nIEFueGlldHkiKSwNCkJldGEgPSBjKC0uMTYsLS40OSwtLjE0LA0KLS4yMiwtLjQ1LC0uMDksDQoxLjU0LC0xLjg3LC4xMyksDQpTRSA9IGMoLjA0LC4wMywuMDQsDQouMDQsLjA0LC4wNCwNCi44MiwuODIsLjA0KSwNCnogPSBjKC0zLjkxLC0xNC41NiwtMy44OCwNCi01LjE0LC0xMi41OCwtMi41MCwNCjEuODgsLTIuMjksMy4wNyksDQpwID0gYygiPCAuMDAxIiwiPCAuMDAxIiwiPCAuMDAxIiwNCiI8IC4wMDEiLCI8IC4wMDEiLCIuMDEyIiwNCiIuMDYwIiwiLjAyMiIsIi4wMDIiKQ0KKQ0KDQprYWJsZShUYWJsZTIsIGNhcHRpb24gPSAiVGFibGUgMi4gU3RhbmRhcmRpemVkIFN0cnVjdHVyYWwgUmVncmVzc2lvbiBQYXRocyBQcmVkaWN0aW5nIE1hdGggQW54aWV0eSIpDQpgYGANCg0KQ29uc2lzdGVudCB3aXRoIGV4cGVjdGF0aW9ucywgDQoqICoqTW9yZSBlZmZlY3RpdmVseSB1c2luZyB0ZWNobm9sb2d5KiogcmVkdWNlZCBNRUEgKCRcYmV0YSA9IC0wLjE2JCwgJHAgPCAuMDAxJCkgYW5kIE1MQSAoJFxiZXRhID0gLTAuMjIkLCAkcCA8IC4wMDEkKS4gDQoqICoqSGlnaGVyIFNlbGYtZWZmaWNhY3kqKiBzdHVkZW50cyB0ZW5kZWQgdG8gaGF2ZSBsb3dlciBNRUEgKCRcYmV0YSA9IC0wLjQ5JCwgJHAgPCAuMDAxJCkgYW5kIE1MQSAoJFxiZXRhID0gLTAuNDUkLCAkcCA8IC4wMDEkKS4gDQoqICoqTW9yZSBFbmdhZ2VtZW50KiogcmVkdWNlZCBNTEEgKCRcYmV0YSA9IC0wLjA5JCwgJHAgPSAuMDEyJCksIGFuZCANCiogKipnZW5kZXIqIHdhcyBzaWduaWZpY2FudC4gTWFsZSBzdHVkZW50cyB0ZW5kZWQgdG8gaGF2ZSBsb3dlciBNRUEgKCRcYmV0YSA9IC0wLjE0JCwgJHAgPCAuMDAxJCkuDQoNClJlZ2FyZGluZyB0ZWFjaGluZyBhcHByb2FjaGVzLCANCiogKipzdHVkZW50LWNlbnRlcmVkIHN0cmF0ZWdpZXMqKiBzaWduaWZpY2FudGx5IHJlZHVjZWQgTUxBICgkXGJldGEgPSAtMS44NyQsICRwID0gLjAyMiQpLiANCiogKipUZWFjaGVyLWNlbnRlcmVkIHN0cmF0ZWdpZXMqKiBzaG93ZWQgYSBtYXJnaW5hbGx5IHBvc2l0aXZlIGFzc29jaWF0aW9uIHdpdGggTUxBICgkXGJldGEgPSAxLjU0JCwgJHAgPSAuMDYwJCk7IGhvd2V2ZXIsIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGluY2x1ZGVkIHplcm8uIE5laXRoZXIgc3RyYXRlZ3kgc2lnbmlmaWNhbnRseSBwcmVkaWN0ZWQgTUVBICgkcCA+IC4xMCQpLg0KDQpBIG1vZGVyYXRlLCBwb3NpdGl2ZSBjb3ZhcmlhbmNlIHJlbWFpbmVkIGJldHdlZW4gTUVBIGFuZCBNTEE6DQoNCiQkDQpccGhpX3tNRUEsTUxBfSA9IDAuNTAuDQokJA0KICANCiAgDQppbmRpY2F0aW5nIHRoYXQgc3R1ZGVudHMgd2hvIGV4cGVyaWVuY2VkIGFueGlldHkgZHVyaW5nIGxlYXJuaW5nIGFsc28gdGVuZGVkIHRvIGV4cGVyaWVuY2UgYW54aWV0eSBpbiBldmFsdWF0aXZlIHNpdHVhdGlvbnMuIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIGVpeHRpbmcgcmVzZWFyY2ggYXMgcmV2aWV3ZWQgZWFybGllci4NCg0KVGhlc2UgZmluZGluZ3Mgc3VnZ2VzdCB0aGF0IHN1cHBvcnRpdmUgaW5zdHJ1Y3Rpb25hbCBhcHByb2FjaGVz4oCUcGFydGljdWxhcmx5IHRob3NlIGVtcGhhc2l6aW5nIGNvbGxhYm9yYXRpb24sIGlucXVpcnksIGFuZCBzdHVkZW50IHBhcnRpY2lwYXRpb27igJRwbGF5IGFuIGltcG9ydGFudCByb2xlIGluIHJlZHVjaW5nIHN0dWRlbnRz4oCZIGVtb3Rpb25hbCBiYXJyaWVycyB0byBtYXRoZW1hdGljcyBsZWFybmluZy4NCg0KXA0KDQojIyBEaXNjdXNzaW9uDQoNClRoZSBwdXJwb3NlIG9mIHRoaXMgc3R1ZHkgd2FzIHRvIGV4YW1pbmUgaG93IHBlcmNlaXZlZCB0ZWFjaGluZyBzdHJhdGVnaWVzLCBzZWxmLWVmZmljYWN5LCB0ZWNobm9sb2d5IHVzZSwgZW5nYWdlbWVudCwgYW5kIHJlc291cmNlIGF2YWlsYWJpbGl0eSByZWxhdGUgdG8gdHdvIGZvcm1zIG9mIG1hdGhlbWF0aWNzIGFueGlldHk6ICoqTWF0aCBFdmFsdWF0aW9uIEFueGlldHkgKE1FQSkqKiBhbmQgKipNYXRoIExlYXJuaW5nIEFueGlldHkgKE1MQSkqKi4gVGhlIHJlc3VsdHMgb2YgdGhlIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWwgKFNFTSkgcHJvdmlkZWQgc3Ryb25nIHN1cHBvcnQgZm9yIHRoZSBoeXBvdGhlc2l6ZWQgYXNzb2NpYXRpb25zIGFuZCBoaWdobGlnaHRlZCBpbnN0cnVjdGlvbmFsIHByYWN0aWNlcyB0aGF0IG1heSBiZSBwYXJ0aWN1bGFybHkgZWZmZWN0aXZlIGZvciByZWR1Y2luZyBzdHVkZW50c+KAmSBlbW90aW9uYWwgY2hhbGxlbmdlcyBpbiBtYXRoZW1hdGljcyBjb250ZXh0cy4NCg0KIyMjIEludGVycHJldGF0aW9uIG9mIEtleSBGaW5kaW5ncw0KDQpDb25zaXN0ZW50IHdpdGggcHJldmlvdXMgcmVzZWFyY2gsICoqc3R1ZGVudC1jZW50ZXJlZCBzdHJhdGVnaWVzKiogc2lnbmlmaWNhbnRseSByZWR1Y2VkIGxlYXJuaW5nLXJlbGF0ZWQgYW54aWV0eSwgc3VnZ2VzdGluZyB0aGF0IGxlYXJuaW5nIGVudmlyb25tZW50cyBwcm9tb3RpbmcgY29sbGFib3JhdGlvbiwgaW5xdWlyeSwgYW5kIGFjdGl2ZSBlbmdhZ2VtZW50IGNhbiBtaXRpZ2F0ZSBuZWdhdGl2ZSBlbW90aW9uYWwgcmVzcG9uc2VzLiBTdWNoIHByYWN0aWNlcyBtYXkgaGVscCBzdHVkZW50cyBmZWVsIG1vcmUgY29tcGV0ZW50IGFuZCBzdXBwb3J0ZWQsIHJlZHVjaW5nIGFueGlldHkgZHVyaW5nIG1hdGggbGVhcm5pbmcuDQoNCioqVGVhY2hlci1jZW50ZXJlZCBhcHByb2FjaGVzKiogc2hvd2VkIGEgbWFyZ2luYWxseSBwb3NpdGl2ZSBhc3NvY2lhdGlvbiB3aXRoIGxlYXJuaW5nIGFueGlldHkuIFdoaWxlIGRpcmVjdCBpbnN0cnVjdGlvbiBtYXkgcHJvdmlkZSBjbGFyaXR5IGFuZCBzdHJ1Y3R1cmUsIGV4Y2Vzc2l2ZSBlbXBoYXNpcyBvbiBwZXJmb3JtYW5jZSBhbmQgY29ycmVjdG5lc3MgbWF5IGluYWR2ZXJ0ZW50bHkgaGVpZ2h0ZW4gcHJlc3N1cmUgYW5kIGxlYWQgdG8gaW5jcmVhc2VkIGFueGlldHkgKFJhbWlyZXogZXQgYWwuLCAyMDE4KS4gVGhlc2UgcmVzdWx0cyBzdWdnZXN0IHRoYXQgYWx0aG91Z2ggdGVhY2hlciBndWlkYW5jZSByZW1haW5zIGltcG9ydGFudCwgYmFsYW5jZWQgaW5zdHJ1Y3Rpb25hbCBhcHByb2FjaGVzIG1heSBiZSBuZWNlc3NhcnkgdG8gcHJldmVudCBhZHZlcnNlIGVtb3Rpb25hbCBlZmZlY3RzLg0KDQpCb3RoICoqc2VsZi1lZmZpY2FjeSoqIGFuZCAqKnRlY2hub2xvZ3kgdXNlKiogY29uc2lzdGVudGx5IHByZWRpY3RlZCBsb3dlciBNRUEgYW5kIE1MQS4gU3R1ZGVudHMgd2hvIGJlbGlldmUgaW4gdGhlaXIgYWJpbGl0eSB0byBzdWNjZWVkIHRlbmQgdG8gYXBwcm9hY2ggbWF0aCB0YXNrcyB3aXRoIG1vcmUgY29uZmlkZW5jZSBhbmQgcGVyc2lzdGVuY2UsIHdoaWNoIHByb3RlY3RzIGFnYWluc3QgYW54aWV0eSAoQmFuZHVyYSwgMTk5NzsgVXNoZXIgZXQgYWwuLCAyMDE5KS4gVGVjaG5vbG9neS1lbmhhbmNlZCBsZWFybmluZyBvcHBvcnR1bml0aWVz4oCUc3VjaCBhcyBpbW1lZGlhdGUgZmVlZGJhY2sgYW5kIGludGVyYWN0aXZlIHByYWN0aWNl4oCUbWF5IGFsc28gaW5jcmVhc2UgY29tZm9ydCBhbmQgY29udHJvbCB3aGVuIGVuZ2FnaW5nIHdpdGggbWF0aCBjb250ZW50Lg0KDQpBbHRob3VnaCBzbWFsbGVyIGluIG1hZ25pdHVkZSwgKiplbmdhZ2VtZW50KiogYWxzbyBjb250cmlidXRlZCB0byByZWR1Y2VkIGFueGlldHkgZHVyaW5nIGxlYXJuaW5nLiBXaGVuIHN0dWRlbnRzIGFyZSBlbW90aW9uYWxseSBhbmQgYmVoYXZpb3JhbGx5IGludmVzdGVkIGluIG1hdGggYWN0aXZpdGllcywgdGhleSBtYXkgZXhwZXJpZW5jZSBpbmNyZWFzZWQgZW5qb3ltZW50IGFuZCByZWR1Y2VkIGF2b2lkYW5jZSB0ZW5kZW5jaWVzIChEb3drZXIgZXQgYWwuLCAyMDE2KS4gSW4gY29udHJhc3QsICoqcmVzb3VyY2UgYXZhaWxhYmlsaXR5Kiogd2FzIGFzc29jaWF0ZWQgd2l0aCBzbGlnaHRseSBoaWdoZXIgbGVhcm5pbmcgYW54aWV0eS4gVGhpcyBtYXkgcmVmbGVjdCBoZWlnaHRlbmVkIGV4cGVjdGF0aW9ucyBvciBwZXJjZWl2ZWQgcHJlc3N1cmUgdG8gbWVldCBhY2FkZW1pYyBzdGFuZGFyZHMgd2hlbiBtb3JlIHN1cHBvcnRzIGFyZSBhdmFpbGFibGUuDQoNCkZpbmFsbHksIHRoZSAqKnBvc2l0aXZlIGNvdmFyaWFuY2UqKiBiZXR3ZWVuIE1FQSBhbmQgTUxBIGluZGljYXRlZCBtZWFuaW5nZnVsIG92ZXJsYXAgYmV0d2VlbiB0aGUgdHdvIGNvbnN0cnVjdHMsIGNvbnNpc3RlbnQgd2l0aCB0aGUgbGl0ZXJhdHVyZSBzaG93aW5nIHNoYXJlZCBlbW90aW9uYWwsIGNvZ25pdGl2ZSwgYW5kIG1vdGl2YXRpb25hbCB1bmRlcnBpbm5pbmdzIG9mIGRpZmZlcmVudCBmb3JtcyBvZiBtYXRoIGFueGlldHkgKEFzaGNyYWZ0ICYgTW9vcmUsIDIwMDkpLiBUb2dldGhlciwgdGhlc2UgZmluZGluZ3MgZW1waGFzaXplIHRoZSBpbXBvcnRhbmNlIG9mIGluc3RydWN0aW9uYWwgYW5kIG1vdGl2YXRpb25hbCBmYWN0b3JzIGluIHNoYXBpbmcgc3R1ZGVudHPigJkgbWF0aC1yZWxhdGVkIGVtb3Rpb25hbCBleHBlcmllbmNlcy4NCg0KIyMjIEltcGxpY2F0aW9ucw0KDQpUaGVzZSBmaW5kaW5ncyBzdWdnZXN0IHRoYXQgZWR1Y2F0b3JzIHNob3VsZCBmb3N0ZXIgZW52aXJvbm1lbnRzIHRoYXQgcHJvbW90ZSBzdHVkZW50IGF1dG9ub215IGFuZCBjb25maWRlbmNlLCB3aGlsZSB1c2luZyBpbnN0cnVjdGlvbmFsIHN1cHBvcnRzIHRoYXQgZW5oYW5jZSB1bmRlcnN0YW5kaW5nIHdpdGhvdXQgaW5jcmVhc2luZyBwZXJjZWl2ZWQgcHJlc3N1cmUuIFByb2Zlc3Npb25hbCBsZWFybmluZyBwcm9ncmFtcyBtYXkgYmVuZWZpdCBmcm9tIGVtcGhhc2l6aW5nIHN0cmF0ZWdpZXMgdGhhdCBidWlsZCBlbW90aW9uYWwgc2FmZXR5IGFuZCBzdXBwb3J0IHN0dWRlbnRz4oCZIGJlbGllZiBpbiB0aGVpciBtYXRoZW1hdGljYWwgY2FwYWJpbGl0eSAoSGVtYnJlZSwgMTk5MCkuIEFkZGl0aW9uYWxseSwgdGVjaG5vbG9neSB0b29scyBzaG91bGQgYmUgbGV2ZXJhZ2VkIHN0cmF0ZWdpY2FsbHkgdG8gcHJvbW90ZSBhY3RpdmUgcGFydGljaXBhdGlvbiBhbmQgc2VsZi1wYWNlZCBlbmdhZ2VtZW50LCByYXRoZXIgdGhhbiBhcyBzdGFuZC1hbG9uZSByZXNvdXJjZXMuDQoNCiMjIyBMaW1pdGF0aW9ucyBhbmQgRnV0dXJlIERpcmVjdGlvbnMNCg0KVGhlIGNyb3NzLXNlY3Rpb25hbCBkZXNpZ24gbGltaXRzIHRoZSBhYmlsaXR5IHRvIGRyYXcgY2F1c2FsIGNvbmNsdXNpb25zLiBMb25naXR1ZGluYWwgYW5kIGludGVydmVudGlvbi1iYXNlZCByZXNlYXJjaCBjb3VsZCBzdHJlbmd0aGVuIHVuZGVyc3RhbmRpbmcgb2YgaG93IHRoZSBpZGVudGlmaWVkIGZhY3RvcnMgY29udHJpYnV0ZSB0byBhbnhpZXR5IHJlZHVjdGlvbiBvdmVyIHRpbWUuIFNlbGYtcmVwb3J0IHN1cnZleSBtZXRob2RzIG1heSBpbnRyb2R1Y2Ugc29jaWFsIGRlc2lyYWJpbGl0eSBvciByZWNhbGwgYmlhczsgdGhlcmVmb3JlLCBtdWx0aW1ldGhvZCBhcHByb2FjaGVzIGluY29ycG9yYXRpbmcgb2JzZXJ2YXRpb25hbCBvciBwaHlzaW9sb2dpY2FsIGRhdGEgY291bGQgZnVydGhlciB2YWxpZGF0ZSBmaW5kaW5ncy4gRnV0dXJlIHdvcmsgbWF5IGFsc28gZXhwbG9yZSBpbnN0cnVjdGlvbmFsIGNvbnRleHQsIHN1Y2ggYXMgY2xhc3Nyb29tIGNsaW1hdGUgb3IgdGVhY2hlciBhdHRpdHVkZXMsIGFzIG1vZGVyYXRvcnMgb2YgdGhlIGFueGlldHnigJNzdHJhdGVneSByZWxhdGlvbnNoaXAuDQoNCiMjIyBDb25jbHVzaW9uDQoNCk92ZXJhbGwsIHRoaXMgc3R1ZHkgZGVtb25zdHJhdGVzIHRoYXQgbWF0aCBhbnhpZXR5IGlzIHNoYXBlZCBieSBhIGNvbWJpbmF0aW9uIG9mIGluc3RydWN0aW9uYWwgcHJhY3RpY2VzIGFuZCBwZXJzb25hbCBiZWxpZWZzLiBFbmNvdXJhZ2luZyBzdHVkZW50LWNlbnRlcmVkIGluc3RydWN0aW9uLCBzZWxmLWVmZmljYWN5IGJ1aWxkaW5nLCB0ZWNobm9sb2d5IGludGVncmF0aW9uLCBhbmQgaGlnaC1xdWFsaXR5IGVuZ2FnZW1lbnQgY2FuIHN1YnN0YW50aWFsbHkgcmVkdWNlIGJvdGggbGVhcm5pbmctcmVsYXRlZCBhbmQgZXZhbHVhdGlvbi1yZWxhdGVkIGFueGlldHkuIFRoZXNlIHJlc3VsdHMgdW5kZXJzY29yZSB0aGUgaW1wb3J0YW5jZSBvZiBzdXBwb3J0aW5nIHN0dWRlbnRz4oCZIGVtb3Rpb25hbCB3ZWxsLWJlaW5nIGFzIGEgZm91bmRhdGlvbiBmb3IgdGhlaXIgbWF0aGVtYXRpY2FsIHN1Y2Nlc3MuDQoNCg0KXA0KDQojIFJlZmVyZW5jZXMNCg0KQXNoY3JhZnQsIE0uIEguICgyMDAyKS4gTWF0aCBhbnhpZXR5OiBQZXJzb25hbCwgZWR1Y2F0aW9uYWwsIGFuZCBjb2duaXRpdmUgY29uc2VxdWVuY2VzLiBDdXJyZW50IGRpcmVjdGlvbnMgaW4gcHN5Y2hvbG9naWNhbCBzY2llbmNlLCAxMSg1KSwgMTgxLTE4NS4NCg0KQXNoY3JhZnQsIE0uIEguLCAmIE1vb3JlLCBBLiBNLiAoMjAwOSkuIE1hdGhlbWF0aWNzIGFueGlldHkgYW5kIHRoZSBhZmZlY3RpdmUgZHJvcCBpbiBwZXJmb3JtYW5jZS4gSm91cm5hbCBvZiBQc3ljaG9lZHVjYXRpb25hbCBhc3Nlc3NtZW50LCAyNygzKSwgMTk3LTIwNS4NCg0KQXNwYXJvdWhvdiwgVC4sICYgTXV0aMOpbiwgQi4gKDIwMDUsIE5vdmVtYmVyKS4gTXVsdGl2YXJpYXRlIHN0YXRpc3RpY2FsIG1vZGVsaW5nIHdpdGggc3VydmV5IGRhdGEuIEluIFByb2NlZWRpbmdzIG9mIHRoZSBGZWRlcmFsIENvbW1pdHRlZSBvbiBTdGF0aXN0aWNhbCBNZXRob2RvbG9neSAoRkNTTSkgcmVzZWFyY2ggY29uZmVyZW5jZSAocHAuIDE0LTE2KS4NCg0KQmFuZGFsb3MsIEQuIEwuICgyMDE4KS4gTWVhc3VyZW1lbnQgdGhlb3J5IGFuZCBhcHBsaWNhdGlvbnMgZm9yIHRoZSBzb2NpYWwgc2NpZW5jZXMuIEd1aWxmb3JkIFB1YmxpY2F0aW9ucy4NCg0KQmFuZHVyYSwgQS4gKDE5OTcpLiBTZWxmLWVmZmljYWN5OiBUaGUgZXhlcmNpc2Ugb2YgY29udHJvbCAoVm9sLiAxMSkuIEZyZWVtYW4uDQoNCkJvYWxlciwgSi4gKDIwMTUpLiBNYXRoZW1hdGljYWwgbWluZHNldHM6IFVubGVhc2hpbmcgc3R1ZGVudHMnIHBvdGVudGlhbCB0aHJvdWdoIGNyZWF0aXZlIG1hdGgsIGluc3BpcmluZyBtZXNzYWdlcyBhbmQgaW5ub3ZhdGl2ZSB0ZWFjaGluZy4gSm9obiBXaWxleSAmIFNvbnMuDQoNCkJvcmljaCwgRy4gRC4gKDIwMTcpLiBFZmZlY3RpdmUgVGVhY2hpbmcgTWV0aG9kczogUmVzZWFyY2gtQmFzZWQgUHJhY3RpY2UgKDl0aCBlZC4pLiBQZWFyc29uLiANCg0KQnJvd24sIEguIEQuLCAmIExlZSwgSC4gKDE5OTQpLiBUZWFjaGluZyBieSBwcmluY2lwbGVzOiBBbiBpbnRlcmFjdGl2ZSBhcHByb2FjaCB0byBsYW5ndWFnZSBwZWRhZ29neSAoVm9sLiAxLCBwLiA5OTQpLiBFbmdsZXdvb2QgQ2xpZmZzLCBOSjogUHJlbnRpY2UgSGFsbCBSZWdlbnRzLg0KDQpCcm93biwgVC4gQS4gKDIwMTUpLiBDb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzIGZvciBhcHBsaWVkIHJlc2VhcmNoLiBHdWlsZm9yZCBwdWJsaWNhdGlvbnMuDQoNCkJydW5lciwgSi4gUy4gKDE5NjEpLiBUaGUgYWN0IG9mIGRpc2NvdmVyeS4gSGFydmFyZCBlZHVjYXRpb25hbCByZXZpZXcuDQpDYXR0ZWxsLCBSLiBCLiAoMTk1MikuIEZhY3RvciBhbmFseXNpczogYW4gaW50cm9kdWN0aW9uIGFuZCBtYW51YWwgZm9yIHRoZSBwc3ljaG9sb2dpc3QgYW5kIHNvY2lhbCBzY2llbnRpc3QuDQoNCkNoYW5nLCBILiwgJiBCZWlsb2NrLCBTLiBMLiAoMjAxNikuIFRoZSBtYXRoIGFueGlldHktbWF0aCBwZXJmb3JtYW5jZSBsaW5rIGFuZCBpdHMgcmVsYXRpb24gdG8gaW5kaXZpZHVhbCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzOiBBIHJldmlldyBvZiBjdXJyZW50IGJlaGF2aW9yYWwgYW5kIHBzeWNob3BoeXNpb2xvZ2ljYWwgcmVzZWFyY2guIEN1cnJlbnQgT3BpbmlvbiBpbiBCZWhhdmlvcmFsIFNjaWVuY2VzLCAxMCwgMzPigJMzOC4NCg0KQ3JvbmJhY2gsIEwuIEouICgxOTUxKS4gQ29lZmZpY2llbnQgYWxwaGEgYW5kIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUgb2YgdGVzdHMuIEJpb21ldHJpa2EsIDE2LCAyOTfigJMzMzUuDQoNCkRha2VyLCBSLiBKLiwgR2F0dGFzLCBTLiBVLiwgU29rb2xvd3NraSwgSC4gTS4sIEdyZWVuLCBBLiBFLiwgJiBMeW9ucywgSS4gTS4gKDIwMjEpLiBGaXJzdC15ZWFyIHN0dWRlbnRz4oCZIG1hdGggYW54aWV0eSBwcmVkaWN0cyBTVEVNIGF2b2lkYW5jZSBhbmQgdW5kZXJwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHVuaXZlcnNpdHksIGluZGVwZW5kZW50bHkgb2YgbWF0aCBhYmlsaXR5LiBOcGogU2NpZW5jZSBvZiBMZWFybmluZywgNigxKSwgMTcuDQoNCkRldmluZSwgQS4sIEZhd2NldHQsIEsuLCBTesWxY3MsIEQuLCAmIERvd2tlciwgQS4gKDIwMTIpLiBHZW5kZXIgZGlmZmVyZW5jZXMgaW4gbWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgdGhlIHJlbGF0aW9uIHRvIG1hdGhlbWF0aWNzIHBlcmZvcm1hbmNlIHdoaWxlIGNvbnRyb2xsaW5nIGZvciB0ZXN0IGFueGlldHkuIEJlaGF2aW9yYWwgYW5kIGJyYWluIGZ1bmN0aW9ucywgOCgxKSwgMzMuDQoNCkRpU3RlZmFubywgQy4sIFpodSwgTS4sICYgTWluZHJpbGEsIEQuICgyMDA5KS4gVW5kZXJzdGFuZGluZyBhbmQgdXNpbmcgZmFjdG9yIHNjb3JlczogQ29uc2lkZXJhdGlvbnMgZm9yIHRoZSBhcHBsaWVkIHJlc2VhcmNoZXIuIFByYWN0aWNhbCBhc3Nlc3NtZW50LCByZXNlYXJjaCwgYW5kIGV2YWx1YXRpb24sIDE0KDEpLg0KDQpEb3drZXIsIEEuLCBTYXJrYXIsIEEuLCAmIExvb2ksIEMuIFkuICgyMDE2KS4gTWF0aGVtYXRpY3MgYW54aWV0eTogV2hhdCBoYXZlIHdlIGxlYXJuZWQgaW4gNjAgeWVhcnM/LiBGcm9udGllcnMgaW4gcHN5Y2hvbG9neSwgNywgNTA4Lg0KDQpEcmVnZXIsIFIuIE0uLCAmIEFpa2VuIEpyLCBMLiBSLiAoMTk1NykuIFRoZSBpZGVudGlmaWNhdGlvbiBvZiBudW1iZXIgYW54aWV0eSBpbiBhIGNvbGxlZ2UgcG9wdWxhdGlvbi4gSm91cm5hbCBvZiBFZHVjYXRpb25hbCBQc3ljaG9sb2d5LCA0OCg2KSwgMzQ0Lg0KDQpEdW5jYW4sIE8uIEQuICgxOTYxKS4gQSBzb2Npb2Vjb25vbWljIGluZGV4IGZvciBhbGwgb2NjdXBhdGlvbnMuIE9jY3VwYXRpb25zIGFuZCBzb2NpYWwgc3RhdHVzLi4NCg0KRHdlY2ssIEMuIFMuICgyMDA2KS4gTWluZHNldDogVGhlIG5ldyBwc3ljaG9sb2d5IG9mIHN1Y2Nlc3MuIFJhbmRvbSBob3VzZS4NCg0KRWxzZS1RdWVzdCwgTi4gTS4sIEh5ZGUsIEouIFMuLCAmIExpbm4sIE0uIEMuICgyMDEwKS4gQ3Jvc3MtbmF0aW9uYWwgcGF0dGVybnMgb2YgZ2VuZGVyIGRpZmZlcmVuY2VzIGluIG1hdGhlbWF0aWNzOiBhIG1ldGEtYW5hbHlzaXMuIFBzeWNob2xvZ2ljYWwgYnVsbGV0aW4sIDEzNigxKSwgMTAzLg0KDQpGaW5uZXksIFMuIEouLCAmIERpU3RlZmFubywgQy4gKDIwMDYpLiBOb24tbm9ybWFsIGFuZCBjYXRlZ29yaWNhbCBkYXRhIGluIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcuIFN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmc6IEEgc2Vjb25kIGNvdXJzZSwgMTAoNiksIDI2OS0zMTQuDQoNCkZsb3JhLCBELiBCLiAoMjAxNykuIFN0YXRpc3RpY2FsIE1ldGhvZHMgZm9yIHRoZSBTb2NpYWwgYW5kIEJlaGF2aW91cmFsIFNjaWVuY2VzOiBBIE1vZGVsLUJhc2VkIEFwcHJvYWNoLiBTQUdFLg0KDQpGb2dhcnR5LCBSLiAoMTk5MSkuIFRoZSBtaW5kZnVsIHNjaG9vbDogSG93IHRvIGludGVncmF0ZSB0aGUgY3VycmljdWxhLiBQYWxhdGluZSwgSUwuIFNreUxpZ2h0IFB1Ymxpc2hpbmcsIEluYy4gUmV0cmlldmVkIEZlYnJ1YXJ5LCAyMiwgMjAwMi4NCg0KR2llcmwsIE0uIEouLCAmIEJpc2FueiwgSi4gKDE5OTUpLiBBbnhpZXRpZXMgYW5kIGF0dGl0dWRlcyByZWxhdGVkIHRvIG1hdGhlbWF0aWNzIGluIGdyYWRlcyAzIGFuZCA2LiBUaGUgSm91cm5hbCBvZiBleHBlcmltZW50YWwgZWR1Y2F0aW9uLCA2MygyKSwgMTM5LTE1OC4NCg0KR29ldHosIFQuLCBCaWVnLCBNLiwgTMO8ZHRrZSwgTy4sIFBla3J1biwgUi4sICYgSGFsbCwgTi4gQy4gKDIwMTMpLiBEbyBnaXJscyByZWFsbHkgZXhwZXJpZW5jZSBtb3JlIGFueGlldHkgaW4gbWF0aGVtYXRpY3M/LiBQc3ljaG9sb2dpY2FsIHNjaWVuY2UsIDI0KDEwKSwgMjA3OS0yMDg3Lg0KDQpHb3VnaCwgTWFyeSBPLiAoMTk1NCkuIFdoeSBmYWlsdXJlcyBpbiBtYXRoZW1hdGljcz8gTWF0aGVtYXBob2JpYTogQ2F1c2VzIGFuZCB0cmVhdG1lbnRzLiBUaGUgQ2xlYXJpbmcgSG91c2U6IEEgSm91cm5hbCBvZiBFZHVjYXRpb25hbCBTdHJhdGVnaWVzLCBJc3N1ZXMgYW5kIElkZWFzLCAyOCg1KSwgMjkw4oCTMjk0LiANCg0KR3V0dG1hbiwgTC4gKDE5NTQpLiBTb21lIG5lY2Vzc2FyeSBjb25kaXRpb25zIGZvciBjb21tb24tZmFjdG9yIGFuYWx5c2lzLiBQc3ljaG9tZXRyaWthLCAxOSgyKSwgMTQ5LTE2MS4NCg0KSGF0dGllLCBKLiAoMjAxMikuIFZpc2libGUgbGVhcm5pbmcgZm9yIHRlYWNoZXJzOiBNYXhpbWl6aW5nIGltcGFjdCBvbiBsZWFybmluZy4gUm91dGxlZGdlLg0KDQpIZW1icmVlLCBSLiAoMTk5MCkuIFRoZSBuYXR1cmUsIGVmZmVjdHMsIGFuZCByZWxpZWYgb2YgbWF0aGVtYXRpY3MgYW54aWV0eS4gSm91cm5hbCBmb3IgcmVzZWFyY2ggaW4gbWF0aGVtYXRpY3MgZWR1Y2F0aW9uLCAyMSgxKSwgMzMtNDYuDQoNCkhvcGtvLCBELiBSLiwgTWFoYWRldmFuLCBSLiwgQmFyZSwgUi4gTC4sICYgSHVudCwgTS4gSy4gKDIwMDMpLiBUaGUgYWJicmV2aWF0ZWQgbWF0aCBhbnhpZXR5IHNjYWxlIChBTUFTKSBjb25zdHJ1Y3Rpb24sIHZhbGlkaXR5LCBhbmQgcmVsaWFiaWxpdHkuIEFzc2Vzc21lbnQsIDEwKDIpLCAxNzjigJMxODIuDQoNCiBIaXJzY2hiZXJnLCBFLiwgJiBTdGFuZGlzaCwgQy4gVi4gKDE5NTkpLiBBIG1ldGhvZCBvZiBkZXJpdmluZyBhIHN0cmF0aWZpY2F0aW9uIHNjb3JlIGJ5IHVzaW5nIHRoZSBwcmluY2lwYWwgY29tcG9uZW50cyBvZiB0aGUgY29ycmVsYXRpb24gbWF0cml4LiBBbWVyaWNhbiBTdGF0aXN0aWNhbCBBc3NvY2lhdGlvbiwgUHJvY2VlZGluZ3Mgb2YgdGhlIFNvY2lhbCBTdGF0aXN0aWNzIFNlY3Rpb24sIDE5NTksIDIyMC0yMjUuDQoNCkphY29icywgSC4gSC4gKDE5ODkpLiBJbnRlcmRpc2NpcGxpbmFyeSBjdXJyaWN1bHVtOiBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uLiBBc3NvY2lhdGlvbiBmb3IgU3VwZXJ2aXNpb24gYW5kIEN1cnJpY3VsdW0gRGV2ZWxvcG1lbnQsIDEyNTAgTi4gUGl0dCBTdHJlZXQsIEFsZXhhbmRyaWEsIFZBIDIyMzE0Lg0KDQpKb2xsaWZmZSwgSS4gVC4sICYgQ2FkaW1hLCBKLiAoMjAxNikuIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXM6IEEgUmV2aWV3IGFuZCBSZWNlbnQgRGV2ZWxvcG1lbnRzLiBQaGlsb3NvcGhpY2FsIFRyYW5zYWN0aW9ucyBvZiB0aGUgUm95YWwgU29jaWV0eSBBLCAzNzQoMjA2NSksIDIwMTUwMjAyLg0KDQpKb2huc29uLCBELiBXLiwgSm9obnNvbiwgUi4gVC4sICYgU21pdGgsIEsuIEEuICgyMDE0KS4gQ29vcGVyYXRpdmUgbGVhcm5pbmc6IEltcHJvdmluZyB1bml2ZXJzaXR5IGluc3RydWN0aW9uIGJ5IGJhc2luZyBwcmFjdGljZSBvbiB2YWxpZGF0ZWQgdGhlb3J5LiBKb3VybmFsIG9uIGV4Y2VsbGVuY2UgaW4gY29sbGVnZSB0ZWFjaGluZywgMjUoMyY0KS4NCg0KSm9zZSBNLiBDYXJkaW5vIEpyLiBhbmQgUnV0aCBBLiBPcnRlZ2EtRGVsYSBDcnV6LCBVbmRlcnN0YW5kaW5nIG9mIGxlYXJuaW5nIHN0eWxlcyBhbmQgdGVhY2hpbmcgc3RyYXRlZ2llcyB0b3dhcmRzIGltcHJvdmluZyB0aGUgdGVhY2hpbmcgYW5kIGxlYXJuaW5nIG9mIG1hdGhlbWF0aWNzLCBMVU1BVCBHZW5lcmFsIElzc3VlLCAgVm9sIDggTm8gMSAoMjAyMCksIDE54oCTNDMuIERvaTogMTAuMzExMjkvIExVTUFULjguMS4xMzQ4DQoNCkpveWNlLCBCLiwgV2VpbCwgTS4sICYgQ2FsaG91biwgRS4gKDIwMTUpLiBNb2RlbHMgb2YgVGVhY2hpbmcgKDl0aCBlZC4pLiBQZWFyc29uLg0KDQpLbGVlLCBILiBMLiwgQnVlaGwsIE0uIE0uLCAmIE1pbGxlciwgQS4gRC4gKDIwMjIpLiBTdHJhdGVnaWVzIGZvciBhbGxldmlhdGluZyBzdHVkZW50c+KAmSBtYXRoIGFueGlldHk6IENvbnRyb2wtdmFsdWUgdGhlb3J5IGluIHByYWN0aWNlLiBUaGVvcnkgSW50byBQcmFjdGljZSwgNjEoMSksIDQ54oCTNjEuDQoNCktsaW5lLCBSLiBCLiAoMjAyMykuIFByaW5jaXBsZXMgYW5kIHByYWN0aWNlIG9mIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcuIEd1aWxmb3JkIHB1YmxpY2F0aW9ucy4NCg0KTGF6YXJzZmVsZCwgUC4gRi4sIFN0b3VmZmVyLCBTLiBBLiwgR3V0dG1hbiwgTC4sICYgU3VjaG1hbiwgRS4gQS4gKDE5NTApLiBNZWFzdXJlbWVudCBhbmQgcHJlZGljdGlvbi4gU0EgU3RvdWZmZXIgKMOpZC4pIFN0dWRpZXMgaW4gc29jaWFsIHBzeWNob2xvZ3kgaW4gd29ybGQgd2FyIElJLCA0Lg0KDQpMaSwgQy4gSC4gKDIwMTYpLiBUaGUgcGVyZm9ybWFuY2Ugb2YgTUwsIERXTFMsIGFuZCBVTFMgZXN0aW1hdGlvbiB3aXRoIHJvYnVzdCBjb3JyZWN0aW9ucyBpbiBzdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVscyB3aXRoIG9yZGluYWwgdmFyaWFibGVzLiBQc3ljaG9sb2dpY2FsIG1ldGhvZHMsIDIxKDMpLCAzNjkuDQoNCkzDs3Blei1Cb25pbGxhLCBKLiBNLmwgYW5kIEzDs3Blei1Cb25pbGxhLCBMLiBNLiAoMjAxMiksIFZhbGlkYXRpb24gb2YgYW4gaW5mb3JtYXRpb24gdGVjaG5vbG9neSBhbnhpZXR5IHNjYWxlIGluIHVuZGVyZ3JhZHVhdGVzLCBCcml0aXNoIEpvdXJuYWwgb2YgRWR1Y2F0aW9uYWwgVGVjaG5vbG9neSBWb2wgNDMuIE5vIDIuICBFNTbigJNFNTguICBkb2k6MTAuMTExMS9qLjE0NjctODUzNS4yMDExLjAxMjU2LngNCg0KTWFsb25leSwgRS4gQS4sICYgQmVpbG9jaywgUy4gTC4gKDIwMTIpLiBNYXRoIGFueGlldHk6IFdobyBoYXMgaXQsIHdoeSBpdCBkZXZlbG9wcywgYW5kIGhvdyB0byBndWFyZCBhZ2FpbnN0IGl0LiBUcmVuZHMgaW4gY29nbml0aXZlIHNjaWVuY2VzLCAxNig4KSwgNDA0LTQwNi4NCg0KTWFyc2gsIEguIFcuICgxOTk2KS4gUG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHNlbGYtZXN0ZWVtOiBBIHN1YnN0YW50aXZlbHkgbWVhbmluZ2Z1bCBkaXN0aW5jdGlvbiBvciBhcnRpZmFjdG9ycz8gSm91cm5hbCBvZiBQZXJzb25hbGl0eSBhbmQgU29jaWFsIFBzeWNob2xvZ3ksIDcwKDQpLCA4MTDigJM4MTkuDQoNCk1jRG9uYWxkLCBSLiBQLiAoMTk5OSkuIFRlc3QgdGhlb3J5OiBBIHVuaWZpZWQgdHJlYXRtZW50LiBNYWh3YWg6IEVybGJhdW0uDQoNCk1vbGluZXIsIEwuLCAmIEFsZWdyZSwgRi4gKDIwMjApLiBQZWVyIHR1dG9yaW5nIGVmZmVjdHMgb24gc3R1ZGVudHPigJkgbWF0aGVtYXRpY3MgYW54aWV0eTogQSBtaWRkbGUgc2Nob29sIGV4cGVyaWVuY2UuIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCAxMSwgMTYxMC4NCg0KTXV0aMOpbiwgQi4gKDE5ODQpLiBBIGdlbmVyYWwgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCB3aXRoIGRpY2hvdG9tb3VzLCBvcmRlcmVkIGNhdGVnb3JpY2FsLCBhbmQgY29udGludW91cyBsYXRlbnQgdmFyaWFibGUgaW5kaWNhdG9ycy4gUHN5Y2hvbWV0cmlrYSwgNDkoMSksIDExNS0xMzIuDQoNCk/igJlMZWFyeSwgSy4sIEZpdHpwYXRyaWNrLCBDLiBMLiwgJiBIYWxsZXR0LCBELiAoMjAxNykuIE1hdGggYW54aWV0eSBpcyByZWxhdGVkIHRvIHNvbWUsIGJ1dCBub3QgYWxsLCBleHBlcmllbmNlcyB3aXRoIG1hdGguIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCA4LCAyMDY3Lg0KDQpPcm1yb2QsIEouIEUuICgyMDIwKS4gSHVtYW4gTGVhcm5pbmcgKDh0aCBlZC4pLiBQZWFyc29uDQoNCk9sc3NvbiwgVS4gKDE5NzkpLiBNYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBvZiB0aGUgcG9seWNob3JpYyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudC4gIFBzeWNob21ldHJpa2EsIDQ0KDQpLCA0NDMtNDYwLg0KDQpQbGV0emVyLCBCLiwgV29vZCwgRy4sIFNjaGVybmRsLCBULiwgS2Vyc2NoYmF1bSwgSC4gSC4sICYgTnVlcmssIEguQy4gKDIwMTYpLiBDb21wb25lbnRzIG9mIG1hdGhlbWF0aWNzIGFueGlldHk6IEZhY3RvciBtb2RlbGluZyBvZiB0aGUgTUFSUzMwLWJyaWVmLiBGcm9udGllcnMgaW4gUHN5Y2hvbG9neSwgNywgOTEuDQoNClByaW5jZSwgTS4gSi4sICYgRmVsZGVyLCBSLiBNLiAoMjAwNikuIEluZHVjdGl2ZSB0ZWFjaGluZyBhbmQgbGVhcm5pbmcgbWV0aG9kczogRGVmaW5pdGlvbnMsIGNvbXBhcmlzb25zLCBhbmQgcmVzZWFyY2ggYmFzZXMuIEpvdXJuYWwgb2YgZW5naW5lZXJpbmcgZWR1Y2F0aW9uLCA5NSgyKSwgMTIzLTEzOC4NCg0KUmFtaXJleiwgRy4sIFNoYXcsIFMuIFQuLCAmIE1hbG9uZXksIEUuIEEuICgyMDE4KS4gTWF0aCBhbnhpZXR5OiBQYXN0IHJlc2VhcmNoLCBwcm9taXNpbmcgaW50ZXJ2ZW50aW9ucywgYW5kIGEgbmV3IGludGVycHJldGF0aW9uIGZyYW1ld29yay4gRWR1Y2F0aW9uYWwgcHN5Y2hvbG9naXN0LCA1MygzKSwgMTQ1LTE2NC4NCg0KUmljaGFyZHNvbiwgRi4gQy4sICYgU3Vpbm4sIFIuIE0uICgxOTcyKS4gVGhlIG1hdGhlbWF0aWNzIGFueGlldHkgcmF0aW5nIHNjYWxlOiBQc3ljaG9tZXRyaWMgZGF0YS4gSm91cm5hbCBvZiBDb3Vuc2VsaW5nIFBzeWNob2xvZ3ksIDE5KDYpLCA1NTEuDQoNClJvemdvbmp1aywgRC4sIEtyYWF2LCBULiwgTWlra29yLCBLLiwgT3Jhdi1QdXVyYW5kLCBLLiwgJiBUw6RodCwgSy4gKDIwMjApLiBNYXRoZW1hdGljcyBhbnhpZXR5IGFtb25nIFNURU0gYW5kIHNvY2lhbCBzY2llbmNlIHN0dWRlbnRzOiBUaGUgcm9sZXMgb2YgbWF0aGVtYXRpY3Mgc2VsZi1lZmZpY2FjeSwgYW5kIGRlZXAgYW5kIHN1cmZhY2UgYXBwcm9hY2ggdG8gbGVhcm5pbmcuIEludGVybmF0aW9uYWwgSm91cm5hbCBvZiBTVEVNIEVkdWNhdGlvbiwgNygxKSwgMeKAkzExLg0KDQpTZWdvb2wsIE4uIEsuLCBDYXJsc29uLCBKLiBTLiwgR29mb3J0aCwgQS4gTi4sIFZvbiBEZXIgRW1ic2UsIE4uLCAmIEJhcnRlcmlhbiwgSi4gQS4gKDIwMTMpLiBIZWlnaHRlbmVkIHRlc3QgYW54aWV0eSBhbW9uZyB5b3VuZyBjaGlsZHJlbjogRWxlbWVudGFyeSBzY2hvb2wgc3R1ZGVudHPigJkgYW54aW91cyByZXNwb25zZXMgdG8gaGlnaC1zdGFrZXMgdGVzdGluZy4gUHN5Y2hvbG9neSBpbiB0aGUgU2Nob29scywgNTAoNSksIDQ4OeKAkzQ5OS4NCg0KU3Bvb3JlbiwgUC4sIEJyb2NreCwgQi4sICYgTW9ydGVsbWFucywgRC4gKDIwMTMpLiBPbiB0aGUgdmFsaWRpdHkgb2Ygc3R1ZGVudCBldmFsdWF0aW9uIG9mIHRlYWNoaW5nOiBUaGUgc3RhdGUgb2YgdGhlIGFydC4gUmV2aWV3IG9mIEVkdWNhdGlvbmFsIFJlc2VhcmNoLCA4Myg0KSwgNTk4LTY0Mi4NCg0KVXNoZXIsIEUuIEwuLCBMaSwgQy4gUi4sIEJ1dHosIEEuIFIuLCAmIFJvamFzLCBKLiBQLiAoMjAxOSkuIFBlcnNldmVyYW50IGdyaXQgYW5kIHNlbGYtZWZmaWNhY3k6IEFyZSBib3RoIGVzc2VudGlhbCBmb3IgY2hpbGRyZW7igJlzIGFjYWRlbWljIHN1Y2Nlc3M/LiBKb3VybmFsIG9mIEVkdWNhdGlvbmFsIFBzeWNob2xvZ3ksIDExMSg1KSwgODc3Lg0KDQogV2F0c29uLCBELiwgQ2xhcmssIEwuIEEuLCAmIFRlbGxlZ2VuLCBBLiAoMTk4OCkuIERldmVsb3BtZW50IGFuZCB2YWxpZGF0aW9uIG9mIGJyaWVmIG1lYXN1cmVzIG9mIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBhZmZlY3Q6IFRoZSBQQU5BUyBzY2FsZXMuIEpvdXJuYWwgb2YgUGVyc29uYWxpdHkgYW5kIFNvY2lhbCBQc3ljaG9sb2d5LCA1NCg2KSwgMTA2M+KAkzEwNzAuDQoNCldpbHNvbiwgUy4gKDIwMTMpLiBNYXR1cmUgYWdlIHByZS1zZXJ2aWNlIHRlYWNoZXJz4oCZIG1hdGhlbWF0aWNzIGFueGlldHkgYW5kIGZhY3RvcnMgaW1wYWN0aW5nIG9uIHVuaXZlcnNpdHkgcmV0ZW50aW9uLiBNYXRoZW1hdGljcyBFZHVjYXRpb246IFllc3RlcmRheSwgVG9kYXkgYW5kIFRvbW9ycm93IChNRVJHQTM2KSwgNjY24oCTNjczLg0KDQpaYWthcmlhLCBFLiwgWmFpbiwgTi4gTS4sIEFobWFkLCBOLiBBLiwgJiBFcmxpbmEsIEEuICgyMDEyKS4gTWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgYWNoaWV2ZW1lbnQgYW1vbmcgc2Vjb25kYXJ5IHNjaG9vbCBzdHVkZW50cy4gQW1lcmljYW4gSm91cm5hbCBvZiBBcHBsaWVkIFNjaWVuY2VzLCA5KDExKSwgMTgyOC4NCg0KDQpcDQoNCiMgQXBwZW5kaWNlcw0KDQojIyBNYXRoZW1hdGljcyBvZiBQQ0ENCg0KKioxLiBQcm9ibGVtIERlZmluaXRpb24qKg0KDQpXZSB3aWxsIHVzZSBhIHF1ZXN0aW9ubmFpcmUgd2l0aCBmb3VyIGl0ZW1zIHRoYXQgYXNzZXNzIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5IHRvIGRlbW9uc3RyYXRlIHRoZSBwcm9jZWR1cmUuDQoNCiAgLSAgICR4XzEkOiBUaGlua2luZyBhYm91dCBhIG1hdGggdGVzdCB0aGUgZGF5IGJlZm9yZSB5b3UgdGFrZSBpdC4NCiAgLSAgICR4XzIkOiBUYWtpbmcgYSBtYXRoIHRlc3QuDQogIC0gICAkeF8zJDogQmVpbmcgZ2l2ZW4gYSBob21ld29yayBhc3NpZ25tZW50IG9mIG1hbnkgZGlmZmljdWx0IHByb2JsZW1zIHRoYXQgaXMgZHVlIGZvciB0aGUgbmV4dCBjbGFzcyBtZWV0aW5nLg0KICAtICAgJHhfNCQ6IEJlaW5nIGdpdmVuIGEgcXVpeiBvbiBtYXRoIHdpdGhvdXQga25vd2luZyBpbiBhZHZhbmNlLg0KDQpMZXQgJFxtYXRoYmZ7eH0gPSBbeF8xLCB4XzIsIHhfMywgeF80XV5UJCBiZSBhIHJhbmRvbSB2ZWN0b3IgcmVwcmVzZW50aW5nIHRoZSByZXNwb25zZXMgb2YgYSByYW5kb21seSBzZWxlY3RlZCBpbmRpdmlkdWFsIHRvIHRoZSBmb3VyIGl0ZW1zLiBXZSBhc3N1bWUgJFxtYXRoYmZ7eH0kIGhhcyBhIHBvcHVsYXRpb24gbWVhbiB2ZWN0b3IgJFxib2xkc3ltYm9se1xtdX0kIGFuZCBwb3B1bGF0aW9uIGNvdmFyaWFuY2UgbWF0cml4ICRcYm9sZHN5bWJvbHtcU2lnbWF9JC4NCg0KV2UgY29sbGVjdCBhIHNhbXBsZSBvZiAkbiQgaW5kaXZpZHVhbHMuIFRoZSBkYXRhIG1hdHJpeCBpcyAkXG1hdGhiZntYfV97biBcdGltZXMgNH0kLCB3aGVyZSBlYWNoIHJvdyBpcyBhbiBpbmRpdmlkdWFsJ3MgcmVzcG9uc2UgdmVjdG9yLiBUaGUgc2FtcGxlIG1lYW4gdmVjdG9yIGlzICRcYmFye1xtYXRoYmZ7eH19JCwgYW5kIHRoZSBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXggaXMgJFxtYXRoYmZ7U30kLg0KDQoqKjIuIFByZXByb2Nlc3Npbmc6IENlbnRlcmluZyB0aGUgRGF0YSoqDQoNClRoZSBmaXJzdCBzdGVwIGlzIHRvIGNlbnRlciB0aGUgZGF0YS4gV2Ugc3VidHJhY3QgdGhlIG1lYW4gb2YgZWFjaCB2YXJpYWJsZSwgY3JlYXRpbmcgYSBuZXcgZGF0YSBtYXRyaXggJFxtYXRoYmZ7WX0kOg0KDQokJA0KXG1hdGhiZntZfSA9IFxtYXRoYmZ7WH0gLSBcbWF0aGJmezF9XGJhcntcbWF0aGJme3h9fV5UDQokJA0KDQp3aGVyZSAkXG1hdGhiZnsxfSQgaXMgYW4gJG4gXHRpbWVzIDEkIHZlY3RvciBvZiBvbmVzLiBUaGUgZWxlbWVudHMgb2YgJFxtYXRoYmZ7WX0kIGFyZSAkeV97aWp9ID0geF97aWp9IC0gXGJhcnt4fV9qJC4gRnJvbSB0aGlzIHBvaW50IGZvcndhcmQsIHdlIHdvcmsgd2l0aCB0aGUgY2VudGVyZWQgZGF0YSAkXG1hdGhiZntZfSQsIGVuc3VyaW5nICRFW1xtYXRoYmZ7eX1dID0gXG1hdGhiZnswfSQuDQoNCioqMy4gR29hbCBvZiBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzIChQQ0EpKioNCg0KVGhlIGdvYWwgb2YgUENBIGlzIHRvIGZpbmQgYSBuZXcgc2V0IG9mIHVuY29ycmVsYXRlZCB2YXJpYWJsZXMgJFxtYXRoYmZ7en0gPSBbel8xLCB6XzIsIHpfMywgel80XV5UJCwgY2FsbGVkIHRoZSBcdGV4dGJme1ByaW5jaXBhbCBDb21wb25lbnRzfSAoUENzKSwgd2hpY2ggYXJlIGxpbmVhciBjb21iaW5hdGlvbnMgb2YgdGhlIG9yaWdpbmFsIGNlbnRlcmVkIHZhcmlhYmxlcyAkXG1hdGhiZnt5fSQuDQoNCiQkDQpcbWF0aGJme3p9ID0gXG1hdGhiZntXfV5UXG1hdGhiZnt5fQ0KJCQNCg0KVGhlIG1hdHJpeCAkXG1hdGhiZntXfSQgaXMgYW4gb3J0aG9nb25hbCBtYXRyaXggKCRcbWF0aGJme1d9XlRcbWF0aGJme1d9ID0gXG1hdGhiZntJfSQpIHdob3NlIGNvbHVtbnMgJFxtYXRoYmZ7d31faSQgYXJlIHRoZSBcdGV4dGJme2xvYWRpbmcgdmVjdG9yc30uIFRoZSBjb21wb25lbnRzIG11c3Qgc2F0aXNmeToNCg0KLSAgIFRoZSBmaXJzdCBjb21wb25lbnQsICR6XzEgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9JCwgaGFzIHRoZSBtYXhpbXVtIHBvc3NpYmxlIHZhcmlhbmNlLg0KLSAgIFRoZSAkayQtdGggY29tcG9uZW50LCAkel9rID0gXG1hdGhiZnt3fV9rXlQgXG1hdGhiZnt5fSQsIGhhcyB0aGUgbWF4aW11bSBwb3NzaWJsZSB2YXJpYW5jZSBzdWJqZWN0IHRvIGJlaW5nIHVuY29ycmVsYXRlZCB3aXRoIChvcnRob2dvbmFsIHRvKSBhbGwgcHJldmlvdXMgY29tcG9uZW50cyAkel8xLCBcZG90cywgel97ay0xfSQuDQoNCioqNC4gRGVyaXZhdGlvbiBvZiB0aGUgRmlyc3QgUHJpbmNpcGFsIENvbXBvbmVudCoqDQoNCkxldCAkXG1hdGhiZnt3fV8xJCBiZSB0aGUgdmVjdG9yIG9mIHdlaWdodHMgZm9yIHRoZSBmaXJzdCBQQywgJHpfMSA9IFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7eX0kLiBUaGUgc2FtcGxlIHZhcmlhbmNlIG9mICR6XzEkIGlzIGdpdmVuIGJ5Og0KDQokJA0KXGJlZ2lue2FsaWduKn0NClx0ZXh0e1Zhcn0oel8xKSAmPSBcdGV4dHtWYXJ9KFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7eX0pIFxcDQogICAgICAgICAgICAgICAgJj0gRVsoXG1hdGhiZnt3fV8xXlQgXG1hdGhiZnt5fSkoXG1hdGhiZnt3fV8xXlQgXG1hdGhiZnt5fSleVF0gXHF1YWQgXHRleHR7KHNpbmNlfSBFW1xtYXRoYmZ7eX1dPVxtYXRoYmZ7MH0pIFxcDQogICAgICAgICAgICAgICAgJj0gRVtcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9IFxtYXRoYmZ7eX1eVCBcbWF0aGJme3d9XzFdIFxcDQogICAgICAgICAgICAgICAgJj0gXG1hdGhiZnt3fV8xXlQgRVtcbWF0aGJme3l9IFxtYXRoYmZ7eX1eVF0gXG1hdGhiZnt3fV8xIFxcDQogICAgICAgICAgICAgICAgJj0gXG1hdGhiZnt3fV8xXlQgXGJvbGRzeW1ib2x7XFNpZ21hfSBcbWF0aGJme3d9XzENClxlbmR7YWxpZ24qfQ0KJCQNCg0KSW4gcHJhY3RpY2UsIHdlIHVzZSB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9ID0gXGZyYWN7MX17bi0xfSBcbWF0aGJme1l9XlQgXG1hdGhiZntZfSQuDQoNCldlIHdpc2ggdG8gbWF4aW1pemUgJFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7U30gXG1hdGhiZnt3fV8xJCBzdWJqZWN0IHRvIHRoZSBub3JtYWxpemF0aW9uIGNvbnN0cmFpbnQgJFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7d31fMSA9IDEkICh0byBwcmV2ZW50IHRoZSB2YXJpYW5jZSBmcm9tIGdyb3dpbmcgYXJiaXRyYXJpbHkgbGFyZ2UpLiBXZSBzb2x2ZSB0aGlzIHVzaW5nIHRoZSBtZXRob2Qgb2YgTGFncmFuZ2UgbXVsdGlwbGllcnMuDQoNClRoZSBMYWdyYW5naWFuIGlzOg0KDQokJA0KXG1hdGhjYWx7TH0oXG1hdGhiZnt3fV8xLCBcbGFtYmRhXzEpID0gXG1hdGhiZnt3fV8xXlQgXG1hdGhiZntTfSBcbWF0aGJme3d9XzEgLSBcbGFtYmRhXzEgKFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7d31fMSAtIDEpDQokJA0KDQpUYWtpbmcgdGhlIGdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAkXG1hdGhiZnt3fV8xJCBhbmQgc2V0dGluZyBpdCB0byB6ZXJvOg0KDQokJA0KXGZyYWN7XHBhcnRpYWwgXG1hdGhjYWx7TH19e1xwYXJ0aWFsIFxtYXRoYmZ7d31fMX0gPSAyXG1hdGhiZntTfVxtYXRoYmZ7d31fMSAtIDJcbGFtYmRhXzEgXG1hdGhiZnt3fV8xID0gMA0KJCQNCg0KVGhpcyB5aWVsZHMgdGhlIGtleSBcdGV4dGJme2VpZ2VudmFsdWUgZXF1YXRpb259Og0KDQokJA0KXGJlZ2lue2VxdWF0aW9ufQ0KXG1hdGhiZntTfSBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzEgXG1hdGhiZnt3fV8xDQpcZW5ke2VxdWF0aW9ufQ0KJCQNCg0KU3Vic3RpdHV0aW5nIHRoZSBhYm92ZSBlcXVhdGlvbiBiYWNrIGludG8gdGhlIHZhcmlhbmNlIGV4cHJlc3Npb246DQoNCiQkDQpcdGV4dHtWYXJ9KHpfMSkgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMSA9IFxtYXRoYmZ7d31fMV5UIChcbGFtYmRhXzEgXG1hdGhiZnt3fV8xKSA9IFxsYW1iZGFfMSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzENCiQkDQoNClRodXMsIHRoZSB2YXJpYW5jZSBvZiB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudCAkel8xJCBpcyB0aGUgZWlnZW52YWx1ZSAkXGxhbWJkYV8xJC4gVG8gbWF4aW1pemUgdGhlIHZhcmlhbmNlLCB3ZSBtdXN0IGNob29zZSB0aGUgXHRleHRiZntlaWdlbnZlY3RvciAkXG1hdGhiZnt3fV8xJCBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXJnZXN0IGVpZ2VudmFsdWUgb2YgJFxtYXRoYmZ7U30kfS4NCg0KKio1LiBEZXJpdmF0aW9uIG9mIHRoZSBTZWNvbmQgUHJpbmNpcGFsIENvbXBvbmVudCoqDQoNCldlIG5vdyBzZWVrIHRoZSBzZWNvbmQgY29tcG9uZW50ICR6XzIgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme3l9JCB0aGF0IGhhcyBtYXhpbXVtIHZhcmlhbmNlLCBzdWJqZWN0IHRvICRcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzIgPSAxJCBhbmQgJFxtYXRoYmZ7d31fMl5UIFxtYXRoYmZ7d31fMSA9IDAkIChlbnN1cmluZyAkel8yJCBpcyB1bmNvcnJlbGF0ZWQgd2l0aCAkel8xJCkuDQoNClRoZSBMYWdyYW5naWFuIGZvciB0aGlzIHByb2JsZW0gaXM6DQoNCiQkDQpcbWF0aGNhbHtMfShcbWF0aGJme3d9XzIsIFxsYW1iZGFfMiwgXHBoaSkgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMiAtIFxsYW1iZGFfMiAoXG1hdGhiZnt3fV8yXlQgXG1hdGhiZnt3fV8yIC0gMSkgLSBccGhpIChcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzEpDQokJA0KDQpUYWtpbmcgdGhlIGdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAkXG1hdGhiZnt3fV8yJCBhbmQgc2V0dGluZyBpdCB0byB6ZXJvOg0KDQokJA0KXGZyYWN7XHBhcnRpYWwgXG1hdGhjYWx7TH19e1xwYXJ0aWFsIFxtYXRoYmZ7d31fMn0gPSAyXG1hdGhiZntTfVxtYXRoYmZ7d31fMiAtIDJcbGFtYmRhXzIgXG1hdGhiZnt3fV8yIC0gXHBoaSBcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpNdWx0aXBseSB0aGlzIGVxdWF0aW9uIG9uIHRoZSBsZWZ0IGJ5ICRcbWF0aGJme3d9XzFeVCQ6DQoNCiQkDQoyXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9XG1hdGhiZnt3fV8yIC0gMlxsYW1iZGFfMiBcbWF0aGJme3d9XzFeVFxtYXRoYmZ7d31fMiAtIFxwaGkgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpGcm9tIHRoZSBlaWdlbnZhbHVlIGVxdWF0aW9uIGZvciAkXG1hdGhiZnt3fV8xJCwgd2Uga25vdyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9ID0gXGxhbWJkYV8xIFxtYXRoYmZ7d31fMV5UJC4gVGhlIG9ydGhvZ29uYWxpdHkgY29uc3RyYWludCBnaXZlcyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzI9MCQuIFN1YnN0aXR1dGluZyB0aGVzZToNCg0KJCQNCjJcbGFtYmRhXzEgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzIgLSAwIC0gXHBoaSAoMSkgPSAwIFxpbXBsaWVzIDJcbGFtYmRhXzEgKDApIC0gXHBoaSA9IDAgXGltcGxpZXMgXHBoaSA9IDANCiQkDQoNCldpdGggJFxwaGk9MCQsIHRoZSBncmFkaWVudCBlcXVhdGlvbiBzaW1wbGlmaWVzIHRvOg0KDQokJA0KMlxtYXRoYmZ7U31cbWF0aGJme3d9XzIgLSAyXGxhbWJkYV8yIFxtYXRoYmZ7d31fMiA9IDAgXGltcGxpZXMgXG1hdGhiZntTfSBcbWF0aGJme3d9XzIgPSBcbGFtYmRhXzIgXG1hdGhiZnt3fV8yDQokJA0KDQpUaGlzIGlzIGFnYWluIGFuIGVpZ2VudmFsdWUgZXF1YXRpb24uIFRoZSB2YXJpYW5jZSBvZiAkel8yJCBpcyAkXGxhbWJkYV8yJC4gVG8gbWF4aW1pemUgdGhlIHZhcmlhbmNlLCB3ZSBjaG9vc2UgdGhlIGVpZ2VudmVjdG9yICRcbWF0aGJme3d9XzIkIGNvcnJlc3BvbmRpbmcgdG8gdGhlIFx0ZXh0YmZ7c2Vjb25kIGxhcmdlc3QgZWlnZW52YWx1ZX0gJFxsYW1iZGFfMiQuIFRoZSBvcnRob2dvbmFsaXR5ICRcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzEgPSAwJCBpcyBhdXRvbWF0aWNhbGx5IHNhdGlzZmllZCBmb3IgZGlzdGluY3QgZWlnZW52YWx1ZXMgc2luY2UgJFxtYXRoYmZ7U30kIGlzIHN5bW1ldHJpYy4NCg0KKio2LiBTdWJzZXF1ZW50IENvbXBvbmVudHMgYW5kIEZ1bGwgU29sdXRpb24qKg0KDQpUaGlzIHByb2Nlc3MgY29udGludWVzIGZvciBhbGwgZm91ciBjb21wb25lbnRzLiBUaGUgc29sdXRpb24gdG8gdGhlIFBDQSBwcm9ibGVtIGlzIGZvdW5kIGJ5IHBlcmZvcm1pbmcgdGhlICoqZWlnZW5kZWNvbXBvc2l0aW9uKiogb2YgdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfSQ6DQoNCiQkDQpcbWF0aGJme1N9ID0gXG1hdGhiZntXfSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aGJme1d9XlQNCiQkDQoNCndoZXJlOg0KDQotICAgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyBhIGRpYWdvbmFsIG1hdHJpeCBjb250YWluaW5nIHRoZSBlaWdlbnZhbHVlcyBpbiBkZXNjZW5kaW5nIG9yZGVyOiAkXGxhbWJkYV8xIFxnZSBcbGFtYmRhXzIgXGdlIFxsYW1iZGFfMyBcZ2UgXGxhbWJkYV80IFxnZSAwJC4NCi0gICAkXG1hdGhiZntXfSA9IFtcbWF0aGJme3d9XzEsIFxtYXRoYmZ7d31fMiwgXG1hdGhiZnt3fV8zLCBcbWF0aGJme3d9XzRdJCBpcyBhbiBvcnRob2dvbmFsIG1hdHJpeCB3aG9zZSBjb2x1bW5zIGFyZSB0aGUgY29ycmVzcG9uZGluZyBlaWdlbnZlY3RvcnMuDQoNClRoZSBwcmluY2lwYWwgY29tcG9uZW50cyBmb3IgYW4gaW5kaXZpZHVhbCB3aXRoIGNlbnRlcmVkIHJlc3BvbnNlIHZlY3RvciAkXG1hdGhiZnt5fSQgYXJlIHRoZW4gY29tcHV0ZWQgYXM6DQoNCiQkDQpcbWF0aGJme3p9ID0gXG1hdGhiZntXfV5UIFxtYXRoYmZ7eX0NCiQkDQoNClRoZSAkayQtdGggUEMgc2NvcmUgaXMgJHpfayA9IFxtYXRoYmZ7d31fa15UIFxtYXRoYmZ7eX0kLg0KDQoqKjcuIFZhcmlhbmNlIEV4cGxhaW5lZCoqDQoNClRoZSB0b3RhbCB2YXJpYW5jZSBpbiB0aGUgb3JpZ2luYWwgZGF0YSBpcyB0aGUgc3VtIG9mIHRoZSB2YXJpYW5jZXMgb2YgdGhlIGNlbnRlcmVkIHZhcmlhYmxlcywgd2hpY2ggaXMgdGhlIHRyYWNlIG9mICRcbWF0aGJme1N9JC4NCg0KJCQNClx0ZXh0e1RvdGFsIFZhcmlhbmNlfSA9IFx0ZXh0e3RyfShcbWF0aGJme1N9KSA9IHNfezExfV4yICsgc197MjJ9XjIgKyBzX3szM31eMiArIHNfezQ0fV4yDQokJA0KDQpGb3IgYSBzeW1tZXRyaWMgbWF0cml4LCB0aGlzIGlzIGFsc28gZXF1YWwgdG8gdGhlIHN1bSBvZiBpdHMgZWlnZW52YWx1ZXM6DQoNCiQkDQpcdGV4dHtUb3RhbCBWYXJpYW5jZX0gPSBcbGFtYmRhXzEgKyBcbGFtYmRhXzIgKyBcbGFtYmRhXzMgKyBcbGFtYmRhXzQNCiQkIFRoZSBwcm9wb3J0aW9uIG9mIHRvdGFsIHZhcmlhbmNlIGV4cGxhaW5lZCBieSB0aGUgJGskLXRoIHByaW5jaXBhbCBjb21wb25lbnQgaXM6DQoNCiQkDQpcdGV4dHtQcm9wb3J0aW9ufV9rID0gXGZyYWN7XGxhbWJkYV9rfXtcc3VtX3tpPTF9Xns0fSBcbGFtYmRhX2l9DQokJA0KDQpUaGUgY3VtdWxhdGl2ZSB2YXJpYW5jZSBleHBsYWluZWQgYnkgdGhlIGZpcnN0ICRtJCBjb21wb25lbnRzIGlzOg0KDQokJA0KXHRleHR7Q3VtdWxhdGl2ZX1fbSA9IFxmcmFje1xzdW1fe2k9MX1ee219IFxsYW1iZGFfaX17XHN1bV97aT0xfV57NH0gXGxhbWJkYV9pfQ0KJCQNCg0KKio4LiBJbnRlcnByZXRhdGlvbiBpbiBvdXIgQ29udGV4dCoqDQoNCkluIHRoZSBjb250ZXh0IG9mIG91ciBtYXRoIGV2YWx1YXRpb24gYW54aWV0eSBxdWVzdGlvbm5haXJlOg0KDQotICAgVGhlIGxvYWRpbmcgdmVjdG9yICRcbWF0aGJme3d9XzEgPSBbd197MTF9LCB3X3sxMn0sIHdfezEzfSwgd197MTR9XV5UJCByZXZlYWxzIGhvdyB0aGUgb3JpZ2luYWwgaXRlbXMgY29tYmluZSB0byBmb3JtIHRoZSBwcmltYXJ5IGxhdGVudCBkaW1lbnNpb24gb2YgYW54aWV0eS4gRm9yIGV4YW1wbGUsIGlmIGFsbCBsb2FkaW5ncyBhcmUgcG9zaXRpdmUgYW5kIHNpbWlsYXIsICR6XzEkIG1pZ2h0IHJlcHJlc2VudCAqKmdlbmVyYWwgTWF0aCBFdmFsdWF0aW9uIEFueGlldHkqKi4NCg0KLSAgIFRoZSBzZWNvbmQgY29tcG9uZW50ICRcbWF0aGJme3d9XzIkIG1pZ2h0IGNvbnRyYXN0IGRpZmZlcmVudCB0eXBlcyBvZiBhbnhpZXR5LiBGb3IgaW5zdGFuY2UsIGlmICR3X3syMX0kIGFuZCAkd197MjJ9JCAodGVzdC1yZWxhdGVkKSBhcmUgcG9zaXRpdmUgd2hpbGUgJHdfezIzfSQgYW5kICR3X3syNH0kIChwb3AgcXVpei9ob21ld29yaykgYXJlIG5lZ2F0aXZlLCAkel8yJCBtaWdodCByZXByZXNlbnQgKipUZXN0IEFueGlldHkgdnMuIFNwb250YW5lb3VzIEV2YWx1YXRpb24gQW54aWV0eSoqLg0KDQotICAgQnkgZXhhbWluaW5nIHRoZSBsb2FkaW5ncywgd2UgY2FuIGludGVycHJldCB0aGUgdW5kZXJseWluZyBwc3ljaG9sb2dpY2FsIGNvbnN0cnVjdHMgdGhhdCBkcml2ZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gdGhlIGZvdXIgcXVlc3Rpb25uYWlyZSBpdGVtcy4NCg0KXA0KDQojIyBDb25maXJtYXRpdmUgRmFjdG9yIEFuYWx5c2lzIChDRkEpDQoNClRoaXMgYXBwZW5kaXggcHJvdmlkZXMgYSBkZXRhaWxlZCBtYXRoZW1hdGljYWwgZGVyaXZhdGlvbiBvZiBhIENvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkgbW9kZWwuIFRoZSBvYnNlcnZlZCB2YXJpYWJsZXMgYXJlIG5pbmUgaXRlbXMgcmVsYXRlZCB0byBtYXRoZW1hdGljYWwgYW54aWV0eSwgd2hpY2ggYXJlIGh5cG90aGVzaXplZCB0byBsb2FkIG9udG8gdHdvIGxhdGVudCBmYWN0b3JzOiAqKlRlc3QgQW54aWV0eSAoVEEpKiogYW5kICoqTGVhcm5pbmcgQW54aWV0eSAoTEEpKiouDQoNCioqMS4gTGF0ZW50IEZhY3RvcnMgYW5kIE9ic2VydmVkIFZhcmlhYmxlcyoqDQoNCldlIGRlZmluZSB0d28gbGF0ZW50IGZhY3RvcnM6DQoNCi0gICAkXGV0YV8xJDogVGVzdCBBbnhpZXR5IChUQSkNCi0gICAkXGV0YV8yJDogTGVhcm5pbmcgQW54aWV0eSAoTEEpDQoNCldlIGhhdmUgbmluZSBvYnNlcnZlZCB2YXJpYWJsZXMgKGl0ZW1zL3F1ZXN0aW9ucyksICR5XzEkIHRvICR5XzkkOg0KDQotICAgJHlfMSQ6IEhhdmluZyB0byB1c2UgdGFibGVzIGluIHRoZSBiYWNrIG9mIGEgbWF0aCBib29rLg0KLSAgICR5XzIkOiBUaGlua2luZyBhYm91dCBhIG1hdGggdGVzdCB0aGUgZGF5IGJlZm9yZSB5b3UgdGFrZSBpdC4NCi0gICAkeV8zJDogV2F0Y2hpbmcgdGhlIHRlYWNoZXIgd29yayBvdXQgYSBtYXRoIHByb2JsZW0gb24gdGhlIGJvYXJkLg0KLSAgICR5XzQkOiBUYWtpbmcgYSBtYXRoIHRlc3QuDQotICAgJHlfNSQ6IEJlaW5nIGdpdmVuIGEgaG9tZXdvcmsgYXNzaWdubWVudCBvZiBtYW55IGRpZmZpY3VsdCBwcm9ibGVtcyB0aGF0IGlzIGR1ZSBmb3IgdGhlIG5leHQgY2xhc3MgbWVldGluZy4NCi0gICAkeV82JDogTGlzdGVuaW5nIHRvIGEgbGVjdHVyZSBpbiBtYXRoIGNsYXNzLg0KLSAgICR5XzckOiBMaXN0ZW5pbmcgdG8gYW5vdGhlciBzdHVkZW50IGV4cGxhaW4gaG93IHRvIGRvIGEgbWF0aCBwcm9ibGVtLg0KLSAgICR5XzgkOiBCZWluZyBnaXZlbiBhIHF1aXogb24gbWF0aCB3aXRob3V0IGtub3dpbmcgaW4gYWR2YW5jZS4NCi0gICAkeV85JDogU3RhcnRpbmcgYSBuZXcgY2hhcHRlciBpbiBhIG1hdGggYm9vay4NCg0KKioyLiBGYWN0b3IgTG9hZGluZ3MgYW5kIE1vZGVsIFN0cnVjdHVyZSoqDQoNCldlIGh5cG90aGVzaXplIHRoZSBmb2xsb3dpbmcgZmFjdG9yIHN0cnVjdHVyZToNCg0KLSAgIEZhY3RvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSBsb2FkcyBvbiBpdGVtcyAkeV8yJCwgJHlfNCQsICR5XzUkLCBhbmQgJHlfOCQuDQotICAgRmFjdG9yICRcZXRhXzIkIChMZWFybmluZyBBbnhpZXR5KSBsb2FkcyBvbiBpdGVtcyAkeV8xJCwgJHlfMyQsICR5XzYkLCAkeV83JCwgYW5kICR5XzkkLg0KDQpUaGUgZnVuZGFtZW50YWwgZXF1YXRpb24gZm9yIGEgQ0ZBIG1vZGVsIGZvciBhIHNpbmdsZSBvYnNlcnZlZCB2YXJpYWJsZSAkeV9pJCBpczoNCg0KJCQNCnlfaSA9IFxudV9pICsgXGxhbWJkYV97aTF9IFxldGFfMSArIFxsYW1iZGFfe2kyfSBcZXRhXzIgKyBcZXBzaWxvbl9pDQokJA0KDQp3aGVyZToNCg0KLSAgICRcbnVfaSQgaXMgdGhlIGludGVyY2VwdCBmb3Igb2JzZXJ2ZWQgdmFyaWFibGUgJHlfaSQuDQotICAgJFxsYW1iZGFfe2kxfSQgaXMgdGhlIGZhY3RvciBsb2FkaW5nIG9mICR5X2kkIG9uIGxhdGVudCBmYWN0b3IgJFxldGFfMSQuDQotICAgJFxsYW1iZGFfe2kyfSQgaXMgdGhlIGZhY3RvciBsb2FkaW5nIG9mICR5X2kkIG9uIGxhdGVudCBmYWN0b3IgJFxldGFfMiQuDQotICAgJFxlcHNpbG9uX2kkIGlzIHRoZSB1bmlxdWUgZmFjdG9yIChtZWFzdXJlbWVudCBlcnJvcikgZm9yICR5X2kkLg0KDQoqKjMuIFRoZSBNZWFzdXJlbWVudCBNb2RlbCBpbiBNYXRyaXggRm9ybSoqDQoNClRoZSBtb2RlbCBmb3IgYWxsIG5pbmUgb2JzZXJ2ZWQgdmFyaWFibGVzIGNhbiBiZSB3cml0dGVuIGNvbXBhY3RseSBpbiBtYXRyaXggZm9ybS4gV2UgZGVmaW5lIHRoZSBmb2xsb3dpbmcgdmVjdG9ycyBhbmQgbWF0cmljZXM6DQoNCi0gICAkXG1hdGhiZnt5fSA9ICh5XzEsIHlfMiwgXGRvdHMsIHlfOSleVCQgaXMgYSAkOSBcdGltZXMgMSQgdmVjdG9yIG9mIG9ic2VydmVkIHZhcmlhYmxlcy4NCi0gICAkXGJvbGRzeW1ib2x7XG51fSA9IChcbnVfMSwgXG51XzIsIFxkb3RzLCBcbnVfOSleVCQgaXMgYSAkOSBcdGltZXMgMSQgdmVjdG9yIG9mIGludGVyY2VwdHMuDQotICAgJFxib2xkc3ltYm9se1xldGF9ID0gKFxldGFfMSwgXGV0YV8yKV5UJCBpcyBhICQyIFx0aW1lcyAxJCB2ZWN0b3Igb2YgbGF0ZW50IGZhY3RvcnMuDQotICAgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyBhICQ5IFx0aW1lcyAyJCBtYXRyaXggb2YgZmFjdG9yIGxvYWRpbmdzICRcbGFtYmRhX3tpan0kLg0KLSAgICRcYm9sZHN5bWJvbHtcZXBzaWxvbn0gPSAoXGVwc2lsb25fMSwgXGVwc2lsb25fMiwgXGRvdHMsIFxlcHNpbG9uXzkpXlQkIGlzIGEgJDkgXHRpbWVzIDEkIHZlY3RvciBvZiBtZWFzdXJlbWVudCBlcnJvcnMuDQoNClRoZSBmdWxsIG1lYXN1cmVtZW50IG1vZGVsIGlzOg0KDQokJA0KXG1hdGhiZnt5fSA9IFxib2xkc3ltYm9se1xudX0gKyBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcYm9sZHN5bWJvbHtcZXRhfSArIFxib2xkc3ltYm9se1xlcHNpbG9ufQ0KJCQNCg0KR2l2ZW4gb3VyIGh5cG90aGVzaXplZCBmYWN0b3Igc3RydWN0dXJlLCB0aGUgbG9hZGluZyBtYXRyaXggJFxib2xkc3ltYm9se1xMYW1iZGF9JCBoYXMgYSBzcGVjaWZpYyBmb3JtIHdpdGggbWFueSBlbGVtZW50cyBmaXhlZCB0byB6ZXJvLiBUbyBlbnN1cmUgbW9kZWwgaWRlbnRpZmljYXRpb24sIHdlIG5lZWQgdG8gc2V0IHRoZSBzY2FsZSBvZiBlYWNoIGxhdGVudCB2YXJpYWJsZS4gVGhpcyBpcyB0eXBpY2FsbHkgZG9uZSBieSAqKmZhY3RvciBzdGFuZGFyZGl6YXRpb24qKiwgd2hlcmUgdGhlIHZhcmlhbmNlIG9mIHRoZSBsYXRlbnQgZmFjdG9yIGlzIGZpeGVkIHRvIDEsIG9yIGJ5ICoqbWFya2VyIHZhcmlhYmxlKiogbWV0aG9kLCB3aGVyZSBvbmUgbG9hZGluZyBwZXIgZmFjdG9yIGlzIGZpeGVkIHRvIDEuIFdlIHdpbGwgdXNlIHRoZSBsYXR0ZXIuDQoNCkxldCB1cyBkZWZpbmU6DQoNCi0gICAkeV8yJCBhcyB0aGUgbWFya2VyIHZhcmlhYmxlIGZvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSwgc28gJFxsYW1iZGFfezIxfSA9IDEkLg0KLSAgICR5XzEkIGFzIHRoZSBtYXJrZXIgdmFyaWFibGUgZm9yICRcZXRhXzIkIChMZWFybmluZyBBbnhpZXR5KSwgc28gJFxsYW1iZGFfezEyfSA9IDEkLg0KDQpUaGUgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBtYXRyaXggaXMgdGhlbjoNCg0KJCQNClxib2xkc3ltYm9se1xMYW1iZGF9ID0NClxiZWdpbntibWF0cml4fQ0KMCAmIDEgXFwgICAgICAgICAgICAgICUgeTEgbG9hZHMgb24gZXRhMiAoTEEpDQoxICYgMCBcXCAgICAgICAgICAgICAgJSB5MiBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3szMn0gXFwgICAlIHkzIGxvYWRzIG9uIGV0YTIgKExBKQ0KXGxhbWJkYV97NDF9ICYgMCBcXCAgICUgeTQgbG9hZHMgb24gZXRhMSAoVEEpDQpcbGFtYmRhX3s1MX0gJiAwIFxcICAgJSB5NSBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s2Mn0gXFwgICAlIHk2IGxvYWRzIG9uIGV0YTIgKExBKQ0KMCAmIFxsYW1iZGFfezcyfSBcXCAgICUgeTcgbG9hZHMgb24gZXRhMiAoTEEpDQpcbGFtYmRhX3s4MX0gJiAwIFxcICAgJSB5OCBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s5Mn0gXFwgICAlIHk5IGxvYWRzIG9uIGV0YTIgKExBKQ0KXGVuZHtibWF0cml4fQ0KJCQNCg0KKio0LiBNb2RlbCBBc3N1bXB0aW9ucyoqDQoNClRoZSBDRkEgbW9kZWwgcmVsaWVzIG9uIHNldmVyYWwga2V5IGFzc3VtcHRpb25zOg0KDQotICAgVGhlIGxhdGVudCBmYWN0b3JzIGFuZCBlcnJvcnMgYXJlIG11bHRpdmFyaWF0ZSBub3JtYWxseSBkaXN0cmlidXRlZDogJFxib2xkc3ltYm9se1xldGF9IFxzaW0gTihcbWF0aGJmezB9LCBcYm9sZHN5bWJvbHtcUHNpfSkkIGFuZCAkXGJvbGRzeW1ib2x7XGVwc2lsb259IFxzaW0gTihcbWF0aGJmezB9LCBcYm9sZHN5bWJvbHtcVGhldGF9X1xlcHNpbG9uKSQuDQoNCi0gICBUaGUgZXJyb3JzIGFuZCBmYWN0b3JzIGFyZSBpbmRlcGVuZGVudDogJFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXRhfSwgXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxtYXRoYmZ7MH0kLg0KDQotICAgVGhlIG9ic2VydmVkIHZhcmlhYmxlcywgYmVpbmcgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiBub3JtYWwgcmFuZG9tIHZhcmlhYmxlcywgYXJlIHRoZXJlZm9yZSBhbHNvIG11bHRpdmFyaWF0ZSBub3JtYWw6ICRcbWF0aGJme3l9IFxzaW0gTihcYm9sZHN5bWJvbHtcbnV9LCBcYm9sZHN5bWJvbHtcU2lnbWF9KSQuDQoNCioqNS4gRGVyaXZhdGlvbiBvZiB0aGUgSW1wbGllZCBDb3ZhcmlhbmNlIE1hdHJpeCoqDQoNClRoZSBjb3JlIG9mIENGQSBpcyB0byBtb2RlbCB0aGUgcG9wdWxhdGlvbiBjb3ZhcmlhbmNlIG1hdHJpeCBvZiB0aGUgb2JzZXJ2ZWQgdmFyaWFibGVzLCAkXGJvbGRzeW1ib2x7XFNpZ21hfSQuIFRoZSBtb2RlbC1pbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4LCBkZW5vdGVkICRcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pJCwgaXMgYSBmdW5jdGlvbiBvZiB0aGUgbW9kZWwgcGFyYW1ldGVycyAkXGJvbGRzeW1ib2x7XHRoZXRhfSQgKGxvYWRpbmdzLCBmYWN0b3IgdmFyaWFuY2VzL2NvdmFyaWFuY2VzLCBlcnJvciB2YXJpYW5jZXMpLg0KDQpMZXQgJFxib2xkc3ltYm9se1xQc2l9JCBiZSB0aGUgJDIgXHRpbWVzIDIkIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBsYXRlbnQgZmFjdG9yczoNCg0KJCQNClxib2xkc3ltYm9se1xQc2l9ID0gXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xldGF9KSA9DQpcYmVnaW57Ym1hdHJpeH0NClxwc2lfezExfSAmIFxwc2lfezEyfSBcXA0KXHBzaV97MjF9ICYgXHBzaV97MjJ9DQpcZW5ke2JtYXRyaXh9DQo9DQpcYmVnaW57Ym1hdHJpeH0NClxtYXRocm17VmFyfShcZXRhXzEpICYgXG1hdGhybXtDb3Z9KFxldGFfMSwgXGV0YV8yKSBcXA0KXG1hdGhybXtDb3Z9KFxldGFfMSwgXGV0YV8yKSAmIFxtYXRocm17VmFyfShcZXRhXzIpDQpcZW5ke2JtYXRyaXh9DQokJA0KDQpUaGUgaW1wbGllZCBjb3ZhcmlhbmNlIG1hdHJpeCAkXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgZGVyaXZlZCBhcyBmb2xsb3dzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXG1hdGhybXtDb3Z9KFxtYXRoYmZ7eX0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XG51fSArIFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSArIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgXHF1YWQgXHRleHR7KHNpbmNlIH0gXGJvbGRzeW1ib2x7XG51fSBcdGV4dHsgaXMgYSBjb25zdGFudCl9IFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkgKyBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pICsgXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSwgXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkNClxlbmR7YWxpZ24qfQ0KJCQNCg0KVXNpbmcgYXNzdW1wdGlvbiAyICgkXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSQpLCB0aGUgY3Jvc3MtdGVybXMgdmFuaXNoOg0KDQokJA0KXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XGV0YX0sIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0sIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcbWF0aGJmezB9LCBccXVhZCBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259LCBcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9KSA9IFxtYXRoYmZ7MH0NCiQkDQoNClRoZXJlZm9yZSwNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0pIFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0gXFwNCiY9IFxib2xkc3ltYm9se1xMYW1iZGF9IFxib2xkc3ltYm9se1xQc2l9IFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KVGhpcyBpcyB0aGUgZnVuZGFtZW50YWwgZXF1YXRpb24gZm9yIHRoZSBpbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4IGluIENGQToNCg0KJCQNClxib3hlZHtcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pID0gXGJvbGRzeW1ib2x7XExhbWJkYX0gXGJvbGRzeW1ib2x7XFBzaX0gXGJvbGRzeW1ib2x7XExhbWJkYX1eVCArIFxib2xkc3ltYm9se1xUaGV0YX1fe1xlcHNpbG9ufX0NCiQkDQoNCioqNi4gUGFyYW1ldGVyIEVzdGltYXRpb24gYW5kIE1vZGVsIElkZW50aWZpY2F0aW9uKioNCg0KVGhlIGdvYWwgb2YgZXN0aW1hdGlvbiBpcyB0byBmaW5kIHBhcmFtZXRlciB2YWx1ZXMgJFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0kIHN1Y2ggdGhhdCAkXGJvbGRzeW1ib2x7XFNpZ21hfShcaGF0e1xib2xkc3ltYm9se1x0aGV0YX19KSQgaXMgYXMgY2xvc2UgYXMgcG9zc2libGUgdG8gdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfSQgb2J0YWluZWQgZnJvbSB0aGUgZGF0YS4NCg0KRm9yIGlkZW50aWZpY2F0aW9uLCB0aGUgbnVtYmVyIG9mIGZyZWUgcGFyYW1ldGVycyAkdCQgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBub24tcmVkdW5kYW50IGVsZW1lbnRzIGluICRcbWF0aGJme1N9JCwgd2hpY2ggaXMgJFxmcmFje3AocCsxKX17Mn0kIHdoZXJlICRwJCBpcyB0aGUgbnVtYmVyIG9mIG9ic2VydmVkIHZhcmlhYmxlcyAoJHA9OSQpLg0KDQpMZXQncyBjb3VudCBvdXIgZnJlZSBwYXJhbWV0ZXJzICR0JDoNCg0KLSAgICoqRmFjdG9yIExvYWRpbmdzKiogKCRcYm9sZHN5bWJvbHtcTGFtYmRhfSQpfTogV2UgZml4ZWQgJFxsYW1iZGFfezIxfSQgYW5kICRcbGFtYmRhX3sxMn0kIHRvIDEuIFdlIGhhdmUgNyBmcmVlIGxvYWRpbmdzOiAkXGxhbWJkYV97MzJ9JCwgJFxsYW1iZGFfezQxfSQsICRcbGFtYmRhX3s1MX0kLCAkXGxhbWJkYV97NjJ9JCwgJFxsYW1iZGFfezcyfSQsICRcbGFtYmRhX3s4MX0kLCAkXGxhbWJkYV97OTJ9JC4NCg0KLSAgICoqTGF0ZW50IEZhY3RvciBDb3ZhcmlhbmNlcyoqICgkXGJvbGRzeW1ib2x7XFBzaX0kKX06IFdlIGhhdmUgMyBmcmVlIHBhcmFtZXRlcnM6ICRccHNpX3sxMX0kICh2YXJpYW5jZSBvZiBUQSksICRccHNpX3syMn0kICh2YXJpYW5jZSBvZiBMQSksIGFuZCAkXHBzaV97MTJ9JCAoY292YXJpYW5jZSBiZXR3ZWVuIFRBIGFuZCBMQSkuDQoNCi0gICAqKkVycm9yIFZhcmlhbmNlcyoqICgkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259JCl9OiBXZSBoYXZlIDkgZnJlZSBwYXJhbWV0ZXJzOiAkXHRoZXRhX3sxMX0sIFx0aGV0YV97MjJ9LCBcZG90cywgXHRoZXRhX3s5OX0kLg0KDQpUb3RhbCBmcmVlIHBhcmFtZXRlcnM6ICR0ID0gNyArIDMgKyA5ID0gMTkkLg0KDQpUaGUgbnVtYmVyIG9mIG5vbi1yZWR1bmRhbnQgZWxlbWVudHMgaW4gJFxtYXRoYmZ7U30kIGlzICRcZnJhY3s5IFx0aW1lcyAoOSsxKX17Mn0gPSA0NSQuDQoNClNpbmNlICQ0NSA+IDE5JCwgdGhlIG1vZGVsIGlzICoqb3Zlci1pZGVudGlmaWVkKiogd2l0aCAkZGYgPSA0NSAtIDE5ID0gMjYkIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhpcyBpcyBhIG5lY2Vzc2FyeSBjb25kaXRpb24gZm9yIGlkZW50aWZpY2F0aW9uLCBhbmQgd2l0aCB0aGUgc2NhbGluZyBjb25zdHJhaW50cyB3ZSBwbGFjZWQsIHRoZSBtb2RlbCBpcyBpZGVudGlmaWVkLg0KDQoqKjcuIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIG9mIFBhcmFtZXRlcnMqKg0KDQpUaGlzIGRlcml2YXRpb24gaGFzIG91dGxpbmVkIHRoZSBjb21wbGV0ZSBtYXRoZW1hdGljYWwgc2V0dXAgZm9yIGEgdHdvLWZhY3RvciBDRkEgbW9kZWwgb2YgbWF0aGVtYXRpY2FsIGFueGlldHkuIFRoZSBtb2RlbCBwb3NpdHMgdGhhdCB0aGUgY292YXJpYXRpb24gYW1vbmcgdGhlIG5pbmUgb2JzZXJ2ZWQgaXRlbXMgY2FuIGJlIGV4cGxhaW5lZCBieSB0d28gY29ycmVsYXRlZCBsYXRlbnQgZmFjdG9ycy4gVGhlIG5leHQgc3RlcCB3b3VsZCBiZSB0byB1c2UgYW4gZXN0aW1hdGlvbiBhbGdvcml0aG0gKGUuZy4sIE1heGltdW0gTGlrZWxpaG9vZCkgdG8gZmluZCB0aGUgcGFyYW1ldGVyIHZhbHVlcyB0aGF0IG1pbmltaXplIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGFuZCB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9JCwgYW5kIHRoZW4gYXNzZXNzIHRoZSBtb2RlbCdzIGZpdCB0byB0aGUgZGF0YS4NCg0KVGhlIGdvYWwgaXMgdG8gZmluZCB0aGUgcGFyYW1ldGVyIHZhbHVlcyAkXGhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSQgdGhhdCBtYWtlIHRoZSBtb2RlbC1pbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4ICRcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pJCBtb3N0IGxpa2VseSB0byBoYXZlIHByb2R1Y2VkIHRoZSBvYnNlcnZlZCBzYW1wbGUgZGF0YS4NCg0KR2l2ZW4gYSBzYW1wbGUgb2YgJE4kIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZCAoaS5pLmQuKSBvYnNlcnZhdGlvbnMgJFxtYXRoYmZ7eX1fMSwgXG1hdGhiZnt5fV8yLCBcZG90cywgXG1hdGhiZnt5fV9OJCwgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gJEwoXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGlzIHRoZSBqb2ludCBwcm9iYWJpbGl0eSBkZW5zaXR5IG9mIG9ic2VydmluZyBhbGwgdGhlIGRhdGEsIGdpdmVuIHRoZSBwYXJhbWV0ZXJzLiBVbmRlciB0aGUgaS5pLmQuIGFzc3VtcHRpb24sIHRoaXMgaXMgdGhlIHByb2R1Y3Qgb2YgdGhlIGluZGl2aWR1YWwgcHJvYmFiaWxpdHkgZGVuc2l0eSBmdW5jdGlvbnMgKFBERnMpOg0KDQokJA0KTChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxwcm9kX3tpPTF9XntOfSBmKFxtYXRoYmZ7eX1faSB8IFxib2xkc3ltYm9se1x0aGV0YX0pDQokJA0KDQpXaGVyZSAkZihcbWF0aGJme3l9X2kgfCBcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgdGhlIG11bHRpdmFyaWF0ZSBub3JtYWwgUERGIGZvciBhIHNpbmdsZSBvYnNlcnZhdGlvbiB2ZWN0b3IgJFxtYXRoYmZ7eX1faSQ6DQoNCiQkDQpmKFxtYXRoYmZ7eX1faSB8IFxib2xkc3ltYm9se1x0aGV0YX0pID0gXGZyYWN7MX17KDJccGkpXntwLzJ9IHxcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfF57MS8yfX0gXGV4cFxsZWZ0WyAtXGZyYWN7MX17Mn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSBccmlnaHRdDQokJA0KDQpUaHVzLCB0aGUgZnVsbCBsaWtlbGlob29kIGZ1bmN0aW9uIGlzOg0KDQokJA0KTChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxwcm9kX3tpPTF9XntOfSBcbGVmdFsgXGZyYWN7MX17KDJccGkpXntwLzJ9IHxcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfF57MS8yfX0gXGV4cFxsZWZ0KCAtXGZyYWN7MX17Mn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSBccmlnaHQpIFxyaWdodF0NCiQkDQoNCio3LjEgVGhlIExvZy1MaWtlbGlob29kIEZ1bmN0aW9uKg0KDQpJdCBpcyBjb21wdXRhdGlvbmFsbHkgZWFzaWVyIHRvIHdvcmsgd2l0aCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24sIHRoZSBsb2ctbGlrZWxpaG9vZCAkXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSA9IFxsbiBMKFxib2xkc3ltYm9se1x0aGV0YX0pJC4gQ29udmVydGluZyB0aGUgcHJvZHVjdCBpbnRvIGEgc3VtIHNpbXBsaWZpZXMgdGhlIGV4cHJlc3Npb246DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcc3VtX3tpPTF9XntOfSBcbG4gZihcbWF0aGJme3l9X2kgfCBcYm9sZHN5bWJvbHtcdGhldGF9KSBcXA0KJj0gXHN1bV97aT0xfV57Tn0gXGxlZnRbIC1cZnJhY3twfXsyfSBcbG4oMlxwaSkgLSBcZnJhY3sxfXsyfSBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8IC0gXGZyYWN7MX17Mn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSBccmlnaHRdDQpcZW5ke2FsaWduKn0NCiQkDQoNCldlIGNhbiBmYWN0b3Igb3V0IHRoZSB0ZXJtcyB0aGF0IGRvIG5vdCBkZXBlbmQgb24gdGhlIHN1bW1hdGlvbiBpbmRleCAkaSQ6DQoNCiQkDQpcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pID0gLVxmcmFje05wfXsyfSBcbG4oMlxwaSkgLSBcZnJhY3tOfXsyfSBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8IC0gXGZyYWN7MX17Mn0gXHN1bV97aT0xfV57Tn0gXGxlZnRbIChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt5fV9pIC0gXGJvbGRzeW1ib2x7XG51fSkgXHJpZ2h0XQ0KJCQNCg0KKjcuMi4gU2ltcGxpZnlpbmcgd2l0aCB0aGUgU2FtcGxlIENvdmFyaWFuY2UgTWF0cml4Kg0KDQpUaGUgc3VtbWF0aW9uIHRlcm0gaXMgcmVsYXRlZCB0byB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4LiBMZXQncyBkZWZpbmUgdGhlIHNhbXBsZSBtZWFuIHZlY3RvciBhcyAkXGJhcntcbWF0aGJme3l9fSA9IFxmcmFjezF9e059IFxzdW1fe2k9MX1eTiBcbWF0aGJme3l9X2kkLiBJdCBjYW4gYmUgc2hvd24gdGhhdDoNCg0KJCQNClxzdW1fe2k9MX1ee059IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt5fV9pIC0gXGJvbGRzeW1ib2x7XG51fSkgPSBOIFxjZG90IFxtYXRocm17dHJ9XGxlZnQoIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSBcbWF0aGJme1N9IFxyaWdodCkgKyBOIChcYmFye1xtYXRoYmZ7eX19IC0gXGJvbGRzeW1ib2x7XG51fSleVCBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pXnstMX0gKFxiYXJ7XG1hdGhiZnt5fX0gLSBcYm9sZHN5bWJvbHtcbnV9KQ0KJCQNCg0Kd2hlcmUgJFxtYXRoYmZ7U30kIGlzIHRoZSB1bmJpYXNlZCBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXg6DQoNCiQkDQpcbWF0aGJme1N9ID0gXGZyYWN7MX17Ti0xfSBcc3VtX3tpPTF9XntOfSAoXG1hdGhiZnt5fV9pIC0gXGJhcntcbWF0aGJme3l9fSkoXG1hdGhiZnt5fV9pIC0gXGJhcntcbWF0aGJme3l9fSleVA0KJCQNCg0KYW5kICRcbWF0aHJte3RyfShcY2RvdCkkIGlzIHRoZSB0cmFjZSBvcGVyYXRvci4NCg0KSW4gdGhlIHR5cGljYWwgc2V0dXAgd2hlcmUgdGhlIG1vZGVsIGZvciB0aGUgbWVhbnMgaXMgc2F0dXJhdGVkIChpLmUuLCB3ZSBzZXQgJFxib2xkc3ltYm9se1xudX0gPSBcYmFye1xtYXRoYmZ7eX19JCksIHRoZSBsYXN0IHRlcm0gdmFuaXNoZXMuIEZ1cnRoZXJtb3JlLCBmb3Igc2ltcGxpY2l0eSBpbiBkZXJpdmF0aW9uLCBpZiB3ZSB1c2UgdGhlIE1heGltdW0gTGlrZWxpaG9vZCBlc3RpbWF0b3IgZm9yIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfV97TUx9ID0gXGZyYWN7MX17Tn0gXHN1bV97aT0xfV57Tn0gKFxtYXRoYmZ7eX1faSAtIFxiYXJ7XG1hdGhiZnt5fX0pKFxtYXRoYmZ7eX1faSAtIFxiYXJ7XG1hdGhiZnt5fX0pXlQkLCB0aGUgZXhwcmVzc2lvbiBzaW1wbGlmaWVzIHNpZ25pZmljYW50bHkuDQoNCldpdGggJFxib2xkc3ltYm9se1xudX0gPSBcYmFye1xtYXRoYmZ7eX19JCwgd2UgZ2V0Og0KDQokJA0KXHN1bV97aT0xfV57Tn0gKFxtYXRoYmZ7eX1faSAtIFxib2xkc3ltYm9se1xudX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3l9X2kgLSBcYm9sZHN5bWJvbHtcbnV9KSA9IE4gXGNkb3QgXG1hdGhybXt0cn1cbGVmdCggXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IFxtYXRoYmZ7U31fe01MfSBccmlnaHQpDQokJA0KDQpTdWJzdGl0dXRpbmcgdGhpcyBiYWNrIGludG8gdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uLCBhbmQgaWdub3JpbmcgdGhlIGNvbnN0YW50IHRlcm0gJC1cZnJhY3tOcH17Mn0gXGxuKDJccGkpJCBhcyBpdCBkb2VzIG5vdCBhZmZlY3Qgb3B0aW1pemF0aW9uLCB3ZSBhcnJpdmUgYXQgdGhlIGNvcmUgZnVuY3Rpb24gbWluaW1pemVkIGluIE1MLUNGQToNCg0KJCQNClxib3hlZHtcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pID0gLVxmcmFje059ezJ9IFxsZWZ0WyBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8ICsgXG1hdGhybXt0cn1cbGVmdCggXG1hdGhiZntTfV97TUx9IFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSBccmlnaHQpIFxyaWdodF0gKyBcdGV4dHtjb25zdGFudH19DQokJA0KDQoqNy4zLiBNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbioNCg0KVGhlIE1heGltdW0gTGlrZWxpaG9vZCBlc3RpbWF0ZXMgJFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0kIGFyZSBmb3VuZCBieSBtYXhpbWl6aW5nIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbjoNCg0KJCQNClxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX1fe01MfSA9IFx1bmRlcnNldHtcYm9sZHN5bWJvbHtcdGhldGF9fXtcYXJnXG1heH0gXCBcZWxsKFxib2xkc3ltYm9se1x0aGV0YX0pDQokJA0KDQpJbiBwcmFjdGljZSwgdGhpcyBpcyBkb25lIHVzaW5nIGl0ZXJhdGl2ZSBudW1lcmljYWwgYWxnb3JpdGhtcyAoZS5nLiwgTmV3dG9uLVJhcGhzb24sIEZpc2hlciBTY29yaW5nKSBiZWNhdXNlIHRoZSBmdW5jdGlvbiAkXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgaGlnaGx5IG5vbmxpbmVhciBpbiB0aGUgcGFyYW1ldGVycyAkXGJvbGRzeW1ib2x7XHRoZXRhfSQuDQoNClRoZSB2YWx1ZSBvZiB0aGUgbGlrZWxpaG9vZCBhdCB0aGUgbWF4aW11bSBpcyBhbHNvIHVzZWQgdG8gY29tcHV0ZSBnb29kbmVzcy1vZi1maXQgc3RhdGlzdGljcywgbW9zdCBub3RhYmx5IHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgKG9yIGNoaS1zcXVhcmUgdGVzdCBvZiBtb2RlbCBmaXQpLCB3aGljaCBjb21wYXJlcyB0aGUgZml0dGVkIG1vZGVsIHRvIGEgc2F0dXJhdGVkIG1vZGVsOg0KDQokJA0KXGNoaV4yID0gKE4tMSkgRl97TUx9DQokJA0KDQp3aGVyZSAkRl97TUx9JCBpcyB0aGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgZGlzY3JlcGFuY3kgZnVuY3Rpb24sIGRlcml2ZWQgZnJvbSB0aGUgbG9nLWxpa2VsaWhvb2Q6DQoNCiQkDQpGX3tNTH0gPSBcbG4gfFxib2xkc3ltYm9se1xTaWdtYX0oXGhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSl8ICsgXG1hdGhybXt0cn1cbGVmdCggXG1hdGhiZntTfSBcYm9sZHN5bWJvbHtcU2lnbWF9KFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0pXnstMX0gXHJpZ2h0KSAtIFxsbiB8XG1hdGhiZntTfXwgLSBwDQokJA0KDQpcDQoNCiMjIE1hdGhlbWF0aWNhbCBGb3JtdWxhdGlvbiBvZiBTRU0gTW9kZWwNCg0KKioxLiBNb2RlbCBTcGVjaWZpY2F0aW9uKioNCg0KTGV0IHRoZSBtb2RlbCBjb25zaXN0IG9mIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czoNCg0KLSAgICoqRXhvZ2Vub3VzIGxhdGVudCB2YXJpYWJsZXMqKjogJFxib2xkc3ltYm9se1x4aX0gPSAoXHhpXzEsIFx4aV8yKV5UJCwgd2hlcmU6DQogICAgLSAgICRceGlfMSQ6IFRlYWNoZXItY2VudGVyZWQNCiAgICAtICAgJFx4aV8yJDogU3R1ZGVudC1jZW50ZXJlZA0KLSAgICoqRW5kb2dlbm91cyBsYXRlbnQgdmFyaWFibGVzKio6ICRcYm9sZHN5bWJvbHtcZXRhfSA9IChcZXRhXzEsIFxldGFfMileVCQsIHdoZXJlOg0KICAgIC0gICAkXGV0YV8xJDogTWF0aCBFdmFsdWF0aW9uIEFueGlldHkgKE1FQSkNCiAgICAtICAgJFxldGFfMiQ6IE1hdGggTGVhcm5pbmcgQW54aWV0eSAoTUxBKQ0KLSAgICoqT2JzZXJ2ZWQgaW5kaWNhdG9ycyBmb3IgVGVhY2hlci1jZW50ZXJlZCoqOiAkXG1hdGhiZnt4fV8xID0gKHhfMSwgeF8yLCB4XzMsIHhfNCleVCQgd2hlcmU6DQogICAgLSAgICR4XzEkOiBEZWR1Y3RpdmUNCiAgICAtICAgJHhfMiQ6IExlY3R1cmUNCiAgICAtICAgJHhfMyQ6IERlbW9uc3RyYXRpb24NCiAgICAtICAgJHhfNCQ6IFJlcGV0aXRpdmUNCi0gICAqKk9ic2VydmVkIGluZGljYXRvcnMgZm9yIFN0dWRlbnQtY2VudGVyZWQqKjogJFxtYXRoYmZ7eH1fMiA9ICh4XzUsIHhfNiwgeF83KV5UJCB3aGVyZToNCiAgICAtICAgJHhfNSQ6IENvb3BlcmF0aXZlDQogICAgLSAgICR4XzYkOiBJbmR1Y3RpdmUNCiAgICAtICAgJHhfNyQ6IEludGVncmF0aXZlDQotICAgKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBNRUEqKjogJFxtYXRoYmZ7eX1fMSA9ICh5XzEsIHlfMiwgeV8zLCB5XzQpXlQkIChNRUExLU1FQTQpDQotICAgKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBNTEEqKjogJFxtYXRoYmZ7eX1fMiA9ICh5XzUsIHlfNiwgeV83LCB5XzgsIHlfOSleVCQgKE1MQTEsIE1MQTMsIE1MQTYsIE1MQTcsIE1MQTkpDQotICAgKipFeG9nZW5vdXMgb2JzZXJ2ZWQgdmFyaWFibGVzKio6ICRcbWF0aGJme3d9ID0gKHdfMSwgd18yLCB3XzMsIHdfNCwgd181KV5UJCB3aGVyZToNCiAgICAtICAgJHdfMSQ6IFNlbGYtZWZmaWNhY3kNCiAgICAtICAgJHdfMiQ6IFRlY2hub2xvZ3kNCiAgICAtICAgJHdfMyQ6IEVuZ2FnZW1lbnQNCiAgICAtICAgJHdfNCQ6IEdlbmRlcg0KICAgIC0gICAkd181JDogUmVzb3VyY2UNCg0KKioyLiBNZWFzdXJlbWVudCBNb2RlbHMqKg0KDQoqRm9yIGV4b2dlbm91cyBsYXRlbnQgdmFyaWFibGVzOioNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcbWF0aGJme3h9ICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXGJvbGRzeW1ib2x7XHhpfSArIFxib2xkc3ltYm9se1xkZWx0YX0gXFwNClxiZWdpbntibWF0cml4fQ0KeF8xIFxcIHhfMiBcXCB4XzMgXFwgeF80IFxcIHhfNSBcXCB4XzYgXFwgeF83DQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQpcbGFtYmRhX3sxLDF9ICYgMCBcXA0KXGxhbWJkYV97MiwxfSAmIDAgXFwNClxsYW1iZGFfezMsMX0gJiAwIFxcDQpcbGFtYmRhX3s0LDF9ICYgMCBcXA0KMCAmIFxsYW1iZGFfezUsMn0gXFwNCjAgJiBcbGFtYmRhX3s2LDJ9IFxcDQowICYgXGxhbWJkYV97NywyfQ0KXGVuZHtibWF0cml4fQ0KXGJlZ2lue2JtYXRyaXh9DQpceGlfMSBcXCBceGlfMg0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcZGVsdGFfMSBcXCBcZGVsdGFfMiBcXCBcZGVsdGFfMyBcXCBcZGVsdGFfNCBcXCBcZGVsdGFfNSBcXCBcZGVsdGFfNiBcXCBcZGVsdGFfNw0KXGVuZHtibWF0cml4fQ0KXGVuZHthbGlnbip9DQokJA0KDQoqRm9yIGVuZG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlczoqDQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXG1hdGhiZnt5fSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV95IFxib2xkc3ltYm9se1xldGF9ICsgXGJvbGRzeW1ib2x7XGVwc2lsb259IFxcDQpcYmVnaW57Ym1hdHJpeH0NCnlfMSBcXCB5XzIgXFwgeV8zIFxcIHlfNCBcXCB5XzUgXFwgeV82IFxcIHlfNyBcXCB5XzggXFwgeV85DQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQpcbGFtYmRhX3sxLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3syLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3szLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3s0LDF9XnkgJiAwIFxcDQowICYgXGxhbWJkYV97NSwyfV55IFxcDQowICYgXGxhbWJkYV97NiwyfV55IFxcDQowICYgXGxhbWJkYV97NywyfV55IFxcDQowICYgXGxhbWJkYV97OCwyfV55IFxcDQowICYgXGxhbWJkYV97OSwyfV55DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClxldGFfMSBcXCBcZXRhXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGVwc2lsb25fMSBcXCBcZXBzaWxvbl8yIFxcIFxlcHNpbG9uXzMgXFwgXGVwc2lsb25fNCBcXCBcZXBzaWxvbl81IFxcIA0KXGVwc2lsb25fNiBcXCBcZXBzaWxvbl83IFxcIFxlcHNpbG9uXzggXFwgXGVwc2lsb25fOQ0KXGVuZHtibWF0cml4fQ0KXGVuZHthbGlnbip9DQokJA0KDQoqKjMuIFN0cnVjdHVyYWwgTW9kZWwqKg0KDQpUaGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGxhdGVudCBhbmQgb2JzZXJ2ZWQgdmFyaWFibGVzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xldGF9ICY9IFxtYXRoYmZ7Qn0gXGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcR2FtbWF9IFxib2xkc3ltYm9se1x4aX0gKyBcYm9sZHN5bWJvbHtcR2FtbWF9X3cgXG1hdGhiZnt3fSArIFxib2xkc3ltYm9se1x6ZXRhfSBcXA0KXGJlZ2lue2JtYXRyaXh9DQpcZXRhXzEgXFwgXGV0YV8yDQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQowICYgMCBcXA0KXGJldGFfezIxfSAmIDANClxlbmR7Ym1hdHJpeH0NClxiZWdpbntibWF0cml4fQ0KXGV0YV8xIFxcIFxldGFfMg0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcZ2FtbWFfezExfSAmIFxnYW1tYV97MTJ9IFxcDQpcZ2FtbWFfezIxfSAmIFxnYW1tYV97MjJ9DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClx4aV8xIFxcIFx4aV8yDQpcZW5ke2JtYXRyaXh9DQorDQpcYmVnaW57Ym1hdHJpeH0NClxnYW1tYV97MTN9ICYgXGdhbW1hX3sxNH0gJiBcZ2FtbWFfezE1fSAmIFxnYW1tYV97MTZ9ICYgXGdhbW1hX3sxN30gXFwNClxnYW1tYV97MjN9ICYgXGdhbW1hX3syNH0gJiBcZ2FtbWFfezI1fSAmIFxnYW1tYV97MjZ9ICYgXGdhbW1hX3syN30NClxlbmR7Ym1hdHJpeH0NClxiZWdpbntibWF0cml4fQ0Kd18xIFxcIHdfMiBcXCB3XzMgXFwgd180IFxcIHdfNQ0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcemV0YV8xIFxcIFx6ZXRhXzINClxlbmR7Ym1hdHJpeH0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KKio0LiBBc3N1bXB0aW9ucyoqDQoNCi0gICBUaGUgbWVhc3VyZW1lbnQgZXJyb3JzIGFyZSB1bmNvcnJlbGF0ZWQgd2l0aCB0aGUgbGF0ZW50IHZhcmlhYmxlczoNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIEUoXGJvbGRzeW1ib2x7XGRlbHRhfXxcYm9sZHN5bWJvbHtceGl9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIEUoXGJvbGRzeW1ib2x7XGVwc2lsb259fFxib2xkc3ltYm9se1xldGF9KSA9IFxtYXRoYmZ7MH0NCiAgICBcZW5ke2FsaWduKn0NCiQkDQoNCi0gICBUaGUgc3RydWN0dXJhbCBkaXN0dXJiYW5jZXMgaGF2ZSB6ZXJvIG1lYW4gYW5kIGFyZSB1bmNvcnJlbGF0ZWQgd2l0aCB0aGUgZXhvZ2Vub3VzIHZhcmlhYmxlczoNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIEUoXGJvbGRzeW1ib2x7XHpldGF9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHpldGF9LCBcYm9sZHN5bWJvbHtceGl9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHpldGF9LCBcbWF0aGJme3d9KSA9IFxtYXRoYmZ7MH0NCiAgICBcZW5ke2FsaWduKn0NCiQkDQoNCi0gICBUaGUgbWVhc3VyZW1lbnQgZXJyb3JzIGFuZCBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSwgXHF1YWQgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9LCBcYm9sZHN5bWJvbHtcemV0YX0pID0gXG1hdGhiZnswfSwgXHF1YWQgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0sIFxib2xkc3ltYm9se1x6ZXRhfSkgPSBcbWF0aGJmezB9DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgVGhlIG1lYXN1cmVtZW50IGVycm9ycyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9KSA9IFxib2xkc3ltYm9se1xUaGV0YX1fe1xkZWx0YX0gPSBcdGV4dHtkaWFnfShcdGhldGFfe1xkZWx0YSwxfSwgXGRvdHMsIFx0aGV0YV97XGRlbHRhLDd9KQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxib2xkc3ltYm9se1xUaGV0YX1fe1xlcHNpbG9ufSA9IFx0ZXh0e2RpYWd9KFx0aGV0YV97XGVwc2lsb24sMX0sIFxkb3RzLCBcdGhldGFfe1xlcHNpbG9uLDl9KQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KLSAgIFRoZSBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcemV0YX0pID0gXGJvbGRzeW1ib2x7XFBzaX0gPSANCiAgICBcYmVnaW57Ym1hdHJpeH0NCiAgICBccHNpX3sxMX0gJiBccHNpX3sxMn0gXFwNCiAgICBccHNpX3syMX0gJiBccHNpX3syMn0NCiAgICBcZW5ke2JtYXRyaXh9DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgVGhlIGV4b2dlbm91cyBsYXRlbnQgdmFyaWFibGVzIGhhdmUgY292YXJpYW5jZSBtYXRyaXg6DQoNCiQkDQogICAgXGJlZ2lue2FsaWduKn0NCiAgICBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x4aX0pID0gXGJvbGRzeW1ib2x7XFBoaX0gPSANCiAgICBcYmVnaW57Ym1hdHJpeH0NCiAgICBccGhpX3sxMX0gJiBccGhpX3sxMn0gXFwNCiAgICBccGhpX3syMX0gJiBccGhpX3syMn0NCiAgICBcZW5ke2JtYXRyaXh9DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgVGhlIGV4b2dlbm91cyBvYnNlcnZlZCB2YXJpYWJsZXMgaGF2ZSBjb3ZhcmlhbmNlIG1hdHJpeDoNCg0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXG1hdGhiZnt3fSkgPSBcYm9sZHN5bWJvbHtcUGhpfV93DQogICAgXGVuZHthbGlnbip9DQokJA0KDQotICAgQWxsIHZhcmlhYmxlcyBhcmUgbXVsdGl2YXJpYXRlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KDQoqKjUuIEltcGxpZWQgQ292YXJpYW5jZSBNYXRyaXgqKg0KDQpMZXQgJFxib2xkc3ltYm9se1x0aGV0YX0kIHJlcHJlc2VudCBhbGwgbW9kZWwgcGFyYW1ldGVycy4gVGhlIGltcGxpZWQgY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIG9ic2VydmVkIHZhcmlhYmxlcyAkXG1hdGhiZnt6fSA9IChcbWF0aGJme3h9XlQsIFxtYXRoYmZ7eX1eVCwgXG1hdGhiZnt3fV5UKV5UJCBpczoNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pID0gDQpcYmVnaW57Ym1hdHJpeH0NClxib2xkc3ltYm9se1xTaWdtYX1fe3h4fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3h5fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3h3fShcYm9sZHN5bWJvbHtcdGhldGF9KSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eXh9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97eXl9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97eXd9KFxib2xkc3ltYm9se1x0aGV0YX0pIFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t3eH0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t3eX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t3d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkNClxlbmR7Ym1hdHJpeH0NClxlbmR7YWxpZ24qfQ0KJCQNCg0Kd2hlcmU6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eHh9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXGJvbGRzeW1ib2x7XFBoaX0gXGJvbGRzeW1ib2x7XExhbWJkYX1feF5UICsgXGJvbGRzeW1ib2x7XFRoZXRhfV97XGRlbHRhfSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eXl9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3kgKFxtYXRoYmZ7SX0tXG1hdGhiZntCfSleey0xfSAoXGJvbGRzeW1ib2x7XEdhbW1hfSBcYm9sZHN5bWJvbHtcUGhpfSBcYm9sZHN5bWJvbHtcR2FtbWF9XlQgKyBcYm9sZHN5bWJvbHtcR2FtbWF9X3cgXGJvbGRzeW1ib2x7XFBoaX1fdyBcYm9sZHN5bWJvbHtcR2FtbWF9X3deVCArIFxib2xkc3ltYm9se1xQc2l9KSBbKFxtYXRoYmZ7SX0tXG1hdGhiZntCfSleey0xfV1eVCBcYm9sZHN5bWJvbHtcTGFtYmRhfV95XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0gXFwNClxib2xkc3ltYm9se1xTaWdtYX1fe3d3fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcYm9sZHN5bWJvbHtcUGhpfV93IFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t4eX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XExhbWJkYX1feCBcYm9sZHN5bWJvbHtcUGhpfSBcYm9sZHN5bWJvbHtcR2FtbWF9XlQgWyhcbWF0aGJme0l9LVxtYXRoYmZ7Qn0pXnstMX1dXlQgXGJvbGRzeW1ib2x7XExhbWJkYX1feV5UIFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t4d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XExhbWJkYX1feCBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x4aX0sIFxtYXRoYmZ7d30pIFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t5d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XExhbWJkYX1feSAoXG1hdGhiZntJfS1cbWF0aGJme0J9KV57LTF9IChcYm9sZHN5bWJvbHtcR2FtbWF9IFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHhpfSwgXG1hdGhiZnt3fSkgKyBcYm9sZHN5bWJvbHtcR2FtbWF9X3cgXGJvbGRzeW1ib2x7XFBoaX1fdykNClxlbmR7YWxpZ24qfQ0KJCQNCg0KKio2LiBMaWtlbGlob29kIEZ1bmN0aW9uKioNCg0KQXNzdW1pbmcgbXVsdGl2YXJpYXRlIG5vcm1hbGl0eSBvZiB0aGUgb2JzZXJ2ZWQgdmFyaWFibGVzICRcbWF0aGJme3p9IFxzaW0gTihcYm9sZHN5bWJvbHtcbXV9LCBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pKSQsIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uIGZvciBhIHNhbXBsZSBvZiAkbiQgaW5kZXBlbmRlbnQgb2JzZXJ2YXRpb25zIGlzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NCkwoXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXHByb2Rfe2k9MX1ebiAoMlxwaSleey1wLzJ9IHxcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfF57LTEvMn0gXGV4cFxsZWZ0Wy1cZnJhY3sxfXsyfShcbWF0aGJme3p9X2kgLSBcYm9sZHN5bWJvbHtcbXV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt6fV9pIC0gXGJvbGRzeW1ib2x7XG11fSlccmlnaHRdDQpcZW5ke2FsaWduKn0NCiQkDQoNCndoZXJlICRwID0gNyArIDkgKyA1ID0gMjEkIGlzIHRoZSB0b3RhbCBudW1iZXIgb2Ygb2JzZXJ2ZWQgdmFyaWFibGVzLg0KDQpUaGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24gaXM6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGVsbChcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSAtXGZyYWN7bnB9ezJ9IFxsb2coMlxwaSkgLSBcZnJhY3tufXsyfSBcbG9nfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8IFxcDQomXHF1YWQgLSBcZnJhY3sxfXsyfSBcc3VtX3tpPTF9Xm4gKFxtYXRoYmZ7en1faSAtIFxib2xkc3ltYm9se1xtdX0pXlQgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9IChcbWF0aGJme3p9X2kgLSBcYm9sZHN5bWJvbHtcbXV9KQ0KXGVuZHthbGlnbip9DQokJA0KDQpGb3IgZXN0aW1hdGlvbiwgd2UgdHlwaWNhbGx5IHVzZSB0aGUgZGlzY3JlcGFuY3kgZnVuY3Rpb246DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KRl97TUx9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxsb2d8XGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KXwgKyBcdGV4dHt0cn0oXG1hdGhiZntTfSBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pXnstMX0pIC0gXGxvZ3xcbWF0aGJme1N9fCAtIHANClxlbmR7YWxpZ24qfQ0KJCQNCg0Kd2hlcmUgJFxtYXRoYmZ7U30kIGlzIHRoZSBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXguDQoNCioqNy4gUGFyYW1ldGVycyB0byBFc3RpbWF0ZSoqDQoNClRoZSBtb2RlbCBwYXJhbWV0ZXJzIGluY2x1ZGU6DQoNCi0gICBGYWN0b3IgbG9hZGluZ3M6ICRcbGFtYmRhX3tpan0kIGluICRcYm9sZHN5bWJvbHtcTGFtYmRhfV94JCBhbmQgJFxib2xkc3ltYm9se1xMYW1iZGF9X3kkDQotICAgU3RydWN0dXJhbCBjb2VmZmljaWVudHM6ICRcYmV0YV97aWp9JCBpbiAkXG1hdGhiZntCfSQsICRcZ2FtbWFfe2lqfSQgaW4gJFxib2xkc3ltYm9se1xHYW1tYX0kLCAkXGdhbW1hX3tpan1edyQgaW4gJFxib2xkc3ltYm9se1xHYW1tYX1fdyQNCi0gICBWYXJpYW5jZXMgYW5kIGNvdmFyaWFuY2VzOiAkXHBoaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBoaX0kLCAkXHBzaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBzaX0kLCAkXHBoaV97dyxpan0kIGluICRcYm9sZHN5bWJvbHtcUGhpfV93JA0KLSAgIE1lYXN1cmVtZW50IGVycm9yIHZhcmlhbmNlczogJFx0aGV0YV97XGRlbHRhLGl9JCBpbiAkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGRlbHRhfSQsICRcdGhldGFfe1xlcHNpbG9uLGl9JCBpbiAkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259JA0KDQpUeXBpY2FsbHksIHdlIHNldCBvbmUgbG9hZGluZyBwZXIgbGF0ZW50IHZhcmlhYmxlIHRvIDEgZm9yIGlkZW50aWZpY2F0aW9uLg0KDQoqKjguIE1vZGVsIElkZW50aWZpY2F0aW9uKioNCg0KVGhlIG1vZGVsIGlzIGlkZW50aWZpZWQgaWY6DQoNCi0gICBFYWNoIGxhdGVudCB2YXJpYWJsZSBoYXMgYXQgbGVhc3QgMyBpbmRpY2F0b3JzIChzYXRpc2ZpZWQpDQotICAgVGhlIHNjYWxlIG9mIGVhY2ggbGF0ZW50IHZhcmlhYmxlIGlzIHNldCBieSBmaXhpbmcgb25lIGxvYWRpbmcgdG8gMQ0KLSAgIFRoZSBtb2RlbCBtZWV0cyB0aGUgb3JkZXIgY29uZGl0aW9uIGFuZCByYW5rIGNvbmRpdGlvbiBmb3IgaWRlbnRpZmljYXRpb24NCg0KDQojIyBXTFNNViBmb3IgTGlrZXJ0IERhdGEgaW4gU0VNDQoNCg0KVGhlIFdlaWdodGVkIExlYXN0IFNxdWFyZXMgTWVhbiBhbmQgVmFyaWFuY2UgQWRqdXN0ZWQgKFdMU01WKSBlc3RpbWF0b3IgaXMgYSByb2J1c3QgZXN0aW1hdGlvbiBtZXRob2QgZGVzaWduZWQgc3BlY2lmaWNhbGx5IGZvciBzdHJ1Y3R1cmFsIGVxdWF0aW9uIG1vZGVsaW5nIChTRU0pIHdpdGggY2F0ZWdvcmljYWwgb3Igb3JkaW5hbCBkYXRhLCBwYXJ0aWN1bGFybHkgbXVsdGktaXRlbSBMaWtlcnQgc2NhbGVzLiBXaGVuIHdvcmtpbmcgd2l0aCBvcmRlcmVkIGNhdGVnb3JpY2FsIGluZGljYXRvcnMgKGUuZy4sIExpa2VydC10eXBlIGl0ZW1zIHdpdGggMi03IHJlc3BvbnNlIGNhdGVnb3JpZXMpLCB0cmFkaXRpb25hbCBtYXhpbXVtIGxpa2VsaWhvb2QgKE1MKSBlc3RpbWF0aW9uIGFzc3VtZXMgY29udGludW91cyBub3JtYWxseSBkaXN0cmlidXRlZCB2YXJpYWJsZXMsIHdoaWNoIHZpb2xhdGVzIHRoZSBkaXNjcmV0ZSBuYXR1cmUgb2Ygb3JkaW5hbCBkYXRhLg0KDQojIyMgTWF0aGVtYXRpY2FsIEZvdW5kYXRpb24NCg0KTGV0ICRcbWF0aGJme3h9XiokIHJlcHJlc2VudCB0aGUgbGF0ZW50IGNvbnRpbnVvdXMgdmFyaWFibGVzIHVuZGVybHlpbmcgdGhlIG9ic2VydmVkIG9yZGluYWwgcmVzcG9uc2VzICRcbWF0aGJme3h9JC4gVGhlIG1lYXN1cmVtZW50IG1vZGVsIGNhbiBiZSBleHByZXNzZWQgYXM6DQoNCiQkDQpcbWF0aGJme3h9XiogPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcYm9sZHN5bWJvbHtceGl9ICsgXGJvbGRzeW1ib2x7XGRlbHRhfQ0KJCQNCg0Kd2hlcmUgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyB0aGUgZmFjdG9yIGxvYWRpbmcgbWF0cml4LCAkXGJvbGRzeW1ib2x7XHhpfSQgcmVwcmVzZW50cyBsYXRlbnQgdmFyaWFibGVzLCBhbmQgJFxib2xkc3ltYm9se1xkZWx0YX0kIGRlbm90ZXMgbWVhc3VyZW1lbnQgZXJyb3JzLg0KDQpUaGUgV0xTTVYgZXN0aW1hdG9yIG1pbmltaXplcyB0aGUgZGlzY3JlcGFuY3kgZnVuY3Rpb246DQoNCiQkDQpGX3tXTFNNVn0gPSAoXG1hdGhiZntzfSAtIFxib2xkc3ltYm9se1xzaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkpJyBcbWF0aGJme1d9XnstMX0gKFxtYXRoYmZ7c30gLSBcYm9sZHN5bWJvbHtcc2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pKQ0KJCQNCg0KKiAkXG1hdGhiZntzfSQgaXMgdGhlIHZlY3RvciBvZiBzYW1wbGUgcG9seWNob3JpYyBjb3JyZWxhdGlvbnMgYW5kIHRocmVzaG9sZCBlc3RpbWF0ZXMNCiogJFxib2xkc3ltYm9se1xzaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGNvbnRhaW5zIHRoZSBtb2RlbC1pbXBsaWVkIGNvcnJlbGF0aW9ucyBhbmQgdGhyZXNob2xkcw0KKiAkXG1hdGhiZntXfSQgaXMgdGhlIGNvbnNpc3RlbnQgYXN5bXB0b3RpYyBjb3ZhcmlhbmNlIG1hdHJpeCBvZiAkXG1hdGhiZntzfSQNCg0KDQoqKktleSBGZWF0dXJlcyBmb3IgTXVsdGktaXRlbSBMaWtlcnQgRGF0YSoqDQoNCiogKipQb2x5Y2hvcmljIENvcnJlbGF0aW9ucyoqOiBXTFNNViB1dGlsaXplcyBwb2x5Y2hvcmljIGNvcnJlbGF0aW9ucyB0aGF0IGVzdGltYXRlIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdW5kZXJseWluZyBjb250aW51b3VzIHZhcmlhYmxlcywgcHJvdmlkaW5nIG1vcmUgYWNjdXJhdGUgZXN0aW1hdGVzIHRoYW4gUGVhcnNvbiBjb3JyZWxhdGlvbnMgZm9yIG9yZGluYWwgZGF0YS4NCiogKipUaHJlc2hvbGQgRXN0aW1hdGlvbioqOiBUaGUgbWV0aG9kIGVzdGltYXRlcyB0aHJlc2hvbGRzICRcYm9sZHN5bWJvbHtcdGF1fSQgdGhhdCBkZWZpbmUgdGhlIGJvdW5kYXJpZXMgYmV0d2VlbiByZXNwb25zZSBjYXRlZ29yaWVzOg0KDQokJA0KeF9pID0gayBccXVhZCBcdGV4dHtpZn0gXHF1YWQgXHRhdV97ay0xfSA8IHhfaV4qIFxsZXEgXHRhdV9rDQokJA0KDQoqICoqRGlhZ29uYWwgV2VpZ2h0IE1hdHJpeCoqOiBXTFNNViBlbXBsb3lzIGEgZGlhZ29uYWwgd2VpZ2h0IG1hdHJpeCBjb250YWluaW5nIGFzeW1wdG90aWMgdmFyaWFuY2VzIG9mIHBvbHljaG9yaWMgY29ycmVsYXRpb25zLCBtYWtpbmcgaXQgY29tcHV0YXRpb25hbGx5IGVmZmljaWVudCB3aGlsZSBtYWludGFpbmluZyByb2J1c3RuZXNzLg0KDQoqICoqTWVhbiBhbmQgVmFyaWFuY2UgQWRqdXN0bWVudCoqOiBUaGUgZXN0aW1hdG9yIGluY29ycG9yYXRlcyBzY2FsaW5nIGNvcnJlY3Rpb25zIHRvIHRoZSB0ZXN0IHN0YXRpc3RpY3MsIHByb3ZpZGluZyBiZXR0ZXIgYXBwcm94aW1hdGlvbiB0byAkXGNoaV4yJCBkaXN0cmlidXRpb25zIHdpdGggc21hbGwgdG8gbW9kZXJhdGUgc2FtcGxlIHNpemVzLg0KDQoNCg0KKipJbnRyb2R1Y3Rpb24gdG8gdGhlIEVzdGltYXRvcioqDQoNClRoZSBXZWlnaHRlZCBMZWFzdCBTcXVhcmVzIE1lYW4gYW5kIFZhcmlhbmNlIGFkanVzdGVkIChXTFNNVikgZXN0aW1hdG9yIGlzIGEgcm9idXN0IGVzdGltYXRpb24gbWV0aG9kIGRldmVsb3BlZCBmb3Igc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZyAoU0VNKSB3aXRoIGNhdGVnb3JpY2FsLCBhbmQgaW4gcGFydGljdWxhciwgb3JkaW5hbCBvYnNlcnZlZCB2YXJpYWJsZXMuIEl0IGlzIHRoZSByZWNvbW1lbmRlZCBlc3RpbWF0b3IgZm9yIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKENGQSkgYW5kIFNFTSB3aGVuIHRoZSBpbmRpY2F0b3JzIGFyZSBtZWFzdXJlZCBvbiBhbiBvcmRpbmFsIHNjYWxlLCBzdWNoIGFzIG11bHRpLWl0ZW0gTGlrZXJ0IHNjYWxlcyBjb21tb24gaW4gc29jaWFsIGFuZCBiZWhhdmlvcmFsIHNjaWVuY2VzIChCcm93biwgMjAxNSwgRmxvcmEsIDIwMjIpLg0KDQpUaGUgbmVlZCBmb3IgV0xTTVYgYXJpc2VzIGZyb20gdGhlIHZpb2xhdGlvbiBvZiBhc3N1bXB0aW9ucyB1bmRlcmx5aW5nIG1heGltdW0gbGlrZWxpaG9vZCAoTUwpIGVzdGltYXRpb24gd2hlbiBvYnNlcnZlZCB2YXJpYWJsZXMgYXJlIG9yZGluYWwuIE1MIGFzc3VtZXMgY29udGludW91cywgbXVsdGl2YXJpYXRlIG5vcm1hbCBkYXRhLiBMaWtlcnQtc2NhbGUgaXRlbXMgYXJlIGRpc2NyZXRlLCBoYXZlIGxpbWl0ZWQgc2NhbGUgcG9pbnRzLCBhbmQgdGhlaXIgZGlzdHJpYnV0aW9ucyBhcmUgb2Z0ZW4gbm9uLW5vcm1hbCwgbGVhZGluZyB0bzoNCg0KKiBJbmZsYXRlZCBDaGktc3F1YXJlICgkXGNoaV4yJCkgdGVzdCBzdGF0aXN0aWNzLg0KKiBCaWFzZWQgc3RhbmRhcmQgZXJyb3JzLg0KKiBJbmNvcnJlY3QgbW9kZWwgZml0IGluZGljZXMgXGNpdGVwe0Zpbm5leTIwMDF9Lg0KDQoNCiMjIyBDb21wdXRhdGlvbmFsIFByb2NlZHVyZQ0KDQpUaGUgV0xTTVYgZXN0aW1hdG9yIGlzIHBhcnQgb2YgYSBmYW1pbHkgb2YgZGlhZ29uYWxseSB3ZWlnaHRlZCBsZWFzdCBzcXVhcmVzIChEV0xTKSBlc3RpbWF0b3JzLiBJdHMgY29tcHV0YXRpb24gaW52b2x2ZXMgYSBzcGVjaWZpYyBzZXF1ZW5jZSBvZiBzdGVwcyB0byBoYW5kbGUgdGhlIGNhdGVnb3JpY2FsIG5hdHVyZSBvZiB0aGUgZGF0YS4NCg0KKipTdGVwIDE6IEVzdGltYXRpb24gb2YgUG9seWNob3JpYyBDb3JyZWxhdGlvbnMqKg0KDQpTaW5jZSB0aGUgb3JkaW5hbCBjYXRlZ29yaWVzIGFyZSBtYW5pZmVzdGF0aW9ucyBvZiBhbiBhc3N1bWVkIGNvbnRpbnVvdXMsIGxhdGVudCByZXNwb25zZSBkaXN0cmlidXRpb24gdW5kZXJseWluZyBlYWNoIGl0ZW0sIHRoZSBmaXJzdCBzdGVwIGludm9sdmVzIGVzdGltYXRpbmcgdGhlICoqcG9seWNob3JpYyBjb3JyZWxhdGlvbioqIG1hdHJpeC4gQSBwb2x5Y2hvcmljIGNvcnJlbGF0aW9uIGVzdGltYXRlcyB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBhc3N1bWVkIGNvbnRpbnVvdXMgbGF0ZW50IHJlc3BvbnNlIHZhcmlhYmxlcyBiYXNlZCBvbiB0aGUgb2JzZXJ2ZWQgb3JkaW5hbCBkYXRhIChPbHNzb24sIDE5NzkpLiBGb3IgZWFjaCBwYWlyIG9mIGl0ZW1zLCBhIHR3by1zdGVwIHRocmVzaG9sZCBlc3RpbWF0aW9uIGlzIHBlcmZvcm1lZCwgZm9sbG93ZWQgYnkgdGhlIGVzdGltYXRpb24gb2YgdGhlaXIgY29ycmVsYXRpb24uDQoNCioqU3RlcCAyOiBFc3RpbWF0aW9uIG9mIHRoZSBBc3ltcHRvdGljIENvdmFyaWFuY2UgTWF0cml4KioNCg0KVGhlIG5leHQgc3RlcCBpcyB0byBjb21wdXRlIHRoZSBmdWxsICoqYXN5bXB0b3RpYyBjb3ZhcmlhbmNlIG1hdHJpeCoqIG9mIHRoZSAqcG9seWNob3JpYyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMqLiBUaGlzIG1hdHJpeCBjb250YWlucyB0aGUgdmFyaWFuY2VzIGFuZCBjb3ZhcmlhbmNlcyBvZiB0aGUgZXN0aW1hdGVkICpwb2x5Y2hvcmljIGNvcnJlbGF0aW9ucyouIEl0IGlzIGEgbGFyZ2UgbWF0cml4IG9mIGRpbWVuc2lvbiAkcF4qKHBeKi0xKS8yJCAod2hlcmUgJHAkIGlzIHRoZSBudW1iZXIgb2YgaXRlbXMpIGFuZCBhY2NvdW50cyBmb3IgdGhlIHByZWNpc2lvbiBvZiBlYWNoIGNvcnJlbGF0aW9uIGVzdGltYXRlLiBUaGlzIG1hdHJpeCBpcyB1c2VkIGFzIHRoZSB3ZWlnaHQgbWF0cml4IGluIHRoZSBmaXR0aW5nIGZ1bmN0aW9uIChNdXRoZW4sIDE5ODQpLg0KDQoqKlN0ZXAgMzogVGhlIEZpdHRpbmcgRnVuY3Rpb24gYW5kIE1lYW4tVmFyaWFuY2UgQWRqdXN0bWVudCoqDQoNClRoZSBwYXJhbWV0ZXIgZXN0aW1hdGVzIGFyZSBvYnRhaW5lZCBieSBtaW5pbWl6aW5nIHRoZSBEV0xTIGZpdHRpbmcgZnVuY3Rpb246DQoNCiQkDQpGX3tcdGV4dHtEV0xTfX0gPSAoXG1hdGhiZntzfSAtIFxib2xkc3ltYm9se1xzaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkpJyBcbWF0aGJme1d9XnstMX0gKFxtYXRoYmZ7c30gLSBcYm9sZHN5bWJvbHtcc2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pKQ0KJCQNCg0Kd2hlcmUgJFxtYXRoYmZ7c30kIGlzIHRoZSB2ZWN0b3Igb2YgZXN0aW1hdGVkIHBvbHljaG9yaWMgY29ycmVsYXRpb25zLCAkXGJvbGRzeW1ib2x7XHNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgdGhlIHZlY3RvciBvZiBtb2RlbC1pbXBsaWVkIGNvcnJlbGF0aW9ucywgYW5kICRcbWF0aGJme1d9XnstMX0kIGlzIHRoZSAqKmRpYWdvbmFsKiogb2YgdGhlIGludmVyc2Ugb2YgdGhlIGFzeW1wdG90aWMgY292YXJpYW5jZSBtYXRyaXggZnJvbSBTdGVwIDIuIFVzaW5nIG9ubHkgdGhlIGRpYWdvbmFsIG1ha2VzIHRoZSBjb21wdXRhdGlvbiBtb3JlIHN0YWJsZSBhbmQgZmVhc2libGUgd2l0aCBzbWFsbGVyIHNhbXBsZSBzaXplcyBjb21wYXJlZCB0byB0aGUgZnVsbCBXTFMgZXN0aW1hdG9yIHdoaWNoIHVzZXMgdGhlIGZ1bGwgbWF0cml4Lg0KDQpUaGUgIk1lYW4gYW5kIFZhcmlhbmNlIiBhZGp1c3RtZW50IChNVikgaXMgdGhlIGNydWNpYWwgZmluYWwgc3RlcCB0aGF0IG1ha2VzIFdMU01WIHN1cGVyaW9yIHRvIHBsYWluIFdMUyBvciBEV0xTLiBJbnN0ZWFkIG9mIHVzaW5nIHRoZSAkXGNoaV4yJCBzdGF0aXN0aWMgYW5kIHN0YW5kYXJkIGVycm9ycyBkZXJpdmVkIGRpcmVjdGx5IGZyb20gdGhlIERXTFMgZml0dGluZyBmdW5jdGlvbiwgV0xTTVYgYXBwbGllcyBhIGNvcnJlY3Rpb246DQoNCiogVGhlIHRlc3Qgc3RhdGlzdGljIGlzIHNjYWxlZCAobWVhbi1hZGp1c3RlZCkgYW5kIHNoaWZ0ZWQgKHZhcmlhbmNlLWFkanVzdGVkKSB0byBtb3JlIGNsb3NlbHkgYXBwcm94aW1hdGUgYSBjZW50cmFsICRcY2hpXjIkIGRpc3RyaWJ1dGlvbi4NCiogU3RhbmRhcmQgZXJyb3JzIGZvciBwYXJhbWV0ZXIgZXN0aW1hdGVzIGFyZSBjb21wdXRlZCB1c2luZyBhIHJvYnVzdCBtZXRob2QgKGUuZy4sIHRoZSBzYW5kd2ljaCBlc3RpbWF0b3IpIHRoYXQgZG9lcyBub3QgcmVseSBvbiB0aGUgYXNzdW1wdGlvbiBvZiBjb3JyZWN0IG1vZGVsIHNwZWNpZmljYXRpb24gKEFzcGFyb3Vob3YsIDIwMDUpLg0KDQoNClRoaXMgYWRqdXN0bWVudCBtYWtlcyB0aGUgV0xTTVYgZXN0aW1hdG9yIGZhciBtb3JlIHJvYnVzdCBpbiBzbWFsbCB0byBtb2RlcmF0ZSBzYW1wbGUgc2l6ZXMgYW5kIHdpdGggbGFyZ2UgbW9kZWxzIHdoZXJlIHRoZSBhc3ltcHRvdGljIGFzc3VtcHRpb25zIG9mIHBsYWluIFdMUyBhcmUgbm90IG1ldC4NCg0KIyMjIEFkdmFudGFnZXMgZm9yIE11bHRpLUl0ZW0gTGlrZXJ0IERhdGENCg0KVGhlIFdMU01WIGVzdGltYXRvciBwcm92aWRlcyBzcGVjaWZpYyBhZHZhbnRhZ2VzIGZvciBtb2RlbGluZyBtdWx0aS1pdGVtIExpa2VydCBzY2FsZSBkYXRhOg0KDQoqICoqUmVhbGlzdGljIEFzc3VtcHRpb25zKio6IEl0IGRvZXMgbm90IGFzc3VtZSBjb250aW51b3VzIG5vcm1hbGl0eSBmb3IgdGhlIG9ic2VydmVkIExpa2VydCBpdGVtcywgaW5zdGVhZCBsZXZlcmFnaW5nIHRoZSB1bmRlcmx5aW5nIGNvbnRpbnVvdXMgdmFyaWFibGUgZm9ybXVsYXRpb24uDQoqICoqQWNjdXJhY3kqKjogSXQgZ2VuZXJhbGx5IHByb2R1Y2VzIHRoZSBtb3N0IGFjY3VyYXRlIHBhcmFtZXRlciBlc3RpbWF0ZXMsIG1vZGVsIGZpdCBzdGF0aXN0aWNzLCBhbmQgc3RhbmRhcmQgZXJyb3JzIGZvciBvcmRpbmFsIGRhdGEgY29tcGFyZWQgdG8gTUwgd2l0aCBhIHJvYnVzdCBjb3JyZWN0aW9uIG9yIHBsYWluIERXTFMgKExpLCAyMDE2KS4NCiogKipFZmZpY2llbmN5IHdpdGggQ29tbW9uIFNjYWxlcyoqOiBJdCBwZXJmb3JtcyB3ZWxsIHdpdGggdGhlIHR5cGljYWwgNS0gdG8gNy1wb2ludCBMaWtlcnQgc2NhbGVzIHViaXF1aXRvdXMgaW4gcHN5Y2hvbG9naWNhbCBhbmQgc3VydmV5IHJlc2VhcmNoLg0KKiAqKlJvYnVzdG5lc3MgdG8gU2FtcGxlIFNpemUqKjogV2hpbGUgbGFyZ2VyIHNhbXBsZXMgYXJlIGFsd2F5cyBwcmVmZXJhYmxlLCBXTFNNViBwZXJmb3JtcyBhZGVxdWF0ZWx5IHdpdGggc21hbGxlciBzYW1wbGVzIChlLmcuLCAkTiA+IDIwMCQpIHRoYW4gd2hhdCBpcyByZXF1aXJlZCBmb3IgdGhlIGZ1bGwgV0xTIGVzdGltYXRvciAoQmFuZGFsb3MsIDIwMTQpLg0KDQoNCkluIGNvbmNsdXNpb24sIFdMU01WIGlzIGEgcm9idXN0LCBkaWFnb25hbGx5IHdlaWdodGVkIGxlYXN0IHNxdWFyZXMgZXN0aW1hdG9yIHRoYXQgdXNlcyBhIHBvbHljaG9yaWMgY29ycmVsYXRpb24gbWF0cml4IGFuZCBhcHBsaWVzIGEgbWVhbi0gYW5kIHZhcmlhbmNlLWFkanVzdG1lbnQgdG8gdGhlIHRlc3Qgc3RhdGlzdGljcyBhbmQgc3RhbmRhcmQgZXJyb3JzLCBtYWtpbmcgaXQgdGhlIGdvbGQtc3RhbmRhcmQgY2hvaWNlIGZvciBTRU0gd2l0aCBvcmRpbmFsIG11bHRpLWl0ZW0gTGlrZXJ0IGRhdGEuDQoNCg0KIyMgU3VydmV5IEluc3RydW1lbnRzDQoNCiMjIyBBYmJyZXZpYXRlZCBNYXRoIEFueGlldHkgU2NhbGUgKEFNQVMpDQoNClBsZWFzZSByYXRlIHlvdXIgZmVlbGluZ3MgZHVyaW5nIGRpZmZlcmVudCBhY3Rpdml0aWVzIG9uIGEgc2NhbGUgZnJvbSAxIHRvIDUuIFRyeSBub3QgdG8gc3BlbmQgdG9vIG11Y2ggdGltZSBvbiBhbnkgb25lIGl0ZW0uIFRoZXJlIGFyZSBubyByaWdodCBvciB3cm9uZyBhbnN3ZXJzLg0KDQpgMSA9IE5vIGJhZCBmZWVsaW5ncywgIDIgPSBTb21ld2hhdCBiYWQsICAzID0gbmVydm91cywgNCA9IFZlcnkgYmFkIGZlZWxpbmdzLCA1ID0gV29yc3QgZmVlbGluZ3NgDQoNClwNCg0KMS4JSGF2aW5nIHRvIHVzZSB0YWJsZXMgaW4gdGhlIGJhY2sgb2YgYSBtYXRoIGJvb2suDQoNCjIuCVRoaW5raW5nIGFib3V0IGEgbWF0aCB0ZXN0IHRoZSBkYXkgYmVmb3JlIHlvdSB0YWtlIGl0Lg0KDQozLglXYXRjaGluZyB0aGUgdGVhY2hlciB3b3JrIG91dCBhIG1hdGggcHJvYmxlbSBvbiB0aGUgYm9hcmQuDQoNCjQuCVRha2luZyBhIG1hdGggdGVzdC4NCg0KNS4JQmVpbmcgZ2l2ZW4gYSBob21ld29yayBhc3NpZ25tZW50IG9mIG1hbnkgZGlmZmljdWx0IHByb2JsZW1zIHRoYXQgaXMgZHVlIGZvciB0aGUgbmV4dCBjbGFzcyBtZWV0aW5nLiANCg0KNi4JTGlzdGVuaW5nIHRvIGEgbGVjdHVyZSBpbiBtYXRoIGNsYXNzLiBbTGlzdGVuaW5nIHRvIHRoZSB0ZWFjaGVyIHRhbGsgZm9yIGEgbG9uZyB0aW1lIGluIG1hdGhdIA0KDQo3LglMaXN0ZW5pbmcgdG8gYW5vdGhlciBzdHVkZW50IGV4cGxhaW4gaG93IHRvIGRvIGEgbWF0aCBwcm9ibGVtLiANCg0KOC4JQmVpbmcgZ2l2ZW4gYSBxdWl6IG9uIG1hdGggd2l0aG91dCBrbm93aW5nIGluIGFkdmFuY2UuIA0KDQo5LglTdGFydGluZyBhIG5ldyBjaGFwdGVyIGluIGEgbWF0aCBib29rLiBbU3RhcnRpbmcgYSBuZXcgdG9waWMgaW4gbWF0aF0NCg0KIyMjIE1hdGggU2VsZi1lZmZpY2FjeSBTY2FsZQ0KDQpTZWxlY3QgdGhlIHJlc3BvbnNlIHRoYXQgbWF0Y2hlcyBob3cgbXVjaCB5b3Ugbm93IGFncmVlIHdpdGggZWFjaCBzdGF0ZW1lbnQuIFRyeSBub3QgdG8gc3BlbmQgdG9vIG11Y2ggdGltZSBvbiBhbnkgb25lIGl0ZW0uIFRoZXJlIGFyZSBubyByaWdodCBvciB3cm9uZyBhbnN3ZXJzLg0KDQpgMSA9IFN0cm9uZ2x5IGRpc2FncmVlCTIgPSBkaXNhZ3JlZQkzID0gbmV1dHJhbAk0ID0gYWdyZWUJNSA9IFN0cm9uZ2x5IGFncmVlYA0KDQpcDQoNCjEuCUkgdXN1YWxseSB1bmRlcnN0YW5kIGEgbWF0aGVtYXRpY2FsIGlkZWEgcXVpY2tseS4NCg0KMi4JSSBoYXZlIHRvIHdvcmsgdmVyeSBoYXJkIHRvIHVuZGVyc3RhbmQgbWF0aGVtYXRpY3MuICAgIA0KDQozLglJIGNhbiBjb25uZWN0IHRoZSBtYXRoZW1hdGljYWwgaWRlYXMgdGhhdCBJIGhhdmUgbGVhcm5lZC4NCg0KDQojIyMgVGVhY2hpbmcgU3RyYXRlZ2llcyBRdWVzdGlvbm5haXJlIA0KDQpUaGUgZm9sbG93aW5nIHN0YXRlbWVudHMgYXJlIHRoZSB3YXlzIHlvdXIgdGVhY2hlciB0ZWFjaGVzIG1hdGhlbWF0aWNzLiBSZXNwb25kIHRvIHRoZSBpdGVtcyBsaXN0ZWQgYmVsb3c6IA0KDQpgNSDigJMgQWx3YXlzLCA0IOKAkyBPZnRlbiwgIDMg4oCTIFNvbWV0aW1lcywgIDIg4oCTIFNlbGRvbSwgICAxIOKAkyBOZXZlcmANCg0KDQoqKkNvb3BlcmF0aXZlLUFwcHJvYWNoKioNCg0KMS4JVGhlIHRlYWNoZXIgZW5jb3VyYWdlcyBzdHVkZW50cyB0byB3b3JrIHdpdGggb3RoZXJzIHRvIGdlbmVyYXRlIGFzIG1hbnkgYWx0ZXJuYXRpdmVzIGFzIHRoZXkgY2FuIGZvciB0aGUgcHJvYmxlbSBkaXNjdXNzZWQuIA0KDQoyLglUaGUgdGVhY2hlciBnaXZlcyBzdHVkZW50cyBlbm91Z2ggdGltZSB0byB0aGluayBhbmQgdG8gaW52ZXN0aWdhdGUgd2l0aCBvdGhlcnMgdG8gYWNoaWV2ZSBhIGRlc2lyYWJsZSByZXN1bHQuDQoNCjMuCVRoZSB0ZWFjaGVyIGdpdmVzIHN0dWRlbnRzIGEgY2hhbmNlIHRvIGdlbmVyYXRlIG5ldyBjb25jZXB0cy4gDQoNCjQuCVRoZSB0ZWFjaGVyIGFwcGxpZXMgZ3JvdXAgd29yayBpbiB0aGUgY2xhc3MgdG8gc2VydmUgZGVzaXJlZCBvYmplY3RpdmVzLg0KDQo1LglUaGUgdGVhY2hlciBkaXN0cmlidXRlcyBkaWZmZXJlbnQgdGVhY2hpbmctbGVhcm5pbmcgdGFza3MgdG8gc3R1ZGVudHMuDQoNCjYuCVRoZSB0ZWFjaGVyIGxldHMgc3R1ZGVudHMgaGF2ZSB0aGVpciBvd24gY29udmVyc2F0aW9ucyBwb3NpdGl2ZWx5Lg0KDQoqKkxlY3R1cmUgVHlwZSoqDQoNCjEuCVRoZSB0ZWFjaGVyIHByb3ZpZGVzIHN0dWRlbnRzIHdpdGggZmVlZGJhY2sgcmVnYXJkaW5nIHRoZWlyIGFuc3dlcnMgYXQgYWxsIHRpbWVzLiANCg0KMi4JVGhlIHRlYWNoZXIgZW5kcyB0aGUgdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9uIGJ5IGNsYXJpZnlpbmcgYW5kIGRpc2N1c3NpbmcgZGlhZ3JhbXMgc3VpdGFibGUgZm9yIHN0dWRlbnRzLiANCg0KMy4JVGhlIHRlYWNoZXIgdHJhaW5zIHN0dWRlbnRzIG9uIGdlbmVyYXRpbmcgc3BlY2lmaWMgYW5zd2VycyB0byB0aGUgcXVlc3Rpb25zIHJhaXNlZCB0byB0aGVtLiANCg0KNC4JVGVhY2hlcnMnIGNvZ25pdGl2ZSB0ZWFjaGluZyBzdHJhdGVnaWVzIGhhcm1vbml6ZSB3aXRoIHN0dWRlbnRzJyBsZWFybmluZyBzdHJhdGVnaWVzLiANCg0KNS4JVGhlIHRlYWNoZXIgYWxsb3dzIHN0dWRlbnRzIHRvIGhhdmUgbW9yZSBjbGFyaWZpY2F0aW9ucyBhbmQgZXhwbGFuYXRpb25zIG9uIGEgY2VydGFpbiB0b3BpYy4gDQoNCjYuCVRoZSB0ZWFjaGVyIHRyYWlucyBzdHVkZW50cyB0byBzb2x2ZSB0aGVpciBwcm9ibGVtcyBpbiBhIGNvbWZvcnRhYmxlIHdheS4gDQoNCjcuCVRoZSB0ZWFjaGVyIG1ha2VzIHN0dWRlbnRzIHRha2UgcGFydCBpbiBkaWZmZXJlbnQgcm9sZXMuDQoNCg0KKipEZWR1Y3RpdmUgQXBwcm9hY2gqKg0KDQoxLglUaGUgdGVhY2hlciB0cmFpbnMgc3R1ZGVudHMgdG8gZGV0ZXJtaW5lIHRoZSB3aG9sZSBpZGVhIG9mIHRoZSB0b3BpYy4gDQoNCjIuCVRoZSB0ZWFjaGVyIHByb3ZpZGVzIHN0dWRlbnRzIHdpdGggYSBjaGFuY2UgdG8gYXBwbHkgbmV3IGtub3dsZWRnZSBpbiBuZXcgcmVhbC1saWZlIHNpdHVhdGlvbnMuIA0KDQozLglUaGUgdGVhY2hlciB0cmFpbnMgc3R1ZGVudHMgb24gbGVhcm5pbmcgdGhlIHdob2xlIGNvbmNlcHQgYmVmb3JlIHRoZSBzcGVjaWZpYyBpZGVhLiANCg0KNC4JU3R1ZGVudHMgdGVuZCB0byBnZW5lcmF0ZSBuZXcgaW5mb3JtYXRpb24gYnkgbWFraW5nIGNvbXBhcmlzb25zIGJldHdlZW4gdGhlaXIgcHJldmlvdXMga25vd2xlZGdlIGFuZCB0aGUgbmV3IGluZm9ybWF0aW9uLiANCg0KNS4JVGhlIHRlYWNoZXIgbW92ZXMgZnJvbSB0aGUgYWJzdHJhY3QgdG8gdGhlIGNvbmNyZXRlIGV4YW1wbGVzLiANCg0KNi4JVGhlIHRlYWNoZXIgYXNrcyBzdHVkZW50cyB0byBkbyB3cml0dGVuIG9yIHZlcmJhbCBzdW1tYXJpZXMgb2YgdGhlIGluZm9ybWF0aW9uIHRoZXkgZ2V0LiANCg0KNy4JVGhlIHRlYWNoZXIgZGlzdHJpYnV0ZXMgZGlmZmVyZW50IHRlYWNoaW5nLWxlYXJuaW5nIHRhc2tzIHRvIHN0dWRlbnRzLiANCg0KDQoqKkluZHVjdGl2ZSBBcHByb2FjaCoqDQoNCjEuCVRoZSB0ZWFjaGVyIHVzZXMgc3BlY2lmaWMgcXVlc3Rpb25zIHRvIGRpc2N1c3MgdGhlIHdob2xlIHRvcGljLiANCg0KMi4JVGhlIHRlYWNoZXIgZGlzYXNzZW1ibGVzIHRoZSB0ZWFjaGluZy1sZWFybmluZyBtYXRlcmlhbCBpbnRvIHNwZWNpZmljIHRhc2tzIHRoYXQgbmVlZCBzcGVjaWZpYyByZXNwb25zZXMuDQoNCjMuCVRoZSB0ZWFjaGVyIHRyYWlucyBoaXMgc3R1ZGVudHMgb24gZGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBkaWZmZXJlbnQgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBzYW1lIGNvbmNlcHQuIA0KDQo0LglUaGUgdGVhY2hlciBiZWdpbnMgYnkgcHJlc2VudGluZyB0aGUgbWFpbiBpZGVhcyBvZiB0aGUgdG9waWMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY2xhc3MuIA0KDQo1LglUaGUgdGVhY2hlciB1c2VzIHNwZWNpZmljIHByb2JsZW0tc29sdmluZyBzdHJhdGVnaWVzIGluIHRoZSB0ZWFjaGluZyBwcm9jZXNzLiANCg0KNi4JVGhlIHRlYWNoZXIgYXNzaWducyBzdHVkZW50cyBhIHNwZWNpZmljIHRhc2sgd2l0aGluIGEgZ2VuZXJhbCB0YXNrLiANCg0KNy4JVGhlIHRlYWNoZXIgaGVscHMgc3R1ZGVudHMgdG8gYW5hbHl6ZSB0aGUgbWFpbiBpZGVhIHRvIGJlIHVzZWQgaW4gZGlzY3Vzc2luZyB0aGUgdG9waWMgYXMgYSB3aG9sZS4gDQoNCg0KKipEZW1vbnN0cmF0aW9uKioNCg0KMS4JVGhlIHRlYWNoZXIgdXNlcyBkaXJlY3QgcHJlc2VudGF0aW9uIHRvIHByb3ZpZGUgc3R1ZGVudHMgd2l0aCBpbmZvcm1hdGlvbi4gDQoNCjIuCVRoZSB0ZWFjaGVyIGhlbHBzIGhpcyBzdHVkZW50cyBpbWl0YXRlIGRlc2lyZWQgbW9kZWxzIGJ5IHNob3dpbmcgdGhlbS4gDQoNCjMuCVRoZSB0ZWFjaGVyIGJlZ2lucyB0aGUgdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9uIGJ5IHByZXNlbnRpbmcgYSBwcm9ibGVtIHRvIHN0dWRlbnRzLiANCg0KNC4JVGhlIHRlYWNoZXIgdHJhaW5zIHN0dWRlbnRzIHRvIHBsYW4sIG9ic2VydmUsIGFuZCBldmFsdWF0ZSB0aGVpciB0ZWFjaGluZyBhY3Rpdml0aWVzLiANCg0KNS4JVGhlIHRlYWNoZXIgc2hvd3Mgc3R1ZGVudHMgaG93IHRvIHZlcmlmeSBpbmZvcm1hdGlvbiBhbmQgZmFjdHMgYmVmb3JlIG1ha2luZyBqdWRnbWVudHMuIA0KDQo2LglUaGUgdGVhY2hlciBiZWdpbnMgd2l0aCBleGFtcGxlcyBvZiB0aGUgY29uY2VwdCBpbiB0aGUgdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9uLiANCg0KNy4JVGhlIHRlYWNoZXIgdGVhY2hlcyBzdHVkZW50cyB0aGUgd2F5IHRvIGlkZW50aWZ5IHRob3NlIHNpbXBsZSB0cmlja3MgdG8gdW5kZXJzdGFuZCB0aGUgbGVzc29uLg0KDQoqKlJlcGV0aXRpdmUgRXhlcmNpc2VzKioNCg0KMS4JVGhlIHRlYWNoZXIgdGFrZXMgYWR2YW50YWdlIG9mIHByb3ZpZGluZyBkaWZmZXJlbnQgYWN0aXZpdGllcyB0byBzZWN1cmUgdGhlIHRlYWNoaW5nLWxlYXJuaW5nIHByb2Nlc3MuIA0KDQoyLglUaGUgdGVhY2hlciBjYXJlcyBhYm91dCBjb3JyZWN0aW5nIHN0dWRlbnRzIGJ5IHByb3ZpZGluZyBtYW55IHdvcmtzaGVldHMuIA0KDQozLglUaGUgdGVhY2hlciBnaXZlcyBzaW1pbGFyIGV4YW1wbGVzIGR1cmluZyB0aGUgZGlzY3Vzc2lvbiB0byBzZWN1cmUgdGhlIG1hc3Rlcnkgb2YgdGhlIHRvcGljLiANCg0KNC4JVGhlIHRlYWNoZXIgdGFrZXMgcGFydCBpbiB0cmFpbmluZyBzdHVkZW50cyBieSBwcm92aWRpbmcgZGlmZmVyZW50IGxlYXJuaW5nIGFjdGl2aXRpZXMuIA0KDQo1LglUaGUgdGVhY2hlciBoZWxwcyBzdHVkZW50cyBpZGVudGlmeSB0aGVpciBvd24gbWlzdGFrZXMgYnkgZG9pbmcgc2ltaWxhciB3b3Jrc2hlZXRzLiANCg0KNi4JVGhlIHRlYWNoZXIgZ2l2ZXMgc3R1ZGVudHMgdGhlIGNoYW5jZSB0byBjb3JyZWN0IHRoZWlyIG1pc3Rha2VzIGJ5IGFuc3dlcmluZyBzaW1pbGFyIHF1ZXN0aW9ucy4gDQoNCjcuCVRoZSB0ZWFjaGVyIHRyYWlucyBzdHVkZW50cyBieSBwcm92aWRpbmcgZGlmZmVyZW50IHNldHMgb2Ygd29ya3NoZWV0cy4gDQoNCg0KKipJbnRlZ3JhdGl2ZSBBcHByb2FjaCoqDQoNCjEuCVRoZSB0ZWFjaGVyIGF3YXJkcyBzdHVkZW50cyBmb3IgdGhlaXIgY29ycmVjdCBhbnN3ZXIuIA0KDQoyLglUZWFjaGVyIGRlcGVuZHMgb24gY3JpdGVyaWEgaW4gZXZhbHVhdGluZyB0aGVpciBzdHVkZW50cy4gDQoNCjMuCVRoZSB0ZWFjaGVyIG5lZ2xlY3RzIHVuZGVzaXJlZCBiZWhhdmlvcnMgaW4gdGVhY2hpbmctbGVhcm5pbmcgc2l0dWF0aW9ucy4gDQoNCjQuCVRoZSB0ZWFjaGVyIG1ha2VzIHVzZSBvZiBjb25jZXB0IG1hcHMgZHVyaW5nIHRoZSB0ZWFjaGluZy1sZWFybmluZyBwcm9jZXNzLiANCg0KNS4JVGhlIHRlYWNoZXIgZmFjaWxpdGF0ZXMgc3R1ZGVudHMgdG8gbWFrZSB1c2Ugb2YgdGhlIHByb2NlZHVyZXMgdGhhdCBvcmdhbml6ZSBtZW1vcnkgcG90ZW50aWFscyAoc3ltYm9saXppbmcgaW5mb3JtYXRpb24pLiANCg0KNi4JVGhlIHRlYWNoZXIgZ3VpZGVzIHN0dWRlbnRzIHRvIHJlZmVyZW5jZXMgc3VjaCBhcyBkaWN0aW9uYXJpZXMsIGVuY3ljbG9wZWRpYXMsIGludGVybmV0IHNpdGVzLCBldGMuIA0KDQo3LglUaGUgdGVhY2hlciBzdXBwb3J0cyBzdHVkZW50cyBpbiB1c2luZyBkaWZmZXJlbnQgbGVhcm5pbmcgdG9vbHMgZm9yIHRoZSBwdXJwb3NlIG9mIHRlYWNoaW5nIHRoZSBsZWFybmluZyBwcm9jZXNzLiANCg0KDQojIyMgVXNlIG9mIHRlY2hub2xvZ2llcyBTY2FsZQ0KDQpgMTogc3Ryb25nbHkgZGlzYWdyZWUsIDI6IGRpc2FncmVlLCAzLiBOZXV0cmFsLCA0IGFncmVlLCA1LiBTdHJvbmdseSBhZ3JlZWANCg0KXA0KDQoxLiBJIGZlZWwgYXBwcmVoZW5zaXZlIGFib3V0IHVzaW5nIGluZm9ybWF0aW9uIHRlY2hub2xvZ2llcyAoSVRzKQ0KDQoyLiBUZWNobm9sb2dpY2FsIGluZm9ybWF0aW9uIHNvdW5kcyBsaWtlIGNvbmZ1c2luZyBqYXJnb24gdG8gbWUNCg0KMy4gSSBoYXZlIGF2b2lkZWQgSVRzIGJlY2F1c2UgaXQgaXMgdW5mYW1pbGlhciB0byBtZQ0KDQo0LiBJIGhlc2l0YXRlIHRvIHVzZSBJVHMgZm9yIGZlYXIgb2YgbWFraW5nIG1pc3Rha2VzIEkgY2Fubm90IGNvcnJlY3QNCg0KNS4gSVRzIGRvIG5vdCBzY2FyZSBtZSBhdCBhbGwNCg0KNi4gV29ya2luZyB3aXRoIElUcyB3b3VsZCBtYWtlIG1lIHZlcnkgbmVydm91cw0KDQo3LiBJIGRvIG5vdCBmZWVsIHRocmVhdGVuZWQgd2hlbiBvdGhlcnMgdGFsayBhYm91dCBJVHMNCg0KOC4gSSBmZWVsIGFnZ3Jlc3NpdmUgYW5kIGhvc3RpbGUgdG93YXJkIElUcw0KDQo5LiBJVCBtYWtlcyBtZSBmZWVsIHVuY29tZm9ydGFibGUNCg0KMTAuIEkgZ2V0IGEgc2lua2luZyBmZWVsaW5nIHdoZW4gSSB0aGluayBvZiB0cnlpbmcgdG8gdXNlIElUcw0KDQoxMS4gSVQgbWFrZXMgbWUgZmVlbCB1bmVhc3kNCg0KMTIuIElUIG1ha2VzIG1lIGZlZWwgY29uZnVzZWQNCg0KIyMjIExlYXJuaW5nIG1vZGFsaXRpZXMNCg0KMS4JV2hlbiBJIGxpc3RlbiB0byBhIGNsYXNzIGxlY3R1cmXigKYgDQogIGEuIEkgbGlzdGVuIHZlcnkgY2xvc2VseS4gDQogIGIuIEkgdHJ5IHRvIGJlIGNsb3NlIHRvIHRoZSBzcGVha2VyIGFuZCB3YXRjaCB0aGUgc3BlYWtlci4gDQogIGMuIEkgdGFrZSBub3RlcyBkdXJpbmcgdGhlIGxlY3R1cmUuIA0KICANCjIuCUkgbGlrZSB0byBzb2x2ZSB3b3JkIHByb2JsZW1zIGJ54oCmIA0KICBhLiB0YWxraW5nIHRvIGEgZnJpZW5kIG9yIHRvIG15c2VsZi4gDQogIGIuIHVzaW5nIGFuIG9yZ2FuaXplZCBhcHByb2FjaCB3aXRoIGxpc3RzIG9yIGNoYXJ0cy4gDQogIGMuIHdhbGtpbmcsIHBhY2luZywgb3IgZG9pbmcgc29tZXRoaW5nIGFjdGl2ZS4gDQogIA0KMy4JV2hlbiBzb21lb25lIHRlbGxzIG1lIG51bWJlcnMsIGJ1dCBJIGFtIHVuYWJsZSB0byB3cml0ZSB0aGVtIGRvd24sIEnigKYgDQogIGEuIFJlcGVhdCB0aGUgbnVtYmVycyB0byBteXNlbGYgb3V0IGxvdWQuIA0KICBiLiB2aXN1YWxpemUgb3Igc2VlIHRoZSBudW1iZXJzIGluIG15IG1pbmQuIA0KICBjLiBXcml0ZSB0aGUgbnVtYmVycyBpbiB0aGUgYWlyIG9yIG9uIHRoZSB0YWJsZS4gDQogIA0KNC4JSSBsZWFybiBzb21ldGhpbmcgbmV3IGJ54oCmIA0KICBhLiBoYXZpbmcgc29tZW9uZSBleHBsYWluIGl0IHRvIG1lIHdoaWxlIEkgbGlzdGVuLiANCiAgYi4gaGF2aW5nIHNvbWVvbmUgZG8gaXQgZm9yIG1lIHdoaWxlIEkgd2F0Y2guIA0KICBjLiBkb2luZyBpdCBteXNlbGYuIA0KICANCjUuCVdoZW4gSSB3YXRjaCBhIG1vdmllLCBJIHJlbWVtYmVy4oCmIA0KICBhLiBldmVyeXRoaW5nICh3aGF0IHdhcyBzYWlkLCBtdXNpYywgYmFja2dyb3VuZCBub2lzZXMpLiANCiAgYi4gdGhlIGNvc3R1bWVzLCBlbnZpcm9ubWVudCwgYW5kIHNjZW5lcnkuIA0KICBjLiBob3cgaXQgbWFkZSBtZSBmZWVsLiANCiAgDQo2LglXaGVuIEkgYW0gdHJ5aW5nIHRvIHJlbWVtYmVyIHNvbWV0aGluZywgSeKApiANCiAgYS4gaGVhciB3aGF0IHdhcyBzYWlkIG9yIHdoYXQgc291bmRzIHdlcmUgYXJvdW5kIG1lLiANCiAgYi4gdmlzdWFsaXplIGl0IGhhcHBlbmluZyBhZ2FpbiBpbiBteSBtaW5kLiANCiAgYy4gZmVlbCB0aGUgd2F5IEkgZGlkIHdoZW4gaXQgaGFwcGVuZWQuIA0KICANCjcuCVdoZW4gSSBkbyBub3Qga25vdyBob3cgdG8gc3BlbGwgYSB3b3JkLCBJ4oCmIA0KICBhLiBzb3VuZCBpdCBvdXQuIA0KICBiLiBzZWUgdGhlIHdvcmQgaW4gbXkgbWluZC4gDQogIGMuIFdyaXRlIHRoZSB3b3JkIG9uIHBhcGVyIHVudGlsIGl0IGxvb2tzIHJpZ2h0Lg0KICANCjguCUkgZW5qb3kgcmVhZGluZyB3aGVuIHRoZSBzdG9yeSBoYXPigKYgDQogIGEuIGEgbG90IG9mIGRpYWxvZ3VlIChjaGFyYWN0ZXJzIHRhbGtpbmcgdG8gZWFjaCBvdGhlcikuIA0KICBiLiBhIGxvdCBvZiBkZXNjcmlwdGl2ZSB3b3Jkcy4gDQogIGMuIGEgbG90IG9mIGFjdGlvbi4gDQogIA0KOS4JSSByZW1lbWJlciBuZXcgcGVvcGxlIGJ54oCmIA0KICBhLiB0aGVpciBuYW1lcy4gDQogIGIuIHRoZWlyIGZhY2VzLiANCiAgYy4gdGhlaXIgYWN0aW9ucy4NCiAgDQoxMC4JSSBoYXZlIGEgaGFyZCB0aW1lIGNvbmNlbnRyYXRpbmcgd2hlbuKApiANCiAgYS4gVGhlcmUgaXMgYSBsb3Qgb2Ygbm9pc2UuIA0KICBiLiBUaGVyZSBhcmUgYSBsb3Qgb2YgcGVvcGxlLiANCiAgYy4gSSBhbSB1bmNvbWZvcnRhYmxlICh0b28gaG90LCB0b28gY29sZCwgdW5jb21mb3J0YWJsZSBjaGFpciwgZXRjLikuIA0KICANCjExLglXaGVuIGl0IGNvbWVzIHRvIGNsb3RoZXMsIEkgcHJlZmVyIHRvIGRyZXNz4oCmIA0KICBhLiBpbiBhbnkgd2F5LCBzaW5jZSBjbG90aGVzIGFyZSBub3QgdGhhdCBpbXBvcnRhbnQgdG8gbWUuIA0KICBiLiB3ZWxsIOKAkyBhbmQgSSBoYXZlIGEgcGFydGljdWxhciBzdHlsZS4gDQogIGMuIGNvbWZvcnRhYmx5LCBzbyBJIGNhbiBtb3ZlIGFyb3VuZCBlYXNpbHkuIA0KICANCjEyLglJZiBJIGNhbm5vdCByZWFkIGFsb3VkIG9yIGdldCB1cCBhbmQgbW92ZSBhcm91bmQsIEnigKYgDQogIGEuIFRhbGsgd2l0aCBhIGZyaWVuZC4gDQogIGIuIGxvb2sgb3V0IGEgd2luZG93LiANCiAgYy4gcm9jayBpbiBteSBjaGFpciwgdGFwIG15IGZvb3QsIGRydW0gbXkgZmluZ2Vycywgb3IgamlnZ2xlIG15IHBlbmNpbC4NCg0KIyMjIEVuZ2FnZW1lbnQgYW5kIFJlc291cmNlcw0KDQpEdXJpbmcgdGhlIGN1cnJlbnQgc2Nob29sIHllYXIgYXQgc2Nob29sLCBob3cgb2Z0ZW4gaGF2ZSB5b3UgZG9uZSB0aGUgZm9sbG93aW5nOg0KYDEgLSBWZXJ5IG9mdGVuLCAyIC0gT2Z0ZW4sIDMgLSBTb21ldGltZXMsIDQg4oCTIE5ldmVyYA0KDQoqKkVuZ2FnZW1lbnQqKiANCg0KMS4gQXNrZWQgcXVlc3Rpb25zIGluIGNsYXNzLiANCg0KMi4gQW5zd2VyZWQgcXVlc3Rpb25zIGZyb20gcHJvZmVzc29ycyBvciBwZWVycyBpbiBjbGFzcy4NCg0KMy4gQ29udHJpYnV0ZWQgdG8gY2xhc3Mgb3IgZ3JvdXAgZGlzY3Vzc2lvbnMuIA0KDQo0LiBQcmFjdGljZSBleGVyY2lzZXMvZXhhbXBsZXMuDQoNCjUuIFRvb2sgZGV0YWlsZWQgY2xhc3Mgbm90ZXMuDQoNCjYuIFByZXZpZXdlZCB0aGUgY29udGVudCBiZWZvcmUgY2xhc3MuDQoNCjcuIFJldmlld2VkIGNsYXNzIG5vdGVzIGFuZCBvdGhlciByZWNvbW1lbmRlZCBleGVyY2lzZXMNCg0KOC4gV29ya2VkIHdpdGggb3RoZXIgc3R1ZGVudHMgb24gdGhlIGNvdXJzZSBtYXRlcmlhbHMuIA0KDQoqKlVzZSBvZiBSZXNvdXJjZXMqKg0KDQo5LiBHb3QgaGVscCBmcm9tIHByb2Zlc3NvcnMgdmlhIGVtYWlsLg0KDQoxMC4gV2VudCB0byB0aGUgcHJvZmVzc29y4oCZcyBpbi1wZXJzb24vWm9vbSBvZmZpY2UgaG91cnMuIA0KDQoxMS4gVXNlZCBmcmVlIHBlZXIgdHV0b3JpbmcgdGhyb3VnaCB0aGUgTWF0aCBMZWFybmluZyBDZW50ZXIgDQoNCjEyLiBVc2VkIHByaXZhdGUgdHV0b3Jpbmcgc2VydmljZXMuDQoNCg==