Asymptotic Sampling Distrubutions
We use sampling distributions when we want to make
statistical inferences about the population. Often running statistics on
the true population is extremely expensive, or impossible. Often the
true population is unknown, so running statistics on the true population
soley, is impractical. To compensate, often we take a random sample from
our population of interest to make a statistical inference to the
population. We assume our sample can provide us with information about
the population.
An Asymptotic Sampling Distribution is an example of
a type of sampling distribution we use to make statistical inferences
about the population. When we use an asymptotic sampling distribution we
assume a large sample size with an independently and identically
distributed sample. We can use an underlining non-parametric or unknown
population shape and standardize the normal distribution to approximate
the distribution and parameters of interest for the samples
collected.
We model raw collected datasets or samples with a Empirical
Cumulative Distribution Function (ECDF). This is a distribution
directly from observed sample data, with no inherently assumed shape
about the sample or population distribution.
The asymptotic distribution converges to a normal distribution as the
sample size increases, although we standardize each observation in the
distribution to approximate a normal distribution to make inferences
about the distribution using our normal distribution as a guide to do so
using the following formulas:
When our standard deviation is known for the population, we
standardize a Asymptotic Distribution using the formula $$
Z= _{} N(0, 1)
$$
When our standard deviation is not known for the population, we
assume the standard deviation is approximately normally distributed
(with a large sample size), we standardize a Asymptotic Distribution
using the formula which happens to be a T-distrubution:
\[
T = \frac{\bar{X}-\mu}{S/\sqrt{n}} \overset{d}{\to} t_{n-1}
\] We estimate the sample variance to apply to the T distribution
which the \(\sqrt(S^2)\) can be placed
in the T distribution formula.
\[
S^2 \stackrel{d}{\to} N\left(\sigma^2, \frac{\mu_4 - \sigma^4}{n}\right)
\quad \text{as } n \to \infty,
\] When our distribution is subset with a proportion (Bernoulli
Random Variable), we a Asymptotic Distribution standardize using the
formula \[
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
\]
The Asymptotic Distribution is very valuable for approximating sample
statistics for example, the sample statistic, mean can be approximated
using the following formula where \(\mu_4 =
E[(X_i - \mu)^4]\) is tje 4th central moment which can be
estimated as:
$$ 4 = {i=1}n(x_i-{x})4.
$$ While our asymptotic distribution can make approximations on
sample statistics, when distributions become more complex, for example
paired observations, unbounded populations, and unknowns about the true
population, direct computation of the asymptotic distributions can
become incredibly complex and non-time efficient. Instead of direct
computations and approximations for the distribution we can run
simulations within the datasets we have to simulate and summary the
statistics after repeated resamples to estimate a sample statistic (for
example mean or variance) through the behavior seen through repeated
measurements instead through direct computation. One way we demonstrate
this simulated resampling is through Bootstrap Sampling
Distributions.
Bootstrap Sampling Distrubutions
A bootstrap sampling distribution is a simulated approach into
analyzing sample statistics (ig. mean, variance, etc.). Instead of
organizing a distribution directly to derive one mean or other sample
statistic, we repeatably sample (with replacement) from the originally
collected sample to derived a variety of the sample statistic of
interest values to compile and compute into a even more robust value for
the sample statistic of interest.
We select a random sample from the true population. We use the
collected random sample as a representative population to draw samples
from. With this originally captured sample we take
We choose to randomly select random samples from the original random
sample to compute a bootstrap samples statistic. We will ultimately use
all the simulated bootstrap statistics to compute the statistic of
interest onto the simulated bootstrap statistics.
Below is the simulation of a bootstrap statistic from an original
dataset, to find a bootstrap distribution we can calculate a statistic
from
#creating a simulated bootstrap
url = "https://pengdsci.github.io/STA506/w04/w02-wcuheights.txt"
height = read.table(url, header = TRUE) #the Population of the heights at west chester university
original.sample = sample(height$Height, 81, replace = FALSE) #Take a random sample of the original population to act as the population proxy for our bootstrap
#our sample size is 81
# we do not need to replace our samples from the true population. We would like consistent values to repeatedly sample from for our bootstrap sampling
bt.sample.mean = NULL #create an empty vector to hold our sample into when we compute the bootstrap mean during our for loop
for(i in 1:1000)
{
ith.bt.sample = x=sample(x=original.sample, size = 81, replace= TRUE) #take repeated samples from our original sample aka the sample acting as a proxy for our original population
#our sample size is 81, the same size of the original population
#we want to take values from this sample repeated so we do replace our samples
bt.sample.mean[i] = mean(ith.bt.sample)
}
hist(bt.sample.mean,
breaks = 12,
probability = TRUE,
xlab = "Bootstrap sample means", #x axis lable
main="Bootstrap Sampling Distribution \n of Sample Means Example",
cex.main = 0.9,
col.main = "darkgreen")
lines(density(bt.sample.mean), col = "skyblue", lwd = 2)

The Bootstrap Sampling Distribution has value because it allows us to
make inferences about a population based on a large independent
identically distrubtued random sample in which we are unsure about the
true population and most likely have complexity in the organization of
our distribution. We may find value in using a bootstrap when
When we do not have complex attributes in our distribution a
Asymptotic Distribution may be better fitted. A simulation may cause
higher likelihood f type I error, due to the need to run more simulation
tests
Assess the performance of Bootstrap sampling distributions against
exact and asymptotic sampling distributions.
An exact distribution has similar qualities to an asymptotic
distribution, although an exact distribution is specific to a small
sample size, with a normally distributed sample that is an identically
and interdependent samples distribution. In comparison to both exact and
asymptotic distributions, a boot strap sampling distribution is valuable
because we can simulate a distribution to reach a statistic for a
distributions that would otherwise be too complex to model through
parametric approximation. Although an exact test is small and a
parametric test, at times an exact test may be more applicable if there
are no complex distributions, a small sample size that does not meet the
large sample size assumption of the Bootstrap Assumptions and there also
be little need to approximate the distribution as the distribution
already known. A Bootstrap sampling distribution may be more appropriate
for complex asymptotic distributions with large sample sizes.
Question 2: Daily Coffee Sales (in mL) at Two Different Cafe
Locations
This data set represents the volume of regular brewed coffee sold per
day (in milliliters) at two different cafe locations over a period of 50
days.
2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200,
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400,
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600,
8400, 3300, 4200, 4500, 4800, 4300, 8500
We are interested in finding the sampling distribution of sample
means that will be used for various inferences about the underlying
population mean.
- Based on the given data, can the Central Limit Theorem be used to
derive the asymptotic sampling distribution of the sample mean? Justify
your answer.
The asymptotic sampling distribution allows a non-parametric
approximation that uses the assumption that the larger the sample size
the, greater the likelihood the sample mean will be normally distrusted.
The Central Limit Theorem is a tool the asymptotic sampling distribution
uses a as an approximation for the sampling distribution. In many cases
both an asymptotic sampling distribution or bootstrap distribution can
be used, although which is most accessible depends on the complexity of
the distribution and parameter of interest. As this sampling
distribution, does not look complex in regards to paired observation for
example, the central limit theorem can be used because the sample we are
assuming is our population is not normally distributed; the asymptotic
sampling distribution does not assume shape of population, unlike the
exact normal distribution.
This is the use of the central limit theory for the asymptotic
distribution
coffees = c(2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 8400, 3300, 4200, 4500, 4800, 4300, 8500)
s.coffee=sort(coffees) #sorting the dataset in increasing ordering
hist(s.coffee, main = "Histogram of Coffee Volume" )#bimodal distribution

#Building Z distribution to Approximate for Asymptotic sampling
n_coffee=length(s.coffee) #sample size is 55
sd_coffee = sd(s.coffee) #standard deviation of sorted coffee
var_coffee = var(s.coffee) #calculating sample variance of coffee
se_coffee <- sd_coffee / sqrt(n_coffee) #standard error of coffee
mean.coffee=mean(s.coffee) #coffee mean is 5250
ecdf(s.coffee)
Empirical CDF
Call: ecdf(s.coffee)
x[1:32] = 2850, 2900, 2950, ..., 8800, 8900
freq_coff=table(coffees)
my.ECDF <- function(indat, outx){
# outx - a vector of given values
freq.table <- table(indat) # frequency table
uniq <- as.numeric(names(freq.table)) # unique data values
rep.time <- as.vector(freq.table) # frequencies of the unique data values
cum.rel.feq <- cumsum(rep.time)/sum(rep.time) # cumulative relative frequencies: CDF
cum.prob <- NULL
for (i in 1:length(outx)){
intvl.id <- which(uniq <= outx[i]) # identify the index meeting the condition
cum.prob[i] <- cum.rel.feq[max(intvl.id)] # extract the cumulative prob according to CDF
}
cum.prob
}
plot(s.coffee, my.ECDF(indat = coffees, outx = s.coffee), type = "s",
main = "ECDF of Coffee Volume",
xlab = "Coffee Volume",
ylab = "Cumulative Probability")

