Introduction
Experimental design is a fundamental aspect of statistical analysis,
allowing researchers to systematically investigate the effects of
different treatments on a response variable. In CRD, experimental units
are randomly assigned to different treatment groups.

In this note, we will explore how Classical Analysis of Variance
(ANOVA) and Regression Analysis can be used to analyze data from a CRD.
We will also illustrate these methods using some numerical examples.
For
Working Data in Plant Physiology
Our example data are from an experiment in plant physiology,
published by Sokal and Rohlf (1995). The lengths of pea sections (the
dependent, or response, variable) grown in a tissue culture were
recorded. The purpose of the experiment was to test the effects of
various sugar media (the independent, or explanatory, variable) on mean
pea section length. A balanced CRD was used with 10
replicates per treatment level.
The data are given in the table below:

The wide-format table is easy to use when performing manual
calculations. Most of the software programs use long-format data tables.
We will reshape this wide table when using the R program for various
analyses.
Objective and Logic of
Analyzing CRD Data
Before moving to data analysis, we first discuss the objective,
logic, and methods for analyzing CRD data. The
The objective and
Logic
The core goals when analyzing Completely Randomized Design (CRD) data
are threefold:
Treatment Effect Detection - Determine if
different treatments produce statistically significant differences in
the response variable. For example, do fertilizers A, B, and C result in
different crop yields?
Effect Size Quantification - Measure the
magnitude of treatment differences. For example, Fertilizer C increases
yield by 13 bushels/acre compared to Fertilizer A
Ranking/Comparison of Treatments Identify which
treatments perform best/worst. This involves multiple comparisons among
means across treatments. For example, we can order fertilizers by yield:
A > B > A through multiple comparisons.
Statistically, treatment Effect Detection in CRD
with \(k\) treatments can be achieved
by testing a hypothesis.
\[
H_0: \mu_1 = \mu_2 = \cdots = \mu_k \ \ \text{vs} \ \ H_a: \ \text{at
least one mean differs}
\]
If \(H_0\) is
rejected, we quantify the size of treatment effects and
rank the treatment effects across the treatments in the CRD. There are
different approaches to testing the above hypothesis
Measuring Discrepancy
between \(H_0\) and \(H_a\)
Let’s use the following balanced CRD data table and related
notations.

The three different errors defined above have the following
relationship.
\[
(y_{ij} - \bar{y}_{\cdot\cdot}) = (y_{ij} - \bar{y}_{i\cdot}) +
(\bar{y}_{i\cdot} - \bar{y}_{\cdot\cdot})
\]
The above expression simply means that we can
decompose the overall residual (\(y_{ij} - \bar{y}_{\cdot\cdot}\)) into
within treatment error (\((y_{ij} -
\bar{y}_{i\cdot})\), also called within residual error) and
between treatment error (\(\bar{y}_{i\cdot} -
\bar{y}_{\cdot\cdot}\)). Since an error could be positive or
negative. Similar to the definition of variance, we square all these
errors to obtain squared errors.
After some tedous
algebra (i.e., not straightforward at all!), we have the
following equation
\[
\sum_{i=1}^t\sum_{j=1}^{n_i}(y_{ij} - \bar{y}_{\cdot\cdot})^2=
\sum_{i=1}^t\sum_{j=1}^{n_i}(y_{ij} - \bar{y}_{i\cdot})^2 +
\sum_{i=1}^t\sum_{j=1}^{n_i}(\bar{y}_{i\cdot} - \bar{y}_{\cdot\cdot})^2
\]
The last term in the above equation has no subscript \(j\); we simplify the last term to get the
following equation.
\[
\underbrace{\sum_{i=1}^t\sum_{j=1}^{n_i}(y_{ij} -
\bar{y}_{\cdot\cdot})^2}_{SS_T} =\underbrace{
\sum_{i=1}^t\sum_{j=1}^{n_i}(y_{ij} - \bar{y}_{i\cdot})^2}_{SS_W} +
\underbrace{\sum_{i=1}^t n_i(\bar{y}_{i\cdot} -
\bar{y}_{\cdot\cdot})^2}_{SS_B}
\] where \(SS_T\) =
Total Sum of Squared Residuals, \(SS_W\) = Sum of Squared Errors
within treatments and \(SS_B\)
= Sum of Squared Errors between treatments.
Recall the definition of sample
variance
\[
s^2 = \frac{(x_1-\bar{x})^2 +(x_2-\bar{x})^2 + \cdots _
(x_n-\bar{x})^2}{n-1} = \frac{\sum_{i=1}^n (x_i-\bar{x})^2}{n-1},
\]
Which is average squared
deviation (also called mean squared deviation
MSD or mean squared error, MSE)! The denominator \(n -1\) in the above definition reflects the
degrees of freedom - meaning that number of independent
observations (\(n\)) minus
one constratint (\(\bar{x} =
\sum_{i=1}^n x_i/n\), each equation based on the \(n\) independent observatiob is considered
as a contraint!).
Let’s look at \(SS_B\): There are
\(t\) independent means (one for each
treatment) \(\{\bar{y}_{1\cdot},
\bar{y}_{2\cdot}, \bar{y}_{3\cdot}, \cdots, \bar{y}_{t\cdot}
\}\), the grand total \(\bar{y}_{\cdot\cdot}\) is consider a
constraint. Therefore, there are $ t-1$ degrees of freedom associated
with \(SS_B\). Therefore, the mean
squared error of the between errors is defined by
\[
MS_B = \frac{SS_B}{t-1}
\]
Similarly, in \(SS_W\), there \(n_T\) independent observations \(y_{ij}\) and \(t\) constraints \(\{\bar{y}_{1\cdot}, \bar{y}_{2\cdot},
\bar{y}_{3\cdot}, \cdots, \bar{y}_{t\cdot} \}\)
(Yes! since each of them is the mean of
observations within each treatment). Therefore, the
degrees of freedom in \(SS_W\) is \(n_T-t\), Therefore, the mean square error
of within errors is defined by
\[
MS_W = \frac{SS_W}{n_T - t}.
\]
Remarks:
Here is the logic for how to
define a measure to assess the discrepancy between \(H_0\) and \(H_a\):
If there is no real difference
between treatments (i.e., \(H_0\) is
true), \(MS_B\) and \(MS_W\) both estimate the same underlying
variance. Therefore \(MS_B \approx
MS_W\)!
We can construct the test statistic based on \(MS_B\) and \(MSE_B\) under \(H_0\). Mathematically, both \(MS_B-MS_W\) (\(\approx 0\)) and \(MS_B/MS_W\) (\(\approx 1\)) are valid measures to assess
the discepancy between \(H_0\) and
\(H_a\). Since both quantities are
random (since they are evaluated based on the random sample), we need to
choose the one with a known probability distribution.
The ratio expression \(MS_B/MS_W\) has
a well-known distribution - F distribution!
Basics of F
Distribution
We have discussed several distributions to characterize test
statistics for the z-test, t-test, and chi-square test. One of the
essential tools in hypothesis testing involving the comparison of
variances (the case we introduced above) is the F-distribution. This
subsection outlines the basics of the F-distribution and demonstrates
how to use R to compute critical values and p-values associated with
F-tests.
The F-distribution is a continuous probability distribution used for
the comparison of two sample variances (such as \(SS_B\) and \(SS_W\)) and regression analysis (will
discuss this later). Using the above quantities, we have
\[
F = \frac{SS_W/(n_T-t)}{SS_B/(t-1)} \rightarrow F_{n_T-t, \ t-1}
\]
\(n_T-t\) is the degrees of freedom
of the numerator and \(t-1\) is the degrees of the
denominator. We can also flip the ratio to get another
valid test statistic
\[
F^\prime = \frac{SS_B/(t-1)}{SS_W/(n_T-t)} \rightarrow F_{\ t-1, n_T-t}
\]
Caution: the degrees of freedom
in the subscript MUST be adjusted so that the first index is the degrees
of freedom of the numerator and the second subscript represents the
degrees of freedom of the denominator.
This means \(F_{7,5}\) and \(F_{5, 7}\) are two different F
distributions!
\(F_{df_N, df_D}\) is skewed to the
right. The following figure shows the density curve of an F-distribution
with degrees of freedom df1 = 7 (numerator) and df2 = 10 (denominator),
together with the R commands to find the critical and p-values.

The syntax of the two R functions used to find the p-value and
critical value is annotated in the following figure.

Most introductory statistics textbooks include an F table based on a
few commonly used significance levels \(\alpha\). For example, the critical value
of \(F_{7, 10}\) at \(\alpha = 0.05\) labeled in the left panel
of the density curve of \(F_{7, 10}\)
can also be found from the following F table

