Introduction
This note covers the definitions and inter-relationships of normal,
t, chi-square, and F distributions, and their assumptions.
Normal
Distrubtions
A normal distribution is a parametric distribution. A parametric
distribution assumes the shape of the distribution. In other words, a
parametric model assumes how the data is organized to make analyses
from.
A normal distribution assumes about:
* 68% of data is 1 standard deviation of the mean
* 95% of the data is 2 standard deviations of the mean
* 99.7% of the data is 3 standard deviations of the mean
(Wackery, Mendenhall, Scheaffer, 1945, p.10).
The assumed normal distribution takes on a bell curve. Demonstrated
by the formula:
\[
f(y) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(y-\mu)^2}{2\sigma^2}}
\]
Note: What is a standard deviation? - A standard deviation measures
how much variation (or how dispersed) a set of values is from the mean.
A lower standard deviation (ig. 1 standard deviation from the mean) is a
value closer to the mean. A value closer the the mean as well as lower
variance may suggest a stronger value or model. As lower variance may
suggest points are clustered tightly around the the mean while higher
variance suggests the data is spread out, potentially containing
outliers.
Assumptions for
Normal Distrubutions
- Data is continuous
- Symmetric with one peak
- Bell Shaped
- Mean, median and mode all assumed to be equal
Using Normal
Distrubutions for Estimation
As the majority of random samples take on a normal distribution as
using a parametric normal distribution as a sole estimator for a true
Cumulative density function (CDF) should come with causation because
assuming the shape of sample may add noise or bias into the estimator
and or analysis, as adding a parameter test may not best hit the sample
and or population.
-Note in most cases the population parameters and or distribution is
unknown.
Although the majority of random samples take on a normal distribution
inherently taking on a parametric distribution as a estimator for a true
Cumulative density function (CDF), always assuming a normal distribution
should come with caution. Assuming the shape of sample, when the sample
distribution shape may be unknown may add noise or bias into the
estimator and or analysis. The a parameter test may not best fit the
sample and or population. If we force a bell-curve onto data that is
actually skewed (leaning to one side instead of symmetric and
non-naturally bell-shaped) our conclusions will hold bias.
Note in many cases the true population’s parameters or distributions
are unknown so assuming shape may increase chance of error.
# https://www.biologyforlife.com/skew.html
knitr::include_graphics("C:/Users/75ER969287/OneDrive - West Chester University of PA/STA 506 - Mathematical Statistics II/Weekly Modules/Week 3/Homework/skewness image image 2.png")

Normal Distrubution
Advantages
Despite a normal distribution being a parametric distribution that
assumes shape, there are many advantages to using a normal
distribution.***********
Uses for a normal distribution
- A normal distribution has act as a comparison and validity checker
- A normal distribution
Often the case for linear regression, t-test and ANOVA residual tests
/
- We will later discuss an normal distribution assumption to assess
the quality of two models by their variance ratio, also known as an F
distribution /
- Overall we often use normal distribution as the bases to make
conclusions or approximations about our distributions because often
samples or population often approach normal distributions and we can
standardize our distributions relatively easily to match a universal
scale for standard deviations. Regardless of the data’s original units,
we can standardize within our data to digest how rare or common a data
point is in respect to the other values.
- Estimation for the Cumulative Distribution Function A normal
distribution can act as an estimator for the cumulative distribution
function. if an empirical CDF is used, the theoretical normal
distribution function can be a base comparison to see if these two are
statistically different.
In this case the empirical CDF is model based on the data observed.
We can compare how well an empirical model compares to a theoretical
normal distribution model to help us understand any nuance in our
observed data.
set.seed(45)
# Generate sample data
sample_data <- rnorm(100, mean = 0, sd = 1)
# Create empirical CDF
empirical_cdf <- ecdf(sample_data)
# Plot empirical vs theoretical CDF
plot_df <- data.frame(
x = seq(-5, 5, length.out = 2500),
Empirical = empirical_cdf(seq(-15, 15, length.out = 2500)),
Theoretical = pnorm(seq(-15, 15, length.out = 2500))
)
plot_df_long <- plot_df %>%
pivot_longer(cols = c(Empirical, Theoretical),
names_to = "Type", values_to = "CDF")
Fn.plt <- ggplot(plot_df_long, aes(x = x, y = CDF, color = Type)) +
geom_line(linewidth = 1) +
scale_color_manual(values = c("Empirical" = "green", "Theoretical" = "purple")) +
labs(title = "Empirical vs Theoretical CDF",
subtitle = "Sample size n = 100 from Standard Normal",
x = "x", y = "CDF") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
ggplotly(Fn.plt)
While the Normal distribution is the foundation of parametric
inference, it can be applied to describe a sampling distribution in two
distinct capacities:
- Exact Distribution: our population distribution is
known to be normally distributed with random variables that are
identically and independently distributed within a small sample size
or
Because we know our population distribution is normal we can
standardize our distribution sample to be under one.
\[
Z = \frac{\bar{X} - \mu}{\sigma / \sqrt{n}} \rightarrow^d N(0,1)
\]
- Asymptotic Distribution our population distribution
is unknown but our sample size is large
Asymptotic
Distribution Relation in Normal Distrubution
As mentioned earlier, there are some advantages to using the normal
distribution despite its shape assumption.
As we take a random sample from the population in which we are not
sure of its distribution, we use the normal distribution as an
approximation for the true distribution.
Due to the large sample size, we can use the Central Limit Theorem to
assume our sample statistic (often our sample mean) approaches and
reaches a normal distribution. Even if in smaller quantities the
distribution may not appear normal, with a large sample size our
distribution my converge to a normal distribution. If an original
population contains skew in its distribution, with a large enough sample
the distribution can place into a bell curve.
# Set a seed so the random results are the same every time you 'knit'
set.seed(12)
# Define number of simulations and different sample sizes to test
n_simulations <- 10000
sample_sizes <- c(2, 5, 20, 50)
# Set up a 2x2 grid for the graphs
par(mfrow = c(2, 2))
for (n in sample_sizes) {
# 1. Take 10,000 random samples of size 'n' from a skewed population
# 2. Calculate the mean for each of those 10,000 samples
sample_means <- replicate(n_simulations, mean(rexp(n, rate = 1)))
# 3. Create the histogram
hist(sample_means,
breaks = 40,
freq = FALSE,
main = paste("Sample Size n =", n),
xlab = "Value of Sample Mean",
col = "skyblue",
border = "white")
# 4. Add a theoretical Normal Curve (Red line) to see the fit
# The mean of our population is 1, and SD is 1.
curve(dnorm(x, mean = 1, sd = 1/sqrt(n)),
add = TRUE, col = "red", lwd = 2)
}