In the histogram of coffee volume the distribution is not normally
distributed but, bimodal, meaning having two peaks. There is most likely
a separation in our dataset that causes the volumes to sit in two
different ‘subsets’.
Our coffee volume sample mean using the CLT approximation
distribution is 5250 mL.
- Apply the bootstrap method to estimate the sampling distribution
(often called the bootstrap sampling distribution) of the sample mean.
Generate a kernel density estimate from the bootstrap sample means and
plot it. Then, use this bootstrap distribution to validate your
conclusion from part (a). Make sure your visuals are effective in
enhancing the presentation of these results.
#Apply the bootstrap method to the sample mean
#Generate a kernel density estimate from the bootstrap and sample plot
#call the sample from the population
set.seed(142)
s.coffee
[1] 2850 2900 2950 3000 3050 3050 3100 3100 3100 3100 3150 3200 3250 3250 3250
[16] 3300 3300 3350 3400 4000 4100 4100 4200 4200 4200 4300 4300 4400 4400 4500
[31] 4500 4500 4600 4600 4700 4800 4800 7700 7800 7900 8100 8100 8200 8200 8200
[46] 8300 8300 8400 8400 8500 8500 8700 8800 8900 8900
#create an empty vector to calculate the bootstrap distribution mean in the for loop
s.coffee.vec.mean = NULL
#sample from the population
for(i in 1:1000)
{
ith.coffee.sample=sample(s.coffee, 55, replace= TRUE) #randomly select from original sample
#Our sample size is 55
#replace our sample each loop because we do not have a large sample
s.coffee.vec.mean[i] = mean(ith.coffee.sample) #calculated mean: 5207.273
}
kde = density(s.coffee.vec.mean, bw = sd_coffee)
#generate a kernel density estimate from the bootstrap from the sample means and plot it
hist(s.coffee.vec.mean, #datapoint aka statistic we just generated, we want to see its simulated distrubution
probability = TRUE, #identify the relative frequency (always say true)
breaks = 14,
xlab = "sample means of repeated samples", #label the x axis
main= "Approximated Sampling Distrubution \n of Sample Means - Bootstrap Resampling",
cex.main = 0.9,
col.main = "darkgreen"
)
lines(density(s.coffee.vec.mean, kernel = "gaussian"), col= "skyblue", lwd=2) #what the bootstrap distribution looks like

# KDE based on built-in function density(): bandwidth = 0.4
########### plot what the bootstrap distribution looks like what kernel ####
The simulated bootstrap resampling mean for the coffee volume is
5207.273 mL.
We see our bootstrap distribution gave is a approximately normal
distribution of the means, our parameter statistic of interest.
Our calculated mean of coffee volume using the bootstrap distribution
is 5217.273 mL.
boot_df <- data.frame(boot_means = s.coffee.vec.mean) #Create a comparison dataframe to compare the CLT Asymptotic Distribution and the Bootstrap Disrtubution
mean.coffee <- mean(s.coffee) # Center (5250) #Call the CLT asymptotic parameters for comparison
se_coffee <- sd(s.coffee) / sqrt(length(s.coffee))
ggplot(boot_df, aes(x = boot_means)) + #create plot using coffee mean aka boots_mean
#creating a histogram based on the bootstrap distribution
geom_histogram(aes(y = after_stat(density)), bins = 30,
fill = "darkgray", alpha = 0.4, color = "black") +
# B: The KDE (Gaussian Kernel - Smoothing the Bootstrap results)
# R defaults to a Gaussian kernel here
geom_density(color = "blue", linewidth = 1.2) + #add a layer for a Gaussian line with a
# C: The CLT Normal Curve (Validation from Part A)
#based on the mean of coffee and standard error for a Asymptotic distribution
stat_function(fun = dnorm, args = list(mean = mean.coffee, sd = se_coffee),
color = "red", linetype = "dashed", linewidth = 1) +
# Labels and Theme
labs(title = "Approximated Sampling Distribution of Sample Means",
subtitle = "Gray: Bootstrap Hist | Blue: Gaussian KDE | Red: CLT Normal",
x = "Sample Mean Volume (mL)",
y = "Density") +
theme_minimal()

As mentioned prior, both the bootstrap and the CLT Asymptotic
Sampling Distribution can be used on this non-complex distribution type,
thus the distributions for taken both for the bootstrap and asymptotic
present similar results. A
- Repeat the analysis in parts (a) and (b) for the sample
variance.
options(scipen = 0)
#Part a for Variance
var_coffee = var(s.coffee) #calculating sample variance of coffee = 5030833
##Part B for Variance
#call the sample from the population
set.seed(142)
s.coffee
[1] 2850 2900 2950 3000 3050 3050 3100 3100 3100 3100 3150 3200 3250 3250 3250
[16] 3300 3300 3350 3400 4000 4100 4100 4200 4200 4200 4300 4300 4400 4400 4500
[31] 4500 4500 4600 4600 4700 4800 4800 7700 7800 7900 8100 8100 8200 8200 8200
[46] 8300 8300 8400 8400 8500 8500 8700 8800 8900 8900
#create an empty vector to calculate the bootstrap distribution mean in the for loop
s.coffee.vec.var = NULL
#sample from the population
for(i in 1:1000)
{
ith.coffee.sample.v=sample(s.coffee, 55, replace= TRUE) #randomly select from original sample
#Our sample size is 55
#replace our sample each loop because we do not have a large sample
s.coffee.vec.var[i] = var(ith.coffee.sample.v) #calculated variance: 4844761
}
kdeV = density(s.coffee.vec.var)
#generate a kernel density estimate from the bootstrap from the sample means and plot it
hist(s.coffee.vec.var, #datapoint aka statistic we just generated, we want to see its simulated distrubution
probability = TRUE, #identify the relative frequency (always say true)
breaks = 14,
xlab = "sample varience of repeated samples", #label the x axis
main= "Approximated Sampling Distrubution \n of Sample Varience - Bootstrap Resampling",
cex.main = 0.9,
col.main = "darkgreen"
)
lines(density(s.coffee.vec.var, kernel = "gaussian"), col= "skyblue", lwd=2) #what the bootstrap distribution looks like