The F tables are constructed based on a few significance levels. It
is not to use use F table to find p-values.
Next, we open a standalone section to formally introduce the one-way
ANOVA for CRD data.
One-Way ANOVA and
Implementation
We have discussed the logic and valid measures for assessing the
discrepancy between \(H_0\) and \(H_a\). Next, we summarize the above results
in a classical one-way ANOVA table and test the following null
hypothesis based on the CRD.
\[
H_0: \mu_1 = \mu_2 = \cdots = \mu_t \ \ \text{vs} \ \ H_a: \text{at
least one mean differs}
\]
The test statistic and corresponding p-value are summarized in the
following ANOVA table.
Between |
\(t-1\) |
\(SS_B\) |
\(MS_B=SS_B/(t-1)\) |
\(MS_W/MS_B\) |
|
Within |
\(n_T - t\) |
\(SS_W\) |
\(MS_W =
SS_W/(n_T-t)\) |
|
|
Total |
\(n_T-`\) |
\(SS_T\) |
|
|
|
Decision Rule: If the p-value in the above table is
less than the significance level \(\alpha\), we reject the null hypothesis;
otherwise, we conclude the null hypothesis.
Next, we use the plant physiology data to
demonstrate to to construct the above ANOVA table and use R as a
calculator to find \(SS\) and \(MS\) and related quantities in the ANOVA
table. The following code loads the data into R in the same format
(i.e., wide table format)
# Create the data vectors
Control <- c(75, 67, 70, 75, 65, 71, 67, 67, 76, 68) # Control
Glucose <- c(57, 58, 59, 59, 62, 60, 60, 57, 59, 61) # Glucose
Fructose <- c(58, 61, 56, 58, 57, 56, 58, 60, 57, 58) # Fructose
GlucFruc <- c(58, 59, 58, 61, 57, 56, 58, 57, 57, 59) # GlucFruc
Sucrose <- c(62, 66, 65, 63, 64, 62, 65, 65, 62, 67) # Sucrose
## using cbind() to display the data
cbind(Control, Glucose, Fructose, GlucFruc, Sucrose)
| Control Glucose Fructose GlucFruc Sucrose
| [1,] 75 57 58 58 62
| [2,] 67 58 61 59 66
| [3,] 70 59 56 58 65
| [4,] 75 59 58 61 63
| [5,] 65 62 57 57 64
| [6,] 71 60 56 56 62
| [7,] 67 60 58 58 65
| [8,] 67 57 60 57 65
| [9,] 76 59 57 57 62
| [10,] 68 61 58 59 67
#colnames(wide.table) <- c("Control", "Glucose", "Fructose", "GlucFruc", "Sucrose")
The next code chunk calculates different quantities in the ANOVA
table. I will make comments in the code to show detailed steps. The
primary R commands are sum()
, mean()
, and
related R functions of the F-distribution.
## degrees of freedom
t = 5
n.T = 10*5
dfN = t - 1
dfD = n.T - t
ybar.. = mean(c(Control, Glucose, Fructose, GlucFruc, Sucrose))
## Sum of squares
SS.B = 10*sum(c((mean(Control)-ybar..)^2, (mean(Glucose)-ybar..)^2, (mean(Fructose)-ybar..)^2, (mean(GlucFruc)-ybar..)^2, (mean(Sucrose)-ybar..)))
SS.W = sum(c(sum((Control-mean(Control))^2), sum((Glucose-mean(Glucose))^2), sum((Fructose-mean(Fructose))^2), sum((GlucFruc-mean(GlucFruc))^2), sum((Sucrose-mean(Sucrose))^2)))
SS.T = sum((c(Control, Glucose, Fructose, GlucFruc, Sucrose) - ybar..)^2)
## MS
MS.B = SS.B/dfN
MS.W = SS.W/dfD
## F value
F.value = MS.B/MS.W
p.val = pf(F.value, dfN, dfD, lower.tail = FALSE)
anova.out <- data.frame(
DF = c(dfN, dfD),
SS = c(SS.B, SS.W),
MS = c(MS.B, MS.W),
F.value = c(F.value, NA),
p.value = c(p.val, NA)
)
rownames(anova.out)=c("Between", "Within")
print(anova.out, na.print = "")
| DF SS MS F.value p.value
| Between 4 1077.944 269.486000 51.31981 3.324636e-16
| Within 45 236.300 5.251111 NA NA
Conclusion: The p-value is approximately 0. We
reject the null hypothesis that all means are equal. In other words, the
mean pea section length is affected by various sugar media.
The second part of the following YouTube video (after 15 Minutes, https://www.youtube.com/watch?v=KJ5G2KjcXcA) discussed
in the next note on One-way ANOVA.
ANOVA with R Function
aov()
We still use plant physiology data to illustrate
one-way ANOVA analysis using aov()
. Since
aov()
requires a long table structure. That is, all
measurements of the response must be stored in a column and a standalone
column to label the treatment of each value in the measurement column.
The following code creates a long table.
# Create the data vectors
lengths <- c(
75, 67, 70, 75, 65, 71, 67, 67, 76, 68, # Control
57, 58, 59, 59, 62, 60, 60, 57, 59, 61, # Glucose
58, 61, 56, 58, 57, 56, 58, 60, 57, 58, # Fructose
58, 59, 58, 61, 57, 56, 58, 57, 57, 59, # GlucFruc
62, 66, 65, 63, 64, 62, 65, 65, 62, 67 # Sucrose
)
# Create the treatment factor
treatment <- rep(c("Control", "Glucose", "Fructose", "GlucFruc", "Sucrose"), each = 10)
# Combine into a data frame
pea.long <- data.frame(
Length = lengths,
Treatment = factor(treatment, levels = c("Control", "Glucose", "Fructose", "GlucFruc", "Sucrose"))
)
# View the first 20 rows to make sure the data structure is correct
head(pea.long, n=20)
| Length Treatment
| 1 75 Control
| 2 67 Control
| 3 70 Control
| 4 75 Control
| 5 65 Control
| 6 71 Control
| 7 67 Control
| 8 67 Control
| 9 76 Control
| 10 68 Control
| 11 57 Glucose
| 12 58 Glucose
| 13 59 Glucose
| 14 59 Glucose
| 15 62 Glucose
| 16 60 Glucose
| 17 60 Glucose
| 18 57 Glucose
| 19 59 Glucose
| 20 61 Glucose
We next call aov()
to perform ANOVA analysis.
## create an anova model object
aov.model <- aov(Length ~ Treatment, data = pea.long)
## create the classical ANOVA table
anova(aov.model)
| Analysis of Variance Table
|
| Response: Length
| Df Sum Sq Mean Sq F value Pr(>F)
| Treatment 4 1105.7 276.430 52.642 < 2.2e-16 ***
| Residuals 45 236.3 5.251
| ---
| Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## or alternatively, you can simply use summary(aov.model) to produce the same results!
The annotated output is given by

Conclusion: Since the p-value is approximately 0,
the null hypothesis is rejected. That is, the various sugar media (the
independent, or explanatory, variable) significantly affect the mean pea
section length.
The following YouTube video ( https://www.youtube.com/watch?v=IkR3Rzrgiv4) gives
another example of using the R function aov()
. The video
also uses some graphical functions to create some visualizations. We did
not discuss visualizations in this class, but we will cover more
visualizations in subsequent statistics courses.
Multiple
Comparisons
When analyzing variance (ANOVA), a significant F-test (i.e., p-value
is less than the given significance level \(\alpha\)) indicates that at least one group
mean differs from the others. However, ANOVA does not specify which
pairs of groups are significantly different. Post-hoc
tests, also known as multiple comparison
tests, are used to identify these specific differences while
controlling for the increased risk of Type I errors (false positives)
that arise from performing multiple comparisons.
There are different Post-hoc tests. We only
introduce two commonly used post-hoc methods using R built-in
functions:
Tukey’s Honest Significant Difference (HSD)
-Controls family-wise error rate (FWER) for all
pairwise comparisons.
Bonferroni Correction - Adjusts p-values by
multiplying them by the number of comparisons
Visual Comparison
We have learned different graphical summaries of data. Box-plot is a
geometric representation of the 5-number-summary of a numerical
variable. Since treatment variable has multiple categories, we can
create a back-to-back box-plot to visualize the different in the
distributions.
The R function boxplot()
can draw multiple boxplots of a
numerical variable according the categories of the group variable. Since
package {graphics} comes with the base R, installation
and loading the package is unnecessary.
boxplot(Length ~ Treatment, data = pea.long)

The above box-plots clearly show that the pea lengths using sugar
media Fructose, Glucose, and GlucFruc are similar to each other.
Tukey’s Honest
Significant Difference (HSD)
Tukey’s Honest Significant Difference (HSD) is a post-hoc test used
after a statistically significant ANOVA to determine which specific
group means differ from each other. Unlike multiple t-tests, which
inflate the Type I error rate, Tukey’s HSD adjusts for multiple
comparisons, maintaining the family-wise error rate (FWER) at the
desired level (e.g., 0.05).
Next, we perform a multiple comparison of pea length across different
sugar media using the plant physiology data. For
convenience, we use the long-format data frame defined earlier and an
anova object in the following R code.
## refit the ANOVA model
aov.model <- aov(Length ~ Treatment, data = pea.long)
## multiple comparison
tukey.comp <- TukeyHSD(aov.model)
print(tukey.comp)
| Tukey multiple comparisons of means
| 95% family-wise confidence level
|
| Fit: aov(formula = Length ~ Treatment, data = pea.long)
|
| $Treatment
| diff lwr upr p adj
| Glucose-Control -10.9 -13.811928 -7.988072 0.0000000
| Fructose-Control -12.2 -15.111928 -9.288072 0.0000000
| GlucFruc-Control -12.1 -15.011928 -9.188072 0.0000000
| Sucrose-Control -6.0 -8.911928 -3.088072 0.0000050
| Fructose-Glucose -1.3 -4.211928 1.611928 0.7114379
| GlucFruc-Glucose -1.2 -4.111928 1.711928 0.7676225
| Sucrose-Glucose 4.9 1.988072 7.811928 0.0001778
| GlucFruc-Fructose 0.1 -2.811928 3.011928 0.9999786
| Sucrose-Fructose 6.2 3.288072 9.111928 0.0000026
| Sucrose-GlucFruc 6.1 3.188072 9.011928 0.0000036
The results indicate that there is no significant difference in pairs
Fructose-Glucose, GlucFruc-Glucose, and GlucFruc-Fructose.
par(mai=c(1.5,2,1,1)) # Makes room on the plot for the group names
plot(tukey.comp, # name of the TukeyHSD() object
cex.lab = 0.6, # adjust the font size of the labels of the vertical axis
las = 1) # orientation of the labels

Bonferroni
Comparison
The Bonferroni correction is a conservative method for adjusting
significance levels when performing multiple comparisons to reduce the
risk of Type I errors (false positives). It is one of the simplest and
most widely used approaches for controlling the family-wise error
rate.
The R function pairwise.t.test()
performs pairwise
comparison. It requires inputting individual variables (response and
treatment group). The following is code for the Bonferroni
procedure.
Bonfeeroni.result <- pairwise.t.test(
x = pea.long$Length,
g = pea.long$Treatment,
p.adjust.method = "bonferroni"
)
print(Bonfeeroni.result)
|
| Pairwise comparisons using t tests with pooled SD
|
| data: pea.long$Length and pea.long$Treatment
|
| Control Glucose Fructose GlucFruc
| Glucose 7.3e-13 - - -
| Fructose 1.7e-14 1.00000 - -
| GlucFruc 2.2e-14 1.00000 1.00000 -
| Sucrose 5.1e-06 0.00019 2.6e-06 3.7e-06
|
| P value adjustment method: bonferroni
Using the p-value adjusted Bonferroni procedure, three pairs of
treatment groups are significantly different: Fructose-Glucose,
GlucFruc-Glucose, and GlucFruc-Fructose. This result is consistent with
Tukeu’s HSD method.
Before conclude this section, we recommend a YouTube video (https://www.youtube.com/watch?v=hPUvqtmCu7Q) with an
example one multiple comparison among group means using R,
LS0tDQp0aXRsZTogIkFuYWx5c2lzIG9mIFZhcmlhbmNlIGZvciBDb21wbGV0ZWx5IFJhbmRvbWl6ZWQgRGVzaWduIg0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICJTVEEyMDAgU3RhdGlzdGljcyBJSSAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiA1DQogICAgZmlnX2hlaWdodDogNA0KLS0tDQoNCmBgYHs9aHRtbH0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQo8L3N0eWxlPg0KYGBgDQoNCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQojIGtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gIkM6L1VzZXJzLzc1Q1BFTkcvT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQS9Eb2N1bWVudHMiKQ0KIyBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICJDOlxcU1RBNDkwXFx3MDUiKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gInwiKQ0KYGBgDQoNCg0KDQpcDQoNCg0KIyBJbnRyb2R1Y3Rpb24NCg0KRXhwZXJpbWVudGFsIGRlc2lnbiBpcyBhIGZ1bmRhbWVudGFsIGFzcGVjdCBvZiBzdGF0aXN0aWNhbCBhbmFseXNpcywgYWxsb3dpbmcgcmVzZWFyY2hlcnMgdG8gc3lzdGVtYXRpY2FsbHkgaW52ZXN0aWdhdGUgdGhlIGVmZmVjdHMgb2YgZGlmZmVyZW50IHRyZWF0bWVudHMgb24gYSByZXNwb25zZSB2YXJpYWJsZS4gSW4gQ1JELCBleHBlcmltZW50YWwgdW5pdHMgYXJlIHJhbmRvbWx5IGFzc2lnbmVkIHRvIGRpZmZlcmVudCB0cmVhdG1lbnQgZ3JvdXBzLg0KDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjcwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDQvQ1JELnBuZyIpDQpgYGANCg0KSW4gdGhpcyBub3RlLCB3ZSB3aWxsIGV4cGxvcmUgaG93IENsYXNzaWNhbCBBbmFseXNpcyBvZiBWYXJpYW5jZSAoQU5PVkEpIGFuZCBSZWdyZXNzaW9uIEFuYWx5c2lzIGNhbiBiZSB1c2VkIHRvIGFuYWx5emUgZGF0YSBmcm9tIGEgQ1JELiBXZSB3aWxsIGFsc28gaWxsdXN0cmF0ZSB0aGVzZSBtZXRob2RzIHVzaW5nIHNvbWUgbnVtZXJpY2FsIGV4YW1wbGVzLiBGb3INCg0KDQoqKldvcmtpbmcgRGF0YSBpbiBQbGFudCBQaHlzaW9sb2d5KioNCg0KT3VyIGV4YW1wbGUgZGF0YSBhcmUgZnJvbSBhbiBleHBlcmltZW50IGluIHBsYW50IHBoeXNpb2xvZ3ksIHB1Ymxpc2hlZCBieSBTb2thbCBhbmQgUm9obGYgKDE5OTUpLiBUaGUgbGVuZ3RocyBvZiBwZWEgc2VjdGlvbnMgKHRoZSBkZXBlbmRlbnQsIG9yIHJlc3BvbnNlLCB2YXJpYWJsZSkgZ3Jvd24gaW4gYSB0aXNzdWUgY3VsdHVyZSB3ZXJlIHJlY29yZGVkLiBUaGUgcHVycG9zZSBvZiB0aGUgZXhwZXJpbWVudCB3YXMgdG8gdGVzdCB0aGUgZWZmZWN0cyBvZiB2YXJpb3VzIHN1Z2FyIG1lZGlhICh0aGUgaW5kZXBlbmRlbnQsIG9yIGV4cGxhbmF0b3J5LCB2YXJpYWJsZSkgb24gbWVhbiBwZWEgc2VjdGlvbiBsZW5ndGguIEEgKipiYWxhbmNlZCBDUkQqKiB3YXMgdXNlZCB3aXRoIDEwIHJlcGxpY2F0ZXMgcGVyIHRyZWF0bWVudCBsZXZlbC4NCg0KVGhlIGRhdGEgYXJlIGdpdmVuIGluIHRoZSB0YWJsZSBiZWxvdzoNCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI3MCUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0FOT1ZBLUV4YW1wbGVEYXRhLnBuZyIpDQpgYGANCg0KDQoNClRoZSB3aWRlLWZvcm1hdCB0YWJsZSBpcyBlYXN5IHRvIHVzZSB3aGVuIHBlcmZvcm1pbmcgbWFudWFsIGNhbGN1bGF0aW9ucy4gTW9zdCBvZiB0aGUgc29mdHdhcmUgcHJvZ3JhbXMgdXNlIGxvbmctZm9ybWF0IGRhdGEgdGFibGVzLiBXZSB3aWxsIHJlc2hhcGUgdGhpcyB3aWRlIHRhYmxlIHdoZW4gdXNpbmcgdGhlIFIgcHJvZ3JhbSBmb3IgdmFyaW91cyBhbmFseXNlcy4NCg0KDQoNCg0KIyBPYmplY3RpdmUgYW5kIExvZ2ljIG9mIEFuYWx5emluZyBDUkQgRGF0YQ0KDQpCZWZvcmUgbW92aW5nIHRvIGRhdGEgYW5hbHlzaXMsIHdlIGZpcnN0IGRpc2N1c3MgdGhlIG9iamVjdGl2ZSwgbG9naWMsIGFuZCBtZXRob2RzIGZvciBhbmFseXppbmcgQ1JEIGRhdGEuIFRoZSANCg0KIyMgVGhlIG9iamVjdGl2ZSBhbmQgTG9naWMNCg0KVGhlIGNvcmUgZ29hbHMgd2hlbiBhbmFseXppbmcgQ29tcGxldGVseSBSYW5kb21pemVkIERlc2lnbiAoQ1JEKSBkYXRhIGFyZSB0aHJlZWZvbGQ6DQoNCiogKipUcmVhdG1lbnQgRWZmZWN0IERldGVjdGlvbioqIC0gRGV0ZXJtaW5lIGlmIGRpZmZlcmVudCB0cmVhdG1lbnRzIHByb2R1Y2Ugc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiB0aGUgcmVzcG9uc2UgdmFyaWFibGUuIEZvciBleGFtcGxlLCBkbyBmZXJ0aWxpemVycyBBLCBCLCBhbmQgQyByZXN1bHQgaW4gZGlmZmVyZW50IGNyb3AgeWllbGRzPw0KDQoqICoqRWZmZWN0IFNpemUgUXVhbnRpZmljYXRpb24qKiAtIE1lYXN1cmUgdGhlIG1hZ25pdHVkZSBvZiB0cmVhdG1lbnQgZGlmZmVyZW5jZXMuIEZvciBleGFtcGxlLCBGZXJ0aWxpemVyIEMgaW5jcmVhc2VzIHlpZWxkIGJ5IDEzIGJ1c2hlbHMvYWNyZSBjb21wYXJlZCB0byBGZXJ0aWxpemVyIEENCg0KKiAqKlJhbmtpbmcvQ29tcGFyaXNvbiBvZiBUcmVhdG1lbnRzKiogSWRlbnRpZnkgd2hpY2ggdHJlYXRtZW50cyBwZXJmb3JtIGJlc3Qvd29yc3QuIFRoaXMgaW52b2x2ZXMgbXVsdGlwbGUgY29tcGFyaXNvbnMgYW1vbmcgbWVhbnMgYWNyb3NzIHRyZWF0bWVudHMuIEZvciBleGFtcGxlLCB3ZSBjYW4gb3JkZXIgZmVydGlsaXplcnMgYnkgeWllbGQ6IEEgPiBCID4gQSB0aHJvdWdoIG11bHRpcGxlIGNvbXBhcmlzb25zLg0KDQoNClN0YXRpc3RpY2FsbHksICoqdHJlYXRtZW50IEVmZmVjdCBEZXRlY3Rpb24qKiBpbiBDUkQgd2l0aCAkayQgdHJlYXRtZW50cyBjYW4gYmUgYWNoaWV2ZWQgYnkgdGVzdGluZyBhIGh5cG90aGVzaXMuDQoNCiQkDQpIXzA6IFxtdV8xID0gXG11XzIgPSBcY2RvdHMgPSBcbXVfayBcIFwgXHRleHR7dnN9IFwgXCAgSF9hOiBcIFx0ZXh0e2F0IGxlYXN0IG9uZSBtZWFuIGRpZmZlcnN9DQokJA0KDQpJZiAkSF8wJCBpcyAqKnJlamVjdGVkKiosIHdlIHF1YW50aWZ5IHRoZSBzaXplIG9mIHRyZWF0bWVudCBlZmZlY3RzIGFuZCByYW5rIHRoZSB0cmVhdG1lbnQgZWZmZWN0cyBhY3Jvc3MgdGhlIHRyZWF0bWVudHMgaW4gdGhlIENSRC4gVGhlcmUgYXJlIGRpZmZlcmVudCBhcHByb2FjaGVzIHRvIHRlc3RpbmcgdGhlIGFib3ZlIGh5cG90aGVzaXMNCg0KDQojIyBNZWFzdXJpbmcgRGlzY3JlcGFuY3kgYmV0d2VlbiAkSF8wJCBhbmQgJEhfYSQNCg0KTGV0J3MgdXNlIHRoZSBmb2xsb3dpbmcgYmFsYW5jZWQgQ1JEIGRhdGEgdGFibGUgYW5kIHJlbGF0ZWQgbm90YXRpb25zLg0KDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjkwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDQvR2VuZXJpY0NSRC1EYXRhVGFibGUucG5nIikNCmBgYA0KDQpUaGUgdGhyZWUgZGlmZmVyZW50IGVycm9ycyBkZWZpbmVkIGFib3ZlIGhhdmUgdGhlIGZvbGxvd2luZyByZWxhdGlvbnNoaXAuDQoNCiQkDQooeV97aWp9IC0gXGJhcnt5fV97XGNkb3RcY2RvdH0pID0gKHlfe2lqfSAtIFxiYXJ7eX1fe2lcY2RvdH0pICsgKFxiYXJ7eX1fe2lcY2RvdH0gLSBcYmFye3l9X3tcY2RvdFxjZG90fSkgDQokJA0KDQpUaGUgYWJvdmUgZXhwcmVzc2lvbiBzaW1wbHkgbWVhbnMgdGhhdCB3ZSBjYW4gKipkZWNvbXBvc2UqKiB0aGUgb3ZlcmFsbCByZXNpZHVhbCAoJHlfe2lqfSAtIFxiYXJ7eX1fe1xjZG90XGNkb3R9JCkgaW50byB3aXRoaW4gdHJlYXRtZW50IGVycm9yICgkKHlfe2lqfSAtIFxiYXJ7eX1fe2lcY2RvdH0pJCwgYWxzbyBjYWxsZWQgd2l0aGluIHJlc2lkdWFsIGVycm9yKSBhbmQgYmV0d2VlbiB0cmVhdG1lbnQgZXJyb3IgKCRcYmFye3l9X3tpXGNkb3R9IC0gXGJhcnt5fV97XGNkb3RcY2RvdH0kKS4gU2luY2UgYW4gZXJyb3IgY291bGQgYmUgcG9zaXRpdmUgb3IgbmVnYXRpdmUuIFNpbWlsYXIgdG8gdGhlIGRlZmluaXRpb24gb2YgdmFyaWFuY2UsIHdlIHNxdWFyZSBhbGwgdGhlc2UgZXJyb3JzIHRvIG9idGFpbiBzcXVhcmVkIGVycm9ycy4gDQoNCjxmb250IGNvbG9yID0gInJlZCIgc2l6ZSA9IDQ+KipcY29sb3J7cmVkfUFmdGVyIHNvbWUgdGVkb3VzIGFsZ2VicmEqKiAoaS5lLiwgbm90IHN0cmFpZ2h0Zm9yd2FyZCBhdCBhbGwhKTwvZm9udD4sIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBlcXVhdGlvbg0KDQokJA0KXHN1bV97aT0xfV50XHN1bV97aj0xfV57bl9pfSh5X3tpan0gLSBcYmFye3l9X3tcY2RvdFxjZG90fSleMj0gXHN1bV97aT0xfV50XHN1bV97aj0xfV57bl9pfSh5X3tpan0gLSBcYmFye3l9X3tpXGNkb3R9KV4yICsgXHN1bV97aT0xfV50XHN1bV97aj0xfV57bl9pfShcYmFye3l9X3tpXGNkb3R9IC0gXGJhcnt5fV97XGNkb3RcY2RvdH0pXjIgDQokJA0KDQpUaGUgbGFzdCB0ZXJtIGluIHRoZSBhYm92ZSBlcXVhdGlvbiBoYXMgbm8gc3Vic2NyaXB0ICRqJDsgd2Ugc2ltcGxpZnkgdGhlIGxhc3QgdGVybSB0byBnZXQgdGhlIGZvbGxvd2luZyBlcXVhdGlvbi4NCg0KJCQNClx1bmRlcmJyYWNle1xzdW1fe2k9MX1edFxzdW1fe2o9MX1ee25faX0oeV97aWp9IC0gXGJhcnt5fV97XGNkb3RcY2RvdH0pXjJ9X3tTU19UfSAgPVx1bmRlcmJyYWNleyBcc3VtX3tpPTF9XnRcc3VtX3tqPTF9XntuX2l9KHlfe2lqfSAtIFxiYXJ7eX1fe2lcY2RvdH0pXjJ9X3tTU19XfSAgKyBcdW5kZXJicmFjZXtcc3VtX3tpPTF9XnQgbl9pKFxiYXJ7eX1fe2lcY2RvdH0gLSBcYmFye3l9X3tcY2RvdFxjZG90fSleMn1fe1NTX0J9ICANCiQkDQp3aGVyZSAkU1NfVCQgPSAqKlRvdGFsIFN1bSBvZiBTcXVhcmVkIFJlc2lkdWFscyoqLCAkU1NfVyQgPSAqKlN1bSBvZiBTcXVhcmVkIEVycm9ycyB3aXRoaW4gdHJlYXRtZW50cyoqIGFuZCAkU1NfQiQgPSAqKlN1bSBvZiBTcXVhcmVkIEVycm9ycyBiZXR3ZWVuIHRyZWF0bWVudHMqKi4NCg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiIHNpemUgPSA1PioqXGNvbG9ye3JlZH0gUmVjYWxsIHRoZSBkZWZpbml0aW9uIG9mIHNhbXBsZSB2YXJpYW5jZSoqPC9mb250Pg0KDQokJA0Kc14yID0gXGZyYWN7KHhfMS1cYmFye3h9KV4yICsoeF8yLVxiYXJ7eH0pXjIgKyBcY2RvdHMgXyAoeF9uLVxiYXJ7eH0pXjJ9e24tMX0gPSBcZnJhY3tcc3VtX3tpPTF9Xm4gKHhfaS1cYmFye3h9KV4yfXtuLTF9LA0KJCQNCg0KV2hpY2ggaXMgPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9YXZlcmFnZSBzcXVhcmVkIGRldmlhdGlvbioqPC9mb250PiAoYWxzbyBjYWxsZWQgKiptZWFuIHNxdWFyZWQgZGV2aWF0aW9uIE1TRCBvciBtZWFuIHNxdWFyZWQgZXJyb3IsIE1TRSoqKSEgVGhlIGRlbm9taW5hdG9yICRuIC0xJCBpbiB0aGUgYWJvdmUgZGVmaW5pdGlvbiByZWZsZWN0cyB0aGUgKipkZWdyZWVzIG9mIGZyZWVkb20qKiAtIG1lYW5pbmcgdGhhdCBudW1iZXIgb2YgaW5kZXBlbmRlbnQgb2JzZXJ2YXRpb25zICgkbiQpIG1pbnVzICoqb25lKiogY29uc3RyYXRpbnQgKCRcYmFye3h9ID0gXHN1bV97aT0xfV5uIHhfaS9uJCwgZWFjaCBlcXVhdGlvbiBiYXNlZCBvbiB0aGUgJG4kIGluZGVwZW5kZW50IG9ic2VydmF0aW9iIGlzIGNvbnNpZGVyZWQgYXMgYSBjb250cmFpbnQhKS4NCg0KTGV0J3MgbG9vayBhdCAkU1NfQiQ6IFRoZXJlIGFyZSAkdCQgaW5kZXBlbmRlbnQgbWVhbnMgKG9uZSBmb3IgZWFjaCB0cmVhdG1lbnQpICRce1xiYXJ7eX1fezFcY2RvdH0sIFxiYXJ7eX1fezJcY2RvdH0sIFxiYXJ7eX1fezNcY2RvdH0sIFxjZG90cywgXGJhcnt5fV97dFxjZG90fSBcfSQsIHRoZSBncmFuZCB0b3RhbCAkXGJhcnt5fV97XGNkb3RcY2RvdH0kIGlzIGNvbnNpZGVyIGEgY29uc3RyYWludC4gVGhlcmVmb3JlLCB0aGVyZSBhcmUgJCB0LTEkIGRlZ3JlZXMgb2YgZnJlZWRvbSBhc3NvY2lhdGVkIHdpdGggJFNTX0IkLiBUaGVyZWZvcmUsIHRoZSBtZWFuIHNxdWFyZWQgZXJyb3Igb2YgdGhlIGJldHdlZW4gZXJyb3JzIGlzIGRlZmluZWQgYnkNCg0KJCQNCk1TX0IgPSBcZnJhY3tTU19CfXt0LTF9DQokJA0KDQoNCg0KDQoNClNpbWlsYXJseSwgaW4gJFNTX1ckLCB0aGVyZSAkbl9UJCBpbmRlcGVuZGVudCBvYnNlcnZhdGlvbnMgJHlfe2lqfSQgYW5kICR0JCBjb25zdHJhaW50cyAkXHtcYmFye3l9X3sxXGNkb3R9LCBcYmFye3l9X3syXGNkb3R9LCBcYmFye3l9X3szXGNkb3R9LCBcY2RvdHMsIFxiYXJ7eX1fe3RcY2RvdH0gXH0kICg8Zm9udCBjb2xvciA9ICJyZWQiPioqWWVzISBzaW5jZSBlYWNoIG9mIHRoZW0gaXMgdGhlIG1lYW4gb2Ygb2JzZXJ2YXRpb25zIHdpdGhpbiBlYWNoIHRyZWF0bWVudCoqKTwvZm9udD4uIFRoZXJlZm9yZSwgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBpbiAkU1NfVyQgaXMgJG5fVC10JCwgVGhlcmVmb3JlLCB0aGUgbWVhbiBzcXVhcmUgZXJyb3Igb2Ygd2l0aGluIGVycm9ycyBpcyBkZWZpbmVkIGJ5DQoNCiQkDQpNU19XID0gXGZyYWN7U1NfV317bl9UIC0gdH0uDQokJA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH1SZW1hcmtzKio8L2ZvbnQ+Og0KDQoqICRNU19CJCBpcyB0aGUgZXN0aW1hdGVkIHNhbXBsZSB2YXJpYW5jZSBvZiB0aGUgKipzYW1wbGUgbWVhbnMqKiBvZiBpbmRpdmlkdWFsIHRyZWF0bWVudHMuDQoNCiogJE1TX1ckIGlzIHRoZSB3ZWlnaHRlZCBhdmVyYWdlIG9mIHRoZSB2YXJpYW5jZXMgb2YgZWFjaCBpbmRpdmlkdWFsIHRyZWF0bWVudC4NCg0KDQoNCg0KPGZvbnQgY29sb3IgPSAicmVkIiBzaXplID0gND4qKlxjb2xvcntyZWR9SGVyZSBpcyB0aGUgbG9naWMgZm9yIGhvdyB0byBkZWZpbmUgYSBtZWFzdXJlIHRvIGFzc2VzcyB0aGUgZGlzY3JlcGFuY3kgYmV0d2VlbiAkSF8wJCBhbmQgJEhfYSQ6Kio8L2ZvbnQ+DQoNCjxmb250IGNvbG9yID0gImJsdWUiIHNpemUgPSA1PioqXGNvbG9ye2JsdWV9SWYgdGhlcmUgaXMgbm8gcmVhbCBkaWZmZXJlbmNlIGJldHdlZW4gdHJlYXRtZW50cyAoaS5lLiwgJEhfMCQgaXMgdHJ1ZSksICRNU19CJCBhbmQgJE1TX1ckIGJvdGggZXN0aW1hdGUgdGhlIHNhbWUgdW5kZXJseWluZyB2YXJpYW5jZS4gVGhlcmVmb3JlICRNU19CIFxhcHByb3ggTVNfVyQhKio8L2ZvbnQ+DQoNClwNCg0KV2UgY2FuIGNvbnN0cnVjdCB0aGUgdGVzdCBzdGF0aXN0aWMgYmFzZWQgb24gJE1TX0IkIGFuZCAkTVNFX0IkIHVuZGVyICRIXzAkLiBNYXRoZW1hdGljYWxseSwgYm90aCAkTVNfQi1NU19XJCAoJFxhcHByb3ggMCQpIGFuZCAkTVNfQi9NU19XJCAoJFxhcHByb3ggMSQpIGFyZSB2YWxpZCBtZWFzdXJlcyB0byBhc3Nlc3MgdGhlIGRpc2NlcGFuY3kgYmV0d2VlbiAkSF8wJCBhbmQgJEhfYSQuIFNpbmNlIGJvdGggcXVhbnRpdGllcyBhcmUgcmFuZG9tIChzaW5jZSB0aGV5IGFyZSBldmFsdWF0ZWQgYmFzZWQgb24gdGhlIHJhbmRvbSBzYW1wbGUpLCB3ZSBuZWVkIHRvIGNob29zZSB0aGUgb25lIHdpdGggYSBrbm93biAqKnByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbioqLiBUaGUgcmF0aW8gZXhwcmVzc2lvbiAkTVNfQi9NU19XJCBoYXMgYSB3ZWxsLWtub3duIGRpc3RyaWJ1dGlvbiAtICoqRiBkaXN0cmlidXRpb24qKiENCg0KXA0KDQojIyBCYXNpY3Mgb2YgRiBEaXN0cmlidXRpb24NCg0KV2UgaGF2ZSBkaXNjdXNzZWQgc2V2ZXJhbCBkaXN0cmlidXRpb25zIHRvIGNoYXJhY3Rlcml6ZSB0ZXN0IHN0YXRpc3RpY3MgZm9yIHRoZSB6LXRlc3QsIHQtdGVzdCwgYW5kIGNoaS1zcXVhcmUgdGVzdC4gT25lIG9mIHRoZSBlc3NlbnRpYWwgdG9vbHMgaW4gaHlwb3RoZXNpcyB0ZXN0aW5nIGludm9sdmluZyB0aGUgY29tcGFyaXNvbiBvZiB2YXJpYW5jZXMgKHRoZSBjYXNlIHdlIGludHJvZHVjZWQgYWJvdmUpIGlzIHRoZSBGLWRpc3RyaWJ1dGlvbi4gVGhpcyBzdWJzZWN0aW9uIG91dGxpbmVzIHRoZSBiYXNpY3Mgb2YgdGhlIEYtZGlzdHJpYnV0aW9uIGFuZCBkZW1vbnN0cmF0ZXMgaG93IHRvIHVzZSBSIHRvIGNvbXB1dGUgY3JpdGljYWwgdmFsdWVzIGFuZCBwLXZhbHVlcyBhc3NvY2lhdGVkIHdpdGggRi10ZXN0cy4NCg0KVGhlIEYtZGlzdHJpYnV0aW9uIGlzIGEgY29udGludW91cyBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gdXNlZCBmb3IgdGhlIGNvbXBhcmlzb24gb2YgdHdvIHNhbXBsZSB2YXJpYW5jZXMgKHN1Y2ggYXMgJFNTX0IkIGFuZCAkU1NfVyQpIGFuZCByZWdyZXNzaW9uIGFuYWx5c2lzICh3aWxsIGRpc2N1c3MgdGhpcyBsYXRlcikuIFVzaW5nIHRoZSBhYm92ZSBxdWFudGl0aWVzLCB3ZSBoYXZlDQoNCiQkDQpGID0gXGZyYWN7U1NfVy8obl9ULXQpfXtTU19CLyh0LTEpfSBccmlnaHRhcnJvdyBGX3tuX1QtdCwgXCB0LTF9DQokJA0KDQokbl9ULXQkIGlzIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gb2YgdGhlICoqbnVtZXJhdG9yKiogYW5kICR0LTEkIGlzIHRoZSBkZWdyZWVzIG9mIHRoZSAqKmRlbm9taW5hdG9yKiouIFdlIGNhbiBhbHNvIGZsaXAgdGhlIHJhdGlvIHRvIGdldCBhbm90aGVyIHZhbGlkIHRlc3Qgc3RhdGlzdGljDQoNCg0KJCQNCkZeXHByaW1lID0gXGZyYWN7U1NfQi8odC0xKX17U1NfVy8obl9ULXQpfSBccmlnaHRhcnJvdyBGX3tcIHQtMSwgbl9ULXR9DQokJA0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH0gQ2F1dGlvbjoqKiB0aGUgZGVncmVlcyBvZiBmcmVlZG9tIGluIHRoZSBzdWJzY3JpcHQgTVVTVCBiZSBhZGp1c3RlZCBzbyB0aGF0IHRoZSBmaXJzdCBpbmRleCBpcyB0aGUgZGVncmVlcyBvZiBmcmVlZG9tIG9mIHRoZSBudW1lcmF0b3IgYW5kIHRoZSBzZWNvbmQgc3Vic2NyaXB0IHJlcHJlc2VudHMgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBvZiB0aGUgZGVub21pbmF0b3IuIDwvZm9udD4gPGZvbnQgY29sb3IgPSAicmVkIj4qKlxjb2xvcntyZWR9IFRoaXMgbWVhbnMgJEZfezcsNX0kIGFuZCAkRl97NSwgN30kIGFyZSB0d28gZGlmZmVyZW50IEYgZGlzdHJpYnV0aW9ucyEqKjwvZm9udD4NCg0KDQokRl97ZGZfTiwgZGZfRH0kIGlzIHNrZXdlZCB0byB0aGUgcmlnaHQuIFRoZSBmb2xsb3dpbmcgZmlndXJlIHNob3dzIHRoZSBkZW5zaXR5IGN1cnZlIG9mIGFuIEYtZGlzdHJpYnV0aW9uIHdpdGggZGVncmVlcyBvZiBmcmVlZG9tIGRmMSA9IDcgKG51bWVyYXRvcikgYW5kIGRmMiA9IDEwIChkZW5vbWluYXRvciksIHRvZ2V0aGVyIHdpdGggdGhlIFIgY29tbWFuZHMgdG8gZmluZCB0aGUgY3JpdGljYWwgYW5kIHAtdmFsdWVzLg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI5OSUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0YtZGVuc2l0eUN1cnZlLnBuZyIpDQpgYGANCg0KVGhlIHN5bnRheCBvZiB0aGUgdHdvIFIgZnVuY3Rpb25zIHVzZWQgdG8gZmluZCB0aGUgcC12YWx1ZSBhbmQgY3JpdGljYWwgdmFsdWUgaXMgYW5ub3RhdGVkIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlLg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI5MCUifQ0KaW5jbHVkZV9ncmFwaGljcygid2VlazA0L0YtRGlzUlN5bnRheC5wbmciKQ0KYGBgDQoNCk1vc3QgaW50cm9kdWN0b3J5IHN0YXRpc3RpY3MgdGV4dGJvb2tzIGluY2x1ZGUgYW4gRiB0YWJsZSBiYXNlZCBvbiBhIGZldyBjb21tb25seSB1c2VkIHNpZ25pZmljYW5jZSBsZXZlbHMgJFxhbHBoYSQuIEZvciBleGFtcGxlLCB0aGUgY3JpdGljYWwgdmFsdWUgb2YgJEZfezcsIDEwfSQgYXQgJFxhbHBoYSA9IDAuMDUkIGxhYmVsZWQgaW4gdGhlIGxlZnQgcGFuZWwgb2YgdGhlIGRlbnNpdHkgY3VydmUgb2YgJEZfezcsIDEwfSQgY2FuIGFsc28gYmUgZm91bmQgZnJvbSB0aGUgZm9sbG93aW5nIEYgdGFibGUNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iOTAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswNC9GLXRhYmxlLnBuZyIpDQpgYGANCg0KVGhlIEYgdGFibGVzIGFyZSBjb25zdHJ1Y3RlZCBiYXNlZCBvbiBhIGZldyBzaWduaWZpY2FuY2UgbGV2ZWxzLiBJdCBpcyBub3QgdG8gdXNlIHVzZSBGIHRhYmxlIHRvIGZpbmQgcC12YWx1ZXMuIA0KDQpOZXh0LCB3ZSBvcGVuIGEgc3RhbmRhbG9uZSBzZWN0aW9uIHRvIGZvcm1hbGx5IGludHJvZHVjZSB0aGUgb25lLXdheSBBTk9WQSBmb3IgQ1JEIGRhdGEuDQoNClwNCg0KIyBPbmUtV2F5IEFOT1ZBIGFuZCBJbXBsZW1lbnRhdGlvbg0KDQpXZSBoYXZlIGRpc2N1c3NlZCB0aGUgbG9naWMgYW5kIHZhbGlkIG1lYXN1cmVzIGZvciBhc3Nlc3NpbmcgdGhlIGRpc2NyZXBhbmN5IGJldHdlZW4gJEhfMCQgYW5kICRIX2EkLiBOZXh0LCB3ZSBzdW1tYXJpemUgdGhlIGFib3ZlIHJlc3VsdHMgaW4gYSBjbGFzc2ljYWwgb25lLXdheSBBTk9WQSB0YWJsZSBhbmQgdGVzdCB0aGUgZm9sbG93aW5nIG51bGwgaHlwb3RoZXNpcyBiYXNlZCBvbiB0aGUgQ1JELg0KDQokJA0KSF8wOiBcbXVfMSA9IFxtdV8yID0gXGNkb3RzID0gXG11X3QgXCBcIFx0ZXh0e3ZzfSBcIFwgSF9hOiBcdGV4dHthdCBsZWFzdCBvbmUgbWVhbiBkaWZmZXJzfQ0KJCQNCg0KVGhlIHRlc3Qgc3RhdGlzdGljIGFuZCBjb3JyZXNwb25kaW5nIHAtdmFsdWUgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZyBBTk9WQSB0YWJsZS4NCg0KfCAgKipTb3VyY2UqKiAgICB8ICoqREYqKiB8ICAgKipTUyoqICAgICB8ICAgKipNUyoqICB8ICoqRi1WYWx1ZSoqIHwgKipQLVZhbHVlKiogICAgfA0KfDotLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS18Oi0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tfA0KfCAqKkJldHdlZW4qKiAgfCAkdC0xJCAgICB8ICRTU19CJCAgICAgICB8ICRNU19CPVNTX0IvKHQtMSkkICAgICAgICB8ICRNU19XL01TX0IkIHwgfA0KfCAqKldpdGhpbioqICAgfCAkbl9UIC0gdCR8ICRTU19XJCAgICAgICB8ICRNU19XID0gU1NfVy8obl9ULXQpJCAgICB8ICAgICAgICAgICAgIHwgfA0KfCAqKlRvdGFsKiogICAgfCAkbl9ULWAkICB8ICRTU19UJCAgICAgICB8DQoNCioqRGVjaXNpb24gUnVsZSoqOiBJZiB0aGUgcC12YWx1ZSBpbiB0aGUgYWJvdmUgdGFibGUgaXMgbGVzcyB0aGFuIHRoZSBzaWduaWZpY2FuY2UgbGV2ZWwgJFxhbHBoYSQsIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzOyBvdGhlcndpc2UsIHdlIGNvbmNsdWRlIHRoZSBudWxsIGh5cG90aGVzaXMuDQoNCg0KTmV4dCwgd2UgdXNlIHRoZSAqKnBsYW50IHBoeXNpb2xvZ3kgZGF0YSoqIHRvIGRlbW9uc3RyYXRlIHRvIHRvIGNvbnN0cnVjdCB0aGUgYWJvdmUgQU5PVkEgdGFibGUgYW5kIHVzZSBSIGFzIGEgY2FsY3VsYXRvciB0byBmaW5kICRTUyQgYW5kICRNUyQgYW5kIHJlbGF0ZWQgcXVhbnRpdGllcyBpbiB0aGUgQU5PVkEgdGFibGUuIFRoZSBmb2xsb3dpbmcgY29kZSBsb2FkcyB0aGUgZGF0YSBpbnRvIFIgaW4gdGhlIHNhbWUgZm9ybWF0IChpLmUuLCB3aWRlIHRhYmxlIGZvcm1hdCkNCg0KYGBge3J9DQojIENyZWF0ZSB0aGUgZGF0YSB2ZWN0b3JzDQpDb250cm9sIDwtIGMoNzUsIDY3LCA3MCwgNzUsIDY1LCA3MSwgNjcsIDY3LCA3NiwgNjgpICAgICAjIENvbnRyb2wNCkdsdWNvc2UgPC0gYyg1NywgNTgsIDU5LCA1OSwgNjIsIDYwLCA2MCwgNTcsIDU5LCA2MSkgICAgICMgR2x1Y29zZQ0KRnJ1Y3Rvc2UgPC0gYyg1OCwgNjEsIDU2LCA1OCwgNTcsIDU2LCA1OCwgNjAsIDU3LCA1OCkgICAgICMgRnJ1Y3Rvc2UNCkdsdWNGcnVjIDwtIGMoNTgsIDU5LCA1OCwgNjEsIDU3LCA1NiwgNTgsIDU3LCA1NywgNTkpICAgICAjIEdsdWNGcnVjDQpTdWNyb3NlIDwtIGMoNjIsIDY2LCA2NSwgNjMsIDY0LCA2MiwgNjUsIDY1LCA2MiwgNjcpICAgICAjIFN1Y3Jvc2UNCiMjIHVzaW5nIGNiaW5kKCkgdG8gZGlzcGxheSB0aGUgZGF0YQ0KY2JpbmQoQ29udHJvbCwgR2x1Y29zZSwgRnJ1Y3Rvc2UsIEdsdWNGcnVjLCBTdWNyb3NlKQ0KI2NvbG5hbWVzKHdpZGUudGFibGUpIDwtIGMoIkNvbnRyb2wiLCAiR2x1Y29zZSIsICJGcnVjdG9zZSIsICJHbHVjRnJ1YyIsICJTdWNyb3NlIikNCmBgYA0KDQoNClRoZSBuZXh0IGNvZGUgY2h1bmsgY2FsY3VsYXRlcyBkaWZmZXJlbnQgcXVhbnRpdGllcyBpbiB0aGUgQU5PVkEgdGFibGUuIEkgd2lsbCBtYWtlIGNvbW1lbnRzIGluIHRoZSBjb2RlIHRvIHNob3cgZGV0YWlsZWQgc3RlcHMuIFRoZSBwcmltYXJ5IFIgY29tbWFuZHMgYXJlIGBzdW0oKWAsIGBtZWFuKClgLCBhbmQgcmVsYXRlZCBSIGZ1bmN0aW9ucyBvZiB0aGUgRi1kaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0KIyMgZGVncmVlcyBvZiBmcmVlZG9tDQp0ID0gNQ0Kbi5UID0gMTAqNQ0KZGZOID0gdCAtIDENCmRmRCA9IG4uVCAtIHQNCnliYXIuLiA9IG1lYW4oYyhDb250cm9sLCBHbHVjb3NlLCBGcnVjdG9zZSwgR2x1Y0ZydWMsIFN1Y3Jvc2UpKQ0KIyMgU3VtIG9mIHNxdWFyZXMNClNTLkIgPSAxMCpzdW0oYygobWVhbihDb250cm9sKS15YmFyLi4pXjIsIChtZWFuKEdsdWNvc2UpLXliYXIuLileMiwgKG1lYW4oRnJ1Y3Rvc2UpLXliYXIuLileMiwgKG1lYW4oR2x1Y0ZydWMpLXliYXIuLileMiwgKG1lYW4oU3Vjcm9zZSkteWJhci4uKSkpDQpTUy5XID0gc3VtKGMoc3VtKChDb250cm9sLW1lYW4oQ29udHJvbCkpXjIpLCBzdW0oKEdsdWNvc2UtbWVhbihHbHVjb3NlKSleMiksIHN1bSgoRnJ1Y3Rvc2UtbWVhbihGcnVjdG9zZSkpXjIpLCBzdW0oKEdsdWNGcnVjLW1lYW4oR2x1Y0ZydWMpKV4yKSwgc3VtKChTdWNyb3NlLW1lYW4oU3Vjcm9zZSkpXjIpKSkNClNTLlQgPSBzdW0oKGMoQ29udHJvbCwgR2x1Y29zZSwgRnJ1Y3Rvc2UsIEdsdWNGcnVjLCBTdWNyb3NlKSAtIHliYXIuLileMikNCiMjIE1TDQpNUy5CID0gU1MuQi9kZk4NCk1TLlcgPSBTUy5XL2RmRA0KIyMgRiB2YWx1ZQ0KRi52YWx1ZSA9IE1TLkIvTVMuVw0KcC52YWwgPSBwZihGLnZhbHVlLCBkZk4sIGRmRCwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYW5vdmEub3V0IDwtIGRhdGEuZnJhbWUoDQogIERGID0gYyhkZk4sIGRmRCksDQogIFNTID0gYyhTUy5CLCBTUy5XKSwNCiAgTVMgPSBjKE1TLkIsIE1TLlcpLA0KICBGLnZhbHVlID0gYyhGLnZhbHVlLCBOQSksDQogIHAudmFsdWUgPSBjKHAudmFsLCBOQSkNCikNCnJvd25hbWVzKGFub3ZhLm91dCk9YygiQmV0d2VlbiIsICJXaXRoaW4iKQ0KcHJpbnQoYW5vdmEub3V0LCBuYS5wcmludCA9ICIiKQ0KDQpgYGANCg0KKipDb25jbHVzaW9uKio6IFRoZSBwLXZhbHVlIGlzIGFwcHJveGltYXRlbHkgMC4gV2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCBhbGwgbWVhbnMgYXJlIGVxdWFsLiBJbiBvdGhlciB3b3JkcywgIHRoZSBtZWFuIHBlYSBzZWN0aW9uIGxlbmd0aCBpcyBhZmZlY3RlZCBieSB2YXJpb3VzIHN1Z2FyIG1lZGlhLg0KDQpcDQoNCg0KVGhlIHNlY29uZCBwYXJ0IG9mIHRoZSBmb2xsb3dpbmcgWW91VHViZSB2aWRlbyAgKGFmdGVyIDE1IE1pbnV0ZXMsIDxodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUtKNUcyS2pjWGNBPikgZGlzY3Vzc2VkIGluIHRoZSBuZXh0IG5vdGUgb24gT25lLXdheSBBTk9WQS4gDQoNClwNCg0KPGNlbnRlcj48YSBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUtKNUcyS2pjWGNBIiB0YXJnZXQ9InBvcHVwIiANCiAgICAgICAgICAgICAgICAgICBvbmNsaWNrPSJ3aW5kb3cub3BlbignaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1LSjVHMktqY1hjQScsDQogICAgICAgICAgICAgICAgICAgICAgJ25hbWUnLCd3aWR0aD04NTAsaGVpZ2h0PTUwMCcpIj48aW1nIHNyYyA9ICJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9NQVQxMjFXNS9pbWcvVmlkZW9JY29uLnBuZyIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIxMjAiPjwvYT4NCjwvY2VudGVyPg0KDQpcDQoNCg0KDQoNCg0KDQoNCg0KDQoNCiMgQU5PVkEgd2l0aCBSIEZ1bmN0aW9uIGBhb3YoKWANCg0KV2Ugc3RpbGwgdXNlICoqcGxhbnQgcGh5c2lvbG9neSBkYXRhKiogdG8gaWxsdXN0cmF0ZSBvbmUtd2F5IEFOT1ZBIGFuYWx5c2lzIHVzaW5nIGBhb3YoKWAuIFNpbmNlIGBhb3YoKWAgcmVxdWlyZXMgYSBsb25nIHRhYmxlIHN0cnVjdHVyZS4gVGhhdCBpcywgYWxsIG1lYXN1cmVtZW50cyBvZiB0aGUgcmVzcG9uc2UgbXVzdCBiZSBzdG9yZWQgaW4gYSBjb2x1bW4gYW5kIGEgc3RhbmRhbG9uZSBjb2x1bW4gdG8gbGFiZWwgdGhlIHRyZWF0bWVudCBvZiBlYWNoIHZhbHVlIGluIHRoZSBtZWFzdXJlbWVudCBjb2x1bW4uIFRoZSBmb2xsb3dpbmcgY29kZSBjcmVhdGVzIGEgbG9uZyB0YWJsZS4gDQoNCmBgYHtyfQ0KIyBDcmVhdGUgdGhlIGRhdGEgdmVjdG9ycw0KbGVuZ3RocyA8LSBjKA0KICA3NSwgNjcsIDcwLCA3NSwgNjUsIDcxLCA2NywgNjcsIDc2LCA2OCwgICAgICMgQ29udHJvbA0KICA1NywgNTgsIDU5LCA1OSwgNjIsIDYwLCA2MCwgNTcsIDU5LCA2MSwgICAgICMgR2x1Y29zZQ0KICA1OCwgNjEsIDU2LCA1OCwgNTcsIDU2LCA1OCwgNjAsIDU3LCA1OCwgICAgICMgRnJ1Y3Rvc2UNCiAgNTgsIDU5LCA1OCwgNjEsIDU3LCA1NiwgNTgsIDU3LCA1NywgNTksICAgICAjIEdsdWNGcnVjDQogIDYyLCA2NiwgNjUsIDYzLCA2NCwgNjIsIDY1LCA2NSwgNjIsIDY3ICAgICAgIyBTdWNyb3NlDQopDQoNCiMgQ3JlYXRlIHRoZSB0cmVhdG1lbnQgZmFjdG9yDQp0cmVhdG1lbnQgPC0gcmVwKGMoIkNvbnRyb2wiLCAiR2x1Y29zZSIsICJGcnVjdG9zZSIsICJHbHVjRnJ1YyIsICJTdWNyb3NlIiksIGVhY2ggPSAxMCkNCg0KIyBDb21iaW5lIGludG8gYSBkYXRhIGZyYW1lDQpwZWEubG9uZyA8LSBkYXRhLmZyYW1lKA0KICBMZW5ndGggPSBsZW5ndGhzLA0KICBUcmVhdG1lbnQgPSBmYWN0b3IodHJlYXRtZW50LCBsZXZlbHMgPSBjKCJDb250cm9sIiwgIkdsdWNvc2UiLCAiRnJ1Y3Rvc2UiLCAiR2x1Y0ZydWMiLCAiU3Vjcm9zZSIpKQ0KKQ0KDQojIFZpZXcgdGhlIGZpcnN0IDIwIHJvd3MgdG8gbWFrZSBzdXJlIHRoZSBkYXRhIHN0cnVjdHVyZSBpcyBjb3JyZWN0DQpoZWFkKHBlYS5sb25nLCBuPTIwKQ0KYGBgDQoNCldlIG5leHQgY2FsbCBgYW92KClgIHRvIHBlcmZvcm0gQU5PVkEgYW5hbHlzaXMuDQoNCmBgYHtyfQ0KIyMgY3JlYXRlIGFuIGFub3ZhIG1vZGVsIG9iamVjdCANCmFvdi5tb2RlbCA8LSBhb3YoTGVuZ3RoIH4gVHJlYXRtZW50LCBkYXRhID0gcGVhLmxvbmcpDQojIyBjcmVhdGUgdGhlIGNsYXNzaWNhbCBBTk9WQSB0YWJsZQ0KYW5vdmEoYW92Lm1vZGVsKQ0KIyMgb3IgYWx0ZXJuYXRpdmVseSwgeW91IGNhbiBzaW1wbHkgdXNlIHN1bW1hcnkoYW92Lm1vZGVsKSB0byBwcm9kdWNlIHRoZSBzYW1lIHJlc3VsdHMhDQpgYGANCg0KVGhlIGFubm90YXRlZCBvdXRwdXQgaXMgZ2l2ZW4gYnkNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNjAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIndlZWswNC9Bbm5vdGF0ZWQtQU5PVkEtT3V0cHV0LnBuZyIpDQpgYGANCg0KKipDb25jbHVzaW9uKio6ICBTaW5jZSB0aGUgcC12YWx1ZSBpcyBhcHByb3hpbWF0ZWx5IDAsIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgcmVqZWN0ZWQuIFRoYXQgaXMsIHRoZSB2YXJpb3VzIHN1Z2FyIG1lZGlhICh0aGUgaW5kZXBlbmRlbnQsIG9yIGV4cGxhbmF0b3J5LCB2YXJpYWJsZSkgc2lnbmlmaWNhbnRseSBhZmZlY3QgdGhlIG1lYW4gcGVhIHNlY3Rpb24gbGVuZ3RoLg0KDQpcDQoNClRoZSBmb2xsb3dpbmcgWW91VHViZSB2aWRlbyAoIDxodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUlrUjNSenJnaXY0PikgZ2l2ZXMgYW5vdGhlciBleGFtcGxlIG9mIHVzaW5nIHRoZSBSIGZ1bmN0aW9uIGBhb3YoKWAuIFRoZSB2aWRlbyBhbHNvIHVzZXMgc29tZSBncmFwaGljYWwgZnVuY3Rpb25zIHRvIGNyZWF0ZSBzb21lIHZpc3VhbGl6YXRpb25zLiBXZSBkaWQgbm90IGRpc2N1c3MgdmlzdWFsaXphdGlvbnMgaW4gdGhpcyBjbGFzcywgYnV0IHdlIHdpbGwgY292ZXIgbW9yZSB2aXN1YWxpemF0aW9ucyBpbiBzdWJzZXF1ZW50IHN0YXRpc3RpY3MgY291cnNlcy4NCg0KXA0KDQo8Y2VudGVyPjxhIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9SWtSM1J6cmdpdjQiIHRhcmdldD0icG9wdXAiIA0KICAgICAgICAgICAgICAgICAgIG9uY2xpY2s9IndpbmRvdy5vcGVuKCdodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUlrUjNSenJnaXY0JywNCiAgICAgICAgICAgICAgICAgICAgICAnbmFtZScsJ3dpZHRoPTg1MCxoZWlnaHQ9NTAwJykiPjxpbWcgc3JjID0gImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL01BVDEyMVc1L2ltZy9WaWRlb0ljb24ucG5nIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjEyMCI+PC9hPg0KPC9jZW50ZXI+DQoNClwNCg0KDQojIE11bHRpcGxlIENvbXBhcmlzb25zDQoNCldoZW4gYW5hbHl6aW5nIHZhcmlhbmNlIChBTk9WQSksIGEgc2lnbmlmaWNhbnQgRi10ZXN0IChpLmUuLCBwLXZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgZ2l2ZW4gc2lnbmlmaWNhbmNlIGxldmVsICRcYWxwaGEkKSBpbmRpY2F0ZXMgdGhhdCBhdCBsZWFzdCBvbmUgZ3JvdXAgbWVhbiBkaWZmZXJzIGZyb20gdGhlIG90aGVycy4gSG93ZXZlciwgQU5PVkEgZG9lcyBub3Qgc3BlY2lmeSB3aGljaCBwYWlycyBvZiBncm91cHMgYXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50LiAqKlBvc3QtaG9jIHRlc3RzKiosIGFsc28ga25vd24gYXMgKiptdWx0aXBsZSBjb21wYXJpc29uIHRlc3RzKiosIGFyZSB1c2VkIHRvIGlkZW50aWZ5IHRoZXNlIHNwZWNpZmljIGRpZmZlcmVuY2VzIHdoaWxlIGNvbnRyb2xsaW5nIGZvciB0aGUgaW5jcmVhc2VkIHJpc2sgb2YgVHlwZSBJIGVycm9ycyAoZmFsc2UgcG9zaXRpdmVzKSB0aGF0IGFyaXNlIGZyb20gcGVyZm9ybWluZyBtdWx0aXBsZSBjb21wYXJpc29ucy4gDQoNClRoZXJlIGFyZSBkaWZmZXJlbnQgKipQb3N0LWhvYyB0ZXN0cyoqLiBXZSBvbmx5IGludHJvZHVjZSB0d28gY29tbW9ubHkgdXNlZCBwb3N0LWhvYyBtZXRob2RzIHVzaW5nIFIgYnVpbHQtaW4gZnVuY3Rpb25zOg0KDQoqICoqVHVrZXnigJlzIEhvbmVzdCBTaWduaWZpY2FudCBEaWZmZXJlbmNlIChIU0QpKiogLUNvbnRyb2xzICoqZmFtaWx5LXdpc2UgZXJyb3IgcmF0ZSoqIChGV0VSKSBmb3IgYWxsIHBhaXJ3aXNlIGNvbXBhcmlzb25zLg0KDQoqICoqQm9uZmVycm9uaSBDb3JyZWN0aW9uKiogLSBBZGp1c3RzIHAtdmFsdWVzIGJ5IG11bHRpcGx5aW5nIHRoZW0gYnkgdGhlIG51bWJlciBvZiBjb21wYXJpc29ucw0KDQoNCiMgVmlzdWFsIENvbXBhcmlzb24NCg0KV2UgaGF2ZSBsZWFybmVkIGRpZmZlcmVudCBncmFwaGljYWwgc3VtbWFyaWVzIG9mIGRhdGEuIEJveC1wbG90IGlzIGEgZ2VvbWV0cmljIHJlcHJlc2VudGF0aW9uIG9mIHRoZSA1LW51bWJlci1zdW1tYXJ5IG9mIGEgbnVtZXJpY2FsIHZhcmlhYmxlLiBTaW5jZSB0cmVhdG1lbnQgdmFyaWFibGUgaGFzIG11bHRpcGxlIGNhdGVnb3JpZXMsIHdlIGNhbiBjcmVhdGUgYSBiYWNrLXRvLWJhY2sgYm94LXBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaWZmZXJlbnQgaW4gdGhlIGRpc3RyaWJ1dGlvbnMuIA0KDQpUaGUgUiBmdW5jdGlvbiBgYm94cGxvdCgpYCBjYW4gZHJhdyBtdWx0aXBsZSBib3hwbG90cyBvZiBhIG51bWVyaWNhbCB2YXJpYWJsZSBhY2NvcmRpbmcgdGhlIGNhdGVnb3JpZXMgb2YgdGhlIGdyb3VwIHZhcmlhYmxlLiBTaW5jZSBwYWNrYWdlICoqe2dyYXBoaWNzfSoqIGNvbWVzIHdpdGggdGhlIGJhc2UgUiwgaW5zdGFsbGF0aW9uIGFuZCBsb2FkaW5nIHRoZSBwYWNrYWdlIGlzIHVubmVjZXNzYXJ5Lg0KDQpgYGB7cn0NCmJveHBsb3QoTGVuZ3RoIH4gVHJlYXRtZW50LCBkYXRhID0gcGVhLmxvbmcpDQpgYGANCg0KVGhlIGFib3ZlIGJveC1wbG90cyBjbGVhcmx5IHNob3cgdGhhdCB0aGUgcGVhIGxlbmd0aHMgdXNpbmcgc3VnYXIgbWVkaWEgRnJ1Y3Rvc2UsIEdsdWNvc2UsIGFuZCBHbHVjRnJ1YyBhcmUgc2ltaWxhciB0byBlYWNoIG90aGVyLg0KDQoNCg0KIyMgVHVrZXnigJlzIEhvbmVzdCBTaWduaWZpY2FudCBEaWZmZXJlbmNlIChIU0QpDQoNClR1a2V54oCZcyBIb25lc3QgU2lnbmlmaWNhbnQgRGlmZmVyZW5jZSAoSFNEKSBpcyBhIHBvc3QtaG9jIHRlc3QgdXNlZCBhZnRlciBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgQU5PVkEgdG8gZGV0ZXJtaW5lIHdoaWNoIHNwZWNpZmljIGdyb3VwIG1lYW5zIGRpZmZlciBmcm9tIGVhY2ggb3RoZXIuIFVubGlrZSBtdWx0aXBsZSB0LXRlc3RzLCB3aGljaCBpbmZsYXRlIHRoZSBUeXBlIEkgZXJyb3IgcmF0ZSwgVHVrZXnigJlzIEhTRCBhZGp1c3RzIGZvciBtdWx0aXBsZSBjb21wYXJpc29ucywgbWFpbnRhaW5pbmcgdGhlIGZhbWlseS13aXNlIGVycm9yIHJhdGUgKEZXRVIpIGF0IHRoZSBkZXNpcmVkIGxldmVsIChlLmcuLCAwLjA1KS4NCg0KTmV4dCwgd2UgcGVyZm9ybSBhIG11bHRpcGxlIGNvbXBhcmlzb24gb2YgcGVhIGxlbmd0aCBhY3Jvc3MgZGlmZmVyZW50IHN1Z2FyIG1lZGlhIHVzaW5nIHRoZSAqKnBsYW50IHBoeXNpb2xvZ3kgZGF0YSoqLiBGb3IgY29udmVuaWVuY2UsIHdlIHVzZSB0aGUgbG9uZy1mb3JtYXQgZGF0YSBmcmFtZSBkZWZpbmVkIGVhcmxpZXIgYW5kIGFuIGFub3ZhIG9iamVjdCBpbiB0aGUgZm9sbG93aW5nIFIgY29kZS4NCg0KYGBge3J9DQojIyByZWZpdCB0aGUgQU5PVkEgbW9kZWwNCmFvdi5tb2RlbCA8LSBhb3YoTGVuZ3RoIH4gVHJlYXRtZW50LCBkYXRhID0gcGVhLmxvbmcpDQojIyBtdWx0aXBsZSBjb21wYXJpc29uDQp0dWtleS5jb21wIDwtIFR1a2V5SFNEKGFvdi5tb2RlbCkNCnByaW50KHR1a2V5LmNvbXApDQoNCmBgYA0KDQpUaGUgcmVzdWx0cyBpbmRpY2F0ZSB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gcGFpcnMgRnJ1Y3Rvc2UtR2x1Y29zZSwgR2x1Y0ZydWMtR2x1Y29zZSwgYW5kIEdsdWNGcnVjLUZydWN0b3NlLiANCg0KYGBge3J9DQpwYXIobWFpPWMoMS41LDIsMSwxKSkgIyBNYWtlcyByb29tIG9uIHRoZSBwbG90IGZvciB0aGUgZ3JvdXAgbmFtZXMNCnBsb3QodHVrZXkuY29tcCwgICAgICAjIG5hbWUgb2YgdGhlIFR1a2V5SFNEKCkgb2JqZWN0DQogICAgIGNleC5sYWIgPSAwLjYsICAgIyBhZGp1c3QgdGhlIGZvbnQgc2l6ZSBvZiB0aGUgbGFiZWxzIG9mIHRoZSB2ZXJ0aWNhbCBheGlzDQogICAgIGxhcyA9IDEpICAgICAgICAgIyBvcmllbnRhdGlvbiBvZiB0aGUgbGFiZWxzDQpgYGANCg0KDQoNCiMjIEJvbmZlcnJvbmkgQ29tcGFyaXNvbiANCg0KVGhlIEJvbmZlcnJvbmkgY29ycmVjdGlvbiBpcyBhIGNvbnNlcnZhdGl2ZSBtZXRob2QgZm9yIGFkanVzdGluZyBzaWduaWZpY2FuY2UgbGV2ZWxzIHdoZW4gcGVyZm9ybWluZyBtdWx0aXBsZSBjb21wYXJpc29ucyB0byByZWR1Y2UgdGhlIHJpc2sgb2YgVHlwZSBJIGVycm9ycyAoZmFsc2UgcG9zaXRpdmVzKS4gSXQgaXMgb25lIG9mIHRoZSBzaW1wbGVzdCBhbmQgbW9zdCB3aWRlbHkgdXNlZCBhcHByb2FjaGVzIGZvciBjb250cm9sbGluZyB0aGUgZmFtaWx5LXdpc2UgZXJyb3IgcmF0ZS4NCg0KVGhlIFIgZnVuY3Rpb24gYHBhaXJ3aXNlLnQudGVzdCgpYCBwZXJmb3JtcyBwYWlyd2lzZSBjb21wYXJpc29uLiBJdCByZXF1aXJlcyBpbnB1dHRpbmcgaW5kaXZpZHVhbCB2YXJpYWJsZXMgKHJlc3BvbnNlIGFuZCB0cmVhdG1lbnQgZ3JvdXApLiBUaGUgZm9sbG93aW5nIGlzIGNvZGUgZm9yIHRoZSBCb25mZXJyb25pIHByb2NlZHVyZS4NCg0KYGBge3J9DQpCb25mZWVyb25pLnJlc3VsdCA8LSBwYWlyd2lzZS50LnRlc3QoDQogIHggPSBwZWEubG9uZyRMZW5ndGgsIA0KICBnID0gcGVhLmxvbmckVHJlYXRtZW50LA0KICBwLmFkanVzdC5tZXRob2QgPSAiYm9uZmVycm9uaSINCikNCnByaW50KEJvbmZlZXJvbmkucmVzdWx0KQ0KYGBgDQoNClVzaW5nIHRoZSBwLXZhbHVlIGFkanVzdGVkIEJvbmZlcnJvbmkgcHJvY2VkdXJlLCB0aHJlZSBwYWlycyBvZiB0cmVhdG1lbnQgZ3JvdXBzIGFyZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudDogRnJ1Y3Rvc2UtR2x1Y29zZSwgR2x1Y0ZydWMtR2x1Y29zZSwgYW5kIEdsdWNGcnVjLUZydWN0b3NlLiBUaGlzIHJlc3VsdCBpcyBjb25zaXN0ZW50IHdpdGggVHVrZXUncyBIU0QgbWV0aG9kLg0KDQpcDQoNCkJlZm9yZSBjb25jbHVkZSB0aGlzIHNlY3Rpb24sIHdlIHJlY29tbWVuZCBhIFlvdVR1YmUgdmlkZW8gKDxodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PWhQVXZxdG1DdTdRPikgd2l0aCBhbiBleGFtcGxlIG9uZSBtdWx0aXBsZSBjb21wYXJpc29uIGFtb25nIGdyb3VwIG1lYW5zIHVzaW5nIFIsDQoNClwNCg0KPGNlbnRlcj48YSBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PWhQVXZxdG1DdTdRIiB0YXJnZXQ9InBvcHVwIiANCiAgICAgICAgICAgICAgICAgICBvbmNsaWNrPSJ3aW5kb3cub3BlbignaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1oUFV2cXRtQ3U3UScsDQogICAgICAgICAgICAgICAgICAgICAgJ25hbWUnLCd3aWR0aD04NTAsaGVpZ2h0PTUwMCcpIj48aW1nIHNyYyA9ICJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9NQVQxMjFXNS9pbWcvVmlkZW9JY29uLnBuZyIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIxMjAiPjwvYT4NCjwvY2VudGVyPg0KDQpcDQoNCg0KIyBDb25jbHVkaW5nIFJlbWFya3MNCg0KKipPbmUtV2F5IEFOT1ZBKiogKEFuYWx5c2lzIG9mIFZhcmlhbmNlKSBpcyBhIHN0YXRpc3RpY2FsIG1ldGhvZCB1c2VkIHRvIGNvbXBhcmUgdGhlIG1lYW5zIG9mIHRocmVlIG9yIG1vcmUgaW5kZXBlbmRlbnQgZ3JvdXBzIHRvIGRldGVybWluZSBpZiBhdCBsZWFzdCBvbmUgZ3JvdXAgbWVhbiBpcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlcnMuIEl0IGV4dGVuZHMgdGhlIHQtdGVzdCAod2hpY2ggY29tcGFyZXMgb25seSB0d28gZ3JvdXBzKSB0byBtdWx0aXBsZSBncm91cHMuDQoNCkh5cG90aGVzZXMNCg0KKiAqKk51bGwgSHlwb3RoZXNpcyAoJEhfMCQpKio6IEFsbCBncm91cCBtZWFucyBhcmUgZXF1YWwoJFxtdV8xID0gXG11XzIgPSBcY2RvdHMgPSBcbXVfayQpLg0KDQoqICoqQWx0ZXJuYXRpdmUgSHlwb3RoZXNpcyAoJEhfYSQpKio6IEF0IGxlYXN0IG9uZSBncm91cCBtZWFuIGlzIGRpZmZlcmVudC4NCg0KDQpUaGUgZnVuZGFtZW50YWwgYXNzdW1wdGlvbnMgb2YgT25lLVdheSBBTk9WQSBpbmNsdWRlOg0KDQoqICoqSW5kZXBlbmRlbmNlKio6IE9ic2VydmF0aW9ucyBtdXN0IGJlIGluZGVwZW5kZW50IChlLmcuLCByYW5kb20gc2FtcGxpbmcpLg0KDQoqICoqTm9ybWFsaXR5Kio6IERhdGEgaW4gZWFjaCBncm91cCBzaG91bGQgYmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZCAoY2hlY2tlZCB2aWEgUS1RIHBsb3RzIG9yIFNoYXBpcm8tV2lsayB0ZXN0KS4NCg0KKiAqKkhvbW9nZW5laXR5IG9mIFZhcmlhbmNlKiogKEhvbW9zY2VkYXN0aWNpdHkpOiBHcm91cHMgc2hvdWxkIGhhdmUgZXF1YWwgdmFyaWFuY2VzICh0ZXN0ZWQgdXNpbmcgTGV2ZW5l4oCZcyB0ZXN0IG9yIEJhcnRsZXR04oCZcyB0ZXN0KS4NCg0KSWYgYW55IG9mIHRoZXNlcyBhc3N1bXB0aW9ucyBhcmUgdmlvbGF0ZWQsIHRoZSBjbGFzc2ljYWwgQU5PVkEgcmVzdWx0cyB3aWxsIGJlIGludmFsaWQuIFRoZXJlIHNvbWUgYWx0ZXJuYXRpdmVzIG9mIHRoZSBjbGFzc2ljIEFOT1ZBIHRoYXQgd2lsbCBiZSBjb3ZlcmVkIGluIHRoZSBzdWJzZXF1ZW50IHJlbGF0ZWQgY291cnNlcy4gVGhlIGtleSBpbmZvcm1hdGlvbiBpbiB0aGUgQU5PVkEgYW5hbHlzaXMgaXMgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nIG9uZS13YXkgQU5PVkEgdGFibGUuDQoNCmBgYHtyIGVjaG8gPSBGQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjkwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJ3ZWVrMDQvU3VtbWFyaXplZEFOT1ZBdGFibGUucG5nIikNCmBgYA0KDQpJZiBBTk9WQSByZWplY3RzIHRoZSBudWxsIGh5cG90aGVpcywgcG9zdC1ob2MgdGVzdHMgaWRlbnRpZnkgd2hpY2ggc3BlY2lmaWMgZ3JvdXBzIGRpZmZlci4gV2UgaW50cm9kdWNlZCB0d28gcHJjZWR1cmVzIGZvciB0aGlzIHB1cnBvc2UuDQoNCiogKipUdWtleeKAmXMgSFNEKiogKGNvbnRyb2xzIGZhbWlseS13aXNlIGVycm9yIHJhdGUpLg0KDQoqICoqQm9uZmVycm9uaSBDb3JyZWN0aW9uKiogKGNvbnNlcnZhdGl2ZSBhZGp1c3RtZW50KS4NCg0KDQoNCg0KDQoNCg0KDQo=