Introduction
Sampling distributions form the cornerstone of statistical inference.
They describe the probability distribution of a sample
statistic calculated from random samples. This note explores
both exact (finite-sample) and asymptotic (large-sample) distributions
for key statistics including sample means, proportions, and related test
statistics.
Sampling Distribution
of the Sample Mean
When the population is normal, by the property of normal
distribution, the sum of the iid random variables are
exactly normally distributed. If the population is not
a normal distribution, using the Central Limit Theorem (CLT), the sum of
the iid random variables is asymptotically normally
distributed.
Exact
Distribution
For a random sample \(X_1, X_2, \ldots,
X_n\) from a normal population \(N(\mu,
\sigma^2)\), the sample mean has an exact normal
distribution:
\[
\bar{X} \to N\left(\mu, \frac{\sigma}{\sqrt{n}}\right)
\]
The standardized version is:
\[
Z = \frac{\bar{X}-\mu}{\sigma/\sqrt{n}} \overset{d}{\to} N(0, 1)
\]
Example: We simulate data from normal distribution
to explain the above sampling distribution of sample means from a normal
population.
set.seed(123)
n <- 10
mu <- 5
sigma <- 2
n.samples <- 10000
sample.means <- replicate(n.samples, mean(rnorm(n, mu, sigma))) # replicate() is a wrapper function
# sapply()
# Create theoretical curve data
x.vals <- seq(mu - 3*sigma/sqrt(n), mu + 3*sigma/sqrt(n), length.out = 100)
theory.density <- dnorm(x.vals, mean = mu, sd = sigma/sqrt(n))
theory.df <- data.frame(x = x.vals, density = theory.density)
xbar.plt <- ggplot(data.frame(mean = sample.means), aes(x = mean)) +
geom_histogram(aes(y = ..density..), bins = 50, alpha = 0.7, fill = "gray") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "red", linewidth = 1) +
labs(title = "Exact Sampling Distribution of Sample Mean \nNormal Population (n = 10)",
x = "Sample Mean", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
ggplotly(xbar.plt)
Asymptotic Sampling
Distribution (Central Limit Theorem)
The asymptotic sampling distribution is the approximate probability
distribution of a sample statistic (like the mean, proportion, or
regression coefficient) when the sample size \(n\) is very large (approaches
infinity).
For any population with finite mean \(\mu\) and variance \(\sigma^2\), as \(n \to \infty\):
\[
Z = \frac{\bar{X}-\mu}{\sigma/\sqrt{n}} \to_{\text{approx}} N(0, 1)
\]
Example We simulation 100000 ransom samples with
size 50 from a skewed exponential population. As the sample size gets
larger, the sampling distribution of the sample means are approximately
distributed.
set.seed(123)
n.large <- 50
lambda <- 1/5 # Mean = 5
# Generate multiple samples from exponential distribution
n.samples <- 10000
exp.means <- replicate(n.samples, mean(rexp(n.large, rate = lambda)))
# Compare with normal approximation
theoretical.mean <- 1/lambda # 5
theoretical.sd <- (1/lambda)/sqrt(n.large) # 5/sqrt(50)
theory.density <- dnorm(x.vals, mean = theoretical.mean, sd = theoretical.sd)
theory.df <- data.frame(x = x.vals, density = theory.density)
# Option 1: Use only stat_function for theoretical curve (Recommended)
gg.clt <- ggplot(data.frame(mean = exp.means), aes(x = mean)) +
geom_histogram(aes(y = after_stat(density)), bins = 50, alpha = 0.7, fill = "lightgreen") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "red", linewidth = 1) +
labs(title = "Asymptotic Sampling Distribution of Sample Mean \nExponential Population (n = 50)",
x = "Sample Mean", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
#gg.clt
ggplotly(gg.clt)
Note: The asymptotic
approximation to the sampling distribution of the sample mean holds
regardless of the shape of the population distribution (provided the
population has finite mean and variance).
Remark: There is no parameter
in the standard normal distribution.
Student’s
t-Distribution
Let \(\{X_1,
X_2, \cdots, X_n \} \overset{\text{i.i.d}}{\sim} N(\mu,
\sigma)\). Define the sample mean to be
\[
\bar{X} = \frac{\sum_{i=1}^n X_i}{n}.
\]
When population variance \(\sigma^2\) is unknown and estimated by
sample variance \(S^2\):
\[
T = \frac{\bar{X}-\mu}{S/\sqrt{n}} \overset{d}{\to} t_{n-1}
\]
where
\[
S^2 = \frac{1}{n-1}\sum_{i=1}^n (X_i - \bar{X})^2.
\]
Note: The t-distribution
depends on a single parameter: the degrees of freedom, \(\nu\), which equals \(n-1\) for a sample of size \(n\). Because \(\nu\) is fixed once the sample size is
known—and does not need to be estimated from the sample data—it is
occasionally treated in applications as if the distribution had no
parameters.
Example: Since the above t-distribution is defined
based on a normal distribution, we will simulate random samples from a
normal distribution with finite mean and variance.
set.seed(123)
n <- 10
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("red", "blue"))
ggplotly(t.plt)
Caution: The standardized
sample mean follows a t-distribution. More precisely, when sampling from
a normal population with unknown mean \(\mu\) and standard deviation \(\sigma\), the t-statistic (calculated using
the sample standard deviation) follows a t-distribution.
Sampling Distribution
of Sample Proportion
Let \(X_1, X_2, \dots, X_n\) be
independent and identically distributed Bernoulli random variables with
parameter \(p\), where:
- \(X_i = 1\) with probability \(p\) (success)
- \(X_i = 0\) with probability \(1-p\) (failure)
The sample proportion is defined as:
\[
\hat{p} = \frac{1}{n} \sum_{i=1}^n X_i
\]
where \(n\) is the fixed sample
size.
In practice, when the sample size is large, the sampling distribution
of the sample mean is generally characterized using approximations. For
small samples, however, the exact sampling distribution must be
used.
Exact
Distribution
For a binomial population with success probability \(p\), the sample proportion \(\hat{p} = X/n\) where \(X \sim Binomial(n,p)\).
The exact distribution is simply the probability mass function of a
binomial distribution with n trials and success
probability \(p\):
\[
P(\hat{p} =k/n)= P(n\times \hat{p} = k) = P(X = k)=\frac{n!}{k!(n-k)!}
p^k (1−p)^{n-k}, \ \ k = 0, 1, 2, \cdots, n.
\]
Asymptotic Sampling
Distribution (Large \(n\))
By the Central Limit Theorem (specifically, the De Moivre-Laplace
Theorem for Bernoulli trials):
\[
\hat{p} \stackrel{d}{\sim} N\left(p, \frac{p(1-p)}{n}\right) \quad
\text{for large } n
\]
More rigorously, in standardized form:
\[
Z_n = \frac{\hat{p}_n - p}{\sqrt{\frac{p(1-p)}{n}}} \stackrel{d}{\to}
N(0,1) \quad \text{as } n \to \infty
\]
Sufficient Conditions for Approximation:
\(np \geq 10\) and \(n(1-p) \geq 10\) (common rule of
thumb)
Alternative: \(n > 9 \times
\max\left(\frac{p}{1-p}, \frac{1-p}{p}\right)\)
Example: We simulate random samples from binary
population (also called Bernoulli population) to demonstrate the
asymptotic sampling distribution of sample proportion.
set.seed(123)
n <- 100
p <- 0.3
# Generate sample proportions
n.samples <- 10000
sample.props <- replicate(n.samples, rbinom(1, n, p)/n) # replicate() is a wrapper
# function of sapply()
# Compare with normal approximation
theoretical.mean <- p
theoretical.sd <- sqrt(p*(1-p)/n)
x.vals <- seq(0,0.6, length=100)
theory.density <- dnorm(x.vals, mean = theoretical.mean, sd = theoretical.sd)
theory.df <- data.frame(x = x.vals, density = theory.density)
binom.plt <- ggplot(data.frame(prop = sample.props), aes(x = prop)) +
geom_histogram(aes(y = ..density..), bins = 30, alpha = 0.7, fill = "skyblue") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "red", linewidth = 1) +
#stat_function(fun = dnorm,
# args = list(mean = theoretical_mean, sd = theoretical_sd),
# color = "red", size = 1) +
labs(title = "Sampling Distribution of Sample Proportion",
subtitle = "p = 0.3, n = 100",
x = "Sample Proportion", y = "Density") +
theme(plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt"))
ggplotly(binom.plt)
Sampling Distribution
of Sample Variance
We first introduce the asymptotic sampling distribution of sample
variance without derivation. The basic setting is given in the
following.
Let \(X_1, X_2, \dots, X_n
\stackrel{\text{i.i.d.}}{\sim} F\) with:
- \(E[X_i] = \mu\)
- \(\text{Var}(X_i) = \sigma^2 <
\infty\)
- \(E[(X_i - \mu)^4] = \mu_4 <
\infty\) (finite fourth central moment)
Define the sample variance:
\[
S^2 = \frac{1}{n-1} \sum_{i=1}^n (X_i - \bar{X})^2
\] where \(\bar{X} = \frac{1}{n}
\sum_{i=1}^n X_i\).
Asymptotic Sampling
Distribution of Sample Variance
When sample size n is large, the sample variance \(S^2\) is approximately normally distributed
as
\[
S^2 \stackrel{d}{\to} N\left(\sigma^2, \frac{\mu_4 - \sigma^4}{n}\right)
\quad \text{as } n \to \infty,
\] equivalently,
\[
\frac{S^2 - \sigma^2}{\sqrt{\frac{\mu_4 - \sigma^4}{n}}}
\stackrel{d}{\to} N(0,1) \quad \text{as } n \to \infty.
\]
In practice, the fourth moment, \(\mu_4\), can be estimated from sample,
which will be discussed in subsequent topics.
Special Case: Normal
Population
When sampling from a normally distributed population, the sampling
distribution of the sample variance can be fully characterized through a
chi-squared distribution with appropriate scaling.
The chi-squared distribution is a special case of the gamma
distribution and can also be constructed from the standard normal
distribution. Specifically, we have the following result:
For \(Z_1, Z_2, \ldots, Z_k
\stackrel{iid}{\sim} N(0,1)\), using moment generating function,
we can show that
\[
Q=\sum_{i=1}^k Z_i^2 \overset{d}{\to} \chi_k^2.
\]
Using the relationship between the standard normal and chi-squared
distributions, we can derive the exact distribution of the scaled sample
variance for a normal population:
\[
\frac{(n-1)S^2}{\sigma^2} \overset{d}{\to} \chi_{n-1}^2.
\]
Proof [optional]: We
prove this in several steps:
We show that for \(X_1, \dots, X_n
\stackrel{iid}{\sim} N(\mu, \sigma^2)\), with
\[
S^2 = \frac{1}{n-1} \sum_{i=1}^n (X_i - \bar{X})^2, \quad \bar{X} =
\frac{1}{n} \sum_{i=1}^n X_i,
\]
we have
\[
\frac{(n-1)S^2}{\sigma^2} \sim \chi_{n-1}^2.
\]
Step 1: Standardize and define notation
Let \(Z_i = \frac{X_i - \mu}{\sigma} \sim
N(0,1)\), i.i.d. Then
\[
\bar{Z} = \frac{1}{n} \sum_{i=1}^n Z_i = \frac{\bar{X} - \mu}{\sigma}.
\]
We can write:
\[
\sum_{i=1}^n (X_i - \bar{X})^2 = \sigma^2 \sum_{i=1}^n (Z_i -
\bar{Z})^2.
\]
So
\[
\frac{(n-1)S^2}{\sigma^2} = \frac{\sum_{i=1}^n (X_i -
\bar{X})^2}{\sigma^2} = \sum_{i=1}^n (Z_i - \bar{Z})^2.
\]
Step 2: Orthogonal transformation
Let \(\mathbf{Z} = (Z_1, \dots,
Z_n)^T\). Choose an \(n \times
n\) orthogonal matrix \(Q\)
whose first row is \(\left(
\frac{1}{\sqrt{n}}, \dots, \frac{1}{\sqrt{n}} \right)\).
Define
\[
\mathbf{Y} = Q \mathbf{Z}.
\]
Then:
- \(Y_1 = \frac{1}{\sqrt{n}} \sum_{i=1}^n
Z_i = \sqrt{n} \, \bar{Z}\).
- Since \(Q\) is orthogonal and \(\mathbf{Z} \sim N(0, I_n)\), we have \(\mathbf{Y} \sim N(0, I_n)\) as well, so
\(Y_1, \dots, Y_n\) are i.i.d. \(N(0,1)\).
Step 3: Express sum of squares in terms of \(Y_j\)
Orthogonality implies:
\[
\sum_{i=1}^n Z_i^2 = \sum_{j=1}^n Y_j^2.
\]
Also,
\[
\sum_{i=1}^n (Z_i - \bar{Z})^2 = \sum_{i=1}^n Z_i^2 - n \bar{Z}^2.
\]
But \(n \bar{Z}^2 = Y_1^2\), so
\[
\sum_{i=1}^n (Z_i - \bar{Z})^2 = \sum_{j=1}^n Y_j^2 - Y_1^2 =
\sum_{j=2}^n Y_j^2.
\]
Step 4: Distribution
Since \(Y_2, \dots, Y_n\) are
i.i.d. \(N(0,1)\), we have
\[
\sum_{j=2}^n Y_j^2 \sim \chi_{n-1}^2.
\]
Thus
\[
\frac{(n-1)S^2}{\sigma^2} = \sum_{i=1}^n (Z_i - \bar{Z})^2 =
\sum_{j=2}^n Y_j^2 \overset{d}{\to} \chi_{n-1}^2.
\]
Step 5: Independence from \(\bar{X}\)
Since \(Y_1 = \sqrt{n} \bar{Z}\) is
independent of \(Y_2, \dots, Y_n\), it
follows that \(\bar{X}\) is independent
of \(S^2\). That is,
\[
\boxed{\frac{(n-1)S^2}{\sigma^2} \to \chi_{n-1}^2}
\]
Example: The \(\chi^2\) distribution is derived from the
standard normal distribution. We simulate standard normal random numbers
and then transform them into \(\chi^2\)
random variables based on the derivations above. A histogram will be
plotted and overlaid with the theoretical \(\chi^2\) density curve.
set.seed(123)
n <- 10
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 = "steelblue") +
geom_line(data = theory.df, aes(x = x, y = density),
color = "red", linewidth = 1) +
#stat_function(fun = dchisq, args = list(df = n), color = "red", size = 1) +
labs(title = "Chi-Square Distribution",
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)
Remark Both the chi-squared and
t-distributions are parameterized by degrees of freedom. In particular,
the scaled sample variance from a sample of size \(n\) follows a chi-squared distribution with
\(n−1\) degrees of freedom.
F-Distribution
The F-distribution serves as the sampling distribution for the ratio
of two independent sample variances. Variance is a key measure of
quality across disciplines, where higher variance corresponds to lower
quality. When comparing quality via variances, both differences and
ratios are conceivable. However, under normal population assumptions,
the difference of two sample variances lacks a convenient known
distribution, while the appropriately scaled ratio follows the \(F\) distribution.
The following is the setup of the definition for \(F\) distribution. For two
independent random sample from two normal
populations:
\[
\{X_1, X_2, \cdots, X_{n_1}\} \overset{i.i.d}{\sim} N(\mu_1,
\sigma_1^2) \quad\text{ and } \quad \{Y_1, Y_2, \cdots,
Y_{n_2}\} \overset{i.i.d}{\sim} N(\mu_2, \sigma_2^2),
\]
Define
\[
S_1^2 = \frac{1}{n_1-1} \sum_{i=1}^{n_1} (X_i - \bar{X})^2 \quad\text{
and } \quad S_2^2 = \frac{1}{n_2-1} \sum_{i=1}^{n_2} (Y_i - \bar{Y})^2
\]
\[
F = \frac{S_1^2/\sigma_1^2}{S_2^2/\sigma_2^2} \overset{d}{\to} F_{n_1-1,
n_2-1}
\]
where \(n_1-1\) and \(n_2-1\) are degrees of freedom of numerator
and denominator respectively. Since \(S_1^2\) and \(S_2^2\) are unbiased for \(\sigma_1^2\) and \(\sigma_2^2\), if our hypothesis is \(\sigma_1^2 = \sigma_2^2\) (indicating equal
product quality in variance terms), the expected F-ratio \(F = S_1^2/S_2^2\) is approximately 1,
though its actual distribution is \(F_{n_1-1,
n_2-1}\).
Example: The F distribution is directly defined
based on two independent \(\chi^2\)
distributions, which are themselves derived from standard normal
distributions. Therefore, we could generate data from normal
distributions and then transform them into F random variables. To keep
the process simple, we generate data directly from \(\chi^2\) distributions.
set.seed(123)
df1 <- 10
df2 <- 15
# 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 = "purple3") +
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)
Remarks:
F has two parameters, degrees of freedom on the numerator and
denominator, what are corresponding sample sizes minus 1. This is
similar to that of t and chi-squared distributions.
From previous section, we see that both numerator and denominator
can be re-expressed in terms of two independent chi-squared
distributions. To see this, both numerators in the following follow
chi-squared distribution with degrees of freedom of \(n_1-1\) and \(n_2-1\), respectively.
\[
\frac{S_1^2}{\sigma_1^2} = \frac{(n_1-1)S_1^2/\sigma_1^2}{n_1-1}
\quad \text{ and } \quad \frac{(n_2-1)S_2^2/\sigma_2^2}{n_2-1}
\]
- Denote \(U_1 = (n_1-1)S_1^2/\sigma_1^2
\overset{d}{\sim} \chi^2_{n_1-1}\) and \(U_2 = (n_2-1)S_2^2/\sigma_2^2 \overset{d}{\sim}
\chi^2_{n_2-1}\). Then, we can re-express the F-ratio as
\[
F = \frac{U_1/(n_1-1)}{U_2/(n_2-1)} \overset{d}{\to} F_{n_1-1, n_2-1}.
\]
- One can also derive the asymptotic sampling
distribution of \(S_1^2/S_2^2\) using a linear approximation
based on a Taylor expansion. However, the analytic expression is complex
and beyond the scope of this class.
Summary of Key
Relationships
We have discussed several exact and asymptotic sampling distributions
for sample means, variances, and their functions. The following table
summarizes these distributions.
| \(\bar{X}\) |
\(N(\mu,
\sigma^2/n)\) |
\(N(\mu,
\sigma^2/n)\) |
Normal population or large n |
| \(\frac{\bar{X}-\mu}{S/\sqrt{n}}\) |
\(t_{n-1}\) |
\(N(0,1)\) |
Normal population |
| \(\hat{p}\) |
\(Binomial(n,p)/n\) |
\(N(p,
p(1-p)/n)\) |
\(np, n(1-p) \geq
5\) |
| \(S^2\) |
- |
\(N(\sigma^2, (\mu_4-\sigma^4
)/n)\) |
large n |
| \(\frac{(n-1)S^2}{\sigma^2}\) |
\(\chi^2_{n-1}\) |
- |
Normal population |
| \(\frac{S_1^2/\sigma_1^2}{S_2^2/\sigma_2^2}\) |
\(F_{n_1-1,n_2-1}\) |
- |
Normal populations |
Pivotal Quantity
A pivotal quantity (or pivot) is a function of the sample data and an
unknown parameter whose probability distribution does
not depend on the unknown parameter.
For example, in normal distribution with known variance, we have
\[
X_1, \dots, X_n \sim \text{N}(\mu, \sigma^2), \quad \sigma^2 \text{
known}
\]
The sample mean follows normal distribution: \(\bar{X} \sim \text{N}\left(\mu,
\frac{\sigma^2}{n}\right)\)
According to the definition of pivotal quantity,
\[
Z = \frac{\bar{X} - \mu}{\sigma / \sqrt{n}} \sim \text{N}(0,1)
\]
is pivot since \(N(0, 1)\) is
independent on \(\mu\). If the normal
distribution has unknown variance, the sample variance
\[
S^2 = \frac{1}{n-1}\sum_{i=1}^n (X_i - \bar{X})^2.
\]
The following standardized expression
\[
T = \frac{\bar{X} - \mu}{S / \sqrt{n}} \sim t_{n-1}
\]
is a pivotal quantity since the t-distribution does not depend on
\(\mu\).
Similarly, \((n-1)S^2/\sigma^2\) and
\(\frac{S_1^2/\sigma_1^2}{S_2^2/\sigma_2^2}\)
in the above summary table are pivotal quantities.
Conclusion
Understanding sampling distributions is fundamental to
statistical inference:
Exact distributions provide precise results when assumptions are
met
Asymptotic distributions offer approximations for large
samples
The choice between exact and asymptotic methods depends on sample
size, distributional assumptions, and the specific parameter being
estimated
Modern computing allows for empirical verification of these
theoretical results
These distributions form the theoretical foundation for hypothesis
testing, confidence intervals, and many other statistical
procedures.
LS0tDQp0aXRsZTogIlNhbXBsaW5nIERpc3RyaWJ1dGlvbnMiDQphdXRob3I6ICJDaGVuZyBQZW5nIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCg0KIyMgbGlicmFyeShsZWFwcykNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQoNClwNCg0KDQojIEludHJvZHVjdGlvbg0KDQpTYW1wbGluZyBkaXN0cmlidXRpb25zIGZvcm0gdGhlIGNvcm5lcnN0b25lIG9mIHN0YXRpc3RpY2FsIGluZmVyZW5jZS4gVGhleSBkZXNjcmliZSB0aGUgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIG9mIGEgKipzYW1wbGUgc3RhdGlzdGljKiogY2FsY3VsYXRlZCBmcm9tIHJhbmRvbSBzYW1wbGVzLiBUaGlzIG5vdGUgZXhwbG9yZXMgYm90aCBleGFjdCAoZmluaXRlLXNhbXBsZSkgYW5kIGFzeW1wdG90aWMgKGxhcmdlLXNhbXBsZSkgZGlzdHJpYnV0aW9ucyBmb3Iga2V5IHN0YXRpc3RpY3MgaW5jbHVkaW5nIHNhbXBsZSBtZWFucywgcHJvcG9ydGlvbnMsIGFuZCByZWxhdGVkIHRlc3Qgc3RhdGlzdGljcy4NCg0KDQojIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiB0aGUgU2FtcGxlIE1lYW4NCg0KV2hlbiB0aGUgcG9wdWxhdGlvbiBpcyBub3JtYWwsIGJ5IHRoZSBwcm9wZXJ0eSBvZiBub3JtYWwgZGlzdHJpYnV0aW9uLCB0aGUgc3VtIG9mIHRoZSBpaWQgcmFuZG9tIHZhcmlhYmxlcyBhcmUgKipleGFjdGx5Kiogbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIElmIHRoZSBwb3B1bGF0aW9uIGlzIG5vdCBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHVzaW5nIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gKENMVCksIHRoZSBzdW0gb2YgdGhlIGlpZCByYW5kb20gdmFyaWFibGVzIGlzICoqYXN5bXB0b3RpY2FsbHkqKiBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KDQojIyBFeGFjdCBEaXN0cmlidXRpb24NCg0KRm9yIGEgcmFuZG9tIHNhbXBsZSAkWF8xLCBYXzIsIFxsZG90cywgWF9uJCBmcm9tIGEgbm9ybWFsIHBvcHVsYXRpb24gJE4oXG11LCBcc2lnbWFeMikkLCB0aGUgc2FtcGxlIG1lYW4gaGFzIGFuIGV4YWN0IG5vcm1hbCBkaXN0cmlidXRpb246DQoNCiQkDQpcYmFye1h9IFx0byBOXGxlZnQoXG11LCAgXGZyYWN7XHNpZ21hfXtcc3FydHtufX1ccmlnaHQpDQokJA0KDQpUaGUgc3RhbmRhcmRpemVkIHZlcnNpb24gaXM6DQoNCiQkDQpaID0gXGZyYWN7XGJhcntYfS1cbXV9e1xzaWdtYS9cc3FydHtufX0gXG92ZXJzZXR7ZH17XHRvfSBOKDAsIDEpDQokJA0KDQoqKkV4YW1wbGUqKjogV2Ugc2ltdWxhdGUgZGF0YSBmcm9tIG5vcm1hbCBkaXN0cmlidXRpb24gdG8gZXhwbGFpbiB0aGUgYWJvdmUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBtZWFucyBmcm9tIGEgbm9ybWFsIHBvcHVsYXRpb24uDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0KbiA8LSAxMA0KbXUgPC0gNQ0Kc2lnbWEgPC0gMg0KDQpuLnNhbXBsZXMgPC0gMTAwMDANCnNhbXBsZS5tZWFucyA8LSByZXBsaWNhdGUobi5zYW1wbGVzLCBtZWFuKHJub3JtKG4sIG11LCBzaWdtYSkpKSAgIyByZXBsaWNhdGUoKSBpcyBhIHdyYXBwZXIgZnVuY3Rpb24gDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2FwcGx5KCkNCg0KIyBDcmVhdGUgdGhlb3JldGljYWwgY3VydmUgZGF0YQ0KeC52YWxzIDwtIHNlcShtdSAtIDMqc2lnbWEvc3FydChuKSwgbXUgKyAzKnNpZ21hL3NxcnQobiksIGxlbmd0aC5vdXQgPSAxMDApDQp0aGVvcnkuZGVuc2l0eSA8LSBkbm9ybSh4LnZhbHMsIG1lYW4gPSBtdSwgc2QgPSBzaWdtYS9zcXJ0KG4pKQ0KdGhlb3J5LmRmIDwtIGRhdGEuZnJhbWUoeCA9IHgudmFscywgZGVuc2l0eSA9IHRoZW9yeS5kZW5zaXR5KQ0KDQp4YmFyLnBsdCA8LSBnZ3Bsb3QoZGF0YS5mcmFtZShtZWFuID0gc2FtcGxlLm1lYW5zKSwgYWVzKHggPSBtZWFuKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgYmlucyA9IDUwLCBhbHBoYSA9IDAuNywgZmlsbCA9ICJncmF5IikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHRoZW9yeS5kZiwgYWVzKHggPSB4LCB5ID0gZGVuc2l0eSksIA0KICAgICAgICAgICAgY29sb3IgPSAicmVkIiwgbGluZXdpZHRoID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIkV4YWN0IFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiBTYW1wbGUgTWVhbiBcbk5vcm1hbCBQb3B1bGF0aW9uIChuID0gMTApIiwNCiAgICAgICB4ID0gIlNhbXBsZSBNZWFuIiwgeSA9ICJEZW5zaXR5IikgKw0KICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSAzNSwgciA9IDIwLCBiID0gMzAsIGwgPSAzMCwgdW5pdCA9ICJwdCIpKQ0KDQpnZ3Bsb3RseSh4YmFyLnBsdCkNCg0KYGBgDQoNCg0KIyMgQXN5bXB0b3RpYyBTYW1wbGluZyBEaXN0cmlidXRpb24gKENlbnRyYWwgTGltaXQgVGhlb3JlbSkNCg0KVGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGlzIHRoZSBhcHByb3hpbWF0ZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gb2YgYSBzYW1wbGUgc3RhdGlzdGljIChsaWtlIHRoZSBtZWFuLCBwcm9wb3J0aW9uLCBvciByZWdyZXNzaW9uIGNvZWZmaWNpZW50KSB3aGVuIHRoZSBzYW1wbGUgc2l6ZSAkbiQgaXMgdmVyeSBsYXJnZSAoKmFwcHJvYWNoZXMgaW5maW5pdHkqKS4NCg0KDQpGb3IgYW55IHBvcHVsYXRpb24gd2l0aCBmaW5pdGUgbWVhbiAkXG11JCBhbmQgdmFyaWFuY2UgJFxzaWdtYV4yJCwgYXMgJG4gXHRvIFxpbmZ0eSQ6DQoNCg0KDQokJA0KWiA9IFxmcmFje1xiYXJ7WH0tXG11fXtcc2lnbWEvXHNxcnR7bn19IFx0b197XHRleHR7YXBwcm94fX0gTigwLCAxKQ0KJCQNCg0KDQoqKkV4YW1wbGUqKiBXZSBzaW11bGF0aW9uIDEwMDAwMCByYW5zb20gc2FtcGxlcyB3aXRoIHNpemUgNTAgZnJvbSBhIHNrZXdlZCBleHBvbmVudGlhbCBwb3B1bGF0aW9uLiBBcyB0aGUgc2FtcGxlIHNpemUgZ2V0cyBsYXJnZXIsIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBtZWFucyBhcmUgYXBwcm94aW1hdGVseSBkaXN0cmlidXRlZC4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQpuLmxhcmdlIDwtIDUwDQpsYW1iZGEgPC0gMS81ICAjIE1lYW4gPSA1DQoNCiMgR2VuZXJhdGUgbXVsdGlwbGUgc2FtcGxlcyBmcm9tIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbg0Kbi5zYW1wbGVzIDwtIDEwMDAwDQpleHAubWVhbnMgPC0gcmVwbGljYXRlKG4uc2FtcGxlcywgbWVhbihyZXhwKG4ubGFyZ2UsIHJhdGUgPSBsYW1iZGEpKSkNCg0KIyBDb21wYXJlIHdpdGggbm9ybWFsIGFwcHJveGltYXRpb24NCnRoZW9yZXRpY2FsLm1lYW4gPC0gMS9sYW1iZGEgICMgNQ0KdGhlb3JldGljYWwuc2QgPC0gKDEvbGFtYmRhKS9zcXJ0KG4ubGFyZ2UpICAjIDUvc3FydCg1MCkNCg0KdGhlb3J5LmRlbnNpdHkgPC0gZG5vcm0oeC52YWxzLCBtZWFuID0gdGhlb3JldGljYWwubWVhbiwgc2QgPSB0aGVvcmV0aWNhbC5zZCkNCnRoZW9yeS5kZiA8LSBkYXRhLmZyYW1lKHggPSB4LnZhbHMsIGRlbnNpdHkgPSB0aGVvcnkuZGVuc2l0eSkNCg0KIyBPcHRpb24gMTogVXNlIG9ubHkgc3RhdF9mdW5jdGlvbiBmb3IgdGhlb3JldGljYWwgY3VydmUgKFJlY29tbWVuZGVkKQ0KZ2cuY2x0IDwtIGdncGxvdChkYXRhLmZyYW1lKG1lYW4gPSBleHAubWVhbnMpLCBhZXMoeCA9IG1lYW4pKSArDQogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gYWZ0ZXJfc3RhdChkZW5zaXR5KSksIGJpbnMgPSA1MCwgYWxwaGEgPSAwLjcsIGZpbGwgPSAibGlnaHRncmVlbiIpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSB0aGVvcnkuZGYsIGFlcyh4ID0geCwgeSA9IGRlbnNpdHkpLCANCiAgICAgICAgICAgIGNvbG9yID0gInJlZCIsIGxpbmV3aWR0aCA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJBc3ltcHRvdGljIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiBTYW1wbGUgTWVhbiBcbkV4cG9uZW50aWFsIFBvcHVsYXRpb24gKG4gPSA1MCkiLA0KICAgICAgIHggPSAiU2FtcGxlIE1lYW4iLCB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gMzUsIHIgPSAyMCwgYiA9IDMwLCBsID0gMzAsIHVuaXQgPSAicHQiKSkNCiNnZy5jbHQNCmdncGxvdGx5KGdnLmNsdCkNCmBgYA0KDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipOb3RlKio6IFRoZSBhc3ltcHRvdGljIGFwcHJveGltYXRpb24gdG8gdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4gaG9sZHMgcmVnYXJkbGVzcyBvZiB0aGUgc2hhcGUgb2YgdGhlIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uIChwcm92aWRlZCB0aGUgcG9wdWxhdGlvbiBoYXMgZmluaXRlIG1lYW4gYW5kIHZhcmlhbmNlKS48L2ZvbnQ+DQoNCjxmb250IGNvbG9yID0gImJsdWUiPioqUmVtYXJrKio6IFRoZXJlIGlzIG5vIHBhcmFtZXRlciBpbiB0aGUgc3RhbmRhcmQgbm9ybWFsIGRpc3RyaWJ1dGlvbi48L2ZvbnQ+DQoNClwNCg0KIyBTdHVkZW50J3MgdC1EaXN0cmlidXRpb24NCg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqTGV0ICRce1hfMSwgWF8yLCBcY2RvdHMsIFhfbiBcfSBcb3ZlcnNldHtcdGV4dHtpLmkuZH19e1xzaW19IE4oXG11LCBcc2lnbWEpJC4qKjwvZm9udD4gRGVmaW5lIHRoZSBzYW1wbGUgbWVhbiB0byBiZQ0KDQokJA0KXGJhcntYfSA9IFxmcmFje1xzdW1fe2k9MX1ebiBYX2l9e259Lg0KJCQNCg0KV2hlbiBwb3B1bGF0aW9uIHZhcmlhbmNlICRcc2lnbWFeMiQgaXMgdW5rbm93biBhbmQgZXN0aW1hdGVkIGJ5IHNhbXBsZSB2YXJpYW5jZSAkU14yJDoNCg0KJCQNClQgPSBcZnJhY3tcYmFye1h9LVxtdX17Uy9cc3FydHtufX0gXG92ZXJzZXR7ZH17XHRvfSAgdF97bi0xfQ0KJCQNCg0Kd2hlcmUgDQoNCiQkDQpTXjIgPSBcZnJhY3sxfXtuLTF9XHN1bV97aT0xfV5uIChYX2kgLSBcYmFye1h9KV4yLg0KJCQNCg0KPGZvbnQgY29sb3IgPSAicmVkIj4qKk5vdGUqKjogKlRoZSB0LWRpc3RyaWJ1dGlvbiBkZXBlbmRzIG9uIGEgc2luZ2xlIHBhcmFtZXRlcjogdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSwgJFxudSQsIHdoaWNoIGVxdWFscyAkbi0xJCBmb3IgYSBzYW1wbGUgb2Ygc2l6ZSAkbiQuIEJlY2F1c2UgJFxudSQgaXMgZml4ZWQgb25jZSB0aGUgc2FtcGxlIHNpemUgaXMga25vd27igJRhbmQgZG9lcyBub3QgbmVlZCB0byBiZSBlc3RpbWF0ZWQgZnJvbSB0aGUgc2FtcGxlIGRhdGHigJRpdCBpcyBvY2Nhc2lvbmFsbHkgdHJlYXRlZCBpbiBhcHBsaWNhdGlvbnMgYXMgaWYgdGhlIGRpc3RyaWJ1dGlvbiBoYWQgbm8gcGFyYW1ldGVycy4qIDwvZm9udD4NCg0KDQoqKkV4YW1wbGUqKjogU2luY2UgdGhlIGFib3ZlIHQtZGlzdHJpYnV0aW9uIGlzIGRlZmluZWQgYmFzZWQgb24gYSBub3JtYWwgZGlzdHJpYnV0aW9uLCB3ZSB3aWxsIHNpbXVsYXRlIHJhbmRvbSBzYW1wbGVzIGZyb20gYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggZmluaXRlIG1lYW4gYW5kIHZhcmlhbmNlLg0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCm4gPC0gMTANCm11IDwtIDUNCnNpZ21hIDwtIDINCg0KIyBHZW5lcmF0ZSB0LXN0YXRpc3RpY3MNCm4uc2FtcGxlcyA8LSAxMDAwMA0KdC5zdGF0cyA8LSBudW1lcmljKG4uc2FtcGxlcykgICMgVGhpcyBkZWZpbmVzIGEgMTAwMDAgZGltZW5zaW9uYWwgemVybyB2ZWN0b3INCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHQudGVzdCA8LSBOVUxMIHVzZXMgbW9yZSBjb21wdXRpbmcgcmVzb3VyY2UNCmZvcihpIGluIDE6bi5zYW1wbGVzKSB7DQogIHNhbXBsZS5kYXRhIDwtIHJub3JtKG4sIG11LCBzaWdtYSkNCiAgeC5iYXIgPC0gbWVhbihzYW1wbGUuZGF0YSkNCiAgcyA8LSBzZChzYW1wbGUuZGF0YSkNCiAgdC5zdGF0c1tpXSA8LSAoeC5iYXIgLSBtdSkgLyAocy9zcXJ0KG4pKQ0KfQ0KDQojIENvbXBhcmUgd2l0aCB0aGVvcmV0aWNhbCB0LWRpc3RyaWJ1dGlvbg0KeC52YWxzIDwtIHNlcSgtNCwgNCwgbGVuZ3RoLm91dCA9IDIwMCkNCnRoZW9yZXRpY2FsLnQgPC0gZHQoeC52YWxzLCBkZiA9IG4tMSkgICAgIyBjYWxsaW5nIHQtZGVuc2l0eSBmdW5jdGlvbg0KdGhlb3JldGljYWwubm9ybWFsIDwtIGRub3JtKHgudmFscykgICAgICAjIHN0YW5kYXJkIG5vcm1hbCBkaXN0cmlidXRpb24NCg0KY29tcGFyaXNvbi5kZiA8LSBkYXRhLmZyYW1lKA0KICB4ID0gcmVwKHgudmFscywgMiksDQogIGRlbnNpdHkgPSBjKHRoZW9yZXRpY2FsLnQsIHRoZW9yZXRpY2FsLm5vcm1hbCksDQogIGRpc3RyaWJ1dGlvbiA9IHJlcChjKCJ0KDkpIiwgIk4oMCwxKSIpLCBlYWNoID0gbGVuZ3RoKHgudmFscykpDQopDQoNCnQucGx0IDwtIGdncGxvdChjb21wYXJpc29uLmRmLCBhZXMoeCA9IHgsIHkgPSBkZW5zaXR5LCBjb2xvciA9IGRpc3RyaWJ1dGlvbikpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAidC1EaXN0cmlidXRpb24gdnMgTm9ybWFsIERpc3RyaWJ1dGlvbiIsDQogICAgICAgeCA9ICJWYWx1ZSIsIHkgPSAiRGVuc2l0eSIpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDM1LCByID0gMjAsIGIgPSAzMCwgbCA9IDMwLCB1bml0ID0gInB0IikpICsNCiAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCAiYmx1ZSIpKQ0KZ2dwbG90bHkodC5wbHQpDQpgYGANCg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPiAqKkNhdXRpb246KiogVGhlIHN0YW5kYXJkaXplZCBzYW1wbGUgbWVhbiBmb2xsb3dzIGEgdC1kaXN0cmlidXRpb24uIE1vcmUgcHJlY2lzZWx5LCB3aGVuIHNhbXBsaW5nIGZyb20gYSBub3JtYWwgcG9wdWxhdGlvbiB3aXRoIHVua25vd24gbWVhbiAkXG11JCBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uICRcc2lnbWEkLCB0aGUgdC1zdGF0aXN0aWMgKGNhbGN1bGF0ZWQgdXNpbmcgdGhlIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24pIGZvbGxvd3MgYSB0LWRpc3RyaWJ1dGlvbi4gPC9mb250Pg0KDQoNCg0KIyBTYW1wbGluZyBEaXN0cmlidXRpb24gb2YgU2FtcGxlIFByb3BvcnRpb24NCg0KTGV0ICRYXzEsIFhfMiwgXGRvdHMsIFhfbiQgYmUgaW5kZXBlbmRlbnQgYW5kIGlkZW50aWNhbGx5IGRpc3RyaWJ1dGVkIEJlcm5vdWxsaSByYW5kb20gdmFyaWFibGVzIHdpdGggcGFyYW1ldGVyICRwJCwgd2hlcmU6DQoNCiogJFhfaSA9IDEkIHdpdGggcHJvYmFiaWxpdHkgJHAkIChzdWNjZXNzKQ0KKiAkWF9pID0gMCQgd2l0aCBwcm9iYWJpbGl0eSAkMS1wJCAoZmFpbHVyZSkNCiANCg0KVGhlIHNhbXBsZSBwcm9wb3J0aW9uIGlzIGRlZmluZWQgYXM6DQoNCiQkDQpcaGF0e3B9ID0gXGZyYWN7MX17bn0gXHN1bV97aT0xfV5uIFhfaQ0KJCQNCg0Kd2hlcmUgJG4kIGlzIHRoZSBmaXhlZCBzYW1wbGUgc2l6ZS4NCg0KSW4gcHJhY3RpY2UsIHdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGxhcmdlLCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiBpcyBnZW5lcmFsbHkgY2hhcmFjdGVyaXplZCB1c2luZyBhcHByb3hpbWF0aW9ucy4gRm9yIHNtYWxsIHNhbXBsZXMsIGhvd2V2ZXIsIHRoZSBleGFjdCBzYW1wbGluZyBkaXN0cmlidXRpb24gbXVzdCBiZSB1c2VkLg0KDQojIyBFeGFjdCBEaXN0cmlidXRpb24NCg0KRm9yIGEgYmlub21pYWwgcG9wdWxhdGlvbiB3aXRoIHN1Y2Nlc3MgcHJvYmFiaWxpdHkgJHAkLCB0aGUgc2FtcGxlIHByb3BvcnRpb24gJFxoYXR7cH0gPSBYL24kIHdoZXJlICRYIFxzaW0gQmlub21pYWwobixwKSQuDQoNClRoZSBleGFjdCBkaXN0cmlidXRpb24gaXMgc2ltcGx5IHRoZSBwcm9iYWJpbGl0eSBtYXNzIGZ1bmN0aW9uIG9mIGEgKipiaW5vbWlhbCBkaXN0cmlidXRpb24qKiB3aXRoIG4gdHJpYWxzIGFuZCBzdWNjZXNzIHByb2JhYmlsaXR5ICRwJDoNCg0KJCQNClAoXGhhdHtwfSA9ay9uKT0gUChuXHRpbWVzIFxoYXR7cH0gPSBrKSA9IFAoWCA9IGspPVxmcmFje24hfXtrIShuLWspIX0gcF5rICgx4oiScClee24ta30sIFwgXCBrID0gMCwgMSwgMiwgXGNkb3RzLCBuLg0KJCQgDQoNCg0KIyMgQXN5bXB0b3RpYyBTYW1wbGluZyBEaXN0cmlidXRpb24gKExhcmdlICRuJCkNCg0KQnkgdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSAoc3BlY2lmaWNhbGx5LCB0aGUgRGUgTW9pdnJlLUxhcGxhY2UgVGhlb3JlbSBmb3IgQmVybm91bGxpIHRyaWFscyk6DQoNCiQkDQpcaGF0e3B9IFxzdGFja3JlbHtkfXtcc2ltfSBOXGxlZnQocCwgXGZyYWN7cCgxLXApfXtufVxyaWdodCkgXHF1YWQgXHRleHR7Zm9yIGxhcmdlIH0gbg0KJCQNCg0KTW9yZSByaWdvcm91c2x5LCBpbiBzdGFuZGFyZGl6ZWQgZm9ybToNCg0KJCQNClpfbiA9IFxmcmFje1xoYXR7cH1fbiAtIHB9e1xzcXJ0e1xmcmFje3AoMS1wKX17bn19fSBcc3RhY2tyZWx7ZH17XHRvfSBOKDAsMSkgXHF1YWQgXHRleHR7YXMgfSBuIFx0byBcaW5mdHkNCiQkDQoNCioqU3VmZmljaWVudCBDb25kaXRpb25zIGZvciBBcHByb3hpbWF0aW9uOioqDQoNCiogJG5wIFxnZXEgMTAkIGFuZCAkbigxLXApIFxnZXEgMTAkIChjb21tb24gcnVsZSBvZiB0aHVtYikNCg0KKiBBbHRlcm5hdGl2ZTogJG4gPiA5IFx0aW1lcyBcbWF4XGxlZnQoXGZyYWN7cH17MS1wfSwgXGZyYWN7MS1wfXtwfVxyaWdodCkkDQoNCg0KDQoqKkV4YW1wbGUqKjogV2Ugc2ltdWxhdGUgcmFuZG9tIHNhbXBsZXMgZnJvbSBiaW5hcnkgcG9wdWxhdGlvbiAoYWxzbyBjYWxsZWQgQmVybm91bGxpIHBvcHVsYXRpb24pIHRvIGRlbW9uc3RyYXRlIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgcHJvcG9ydGlvbi4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQpuIDwtIDEwMA0KcCA8LSAwLjMNCg0KIyBHZW5lcmF0ZSBzYW1wbGUgcHJvcG9ydGlvbnMNCm4uc2FtcGxlcyA8LSAxMDAwMA0Kc2FtcGxlLnByb3BzIDwtIHJlcGxpY2F0ZShuLnNhbXBsZXMsIHJiaW5vbSgxLCBuLCBwKS9uKSAjIHJlcGxpY2F0ZSgpIGlzIGEgd3JhcHBlciANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmdW5jdGlvbiBvZiBzYXBwbHkoKQ0KDQojIENvbXBhcmUgd2l0aCBub3JtYWwgYXBwcm94aW1hdGlvbg0KdGhlb3JldGljYWwubWVhbiA8LSBwDQp0aGVvcmV0aWNhbC5zZCA8LSBzcXJ0KHAqKDEtcCkvbikNCg0KeC52YWxzIDwtIHNlcSgwLDAuNiwgbGVuZ3RoPTEwMCkNCnRoZW9yeS5kZW5zaXR5IDwtIGRub3JtKHgudmFscywgbWVhbiA9IHRoZW9yZXRpY2FsLm1lYW4sIHNkID0gdGhlb3JldGljYWwuc2QpDQp0aGVvcnkuZGYgPC0gZGF0YS5mcmFtZSh4ID0geC52YWxzLCBkZW5zaXR5ID0gdGhlb3J5LmRlbnNpdHkpDQoNCmJpbm9tLnBsdCA8LSBnZ3Bsb3QoZGF0YS5mcmFtZShwcm9wID0gc2FtcGxlLnByb3BzKSwgYWVzKHggPSBwcm9wKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgYmlucyA9IDMwLCBhbHBoYSA9IDAuNywgZmlsbCA9ICJza3libHVlIikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHRoZW9yeS5kZiwgYWVzKHggPSB4LCB5ID0gZGVuc2l0eSksIA0KICAgICAgICAgICAgY29sb3IgPSAicmVkIiwgbGluZXdpZHRoID0gMSkgKw0KICAjc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgDQogICMgICAgICAgICAgICAgIGFyZ3MgPSBsaXN0KG1lYW4gPSB0aGVvcmV0aWNhbF9tZWFuLCBzZCA9IHRoZW9yZXRpY2FsX3NkKSwNCiAgIyAgICAgICAgICAgICAgY29sb3IgPSAicmVkIiwgc2l6ZSA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJTYW1wbGluZyBEaXN0cmlidXRpb24gb2YgU2FtcGxlIFByb3BvcnRpb24iLA0KICAgICAgIHN1YnRpdGxlID0gInAgPSAwLjMsIG4gPSAxMDAiLA0KICAgICAgIHggPSAiU2FtcGxlIFByb3BvcnRpb24iLCB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gMzUsIHIgPSAyMCwgYiA9IDMwLCBsID0gMzAsIHVuaXQgPSAicHQiKSkNCmdncGxvdGx5KGJpbm9tLnBsdCkNCmBgYA0KDQoNCiMgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIFNhbXBsZSBWYXJpYW5jZQ0KDQpXZSBmaXJzdCBpbnRyb2R1Y2UgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSB2YXJpYW5jZSB3aXRob3V0IGRlcml2YXRpb24uIFRoZSBiYXNpYyBzZXR0aW5nIGlzIGdpdmVuIGluIHRoZSBmb2xsb3dpbmcuDQoNCkxldCAkWF8xLCBYXzIsIFxkb3RzLCBYX24gXHN0YWNrcmVse1x0ZXh0e2kuaS5kLn19e1xzaW19IEYkIHdpdGg6DQoNCiogJEVbWF9pXSA9IFxtdSQNCiogJFx0ZXh0e1Zhcn0oWF9pKSA9IFxzaWdtYV4yIDwgXGluZnR5JA0KKiAkRVsoWF9pIC0gXG11KV40XSA9IFxtdV80IDwgXGluZnR5JCAoZmluaXRlIGZvdXJ0aCBjZW50cmFsIG1vbWVudCkNCg0KDQpEZWZpbmUgdGhlIHNhbXBsZSB2YXJpYW5jZToNCg0KJCQNClNeMiA9IFxmcmFjezF9e24tMX0gXHN1bV97aT0xfV5uIChYX2kgLSBcYmFye1h9KV4yDQokJA0Kd2hlcmUgJFxiYXJ7WH0gPSBcZnJhY3sxfXtufSBcc3VtX3tpPTF9Xm4gWF9pJC4NCg0KDQojIyBBc3ltcHRvdGljIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiBTYW1wbGUgVmFyaWFuY2UNCg0KV2hlbiBzYW1wbGUgc2l6ZSBuIGlzIGxhcmdlLCB0aGUgc2FtcGxlIHZhcmlhbmNlICRTXjIkIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgYXMNCg0KJCQNClNeMiBcc3RhY2tyZWx7ZH17XHRvfSBOXGxlZnQoXHNpZ21hXjIsIFxmcmFje1xtdV80IC0gXHNpZ21hXjR9e259XHJpZ2h0KSBccXVhZCBcdGV4dHthcyB9IG4gXHRvIFxpbmZ0eSwNCiQkDQplcXVpdmFsZW50bHksDQoNCiQkDQpcZnJhY3tTXjIgLSBcc2lnbWFeMn17XHNxcnR7XGZyYWN7XG11XzQgLSBcc2lnbWFeNH17bn19fSBcc3RhY2tyZWx7ZH17XHRvfSBOKDAsMSkgXHF1YWQgXHRleHR7YXMgfSBuIFx0byBcaW5mdHkuDQokJA0KDQoNCkluIHByYWN0aWNlLCB0aGUgZm91cnRoIG1vbWVudCwgICRcbXVfNCQsIGNhbiBiZSBlc3RpbWF0ZWQgZnJvbSBzYW1wbGUsIHdoaWNoIHdpbGwgYmUgZGlzY3Vzc2VkIGluIHN1YnNlcXVlbnQgdG9waWNzLg0KDQoNCiMjIFNwZWNpYWwgQ2FzZTogTm9ybWFsIFBvcHVsYXRpb24NCg0KV2hlbiBzYW1wbGluZyBmcm9tIGEgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgcG9wdWxhdGlvbiwgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIHZhcmlhbmNlIGNhbiBiZSBmdWxseSBjaGFyYWN0ZXJpemVkIHRocm91Z2ggYSBjaGktc3F1YXJlZCBkaXN0cmlidXRpb24gd2l0aCBhcHByb3ByaWF0ZSBzY2FsaW5nLiANCg0KVGhlIGNoaS1zcXVhcmVkIGRpc3RyaWJ1dGlvbiBpcyBhIHNwZWNpYWwgY2FzZSBvZiB0aGUgZ2FtbWEgZGlzdHJpYnV0aW9uIGFuZCBjYW4gYWxzbyBiZSBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uLiBTcGVjaWZpY2FsbHksIHdlIGhhdmUgdGhlIGZvbGxvd2luZyByZXN1bHQ6DQoNCkZvciAkWl8xLCBaXzIsIFxsZG90cywgWl9rIFxzdGFja3JlbHtpaWR9e1xzaW19IE4oMCwxKSQsIHVzaW5nIG1vbWVudCBnZW5lcmF0aW5nIGZ1bmN0aW9uLCB3ZSBjYW4gc2hvdyB0aGF0DQoNCiQkDQpRPVxzdW1fe2k9MX1eayBaX2leMiBcb3ZlcnNldHtkfXtcdG99IFxjaGlfa14yLg0KJCQNCiANClVzaW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgc3RhbmRhcmQgbm9ybWFsIGFuZCBjaGktc3F1YXJlZCBkaXN0cmlidXRpb25zLCB3ZSBjYW4gZGVyaXZlIHRoZSBleGFjdCBkaXN0cmlidXRpb24gb2YgdGhlIHNjYWxlZCBzYW1wbGUgdmFyaWFuY2UgZm9yIGEgbm9ybWFsIHBvcHVsYXRpb246DQoNCiQkDQpcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9IFxvdmVyc2V0e2R9e1x0b30gXGNoaV97bi0xfV4yLg0KJCQNCg0KKipQcm9vZiA8Zm9udCBjb2xvciA9ICJyZWQiPltvcHRpb25hbF08L2ZvbnQ+Kio6IFdlIHByb3ZlIHRoaXMgaW4gc2V2ZXJhbCBzdGVwczoNCg0KV2Ugc2hvdyB0aGF0IGZvciAkWF8xLCBcZG90cywgWF9uIFxzdGFja3JlbHtpaWR9e1xzaW19IE4oXG11LCBcc2lnbWFeMikkLCB3aXRoDQoNCiQkDQpTXjIgPSBcZnJhY3sxfXtuLTF9IFxzdW1fe2k9MX1ebiAoWF9pIC0gXGJhcntYfSleMiwgXHF1YWQgXGJhcntYfSA9IFxmcmFjezF9e259IFxzdW1fe2k9MX1ebiBYX2ksDQokJA0KDQp3ZSBoYXZlDQoNCiQkDQpcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9IFxzaW0gXGNoaV97bi0xfV4yLg0KJCQNCg0KKipTdGVwIDE6IFN0YW5kYXJkaXplIGFuZCBkZWZpbmUgbm90YXRpb24qKg0KDQpMZXQgJFpfaSA9IFxmcmFje1hfaSAtIFxtdX17XHNpZ21hfSBcc2ltIE4oMCwxKSQsIGkuaS5kLiBUaGVuDQoNCiQkDQpcYmFye1p9ID0gXGZyYWN7MX17bn0gXHN1bV97aT0xfV5uIFpfaSA9IFxmcmFje1xiYXJ7WH0gLSBcbXV9e1xzaWdtYX0uDQokJA0KDQpXZSBjYW4gd3JpdGU6DQoNCiQkDQpcc3VtX3tpPTF9Xm4gKFhfaSAtIFxiYXJ7WH0pXjIgPSBcc2lnbWFeMiBcc3VtX3tpPTF9Xm4gKFpfaSAtIFxiYXJ7Wn0pXjIuDQokJA0KDQpTbw0KDQokJA0KXGZyYWN7KG4tMSlTXjJ9e1xzaWdtYV4yfSA9IFxmcmFje1xzdW1fe2k9MX1ebiAoWF9pIC0gXGJhcntYfSleMn17XHNpZ21hXjJ9ID0gXHN1bV97aT0xfV5uIChaX2kgLSBcYmFye1p9KV4yLg0KJCQNCg0KKipTdGVwIDI6IE9ydGhvZ29uYWwgdHJhbnNmb3JtYXRpb24qKg0KDQpMZXQgXCggXG1hdGhiZntafSA9IChaXzEsIFxkb3RzLCBaX24pXlQgXCkuIENob29zZSBhbiBcKCBuIFx0aW1lcyBuIFwpIG9ydGhvZ29uYWwgbWF0cml4IFwoIFEgXCkgd2hvc2UgZmlyc3Qgcm93IGlzIFwoIFxsZWZ0KCBcZnJhY3sxfXtcc3FydHtufX0sIFxkb3RzLCBcZnJhY3sxfXtcc3FydHtufX0gXHJpZ2h0KSBcKS4gRGVmaW5lDQoNCiQkDQpcbWF0aGJme1l9ID0gUSBcbWF0aGJme1p9Lg0KJCQNCg0KVGhlbjoNCg0KKiAkWV8xID0gXGZyYWN7MX17XHNxcnR7bn19IFxzdW1fe2k9MX1ebiBaX2kgPSBcc3FydHtufSBcLCBcYmFye1p9JC4NCiogU2luY2UgJFEkIGlzIG9ydGhvZ29uYWwgYW5kICRcbWF0aGJme1p9IFxzaW0gTigwLCBJX24pJCwgd2UgaGF2ZSAkXG1hdGhiZntZfSBcc2ltIE4oMCwgSV9uKSQgYXMgd2VsbCwgc28gJFlfMSwgXGRvdHMsIFlfbiQgYXJlIGkuaS5kLlwgJE4oMCwxKSQuDQoNCg0KKipTdGVwIDM6IEV4cHJlc3Mgc3VtIG9mIHNxdWFyZXMgaW4gdGVybXMgb2YgXCggWV9qIFwpKioNCg0KT3J0aG9nb25hbGl0eSBpbXBsaWVzOg0KDQokJA0KXHN1bV97aT0xfV5uIFpfaV4yID0gXHN1bV97aj0xfV5uIFlfal4yLg0KJCQNCg0KQWxzbywNCg0KJCQNClxzdW1fe2k9MX1ebiAoWl9pIC0gXGJhcntafSleMiA9IFxzdW1fe2k9MX1ebiBaX2leMiAtIG4gXGJhcntafV4yLg0KJCQNCg0KQnV0ICRuIFxiYXJ7Wn1eMiA9IFlfMV4yJCwgc28NCg0KJCQNClxzdW1fe2k9MX1ebiAoWl9pIC0gXGJhcntafSleMiA9IFxzdW1fe2o9MX1ebiBZX2peMiAtIFlfMV4yID0gXHN1bV97aj0yfV5uIFlfal4yLg0KJCQNCg0KKipTdGVwIDQ6IERpc3RyaWJ1dGlvbioqDQoNClNpbmNlICRZXzIsIFxkb3RzLCBZX24kIGFyZSBpLmkuZC5cICROKDAsMSkkLCB3ZSBoYXZlDQoNCiQkDQpcc3VtX3tqPTJ9Xm4gWV9qXjIgXHNpbSBcY2hpX3tuLTF9XjIuDQokJA0KDQpUaHVzDQoNCiQkDQpcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9ID0gXHN1bV97aT0xfV5uIChaX2kgLSBcYmFye1p9KV4yID0gXHN1bV97aj0yfV5uIFlfal4yIFxvdmVyc2V0e2R9e1x0b30gXGNoaV97bi0xfV4yLg0KJCQNCg0KKipTdGVwIDU6IEluZGVwZW5kZW5jZSBmcm9tIFwoIFxiYXJ7WH0gXCkqKg0KDQpTaW5jZSAkWV8xID0gXHNxcnR7bn0gXGJhcntafSQgaXMgaW5kZXBlbmRlbnQgb2YgJFlfMiwgXGRvdHMsIFlfbiQsIGl0IGZvbGxvd3MgdGhhdCAkXGJhcntYfSQgaXMgaW5kZXBlbmRlbnQgb2YgJFNeMiQuIFRoYXQgaXMsDQoNCiQkDQpcYm94ZWR7XGZyYWN7KG4tMSlTXjJ9e1xzaWdtYV4yfSBcdG8gXGNoaV97bi0xfV4yfQ0KJCQNCg0KKipFeGFtcGxlKio6IFRoZSAkXGNoaV4yJCBkaXN0cmlidXRpb24gaXMgZGVyaXZlZCBmcm9tIHRoZSBzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uLiBXZSBzaW11bGF0ZSBzdGFuZGFyZCBub3JtYWwgcmFuZG9tIG51bWJlcnMgYW5kIHRoZW4gdHJhbnNmb3JtIHRoZW0gaW50byAkXGNoaV4yJCByYW5kb20gdmFyaWFibGVzIGJhc2VkIG9uIHRoZSBkZXJpdmF0aW9ucyBhYm92ZS4gQSBoaXN0b2dyYW0gd2lsbCBiZSBwbG90dGVkIGFuZCBvdmVybGFpZCB3aXRoIHRoZSB0aGVvcmV0aWNhbCAkXGNoaV4yJCBkZW5zaXR5IGN1cnZlLg0KDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0KbiA8LSAxMA0Kc2lnbWEgPC0gMg0KDQojIEdlbmVyYXRlIGNoaS1zcXVhcmUgc3RhdGlzdGljcw0Kbi5zYW1wbGVzIDwtIDEwMDAwDQpjaGlzcS5zdGF0cyA8LSBudW1lcmljKG4uc2FtcGxlcykNCg0KZm9yKGkgaW4gMTpuLnNhbXBsZXMpIHsNCiAgc2FtcGxlLmRhdGEgPC0gcm5vcm0obiwgMCwgc2lnbWEpDQogIGNoaXNxLnN0YXRzW2ldIDwtIHN1bSgoc2FtcGxlLmRhdGEvc2lnbWEpXjIpDQp9DQoNCiMgQ29tcGFyZSB3aXRoIHRoZW9yZXRpY2FsIGNoaS1zcXVhcmUNCngudmFscyA8LSBzZXEoMCwgMzAsIGxlbmd0aC5vdXQgPSAyMDApDQp0aGVvcmV0aWNhbC5jaGlzcSA8LSBkY2hpc3EoeC52YWxzLCBkZiA9IG4pDQp0aGVvcnkuZGYgPC0gZGF0YS5mcmFtZSh4ID0geC52YWxzLCBkZW5zaXR5ID0gdGhlb3JldGljYWwuY2hpc3EpDQoNCmNoaS5wbHQgPC0gZ2dwbG90KGRhdGEuZnJhbWUoeCA9IGNoaXNxLnN0YXRzKSwgYWVzKHggPSB4KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgYmlucyA9IDUwLCBhbHBoYSA9IDAuNywgZmlsbCA9ICJzdGVlbGJsdWUiKSArDQogIGdlb21fbGluZShkYXRhID0gdGhlb3J5LmRmLCBhZXMoeCA9IHgsIHkgPSBkZW5zaXR5KSwgDQogICAgICAgICAgICBjb2xvciA9ICJyZWQiLCBsaW5ld2lkdGggPSAxKSArDQogICNzdGF0X2Z1bmN0aW9uKGZ1biA9IGRjaGlzcSwgYXJncyA9IGxpc3QoZGYgPSBuKSwgY29sb3IgPSAicmVkIiwgc2l6ZSA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJDaGktU3F1YXJlIERpc3RyaWJ1dGlvbiIsDQogICAgICAgc3VidGl0bGUgPSAiU3VtIG9mIHNxdWFyZWQgc3RhbmRhcmQgbm9ybWFscyIsDQogICAgICAgeCA9ICJWYWx1ZSIsIHkgPSAiRGVuc2l0eSIpICsNCiAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gMzUsIHIgPSAyMCwgYiA9IDMwLCBsID0gMzAsIHVuaXQgPSAicHQiKSkNCmdncGxvdGx5KGNoaS5wbHQpDQpgYGANCg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPiAqKlJlbWFyayoqIEJvdGggdGhlIGNoaS1zcXVhcmVkIGFuZCB0LWRpc3RyaWJ1dGlvbnMgYXJlIHBhcmFtZXRlcml6ZWQgYnkgZGVncmVlcyBvZiBmcmVlZG9tLiBJbiBwYXJ0aWN1bGFyLCB0aGUgc2NhbGVkIHNhbXBsZSB2YXJpYW5jZSBmcm9tIGEgc2FtcGxlIG9mIHNpemUgJG4kIGZvbGxvd3MgYSBjaGktc3F1YXJlZCBkaXN0cmlidXRpb24gd2l0aCAkbuKIkjEkIGRlZ3JlZXMgb2YgZnJlZWRvbS4gPC9mb250Pg0KDQoNCiMgRi1EaXN0cmlidXRpb24NCg0KVGhlIEYtZGlzdHJpYnV0aW9uIHNlcnZlcyBhcyB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGZvciB0aGUgcmF0aW8gb2YgdHdvIGluZGVwZW5kZW50IHNhbXBsZSB2YXJpYW5jZXMuIFZhcmlhbmNlIGlzIGEga2V5IG1lYXN1cmUgb2YgcXVhbGl0eSBhY3Jvc3MgZGlzY2lwbGluZXMsIHdoZXJlIGhpZ2hlciB2YXJpYW5jZSBjb3JyZXNwb25kcyB0byBsb3dlciBxdWFsaXR5LiBXaGVuIGNvbXBhcmluZyBxdWFsaXR5IHZpYSB2YXJpYW5jZXMsIGJvdGggZGlmZmVyZW5jZXMgYW5kIHJhdGlvcyBhcmUgY29uY2VpdmFibGUuIEhvd2V2ZXIsIHVuZGVyIG5vcm1hbCBwb3B1bGF0aW9uIGFzc3VtcHRpb25zLCB0aGUgZGlmZmVyZW5jZSBvZiB0d28gc2FtcGxlIHZhcmlhbmNlcyBsYWNrcyBhIGNvbnZlbmllbnQga25vd24gZGlzdHJpYnV0aW9uLCB3aGlsZSB0aGUgYXBwcm9wcmlhdGVseSBzY2FsZWQgcmF0aW8gZm9sbG93cyB0aGUgJEYkIGRpc3RyaWJ1dGlvbi4gIA0KDQpUaGUgZm9sbG93aW5nIGlzIHRoZSBzZXR1cCBvZiB0aGUgZGVmaW5pdGlvbiBmb3IgJEYkIGRpc3RyaWJ1dGlvbi4gRm9yIHR3byAqKmluZGVwZW5kZW50KiogcmFuZG9tIHNhbXBsZSBmcm9tIHR3byBub3JtYWwgcG9wdWxhdGlvbnM6DQoNCiQkDQpce1hfMSwgWF8yLCBcY2RvdHMsIFhfe25fMX1cfSAgXG92ZXJzZXR7aS5pLmR9e1xzaW19IE4oXG11XzEsIFxzaWdtYV8xXjIpIFxxdWFkXHRleHR7IGFuZCB9IFxxdWFkIFx7WV8xLCBZXzIsIFxjZG90cywgWV97bl8yfVx9ICBcb3ZlcnNldHtpLmkuZH17XHNpbX0gTihcbXVfMiwgXHNpZ21hXzJeMiksDQokJA0KDQpEZWZpbmUNCg0KJCQNClNfMV4yID0gXGZyYWN7MX17bl8xLTF9IFxzdW1fe2k9MX1ee25fMX0gKFhfaSAtIFxiYXJ7WH0pXjIgXHF1YWRcdGV4dHsgYW5kIH0gXHF1YWQgU18yXjIgPSBcZnJhY3sxfXtuXzItMX0gXHN1bV97aT0xfV57bl8yfSAoWV9pIC0gXGJhcntZfSleMiANCiQkDQoNCiQkDQpGID0gXGZyYWN7U18xXjIvXHNpZ21hXzFeMn17U18yXjIvXHNpZ21hXzJeMn0gXG92ZXJzZXR7ZH17XHRvfSBGX3tuXzEtMSwgbl8yLTF9DQokJA0KIA0Kd2hlcmUgJG5fMS0xJCBhbmQgJG5fMi0xJCBhcmUgZGVncmVlcyBvZiBmcmVlZG9tIG9mIG51bWVyYXRvciBhbmQgZGVub21pbmF0b3IgcmVzcGVjdGl2ZWx5LiBTaW5jZSAkU18xXjIkIGFuZCAkU18yXjIkIGFyZSB1bmJpYXNlZCBmb3IgJFxzaWdtYV8xXjIkIGFuZCAkXHNpZ21hXzJeMiQsIGlmIG91ciBoeXBvdGhlc2lzIGlzICRcc2lnbWFfMV4yID0gXHNpZ21hXzJeMiQgKGluZGljYXRpbmcgZXF1YWwgcHJvZHVjdCBxdWFsaXR5IGluIHZhcmlhbmNlIHRlcm1zKSwgdGhlIGV4cGVjdGVkIEYtcmF0aW8gJEYgPSBTXzFeMi9TXzJeMiQgaXMgYXBwcm94aW1hdGVseSAxLCB0aG91Z2ggaXRzIGFjdHVhbCBkaXN0cmlidXRpb24gaXMgJEZfe25fMS0xLCBuXzItMX0kLiANCg0KDQoNCg0KDQoqKkV4YW1wbGUqKjogVGhlIEYgZGlzdHJpYnV0aW9uIGlzIGRpcmVjdGx5IGRlZmluZWQgYmFzZWQgb24gdHdvIGluZGVwZW5kZW50ICRcY2hpXjIkIGRpc3RyaWJ1dGlvbnMsIHdoaWNoIGFyZSB0aGVtc2VsdmVzIGRlcml2ZWQgZnJvbSBzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9ucy4gVGhlcmVmb3JlLCB3ZSBjb3VsZCBnZW5lcmF0ZSBkYXRhIGZyb20gbm9ybWFsIGRpc3RyaWJ1dGlvbnMgYW5kIHRoZW4gdHJhbnNmb3JtIHRoZW0gaW50byBGIHJhbmRvbSB2YXJpYWJsZXMuIFRvIGtlZXAgdGhlIHByb2Nlc3Mgc2ltcGxlLCB3ZSBnZW5lcmF0ZSBkYXRhIGRpcmVjdGx5IGZyb20gJFxjaGleMiQgZGlzdHJpYnV0aW9ucy4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQpkZjEgPC0gMTANCmRmMiA8LSAxNQ0KDQojIEdlbmVyYXRlIEYgc3RhdGlzdGljcw0Kbi5zYW1wbGVzIDwtIDEwMDAwDQpmLnN0YXRzIDwtIG51bWVyaWMobi5zYW1wbGVzKQ0KDQpmb3IoaSBpbiAxOm4uc2FtcGxlcykgew0KICB1MSA8LSByY2hpc3EoMSwgZGYxKQ0KICB1MiA8LSByY2hpc3EoMSwgZGYyKQ0KICBmLnN0YXRzW2ldIDwtICh1MS9kZjEpIC8gKHUyL2RmMikNCn0NCg0KIyBDb21wYXJlIHdpdGggdGhlb3JldGljYWwgRi1kaXN0cmlidXRpb24NCngudmFscyA8LSBzZXEoMCwgNSwgbGVuZ3RoLm91dCA9IDIwMCkNCnRoZW9yZXRpY2FsLmYgPC0gZGYoeC52YWxzLCBkZjEsIGRmMikNCnRoZW9yeS5kZiA8LSBkYXRhLmZyYW1lKHggPSB4LnZhbHMsIGRlbnNpdHkgPSB0aGVvcmV0aWNhbC5mKQ0KDQoNCg0KDQpmLnBsdCA8LSBnZ3Bsb3QoZGF0YS5mcmFtZSh4ID0gZi5zdGF0cyksIGFlcyh4ID0geCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIGJpbnMgPSA1MCwgYWxwaGEgPSAwLjcsIGZpbGwgPSAicHVycGxlMyIpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSB0aGVvcnkuZGYsIGFlcyh4ID0geCwgeSA9IGRlbnNpdHkpLCANCiAgICAgICAgICAgIGNvbG9yID0gInJlZCIsIGxpbmV3aWR0aCA9IDEpICsNCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIDUpKSArDQogIGxhYnModGl0bGUgPSBwYXN0ZSgiRi1EaXN0cmlidXRpb24gXG4gRigiLCBkZjEsICIsIiwgZGYyLCAiKSIsIHNlcCA9ICIiKSwNCiAgICAgICB4ID0gIlZhbHVlIiwgeSA9ICJEZW5zaXR5IikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDM1LCByID0gMjAsIGIgPSAzMCwgbCA9IDMwLCB1bml0ID0gInB0IikpDQpnZ3Bsb3RseShmLnBsdCkNCmBgYA0KDQoNCioqUmVtYXJrcyoqOiANCg0KMS4gRiBoYXMgdHdvIHBhcmFtZXRlcnMsIGRlZ3JlZXMgb2YgZnJlZWRvbSBvbiB0aGUgbnVtZXJhdG9yIGFuZCBkZW5vbWluYXRvciwgd2hhdCBhcmUgY29ycmVzcG9uZGluZyBzYW1wbGUgc2l6ZXMgbWludXMgMS4gVGhpcyBpcyBzaW1pbGFyIHRvIHRoYXQgb2YgdCBhbmQgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9ucy4NCg0KMi4gRnJvbSBwcmV2aW91cyBzZWN0aW9uLCB3ZSBzZWUgdGhhdCBib3RoIG51bWVyYXRvciBhbmQgZGVub21pbmF0b3IgY2FuIGJlIHJlLWV4cHJlc3NlZCBpbiB0ZXJtcyBvZiB0d28gaW5kZXBlbmRlbnQgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9ucy4gVG8gc2VlIHRoaXMsIGJvdGggbnVtZXJhdG9ycyBpbiB0aGUgZm9sbG93aW5nIGZvbGxvdyBjaGktc3F1YXJlZCBkaXN0cmlidXRpb24gd2l0aCBkZWdyZWVzIG9mIGZyZWVkb20gb2YgJG5fMS0xJCBhbmQgJG5fMi0xJCwgcmVzcGVjdGl2ZWx5LiANCg0KJCQNClxmcmFje1NfMV4yfXtcc2lnbWFfMV4yfSA9IFxmcmFjeyhuXzEtMSlTXzFeMi9cc2lnbWFfMV4yfXtuXzEtMX0gXHF1YWQgIFx0ZXh0eyBhbmQgfSBccXVhZCBcZnJhY3sobl8yLTEpU18yXjIvXHNpZ21hXzJeMn17bl8yLTF9DQokJA0KDQozLiAgIERlbm90ZSAkVV8xID0gKG5fMS0xKVNfMV4yL1xzaWdtYV8xXjIgXG92ZXJzZXR7ZH17XHNpbX0gXGNoaV4yX3tuXzEtMX0kIGFuZCAkVV8yID0gKG5fMi0xKVNfMl4yL1xzaWdtYV8yXjIgXG92ZXJzZXR7ZH17XHNpbX0gXGNoaV4yX3tuXzItMX0kLiBUaGVuLCB3ZSBjYW4gcmUtZXhwcmVzcyB0aGUgRi1yYXRpbyBhcw0KDQokJA0KRiA9IFxmcmFje1VfMS8obl8xLTEpfXtVXzIvKG5fMi0xKX0gXG92ZXJzZXR7ZH17XHRvfSBGX3tuXzEtMSwgbl8yLTF9Lg0KJCQNCg0KNC4gT25lIGNhbiBhbHNvIGRlcml2ZSB0aGUgKiphc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbioqIG9mICRTXzFeMi9TXzJeMiQgdXNpbmcgYSBsaW5lYXIgYXBwcm94aW1hdGlvbiBiYXNlZCBvbiBhIFRheWxvciBleHBhbnNpb24uIEhvd2V2ZXIsIHRoZSBhbmFseXRpYyBleHByZXNzaW9uIGlzIGNvbXBsZXggYW5kIGJleW9uZCB0aGUgc2NvcGUgb2YgdGhpcyBjbGFzcy4NCg0KDQoNCg0KIyBTdW1tYXJ5IG9mIEtleSBSZWxhdGlvbnNoaXBzDQoNCldlIGhhdmUgZGlzY3Vzc2VkIHNldmVyYWwgZXhhY3QgYW5kIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBmb3Igc2FtcGxlIG1lYW5zLCB2YXJpYW5jZXMsIGFuZCB0aGVpciBmdW5jdGlvbnMuIFRoZSBmb2xsb3dpbmcgdGFibGUgc3VtbWFyaXplcyB0aGVzZSBkaXN0cmlidXRpb25zLg0KDQoNCnxTdGF0aXN0aWMJfCBFeGFjdCBEaXN0cmlidXRpb24gfAlBc3ltcHRvdGljIERpc3RyaWJ1dGlvbiB8CUNvbmRpdGlvbnMgfA0KfDotLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS18DQp8ICRcYmFye1h9JAl8ICROKFxtdSwgXHNpZ21hXjIvbikkfCAJJE4oXG11LCBcc2lnbWFeMi9uKSR8IAlOb3JtYWwgcG9wdWxhdGlvbiBvciBsYXJnZSBufCANCnwgJFxmcmFje1xiYXJ7WH0tXG11fXtTL1xzcXJ0e259fSR8IAkkdF97bi0xfSQJfCAkTigwLDEpJHwgCU5vcm1hbCBwb3B1bGF0aW9ufCANCnwgJFxoYXR7cH0kCXwgJEJpbm9taWFsKG4scCkvbiQJfCAkTihwLCBwKDEtcCkvbikkfCAJJG5wLCBuKDEtcCkgXGdlcSA1JHwgDQp8ICRTXjIkICAgICB8IC0gfCAkTihcc2lnbWFeMiwgKFxtdV80LVxzaWdtYV40ICkvbikkIHwgbGFyZ2UgbiB8DQp8ICRcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9JAl8ICRcY2hpXjJfe24tMX0kIHwtCXwgTm9ybWFsIHBvcHVsYXRpb258IA0KfCAkXGZyYWN7U18xXjIvXHNpZ21hXzFeMn17U18yXjIvXHNpZ21hXzJeMn0kfCAkRl97bl8xLTEsbl8yLTF9JHwgCS0JfCBOb3JtYWwgcG9wdWxhdGlvbnN8IA0KDQoNCioqUGl2b3RhbCBRdWFudGl0eSoqDQoNCkEgcGl2b3RhbCBxdWFudGl0eSAob3IgcGl2b3QpIGlzIGEgZnVuY3Rpb24gb2YgdGhlIHNhbXBsZSBkYXRhIGFuZCBhbiAqKnVua25vd24gcGFyYW1ldGVyKiogd2hvc2UgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIGRvZXMgbm90IGRlcGVuZCBvbiB0aGUgKip1bmtub3duIHBhcmFtZXRlcioqLg0KDQpGb3IgZXhhbXBsZSwgaW4gbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aXRoIGtub3duIHZhcmlhbmNlLCB3ZSBoYXZlDQoNCiQkDQpYXzEsIFxkb3RzLCBYX24gXHNpbSBcdGV4dHtOfShcbXUsIFxzaWdtYV4yKSwgXHF1YWQgXHNpZ21hXjIgXHRleHR7IGtub3dufQ0KJCQNCg0KVGhlIHNhbXBsZSBtZWFuIGZvbGxvd3Mgbm9ybWFsIGRpc3RyaWJ1dGlvbjogJFxiYXJ7WH0gXHNpbSBcdGV4dHtOfVxsZWZ0KFxtdSwgXGZyYWN7XHNpZ21hXjJ9e259XHJpZ2h0KSQgDQoNCkFjY29yZGluZyB0byB0aGUgZGVmaW5pdGlvbiBvZiBwaXZvdGFsIHF1YW50aXR5LCANCg0KJCQNClogPSBcZnJhY3tcYmFye1h9IC0gXG11fXtcc2lnbWEgLyBcc3FydHtufX0gXHNpbSBcdGV4dHtOfSgwLDEpDQokJA0KDQppcyBwaXZvdCBzaW5jZSAkTigwLCAxKSQgaXMgaW5kZXBlbmRlbnQgb24gJFxtdSQuICBJZiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBoYXMgdW5rbm93biB2YXJpYW5jZSwgdGhlIHNhbXBsZSB2YXJpYW5jZQ0KDQokJA0KIFNeMiA9IFxmcmFjezF9e24tMX1cc3VtX3tpPTF9Xm4gKFhfaSAtIFxiYXJ7WH0pXjIuDQokJA0KDQpUaGUgZm9sbG93aW5nIHN0YW5kYXJkaXplZCBleHByZXNzaW9uDQoNCiQkDQpUID0gXGZyYWN7XGJhcntYfSAtIFxtdX17UyAvIFxzcXJ0e259fSBcc2ltIHRfe24tMX0NCiQkDQoNCmlzIGEgcGl2b3RhbCBxdWFudGl0eSBzaW5jZSB0aGUgdC1kaXN0cmlidXRpb24gZG9lcyBub3QgZGVwZW5kIG9uICRcbXUkLiANCg0KU2ltaWxhcmx5LCAkKG4tMSlTXjIvXHNpZ21hXjIkIGFuZCAkXGZyYWN7U18xXjIvXHNpZ21hXzFeMn17U18yXjIvXHNpZ21hXzJeMn0kIGluIHRoZSBhYm92ZSBzdW1tYXJ5IHRhYmxlIGFyZSBwaXZvdGFsIHF1YW50aXRpZXMuDQoNCg0KDQoqKkNvbmNsdXNpb24qKg0KDQoqIFVuZGVyc3RhbmRpbmcgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBpcyBmdW5kYW1lbnRhbCB0byBzdGF0aXN0aWNhbCBpbmZlcmVuY2U6DQoNCiogRXhhY3QgZGlzdHJpYnV0aW9ucyBwcm92aWRlIHByZWNpc2UgcmVzdWx0cyB3aGVuIGFzc3VtcHRpb25zIGFyZSBtZXQNCg0KKiBBc3ltcHRvdGljIGRpc3RyaWJ1dGlvbnMgb2ZmZXIgYXBwcm94aW1hdGlvbnMgZm9yIGxhcmdlIHNhbXBsZXMNCg0KKiBUaGUgY2hvaWNlIGJldHdlZW4gZXhhY3QgYW5kIGFzeW1wdG90aWMgbWV0aG9kcyBkZXBlbmRzIG9uIHNhbXBsZSBzaXplLCBkaXN0cmlidXRpb25hbCBhc3N1bXB0aW9ucywgYW5kIHRoZSBzcGVjaWZpYyBwYXJhbWV0ZXIgYmVpbmcgZXN0aW1hdGVkDQoNCiogTW9kZXJuIGNvbXB1dGluZyBhbGxvd3MgZm9yIGVtcGlyaWNhbCB2ZXJpZmljYXRpb24gb2YgdGhlc2UgdGhlb3JldGljYWwgcmVzdWx0cw0KDQoNClRoZXNlIGRpc3RyaWJ1dGlvbnMgZm9ybSB0aGUgdGhlb3JldGljYWwgZm91bmRhdGlvbiBmb3IgaHlwb3RoZXNpcyB0ZXN0aW5nLCBjb25maWRlbmNlIGludGVydmFscywgYW5kIG1hbnkgb3RoZXIgc3RhdGlzdGljYWwgcHJvY2VkdXJlcy4NCg0KDQoNCg0KDQo=