In these images we see as the sample size (n) increases,the
distribution to moves to be less skewed into a more normal
distribution.
As the observed distribution, may not follow a normal distribution
directly we standardize our values into a normal distribution, using the
following formula. Note this formula is an approximation. An
approximation acts as best estimate considering we do not know the true
distribution, unlike the exact distribution.
\[
Z = \frac{\bar{X} - \mu}{\sigma / \sqrt{n}} \rightarrow^{aprox} N(0,1)
\]
By standardizing our values into Z scores, we can approximate our
probability distribution sample statistics, which are values like the
mean, proportion, or regression coefficient.
t-distubution
We used a normal distribution when our population standard deviation
\(\sigma^2\) was known. When we do not
know our population’s standard deviation we use a t
distribution.
When we do not know our population’s standard deviation we estimate
using the sample variance \(S^2\)
.
\[
T = \frac{\bar{X} - \mu}{\ S/ \sqrt{n}} \rightarrow t_{n-1}
\] Our formula for out sample variance \(S^2\) is :
\[
S^2 = \frac {1}{n-1} \sum_{i=1}^{n} ({x_i -\bar{X}})^2
\] In our T distribution since we do not know our population
standard deviation and divide by the sample standard deviation, we must
consider the variation within the sample, which is why we divide \(S\) by the square root of the sample
size.
As the shape of a t-distribution and normal distribution by the naked
eye follow highly similar shapes the formulaic difference of the \(S /\sqrt{n}\) ,in the t distribution
denominator, causes more uncertainty in the distribution leading to
wider “fatter” tails in the t- distribution rather than the normal
distribution. Unlike in the normal distribution where we know the
variance, or spread of data, with the goal of finding the sample mean,
in a t-distribution we neither know the variance nor the sample mean,
leading to a greater chance of uncertainty. Greater uncertainty
ultimately leads us to have fatter tails showing higher variance,
although as n increases this uncertainty is reduced, giving a smaller
standard deviation \(S^2\) ultimately
decreasing the spread in the distribution.
Note as our sample size grows, the tails of the t-distribution get
less fat, often converging closer the a normal distribution. Similar to
our Central Limit Theron where the larger our sample size, the more our
model converges to the normal distribution. The formula component of
\(\sqrt{n}\) assists in changing the
distribution shape, as the level of n contributes to the degrees of
freedom, the only parameter in the t-distribution formula.
Below we compare a t-distribution with a normal distribution. Note
the t-distribution has ‘fatter’ tails.
set.seed(359)
n <- 15
mu <- 5
sigma <- 2
# Generate t-statistics
n.samples <- 10000
t.stats <- numeric(n.samples) # This defines a 10000 dimensional zero vector
# t.test <- NULL uses more computing resource
for(i in 1:n.samples) {
sample.data <- rnorm(n, mu, sigma)
x.bar <- mean(sample.data)
s <- sd(sample.data)
t.stats[i] <- (x.bar - mu) / (s/sqrt(n))
}
# Compare with theoretical t-distribution
x.vals <- seq(-4, 4, length.out = 200)
theoretical.t <- dt(x.vals, df = n-1) # calling t-density function
theoretical.normal <- dnorm(x.vals) # standard normal distribution
comparison.df <- data.frame(
x = rep(x.vals, 2),
density = c(theoretical.t, theoretical.normal),
distribution = rep(c("t(9)", "N(0,1)"), each = length(x.vals))
)
t.plt <- ggplot(comparison.df, aes(x = x, y = density, color = distribution)) +
geom_line(size = 1) +
labs(title = "t-Distribution vs Normal Distribution",
x = "Value", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt")) +
scale_color_manual(values = c("blue", "orange"))
ggplotly(t.plt)
Why our t-distribution connects with the normal distribution?
Our t-distribution in function behaves similarly to the normal
distribution. Our normal standardized formula and normal distribution
formula share a numerator accounting for the distance between the mean
and the observed value ( shared numerator: \(\bar{X} - \mu\)). Even in shape both the t
and normal distributions share a bell curve centered at 0. When the
sample size is large enough a t distribution can become a normal
distribution. Our t-distribution converging to the normal distribution
is valuable because with a large enough sample size, our sample variance
because accurate enough to account as the true population variance,
allowing our statistics to be more accurate as they are closer to the
true population.
Our assumptions of the t-distribution include independent random
observations, random sampling, and that our population is normally
distributed.
As t distributions tend to converge into normal distributions upon
large sample size, often t distributions prior to converging have
smaller sample sizes.
The t-distribution considers estimations for the sample mean, we use
a chi-squared distribution to assess the variance, also known as spread,
of the distribution.
Chi-Squared
Distrubution
A chi-squared distribution is also a distribution type that can
converge into normal distribution. A chi- squared distribution is a
special case of a gamma distribution, in which both distributions have
skewness.
Below is an example of a chi-square distribution:
set.seed(6)
n <- 5
sigma <- 2
# Generate chi-square statistics
n.samples <- 10000
chisq.stats <- numeric(n.samples)
for(i in 1:n.samples) {
sample.data <- rnorm(n, 0, sigma)
chisq.stats[i] <- sum((sample.data/sigma)^2)
}
# Compare with theoretical chi-square
x.vals <- seq(0, 30, length.out = 200)
theoretical.chisq <- dchisq(x.vals, df = n)
theory.df <- data.frame(x = x.vals, density = theoretical.chisq)
chi.plt <- ggplot(data.frame(x = chisq.stats), aes(x = x)) +
geom_histogram(aes(y = ..density..), bins = 50, alpha = 0.7, fill = "green") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "blue", linewidth = 1.5) +
#stat_function(fun = dchisq, args = list(df = n), color = "red", size = 1) +
labs(title = "Chi-Squared Distribution (n=5) ",
subtitle = "Sum of squared standard normals",
x = "Value", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
ggplotly(chi.plt)
An increase in sample size can lead to a normal distribution, as
increase in sample size reduces the skewness.
set.seed(6)
n <- 500
sigma <- 2
# Generate chi-square statistics
n.samples <- 10000
chisq.stats <- numeric(n.samples)
for(i in 1:n.samples) {
sample.data <- rnorm(n, 0, sigma)
chisq.stats[i] <- sum((sample.data/sigma)^2)
}
# Compare with theoretical chi-square
x.vals <- seq(0, 1100, length.out = 200)
theoretical.chisq <- dchisq(x.vals, df = n)
theory.df <- data.frame(x = x.vals, density = theoretical.chisq)
chi.plt <- ggplot(data.frame(x = chisq.stats), aes(x = x)) +
geom_histogram(aes(y = ..density..), bins = 50, alpha = 0.7, fill = "green") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "blue", linewidth =1.5) +
#stat_function(fun = dchisq, args = list(df = n), color = "red", size = 1) +
labs(title = "Chi-Squared Distribution (n=500) ",
subtitle = "Sum of squared standard normals",
x = "Value", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
ggplotly(chi.plt)
A chi-square distribution can derive from an exact normal
distribution. It can essentially act as a squared standard normal with
one degree of freedom or a sum of squares with more than 1 degree of
freedom, adding skewness to a normal distribution. As the chi-square is
a squared normal, the distribution can never be negative, exaggerating
any right skewness. In other words, a chi-squared distribution can be
described as a normal distribution, whose center has moved and now
possesses skewness.
In contribution that the variance is a squared parameter, the
sampling distribution of the sample variance can be described as a
chi-square distribution upon scaling. When our sample size increases,the
degree of freedom parameter \((n-1)\)
in our numerator increases. The Central Limit Theorem helps our
chi-squared distribution take on a normal distribution, smoothing the
skewness into a bell-shape, as the sample size increase.
Our chi-square distribution relationship with a normal
distribution:
\[
\frac{(n-1)S^2}{\sigma^2} \rightarrow \chi^2_{n-1}
\]
Like a t-distribution, our assumptions about a chi-square
distribution is that we sample from a normally distributed population as
well as individually and independently distributed. The chi-squared and
t-distribution have degrees of freedom in their parameters, dictating
the shapes of their distributions.
F distrubution
With our chi-squared distribution we see the variance of our
distribution. Often we have multiple distributions and we need to relate
the variances to each other to see quality of the two distributions.
Hence we build a F distribution as a ratio of two chi-squared variables
of independent sample variances. Like the individual chi-squared, both
assume normal distribution. These chi-squared distributions source from
independent populations.
\[
{X_1, X_2, ...X_n} ~ ^{i.i.d} N(\mu_2, \sigma^2_1) \\ and \\{Y_1, Y_2,
...Y_n} ~ ^{i.i.d} N(\mu_2, \sigma^2_2)
\] \[
S^2_1 = \frac {1}{n_1-1} \sum_{i=1}^{n} ({X_i -\bar{X}})^2 \\and\\
S^2_2 = \frac {1}{n_2-1} \sum_{i=1}^{n} ({Y_i -\bar{Y}})^2
\] Define \[
F= \frac {S^2_1/ \sigma^2} {S^2_2/\sigma^2_2} \rightarrow^d F_{n-1,
n_2-1}
\]
The 1 degree of freedom each chi-squares hold in the F-distribution
give us 2 degrees of freedom (one in the denominator, and one in the
numerator) that both contribute to the distribution’s shape.
In the greater the F distribution ratio, the more variance in the
numerator’s distribution. The smaller the variance the variance is
larger in the denominator distribution. If the F distribution ratio is
1, the two variances in the numerator and denominator are equal.
set.seed(45)
df1 <- 20
df2 <- 25
# Generate F statistics
n.samples <- 10000
f.stats <- numeric(n.samples)
for(i in 1:n.samples) {
u1 <- rchisq(1, df1)
u2 <- rchisq(1, df2)
f.stats[i] <- (u1/df1) / (u2/df2)
}
# Compare with theoretical F-distribution
x.vals <- seq(0, 5, length.out = 200)
theoretical.f <- df(x.vals, df1, df2)
theory.df <- data.frame(x = x.vals, density = theoretical.f)
f.plt <- ggplot(data.frame(x = f.stats), aes(x = x)) +
geom_histogram(aes(y = ..density..), bins = 50, alpha = 0.7, fill = "blue") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "red", linewidth = 1) +
coord_cartesian(xlim = c(0, 5)) +
labs(title = paste("F-Distribution \n F(", df1, ",", df2, ")", sep = ""),
x = "Value", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
ggplotly(f.plt)
Conclusion
Assuming a normal distribution allows us to connect a t distribution
to a normal distribution. A normal distribution can be used towards a
chi- squared distribution to assess model variance and two chi-square
tests can be used in an F distribution ratio to assess the overall
quality of two distributions.
The normal distribution builds into advanced analyse that allow us to
consider the quality of our distribution. Without a standardized
distribution shape that the normal distribution gives us, making these
comparisons would be challenging, especially through various unit types.
Our normal distribution allows us to organize our distribution for
analysis, and test the quality of an observed data set either through
approximation or theoretical comparison.
LS0tDQp0aXRsZTogIkhvbWV3b3JrIDIiDQphdXRob3I6ICJFemFuYSBSaXZlcnMiDQpkYXRlOiAiMDItMTAtMjAyNiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KI1RPQzo6YmVmb3JlIHsNCiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc2l6ZTogMS4yZW07DQogIGRpc3BsYXk6IGJsb2NrOw0KICBjb2xvcjogbmF2eTsNCiAgbWFyZ2luLWJvdHRvbTogMTBweDsNCn0NCg0KDQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovDQogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQoNCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovDQogIGZvbnQtc2l6ZTogMjJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxNXB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0NCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQoNCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgbGlicmFyeShwbG90bHkpDQp9DQppZiAoIXJlcXVpcmUoIm1peHRvb2xzIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygibWl4dG9vbHMiKQ0KICBsaWJyYXJ5KG1peHRvb2xzKQ0KfQ0KDQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KDQoNCmlmICghcmVxdWlyZSgiZ2dhbmltYXRlIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikNCiAgbGlicmFyeShnZ2FuaW1hdGUpDQp9DQoNCmlmICghcmVxdWlyZSgiZ2lmc2tpIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikNCiAgbGlicmFyeShnaWZza2kpDQp9DQoNCg0KIyMgbGlicmFyeShtaXh0b29scykNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KDQojIFlvdSB3aWxsIG5lZWQgdGhlc2UgcGFja2FnZXMgaW5zdGFsbGVkOg0KIyBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiMgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikNCg0KDQoNCmBgYA0KDQpcDQoNCg0KIyBJbnRyb2R1Y3Rpb24NCg0KVGhpcyBub3RlIGNvdmVycyB0aGUgZGVmaW5pdGlvbnMgYW5kIGludGVyLXJlbGF0aW9uc2hpcHMgb2Ygbm9ybWFsLCB0LCBjaGktc3F1YXJlLCBhbmQgRiBkaXN0cmlidXRpb25zLCBhbmQgdGhlaXIgYXNzdW1wdGlvbnMuDQoNCg0KIyBOb3JtYWwgRGlzdHJ1YnRpb25zDQoNCkEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyBhIHBhcmFtZXRyaWMgZGlzdHJpYnV0aW9uLiBBIHBhcmFtZXRyaWMgZGlzdHJpYnV0aW9uIGFzc3VtZXMgdGhlIHNoYXBlIG9mIHRoZSBkaXN0cmlidXRpb24uIEluIG90aGVyIHdvcmRzLCBhIHBhcmFtZXRyaWMgbW9kZWwgYXNzdW1lcyBob3cgdGhlIGRhdGEgaXMgb3JnYW5pemVkIHRvIG1ha2UgYW5hbHlzZXMgZnJvbS4NCg0KQSBub3JtYWwgZGlzdHJpYnV0aW9uIGFzc3VtZXMgYWJvdXQ6DQpcDQogICogNjglIG9mIGRhdGEgaXMgMSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIG1lYW4gDQpcDQogICogOTUlIG9mIHRoZSBkYXRhIGlzIDIgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiB0aGUgbWVhbiANClwNCiAgKiA5OS43JSBvZiB0aGUgZGF0YSBpcyAzIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgdGhlIG1lYW4gDQpcDQooV2Fja2VyeSwgTWVuZGVuaGFsbCwgU2NoZWFmZmVyLCAxOTQ1LCBwLjEwKS4NCg0KICANCmBgYHtyIEltYWdlLCBlY2hvPUZBTFNFLCBmaWcuY2FwPSIgTm9ybWFsIERpc3RydWJ0aW9uIiwgb3V0LndpZHRoPSc3MCUnLCBmaWcuYWxpZ249J2NlbnRlcid9DQogIA0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzLzc1RVI5NjkyODcvT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQS9TVEEgNTA2IC0gTWF0aGVtYXRpY2FsIFN0YXRpc3RpY3MgSUkvV2Vla2x5IE1vZHVsZXMvV2VlayAzL0hvbWV3b3JrL0ltYWdlIDEgbm9ybWFsIGRpc3RydWJ0aW9uIGZvciBhc3NpZ25lbWVudCAyLnBuZyIpDQoNCiNjZW50ZXIgdGhpcyBpbWFnZQ0KDQpgYGANClRoZSBhc3N1bWVkIG5vcm1hbCBkaXN0cmlidXRpb24gdGFrZXMgb24gYSBiZWxsIGN1cnZlLiBEZW1vbnN0cmF0ZWQgYnkgdGhlIGZvcm11bGE6DQoNCiQkDQpmKHkpID0gXGZyYWN7MX17XHNpZ21hXHNxcnR7MlxwaX19IGVeey1cZnJhY3soeS1cbXUpXjJ9ezJcc2lnbWFeMn19DQokJA0KDQpOb3RlOiBXaGF0IGlzIGEgc3RhbmRhcmQgZGV2aWF0aW9uPyANCiAgLSBBIHN0YW5kYXJkIGRldmlhdGlvbiBtZWFzdXJlcyBob3cgbXVjaCB2YXJpYXRpb24gKG9yIGhvdyBkaXNwZXJzZWQpIGEgc2V0IG9mIHZhbHVlcyBpcyBmcm9tIHRoZSBtZWFuLiBBIGxvd2VyIHN0YW5kYXJkIGRldmlhdGlvbiAoaWcuIDEgc3RhbmRhcmQgZGV2aWF0aW9uIGZyb20gdGhlIG1lYW4pIGlzIGEgdmFsdWUgY2xvc2VyIHRvIHRoZSBtZWFuLiBBIHZhbHVlIGNsb3NlciB0aGUgdGhlIG1lYW4gYXMgd2VsbCBhcyBsb3dlciB2YXJpYW5jZSBtYXkgc3VnZ2VzdCBhIHN0cm9uZ2VyIHZhbHVlIG9yIG1vZGVsLiBBcyBsb3dlciB2YXJpYW5jZSBtYXkgc3VnZ2VzdCBwb2ludHMgYXJlIGNsdXN0ZXJlZCB0aWdodGx5IGFyb3VuZCB0aGUgdGhlIG1lYW4gd2hpbGUgaGlnaGVyIHZhcmlhbmNlIHN1Z2dlc3RzIHRoZSBkYXRhIGlzIHNwcmVhZCBvdXQsIHBvdGVudGlhbGx5IGNvbnRhaW5pbmcgb3V0bGllcnMuDQogIA0KDQoNCiMjIEFzc3VtcHRpb25zIGZvciBOb3JtYWwgRGlzdHJ1YnV0aW9ucw0KICAxLiBEYXRhIGlzIGNvbnRpbnVvdXMNCiAgMi4gU3ltbWV0cmljIHdpdGggb25lIHBlYWsNCiAgMy4gQmVsbCBTaGFwZWQNCiAgNC4gTWVhbiwgbWVkaWFuIGFuZCBtb2RlIGFsbCBhc3N1bWVkIHRvIGJlIGVxdWFsICANCg0KDQoNCiMgVXNpbmcgTm9ybWFsIERpc3RydWJ1dGlvbnMgZm9yIEVzdGltYXRpb24NCg0KDQpBcyB0aGUgbWFqb3JpdHkgb2YgcmFuZG9tIHNhbXBsZXMgdGFrZSBvbiBhIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgdXNpbmcgYSBwYXJhbWV0cmljIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgYSBzb2xlIGVzdGltYXRvciBmb3IgYSB0cnVlIEN1bXVsYXRpdmUgZGVuc2l0eSBmdW5jdGlvbiAoQ0RGKSBzaG91bGQgY29tZSB3aXRoIGNhdXNhdGlvbiBiZWNhdXNlIGFzc3VtaW5nIHRoZSBzaGFwZSBvZiBzYW1wbGUgbWF5IGFkZCBub2lzZSBvciBiaWFzIGludG8gdGhlIGVzdGltYXRvciBhbmQgb3IgYW5hbHlzaXMsIGFzIGFkZGluZyBhIHBhcmFtZXRlciB0ZXN0IG1heSBub3QgYmVzdCBoaXQgdGhlIHNhbXBsZSBhbmQgb3IgcG9wdWxhdGlvbi4NCg0KLU5vdGUgaW4gbW9zdCBjYXNlcyB0aGUgcG9wdWxhdGlvbiBwYXJhbWV0ZXJzIGFuZCBvciBkaXN0cmlidXRpb24gaXMgdW5rbm93bi4NCiAgDQoNCkFsdGhvdWdoIHRoZSBtYWpvcml0eSBvZiByYW5kb20gc2FtcGxlcyB0YWtlIG9uIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpbmhlcmVudGx5IHRha2luZyBvbiBhIHBhcmFtZXRyaWMgZGlzdHJpYnV0aW9uIGFzIGEgZXN0aW1hdG9yIGZvciBhIHRydWUgQ3VtdWxhdGl2ZSBkZW5zaXR5IGZ1bmN0aW9uIChDREYpLCBhbHdheXMgYXNzdW1pbmcgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHNob3VsZCBjb21lIHdpdGggY2F1dGlvbi4gQXNzdW1pbmcgdGhlIHNoYXBlIG9mIHNhbXBsZSwgd2hlbiB0aGUgc2FtcGxlIGRpc3RyaWJ1dGlvbiBzaGFwZSBtYXkgYmUgdW5rbm93biBtYXkgYWRkIG5vaXNlIG9yIGJpYXMgaW50byB0aGUgZXN0aW1hdG9yIGFuZCBvciBhbmFseXNpcy4gVGhlIGEgcGFyYW1ldGVyIHRlc3QgbWF5IG5vdCBiZXN0IGZpdCB0aGUgc2FtcGxlIGFuZCBvciBwb3B1bGF0aW9uLiBJZiB3ZSBmb3JjZSBhIGJlbGwtY3VydmUgb250byBkYXRhIHRoYXQgaXMgYWN0dWFsbHkgc2tld2VkIChsZWFuaW5nIHRvIG9uZSBzaWRlIGluc3RlYWQgb2Ygc3ltbWV0cmljIGFuZCBub24tbmF0dXJhbGx5IGJlbGwtc2hhcGVkKSBvdXIgY29uY2x1c2lvbnMgd2lsbCBob2xkIGJpYXMuIA0KDQpOb3RlIGluIG1hbnkgY2FzZXMgdGhlIHRydWUgcG9wdWxhdGlvbidzIHBhcmFtZXRlcnMgb3IgZGlzdHJpYnV0aW9ucyBhcmUgdW5rbm93biBzbyBhc3N1bWluZyBzaGFwZSBtYXkgaW5jcmVhc2UgY2hhbmNlIG9mIGVycm9yLg0KDQoNCmBgYHtyIGltYWdlc2tldywgb3V0LndpZHRoPSc3MCUnLCBmaWcuYWxpZ249J2NlbnRlcid9DQoNCiMgaHR0cHM6Ly93d3cuYmlvbG9neWZvcmxpZmUuY29tL3NrZXcuaHRtbA0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMvNzVFUjk2OTI4Ny9PbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBL1NUQSA1MDYgLSBNYXRoZW1hdGljYWwgU3RhdGlzdGljcyBJSS9XZWVrbHkgTW9kdWxlcy9XZWVrIDMvSG9tZXdvcmsvc2tld25lc3MgaW1hZ2UgaW1hZ2UgMi5wbmciKQ0KDQpgYGANCiAgDQoNCg0KIyMgTm9ybWFsIERpc3RydWJ1dGlvbiBBZHZhbnRhZ2VzIA0KDQpEZXNwaXRlIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBiZWluZyBhIHBhcmFtZXRyaWMgZGlzdHJpYnV0aW9uIHRoYXQgYXNzdW1lcyBzaGFwZSwgdGhlcmUgYXJlIG1hbnkgYWR2YW50YWdlcyB0byB1c2luZyBhIG5vcm1hbCBkaXN0cmlidXRpb24uKioqKioqKioqKioNCg0KVXNlcyBmb3IgYSBub3JtYWwgZGlzdHJpYnV0aW9uIA0KDQotIEEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBoYXMgYWN0IGFzIGEgY29tcGFyaXNvbiBhbmQgdmFsaWRpdHkgY2hlY2tlciANCiAgICAqICAgQSBub3JtYWwgZGlzdHJpYnV0aW9uICANCiAgICAgICAgT2Z0ZW4gdGhlIGNhc2UgZm9yIGxpbmVhciByZWdyZXNzaW9uLCB0LXRlc3QgYW5kIEFOT1ZBIHJlc2lkdWFsIHRlc3RzDQovDQogICAgKiBXZSB3aWxsIGxhdGVyIGRpc2N1c3MgYW4gbm9ybWFsIGRpc3RyaWJ1dGlvbiBhc3N1bXB0aW9uIHRvIGFzc2VzcyB0aGUgcXVhbGl0eSBvZiB0d28gbW9kZWxzIGJ5IHRoZWlyIHZhcmlhbmNlIHJhdGlvLCBhbHNvIGtub3duIGFzIGFuIEYgZGlzdHJpYnV0aW9uIA0KLw0KICAgICogT3ZlcmFsbCB3ZSBvZnRlbiB1c2Ugbm9ybWFsIGRpc3RyaWJ1dGlvbiBhcyB0aGUgYmFzZXMgdG8gbWFrZSBjb25jbHVzaW9ucyBvciBhcHByb3hpbWF0aW9ucyBhYm91dCBvdXIgZGlzdHJpYnV0aW9ucyBiZWNhdXNlIG9mdGVuIHNhbXBsZXMgb3IgcG9wdWxhdGlvbiBvZnRlbiBhcHByb2FjaCBub3JtYWwgZGlzdHJpYnV0aW9ucyBhbmQgd2UgY2FuIHN0YW5kYXJkaXplIG91ciBkaXN0cmlidXRpb25zIHJlbGF0aXZlbHkgZWFzaWx5IHRvIG1hdGNoIGEgdW5pdmVyc2FsIHNjYWxlIGZvciBzdGFuZGFyZCBkZXZpYXRpb25zLiBSZWdhcmRsZXNzIG9mIHRoZSBkYXRhJ3Mgb3JpZ2luYWwgdW5pdHMsIHdlIGNhbiBzdGFuZGFyZGl6ZSB3aXRoaW4gb3VyIGRhdGEgdG8gZGlnZXN0IGhvdyByYXJlIG9yIGNvbW1vbiBhIGRhdGEgcG9pbnQgaXMgaW4gcmVzcGVjdCB0byB0aGUgb3RoZXIgdmFsdWVzLg0KICAgIA0KDQotIEVzdGltYXRpb24gZm9yIHRoZSBDdW11bGF0aXZlIERpc3RyaWJ1dGlvbiBGdW5jdGlvbg0KICBBIG5vcm1hbCBkaXN0cmlidXRpb24gY2FuIGFjdCBhcyBhbiBlc3RpbWF0b3IgZm9yIHRoZSBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbi4gIGlmIGFuIGVtcGlyaWNhbCBDREYgaXMgdXNlZCwgdGhlIHRoZW9yZXRpY2FsIG5vcm1hbCBkaXN0cmlidXRpb24gZnVuY3Rpb24gY2FuIGJlIGEgYmFzZSBjb21wYXJpc29uIHRvIHNlZSBpZiB0aGVzZSB0d28gYXJlIHN0YXRpc3RpY2FsbHkgZGlmZmVyZW50LiANCg0KSW4gdGhpcyBjYXNlIHRoZSBlbXBpcmljYWwgQ0RGIGlzIG1vZGVsIGJhc2VkIG9uIHRoZSBkYXRhIG9ic2VydmVkLiBXZSBjYW4gY29tcGFyZSBob3cgd2VsbCBhbiBlbXBpcmljYWwgbW9kZWwgY29tcGFyZXMgdG8gYSB0aGVvcmV0aWNhbCBub3JtYWwgZGlzdHJpYnV0aW9uIG1vZGVsIHRvIGhlbHAgdXMgdW5kZXJzdGFuZCBhbnkgbnVhbmNlIGluIG91ciBvYnNlcnZlZCBkYXRhLiANCg0KYGBge3J9DQoNCnNldC5zZWVkKDQ1KQ0KIyBHZW5lcmF0ZSBzYW1wbGUgZGF0YQ0Kc2FtcGxlX2RhdGEgPC0gcm5vcm0oMTAwLCBtZWFuID0gMCwgc2QgPSAxKQ0KDQojIENyZWF0ZSBlbXBpcmljYWwgQ0RGDQplbXBpcmljYWxfY2RmIDwtIGVjZGYoc2FtcGxlX2RhdGEpDQoNCiMgUGxvdCBlbXBpcmljYWwgdnMgdGhlb3JldGljYWwgQ0RGDQpwbG90X2RmIDwtIGRhdGEuZnJhbWUoDQogIHggPSBzZXEoLTUsIDUsIGxlbmd0aC5vdXQgPSAyNTAwKSwNCiAgRW1waXJpY2FsID0gZW1waXJpY2FsX2NkZihzZXEoLTE1LCAxNSwgbGVuZ3RoLm91dCA9IDI1MDApKSwNCiAgVGhlb3JldGljYWwgPSBwbm9ybShzZXEoLTE1LCAxNSwgbGVuZ3RoLm91dCA9IDI1MDApKQ0KKQ0KDQpwbG90X2RmX2xvbmcgPC0gcGxvdF9kZiAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKEVtcGlyaWNhbCwgVGhlb3JldGljYWwpLCANCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlR5cGUiLCB2YWx1ZXNfdG8gPSAiQ0RGIikNCg0KRm4ucGx0IDwtIGdncGxvdChwbG90X2RmX2xvbmcsIGFlcyh4ID0geCwgeSA9IENERiwgY29sb3IgPSBUeXBlKSkgKw0KICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiRW1waXJpY2FsIiA9ICJncmVlbiIsICJUaGVvcmV0aWNhbCIgPSAicHVycGxlIikpICsNCiAgbGFicyh0aXRsZSA9ICJFbXBpcmljYWwgdnMgVGhlb3JldGljYWwgQ0RGIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJTYW1wbGUgc2l6ZSBuID0gMTAwIGZyb20gU3RhbmRhcmQgTm9ybWFsIiwNCiAgICAgICB4ID0gIngiLCB5ID0gIkNERiIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSAzNSwgciA9IDIwLCBiID0gMzAsIGwgPSAzMCwgdW5pdCA9ICJwdCIpKQ0KZ2dwbG90bHkoRm4ucGx0KQ0KDQoNCmBgYA0KDQoNCg0KDQpXaGlsZSB0aGUgTm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyB0aGUgZm91bmRhdGlvbiBvZiBwYXJhbWV0cmljIGluZmVyZW5jZSwgaXQgY2FuIGJlIGFwcGxpZWQgdG8gZGVzY3JpYmUgYSBzYW1wbGluZyBkaXN0cmlidXRpb24gaW4gdHdvIGRpc3RpbmN0IGNhcGFjaXRpZXM6DQogIA0KICANCjEuICoqRXhhY3QgRGlzdHJpYnV0aW9uKio6IG91ciBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBpcyBrbm93biB0byBiZSBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoIHJhbmRvbSB2YXJpYWJsZXMgdGhhdCBhcmUgaWRlbnRpY2FsbHkgYW5kIGluZGVwZW5kZW50bHkgZGlzdHJpYnV0ZWQgd2l0aGluIGEgc21hbGwgc2FtcGxlIHNpemUgb3INCg0KQmVjYXVzZSB3ZSBrbm93IG91ciBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBpcyBub3JtYWwgd2UgY2FuIHN0YW5kYXJkaXplIG91ciBkaXN0cmlidXRpb24gIHNhbXBsZSB0byBiZSB1bmRlciBvbmUuIA0KDQokJA0KWiA9IFxmcmFje1xiYXJ7WH0gLSBcbXV9e1xzaWdtYSAvIFxzcXJ0e259fSBccmlnaHRhcnJvd15kIE4oMCwxKQ0KJCQNCg0KDQoNCg0KMi4gKipBc3ltcHRvdGljIERpc3RyaWJ1dGlvbioqIG91ciBwb3B1bGF0aW9uIGRpc3RyaWJ1dGlvbiBpcyB1bmtub3duIGJ1dCBvdXIgc2FtcGxlIHNpemUgaXMgbGFyZ2UNCg0KDQojIyBFeHRyYWN0IERpc3RydWJ0aW9uIA0KICBBIGV4YWN0IGRpc3RyaWJ1dGlvbiBhc3N1bWVzIGEgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgcG9wdWxhdGlvbiB3aXRoIHJhbmRvbSB2YXJpYWJsZXMgdGhhdCBhcmUgaWRlbnRpY2FsbHkgYW5kIGluZGVwZW5kZW50bHkgZGlzdHJpYnV0ZWQgd2l0aGluIGEgc21hbGwgc2FtcGxlIHNpemUuIE91ciByYW5kb20gdmFyaWFibGVzIGFyZSBjb2xsZWN0ZWQgYW5kIHRyZWF0ZWQgaW5kZXBlbmRlbnRseSwgYXMgdGhlIHByb2JhYmlsaXR5IG9mIHRoZSBvbmUgdmFsdWUgZG9lcyBub3QgZWZmZWN0IHRoZSBwcm9iYWJpbGl0eSBvZiB0aGUgbmV4dCB2YWx1ZS4NCg0KIyMgQXN5bXB0b3RpYyBEaXN0cmlidXRpb24gUmVsYXRpb24gaW4gTm9ybWFsIERpc3RydWJ1dGlvbg0KQXMgbWVudGlvbmVkIGVhcmxpZXIsIHRoZXJlIGFyZSBzb21lIGFkdmFudGFnZXMgdG8gdXNpbmcgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gZGVzcGl0ZSBpdHMgc2hhcGUgYXNzdW1wdGlvbi4NCg0KQXMgd2UgdGFrZSBhIHJhbmRvbSBzYW1wbGUgZnJvbSB0aGUgcG9wdWxhdGlvbiBpbiB3aGljaCB3ZSBhcmUgbm90IHN1cmUgb2YgaXRzIGRpc3RyaWJ1dGlvbiwgd2UgdXNlIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGFzIGFuIGFwcHJveGltYXRpb24gZm9yIHRoZSB0cnVlIGRpc3RyaWJ1dGlvbi4gDQoNCkR1ZSB0byB0aGUgbGFyZ2Ugc2FtcGxlIHNpemUsIHdlIGNhbiB1c2UgdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSB0byBhc3N1bWUgb3VyIHNhbXBsZSBzdGF0aXN0aWMgKG9mdGVuIG91ciBzYW1wbGUgbWVhbikgYXBwcm9hY2hlcyBhbmQgcmVhY2hlcyBhIG5vcm1hbCBkaXN0cmlidXRpb24uIEV2ZW4gaWYgaW4gc21hbGxlciBxdWFudGl0aWVzIHRoZSBkaXN0cmlidXRpb24gbWF5IG5vdCBhcHBlYXIgbm9ybWFsLCB3aXRoIGEgbGFyZ2Ugc2FtcGxlIHNpemUgb3VyIGRpc3RyaWJ1dGlvbiBteSBjb252ZXJnZSB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24uIElmIGFuIG9yaWdpbmFsIHBvcHVsYXRpb24gY29udGFpbnMgc2tldyBpbiBpdHMgZGlzdHJpYnV0aW9uLCB3aXRoIGEgbGFyZ2UgZW5vdWdoIHNhbXBsZSB0aGUgZGlzdHJpYnV0aW9uIGNhbiBwbGFjZSBpbnRvIGEgYmVsbCBjdXJ2ZS4NCg0KYGBge3IgfQ0KIyBTZXQgYSBzZWVkIHNvIHRoZSByYW5kb20gcmVzdWx0cyBhcmUgdGhlIHNhbWUgZXZlcnkgdGltZSB5b3UgJ2tuaXQnDQpzZXQuc2VlZCgxMikNCg0KIyBEZWZpbmUgbnVtYmVyIG9mIHNpbXVsYXRpb25zIGFuZCBkaWZmZXJlbnQgc2FtcGxlIHNpemVzIHRvIHRlc3QNCm5fc2ltdWxhdGlvbnMgPC0gMTAwMDANCnNhbXBsZV9zaXplcyA8LSBjKDIsIDUsIDIwLCA1MCkNCg0KIyBTZXQgdXAgYSAyeDIgZ3JpZCBmb3IgdGhlIGdyYXBocw0KcGFyKG1mcm93ID0gYygyLCAyKSkNCg0KZm9yIChuIGluIHNhbXBsZV9zaXplcykgew0KICAjIDEuIFRha2UgMTAsMDAwIHJhbmRvbSBzYW1wbGVzIG9mIHNpemUgJ24nIGZyb20gYSBza2V3ZWQgcG9wdWxhdGlvbg0KICAjIDIuIENhbGN1bGF0ZSB0aGUgbWVhbiBmb3IgZWFjaCBvZiB0aG9zZSAxMCwwMDAgc2FtcGxlcw0KICBzYW1wbGVfbWVhbnMgPC0gcmVwbGljYXRlKG5fc2ltdWxhdGlvbnMsIG1lYW4ocmV4cChuLCByYXRlID0gMSkpKQ0KICANCiAgIyAzLiBDcmVhdGUgdGhlIGhpc3RvZ3JhbQ0KICBoaXN0KHNhbXBsZV9tZWFucywgDQogICAgICAgYnJlYWtzID0gNDAsIA0KICAgICAgIGZyZXEgPSBGQUxTRSwgDQogICAgICAgbWFpbiA9IHBhc3RlKCJTYW1wbGUgU2l6ZSBuID0iLCBuKSwNCiAgICAgICB4bGFiID0gIlZhbHVlIG9mIFNhbXBsZSBNZWFuIiwgDQogICAgICAgY29sID0gInNreWJsdWUiLCANCiAgICAgICBib3JkZXIgPSAid2hpdGUiKQ0KICANCiAgIyA0LiBBZGQgYSB0aGVvcmV0aWNhbCBOb3JtYWwgQ3VydmUgKFJlZCBsaW5lKSB0byBzZWUgdGhlIGZpdA0KICAjIFRoZSBtZWFuIG9mIG91ciBwb3B1bGF0aW9uIGlzIDEsIGFuZCBTRCBpcyAxLg0KICBjdXJ2ZShkbm9ybSh4LCBtZWFuID0gMSwgc2QgPSAxL3NxcnQobikpLCANCiAgICAgICAgYWRkID0gVFJVRSwgY29sID0gInJlZCIsIGx3ZCA9IDIpDQp9DQoNCg0KYGBgDQoNCkluIHRoZXNlIGltYWdlcyB3ZSBzZWUgYXMgdGhlIHNhbXBsZSBzaXplIChuKSBpbmNyZWFzZXMsdGhlIGRpc3RyaWJ1dGlvbiB0byBtb3ZlcyB0byBiZSBsZXNzIHNrZXdlZCBpbnRvIGEgbW9yZSBub3JtYWwgZGlzdHJpYnV0aW9uLiANCg0KDQpBcyB0aGUgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uLCBtYXkgbm90IGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24gZGlyZWN0bHkgd2Ugc3RhbmRhcmRpemUgb3VyIHZhbHVlcyBpbnRvIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdXNpbmcgdGhlIGZvbGxvd2luZyBmb3JtdWxhLiBOb3RlIHRoaXMgZm9ybXVsYSBpcyBhbiBhcHByb3hpbWF0aW9uLiBBbiBhcHByb3hpbWF0aW9uIGFjdHMgYXMgYmVzdCBlc3RpbWF0ZSBjb25zaWRlcmluZyB3ZSBkbyBub3Qga25vdyB0aGUgdHJ1ZSBkaXN0cmlidXRpb24sIHVubGlrZSB0aGUgZXhhY3QgZGlzdHJpYnV0aW9uLg0KDQoNCiQkDQpaID0gXGZyYWN7XGJhcntYfSAtIFxtdX17XHNpZ21hIC8gXHNxcnR7bn19IFxyaWdodGFycm93XnthcHJveH0gTigwLDEpDQokJA0KDQpCeSBzdGFuZGFyZGl6aW5nIG91ciB2YWx1ZXMgaW50byBaIHNjb3Jlcywgd2UgY2FuIGFwcHJveGltYXRlIG91ciBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gc2FtcGxlIHN0YXRpc3RpY3MsIHdoaWNoIGFyZSB2YWx1ZXMgbGlrZSB0aGUgbWVhbiwgcHJvcG9ydGlvbiwgb3IgcmVncmVzc2lvbiBjb2VmZmljaWVudC4NCg0KDQoNCg0KDQojIHQtZGlzdHVidXRpb24gDQoNCldlIHVzZWQgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdoZW4gb3VyIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uICRcc2lnbWFeMiQgd2FzIGtub3duLiBXaGVuIHdlIGRvIG5vdCBrbm93IG91ciBwb3B1bGF0aW9uJ3Mgc3RhbmRhcmQgZGV2aWF0aW9uIHdlIHVzZSBhICoqdCBkaXN0cmlidXRpb24qKi4gDQoNCldoZW4gd2UgZG8gbm90IGtub3cgb3VyIHBvcHVsYXRpb24ncyBzdGFuZGFyZCBkZXZpYXRpb24gd2UgZXN0aW1hdGUgdXNpbmcgdGhlIHNhbXBsZSB2YXJpYW5jZSAkU14yJCAuICANCiQkDQogIFQgPSBcZnJhY3tcYmFye1h9IC0gXG11fXtcIFMvIFxzcXJ0e259fSAgXHJpZ2h0YXJyb3cgdF97bi0xfQ0KJCQNCk91ciBmb3JtdWxhIGZvciBvdXQgc2FtcGxlIHZhcmlhbmNlICRTXjIkIGlzIDoNCg0KJCQNClNeMiA9IFxmcmFjIHsxfXtuLTF9IFxzdW1fe2k9MX1ee259ICh7eF9pIC1cYmFye1h9fSleMg0KJCQNCkluIG91ciBUIGRpc3RyaWJ1dGlvbiBzaW5jZSB3ZSBkbyBub3Qga25vdyBvdXIgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24gYW5kIGRpdmlkZSBieSB0aGUgc2FtcGxlIHN0YW5kYXJkIGRldmlhdGlvbiwgd2UgbXVzdCBjb25zaWRlciB0aGUgdmFyaWF0aW9uIHdpdGhpbiB0aGUgc2FtcGxlLCB3aGljaCBpcyB3aHkgd2UgZGl2aWRlICRTJCBieSB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlIHNhbXBsZSBzaXplLiANCg0KQXMgdGhlIHNoYXBlIG9mIGEgdC1kaXN0cmlidXRpb24gYW5kIG5vcm1hbCBkaXN0cmlidXRpb24gYnkgdGhlIG5ha2VkIGV5ZSBmb2xsb3cgaGlnaGx5IHNpbWlsYXIgc2hhcGVzIHRoZSBmb3JtdWxhaWMgZGlmZmVyZW5jZSBvZiB0aGUgICRTIC9cc3FydHtufSQgLGluIHRoZSB0IGRpc3RyaWJ1dGlvbiBkZW5vbWluYXRvciwgY2F1c2VzIG1vcmUgdW5jZXJ0YWludHkgaW4gdGhlIGRpc3RyaWJ1dGlvbiBsZWFkaW5nIHRvIHdpZGVyICJmYXR0ZXIiIHRhaWxzIGluIHRoZSB0LSBkaXN0cmlidXRpb24gcmF0aGVyIHRoYW4gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uIFVubGlrZSBpbiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aGVyZSB3ZSBrbm93IHRoZSB2YXJpYW5jZSwgb3Igc3ByZWFkIG9mIGRhdGEsIHdpdGggdGhlIGdvYWwgb2YgZmluZGluZyB0aGUgc2FtcGxlIG1lYW4sIGluIGEgdC1kaXN0cmlidXRpb24gd2UgbmVpdGhlciBrbm93IHRoZSB2YXJpYW5jZSBub3IgdGhlIHNhbXBsZSBtZWFuLCBsZWFkaW5nIHRvIGEgZ3JlYXRlciBjaGFuY2Ugb2YgdW5jZXJ0YWludHkuIEdyZWF0ZXIgdW5jZXJ0YWludHkgIHVsdGltYXRlbHkgbGVhZHMgdXMgdG8gaGF2ZSBmYXR0ZXIgdGFpbHMgc2hvd2luZyBoaWdoZXIgdmFyaWFuY2UsIGFsdGhvdWdoIGFzIG4gaW5jcmVhc2VzIHRoaXMgdW5jZXJ0YWludHkgaXMgcmVkdWNlZCwgZ2l2aW5nIGEgc21hbGxlciBzdGFuZGFyZCBkZXZpYXRpb24gJFNeMiQgdWx0aW1hdGVseSBkZWNyZWFzaW5nIHRoZSBzcHJlYWQgaW4gdGhlIGRpc3RyaWJ1dGlvbi4gDQoNCg0KDQpOb3RlIGFzIG91ciBzYW1wbGUgc2l6ZSBncm93cywgdGhlIHRhaWxzIG9mIHRoZSB0LWRpc3RyaWJ1dGlvbiBnZXQgbGVzcyBmYXQsIG9mdGVuIGNvbnZlcmdpbmcgY2xvc2VyIHRoZSBhIG5vcm1hbCBkaXN0cmlidXRpb24uIFNpbWlsYXIgdG8gb3VyIENlbnRyYWwgTGltaXQgVGhlcm9uIHdoZXJlIHRoZSBsYXJnZXIgb3VyIHNhbXBsZSBzaXplLCB0aGUgbW9yZSBvdXIgbW9kZWwgY29udmVyZ2VzIHRvIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uLiBUaGUgZm9ybXVsYSBjb21wb25lbnQgb2YgJFxzcXJ0e259JCBhc3Npc3RzIGluIGNoYW5naW5nIHRoZSBkaXN0cmlidXRpb24gc2hhcGUsIGFzIHRoZSBsZXZlbCBvZiBuIGNvbnRyaWJ1dGVzIHRvIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20sIHRoZSBvbmx5IHBhcmFtZXRlciBpbiB0aGUgdC1kaXN0cmlidXRpb24gZm9ybXVsYS4gDQoNCg0KQmVsb3cgd2UgY29tcGFyZSBhIHQtZGlzdHJpYnV0aW9uIHdpdGggYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBOb3RlIHRoZSB0LWRpc3RyaWJ1dGlvbiBoYXMgJ2ZhdHRlcicgdGFpbHMuDQoNCmBgYHtyfQ0KDQpzZXQuc2VlZCgzNTkpDQpuIDwtIDE1DQptdSA8LSA1DQpzaWdtYSA8LSAyDQoNCiMgR2VuZXJhdGUgdC1zdGF0aXN0aWNzDQpuLnNhbXBsZXMgPC0gMTAwMDANCnQuc3RhdHMgPC0gbnVtZXJpYyhuLnNhbXBsZXMpICAjIFRoaXMgZGVmaW5lcyBhIDEwMDAwIGRpbWVuc2lvbmFsIHplcm8gdmVjdG9yDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0LnRlc3QgPC0gTlVMTCB1c2VzIG1vcmUgY29tcHV0aW5nIHJlc291cmNlDQpmb3IoaSBpbiAxOm4uc2FtcGxlcykgew0KICBzYW1wbGUuZGF0YSA8LSBybm9ybShuLCBtdSwgc2lnbWEpDQogIHguYmFyIDwtIG1lYW4oc2FtcGxlLmRhdGEpDQogIHMgPC0gc2Qoc2FtcGxlLmRhdGEpDQogIHQuc3RhdHNbaV0gPC0gKHguYmFyIC0gbXUpIC8gKHMvc3FydChuKSkNCn0NCg0KIyBDb21wYXJlIHdpdGggdGhlb3JldGljYWwgdC1kaXN0cmlidXRpb24NCngudmFscyA8LSBzZXEoLTQsIDQsIGxlbmd0aC5vdXQgPSAyMDApDQp0aGVvcmV0aWNhbC50IDwtIGR0KHgudmFscywgZGYgPSBuLTEpICAgICMgY2FsbGluZyB0LWRlbnNpdHkgZnVuY3Rpb24NCnRoZW9yZXRpY2FsLm5vcm1hbCA8LSBkbm9ybSh4LnZhbHMpICAgICAgIyBzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uDQoNCmNvbXBhcmlzb24uZGYgPC0gZGF0YS5mcmFtZSgNCiAgeCA9IHJlcCh4LnZhbHMsIDIpLA0KICBkZW5zaXR5ID0gYyh0aGVvcmV0aWNhbC50LCB0aGVvcmV0aWNhbC5ub3JtYWwpLA0KICBkaXN0cmlidXRpb24gPSByZXAoYygidCg5KSIsICJOKDAsMSkiKSwgZWFjaCA9IGxlbmd0aCh4LnZhbHMpKQ0KKQ0KDQp0LnBsdCA8LSBnZ3Bsb3QoY29tcGFyaXNvbi5kZiwgYWVzKHggPSB4LCB5ID0gZGVuc2l0eSwgY29sb3IgPSBkaXN0cmlidXRpb24pKSArDQogIGdlb21fbGluZShzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gInQtRGlzdHJpYnV0aW9uIHZzIE5vcm1hbCBEaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiVmFsdWUiLCB5ID0gIkRlbnNpdHkiKSArDQogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSAzNSwgciA9IDIwLCBiID0gMzAsIGwgPSAzMCwgdW5pdCA9ICJwdCIpKSArDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYmx1ZSIsICJvcmFuZ2UiKSkNCmdncGxvdGx5KHQucGx0KQ0KDQpgYGANCg0KDQpXaHkgb3VyIHQtZGlzdHJpYnV0aW9uIGNvbm5lY3RzIHdpdGggdGhlIG5vcm1hbCBkaXN0cmlidXRpb24/IA0KDQpPdXIgdC1kaXN0cmlidXRpb24gaW4gZnVuY3Rpb24gYmVoYXZlcyBzaW1pbGFybHkgdG8gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uIE91ciBub3JtYWwgc3RhbmRhcmRpemVkIGZvcm11bGEgYW5kIG5vcm1hbCBkaXN0cmlidXRpb24gZm9ybXVsYSAgc2hhcmUgYSBudW1lcmF0b3IgYWNjb3VudGluZyBmb3IgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIG1lYW4gYW5kIHRoZSBvYnNlcnZlZCB2YWx1ZSAoIHNoYXJlZCBudW1lcmF0b3I6ICRcYmFye1h9IC0gXG11JCkuIEV2ZW4gaW4gc2hhcGUgYm90aCB0aGUgdCBhbmQgbm9ybWFsIGRpc3RyaWJ1dGlvbnMgc2hhcmUgYSBiZWxsIGN1cnZlIGNlbnRlcmVkIGF0IDAuIFdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGxhcmdlIGVub3VnaCBhIHQgZGlzdHJpYnV0aW9uIGNhbiBiZWNvbWUgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBPdXIgdC1kaXN0cmlidXRpb24gY29udmVyZ2luZyB0byB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyB2YWx1YWJsZSBiZWNhdXNlIHdpdGggYSBsYXJnZSBlbm91Z2ggc2FtcGxlIHNpemUsIG91ciBzYW1wbGUgdmFyaWFuY2UgYmVjYXVzZSBhY2N1cmF0ZSBlbm91Z2ggdG8gYWNjb3VudCBhcyB0aGUgdHJ1ZSBwb3B1bGF0aW9uIHZhcmlhbmNlLCBhbGxvd2luZyBvdXIgc3RhdGlzdGljcyB0byBiZSBtb3JlIGFjY3VyYXRlIGFzIHRoZXkgYXJlIGNsb3NlciB0byB0aGUgdHJ1ZSBwb3B1bGF0aW9uLg0KDQoNCk91ciBhc3N1bXB0aW9ucyBvZiB0aGUgdC1kaXN0cmlidXRpb24gaW5jbHVkZSBpbmRlcGVuZGVudCByYW5kb20gb2JzZXJ2YXRpb25zLCByYW5kb20gc2FtcGxpbmcsIGFuZCB0aGF0IG91ciBwb3B1bGF0aW9uIGlzIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiAgDQoNCkFzIHQgZGlzdHJpYnV0aW9ucyB0ZW5kIHRvIGNvbnZlcmdlIGludG8gbm9ybWFsIGRpc3RyaWJ1dGlvbnMgdXBvbiBsYXJnZSBzYW1wbGUgc2l6ZSwgb2Z0ZW4gdCBkaXN0cmlidXRpb25zIHByaW9yIHRvIGNvbnZlcmdpbmcgaGF2ZSBzbWFsbGVyIHNhbXBsZSBzaXplcy4NCg0KVGhlIHQtZGlzdHJpYnV0aW9uIGNvbnNpZGVycyBlc3RpbWF0aW9ucyBmb3IgdGhlIHNhbXBsZSBtZWFuLCB3ZSB1c2UgYSBjaGktc3F1YXJlZCBkaXN0cmlidXRpb24gdG8gYXNzZXNzIHRoZSB2YXJpYW5jZSwgYWxzbyBrbm93biBhcyBzcHJlYWQsIG9mIHRoZSBkaXN0cmlidXRpb24uDQoNCiMgQ2hpLVNxdWFyZWQgRGlzdHJ1YnV0aW9uDQoNCkEgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9uIGlzIGFsc28gYSBkaXN0cmlidXRpb24gdHlwZSB0aGF0IGNhbiBjb252ZXJnZSBpbnRvIG5vcm1hbCBkaXN0cmlidXRpb24uIEEgY2hpLSBzcXVhcmVkIGRpc3RyaWJ1dGlvbiBpcyBhIHNwZWNpYWwgY2FzZSBvZiBhIGdhbW1hIGRpc3RyaWJ1dGlvbiwgaW4gd2hpY2ggYm90aCBkaXN0cmlidXRpb25zIGhhdmUgc2tld25lc3MuIA0KDQpCZWxvdyBpcyBhbiBleGFtcGxlIG9mIGEgY2hpLXNxdWFyZSBkaXN0cmlidXRpb246DQoNCmBgYHtyIGNoaWV4YW1wbGUxfQ0KDQpzZXQuc2VlZCg2KQ0KbiA8LSA1DQpzaWdtYSA8LSAyDQoNCiMgR2VuZXJhdGUgY2hpLXNxdWFyZSBzdGF0aXN0aWNzDQpuLnNhbXBsZXMgPC0gMTAwMDANCmNoaXNxLnN0YXRzIDwtIG51bWVyaWMobi5zYW1wbGVzKQ0KDQpmb3IoaSBpbiAxOm4uc2FtcGxlcykgew0KICBzYW1wbGUuZGF0YSA8LSBybm9ybShuLCAwLCBzaWdtYSkNCiAgY2hpc3Euc3RhdHNbaV0gPC0gc3VtKChzYW1wbGUuZGF0YS9zaWdtYSleMikNCn0NCg0KIyBDb21wYXJlIHdpdGggdGhlb3JldGljYWwgY2hpLXNxdWFyZQ0KeC52YWxzIDwtIHNlcSgwLCAzMCwgbGVuZ3RoLm91dCA9IDIwMCkNCnRoZW9yZXRpY2FsLmNoaXNxIDwtIGRjaGlzcSh4LnZhbHMsIGRmID0gbikNCnRoZW9yeS5kZiA8LSBkYXRhLmZyYW1lKHggPSB4LnZhbHMsIGRlbnNpdHkgPSB0aGVvcmV0aWNhbC5jaGlzcSkNCg0KY2hpLnBsdCA8LSBnZ3Bsb3QoZGF0YS5mcmFtZSh4ID0gY2hpc3Euc3RhdHMpLCBhZXMoeCA9IHgpKSArDQogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBiaW5zID0gNTAsIGFscGhhID0gMC43LCBmaWxsID0gImdyZWVuIikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHRoZW9yeS5kZiwgYWVzKHggPSB4LCB5ID0gZGVuc2l0eSksIA0KICAgICAgICAgICAgY29sb3IgPSAiYmx1ZSIsIGxpbmV3aWR0aCA9IDEuNSkgKw0KICAjc3RhdF9mdW5jdGlvbihmdW4gPSBkY2hpc3EsIGFyZ3MgPSBsaXN0KGRmID0gbiksIGNvbG9yID0gInJlZCIsIHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiQ2hpLVNxdWFyZWQgRGlzdHJpYnV0aW9uIChuPTUpICIsDQogICAgICAgc3VidGl0bGUgPSAiU3VtIG9mIHNxdWFyZWQgc3RhbmRhcmQgbm9ybWFscyIsDQogICAgICAgeCA9ICJWYWx1ZSIsIHkgPSAiRGVuc2l0eSIpICsNCiAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gMzUsIHIgPSAyMCwgYiA9IDMwLCBsID0gMzAsIHVuaXQgPSAicHQiKSkNCmdncGxvdGx5KGNoaS5wbHQpDQoNCg0KYGBgDQoNCkFuIGluY3JlYXNlIGluIHNhbXBsZSBzaXplIGNhbiBsZWFkIHRvIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgYXMgaW5jcmVhc2UgaW4gc2FtcGxlIHNpemUgcmVkdWNlcyB0aGUgc2tld25lc3MuDQpgYGB7ciBjaGlleGFtcGxlM30NCg0Kc2V0LnNlZWQoNikNCm4gPC0gNTAwDQpzaWdtYSA8LSAyDQoNCiMgR2VuZXJhdGUgY2hpLXNxdWFyZSBzdGF0aXN0aWNzDQpuLnNhbXBsZXMgPC0gMTAwMDANCmNoaXNxLnN0YXRzIDwtIG51bWVyaWMobi5zYW1wbGVzKQ0KDQpmb3IoaSBpbiAxOm4uc2FtcGxlcykgew0KICBzYW1wbGUuZGF0YSA8LSBybm9ybShuLCAwLCBzaWdtYSkNCiAgY2hpc3Euc3RhdHNbaV0gPC0gc3VtKChzYW1wbGUuZGF0YS9zaWdtYSleMikNCn0NCg0KIyBDb21wYXJlIHdpdGggdGhlb3JldGljYWwgY2hpLXNxdWFyZQ0KeC52YWxzIDwtIHNlcSgwLCAxMTAwLCBsZW5ndGgub3V0ID0gMjAwKQ0KdGhlb3JldGljYWwuY2hpc3EgPC0gZGNoaXNxKHgudmFscywgZGYgPSBuKQ0KdGhlb3J5LmRmIDwtIGRhdGEuZnJhbWUoeCA9IHgudmFscywgZGVuc2l0eSA9IHRoZW9yZXRpY2FsLmNoaXNxKQ0KDQpjaGkucGx0IDwtIGdncGxvdChkYXRhLmZyYW1lKHggPSBjaGlzcS5zdGF0cyksIGFlcyh4ID0geCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIGJpbnMgPSA1MCwgYWxwaGEgPSAwLjcsIGZpbGwgPSAiZ3JlZW4iKSArDQogIGdlb21fbGluZShkYXRhID0gdGhlb3J5LmRmLCBhZXMoeCA9IHgsIHkgPSBkZW5zaXR5KSwgDQogICAgICAgICAgICBjb2xvciA9ICJibHVlIiwgbGluZXdpZHRoID0xLjUpICsNCiAgI3N0YXRfZnVuY3Rpb24oZnVuID0gZGNoaXNxLCBhcmdzID0gbGlzdChkZiA9IG4pLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIkNoaS1TcXVhcmVkIERpc3RyaWJ1dGlvbiAobj01MDApICIsDQogICAgICAgc3VidGl0bGUgPSAiU3VtIG9mIHNxdWFyZWQgc3RhbmRhcmQgbm9ybWFscyIsDQogICAgICAgeCA9ICJWYWx1ZSIsIHkgPSAiRGVuc2l0eSIpICsNCiAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gMzUsIHIgPSAyMCwgYiA9IDMwLCBsID0gMzAsIHVuaXQgPSAicHQiKSkNCmdncGxvdGx5KGNoaS5wbHQpDQoNCg0KYGBgDQoNCkEgY2hpLXNxdWFyZSBkaXN0cmlidXRpb24gY2FuIGRlcml2ZSBmcm9tIGFuIGV4YWN0IG5vcm1hbCBkaXN0cmlidXRpb24uIEl0IGNhbiBlc3NlbnRpYWxseSBhY3QgYXMgYSBzcXVhcmVkIHN0YW5kYXJkIG5vcm1hbCB3aXRoIG9uZSBkZWdyZWUgb2YgZnJlZWRvbSBvciBhIHN1bSBvZiBzcXVhcmVzIHdpdGggbW9yZSB0aGFuIDEgZGVncmVlIG9mIGZyZWVkb20sIGFkZGluZyBza2V3bmVzcyB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24uIEFzIHRoZSBjaGktc3F1YXJlIGlzIGEgc3F1YXJlZCBub3JtYWwsIHRoZSBkaXN0cmlidXRpb24gY2FuIG5ldmVyIGJlIG5lZ2F0aXZlLCBleGFnZ2VyYXRpbmcgYW55IHJpZ2h0IHNrZXduZXNzLiBJbiBvdGhlciB3b3JkcywgYSBjaGktc3F1YXJlZCBkaXN0cmlidXRpb24gY2FuIGJlIGRlc2NyaWJlZCBhcyBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHdob3NlIGNlbnRlciBoYXMgbW92ZWQgYW5kIG5vdyBwb3NzZXNzZXMgc2tld25lc3MuDQoNCkluIGNvbnRyaWJ1dGlvbiB0aGF0IHRoZSB2YXJpYW5jZSBpcyBhIHNxdWFyZWQgcGFyYW1ldGVyLCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgdmFyaWFuY2UgY2FuIGJlIGRlc2NyaWJlZCBhcyBhIGNoaS1zcXVhcmUgZGlzdHJpYnV0aW9uIHVwb24gc2NhbGluZy4gV2hlbiBvdXIgc2FtcGxlIHNpemUgaW5jcmVhc2VzLHRoZSBkZWdyZWUgb2YgZnJlZWRvbSBwYXJhbWV0ZXIgJChuLTEpJCBpbiBvdXIgbnVtZXJhdG9yIGluY3JlYXNlcy4gVGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSBoZWxwcyBvdXIgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9uIHRha2Ugb24gYSBub3JtYWwgZGlzdHJpYnV0aW9uLCBzbW9vdGhpbmcgdGhlIHNrZXduZXNzIGludG8gYSBiZWxsLXNoYXBlLCBhcyB0aGUgc2FtcGxlIHNpemUgaW5jcmVhc2UuIA0KDQpPdXIgY2hpLXNxdWFyZSBkaXN0cmlidXRpb24gcmVsYXRpb25zaGlwIHdpdGggYSBub3JtYWwgZGlzdHJpYnV0aW9uOg0KDQokJA0KICBcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9IFxyaWdodGFycm93IFxjaGleMl97bi0xfQ0KJCQNCg0KTGlrZSBhIHQtZGlzdHJpYnV0aW9uLCBvdXIgYXNzdW1wdGlvbnMgYWJvdXQgYSBjaGktc3F1YXJlIGRpc3RyaWJ1dGlvbiBpcyB0aGF0IHdlIHNhbXBsZSBmcm9tIGEgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgcG9wdWxhdGlvbiBhcyB3ZWxsIGFzIGluZGl2aWR1YWxseSBhbmQgaW5kZXBlbmRlbnRseSBkaXN0cmlidXRlZC4NClRoZSBjaGktc3F1YXJlZCBhbmQgdC1kaXN0cmlidXRpb24gaGF2ZSBkZWdyZWVzIG9mIGZyZWVkb20gaW4gdGhlaXIgcGFyYW1ldGVycywgZGljdGF0aW5nIHRoZSBzaGFwZXMgb2YgdGhlaXIgZGlzdHJpYnV0aW9ucy4NCg0KDQojIEYgZGlzdHJ1YnV0aW9uDQoNCldpdGggb3VyIGNoaS1zcXVhcmVkIGRpc3RyaWJ1dGlvbiB3ZSBzZWUgdGhlIHZhcmlhbmNlIG9mIG91ciBkaXN0cmlidXRpb24uIE9mdGVuIHdlIGhhdmUgbXVsdGlwbGUgZGlzdHJpYnV0aW9ucyBhbmQgd2UgbmVlZCB0byByZWxhdGUgdGhlIHZhcmlhbmNlcyB0byBlYWNoIG90aGVyIHRvIHNlZSBxdWFsaXR5IG9mIHRoZSB0d28gZGlzdHJpYnV0aW9ucy4gSGVuY2Ugd2UgYnVpbGQgYSBGIGRpc3RyaWJ1dGlvbiBhcyBhIHJhdGlvIG9mIHR3byBjaGktc3F1YXJlZCB2YXJpYWJsZXMgb2YgaW5kZXBlbmRlbnQgc2FtcGxlIHZhcmlhbmNlcy4gTGlrZSB0aGUgaW5kaXZpZHVhbCBjaGktc3F1YXJlZCwgYm90aCBhc3N1bWUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlc2UgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9ucyBzb3VyY2UgZnJvbSBpbmRlcGVuZGVudCBwb3B1bGF0aW9ucy4gDQoNCiQkDQp7WF8xLCBYXzIsIC4uLlhfbn0gfiBee2kuaS5kfSBOKFxtdV8yLCBcc2lnbWFeMl8xKSBcXCBhbmQgXFx7WV8xLCBZXzIsIC4uLllfbn0gfiBee2kuaS5kfSBOKFxtdV8yLCBcc2lnbWFeMl8yKSANCiQkDQokJA0KU14yXzEgPSBcZnJhYyB7MX17bl8xLTF9IFxzdW1fe2k9MX1ee259ICh7WF9pIC1cYmFye1h9fSleMiAgICBcXGFuZFxcIA0KU14yXzIgPSBcZnJhYyB7MX17bl8yLTF9IFxzdW1fe2k9MX1ee259ICh7WV9pIC1cYmFye1l9fSleMg0KJCQNCkRlZmluZQ0KJCQNCkY9IFxmcmFjIHtTXjJfMS8gXHNpZ21hXjJ9IHtTXjJfMi9cc2lnbWFeMl8yfSBccmlnaHRhcnJvd15kIEZfe24tMSwgbl8yLTF9DQokJCANCg0KDQpUaGUgMSBkZWdyZWUgb2YgZnJlZWRvbSBlYWNoIGNoaS1zcXVhcmVzIGhvbGQgaW4gdGhlIEYtZGlzdHJpYnV0aW9uIGdpdmUgdXMgMiBkZWdyZWVzIG9mIGZyZWVkb20gKG9uZSBpbiB0aGUgZGVub21pbmF0b3IsIGFuZCBvbmUgaW4gdGhlIG51bWVyYXRvcikgdGhhdCBib3RoIGNvbnRyaWJ1dGUgdG8gdGhlIGRpc3RyaWJ1dGlvbidzIHNoYXBlLg0KDQpJbiB0aGUgZ3JlYXRlciB0aGUgRiBkaXN0cmlidXRpb24gcmF0aW8sIHRoZSBtb3JlIHZhcmlhbmNlIGluIHRoZSBudW1lcmF0b3IncyBkaXN0cmlidXRpb24uIFRoZSBzbWFsbGVyIHRoZSB2YXJpYW5jZSB0aGUgdmFyaWFuY2UgaXMgbGFyZ2VyIGluIHRoZSBkZW5vbWluYXRvciBkaXN0cmlidXRpb24uIElmIHRoZSBGIGRpc3RyaWJ1dGlvbiByYXRpbyBpcyAxLCB0aGUgdHdvIHZhcmlhbmNlcyBpbiB0aGUgbnVtZXJhdG9yIGFuZCBkZW5vbWluYXRvciBhcmUgZXF1YWwuDQoNCg0KDQpgYGB7cn0NCg0Kc2V0LnNlZWQoNDUpDQpkZjEgPC0gMjANCmRmMiA8LSAyNQ0KDQojIEdlbmVyYXRlIEYgc3RhdGlzdGljcw0Kbi5zYW1wbGVzIDwtIDEwMDAwDQpmLnN0YXRzIDwtIG51bWVyaWMobi5zYW1wbGVzKQ0KDQpmb3IoaSBpbiAxOm4uc2FtcGxlcykgew0KICB1MSA8LSByY2hpc3EoMSwgZGYxKQ0KICB1MiA8LSByY2hpc3EoMSwgZGYyKQ0KICBmLnN0YXRzW2ldIDwtICh1MS9kZjEpIC8gKHUyL2RmMikNCn0NCg0KIyBDb21wYXJlIHdpdGggdGhlb3JldGljYWwgRi1kaXN0cmlidXRpb24NCngudmFscyA8LSBzZXEoMCwgNSwgbGVuZ3RoLm91dCA9IDIwMCkNCnRoZW9yZXRpY2FsLmYgPC0gZGYoeC52YWxzLCBkZjEsIGRmMikNCnRoZW9yeS5kZiA8LSBkYXRhLmZyYW1lKHggPSB4LnZhbHMsIGRlbnNpdHkgPSB0aGVvcmV0aWNhbC5mKQ0KDQoNCg0KDQpmLnBsdCA8LSBnZ3Bsb3QoZGF0YS5mcmFtZSh4ID0gZi5zdGF0cyksIGFlcyh4ID0geCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIGJpbnMgPSA1MCwgYWxwaGEgPSAwLjcsIGZpbGwgPSAiYmx1ZSIpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSB0aGVvcnkuZGYsIGFlcyh4ID0geCwgeSA9IGRlbnNpdHkpLCANCiAgICAgICAgICAgIGNvbG9yID0gInJlZCIsIGxpbmV3aWR0aCA9IDEpICsNCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIDUpKSArDQogIGxhYnModGl0bGUgPSBwYXN0ZSgiRi1EaXN0cmlidXRpb24gXG4gRigiLCBkZjEsICIsIiwgZGYyLCAiKSIsIHNlcCA9ICIiKSwNCiAgICAgICB4ID0gIlZhbHVlIiwgeSA9ICJEZW5zaXR5IikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDM1LCByID0gMjAsIGIgPSAzMCwgbCA9IDMwLCB1bml0ID0gInB0IikpDQpnZ3Bsb3RseShmLnBsdCkNCg0KDQoNCmBgYA0KDQoNCg0KDQojIENvbmNsdXNpb24NCkFzc3VtaW5nIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhbGxvd3MgdXMgdG8gY29ubmVjdCBhIHQgZGlzdHJpYnV0aW9uIHRvIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gQSBub3JtYWwgZGlzdHJpYnV0aW9uIGNhbiBiZSB1c2VkIHRvd2FyZHMgYSBjaGktIHNxdWFyZWQgZGlzdHJpYnV0aW9uIHRvIGFzc2VzcyBtb2RlbCB2YXJpYW5jZSBhbmQgdHdvIGNoaS1zcXVhcmUgdGVzdHMgY2FuIGJlIHVzZWQgaW4gYW4gRiBkaXN0cmlidXRpb24gcmF0aW8gdG8gYXNzZXNzIHRoZSBvdmVyYWxsIHF1YWxpdHkgb2YgdHdvIGRpc3RyaWJ1dGlvbnMuIA0KDQpUaGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBidWlsZHMgaW50byBhZHZhbmNlZCBhbmFseXNlIHRoYXQgYWxsb3cgdXMgdG8gY29uc2lkZXIgdGhlIHF1YWxpdHkgb2Ygb3VyIGRpc3RyaWJ1dGlvbi4gV2l0aG91dCBhIHN0YW5kYXJkaXplZCBkaXN0cmlidXRpb24gc2hhcGUgdGhhdCB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBnaXZlcyB1cywgbWFraW5nIHRoZXNlIGNvbXBhcmlzb25zIHdvdWxkIGJlIGNoYWxsZW5naW5nLCBlc3BlY2lhbGx5IHRocm91Z2ggdmFyaW91cyB1bml0IHR5cGVzLiBPdXIgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhbGxvd3MgdXMgdG8gb3JnYW5pemUgb3VyIGRpc3RyaWJ1dGlvbiBmb3IgYW5hbHlzaXMsIGFuZCB0ZXN0IHRoZSBxdWFsaXR5IG9mIGFuIG9ic2VydmVkIGRhdGEgc2V0IGVpdGhlciB0aHJvdWdoIGFwcHJveGltYXRpb24gb3IgdGhlb3JldGljYWwgY29tcGFyaXNvbi4=