The asymptotic sampling distribution is a distribution better
represented for non-complex values. As the variance is a squared
parameter that adds complexity a asymptotic sampling distribution is not
a strong distribution type for identifying a variance parameter. A
bootstrap resampling distribution is a better suited distribution type
for identifying a variance’s added complexity.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMzogRUNERiBhbmQgQm9vdHN0cmFwIFNhbXBsaW5nIGFuZCBBcHBsaWNhdGlvbnMiDQphdXRob3I6ICJFemFuYSBSaXZlcnMgIg0KZGF0ZTogIiAyLTE3LTIwMjYiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KI1RPQzo6YmVmb3JlIHsNCiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc2l6ZTogMS4yZW07DQogIGRpc3BsYXk6IGJsb2NrOw0KICBjb2xvcjogbmF2eTsNCiAgbWFyZ2luLWJvdHRvbTogMTBweDsNCn0NCg0KDQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovDQogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQoNCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovDQogIGZvbnQtc2l6ZTogMjJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxNXB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0NCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQoNCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgbGlicmFyeShwbG90bHkpDQp9DQojIyMjDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgICMgaW5jbHVkZSBjb2RlIGNodW5rIGluIHRoZSBvdXRwdXQgZmlsZQ0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICAjIHNvbWV0aW1lcywgeW91IGNvZGUgbWF5IHByb2R1Y2Ugd2FybmluZyBtZXNzYWdlcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3UgY2FuIGNob29zZSB0byBpbmNsdWRlIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGluDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG91dHB1dCBmaWxlLiANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAgIyB5b3UgY2FuIGFsc28gZGVjaWRlIHdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgb3V0cHV0DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW4gdGhlIG91dHB1dCBmaWxlLg0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkENCiAgICAgICAgICAgICAgICAgICAgICApICANCmBgYA0KIA0KIFwNCiANCiMjICoqQXNzaWdubWVudCBPYmplY3RpdmVzKiogDQoNCiogVW5kZXJzdGFuZCB0aGUgdGhlb3JldGljYWwgYmFzaXMgb2YgQm9vdHN0cmFwIHNhbXBsaW5nIG1ldGhvZHMgZm9yIGFwcHJveGltYXRpbmcgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucy4NCg0KKiBBc3Nlc3MgdGhlIHBlcmZvcm1hbmNlIG9mIEJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb25zIGFnYWluc3QgZXhhY3QgYW5kIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucy4NCg0KKiBJbXBsZW1lbnQgQm9vdHN0cmFwIHNhbXBsaW5nIGFsZ29yaXRobSBhbmQgY29uc3RydWN0IHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgdXNpbmcgUi4NCg0KXA0KDQoqKlVzZSBvZiBBSSBUb29scyoqDQoNCioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFN0dWRlbnRzIG11c3QgYWRoZXJlIHRvIHRoZSBBSSB0b29sIHBvbGljeSBzcGVjaWZpZWQgaW4gdGhlIGNvdXJzZSBzeWxsYWJ1cy4gVGhlIGRpcmVjdCBjb3B5aW5nIG9mIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0IHJlZmxlY3QgeW91ciBvd24gdW5kZXJzdGFuZGluZzsgd2hlcmUgZXh0ZXJuYWwgdG9vbHMgYXJlIGNvbnN1bHRlZCwgY29udGVudCBtdXN0IGJlIHRob3JvdWdobHkgcmVwaHJhc2VkIGFuZCBzeW50aGVzaXplZCBpbiB5b3VyIG93biB3b3Jkcy4NCg0KKipDb2RlIEluY2x1c2lvbiBSZXF1aXJlbWVudCoqOiBBbnkgY29kZSBpbmNsdWRlZCBpbiB5b3VyIGVzc2F5IG11c3QgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dCBvZiBrZXkgY29kZSBsaW5lcy4gU3VibWl0dGluZyBBSS1nZW5lcmF0ZWQgY29kZSB3aXRob3V0IG1lYW5pbmdmdWwsIHN0dWRlbnQtYWRkZWQgY29tbWVudHMgd2lsbCBub3QgYmUgYWNjZXB0ZWQuDQoNClwNCg0KKipBc3ltcHRvdGljIERpc3RyaWJ1dGlvbiBvZiBTYW1wbGUgVmFyaWFuY2UqKg0KDQpBc3N1bWUgdGhhdCAkXHsgeF8xLCB4XzIsIFxjZG90cywgeF9uIFx9IFx0byBGKHgpJCB3aXRoICRcbXUgPSBFW1hdJCBhbmQgJFxzaWdtYV4yID0gXHRleHR7dmFyfShYKSQuIERlbm90ZSANCg0KJCQNCnNeMiA9IFxmcmFjezF9e24tMX1cc3VtX3tpPTF9Xm4gKHhfaSAtIFxtdSleMg0KJCQNCg0KSWYgJG4kIGlzIGxhcmdlLCANCg0KJCQNCnNeMiBcdG8gTlxsZWZ0KFxzaWdtYV4yLCAgXGZyYWN7XG11XzQtXHNpZ21hXjR9e259IFxyaWdodCkNCiQkDQoNCndoZXJlICRcbXVfNCA9IEVbKFhfaSAtIFxtdSleNF0kIGlzIHRqZSA0dGggY2VudHJhbCBtb21lbnQgd2hpY2ggY2FuIGJlIGVzdGltYXRlZCBieQ0KDQokJA0KXGhhdHtcbXV9XzQgPSBcZnJhY3sxfXtufVxzdW1fe2k9MX1ebih4X2ktXGJhcnt4fSleNC4NCiQkDQoNCioqTm90ZSoqOiBUaGlzIGRlc2NyaWJlcyB0aGUgYXN5bXB0b3RpYyBjb252ZXJnZW5jZSBvZiB0aGUgc2FtcGxlIHZhcmlhbmNlLCBmb2xsb3dpbmcgZnJvbSB0aGUgY2VudHJhbCBsaW1pdCB0aGVvcmVtIChDTFQpLiBUaGUgc2FtcGxlIHNpemUgcmVxdWlyZWQgZm9yIHRoaXMgYXBwcm94aW1hdGlvbiB0byBob2xkIGlzIHNpdHVhdGlvbi1kZXBlbmRlbnQuDQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uIDE6IEFzeW1wdG90aWMgdnMgQm9vdHN0cmFwIFNhbXBsaW5nIERpc3RyaWJ1dGlvbnMqKg0KDQpXcml0ZSBhbiBlc3NheSBzdW1tYXJpemluZyB0aGUgY29uY2VwdHMgb2YgQXN5bXB0b3RpYyBhbmQgQm9vdHN0cmFwIFNhbXBsaW5nIERpc3RyaWJ1dGlvbnMsIGFsb25nIHdpdGggdGhlaXIga2V5IGFwcGxpY2F0aW9ucy4gWW91ciBkaXNjdXNzaW9uIHNob3VsZCBiZSBncm91bmRlZCBpbiB5b3VyIHBlcnNvbmFsIHVuZGVyc3RhbmRpbmcgb2YgdGhlIG1hdGVyaWFsLiBBbnkgZXh0ZXJuYWwgc291cmNlcyBpbmNsdWRpbmcgQUkgdG9vbHMgY29uc3VsdGVkIG11c3QgYmUgY2xlYXJseSBjaXRlZC4gDQoNCg0KKipFc3NheSBQcm9tcHQqKjogRGlzY3VzcyB0aGUgY29uY2VwdHMgb2YgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBwbGFuLCB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgYW5kIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBpbiB0aGUgY29udGV4dCBvZiBzdGF0aXN0aWNzIChlLmcuLCBzYW1wbGUgbWVhbiBhbmQgdmFyaWFuY2UpIGNvbXB1dGVkIGZyb20gYW4gaW5kZXBlbmRlbnQgYW5kIGlkZW50aWNhbGx5IGRpc3RyaWJ1dGVkIChpLmkuZC4pIHNhbXBsZS4gWW91ciBkaXNjdXNzaW9uIHNob3VsZDoNCg0KKiBDbGVhcmx5IG91dGxpbmUgdGhlIGtleSBhc3N1bXB0aW9ucyByZXF1aXJlZCBmb3IgZWFjaCBtZXRob2QuDQoNCiogRXhwbGFpbiB0aGUgcHJhY3RpY2FsIGFwcGxpY2F0aW9uIG9mIGVhY2ggZGlzdHJpYnV0aW9uLg0KDQoqIFByb3ZpZGUgZ3VpZGFuY2Ugb24gd2hlbiBhbmQgd2h5IG9uZSBzaG91bGQgYmUgcHJlZmVycmVkIG92ZXIgdGhlIG90aGVyIGluIHN0YXRpc3RpY2FsIGluZmVyZW5jZS4NCg0KDQoNClwNCg0KIyMgQXN5bXB0b3RpYyBTYW1wbGluZyBEaXN0cnVidXRpb25zDQoNCg0KV2UgdXNlICoqc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyoqIHdoZW4gd2Ugd2FudCB0byBtYWtlIHN0YXRpc3RpY2FsIGluZmVyZW5jZXMgYWJvdXQgdGhlIHBvcHVsYXRpb24uIE9mdGVuIHJ1bm5pbmcgc3RhdGlzdGljcyBvbiB0aGUgdHJ1ZSBwb3B1bGF0aW9uIGlzIGV4dHJlbWVseSBleHBlbnNpdmUsIG9yIGltcG9zc2libGUuIE9mdGVuIHRoZSB0cnVlIHBvcHVsYXRpb24gaXMgdW5rbm93biwgc28gcnVubmluZyBzdGF0aXN0aWNzIG9uIHRoZSB0cnVlIHBvcHVsYXRpb24gc29sZXksIGlzIGltcHJhY3RpY2FsLiBUbyBjb21wZW5zYXRlLCBvZnRlbiB3ZSB0YWtlIGEgcmFuZG9tIHNhbXBsZSBmcm9tIG91ciBwb3B1bGF0aW9uIG9mIGludGVyZXN0IHRvIG1ha2UgYSBzdGF0aXN0aWNhbCBpbmZlcmVuY2UgdG8gdGhlIHBvcHVsYXRpb24uIFdlIGFzc3VtZSBvdXIgc2FtcGxlIGNhbiBwcm92aWRlIHVzIHdpdGggaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBvcHVsYXRpb24uDQoNCkFuICoqQXN5bXB0b3RpYyBTYW1wbGluZyBEaXN0cmlidXRpb24qKiBpcyBhbiBleGFtcGxlIG9mIGEgdHlwZSBvZiBzYW1wbGluZyBkaXN0cmlidXRpb24gd2UgdXNlIHRvIG1ha2Ugc3RhdGlzdGljYWwgaW5mZXJlbmNlcyBhYm91dCB0aGUgcG9wdWxhdGlvbi4gV2hlbiB3ZSB1c2UgYW4gYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gd2UgYXNzdW1lIGEgbGFyZ2Ugc2FtcGxlIHNpemUgd2l0aCBhbiBpbmRlcGVuZGVudGx5IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZCBzYW1wbGUuIFdlIGNhbiB1c2UgYW4gdW5kZXJsaW5pbmcgbm9uLXBhcmFtZXRyaWMgb3IgdW5rbm93biBwb3B1bGF0aW9uIHNoYXBlIGFuZCBzdGFuZGFyZGl6ZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiB0byBhcHByb3hpbWF0ZSB0aGUgZGlzdHJpYnV0aW9uIGFuZCBwYXJhbWV0ZXJzIG9mIGludGVyZXN0IGZvciB0aGUgc2FtcGxlcyBjb2xsZWN0ZWQuIA0KDQpXZSBtb2RlbCByYXcgY29sbGVjdGVkIGRhdGFzZXRzIG9yIHNhbXBsZXMgd2l0aCBhICoqRW1waXJpY2FsIEN1bXVsYXRpdmUgRGlzdHJpYnV0aW9uIEZ1bmN0aW9uIChFQ0RGKSoqLiBUaGlzIGlzIGEgZGlzdHJpYnV0aW9uIGRpcmVjdGx5IGZyb20gb2JzZXJ2ZWQgc2FtcGxlIGRhdGEsIHdpdGggbm8gaW5oZXJlbnRseSBhc3N1bWVkIHNoYXBlIGFib3V0IHRoZSBzYW1wbGUgb3IgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24uICANCg0KVGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIGNvbnZlcmdlcyB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgdGhlIHNhbXBsZSBzaXplIGluY3JlYXNlcywgYWx0aG91Z2ggd2Ugc3RhbmRhcmRpemUgZWFjaCBvYnNlcnZhdGlvbiBpbiB0aGUgZGlzdHJpYnV0aW9uIHRvIGFwcHJveGltYXRlIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiB0byBtYWtlIGluZmVyZW5jZXMgYWJvdXQgdGhlIGRpc3RyaWJ1dGlvbiB1c2luZyBvdXIgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhcyBhIGd1aWRlIHRvIGRvIHNvIHVzaW5nIHRoZSBmb2xsb3dpbmcgZm9ybXVsYXM6DQoNCg0KV2hlbiBvdXIgc3RhbmRhcmQgZGV2aWF0aW9uIGlzIGtub3duIGZvciB0aGUgcG9wdWxhdGlvbiwgd2Ugc3RhbmRhcmRpemUgYSBBc3ltcHRvdGljIERpc3RyaWJ1dGlvbiAgdXNpbmcgdGhlIGZvcm11bGENCiQkDQoNClo9IFxmcmFje1xiYXJ7WH0tXG11fXtcc2lnbWEvXHNxcnR7bn19IFx0b197XHRleHR7YXBwcm94fX0gTigwLCAxKQ0KDQoNCiQkDQoNCg0KV2hlbiBvdXIgc3RhbmRhcmQgZGV2aWF0aW9uIGlzIG5vdCBrbm93biBmb3IgdGhlIHBvcHVsYXRpb24sIHdlIGFzc3VtZSB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgKHdpdGggYSBsYXJnZSBzYW1wbGUgc2l6ZSksIHdlIHN0YW5kYXJkaXplIGEgQXN5bXB0b3RpYyBEaXN0cmlidXRpb24gdXNpbmcgdGhlIGZvcm11bGEgd2hpY2ggaGFwcGVucyB0byBiZSBhIFQtZGlzdHJ1YnV0aW9uOiANCg0KJCQNClQgPSBcZnJhY3tcYmFye1h9LVxtdX17Uy9cc3FydHtufX0gXG92ZXJzZXR7ZH17XHRvfSAgdF97bi0xfQ0KJCQNCldlIGVzdGltYXRlIHRoZSBzYW1wbGUgdmFyaWFuY2UgdG8gYXBwbHkgdG8gdGhlIFQgZGlzdHJpYnV0aW9uIHdoaWNoIHRoZSAkXHNxcnQoU14yKSQgY2FuIGJlIHBsYWNlZCBpbiB0aGUgVCBkaXN0cmlidXRpb24gZm9ybXVsYS4gDQoNCiQkDQpTXjIgXHN0YWNrcmVse2R9e1x0b30gTlxsZWZ0KFxzaWdtYV4yLCBcZnJhY3tcbXVfNCAtIFxzaWdtYV40fXtufVxyaWdodCkgXHF1YWQgXHRleHR7YXMgfSBuIFx0byBcaW5mdHksDQokJA0KV2hlbiBvdXIgZGlzdHJpYnV0aW9uIGlzIHN1YnNldCB3aXRoIGEgcHJvcG9ydGlvbiAoQmVybm91bGxpIFJhbmRvbSBWYXJpYWJsZSksIHdlIGEgQXN5bXB0b3RpYyBEaXN0cmlidXRpb24gc3RhbmRhcmRpemUgdXNpbmcgdGhlIGZvcm11bGENCiQkDQpaX24gPSBcZnJhY3tcaGF0e3B9X24gLSBwfXtcc3FydHtcZnJhY3twKDEtcCl9e259fX0gXHN0YWNrcmVse2R9e1x0b30gTigwLDEpIFxxdWFkIFx0ZXh0e2FzIH0gbiBcdG8gXGluZnR5DQokJA0KDQpUaGUgQXN5bXB0b3RpYyBEaXN0cmlidXRpb24gaXMgdmVyeSB2YWx1YWJsZSBmb3IgYXBwcm94aW1hdGluZyBzYW1wbGUgc3RhdGlzdGljcyBmb3IgZXhhbXBsZSwgdGhlIHNhbXBsZSBzdGF0aXN0aWMsIG1lYW4gY2FuIGJlIGFwcHJveGltYXRlZCB1c2luZyB0aGUgZm9sbG93aW5nIGZvcm11bGEgd2hlcmUgJFxtdV80ID0gRVsoWF9pIC0gXG11KV40XSQgaXMgdGplIDR0aCBjZW50cmFsIG1vbWVudCB3aGljaCBjYW4gYmUgZXN0aW1hdGVkIGFzOg0KDQokJA0KXGhhdHtcbXV9XzQgPSBcZnJhY3sxfXtufVxzdW1fe2k9MX1ebih4X2ktXGJhcnt4fSleNC4NCg0KJCQNCldoaWxlIG91ciBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbiBjYW4gbWFrZSBhcHByb3hpbWF0aW9ucyBvbiBzYW1wbGUgc3RhdGlzdGljcywgd2hlbiBkaXN0cmlidXRpb25zIGJlY29tZSBtb3JlIGNvbXBsZXgsIGZvciBleGFtcGxlIHBhaXJlZCBvYnNlcnZhdGlvbnMsIHVuYm91bmRlZCBwb3B1bGF0aW9ucywgYW5kIHVua25vd25zIGFib3V0IHRoZSB0cnVlIHBvcHVsYXRpb24sIGRpcmVjdCBjb21wdXRhdGlvbiBvZiB0aGUgYXN5bXB0b3RpYyBkaXN0cmlidXRpb25zIGNhbiBiZWNvbWUgaW5jcmVkaWJseSBjb21wbGV4IGFuZCBub24tdGltZSBlZmZpY2llbnQuIEluc3RlYWQgb2YgZGlyZWN0IGNvbXB1dGF0aW9ucyBhbmQgYXBwcm94aW1hdGlvbnMgZm9yIHRoZSBkaXN0cmlidXRpb24gd2UgY2FuIHJ1biBzaW11bGF0aW9ucyB3aXRoaW4gdGhlIGRhdGFzZXRzIHdlIGhhdmUgdG8gc2ltdWxhdGUgYW5kIHN1bW1hcnkgdGhlIHN0YXRpc3RpY3MgYWZ0ZXIgcmVwZWF0ZWQgcmVzYW1wbGVzIHRvIGVzdGltYXRlIGEgc2FtcGxlIHN0YXRpc3RpYyAoZm9yIGV4YW1wbGUgbWVhbiBvciB2YXJpYW5jZSkgdGhyb3VnaCB0aGUgYmVoYXZpb3Igc2VlbiB0aHJvdWdoIHJlcGVhdGVkIG1lYXN1cmVtZW50cyBpbnN0ZWFkIHRocm91Z2ggZGlyZWN0IGNvbXB1dGF0aW9uLiBPbmUgd2F5IHdlIGRlbW9uc3RyYXRlIHRoaXMgc2ltdWxhdGVkIHJlc2FtcGxpbmcgaXMgdGhyb3VnaCAqKkJvb3RzdHJhcCBTYW1wbGluZyBEaXN0cmlidXRpb25zKiouIA0KDQoNCg0KIyMgQm9vdHN0cmFwIFNhbXBsaW5nIERpc3RydWJ1dGlvbnMgDQpBIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgYSBzaW11bGF0ZWQgYXBwcm9hY2ggaW50byBhbmFseXppbmcgc2FtcGxlIHN0YXRpc3RpY3MgKGlnLiBtZWFuLCB2YXJpYW5jZSwgZXRjLikuIEluc3RlYWQgb2Ygb3JnYW5pemluZyBhIGRpc3RyaWJ1dGlvbiBkaXJlY3RseSB0byBkZXJpdmUgb25lIG1lYW4gb3Igb3RoZXIgc2FtcGxlIHN0YXRpc3RpYywgd2UgcmVwZWF0YWJseSBzYW1wbGUgKHdpdGggcmVwbGFjZW1lbnQpIGZyb20gdGhlIG9yaWdpbmFsbHkgY29sbGVjdGVkIHNhbXBsZSB0byBkZXJpdmVkIGEgdmFyaWV0eSBvZiB0aGUgc2FtcGxlIHN0YXRpc3RpYyBvZiBpbnRlcmVzdCB2YWx1ZXMgdG8gY29tcGlsZSBhbmQgY29tcHV0ZSBpbnRvIGEgZXZlbiBtb3JlIHJvYnVzdCB2YWx1ZSBmb3IgdGhlIHNhbXBsZSBzdGF0aXN0aWMgb2YgaW50ZXJlc3QuICANCg0KV2Ugc2VsZWN0IGEgcmFuZG9tIHNhbXBsZSBmcm9tIHRoZSB0cnVlIHBvcHVsYXRpb24uICBXZSB1c2UgdGhlIGNvbGxlY3RlZCByYW5kb20gc2FtcGxlIGFzIGEgcmVwcmVzZW50YXRpdmUgcG9wdWxhdGlvbiB0byBkcmF3IHNhbXBsZXMgZnJvbS4gV2l0aCB0aGlzIG9yaWdpbmFsbHkgY2FwdHVyZWQgc2FtcGxlIHdlIHRha2UgDQoNCg0KV2UgY2hvb3NlIHRvIHJhbmRvbWx5IHNlbGVjdCByYW5kb20gc2FtcGxlcyBmcm9tIHRoZSBvcmlnaW5hbCByYW5kb20gc2FtcGxlIHRvIGNvbXB1dGUgYSBib290c3RyYXAgc2FtcGxlcyBzdGF0aXN0aWMuIFdlIHdpbGwgdWx0aW1hdGVseSB1c2UgYWxsIHRoZSBzaW11bGF0ZWQgYm9vdHN0cmFwIHN0YXRpc3RpY3MgdG8gY29tcHV0ZSB0aGUgc3RhdGlzdGljIG9mIGludGVyZXN0IG9udG8gdGhlIHNpbXVsYXRlZCBib290c3RyYXAgc3RhdGlzdGljcy4gDQoNCg0KQmVsb3cgaXMgdGhlIHNpbXVsYXRpb24gb2YgYSBib290c3RyYXAgc3RhdGlzdGljIGZyb20gYW4gb3JpZ2luYWwgZGF0YXNldCwgdG8gZmluZCBhIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gd2UgY2FuIGNhbGN1bGF0ZSBhIHN0YXRpc3RpYyBmcm9tDQoNCmBgYHtyfQ0KDQojY3JlYXRpbmcgYSBzaW11bGF0ZWQgYm9vdHN0cmFwDQoNCnVybCA9ICJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9TVEE1MDYvdzA0L3cwMi13Y3VoZWlnaHRzLnR4dCINCg0KDQpoZWlnaHQgPSByZWFkLnRhYmxlKHVybCwgaGVhZGVyID0gVFJVRSkgI3RoZSBQb3B1bGF0aW9uIG9mIHRoZSBoZWlnaHRzIGF0IHdlc3QgY2hlc3RlciB1bml2ZXJzaXR5IA0KDQpvcmlnaW5hbC5zYW1wbGUgPSBzYW1wbGUoaGVpZ2h0JEhlaWdodCwgODEsIHJlcGxhY2UgPSBGQUxTRSkgI1Rha2UgYSByYW5kb20gc2FtcGxlIG9mIHRoZSBvcmlnaW5hbCBwb3B1bGF0aW9uIHRvIGFjdCBhcyB0aGUgcG9wdWxhdGlvbiBwcm94eSBmb3Igb3VyIGJvb3RzdHJhcA0KDQojb3VyIHNhbXBsZSBzaXplIGlzIDgxDQojIHdlIGRvIG5vdCBuZWVkIHRvIHJlcGxhY2Ugb3VyIHNhbXBsZXMgZnJvbSB0aGUgdHJ1ZSBwb3B1bGF0aW9uLiBXZSB3b3VsZCBsaWtlIGNvbnNpc3RlbnQgdmFsdWVzIHRvIHJlcGVhdGVkbHkgc2FtcGxlIGZyb20gZm9yIG91ciBib290c3RyYXAgc2FtcGxpbmcNCg0KYnQuc2FtcGxlLm1lYW4gPSBOVUxMICNjcmVhdGUgYW4gZW1wdHkgdmVjdG9yIHRvIGhvbGQgb3VyIHNhbXBsZSBpbnRvIHdoZW4gd2UgY29tcHV0ZSB0aGUgYm9vdHN0cmFwIG1lYW4gZHVyaW5nIG91ciBmb3IgbG9vcA0KDQpmb3IoaSBpbiAxOjEwMDApDQp7DQogIA0KICBpdGguYnQuc2FtcGxlID0geD1zYW1wbGUoeD1vcmlnaW5hbC5zYW1wbGUsIHNpemUgPSA4MSwgcmVwbGFjZT0gVFJVRSkgI3Rha2UgcmVwZWF0ZWQgc2FtcGxlcyBmcm9tIG91ciBvcmlnaW5hbCBzYW1wbGUgYWthIHRoZSBzYW1wbGUgYWN0aW5nIGFzIGEgcHJveHkgZm9yIG91ciBvcmlnaW5hbCBwb3B1bGF0aW9uDQogIA0KICAjb3VyIHNhbXBsZSBzaXplIGlzIDgxLCB0aGUgc2FtZSBzaXplIG9mIHRoZSBvcmlnaW5hbCBwb3B1bGF0aW9uDQogICN3ZSB3YW50IHRvIHRha2UgdmFsdWVzIGZyb20gdGhpcyBzYW1wbGUgcmVwZWF0ZWQgc28gd2UgZG8gcmVwbGFjZSBvdXIgc2FtcGxlcyANCiAgDQogIGJ0LnNhbXBsZS5tZWFuW2ldID0gbWVhbihpdGguYnQuc2FtcGxlKQ0KICANCiAgDQp9DQoNCg0KaGlzdChidC5zYW1wbGUubWVhbiwNCiAgICAgYnJlYWtzID0gMTIsDQogICAgIHByb2JhYmlsaXR5ID0gVFJVRSwNCiAgICAgeGxhYiA9ICJCb290c3RyYXAgc2FtcGxlIG1lYW5zIiwgI3ggYXhpcyBsYWJsZQ0KICAgbWFpbj0iQm9vdHN0cmFwIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBcbiBvZiBTYW1wbGUgTWVhbnMgRXhhbXBsZSIsDQogICAgICAgICAgY2V4Lm1haW4gPSAwLjksDQogICAgICAgY29sLm1haW4gPSAiZGFya2dyZWVuIikgICANCmxpbmVzKGRlbnNpdHkoYnQuc2FtcGxlLm1lYW4pLCBjb2wgPSAic2t5Ymx1ZSIsIGx3ZCA9IDIpDQoNCmBgYA0KDQoNCg0KVGhlIEJvb3RzdHJhcCBTYW1wbGluZyBEaXN0cmlidXRpb24gaGFzIHZhbHVlIGJlY2F1c2UgaXQgYWxsb3dzIHVzIHRvIG1ha2UgaW5mZXJlbmNlcyBhYm91dCBhIHBvcHVsYXRpb24gYmFzZWQgb24gYSBsYXJnZSBpbmRlcGVuZGVudCBpZGVudGljYWxseSBkaXN0cnVidHVlZCByYW5kb20gc2FtcGxlIGluIHdoaWNoIHdlIGFyZSB1bnN1cmUgYWJvdXQgdGhlIHRydWUgcG9wdWxhdGlvbiBhbmQgbW9zdCBsaWtlbHkgaGF2ZSBjb21wbGV4aXR5IGluIHRoZSBvcmdhbml6YXRpb24gb2Ygb3VyIGRpc3RyaWJ1dGlvbi4gV2UgbWF5IGZpbmQgdmFsdWUgaW4gdXNpbmcgYSBib290c3RyYXAgd2hlbiANCg0KV2hlbiB3ZSBkbyBub3QgaGF2ZSBjb21wbGV4IGF0dHJpYnV0ZXMgaW4gb3VyIGRpc3RyaWJ1dGlvbiBhIEFzeW1wdG90aWMgRGlzdHJpYnV0aW9uIG1heSBiZSBiZXR0ZXIgZml0dGVkLiBBIHNpbXVsYXRpb24gbWF5IGNhdXNlIGhpZ2hlciBsaWtlbGlob29kIGYgdHlwZSBJIGVycm9yLCBkdWUgdG8gdGhlIG5lZWQgdG8gcnVuIG1vcmUgc2ltdWxhdGlvbiB0ZXN0cw0KDQoNCkFzc2VzcyB0aGUgcGVyZm9ybWFuY2Ugb2YgQm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgYWdhaW5zdCBleGFjdCBhbmQgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb25zLg0KDQpBbiBleGFjdCBkaXN0cmlidXRpb24gaGFzIHNpbWlsYXIgcXVhbGl0aWVzIHRvIGFuIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uLCBhbHRob3VnaCBhbiBleGFjdCBkaXN0cmlidXRpb24gaXMgc3BlY2lmaWMgdG8gYSBzbWFsbCBzYW1wbGUgc2l6ZSwgd2l0aCBhIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHNhbXBsZSB0aGF0IGlzIGFuIGlkZW50aWNhbGx5IGFuZCBpbnRlcmRlcGVuZGVudCBzYW1wbGVzIGRpc3RyaWJ1dGlvbi4gSW4gY29tcGFyaXNvbiB0byBib3RoIGV4YWN0IGFuZCBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbnMsIGEgYm9vdCBzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgdmFsdWFibGUgYmVjYXVzZSB3ZSBjYW4gc2ltdWxhdGUgYSBkaXN0cmlidXRpb24gdG8gcmVhY2ggYSBzdGF0aXN0aWMgZm9yIGEgZGlzdHJpYnV0aW9ucyB0aGF0IHdvdWxkIG90aGVyd2lzZSBiZSB0b28gY29tcGxleCB0byBtb2RlbCB0aHJvdWdoIHBhcmFtZXRyaWMgYXBwcm94aW1hdGlvbi4gQWx0aG91Z2ggYW4gZXhhY3QgdGVzdCBpcyBzbWFsbCBhbmQgYSBwYXJhbWV0cmljIHRlc3QsIGF0IHRpbWVzIGFuIGV4YWN0IHRlc3QgbWF5IGJlIG1vcmUgYXBwbGljYWJsZSBpZiB0aGVyZSBhcmUgbm8gY29tcGxleCBkaXN0cmlidXRpb25zLCBhIHNtYWxsIHNhbXBsZSBzaXplIHRoYXQgZG9lcyBub3QgbWVldCB0aGUgbGFyZ2Ugc2FtcGxlIHNpemUgYXNzdW1wdGlvbiBvZiB0aGUgQm9vdHN0cmFwIEFzc3VtcHRpb25zIGFuZCB0aGVyZSBhbHNvIGJlIGxpdHRsZSBuZWVkIHRvIGFwcHJveGltYXRlIHRoZSBkaXN0cmlidXRpb24gYXMgdGhlIGRpc3RyaWJ1dGlvbiBhbHJlYWR5IGtub3duLiBBIEJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24gbWF5IGJlIG1vcmUgYXBwcm9wcmlhdGUgZm9yIGNvbXBsZXggYXN5bXB0b3RpYyBkaXN0cmlidXRpb25zIHdpdGggbGFyZ2Ugc2FtcGxlIHNpemVzLg0KDQoNCg0KIyMgKipRdWVzdGlvbiAyOiBEYWlseSBDb2ZmZWUgU2FsZXMgKGluIG1MKSBhdCBUd28gRGlmZmVyZW50IENhZmUgTG9jYXRpb25zKioNCg0KVGhpcyBkYXRhIHNldCByZXByZXNlbnRzIHRoZSB2b2x1bWUgb2YgcmVndWxhciBicmV3ZWQgY29mZmVlIHNvbGQgcGVyIGRheSAoaW4gbWlsbGlsaXRlcnMpIGF0IHR3byBkaWZmZXJlbnQgY2FmZSBsb2NhdGlvbnMgb3ZlciBhIHBlcmlvZCBvZiA1MCBkYXlzLiANCg0KYGBgDQoyODUwLCAzMjAwLCAyOTAwLCAzMTAwLCAyOTUwLCA3ODAwLCA4MTAwLCA3OTAwLCAzMzAwLCAzMDUwLCA0MDAwLCA0MjAwLCAzMTUwLCAzNDAwLCA3NzAwLCA4MjAwLCANCjMyNTAsIDQ0MDAsIDMxMDAsIDQyMDAsIDQ1MDAsIDQ4MDAsIDQzMDAsIDg1MDAsIDgyMDAsIDg5MDAsIDg3MDAsIDMyNTAsIDMwMDAsIDQ2MDAsIDQxMDAsIDg0MDAsIA0KODgwMCwgMzM1MCwgNDcwMCwgMzEwMCwgODEwMCwgMzA1MCwgODMwMCwgNDEwMCwgMzEwMCwgODMwMCwgODkwMCwgODIwMCwgNDQwMCwgNDUwMCwgMzI1MCwgNDYwMCwgDQo4NDAwLCAzMzAwLCA0MjAwLCA0NTAwLCA0ODAwLCA0MzAwLCA4NTAwDQpgYGANCldlIGFyZSBpbnRlcmVzdGVkIGluIGZpbmRpbmcgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHZhcmlvdXMgaW5mZXJlbmNlcyBhYm91dCB0aGUgdW5kZXJseWluZyBwb3B1bGF0aW9uIG1lYW4uDQoNCmEpIEJhc2VkIG9uIHRoZSBnaXZlbiBkYXRhLCBjYW4gdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSBiZSB1c2VkIHRvIGRlcml2ZSB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBtZWFuPyBKdXN0aWZ5IHlvdXIgYW5zd2VyLg0KDQpUaGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gYWxsb3dzIGEgbm9uLXBhcmFtZXRyaWMgYXBwcm94aW1hdGlvbiB0aGF0IHVzZXMgdGhlIGFzc3VtcHRpb24gdGhhdCB0aGUgbGFyZ2VyIHRoZSBzYW1wbGUgc2l6ZSB0aGUsIGdyZWF0ZXIgdGhlIGxpa2VsaWhvb2QgdGhlIHNhbXBsZSBtZWFuIHdpbGwgYmUgbm9ybWFsbHkgZGlzdHJ1c3RlZC4gVGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSBpcyBhIHRvb2wgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHVzZXMgYSBhcyBhbiBhcHByb3hpbWF0aW9uIGZvciB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLiBJbiBtYW55IGNhc2VzIGJvdGggYW4gYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gb3IgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbiBjYW4gYmUgdXNlZCwgYWx0aG91Z2ggd2hpY2ggaXMgbW9zdCBhY2Nlc3NpYmxlIGRlcGVuZHMgb24gdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGRpc3RyaWJ1dGlvbiBhbmQgcGFyYW1ldGVyIG9mIGludGVyZXN0LiBBcyB0aGlzIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgZG9lcyBub3QgbG9vayBjb21wbGV4IGluIHJlZ2FyZHMgdG8gcGFpcmVkIG9ic2VydmF0aW9uIGZvciBleGFtcGxlLCB0aGUgY2VudHJhbCBsaW1pdCB0aGVvcmVtIGNhbiBiZSB1c2VkIGJlY2F1c2UgdGhlIHNhbXBsZSB3ZSBhcmUgYXNzdW1pbmcgaXMgb3VyIHBvcHVsYXRpb24gaXMgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkOyB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gZG9lcyBub3QgYXNzdW1lIHNoYXBlIG9mIHBvcHVsYXRpb24sIHVubGlrZSB0aGUgZXhhY3Qgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gDQoNCg0KVGhpcyBpcyB0aGUgdXNlIG9mIHRoZSBjZW50cmFsIGxpbWl0IHRoZW9yeSBmb3IgdGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIA0KDQpgYGB7cn0NCg0KY29mZmVlcyA9IGMoMjg1MCwgMzIwMCwgMjkwMCwgMzEwMCwgMjk1MCwgNzgwMCwgODEwMCwgNzkwMCwgMzMwMCwgMzA1MCwgNDAwMCwgNDIwMCwgMzE1MCwgMzQwMCwgNzcwMCwgODIwMCwgMzI1MCwgNDQwMCwgMzEwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCwgODIwMCwgODkwMCwgODcwMCwgMzI1MCwgMzAwMCwgNDYwMCwgNDEwMCwgODQwMCwgODgwMCwgMzM1MCwgNDcwMCwgMzEwMCwgODEwMCwgMzA1MCwgODMwMCwgNDEwMCwgMzEwMCwgODMwMCwgODkwMCwgODIwMCwgNDQwMCwgNDUwMCwgMzI1MCwgNDYwMCwgODQwMCwgMzMwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCkNCg0KDQoNCnMuY29mZmVlPXNvcnQoY29mZmVlcykgI3NvcnRpbmcgdGhlIGRhdGFzZXQgaW4gaW5jcmVhc2luZyBvcmRlcmluZw0KDQpoaXN0KHMuY29mZmVlLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBDb2ZmZWUgVm9sdW1lIiApI2JpbW9kYWwgZGlzdHJpYnV0aW9uDQoNCg0KDQojQnVpbGRpbmcgWiBkaXN0cmlidXRpb24gdG8gQXBwcm94aW1hdGUgZm9yIEFzeW1wdG90aWMgc2FtcGxpbmcgDQpuX2NvZmZlZT1sZW5ndGgocy5jb2ZmZWUpICNzYW1wbGUgc2l6ZSBpcyA1NQ0Kc2RfY29mZmVlID0gc2Qocy5jb2ZmZWUpICNzdGFuZGFyZCBkZXZpYXRpb24gb2Ygc29ydGVkIGNvZmZlZQ0KDQp2YXJfY29mZmVlID0gdmFyKHMuY29mZmVlKSAjY2FsY3VsYXRpbmcgc2FtcGxlIHZhcmlhbmNlIG9mIGNvZmZlZQ0KDQpzZV9jb2ZmZWUgPC0gc2RfY29mZmVlIC8gc3FydChuX2NvZmZlZSkgI3N0YW5kYXJkIGVycm9yIG9mIGNvZmZlZQ0KDQptZWFuLmNvZmZlZT1tZWFuKHMuY29mZmVlKSAjY29mZmVlIG1lYW4gaXMgNTI1MA0KDQplY2RmKHMuY29mZmVlKQ0KDQpmcmVxX2NvZmY9dGFibGUoY29mZmVlcykNCg0KDQoNCm15LkVDREYgPC0gZnVuY3Rpb24oaW5kYXQsIG91dHgpew0KICAjIG91dHggLSBhIHZlY3RvciBvZiBnaXZlbiB2YWx1ZXMNCiAgZnJlcS50YWJsZSA8LSB0YWJsZShpbmRhdCkgICAgICAgICAgICAgICAgICAgICAgICAgICMgZnJlcXVlbmN5IHRhYmxlDQogIHVuaXEgPC0gYXMubnVtZXJpYyhuYW1lcyhmcmVxLnRhYmxlKSkgICAgICAgICAgIyB1bmlxdWUgZGF0YSB2YWx1ZXMNCiAgcmVwLnRpbWUgPC0gYXMudmVjdG9yKGZyZXEudGFibGUpICAgICAgICAgICAgICAgICAgICMgZnJlcXVlbmNpZXMgb2YgdGhlIHVuaXF1ZSBkYXRhIHZhbHVlcw0KICBjdW0ucmVsLmZlcSA8LSBjdW1zdW0ocmVwLnRpbWUpL3N1bShyZXAudGltZSkgICAgICAgIyBjdW11bGF0aXZlIHJlbGF0aXZlIGZyZXF1ZW5jaWVzOiBDREYNCiAgY3VtLnByb2IgPC0gTlVMTA0KICBmb3IgKGkgaW4gMTpsZW5ndGgob3V0eCkpew0KICAgIGludHZsLmlkIDwtIHdoaWNoKHVuaXEgPD0gb3V0eFtpXSkgICAgICAjIGlkZW50aWZ5IHRoZSBpbmRleCBtZWV0aW5nIHRoZSBjb25kaXRpb24NCiAgICBjdW0ucHJvYltpXSA8LSBjdW0ucmVsLmZlcVttYXgoaW50dmwuaWQpXSAjIGV4dHJhY3QgdGhlIGN1bXVsYXRpdmUgcHJvYiBhY2NvcmRpbmcgdG8gQ0RGIA0KICB9DQogIGN1bS5wcm9iICAgICAgICAgICAgIA0KfQ0KDQpwbG90KHMuY29mZmVlLCBteS5FQ0RGKGluZGF0ID0gY29mZmVlcywgb3V0eCA9IHMuY29mZmVlKSwgdHlwZSA9ICJzIiwNCiAgICAgbWFpbiA9ICJFQ0RGIG9mIENvZmZlZSBWb2x1bWUiLA0KICAgICB4bGFiID0gIkNvZmZlZSBWb2x1bWUiLA0KICAgICB5bGFiID0gIkN1bXVsYXRpdmUgUHJvYmFiaWxpdHkiKQ0KDQoNCg0KYGBgDQoNCkluIHRoZSBoaXN0b2dyYW0gb2YgY29mZmVlIHZvbHVtZSB0aGUgZGlzdHJpYnV0aW9uIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZCBidXQsIGJpbW9kYWwsIG1lYW5pbmcgaGF2aW5nIHR3byBwZWFrcy4gVGhlcmUgaXMgbW9zdCBsaWtlbHkgYSBzZXBhcmF0aW9uIGluIG91ciBkYXRhc2V0IHRoYXQgY2F1c2VzIHRoZSB2b2x1bWVzIHRvIHNpdCBpbiB0d28gZGlmZmVyZW50ICdzdWJzZXRzJy4NCg0KDQpPdXIgY29mZmVlIHZvbHVtZSBzYW1wbGUgbWVhbiB1c2luZyB0aGUgQ0xUIGFwcHJveGltYXRpb24gZGlzdHJpYnV0aW9uIGlzIDUyNTAgbUwuDQogDQoNCg0KDQpiKSBBcHBseSB0aGUgYm9vdHN0cmFwIG1ldGhvZCB0byBlc3RpbWF0ZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIChvZnRlbiBjYWxsZWQgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24pIG9mIHRoZSBzYW1wbGUgbWVhbi4gR2VuZXJhdGUgYSBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBmcm9tIHRoZSBib290c3RyYXAgc2FtcGxlIG1lYW5zIGFuZCBwbG90IGl0LiBUaGVuLCB1c2UgdGhpcyBib290c3RyYXAgZGlzdHJpYnV0aW9uIHRvIHZhbGlkYXRlIHlvdXIgY29uY2x1c2lvbiBmcm9tIHBhcnQgKGEpLiBNYWtlIHN1cmUgeW91ciB2aXN1YWxzIGFyZSBlZmZlY3RpdmUgaW4gZW5oYW5jaW5nIHRoZSBwcmVzZW50YXRpb24gb2YgdGhlc2UgcmVzdWx0cy4NCg0KYGBge3J9DQojQXBwbHkgdGhlIGJvb3RzdHJhcCBtZXRob2QgdG8gdGhlIHNhbXBsZSBtZWFuDQojR2VuZXJhdGUgYSBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBmcm9tIHRoZSBib290c3RyYXAgYW5kIHNhbXBsZSBwbG90DQoNCiNjYWxsIHRoZSBzYW1wbGUgZnJvbSB0aGUgcG9wdWxhdGlvbg0Kc2V0LnNlZWQoMTQyKQ0KDQpzLmNvZmZlZQ0KI2NyZWF0ZSBhbiAgZW1wdHkgdmVjdG9yIHRvIGNhbGN1bGF0ZSB0aGUgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbiBtZWFuIGluIHRoZSBmb3IgbG9vcA0KDQpzLmNvZmZlZS52ZWMubWVhbiA9IE5VTEwNCg0KI3NhbXBsZSBmcm9tIHRoZSBwb3B1bGF0aW9uDQoNCmZvcihpIGluIDE6MTAwMCkNCnsNCiANCml0aC5jb2ZmZWUuc2FtcGxlPXNhbXBsZShzLmNvZmZlZSwgNTUsIHJlcGxhY2U9IFRSVUUpICNyYW5kb21seSBzZWxlY3QgZnJvbSBvcmlnaW5hbCBzYW1wbGUNCiNPdXIgc2FtcGxlIHNpemUgaXMgNTUNCiNyZXBsYWNlIG91ciBzYW1wbGUgZWFjaCBsb29wIGJlY2F1c2Ugd2UgZG8gbm90IGhhdmUgYSBsYXJnZSBzYW1wbGUNCg0Kcy5jb2ZmZWUudmVjLm1lYW5baV0gPSBtZWFuKGl0aC5jb2ZmZWUuc2FtcGxlKSAjY2FsY3VsYXRlZCBtZWFuOiA1MjA3LjI3Mw0KICANCn0NCg0Ka2RlID0gZGVuc2l0eShzLmNvZmZlZS52ZWMubWVhbiwgYncgPSBzZF9jb2ZmZWUpDQoNCiNnZW5lcmF0ZSBhIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRlIGZyb20gdGhlIGJvb3RzdHJhcCBmcm9tIHRoZSBzYW1wbGUgbWVhbnMgYW5kIHBsb3QgaXQNCg0KaGlzdChzLmNvZmZlZS52ZWMubWVhbiwgI2RhdGFwb2ludCBha2Egc3RhdGlzdGljIHdlIGp1c3QgZ2VuZXJhdGVkLCB3ZSB3YW50IHRvIHNlZSBpdHMgc2ltdWxhdGVkIGRpc3RydWJ1dGlvbg0KICAgICAgICBwcm9iYWJpbGl0eSA9IFRSVUUsICAjaWRlbnRpZnkgdGhlIHJlbGF0aXZlIGZyZXF1ZW5jeSAoYWx3YXlzIHNheSB0cnVlKQ0KICAgICAgICBicmVha3MgPSAxNCwNCiAgICAgICAgeGxhYiA9ICJzYW1wbGUgbWVhbnMgb2YgcmVwZWF0ZWQgc2FtcGxlcyIsICNsYWJlbCB0aGUgeCBheGlzDQogICAgICAgIG1haW49ICJBcHByb3hpbWF0ZWQgU2FtcGxpbmcgRGlzdHJ1YnV0aW9uIFxuIG9mIFNhbXBsZSBNZWFucyAtIEJvb3RzdHJhcCBSZXNhbXBsaW5nIiwNCiAgICAgY2V4Lm1haW4gPSAwLjksDQogICAgIGNvbC5tYWluID0gImRhcmtncmVlbiINCiAgICAgKQ0KbGluZXMoZGVuc2l0eShzLmNvZmZlZS52ZWMubWVhbiwga2VybmVsID0gImdhdXNzaWFuIiksIGNvbD0gInNreWJsdWUiLCBsd2Q9MikgI3doYXQgdGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gbG9va3MgbGlrZSANCg0KDQoNCg0KDQojIEtERSBiYXNlZCBvbiBidWlsdC1pbiBmdW5jdGlvbiBkZW5zaXR5KCk6IGJhbmR3aWR0aCA9IDAuNA0KDQojIyMjIyMjIyMjIyBwbG90IHdoYXQgdGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gbG9va3MgbGlrZSB3aGF0IGtlcm5lbCAjIyMjDQogIA0KDQoNCmBgYA0KDQpUaGUgc2ltdWxhdGVkIGJvb3RzdHJhcCByZXNhbXBsaW5nIG1lYW4gZm9yIHRoZSBjb2ZmZWUgdm9sdW1lIGlzIDUyMDcuMjczIG1MLg0KDQoNCldlIHNlZSBvdXIgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbiBnYXZlIGlzIGEgYXBwcm94aW1hdGVseSBub3JtYWwgZGlzdHJpYnV0aW9uIG9mIHRoZSBtZWFucywgb3VyIHBhcmFtZXRlciBzdGF0aXN0aWMgb2YgaW50ZXJlc3QuIA0KDQpPdXIgY2FsY3VsYXRlZCBtZWFuIG9mIGNvZmZlZSB2b2x1bWUgdXNpbmcgdGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gaXMgNTIxNy4yNzMgbUwuDQoNCg0KYGBge3J9DQoNCmJvb3RfZGYgPC0gZGF0YS5mcmFtZShib290X21lYW5zID0gcy5jb2ZmZWUudmVjLm1lYW4pICNDcmVhdGUgYSBjb21wYXJpc29uIGRhdGFmcmFtZSB0byBjb21wYXJlIHRoZSBDTFQgQXN5bXB0b3RpYyBEaXN0cmlidXRpb24gYW5kIHRoZSBCb290c3RyYXAgRGlzcnR1YnV0aW9uDQoNCg0KbWVhbi5jb2ZmZWUgPC0gbWVhbihzLmNvZmZlZSkgICAgIyBDZW50ZXIgKDUyNTApICNDYWxsIHRoZSBDTFQgYXN5bXB0b3RpYyAgIHBhcmFtZXRlcnMgZm9yIGNvbXBhcmlzb24NCnNlX2NvZmZlZSA8LSBzZChzLmNvZmZlZSkgLyBzcXJ0KGxlbmd0aChzLmNvZmZlZSkpICANCg0KIA0KZ2dwbG90KGJvb3RfZGYsIGFlcyh4ID0gYm9vdF9tZWFucykpICsgI2NyZWF0ZSBwbG90IHVzaW5nIGNvZmZlZSBtZWFuIGFrYSAgYm9vdHNfbWVhbg0KICAjY3JlYXRpbmcgYSBoaXN0b2dyYW0gYmFzZWQgb24gdGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gDQogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gYWZ0ZXJfc3RhdChkZW5zaXR5KSksIGJpbnMgPSAzMCwgDQogICAgICAgICAgICAgICAgIGZpbGwgPSAiZGFya2dyYXkiLCBhbHBoYSA9IDAuNCwgY29sb3IgPSAiYmxhY2siKSArDQogIA0KICAjIEI6IFRoZSBLREUgKEdhdXNzaWFuIEtlcm5lbCAtIFNtb290aGluZyB0aGUgQm9vdHN0cmFwIHJlc3VsdHMpDQogICMgUiBkZWZhdWx0cyB0byBhIEdhdXNzaWFuIGtlcm5lbCBoZXJlDQogIGdlb21fZGVuc2l0eShjb2xvciA9ICJibHVlIiwgbGluZXdpZHRoID0gMS4yKSArICNhZGQgYSBsYXllciBmb3IgYSBHYXVzc2lhbiBsaW5lIHdpdGggYSANCiAgDQogICMgQzogVGhlIENMVCBOb3JtYWwgQ3VydmUgKFZhbGlkYXRpb24gZnJvbSBQYXJ0IEEpDQogICNiYXNlZCBvbiB0aGUgbWVhbiBvZiBjb2ZmZWUgYW5kIHN0YW5kYXJkIGVycm9yIGZvciBhIEFzeW1wdG90aWMgZGlzdHJpYnV0aW9uDQogIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBsaXN0KG1lYW4gPSBtZWFuLmNvZmZlZSwgc2QgPSBzZV9jb2ZmZWUpLCANCiAgICAgICAgICAgICAgICBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBsaW5ld2lkdGggPSAxKSArDQogIA0KICAjIExhYmVscyBhbmQgVGhlbWUNCiAgbGFicyh0aXRsZSA9ICJBcHByb3hpbWF0ZWQgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIFNhbXBsZSBNZWFucyIsDQogICAgICAgc3VidGl0bGUgPSAiR3JheTogQm9vdHN0cmFwIEhpc3QgfCBCbHVlOiBHYXVzc2lhbiBLREUgfCBSZWQ6IENMVCBOb3JtYWwiLA0KICAgICAgIHggPSAiU2FtcGxlIE1lYW4gVm9sdW1lIChtTCkiLCANCiAgICAgICB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KQXMgbWVudGlvbmVkIHByaW9yLCBib3RoIHRoZSBib290c3RyYXAgYW5kIHRoZSBDTFQgQXN5bXB0b3RpYyBTYW1wbGluZyBEaXN0cmlidXRpb24gY2FuIGJlIHVzZWQgb24gdGhpcyBub24tY29tcGxleCBkaXN0cmlidXRpb24gdHlwZSwgdGh1cyB0aGUgZGlzdHJpYnV0aW9ucyBmb3IgdGFrZW4gYm90aCBmb3IgdGhlIGJvb3RzdHJhcCBhbmQgYXN5bXB0b3RpYyBwcmVzZW50IHNpbWlsYXIgcmVzdWx0cy4gQQ0KDQoNCg0KDQpjKSBSZXBlYXQgdGhlIGFuYWx5c2lzIGluIHBhcnRzIChhKSBhbmQgKGIpIGZvciB0aGUgc2FtcGxlIHZhcmlhbmNlLg0KDQoNCmBgYHtyfQ0Kb3B0aW9ucyhzY2lwZW4gPSAwKQ0KDQojUGFydCBhIGZvciBWYXJpYW5jZQ0KdmFyX2NvZmZlZSA9IHZhcihzLmNvZmZlZSkgI2NhbGN1bGF0aW5nIHNhbXBsZSB2YXJpYW5jZSBvZiBjb2ZmZWUgPSA1MDMwODMzDQoNCiMjUGFydCBCIGZvciBWYXJpYW5jZSAgDQoNCiNjYWxsIHRoZSBzYW1wbGUgZnJvbSB0aGUgcG9wdWxhdGlvbg0Kc2V0LnNlZWQoMTQyKQ0KDQpzLmNvZmZlZQ0KI2NyZWF0ZSBhbiAgZW1wdHkgdmVjdG9yIHRvIGNhbGN1bGF0ZSB0aGUgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbiBtZWFuIGluIHRoZSBmb3IgbG9vcA0KDQpzLmNvZmZlZS52ZWMudmFyID0gTlVMTA0KDQojc2FtcGxlIGZyb20gdGhlIHBvcHVsYXRpb24NCg0KZm9yKGkgaW4gMToxMDAwKQ0Kew0KIA0KaXRoLmNvZmZlZS5zYW1wbGUudj1zYW1wbGUocy5jb2ZmZWUsIDU1LCByZXBsYWNlPSBUUlVFKSAjcmFuZG9tbHkgc2VsZWN0IGZyb20gb3JpZ2luYWwgc2FtcGxlDQojT3VyIHNhbXBsZSBzaXplIGlzIDU1DQojcmVwbGFjZSBvdXIgc2FtcGxlIGVhY2ggbG9vcCBiZWNhdXNlIHdlIGRvIG5vdCBoYXZlIGEgbGFyZ2Ugc2FtcGxlDQoNCnMuY29mZmVlLnZlYy52YXJbaV0gPSB2YXIoaXRoLmNvZmZlZS5zYW1wbGUudikgI2NhbGN1bGF0ZWQgdmFyaWFuY2U6IDQ4NDQ3NjENCiAgDQp9DQoNCmtkZVYgPSBkZW5zaXR5KHMuY29mZmVlLnZlYy52YXIpDQoNCiNnZW5lcmF0ZSBhIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRlIGZyb20gdGhlIGJvb3RzdHJhcCBmcm9tIHRoZSBzYW1wbGUgbWVhbnMgYW5kIHBsb3QgaXQNCg0KaGlzdChzLmNvZmZlZS52ZWMudmFyLCAjZGF0YXBvaW50IGFrYSBzdGF0aXN0aWMgd2UganVzdCBnZW5lcmF0ZWQsIHdlIHdhbnQgdG8gc2VlIGl0cyBzaW11bGF0ZWQgZGlzdHJ1YnV0aW9uDQogICAgICAgIHByb2JhYmlsaXR5ID0gVFJVRSwgICNpZGVudGlmeSB0aGUgcmVsYXRpdmUgZnJlcXVlbmN5IChhbHdheXMgc2F5IHRydWUpDQogICAgICAgIGJyZWFrcyA9IDE0LA0KICAgICAgICB4bGFiID0gInNhbXBsZSB2YXJpZW5jZSBvZiByZXBlYXRlZCBzYW1wbGVzIiwgI2xhYmVsIHRoZSB4IGF4aXMNCiAgICAgICAgbWFpbj0gIkFwcHJveGltYXRlZCBTYW1wbGluZyBEaXN0cnVidXRpb24gXG4gb2YgU2FtcGxlIFZhcmllbmNlIC0gQm9vdHN0cmFwIFJlc2FtcGxpbmciLA0KICAgICBjZXgubWFpbiA9IDAuOSwNCiAgICAgY29sLm1haW4gPSAiZGFya2dyZWVuIg0KICAgICApDQpsaW5lcyhkZW5zaXR5KHMuY29mZmVlLnZlYy52YXIsIGtlcm5lbCA9ICJnYXVzc2lhbiIpLCBjb2w9ICJza3libHVlIiwgbHdkPTIpICN3aGF0IHRoZSBib290c3RyYXAgZGlzdHJpYnV0aW9uIGxvb2tzIGxpa2UgDQoNCg0KDQpgYGANCg0KDQpUaGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgYSBkaXN0cmlidXRpb24gYmV0dGVyIHJlcHJlc2VudGVkIGZvciBub24tY29tcGxleCB2YWx1ZXMuIEFzIHRoZSB2YXJpYW5jZSBpcyBhIHNxdWFyZWQgcGFyYW1ldGVyIHRoYXQgYWRkcyBjb21wbGV4aXR5IGEgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgbm90IGEgc3Ryb25nIGRpc3RyaWJ1dGlvbiB0eXBlIGZvciBpZGVudGlmeWluZyBhIHZhcmlhbmNlIHBhcmFtZXRlci4gQSBib290c3RyYXAgcmVzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgYSBiZXR0ZXIgc3VpdGVkIGRpc3RyaWJ1dGlvbiB0eXBlIGZvciBpZGVudGlmeWluZyBhIHZhcmlhbmNlJ3MgYWRkZWQgY29tcGxleGl0eS4gDQoNCg0KDQo=